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