xref: /wlan-driver/qca-wifi-host-cmn/umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 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 "wlan_mlo_mgr_cmn.h"
22*5113495bSYour Name #include "wlan_mlo_mgr_main.h"
23*5113495bSYour Name #include "wlan_mlo_mgr_sta.h"
24*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
25*5113495bSYour Name #include "wlan_lmac_if_def.h"
26*5113495bSYour Name #endif
27*5113495bSYour Name #include "wlan_serialization_api.h"
28*5113495bSYour Name #include <target_if_mlo_mgr.h>
29*5113495bSYour Name #include <cdp_txrx_cmn.h>
30*5113495bSYour Name #include <wlan_cfg.h>
31*5113495bSYour Name #include "wlan_utility.h"
32*5113495bSYour Name 
mlo_get_link_information(struct qdf_mac_addr * mld_addr,struct mlo_link_info * info)33*5113495bSYour Name void mlo_get_link_information(struct qdf_mac_addr *mld_addr,
34*5113495bSYour Name 			      struct mlo_link_info *info)
35*5113495bSYour Name {
36*5113495bSYour Name /* Pass the partner link information*/
37*5113495bSYour Name }
38*5113495bSYour Name 
is_mlo_all_links_up(struct wlan_mlo_dev_context * mldev)39*5113495bSYour Name void is_mlo_all_links_up(struct wlan_mlo_dev_context *mldev)
40*5113495bSYour Name {
41*5113495bSYour Name /* Loop through all the vdev's part of the ML device*/
42*5113495bSYour Name /* STA: Loop through all the associated vdev status. */
43*5113495bSYour Name }
44*5113495bSYour Name 
mlo_get_vdev_by_link_id(struct wlan_objmgr_vdev * vdev,uint8_t link_id,wlan_objmgr_ref_dbgid id)45*5113495bSYour Name struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(struct wlan_objmgr_vdev *vdev,
46*5113495bSYour Name 						 uint8_t link_id,
47*5113495bSYour Name 						 wlan_objmgr_ref_dbgid id)
48*5113495bSYour Name {
49*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
50*5113495bSYour Name 	int i;
51*5113495bSYour Name 	struct wlan_objmgr_vdev *partner_vdev = NULL;
52*5113495bSYour Name 
53*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
54*5113495bSYour Name 		mlo_err("Invalid input");
55*5113495bSYour Name 		return partner_vdev;
56*5113495bSYour Name 	}
57*5113495bSYour Name 
58*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
59*5113495bSYour Name 
60*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
61*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
62*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i] &&
63*5113495bSYour Name 		    wlan_vdev_mlme_is_mlo_vdev(dev_ctx->wlan_vdev_list[i]) &&
64*5113495bSYour Name 		    dev_ctx->wlan_vdev_list[i]->vdev_mlme.mlo_link_id ==
65*5113495bSYour Name 		    link_id) {
66*5113495bSYour Name 			if (wlan_objmgr_vdev_try_get_ref(
67*5113495bSYour Name 						dev_ctx->wlan_vdev_list[i],
68*5113495bSYour Name 						id) == QDF_STATUS_SUCCESS)
69*5113495bSYour Name 				partner_vdev = dev_ctx->wlan_vdev_list[i];
70*5113495bSYour Name 
71*5113495bSYour Name 			break;
72*5113495bSYour Name 		}
73*5113495bSYour Name 	}
74*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
75*5113495bSYour Name 
76*5113495bSYour Name 	return partner_vdev;
77*5113495bSYour Name }
78*5113495bSYour Name 
mlo_release_vdev_ref(struct wlan_objmgr_vdev * vdev)79*5113495bSYour Name void mlo_release_vdev_ref(struct wlan_objmgr_vdev *vdev)
80*5113495bSYour Name {
81*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLO_MGR_ID);
82*5113495bSYour Name }
83*5113495bSYour Name 
mlo_reg_mlme_ext_cb(struct mlo_mgr_context * ctx,struct mlo_mlme_ext_ops * ops)84*5113495bSYour Name QDF_STATUS mlo_reg_mlme_ext_cb(struct mlo_mgr_context *ctx,
85*5113495bSYour Name 			       struct mlo_mlme_ext_ops *ops)
86*5113495bSYour Name {
87*5113495bSYour Name 	if (!ctx)
88*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
89*5113495bSYour Name 
90*5113495bSYour Name 	ctx->mlme_ops = ops;
91*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
92*5113495bSYour Name }
93*5113495bSYour Name 
mlo_unreg_mlme_ext_cb(struct mlo_mgr_context * ctx)94*5113495bSYour Name QDF_STATUS mlo_unreg_mlme_ext_cb(struct mlo_mgr_context *ctx)
95*5113495bSYour Name {
96*5113495bSYour Name 	if (!ctx)
97*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
98*5113495bSYour Name 
99*5113495bSYour Name 	ctx->mlme_ops = NULL;
100*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
101*5113495bSYour Name }
102*5113495bSYour Name 
103*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
wlan_mlo_mgr_register_osif_ext_ops(struct mlo_mgr_context * mlo_ctx,struct mlo_osif_ext_ops * ops)104*5113495bSYour Name QDF_STATUS wlan_mlo_mgr_register_osif_ext_ops(struct mlo_mgr_context *mlo_ctx,
105*5113495bSYour Name 					      struct mlo_osif_ext_ops *ops)
106*5113495bSYour Name {
107*5113495bSYour Name 	if (!ops || !mlo_ctx)
108*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
109*5113495bSYour Name 
110*5113495bSYour Name 	mlo_ctx->osif_ops = ops;
111*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
112*5113495bSYour Name }
113*5113495bSYour Name 
wlan_mlo_mgr_unregister_osif_ext_ops(struct mlo_mgr_context * mlo_ctx)114*5113495bSYour Name QDF_STATUS wlan_mlo_mgr_unregister_osif_ext_ops(struct mlo_mgr_context *mlo_ctx)
115*5113495bSYour Name {
116*5113495bSYour Name 	if (!mlo_ctx)
117*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
118*5113495bSYour Name 
119*5113495bSYour Name 	mlo_ctx->osif_ops = NULL;
120*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
121*5113495bSYour Name }
122*5113495bSYour Name #endif
123*5113495bSYour Name 
mlo_mlme_clone_sta_security(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * req)124*5113495bSYour Name QDF_STATUS mlo_mlme_clone_sta_security(struct wlan_objmgr_vdev *vdev,
125*5113495bSYour Name 				       struct wlan_cm_connect_req *req)
126*5113495bSYour Name {
127*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
128*5113495bSYour Name 	struct vdev_mlme_obj *vdev_mlme;
129*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
130*5113495bSYour Name 
131*5113495bSYour Name 	if (!req || !mlo_ctx || !mlo_ctx->mlme_ops ||
132*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_validate_conn_req)
133*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
134*5113495bSYour Name 
135*5113495bSYour Name 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
136*5113495bSYour Name 	if (!vdev_mlme)
137*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
138*5113495bSYour Name 
139*5113495bSYour Name 	if (mlo_ctx->mlme_ops->mlo_mlme_ext_clone_security_param) {
140*5113495bSYour Name 		status =
141*5113495bSYour Name 			mlo_ctx->mlme_ops->mlo_mlme_ext_clone_security_param(
142*5113495bSYour Name 				vdev_mlme, req);
143*5113495bSYour Name 	}
144*5113495bSYour Name 
145*5113495bSYour Name 	return status;
146*5113495bSYour Name }
147*5113495bSYour Name 
mlo_mlme_sta_op_class(struct wlan_objmgr_vdev * vdev,uint8_t * ml_ie)148*5113495bSYour Name QDF_STATUS mlo_mlme_sta_op_class(struct wlan_objmgr_vdev *vdev,
149*5113495bSYour Name 				 uint8_t *ml_ie)
150*5113495bSYour Name {
151*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
152*5113495bSYour Name 	struct vdev_mlme_obj *vdev_mlme;
153*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
154*5113495bSYour Name 
155*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
156*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_validate_conn_req)
157*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
158*5113495bSYour Name 
159*5113495bSYour Name 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
160*5113495bSYour Name 	if (!vdev_mlme)
161*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
162*5113495bSYour Name 
163*5113495bSYour Name 	if (mlo_ctx->mlme_ops->mlo_mlme_ext_sta_op_class)
164*5113495bSYour Name 		status =
165*5113495bSYour Name 			mlo_ctx->mlme_ops->mlo_mlme_ext_sta_op_class(
166*5113495bSYour Name 				vdev_mlme, ml_ie);
167*5113495bSYour Name 
168*5113495bSYour Name 	return status;
169*5113495bSYour Name }
170*5113495bSYour Name 
mlo_mlme_validate_conn_req(struct wlan_objmgr_vdev * vdev,void * ext_data)171*5113495bSYour Name QDF_STATUS mlo_mlme_validate_conn_req(struct wlan_objmgr_vdev *vdev,
172*5113495bSYour Name 				      void *ext_data)
173*5113495bSYour Name {
174*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
175*5113495bSYour Name 	struct vdev_mlme_obj *vdev_mlme;
176*5113495bSYour Name 	QDF_STATUS status;
177*5113495bSYour Name 
178*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
179*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_validate_conn_req)
180*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
181*5113495bSYour Name 
182*5113495bSYour Name 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
183*5113495bSYour Name 	if (!vdev_mlme)
184*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
185*5113495bSYour Name 
186*5113495bSYour Name 	status =
187*5113495bSYour Name 		mlo_ctx->mlme_ops->mlo_mlme_ext_validate_conn_req(vdev_mlme,
188*5113495bSYour Name 								  ext_data);
189*5113495bSYour Name 	return status;
190*5113495bSYour Name }
191*5113495bSYour Name 
mlo_mlme_create_link_vdev(struct wlan_objmgr_vdev * vdev,void * ext_data)192*5113495bSYour Name QDF_STATUS mlo_mlme_create_link_vdev(struct wlan_objmgr_vdev *vdev,
193*5113495bSYour Name 				     void *ext_data)
194*5113495bSYour Name {
195*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
196*5113495bSYour Name 	struct vdev_mlme_obj *vdev_mlme;
197*5113495bSYour Name 	QDF_STATUS status;
198*5113495bSYour Name 
199*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
200*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_create_link_vdev)
201*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
202*5113495bSYour Name 
203*5113495bSYour Name 	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
204*5113495bSYour Name 	if (!vdev_mlme)
205*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
206*5113495bSYour Name 
207*5113495bSYour Name 	status =
208*5113495bSYour Name 		mlo_ctx->mlme_ops->mlo_mlme_ext_create_link_vdev(vdev_mlme,
209*5113495bSYour Name 								 ext_data);
210*5113495bSYour Name 	return status;
211*5113495bSYour Name }
212*5113495bSYour Name 
mlo_mlme_peer_create(struct wlan_objmgr_vdev * vdev,struct wlan_mlo_peer_context * ml_peer,struct qdf_mac_addr * addr,qdf_nbuf_t frm_buf)213*5113495bSYour Name void mlo_mlme_peer_create(struct wlan_objmgr_vdev *vdev,
214*5113495bSYour Name 			  struct wlan_mlo_peer_context *ml_peer,
215*5113495bSYour Name 			  struct qdf_mac_addr *addr,
216*5113495bSYour Name 			  qdf_nbuf_t frm_buf)
217*5113495bSYour Name {
218*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
219*5113495bSYour Name 
220*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
221*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_create)
222*5113495bSYour Name 		return;
223*5113495bSYour Name 
224*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_create(vdev, ml_peer,
225*5113495bSYour Name 						    addr, frm_buf);
226*5113495bSYour Name }
227*5113495bSYour Name 
mlo_mlme_bridge_peer_create(struct wlan_objmgr_vdev * vdev,struct wlan_mlo_peer_context * ml_peer,struct qdf_mac_addr * addr,qdf_nbuf_t frm_buf)228*5113495bSYour Name void mlo_mlme_bridge_peer_create(struct wlan_objmgr_vdev *vdev,
229*5113495bSYour Name 				 struct wlan_mlo_peer_context *ml_peer,
230*5113495bSYour Name 				 struct qdf_mac_addr *addr,
231*5113495bSYour Name 				 qdf_nbuf_t frm_buf)
232*5113495bSYour Name {
233*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
234*5113495bSYour Name 
235*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
236*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_bridge_peer_create)
237*5113495bSYour Name 		return;
238*5113495bSYour Name 
239*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_bridge_peer_create(vdev, ml_peer,
240*5113495bSYour Name 							   addr, frm_buf);
241*5113495bSYour Name }
242*5113495bSYour Name 
mlo_mlme_peer_assoc(struct wlan_objmgr_peer * peer)243*5113495bSYour Name void mlo_mlme_peer_assoc(struct wlan_objmgr_peer *peer)
244*5113495bSYour Name {
245*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
246*5113495bSYour Name 
247*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
248*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_assoc)
249*5113495bSYour Name 		return;
250*5113495bSYour Name 
251*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_assoc(peer);
252*5113495bSYour Name }
253*5113495bSYour Name 
mlo_mlme_peer_assoc_fail(struct wlan_objmgr_peer * peer)254*5113495bSYour Name void mlo_mlme_peer_assoc_fail(struct wlan_objmgr_peer *peer)
255*5113495bSYour Name {
256*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
257*5113495bSYour Name 
258*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
259*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_assoc_fail)
260*5113495bSYour Name 		return;
261*5113495bSYour Name 
262*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_assoc_fail(peer);
263*5113495bSYour Name }
264*5113495bSYour Name 
mlo_mlme_peer_delete(struct wlan_objmgr_peer * peer)265*5113495bSYour Name void mlo_mlme_peer_delete(struct wlan_objmgr_peer *peer)
266*5113495bSYour Name {
267*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
268*5113495bSYour Name 
269*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
270*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_delete)
271*5113495bSYour Name 		return;
272*5113495bSYour Name 
273*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_delete(peer);
274*5113495bSYour Name }
275*5113495bSYour Name 
mlo_mlme_peer_assoc_resp(struct wlan_objmgr_peer * peer)276*5113495bSYour Name void mlo_mlme_peer_assoc_resp(struct wlan_objmgr_peer *peer)
277*5113495bSYour Name {
278*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
279*5113495bSYour Name 
280*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
281*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_assoc_resp)
282*5113495bSYour Name 		return;
283*5113495bSYour Name 
284*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_assoc_resp(peer);
285*5113495bSYour Name }
286*5113495bSYour Name 
mlo_mlme_get_link_assoc_req(struct wlan_objmgr_peer * peer,uint8_t link_ix)287*5113495bSYour Name qdf_nbuf_t mlo_mlme_get_link_assoc_req(struct wlan_objmgr_peer *peer,
288*5113495bSYour Name 				       uint8_t link_ix)
289*5113495bSYour Name {
290*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
291*5113495bSYour Name 
292*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
293*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_get_link_assoc_req)
294*5113495bSYour Name 		return NULL;
295*5113495bSYour Name 
296*5113495bSYour Name 	return mlo_ctx->mlme_ops->mlo_mlme_get_link_assoc_req(peer, link_ix);
297*5113495bSYour Name }
298*5113495bSYour Name 
mlo_mlme_peer_deauth(struct wlan_objmgr_peer * peer,uint8_t is_disassoc)299*5113495bSYour Name void mlo_mlme_peer_deauth(struct wlan_objmgr_peer *peer, uint8_t is_disassoc)
300*5113495bSYour Name {
301*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
302*5113495bSYour Name 
303*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
304*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_deauth)
305*5113495bSYour Name 		return;
306*5113495bSYour Name 
307*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_deauth(peer, is_disassoc);
308*5113495bSYour Name }
309*5113495bSYour Name 
310*5113495bSYour Name #ifdef UMAC_MLO_AUTH_DEFER
mlo_mlme_peer_process_auth(struct mlpeer_auth_params * auth_param)311*5113495bSYour Name void mlo_mlme_peer_process_auth(struct mlpeer_auth_params *auth_param)
312*5113495bSYour Name {
313*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
314*5113495bSYour Name 
315*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
316*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_process_auth)
317*5113495bSYour Name 		return;
318*5113495bSYour Name 
319*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_process_auth(auth_param);
320*5113495bSYour Name }
321*5113495bSYour Name #endif
322*5113495bSYour Name 
mlo_mlme_peer_reassoc(struct wlan_objmgr_vdev * vdev,struct wlan_mlo_peer_context * ml_peer,struct qdf_mac_addr * addr,qdf_nbuf_t frm_buf)323*5113495bSYour Name void mlo_mlme_peer_reassoc(struct wlan_objmgr_vdev *vdev,
324*5113495bSYour Name 			   struct wlan_mlo_peer_context *ml_peer,
325*5113495bSYour Name 			   struct qdf_mac_addr *addr,
326*5113495bSYour Name 			   qdf_nbuf_t frm_buf)
327*5113495bSYour Name {
328*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
329*5113495bSYour Name 
330*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
331*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_peer_reassoc)
332*5113495bSYour Name 		return;
333*5113495bSYour Name 
334*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_peer_reassoc(vdev, ml_peer, addr,
335*5113495bSYour Name 						     frm_buf);
336*5113495bSYour Name }
337*5113495bSYour Name 
mlo_get_link_vdev_ix(struct wlan_mlo_dev_context * ml_dev,struct wlan_objmgr_vdev * vdev)338*5113495bSYour Name uint8_t mlo_get_link_vdev_ix(struct wlan_mlo_dev_context *ml_dev,
339*5113495bSYour Name 			     struct wlan_objmgr_vdev *vdev)
340*5113495bSYour Name {
341*5113495bSYour Name 	uint8_t i;
342*5113495bSYour Name 
343*5113495bSYour Name 	mlo_dev_lock_acquire(ml_dev);
344*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
345*5113495bSYour Name 		if (vdev == ml_dev->wlan_vdev_list[i]) {
346*5113495bSYour Name 			mlo_dev_lock_release(ml_dev);
347*5113495bSYour Name 			return i;
348*5113495bSYour Name 		}
349*5113495bSYour Name 	}
350*5113495bSYour Name 	mlo_dev_lock_release(ml_dev);
351*5113495bSYour Name 
352*5113495bSYour Name 	return (uint8_t)-1;
353*5113495bSYour Name }
354*5113495bSYour Name 
355*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
wlan_mlo_get_max_num_links(uint8_t grp_id)356*5113495bSYour Name int8_t wlan_mlo_get_max_num_links(uint8_t grp_id)
357*5113495bSYour Name {
358*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx;
359*5113495bSYour Name 
360*5113495bSYour Name 	mlo_ctx = wlan_objmgr_get_mlo_ctx();
361*5113495bSYour Name 	if (!mlo_ctx)
362*5113495bSYour Name 		return WLAN_MLO_INVALID_NUM_LINKS;
363*5113495bSYour Name 
364*5113495bSYour Name 	if (grp_id >= mlo_ctx->total_grp) {
365*5113495bSYour Name 		mlo_err("Invalid grp id %d, total no of groups %d",
366*5113495bSYour Name 			grp_id, mlo_ctx->total_grp);
367*5113495bSYour Name 		return WLAN_MLO_INVALID_NUM_LINKS;
368*5113495bSYour Name 	}
369*5113495bSYour Name 
370*5113495bSYour Name 	return (mlo_ctx->setup_info[grp_id].tot_socs *
371*5113495bSYour Name 		WLAN_MAX_MLO_LINKS_PER_SOC);
372*5113495bSYour Name }
373*5113495bSYour Name 
wlan_mlo_get_num_active_links(uint8_t grp_id)374*5113495bSYour Name int8_t wlan_mlo_get_num_active_links(uint8_t grp_id)
375*5113495bSYour Name {
376*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx;
377*5113495bSYour Name 
378*5113495bSYour Name 	mlo_ctx = wlan_objmgr_get_mlo_ctx();
379*5113495bSYour Name 
380*5113495bSYour Name 	if (!mlo_ctx)
381*5113495bSYour Name 		return WLAN_MLO_INVALID_NUM_LINKS;
382*5113495bSYour Name 
383*5113495bSYour Name 	if (grp_id >= mlo_ctx->total_grp) {
384*5113495bSYour Name 		qdf_err("Invalid grp id %d, total no of groups %d",
385*5113495bSYour Name 			grp_id, mlo_ctx->total_grp);
386*5113495bSYour Name 		return WLAN_MLO_INVALID_NUM_LINKS;
387*5113495bSYour Name 	}
388*5113495bSYour Name 
389*5113495bSYour Name 	return mlo_ctx->setup_info[grp_id].tot_links;
390*5113495bSYour Name }
391*5113495bSYour Name 
wlan_mlo_get_valid_link_bitmap(uint8_t grp_id)392*5113495bSYour Name uint16_t wlan_mlo_get_valid_link_bitmap(uint8_t grp_id)
393*5113495bSYour Name {
394*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx;
395*5113495bSYour Name 
396*5113495bSYour Name 	mlo_ctx = wlan_objmgr_get_mlo_ctx();
397*5113495bSYour Name 	if (!mlo_ctx)
398*5113495bSYour Name 		return 0;
399*5113495bSYour Name 
400*5113495bSYour Name 	if (grp_id >= mlo_ctx->total_grp) {
401*5113495bSYour Name 		qdf_err("Invalid grp id %d, total no of groups %d",
402*5113495bSYour Name 			grp_id, mlo_ctx->total_grp);
403*5113495bSYour Name 		return 0;
404*5113495bSYour Name 	}
405*5113495bSYour Name 
406*5113495bSYour Name 	return mlo_ctx->setup_info[grp_id].valid_link_bitmap;
407*5113495bSYour Name }
408*5113495bSYour Name 
wlan_mlo_get_psoc_mlo_chip_id(struct wlan_objmgr_psoc * psoc)409*5113495bSYour Name uint8_t wlan_mlo_get_psoc_mlo_chip_id(struct wlan_objmgr_psoc *psoc)
410*5113495bSYour Name {
411*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
412*5113495bSYour Name 	uint8_t mlo_chip_id = WLAN_MLO_CHIP_ID_INVALID;
413*5113495bSYour Name 
414*5113495bSYour Name 	if (!psoc) {
415*5113495bSYour Name 		qdf_err("PSOC is NULL");
416*5113495bSYour Name 		return mlo_chip_id;
417*5113495bSYour Name 	}
418*5113495bSYour Name 
419*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
420*5113495bSYour Name 	if (tx_ops && tx_ops->mops.get_psoc_mlo_chip_id)
421*5113495bSYour Name 		mlo_chip_id = tx_ops->mops.get_psoc_mlo_chip_id(psoc);
422*5113495bSYour Name 
423*5113495bSYour Name 	return mlo_chip_id;
424*5113495bSYour Name }
425*5113495bSYour Name 
426*5113495bSYour Name qdf_export_symbol(wlan_mlo_get_psoc_mlo_chip_id);
427*5113495bSYour Name 
wlan_mlo_get_psoc_group_id(struct wlan_objmgr_psoc * psoc)428*5113495bSYour Name uint8_t wlan_mlo_get_psoc_group_id(struct wlan_objmgr_psoc *psoc)
429*5113495bSYour Name {
430*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
431*5113495bSYour Name 	uint8_t ml_grp_id = WLAN_MLO_GROUP_INVALID;
432*5113495bSYour Name 
433*5113495bSYour Name 	if (!psoc) {
434*5113495bSYour Name 		qdf_err("PSOC is NULL");
435*5113495bSYour Name 		return -EINVAL;
436*5113495bSYour Name 	}
437*5113495bSYour Name 
438*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
439*5113495bSYour Name 	if (tx_ops && tx_ops->mops.get_psoc_mlo_group_id)
440*5113495bSYour Name 		ml_grp_id = tx_ops->mops.get_psoc_mlo_group_id(psoc);
441*5113495bSYour Name 
442*5113495bSYour Name 	return ml_grp_id;
443*5113495bSYour Name }
444*5113495bSYour Name 
445*5113495bSYour Name qdf_export_symbol(wlan_mlo_get_psoc_group_id);
446*5113495bSYour Name 
wlan_mlo_get_psoc_capable(struct wlan_objmgr_psoc * psoc)447*5113495bSYour Name bool wlan_mlo_get_psoc_capable(struct wlan_objmgr_psoc *psoc)
448*5113495bSYour Name {
449*5113495bSYour Name 	struct target_psoc_info *tgt_hdl;
450*5113495bSYour Name 
451*5113495bSYour Name 	if (!psoc) {
452*5113495bSYour Name 		qdf_err("PSOC is NULL");
453*5113495bSYour Name 		return false;
454*5113495bSYour Name 	}
455*5113495bSYour Name 
456*5113495bSYour Name 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
457*5113495bSYour Name 	if (!tgt_hdl) {
458*5113495bSYour Name 		target_if_err("target_psoc_info is null");
459*5113495bSYour Name 		return false;
460*5113495bSYour Name 	}
461*5113495bSYour Name 
462*5113495bSYour Name 	if ((tgt_hdl->tif_ops) &&
463*5113495bSYour Name 	    (tgt_hdl->tif_ops->mlo_capable))
464*5113495bSYour Name 		return tgt_hdl->tif_ops->mlo_capable(psoc);
465*5113495bSYour Name 
466*5113495bSYour Name 	return false;
467*5113495bSYour Name }
468*5113495bSYour Name 
wlan_mlo_get_pdev_hw_link_id(struct wlan_objmgr_pdev * pdev)469*5113495bSYour Name uint16_t wlan_mlo_get_pdev_hw_link_id(struct wlan_objmgr_pdev *pdev)
470*5113495bSYour Name {
471*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
472*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
473*5113495bSYour Name 	uint16_t hw_link_id = INVALID_HW_LINK_ID;
474*5113495bSYour Name 
475*5113495bSYour Name 	psoc = wlan_pdev_get_psoc(pdev);
476*5113495bSYour Name 	if (psoc) {
477*5113495bSYour Name 		tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
478*5113495bSYour Name 		if (tx_ops && tx_ops->mops.get_hw_link_id)
479*5113495bSYour Name 			hw_link_id = tx_ops->mops.get_hw_link_id(pdev);
480*5113495bSYour Name 	}
481*5113495bSYour Name 
482*5113495bSYour Name 	return hw_link_id;
483*5113495bSYour Name }
484*5113495bSYour Name 
485*5113495bSYour Name qdf_export_symbol(wlan_mlo_get_pdev_hw_link_id);
486*5113495bSYour Name 
wlan_pdev_hw_link_iterator(struct wlan_objmgr_psoc * psoc,void * obj,void * arg)487*5113495bSYour Name static void wlan_pdev_hw_link_iterator(struct wlan_objmgr_psoc *psoc,
488*5113495bSYour Name 				       void *obj, void *arg)
489*5113495bSYour Name {
490*5113495bSYour Name 	struct hw_link_id_iterator *itr = (struct hw_link_id_iterator *)arg;
491*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
492*5113495bSYour Name 	uint16_t hw_link_id;
493*5113495bSYour Name 	uint8_t ml_grp_id;
494*5113495bSYour Name 
495*5113495bSYour Name 	if (itr->pdev)
496*5113495bSYour Name 		return;
497*5113495bSYour Name 
498*5113495bSYour Name 	ml_grp_id = wlan_mlo_get_psoc_group_id(psoc);
499*5113495bSYour Name 	if (ml_grp_id > WLAN_MAX_MLO_GROUPS)
500*5113495bSYour Name 		return;
501*5113495bSYour Name 
502*5113495bSYour Name 	if (ml_grp_id != itr->mlo_grp_id)
503*5113495bSYour Name 		return;
504*5113495bSYour Name 
505*5113495bSYour Name 	hw_link_id = wlan_mlo_get_pdev_hw_link_id(pdev);
506*5113495bSYour Name 	if (hw_link_id == itr->hw_link_id) {
507*5113495bSYour Name 		if (wlan_objmgr_pdev_try_get_ref(pdev, itr->dbgid) ==
508*5113495bSYour Name 							QDF_STATUS_SUCCESS)
509*5113495bSYour Name 			itr->pdev = pdev;
510*5113495bSYour Name 	}
511*5113495bSYour Name }
512*5113495bSYour Name 
wlan_mlo_find_hw_link_id(struct wlan_objmgr_psoc * psoc,void * arg,uint8_t index)513*5113495bSYour Name static void wlan_mlo_find_hw_link_id(struct wlan_objmgr_psoc *psoc,
514*5113495bSYour Name 				     void *arg,
515*5113495bSYour Name 				     uint8_t index)
516*5113495bSYour Name {
517*5113495bSYour Name 	struct hw_link_id_iterator *itr = (struct hw_link_id_iterator *)arg;
518*5113495bSYour Name 
519*5113495bSYour Name 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
520*5113495bSYour Name 				     wlan_pdev_hw_link_iterator,
521*5113495bSYour Name 				     arg, false, itr->dbgid);
522*5113495bSYour Name }
523*5113495bSYour Name 
524*5113495bSYour Name struct wlan_objmgr_pdev *
wlan_mlo_get_pdev_by_hw_link_id(uint16_t hw_link_id,uint8_t ml_grp_id,wlan_objmgr_ref_dbgid refdbgid)525*5113495bSYour Name wlan_mlo_get_pdev_by_hw_link_id(uint16_t hw_link_id, uint8_t ml_grp_id,
526*5113495bSYour Name 				wlan_objmgr_ref_dbgid refdbgid)
527*5113495bSYour Name {
528*5113495bSYour Name 	struct hw_link_id_iterator itr;
529*5113495bSYour Name 
530*5113495bSYour Name 	itr.hw_link_id = hw_link_id;
531*5113495bSYour Name 	itr.pdev = NULL;
532*5113495bSYour Name 	itr.mlo_grp_id = ml_grp_id;
533*5113495bSYour Name 	itr.dbgid = refdbgid;
534*5113495bSYour Name 
535*5113495bSYour Name 	wlan_objmgr_iterate_psoc_list(wlan_mlo_find_hw_link_id,
536*5113495bSYour Name 				      &itr, refdbgid);
537*5113495bSYour Name 
538*5113495bSYour Name 	return itr.pdev;
539*5113495bSYour Name }
540*5113495bSYour Name 
541*5113495bSYour Name qdf_export_symbol(wlan_mlo_get_pdev_by_hw_link_id);
542*5113495bSYour Name #endif /*WLAN_MLO_MULTI_CHIP*/
543*5113495bSYour Name 
mlo_get_ml_vdev_list(struct wlan_objmgr_vdev * vdev,uint16_t * vdev_count,struct wlan_objmgr_vdev ** wlan_vdev_list)544*5113495bSYour Name void mlo_get_ml_vdev_list(struct wlan_objmgr_vdev *vdev,
545*5113495bSYour Name 			  uint16_t *vdev_count,
546*5113495bSYour Name 			  struct wlan_objmgr_vdev **wlan_vdev_list)
547*5113495bSYour Name {
548*5113495bSYour Name 	struct wlan_mlo_dev_context *dev_ctx;
549*5113495bSYour Name 	int i;
550*5113495bSYour Name 	QDF_STATUS status;
551*5113495bSYour Name 
552*5113495bSYour Name 	*vdev_count = 0;
553*5113495bSYour Name 
554*5113495bSYour Name 	if (!vdev || !vdev->mlo_dev_ctx) {
555*5113495bSYour Name 		mlo_err("Invalid input");
556*5113495bSYour Name 		return;
557*5113495bSYour Name 	}
558*5113495bSYour Name 
559*5113495bSYour Name 	dev_ctx = vdev->mlo_dev_ctx;
560*5113495bSYour Name 
561*5113495bSYour Name 	mlo_dev_lock_acquire(dev_ctx);
562*5113495bSYour Name 	*vdev_count = 0;
563*5113495bSYour Name 	for (i = 0; i < QDF_ARRAY_SIZE(dev_ctx->wlan_vdev_list); i++) {
564*5113495bSYour Name 		if (dev_ctx->wlan_vdev_list[i] &&
565*5113495bSYour Name 		    wlan_vdev_mlme_is_mlo_vdev(dev_ctx->wlan_vdev_list[i])) {
566*5113495bSYour Name 			status = wlan_objmgr_vdev_try_get_ref(
567*5113495bSYour Name 						dev_ctx->wlan_vdev_list[i],
568*5113495bSYour Name 						WLAN_MLO_MGR_ID);
569*5113495bSYour Name 			if (QDF_IS_STATUS_ERROR(status))
570*5113495bSYour Name 				break;
571*5113495bSYour Name 			wlan_vdev_list[*vdev_count] =
572*5113495bSYour Name 				dev_ctx->wlan_vdev_list[i];
573*5113495bSYour Name 			(*vdev_count) += 1;
574*5113495bSYour Name 		}
575*5113495bSYour Name 	}
576*5113495bSYour Name 	mlo_dev_lock_release(dev_ctx);
577*5113495bSYour Name }
578*5113495bSYour Name 
579*5113495bSYour Name /**
580*5113495bSYour Name  * mlo_link_set_active() - send MLO link set active command
581*5113495bSYour Name  * @psoc: PSOC object
582*5113495bSYour Name  * @req: MLO link set active request
583*5113495bSYour Name  *
584*5113495bSYour Name  * Return: QDF_STATUS
585*5113495bSYour Name  */
586*5113495bSYour Name static QDF_STATUS
mlo_link_set_active(struct wlan_objmgr_psoc * psoc,struct mlo_link_set_active_req * req)587*5113495bSYour Name mlo_link_set_active(struct wlan_objmgr_psoc *psoc,
588*5113495bSYour Name 		    struct mlo_link_set_active_req *req)
589*5113495bSYour Name {
590*5113495bSYour Name 	struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops;
591*5113495bSYour Name 	struct mlo_link_set_active_param *param = &req->param;
592*5113495bSYour Name 	QDF_STATUS status;
593*5113495bSYour Name 	struct mlo_link_set_active_resp rsp_evt;
594*5113495bSYour Name 
595*5113495bSYour Name 	if (!psoc) {
596*5113495bSYour Name 		mlo_err("psoc is null");
597*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
598*5113495bSYour Name 	}
599*5113495bSYour Name 
600*5113495bSYour Name 	mlo_tx_ops = target_if_mlo_get_tx_ops(psoc);
601*5113495bSYour Name 	if (!mlo_tx_ops) {
602*5113495bSYour Name 		mlo_err("tx_ops is null!");
603*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
604*5113495bSYour Name 	}
605*5113495bSYour Name 
606*5113495bSYour Name 	if (!mlo_tx_ops->link_set_active) {
607*5113495bSYour Name 		mlo_err("link_set_active function is null!");
608*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
609*5113495bSYour Name 	}
610*5113495bSYour Name 
611*5113495bSYour Name 	if (req->ctx.validate_set_mlo_link_cb) {
612*5113495bSYour Name 		status = req->ctx.validate_set_mlo_link_cb(psoc, param);
613*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
614*5113495bSYour Name 			qdf_mem_zero(&rsp_evt, sizeof(rsp_evt));
615*5113495bSYour Name 			rsp_evt.status = status;
616*5113495bSYour Name 			if (req->ctx.set_mlo_link_cb)
617*5113495bSYour Name 				req->ctx.set_mlo_link_cb(req->ctx.vdev,
618*5113495bSYour Name 							 req->ctx.cb_arg,
619*5113495bSYour Name 							 &rsp_evt);
620*5113495bSYour Name 			return status;
621*5113495bSYour Name 		}
622*5113495bSYour Name 	}
623*5113495bSYour Name 
624*5113495bSYour Name 	return mlo_tx_ops->link_set_active(psoc, param);
625*5113495bSYour Name }
626*5113495bSYour Name 
627*5113495bSYour Name /**
628*5113495bSYour Name  * mlo_release_ser_link_set_active_cmd() - releases serialization command for
629*5113495bSYour Name  *  forcing MLO link active/inactive
630*5113495bSYour Name  * @vdev: Object manager vdev
631*5113495bSYour Name  *
632*5113495bSYour Name  * Return: None
633*5113495bSYour Name  */
634*5113495bSYour Name static void
mlo_release_ser_link_set_active_cmd(struct wlan_objmgr_vdev * vdev)635*5113495bSYour Name mlo_release_ser_link_set_active_cmd(struct wlan_objmgr_vdev *vdev)
636*5113495bSYour Name {
637*5113495bSYour Name 	struct wlan_serialization_queued_cmd_info cmd = {0};
638*5113495bSYour Name 
639*5113495bSYour Name 	cmd.cmd_type = WLAN_SER_CMD_SET_MLO_LINK;
640*5113495bSYour Name 	cmd.requestor = WLAN_UMAC_COMP_MLO_MGR;
641*5113495bSYour Name 	cmd.cmd_id = 0;
642*5113495bSYour Name 	cmd.vdev = vdev;
643*5113495bSYour Name 
644*5113495bSYour Name 	mlo_debug("release serialization command");
645*5113495bSYour Name 	wlan_serialization_remove_cmd(&cmd);
646*5113495bSYour Name }
647*5113495bSYour Name 
648*5113495bSYour Name /**
649*5113495bSYour Name  * mlo_link_set_active_resp_vdev_handler() - vdev handler for mlo link set
650*5113495bSYour Name  * active response event.
651*5113495bSYour Name  * @psoc: psoc object
652*5113495bSYour Name  * @obj: vdev object
653*5113495bSYour Name  * @arg: mlo link set active response
654*5113495bSYour Name  *
655*5113495bSYour Name  * Return: None
656*5113495bSYour Name  */
657*5113495bSYour Name static void
mlo_link_set_active_resp_vdev_handler(struct wlan_objmgr_psoc * psoc,void * obj,void * arg)658*5113495bSYour Name mlo_link_set_active_resp_vdev_handler(struct wlan_objmgr_psoc *psoc,
659*5113495bSYour Name 				      void *obj, void *arg)
660*5113495bSYour Name {
661*5113495bSYour Name 	struct mlo_link_set_active_req *req;
662*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = obj;
663*5113495bSYour Name 	struct mlo_link_set_active_resp *event = arg;
664*5113495bSYour Name 
665*5113495bSYour Name 	if (event->evt_handled)
666*5113495bSYour Name 		return;
667*5113495bSYour Name 	req = wlan_serialization_get_active_cmd(wlan_vdev_get_psoc(vdev),
668*5113495bSYour Name 						wlan_vdev_get_id(vdev),
669*5113495bSYour Name 						WLAN_SER_CMD_SET_MLO_LINK);
670*5113495bSYour Name 	if (!req)
671*5113495bSYour Name 		return;
672*5113495bSYour Name 
673*5113495bSYour Name 	if (req->ctx.set_mlo_link_cb)
674*5113495bSYour Name 		req->ctx.set_mlo_link_cb(vdev, req->ctx.cb_arg, event);
675*5113495bSYour Name 
676*5113495bSYour Name 	mlo_release_ser_link_set_active_cmd(vdev);
677*5113495bSYour Name 	event->evt_handled = true;
678*5113495bSYour Name }
679*5113495bSYour Name 
680*5113495bSYour Name QDF_STATUS
mlo_process_link_set_active_resp(struct wlan_objmgr_psoc * psoc,struct mlo_link_set_active_resp * event)681*5113495bSYour Name mlo_process_link_set_active_resp(struct wlan_objmgr_psoc *psoc,
682*5113495bSYour Name 				 struct mlo_link_set_active_resp *event)
683*5113495bSYour Name {
684*5113495bSYour Name 	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
685*5113495bSYour Name 				     mlo_link_set_active_resp_vdev_handler,
686*5113495bSYour Name 				     event, true, WLAN_MLO_MGR_ID);
687*5113495bSYour Name 	if (!event->evt_handled)
688*5113495bSYour Name 		mlo_debug("link set resp evt not handled");
689*5113495bSYour Name 
690*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
691*5113495bSYour Name }
692*5113495bSYour Name 
693*5113495bSYour Name /**
694*5113495bSYour Name  * mlo_ser_set_link_cb() - Serialization callback function
695*5113495bSYour Name  * @cmd: Serialization command info
696*5113495bSYour Name  * @reason: Serialization reason for callback execution
697*5113495bSYour Name  *
698*5113495bSYour Name  * Return: Status of callback execution
699*5113495bSYour Name  */
700*5113495bSYour Name static QDF_STATUS
mlo_ser_set_link_cb(struct wlan_serialization_command * cmd,enum wlan_serialization_cb_reason reason)701*5113495bSYour Name mlo_ser_set_link_cb(struct wlan_serialization_command *cmd,
702*5113495bSYour Name 		    enum wlan_serialization_cb_reason reason)
703*5113495bSYour Name {
704*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
705*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
706*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
707*5113495bSYour Name 	struct mlo_link_set_active_req *req;
708*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx;
709*5113495bSYour Name 
710*5113495bSYour Name 	if (!cmd || !cmd->vdev)
711*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
712*5113495bSYour Name 
713*5113495bSYour Name 	mlo_ctx = wlan_objmgr_get_mlo_ctx();
714*5113495bSYour Name 	if (!mlo_ctx)
715*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
716*5113495bSYour Name 
717*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(cmd->vdev);
718*5113495bSYour Name 	if (!psoc) {
719*5113495bSYour Name 		mlo_err("psoc is NULL, reason: %d", reason);
720*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
721*5113495bSYour Name 	}
722*5113495bSYour Name 
723*5113495bSYour Name 	req = cmd->umac_cmd;
724*5113495bSYour Name 	if (!req)
725*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
726*5113495bSYour Name 
727*5113495bSYour Name 	vdev = cmd->vdev;
728*5113495bSYour Name 	switch (reason) {
729*5113495bSYour Name 	case WLAN_SER_CB_ACTIVATE_CMD:
730*5113495bSYour Name 		status = mlo_link_set_active(psoc, req);
731*5113495bSYour Name 		break;
732*5113495bSYour Name 	case WLAN_SER_CB_CANCEL_CMD:
733*5113495bSYour Name 	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
734*5113495bSYour Name 		mlo_err("vdev %d command not execute: %d",
735*5113495bSYour Name 			wlan_vdev_get_id(vdev), reason);
736*5113495bSYour Name 		if (req->ctx.set_mlo_link_cb)
737*5113495bSYour Name 			req->ctx.set_mlo_link_cb(vdev, req->ctx.cb_arg, NULL);
738*5113495bSYour Name 		break;
739*5113495bSYour Name 	case WLAN_SER_CB_RELEASE_MEM_CMD:
740*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLO_MGR_ID);
741*5113495bSYour Name 		qdf_mem_free(req);
742*5113495bSYour Name 		break;
743*5113495bSYour Name 	default:
744*5113495bSYour Name 		QDF_ASSERT(0);
745*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
746*5113495bSYour Name 		break;
747*5113495bSYour Name 	}
748*5113495bSYour Name 
749*5113495bSYour Name 	return status;
750*5113495bSYour Name }
751*5113495bSYour Name 
752*5113495bSYour Name #define MLO_SER_CMD_TIMEOUT_MS 5000
mlo_ser_set_link_req(struct mlo_link_set_active_req * req)753*5113495bSYour Name QDF_STATUS mlo_ser_set_link_req(struct mlo_link_set_active_req *req)
754*5113495bSYour Name {
755*5113495bSYour Name 	struct wlan_serialization_command cmd = {0, };
756*5113495bSYour Name 	enum wlan_serialization_status ser_cmd_status;
757*5113495bSYour Name 	QDF_STATUS status;
758*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
759*5113495bSYour Name 
760*5113495bSYour Name 	if (!req)
761*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
762*5113495bSYour Name 
763*5113495bSYour Name 	vdev = req->ctx.vdev;
764*5113495bSYour Name 	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_MLO_MGR_ID);
765*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
766*5113495bSYour Name 		mlo_err("vdev %d unable to get reference",
767*5113495bSYour Name 			wlan_vdev_get_id(vdev));
768*5113495bSYour Name 		return status;
769*5113495bSYour Name 	}
770*5113495bSYour Name 
771*5113495bSYour Name 	cmd.cmd_type = WLAN_SER_CMD_SET_MLO_LINK;
772*5113495bSYour Name 	cmd.cmd_id = 0;
773*5113495bSYour Name 	cmd.cmd_cb = mlo_ser_set_link_cb;
774*5113495bSYour Name 	cmd.source = WLAN_UMAC_COMP_MLO_MGR;
775*5113495bSYour Name 	cmd.is_high_priority = false;
776*5113495bSYour Name 	cmd.cmd_timeout_duration = MLO_SER_CMD_TIMEOUT_MS;
777*5113495bSYour Name 	cmd.vdev = vdev;
778*5113495bSYour Name 	cmd.is_blocking = true;
779*5113495bSYour Name 	cmd.umac_cmd = (void *)req;
780*5113495bSYour Name 
781*5113495bSYour Name 	ser_cmd_status = wlan_serialization_request(&cmd);
782*5113495bSYour Name 	switch (ser_cmd_status) {
783*5113495bSYour Name 	case WLAN_SER_CMD_PENDING:
784*5113495bSYour Name 		/* command moved to pending list.Do nothing */
785*5113495bSYour Name 		break;
786*5113495bSYour Name 	case WLAN_SER_CMD_ACTIVE:
787*5113495bSYour Name 		/* command moved to active list. Do nothing */
788*5113495bSYour Name 		break;
789*5113495bSYour Name 	default:
790*5113495bSYour Name 		mlo_err("vdev %d ser cmd status %d",
791*5113495bSYour Name 			wlan_vdev_get_id(vdev), ser_cmd_status);
792*5113495bSYour Name 		status = QDF_STATUS_E_FAILURE;
793*5113495bSYour Name 	}
794*5113495bSYour Name 
795*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status))
796*5113495bSYour Name 		return status;
797*5113495bSYour Name 
798*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLO_MGR_ID);
799*5113495bSYour Name 
800*5113495bSYour Name 	return status;
801*5113495bSYour Name }
802*5113495bSYour Name 
mlo_mlme_handle_sta_csa_param(struct wlan_objmgr_vdev * vdev,struct csa_offload_params * csa_param)803*5113495bSYour Name void mlo_mlme_handle_sta_csa_param(struct wlan_objmgr_vdev *vdev,
804*5113495bSYour Name 				   struct csa_offload_params *csa_param)
805*5113495bSYour Name {
806*5113495bSYour Name 	struct mlo_mgr_context *mlo_ctx = wlan_objmgr_get_mlo_ctx();
807*5113495bSYour Name 
808*5113495bSYour Name 	if (!mlo_ctx || !mlo_ctx->mlme_ops ||
809*5113495bSYour Name 	    !mlo_ctx->mlme_ops->mlo_mlme_ext_handle_sta_csa_param)
810*5113495bSYour Name 		return;
811*5113495bSYour Name 
812*5113495bSYour Name 	mlo_ctx->mlme_ops->mlo_mlme_ext_handle_sta_csa_param(vdev, csa_param);
813*5113495bSYour Name }
814*5113495bSYour Name 
815*5113495bSYour Name QDF_STATUS
mlo_get_mlstats_vdev_params(struct wlan_objmgr_psoc * psoc,struct mlo_stats_vdev_params * info,uint8_t vdev_id)816*5113495bSYour Name mlo_get_mlstats_vdev_params(struct wlan_objmgr_psoc *psoc,
817*5113495bSYour Name 			    struct mlo_stats_vdev_params *info,
818*5113495bSYour Name 			    uint8_t vdev_id)
819*5113495bSYour Name {
820*5113495bSYour Name 	struct wlan_objmgr_vdev *ml_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
821*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
822*5113495bSYour Name 	int i;
823*5113495bSYour Name 	uint16_t ml_vdev_cnt = 0;
824*5113495bSYour Name 
825*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
826*5113495bSYour Name 						    WLAN_MLO_MGR_ID);
827*5113495bSYour Name 	if (!vdev) {
828*5113495bSYour Name 		mlo_err("vdev object is NULL for vdev %d", vdev_id);
829*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
830*5113495bSYour Name 	}
831*5113495bSYour Name 
832*5113495bSYour Name 	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, ml_vdev_list);
833*5113495bSYour Name 	for (i = 0; i < ml_vdev_cnt; i++) {
834*5113495bSYour Name 		info->ml_vdev_id[i] = wlan_vdev_get_id(ml_vdev_list[i]);
835*5113495bSYour Name 		mlo_release_vdev_ref(ml_vdev_list[i]);
836*5113495bSYour Name 	}
837*5113495bSYour Name 	info->ml_vdev_count = ml_vdev_cnt;
838*5113495bSYour Name 	mlo_release_vdev_ref(vdev);
839*5113495bSYour Name 
840*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
841*5113495bSYour Name }
842*5113495bSYour Name 
ml_extract_link_state(struct wlan_objmgr_psoc * psoc,struct ml_link_state_info_event * event)843*5113495bSYour Name static void ml_extract_link_state(struct wlan_objmgr_psoc *psoc,
844*5113495bSYour Name 				  struct ml_link_state_info_event *event)
845*5113495bSYour Name {
846*5113495bSYour Name 	QDF_STATUS status;
847*5113495bSYour Name 	get_ml_link_state_cb resp_cb = NULL;
848*5113495bSYour Name 	void *context = NULL;
849*5113495bSYour Name 	uint8_t vdev_id;
850*5113495bSYour Name 
851*5113495bSYour Name 	vdev_id = event->vdev_id;
852*5113495bSYour Name 
853*5113495bSYour Name 	status = mlo_get_link_state_context(psoc,
854*5113495bSYour Name 					    &resp_cb, &context, vdev_id);
855*5113495bSYour Name 
856*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
857*5113495bSYour Name 		return;
858*5113495bSYour Name 
859*5113495bSYour Name 	if (resp_cb)
860*5113495bSYour Name 		resp_cb(event, context);
861*5113495bSYour Name }
862*5113495bSYour Name 
863*5113495bSYour Name QDF_STATUS
wlan_handle_ml_link_state_info_event(struct wlan_objmgr_psoc * psoc,struct ml_link_state_info_event * event)864*5113495bSYour Name wlan_handle_ml_link_state_info_event(struct wlan_objmgr_psoc *psoc,
865*5113495bSYour Name 				     struct ml_link_state_info_event *event)
866*5113495bSYour Name {
867*5113495bSYour Name 	if (!event)
868*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
869*5113495bSYour Name 
870*5113495bSYour Name 	ml_extract_link_state(psoc, event);
871*5113495bSYour Name 
872*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
873*5113495bSYour Name }
874*5113495bSYour Name 
ml_get_link_state_req_cb(struct scheduler_msg * msg)875*5113495bSYour Name static QDF_STATUS ml_get_link_state_req_cb(struct scheduler_msg *msg)
876*5113495bSYour Name {
877*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = msg->bodyptr;
878*5113495bSYour Name 	struct wlan_mlo_dev_context *mlo_dev_ctx = NULL;
879*5113495bSYour Name 	struct mlo_link_state_cmd_params cmd = {0};
880*5113495bSYour Name 	struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops;
881*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
882*5113495bSYour Name 	int status = 0;
883*5113495bSYour Name 
884*5113495bSYour Name 	if (!vdev) {
885*5113495bSYour Name 		mlo_err("null input vdev");
886*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
887*5113495bSYour Name 	}
888*5113495bSYour Name 
889*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
890*5113495bSYour Name 
891*5113495bSYour Name 	if (!psoc) {
892*5113495bSYour Name 		mlo_err("null psoc");
893*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
894*5113495bSYour Name 	}
895*5113495bSYour Name 
896*5113495bSYour Name 	mlo_tx_ops = &psoc->soc_cb.tx_ops->mlo_ops;
897*5113495bSYour Name 
898*5113495bSYour Name 	if (!mlo_tx_ops) {
899*5113495bSYour Name 		mlo_err("tx_ops is null!");
900*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
901*5113495bSYour Name 	}
902*5113495bSYour Name 
903*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
904*5113495bSYour Name 		mlo_err("vdev is not MLO vdev");
905*5113495bSYour Name 		return status;
906*5113495bSYour Name 	}
907*5113495bSYour Name 
908*5113495bSYour Name 	mlo_dev_ctx = vdev->mlo_dev_ctx;
909*5113495bSYour Name 	cmd.vdev_id = vdev->vdev_objmgr.vdev_id;
910*5113495bSYour Name 	qdf_mem_copy(&cmd.mld_mac[0], &mlo_dev_ctx->mld_addr,
911*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
912*5113495bSYour Name 
913*5113495bSYour Name 	if (!mlo_tx_ops->request_link_state_info_cmd) {
914*5113495bSYour Name 		mlo_err("handler is not registered");
915*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
916*5113495bSYour Name 	}
917*5113495bSYour Name 
918*5113495bSYour Name 	status = mlo_tx_ops->request_link_state_info_cmd(psoc, &cmd);
919*5113495bSYour Name 
920*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
921*5113495bSYour Name 		mlo_err("failed to send ml link info command to FW");
922*5113495bSYour Name 
923*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
924*5113495bSYour Name }
925*5113495bSYour Name 
926*5113495bSYour Name QDF_STATUS
mlo_get_link_state_register_resp_cb(struct wlan_objmgr_vdev * vdev,struct ml_link_state_cmd_info * req)927*5113495bSYour Name mlo_get_link_state_register_resp_cb(struct wlan_objmgr_vdev *vdev,
928*5113495bSYour Name 				    struct ml_link_state_cmd_info *req)
929*5113495bSYour Name {
930*5113495bSYour Name 	struct wlan_mlo_dev_context *mlo_ctx;
931*5113495bSYour Name 	struct wlan_mlo_sta *sta_ctx = NULL;
932*5113495bSYour Name 
933*5113495bSYour Name 	if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev))
934*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
935*5113495bSYour Name 	mlo_ctx = vdev->mlo_dev_ctx;
936*5113495bSYour Name 
937*5113495bSYour Name 	if (!mlo_ctx) {
938*5113495bSYour Name 		mlo_err("null mlo_dev_ctx");
939*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
940*5113495bSYour Name 	}
941*5113495bSYour Name 
942*5113495bSYour Name 	sta_ctx = mlo_ctx->sta_ctx;
943*5113495bSYour Name 
944*5113495bSYour Name 	if (!sta_ctx)
945*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
946*5113495bSYour Name 
947*5113495bSYour Name 	mlo_dev_lock_acquire(mlo_ctx);
948*5113495bSYour Name 
949*5113495bSYour Name 	sta_ctx->ml_link_state.ml_link_state_resp_cb =
950*5113495bSYour Name 		req->ml_link_state_resp_cb;
951*5113495bSYour Name 	sta_ctx->ml_link_state.ml_link_state_req_context =
952*5113495bSYour Name 		req->request_cookie;
953*5113495bSYour Name 	mlo_dev_lock_release(mlo_ctx);
954*5113495bSYour Name 
955*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
956*5113495bSYour Name }
957*5113495bSYour Name 
ml_get_link_state_req_flush_cb(struct scheduler_msg * msg)958*5113495bSYour Name static QDF_STATUS ml_get_link_state_req_flush_cb(struct scheduler_msg *msg)
959*5113495bSYour Name {
960*5113495bSYour Name 	mlo_debug("ml_get_link_state_req flush callback");
961*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
962*5113495bSYour Name }
963*5113495bSYour Name 
ml_post_get_link_state_msg(struct wlan_objmgr_vdev * vdev)964*5113495bSYour Name QDF_STATUS ml_post_get_link_state_msg(struct wlan_objmgr_vdev *vdev)
965*5113495bSYour Name {
966*5113495bSYour Name 	struct scheduler_msg msg = {0};
967*5113495bSYour Name 	QDF_STATUS qdf_status = 0;
968*5113495bSYour Name 
969*5113495bSYour Name 	msg.bodyptr = vdev;
970*5113495bSYour Name 	msg.callback = ml_get_link_state_req_cb;
971*5113495bSYour Name 	msg.flush_callback = ml_get_link_state_req_flush_cb;
972*5113495bSYour Name 
973*5113495bSYour Name 	qdf_status = scheduler_post_message(
974*5113495bSYour Name 				QDF_MODULE_ID_OS_IF,
975*5113495bSYour Name 				QDF_MODULE_ID_MLME,
976*5113495bSYour Name 				QDF_MODULE_ID_OS_IF,
977*5113495bSYour Name 				&msg);
978*5113495bSYour Name 	return qdf_status;
979*5113495bSYour Name }
980*5113495bSYour Name 
981*5113495bSYour Name bool
wlan_mlo_is_csa_allow(struct wlan_objmgr_vdev * vdev,uint16_t csa_freq)982*5113495bSYour Name wlan_mlo_is_csa_allow(struct wlan_objmgr_vdev *vdev, uint16_t csa_freq)
983*5113495bSYour Name {
984*5113495bSYour Name 	struct wlan_channel *chan;
985*5113495bSYour Name 	struct wlan_objmgr_vdev *ml_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
986*5113495bSYour Name 	uint16_t ml_vdev_cnt = 0;
987*5113495bSYour Name 	struct wlan_objmgr_vdev *t_vdev;
988*5113495bSYour Name 	int i;
989*5113495bSYour Name 	bool is_allow = true;
990*5113495bSYour Name 
991*5113495bSYour Name 	if (!vdev) {
992*5113495bSYour Name 		mlo_err("vdev is NULL");
993*5113495bSYour Name 		return false;
994*5113495bSYour Name 	}
995*5113495bSYour Name 
996*5113495bSYour Name 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
997*5113495bSYour Name 		return true;
998*5113495bSYour Name 
999*5113495bSYour Name 	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, ml_vdev_list);
1000*5113495bSYour Name 	for (i = 0; i < ml_vdev_cnt; i++) {
1001*5113495bSYour Name 		t_vdev = ml_vdev_list[i];
1002*5113495bSYour Name 		if (t_vdev == vdev)
1003*5113495bSYour Name 			goto next;
1004*5113495bSYour Name 		chan = wlan_vdev_get_active_channel(t_vdev);
1005*5113495bSYour Name 		if (!chan)
1006*5113495bSYour Name 			goto next;
1007*5113495bSYour Name 
1008*5113495bSYour Name 		if (csa_freq == chan->ch_freq) {
1009*5113495bSYour Name 			mlo_err("vdev %d will SCC with vdev %d on freq %d",
1010*5113495bSYour Name 				wlan_vdev_get_id(vdev),
1011*5113495bSYour Name 				wlan_vdev_get_id(t_vdev), csa_freq);
1012*5113495bSYour Name 			is_allow = false;
1013*5113495bSYour Name 		}
1014*5113495bSYour Name next:
1015*5113495bSYour Name 		mlo_release_vdev_ref(t_vdev);
1016*5113495bSYour Name 	}
1017*5113495bSYour Name 
1018*5113495bSYour Name 	return is_allow;
1019*5113495bSYour Name }
1020*5113495bSYour Name 
1021