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