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