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