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