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