1 /* 2 * Copyright (c) 2016-2020 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 Peer object 20 */ 21 #include <wlan_objmgr_cmn.h> 22 #include <wlan_objmgr_global_obj.h> 23 #include <wlan_objmgr_psoc_obj.h> 24 #include <wlan_objmgr_pdev_obj.h> 25 #include <wlan_objmgr_vdev_obj.h> 26 #include <wlan_objmgr_peer_obj.h> 27 #include <wlan_objmgr_debug.h> 28 #include <qdf_mem.h> 29 #include <qdf_module.h> 30 #include "wlan_objmgr_global_obj_i.h" 31 #include "wlan_objmgr_psoc_obj_i.h" 32 #include "wlan_objmgr_pdev_obj_i.h" 33 #include "wlan_objmgr_vdev_obj_i.h" 34 35 36 /** 37 ** APIs to Create/Delete Peer object APIs 38 */ 39 static QDF_STATUS wlan_objmgr_peer_object_status( 40 struct wlan_objmgr_peer *peer) 41 { 42 uint8_t id; 43 QDF_STATUS status = QDF_STATUS_SUCCESS; 44 45 wlan_peer_obj_lock(peer); 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 (peer->obj_status[id] == QDF_STATUS_COMP_DISABLED) 50 continue; 51 /* If component operates in Async, status is Partially created, 52 break */ 53 else if (peer->obj_status[id] == QDF_STATUS_COMP_ASYNC) { 54 if (!peer->peer_comp_priv_obj[id]) { 55 status = QDF_STATUS_COMP_ASYNC; 56 break; 57 } 58 /* If component failed to allocate its object, treat it as 59 failure, complete object need to be cleaned up */ 60 } else if ((peer->obj_status[id] == QDF_STATUS_E_NOMEM) || 61 (peer->obj_status[id] == QDF_STATUS_E_FAILURE)) { 62 obj_mgr_err("Peer comp object(id:%d) alloc fail", id); 63 status = QDF_STATUS_E_FAILURE; 64 break; 65 } 66 } 67 wlan_peer_obj_unlock(peer); 68 return status; 69 } 70 71 static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer) 72 { 73 struct wlan_objmgr_psoc *psoc; 74 struct wlan_objmgr_vdev *vdev; 75 uint8_t *macaddr; 76 uint8_t vdev_id; 77 bool peer_free_notify = true; 78 79 if (!peer) { 80 obj_mgr_err("PEER is NULL"); 81 return QDF_STATUS_E_FAILURE; 82 } 83 84 macaddr = wlan_peer_get_macaddr(peer); 85 86 vdev = wlan_peer_get_vdev(peer); 87 if (!vdev) { 88 obj_mgr_err( 89 "VDEV is NULL for peer("QDF_MAC_ADDR_FMT")", 90 QDF_MAC_ADDR_REF(macaddr)); 91 return QDF_STATUS_E_FAILURE; 92 } 93 94 /* Notify peer free only for non self peer*/ 95 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), 96 wlan_vdev_mlme_get_macaddr(vdev)) == 97 QDF_STATUS_SUCCESS) 98 peer_free_notify = false; 99 100 vdev_id = wlan_vdev_get_id(vdev); 101 102 /* get PSOC from VDEV, if it is NULL, return */ 103 psoc = wlan_vdev_get_psoc(vdev); 104 if (!psoc) { 105 obj_mgr_err( 106 "PSOC is NULL for peer("QDF_MAC_ADDR_FMT")", 107 QDF_MAC_ADDR_REF(macaddr)); 108 return QDF_STATUS_E_FAILURE; 109 } 110 111 /* Decrement ref count for BSS peer, so that BSS peer deletes last*/ 112 if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) || 113 (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP) || 114 (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_CLI)) 115 wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev), 116 WLAN_OBJMGR_ID); 117 118 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); 119 120 /* Detach peer from VDEV's peer list */ 121 if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) { 122 obj_mgr_err( 123 "Peer("QDF_MAC_ADDR_FMT") VDEV detach fail, vdev id: %d", 124 QDF_MAC_ADDR_REF(macaddr), vdev_id); 125 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 126 return QDF_STATUS_E_FAILURE; 127 } 128 /* Detach peer from PSOC's peer list */ 129 if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) { 130 obj_mgr_err( 131 "Peer("QDF_MAC_ADDR_FMT") PSOC detach failure", 132 QDF_MAC_ADDR_REF(macaddr)); 133 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 134 return QDF_STATUS_E_FAILURE; 135 } 136 wlan_objmgr_peer_trace_del_ref_list(peer); 137 wlan_objmgr_peer_trace_deinit_lock(peer); 138 qdf_spinlock_destroy(&peer->peer_lock); 139 qdf_mem_free(peer); 140 141 if (peer_free_notify) 142 wlan_objmgr_vdev_peer_freed_notify(vdev); 143 144 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 145 146 return QDF_STATUS_SUCCESS; 147 148 } 149 150 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 151 static void 152 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) 153 { 154 uint8_t id; 155 156 for (id = 0; id < WLAN_REF_ID_MAX; id++) 157 qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]); 158 } 159 #else 160 static inline void 161 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) {} 162 #endif 163 164 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( 165 struct wlan_objmgr_vdev *vdev, 166 enum wlan_peer_type type, 167 uint8_t *macaddr) 168 { 169 struct wlan_objmgr_peer *peer; 170 struct wlan_objmgr_psoc *psoc; 171 wlan_objmgr_peer_create_handler handler; 172 wlan_objmgr_peer_status_handler stat_handler; 173 void *arg; 174 QDF_STATUS obj_status; 175 uint8_t id; 176 177 if (!vdev) { 178 obj_mgr_err( 179 "VDEV is NULL for peer ("QDF_MAC_ADDR_FMT")", 180 QDF_MAC_ADDR_REF(macaddr)); 181 return NULL; 182 } 183 /* Get psoc, if psoc is NULL, return */ 184 psoc = wlan_vdev_get_psoc(vdev); 185 if (!psoc) { 186 obj_mgr_err( 187 "PSOC is NULL for peer ("QDF_MAC_ADDR_FMT")", 188 QDF_MAC_ADDR_REF(macaddr)); 189 return NULL; 190 } 191 /* Allocate memory for peer object */ 192 peer = qdf_mem_malloc(sizeof(*peer)); 193 if (!peer) 194 return NULL; 195 196 peer->obj_state = WLAN_OBJ_STATE_ALLOCATED; 197 qdf_atomic_init(&peer->peer_objmgr.ref_cnt); 198 wlan_objmgr_peer_init_ref_id_debug(peer); 199 wlan_objmgr_peer_trace_init_lock(peer); 200 wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID); 201 /* set vdev to peer */ 202 wlan_peer_set_vdev(peer, vdev); 203 /* set peer type */ 204 wlan_peer_set_peer_type(peer, type); 205 /* set mac address of peer */ 206 wlan_peer_set_macaddr(peer, macaddr); 207 /* initialize peer state */ 208 wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE); 209 wlan_peer_mlme_reset_seq_num(peer); 210 peer->peer_objmgr.print_cnt = 0; 211 212 qdf_spinlock_create(&peer->peer_lock); 213 /* Attach peer to psoc, psoc maintains the node table for the device */ 214 if (wlan_objmgr_psoc_peer_attach(psoc, peer) != 215 QDF_STATUS_SUCCESS) { 216 obj_mgr_warn( 217 "Peer("QDF_MAC_ADDR_FMT") PSOC attach failure", 218 QDF_MAC_ADDR_REF(macaddr)); 219 qdf_spinlock_destroy(&peer->peer_lock); 220 wlan_objmgr_peer_trace_deinit_lock(peer); 221 qdf_mem_free(peer); 222 return NULL; 223 } 224 /* Attach peer to vdev peer table */ 225 if (wlan_objmgr_vdev_peer_attach(vdev, peer) != 226 QDF_STATUS_SUCCESS) { 227 obj_mgr_warn( 228 "Peer("QDF_MAC_ADDR_FMT") VDEV attach failure", 229 QDF_MAC_ADDR_REF(macaddr)); 230 /* if attach fails, detach from psoc table before free */ 231 wlan_objmgr_psoc_peer_detach(psoc, peer); 232 qdf_spinlock_destroy(&peer->peer_lock); 233 wlan_objmgr_peer_trace_deinit_lock(peer); 234 qdf_mem_free(peer); 235 return NULL; 236 } 237 wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id( 238 wlan_vdev_get_pdev(vdev))); 239 /* Increment ref count for BSS peer, so that BSS peer deletes last*/ 240 if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP) 241 || (type == WLAN_PEER_P2P_CLI)) 242 wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev), 243 WLAN_OBJMGR_ID); 244 /* TODO init other parameters */ 245 /* Invoke registered create handlers */ 246 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 247 handler = g_umac_glb_obj->peer_create_handler[id]; 248 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 249 if (handler) 250 peer->obj_status[id] = handler(peer, arg); 251 else 252 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 253 } 254 /* derive the object status */ 255 obj_status = wlan_objmgr_peer_object_status(peer); 256 /* If SUCCESS, Object is created */ 257 if (obj_status == QDF_STATUS_SUCCESS) { 258 peer->obj_state = WLAN_OBJ_STATE_CREATED; 259 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 260 stat_handler = g_umac_glb_obj->peer_status_handler[id]; 261 arg = g_umac_glb_obj->peer_status_handler_arg[id]; 262 if (stat_handler) 263 stat_handler(peer, arg, 264 QDF_STATUS_SUCCESS); 265 } 266 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 267 /* If any component operates in different context, update it 268 as partially created */ 269 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 270 } else if (obj_status == QDF_STATUS_E_FAILURE) { 271 /* Clean up the peer */ 272 obj_mgr_err( 273 "Peer("QDF_MAC_ADDR_FMT") comp object alloc fail", 274 QDF_MAC_ADDR_REF(macaddr)); 275 wlan_objmgr_peer_obj_delete(peer); 276 return NULL; 277 } 278 279 obj_mgr_debug("Created peer " QDF_MAC_ADDR_FMT " type %d", 280 QDF_MAC_ADDR_REF(macaddr), type); 281 282 return peer; 283 } 284 285 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer) 286 { 287 uint8_t id; 288 wlan_objmgr_peer_destroy_handler handler; 289 QDF_STATUS obj_status; 290 void *arg; 291 uint8_t *macaddr; 292 293 if (!peer) { 294 obj_mgr_err("PEER is NULL"); 295 return QDF_STATUS_E_FAILURE; 296 } 297 wlan_objmgr_notify_destroy(peer, WLAN_PEER_OP); 298 299 macaddr = wlan_peer_get_macaddr(peer); 300 301 obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_FMT, 302 QDF_MAC_ADDR_REF(macaddr)); 303 304 if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { 305 obj_mgr_err("PEER object del is not invoked obj_state:%d peer " 306 QDF_MAC_ADDR_FMT, peer->obj_state, 307 QDF_MAC_ADDR_REF(macaddr)); 308 WLAN_OBJMGR_BUG(0); 309 } 310 311 /* Invoke registered destroy handlers */ 312 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 313 handler = g_umac_glb_obj->peer_destroy_handler[id]; 314 arg = g_umac_glb_obj->peer_destroy_handler_arg[id]; 315 if (handler && 316 (peer->obj_status[id] == QDF_STATUS_SUCCESS || 317 peer->obj_status[id] == QDF_STATUS_COMP_ASYNC)) 318 peer->obj_status[id] = handler(peer, arg); 319 else 320 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 321 } 322 /* Derive the object status */ 323 obj_status = wlan_objmgr_peer_object_status(peer); 324 if (obj_status == QDF_STATUS_E_FAILURE) { 325 /* If it status is failure, memory will not be freed */ 326 QDF_BUG(0); 327 return QDF_STATUS_E_FAILURE; 328 } 329 /* few components deletion is in progress */ 330 if (obj_status == QDF_STATUS_COMP_ASYNC) { 331 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED; 332 return QDF_STATUS_COMP_ASYNC; 333 } 334 335 /* Free the peer object */ 336 return wlan_objmgr_peer_obj_free(peer); 337 } 338 339 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer) 340 { 341 uint8_t print_idx; 342 uint8_t *macaddr; 343 344 if (!peer) { 345 obj_mgr_err("PEER is NULL"); 346 return QDF_STATUS_E_FAILURE; 347 } 348 349 wlan_peer_obj_lock(peer); 350 macaddr = wlan_peer_get_macaddr(peer); 351 wlan_peer_obj_unlock(peer); 352 353 obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_FMT, 354 QDF_MAC_ADDR_REF(macaddr)); 355 356 print_idx = qdf_get_pidx(); 357 wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_DEBUG); 358 /** 359 * Update VDEV object state to LOGICALLY DELETED 360 * It prevents further access of this object 361 */ 362 wlan_peer_obj_lock(peer); 363 peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED; 364 wlan_peer_obj_unlock(peer); 365 wlan_objmgr_notify_log_delete(peer, WLAN_PEER_OP); 366 wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID); 367 368 return QDF_STATUS_SUCCESS; 369 } 370 qdf_export_symbol(wlan_objmgr_peer_obj_delete); 371 /** 372 ** APIs to attach/detach component objects 373 */ 374 QDF_STATUS wlan_objmgr_peer_component_obj_attach( 375 struct wlan_objmgr_peer *peer, 376 enum wlan_umac_comp_id id, 377 void *comp_priv_obj, 378 QDF_STATUS status) 379 { 380 wlan_objmgr_peer_status_handler s_hler; 381 void *arg; 382 uint8_t i; 383 QDF_STATUS obj_status; 384 385 /* component id is invalid */ 386 if (id >= WLAN_UMAC_MAX_COMPONENTS) 387 return QDF_STATUS_MAXCOMP_FAIL; 388 389 wlan_peer_obj_lock(peer); 390 /* If there is a valid entry, return failure, 391 valid object needs to be freed first */ 392 if (peer->peer_comp_priv_obj[id]) { 393 wlan_peer_obj_unlock(peer); 394 return QDF_STATUS_E_FAILURE; 395 } 396 /* Assign component object private pointer(can be NULL also), status */ 397 peer->peer_comp_priv_obj[id] = comp_priv_obj; 398 peer->obj_status[id] = status; 399 wlan_peer_obj_unlock(peer); 400 401 if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED) 402 return QDF_STATUS_SUCCESS; 403 404 /* If PEER object status is partially created means, this API is 405 invoked with differnt context. this block should be executed for async 406 components only */ 407 /* Derive status */ 408 obj_status = wlan_objmgr_peer_object_status(peer); 409 /* STATUS_SUCCESS means, object is CREATED */ 410 if (obj_status == QDF_STATUS_SUCCESS) 411 peer->obj_state = WLAN_OBJ_STATE_CREATED; 412 /* update state as CREATION failed, caller has to delete the 413 PEER object */ 414 else if (obj_status == QDF_STATUS_E_FAILURE) 415 peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED; 416 /* Notify components about the CREATION success/failure */ 417 if ((obj_status == QDF_STATUS_SUCCESS) || 418 (obj_status == QDF_STATUS_E_FAILURE)) { 419 /* nofity object status */ 420 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 421 s_hler = g_umac_glb_obj->peer_status_handler[i]; 422 arg = g_umac_glb_obj->peer_status_handler_arg[i]; 423 if (s_hler) 424 s_hler(peer, arg, obj_status); 425 } 426 } 427 return QDF_STATUS_SUCCESS; 428 } 429 430 QDF_STATUS wlan_objmgr_peer_component_obj_detach( 431 struct wlan_objmgr_peer *peer, 432 enum wlan_umac_comp_id id, 433 void *comp_priv_obj) 434 { 435 QDF_STATUS obj_status; 436 437 /* component id is invalid */ 438 if (id >= WLAN_UMAC_MAX_COMPONENTS) 439 return QDF_STATUS_MAXCOMP_FAIL; 440 441 wlan_peer_obj_lock(peer); 442 /* If there is a invalid entry, return failure */ 443 if (peer->peer_comp_priv_obj[id] != comp_priv_obj) { 444 peer->obj_status[id] = QDF_STATUS_E_FAILURE; 445 wlan_peer_obj_unlock(peer); 446 return QDF_STATUS_E_FAILURE; 447 } 448 /* Reset the pointer to NULL */ 449 peer->peer_comp_priv_obj[id] = NULL; 450 peer->obj_status[id] = QDF_STATUS_SUCCESS; 451 wlan_peer_obj_unlock(peer); 452 453 /* If PEER object status is partially destroyed means, this API is 454 invoked with differnt context, this block should be executed for async 455 components only */ 456 if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) || 457 (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) { 458 /* Derive object status */ 459 obj_status = wlan_objmgr_peer_object_status(peer); 460 if (obj_status == QDF_STATUS_SUCCESS) { 461 /*Update the status as Deleted, if full object 462 deletion is in progress */ 463 if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 464 peer->obj_state = WLAN_OBJ_STATE_DELETED; 465 /* Move to creation state, since this component 466 deletion alone requested */ 467 if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 468 peer->obj_state = WLAN_OBJ_STATE_CREATED; 469 /* Object status is failure */ 470 } else if (obj_status == QDF_STATUS_E_FAILURE) { 471 /*Update the status as Deletion failed, if full object 472 deletion is in progress */ 473 if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 474 peer->obj_state = 475 WLAN_OBJ_STATE_DELETION_FAILED; 476 /* Move to creation state, since this component 477 deletion alone requested (do not block other 478 components) */ 479 if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 480 peer->obj_state = WLAN_OBJ_STATE_CREATED; 481 } 482 483 /* Delete peer object */ 484 if ((obj_status == QDF_STATUS_SUCCESS) && 485 (peer->obj_state == WLAN_OBJ_STATE_DELETED)) { 486 /* Free the peer object */ 487 return wlan_objmgr_peer_obj_free(peer); 488 } 489 } 490 491 return QDF_STATUS_SUCCESS; 492 } 493 494 495 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation( 496 struct wlan_objmgr_peer *peer, 497 enum wlan_umac_comp_id id) 498 { 499 wlan_objmgr_peer_create_handler handler; 500 void *arg; 501 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 502 503 /* Component id is invalid */ 504 if (id >= WLAN_UMAC_MAX_COMPONENTS) 505 return QDF_STATUS_MAXCOMP_FAIL; 506 507 wlan_peer_obj_lock(peer); 508 /* If component object is already created, delete old 509 component object, then invoke creation */ 510 if (peer->peer_comp_priv_obj[id]) { 511 wlan_peer_obj_unlock(peer); 512 return QDF_STATUS_E_FAILURE; 513 } 514 wlan_peer_obj_unlock(peer); 515 516 /* Invoke registered create handlers */ 517 handler = g_umac_glb_obj->peer_create_handler[id]; 518 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 519 if (handler) 520 peer->obj_status[id] = handler(peer, arg); 521 else 522 return QDF_STATUS_E_FAILURE; 523 524 /* If object status is created, then only handle this object status */ 525 if (peer->obj_state == WLAN_OBJ_STATE_CREATED) { 526 /* Derive object status */ 527 obj_status = wlan_objmgr_peer_object_status(peer); 528 /* Move PDEV object state to Partially created state */ 529 if (obj_status == QDF_STATUS_COMP_ASYNC) { 530 /*TODO atomic */ 531 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 532 } 533 } 534 535 return obj_status; 536 } 537 538 539 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion( 540 struct wlan_objmgr_peer *peer, 541 enum wlan_umac_comp_id id) 542 { 543 wlan_objmgr_peer_destroy_handler handler; 544 void *arg; 545 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 546 547 /* component id is invalid */ 548 if (id >= WLAN_UMAC_MAX_COMPONENTS) 549 return QDF_STATUS_MAXCOMP_FAIL; 550 551 wlan_peer_obj_lock(peer); 552 /* Component object was never created, invalid operation */ 553 if (!peer->peer_comp_priv_obj[id]) { 554 wlan_peer_obj_unlock(peer); 555 return QDF_STATUS_E_FAILURE; 556 } 557 558 wlan_peer_obj_unlock(peer); 559 560 /* Invoke registered destroy handlers */ 561 handler = g_umac_glb_obj->peer_destroy_handler[id]; 562 arg = g_umac_glb_obj->peer_destroy_handler_arg[id]; 563 if (handler) 564 peer->obj_status[id] = handler(peer, arg); 565 else 566 return QDF_STATUS_E_FAILURE; 567 568 /* If object status is created, then only handle this object status */ 569 if (peer->obj_state == WLAN_OBJ_STATE_CREATED) { 570 obj_status = wlan_objmgr_peer_object_status(peer); 571 /* move object state to DEL progress */ 572 if (obj_status == QDF_STATUS_COMP_ASYNC) 573 peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS; 574 } 575 return obj_status; 576 } 577 578 void *wlan_objmgr_peer_get_comp_private_obj( 579 struct wlan_objmgr_peer *peer, 580 enum wlan_umac_comp_id id) 581 { 582 void *comp_priv_obj; 583 584 /* component id is invalid */ 585 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 586 QDF_BUG(0); 587 return NULL; 588 } 589 590 if (!peer) { 591 QDF_BUG(0); 592 return NULL; 593 } 594 595 comp_priv_obj = peer->peer_comp_priv_obj[id]; 596 return comp_priv_obj; 597 } 598 qdf_export_symbol(wlan_objmgr_peer_get_comp_private_obj); 599 600 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 601 static inline void 602 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer, 603 wlan_objmgr_ref_dbgid id) 604 { 605 qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]); 606 } 607 #else 608 static inline void 609 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer, 610 wlan_objmgr_ref_dbgid id) {} 611 #endif 612 613 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 614 static QDF_STATUS 615 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, 616 wlan_objmgr_ref_dbgid id) 617 { 618 if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) { 619 uint8_t *macaddr; 620 621 macaddr = wlan_peer_get_macaddr(peer); 622 obj_mgr_err( 623 "peer("QDF_MAC_ADDR_FMT") ref was not taken by %d", 624 QDF_MAC_ADDR_REF(macaddr), id); 625 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, 626 QDF_TRACE_LEVEL_FATAL); 627 WLAN_OBJMGR_BUG(0); 628 return QDF_STATUS_E_FAILURE; 629 } 630 631 qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]); 632 return QDF_STATUS_SUCCESS; 633 } 634 #else 635 static QDF_STATUS 636 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, 637 wlan_objmgr_ref_dbgid id) 638 { 639 return QDF_STATUS_SUCCESS; 640 } 641 #endif 642 643 #ifdef WLAN_OBJMGR_REF_ID_TRACE 644 static inline void 645 wlan_objmgr_peer_ref_trace(struct wlan_objmgr_peer *peer, 646 wlan_objmgr_ref_dbgid id, 647 const char *func, int line) 648 { 649 struct wlan_objmgr_trace *trace; 650 651 trace = &peer->peer_objmgr.trace; 652 653 if (func) 654 wlan_objmgr_trace_ref(&trace->references[id].head, 655 trace, func, line); 656 } 657 658 static inline void 659 wlan_objmgr_peer_deref_trace(struct wlan_objmgr_peer *peer, 660 wlan_objmgr_ref_dbgid id, 661 const char *func, int line) 662 { 663 struct wlan_objmgr_trace *trace; 664 665 trace = &peer->peer_objmgr.trace; 666 if (func) 667 wlan_objmgr_trace_ref(&trace->dereferences[id].head, 668 trace, func, line); 669 } 670 #endif 671 672 #ifdef WLAN_OBJMGR_REF_ID_TRACE 673 void wlan_objmgr_peer_get_ref_debug(struct wlan_objmgr_peer *peer, 674 wlan_objmgr_ref_dbgid id, 675 const char *func, int line) 676 { 677 if (!peer) { 678 obj_mgr_err("peer obj is NULL for %d", id); 679 QDF_ASSERT(0); 680 return; 681 } 682 /* Increment ref count */ 683 qdf_atomic_inc(&peer->peer_objmgr.ref_cnt); 684 wlan_objmgr_peer_get_debug_id_ref(peer, id); 685 686 wlan_objmgr_peer_ref_trace(peer, id, func, line); 687 return; 688 } 689 690 qdf_export_symbol(wlan_objmgr_peer_get_ref_debug); 691 #else 692 void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, 693 wlan_objmgr_ref_dbgid id) 694 { 695 if (!peer) { 696 obj_mgr_err("peer obj is NULL for %d", id); 697 QDF_ASSERT(0); 698 return; 699 } 700 /* Increment ref count */ 701 qdf_atomic_inc(&peer->peer_objmgr.ref_cnt); 702 wlan_objmgr_peer_get_debug_id_ref(peer, id); 703 } 704 705 qdf_export_symbol(wlan_objmgr_peer_get_ref); 706 #endif 707 708 #ifdef WLAN_OBJMGR_REF_ID_TRACE 709 QDF_STATUS wlan_objmgr_peer_try_get_ref_debug(struct wlan_objmgr_peer *peer, 710 wlan_objmgr_ref_dbgid id, 711 const char *func, int line) 712 { 713 if (!peer) { 714 obj_mgr_err("peer obj is NULL for %d", id); 715 QDF_ASSERT(0); 716 return QDF_STATUS_E_FAILURE; 717 } 718 719 wlan_peer_obj_lock(peer); 720 if (peer->obj_state != WLAN_OBJ_STATE_CREATED) { 721 wlan_peer_obj_unlock(peer); 722 if (peer->peer_objmgr.print_cnt++ <= 723 WLAN_OBJMGR_RATELIMIT_THRESH) { 724 uint8_t *macaddr; 725 726 macaddr = wlan_peer_get_macaddr(peer); 727 obj_mgr_debug( 728 "peer(" QDF_MAC_ADDR_FMT ") not in Created st(%d)", 729 QDF_MAC_ADDR_REF(macaddr), 730 peer->obj_state); 731 } 732 return QDF_STATUS_E_RESOURCES; 733 } 734 735 wlan_objmgr_peer_get_ref_debug(peer, id, func, line); 736 wlan_peer_obj_unlock(peer); 737 738 return QDF_STATUS_SUCCESS; 739 } 740 741 qdf_export_symbol(wlan_objmgr_peer_try_get_ref_debug); 742 #else 743 QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, 744 wlan_objmgr_ref_dbgid id) 745 { 746 if (!peer) { 747 obj_mgr_err("peer obj is NULL for %d", id); 748 QDF_ASSERT(0); 749 return QDF_STATUS_E_FAILURE; 750 } 751 752 wlan_peer_obj_lock(peer); 753 if (peer->obj_state != WLAN_OBJ_STATE_CREATED) { 754 wlan_peer_obj_unlock(peer); 755 if (peer->peer_objmgr.print_cnt++ <= 756 WLAN_OBJMGR_RATELIMIT_THRESH) { 757 uint8_t *macaddr; 758 759 macaddr = wlan_peer_get_macaddr(peer); 760 obj_mgr_debug( 761 "peer(" QDF_MAC_ADDR_FMT ") not in Created st(%d)", 762 QDF_MAC_ADDR_REF(macaddr), 763 peer->obj_state); 764 } 765 return QDF_STATUS_E_RESOURCES; 766 } 767 768 wlan_objmgr_peer_get_ref(peer, id); 769 wlan_peer_obj_unlock(peer); 770 771 return QDF_STATUS_SUCCESS; 772 } 773 774 qdf_export_symbol(wlan_objmgr_peer_try_get_ref); 775 #endif 776 777 #ifdef WLAN_OBJMGR_REF_ID_TRACE 778 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc_debug( 779 struct wlan_peer_list *peer_list, 780 uint8_t hash_index, 781 struct wlan_objmgr_peer *peer, 782 wlan_objmgr_ref_dbgid dbg_id, 783 const char *func, int line) 784 { 785 struct wlan_objmgr_peer *peer_next = NULL; 786 qdf_list_node_t *psoc_node = NULL; 787 qdf_list_node_t *prev_psoc_node = NULL; 788 qdf_list_t *obj_list; 789 790 qdf_spin_lock_bh(&peer_list->peer_list_lock); 791 obj_list = &peer_list->peer_hash[hash_index]; 792 793 prev_psoc_node = &peer->psoc_peer; 794 while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == 795 QDF_STATUS_SUCCESS) { 796 peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer, 797 psoc_peer); 798 799 if (wlan_objmgr_peer_try_get_ref_debug(peer_next, dbg_id, 800 func, line) == 801 QDF_STATUS_SUCCESS) { 802 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 803 return peer_next; 804 } 805 806 prev_psoc_node = psoc_node; 807 } 808 809 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 810 811 return NULL; 812 } 813 #else 814 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_psoc( 815 struct wlan_peer_list *peer_list, 816 uint8_t hash_index, 817 struct wlan_objmgr_peer *peer, 818 wlan_objmgr_ref_dbgid dbg_id) 819 { 820 struct wlan_objmgr_peer *peer_next = NULL; 821 qdf_list_node_t *psoc_node = NULL; 822 qdf_list_node_t *prev_psoc_node = NULL; 823 qdf_list_t *obj_list; 824 825 qdf_spin_lock_bh(&peer_list->peer_list_lock); 826 obj_list = &peer_list->peer_hash[hash_index]; 827 828 prev_psoc_node = &peer->psoc_peer; 829 while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == 830 QDF_STATUS_SUCCESS) { 831 peer_next = qdf_container_of(psoc_node, struct wlan_objmgr_peer, 832 psoc_peer); 833 834 if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) == 835 QDF_STATUS_SUCCESS) { 836 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 837 return peer_next; 838 } 839 840 prev_psoc_node = psoc_node; 841 } 842 843 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 844 845 return NULL; 846 } 847 #endif 848 849 #ifdef WLAN_OBJMGR_REF_ID_TRACE 850 struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head_debug( 851 struct wlan_objmgr_vdev *vdev, 852 qdf_list_t *peer_list, 853 wlan_objmgr_ref_dbgid dbg_id, 854 const char *func, int line) 855 { 856 struct wlan_objmgr_peer *peer; 857 qdf_list_node_t *vdev_node = NULL; 858 qdf_list_node_t *prev_vdev_node = NULL; 859 860 wlan_vdev_obj_lock(vdev); 861 862 if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) { 863 wlan_vdev_obj_unlock(vdev); 864 return NULL; 865 } 866 867 do { 868 peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, 869 vdev_peer); 870 871 if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, 872 func, line) == 873 QDF_STATUS_SUCCESS) { 874 wlan_vdev_obj_unlock(vdev); 875 return peer; 876 } 877 878 prev_vdev_node = vdev_node; 879 } while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == 880 QDF_STATUS_SUCCESS); 881 882 wlan_vdev_obj_unlock(vdev); 883 884 return NULL; 885 } 886 #else 887 struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_active_head( 888 struct wlan_objmgr_vdev *vdev, 889 qdf_list_t *peer_list, 890 wlan_objmgr_ref_dbgid dbg_id) 891 { 892 struct wlan_objmgr_peer *peer; 893 qdf_list_node_t *vdev_node = NULL; 894 qdf_list_node_t *prev_vdev_node = NULL; 895 896 wlan_vdev_obj_lock(vdev); 897 898 if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS) { 899 wlan_vdev_obj_unlock(vdev); 900 return NULL; 901 } 902 903 do { 904 peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, 905 vdev_peer); 906 907 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 908 QDF_STATUS_SUCCESS) { 909 wlan_vdev_obj_unlock(vdev); 910 return peer; 911 } 912 913 prev_vdev_node = vdev_node; 914 } while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == 915 QDF_STATUS_SUCCESS); 916 917 wlan_vdev_obj_unlock(vdev); 918 919 return NULL; 920 } 921 #endif 922 923 #ifdef WLAN_OBJMGR_REF_ID_TRACE 924 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev_debug( 925 struct wlan_objmgr_vdev *vdev, 926 qdf_list_t *peer_list, 927 struct wlan_objmgr_peer *peer, 928 wlan_objmgr_ref_dbgid dbg_id, 929 const char *func, int line) 930 { 931 struct wlan_objmgr_peer *peer_next; 932 qdf_list_node_t *vdev_node = NULL; 933 qdf_list_node_t *prev_vdev_node = NULL; 934 935 if (!peer) 936 return NULL; 937 938 wlan_vdev_obj_lock(vdev); 939 940 prev_vdev_node = &peer->vdev_peer; 941 while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == 942 QDF_STATUS_SUCCESS) { 943 peer_next = qdf_container_of(vdev_node, struct wlan_objmgr_peer, 944 vdev_peer); 945 946 if (wlan_objmgr_peer_try_get_ref_debug(peer_next, dbg_id, 947 func, line) == 948 QDF_STATUS_SUCCESS) { 949 wlan_vdev_obj_unlock(vdev); 950 return peer_next; 951 } 952 953 prev_vdev_node = vdev_node; 954 } 955 956 wlan_vdev_obj_unlock(vdev); 957 958 return NULL; 959 } 960 #else 961 struct wlan_objmgr_peer *wlan_peer_get_next_active_peer_of_vdev( 962 struct wlan_objmgr_vdev *vdev, 963 qdf_list_t *peer_list, 964 struct wlan_objmgr_peer *peer, 965 wlan_objmgr_ref_dbgid dbg_id) 966 { 967 struct wlan_objmgr_peer *peer_next; 968 qdf_list_node_t *vdev_node = NULL; 969 qdf_list_node_t *prev_vdev_node = NULL; 970 971 if (!peer) 972 return NULL; 973 974 wlan_vdev_obj_lock(vdev); 975 976 prev_vdev_node = &peer->vdev_peer; 977 while (qdf_list_peek_next(peer_list, prev_vdev_node, &vdev_node) == 978 QDF_STATUS_SUCCESS) { 979 peer_next = qdf_container_of(vdev_node, struct wlan_objmgr_peer, 980 vdev_peer); 981 982 if (wlan_objmgr_peer_try_get_ref(peer_next, dbg_id) == 983 QDF_STATUS_SUCCESS) { 984 wlan_vdev_obj_unlock(vdev); 985 return peer_next; 986 } 987 988 prev_vdev_node = vdev_node; 989 } 990 991 wlan_vdev_obj_unlock(vdev); 992 993 return NULL; 994 } 995 #endif 996 997 #ifdef WLAN_OBJMGR_REF_ID_TRACE 998 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head_debug( 999 struct wlan_peer_list *peer_list, 1000 uint8_t hash_index, 1001 wlan_objmgr_ref_dbgid dbg_id, 1002 const char *func, int line) 1003 { 1004 struct wlan_objmgr_peer *peer; 1005 qdf_list_node_t *psoc_node = NULL; 1006 qdf_list_node_t *prev_psoc_node = NULL; 1007 qdf_list_t *obj_list; 1008 1009 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1010 obj_list = &peer_list->peer_hash[hash_index]; 1011 1012 if (qdf_list_peek_front(obj_list, &psoc_node) != QDF_STATUS_SUCCESS) { 1013 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1014 return NULL; 1015 } 1016 1017 do { 1018 peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, 1019 psoc_peer); 1020 if (wlan_objmgr_peer_try_get_ref_debug(peer, dbg_id, 1021 func, line) == 1022 QDF_STATUS_SUCCESS) { 1023 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1024 return peer; 1025 } 1026 1027 prev_psoc_node = psoc_node; 1028 } while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == 1029 QDF_STATUS_SUCCESS); 1030 1031 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1032 return NULL; 1033 } 1034 #else 1035 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_active_head( 1036 struct wlan_peer_list *peer_list, 1037 uint8_t hash_index, 1038 wlan_objmgr_ref_dbgid dbg_id) 1039 { 1040 struct wlan_objmgr_peer *peer; 1041 qdf_list_node_t *psoc_node = NULL; 1042 qdf_list_node_t *prev_psoc_node = NULL; 1043 qdf_list_t *obj_list; 1044 1045 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1046 obj_list = &peer_list->peer_hash[hash_index]; 1047 1048 if (qdf_list_peek_front(obj_list, &psoc_node) != QDF_STATUS_SUCCESS) { 1049 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1050 return NULL; 1051 } 1052 1053 do { 1054 peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, 1055 psoc_peer); 1056 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 1057 QDF_STATUS_SUCCESS) { 1058 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1059 return peer; 1060 } 1061 1062 prev_psoc_node = psoc_node; 1063 } while (qdf_list_peek_next(obj_list, prev_psoc_node, &psoc_node) == 1064 QDF_STATUS_SUCCESS); 1065 1066 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1067 return NULL; 1068 } 1069 #endif 1070 1071 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1072 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref_debug( 1073 struct wlan_peer_list *peer_list, 1074 uint8_t hash_index, 1075 wlan_objmgr_ref_dbgid dbg_id, 1076 const char *func, int line) 1077 { 1078 struct wlan_objmgr_peer *peer; 1079 qdf_list_t *obj_list; 1080 1081 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1082 obj_list = &peer_list->peer_hash[hash_index]; 1083 1084 peer = wlan_psoc_peer_list_peek_head(obj_list); 1085 1086 /* This API is invoked by caller, only when caller need to access the 1087 * peer object, though object is not in active state, this API should be 1088 * used carefully, where multiple object frees are not triggered 1089 */ 1090 if (peer) 1091 wlan_objmgr_peer_get_ref_debug(peer, dbg_id, func, line); 1092 1093 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1094 1095 return peer; 1096 } 1097 #else 1098 struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head_ref( 1099 struct wlan_peer_list *peer_list, 1100 uint8_t hash_index, 1101 wlan_objmgr_ref_dbgid dbg_id) 1102 { 1103 struct wlan_objmgr_peer *peer; 1104 qdf_list_t *obj_list; 1105 1106 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1107 obj_list = &peer_list->peer_hash[hash_index]; 1108 1109 peer = wlan_psoc_peer_list_peek_head(obj_list); 1110 1111 /* This API is invoked by caller, only when caller need to access the 1112 * peer object, though object is not in active state, this API should be 1113 * used carefully, where multiple object frees are not triggered 1114 */ 1115 if (peer) 1116 wlan_objmgr_peer_get_ref(peer, dbg_id); 1117 1118 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1119 1120 return peer; 1121 } 1122 #endif 1123 1124 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1125 struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref_debug( 1126 struct wlan_peer_list *peer_list, uint8_t hash_index, 1127 struct wlan_objmgr_peer *peer, 1128 wlan_objmgr_ref_dbgid dbg_id, 1129 const char *func, int line) 1130 { 1131 qdf_list_t *obj_list; 1132 struct wlan_objmgr_peer *peer_next; 1133 1134 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1135 obj_list = &peer_list->peer_hash[hash_index]; 1136 1137 peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer); 1138 /* This API is invoked by caller, only when caller need to access the 1139 * peer object, though object is not in active state, this API should be 1140 * used carefully, where multiple free on object are not triggered 1141 */ 1142 if (peer_next) 1143 wlan_objmgr_peer_get_ref_debug(peer_next, dbg_id, func, line); 1144 1145 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1146 1147 return peer_next; 1148 } 1149 #else 1150 struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc_ref( 1151 struct wlan_peer_list *peer_list, uint8_t hash_index, 1152 struct wlan_objmgr_peer *peer, 1153 wlan_objmgr_ref_dbgid dbg_id) 1154 { 1155 qdf_list_t *obj_list; 1156 struct wlan_objmgr_peer *peer_next; 1157 1158 qdf_spin_lock_bh(&peer_list->peer_list_lock); 1159 obj_list = &peer_list->peer_hash[hash_index]; 1160 1161 peer_next = wlan_peer_get_next_peer_of_psoc(obj_list, peer); 1162 /* This API is invoked by caller, only when caller need to access the 1163 * peer object, though object is not in active state, this API should be 1164 * used carefully, where multiple free on object are not triggered 1165 */ 1166 if (peer_next) 1167 wlan_objmgr_peer_get_ref(peer_next, dbg_id); 1168 1169 qdf_spin_unlock_bh(&peer_list->peer_list_lock); 1170 1171 return peer_next; 1172 } 1173 #endif 1174 1175 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1176 void wlan_objmgr_peer_release_ref_debug(struct wlan_objmgr_peer *peer, 1177 wlan_objmgr_ref_dbgid id, 1178 const char *func, int line) 1179 { 1180 QDF_STATUS status; 1181 1182 if (!peer) { 1183 obj_mgr_err("peer obj is NULL for %d", id); 1184 QDF_ASSERT(0); 1185 return; 1186 } 1187 1188 if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { 1189 uint8_t *macaddr; 1190 1191 macaddr = wlan_peer_get_macaddr(peer); 1192 obj_mgr_err("peer("QDF_MAC_ADDR_FMT") ref cnt is 0", 1193 QDF_MAC_ADDR_REF(macaddr)); 1194 WLAN_OBJMGR_BUG(0); 1195 return; 1196 } 1197 1198 status = wlan_objmgr_peer_release_debug_id_ref(peer, id); 1199 if (QDF_IS_STATUS_ERROR(status)) 1200 return; 1201 1202 wlan_objmgr_peer_deref_trace(peer, id, func, line); 1203 /* Provide synchronization from the access to add peer 1204 * to logically deleted peer list. 1205 */ 1206 wlan_peer_obj_lock(peer); 1207 /* Decrement ref count, free peer object, if ref count == 0 */ 1208 if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { 1209 wlan_peer_obj_unlock(peer); 1210 wlan_objmgr_peer_obj_destroy(peer); 1211 } else { 1212 wlan_peer_obj_unlock(peer); 1213 } 1214 1215 return; 1216 } 1217 1218 qdf_export_symbol(wlan_objmgr_peer_release_ref_debug); 1219 #else 1220 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, 1221 wlan_objmgr_ref_dbgid id) 1222 { 1223 QDF_STATUS status; 1224 1225 if (!peer) { 1226 obj_mgr_err("peer obj is NULL for %d", id); 1227 QDF_ASSERT(0); 1228 return; 1229 } 1230 1231 if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { 1232 uint8_t *macaddr; 1233 1234 macaddr = wlan_peer_get_macaddr(peer); 1235 obj_mgr_err("peer("QDF_MAC_ADDR_FMT") ref cnt is 0", 1236 QDF_MAC_ADDR_REF(macaddr)); 1237 WLAN_OBJMGR_BUG(0); 1238 return; 1239 } 1240 1241 status = wlan_objmgr_peer_release_debug_id_ref(peer, id); 1242 if (QDF_IS_STATUS_ERROR(status)) 1243 return; 1244 1245 /* Provide synchronization from the access to add peer 1246 * to logically deleted peer list. 1247 */ 1248 wlan_peer_obj_lock(peer); 1249 /* Decrement ref count, free peer object, if ref count == 0 */ 1250 if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { 1251 wlan_peer_obj_unlock(peer); 1252 wlan_objmgr_peer_obj_destroy(peer); 1253 } else { 1254 wlan_peer_obj_unlock(peer); 1255 } 1256 } 1257 1258 qdf_export_symbol(wlan_objmgr_peer_release_ref); 1259 #endif 1260 1261 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 1262 void 1263 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer, 1264 QDF_TRACE_LEVEL log_level) 1265 { 1266 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, log_level); 1267 } 1268 1269 uint32_t 1270 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, 1271 enum wlan_umac_comp_id id) 1272 { 1273 return qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id]); 1274 } 1275 #else 1276 void 1277 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer, 1278 QDF_TRACE_LEVEL log_level) 1279 { 1280 uint32_t pending_ref; 1281 1282 pending_ref = qdf_atomic_read(&peer->peer_objmgr.ref_cnt); 1283 obj_mgr_log_level(log_level, "Pending refs -- %d", pending_ref); 1284 } 1285 1286 uint32_t 1287 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, 1288 enum wlan_umac_comp_id id) 1289 { 1290 return 0; 1291 } 1292 #endif 1293