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