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