1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /** 19 * DOC: Public APIs to perform operations on Global objects 20 */ 21 22 #include <wlan_objmgr_cmn.h> 23 #include <wlan_objmgr_global_obj.h> 24 #include <wlan_objmgr_psoc_obj.h> 25 #include <wlan_objmgr_pdev_obj.h> 26 #include <wlan_objmgr_vdev_obj.h> 27 #include <wlan_objmgr_peer_obj.h> 28 #include <qdf_mem.h> 29 #include <qdf_types.h> 30 #include <qdf_module.h> 31 #include "wlan_objmgr_global_obj_i.h" 32 #include "wlan_objmgr_psoc_obj_i.h" 33 #include "wlan_objmgr_pdev_obj_i.h" 34 35 /** 36 ** APIs to Create/Delete Global object APIs 37 */ 38 static QDF_STATUS wlan_objmgr_psoc_object_status( 39 struct wlan_objmgr_psoc *psoc) 40 { 41 uint8_t id; 42 QDF_STATUS status = QDF_STATUS_SUCCESS; 43 44 wlan_psoc_obj_lock(psoc); 45 /* Iterate through all components to derive the object status */ 46 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 47 /* If component disabled, Ignore */ 48 if (psoc->obj_status[id] == QDF_STATUS_COMP_DISABLED) 49 continue; 50 /* If component operates in Async, status is Partially created, 51 * break 52 */ 53 else if (psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC) { 54 if (psoc->soc_comp_priv_obj[id] == NULL) { 55 status = QDF_STATUS_COMP_ASYNC; 56 break; 57 } 58 /* 59 * If component failed to allocate its object, treat it as 60 * failure, complete object need to be cleaned up 61 */ 62 } else if ((psoc->obj_status[id] == QDF_STATUS_E_NOMEM) || 63 (psoc->obj_status[id] == QDF_STATUS_E_FAILURE)) { 64 status = QDF_STATUS_E_FAILURE; 65 break; 66 } 67 } 68 wlan_psoc_obj_unlock(psoc); 69 70 return status; 71 } 72 73 static void wlan_objmgr_psoc_peer_list_init(struct wlan_peer_list *peer_list) 74 { 75 uint8_t i; 76 77 qdf_spinlock_create(&peer_list->peer_list_lock); 78 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) 79 qdf_list_create(&peer_list->peer_hash[i], 80 WLAN_UMAC_PSOC_MAX_PEERS); 81 } 82 83 static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list) 84 { 85 uint8_t i; 86 87 /* deinit the lock */ 88 qdf_spinlock_destroy(&peer_list->peer_list_lock); 89 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) 90 qdf_list_destroy(&peer_list->peer_hash[i]); 91 } 92 93 static QDF_STATUS wlan_objmgr_psoc_obj_free(struct wlan_objmgr_psoc *psoc) 94 { 95 /* Detach PSOC from global object's psoc list */ 96 if (wlan_objmgr_psoc_object_detach(psoc) == QDF_STATUS_E_FAILURE) { 97 obj_mgr_err("PSOC object detach failed"); 98 return QDF_STATUS_E_FAILURE; 99 } 100 wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list); 101 102 qdf_spinlock_destroy(&psoc->psoc_lock); 103 qdf_mem_free(psoc); 104 105 return QDF_STATUS_SUCCESS; 106 } 107 108 struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version, 109 WLAN_DEV_TYPE dev_type) 110 { 111 uint8_t id; 112 struct wlan_objmgr_psoc *psoc = NULL; 113 wlan_objmgr_psoc_create_handler handler; 114 wlan_objmgr_psoc_status_handler stat_handler; 115 struct wlan_objmgr_psoc_objmgr *objmgr; 116 QDF_STATUS obj_status; 117 void *arg; 118 119 psoc = qdf_mem_malloc(sizeof(*psoc)); 120 if (psoc == NULL) { 121 obj_mgr_err("PSOC allocation failed"); 122 return NULL; 123 } 124 psoc->obj_state = WLAN_OBJ_STATE_ALLOCATED; 125 qdf_spinlock_create(&psoc->psoc_lock); 126 /* Initialize with default values */ 127 objmgr = &psoc->soc_objmgr; 128 objmgr->wlan_pdev_count = 0; 129 objmgr->wlan_vdev_count = 0; 130 objmgr->max_vdev_count = WLAN_UMAC_PSOC_MAX_VDEVS; 131 objmgr->wlan_peer_count = 0; 132 objmgr->max_peer_count = WLAN_UMAC_PSOC_MAX_PEERS; 133 qdf_atomic_init(&objmgr->ref_cnt); 134 objmgr->print_cnt = 0; 135 /* set phy version, dev_type in psoc */ 136 wlan_psoc_set_nif_phy_version(psoc, phy_version); 137 wlan_psoc_set_dev_type(psoc, dev_type); 138 /* Initialize peer list */ 139 wlan_objmgr_psoc_peer_list_init(&objmgr->peer_list); 140 wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID); 141 /* Invoke registered create handlers */ 142 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 143 handler = g_umac_glb_obj->psoc_create_handler[id]; 144 arg = g_umac_glb_obj->psoc_create_handler_arg[id]; 145 if (handler != NULL) 146 psoc->obj_status[id] = handler(psoc, arg); 147 else 148 psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED; 149 } 150 /* Derive object status */ 151 obj_status = wlan_objmgr_psoc_object_status(psoc); 152 153 if (obj_status == QDF_STATUS_SUCCESS) { 154 /* Object status is SUCCESS, Object is created */ 155 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 156 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 157 stat_handler = g_umac_glb_obj->psoc_status_handler[id]; 158 arg = g_umac_glb_obj->psoc_status_handler_arg[id]; 159 if (stat_handler != NULL) 160 stat_handler(psoc, arg, 161 QDF_STATUS_SUCCESS); 162 } 163 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 164 /* 165 * Few components operates in Asynchrous communction 166 * Object state partially created 167 */ 168 psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 169 } else if (obj_status == QDF_STATUS_E_FAILURE) { 170 /* Component object failed to be created, clean up the object */ 171 obj_mgr_err("PSOC component objects allocation failed"); 172 /* Clean up the psoc */ 173 wlan_objmgr_psoc_obj_delete(psoc); 174 return NULL; 175 } 176 177 if (wlan_objmgr_psoc_object_attach(psoc) != 178 QDF_STATUS_SUCCESS) { 179 obj_mgr_err("PSOC object attach failed"); 180 wlan_objmgr_psoc_obj_delete(psoc); 181 return NULL; 182 } 183 184 obj_mgr_info("Created psoc %d", psoc->soc_objmgr.psoc_id); 185 186 return psoc; 187 } 188 qdf_export_symbol(wlan_objmgr_psoc_obj_create); 189 190 static QDF_STATUS wlan_objmgr_psoc_obj_destroy(struct wlan_objmgr_psoc *psoc) 191 { 192 uint8_t id; 193 wlan_objmgr_psoc_destroy_handler handler; 194 QDF_STATUS obj_status; 195 void *arg; 196 197 if (psoc == NULL) { 198 obj_mgr_err("psoc is NULL"); 199 return QDF_STATUS_E_FAILURE; 200 } 201 wlan_objmgr_notify_destroy(psoc, WLAN_PSOC_OP); 202 203 obj_mgr_info("Physically deleting psoc %d", psoc->soc_objmgr.psoc_id); 204 205 if (psoc->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { 206 obj_mgr_err("psoc object delete is not invoked"); 207 WLAN_OBJMGR_BUG(0); 208 } 209 210 /* Invoke registered create handlers */ 211 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 212 handler = g_umac_glb_obj->psoc_destroy_handler[id]; 213 arg = g_umac_glb_obj->psoc_destroy_handler_arg[id]; 214 if (handler != NULL) 215 psoc->obj_status[id] = handler(psoc, arg); 216 else 217 psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED; 218 } 219 /* Derive object status */ 220 obj_status = wlan_objmgr_psoc_object_status(psoc); 221 222 if (obj_status == QDF_STATUS_E_FAILURE) { 223 obj_mgr_err("PSOC component object free failed"); 224 /* Ideally should not happen 225 * This leads to memleak, BUG_ON to find which component 226 * delete notification failed and fix it. 227 */ 228 QDF_BUG(0); 229 return QDF_STATUS_E_FAILURE; 230 } 231 /* Deletion is in progress */ 232 if (obj_status == QDF_STATUS_COMP_ASYNC) { 233 psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED; 234 return QDF_STATUS_COMP_ASYNC; 235 } 236 237 /* Free psoc object */ 238 return wlan_objmgr_psoc_obj_free(psoc); 239 } 240 241 242 QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc) 243 { 244 uint8_t print_idx; 245 246 if (psoc == NULL) { 247 obj_mgr_err("psoc is NULL"); 248 return QDF_STATUS_E_FAILURE; 249 } 250 251 obj_mgr_info("Logically deleting psoc %d", psoc->soc_objmgr.psoc_id); 252 253 print_idx = qdf_get_pidx(); 254 if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR, 255 QDF_TRACE_LEVEL_DEBUG)) { 256 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg); 257 } 258 259 /* 260 * Update PSOC object state to LOGICALLY DELETED 261 * It prevents further access of this object 262 */ 263 wlan_psoc_obj_lock(psoc); 264 psoc->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED; 265 wlan_psoc_obj_unlock(psoc); 266 wlan_objmgr_notify_log_delete(psoc, WLAN_PSOC_OP); 267 wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID); 268 269 return QDF_STATUS_SUCCESS; 270 } 271 qdf_export_symbol(wlan_objmgr_psoc_obj_delete); 272 273 QDF_STATUS wlan_objmgr_psoc_component_obj_attach( 274 struct wlan_objmgr_psoc *psoc, 275 enum wlan_umac_comp_id id, 276 void *comp_priv_obj, 277 QDF_STATUS status) 278 { 279 wlan_objmgr_psoc_status_handler stat_handler; 280 void *arg = NULL; 281 QDF_STATUS obj_status; 282 uint8_t i; 283 284 /* component id is invalid */ 285 if (id >= WLAN_UMAC_MAX_COMPONENTS) 286 return QDF_STATUS_MAXCOMP_FAIL; 287 288 wlan_psoc_obj_lock(psoc); 289 /* If there is a valid entry, return failure */ 290 if (psoc->soc_comp_priv_obj[id] != NULL) { 291 wlan_psoc_obj_unlock(psoc); 292 return QDF_STATUS_E_FAILURE; 293 } 294 /* Save component's pointer and status */ 295 psoc->soc_comp_priv_obj[id] = comp_priv_obj; 296 psoc->obj_status[id] = status; 297 298 wlan_psoc_obj_unlock(psoc); 299 300 if (psoc->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED) 301 return QDF_STATUS_SUCCESS; 302 /* If PSOC object status is partially created means, this API is 303 * invoked with differnt context, this block should be executed for 304 * async components only 305 */ 306 /* Derive status */ 307 obj_status = wlan_objmgr_psoc_object_status(psoc); 308 /* STATUS_SUCCESS means, object is CREATED */ 309 if (obj_status == QDF_STATUS_SUCCESS) 310 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 311 /* update state as CREATION failed, caller has to delete the 312 * PSOC object 313 */ 314 else if (obj_status == QDF_STATUS_E_FAILURE) 315 psoc->obj_state = WLAN_OBJ_STATE_CREATION_FAILED; 316 317 /* Notify components about the CREATION success/failure */ 318 if ((obj_status == QDF_STATUS_SUCCESS) || 319 (obj_status == QDF_STATUS_E_FAILURE)) { 320 /* nofity object status */ 321 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 322 stat_handler = g_umac_glb_obj->psoc_status_handler[i]; 323 arg = g_umac_glb_obj->psoc_status_handler_arg[i]; 324 if (stat_handler != NULL) 325 stat_handler(psoc, arg, obj_status); 326 } 327 } 328 329 return QDF_STATUS_SUCCESS; 330 } 331 qdf_export_symbol(wlan_objmgr_psoc_component_obj_attach); 332 333 QDF_STATUS wlan_objmgr_psoc_component_obj_detach( 334 struct wlan_objmgr_psoc *psoc, 335 enum wlan_umac_comp_id id, 336 void *comp_priv_obj) 337 { 338 QDF_STATUS obj_status; 339 340 /* component id is invalid */ 341 if (id >= WLAN_UMAC_MAX_COMPONENTS) 342 return QDF_STATUS_MAXCOMP_FAIL; 343 344 wlan_psoc_obj_lock(psoc); 345 /* If there is a valid entry, return failure */ 346 if (psoc->soc_comp_priv_obj[id] != comp_priv_obj) { 347 psoc->obj_status[id] = QDF_STATUS_E_FAILURE; 348 wlan_psoc_obj_unlock(psoc); 349 return QDF_STATUS_E_FAILURE; 350 } 351 /* Reset pointers to NULL, update the status*/ 352 psoc->soc_comp_priv_obj[id] = NULL; 353 psoc->obj_status[id] = QDF_STATUS_SUCCESS; 354 wlan_psoc_obj_unlock(psoc); 355 356 /* If PSOC object status is partially created means, this API is 357 * invoked with differnt context, this block should be executed for 358 * async components only 359 */ 360 if ((psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) || 361 (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) { 362 /* Derive object status */ 363 obj_status = wlan_objmgr_psoc_object_status(psoc); 364 if (obj_status == QDF_STATUS_SUCCESS) { 365 /* Update the status as Deleted, if full object 366 * deletion is in progress 367 */ 368 if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 369 psoc->obj_state = WLAN_OBJ_STATE_DELETED; 370 371 /* Move to creation state, since this component 372 * deletion alone requested 373 */ 374 if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 375 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 376 /* Object status is failure */ 377 } else if (obj_status == QDF_STATUS_E_FAILURE) { 378 /* Update the status as Deletion failed, if full object 379 * deletion is in progress 380 */ 381 if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 382 psoc->obj_state = 383 WLAN_OBJ_STATE_DELETION_FAILED; 384 385 /* Move to creation state, since this component 386 * deletion alone requested (do not block other 387 * components) 388 */ 389 if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 390 psoc->obj_state = WLAN_OBJ_STATE_CREATED; 391 } 392 393 /* Delete psoc object */ 394 if ((obj_status == QDF_STATUS_SUCCESS) && 395 (psoc->obj_state == WLAN_OBJ_STATE_DELETED)) { 396 /* Free psoc object */ 397 return wlan_objmgr_psoc_obj_free(psoc); 398 } 399 } 400 401 return QDF_STATUS_SUCCESS; 402 } 403 qdf_export_symbol(wlan_objmgr_psoc_component_obj_detach); 404 405 QDF_STATUS wlan_objmgr_iterate_obj_list( 406 struct wlan_objmgr_psoc *psoc, 407 enum wlan_objmgr_obj_type obj_type, 408 wlan_objmgr_op_handler handler, 409 void *arg, uint8_t lock_free_op, 410 wlan_objmgr_ref_dbgid dbg_id) 411 { 412 uint16_t obj_id; 413 uint8_t i; 414 struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; 415 struct wlan_peer_list *peer_list; 416 qdf_list_t *obj_list; 417 struct wlan_objmgr_pdev *pdev; 418 struct wlan_objmgr_vdev *vdev; 419 struct wlan_objmgr_peer *peer; 420 struct wlan_objmgr_peer *peer_next; 421 uint16_t max_vdev_cnt; 422 423 /* If caller requests for lock free opeation, do not acquire, 424 * handler will handle the synchronization 425 */ 426 if (!lock_free_op) 427 wlan_psoc_obj_lock(psoc); 428 429 switch (obj_type) { 430 case WLAN_PDEV_OP: 431 /* Iterate through PDEV list, invoke handler for each pdev */ 432 for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { 433 pdev = objmgr->wlan_pdev_list[obj_id]; 434 if ((pdev != NULL) && 435 (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) == 436 QDF_STATUS_SUCCESS)) { 437 handler(psoc, (void *)pdev, arg); 438 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 439 } 440 } 441 break; 442 case WLAN_VDEV_OP: 443 /* Iterate through VDEV list, invoke handler for each vdev */ 444 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 445 for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { 446 vdev = objmgr->wlan_vdev_list[obj_id]; 447 if ((vdev != NULL) && 448 (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == 449 QDF_STATUS_SUCCESS)) { 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 /* psoc lock should be taken before list lock */ 459 if (!lock_free_op) 460 qdf_spin_lock_bh(&peer_list->peer_list_lock); 461 /* Since peer list has sublist, iterate through sublists */ 462 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { 463 obj_list = &peer_list->peer_hash[i]; 464 peer = wlan_psoc_peer_list_peek_head(obj_list); 465 while (peer) { 466 /* Get next peer */ 467 peer_next = wlan_peer_get_next_peer_of_psoc( 468 obj_list, peer); 469 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) 470 == QDF_STATUS_SUCCESS) { 471 handler(psoc, (void *)peer, arg); 472 wlan_objmgr_peer_release_ref(peer, 473 dbg_id); 474 } 475 peer = peer_next; 476 } 477 } 478 if (!lock_free_op) 479 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 480 break; 481 default: 482 break; 483 } 484 if (!lock_free_op) 485 wlan_psoc_obj_unlock(psoc); 486 487 return QDF_STATUS_SUCCESS; 488 } 489 qdf_export_symbol(wlan_objmgr_iterate_obj_list); 490 491 QDF_STATUS wlan_objmgr_iterate_obj_list_all( 492 struct wlan_objmgr_psoc *psoc, 493 enum wlan_objmgr_obj_type obj_type, 494 wlan_objmgr_op_handler handler, 495 void *arg, uint8_t lock_free_op, 496 wlan_objmgr_ref_dbgid dbg_id) 497 { 498 uint16_t obj_id; 499 uint8_t i; 500 struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; 501 struct wlan_peer_list *peer_list; 502 qdf_list_t *obj_list; 503 struct wlan_objmgr_pdev *pdev; 504 struct wlan_objmgr_vdev *vdev; 505 struct wlan_objmgr_peer *peer; 506 struct wlan_objmgr_peer *peer_next; 507 uint16_t max_vdev_cnt; 508 509 /* If caller requests for lock free opeation, do not acquire, 510 * handler will handle the synchronization 511 */ 512 if (!lock_free_op) 513 wlan_psoc_obj_lock(psoc); 514 515 switch (obj_type) { 516 case WLAN_PDEV_OP: 517 /* Iterate through PDEV list, invoke handler for each pdev */ 518 for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { 519 pdev = objmgr->wlan_pdev_list[obj_id]; 520 if (pdev != NULL) { 521 wlan_objmgr_pdev_get_ref(pdev, dbg_id); 522 handler(psoc, (void *)pdev, arg); 523 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 524 } 525 } 526 break; 527 case WLAN_VDEV_OP: 528 /* Iterate through VDEV list, invoke handler for each vdev */ 529 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 530 for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { 531 vdev = objmgr->wlan_vdev_list[obj_id]; 532 if (vdev != NULL) { 533 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 534 handler(psoc, vdev, arg); 535 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 536 } 537 } 538 break; 539 case WLAN_PEER_OP: 540 /* Iterate through PEER list, invoke handler for each peer */ 541 peer_list = &objmgr->peer_list; 542 /* psoc lock should be taken before list lock */ 543 if (!lock_free_op) 544 qdf_spin_lock_bh(&peer_list->peer_list_lock); 545 /* Since peer list has sublist, iterate through sublists */ 546 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { 547 obj_list = &peer_list->peer_hash[i]; 548 peer = wlan_psoc_peer_list_peek_head(obj_list); 549 while (peer) { 550 /* Get next peer */ 551 peer_next = wlan_peer_get_next_peer_of_psoc( 552 obj_list, peer); 553 wlan_objmgr_peer_get_ref(peer, dbg_id); 554 handler(psoc, (void *)peer, arg); 555 wlan_objmgr_peer_release_ref(peer, dbg_id); 556 peer = peer_next; 557 } 558 } 559 if (!lock_free_op) 560 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 561 break; 562 default: 563 break; 564 } 565 if (!lock_free_op) 566 wlan_psoc_obj_unlock(psoc); 567 568 return QDF_STATUS_SUCCESS; 569 } 570 qdf_export_symbol(wlan_objmgr_iterate_obj_list_all); 571 572 /** 573 * wlan_objmgr_iterate_obj_list_all_noref() - iterate through all psoc objects 574 * without taking ref 575 * @psoc: PSOC object 576 * @obj_type: PDEV_OP/VDEV_OP/PEER_OP 577 * @handler: the handler will be called for each object of requested type 578 * the handler should be implemented to perform required operation 579 * @arg: agruments passed by caller 580 * 581 * API to be used for performing the operations on all PDEV/VDEV/PEER objects 582 * of psoc with lock protected 583 * 584 * Return: SUCCESS/FAILURE 585 */ 586 static QDF_STATUS wlan_objmgr_iterate_obj_list_all_noref( 587 struct wlan_objmgr_psoc *psoc, 588 enum wlan_objmgr_obj_type obj_type, 589 wlan_objmgr_op_handler handler, 590 void *arg) 591 { 592 uint16_t obj_id; 593 uint8_t i; 594 struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr; 595 struct wlan_peer_list *peer_list; 596 qdf_list_t *obj_list; 597 struct wlan_objmgr_pdev *pdev; 598 struct wlan_objmgr_vdev *vdev; 599 struct wlan_objmgr_peer *peer; 600 struct wlan_objmgr_peer *peer_next; 601 uint16_t max_vdev_cnt; 602 603 /* If caller requests for lock free opeation, do not acquire, 604 * handler will handle the synchronization 605 */ 606 wlan_psoc_obj_lock(psoc); 607 608 switch (obj_type) { 609 case WLAN_PDEV_OP: 610 /* Iterate through PDEV list, invoke handler for each pdev */ 611 for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) { 612 pdev = objmgr->wlan_pdev_list[obj_id]; 613 if (pdev != NULL) 614 handler(psoc, (void *)pdev, arg); 615 } 616 break; 617 case WLAN_VDEV_OP: 618 /* Iterate through VDEV list, invoke handler for each vdev */ 619 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 620 for (obj_id = 0; obj_id < max_vdev_cnt; obj_id++) { 621 vdev = objmgr->wlan_vdev_list[obj_id]; 622 if (vdev != NULL) 623 handler(psoc, vdev, arg); 624 } 625 break; 626 case WLAN_PEER_OP: 627 /* Iterate through PEER list, invoke handler for each peer */ 628 peer_list = &objmgr->peer_list; 629 /* psoc lock should be taken before list lock */ 630 qdf_spin_lock_bh(&peer_list->peer_list_lock); 631 /* Since peer list has sublist, iterate through sublists */ 632 for (i = 0; i < WLAN_PEER_HASHSIZE; i++) { 633 obj_list = &peer_list->peer_hash[i]; 634 peer = wlan_psoc_peer_list_peek_head(obj_list); 635 while (peer) { 636 /* Get next peer */ 637 peer_next = wlan_peer_get_next_peer_of_psoc( 638 obj_list, peer); 639 handler(psoc, (void *)peer, arg); 640 peer = peer_next; 641 } 642 } 643 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 644 break; 645 default: 646 break; 647 } 648 wlan_psoc_obj_unlock(psoc); 649 650 return QDF_STATUS_SUCCESS; 651 } 652 653 static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc, 654 void *obj, void *args) 655 { 656 struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj; 657 658 wlan_objmgr_peer_obj_delete(peer); 659 } 660 661 static void wlan_objmgr_psoc_vdev_delete(struct wlan_objmgr_psoc *psoc, 662 void *obj, void *args) 663 { 664 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj; 665 666 wlan_objmgr_vdev_obj_delete(vdev); 667 } 668 669 static void wlan_objmgr_psoc_pdev_delete(struct wlan_objmgr_psoc *psoc, 670 void *obj, void *args) 671 { 672 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj; 673 674 wlan_objmgr_pdev_obj_delete(pdev); 675 } 676 677 QDF_STATUS wlan_objmgr_free_all_objects_per_psoc( 678 struct wlan_objmgr_psoc *psoc) 679 { 680 /* Free all peers */ 681 wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, 682 wlan_objmgr_psoc_peer_delete, NULL, 1, 683 WLAN_OBJMGR_ID); 684 /* Free all vdevs */ 685 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, 686 wlan_objmgr_psoc_vdev_delete, NULL, 1, 687 WLAN_OBJMGR_ID); 688 /* Free all PDEVs */ 689 wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 690 wlan_objmgr_psoc_pdev_delete, NULL, 1, 691 WLAN_OBJMGR_ID); 692 693 return QDF_STATUS_SUCCESS; 694 } 695 696 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_creation( 697 struct wlan_objmgr_psoc *psoc, 698 enum wlan_umac_comp_id id) 699 { 700 wlan_objmgr_psoc_create_handler handler; 701 void *arg; 702 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 703 704 /* Component id is invalid */ 705 if (id >= WLAN_UMAC_MAX_COMPONENTS) 706 return QDF_STATUS_MAXCOMP_FAIL; 707 708 wlan_psoc_obj_lock(psoc); 709 /* If component object is already created, delete old 710 * component object, then invoke creation 711 */ 712 if (psoc->soc_comp_priv_obj[id] != NULL) { 713 wlan_psoc_obj_unlock(psoc); 714 return QDF_STATUS_E_FAILURE; 715 } 716 wlan_psoc_obj_unlock(psoc); 717 /* Invoke registered create handlers */ 718 handler = g_umac_glb_obj->psoc_create_handler[id]; 719 arg = g_umac_glb_obj->psoc_create_handler_arg[id]; 720 if (handler != NULL) 721 psoc->obj_status[id] = handler(psoc, arg); 722 else 723 return QDF_STATUS_E_FAILURE; 724 725 /* If object status is created, then only handle this object status */ 726 if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) { 727 /* Derive object status */ 728 obj_status = wlan_objmgr_psoc_object_status(psoc); 729 /* Move PSOC object state to Partially created state */ 730 if (obj_status == QDF_STATUS_COMP_ASYNC) { 731 /*TODO atomic */ 732 psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 733 } 734 } 735 736 return obj_status; 737 } 738 739 QDF_STATUS wlan_objmgr_trigger_psoc_comp_priv_object_deletion( 740 struct wlan_objmgr_psoc *psoc, 741 enum wlan_umac_comp_id id) 742 { 743 wlan_objmgr_psoc_destroy_handler handler; 744 void *arg; 745 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 746 747 /* component id is invalid */ 748 if (id >= WLAN_UMAC_MAX_COMPONENTS) 749 return QDF_STATUS_MAXCOMP_FAIL; 750 751 wlan_psoc_obj_lock(psoc); 752 /* Component object was never created, invalid operation */ 753 if (psoc->soc_comp_priv_obj[id] == NULL) { 754 wlan_psoc_obj_unlock(psoc); 755 return QDF_STATUS_E_FAILURE; 756 } 757 wlan_psoc_obj_unlock(psoc); 758 /* Invoke registered create handlers */ 759 handler = g_umac_glb_obj->psoc_destroy_handler[id]; 760 arg = g_umac_glb_obj->psoc_destroy_handler_arg[id]; 761 if (handler != NULL) 762 psoc->obj_status[id] = handler(psoc, arg); 763 else 764 return QDF_STATUS_E_FAILURE; 765 766 /* If object status is created, then only handle this object status */ 767 if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) { 768 obj_status = wlan_objmgr_psoc_object_status(psoc); 769 /* move object state to DEL progress */ 770 if (obj_status == QDF_STATUS_COMP_ASYNC) 771 psoc->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS; 772 } 773 774 return obj_status; 775 } 776 777 /* Util APIs */ 778 779 QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc, 780 struct wlan_objmgr_pdev *pdev) 781 { 782 struct wlan_objmgr_psoc_objmgr *objmgr; 783 uint8_t id = 0; 784 QDF_STATUS status; 785 786 wlan_psoc_obj_lock(psoc); 787 objmgr = &psoc->soc_objmgr; 788 /* 789 * Derive pdev id from pdev map 790 * First free pdev id is assigned 791 */ 792 while ((id < WLAN_UMAC_MAX_PDEVS) && 793 (objmgr->wlan_pdev_id_map & (1<<id))) 794 id++; 795 796 if (id == WLAN_UMAC_MAX_PDEVS) { 797 status = QDF_STATUS_E_FAILURE; 798 } else { 799 /* Update the map for reserving the id */ 800 objmgr->wlan_pdev_id_map |= (1<<id); 801 /* store pdev in pdev list */ 802 objmgr->wlan_pdev_list[id] = pdev; 803 /* Increment pdev count */ 804 objmgr->wlan_pdev_count++; 805 /* save pdev id */ 806 pdev->pdev_objmgr.wlan_pdev_id = id; 807 status = QDF_STATUS_SUCCESS; 808 /* Inrement psoc ref count to block its free before pdev */ 809 wlan_objmgr_psoc_get_ref(psoc, WLAN_OBJMGR_ID); 810 } 811 wlan_psoc_obj_unlock(psoc); 812 813 return status; 814 } 815 816 QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc, 817 struct wlan_objmgr_pdev *pdev) 818 { 819 struct wlan_objmgr_psoc_objmgr *objmgr; 820 uint8_t id; 821 822 id = pdev->pdev_objmgr.wlan_pdev_id; 823 /* If id is invalid, return */ 824 if (id >= WLAN_UMAC_MAX_PDEVS) 825 return QDF_STATUS_E_FAILURE; 826 827 wlan_psoc_obj_lock(psoc); 828 objmgr = &psoc->soc_objmgr; 829 /* Free pdev id slot */ 830 objmgr->wlan_pdev_id_map &= ~(1<<id); 831 objmgr->wlan_pdev_list[id] = NULL; 832 objmgr->wlan_pdev_count--; 833 pdev->pdev_objmgr.wlan_pdev_id = 0xff; 834 wlan_psoc_obj_unlock(psoc); 835 /* Release ref count of psoc */ 836 wlan_objmgr_psoc_release_ref(psoc, WLAN_OBJMGR_ID); 837 838 return QDF_STATUS_SUCCESS; 839 } 840 841 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id( 842 struct wlan_objmgr_psoc *psoc, uint8_t id, 843 wlan_objmgr_ref_dbgid dbg_id) 844 { 845 struct wlan_objmgr_psoc_objmgr *objmgr; 846 struct wlan_objmgr_pdev *pdev = NULL; 847 848 /* If id is invalid, return */ 849 if (id >= WLAN_UMAC_MAX_PDEVS) 850 return NULL; 851 852 wlan_psoc_obj_lock(psoc); 853 objmgr = &psoc->soc_objmgr; 854 /* get pdev from pdev list */ 855 pdev = objmgr->wlan_pdev_list[id]; 856 /* Do not return object, if it is not CREATED state */ 857 if (pdev != NULL) { 858 if (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) != 859 QDF_STATUS_SUCCESS) 860 pdev = NULL; 861 } 862 863 wlan_psoc_obj_unlock(psoc); 864 865 return pdev; 866 } 867 qdf_export_symbol(wlan_objmgr_get_pdev_by_id); 868 869 struct wlan_objmgr_pdev *wlan_objmgr_get_pdev_by_id_no_state( 870 struct wlan_objmgr_psoc *psoc, uint8_t id, 871 wlan_objmgr_ref_dbgid dbg_id) 872 { 873 struct wlan_objmgr_psoc_objmgr *objmgr; 874 struct wlan_objmgr_pdev *pdev = NULL; 875 876 /* If id is invalid, return */ 877 if (id >= WLAN_UMAC_MAX_PDEVS) 878 return NULL; 879 880 wlan_psoc_obj_lock(psoc); 881 objmgr = &psoc->soc_objmgr; 882 /* get pdev from pdev list */ 883 pdev = objmgr->wlan_pdev_list[id]; 884 /* Do not return object, if it is not CREATED state */ 885 if (pdev != NULL) 886 wlan_objmgr_pdev_get_ref(pdev, dbg_id); 887 888 wlan_psoc_obj_unlock(psoc); 889 890 return pdev; 891 } 892 QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc, 893 struct wlan_objmgr_vdev *vdev) 894 { 895 struct wlan_objmgr_psoc_objmgr *objmgr; 896 uint8_t id = 0; 897 uint8_t map_index = 0; 898 uint8_t map_entry_size = 32; 899 uint8_t adjust_ix = 0; 900 QDF_STATUS status; 901 902 wlan_psoc_obj_lock(psoc); 903 objmgr = &psoc->soc_objmgr; 904 /* Find first free vdev id */ 905 while ((id < objmgr->max_vdev_count) && 906 (objmgr->wlan_vdev_id_map[map_index] & (1<<(id - adjust_ix)))) { 907 id++; 908 /* 909 * The map is two DWORDS(32 bits), so, map_index 910 * adjust_ix derived based on the id value 911 */ 912 if (id == ((map_index + 1) * map_entry_size)) { 913 map_index++; 914 adjust_ix = map_index * map_entry_size; 915 } 916 } 917 /* If no free slot, return failure */ 918 if (id == objmgr->max_vdev_count) { 919 status = QDF_STATUS_E_FAILURE; 920 } else { 921 /* set free vdev id index */ 922 objmgr->wlan_vdev_id_map[map_index] |= (1<<(id-adjust_ix)); 923 /* store vdev pointer in vdev list */ 924 objmgr->wlan_vdev_list[id] = vdev; 925 /* increment vdev counter */ 926 objmgr->wlan_vdev_count++; 927 /* save vdev id */ 928 vdev->vdev_objmgr.vdev_id = id; 929 status = QDF_STATUS_SUCCESS; 930 } 931 wlan_psoc_obj_unlock(psoc); 932 933 return status; 934 } 935 936 QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc, 937 struct wlan_objmgr_vdev *vdev) 938 { 939 struct wlan_objmgr_psoc_objmgr *objmgr; 940 uint8_t id = 0; 941 uint8_t map_index = 0; 942 uint8_t map_entry_size = 32; 943 uint8_t adjust_ix = 0; 944 945 id = vdev->vdev_objmgr.vdev_id; 946 /* Invalid vdev id */ 947 if (id >= wlan_psoc_get_max_vdev_count(psoc)) 948 return QDF_STATUS_E_FAILURE; 949 /* 950 * Derive map_index and adjust_ix to find actual DWORD 951 * the id map is present 952 */ 953 while ((id - adjust_ix) >= map_entry_size) { 954 map_index++; 955 adjust_ix = map_index * map_entry_size; 956 } 957 wlan_psoc_obj_lock(psoc); 958 objmgr = &psoc->soc_objmgr; 959 /* unset bit, to free the slot */ 960 objmgr->wlan_vdev_id_map[map_index] &= ~(1<<(id-adjust_ix)); 961 /* reset VDEV pointer to NULL in VDEV list array */ 962 objmgr->wlan_vdev_list[id] = NULL; 963 /* decrement vdev count */ 964 objmgr->wlan_vdev_count--; 965 vdev->vdev_objmgr.vdev_id = 0xff; 966 wlan_psoc_obj_unlock(psoc); 967 968 return QDF_STATUS_SUCCESS; 969 } 970 971 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_opmode_from_psoc( 972 struct wlan_objmgr_psoc *psoc, 973 enum QDF_OPMODE opmode, 974 wlan_objmgr_ref_dbgid dbg_id) 975 { 976 struct wlan_objmgr_vdev *vdev = NULL; 977 int vdev_cnt = 0; 978 uint16_t max_vdev_cnt; 979 980 /* if PSOC is NULL, return */ 981 if (psoc == NULL) 982 return NULL; 983 984 wlan_psoc_obj_lock(psoc); 985 986 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 987 /* retrieve vdev pointer from vdev list */ 988 while (vdev_cnt < max_vdev_cnt) { 989 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_cnt]; 990 vdev_cnt++; 991 if (vdev == NULL) 992 continue; 993 wlan_vdev_obj_lock(vdev); 994 if (vdev->vdev_mlme.vdev_opmode == opmode) { 995 wlan_vdev_obj_unlock(vdev); 996 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != 997 QDF_STATUS_SUCCESS) { 998 vdev = NULL; 999 continue; 1000 } 1001 break; 1002 } 1003 wlan_vdev_obj_unlock(vdev); 1004 } 1005 wlan_psoc_obj_unlock(psoc); 1006 1007 return vdev; 1008 } 1009 1010 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc( 1011 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 1012 wlan_objmgr_ref_dbgid dbg_id) 1013 { 1014 struct wlan_objmgr_vdev *vdev; 1015 1016 /* if PSOC is NULL, return */ 1017 if (psoc == NULL) 1018 return NULL; 1019 /* vdev id is invalid */ 1020 if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) 1021 return NULL; 1022 1023 wlan_psoc_obj_lock(psoc); 1024 /* retrieve vdev pointer from vdev list */ 1025 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; 1026 if (vdev != NULL) { 1027 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != 1028 QDF_STATUS_SUCCESS) 1029 vdev = NULL; 1030 } 1031 wlan_psoc_obj_unlock(psoc); 1032 1033 return vdev; 1034 } 1035 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc); 1036 1037 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_id_from_psoc_no_state( 1038 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 1039 wlan_objmgr_ref_dbgid dbg_id) 1040 { 1041 struct wlan_objmgr_vdev *vdev; 1042 1043 /* if PSOC is NULL, return */ 1044 if (psoc == NULL) 1045 return NULL; 1046 /* vdev id is invalid */ 1047 if (vdev_id >= wlan_psoc_get_max_vdev_count(psoc)) 1048 return NULL; 1049 1050 wlan_psoc_obj_lock(psoc); 1051 /* retrieve vdev pointer from vdev list */ 1052 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; 1053 if (vdev != NULL) 1054 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 1055 1056 wlan_psoc_obj_unlock(psoc); 1057 1058 return vdev; 1059 } 1060 qdf_export_symbol(wlan_objmgr_get_vdev_by_id_from_psoc_no_state); 1061 1062 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc( 1063 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1064 wlan_objmgr_ref_dbgid dbg_id) 1065 { 1066 struct wlan_objmgr_vdev *vdev; 1067 uint8_t id; 1068 uint16_t max_vdev_cnt; 1069 1070 /* if PSOC is NULL, return */ 1071 if (psoc == NULL) 1072 return NULL; 1073 1074 wlan_psoc_obj_lock(psoc); 1075 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 1076 /* Iterate through PSOC's vdev list */ 1077 for (id = 0; id < max_vdev_cnt; id++) { 1078 vdev = psoc->soc_objmgr.wlan_vdev_list[id]; 1079 if (vdev == NULL) 1080 continue; 1081 /* MAC address matches, break */ 1082 if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr) 1083 == QDF_STATUS_SUCCESS) { 1084 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) != 1085 QDF_STATUS_SUCCESS) 1086 vdev = NULL; 1087 1088 wlan_psoc_obj_unlock(psoc); 1089 1090 return vdev; 1091 } 1092 } 1093 wlan_psoc_obj_unlock(psoc); 1094 1095 return NULL; 1096 } 1097 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc); 1098 1099 struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state( 1100 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1101 wlan_objmgr_ref_dbgid dbg_id) 1102 { 1103 struct wlan_objmgr_vdev *vdev; 1104 uint8_t id; 1105 uint16_t max_vdev_cnt; 1106 1107 /* if PSOC is NULL, return */ 1108 if (psoc == NULL) 1109 return NULL; 1110 1111 wlan_psoc_obj_lock(psoc); 1112 max_vdev_cnt = wlan_psoc_get_max_vdev_count(psoc); 1113 /* Iterate through PSOC's vdev list */ 1114 for (id = 0; id < max_vdev_cnt; id++) { 1115 vdev = psoc->soc_objmgr.wlan_vdev_list[id]; 1116 if (vdev == NULL) 1117 continue; 1118 /* MAC address matches, break */ 1119 if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr) 1120 == QDF_STATUS_SUCCESS) { 1121 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 1122 wlan_psoc_obj_unlock(psoc); 1123 1124 return vdev; 1125 } 1126 } 1127 wlan_psoc_obj_unlock(psoc); 1128 1129 return NULL; 1130 } 1131 qdf_export_symbol(wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state); 1132 1133 static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list, 1134 struct wlan_objmgr_peer *obj) 1135 { 1136 qdf_list_insert_back(obj_list, &obj->psoc_peer); 1137 } 1138 1139 static QDF_STATUS wlan_obj_psoc_peerlist_remove_peer( 1140 qdf_list_t *obj_list, 1141 struct wlan_objmgr_peer *peer) 1142 { 1143 qdf_list_node_t *psoc_node = NULL; 1144 1145 if (peer == NULL) 1146 return QDF_STATUS_E_FAILURE; 1147 /* get vdev list node element */ 1148 psoc_node = &peer->psoc_peer; 1149 /* list is empty, return failure */ 1150 if (qdf_list_remove_node(obj_list, psoc_node) != QDF_STATUS_SUCCESS) 1151 return QDF_STATUS_E_FAILURE; 1152 1153 return QDF_STATUS_SUCCESS; 1154 } 1155 1156 static QDF_STATUS wlan_peer_bssid_match(struct wlan_objmgr_peer *peer, 1157 uint8_t *bssid) 1158 { 1159 struct wlan_objmgr_vdev *vdev = wlan_peer_get_vdev(peer); 1160 uint8_t *peer_bssid = wlan_vdev_mlme_get_macaddr(vdev); 1161 1162 if (WLAN_ADDR_EQ(peer_bssid, bssid) == QDF_STATUS_SUCCESS) 1163 return QDF_STATUS_SUCCESS; 1164 else 1165 return QDF_STATUS_E_FAILURE; 1166 } 1167 1168 /** 1169 * wlan_obj_psoc_peerlist_get_peer_logically_deleted() - get peer 1170 * from psoc peer list 1171 * @psoc: PSOC object 1172 * @macaddr: MAC address 1173 * 1174 * API to finds peer object pointer of logically deleted peer 1175 * 1176 * Return: peer pointer 1177 * NULL on FAILURE 1178 */ 1179 static struct wlan_objmgr_peer * 1180 wlan_obj_psoc_peerlist_get_peer_logically_deleted( 1181 qdf_list_t *obj_list, uint8_t *macaddr, 1182 wlan_objmgr_ref_dbgid dbg_id) 1183 { 1184 struct wlan_objmgr_peer *peer; 1185 struct wlan_objmgr_peer *peer_temp; 1186 1187 /* Iterate through hash list to get the peer */ 1188 peer = wlan_psoc_peer_list_peek_head(obj_list); 1189 while (peer != NULL) { 1190 /* For peer, macaddr is key */ 1191 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1192 == QDF_STATUS_SUCCESS) { 1193 /* Return peer in logically deleted state */ 1194 if (peer->obj_state == 1195 WLAN_OBJ_STATE_LOGICALLY_DELETED) { 1196 wlan_objmgr_peer_get_ref(peer, dbg_id); 1197 1198 return peer; 1199 } 1200 1201 } 1202 /* Move to next peer */ 1203 peer_temp = peer; 1204 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1205 } 1206 1207 /* Not found, return NULL */ 1208 return NULL; 1209 } 1210 1211 /** 1212 * wlan_obj_psoc_peerlist_get_peer() - get peer from psoc peer list 1213 * @psoc: PSOC object 1214 * @macaddr: MAC address 1215 * 1216 * API to finds peer object pointer by MAC addr from hash list 1217 * 1218 * Return: peer pointer 1219 * NULL on FAILURE 1220 */ 1221 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer( 1222 qdf_list_t *obj_list, uint8_t *macaddr, 1223 wlan_objmgr_ref_dbgid dbg_id) 1224 { 1225 struct wlan_objmgr_peer *peer; 1226 struct wlan_objmgr_peer *peer_temp; 1227 1228 /* Iterate through hash list to get the peer */ 1229 peer = wlan_psoc_peer_list_peek_head(obj_list); 1230 while (peer != NULL) { 1231 /* For peer, macaddr is key */ 1232 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1233 == QDF_STATUS_SUCCESS) { 1234 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 1235 QDF_STATUS_SUCCESS) { 1236 return peer; 1237 } 1238 } 1239 /* Move to next peer */ 1240 peer_temp = peer; 1241 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1242 } 1243 1244 /* Not found, return NULL */ 1245 return NULL; 1246 } 1247 1248 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_no_state( 1249 qdf_list_t *obj_list, uint8_t *macaddr, 1250 wlan_objmgr_ref_dbgid dbg_id) 1251 { 1252 struct wlan_objmgr_peer *peer; 1253 struct wlan_objmgr_peer *peer_temp; 1254 1255 /* Iterate through hash list to get the peer */ 1256 peer = wlan_psoc_peer_list_peek_head(obj_list); 1257 while (peer != NULL) { 1258 /* For peer, macaddr is key */ 1259 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1260 == QDF_STATUS_SUCCESS) { 1261 wlan_objmgr_peer_get_ref(peer, dbg_id); 1262 1263 return peer; 1264 } 1265 /* Move to next peer */ 1266 peer_temp = peer; 1267 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1268 } 1269 1270 /* Not found, return NULL */ 1271 return NULL; 1272 } 1273 1274 /** 1275 * wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid() - get peer 1276 * from psoc peer list using 1277 * mac and vdev self mac 1278 * @obj_list: peer object list 1279 * @macaddr: MAC address 1280 * @bssid: BSSID address 1281 * @dbg_id: id of the caller 1282 * 1283 * API to finds peer object pointer by MAC addr and BSSID from 1284 * peer hash list for a node which is in logically deleted state, 1285 * bssid check is done on matching peer 1286 * 1287 * Caller to free the list allocated in this function 1288 * 1289 * Return: list of peer pointers 1290 * NULL on FAILURE 1291 */ 1292 static qdf_list_t 1293 *wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( 1294 qdf_list_t *obj_list, uint8_t *macaddr, 1295 uint8_t *bssid, 1296 wlan_objmgr_ref_dbgid dbg_id) 1297 { 1298 struct wlan_objmgr_peer *peer; 1299 struct wlan_objmgr_peer *peer_temp; 1300 struct wlan_logically_del_peer *peer_list = NULL; 1301 qdf_list_t *logical_del_peer_list = NULL; 1302 bool lock_released = false; 1303 1304 logical_del_peer_list = qdf_mem_malloc(sizeof(*logical_del_peer_list)); 1305 if (!logical_del_peer_list) { 1306 obj_mgr_err("failed to allocate list"); 1307 return NULL; 1308 } 1309 1310 qdf_list_create(logical_del_peer_list, WLAN_UMAC_PSOC_MAX_PEERS); 1311 1312 /* Iterate through hash list to get the peer */ 1313 peer = wlan_psoc_peer_list_peek_head(obj_list); 1314 while (peer != NULL) { 1315 wlan_peer_obj_lock(peer); 1316 /* For peer, macaddr is key */ 1317 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1318 == QDF_STATUS_SUCCESS) { 1319 /* 1320 * if BSSID not NULL, 1321 * then match is requested by caller, check BSSID 1322 * (vdev mac == bssid) -- return peer 1323 * (vdev mac != bssid) -- perform next iteration 1324 */ 1325 if ((bssid == NULL) || 1326 (wlan_peer_bssid_match(peer, bssid) == 1327 QDF_STATUS_SUCCESS)) { 1328 /* Return peer in logically deleted state */ 1329 if ((peer->obj_state == 1330 WLAN_OBJ_STATE_LOGICALLY_DELETED) && 1331 qdf_atomic_read( 1332 &peer->peer_objmgr.ref_cnt)) { 1333 1334 wlan_objmgr_peer_get_ref(peer, dbg_id); 1335 wlan_peer_obj_unlock(peer); 1336 lock_released = true; 1337 1338 peer_list = 1339 qdf_mem_malloc( 1340 sizeof(struct wlan_logically_del_peer)); 1341 if (peer_list == NULL) { 1342 /* Lock is already released */ 1343 obj_mgr_err("Mem alloc failed"); 1344 break; 1345 } 1346 1347 peer_list->peer = peer; 1348 1349 qdf_list_insert_front( 1350 logical_del_peer_list, 1351 &peer_list->list); 1352 } 1353 } 1354 } 1355 1356 if (!lock_released) 1357 wlan_peer_obj_unlock(peer); 1358 1359 /* Move to next peer */ 1360 peer_temp = peer; 1361 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1362 lock_released = false; 1363 } 1364 1365 /* Not found, return NULL */ 1366 if (qdf_list_empty(logical_del_peer_list)) { 1367 qdf_mem_free(logical_del_peer_list); 1368 return NULL; 1369 } else { 1370 return logical_del_peer_list; 1371 } 1372 1373 } 1374 1375 /** 1376 * wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid() - get peer from psoc peer 1377 * list using mac and vdev 1378 * self mac 1379 * @psoc: PSOC object 1380 * @macaddr: MAC address 1381 * @bssid: BSSID address 1382 * 1383 * API to finds peer object pointer by MAC addr and BSSID from 1384 * peer hash list, bssid check is done on matching peer 1385 * 1386 * Return: peer pointer 1387 * NULL on FAILURE 1388 */ 1389 static struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( 1390 qdf_list_t *obj_list, uint8_t *macaddr, 1391 uint8_t *bssid, 1392 wlan_objmgr_ref_dbgid dbg_id) 1393 { 1394 struct wlan_objmgr_peer *peer; 1395 struct wlan_objmgr_peer *peer_temp; 1396 1397 /* Iterate through hash list to get the peer */ 1398 peer = wlan_psoc_peer_list_peek_head(obj_list); 1399 while (peer != NULL) { 1400 /* For peer, macaddr is key */ 1401 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1402 == QDF_STATUS_SUCCESS) { 1403 /* 1404 * BSSID match is requested by caller, check BSSID 1405 * (vdev mac == bssid) -- return peer 1406 * (vdev mac != bssid) -- perform next iteration 1407 */ 1408 if (wlan_peer_bssid_match(peer, bssid) == 1409 QDF_STATUS_SUCCESS) { 1410 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) 1411 == QDF_STATUS_SUCCESS) { 1412 return peer; 1413 } 1414 } 1415 } 1416 /* Move to next peer */ 1417 peer_temp = peer; 1418 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1419 } 1420 /* Not found, return NULL */ 1421 return NULL; 1422 } 1423 1424 static struct wlan_objmgr_peer 1425 *wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( 1426 qdf_list_t *obj_list, uint8_t *macaddr, 1427 uint8_t *bssid, 1428 wlan_objmgr_ref_dbgid dbg_id) 1429 { 1430 struct wlan_objmgr_peer *peer; 1431 struct wlan_objmgr_peer *peer_temp; 1432 1433 /* Iterate through hash list to get the peer */ 1434 peer = wlan_psoc_peer_list_peek_head(obj_list); 1435 while (peer != NULL) { 1436 /* For peer, macaddr is key */ 1437 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr) 1438 == QDF_STATUS_SUCCESS) { 1439 /* 1440 * BSSID match is requested by caller, check BSSID 1441 * (vdev mac == bssid) -- return peer 1442 * (vdev mac != bssid) -- perform next iteration 1443 */ 1444 if (wlan_peer_bssid_match(peer, bssid) == 1445 QDF_STATUS_SUCCESS) { 1446 wlan_objmgr_peer_get_ref(peer, dbg_id); 1447 1448 return peer; 1449 } 1450 } 1451 /* Move to next peer */ 1452 peer_temp = peer; 1453 peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp); 1454 } 1455 1456 /* Not found, return NULL */ 1457 return NULL; 1458 } 1459 1460 QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc, 1461 struct wlan_objmgr_peer *peer) 1462 { 1463 struct wlan_objmgr_psoc_objmgr *objmgr; 1464 uint8_t hash_index; 1465 struct wlan_peer_list *peer_list; 1466 1467 wlan_psoc_obj_lock(psoc); 1468 objmgr = &psoc->soc_objmgr; 1469 /* Max peer limit is reached, return failure */ 1470 if (objmgr->wlan_peer_count >= wlan_psoc_get_max_peer_count(psoc)) { 1471 wlan_psoc_obj_unlock(psoc); 1472 return QDF_STATUS_E_FAILURE; 1473 } 1474 /* Derive hash index from mac address */ 1475 hash_index = WLAN_PEER_HASH(peer->macaddr); 1476 peer_list = &objmgr->peer_list; 1477 /* psoc lock should be taken before list lock */ 1478 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1479 /* add peer to hash peer list */ 1480 wlan_obj_psoc_peerlist_add_tail( 1481 &peer_list->peer_hash[hash_index], 1482 peer); 1483 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1484 /* Increment peer count */ 1485 objmgr->wlan_peer_count++; 1486 wlan_psoc_obj_unlock(psoc); 1487 1488 return QDF_STATUS_SUCCESS; 1489 } 1490 1491 QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc, 1492 struct wlan_objmgr_peer *peer) 1493 { 1494 struct wlan_objmgr_psoc_objmgr *objmgr; 1495 uint8_t hash_index; 1496 struct wlan_peer_list *peer_list; 1497 1498 wlan_psoc_obj_lock(psoc); 1499 objmgr = &psoc->soc_objmgr; 1500 /* if list is empty, return */ 1501 if (objmgr->wlan_peer_count == 0) { 1502 wlan_psoc_obj_unlock(psoc); 1503 return QDF_STATUS_E_FAILURE; 1504 } 1505 /* Get hash index, to locate the actual peer list */ 1506 hash_index = WLAN_PEER_HASH(peer->macaddr); 1507 peer_list = &objmgr->peer_list; 1508 /* psoc lock should be taken before list lock */ 1509 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1510 /* removes the peer from peer_list */ 1511 if (wlan_obj_psoc_peerlist_remove_peer( 1512 &peer_list->peer_hash[hash_index], 1513 peer) == 1514 QDF_STATUS_E_FAILURE) { 1515 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1516 wlan_psoc_obj_unlock(psoc); 1517 obj_mgr_err("Failed to detach peer"); 1518 return QDF_STATUS_E_FAILURE; 1519 } 1520 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1521 /* Decrement peer count */ 1522 objmgr->wlan_peer_count--; 1523 wlan_psoc_obj_unlock(psoc); 1524 1525 return QDF_STATUS_SUCCESS; 1526 } 1527 1528 struct wlan_objmgr_peer *wlan_objmgr_get_peer_logically_deleted( 1529 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1530 wlan_objmgr_ref_dbgid dbg_id) 1531 { 1532 struct wlan_objmgr_psoc_objmgr *objmgr; 1533 uint8_t hash_index; 1534 struct wlan_objmgr_peer *peer = NULL; 1535 struct wlan_peer_list *peer_list; 1536 1537 /* psoc lock should be taken before peer list lock */ 1538 wlan_psoc_obj_lock(psoc); 1539 objmgr = &psoc->soc_objmgr; 1540 /* List is empty, return NULL */ 1541 if (objmgr->wlan_peer_count == 0) { 1542 wlan_psoc_obj_unlock(psoc); 1543 return NULL; 1544 } 1545 /* reduce the search window, with hash key */ 1546 hash_index = WLAN_PEER_HASH(macaddr); 1547 peer_list = &objmgr->peer_list; 1548 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1549 /* Iterate through peer list, get peer */ 1550 peer = wlan_obj_psoc_peerlist_get_peer_logically_deleted( 1551 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 1552 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1553 wlan_psoc_obj_unlock(psoc); 1554 1555 return peer; 1556 } 1557 1558 struct wlan_objmgr_peer *wlan_objmgr_get_peer( 1559 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1560 wlan_objmgr_ref_dbgid dbg_id) 1561 { 1562 struct wlan_objmgr_psoc_objmgr *objmgr; 1563 uint8_t hash_index; 1564 struct wlan_objmgr_peer *peer = NULL; 1565 struct wlan_peer_list *peer_list; 1566 1567 /* psoc lock should be taken before peer list lock */ 1568 wlan_psoc_obj_lock(psoc); 1569 objmgr = &psoc->soc_objmgr; 1570 /* List is empty, return NULL */ 1571 if (objmgr->wlan_peer_count == 0) { 1572 wlan_psoc_obj_unlock(psoc); 1573 return NULL; 1574 } 1575 /* reduce the search window, with hash key */ 1576 hash_index = WLAN_PEER_HASH(macaddr); 1577 peer_list = &objmgr->peer_list; 1578 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1579 /* Iterate through peer list, get peer */ 1580 peer = wlan_obj_psoc_peerlist_get_peer( 1581 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 1582 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1583 wlan_psoc_obj_unlock(psoc); 1584 1585 return peer; 1586 } 1587 qdf_export_symbol(wlan_objmgr_get_peer); 1588 1589 struct wlan_objmgr_peer *wlan_objmgr_get_peer_nolock( 1590 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1591 wlan_objmgr_ref_dbgid dbg_id) 1592 { 1593 struct wlan_objmgr_psoc_objmgr *objmgr; 1594 uint8_t hash_index; 1595 struct wlan_objmgr_peer *peer = NULL; 1596 struct wlan_peer_list *peer_list; 1597 1598 /* psoc lock should be taken before peer list lock */ 1599 objmgr = &psoc->soc_objmgr; 1600 /* List is empty, return NULL */ 1601 if (objmgr->wlan_peer_count == 0) 1602 return NULL; 1603 1604 /* reduce the search window, with hash key */ 1605 hash_index = WLAN_PEER_HASH(macaddr); 1606 peer_list = &objmgr->peer_list; 1607 /* Iterate through peer list, get peer */ 1608 peer = wlan_obj_psoc_peerlist_get_peer( 1609 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 1610 1611 return peer; 1612 } 1613 qdf_export_symbol(wlan_objmgr_get_peer_nolock); 1614 1615 1616 struct wlan_objmgr_peer *wlan_objmgr_get_peer_no_state( 1617 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1618 wlan_objmgr_ref_dbgid dbg_id) 1619 { 1620 struct wlan_objmgr_psoc_objmgr *objmgr; 1621 uint8_t hash_index; 1622 struct wlan_objmgr_peer *peer = NULL; 1623 struct wlan_peer_list *peer_list; 1624 1625 /* psoc lock should be taken before peer list lock */ 1626 wlan_psoc_obj_lock(psoc); 1627 objmgr = &psoc->soc_objmgr; 1628 /* List is empty, return NULL */ 1629 if (objmgr->wlan_peer_count == 0) { 1630 wlan_psoc_obj_unlock(psoc); 1631 return NULL; 1632 } 1633 /* reduce the search window, with hash key */ 1634 hash_index = WLAN_PEER_HASH(macaddr); 1635 peer_list = &objmgr->peer_list; 1636 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1637 /* Iterate through peer list, get peer */ 1638 peer = wlan_obj_psoc_peerlist_get_peer_no_state( 1639 &peer_list->peer_hash[hash_index], macaddr, dbg_id); 1640 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1641 wlan_psoc_obj_unlock(psoc); 1642 1643 return peer; 1644 } 1645 qdf_export_symbol(wlan_objmgr_get_peer_no_state); 1646 1647 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev( 1648 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1649 uint8_t *bssid, wlan_objmgr_ref_dbgid dbg_id) 1650 { 1651 struct wlan_objmgr_psoc_objmgr *objmgr; 1652 uint8_t hash_index; 1653 struct wlan_objmgr_peer *peer = NULL; 1654 struct wlan_peer_list *peer_list; 1655 1656 /* psoc lock should be taken before peer list lock */ 1657 wlan_psoc_obj_lock(psoc); 1658 objmgr = &psoc->soc_objmgr; 1659 /* List is empty, return NULL */ 1660 if (objmgr->wlan_peer_count == 0) { 1661 wlan_psoc_obj_unlock(psoc); 1662 return NULL; 1663 } 1664 /* reduce the search window, with hash key */ 1665 hash_index = WLAN_PEER_HASH(macaddr); 1666 peer_list = &objmgr->peer_list; 1667 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1668 /* Iterate through peer list, get peer */ 1669 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid( 1670 &peer_list->peer_hash[hash_index], macaddr, bssid, dbg_id); 1671 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1672 wlan_psoc_obj_unlock(psoc); 1673 1674 return peer; 1675 } 1676 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev); 1677 1678 1679 /** 1680 * wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev() - get peer from psoc 1681 * peer list using 1682 * mac and vdev 1683 * self mac 1684 * @psoc: PSOC object 1685 * @macaddr: MAC address 1686 * @bssid: BSSID address. NULL mac means search all. 1687 * @dbg_id: id of the caller 1688 * 1689 * API to finds peer object pointer by MAC addr and BSSID from 1690 * peer hash list, bssid check is done on matching peer 1691 * 1692 * Return: list of peer pointer pointers 1693 * NULL on FAILURE 1694 */ 1695 1696 qdf_list_t *wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev( 1697 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1698 uint8_t *bssid, wlan_objmgr_ref_dbgid dbg_id) 1699 { 1700 struct wlan_objmgr_psoc_objmgr *objmgr; 1701 uint8_t hash_index; 1702 struct wlan_peer_list *peer_list = NULL; 1703 qdf_list_t *logical_del_peer_list = NULL; 1704 1705 /* psoc lock should be taken before peer list lock */ 1706 wlan_psoc_obj_lock(psoc); 1707 objmgr = &psoc->soc_objmgr; 1708 /* List is empty, return NULL */ 1709 if (objmgr->wlan_peer_count == 0) { 1710 wlan_psoc_obj_unlock(psoc); 1711 return NULL; 1712 } 1713 /* reduce the search window, with hash key */ 1714 hash_index = WLAN_PEER_HASH(macaddr); 1715 peer_list = &objmgr->peer_list; 1716 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1717 1718 /* Iterate through peer list, get peer */ 1719 logical_del_peer_list = 1720 wlan_obj_psoc_populate_logically_del_peerlist_by_mac_n_bssid( 1721 &peer_list->peer_hash[hash_index], macaddr, 1722 bssid, dbg_id); 1723 1724 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1725 wlan_psoc_obj_unlock(psoc); 1726 1727 return logical_del_peer_list; 1728 } 1729 qdf_export_symbol(wlan_objmgr_populate_logically_deleted_peerlist_by_mac_n_vdev); 1730 1731 struct wlan_objmgr_peer *wlan_objmgr_get_peer_by_mac_n_vdev_no_state( 1732 struct wlan_objmgr_psoc *psoc, uint8_t *macaddr, 1733 uint8_t *bssid, wlan_objmgr_ref_dbgid dbg_id) 1734 { 1735 struct wlan_objmgr_psoc_objmgr *objmgr; 1736 uint8_t hash_index; 1737 struct wlan_objmgr_peer *peer = NULL; 1738 struct wlan_peer_list *peer_list; 1739 1740 /* psoc lock should be taken before peer list lock */ 1741 wlan_psoc_obj_lock(psoc); 1742 objmgr = &psoc->soc_objmgr; 1743 /* List is empty, return NULL */ 1744 if (objmgr->wlan_peer_count == 0) { 1745 wlan_psoc_obj_unlock(psoc); 1746 return NULL; 1747 } 1748 /* reduce the search window, with hash key */ 1749 hash_index = WLAN_PEER_HASH(macaddr); 1750 peer_list = &objmgr->peer_list; 1751 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1752 /* Iterate through peer list, get peer */ 1753 peer = wlan_obj_psoc_peerlist_get_peer_by_mac_n_bssid_no_state( 1754 &peer_list->peer_hash[hash_index], macaddr, bssid, dbg_id); 1755 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1756 wlan_psoc_obj_unlock(psoc); 1757 1758 return peer; 1759 } 1760 qdf_export_symbol(wlan_objmgr_get_peer_by_mac_n_vdev_no_state); 1761 1762 void *wlan_objmgr_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc, 1763 enum wlan_umac_comp_id id) 1764 { 1765 void *comp_private_obj; 1766 1767 /* component id is invalid */ 1768 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 1769 QDF_BUG(0); 1770 return NULL; 1771 } 1772 1773 if (psoc == NULL) { 1774 QDF_BUG(0); 1775 return NULL; 1776 } 1777 1778 comp_private_obj = psoc->soc_comp_priv_obj[id]; 1779 1780 return comp_private_obj; 1781 } 1782 qdf_export_symbol(wlan_objmgr_psoc_get_comp_private_obj); 1783 1784 void wlan_objmgr_psoc_get_ref(struct wlan_objmgr_psoc *psoc, 1785 wlan_objmgr_ref_dbgid id) 1786 { 1787 if (psoc == NULL) { 1788 obj_mgr_err("psoc obj is NULL for id:%d", id); 1789 QDF_ASSERT(0); 1790 return; 1791 } 1792 /* Increment ref count */ 1793 qdf_atomic_inc(&psoc->soc_objmgr.ref_cnt); 1794 qdf_atomic_inc(&psoc->soc_objmgr.ref_id_dbg[id]); 1795 return; 1796 } 1797 qdf_export_symbol(wlan_objmgr_psoc_get_ref); 1798 1799 QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc, 1800 wlan_objmgr_ref_dbgid id) 1801 { 1802 if (psoc == NULL) { 1803 obj_mgr_err("psoc obj is NULL for id:%d", id); 1804 QDF_ASSERT(0); 1805 return QDF_STATUS_E_FAILURE; 1806 } 1807 1808 wlan_psoc_obj_lock(psoc); 1809 if (psoc->obj_state != WLAN_OBJ_STATE_CREATED) { 1810 wlan_psoc_obj_unlock(psoc); 1811 if (psoc->soc_objmgr.print_cnt++ <= 1812 WLAN_OBJMGR_RATELIMIT_THRESH) 1813 obj_mgr_err( 1814 "[Ref id: %d] psoc is not in Created state(%d)", 1815 id, psoc->obj_state); 1816 1817 return QDF_STATUS_E_RESOURCES; 1818 } 1819 1820 /* Increment ref count */ 1821 wlan_objmgr_psoc_get_ref(psoc, id); 1822 wlan_psoc_obj_unlock(psoc); 1823 1824 return QDF_STATUS_SUCCESS; 1825 } 1826 qdf_export_symbol(wlan_objmgr_psoc_try_get_ref); 1827 1828 void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc, 1829 wlan_objmgr_ref_dbgid id) 1830 { 1831 if (psoc == NULL) { 1832 obj_mgr_err("psoc obj is NULL for id:%d", id); 1833 QDF_ASSERT(0); 1834 return; 1835 } 1836 1837 if (!qdf_atomic_read(&psoc->soc_objmgr.ref_id_dbg[id])) { 1838 obj_mgr_err("psoc ref cnt was not taken by %d", id); 1839 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg); 1840 WLAN_OBJMGR_BUG(0); 1841 } 1842 1843 if (!qdf_atomic_read(&psoc->soc_objmgr.ref_cnt)) { 1844 obj_mgr_err("psoc ref cnt is 0"); 1845 WLAN_OBJMGR_BUG(0); 1846 return; 1847 } 1848 1849 qdf_atomic_dec(&psoc->soc_objmgr.ref_id_dbg[id]); 1850 /* Decrement ref count, free psoc, if ref count == 0 */ 1851 if (qdf_atomic_dec_and_test(&psoc->soc_objmgr.ref_cnt)) 1852 wlan_objmgr_psoc_obj_destroy(psoc); 1853 1854 return; 1855 } 1856 qdf_export_symbol(wlan_objmgr_psoc_release_ref); 1857 1858 static void wlan_objmgr_psoc_peer_ref_print(struct wlan_objmgr_psoc *psoc, 1859 void *obj, void *args) 1860 { 1861 struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj; 1862 WLAN_OBJ_STATE obj_state; 1863 uint8_t vdev_id; 1864 uint8_t *macaddr; 1865 1866 wlan_peer_obj_lock(peer); 1867 macaddr = wlan_peer_get_macaddr(peer); 1868 obj_state = peer->obj_state; 1869 vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); 1870 wlan_peer_obj_unlock(peer); 1871 1872 obj_mgr_alert("Peer MAC:%02x:%02x:%02x:%02x:%02x:%02x state:%d vdev_id:%d", 1873 macaddr[0], macaddr[1], macaddr[2], macaddr[3], 1874 macaddr[4], macaddr[5], obj_state, vdev_id); 1875 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg); 1876 } 1877 1878 static void wlan_objmgr_psoc_vdev_ref_print(struct wlan_objmgr_psoc *psoc, 1879 void *obj, void *args) 1880 { 1881 struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj; 1882 WLAN_OBJ_STATE obj_state; 1883 uint8_t id; 1884 1885 wlan_vdev_obj_lock(vdev); 1886 id = wlan_vdev_get_id(vdev); 1887 obj_state = vdev->obj_state; 1888 wlan_vdev_obj_unlock(vdev); 1889 obj_mgr_alert("Vdev ID is %d, state %d", id, obj_state); 1890 1891 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg); 1892 } 1893 1894 static void wlan_objmgr_psoc_pdev_ref_print(struct wlan_objmgr_psoc *psoc, 1895 void *obj, void *args) 1896 { 1897 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj; 1898 uint8_t id; 1899 1900 wlan_pdev_obj_lock(pdev); 1901 id = wlan_objmgr_pdev_get_pdev_id(pdev); 1902 wlan_pdev_obj_unlock(pdev); 1903 obj_mgr_alert("pdev ID is %d", id); 1904 1905 wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg); 1906 } 1907 1908 QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc( 1909 struct wlan_objmgr_psoc *psoc) 1910 { 1911 obj_mgr_alert("Ref counts of PEER"); 1912 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PEER_OP, 1913 wlan_objmgr_psoc_peer_ref_print, NULL); 1914 obj_mgr_alert("Ref counts of VDEV"); 1915 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_VDEV_OP, 1916 wlan_objmgr_psoc_vdev_ref_print, NULL); 1917 obj_mgr_alert("Ref counts of PDEV"); 1918 wlan_objmgr_iterate_obj_list_all_noref(psoc, WLAN_PDEV_OP, 1919 wlan_objmgr_psoc_pdev_ref_print, NULL); 1920 1921 obj_mgr_alert(" Ref counts of PSOC"); 1922 wlan_objmgr_print_ref_ids(psoc->soc_objmgr.ref_id_dbg); 1923 1924 return QDF_STATUS_SUCCESS; 1925 } 1926 qdf_export_symbol(wlan_objmgr_print_ref_all_objects_per_psoc); 1927 1928 QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc, 1929 struct wlan_objmgr_psoc_user_config *user_config_data) 1930 { 1931 if (user_config_data == NULL) { 1932 obj_mgr_err("user_config_data is NULL"); 1933 QDF_BUG(0); 1934 return QDF_STATUS_E_FAILURE; 1935 } 1936 wlan_psoc_obj_lock(psoc); 1937 qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data, 1938 sizeof(psoc->soc_nif.user_config)); 1939 wlan_psoc_obj_unlock(psoc); 1940 1941 return QDF_STATUS_SUCCESS; 1942 } 1943