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 78 if (!peer) { 79 obj_mgr_err("PEER is NULL"); 80 return QDF_STATUS_E_FAILURE; 81 } 82 83 macaddr = wlan_peer_get_macaddr(peer); 84 85 vdev = wlan_peer_get_vdev(peer); 86 if (!vdev) { 87 obj_mgr_err( 88 "VDEV is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", 89 macaddr[0], macaddr[1], macaddr[2], 90 macaddr[3], macaddr[4], macaddr[5]); 91 return QDF_STATUS_E_FAILURE; 92 } 93 94 vdev_id = wlan_vdev_get_id(vdev); 95 96 /* get PSOC from VDEV, if it is NULL, return */ 97 psoc = wlan_vdev_get_psoc(vdev); 98 if (!psoc) { 99 obj_mgr_err( 100 "PSOC is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", 101 macaddr[0], macaddr[1], macaddr[2], 102 macaddr[3], macaddr[4], macaddr[5]); 103 return QDF_STATUS_E_FAILURE; 104 } 105 106 /* Decrement ref count for BSS peer, so that BSS peer deletes last*/ 107 if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) || 108 (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP) || 109 (wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_CLI)) 110 wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev), 111 WLAN_OBJMGR_ID); 112 113 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); 114 115 /* Detach peer from VDEV's peer list */ 116 if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) { 117 obj_mgr_err( 118 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d", 119 macaddr[0], macaddr[1], macaddr[2], 120 macaddr[3], macaddr[4], macaddr[5], vdev_id); 121 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 122 return QDF_STATUS_E_FAILURE; 123 } 124 /* Detach peer from PSOC's peer list */ 125 if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) { 126 obj_mgr_err( 127 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure", 128 macaddr[0], macaddr[1], macaddr[2], 129 macaddr[3], macaddr[4], macaddr[5]); 130 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 131 return QDF_STATUS_E_FAILURE; 132 } 133 wlan_objmgr_peer_trace_del_ref_list(peer); 134 wlan_objmgr_peer_trace_deinit_lock(peer); 135 qdf_spinlock_destroy(&peer->peer_lock); 136 qdf_mem_free(peer); 137 138 wlan_objmgr_vdev_peer_freed_notify(vdev); 139 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 140 141 return QDF_STATUS_SUCCESS; 142 143 } 144 145 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 146 static void 147 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) 148 { 149 uint8_t id; 150 151 for (id = 0; id < WLAN_REF_ID_MAX; id++) 152 qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]); 153 } 154 #else 155 static inline void 156 wlan_objmgr_peer_init_ref_id_debug(struct wlan_objmgr_peer *peer) {} 157 #endif 158 159 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( 160 struct wlan_objmgr_vdev *vdev, 161 enum wlan_peer_type type, 162 uint8_t *macaddr) 163 { 164 struct wlan_objmgr_peer *peer; 165 struct wlan_objmgr_psoc *psoc; 166 wlan_objmgr_peer_create_handler handler; 167 wlan_objmgr_peer_status_handler stat_handler; 168 void *arg; 169 QDF_STATUS obj_status; 170 uint8_t id; 171 172 if (!vdev) { 173 obj_mgr_err( 174 "VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", 175 macaddr[0], macaddr[1], macaddr[2], 176 macaddr[3], macaddr[4], macaddr[5]); 177 return NULL; 178 } 179 /* Get psoc, if psoc is NULL, return */ 180 psoc = wlan_vdev_get_psoc(vdev); 181 if (!psoc) { 182 obj_mgr_err( 183 "PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", 184 macaddr[0], macaddr[1], macaddr[2], 185 macaddr[3], macaddr[4], macaddr[5]); 186 return NULL; 187 } 188 /* Allocate memory for peer object */ 189 peer = qdf_mem_malloc(sizeof(*peer)); 190 if (!peer) 191 return NULL; 192 193 peer->obj_state = WLAN_OBJ_STATE_ALLOCATED; 194 qdf_atomic_init(&peer->peer_objmgr.ref_cnt); 195 wlan_objmgr_peer_init_ref_id_debug(peer); 196 wlan_objmgr_peer_trace_init_lock(peer); 197 wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID); 198 /* set vdev to peer */ 199 wlan_peer_set_vdev(peer, vdev); 200 /* set peer type */ 201 wlan_peer_set_peer_type(peer, type); 202 /* set mac address of peer */ 203 wlan_peer_set_macaddr(peer, macaddr); 204 /* initialize peer state */ 205 wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE); 206 wlan_peer_mlme_reset_seq_num(peer); 207 peer->peer_objmgr.print_cnt = 0; 208 209 qdf_spinlock_create(&peer->peer_lock); 210 /* Attach peer to psoc, psoc maintains the node table for the device */ 211 if (wlan_objmgr_psoc_peer_attach(psoc, peer) != 212 QDF_STATUS_SUCCESS) { 213 obj_mgr_warn( 214 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure", 215 macaddr[0], macaddr[1], macaddr[2], 216 macaddr[3], macaddr[4], macaddr[5]); 217 qdf_spinlock_destroy(&peer->peer_lock); 218 wlan_objmgr_peer_trace_deinit_lock(peer); 219 qdf_mem_free(peer); 220 return NULL; 221 } 222 /* Attach peer to vdev peer table */ 223 if (wlan_objmgr_vdev_peer_attach(vdev, peer) != 224 QDF_STATUS_SUCCESS) { 225 obj_mgr_warn( 226 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure", 227 macaddr[0], macaddr[1], macaddr[2], 228 macaddr[3], macaddr[4], macaddr[5]); 229 /* if attach fails, detach from psoc table before free */ 230 wlan_objmgr_psoc_peer_detach(psoc, peer); 231 qdf_spinlock_destroy(&peer->peer_lock); 232 wlan_objmgr_peer_trace_deinit_lock(peer); 233 qdf_mem_free(peer); 234 return NULL; 235 } 236 wlan_peer_set_pdev_id(peer, wlan_objmgr_pdev_get_pdev_id( 237 wlan_vdev_get_pdev(vdev))); 238 /* Increment ref count for BSS peer, so that BSS peer deletes last*/ 239 if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP) 240 || (type == WLAN_PEER_P2P_CLI)) 241 wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev), 242 WLAN_OBJMGR_ID); 243 /* TODO init other parameters */ 244 /* Invoke registered create handlers */ 245 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 246 handler = g_umac_glb_obj->peer_create_handler[id]; 247 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 248 if (handler) 249 peer->obj_status[id] = handler(peer, arg); 250 else 251 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 252 } 253 /* derive the object status */ 254 obj_status = wlan_objmgr_peer_object_status(peer); 255 /* If SUCCESS, Object is created */ 256 if (obj_status == QDF_STATUS_SUCCESS) { 257 peer->obj_state = WLAN_OBJ_STATE_CREATED; 258 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 259 stat_handler = g_umac_glb_obj->peer_status_handler[id]; 260 arg = g_umac_glb_obj->peer_status_handler_arg[id]; 261 if (stat_handler) 262 stat_handler(peer, arg, 263 QDF_STATUS_SUCCESS); 264 } 265 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 266 /* If any component operates in different context, update it 267 as partially created */ 268 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 269 } else if (obj_status == QDF_STATUS_E_FAILURE) { 270 /* Clean up the peer */ 271 obj_mgr_err( 272 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail", 273 macaddr[0], macaddr[1], macaddr[2], 274 macaddr[3], macaddr[4], macaddr[5]); 275 wlan_objmgr_peer_obj_delete(peer); 276 return NULL; 277 } 278 279 obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR " type %d", 280 QDF_MAC_ADDR_ARRAY(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_STR, 302 QDF_MAC_ADDR_ARRAY(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_STR, peer->obj_state, 307 QDF_MAC_ADDR_ARRAY(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_STR, 354 QDF_MAC_ADDR_ARRAY(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(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d", 624 macaddr[0], macaddr[1], macaddr[2], 625 macaddr[3], macaddr[4], macaddr[5], 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_STR ") not in Created st(%d)", 730 QDF_MAC_ADDR_ARRAY(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_STR ") not in Created st(%d)", 763 QDF_MAC_ADDR_ARRAY(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(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0", 1194 macaddr[0], macaddr[1], macaddr[2], 1195 macaddr[3], macaddr[4], macaddr[5]); 1196 WLAN_OBJMGR_BUG(0); 1197 return; 1198 } 1199 1200 status = wlan_objmgr_peer_release_debug_id_ref(peer, id); 1201 if (QDF_IS_STATUS_ERROR(status)) 1202 return; 1203 1204 wlan_objmgr_peer_deref_trace(peer, id, func, line); 1205 /* Provide synchronization from the access to add peer 1206 * to logically deleted peer list. 1207 */ 1208 wlan_peer_obj_lock(peer); 1209 /* Decrement ref count, free peer object, if ref count == 0 */ 1210 if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { 1211 wlan_peer_obj_unlock(peer); 1212 wlan_objmgr_peer_obj_destroy(peer); 1213 } else { 1214 wlan_peer_obj_unlock(peer); 1215 } 1216 1217 return; 1218 } 1219 1220 qdf_export_symbol(wlan_objmgr_peer_release_ref_debug); 1221 #else 1222 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, 1223 wlan_objmgr_ref_dbgid id) 1224 { 1225 QDF_STATUS status; 1226 1227 if (!peer) { 1228 obj_mgr_err("peer obj is NULL for %d", id); 1229 QDF_ASSERT(0); 1230 return; 1231 } 1232 1233 if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { 1234 uint8_t *macaddr; 1235 1236 macaddr = wlan_peer_get_macaddr(peer); 1237 obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0", 1238 macaddr[0], macaddr[1], macaddr[2], 1239 macaddr[3], macaddr[4], macaddr[5]); 1240 WLAN_OBJMGR_BUG(0); 1241 return; 1242 } 1243 1244 status = wlan_objmgr_peer_release_debug_id_ref(peer, id); 1245 if (QDF_IS_STATUS_ERROR(status)) 1246 return; 1247 1248 /* Provide synchronization from the access to add peer 1249 * to logically deleted peer list. 1250 */ 1251 wlan_peer_obj_lock(peer); 1252 /* Decrement ref count, free peer object, if ref count == 0 */ 1253 if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { 1254 wlan_peer_obj_unlock(peer); 1255 wlan_objmgr_peer_obj_destroy(peer); 1256 } else { 1257 wlan_peer_obj_unlock(peer); 1258 } 1259 } 1260 1261 qdf_export_symbol(wlan_objmgr_peer_release_ref); 1262 #endif 1263 1264 #ifdef WLAN_OBJMGR_REF_ID_DEBUG 1265 void 1266 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer, 1267 QDF_TRACE_LEVEL log_level) 1268 { 1269 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg, log_level); 1270 } 1271 1272 uint32_t 1273 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, 1274 enum wlan_umac_comp_id id) 1275 { 1276 return qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id]); 1277 } 1278 #else 1279 void 1280 wlan_objmgr_print_peer_ref_ids(struct wlan_objmgr_peer *peer, 1281 QDF_TRACE_LEVEL log_level) 1282 { 1283 uint32_t pending_ref; 1284 1285 pending_ref = qdf_atomic_read(&peer->peer_objmgr.ref_cnt); 1286 obj_mgr_log_level(log_level, "Pending refs -- %d", pending_ref); 1287 } 1288 1289 uint32_t 1290 wlan_objmgr_peer_get_comp_ref_cnt(struct wlan_objmgr_peer *peer, 1291 enum wlan_umac_comp_id id) 1292 { 1293 return 0; 1294 } 1295 #endif 1296