1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 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 different 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 /* notify 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 different 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 operation, 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: arguments 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 operation, 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 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1349 /** 1350 * wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug() - get peer from 1351 * psoc peer list 1352 * @obj_list: Peer object list 1353 * @macaddr: MAC address 1354 * @pdev_id: Pdev id 1355 * @dbg_id: id of the caller 1356 * @func: function name 1357 * @line: line number 1358 * 1359 * API to finds peer object pointer by MAC addr and pdev id from hash list 1360 * 1361 * Return: peer pointer 1362 * NULL on FAILURE 1363 */ 1364 static struct wlan_objmgr_peer 1365 *wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( 1366 qdf_list_t *obj_list, const uint8_t *macaddr, 1367 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id, 1368 const char *func, int line) 1369 { 1370 struct wlan_objmgr_peer *peer; 1371 struct wlan_objmgr_peer *peer_temp; 1372 1373 /* Iterate through hash list to get the peer */ 1374 peer = wlan_psoc_peer_list_peek_head(obj_list); 1375 while (peer) { 1376 /* For peer, macaddr is key */ 1377 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1378 == QDF_STATUS_SUCCESS) && 1379 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1380 if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, 1381 func, line) == 1382 QDF_STATUS_SUCCESS) { 1383 return peer; 1384 } 1385 } 1386 /* Move to next peer */ 1387 peer_temp = peer; 1388 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1389 } 1390 1391 /* Not found, return NULL */ 1392 return NULL; 1393 } 1394 #else 1395 /** 1396 * wlan_obj_psoc_peerlist_get_peer_by_pdev_id() - get peer from 1397 * psoc peer list 1398 * @obj_list: Peer object list 1399 * @macaddr: MAC address 1400 * @pdev_id: Pdev id 1401 * @dbg_id: id of the caller 1402 * 1403 * API to finds peer object pointer by MAC addr and pdev id from hash list 1404 * 1405 * Return: peer pointer 1406 * NULL on FAILURE 1407 */ 1408 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_pdev_id( 1409 qdf_list_t *obj_list, const uint8_t *macaddr, 1410 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) 1411 { 1412 struct wlan_objmgr_peer *peer; 1413 struct wlan_objmgr_peer *peer_temp; 1414 1415 /* Iterate through hash list to get the peer */ 1416 peer = wlan_psoc_peer_list_peek_head(obj_list); 1417 while (peer) { 1418 /* For peer, macaddr is key */ 1419 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1420 == QDF_STATUS_SUCCESS) && 1421 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1422 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 1423 QDF_STATUS_SUCCESS) { 1424 return peer; 1425 } 1426 } 1427 /* Move to next peer */ 1428 peer_temp = peer; 1429 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1430 } 1431 1432 /* Not found, return NULL */ 1433 return NULL; 1434 } 1435 #endif 1436 1437 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1438 /** 1439 * wlan_obj_psoc_peerlist_get_peer_debug() - get peer from psoc peer list 1440 * @obj_list: Peer object list 1441 * @macaddr: MAC address 1442 * @dbg_id: id of the caller 1443 * @func: function name 1444 * @line: line number 1445 * 1446 * API to finds peer object pointer by MAC addr from hash list 1447 * 1448 * Return: peer pointer 1449 * NULL on FAILURE 1450 */ 1451 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_debug( 1452 qdf_list_t *obj_list, uint8_t *macaddr, 1453 wlan_objmgr_ref_dbgid dbg_id, 1454 const char *func, int line) 1455 { 1456 struct wlan_objmgr_peer *peer; 1457 struct wlan_objmgr_peer *peer_temp; 1458 1459 /* Iterate through hash list to get the peer */ 1460 peer = wlan_psoc_peer_list_peek_head(obj_list); 1461 while (peer) { 1462 /* For peer, macaddr is key */ 1463 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1464 == QDF_STATUS_SUCCESS) { 1465 if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, 1466 func, line) == 1467 QDF_STATUS_SUCCESS) { 1468 return peer; 1469 } 1470 } 1471 /* Move to next peer */ 1472 peer_temp = peer; 1473 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1474 } 1475 1476 /* Not found, return NULL */ 1477 return NULL; 1478 } 1479 #else 1480 /** 1481 * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list 1482 * @obj_list: Peer object list 1483 * @macaddr: MAC address 1484 * @dbg_id: id of the caller 1485 * 1486 * API to finds peer object pointer by MAC addr from hash list 1487 * 1488 * Return: peer pointer 1489 * NULL on FAILURE 1490 */ 1491 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( 1492 qdf_list_t *obj_list, uint8_t *macaddr, 1493 wlan_objmgr_ref_dbgid dbg_id) 1494 { 1495 struct wlan_objmgr_peer *peer; 1496 struct wlan_objmgr_peer *peer_temp; 1497 1498 /* Iterate through hash list to get the peer */ 1499 peer = wlan_psoc_peer_list_peek_head(obj_list); 1500 while (peer) { 1501 /* For peer, macaddr is key */ 1502 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1503 == QDF_STATUS_SUCCESS) { 1504 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 1505 QDF_STATUS_SUCCESS) { 1506 return peer; 1507 } 1508 } 1509 /* Move to next peer */ 1510 peer_temp = peer; 1511 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1512 } 1513 1514 /* Not found, return NULL */ 1515 return NULL; 1516 } 1517 #endif 1518 1519 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1520 /** 1521 * wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug() - get peer 1522 * from psoc peer list 1523 * @obj_list: Peer object list 1524 * @macaddr: MAC address 1525 * @dbg_id: id of the caller 1526 * @func: function name 1527 * @line: line number 1528 * 1529 * API to finds peer object pointer of logically deleted peer 1530 * 1531 * Return: peer pointer 1532 * NULL on FAILURE 1533 */ 1534 static struct wlan_objmgr_peer * 1535 wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug( 1536 qdf_list_t *obj_list, uint8_t *macaddr, 1537 wlan_objmgr_ref_dbgid dbg_id, 1538 const char *func, int line) 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_debug(peer, dbg_id, 1553 func, line); 1554 1555 return peer; 1556 } 1557 1558 } 1559 /* Move to next peer */ 1560 peer_temp = peer; 1561 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1562 } 1563 1564 /* Not found, return NULL */ 1565 return NULL; 1566 } 1567 #else 1568 /** 1569 * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer 1570 * from psoc peer list 1571 * @obj_list: Peer object list 1572 * @macaddr: MAC address 1573 * @dbg_id: id of the caller 1574 * 1575 * API to finds peer object pointer of logically deleted peer 1576 * 1577 * Return: peer pointer 1578 * NULL on FAILURE 1579 */ 1580 static struct wlan_objmgr_peer * 1581 wlan_obj_psoc_peerlist_get_peer_logically_deleted( 1582 qdf_list_t *obj_list, uint8_t *macaddr, 1583 wlan_objmgr_ref_dbgid dbg_id) 1584 { 1585 struct wlan_objmgr_peer *peer; 1586 struct wlan_objmgr_peer *peer_temp; 1587 1588 /* Iterate through hash list to get the peer */ 1589 peer = wlan_psoc_peer_list_peek_head(obj_list); 1590 while (peer) { 1591 /* For peer, macaddr is key */ 1592 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1593 == QDF_STATUS_SUCCESS) { 1594 /* Return peer in logically deleted state */ 1595 if (peer->obj_state == 1596 WLAN_OBJ_STATE_LOGICALLY_DELETED) { 1597 wlan_objmgr_peer_get_ref(peer, dbg_id); 1598 1599 return peer; 1600 } 1601 } 1602 /* Move to next peer */ 1603 peer_temp = peer; 1604 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1605 } 1606 1607 /* Not found, return NULL */ 1608 return NULL; 1609 } 1610 #endif 1611 1612 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1613 static struct wlan_objmgr_peer 1614 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state_debug( 1615 qdf_list_t *obj_list, uint8_t *macaddr, 1616 uint8_t *bssid, 1617 uint8_t pdev_id, 1618 wlan_objmgr_ref_dbgid dbg_id, 1619 const char *func, int line) 1620 { 1621 struct wlan_objmgr_peer *peer; 1622 struct wlan_objmgr_peer *peer_temp; 1623 1624 /* Iterate through hash list to get the peer */ 1625 peer = wlan_psoc_peer_list_peek_head(obj_list); 1626 while (peer) { 1627 /* For peer, macaddr is key */ 1628 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1629 == QDF_STATUS_SUCCESS) { 1630 /* 1631 * BSSID match is requested by caller, check BSSID 1632 * (vdev mac == bssid) -- return peer 1633 * (vdev mac != bssid) -- perform next iteration 1634 */ 1635 if ((wlan_peer_bssid_match(peer, bssid) == 1636 QDF_STATUS_SUCCESS) && 1637 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1638 wlan_objmgr_peer_get_ref_debug(peer, dbg_id, 1639 func, line); 1640 1641 return peer; 1642 } 1643 } 1644 /* Move to next peer */ 1645 peer_temp = peer; 1646 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1647 } 1648 1649 /* Not found, return NULL */ 1650 return NULL; 1651 } 1652 #else 1653 static struct wlan_objmgr_peer 1654 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( 1655 qdf_list_t *obj_list, uint8_t *macaddr, 1656 uint8_t *bssid, 1657 uint8_t pdev_id, 1658 wlan_objmgr_ref_dbgid dbg_id) 1659 { 1660 struct wlan_objmgr_peer *peer; 1661 struct wlan_objmgr_peer *peer_temp; 1662 1663 /* Iterate through hash list to get the peer */ 1664 peer = wlan_psoc_peer_list_peek_head(obj_list); 1665 while (peer) { 1666 /* For peer, macaddr is key */ 1667 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1668 == QDF_STATUS_SUCCESS) { 1669 /* 1670 * BSSID match is requested by caller, check BSSID 1671 * (vdev mac == bssid) -- return peer 1672 * (vdev mac != bssid) -- perform next iteration 1673 */ 1674 if ((wlan_peer_bssid_match(peer, bssid) == 1675 QDF_STATUS_SUCCESS) && 1676 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1677 wlan_objmgr_peer_get_ref(peer, dbg_id); 1678 1679 return peer; 1680 } 1681 } 1682 /* Move to next peer */ 1683 peer_temp = peer; 1684 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1685 } 1686 1687 /* Not found, return NULL */ 1688 return NULL; 1689 } 1690 #endif 1691 1692 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1693 /** 1694 * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug() - get peer 1695 * from psoc peer 1696 * list using mac and vdev 1697 * self mac 1698 * @obj_list: Peer object list 1699 * @macaddr: MAC address 1700 * @bssid: BSSID address 1701 * @pdev_id: Pdev id 1702 * @dbg_id: id of the caller 1703 * @func: function name 1704 * @line: line number 1705 * 1706 * API to finds peer object pointer by MAC addr and BSSID from 1707 * peer hash list, bssid check is done on matching peer 1708 * 1709 * Return: peer pointer 1710 * NULL on FAILURE 1711 */ 1712 static struct wlan_objmgr_peer 1713 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug( 1714 qdf_list_t *obj_list, uint8_t *macaddr, 1715 uint8_t *bssid, uint8_t pdev_id, 1716 wlan_objmgr_ref_dbgid dbg_id, 1717 const char *func, int line) 1718 { 1719 struct wlan_objmgr_peer *peer; 1720 struct wlan_objmgr_peer *peer_temp; 1721 1722 /* Iterate through hash list to get the peer */ 1723 peer = wlan_psoc_peer_list_peek_head(obj_list); 1724 while (peer) { 1725 /* For peer, macaddr is key */ 1726 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1727 == QDF_STATUS_SUCCESS) { 1728 /* 1729 * BSSID match is requested by caller, check BSSID 1730 * (vdev mac == bssid) -- return peer 1731 * (vdev mac != bssid) -- perform next iteration 1732 */ 1733 if ((wlan_peer_bssid_match(peer, bssid) == 1734 QDF_STATUS_SUCCESS) && 1735 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1736 if (wlan_objmgr_peer_try_get_ref_debug(peer, 1737 dbg_id, 1738 func, 1739 line) 1740 == QDF_STATUS_SUCCESS) { 1741 return peer; 1742 } 1743 } 1744 } 1745 /* Move to next peer */ 1746 peer_temp = peer; 1747 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1748 } 1749 /* Not found, return NULL */ 1750 return NULL; 1751 } 1752 #else 1753 /** 1754 * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer 1755 * from psoc peer 1756 * list using mac and vdev 1757 * self mac 1758 * @obj_list: Peer object list 1759 * @macaddr: MAC address 1760 * @bssid: BSSID address 1761 * @pdev_id: Pdev id 1762 * @dbg_id: id of the caller 1763 * 1764 * API to finds peer object pointer by MAC addr and BSSID from 1765 * peer hash list, bssid check is done on matching peer 1766 * 1767 * Return: peer pointer 1768 * NULL on FAILURE 1769 */ 1770 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( 1771 qdf_list_t *obj_list, uint8_t *macaddr, 1772 uint8_t *bssid, uint8_t pdev_id, 1773 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 is key */ 1782 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1783 == QDF_STATUS_SUCCESS) { 1784 /* 1785 * BSSID match is requested by caller, check BSSID 1786 * (vdev mac == bssid) -- return peer 1787 * (vdev mac != bssid) -- perform next iteration 1788 */ 1789 if ((wlan_peer_bssid_match(peer, bssid) == 1790 QDF_STATUS_SUCCESS) && 1791 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1792 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) 1793 == QDF_STATUS_SUCCESS) { 1794 return peer; 1795 } 1796 } 1797 } 1798 /* Move to next peer */ 1799 peer_temp = peer; 1800 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1801 } 1802 /* Not found, return NULL */ 1803 return NULL; 1804 } 1805 #endif 1806 1807 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1808 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state_debug( 1809 qdf_list_t *obj_list, uint8_t *macaddr, 1810 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id, 1811 const char *func, int line) 1812 { 1813 struct wlan_objmgr_peer *peer; 1814 struct wlan_objmgr_peer *peer_temp; 1815 1816 /* Iterate through hash list to get the peer */ 1817 peer = wlan_psoc_peer_list_peek_head(obj_list); 1818 while (peer) { 1819 /* For peer, macaddr and pdev_id is key */ 1820 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1821 == QDF_STATUS_SUCCESS) && 1822 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1823 wlan_objmgr_peer_get_ref_debug(peer, dbg_id, func, 1824 line); 1825 1826 return peer; 1827 } 1828 /* Move to next peer */ 1829 peer_temp = peer; 1830 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1831 } 1832 1833 /* Not found, return NULL */ 1834 return NULL; 1835 } 1836 #else 1837 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( 1838 qdf_list_t *obj_list, uint8_t *macaddr, 1839 uint8_t pdev_id, wlan_objmgr_ref_dbgid dbg_id) 1840 { 1841 struct wlan_objmgr_peer *peer; 1842 struct wlan_objmgr_peer *peer_temp; 1843 1844 /* Iterate through hash list to get the peer */ 1845 peer = wlan_psoc_peer_list_peek_head(obj_list); 1846 while (peer) { 1847 /* For peer, macaddr and pdev_id is key */ 1848 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1849 == QDF_STATUS_SUCCESS) && 1850 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1851 wlan_objmgr_peer_get_ref(peer, dbg_id); 1852 1853 return peer; 1854 } 1855 /* Move to next peer */ 1856 peer_temp = peer; 1857 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1858 } 1859 1860 /* Not found, return NULL */ 1861 return NULL; 1862 } 1863 #endif 1864 1865 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1866 /** 1867 * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug() - 1868 * get peer 1869 * from psoc peer list using 1870 * mac and vdev self mac 1871 * @obj_list: peer object list 1872 * @macaddr: MAC address 1873 * @bssid: BSSID address 1874 * @pdev_id: pdev id 1875 * @dbg_id: id of the caller 1876 * @func: function name 1877 * @line: line number 1878 * 1879 * API to finds peer object pointer by MAC addr and BSSID from 1880 * peer hash list for a node which is in logically deleted state, 1881 * bssid check is done on matching peer 1882 * 1883 * Caller to free the list allocated in this function 1884 * 1885 * Return: list of peer pointers 1886 * NULL on FAILURE 1887 */ 1888 static qdf_list_t 1889 *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug( 1890 qdf_list_t *obj_list, uint8_t *macaddr, 1891 uint8_t *bssid, uint8_t pdev_id, 1892 wlan_objmgr_ref_dbgid dbg_id, 1893 const char *func, int line) 1894 { 1895 struct wlan_objmgr_peer *peer; 1896 struct wlan_objmgr_peer *peer_temp; 1897 struct wlan_logically_del_peer *peer_list = NULL; 1898 qdf_list_t *logical_del_peer_list = NULL; 1899 bool lock_released = false; 1900 1901 logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); 1902 if (!logical_del_peer_list) 1903 return NULL; 1904 1905 qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); 1906 1907 /* Iterate through hash list to get the peer */ 1908 peer = wlan_psoc_peer_list_peek_head(obj_list); 1909 while (peer) { 1910 wlan_peer_obj_lock(peer); 1911 /* For peer, macaddr and pdev id are keys */ 1912 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1913 == QDF_STATUS_SUCCESS) && 1914 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 1915 /* 1916 * if BSSID not NULL, 1917 * then match is requested by caller, check BSSID 1918 * (vdev mac == bssid) -- return peer 1919 * (vdev mac != bssid) -- perform next iteration 1920 */ 1921 if ((!bssid) || 1922 (wlan_peer_bssid_match(peer, bssid) == 1923 QDF_STATUS_SUCCESS)) { 1924 /* Return peer in logically deleted state */ 1925 if ((peer->obj_state == 1926 WLAN_OBJ_STATE_LOGICALLY_DELETED) && 1927 qdf_atomic_read( 1928 &peer->peer_objmgr.ref_cnt)) { 1929 wlan_objmgr_peer_get_ref_debug(peer, 1930 dbg_id, 1931 func, 1932 line); 1933 wlan_peer_obj_unlock(peer); 1934 lock_released = true; 1935 1936 peer_list = 1937 qdf_mem_malloc( 1938 sizeof(struct wlan_logically_del_peer)); 1939 if (!peer_list) { 1940 wlan_objmgr_peer_release_ref(peer, dbg_id); 1941 /* Lock is already released */ 1942 WLAN_OBJMGR_BUG(0); 1943 break; 1944 } 1945 1946 peer_list->peer = peer; 1947 1948 qdf_list_insert_front( 1949 logical_del_peer_list, 1950 &peer_list->list); 1951 } 1952 } 1953 } 1954 1955 if (!lock_released) 1956 wlan_peer_obj_unlock(peer); 1957 1958 /* Move to next peer */ 1959 peer_temp = peer; 1960 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1961 lock_released = false; 1962 } 1963 1964 /* Not found, return NULL */ 1965 if (qdf_list_empty(logical_del_peer_list)) { 1966 qdf_mem_free(logical_del_peer_list); 1967 return NULL; 1968 } else { 1969 return logical_del_peer_list; 1970 } 1971 } 1972 #else 1973 /** 1974 * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - 1975 * get peer 1976 * from psoc peer list using 1977 * mac and vdev self mac 1978 * @obj_list: peer object list 1979 * @macaddr: MAC address 1980 * @bssid: BSSID address 1981 * @pdev_id: pdev id 1982 * @dbg_id: id of the caller 1983 * 1984 * API to finds peer object pointer by MAC addr and BSSID from 1985 * peer hash list for a node which is in logically deleted state, 1986 * bssid check is done on matching peer 1987 * 1988 * Caller to free the list allocated in this function 1989 * 1990 * Return: list of peer pointers 1991 * NULL on FAILURE 1992 */ 1993 static qdf_list_t 1994 *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( 1995 qdf_list_t *obj_list, uint8_t *macaddr, 1996 uint8_t *bssid, uint8_t pdev_id, 1997 wlan_objmgr_ref_dbgid dbg_id) 1998 { 1999 struct wlan_objmgr_peer *peer; 2000 struct wlan_objmgr_peer *peer_temp; 2001 struct wlan_logically_del_peer *peer_list = NULL; 2002 qdf_list_t *logical_del_peer_list = NULL; 2003 bool lock_released = false; 2004 2005 logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); 2006 if (!logical_del_peer_list) 2007 return NULL; 2008 2009 qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); 2010 2011 /* Iterate through hash list to get the peer */ 2012 peer = wlan_psoc_peer_list_peek_head(obj_list); 2013 while (peer) { 2014 wlan_peer_obj_lock(peer); 2015 /* For peer, macaddr and pdev id are keys */ 2016 if ((WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 2017 == QDF_STATUS_SUCCESS) && 2018 (wlan_peer_get_pdev_id(peer) == pdev_id)) { 2019 /* 2020 * if BSSID not NULL, 2021 * then match is requested by caller, check BSSID 2022 * (vdev mac == bssid) -- return peer 2023 * (vdev mac != bssid) -- perform next iteration 2024 */ 2025 if ((!bssid) || 2026 (wlan_peer_bssid_match(peer, bssid) == 2027 QDF_STATUS_SUCCESS)) { 2028 /* Return peer in logically deleted state */ 2029 if ((peer->obj_state == 2030 WLAN_OBJ_STATE_LOGICALLY_DELETED) && 2031 qdf_atomic_read( 2032 &peer->peer_objmgr.ref_cnt)) { 2033 wlan_objmgr_peer_get_ref(peer, dbg_id); 2034 wlan_peer_obj_unlock(peer); 2035 lock_released = true; 2036 2037 peer_list = 2038 qdf_mem_malloc( 2039 sizeof(struct wlan_logically_del_peer)); 2040 if (!peer_list) { 2041 wlan_objmgr_peer_release_ref(peer, dbg_id); 2042 /* Lock is already released */ 2043 WLAN_OBJMGR_BUG(0); 2044 break; 2045 } 2046 2047 peer_list->peer = peer; 2048 2049 qdf_list_insert_front( 2050 logical_del_peer_list, 2051 &peer_list->list); 2052 } 2053 } 2054 } 2055 2056 if (!lock_released) 2057 wlan_peer_obj_unlock(peer); 2058 2059 /* Move to next peer */ 2060 peer_temp = peer; 2061 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 2062 lock_released = false; 2063 } 2064 2065 /* Not found, return NULL */ 2066 if (qdf_list_empty(logical_del_peer_list)) { 2067 qdf_mem_free(logical_del_peer_list); 2068 return NULL; 2069 } else { 2070 return logical_del_peer_list; 2071 } 2072 } 2073 #endif 2074 2075 QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc, 2076 struct wlan_objmgr_peer *peer) 2077 { 2078 struct wlan_objmgr_psoc_objmgr *objmgr; 2079 uint8_t hash_index; 2080 struct wlan_peer_list *peer_list; 2081 2082 wlan_psoc_obj_lock(psoc); 2083 objmgr = &psoc->soc_objmgr; 2084 /* Max temporary peer limit is reached, return failure */ 2085 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP || 2086 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) { 2087 if (objmgr->temp_peer_count >= WLAN_MAX_PSOC_TEMP_PEERS) { 2088 wlan_psoc_obj_unlock(psoc); 2089 return QDF_STATUS_E_FAILURE; 2090 } 2091 } else { 2092 /* Max peer limit is reached, return failure */ 2093 if (objmgr->wlan_peer_count 2094 >= wlan_psoc_get_max_peer_count(psoc)) { 2095 wlan_psoc_obj_unlock(psoc); 2096 return QDF_STATUS_E_FAILURE; 2097 } 2098 } 2099 2100 /* Derive hash index from mac address */ 2101 hash_index = WLAN_PEER_HASH(peer->macaddr); 2102 peer_list = &objmgr->peer_list; 2103 /* psoc lock should be taken before list lock */ 2104 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2105 /* add peer to hash peer list */ 2106 wlan_obj_psoc_peerlist_add_tail( 2107 &peer_list->peer_hash[hash_index], 2108 peer); 2109 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2110 /* Increment peer count */ 2111 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP || 2112 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) 2113 objmgr->temp_peer_count++; 2114 else 2115 objmgr->wlan_peer_count++; 2116 2117 wlan_psoc_obj_unlock(psoc); 2118 2119 return QDF_STATUS_SUCCESS; 2120 } 2121 2122 QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc, 2123 struct wlan_objmgr_peer *peer) 2124 { 2125 struct wlan_objmgr_psoc_objmgr *objmgr; 2126 uint8_t hash_index; 2127 struct wlan_peer_list *peer_list; 2128 2129 wlan_psoc_obj_lock(psoc); 2130 objmgr = &psoc->soc_objmgr; 2131 /* if list is empty, return */ 2132 if (objmgr->wlan_peer_count == 0) { 2133 wlan_psoc_obj_unlock(psoc); 2134 return QDF_STATUS_E_FAILURE; 2135 } 2136 /* Get hash index, to locate the actual peer list */ 2137 hash_index = WLAN_PEER_HASH(peer->macaddr); 2138 peer_list = &objmgr->peer_list; 2139 /* psoc lock should be taken before list lock */ 2140 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2141 /* removes the peer from peer_list */ 2142 if (wlan_obj_psoc_peerlist_remove_peer( 2143 &peer_list->peer_hash[hash_index], 2144 peer) == 2145 QDF_STATUS_E_FAILURE) { 2146 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2147 wlan_psoc_obj_unlock(psoc); 2148 obj_mgr_err("Failed to detach peer"); 2149 return QDF_STATUS_E_FAILURE; 2150 } 2151 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2152 /* Decrement peer count */ 2153 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP || 2154 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) 2155 objmgr->temp_peer_count--; 2156 else 2157 objmgr->wlan_peer_count--; 2158 wlan_psoc_obj_unlock(psoc); 2159 2160 return QDF_STATUS_SUCCESS; 2161 } 2162 2163 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2164 struct wlan_objmgr_peer *wlan_objmgr_get_peer_debug( 2165 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2166 const uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 2167 const char *func, int line) 2168 { 2169 struct wlan_objmgr_psoc_objmgr *objmgr; 2170 uint8_t hash_index; 2171 struct wlan_objmgr_peer *peer = NULL; 2172 struct wlan_peer_list *peer_list; 2173 2174 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) 2175 QDF_ASSERT(0); 2176 2177 if (!macaddr) 2178 return NULL; 2179 2180 /* psoc lock should be taken before peer list lock */ 2181 wlan_psoc_obj_lock(psoc); 2182 objmgr = &psoc->soc_objmgr; 2183 /* List is empty, return NULL */ 2184 if (objmgr->wlan_peer_count == 0) { 2185 wlan_psoc_obj_unlock(psoc); 2186 return NULL; 2187 } 2188 /* reduce the search window, with hash key */ 2189 hash_index = WLAN_PEER_HASH(macaddr); 2190 peer_list = &objmgr->peer_list; 2191 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2192 /* Iterate through peer list, get peer */ 2193 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( 2194 &peer_list->peer_hash[hash_index], macaddr, 2195 pdev_id, dbg_id, func, line); 2196 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2197 wlan_psoc_obj_unlock(psoc); 2198 2199 return peer; 2200 } 2201 2202 qdf_export_symbol(wlan_objmgr_get_peer_debug); 2203 #else 2204 struct wlan_objmgr_peer *wlan_objmgr_get_peer( 2205 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2206 const uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 2207 { 2208 struct wlan_objmgr_psoc_objmgr *objmgr; 2209 uint8_t hash_index; 2210 struct wlan_objmgr_peer *peer = NULL; 2211 struct wlan_peer_list *peer_list; 2212 2213 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) 2214 QDF_ASSERT(0); 2215 2216 if (!macaddr) 2217 return NULL; 2218 2219 /* psoc lock should be taken before peer list lock */ 2220 wlan_psoc_obj_lock(psoc); 2221 objmgr = &psoc->soc_objmgr; 2222 /* List is empty, return NULL */ 2223 if (objmgr->wlan_peer_count == 0) { 2224 wlan_psoc_obj_unlock(psoc); 2225 return NULL; 2226 } 2227 /* reduce the search window, with hash key */ 2228 hash_index = WLAN_PEER_HASH(macaddr); 2229 peer_list = &objmgr->peer_list; 2230 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2231 /* Iterate through peer list, get peer */ 2232 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id( 2233 &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); 2234 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2235 wlan_psoc_obj_unlock(psoc); 2236 2237 return peer; 2238 } 2239 2240 qdf_export_symbol(wlan_objmgr_get_peer); 2241 #endif 2242 2243 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2244 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_debug( 2245 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2246 wlan_objmgr_ref_dbgid dbg_id, 2247 const char *func, int line) 2248 { 2249 struct wlan_objmgr_psoc_objmgr *objmgr; 2250 uint8_t hash_index; 2251 struct wlan_objmgr_peer *peer = NULL; 2252 struct wlan_peer_list *peer_list; 2253 2254 if (!macaddr) 2255 return NULL; 2256 if (!psoc) 2257 return NULL; 2258 2259 /* psoc lock should be taken before peer list lock */ 2260 wlan_psoc_obj_lock(psoc); 2261 objmgr = &psoc->soc_objmgr; 2262 /* List is empty, return NULL */ 2263 if (objmgr->wlan_peer_count == 0) { 2264 wlan_psoc_obj_unlock(psoc); 2265 return NULL; 2266 } 2267 /* reduce the search window, with hash key */ 2268 hash_index = WLAN_PEER_HASH(macaddr); 2269 peer_list = &objmgr->peer_list; 2270 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2271 /* Iterate through peer list, get peer */ 2272 peer = wlan_obj_psoc_peerlist_get_peer_debug( 2273 &peer_list->peer_hash[hash_index], 2274 macaddr, dbg_id, func, line); 2275 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2276 wlan_psoc_obj_unlock(psoc); 2277 2278 return peer; 2279 } 2280 2281 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_debug); 2282 #else 2283 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac( 2284 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2285 wlan_objmgr_ref_dbgid dbg_id) 2286 { 2287 struct wlan_objmgr_psoc_objmgr *objmgr; 2288 uint8_t hash_index; 2289 struct wlan_objmgr_peer *peer = NULL; 2290 struct wlan_peer_list *peer_list; 2291 2292 if (!macaddr) 2293 return NULL; 2294 if (!psoc) 2295 return NULL; 2296 2297 /* psoc lock should be taken before peer list lock */ 2298 wlan_psoc_obj_lock(psoc); 2299 objmgr = &psoc->soc_objmgr; 2300 /* List is empty, return NULL */ 2301 if (objmgr->wlan_peer_count == 0) { 2302 wlan_psoc_obj_unlock(psoc); 2303 return NULL; 2304 } 2305 /* reduce the search window, with hash key */ 2306 hash_index = WLAN_PEER_HASH(macaddr); 2307 peer_list = &objmgr->peer_list; 2308 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2309 /* Iterate through peer list, get peer */ 2310 peer = wlan_obj_psoc_peerlist_get_peer( 2311 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 2312 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2313 wlan_psoc_obj_unlock(psoc); 2314 2315 return peer; 2316 } 2317 2318 qdf_export_symbol(wlan_objmgr_get_peer_by_mac); 2319 #endif 2320 2321 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2322 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted_debug( 2323 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2324 wlan_objmgr_ref_dbgid dbg_id, 2325 const char *func, int line) 2326 { 2327 struct wlan_objmgr_psoc_objmgr *objmgr; 2328 uint8_t hash_index; 2329 struct wlan_objmgr_peer *peer = NULL; 2330 struct wlan_peer_list *peer_list; 2331 2332 /* psoc lock should be taken before peer list lock */ 2333 wlan_psoc_obj_lock(psoc); 2334 objmgr = &psoc->soc_objmgr; 2335 /* List is empty, return NULL */ 2336 if (objmgr->wlan_peer_count == 0) { 2337 wlan_psoc_obj_unlock(psoc); 2338 return NULL; 2339 } 2340 /* reduce the search window, with hash key */ 2341 hash_index = WLAN_PEER_HASH(macaddr); 2342 peer_list = &objmgr->peer_list; 2343 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2344 /* Iterate through peer list, get peer */ 2345 peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted_debug( 2346 &peer_list->peer_hash[hash_index], macaddr, dbg_id, 2347 func, line); 2348 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2349 wlan_psoc_obj_unlock(psoc); 2350 2351 return peer; 2352 } 2353 #else 2354 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( 2355 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 2356 wlan_objmgr_ref_dbgid dbg_id) 2357 { 2358 struct wlan_objmgr_psoc_objmgr *objmgr; 2359 uint8_t hash_index; 2360 struct wlan_objmgr_peer *peer = NULL; 2361 struct wlan_peer_list *peer_list; 2362 2363 /* psoc lock should be taken before peer list lock */ 2364 wlan_psoc_obj_lock(psoc); 2365 objmgr = &psoc->soc_objmgr; 2366 /* List is empty, return NULL */ 2367 if (objmgr->wlan_peer_count == 0) { 2368 wlan_psoc_obj_unlock(psoc); 2369 return NULL; 2370 } 2371 /* reduce the search window, with hash key */ 2372 hash_index = WLAN_PEER_HASH(macaddr); 2373 peer_list = &objmgr->peer_list; 2374 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2375 /* Iterate through peer list, get peer */ 2376 peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted( 2377 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 2378 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2379 wlan_psoc_obj_unlock(psoc); 2380 2381 return peer; 2382 } 2383 #endif 2384 2385 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2386 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug( 2387 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2388 uint8_t *bssid, uint8_t *macaddr, 2389 wlan_objmgr_ref_dbgid dbg_id, 2390 const char *func, int line) 2391 { 2392 struct wlan_objmgr_psoc_objmgr *objmgr; 2393 uint8_t hash_index; 2394 struct wlan_objmgr_peer *peer = NULL; 2395 struct wlan_peer_list *peer_list; 2396 2397 /* psoc lock should be taken before peer list lock */ 2398 wlan_psoc_obj_lock(psoc); 2399 objmgr = &psoc->soc_objmgr; 2400 /* List is empty, return NULL */ 2401 if (objmgr->wlan_peer_count == 0) { 2402 wlan_psoc_obj_unlock(psoc); 2403 return NULL; 2404 } 2405 /* reduce the search window, with hash key */ 2406 hash_index = WLAN_PEER_HASH(macaddr); 2407 peer_list = &objmgr->peer_list; 2408 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2409 /* Iterate through peer list, get peer */ 2410 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state_debug( 2411 &peer_list->peer_hash[hash_index], macaddr, bssid, 2412 pdev_id, dbg_id, func, line); 2413 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2414 wlan_psoc_obj_unlock(psoc); 2415 2416 return peer; 2417 } 2418 2419 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state_debug); 2420 #else 2421 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( 2422 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2423 uint8_t *bssid, uint8_t *macaddr, 2424 wlan_objmgr_ref_dbgid dbg_id) 2425 { 2426 struct wlan_objmgr_psoc_objmgr *objmgr; 2427 uint8_t hash_index; 2428 struct wlan_objmgr_peer *peer = NULL; 2429 struct wlan_peer_list *peer_list; 2430 2431 /* psoc lock should be taken before peer list lock */ 2432 wlan_psoc_obj_lock(psoc); 2433 objmgr = &psoc->soc_objmgr; 2434 /* List is empty, return NULL */ 2435 if (objmgr->wlan_peer_count == 0) { 2436 wlan_psoc_obj_unlock(psoc); 2437 return NULL; 2438 } 2439 /* reduce the search window, with hash key */ 2440 hash_index = WLAN_PEER_HASH(macaddr); 2441 peer_list = &objmgr->peer_list; 2442 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2443 /* Iterate through peer list, get peer */ 2444 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( 2445 &peer_list->peer_hash[hash_index], macaddr, bssid, 2446 pdev_id, dbg_id); 2447 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2448 wlan_psoc_obj_unlock(psoc); 2449 2450 return peer; 2451 } 2452 2453 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state); 2454 #endif 2455 2456 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2457 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_debug( 2458 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2459 uint8_t *bssid, uint8_t *macaddr, 2460 wlan_objmgr_ref_dbgid dbg_id, 2461 const char *func, int line) 2462 { 2463 struct wlan_objmgr_psoc_objmgr *objmgr; 2464 uint8_t hash_index; 2465 struct wlan_objmgr_peer *peer = NULL; 2466 struct wlan_peer_list *peer_list; 2467 2468 /* psoc lock should be taken before peer list lock */ 2469 wlan_psoc_obj_lock(psoc); 2470 objmgr = &psoc->soc_objmgr; 2471 /* List is empty, return NULL */ 2472 if (objmgr->wlan_peer_count == 0) { 2473 wlan_psoc_obj_unlock(psoc); 2474 return NULL; 2475 } 2476 /* reduce the search window, with hash key */ 2477 hash_index = WLAN_PEER_HASH(macaddr); 2478 peer_list = &objmgr->peer_list; 2479 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2480 /* Iterate through peer list, get peer */ 2481 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_debug( 2482 &peer_list->peer_hash[hash_index], macaddr, bssid, 2483 pdev_id, dbg_id, func, line); 2484 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2485 wlan_psoc_obj_unlock(psoc); 2486 2487 return peer; 2488 } 2489 2490 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_debug); 2491 #else 2492 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( 2493 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2494 uint8_t *bssid, uint8_t *macaddr, 2495 wlan_objmgr_ref_dbgid dbg_id) 2496 { 2497 struct wlan_objmgr_psoc_objmgr *objmgr; 2498 uint8_t hash_index; 2499 struct wlan_objmgr_peer *peer = NULL; 2500 struct wlan_peer_list *peer_list; 2501 2502 /* psoc lock should be taken before peer list lock */ 2503 wlan_psoc_obj_lock(psoc); 2504 objmgr = &psoc->soc_objmgr; 2505 /* List is empty, return NULL */ 2506 if (objmgr->wlan_peer_count == 0) { 2507 wlan_psoc_obj_unlock(psoc); 2508 return NULL; 2509 } 2510 /* reduce the search window, with hash key */ 2511 hash_index = WLAN_PEER_HASH(macaddr); 2512 peer_list = &objmgr->peer_list; 2513 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2514 /* Iterate through peer list, get peer */ 2515 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( 2516 &peer_list->peer_hash[hash_index], macaddr, bssid, 2517 pdev_id, dbg_id); 2518 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2519 wlan_psoc_obj_unlock(psoc); 2520 2521 return peer; 2522 } 2523 2524 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); 2525 #endif 2526 2527 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2528 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock_debug( 2529 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2530 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 2531 const char *func, int line) 2532 { 2533 struct wlan_objmgr_psoc_objmgr *objmgr; 2534 uint8_t hash_index; 2535 struct wlan_objmgr_peer *peer = NULL; 2536 struct wlan_peer_list *peer_list; 2537 2538 /* psoc lock should be taken before peer list lock */ 2539 objmgr = &psoc->soc_objmgr; 2540 /* List is empty, return NULL */ 2541 if (objmgr->wlan_peer_count == 0) 2542 return NULL; 2543 2544 /* reduce the search window, with hash key */ 2545 hash_index = WLAN_PEER_HASH(macaddr); 2546 peer_list = &objmgr->peer_list; 2547 /* Iterate through peer list, get peer */ 2548 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id_debug( 2549 &peer_list->peer_hash[hash_index], macaddr, 2550 pdev_id, dbg_id, func, line); 2551 2552 return peer; 2553 } 2554 2555 qdf_export_symbol(wlan_objmgr_get_peer_nolock_debug); 2556 #else 2557 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( 2558 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2559 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 2560 { 2561 struct wlan_objmgr_psoc_objmgr *objmgr; 2562 uint8_t hash_index; 2563 struct wlan_objmgr_peer *peer = NULL; 2564 struct wlan_peer_list *peer_list; 2565 2566 /* psoc lock should be taken before peer list lock */ 2567 objmgr = &psoc->soc_objmgr; 2568 /* List is empty, return NULL */ 2569 if (objmgr->wlan_peer_count == 0) 2570 return NULL; 2571 2572 /* reduce the search window, with hash key */ 2573 hash_index = WLAN_PEER_HASH(macaddr); 2574 peer_list = &objmgr->peer_list; 2575 /* Iterate through peer list, get peer */ 2576 peer = wlan_obj_psoc_peerlist_get_peer_by_pdev_id( 2577 &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); 2578 2579 return peer; 2580 } 2581 2582 qdf_export_symbol(wlan_objmgr_get_peer_nolock); 2583 #endif 2584 2585 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2586 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state_debug( 2587 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2588 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id, 2589 const char *func, int line) 2590 { 2591 struct wlan_objmgr_psoc_objmgr *objmgr; 2592 uint8_t hash_index; 2593 struct wlan_objmgr_peer *peer = NULL; 2594 struct wlan_peer_list *peer_list; 2595 2596 /* psoc lock should be taken before peer list lock */ 2597 wlan_psoc_obj_lock(psoc); 2598 objmgr = &psoc->soc_objmgr; 2599 /* List is empty, return NULL */ 2600 if (objmgr->wlan_peer_count == 0) { 2601 wlan_psoc_obj_unlock(psoc); 2602 return NULL; 2603 } 2604 /* reduce the search window, with hash key */ 2605 hash_index = WLAN_PEER_HASH(macaddr); 2606 peer_list = &objmgr->peer_list; 2607 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2608 /* Iterate through peer list, get peer */ 2609 peer = wlan_obj_psoc_peerlist_get_peer_no_state_debug( 2610 &peer_list->peer_hash[hash_index], macaddr, 2611 pdev_id, dbg_id, func, line); 2612 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2613 wlan_psoc_obj_unlock(psoc); 2614 2615 return peer; 2616 } 2617 2618 qdf_export_symbol(wlan_objmgr_get_peer_no_state_debug); 2619 #else 2620 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( 2621 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2622 uint8_t *macaddr, wlan_objmgr_ref_dbgid dbg_id) 2623 { 2624 struct wlan_objmgr_psoc_objmgr *objmgr; 2625 uint8_t hash_index; 2626 struct wlan_objmgr_peer *peer = NULL; 2627 struct wlan_peer_list *peer_list; 2628 2629 /* psoc lock should be taken before peer list lock */ 2630 wlan_psoc_obj_lock(psoc); 2631 objmgr = &psoc->soc_objmgr; 2632 /* List is empty, return NULL */ 2633 if (objmgr->wlan_peer_count == 0) { 2634 wlan_psoc_obj_unlock(psoc); 2635 return NULL; 2636 } 2637 /* reduce the search window, with hash key */ 2638 hash_index = WLAN_PEER_HASH(macaddr); 2639 peer_list = &objmgr->peer_list; 2640 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2641 /* Iterate through peer list, get peer */ 2642 peer = wlan_obj_psoc_peerlist_get_peer_no_state( 2643 &peer_list->peer_hash[hash_index], macaddr, pdev_id, dbg_id); 2644 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2645 wlan_psoc_obj_unlock(psoc); 2646 2647 return peer; 2648 } 2649 2650 qdf_export_symbol(wlan_objmgr_get_peer_no_state); 2651 #endif 2652 2653 #ifdef WLAN_OBJMGR_REF_ID_TRACE 2654 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug( 2655 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2656 uint8_t *bssid, uint8_t *macaddr, 2657 wlan_objmgr_ref_dbgid dbg_id, 2658 const char *func, int line) 2659 { 2660 struct wlan_objmgr_psoc_objmgr *objmgr; 2661 uint8_t hash_index; 2662 struct wlan_peer_list *peer_list = NULL; 2663 qdf_list_t *logical_del_peer_list = NULL; 2664 2665 /* psoc lock should be taken before peer list lock */ 2666 wlan_psoc_obj_lock(psoc); 2667 objmgr = &psoc->soc_objmgr; 2668 /* List is empty, return NULL */ 2669 if (objmgr->wlan_peer_count == 0) { 2670 wlan_psoc_obj_unlock(psoc); 2671 return NULL; 2672 } 2673 /* reduce the search window, with hash key */ 2674 hash_index = WLAN_PEER_HASH(macaddr); 2675 peer_list = &objmgr->peer_list; 2676 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2677 2678 /* Iterate through peer list, get peer */ 2679 logical_del_peer_list = 2680 wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid_debug( 2681 &peer_list->peer_hash[hash_index], macaddr, 2682 bssid, pdev_id, dbg_id, func, line); 2683 2684 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2685 wlan_psoc_obj_unlock(psoc); 2686 2687 return logical_del_peer_list; 2688 } 2689 2690 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev_debug); 2691 #else 2692 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( 2693 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, 2694 uint8_t *bssid, uint8_t *macaddr, 2695 wlan_objmgr_ref_dbgid dbg_id) 2696 { 2697 struct wlan_objmgr_psoc_objmgr *objmgr; 2698 uint8_t hash_index; 2699 struct wlan_peer_list *peer_list = NULL; 2700 qdf_list_t *logical_del_peer_list = NULL; 2701 2702 /* psoc lock should be taken before peer list lock */ 2703 wlan_psoc_obj_lock(psoc); 2704 objmgr = &psoc->soc_objmgr; 2705 /* List is empty, return NULL */ 2706 if (objmgr->wlan_peer_count == 0) { 2707 wlan_psoc_obj_unlock(psoc); 2708 return NULL; 2709 } 2710 /* reduce the search window, with hash key */ 2711 hash_index = WLAN_PEER_HASH(macaddr); 2712 peer_list = &objmgr->peer_list; 2713 qdf_spin_lock_bh(&peer_list->peer_list_lock); 2714 2715 /* Iterate through peer list, get peer */ 2716 logical_del_peer_list = 2717 wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( 2718 &peer_list->peer_hash[hash_index], macaddr, 2719 bssid, pdev_id, dbg_id); 2720 2721 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 2722 wlan_psoc_obj_unlock(psoc); 2723 2724 return logical_del_peer_list; 2725 } 2726 2727 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev); 2728 #endif 2729 2730 void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc, 2731 enum wlan_umac_comp_id id) 2732 { 2733 void *comp_private_obj; 2734 2735 /* component id is invalid */ 2736 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 2737 QDF_BUG(0); 2738 return NULL; 2739 } 2740 2741 if (!psoc) { 2742 QDF_BUG(0); 2743 return NULL; 2744 } 2745 2746 comp_private_obj = psoc->soc_comp_priv_obj[id]; 2747 2748 return comp_private_obj; 2749 } 2750 qdf_export_symbol(wlan_objmgr_psoc_get_comp_private_obj); 2751 2752 void wlan_objmgr_psoc_get_ref(struct wlan_objmgr_psoc *psoc, 2753 wlan_objmgr_ref_dbgid id) 2754 { 2755 if (!psoc) { 2756 obj_mgr_err("psoc obj is NULL for id:%d", id); 2757 QDF_ASSERT(0); 2758 return; 2759 } 2760 /* Increment ref count */ 2761 qdf_atomic_inc(&psoc->soc_objmgr.ref_cnt); 2762 qdf_atomic_inc(&psoc->soc_objmgr.ref_id_dbg[id]); 2763 return; 2764 } 2765 qdf_export_symbol(wlan_objmgr_psoc_get_ref); 2766 2767 QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc, 2768 wlan_objmgr_ref_dbgid id) 2769 { 2770 if (!psoc) { 2771 obj_mgr_err("psoc obj is NULL for id:%d", id); 2772 QDF_ASSERT(0); 2773 return QDF_STATUS_E_FAILURE; 2774 } 2775 2776 wlan_psoc_obj_lock(psoc); 2777 if (psoc->obj_state != WLAN_OBJ_STATE_CREATED) { 2778 wlan_psoc_obj_unlock(psoc); 2779 if (psoc->soc_objmgr.print_cnt++ <= 2780 WLAN_OBJMGR_RATELIMIT_THRESH) 2781 obj_mgr_err( 2782 "[Ref id: %d] psoc is not in Created state(%d)", 2783 id, psoc->obj_state); 2784 2785 return QDF_STATUS_E_RESOURCES; 2786 } 2787 2788 /* Increment ref count */ 2789 wlan_objmgr_psoc_get_ref(psoc, id); 2790 wlan_psoc_obj_unlock(psoc); 2791 2792 return QDF_STATUS_SUCCESS; 2793 } 2794 qdf_export_symbol(wlan_objmgr_psoc_try_get_ref); 2795 2796 void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc, 2797 wlan_objmgr_ref_dbgid id) 2798 { 2799 if (!psoc) { 2800 obj_mgr_err("psoc obj is NULL for id:%d", id); 2801 QDF_ASSERT(0); 2802 return; 2803 } 2804 2805 if (!qdf_atomic_read(&psoc->soc_objmgr.ref_id_dbg[id])) { 2806 obj_mgr_err("psoc ref cnt was not taken by %d", id); 2807 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg, 2808 QDF_TRACE_LEVEL_FATAL); 2809 WLAN_OBJMGR_BUG(0); 2810 } 2811 2812 if (!qdf_atomic_read(&psoc->soc_objmgr.ref_cnt)) { 2813 obj_mgr_err("psoc ref cnt is 0"); 2814 WLAN_OBJMGR_BUG(0); 2815 return; 2816 } 2817 2818 qdf_atomic_dec(&psoc->soc_objmgr.ref_id_dbg[id]); 2819 /* Decrement ref count, free psoc, if ref count == 0 */ 2820 if (qdf_atomic_dec_and_test(&psoc->soc_objmgr.ref_cnt)) 2821 wlan_objmgr_psoc_obj_destroy(psoc); 2822 2823 return; 2824 } 2825 qdf_export_symbol(wlan_objmgr_psoc_release_ref); 2826 2827 static void wlan_objmgr_psoc_peer_ref_print(struct wlan_objmgr_psoc *psoc, 2828 void *obj, void *args) 2829 { 2830 struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj; 2831 WLAN_OBJ_STATE obj_state; 2832 uint8_t vdev_id; 2833 uint8_t *macaddr; 2834 2835 wlan_peer_obj_lock(peer); 2836 macaddr = wlan_peer_get_macaddr(peer); 2837 obj_state = peer->obj_state; 2838 vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); 2839 wlan_peer_obj_unlock(peer); 2840 2841 obj_mgr_alert("Peer MAC:" QDF_MAC_ADDR_FMT "state:%d vdev_id:%d", 2842 QDF_MAC_ADDR_REF(macaddr), obj_state, vdev_id); 2843 wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_FATAL); 2844 } 2845 2846 static void wlan_objmgr_psoc_vdev_ref_print(struct wlan_objmgr_psoc *psoc, 2847 void *obj, void *args) 2848 { 2849 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj; 2850 WLAN_OBJ_STATE obj_state; 2851 uint8_t id; 2852 2853 wlan_vdev_obj_lock(vdev); 2854 id = wlan_vdev_get_id(vdev); 2855 obj_state = vdev->obj_state; 2856 wlan_vdev_obj_unlock(vdev); 2857 obj_mgr_alert("Vdev ID is %d, state %d", id, obj_state); 2858 2859 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, 2860 QDF_TRACE_LEVEL_FATAL); 2861 } 2862 2863 static void wlan_objmgr_psoc_pdev_ref_print(struct wlan_objmgr_psoc *psoc, 2864 void *obj, void *args) 2865 { 2866 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj; 2867 uint8_t id; 2868 2869 wlan_pdev_obj_lock(pdev); 2870 id = wlan_objmgr_pdev_get_pdev_id(pdev); 2871 wlan_pdev_obj_unlock(pdev); 2872 obj_mgr_alert("pdev ID is %d", id); 2873 2874 wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg, 2875 QDF_TRACE_LEVEL_FATAL); 2876 } 2877 2878 QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc( 2879 struct wlan_objmgr_psoc *psoc) 2880 { 2881 obj_mgr_alert("Ref counts of PEER"); 2882 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PEER_OP, 2883 wlan_objmgr_psoc_peer_ref_print, NULL); 2884 obj_mgr_alert("Ref counts of VDEV"); 2885 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_VDEV_OP, 2886 wlan_objmgr_psoc_vdev_ref_print, NULL); 2887 obj_mgr_alert("Ref counts of PDEV"); 2888 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PDEV_OP, 2889 wlan_objmgr_psoc_pdev_ref_print, NULL); 2890 2891 obj_mgr_alert(" Ref counts of PSOC"); 2892 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg, 2893 QDF_TRACE_LEVEL_FATAL); 2894 2895 return QDF_STATUS_SUCCESS; 2896 } 2897 qdf_export_symbol(wlan_objmgr_print_ref_all_objects_per_psoc); 2898 2899 QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, 2900 struct wlan_objmgr_psoc_user_config *user_config_data) 2901 { 2902 if (!user_config_data) { 2903 obj_mgr_err("user_config_data is NULL"); 2904 QDF_BUG(0); 2905 return QDF_STATUS_E_FAILURE; 2906 } 2907 wlan_psoc_obj_lock(psoc); 2908 qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data, 2909 sizeof(psoc->soc_nif.user_config)); 2910 wlan_psoc_obj_unlock(psoc); 2911 2912 return QDF_STATUS_SUCCESS; 2913 } 2914 2915 uint32_t wlan_objmgr_psoc_check_for_pdev_leaks(struct wlan_objmgr_psoc *psoc) 2916 { 2917 struct wlan_objmgr_psoc_objmgr *_psoc; 2918 struct wlan_objmgr_pdev *pdev; 2919 int pdev_id; 2920 uint32_t leaks = 0; 2921 2922 QDF_BUG(psoc); 2923 if (!psoc) 2924 return leaks; 2925 2926 wlan_psoc_obj_lock(psoc); 2927 _psoc = &psoc->soc_objmgr; 2928 if (!_psoc->wlan_pdev_count) { 2929 wlan_psoc_obj_unlock(psoc); 2930 return leaks; 2931 } 2932 2933 obj_mgr_alert("objmgr pdev leaks detected for psoc %u!", 2934 _psoc->psoc_id); 2935 obj_mgr_alert("----------------------------------------------------"); 2936 obj_mgr_alert("Pdev Id Refs Module"); 2937 obj_mgr_alert("----------------------------------------------------"); 2938 2939 wlan_objmgr_for_each_psoc_pdev(psoc, pdev_id, pdev) { 2940 qdf_atomic_t *ref_id_dbg; 2941 int ref_id; 2942 int32_t refs; 2943 2944 wlan_pdev_obj_lock(pdev); 2945 ref_id_dbg = pdev->pdev_objmgr.ref_id_dbg; 2946 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 2947 leaks++; 2948 obj_mgr_alert("%7u %4u %s(%d)", 2949 pdev_id, refs, 2950 string_from_dbgid(ref_id), ref_id); 2951 } 2952 wlan_pdev_obj_unlock(pdev); 2953 } 2954 2955 wlan_psoc_obj_unlock(psoc); 2956 return leaks; 2957 } 2958 qdf_export_symbol(wlan_objmgr_psoc_check_for_pdev_leaks); 2959 2960 uint32_t wlan_objmgr_psoc_check_for_vdev_leaks(struct wlan_objmgr_psoc *psoc) 2961 { 2962 struct wlan_objmgr_psoc_objmgr *_psoc; 2963 struct wlan_objmgr_vdev *vdev; 2964 int vdev_id; 2965 uint32_t leaks = 0; 2966 2967 QDF_BUG(psoc); 2968 if (!psoc) 2969 return leaks; 2970 2971 wlan_psoc_obj_lock(psoc); 2972 _psoc = &psoc->soc_objmgr; 2973 if (!_psoc->wlan_vdev_count) { 2974 wlan_psoc_obj_unlock(psoc); 2975 return leaks; 2976 } 2977 2978 obj_mgr_alert("objmgr vdev leaks detected for psoc %u!", 2979 _psoc->psoc_id); 2980 obj_mgr_alert("----------------------------------------------------"); 2981 obj_mgr_alert("Vdev Id Refs Module"); 2982 obj_mgr_alert("----------------------------------------------------"); 2983 2984 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 2985 qdf_atomic_t *ref_id_dbg; 2986 int ref_id; 2987 int32_t refs; 2988 2989 wlan_vdev_obj_lock(vdev); 2990 ref_id_dbg = vdev->vdev_objmgr.ref_id_dbg; 2991 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 2992 leaks++; 2993 obj_mgr_alert("%7u %4u %s(%d)", 2994 vdev_id, refs, string_from_dbgid(ref_id), 2995 ref_id); 2996 } 2997 wlan_vdev_obj_unlock(vdev); 2998 } 2999 3000 wlan_psoc_obj_unlock(psoc); 3001 return leaks; 3002 } 3003 qdf_export_symbol(wlan_objmgr_psoc_check_for_vdev_leaks); 3004 3005 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 3006 static void 3007 wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) 3008 { 3009 qdf_atomic_t *ref_id_dbg; 3010 int32_t refs; 3011 int ref_id; 3012 3013 ref_id_dbg = peer->peer_objmgr.ref_id_dbg; 3014 wlan_objmgr_for_each_refs(ref_id_dbg, ref_id, refs) { 3015 obj_mgr_alert(QDF_MAC_ADDR_FMT " %7u %4u %s(%d)", 3016 QDF_MAC_ADDR_REF(peer->macaddr), 3017 vdev_id, 3018 refs, 3019 string_from_dbgid(ref_id), ref_id); 3020 } 3021 } 3022 #else 3023 static inline void 3024 wlan_objmgr_print_peer_ref_leaks(struct wlan_objmgr_peer *peer, int vdev_id) 3025 { 3026 obj_mgr_alert(QDF_MAC_ADDR_FMT " %7u %4u %s", 3027 QDF_MAC_ADDR_REF(peer->macaddr), 3028 vdev_id, 3029 qdf_atomic_read(&peer->peer_objmgr.ref_cnt), 3030 "TOTAL_REF_COUNT"); 3031 } 3032 #endif 3033 3034 uint32_t wlan_objmgr_psoc_check_for_peer_leaks(struct wlan_objmgr_psoc *psoc) 3035 { 3036 struct wlan_objmgr_psoc_objmgr *_psoc; 3037 struct wlan_objmgr_vdev *vdev; 3038 int vdev_id; 3039 uint32_t leaks = 0; 3040 3041 QDF_BUG(psoc); 3042 if (!psoc) 3043 return leaks; 3044 3045 wlan_psoc_obj_lock(psoc); 3046 _psoc = &psoc->soc_objmgr; 3047 if (!_psoc->temp_peer_count && !_psoc->wlan_peer_count) { 3048 wlan_psoc_obj_unlock(psoc); 3049 return leaks; 3050 } 3051 3052 obj_mgr_alert("objmgr peer leaks detected for psoc %u!", 3053 _psoc->psoc_id); 3054 obj_mgr_alert("----------------------------------------------------"); 3055 obj_mgr_alert("Peer MAC Vdev Id Refs Module"); 3056 obj_mgr_alert("----------------------------------------------------"); 3057 3058 wlan_objmgr_for_each_psoc_vdev(psoc, vdev_id, vdev) { 3059 struct wlan_objmgr_peer *peer; 3060 3061 wlan_vdev_obj_lock(vdev); 3062 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 3063 wlan_peer_obj_lock(peer); 3064 leaks += qdf_atomic_read(&peer->peer_objmgr.ref_cnt); 3065 wlan_objmgr_print_peer_ref_leaks(peer, vdev_id); 3066 wlan_peer_obj_unlock(peer); 3067 } 3068 wlan_vdev_obj_unlock(vdev); 3069 } 3070 3071 wlan_psoc_obj_unlock(psoc); 3072 return leaks; 3073 } 3074 qdf_export_symbol(wlan_objmgr_psoc_check_for_peer_leaks); 3075 3076 void wlan_objmgr_psoc_check_for_leaks(struct wlan_objmgr_psoc *psoc) 3077 { 3078 struct wlan_objmgr_psoc_objmgr *_psoc; 3079 uint32_t peer_leaks = 0; 3080 uint32_t vdev_leaks = 0; 3081 uint32_t pdev_leaks = 0; 3082 3083 _psoc = &psoc->soc_objmgr; 3084 3085 peer_leaks = wlan_objmgr_psoc_check_for_peer_leaks(psoc); 3086 vdev_leaks = wlan_objmgr_psoc_check_for_vdev_leaks(psoc); 3087 pdev_leaks = wlan_objmgr_psoc_check_for_pdev_leaks(psoc); 3088 3089 if (peer_leaks || vdev_leaks || pdev_leaks) { 3090 QDF_DEBUG_PANIC("%u objmgr peer leaks %u objmgr vdev leaks" 3091 "%u objmgr pdev leaks detected for psoc %u!", 3092 peer_leaks, vdev_leaks, pdev_leaks, 3093 _psoc->psoc_id); 3094 } 3095 } 3096 3097 qdf_export_symbol(wlan_objmgr_psoc_check_for_leaks); 3098 3099 #ifdef WLAN_OBJMGR_DEBUG 3100 void wlan_print_psoc_info(struct wlan_objmgr_psoc *psoc) 3101 { 3102 struct wlan_objmgr_psoc_objmgr *psoc_objmgr; 3103 struct wlan_objmgr_pdev *pdev; 3104 struct wlan_objmgr_vdev *vdev; 3105 uint16_t index = 0; 3106 3107 psoc_objmgr = &psoc->soc_objmgr; 3108 3109 obj_mgr_debug("psoc: %pK", psoc); 3110 obj_mgr_debug("psoc_id: %d", psoc_objmgr->psoc_id); 3111 obj_mgr_debug("wlan_pdev_count: %d", psoc_objmgr->wlan_pdev_count); 3112 obj_mgr_debug("wlan_pdev_id_map: 0x%x", psoc_objmgr->wlan_pdev_id_map); 3113 obj_mgr_debug("wlan_vdev_count: %d", psoc_objmgr->wlan_vdev_count); 3114 obj_mgr_debug("max_vdev_count: %d", psoc_objmgr->max_vdev_count); 3115 obj_mgr_debug("wlan_peer_count: %d", psoc_objmgr->wlan_peer_count); 3116 obj_mgr_debug("max_peer_count: %d", psoc_objmgr->max_peer_count); 3117 obj_mgr_debug("temp_peer_count: %d", psoc_objmgr->temp_peer_count); 3118 obj_mgr_debug("ref_cnt: %d", qdf_atomic_read(&psoc_objmgr->ref_cnt)); 3119 obj_mgr_debug("qdf_dev: %pK", psoc_objmgr->qdf_dev); 3120 3121 obj_mgr_debug("wlan_vdev_id_map:"); 3122 obj_mgr_debug_hex(psoc_objmgr->wlan_vdev_id_map, 3123 sizeof(psoc_objmgr->wlan_vdev_id_map)); 3124 3125 wlan_objmgr_for_each_psoc_pdev(psoc, index, pdev) { 3126 obj_mgr_debug("wlan_pdev_list[%d]: %pK", index, pdev); 3127 wlan_print_pdev_info(pdev); 3128 } 3129 3130 wlan_objmgr_for_each_psoc_vdev(psoc, index, vdev) { 3131 obj_mgr_debug("wlan_vdev_list[%d]: %pK", index, vdev); 3132 wlan_print_vdev_info(vdev); 3133 } 3134 } 3135 3136 qdf_export_symbol(wlan_print_psoc_info); 3137 #endif 3138