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