xref: /wlan-driver/qca-wifi-host-cmn/target_if/dcs/src/target_if_dcs.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2020-2021, The Linux Foundation. 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_dcs.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_api.h>
24*5113495bSYour Name #include <wmi_unified_priv.h>
25*5113495bSYour Name #include <wmi_unified_dcs_api.h>
26*5113495bSYour Name #include <init_deinit_lmac.h>
27*5113495bSYour Name #include "wlan_dcs_tgt_api.h"
28*5113495bSYour Name #include "target_if_dcs.h"
29*5113495bSYour Name 
30*5113495bSYour Name /**
31*5113495bSYour Name  * target_if_dcs_interference_event_handler() - function to handle dcs event
32*5113495bSYour Name  * from firmware.
33*5113495bSYour Name  * @scn: scn handle
34*5113495bSYour Name  * @data: data buffer for event
35*5113495bSYour Name  * @datalen: data length
36*5113495bSYour Name  *
37*5113495bSYour Name  * Return: status of operation.
38*5113495bSYour Name  */
target_if_dcs_interference_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)39*5113495bSYour Name static int target_if_dcs_interference_event_handler(ol_scn_t scn,
40*5113495bSYour Name 						    uint8_t *data,
41*5113495bSYour Name 						    uint32_t datalen)
42*5113495bSYour Name {
43*5113495bSYour Name 	QDF_STATUS status;
44*5113495bSYour Name 	struct wlan_host_dcs_event ev;
45*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
46*5113495bSYour Name 	struct wmi_unified *wmi_handle;
47*5113495bSYour Name 	struct wlan_target_if_dcs_rx_ops *rx_ops;
48*5113495bSYour Name 
49*5113495bSYour Name 	if (!scn || !data) {
50*5113495bSYour Name 		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
51*5113495bSYour Name 		return -EINVAL;
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_dcs_get_rx_ops(psoc);
60*5113495bSYour Name 	if (!rx_ops || !rx_ops->process_dcs_event) {
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 
71*5113495bSYour Name 	if (wmi_extract_dcs_interference_type(wmi_handle, data,
72*5113495bSYour Name 					      &ev.dcs_param) !=
73*5113495bSYour Name 	    QDF_STATUS_SUCCESS) {
74*5113495bSYour Name 		target_if_err("Unable to extract dcs interference type");
75*5113495bSYour Name 		return -EINVAL;
76*5113495bSYour Name 	}
77*5113495bSYour Name 
78*5113495bSYour Name 	if (ev.dcs_param.interference_type == WLAN_HOST_DCS_WLANIM &&
79*5113495bSYour Name 	    wmi_extract_dcs_im_tgt_stats(wmi_handle, data, &ev.wlan_stat) !=
80*5113495bSYour Name 	    QDF_STATUS_SUCCESS) {
81*5113495bSYour Name 		target_if_err("Unable to extract WLAN IM stats");
82*5113495bSYour Name 		return -EINVAL;
83*5113495bSYour Name 	}
84*5113495bSYour Name 
85*5113495bSYour Name 	if (ev.dcs_param.interference_type == WLAN_HOST_DCS_AWGNIM &&
86*5113495bSYour Name 	    wmi_extract_dcs_awgn_info(wmi_handle, data, &ev.awgn_info) !=
87*5113495bSYour Name 	    QDF_STATUS_SUCCESS) {
88*5113495bSYour Name 		target_if_err("Unable to extract AWGN info");
89*5113495bSYour Name 		return -EINVAL;
90*5113495bSYour Name 	}
91*5113495bSYour Name 
92*5113495bSYour Name 	status = rx_ops->process_dcs_event(psoc, &ev);
93*5113495bSYour Name 
94*5113495bSYour Name 	return qdf_status_to_os_return(status);
95*5113495bSYour Name }
96*5113495bSYour Name 
97*5113495bSYour Name static QDF_STATUS
target_if_dcs_register_event_handler(struct wlan_objmgr_psoc * psoc)98*5113495bSYour Name target_if_dcs_register_event_handler(struct wlan_objmgr_psoc *psoc)
99*5113495bSYour Name {
100*5113495bSYour Name 	QDF_STATUS ret_val;
101*5113495bSYour Name 	struct wmi_unified *wmi_handle;
102*5113495bSYour Name 
103*5113495bSYour Name 	if (!psoc) {
104*5113495bSYour Name 		target_if_err("PSOC is NULL!");
105*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
106*5113495bSYour Name 	}
107*5113495bSYour Name 
108*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
109*5113495bSYour Name 	if (!wmi_handle) {
110*5113495bSYour Name 		target_if_err("wmi_handle is null");
111*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
112*5113495bSYour Name 	}
113*5113495bSYour Name 
114*5113495bSYour Name 	ret_val = wmi_unified_register_event_handler(
115*5113495bSYour Name 			wmi_handle,
116*5113495bSYour Name 			wmi_dcs_interference_event_id,
117*5113495bSYour Name 			target_if_dcs_interference_event_handler,
118*5113495bSYour Name 			WMI_RX_WORK_CTX);
119*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret_val))
120*5113495bSYour Name 		target_if_err("Failed to register dcs interference event cb");
121*5113495bSYour Name 
122*5113495bSYour Name 	return ret_val;
123*5113495bSYour Name }
124*5113495bSYour Name 
125*5113495bSYour Name static QDF_STATUS
target_if_dcs_unregister_event_handler(struct wlan_objmgr_psoc * psoc)126*5113495bSYour Name target_if_dcs_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
127*5113495bSYour Name {
128*5113495bSYour Name 	struct wmi_unified *wmi_handle;
129*5113495bSYour Name 
130*5113495bSYour Name 	if (!psoc) {
131*5113495bSYour Name 		target_if_err("PSOC is NULL!");
132*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
133*5113495bSYour Name 	}
134*5113495bSYour Name 
135*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
136*5113495bSYour Name 	if (!wmi_handle) {
137*5113495bSYour Name 		target_if_err("wmi_handle is null");
138*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
139*5113495bSYour Name 	}
140*5113495bSYour Name 	wmi_unified_unregister_event_handler(wmi_handle,
141*5113495bSYour Name 					     wmi_dcs_interference_event_id);
142*5113495bSYour Name 
143*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
144*5113495bSYour Name }
145*5113495bSYour Name 
146*5113495bSYour Name /**
147*5113495bSYour Name  * target_if_dcs_cmd_send() - Send WMI command for dcs requests
148*5113495bSYour Name  * @psoc: psoc pointer
149*5113495bSYour Name  * @pdev_id: pdev_id
150*5113495bSYour Name  * @is_host_pdev_id: pdev_id is host pdev_id or not
151*5113495bSYour Name  * @dcs_enable: dcs enable or not
152*5113495bSYour Name  *
153*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
154*5113495bSYour Name  */
155*5113495bSYour Name static QDF_STATUS
target_if_dcs_cmd_send(struct wlan_objmgr_psoc * psoc,uint32_t pdev_id,bool is_host_pdev_id,uint32_t dcs_enable)156*5113495bSYour Name target_if_dcs_cmd_send(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
157*5113495bSYour Name 		       bool is_host_pdev_id, uint32_t dcs_enable)
158*5113495bSYour Name {
159*5113495bSYour Name 	QDF_STATUS ret;
160*5113495bSYour Name 	struct wmi_unified *wmi_handle;
161*5113495bSYour Name 
162*5113495bSYour Name 	if (!psoc) {
163*5113495bSYour Name 		target_if_err("null psoc");
164*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
165*5113495bSYour Name 	}
166*5113495bSYour Name 
167*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
168*5113495bSYour Name 	if (!wmi_handle) {
169*5113495bSYour Name 		target_if_err("null handle");
170*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
171*5113495bSYour Name 	}
172*5113495bSYour Name 
173*5113495bSYour Name 	ret = wmi_send_dcs_pdev_param(wmi_handle, pdev_id,
174*5113495bSYour Name 				      is_host_pdev_id, dcs_enable);
175*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
176*5113495bSYour Name 		target_if_err("wmi dcs cmd send failed, ret: %d", ret);
177*5113495bSYour Name 
178*5113495bSYour Name 	return ret;
179*5113495bSYour Name }
180*5113495bSYour Name 
181*5113495bSYour Name QDF_STATUS
target_if_dcs_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)182*5113495bSYour Name target_if_dcs_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
183*5113495bSYour Name {
184*5113495bSYour Name 	struct wlan_target_if_dcs_tx_ops *dcs_tx_ops;
185*5113495bSYour Name 
186*5113495bSYour Name 	if (!tx_ops) {
187*5113495bSYour Name 		target_if_err("lmac tx ops is NULL!");
188*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
189*5113495bSYour Name 	}
190*5113495bSYour Name 
191*5113495bSYour Name 	dcs_tx_ops = &tx_ops->dcs_tx_ops;
192*5113495bSYour Name 	if (!dcs_tx_ops) {
193*5113495bSYour Name 		target_if_err("lmac tx ops is NULL!");
194*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
195*5113495bSYour Name 	}
196*5113495bSYour Name 
197*5113495bSYour Name 	dcs_tx_ops->dcs_attach =
198*5113495bSYour Name 		target_if_dcs_register_event_handler;
199*5113495bSYour Name 	dcs_tx_ops->dcs_detach =
200*5113495bSYour Name 		target_if_dcs_unregister_event_handler;
201*5113495bSYour Name 	dcs_tx_ops->dcs_cmd_send = target_if_dcs_cmd_send;
202*5113495bSYour Name 
203*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
204*5113495bSYour Name }
205*5113495bSYour Name 
206