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