1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021 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 uint16_t wlan_mlo_peer_alloc_aid( 40 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 41 bool is_mlo_peer, 42 uint8_t link_ix) 43 { 44 uint16_t assoc_id = (uint16_t)-1; 45 uint16_t i, j; 46 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 47 uint16_t first_aid = 0; 48 uint16_t start_aid; 49 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 50 51 if (!mlo_mgr_ctx) { 52 mlo_err(" MLO mgr context is NULL, assoc id alloc failed"); 53 return assoc_id; 54 } 55 56 if (!is_mlo_peer && link_ix == MLO_INVALID_LINK_IDX) { 57 mlo_err(" is MLO peer %d, link_ix %d", is_mlo_peer, link_ix); 58 return assoc_id; 59 } 60 /* TODO check locking strategy */ 61 ml_aid_lock_acquire(mlo_mgr_ctx); 62 63 start_aid = ml_aid_mgr->start_aid; 64 for (i = start_aid; i < ml_aid_mgr->max_aid; i++) { 65 if (qdf_test_bit(i, ml_aid_mgr->aid_bitmap)) 66 continue; 67 68 if (is_mlo_peer) { 69 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 70 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 71 if (vdev_aid_mgr && 72 qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) 73 break; 74 /* AID is free */ 75 if (j == WLAN_UMAC_MLO_MAX_VDEVS - 1) { 76 assoc_id = i + 1; 77 mlo_peer_set_aid_bit(ml_aid_mgr, i); 78 } 79 } 80 81 if (assoc_id == i + 1) { 82 qdf_set_bit(i, ml_aid_mgr->aid_bitmap); 83 break; 84 } 85 } else { 86 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 87 if (!vdev_aid_mgr) 88 break; 89 90 if (qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) 91 continue; 92 93 if (!first_aid) 94 first_aid = i + 1; 95 96 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 97 if (j == link_ix) 98 continue; 99 /* Check whether this bit used by other VDEV 100 * Non-MLO peers 101 */ 102 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 103 if (vdev_aid_mgr && 104 qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) { 105 assoc_id = i + 1; 106 break; 107 } 108 } 109 /* Assoc ID is used by other link, return this aid 110 * to caller 111 */ 112 if (assoc_id == i + 1) { 113 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 114 qdf_set_bit(i, vdev_aid_mgr->aid_bitmap); 115 first_aid = 0; 116 break; 117 } 118 } 119 } 120 121 if ((!is_mlo_peer) && first_aid) { 122 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 123 qdf_set_bit(first_aid - 1, vdev_aid_mgr->aid_bitmap); 124 assoc_id = first_aid; 125 } 126 127 if ((assoc_id == (uint16_t)-1) && (i == ml_aid_mgr->max_aid)) 128 mlo_err("MLO aid allocation failed (reached max)"); 129 130 ml_aid_lock_release(mlo_mgr_ctx); 131 132 return assoc_id; 133 } 134 135 static uint16_t wlan_mlme_peer_alloc_aid( 136 struct wlan_vdev_aid_mgr *vdev_aid_mgr, 137 bool no_lock) 138 { 139 uint16_t assoc_id = (uint16_t)-1; 140 uint16_t i; 141 uint16_t start_aid; 142 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 143 144 if (!mlo_mgr_ctx) 145 return assoc_id; 146 147 if (!no_lock) 148 ml_aid_lock_acquire(mlo_mgr_ctx); 149 150 start_aid = vdev_aid_mgr->start_aid; 151 for (i = start_aid; i < vdev_aid_mgr->max_aid; i++) { 152 if (qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) 153 continue; 154 155 assoc_id = i + 1; 156 qdf_set_bit(i, vdev_aid_mgr->aid_bitmap); 157 break; 158 } 159 160 if (!no_lock) 161 ml_aid_lock_release(mlo_mgr_ctx); 162 163 if (i == vdev_aid_mgr->max_aid) 164 return (uint16_t)-1; 165 166 return assoc_id; 167 } 168 169 static QDF_STATUS wlan_mlo_peer_set_aid( 170 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 171 bool is_mlo_peer, 172 uint8_t link_ix, 173 uint16_t assoc_id) 174 { 175 uint16_t j; 176 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 177 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 178 179 if (!mlo_mgr_ctx) 180 return QDF_STATUS_E_FAILURE; 181 182 if (!is_mlo_peer && link_ix == 0xff) 183 return QDF_STATUS_E_FAILURE; 184 /* TODO check locking strategy */ 185 ml_aid_lock_acquire(mlo_mgr_ctx); 186 187 if (qdf_test_bit(WLAN_AID(assoc_id) - 1, ml_aid_mgr->aid_bitmap)) { 188 ml_aid_lock_release(mlo_mgr_ctx); 189 return QDF_STATUS_E_FAILURE; 190 } 191 192 if (is_mlo_peer) { 193 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 194 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 195 if (vdev_aid_mgr && 196 qdf_test_bit(WLAN_AID(assoc_id) - 1, 197 vdev_aid_mgr->aid_bitmap)) { 198 ml_aid_lock_release(mlo_mgr_ctx); 199 return QDF_STATUS_E_FAILURE; 200 } 201 /* AID is free */ 202 if (j == WLAN_UMAC_MLO_MAX_VDEVS - 1) 203 mlo_peer_set_aid_bit(ml_aid_mgr, 204 WLAN_AID(assoc_id) - 1); 205 } 206 qdf_set_bit(WLAN_AID(assoc_id) - 1, ml_aid_mgr->aid_bitmap); 207 } else { 208 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 209 if (!vdev_aid_mgr) { 210 ml_aid_lock_release(mlo_mgr_ctx); 211 return QDF_STATUS_E_FAILURE; 212 } 213 214 if (qdf_test_bit(WLAN_AID(assoc_id) - 1, 215 vdev_aid_mgr->aid_bitmap)) { 216 ml_aid_lock_release(mlo_mgr_ctx); 217 return QDF_STATUS_E_FAILURE; 218 } 219 220 qdf_set_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 221 } 222 223 ml_aid_lock_release(mlo_mgr_ctx); 224 225 return QDF_STATUS_SUCCESS; 226 } 227 228 static QDF_STATUS wlan_mlme_peer_set_aid( 229 struct wlan_vdev_aid_mgr *vdev_aid_mgr, 230 bool no_lock, uint16_t assoc_id) 231 { 232 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 233 QDF_STATUS status = QDF_STATUS_E_FAILURE; 234 235 if (!mlo_mgr_ctx) 236 return status; 237 238 if (!no_lock) 239 ml_aid_lock_acquire(mlo_mgr_ctx); 240 241 if (!qdf_test_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap)) { 242 qdf_set_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 243 status = QDF_STATUS_SUCCESS; 244 } 245 246 if (!no_lock) 247 ml_aid_lock_release(mlo_mgr_ctx); 248 249 return status; 250 } 251 252 QDF_STATUS wlan_mlo_peer_free_aid( 253 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr, 254 uint8_t link_ix, 255 uint16_t assoc_id) 256 { 257 uint16_t j; 258 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 259 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 260 uint16_t assoc_id_ix; 261 262 if (!mlo_mgr_ctx) 263 return QDF_STATUS_E_FAILURE; 264 265 /* TODO check locking strategy */ 266 ml_aid_lock_acquire(mlo_mgr_ctx); 267 assoc_id_ix = WLAN_AID(assoc_id) - 1; 268 if (qdf_test_bit(assoc_id_ix, ml_aid_mgr->aid_bitmap)) { 269 qdf_clear_bit(assoc_id_ix, ml_aid_mgr->aid_bitmap); 270 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 271 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 272 if (vdev_aid_mgr && 273 qdf_test_bit(assoc_id_ix, 274 vdev_aid_mgr->aid_bitmap)) { 275 qdf_clear_bit(assoc_id_ix, 276 vdev_aid_mgr->aid_bitmap); 277 } 278 } 279 } else { 280 vdev_aid_mgr = ml_aid_mgr->aid_mgr[link_ix]; 281 if (vdev_aid_mgr) 282 qdf_clear_bit(assoc_id_ix, vdev_aid_mgr->aid_bitmap); 283 } 284 285 ml_aid_lock_release(mlo_mgr_ctx); 286 287 return QDF_STATUS_SUCCESS; 288 } 289 290 static int wlan_mlme_peer_aid_is_set(struct wlan_vdev_aid_mgr *vdev_aid_mgr, 291 bool no_lock, uint16_t assoc_id) 292 { 293 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 294 int isset = 0; 295 296 if (!mlo_mgr_ctx) 297 return isset; 298 299 if (!no_lock) 300 ml_aid_lock_acquire(mlo_mgr_ctx); 301 302 isset = qdf_test_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 303 304 if (!no_lock) 305 ml_aid_lock_release(mlo_mgr_ctx); 306 307 return isset; 308 } 309 310 void wlan_mlme_peer_free_aid( 311 struct wlan_vdev_aid_mgr *vdev_aid_mgr, 312 bool no_lock, uint16_t assoc_id) 313 { 314 struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx(); 315 316 if (!mlo_mgr_ctx) 317 return; 318 319 if (!no_lock) 320 ml_aid_lock_acquire(mlo_mgr_ctx); 321 322 qdf_clear_bit(WLAN_AID(assoc_id) - 1, vdev_aid_mgr->aid_bitmap); 323 324 if (!no_lock) 325 ml_aid_lock_release(mlo_mgr_ctx); 326 } 327 328 uint16_t wlan_mlme_get_aid_count(struct wlan_objmgr_vdev *vdev) 329 { 330 uint16_t i; 331 uint16_t aid_count = 0; 332 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 333 334 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 335 if (!vdev_aid_mgr) 336 return (uint16_t)-1; 337 338 for (i = 0; i < vdev_aid_mgr->max_aid; i++) { 339 if (qdf_test_bit(i, vdev_aid_mgr->aid_bitmap)) 340 aid_count++; 341 } 342 343 return aid_count; 344 } 345 346 QDF_STATUS mlo_peer_allocate_aid( 347 struct wlan_mlo_dev_context *ml_dev, 348 struct wlan_mlo_peer_context *ml_peer) 349 { 350 uint16_t assoc_id = (uint16_t)-1; 351 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 352 struct wlan_mlo_ap *ap_ctx; 353 354 ap_ctx = ml_dev->ap_ctx; 355 if (!ap_ctx) { 356 mlo_err("MLD ID %d ap_ctx is NULL", ml_dev->mld_id); 357 return QDF_STATUS_E_INVAL; 358 } 359 360 ml_aid_mgr = ap_ctx->ml_aid_mgr; 361 if (!ml_aid_mgr) { 362 mlo_err("MLD ID %d aid mgr is NULL", ml_dev->mld_id); 363 return QDF_STATUS_E_INVAL; 364 } 365 366 assoc_id = wlan_mlo_peer_alloc_aid(ml_aid_mgr, true, 0xff); 367 if (assoc_id == (uint16_t)-1) { 368 mlo_err("MLD ID %d aid mgr is NULL", ml_dev->mld_id); 369 return QDF_STATUS_E_NOENT; 370 } 371 372 ml_peer->assoc_id = assoc_id; 373 374 mlo_debug("MLD ID %d ML Peer " QDF_MAC_ADDR_FMT " ML assoc id %d", 375 ml_dev->mld_id, 376 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes), assoc_id); 377 378 return QDF_STATUS_SUCCESS; 379 } 380 381 QDF_STATUS mlo_peer_free_aid(struct wlan_mlo_dev_context *ml_dev, 382 struct wlan_mlo_peer_context *ml_peer) 383 { 384 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 385 QDF_STATUS status = QDF_STATUS_SUCCESS; 386 387 if (!ml_dev->ap_ctx) { 388 mlo_err("ml_dev->ap_ctx is null"); 389 return QDF_STATUS_E_INVAL; 390 } 391 392 if (!ml_peer) { 393 mlo_err("ml_peer is null"); 394 return QDF_STATUS_E_INVAL; 395 } 396 397 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 398 if (!ml_aid_mgr) 399 return QDF_STATUS_E_INVAL; 400 401 wlan_mlo_peer_free_aid(ml_aid_mgr, 0xff, ml_peer->assoc_id); 402 403 return status; 404 } 405 406 uint16_t mlo_get_aid(struct wlan_objmgr_vdev *vdev) 407 { 408 struct wlan_mlo_dev_context *ml_dev; 409 uint16_t assoc_id = (uint16_t)-1; 410 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 411 struct wlan_mlo_ap *ap_ctx; 412 413 ml_dev = vdev->mlo_dev_ctx; 414 415 if (!ml_dev) 416 return assoc_id; 417 418 ap_ctx = ml_dev->ap_ctx; 419 if (!ap_ctx) 420 return QDF_STATUS_E_INVAL; 421 422 ml_aid_mgr = ap_ctx->ml_aid_mgr; 423 if (!ml_aid_mgr) 424 return assoc_id; 425 426 return wlan_mlo_peer_alloc_aid(ml_aid_mgr, true, 0xff); 427 } 428 429 QDF_STATUS mlo_free_aid(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 430 { 431 struct wlan_mlo_dev_context *ml_dev; 432 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 433 struct wlan_mlo_ap *ap_ctx; 434 435 ml_dev = vdev->mlo_dev_ctx; 436 437 if (!ml_dev) 438 return QDF_STATUS_E_INVAL; 439 440 ap_ctx = ml_dev->ap_ctx; 441 if (!ap_ctx) 442 return QDF_STATUS_E_INVAL; 443 444 ml_aid_mgr = ap_ctx->ml_aid_mgr; 445 if (!ml_aid_mgr) 446 return QDF_STATUS_E_INVAL; 447 448 return wlan_mlo_peer_free_aid(ml_aid_mgr, 0xff, assoc_id); 449 } 450 451 static QDF_STATUS mlo_peer_set_aid(struct wlan_mlo_dev_context *ml_dev, 452 uint16_t assoc_id) 453 { 454 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 455 QDF_STATUS status; 456 struct wlan_mlo_ap *ap_ctx; 457 458 ap_ctx = ml_dev->ap_ctx; 459 if (!ap_ctx) 460 return QDF_STATUS_E_FAILURE; 461 462 ml_aid_mgr = ap_ctx->ml_aid_mgr; 463 if (!ml_aid_mgr) 464 return QDF_STATUS_E_FAILURE; 465 466 status = wlan_mlo_peer_set_aid(ml_aid_mgr, true, 0xff, assoc_id); 467 468 return status; 469 } 470 471 QDF_STATUS mlo_set_aid(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 472 { 473 struct wlan_mlo_dev_context *ml_dev; 474 475 ml_dev = vdev->mlo_dev_ctx; 476 477 if (!ml_dev) 478 return QDF_STATUS_E_FAILURE; 479 480 return mlo_peer_set_aid(ml_dev, assoc_id); 481 } 482 483 int mlme_is_aid_set(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 484 { 485 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 486 bool no_lock = true; 487 488 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 489 if (vdev_aid_mgr) { 490 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 491 no_lock = false; 492 493 return wlan_mlme_peer_aid_is_set(vdev_aid_mgr, no_lock, 494 assoc_id); 495 } 496 497 return 0; 498 } 499 500 uint16_t mlme_get_aid(struct wlan_objmgr_vdev *vdev) 501 { 502 struct wlan_mlo_dev_context *ml_dev; 503 uint16_t assoc_id = (uint16_t)-1; 504 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 505 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 506 bool no_lock = true; 507 uint8_t link_id; 508 509 ml_dev = vdev->mlo_dev_ctx; 510 511 if (!ml_dev) { 512 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 513 if (vdev_aid_mgr) { 514 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 515 no_lock = false; 516 return wlan_mlme_peer_alloc_aid(vdev_aid_mgr, no_lock); 517 } 518 return assoc_id; 519 } 520 521 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 522 if (!ml_aid_mgr) 523 return assoc_id; 524 525 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 526 527 assoc_id = wlan_mlo_peer_alloc_aid(ml_aid_mgr, false, link_id); 528 529 return assoc_id; 530 } 531 532 QDF_STATUS mlme_set_aid(struct wlan_objmgr_vdev *vdev, 533 uint16_t assoc_id) 534 { 535 struct wlan_mlo_dev_context *ml_dev; 536 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 537 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 538 bool no_lock = true; 539 uint8_t link_id; 540 541 ml_dev = vdev->mlo_dev_ctx; 542 543 if (!ml_dev) { 544 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 545 if (vdev_aid_mgr) { 546 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 547 no_lock = false; 548 549 return wlan_mlme_peer_set_aid(vdev_aid_mgr, no_lock, 550 assoc_id); 551 } else { 552 return QDF_STATUS_E_FAILURE; 553 } 554 } 555 556 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 557 if (!ml_aid_mgr) 558 return QDF_STATUS_E_FAILURE; 559 560 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 561 562 return wlan_mlo_peer_set_aid(ml_aid_mgr, false, link_id, assoc_id); 563 } 564 565 void mlme_free_aid(struct wlan_objmgr_vdev *vdev, uint16_t assoc_id) 566 { 567 struct wlan_mlo_dev_context *ml_dev; 568 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 569 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 570 bool no_lock = true; 571 uint8_t link_id; 572 573 ml_dev = vdev->mlo_dev_ctx; 574 575 if (!ml_dev) { 576 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 577 if (vdev_aid_mgr) { 578 if (qdf_atomic_read(&vdev_aid_mgr->ref_cnt) > 1) 579 no_lock = false; 580 581 wlan_mlme_peer_free_aid(vdev_aid_mgr, no_lock, 582 assoc_id); 583 } 584 return; 585 } 586 587 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 588 if (!ml_aid_mgr) 589 return; 590 591 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 592 593 wlan_mlo_peer_free_aid(ml_aid_mgr, link_id, assoc_id); 594 } 595 596 void wlan_vdev_mlme_aid_mgr_max_aid_set(struct wlan_objmgr_vdev *vdev, 597 uint16_t max_aid) 598 { 599 struct wlan_vdev_aid_mgr *aid_mgr; 600 601 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 602 if (!aid_mgr) 603 return; 604 605 aid_mgr->max_aid = max_aid; 606 } 607 608 QDF_STATUS wlan_vdev_mlme_set_start_aid(struct wlan_objmgr_vdev *vdev, 609 uint16_t start_aid) 610 { 611 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 612 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 613 struct wlan_mlo_dev_context *ml_dev; 614 uint16_t j, max_aid_start = 0; 615 616 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 617 if (!vdev_aid_mgr) 618 return QDF_STATUS_E_FAILURE; 619 620 vdev_aid_mgr->start_aid = start_aid; 621 622 ml_dev = vdev->mlo_dev_ctx; 623 if (ml_dev) { 624 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 625 if (!ml_aid_mgr) 626 return QDF_STATUS_E_FAILURE; 627 628 /* Derive higher start_aid */ 629 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 630 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 631 if (!vdev_aid_mgr) 632 continue; 633 634 if (max_aid_start < vdev_aid_mgr->start_aid) 635 max_aid_start = vdev_aid_mgr->start_aid; 636 } 637 638 ml_aid_mgr->start_aid = max_aid_start; 639 } 640 641 return QDF_STATUS_SUCCESS; 642 } 643 644 struct wlan_vdev_aid_mgr *wlan_vdev_aid_mgr_init(uint16_t max_aid) 645 { 646 struct wlan_vdev_aid_mgr *aid_mgr; 647 648 aid_mgr = qdf_mem_malloc(sizeof(struct wlan_vdev_aid_mgr)); 649 if (!aid_mgr) 650 return NULL; 651 652 aid_mgr->start_aid = 0; 653 aid_mgr->max_aid = max_aid; 654 qdf_atomic_init(&aid_mgr->ref_cnt); 655 /* Take reference before returning */ 656 qdf_atomic_inc(&aid_mgr->ref_cnt); 657 658 return aid_mgr; 659 } 660 661 void wlan_vdev_aid_mgr_free(struct wlan_vdev_aid_mgr *aid_mgr) 662 { 663 if (!aid_mgr) 664 return; 665 666 if (!qdf_atomic_dec_and_test(&aid_mgr->ref_cnt)) 667 return; 668 669 aid_mgr->max_aid = 0; 670 qdf_mem_free(aid_mgr); 671 } 672 673 QDF_STATUS wlan_mlo_vdev_alloc_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 674 struct wlan_objmgr_vdev *vdev) 675 { 676 uint8_t i; 677 uint8_t is_mbss_enabled = 0; 678 struct wlan_objmgr_vdev *vdev_iter; 679 struct wlan_objmgr_vdev *tx_vdev = NULL; 680 struct wlan_vdev_aid_mgr *aid_mgr; 681 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 682 uint16_t max_aid = WLAN_UMAC_MAX_AID; 683 684 if (!ml_dev->ap_ctx) { 685 mlo_err(" ML AP context is not initialized"); 686 QDF_BUG(0); 687 return QDF_STATUS_E_NOMEM; 688 } 689 ml_aidmgr = ml_dev->ap_ctx->ml_aid_mgr; 690 if (!ml_aidmgr) { 691 mlo_err(" ML AID mgr allocation failed"); 692 return QDF_STATUS_E_NOMEM; 693 } 694 695 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 696 vdev_iter = ml_dev->wlan_vdev_list[i]; 697 if (!vdev_iter) 698 continue; 699 700 if (vdev != vdev_iter) 701 continue; 702 703 /* TODO */ 704 /* Get Tx VDEV, if VDEV is MBSSID */ 705 if (is_mbss_enabled) { 706 aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 707 if (!aid_mgr) { 708 mlo_err("AID bitmap allocation failed for Tx VDEV%d", 709 wlan_vdev_get_id(tx_vdev)); 710 return QDF_STATUS_E_NOMEM; 711 } 712 qdf_atomic_inc(&aid_mgr->ref_cnt); 713 ml_aidmgr->aid_mgr[i] = aid_mgr; 714 wlan_vdev_mlme_set_aid_mgr(vdev, 715 ml_aidmgr->aid_mgr[i]); 716 break; 717 } else { 718 ml_aidmgr->aid_mgr[i] = wlan_vdev_aid_mgr_init(max_aid); 719 if (!ml_aidmgr->aid_mgr[i]) { 720 mlo_err("AID bitmap allocation failed for VDEV%d", 721 wlan_vdev_get_id(vdev)); 722 return QDF_STATUS_E_NOMEM; 723 } 724 wlan_vdev_mlme_set_aid_mgr(vdev, ml_aidmgr->aid_mgr[i]); 725 break; 726 } 727 } 728 729 return QDF_STATUS_SUCCESS; 730 } 731 732 QDF_STATUS wlan_mlo_vdev_free_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 733 struct wlan_objmgr_vdev *vdev) 734 { 735 uint8_t i; 736 struct wlan_objmgr_vdev *vdev_iter; 737 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 738 739 if (!ml_dev->ap_ctx) { 740 mlo_err(" ML AP context is not initialized"); 741 QDF_BUG(0); 742 return QDF_STATUS_E_NOMEM; 743 } 744 ml_aidmgr = ml_dev->ap_ctx->ml_aid_mgr; 745 if (!ml_aidmgr) { 746 mlo_err(" ML AID mgr allocation failed"); 747 return QDF_STATUS_E_NOMEM; 748 } 749 750 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 751 vdev_iter = ml_dev->wlan_vdev_list[i]; 752 if (!vdev_iter) 753 continue; 754 755 if (vdev != vdev_iter) 756 continue; 757 758 wlan_vdev_aid_mgr_free(ml_aidmgr->aid_mgr[i]); 759 ml_aidmgr->aid_mgr[i] = NULL; 760 break; 761 } 762 763 return QDF_STATUS_SUCCESS; 764 } 765 766 QDF_STATUS wlan_mlo_vdev_aid_mgr_init(struct wlan_mlo_dev_context *ml_dev) 767 { 768 uint8_t i; 769 uint8_t is_mbss_enabled = 0; 770 struct wlan_objmgr_vdev *vdev; 771 struct wlan_objmgr_vdev *tx_vdev = NULL; 772 struct wlan_vdev_aid_mgr *aid_mgr; 773 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 774 uint16_t max_aid = WLAN_UMAC_MAX_AID; 775 776 ml_aidmgr = qdf_mem_malloc(sizeof(struct wlan_ml_vdev_aid_mgr)); 777 if (!ml_aidmgr) { 778 ml_dev->ap_ctx->ml_aid_mgr = NULL; 779 mlo_err(" ML AID mgr allocation failed"); 780 return QDF_STATUS_E_NOMEM; 781 } 782 783 ml_aidmgr->start_aid = 0; 784 ml_aidmgr->max_aid = max_aid; 785 ml_dev->ap_ctx->ml_aid_mgr = ml_aidmgr; 786 787 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 788 vdev = ml_dev->wlan_vdev_list[i]; 789 if (!vdev) 790 continue; 791 /* TODO */ 792 /* Get Tx VDEV, if VDEV is MBSSID */ 793 if (is_mbss_enabled) { 794 aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 795 if (!aid_mgr) { 796 mlo_err("AID bitmap allocation failed for Tx VDEV%d", 797 wlan_vdev_get_id(tx_vdev)); 798 goto free_ml_aid_mgr; 799 } 800 801 qdf_atomic_inc(&aid_mgr->ref_cnt); 802 ml_aidmgr->aid_mgr[i] = aid_mgr; 803 } else { 804 ml_aidmgr->aid_mgr[i] = wlan_vdev_aid_mgr_init(max_aid); 805 if (!ml_aidmgr->aid_mgr[i]) { 806 mlo_err("AID bitmap allocation failed for VDEV%d", 807 wlan_vdev_get_id(vdev)); 808 goto free_ml_aid_mgr; 809 } 810 wlan_vdev_mlme_set_aid_mgr(vdev, 811 ml_aidmgr->aid_mgr[i]); 812 } 813 } 814 815 return QDF_STATUS_SUCCESS; 816 817 free_ml_aid_mgr: 818 wlan_mlo_vdev_aid_mgr_deinit(ml_dev); 819 820 return QDF_STATUS_E_NOMEM; 821 } 822 823 void wlan_mlo_vdev_aid_mgr_deinit(struct wlan_mlo_dev_context *ml_dev) 824 { 825 uint8_t i; 826 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 827 int32_t n; 828 829 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 830 if (!ml_aid_mgr) 831 return; 832 833 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 834 835 if (ml_aid_mgr->aid_mgr[i]) { 836 n = qdf_atomic_read(&ml_aid_mgr->aid_mgr[i]->ref_cnt); 837 mlo_info("AID mgr ref cnt %d", n); 838 } else { 839 mlo_err("ID %d, doesn't have associated AID mgr", i); 840 continue; 841 } 842 wlan_vdev_aid_mgr_free(ml_aid_mgr->aid_mgr[i]); 843 ml_aid_mgr->aid_mgr[i] = NULL; 844 } 845 846 qdf_mem_free(ml_aid_mgr); 847 ml_dev->ap_ctx->ml_aid_mgr = NULL; 848 } 849