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