1 /* 2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 /** 18 * DOC: Public APIs to perform operations on Global objects 19 */ 20 #include <wlan_objmgr_cmn.h> 21 #include <wlan_objmgr_global_obj.h> 22 #include <wlan_objmgr_psoc_obj.h> 23 #include <wlan_objmgr_pdev_obj.h> 24 #include <wlan_objmgr_vdev_obj.h> 25 #include <wlan_objmgr_peer_obj.h> 26 #include <wlan_objmgr_debug.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 #include <wlan_utility.h> 34 #include <wlan_osif_priv.h> 35 #include "cdp_txrx_cmn.h" 36 37 /* 38 * APIs to Create/Delete Global object APIs 39 */ 40 wlan_objmgr_vdev_object_status(struct wlan_objmgr_vdev * vdev)41 static QDF_STATUS wlan_objmgr_vdev_object_status( 42 struct wlan_objmgr_vdev *vdev) 43 { 44 uint8_t id; 45 QDF_STATUS status = QDF_STATUS_SUCCESS; 46 47 wlan_vdev_obj_lock(vdev); 48 49 /* Iterate through all components to derive the object status */ 50 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 51 /* If component disabled, Ignore */ 52 if (vdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) { 53 continue; 54 /* 55 * If component operates in Async, status is Partially created, 56 * break 57 */ 58 } else if (vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) { 59 if (!vdev->vdev_comp_priv_obj[id]) { 60 status = QDF_STATUS_COMP_ASYNC; 61 break; 62 } 63 /* 64 * If component failed to allocate its object, treat it as 65 * failure, complete object need to be cleaned up 66 */ 67 } else if ((vdev->obj_status[id] == QDF_STATUS_E_NOMEM) || 68 (vdev->obj_status[id] == QDF_STATUS_E_FAILURE)) { 69 status = QDF_STATUS_E_FAILURE; 70 break; 71 } 72 } 73 wlan_vdev_obj_unlock(vdev); 74 75 return status; 76 } 77 wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev * vdev)78 static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev) 79 { 80 struct wlan_objmgr_pdev *pdev; 81 struct wlan_objmgr_psoc *psoc; 82 83 if (!vdev) { 84 obj_mgr_err("vdev is NULL"); 85 return QDF_STATUS_E_FAILURE; 86 } 87 /* if PDEV is NULL, return */ 88 pdev = wlan_vdev_get_pdev(vdev); 89 if (!pdev) { 90 obj_mgr_err("pdev is NULL for vdev-id: %d", 91 vdev->vdev_objmgr.vdev_id); 92 return QDF_STATUS_E_FAILURE; 93 } 94 psoc = wlan_pdev_get_psoc(pdev); 95 if (!psoc) { 96 obj_mgr_err("psoc is NULL in pdev"); 97 return QDF_STATUS_E_FAILURE; 98 } 99 100 /* Detach VDEV from PDEV VDEV's list */ 101 if (wlan_objmgr_pdev_vdev_detach(pdev, vdev) == 102 QDF_STATUS_E_FAILURE) 103 return QDF_STATUS_E_FAILURE; 104 105 /* Detach VDEV from PSOC VDEV's list */ 106 if (wlan_objmgr_psoc_vdev_detach(psoc, vdev) == 107 QDF_STATUS_E_FAILURE) 108 return QDF_STATUS_E_FAILURE; 109 110 wlan_objmgr_vdev_trace_del_ref_list(vdev); 111 wlan_objmgr_vdev_trace_deinit_lock(vdev); 112 qdf_spinlock_destroy(&vdev->vdev_lock); 113 114 wlan_destroy_vdev_mlo_lock(vdev); 115 116 qdf_mem_free(vdev->vdev_mlme.bss_chan); 117 qdf_mem_free(vdev->vdev_mlme.des_chan); 118 qdf_mem_free(vdev); 119 120 return QDF_STATUS_SUCCESS; 121 122 } 123 wlan_objmgr_vdev_get_osif_priv(struct wlan_objmgr_vdev * vdev)124 static struct vdev_osif_priv *wlan_objmgr_vdev_get_osif_priv( 125 struct wlan_objmgr_vdev *vdev) 126 { 127 struct vdev_osif_priv *osif_priv; 128 129 /* private data area immediately follows the struct wlan_objmgr_vdev */ 130 osif_priv = (struct vdev_osif_priv *)(vdev + 1); 131 132 return osif_priv; 133 } 134 wlan_objmgr_vdev_obj_create(struct wlan_objmgr_pdev * pdev,struct wlan_vdev_create_params * params)135 struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( 136 struct wlan_objmgr_pdev *pdev, 137 struct wlan_vdev_create_params *params) 138 { 139 struct wlan_objmgr_vdev *vdev; 140 struct wlan_objmgr_psoc *psoc; 141 uint8_t id; 142 wlan_objmgr_vdev_create_handler handler; 143 wlan_objmgr_vdev_status_handler stat_handler; 144 void *arg; 145 QDF_STATUS obj_status; 146 147 if (!pdev) { 148 obj_mgr_err("pdev is NULL"); 149 return NULL; 150 } 151 psoc = wlan_pdev_get_psoc(pdev); 152 /* PSOC is NULL */ 153 if (!psoc) { 154 obj_mgr_err("psoc is NULL for pdev-id:%d", 155 pdev->pdev_objmgr.wlan_pdev_id); 156 return NULL; 157 } 158 /* Allocate vdev object memory */ 159 vdev = qdf_mem_malloc(sizeof(*vdev) + params->size_vdev_priv); 160 if (!vdev) 161 return NULL; 162 vdev->obj_state = WLAN_OBJ_STATE_ALLOCATED; 163 164 vdev->vdev_mlme.bss_chan = qdf_mem_malloc(sizeof(struct wlan_channel)); 165 if (!vdev->vdev_mlme.bss_chan) { 166 qdf_mem_free(vdev); 167 return NULL; 168 } 169 170 vdev->vdev_mlme.des_chan = qdf_mem_malloc(sizeof(struct wlan_channel)); 171 if (!vdev->vdev_mlme.des_chan) { 172 qdf_mem_free(vdev->vdev_mlme.bss_chan); 173 qdf_mem_free(vdev); 174 return NULL; 175 } 176 177 wlan_create_vdev_mlo_lock(vdev); 178 179 wlan_objmgr_vdev_trace_init_lock(vdev); 180 /* Initialize spinlock */ 181 qdf_spinlock_create(&vdev->vdev_lock); 182 /* Attach VDEV to PSOC VDEV's list */ 183 if (wlan_objmgr_psoc_vdev_attach(psoc, vdev) != 184 QDF_STATUS_SUCCESS) { 185 obj_mgr_err("psoc vdev attach failed for vdev-id:%d", 186 vdev->vdev_objmgr.vdev_id); 187 qdf_mem_free(vdev->vdev_mlme.bss_chan); 188 qdf_mem_free(vdev->vdev_mlme.des_chan); 189 wlan_destroy_vdev_mlo_lock(vdev); 190 qdf_spinlock_destroy(&vdev->vdev_lock); 191 wlan_objmgr_vdev_trace_deinit_lock(vdev); 192 qdf_mem_free(vdev); 193 return NULL; 194 } 195 /* Store pdev in vdev */ 196 wlan_vdev_set_pdev(vdev, pdev); 197 /* Attach vdev to PDEV */ 198 if (wlan_objmgr_pdev_vdev_attach(pdev, vdev) != 199 QDF_STATUS_SUCCESS) { 200 obj_mgr_err("pdev vdev attach failed for vdev-id:%d", 201 vdev->vdev_objmgr.vdev_id); 202 wlan_objmgr_psoc_vdev_detach(psoc, vdev); 203 qdf_mem_free(vdev->vdev_mlme.bss_chan); 204 qdf_mem_free(vdev->vdev_mlme.des_chan); 205 wlan_destroy_vdev_mlo_lock(vdev); 206 qdf_spinlock_destroy(&vdev->vdev_lock); 207 wlan_objmgr_vdev_trace_deinit_lock(vdev); 208 qdf_mem_free(vdev); 209 return NULL; 210 } 211 /* set opmode */ 212 wlan_vdev_mlme_set_opmode(vdev, params->opmode); 213 /* set MAC address */ 214 wlan_vdev_mlme_set_macaddr(vdev, params->macaddr); 215 /* set MAT address */ 216 wlan_vdev_mlme_set_mataddr(vdev, params->mataddr); 217 /* set MLD address */ 218 wlan_vdev_mlme_set_mldaddr(vdev, params->mldaddr); 219 /* set link address */ 220 wlan_vdev_mlme_set_linkaddr(vdev, params->macaddr); 221 /* Set create flags */ 222 vdev->vdev_objmgr.c_flags = params->flags; 223 /* store os-specific pointer */ 224 vdev->vdev_nif.osdev = wlan_objmgr_vdev_get_osif_priv(vdev); 225 226 /* peer count to 0 */ 227 vdev->vdev_objmgr.wlan_peer_count = 0; 228 wlan_objmgr_vdev_init_ml_peer_count(vdev); 229 qdf_atomic_init(&vdev->vdev_objmgr.ref_cnt); 230 vdev->vdev_objmgr.print_cnt = 0; 231 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); 232 /* Initialize max peer count based on opmode type */ 233 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) 234 vdev->vdev_objmgr.max_peer_count = WLAN_UMAC_MAX_STA_PEERS; 235 else 236 vdev->vdev_objmgr.max_peer_count = 237 wlan_pdev_get_max_peer_count(pdev); 238 239 wlan_vdev_init_skip_pumac_cnt(vdev); 240 if (params->legacy_osif) 241 vdev->vdev_nif.osdev->legacy_osif_priv = params->legacy_osif; 242 243 /* Initialize peer list */ 244 qdf_list_create(&vdev->vdev_objmgr.wlan_peer_list, 245 vdev->vdev_objmgr.max_peer_count + 246 WLAN_MAX_PDEV_TEMP_PEERS); 247 /* TODO init other parameters */ 248 249 /* Invoke registered create handlers */ 250 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 251 handler = g_umac_glb_obj->vdev_create_handler[id]; 252 arg = g_umac_glb_obj->vdev_create_handler_arg[id]; 253 if (handler) 254 vdev->obj_status[id] = handler(vdev, arg); 255 else 256 vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED; 257 } 258 259 /* Derive object status */ 260 obj_status = wlan_objmgr_vdev_object_status(vdev); 261 262 if (obj_status == QDF_STATUS_SUCCESS) { 263 /* Object status is SUCCESS, Object is created */ 264 vdev->obj_state = WLAN_OBJ_STATE_CREATED; 265 /* Invoke component registered status handlers */ 266 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) { 267 stat_handler = g_umac_glb_obj->vdev_status_handler[id]; 268 arg = g_umac_glb_obj->vdev_status_handler_arg[id]; 269 if (stat_handler) { 270 stat_handler(vdev, arg, 271 QDF_STATUS_SUCCESS); 272 } 273 } 274 /* 275 * Few components operates in Asynchrous communction, Object state 276 * partially created 277 */ 278 } else if (obj_status == QDF_STATUS_COMP_ASYNC) { 279 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 280 /* Component object failed to be created, clean up the object */ 281 } else if (obj_status == QDF_STATUS_E_FAILURE) { 282 /* Clean up the psoc */ 283 obj_mgr_err("VDEV comp objects creation failed for vdev-id:%d", 284 vdev->vdev_objmgr.vdev_id); 285 wlan_objmgr_vdev_obj_delete(vdev); 286 return NULL; 287 } 288 289 wlan_minidump_log(vdev, sizeof(*vdev), psoc, 290 WLAN_MD_OBJMGR_VDEV, "wlan_objmgr_vdev"); 291 292 obj_mgr_debug("Created vdev %d", vdev->vdev_objmgr.vdev_id); 293 294 obj_status = wlan_objmgr_vdev_mlo_dev_ctxt_attach(vdev); 295 if (obj_status != QDF_STATUS_SUCCESS) 296 return NULL; 297 298 return vdev; 299 } 300 qdf_export_symbol(wlan_objmgr_vdev_obj_create); 301 wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev * vdev)302 static QDF_STATUS wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev *vdev) 303 { 304 int8_t id; 305 wlan_objmgr_vdev_destroy_handler handler; 306 QDF_STATUS obj_status; 307 void *arg; 308 uint8_t vdev_id; 309 struct wlan_objmgr_psoc *psoc = NULL; 310 311 if (!vdev) { 312 obj_mgr_err("vdev is NULL"); 313 return QDF_STATUS_E_FAILURE; 314 } 315 316 psoc = wlan_vdev_get_psoc(vdev); 317 if (!psoc) { 318 obj_mgr_err("Failed to get psoc"); 319 return QDF_STATUS_E_FAILURE; 320 } 321 322 wlan_objmgr_notify_destroy(vdev, WLAN_VDEV_OP); 323 324 vdev_id = wlan_vdev_get_id(vdev); 325 326 obj_mgr_debug("Physically deleting vdev %d", vdev_id); 327 328 if (vdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) { 329 obj_mgr_alert("VDEV object delete is not invoked vdevid:%d objstate:%d", 330 wlan_vdev_get_id(vdev), vdev->obj_state); 331 WLAN_OBJMGR_BUG(0); 332 return QDF_STATUS_E_FAILURE; 333 } 334 335 wlan_minidump_remove(vdev, sizeof(*vdev), wlan_vdev_get_psoc(vdev), 336 WLAN_MD_OBJMGR_VDEV, "wlan_objmgr_vdev"); 337 338 /* Detach DP vdev from DP MLO Device Context */ 339 340 obj_status = wlan_objmgr_vdev_mlo_dev_ctxt_detach(vdev); 341 if (obj_status != QDF_STATUS_SUCCESS) 342 return obj_status; 343 344 /* Invoke registered destroy handlers in reverse order of creation */ 345 for (id = WLAN_UMAC_COMP_ID_MAX - 1; id >= 0; id--) { 346 handler = g_umac_glb_obj->vdev_destroy_handler[id]; 347 arg = g_umac_glb_obj->vdev_destroy_handler_arg[id]; 348 if (handler && 349 (vdev->obj_status[id] == QDF_STATUS_SUCCESS || 350 vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC)) 351 vdev->obj_status[id] = handler(vdev, arg); 352 else 353 vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED; 354 } 355 /* Derive object status */ 356 obj_status = wlan_objmgr_vdev_object_status(vdev); 357 358 if (obj_status == QDF_STATUS_E_FAILURE) { 359 obj_mgr_err("VDEV object deletion failed: vdev-id: %d", 360 vdev_id); 361 /* Ideally should not happen */ 362 /* This leads to memleak ??? how to handle */ 363 QDF_BUG(0); 364 return QDF_STATUS_E_FAILURE; 365 } 366 367 /* Deletion is in progress */ 368 if (obj_status == QDF_STATUS_COMP_ASYNC) { 369 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED; 370 return QDF_STATUS_COMP_ASYNC; 371 } 372 373 /* Free VDEV object */ 374 return wlan_objmgr_vdev_obj_free(vdev); 375 } 376 377 QDF_STATUS wlan_objmgr_vdev_mlo_dev_ctxt_attach(struct wlan_objmgr_vdev * vdev)378 wlan_objmgr_vdev_mlo_dev_ctxt_attach(struct wlan_objmgr_vdev *vdev) 379 { 380 struct wlan_objmgr_psoc *psoc = NULL; 381 QDF_STATUS status = QDF_STATUS_SUCCESS; 382 struct qdf_mac_addr *mld_addr; 383 384 psoc = wlan_vdev_get_psoc(vdev); 385 if (!psoc) { 386 obj_mgr_err("Failed to get psoc"); 387 return QDF_STATUS_E_FAILURE; 388 } 389 390 /* Attach DP vdev to DP MLO dev ctx */ 391 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev); 392 393 if (qdf_is_macaddr_zero(mld_addr)) 394 return status; 395 396 /* only for MLO vdev's */ 397 status = cdp_mlo_dev_ctxt_attach(wlan_psoc_get_dp_handle(psoc), 398 wlan_vdev_get_id(vdev), 399 (uint8_t *)mld_addr); 400 if (status != QDF_STATUS_SUCCESS) { 401 obj_mgr_err("Fail to attach vdev to DP MLO Dev ctxt"); 402 wlan_objmgr_vdev_obj_delete(vdev); 403 return status; 404 } 405 406 return status; 407 } 408 409 qdf_export_symbol(wlan_objmgr_vdev_mlo_dev_ctxt_attach); 410 411 #if defined(WLAN_MLO_MULTI_CHIP) 412 QDF_STATUS wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev * vdev)413 wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev *vdev) 414 { 415 struct qdf_mac_addr *mld_addr; 416 struct wlan_objmgr_psoc *psoc = NULL; 417 418 psoc = wlan_vdev_get_psoc(vdev); 419 if (!psoc) { 420 obj_mgr_err("Failed to get psoc"); 421 return QDF_STATUS_E_FAILURE; 422 } 423 424 /* Detach DP vdev from DP MLO Device Context */ 425 mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev); 426 if (qdf_is_macaddr_zero(mld_addr)) 427 return QDF_STATUS_SUCCESS; 428 429 /* only for MLO vdev's */ 430 if (cdp_mlo_dev_ctxt_detach(wlan_psoc_get_dp_handle(psoc), 431 wlan_vdev_get_id(vdev), 432 (uint8_t *)mld_addr) 433 != QDF_STATUS_SUCCESS) { 434 obj_mgr_err("Failed to detach DP vdev from DP MLO Dev ctxt"); 435 QDF_BUG(0); 436 return QDF_STATUS_E_FAILURE; 437 } 438 return QDF_STATUS_SUCCESS; 439 } 440 441 qdf_export_symbol(wlan_objmgr_vdev_mlo_dev_ctxt_detach); 442 443 #else 444 QDF_STATUS wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev * vdev)445 wlan_objmgr_vdev_mlo_dev_ctxt_detach(struct wlan_objmgr_vdev *vdev) 446 { 447 return QDF_STATUS_SUCCESS; 448 } 449 450 qdf_export_symbol(wlan_objmgr_vdev_mlo_dev_ctxt_detach); 451 #endif 452 wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev * vdev)453 QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev) 454 { 455 uint8_t print_idx; 456 457 if (!vdev) { 458 obj_mgr_err("vdev is NULL"); 459 return QDF_STATUS_E_FAILURE; 460 } 461 462 obj_mgr_debug("Logically deleting vdev %d", vdev->vdev_objmgr.vdev_id); 463 464 print_idx = qdf_get_pidx(); 465 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, 466 QDF_TRACE_LEVEL_DEBUG); 467 /* 468 * Update VDEV object state to LOGICALLY DELETED 469 * It prevents further access of this object 470 */ 471 wlan_vdev_obj_lock(vdev); 472 vdev->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED; 473 wlan_vdev_obj_unlock(vdev); 474 wlan_objmgr_notify_log_delete(vdev, WLAN_VDEV_OP); 475 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 476 477 return QDF_STATUS_SUCCESS; 478 } 479 qdf_export_symbol(wlan_objmgr_vdev_obj_delete); 480 481 /* 482 * APIs to attach/detach component objects 483 */ wlan_objmgr_vdev_component_obj_attach(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id,void * comp_priv_obj,QDF_STATUS status)484 QDF_STATUS wlan_objmgr_vdev_component_obj_attach( 485 struct wlan_objmgr_vdev *vdev, 486 enum wlan_umac_comp_id id, 487 void *comp_priv_obj, 488 QDF_STATUS status) 489 { 490 wlan_objmgr_vdev_status_handler stat_handler; 491 void *arg; 492 uint8_t i; 493 QDF_STATUS obj_status; 494 495 /* component id is invalid */ 496 if (id >= WLAN_UMAC_MAX_COMPONENTS) 497 return QDF_STATUS_MAXCOMP_FAIL; 498 499 wlan_vdev_obj_lock(vdev); 500 /* If there is a valid entry, return failure */ 501 if (vdev->vdev_comp_priv_obj[id]) { 502 wlan_vdev_obj_unlock(vdev); 503 return QDF_STATUS_E_FAILURE; 504 } 505 /* Save component's pointer and status */ 506 vdev->vdev_comp_priv_obj[id] = comp_priv_obj; 507 vdev->obj_status[id] = status; 508 wlan_vdev_obj_unlock(vdev); 509 if (vdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED) 510 return QDF_STATUS_SUCCESS; 511 /* 512 * If VDEV object status is partially created means, this API is 513 * invoked with different context, this block should be executed for 514 * async components only 515 */ 516 /* Derive status */ 517 obj_status = wlan_objmgr_vdev_object_status(vdev); 518 /* STATUS_SUCCESS means, object is CREATED */ 519 if (obj_status == QDF_STATUS_SUCCESS) 520 vdev->obj_state = WLAN_OBJ_STATE_CREATED; 521 /* 522 * update state as CREATION failed, caller has to delete the 523 * VDEV object 524 */ 525 else if (obj_status == QDF_STATUS_E_FAILURE) 526 vdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED; 527 /* Notify components about the CREATION success/failure */ 528 if ((obj_status == QDF_STATUS_SUCCESS) || 529 (obj_status == QDF_STATUS_E_FAILURE)) { 530 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 531 stat_handler = g_umac_glb_obj->vdev_status_handler[i]; 532 arg = g_umac_glb_obj->vdev_status_handler_arg[i]; 533 if (stat_handler) 534 stat_handler(vdev, arg, obj_status); 535 } 536 } 537 return QDF_STATUS_SUCCESS; 538 } 539 qdf_export_symbol(wlan_objmgr_vdev_component_obj_attach); 540 wlan_objmgr_vdev_component_obj_detach(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id,void * comp_priv_obj)541 QDF_STATUS wlan_objmgr_vdev_component_obj_detach( 542 struct wlan_objmgr_vdev *vdev, 543 enum wlan_umac_comp_id id, 544 void *comp_priv_obj) 545 { 546 QDF_STATUS obj_status; 547 548 /* component id is invalid */ 549 if (id >= WLAN_UMAC_MAX_COMPONENTS) 550 return QDF_STATUS_MAXCOMP_FAIL; 551 552 wlan_vdev_obj_lock(vdev); 553 /* If there is a valid entry, return failure */ 554 if (vdev->vdev_comp_priv_obj[id] != comp_priv_obj) { 555 vdev->obj_status[id] = QDF_STATUS_E_FAILURE; 556 wlan_vdev_obj_unlock(vdev); 557 return QDF_STATUS_E_FAILURE; 558 } 559 /* Reset pointers to NULL, update the status*/ 560 vdev->vdev_comp_priv_obj[id] = NULL; 561 vdev->obj_status[id] = QDF_STATUS_SUCCESS; 562 wlan_vdev_obj_unlock(vdev); 563 564 /* 565 *If VDEV object status is partially destroyed means, this API is 566 * invoked with different context, this block should be executed for 567 * async components only 568 */ 569 if ((vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) || 570 (vdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) { 571 /* Derive object status */ 572 obj_status = wlan_objmgr_vdev_object_status(vdev); 573 if (obj_status == QDF_STATUS_SUCCESS) { 574 /* 575 * Update the status as Deleted, if full object 576 * deletion is in progress 577 */ 578 if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 579 vdev->obj_state = WLAN_OBJ_STATE_DELETED; 580 /* 581 * Move to creation state, since this component 582 * deletion alone requested 583 */ 584 else if (vdev->obj_state == 585 WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 586 vdev->obj_state = WLAN_OBJ_STATE_CREATED; 587 /* Object status is failure */ 588 } else if (obj_status == QDF_STATUS_E_FAILURE) { 589 /* 590 * Update the status as Deletion failed, if full object 591 * deletion is in progress 592 */ 593 if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) 594 vdev->obj_state = 595 WLAN_OBJ_STATE_DELETION_FAILED; 596 /* Move to creation state, since this component 597 deletion alone requested (do not block other 598 components) */ 599 else if (vdev->obj_state == 600 WLAN_OBJ_STATE_COMP_DEL_PROGRESS) 601 vdev->obj_state = WLAN_OBJ_STATE_CREATED; 602 } 603 /* Delete vdev object */ 604 if ((obj_status == QDF_STATUS_SUCCESS) && 605 (vdev->obj_state == WLAN_OBJ_STATE_DELETED)) { 606 /* Free VDEV object */ 607 return wlan_objmgr_vdev_obj_free(vdev); 608 } 609 } 610 return QDF_STATUS_SUCCESS; 611 } 612 qdf_export_symbol(wlan_objmgr_vdev_component_obj_detach); 613 614 /* 615 * APIs to operations on vdev objects 616 */ wlan_objmgr_iterate_peerobj_list(struct wlan_objmgr_vdev * vdev,wlan_objmgr_vdev_op_handler handler,void * arg,wlan_objmgr_ref_dbgid dbg_id)617 QDF_STATUS wlan_objmgr_iterate_peerobj_list( 618 struct wlan_objmgr_vdev *vdev, 619 wlan_objmgr_vdev_op_handler handler, 620 void *arg, wlan_objmgr_ref_dbgid dbg_id) 621 { 622 qdf_list_t *peer_list = NULL; 623 struct wlan_objmgr_peer *peer = NULL; 624 struct wlan_objmgr_peer *peer_next = NULL; 625 uint8_t vdev_id; 626 627 if (!vdev) { 628 obj_mgr_err("VDEV is NULL"); 629 return QDF_STATUS_E_FAILURE; 630 } 631 wlan_vdev_obj_lock(vdev); 632 vdev_id = wlan_vdev_get_id(vdev); 633 634 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { 635 wlan_vdev_obj_unlock(vdev); 636 obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d", 637 vdev->obj_state, vdev_id); 638 return QDF_STATUS_E_FAILURE; 639 } 640 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 641 peer_list = &vdev->vdev_objmgr.wlan_peer_list; 642 if (peer_list) { 643 /* Iterate through VDEV's peer list */ 644 peer = wlan_vdev_peer_list_peek_head(peer_list); 645 while (peer) { 646 peer_next = wlan_peer_get_next_peer_of_vdev(peer_list, 647 peer); 648 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 649 QDF_STATUS_SUCCESS) { 650 /* Invoke handler for operation */ 651 handler(vdev, (void *)peer, arg); 652 wlan_objmgr_peer_release_ref(peer, dbg_id); 653 } 654 peer = peer_next; 655 } 656 } 657 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 658 wlan_vdev_obj_unlock(vdev); 659 return QDF_STATUS_SUCCESS; 660 } 661 662 qdf_export_symbol(wlan_objmgr_iterate_peerobj_list); 663 664 /* 665 * APIs to get a peer with given mac in a vdev 666 */ 667 struct wlan_objmgr_peer * wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac,wlan_objmgr_ref_dbgid dbg_id)668 wlan_objmgr_vdev_find_peer_by_mac(struct wlan_objmgr_vdev *vdev, 669 uint8_t *peer_mac, 670 wlan_objmgr_ref_dbgid dbg_id) 671 { 672 qdf_list_t *peer_list; 673 struct wlan_objmgr_peer *peer = NULL; 674 struct wlan_objmgr_peer *peer_next = NULL; 675 uint8_t vdev_id; 676 677 if (!vdev) { 678 obj_mgr_err("VDEV is NULL"); 679 return NULL; 680 } 681 wlan_vdev_obj_lock(vdev); 682 vdev_id = wlan_vdev_get_id(vdev); 683 684 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { 685 wlan_vdev_obj_unlock(vdev); 686 obj_mgr_err("VDEV is not in create state:%d: vdev-id:%d", 687 vdev->obj_state, vdev_id); 688 return NULL; 689 } 690 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 691 peer_list = &vdev->vdev_objmgr.wlan_peer_list; 692 /* Iterate through VDEV's peer list */ 693 peer = wlan_vdev_peer_list_peek_head(peer_list); 694 while (peer) { 695 peer_next = wlan_peer_get_next_peer_of_vdev(peer_list, 696 peer); 697 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) == 698 QDF_STATUS_SUCCESS) { 699 if (!WLAN_ADDR_EQ(peer_mac, 700 wlan_peer_get_macaddr(peer))) { 701 wlan_objmgr_vdev_release_ref(vdev, 702 dbg_id); 703 wlan_vdev_obj_unlock(vdev); 704 return peer; 705 } 706 wlan_objmgr_peer_release_ref(peer, dbg_id); 707 } 708 peer = peer_next; 709 } 710 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 711 wlan_vdev_obj_unlock(vdev); 712 return NULL; 713 } 714 715 qdf_export_symbol(wlan_objmgr_vdev_find_peer_by_mac); 716 717 /** 718 * wlan_obj_vdev_populate_logically_del_peerlist() - get peer 719 * from vdev peer list 720 * @obj_list: peer object list 721 * @vdev_obj: vdev object mgr substructure 722 * @dbg_id: id of the caller 723 * 724 * API to finds peer object pointer by vdev from peer hash list for a node 725 * which is in logically deleted state 726 * 727 * Caller to free the list allocated in this function 728 * 729 * Return: list of peer pointers 730 * NULL on FAILURE 731 */ wlan_obj_vdev_populate_logically_del_peerlist(qdf_list_t * obj_list,struct wlan_objmgr_vdev_objmgr * vdev_obj,wlan_objmgr_ref_dbgid dbg_id)732 static qdf_list_t *wlan_obj_vdev_populate_logically_del_peerlist( 733 qdf_list_t *obj_list, 734 struct wlan_objmgr_vdev_objmgr *vdev_obj, 735 wlan_objmgr_ref_dbgid dbg_id) 736 { 737 struct wlan_objmgr_peer *peer; 738 struct wlan_objmgr_peer *peer_next; 739 struct wlan_logically_del_peer *peer_list; 740 qdf_list_t *logical_del_peerlist; 741 bool lock_released = false; 742 743 logical_del_peerlist = qdf_mem_malloc(sizeof(*logical_del_peerlist)); 744 if (!logical_del_peerlist) 745 return NULL; 746 747 qdf_list_create(logical_del_peerlist, vdev_obj->max_peer_count); 748 749 peer = wlan_vdev_peer_list_peek_head(obj_list); 750 while (peer) { 751 wlan_peer_obj_lock(peer); 752 peer_next = wlan_peer_get_next_peer_of_vdev(obj_list, peer); 753 if (peer->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED && 754 qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) { 755 wlan_objmgr_peer_get_ref(peer, dbg_id); 756 wlan_peer_obj_unlock(peer); 757 lock_released = true; 758 759 peer_list = qdf_mem_malloc(sizeof(*peer_list)); 760 if (!peer_list) { 761 wlan_objmgr_peer_release_ref(peer, dbg_id); 762 WLAN_OBJMGR_BUG(0); 763 break; 764 } 765 766 peer_list->peer = peer; 767 qdf_list_insert_front(logical_del_peerlist, 768 &peer_list->list); 769 } 770 771 if (!lock_released) 772 wlan_peer_obj_unlock(peer); 773 774 peer = peer_next; 775 lock_released = false; 776 } 777 778 /* Not found, return NULL */ 779 if (qdf_list_empty(logical_del_peerlist)) { 780 qdf_mem_free(logical_del_peerlist); 781 return NULL; 782 } 783 784 return logical_del_peerlist; 785 } 786 wlan_objmgr_vdev_get_log_del_peer_list(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)787 qdf_list_t *wlan_objmgr_vdev_get_log_del_peer_list( 788 struct wlan_objmgr_vdev *vdev, 789 wlan_objmgr_ref_dbgid dbg_id) 790 { 791 qdf_list_t *peer_list; 792 qdf_list_t *log_del_peer_list = NULL; 793 794 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { 795 obj_mgr_err("Invalid state vdev:%d state:%d", 796 wlan_vdev_get_id(vdev), vdev->obj_state); 797 return NULL; 798 } 799 800 wlan_vdev_obj_lock(vdev); 801 if (vdev->vdev_objmgr.wlan_peer_count == 0) { 802 wlan_vdev_obj_unlock(vdev); 803 return NULL; 804 } 805 806 wlan_objmgr_vdev_get_ref(vdev, dbg_id); 807 peer_list = &vdev->vdev_objmgr.wlan_peer_list; 808 if (peer_list) { 809 log_del_peer_list = 810 wlan_obj_vdev_populate_logically_del_peerlist( 811 peer_list, &vdev->vdev_objmgr, 812 dbg_id); 813 } 814 815 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 816 wlan_vdev_obj_unlock(vdev); 817 818 return log_del_peer_list; 819 } 820 wlan_objmgr_trigger_vdev_comp_priv_object_creation(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)821 QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_creation( 822 struct wlan_objmgr_vdev *vdev, 823 enum wlan_umac_comp_id id) 824 { 825 wlan_objmgr_vdev_create_handler handler; 826 void *arg; 827 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 828 829 /* Component id is invalid */ 830 if (id >= WLAN_UMAC_MAX_COMPONENTS) 831 return QDF_STATUS_MAXCOMP_FAIL; 832 833 wlan_vdev_obj_lock(vdev); 834 /* 835 * If component object is already created, delete old 836 * component object, then invoke creation 837 */ 838 if (vdev->vdev_comp_priv_obj[id]) { 839 wlan_vdev_obj_unlock(vdev); 840 return QDF_STATUS_E_FAILURE; 841 } 842 wlan_vdev_obj_unlock(vdev); 843 844 /* Invoke registered create handlers */ 845 handler = g_umac_glb_obj->vdev_create_handler[id]; 846 arg = g_umac_glb_obj->vdev_create_handler_arg[id]; 847 if (handler) 848 vdev->obj_status[id] = handler(vdev, arg); 849 else 850 return QDF_STATUS_E_FAILURE; 851 852 /* If object status is created, then only handle this object status */ 853 if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) { 854 /* Derive object status */ 855 obj_status = wlan_objmgr_vdev_object_status(vdev); 856 /* Move PDEV object state to Partially created state */ 857 if (obj_status == QDF_STATUS_COMP_ASYNC) { 858 /*TODO atomic */ 859 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED; 860 } 861 } 862 return obj_status; 863 } 864 wlan_objmgr_trigger_vdev_comp_priv_object_deletion(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)865 QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_deletion( 866 struct wlan_objmgr_vdev *vdev, 867 enum wlan_umac_comp_id id) 868 { 869 wlan_objmgr_vdev_destroy_handler handler; 870 void *arg; 871 QDF_STATUS obj_status = QDF_STATUS_SUCCESS; 872 873 /* component id is invalid */ 874 if (id >= WLAN_UMAC_MAX_COMPONENTS) 875 return QDF_STATUS_MAXCOMP_FAIL; 876 877 wlan_vdev_obj_lock(vdev); 878 /* Component object was never created, invalid operation */ 879 if (!vdev->vdev_comp_priv_obj[id]) { 880 wlan_vdev_obj_unlock(vdev); 881 return QDF_STATUS_E_FAILURE; 882 } 883 wlan_vdev_obj_unlock(vdev); 884 885 /* Invoke registered create handlers */ 886 handler = g_umac_glb_obj->vdev_destroy_handler[id]; 887 arg = g_umac_glb_obj->vdev_destroy_handler_arg[id]; 888 if (handler) 889 vdev->obj_status[id] = handler(vdev, arg); 890 else 891 return QDF_STATUS_E_FAILURE; 892 893 /* If object status is created, then only handle this object status */ 894 if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) { 895 obj_status = wlan_objmgr_vdev_object_status(vdev); 896 /* move object state to DEL progress */ 897 if (obj_status == QDF_STATUS_COMP_ASYNC) 898 vdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS; 899 } 900 return obj_status; 901 } 902 903 904 wlan_obj_vdev_peerlist_add_tail(qdf_list_t * obj_list,struct wlan_objmgr_peer * obj)905 static void wlan_obj_vdev_peerlist_add_tail(qdf_list_t *obj_list, 906 struct wlan_objmgr_peer *obj) 907 { 908 qdf_list_insert_back(obj_list, &obj->vdev_peer); 909 } 910 wlan_obj_vdev_peerlist_remove_peer(qdf_list_t * obj_list,struct wlan_objmgr_peer * peer)911 static QDF_STATUS wlan_obj_vdev_peerlist_remove_peer(qdf_list_t *obj_list, 912 struct wlan_objmgr_peer *peer) 913 { 914 qdf_list_node_t *vdev_node = NULL; 915 916 if (!peer) 917 return QDF_STATUS_E_FAILURE; 918 /* get vdev list node element */ 919 vdev_node = &peer->vdev_peer; 920 /* list is empty, return failure */ 921 if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS) 922 return QDF_STATUS_E_FAILURE; 923 924 return QDF_STATUS_SUCCESS; 925 } 926 wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)927 QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev, 928 struct wlan_objmgr_peer *peer) 929 { 930 struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr; 931 struct wlan_objmgr_pdev *pdev; 932 enum QDF_OPMODE opmode; 933 934 wlan_vdev_obj_lock(vdev); 935 pdev = wlan_vdev_get_pdev(vdev); 936 /* If Max VDEV peer count exceeds, return failure */ 937 if (peer->peer_mlme.peer_type != WLAN_PEER_STA_TEMP && 938 peer->peer_mlme.peer_type != WLAN_PEER_MLO_TEMP) { 939 if (objmgr->wlan_peer_count >= objmgr->max_peer_count) { 940 wlan_vdev_obj_unlock(vdev); 941 return QDF_STATUS_E_FAILURE; 942 } 943 } 944 wlan_vdev_obj_unlock(vdev); 945 946 /* If Max PDEV peer count exceeds, return failure */ 947 wlan_pdev_obj_lock(pdev); 948 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP || 949 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) { 950 if (wlan_pdev_get_temp_peer_count(pdev) >= 951 WLAN_MAX_PDEV_TEMP_PEERS) { 952 wlan_pdev_obj_unlock(pdev); 953 return QDF_STATUS_E_FAILURE; 954 } 955 } else { 956 if (wlan_pdev_get_peer_count(pdev) >= 957 wlan_pdev_get_max_peer_count(pdev)) { 958 wlan_pdev_obj_unlock(pdev); 959 return QDF_STATUS_E_FAILURE; 960 } 961 } 962 963 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP || 964 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) 965 wlan_pdev_incr_temp_peer_count(wlan_vdev_get_pdev(vdev)); 966 else 967 wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev)); 968 wlan_pdev_obj_unlock(pdev); 969 970 wlan_vdev_obj_lock(vdev); 971 /* Add peer to vdev's peer list */ 972 wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer); 973 objmgr->wlan_peer_count++; 974 975 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), 976 wlan_vdev_mlme_get_macaddr(vdev)) == 977 QDF_STATUS_SUCCESS) { 978 /* 979 * if peer mac address and vdev mac address match, set 980 * this peer as self peer 981 */ 982 wlan_vdev_set_selfpeer(vdev, peer); 983 opmode = wlan_vdev_mlme_get_opmode(vdev); 984 /* For AP mode, self peer and BSS peer are same */ 985 if ((opmode == QDF_SAP_MODE) || 986 (opmode == QDF_P2P_GO_MODE) || 987 (opmode == QDF_NDI_MODE)) 988 wlan_vdev_set_bsspeer(vdev, peer); 989 } 990 /* set BSS peer for sta */ 991 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE || 992 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) && 993 (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP || 994 wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO)) 995 wlan_vdev_set_bsspeer(vdev, peer); 996 997 /* Increment vdev ref count to make sure it won't be destroyed before */ 998 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID); 999 wlan_vdev_obj_unlock(vdev); 1000 return QDF_STATUS_SUCCESS; 1001 } 1002 wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)1003 QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev, 1004 struct wlan_objmgr_peer *peer) 1005 { 1006 struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr; 1007 struct wlan_objmgr_pdev *pdev; 1008 1009 wlan_vdev_obj_lock(vdev); 1010 /* if peer count is 0, return failure */ 1011 if (objmgr->wlan_peer_count == 0) { 1012 wlan_vdev_obj_unlock(vdev); 1013 return QDF_STATUS_E_FAILURE; 1014 } 1015 1016 if (wlan_vdev_get_selfpeer(vdev) == peer) { 1017 /* 1018 * There might be instances where new node is created 1019 * before deleting existing node, in which case selfpeer 1020 * will be pointing to the new node. So set selfpeer to 1021 * NULL only if vdev->vdev_objmgr.self_peer is pointing 1022 * to the peer processed for deletion 1023 */ 1024 wlan_vdev_set_selfpeer(vdev, NULL); 1025 } 1026 1027 if (wlan_vdev_get_bsspeer(vdev) == peer) { 1028 /* 1029 * There might be instances where new node is created 1030 * before deleting existing node, in which case bsspeer 1031 * in vdev will be pointing to the new node. So set 1032 * bsspeer to NULL only if vdev->vdev_objmgr.bss_peer is 1033 * pointing to the peer processed for deletion 1034 */ 1035 wlan_vdev_set_bsspeer(vdev, NULL); 1036 } 1037 1038 /* remove peer from vdev's peer list */ 1039 if (wlan_obj_vdev_peerlist_remove_peer(&objmgr->wlan_peer_list, peer) 1040 == QDF_STATUS_E_FAILURE) { 1041 wlan_vdev_obj_unlock(vdev); 1042 return QDF_STATUS_E_FAILURE; 1043 } 1044 /* decrement peer count */ 1045 objmgr->wlan_peer_count--; 1046 /* decrement pdev peer count */ 1047 pdev = wlan_vdev_get_pdev(vdev); 1048 wlan_vdev_obj_unlock(vdev); 1049 1050 wlan_pdev_obj_lock(pdev); 1051 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP || 1052 peer->peer_mlme.peer_type == WLAN_PEER_MLO_TEMP) 1053 wlan_pdev_decr_temp_peer_count(pdev); 1054 else 1055 wlan_pdev_decr_peer_count(pdev); 1056 wlan_pdev_obj_unlock(pdev); 1057 1058 /* decrement vdev ref count after peer released its reference */ 1059 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID); 1060 return QDF_STATUS_SUCCESS; 1061 } 1062 wlan_objmgr_vdev_try_get_bsspeer(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1063 struct wlan_objmgr_peer *wlan_objmgr_vdev_try_get_bsspeer( 1064 struct wlan_objmgr_vdev *vdev, 1065 wlan_objmgr_ref_dbgid id) 1066 { 1067 struct wlan_objmgr_peer *peer; 1068 QDF_STATUS status = QDF_STATUS_E_EMPTY; 1069 1070 if (!vdev) 1071 return NULL; 1072 1073 wlan_vdev_obj_lock(vdev); 1074 peer = wlan_vdev_get_bsspeer(vdev); 1075 if (peer) 1076 status = wlan_objmgr_peer_try_get_ref(peer, id); 1077 wlan_vdev_obj_unlock(vdev); 1078 1079 if (QDF_IS_STATUS_SUCCESS(status)) 1080 return peer; 1081 1082 return NULL; 1083 } 1084 wlan_objmgr_vdev_get_comp_private_obj(struct wlan_objmgr_vdev * vdev,enum wlan_umac_comp_id id)1085 void *wlan_objmgr_vdev_get_comp_private_obj( 1086 struct wlan_objmgr_vdev *vdev, 1087 enum wlan_umac_comp_id id) 1088 { 1089 void *comp_priv_obj; 1090 1091 /* component id is invalid */ 1092 if (id >= WLAN_UMAC_MAX_COMPONENTS) { 1093 QDF_BUG(0); 1094 return NULL; 1095 } 1096 1097 if (!vdev) { 1098 QDF_BUG(0); 1099 return NULL; 1100 } 1101 1102 comp_priv_obj = vdev->vdev_comp_priv_obj[id]; 1103 1104 return comp_priv_obj; 1105 } 1106 qdf_export_symbol(wlan_objmgr_vdev_get_comp_private_obj); 1107 1108 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1109 static inline void wlan_objmgr_vdev_ref_trace(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1110 wlan_objmgr_vdev_ref_trace(struct wlan_objmgr_vdev *vdev, 1111 wlan_objmgr_ref_dbgid id, 1112 const char *func, int line) 1113 { 1114 struct wlan_objmgr_trace *trace; 1115 1116 trace = &vdev->vdev_objmgr.trace; 1117 1118 if (func) 1119 wlan_objmgr_trace_ref(&trace->references[id].head, 1120 trace, func, line); 1121 } 1122 1123 static inline void wlan_objmgr_vdev_deref_trace(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1124 wlan_objmgr_vdev_deref_trace(struct wlan_objmgr_vdev *vdev, 1125 wlan_objmgr_ref_dbgid id, 1126 const char *func, int line) 1127 { 1128 struct wlan_objmgr_trace *trace; 1129 1130 trace = &vdev->vdev_objmgr.trace; 1131 1132 if (func) 1133 wlan_objmgr_trace_ref(&trace->dereferences[id].head, 1134 trace, func, line); 1135 } 1136 #endif 1137 1138 #ifdef WLAN_OBJMGR_REF_ID_TRACE wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1139 void wlan_objmgr_vdev_get_ref_debug(struct wlan_objmgr_vdev *vdev, 1140 wlan_objmgr_ref_dbgid id, 1141 const char *func, int line) 1142 { 1143 if (!vdev) { 1144 obj_mgr_err("vdev obj is NULL for id:%d", id); 1145 QDF_ASSERT(0); 1146 return; 1147 } 1148 /* Increment ref count */ 1149 qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt); 1150 qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]); 1151 1152 wlan_objmgr_vdev_ref_trace(vdev, id, func, line); 1153 return; 1154 } 1155 1156 qdf_export_symbol(wlan_objmgr_vdev_get_ref_debug); 1157 #else wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1158 void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev, 1159 wlan_objmgr_ref_dbgid id) 1160 { 1161 if (!vdev) { 1162 obj_mgr_err("vdev obj is NULL for id:%d", id); 1163 QDF_ASSERT(0); 1164 return; 1165 } 1166 /* Increment ref count */ 1167 qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt); 1168 qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]); 1169 } 1170 1171 qdf_export_symbol(wlan_objmgr_vdev_get_ref); 1172 #endif 1173 1174 #ifdef WLAN_OBJMGR_REF_ID_TRACE wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1175 QDF_STATUS wlan_objmgr_vdev_try_get_ref_debug(struct wlan_objmgr_vdev *vdev, 1176 wlan_objmgr_ref_dbgid id, 1177 const char *func, int line) 1178 { 1179 uint8_t vdev_id; 1180 1181 if (!vdev) { 1182 obj_mgr_err("vdev obj is NULL for id:%d", id); 1183 QDF_ASSERT(0); 1184 return QDF_STATUS_E_FAILURE; 1185 } 1186 1187 wlan_vdev_obj_lock(vdev); 1188 vdev_id = wlan_vdev_get_id(vdev); 1189 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { 1190 wlan_vdev_obj_unlock(vdev); 1191 if (vdev->vdev_objmgr.print_cnt++ <= 1192 WLAN_OBJMGR_RATELIMIT_THRESH) 1193 obj_mgr_err( 1194 "[Ref id: %d] vdev(%d) is not in Created state(%d)", 1195 id, vdev_id, vdev->obj_state); 1196 1197 return QDF_STATUS_E_RESOURCES; 1198 } 1199 1200 /* Increment ref count */ 1201 wlan_objmgr_vdev_get_ref_debug(vdev, id, func, line); 1202 wlan_vdev_obj_unlock(vdev); 1203 1204 return QDF_STATUS_SUCCESS; 1205 } 1206 1207 qdf_export_symbol(wlan_objmgr_vdev_try_get_ref_debug); 1208 #else wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1209 QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev, 1210 wlan_objmgr_ref_dbgid id) 1211 { 1212 uint8_t vdev_id; 1213 1214 if (!vdev) { 1215 obj_mgr_err("vdev obj is NULL for id:%d", id); 1216 QDF_ASSERT(0); 1217 return QDF_STATUS_E_FAILURE; 1218 } 1219 1220 wlan_vdev_obj_lock(vdev); 1221 vdev_id = wlan_vdev_get_id(vdev); 1222 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) { 1223 wlan_vdev_obj_unlock(vdev); 1224 if (vdev->vdev_objmgr.print_cnt++ <= 1225 WLAN_OBJMGR_RATELIMIT_THRESH) 1226 obj_mgr_debug( 1227 "[Ref id: %d] vdev(%d) is not in Created state(%d)", 1228 id, vdev_id, vdev->obj_state); 1229 1230 return QDF_STATUS_E_RESOURCES; 1231 } 1232 1233 /* Increment ref count */ 1234 wlan_objmgr_vdev_get_ref(vdev, id); 1235 wlan_vdev_obj_unlock(vdev); 1236 1237 return QDF_STATUS_SUCCESS; 1238 } 1239 1240 qdf_export_symbol(wlan_objmgr_vdev_try_get_ref); 1241 #endif 1242 1243 #ifdef WLAN_OBJMGR_REF_ID_TRACE wlan_vdev_get_next_active_vdev_of_pdev_debug(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1244 struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev_debug( 1245 struct wlan_objmgr_pdev *pdev, 1246 qdf_list_t *vdev_list, 1247 struct wlan_objmgr_vdev *vdev, 1248 wlan_objmgr_ref_dbgid dbg_id, 1249 const char *func, int line) 1250 { 1251 struct wlan_objmgr_vdev *vdev_next; 1252 qdf_list_node_t *node = &vdev->vdev_node; 1253 qdf_list_node_t *prev_node = NULL; 1254 1255 if (!node) 1256 return NULL; 1257 1258 wlan_pdev_obj_lock(pdev); 1259 prev_node = node; 1260 while (qdf_list_peek_next(vdev_list, prev_node, &node) == 1261 QDF_STATUS_SUCCESS) { 1262 vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev, 1263 vdev_node); 1264 if (wlan_objmgr_vdev_try_get_ref_debug(vdev_next, dbg_id, 1265 func, line) == 1266 QDF_STATUS_SUCCESS) { 1267 wlan_pdev_obj_unlock(pdev); 1268 return vdev_next; 1269 } 1270 1271 prev_node = node; 1272 } 1273 wlan_pdev_obj_unlock(pdev); 1274 1275 return NULL; 1276 } 1277 #else wlan_vdev_get_next_active_vdev_of_pdev(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)1278 struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev( 1279 struct wlan_objmgr_pdev *pdev, 1280 qdf_list_t *vdev_list, 1281 struct wlan_objmgr_vdev *vdev, 1282 wlan_objmgr_ref_dbgid dbg_id) 1283 { 1284 struct wlan_objmgr_vdev *vdev_next; 1285 qdf_list_node_t *node = &vdev->vdev_node; 1286 qdf_list_node_t *prev_node = NULL; 1287 1288 if (!node) 1289 return NULL; 1290 1291 wlan_pdev_obj_lock(pdev); 1292 prev_node = node; 1293 while (qdf_list_peek_next(vdev_list, prev_node, &node) == 1294 QDF_STATUS_SUCCESS) { 1295 vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev, 1296 vdev_node); 1297 if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) == 1298 QDF_STATUS_SUCCESS) { 1299 wlan_pdev_obj_unlock(pdev); 1300 return vdev_next; 1301 } 1302 1303 prev_node = node; 1304 } 1305 wlan_pdev_obj_unlock(pdev); 1306 1307 return NULL; 1308 } 1309 #endif 1310 1311 #ifdef WLAN_OBJMGR_REF_ID_TRACE wlan_pdev_vdev_list_peek_active_head_debug(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1312 struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head_debug( 1313 struct wlan_objmgr_pdev *pdev, 1314 qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id, 1315 const char *func, int line) 1316 { 1317 struct wlan_objmgr_vdev *vdev; 1318 qdf_list_node_t *node = NULL; 1319 qdf_list_node_t *prev_node = NULL; 1320 1321 wlan_pdev_obj_lock(pdev); 1322 1323 if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { 1324 wlan_pdev_obj_unlock(pdev); 1325 return NULL; 1326 } 1327 1328 do { 1329 vdev = qdf_container_of(node, struct wlan_objmgr_vdev, 1330 vdev_node); 1331 if (wlan_objmgr_vdev_try_get_ref_debug(vdev, dbg_id, 1332 func, line) == 1333 QDF_STATUS_SUCCESS) { 1334 wlan_pdev_obj_unlock(pdev); 1335 return vdev; 1336 } 1337 1338 prev_node = node; 1339 } while (qdf_list_peek_next(vdev_list, prev_node, &node) == 1340 QDF_STATUS_SUCCESS); 1341 1342 wlan_pdev_obj_unlock(pdev); 1343 1344 return NULL; 1345 } 1346 #else wlan_pdev_vdev_list_peek_active_head(struct wlan_objmgr_pdev * pdev,qdf_list_t * vdev_list,wlan_objmgr_ref_dbgid dbg_id)1347 struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head( 1348 struct wlan_objmgr_pdev *pdev, 1349 qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id) 1350 { 1351 struct wlan_objmgr_vdev *vdev; 1352 qdf_list_node_t *node = NULL; 1353 qdf_list_node_t *prev_node = NULL; 1354 1355 wlan_pdev_obj_lock(pdev); 1356 1357 if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) { 1358 wlan_pdev_obj_unlock(pdev); 1359 return NULL; 1360 } 1361 1362 do { 1363 vdev = qdf_container_of(node, struct wlan_objmgr_vdev, 1364 vdev_node); 1365 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) == 1366 QDF_STATUS_SUCCESS) { 1367 wlan_pdev_obj_unlock(pdev); 1368 return vdev; 1369 } 1370 1371 prev_node = node; 1372 } while (qdf_list_peek_next(vdev_list, prev_node, &node) == 1373 QDF_STATUS_SUCCESS); 1374 1375 wlan_pdev_obj_unlock(pdev); 1376 1377 return NULL; 1378 } 1379 #endif 1380 1381 #ifdef WLAN_OBJMGR_REF_ID_TRACE wlan_pdev_peek_active_first_vdev_debug(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id,const char * func,int line)1382 struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev_debug( 1383 struct wlan_objmgr_pdev *pdev, 1384 wlan_objmgr_ref_dbgid dbg_id, 1385 const char *func, int line) 1386 { 1387 struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr; 1388 qdf_list_t *vdev_list; 1389 1390 /* VDEV list */ 1391 vdev_list = &objmgr->wlan_vdev_list; 1392 1393 return wlan_pdev_vdev_list_peek_active_head_debug(pdev, vdev_list, 1394 dbg_id, func, line); 1395 } 1396 #else wlan_pdev_peek_active_first_vdev(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id)1397 struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev( 1398 struct wlan_objmgr_pdev *pdev, 1399 wlan_objmgr_ref_dbgid dbg_id) 1400 { 1401 struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr; 1402 qdf_list_t *vdev_list; 1403 1404 /* VDEV list */ 1405 vdev_list = &objmgr->wlan_vdev_list; 1406 1407 return wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list, 1408 dbg_id); 1409 } 1410 #endif 1411 1412 #ifdef WLAN_OBJMGR_REF_ID_TRACE wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1413 void wlan_objmgr_vdev_release_ref_debug(struct wlan_objmgr_vdev *vdev, 1414 wlan_objmgr_ref_dbgid id, 1415 const char *func, int line) 1416 { 1417 uint8_t vdev_id; 1418 1419 if (!vdev) { 1420 obj_mgr_err("vdev obj is NULL for id:%d", id); 1421 QDF_ASSERT(0); 1422 return; 1423 } 1424 1425 vdev_id = wlan_vdev_get_id(vdev); 1426 1427 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) { 1428 obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d", 1429 vdev_id, id); 1430 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, 1431 QDF_TRACE_LEVEL_FATAL); 1432 WLAN_OBJMGR_BUG(0); 1433 return; 1434 } 1435 1436 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) { 1437 obj_mgr_alert("vdev ref cnt is 0"); 1438 WLAN_OBJMGR_BUG(0); 1439 return; 1440 } 1441 qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]); 1442 wlan_objmgr_vdev_deref_trace(vdev, id, func, line); 1443 1444 /* Decrement ref count, free vdev, if ref count == 0 */ 1445 if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt)) 1446 wlan_objmgr_vdev_obj_destroy(vdev); 1447 } 1448 1449 qdf_export_symbol(wlan_objmgr_vdev_release_ref_debug); 1450 #else wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id)1451 void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev, 1452 wlan_objmgr_ref_dbgid id) 1453 { 1454 uint8_t vdev_id; 1455 1456 if (!vdev) { 1457 obj_mgr_err("vdev obj is NULL for id:%d", id); 1458 QDF_ASSERT(0); 1459 return; 1460 } 1461 1462 vdev_id = wlan_vdev_get_id(vdev); 1463 1464 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) { 1465 obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d", 1466 vdev_id, id); 1467 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg, 1468 QDF_TRACE_LEVEL_FATAL); 1469 WLAN_OBJMGR_BUG(0); 1470 return; 1471 } 1472 1473 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) { 1474 obj_mgr_alert("vdev ref cnt is 0"); 1475 WLAN_OBJMGR_BUG(0); 1476 return; 1477 } 1478 qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]); 1479 1480 /* Decrement ref count, free vdev, if ref count == 0 */ 1481 if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt)) 1482 wlan_objmgr_vdev_obj_destroy(vdev); 1483 } 1484 1485 qdf_export_symbol(wlan_objmgr_vdev_release_ref); 1486 #endif 1487 1488 #ifdef WLAN_OBJMGR_DEBUG wlan_print_vdev_info(struct wlan_objmgr_vdev * vdev)1489 void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev) 1490 { 1491 struct wlan_objmgr_vdev_objmgr *vdev_objmgr; 1492 uint32_t ref_cnt; 1493 1494 vdev_objmgr = &vdev->vdev_objmgr; 1495 1496 ref_cnt = qdf_atomic_read(&vdev_objmgr->ref_cnt); 1497 1498 obj_mgr_debug("vdev: %pK", vdev); 1499 obj_mgr_debug("vdev_id: %d", vdev_objmgr->vdev_id); 1500 obj_mgr_debug("print_cnt: %d", vdev_objmgr->print_cnt); 1501 obj_mgr_debug("wlan_pdev: %pK", vdev_objmgr->wlan_pdev); 1502 obj_mgr_debug("ref_cnt: %d", ref_cnt); 1503 } 1504 1505 qdf_export_symbol(wlan_print_vdev_info); 1506 #endif 1507 wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev * vdev)1508 void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev) 1509 { 1510 wlan_objmgr_vdev_peer_free_notify_handler stat_handler; 1511 uint8_t i; 1512 1513 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) { 1514 stat_handler = g_umac_glb_obj->vdev_peer_free_notify_handler[i]; 1515 if (stat_handler) 1516 stat_handler(vdev); 1517 } 1518 } 1519 1520 QDF_STATUS wlan_vdev_get_bss_peer_mac_for_pmksa(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bss_peer_mac)1521 wlan_vdev_get_bss_peer_mac_for_pmksa(struct wlan_objmgr_vdev *vdev, 1522 struct qdf_mac_addr *bss_peer_mac) 1523 { 1524 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) 1525 return wlan_vdev_get_bss_peer_mld_mac(vdev, bss_peer_mac); 1526 1527 return wlan_vdev_get_bss_peer_mac(vdev, bss_peer_mac); 1528 } 1529 wlan_vdev_get_bss_peer_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bss_peer_mac)1530 QDF_STATUS wlan_vdev_get_bss_peer_mac(struct wlan_objmgr_vdev *vdev, 1531 struct qdf_mac_addr *bss_peer_mac) 1532 { 1533 struct wlan_objmgr_peer *peer; 1534 1535 if (!vdev) { 1536 obj_mgr_err("vdev is null"); 1537 return QDF_STATUS_E_INVAL; 1538 } 1539 1540 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_OBJMGR_ID); 1541 if (!peer) { 1542 obj_mgr_debug("not able to find bss peer for vdev %d", 1543 wlan_vdev_get_id(vdev)); 1544 return QDF_STATUS_E_INVAL; 1545 } 1546 wlan_peer_obj_lock(peer); 1547 qdf_mem_copy(bss_peer_mac->bytes, wlan_peer_get_macaddr(peer), 1548 QDF_MAC_ADDR_SIZE); 1549 wlan_peer_obj_unlock(peer); 1550 1551 wlan_objmgr_peer_release_ref(peer, WLAN_MLME_OBJMGR_ID); 1552 1553 return QDF_STATUS_SUCCESS; 1554 } 1555 1556 #ifdef WLAN_FEATURE_11BE_MLO wlan_vdev_get_bss_peer_mld_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * mld_mac)1557 QDF_STATUS wlan_vdev_get_bss_peer_mld_mac(struct wlan_objmgr_vdev *vdev, 1558 struct qdf_mac_addr *mld_mac) 1559 { 1560 struct wlan_objmgr_peer *peer; 1561 1562 if (!vdev) { 1563 obj_mgr_err("vdev is null"); 1564 return QDF_STATUS_E_INVAL; 1565 } 1566 1567 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLME_OBJMGR_ID); 1568 if (!peer) { 1569 obj_mgr_err("not able to find bss peer for vdev %d", 1570 wlan_vdev_get_id(vdev)); 1571 return QDF_STATUS_E_INVAL; 1572 } 1573 wlan_peer_obj_lock(peer); 1574 qdf_mem_copy(mld_mac->bytes, wlan_peer_mlme_get_mldaddr(peer), 1575 QDF_MAC_ADDR_SIZE); 1576 wlan_peer_obj_unlock(peer); 1577 1578 wlan_objmgr_peer_release_ref(peer, WLAN_MLME_OBJMGR_ID); 1579 1580 return QDF_STATUS_SUCCESS; 1581 } 1582 wlan_vdev_mlme_is_tdls_vdev(struct wlan_objmgr_vdev * vdev)1583 bool wlan_vdev_mlme_is_tdls_vdev(struct wlan_objmgr_vdev *vdev) 1584 { 1585 bool is_tdls_vdev; 1586 1587 if (!vdev) { 1588 obj_mgr_err("vdev is NULL"); 1589 return false; 1590 } 1591 1592 wlan_acquire_vdev_mlo_lock(vdev); 1593 1594 is_tdls_vdev = 1595 wlan_vdev_mlme_feat_ext2_cap_get(vdev, 1596 WLAN_VDEV_FEXT2_MLO_STA_TDLS); 1597 1598 wlan_release_vdev_mlo_lock(vdev); 1599 1600 return is_tdls_vdev; 1601 } 1602 1603 qdf_export_symbol(wlan_vdev_mlme_is_tdls_vdev); 1604 wlan_vdev_mlme_is_mlo_vdev(struct wlan_objmgr_vdev * vdev)1605 bool wlan_vdev_mlme_is_mlo_vdev(struct wlan_objmgr_vdev *vdev) 1606 { 1607 bool is_mlo_vdev; 1608 1609 if (!vdev) { 1610 obj_mgr_err("vdev is NULL"); 1611 return false; 1612 } 1613 1614 wlan_acquire_vdev_mlo_lock(vdev); 1615 1616 is_mlo_vdev = 1617 wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO); 1618 1619 wlan_release_vdev_mlo_lock(vdev); 1620 1621 return is_mlo_vdev; 1622 } 1623 1624 qdf_export_symbol(wlan_vdev_mlme_is_mlo_vdev); 1625 1626 #ifdef WLAN_MLO_MULTI_CHIP wlan_vdev_mlme_is_mlo_bridge_vdev(struct wlan_objmgr_vdev * vdev)1627 bool wlan_vdev_mlme_is_mlo_bridge_vdev(struct wlan_objmgr_vdev *vdev) 1628 { 1629 if (!vdev) 1630 return false; 1631 1632 return vdev->vdev_objmgr.mlo_bridge_vdev; 1633 } 1634 #endif 1635 wlan_vdev_mlme_set_epcs_flag(struct wlan_objmgr_vdev * vdev,bool flag)1636 void wlan_vdev_mlme_set_epcs_flag(struct wlan_objmgr_vdev *vdev, bool flag) 1637 { 1638 if (!vdev) { 1639 obj_mgr_err("vdev is NULL"); 1640 return; 1641 } 1642 1643 vdev->vdev_mlme.epcs_enable = flag; 1644 } 1645 wlan_vdev_mlme_get_epcs_flag(struct wlan_objmgr_vdev * vdev)1646 bool wlan_vdev_mlme_get_epcs_flag(struct wlan_objmgr_vdev *vdev) 1647 { 1648 if (!vdev) { 1649 obj_mgr_err("vdev is NULL"); 1650 return false; 1651 } 1652 1653 return vdev->vdev_mlme.epcs_enable; 1654 } 1655 wlan_vdev_mlme_set_user_dis_eht_flag(struct wlan_objmgr_vdev * vdev,bool flag)1656 void wlan_vdev_mlme_set_user_dis_eht_flag(struct wlan_objmgr_vdev *vdev, 1657 bool flag) 1658 { 1659 if (!vdev) { 1660 obj_mgr_err("vdev is NULL"); 1661 return; 1662 } 1663 1664 vdev->vdev_mlme.user_disable_eht = flag; 1665 } 1666 wlan_vdev_mlme_get_user_dis_eht_flag(struct wlan_objmgr_vdev * vdev)1667 bool wlan_vdev_mlme_get_user_dis_eht_flag(struct wlan_objmgr_vdev *vdev) 1668 { 1669 if (!vdev) { 1670 obj_mgr_err("vdev is NULL"); 1671 return false; 1672 } 1673 1674 return vdev->vdev_mlme.user_disable_eht; 1675 } 1676 wlan_vdev_mlme_set_mlo_vdev(struct wlan_objmgr_vdev * vdev)1677 void wlan_vdev_mlme_set_mlo_vdev(struct wlan_objmgr_vdev *vdev) 1678 { 1679 struct wlan_objmgr_pdev *pdev; 1680 1681 if (!vdev) { 1682 obj_mgr_err("vdev is NULL"); 1683 return; 1684 } 1685 1686 pdev = wlan_vdev_get_pdev(vdev); 1687 if (!pdev) { 1688 obj_mgr_err("pdev is NULL"); 1689 return; 1690 } 1691 1692 wlan_acquire_vdev_mlo_lock(vdev); 1693 1694 if (wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO)) { 1695 wlan_release_vdev_mlo_lock(vdev); 1696 return; 1697 } 1698 wlan_vdev_mlme_feat_ext2_cap_set(vdev, WLAN_VDEV_FEXT2_MLO); 1699 1700 wlan_pdev_inc_mlo_vdev_count(pdev); 1701 1702 wlan_release_vdev_mlo_lock(vdev); 1703 obj_mgr_debug("Set MLO flag: vdev_id: %d", wlan_vdev_get_id(vdev)); 1704 } 1705 wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev * vdev)1706 void wlan_vdev_mlme_clear_mlo_vdev(struct wlan_objmgr_vdev *vdev) 1707 { 1708 struct wlan_objmgr_pdev *pdev; 1709 uint32_t mlo_vdev_cap; 1710 1711 if (!vdev) { 1712 obj_mgr_err("vdev is NULL"); 1713 return; 1714 } 1715 1716 pdev = wlan_vdev_get_pdev(vdev); 1717 if (!pdev) { 1718 obj_mgr_err("pdev is NULL"); 1719 return; 1720 } 1721 1722 wlan_acquire_vdev_mlo_lock(vdev); 1723 1724 if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO)) { 1725 wlan_release_vdev_mlo_lock(vdev); 1726 return; 1727 } 1728 1729 mlo_vdev_cap = WLAN_VDEV_FEXT2_MLO | WLAN_VDEV_FEXT2_MLO_STA_LINK; 1730 wlan_vdev_mlme_feat_ext2_cap_clear(vdev, mlo_vdev_cap); 1731 1732 wlan_pdev_dec_mlo_vdev_count(pdev); 1733 1734 wlan_release_vdev_mlo_lock(vdev); 1735 obj_mgr_debug("Clear MLO flag: vdev_id: %d", wlan_vdev_get_id(vdev)); 1736 } 1737 wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev * vdev)1738 void wlan_vdev_mlme_set_mlo_link_vdev(struct wlan_objmgr_vdev *vdev) 1739 { 1740 uint32_t mlo_vdev_cap; 1741 struct wlan_objmgr_pdev *pdev; 1742 1743 if (!vdev) { 1744 obj_mgr_err("vdev is NULL"); 1745 return; 1746 } 1747 1748 pdev = wlan_vdev_get_pdev(vdev); 1749 if (!pdev) { 1750 obj_mgr_err("pdev is NULL"); 1751 return; 1752 } 1753 1754 wlan_acquire_vdev_mlo_lock(vdev); 1755 1756 if (wlan_vdev_mlme_feat_ext2_cap_get(vdev, 1757 WLAN_VDEV_FEXT2_MLO_STA_LINK)) { 1758 wlan_release_vdev_mlo_lock(vdev); 1759 return; 1760 } else if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev, WLAN_VDEV_FEXT2_MLO)) { 1761 wlan_pdev_inc_mlo_vdev_count(pdev); 1762 } 1763 1764 mlo_vdev_cap = WLAN_VDEV_FEXT2_MLO | WLAN_VDEV_FEXT2_MLO_STA_LINK; 1765 wlan_vdev_mlme_feat_ext2_cap_set(vdev, mlo_vdev_cap); 1766 1767 wlan_release_vdev_mlo_lock(vdev); 1768 obj_mgr_debug("Set MLO link flag: vdev_id: %d", wlan_vdev_get_id(vdev)); 1769 } 1770 wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev * vdev)1771 void wlan_vdev_mlme_clear_mlo_link_vdev(struct wlan_objmgr_vdev *vdev) 1772 { 1773 if (!vdev) { 1774 obj_mgr_err("vdev is NULL"); 1775 return; 1776 } 1777 1778 wlan_acquire_vdev_mlo_lock(vdev); 1779 1780 if (!wlan_vdev_mlme_feat_ext2_cap_get(vdev, 1781 WLAN_VDEV_FEXT2_MLO_STA_LINK)) { 1782 wlan_release_vdev_mlo_lock(vdev); 1783 return; 1784 } 1785 wlan_vdev_mlme_feat_ext2_cap_clear(vdev, WLAN_VDEV_FEXT2_MLO_STA_LINK); 1786 1787 wlan_release_vdev_mlo_lock(vdev); 1788 obj_mgr_debug("Clear MLO link flag: vdev_id: %d", 1789 wlan_vdev_get_id(vdev)); 1790 } 1791 #endif /* WLAN_FEATURE_11BE_MLO */ 1792 wlan_vdev_get_peer_sta_count(struct wlan_objmgr_vdev * vdev)1793 uint8_t wlan_vdev_get_peer_sta_count(struct wlan_objmgr_vdev *vdev) 1794 { 1795 struct wlan_objmgr_peer *peer; 1796 uint8_t peer_count = 0; 1797 1798 wlan_vdev_obj_lock(vdev); 1799 wlan_objmgr_for_each_vdev_peer(vdev, peer) { 1800 wlan_objmgr_peer_get_ref(peer, WLAN_OBJMGR_ID); 1801 if (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) 1802 peer_count++; 1803 1804 wlan_objmgr_peer_release_ref(peer, WLAN_OBJMGR_ID); 1805 } 1806 wlan_vdev_obj_unlock(vdev); 1807 1808 return peer_count; 1809 } 1810