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