xref: /wlan-driver/qca-wifi-host-cmn/target_if/mlo_mgr/src/target_if_mlo_mgr.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3*5113495bSYour Name  *
4*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
5*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
6*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
7*5113495bSYour Name  *
8*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*5113495bSYour Name  */
16*5113495bSYour Name 
17*5113495bSYour Name /**
18*5113495bSYour Name  * DOC: target_if_mlo_mgr.c
19*5113495bSYour Name  *
20*5113495bSYour Name  * This file provide definition for APIs registered through lmac Tx Ops
21*5113495bSYour Name  */
22*5113495bSYour Name 
23*5113495bSYour Name #include <wmi_unified_11be_api.h>
24*5113495bSYour Name #include <init_deinit_lmac.h>
25*5113495bSYour Name #include "target_if_mlo_mgr.h"
26*5113495bSYour Name #include <wlan_objmgr_peer_obj.h>
27*5113495bSYour Name #include <wlan_mlo_t2lm.h>
28*5113495bSYour Name 
29*5113495bSYour Name /**
30*5113495bSYour Name  * target_if_mlo_link_set_active_resp_handler() - function to handle mlo link
31*5113495bSYour Name  *  set active response from firmware.
32*5113495bSYour Name  * @scn: scn handle
33*5113495bSYour Name  * @data: data buffer for event
34*5113495bSYour Name  * @datalen: data length
35*5113495bSYour Name  *
36*5113495bSYour Name  * Return: 0 on success, else error on failure
37*5113495bSYour Name  */
38*5113495bSYour Name static int
target_if_mlo_link_set_active_resp_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)39*5113495bSYour Name target_if_mlo_link_set_active_resp_handler(ol_scn_t scn, uint8_t *data,
40*5113495bSYour Name 					   uint32_t datalen)
41*5113495bSYour Name {
42*5113495bSYour Name 	QDF_STATUS status;
43*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
44*5113495bSYour Name 	struct wmi_unified *wmi_handle;
45*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *rx_ops;
46*5113495bSYour Name 	struct mlo_link_set_active_resp resp;
47*5113495bSYour Name 
48*5113495bSYour Name 	if (!scn || !data) {
49*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
50*5113495bSYour Name 		return -EINVAL;
51*5113495bSYour Name 	}
52*5113495bSYour Name 
53*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
54*5113495bSYour Name 	if (!psoc) {
55*5113495bSYour Name 		target_if_err("null psoc");
56*5113495bSYour Name 		return -EINVAL;
57*5113495bSYour Name 	}
58*5113495bSYour Name 
59*5113495bSYour Name 	rx_ops = target_if_mlo_get_rx_ops(psoc);
60*5113495bSYour Name 	if (!rx_ops || !rx_ops->process_link_set_active_resp) {
61*5113495bSYour Name 		target_if_err("callback not registered");
62*5113495bSYour Name 		return -EINVAL;
63*5113495bSYour Name 	}
64*5113495bSYour Name 
65*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
66*5113495bSYour Name 	if (!wmi_handle) {
67*5113495bSYour Name 		target_if_err("wmi_handle is null");
68*5113495bSYour Name 		return -EINVAL;
69*5113495bSYour Name 	}
70*5113495bSYour Name 	qdf_mem_zero(&resp, sizeof(resp));
71*5113495bSYour Name 	if (wmi_extract_mlo_link_set_active_resp(wmi_handle, data, &resp) !=
72*5113495bSYour Name 	    QDF_STATUS_SUCCESS) {
73*5113495bSYour Name 		target_if_err("Unable to extract mlo link set active resp");
74*5113495bSYour Name 		return -EINVAL;
75*5113495bSYour Name 	}
76*5113495bSYour Name 
77*5113495bSYour Name 	status = rx_ops->process_link_set_active_resp(psoc, &resp);
78*5113495bSYour Name 
79*5113495bSYour Name 	return qdf_status_to_os_return(status);
80*5113495bSYour Name }
81*5113495bSYour Name 
82*5113495bSYour Name /**
83*5113495bSYour Name  * target_if_mlo_link_removal_event_handler() - Handler for MLO link removal
84*5113495bSYour Name  * event sent by the FW
85*5113495bSYour Name  * @scn: scn handle
86*5113495bSYour Name  * @data: data buffer for event
87*5113495bSYour Name  * @datalen: data length
88*5113495bSYour Name  *
89*5113495bSYour Name  * Return: 0 on success, else error on failure
90*5113495bSYour Name  */
91*5113495bSYour Name static int
target_if_mlo_link_removal_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)92*5113495bSYour Name target_if_mlo_link_removal_event_handler(ol_scn_t scn, uint8_t *data,
93*5113495bSYour Name 					 uint32_t datalen)
94*5113495bSYour Name {
95*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
96*5113495bSYour Name 	struct wmi_unified *wmi_handle;
97*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *mlo_rx_ops;
98*5113495bSYour Name 	QDF_STATUS status;
99*5113495bSYour Name 	struct mlo_link_removal_evt_params evt_params;
100*5113495bSYour Name 
101*5113495bSYour Name 	if (!scn || !data) {
102*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
103*5113495bSYour Name 		return -EINVAL;
104*5113495bSYour Name 	}
105*5113495bSYour Name 
106*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
107*5113495bSYour Name 	if (!psoc) {
108*5113495bSYour Name 		target_if_err("null psoc");
109*5113495bSYour Name 		return -EINVAL;
110*5113495bSYour Name 	}
111*5113495bSYour Name 
112*5113495bSYour Name 	mlo_rx_ops = target_if_mlo_get_rx_ops(psoc);
113*5113495bSYour Name 	if (!mlo_rx_ops || !mlo_rx_ops->mlo_link_removal_handler) {
114*5113495bSYour Name 		target_if_err("callback not registered");
115*5113495bSYour Name 		return -EINVAL;
116*5113495bSYour Name 	}
117*5113495bSYour Name 
118*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
119*5113495bSYour Name 	if (!wmi_handle) {
120*5113495bSYour Name 		target_if_err("wmi_handle is null");
121*5113495bSYour Name 		return -EINVAL;
122*5113495bSYour Name 	}
123*5113495bSYour Name 
124*5113495bSYour Name 	status = wmi_extract_mlo_link_removal_evt_fixed_param(wmi_handle, data,
125*5113495bSYour Name 							      &evt_params);
126*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
127*5113495bSYour Name 		target_if_err("Unable to extract fixed param, ret = %d",
128*5113495bSYour Name 			      status);
129*5113495bSYour Name 		goto exit;
130*5113495bSYour Name 	}
131*5113495bSYour Name 
132*5113495bSYour Name 	status = wmi_extract_mlo_link_removal_tbtt_update(
133*5113495bSYour Name 			wmi_handle, data, &evt_params.tbtt_info);
134*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
135*5113495bSYour Name 		target_if_err("Unable to extract TBTT update TLV, ret = %d",
136*5113495bSYour Name 			      status);
137*5113495bSYour Name 		goto exit;
138*5113495bSYour Name 	}
139*5113495bSYour Name 
140*5113495bSYour Name 	status = mlo_rx_ops->mlo_link_removal_handler(psoc, &evt_params);
141*5113495bSYour Name exit:
142*5113495bSYour Name 	return qdf_status_to_os_return(status);
143*5113495bSYour Name }
144*5113495bSYour Name 
145*5113495bSYour Name QDF_STATUS
target_if_extract_mlo_link_removal_info_mgmt_rx(wmi_unified_t wmi_handle,void * evt_buf,struct mgmt_rx_event_params * rx_event)146*5113495bSYour Name target_if_extract_mlo_link_removal_info_mgmt_rx(
147*5113495bSYour Name 		wmi_unified_t wmi_handle,
148*5113495bSYour Name 		void *evt_buf,
149*5113495bSYour Name 		struct mgmt_rx_event_params *rx_event)
150*5113495bSYour Name {
151*5113495bSYour Name 	QDF_STATUS status;
152*5113495bSYour Name 	struct mgmt_rx_mlo_link_removal_info *link_removal_info;
153*5113495bSYour Name 
154*5113495bSYour Name 	if (!rx_event) {
155*5113495bSYour Name 		target_if_err("Invalid rx_event");
156*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
157*5113495bSYour Name 	}
158*5113495bSYour Name 
159*5113495bSYour Name 	rx_event->link_removal_info = NULL;
160*5113495bSYour Name 	if (!rx_event->num_link_removal_info) {
161*5113495bSYour Name 		/**
162*5113495bSYour Name 		 * This is not an error. Only probe request frames will contain
163*5113495bSYour Name 		 * Link removal TLVs, that too only till the link removal TBTT
164*5113495bSYour Name 		 * countdown completion.
165*5113495bSYour Name 		 */
166*5113495bSYour Name 		target_if_debug("Link removal TLVs are not present");
167*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
168*5113495bSYour Name 	}
169*5113495bSYour Name 
170*5113495bSYour Name 	link_removal_info = qdf_mem_malloc(rx_event->num_link_removal_info *
171*5113495bSYour Name 					   sizeof(*link_removal_info));
172*5113495bSYour Name 	if (!link_removal_info) {
173*5113495bSYour Name 		target_if_err("Couldn't allocate memory for link_removal_info");
174*5113495bSYour Name 		rx_event->num_link_removal_info = 0;
175*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
176*5113495bSYour Name 	}
177*5113495bSYour Name 
178*5113495bSYour Name 	status = wmi_extract_mgmt_rx_mlo_link_removal_info(
179*5113495bSYour Name 					wmi_handle, evt_buf,
180*5113495bSYour Name 					link_removal_info,
181*5113495bSYour Name 					rx_event->num_link_removal_info);
182*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
183*5113495bSYour Name 		target_if_err("Unable to extract link removal TLVs");
184*5113495bSYour Name 		rx_event->num_link_removal_info = 0;
185*5113495bSYour Name 		qdf_mem_free(link_removal_info);
186*5113495bSYour Name 		return status;
187*5113495bSYour Name 	}
188*5113495bSYour Name 
189*5113495bSYour Name 	rx_event->link_removal_info = link_removal_info;
190*5113495bSYour Name 
191*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
192*5113495bSYour Name }
193*5113495bSYour Name 
194*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
195*5113495bSYour Name static QDF_STATUS
target_if_send_mlo_link_switch_cnf_cmd(struct wlan_objmgr_psoc * psoc,struct wlan_mlo_link_switch_cnf * params)196*5113495bSYour Name target_if_send_mlo_link_switch_cnf_cmd(struct wlan_objmgr_psoc *psoc,
197*5113495bSYour Name 				       struct wlan_mlo_link_switch_cnf *params)
198*5113495bSYour Name {
199*5113495bSYour Name 	struct wmi_unified *wmi_handle = NULL;
200*5113495bSYour Name 
201*5113495bSYour Name 	if (!psoc) {
202*5113495bSYour Name 		target_if_err("null pdev");
203*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
204*5113495bSYour Name 	}
205*5113495bSYour Name 
206*5113495bSYour Name 	if (!params) {
207*5113495bSYour Name 		target_if_err("params is null");
208*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
209*5113495bSYour Name 	}
210*5113495bSYour Name 
211*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
212*5113495bSYour Name 	if (!wmi_handle) {
213*5113495bSYour Name 		target_if_err("null wmi handle");
214*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
215*5113495bSYour Name 	}
216*5113495bSYour Name 
217*5113495bSYour Name 	return wmi_send_mlo_link_switch_req_cnf_cmd(wmi_handle, params);
218*5113495bSYour Name }
219*5113495bSYour Name 
220*5113495bSYour Name static int
target_if_mlo_link_state_switch_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)221*5113495bSYour Name target_if_mlo_link_state_switch_event_handler(ol_scn_t scn, uint8_t *data,
222*5113495bSYour Name 					      uint32_t datalen)
223*5113495bSYour Name {
224*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
225*5113495bSYour Name 	struct wmi_unified *wmi_handle;
226*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *mlo_rx_ops;
227*5113495bSYour Name 	struct mlo_link_switch_state_info evt_params;
228*5113495bSYour Name 	QDF_STATUS status;
229*5113495bSYour Name 
230*5113495bSYour Name 	if (!scn || !data) {
231*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
232*5113495bSYour Name 		return -EINVAL;
233*5113495bSYour Name 	}
234*5113495bSYour Name 
235*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
236*5113495bSYour Name 	if (!psoc) {
237*5113495bSYour Name 		target_if_err("null psoc");
238*5113495bSYour Name 		return -EINVAL;
239*5113495bSYour Name 	}
240*5113495bSYour Name 
241*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
242*5113495bSYour Name 	if (!wmi_handle) {
243*5113495bSYour Name 		target_if_err("wmi_handle is null");
244*5113495bSYour Name 		return -EINVAL;
245*5113495bSYour Name 	}
246*5113495bSYour Name 
247*5113495bSYour Name 	mlo_rx_ops = target_if_mlo_get_rx_ops(psoc);
248*5113495bSYour Name 	if (!mlo_rx_ops || !mlo_rx_ops->mlo_link_state_switch_event_handler) {
249*5113495bSYour Name 		target_if_err("callback not registered");
250*5113495bSYour Name 		return -EINVAL;
251*5113495bSYour Name 	}
252*5113495bSYour Name 
253*5113495bSYour Name 	status = wmi_extract_mlo_link_state_switch_evt(wmi_handle, data,
254*5113495bSYour Name 						       datalen,
255*5113495bSYour Name 						       &evt_params);
256*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
257*5113495bSYour Name 		target_if_err("Unable to extract link state switch params");
258*5113495bSYour Name 		goto exit;
259*5113495bSYour Name 	}
260*5113495bSYour Name 
261*5113495bSYour Name 	status = mlo_rx_ops->mlo_link_state_switch_event_handler(psoc,
262*5113495bSYour Name 								 &evt_params);
263*5113495bSYour Name exit:
264*5113495bSYour Name 	return qdf_status_to_os_return(status);
265*5113495bSYour Name }
266*5113495bSYour Name 
267*5113495bSYour Name static int
target_if_mlo_link_switch_request_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)268*5113495bSYour Name target_if_mlo_link_switch_request_event_handler(ol_scn_t scn, uint8_t *data,
269*5113495bSYour Name 						uint32_t datalen)
270*5113495bSYour Name {
271*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
272*5113495bSYour Name 	struct wmi_unified *wmi_handle;
273*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *mlo_rx_ops;
274*5113495bSYour Name 	QDF_STATUS status;
275*5113495bSYour Name 	struct wlan_mlo_link_switch_req req = {0};
276*5113495bSYour Name 
277*5113495bSYour Name 	if (!scn || !data) {
278*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
279*5113495bSYour Name 		return -EINVAL;
280*5113495bSYour Name 	}
281*5113495bSYour Name 
282*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
283*5113495bSYour Name 	if (!psoc) {
284*5113495bSYour Name 		target_if_err("null psoc");
285*5113495bSYour Name 		return -EINVAL;
286*5113495bSYour Name 	}
287*5113495bSYour Name 
288*5113495bSYour Name 	mlo_rx_ops = target_if_mlo_get_rx_ops(psoc);
289*5113495bSYour Name 	if (!mlo_rx_ops || !mlo_rx_ops->mlo_link_switch_request_handler) {
290*5113495bSYour Name 		target_if_err("callback not registered");
291*5113495bSYour Name 		return -EINVAL;
292*5113495bSYour Name 	}
293*5113495bSYour Name 
294*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
295*5113495bSYour Name 	if (!wmi_handle) {
296*5113495bSYour Name 		target_if_err("wmi_handle is null");
297*5113495bSYour Name 		return -EINVAL;
298*5113495bSYour Name 	}
299*5113495bSYour Name 
300*5113495bSYour Name 	status = wmi_extract_mlo_link_switch_request_evt(wmi_handle, data,
301*5113495bSYour Name 							 &req);
302*5113495bSYour Name 
303*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
304*5113495bSYour Name 		target_if_err("Unable to extract fixed param, ret = %d",
305*5113495bSYour Name 			      status);
306*5113495bSYour Name 		goto exit;
307*5113495bSYour Name 	}
308*5113495bSYour Name 
309*5113495bSYour Name 	status = mlo_rx_ops->mlo_link_switch_request_handler(psoc, &req);
310*5113495bSYour Name 
311*5113495bSYour Name exit:
312*5113495bSYour Name 	return status;
313*5113495bSYour Name }
314*5113495bSYour Name 
315*5113495bSYour Name static inline void
target_if_mlo_register_link_switch_cnf_handler(struct wlan_lmac_if_mlo_tx_ops * mlo_tx_ops)316*5113495bSYour Name target_if_mlo_register_link_switch_cnf_handler(struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops)
317*5113495bSYour Name {
318*5113495bSYour Name 	mlo_tx_ops->send_mlo_link_switch_cnf_cmd =
319*5113495bSYour Name 			target_if_send_mlo_link_switch_cnf_cmd;
320*5113495bSYour Name }
321*5113495bSYour Name 
322*5113495bSYour Name static QDF_STATUS
target_if_mlo_register_link_switch_event_handler(struct wmi_unified * wmi_handle)323*5113495bSYour Name target_if_mlo_register_link_switch_event_handler(struct wmi_unified *wmi_handle)
324*5113495bSYour Name {
325*5113495bSYour Name 	QDF_STATUS status;
326*5113495bSYour Name 
327*5113495bSYour Name 	status = wmi_unified_register_event_handler(
328*5113495bSYour Name 			wmi_handle,
329*5113495bSYour Name 			wmi_mlo_link_switch_request_eventid,
330*5113495bSYour Name 			target_if_mlo_link_switch_request_event_handler,
331*5113495bSYour Name 			WMI_RX_SERIALIZER_CTX);
332*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
333*5113495bSYour Name 		target_if_err("Register event:%d failed",
334*5113495bSYour Name 			      wmi_mlo_link_switch_request_eventid);
335*5113495bSYour Name 
336*5113495bSYour Name 	status = wmi_unified_register_event_handler(
337*5113495bSYour Name 			wmi_handle, wmi_mlo_link_state_switch_eventid,
338*5113495bSYour Name 			target_if_mlo_link_state_switch_event_handler,
339*5113495bSYour Name 			WMI_RX_SERIALIZER_CTX);
340*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
341*5113495bSYour Name 		target_if_err("Register event:%d failed",
342*5113495bSYour Name 			      wmi_mlo_link_state_switch_eventid);
343*5113495bSYour Name 
344*5113495bSYour Name 	return status;
345*5113495bSYour Name }
346*5113495bSYour Name 
347*5113495bSYour Name static inline void
target_if_mlo_unregister_link_switch_event_handler(struct wmi_unified * wmi_handle)348*5113495bSYour Name target_if_mlo_unregister_link_switch_event_handler(struct wmi_unified *wmi_handle)
349*5113495bSYour Name {
350*5113495bSYour Name 	wmi_unified_unregister_event(wmi_handle,
351*5113495bSYour Name 				     wmi_mlo_link_switch_request_eventid);
352*5113495bSYour Name }
353*5113495bSYour Name #else
354*5113495bSYour Name static inline QDF_STATUS
target_if_mlo_register_link_switch_event_handler(struct wmi_unified * wmi_handle)355*5113495bSYour Name target_if_mlo_register_link_switch_event_handler(struct wmi_unified *wmi_handle)
356*5113495bSYour Name {
357*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
358*5113495bSYour Name }
359*5113495bSYour Name 
360*5113495bSYour Name static inline void
target_if_mlo_unregister_link_switch_event_handler(struct wmi_unified * wmi_handle)361*5113495bSYour Name target_if_mlo_unregister_link_switch_event_handler(struct wmi_unified *wmi_handle)
362*5113495bSYour Name {
363*5113495bSYour Name }
364*5113495bSYour Name 
365*5113495bSYour Name static inline QDF_STATUS
target_if_send_mlo_link_switch_cnf_cmd(struct wlan_objmgr_psoc * psoc,struct wlan_mlo_link_switch_cnf * params)366*5113495bSYour Name target_if_send_mlo_link_switch_cnf_cmd(struct wlan_objmgr_psoc *psoc,
367*5113495bSYour Name 				       struct wlan_mlo_link_switch_cnf *params)
368*5113495bSYour Name {
369*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
370*5113495bSYour Name }
371*5113495bSYour Name 
372*5113495bSYour Name static inline void
target_if_mlo_register_link_switch_cnf_handler(struct wlan_lmac_if_mlo_tx_ops * mlo_tx_ops)373*5113495bSYour Name target_if_mlo_register_link_switch_cnf_handler(struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops)
374*5113495bSYour Name {
375*5113495bSYour Name }
376*5113495bSYour Name 
377*5113495bSYour Name static inline int
target_if_mlo_link_switch_request_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)378*5113495bSYour Name target_if_mlo_link_switch_request_event_handler(ol_scn_t scn, uint8_t *data,
379*5113495bSYour Name 						uint32_t datalen)
380*5113495bSYour Name {
381*5113495bSYour Name 	return 0;
382*5113495bSYour Name }
383*5113495bSYour Name #endif
384*5113495bSYour Name 
385*5113495bSYour Name /**
386*5113495bSYour Name  * target_if_mlo_link_disable_request_event_handler() - Handler for MLO
387*5113495bSYour Name  * link disable request event sent by the FW
388*5113495bSYour Name  * @scn: scn handle
389*5113495bSYour Name  * @data: data buffer for event
390*5113495bSYour Name  * @datalen: data length
391*5113495bSYour Name  *
392*5113495bSYour Name  * Return: 0 on success, else error on failure
393*5113495bSYour Name  */
394*5113495bSYour Name static int
target_if_mlo_link_disable_request_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)395*5113495bSYour Name target_if_mlo_link_disable_request_event_handler(ol_scn_t scn, uint8_t *data,
396*5113495bSYour Name 						 uint32_t datalen)
397*5113495bSYour Name {
398*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
399*5113495bSYour Name 	struct wmi_unified *wmi_handle;
400*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *mlo_rx_ops;
401*5113495bSYour Name 	QDF_STATUS status;
402*5113495bSYour Name 	struct mlo_link_disable_request_evt_params evt_params;
403*5113495bSYour Name 
404*5113495bSYour Name 	if (!scn || !data) {
405*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
406*5113495bSYour Name 		return -EINVAL;
407*5113495bSYour Name 	}
408*5113495bSYour Name 
409*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
410*5113495bSYour Name 	if (!psoc) {
411*5113495bSYour Name 		target_if_err("null psoc");
412*5113495bSYour Name 		return -EINVAL;
413*5113495bSYour Name 	}
414*5113495bSYour Name 
415*5113495bSYour Name 	mlo_rx_ops = target_if_mlo_get_rx_ops(psoc);
416*5113495bSYour Name 	if (!mlo_rx_ops || !mlo_rx_ops->mlo_link_disable_request_handler) {
417*5113495bSYour Name 		target_if_err("callback not registered");
418*5113495bSYour Name 		return -EINVAL;
419*5113495bSYour Name 	}
420*5113495bSYour Name 
421*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
422*5113495bSYour Name 	if (!wmi_handle) {
423*5113495bSYour Name 		target_if_err("wmi_handle is null");
424*5113495bSYour Name 		return -EINVAL;
425*5113495bSYour Name 	}
426*5113495bSYour Name 
427*5113495bSYour Name 	status = wmi_extract_mlo_link_disable_request_evt(wmi_handle, data,
428*5113495bSYour Name 							  &evt_params);
429*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
430*5113495bSYour Name 		target_if_err("Unable to extract fixed param, ret = %d",
431*5113495bSYour Name 			      status);
432*5113495bSYour Name 		goto exit;
433*5113495bSYour Name 	}
434*5113495bSYour Name 
435*5113495bSYour Name 	status = mlo_rx_ops->mlo_link_disable_request_handler(psoc,
436*5113495bSYour Name 							      &evt_params);
437*5113495bSYour Name exit:
438*5113495bSYour Name 	return qdf_status_to_os_return(status);
439*5113495bSYour Name }
440*5113495bSYour Name 
441*5113495bSYour Name /**
442*5113495bSYour Name  * target_if_mlo_register_event_handler() - function to register handler for
443*5113495bSYour Name  *  mlo related wmi event from firmware.
444*5113495bSYour Name  * @psoc: psoc pointer
445*5113495bSYour Name  *
446*5113495bSYour Name  * Return: QDF_STATUS
447*5113495bSYour Name  */
448*5113495bSYour Name static QDF_STATUS
target_if_mlo_register_event_handler(struct wlan_objmgr_psoc * psoc)449*5113495bSYour Name target_if_mlo_register_event_handler(struct wlan_objmgr_psoc *psoc)
450*5113495bSYour Name {
451*5113495bSYour Name 	QDF_STATUS status;
452*5113495bSYour Name 	struct wmi_unified *wmi_handle;
453*5113495bSYour Name 
454*5113495bSYour Name 	if (!psoc) {
455*5113495bSYour Name 		target_if_err("PSOC is NULL!");
456*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
457*5113495bSYour Name 	}
458*5113495bSYour Name 
459*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
460*5113495bSYour Name 	if (!wmi_handle) {
461*5113495bSYour Name 		target_if_err("wmi_handle is null");
462*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
463*5113495bSYour Name 	}
464*5113495bSYour Name 
465*5113495bSYour Name 	status = wmi_unified_register_event(
466*5113495bSYour Name 			wmi_handle,
467*5113495bSYour Name 			wmi_mlo_link_removal_eventid,
468*5113495bSYour Name 			target_if_mlo_link_removal_event_handler);
469*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
470*5113495bSYour Name 		target_if_err("Couldn't register handler for Link removal WMI event %d",
471*5113495bSYour Name 			      status);
472*5113495bSYour Name 
473*5113495bSYour Name 	status = wmi_unified_register_event_handler(
474*5113495bSYour Name 			wmi_handle,
475*5113495bSYour Name 			wmi_mlo_link_set_active_resp_eventid,
476*5113495bSYour Name 			target_if_mlo_link_set_active_resp_handler,
477*5113495bSYour Name 			WMI_RX_SERIALIZER_CTX);
478*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
479*5113495bSYour Name 		target_if_err("Register mlo link set active resp cb errcode %d",
480*5113495bSYour Name 			      status);
481*5113495bSYour Name 		if (status == QDF_STATUS_E_NOSUPPORT)
482*5113495bSYour Name 			status = QDF_STATUS_SUCCESS;
483*5113495bSYour Name 	}
484*5113495bSYour Name 
485*5113495bSYour Name 	target_if_mlo_register_vdev_tid_to_link_map_event(wmi_handle);
486*5113495bSYour Name 	target_if_mlo_register_mlo_link_state_info_event(wmi_handle);
487*5113495bSYour Name 
488*5113495bSYour Name 	status = wmi_unified_register_event_handler(wmi_handle,
489*5113495bSYour Name 			wmi_mlo_link_disable_request_eventid,
490*5113495bSYour Name 			target_if_mlo_link_disable_request_event_handler,
491*5113495bSYour Name 			WMI_RX_SERIALIZER_CTX);
492*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
493*5113495bSYour Name 		target_if_err("Couldn't register handler for link disable request WMI event %d",
494*5113495bSYour Name 			      status);
495*5113495bSYour Name 		if (status == QDF_STATUS_E_NOSUPPORT)
496*5113495bSYour Name 			status = QDF_STATUS_SUCCESS;
497*5113495bSYour Name 	}
498*5113495bSYour Name 
499*5113495bSYour Name 	status = target_if_mlo_register_link_switch_event_handler(wmi_handle);
500*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
501*5113495bSYour Name 		target_if_err("Couldn't register handler for link switch WMI event %d",
502*5113495bSYour Name 			      status);
503*5113495bSYour Name 		if (status == QDF_STATUS_E_NOSUPPORT)
504*5113495bSYour Name 			status = QDF_STATUS_SUCCESS;
505*5113495bSYour Name 	}
506*5113495bSYour Name 
507*5113495bSYour Name 	return status;
508*5113495bSYour Name }
509*5113495bSYour Name 
510*5113495bSYour Name /**
511*5113495bSYour Name  * target_if_mlo_unregister_event_handler() - function to unregister handler for
512*5113495bSYour Name  *  mlo related wmi event from firmware.
513*5113495bSYour Name  * @psoc: psoc pointer
514*5113495bSYour Name  *
515*5113495bSYour Name  * Return: QDF_STATUS
516*5113495bSYour Name  */
517*5113495bSYour Name static QDF_STATUS
target_if_mlo_unregister_event_handler(struct wlan_objmgr_psoc * psoc)518*5113495bSYour Name target_if_mlo_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
519*5113495bSYour Name {
520*5113495bSYour Name 	struct wmi_unified *wmi_handle;
521*5113495bSYour Name 
522*5113495bSYour Name 	if (!psoc) {
523*5113495bSYour Name 		target_if_err("PSOC is NULL!");
524*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
525*5113495bSYour Name 	}
526*5113495bSYour Name 
527*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
528*5113495bSYour Name 	if (!wmi_handle) {
529*5113495bSYour Name 		target_if_err("wmi_handle is null");
530*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
531*5113495bSYour Name 	}
532*5113495bSYour Name 
533*5113495bSYour Name 	wmi_unified_unregister_event_handler(wmi_handle,
534*5113495bSYour Name 		wmi_mlo_link_set_active_resp_eventid);
535*5113495bSYour Name 
536*5113495bSYour Name 	wmi_unified_unregister_event(wmi_handle,
537*5113495bSYour Name 				     wmi_mlo_link_removal_eventid);
538*5113495bSYour Name 
539*5113495bSYour Name 	target_if_mlo_unregister_vdev_tid_to_link_map_event(wmi_handle);
540*5113495bSYour Name 	target_if_mlo_unregister_mlo_link_state_info_event(wmi_handle);
541*5113495bSYour Name 
542*5113495bSYour Name 	wmi_unified_unregister_event(wmi_handle,
543*5113495bSYour Name 				     wmi_mlo_link_disable_request_eventid);
544*5113495bSYour Name 
545*5113495bSYour Name 	target_if_mlo_unregister_link_switch_event_handler(wmi_handle);
546*5113495bSYour Name 
547*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
548*5113495bSYour Name }
549*5113495bSYour Name 
550*5113495bSYour Name /**
551*5113495bSYour Name  * target_if_mlo_link_set_active() - Send WMI command for set mlo link active
552*5113495bSYour Name  * @psoc: psoc pointer
553*5113495bSYour Name  * @param: parameter for setting mlo link active
554*5113495bSYour Name  *
555*5113495bSYour Name  * Return: QDF_STATUS
556*5113495bSYour Name  */
557*5113495bSYour Name static QDF_STATUS
target_if_mlo_link_set_active(struct wlan_objmgr_psoc * psoc,struct mlo_link_set_active_param * param)558*5113495bSYour Name target_if_mlo_link_set_active(struct wlan_objmgr_psoc *psoc,
559*5113495bSYour Name 			      struct mlo_link_set_active_param *param)
560*5113495bSYour Name {
561*5113495bSYour Name 	QDF_STATUS ret;
562*5113495bSYour Name 	struct wmi_unified *wmi_handle;
563*5113495bSYour Name 
564*5113495bSYour Name 	if (!psoc) {
565*5113495bSYour Name 		target_if_err("null psoc");
566*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
567*5113495bSYour Name 	}
568*5113495bSYour Name 
569*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
570*5113495bSYour Name 	if (!wmi_handle) {
571*5113495bSYour Name 		target_if_err("null handle");
572*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
573*5113495bSYour Name 	}
574*5113495bSYour Name 
575*5113495bSYour Name 	ret = wmi_send_mlo_link_set_active_cmd(wmi_handle, param);
576*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
577*5113495bSYour Name 		target_if_err("wmi mlo link set active send failed: %d", ret);
578*5113495bSYour Name 
579*5113495bSYour Name 	return ret;
580*5113495bSYour Name }
581*5113495bSYour Name 
target_if_mlo_vdev_tid_to_link_map_event_handler(ol_scn_t scn,uint8_t * event_buff,uint32_t len)582*5113495bSYour Name static int target_if_mlo_vdev_tid_to_link_map_event_handler(
583*5113495bSYour Name 		ol_scn_t scn, uint8_t *event_buff, uint32_t len)
584*5113495bSYour Name {
585*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
586*5113495bSYour Name 	struct mlo_vdev_host_tid_to_link_map_resp event = {0};
587*5113495bSYour Name 	struct wmi_unified *wmi_handle;
588*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *rx_ops;
589*5113495bSYour Name 	QDF_STATUS status;
590*5113495bSYour Name 
591*5113495bSYour Name 	if (!event_buff) {
592*5113495bSYour Name 		mlme_err("Received NULL event ptr from FW");
593*5113495bSYour Name 		return -EINVAL;
594*5113495bSYour Name 	}
595*5113495bSYour Name 
596*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
597*5113495bSYour Name 	if (!psoc) {
598*5113495bSYour Name 		mlme_err("PSOC is NULL");
599*5113495bSYour Name 		return -EINVAL;
600*5113495bSYour Name 	}
601*5113495bSYour Name 
602*5113495bSYour Name 	rx_ops = target_if_mlo_get_rx_ops(psoc);
603*5113495bSYour Name 	if (!rx_ops || !rx_ops->process_mlo_vdev_tid_to_link_map_event) {
604*5113495bSYour Name 		target_if_err("callback not registered");
605*5113495bSYour Name 		return -EINVAL;
606*5113495bSYour Name 	}
607*5113495bSYour Name 
608*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
609*5113495bSYour Name 	if (!wmi_handle) {
610*5113495bSYour Name 		mlme_err("wmi_handle is null");
611*5113495bSYour Name 		return -EINVAL;
612*5113495bSYour Name 	}
613*5113495bSYour Name 
614*5113495bSYour Name 	if (wmi_extract_mlo_vdev_tid_to_link_map_event(wmi_handle, event_buff,
615*5113495bSYour Name 						       &event)) {
616*5113495bSYour Name 		mlme_err("Failed to extract TID-to-link mapping event");
617*5113495bSYour Name 		return -EINVAL;
618*5113495bSYour Name 	}
619*5113495bSYour Name 
620*5113495bSYour Name 	status = rx_ops->process_mlo_vdev_tid_to_link_map_event(psoc, &event);
621*5113495bSYour Name 
622*5113495bSYour Name 	return qdf_status_to_os_return(status);
623*5113495bSYour Name }
624*5113495bSYour Name 
target_if_mlo_register_vdev_tid_to_link_map_event(struct wmi_unified * wmi_handle)625*5113495bSYour Name void target_if_mlo_register_vdev_tid_to_link_map_event(
626*5113495bSYour Name 		struct wmi_unified *wmi_handle)
627*5113495bSYour Name {
628*5113495bSYour Name 	wmi_unified_register_event_handler(
629*5113495bSYour Name 			wmi_handle, wmi_mlo_ap_vdev_tid_to_link_map_eventid,
630*5113495bSYour Name 			target_if_mlo_vdev_tid_to_link_map_event_handler,
631*5113495bSYour Name 			WMI_RX_EXECUTION_CTX);
632*5113495bSYour Name }
633*5113495bSYour Name 
target_if_mlo_unregister_vdev_tid_to_link_map_event(struct wmi_unified * wmi_handle)634*5113495bSYour Name void target_if_mlo_unregister_vdev_tid_to_link_map_event(
635*5113495bSYour Name 		struct wmi_unified *wmi_handle)
636*5113495bSYour Name {
637*5113495bSYour Name 	wmi_unified_unregister_event_handler(
638*5113495bSYour Name 			wmi_handle, wmi_mlo_ap_vdev_tid_to_link_map_eventid);
639*5113495bSYour Name }
640*5113495bSYour Name 
target_if_mlo_link_state_info_event_handler(ol_scn_t scn,uint8_t * event_buff,uint32_t len)641*5113495bSYour Name static int target_if_mlo_link_state_info_event_handler(
642*5113495bSYour Name 		ol_scn_t scn, uint8_t *event_buff, uint32_t len)
643*5113495bSYour Name {
644*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
645*5113495bSYour Name 	struct wmi_unified *wmi_handle;
646*5113495bSYour Name 	QDF_STATUS status;
647*5113495bSYour Name 	struct wlan_lmac_if_mlo_rx_ops *mlo_rx_ops;
648*5113495bSYour Name 	struct ml_link_state_info_event event = {0};
649*5113495bSYour Name 
650*5113495bSYour Name 	if (!event_buff) {
651*5113495bSYour Name 		target_if_err("Received NULL event ptr from FW");
652*5113495bSYour Name 		return -EINVAL;
653*5113495bSYour Name 	}
654*5113495bSYour Name 
655*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
656*5113495bSYour Name 	if (!psoc) {
657*5113495bSYour Name 		target_if_err("PSOC is NULL");
658*5113495bSYour Name 		return -EINVAL;
659*5113495bSYour Name 	}
660*5113495bSYour Name 
661*5113495bSYour Name 	mlo_rx_ops = target_if_mlo_get_rx_ops(psoc);
662*5113495bSYour Name 	if (!mlo_rx_ops || !mlo_rx_ops->process_mlo_link_state_info_event) {
663*5113495bSYour Name 		target_if_err("callback not registered");
664*5113495bSYour Name 		return -EINVAL;
665*5113495bSYour Name 	}
666*5113495bSYour Name 
667*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
668*5113495bSYour Name 	if (!wmi_handle) {
669*5113495bSYour Name 		target_if_err("wmi_handle is null");
670*5113495bSYour Name 		return -EINVAL;
671*5113495bSYour Name 	}
672*5113495bSYour Name 
673*5113495bSYour Name 	if (wmi_extract_mlo_link_state_info_event(wmi_handle, event_buff,
674*5113495bSYour Name 						  &event)) {
675*5113495bSYour Name 		target_if_err("Failed to extract link status event");
676*5113495bSYour Name 		return -EINVAL;
677*5113495bSYour Name 	}
678*5113495bSYour Name 
679*5113495bSYour Name 	status = mlo_rx_ops->process_mlo_link_state_info_event(psoc, &event);
680*5113495bSYour Name 	return qdf_status_to_os_return(status);
681*5113495bSYour Name }
682*5113495bSYour Name 
target_if_mlo_register_mlo_link_state_info_event(struct wmi_unified * wmi_handle)683*5113495bSYour Name void target_if_mlo_register_mlo_link_state_info_event(
684*5113495bSYour Name 		struct wmi_unified *wmi_handle)
685*5113495bSYour Name {
686*5113495bSYour Name 	wmi_unified_register_event_handler(
687*5113495bSYour Name 		wmi_handle, wmi_mlo_link_state_info_eventid,
688*5113495bSYour Name 		target_if_mlo_link_state_info_event_handler,
689*5113495bSYour Name 		WMI_RX_EXECUTION_CTX);
690*5113495bSYour Name }
691*5113495bSYour Name 
target_if_mlo_unregister_mlo_link_state_info_event(struct wmi_unified * wmi_handle)692*5113495bSYour Name void  target_if_mlo_unregister_mlo_link_state_info_event(
693*5113495bSYour Name 		struct wmi_unified *wmi_handle)
694*5113495bSYour Name {
695*5113495bSYour Name 	wmi_unified_unregister_event_handler(
696*5113495bSYour Name 			wmi_handle,
697*5113495bSYour Name 			wmi_mlo_link_state_info_eventid);
698*5113495bSYour Name }
699*5113495bSYour Name 
700*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
701*5113495bSYour Name /**
702*5113495bSYour Name  * target_if_fill_provisioned_links() - API to fill the provisioned links
703*5113495bSYour Name  * @params: Pointer to T2LM params structure
704*5113495bSYour Name  * @t2lm: Pointer to T2LM info structure
705*5113495bSYour Name  *
706*5113495bSYour Name  * Return: none
707*5113495bSYour Name  */
target_if_fill_provisioned_links(struct wmi_host_tid_to_link_map_params * params,struct wlan_t2lm_info * t2lm)708*5113495bSYour Name static inline void target_if_fill_provisioned_links(
709*5113495bSYour Name 		struct wmi_host_tid_to_link_map_params *params,
710*5113495bSYour Name 		struct wlan_t2lm_info *t2lm)
711*5113495bSYour Name {
712*5113495bSYour Name 	qdf_mem_copy(&params->t2lm_info[params->num_dir].t2lm_provisioned_links,
713*5113495bSYour Name 		     &t2lm->ieee_link_map_tid,
714*5113495bSYour Name 		     sizeof(uint16_t) * T2LM_MAX_NUM_TIDS);
715*5113495bSYour Name }
716*5113495bSYour Name 
717*5113495bSYour Name /**
718*5113495bSYour Name  * target_if_fill_timer() - API to fill the t2lm timer values
719*5113495bSYour Name  * @params: Pointer to T2LM params structure
720*5113495bSYour Name  * @t2lm: Pointer to T2LM info structure
721*5113495bSYour Name  *
722*5113495bSYour Name  * Return: none
723*5113495bSYour Name  */
724*5113495bSYour Name static inline void
target_if_fill_timer(struct wmi_host_tid_to_link_map_params * params,struct wlan_t2lm_info * t2lm)725*5113495bSYour Name target_if_fill_timer(struct wmi_host_tid_to_link_map_params *params,
726*5113495bSYour Name 		     struct wlan_t2lm_info *t2lm)
727*5113495bSYour Name {
728*5113495bSYour Name 	if (t2lm->mapping_switch_time_present)
729*5113495bSYour Name 		params->mapping_switch_time = t2lm->mapping_switch_time;
730*5113495bSYour Name 
731*5113495bSYour Name 	if (t2lm->expected_duration_present)
732*5113495bSYour Name 		params->expected_duration = t2lm->expected_duration;
733*5113495bSYour Name }
734*5113495bSYour Name 
735*5113495bSYour Name #else
target_if_fill_provisioned_links(struct wmi_host_tid_to_link_map_params * params,struct wlan_t2lm_info * t2lm)736*5113495bSYour Name static inline void target_if_fill_provisioned_links(
737*5113495bSYour Name 		struct wmi_host_tid_to_link_map_params *params,
738*5113495bSYour Name 		struct wlan_t2lm_info *t2lm)
739*5113495bSYour Name {
740*5113495bSYour Name 	qdf_mem_copy(&params->t2lm_info[params->num_dir].t2lm_provisioned_links,
741*5113495bSYour Name 		     &t2lm->hw_link_map_tid,
742*5113495bSYour Name 		     sizeof(uint16_t) * T2LM_MAX_NUM_TIDS);
743*5113495bSYour Name }
744*5113495bSYour Name 
745*5113495bSYour Name static inline void
target_if_fill_timer(struct wmi_host_tid_to_link_map_params * params,struct wlan_t2lm_info * t2lm)746*5113495bSYour Name target_if_fill_timer(struct wmi_host_tid_to_link_map_params *params,
747*5113495bSYour Name 		     struct wlan_t2lm_info *t2lm)
748*5113495bSYour Name {
749*5113495bSYour Name }
750*5113495bSYour Name #endif
751*5113495bSYour Name 
752*5113495bSYour Name static QDF_STATUS
target_if_mlo_send_tid_to_link_mapping(struct wlan_objmgr_vdev * vdev,struct wlan_t2lm_info * t2lm)753*5113495bSYour Name target_if_mlo_send_tid_to_link_mapping(struct wlan_objmgr_vdev *vdev,
754*5113495bSYour Name 				       struct wlan_t2lm_info *t2lm)
755*5113495bSYour Name {
756*5113495bSYour Name 	struct wmi_unified *wmi_handle = NULL;
757*5113495bSYour Name 	struct wmi_host_tid_to_link_map_params params = {0};
758*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = NULL;
759*5113495bSYour Name 	int tid = 0;
760*5113495bSYour Name 	QDF_STATUS status;
761*5113495bSYour Name 
762*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
763*5113495bSYour Name 	if (!pdev) {
764*5113495bSYour Name 		t2lm_err("null pdev");
765*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
766*5113495bSYour Name 	}
767*5113495bSYour Name 
768*5113495bSYour Name 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
769*5113495bSYour Name 	if (!wmi_handle) {
770*5113495bSYour Name 		t2lm_err("null wmi handle");
771*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
772*5113495bSYour Name 	}
773*5113495bSYour Name 
774*5113495bSYour Name 	params.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
775*5113495bSYour Name 	qdf_mem_copy(params.peer_macaddr, vdev->vdev_objmgr.bss_peer->macaddr,
776*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
777*5113495bSYour Name 
778*5113495bSYour Name 	t2lm_debug("Fill T2LM WMI info for peer: " QDF_MAC_ADDR_FMT " pdev_id:%d",
779*5113495bSYour Name 		   QDF_MAC_ADDR_REF(params.peer_macaddr), params.pdev_id);
780*5113495bSYour Name 
781*5113495bSYour Name 	params.t2lm_info[params.num_dir].direction = t2lm->direction;
782*5113495bSYour Name 	params.t2lm_info[params.num_dir].default_link_mapping =
783*5113495bSYour Name 		t2lm->default_link_mapping;
784*5113495bSYour Name 
785*5113495bSYour Name 	if (!params.t2lm_info[params.num_dir].default_link_mapping)
786*5113495bSYour Name 		target_if_fill_provisioned_links(&params, t2lm);
787*5113495bSYour Name 
788*5113495bSYour Name 	target_if_fill_timer(&params, t2lm);
789*5113495bSYour Name 	t2lm_debug("mapping_switch_time_present %d MST %d",
790*5113495bSYour Name 		   t2lm->mapping_switch_time_present,
791*5113495bSYour Name 		   params.mapping_switch_time);
792*5113495bSYour Name 	t2lm_debug("expected_switch_time_present %d EDT %d",
793*5113495bSYour Name 		   t2lm->expected_duration_present,
794*5113495bSYour Name 		   params.expected_duration);
795*5113495bSYour Name 
796*5113495bSYour Name 	t2lm_debug("num_dir:%d direction:%d default_link_mapping:%d",
797*5113495bSYour Name 		   params.num_dir, params.t2lm_info[params.num_dir].direction,
798*5113495bSYour Name 		   params.t2lm_info[params.num_dir].default_link_mapping);
799*5113495bSYour Name 
800*5113495bSYour Name 	for (tid = 0; tid < T2LM_MAX_NUM_TIDS; tid++) {
801*5113495bSYour Name 		t2lm_debug("tid:%d hw_link_map:%x ieee_link_map:%x", tid,
802*5113495bSYour Name 			   params.t2lm_info[params.num_dir].t2lm_provisioned_links[tid],
803*5113495bSYour Name 			   t2lm->ieee_link_map_tid[tid]);
804*5113495bSYour Name 	}
805*5113495bSYour Name 
806*5113495bSYour Name 	params.num_dir++;
807*5113495bSYour Name 
808*5113495bSYour Name 	status = wmi_send_mlo_peer_tid_to_link_map_cmd(wmi_handle, &params, true);
809*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
810*5113495bSYour Name 		t2lm_err("Failed to send T2LM WMI command for pdev_id:%d peer_mac: " QDF_MAC_ADDR_FMT,
811*5113495bSYour Name 			 params.pdev_id,
812*5113495bSYour Name 			 QDF_MAC_ADDR_REF(params.peer_macaddr));
813*5113495bSYour Name 		return status;
814*5113495bSYour Name 	}
815*5113495bSYour Name 
816*5113495bSYour Name 	return status;
817*5113495bSYour Name }
818*5113495bSYour Name 
819*5113495bSYour Name static QDF_STATUS
target_if_request_ml_link_state_info(struct wlan_objmgr_psoc * psoc,struct mlo_link_state_cmd_params * cmd)820*5113495bSYour Name target_if_request_ml_link_state_info(struct wlan_objmgr_psoc *psoc,
821*5113495bSYour Name 				     struct mlo_link_state_cmd_params *cmd)
822*5113495bSYour Name {
823*5113495bSYour Name 	struct wmi_unified *wmi_handle = NULL;
824*5113495bSYour Name 	struct wmi_host_link_state_params params = {0};
825*5113495bSYour Name 	QDF_STATUS status;
826*5113495bSYour Name 
827*5113495bSYour Name 	if (!psoc) {
828*5113495bSYour Name 		target_if_err("null pdev");
829*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
830*5113495bSYour Name 	}
831*5113495bSYour Name 
832*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
833*5113495bSYour Name 	if (!wmi_handle) {
834*5113495bSYour Name 		target_if_err("null wmi handle");
835*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
836*5113495bSYour Name 	}
837*5113495bSYour Name 
838*5113495bSYour Name 	if (!cmd) {
839*5113495bSYour Name 		target_if_err("cmd is null");
840*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
841*5113495bSYour Name 	}
842*5113495bSYour Name 
843*5113495bSYour Name 	params.vdev_id = cmd->vdev_id;
844*5113495bSYour Name 	qdf_mem_copy(params.mld_mac, cmd->mld_mac,
845*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
846*5113495bSYour Name 
847*5113495bSYour Name 	status = wmi_send_mlo_link_state_request_cmd(wmi_handle, &params);
848*5113495bSYour Name 	return status;
849*5113495bSYour Name }
850*5113495bSYour Name 
851*5113495bSYour Name #ifdef WLAN_WSI_STATS_SUPPORT
852*5113495bSYour Name static QDF_STATUS
target_if_mlo_send_wsi_link_info_cmd(struct wlan_objmgr_pdev * pdev,struct mlo_wsi_link_stats * param)853*5113495bSYour Name target_if_mlo_send_wsi_link_info_cmd(struct wlan_objmgr_pdev *pdev,
854*5113495bSYour Name 				     struct mlo_wsi_link_stats *param)
855*5113495bSYour Name {
856*5113495bSYour Name 	struct wmi_unified *wmi_handle;
857*5113495bSYour Name 	struct wmi_wsi_stats_info_params params = {0};
858*5113495bSYour Name 
859*5113495bSYour Name 	if (!pdev) {
860*5113495bSYour Name 		target_if_err("null pdev");
861*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
862*5113495bSYour Name 	}
863*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
864*5113495bSYour Name 	if (!wmi_handle) {
865*5113495bSYour Name 		target_if_err("null handle");
866*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
867*5113495bSYour Name 	}
868*5113495bSYour Name 
869*5113495bSYour Name 	params.pdev_id = pdev->pdev_objmgr.wlan_pdev_id;
870*5113495bSYour Name 	params.wsi_ingress_load_info = param->ingress_cnt;
871*5113495bSYour Name 	params.wsi_egress_load_info = param->egress_cnt;
872*5113495bSYour Name 
873*5113495bSYour Name 	target_if_debug("pdev id %d, ingress %d, egress %d", params.pdev_id,
874*5113495bSYour Name 			params.wsi_ingress_load_info,
875*5113495bSYour Name 			params.wsi_egress_load_info);
876*5113495bSYour Name 
877*5113495bSYour Name 	return wmi_unified_config_wsi_stats_info_cmd_send(wmi_handle, &params);
878*5113495bSYour Name }
879*5113495bSYour Name #else
880*5113495bSYour Name static QDF_STATUS
target_if_mlo_send_wsi_link_info_cmd(struct wlan_objmgr_pdev * pdev,struct mlo_wsi_link_stats * param)881*5113495bSYour Name target_if_mlo_send_wsi_link_info_cmd(struct wlan_objmgr_pdev *pdev,
882*5113495bSYour Name 				     struct mlo_wsi_link_stats *param)
883*5113495bSYour Name {
884*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
885*5113495bSYour Name }
886*5113495bSYour Name #endif
887*5113495bSYour Name static QDF_STATUS
target_if_send_link_set_bss_params_cmd(struct wlan_objmgr_psoc * psoc,struct mlo_link_bss_params * cmd)888*5113495bSYour Name target_if_send_link_set_bss_params_cmd(struct wlan_objmgr_psoc *psoc,
889*5113495bSYour Name 				       struct mlo_link_bss_params *cmd)
890*5113495bSYour Name {
891*5113495bSYour Name 	QDF_STATUS status;
892*5113495bSYour Name 	struct wmi_unified *wmi_handle = NULL;
893*5113495bSYour Name 	struct wmi_host_link_bss_params params = {0};
894*5113495bSYour Name 
895*5113495bSYour Name 	if (!psoc) {
896*5113495bSYour Name 		target_if_err("null pdev");
897*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
898*5113495bSYour Name 	}
899*5113495bSYour Name 
900*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
901*5113495bSYour Name 	if (!wmi_handle) {
902*5113495bSYour Name 		target_if_err("null wmi handle");
903*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
904*5113495bSYour Name 	}
905*5113495bSYour Name 	if (!cmd) {
906*5113495bSYour Name 		target_if_err("cmd is null");
907*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
908*5113495bSYour Name 	}
909*5113495bSYour Name 	params.link_id = cmd->link_id;
910*5113495bSYour Name 	qdf_mem_copy(&params.ap_mld_mac[0], &cmd->ap_mld_mac[0],
911*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
912*5113495bSYour Name 
913*5113495bSYour Name 	params.chan.ch_freq = cmd->chan->ch_freq;
914*5113495bSYour Name 	params.chan.ch_cfreq1 = cmd->chan->ch_cfreq1;
915*5113495bSYour Name 	params.chan.ch_cfreq2 = cmd->chan->ch_cfreq2;
916*5113495bSYour Name 	params.chan.ch_phymode  = cmd->chan->ch_phymode;
917*5113495bSYour Name 
918*5113495bSYour Name 	status = wmi_send_link_set_bss_params_cmd(wmi_handle, &params);
919*5113495bSYour Name 
920*5113495bSYour Name 	return status;
921*5113495bSYour Name }
922*5113495bSYour Name 
target_if_mlo_send_link_removal_cmd(struct wlan_objmgr_psoc * psoc,const struct mlo_link_removal_cmd_params * param)923*5113495bSYour Name QDF_STATUS target_if_mlo_send_link_removal_cmd(
924*5113495bSYour Name 		struct wlan_objmgr_psoc *psoc,
925*5113495bSYour Name 		const struct mlo_link_removal_cmd_params *param)
926*5113495bSYour Name {
927*5113495bSYour Name 	struct wmi_unified *wmi_handle;
928*5113495bSYour Name 
929*5113495bSYour Name 	if (!psoc) {
930*5113495bSYour Name 		target_if_err("null psoc");
931*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
932*5113495bSYour Name 	}
933*5113495bSYour Name 
934*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
935*5113495bSYour Name 	if (!wmi_handle) {
936*5113495bSYour Name 		target_if_err("null handle");
937*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
938*5113495bSYour Name 	}
939*5113495bSYour Name 
940*5113495bSYour Name 	return wmi_send_mlo_link_removal_cmd(wmi_handle, param);
941*5113495bSYour Name }
942*5113495bSYour Name 
target_if_mlo_send_vdev_pause(struct wlan_objmgr_psoc * psoc,struct mlo_vdev_pause * info)943*5113495bSYour Name QDF_STATUS target_if_mlo_send_vdev_pause(struct wlan_objmgr_psoc *psoc,
944*5113495bSYour Name 					 struct mlo_vdev_pause *info)
945*5113495bSYour Name {
946*5113495bSYour Name 	struct wmi_unified *wmi_handle;
947*5113495bSYour Name 
948*5113495bSYour Name 	if (!psoc) {
949*5113495bSYour Name 		target_if_err("null psoc");
950*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
951*5113495bSYour Name 	}
952*5113495bSYour Name 
953*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
954*5113495bSYour Name 	if (!wmi_handle) {
955*5113495bSYour Name 		target_if_err("null handle");
956*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
957*5113495bSYour Name 	}
958*5113495bSYour Name 
959*5113495bSYour Name 	return wmi_send_mlo_vdev_pause(wmi_handle, info);
960*5113495bSYour Name }
961*5113495bSYour Name 
962*5113495bSYour Name #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE
target_if_mlo_send_peer_ptqm_migrate_cmd(struct wlan_objmgr_vdev * vdev,struct peer_ptqm_migrate_params * param)963*5113495bSYour Name static QDF_STATUS target_if_mlo_send_peer_ptqm_migrate_cmd(
964*5113495bSYour Name 					struct wlan_objmgr_vdev *vdev,
965*5113495bSYour Name 					struct peer_ptqm_migrate_params *param)
966*5113495bSYour Name {
967*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = NULL;
968*5113495bSYour Name 	struct wmi_unified *wmi_handle;
969*5113495bSYour Name 	QDF_STATUS status;
970*5113495bSYour Name 
971*5113495bSYour Name 	if (!vdev || !param) {
972*5113495bSYour Name 		target_if_err("Invalid input");
973*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
974*5113495bSYour Name 	}
975*5113495bSYour Name 
976*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
977*5113495bSYour Name 	if (!pdev) {
978*5113495bSYour Name 		target_if_err("null pdev");
979*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
980*5113495bSYour Name 	}
981*5113495bSYour Name 
982*5113495bSYour Name 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
983*5113495bSYour Name 	if (!wmi_handle) {
984*5113495bSYour Name 		target_if_err("Failed to get WMI handle!");
985*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
986*5113495bSYour Name 	}
987*5113495bSYour Name 
988*5113495bSYour Name 	status = wmi_unified_peer_ptqm_migrate_send(wmi_handle, param);
989*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
990*5113495bSYour Name 		target_if_err("Failed to send peer ptqm migration WMI");
991*5113495bSYour Name 
992*5113495bSYour Name 	return status;
993*5113495bSYour Name }
994*5113495bSYour Name 
target_if_mlo_register_peer_ptqm_migrate_send(struct wlan_lmac_if_mlo_tx_ops * mlo_tx_ops)995*5113495bSYour Name static void target_if_mlo_register_peer_ptqm_migrate_send(
996*5113495bSYour Name 		struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops)
997*5113495bSYour Name {
998*5113495bSYour Name 	mlo_tx_ops->peer_ptqm_migrate_send =
999*5113495bSYour Name 				target_if_mlo_send_peer_ptqm_migrate_cmd;
1000*5113495bSYour Name }
1001*5113495bSYour Name #else
target_if_mlo_register_peer_ptqm_migrate_send(struct wlan_lmac_if_mlo_tx_ops * mlo_tx_ops)1002*5113495bSYour Name static void target_if_mlo_register_peer_ptqm_migrate_send(
1003*5113495bSYour Name 		struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops)
1004*5113495bSYour Name {
1005*5113495bSYour Name }
1006*5113495bSYour Name #endif
1007*5113495bSYour Name 
1008*5113495bSYour Name /**
1009*5113495bSYour Name  * target_if_mlo_register_tx_ops() - lmac handler to register mlo tx ops
1010*5113495bSYour Name  *  callback functions
1011*5113495bSYour Name  * @tx_ops: wlan_lmac_if_tx_ops object
1012*5113495bSYour Name  *
1013*5113495bSYour Name  * Return: QDF_STATUS
1014*5113495bSYour Name  */
1015*5113495bSYour Name QDF_STATUS
target_if_mlo_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)1016*5113495bSYour Name target_if_mlo_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
1017*5113495bSYour Name {
1018*5113495bSYour Name 	struct wlan_lmac_if_mlo_tx_ops *mlo_tx_ops;
1019*5113495bSYour Name 
1020*5113495bSYour Name 	if (!tx_ops) {
1021*5113495bSYour Name 		target_if_err("lmac tx ops is NULL!");
1022*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1023*5113495bSYour Name 	}
1024*5113495bSYour Name 
1025*5113495bSYour Name 	mlo_tx_ops = &tx_ops->mlo_ops;
1026*5113495bSYour Name 	if (!mlo_tx_ops) {
1027*5113495bSYour Name 		target_if_err("lmac tx ops is NULL!");
1028*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1029*5113495bSYour Name 	}
1030*5113495bSYour Name 
1031*5113495bSYour Name 	mlo_tx_ops->register_events =
1032*5113495bSYour Name 		target_if_mlo_register_event_handler;
1033*5113495bSYour Name 	mlo_tx_ops->unregister_events =
1034*5113495bSYour Name 		target_if_mlo_unregister_event_handler;
1035*5113495bSYour Name 	mlo_tx_ops->link_set_active = target_if_mlo_link_set_active;
1036*5113495bSYour Name 	mlo_tx_ops->send_tid_to_link_mapping =
1037*5113495bSYour Name 		target_if_mlo_send_tid_to_link_mapping;
1038*5113495bSYour Name 	mlo_tx_ops->send_link_removal_cmd = target_if_mlo_send_link_removal_cmd;
1039*5113495bSYour Name 	mlo_tx_ops->request_link_state_info_cmd =
1040*5113495bSYour Name 		target_if_request_ml_link_state_info;
1041*5113495bSYour Name 	mlo_tx_ops->send_link_set_bss_params_cmd =
1042*5113495bSYour Name 		target_if_send_link_set_bss_params_cmd;
1043*5113495bSYour Name 	mlo_tx_ops->send_vdev_pause = target_if_mlo_send_vdev_pause;
1044*5113495bSYour Name 
1045*5113495bSYour Name 	target_if_mlo_register_link_switch_cnf_handler(mlo_tx_ops);
1046*5113495bSYour Name 
1047*5113495bSYour Name 	mlo_tx_ops->send_wsi_link_info_cmd =
1048*5113495bSYour Name 		target_if_mlo_send_wsi_link_info_cmd;
1049*5113495bSYour Name 
1050*5113495bSYour Name 	target_if_mlo_register_peer_ptqm_migrate_send(mlo_tx_ops);
1051*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1052*5113495bSYour Name }
1053*5113495bSYour Name 
1054