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