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 }; 85 86 static void wlan_spectral_intit_config(struct spectral_config *config_req) 87 { 88 config_req->ss_period = SPECTRAL_PHYERR_PARAM_NOVAL; 89 config_req->ss_count = SPECTRAL_PHYERR_PARAM_NOVAL; 90 config_req->ss_fft_period = SPECTRAL_PHYERR_PARAM_NOVAL; 91 config_req->ss_short_report = SPECTRAL_PHYERR_PARAM_NOVAL; 92 config_req->ss_spectral_pri = SPECTRAL_PHYERR_PARAM_NOVAL; 93 config_req->ss_fft_size = SPECTRAL_PHYERR_PARAM_NOVAL; 94 config_req->ss_gc_ena = SPECTRAL_PHYERR_PARAM_NOVAL; 95 config_req->ss_restart_ena = SPECTRAL_PHYERR_PARAM_NOVAL; 96 config_req->ss_noise_floor_ref = SPECTRAL_PHYERR_PARAM_NOVAL; 97 config_req->ss_init_delay = SPECTRAL_PHYERR_PARAM_NOVAL; 98 config_req->ss_nb_tone_thr = SPECTRAL_PHYERR_PARAM_NOVAL; 99 config_req->ss_str_bin_thr = SPECTRAL_PHYERR_PARAM_NOVAL; 100 config_req->ss_wb_rpt_mode = SPECTRAL_PHYERR_PARAM_NOVAL; 101 config_req->ss_rssi_rpt_mode = SPECTRAL_PHYERR_PARAM_NOVAL; 102 config_req->ss_rssi_thr = SPECTRAL_PHYERR_PARAM_NOVAL; 103 config_req->ss_pwr_format = SPECTRAL_PHYERR_PARAM_NOVAL; 104 config_req->ss_rpt_mode = SPECTRAL_PHYERR_PARAM_NOVAL; 105 config_req->ss_bin_scale = SPECTRAL_PHYERR_PARAM_NOVAL; 106 config_req->ss_dbm_adj = SPECTRAL_PHYERR_PARAM_NOVAL; 107 config_req->ss_chn_mask = SPECTRAL_PHYERR_PARAM_NOVAL; 108 } 109 110 static int wlan_spectral_set_config(struct wlan_objmgr_pdev *pdev, 111 struct spectral_config *config_req) 112 { 113 int status; 114 115 status = ucfg_spectral_control(pdev, 116 SPECTRAL_SET_CONFIG, 117 config_req, 118 sizeof(struct spectral_config), 119 NULL, 120 NULL); 121 if (status < 0) 122 return -EINVAL; 123 124 return 0; 125 } 126 127 static int wlan_spectral_set_debug_level(struct wlan_objmgr_pdev *pdev, 128 uint32_t spectral_dbg_level) 129 { 130 int status; 131 132 status = ucfg_spectral_control(pdev, 133 SPECTRAL_SET_DEBUG_LEVEL, 134 &spectral_dbg_level, 135 sizeof(uint32_t), 136 NULL, 137 NULL); 138 if (status < 0) 139 return -EINVAL; 140 141 return 0; 142 } 143 144 static int wlan_spectral_get_debug_level(struct wlan_objmgr_pdev *pdev, 145 uint32_t *spectral_dbg_level) 146 { 147 int status; 148 uint32_t outsize; 149 150 outsize = sizeof(uint32_t); 151 status = ucfg_spectral_control(pdev, 152 SPECTRAL_GET_DEBUG_LEVEL, 153 NULL, 154 0, 155 spectral_dbg_level, 156 &outsize); 157 if (status < 0) 158 return -EINVAL; 159 160 return 0; 161 } 162 163 static int wlan_spectral_get_config(struct wlan_objmgr_pdev *pdev, 164 struct spectral_config *config_req) 165 { 166 int status; 167 uint32_t outsize; 168 169 outsize = sizeof(struct spectral_config); 170 status = ucfg_spectral_control(pdev, 171 SPECTRAL_GET_CONFIG, 172 NULL, 173 0, 174 config_req, 175 &outsize); 176 if (status < 0) 177 return -EINVAL; 178 179 return 0; 180 } 181 182 static int wlan_spectral_get_cap(struct wlan_objmgr_pdev *pdev, 183 struct spectral_caps *spectral_cap) 184 { 185 int status; 186 uint32_t outsize; 187 188 outsize = sizeof(struct spectral_caps); 189 status = ucfg_spectral_control(pdev, 190 SPECTRAL_GET_CAPABILITY_INFO, 191 NULL, 192 0, 193 spectral_cap, 194 &outsize); 195 if (status < 0) 196 return -EINVAL; 197 198 return 0; 199 } 200 201 static int wlan_spectral_get_diag_stats( 202 struct wlan_objmgr_pdev *pdev, 203 struct spectral_diag_stats *spectral_diag) 204 { 205 int status; 206 uint32_t outsize; 207 208 outsize = sizeof(struct spectral_diag_stats); 209 status = ucfg_spectral_control(pdev, 210 SPECTRAL_GET_DIAG_STATS, 211 NULL, 212 0, 213 spectral_diag, 214 &outsize); 215 if (status < 0) 216 return -EINVAL; 217 218 return 0; 219 } 220 221 static int wlan_spectral_scan_get_status( 222 struct wlan_objmgr_pdev *pdev, 223 struct spectral_scan_state *sscan_state) 224 { 225 uint32_t is_active; 226 uint32_t is_enabled; 227 int status; 228 uint32_t outsize; 229 230 outsize = sizeof(uint32_t); 231 status = ucfg_spectral_control(pdev, 232 SPECTRAL_IS_ACTIVE, 233 NULL, 234 0, 235 &is_active, 236 &outsize); 237 if (status < 0) 238 return -EINVAL; 239 240 sscan_state->is_active = is_active; 241 242 outsize = sizeof(uint32_t); 243 status = ucfg_spectral_control(pdev, 244 SPECTRAL_IS_ENABLED, 245 NULL, 246 0, 247 &is_enabled, 248 &outsize); 249 if (status < 0) 250 return -EINVAL; 251 252 sscan_state->is_enabled = is_enabled; 253 254 return 0; 255 } 256 257 static int wlan_start_spectral_scan(struct wlan_objmgr_pdev *pdev) 258 { 259 int status; 260 261 status = ucfg_spectral_control(pdev, 262 SPECTRAL_ACTIVATE_SCAN, 263 NULL, 264 0, 265 NULL, 266 NULL); 267 if (status < 0) 268 return -EINVAL; 269 270 return 0; 271 } 272 273 static int wlan_stop_spectral_scan(struct wlan_objmgr_pdev *pdev) 274 { 275 int status; 276 277 status = ucfg_spectral_control(pdev, 278 SPECTRAL_STOP_SCAN, 279 NULL, 280 0, 281 NULL, 282 NULL); 283 if (status < 0) 284 return -EINVAL; 285 286 return 0; 287 } 288 289 int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, 290 struct wlan_objmgr_pdev *pdev, 291 const void *data, 292 int data_len) 293 { 294 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX + 1]; 295 struct spectral_config config_req; 296 QDF_STATUS status; 297 uint64_t cookie; 298 struct sk_buff *skb; 299 uint32_t spectral_dbg_level; 300 uint32_t scan_req_type = 0; 301 302 if (wlan_cfg80211_nla_parse( 303 tb, 304 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX, 305 data, 306 data_len, 307 spectral_scan_policy)) { 308 qdf_print("Invalid Spectral Scan config ATTR"); 309 return -EINVAL; 310 } 311 312 wlan_spectral_intit_config(&config_req); 313 314 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT]) 315 config_req.ss_count = nla_get_u32(tb 316 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT]); 317 318 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD]) 319 config_req.ss_period = nla_get_u32(tb 320 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD]); 321 322 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY]) 323 config_req.ss_spectral_pri = nla_get_u32(tb 324 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY]); 325 326 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE]) 327 config_req.ss_fft_size = nla_get_u32(tb 328 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE]); 329 330 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA]) 331 config_req.ss_gc_ena = nla_get_u32(tb 332 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA]); 333 334 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA]) 335 config_req.ss_restart_ena = nla_get_u32(tb 336 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA]); 337 338 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF]) 339 config_req.ss_noise_floor_ref = nla_get_u32(tb 340 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF]); 341 342 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY]) 343 config_req.ss_init_delay = nla_get_u32(tb 344 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY]); 345 346 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR]) 347 config_req.ss_nb_tone_thr = nla_get_u32(tb 348 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR]); 349 350 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR]) 351 config_req.ss_str_bin_thr = nla_get_u32(tb 352 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR]); 353 354 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE]) 355 config_req.ss_wb_rpt_mode = nla_get_u32(tb 356 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE]); 357 358 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE]) 359 config_req.ss_rssi_rpt_mode = nla_get_u32(tb 360 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE]); 361 362 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR]) 363 config_req.ss_rssi_thr = nla_get_u32(tb 364 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR]); 365 366 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT]) 367 config_req.ss_pwr_format = nla_get_u32(tb 368 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT]); 369 370 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE]) 371 config_req.ss_rpt_mode = nla_get_u32(tb 372 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE]); 373 374 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE]) 375 config_req.ss_bin_scale = nla_get_u32(tb 376 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE]); 377 378 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ]) 379 config_req.ss_dbm_adj = nla_get_u32(tb 380 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ]); 381 382 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK]) 383 config_req.ss_chn_mask = nla_get_u32(tb 384 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK]); 385 386 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD]) 387 config_req.ss_fft_period = nla_get_u32(tb 388 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD]); 389 390 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT]) 391 config_req.ss_short_report = nla_get_u32(tb 392 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT]); 393 394 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL]) { 395 spectral_dbg_level = nla_get_u32(tb 396 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL]); 397 status = wlan_spectral_set_debug_level(pdev, 398 spectral_dbg_level); 399 if (QDF_STATUS_SUCCESS != status) 400 return -EINVAL; 401 } 402 403 if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE]) 404 scan_req_type = nla_get_u32(tb 405 [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE]); 406 407 if (CONFIG_REQUESTED(scan_req_type)) { 408 status = wlan_spectral_set_config(pdev, &config_req); 409 if (QDF_STATUS_SUCCESS != status) 410 return -EINVAL; 411 } 412 413 if (SCAN_REQUESTED(scan_req_type)) { 414 status = wlan_start_spectral_scan(pdev); 415 if (QDF_STATUS_SUCCESS != status) 416 return -EINVAL; 417 } 418 419 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u64) + 420 NLA_HDRLEN + NLMSG_HDRLEN); 421 if (!skb) { 422 qdf_print(" reply skb alloc failed"); 423 return -ENOMEM; 424 } 425 426 cookie = 0; 427 if (wlan_cfg80211_nla_put_u64(skb, 428 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE, 429 cookie)) { 430 kfree_skb(skb); 431 return -EINVAL; 432 } 433 434 qal_devcfg_send_response((qdf_nbuf_t)skb); 435 436 return 0; 437 } 438 439 int wlan_cfg80211_spectral_scan_stop(struct wiphy *wiphy, 440 struct wlan_objmgr_pdev *pdev, 441 const void *data, 442 int data_len) 443 { 444 QDF_STATUS status; 445 446 status = wlan_stop_spectral_scan(pdev); 447 if (QDF_STATUS_SUCCESS != status) 448 return -EINVAL; 449 return 0; 450 } 451 452 int wlan_cfg80211_spectral_scan_get_config(struct wiphy *wiphy, 453 struct wlan_objmgr_pdev *pdev, 454 const void *data, 455 int data_len) 456 { 457 struct spectral_config config_buf; 458 uint32_t spectral_dbg_level; 459 struct sk_buff *skb; 460 461 wlan_spectral_get_config(pdev, &config_buf); 462 wlan_spectral_get_debug_level(pdev, &spectral_dbg_level); 463 464 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (21 * sizeof(u32)) + 465 NLA_HDRLEN + NLMSG_HDRLEN); 466 if (!skb) { 467 qdf_print(" reply skb alloc failed"); 468 return -ENOMEM; 469 } 470 471 if (nla_put_u32(skb, 472 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT, 473 config_buf.ss_count) || 474 nla_put_u32(skb, 475 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD, 476 config_buf.ss_period) || 477 nla_put_u32(skb, 478 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY, 479 config_buf.ss_spectral_pri) || 480 nla_put_u32(skb, 481 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE, 482 config_buf.ss_fft_size) || 483 nla_put_u32(skb, 484 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA, 485 config_buf.ss_gc_ena) || 486 nla_put_u32(skb, 487 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA, 488 config_buf.ss_restart_ena) || 489 nla_put_u32( 490 skb, 491 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF, 492 config_buf.ss_noise_floor_ref) || 493 nla_put_u32(skb, 494 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY, 495 config_buf.ss_init_delay) || 496 nla_put_u32(skb, 497 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR, 498 config_buf.ss_nb_tone_thr) || 499 nla_put_u32(skb, 500 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR, 501 config_buf.ss_str_bin_thr) || 502 nla_put_u32(skb, 503 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE, 504 config_buf.ss_wb_rpt_mode) || 505 nla_put_u32(skb, 506 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE, 507 config_buf.ss_rssi_rpt_mode) || 508 nla_put_u32(skb, 509 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR, 510 config_buf.ss_rssi_thr) || 511 nla_put_u32(skb, 512 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT, 513 config_buf.ss_pwr_format) || 514 nla_put_u32(skb, 515 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE, 516 config_buf.ss_rpt_mode) || 517 nla_put_u32(skb, 518 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE, 519 config_buf.ss_bin_scale) || 520 nla_put_u32(skb, 521 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ, 522 config_buf.ss_dbm_adj) || 523 nla_put_u32(skb, 524 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK, 525 config_buf.ss_chn_mask) || 526 nla_put_u32(skb, 527 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD, 528 config_buf.ss_fft_period) || 529 nla_put_u32(skb, 530 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT, 531 config_buf.ss_short_report) || 532 nla_put_u32(skb, 533 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL, 534 spectral_dbg_level)) { 535 kfree_skb(skb); 536 return -EINVAL; 537 } 538 qal_devcfg_send_response((qdf_nbuf_t)skb); 539 540 return 0; 541 } 542 543 int wlan_cfg80211_spectral_scan_get_cap(struct wiphy *wiphy, 544 struct wlan_objmgr_pdev *pdev, 545 const void *data, 546 int data_len) 547 { 548 struct spectral_caps spectral_cap; 549 struct sk_buff *skb; 550 551 wlan_spectral_get_cap(pdev, &spectral_cap); 552 553 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 10 * sizeof(u32) + 554 NLA_HDRLEN + NLMSG_HDRLEN); 555 if (!skb) { 556 qdf_print(" reply skb alloc failed"); 557 return -ENOMEM; 558 } 559 560 if (spectral_cap.phydiag_cap) 561 if (nla_put_flag( 562 skb, 563 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_PHYDIAG)) 564 goto fail; 565 566 if (spectral_cap.radar_cap) 567 if (nla_put_flag(skb, 568 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RADAR)) 569 goto fail; 570 571 if (spectral_cap.spectral_cap) 572 if (nla_put_flag( 573 skb, 574 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_SPECTRAL)) 575 goto fail; 576 577 if (spectral_cap.advncd_spectral_cap) 578 if (nla_put_flag( 579 skb, 580 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_ADVANCED_SPECTRAL)) 581 goto fail; 582 583 if (nla_put_u32(skb, 584 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN, 585 spectral_cap.hw_gen)) 586 goto fail; 587 588 if (spectral_cap.is_scaling_params_populated) { 589 if (nla_put_u16( 590 skb, 591 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID, 592 spectral_cap.formula_id)) 593 goto fail; 594 595 if (nla_put_u16( 596 skb, 597 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_LOW_LEVEL_OFFSET, 598 spectral_cap.low_level_offset)) 599 goto fail; 600 601 if (nla_put_u16( 602 skb, 603 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HIGH_LEVEL_OFFSET, 604 spectral_cap.high_level_offset)) 605 goto fail; 606 607 if (nla_put_u16( 608 skb, 609 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RSSI_THR, 610 spectral_cap.rssi_thr)) 611 goto fail; 612 613 if (nla_put_u8( 614 skb, 615 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN, 616 spectral_cap.default_agc_max_gain)) 617 goto fail; 618 } 619 620 qal_devcfg_send_response((qdf_nbuf_t)skb); 621 622 return 0; 623 624 fail: 625 kfree_skb(skb); 626 return -EINVAL; 627 } 628 629 int wlan_cfg80211_spectral_scan_get_diag_stats(struct wiphy *wiphy, 630 struct wlan_objmgr_pdev *pdev, 631 const void *data, 632 int data_len) 633 { 634 struct spectral_diag_stats spetcral_diag; 635 struct sk_buff *skb; 636 637 wlan_spectral_get_diag_stats(pdev, &spetcral_diag); 638 639 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 5 * sizeof(u64) + 640 NLA_HDRLEN + NLMSG_HDRLEN); 641 if (!skb) { 642 qdf_print(" reply skb alloc failed"); 643 return -ENOMEM; 644 } 645 646 if (wlan_cfg80211_nla_put_u64( 647 skb, 648 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SIG_MISMATCH, 649 spetcral_diag.spectral_mismatch) || 650 wlan_cfg80211_nla_put_u64( 651 skb, 652 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SEC80_SFFT_INSUFFLEN, 653 spetcral_diag.spectral_sec80_sfft_insufflen) || 654 wlan_cfg80211_nla_put_u64( 655 skb, 656 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_NOSEC80_SFFT, 657 spetcral_diag.spectral_no_sec80_sfft) || 658 wlan_cfg80211_nla_put_u64( 659 skb, 660 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG1ID_MISMATCH, 661 spetcral_diag.spectral_vhtseg1id_mismatch) || 662 wlan_cfg80211_nla_put_u64( 663 skb, 664 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG2ID_MISMATCH, 665 spetcral_diag.spectral_vhtseg2id_mismatch)) { 666 kfree_skb(skb); 667 return -EINVAL; 668 } 669 qal_devcfg_send_response((qdf_nbuf_t)skb); 670 671 return 0; 672 } 673 674 int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy, 675 struct wlan_objmgr_pdev *pdev, 676 const void *data, 677 int data_len) 678 { 679 struct spectral_scan_state sscan_state = { 0 }; 680 struct sk_buff *skb; 681 682 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 2 * sizeof(u32) + 683 NLA_HDRLEN + NLMSG_HDRLEN); 684 if (!skb) { 685 qdf_print(" reply skb alloc failed"); 686 return -ENOMEM; 687 } 688 689 wlan_spectral_scan_get_status(pdev, &sscan_state); 690 691 if (sscan_state.is_enabled) 692 if (nla_put_flag( 693 skb, 694 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ENABLED)) 695 goto fail; 696 697 if (sscan_state.is_active) 698 if (nla_put_flag( 699 skb, 700 QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ACTIVE)) 701 goto fail; 702 qal_devcfg_send_response((qdf_nbuf_t)skb); 703 return 0; 704 705 fail: 706 kfree_skb(skb); 707 return -EINVAL; 708 } 709