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