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