1 /* 2 * Copyright (c) 2011,2017-2018 The Linux Foundation. All rights reserved. 3 * 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <wlan_tgt_def_config.h> 21 #include <hif.h> 22 #include <target_type.h> 23 #include <hif_hw_version.h> 24 #include <wmi_unified_api.h> 25 #include <target_if_spectral.h> 26 #include <wlan_lmac_if_def.h> 27 #include <wlan_osif_priv.h> 28 #include <init_deinit_lmac.h> 29 #include <reg_services_public_struct.h> 30 #ifdef CONFIG_WIN 31 #include <wlan_mlme_dispatcher.h> 32 #endif /*CONFIG_WIN*/ 33 #include <reg_services_public_struct.h> 34 #include <target_if_spectral_sim.h> 35 #include <target_if.h> 36 #include <qdf_module.h> 37 /** 38 * @spectral_ops - Spectral function table, holds the Spectral functions that 39 * depend on whether the architecture is Direct Attach or Offload. This is used 40 * to populate the actual Spectral function table present in the Spectral 41 * module. 42 */ 43 struct target_if_spectral_ops spectral_ops; 44 int spectral_debug_level = DEBUG_SPECTRAL; 45 46 static void target_if_spectral_get_firstvdev_pdev(struct wlan_objmgr_pdev *pdev, 47 void *obj, void *arg) 48 { 49 struct wlan_objmgr_vdev *vdev = obj; 50 struct wlan_objmgr_vdev **first_vdev = arg; 51 52 if (!(*first_vdev)) 53 *first_vdev = vdev; 54 } 55 56 struct wlan_objmgr_vdev * 57 target_if_spectral_get_vdev(struct target_if_spectral *spectral) 58 { 59 struct wlan_objmgr_pdev *pdev = NULL; 60 struct wlan_objmgr_vdev *first_vdev = NULL; 61 62 qdf_assert_always(spectral); 63 pdev = spectral->pdev_obj; 64 qdf_assert_always(pdev); 65 66 if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_SPECTRAL_ID) != 67 QDF_STATUS_SUCCESS) { 68 spectral_err("Unable to get pdev reference."); 69 return NULL; 70 } 71 72 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 73 target_if_spectral_get_firstvdev_pdev, 74 &first_vdev, 0, WLAN_SPECTRAL_ID); 75 76 wlan_objmgr_pdev_release_ref(pdev, WLAN_SPECTRAL_ID); 77 78 if (wlan_objmgr_vdev_try_get_ref(first_vdev, WLAN_SPECTRAL_ID) != 79 QDF_STATUS_SUCCESS) 80 first_vdev = NULL; 81 82 if (!first_vdev) { 83 spectral_warn("Unable to get first vdev of pdev."); 84 return NULL; 85 } 86 87 return first_vdev; 88 } 89 90 /** 91 * target_if_send_vdev_spectral_configure_cmd() - Send WMI command to configure 92 * spectral parameters 93 * @spectral: Pointer to Spectral target_if internal private data 94 * @param: Pointer to spectral_config giving the Spectral configuration 95 * 96 * Return: QDF_STATUS_SUCCESS on success, negative error code on failure 97 */ 98 static int 99 target_if_send_vdev_spectral_configure_cmd(struct target_if_spectral *spectral, 100 struct spectral_config *param) 101 { 102 struct vdev_spectral_configure_params sparam; 103 struct wlan_objmgr_pdev *pdev = NULL; 104 struct wlan_objmgr_vdev *vdev = NULL; 105 106 qdf_assert_always(spectral && param); 107 108 pdev = spectral->pdev_obj; 109 110 qdf_assert_always(pdev); 111 112 vdev = target_if_spectral_get_vdev(spectral); 113 if (!vdev) 114 return QDF_STATUS_E_NOENT; 115 116 qdf_mem_set(&sparam, sizeof(sparam), 0); 117 118 sparam.vdev_id = wlan_vdev_get_id(vdev); 119 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 120 121 sparam.count = param->ss_count; 122 sparam.period = param->ss_period; 123 sparam.spectral_pri = param->ss_spectral_pri; 124 sparam.fft_size = param->ss_fft_size; 125 sparam.gc_enable = param->ss_gc_ena; 126 sparam.restart_enable = param->ss_restart_ena; 127 sparam.noise_floor_ref = param->ss_noise_floor_ref; 128 sparam.init_delay = param->ss_init_delay; 129 sparam.nb_tone_thr = param->ss_nb_tone_thr; 130 sparam.str_bin_thr = param->ss_str_bin_thr; 131 sparam.wb_rpt_mode = param->ss_wb_rpt_mode; 132 sparam.rssi_rpt_mode = param->ss_rssi_rpt_mode; 133 sparam.rssi_thr = param->ss_rssi_thr; 134 sparam.pwr_format = param->ss_pwr_format; 135 sparam.rpt_mode = param->ss_rpt_mode; 136 sparam.bin_scale = param->ss_bin_scale; 137 sparam.dbm_adj = param->ss_dbm_adj; 138 sparam.chn_mask = param->ss_chn_mask; 139 140 return spectral->param_wmi_cmd_ops.wmi_spectral_configure_cmd_send( 141 GET_WMI_HDL_FROM_PDEV(pdev), &sparam); 142 } 143 144 /** 145 * target_if_send_vdev_spectral_enable_cmd() - Send WMI command to 146 * enable/disable Spectral 147 * @spectral: Pointer to Spectral target_if internal private data 148 * @is_spectral_active_valid: Flag to indicate if spectral activate (trigger) is 149 * valid 150 * @is_spectral_active: Value of spectral activate 151 * @is_spectral_enabled_valid: Flag to indicate if spectral enable is valid 152 * @is_spectral_enabled: Value of spectral enable 153 * 154 * Return: QDF_STATUS_SUCCESS on success, negative error code on failure 155 */ 156 static int 157 target_if_send_vdev_spectral_enable_cmd(struct target_if_spectral *spectral, 158 uint8_t is_spectral_active_valid, 159 uint8_t is_spectral_active, 160 uint8_t is_spectral_enabled_valid, 161 uint8_t is_spectral_enabled) 162 { 163 struct vdev_spectral_enable_params param; 164 struct wlan_objmgr_pdev *pdev = NULL; 165 struct wlan_objmgr_vdev *vdev = NULL; 166 167 qdf_assert_always(spectral); 168 169 pdev = spectral->pdev_obj; 170 171 qdf_assert_always(pdev); 172 173 vdev = target_if_spectral_get_vdev(spectral); 174 if (!vdev) 175 return QDF_STATUS_E_NOENT; 176 177 qdf_mem_set(¶m, sizeof(param), 0); 178 179 param.vdev_id = wlan_vdev_get_id(vdev); 180 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 181 182 param.active_valid = is_spectral_active_valid; 183 param.enabled_valid = is_spectral_enabled_valid; 184 param.active = is_spectral_active; 185 param.enabled = is_spectral_enabled; 186 187 return spectral->param_wmi_cmd_ops.wmi_spectral_enable_cmd_send( 188 GET_WMI_HDL_FROM_PDEV(pdev), ¶m); 189 } 190 191 /** 192 * target_if_spectral_info_init_defaults() - Helper function to load defaults 193 * for Spectral information (parameters and state) into cache. 194 * @spectral: Pointer to Spectral target_if internal private data 195 * 196 * It is assumed that the caller has obtained the requisite lock if applicable. 197 * Note that this is currently treated as a temporary function. Ideally, we 198 * would like to get defaults from the firmware. 199 * 200 * Return: QDF_STATUS_SUCCESS on success, negative error code on failure 201 */ 202 static int 203 target_if_spectral_info_init_defaults(struct target_if_spectral *spectral) 204 { 205 struct target_if_spectral_param_state_info *info = 206 &spectral->param_info; 207 struct wlan_objmgr_vdev *vdev = NULL; 208 209 /* State */ 210 info->osps_cache.osc_spectral_active = SPECTRAL_SCAN_ACTIVE_DEFAULT; 211 212 info->osps_cache.osc_spectral_enabled = SPECTRAL_SCAN_ENABLE_DEFAULT; 213 214 /* Parameters */ 215 info->osps_cache.osc_params.ss_count = SPECTRAL_SCAN_COUNT_DEFAULT; 216 217 if (spectral->spectral_gen == SPECTRAL_GEN3) 218 info->osps_cache.osc_params.ss_period = 219 SPECTRAL_SCAN_PERIOD_GEN_III_DEFAULT; 220 else 221 info->osps_cache.osc_params.ss_period = 222 SPECTRAL_SCAN_PERIOD_GEN_II_DEFAULT; 223 224 info->osps_cache.osc_params.ss_spectral_pri = 225 SPECTRAL_SCAN_PRIORITY_DEFAULT; 226 227 info->osps_cache.osc_params.ss_fft_size = 228 SPECTRAL_SCAN_FFT_SIZE_DEFAULT; 229 230 info->osps_cache.osc_params.ss_gc_ena = SPECTRAL_SCAN_GC_ENA_DEFAULT; 231 232 info->osps_cache.osc_params.ss_restart_ena = 233 SPECTRAL_SCAN_RESTART_ENA_DEFAULT; 234 235 info->osps_cache.osc_params.ss_noise_floor_ref = 236 SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT; 237 238 info->osps_cache.osc_params.ss_init_delay = 239 SPECTRAL_SCAN_INIT_DELAY_DEFAULT; 240 241 info->osps_cache.osc_params.ss_nb_tone_thr = 242 SPECTRAL_SCAN_NB_TONE_THR_DEFAULT; 243 244 info->osps_cache.osc_params.ss_str_bin_thr = 245 SPECTRAL_SCAN_STR_BIN_THR_DEFAULT; 246 247 info->osps_cache.osc_params.ss_wb_rpt_mode = 248 SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT; 249 250 info->osps_cache.osc_params.ss_rssi_rpt_mode = 251 SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT; 252 253 info->osps_cache.osc_params.ss_rssi_thr = 254 SPECTRAL_SCAN_RSSI_THR_DEFAULT; 255 256 info->osps_cache.osc_params.ss_pwr_format = 257 SPECTRAL_SCAN_PWR_FORMAT_DEFAULT; 258 259 info->osps_cache.osc_params.ss_rpt_mode = 260 SPECTRAL_SCAN_RPT_MODE_DEFAULT; 261 262 info->osps_cache.osc_params.ss_bin_scale = 263 SPECTRAL_SCAN_BIN_SCALE_DEFAULT; 264 265 info->osps_cache.osc_params.ss_dbm_adj = SPECTRAL_SCAN_DBM_ADJ_DEFAULT; 266 267 vdev = target_if_spectral_get_vdev(spectral); 268 if (!vdev) 269 return QDF_STATUS_E_NOENT; 270 271 info->osps_cache.osc_params.ss_chn_mask = 272 wlan_vdev_mlme_get_rxchainmask(vdev); 273 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 274 275 /* The cache is now valid */ 276 info->osps_cache.osc_is_valid = 1; 277 278 return QDF_STATUS_SUCCESS; 279 } 280 281 #ifdef OL_SPECTRAL_DEBUG_CONFIG_INTERACTIONS 282 /** 283 * target_if_log_read_spectral_active() - Helper function to log whether 284 * spectral is active after reading cache 285 * @function_name: Function name 286 * @output: whether spectral is active or not 287 * 288 * Helper function to log whether spectral is active after reading cache 289 * 290 * Return: none 291 */ 292 static void 293 target_if_log_read_spectral_active( 294 const char *function_name, 295 unsigned char output) 296 { 297 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_ACTIVE. Returning val=%u", 298 function_name, output); 299 } 300 301 /** 302 * target_if_log_read_spectral_enabled() - Helper function to log whether 303 * spectral is enabled after reading cache 304 * @function_name: Function name 305 * @output: whether spectral is enabled or not 306 * 307 * Helper function to log whether spectral is enabled after reading cache 308 * 309 * Return: none 310 */ 311 static void 312 target_if_log_read_spectral_enabled( 313 const char *function_name, 314 unsigned char output) 315 { 316 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_ENABLED. Returning val=%u", 317 function_name, output); 318 } 319 320 /** 321 * target_if_log_read_spectral_enabled() - Helper function to log spectral 322 * parameters after reading cache 323 * @function_name: Function name 324 * @pparam: Spectral parameters 325 * 326 * Helper function to log spectral parameters after reading cache 327 * 328 * Return: none 329 */ 330 static void 331 target_if_log_read_spectral_params( 332 const char *function_name, 333 struct spectral_config *pparam) 334 { 335 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Returning following params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\n", 336 function_name, 337 pparam->ss_count, 338 pparam->ss_period, 339 pparam->ss_spectral_pri, 340 pparam->ss_fft_size, 341 pparam->ss_gc_ena, 342 pparam->ss_restart_ena, 343 (int8_t)pparam->ss_noise_floor_ref, 344 pparam->ss_init_delay, 345 pparam->ss_nb_tone_thr, 346 pparam->ss_str_bin_thr, 347 pparam->ss_wb_rpt_mode, 348 pparam->ss_rssi_rpt_mode, 349 (int8_t)pparam->ss_rssi_thr, 350 pparam->ss_pwr_format, 351 pparam->ss_rpt_mode, 352 pparam->ss_bin_scale, 353 pparam->ss_dbm_adj, 354 pparam->ss_chn_mask); 355 } 356 357 /** 358 * target_if_log_read_spectral_active_catch_validate() - Helper function to 359 * log whether spectral is active after intializing the cache 360 * @function_name: Function name 361 * @output: whether spectral is active or not 362 * 363 * Helper function to log whether spectral is active after intializing cache 364 * 365 * Return: none 366 */ 367 static void 368 target_if_log_read_spectral_active_catch_validate( 369 const char *function_name, 370 unsigned char output) 371 { 372 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_ACTIVE on initial cache validation\nReturning val=%u", 373 function_name, output); 374 } 375 376 /** 377 * target_if_log_read_spectral_enabled_catch_validate() - Helper function to 378 * log whether spectral is enabled after intializing the cache 379 * @function_name: Function name 380 * @output: whether spectral is enabled or not 381 * 382 * Helper function to log whether spectral is enabled after intializing cache 383 * 384 * Return: none 385 */ 386 static void 387 target_if_log_read_spectral_enabled_catch_validate( 388 const char *function_name, 389 unsigned char output) 390 { 391 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_ENABLED on initial cache validation\nReturning val=%u\n", 392 function_name, output); 393 } 394 395 /** 396 * target_if_log_read_spectral_params_catch_validate() - Helper function to 397 * log spectral parameters after intializing the cache 398 * @function_name: Function name 399 * @pparam: Spectral parameters 400 * 401 * Helper function to log spectral parameters after intializing the cache 402 * 403 * Return: none 404 */ 405 static void 406 target_if_log_read_spectral_params_catch_validate( 407 const char *function_name, 408 struct spectral_config *pparam) 409 { 410 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS on initial cache validation\nReturning following params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u", 411 function_name, 412 pparam->ss_count, 413 pparam->ss_period, 414 pparam->ss_spectral_pri, 415 pparam->ss_fft_size, 416 pparam->ss_gc_ena, 417 pparam->ss_restart_ena, 418 (int8_t)pparam->ss_noise_floor_ref, 419 pparam->ss_init_delay, 420 pparam->ss_nb_tone_thr, 421 pparam->ss_str_bin_thr, 422 pparam->ss_wb_rpt_mode, 423 pparam->ss_rssi_rpt_mode, 424 (int8_t)pparam->ss_rssi_thr, 425 pparam->ss_pwr_format, 426 pparam->ss_rpt_mode, 427 pparam->ss_bin_scale, 428 pparam->ss_dbm_adj, pparam->ss_chn_mask); 429 } 430 431 #else 432 static void 433 target_if_log_read_spectral_active( 434 const char *function_name, 435 unsigned char output) 436 { 437 } 438 439 static void 440 target_if_log_read_spectral_enabled( 441 const char *function_name, 442 unsigned char output) 443 { 444 } 445 446 static void 447 target_if_log_read_spectral_params( 448 const char *function_name, 449 struct spectral_config *pparam) 450 { 451 } 452 453 static void 454 target_if_log_read_spectral_active_catch_validate( 455 const char *function_name, 456 unsigned char output) 457 { 458 } 459 460 static void 461 target_if_log_read_spectral_enabled_catch_validate( 462 const char *function_name, 463 unsigned char output) 464 { 465 } 466 467 static void 468 target_if_log_read_spectral_params_catch_validate( 469 const char *function_name, 470 struct spectral_config *pparam) 471 { 472 } 473 #endif 474 475 /** 476 * target_if_spectral_info_read() - Read spectral information from the cache. 477 * @spectral: Pointer to Spectral target_if internal private data 478 * @specifier: target_if_spectral_info enumeration specifying which 479 * information is required 480 * @output: Void output pointer into which the information will be read 481 * @output_len: size of object pointed to by output pointer 482 * 483 * Read spectral parameters or the desired state information from the cache. 484 * 485 * Return: 0 on success, negative error code on failure 486 */ 487 static int 488 target_if_spectral_info_read( 489 struct target_if_spectral *spectral, 490 enum target_if_spectral_info specifier, 491 void *output, int output_len) 492 { 493 /* 494 * Note: This function is designed to be able to accommodate 495 * WMI reads for defaults, non-cacheable information, etc 496 * if required. 497 */ 498 struct target_if_spectral_param_state_info *info = 499 &spectral->param_info; 500 int is_cacheable = 0; 501 int init_def_retval = 0; 502 503 if (!output) 504 return -EINVAL; 505 506 switch (specifier) { 507 case TARGET_IF_SPECTRAL_INFO_ACTIVE: 508 if (output_len != sizeof(info->osps_cache.osc_spectral_active)) 509 return -EINVAL; 510 is_cacheable = 1; 511 break; 512 513 case TARGET_IF_SPECTRAL_INFO_ENABLED: 514 if (output_len != sizeof(info->osps_cache.osc_spectral_enabled)) 515 return -EINVAL; 516 is_cacheable = 1; 517 break; 518 519 case TARGET_IF_SPECTRAL_INFO_PARAMS: 520 if (output_len != sizeof(info->osps_cache.osc_params)) 521 return -EINVAL; 522 is_cacheable = 1; 523 break; 524 525 default: 526 spectral_err("Unknown target_if_spectral_info specifier"); 527 return -EINVAL; 528 } 529 530 qdf_spin_lock(&info->osps_lock); 531 532 if (is_cacheable) { 533 if (info->osps_cache.osc_is_valid) { 534 switch (specifier) { 535 case TARGET_IF_SPECTRAL_INFO_ACTIVE: 536 qdf_mem_copy( 537 output, 538 &info->osps_cache.osc_spectral_active, 539 sizeof(info->osps_cache.osc_spectral_active)); 540 541 target_if_log_read_spectral_active( 542 __func__, 543 *((unsigned char *)output)); 544 break; 545 546 case TARGET_IF_SPECTRAL_INFO_ENABLED: 547 qdf_mem_copy( 548 output, 549 &info->osps_cache.osc_spectral_enabled, 550 sizeof( 551 info->osps_cache.osc_spectral_enabled)); 552 553 target_if_log_read_spectral_enabled( 554 __func__, 555 *((unsigned char *)output)); 556 break; 557 558 case TARGET_IF_SPECTRAL_INFO_PARAMS: 559 qdf_mem_copy( 560 output, 561 &info->osps_cache.osc_params, 562 sizeof(info->osps_cache.osc_params)); 563 564 target_if_log_read_spectral_params( 565 __func__, 566 (struct spectral_config *)output); 567 break; 568 569 default: 570 /* We can't reach this point */ 571 break; 572 } 573 qdf_spin_unlock(&info->osps_lock); 574 return 0; 575 } 576 } 577 578 /* Cache is invalid */ 579 580 /* 581 * If WMI Reads are implemented to fetch defaults/non-cacheable info, 582 * then the below implementation will change 583 */ 584 init_def_retval = target_if_spectral_info_init_defaults(spectral); 585 if (init_def_retval != QDF_STATUS_SUCCESS) { 586 qdf_spin_unlock(&info->osps_lock); 587 if (init_def_retval == QDF_STATUS_E_NOENT) 588 return -ENOENT; 589 else 590 return -EINVAL; 591 } 592 /* target_if_spectral_info_init_defaults() has set cache to valid */ 593 594 switch (specifier) { 595 case TARGET_IF_SPECTRAL_INFO_ACTIVE: 596 qdf_mem_copy(output, 597 &info->osps_cache.osc_spectral_active, 598 sizeof(info->osps_cache.osc_spectral_active)); 599 600 target_if_log_read_spectral_active_catch_validate( 601 __func__, 602 *((unsigned char *)output)); 603 break; 604 605 case TARGET_IF_SPECTRAL_INFO_ENABLED: 606 qdf_mem_copy(output, 607 &info->osps_cache.osc_spectral_enabled, 608 sizeof(info->osps_cache.osc_spectral_enabled)); 609 610 target_if_log_read_spectral_enabled_catch_validate( 611 __func__, 612 *((unsigned char *)output)); 613 break; 614 615 case TARGET_IF_SPECTRAL_INFO_PARAMS: 616 qdf_mem_copy(output, 617 &info->osps_cache.osc_params, 618 sizeof(info->osps_cache.osc_params)); 619 620 target_if_log_read_spectral_params_catch_validate( 621 __func__, 622 (struct spectral_config *)output); 623 624 break; 625 626 default: 627 /* We can't reach this point */ 628 break; 629 } 630 631 qdf_spin_unlock(&info->osps_lock); 632 633 return 0; 634 } 635 636 #ifdef OL_SPECTRAL_DEBUG_CONFIG_INTERACTIONS 637 /** 638 * target_if_log_write_spectral_active() - Helper function to log inputs and 639 * return value of call to configure the Spectral 'active' configuration, 640 * TARGET_IF_SPECTRAL_INFO_ACTIVE into firmware 641 * @function_name: Function name in which this is called 642 * @pval: whether spectral is active or not 643 * @ret: return value of the firmware write function 644 * 645 * Return: none 646 */ 647 static void 648 target_if_log_write_spectral_active( 649 const char *function_name, 650 uint8_t pval, 651 int ret) 652 { 653 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_ACTIVE with val=%u status=%d", 654 function_name, pval, ret); 655 } 656 657 /** 658 * target_if_log_write_spectral_enabled() - Helper function to log inputs and 659 * return value of call to configure the Spectral 'enabled' configuration, 660 * TARGET_IF_SPECTRAL_INFO_ENABLED into firmware 661 * @function_name: Function name in which this is called 662 * @pval: whether spectral is enabled or not 663 * @ret: return value of the firmware write function 664 * 665 * Return: none 666 */ 667 static void 668 target_if_log_write_spectral_enabled( 669 const char *function_name, 670 uint8_t pval, 671 int ret) 672 { 673 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_ENABLED with val=%u status=%d", 674 function_name, pval, ret); 675 } 676 677 /** 678 * target_if_log_write_spectral_params() - Helper function to log inputs and 679 * return value of call to configure Spectral parameters, 680 * TARGET_IF_SPECTRAL_INFO_PARAMS into firmware 681 * @param: Spectral parameters 682 * @function_name: Function name in which this is called 683 * @ret: return value of the firmware write function 684 * 685 * Return: none 686 */ 687 static void 688 target_if_log_write_spectral_params( 689 struct spectral_config *param, 690 const char *function_name, 691 int ret) 692 { 693 spectral_debug("%s: TARGET_IF_SPECTRAL_INFO_PARAMS. Params:\nss_count = %u\nss_period = %u\nss_spectral_pri = %u\nss_fft_size = %u\nss_gc_ena = %u\nss_restart_ena = %u\nss_noise_floor_ref = %d\nss_init_delay = %u\nss_nb_tone_thr = %u\nss_str_bin_thr = %u\nss_wb_rpt_mode = %u\nss_rssi_rpt_mode = %u\nss_rssi_thr = %d\nss_pwr_format = %u\nss_rpt_mode = %u\nss_bin_scale = %u\nss_dbm_adj = %u\nss_chn_mask = %u\nstatus = %d", 694 function_name, 695 param->ss_count, 696 param->ss_period, 697 param->ss_spectral_pri, 698 param->ss_fft_size, 699 param->ss_gc_ena, 700 param->ss_restart_ena, 701 (int8_t)param->ss_noise_floor_ref, 702 param->ss_init_delay, 703 param->ss_nb_tone_thr, 704 param->ss_str_bin_thr, 705 param->ss_wb_rpt_mode, 706 param->ss_rssi_rpt_mode, 707 (int8_t)param->ss_rssi_thr, 708 param->ss_pwr_format, 709 param->ss_rpt_mode, 710 param->ss_bin_scale, 711 param->ss_dbm_adj, param->ss_chn_mask, ret); 712 } 713 #else 714 static void 715 target_if_log_write_spectral_active( 716 const char *function_name, 717 uint8_t pval, 718 int ret) 719 { 720 } 721 722 static void 723 target_if_log_write_spectral_enabled( 724 const char *function_name, 725 uint8_t pval, 726 int ret) 727 { 728 } 729 730 static void 731 target_if_log_write_spectral_params( 732 struct spectral_config *param, 733 const char *function_name, 734 int ret) 735 { 736 } 737 738 #endif 739 740 /** 741 * target_if_spectral_info_write() - Write Spectral information to the 742 * firmware, and update cache 743 * @spectral: Pointer to Spectral target_if internal private data 744 * @specifier: target_if_spectral_info enumeration specifying which 745 * information is involved 746 * @input: void input pointer containing the information to be written 747 * @input_len: size of object pointed to by input pointer 748 * 749 * Write Spectral parameters or the desired state information to 750 * the firmware, and update cache 751 * 752 * Return: 0 on success, negative error code on failure 753 */ 754 static int 755 target_if_spectral_info_write( 756 struct target_if_spectral *spectral, 757 enum target_if_spectral_info specifier, 758 void *input, int input_len) 759 { 760 struct target_if_spectral_param_state_info *info = 761 &spectral->param_info; 762 int ret; 763 uint8_t *pval = NULL; 764 struct spectral_config *param = NULL; 765 766 if (!input) 767 return -EINVAL; 768 769 switch (specifier) { 770 case TARGET_IF_SPECTRAL_INFO_ACTIVE: 771 if (input_len != sizeof(info->osps_cache.osc_spectral_active)) 772 return -EINVAL; 773 774 pval = (uint8_t *)input; 775 776 qdf_spin_lock(&info->osps_lock); 777 ret = target_if_send_vdev_spectral_enable_cmd(spectral, 778 1, *pval, 0, 0); 779 780 target_if_log_write_spectral_active( 781 __func__, 782 *pval, 783 ret); 784 785 if (ret < 0) { 786 spectral_err("target_if_send_vdev_spectral_enable_cmd failed with error=%d", 787 ret); 788 qdf_spin_unlock(&info->osps_lock); 789 return ret; 790 } 791 792 info->osps_cache.osc_spectral_active = *pval; 793 794 /* The cache is now valid */ 795 info->osps_cache.osc_is_valid = 1; 796 797 qdf_spin_unlock(&info->osps_lock); 798 break; 799 800 case TARGET_IF_SPECTRAL_INFO_ENABLED: 801 if (input_len != sizeof(info->osps_cache.osc_spectral_enabled)) 802 return -EINVAL; 803 804 pval = (uint8_t *)input; 805 806 qdf_spin_lock(&info->osps_lock); 807 ret = target_if_send_vdev_spectral_enable_cmd(spectral, 808 0, 0, 1, *pval); 809 810 target_if_log_write_spectral_enabled( 811 __func__, 812 *pval, 813 ret); 814 815 if (ret < 0) { 816 spectral_err("target_if_send_vdev_spectral_enable_cmd failed with error=%d", 817 ret); 818 qdf_spin_unlock(&info->osps_lock); 819 return ret; 820 } 821 822 info->osps_cache.osc_spectral_enabled = *pval; 823 824 /* The cache is now valid */ 825 info->osps_cache.osc_is_valid = 1; 826 827 qdf_spin_unlock(&info->osps_lock); 828 break; 829 830 case TARGET_IF_SPECTRAL_INFO_PARAMS: 831 if (input_len != sizeof(info->osps_cache.osc_params)) 832 return -EINVAL; 833 834 param = (struct spectral_config *)input; 835 836 qdf_spin_lock(&info->osps_lock); 837 ret = target_if_send_vdev_spectral_configure_cmd(spectral, 838 param); 839 840 target_if_log_write_spectral_params( 841 param, 842 __func__, 843 ret); 844 845 if (ret < 0) { 846 spectral_err("target_if_send_vdev_spectral_configure_cmd failed with error=%d", 847 ret); 848 qdf_spin_unlock(&info->osps_lock); 849 return ret; 850 } 851 852 qdf_mem_copy(&info->osps_cache.osc_params, 853 param, sizeof(info->osps_cache.osc_params)); 854 855 /* The cache is now valid */ 856 info->osps_cache.osc_is_valid = 1; 857 858 qdf_spin_unlock(&info->osps_lock); 859 break; 860 861 default: 862 spectral_err("Unknown target_if_spectral_info specifier"); 863 return -EINVAL; 864 } 865 866 return 0; 867 } 868 869 /** 870 * target_if_spectral_get_tsf64() - Function to get the TSF value 871 * @arg: Pointer to handle for Spectral target_if internal private data 872 * 873 * Get the last TSF received in WMI buffer 874 * 875 * Return: TSF value 876 */ 877 static uint64_t 878 target_if_spectral_get_tsf64(void *arg) 879 { 880 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 881 882 return spectral->tsf64; 883 } 884 885 /** 886 * target_if_spectral_get_capability() - Function to get whether a 887 * given Spectral hardware capability is available 888 * @arg: Pointer to handle for Spectral target_if internal private data 889 * @type: Spectral hardware capability type 890 * 891 * Get whether a given Spectral hardware capability is available 892 * 893 * Return: True if the capability is available, false if the capability is not 894 * available 895 */ 896 uint32_t 897 target_if_spectral_get_capability(void *arg, enum spectral_capability_type type) 898 { 899 int status = STATUS_FAIL; 900 901 switch (type) { 902 case SPECTRAL_CAP_PHYDIAG: 903 case SPECTRAL_CAP_RADAR: 904 case SPECTRAL_CAP_SPECTRAL_SCAN: 905 case SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN: 906 status = STATUS_PASS; 907 break; 908 default: 909 status = STATUS_FAIL; 910 } 911 return status; 912 } 913 914 /** 915 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 916 * @arg: Pointer to handle for Spectral target_if internal private data 917 * @rxfilter: Rx filter to be used 918 * 919 * Note: This is only a placeholder function. It is not currently required since 920 * FW should be taking care of setting the required filters. 921 * 922 * Return: 0 923 */ 924 uint32_t 925 target_if_spectral_set_rxfilter(void *arg, int rxfilter) 926 { 927 /* 928 * Will not be required since enabling of spectral in firmware 929 * will take care of this 930 */ 931 return 0; 932 } 933 934 /** 935 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 936 * @arg: Pointer to handle for Spectral target_if internal private data 937 * 938 * Note: This is only a placeholder function. It is not currently required since 939 * FW should be taking care of setting the required filters. 940 * 941 * Return: 0 942 */ 943 uint32_t 944 target_if_spectral_get_rxfilter(void *arg) 945 { 946 /* 947 * Will not be required since enabling of spectral in firmware 948 * will take care of this 949 */ 950 return 0; 951 } 952 953 /** 954 * target_if_sops_is_spectral_active() - Get whether Spectral is active 955 * @arg: Pointer to handle for Spectral target_if internal private data 956 * 957 * Function to check whether Spectral is active 958 * 959 * Return: True if Spectral is active, false if Spectral is not active 960 */ 961 uint32_t 962 target_if_sops_is_spectral_active(void *arg) 963 { 964 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 965 uint8_t val = 0; 966 int ret; 967 968 ret = target_if_spectral_info_read( 969 spectral, 970 TARGET_IF_SPECTRAL_INFO_ACTIVE, 971 &val, sizeof(val)); 972 973 if (ret != 0) { 974 /* 975 * Could not determine if Spectral is active. 976 * Return false as a safe value. 977 * XXX: Consider changing the function prototype 978 * to be able to indicate failure to fetch value. 979 */ 980 return 0; 981 } 982 983 return val; 984 } 985 986 /** 987 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 988 * @arg: Pointer to handle for Spectral target_if internal private data 989 * 990 * Function to check whether Spectral is enabled 991 * 992 * Return: True if Spectral is enabled, false if Spectral is not enabled 993 */ 994 uint32_t 995 target_if_sops_is_spectral_enabled(void *arg) 996 { 997 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 998 uint8_t val = 0; 999 int ret; 1000 1001 ret = target_if_spectral_info_read( 1002 spectral, 1003 TARGET_IF_SPECTRAL_INFO_ENABLED, 1004 &val, sizeof(val)); 1005 1006 if (ret != 0) { 1007 /* 1008 * Could not determine if Spectral is enabled. 1009 * Return false as a safe value. 1010 * XXX: Consider changing the function prototype 1011 * to be able to indicate failure to fetch value. 1012 */ 1013 return 0; 1014 } 1015 1016 return val; 1017 } 1018 1019 /** 1020 * target_if_sops_start_spectral_scan() - Start Spectral scan 1021 * @arg: Pointer to handle for Spectral target_if internal private data 1022 * 1023 * Function to start spectral scan 1024 * 1025 * Return: 0 on success else failure 1026 */ 1027 uint32_t 1028 target_if_sops_start_spectral_scan(void *arg) 1029 { 1030 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 1031 uint8_t val = 1; 1032 uint8_t enabled = 0; 1033 int ret; 1034 1035 ret = target_if_spectral_info_read( 1036 spectral, 1037 TARGET_IF_SPECTRAL_INFO_ENABLED, 1038 &enabled, sizeof(enabled)); 1039 1040 if (ret != 0) { 1041 /* 1042 * Could not determine if Spectral is enabled. Assume we need 1043 * to enable it 1044 */ 1045 enabled = 0; 1046 } 1047 1048 if (!enabled) { 1049 ret = target_if_spectral_info_write( 1050 spectral, 1051 TARGET_IF_SPECTRAL_INFO_ENABLED, 1052 &val, sizeof(val)); 1053 1054 if (ret != 0) 1055 return ret; 1056 } 1057 1058 ret = target_if_spectral_info_write( 1059 spectral, 1060 TARGET_IF_SPECTRAL_INFO_ACTIVE, 1061 &val, sizeof(val)); 1062 1063 if (ret != 0) 1064 return ret; 1065 1066 return 0; 1067 } 1068 1069 /** 1070 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 1071 * @arg: Pointer to handle for Spectral target_if internal private data 1072 * 1073 * Function to stop spectral scan 1074 * 1075 * Return: 0 on success else failure 1076 */ 1077 uint32_t 1078 target_if_sops_stop_spectral_scan(void *arg) 1079 { 1080 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 1081 uint8_t val = 0; 1082 int tempret, ret = 0; 1083 1084 tempret = target_if_spectral_info_write( 1085 spectral, 1086 TARGET_IF_SPECTRAL_INFO_ACTIVE, 1087 &val, sizeof(val)); 1088 1089 if (tempret != 0) 1090 ret = tempret; 1091 1092 tempret = target_if_spectral_info_write( 1093 spectral, 1094 TARGET_IF_SPECTRAL_INFO_ENABLED, 1095 &val, sizeof(val)); 1096 1097 if (tempret != 0) 1098 ret = tempret; 1099 1100 return ret; 1101 } 1102 1103 /** 1104 * target_if_spectral_get_extension_channel() - Get the Extension channel 1105 * @arg: Pointer to handle for Spectral target_if internal private data 1106 * 1107 * Function to get the current Extension channel (in MHz) 1108 * 1109 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 1110 * extension channel is not present. 1111 */ 1112 uint32_t 1113 target_if_spectral_get_extension_channel(void *arg) 1114 { 1115 /* 1116 * XXX: Once we expand to use cases where Spectral could be activated 1117 * without a channel being set to VDEV, we need to consider returning a 1118 * negative value in case of failure and having all callers handle this. 1119 */ 1120 1121 struct target_if_spectral *spectral = NULL; 1122 struct wlan_objmgr_vdev *vdev = NULL; 1123 uint16_t sec20chan_freq = 0; 1124 1125 qdf_assert_always(arg); 1126 spectral = (struct target_if_spectral *)arg; 1127 1128 vdev = target_if_spectral_get_vdev(spectral); 1129 if (!vdev) 1130 return 0; 1131 1132 if (target_if_vdev_get_sec20chan_freq_mhz(vdev, &sec20chan_freq) < 0) { 1133 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 1134 return 0; 1135 } 1136 1137 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 1138 1139 return sec20chan_freq; 1140 } 1141 1142 /** 1143 * target_if_spectral_get_current_channel() - Get the current channel 1144 * @arg: Pointer to handle for Spectral target_if internal private data 1145 * 1146 * Function to get the current channel (in MHz) 1147 * 1148 * Return: Current channel (in MHz) on success, 0 on failure 1149 */ 1150 uint32_t 1151 target_if_spectral_get_current_channel(void *arg) 1152 { 1153 /* 1154 * XXX: Once we expand to use cases where Spectral could be activated 1155 * without a channel being set to VDEV, we need to consider returning a 1156 * negative value in case of failure and having all callers handle this. 1157 */ 1158 1159 struct target_if_spectral *spectral = NULL; 1160 int16_t chan_freq = 0; 1161 struct wlan_objmgr_vdev *vdev = NULL; 1162 1163 qdf_assert_always(arg); 1164 spectral = (struct target_if_spectral *)arg; 1165 1166 vdev = target_if_spectral_get_vdev(spectral); 1167 if (!vdev) 1168 return 0; 1169 1170 chan_freq = target_if_vdev_get_chan_freq(vdev); 1171 if (chan_freq < 0) { 1172 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 1173 return 0; 1174 } 1175 1176 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 1177 1178 return chan_freq; 1179 } 1180 1181 /** 1182 * target_if_spectral_reset_hw() - Reset the hardware 1183 * @arg: Pointer to handle for Spectral target_if internal private data 1184 * 1185 * This is only a placeholder since it is not currently required in the offload 1186 * case. 1187 * 1188 * Return: 0 1189 */ 1190 uint32_t 1191 target_if_spectral_reset_hw(void *arg) 1192 { 1193 not_yet_implemented(); 1194 return 0; 1195 } 1196 1197 /** 1198 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 1199 * Noisefloor history buffer 1200 * @arg: Pointer to handle for Spectral target_if internal private data 1201 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 1202 * 1203 * This is only a placeholder since it is not currently required in the offload 1204 * case. 1205 * 1206 * Return: 0 1207 */ 1208 uint32_t 1209 target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf) 1210 { 1211 not_yet_implemented(); 1212 return 0; 1213 } 1214 1215 /** 1216 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 1217 * noisefloor 1218 * @arg: Pointer to handle for Spectral target_if internal private data 1219 * 1220 * This is only a placeholder since it is not currently required in the offload 1221 * case. 1222 * 1223 * Return: 0 1224 */ 1225 int8_t 1226 target_if_spectral_get_ext_noisefloor(void *arg) 1227 { 1228 not_yet_implemented(); 1229 return 0; 1230 } 1231 1232 /** 1233 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 1234 * @arg: Pointer to handle for Spectral target_if internal private data 1235 * 1236 * This is only a placeholder since it is not currently required in the offload 1237 * case. 1238 * 1239 * Return: 0 1240 */ 1241 int8_t 1242 target_if_spectral_get_ctl_noisefloor(void *arg) 1243 { 1244 not_yet_implemented(); 1245 return 0; 1246 } 1247 1248 /** 1249 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 1250 * parameters 1251 * @arg: Pointer to handle for Spectral target_if internal private data 1252 * @params: Spectral parameters 1253 * 1254 * Function to configure spectral parameters 1255 * 1256 * Return: 0 on success else failure 1257 */ 1258 uint32_t 1259 target_if_spectral_sops_configure_params( 1260 void *arg, struct spectral_config *params) 1261 { 1262 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 1263 1264 return target_if_spectral_info_write( 1265 spectral, 1266 TARGET_IF_SPECTRAL_INFO_PARAMS, 1267 params, sizeof(*params)); 1268 } 1269 1270 /** 1271 * target_if_spectral_sops_get_params() - Get user configured Spectral 1272 * parameters 1273 * @arg: Pointer to handle for Spectral target_if internal private data 1274 * @params: Pointer to buffer into which Spectral parameters should be copied 1275 * 1276 * Function to get the configured spectral parameters 1277 * 1278 * Return: 0 on success else failure 1279 */ 1280 uint32_t 1281 target_if_spectral_sops_get_params(void *arg, struct spectral_config *params) 1282 { 1283 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 1284 1285 return target_if_spectral_info_read( 1286 spectral, 1287 TARGET_IF_SPECTRAL_INFO_PARAMS, 1288 params, sizeof(*params)); 1289 } 1290 1291 /** 1292 * target_if_spectral_get_ent_mask() - Get enterprise mask 1293 * @arg: Pointer to handle for Spectral target_if internal private data 1294 * 1295 * This is only a placeholder since it is not currently required in the offload 1296 * case. 1297 * 1298 * Return: 0 1299 */ 1300 static uint32_t 1301 target_if_spectral_get_ent_mask(void *arg) 1302 { 1303 not_yet_implemented(); 1304 return 0; 1305 } 1306 1307 /** 1308 * target_if_spectral_get_macaddr() - Get radio MAC address 1309 * @arg: Pointer to handle for Spectral target_if internal private data 1310 * @addr: Pointer to buffer into which MAC address should be copied 1311 * 1312 * Function to get the MAC address of the pdev 1313 * 1314 * Return: 0 on success, -1 on failure 1315 */ 1316 static uint32_t 1317 target_if_spectral_get_macaddr(void *arg, char *addr) 1318 { 1319 uint8_t *myaddr = NULL; 1320 struct target_if_spectral *spectral = (struct target_if_spectral *)arg; 1321 struct wlan_objmgr_pdev *pdev = NULL; 1322 1323 pdev = spectral->pdev_obj; 1324 1325 wlan_pdev_obj_lock(pdev); 1326 myaddr = wlan_pdev_get_hw_macaddr(pdev); 1327 wlan_pdev_obj_unlock(pdev); 1328 qdf_mem_copy(addr, myaddr, IEEE80211_ADDR_LEN); 1329 1330 return 0; 1331 } 1332 1333 /** 1334 * target_if_init_spectral_capability() - Initialize Spectral capability 1335 * @spectral: Pointer to Spectral target_if internal private data 1336 * 1337 * This is a workaround. 1338 * 1339 * Return: None 1340 */ 1341 void 1342 target_if_init_spectral_capability(struct target_if_spectral *spectral) 1343 { 1344 struct spectral_caps *pcap = &spectral->capability; 1345 1346 /* XXX : Workaround: Set Spectral capability */ 1347 pcap = &spectral->capability; 1348 pcap->phydiag_cap = 1; 1349 pcap->radar_cap = 1; 1350 pcap->spectral_cap = 1; 1351 pcap->advncd_spectral_cap = 1; 1352 pcap->hw_gen = spectral->spectral_gen; 1353 } 1354 1355 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 1356 /** 1357 * target_if_init_spectral_simulation_ops() - Initialize spectral target_if 1358 * internal operations with functions related to spectral simulation 1359 * @p_sops: spectral low level ops table 1360 * 1361 * Initialize spectral target_if internal operations with functions 1362 * related to spectral simulation 1363 * 1364 * Return: None 1365 */ 1366 static void 1367 target_if_init_spectral_simulation_ops(struct target_if_spectral_ops *p_sops) 1368 { 1369 /* 1370 * Spectral simulation is currently intended for platform transitions 1371 * where underlying HW support may not be available for some time. 1372 * Hence, we do not currently provide a runtime switch to turn the 1373 * simulation on or off. 1374 * In case of future requirements where runtime switches are required, 1375 * this can be added. But it is suggested to use application layer 1376 * simulation as far as possible in such cases, since the main 1377 * use of record and replay of samples would concern higher 1378 * level sample processing rather than lower level delivery. 1379 */ 1380 p_sops->is_spectral_enabled = target_if_spectral_sops_sim_is_enabled; 1381 p_sops->is_spectral_active = target_if_spectral_sops_sim_is_active; 1382 p_sops->start_spectral_scan = target_if_spectral_sops_sim_start_scan; 1383 p_sops->stop_spectral_scan = target_if_spectral_sops_sim_stop_scan; 1384 p_sops->configure_spectral = 1385 target_if_spectral_sops_sim_configure_params; 1386 p_sops->get_spectral_config = target_if_spectral_sops_sim_get_params; 1387 } 1388 1389 #else 1390 /** 1391 * target_if_init_spectral_simulation_ops() - Initialize spectral target_if 1392 * internal operations 1393 * @p_sops: spectral low level ops table 1394 * 1395 * Return: None 1396 */ 1397 static void 1398 target_if_init_spectral_simulation_ops(struct target_if_spectral_ops *p_sops) 1399 { 1400 p_sops->is_spectral_enabled = target_if_sops_is_spectral_enabled; 1401 p_sops->is_spectral_active = target_if_sops_is_spectral_active; 1402 p_sops->start_spectral_scan = target_if_sops_start_spectral_scan; 1403 p_sops->stop_spectral_scan = target_if_sops_stop_spectral_scan; 1404 p_sops->configure_spectral = target_if_spectral_sops_configure_params; 1405 p_sops->get_spectral_config = target_if_spectral_sops_get_params; 1406 } 1407 #endif 1408 1409 /** 1410 * target_if_init_spectral_ops_common() - Initialize Spectral target_if internal 1411 * operations common to all Spectral chipset generations 1412 * 1413 * Initializes target_if_spectral_ops common to all chipset generations 1414 * 1415 * Return: None 1416 */ 1417 static void 1418 target_if_init_spectral_ops_common(void) 1419 { 1420 struct target_if_spectral_ops *p_sops = &spectral_ops; 1421 1422 p_sops->get_tsf64 = target_if_spectral_get_tsf64; 1423 p_sops->get_capability = target_if_spectral_get_capability; 1424 p_sops->set_rxfilter = target_if_spectral_set_rxfilter; 1425 p_sops->get_rxfilter = target_if_spectral_get_rxfilter; 1426 1427 target_if_init_spectral_simulation_ops(p_sops); 1428 1429 p_sops->get_extension_channel = 1430 target_if_spectral_get_extension_channel; 1431 p_sops->get_ctl_noisefloor = target_if_spectral_get_ctl_noisefloor; 1432 p_sops->get_ext_noisefloor = target_if_spectral_get_ext_noisefloor; 1433 p_sops->get_ent_spectral_mask = target_if_spectral_get_ent_mask; 1434 p_sops->get_mac_address = target_if_spectral_get_macaddr; 1435 p_sops->get_current_channel = target_if_spectral_get_current_channel; 1436 p_sops->reset_hw = target_if_spectral_reset_hw; 1437 p_sops->get_chain_noise_floor = 1438 target_if_spectral_get_chain_noise_floor; 1439 } 1440 1441 /** 1442 * target_if_init_spectral_ops_gen2() - Initialize Spectral target_if internal 1443 * operations specific to Spectral chipset generation 2. 1444 * 1445 * Initializes target_if_spectral_ops specific to Spectral chipset generation 2. 1446 * 1447 * Return: None 1448 */ 1449 static void 1450 target_if_init_spectral_ops_gen2(void) 1451 { 1452 struct target_if_spectral_ops *p_sops = &spectral_ops; 1453 1454 p_sops->spectral_process_phyerr = target_if_process_phyerr_gen2; 1455 } 1456 1457 /** 1458 * target_if_init_spectral_ops_gen3() - Initialize Spectral target_if internal 1459 * operations specific to Spectral chipset generation 3. 1460 * 1461 * Initializes target_if_spectral_ops specific to Spectral chipset generation 3. 1462 * 1463 * Return: None 1464 */ 1465 static void 1466 target_if_init_spectral_ops_gen3(void) 1467 { 1468 struct target_if_spectral_ops *p_sops = &spectral_ops; 1469 1470 p_sops->process_spectral_report = 1471 target_if_spectral_process_report_gen3; 1472 return; 1473 } 1474 1475 /** 1476 * target_if_init_spectral_ops() - Initialize target_if internal Spectral 1477 * operations. 1478 * @spectral: Pointer to Spectral target_if internal private data 1479 * 1480 * Initializes all function pointers in target_if_spectral_ops for 1481 * all generations 1482 * 1483 * Return: None 1484 */ 1485 static void 1486 target_if_init_spectral_ops(struct target_if_spectral *spectral) 1487 { 1488 target_if_init_spectral_ops_common(); 1489 if (spectral->spectral_gen == SPECTRAL_GEN2) 1490 target_if_init_spectral_ops_gen2(); 1491 else if (spectral->spectral_gen == SPECTRAL_GEN3) 1492 target_if_init_spectral_ops_gen3(); 1493 else 1494 spectral_err("Invalid Spectral generation"); 1495 } 1496 1497 /* 1498 * Dummy Functions: 1499 * These functions are initially registered to avoid any crashes due to 1500 * invocation of spectral functions before they are registered. 1501 */ 1502 1503 static uint64_t 1504 null_get_tsf64(void *arg) 1505 { 1506 spectral_ops_not_registered("get_tsf64"); 1507 return 0; 1508 } 1509 1510 static uint32_t 1511 null_get_capability(void *arg, enum spectral_capability_type type) 1512 { 1513 /* 1514 * TODO : We should have conditional compilation to get the capability 1515 * : We have not yet attahced ATH layer here, so there is no 1516 * : way to check the HAL capbalities 1517 */ 1518 spectral_ops_not_registered("get_capability"); 1519 1520 /* TODO : For the time being, we are returning TRUE */ 1521 return true; 1522 } 1523 1524 static uint32_t 1525 null_set_rxfilter(void *arg, int rxfilter) 1526 { 1527 spectral_ops_not_registered("set_rxfilter"); 1528 return 1; 1529 } 1530 1531 static uint32_t 1532 null_get_rxfilter(void *arg) 1533 { 1534 spectral_ops_not_registered("get_rxfilter"); 1535 return 0; 1536 } 1537 1538 static uint32_t 1539 null_is_spectral_active(void *arg) 1540 { 1541 spectral_ops_not_registered("is_spectral_active"); 1542 return 1; 1543 } 1544 1545 static uint32_t 1546 null_is_spectral_enabled(void *arg) 1547 { 1548 spectral_ops_not_registered("is_spectral_enabled"); 1549 return 1; 1550 } 1551 1552 static uint32_t 1553 null_start_spectral_scan(void *arg) 1554 { 1555 spectral_ops_not_registered("start_spectral_scan"); 1556 return 1; 1557 } 1558 1559 static uint32_t 1560 null_stop_spectral_scan(void *arg) 1561 { 1562 spectral_ops_not_registered("stop_spectral_scan"); 1563 return 1; 1564 } 1565 1566 static uint32_t 1567 null_get_extension_channel(void *arg) 1568 { 1569 spectral_ops_not_registered("get_extension_channel"); 1570 return 1; 1571 } 1572 1573 static int8_t 1574 null_get_ctl_noisefloor(void *arg) 1575 { 1576 spectral_ops_not_registered("get_ctl_noisefloor"); 1577 return 1; 1578 } 1579 1580 static int8_t 1581 null_get_ext_noisefloor(void *arg) 1582 { 1583 spectral_ops_not_registered("get_ext_noisefloor"); 1584 return 0; 1585 } 1586 1587 static uint32_t 1588 null_configure_spectral(void *arg, struct spectral_config *params) 1589 { 1590 spectral_ops_not_registered("configure_spectral"); 1591 return 0; 1592 } 1593 1594 static uint32_t 1595 null_get_spectral_config(void *arg, struct spectral_config *params) 1596 { 1597 spectral_ops_not_registered("get_spectral_config"); 1598 return 0; 1599 } 1600 1601 static uint32_t 1602 null_get_ent_spectral_mask(void *arg) 1603 { 1604 spectral_ops_not_registered("get_ent_spectral_mask"); 1605 return 0; 1606 } 1607 1608 static uint32_t 1609 null_get_mac_address(void *arg, char *addr) 1610 { 1611 spectral_ops_not_registered("get_mac_address"); 1612 return 0; 1613 } 1614 1615 static uint32_t 1616 null_get_current_channel(void *arg) 1617 { 1618 spectral_ops_not_registered("get_current_channel"); 1619 return 0; 1620 } 1621 1622 static uint32_t 1623 null_reset_hw(void *arg) 1624 { 1625 spectral_ops_not_registered("get_current_channel"); 1626 return 0; 1627 } 1628 1629 static uint32_t 1630 null_get_chain_noise_floor(void *arg, int16_t *nf_buf) 1631 { 1632 spectral_ops_not_registered("get_chain_noise_floor"); 1633 return 0; 1634 } 1635 1636 static int 1637 null_spectral_process_phyerr(struct target_if_spectral *spectral, 1638 uint8_t *data, 1639 uint32_t datalen, 1640 struct target_if_spectral_rfqual_info *p_rfqual, 1641 struct target_if_spectral_chan_info *p_chaninfo, 1642 uint64_t tsf64, 1643 struct target_if_spectral_acs_stats *acs_stats) 1644 { 1645 spectral_ops_not_registered("spectral_process_phyerr"); 1646 return 0; 1647 } 1648 1649 static int 1650 null_process_spectral_report(struct wlan_objmgr_pdev *pdev, 1651 void *payload) 1652 { 1653 spectral_ops_not_registered("process_spectral_report"); 1654 return 0; 1655 } 1656 /** 1657 * target_if_spectral_init_dummy_function_table() - 1658 * Initialize target_if internal 1659 * Spectral operations to dummy functions 1660 * @ps: Pointer to Spectral target_if internal private data 1661 * 1662 * Initialize all the function pointers in target_if_spectral_ops with 1663 * dummy functions. 1664 * 1665 * Return: None 1666 */ 1667 static void 1668 target_if_spectral_init_dummy_function_table(struct target_if_spectral *ps) 1669 { 1670 struct target_if_spectral_ops *p_sops = GET_TARGET_IF_SPECTRAL_OPS(ps); 1671 1672 p_sops->get_tsf64 = null_get_tsf64; 1673 p_sops->get_capability = null_get_capability; 1674 p_sops->set_rxfilter = null_set_rxfilter; 1675 p_sops->get_rxfilter = null_get_rxfilter; 1676 p_sops->is_spectral_enabled = null_is_spectral_enabled; 1677 p_sops->is_spectral_active = null_is_spectral_active; 1678 p_sops->start_spectral_scan = null_start_spectral_scan; 1679 p_sops->stop_spectral_scan = null_stop_spectral_scan; 1680 p_sops->get_extension_channel = null_get_extension_channel; 1681 p_sops->get_ctl_noisefloor = null_get_ctl_noisefloor; 1682 p_sops->get_ext_noisefloor = null_get_ext_noisefloor; 1683 p_sops->configure_spectral = null_configure_spectral; 1684 p_sops->get_spectral_config = null_get_spectral_config; 1685 p_sops->get_ent_spectral_mask = null_get_ent_spectral_mask; 1686 p_sops->get_mac_address = null_get_mac_address; 1687 p_sops->get_current_channel = null_get_current_channel; 1688 p_sops->reset_hw = null_reset_hw; 1689 p_sops->get_chain_noise_floor = null_get_chain_noise_floor; 1690 p_sops->spectral_process_phyerr = null_spectral_process_phyerr; 1691 p_sops->process_spectral_report = null_process_spectral_report; 1692 } 1693 1694 /** 1695 * target_if_spectral_register_funcs() - Initialize target_if internal Spectral 1696 * operations 1697 * @spectral: Pointer to Spectral target_if internal private data 1698 * @p: Pointer to Spectral function table 1699 * 1700 * Return: None 1701 */ 1702 static void 1703 target_if_spectral_register_funcs(struct target_if_spectral *spectral, 1704 struct target_if_spectral_ops *p) 1705 { 1706 struct target_if_spectral_ops *p_sops = 1707 GET_TARGET_IF_SPECTRAL_OPS(spectral); 1708 1709 p_sops->get_tsf64 = p->get_tsf64; 1710 p_sops->get_capability = p->get_capability; 1711 p_sops->set_rxfilter = p->set_rxfilter; 1712 p_sops->get_rxfilter = p->get_rxfilter; 1713 p_sops->is_spectral_enabled = p->is_spectral_enabled; 1714 p_sops->is_spectral_active = p->is_spectral_active; 1715 p_sops->start_spectral_scan = p->start_spectral_scan; 1716 p_sops->stop_spectral_scan = p->stop_spectral_scan; 1717 p_sops->get_extension_channel = p->get_extension_channel; 1718 p_sops->get_ctl_noisefloor = p->get_ctl_noisefloor; 1719 p_sops->get_ext_noisefloor = p->get_ext_noisefloor; 1720 p_sops->configure_spectral = p->configure_spectral; 1721 p_sops->get_spectral_config = p->get_spectral_config; 1722 p_sops->get_ent_spectral_mask = p->get_ent_spectral_mask; 1723 p_sops->get_mac_address = p->get_mac_address; 1724 p_sops->get_current_channel = p->get_current_channel; 1725 p_sops->reset_hw = p->reset_hw; 1726 p_sops->get_chain_noise_floor = p->get_chain_noise_floor; 1727 p_sops->spectral_process_phyerr = p->spectral_process_phyerr; 1728 p_sops->process_spectral_report = p->process_spectral_report; 1729 } 1730 1731 /** 1732 * target_if_spectral_clear_stats() - Clear Spectral stats 1733 * @spectral: Pointer to Spectral target_if internal private data 1734 * 1735 * Function to clear spectral stats 1736 * 1737 * Return: None 1738 */ 1739 static void 1740 target_if_spectral_clear_stats(struct target_if_spectral *spectral) 1741 { 1742 struct target_if_spectral_ops *p_sops = 1743 GET_TARGET_IF_SPECTRAL_OPS(spectral); 1744 1745 qdf_mem_zero(&spectral->spectral_stats, 1746 sizeof(struct target_if_spectral_stats)); 1747 spectral->spectral_stats.last_reset_tstamp = 1748 p_sops->get_tsf64(spectral); 1749 } 1750 1751 /** 1752 * target_if_spectral_check_hw_capability() - Check whether HW supports spectral 1753 * @spectral: Pointer to Spectral target_if internal private data 1754 * 1755 * Function to check whether hardware supports spectral 1756 * 1757 * Return: True if HW supports Spectral, false if HW does not support Spectral 1758 */ 1759 static int 1760 target_if_spectral_check_hw_capability(struct target_if_spectral *spectral) 1761 { 1762 struct target_if_spectral_ops *p_sops = NULL; 1763 struct spectral_caps *pcap = NULL; 1764 int is_spectral_supported = true; 1765 1766 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1767 pcap = &spectral->capability; 1768 1769 if (p_sops->get_capability(spectral, SPECTRAL_CAP_PHYDIAG) == false) { 1770 is_spectral_supported = false; 1771 spectral_info("SPECTRAL : No PHYDIAG support"); 1772 return is_spectral_supported; 1773 } 1774 pcap->phydiag_cap = 1; 1775 1776 if (p_sops->get_capability(spectral, SPECTRAL_CAP_RADAR) == false) { 1777 is_spectral_supported = false; 1778 spectral_info("SPECTRAL : No RADAR support"); 1779 return is_spectral_supported; 1780 } 1781 pcap->radar_cap = 1; 1782 1783 if (p_sops->get_capability(spectral, 1784 SPECTRAL_CAP_SPECTRAL_SCAN) == false) { 1785 is_spectral_supported = false; 1786 spectral_info("SPECTRAL : No SPECTRAL SUPPORT"); 1787 return is_spectral_supported; 1788 } 1789 pcap->spectral_cap = 1; 1790 1791 if (p_sops->get_capability(spectral, SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN) 1792 == false) { 1793 spectral_info("SPECTRAL : No ADVANCED SPECTRAL SUPPORT"); 1794 } else { 1795 pcap->advncd_spectral_cap = 1; 1796 } 1797 1798 return is_spectral_supported; 1799 } 1800 1801 /** 1802 * target_if_spectral_init_param_defaults() - Initialize Spectral 1803 * parameter defaults 1804 * @spectral: Pointer to Spectral target_if internal private data 1805 * 1806 * It is the caller's responsibility to ensure that the Spectral parameters 1807 * structure passed as part of Spectral target_if internal private data is 1808 * valid. 1809 * 1810 * Return: None 1811 */ 1812 static void 1813 target_if_spectral_init_param_defaults(struct target_if_spectral *spectral) 1814 { 1815 struct spectral_config *params = &spectral->params; 1816 1817 params->ss_count = SPECTRAL_SCAN_COUNT_DEFAULT; 1818 if (spectral->spectral_gen == SPECTRAL_GEN3) 1819 params->ss_period = SPECTRAL_SCAN_PERIOD_GEN_III_DEFAULT; 1820 else 1821 params->ss_period = SPECTRAL_SCAN_PERIOD_GEN_II_DEFAULT; 1822 params->ss_spectral_pri = SPECTRAL_SCAN_PRIORITY_DEFAULT; 1823 params->ss_fft_size = SPECTRAL_SCAN_FFT_SIZE_DEFAULT; 1824 params->ss_gc_ena = SPECTRAL_SCAN_GC_ENA_DEFAULT; 1825 params->ss_restart_ena = SPECTRAL_SCAN_RESTART_ENA_DEFAULT; 1826 params->ss_noise_floor_ref = SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT; 1827 params->ss_init_delay = SPECTRAL_SCAN_INIT_DELAY_DEFAULT; 1828 params->ss_nb_tone_thr = SPECTRAL_SCAN_NB_TONE_THR_DEFAULT; 1829 params->ss_str_bin_thr = SPECTRAL_SCAN_STR_BIN_THR_DEFAULT; 1830 params->ss_wb_rpt_mode = SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT; 1831 params->ss_rssi_rpt_mode = SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT; 1832 params->ss_rssi_thr = SPECTRAL_SCAN_RSSI_THR_DEFAULT; 1833 params->ss_pwr_format = SPECTRAL_SCAN_PWR_FORMAT_DEFAULT; 1834 params->ss_rpt_mode = SPECTRAL_SCAN_RPT_MODE_DEFAULT; 1835 params->ss_bin_scale = SPECTRAL_SCAN_BIN_SCALE_DEFAULT; 1836 params->ss_dbm_adj = SPECTRAL_SCAN_DBM_ADJ_DEFAULT; 1837 /* 1838 * XXX 1839 * SPECTRAL_SCAN_CHN_MASK_DEFAULT (0x1) specifies that chain 0 is to be 1840 * used 1841 * for Spectral. This is expected to be an optimal configuration for 1842 * most chipsets considering aspects like power save. But this can later 1843 * optionally be changed to be set to the default system Rx chainmask 1844 * advertised by FW (if required for some purpose), once the Convergence 1845 * framework supports such retrieval at pdev attach time. 1846 */ 1847 params->ss_chn_mask = SPECTRAL_SCAN_CHN_MASK_DEFAULT; 1848 params->ss_short_report = SPECTRAL_SCAN_SHORT_REPORT_DEFAULT; 1849 params->ss_fft_period = SPECTRAL_SCAN_FFT_PERIOD_DEFAULT; 1850 } 1851 1852 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 1853 /** 1854 * target_if_spectral_detach_simulation() - De-initialize Spectral 1855 * Simulation functionality 1856 * @spectral: Pointer to Spectral target_if internal private data 1857 * 1858 * Function to de-initialize Spectral Simulation functionality 1859 * 1860 * Return: None 1861 */ 1862 static void 1863 target_if_spectral_detach_simulation(struct target_if_spectral *spectral) 1864 { 1865 target_if_spectral_sim_detach(spectral); 1866 } 1867 1868 #else 1869 static void 1870 target_if_spectral_detach_simulation(struct target_if_spectral *spectral) 1871 { 1872 } 1873 #endif 1874 1875 /** 1876 * target_if_spectral_detach() - De-initialize target_if Spectral 1877 * @pdev: Pointer to pdev object 1878 * 1879 * Function to detach target_if spectral 1880 * 1881 * Return: None 1882 */ 1883 static void 1884 target_if_spectral_detach(struct target_if_spectral *spectral) 1885 { 1886 spectral_info("spectral detach"); 1887 1888 if (spectral) { 1889 qdf_spinlock_destroy(&spectral->param_info.osps_lock); 1890 1891 target_if_spectral_detach_simulation(spectral); 1892 1893 qdf_spinlock_destroy(&spectral->spectral_lock); 1894 qdf_spinlock_destroy(&spectral->noise_pwr_reports_lock); 1895 1896 qdf_mem_free(spectral); 1897 spectral = NULL; 1898 } 1899 } 1900 1901 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 1902 /** 1903 * target_if_spectral_attach_simulation() - Initialize Spectral Simulation 1904 * functionality 1905 * @spectral: Pointer to Spectral target_if internal private data 1906 * 1907 * Function to initialize spectral simulation functionality 1908 * 1909 * Return: 0 on success, negative error code on failure 1910 */ 1911 static int 1912 target_if_spectral_attach_simulation(struct target_if_spectral *spectral) 1913 { 1914 if (target_if_spectral_sim_attach(spectral)) { 1915 qdf_mem_free(spectral); 1916 return -EPERM; 1917 } 1918 return 0; 1919 } 1920 1921 #else 1922 static int 1923 target_if_spectral_attach_simulation(struct target_if_spectral *spectral) 1924 { 1925 return 0; 1926 } 1927 #endif 1928 1929 /** 1930 * target_if_pdev_spectral_init() - Initialize target_if Spectral 1931 * functionality for the given pdev 1932 * @pdev: Pointer to pdev object 1933 * 1934 * Function to initialize pointer to spectral target_if internal private data 1935 * 1936 * Return: On success, pointer to Spectral target_if internal private data, on 1937 * failure, NULL 1938 */ 1939 void * 1940 target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) 1941 { 1942 struct target_if_spectral_ops *p_sops = NULL; 1943 struct target_if_spectral *spectral = NULL; 1944 #ifdef CONFIG_WIN 1945 uint32_t target_type; 1946 uint32_t target_revision; 1947 struct wlan_objmgr_psoc *psoc; 1948 struct wlan_lmac_if_target_tx_ops *tx_ops; 1949 #endif 1950 1951 if (!pdev) { 1952 spectral_err("SPECTRAL: pdev is NULL!"); 1953 return NULL; 1954 } 1955 spectral = (struct target_if_spectral *)qdf_mem_malloc( 1956 sizeof(struct target_if_spectral)); 1957 if (!spectral) { 1958 spectral_err("SPECTRAL : Memory allocation failed"); 1959 return spectral; 1960 } 1961 qdf_mem_zero(spectral, sizeof(struct target_if_spectral)); 1962 /* Store pdev in Spectral */ 1963 spectral->pdev_obj = pdev; 1964 1965 #ifdef CONFIG_WIN 1966 psoc = wlan_pdev_get_psoc(pdev); 1967 1968 tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops; 1969 1970 if (tx_ops->tgt_get_tgt_type) { 1971 target_type = tx_ops->tgt_get_tgt_type(psoc); 1972 } else { 1973 qdf_mem_free(spectral); 1974 return NULL; 1975 } 1976 1977 if (tx_ops->tgt_get_tgt_revision) { 1978 target_revision = tx_ops->tgt_get_tgt_revision(psoc); 1979 } else { 1980 qdf_mem_free(spectral); 1981 return NULL; 1982 } 1983 #endif 1984 1985 /* init the function ptr table */ 1986 target_if_spectral_init_dummy_function_table(spectral); 1987 1988 /* get spectral function table */ 1989 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1990 /* TODO : Should this be called here of after ath_attach ? */ 1991 if (p_sops->get_capability(spectral, SPECTRAL_CAP_PHYDIAG)) 1992 spectral_info("HAL_CAP_PHYDIAG : Capable"); 1993 1994 /* TODO: Need to fix the capablity check for RADAR */ 1995 if (p_sops->get_capability(spectral, SPECTRAL_CAP_RADAR)) 1996 spectral_info("HAL_CAP_RADAR : Capable"); 1997 1998 /* TODO : Need to fix the capablity check for SPECTRAL */ 1999 /* TODO : Should this be called here of after ath_attach ? */ 2000 if (p_sops->get_capability(spectral, SPECTRAL_CAP_SPECTRAL_SCAN)) 2001 spectral_info("HAL_CAP_SPECTRAL_SCAN : Capable"); 2002 2003 qdf_spinlock_create(&spectral->spectral_lock); 2004 qdf_spinlock_create(&spectral->noise_pwr_reports_lock); 2005 target_if_spectral_clear_stats(spectral); 2006 2007 #ifdef CONFIG_WIN 2008 if (target_type == TARGET_TYPE_QCA8074) { 2009 spectral->fftbin_size_war = 1; 2010 spectral->inband_fftbin_size_adj = 1; 2011 } else { 2012 spectral->fftbin_size_war = 0; 2013 spectral->inband_fftbin_size_adj = 0; 2014 } 2015 if ((target_type == TARGET_TYPE_QCA8074) || ( 2016 target_type == TARGET_TYPE_QCA6290)) { 2017 spectral->spectral_gen = SPECTRAL_GEN3; 2018 spectral->hdr_sig_exp = SPECTRAL_PHYERR_SIGNATURE_GEN3; 2019 spectral->tag_sscan_summary_exp = 2020 TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3; 2021 spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN3; 2022 spectral->tlvhdr_size = SPECTRAL_PHYERR_TLVSIZE_GEN3; 2023 } else 2024 #endif 2025 { 2026 spectral->spectral_gen = SPECTRAL_GEN2; 2027 spectral->hdr_sig_exp = SPECTRAL_PHYERR_SIGNATURE_GEN2; 2028 spectral->tag_sscan_summary_exp = 2029 TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2; 2030 spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN2; 2031 spectral->tlvhdr_size = sizeof(struct spectral_phyerr_tlv_gen2); 2032 } 2033 2034 /* Set the default values for spectral parameters */ 2035 target_if_spectral_init_param_defaults(spectral); 2036 /* Init spectral capability */ 2037 target_if_init_spectral_capability(spectral); 2038 if (target_if_spectral_attach_simulation(spectral) < 0) 2039 return NULL; 2040 2041 target_if_init_spectral_ops(spectral); 2042 2043 qdf_spinlock_create(&spectral->param_info.osps_lock); 2044 spectral->param_info.osps_cache.osc_is_valid = 0; 2045 2046 target_if_spectral_register_funcs(spectral, &spectral_ops); 2047 2048 if (target_if_spectral_check_hw_capability(spectral) == false) { 2049 target_if_spectral_detach(spectral); 2050 spectral = NULL; 2051 } else { 2052 /* 2053 * TODO: Once the driver architecture transitions to chipset 2054 * versioning based checks, reflect this here. 2055 */ 2056 spectral->is_160_format = false; 2057 spectral->is_lb_edge_extrabins_format = false; 2058 spectral->is_rb_edge_extrabins_format = false; 2059 #ifdef CONFIG_WIN 2060 2061 if (target_type == TARGET_TYPE_QCA9984 || 2062 target_type == TARGET_TYPE_QCA9888) { 2063 spectral->is_160_format = true; 2064 spectral->is_lb_edge_extrabins_format = true; 2065 spectral->is_rb_edge_extrabins_format = true; 2066 } else if ((target_type == TARGET_TYPE_AR900B) && 2067 (target_revision == AR900B_REV_2)) { 2068 spectral->is_rb_edge_extrabins_format = true; 2069 } 2070 2071 if (target_type == TARGET_TYPE_QCA9984 || 2072 target_type == TARGET_TYPE_QCA9888) 2073 spectral->is_sec80_rssi_war_required = true; 2074 spectral->use_nl_bcast = true; 2075 #else 2076 spectral->use_nl_bcast = false; 2077 #endif 2078 } 2079 2080 return spectral; 2081 } 2082 2083 /** 2084 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 2085 * functionality for the given pdev 2086 * @pdev: Pointer to pdev object 2087 * 2088 * Function to de-initialize pointer to spectral target_if internal private data 2089 * 2090 * Return: None 2091 */ 2092 void 2093 target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev) 2094 { 2095 struct target_if_spectral *spectral = NULL; 2096 2097 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2098 if (!spectral) { 2099 spectral_err("SPECTRAL : Module doesn't exist"); 2100 return; 2101 } 2102 target_if_spectral_detach(spectral); 2103 2104 return; 2105 } 2106 2107 /** 2108 * target_if_set_spectral_config() - Set spectral config 2109 * @pdev: Pointer to pdev object 2110 * @threshtype: config type 2111 * @value: config value 2112 * 2113 * API to set spectral configurations 2114 * 2115 * Return: 0 on success else failure 2116 */ 2117 int 2118 target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 2119 const uint32_t threshtype, const uint32_t value) 2120 { 2121 struct spectral_config params; 2122 struct target_if_spectral_ops *p_sops = NULL; 2123 struct target_if_spectral *spectral = NULL; 2124 2125 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2126 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2127 if (!spectral) { 2128 spectral_err("spectral object is NULL"); 2129 return -EPERM; 2130 } 2131 2132 switch (threshtype) { 2133 case SPECTRAL_PARAM_FFT_PERIOD: 2134 spectral->params.ss_fft_period = value; 2135 break; 2136 case SPECTRAL_PARAM_SCAN_PERIOD: 2137 spectral->params.ss_period = value; 2138 break; 2139 case SPECTRAL_PARAM_SCAN_COUNT: 2140 spectral->params.ss_count = value; 2141 break; 2142 case SPECTRAL_PARAM_SHORT_REPORT: 2143 spectral->params.ss_short_report = (!!value) ? true : false; 2144 break; 2145 case SPECTRAL_PARAM_SPECT_PRI: 2146 spectral->params.ss_spectral_pri = (!!value) ? true : false; 2147 break; 2148 case SPECTRAL_PARAM_FFT_SIZE: 2149 spectral->params.ss_fft_size = value; 2150 break; 2151 case SPECTRAL_PARAM_GC_ENA: 2152 spectral->params.ss_gc_ena = !!value; 2153 break; 2154 case SPECTRAL_PARAM_RESTART_ENA: 2155 spectral->params.ss_restart_ena = !!value; 2156 break; 2157 case SPECTRAL_PARAM_NOISE_FLOOR_REF: 2158 spectral->params.ss_noise_floor_ref = value; 2159 break; 2160 case SPECTRAL_PARAM_INIT_DELAY: 2161 spectral->params.ss_init_delay = value; 2162 break; 2163 case SPECTRAL_PARAM_NB_TONE_THR: 2164 spectral->params.ss_nb_tone_thr = value; 2165 break; 2166 case SPECTRAL_PARAM_STR_BIN_THR: 2167 spectral->params.ss_str_bin_thr = value; 2168 break; 2169 case SPECTRAL_PARAM_WB_RPT_MODE: 2170 spectral->params.ss_wb_rpt_mode = !!value; 2171 break; 2172 case SPECTRAL_PARAM_RSSI_RPT_MODE: 2173 spectral->params.ss_rssi_rpt_mode = !!value; 2174 break; 2175 case SPECTRAL_PARAM_RSSI_THR: 2176 spectral->params.ss_rssi_thr = value; 2177 break; 2178 case SPECTRAL_PARAM_PWR_FORMAT: 2179 spectral->params.ss_pwr_format = !!value; 2180 break; 2181 case SPECTRAL_PARAM_RPT_MODE: 2182 spectral->params.ss_rpt_mode = value; 2183 break; 2184 case SPECTRAL_PARAM_BIN_SCALE: 2185 spectral->params.ss_bin_scale = value; 2186 break; 2187 case SPECTRAL_PARAM_DBM_ADJ: 2188 spectral->params.ss_dbm_adj = !!value; 2189 break; 2190 case SPECTRAL_PARAM_CHN_MASK: 2191 spectral->params.ss_chn_mask = value; 2192 break; 2193 } 2194 2195 p_sops->configure_spectral(spectral, &spectral->params); 2196 /* only to validate the writes */ 2197 p_sops->get_spectral_config(spectral, ¶ms); 2198 return 0; 2199 } 2200 2201 /** 2202 * target_if_get_fft_bin_count() - Get fft bin count for a given fft length 2203 * @fft_len: FFT length 2204 * @pdev: Pointer to pdev object 2205 * 2206 * API to get fft bin count for a given fft length 2207 * 2208 * Return: FFt bin count 2209 */ 2210 static int 2211 target_if_get_fft_bin_count(int fft_len) 2212 { 2213 int bin_count = 0; 2214 2215 switch (fft_len) { 2216 case 5: 2217 bin_count = 16; 2218 break; 2219 case 6: 2220 bin_count = 32; 2221 break; 2222 case 7: 2223 bin_count = 64; 2224 break; 2225 case 8: 2226 bin_count = 128; 2227 break; 2228 case 9: 2229 bin_count = 256; 2230 break; 2231 default: 2232 break; 2233 } 2234 2235 return bin_count; 2236 } 2237 2238 /** 2239 * target_if_init_upper_lower_flags() - Initializes control and extension 2240 * segment flags 2241 * @fft_len: FFT length 2242 * @pdev: Pointer to pdev object 2243 * 2244 * API to initialize the control and extension flags with the lower/upper 2245 * segment based on the HT mode 2246 * 2247 * Return: FFt bin count 2248 */ 2249 static void 2250 target_if_init_upper_lower_flags(struct target_if_spectral *spectral) 2251 { 2252 int current_channel = 0; 2253 int ext_channel = 0; 2254 struct target_if_spectral_ops *p_sops = 2255 GET_TARGET_IF_SPECTRAL_OPS(spectral); 2256 2257 current_channel = p_sops->get_current_channel(spectral); 2258 ext_channel = p_sops->get_extension_channel(spectral); 2259 2260 if ((current_channel == 0) || (ext_channel == 0)) 2261 return; 2262 2263 if (spectral->sc_spectral_20_40_mode) { 2264 /* HT40 mode */ 2265 if (ext_channel < current_channel) { 2266 spectral->lower_is_extension = 1; 2267 spectral->upper_is_control = 1; 2268 spectral->lower_is_control = 0; 2269 spectral->upper_is_extension = 0; 2270 } else { 2271 spectral->lower_is_extension = 0; 2272 spectral->upper_is_control = 0; 2273 spectral->lower_is_control = 1; 2274 spectral->upper_is_extension = 1; 2275 } 2276 } else { 2277 /* HT20 mode, lower is always control */ 2278 spectral->lower_is_extension = 0; 2279 spectral->upper_is_control = 0; 2280 spectral->lower_is_control = 1; 2281 spectral->upper_is_extension = 0; 2282 } 2283 } 2284 2285 /** 2286 * target_if_get_spectral_config() - Get spectral configuration 2287 * @pdev: Pointer to pdev object 2288 * @param: Pointer to spectral_config structure in which the configuration 2289 * should be returned 2290 * 2291 * API to get the current spectral configuration 2292 * 2293 * Return: None 2294 */ 2295 void 2296 target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 2297 struct spectral_config *param) 2298 { 2299 struct target_if_spectral_ops *p_sops = NULL; 2300 struct target_if_spectral *spectral = NULL; 2301 2302 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2303 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2304 2305 qdf_mem_zero(param, sizeof(struct spectral_config)); 2306 p_sops->get_spectral_config(spectral, param); 2307 } 2308 2309 /** 2310 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 2311 * parameters 2312 * @spectral: Pointer to Spectral target_if internal private data 2313 * @spectral_params: Pointer to Spectral parameters 2314 * 2315 * Enable use of desired Spectral parameters by configuring them into HW, and 2316 * starting Spectral scan 2317 * 2318 * Return: 0 on success, 1 on failure 2319 */ 2320 int 2321 target_if_spectral_scan_enable_params(struct target_if_spectral *spectral, 2322 struct spectral_config *spectral_params) 2323 { 2324 int extension_channel = 0; 2325 int current_channel = 0; 2326 struct target_if_spectral_ops *p_sops = NULL; 2327 struct wlan_objmgr_vdev *vdev = NULL; 2328 2329 if (!spectral) { 2330 spectral_err("SPECTRAL : Spectral is NULL"); 2331 return 1; 2332 } 2333 2334 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2335 2336 if (!p_sops) { 2337 spectral_err("SPECTRAL : p_sops is NULL"); 2338 return 1; 2339 } 2340 2341 spectral->sc_spectral_noise_pwr_cal = 2342 spectral_params->ss_spectral_pri ? 1 : 0; 2343 2344 /* check if extension channel is present */ 2345 extension_channel = p_sops->get_extension_channel(spectral); 2346 current_channel = p_sops->get_current_channel(spectral); 2347 2348 vdev = target_if_spectral_get_vdev(spectral); 2349 if (!vdev) 2350 return 1; 2351 2352 spectral->ch_width = target_if_vdev_get_ch_width(vdev); 2353 wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID); 2354 2355 if (spectral->ch_width == CH_WIDTH_INVALID) 2356 return 1; 2357 2358 if (spectral->capability.advncd_spectral_cap) { 2359 spectral->lb_edge_extrabins = 0; 2360 spectral->rb_edge_extrabins = 0; 2361 2362 if (spectral->is_lb_edge_extrabins_format && 2363 spectral->params.ss_rpt_mode == 2) { 2364 spectral->lb_edge_extrabins = 4; 2365 } 2366 2367 if (spectral->is_rb_edge_extrabins_format && 2368 spectral->params.ss_rpt_mode == 2) { 2369 spectral->rb_edge_extrabins = 4; 2370 } 2371 2372 if (spectral->ch_width == CH_WIDTH_20MHZ) { 2373 spectral->sc_spectral_20_40_mode = 0; 2374 2375 spectral->spectral_numbins = 2376 target_if_get_fft_bin_count( 2377 spectral->params.ss_fft_size); 2378 spectral->spectral_fft_len = 2379 target_if_get_fft_bin_count( 2380 spectral->params.ss_fft_size); 2381 spectral->spectral_data_len = 2382 target_if_get_fft_bin_count( 2383 spectral->params.ss_fft_size); 2384 /* 2385 * Initialize classifier params to be sent to user 2386 * space classifier 2387 */ 2388 spectral->classifier_params.lower_chan_in_mhz = 2389 current_channel; 2390 spectral->classifier_params.upper_chan_in_mhz = 0; 2391 2392 } else if (spectral->ch_width == CH_WIDTH_40MHZ) { 2393 /* TODO : Remove this variable */ 2394 spectral->sc_spectral_20_40_mode = 1; 2395 spectral->spectral_numbins = 2396 target_if_get_fft_bin_count( 2397 spectral->params.ss_fft_size); 2398 spectral->spectral_fft_len = 2399 target_if_get_fft_bin_count( 2400 spectral->params.ss_fft_size); 2401 spectral->spectral_data_len = 2402 target_if_get_fft_bin_count( 2403 spectral->params.ss_fft_size); 2404 2405 /* 2406 * Initialize classifier params to be sent to user 2407 * space classifier 2408 */ 2409 if (extension_channel < current_channel) { 2410 spectral->classifier_params.lower_chan_in_mhz = 2411 extension_channel; 2412 spectral->classifier_params.upper_chan_in_mhz = 2413 current_channel; 2414 } else { 2415 spectral->classifier_params.lower_chan_in_mhz = 2416 current_channel; 2417 spectral->classifier_params.upper_chan_in_mhz = 2418 extension_channel; 2419 } 2420 2421 } else if (spectral->ch_width == CH_WIDTH_80MHZ) { 2422 /* Set the FFT Size */ 2423 /* TODO : Remove this variable */ 2424 spectral->sc_spectral_20_40_mode = 0; 2425 spectral->spectral_numbins = 2426 target_if_get_fft_bin_count( 2427 spectral->params.ss_fft_size); 2428 spectral->spectral_fft_len = 2429 target_if_get_fft_bin_count( 2430 spectral->params.ss_fft_size); 2431 spectral->spectral_data_len = 2432 target_if_get_fft_bin_count( 2433 spectral->params.ss_fft_size); 2434 2435 /* 2436 * Initialize classifier params to be sent to user 2437 * space classifier 2438 */ 2439 spectral->classifier_params.lower_chan_in_mhz = 2440 current_channel; 2441 spectral->classifier_params.upper_chan_in_mhz = 0; 2442 2443 /* 2444 * Initialize classifier params to be sent to user 2445 * space classifier 2446 */ 2447 if (extension_channel < current_channel) { 2448 spectral->classifier_params.lower_chan_in_mhz = 2449 extension_channel; 2450 spectral->classifier_params.upper_chan_in_mhz = 2451 current_channel; 2452 } else { 2453 spectral->classifier_params.lower_chan_in_mhz = 2454 current_channel; 2455 spectral->classifier_params.upper_chan_in_mhz = 2456 extension_channel; 2457 } 2458 2459 } else if (spectral->ch_width == CH_WIDTH_160MHZ) { 2460 /* Set the FFT Size */ 2461 2462 /* The below applies to both 160 and 80+80 cases */ 2463 2464 /* TODO : Remove this variable */ 2465 spectral->sc_spectral_20_40_mode = 0; 2466 spectral->spectral_numbins = 2467 target_if_get_fft_bin_count( 2468 spectral->params.ss_fft_size); 2469 spectral->spectral_fft_len = 2470 target_if_get_fft_bin_count( 2471 spectral->params.ss_fft_size); 2472 spectral->spectral_data_len = 2473 target_if_get_fft_bin_count( 2474 spectral->params.ss_fft_size); 2475 2476 /* 2477 * Initialize classifier params to be sent to user 2478 * space classifier 2479 */ 2480 spectral->classifier_params.lower_chan_in_mhz = 2481 current_channel; 2482 spectral->classifier_params.upper_chan_in_mhz = 0; 2483 2484 /* 2485 * Initialize classifier params to be sent to user 2486 * space classifier 2487 */ 2488 if (extension_channel < current_channel) { 2489 spectral->classifier_params.lower_chan_in_mhz = 2490 extension_channel; 2491 spectral->classifier_params.upper_chan_in_mhz = 2492 current_channel; 2493 } else { 2494 spectral->classifier_params.lower_chan_in_mhz = 2495 current_channel; 2496 spectral->classifier_params.upper_chan_in_mhz = 2497 extension_channel; 2498 } 2499 } 2500 2501 if (spectral->spectral_numbins) { 2502 spectral->spectral_numbins += 2503 spectral->lb_edge_extrabins; 2504 spectral->spectral_numbins += 2505 spectral->rb_edge_extrabins; 2506 } 2507 2508 if (spectral->spectral_fft_len) { 2509 spectral->spectral_fft_len += 2510 spectral->lb_edge_extrabins; 2511 spectral->spectral_fft_len += 2512 spectral->rb_edge_extrabins; 2513 } 2514 2515 if (spectral->spectral_data_len) { 2516 spectral->spectral_data_len += 2517 spectral->lb_edge_extrabins; 2518 spectral->spectral_data_len += 2519 spectral->rb_edge_extrabins; 2520 } 2521 } else { 2522 /* 2523 * The decision to find 20/40 mode is found based on the 2524 * presence of extension channel 2525 * instead of channel width, as the channel width can 2526 * dynamically change 2527 */ 2528 2529 if (extension_channel == 0) { 2530 spectral->spectral_numbins = SPECTRAL_HT20_NUM_BINS; 2531 spectral->spectral_dc_index = SPECTRAL_HT20_DC_INDEX; 2532 spectral->spectral_fft_len = SPECTRAL_HT20_FFT_LEN; 2533 spectral->spectral_data_len = 2534 SPECTRAL_HT20_TOTAL_DATA_LEN; 2535 /* only valid in 20-40 mode */ 2536 spectral->spectral_lower_max_index_offset = -1; 2537 /* only valid in 20-40 mode */ 2538 spectral->spectral_upper_max_index_offset = -1; 2539 spectral->spectral_max_index_offset = 2540 spectral->spectral_fft_len + 2; 2541 spectral->sc_spectral_20_40_mode = 0; 2542 2543 /* 2544 * Initialize classifier params to be sent to user 2545 * space classifier 2546 */ 2547 spectral->classifier_params.lower_chan_in_mhz = 2548 current_channel; 2549 spectral->classifier_params.upper_chan_in_mhz = 0; 2550 2551 } else { 2552 spectral->spectral_numbins = 2553 SPECTRAL_HT40_TOTAL_NUM_BINS; 2554 spectral->spectral_fft_len = SPECTRAL_HT40_FFT_LEN; 2555 spectral->spectral_data_len = 2556 SPECTRAL_HT40_TOTAL_DATA_LEN; 2557 spectral->spectral_dc_index = SPECTRAL_HT40_DC_INDEX; 2558 /* only valid in 20 mode */ 2559 spectral->spectral_max_index_offset = -1; 2560 spectral->spectral_lower_max_index_offset = 2561 spectral->spectral_fft_len + 2; 2562 spectral->spectral_upper_max_index_offset = 2563 spectral->spectral_fft_len + 5; 2564 spectral->sc_spectral_20_40_mode = 1; 2565 2566 /* 2567 * Initialize classifier params to be sent to user 2568 * space classifier 2569 */ 2570 if (extension_channel < current_channel) { 2571 spectral->classifier_params.lower_chan_in_mhz = 2572 extension_channel; 2573 spectral->classifier_params.upper_chan_in_mhz = 2574 current_channel; 2575 } else { 2576 spectral->classifier_params.lower_chan_in_mhz = 2577 current_channel; 2578 spectral->classifier_params.upper_chan_in_mhz = 2579 extension_channel; 2580 } 2581 } 2582 } 2583 2584 spectral->send_single_packet = 0; 2585 spectral->classifier_params.spectral_20_40_mode = 2586 spectral->sc_spectral_20_40_mode; 2587 spectral->classifier_params.spectral_dc_index = 2588 spectral->spectral_dc_index; 2589 spectral->spectral_sent_msg = 0; 2590 spectral->classify_scan = 0; 2591 spectral->num_spectral_data = 0; 2592 2593 if (!p_sops->is_spectral_active(spectral)) { 2594 p_sops->configure_spectral(spectral, spectral_params); 2595 p_sops->start_spectral_scan(spectral); 2596 } else { 2597 } 2598 2599 /* get current spectral configuration */ 2600 p_sops->get_spectral_config(spectral, &spectral->params); 2601 2602 target_if_init_upper_lower_flags(spectral); 2603 2604 return 0; 2605 } 2606 2607 /** 2608 * target_if_start_spectral_scan() - Start spectral scan 2609 * @pdev: Pointer to pdev object 2610 * 2611 * API to start spectral scan 2612 * 2613 * Return: 0 in case of success, -1 on failure 2614 */ 2615 int 2616 target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev) 2617 { 2618 struct target_if_spectral_ops *p_sops = NULL; 2619 struct target_if_spectral *spectral = NULL; 2620 2621 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2622 if (!spectral) { 2623 spectral_err("SPECTRAL : Spectral LMAC object is NUll"); 2624 return -EPERM; 2625 } 2626 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2627 2628 qdf_spin_lock(&spectral->spectral_lock); 2629 target_if_spectral_scan_enable_params(spectral, &spectral->params); 2630 qdf_spin_unlock(&spectral->spectral_lock); 2631 2632 return 0; 2633 } 2634 2635 void 2636 target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev) 2637 { 2638 struct target_if_spectral_ops *p_sops = NULL; 2639 struct target_if_spectral *spectral = NULL; 2640 2641 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2642 if (!spectral) { 2643 spectral_err("SPECTRAL : Spectral LMAC object is NUll "); 2644 return; 2645 } 2646 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2647 2648 qdf_spin_lock(&spectral->spectral_lock); 2649 p_sops->stop_spectral_scan(spectral); 2650 if (spectral->classify_scan) { 2651 /* TODO : Check if this logic is necessary */ 2652 spectral->detects_control_channel = 0; 2653 spectral->detects_extension_channel = 0; 2654 spectral->detects_above_dc = 0; 2655 spectral->detects_below_dc = 0; 2656 spectral->classify_scan = 0; 2657 } 2658 2659 spectral->send_single_packet = 0; 2660 spectral->sc_spectral_scan = 0; 2661 spectral->sc_spectral_noise_pwr_cal = 0; 2662 2663 /* 2664 * Reset the priority because it stops WLAN rx. 2665 * If it is needed to set, user has to set it explicitly 2666 * 2667 */ 2668 /* Reset Priority */ 2669 spectral->params.ss_spectral_pri = 0; 2670 qdf_spin_unlock(&spectral->spectral_lock); 2671 } 2672 2673 /** 2674 * target_if_is_spectral_active() - Get whether Spectral is active 2675 * @pdev: Pointer to pdev object 2676 * 2677 * API to get whether Spectral is active 2678 * 2679 * Return: True if Spectral is active, false if Spectral is not active 2680 */ 2681 bool 2682 target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev) 2683 { 2684 struct target_if_spectral *spectral = NULL; 2685 struct target_if_spectral_ops *p_sops = NULL; 2686 2687 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2688 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2689 return p_sops->is_spectral_active(spectral); 2690 } 2691 2692 /** 2693 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 2694 * @pdev: Pointer to pdev object 2695 * 2696 * API to get whether Spectral is enabled 2697 * 2698 * Return: True if Spectral is enabled, false if Spectral is not enabled 2699 */ 2700 bool 2701 target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev) 2702 { 2703 struct target_if_spectral *spectral = NULL; 2704 struct target_if_spectral_ops *p_sops = NULL; 2705 2706 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2707 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2708 return p_sops->is_spectral_enabled(spectral); 2709 } 2710 2711 /** 2712 * target_if_set_debug_level() - Set debug level for Spectral 2713 * @pdev: Pointer to pdev object 2714 * @debug_level: Debug level 2715 * 2716 * API to set the debug level for Spectral 2717 * 2718 * Return: 0 in case of success 2719 */ 2720 int 2721 target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, uint32_t debug_level) 2722 { 2723 spectral_debug_level = (DEBUG_SPECTRAL << debug_level); 2724 return 0; 2725 } 2726 2727 /** 2728 * target_if_get_debug_level() - Get debug level for Spectral 2729 * @pdev: Pointer to pdev object 2730 * 2731 * API to get the debug level for Spectral 2732 * 2733 * Return: Current debug level 2734 */ 2735 uint32_t 2736 target_if_get_debug_level(struct wlan_objmgr_pdev *pdev) 2737 { 2738 return spectral_debug_level; 2739 } 2740 2741 /** 2742 * target_if_get_spectral_capinfo() - Get Spectral capability information 2743 * @pdev: Pointer to pdev object 2744 * @outdata: Buffer into which data should be copied 2745 * 2746 * API to get the spectral capability information 2747 * 2748 * Return: void 2749 */ 2750 void 2751 target_if_get_spectral_capinfo(struct wlan_objmgr_pdev *pdev, void *outdata) 2752 { 2753 struct target_if_spectral *spectral = NULL; 2754 2755 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2756 qdf_mem_copy(outdata, &spectral->capability, 2757 sizeof(struct spectral_caps)); 2758 } 2759 2760 /** 2761 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 2762 * @pdev: Pointer to pdev object 2763 * @outdata: Buffer into which data should be copied 2764 * 2765 * API to get the spectral diagnostic statistics 2766 * 2767 * Return: void 2768 */ 2769 void 2770 target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, void *outdata) 2771 { 2772 struct target_if_spectral *spectral = NULL; 2773 2774 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2775 qdf_mem_copy(outdata, &spectral->diag_stats, 2776 sizeof(struct spectral_diag_stats)); 2777 } 2778 2779 /** 2780 * target_if_register_wmi_spectral_cmd_ops() - Register wmi_spectral_cmd_ops 2781 * @cmd_ops: Pointer to the structure having wmi_spectral_cmd function pointers 2782 * @pdev: Pointer to pdev object 2783 * 2784 * API for register wmi_spectral_cmd_ops in spectral internal data structure 2785 * 2786 * Return: void 2787 */ 2788 void 2789 target_if_register_wmi_spectral_cmd_ops(struct wlan_objmgr_pdev *pdev, 2790 struct wmi_spectral_cmd_ops *cmd_ops) 2791 { 2792 struct target_if_spectral *spectral = NULL; 2793 2794 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2795 spectral->param_wmi_cmd_ops.wmi_spectral_configure_cmd_send = 2796 cmd_ops->wmi_spectral_configure_cmd_send; 2797 spectral->param_wmi_cmd_ops.wmi_spectral_enable_cmd_send = 2798 cmd_ops->wmi_spectral_enable_cmd_send; 2799 } 2800 2801 /** 2802 * target_if_register_netlink_cb() - Register Netlink callbacks 2803 * @pdev: Pointer to pdev object 2804 * @nl_cb: Netlink callbacks to register 2805 * 2806 * Return: void 2807 */ 2808 static void 2809 target_if_register_netlink_cb( 2810 struct wlan_objmgr_pdev *pdev, 2811 struct spectral_nl_cb *nl_cb) 2812 { 2813 struct target_if_spectral *spectral = NULL; 2814 2815 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2816 qdf_mem_copy(&spectral->nl_cb, nl_cb, sizeof(struct spectral_nl_cb)); 2817 2818 if (spectral->use_nl_bcast) 2819 spectral->send_phy_data = spectral->nl_cb.send_nl_bcast; 2820 else 2821 spectral->send_phy_data = spectral->nl_cb.send_nl_unicast; 2822 } 2823 2824 /** 2825 * target_if_use_nl_bcast() - Get whether to use broadcast/unicast while sending 2826 * Netlink messages to the application layer 2827 * @pdev: Pointer to pdev object 2828 * 2829 * Return: true for broadcast, false for unicast 2830 */ 2831 static bool 2832 target_if_use_nl_bcast(struct wlan_objmgr_pdev *pdev) 2833 { 2834 struct target_if_spectral *spectral = NULL; 2835 2836 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2837 return spectral->use_nl_bcast; 2838 } 2839 2840 /** 2841 * target_if_deregister_netlink_cb() - De-register Netlink callbacks 2842 * @pdev: Pointer to pdev object 2843 * 2844 * Return: void 2845 */ 2846 static void 2847 target_if_deregister_netlink_cb(struct wlan_objmgr_pdev *pdev) 2848 { 2849 struct target_if_spectral *spectral = NULL; 2850 2851 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2852 if (!spectral) { 2853 spectral_err("SPECTRAL : Module doesn't exist"); 2854 return; 2855 } 2856 2857 qdf_mem_zero(&spectral->nl_cb, sizeof(struct spectral_nl_cb)); 2858 } 2859 2860 static int 2861 target_if_process_spectral_report(struct wlan_objmgr_pdev *pdev, 2862 void *payload) 2863 { 2864 struct target_if_spectral *spectral = NULL; 2865 struct target_if_spectral_ops *p_sops = NULL; 2866 2867 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2868 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2869 2870 return p_sops->process_spectral_report(pdev, payload); 2871 } 2872 2873 void 2874 target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) 2875 { 2876 tx_ops->sptrl_tx_ops.sptrlto_pdev_spectral_init = 2877 target_if_pdev_spectral_init; 2878 tx_ops->sptrl_tx_ops.sptrlto_pdev_spectral_deinit = 2879 target_if_pdev_spectral_deinit; 2880 tx_ops->sptrl_tx_ops.sptrlto_set_spectral_config = 2881 target_if_set_spectral_config; 2882 tx_ops->sptrl_tx_ops.sptrlto_get_spectral_config = 2883 target_if_get_spectral_config; 2884 tx_ops->sptrl_tx_ops.sptrlto_start_spectral_scan = 2885 target_if_start_spectral_scan; 2886 tx_ops->sptrl_tx_ops.sptrlto_stop_spectral_scan = 2887 target_if_stop_spectral_scan; 2888 tx_ops->sptrl_tx_ops.sptrlto_is_spectral_active = 2889 target_if_is_spectral_active; 2890 tx_ops->sptrl_tx_ops.sptrlto_is_spectral_enabled = 2891 target_if_is_spectral_enabled; 2892 tx_ops->sptrl_tx_ops.sptrlto_set_debug_level = 2893 target_if_set_debug_level; 2894 tx_ops->sptrl_tx_ops.sptrlto_get_debug_level = 2895 target_if_get_debug_level; 2896 tx_ops->sptrl_tx_ops.sptrlto_get_spectral_capinfo = 2897 target_if_get_spectral_capinfo; 2898 tx_ops->sptrl_tx_ops.sptrlto_get_spectral_diagstats = 2899 target_if_get_spectral_diagstats; 2900 tx_ops->sptrl_tx_ops.sptrlto_register_wmi_spectral_cmd_ops = 2901 target_if_register_wmi_spectral_cmd_ops; 2902 tx_ops->sptrl_tx_ops.sptrlto_register_netlink_cb = 2903 target_if_register_netlink_cb; 2904 tx_ops->sptrl_tx_ops.sptrlto_use_nl_bcast = 2905 target_if_use_nl_bcast; 2906 tx_ops->sptrl_tx_ops.sptrlto_deregister_netlink_cb = 2907 target_if_deregister_netlink_cb; 2908 tx_ops->sptrl_tx_ops.sptrlto_process_spectral_report = 2909 target_if_process_spectral_report; 2910 } 2911 qdf_export_symbol(target_if_sptrl_register_tx_ops); 2912 2913 void 2914 target_if_spectral_send_intf_found_msg(struct wlan_objmgr_pdev *pdev, 2915 uint16_t cw_int, uint32_t dcs_enabled) 2916 { 2917 struct spectral_samp_msg *msg = NULL; 2918 struct target_if_spectral_ops *p_sops = NULL; 2919 struct target_if_spectral *spectral = NULL; 2920 2921 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2922 msg = (struct spectral_samp_msg *)spectral->nl_cb.get_nbuff( 2923 spectral->pdev_obj); 2924 2925 if (msg) { 2926 msg->int_type = cw_int ? 2927 SPECTRAL_DCS_INT_CW : SPECTRAL_DCS_INT_WIFI; 2928 msg->dcs_enabled = dcs_enabled; 2929 msg->signature = SPECTRAL_SIGNATURE; 2930 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2931 p_sops->get_mac_address(spectral, msg->macaddr); 2932 if (spectral->send_phy_data(pdev) == 0) 2933 spectral->spectral_sent_msg++; 2934 } 2935 } 2936 qdf_export_symbol(target_if_spectral_send_intf_found_msg); 2937