1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name * above copyright notice and this permission notice appear in all
8*5113495bSYour Name * copies.
9*5113495bSYour Name *
10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name */
19*5113495bSYour Name
20*5113495bSYour Name /**
21*5113495bSYour Name * DOC: defines driver functions interfacing with linux kernel
22*5113495bSYour Name */
23*5113495bSYour Name
24*5113495bSYour Name #include <qdf_list.h>
25*5113495bSYour Name #include <qdf_status.h>
26*5113495bSYour Name #include <linux/wireless.h>
27*5113495bSYour Name #include <linux/netdevice.h>
28*5113495bSYour Name #include <net/cfg80211.h>
29*5113495bSYour Name #include <wlan_cfg80211.h>
30*5113495bSYour Name #include <wlan_osif_priv.h>
31*5113495bSYour Name #include <qdf_mem.h>
32*5113495bSYour Name #include <wlan_spectral_ucfg_api.h>
33*5113495bSYour Name #include <wlan_cfg80211_spectral.h>
34*5113495bSYour Name #include <spectral_ioctl.h>
35*5113495bSYour Name #include <wlan_objmgr_vdev_obj.h>
36*5113495bSYour Name #include "wlan_osif_features.h"
37*5113495bSYour Name
38*5113495bSYour Name const struct nla_policy spectral_scan_policy[
39*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + 1] = {
40*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT] = {
41*5113495bSYour Name .type = NLA_U32},
42*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD] = {
43*5113495bSYour Name .type = NLA_U32},
44*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY] = {
45*5113495bSYour Name .type = NLA_U32},
46*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE] = {
47*5113495bSYour Name .type = NLA_U32},
48*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA] = {
49*5113495bSYour Name .type = NLA_U32},
50*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA] = {
51*5113495bSYour Name .type = NLA_U32},
52*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF] = {
53*5113495bSYour Name .type = NLA_U32},
54*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY] = {
55*5113495bSYour Name .type = NLA_U32},
56*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR] = {
57*5113495bSYour Name .type = NLA_U32},
58*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR] = {
59*5113495bSYour Name .type = NLA_U32},
60*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE] = {
61*5113495bSYour Name .type = NLA_U32},
62*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE] = {
63*5113495bSYour Name .type = NLA_U32},
64*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR] = {
65*5113495bSYour Name .type = NLA_U32},
66*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT] = {
67*5113495bSYour Name .type = NLA_U32},
68*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE] = {
69*5113495bSYour Name .type = NLA_U32},
70*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE] = {
71*5113495bSYour Name .type = NLA_U32},
72*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ] = {
73*5113495bSYour Name .type = NLA_U32},
74*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK] = {
75*5113495bSYour Name .type = NLA_U32},
76*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE] = {
77*5113495bSYour Name .type = NLA_U32},
78*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE] = {
79*5113495bSYour Name .type = NLA_U64},
80*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD] = {
81*5113495bSYour Name .type = NLA_U32},
82*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT] = {
83*5113495bSYour Name .type = NLA_U32},
84*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL] = {
85*5113495bSYour Name .type = NLA_U32},
86*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY] = {
87*5113495bSYour Name .type = NLA_U32},
88*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2] = {
89*5113495bSYour Name .type = NLA_U32},
90*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE] = {
91*5113495bSYour Name .type = NLA_U32},
92*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG] = {
93*5113495bSYour Name .type = NLA_U8},
94*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG] = {
95*5113495bSYour Name .type = NLA_U8},
96*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH] = {
97*5113495bSYour Name .type = NLA_U8},
98*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_RECAPTURE] = {
99*5113495bSYour Name .type = NLA_U32},
100*5113495bSYour Name };
101*5113495bSYour Name
102*5113495bSYour Name const struct nla_policy spectral_scan_get_status_policy[
103*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MAX + 1] = {
104*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ENABLED] = {
105*5113495bSYour Name .type = NLA_FLAG },
106*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ACTIVE] = {
107*5113495bSYour Name .type = NLA_FLAG },
108*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE] = { .type = NLA_U32 },
109*5113495bSYour Name };
110*5113495bSYour Name
wlan_spectral_intit_config(struct spectral_config * config_req)111*5113495bSYour Name static void wlan_spectral_intit_config(struct spectral_config *config_req)
112*5113495bSYour Name {
113*5113495bSYour Name config_req->ss_period = SPECTRAL_PHYERR_PARAM_NOVAL;
114*5113495bSYour Name config_req->ss_recapture = SPECTRAL_PHYERR_PARAM_NOVAL;
115*5113495bSYour Name config_req->ss_count = SPECTRAL_PHYERR_PARAM_NOVAL;
116*5113495bSYour Name config_req->ss_fft_period = SPECTRAL_PHYERR_PARAM_NOVAL;
117*5113495bSYour Name config_req->ss_short_report = SPECTRAL_PHYERR_PARAM_NOVAL;
118*5113495bSYour Name config_req->ss_spectral_pri = SPECTRAL_PHYERR_PARAM_NOVAL;
119*5113495bSYour Name config_req->ss_fft_size = SPECTRAL_PHYERR_PARAM_NOVAL;
120*5113495bSYour Name config_req->ss_gc_ena = SPECTRAL_PHYERR_PARAM_NOVAL;
121*5113495bSYour Name config_req->ss_restart_ena = SPECTRAL_PHYERR_PARAM_NOVAL;
122*5113495bSYour Name config_req->ss_noise_floor_ref = SPECTRAL_PHYERR_PARAM_NOVAL;
123*5113495bSYour Name config_req->ss_init_delay = SPECTRAL_PHYERR_PARAM_NOVAL;
124*5113495bSYour Name config_req->ss_nb_tone_thr = SPECTRAL_PHYERR_PARAM_NOVAL;
125*5113495bSYour Name config_req->ss_str_bin_thr = SPECTRAL_PHYERR_PARAM_NOVAL;
126*5113495bSYour Name config_req->ss_wb_rpt_mode = SPECTRAL_PHYERR_PARAM_NOVAL;
127*5113495bSYour Name config_req->ss_rssi_rpt_mode = SPECTRAL_PHYERR_PARAM_NOVAL;
128*5113495bSYour Name config_req->ss_rssi_thr = SPECTRAL_PHYERR_PARAM_NOVAL;
129*5113495bSYour Name config_req->ss_pwr_format = SPECTRAL_PHYERR_PARAM_NOVAL;
130*5113495bSYour Name config_req->ss_rpt_mode = SPECTRAL_PHYERR_PARAM_NOVAL;
131*5113495bSYour Name config_req->ss_bin_scale = SPECTRAL_PHYERR_PARAM_NOVAL;
132*5113495bSYour Name config_req->ss_dbm_adj = SPECTRAL_PHYERR_PARAM_NOVAL;
133*5113495bSYour Name config_req->ss_chn_mask = SPECTRAL_PHYERR_PARAM_NOVAL;
134*5113495bSYour Name config_req->ss_frequency.cfreq1 = SPECTRAL_PHYERR_PARAM_NOVAL;
135*5113495bSYour Name config_req->ss_frequency.cfreq2 = SPECTRAL_PHYERR_PARAM_NOVAL;
136*5113495bSYour Name config_req->ss_bandwidth = SPECTRAL_PHYERR_PARAM_NOVAL;
137*5113495bSYour Name }
138*5113495bSYour Name
139*5113495bSYour Name /**
140*5113495bSYour Name * convert_spectral_mode_nl_to_internal() - Get Spectral mode
141*5113495bSYour Name * @nl_spectral_mode: Spectral mode in vendor attribute
142*5113495bSYour Name * @mode: Converted Spectral mode
143*5113495bSYour Name *
144*5113495bSYour Name * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE
145*5113495bSYour Name */
146*5113495bSYour Name static QDF_STATUS
convert_spectral_mode_nl_to_internal(enum qca_wlan_vendor_spectral_scan_mode nl_spectral_mode,enum spectral_scan_mode * mode)147*5113495bSYour Name convert_spectral_mode_nl_to_internal
148*5113495bSYour Name (enum qca_wlan_vendor_spectral_scan_mode nl_spectral_mode,
149*5113495bSYour Name enum spectral_scan_mode *mode)
150*5113495bSYour Name {
151*5113495bSYour Name switch (nl_spectral_mode) {
152*5113495bSYour Name case QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL:
153*5113495bSYour Name *mode = SPECTRAL_SCAN_MODE_NORMAL;
154*5113495bSYour Name break;
155*5113495bSYour Name
156*5113495bSYour Name case QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE:
157*5113495bSYour Name *mode = SPECTRAL_SCAN_MODE_AGILE;
158*5113495bSYour Name break;
159*5113495bSYour Name
160*5113495bSYour Name default:
161*5113495bSYour Name osif_err("Invalid spectral mode %u", nl_spectral_mode);
162*5113495bSYour Name return QDF_STATUS_E_FAILURE;
163*5113495bSYour Name }
164*5113495bSYour Name
165*5113495bSYour Name return QDF_STATUS_SUCCESS;
166*5113495bSYour Name }
167*5113495bSYour Name
168*5113495bSYour Name /**
169*5113495bSYour Name * convert_spectral_err_code_internal_to_nl() - Get Spectral error code
170*5113495bSYour Name * @spectral_err_code: Spectral error code used internally
171*5113495bSYour Name * @nl_err_code: Spectral error code for cfg80211
172*5113495bSYour Name *
173*5113495bSYour Name * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS_E_FAILURE
174*5113495bSYour Name */
175*5113495bSYour Name static QDF_STATUS
convert_spectral_err_code_internal_to_nl(enum spectral_cp_error_code spectral_err_code,enum qca_wlan_vendor_spectral_scan_error_code * nl_err_code)176*5113495bSYour Name convert_spectral_err_code_internal_to_nl
177*5113495bSYour Name (enum spectral_cp_error_code spectral_err_code,
178*5113495bSYour Name enum qca_wlan_vendor_spectral_scan_error_code *nl_err_code)
179*5113495bSYour Name {
180*5113495bSYour Name switch (spectral_err_code) {
181*5113495bSYour Name case SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED:
182*5113495bSYour Name *nl_err_code =
183*5113495bSYour Name QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED;
184*5113495bSYour Name break;
185*5113495bSYour Name
186*5113495bSYour Name case SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED:
187*5113495bSYour Name *nl_err_code =
188*5113495bSYour Name QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED;
189*5113495bSYour Name break;
190*5113495bSYour Name
191*5113495bSYour Name case SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE:
192*5113495bSYour Name *nl_err_code =
193*5113495bSYour Name QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
194*5113495bSYour Name break;
195*5113495bSYour Name
196*5113495bSYour Name case SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED:
197*5113495bSYour Name *nl_err_code =
198*5113495bSYour Name QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED;
199*5113495bSYour Name break;
200*5113495bSYour Name
201*5113495bSYour Name default:
202*5113495bSYour Name osif_err("Invalid spectral error code %u", spectral_err_code);
203*5113495bSYour Name return QDF_STATUS_E_FAILURE;
204*5113495bSYour Name }
205*5113495bSYour Name
206*5113495bSYour Name return QDF_STATUS_SUCCESS;
207*5113495bSYour Name }
208*5113495bSYour Name
209*5113495bSYour Name #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
210*5113495bSYour Name int
wlan_spectral_get_nl80211_chwidth(uint8_t phy_chwidth)211*5113495bSYour Name wlan_spectral_get_nl80211_chwidth(uint8_t phy_chwidth)
212*5113495bSYour Name {
213*5113495bSYour Name switch ((enum phy_ch_width)phy_chwidth) {
214*5113495bSYour Name case CH_WIDTH_5MHZ:
215*5113495bSYour Name return NL80211_CHAN_WIDTH_5;
216*5113495bSYour Name case CH_WIDTH_10MHZ:
217*5113495bSYour Name return NL80211_CHAN_WIDTH_10;
218*5113495bSYour Name case CH_WIDTH_20MHZ:
219*5113495bSYour Name return NL80211_CHAN_WIDTH_20;
220*5113495bSYour Name case CH_WIDTH_40MHZ:
221*5113495bSYour Name return NL80211_CHAN_WIDTH_40;
222*5113495bSYour Name case CH_WIDTH_80MHZ:
223*5113495bSYour Name return NL80211_CHAN_WIDTH_80;
224*5113495bSYour Name case CH_WIDTH_160MHZ:
225*5113495bSYour Name return NL80211_CHAN_WIDTH_160;
226*5113495bSYour Name case CH_WIDTH_80P80MHZ:
227*5113495bSYour Name return NL80211_CHAN_WIDTH_80P80;
228*5113495bSYour Name case CH_WIDTH_320MHZ:
229*5113495bSYour Name case CH_WIDTH_MAX:
230*5113495bSYour Name return NL80211_CHAN_WIDTH_320;
231*5113495bSYour Name case CH_WIDTH_INVALID:
232*5113495bSYour Name default:
233*5113495bSYour Name osif_err("Invalid spectral channel width %u", phy_chwidth);
234*5113495bSYour Name return -EINVAL;
235*5113495bSYour Name }
236*5113495bSYour Name }
237*5113495bSYour Name
238*5113495bSYour Name uint8_t
wlan_spectral_get_phy_ch_width(uint8_t nl_chwidth)239*5113495bSYour Name wlan_spectral_get_phy_ch_width(uint8_t nl_chwidth)
240*5113495bSYour Name {
241*5113495bSYour Name switch ((enum nl80211_chan_width)nl_chwidth) {
242*5113495bSYour Name case NL80211_CHAN_WIDTH_5:
243*5113495bSYour Name return CH_WIDTH_5MHZ;
244*5113495bSYour Name case NL80211_CHAN_WIDTH_10:
245*5113495bSYour Name return CH_WIDTH_10MHZ;
246*5113495bSYour Name case NL80211_CHAN_WIDTH_20:
247*5113495bSYour Name return CH_WIDTH_20MHZ;
248*5113495bSYour Name case NL80211_CHAN_WIDTH_40:
249*5113495bSYour Name return CH_WIDTH_40MHZ;
250*5113495bSYour Name case NL80211_CHAN_WIDTH_80:
251*5113495bSYour Name return CH_WIDTH_80MHZ;
252*5113495bSYour Name case NL80211_CHAN_WIDTH_160:
253*5113495bSYour Name return CH_WIDTH_160MHZ;
254*5113495bSYour Name case NL80211_CHAN_WIDTH_80P80:
255*5113495bSYour Name return CH_WIDTH_80P80MHZ;
256*5113495bSYour Name case NL80211_CHAN_WIDTH_320:
257*5113495bSYour Name return CH_WIDTH_320MHZ;
258*5113495bSYour Name default:
259*5113495bSYour Name osif_err("Invalid nl80211 channel width %u", nl_chwidth);
260*5113495bSYour Name return CH_WIDTH_INVALID;
261*5113495bSYour Name }
262*5113495bSYour Name }
263*5113495bSYour Name #else
264*5113495bSYour Name int
wlan_spectral_get_nl80211_chwidth(uint8_t phy_chwidth)265*5113495bSYour Name wlan_spectral_get_nl80211_chwidth(uint8_t phy_chwidth)
266*5113495bSYour Name {
267*5113495bSYour Name switch ((enum phy_ch_width)phy_chwidth) {
268*5113495bSYour Name case CH_WIDTH_5MHZ:
269*5113495bSYour Name return NL80211_CHAN_WIDTH_5;
270*5113495bSYour Name case CH_WIDTH_10MHZ:
271*5113495bSYour Name return NL80211_CHAN_WIDTH_10;
272*5113495bSYour Name case CH_WIDTH_20MHZ:
273*5113495bSYour Name return NL80211_CHAN_WIDTH_20;
274*5113495bSYour Name case CH_WIDTH_40MHZ:
275*5113495bSYour Name return NL80211_CHAN_WIDTH_40;
276*5113495bSYour Name case CH_WIDTH_80MHZ:
277*5113495bSYour Name return NL80211_CHAN_WIDTH_80;
278*5113495bSYour Name case CH_WIDTH_160MHZ:
279*5113495bSYour Name case CH_WIDTH_MAX:
280*5113495bSYour Name return NL80211_CHAN_WIDTH_160;
281*5113495bSYour Name case CH_WIDTH_80P80MHZ:
282*5113495bSYour Name return NL80211_CHAN_WIDTH_80P80;
283*5113495bSYour Name case CH_WIDTH_INVALID:
284*5113495bSYour Name default:
285*5113495bSYour Name osif_err("Invalid spectral channel width %u", phy_chwidth);
286*5113495bSYour Name return -EINVAL;
287*5113495bSYour Name }
288*5113495bSYour Name }
289*5113495bSYour Name
290*5113495bSYour Name uint8_t
wlan_spectral_get_phy_ch_width(uint8_t nl_chwidth)291*5113495bSYour Name wlan_spectral_get_phy_ch_width(uint8_t nl_chwidth)
292*5113495bSYour Name {
293*5113495bSYour Name switch ((enum nl80211_chan_width)nl_chwidth) {
294*5113495bSYour Name case NL80211_CHAN_WIDTH_5:
295*5113495bSYour Name return CH_WIDTH_5MHZ;
296*5113495bSYour Name case NL80211_CHAN_WIDTH_10:
297*5113495bSYour Name return CH_WIDTH_10MHZ;
298*5113495bSYour Name case NL80211_CHAN_WIDTH_20:
299*5113495bSYour Name return CH_WIDTH_20MHZ;
300*5113495bSYour Name case NL80211_CHAN_WIDTH_40:
301*5113495bSYour Name return CH_WIDTH_40MHZ;
302*5113495bSYour Name case NL80211_CHAN_WIDTH_80:
303*5113495bSYour Name return CH_WIDTH_80MHZ;
304*5113495bSYour Name case NL80211_CHAN_WIDTH_160:
305*5113495bSYour Name return CH_WIDTH_160MHZ;
306*5113495bSYour Name case NL80211_CHAN_WIDTH_80P80:
307*5113495bSYour Name return CH_WIDTH_80P80MHZ;
308*5113495bSYour Name default:
309*5113495bSYour Name osif_err("Invalid nl80211 channel width %u", nl_chwidth);
310*5113495bSYour Name return CH_WIDTH_INVALID;
311*5113495bSYour Name }
312*5113495bSYour Name }
313*5113495bSYour Name #endif /* WLAN_FEATURE_11BE */
314*5113495bSYour Name
315*5113495bSYour Name #ifdef DIRECT_BUF_RX_DEBUG
wlan_cfg80211_spectral_scan_dma_debug_config(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,struct nlattr ** tb,enum spectral_scan_mode sscan_mode)316*5113495bSYour Name QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config(
317*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
318*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
319*5113495bSYour Name struct nlattr **tb,
320*5113495bSYour Name enum spectral_scan_mode sscan_mode)
321*5113495bSYour Name {
322*5113495bSYour Name struct spectral_cp_request sscan_req;
323*5113495bSYour Name uint8_t dma_debug_enable;
324*5113495bSYour Name QDF_STATUS status;
325*5113495bSYour Name
326*5113495bSYour Name if (!tb || !pdev)
327*5113495bSYour Name return QDF_STATUS_E_FAILURE;
328*5113495bSYour Name
329*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG]) {
330*5113495bSYour Name dma_debug_enable = nla_get_u8(tb[
331*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG]);
332*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
333*5113495bSYour Name sscan_req.dma_debug_req.dma_debug_enable = !!dma_debug_enable;
334*5113495bSYour Name sscan_req.dma_debug_req.dma_debug_type =
335*5113495bSYour Name SPECTRAL_DMA_RING_DEBUG;
336*5113495bSYour Name sscan_req.req_id = SPECTRAL_SET_DMA_DEBUG;
337*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
338*5113495bSYour Name if (status != QDF_STATUS_SUCCESS) {
339*5113495bSYour Name osif_err("Could not configure dma ring debug");
340*5113495bSYour Name return QDF_STATUS_E_FAILURE;
341*5113495bSYour Name }
342*5113495bSYour Name }
343*5113495bSYour Name
344*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG]) {
345*5113495bSYour Name dma_debug_enable = nla_get_u8(tb[
346*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG]);
347*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
348*5113495bSYour Name sscan_req.dma_debug_req.dma_debug_enable = !!dma_debug_enable;
349*5113495bSYour Name sscan_req.dma_debug_req.dma_debug_type =
350*5113495bSYour Name SPECTRAL_DMA_BUFFER_DEBUG;
351*5113495bSYour Name sscan_req.req_id = SPECTRAL_SET_DMA_DEBUG;
352*5113495bSYour Name return ucfg_spectral_control(pdev, &sscan_req);
353*5113495bSYour Name }
354*5113495bSYour Name
355*5113495bSYour Name return QDF_STATUS_SUCCESS;
356*5113495bSYour Name }
357*5113495bSYour Name #else
wlan_cfg80211_spectral_scan_dma_debug_config(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,struct nlattr ** tb,enum spectral_scan_mode sscan_mode)358*5113495bSYour Name QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config(
359*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
360*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
361*5113495bSYour Name struct nlattr **tb,
362*5113495bSYour Name enum spectral_scan_mode sscan_mode)
363*5113495bSYour Name {
364*5113495bSYour Name return QDF_STATUS_SUCCESS;
365*5113495bSYour Name }
366*5113495bSYour Name #endif /* DIRECT_BUF_RX_DEBUG */
367*5113495bSYour Name
wlan_cfg80211_spectral_scan_config_and_start(struct wiphy * wiphy,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,const void * data,int data_len)368*5113495bSYour Name int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy,
369*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
370*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
371*5113495bSYour Name const void *data,
372*5113495bSYour Name int data_len)
373*5113495bSYour Name {
374*5113495bSYour Name struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + 1];
375*5113495bSYour Name struct spectral_config config_req;
376*5113495bSYour Name QDF_STATUS status;
377*5113495bSYour Name uint64_t cookie;
378*5113495bSYour Name struct sk_buff *skb;
379*5113495bSYour Name uint32_t spectral_dbg_level;
380*5113495bSYour Name uint32_t scan_req_type = 0;
381*5113495bSYour Name struct spectral_cp_request sscan_req;
382*5113495bSYour Name enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
383*5113495bSYour Name uint16_t skb_len;
384*5113495bSYour Name
385*5113495bSYour Name if (wlan_cfg80211_nla_parse(
386*5113495bSYour Name tb,
387*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX,
388*5113495bSYour Name data,
389*5113495bSYour Name data_len,
390*5113495bSYour Name spectral_scan_policy)) {
391*5113495bSYour Name osif_err("Invalid Spectral Scan config ATTR");
392*5113495bSYour Name return -EINVAL;
393*5113495bSYour Name }
394*5113495bSYour Name
395*5113495bSYour Name wlan_spectral_intit_config(&config_req);
396*5113495bSYour Name
397*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT])
398*5113495bSYour Name config_req.ss_count = nla_get_u32(tb
399*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT]);
400*5113495bSYour Name
401*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD])
402*5113495bSYour Name config_req.ss_period = nla_get_u32(tb
403*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD]);
404*5113495bSYour Name
405*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_RECAPTURE])
406*5113495bSYour Name config_req.ss_recapture = nla_get_u32(tb
407*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_RECAPTURE]);
408*5113495bSYour Name
409*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY])
410*5113495bSYour Name config_req.ss_spectral_pri = nla_get_u32(tb
411*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY]);
412*5113495bSYour Name
413*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE])
414*5113495bSYour Name config_req.ss_fft_size = nla_get_u32(tb
415*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE]);
416*5113495bSYour Name
417*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA])
418*5113495bSYour Name config_req.ss_gc_ena = nla_get_u32(tb
419*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA]);
420*5113495bSYour Name
421*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA])
422*5113495bSYour Name config_req.ss_restart_ena = nla_get_u32(tb
423*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA]);
424*5113495bSYour Name
425*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF])
426*5113495bSYour Name config_req.ss_noise_floor_ref = nla_get_u32(tb
427*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF]);
428*5113495bSYour Name
429*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY])
430*5113495bSYour Name config_req.ss_init_delay = nla_get_u32(tb
431*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY]);
432*5113495bSYour Name
433*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR])
434*5113495bSYour Name config_req.ss_nb_tone_thr = nla_get_u32(tb
435*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR]);
436*5113495bSYour Name
437*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR])
438*5113495bSYour Name config_req.ss_str_bin_thr = nla_get_u32(tb
439*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR]);
440*5113495bSYour Name
441*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE])
442*5113495bSYour Name config_req.ss_wb_rpt_mode = nla_get_u32(tb
443*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE]);
444*5113495bSYour Name
445*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE])
446*5113495bSYour Name config_req.ss_rssi_rpt_mode = nla_get_u32(tb
447*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE]);
448*5113495bSYour Name
449*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR])
450*5113495bSYour Name config_req.ss_rssi_thr = nla_get_u32(tb
451*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR]);
452*5113495bSYour Name
453*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT])
454*5113495bSYour Name config_req.ss_pwr_format = nla_get_u32(tb
455*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT]);
456*5113495bSYour Name
457*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE])
458*5113495bSYour Name config_req.ss_rpt_mode = nla_get_u32(tb
459*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE]);
460*5113495bSYour Name
461*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE])
462*5113495bSYour Name config_req.ss_bin_scale = nla_get_u32(tb
463*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE]);
464*5113495bSYour Name
465*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ])
466*5113495bSYour Name config_req.ss_dbm_adj = nla_get_u32(tb
467*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ]);
468*5113495bSYour Name
469*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK])
470*5113495bSYour Name config_req.ss_chn_mask = nla_get_u32(tb
471*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK]);
472*5113495bSYour Name
473*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD])
474*5113495bSYour Name config_req.ss_fft_period = nla_get_u32(tb
475*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD]);
476*5113495bSYour Name
477*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT])
478*5113495bSYour Name config_req.ss_short_report = nla_get_u32(tb
479*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT]);
480*5113495bSYour Name
481*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY])
482*5113495bSYour Name config_req.ss_frequency.cfreq1 = nla_get_u32(tb
483*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY]);
484*5113495bSYour Name
485*5113495bSYour Name config_req.ss_frequency.cfreq2 = 0;
486*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2])
487*5113495bSYour Name config_req.ss_frequency.cfreq2 = nla_get_u32(tb
488*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2]);
489*5113495bSYour Name
490*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH]) {
491*5113495bSYour Name uint8_t sscan_bw_nl;
492*5113495bSYour Name
493*5113495bSYour Name sscan_bw_nl = nla_get_u8(
494*5113495bSYour Name tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH]);
495*5113495bSYour Name
496*5113495bSYour Name /* Convert to phy_ch_width format */
497*5113495bSYour Name config_req.ss_bandwidth =
498*5113495bSYour Name wlan_spectral_get_phy_ch_width(sscan_bw_nl);
499*5113495bSYour Name }
500*5113495bSYour Name
501*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]) {
502*5113495bSYour Name status = convert_spectral_mode_nl_to_internal(nla_get_u32(tb
503*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]), &sscan_mode);
504*5113495bSYour Name
505*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
506*5113495bSYour Name return -EINVAL;
507*5113495bSYour Name }
508*5113495bSYour Name
509*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL]) {
510*5113495bSYour Name spectral_dbg_level = nla_get_u32(tb
511*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL]);
512*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
513*5113495bSYour Name sscan_req.debug_req.spectral_dbg_level = spectral_dbg_level;
514*5113495bSYour Name sscan_req.req_id = SPECTRAL_SET_DEBUG_LEVEL;
515*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
516*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
517*5113495bSYour Name return -EINVAL;
518*5113495bSYour Name }
519*5113495bSYour Name
520*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE])
521*5113495bSYour Name scan_req_type = nla_get_u32(tb
522*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE]);
523*5113495bSYour Name
524*5113495bSYour Name skb_len = NLMSG_HDRLEN;
525*5113495bSYour Name /* QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE */
526*5113495bSYour Name skb_len += NLA_HDRLEN + sizeof(u32);
527*5113495bSYour Name /* QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE */
528*5113495bSYour Name skb_len += NLA_HDRLEN + sizeof(u64);
529*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len);
530*5113495bSYour Name
531*5113495bSYour Name if (!skb) {
532*5113495bSYour Name osif_err(" reply skb alloc failed");
533*5113495bSYour Name return -ENOMEM;
534*5113495bSYour Name }
535*5113495bSYour Name
536*5113495bSYour Name status = wlan_cfg80211_spectral_scan_dma_debug_config(
537*5113495bSYour Name pdev, vdev, tb, sscan_mode);
538*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
539*5113495bSYour Name status = QDF_STATUS_E_INVAL;
540*5113495bSYour Name goto free_skb_return_os_status;
541*5113495bSYour Name }
542*5113495bSYour Name
543*5113495bSYour Name if (vdev)
544*5113495bSYour Name sscan_req.vdev_id = wlan_vdev_get_id(vdev);
545*5113495bSYour Name else
546*5113495bSYour Name sscan_req.vdev_id = WLAN_INVALID_VDEV_ID;
547*5113495bSYour Name
548*5113495bSYour Name if (CONFIG_REQUESTED(scan_req_type)) {
549*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
550*5113495bSYour Name sscan_req.req_id = SPECTRAL_SET_CONFIG;
551*5113495bSYour Name qdf_mem_copy(&sscan_req.config_req.sscan_config, &config_req,
552*5113495bSYour Name qdf_min(sizeof(sscan_req.config_req.sscan_config),
553*5113495bSYour Name sizeof(config_req)));
554*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
555*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
556*5113495bSYour Name enum qca_wlan_vendor_spectral_scan_error_code
557*5113495bSYour Name spectral_nl_err_code;
558*5113495bSYour Name
559*5113495bSYour Name /* No error reasons populated, just return error */
560*5113495bSYour Name if (sscan_req.config_req.sscan_err_code ==
561*5113495bSYour Name SPECTRAL_SCAN_ERR_INVALID)
562*5113495bSYour Name goto free_skb_return_os_status;
563*5113495bSYour Name
564*5113495bSYour Name status = convert_spectral_err_code_internal_to_nl
565*5113495bSYour Name (sscan_req.config_req.sscan_err_code,
566*5113495bSYour Name &spectral_nl_err_code);
567*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
568*5113495bSYour Name status = QDF_STATUS_E_INVAL;
569*5113495bSYour Name goto free_skb_return_os_status;
570*5113495bSYour Name }
571*5113495bSYour Name
572*5113495bSYour Name if (nla_put_u32
573*5113495bSYour Name (skb,
574*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE,
575*5113495bSYour Name spectral_nl_err_code)) {
576*5113495bSYour Name status = QDF_STATUS_E_INVAL;
577*5113495bSYour Name goto free_skb_return_os_status;
578*5113495bSYour Name }
579*5113495bSYour Name }
580*5113495bSYour Name }
581*5113495bSYour Name
582*5113495bSYour Name if (SCAN_REQUESTED(scan_req_type)) {
583*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
584*5113495bSYour Name sscan_req.req_id = SPECTRAL_ACTIVATE_SCAN;
585*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
586*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
587*5113495bSYour Name enum qca_wlan_vendor_spectral_scan_error_code
588*5113495bSYour Name spectral_nl_err_code;
589*5113495bSYour Name
590*5113495bSYour Name /* No error reasons populated, just return error */
591*5113495bSYour Name if (sscan_req.action_req.sscan_err_code ==
592*5113495bSYour Name SPECTRAL_SCAN_ERR_INVALID)
593*5113495bSYour Name goto free_skb_return_os_status;
594*5113495bSYour Name
595*5113495bSYour Name status = convert_spectral_err_code_internal_to_nl
596*5113495bSYour Name (sscan_req.action_req.sscan_err_code,
597*5113495bSYour Name &spectral_nl_err_code);
598*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
599*5113495bSYour Name status = QDF_STATUS_E_INVAL;
600*5113495bSYour Name goto free_skb_return_os_status;
601*5113495bSYour Name }
602*5113495bSYour Name
603*5113495bSYour Name if (nla_put_u32
604*5113495bSYour Name (skb,
605*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE,
606*5113495bSYour Name spectral_nl_err_code)) {
607*5113495bSYour Name status = QDF_STATUS_E_INVAL;
608*5113495bSYour Name goto free_skb_return_os_status;
609*5113495bSYour Name }
610*5113495bSYour Name }
611*5113495bSYour Name }
612*5113495bSYour Name
613*5113495bSYour Name cookie = 0;
614*5113495bSYour Name if (wlan_cfg80211_nla_put_u64(skb,
615*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE,
616*5113495bSYour Name cookie)) {
617*5113495bSYour Name status = QDF_STATUS_E_INVAL;
618*5113495bSYour Name goto free_skb_return_os_status;
619*5113495bSYour Name }
620*5113495bSYour Name
621*5113495bSYour Name wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb);
622*5113495bSYour Name return 0;
623*5113495bSYour Name free_skb_return_os_status:
624*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
625*5113495bSYour Name return qdf_status_to_os_return(status);
626*5113495bSYour Name }
627*5113495bSYour Name
wlan_cfg80211_spectral_scan_stop(struct wiphy * wiphy,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,const void * data,int data_len)628*5113495bSYour Name int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy,
629*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
630*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
631*5113495bSYour Name const void *data,
632*5113495bSYour Name int data_len)
633*5113495bSYour Name {
634*5113495bSYour Name struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + 1];
635*5113495bSYour Name QDF_STATUS status;
636*5113495bSYour Name struct spectral_cp_request sscan_req;
637*5113495bSYour Name enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
638*5113495bSYour Name struct sk_buff *skb;
639*5113495bSYour Name
640*5113495bSYour Name if (wlan_cfg80211_nla_parse(
641*5113495bSYour Name tb,
642*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX,
643*5113495bSYour Name data,
644*5113495bSYour Name data_len,
645*5113495bSYour Name spectral_scan_policy)) {
646*5113495bSYour Name osif_err("Invalid Spectral Scan stop ATTR");
647*5113495bSYour Name return -EINVAL;
648*5113495bSYour Name }
649*5113495bSYour Name
650*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]) {
651*5113495bSYour Name status = convert_spectral_mode_nl_to_internal(nla_get_u32(tb
652*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]), &sscan_mode);
653*5113495bSYour Name
654*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
655*5113495bSYour Name return -EINVAL;
656*5113495bSYour Name }
657*5113495bSYour Name
658*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
659*5113495bSYour Name sscan_req.req_id = SPECTRAL_STOP_SCAN;
660*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
661*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
662*5113495bSYour Name enum qca_wlan_vendor_spectral_scan_error_code
663*5113495bSYour Name spectral_nl_err_code;
664*5113495bSYour Name
665*5113495bSYour Name /* No error reasons populated, just return error */
666*5113495bSYour Name if (sscan_req.action_req.sscan_err_code ==
667*5113495bSYour Name SPECTRAL_SCAN_ERR_INVALID)
668*5113495bSYour Name return qdf_status_to_os_return(status);
669*5113495bSYour Name
670*5113495bSYour Name status = convert_spectral_err_code_internal_to_nl
671*5113495bSYour Name (sscan_req.action_req.sscan_err_code,
672*5113495bSYour Name &spectral_nl_err_code);
673*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
674*5113495bSYour Name return -EINVAL;
675*5113495bSYour Name
676*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
677*5113495bSYour Name NLMSG_HDRLEN + sizeof(u32) + NLA_HDRLEN);
678*5113495bSYour Name
679*5113495bSYour Name if (!skb) {
680*5113495bSYour Name osif_err(" reply skb alloc failed");
681*5113495bSYour Name return -ENOMEM;
682*5113495bSYour Name }
683*5113495bSYour Name
684*5113495bSYour Name if (nla_put_u32
685*5113495bSYour Name (skb,
686*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE,
687*5113495bSYour Name spectral_nl_err_code)) {
688*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
689*5113495bSYour Name return -EINVAL;
690*5113495bSYour Name }
691*5113495bSYour Name wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb);
692*5113495bSYour Name }
693*5113495bSYour Name
694*5113495bSYour Name return 0;
695*5113495bSYour Name }
696*5113495bSYour Name
wlan_cfg80211_spectral_scan_get_config(struct wiphy * wiphy,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,const void * data,int data_len)697*5113495bSYour Name int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy,
698*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
699*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
700*5113495bSYour Name const void *data,
701*5113495bSYour Name int data_len)
702*5113495bSYour Name {
703*5113495bSYour Name struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + 1];
704*5113495bSYour Name struct spectral_config *sconfig;
705*5113495bSYour Name uint32_t spectral_dbg_level;
706*5113495bSYour Name struct sk_buff *skb;
707*5113495bSYour Name struct spectral_cp_request sscan_req;
708*5113495bSYour Name enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
709*5113495bSYour Name QDF_STATUS status;
710*5113495bSYour Name int sscan_bw_nl;
711*5113495bSYour Name
712*5113495bSYour Name if (wlan_cfg80211_nla_parse(
713*5113495bSYour Name tb,
714*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX,
715*5113495bSYour Name data,
716*5113495bSYour Name data_len,
717*5113495bSYour Name spectral_scan_policy)) {
718*5113495bSYour Name osif_err("Invalid Spectral Scan config ATTR");
719*5113495bSYour Name return -EINVAL;
720*5113495bSYour Name }
721*5113495bSYour Name
722*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]) {
723*5113495bSYour Name status = convert_spectral_mode_nl_to_internal(nla_get_u32(tb
724*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE]), &sscan_mode);
725*5113495bSYour Name
726*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
727*5113495bSYour Name return -EINVAL;
728*5113495bSYour Name }
729*5113495bSYour Name
730*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
731*5113495bSYour Name (sizeof(u32) +
732*5113495bSYour Name NLA_HDRLEN) * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX +
733*5113495bSYour Name NLMSG_HDRLEN);
734*5113495bSYour Name if (!skb) {
735*5113495bSYour Name osif_err(" reply skb alloc failed");
736*5113495bSYour Name return -ENOMEM;
737*5113495bSYour Name }
738*5113495bSYour Name
739*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
740*5113495bSYour Name sscan_req.req_id = SPECTRAL_GET_CONFIG;
741*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
742*5113495bSYour Name sconfig = &sscan_req.config_req.sscan_config;
743*5113495bSYour Name
744*5113495bSYour Name /* Convert to sscan_bw to NL8021 format */
745*5113495bSYour Name sscan_bw_nl = wlan_spectral_get_nl80211_chwidth(sconfig->ss_bandwidth);
746*5113495bSYour Name if (sscan_bw_nl == -EINVAL)
747*5113495bSYour Name goto fail;
748*5113495bSYour Name
749*5113495bSYour Name if (nla_put_u32(skb,
750*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT,
751*5113495bSYour Name sconfig->ss_count) ||
752*5113495bSYour Name nla_put_u32(skb,
753*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD,
754*5113495bSYour Name sconfig->ss_period) ||
755*5113495bSYour Name nla_put_u32(skb,
756*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY,
757*5113495bSYour Name sconfig->ss_spectral_pri) ||
758*5113495bSYour Name nla_put_u32(skb,
759*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE,
760*5113495bSYour Name sconfig->ss_fft_size) ||
761*5113495bSYour Name nla_put_u32(skb,
762*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA,
763*5113495bSYour Name sconfig->ss_gc_ena) ||
764*5113495bSYour Name nla_put_u32(skb,
765*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA,
766*5113495bSYour Name sconfig->ss_restart_ena) ||
767*5113495bSYour Name nla_put_u32(
768*5113495bSYour Name skb,
769*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF,
770*5113495bSYour Name sconfig->ss_noise_floor_ref) ||
771*5113495bSYour Name nla_put_u32(skb,
772*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY,
773*5113495bSYour Name sconfig->ss_init_delay) ||
774*5113495bSYour Name nla_put_u32(skb,
775*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR,
776*5113495bSYour Name sconfig->ss_nb_tone_thr) ||
777*5113495bSYour Name nla_put_u32(skb,
778*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR,
779*5113495bSYour Name sconfig->ss_str_bin_thr) ||
780*5113495bSYour Name nla_put_u32(skb,
781*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE,
782*5113495bSYour Name sconfig->ss_wb_rpt_mode) ||
783*5113495bSYour Name nla_put_u32(skb,
784*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE,
785*5113495bSYour Name sconfig->ss_rssi_rpt_mode) ||
786*5113495bSYour Name nla_put_u32(skb,
787*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR,
788*5113495bSYour Name sconfig->ss_rssi_thr) ||
789*5113495bSYour Name nla_put_u32(skb,
790*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT,
791*5113495bSYour Name sconfig->ss_pwr_format) ||
792*5113495bSYour Name nla_put_u32(skb,
793*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE,
794*5113495bSYour Name sconfig->ss_rpt_mode) ||
795*5113495bSYour Name nla_put_u32(skb,
796*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE,
797*5113495bSYour Name sconfig->ss_bin_scale) ||
798*5113495bSYour Name nla_put_u32(skb,
799*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ,
800*5113495bSYour Name sconfig->ss_dbm_adj) ||
801*5113495bSYour Name nla_put_u32(skb,
802*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK,
803*5113495bSYour Name sconfig->ss_chn_mask) ||
804*5113495bSYour Name nla_put_u32(skb,
805*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD,
806*5113495bSYour Name sconfig->ss_fft_period) ||
807*5113495bSYour Name nla_put_u32(skb,
808*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT,
809*5113495bSYour Name sconfig->ss_short_report) ||
810*5113495bSYour Name nla_put_u32(skb,
811*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY,
812*5113495bSYour Name sconfig->ss_frequency.cfreq1) ||
813*5113495bSYour Name nla_put_u32(skb,
814*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2,
815*5113495bSYour Name sconfig->ss_frequency.cfreq2) ||
816*5113495bSYour Name nla_put_u8(skb,
817*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH,
818*5113495bSYour Name sscan_bw_nl) ||
819*5113495bSYour Name nla_put_u32(skb,
820*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_RECAPTURE,
821*5113495bSYour Name sconfig->ss_recapture))
822*5113495bSYour Name
823*5113495bSYour Name goto fail;
824*5113495bSYour Name
825*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
826*5113495bSYour Name sscan_req.req_id = SPECTRAL_GET_DEBUG_LEVEL;
827*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
828*5113495bSYour Name spectral_dbg_level = sscan_req.debug_req.spectral_dbg_level;
829*5113495bSYour Name if (nla_put_u32(skb,
830*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL,
831*5113495bSYour Name spectral_dbg_level))
832*5113495bSYour Name goto fail;
833*5113495bSYour Name
834*5113495bSYour Name wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb);
835*5113495bSYour Name return 0;
836*5113495bSYour Name fail:
837*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
838*5113495bSYour Name return -EINVAL;
839*5113495bSYour Name }
840*5113495bSYour Name
wlan_cfg80211_spectral_scan_get_cap(struct wiphy * wiphy,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,const void * data,int data_len)841*5113495bSYour Name int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy,
842*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
843*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
844*5113495bSYour Name const void *data,
845*5113495bSYour Name int data_len)
846*5113495bSYour Name {
847*5113495bSYour Name struct spectral_caps *scaps;
848*5113495bSYour Name struct sk_buff *skb;
849*5113495bSYour Name struct spectral_cp_request sscan_req;
850*5113495bSYour Name QDF_STATUS status;
851*5113495bSYour Name
852*5113495bSYour Name sscan_req.req_id = SPECTRAL_GET_CAPABILITY_INFO;
853*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
854*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
855*5113495bSYour Name return -EINVAL;
856*5113495bSYour Name scaps = &sscan_req.caps_req.sscan_caps;
857*5113495bSYour Name
858*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
859*5113495bSYour Name (sizeof(u32) +
860*5113495bSYour Name NLA_HDRLEN) * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX +
861*5113495bSYour Name NLMSG_HDRLEN);
862*5113495bSYour Name if (!skb) {
863*5113495bSYour Name osif_err(" reply skb alloc failed");
864*5113495bSYour Name return -ENOMEM;
865*5113495bSYour Name }
866*5113495bSYour Name
867*5113495bSYour Name if (scaps->phydiag_cap)
868*5113495bSYour Name if (nla_put_flag(
869*5113495bSYour Name skb,
870*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_PHYDIAG))
871*5113495bSYour Name goto fail;
872*5113495bSYour Name
873*5113495bSYour Name if (scaps->radar_cap)
874*5113495bSYour Name if (nla_put_flag(skb,
875*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RADAR))
876*5113495bSYour Name goto fail;
877*5113495bSYour Name
878*5113495bSYour Name if (scaps->spectral_cap)
879*5113495bSYour Name if (nla_put_flag(
880*5113495bSYour Name skb,
881*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_SPECTRAL))
882*5113495bSYour Name goto fail;
883*5113495bSYour Name
884*5113495bSYour Name if (scaps->advncd_spectral_cap)
885*5113495bSYour Name if (nla_put_flag(
886*5113495bSYour Name skb,
887*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_ADVANCED_SPECTRAL))
888*5113495bSYour Name goto fail;
889*5113495bSYour Name
890*5113495bSYour Name if (nla_put_u32(skb,
891*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN,
892*5113495bSYour Name scaps->hw_gen))
893*5113495bSYour Name goto fail;
894*5113495bSYour Name
895*5113495bSYour Name if (scaps->is_scaling_params_populated) {
896*5113495bSYour Name if (nla_put_u16(
897*5113495bSYour Name skb,
898*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID,
899*5113495bSYour Name scaps->formula_id))
900*5113495bSYour Name goto fail;
901*5113495bSYour Name
902*5113495bSYour Name if (nla_put_u16(
903*5113495bSYour Name skb,
904*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_LOW_LEVEL_OFFSET,
905*5113495bSYour Name scaps->low_level_offset))
906*5113495bSYour Name goto fail;
907*5113495bSYour Name
908*5113495bSYour Name if (nla_put_u16(
909*5113495bSYour Name skb,
910*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HIGH_LEVEL_OFFSET,
911*5113495bSYour Name scaps->high_level_offset))
912*5113495bSYour Name goto fail;
913*5113495bSYour Name
914*5113495bSYour Name if (nla_put_u16(
915*5113495bSYour Name skb,
916*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RSSI_THR,
917*5113495bSYour Name scaps->rssi_thr))
918*5113495bSYour Name goto fail;
919*5113495bSYour Name
920*5113495bSYour Name if (nla_put_u8(
921*5113495bSYour Name skb,
922*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN,
923*5113495bSYour Name scaps->default_agc_max_gain))
924*5113495bSYour Name goto fail;
925*5113495bSYour Name }
926*5113495bSYour Name
927*5113495bSYour Name if (scaps->agile_spectral_cap) {
928*5113495bSYour Name int ret;
929*5113495bSYour Name
930*5113495bSYour Name ret = nla_put_flag
931*5113495bSYour Name (skb,
932*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL);
933*5113495bSYour Name if (ret)
934*5113495bSYour Name goto fail;
935*5113495bSYour Name }
936*5113495bSYour Name
937*5113495bSYour Name if (scaps->agile_spectral_cap_160) {
938*5113495bSYour Name int ret;
939*5113495bSYour Name
940*5113495bSYour Name ret = nla_put_flag
941*5113495bSYour Name (skb,
942*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_160);
943*5113495bSYour Name if (ret)
944*5113495bSYour Name goto fail;
945*5113495bSYour Name }
946*5113495bSYour Name if (scaps->agile_spectral_cap_80p80) {
947*5113495bSYour Name int ret;
948*5113495bSYour Name
949*5113495bSYour Name ret = nla_put_flag
950*5113495bSYour Name (skb,
951*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_80_80);
952*5113495bSYour Name if (ret)
953*5113495bSYour Name goto fail;
954*5113495bSYour Name }
955*5113495bSYour Name if (scaps->agile_spectral_cap_320) {
956*5113495bSYour Name int ret;
957*5113495bSYour Name
958*5113495bSYour Name ret = nla_put_flag
959*5113495bSYour Name (skb,
960*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320);
961*5113495bSYour Name if (ret)
962*5113495bSYour Name goto fail;
963*5113495bSYour Name }
964*5113495bSYour Name
965*5113495bSYour Name
966*5113495bSYour Name if (nla_put_u32(
967*5113495bSYour Name skb,
968*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_20_MHZ,
969*5113495bSYour Name scaps->num_detectors_20mhz))
970*5113495bSYour Name goto fail;
971*5113495bSYour Name
972*5113495bSYour Name if (nla_put_u32(
973*5113495bSYour Name skb,
974*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_40_MHZ,
975*5113495bSYour Name scaps->num_detectors_40mhz))
976*5113495bSYour Name goto fail;
977*5113495bSYour Name
978*5113495bSYour Name if (nla_put_u32(
979*5113495bSYour Name skb,
980*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80_MHZ,
981*5113495bSYour Name scaps->num_detectors_80mhz))
982*5113495bSYour Name goto fail;
983*5113495bSYour Name
984*5113495bSYour Name if (nla_put_u32(
985*5113495bSYour Name skb,
986*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_160_MHZ,
987*5113495bSYour Name scaps->num_detectors_160mhz))
988*5113495bSYour Name goto fail;
989*5113495bSYour Name
990*5113495bSYour Name if (nla_put_u32(
991*5113495bSYour Name skb,
992*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ,
993*5113495bSYour Name scaps->num_detectors_80p80mhz))
994*5113495bSYour Name goto fail;
995*5113495bSYour Name
996*5113495bSYour Name if (nla_put_u32(
997*5113495bSYour Name skb,
998*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ,
999*5113495bSYour Name scaps->num_detectors_320mhz))
1000*5113495bSYour Name goto fail;
1001*5113495bSYour Name
1002*5113495bSYour Name wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb);
1003*5113495bSYour Name
1004*5113495bSYour Name return 0;
1005*5113495bSYour Name
1006*5113495bSYour Name fail:
1007*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
1008*5113495bSYour Name return -EINVAL;
1009*5113495bSYour Name }
1010*5113495bSYour Name
wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy * wiphy,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,const void * data,int data_len)1011*5113495bSYour Name int wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy,
1012*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
1013*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
1014*5113495bSYour Name const void *data,
1015*5113495bSYour Name int data_len)
1016*5113495bSYour Name {
1017*5113495bSYour Name struct spectral_diag_stats *spetcral_diag;
1018*5113495bSYour Name struct sk_buff *skb;
1019*5113495bSYour Name struct spectral_cp_request sscan_req;
1020*5113495bSYour Name QDF_STATUS status;
1021*5113495bSYour Name
1022*5113495bSYour Name sscan_req.req_id = SPECTRAL_GET_DIAG_STATS;
1023*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
1024*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
1025*5113495bSYour Name return -EINVAL;
1026*5113495bSYour Name spetcral_diag = &sscan_req.diag_req.sscan_diag;
1027*5113495bSYour Name
1028*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1029*5113495bSYour Name (sizeof(u64) + NLA_HDRLEN) *
1030*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_MAX +
1031*5113495bSYour Name NLMSG_HDRLEN);
1032*5113495bSYour Name if (!skb) {
1033*5113495bSYour Name osif_err(" reply skb alloc failed");
1034*5113495bSYour Name return -ENOMEM;
1035*5113495bSYour Name }
1036*5113495bSYour Name
1037*5113495bSYour Name if (wlan_cfg80211_nla_put_u64(
1038*5113495bSYour Name skb,
1039*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SIG_MISMATCH,
1040*5113495bSYour Name spetcral_diag->spectral_mismatch) ||
1041*5113495bSYour Name wlan_cfg80211_nla_put_u64(
1042*5113495bSYour Name skb,
1043*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SEC80_SFFT_INSUFFLEN,
1044*5113495bSYour Name spetcral_diag->spectral_sec80_sfft_insufflen) ||
1045*5113495bSYour Name wlan_cfg80211_nla_put_u64(
1046*5113495bSYour Name skb,
1047*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_NOSEC80_SFFT,
1048*5113495bSYour Name spetcral_diag->spectral_no_sec80_sfft) ||
1049*5113495bSYour Name wlan_cfg80211_nla_put_u64(
1050*5113495bSYour Name skb,
1051*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG1ID_MISMATCH,
1052*5113495bSYour Name spetcral_diag->spectral_vhtseg1id_mismatch) ||
1053*5113495bSYour Name wlan_cfg80211_nla_put_u64(
1054*5113495bSYour Name skb,
1055*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG2ID_MISMATCH,
1056*5113495bSYour Name spetcral_diag->spectral_vhtseg2id_mismatch)) {
1057*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
1058*5113495bSYour Name return -EINVAL;
1059*5113495bSYour Name }
1060*5113495bSYour Name wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb);
1061*5113495bSYour Name
1062*5113495bSYour Name return 0;
1063*5113495bSYour Name }
1064*5113495bSYour Name
wlan_cfg80211_spectral_scan_get_status(struct wiphy * wiphy,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,const void * data,int data_len)1065*5113495bSYour Name int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy,
1066*5113495bSYour Name struct wlan_objmgr_pdev *pdev,
1067*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
1068*5113495bSYour Name const void *data,
1069*5113495bSYour Name int data_len)
1070*5113495bSYour Name {
1071*5113495bSYour Name struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MAX + 1];
1072*5113495bSYour Name struct spectral_scan_state sscan_state = { 0 };
1073*5113495bSYour Name struct sk_buff *skb;
1074*5113495bSYour Name struct spectral_cp_request sscan_req;
1075*5113495bSYour Name enum spectral_scan_mode sscan_mode = SPECTRAL_SCAN_MODE_NORMAL;
1076*5113495bSYour Name QDF_STATUS status;
1077*5113495bSYour Name
1078*5113495bSYour Name if (wlan_cfg80211_nla_parse(
1079*5113495bSYour Name tb,
1080*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MAX,
1081*5113495bSYour Name data,
1082*5113495bSYour Name data_len,
1083*5113495bSYour Name spectral_scan_get_status_policy)) {
1084*5113495bSYour Name osif_err("Invalid Spectral Scan config ATTR");
1085*5113495bSYour Name return -EINVAL;
1086*5113495bSYour Name }
1087*5113495bSYour Name
1088*5113495bSYour Name if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE]) {
1089*5113495bSYour Name status = convert_spectral_mode_nl_to_internal(nla_get_u32(tb
1090*5113495bSYour Name [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE]), &sscan_mode);
1091*5113495bSYour Name
1092*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
1093*5113495bSYour Name return -EINVAL;
1094*5113495bSYour Name }
1095*5113495bSYour Name
1096*5113495bSYour Name /* Sending a request and extracting response from it has to be atomic */
1097*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
1098*5113495bSYour Name sscan_req.req_id = SPECTRAL_IS_ACTIVE;
1099*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
1100*5113495bSYour Name sscan_state.is_active = sscan_req.status_req.is_active;
1101*5113495bSYour Name
1102*5113495bSYour Name sscan_req.ss_mode = sscan_mode;
1103*5113495bSYour Name sscan_req.req_id = SPECTRAL_IS_ENABLED;
1104*5113495bSYour Name status = ucfg_spectral_control(pdev, &sscan_req);
1105*5113495bSYour Name sscan_state.is_enabled = sscan_req.status_req.is_enabled;
1106*5113495bSYour Name
1107*5113495bSYour Name skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1108*5113495bSYour Name 2 * (sizeof(u32) + NLA_HDRLEN) + NLMSG_HDRLEN);
1109*5113495bSYour Name if (!skb) {
1110*5113495bSYour Name osif_err(" reply skb alloc failed");
1111*5113495bSYour Name return -ENOMEM;
1112*5113495bSYour Name }
1113*5113495bSYour Name
1114*5113495bSYour Name if (sscan_state.is_enabled)
1115*5113495bSYour Name if (nla_put_flag(
1116*5113495bSYour Name skb,
1117*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ENABLED))
1118*5113495bSYour Name goto fail;
1119*5113495bSYour Name
1120*5113495bSYour Name if (sscan_state.is_active)
1121*5113495bSYour Name if (nla_put_flag(
1122*5113495bSYour Name skb,
1123*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ACTIVE))
1124*5113495bSYour Name goto fail;
1125*5113495bSYour Name wlan_cfg80211_qal_devcfg_send_response((qdf_nbuf_t)skb);
1126*5113495bSYour Name
1127*5113495bSYour Name return 0;
1128*5113495bSYour Name fail:
1129*5113495bSYour Name wlan_cfg80211_vendor_free_skb(skb);
1130*5113495bSYour Name return -EINVAL;
1131*5113495bSYour Name }
1132