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 <qdf_mem.h> 28 #include <qdf_module.h> 29 #include "wlan_objmgr_global_obj_i.h" 30 #include "wlan_objmgr_psoc_obj_i.h" 31 #include "wlan_objmgr_pdev_obj_i.h" 32 #include "wlan_objmgr_vdev_obj_i.h" 33 34 35 /** 36 ** APIs to Create/Delete Peer object APIs 37 */ 38 static QDF_STATUS wlan_objmgr_peer_object_status( 39 struct wlan_objmgr_peer *peer) 40 { 41 uint8_t id; 42 QDF_STATUS status = QDF_STATUS_SUCCESS; 43 44 wlan_peer_obj_lock(peer); 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 (peer->obj_status[id] == QDF_STATUS_COMP_DISABLED) 49 continue; 50 /* If component operates in Async, status is Partially created, 51 break */ 52 else if (peer->obj_status[id] == QDF_STATUS_COMP_ASYNC) { 53 if (!peer->peer_comp_priv_obj[id]) { 54 status = QDF_STATUS_COMP_ASYNC; 55 break; 56 } 57 /* If component failed to allocate its object, treat it as 58 failure, complete object need to be cleaned up */ 59 } else if ((peer->obj_status[id] == QDF_STATUS_E_NOMEM) || 60 (peer->obj_status[id] == QDF_STATUS_E_FAILURE)) { 61 obj_mgr_err("Peer comp object(id:%d) alloc fail", id); 62 status = QDF_STATUS_E_FAILURE; 63 break; 64 } 65 } 66 wlan_peer_obj_unlock(peer); 67 return status; 68 } 69 70 static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer) 71 { 72 struct wlan_objmgr_psoc *psoc; 73 struct wlan_objmgr_vdev *vdev; 74 uint8_t *macaddr; 75 uint8_t vdev_id; 76 77 if (!peer) { 78 obj_mgr_err("PEER is NULL"); 79 return QDF_STATUS_E_FAILURE; 80 } 81 82 macaddr = wlan_peer_get_macaddr(peer); 83 84 vdev = wlan_peer_get_vdev(peer); 85 if (!vdev) { 86 obj_mgr_err( 87 "VDEV is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", 88 macaddr[0], macaddr[1], macaddr[2], 89 macaddr[3], macaddr[4], macaddr[5]); 90 return QDF_STATUS_E_FAILURE; 91 } 92 93 vdev_id = wlan_vdev_get_id(vdev); 94 95 /* get PSOC from VDEV, if it is NULL, return */ 96 psoc = wlan_vdev_get_psoc(vdev); 97 if (!psoc) { 98 obj_mgr_err( 99 "PSOC is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", 100 macaddr[0], macaddr[1], macaddr[2], 101 macaddr[3], macaddr[4], macaddr[5]); 102 return QDF_STATUS_E_FAILURE; 103 } 104 105 /* Decrement ref count for BSS peer, so that BSS peer deletes last*/ 106 if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) || 107 (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP) || 108 (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_CLI)) 109 wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev), 110 WLAN_OBJMGR_ID); 111 112 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); 113 114 /* Detach peer from VDEV's peer list */ 115 if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) { 116 obj_mgr_err( 117 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d", 118 macaddr[0], macaddr[1], macaddr[2], 119 macaddr[3], macaddr[4], macaddr[5], vdev_id); 120 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 121 return QDF_STATUS_E_FAILURE; 122 } 123 /* Detach peer from PSOC's peer list */ 124 if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) { 125 obj_mgr_err( 126 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure", 127 macaddr[0], macaddr[1], macaddr[2], 128 macaddr[3], macaddr[4], macaddr[5]); 129 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 130 return QDF_STATUS_E_FAILURE; 131 } 132 wlan_objmgr_peer_trace_del_ref_list(peer); 133 wlan_objmgr_peer_trace_deinit_lock(peer); 134 qdf_spinlock_destroy(&peer->peer_lock); 135 qdf_mem_free(peer); 136 137 wlan_objmgr_vdev_peer_freed_notify(vdev); 138 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 139 140 return QDF_STATUS_SUCCESS; 141 142 } 143 144 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 145 static void 146 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) 147 { 148 uint8_t id; 149 150 for (id = 0; id < WLAN_REF_ID_MAX; id++) 151 qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]); 152 } 153 #else 154 static inline void 155 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) {} 156 #endif 157 158 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( 159 struct wlan_objmgr_vdev *vdev, 160 enum wlan_peer_type type, 161 uint8_t *macaddr) 162 { 163 struct wlan_objmgr_peer *peer; 164 struct wlan_objmgr_psoc *psoc; 165 wlan_objmgr_peer_create_handler handler; 166 wlan_objmgr_peer_status_handler stat_handler; 167 void *arg; 168 QDF_STATUS obj_status; 169 uint8_t id; 170 171 if (!vdev) { 172 obj_mgr_err( 173 "VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", 174 macaddr[0], macaddr[1], macaddr[2], 175 macaddr[3], macaddr[4], macaddr[5]); 176 return NULL; 177 } 178 /* Get psoc, if psoc is NULL, return */ 179 psoc = wlan_vdev_get_psoc(vdev); 180 if (!psoc) { 181 obj_mgr_err( 182 "PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", 183 macaddr[0], macaddr[1], macaddr[2], 184 macaddr[3], macaddr[4], macaddr[5]); 185 return NULL; 186 } 187 /* Allocate memory for peer object */ 188 peer = qdf_mem_malloc(sizeof(*peer)); 189 if (!peer) 190 return NULL; 191 192 peer->obj_state = WLAN_OBJ_STATE_ALLOCATED; 193 qdf_atomic_init(&peer->peer_objmgr.ref_cnt); 194 wlan_objmgr_peer_init_ref_id_debug(peer); 195 wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID); 196 /* set vdev to peer */ 197 wlan_peer_set_vdev(peer, vdev); 198 /* set peer type */ 199 wlan_peer_set_peer_type(peer, type); 200 /* set mac address of peer */ 201 wlan_peer_set_macaddr(peer, macaddr); 202 /* initialize peer state */ 203 wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE); 204 wlan_peer_mlme_reset_seq_num(peer); 205 peer->peer_objmgr.print_cnt = 0; 206 207 qdf_spinlock_create(&peer->peer_lock); 208 wlan_objmgr_peer_trace_init_lock(peer); 209 /* Attach peer to psoc, psoc maintains the node table for the device */ 210 if (wlan_objmgr_psoc_peer_attach(psoc, peer) != 211 QDF_STATUS_SUCCESS) { 212 obj_mgr_warn( 213 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure", 214 macaddr[0], macaddr[1], macaddr[2], 215 macaddr[3], macaddr[4], macaddr[5]); 216 qdf_spinlock_destroy(&peer->peer_lock); 217 wlan_objmgr_peer_trace_deinit_lock(peer); 218 qdf_mem_free(peer); 219 return NULL; 220 } 221 /* Attach peer to vdev peer table */ 222 if (wlan_objmgr_vdev_peer_attach(vdev, peer) != 223 QDF_STATUS_SUCCESS) { 224 obj_mgr_warn( 225 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure", 226 macaddr[0], macaddr[1], macaddr[2], 227 macaddr[3], macaddr[4], macaddr[5]); 228 /* if attach fails, detach from psoc table before free */ 229 wlan_objmgr_psoc_peer_detach(psoc, peer); 230 qdf_spinlock_destroy(&peer->peer_lock); 231 wlan_objmgr_peer_trace_deinit_lock(peer); 232 qdf_mem_free(peer); 233 return NULL; 234 } 235 wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id( 236 wlan_vdev_get_pdev(vdev))); 237 /* Increment ref count for BSS peer, so that BSS peer deletes last*/ 238 if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP) 239 || (type == WLAN_PEER_P2P_CLI)) 240 wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev), 241 WLAN_OBJMGR_ID); 242 /* TODO init other parameters */ 243 /* Invoke registered create handlers */ 244 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 245 handler = g_umac_glb_obj->peer_create_handler[id]; 246 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 247 if (handler) 248 peer->obj_status[id] = handler(peer, arg); 249 else 250 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 251 } 252 /* derive the object status */ 253 obj_status = wlan_objmgr_peer_object_status(peer); 254 /* If SUCCESS, Object is created */ 255 if (obj_status == QDF_STATUS_SUCCESS) { 256 peer->obj_state = WLAN_OBJ_STATE_CREATED; 257 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 258 stat_handler = g_umac_glb_obj->peer_status_handler[id]; 259 arg = g_umac_glb_obj->peer_status_handler_arg[id]; 260 if (stat_handler) 261 stat_handler(peer, arg, 262 QDF_STATUS_SUCCESS); 263 } 264 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 265 /* If any component operates in different context, update it 266 as partially created */ 267 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 268 } else if (obj_status == QDF_STATUS_E_FAILURE) { 269 /* Clean up the peer */ 270 obj_mgr_err( 271 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail", 272 macaddr[0], macaddr[1], macaddr[2], 273 macaddr[3], macaddr[4], macaddr[5]); 274 wlan_objmgr_peer_obj_delete(peer); 275 return NULL; 276 } 277 278 obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR " type %d", 279 QDF_MAC_ADDR_ARRAY(macaddr), type); 280 281 return peer; 282 } 283 284 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer) 285 { 286 uint8_t id; 287 wlan_objmgr_peer_destroy_handler handler; 288 QDF_STATUS obj_status; 289 void *arg; 290 uint8_t *macaddr; 291 292 if (!peer) { 293 obj_mgr_err("PEER is NULL"); 294 return QDF_STATUS_E_FAILURE; 295 } 296 wlan_objmgr_notify_destroy(peer, WLAN_PEER_OP); 297 298 macaddr = wlan_peer_get_macaddr(peer); 299 300 obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_STR, 301 QDF_MAC_ADDR_ARRAY(macaddr)); 302 303 if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { 304 obj_mgr_err("PEER object del is not invoked obj_state:%d peer " 305 QDF_MAC_ADDR_STR, peer->obj_state, 306 QDF_MAC_ADDR_ARRAY(macaddr)); 307 WLAN_OBJMGR_BUG(0); 308 } 309 310 /* Invoke registered destroy handlers */ 311 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 312 handler = g_umac_glb_obj->peer_destroy_handler[id]; 313 arg = g_umac_glb_obj->peer_destroy_handler_arg[id]; 314 if (handler && 315 (peer->obj_status[id] == QDF_STATUS_SUCCESS || 316 peer->obj_status[id] == QDF_STATUS_COMP_ASYNC)) 317 peer->obj_status[id] = handler(peer, arg); 318 else 319 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 320 } 321 /* Derive the object status */ 322 obj_status = wlan_objmgr_peer_object_status(peer); 323 if (obj_status == QDF_STATUS_E_FAILURE) { 324 /* If it status is failure, memory will not be freed */ 325 QDF_BUG(0); 326 return QDF_STATUS_E_FAILURE; 327 } 328 /* few components deletion is in progress */ 329 if (obj_status == QDF_STATUS_COMP_ASYNC) { 330 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED; 331 return QDF_STATUS_COMP_ASYNC; 332 } 333 334 /* Free the peer object */ 335 return wlan_objmgr_peer_obj_free(peer); 336 } 337 338 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer) 339 { 340 uint8_t print_idx; 341 uint8_t *macaddr; 342 343 if (!peer) { 344 obj_mgr_err("PEER is NULL"); 345 return QDF_STATUS_E_FAILURE; 346 } 347 348 wlan_peer_obj_lock(peer); 349 macaddr = wlan_peer_get_macaddr(peer); 350 wlan_peer_obj_unlock(peer); 351 352 obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_STR, 353 QDF_MAC_ADDR_ARRAY(macaddr)); 354 355 print_idx = qdf_get_pidx(); 356 wlan_objmgr_print_peer_ref_ids(peer, QDF_TRACE_LEVEL_DEBUG); 357 /** 358 * Update VDEV object state to LOGICALLY DELETED 359 * It prevents further access of this object 360 */ 361 wlan_peer_obj_lock(peer); 362 peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED; 363 wlan_peer_obj_unlock(peer); 364 wlan_objmgr_notify_log_delete(peer, WLAN_PEER_OP); 365 wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID); 366 367 return QDF_STATUS_SUCCESS; 368 } 369 qdf_export_symbol(wlan_objmgr_peer_obj_delete); 370 /** 371 ** APIs to attach/detach component objects 372 */ 373 QDF_STATUS wlan_objmgr_peer_component_obj_attach( 374 struct wlan_objmgr_peer *peer, 375 enum wlan_umac_comp_id id, 376 void *comp_priv_obj, 377 QDF_STATUS status) 378 { 379 wlan_objmgr_peer_status_handler s_hler; 380 void *arg; 381 uint8_t i; 382 QDF_STATUS obj_status; 383 384 /* component id is invalid */ 385 if (id >= WLAN_UMAC_MAX_COMPONENTS) 386 return QDF_STATUS_MAXCOMP_FAIL; 387 388 wlan_peer_obj_lock(peer); 389 /* If there is a valid entry, return failure, 390 valid object needs to be freed first */ 391 if (peer->peer_comp_priv_obj[id]) { 392 wlan_peer_obj_unlock(peer); 393 return QDF_STATUS_E_FAILURE; 394 } 395 /* Assign component object private pointer(can be NULL also), status */ 396 peer->peer_comp_priv_obj[id] = comp_priv_obj; 397 peer->obj_status[id] = status; 398 wlan_peer_obj_unlock(peer); 399 400 if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED) 401 return QDF_STATUS_SUCCESS; 402 403 /* If PEER object status is partially created means, this API is 404 invoked with differnt context. this block should be executed for async 405 components only */ 406 /* Derive status */ 407 obj_status = wlan_objmgr_peer_object_status(peer); 408 /* STATUS_SUCCESS means, object is CREATED */ 409 if (obj_status == QDF_STATUS_SUCCESS) 410 peer->obj_state = WLAN_OBJ_STATE_CREATED; 411 /* update state as CREATION failed, caller has to delete the 412 PEER object */ 413 else if (obj_status == QDF_STATUS_E_FAILURE) 414 peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED; 415 /* Notify components about the CREATION success/failure */ 416 if ((obj_status == QDF_STATUS_SUCCESS) || 417 (obj_status == QDF_STATUS_E_FAILURE)) { 418 /* nofity object status */ 419 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 420 s_hler = g_umac_glb_obj->peer_status_handler[i]; 421 arg = g_umac_glb_obj->peer_status_handler_arg[i]; 422 if (s_hler) 423 s_hler(peer, arg, obj_status); 424 } 425 } 426 return QDF_STATUS_SUCCESS; 427 } 428 429 QDF_STATUS wlan_objmgr_peer_component_obj_detach( 430 struct wlan_objmgr_peer *peer, 431 enum wlan_umac_comp_id id, 432 void *comp_priv_obj) 433 { 434 QDF_STATUS obj_status; 435 436 /* component id is invalid */ 437 if (id >= WLAN_UMAC_MAX_COMPONENTS) 438 return QDF_STATUS_MAXCOMP_FAIL; 439 440 wlan_peer_obj_lock(peer); 441 /* If there is a invalid entry, return failure */ 442 if (peer->peer_comp_priv_obj[id] != comp_priv_obj) { 443 peer->obj_status[id] = QDF_STATUS_E_FAILURE; 444 wlan_peer_obj_unlock(peer); 445 return QDF_STATUS_E_FAILURE; 446 } 447 /* Reset the pointer to NULL */ 448 peer->peer_comp_priv_obj[id] = NULL; 449 peer->obj_status[id] = QDF_STATUS_SUCCESS; 450 wlan_peer_obj_unlock(peer); 451 452 /* If PEER object status is partially destroyed means, this API is 453 invoked with differnt context, this block should be executed for async 454 components only */ 455 if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) || 456 (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) { 457 /* Derive object status */ 458 obj_status = wlan_objmgr_peer_object_status(peer); 459 if (obj_status == QDF_STATUS_SUCCESS) { 460 /*Update the status as Deleted, if full object 461 deletion is in progress */ 462 if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 463 peer->obj_state = WLAN_OBJ_STATE_DELETED; 464 /* Move to creation state, since this component 465 deletion alone requested */ 466 if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 467 peer->obj_state = WLAN_OBJ_STATE_CREATED; 468 /* Object status is failure */ 469 } else if (obj_status == QDF_STATUS_E_FAILURE) { 470 /*Update the status as Deletion failed, if full object 471 deletion is in progress */ 472 if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 473 peer->obj_state = 474 WLAN_OBJ_STATE_DELETION_FAILED; 475 /* Move to creation state, since this component 476 deletion alone requested (do not block other 477 components) */ 478 if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 479 peer->obj_state = WLAN_OBJ_STATE_CREATED; 480 } 481 482 /* Delete peer object */ 483 if ((obj_status == QDF_STATUS_SUCCESS) && 484 (peer->obj_state == WLAN_OBJ_STATE_DELETED)) { 485 /* Free the peer object */ 486 return wlan_objmgr_peer_obj_free(peer); 487 } 488 } 489 490 return QDF_STATUS_SUCCESS; 491 } 492 493 494 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation( 495 struct wlan_objmgr_peer *peer, 496 enum wlan_umac_comp_id id) 497 { 498 wlan_objmgr_peer_create_handler handler; 499 void *arg; 500 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 501 502 /* Component id is invalid */ 503 if (id >= WLAN_UMAC_MAX_COMPONENTS) 504 return QDF_STATUS_MAXCOMP_FAIL; 505 506 wlan_peer_obj_lock(peer); 507 /* If component object is already created, delete old 508 component object, then invoke creation */ 509 if (peer->peer_comp_priv_obj[id]) { 510 wlan_peer_obj_unlock(peer); 511 return QDF_STATUS_E_FAILURE; 512 } 513 wlan_peer_obj_unlock(peer); 514 515 /* Invoke registered create handlers */ 516 handler = g_umac_glb_obj->peer_create_handler[id]; 517 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 518 if (handler) 519 peer->obj_status[id] = handler(peer, arg); 520 else 521 return QDF_STATUS_E_FAILURE; 522 523 /* If object status is created, then only handle this object status */ 524 if (peer->obj_state == WLAN_OBJ_STATE_CREATED) { 525 /* Derive object status */ 526 obj_status = wlan_objmgr_peer_object_status(peer); 527 /* Move PDEV object state to Partially created state */ 528 if (obj_status == QDF_STATUS_COMP_ASYNC) { 529 /*TODO atomic */ 530 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 531 } 532 } 533 534 return obj_status; 535 } 536 537 538 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion( 539 struct wlan_objmgr_peer *peer, 540 enum wlan_umac_comp_id id) 541 { 542 wlan_objmgr_peer_destroy_handler handler; 543 void *arg; 544 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 545 546 /* component id is invalid */ 547 if (id >= WLAN_UMAC_MAX_COMPONENTS) 548 return QDF_STATUS_MAXCOMP_FAIL; 549 550 wlan_peer_obj_lock(peer); 551 /* Component object was never created, invalid operation */ 552 if (!peer->peer_comp_priv_obj[id]) { 553 wlan_peer_obj_unlock(peer); 554 return QDF_STATUS_E_FAILURE; 555 } 556 557 wlan_peer_obj_unlock(peer); 558 559 /* Invoke registered destroy handlers */ 560 handler = g_umac_glb_obj->peer_destroy_handler[id]; 561 arg = g_umac_glb_obj->peer_destroy_handler_arg[id]; 562 if (handler) 563 peer->obj_status[id] = handler(peer, arg); 564 else 565 return QDF_STATUS_E_FAILURE; 566 567 /* If object status is created, then only handle this object status */ 568 if (peer->obj_state == WLAN_OBJ_STATE_CREATED) { 569 obj_status = wlan_objmgr_peer_object_status(peer); 570 /* move object state to DEL progress */ 571 if (obj_status == QDF_STATUS_COMP_ASYNC) 572 peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS; 573 } 574 return obj_status; 575 } 576 577 void *wlan_objmgr_peer_get_comp_private_obj( 578 struct wlan_objmgr_peer *peer, 579 enum wlan_umac_comp_id id) 580 { 581 void *comp_priv_obj; 582 583 /* component id is invalid */ 584 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 585 QDF_BUG(0); 586 return NULL; 587 } 588 589 if (!peer) { 590 QDF_BUG(0); 591 return NULL; 592 } 593 594 comp_priv_obj = peer->peer_comp_priv_obj[id]; 595 return comp_priv_obj; 596 } 597 qdf_export_symbol(wlan_objmgr_peer_get_comp_private_obj); 598 599 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 600 static inline void 601 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer, 602 wlan_objmgr_ref_dbgid id) 603 { 604 qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]); 605 } 606 #else 607 static inline void 608 wlan_objmgr_peer_get_debug_id_ref(struct wlan_objmgr_peer *peer, 609 wlan_objmgr_ref_dbgid id) {} 610 #endif 611 612 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 613 static QDF_STATUS 614 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer, 615 wlan_objmgr_ref_dbgid id) 616 { 617 if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) { 618 uint8_t *macaddr; 619 620 macaddr = wlan_peer_get_macaddr(peer); 621 obj_mgr_err( 622 "peer(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d", 623 macaddr[0], macaddr[1], macaddr[2], 624 macaddr[3], macaddr[4], macaddr[5], 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_STR ") not in Created st(%d)", 729 QDF_MAC_ADDR_ARRAY(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_STR ") not in Created st(%d)", 762 QDF_MAC_ADDR_ARRAY(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(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0", 1193 macaddr[0], macaddr[1], macaddr[2], 1194 macaddr[3], macaddr[4], macaddr[5]); 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(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0", 1237 macaddr[0], macaddr[1], macaddr[2], 1238 macaddr[3], macaddr[4], macaddr[5]); 1239 WLAN_OBJMGR_BUG(0); 1240 return; 1241 } 1242 1243 status = wlan_objmgr_peer_release_debug_id_ref(peer, id); 1244 if (QDF_IS_STATUS_ERROR(status)) 1245 return; 1246 1247 /* Provide synchronization from the access to add peer 1248 * to logically deleted peer list. 1249 */ 1250 wlan_peer_obj_lock(peer); 1251 /* Decrement ref count, free peer object, if ref count == 0 */ 1252 if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { 1253 wlan_peer_obj_unlock(peer); 1254 wlan_objmgr_peer_obj_destroy(peer); 1255 } else { 1256 wlan_peer_obj_unlock(peer); 1257 } 1258 } 1259 1260 qdf_export_symbol(wlan_objmgr_peer_release_ref); 1261 #endif 1262 1263 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 1264 void 1265 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer, 1266 QDF_TRACE_LEVEL log_level) 1267 { 1268 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, log_level); 1269 } 1270 1271 uint32_t 1272 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, 1273 enum wlan_umac_comp_id id) 1274 { 1275 return qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id]); 1276 } 1277 #else 1278 void 1279 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer, 1280 QDF_TRACE_LEVEL log_level) 1281 { 1282 uint32_t pending_ref; 1283 1284 pending_ref = qdf_atomic_read(&peer->peer_objmgr.ref_cnt); 1285 obj_mgr_log_level(log_level, "Pending refs -- %d", pending_ref); 1286 } 1287 1288 uint32_t 1289 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, 1290 enum wlan_umac_comp_id id) 1291 { 1292 return 0; 1293 } 1294 #endif 1295