xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_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 any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 
16  */
17  /**
18   * DOC: Public APIs to perform operations on Global objects
19   */
20 #include <wlan_objmgr_cmn.h>
21 #include <wlan_objmgr_global_obj.h>
22 #include <wlan_objmgr_psoc_obj.h>
23 #include <wlan_objmgr_pdev_obj.h>
24 #include <wlan_objmgr_vdev_obj.h>
25 #include <wlan_objmgr_peer_obj.h>
26 #include <wlan_objmgr_debug.h>
27 #include <qdf_mem.h>
28 #include <qdf_module.h>
29 #include "wlan_objmgr_global_obj_i.h"
30 #include "wlan_objmgr_psoc_obj_i.h"
31 #include "wlan_objmgr_pdev_obj_i.h"
32 #include "wlan_objmgr_vdev_obj_i.h"
33 #include <wlan_utility.h>
34 #include <wlan_osif_priv.h>
35 
36 
37 /**
38  ** APIs to Create/Delete Global object APIs
39  */
40 
41 static QDF_STATUS wlan_objmgr_vdev_object_status(
42 		struct wlan_objmgr_vdev *vdev)
43 {
44 	uint8_t id;
45 	QDF_STATUS status = QDF_STATUS_SUCCESS;
46 
47 	wlan_vdev_obj_lock(vdev);
48 
49 	/* Iterate through all components to derive the object status */
50 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
51 		/* If component disabled, Ignore */
52 		if (vdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
53 			continue;
54 		/*
55 		 * If component operates in Async, status is Partially created,
56 		 * break
57 		 */
58 		} else if (vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
59 			if (!vdev->vdev_comp_priv_obj[id]) {
60 				status = QDF_STATUS_COMP_ASYNC;
61 				break;
62 			}
63 		/*
64 		 * If component failed to allocate its object, treat it as
65 		 * failure, complete object need to be cleaned up
66 		 */
67 		} else if ((vdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
68 			(vdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
69 			status = QDF_STATUS_E_FAILURE;
70 			break;
71 		}
72 	}
73 	wlan_vdev_obj_unlock(vdev);
74 
75 	return status;
76 }
77 
78 static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev)
79 {
80 	struct wlan_objmgr_pdev *pdev;
81 	struct wlan_objmgr_psoc *psoc;
82 
83 	if (!vdev) {
84 		obj_mgr_err("vdev is NULL");
85 		return QDF_STATUS_E_FAILURE;
86 	}
87 	/* if PDEV is NULL, return */
88 	pdev = wlan_vdev_get_pdev(vdev);
89 	if (!pdev) {
90 		obj_mgr_err("pdev is NULL for vdev-id: %d",
91 			vdev->vdev_objmgr.vdev_id);
92 		return QDF_STATUS_E_FAILURE;
93 	}
94 	psoc = wlan_pdev_get_psoc(pdev);
95 	if (!psoc) {
96 		obj_mgr_err("psoc is NULL in pdev");
97 		return QDF_STATUS_E_FAILURE;
98 	}
99 
100 	/* Detach VDEV from PDEV VDEV's list */
101 	if (wlan_objmgr_pdev_vdev_detach(pdev, vdev) ==
102 					QDF_STATUS_E_FAILURE)
103 		return QDF_STATUS_E_FAILURE;
104 
105 	/* Detach VDEV from PSOC VDEV's list */
106 	if (wlan_objmgr_psoc_vdev_detach(psoc, vdev) ==
107 					 QDF_STATUS_E_FAILURE)
108 		return QDF_STATUS_E_FAILURE;
109 
110 	wlan_objmgr_vdev_trace_del_ref_list(vdev);
111 	wlan_objmgr_vdev_trace_deinit_lock(vdev);
112 	qdf_spinlock_destroy(&vdev->vdev_lock);
113 
114 	qdf_mem_free(vdev->vdev_mlme.bss_chan);
115 	qdf_mem_free(vdev->vdev_mlme.des_chan);
116 	qdf_mem_free(vdev);
117 
118 	return QDF_STATUS_SUCCESS;
119 
120 }
121 
122 static struct vdev_osif_priv *wlan_objmgr_vdev_get_osif_priv(
123 						struct wlan_objmgr_vdev *vdev)
124 {
125 	struct vdev_osif_priv *osif_priv;
126 
127 	/* private data area immediately follows the struct wlan_objmgr_vdev */
128 	osif_priv = (struct vdev_osif_priv *)(vdev + 1);
129 
130 	return osif_priv;
131 }
132 
133 struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
134 			struct wlan_objmgr_pdev *pdev,
135 			struct wlan_vdev_create_params *params)
136 {
137 	struct wlan_objmgr_vdev *vdev;
138 	struct wlan_objmgr_psoc *psoc;
139 	uint8_t id;
140 	wlan_objmgr_vdev_create_handler handler;
141 	wlan_objmgr_vdev_status_handler stat_handler;
142 	void *arg;
143 	QDF_STATUS obj_status;
144 
145 	if (!pdev) {
146 		obj_mgr_err("pdev is NULL");
147 		return NULL;
148 	}
149 	psoc = wlan_pdev_get_psoc(pdev);
150 	/* PSOC is NULL */
151 	if (!psoc) {
152 		obj_mgr_err("psoc is NULL for pdev-id:%d",
153 			pdev->pdev_objmgr.wlan_pdev_id);
154 		return NULL;
155 	}
156 	/* Allocate vdev object memory */
157 	vdev = qdf_mem_malloc(sizeof(*vdev) + params->size_vdev_priv);
158 	if (!vdev)
159 		return NULL;
160 	vdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
161 
162 	vdev->vdev_mlme.bss_chan = qdf_mem_malloc(sizeof(struct wlan_channel));
163 	if (!vdev->vdev_mlme.bss_chan) {
164 		qdf_mem_free(vdev);
165 		return NULL;
166 	}
167 
168 	vdev->vdev_mlme.des_chan = qdf_mem_malloc(sizeof(struct wlan_channel));
169 	if (!vdev->vdev_mlme.des_chan) {
170 		qdf_mem_free(vdev->vdev_mlme.bss_chan);
171 		qdf_mem_free(vdev);
172 		return NULL;
173 	}
174 
175 	wlan_objmgr_vdev_trace_init_lock(vdev);
176 	/* Initialize spinlock */
177 	qdf_spinlock_create(&vdev->vdev_lock);
178 	/* Attach VDEV to PSOC VDEV's list */
179 	if (wlan_objmgr_psoc_vdev_attach(psoc, vdev) !=
180 				QDF_STATUS_SUCCESS) {
181 		obj_mgr_err("psoc vdev attach failed for vdev-id:%d",
182 					vdev->vdev_objmgr.vdev_id);
183 		qdf_mem_free(vdev->vdev_mlme.bss_chan);
184 		qdf_mem_free(vdev->vdev_mlme.des_chan);
185 		qdf_spinlock_destroy(&vdev->vdev_lock);
186 		wlan_objmgr_vdev_trace_deinit_lock(vdev);
187 		qdf_mem_free(vdev);
188 		return NULL;
189 	}
190 	/* Store pdev in vdev */
191 	wlan_vdev_set_pdev(vdev, pdev);
192 	/* Attach vdev to PDEV */
193 	if (wlan_objmgr_pdev_vdev_attach(pdev, vdev) !=
194 				QDF_STATUS_SUCCESS) {
195 		obj_mgr_err("pdev vdev attach failed for vdev-id:%d",
196 				vdev->vdev_objmgr.vdev_id);
197 		wlan_objmgr_psoc_vdev_detach(psoc, vdev);
198 		qdf_mem_free(vdev->vdev_mlme.bss_chan);
199 		qdf_mem_free(vdev->vdev_mlme.des_chan);
200 		qdf_spinlock_destroy(&vdev->vdev_lock);
201 		wlan_objmgr_vdev_trace_deinit_lock(vdev);
202 		qdf_mem_free(vdev);
203 		return NULL;
204 	}
205 	/* set opmode */
206 	wlan_vdev_mlme_set_opmode(vdev, params->opmode);
207 	/* set MAC address */
208 	wlan_vdev_mlme_set_macaddr(vdev, params->macaddr);
209 	/* set MAT address */
210 	wlan_vdev_mlme_set_mataddr(vdev, params->mataddr);
211 	/* set MLD address */
212 	wlan_vdev_mlme_set_mldaddr(vdev, params->mldaddr);
213 	/* set link address */
214 	wlan_vdev_mlme_set_linkaddr(vdev, params->macaddr);
215 	/* Set create flags */
216 	vdev->vdev_objmgr.c_flags = params->flags;
217 	/* store os-specific pointer */
218 	vdev->vdev_nif.osdev = wlan_objmgr_vdev_get_osif_priv(vdev);
219 
220 	/* peer count to 0 */
221 	vdev->vdev_objmgr.wlan_peer_count = 0;
222 	qdf_atomic_init(&vdev->vdev_objmgr.ref_cnt);
223 	vdev->vdev_objmgr.print_cnt = 0;
224 	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
225 	/* Initialize max peer count based on opmode type */
226 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
227 		vdev->vdev_objmgr.max_peer_count = WLAN_UMAC_MAX_STA_PEERS;
228 	else
229 		vdev->vdev_objmgr.max_peer_count =
230 				wlan_pdev_get_max_peer_count(pdev);
231 
232 	if (params->legacy_osif)
233 		vdev->vdev_nif.osdev->legacy_osif_priv = params->legacy_osif;
234 
235 	/* Initialize peer list */
236 	qdf_list_create(&vdev->vdev_objmgr.wlan_peer_list,
237 			vdev->vdev_objmgr.max_peer_count +
238 			WLAN_MAX_PDEV_TEMP_PEERS);
239 	/* TODO init other parameters */
240 
241 	/* Invoke registered create handlers */
242 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
243 		handler = g_umac_glb_obj->vdev_create_handler[id];
244 		arg = g_umac_glb_obj->vdev_create_handler_arg[id];
245 		if (handler)
246 			vdev->obj_status[id] = handler(vdev, arg);
247 		else
248 			vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
249 	}
250 
251 	/* Derive object status */
252 	obj_status = wlan_objmgr_vdev_object_status(vdev);
253 
254 	if (obj_status == QDF_STATUS_SUCCESS) {
255 		/* Object status is SUCCESS, Object is created */
256 		vdev->obj_state = WLAN_OBJ_STATE_CREATED;
257 		/* Invoke component registered status handlers */
258 		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
259 			stat_handler = g_umac_glb_obj->vdev_status_handler[id];
260 			arg = g_umac_glb_obj->vdev_status_handler_arg[id];
261 			if (stat_handler) {
262 				stat_handler(vdev, arg,
263 					     QDF_STATUS_SUCCESS);
264 			}
265 		}
266 	/*
267 	 * Few components operates in Asynchrous communction, Object state
268 	 * partially created
269 	 */
270 	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
271 		vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
272 	/* Component object failed to be created, clean up the object */
273 	} else if (obj_status == QDF_STATUS_E_FAILURE) {
274 		/* Clean up the psoc */
275 		obj_mgr_err("VDEV comp objects creation failed for vdev-id:%d",
276 			vdev->vdev_objmgr.vdev_id);
277 		wlan_objmgr_vdev_obj_delete(vdev);
278 		return NULL;
279 	}
280 
281 	wlan_minidump_log(vdev, sizeof(*vdev), psoc,
282 			  WLAN_MD_OBJMGR_VDEV, "wlan_objmgr_vdev");
283 
284 	obj_mgr_debug("Created vdev %d", vdev->vdev_objmgr.vdev_id);
285 
286 	return vdev;
287 }
288 qdf_export_symbol(wlan_objmgr_vdev_obj_create);
289 
290 static QDF_STATUS wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev *vdev)
291 {
292 	uint8_t id;
293 	wlan_objmgr_vdev_destroy_handler handler;
294 	QDF_STATUS obj_status;
295 	void *arg;
296 	uint8_t vdev_id;
297 
298 	if (!vdev) {
299 		obj_mgr_err("vdev is NULL");
300 		return QDF_STATUS_E_FAILURE;
301 	}
302 	wlan_objmgr_notify_destroy(vdev, WLAN_VDEV_OP);
303 
304 	vdev_id = wlan_vdev_get_id(vdev);
305 
306 	obj_mgr_debug("Physically deleting vdev %d", vdev_id);
307 
308 	if (vdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
309 		obj_mgr_alert("VDEV object delete is not invoked vdevid:%d objstate:%d",
310 			      wlan_vdev_get_id(vdev), vdev->obj_state);
311 		WLAN_OBJMGR_BUG(0);
312 		return QDF_STATUS_E_FAILURE;
313 	}
314 
315 	wlan_minidump_remove(vdev, sizeof(*vdev), wlan_vdev_get_psoc(vdev),
316 			     WLAN_MD_OBJMGR_VDEV, "wlan_objmgr_vdev");
317 
318 	/* Invoke registered destroy handlers */
319 	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
320 		handler = g_umac_glb_obj->vdev_destroy_handler[id];
321 		arg = g_umac_glb_obj->vdev_destroy_handler_arg[id];
322 		if (handler &&
323 		    (vdev->obj_status[id] == QDF_STATUS_SUCCESS ||
324 		     vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC))
325 			vdev->obj_status[id] = handler(vdev, arg);
326 		else
327 			vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
328 	}
329 	/* Derive object status */
330 	obj_status = wlan_objmgr_vdev_object_status(vdev);
331 
332 	if (obj_status == QDF_STATUS_E_FAILURE) {
333 		obj_mgr_err("VDEV object deletion failed: vdev-id: %d",
334 				vdev_id);
335 		/* Ideally should not happen */
336 		/* This leads to memleak ??? how to handle */
337 		QDF_BUG(0);
338 		return QDF_STATUS_E_FAILURE;
339 	}
340 
341 	/* Deletion is in progress */
342 	if (obj_status == QDF_STATUS_COMP_ASYNC) {
343 		vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
344 		return QDF_STATUS_COMP_ASYNC;
345 	}
346 
347 	/* Free VDEV object */
348 	return wlan_objmgr_vdev_obj_free(vdev);
349 }
350 
351 QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev)
352 {
353 	uint8_t print_idx;
354 
355 	if (!vdev) {
356 		obj_mgr_err("vdev is NULL");
357 		return QDF_STATUS_E_FAILURE;
358 	}
359 
360 	obj_mgr_debug("Logically deleting vdev %d", vdev->vdev_objmgr.vdev_id);
361 
362 	print_idx = qdf_get_pidx();
363 	wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
364 				  QDF_TRACE_LEVEL_DEBUG);
365 	/*
366 	 * Update VDEV object state to LOGICALLY DELETED
367 	 * It prevents further access of this object
368 	 */
369 	wlan_vdev_obj_lock(vdev);
370 	vdev->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
371 	wlan_vdev_obj_unlock(vdev);
372 	wlan_objmgr_notify_log_delete(vdev, WLAN_VDEV_OP);
373 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
374 
375 	return QDF_STATUS_SUCCESS;
376 }
377 qdf_export_symbol(wlan_objmgr_vdev_obj_delete);
378 
379 /**
380  ** APIs to attach/detach component objects
381  */
382 QDF_STATUS wlan_objmgr_vdev_component_obj_attach(
383 		struct wlan_objmgr_vdev *vdev,
384 		enum wlan_umac_comp_id id,
385 		void *comp_priv_obj,
386 		QDF_STATUS status)
387 {
388 	wlan_objmgr_vdev_status_handler stat_handler;
389 	void *arg;
390 	uint8_t i;
391 	QDF_STATUS obj_status;
392 
393 	/* component id is invalid */
394 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
395 		return QDF_STATUS_MAXCOMP_FAIL;
396 
397 	wlan_vdev_obj_lock(vdev);
398 	/* If there is a valid entry, return failure */
399 	if (vdev->vdev_comp_priv_obj[id]) {
400 		wlan_vdev_obj_unlock(vdev);
401 		return QDF_STATUS_E_FAILURE;
402 	}
403 	/* Save component's pointer and status */
404 	vdev->vdev_comp_priv_obj[id] = comp_priv_obj;
405 	vdev->obj_status[id] = status;
406 	wlan_vdev_obj_unlock(vdev);
407 	if (vdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
408 		return QDF_STATUS_SUCCESS;
409 	/*
410 	 * If VDEV object status is partially created means, this API is
411 	 * invoked with differnt context, this block should be executed for
412 	 * async components only
413 	 */
414 	/* Derive status */
415 	obj_status = wlan_objmgr_vdev_object_status(vdev);
416 	/* STATUS_SUCCESS means, object is CREATED */
417 	if (obj_status == QDF_STATUS_SUCCESS)
418 		vdev->obj_state = WLAN_OBJ_STATE_CREATED;
419 	/*
420 	 * update state as CREATION failed, caller has to delete the
421 	 * VDEV object
422 	 */
423 	else if (obj_status == QDF_STATUS_E_FAILURE)
424 		vdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
425 	/* Notify components about the CREATION success/failure */
426 	if ((obj_status == QDF_STATUS_SUCCESS) ||
427 	    (obj_status == QDF_STATUS_E_FAILURE)) {
428 		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
429 			stat_handler = g_umac_glb_obj->vdev_status_handler[i];
430 			arg = g_umac_glb_obj->vdev_status_handler_arg[i];
431 			if (stat_handler)
432 				stat_handler(vdev, arg, obj_status);
433 		}
434 	}
435 	return QDF_STATUS_SUCCESS;
436 }
437 qdf_export_symbol(wlan_objmgr_vdev_component_obj_attach);
438 
439 QDF_STATUS wlan_objmgr_vdev_component_obj_detach(
440 		struct wlan_objmgr_vdev *vdev,
441 		enum wlan_umac_comp_id id,
442 		void *comp_priv_obj)
443 {
444 	QDF_STATUS obj_status;
445 
446 	/* component id is invalid */
447 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
448 		return QDF_STATUS_MAXCOMP_FAIL;
449 
450 	wlan_vdev_obj_lock(vdev);
451 	/* If there is a valid entry, return failure */
452 	if (vdev->vdev_comp_priv_obj[id] != comp_priv_obj) {
453 		vdev->obj_status[id] = QDF_STATUS_E_FAILURE;
454 		wlan_vdev_obj_unlock(vdev);
455 		return QDF_STATUS_E_FAILURE;
456 	}
457 	/* Reset pointers to NULL, update the status*/
458 	vdev->vdev_comp_priv_obj[id] = NULL;
459 	vdev->obj_status[id] = QDF_STATUS_SUCCESS;
460 	wlan_vdev_obj_unlock(vdev);
461 
462 	/**
463 	 *If VDEV object status is partially destroyed means, this API is
464 	 * invoked with differnt context, this block should be executed for
465 	 * async components only
466 	 */
467 	if ((vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
468 	    (vdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
469 		/* Derive object status */
470 		obj_status = wlan_objmgr_vdev_object_status(vdev);
471 		if (obj_status == QDF_STATUS_SUCCESS) {
472 			/*
473 			 * Update the status as Deleted, if full object
474 			 * deletion is in progress
475 			 */
476 			if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
477 				vdev->obj_state = WLAN_OBJ_STATE_DELETED;
478 			/*
479 			 * Move to creation state, since this component
480 			 * deletion alone requested
481 			 */
482 			else if (vdev->obj_state ==
483 					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
484 				vdev->obj_state = WLAN_OBJ_STATE_CREATED;
485 		/* Object status is failure */
486 		} else if (obj_status == QDF_STATUS_E_FAILURE) {
487 			/*
488 			 * Update the status as Deletion failed, if full object
489 			 * deletion is in progress
490 			 */
491 			if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
492 				vdev->obj_state =
493 					WLAN_OBJ_STATE_DELETION_FAILED;
494 			/* Move to creation state, since this component
495 			deletion alone requested (do not block other
496 			components) */
497 			else if (vdev->obj_state ==
498 					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
499 				vdev->obj_state = WLAN_OBJ_STATE_CREATED;
500 		}
501 		/* Delete vdev object */
502 		if ((obj_status == QDF_STATUS_SUCCESS)  &&
503 		    (vdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
504 			/* Free VDEV object */
505 			return wlan_objmgr_vdev_obj_free(vdev);
506 		}
507 	}
508 	return QDF_STATUS_SUCCESS;
509 }
510 qdf_export_symbol(wlan_objmgr_vdev_component_obj_detach);
511 
512 /**
513  ** APIs to operations on vdev objects
514  */
515 QDF_STATUS wlan_objmgr_iterate_peerobj_list(
516 		struct wlan_objmgr_vdev *vdev,
517 		wlan_objmgr_vdev_op_handler handler,
518 		void *arg, wlan_objmgr_ref_dbgid dbg_id)
519 {
520 	qdf_list_t *peer_list = NULL;
521 	struct wlan_objmgr_peer *peer = NULL;
522 	struct wlan_objmgr_peer *peer_next = NULL;
523 	uint8_t vdev_id;
524 
525 	if (!vdev) {
526 		obj_mgr_err("VDEV is NULL");
527 		return QDF_STATUS_E_FAILURE;
528 	}
529 	wlan_vdev_obj_lock(vdev);
530 	vdev_id = wlan_vdev_get_id(vdev);
531 
532 	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
533 		wlan_vdev_obj_unlock(vdev);
534 		obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d",
535 			    vdev->obj_state, vdev_id);
536 		return QDF_STATUS_E_FAILURE;
537 	}
538 	wlan_objmgr_vdev_get_ref(vdev, dbg_id);
539 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
540 	if (peer_list) {
541 		/* Iterate through VDEV's peer list */
542 		peer = wlan_vdev_peer_list_peek_head(peer_list);
543 		while (peer) {
544 			peer_next = wlan_peer_get_next_peer_of_vdev(peer_list,
545 							       peer);
546 			if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
547 					QDF_STATUS_SUCCESS) {
548 				/* Invoke handler for operation */
549 				handler(vdev, (void *)peer, arg);
550 				wlan_objmgr_peer_release_ref(peer, dbg_id);
551 			}
552 			peer = peer_next;
553 		}
554 	}
555 	wlan_objmgr_vdev_release_ref(vdev, dbg_id);
556 	wlan_vdev_obj_unlock(vdev);
557 	return QDF_STATUS_SUCCESS;
558 }
559 
560 /**
561  ** APIs to get a peer with given mac in a vdev
562  */
563 struct wlan_objmgr_peer *
564 wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev *vdev,
565 				  uint8_t *peer_mac,
566 				  wlan_objmgr_ref_dbgid dbg_id)
567 {
568 	qdf_list_t *peer_list;
569 	struct wlan_objmgr_peer *peer = NULL;
570 	struct wlan_objmgr_peer *peer_next = NULL;
571 	uint8_t vdev_id;
572 
573 	if (!vdev) {
574 		obj_mgr_err("VDEV is NULL");
575 		return NULL;
576 	}
577 	wlan_vdev_obj_lock(vdev);
578 	vdev_id = wlan_vdev_get_id(vdev);
579 
580 	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
581 		wlan_vdev_obj_unlock(vdev);
582 		obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d",
583 			    vdev->obj_state, vdev_id);
584 		return NULL;
585 	}
586 	wlan_objmgr_vdev_get_ref(vdev, dbg_id);
587 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
588 	/* Iterate through VDEV's peer list */
589 	peer = wlan_vdev_peer_list_peek_head(peer_list);
590 	while (peer) {
591 		peer_next = wlan_peer_get_next_peer_of_vdev(peer_list,
592 							    peer);
593 		if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
594 						 QDF_STATUS_SUCCESS) {
595 			if (!WLAN_ADDR_EQ(peer_mac,
596 					  wlan_peer_get_macaddr(peer))) {
597 				wlan_objmgr_vdev_release_ref(vdev,
598 							     dbg_id);
599 				wlan_vdev_obj_unlock(vdev);
600 				return peer;
601 			}
602 			wlan_objmgr_peer_release_ref(peer, dbg_id);
603 		}
604 		peer = peer_next;
605 	}
606 	wlan_objmgr_vdev_release_ref(vdev, dbg_id);
607 	wlan_vdev_obj_unlock(vdev);
608 	return NULL;
609 }
610 
611 qdf_export_symbol(wlan_objmgr_vdev_find_peer_by_mac);
612 
613 /**
614  * wlan_obj_vdev_populate_logically_del_peerlist() - get peer
615  * from vdev peer list
616  * @obj_list: peer object list
617  * @vdev_obj: vdev object mgr substructure
618  * @dbg_id: id of the caller
619  *
620  * API to finds peer object pointer by vdev from peer hash list for a node
621  * which is in logically deleted state
622  *
623  * Caller to free the list allocated in this function
624  *
625  * Return: list of peer pointers
626  *         NULL on FAILURE
627  */
628 static qdf_list_t *wlan_obj_vdev_populate_logically_del_peerlist(
629 				qdf_list_t *obj_list,
630 				struct wlan_objmgr_vdev_objmgr *vdev_obj,
631 				wlan_objmgr_ref_dbgid dbg_id)
632 {
633 	struct wlan_objmgr_peer *peer;
634 	struct wlan_objmgr_peer *peer_next;
635 	struct wlan_logically_del_peer *peer_list;
636 	qdf_list_t *logical_del_peerlist;
637 	bool lock_released = false;
638 
639 	logical_del_peerlist = qdf_mem_malloc(sizeof(*logical_del_peerlist));
640 	if (!logical_del_peerlist)
641 		return NULL;
642 
643 	qdf_list_create(logical_del_peerlist, vdev_obj->max_peer_count);
644 
645 	peer = wlan_vdev_peer_list_peek_head(obj_list);
646 	while (peer) {
647 		wlan_peer_obj_lock(peer);
648 		peer_next = wlan_peer_get_next_peer_of_vdev(obj_list, peer);
649 		if (peer->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED &&
650 		    qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
651 			wlan_objmgr_peer_get_ref(peer, dbg_id);
652 			wlan_peer_obj_unlock(peer);
653 			lock_released = true;
654 
655 			peer_list = qdf_mem_malloc(sizeof(*peer_list));
656 			if (!peer_list) {
657 				wlan_objmgr_peer_release_ref(peer, dbg_id);
658 				WLAN_OBJMGR_BUG(0);
659 				break;
660 			}
661 
662 			peer_list->peer = peer;
663 			qdf_list_insert_front(logical_del_peerlist,
664 					      &peer_list->list);
665 		}
666 
667 		if (!lock_released)
668 			wlan_peer_obj_unlock(peer);
669 
670 		peer = peer_next;
671 		lock_released = false;
672 	}
673 
674 	/* Not found, return NULL */
675 	if (qdf_list_empty(logical_del_peerlist)) {
676 		qdf_mem_free(logical_del_peerlist);
677 		return NULL;
678 	}
679 
680 	return logical_del_peerlist;
681 }
682 
683 qdf_list_t *wlan_objmgr_vdev_get_log_del_peer_list(
684 		struct wlan_objmgr_vdev *vdev,
685 		wlan_objmgr_ref_dbgid dbg_id)
686 {
687 	qdf_list_t *peer_list;
688 	qdf_list_t *log_del_peer_list = NULL;
689 
690 	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
691 		obj_mgr_err("Invalid state vdev:%d state:%d",
692 			    wlan_vdev_get_id(vdev), vdev->obj_state);
693 		return NULL;
694 	}
695 
696 	wlan_vdev_obj_lock(vdev);
697 	if (vdev->vdev_objmgr.wlan_peer_count == 0) {
698 		wlan_vdev_obj_unlock(vdev);
699 		return NULL;
700 	}
701 
702 	wlan_objmgr_vdev_get_ref(vdev, dbg_id);
703 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
704 	if (peer_list) {
705 		log_del_peer_list =
706 			wlan_obj_vdev_populate_logically_del_peerlist(
707 					peer_list, &vdev->vdev_objmgr,
708 					dbg_id);
709 	}
710 
711 	wlan_objmgr_vdev_release_ref(vdev, dbg_id);
712 	wlan_vdev_obj_unlock(vdev);
713 
714 	return log_del_peer_list;
715 }
716 
717 QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_creation(
718 		struct wlan_objmgr_vdev *vdev,
719 		enum wlan_umac_comp_id id)
720 {
721 	wlan_objmgr_vdev_create_handler handler;
722 	void *arg;
723 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
724 
725 	/* Component id is invalid */
726 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
727 		return QDF_STATUS_MAXCOMP_FAIL;
728 
729 	wlan_vdev_obj_lock(vdev);
730 	/*
731 	 * If component object is already created, delete old
732 	 * component object, then invoke creation
733 	 */
734 	if (vdev->vdev_comp_priv_obj[id]) {
735 		wlan_vdev_obj_unlock(vdev);
736 		return QDF_STATUS_E_FAILURE;
737 	}
738 	wlan_vdev_obj_unlock(vdev);
739 
740 	/* Invoke registered create handlers */
741 	handler = g_umac_glb_obj->vdev_create_handler[id];
742 	arg = g_umac_glb_obj->vdev_create_handler_arg[id];
743 	if (handler)
744 		vdev->obj_status[id] = handler(vdev, arg);
745 	else
746 		return QDF_STATUS_E_FAILURE;
747 
748 	/* If object status is created, then only handle this object status */
749 	if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
750 		/* Derive object status */
751 		obj_status = wlan_objmgr_vdev_object_status(vdev);
752 		/* Move PDEV object state to Partially created state */
753 		if (obj_status == QDF_STATUS_COMP_ASYNC) {
754 			/*TODO atomic */
755 			vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
756 		}
757 	}
758 	return obj_status;
759 }
760 
761 QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_deletion(
762 		struct wlan_objmgr_vdev *vdev,
763 		enum wlan_umac_comp_id id)
764 {
765 	wlan_objmgr_vdev_destroy_handler handler;
766 	void *arg;
767 	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
768 
769 	/* component id is invalid */
770 	if (id >= WLAN_UMAC_MAX_COMPONENTS)
771 		return QDF_STATUS_MAXCOMP_FAIL;
772 
773 	wlan_vdev_obj_lock(vdev);
774 	/* Component object was never created, invalid operation */
775 	if (!vdev->vdev_comp_priv_obj[id]) {
776 		wlan_vdev_obj_unlock(vdev);
777 		return QDF_STATUS_E_FAILURE;
778 	}
779 	wlan_vdev_obj_unlock(vdev);
780 
781 	/* Invoke registered create handlers */
782 	handler = g_umac_glb_obj->vdev_destroy_handler[id];
783 	arg = g_umac_glb_obj->vdev_destroy_handler_arg[id];
784 	if (handler)
785 		vdev->obj_status[id] = handler(vdev, arg);
786 	else
787 		return QDF_STATUS_E_FAILURE;
788 
789 	/* If object status is created, then only handle this object status */
790 	if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
791 		obj_status = wlan_objmgr_vdev_object_status(vdev);
792 		/* move object state to DEL progress */
793 		if (obj_status == QDF_STATUS_COMP_ASYNC)
794 			vdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
795 	}
796 	return obj_status;
797 }
798 
799 
800 
801 static void wlan_obj_vdev_peerlist_add_tail(qdf_list_t *obj_list,
802 	struct wlan_objmgr_peer *obj)
803 {
804 	qdf_list_insert_back(obj_list, &obj->vdev_peer);
805 }
806 
807 static QDF_STATUS wlan_obj_vdev_peerlist_remove_peer(qdf_list_t *obj_list,
808 					struct wlan_objmgr_peer *peer)
809 {
810 	qdf_list_node_t *vdev_node = NULL;
811 
812 	if (!peer)
813 		return QDF_STATUS_E_FAILURE;
814 	/* get vdev list node element */
815 	vdev_node = &peer->vdev_peer;
816 	/* list is empty, return failure */
817 	if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
818 		return QDF_STATUS_E_FAILURE;
819 
820 	return QDF_STATUS_SUCCESS;
821 }
822 
823 QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
824 						struct wlan_objmgr_peer *peer)
825 {
826 	struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
827 	struct wlan_objmgr_pdev *pdev;
828 	enum QDF_OPMODE opmode;
829 
830 	wlan_vdev_obj_lock(vdev);
831 	pdev = wlan_vdev_get_pdev(vdev);
832 	/* If Max VDEV peer count exceeds, return failure */
833 	if (peer->peer_mlme.peer_type != WLAN_PEER_STA_TEMP) {
834 		if (objmgr->wlan_peer_count >= objmgr->max_peer_count) {
835 			wlan_vdev_obj_unlock(vdev);
836 			return QDF_STATUS_E_FAILURE;
837 		}
838 	}
839 	wlan_vdev_obj_unlock(vdev);
840 
841 	/* If Max PDEV peer count exceeds, return failure */
842 	wlan_pdev_obj_lock(pdev);
843 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) {
844 		if (wlan_pdev_get_temp_peer_count(pdev) >=
845 			WLAN_MAX_PDEV_TEMP_PEERS) {
846 			wlan_pdev_obj_unlock(pdev);
847 			return QDF_STATUS_E_FAILURE;
848 		}
849 	} else {
850 		if (wlan_pdev_get_peer_count(pdev) >=
851 			wlan_pdev_get_max_peer_count(pdev)) {
852 			wlan_pdev_obj_unlock(pdev);
853 			return QDF_STATUS_E_FAILURE;
854 		}
855 	}
856 
857 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
858 		wlan_pdev_incr_temp_peer_count(wlan_vdev_get_pdev(vdev));
859 	else
860 		wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
861 	wlan_pdev_obj_unlock(pdev);
862 
863 	wlan_vdev_obj_lock(vdev);
864 	/* Add peer to vdev's peer list */
865 	wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer);
866 	objmgr->wlan_peer_count++;
867 
868 	if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
869 			 wlan_vdev_mlme_get_macaddr(vdev)) ==
870 				QDF_STATUS_SUCCESS) {
871 		/*
872 		 * if peer mac address and vdev mac address match, set
873 		 * this peer as self peer
874 		 */
875 		wlan_vdev_set_selfpeer(vdev, peer);
876 		opmode = wlan_vdev_mlme_get_opmode(vdev);
877 		/* For AP mode, self peer and BSS peer are same */
878 		if ((opmode == QDF_SAP_MODE) ||
879 		    (opmode == QDF_P2P_GO_MODE) ||
880 		    (opmode == QDF_NDI_MODE))
881 			wlan_vdev_set_bsspeer(vdev, peer);
882 	}
883 	/* set BSS peer for sta */
884 	if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
885 	     wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) &&
886 	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP ||
887 	     wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO))
888 		wlan_vdev_set_bsspeer(vdev, peer);
889 
890 	/* Increment vdev ref count to make sure it won't be destroyed before */
891 	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
892 	wlan_vdev_obj_unlock(vdev);
893 	return QDF_STATUS_SUCCESS;
894 }
895 
896 QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
897 					struct wlan_objmgr_peer *peer)
898 {
899 	struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
900 	struct wlan_objmgr_pdev *pdev;
901 
902 	wlan_vdev_obj_lock(vdev);
903 	/* if peer count is 0, return failure */
904 	if (objmgr->wlan_peer_count == 0) {
905 		wlan_vdev_obj_unlock(vdev);
906 		return QDF_STATUS_E_FAILURE;
907 	}
908 
909 	if (wlan_vdev_get_selfpeer(vdev) == peer) {
910 		/*
911 		 * There might be instances where new node is created
912 		 * before deleting existing node, in which case selfpeer
913 		 * will be pointing to the new node. So set selfpeer to
914 		 * NULL only if vdev->vdev_objmgr.self_peer is pointing
915 		 * to the peer processed for deletion
916 		 */
917 		wlan_vdev_set_selfpeer(vdev, NULL);
918 	}
919 
920 	if (wlan_vdev_get_bsspeer(vdev) == peer) {
921 		/*
922 		 * There might be instances where new node is created
923 		 * before deleting existing node, in which case bsspeer
924 		 * in vdev will be pointing to the new node. So set
925 		 * bsspeer to NULL only if vdev->vdev_objmgr.bss_peer is
926 		 * pointing to the peer processed for deletion
927 		 */
928 		wlan_vdev_set_bsspeer(vdev, NULL);
929 	}
930 
931 	/* remove peer from vdev's peer list */
932 	if (wlan_obj_vdev_peerlist_remove_peer(&objmgr->wlan_peer_list, peer)
933 				== QDF_STATUS_E_FAILURE) {
934 		wlan_vdev_obj_unlock(vdev);
935 		return QDF_STATUS_E_FAILURE;
936 	}
937 	/* decrement peer count */
938 	objmgr->wlan_peer_count--;
939 	/* decrement pdev peer count */
940 	pdev = wlan_vdev_get_pdev(vdev);
941 	wlan_vdev_obj_unlock(vdev);
942 
943 	wlan_pdev_obj_lock(pdev);
944 	if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
945 		wlan_pdev_decr_temp_peer_count(pdev);
946 	else
947 		wlan_pdev_decr_peer_count(pdev);
948 	wlan_pdev_obj_unlock(pdev);
949 
950 	/* decrement vdev ref count after peer released its reference */
951 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
952 	return QDF_STATUS_SUCCESS;
953 }
954 
955 struct wlan_objmgr_peer *wlan_objmgr_vdev_try_get_bsspeer(
956 					struct wlan_objmgr_vdev *vdev,
957 					wlan_objmgr_ref_dbgid id)
958 {
959 	struct wlan_objmgr_peer *peer;
960 	QDF_STATUS status = QDF_STATUS_E_EMPTY;
961 
962 	if (!vdev)
963 		return NULL;
964 
965 	wlan_vdev_obj_lock(vdev);
966 	peer = wlan_vdev_get_bsspeer(vdev);
967 	if (peer)
968 		status = wlan_objmgr_peer_try_get_ref(peer, id);
969 	wlan_vdev_obj_unlock(vdev);
970 
971 	if (QDF_IS_STATUS_SUCCESS(status))
972 		return peer;
973 
974 	return NULL;
975 }
976 
977 void *wlan_objmgr_vdev_get_comp_private_obj(
978 		struct wlan_objmgr_vdev *vdev,
979 		enum wlan_umac_comp_id id)
980 {
981 	void *comp_priv_obj;
982 
983 	/* component id is invalid */
984 	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
985 		QDF_BUG(0);
986 		return NULL;
987 	}
988 
989 	if (!vdev) {
990 		QDF_BUG(0);
991 		return NULL;
992 	}
993 
994 	comp_priv_obj = vdev->vdev_comp_priv_obj[id];
995 
996 	return comp_priv_obj;
997 }
998 qdf_export_symbol(wlan_objmgr_vdev_get_comp_private_obj);
999 
1000 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1001 static inline void
1002 wlan_objmgr_vdev_ref_trace(struct wlan_objmgr_vdev *vdev,
1003 			   wlan_objmgr_ref_dbgid id,
1004 			   const char *func, int line)
1005 {
1006 	struct wlan_objmgr_trace *trace;
1007 
1008 	trace = &vdev->vdev_objmgr.trace;
1009 
1010 	if (func)
1011 		wlan_objmgr_trace_ref(&trace->references[id].head,
1012 				      trace, func, line);
1013 }
1014 
1015 static inline void
1016 wlan_objmgr_vdev_deref_trace(struct wlan_objmgr_vdev *vdev,
1017 			     wlan_objmgr_ref_dbgid id,
1018 			     const char *func, int line)
1019 {
1020 	struct wlan_objmgr_trace *trace;
1021 
1022 	trace = &vdev->vdev_objmgr.trace;
1023 
1024 	if (func)
1025 		wlan_objmgr_trace_ref(&trace->dereferences[id].head,
1026 				      trace, func, line);
1027 }
1028 #endif
1029 
1030 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1031 void wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev *vdev,
1032 				    wlan_objmgr_ref_dbgid id,
1033 				    const char *func, int line)
1034 {
1035 	if (!vdev) {
1036 		obj_mgr_err("vdev obj is NULL for id:%d", id);
1037 		QDF_ASSERT(0);
1038 		return;
1039 	}
1040 	/* Increment ref count */
1041 	qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt);
1042 	qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]);
1043 
1044 	wlan_objmgr_vdev_ref_trace(vdev, id, func, line);
1045 	return;
1046 }
1047 
1048 qdf_export_symbol(wlan_objmgr_vdev_get_ref_debug);
1049 #else
1050 void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev,
1051 			      wlan_objmgr_ref_dbgid id)
1052 {
1053 	if (!vdev) {
1054 		obj_mgr_err("vdev obj is NULL for id:%d", id);
1055 		QDF_ASSERT(0);
1056 		return;
1057 	}
1058 	/* Increment ref count */
1059 	qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt);
1060 	qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]);
1061 }
1062 
1063 qdf_export_symbol(wlan_objmgr_vdev_get_ref);
1064 #endif
1065 
1066 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1067 QDF_STATUS wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev *vdev,
1068 					      wlan_objmgr_ref_dbgid id,
1069 					      const char *func, int line)
1070 {
1071 	uint8_t vdev_id;
1072 
1073 	if (!vdev) {
1074 		obj_mgr_err("vdev obj is NULL for id:%d", id);
1075 		QDF_ASSERT(0);
1076 		return QDF_STATUS_E_FAILURE;
1077 	}
1078 
1079 	wlan_vdev_obj_lock(vdev);
1080 	vdev_id = wlan_vdev_get_id(vdev);
1081 	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
1082 		wlan_vdev_obj_unlock(vdev);
1083 		if (vdev->vdev_objmgr.print_cnt++ <=
1084 				WLAN_OBJMGR_RATELIMIT_THRESH)
1085 			obj_mgr_err(
1086 			"[Ref id: %d] vdev(%d) is not in Created state(%d)",
1087 				id, vdev_id, vdev->obj_state);
1088 
1089 		return QDF_STATUS_E_RESOURCES;
1090 	}
1091 
1092 	/* Increment ref count */
1093 	wlan_objmgr_vdev_get_ref_debug(vdev, id, func, line);
1094 	wlan_vdev_obj_unlock(vdev);
1095 
1096 	return QDF_STATUS_SUCCESS;
1097 }
1098 
1099 qdf_export_symbol(wlan_objmgr_vdev_try_get_ref_debug);
1100 #else
1101 QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev,
1102 					wlan_objmgr_ref_dbgid id)
1103 {
1104 	uint8_t vdev_id;
1105 
1106 	if (!vdev) {
1107 		obj_mgr_err("vdev obj is NULL for id:%d", id);
1108 		QDF_ASSERT(0);
1109 		return QDF_STATUS_E_FAILURE;
1110 	}
1111 
1112 	wlan_vdev_obj_lock(vdev);
1113 	vdev_id = wlan_vdev_get_id(vdev);
1114 	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
1115 		wlan_vdev_obj_unlock(vdev);
1116 		if (vdev->vdev_objmgr.print_cnt++ <=
1117 				WLAN_OBJMGR_RATELIMIT_THRESH)
1118 			obj_mgr_debug(
1119 			"[Ref id: %d] vdev(%d) is not in Created state(%d)",
1120 				id, vdev_id, vdev->obj_state);
1121 
1122 		return QDF_STATUS_E_RESOURCES;
1123 	}
1124 
1125 	/* Increment ref count */
1126 	wlan_objmgr_vdev_get_ref(vdev, id);
1127 	wlan_vdev_obj_unlock(vdev);
1128 
1129 	return QDF_STATUS_SUCCESS;
1130 }
1131 
1132 qdf_export_symbol(wlan_objmgr_vdev_try_get_ref);
1133 #endif
1134 
1135 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1136 struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev_debug(
1137 			struct wlan_objmgr_pdev *pdev,
1138 			qdf_list_t *vdev_list,
1139 			struct wlan_objmgr_vdev *vdev,
1140 			wlan_objmgr_ref_dbgid dbg_id,
1141 			const char *func, int line)
1142 {
1143 	struct wlan_objmgr_vdev *vdev_next;
1144 	qdf_list_node_t *node = &vdev->vdev_node;
1145 	qdf_list_node_t *prev_node = NULL;
1146 
1147 	if (!node)
1148 		return NULL;
1149 
1150 	wlan_pdev_obj_lock(pdev);
1151 	prev_node = node;
1152 	while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1153 							QDF_STATUS_SUCCESS) {
1154 		vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev,
1155 					     vdev_node);
1156 		if (wlan_objmgr_vdev_try_get_ref_debug(vdev_next, dbg_id,
1157 						       func, line) ==
1158 			QDF_STATUS_SUCCESS) {
1159 			wlan_pdev_obj_unlock(pdev);
1160 			return vdev_next;
1161 		}
1162 
1163 		prev_node = node;
1164 	}
1165 	wlan_pdev_obj_unlock(pdev);
1166 
1167 	return NULL;
1168 }
1169 #else
1170 struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev(
1171 			struct wlan_objmgr_pdev *pdev,
1172 			qdf_list_t *vdev_list,
1173 			struct wlan_objmgr_vdev *vdev,
1174 			wlan_objmgr_ref_dbgid dbg_id)
1175 {
1176 	struct wlan_objmgr_vdev *vdev_next;
1177 	qdf_list_node_t *node = &vdev->vdev_node;
1178 	qdf_list_node_t *prev_node = NULL;
1179 
1180 	if (!node)
1181 		return NULL;
1182 
1183 	wlan_pdev_obj_lock(pdev);
1184 	prev_node = node;
1185 	while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1186 							QDF_STATUS_SUCCESS) {
1187 		vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev,
1188 					     vdev_node);
1189 		if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) ==
1190 						QDF_STATUS_SUCCESS) {
1191 			wlan_pdev_obj_unlock(pdev);
1192 			return vdev_next;
1193 		}
1194 
1195 		prev_node = node;
1196 	}
1197 	wlan_pdev_obj_unlock(pdev);
1198 
1199 	return NULL;
1200 }
1201 #endif
1202 
1203 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1204 struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head_debug(
1205 			struct wlan_objmgr_pdev *pdev,
1206 			qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id,
1207 			const char *func, int line)
1208 {
1209 	struct wlan_objmgr_vdev *vdev;
1210 	qdf_list_node_t *node = NULL;
1211 	qdf_list_node_t *prev_node = NULL;
1212 
1213 	wlan_pdev_obj_lock(pdev);
1214 
1215 	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
1216 		wlan_pdev_obj_unlock(pdev);
1217 		return NULL;
1218 	}
1219 
1220 	do {
1221 		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1222 					vdev_node);
1223 		if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id,
1224 						       func, line) ==
1225 						QDF_STATUS_SUCCESS) {
1226 			wlan_pdev_obj_unlock(pdev);
1227 			return vdev;
1228 		}
1229 
1230 		prev_node = node;
1231 	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1232 						QDF_STATUS_SUCCESS);
1233 
1234 	wlan_pdev_obj_unlock(pdev);
1235 
1236 	return NULL;
1237 }
1238 #else
1239 struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head(
1240 			struct wlan_objmgr_pdev *pdev,
1241 			qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id)
1242 {
1243 	struct wlan_objmgr_vdev *vdev;
1244 	qdf_list_node_t *node = NULL;
1245 	qdf_list_node_t *prev_node = NULL;
1246 
1247 	wlan_pdev_obj_lock(pdev);
1248 
1249 	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
1250 		wlan_pdev_obj_unlock(pdev);
1251 		return NULL;
1252 	}
1253 
1254 	do {
1255 		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1256 								vdev_node);
1257 		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
1258 						QDF_STATUS_SUCCESS) {
1259 			wlan_pdev_obj_unlock(pdev);
1260 			return vdev;
1261 		}
1262 
1263 		prev_node = node;
1264 	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1265 						QDF_STATUS_SUCCESS);
1266 
1267 	wlan_pdev_obj_unlock(pdev);
1268 
1269 	return NULL;
1270 }
1271 #endif
1272 
1273 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1274 struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev_debug(
1275 		struct wlan_objmgr_pdev *pdev,
1276 		wlan_objmgr_ref_dbgid dbg_id,
1277 		const char *func, int line)
1278 {
1279 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1280 	qdf_list_t *vdev_list;
1281 
1282 	/* VDEV list */
1283 	vdev_list = &objmgr->wlan_vdev_list;
1284 
1285 	return wlan_pdev_vdev_list_peek_active_head_debug(pdev, vdev_list,
1286 						    dbg_id, func, line);
1287 }
1288 #else
1289 struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev(
1290 		struct wlan_objmgr_pdev *pdev,
1291 		wlan_objmgr_ref_dbgid dbg_id)
1292 {
1293 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1294 	qdf_list_t *vdev_list;
1295 
1296 	/* VDEV list */
1297 	vdev_list = &objmgr->wlan_vdev_list;
1298 
1299 	return wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
1300 						    dbg_id);
1301 }
1302 #endif
1303 
1304 #ifdef WLAN_OBJMGR_REF_ID_TRACE
1305 void wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev *vdev,
1306 					wlan_objmgr_ref_dbgid id,
1307 					const char *func, int line)
1308 {
1309 	uint8_t vdev_id;
1310 
1311 	if (!vdev) {
1312 		obj_mgr_err("vdev obj is NULL for id:%d", id);
1313 		QDF_ASSERT(0);
1314 		return;
1315 	}
1316 
1317 	vdev_id = wlan_vdev_get_id(vdev);
1318 
1319 	if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) {
1320 		obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d",
1321 			      vdev_id, id);
1322 		wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
1323 					  QDF_TRACE_LEVEL_FATAL);
1324 		WLAN_OBJMGR_BUG(0);
1325 		return;
1326 	}
1327 
1328 	if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) {
1329 		obj_mgr_alert("vdev ref cnt is 0");
1330 		WLAN_OBJMGR_BUG(0);
1331 		return;
1332 	}
1333 	qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]);
1334 	wlan_objmgr_vdev_deref_trace(vdev, id, func, line);
1335 
1336 	/* Decrement ref count, free vdev, if ref count == 0 */
1337 	if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt))
1338 		wlan_objmgr_vdev_obj_destroy(vdev);
1339 }
1340 
1341 qdf_export_symbol(wlan_objmgr_vdev_release_ref_debug);
1342 #else
1343 void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev,
1344 				  wlan_objmgr_ref_dbgid id)
1345 {
1346 	uint8_t vdev_id;
1347 
1348 	if (!vdev) {
1349 		obj_mgr_err("vdev obj is NULL for id:%d", id);
1350 		QDF_ASSERT(0);
1351 		return;
1352 	}
1353 
1354 	vdev_id = wlan_vdev_get_id(vdev);
1355 
1356 	if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) {
1357 		obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d",
1358 			      vdev_id, id);
1359 		wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
1360 					  QDF_TRACE_LEVEL_FATAL);
1361 		WLAN_OBJMGR_BUG(0);
1362 		return;
1363 	}
1364 
1365 	if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) {
1366 		obj_mgr_alert("vdev ref cnt is 0");
1367 		WLAN_OBJMGR_BUG(0);
1368 		return;
1369 	}
1370 	qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]);
1371 
1372 	/* Decrement ref count, free vdev, if ref count == 0 */
1373 	if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt))
1374 		wlan_objmgr_vdev_obj_destroy(vdev);
1375 }
1376 
1377 qdf_export_symbol(wlan_objmgr_vdev_release_ref);
1378 #endif
1379 
1380 #ifdef WLAN_OBJMGR_DEBUG
1381 void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev)
1382 {
1383 	struct wlan_objmgr_vdev_objmgr *vdev_objmgr;
1384 	uint32_t ref_cnt;
1385 
1386 	vdev_objmgr = &vdev->vdev_objmgr;
1387 
1388 	ref_cnt = qdf_atomic_read(&vdev_objmgr->ref_cnt);
1389 
1390 	obj_mgr_debug("vdev: %pK", vdev);
1391 	obj_mgr_debug("vdev_id: %d", vdev_objmgr->vdev_id);
1392 	obj_mgr_debug("print_cnt: %d", vdev_objmgr->print_cnt);
1393 	obj_mgr_debug("wlan_pdev: %pK", vdev_objmgr->wlan_pdev);
1394 	obj_mgr_debug("ref_cnt: %d", ref_cnt);
1395 }
1396 
1397 qdf_export_symbol(wlan_print_vdev_info);
1398 #endif
1399 
1400 void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev)
1401 {
1402 	wlan_objmgr_vdev_peer_free_notify_handler stat_handler;
1403 	uint8_t i;
1404 
1405 	for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
1406 		stat_handler = g_umac_glb_obj->vdev_peer_free_notify_handler[i];
1407 		if (stat_handler)
1408 			stat_handler(vdev);
1409 	}
1410 }
1411 
1412 QDF_STATUS wlan_vdev_get_bss_peer_mac(struct wlan_objmgr_vdev *vdev,
1413 				      struct qdf_mac_addr *bss_peer_mac)
1414 {
1415 	struct wlan_objmgr_peer *peer;
1416 
1417 	if (!vdev) {
1418 		obj_mgr_err("vdev is null");
1419 		return QDF_STATUS_E_INVAL;
1420 	}
1421 
1422 	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_OBJMGR_ID);
1423 	if (!peer) {
1424 		obj_mgr_err("not able to find bss peer for vdev %d",
1425 			    wlan_vdev_get_id(vdev));
1426 		return QDF_STATUS_E_INVAL;
1427 	}
1428 	wlan_peer_obj_lock(peer);
1429 	qdf_mem_copy(bss_peer_mac->bytes, wlan_peer_get_macaddr(peer),
1430 		     QDF_MAC_ADDR_SIZE);
1431 	wlan_peer_obj_unlock(peer);
1432 
1433 	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_OBJMGR_ID);
1434 
1435 	return QDF_STATUS_SUCCESS;
1436 }
1437