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