1 /* 2 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /** 19 * DOC: Public APIs to perform operations on Global objects 20 */ 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_types.h> 31 #include <qdf_module.h> 32 #include "wlan_objmgr_global_obj_i.h" 33 #include "wlan_objmgr_psoc_obj_i.h" 34 #include "wlan_objmgr_pdev_obj_i.h" 35 #include "wlan_objmgr_vdev_obj_i.h" 36 #include <wlan_utility.h> 37 38 /** 39 ** APIs to Create/Delete Global object APIs 40 */ 41 static QDF_STATUS wlan_objmgr_psoc_object_status( 42 struct wlan_objmgr_psoc *psoc) 43 { 44 uint8_t id; 45 QDF_STATUS status = QDF_STATUS_SUCCESS; 46 47 wlan_psoc_obj_lock(psoc); 48 /* Iterate through all components to derive the object status */ 49 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 50 /* If component disabled, Ignore */ 51 if (psoc->obj_status[id] == QDF_STATUS_COMP_DISABLED) 52 continue; 53 /* If component operates in Async, status is Partially created, 54 * break 55 */ 56 else if (psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC) { 57 if (!psoc->soc_comp_priv_obj[id]) { 58 status = QDF_STATUS_COMP_ASYNC; 59 break; 60 } 61 /* 62 * If component failed to allocate its object, treat it as 63 * failure, complete object need to be cleaned up 64 */ 65 } else if ((psoc->obj_status[id] == QDF_STATUS_E_NOMEM) || 66 (psoc->obj_status[id] == QDF_STATUS_E_FAILURE)) { 67 status = QDF_STATUS_E_FAILURE; 68 break; 69 } 70 } 71 wlan_psoc_obj_unlock(psoc); 72 73 return status; 74 } 75 76 static void wlan_objmgr_psoc_peer_list_init(struct wlan_peer_list *peer_list) 77 { 78 uint8_t i; 79 80 qdf_spinlock_create(&peer_list->peer_list_lock); 81 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) 82 qdf_list_create(&peer_list->peer_hash[i], 83 WLAN_UMAC_PSOC_MAX_PEERS + 84 WLAN_MAX_PSOC_TEMP_PEERS); 85 } 86 87 static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list) 88 { 89 uint8_t i; 90 91 /* deinit the lock */ 92 qdf_spinlock_destroy(&peer_list->peer_list_lock); 93 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) 94 qdf_list_destroy(&peer_list->peer_hash[i]); 95 } 96 97 static QDF_STATUS wlan_objmgr_psoc_obj_free(struct wlan_objmgr_psoc *psoc) 98 { 99 /* Detach PSOC from global object's psoc list */ 100 if (wlan_objmgr_psoc_object_detach(psoc) == QDF_STATUS_E_FAILURE) { 101 obj_mgr_err("PSOC object detach failed"); 102 return QDF_STATUS_E_FAILURE; 103 } 104 wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list); 105 106 qdf_spinlock_destroy(&psoc->psoc_lock); 107 wlan_minidump_remove(psoc); 108 qdf_mem_free(psoc); 109 110 return QDF_STATUS_SUCCESS; 111 } 112 113 struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version, 114 WLAN_DEV_TYPE dev_type) 115 { 116 uint8_t id; 117 struct wlan_objmgr_psoc *psoc = NULL; 118 wlan_objmgr_psoc_create_handler handler; 119 wlan_objmgr_psoc_status_handler stat_handler; 120 struct wlan_objmgr_psoc_objmgr *objmgr; 121 QDF_STATUS obj_status; 122 void *arg; 123 124 psoc = qdf_mem_malloc(sizeof(*psoc)); 125 if (!psoc) 126 return NULL; 127 128 psoc->obj_state = WLAN_OBJ_STATE_ALLOCATED; 129 qdf_spinlock_create(&psoc->psoc_lock); 130 /* Initialize with default values */ 131 objmgr = &psoc->soc_objmgr; 132 objmgr->wlan_pdev_count = 0; 133 objmgr->wlan_vdev_count = 0; 134 objmgr->max_vdev_count = WLAN_UMAC_PSOC_MAX_VDEVS; 135 objmgr->wlan_peer_count = 0; 136 objmgr->temp_peer_count = 0; 137 objmgr->max_peer_count = WLAN_UMAC_PSOC_MAX_PEERS; 138 qdf_atomic_init(&objmgr->ref_cnt); 139 objmgr->print_cnt = 0; 140 /* set phy version, dev_type in psoc */ 141 wlan_psoc_set_nif_phy_version(psoc, phy_version); 142 wlan_psoc_set_dev_type(psoc, dev_type); 143 /* Initialize peer list */ 144 wlan_objmgr_psoc_peer_list_init(&objmgr->peer_list); 145 wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID); 146 /* Invoke registered create handlers */ 147 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 148 handler = g_umac_glb_obj->psoc_create_handler[id]; 149 arg = g_umac_glb_obj->psoc_create_handler_arg[id]; 150 if (handler) 151 psoc->obj_status[id] = handler(psoc, arg); 152 else 153 psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED; 154 } 155 /* Derive object status */ 156 obj_status = wlan_objmgr_psoc_object_status(psoc); 157 158 if (obj_status == QDF_STATUS_SUCCESS) { 159 /* Object status is SUCCESS, Object is created */ 160 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 161 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 162 stat_handler = g_umac_glb_obj->psoc_status_handler[id]; 163 arg = g_umac_glb_obj->psoc_status_handler_arg[id]; 164 if (stat_handler) 165 stat_handler(psoc, arg, 166 QDF_STATUS_SUCCESS); 167 } 168 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 169 /* 170 * Few components operates in Asynchrous communction 171 * Object state partially created 172 */ 173 psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 174 } else if (obj_status == QDF_STATUS_E_FAILURE) { 175 /* Component object failed to be created, clean up the object */ 176 obj_mgr_err("PSOC component objects allocation failed"); 177 /* Clean up the psoc */ 178 wlan_objmgr_psoc_obj_delete(psoc); 179 return NULL; 180 } 181 182 if (wlan_objmgr_psoc_object_attach(psoc) != 183 QDF_STATUS_SUCCESS) { 184 obj_mgr_err("PSOC object attach failed"); 185 wlan_objmgr_psoc_obj_delete(psoc); 186 return NULL; 187 } 188 wlan_minidump_log(psoc, sizeof(*psoc), psoc, 189 WLAN_MD_OBJMGR_PSOC, "wlan_objmgr_psoc"); 190 obj_mgr_info("Created psoc %d", psoc->soc_objmgr.psoc_id); 191 192 return psoc; 193 } 194 qdf_export_symbol(wlan_objmgr_psoc_obj_create); 195 196 static QDF_STATUS wlan_objmgr_psoc_obj_destroy(struct wlan_objmgr_psoc *psoc) 197 { 198 uint8_t id; 199 wlan_objmgr_psoc_destroy_handler handler; 200 QDF_STATUS obj_status; 201 void *arg; 202 203 if (!psoc) { 204 obj_mgr_err("psoc is NULL"); 205 return QDF_STATUS_E_FAILURE; 206 } 207 wlan_objmgr_notify_destroy(psoc, WLAN_PSOC_OP); 208 209 wlan_print_psoc_info(psoc); 210 obj_mgr_info("Physically deleting psoc %d", psoc->soc_objmgr.psoc_id); 211 212 if (psoc->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { 213 obj_mgr_err("PSOC object delete is not invoked obj_state:%d", 214 psoc->obj_state); 215 WLAN_OBJMGR_BUG(0); 216 } 217 218 /* Invoke registered create handlers */ 219 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 220 handler = g_umac_glb_obj->psoc_destroy_handler[id]; 221 arg = g_umac_glb_obj->psoc_destroy_handler_arg[id]; 222 if (handler && 223 (psoc->obj_status[id] == QDF_STATUS_SUCCESS || 224 psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC)) 225 psoc->obj_status[id] = handler(psoc, arg); 226 else 227 psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED; 228 } 229 /* Derive object status */ 230 obj_status = wlan_objmgr_psoc_object_status(psoc); 231 232 if (obj_status == QDF_STATUS_E_FAILURE) { 233 obj_mgr_err("PSOC component object free failed"); 234 /* Ideally should not happen 235 * This leads to memleak, BUG_ON to find which component 236 * delete notification failed and fix it. 237 */ 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 psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED; 244 return QDF_STATUS_COMP_ASYNC; 245 } 246 247 /* Free psoc object */ 248 return wlan_objmgr_psoc_obj_free(psoc); 249 } 250 251 252 QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc) 253 { 254 uint8_t print_idx; 255 256 if (!psoc) { 257 obj_mgr_err("psoc is NULL"); 258 return QDF_STATUS_E_FAILURE; 259 } 260 261 obj_mgr_info("Logically deleting psoc %d", psoc->soc_objmgr.psoc_id); 262 263 print_idx = qdf_get_pidx(); 264 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg, 265 QDF_TRACE_LEVEL_DEBUG); 266 /* 267 * Update PSOC object state to LOGICALLY DELETED 268 * It prevents further access of this object 269 */ 270 wlan_psoc_obj_lock(psoc); 271 psoc->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED; 272 wlan_psoc_obj_unlock(psoc); 273 wlan_objmgr_notify_log_delete(psoc, WLAN_PSOC_OP); 274 wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID); 275 276 return QDF_STATUS_SUCCESS; 277 } 278 qdf_export_symbol(wlan_objmgr_psoc_obj_delete); 279 280 QDF_STATUS wlan_objmgr_psoc_component_obj_attach( 281 struct wlan_objmgr_psoc *psoc, 282 enum wlan_umac_comp_id id, 283 void *comp_priv_obj, 284 QDF_STATUS status) 285 { 286 wlan_objmgr_psoc_status_handler stat_handler; 287 void *arg = NULL; 288 QDF_STATUS obj_status; 289 uint8_t i; 290 291 /* component id is invalid */ 292 if (id >= WLAN_UMAC_MAX_COMPONENTS) 293 return QDF_STATUS_MAXCOMP_FAIL; 294 295 wlan_psoc_obj_lock(psoc); 296 /* If there is a valid entry, return failure */ 297 if (psoc->soc_comp_priv_obj[id]) { 298 wlan_psoc_obj_unlock(psoc); 299 return QDF_STATUS_E_FAILURE; 300 } 301 /* Save component's pointer and status */ 302 psoc->soc_comp_priv_obj[id] = comp_priv_obj; 303 psoc->obj_status[id] = status; 304 305 wlan_psoc_obj_unlock(psoc); 306 307 if (psoc->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED) 308 return QDF_STATUS_SUCCESS; 309 /* If PSOC object status is partially created means, this API is 310 * invoked with differnt context, this block should be executed for 311 * async components only 312 */ 313 /* Derive status */ 314 obj_status = wlan_objmgr_psoc_object_status(psoc); 315 /* STATUS_SUCCESS means, object is CREATED */ 316 if (obj_status == QDF_STATUS_SUCCESS) 317 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 318 /* update state as CREATION failed, caller has to delete the 319 * PSOC object 320 */ 321 else if (obj_status == QDF_STATUS_E_FAILURE) 322 psoc->obj_state = WLAN_OBJ_STATE_CREATION_FAILED; 323 324 /* Notify components about the CREATION success/failure */ 325 if ((obj_status == QDF_STATUS_SUCCESS) || 326 (obj_status == QDF_STATUS_E_FAILURE)) { 327 /* nofity object status */ 328 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 329 stat_handler = g_umac_glb_obj->psoc_status_handler[i]; 330 arg = g_umac_glb_obj->psoc_status_handler_arg[i]; 331 if (stat_handler) 332 stat_handler(psoc, arg, obj_status); 333 } 334 } 335 336 return QDF_STATUS_SUCCESS; 337 } 338 qdf_export_symbol(wlan_objmgr_psoc_component_obj_attach); 339 340 QDF_STATUS wlan_objmgr_psoc_component_obj_detach( 341 struct wlan_objmgr_psoc *psoc, 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_psoc_obj_lock(psoc); 352 /* If there is a valid entry, return failure */ 353 if (psoc->soc_comp_priv_obj[id] != comp_priv_obj) { 354 psoc->obj_status[id] = QDF_STATUS_E_FAILURE; 355 wlan_psoc_obj_unlock(psoc); 356 return QDF_STATUS_E_FAILURE; 357 } 358 /* Reset pointers to NULL, update the status*/ 359 psoc->soc_comp_priv_obj[id] = NULL; 360 psoc->obj_status[id] = QDF_STATUS_SUCCESS; 361 wlan_psoc_obj_unlock(psoc); 362 363 /* If PSOC object status is partially created means, this API is 364 * invoked with differnt context, this block should be executed for 365 * async components only 366 */ 367 if ((psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) || 368 (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) { 369 /* Derive object status */ 370 obj_status = wlan_objmgr_psoc_object_status(psoc); 371 if (obj_status == QDF_STATUS_SUCCESS) { 372 /* Update the status as Deleted, if full object 373 * deletion is in progress 374 */ 375 if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 376 psoc->obj_state = WLAN_OBJ_STATE_DELETED; 377 378 /* Move to creation state, since this component 379 * deletion alone requested 380 */ 381 if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 382 psoc->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 */ 388 if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 389 psoc->obj_state = 390 WLAN_OBJ_STATE_DELETION_FAILED; 391 392 /* Move to creation state, since this component 393 * deletion alone requested (do not block other 394 * components) 395 */ 396 if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 397 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 398 } 399 400 /* Delete psoc object */ 401 if ((obj_status == QDF_STATUS_SUCCESS) && 402 (psoc->obj_state == WLAN_OBJ_STATE_DELETED)) { 403 /* Free psoc object */ 404 return wlan_objmgr_psoc_obj_free(psoc); 405 } 406 } 407 408 return QDF_STATUS_SUCCESS; 409 } 410 qdf_export_symbol(wlan_objmgr_psoc_component_obj_detach); 411 412 QDF_STATUS wlan_objmgr_iterate_obj_list( 413 struct wlan_objmgr_psoc *psoc, 414 enum wlan_objmgr_obj_type obj_type, 415 wlan_objmgr_op_handler handler, 416 void *arg, uint8_t lock_free_op, 417 wlan_objmgr_ref_dbgid dbg_id) 418 { 419 uint16_t obj_id; 420 uint8_t i; 421 struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; 422 struct wlan_peer_list *peer_list; 423 struct wlan_objmgr_pdev *pdev; 424 struct wlan_objmgr_vdev *vdev; 425 struct wlan_objmgr_peer *peer; 426 struct wlan_objmgr_peer *peer_next; 427 uint16_t max_vdev_cnt; 428 429 switch (obj_type) { 430 case WLAN_PDEV_OP: 431 /* Iterate through PDEV list, invoke handler for each pdev */ 432 for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { 433 pdev = wlan_objmgr_get_pdev_by_id(psoc, obj_id, dbg_id); 434 if (pdev) { 435 handler(psoc, (void *)pdev, arg); 436 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 437 } 438 } 439 break; 440 case WLAN_VDEV_OP: 441 /* Iterate through VDEV list, invoke handler for each vdev */ 442 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 443 for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { 444 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 445 obj_id, dbg_id); 446 if (vdev) { 447 handler(psoc, vdev, arg); 448 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 449 } 450 } 451 break; 452 case WLAN_PEER_OP: 453 /* Iterate through PEER list, invoke handler for each peer */ 454 peer_list = &objmgr->peer_list; 455 /* Since peer list has sublist, iterate through sublists */ 456 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { 457 peer = wlan_psoc_peer_list_peek_active_head(peer_list, 458 i, dbg_id); 459 while (peer) { 460 handler(psoc, (void *)peer, arg); 461 /* Get next peer */ 462 peer_next = 463 wlan_peer_get_next_active_peer_of_psoc( 464 peer_list, i, peer, dbg_id); 465 wlan_objmgr_peer_release_ref(peer, dbg_id); 466 peer = peer_next; 467 } 468 } 469 break; 470 default: 471 break; 472 } 473 474 return QDF_STATUS_SUCCESS; 475 } 476 qdf_export_symbol(wlan_objmgr_iterate_obj_list); 477 478 QDF_STATUS wlan_objmgr_iterate_obj_list_all( 479 struct wlan_objmgr_psoc *psoc, 480 enum wlan_objmgr_obj_type obj_type, 481 wlan_objmgr_op_handler handler, 482 void *arg, uint8_t lock_free_op, 483 wlan_objmgr_ref_dbgid dbg_id) 484 { 485 uint16_t obj_id; 486 uint8_t i; 487 struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; 488 struct wlan_peer_list *peer_list; 489 struct wlan_objmgr_pdev *pdev; 490 struct wlan_objmgr_vdev *vdev; 491 struct wlan_objmgr_peer *peer; 492 struct wlan_objmgr_peer *peer_next; 493 uint16_t max_vdev_cnt; 494 495 /* If caller requests for lock free opeation, do not acquire, 496 * handler will handle the synchronization 497 */ 498 499 switch (obj_type) { 500 case WLAN_PDEV_OP: 501 /* Iterate through PDEV list, invoke handler for each pdev */ 502 for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { 503 pdev = wlan_objmgr_get_pdev_by_id_no_state(psoc, 504 obj_id, dbg_id); 505 if (pdev) { 506 handler(psoc, (void *)pdev, arg); 507 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 508 } 509 } 510 break; 511 case WLAN_VDEV_OP: 512 /* Iterate through VDEV list, invoke handler for each vdev */ 513 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 514 for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { 515 vdev = wlan_objmgr_get_vdev_by_id_from_psoc_no_state( 516 psoc, obj_id, dbg_id); 517 if (vdev) { 518 handler(psoc, vdev, arg); 519 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 520 } 521 } 522 break; 523 case WLAN_PEER_OP: 524 /* Iterate through PEER list, invoke handler for each peer */ 525 peer_list = &objmgr->peer_list; 526 /* Since peer list has sublist, iterate through sublists */ 527 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { 528 peer = wlan_psoc_peer_list_peek_head_ref(peer_list, i, 529 dbg_id); 530 531 while (peer) { 532 handler(psoc, (void *)peer, arg); 533 /* Get next peer */ 534 peer_next = wlan_peer_get_next_peer_of_psoc_ref( 535 peer_list, i, 536 peer, dbg_id); 537 wlan_objmgr_peer_release_ref(peer, dbg_id); 538 peer = peer_next; 539 } 540 } 541 break; 542 default: 543 break; 544 } 545 546 return QDF_STATUS_SUCCESS; 547 } 548 qdf_export_symbol(wlan_objmgr_iterate_obj_list_all); 549 550 /** 551 * wlan_objmgr_iterate_obj_list_all_noref() - iterate through all psoc objects 552 * without taking ref 553 * @psoc: PSOC object 554 * @obj_type: PDEV_OP/VDEV_OP/PEER_OP 555 * @handler: the handler will be called for each object of requested type 556 * the handler should be implemented to perform required operation 557 * @arg: agruments passed by caller 558 * 559 * API to be used for performing the operations on all PDEV/VDEV/PEER objects 560 * of psoc with lock protected 561 * 562 * Return: SUCCESS/FAILURE 563 */ 564 static QDF_STATUS wlan_objmgr_iterate_obj_list_all_noref( 565 struct wlan_objmgr_psoc *psoc, 566 enum wlan_objmgr_obj_type obj_type, 567 wlan_objmgr_op_handler handler, 568 void *arg) 569 { 570 uint16_t obj_id; 571 uint8_t i; 572 struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; 573 struct wlan_peer_list *peer_list; 574 qdf_list_t *obj_list; 575 struct wlan_objmgr_pdev *pdev; 576 struct wlan_objmgr_vdev *vdev; 577 struct wlan_objmgr_peer *peer; 578 struct wlan_objmgr_peer *peer_next; 579 uint16_t max_vdev_cnt; 580 581 /* If caller requests for lock free opeation, do not acquire, 582 * handler will handle the synchronization 583 */ 584 wlan_psoc_obj_lock(psoc); 585 586 switch (obj_type) { 587 case WLAN_PDEV_OP: 588 /* Iterate through PDEV list, invoke handler for each pdev */ 589 for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { 590 pdev = objmgr->wlan_pdev_list[obj_id]; 591 if (pdev) 592 handler(psoc, (void *)pdev, arg); 593 } 594 break; 595 case WLAN_VDEV_OP: 596 /* Iterate through VDEV list, invoke handler for each vdev */ 597 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 598 for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { 599 vdev = objmgr->wlan_vdev_list[obj_id]; 600 if (vdev) 601 handler(psoc, vdev, arg); 602 } 603 break; 604 case WLAN_PEER_OP: 605 /* Iterate through PEER list, invoke handler for each peer */ 606 peer_list = &objmgr->peer_list; 607 /* psoc lock should be taken before list lock */ 608 qdf_spin_lock_bh(&peer_list->peer_list_lock); 609 /* Since peer list has sublist, iterate through sublists */ 610 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { 611 obj_list = &peer_list->peer_hash[i]; 612 peer = wlan_psoc_peer_list_peek_head(obj_list); 613 while (peer) { 614 /* Get next peer */ 615 peer_next = wlan_peer_get_next_peer_of_psoc( 616 obj_list, peer); 617 handler(psoc, (void *)peer, arg); 618 peer = peer_next; 619 } 620 } 621 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 622 break; 623 default: 624 break; 625 } 626 wlan_psoc_obj_unlock(psoc); 627 628 return QDF_STATUS_SUCCESS; 629 } 630 631 static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc, 632 void *obj, void *args) 633 { 634 struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj; 635 636 wlan_objmgr_peer_obj_delete(peer); 637 } 638 639 static void wlan_objmgr_psoc_vdev_delete(struct wlan_objmgr_psoc *psoc, 640 void *obj, void *args) 641 { 642 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj; 643 644 wlan_objmgr_vdev_obj_delete(vdev); 645 } 646 647 static void wlan_objmgr_psoc_pdev_delete(struct wlan_objmgr_psoc *psoc, 648 void *obj, void *args) 649 { 650 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj; 651 652 wlan_objmgr_pdev_obj_delete(pdev); 653 } 654 655 QDF_STATUS wlan_objmgr_free_all_objects_per_psoc( 656 struct wlan_objmgr_psoc *psoc) 657 { 658 /* Free all peers */ 659 wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, 660 wlan_objmgr_psoc_peer_delete, NULL, 1, 661 WLAN_OBJMGR_ID); 662 /* Free all vdevs */ 663 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, 664 wlan_objmgr_psoc_vdev_delete, NULL, 1, 665 WLAN_OBJMGR_ID); 666 /* Free all PDEVs */ 667 wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 668 wlan_objmgr_psoc_pdev_delete, NULL, 1, 669 WLAN_OBJMGR_ID); 670 671 return QDF_STATUS_SUCCESS; 672 } 673 674 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_creation( 675 struct wlan_objmgr_psoc *psoc, 676 enum wlan_umac_comp_id id) 677 { 678 wlan_objmgr_psoc_create_handler handler; 679 void *arg; 680 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 681 682 /* Component id is invalid */ 683 if (id >= WLAN_UMAC_MAX_COMPONENTS) 684 return QDF_STATUS_MAXCOMP_FAIL; 685 686 wlan_psoc_obj_lock(psoc); 687 /* If component object is already created, delete old 688 * component object, then invoke creation 689 */ 690 if (psoc->soc_comp_priv_obj[id]) { 691 wlan_psoc_obj_unlock(psoc); 692 return QDF_STATUS_E_FAILURE; 693 } 694 wlan_psoc_obj_unlock(psoc); 695 /* Invoke registered create handlers */ 696 handler = g_umac_glb_obj->psoc_create_handler[id]; 697 arg = g_umac_glb_obj->psoc_create_handler_arg[id]; 698 if (handler) 699 psoc->obj_status[id] = handler(psoc, arg); 700 else 701 return QDF_STATUS_E_FAILURE; 702 703 /* If object status is created, then only handle this object status */ 704 if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) { 705 /* Derive object status */ 706 obj_status = wlan_objmgr_psoc_object_status(psoc); 707 /* Move PSOC object state to Partially created state */ 708 if (obj_status == QDF_STATUS_COMP_ASYNC) { 709 /*TODO atomic */ 710 psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 711 } 712 } 713 714 return obj_status; 715 } 716 717 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_deletion( 718 struct wlan_objmgr_psoc *psoc, 719 enum wlan_umac_comp_id id) 720 { 721 wlan_objmgr_psoc_destroy_handler handler; 722 void *arg; 723 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 724 725 /* component id is invalid */ 726 if (id >= WLAN_UMAC_MAX_COMPONENTS) 727 return QDF_STATUS_MAXCOMP_FAIL; 728 729 wlan_psoc_obj_lock(psoc); 730 /* Component object was never created, invalid operation */ 731 if (!psoc->soc_comp_priv_obj[id]) { 732 wlan_psoc_obj_unlock(psoc); 733 return QDF_STATUS_E_FAILURE; 734 } 735 wlan_psoc_obj_unlock(psoc); 736 /* Invoke registered create handlers */ 737 handler = g_umac_glb_obj->psoc_destroy_handler[id]; 738 arg = g_umac_glb_obj->psoc_destroy_handler_arg[id]; 739 if (handler) 740 psoc->obj_status[id] = handler(psoc, arg); 741 else 742 return QDF_STATUS_E_FAILURE; 743 744 /* If object status is created, then only handle this object status */ 745 if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) { 746 obj_status = wlan_objmgr_psoc_object_status(psoc); 747 /* move object state to DEL progress */ 748 if (obj_status == QDF_STATUS_COMP_ASYNC) 749 psoc->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS; 750 } 751 752 return obj_status; 753 } 754 755 /* Util APIs */ 756 757 QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc, 758 struct wlan_objmgr_pdev *pdev) 759 { 760 struct wlan_objmgr_psoc_objmgr *objmgr; 761 uint8_t id = 0; 762 QDF_STATUS status; 763 764 wlan_psoc_obj_lock(psoc); 765 objmgr = &psoc->soc_objmgr; 766 /* 767 * Derive pdev id from pdev map 768 * First free pdev id is assigned 769 */ 770 while ((id < WLAN_UMAC_MAX_PDEVS) && 771 (objmgr->wlan_pdev_id_map & (1<<id))) 772 id++; 773 774 if (id == WLAN_UMAC_MAX_PDEVS) { 775 status = QDF_STATUS_E_FAILURE; 776 } else { 777 /* Update the map for reserving the id */ 778 objmgr->wlan_pdev_id_map |= (1<<id); 779 /* store pdev in pdev list */ 780 objmgr->wlan_pdev_list[id] = pdev; 781 /* Increment pdev count */ 782 objmgr->wlan_pdev_count++; 783 /* save pdev id */ 784 pdev->pdev_objmgr.wlan_pdev_id = id; 785 status = QDF_STATUS_SUCCESS; 786 /* Inrement psoc ref count to block its free before pdev */ 787 wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID); 788 } 789 wlan_psoc_obj_unlock(psoc); 790 791 return status; 792 } 793 794 QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc, 795 struct wlan_objmgr_pdev *pdev) 796 { 797 struct wlan_objmgr_psoc_objmgr *objmgr; 798 uint8_t id; 799 800 id = pdev->pdev_objmgr.wlan_pdev_id; 801 /* If id is invalid, return */ 802 if (id >= WLAN_UMAC_MAX_PDEVS) 803 return QDF_STATUS_E_FAILURE; 804 805 wlan_psoc_obj_lock(psoc); 806 objmgr = &psoc->soc_objmgr; 807 /* Free pdev id slot */ 808 objmgr->wlan_pdev_id_map &= ~(1<<id); 809 objmgr->wlan_pdev_list[id] = NULL; 810 objmgr->wlan_pdev_count--; 811 pdev->pdev_objmgr.wlan_pdev_id = 0xff; 812 wlan_psoc_obj_unlock(psoc); 813 /* Release ref count of psoc */ 814 wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID); 815 816 return QDF_STATUS_SUCCESS; 817 } 818 819 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id( 820 struct wlan_objmgr_psoc *psoc, uint8_t id, 821 wlan_objmgr_ref_dbgid dbg_id) 822 { 823 struct wlan_objmgr_psoc_objmgr *objmgr; 824 struct wlan_objmgr_pdev *pdev = NULL; 825 826 /* If id is invalid, return */ 827 if (id >= WLAN_UMAC_MAX_PDEVS) 828 return NULL; 829 830 wlan_psoc_obj_lock(psoc); 831 objmgr = &psoc->soc_objmgr; 832 /* get pdev from pdev list */ 833 pdev = objmgr->wlan_pdev_list[id]; 834 /* Do not return object, if it is not CREATED state */ 835 if (pdev) { 836 if (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) != 837 QDF_STATUS_SUCCESS) 838 pdev = NULL; 839 } 840 841 wlan_psoc_obj_unlock(psoc); 842 843 return pdev; 844 } 845 qdf_export_symbol(wlan_objmgr_get_pdev_by_id); 846 847 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id_no_state( 848 struct wlan_objmgr_psoc *psoc, uint8_t id, 849 wlan_objmgr_ref_dbgid dbg_id) 850 { 851 struct wlan_objmgr_psoc_objmgr *objmgr; 852 struct wlan_objmgr_pdev *pdev = NULL; 853 854 /* If id is invalid, return */ 855 if (id >= WLAN_UMAC_MAX_PDEVS) 856 return NULL; 857 858 wlan_psoc_obj_lock(psoc); 859 objmgr = &psoc->soc_objmgr; 860 /* get pdev from pdev list */ 861 pdev = objmgr->wlan_pdev_list[id]; 862 /* Do not return object, if it is not CREATED state */ 863 if (pdev) 864 wlan_objmgr_pdev_get_ref(pdev, dbg_id); 865 866 wlan_psoc_obj_unlock(psoc); 867 868 return pdev; 869 } 870 QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc, 871 struct wlan_objmgr_vdev *vdev) 872 { 873 struct wlan_objmgr_psoc_objmgr *objmgr; 874 uint8_t id = 0; 875 QDF_STATUS status; 876 877 wlan_psoc_obj_lock(psoc); 878 objmgr = &psoc->soc_objmgr; 879 /* Find first free vdev id */ 880 while ((id < objmgr->max_vdev_count)) { 881 if (qdf_test_bit(id, objmgr->wlan_vdev_id_map)) { 882 id++; 883 continue; 884 } 885 break; 886 } 887 888 /* If no free slot, return failure */ 889 if (id < objmgr->max_vdev_count) { 890 /* set free vdev id index */ 891 qdf_set_bit(id, objmgr->wlan_vdev_id_map); 892 /* store vdev pointer in vdev list */ 893 objmgr->wlan_vdev_list[id] = vdev; 894 /* increment vdev counter */ 895 objmgr->wlan_vdev_count++; 896 /* save vdev id */ 897 vdev->vdev_objmgr.vdev_id = id; 898 status = QDF_STATUS_SUCCESS; 899 } else { 900 status = QDF_STATUS_E_FAILURE; 901 } 902 wlan_psoc_obj_unlock(psoc); 903 904 return status; 905 } 906 907 QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc, 908 struct wlan_objmgr_vdev *vdev) 909 { 910 struct wlan_objmgr_psoc_objmgr *objmgr; 911 uint8_t id = 0; 912 913 id = vdev->vdev_objmgr.vdev_id; 914 /* Invalid vdev id */ 915 if (id >= wlan_psoc_get_max_vdev_count(psoc)) 916 return QDF_STATUS_E_FAILURE; 917 918 wlan_psoc_obj_lock(psoc); 919 objmgr = &psoc->soc_objmgr; 920 /* unset bit, to free the slot */ 921 qdf_clear_bit(id, objmgr->wlan_vdev_id_map); 922 /* reset VDEV pointer to NULL in VDEV list array */ 923 objmgr->wlan_vdev_list[id] = NULL; 924 /* decrement vdev count */ 925 objmgr->wlan_vdev_count--; 926 vdev->vdev_objmgr.vdev_id = 0xff; 927 wlan_psoc_obj_unlock(psoc); 928 929 return QDF_STATUS_SUCCESS; 930 } 931 932 #ifdef WLAN_OBJMGR_REF_ID_TRACE 933 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_debug( 934 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 935 wlan_objmgr_ref_dbgid dbg_id, 936 const char *func, int line) 937 { 938 struct wlan_objmgr_vdev *vdev; 939 940 /* if PSOC is NULL, return */ 941 if (!psoc) 942 return NULL; 943 /* vdev id is invalid */ 944 if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) 945 return NULL; 946 947 wlan_psoc_obj_lock(psoc); 948 /* retrieve vdev pointer from vdev list */ 949 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; 950 if (vdev) { 951 if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, 952 func, line) != 953 QDF_STATUS_SUCCESS) 954 vdev = NULL; 955 } 956 wlan_psoc_obj_unlock(psoc); 957 958 return vdev; 959 } 960 961 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_debug); 962 #else 963 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc( 964 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 965 wlan_objmgr_ref_dbgid dbg_id) 966 { 967 struct wlan_objmgr_vdev *vdev; 968 969 /* if PSOC is NULL, return */ 970 if (!psoc) 971 return NULL; 972 /* vdev id is invalid */ 973 if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) 974 return NULL; 975 976 wlan_psoc_obj_lock(psoc); 977 /* retrieve vdev pointer from vdev list */ 978 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; 979 if (vdev) { 980 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != 981 QDF_STATUS_SUCCESS) 982 vdev = NULL; 983 } 984 wlan_psoc_obj_unlock(psoc); 985 986 return vdev; 987 } 988 989 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc); 990 #endif 991 992 #ifdef WLAN_OBJMGR_REF_ID_TRACE 993 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state_debug( 994 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 995 wlan_objmgr_ref_dbgid dbg_id, 996 const char *func, int line) 997 { 998 struct wlan_objmgr_vdev *vdev; 999 1000 /* if PSOC is NULL, return */ 1001 if (!psoc) 1002 return NULL; 1003 /* vdev id is invalid */ 1004 if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) 1005 return NULL; 1006 1007 wlan_psoc_obj_lock(psoc); 1008 /* retrieve vdev pointer from vdev list */ 1009 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; 1010 if (vdev) 1011 wlan_objmgr_vdev_get_ref_debug(vdev, dbg_id, func, line); 1012 1013 wlan_psoc_obj_unlock(psoc); 1014 1015 return vdev; 1016 } 1017 1018 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state_debug); 1019 #else 1020 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state( 1021 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 1022 wlan_objmgr_ref_dbgid dbg_id) 1023 { 1024 struct wlan_objmgr_vdev *vdev; 1025 1026 /* if PSOC is NULL, return */ 1027 if (!psoc) 1028 return NULL; 1029 /* vdev id is invalid */ 1030 if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) 1031 return NULL; 1032 1033 wlan_psoc_obj_lock(psoc); 1034 /* retrieve vdev pointer from vdev list */ 1035 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; 1036 if (vdev) 1037 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 1038 1039 wlan_psoc_obj_unlock(psoc); 1040 1041 return vdev; 1042 } 1043 1044 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state); 1045 #endif 1046 1047 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1048 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc_debug( 1049 struct wlan_objmgr_psoc *psoc, 1050 enum QDF_OPMODE opmode, 1051 wlan_objmgr_ref_dbgid dbg_id, 1052 const char *func, int line) 1053 { 1054 struct wlan_objmgr_vdev *vdev = NULL; 1055 int vdev_cnt = 0; 1056 uint16_t max_vdev_cnt; 1057 1058 /* if PSOC is NULL, return */ 1059 if (!psoc) 1060 return NULL; 1061 1062 wlan_psoc_obj_lock(psoc); 1063 1064 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 1065 /* retrieve vdev pointer from vdev list */ 1066 while (vdev_cnt < max_vdev_cnt) { 1067 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt]; 1068 vdev_cnt++; 1069 if (!vdev) 1070 continue; 1071 wlan_vdev_obj_lock(vdev); 1072 if (vdev->vdev_mlme.vdev_opmode == opmode) { 1073 wlan_vdev_obj_unlock(vdev); 1074 if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, 1075 func, line) != 1076 QDF_STATUS_SUCCESS) { 1077 vdev = NULL; 1078 continue; 1079 } 1080 break; 1081 } 1082 wlan_vdev_obj_unlock(vdev); 1083 } 1084 wlan_psoc_obj_unlock(psoc); 1085 1086 return vdev; 1087 } 1088 #else 1089 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc( 1090 struct wlan_objmgr_psoc *psoc, 1091 enum QDF_OPMODE opmode, 1092 wlan_objmgr_ref_dbgid dbg_id) 1093 { 1094 struct wlan_objmgr_vdev *vdev = NULL; 1095 int vdev_cnt = 0; 1096 uint16_t max_vdev_cnt; 1097 1098 /* if PSOC is NULL, return */ 1099 if (!psoc) 1100 return NULL; 1101 1102 wlan_psoc_obj_lock(psoc); 1103 1104 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 1105 /* retrieve vdev pointer from vdev list */ 1106 while (vdev_cnt < max_vdev_cnt) { 1107 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt]; 1108 vdev_cnt++; 1109 if (!vdev) 1110 continue; 1111 wlan_vdev_obj_lock(vdev); 1112 if (vdev->vdev_mlme.vdev_opmode == opmode) { 1113 wlan_vdev_obj_unlock(vdev); 1114 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != 1115 QDF_STATUS_SUCCESS) { 1116 vdev = NULL; 1117 continue; 1118 } 1119 break; 1120 } 1121 wlan_vdev_obj_unlock(vdev); 1122 } 1123 wlan_psoc_obj_unlock(psoc); 1124 1125 return vdev; 1126 } 1127 #endif 1128 1129 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1130 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_debug( 1131 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1132 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 1133 const char *func, int line) 1134 { 1135 struct wlan_objmgr_vdev *vdev; 1136 struct wlan_objmgr_pdev *pdev; 1137 1138 /* if PSOC is NULL, return */ 1139 if (!psoc) 1140 return NULL; 1141 1142 if (!macaddr) 1143 return NULL; 1144 1145 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 1146 if (!pdev) { 1147 obj_mgr_err("pdev is null"); 1148 return NULL; 1149 } 1150 vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_debug(pdev, macaddr, 1151 dbg_id, 1152 func, line); 1153 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 1154 1155 return vdev; 1156 } 1157 1158 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_debug); 1159 #else 1160 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc( 1161 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1162 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 1163 { 1164 struct wlan_objmgr_vdev *vdev; 1165 struct wlan_objmgr_pdev *pdev; 1166 1167 /* if PSOC is NULL, return */ 1168 if (!psoc) 1169 return NULL; 1170 1171 if (!macaddr) 1172 return NULL; 1173 1174 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 1175 if (!pdev) { 1176 obj_mgr_err("pdev is null"); 1177 return NULL; 1178 } 1179 vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, macaddr, dbg_id); 1180 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 1181 1182 return vdev; 1183 } 1184 1185 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc); 1186 #endif 1187 1188 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1189 struct wlan_objmgr_vdev 1190 *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state_debug( 1191 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1192 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 1193 const char *func, int line) 1194 { 1195 struct wlan_objmgr_vdev *vdev; 1196 struct wlan_objmgr_pdev *pdev; 1197 1198 /* if PSOC is NULL, return */ 1199 if (!psoc) 1200 return NULL; 1201 1202 if (!macaddr) 1203 return NULL; 1204 1205 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 1206 if (!pdev) { 1207 obj_mgr_err("pdev is null"); 1208 return NULL; 1209 } 1210 vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state_debug(pdev, 1211 macaddr, 1212 dbg_id, 1213 func, 1214 line); 1215 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 1216 1217 return vdev; 1218 } 1219 1220 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state_debug); 1221 #else 1222 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state( 1223 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 1224 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 1225 { 1226 struct wlan_objmgr_vdev *vdev; 1227 struct wlan_objmgr_pdev *pdev; 1228 1229 /* if PSOC is NULL, return */ 1230 if (!psoc) 1231 return NULL; 1232 1233 if (!macaddr) 1234 return NULL; 1235 1236 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, dbg_id); 1237 if (!pdev) { 1238 obj_mgr_err("pdev is null"); 1239 return NULL; 1240 } 1241 vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev_no_state(pdev, macaddr, dbg_id); 1242 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 1243 1244 return vdev; 1245 } 1246 1247 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state); 1248 #endif 1249 1250 static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list, 1251 struct wlan_objmgr_peer *obj) 1252 { 1253 qdf_list_insert_back(obj_list, &obj->psoc_peer); 1254 } 1255 1256 static QDF_STATUS wlan_obj_psoc_peerlist_remove_peer( 1257 qdf_list_t *obj_list, 1258 struct wlan_objmgr_peer *peer) 1259 { 1260 qdf_list_node_t *psoc_node = NULL; 1261 1262 if (!peer) 1263 return QDF_STATUS_E_FAILURE; 1264 /* get vdev list node element */ 1265 psoc_node = &peer->psoc_peer; 1266 /* list is empty, return failure */ 1267 if (qdf_list_remove_node(obj_list, psoc_node) != QDF_STATUS_SUCCESS) 1268 return QDF_STATUS_E_FAILURE; 1269 1270 return QDF_STATUS_SUCCESS; 1271 } 1272 1273 static QDF_STATUS wlan_peer_bssid_match(struct wlan_objmgr_peer *peer, 1274 uint8_t *bssid) 1275 { 1276 struct wlan_objmgr_vdev *vdev = wlan_peer_get_vdev(peer); 1277 uint8_t *peer_bssid = wlan_vdev_mlme_get_macaddr(vdev); 1278 1279 if (WLAN_ADDR_EQ(peer_bssid, bssid) == QDF_STATUS_SUCCESS) 1280 return QDF_STATUS_SUCCESS; 1281 else 1282 return QDF_STATUS_E_FAILURE; 1283 } 1284 1285 /** 1286 * wlan_obj_psoc_peerlist_get_peer_by_pdev_id() - get peer from 1287 * psoc peer list 1288 * @psoc: PSOC object 1289 * @macaddr: MAC address 1290 * #pdev_id: Pdev id 1291 * 1292 * API to finds peer object pointer by MAC addr and pdev id from hash list 1293 * 1294 * Return: peer pointer 1295 * NULL on FAILURE 1296 */ 1297 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1298 static struct wlan_objmgr_peer 1299 *wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( 1300 qdf_list_t *obj_list, uint8_t *macaddr, 1301 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id, 1302 const char *func, int line) 1303 { 1304 struct wlan_objmgr_peer *peer; 1305 struct wlan_objmgr_peer *peer_temp; 1306 1307 /* Iterate through hash list to get the peer */ 1308 peer = wlan_psoc_peer_list_peek_head(obj_list); 1309 while (peer) { 1310 /* For peer, macaddr is key */ 1311 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1312 == QDF_STATUS_SUCCESS) && 1313 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1314 if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, 1315 func, line) == 1316 QDF_STATUS_SUCCESS) { 1317 return peer; 1318 } 1319 } 1320 /* Move to next peer */ 1321 peer_temp = peer; 1322 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1323 } 1324 1325 /* Not found, return NULL */ 1326 return NULL; 1327 } 1328 #else 1329 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id( 1330 qdf_list_t *obj_list, uint8_t *macaddr, 1331 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) 1332 { 1333 struct wlan_objmgr_peer *peer; 1334 struct wlan_objmgr_peer *peer_temp; 1335 1336 /* Iterate through hash list to get the peer */ 1337 peer = wlan_psoc_peer_list_peek_head(obj_list); 1338 while (peer) { 1339 /* For peer, macaddr is key */ 1340 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1341 == QDF_STATUS_SUCCESS) && 1342 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1343 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 1344 QDF_STATUS_SUCCESS) { 1345 return peer; 1346 } 1347 } 1348 /* Move to next peer */ 1349 peer_temp = peer; 1350 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1351 } 1352 1353 /* Not found, return NULL */ 1354 return NULL; 1355 } 1356 #endif 1357 1358 /** 1359 * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list 1360 * @psoc: PSOC object 1361 * @macaddr: MAC address 1362 * 1363 * API to finds peer object pointer by MAC addr from hash list 1364 * 1365 * Return: peer pointer 1366 * NULL on FAILURE 1367 */ 1368 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1369 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_debug( 1370 qdf_list_t *obj_list, uint8_t *macaddr, 1371 wlan_objmgr_ref_dbgid dbg_id, 1372 const char *func, int line) 1373 { 1374 struct wlan_objmgr_peer *peer; 1375 struct wlan_objmgr_peer *peer_temp; 1376 1377 /* Iterate through hash list to get the peer */ 1378 peer = wlan_psoc_peer_list_peek_head(obj_list); 1379 while (peer) { 1380 /* For peer, macaddr is key */ 1381 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1382 == QDF_STATUS_SUCCESS) { 1383 if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, 1384 func, line) == 1385 QDF_STATUS_SUCCESS) { 1386 return peer; 1387 } 1388 } 1389 /* Move to next peer */ 1390 peer_temp = peer; 1391 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1392 } 1393 1394 /* Not found, return NULL */ 1395 return NULL; 1396 } 1397 #else 1398 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( 1399 qdf_list_t *obj_list, uint8_t *macaddr, 1400 wlan_objmgr_ref_dbgid dbg_id) 1401 { 1402 struct wlan_objmgr_peer *peer; 1403 struct wlan_objmgr_peer *peer_temp; 1404 1405 /* Iterate through hash list to get the peer */ 1406 peer = wlan_psoc_peer_list_peek_head(obj_list); 1407 while (peer) { 1408 /* For peer, macaddr is key */ 1409 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1410 == QDF_STATUS_SUCCESS) { 1411 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 1412 QDF_STATUS_SUCCESS) { 1413 return peer; 1414 } 1415 } 1416 /* Move to next peer */ 1417 peer_temp = peer; 1418 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1419 } 1420 1421 /* Not found, return NULL */ 1422 return NULL; 1423 } 1424 #endif 1425 1426 /** 1427 * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer 1428 * from psoc peer list 1429 * @psoc: PSOC object 1430 * @macaddr: MAC address 1431 * 1432 * API to finds peer object pointer of logically deleted peer 1433 * 1434 * Return: peer pointer 1435 * NULL on FAILURE 1436 */ 1437 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1438 static struct wlan_objmgr_peer * 1439 wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug( 1440 qdf_list_t *obj_list, uint8_t *macaddr, 1441 wlan_objmgr_ref_dbgid dbg_id, 1442 const char *func, int line) 1443 { 1444 struct wlan_objmgr_peer *peer; 1445 struct wlan_objmgr_peer *peer_temp; 1446 1447 /* Iterate through hash list to get the peer */ 1448 peer = wlan_psoc_peer_list_peek_head(obj_list); 1449 while (peer) { 1450 /* For peer, macaddr is key */ 1451 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1452 == QDF_STATUS_SUCCESS) { 1453 /* Return peer in logically deleted state */ 1454 if (peer->obj_state == 1455 WLAN_OBJ_STATE_LOGICALLY_DELETED) { 1456 wlan_objmgr_peer_get_ref_debug(peer, dbg_id, 1457 func, line); 1458 1459 return peer; 1460 } 1461 1462 } 1463 /* Move to next peer */ 1464 peer_temp = peer; 1465 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1466 } 1467 1468 /* Not found, return NULL */ 1469 return NULL; 1470 } 1471 #else 1472 static struct wlan_objmgr_peer * 1473 wlan_obj_psoc_peerlist_get_peer_logically_deleted( 1474 qdf_list_t *obj_list, uint8_t *macaddr, 1475 wlan_objmgr_ref_dbgid dbg_id) 1476 { 1477 struct wlan_objmgr_peer *peer; 1478 struct wlan_objmgr_peer *peer_temp; 1479 1480 /* Iterate through hash list to get the peer */ 1481 peer = wlan_psoc_peer_list_peek_head(obj_list); 1482 while (peer) { 1483 /* For peer, macaddr is key */ 1484 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1485 == QDF_STATUS_SUCCESS) { 1486 /* Return peer in logically deleted state */ 1487 if (peer->obj_state == 1488 WLAN_OBJ_STATE_LOGICALLY_DELETED) { 1489 wlan_objmgr_peer_get_ref(peer, dbg_id); 1490 1491 return peer; 1492 } 1493 } 1494 /* Move to next peer */ 1495 peer_temp = peer; 1496 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1497 } 1498 1499 /* Not found, return NULL */ 1500 return NULL; 1501 } 1502 #endif 1503 1504 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1505 static struct wlan_objmgr_peer 1506 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state_debug( 1507 qdf_list_t *obj_list, uint8_t *macaddr, 1508 uint8_t *bssid, 1509 uint8_t pdev_id, 1510 wlan_objmgr_ref_dbgid dbg_id, 1511 const char *func, int line) 1512 { 1513 struct wlan_objmgr_peer *peer; 1514 struct wlan_objmgr_peer *peer_temp; 1515 1516 /* Iterate through hash list to get the peer */ 1517 peer = wlan_psoc_peer_list_peek_head(obj_list); 1518 while (peer) { 1519 /* For peer, macaddr is key */ 1520 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1521 == QDF_STATUS_SUCCESS) { 1522 /* 1523 * BSSID match is requested by caller, check BSSID 1524 * (vdev mac == bssid) -- return peer 1525 * (vdev mac != bssid) -- perform next iteration 1526 */ 1527 if ((wlan_peer_bssid_match(peer, bssid) == 1528 QDF_STATUS_SUCCESS) && 1529 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1530 wlan_objmgr_peer_get_ref_debug(peer, dbg_id, 1531 func, line); 1532 1533 return peer; 1534 } 1535 } 1536 /* Move to next peer */ 1537 peer_temp = peer; 1538 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1539 } 1540 1541 /* Not found, return NULL */ 1542 return NULL; 1543 } 1544 #else 1545 static struct wlan_objmgr_peer 1546 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( 1547 qdf_list_t *obj_list, uint8_t *macaddr, 1548 uint8_t *bssid, 1549 uint8_t pdev_id, 1550 wlan_objmgr_ref_dbgid dbg_id) 1551 { 1552 struct wlan_objmgr_peer *peer; 1553 struct wlan_objmgr_peer *peer_temp; 1554 1555 /* Iterate through hash list to get the peer */ 1556 peer = wlan_psoc_peer_list_peek_head(obj_list); 1557 while (peer) { 1558 /* For peer, macaddr is key */ 1559 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1560 == QDF_STATUS_SUCCESS) { 1561 /* 1562 * BSSID match is requested by caller, check BSSID 1563 * (vdev mac == bssid) -- return peer 1564 * (vdev mac != bssid) -- perform next iteration 1565 */ 1566 if ((wlan_peer_bssid_match(peer, bssid) == 1567 QDF_STATUS_SUCCESS) && 1568 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1569 wlan_objmgr_peer_get_ref(peer, dbg_id); 1570 1571 return peer; 1572 } 1573 } 1574 /* Move to next peer */ 1575 peer_temp = peer; 1576 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1577 } 1578 1579 /* Not found, return NULL */ 1580 return NULL; 1581 } 1582 #endif 1583 1584 /** 1585 * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer 1586 * from psoc peer 1587 * list using mac and vdev 1588 * self mac 1589 * @psoc: PSOC object 1590 * @macaddr: MAC address 1591 * @bssid: BSSID address 1592 * 1593 * API to finds peer object pointer by MAC addr and BSSID from 1594 * peer hash list, bssid check is done on matching peer 1595 * 1596 * Return: peer pointer 1597 * NULL on FAILURE 1598 */ 1599 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1600 static struct wlan_objmgr_peer 1601 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug( 1602 qdf_list_t *obj_list, uint8_t *macaddr, 1603 uint8_t *bssid, uint8_t pdev_id, 1604 wlan_objmgr_ref_dbgid dbg_id, 1605 const char *func, int line) 1606 { 1607 struct wlan_objmgr_peer *peer; 1608 struct wlan_objmgr_peer *peer_temp; 1609 1610 /* Iterate through hash list to get the peer */ 1611 peer = wlan_psoc_peer_list_peek_head(obj_list); 1612 while (peer) { 1613 /* For peer, macaddr is key */ 1614 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1615 == QDF_STATUS_SUCCESS) { 1616 /* 1617 * BSSID match is requested by caller, check BSSID 1618 * (vdev mac == bssid) -- return peer 1619 * (vdev mac != bssid) -- perform next iteration 1620 */ 1621 if ((wlan_peer_bssid_match(peer, bssid) == 1622 QDF_STATUS_SUCCESS) && 1623 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1624 if (wlan_objmgr_peer_try_get_ref_debug(peer, 1625 dbg_id, 1626 func, 1627 line) 1628 == QDF_STATUS_SUCCESS) { 1629 return peer; 1630 } 1631 } 1632 } 1633 /* Move to next peer */ 1634 peer_temp = peer; 1635 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1636 } 1637 /* Not found, return NULL */ 1638 return NULL; 1639 } 1640 #else 1641 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( 1642 qdf_list_t *obj_list, uint8_t *macaddr, 1643 uint8_t *bssid, uint8_t pdev_id, 1644 wlan_objmgr_ref_dbgid dbg_id) 1645 { 1646 struct wlan_objmgr_peer *peer; 1647 struct wlan_objmgr_peer *peer_temp; 1648 1649 /* Iterate through hash list to get the peer */ 1650 peer = wlan_psoc_peer_list_peek_head(obj_list); 1651 while (peer) { 1652 /* For peer, macaddr is key */ 1653 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1654 == QDF_STATUS_SUCCESS) { 1655 /* 1656 * BSSID match is requested by caller, check BSSID 1657 * (vdev mac == bssid) -- return peer 1658 * (vdev mac != bssid) -- perform next iteration 1659 */ 1660 if ((wlan_peer_bssid_match(peer, bssid) == 1661 QDF_STATUS_SUCCESS) && 1662 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1663 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) 1664 == QDF_STATUS_SUCCESS) { 1665 return peer; 1666 } 1667 } 1668 } 1669 /* Move to next peer */ 1670 peer_temp = peer; 1671 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1672 } 1673 /* Not found, return NULL */ 1674 return NULL; 1675 } 1676 #endif 1677 1678 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1679 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state_debug( 1680 qdf_list_t *obj_list, uint8_t *macaddr, 1681 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id, 1682 const char *func, int line) 1683 { 1684 struct wlan_objmgr_peer *peer; 1685 struct wlan_objmgr_peer *peer_temp; 1686 1687 /* Iterate through hash list to get the peer */ 1688 peer = wlan_psoc_peer_list_peek_head(obj_list); 1689 while (peer) { 1690 /* For peer, macaddr and pdev_id is key */ 1691 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1692 == QDF_STATUS_SUCCESS) && 1693 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1694 wlan_objmgr_peer_get_ref_debug(peer, dbg_id, func, 1695 line); 1696 1697 return peer; 1698 } 1699 /* Move to next peer */ 1700 peer_temp = peer; 1701 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1702 } 1703 1704 /* Not found, return NULL */ 1705 return NULL; 1706 } 1707 #else 1708 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( 1709 qdf_list_t *obj_list, uint8_t *macaddr, 1710 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) 1711 { 1712 struct wlan_objmgr_peer *peer; 1713 struct wlan_objmgr_peer *peer_temp; 1714 1715 /* Iterate through hash list to get the peer */ 1716 peer = wlan_psoc_peer_list_peek_head(obj_list); 1717 while (peer) { 1718 /* For peer, macaddr and pdev_id is key */ 1719 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1720 == QDF_STATUS_SUCCESS) && 1721 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1722 wlan_objmgr_peer_get_ref(peer, dbg_id); 1723 1724 return peer; 1725 } 1726 /* Move to next peer */ 1727 peer_temp = peer; 1728 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1729 } 1730 1731 /* Not found, return NULL */ 1732 return NULL; 1733 } 1734 #endif 1735 1736 /** 1737 * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - 1738 * get peer 1739 * from psoc peer list using 1740 * mac and vdev self mac 1741 * @obj_list: peer object list 1742 * @macaddr: MAC address 1743 * @bssid: BSSID address 1744 * @dbg_id: id of the caller 1745 * @func: function name 1746 * @line: line number 1747 * 1748 * API to finds peer object pointer by MAC addr and BSSID from 1749 * peer hash list for a node which is in logically deleted state, 1750 * bssid check is done on matching peer 1751 * 1752 * Caller to free the list allocated in this function 1753 * 1754 * Return: list of peer pointers 1755 * NULL on FAILURE 1756 */ 1757 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1758 static qdf_list_t 1759 *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug( 1760 qdf_list_t *obj_list, uint8_t *macaddr, 1761 uint8_t *bssid, uint8_t pdev_id, 1762 wlan_objmgr_ref_dbgid dbg_id, 1763 const char *func, int line) 1764 { 1765 struct wlan_objmgr_peer *peer; 1766 struct wlan_objmgr_peer *peer_temp; 1767 struct wlan_logically_del_peer *peer_list = NULL; 1768 qdf_list_t *logical_del_peer_list = NULL; 1769 bool lock_released = false; 1770 1771 logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); 1772 if (!logical_del_peer_list) 1773 return NULL; 1774 1775 qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); 1776 1777 /* Iterate through hash list to get the peer */ 1778 peer = wlan_psoc_peer_list_peek_head(obj_list); 1779 while (peer) { 1780 wlan_peer_obj_lock(peer); 1781 /* For peer, macaddr and pdev id are keys */ 1782 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1783 == QDF_STATUS_SUCCESS) && 1784 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1785 /* 1786 * if BSSID not NULL, 1787 * then match is requested by caller, check BSSID 1788 * (vdev mac == bssid) -- return peer 1789 * (vdev mac != bssid) -- perform next iteration 1790 */ 1791 if ((!bssid) || 1792 (wlan_peer_bssid_match(peer, bssid) == 1793 QDF_STATUS_SUCCESS)) { 1794 /* Return peer in logically deleted state */ 1795 if ((peer->obj_state == 1796 WLAN_OBJ_STATE_LOGICALLY_DELETED) && 1797 qdf_atomic_read( 1798 &peer->peer_objmgr.ref_cnt)) { 1799 wlan_objmgr_peer_get_ref_debug(peer, 1800 dbg_id, 1801 func, 1802 line); 1803 wlan_peer_obj_unlock(peer); 1804 lock_released = true; 1805 1806 peer_list = 1807 qdf_mem_malloc( 1808 sizeof(struct wlan_logically_del_peer)); 1809 if (!peer_list) { 1810 wlan_objmgr_peer_release_ref(peer, dbg_id); 1811 /* Lock is already released */ 1812 WLAN_OBJMGR_BUG(0); 1813 break; 1814 } 1815 1816 peer_list->peer = peer; 1817 1818 qdf_list_insert_front( 1819 logical_del_peer_list, 1820 &peer_list->list); 1821 } 1822 } 1823 } 1824 1825 if (!lock_released) 1826 wlan_peer_obj_unlock(peer); 1827 1828 /* Move to next peer */ 1829 peer_temp = peer; 1830 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1831 lock_released = false; 1832 } 1833 1834 /* Not found, return NULL */ 1835 if (qdf_list_empty(logical_del_peer_list)) { 1836 qdf_mem_free(logical_del_peer_list); 1837 return NULL; 1838 } else { 1839 return logical_del_peer_list; 1840 } 1841 } 1842 #else 1843 static qdf_list_t 1844 *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( 1845 qdf_list_t *obj_list, uint8_t *macaddr, 1846 uint8_t *bssid, uint8_t pdev_id, 1847 wlan_objmgr_ref_dbgid dbg_id) 1848 { 1849 struct wlan_objmgr_peer *peer; 1850 struct wlan_objmgr_peer *peer_temp; 1851 struct wlan_logically_del_peer *peer_list = NULL; 1852 qdf_list_t *logical_del_peer_list = NULL; 1853 bool lock_released = false; 1854 1855 logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); 1856 if (!logical_del_peer_list) 1857 return NULL; 1858 1859 qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); 1860 1861 /* Iterate through hash list to get the peer */ 1862 peer = wlan_psoc_peer_list_peek_head(obj_list); 1863 while (peer) { 1864 wlan_peer_obj_lock(peer); 1865 /* For peer, macaddr and pdev id are keys */ 1866 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1867 == QDF_STATUS_SUCCESS) && 1868 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1869 /* 1870 * if BSSID not NULL, 1871 * then match is requested by caller, check BSSID 1872 * (vdev mac == bssid) -- return peer 1873 * (vdev mac != bssid) -- perform next iteration 1874 */ 1875 if ((!bssid) || 1876 (wlan_peer_bssid_match(peer, bssid) == 1877 QDF_STATUS_SUCCESS)) { 1878 /* Return peer in logically deleted state */ 1879 if ((peer->obj_state == 1880 WLAN_OBJ_STATE_LOGICALLY_DELETED) && 1881 qdf_atomic_read( 1882 &peer->peer_objmgr.ref_cnt)) { 1883 wlan_objmgr_peer_get_ref(peer, dbg_id); 1884 wlan_peer_obj_unlock(peer); 1885 lock_released = true; 1886 1887 peer_list = 1888 qdf_mem_malloc( 1889 sizeof(struct wlan_logically_del_peer)); 1890 if (!peer_list) { 1891 wlan_objmgr_peer_release_ref(peer, dbg_id); 1892 /* Lock is already released */ 1893 WLAN_OBJMGR_BUG(0); 1894 break; 1895 } 1896 1897 peer_list->peer = peer; 1898 1899 qdf_list_insert_front( 1900 logical_del_peer_list, 1901 &peer_list->list); 1902 } 1903 } 1904 } 1905 1906 if (!lock_released) 1907 wlan_peer_obj_unlock(peer); 1908 1909 /* Move to next peer */ 1910 peer_temp = peer; 1911 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1912 lock_released = false; 1913 } 1914 1915 /* Not found, return NULL */ 1916 if (qdf_list_empty(logical_del_peer_list)) { 1917 qdf_mem_free(logical_del_peer_list); 1918 return NULL; 1919 } else { 1920 return logical_del_peer_list; 1921 } 1922 } 1923 #endif 1924 1925 QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc, 1926 struct wlan_objmgr_peer *peer) 1927 { 1928 struct wlan_objmgr_psoc_objmgr *objmgr; 1929 uint8_t hash_index; 1930 struct wlan_peer_list *peer_list; 1931 1932 wlan_psoc_obj_lock(psoc); 1933 objmgr = &psoc->soc_objmgr; 1934 /* Max temporary peer limit is reached, return failure */ 1935 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) { 1936 if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) { 1937 wlan_psoc_obj_unlock(psoc); 1938 return QDF_STATUS_E_FAILURE; 1939 } 1940 } else { 1941 /* Max peer limit is reached, return failure */ 1942 if (objmgr->wlan_peer_count 1943 >= wlan_psoc_get_max_peer_count(psoc)) { 1944 wlan_psoc_obj_unlock(psoc); 1945 return QDF_STATUS_E_FAILURE; 1946 } 1947 } 1948 1949 /* Derive hash index from mac address */ 1950 hash_index = WLAN_PEER_HASH(peer->macaddr); 1951 peer_list = &objmgr->peer_list; 1952 /* psoc lock should be taken before list lock */ 1953 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1954 /* add peer to hash peer list */ 1955 wlan_obj_psoc_peerlist_add_tail( 1956 &peer_list->peer_hash[hash_index], 1957 peer); 1958 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1959 /* Increment peer count */ 1960 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) 1961 objmgr->temp_peer_count++; 1962 else 1963 objmgr->wlan_peer_count++; 1964 1965 wlan_psoc_obj_unlock(psoc); 1966 1967 return QDF_STATUS_SUCCESS; 1968 } 1969 1970 QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc, 1971 struct wlan_objmgr_peer *peer) 1972 { 1973 struct wlan_objmgr_psoc_objmgr *objmgr; 1974 uint8_t hash_index; 1975 struct wlan_peer_list *peer_list; 1976 1977 wlan_psoc_obj_lock(psoc); 1978 objmgr = &psoc->soc_objmgr; 1979 /* if list is empty, return */ 1980 if (objmgr->wlan_peer_count == 0) { 1981 wlan_psoc_obj_unlock(psoc); 1982 return QDF_STATUS_E_FAILURE; 1983 } 1984 /* Get hash index, to locate the actual peer list */ 1985 hash_index = WLAN_PEER_HASH(peer->macaddr); 1986 peer_list = &objmgr->peer_list; 1987 /* psoc lock should be taken before list lock */ 1988 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1989 /* removes the peer from peer_list */ 1990 if (wlan_obj_psoc_peerlist_remove_peer( 1991 &peer_list->peer_hash[hash_index], 1992 peer) == 1993 QDF_STATUS_E_FAILURE) { 1994 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1995 wlan_psoc_obj_unlock(psoc); 1996 obj_mgr_err("Failed to detach peer"); 1997 return QDF_STATUS_E_FAILURE; 1998 } 1999 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2000 /* Decrement peer count */ 2001 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) 2002 objmgr->temp_peer_count--; 2003 else 2004 objmgr->wlan_peer_count--; 2005 wlan_psoc_obj_unlock(psoc); 2006 2007 return QDF_STATUS_SUCCESS; 2008 } 2009 2010 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2011 struct wlan_objmgr_peer *wlan_objmgr_get_peer_debug( 2012 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2013 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 2014 const char *func, int line) 2015 { 2016 struct wlan_objmgr_psoc_objmgr *objmgr; 2017 uint8_t hash_index; 2018 struct wlan_objmgr_peer *peer = NULL; 2019 struct wlan_peer_list *peer_list; 2020 2021 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) 2022 QDF_ASSERT(0); 2023 2024 if (!macaddr) 2025 return NULL; 2026 2027 /* psoc lock should be taken before peer list lock */ 2028 wlan_psoc_obj_lock(psoc); 2029 objmgr = &psoc->soc_objmgr; 2030 /* List is empty, return NULL */ 2031 if (objmgr->wlan_peer_count == 0) { 2032 wlan_psoc_obj_unlock(psoc); 2033 return NULL; 2034 } 2035 /* reduce the search window, with hash key */ 2036 hash_index = WLAN_PEER_HASH(macaddr); 2037 peer_list = &objmgr->peer_list; 2038 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2039 /* Iterate through peer list, get peer */ 2040 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( 2041 &peer_list->peer_hash[hash_index], macaddr, 2042 pdev_id, dbg_id, func, line); 2043 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2044 wlan_psoc_obj_unlock(psoc); 2045 2046 return peer; 2047 } 2048 2049 qdf_export_symbol(wlan_objmgr_get_peer_debug); 2050 #else 2051 struct wlan_objmgr_peer *wlan_objmgr_get_peer( 2052 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2053 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 2054 { 2055 struct wlan_objmgr_psoc_objmgr *objmgr; 2056 uint8_t hash_index; 2057 struct wlan_objmgr_peer *peer = NULL; 2058 struct wlan_peer_list *peer_list; 2059 2060 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) 2061 QDF_ASSERT(0); 2062 2063 if (!macaddr) 2064 return NULL; 2065 2066 /* psoc lock should be taken before peer list lock */ 2067 wlan_psoc_obj_lock(psoc); 2068 objmgr = &psoc->soc_objmgr; 2069 /* List is empty, return NULL */ 2070 if (objmgr->wlan_peer_count == 0) { 2071 wlan_psoc_obj_unlock(psoc); 2072 return NULL; 2073 } 2074 /* reduce the search window, with hash key */ 2075 hash_index = WLAN_PEER_HASH(macaddr); 2076 peer_list = &objmgr->peer_list; 2077 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2078 /* Iterate through peer list, get peer */ 2079 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id( 2080 &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); 2081 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2082 wlan_psoc_obj_unlock(psoc); 2083 2084 return peer; 2085 } 2086 2087 qdf_export_symbol(wlan_objmgr_get_peer); 2088 #endif 2089 2090 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2091 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_debug( 2092 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2093 wlan_objmgr_ref_dbgid dbg_id, 2094 const char *func, int line) 2095 { 2096 struct wlan_objmgr_psoc_objmgr *objmgr; 2097 uint8_t hash_index; 2098 struct wlan_objmgr_peer *peer = NULL; 2099 struct wlan_peer_list *peer_list; 2100 2101 if (!macaddr) 2102 return NULL; 2103 2104 /* psoc lock should be taken before peer list lock */ 2105 wlan_psoc_obj_lock(psoc); 2106 objmgr = &psoc->soc_objmgr; 2107 /* List is empty, return NULL */ 2108 if (objmgr->wlan_peer_count == 0) { 2109 wlan_psoc_obj_unlock(psoc); 2110 return NULL; 2111 } 2112 /* reduce the search window, with hash key */ 2113 hash_index = WLAN_PEER_HASH(macaddr); 2114 peer_list = &objmgr->peer_list; 2115 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2116 /* Iterate through peer list, get peer */ 2117 peer = wlan_obj_psoc_peerlist_get_peer_debug( 2118 &peer_list->peer_hash[hash_index], 2119 macaddr, dbg_id, func, line); 2120 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2121 wlan_psoc_obj_unlock(psoc); 2122 2123 return peer; 2124 } 2125 2126 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_debug); 2127 #else 2128 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( 2129 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2130 wlan_objmgr_ref_dbgid dbg_id) 2131 { 2132 struct wlan_objmgr_psoc_objmgr *objmgr; 2133 uint8_t hash_index; 2134 struct wlan_objmgr_peer *peer = NULL; 2135 struct wlan_peer_list *peer_list; 2136 2137 if (!macaddr) 2138 return NULL; 2139 2140 /* psoc lock should be taken before peer list lock */ 2141 wlan_psoc_obj_lock(psoc); 2142 objmgr = &psoc->soc_objmgr; 2143 /* List is empty, return NULL */ 2144 if (objmgr->wlan_peer_count == 0) { 2145 wlan_psoc_obj_unlock(psoc); 2146 return NULL; 2147 } 2148 /* reduce the search window, with hash key */ 2149 hash_index = WLAN_PEER_HASH(macaddr); 2150 peer_list = &objmgr->peer_list; 2151 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2152 /* Iterate through peer list, get peer */ 2153 peer = wlan_obj_psoc_peerlist_get_peer( 2154 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 2155 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2156 wlan_psoc_obj_unlock(psoc); 2157 2158 return peer; 2159 } 2160 2161 qdf_export_symbol(wlan_objmgr_get_peer_by_mac); 2162 #endif 2163 2164 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2165 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted_debug( 2166 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2167 wlan_objmgr_ref_dbgid dbg_id, 2168 const char *func, int line) 2169 { 2170 struct wlan_objmgr_psoc_objmgr *objmgr; 2171 uint8_t hash_index; 2172 struct wlan_objmgr_peer *peer = NULL; 2173 struct wlan_peer_list *peer_list; 2174 2175 /* psoc lock should be taken before peer list lock */ 2176 wlan_psoc_obj_lock(psoc); 2177 objmgr = &psoc->soc_objmgr; 2178 /* List is empty, return NULL */ 2179 if (objmgr->wlan_peer_count == 0) { 2180 wlan_psoc_obj_unlock(psoc); 2181 return NULL; 2182 } 2183 /* reduce the search window, with hash key */ 2184 hash_index = WLAN_PEER_HASH(macaddr); 2185 peer_list = &objmgr->peer_list; 2186 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2187 /* Iterate through peer list, get peer */ 2188 peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug( 2189 &peer_list->peer_hash[hash_index], macaddr, dbg_id, 2190 func, line); 2191 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2192 wlan_psoc_obj_unlock(psoc); 2193 2194 return peer; 2195 } 2196 #else 2197 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( 2198 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2199 wlan_objmgr_ref_dbgid dbg_id) 2200 { 2201 struct wlan_objmgr_psoc_objmgr *objmgr; 2202 uint8_t hash_index; 2203 struct wlan_objmgr_peer *peer = NULL; 2204 struct wlan_peer_list *peer_list; 2205 2206 /* psoc lock should be taken before peer list lock */ 2207 wlan_psoc_obj_lock(psoc); 2208 objmgr = &psoc->soc_objmgr; 2209 /* List is empty, return NULL */ 2210 if (objmgr->wlan_peer_count == 0) { 2211 wlan_psoc_obj_unlock(psoc); 2212 return NULL; 2213 } 2214 /* reduce the search window, with hash key */ 2215 hash_index = WLAN_PEER_HASH(macaddr); 2216 peer_list = &objmgr->peer_list; 2217 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2218 /* Iterate through peer list, get peer */ 2219 peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted( 2220 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 2221 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2222 wlan_psoc_obj_unlock(psoc); 2223 2224 return peer; 2225 } 2226 #endif 2227 2228 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2229 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug( 2230 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2231 uint8_t *bssid, uint8_t *macaddr, 2232 wlan_objmgr_ref_dbgid dbg_id, 2233 const char *func, int line) 2234 { 2235 struct wlan_objmgr_psoc_objmgr *objmgr; 2236 uint8_t hash_index; 2237 struct wlan_objmgr_peer *peer = NULL; 2238 struct wlan_peer_list *peer_list; 2239 2240 /* psoc lock should be taken before peer list lock */ 2241 wlan_psoc_obj_lock(psoc); 2242 objmgr = &psoc->soc_objmgr; 2243 /* List is empty, return NULL */ 2244 if (objmgr->wlan_peer_count == 0) { 2245 wlan_psoc_obj_unlock(psoc); 2246 return NULL; 2247 } 2248 /* reduce the search window, with hash key */ 2249 hash_index = WLAN_PEER_HASH(macaddr); 2250 peer_list = &objmgr->peer_list; 2251 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2252 /* Iterate through peer list, get peer */ 2253 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state_debug( 2254 &peer_list->peer_hash[hash_index], macaddr, bssid, 2255 pdev_id, dbg_id, func, line); 2256 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2257 wlan_psoc_obj_unlock(psoc); 2258 2259 return peer; 2260 } 2261 2262 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug); 2263 #else 2264 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( 2265 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2266 uint8_t *bssid, uint8_t *macaddr, 2267 wlan_objmgr_ref_dbgid dbg_id) 2268 { 2269 struct wlan_objmgr_psoc_objmgr *objmgr; 2270 uint8_t hash_index; 2271 struct wlan_objmgr_peer *peer = NULL; 2272 struct wlan_peer_list *peer_list; 2273 2274 /* psoc lock should be taken before peer list lock */ 2275 wlan_psoc_obj_lock(psoc); 2276 objmgr = &psoc->soc_objmgr; 2277 /* List is empty, return NULL */ 2278 if (objmgr->wlan_peer_count == 0) { 2279 wlan_psoc_obj_unlock(psoc); 2280 return NULL; 2281 } 2282 /* reduce the search window, with hash key */ 2283 hash_index = WLAN_PEER_HASH(macaddr); 2284 peer_list = &objmgr->peer_list; 2285 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2286 /* Iterate through peer list, get peer */ 2287 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( 2288 &peer_list->peer_hash[hash_index], macaddr, bssid, 2289 pdev_id, dbg_id); 2290 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2291 wlan_psoc_obj_unlock(psoc); 2292 2293 return peer; 2294 } 2295 2296 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state); 2297 #endif 2298 2299 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2300 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_debug( 2301 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2302 uint8_t *bssid, uint8_t *macaddr, 2303 wlan_objmgr_ref_dbgid dbg_id, 2304 const char *func, int line) 2305 { 2306 struct wlan_objmgr_psoc_objmgr *objmgr; 2307 uint8_t hash_index; 2308 struct wlan_objmgr_peer *peer = NULL; 2309 struct wlan_peer_list *peer_list; 2310 2311 /* psoc lock should be taken before peer list lock */ 2312 wlan_psoc_obj_lock(psoc); 2313 objmgr = &psoc->soc_objmgr; 2314 /* List is empty, return NULL */ 2315 if (objmgr->wlan_peer_count == 0) { 2316 wlan_psoc_obj_unlock(psoc); 2317 return NULL; 2318 } 2319 /* reduce the search window, with hash key */ 2320 hash_index = WLAN_PEER_HASH(macaddr); 2321 peer_list = &objmgr->peer_list; 2322 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2323 /* Iterate through peer list, get peer */ 2324 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug( 2325 &peer_list->peer_hash[hash_index], macaddr, bssid, 2326 pdev_id, dbg_id, func, line); 2327 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2328 wlan_psoc_obj_unlock(psoc); 2329 2330 return peer; 2331 } 2332 2333 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_debug); 2334 #else 2335 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( 2336 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2337 uint8_t *bssid, uint8_t *macaddr, 2338 wlan_objmgr_ref_dbgid dbg_id) 2339 { 2340 struct wlan_objmgr_psoc_objmgr *objmgr; 2341 uint8_t hash_index; 2342 struct wlan_objmgr_peer *peer = NULL; 2343 struct wlan_peer_list *peer_list; 2344 2345 /* psoc lock should be taken before peer list lock */ 2346 wlan_psoc_obj_lock(psoc); 2347 objmgr = &psoc->soc_objmgr; 2348 /* List is empty, return NULL */ 2349 if (objmgr->wlan_peer_count == 0) { 2350 wlan_psoc_obj_unlock(psoc); 2351 return NULL; 2352 } 2353 /* reduce the search window, with hash key */ 2354 hash_index = WLAN_PEER_HASH(macaddr); 2355 peer_list = &objmgr->peer_list; 2356 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2357 /* Iterate through peer list, get peer */ 2358 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( 2359 &peer_list->peer_hash[hash_index], macaddr, bssid, 2360 pdev_id, dbg_id); 2361 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2362 wlan_psoc_obj_unlock(psoc); 2363 2364 return peer; 2365 } 2366 2367 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); 2368 #endif 2369 2370 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2371 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock_debug( 2372 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2373 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 2374 const char *func, int line) 2375 { 2376 struct wlan_objmgr_psoc_objmgr *objmgr; 2377 uint8_t hash_index; 2378 struct wlan_objmgr_peer *peer = NULL; 2379 struct wlan_peer_list *peer_list; 2380 2381 /* psoc lock should be taken before peer list lock */ 2382 objmgr = &psoc->soc_objmgr; 2383 /* List is empty, return NULL */ 2384 if (objmgr->wlan_peer_count == 0) 2385 return NULL; 2386 2387 /* reduce the search window, with hash key */ 2388 hash_index = WLAN_PEER_HASH(macaddr); 2389 peer_list = &objmgr->peer_list; 2390 /* Iterate through peer list, get peer */ 2391 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( 2392 &peer_list->peer_hash[hash_index], macaddr, 2393 pdev_id, dbg_id, func, line); 2394 2395 return peer; 2396 } 2397 2398 qdf_export_symbol(wlan_objmgr_get_peer_nolock_debug); 2399 #else 2400 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( 2401 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2402 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 2403 { 2404 struct wlan_objmgr_psoc_objmgr *objmgr; 2405 uint8_t hash_index; 2406 struct wlan_objmgr_peer *peer = NULL; 2407 struct wlan_peer_list *peer_list; 2408 2409 /* psoc lock should be taken before peer list lock */ 2410 objmgr = &psoc->soc_objmgr; 2411 /* List is empty, return NULL */ 2412 if (objmgr->wlan_peer_count == 0) 2413 return NULL; 2414 2415 /* reduce the search window, with hash key */ 2416 hash_index = WLAN_PEER_HASH(macaddr); 2417 peer_list = &objmgr->peer_list; 2418 /* Iterate through peer list, get peer */ 2419 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id( 2420 &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); 2421 2422 return peer; 2423 } 2424 2425 qdf_export_symbol(wlan_objmgr_get_peer_nolock); 2426 #endif 2427 2428 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2429 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state_debug( 2430 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2431 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 2432 const char *func, int line) 2433 { 2434 struct wlan_objmgr_psoc_objmgr *objmgr; 2435 uint8_t hash_index; 2436 struct wlan_objmgr_peer *peer = NULL; 2437 struct wlan_peer_list *peer_list; 2438 2439 /* psoc lock should be taken before peer list lock */ 2440 wlan_psoc_obj_lock(psoc); 2441 objmgr = &psoc->soc_objmgr; 2442 /* List is empty, return NULL */ 2443 if (objmgr->wlan_peer_count == 0) { 2444 wlan_psoc_obj_unlock(psoc); 2445 return NULL; 2446 } 2447 /* reduce the search window, with hash key */ 2448 hash_index = WLAN_PEER_HASH(macaddr); 2449 peer_list = &objmgr->peer_list; 2450 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2451 /* Iterate through peer list, get peer */ 2452 peer = wlan_obj_psoc_peerlist_get_peer_no_state_debug( 2453 &peer_list->peer_hash[hash_index], macaddr, 2454 pdev_id, dbg_id, func, line); 2455 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2456 wlan_psoc_obj_unlock(psoc); 2457 2458 return peer; 2459 } 2460 2461 qdf_export_symbol(wlan_objmgr_get_peer_no_state_debug); 2462 #else 2463 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( 2464 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2465 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 2466 { 2467 struct wlan_objmgr_psoc_objmgr *objmgr; 2468 uint8_t hash_index; 2469 struct wlan_objmgr_peer *peer = NULL; 2470 struct wlan_peer_list *peer_list; 2471 2472 /* psoc lock should be taken before peer list lock */ 2473 wlan_psoc_obj_lock(psoc); 2474 objmgr = &psoc->soc_objmgr; 2475 /* List is empty, return NULL */ 2476 if (objmgr->wlan_peer_count == 0) { 2477 wlan_psoc_obj_unlock(psoc); 2478 return NULL; 2479 } 2480 /* reduce the search window, with hash key */ 2481 hash_index = WLAN_PEER_HASH(macaddr); 2482 peer_list = &objmgr->peer_list; 2483 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2484 /* Iterate through peer list, get peer */ 2485 peer = wlan_obj_psoc_peerlist_get_peer_no_state( 2486 &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); 2487 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2488 wlan_psoc_obj_unlock(psoc); 2489 2490 return peer; 2491 } 2492 2493 qdf_export_symbol(wlan_objmgr_get_peer_no_state); 2494 #endif 2495 2496 /** 2497 * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - 2498 * get peer from psoc 2499 * peer list using 2500 * mac and vdev 2501 * self mac 2502 * @psoc: PSOC object 2503 * @pdev_id: Pdev id 2504 * @macaddr: MAC address 2505 * @bssid: BSSID address. NULL mac means search all. 2506 * @dbg_id: id of the caller 2507 * @func: function name 2508 * @line: line number 2509 * 2510 * API to finds peer object pointer by MAC addr and BSSID from 2511 * peer hash list, bssid check is done on matching peer 2512 * 2513 * Return: list of peer pointer pointers 2514 * NULL on FAILURE 2515 */ 2516 2517 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2518 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug( 2519 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2520 uint8_t *bssid, uint8_t *macaddr, 2521 wlan_objmgr_ref_dbgid dbg_id, 2522 const char *func, int line) 2523 { 2524 struct wlan_objmgr_psoc_objmgr *objmgr; 2525 uint8_t hash_index; 2526 struct wlan_peer_list *peer_list = NULL; 2527 qdf_list_t *logical_del_peer_list = NULL; 2528 2529 /* psoc lock should be taken before peer list lock */ 2530 wlan_psoc_obj_lock(psoc); 2531 objmgr = &psoc->soc_objmgr; 2532 /* List is empty, return NULL */ 2533 if (objmgr->wlan_peer_count == 0) { 2534 wlan_psoc_obj_unlock(psoc); 2535 return NULL; 2536 } 2537 /* reduce the search window, with hash key */ 2538 hash_index = WLAN_PEER_HASH(macaddr); 2539 peer_list = &objmgr->peer_list; 2540 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2541 2542 /* Iterate through peer list, get peer */ 2543 logical_del_peer_list = 2544 wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug( 2545 &peer_list->peer_hash[hash_index], macaddr, 2546 bssid, pdev_id, dbg_id, func, line); 2547 2548 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2549 wlan_psoc_obj_unlock(psoc); 2550 2551 return logical_del_peer_list; 2552 } 2553 2554 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug); 2555 #else 2556 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( 2557 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2558 uint8_t *bssid, uint8_t *macaddr, 2559 wlan_objmgr_ref_dbgid dbg_id) 2560 { 2561 struct wlan_objmgr_psoc_objmgr *objmgr; 2562 uint8_t hash_index; 2563 struct wlan_peer_list *peer_list = NULL; 2564 qdf_list_t *logical_del_peer_list = NULL; 2565 2566 /* psoc lock should be taken before peer list lock */ 2567 wlan_psoc_obj_lock(psoc); 2568 objmgr = &psoc->soc_objmgr; 2569 /* List is empty, return NULL */ 2570 if (objmgr->wlan_peer_count == 0) { 2571 wlan_psoc_obj_unlock(psoc); 2572 return NULL; 2573 } 2574 /* reduce the search window, with hash key */ 2575 hash_index = WLAN_PEER_HASH(macaddr); 2576 peer_list = &objmgr->peer_list; 2577 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2578 2579 /* Iterate through peer list, get peer */ 2580 logical_del_peer_list = 2581 wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( 2582 &peer_list->peer_hash[hash_index], macaddr, 2583 bssid, pdev_id, dbg_id); 2584 2585 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2586 wlan_psoc_obj_unlock(psoc); 2587 2588 return logical_del_peer_list; 2589 } 2590 2591 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev); 2592 #endif 2593 2594 void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc, 2595 enum wlan_umac_comp_id id) 2596 { 2597 void *comp_private_obj; 2598 2599 /* component id is invalid */ 2600 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 2601 QDF_BUG(0); 2602 return NULL; 2603 } 2604 2605 if (!psoc) { 2606 QDF_BUG(0); 2607 return NULL; 2608 } 2609 2610 comp_private_obj = psoc->soc_comp_priv_obj[id]; 2611 2612 return comp_private_obj; 2613 } 2614 qdf_export_symbol(wlan_objmgr_psoc_get_comp_private_obj); 2615 2616 void wlan_objmgr_psoc_get_ref(struct wlan_objmgr_psoc *psoc, 2617 wlan_objmgr_ref_dbgid id) 2618 { 2619 if (!psoc) { 2620 obj_mgr_err("psoc obj is NULL for id:%d", id); 2621 QDF_ASSERT(0); 2622 return; 2623 } 2624 /* Increment ref count */ 2625 qdf_atomic_inc(&psoc->soc_objmgr.ref_cnt); 2626 qdf_atomic_inc(&psoc->soc_objmgr.ref_id_dbg[id]); 2627 return; 2628 } 2629 qdf_export_symbol(wlan_objmgr_psoc_get_ref); 2630 2631 QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc, 2632 wlan_objmgr_ref_dbgid id) 2633 { 2634 if (!psoc) { 2635 obj_mgr_err("psoc obj is NULL for id:%d", id); 2636 QDF_ASSERT(0); 2637 return QDF_STATUS_E_FAILURE; 2638 } 2639 2640 wlan_psoc_obj_lock(psoc); 2641 if (psoc->obj_state != WLAN_OBJ_STATE_CREATED) { 2642 wlan_psoc_obj_unlock(psoc); 2643 if (psoc->soc_objmgr.print_cnt++ <= 2644 WLAN_OBJMGR_RATELIMIT_THRESH) 2645 obj_mgr_err( 2646 "[Ref id: %d] psoc is not in Created state(%d)", 2647 id, psoc->obj_state); 2648 2649 return QDF_STATUS_E_RESOURCES; 2650 } 2651 2652 /* Increment ref count */ 2653 wlan_objmgr_psoc_get_ref(psoc, id); 2654 wlan_psoc_obj_unlock(psoc); 2655 2656 return QDF_STATUS_SUCCESS; 2657 } 2658 qdf_export_symbol(wlan_objmgr_psoc_try_get_ref); 2659 2660 void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc, 2661 wlan_objmgr_ref_dbgid id) 2662 { 2663 if (!psoc) { 2664 obj_mgr_err("psoc obj is NULL for id:%d", id); 2665 QDF_ASSERT(0); 2666 return; 2667 } 2668 2669 if (!qdf_atomic_read(&psoc->soc_objmgr.ref_id_dbg[id])) { 2670 obj_mgr_err("psoc ref cnt was not taken by %d", id); 2671 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg, 2672 QDF_TRACE_LEVEL_FATAL); 2673 WLAN_OBJMGR_BUG(0); 2674 } 2675 2676 if (!qdf_atomic_read(&psoc->soc_objmgr.ref_cnt)) { 2677 obj_mgr_err("psoc ref cnt is 0"); 2678 WLAN_OBJMGR_BUG(0); 2679 return; 2680 } 2681 2682 qdf_atomic_dec(&psoc->soc_objmgr.ref_id_dbg[id]); 2683 /* Decrement ref count, free psoc, if ref count == 0 */ 2684 if (qdf_atomic_dec_and_test(&psoc->soc_objmgr.ref_cnt)) 2685 wlan_objmgr_psoc_obj_destroy(psoc); 2686 2687 return; 2688 } 2689 qdf_export_symbol(wlan_objmgr_psoc_release_ref); 2690 2691 static void wlan_objmgr_psoc_peer_ref_print(struct wlan_objmgr_psoc *psoc, 2692 void *obj, void *args) 2693 { 2694 struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj; 2695 WLAN_OBJ_STATE obj_state; 2696 uint8_t vdev_id; 2697 uint8_t *macaddr; 2698 2699 wlan_peer_obj_lock(peer); 2700 macaddr = wlan_peer_get_macaddr(peer); 2701 obj_state = peer->obj_state; 2702 vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); 2703 wlan_peer_obj_unlock(peer); 2704 2705 obj_mgr_alert("Peer MAC:%02x:%02x:%02x:%02x:%02x:%02x state:%d vdev_id:%d", 2706 macaddr[0], macaddr[1], macaddr[2], macaddr[3], 2707 macaddr[4], macaddr[5], obj_state, vdev_id); 2708 wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_FATAL); 2709 } 2710 2711 static void wlan_objmgr_psoc_vdev_ref_print(struct wlan_objmgr_psoc *psoc, 2712 void *obj, void *args) 2713 { 2714 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj; 2715 WLAN_OBJ_STATE obj_state; 2716 uint8_t id; 2717 2718 wlan_vdev_obj_lock(vdev); 2719 id = wlan_vdev_get_id(vdev); 2720 obj_state = vdev->obj_state; 2721 wlan_vdev_obj_unlock(vdev); 2722 obj_mgr_alert("Vdev ID is %d, state %d", id, obj_state); 2723 2724 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, 2725 QDF_TRACE_LEVEL_FATAL); 2726 } 2727 2728 static void wlan_objmgr_psoc_pdev_ref_print(struct wlan_objmgr_psoc *psoc, 2729 void *obj, void *args) 2730 { 2731 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj; 2732 uint8_t id; 2733 2734 wlan_pdev_obj_lock(pdev); 2735 id = wlan_objmgr_pdev_get_pdev_id(pdev); 2736 wlan_pdev_obj_unlock(pdev); 2737 obj_mgr_alert("pdev ID is %d", id); 2738 2739 wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg, 2740 QDF_TRACE_LEVEL_FATAL); 2741 } 2742 2743 QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc( 2744 struct wlan_objmgr_psoc *psoc) 2745 { 2746 obj_mgr_alert("Ref counts of PEER"); 2747 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PEER_OP, 2748 wlan_objmgr_psoc_peer_ref_print, NULL); 2749 obj_mgr_alert("Ref counts of VDEV"); 2750 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_VDEV_OP, 2751 wlan_objmgr_psoc_vdev_ref_print, NULL); 2752 obj_mgr_alert("Ref counts of PDEV"); 2753 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PDEV_OP, 2754 wlan_objmgr_psoc_pdev_ref_print, NULL); 2755 2756 obj_mgr_alert(" Ref counts of PSOC"); 2757 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg, 2758 QDF_TRACE_LEVEL_FATAL); 2759 2760 return QDF_STATUS_SUCCESS; 2761 } 2762 qdf_export_symbol(wlan_objmgr_print_ref_all_objects_per_psoc); 2763 2764 QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, 2765 struct wlan_objmgr_psoc_user_config *user_config_data) 2766 { 2767 if (!user_config_data) { 2768 obj_mgr_err("user_config_data is NULL"); 2769 QDF_BUG(0); 2770 return QDF_STATUS_E_FAILURE; 2771 } 2772 wlan_psoc_obj_lock(psoc); 2773 qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data, 2774 sizeof(psoc->soc_nif.user_config)); 2775 wlan_psoc_obj_unlock(psoc); 2776 2777 return QDF_STATUS_SUCCESS; 2778 } 2779 2780 uint32_t wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) 2781 { 2782 struct wlan_objmgr_psoc_objmgr *_psoc; 2783 struct wlan_objmgr_pdev *pdev; 2784 int pdev_id; 2785 uint32_t leaks = 0; 2786 2787 QDF_BUG(psoc); 2788 if (!psoc) 2789 return leaks; 2790 2791 wlan_psoc_obj_lock(psoc); 2792 _psoc = &psoc->soc_objmgr; 2793 if (!_psoc->wlan_pdev_count) { 2794 wlan_psoc_obj_unlock(psoc); 2795 return leaks; 2796 } 2797 2798 obj_mgr_alert("objmgr pdev leaks detected for psoc %u!", 2799 _psoc->psoc_id); 2800 obj_mgr_alert("----------------------------------------------------"); 2801 obj_mgr_alert("Pdev Id Refs Module"); 2802 obj_mgr_alert("----------------------------------------------------"); 2803 2804 wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) { 2805 qdf_atomic_t *ref_id_dbg; 2806 int ref_id; 2807 int32_t refs; 2808 2809 wlan_pdev_obj_lock(pdev); 2810 ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; 2811 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 2812 leaks++; 2813 obj_mgr_alert("%7u %4u %s", 2814 pdev_id, refs, 2815 string_from_dbgid(ref_id)); 2816 } 2817 wlan_pdev_obj_unlock(pdev); 2818 } 2819 2820 wlan_psoc_obj_unlock(psoc); 2821 return leaks; 2822 } 2823 qdf_export_symbol(wlan_objmgr_psoc_check_for_pdev_leaks); 2824 2825 uint32_t wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) 2826 { 2827 struct wlan_objmgr_psoc_objmgr *_psoc; 2828 struct wlan_objmgr_vdev *vdev; 2829 int vdev_id; 2830 uint32_t leaks = 0; 2831 2832 QDF_BUG(psoc); 2833 if (!psoc) 2834 return leaks; 2835 2836 wlan_psoc_obj_lock(psoc); 2837 _psoc = &psoc->soc_objmgr; 2838 if (!_psoc->wlan_vdev_count) { 2839 wlan_psoc_obj_unlock(psoc); 2840 return leaks; 2841 } 2842 2843 obj_mgr_alert("objmgr vdev leaks detected for psoc %u!", 2844 _psoc->psoc_id); 2845 obj_mgr_alert("----------------------------------------------------"); 2846 obj_mgr_alert("Vdev Id Refs Module"); 2847 obj_mgr_alert("----------------------------------------------------"); 2848 2849 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 2850 qdf_atomic_t *ref_id_dbg; 2851 int ref_id; 2852 int32_t refs; 2853 2854 wlan_vdev_obj_lock(vdev); 2855 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 2856 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 2857 leaks++; 2858 obj_mgr_alert("%7u %4u %s", 2859 vdev_id, refs, string_from_dbgid(ref_id)); 2860 } 2861 wlan_vdev_obj_unlock(vdev); 2862 } 2863 2864 wlan_psoc_obj_unlock(psoc); 2865 return leaks; 2866 } 2867 qdf_export_symbol(wlan_objmgr_psoc_check_for_vdev_leaks); 2868 2869 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 2870 static void 2871 wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) 2872 { 2873 qdf_atomic_t *ref_id_dbg; 2874 int32_t refs; 2875 int ref_id; 2876 2877 ref_id_dbg = peer->peer_objmgr.ref_id_dbg; 2878 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 2879 obj_mgr_alert(QDF_MAC_ADDR_STR " %7u %4u %s", 2880 QDF_MAC_ADDR_ARRAY(peer->macaddr), 2881 vdev_id, 2882 refs, 2883 string_from_dbgid(ref_id)); 2884 } 2885 } 2886 #else 2887 static inline void 2888 wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) 2889 { 2890 obj_mgr_alert(QDF_MAC_ADDR_STR " %7u %4u %s", 2891 QDF_MAC_ADDR_ARRAY(peer->macaddr), 2892 vdev_id, 2893 qdf_atomic_read(&peer->peer_objmgr.ref_cnt), 2894 "TOTAL_REF_COUNT"); 2895 } 2896 #endif 2897 2898 uint32_t wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc) 2899 { 2900 struct wlan_objmgr_psoc_objmgr *_psoc; 2901 struct wlan_objmgr_vdev *vdev; 2902 int vdev_id; 2903 uint32_t leaks = 0; 2904 2905 QDF_BUG(psoc); 2906 if (!psoc) 2907 return leaks; 2908 2909 wlan_psoc_obj_lock(psoc); 2910 _psoc = &psoc->soc_objmgr; 2911 if (!_psoc->temp_peer_count && !_psoc->wlan_peer_count) { 2912 wlan_psoc_obj_unlock(psoc); 2913 return leaks; 2914 } 2915 2916 obj_mgr_alert("objmgr peer leaks detected for psoc %u!", 2917 _psoc->psoc_id); 2918 obj_mgr_alert("----------------------------------------------------"); 2919 obj_mgr_alert("Peer MAC Vdev Id Refs Module"); 2920 obj_mgr_alert("----------------------------------------------------"); 2921 2922 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 2923 struct wlan_objmgr_peer *peer; 2924 2925 wlan_vdev_obj_lock(vdev); 2926 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 2927 wlan_peer_obj_lock(peer); 2928 leaks += qdf_atomic_read(&peer->peer_objmgr.ref_cnt); 2929 wlan_objmgr_print_peer_ref_leaks(peer, vdev_id); 2930 wlan_peer_obj_unlock(peer); 2931 } 2932 wlan_vdev_obj_unlock(vdev); 2933 } 2934 2935 wlan_psoc_obj_unlock(psoc); 2936 return leaks; 2937 } 2938 qdf_export_symbol(wlan_objmgr_psoc_check_for_peer_leaks); 2939 2940 void wlan_objmgr_psoc_check_for_leaks(struct wlan_objmgr_psoc *psoc) 2941 { 2942 struct wlan_objmgr_psoc_objmgr *_psoc; 2943 uint32_t peer_leaks = 0; 2944 uint32_t vdev_leaks = 0; 2945 uint32_t pdev_leaks = 0; 2946 2947 _psoc = &psoc->soc_objmgr; 2948 2949 peer_leaks = wlan_objmgr_psoc_check_for_peer_leaks(psoc); 2950 vdev_leaks = wlan_objmgr_psoc_check_for_vdev_leaks(psoc); 2951 pdev_leaks = wlan_objmgr_psoc_check_for_pdev_leaks(psoc); 2952 2953 if (peer_leaks || vdev_leaks || pdev_leaks) { 2954 QDF_DEBUG_PANIC("%u objmgr peer leaks %u objmgr vdev leaks" 2955 "%u objmgr pdev leaks detected for psoc %u!", 2956 peer_leaks, vdev_leaks, pdev_leaks, 2957 _psoc->psoc_id); 2958 } 2959 } 2960 2961 qdf_export_symbol(wlan_objmgr_psoc_check_for_leaks); 2962 2963 #ifdef WLAN_OBJMGR_DEBUG 2964 void wlan_print_psoc_info(struct wlan_objmgr_psoc *psoc) 2965 { 2966 struct wlan_objmgr_psoc_objmgr *psoc_objmgr; 2967 struct wlan_objmgr_pdev *pdev; 2968 struct wlan_objmgr_vdev *vdev; 2969 uint16_t index = 0; 2970 2971 psoc_objmgr = &psoc->soc_objmgr; 2972 2973 obj_mgr_debug("psoc: %pK", psoc); 2974 obj_mgr_debug("psoc_id: %d", psoc_objmgr->psoc_id); 2975 obj_mgr_debug("wlan_pdev_count: %d", psoc_objmgr->wlan_pdev_count); 2976 obj_mgr_debug("wlan_pdev_id_map: 0x%x", psoc_objmgr->wlan_pdev_id_map); 2977 obj_mgr_debug("wlan_vdev_count: %d", psoc_objmgr->wlan_vdev_count); 2978 obj_mgr_debug("max_vdev_count: %d", psoc_objmgr->max_vdev_count); 2979 obj_mgr_debug("wlan_peer_count: %d", psoc_objmgr->wlan_peer_count); 2980 obj_mgr_debug("max_peer_count: %d", psoc_objmgr->max_peer_count); 2981 obj_mgr_debug("temp_peer_count: %d", psoc_objmgr->temp_peer_count); 2982 obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&psoc_objmgr->ref_cnt)); 2983 obj_mgr_debug("qdf_dev: %pK", psoc_objmgr->qdf_dev); 2984 2985 obj_mgr_debug("wlan_vdev_id_map:"); 2986 obj_mgr_debug_hex(psoc_objmgr->wlan_vdev_id_map, 2987 sizeof(psoc_objmgr->wlan_vdev_id_map)); 2988 2989 wlan_objmgr_for_each_psoc_pdev(psoc, index, pdev) { 2990 obj_mgr_debug("wlan_pdev_list[%d]: %pK", index, pdev); 2991 wlan_print_pdev_info(pdev); 2992 } 2993 2994 wlan_objmgr_for_each_psoc_vdev(psoc, index, vdev) { 2995 obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev); 2996 wlan_print_vdev_info(vdev); 2997 } 2998 } 2999 3000 qdf_export_symbol(wlan_print_psoc_info); 3001 #endif 3002