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