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