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