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