1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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 #include "wlan_mlo_mgr_main.h" 19 #include "qdf_types.h" 20 #include "wlan_cmn.h" 21 #include <include/wlan_vdev_mlme.h> 22 #include "wlan_mlo_mgr_ap.h" 23 #include "wlan_mlo_mgr_cmn.h" 24 25 static void mlo_peer_set_aid_bit(struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 26 uint16_t assoc_id_ix) 27 { 28 uint16_t ix; 29 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 30 31 /* Mark this bit as AID assigned */ 32 for (ix = 0; ix < WLAN_UMAC_MLO_MAX_VDEVS; ix++) { 33 vdev_aid_mgr = ml_aid_mgr->aid_mgr[ix]; 34 if (vdev_aid_mgr) 35 qdf_set_bit(assoc_id_ix, vdev_aid_mgr->aid_bitmap); 36 } 37 } 38 39 static bool wlan_mlo_check_aid_free(struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 40 uint16_t assoc_idx, bool skip_link, 41 uint8_t link_ix) 42 { 43 uint16_t j; 44 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 45 46 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 47 if (skip_link && j == link_ix) 48 continue; 49 50 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 51 if (vdev_aid_mgr && 52 qdf_test_bit(assoc_idx, vdev_aid_mgr->aid_bitmap)) 53 break; 54 55 /* AID is free */ 56 if (j == WLAN_UMAC_MLO_MAX_VDEVS - 1) 57 return true; 58 } 59 60 return false; 61 } 62 63 static bool wlan_mlo_aid_idx_check(uint16_t start_idx, uint16_t end_idx, 64 uint16_t curr_idx) 65 { 66 if (start_idx < end_idx) 67 return (curr_idx < end_idx); 68 69 return (curr_idx >= end_idx); 70 } 71 72 static int32_t wlan_mlo_aid_idx_update(uint16_t start_idx, uint16_t end_idx, 73 uint16_t curr_idx) 74 { 75 if (start_idx < end_idx) 76 return (curr_idx + 1); 77 78 if (curr_idx >= end_idx) 79 return ((int32_t)curr_idx - 1); 80 81 mlo_err("AID index is out of sync"); 82 QDF_BUG(0); 83 return 0; 84 } 85 86 static uint16_t wlan_mlo_alloc_aid(struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 87 uint16_t start_idx, uint16_t end_idx, 88 uint8_t link_ix, bool is_mlo_peer) 89 { 90 uint16_t assoc_id = (uint16_t)-1; 91 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 92 uint16_t first_aid = 0; 93 uint16_t assoc_idx = start_idx; 94 int32_t signed_assoc_idx = assoc_idx; 95 96 while (wlan_mlo_aid_idx_check(start_idx, end_idx, assoc_idx)) { 97 if (qdf_test_bit(assoc_idx, ml_aid_mgr->aid_bitmap)) { 98 signed_assoc_idx = wlan_mlo_aid_idx_update(start_idx, 99 end_idx, 100 assoc_idx); 101 if (signed_assoc_idx < 0) 102 break; 103 104 assoc_idx = signed_assoc_idx; 105 continue; 106 } 107 108 if (is_mlo_peer) { 109 if (wlan_mlo_check_aid_free(ml_aid_mgr, assoc_idx, 110 false, link_ix)) { 111 /* associd available */ 112 mlo_peer_set_aid_bit(ml_aid_mgr, assoc_idx); 113 qdf_set_bit(assoc_idx, ml_aid_mgr->aid_bitmap); 114 assoc_id = assoc_idx + 1; 115 break; 116 } 117 } else { 118 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 119 if (!vdev_aid_mgr) 120 break; 121 122 if (qdf_test_bit(assoc_idx, vdev_aid_mgr->aid_bitmap)) { 123 signed_assoc_idx = 124 wlan_mlo_aid_idx_update(start_idx, 125 end_idx, 126 assoc_idx); 127 if (signed_assoc_idx < 0) 128 break; 129 130 assoc_idx = signed_assoc_idx; 131 continue; 132 } 133 134 if (!first_aid) 135 first_aid = assoc_idx + 1; 136 137 /* Check whether this bit used by other VDEV 138 * Non-MLO peers 139 */ 140 if (!wlan_mlo_check_aid_free(ml_aid_mgr, assoc_idx, 141 true, link_ix)) { 142 /* Assoc ID is used by other link, return this 143 * aid to caller 144 */ 145 assoc_id = assoc_idx + 1; 146 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 147 qdf_set_bit(assoc_idx, 148 vdev_aid_mgr->aid_bitmap); 149 first_aid = 0; 150 break; 151 } 152 } 153 154 signed_assoc_idx = wlan_mlo_aid_idx_update(start_idx, 155 end_idx, assoc_idx); 156 if (signed_assoc_idx < 0) 157 break; 158 assoc_idx = signed_assoc_idx; 159 } 160 161 if ((!is_mlo_peer) && first_aid) { 162 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 163 qdf_set_bit(first_aid - 1, vdev_aid_mgr->aid_bitmap); 164 assoc_id = first_aid; 165 } 166 167 return assoc_id; 168 } 169 170 #ifdef WLAN_FEATURE_11BE 171 #define AID_NUM_BUCKET 3 172 static uint16_t _wlan_mlo_peer_alloc_aid( 173 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 174 bool is_mlo_peer, bool t2lm_peer, 175 uint8_t link_ix) 176 { 177 uint16_t assoc_id = (uint16_t)-1; 178 uint16_t start_aid, aid_end1, aid_end2, tot_aid; 179 uint16_t pool_1_max_aid; 180 181 start_aid = ml_aid_mgr->start_aid; 182 if (start_aid > ml_aid_mgr->max_aid) { 183 mlo_err("MAX AID %d is less than start aid %d ", 184 ml_aid_mgr->max_aid, start_aid); 185 return assoc_id; 186 } 187 188 tot_aid = ml_aid_mgr->max_aid - start_aid; 189 pool_1_max_aid = tot_aid / AID_NUM_BUCKET; 190 aid_end1 = pool_1_max_aid + start_aid; 191 aid_end2 = pool_1_max_aid + pool_1_max_aid + start_aid; 192 193 mlo_debug("max_aid = %d start_aid = %d tot_aid = %d pool_1_max_aid = %d aid_end1 = %d aid_end2 = %d", 194 ml_aid_mgr->max_aid, start_aid, tot_aid, pool_1_max_aid, 195 aid_end1, aid_end2); 196 if ((start_aid > aid_end1) || (aid_end1 > aid_end2)) { 197 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, start_aid, 198 ml_aid_mgr->max_aid, link_ix, 199 is_mlo_peer); 200 return assoc_id; 201 } 202 mlo_debug("T2LM peer = %d", t2lm_peer); 203 204 if (t2lm_peer) { 205 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, aid_end1, 206 aid_end2, link_ix, 207 is_mlo_peer); 208 209 if (assoc_id != (uint16_t)-1) 210 return assoc_id; 211 212 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, aid_end2, 213 ml_aid_mgr->max_aid, 214 link_ix, is_mlo_peer); 215 216 if (assoc_id != (uint16_t)-1) 217 return assoc_id; 218 219 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, aid_end1, 220 start_aid, link_ix, 221 is_mlo_peer); 222 } else { 223 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, start_aid, 224 aid_end1, link_ix, 225 is_mlo_peer); 226 227 if (assoc_id != (uint16_t)-1) 228 return assoc_id; 229 230 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, aid_end2, 231 ml_aid_mgr->max_aid, 232 link_ix, is_mlo_peer); 233 234 if (assoc_id != (uint16_t)-1) 235 return assoc_id; 236 237 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, aid_end2, 238 aid_end1, link_ix, 239 is_mlo_peer); 240 } 241 242 return assoc_id; 243 } 244 #else 245 static uint16_t _wlan_mlo_peer_alloc_aid( 246 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 247 bool is_mlo_peer, bool t2lm_peer, 248 uint8_t link_ix) 249 { 250 uint16_t assoc_id = (uint16_t)-1; 251 252 assoc_id = wlan_mlo_alloc_aid(ml_aid_mgr, ml_aid_mgr->start_aid, 253 ml_aid_mgr->max_aid, 254 link_ix, is_mlo_peer); 255 256 return assoc_id; 257 } 258 #endif 259 260 static uint16_t wlan_mlo_peer_alloc_aid( 261 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 262 bool is_mlo_peer, bool t2lm_peer, 263 uint8_t link_ix) 264 { 265 uint16_t assoc_id = (uint16_t)-1; 266 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 267 268 if (!mlo_mgr_ctx) { 269 mlo_err(" MLO mgr context is NULL, assoc id alloc failed"); 270 return assoc_id; 271 } 272 273 if (!is_mlo_peer && link_ix == MLO_INVALID_LINK_IDX) { 274 mlo_err(" is MLO peer %d, link_ix %d", is_mlo_peer, link_ix); 275 return assoc_id; 276 } 277 /* TODO check locking strategy */ 278 ml_aid_lock_acquire(mlo_mgr_ctx); 279 280 assoc_id = _wlan_mlo_peer_alloc_aid(ml_aid_mgr, is_mlo_peer, 281 t2lm_peer, link_ix); 282 if (assoc_id == (uint16_t)-1) 283 mlo_err("MLO aid allocation failed (reached max)"); 284 285 ml_aid_lock_release(mlo_mgr_ctx); 286 287 return assoc_id; 288 } 289 290 static uint16_t wlan_mlme_peer_alloc_aid( 291 struct wlan_vdev_aid_mgr *vdev_aid_mgr, 292 bool no_lock) 293 { 294 uint16_t assoc_id = (uint16_t)-1; 295 uint16_t i; 296 uint16_t start_aid; 297 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 298 299 if (!mlo_mgr_ctx) 300 return assoc_id; 301 302 if (!no_lock) 303 ml_aid_lock_acquire(mlo_mgr_ctx); 304 305 start_aid = vdev_aid_mgr->start_aid; 306 for (i = start_aid; i < vdev_aid_mgr->max_aid; i++) { 307 if (qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) 308 continue; 309 310 assoc_id = i + 1; 311 qdf_set_bit(i, vdev_aid_mgr->aid_bitmap); 312 break; 313 } 314 315 if (!no_lock) 316 ml_aid_lock_release(mlo_mgr_ctx); 317 318 if (i == vdev_aid_mgr->max_aid) 319 return (uint16_t)-1; 320 321 return assoc_id; 322 } 323 324 static QDF_STATUS wlan_mlo_peer_set_aid( 325 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 326 bool is_mlo_peer, 327 uint8_t link_ix, 328 uint16_t assoc_id) 329 { 330 uint16_t j; 331 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 332 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 333 334 if (!mlo_mgr_ctx) 335 return QDF_STATUS_E_FAILURE; 336 337 if (!is_mlo_peer && link_ix == 0xff) 338 return QDF_STATUS_E_FAILURE; 339 /* TODO check locking strategy */ 340 ml_aid_lock_acquire(mlo_mgr_ctx); 341 342 if (qdf_test_bit(WLAN_AID(assoc_id) - 1, ml_aid_mgr->aid_bitmap)) { 343 ml_aid_lock_release(mlo_mgr_ctx); 344 mlo_err("Assoc id %d is not available on ml aid mgr", assoc_id); 345 return QDF_STATUS_E_FAILURE; 346 } 347 348 if (is_mlo_peer) { 349 if ((assoc_id < ml_aid_mgr->start_aid) || 350 (assoc_id >= ml_aid_mgr->max_aid)) { 351 ml_aid_lock_release(mlo_mgr_ctx); 352 mlo_err("Assoc id %d is not in bounds, start aid %d, max aid %d", 353 assoc_id, ml_aid_mgr->start_aid, 354 ml_aid_mgr->max_aid); 355 return QDF_STATUS_E_FAILURE; 356 } 357 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 358 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 359 if (vdev_aid_mgr && 360 qdf_test_bit(WLAN_AID(assoc_id) - 1, 361 vdev_aid_mgr->aid_bitmap)) { 362 ml_aid_lock_release(mlo_mgr_ctx); 363 mlo_err("Assoc id %d is not available on link vdev %d", 364 assoc_id, j); 365 return QDF_STATUS_E_FAILURE; 366 } 367 /* AID is free */ 368 if (j == WLAN_UMAC_MLO_MAX_VDEVS - 1) 369 mlo_peer_set_aid_bit(ml_aid_mgr, 370 WLAN_AID(assoc_id) - 1); 371 } 372 qdf_set_bit(WLAN_AID(assoc_id) - 1, ml_aid_mgr->aid_bitmap); 373 } else { 374 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 375 if (!vdev_aid_mgr) { 376 ml_aid_lock_release(mlo_mgr_ctx); 377 return QDF_STATUS_E_FAILURE; 378 } 379 if ((assoc_id < vdev_aid_mgr->start_aid) || 380 (assoc_id >= vdev_aid_mgr->max_aid)) { 381 ml_aid_lock_release(mlo_mgr_ctx); 382 mlo_err("Assoc id %d is not in bounds, start aid %d, max aid %d", 383 assoc_id, vdev_aid_mgr->start_aid, 384 vdev_aid_mgr->max_aid); 385 return QDF_STATUS_E_FAILURE; 386 } 387 388 if (qdf_test_bit(WLAN_AID(assoc_id) - 1, 389 vdev_aid_mgr->aid_bitmap)) { 390 ml_aid_lock_release(mlo_mgr_ctx); 391 mlo_err("Assoc id %d is not available on vdev aid mgr", 392 assoc_id); 393 return QDF_STATUS_E_FAILURE; 394 } 395 396 qdf_set_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 397 } 398 399 ml_aid_lock_release(mlo_mgr_ctx); 400 401 return QDF_STATUS_SUCCESS; 402 } 403 404 static QDF_STATUS wlan_mlme_peer_set_aid( 405 struct wlan_vdev_aid_mgr *vdev_aid_mgr, 406 bool no_lock, uint16_t assoc_id) 407 { 408 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 409 QDF_STATUS status = QDF_STATUS_E_FAILURE; 410 411 if (!mlo_mgr_ctx) 412 return status; 413 414 if (!no_lock) 415 ml_aid_lock_acquire(mlo_mgr_ctx); 416 417 if ((assoc_id < vdev_aid_mgr->start_aid) || 418 (assoc_id >= vdev_aid_mgr->max_aid)) { 419 if (!no_lock) 420 ml_aid_lock_release(mlo_mgr_ctx); 421 422 mlo_err("Assoc id %d is not in bounds, start aid %d, max aid %d", 423 assoc_id, vdev_aid_mgr->start_aid, 424 vdev_aid_mgr->max_aid); 425 return QDF_STATUS_E_FAILURE; 426 } 427 428 if (!qdf_test_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap)) { 429 qdf_set_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 430 status = QDF_STATUS_SUCCESS; 431 } 432 433 if (!no_lock) 434 ml_aid_lock_release(mlo_mgr_ctx); 435 436 return status; 437 } 438 439 QDF_STATUS wlan_mlo_peer_free_aid( 440 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 441 uint8_t link_ix, 442 uint16_t assoc_id) 443 { 444 uint16_t j; 445 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 446 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 447 uint16_t assoc_id_ix; 448 449 if (!mlo_mgr_ctx) 450 return QDF_STATUS_E_FAILURE; 451 452 /* TODO check locking strategy */ 453 ml_aid_lock_acquire(mlo_mgr_ctx); 454 assoc_id_ix = WLAN_AID(assoc_id) - 1; 455 if (qdf_test_bit(assoc_id_ix, ml_aid_mgr->aid_bitmap)) { 456 qdf_clear_bit(assoc_id_ix, ml_aid_mgr->aid_bitmap); 457 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 458 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 459 if (vdev_aid_mgr && 460 qdf_test_bit(assoc_id_ix, 461 vdev_aid_mgr->aid_bitmap)) { 462 qdf_clear_bit(assoc_id_ix, 463 vdev_aid_mgr->aid_bitmap); 464 } 465 } 466 } else { 467 if ((link_ix != 0xff) && (link_ix < WLAN_UMAC_MLO_MAX_VDEVS)) { 468 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 469 if (vdev_aid_mgr) 470 qdf_clear_bit(assoc_id_ix, 471 vdev_aid_mgr->aid_bitmap); 472 } else { 473 mlo_err("AID free failed, link ix(%d) is invalid for assoc_id %d", 474 link_ix, assoc_id); 475 } 476 } 477 478 ml_aid_lock_release(mlo_mgr_ctx); 479 480 return QDF_STATUS_SUCCESS; 481 } 482 483 static int wlan_mlme_peer_aid_is_set(struct wlan_vdev_aid_mgr *vdev_aid_mgr, 484 bool no_lock, uint16_t assoc_id) 485 { 486 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 487 int isset = 0; 488 489 if (!mlo_mgr_ctx) 490 return isset; 491 492 if (!no_lock) 493 ml_aid_lock_acquire(mlo_mgr_ctx); 494 495 isset = qdf_test_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 496 497 if (!no_lock) 498 ml_aid_lock_release(mlo_mgr_ctx); 499 500 return isset; 501 } 502 503 void wlan_mlme_peer_free_aid( 504 struct wlan_vdev_aid_mgr *vdev_aid_mgr, 505 bool no_lock, uint16_t assoc_id) 506 { 507 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 508 509 if (!mlo_mgr_ctx) 510 return; 511 512 if (!no_lock) 513 ml_aid_lock_acquire(mlo_mgr_ctx); 514 515 qdf_clear_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 516 517 if (!no_lock) 518 ml_aid_lock_release(mlo_mgr_ctx); 519 } 520 521 uint16_t wlan_mlme_get_aid_count(struct wlan_objmgr_vdev *vdev) 522 { 523 uint16_t i; 524 uint16_t aid_count = 0; 525 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 526 527 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 528 if (!vdev_aid_mgr) 529 return (uint16_t)-1; 530 531 for (i = 0; i < vdev_aid_mgr->max_aid; i++) { 532 if (qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) 533 aid_count++; 534 } 535 536 return aid_count; 537 } 538 539 #ifdef WLAN_FEATURE_11BE 540 static bool mlo_peer_t2lm_enabled(struct wlan_mlo_peer_context *ml_peer) 541 { 542 if (ml_peer->t2lm_policy.t2lm_enable_val > WLAN_T2LM_NOT_SUPPORTED && 543 ml_peer->t2lm_policy.t2lm_enable_val < WLAN_T2LM_ENABLE_INVALID) 544 return true; 545 546 return false; 547 } 548 #else 549 static bool mlo_peer_t2lm_enabled(struct wlan_mlo_peer_context *ml_peer) 550 { 551 return false; 552 } 553 #endif 554 555 QDF_STATUS mlo_peer_allocate_aid( 556 struct wlan_mlo_dev_context *ml_dev, 557 struct wlan_mlo_peer_context *ml_peer) 558 { 559 uint16_t assoc_id = (uint16_t)-1; 560 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 561 struct wlan_mlo_ap *ap_ctx; 562 bool t2lm_peer = false; 563 564 ap_ctx = ml_dev->ap_ctx; 565 if (!ap_ctx) { 566 mlo_err("MLD ID %d ap_ctx is NULL", ml_dev->mld_id); 567 return QDF_STATUS_E_INVAL; 568 } 569 570 ml_aid_mgr = ap_ctx->ml_aid_mgr; 571 if (!ml_aid_mgr) { 572 mlo_err("MLD ID %d aid mgr is NULL", ml_dev->mld_id); 573 return QDF_STATUS_E_INVAL; 574 } 575 576 t2lm_peer = mlo_peer_t2lm_enabled(ml_peer); 577 578 assoc_id = wlan_mlo_peer_alloc_aid(ml_aid_mgr, true, t2lm_peer, 0xff); 579 if (assoc_id == (uint16_t)-1) { 580 mlo_err("MLD ID %d AID alloc failed", ml_dev->mld_id); 581 return QDF_STATUS_E_NOENT; 582 } 583 584 ml_peer->assoc_id = assoc_id; 585 586 mlo_debug("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " ML assoc id %d", 587 ml_dev->mld_id, 588 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), assoc_id); 589 590 return QDF_STATUS_SUCCESS; 591 } 592 593 QDF_STATUS mlo_peer_free_aid(struct wlan_mlo_dev_context *ml_dev, 594 struct wlan_mlo_peer_context *ml_peer) 595 { 596 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 597 QDF_STATUS status = QDF_STATUS_SUCCESS; 598 599 if (!ml_dev->ap_ctx) { 600 mlo_err("ml_dev->ap_ctx is null"); 601 return QDF_STATUS_E_INVAL; 602 } 603 604 if (!ml_peer) { 605 mlo_err("ml_peer is null"); 606 return QDF_STATUS_E_INVAL; 607 } 608 609 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 610 if (!ml_aid_mgr) { 611 mlo_err(" Free failed, ml_aid_mgr is NULL"); 612 return QDF_STATUS_E_INVAL; 613 } 614 615 if (!ml_peer->assoc_id) { 616 mlo_info("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " ML assoc id is 0", 617 ml_dev->mld_id, 618 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes)); 619 return status; 620 } 621 622 wlan_mlo_peer_free_aid(ml_aid_mgr, 0xff, ml_peer->assoc_id); 623 624 return status; 625 } 626 627 uint16_t mlo_get_aid(struct wlan_objmgr_vdev *vdev) 628 { 629 struct wlan_mlo_dev_context *ml_dev; 630 uint16_t assoc_id = (uint16_t)-1; 631 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 632 struct wlan_mlo_ap *ap_ctx; 633 634 ml_dev = vdev->mlo_dev_ctx; 635 636 if (!ml_dev) 637 return assoc_id; 638 639 ap_ctx = ml_dev->ap_ctx; 640 if (!ap_ctx) 641 return QDF_STATUS_E_INVAL; 642 643 ml_aid_mgr = ap_ctx->ml_aid_mgr; 644 if (!ml_aid_mgr) 645 return assoc_id; 646 647 return wlan_mlo_peer_alloc_aid(ml_aid_mgr, true, false, 0xff); 648 } 649 650 QDF_STATUS mlo_free_aid(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 651 { 652 struct wlan_mlo_dev_context *ml_dev; 653 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 654 struct wlan_mlo_ap *ap_ctx; 655 656 ml_dev = vdev->mlo_dev_ctx; 657 658 if (!ml_dev) 659 return QDF_STATUS_E_INVAL; 660 661 ap_ctx = ml_dev->ap_ctx; 662 if (!ap_ctx) 663 return QDF_STATUS_E_INVAL; 664 665 ml_aid_mgr = ap_ctx->ml_aid_mgr; 666 if (!ml_aid_mgr) 667 return QDF_STATUS_E_INVAL; 668 669 return wlan_mlo_peer_free_aid(ml_aid_mgr, 0xff, assoc_id); 670 } 671 672 static QDF_STATUS mlo_peer_set_aid(struct wlan_mlo_dev_context *ml_dev, 673 uint16_t assoc_id) 674 { 675 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 676 QDF_STATUS status; 677 struct wlan_mlo_ap *ap_ctx; 678 679 ap_ctx = ml_dev->ap_ctx; 680 if (!ap_ctx) 681 return QDF_STATUS_E_FAILURE; 682 683 ml_aid_mgr = ap_ctx->ml_aid_mgr; 684 if (!ml_aid_mgr) 685 return QDF_STATUS_E_FAILURE; 686 687 status = wlan_mlo_peer_set_aid(ml_aid_mgr, true, 0xff, assoc_id); 688 689 return status; 690 } 691 692 QDF_STATUS mlo_set_aid(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 693 { 694 struct wlan_mlo_dev_context *ml_dev; 695 696 ml_dev = vdev->mlo_dev_ctx; 697 698 if (!ml_dev) 699 return QDF_STATUS_E_FAILURE; 700 701 return mlo_peer_set_aid(ml_dev, assoc_id); 702 } 703 704 int mlme_is_aid_set(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 705 { 706 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 707 bool no_lock = true; 708 709 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 710 if (vdev_aid_mgr) { 711 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 712 no_lock = false; 713 714 return wlan_mlme_peer_aid_is_set(vdev_aid_mgr, no_lock, 715 assoc_id); 716 } 717 718 return 0; 719 } 720 721 uint16_t mlme_get_aid(struct wlan_objmgr_vdev *vdev) 722 { 723 struct wlan_mlo_dev_context *ml_dev; 724 uint16_t assoc_id = (uint16_t)-1; 725 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 726 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 727 bool no_lock = true; 728 uint8_t link_id; 729 730 ml_dev = vdev->mlo_dev_ctx; 731 732 if (!ml_dev) { 733 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 734 if (vdev_aid_mgr) { 735 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 736 no_lock = false; 737 return wlan_mlme_peer_alloc_aid(vdev_aid_mgr, no_lock); 738 } 739 return assoc_id; 740 } 741 742 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 743 if (!ml_aid_mgr) 744 return assoc_id; 745 746 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 747 748 assoc_id = wlan_mlo_peer_alloc_aid(ml_aid_mgr, false, false, link_id); 749 750 return assoc_id; 751 } 752 753 QDF_STATUS mlme_set_aid(struct wlan_objmgr_vdev *vdev, 754 uint16_t assoc_id) 755 { 756 struct wlan_mlo_dev_context *ml_dev; 757 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 758 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 759 bool no_lock = true; 760 uint8_t link_id; 761 762 ml_dev = vdev->mlo_dev_ctx; 763 764 if (!ml_dev) { 765 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 766 if (vdev_aid_mgr) { 767 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 768 no_lock = false; 769 770 return wlan_mlme_peer_set_aid(vdev_aid_mgr, no_lock, 771 assoc_id); 772 } else { 773 return QDF_STATUS_E_FAILURE; 774 } 775 } 776 777 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 778 if (!ml_aid_mgr) 779 return QDF_STATUS_E_FAILURE; 780 781 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 782 783 return wlan_mlo_peer_set_aid(ml_aid_mgr, false, link_id, assoc_id); 784 } 785 786 void mlme_free_aid(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 787 { 788 struct wlan_mlo_dev_context *ml_dev; 789 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 790 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 791 bool no_lock = true; 792 uint8_t link_id; 793 794 ml_dev = vdev->mlo_dev_ctx; 795 796 if (!ml_dev) { 797 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 798 if (vdev_aid_mgr) { 799 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 800 no_lock = false; 801 802 wlan_mlme_peer_free_aid(vdev_aid_mgr, no_lock, 803 assoc_id); 804 } 805 return; 806 } 807 808 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 809 if (!ml_aid_mgr) 810 return; 811 812 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 813 814 wlan_mlo_peer_free_aid(ml_aid_mgr, link_id, assoc_id); 815 } 816 817 void wlan_vdev_mlme_aid_mgr_max_aid_set(struct wlan_objmgr_vdev *vdev, 818 uint16_t max_aid) 819 { 820 struct wlan_vdev_aid_mgr *aid_mgr; 821 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 822 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 823 struct wlan_mlo_dev_context *ml_dev; 824 uint16_t j, max_sta_count = 0; 825 uint16_t aidmgr_sta_count = 0; 826 827 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 828 if (!aid_mgr || !max_aid) 829 return; 830 831 mlo_debug("VDEV mgr max aid %d", max_aid); 832 833 aid_mgr->max_aid = max_aid; 834 ml_dev = vdev->mlo_dev_ctx; 835 if (ml_dev) { 836 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 837 if (!ml_aid_mgr) 838 return; 839 840 /* Derive lower max_aid */ 841 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 842 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 843 if (!vdev_aid_mgr) 844 continue; 845 846 aidmgr_sta_count = vdev_aid_mgr->max_aid - 847 vdev_aid_mgr->start_aid; 848 if (!max_sta_count) { 849 max_sta_count = aidmgr_sta_count; 850 continue; 851 } 852 853 if (max_sta_count > aidmgr_sta_count) 854 max_sta_count = aidmgr_sta_count; 855 } 856 857 ml_aid_mgr->max_aid = ml_aid_mgr->start_aid + max_sta_count; 858 mlo_debug("MLO mgr max aid %d", ml_aid_mgr->max_aid); 859 } 860 } 861 862 QDF_STATUS wlan_vdev_mlme_set_start_aid(struct wlan_objmgr_vdev *vdev, 863 uint16_t start_aid) 864 { 865 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 866 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 867 struct wlan_mlo_dev_context *ml_dev; 868 uint16_t j, max_aid_start = 0; 869 870 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 871 if (!vdev_aid_mgr) 872 return QDF_STATUS_E_FAILURE; 873 874 vdev_aid_mgr->start_aid = start_aid; 875 mlo_debug("VDEV mgr start aid %d", start_aid); 876 877 ml_dev = vdev->mlo_dev_ctx; 878 if (ml_dev) { 879 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 880 if (!ml_aid_mgr) 881 return QDF_STATUS_E_FAILURE; 882 883 /* Derive higher start_aid */ 884 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 885 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 886 if (!vdev_aid_mgr) 887 continue; 888 889 if (max_aid_start < vdev_aid_mgr->start_aid) 890 max_aid_start = vdev_aid_mgr->start_aid; 891 } 892 893 ml_aid_mgr->start_aid = max_aid_start; 894 mlo_debug("MLO mgr start aid %d", max_aid_start); 895 } 896 897 return QDF_STATUS_SUCCESS; 898 } 899 900 uint16_t wlan_vdev_mlme_get_start_aid(struct wlan_objmgr_vdev *vdev) 901 { 902 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 903 904 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 905 if (!vdev_aid_mgr) 906 return 0; 907 908 return vdev_aid_mgr->start_aid; 909 } 910 911 struct wlan_vdev_aid_mgr *wlan_vdev_aid_mgr_init(uint16_t max_aid) 912 { 913 struct wlan_vdev_aid_mgr *aid_mgr; 914 915 aid_mgr = qdf_mem_malloc(sizeof(struct wlan_vdev_aid_mgr)); 916 if (!aid_mgr) 917 return NULL; 918 919 aid_mgr->start_aid = 0; 920 aid_mgr->max_aid = max_aid; 921 qdf_atomic_init(&aid_mgr->ref_cnt); 922 /* Take reference before returning */ 923 qdf_atomic_inc(&aid_mgr->ref_cnt); 924 925 return aid_mgr; 926 } 927 928 void wlan_vdev_aid_mgr_free(struct wlan_vdev_aid_mgr *aid_mgr) 929 { 930 if (!aid_mgr) 931 return; 932 933 if (!qdf_atomic_dec_and_test(&aid_mgr->ref_cnt)) 934 return; 935 936 aid_mgr->max_aid = 0; 937 qdf_mem_free(aid_mgr); 938 } 939 940 QDF_STATUS wlan_mlo_vdev_init_mbss_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 941 struct wlan_objmgr_vdev *vdev, 942 struct wlan_objmgr_vdev *tx_vdev) 943 { 944 struct wlan_vdev_aid_mgr *aid_mgr; 945 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 946 struct wlan_objmgr_vdev *vdev_iter; 947 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 948 uint16_t start_aid = 0; 949 uint8_t i; 950 951 if (!ml_dev) { 952 mlo_err("ML DEV pointer is NULL"); 953 return QDF_STATUS_E_FAILURE; 954 } 955 956 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 957 if (!ml_aid_mgr) { 958 mlo_err("AID mgr of ML VDEV(%d) is invalid", ml_dev->mld_id); 959 return QDF_STATUS_E_FAILURE; 960 } 961 962 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 963 if (!txvdev_aid_mgr) { 964 mlo_err("AID mgr of Tx VDEV%d is invalid", 965 wlan_vdev_get_id(tx_vdev)); 966 return QDF_STATUS_E_FAILURE; 967 } 968 969 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 970 971 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 972 vdev_iter = ml_dev->wlan_vdev_list[i]; 973 if (!vdev_iter) 974 continue; 975 976 if (vdev != vdev_iter) 977 continue; 978 979 start_aid = wlan_vdev_mlme_get_start_aid(tx_vdev); 980 /* Update start_aid, which updates MLO Dev start aid */ 981 wlan_vdev_mlme_set_start_aid(vdev, start_aid); 982 983 qdf_atomic_inc(&txvdev_aid_mgr->ref_cnt); 984 wlan_vdev_mlme_set_aid_mgr(vdev, 985 txvdev_aid_mgr); 986 ml_aid_mgr->aid_mgr[i] = txvdev_aid_mgr; 987 988 if (aid_mgr) { 989 mlo_info("AID mgr is freed for vdev %d with txvdev %d", 990 wlan_vdev_get_id(vdev), 991 wlan_vdev_get_id(tx_vdev)); 992 wlan_vdev_aid_mgr_free(aid_mgr); 993 } 994 995 mlo_debug("AID mgr replaced for vdev %d with txvdev %d", 996 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 997 } 998 999 return QDF_STATUS_SUCCESS; 1000 } 1001 1002 QDF_STATUS wlan_mlo_vdev_deinit_mbss_aid_mgr(struct wlan_mlo_dev_context *mldev, 1003 struct wlan_objmgr_vdev *vdev, 1004 struct wlan_objmgr_vdev *tx_vdev) 1005 { 1006 struct wlan_vdev_aid_mgr *aid_mgr; 1007 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 1008 struct wlan_objmgr_vdev *vdev_iter; 1009 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 1010 uint8_t i; 1011 1012 if (!mldev) { 1013 mlo_err("ML DEV pointer is NULL"); 1014 return QDF_STATUS_E_FAILURE; 1015 } 1016 1017 ml_aid_mgr = mldev->ap_ctx->ml_aid_mgr; 1018 if (!ml_aid_mgr) { 1019 mlo_err("AID mgr of ML VDEV(%d) is invalid", mldev->mld_id); 1020 return QDF_STATUS_E_FAILURE; 1021 } 1022 1023 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 1024 if (!txvdev_aid_mgr) { 1025 mlo_err("AID mgr of Tx VDEV%d is invalid", 1026 wlan_vdev_get_id(tx_vdev)); 1027 return QDF_STATUS_E_FAILURE; 1028 } 1029 1030 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1031 if (!aid_mgr) { 1032 mlo_err("AID mgr of VDEV%d is invalid", 1033 wlan_vdev_get_id(vdev)); 1034 return QDF_STATUS_E_FAILURE; 1035 } 1036 1037 if (aid_mgr != txvdev_aid_mgr) { 1038 mlo_err("AID mgr of VDEV%d and tx vdev(%d) aid mgr doesn't match", 1039 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1040 return QDF_STATUS_E_FAILURE; 1041 } 1042 1043 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1044 vdev_iter = mldev->wlan_vdev_list[i]; 1045 if (!vdev_iter) 1046 continue; 1047 1048 if (vdev != vdev_iter) 1049 continue; 1050 1051 aid_mgr = wlan_vdev_aid_mgr_init(ml_aid_mgr->max_aid); 1052 if (!aid_mgr) { 1053 mlo_err("AID bitmap allocation failed for VDEV%d", 1054 wlan_vdev_get_id(vdev)); 1055 QDF_BUG(0); 1056 return QDF_STATUS_E_NOMEM; 1057 } 1058 1059 wlan_vdev_mlme_set_aid_mgr(vdev, aid_mgr); 1060 ml_aid_mgr->aid_mgr[i] = aid_mgr; 1061 1062 wlan_vdev_aid_mgr_free(txvdev_aid_mgr); 1063 1064 mlo_debug("AID mgr restored for vdev %d (txvdev %d)", 1065 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1066 } 1067 1068 return QDF_STATUS_SUCCESS; 1069 } 1070 1071 QDF_STATUS wlan_mlme_vdev_init_mbss_aid_mgr(struct wlan_objmgr_vdev *vdev, 1072 struct wlan_objmgr_vdev *tx_vdev) 1073 { 1074 struct wlan_vdev_aid_mgr *aid_mgr; 1075 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 1076 1077 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 1078 if (!txvdev_aid_mgr) { 1079 mlo_err("AID mgr of Tx VDEV%d is invalid", 1080 wlan_vdev_get_id(tx_vdev)); 1081 return QDF_STATUS_E_FAILURE; 1082 } 1083 1084 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1085 1086 qdf_atomic_inc(&txvdev_aid_mgr->ref_cnt); 1087 wlan_vdev_mlme_set_aid_mgr(vdev, 1088 txvdev_aid_mgr); 1089 1090 if (aid_mgr) { 1091 mlo_info("AID mgr is freed for vdev %d with txvdev %d", 1092 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1093 wlan_vdev_aid_mgr_free(aid_mgr); 1094 } 1095 1096 mlo_debug("AID mgr replaced for vdev %d with txvdev %d", 1097 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1098 1099 return QDF_STATUS_SUCCESS; 1100 } 1101 1102 QDF_STATUS wlan_mlme_vdev_deinit_mbss_aid_mgr(struct wlan_objmgr_vdev *vdev, 1103 struct wlan_objmgr_vdev *tx_vdev) 1104 { 1105 struct wlan_vdev_aid_mgr *aid_mgr; 1106 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 1107 1108 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 1109 if (!txvdev_aid_mgr) { 1110 mlo_err("AID mgr of Tx VDEV%d is invalid", 1111 wlan_vdev_get_id(tx_vdev)); 1112 return QDF_STATUS_E_FAILURE; 1113 } 1114 1115 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1116 if (!aid_mgr) { 1117 mlo_err("AID mgr of VDEV%d is invalid", 1118 wlan_vdev_get_id(vdev)); 1119 return QDF_STATUS_E_FAILURE; 1120 } 1121 1122 if (aid_mgr != txvdev_aid_mgr) { 1123 mlo_err("AID mgr of VDEV%d and tx vdev(%d) aid mgr doesn't match", 1124 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1125 return QDF_STATUS_E_FAILURE; 1126 } 1127 1128 aid_mgr = wlan_vdev_aid_mgr_init(txvdev_aid_mgr->max_aid); 1129 if (!aid_mgr) { 1130 mlo_err("AID bitmap allocation failed for VDEV%d", 1131 wlan_vdev_get_id(vdev)); 1132 QDF_BUG(0); 1133 return QDF_STATUS_E_NOMEM; 1134 } 1135 1136 wlan_vdev_mlme_set_aid_mgr(vdev, aid_mgr); 1137 1138 wlan_vdev_aid_mgr_free(txvdev_aid_mgr); 1139 1140 mlo_debug("AID mgr restored for vdev %d (txvdev %d)", 1141 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1142 1143 return QDF_STATUS_SUCCESS; 1144 } 1145 1146 QDF_STATUS wlan_mlo_vdev_alloc_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 1147 struct wlan_objmgr_vdev *vdev) 1148 { 1149 uint8_t i; 1150 struct wlan_objmgr_vdev *vdev_iter; 1151 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 1152 struct wlan_vdev_aid_mgr *aid_mgr = NULL; 1153 uint16_t max_aid = WLAN_UMAC_MAX_AID; 1154 1155 if (!ml_dev->ap_ctx) { 1156 mlo_err(" ML AP context is not initialized"); 1157 QDF_BUG(0); 1158 return QDF_STATUS_E_NOMEM; 1159 } 1160 ml_aidmgr = ml_dev->ap_ctx->ml_aid_mgr; 1161 if (!ml_aidmgr) { 1162 mlo_err(" ML AID mgr allocation failed"); 1163 return QDF_STATUS_E_NOMEM; 1164 } 1165 1166 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1167 vdev_iter = ml_dev->wlan_vdev_list[i]; 1168 if (!vdev_iter) 1169 continue; 1170 1171 if (vdev != vdev_iter) 1172 continue; 1173 1174 /* if it is already allocated, assign it to ML AID mgr */ 1175 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1176 if (!aid_mgr) { 1177 aid_mgr = wlan_vdev_aid_mgr_init(max_aid); 1178 if (aid_mgr) { 1179 wlan_vdev_mlme_set_aid_mgr(vdev, aid_mgr); 1180 } else { 1181 mlo_err("AID bitmap allocation failed for VDEV%d", 1182 wlan_vdev_get_id(vdev)); 1183 return QDF_STATUS_E_NOMEM; 1184 } 1185 } 1186 1187 ml_aidmgr->aid_mgr[i] = aid_mgr; 1188 break; 1189 } 1190 1191 return QDF_STATUS_SUCCESS; 1192 } 1193 1194 QDF_STATUS wlan_mlo_vdev_free_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 1195 struct wlan_objmgr_vdev *vdev) 1196 { 1197 uint8_t i; 1198 struct wlan_objmgr_vdev *vdev_iter; 1199 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 1200 1201 if (!ml_dev->ap_ctx) { 1202 mlo_err(" ML AP context is not initialized"); 1203 QDF_BUG(0); 1204 return QDF_STATUS_E_NOMEM; 1205 } 1206 ml_aidmgr = ml_dev->ap_ctx->ml_aid_mgr; 1207 if (!ml_aidmgr) { 1208 mlo_err(" ML AID mgr allocation failed"); 1209 return QDF_STATUS_E_NOMEM; 1210 } 1211 1212 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1213 vdev_iter = ml_dev->wlan_vdev_list[i]; 1214 if (!vdev_iter) 1215 continue; 1216 1217 if (vdev != vdev_iter) 1218 continue; 1219 1220 wlan_vdev_aid_mgr_free(ml_aidmgr->aid_mgr[i]); 1221 ml_aidmgr->aid_mgr[i] = NULL; 1222 wlan_vdev_mlme_set_aid_mgr(vdev, NULL); 1223 break; 1224 } 1225 1226 return QDF_STATUS_SUCCESS; 1227 } 1228 1229 QDF_STATUS wlan_mlo_vdev_aid_mgr_init(struct wlan_mlo_dev_context *ml_dev) 1230 { 1231 uint8_t i; 1232 struct wlan_objmgr_vdev *vdev; 1233 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 1234 uint16_t max_aid = WLAN_UMAC_MAX_AID; 1235 1236 ml_aidmgr = qdf_mem_malloc(sizeof(struct wlan_ml_vdev_aid_mgr)); 1237 if (!ml_aidmgr) { 1238 ml_dev->ap_ctx->ml_aid_mgr = NULL; 1239 mlo_err(" ML AID mgr allocation failed"); 1240 return QDF_STATUS_E_NOMEM; 1241 } 1242 1243 ml_aidmgr->start_aid = 0; 1244 ml_aidmgr->max_aid = max_aid; 1245 ml_dev->ap_ctx->ml_aid_mgr = ml_aidmgr; 1246 1247 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1248 vdev = ml_dev->wlan_vdev_list[i]; 1249 if (!vdev) 1250 continue; 1251 1252 ml_aidmgr->aid_mgr[i] = wlan_vdev_aid_mgr_init(max_aid); 1253 if (!ml_aidmgr->aid_mgr[i]) { 1254 mlo_err("AID bitmap allocation failed for VDEV%d", 1255 wlan_vdev_get_id(vdev)); 1256 goto free_ml_aid_mgr; 1257 } 1258 wlan_vdev_mlme_set_aid_mgr(vdev, ml_aidmgr->aid_mgr[i]); 1259 } 1260 1261 return QDF_STATUS_SUCCESS; 1262 1263 free_ml_aid_mgr: 1264 wlan_mlo_vdev_aid_mgr_deinit(ml_dev); 1265 1266 return QDF_STATUS_E_NOMEM; 1267 } 1268 1269 void wlan_mlo_vdev_aid_mgr_deinit(struct wlan_mlo_dev_context *ml_dev) 1270 { 1271 uint8_t i; 1272 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 1273 int32_t n; 1274 1275 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 1276 if (!ml_aid_mgr) 1277 return; 1278 1279 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1280 1281 if (ml_aid_mgr->aid_mgr[i]) { 1282 n = qdf_atomic_read(&ml_aid_mgr->aid_mgr[i]->ref_cnt); 1283 mlo_info("AID mgr ref cnt %d", n); 1284 } else { 1285 mlo_err("ID %d, doesn't have associated AID mgr", i); 1286 continue; 1287 } 1288 wlan_vdev_aid_mgr_free(ml_aid_mgr->aid_mgr[i]); 1289 ml_aid_mgr->aid_mgr[i] = NULL; 1290 } 1291 1292 qdf_mem_free(ml_aid_mgr); 1293 ml_dev->ap_ctx->ml_aid_mgr = NULL; 1294 } 1295