1 /* 2 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /** 19 * DOC: Public APIs to perform operations on 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 "wlan_objmgr_global_obj_i.h" 29 #include "wlan_objmgr_psoc_obj_i.h" 30 #include "wlan_objmgr_pdev_obj_i.h" 31 #include "wlan_objmgr_vdev_obj_i.h" 32 33 34 /** 35 ** APIs to Create/Delete Peer object APIs 36 */ 37 static QDF_STATUS wlan_objmgr_peer_object_status( 38 struct wlan_objmgr_peer *peer) 39 { 40 uint8_t id; 41 QDF_STATUS status = QDF_STATUS_SUCCESS; 42 43 wlan_peer_obj_lock(peer); 44 /* Iterate through all components to derive the object status */ 45 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 46 /* If component disabled, Ignore */ 47 if (peer->obj_status[id] == QDF_STATUS_COMP_DISABLED) 48 continue; 49 /* If component operates in Async, status is Partially created, 50 break */ 51 else if (peer->obj_status[id] == QDF_STATUS_COMP_ASYNC) { 52 if (peer->peer_comp_priv_obj[id] == NULL) { 53 status = QDF_STATUS_COMP_ASYNC; 54 break; 55 } 56 /* If component failed to allocate its object, treat it as 57 failure, complete object need to be cleaned up */ 58 } else if ((peer->obj_status[id] == QDF_STATUS_E_NOMEM) || 59 (peer->obj_status[id] == QDF_STATUS_E_FAILURE)) { 60 obj_mgr_err("Peer comp object(id:%d) alloc fail", id); 61 status = QDF_STATUS_E_FAILURE; 62 break; 63 } 64 } 65 wlan_peer_obj_unlock(peer); 66 return status; 67 } 68 69 static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer) 70 { 71 struct wlan_objmgr_psoc *psoc; 72 struct wlan_objmgr_vdev *vdev; 73 uint8_t *macaddr; 74 uint8_t vdev_id; 75 76 if (peer == NULL) { 77 obj_mgr_err("PEER is NULL"); 78 return QDF_STATUS_E_FAILURE; 79 } 80 81 macaddr = wlan_peer_get_macaddr(peer); 82 83 vdev = wlan_peer_get_vdev(peer); 84 if (vdev == NULL) { 85 obj_mgr_err( 86 "VDEV is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", 87 macaddr[0], macaddr[1], macaddr[2], 88 macaddr[3], macaddr[4], macaddr[5]); 89 return QDF_STATUS_E_FAILURE; 90 } 91 92 vdev_id = wlan_vdev_get_id(vdev); 93 94 /* get PSOC from VDEV, if it is NULL, return */ 95 psoc = wlan_vdev_get_psoc(vdev); 96 if (psoc == NULL) { 97 obj_mgr_err( 98 "PSOC is NULL for peer(%02x:%02x:%02x:%02x:%02x:%02x)", 99 macaddr[0], macaddr[1], macaddr[2], 100 macaddr[3], macaddr[4], macaddr[5]); 101 return QDF_STATUS_E_FAILURE; 102 } 103 104 /* Decrement ref count for BSS peer, so that BSS peer deletes last*/ 105 if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) || 106 (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP)) 107 wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev), 108 WLAN_OBJMGR_ID); 109 110 /* Detach peer from VDEV's peer list */ 111 if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) { 112 obj_mgr_err( 113 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d", 114 macaddr[0], macaddr[1], macaddr[2], 115 macaddr[3], macaddr[4], macaddr[5], vdev_id); 116 return QDF_STATUS_E_FAILURE; 117 } 118 /* Detach peer from PSOC's peer list */ 119 if (wlan_objmgr_psoc_peer_detach(psoc, peer) == QDF_STATUS_E_FAILURE) { 120 obj_mgr_err( 121 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure", 122 macaddr[0], macaddr[1], macaddr[2], 123 macaddr[3], macaddr[4], macaddr[5]); 124 return QDF_STATUS_E_FAILURE; 125 } 126 qdf_spinlock_destroy(&peer->peer_lock); 127 qdf_mem_free(peer); 128 129 return QDF_STATUS_SUCCESS; 130 131 } 132 133 struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create( 134 struct wlan_objmgr_vdev *vdev, 135 enum wlan_peer_type type, 136 uint8_t *macaddr) 137 { 138 struct wlan_objmgr_peer *peer; 139 struct wlan_objmgr_psoc *psoc; 140 wlan_objmgr_peer_create_handler handler; 141 wlan_objmgr_peer_status_handler stat_handler; 142 void *arg; 143 QDF_STATUS obj_status; 144 uint8_t id; 145 146 if (vdev == NULL) { 147 obj_mgr_err( 148 "VDEV is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", 149 macaddr[0], macaddr[1], macaddr[2], 150 macaddr[3], macaddr[4], macaddr[5]); 151 return NULL; 152 } 153 /* Get psoc, if psoc is NULL, return */ 154 psoc = wlan_vdev_get_psoc(vdev); 155 if (psoc == NULL) { 156 obj_mgr_err( 157 "PSOC is NULL for peer (%02x:%02x:%02x:%02x:%02x:%02x)", 158 macaddr[0], macaddr[1], macaddr[2], 159 macaddr[3], macaddr[4], macaddr[5]); 160 return NULL; 161 } 162 /* Allocate memory for peer object */ 163 peer = qdf_mem_malloc(sizeof(*peer)); 164 if (peer == NULL) { 165 obj_mgr_err( 166 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) allocation failure", 167 macaddr[0], macaddr[1], macaddr[2], 168 macaddr[3], macaddr[4], macaddr[5]); 169 return NULL; 170 } 171 peer->obj_state = WLAN_OBJ_STATE_ALLOCATED; 172 qdf_atomic_init(&peer->peer_objmgr.ref_cnt); 173 for (id = 0; id < WLAN_REF_ID_MAX; id++) 174 qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]); 175 wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID); 176 /* set vdev to peer */ 177 wlan_peer_set_vdev(peer, vdev); 178 /* set peer type */ 179 wlan_peer_set_peer_type(peer, type); 180 /* set mac address of peer */ 181 wlan_peer_set_macaddr(peer, macaddr); 182 /* initialize peer state */ 183 wlan_peer_mlme_set_state(peer, WLAN_INIT_STATE); 184 wlan_peer_mlme_reset_seq_num(peer); 185 peer->peer_objmgr.print_cnt = 0; 186 187 qdf_spinlock_create(&peer->peer_lock); 188 /* Attach peer to psoc, psoc maintains the node table for the device */ 189 if (wlan_objmgr_psoc_peer_attach(psoc, peer) != 190 QDF_STATUS_SUCCESS) { 191 obj_mgr_warn( 192 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC attach failure", 193 macaddr[0], macaddr[1], macaddr[2], 194 macaddr[3], macaddr[4], macaddr[5]); 195 qdf_spinlock_destroy(&peer->peer_lock); 196 qdf_mem_free(peer); 197 return NULL; 198 } 199 /* Attach peer to vdev peer table */ 200 if (wlan_objmgr_vdev_peer_attach(vdev, peer) != 201 QDF_STATUS_SUCCESS) { 202 obj_mgr_warn( 203 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV attach failure", 204 macaddr[0], macaddr[1], macaddr[2], 205 macaddr[3], macaddr[4], macaddr[5]); 206 /* if attach fails, detach from psoc table before free */ 207 wlan_objmgr_psoc_peer_detach(psoc, peer); 208 qdf_spinlock_destroy(&peer->peer_lock); 209 qdf_mem_free(peer); 210 return NULL; 211 } 212 /* Increment ref count for BSS peer, so that BSS peer deletes last*/ 213 if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP) 214 || (type == WLAN_PEER_P2P_CLI)) 215 wlan_objmgr_peer_get_ref(wlan_vdev_get_bsspeer(vdev), 216 WLAN_OBJMGR_ID); 217 /* TODO init other parameters */ 218 /* Invoke registered create handlers */ 219 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 220 handler = g_umac_glb_obj->peer_create_handler[id]; 221 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 222 if (handler != NULL) 223 peer->obj_status[id] = handler(peer, arg); 224 else 225 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 226 } 227 /* derive the object status */ 228 obj_status = wlan_objmgr_peer_object_status(peer); 229 /* If SUCCESS, Object is created */ 230 if (obj_status == QDF_STATUS_SUCCESS) { 231 peer->obj_state = WLAN_OBJ_STATE_CREATED; 232 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 233 stat_handler = g_umac_glb_obj->peer_status_handler[id]; 234 arg = g_umac_glb_obj->peer_status_handler_arg[id]; 235 if (stat_handler != NULL) 236 stat_handler(peer, arg, 237 QDF_STATUS_SUCCESS); 238 } 239 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 240 /* If any component operates in different context, update it 241 as partially created */ 242 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 243 } else if (obj_status == QDF_STATUS_E_FAILURE) { 244 /* Clean up the peer */ 245 obj_mgr_err( 246 "Peer(%02x:%02x:%02x:%02x:%02x:%02x) comp object alloc fail", 247 macaddr[0], macaddr[1], macaddr[2], 248 macaddr[3], macaddr[4], macaddr[5]); 249 wlan_objmgr_peer_obj_delete(peer); 250 return NULL; 251 } 252 253 obj_mgr_debug("Created peer " QDF_MAC_ADDR_STR, 254 QDF_MAC_ADDR_ARRAY(macaddr)); 255 256 return peer; 257 } 258 259 static QDF_STATUS wlan_objmgr_peer_obj_destroy(struct wlan_objmgr_peer *peer) 260 { 261 uint8_t id; 262 wlan_objmgr_peer_destroy_handler handler; 263 QDF_STATUS obj_status; 264 void *arg; 265 uint8_t *macaddr; 266 267 if (peer == NULL) { 268 obj_mgr_err("PEER is NULL"); 269 return QDF_STATUS_E_FAILURE; 270 } 271 272 macaddr = wlan_peer_get_macaddr(peer); 273 274 obj_mgr_debug("Physically deleting peer " QDF_MAC_ADDR_STR, 275 QDF_MAC_ADDR_ARRAY(macaddr)); 276 277 if (peer->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { 278 obj_mgr_err( 279 "peer(%02x:%02x:%02x:%02x:%02x:%02x) object del is not invoked", 280 macaddr[0], macaddr[1], macaddr[2], 281 macaddr[3], macaddr[4], macaddr[5]); 282 WLAN_OBJMGR_BUG(0); 283 } 284 285 /* Invoke registered destroy handlers */ 286 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 287 handler = g_umac_glb_obj->peer_destroy_handler[id]; 288 arg = g_umac_glb_obj->peer_destroy_handler_arg[id]; 289 if (handler != NULL) 290 peer->obj_status[id] = handler(peer, arg); 291 else 292 peer->obj_status[id] = QDF_STATUS_COMP_DISABLED; 293 } 294 /* Derive the object status */ 295 obj_status = wlan_objmgr_peer_object_status(peer); 296 if (obj_status == QDF_STATUS_E_FAILURE) { 297 /* If it status is failure, memory will not be freed */ 298 QDF_BUG(0); 299 return QDF_STATUS_E_FAILURE; 300 } 301 /* few components deletion is in progress */ 302 if (obj_status == QDF_STATUS_COMP_ASYNC) { 303 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED; 304 return QDF_STATUS_COMP_ASYNC; 305 } 306 307 /* Free the peer object */ 308 return wlan_objmgr_peer_obj_free(peer); 309 } 310 311 QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer) 312 { 313 uint8_t print_idx; 314 uint8_t *macaddr; 315 316 if (peer == NULL) { 317 obj_mgr_err("PEER is NULL"); 318 return QDF_STATUS_E_FAILURE; 319 } 320 321 wlan_peer_obj_lock(peer); 322 macaddr = wlan_peer_get_macaddr(peer); 323 wlan_peer_obj_unlock(peer); 324 325 obj_mgr_debug("Logically deleting peer " QDF_MAC_ADDR_STR, 326 QDF_MAC_ADDR_ARRAY(macaddr)); 327 328 print_idx = qdf_get_pidx(); 329 if (qdf_print_is_verbose_enabled(print_idx, QDF_MODULE_ID_OBJ_MGR, 330 QDF_TRACE_LEVEL_DEBUG)) { 331 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg); 332 } 333 334 /** 335 * Update VDEV object state to LOGICALLY DELETED 336 * It prevents further access of this object 337 */ 338 wlan_peer_obj_lock(peer); 339 peer->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED; 340 wlan_peer_obj_unlock(peer); 341 wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID); 342 343 return QDF_STATUS_SUCCESS; 344 } 345 EXPORT_SYMBOL(wlan_objmgr_peer_obj_delete); 346 /** 347 ** APIs to attach/detach component objects 348 */ 349 QDF_STATUS wlan_objmgr_peer_component_obj_attach( 350 struct wlan_objmgr_peer *peer, 351 enum wlan_umac_comp_id id, 352 void *comp_priv_obj, 353 QDF_STATUS status) 354 { 355 wlan_objmgr_peer_status_handler s_hler; 356 void *arg; 357 uint8_t i; 358 QDF_STATUS obj_status; 359 360 /* component id is invalid */ 361 if (id >= WLAN_UMAC_MAX_COMPONENTS) 362 return QDF_STATUS_MAXCOMP_FAIL; 363 364 wlan_peer_obj_lock(peer); 365 /* If there is a valid entry, return failure, 366 valid object needs to be freed first */ 367 if (peer->peer_comp_priv_obj[id] != NULL) { 368 wlan_peer_obj_unlock(peer); 369 return QDF_STATUS_E_FAILURE; 370 } 371 /* Assign component object private pointer(can be NULL also), status */ 372 peer->peer_comp_priv_obj[id] = comp_priv_obj; 373 peer->obj_status[id] = status; 374 wlan_peer_obj_unlock(peer); 375 376 if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED) 377 return QDF_STATUS_SUCCESS; 378 379 /* If PEER object status is partially created means, this API is 380 invoked with differnt context. this block should be executed for async 381 components only */ 382 /* Derive status */ 383 obj_status = wlan_objmgr_peer_object_status(peer); 384 /* STATUS_SUCCESS means, object is CREATED */ 385 if (obj_status == QDF_STATUS_SUCCESS) 386 peer->obj_state = WLAN_OBJ_STATE_CREATED; 387 /* update state as CREATION failed, caller has to delete the 388 PEER object */ 389 else if (obj_status == QDF_STATUS_E_FAILURE) 390 peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED; 391 /* Notify components about the CREATION success/failure */ 392 if ((obj_status == QDF_STATUS_SUCCESS) || 393 (obj_status == QDF_STATUS_E_FAILURE)) { 394 /* nofity object status */ 395 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 396 s_hler = g_umac_glb_obj->peer_status_handler[i]; 397 arg = g_umac_glb_obj->peer_status_handler_arg[i]; 398 if (s_hler != NULL) 399 s_hler(peer, arg, obj_status); 400 } 401 } 402 return QDF_STATUS_SUCCESS; 403 } 404 405 QDF_STATUS wlan_objmgr_peer_component_obj_detach( 406 struct wlan_objmgr_peer *peer, 407 enum wlan_umac_comp_id id, 408 void *comp_priv_obj) 409 { 410 QDF_STATUS obj_status; 411 412 /* component id is invalid */ 413 if (id >= WLAN_UMAC_MAX_COMPONENTS) 414 return QDF_STATUS_MAXCOMP_FAIL; 415 416 wlan_peer_obj_lock(peer); 417 /* If there is a invalid entry, return failure */ 418 if (peer->peer_comp_priv_obj[id] != comp_priv_obj) { 419 peer->obj_status[id] = QDF_STATUS_E_FAILURE; 420 wlan_peer_obj_unlock(peer); 421 return QDF_STATUS_E_FAILURE; 422 } 423 /* Reset the pointer to NULL */ 424 peer->peer_comp_priv_obj[id] = NULL; 425 peer->obj_status[id] = QDF_STATUS_SUCCESS; 426 wlan_peer_obj_unlock(peer); 427 428 /* If PEER object status is partially destroyed means, this API is 429 invoked with differnt context, this block should be executed for async 430 components only */ 431 if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) || 432 (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) { 433 /* Derive object status */ 434 obj_status = wlan_objmgr_peer_object_status(peer); 435 if (obj_status == QDF_STATUS_SUCCESS) { 436 /*Update the status as Deleted, if full object 437 deletion is in progress */ 438 if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 439 peer->obj_state = WLAN_OBJ_STATE_DELETED; 440 /* Move to creation state, since this component 441 deletion alone requested */ 442 if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 443 peer->obj_state = WLAN_OBJ_STATE_CREATED; 444 /* Object status is failure */ 445 } else if (obj_status == QDF_STATUS_E_FAILURE) { 446 /*Update the status as Deletion failed, if full object 447 deletion is in progress */ 448 if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 449 peer->obj_state = 450 WLAN_OBJ_STATE_DELETION_FAILED; 451 /* Move to creation state, since this component 452 deletion alone requested (do not block other 453 components) */ 454 if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 455 peer->obj_state = WLAN_OBJ_STATE_CREATED; 456 } 457 458 /* Delete peer object */ 459 if ((obj_status == QDF_STATUS_SUCCESS) && 460 (peer->obj_state == WLAN_OBJ_STATE_DELETED)) { 461 /* Free the peer object */ 462 return wlan_objmgr_peer_obj_free(peer); 463 } 464 } 465 466 return QDF_STATUS_SUCCESS; 467 } 468 469 470 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_creation( 471 struct wlan_objmgr_peer *peer, 472 enum wlan_umac_comp_id id) 473 { 474 wlan_objmgr_peer_create_handler handler; 475 void *arg; 476 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 477 478 /* Component id is invalid */ 479 if (id >= WLAN_UMAC_MAX_COMPONENTS) 480 return QDF_STATUS_MAXCOMP_FAIL; 481 482 wlan_peer_obj_lock(peer); 483 /* If component object is already created, delete old 484 component object, then invoke creation */ 485 if (peer->peer_comp_priv_obj[id] != NULL) { 486 wlan_peer_obj_unlock(peer); 487 return QDF_STATUS_E_FAILURE; 488 } 489 wlan_peer_obj_unlock(peer); 490 491 /* Invoke registered create handlers */ 492 handler = g_umac_glb_obj->peer_create_handler[id]; 493 arg = g_umac_glb_obj->peer_create_handler_arg[id]; 494 if (handler != NULL) 495 peer->obj_status[id] = handler(peer, arg); 496 else 497 return QDF_STATUS_E_FAILURE; 498 499 /* If object status is created, then only handle this object status */ 500 if (peer->obj_state == WLAN_OBJ_STATE_CREATED) { 501 /* Derive object status */ 502 obj_status = wlan_objmgr_peer_object_status(peer); 503 /* Move PDEV object state to Partially created state */ 504 if (obj_status == QDF_STATUS_COMP_ASYNC) { 505 /*TODO atomic */ 506 peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 507 } 508 } 509 510 return obj_status; 511 } 512 513 514 QDF_STATUS wlan_objmgr_trigger_peer_comp_priv_object_deletion( 515 struct wlan_objmgr_peer *peer, 516 enum wlan_umac_comp_id id) 517 { 518 wlan_objmgr_peer_destroy_handler handler; 519 void *arg; 520 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 521 522 /* component id is invalid */ 523 if (id >= WLAN_UMAC_MAX_COMPONENTS) 524 return QDF_STATUS_MAXCOMP_FAIL; 525 526 wlan_peer_obj_lock(peer); 527 /* Component object was never created, invalid operation */ 528 if (peer->peer_comp_priv_obj[id] == NULL) { 529 wlan_peer_obj_unlock(peer); 530 return QDF_STATUS_E_FAILURE; 531 } 532 533 wlan_peer_obj_unlock(peer); 534 535 /* Invoke registered destroy handlers */ 536 handler = g_umac_glb_obj->peer_destroy_handler[id]; 537 arg = g_umac_glb_obj->peer_destroy_handler_arg[id]; 538 if (handler != NULL) 539 peer->obj_status[id] = handler(peer, arg); 540 else 541 return QDF_STATUS_E_FAILURE; 542 543 /* If object status is created, then only handle this object status */ 544 if (peer->obj_state == WLAN_OBJ_STATE_CREATED) { 545 obj_status = wlan_objmgr_peer_object_status(peer); 546 /* move object state to DEL progress */ 547 if (obj_status == QDF_STATUS_COMP_ASYNC) 548 peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS; 549 } 550 return obj_status; 551 } 552 553 void *wlan_objmgr_peer_get_comp_private_obj( 554 struct wlan_objmgr_peer *peer, 555 enum wlan_umac_comp_id id) 556 { 557 void *comp_priv_obj; 558 559 /* component id is invalid */ 560 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 561 QDF_BUG(0); 562 return NULL; 563 } 564 565 if (peer == NULL) { 566 QDF_BUG(0); 567 return NULL; 568 } 569 570 comp_priv_obj = peer->peer_comp_priv_obj[id]; 571 return comp_priv_obj; 572 } 573 EXPORT_SYMBOL(wlan_objmgr_peer_get_comp_private_obj); 574 575 void wlan_objmgr_peer_get_ref(struct wlan_objmgr_peer *peer, 576 wlan_objmgr_ref_dbgid id) 577 { 578 if (peer == NULL) { 579 obj_mgr_err("peer obj is NULL for %d", id); 580 QDF_ASSERT(0); 581 return; 582 } 583 /* Increment ref count */ 584 qdf_atomic_inc(&peer->peer_objmgr.ref_cnt); 585 qdf_atomic_inc(&peer->peer_objmgr.ref_id_dbg[id]); 586 587 return; 588 } 589 EXPORT_SYMBOL(wlan_objmgr_peer_get_ref); 590 591 QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer, 592 wlan_objmgr_ref_dbgid id) 593 { 594 595 uint8_t *macaddr; 596 597 if (peer == NULL) { 598 obj_mgr_err("peer obj is NULL for %d", id); 599 QDF_ASSERT(0); 600 return QDF_STATUS_E_FAILURE; 601 } 602 603 wlan_peer_obj_lock(peer); 604 macaddr = wlan_peer_get_macaddr(peer); 605 if (peer->obj_state != WLAN_OBJ_STATE_CREATED) { 606 wlan_peer_obj_unlock(peer); 607 if (peer->peer_objmgr.print_cnt++ <= 608 WLAN_OBJMGR_RATELIMIT_THRESH) 609 obj_mgr_warn( 610 "peer(" QDF_MAC_ADDR_STR ") not in Created st(%d)", 611 QDF_MAC_ADDR_ARRAY(macaddr), 612 peer->obj_state); 613 return QDF_STATUS_E_RESOURCES; 614 } 615 616 wlan_objmgr_peer_get_ref(peer, id); 617 wlan_peer_obj_unlock(peer); 618 619 return QDF_STATUS_SUCCESS; 620 } 621 EXPORT_SYMBOL(wlan_objmgr_peer_try_get_ref); 622 623 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer, 624 wlan_objmgr_ref_dbgid id) 625 { 626 627 uint8_t *macaddr; 628 629 if (peer == NULL) { 630 obj_mgr_err("peer obj is NULL for %d", id); 631 QDF_ASSERT(0); 632 return; 633 } 634 635 macaddr = wlan_peer_get_macaddr(peer); 636 637 if (!qdf_atomic_read(&peer->peer_objmgr.ref_id_dbg[id])) { 638 obj_mgr_err( 639 "peer(%02x:%02x:%02x:%02x:%02x:%02x) ref was not taken by %d", 640 macaddr[0], macaddr[1], macaddr[2], 641 macaddr[3], macaddr[4], macaddr[5], id); 642 wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg); 643 WLAN_OBJMGR_BUG(0); 644 } 645 646 if (!qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { 647 obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) ref cnt is 0", 648 macaddr[0], macaddr[1], macaddr[2], 649 macaddr[3], macaddr[4], macaddr[5]); 650 WLAN_OBJMGR_BUG(0); 651 return; 652 } 653 qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]); 654 655 /* Provide synchronization from the access to add peer 656 * to logically deleted peer list. 657 */ 658 wlan_peer_obj_lock(peer); 659 /* Decrement ref count, free peer object, if ref count == 0 */ 660 if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt)) { 661 wlan_peer_obj_unlock(peer); 662 wlan_objmgr_peer_obj_destroy(peer); 663 } else { 664 wlan_peer_obj_unlock(peer); 665 } 666 667 return; 668 } 669 EXPORT_SYMBOL(wlan_objmgr_peer_release_ref); 670