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