1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #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 mlo_peer_set_aid_bit(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,uint16_t assoc_id_ix)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 wlan_mlo_check_aid_free(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,uint16_t assoc_idx,bool skip_link,uint8_t link_ix)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 wlan_mlo_aid_idx_check(uint16_t start_idx,uint16_t end_idx,uint16_t curr_idx)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 wlan_mlo_aid_idx_update(uint16_t start_idx,uint16_t end_idx,uint16_t curr_idx)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 wlan_mlo_alloc_aid(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,uint16_t start_idx,uint16_t end_idx,uint8_t link_ix,bool is_mlo_peer)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 _wlan_mlo_peer_alloc_aid(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,bool is_mlo_peer,bool t2lm_peer,uint8_t link_ix)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 _wlan_mlo_peer_alloc_aid(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,bool is_mlo_peer,bool t2lm_peer,uint8_t link_ix)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 wlan_mlo_peer_alloc_aid(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,bool is_mlo_peer,bool t2lm_peer,uint8_t link_ix)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 wlan_mlme_peer_alloc_aid(struct wlan_vdev_aid_mgr * vdev_aid_mgr,bool no_lock)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 wlan_mlo_peer_set_aid(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,bool is_mlo_peer,uint8_t link_ix,uint16_t assoc_id)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 wlan_mlme_peer_set_aid(struct wlan_vdev_aid_mgr * vdev_aid_mgr,bool no_lock,uint16_t assoc_id)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 wlan_mlo_peer_free_aid(struct wlan_ml_vdev_aid_mgr * ml_aid_mgr,uint8_t link_ix,uint16_t assoc_id)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 wlan_mlme_peer_aid_is_set(struct wlan_vdev_aid_mgr * vdev_aid_mgr,bool no_lock,uint16_t assoc_id)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 wlan_mlme_peer_free_aid(struct wlan_vdev_aid_mgr * vdev_aid_mgr,bool no_lock,uint16_t assoc_id)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 wlan_mlme_get_aid_count(struct wlan_objmgr_vdev * vdev)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 mlo_peer_t2lm_enabled(struct wlan_mlo_peer_context * ml_peer)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 mlo_peer_t2lm_enabled(struct wlan_mlo_peer_context * ml_peer)549 static bool mlo_peer_t2lm_enabled(struct wlan_mlo_peer_context *ml_peer) 550 { 551 return false; 552 } 553 #endif 554 mlo_peer_allocate_aid(struct wlan_mlo_dev_context * ml_dev,struct wlan_mlo_peer_context * ml_peer)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 mlo_peer_free_aid(struct wlan_mlo_dev_context * ml_dev,struct wlan_mlo_peer_context * ml_peer)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 mlo_get_aid(struct wlan_objmgr_vdev * vdev)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 mlo_free_aid(struct wlan_objmgr_vdev * vdev,uint16_t assoc_id)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 mlo_peer_set_aid(struct wlan_mlo_dev_context * ml_dev,uint16_t assoc_id)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 mlo_set_aid(struct wlan_objmgr_vdev * vdev,uint16_t assoc_id)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 mlme_is_aid_set(struct wlan_objmgr_vdev * vdev,uint16_t assoc_id)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 mlme_get_aid(struct wlan_objmgr_vdev * vdev)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 mlme_set_aid(struct wlan_objmgr_vdev * vdev,uint16_t assoc_id)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 mlme_free_aid(struct wlan_objmgr_vdev * vdev,uint16_t assoc_id)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 if (!ml_dev->ap_ctx) 809 return; 810 811 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 812 if (!ml_aid_mgr) 813 return; 814 815 link_id = mlo_get_link_vdev_ix(ml_dev, vdev); 816 817 wlan_mlo_peer_free_aid(ml_aid_mgr, link_id, assoc_id); 818 } 819 wlan_vdev_mlme_aid_mgr_max_aid_set(struct wlan_objmgr_vdev * vdev,uint16_t max_aid)820 void wlan_vdev_mlme_aid_mgr_max_aid_set(struct wlan_objmgr_vdev *vdev, 821 uint16_t max_aid) 822 { 823 struct wlan_vdev_aid_mgr *aid_mgr; 824 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 825 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 826 struct wlan_mlo_dev_context *ml_dev; 827 uint16_t j, max_sta_count = 0; 828 uint16_t aidmgr_sta_count = 0; 829 830 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 831 if (!aid_mgr || !max_aid) 832 return; 833 834 mlo_debug("VDEV mgr max aid %d", max_aid); 835 836 aid_mgr->max_aid = max_aid; 837 ml_dev = vdev->mlo_dev_ctx; 838 if (ml_dev) { 839 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 840 if (!ml_aid_mgr) 841 return; 842 843 /* Derive lower max_aid */ 844 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 845 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 846 if (!vdev_aid_mgr) 847 continue; 848 849 aidmgr_sta_count = vdev_aid_mgr->max_aid - 850 vdev_aid_mgr->start_aid; 851 if (!max_sta_count) { 852 max_sta_count = aidmgr_sta_count; 853 continue; 854 } 855 856 if (max_sta_count > aidmgr_sta_count) 857 max_sta_count = aidmgr_sta_count; 858 } 859 860 ml_aid_mgr->max_aid = ml_aid_mgr->start_aid + max_sta_count; 861 mlo_debug("MLO mgr max aid %d", ml_aid_mgr->max_aid); 862 } 863 } 864 wlan_vdev_mlme_set_start_aid(struct wlan_objmgr_vdev * vdev,uint16_t start_aid)865 QDF_STATUS wlan_vdev_mlme_set_start_aid(struct wlan_objmgr_vdev *vdev, 866 uint16_t start_aid) 867 { 868 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 869 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 870 struct wlan_mlo_dev_context *ml_dev; 871 uint16_t j, max_aid_start = 0; 872 873 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 874 if (!vdev_aid_mgr) 875 return QDF_STATUS_E_FAILURE; 876 877 vdev_aid_mgr->start_aid = start_aid; 878 mlo_debug("VDEV mgr start aid %d", start_aid); 879 880 ml_dev = vdev->mlo_dev_ctx; 881 if (ml_dev) { 882 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 883 if (!ml_aid_mgr) 884 return QDF_STATUS_E_FAILURE; 885 886 /* Derive higher start_aid */ 887 for (j = 0; j < WLAN_UMAC_MLO_MAX_VDEVS; j++) { 888 vdev_aid_mgr = ml_aid_mgr->aid_mgr[j]; 889 if (!vdev_aid_mgr) 890 continue; 891 892 if (max_aid_start < vdev_aid_mgr->start_aid) 893 max_aid_start = vdev_aid_mgr->start_aid; 894 } 895 896 ml_aid_mgr->start_aid = max_aid_start; 897 mlo_debug("MLO mgr start aid %d", max_aid_start); 898 } 899 900 return QDF_STATUS_SUCCESS; 901 } 902 wlan_vdev_mlme_get_start_aid(struct wlan_objmgr_vdev * vdev)903 uint16_t wlan_vdev_mlme_get_start_aid(struct wlan_objmgr_vdev *vdev) 904 { 905 struct wlan_vdev_aid_mgr *vdev_aid_mgr; 906 907 vdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 908 if (!vdev_aid_mgr) 909 return 0; 910 911 return vdev_aid_mgr->start_aid; 912 } 913 wlan_vdev_aid_mgr_init(uint16_t max_aid)914 struct wlan_vdev_aid_mgr *wlan_vdev_aid_mgr_init(uint16_t max_aid) 915 { 916 struct wlan_vdev_aid_mgr *aid_mgr; 917 918 aid_mgr = qdf_mem_malloc(sizeof(struct wlan_vdev_aid_mgr)); 919 if (!aid_mgr) 920 return NULL; 921 922 aid_mgr->start_aid = 0; 923 aid_mgr->max_aid = max_aid; 924 qdf_atomic_init(&aid_mgr->ref_cnt); 925 /* Take reference before returning */ 926 qdf_atomic_inc(&aid_mgr->ref_cnt); 927 928 return aid_mgr; 929 } 930 wlan_vdev_aid_mgr_free(struct wlan_vdev_aid_mgr * aid_mgr)931 void wlan_vdev_aid_mgr_free(struct wlan_vdev_aid_mgr *aid_mgr) 932 { 933 if (!aid_mgr) 934 return; 935 936 if (!qdf_atomic_dec_and_test(&aid_mgr->ref_cnt)) 937 return; 938 939 aid_mgr->max_aid = 0; 940 qdf_mem_free(aid_mgr); 941 } 942 wlan_mlo_vdev_init_mbss_aid_mgr(struct wlan_mlo_dev_context * ml_dev,struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_vdev * tx_vdev)943 QDF_STATUS wlan_mlo_vdev_init_mbss_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 944 struct wlan_objmgr_vdev *vdev, 945 struct wlan_objmgr_vdev *tx_vdev) 946 { 947 struct wlan_vdev_aid_mgr *aid_mgr; 948 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 949 struct wlan_objmgr_vdev *vdev_iter; 950 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 951 uint16_t start_aid = 0; 952 uint8_t i; 953 954 if (!ml_dev) { 955 mlo_err("ML DEV pointer is NULL"); 956 return QDF_STATUS_E_FAILURE; 957 } 958 959 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 960 if (!ml_aid_mgr) { 961 mlo_err("AID mgr of ML VDEV(%d) is invalid", ml_dev->mld_id); 962 return QDF_STATUS_E_FAILURE; 963 } 964 965 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 966 if (!txvdev_aid_mgr) { 967 mlo_err("AID mgr of Tx VDEV%d is invalid", 968 wlan_vdev_get_id(tx_vdev)); 969 return QDF_STATUS_E_FAILURE; 970 } 971 972 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 973 974 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 975 vdev_iter = ml_dev->wlan_vdev_list[i]; 976 if (!vdev_iter) 977 continue; 978 979 if (vdev != vdev_iter) 980 continue; 981 982 start_aid = wlan_vdev_mlme_get_start_aid(tx_vdev); 983 /* Update start_aid, which updates MLO Dev start aid */ 984 wlan_vdev_mlme_set_start_aid(vdev, start_aid); 985 986 qdf_atomic_inc(&txvdev_aid_mgr->ref_cnt); 987 wlan_vdev_mlme_set_aid_mgr(vdev, 988 txvdev_aid_mgr); 989 ml_aid_mgr->aid_mgr[i] = txvdev_aid_mgr; 990 991 if (aid_mgr) { 992 mlo_info("AID mgr is freed for vdev %d with txvdev %d", 993 wlan_vdev_get_id(vdev), 994 wlan_vdev_get_id(tx_vdev)); 995 wlan_vdev_aid_mgr_free(aid_mgr); 996 } 997 998 mlo_debug("AID mgr replaced for vdev %d with txvdev %d", 999 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1000 } 1001 1002 return QDF_STATUS_SUCCESS; 1003 } 1004 wlan_mlo_vdev_deinit_mbss_aid_mgr(struct wlan_mlo_dev_context * mldev,struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_vdev * tx_vdev)1005 QDF_STATUS wlan_mlo_vdev_deinit_mbss_aid_mgr(struct wlan_mlo_dev_context *mldev, 1006 struct wlan_objmgr_vdev *vdev, 1007 struct wlan_objmgr_vdev *tx_vdev) 1008 { 1009 struct wlan_vdev_aid_mgr *aid_mgr; 1010 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 1011 struct wlan_objmgr_vdev *vdev_iter; 1012 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 1013 uint8_t i; 1014 1015 if (!mldev) { 1016 mlo_err("ML DEV pointer is NULL"); 1017 return QDF_STATUS_E_FAILURE; 1018 } 1019 1020 ml_aid_mgr = mldev->ap_ctx->ml_aid_mgr; 1021 if (!ml_aid_mgr) { 1022 mlo_err("AID mgr of ML VDEV(%d) is invalid", mldev->mld_id); 1023 return QDF_STATUS_E_FAILURE; 1024 } 1025 1026 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 1027 if (!txvdev_aid_mgr) { 1028 mlo_err("AID mgr of Tx VDEV%d is invalid", 1029 wlan_vdev_get_id(tx_vdev)); 1030 return QDF_STATUS_E_FAILURE; 1031 } 1032 1033 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1034 if (!aid_mgr) { 1035 mlo_err("AID mgr of VDEV%d is invalid", 1036 wlan_vdev_get_id(vdev)); 1037 return QDF_STATUS_E_FAILURE; 1038 } 1039 1040 if (aid_mgr != txvdev_aid_mgr) { 1041 mlo_err("AID mgr of VDEV%d and tx vdev(%d) aid mgr doesn't match", 1042 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1043 return QDF_STATUS_E_FAILURE; 1044 } 1045 1046 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1047 vdev_iter = mldev->wlan_vdev_list[i]; 1048 if (!vdev_iter) 1049 continue; 1050 1051 if (vdev != vdev_iter) 1052 continue; 1053 1054 aid_mgr = wlan_vdev_aid_mgr_init(ml_aid_mgr->max_aid); 1055 if (!aid_mgr) { 1056 mlo_err("AID bitmap allocation failed for VDEV%d", 1057 wlan_vdev_get_id(vdev)); 1058 QDF_BUG(0); 1059 return QDF_STATUS_E_NOMEM; 1060 } 1061 1062 wlan_vdev_mlme_set_aid_mgr(vdev, aid_mgr); 1063 ml_aid_mgr->aid_mgr[i] = aid_mgr; 1064 1065 wlan_vdev_aid_mgr_free(txvdev_aid_mgr); 1066 1067 mlo_debug("AID mgr restored for vdev %d (txvdev %d)", 1068 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1069 } 1070 1071 return QDF_STATUS_SUCCESS; 1072 } 1073 wlan_mlme_vdev_init_mbss_aid_mgr(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_vdev * tx_vdev)1074 QDF_STATUS wlan_mlme_vdev_init_mbss_aid_mgr(struct wlan_objmgr_vdev *vdev, 1075 struct wlan_objmgr_vdev *tx_vdev) 1076 { 1077 struct wlan_vdev_aid_mgr *aid_mgr; 1078 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 1079 1080 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 1081 if (!txvdev_aid_mgr) { 1082 mlo_err("AID mgr of Tx VDEV%d is invalid", 1083 wlan_vdev_get_id(tx_vdev)); 1084 return QDF_STATUS_E_FAILURE; 1085 } 1086 1087 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1088 1089 qdf_atomic_inc(&txvdev_aid_mgr->ref_cnt); 1090 wlan_vdev_mlme_set_aid_mgr(vdev, 1091 txvdev_aid_mgr); 1092 1093 if (aid_mgr) { 1094 mlo_info("AID mgr is freed for vdev %d with txvdev %d", 1095 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1096 wlan_vdev_aid_mgr_free(aid_mgr); 1097 } 1098 1099 mlo_debug("AID mgr replaced for vdev %d with txvdev %d", 1100 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1101 1102 return QDF_STATUS_SUCCESS; 1103 } 1104 wlan_mlme_vdev_deinit_mbss_aid_mgr(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_vdev * tx_vdev)1105 QDF_STATUS wlan_mlme_vdev_deinit_mbss_aid_mgr(struct wlan_objmgr_vdev *vdev, 1106 struct wlan_objmgr_vdev *tx_vdev) 1107 { 1108 struct wlan_vdev_aid_mgr *aid_mgr; 1109 struct wlan_vdev_aid_mgr *txvdev_aid_mgr; 1110 1111 txvdev_aid_mgr = wlan_vdev_mlme_get_aid_mgr(tx_vdev); 1112 if (!txvdev_aid_mgr) { 1113 mlo_err("AID mgr of Tx VDEV%d is invalid", 1114 wlan_vdev_get_id(tx_vdev)); 1115 return QDF_STATUS_E_FAILURE; 1116 } 1117 1118 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1119 if (!aid_mgr) { 1120 mlo_err("AID mgr of VDEV%d is invalid", 1121 wlan_vdev_get_id(vdev)); 1122 return QDF_STATUS_E_FAILURE; 1123 } 1124 1125 if (aid_mgr != txvdev_aid_mgr) { 1126 mlo_err("AID mgr of VDEV%d and tx vdev(%d) aid mgr doesn't match", 1127 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1128 return QDF_STATUS_E_FAILURE; 1129 } 1130 1131 aid_mgr = wlan_vdev_aid_mgr_init(txvdev_aid_mgr->max_aid); 1132 if (!aid_mgr) { 1133 mlo_err("AID bitmap allocation failed for VDEV%d", 1134 wlan_vdev_get_id(vdev)); 1135 QDF_BUG(0); 1136 return QDF_STATUS_E_NOMEM; 1137 } 1138 1139 wlan_vdev_mlme_set_aid_mgr(vdev, aid_mgr); 1140 1141 wlan_vdev_aid_mgr_free(txvdev_aid_mgr); 1142 1143 mlo_debug("AID mgr restored for vdev %d (txvdev %d)", 1144 wlan_vdev_get_id(vdev), wlan_vdev_get_id(tx_vdev)); 1145 1146 return QDF_STATUS_SUCCESS; 1147 } 1148 wlan_mlo_vdev_alloc_aid_mgr(struct wlan_mlo_dev_context * ml_dev,struct wlan_objmgr_vdev * vdev)1149 QDF_STATUS wlan_mlo_vdev_alloc_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 1150 struct wlan_objmgr_vdev *vdev) 1151 { 1152 uint8_t i; 1153 struct wlan_objmgr_vdev *vdev_iter; 1154 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 1155 struct wlan_vdev_aid_mgr *aid_mgr = NULL; 1156 uint16_t max_aid = WLAN_UMAC_MAX_AID; 1157 1158 if (!ml_dev->ap_ctx) { 1159 mlo_err(" ML AP context is not initialized"); 1160 QDF_BUG(0); 1161 return QDF_STATUS_E_NOMEM; 1162 } 1163 ml_aidmgr = ml_dev->ap_ctx->ml_aid_mgr; 1164 if (!ml_aidmgr) { 1165 mlo_err(" ML AID mgr allocation failed"); 1166 return QDF_STATUS_E_NOMEM; 1167 } 1168 1169 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1170 vdev_iter = ml_dev->wlan_vdev_list[i]; 1171 if (!vdev_iter) 1172 continue; 1173 1174 if (vdev != vdev_iter) 1175 continue; 1176 1177 /* if it is already allocated, assign it to ML AID mgr */ 1178 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1179 if (!aid_mgr) { 1180 aid_mgr = wlan_vdev_aid_mgr_init(max_aid); 1181 if (aid_mgr) { 1182 wlan_vdev_mlme_set_aid_mgr(vdev, aid_mgr); 1183 } else { 1184 mlo_err("AID bitmap allocation failed for VDEV%d", 1185 wlan_vdev_get_id(vdev)); 1186 return QDF_STATUS_E_NOMEM; 1187 } 1188 } 1189 1190 ml_aidmgr->aid_mgr[i] = aid_mgr; 1191 break; 1192 } 1193 1194 return QDF_STATUS_SUCCESS; 1195 } 1196 wlan_mlo_vdev_free_aid_mgr(struct wlan_mlo_dev_context * ml_dev,struct wlan_objmgr_vdev * vdev)1197 QDF_STATUS wlan_mlo_vdev_free_aid_mgr(struct wlan_mlo_dev_context *ml_dev, 1198 struct wlan_objmgr_vdev *vdev) 1199 { 1200 uint8_t i; 1201 struct wlan_objmgr_vdev *vdev_iter; 1202 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 1203 1204 if (!ml_dev->ap_ctx) { 1205 mlo_err(" ML AP context is not initialized"); 1206 QDF_BUG(0); 1207 return QDF_STATUS_E_NOMEM; 1208 } 1209 ml_aidmgr = ml_dev->ap_ctx->ml_aid_mgr; 1210 if (!ml_aidmgr) { 1211 mlo_err(" ML AID mgr allocation failed"); 1212 return QDF_STATUS_E_NOMEM; 1213 } 1214 1215 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1216 vdev_iter = ml_dev->wlan_vdev_list[i]; 1217 if (!vdev_iter) 1218 continue; 1219 1220 if (vdev != vdev_iter) 1221 continue; 1222 1223 wlan_vdev_aid_mgr_free(ml_aidmgr->aid_mgr[i]); 1224 ml_aidmgr->aid_mgr[i] = NULL; 1225 wlan_vdev_mlme_set_aid_mgr(vdev, NULL); 1226 break; 1227 } 1228 1229 return QDF_STATUS_SUCCESS; 1230 } 1231 wlan_mlo_vdev_aid_mgr_init(struct wlan_mlo_dev_context * ml_dev)1232 QDF_STATUS wlan_mlo_vdev_aid_mgr_init(struct wlan_mlo_dev_context *ml_dev) 1233 { 1234 uint8_t i; 1235 struct wlan_objmgr_vdev *vdev; 1236 struct wlan_ml_vdev_aid_mgr *ml_aidmgr; 1237 uint16_t max_aid = WLAN_UMAC_MAX_AID; 1238 struct wlan_vdev_aid_mgr *aid_mgr = NULL; 1239 1240 ml_aidmgr = qdf_mem_malloc(sizeof(struct wlan_ml_vdev_aid_mgr)); 1241 if (!ml_aidmgr) { 1242 ml_dev->ap_ctx->ml_aid_mgr = NULL; 1243 mlo_err(" ML AID mgr allocation failed"); 1244 return QDF_STATUS_E_NOMEM; 1245 } 1246 1247 ml_aidmgr->start_aid = 0; 1248 ml_aidmgr->max_aid = max_aid; 1249 ml_dev->ap_ctx->ml_aid_mgr = ml_aidmgr; 1250 1251 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1252 vdev = ml_dev->wlan_vdev_list[i]; 1253 if (!vdev) 1254 continue; 1255 1256 aid_mgr = wlan_vdev_mlme_get_aid_mgr(vdev); 1257 if (!aid_mgr) 1258 aid_mgr = wlan_vdev_aid_mgr_init(max_aid); 1259 1260 ml_aidmgr->aid_mgr[i] = aid_mgr; 1261 if (!ml_aidmgr->aid_mgr[i]) { 1262 mlo_err("AID bitmap allocation failed for VDEV%d", 1263 wlan_vdev_get_id(vdev)); 1264 goto free_ml_aid_mgr; 1265 } 1266 wlan_vdev_mlme_set_aid_mgr(vdev, ml_aidmgr->aid_mgr[i]); 1267 } 1268 1269 return QDF_STATUS_SUCCESS; 1270 1271 free_ml_aid_mgr: 1272 wlan_mlo_vdev_aid_mgr_deinit(ml_dev); 1273 1274 return QDF_STATUS_E_NOMEM; 1275 } 1276 wlan_mlo_vdev_aid_mgr_deinit(struct wlan_mlo_dev_context * ml_dev)1277 void wlan_mlo_vdev_aid_mgr_deinit(struct wlan_mlo_dev_context *ml_dev) 1278 { 1279 uint8_t i; 1280 struct wlan_ml_vdev_aid_mgr *ml_aid_mgr; 1281 int32_t n; 1282 1283 ml_aid_mgr = ml_dev->ap_ctx->ml_aid_mgr; 1284 if (!ml_aid_mgr) 1285 return; 1286 1287 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1288 1289 if (ml_aid_mgr->aid_mgr[i]) { 1290 n = qdf_atomic_read(&ml_aid_mgr->aid_mgr[i]->ref_cnt); 1291 mlo_info("AID mgr ref cnt %d", n); 1292 } else { 1293 mlo_err("ID %d, doesn't have associated AID mgr", i); 1294 continue; 1295 } 1296 wlan_vdev_aid_mgr_free(ml_aid_mgr->aid_mgr[i]); 1297 ml_aid_mgr->aid_mgr[i] = NULL; 1298 } 1299 1300 qdf_mem_free(ml_aid_mgr); 1301 ml_dev->ap_ctx->ml_aid_mgr = NULL; 1302 } 1303