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 #ifndef _TARGET_IF_SPECTRAL_H_ 21 #define _TARGET_IF_SPECTRAL_H_ 22 23 #include <wlan_objmgr_cmn.h> 24 #include <wlan_objmgr_psoc_obj.h> 25 #include <wlan_objmgr_pdev_obj.h> 26 #include <wlan_objmgr_vdev_obj.h> 27 #include <qdf_lock.h> 28 #include <wlan_spectral_public_structs.h> 29 #include <reg_services_public_struct.h> 30 #include <target_if_direct_buf_rx_api.h> 31 32 #ifdef WIN32 33 #pragma pack(push, target_if_spectral, 1) 34 #define __ATTRIB_PACK 35 #else 36 #ifndef __ATTRIB_PACK 37 #define __ATTRIB_PACK __attribute__ ((packed)) 38 #endif 39 #endif 40 41 #define spectral_log(level, args...) \ 42 QDF_PRINT_INFO(QDF_PRINT_IDX_SHARED, QDF_MODULE_ID_SPECTRAL, level, ## args) 43 44 #define spectral_logfl(level, format, args...) \ 45 spectral_log(level, FL(format), ## args) 46 47 #define spectral_fatal(format, args...) \ 48 spectral_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) 49 #define spectral_err(format, args...) \ 50 spectral_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) 51 #define spectral_warn(format, args...) \ 52 spectral_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) 53 #define spectral_info(format, args...) \ 54 spectral_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) 55 #define spectral_debug(format, args...) \ 56 spectral_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) 57 58 #define STATUS_PASS 1 59 #define STATUS_FAIL 0 60 #undef spectral_dbg_line 61 #define spectral_dbg_line() \ 62 spectral_debug("----------------------------------------------------\n") 63 64 #undef spectral_ops_not_registered 65 #define spectral_ops_not_registered(str) \ 66 spectral_info("SPECTRAL : %s not registered\n", (str)) 67 #undef not_yet_implemented 68 #define not_yet_implemented() \ 69 spectral_info("SPECTRAL : %s : %d Not yet implemented\n", \ 70 __func__, __LINE__) 71 72 #define SPECTRAL_HT20_NUM_BINS 56 73 #define SPECTRAL_HT20_FFT_LEN 56 74 #define SPECTRAL_HT20_DC_INDEX (SPECTRAL_HT20_FFT_LEN / 2) 75 #define SPECTRAL_HT20_DATA_LEN 60 76 #define SPECTRAL_HT20_TOTAL_DATA_LEN (SPECTRAL_HT20_DATA_LEN + 3) 77 #define SPECTRAL_HT40_TOTAL_NUM_BINS 128 78 #define SPECTRAL_HT40_DATA_LEN 135 79 #define SPECTRAL_HT40_TOTAL_DATA_LEN (SPECTRAL_HT40_DATA_LEN + 3) 80 #define SPECTRAL_HT40_FFT_LEN 128 81 #define SPECTRAL_HT40_DC_INDEX (SPECTRAL_HT40_FFT_LEN / 2) 82 83 /* 84 * Used for the SWAR to obtain approximate combined rssi 85 * in secondary 80Mhz segment 86 */ 87 #define OFFSET_CH_WIDTH_20 65 88 #define OFFSET_CH_WIDTH_40 62 89 #define OFFSET_CH_WIDTH_80 56 90 #define OFFSET_CH_WIDTH_160 50 91 92 #ifdef BIG_ENDIAN_HOST 93 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) do { \ 94 int j; \ 95 uint32_t *src, *dest; \ 96 src = (uint32_t *)(srcp); \ 97 dest = (uint32_t *)(destp); \ 98 for (j = 0; j < roundup((len), sizeof(uint32_t)) / 4; j++) { \ 99 *(dest + j) = qdf_le32_to_cpu(*(src + j)); \ 100 } \ 101 } while (0) 102 #else 103 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) \ 104 OS_MEMCPY((destp), (srcp), (len)); 105 #endif 106 107 #define DUMMY_NF_VALUE (-123) 108 /* 5 categories x (lower + upper) bands */ 109 #define MAX_INTERF 10 110 #define HOST_MAX_ANTENNA 3 111 /* Mask for time stamp from descriptor */ 112 #define SPECTRAL_TSMASK 0xFFFFFFFF 113 #define SPECTRAL_SIGNATURE 0xdeadbeef 114 115 /* START of spectral GEN II HW specific details */ 116 #define SPECTRAL_PHYERR_SIGNATURE_GEN2 0xbb 117 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2 0xF9 118 #define TLV_TAG_ADC_REPORT_GEN2 0xFA 119 #define TLV_TAG_SEARCH_FFT_REPORT_GEN2 0xFB 120 121 /** 122 * struct spectral_search_fft_info_gen2 - spectral search fft report for gen2 123 * @relpwr_db: Total bin power in db 124 * @num_str_bins_ib: Number of strong bins 125 * @base_pwr: Base power 126 * @total_gain_info: Total gain 127 * @fft_chn_idx: FFT chain on which report is originated 128 * @avgpwr_db: Average power in db 129 * @peak_mag: Peak power seen in the bins 130 * @peak_inx: Index of bin holding peak power 131 */ 132 struct spectral_search_fft_info_gen2 { 133 uint32_t relpwr_db; 134 uint32_t num_str_bins_ib; 135 uint32_t base_pwr; 136 uint32_t total_gain_info; 137 uint32_t fft_chn_idx; 138 uint32_t avgpwr_db; 139 uint32_t peak_mag; 140 int16_t peak_inx; 141 }; 142 143 /* 144 * XXX Check if we should be handling the endinness difference in some 145 * other way opaque to the host 146 */ 147 #ifdef BIG_ENDIAN_HOST 148 149 /** 150 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for big endian host 151 * @signature: signature 152 * @tag: tag 153 * @length: length 154 */ 155 struct spectral_phyerr_tlv_gen2 { 156 uint8_t signature; 157 uint8_t tag; 158 uint16_t length; 159 } __ATTRIB_PACK; 160 161 #else 162 163 /** 164 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for little endian host 165 * @length: length 166 * @tag: tag 167 * @signature: signature 168 */ 169 struct spectral_phyerr_tlv_gen2 { 170 uint16_t length; 171 uint8_t tag; 172 uint8_t signature; 173 } __ATTRIB_PACK; 174 175 #endif /* BIG_ENDIAN_HOST */ 176 177 /** 178 * struct spectral_phyerr_hdr_gen2 - phyerr header for gen2 HW 179 * @hdr_a: Header[0:31] 180 * @hdr_b: Header[32:63] 181 */ 182 struct spectral_phyerr_hdr_gen2 { 183 uint32_t hdr_a; 184 uint32_t hdr_b; 185 }; 186 187 /* 188 * Segment ID information for 80+80. 189 * 190 * If the HW micro-architecture specification extends this DWORD for other 191 * purposes, then redefine+rename accordingly. For now, the specification 192 * mentions only segment ID (though this doesn't require an entire DWORD) 193 * without mention of any generic terminology for the DWORD, or any reservation. 194 * We use nomenclature accordingly. 195 */ 196 typedef uint32_t SPECTRAL_SEGID_INFO; 197 198 /** 199 * struct spectral_phyerr_fft_gen2 - fft info in phyerr event 200 * @buf: fft report 201 */ 202 struct spectral_phyerr_fft_gen2 { 203 uint8_t buf[0]; 204 }; 205 /* END of spectral GEN II HW specific details */ 206 207 /* START of spectral GEN III HW specific details */ 208 209 #define get_bitfield(value, size, pos) \ 210 (((value) >> (pos)) & ((1 << (size)) - 1)) 211 #define unsigned_to_signed(value, width) \ 212 (((value) >= (1 << ((width) - 1))) ? \ 213 (value - (1 << (width))) : (value)) 214 215 #define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) 216 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) 217 #define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) 218 #define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) 219 220 #define PHYERR_HDR_SIG_POS \ 221 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig)) 222 #define PHYERR_HDR_TAG_POS \ 223 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_tag)) 224 #define SPECTRAL_FFT_BINS_POS \ 225 (offsetof(struct spectral_phyerr_fft_report_gen3, buf)) 226 227 /** 228 * struct phyerr_info - spectral search fft report for gen3 229 * @data: handle to phyerror buffer 230 * @datalen: length of phyerror bufer 231 * @p_rfqual: rf quality matrices 232 * @p_chaninfo: pointer to chaninfo 233 * @tsf64: 64 bit TSF 234 * @acs_stats: acs stats 235 */ 236 struct phyerr_info { 237 uint8_t *data; 238 uint32_t datalen; 239 struct target_if_spectral_rfqual_info *p_rfqual; 240 struct target_if_spectral_chan_info *p_chaninfo; 241 uint64_t tsf64; 242 struct target_if_spectral_acs_stats *acs_stats; 243 }; 244 245 /** 246 * struct spectral_search_fft_info_gen3 - spectral search fft report for gen3 247 * @timestamp: Timestamp at which fft report was generated 248 * @fft_detector_id: Which radio generated this report 249 * @fft_num: The FFT count number. Set to 0 for short FFT. 250 * @fft_radar_check: NA for spectral 251 * @fft_peak_sidx: Index of bin with maximum power 252 * @fft_chn_idx: Rx chain index 253 * @fft_base_pwr_db: Base power in dB 254 * @fft_total_gain_db: Total gain in dB 255 * @fft_num_str_bins_ib: Number of strong bins in the report 256 * @fft_peak_mag: Peak magnitude 257 * @fft_avgpwr_db: Average power in dB 258 * @fft_relpwr_db: Relative power in dB 259 */ 260 struct spectral_search_fft_info_gen3 { 261 uint32_t timestamp; 262 uint32_t fft_detector_id; 263 uint32_t fft_num; 264 uint32_t fft_radar_check; 265 int32_t fft_peak_sidx; 266 uint32_t fft_chn_idx; 267 uint32_t fft_base_pwr_db; 268 uint32_t fft_total_gain_db; 269 uint32_t fft_num_str_bins_ib; 270 int32_t fft_peak_mag; 271 uint32_t fft_avgpwr_db; 272 uint32_t fft_relpwr_db; 273 }; 274 275 /** 276 * struct spectral_phyerr_sfftreport_gen3 - fft info in phyerr event 277 * @fft_timestamp: Timestamp at which fft report was generated 278 * @fft_hdr_sig: signature 279 * @fft_hdr_tag: tag 280 * @fft_hdr_length: length 281 * @hdr_a: Header[0:31] 282 * @hdr_b: Header[32:63] 283 * @hdr_c: Header[64:95] 284 * @resv: Header[96:127] 285 * @buf: fft bins 286 */ 287 struct spectral_phyerr_fft_report_gen3 { 288 uint32_t fft_timestamp; 289 #ifdef BIG_ENDIAN_HOST 290 uint8_t fft_hdr_sig; 291 uint8_t fft_hdr_tag; 292 uint16_t fft_hdr_length; 293 #else 294 uint16_t fft_hdr_length; 295 uint8_t fft_hdr_tag; 296 uint8_t fft_hdr_sig; 297 #endif /* BIG_ENDIAN_HOST */ 298 uint32_t hdr_a; 299 uint32_t hdr_b; 300 uint32_t hdr_c; 301 uint32_t resv; 302 uint8_t buf[0]; 303 } __ATTRIB_PACK; 304 305 /** 306 * struct spectral_sscan_report_gen3 - spectral report in phyerr event 307 * @sscan_timestamp: Timestamp at which fft report was generated 308 * @sscan_hdr_sig: signature 309 * @sscan_hdr_tag: tag 310 * @sscan_hdr_length: length 311 * @hdr_a: Header[0:31] 312 * @resv: Header[32:63] 313 * @hdr_b: Header[64:95] 314 * @resv: Header[96:127] 315 */ 316 struct spectral_sscan_report_gen3 { 317 u_int32_t sscan_timestamp; 318 #ifdef BIG_ENDIAN_HOST 319 u_int8_t sscan_hdr_sig; 320 u_int8_t sscan_hdr_tag; 321 u_int16_t sscan_hdr_length; 322 #else 323 u_int16_t sscan_hdr_length; 324 u_int8_t sscan_hdr_tag; 325 u_int8_t sscan_hdr_sig; 326 #endif /* BIG_ENDIAN_HOST */ 327 u_int32_t hdr_a; 328 u_int32_t res1; 329 u_int32_t hdr_b; 330 u_int32_t res2; 331 } __ATTRIB_PACK; 332 /* END of spectral GEN III HW specific details */ 333 334 typedef signed char pwr_dbm; 335 336 /** 337 * enum spectral_gen - spectral hw generation 338 * @SPECTRAL_GEN1 : spectral hw gen 1 339 * @SPECTRAL_GEN2 : spectral hw gen 2 340 * @SPECTRAL_GEN3 : spectral hw gen 3 341 */ 342 enum spectral_gen { 343 SPECTRAL_GEN1, 344 SPECTRAL_GEN2, 345 SPECTRAL_GEN3, 346 }; 347 348 #if ATH_PERF_PWR_OFFLOAD 349 /** 350 * enum target_if_spectral_info - Enumerations for specifying which spectral 351 * information (among parameters and states) 352 * is desired. 353 * @TARGET_IF_SPECTRAL_INFO_ACTIVE: Indicated whether spectral is active 354 * @TARGET_IF_SPECTRAL_INFO_ENABLED: Indicated whether spectral is enabled 355 * @TARGET_IF_SPECTRAL_INFO_PARAMS: Config params 356 */ 357 enum target_if_spectral_info { 358 TARGET_IF_SPECTRAL_INFO_ACTIVE, 359 TARGET_IF_SPECTRAL_INFO_ENABLED, 360 TARGET_IF_SPECTRAL_INFO_PARAMS, 361 }; 362 #endif /* ATH_PERF_PWR_OFFLOAD */ 363 364 /* forward declaration */ 365 struct target_if_spectral; 366 367 /** 368 * struct target_if_spectral_chan_info - Channel information 369 * @center_freq1: center frequency 1 in MHz 370 * @center_freq2: center frequency 2 in MHz -valid only for 371 * 11ACVHT 80PLUS80 mode 372 * @chan_width: channel width in MHz 373 */ 374 struct target_if_spectral_chan_info { 375 uint16_t center_freq1; 376 uint16_t center_freq2; 377 uint8_t chan_width; 378 }; 379 380 /** 381 * struct target_if_spectral_acs_stats - EACS stats from spectral samples 382 * @nfc_ctl_rssi: Control chan rssi 383 * @nfc_ext_rssi: Extension chan rssi 384 * @ctrl_nf: Control chan Noise Floor 385 * @ext_nf: Extension chan Noise Floor 386 */ 387 struct target_if_spectral_acs_stats { 388 int8_t nfc_ctl_rssi; 389 int8_t nfc_ext_rssi; 390 int8_t ctrl_nf; 391 int8_t ext_nf; 392 }; 393 394 /** 395 * struct target_if_spectral_perchain_rssi_info - per chain rssi info 396 * @rssi_pri20: Rssi of primary 20 Mhz 397 * @rssi_sec20: Rssi of secondary 20 Mhz 398 * @rssi_sec40: Rssi of secondary 40 Mhz 399 * @rssi_sec80: Rssi of secondary 80 Mhz 400 */ 401 struct target_if_spectral_perchain_rssi_info { 402 int8_t rssi_pri20; 403 int8_t rssi_sec20; 404 int8_t rssi_sec40; 405 int8_t rssi_sec80; 406 }; 407 408 /** 409 * struct target_if_spectral_rfqual_info - RF measurement information 410 * @rssi_comb: RSSI Information 411 * @pc_rssi_info: XXX : For now, we know we are getting information 412 * for only 4 chains at max. For future extensions 413 * use a define 414 * @noise_floor: Noise floor information 415 */ 416 struct target_if_spectral_rfqual_info { 417 int8_t rssi_comb; 418 struct target_if_spectral_perchain_rssi_info pc_rssi_info[4]; 419 int16_t noise_floor[4]; 420 }; 421 422 #define GET_TARGET_IF_SPECTRAL_OPS(spectral) \ 423 ((struct target_if_spectral_ops *)(&((spectral)->spectral_ops))) 424 425 /** 426 * struct target_if_spectral_ops - spectral low level ops table 427 * @get_tsf64: Get 64 bit TSF value 428 * @get_capability: Get capability info 429 * @set_rxfilter: Set rx filter 430 * @get_rxfilter: Get rx filter 431 * @is_spectral_active: Check whether icm is active 432 * @is_spectral_enabled: Check whether spectral is enabled 433 * @start_spectral_scan: Start spectral scan 434 * @stop_spectral_scan: Stop spectral scan 435 * @get_extension_channel: Get extension channel 436 * @get_ctl_noisefloor: Get control noise floor 437 * @get_ext_noisefloor: Get extension noise floor 438 * @configure_spectral: Set spectral configurations 439 * @get_spectral_config: Get spectral configurations 440 * @get_ent_spectral_mask: Get spectral mask 441 * @get_mac_address: Get mac address 442 * @get_current_channel: Get current channel 443 * @reset_hw: Reset HW 444 * @get_chain_noise_floor: Get Channel noise floor 445 * @spectral_process_phyerr: Process phyerr event 446 */ 447 struct target_if_spectral_ops { 448 uint64_t (*get_tsf64)(void *arg); 449 uint32_t (*get_capability)( 450 void *arg, enum spectral_capability_type type); 451 uint32_t (*set_rxfilter)(void *arg, int rxfilter); 452 uint32_t (*get_rxfilter)(void *arg); 453 uint32_t (*is_spectral_active)(void *arg); 454 uint32_t (*is_spectral_enabled)(void *arg); 455 uint32_t (*start_spectral_scan)(void *arg); 456 uint32_t (*stop_spectral_scan)(void *arg); 457 uint32_t (*get_extension_channel)(void *arg); 458 int8_t (*get_ctl_noisefloor)(void *arg); 459 int8_t (*get_ext_noisefloor)(void *arg); 460 uint32_t (*configure_spectral)( 461 void *arg, 462 struct spectral_config *params); 463 uint32_t (*get_spectral_config)( 464 void *arg, 465 struct spectral_config *params); 466 uint32_t (*get_ent_spectral_mask)(void *arg); 467 uint32_t (*get_mac_address)(void *arg, char *addr); 468 uint32_t (*get_current_channel)(void *arg); 469 uint32_t (*reset_hw)(void *arg); 470 uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf); 471 int (*spectral_process_phyerr)(struct target_if_spectral *spectral, 472 uint8_t *data, uint32_t datalen, 473 struct target_if_spectral_rfqual_info *p_rfqual, 474 struct target_if_spectral_chan_info *p_chaninfo, 475 uint64_t tsf64, 476 struct target_if_spectral_acs_stats *acs_stats); 477 }; 478 479 /** 480 * struct target_if_spectral_stats - spectral stats info 481 * @num_spectral_detects: Total num. of spectral detects 482 * @total_phy_errors: Total number of phyerrors 483 * @owl_phy_errors: Indicated phyerrors in old gen1 chipsets 484 * @pri_phy_errors: Phyerrors in primary channel 485 * @ext_phy_errors: Phyerrors in secondary channel 486 * @dc_phy_errors: Phyerrors due to dc 487 * @early_ext_phy_errors: Early secondary channel phyerrors 488 * @bwinfo_errors: Bandwidth info errors 489 * @datalen_discards: Invalid data length errors, seen in gen1 chipsets 490 * @rssi_discards bw: Indicates reports dropped due to RSSI threshold 491 * @last_reset_tstamp: Last reset time stamp 492 */ 493 struct target_if_spectral_stats { 494 uint32_t num_spectral_detects; 495 uint32_t total_phy_errors; 496 uint32_t owl_phy_errors; 497 uint32_t pri_phy_errors; 498 uint32_t ext_phy_errors; 499 uint32_t dc_phy_errors; 500 uint32_t early_ext_phy_errors; 501 uint32_t bwinfo_errors; 502 uint32_t datalen_discards; 503 uint32_t rssi_discards; 504 uint64_t last_reset_tstamp; 505 }; 506 507 /** 508 * struct target_if_spectral_event - spectral event structure 509 * @se_ts: Original 15 bit recv timestamp 510 * @se_full_ts: 64-bit full timestamp from interrupt time 511 * @se_rssi: Rssi of spectral event 512 * @se_bwinfo: Rssi of spectral event 513 * @se_dur: Duration of spectral pulse 514 * @se_chanindex: Channel of event 515 * @se_list: List of spectral events 516 */ 517 struct target_if_spectral_event { 518 uint32_t se_ts; 519 uint64_t se_full_ts; 520 uint8_t se_rssi; 521 uint8_t se_bwinfo; 522 uint8_t se_dur; 523 uint8_t se_chanindex; 524 525 STAILQ_ENTRY(spectral_event) se_list; 526 }; 527 528 /** 529 * struct target_if_chain_noise_pwr_info - Noise power info for each channel 530 * @rptcount: Count of reports in pwr array 531 * @un_cal_nf: Uncalibrated noise floor 532 * @factory_cal_nf: Noise floor as calibrated at the factory for module 533 * @median_pwr: Median power (median of pwr array) 534 * @pwr: Power reports 535 */ 536 struct target_if_chain_noise_pwr_info { 537 int rptcount; 538 pwr_dbm un_cal_nf; 539 pwr_dbm factory_cal_nf; 540 pwr_dbm median_pwr; 541 pwr_dbm pwr[]; 542 } __ATTRIB_PACK; 543 544 /** 545 * struct target_if_spectral_chan_stats - Channel information 546 * @cycle_count: Cycle count 547 * @channel_load: Channel load 548 * @per: Period 549 * @noisefloor: Noise floor 550 * @comp_usablity: Computed usability 551 * @maxregpower: Maximum allowed regulatary power 552 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 553 * @maxregpower_sec80: Max regulatory power in secondary 80 Mhz 554 */ 555 struct target_if_spectral_chan_stats { 556 int cycle_count; 557 int channel_load; 558 int per; 559 int noisefloor; 560 uint16_t comp_usablity; 561 int8_t maxregpower; 562 uint16_t comp_usablity_sec80; 563 int8_t maxregpower_sec80; 564 }; 565 566 #if ATH_PERF_PWR_OFFLOAD 567 568 /** 569 * struct target_if_spectral_cache - Cache used to minimize WMI operations 570 * in offload architecture 571 * @osc_spectral_enabled: Whether Spectral is enabled 572 * @osc_spectral_active: Whether spectral is active 573 * XXX: Ideally, we should NOT cache this 574 * since the hardware can self clear the bit, 575 * the firmware can possibly stop spectral due to 576 * intermittent off-channel activity, etc 577 * A WMI read command should be introduced to handle 578 * this This will be discussed. 579 * @osc_params: Spectral parameters 580 * @osc_is_valid: Whether the cache is valid 581 */ 582 struct target_if_spectral_cache { 583 uint8_t osc_spectral_enabled; 584 uint8_t osc_spectral_active; 585 struct spectral_config osc_params; 586 uint8_t osc_is_valid; 587 }; 588 589 /** 590 * struct target_if_spectral_param_state_info - Structure used to represent and 591 * manage spectral information 592 * (parameters and states) 593 * @osps_lock: Lock to synchronize accesses to information 594 * @osps_cache: Cacheable' information 595 */ 596 struct target_if_spectral_param_state_info { 597 qdf_spinlock_t osps_lock; 598 struct target_if_spectral_cache osps_cache; 599 /* XXX - Non-cacheable information goes here, in the future */ 600 }; 601 #endif /* ATH_PERF_PWR_OFFLOAD */ 602 603 struct vdev_spectral_configure_params; 604 struct vdev_spectral_enable_params; 605 606 /** 607 * struct wmi_spectral_cmd_ops - structure used holding the operations 608 * related to wmi commands on spectral parameters. 609 * @wmi_spectral_configure_cmd_send: 610 * @wmi_spectral_enable_cmd_send: 611 */ 612 struct wmi_spectral_cmd_ops { 613 QDF_STATUS (*wmi_spectral_configure_cmd_send)( 614 void *wmi_hdl, 615 struct vdev_spectral_configure_params *param); 616 QDF_STATUS (*wmi_spectral_enable_cmd_send)( 617 void *wmi_hdl, 618 struct vdev_spectral_enable_params *param); 619 }; 620 621 /** 622 * struct target_if_spectral - main spectral structure 623 * @pdev: Pointer to pdev 624 * @spectral_ops: Target if internal Spectral low level operations table 625 * @capability: Spectral capabilities structure 626 * @spectral_lock: Lock used for internal Spectral operations 627 * @spectral_curchan_radindex: Current channel spectral index 628 * @spectral_extchan_radindex: Extension channel spectral index 629 * @spectraldomain: Current Spectral domain 630 * @spectral_proc_phyerr: Flags to process for PHY errors 631 * @spectral_defaultparams: Default PHY params per Spectral stat 632 * @spectral_stats: Spectral related stats 633 * @events: Events structure 634 * @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel? 635 * @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI? 636 * @sc_spectral_20_40_mode: Is AP in 20-40 mode? 637 * @sc_spectral_noise_pwr_cal: Noise power cal required? 638 * @sc_spectral_non_edma: Is the spectral capable device Non-EDMA? 639 * @upper_is_control: Upper segment is primary 640 * @upper_is_extension: Upper segment is secondary 641 * @lower_is_control: Lower segment is primary 642 * @lower_is_extension: Lower segment is secondary 643 * @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral 644 * mute test 645 * @spectral_numbins: Number of bins 646 * @spectral_fft_len: FFT length 647 * @spectral_data_len: Total phyerror report length 648 * @lb_edge_extrabins: Number of extra bins on left band edge 649 * @rb_edge_extrabins: Number of extra bins on right band edge 650 * @spectral_max_index_offset: Max FFT index offset (20 MHz mode) 651 * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode) 652 * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode) 653 * @spectral_dc_index: At which index DC is present 654 * @send_single_packet: Deprecated 655 * @spectral_sent_msg: Indicates whether we send report to upper layers 656 * @params: Spectral parameters 657 * @last_capture_time: Indicates timestamp of previouse report 658 * @num_spectral_data: Number of Spectral samples received in current session 659 * @total_spectral_data: Total number of Spectral samples received 660 * @max_rssi: Maximum RSSI 661 * @detects_control_channel: NA 662 * @detects_extension_channel: NA 663 * @detects_below_dc: NA 664 * @detects_above_dc: NA 665 * @sc_scanning: Indicates active wifi scan 666 * @sc_spectral_scan: Indicates active specral scan 667 * @sc_spectral_full_scan: Deprecated 668 * @scan_start_tstamp: Deprecated 669 * @last_tstamp: Deprecated 670 * @first_tstamp: Deprecated 671 * @spectral_samp_count: Deprecated 672 * @sc_spectral_samp_count: Deprecated 673 * @noise_pwr_reports_reqd: Number of noise power reports required 674 * @noise_pwr_reports_recv: Number of noise power reports received 675 * @noise_pwr_reports_lock: Lock used for Noise power report processing 676 * @noise_pwr_chain_ctl: Noise power report - control channel 677 * @noise_pwr_chain_ext: Noise power report - extension channel 678 * @chaninfo: Channel statistics 679 * @tsf64: Latest TSF Value 680 * @param_info: Offload architecture Spectral parameter cache information 681 * @ch_width: Indicates Channel Width 20/40/80/160 MHz with values 0, 1, 2, 3 682 * respectively 683 * @diag_stats: Diagnostic statistics 684 * @is_160_format: Indicates whether information provided by HW is in altered 685 * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) 686 * @is_lb_edge_extrabins_format: Indicates whether information provided by 687 * HW has 4 extra bins, at left band edge, for report mode 2 688 * @is_rb_edge_extrabins_format: Indicates whether information provided 689 * by HW has 4 extra bins, at right band edge, for report mode 2 690 * @is_sec80_rssi_war_required: Indicates whether the software workaround is 691 * required to obtain approximate combined RSSI for secondary 80Mhz segment 692 * @simctx: Spectral Simulation context 693 * @spectral_gen: Spectral hardware generation 694 * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware 695 * generation 696 * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV 697 * header, for the given hardware generation 698 * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV 699 * header, for the given hardware generation 700 * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware 701 * generation 702 * @nl_cb: Netlink callbacks 703 * @use_nl_bcast: Whether to use Netlink broadcast/unicast 704 * @send_phy_data: Send data to the applicaton layer 705 */ 706 struct target_if_spectral { 707 struct wlan_objmgr_pdev *pdev_obj; 708 struct target_if_spectral_ops spectral_ops; 709 struct spectral_caps capability; 710 qdf_spinlock_t spectral_lock; 711 int16_t spectral_curchan_radindex; 712 int16_t spectral_extchan_radindex; 713 uint32_t spectraldomain; 714 uint32_t spectral_proc_phyerr; 715 struct spectral_config spectral_defaultparams; 716 struct target_if_spectral_stats spectral_stats; 717 struct target_if_spectral_event *events; 718 unsigned int sc_spectral_ext_chan_ok:1, 719 sc_spectral_combined_rssi_ok:1, 720 sc_spectral_20_40_mode:1, 721 sc_spectral_noise_pwr_cal:1, 722 sc_spectral_non_edma:1; 723 int upper_is_control; 724 int upper_is_extension; 725 int lower_is_control; 726 int lower_is_extension; 727 uint8_t sc_spectraltest_ieeechan; 728 int spectral_numbins; 729 int spectral_fft_len; 730 int spectral_data_len; 731 732 /* 733 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are 734 * delivered. However, there can be additional bins reported for 735 * AR900B version 2.0 and QCA9984 as described next: 736 * 737 * AR900B version 2.0: An additional tone is processed on the right 738 * hand side in order to facilitate detection of radar pulses out to 739 * the extreme band-edge of the channel frequency. Since the HW design 740 * processes four tones at a time, this requires one additional Dword 741 * to be added to the search FFT report. 742 * 743 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary + 744 * 1x-oversampled bins (in-band) per FFT, then 8 more bins 745 * (4 more on left side and 4 more on right side)are added. 746 */ 747 748 int lb_edge_extrabins; 749 int rb_edge_extrabins; 750 int spectral_max_index_offset; 751 int spectral_upper_max_index_offset; 752 int spectral_lower_max_index_offset; 753 int spectral_dc_index; 754 int send_single_packet; 755 int spectral_sent_msg; 756 int classify_scan; 757 os_timer_t classify_timer; 758 struct spectral_config params; 759 struct spectral_classifier_params classifier_params; 760 int last_capture_time; 761 int num_spectral_data; 762 int total_spectral_data; 763 int max_rssi; 764 int detects_control_channel; 765 int detects_extension_channel; 766 int detects_below_dc; 767 int detects_above_dc; 768 int sc_scanning; 769 int sc_spectral_scan; 770 int sc_spectral_full_scan; 771 uint64_t scan_start_tstamp; 772 uint32_t last_tstamp; 773 uint32_t first_tstamp; 774 uint32_t spectral_samp_count; 775 uint32_t sc_spectral_samp_count; 776 int noise_pwr_reports_reqd; 777 int noise_pwr_reports_recv; 778 qdf_spinlock_t noise_pwr_reports_lock; 779 struct target_if_chain_noise_pwr_info 780 *noise_pwr_chain_ctl[HOST_MAX_ANTENNA]; 781 struct target_if_chain_noise_pwr_info 782 *noise_pwr_chain_ext[HOST_MAX_ANTENNA]; 783 uint64_t tsf64; 784 #if ATH_PERF_PWR_OFFLOAD 785 struct target_if_spectral_param_state_info param_info; 786 #endif 787 uint32_t ch_width; 788 struct spectral_diag_stats diag_stats; 789 bool is_160_format; 790 bool is_lb_edge_extrabins_format; 791 bool is_rb_edge_extrabins_format; 792 bool is_sec80_rssi_war_required; 793 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 794 void *simctx; 795 #endif 796 enum spectral_gen spectral_gen; 797 uint8_t hdr_sig_exp; 798 uint8_t tag_sscan_summary_exp; 799 uint8_t tag_sscan_fft_exp; 800 uint8_t tlvhdr_size; 801 struct wmi_spectral_cmd_ops param_wmi_cmd_ops; 802 struct spectral_nl_cb nl_cb; 803 bool use_nl_bcast; 804 int (*send_phy_data)(struct wlan_objmgr_pdev *pdev); 805 u_int8_t fftbin_size_war; 806 }; 807 808 /** 809 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 810 * data format 811 * @rssi: RSSI (except for secondary 80 segment) 812 * @rssi_sec80: RSSI for secondary 80 segment 813 * @lower_rssi: RSSI of lower band 814 * @upper_rssi: RSSI of upper band 815 * @chain_ctl_rssi: RSSI for control channel, for all antennas 816 * @chain_ext_rssi: RSSI for extension channel, for all antennas 817 * @bwinfo: bandwidth info 818 * @data_len: length of FFT data (except for secondary 80 segment) 819 * @data_len_sec80: length of FFT data for secondary 80 segment 820 * @tstamp: timestamp 821 * @last_tstamp: last time stamp 822 * @max_mag: maximum magnitude (except for secondary 80 segment) 823 * @max_mag_sec80: maximum magnitude for secondary 80 segment 824 * @max_index: index of max magnitude (except for secondary 80 segment) 825 * @max_index_sec80: index of max magnitude for secondary 80 segment 826 * @max_exp: max exp 827 * @peak: peak frequency (obsolete) 828 * @pwr_count: number of FFT bins (except for secondary 80 segment) 829 * @pwr_count_sec80: number of FFT bins in secondary 80 segment 830 * @nb_lower: This is deprecated 831 * @nb_upper: This is deprecated 832 * @max_upper_index: index of max mag in upper band 833 * @max_lower_index: index of max mag in lower band 834 * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment) 835 * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment 836 * @freq: Center frequency of primary 20MHz channel in MHz 837 * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz 838 * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz 839 * @freq_loading: spectral control duty cycles 840 * @noise_floor: current noise floor (except for secondary 80 segment) 841 * @noise_floor_sec80: current noise floor for secondary 80 segment 842 * @interf_list: List of interfernce sources 843 * @classifier_params: classifier parameters 844 * @sc: classifier parameters 845 */ 846 struct target_if_samp_msg_params { 847 int8_t rssi; 848 int8_t rssi_sec80; 849 int8_t lower_rssi; 850 int8_t upper_rssi; 851 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 852 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 853 uint16_t bwinfo; 854 uint16_t datalen; 855 uint16_t datalen_sec80; 856 uint32_t tstamp; 857 uint32_t last_tstamp; 858 uint16_t max_mag; 859 uint16_t max_mag_sec80; 860 uint16_t max_index; 861 uint16_t max_index_sec80; 862 uint8_t max_exp; 863 int peak; 864 int pwr_count; 865 int pwr_count_sec80; 866 int8_t nb_lower; 867 int8_t nb_upper; 868 uint16_t max_lower_index; 869 uint16_t max_upper_index; 870 uint8_t *bin_pwr_data; 871 uint8_t *bin_pwr_data_sec80; 872 uint16_t freq; 873 uint16_t vhtop_ch_freq_seg1; 874 uint16_t vhtop_ch_freq_seg2; 875 uint16_t freq_loading; 876 int16_t noise_floor; 877 int16_t noise_floor_sec80; 878 struct interf_src_rsp interf_list; 879 struct spectral_classifier_params classifier_params; 880 struct ath_softc *sc; 881 }; 882 883 /** 884 * target_if_spectral_dump_fft() - Dump Spectral FFT 885 * @pfft: Pointer to Spectral Phyerr FFT 886 * @fftlen: FFT length 887 * 888 * Return: Success or failure 889 */ 890 int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen); 891 892 /** 893 * target_if_dbg_print_samp_param() - Print contents of SAMP struct 894 * @p: Pointer to SAMP message 895 * 896 * Return: Void 897 */ 898 void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p); 899 900 /** 901 * target_if_get_offset_swar_sec80() - Get offset for SWAR according to 902 * the channel width 903 * @channel_width: Channel width 904 * 905 * Return: Offset for SWAR 906 */ 907 uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width); 908 909 /** 910 * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops 911 * @tx_ops: Tx Ops 912 * 913 * Return: void 914 */ 915 void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); 916 917 /** 918 * target_if_spectral_create_samp_msg() - Create the spectral samp message 919 * @spectral : Pointer to spectral internal structure 920 * @params : spectral samp message parameters 921 * 922 * API to create the spectral samp message 923 * 924 * Return: void 925 */ 926 void target_if_spectral_create_samp_msg( 927 struct target_if_spectral *spectral, 928 struct target_if_samp_msg_params *params); 929 930 /** 931 * target_if_spectral_process_phyerr_gen3() - Process phyerror event for gen3 932 * @pdev: Pointer to pdev object 933 * @payload: Pointer to spectral report 934 * 935 * Process phyerror event for gen3 936 * 937 * Return: Success/Failure 938 */ 939 int target_if_spectral_process_phyerr_gen3( 940 struct wlan_objmgr_pdev *pdev, 941 struct direct_buf_rx_data *payload); 942 943 /** 944 * target_if_process_phyerr_gen2() - Process PHY Error for gen2 945 * @spectral: Pointer to Spectral object 946 * @data: Pointer to phyerror event buffer 947 * @datalen: Data length 948 * @p_rfqual: RF quality info 949 * @p_chaninfo: Channel info 950 * @tsf64: 64 bit tsf timestamp 951 * @acs_stats: ACS stats 952 * 953 * Process PHY Error for gen2 954 * 955 * Return: Success/Failure 956 */ 957 int target_if_process_phyerr_gen2( 958 struct target_if_spectral *spectral, 959 uint8_t *data, 960 uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual, 961 struct target_if_spectral_chan_info *p_chaninfo, 962 uint64_t tsf64, 963 struct target_if_spectral_acs_stats *acs_stats); 964 965 /** 966 * target_if_spectral_send_intf_found_msg() - Indicate to application layer that 967 * interference has been found 968 * @pdev: Pointer to pdev 969 * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found 970 * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled 971 * 972 * Send message to application layer 973 * indicating that interference has been found 974 * 975 * Return: None 976 */ 977 void target_if_spectral_send_intf_found_msg( 978 struct wlan_objmgr_pdev *pdev, 979 uint16_t cw_int, uint32_t dcs_enabled); 980 981 /** 982 * target_if_stop_spectral_scan() - Stop spectral scan 983 * @pdev: Pointer to pdev object 984 * 985 * API to stop the current on-going spectral scan 986 * 987 * Return: None 988 */ 989 void target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev); 990 991 /** 992 * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral 993 * operations 994 * @spectral: Pointer to Spectral target_if internal private data 995 * 996 * Spectral operates on pdev. However, in order to retrieve some WLAN 997 * properties, a vdev is required. To facilitate this, the function returns the 998 * first vdev in our pdev. The caller should release the reference to the vdev 999 * once it is done using it. 1000 * TODO: If the framework later provides an API to obtain the first active 1001 * vdev, then it would be preferable to use this API. 1002 * 1003 * Return: Pointer to vdev on success, NULL on failure 1004 */ 1005 struct wlan_objmgr_vdev *target_if_spectral_get_vdev( 1006 struct target_if_spectral *spectral); 1007 1008 /** 1009 * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2 1010 * @phdr: Pointer to Spectral Phyerr Header 1011 * 1012 * Dump Spectral header 1013 * 1014 * Return: Success/Failure 1015 */ 1016 int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr); 1017 1018 /** 1019 * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI 1020 * for Secondary 80 segment 1021 * @spectral: Pointer to spectral object 1022 * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment 1023 * 1024 * Get approximate combined RSSI for Secondary 80 segment 1025 * 1026 * Return: Combined RSSI for secondary 80Mhz segment 1027 */ 1028 int8_t target_if_get_combrssi_sec80_seg_gen2( 1029 struct target_if_spectral *spectral, 1030 struct spectral_search_fft_info_gen2 *p_sfft_sec80); 1031 1032 /** 1033 * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2 1034 * @ptlv: Pointer to Spectral Phyerr TLV 1035 * @is_160_format: Indicates 160 format 1036 * 1037 * Dump Spectral TLV for gen2 1038 * 1039 * Return: Success/Failure 1040 */ 1041 int target_if_spectral_dump_tlv_gen2( 1042 struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format); 1043 1044 /** 1045 * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral 1046 * related PHY Error for gen2 1047 * @data: Pointer to phyerror buffer 1048 * @datalen: Data length 1049 * @is_160_format: Indicates 160 format 1050 * 1051 * Dump Spectral related PHY Error for gen2 1052 * 1053 * Return: Success/Failure 1054 */ 1055 int target_if_spectral_dump_phyerr_data_gen2( 1056 uint8_t *data, 1057 uint32_t datalen, 1058 bool is_160_format); 1059 1060 /** 1061 * target_if_dump_fft_report_gen3() - Dump FFT Report for gen3 1062 * @p_fft_report: Pointer to fft report 1063 * @p_sfft: Pointer to search fft report 1064 * 1065 * Dump FFT Report for gen3 1066 * 1067 * Return: Success/Failure 1068 */ 1069 int target_if_dump_fft_report_gen3( 1070 struct spectral_phyerr_fft_report_gen3 *p_fft_report, 1071 struct spectral_search_fft_info_gen3 *p_sfft); 1072 1073 /** 1074 * target_if_dbg_print_samp_msg() - Print contents of SAMP Message 1075 * @p: Pointer to SAMP message 1076 * 1077 * Print contents of SAMP Message 1078 * 1079 * Return: Void 1080 */ 1081 void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); 1082 1083 /** 1084 * target_if_process_sfft_report_gen3() - Process Search FFT Report for gen3 1085 * @p_fft_report: Pointer to fft report 1086 * @p_sfft: Pointer to search fft report 1087 * 1088 * Process Search FFT Report for gen3 1089 * 1090 * Return: Success/Failure 1091 */ 1092 int target_if_process_sfft_report_gen3( 1093 struct spectral_phyerr_fft_report_gen3 *p_fft_report, 1094 struct spectral_search_fft_info_gen3 *p_fft_info); 1095 1096 /** 1097 * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal 1098 * Spectral data 1099 * @pdev: Pointer to pdev 1100 * 1101 * Return: Handle to target_if internal Spectral data on success, NULL on 1102 * failure 1103 */ 1104 static inline 1105 struct target_if_spectral *get_target_if_spectral_handle_from_pdev( 1106 struct wlan_objmgr_pdev *pdev) 1107 { 1108 struct target_if_spectral *spectral = NULL; 1109 struct wlan_objmgr_psoc *psoc = NULL; 1110 1111 psoc = wlan_pdev_get_psoc(pdev); 1112 1113 spectral = (struct target_if_spectral *) 1114 psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_get_target_handle( 1115 pdev); 1116 return spectral; 1117 } 1118 1119 /** 1120 * target_if_vdev_get_chan_freq() - Get the operating channel frequency of a 1121 * given vdev 1122 * @pdev: Pointer to vdev 1123 * 1124 * Get the operating channel frequency of a given vdev 1125 * 1126 * Return: Operating channel frequency of a vdev 1127 */ 1128 static inline 1129 int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) 1130 { 1131 struct wlan_objmgr_psoc *psoc = NULL; 1132 1133 psoc = wlan_vdev_get_psoc(vdev); 1134 if (!psoc) { 1135 spectral_err("psoc is NULL"); 1136 return -EINVAL; 1137 } 1138 1139 return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_chan_freq( 1140 vdev); 1141 } 1142 1143 /** 1144 * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a 1145 * given vdev 1146 * @pdev: Pointer to vdev 1147 * 1148 * Get the operating channel bandwidth of a given vdev 1149 * 1150 * Return: channel bandwidth enumeration corresponding to the vdev 1151 */ 1152 static inline 1153 enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) 1154 { 1155 struct wlan_objmgr_psoc *psoc = NULL; 1156 1157 psoc = wlan_vdev_get_psoc(vdev); 1158 if (!psoc) { 1159 spectral_err("psoc is NULL"); 1160 return CH_WIDTH_INVALID; 1161 } 1162 1163 return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_ch_width( 1164 vdev); 1165 } 1166 1167 /** 1168 * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary 1169 * 20 MHz channel for a given vdev 1170 * @pdev: Pointer to vdev 1171 * 1172 * Get the frequency of secondary 20Mhz channel for a given vdev 1173 * 1174 * Return: Frequency of secondary 20Mhz channel for a given vdev 1175 */ 1176 static inline 1177 int target_if_vdev_get_sec20chan_freq_mhz( 1178 struct wlan_objmgr_vdev *vdev, 1179 uint16_t *sec20chan_freq) 1180 { 1181 struct wlan_objmgr_psoc *psoc = NULL; 1182 1183 psoc = wlan_vdev_get_psoc(vdev); 1184 if (!psoc) { 1185 spectral_err("psoc is NULL"); 1186 return -EINVAL; 1187 } 1188 1189 return psoc->soc_cb.rx_ops.sptrl_rx_ops. 1190 sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); 1191 } 1192 1193 /** 1194 * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask 1195 * @pdev: Pointer to pdev 1196 * @spectral_rx_chainmask: Spectral Rx chainmask 1197 * 1198 * Return: None 1199 */ 1200 static inline 1201 void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, 1202 uint8_t spectral_rx_chainmask) 1203 { 1204 struct target_if_spectral *spectral = NULL; 1205 1206 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1207 spectral->params.ss_chn_mask = spectral_rx_chainmask; 1208 } 1209 1210 /** 1211 * target_if_spectral_process_phyerr() - Process Spectral PHY error 1212 * @pdev: Pointer to pdev 1213 * @data: PHY error data received from FW 1214 * @datalen: Length of data 1215 * @p_rfqual: Pointer to RF Quality information 1216 * @p_chaninfo: Pointer to channel information 1217 * @tsf: TSF time instance at which the Spectral sample was received 1218 * @acs_stats: ACS stats 1219 * 1220 * Process Spectral PHY error by extracting necessary information from the data 1221 * sent by FW, and send the extracted information to application layer. 1222 * 1223 * Return: None 1224 */ 1225 static inline 1226 void target_if_spectral_process_phyerr( 1227 struct wlan_objmgr_pdev *pdev, 1228 uint8_t *data, uint32_t datalen, 1229 struct target_if_spectral_rfqual_info *p_rfqual, 1230 struct target_if_spectral_chan_info *p_chaninfo, 1231 uint64_t tsf64, 1232 struct target_if_spectral_acs_stats *acs_stats) 1233 { 1234 struct target_if_spectral *spectral = NULL; 1235 struct target_if_spectral_ops *p_sops = NULL; 1236 1237 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1238 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1239 p_sops->spectral_process_phyerr(spectral, data, datalen, 1240 p_rfqual, p_chaninfo, 1241 tsf64, acs_stats); 1242 } 1243 1244 /** 1245 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 1246 * @arg: Pointer to handle for Spectral target_if internal private data 1247 * 1248 * Function to check whether Spectral is enabled 1249 * 1250 * Return: True if Spectral is enabled, false if Spectral is not enabled 1251 */ 1252 uint32_t target_if_sops_is_spectral_enabled(void *arg); 1253 1254 /** 1255 * target_if_sops_is_spectral_active() - Get whether Spectral is active 1256 * @arg: Pointer to handle for Spectral target_if internal private data 1257 * 1258 * Function to check whether Spectral is active 1259 * 1260 * Return: True if Spectral is active, false if Spectral is not active 1261 */ 1262 uint32_t target_if_sops_is_spectral_active(void *arg); 1263 1264 /** 1265 * target_if_sops_start_spectral_scan() - Start Spectral scan 1266 * @arg: Pointer to handle for Spectral target_if internal private data 1267 * 1268 * Function to start spectral scan 1269 * 1270 * Return: 0 on success else failure 1271 */ 1272 uint32_t target_if_sops_start_spectral_scan(void *arg); 1273 1274 /** 1275 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 1276 * @arg: Pointer to handle for Spectral target_if internal private data 1277 * 1278 * Function to stop spectral scan 1279 * 1280 * Return: 0 in case of success, -1 on failure 1281 */ 1282 uint32_t target_if_sops_stop_spectral_scan(void *arg); 1283 1284 /** 1285 * target_if_spectral_get_extension_channel() - Get the current Extension 1286 * channel (in MHz) 1287 * @arg: Pointer to handle for Spectral target_if internal private data 1288 * 1289 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 1290 * extension channel is not present. 1291 */ 1292 uint32_t target_if_spectral_get_extension_channel(void *arg); 1293 1294 /** 1295 * target_if_spectral_get_current_channel() - Get the current channel (in MHz) 1296 * @arg: Pointer to handle for Spectral target_if internal private data 1297 * 1298 * Return: Current channel (in MHz) on success, 0 on failure 1299 */ 1300 uint32_t target_if_spectral_get_current_channel(void *arg); 1301 1302 1303 /** 1304 * target_if_spectral_reset_hw() - Reset the hardware 1305 * @arg: Pointer to handle for Spectral target_if internal private data 1306 * 1307 * This is only a placeholder since it is not currently required in the offload 1308 * case. 1309 * 1310 * Return: 0 1311 */ 1312 uint32_t target_if_spectral_reset_hw(void *arg); 1313 1314 /** 1315 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 1316 * Noisefloor history buffer 1317 * @arg: Pointer to handle for Spectral target_if internal private data 1318 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 1319 * 1320 * This is only a placeholder since it is not currently required in the offload 1321 * case. 1322 * 1323 * Return: 0 1324 */ 1325 uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf); 1326 1327 /** 1328 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 1329 * noisefloor 1330 * @arg: Pointer to handle for Spectral target_if internal private data 1331 * 1332 * This is only a placeholder since it is not currently required in the offload 1333 * case. 1334 * 1335 * Return: 0 1336 */ 1337 int8_t target_if_spectral_get_ext_noisefloor(void *arg); 1338 1339 /** 1340 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 1341 * @arg: Pointer to handle for Spectral target_if internal private data 1342 * 1343 * This is only a placeholder since it is not currently required in the offload 1344 * case. 1345 * 1346 * Return: 0 1347 */ 1348 int8_t target_if_spectral_get_ctl_noisefloor(void *arg); 1349 1350 /** 1351 * target_if_spectral_get_capability() - Get whether a given Spectral hardware 1352 * capability is available 1353 * @arg: Pointer to handle for Spectral target_if internal private data 1354 * @type: Spectral hardware capability type 1355 * 1356 * Return: True if the capability is available, false if the capability is not 1357 * available 1358 */ 1359 uint32_t target_if_spectral_get_capability( 1360 void *arg, enum spectral_capability_type type); 1361 1362 /** 1363 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 1364 * @arg: Pointer to handle for Spectral target_if internal private data 1365 * @rxfilter: Rx filter to be used 1366 * 1367 * Note: This is only a placeholder function. It is not currently required since 1368 * FW should be taking care of setting the required filters. 1369 * 1370 * Return: 0 1371 */ 1372 uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter); 1373 1374 /** 1375 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 1376 * parameters 1377 * @arg: Pointer to handle for Spectral target_if internal private data 1378 * @params: Spectral parameters 1379 * 1380 * Return: 0 in case of success, -1 on failure 1381 */ 1382 uint32_t target_if_spectral_sops_configure_params( 1383 void *arg, struct spectral_config *params); 1384 1385 /** 1386 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 1387 * @arg: Pointer to handle for Spectral target_if internal private data 1388 * 1389 * Note: This is only a placeholder function. It is not currently required since 1390 * FW should be taking care of setting the required filters. 1391 * 1392 * Return: 0 1393 */ 1394 uint32_t target_if_spectral_get_rxfilter(void *arg); 1395 1396 /** 1397 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 1398 * functionality for the given pdev 1399 * @pdev: Pointer to pdev object 1400 * 1401 * Return: None 1402 */ 1403 void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev); 1404 1405 /** 1406 * target_if_set_spectral_config() - Set spectral config 1407 * @pdev: Pointer to pdev object 1408 * @threshtype: config type 1409 * @value: config value 1410 * 1411 * API to set spectral configurations 1412 * 1413 * Return: 0 in case of success, -1 on failure 1414 */ 1415 int target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 1416 const uint32_t threshtype, 1417 const uint32_t value); 1418 1419 /** 1420 * target_if_pdev_spectral_init() - Initialize target_if Spectral 1421 * functionality for the given pdev 1422 * @pdev: Pointer to pdev object 1423 * 1424 * Return: On success, pointer to Spectral target_if internal private data, on 1425 * failure, NULL 1426 */ 1427 void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev); 1428 1429 /** 1430 * target_if_spectral_sops_get_params() - Get user configured Spectral 1431 * parameters 1432 * @arg: Pointer to handle for Spectral target_if internal private data 1433 * @params: Pointer to buffer into which Spectral parameters should be copied 1434 * 1435 * Return: 0 in case of success, -1 on failure 1436 */ 1437 uint32_t target_if_spectral_sops_get_params( 1438 void *arg, struct spectral_config *params); 1439 1440 /** 1441 * target_if_init_spectral_capability() - Initialize Spectral capability 1442 * @spectral: Pointer to Spectral target_if internal private data 1443 * 1444 * This is a workaround. 1445 * 1446 * Return: None 1447 */ 1448 void target_if_init_spectral_capability(struct target_if_spectral *spectral); 1449 1450 /** 1451 * target_if_start_spectral_scan() - Start spectral scan 1452 * @pdev: Pointer to pdev object 1453 * 1454 * API to start spectral scan 1455 * 1456 * Return: 0 in case of success, -1 on failure 1457 */ 1458 int target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev); 1459 1460 /** 1461 * target_if_get_spectral_config() - Get spectral configuration 1462 * @pdev: Pointer to pdev object 1463 * @param: Pointer to spectral_config structure in which the configuration 1464 * should be returned 1465 * 1466 * API to get the current spectral configuration 1467 * 1468 * Return: 0 in case of success, -1 on failure 1469 */ 1470 void target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 1471 struct spectral_config *param); 1472 1473 /** 1474 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 1475 * parameters 1476 * @spectral: Pointer to Spectral target_if internal private data 1477 * @spectral_params: Pointer to Spectral parameters 1478 * 1479 * Enable use of desired Spectral parameters by configuring them into HW, and 1480 * starting Spectral scan 1481 * 1482 * Return: 0 on success, 1 on failure 1483 */ 1484 int target_if_spectral_scan_enable_params( 1485 struct target_if_spectral *spectral, struct spectral_config *spectral_params); 1486 1487 /** 1488 * target_if_is_spectral_active() - Get whether Spectral is active 1489 * @pdev: Pointer to pdev object 1490 * 1491 * Return: True if Spectral is active, false if Spectral is not active 1492 */ 1493 bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev); 1494 1495 /** 1496 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 1497 * @pdev: Pointer to pdev object 1498 * 1499 * Return: True if Spectral is enabled, false if Spectral is not enabled 1500 */ 1501 bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev); 1502 1503 /** 1504 * target_if_set_debug_level() - Set debug level for Spectral 1505 * @pdev: Pointer to pdev object 1506 * @debug_level: Debug level 1507 * 1508 * Return: 0 in case of success 1509 */ 1510 int target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, 1511 uint32_t debug_level); 1512 1513 /** 1514 * target_if_get_debug_level() - Get debug level for Spectral 1515 * @pdev: Pointer to pdev object 1516 * 1517 * Return: Current debug level 1518 */ 1519 uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev); 1520 1521 1522 /** 1523 * target_if_get_spectral_capinfo() - Get Spectral capability information 1524 * @pdev: Pointer to pdev object 1525 * @outdata: Buffer into which data should be copied 1526 * 1527 * Return: void 1528 */ 1529 void target_if_get_spectral_capinfo( 1530 struct wlan_objmgr_pdev *pdev, 1531 void *outdata); 1532 1533 1534 /** 1535 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 1536 * @pdev: Pointer to pdev object 1537 * @outdata: Buffer into which data should be copied 1538 * 1539 * Return: void 1540 */ 1541 void target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, 1542 void *outdata); 1543 1544 /* 1545 * target_if_spectral_send_tlv_to_host - target_if_spectral_send_tlv_to_host 1546 * @spectral: Send the TLV information to Host 1547 * @data: Pointer to the TLV 1548 * @datalen: tlv length 1549 * 1550 * Return: Success/Failure 1551 * 1552 */ 1553 int target_if_spectral_send_tlv_to_host( 1554 struct target_if_spectral *spectral, 1555 uint8_t *data, uint32_t datalen); 1556 1557 void target_if_register_wmi_spectral_cmd_ops( 1558 struct wlan_objmgr_pdev *pdev, 1559 struct wmi_spectral_cmd_ops *cmd_ops); 1560 1561 1562 #ifdef WIN32 1563 #pragma pack(pop, target_if_spectral) 1564 #endif 1565 #ifdef __ATTRIB_PACK 1566 #undef __ATTRIB_PACK 1567 #endif 1568 1569 #endif /* _TARGET_IF_SPECTRAL_H_ */ 1570