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