xref: /wlan-driver/qca-wifi-host-cmn/umac/mlo_mgr/src/wlan_mlo_mgr_ap.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name /*
19*5113495bSYour Name  * DOC: contains MLO manager ap related functionality
20*5113495bSYour Name  */
21*5113495bSYour Name #include <qdf_module.h>
22*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
23*5113495bSYour Name #include "wlan_mlo_mgr_ap.h"
24*5113495bSYour Name #include <wlan_mlo_mgr_cmn.h>
25*5113495bSYour Name #include <wlan_mlo_mgr_main.h>
26*5113495bSYour Name #include <wlan_utility.h>
27*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
28*5113495bSYour Name #include "cdp_txrx_mlo.h"
29*5113495bSYour Name #endif
30*5113495bSYour Name #include "wlan_mlo_mgr_peer.h"
31*5113495bSYour Name 
32*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
mlo_ap_vdev_attach(struct wlan_objmgr_vdev * vdev,uint8_t link_id,uint16_t vdev_count)33*5113495bSYour Name bool mlo_ap_vdev_attach(struct wlan_objmgr_vdev *vdev,
34*5113495bSYour Name 			uint8_t link_id,
35*5113495bSYour Name 			uint16_t vdev_count)
36*5113495bSYour Name {
37*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
38*5113495bSYour Name 	uint8_t pr_vdev_ids[WLAN_UMAC_MLO_MAX_VDEVS] = { CDP_INVALID_VDEV_ID };
39*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
40*5113495bSYour Name 	int i;
41*5113495bSYour Name 
42*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx || !vdev->mlo_dev_ctx->ap_ctx) {
43*5113495bSYour Name 		mlo_err("Invalid input");
44*5113495bSYour Name 		return false;
45*5113495bSYour Name 	}
46*5113495bSYour Name 
47*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
48*5113495bSYour Name 	if (!psoc)
49*5113495bSYour Name 		return false;
50*5113495bSYour Name 
51*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
52*5113495bSYour Name 
53*5113495bSYour Name 	if (!vdev->vdev_objmgr.mlo_bridge_vdev) {
54*5113495bSYour Name 		wlan_vdev_set_link_id(vdev, link_id);
55*5113495bSYour Name 		wlan_vdev_mlme_set_mlo_vdev(vdev);
56*5113495bSYour Name 
57*5113495bSYour Name 		/*
58*5113495bSYour Name 		 * every link will trigger mlo_ap_vdev_attach,
59*5113495bSYour Name 		 * and they should provide the same vdev_count.
60*5113495bSYour Name 		 */
61*5113495bSYour Name 		mlo_dev_lock_acquire(dev_ctx);
62*5113495bSYour Name 		dev_ctx->ap_ctx->num_ml_vdevs = vdev_count;
63*5113495bSYour Name 		mlo_dev_lock_release(dev_ctx);
64*5113495bSYour Name 	}
65*5113495bSYour Name 
66*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
67*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i])
68*5113495bSYour Name 			pr_vdev_ids[i] = wlan_vdev_get_id(dev_ctx->wlan_vdev_list[i]);
69*5113495bSYour Name 	}
70*5113495bSYour Name 
71*5113495bSYour Name 	/* reset the vdev id list */
72*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++)
73*5113495bSYour Name 		pr_vdev_ids[i] = CDP_INVALID_VDEV_ID;
74*5113495bSYour Name 
75*5113495bSYour Name 	/* update the bridge vaps in partner list*/
76*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MLO_MAX_BRIDGE_VDEVS; i++) {
77*5113495bSYour Name 		if (dev_ctx->wlan_bridge_vdev_list[i])
78*5113495bSYour Name 			pr_vdev_ids[i] = wlan_vdev_get_id(
79*5113495bSYour Name 					dev_ctx->wlan_bridge_vdev_list[i]);
80*5113495bSYour Name 	}
81*5113495bSYour Name 
82*5113495bSYour Name 	return true;
83*5113495bSYour Name }
84*5113495bSYour Name #else
mlo_ap_vdev_attach(struct wlan_objmgr_vdev * vdev,uint8_t link_id,uint16_t vdev_count)85*5113495bSYour Name bool mlo_ap_vdev_attach(struct wlan_objmgr_vdev *vdev,
86*5113495bSYour Name 			uint8_t link_id,
87*5113495bSYour Name 			uint16_t vdev_count)
88*5113495bSYour Name {
89*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
90*5113495bSYour Name 
91*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx || !vdev->mlo_dev_ctx->ap_ctx) {
92*5113495bSYour Name 		mlo_err("Invalid input");
93*5113495bSYour Name 		return false;
94*5113495bSYour Name 	}
95*5113495bSYour Name 
96*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
97*5113495bSYour Name 	wlan_vdev_set_link_id(vdev, link_id);
98*5113495bSYour Name 	wlan_vdev_mlme_set_mlo_vdev(vdev);
99*5113495bSYour Name 
100*5113495bSYour Name 	/*
101*5113495bSYour Name 	 * every link will trigger mlo_ap_vdev_attach,
102*5113495bSYour Name 	 * and they should provide the same vdev_count.
103*5113495bSYour Name 	 */
104*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
105*5113495bSYour Name 	dev_ctx->ap_ctx->num_ml_vdevs = vdev_count;
106*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
107*5113495bSYour Name 
108*5113495bSYour Name 	return true;
109*5113495bSYour Name }
110*5113495bSYour Name #endif
111*5113495bSYour Name 
112*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
mlo_ap_get_bridge_vdev_list(struct wlan_objmgr_vdev * vdev,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_bridge_vdev_list)113*5113495bSYour Name void mlo_ap_get_bridge_vdev_list(struct wlan_objmgr_vdev *vdev,
114*5113495bSYour Name 				 uint16_t *vdev_count,
115*5113495bSYour Name 				 struct wlan_objmgr_vdev **wlan_bridge_vdev_list)
116*5113495bSYour Name {
117*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
118*5113495bSYour Name 	int i;
119*5113495bSYour Name 	QDF_STATUS status;
120*5113495bSYour Name 
121*5113495bSYour Name 	*vdev_count = 0;
122*5113495bSYour Name 
123*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
124*5113495bSYour Name 		mlo_err("Invalid input");
125*5113495bSYour Name 		return;
126*5113495bSYour Name 	}
127*5113495bSYour Name 
128*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
129*5113495bSYour Name 
130*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
131*5113495bSYour Name 	*vdev_count = 0;
132*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_bridge_vdev_list); i++) {
133*5113495bSYour Name 		if (dev_ctx->wlan_bridge_vdev_list[i]) {
134*5113495bSYour Name 			status = wlan_objmgr_vdev_try_get_ref(
135*5113495bSYour Name 						dev_ctx->wlan_bridge_vdev_list[i],
136*5113495bSYour Name 						WLAN_MLO_MGR_ID);
137*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status))
138*5113495bSYour Name 				break;
139*5113495bSYour Name 			wlan_bridge_vdev_list[*vdev_count] =
140*5113495bSYour Name 				dev_ctx->wlan_bridge_vdev_list[i];
141*5113495bSYour Name 			(*vdev_count) += 1;
142*5113495bSYour Name 		}
143*5113495bSYour Name 	}
144*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
145*5113495bSYour Name }
146*5113495bSYour Name 
mlo_ap_get_bridge_vdev_count(struct wlan_mlo_dev_context * mld_ctx,uint16_t * vdev_count)147*5113495bSYour Name QDF_STATUS mlo_ap_get_bridge_vdev_count(struct wlan_mlo_dev_context *mld_ctx,
148*5113495bSYour Name 					uint16_t *vdev_count)
149*5113495bSYour Name {
150*5113495bSYour Name 	int i;
151*5113495bSYour Name 
152*5113495bSYour Name 	*vdev_count = 0;
153*5113495bSYour Name 
154*5113495bSYour Name 	if (!mld_ctx) {
155*5113495bSYour Name 		mlo_err("Invalid input");
156*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
157*5113495bSYour Name 	}
158*5113495bSYour Name 
159*5113495bSYour Name 	mlo_dev_lock_acquire(mld_ctx);
160*5113495bSYour Name 	*vdev_count = 0;
161*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(mld_ctx->wlan_bridge_vdev_list); i++) {
162*5113495bSYour Name 		if (mld_ctx->wlan_bridge_vdev_list[i])
163*5113495bSYour Name 			(*vdev_count) += 1;
164*5113495bSYour Name 	}
165*5113495bSYour Name 	mlo_dev_lock_release(mld_ctx);
166*5113495bSYour Name 
167*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
168*5113495bSYour Name }
169*5113495bSYour Name 
mlo_ap_get_vdev_list_no_flag(struct wlan_objmgr_vdev * vdev,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_vdev_list)170*5113495bSYour Name void mlo_ap_get_vdev_list_no_flag(struct wlan_objmgr_vdev *vdev,
171*5113495bSYour Name 				  uint16_t *vdev_count,
172*5113495bSYour Name 				  struct wlan_objmgr_vdev **wlan_vdev_list)
173*5113495bSYour Name {
174*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
175*5113495bSYour Name 	int i;
176*5113495bSYour Name 	QDF_STATUS status;
177*5113495bSYour Name 
178*5113495bSYour Name 	*vdev_count = 0;
179*5113495bSYour Name 
180*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
181*5113495bSYour Name 		mlo_err("Invalid input");
182*5113495bSYour Name 		return;
183*5113495bSYour Name 	}
184*5113495bSYour Name 
185*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
186*5113495bSYour Name 
187*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
188*5113495bSYour Name 	*vdev_count = 0;
189*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
190*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i]) {
191*5113495bSYour Name 			status = wlan_objmgr_vdev_try_get_ref(
192*5113495bSYour Name 					dev_ctx->wlan_vdev_list[i],
193*5113495bSYour Name 					WLAN_MLO_MGR_ID);
194*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status))
195*5113495bSYour Name 				break;
196*5113495bSYour Name 			wlan_vdev_list[*vdev_count] =
197*5113495bSYour Name 				dev_ctx->wlan_vdev_list[i];
198*5113495bSYour Name 			(*vdev_count) += 1;
199*5113495bSYour Name 		}
200*5113495bSYour Name 	}
201*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
202*5113495bSYour Name }
203*5113495bSYour Name #endif
204*5113495bSYour Name 
mlo_peer_get_vdev_list(struct wlan_objmgr_peer * peer,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_vdev_list)205*5113495bSYour Name void mlo_peer_get_vdev_list(struct wlan_objmgr_peer *peer,
206*5113495bSYour Name 			    uint16_t *vdev_count,
207*5113495bSYour Name 			    struct wlan_objmgr_vdev **wlan_vdev_list)
208*5113495bSYour Name {
209*5113495bSYour Name 	struct wlan_mlo_link_peer_entry *peer_entry;
210*5113495bSYour Name 	struct wlan_objmgr_peer *link_peer;
211*5113495bSYour Name 	int i;
212*5113495bSYour Name 	QDF_STATUS status;
213*5113495bSYour Name 
214*5113495bSYour Name 	*vdev_count = 0;
215*5113495bSYour Name 
216*5113495bSYour Name 	if (!peer) {
217*5113495bSYour Name 		mlo_err("Invalid input");
218*5113495bSYour Name 		return;
219*5113495bSYour Name 	}
220*5113495bSYour Name 
221*5113495bSYour Name 	mlo_peer_lock_acquire(peer->mlo_peer_ctx);
222*5113495bSYour Name 
223*5113495bSYour Name 	for (i = 0; i < MAX_MLO_LINK_PEERS; i++) {
224*5113495bSYour Name 		peer_entry = &peer->mlo_peer_ctx->peer_list[i];
225*5113495bSYour Name 		link_peer = peer_entry->link_peer;
226*5113495bSYour Name 		if (!link_peer)
227*5113495bSYour Name 			continue;
228*5113495bSYour Name 
229*5113495bSYour Name 		status = wlan_objmgr_vdev_try_get_ref(
230*5113495bSYour Name 				wlan_peer_get_vdev(link_peer),
231*5113495bSYour Name 				WLAN_MLO_MGR_ID);
232*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status))
233*5113495bSYour Name 			break;
234*5113495bSYour Name 
235*5113495bSYour Name 		wlan_vdev_list[*vdev_count] =
236*5113495bSYour Name 				wlan_peer_get_vdev(link_peer);
237*5113495bSYour Name 		(*vdev_count) += 1;
238*5113495bSYour Name 	}
239*5113495bSYour Name 
240*5113495bSYour Name 	mlo_peer_lock_release(peer->mlo_peer_ctx);
241*5113495bSYour Name }
242*5113495bSYour Name 
mlo_ap_get_vdev_list(struct wlan_objmgr_vdev * vdev,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_vdev_list)243*5113495bSYour Name void mlo_ap_get_vdev_list(struct wlan_objmgr_vdev *vdev,
244*5113495bSYour Name 			  uint16_t *vdev_count,
245*5113495bSYour Name 			  struct wlan_objmgr_vdev **wlan_vdev_list)
246*5113495bSYour Name {
247*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
248*5113495bSYour Name 	int i;
249*5113495bSYour Name 	QDF_STATUS status;
250*5113495bSYour Name 
251*5113495bSYour Name 	*vdev_count = 0;
252*5113495bSYour Name 
253*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
254*5113495bSYour Name 		mlo_err("Invalid input");
255*5113495bSYour Name 		return;
256*5113495bSYour Name 	}
257*5113495bSYour Name 
258*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
259*5113495bSYour Name 
260*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
261*5113495bSYour Name 	*vdev_count = 0;
262*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
263*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i] &&
264*5113495bSYour Name 		    wlan_vdev_mlme_is_mlo_ap(dev_ctx->wlan_vdev_list[i])) {
265*5113495bSYour Name 			status = wlan_objmgr_vdev_try_get_ref(
266*5113495bSYour Name 						dev_ctx->wlan_vdev_list[i],
267*5113495bSYour Name 						WLAN_MLO_MGR_ID);
268*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status))
269*5113495bSYour Name 				break;
270*5113495bSYour Name 			wlan_vdev_list[*vdev_count] =
271*5113495bSYour Name 				dev_ctx->wlan_vdev_list[i];
272*5113495bSYour Name 			(*vdev_count) += 1;
273*5113495bSYour Name 		}
274*5113495bSYour Name 	}
275*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
276*5113495bSYour Name }
277*5113495bSYour Name 
mlo_ap_get_active_vdev_list(struct wlan_objmgr_vdev * vdev,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_vdev_list)278*5113495bSYour Name void mlo_ap_get_active_vdev_list(struct wlan_objmgr_vdev *vdev,
279*5113495bSYour Name 				 uint16_t *vdev_count,
280*5113495bSYour Name 				 struct wlan_objmgr_vdev **wlan_vdev_list)
281*5113495bSYour Name {
282*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
283*5113495bSYour Name 	int i;
284*5113495bSYour Name 	QDF_STATUS status;
285*5113495bSYour Name 	struct wlan_objmgr_vdev *partner_vdev = NULL;
286*5113495bSYour Name 
287*5113495bSYour Name 	*vdev_count = 0;
288*5113495bSYour Name 
289*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
290*5113495bSYour Name 		mlo_err("Invalid input");
291*5113495bSYour Name 		return;
292*5113495bSYour Name 	}
293*5113495bSYour Name 
294*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
295*5113495bSYour Name 
296*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
297*5113495bSYour Name 	*vdev_count = 0;
298*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
299*5113495bSYour Name 		partner_vdev = dev_ctx->wlan_vdev_list[i];
300*5113495bSYour Name 		if (partner_vdev &&
301*5113495bSYour Name 		    wlan_vdev_mlme_is_mlo_ap(partner_vdev)) {
302*5113495bSYour Name 			if (wlan_vdev_chan_config_valid(partner_vdev) !=
303*5113495bSYour Name 						 QDF_STATUS_SUCCESS)
304*5113495bSYour Name 				continue;
305*5113495bSYour Name 
306*5113495bSYour Name 			status = wlan_objmgr_vdev_try_get_ref(partner_vdev,
307*5113495bSYour Name 							      WLAN_MLO_MGR_ID);
308*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status))
309*5113495bSYour Name 				break;
310*5113495bSYour Name 			wlan_vdev_list[*vdev_count] = partner_vdev;
311*5113495bSYour Name 			(*vdev_count) += 1;
312*5113495bSYour Name 		}
313*5113495bSYour Name 	}
314*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
315*5113495bSYour Name }
316*5113495bSYour Name 
mlo_ap_get_partner_vdev_list_from_mld(struct wlan_objmgr_vdev * vdev,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_vdev_list)317*5113495bSYour Name void mlo_ap_get_partner_vdev_list_from_mld(
318*5113495bSYour Name 		struct wlan_objmgr_vdev *vdev,
319*5113495bSYour Name 		uint16_t *vdev_count,
320*5113495bSYour Name 		struct wlan_objmgr_vdev **wlan_vdev_list)
321*5113495bSYour Name {
322*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
323*5113495bSYour Name 	int i;
324*5113495bSYour Name 	QDF_STATUS status;
325*5113495bSYour Name 
326*5113495bSYour Name 	*vdev_count = 0;
327*5113495bSYour Name 
328*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
329*5113495bSYour Name 		mlo_err("Invalid input");
330*5113495bSYour Name 		return;
331*5113495bSYour Name 	}
332*5113495bSYour Name 
333*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
334*5113495bSYour Name 
335*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
336*5113495bSYour Name 	*vdev_count = 0;
337*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
338*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i] &&
339*5113495bSYour Name 		    (QDF_SAP_MODE ==
340*5113495bSYour Name 		     wlan_vdev_mlme_get_opmode(dev_ctx->wlan_vdev_list[i]))) {
341*5113495bSYour Name 			status = wlan_objmgr_vdev_try_get_ref(
342*5113495bSYour Name 						dev_ctx->wlan_vdev_list[i],
343*5113495bSYour Name 						WLAN_MLO_MGR_ID);
344*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status))
345*5113495bSYour Name 				break;
346*5113495bSYour Name 			wlan_vdev_list[*vdev_count] =
347*5113495bSYour Name 				dev_ctx->wlan_vdev_list[i];
348*5113495bSYour Name 			(*vdev_count) += 1;
349*5113495bSYour Name 		}
350*5113495bSYour Name 	}
351*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
352*5113495bSYour Name }
353*5113495bSYour Name 
354*5113495bSYour Name /**
355*5113495bSYour Name  * mlo_ap_vdev_is_start_resp_rcvd() - Is start response received on this vdev
356*5113495bSYour Name  * @vdev: vdev pointer
357*5113495bSYour Name  *
358*5113495bSYour Name  * Return: SUCCESS if start response is received, ERROR otherwise.
359*5113495bSYour Name  */
mlo_ap_vdev_is_start_resp_rcvd(struct wlan_objmgr_vdev * vdev)360*5113495bSYour Name static QDF_STATUS mlo_ap_vdev_is_start_resp_rcvd(struct wlan_objmgr_vdev *vdev)
361*5113495bSYour Name {
362*5113495bSYour Name 	enum wlan_vdev_state state;
363*5113495bSYour Name 
364*5113495bSYour Name 	if (!vdev) {
365*5113495bSYour Name 		mlme_err("vdev is null");
366*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
367*5113495bSYour Name 	}
368*5113495bSYour Name 
369*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_ap(vdev))
370*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
371*5113495bSYour Name 
372*5113495bSYour Name 	state = wlan_vdev_mlme_get_state(vdev);
373*5113495bSYour Name 	if ((state == WLAN_VDEV_S_UP) ||
374*5113495bSYour Name 	    (state == WLAN_VDEV_S_DFS_CAC_WAIT) ||
375*5113495bSYour Name 	    (state == WLAN_VDEV_S_SUSPEND))
376*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
377*5113495bSYour Name 
378*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
379*5113495bSYour Name }
380*5113495bSYour Name 
wlan_mlo_ap_get_active_links(struct wlan_objmgr_vdev * vdev)381*5113495bSYour Name uint16_t wlan_mlo_ap_get_active_links(struct wlan_objmgr_vdev *vdev)
382*5113495bSYour Name {
383*5113495bSYour Name 	uint16_t vdev_count = 0;
384*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
385*5113495bSYour Name 	int i;
386*5113495bSYour Name 
387*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx || !vdev->mlo_dev_ctx->ap_ctx) {
388*5113495bSYour Name 		mlo_err("Invalid input");
389*5113495bSYour Name 		return vdev_count;
390*5113495bSYour Name 	}
391*5113495bSYour Name 
392*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
393*5113495bSYour Name 
394*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
395*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
396*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i] && QDF_IS_STATUS_SUCCESS(
397*5113495bSYour Name 		    mlo_ap_vdev_is_start_resp_rcvd(dev_ctx->wlan_vdev_list[i])))
398*5113495bSYour Name 			vdev_count++;
399*5113495bSYour Name 	}
400*5113495bSYour Name 
401*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
402*5113495bSYour Name 
403*5113495bSYour Name 	return vdev_count;
404*5113495bSYour Name }
405*5113495bSYour Name 
406*5113495bSYour Name /**
407*5113495bSYour Name  * mlo_is_ap_vdev_up_allowed() - Is mlo ap allowed to come up
408*5113495bSYour Name  * @vdev: vdev pointer
409*5113495bSYour Name  *
410*5113495bSYour Name  * Return: true if given ap is allowed to up, false otherwise.
411*5113495bSYour Name  */
mlo_is_ap_vdev_up_allowed(struct wlan_objmgr_vdev * vdev)412*5113495bSYour Name static bool mlo_is_ap_vdev_up_allowed(struct wlan_objmgr_vdev *vdev)
413*5113495bSYour Name {
414*5113495bSYour Name 	uint16_t vdev_count = 0;
415*5113495bSYour Name 	bool up_allowed = false;
416*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
417*5113495bSYour Name 
418*5113495bSYour Name 	if (!vdev) {
419*5113495bSYour Name 		mlo_err("Invalid input");
420*5113495bSYour Name 		return up_allowed;
421*5113495bSYour Name 	}
422*5113495bSYour Name 
423*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
424*5113495bSYour Name 
425*5113495bSYour Name 	vdev_count = wlan_mlo_ap_get_active_links(vdev);
426*5113495bSYour Name 	if (vdev_count == dev_ctx->ap_ctx->num_ml_vdevs)
427*5113495bSYour Name 		up_allowed = true;
428*5113495bSYour Name 
429*5113495bSYour Name 	return up_allowed;
430*5113495bSYour Name }
431*5113495bSYour Name 
432*5113495bSYour Name /**
433*5113495bSYour Name  * mlo_pre_link_up() - Carry out preparation before bringing up the link
434*5113495bSYour Name  * @vdev: vdev pointer
435*5113495bSYour Name  *
436*5113495bSYour Name  * Return: true if preparation is done successfully
437*5113495bSYour Name  */
mlo_pre_link_up(struct wlan_objmgr_vdev * vdev)438*5113495bSYour Name static bool mlo_pre_link_up(struct wlan_objmgr_vdev *vdev)
439*5113495bSYour Name {
440*5113495bSYour Name 	if (!vdev) {
441*5113495bSYour Name 		mlo_err("vdev is NULL");
442*5113495bSYour Name 		return false;
443*5113495bSYour Name 	}
444*5113495bSYour Name 
445*5113495bSYour Name 	if ((wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP) &&
446*5113495bSYour Name 	    (wlan_vdev_mlme_get_substate(vdev) ==
447*5113495bSYour Name 	     WLAN_VDEV_SS_MLO_SYNC_WAIT))
448*5113495bSYour Name 		return true;
449*5113495bSYour Name 
450*5113495bSYour Name 	return false;
451*5113495bSYour Name }
452*5113495bSYour Name 
453*5113495bSYour Name /**
454*5113495bSYour Name  * mlo_handle_link_ready() - Check if mlo ap is allowed to up or not.
455*5113495bSYour Name  *                           If it is allowed, for every link in the
456*5113495bSYour Name  *                           WLAN_VDEV_SS_MLO_SYNC_WAIT state, deliver
457*5113495bSYour Name  *                           event WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE.
458*5113495bSYour Name  *
459*5113495bSYour Name  * This function is triggered once a link gets start response or enters
460*5113495bSYour Name  * WLAN_VDEV_SS_MLO_SYNC_WAIT state
461*5113495bSYour Name  *
462*5113495bSYour Name  * @vdev: vdev pointer
463*5113495bSYour Name  *
464*5113495bSYour Name  * Return: true if MLO_SYNC_COMPLETE is posted, else false
465*5113495bSYour Name  */
mlo_handle_link_ready(struct wlan_objmgr_vdev * vdev)466*5113495bSYour Name static bool mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
467*5113495bSYour Name {
468*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {NULL};
469*5113495bSYour Name 	struct wlan_mlo_dev_context *mld_ctx = NULL;
470*5113495bSYour Name 	uint16_t num_links = 0;
471*5113495bSYour Name 	uint8_t i;
472*5113495bSYour Name 	uint8_t idx;
473*5113495bSYour Name 	enum wlan_vdev_state state;
474*5113495bSYour Name 	enum wlan_vdev_state substate;
475*5113495bSYour Name 
476*5113495bSYour Name 
477*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
478*5113495bSYour Name 		mlo_err("Invalid input");
479*5113495bSYour Name 		return false;
480*5113495bSYour Name 	}
481*5113495bSYour Name 
482*5113495bSYour Name 	if (wlan_vdev_is_up(vdev) == QDF_STATUS_SUCCESS)
483*5113495bSYour Name 		return true;
484*5113495bSYour Name 
485*5113495bSYour Name 	mld_ctx = vdev->mlo_dev_ctx;
486*5113495bSYour Name 	/*
487*5113495bSYour Name 	 * The last vdev in MLD to receive start response is responsible for
488*5113495bSYour Name 	 * dispatching MLO_SYNC_COMPLETE event all the partner vdevs and then to
489*5113495bSYour Name 	 * self.
490*5113495bSYour Name 	 *
491*5113495bSYour Name 	 * If vdev_up_bmap is set, then return.
492*5113495bSYour Name 	 */
493*5113495bSYour Name 	idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
494*5113495bSYour Name 	if (idx == MLO_INVALID_LINK_IDX)
495*5113495bSYour Name 		return false;
496*5113495bSYour Name 
497*5113495bSYour Name 	if (wlan_util_map_index_is_set(mld_ctx->ap_ctx->mlo_vdev_up_bmap,
498*5113495bSYour Name 				       idx)) {
499*5113495bSYour Name 		mlo_debug("Bmap is set for idx:%u mld_addr " QDF_MAC_ADDR_FMT,
500*5113495bSYour Name 			  idx, QDF_MAC_ADDR_REF(mld_ctx->mld_addr.bytes));
501*5113495bSYour Name 		return false;
502*5113495bSYour Name 	}
503*5113495bSYour Name 
504*5113495bSYour Name 	mlo_ap_lock_acquire(vdev->mlo_dev_ctx->ap_ctx);
505*5113495bSYour Name 	state = wlan_vdev_mlme_get_state(vdev);
506*5113495bSYour Name 	substate = wlan_vdev_mlme_get_substate(vdev);
507*5113495bSYour Name 	if (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_MLO_SYNC_WAIT) {
508*5113495bSYour Name 		idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
509*5113495bSYour Name 		if (idx == MLO_INVALID_LINK_IDX) {
510*5113495bSYour Name 			mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
511*5113495bSYour Name 			return false;
512*5113495bSYour Name 		}
513*5113495bSYour Name 		wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_up_bmap,
514*5113495bSYour Name 					   idx, 1);
515*5113495bSYour Name 		mlo_debug("Setting Bmap for idx:%u mld_addr " QDF_MAC_ADDR_FMT,
516*5113495bSYour Name 			  idx, QDF_MAC_ADDR_REF(mld_ctx->mld_addr.bytes));
517*5113495bSYour Name 	}
518*5113495bSYour Name 
519*5113495bSYour Name 	if (!mlo_is_ap_vdev_up_allowed(vdev)) {
520*5113495bSYour Name 		mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
521*5113495bSYour Name 		return false;
522*5113495bSYour Name 	}
523*5113495bSYour Name 
524*5113495bSYour Name 	mlo_ap_get_vdev_list(vdev, &num_links, vdev_list);
525*5113495bSYour Name 	if (!num_links || (num_links > QDF_ARRAY_SIZE(vdev_list))) {
526*5113495bSYour Name 		mlo_err("Invalid number of VDEVs under AP-MLD");
527*5113495bSYour Name 		mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
528*5113495bSYour Name 		return false;
529*5113495bSYour Name 	}
530*5113495bSYour Name 
531*5113495bSYour Name 	for (i = 0; i < num_links; i++) {
532*5113495bSYour Name 		if (mlo_pre_link_up(vdev_list[i])) {
533*5113495bSYour Name 			if (vdev_list[i] == vdev) {
534*5113495bSYour Name 				mlo_release_vdev_ref(vdev_list[i]);
535*5113495bSYour Name 				continue;
536*5113495bSYour Name 			}
537*5113495bSYour Name 
538*5113495bSYour Name 			idx = mlo_get_link_vdev_ix(mld_ctx, vdev_list[i]);
539*5113495bSYour Name 			if (idx == MLO_INVALID_LINK_IDX) {
540*5113495bSYour Name 				mlo_release_vdev_ref(vdev_list[i]);
541*5113495bSYour Name 				continue;
542*5113495bSYour Name 			}
543*5113495bSYour Name 
544*5113495bSYour Name 			if (wlan_util_map_index_is_set(
545*5113495bSYour Name 				vdev->mlo_dev_ctx->ap_ctx->mlo_vdev_up_bmap,
546*5113495bSYour Name 				idx))
547*5113495bSYour Name 				wlan_vdev_mlme_sm_deliver_evt(
548*5113495bSYour Name 					vdev_list[i],
549*5113495bSYour Name 					WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE,
550*5113495bSYour Name 					0, NULL);
551*5113495bSYour Name 		}
552*5113495bSYour Name 		/* Release ref taken as part of mlo_ap_get_vdev_list */
553*5113495bSYour Name 		mlo_release_vdev_ref(vdev_list[i]);
554*5113495bSYour Name 	}
555*5113495bSYour Name 
556*5113495bSYour Name 	/* Clear up bmap for this vdev as it is moving to UP_ACTIVE state */
557*5113495bSYour Name 	idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
558*5113495bSYour Name 	wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_up_bmap, idx, 0);
559*5113495bSYour Name 
560*5113495bSYour Name 	mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
561*5113495bSYour Name 	return true;
562*5113495bSYour Name }
563*5113495bSYour Name 
mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev * vdev)564*5113495bSYour Name bool mlo_ap_link_sync_wait_notify(struct wlan_objmgr_vdev *vdev)
565*5113495bSYour Name {
566*5113495bSYour Name 	return mlo_handle_link_ready(vdev);
567*5113495bSYour Name }
568*5113495bSYour Name 
mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev * vdev)569*5113495bSYour Name void mlo_ap_link_start_rsp_notify(struct wlan_objmgr_vdev *vdev)
570*5113495bSYour Name {
571*5113495bSYour Name 	mlo_handle_link_ready(vdev);
572*5113495bSYour Name }
573*5113495bSYour Name 
mlo_ap_vdev_detach(struct wlan_objmgr_vdev * vdev)574*5113495bSYour Name void mlo_ap_vdev_detach(struct wlan_objmgr_vdev *vdev)
575*5113495bSYour Name {
576*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
577*5113495bSYour Name 
578*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
579*5113495bSYour Name 		mlo_err("Invalid input");
580*5113495bSYour Name 		return;
581*5113495bSYour Name 	}
582*5113495bSYour Name 
583*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
584*5113495bSYour Name 
585*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
586*5113495bSYour Name 	dev_ctx->ap_ctx->num_ml_vdevs--;
587*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
588*5113495bSYour Name 
589*5113495bSYour Name 	wlan_vdev_mlme_clear_mlo_vdev(vdev);
590*5113495bSYour Name }
591*5113495bSYour Name 
mlo_ap_link_down_cmpl_notify(struct wlan_objmgr_vdev * vdev)592*5113495bSYour Name void mlo_ap_link_down_cmpl_notify(struct wlan_objmgr_vdev *vdev)
593*5113495bSYour Name {
594*5113495bSYour Name 	mlo_ap_vdev_detach(vdev);
595*5113495bSYour Name }
596*5113495bSYour Name 
597*5113495bSYour Name QDF_STATUS
mlo_ap_update_max_ml_peer_ids(uint32_t pdev_id,uint32_t max_ml_peer_ids)598*5113495bSYour Name mlo_ap_update_max_ml_peer_ids(uint32_t pdev_id, uint32_t max_ml_peer_ids)
599*5113495bSYour Name {
600*5113495bSYour Name 	struct mlo_mgr_context *mlo_mgr_ctx = wlan_objmgr_get_mlo_ctx();
601*5113495bSYour Name 	uint16_t max_mlo_peer_id_stale;
602*5113495bSYour Name 
603*5113495bSYour Name 	max_mlo_peer_id_stale = mlo_mgr_ctx->max_mlo_peer_id;
604*5113495bSYour Name 
605*5113495bSYour Name 	ml_peerid_lock_acquire(mlo_mgr_ctx);
606*5113495bSYour Name 
607*5113495bSYour Name 	/* Reset the value to default if max_ml_peer_ids received is "0" */
608*5113495bSYour Name 	mlo_mgr_ctx->max_mlo_peer_id = max_ml_peer_ids ?
609*5113495bSYour Name 				max_ml_peer_ids : MAX_MLO_PEER_ID;
610*5113495bSYour Name 
611*5113495bSYour Name 	mlo_info("max_ml_peer_ids update from: %d to: %d for pdev: %d",
612*5113495bSYour Name 		 max_mlo_peer_id_stale,
613*5113495bSYour Name 		 mlo_mgr_ctx->max_mlo_peer_id, pdev_id);
614*5113495bSYour Name 
615*5113495bSYour Name 	mlo_info("max_peer support from target obtained :%d", max_ml_peer_ids);
616*5113495bSYour Name 
617*5113495bSYour Name 	ml_peerid_lock_release(mlo_mgr_ctx);
618*5113495bSYour Name 
619*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
620*5113495bSYour Name }
621*5113495bSYour Name 
622*5113495bSYour Name qdf_export_symbol(mlo_ap_update_max_ml_peer_ids);
623*5113495bSYour Name 
mlo_ap_ml_peerid_alloc(void)624*5113495bSYour Name uint16_t mlo_ap_ml_peerid_alloc(void)
625*5113495bSYour Name {
626*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
627*5113495bSYour Name 	uint16_t i;
628*5113495bSYour Name 	uint16_t mlo_peer_id;
629*5113495bSYour Name 
630*5113495bSYour Name 	ml_peerid_lock_acquire(mlo_ctx);
631*5113495bSYour Name 	mlo_peer_id = mlo_ctx->last_mlo_peer_id;
632*5113495bSYour Name 	for (i = 0; i < mlo_ctx->max_mlo_peer_id; i++) {
633*5113495bSYour Name 		mlo_peer_id = (mlo_peer_id + 1) % mlo_ctx->max_mlo_peer_id;
634*5113495bSYour Name 
635*5113495bSYour Name 		if (!mlo_peer_id)
636*5113495bSYour Name 			continue;
637*5113495bSYour Name 
638*5113495bSYour Name 		if (qdf_test_bit(mlo_peer_id, mlo_ctx->mlo_peer_id_bmap))
639*5113495bSYour Name 			continue;
640*5113495bSYour Name 
641*5113495bSYour Name 		qdf_set_bit(mlo_peer_id, mlo_ctx->mlo_peer_id_bmap);
642*5113495bSYour Name 		break;
643*5113495bSYour Name 	}
644*5113495bSYour Name 	mlo_ctx->last_mlo_peer_id = mlo_peer_id;
645*5113495bSYour Name 	ml_peerid_lock_release(mlo_ctx);
646*5113495bSYour Name 
647*5113495bSYour Name 	if (i == mlo_ctx->max_mlo_peer_id)
648*5113495bSYour Name 		return MLO_INVALID_PEER_ID;
649*5113495bSYour Name 
650*5113495bSYour Name 	mlo_debug(" ML peer id %d is allocated", mlo_peer_id);
651*5113495bSYour Name 
652*5113495bSYour Name 	return mlo_peer_id;
653*5113495bSYour Name }
654*5113495bSYour Name 
655*5113495bSYour Name #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE
mlo_ap_ml_ptqm_peerid_free(struct wlan_mlo_dev_context * ml_dev,uint16_t mlo_peer_id)656*5113495bSYour Name void mlo_ap_ml_ptqm_peerid_free(struct wlan_mlo_dev_context *ml_dev,
657*5113495bSYour Name 				uint16_t mlo_peer_id)
658*5113495bSYour Name {
659*5113495bSYour Name 	/* Free the bitmap for ptqm migration */
660*5113495bSYour Name 	if (qdf_test_bit(mlo_peer_id, ml_dev->mlo_peer_id_bmap))
661*5113495bSYour Name 		qdf_clear_bit(mlo_peer_id, ml_dev->mlo_peer_id_bmap);
662*5113495bSYour Name }
663*5113495bSYour Name #endif
664*5113495bSYour Name 
mlo_ap_ml_peerid_free(uint16_t mlo_peer_id)665*5113495bSYour Name void mlo_ap_ml_peerid_free(uint16_t mlo_peer_id)
666*5113495bSYour Name {
667*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
668*5113495bSYour Name 
669*5113495bSYour Name 	if ((mlo_peer_id == 0) || (mlo_peer_id == MLO_INVALID_PEER_ID)) {
670*5113495bSYour Name 		mlo_err(" ML peer id %d is invalid", mlo_peer_id);
671*5113495bSYour Name 		return;
672*5113495bSYour Name 	}
673*5113495bSYour Name 
674*5113495bSYour Name 	if ((mlo_peer_id > mlo_ctx->max_mlo_peer_id) ||
675*5113495bSYour Name 	    (mlo_peer_id > MAX_MLO_PEER_ID)) {
676*5113495bSYour Name 		mlo_err(" ML peer id %d is invalid", mlo_peer_id);
677*5113495bSYour Name 		QDF_BUG(0);
678*5113495bSYour Name 		return;
679*5113495bSYour Name 	}
680*5113495bSYour Name 
681*5113495bSYour Name 	ml_peerid_lock_acquire(mlo_ctx);
682*5113495bSYour Name 	if (qdf_test_bit(mlo_peer_id, mlo_ctx->mlo_peer_id_bmap))
683*5113495bSYour Name 		qdf_clear_bit(mlo_peer_id, mlo_ctx->mlo_peer_id_bmap);
684*5113495bSYour Name 
685*5113495bSYour Name 	ml_peerid_lock_release(mlo_ctx);
686*5113495bSYour Name 
687*5113495bSYour Name 	mlo_debug(" ML peer id %d is freed", mlo_peer_id);
688*5113495bSYour Name }
689*5113495bSYour Name 
mlo_ap_vdev_quiet_set(struct wlan_objmgr_vdev * vdev)690*5113495bSYour Name void mlo_ap_vdev_quiet_set(struct wlan_objmgr_vdev *vdev)
691*5113495bSYour Name {
692*5113495bSYour Name 	struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx;
693*5113495bSYour Name 	uint8_t idx;
694*5113495bSYour Name 
695*5113495bSYour Name 	if (!mld_ctx || !wlan_vdev_mlme_is_mlo_ap(vdev))
696*5113495bSYour Name 		return;
697*5113495bSYour Name 
698*5113495bSYour Name 	idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
699*5113495bSYour Name 	if (idx == MLO_INVALID_LINK_IDX)
700*5113495bSYour Name 		return;
701*5113495bSYour Name 
702*5113495bSYour Name 	mlo_debug("Quiet set for PSOC:%d vdev:%d",
703*5113495bSYour Name 		  wlan_psoc_get_id(wlan_vdev_get_psoc(vdev)),
704*5113495bSYour Name 		  wlan_vdev_get_id(vdev));
705*5113495bSYour Name 
706*5113495bSYour Name 	wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_quiet_bmap,
707*5113495bSYour Name 				   idx, 1);
708*5113495bSYour Name }
709*5113495bSYour Name 
mlo_ap_vdev_quiet_clear(struct wlan_objmgr_vdev * vdev)710*5113495bSYour Name void mlo_ap_vdev_quiet_clear(struct wlan_objmgr_vdev *vdev)
711*5113495bSYour Name {
712*5113495bSYour Name 	struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx;
713*5113495bSYour Name 	uint8_t idx;
714*5113495bSYour Name 
715*5113495bSYour Name 	if (!mld_ctx || !wlan_vdev_mlme_is_mlo_ap(vdev))
716*5113495bSYour Name 		return;
717*5113495bSYour Name 
718*5113495bSYour Name 	idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
719*5113495bSYour Name 	if (idx == MLO_INVALID_LINK_IDX)
720*5113495bSYour Name 		return;
721*5113495bSYour Name 
722*5113495bSYour Name 	mlo_debug("Quiet clear for PSOC:%d vdev:%d",
723*5113495bSYour Name 		  wlan_psoc_get_id(wlan_vdev_get_psoc(vdev)),
724*5113495bSYour Name 		  wlan_vdev_get_id(vdev));
725*5113495bSYour Name 
726*5113495bSYour Name 	wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_quiet_bmap,
727*5113495bSYour Name 				   idx, 0);
728*5113495bSYour Name }
729*5113495bSYour Name 
mlo_ap_vdev_quiet_is_any_idx_set(struct wlan_objmgr_vdev * vdev)730*5113495bSYour Name bool mlo_ap_vdev_quiet_is_any_idx_set(struct wlan_objmgr_vdev *vdev)
731*5113495bSYour Name {
732*5113495bSYour Name 	struct wlan_mlo_dev_context *mld_ctx = vdev->mlo_dev_ctx;
733*5113495bSYour Name 
734*5113495bSYour Name 	if (!mld_ctx || !wlan_vdev_mlme_is_mlo_ap(vdev))
735*5113495bSYour Name 		return false;
736*5113495bSYour Name 
737*5113495bSYour Name 	return wlan_util_map_is_any_index_set(
738*5113495bSYour Name 			mld_ctx->ap_ctx->mlo_vdev_quiet_bmap,
739*5113495bSYour Name 			sizeof(mld_ctx->ap_ctx->mlo_vdev_quiet_bmap));
740*5113495bSYour Name }
741*5113495bSYour Name 
742*5113495bSYour Name QDF_STATUS
mlo_peer_create_get_frm_buf(struct wlan_mlo_peer_context * ml_peer,struct peer_create_notif_s * peer_create,qdf_nbuf_t frm_buf)743*5113495bSYour Name mlo_peer_create_get_frm_buf(
744*5113495bSYour Name 		struct wlan_mlo_peer_context *ml_peer,
745*5113495bSYour Name 		struct peer_create_notif_s *peer_create,
746*5113495bSYour Name 		qdf_nbuf_t frm_buf)
747*5113495bSYour Name {
748*5113495bSYour Name 	if (wlan_mlo_peer_is_nawds(ml_peer) ||
749*5113495bSYour Name 	    wlan_mlo_peer_is_mesh(ml_peer)) {
750*5113495bSYour Name 		peer_create->frm_buf = NULL;
751*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
752*5113495bSYour Name 	}
753*5113495bSYour Name 
754*5113495bSYour Name 	if (!frm_buf)
755*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
756*5113495bSYour Name 
757*5113495bSYour Name 	peer_create->frm_buf = qdf_nbuf_clone(frm_buf);
758*5113495bSYour Name 	if (!peer_create->frm_buf)
759*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
760*5113495bSYour Name 
761*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
762*5113495bSYour Name }
763*5113495bSYour Name 
764*5113495bSYour Name #ifdef UMAC_SUPPORT_MLNAWDS
mlo_peer_populate_nawds_params(struct wlan_mlo_peer_context * ml_peer,struct mlo_partner_info * ml_info)765*5113495bSYour Name void mlo_peer_populate_nawds_params(
766*5113495bSYour Name 		struct wlan_mlo_peer_context *ml_peer,
767*5113495bSYour Name 		struct mlo_partner_info *ml_info)
768*5113495bSYour Name {
769*5113495bSYour Name 	uint8_t i;
770*5113495bSYour Name 	uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0x00, 0x00, 0x00,
771*5113495bSYour Name 					       0x00, 0x00, 0x00};
772*5113495bSYour Name 	struct mlnawds_config nawds_config;
773*5113495bSYour Name 
774*5113495bSYour Name 	mlo_peer_lock_acquire(ml_peer);
775*5113495bSYour Name 	ml_peer->is_nawds_ml_peer = false;
776*5113495bSYour Name 	for (i = 0; i < ml_info->num_partner_links; i++) {
777*5113495bSYour Name 		nawds_config = ml_info->partner_link_info[i].nawds_config;
778*5113495bSYour Name 		/*
779*5113495bSYour Name 		 * if ml_info->partner_link_info[i].nawds_config has valid
780*5113495bSYour Name 		 * config(check for non-null mac or non-0 caps), then mark
781*5113495bSYour Name 		 * ml_peer's is_nawds_ml_peer true & copy the config
782*5113495bSYour Name 		 */
783*5113495bSYour Name 		if ((nawds_config.caps) ||
784*5113495bSYour Name 		    (qdf_mem_cmp(null_mac,
785*5113495bSYour Name 				 nawds_config.mac,
786*5113495bSYour Name 				 sizeof(null_mac)))) {
787*5113495bSYour Name 			ml_peer->is_nawds_ml_peer = true;
788*5113495bSYour Name 			ml_peer->nawds_config[i] = nawds_config;
789*5113495bSYour Name 		}
790*5113495bSYour Name 	}
791*5113495bSYour Name 	mlo_peer_lock_release(ml_peer);
792*5113495bSYour Name }
793*5113495bSYour Name #endif
794*5113495bSYour Name 
795*5113495bSYour Name #ifdef MESH_MODE_SUPPORT
mlo_peer_populate_mesh_params(struct wlan_mlo_peer_context * ml_peer,struct mlo_partner_info * ml_info)796*5113495bSYour Name void mlo_peer_populate_mesh_params(
797*5113495bSYour Name 		struct wlan_mlo_peer_context *ml_peer,
798*5113495bSYour Name 		struct mlo_partner_info *ml_info)
799*5113495bSYour Name {
800*5113495bSYour Name 	uint8_t i;
801*5113495bSYour Name 	uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0};
802*5113495bSYour Name 	struct mlnawds_config mesh_config;
803*5113495bSYour Name 
804*5113495bSYour Name 	mlo_peer_lock_acquire(ml_peer);
805*5113495bSYour Name 	ml_peer->is_mesh_ml_peer = false;
806*5113495bSYour Name 	for (i = 0; i < ml_info->num_partner_links; i++) {
807*5113495bSYour Name 		mesh_config = ml_info->partner_link_info[i].mesh_config;
808*5113495bSYour Name 		/*
809*5113495bSYour Name 		 * if ml_info->partner_link_info[i].mesh_config has valid
810*5113495bSYour Name 		 * config(check for non-null mac or non-0 caps), then mark
811*5113495bSYour Name 		 * ml_peer's is_mesh_ml_peer true & copy the config
812*5113495bSYour Name 		 */
813*5113495bSYour Name 		if ((mesh_config.caps) ||
814*5113495bSYour Name 		    (qdf_mem_cmp(null_mac,
815*5113495bSYour Name 				 mesh_config.mac,
816*5113495bSYour Name 				 sizeof(null_mac)))) {
817*5113495bSYour Name 			ml_peer->is_mesh_ml_peer = true;
818*5113495bSYour Name 			ml_peer->mesh_config[i] = mesh_config;
819*5113495bSYour Name 		}
820*5113495bSYour Name 	}
821*5113495bSYour Name 	mlo_peer_lock_release(ml_peer);
822*5113495bSYour Name }
823*5113495bSYour Name #endif
824