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