xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18  /**
19   * DOC: Public APIs to perform operations on Global objects
20   */
21 #include <wlan_objmgr_cmn.h>
22 #include <wlan_objmgr_global_obj.h>
23 #include <wlan_objmgr_psoc_obj.h>
24 #include <wlan_objmgr_pdev_obj.h>
25 #include <wlan_objmgr_vdev_obj.h>
26 #include <wlan_objmgr_peer_obj.h>
27 #include <wlan_objmgr_debug.h>
28 #include <qdf_mem.h>
29 #include <qdf_module.h>
30 #include "wlan_objmgr_global_obj_i.h"
31 #include "wlan_objmgr_psoc_obj_i.h"
32 #include "wlan_objmgr_pdev_obj_i.h"
33 #include <wlan_utility.h>
34 
35 /**
36  ** APIs to Create/Delete Global object APIs
37  */
38 static QDF_STATUS wlan_objmgr_pdev_object_status(
39 		struct wlan_objmgr_pdev *pdev)
40 {
41 	uint8_t id;
42 	QDF_STATUS status = QDF_STATUS_SUCCESS;
43 
44 	wlan_pdev_obj_lock(pdev);
45 	/* Iterate through all components to derive the object status */
46 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
47 		/* If component disabled, Ignore */
48 		if (pdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
49 			continue;
50 		/* If component operates in Async, status is Partially created,
51 			break */
52 		} else if (pdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
53 			if (!pdev->pdev_comp_priv_obj[id]) {
54 				status = QDF_STATUS_COMP_ASYNC;
55 				break;
56 			}
57 		/* If component failed to allocate its object, treat it as
58 			failure, complete object need to be cleaned up */
59 		} else if ((pdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
60 			(pdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
61 			status = QDF_STATUS_E_FAILURE;
62 			break;
63 		}
64 	}
65 	wlan_pdev_obj_unlock(pdev);
66 	return status;
67 }
68 
69 static QDF_STATUS wlan_objmgr_pdev_obj_free(struct wlan_objmgr_pdev *pdev)
70 {
71 
72 	uint8_t pdev_id;
73 
74 	if (!pdev) {
75 		obj_mgr_err("pdev obj is NULL");
76 		QDF_ASSERT(0);
77 		return QDF_STATUS_E_FAILURE;
78 	}
79 
80 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
81 
82 	/* Detach PDEV from PSOC PDEV's list */
83 	if (wlan_objmgr_psoc_pdev_detach(pdev->pdev_objmgr.wlan_psoc, pdev) ==
84 						QDF_STATUS_E_FAILURE) {
85 		obj_mgr_err("PSOC PDEV detach failed: pdev-id: %d", pdev_id);
86 		return QDF_STATUS_E_FAILURE;
87 	}
88 	qdf_spinlock_destroy(&pdev->pdev_lock);
89 	qdf_mem_free(pdev);
90 
91 	return QDF_STATUS_SUCCESS;
92 }
93 
94 struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create(
95 			struct wlan_objmgr_psoc *psoc,
96 			struct pdev_osif_priv *osdev_priv)
97 {
98 	struct wlan_objmgr_pdev *pdev;
99 	uint8_t id;
100 	wlan_objmgr_pdev_create_handler handler;
101 	wlan_objmgr_pdev_status_handler s_handler;
102 	void *arg;
103 	QDF_STATUS obj_status;
104 
105 	if (!psoc) {
106 		obj_mgr_err("psoc is NULL");
107 		return NULL;
108 	}
109 	/* Allocate PDEV object's memory */
110 	pdev = qdf_mem_malloc(sizeof(*pdev));
111 	if (!pdev)
112 		return NULL;
113 
114 	pdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
115 	/* Initialize PDEV spinlock */
116 	qdf_spinlock_create(&pdev->pdev_lock);
117 	/* Attach PDEV with PSOC */
118 	if (wlan_objmgr_psoc_pdev_attach(psoc, pdev)
119 				!= QDF_STATUS_SUCCESS) {
120 		obj_mgr_err("pdev psoc attach failed");
121 		qdf_spinlock_destroy(&pdev->pdev_lock);
122 		qdf_mem_free(pdev);
123 		return NULL;
124 	}
125 	wlan_minidump_log(pdev, sizeof(*pdev), psoc,
126 			  WLAN_MD_OBJMGR_PDEV, "wlan_objmgr_pdev");
127 	/* Save PSOC object pointer in PDEV */
128 	wlan_pdev_set_psoc(pdev, psoc);
129 	/* Initialize PDEV's VDEV list, assign default values */
130 	qdf_list_create(&pdev->pdev_objmgr.wlan_vdev_list,
131 			WLAN_UMAC_PDEV_MAX_VDEVS);
132 	pdev->pdev_objmgr.wlan_vdev_count = 0;
133 	pdev->pdev_objmgr.max_vdev_count = WLAN_UMAC_PDEV_MAX_VDEVS;
134 	pdev->pdev_objmgr.wlan_peer_count = 0;
135 	pdev->pdev_objmgr.temp_peer_count = 0;
136 	pdev->pdev_objmgr.max_peer_count = wlan_psoc_get_max_peer_count(psoc);
137 	/* Save HDD/OSIF pointer */
138 	pdev->pdev_nif.pdev_ospriv = osdev_priv;
139 	qdf_atomic_init(&pdev->pdev_objmgr.ref_cnt);
140 	pdev->pdev_objmgr.print_cnt = 0;
141 	wlan_objmgr_pdev_get_ref(pdev, WLAN_OBJMGR_ID);
142 	/* Invoke registered create handlers */
143 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
144 		handler = g_umac_glb_obj->pdev_create_handler[id];
145 		arg = g_umac_glb_obj->pdev_create_handler_arg[id];
146 		if (handler)
147 			pdev->obj_status[id] = handler(pdev, arg);
148 		else
149 			pdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
150 	}
151 	/* Derive object status */
152 	obj_status = wlan_objmgr_pdev_object_status(pdev);
153 
154 	if (obj_status == QDF_STATUS_SUCCESS) {
155 		/* Object status is SUCCESS, Object is created */
156 		pdev->obj_state = WLAN_OBJ_STATE_CREATED;
157 		/* Invoke component registered status handlers */
158 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
159 			s_handler = g_umac_glb_obj->pdev_status_handler[id];
160 			arg = g_umac_glb_obj->pdev_status_handler_arg[id];
161 			if (s_handler) {
162 				s_handler(pdev, arg,
163 					  QDF_STATUS_SUCCESS);
164 			}
165 		}
166 	/* Few components operates in Asynchrous communction, Object state
167 	partially created */
168 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
169 		pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
170 	/* Component object failed to be created, clean up the object */
171 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
172 		/* Clean up the psoc */
173 		obj_mgr_err("PDEV component objects allocation failed");
174 		wlan_objmgr_pdev_obj_delete(pdev);
175 		return NULL;
176 	}
177 
178 	obj_mgr_debug("Created pdev %d", pdev->pdev_objmgr.wlan_pdev_id);
179 
180 	return pdev;
181 }
182 qdf_export_symbol(wlan_objmgr_pdev_obj_create);
183 
184 static QDF_STATUS wlan_objmgr_pdev_obj_destroy(struct wlan_objmgr_pdev *pdev)
185 {
186 	uint8_t id;
187 	wlan_objmgr_pdev_destroy_handler handler;
188 	QDF_STATUS obj_status;
189 	void *arg;
190 	uint8_t pdev_id;
191 
192 	if (!pdev) {
193 		obj_mgr_err("pdev is NULL");
194 		return QDF_STATUS_E_FAILURE;
195 	}
196 	wlan_objmgr_notify_destroy(pdev, WLAN_PDEV_OP);
197 
198 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
199 
200 	wlan_print_pdev_info(pdev);
201 	obj_mgr_debug("Physically deleting pdev %d", pdev_id);
202 
203 	if (pdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
204 		obj_mgr_err("PDEV object delete is not invoked pdevid:%d objstate:%d",
205 			    pdev_id, pdev->obj_state);
206 		WLAN_OBJMGR_BUG(0);
207 	}
208 
209 	wlan_minidump_remove(pdev, sizeof(*pdev), wlan_pdev_get_psoc(pdev),
210 			     WLAN_MD_OBJMGR_PDEV, "wlan_objmgr_pdev");
211 
212 	/* Invoke registered destroy handlers */
213 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
214 		handler = g_umac_glb_obj->pdev_destroy_handler[id];
215 		arg = g_umac_glb_obj->pdev_destroy_handler_arg[id];
216 		if (handler &&
217 		    (pdev->obj_status[id] == QDF_STATUS_SUCCESS ||
218 		     pdev->obj_status[id] == QDF_STATUS_COMP_ASYNC))
219 			pdev->obj_status[id] = handler(pdev, arg);
220 		else
221 			pdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
222 	}
223 	/* Derive object status */
224 	obj_status = wlan_objmgr_pdev_object_status(pdev);
225 
226 	if (obj_status == QDF_STATUS_E_FAILURE) {
227 		obj_mgr_err("PDEV component objects destroy failed: pdev-id:%d",
228 				pdev_id);
229 		/* Ideally should not happen */
230 		/* This leads to memleak ??? how to handle */
231 		QDF_BUG(0);
232 		return QDF_STATUS_E_FAILURE;
233 	}
234 	/* Deletion is in progress */
235 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
236 		pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
237 		return QDF_STATUS_COMP_ASYNC;
238 	}
239 	/* Free PDEV object */
240 	return wlan_objmgr_pdev_obj_free(pdev);
241 }
242 
243 QDF_STATUS wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev *pdev)
244 {
245 	uint8_t print_idx;
246 
247 	if (!pdev) {
248 		obj_mgr_err("pdev is NULL");
249 		return QDF_STATUS_E_FAILURE;
250 	}
251 
252 	obj_mgr_debug("Logically deleting pdev %d",
253 		      pdev->pdev_objmgr.wlan_pdev_id);
254 
255 	print_idx = qdf_get_pidx();
256 	wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg,
257 				  QDF_TRACE_LEVEL_DEBUG);
258 	/*
259 	 * Update PDEV object state to LOGICALLY DELETED
260 	 * It prevents further access of this object
261 	 */
262 	wlan_pdev_obj_lock(pdev);
263 	pdev->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
264 	wlan_pdev_obj_unlock(pdev);
265 	wlan_objmgr_notify_log_delete(pdev, WLAN_PDEV_OP);
266 	wlan_objmgr_pdev_release_ref(pdev, WLAN_OBJMGR_ID);
267 
268 	return QDF_STATUS_SUCCESS;
269 }
270 qdf_export_symbol(wlan_objmgr_pdev_obj_delete);
271 
272 /**
273  ** APIs to attach/detach component objects
274  */
275 QDF_STATUS wlan_objmgr_pdev_component_obj_attach(
276 		struct wlan_objmgr_pdev *pdev,
277 		enum wlan_umac_comp_id id,
278 		void *comp_priv_obj,
279 		QDF_STATUS status)
280 {
281 	uint8_t i;
282 	wlan_objmgr_pdev_status_handler s_hlr;
283 	void *a;
284 	QDF_STATUS obj_status;
285 
286 	/* component id is invalid */
287 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
288 		obj_mgr_err("component-id %d is not supported", id);
289 		return QDF_STATUS_MAXCOMP_FAIL;
290 	}
291 	wlan_pdev_obj_lock(pdev);
292 	/* If there is a valid entry, return failure */
293 	if (pdev->pdev_comp_priv_obj[id]) {
294 		obj_mgr_err("component-%d already have valid pointer", id);
295 		wlan_pdev_obj_unlock(pdev);
296 		return QDF_STATUS_E_FAILURE;
297 	}
298 	/* Save component's pointer and status */
299 	pdev->pdev_comp_priv_obj[id] = comp_priv_obj;
300 	pdev->obj_status[id] = status;
301 
302 	wlan_pdev_obj_unlock(pdev);
303 
304 	if (pdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
305 		return QDF_STATUS_SUCCESS;
306 	/**
307 	 * If PDEV object status is partially created means, this API is
308 	 * invoked with differnt context, this block should be executed for
309 	 * async components only
310 	 */
311 	/* Derive status */
312 	obj_status = wlan_objmgr_pdev_object_status(pdev);
313 	/* STATUS_SUCCESS means, object is CREATED */
314 	if (obj_status == QDF_STATUS_SUCCESS)
315 		pdev->obj_state = WLAN_OBJ_STATE_CREATED;
316 	/* update state as CREATION failed, caller has to delete the
317 	PDEV object */
318 	else if (obj_status == QDF_STATUS_E_FAILURE)
319 		pdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
320 	/* Notify components about the CREATION success/failure */
321 	if ((obj_status == QDF_STATUS_SUCCESS) ||
322 	    (obj_status == QDF_STATUS_E_FAILURE)) {
323 		/* nofity object status */
324 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
325 			s_hlr = g_umac_glb_obj->pdev_status_handler[i];
326 			a = g_umac_glb_obj->pdev_status_handler_arg[i];
327 			if (s_hlr)
328 				s_hlr(pdev, a, obj_status);
329 		}
330 	}
331 	return QDF_STATUS_SUCCESS;
332 }
333 qdf_export_symbol(wlan_objmgr_pdev_component_obj_attach);
334 
335 QDF_STATUS wlan_objmgr_pdev_component_obj_detach(
336 		struct wlan_objmgr_pdev *pdev,
337 		enum wlan_umac_comp_id id,
338 		void *comp_priv_obj)
339 {
340 	QDF_STATUS obj_status;
341 
342 	/* component id is invalid */
343 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
344 		return QDF_STATUS_MAXCOMP_FAIL;
345 
346 	wlan_pdev_obj_lock(pdev);
347 	/* If there is a invalid entry, return failure */
348 	if (pdev->pdev_comp_priv_obj[id] != comp_priv_obj) {
349 		pdev->obj_status[id] = QDF_STATUS_E_FAILURE;
350 		wlan_pdev_obj_unlock(pdev);
351 		return QDF_STATUS_E_FAILURE;
352 	}
353 	/* Reset pointers to NULL, update the status*/
354 	pdev->pdev_comp_priv_obj[id] = NULL;
355 	pdev->obj_status[id] = QDF_STATUS_SUCCESS;
356 	wlan_pdev_obj_unlock(pdev);
357 
358 	/* If PDEV object status is partially destroyed means, this API is
359 	invoked with differnt context, this block should be executed for async
360 	components only */
361 	if ((pdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
362 	    (pdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
363 		/* Derive object status */
364 		obj_status = wlan_objmgr_pdev_object_status(pdev);
365 		if (obj_status == QDF_STATUS_SUCCESS) {
366 			/*Update the status as Deleted, if full object
367 				deletion is in progress */
368 			if (pdev->obj_state ==
369 				WLAN_OBJ_STATE_PARTIALLY_DELETED)
370 				pdev->obj_state = WLAN_OBJ_STATE_DELETED;
371 			/* Move to creation state, since this component
372 			deletion alone requested */
373 			if (pdev->obj_state ==
374 				WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
375 				pdev->obj_state = WLAN_OBJ_STATE_CREATED;
376 		/* Object status is failure */
377 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
378 			/*Update the status as Deletion failed, if full object
379 				deletion is in progress */
380 			if (pdev->obj_state ==
381 					WLAN_OBJ_STATE_PARTIALLY_DELETED)
382 				pdev->obj_state =
383 					WLAN_OBJ_STATE_DELETION_FAILED;
384 			/* Move to creation state, since this component
385 			deletion alone requested (do not block other
386 			components)*/
387 			if (pdev->obj_state ==
388 					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
389 				pdev->obj_state = WLAN_OBJ_STATE_CREATED;
390 		}
391 
392 		/* Delete pdev object */
393 		if ((obj_status == QDF_STATUS_SUCCESS) &&
394 		    (pdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
395 			/* Free PDEV object */
396 			return wlan_objmgr_pdev_obj_free(pdev);
397 		}
398 	}
399 	return QDF_STATUS_SUCCESS;
400 }
401 qdf_export_symbol(wlan_objmgr_pdev_component_obj_detach);
402 
403 /**
404  ** APIs to operations on pdev objects
405  */
406 static void wlan_objmgr_pdev_vdev_iterate_peers(struct wlan_objmgr_pdev *pdev,
407 				struct wlan_objmgr_vdev *vdev,
408 				wlan_objmgr_pdev_op_handler handler,
409 				void *arg, uint8_t lock_free_op,
410 				wlan_objmgr_ref_dbgid dbg_id)
411 {
412 	qdf_list_t *peer_list = NULL;
413 	struct wlan_objmgr_peer *peer = NULL;
414 	struct wlan_objmgr_peer *peer_next = NULL;
415 
416 	/* Iterating through vdev's peer list, so lock is
417 		needed */
418 	/* Get peer list of the vdev */
419 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
420 	if (peer_list) {
421 		peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
422 								dbg_id);
423 		while (peer) {
424 			/* Invoke the handler */
425 			handler(pdev, (void *)peer, arg);
426 			/* Get next peer pointer, increments the ref count */
427 			peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev,
428 						peer_list, peer, dbg_id);
429 			wlan_objmgr_peer_release_ref(peer, dbg_id);
430 			peer = peer_next;
431 		}
432 	}
433 }
434 
435 QDF_STATUS wlan_objmgr_pdev_iterate_obj_list(
436 		struct wlan_objmgr_pdev *pdev,
437 		enum wlan_objmgr_obj_type obj_type,
438 		wlan_objmgr_pdev_op_handler handler,
439 		void *arg, uint8_t lock_free_op,
440 		wlan_objmgr_ref_dbgid dbg_id)
441 {
442 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
443 	qdf_list_t *vdev_list = NULL;
444 	struct wlan_objmgr_vdev *vdev = NULL;
445 	struct wlan_objmgr_vdev *vdev_next = NULL;
446 
447 	/* VDEV list */
448 	vdev_list = &objmgr->wlan_vdev_list;
449 
450 	switch (obj_type) {
451 	case WLAN_VDEV_OP:
452 		/* Iterate through all VDEV object, and invoke handler for each
453 			VDEV object */
454 		vdev = wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
455 								dbg_id);
456 		while (vdev) {
457 			handler(pdev, (void *)vdev, arg);
458 			 /* Get next vdev, it increments ref of next vdev */
459 			vdev_next = wlan_vdev_get_next_active_vdev_of_pdev(
460 					pdev, vdev_list, vdev, dbg_id);
461 			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
462 			vdev = vdev_next;
463 		}
464 		break;
465 	case WLAN_PEER_OP:
466 		vdev = wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
467 								dbg_id);
468 		while (vdev) {
469 			wlan_objmgr_pdev_vdev_iterate_peers(pdev, vdev,	handler,
470 						arg, lock_free_op, dbg_id);
471 			 /* Get next vdev, it increments ref of next vdev */
472 			vdev_next = wlan_vdev_get_next_active_vdev_of_pdev(
473 					pdev, vdev_list, vdev, dbg_id);
474 			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
475 			vdev = vdev_next;
476 		}
477 		break;
478 	default:
479 		break;
480 	}
481 
482 	return QDF_STATUS_SUCCESS;
483 }
484 qdf_export_symbol(wlan_objmgr_pdev_iterate_obj_list);
485 
486 QDF_STATUS wlan_objmgr_trigger_pdev_comp_priv_object_creation(
487 		struct wlan_objmgr_pdev *pdev,
488 		enum wlan_umac_comp_id id)
489 {
490 	wlan_objmgr_pdev_create_handler handler;
491 	void *arg;
492 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
493 
494 	/* Component id is invalid */
495 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
496 		return QDF_STATUS_MAXCOMP_FAIL;
497 
498 	wlan_pdev_obj_lock(pdev);
499 	/* If component object is already created, delete old
500 		component object, then invoke creation */
501 	if (pdev->pdev_comp_priv_obj[id]) {
502 		wlan_pdev_obj_unlock(pdev);
503 		return QDF_STATUS_E_FAILURE;
504 	}
505 	wlan_pdev_obj_unlock(pdev);
506 
507 	/* Invoke registered create handlers */
508 	handler = g_umac_glb_obj->pdev_create_handler[id];
509 	arg = g_umac_glb_obj->pdev_create_handler_arg[id];
510 	if (handler)
511 		pdev->obj_status[id] = handler(pdev, arg);
512 	else
513 		return QDF_STATUS_E_FAILURE;
514 	/* If object status is created, then only handle this object status */
515 	if (pdev->obj_state == WLAN_OBJ_STATE_CREATED) {
516 		/* Derive object status */
517 		obj_status = wlan_objmgr_pdev_object_status(pdev);
518 		/* Move PDEV object state to Partially created state */
519 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
520 			/*TODO atomic */
521 			pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
522 		}
523 	}
524 	return obj_status;
525 }
526 
527 QDF_STATUS wlan_objmgr_trigger_pdev_comp_priv_object_deletion(
528 		struct wlan_objmgr_pdev *pdev,
529 		enum wlan_umac_comp_id id)
530 {
531 	wlan_objmgr_pdev_destroy_handler handler;
532 	void *arg;
533 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
534 
535 	/* component id is invalid */
536 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
537 		return QDF_STATUS_MAXCOMP_FAIL;
538 
539 	wlan_pdev_obj_lock(pdev);
540 	/* Component object was never created, invalid operation */
541 	if (!pdev->pdev_comp_priv_obj[id]) {
542 		wlan_pdev_obj_unlock(pdev);
543 		return QDF_STATUS_E_FAILURE;
544 	}
545 	wlan_pdev_obj_unlock(pdev);
546 
547 	/* Invoke registered create handlers */
548 	handler = g_umac_glb_obj->pdev_destroy_handler[id];
549 	arg = g_umac_glb_obj->pdev_destroy_handler_arg[id];
550 	if (handler)
551 		pdev->obj_status[id] = handler(pdev, arg);
552 	else
553 		return QDF_STATUS_E_FAILURE;
554 
555 	/* If object status is created, then only handle this object status */
556 	if (pdev->obj_state == WLAN_OBJ_STATE_CREATED) {
557 		obj_status = wlan_objmgr_pdev_object_status(pdev);
558 		/* move object state to DEL progress */
559 		if (obj_status == QDF_STATUS_COMP_ASYNC)
560 			pdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
561 	}
562 	return obj_status;
563 }
564 
565 static void wlan_obj_pdev_vdevlist_add_tail(qdf_list_t *obj_list,
566 				struct wlan_objmgr_vdev *obj)
567 {
568 	qdf_list_insert_back(obj_list, &obj->vdev_node);
569 }
570 
571 static QDF_STATUS wlan_obj_pdev_vdevlist_remove_vdev(
572 				qdf_list_t *obj_list,
573 				struct wlan_objmgr_vdev *vdev)
574 {
575 	qdf_list_node_t *vdev_node = NULL;
576 
577 	if (!vdev)
578 		return QDF_STATUS_E_FAILURE;
579 	/* get vdev list node element */
580 	vdev_node = &vdev->vdev_node;
581 	/* list is empty, return failure */
582 	if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
583 		return QDF_STATUS_E_FAILURE;
584 
585 	return QDF_STATUS_SUCCESS;
586 }
587 
588 QDF_STATUS wlan_objmgr_pdev_vdev_attach(struct wlan_objmgr_pdev *pdev,
589 					struct wlan_objmgr_vdev *vdev)
590 {
591 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
592 
593 	wlan_pdev_obj_lock(pdev);
594 	/* If Max vdev count exceeds, return failure */
595 	if (objmgr->wlan_vdev_count >= objmgr->max_vdev_count) {
596 		wlan_pdev_obj_unlock(pdev);
597 		return QDF_STATUS_E_FAILURE;
598 	}
599 	/* Add vdev to pdev's vdev list */
600 	wlan_obj_pdev_vdevlist_add_tail(&objmgr->wlan_vdev_list, vdev);
601 	/* Increment pdev ref count to make sure it won't be destroyed before */
602 	wlan_objmgr_pdev_get_ref(pdev, WLAN_OBJMGR_ID);
603 	/* Increment vdev count of pdev */
604 	objmgr->wlan_vdev_count++;
605 	wlan_pdev_obj_unlock(pdev);
606 
607 	return QDF_STATUS_SUCCESS;
608 }
609 
610 QDF_STATUS wlan_objmgr_pdev_vdev_detach(struct wlan_objmgr_pdev *pdev,
611 				struct wlan_objmgr_vdev *vdev)
612 {
613 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
614 
615 	wlan_pdev_obj_lock(pdev);
616 	/* if vdev count is 0, return failure */
617 	if (objmgr->wlan_vdev_count == 0) {
618 		wlan_pdev_obj_unlock(pdev);
619 		return QDF_STATUS_E_FAILURE;
620 	}
621 	/* remove vdev from pdev's vdev list */
622 	wlan_obj_pdev_vdevlist_remove_vdev(&objmgr->wlan_vdev_list, vdev);
623 	/* decrement vdev count */
624 	objmgr->wlan_vdev_count--;
625 	wlan_pdev_obj_unlock(pdev);
626 	/* Decrement pdev ref count since vdev is releasing reference */
627 	wlan_objmgr_pdev_release_ref(pdev, WLAN_OBJMGR_ID);
628 	return QDF_STATUS_SUCCESS;
629 }
630 
631 void *wlan_objmgr_pdev_get_comp_private_obj(
632 		struct wlan_objmgr_pdev *pdev,
633 		enum wlan_umac_comp_id id)
634 {
635 	void *comp_priv_obj;
636 
637 	/* component id is invalid */
638 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
639 		QDF_BUG(0);
640 		return NULL;
641 	}
642 
643 	if (!pdev) {
644 		QDF_BUG(0);
645 		return NULL;
646 	}
647 
648 	comp_priv_obj = pdev->pdev_comp_priv_obj[id];
649 
650 	return comp_priv_obj;
651 }
652 
653 qdf_export_symbol(wlan_objmgr_pdev_get_comp_private_obj);
654 
655 void wlan_objmgr_pdev_get_ref(struct wlan_objmgr_pdev *pdev,
656 			      wlan_objmgr_ref_dbgid id)
657 {
658 	if (!pdev) {
659 		obj_mgr_err("pdev obj is NULL");
660 		QDF_ASSERT(0);
661 		return;
662 	}
663 	qdf_atomic_inc(&pdev->pdev_objmgr.ref_cnt);
664 	qdf_atomic_inc(&pdev->pdev_objmgr.ref_id_dbg[id]);
665 }
666 
667 qdf_export_symbol(wlan_objmgr_pdev_get_ref);
668 
669 QDF_STATUS wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev *pdev,
670 					wlan_objmgr_ref_dbgid id)
671 {
672 	uint8_t pdev_id;
673 
674 	if (!pdev) {
675 		obj_mgr_err("pdev obj is NULL");
676 		QDF_ASSERT(0);
677 		return QDF_STATUS_E_FAILURE;
678 	}
679 
680 	wlan_pdev_obj_lock(pdev);
681 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
682 	if (pdev->obj_state != WLAN_OBJ_STATE_CREATED) {
683 		wlan_pdev_obj_unlock(pdev);
684 		if (pdev->pdev_objmgr.print_cnt++ <=
685 				WLAN_OBJMGR_RATELIMIT_THRESH)
686 			obj_mgr_err(
687 			"[Ref id: %d] pdev [%d] is not in Created(st:%d)",
688 					id, pdev_id, pdev->obj_state);
689 		return QDF_STATUS_E_RESOURCES;
690 	}
691 
692 	wlan_objmgr_pdev_get_ref(pdev, id);
693 	wlan_pdev_obj_unlock(pdev);
694 
695 	return QDF_STATUS_SUCCESS;
696 }
697 
698 qdf_export_symbol(wlan_objmgr_pdev_try_get_ref);
699 
700 void wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev *pdev,
701 				  wlan_objmgr_ref_dbgid id)
702 {
703 	uint8_t pdev_id;
704 
705 	if (!pdev) {
706 		obj_mgr_err("pdev obj is NULL");
707 		QDF_ASSERT(0);
708 		return;
709 	}
710 
711 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
712 
713 	if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_id_dbg[id])) {
714 		obj_mgr_err("pdev (id:%d)ref cnt was not taken by %d",
715 			    pdev_id, id);
716 		wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg,
717 					  QDF_TRACE_LEVEL_FATAL);
718 		WLAN_OBJMGR_BUG(0);
719 		return;
720 	}
721 
722 	if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_cnt)) {
723 		obj_mgr_err("pdev ref cnt is 0: pdev-id:%d", pdev_id);
724 		WLAN_OBJMGR_BUG(0);
725 		return;
726 	}
727 
728 	qdf_atomic_dec(&pdev->pdev_objmgr.ref_id_dbg[id]);
729 	/* Decrement ref count, free pdev, if ref count == 0 */
730 	if (qdf_atomic_dec_and_test(&pdev->pdev_objmgr.ref_cnt))
731 		wlan_objmgr_pdev_obj_destroy(pdev);
732 }
733 
734 qdf_export_symbol(wlan_objmgr_pdev_release_ref);
735 
736 #ifdef WLAN_OBJMGR_REF_ID_TRACE
737 struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev_debug(
738 		struct wlan_objmgr_pdev *pdev,
739 		wlan_objmgr_ref_dbgid dbg_id,
740 		const char *func, int line)
741 {
742 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
743 	qdf_list_t *vdev_list = NULL;
744 	struct wlan_objmgr_vdev *vdev;
745 	qdf_list_node_t *node = NULL;
746 	qdf_list_node_t *prev_node = NULL;
747 
748 	wlan_pdev_obj_lock(pdev);
749 
750 	/* VDEV list */
751 	vdev_list = &objmgr->wlan_vdev_list;
752 	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
753 		wlan_pdev_obj_unlock(pdev);
754 		return NULL;
755 	}
756 
757 	do {
758 		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
759 					vdev_node);
760 		if (wlan_objmgr_vdev_try_get_ref_debug(vdev,
761 						       dbg_id, func, line) ==
762 						QDF_STATUS_SUCCESS) {
763 			wlan_pdev_obj_unlock(pdev);
764 			return vdev;
765 		}
766 
767 		prev_node = node;
768 	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
769 						QDF_STATUS_SUCCESS);
770 
771 	wlan_pdev_obj_unlock(pdev);
772 
773 	return NULL;
774 }
775 
776 qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev_debug);
777 #else
778 struct wlan_objmgr_vdev *wlan_objmgr_pdev_get_first_vdev(
779 		struct wlan_objmgr_pdev *pdev,
780 		wlan_objmgr_ref_dbgid dbg_id)
781 {
782 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
783 	qdf_list_t *vdev_list = NULL;
784 	struct wlan_objmgr_vdev *vdev;
785 	qdf_list_node_t *node = NULL;
786 	qdf_list_node_t *prev_node = NULL;
787 
788 	wlan_pdev_obj_lock(pdev);
789 
790 	/* VDEV list */
791 	vdev_list = &objmgr->wlan_vdev_list;
792 	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
793 		wlan_pdev_obj_unlock(pdev);
794 		return NULL;
795 	}
796 
797 	do {
798 		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
799 					vdev_node);
800 		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
801 						QDF_STATUS_SUCCESS) {
802 			wlan_pdev_obj_unlock(pdev);
803 			return vdev;
804 		}
805 
806 		prev_node = node;
807 	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
808 						QDF_STATUS_SUCCESS);
809 
810 	wlan_pdev_obj_unlock(pdev);
811 
812 	return NULL;
813 }
814 
815 qdf_export_symbol(wlan_objmgr_pdev_get_first_vdev);
816 #endif
817 
818 #ifdef WLAN_OBJMGR_REF_ID_TRACE
819 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_debug(
820 			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
821 			wlan_objmgr_ref_dbgid dbg_id,
822 			const char *func, int line)
823 {
824 	struct wlan_objmgr_vdev *vdev;
825 	struct wlan_objmgr_vdev *vdev_next;
826 	struct wlan_objmgr_pdev_objmgr *objmgr;
827 	qdf_list_t *vdev_list;
828 
829 	wlan_pdev_obj_lock(pdev);
830 
831 	objmgr = &pdev->pdev_objmgr;
832 	vdev_list = &objmgr->wlan_vdev_list;
833 	/* Get first vdev */
834 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
835 	/**
836 	 * Iterate through pdev's vdev list, till vdev id matches with
837 	 * entry of vdev list
838 	 */
839 	while (vdev) {
840 		if (wlan_vdev_get_id(vdev) == vdev_id) {
841 			if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id,
842 							       func, line) !=
843 				QDF_STATUS_SUCCESS)
844 				vdev = NULL;
845 
846 			wlan_pdev_obj_unlock(pdev);
847 			return vdev;
848 		}
849 		/* get next vdev */
850 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
851 		vdev = vdev_next;
852 	}
853 	wlan_pdev_obj_unlock(pdev);
854 	return NULL;
855 }
856 
857 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_debug);
858 #else
859 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev(
860 			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
861 			wlan_objmgr_ref_dbgid dbg_id)
862 {
863 	struct wlan_objmgr_vdev *vdev;
864 	struct wlan_objmgr_vdev *vdev_next;
865 	struct wlan_objmgr_pdev_objmgr *objmgr;
866 	qdf_list_t *vdev_list;
867 
868 	wlan_pdev_obj_lock(pdev);
869 
870 	objmgr = &pdev->pdev_objmgr;
871 	vdev_list = &objmgr->wlan_vdev_list;
872 	/* Get first vdev */
873 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
874 	/**
875 	 * Iterate through pdev's vdev list, till vdev id matches with
876 	 * entry of vdev list
877 	 */
878 	while (vdev) {
879 		if (wlan_vdev_get_id(vdev) == vdev_id) {
880 			if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) !=
881 							QDF_STATUS_SUCCESS)
882 				vdev = NULL;
883 
884 			wlan_pdev_obj_unlock(pdev);
885 			return vdev;
886 		}
887 		/* get next vdev */
888 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
889 		vdev = vdev_next;
890 	}
891 	wlan_pdev_obj_unlock(pdev);
892 	return NULL;
893 }
894 
895 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev);
896 #endif
897 
898 #ifdef WLAN_OBJMGR_REF_ID_TRACE
899 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug(
900 			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
901 			wlan_objmgr_ref_dbgid dbg_id,
902 			const char *func, int line)
903 {
904 	struct wlan_objmgr_vdev *vdev;
905 	struct wlan_objmgr_vdev *vdev_next;
906 	struct wlan_objmgr_pdev_objmgr *objmgr;
907 	qdf_list_t *vdev_list;
908 
909 	wlan_pdev_obj_lock(pdev);
910 
911 	objmgr = &pdev->pdev_objmgr;
912 	vdev_list = &objmgr->wlan_vdev_list;
913 	/* Get first vdev */
914 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
915 	/**
916 	 * Iterate through pdev's vdev list, till vdev id matches with
917 	 * entry of vdev list
918 	 */
919 	while (vdev) {
920 		if (wlan_vdev_get_id(vdev) == vdev_id) {
921 			wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id,
922 						       func, line);
923 			wlan_pdev_obj_unlock(pdev);
924 
925 			return vdev;
926 		}
927 		/* get next vdev */
928 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
929 		vdev = vdev_next;
930 	}
931 	wlan_pdev_obj_unlock(pdev);
932 
933 	return NULL;
934 }
935 
936 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state_debug);
937 #else
938 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_pdev_no_state(
939 			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
940 			wlan_objmgr_ref_dbgid dbg_id)
941 {
942 	struct wlan_objmgr_vdev *vdev;
943 	struct wlan_objmgr_vdev *vdev_next;
944 	struct wlan_objmgr_pdev_objmgr *objmgr;
945 	qdf_list_t *vdev_list;
946 
947 	wlan_pdev_obj_lock(pdev);
948 
949 	objmgr = &pdev->pdev_objmgr;
950 	vdev_list = &objmgr->wlan_vdev_list;
951 	/* Get first vdev */
952 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
953 	/**
954 	 * Iterate through pdev's vdev list, till vdev id matches with
955 	 * entry of vdev list
956 	 */
957 	while (vdev) {
958 		if (wlan_vdev_get_id(vdev) == vdev_id) {
959 			wlan_objmgr_vdev_get_ref(vdev, dbg_id);
960 			wlan_pdev_obj_unlock(pdev);
961 
962 			return vdev;
963 		}
964 		/* get next vdev */
965 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
966 		vdev = vdev_next;
967 	}
968 	wlan_pdev_obj_unlock(pdev);
969 
970 	return NULL;
971 }
972 
973 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_pdev_no_state);
974 #endif
975 
976 #ifdef WLAN_OBJMGR_REF_ID_TRACE
977 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug(
978 		struct wlan_objmgr_pdev *pdev, uint8_t *macaddr,
979 		wlan_objmgr_ref_dbgid dbg_id,
980 		const char *fnc, int ln)
981 {
982 	struct wlan_objmgr_vdev *vdev;
983 	struct wlan_objmgr_vdev *vdev_next;
984 	struct wlan_objmgr_pdev_objmgr *objmgr;
985 	qdf_list_t *vdev_list;
986 
987 	wlan_pdev_obj_lock(pdev);
988 	objmgr = &pdev->pdev_objmgr;
989 	vdev_list = &objmgr->wlan_vdev_list;
990 	/* Get first vdev */
991 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
992 	/**
993 	 * Iterate through pdev's vdev list, till vdev macaddr matches with
994 	 * entry of vdev list
995 	 */
996 	while (vdev) {
997 		if (QDF_IS_STATUS_SUCCESS(
998 		    WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr))) {
999 			if (QDF_IS_STATUS_SUCCESS(
1000 				wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id,
1001 								   fnc, ln))) {
1002 				wlan_pdev_obj_unlock(pdev);
1003 				return vdev;
1004 			}
1005 		}
1006 		/* get next vdev */
1007 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1008 		vdev = vdev_next;
1009 	}
1010 	wlan_pdev_obj_unlock(pdev);
1011 
1012 	return NULL;
1013 }
1014 #else
1015 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev(
1016 		struct wlan_objmgr_pdev *pdev, uint8_t *macaddr,
1017 		wlan_objmgr_ref_dbgid dbg_id)
1018 {
1019 	struct wlan_objmgr_vdev *vdev;
1020 	struct wlan_objmgr_vdev *vdev_next;
1021 	struct wlan_objmgr_pdev_objmgr *objmgr;
1022 	qdf_list_t *vdev_list;
1023 
1024 	wlan_pdev_obj_lock(pdev);
1025 	objmgr = &pdev->pdev_objmgr;
1026 	vdev_list = &objmgr->wlan_vdev_list;
1027 	/* Get first vdev */
1028 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1029 	/**
1030 	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1031 	 * entry of vdev list
1032 	 */
1033 	while (vdev) {
1034 		if (QDF_IS_STATUS_SUCCESS(
1035 		    WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr))) {
1036 			if (QDF_IS_STATUS_SUCCESS(
1037 				wlan_objmgr_vdev_try_get_ref(vdev, dbg_id))) {
1038 				wlan_pdev_obj_unlock(pdev);
1039 				return vdev;
1040 			}
1041 		}
1042 		/* get next vdev */
1043 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1044 		vdev = vdev_next;
1045 	}
1046 	wlan_pdev_obj_unlock(pdev);
1047 
1048 	return NULL;
1049 }
1050 #endif
1051 
1052 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1053 struct wlan_objmgr_vdev
1054 	*wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug(
1055 		struct wlan_objmgr_pdev *pdev, uint8_t *macaddr,
1056 		wlan_objmgr_ref_dbgid dbg_id,
1057 		const char *func, int line)
1058 {
1059 	struct wlan_objmgr_vdev *vdev;
1060 	struct wlan_objmgr_vdev *vdev_next;
1061 	struct wlan_objmgr_pdev_objmgr *objmgr;
1062 	qdf_list_t *vdev_list;
1063 
1064 	wlan_pdev_obj_lock(pdev);
1065 	objmgr = &pdev->pdev_objmgr;
1066 	vdev_list = &objmgr->wlan_vdev_list;
1067 	/* Get first vdev */
1068 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1069 	/**
1070 	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1071 	 * entry of vdev list
1072 	 */
1073 	while (vdev) {
1074 		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
1075 					== QDF_STATUS_SUCCESS) {
1076 			wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id,
1077 						       func, line);
1078 			wlan_pdev_obj_unlock(pdev);
1079 
1080 			return vdev;
1081 		}
1082 		/* get next vdev */
1083 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1084 		vdev = vdev_next;
1085 	}
1086 	wlan_pdev_obj_unlock(pdev);
1087 
1088 	return NULL;
1089 }
1090 #else
1091 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(
1092 		struct wlan_objmgr_pdev *pdev, uint8_t *macaddr,
1093 		wlan_objmgr_ref_dbgid dbg_id)
1094 {
1095 	struct wlan_objmgr_vdev *vdev;
1096 	struct wlan_objmgr_vdev *vdev_next;
1097 	struct wlan_objmgr_pdev_objmgr *objmgr;
1098 	qdf_list_t *vdev_list;
1099 
1100 	wlan_pdev_obj_lock(pdev);
1101 	objmgr = &pdev->pdev_objmgr;
1102 	vdev_list = &objmgr->wlan_vdev_list;
1103 	/* Get first vdev */
1104 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1105 	/**
1106 	 * Iterate through pdev's vdev list, till vdev macaddr matches with
1107 	 * entry of vdev list
1108 	 */
1109 	while (vdev) {
1110 		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
1111 					== QDF_STATUS_SUCCESS) {
1112 			wlan_objmgr_vdev_get_ref(vdev, dbg_id);
1113 			wlan_pdev_obj_unlock(pdev);
1114 
1115 			return vdev;
1116 		}
1117 		/* get next vdev */
1118 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1119 		vdev = vdev_next;
1120 	}
1121 	wlan_pdev_obj_unlock(pdev);
1122 
1123 	return NULL;
1124 }
1125 #endif
1126 
1127 #ifdef WLAN_OBJMGR_DEBUG
1128 void wlan_print_pdev_info(struct wlan_objmgr_pdev *pdev)
1129 {
1130 	struct wlan_objmgr_pdev_objmgr *pdev_objmgr;
1131 	struct wlan_objmgr_vdev *vdev;
1132 	struct wlan_objmgr_vdev *vdev_next;
1133 	qdf_list_t *vdev_list;
1134 	uint16_t index = 0;
1135 
1136 	pdev_objmgr = &pdev->pdev_objmgr;
1137 
1138 	obj_mgr_debug("pdev: %pK", pdev);
1139 	obj_mgr_debug("wlan_pdev_id: %d", pdev_objmgr->wlan_pdev_id);
1140 	obj_mgr_debug("wlan_vdev_count: %d", pdev_objmgr->wlan_vdev_count);
1141 	obj_mgr_debug("max_vdev_count: %d", pdev_objmgr->max_vdev_count);
1142 	obj_mgr_debug("wlan_peer_count: %d", pdev_objmgr->wlan_peer_count);
1143 	obj_mgr_debug("max_peer_count: %d", pdev_objmgr->max_peer_count);
1144 	obj_mgr_debug("temp_peer_count: %d", pdev_objmgr->temp_peer_count);
1145 	obj_mgr_debug("wlan_psoc: %pK", pdev_objmgr->wlan_psoc);
1146 	obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&pdev_objmgr->ref_cnt));
1147 
1148 	wlan_pdev_obj_lock(pdev);
1149 	vdev_list = &pdev_objmgr->wlan_vdev_list;
1150 	/* Get first vdev */
1151 	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
1152 
1153 	while (vdev) {
1154 		obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev);
1155 		wlan_print_vdev_info(vdev);
1156 		index++;
1157 		/* get next vdev */
1158 		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
1159 		vdev = vdev_next;
1160 	}
1161 	wlan_pdev_obj_unlock(pdev);
1162 }
1163 
1164 qdf_export_symbol(wlan_print_pdev_info);
1165 #endif
1166