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