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