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