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