xref: /wlan-driver/qcacld-3.0/components/target_if/coex/src/target_if_coex.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name /**
19*5113495bSYour Name  * DOC: contains coex target if functions
20*5113495bSYour Name  */
21*5113495bSYour Name #include <wlan_coex_main.h>
22*5113495bSYour Name #include <target_if_coex.h>
23*5113495bSYour Name #include "wlan_coex_public_structs.h"
24*5113495bSYour Name 
25*5113495bSYour Name /**
26*5113495bSYour Name  * target_if_coex_config_send() - Function to send coex config command
27*5113495bSYour Name  * @pdev: PDEV object
28*5113495bSYour Name  * @param: Pointer to coex config parameters
29*5113495bSYour Name  *
30*5113495bSYour Name  * Return: QDF STATUS
31*5113495bSYour Name  */
32*5113495bSYour Name static QDF_STATUS
target_if_coex_config_send(struct wlan_objmgr_pdev * pdev,struct coex_config_params * param)33*5113495bSYour Name target_if_coex_config_send(struct wlan_objmgr_pdev *pdev,
34*5113495bSYour Name 			   struct coex_config_params *param)
35*5113495bSYour Name {
36*5113495bSYour Name 	wmi_unified_t pdev_wmi_handle;
37*5113495bSYour Name 
38*5113495bSYour Name 	pdev_wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
39*5113495bSYour Name 	if (!pdev_wmi_handle) {
40*5113495bSYour Name 		coex_err("Invalid PDEV WMI handle");
41*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
42*5113495bSYour Name 	}
43*5113495bSYour Name 
44*5113495bSYour Name 	return wmi_unified_send_coex_config_cmd(pdev_wmi_handle, param);
45*5113495bSYour Name }
46*5113495bSYour Name 
47*5113495bSYour Name /**
48*5113495bSYour Name  * target_if_coex_multi_config_send() - Function to send coex multiple config
49*5113495bSYour Name  * command
50*5113495bSYour Name  * @pdev: PDEV object
51*5113495bSYour Name  * @param: Pointer to coex multiple config parameters
52*5113495bSYour Name  *
53*5113495bSYour Name  * Return: QDF STATUS
54*5113495bSYour Name  */
55*5113495bSYour Name static QDF_STATUS
target_if_coex_multi_config_send(struct wlan_objmgr_pdev * pdev,struct coex_multi_config * param)56*5113495bSYour Name target_if_coex_multi_config_send(struct wlan_objmgr_pdev *pdev,
57*5113495bSYour Name 				 struct coex_multi_config *param)
58*5113495bSYour Name {
59*5113495bSYour Name 	wmi_unified_t pdev_wmi_handle;
60*5113495bSYour Name 
61*5113495bSYour Name 	pdev_wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
62*5113495bSYour Name 	if (!pdev_wmi_handle) {
63*5113495bSYour Name 		coex_err("Invalid PDEV WMI handle");
64*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
65*5113495bSYour Name 	}
66*5113495bSYour Name 
67*5113495bSYour Name 	return wmi_unified_send_coex_multi_config_cmd(pdev_wmi_handle, param);
68*5113495bSYour Name }
69*5113495bSYour Name 
70*5113495bSYour Name /**
71*5113495bSYour Name  * target_if_coex_get_multi_config_support() - Function to get coex multiple
72*5113495bSYour Name  * config command support
73*5113495bSYour Name  * @psoc: PSOC object
74*5113495bSYour Name  *
75*5113495bSYour Name  * Return: true if target support coex multiple config command
76*5113495bSYour Name  */
77*5113495bSYour Name static bool
target_if_coex_get_multi_config_support(struct wlan_objmgr_psoc * psoc)78*5113495bSYour Name target_if_coex_get_multi_config_support(struct wlan_objmgr_psoc *psoc)
79*5113495bSYour Name {
80*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
81*5113495bSYour Name 
82*5113495bSYour Name 	if (!wmi_handle) {
83*5113495bSYour Name 		target_if_err("Invalid wmi handle");
84*5113495bSYour Name 		return false;
85*5113495bSYour Name 	}
86*5113495bSYour Name 
87*5113495bSYour Name 	return wmi_service_enabled(wmi_handle,
88*5113495bSYour Name 				   wmi_service_multiple_coex_config_support);
89*5113495bSYour Name }
90*5113495bSYour Name 
91*5113495bSYour Name QDF_STATUS
target_if_coex_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)92*5113495bSYour Name target_if_coex_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
93*5113495bSYour Name {
94*5113495bSYour Name 	struct wlan_lmac_if_coex_tx_ops *coex_ops;
95*5113495bSYour Name 
96*5113495bSYour Name 	if (!tx_ops) {
97*5113495bSYour Name 		coex_err("target if tx ops is NULL!");
98*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
99*5113495bSYour Name 	}
100*5113495bSYour Name 
101*5113495bSYour Name 	coex_ops = &tx_ops->coex_ops;
102*5113495bSYour Name 	coex_ops->coex_config_send = target_if_coex_config_send;
103*5113495bSYour Name 	coex_ops->coex_multi_config_send = target_if_coex_multi_config_send;
104*5113495bSYour Name 	coex_ops->coex_get_multi_config_support =
105*5113495bSYour Name 				target_if_coex_get_multi_config_support;
106*5113495bSYour Name 
107*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
108*5113495bSYour Name }
109*5113495bSYour Name 
110*5113495bSYour Name #ifdef WLAN_FEATURE_DBAM_CONFIG
111*5113495bSYour Name QDF_STATUS
target_if_dbam_process_event(struct wlan_objmgr_psoc * psoc,enum coex_dbam_comp_status resp)112*5113495bSYour Name target_if_dbam_process_event(struct wlan_objmgr_psoc *psoc,
113*5113495bSYour Name 			     enum coex_dbam_comp_status resp)
114*5113495bSYour Name {
115*5113495bSYour Name 	struct coex_psoc_obj *coex_obj;
116*5113495bSYour Name 	struct wlan_coex_callback *cb;
117*5113495bSYour Name 
118*5113495bSYour Name 	if (!psoc) {
119*5113495bSYour Name 		coex_err("psoc is null");
120*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
121*5113495bSYour Name 	}
122*5113495bSYour Name 
123*5113495bSYour Name 	coex_obj = wlan_psoc_get_coex_obj(psoc);
124*5113495bSYour Name 	if (!coex_obj) {
125*5113495bSYour Name 		coex_err("failed to get coex_obj");
126*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
127*5113495bSYour Name 	}
128*5113495bSYour Name 
129*5113495bSYour Name 	cb = &coex_obj->cb;
130*5113495bSYour Name 	if (cb->set_dbam_config_cb)
131*5113495bSYour Name 		cb->set_dbam_config_cb(cb->set_dbam_config_ctx, &resp);
132*5113495bSYour Name 
133*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
134*5113495bSYour Name }
135*5113495bSYour Name 
136*5113495bSYour Name /**
137*5113495bSYour Name  * target_if_dbam_response_event_handler() - function to handle dbam response
138*5113495bSYour Name  * event from firmware.
139*5113495bSYour Name  * @scn: scn handle
140*5113495bSYour Name  * @data: data buffer foe the event
141*5113495bSYour Name  * @len: data length
142*5113495bSYour Name  *
143*5113495bSYour Name  * Return: 0 on success, and error code on failure
144*5113495bSYour Name  */
target_if_dbam_response_event_handler(ol_scn_t scn,uint8_t * data,uint32_t len)145*5113495bSYour Name static int target_if_dbam_response_event_handler(ol_scn_t scn,
146*5113495bSYour Name 						 uint8_t *data,
147*5113495bSYour Name 						 uint32_t len)
148*5113495bSYour Name {
149*5113495bSYour Name 	QDF_STATUS status;
150*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
151*5113495bSYour Name 	wmi_unified_t wmi_handle;
152*5113495bSYour Name 	struct wlan_lmac_if_dbam_rx_ops *rx_ops;
153*5113495bSYour Name 	struct coex_dbam_config_resp resp = {0};
154*5113495bSYour Name 
155*5113495bSYour Name 	target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, data, len);
156*5113495bSYour Name 	if (!scn || !data) {
157*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
158*5113495bSYour Name 		return -EINVAL;
159*5113495bSYour Name 	}
160*5113495bSYour Name 
161*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
162*5113495bSYour Name 	if (!psoc) {
163*5113495bSYour Name 		target_if_err("psoc is Null");
164*5113495bSYour Name 		return -EINVAL;
165*5113495bSYour Name 	}
166*5113495bSYour Name 
167*5113495bSYour Name 	rx_ops = wlan_psoc_get_dbam_rx_ops(psoc);
168*5113495bSYour Name 	if (!rx_ops || !rx_ops->dbam_resp_event) {
169*5113495bSYour Name 		target_if_err("callback not registered");
170*5113495bSYour Name 		return -EINVAL;
171*5113495bSYour Name 	}
172*5113495bSYour Name 
173*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
174*5113495bSYour Name 	if (!wmi_handle) {
175*5113495bSYour Name 		target_if_err("wmi_handle is null");
176*5113495bSYour Name 		return -EINVAL;
177*5113495bSYour Name 	}
178*5113495bSYour Name 
179*5113495bSYour Name 	status = wmi_extract_dbam_config_response(wmi_handle, data, &resp);
180*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
181*5113495bSYour Name 		target_if_err("Failed to extract dbam config response");
182*5113495bSYour Name 		return -EINVAL;
183*5113495bSYour Name 	}
184*5113495bSYour Name 
185*5113495bSYour Name 	status = rx_ops->dbam_resp_event(psoc, resp.dbam_resp);
186*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
187*5113495bSYour Name 		target_if_err("process dbam response event failed");
188*5113495bSYour Name 		return -EINVAL;
189*5113495bSYour Name 	}
190*5113495bSYour Name 
191*5113495bSYour Name 	return 0;
192*5113495bSYour Name }
193*5113495bSYour Name 
194*5113495bSYour Name /**
195*5113495bSYour Name  * target_if_dbam_config_send() - Send WMI command for DBAM configuration
196*5113495bSYour Name  * @psoc: psoc pointer
197*5113495bSYour Name  * @param: dbam config parameters
198*5113495bSYour Name  *
199*5113495bSYour Name  * Return: QDF_STATUS
200*5113495bSYour Name  */
201*5113495bSYour Name static QDF_STATUS
target_if_dbam_config_send(struct wlan_objmgr_psoc * psoc,struct coex_dbam_config_params * param)202*5113495bSYour Name target_if_dbam_config_send(struct wlan_objmgr_psoc *psoc,
203*5113495bSYour Name 			   struct coex_dbam_config_params *param)
204*5113495bSYour Name {
205*5113495bSYour Name 	QDF_STATUS status;
206*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
207*5113495bSYour Name 
208*5113495bSYour Name 	if (!wmi_handle) {
209*5113495bSYour Name 		target_if_err("Invalid WMI handle");
210*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
211*5113495bSYour Name 	}
212*5113495bSYour Name 
213*5113495bSYour Name 	status = wmi_unified_send_dbam_config_cmd(wmi_handle, param);
214*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
215*5113495bSYour Name 		target_if_err("Failed to send DBAM config %d", status);
216*5113495bSYour Name 
217*5113495bSYour Name 	return status;
218*5113495bSYour Name }
219*5113495bSYour Name 
220*5113495bSYour Name static QDF_STATUS
target_if_dbam_register_event_handler(struct wlan_objmgr_psoc * psoc)221*5113495bSYour Name target_if_dbam_register_event_handler(struct wlan_objmgr_psoc *psoc)
222*5113495bSYour Name {
223*5113495bSYour Name 	QDF_STATUS status;
224*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
225*5113495bSYour Name 
226*5113495bSYour Name 	if (!wmi_handle) {
227*5113495bSYour Name 		target_if_err("Invalid WMI handle");
228*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
229*5113495bSYour Name 	}
230*5113495bSYour Name 
231*5113495bSYour Name 	status = wmi_unified_register_event_handler(wmi_handle,
232*5113495bSYour Name 					wmi_coex_dbam_complete_event_id,
233*5113495bSYour Name 					target_if_dbam_response_event_handler,
234*5113495bSYour Name 					WMI_RX_WORK_CTX);
235*5113495bSYour Name 
236*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
237*5113495bSYour Name 		target_if_err("Failed to register dbam complete event cb");
238*5113495bSYour Name 
239*5113495bSYour Name 	return status;
240*5113495bSYour Name }
241*5113495bSYour Name 
242*5113495bSYour Name static QDF_STATUS
target_if_dbam_unregister_event_handler(struct wlan_objmgr_psoc * psoc)243*5113495bSYour Name target_if_dbam_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
244*5113495bSYour Name {
245*5113495bSYour Name 	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
246*5113495bSYour Name 
247*5113495bSYour Name 	if (!wmi_handle) {
248*5113495bSYour Name 		target_if_err("Invalid WMI handle");
249*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
250*5113495bSYour Name 	}
251*5113495bSYour Name 
252*5113495bSYour Name 	wmi_unified_unregister_event_handler(wmi_handle,
253*5113495bSYour Name 					     wmi_coex_dbam_complete_event_id);
254*5113495bSYour Name 
255*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
256*5113495bSYour Name }
257*5113495bSYour Name 
258*5113495bSYour Name QDF_STATUS
target_if_dbam_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)259*5113495bSYour Name target_if_dbam_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
260*5113495bSYour Name {
261*5113495bSYour Name 	struct wlan_lmac_if_dbam_tx_ops *dbam_tx_ops;
262*5113495bSYour Name 
263*5113495bSYour Name 	if (!tx_ops) {
264*5113495bSYour Name 		target_if_err("target if tx ops is NULL!");
265*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
266*5113495bSYour Name 	}
267*5113495bSYour Name 
268*5113495bSYour Name 	dbam_tx_ops = &tx_ops->dbam_tx_ops;
269*5113495bSYour Name 	if (!dbam_tx_ops) {
270*5113495bSYour Name 		target_if_err("target if dbam ops is NULL!");
271*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
272*5113495bSYour Name 	}
273*5113495bSYour Name 
274*5113495bSYour Name 	dbam_tx_ops->set_dbam_config = target_if_dbam_config_send;
275*5113495bSYour Name 	dbam_tx_ops->dbam_event_attach = target_if_dbam_register_event_handler;
276*5113495bSYour Name 	dbam_tx_ops->dbam_event_detach =
277*5113495bSYour Name 		target_if_dbam_unregister_event_handler;
278*5113495bSYour Name 
279*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
280*5113495bSYour Name }
281*5113495bSYour Name #endif
282