1 /* 2 * Copyright (c) 2011,2017-2020 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 #ifdef DIRECT_BUF_RX_ENABLE 31 #include <target_if_direct_buf_rx_api.h> 32 #endif 33 #ifdef WIN32 34 #pragma pack(push, target_if_spectral, 1) 35 #define __ATTRIB_PACK 36 #else 37 #ifndef __ATTRIB_PACK 38 #define __ATTRIB_PACK __attribute__ ((packed)) 39 #endif 40 #endif 41 42 #include <spectral_defs_i.h> 43 #include <wmi_unified_param.h> 44 45 #define FREQ_OFFSET_10MHZ (10) 46 #define FREQ_OFFSET_40MHZ (40) 47 #define FREQ_OFFSET_80MHZ (80) 48 #ifndef SPECTRAL_USE_NL_BCAST 49 #define SPECTRAL_USE_NL_BCAST (0) 50 #endif 51 52 #define STATUS_PASS 1 53 #define STATUS_FAIL 0 54 #undef spectral_dbg_line 55 #define spectral_dbg_line() \ 56 spectral_debug("----------------------------------------------------") 57 58 #undef spectral_ops_not_registered 59 #define spectral_ops_not_registered(str) \ 60 spectral_info("SPECTRAL : %s not registered\n", (str)) 61 #undef not_yet_implemented 62 #define not_yet_implemented() \ 63 spectral_info("SPECTRAL : %s : %d Not yet implemented\n", \ 64 __func__, __LINE__) 65 66 #define SPECTRAL_HT20_NUM_BINS 56 67 #define SPECTRAL_HT20_FFT_LEN 56 68 #define SPECTRAL_HT20_DC_INDEX (SPECTRAL_HT20_FFT_LEN / 2) 69 #define SPECTRAL_HT20_DATA_LEN 60 70 #define SPECTRAL_HT20_TOTAL_DATA_LEN (SPECTRAL_HT20_DATA_LEN + 3) 71 #define SPECTRAL_HT40_TOTAL_NUM_BINS 128 72 #define SPECTRAL_HT40_DATA_LEN 135 73 #define SPECTRAL_HT40_TOTAL_DATA_LEN (SPECTRAL_HT40_DATA_LEN + 3) 74 #define SPECTRAL_HT40_FFT_LEN 128 75 #define SPECTRAL_HT40_DC_INDEX (SPECTRAL_HT40_FFT_LEN / 2) 76 77 /* 78 * Used for the SWAR to obtain approximate combined rssi 79 * in secondary 80Mhz segment 80 */ 81 #define OFFSET_CH_WIDTH_20 65 82 #define OFFSET_CH_WIDTH_40 62 83 #define OFFSET_CH_WIDTH_80 56 84 #define OFFSET_CH_WIDTH_160 50 85 86 /* Min and max for relevant Spectral params */ 87 #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2 (1) 88 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2 (9) 89 #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3 (5) 90 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT (9) 91 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000 (10) 92 #define SPECTRAL_PARAM_RPT_MODE_MIN (0) 93 #define SPECTRAL_PARAM_RPT_MODE_MAX (3) 94 95 /* DBR ring debug size for Spectral */ 96 #define SPECTRAL_DBR_RING_DEBUG_SIZE 512 97 98 #ifdef BIG_ENDIAN_HOST 99 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) do { \ 100 int j; \ 101 uint32_t *src, *dest; \ 102 src = (uint32_t *)(srcp); \ 103 dest = (uint32_t *)(destp); \ 104 for (j = 0; j < roundup((len), sizeof(uint32_t)) / 4; j++) { \ 105 *(dest + j) = qdf_le32_to_cpu(*(src + j)); \ 106 } \ 107 } while (0) 108 #else 109 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) \ 110 OS_MEMCPY((destp), (srcp), (len)); 111 #endif 112 113 #define DUMMY_NF_VALUE (-123) 114 /* 5 categories x (lower + upper) bands */ 115 #define MAX_INTERF 10 116 #define HOST_MAX_ANTENNA 3 117 /* Mask for time stamp from descriptor */ 118 #define SPECTRAL_TSMASK 0xFFFFFFFF 119 #define SPECTRAL_SIGNATURE 0xdeadbeef 120 /* Signature to write onto spectral buffer and then later validate */ 121 #define MEM_POISON_SIGNATURE (htobe32(0xdeadbeef)) 122 123 /* START of spectral GEN II HW specific details */ 124 #define SPECTRAL_PHYERR_SIGNATURE_GEN2 0xbb 125 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2 0xF9 126 #define TLV_TAG_ADC_REPORT_GEN2 0xFA 127 #define TLV_TAG_SEARCH_FFT_REPORT_GEN2 0xFB 128 129 /** 130 * enum spectral_160mhz_report_delivery_state - 160 MHz state machine states 131 * @SPECTRAL_REPORT_WAIT_PRIMARY80: Wait for primary80 report 132 * @SPECTRAL_REPORT_RX_PRIMARY80: Receive primary 80 report 133 * @SPECTRAL_REPORT_WAIT_SECONDARY80: Wait for secondory 80 report 134 * @SPECTRAL_REPORT_RX_SECONDARY80: Receive secondary 80 report 135 */ 136 enum spectral_160mhz_report_delivery_state { 137 SPECTRAL_REPORT_WAIT_PRIMARY80, 138 SPECTRAL_REPORT_RX_PRIMARY80, 139 SPECTRAL_REPORT_WAIT_SECONDARY80, 140 SPECTRAL_REPORT_RX_SECONDARY80, 141 }; 142 143 /** 144 * enum spectral_detector_id - Spectral detector id 145 * @SPECTRAL_DETECTOR_ID_0: Spectral detector 0 146 * @SPECTRAL_DETECTOR_ID_1: Spectral detector 1 147 * @SPECTRAL_DETECTOR_ID_2: Spectral detector 2 148 * @SPECTRAL_DETECTOR_ID_MAX: Max Spectral detector ID 149 * @SPECTRAL_DETECTOR_ID_INVALID: Invalid Spectral detector ID 150 */ 151 enum spectral_detector_id { 152 SPECTRAL_DETECTOR_ID_0, 153 SPECTRAL_DETECTOR_ID_1, 154 SPECTRAL_DETECTOR_ID_2, 155 SPECTRAL_DETECTOR_ID_MAX, 156 SPECTRAL_DETECTOR_ID_INVALID = 0xff, 157 }; 158 159 /** 160 * struct spectral_search_fft_info_gen2 - spectral search fft report for gen2 161 * @relpwr_db: Total bin power in db 162 * @num_str_bins_ib: Number of strong bins 163 * @base_pwr: Base power 164 * @total_gain_info: Total gain 165 * @fft_chn_idx: FFT chain on which report is originated 166 * @avgpwr_db: Average power in db 167 * @peak_mag: Peak power seen in the bins 168 * @peak_inx: Index of bin holding peak power 169 */ 170 struct spectral_search_fft_info_gen2 { 171 uint32_t relpwr_db; 172 uint32_t num_str_bins_ib; 173 uint32_t base_pwr; 174 uint32_t total_gain_info; 175 uint32_t fft_chn_idx; 176 uint32_t avgpwr_db; 177 uint32_t peak_mag; 178 int16_t peak_inx; 179 }; 180 181 /* 182 * XXX Check if we should be handling the endinness difference in some 183 * other way opaque to the host 184 */ 185 #ifdef BIG_ENDIAN_HOST 186 187 /** 188 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for big endian host 189 * @signature: signature 190 * @tag: tag 191 * @length: length 192 */ 193 struct spectral_phyerr_tlv_gen2 { 194 uint8_t signature; 195 uint8_t tag; 196 uint16_t length; 197 } __ATTRIB_PACK; 198 199 #else 200 201 /** 202 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for little endian host 203 * @length: length 204 * @tag: tag 205 * @signature: signature 206 */ 207 struct spectral_phyerr_tlv_gen2 { 208 uint16_t length; 209 uint8_t tag; 210 uint8_t signature; 211 } __ATTRIB_PACK; 212 213 #endif /* BIG_ENDIAN_HOST */ 214 215 /** 216 * struct spectral_phyerr_hdr_gen2 - phyerr header for gen2 HW 217 * @hdr_a: Header[0:31] 218 * @hdr_b: Header[32:63] 219 */ 220 struct spectral_phyerr_hdr_gen2 { 221 uint32_t hdr_a; 222 uint32_t hdr_b; 223 }; 224 225 /* 226 * Segment ID information for 80+80. 227 * 228 * If the HW micro-architecture specification extends this DWORD for other 229 * purposes, then redefine+rename accordingly. For now, the specification 230 * mentions only segment ID (though this doesn't require an entire DWORD) 231 * without mention of any generic terminology for the DWORD, or any reservation. 232 * We use nomenclature accordingly. 233 */ 234 typedef uint32_t SPECTRAL_SEGID_INFO; 235 236 /** 237 * struct spectral_phyerr_fft_gen2 - fft info in phyerr event 238 * @buf: fft report 239 */ 240 struct spectral_phyerr_fft_gen2 { 241 uint8_t buf[0]; 242 }; 243 /* END of spectral GEN II HW specific details */ 244 245 /* START of spectral GEN III HW specific details */ 246 247 #define get_bitfield(value, size, pos) \ 248 (((value) >> (pos)) & ((1 << (size)) - 1)) 249 #define unsigned_to_signed(value, width) \ 250 (((value) >= (1 << ((width) - 1))) ? \ 251 (value - (1 << (width))) : (value)) 252 253 #define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_POS_GEN3 (29) 254 #define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3 (2) 255 #define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_POS_GEN3 (0) 256 #define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_SIZE_GEN3 (8) 257 #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_POS_GEN3 (18) 258 #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3 (10) 259 #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3 (31) 260 #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3 (1) 261 #define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1 (30) 262 #define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1 (1) 263 #define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2 (16) 264 #define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2 (1) 265 266 #define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) 267 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) 268 #define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) 269 #define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) 270 271 #define NUM_SPECTRAL_DETECTORS_GEN3_V1 (3) 272 #define NUM_SPECTRAL_DETECTORS_GEN3_V2 (2) 273 #define FFT_REPORT_HEADER_LENGTH_GEN3_V2 (24) 274 #define FFT_REPORT_HEADER_LENGTH_GEN3_V1 (16) 275 #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1 (0) 276 #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2 (16) 277 278 #define PHYERR_HDR_SIG_POS \ 279 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig)) 280 #define PHYERR_HDR_TAG_POS \ 281 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_tag)) 282 #define SPECTRAL_FFT_BINS_POS \ 283 (offsetof(struct spectral_phyerr_fft_report_gen3, buf)) 284 285 /** 286 * struct phyerr_info - spectral search fft report for gen3 287 * @data: handle to phyerror buffer 288 * @datalen: length of phyerror bufer 289 * @p_rfqual: rf quality matrices 290 * @p_chaninfo: pointer to chaninfo 291 * @tsf64: 64 bit TSF 292 * @acs_stats: acs stats 293 */ 294 struct phyerr_info { 295 uint8_t *data; 296 uint32_t datalen; 297 struct target_if_spectral_rfqual_info *p_rfqual; 298 struct target_if_spectral_chan_info *p_chaninfo; 299 uint64_t tsf64; 300 struct target_if_spectral_acs_stats *acs_stats; 301 }; 302 303 /** 304 * struct spectral_search_fft_info_gen3 - spectral search fft report for gen3 305 * @timestamp: Timestamp at which fft report was generated 306 * @fft_detector_id: Which radio generated this report 307 * @fft_num: The FFT count number. Set to 0 for short FFT. 308 * @fft_radar_check: NA for spectral 309 * @fft_peak_sidx: Index of bin with maximum power 310 * @fft_chn_idx: Rx chain index 311 * @fft_base_pwr_db: Base power in dB 312 * @fft_total_gain_db: Total gain in dB 313 * @fft_num_str_bins_ib: Number of strong bins in the report 314 * @fft_peak_mag: Peak magnitude 315 * @fft_avgpwr_db: Average power in dB 316 * @fft_relpwr_db: Relative power in dB 317 */ 318 struct spectral_search_fft_info_gen3 { 319 uint32_t timestamp; 320 uint32_t fft_detector_id; 321 uint32_t fft_num; 322 uint32_t fft_radar_check; 323 int32_t fft_peak_sidx; 324 uint32_t fft_chn_idx; 325 uint32_t fft_base_pwr_db; 326 uint32_t fft_total_gain_db; 327 uint32_t fft_num_str_bins_ib; 328 int32_t fft_peak_mag; 329 uint32_t fft_avgpwr_db; 330 uint32_t fft_relpwr_db; 331 }; 332 333 /** 334 * struct spectral_phyerr_sfftreport_gen3 - fft info in phyerr event 335 * @fft_timestamp: Timestamp at which fft report was generated 336 * @fft_hdr_sig: signature 337 * @fft_hdr_tag: tag 338 * @fft_hdr_length: length 339 * @hdr_a: Header[0:31] 340 * @hdr_b: Header[32:63] 341 * @hdr_c: Header[64:95] 342 * @resv: Header[96:127] 343 * @buf: fft bins 344 */ 345 struct spectral_phyerr_fft_report_gen3 { 346 uint32_t fft_timestamp; 347 #ifdef BIG_ENDIAN_HOST 348 uint8_t fft_hdr_sig; 349 uint8_t fft_hdr_tag; 350 uint16_t fft_hdr_length; 351 #else 352 uint16_t fft_hdr_length; 353 uint8_t fft_hdr_tag; 354 uint8_t fft_hdr_sig; 355 #endif /* BIG_ENDIAN_HOST */ 356 uint32_t hdr_a; 357 uint32_t hdr_b; 358 uint32_t hdr_c; 359 uint32_t resv; 360 uint8_t buf[0]; 361 } __ATTRIB_PACK; 362 363 /** 364 * struct sscan_report_fields_gen3 - Fields of spectral report 365 * @sscan_agc_total_gain: The AGC total gain in DB. 366 * @inband_pwr_db: The in-band power of the signal in 1/2 DB steps 367 * @sscan_gainchange: This bit is set to 1 if a gainchange occurred during 368 * the spectral scan FFT. Software may choose to 369 * disregard the results. 370 * @sscan_pri80: This is set to 1 to indicate that the Spectral scan was 371 * performed on the pri80 segment. Software may choose to 372 * disregard the FFT sample if this is set to 1 but detector ID 373 * does not correspond to the ID for the pri80 segment. 374 */ 375 struct sscan_report_fields_gen3 { 376 uint8_t sscan_agc_total_gain; 377 int16_t inband_pwr_db; 378 uint8_t sscan_gainchange; 379 uint8_t sscan_pri80; 380 }; 381 382 /** 383 * struct spectral_sscan_summary_report_gen3 - Spectral summary report 384 * event 385 * @sscan_timestamp: Timestamp at which fft report was generated 386 * @sscan_hdr_sig: signature 387 * @sscan_hdr_tag: tag 388 * @sscan_hdr_length: length 389 * @hdr_a: Header[0:31] 390 * @resv: Header[32:63] 391 * @hdr_b: Header[64:95] 392 * @hdr_c: Header[96:127] 393 */ 394 struct spectral_sscan_summary_report_gen3 { 395 u_int32_t sscan_timestamp; 396 #ifdef BIG_ENDIAN_HOST 397 u_int8_t sscan_hdr_sig; 398 u_int8_t sscan_hdr_tag; 399 u_int16_t sscan_hdr_length; 400 #else 401 u_int16_t sscan_hdr_length; 402 u_int8_t sscan_hdr_tag; 403 u_int8_t sscan_hdr_sig; 404 #endif /* BIG_ENDIAN_HOST */ 405 u_int32_t hdr_a; 406 u_int32_t res1; 407 u_int32_t hdr_b; 408 u_int32_t hdr_c; 409 } __ATTRIB_PACK; 410 411 #ifdef DIRECT_BUF_RX_ENABLE 412 /** 413 * struct Spectral_report - spectral report 414 * @data: Report buffer 415 * @noisefloor: Noise floor values 416 * @reset_delay: Time taken for warm reset in us 417 * @cfreq1: center frequency 1 418 * @cfreq2: center frequency 2 419 * @ch_width: channel width 420 */ 421 struct spectral_report { 422 uint8_t *data; 423 int32_t noisefloor[DBR_MAX_CHAINS]; 424 uint32_t reset_delay; 425 uint32_t cfreq1; 426 uint32_t cfreq2; 427 uint32_t ch_width; 428 }; 429 #endif 430 /* END of spectral GEN III HW specific details */ 431 432 typedef signed char pwr_dbm; 433 434 /** 435 * enum spectral_gen - spectral hw generation 436 * @SPECTRAL_GEN1 : spectral hw gen 1 437 * @SPECTRAL_GEN2 : spectral hw gen 2 438 * @SPECTRAL_GEN3 : spectral hw gen 3 439 */ 440 enum spectral_gen { 441 SPECTRAL_GEN1, 442 SPECTRAL_GEN2, 443 SPECTRAL_GEN3, 444 }; 445 446 /** 447 * enum spectral_fftbin_size_war - spectral fft bin size war 448 * @SPECTRAL_FFTBIN_SIZE_NO_WAR : No WAR applicable for Spectral FFT bin size 449 * @SPECTRAL_FFTBIN_SIZE_2BYTE_TO_1BYTE : Spectral FFT bin size: Retain only 450 * least significant byte from 2 byte 451 * FFT bin transferred by HW 452 * @SPECTRAL_FFTBIN_SIZE_4BYTE_TO_1BYTE : Spectral FFT bin size: Retain only 453 * least significant byte from 4 byte 454 * FFT bin transferred by HW 455 */ 456 enum spectral_fftbin_size_war { 457 SPECTRAL_FFTBIN_SIZE_NO_WAR = 0, 458 SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE = 1, 459 SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE = 2, 460 }; 461 462 /** 463 * enum spectral_report_format_version - This represents the report format 464 * version number within each Spectral generation. 465 * @SPECTRAL_REPORT_FORMAT_VERSION_1 : version 1 466 * @SPECTRAL_REPORT_FORMAT_VERSION_2 : version 2 467 */ 468 enum spectral_report_format_version { 469 SPECTRAL_REPORT_FORMAT_VERSION_1, 470 SPECTRAL_REPORT_FORMAT_VERSION_2, 471 }; 472 473 /** 474 * struct spectral_fft_bin_len_adj_swar - Encapsulate information required for 475 * Spectral FFT bin length adjusting software WARS. 476 * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for 477 * in-band report format. This would be required on some chipsets under the 478 * following circumstances: In report mode 2 only the in-band bins are DMA'ed. 479 * Scatter/gather is used. However, the HW generates all bins, not just in-band, 480 * and reports the number of bins accordingly. The subsystem arranging for the 481 * DMA cannot change this value. On such chipsets the adjustment required at the 482 * host driver is to check if report format is 2, and if so halve the number of 483 * bins reported to get the number actually DMA'ed. 484 * @null_fftbin_adj: Whether to remove NULL FFT bins for report mode (1) in 485 * which only summary of metrics for each completed FFT + spectral scan summary 486 * report are to be provided. This would be required on some chipsets under the 487 * following circumstances: In report mode 1, HW reports a length corresponding 488 * to all bins, and provides bins with value 0. This is because the subsystem 489 * arranging for the FFT information does not arrange for DMA of FFT bin values 490 * (as expected), but cannot arrange for a smaller length to be reported by HW. 491 * In these circumstances, the driver would have to disregard the NULL bins and 492 * report a bin count of 0 to higher layers. 493 * @packmode_fftbin_size_adj: Pack mode in HW refers to packing of each Spectral 494 * FFT bin into 2 bytes. But due to a bug HW reports 2 times the expected length 495 * when packmode is enabled. This SWAR compensates this bug by dividing the 496 * length with 2. 497 * @fftbin_size_war: Type of FFT bin size SWAR 498 */ 499 struct spectral_fft_bin_len_adj_swar { 500 u_int8_t inband_fftbin_size_adj; 501 u_int8_t null_fftbin_adj; 502 uint8_t packmode_fftbin_size_adj; 503 enum spectral_fftbin_size_war fftbin_size_war; 504 }; 505 506 /** 507 * struct spectral_report_params - Parameters related to format of Spectral 508 * report. 509 * @version: This represents the report format version number within each 510 * Spectral generation. 511 * @ssumaary_padding_bytes: Number of bytes of padding after Spectral summary 512 * report 513 * @fft_report_hdr_len: Number of bytes in the header of the FFT report. This 514 * has to be subtracted from the length field of FFT report to find the length 515 * of FFT bins. 516 * @fragmentation_160: This indicates whether Spectral reports in 160/80p80 is 517 * fragmented. 518 * @max_agile_ch_width: Maximum agile BW supported by the target 519 * @detid_mode_table: Detector ID to Spectral scan mode table 520 * @num_spectral_detectors: Total number of Spectral detectors 521 * @marker: Describes the boundaries of pri80, 5 MHz and sec80 bins 522 */ 523 struct spectral_report_params { 524 enum spectral_report_format_version version; 525 uint8_t ssumaary_padding_bytes; 526 uint8_t fft_report_hdr_len; 527 bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX]; 528 enum phy_ch_width max_agile_ch_width; 529 enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX]; 530 uint8_t num_spectral_detectors; 531 struct spectral_fft_bin_markers_160_165mhz 532 marker[SPECTRAL_SCAN_MODE_MAX]; 533 }; 534 535 /** 536 * struct spectral_param_min_max - Spectral parameter minimum and maximum values 537 * @fft_size_min: Minimum value of fft_size 538 * @fft_size_max: Maximum value of fft_size for each BW 539 */ 540 struct spectral_param_min_max { 541 uint16_t fft_size_min; 542 uint16_t fft_size_max[CH_WIDTH_MAX]; 543 }; 544 545 /** 546 * struct spectral_timestamp_swar - Spectral time stamp WAR related parameters 547 * @timestamp_war_offset: Offset to be added to correct timestamp 548 * @target_reset_count: Number of times target exercised the reset routine 549 * @last_fft_timestamp: last fft report timestamp 550 */ 551 struct spectral_timestamp_war { 552 uint32_t timestamp_war_offset[SPECTRAL_SCAN_MODE_MAX]; 553 uint64_t target_reset_count; 554 uint32_t last_fft_timestamp[SPECTRAL_SCAN_MODE_MAX]; 555 }; 556 557 #if ATH_PERF_PWR_OFFLOAD 558 /** 559 * enum target_if_spectral_info - Enumerations for specifying which spectral 560 * information (among parameters and states) 561 * is desired. 562 * @TARGET_IF_SPECTRAL_INFO_ACTIVE: Indicated whether spectral is active 563 * @TARGET_IF_SPECTRAL_INFO_ENABLED: Indicated whether spectral is enabled 564 * @TARGET_IF_SPECTRAL_INFO_PARAMS: Config params 565 */ 566 enum target_if_spectral_info { 567 TARGET_IF_SPECTRAL_INFO_ACTIVE, 568 TARGET_IF_SPECTRAL_INFO_ENABLED, 569 TARGET_IF_SPECTRAL_INFO_PARAMS, 570 }; 571 #endif /* ATH_PERF_PWR_OFFLOAD */ 572 573 /* forward declaration */ 574 struct target_if_spectral; 575 576 /** 577 * struct target_if_spectral_chan_info - Channel information 578 * @center_freq1: center frequency 1 in MHz 579 * @center_freq2: center frequency 2 in MHz -valid only for 580 * 11ACVHT 80PLUS80 mode 581 * @chan_width: channel width in MHz 582 */ 583 struct target_if_spectral_chan_info { 584 uint16_t center_freq1; 585 uint16_t center_freq2; 586 uint8_t chan_width; 587 }; 588 589 /** 590 * struct target_if_spectral_acs_stats - EACS stats from spectral samples 591 * @nfc_ctl_rssi: Control chan rssi 592 * @nfc_ext_rssi: Extension chan rssi 593 * @ctrl_nf: Control chan Noise Floor 594 * @ext_nf: Extension chan Noise Floor 595 */ 596 struct target_if_spectral_acs_stats { 597 int8_t nfc_ctl_rssi; 598 int8_t nfc_ext_rssi; 599 int8_t ctrl_nf; 600 int8_t ext_nf; 601 }; 602 603 /** 604 * struct target_if_spectral_perchain_rssi_info - per chain rssi info 605 * @rssi_pri20: Rssi of primary 20 Mhz 606 * @rssi_sec20: Rssi of secondary 20 Mhz 607 * @rssi_sec40: Rssi of secondary 40 Mhz 608 * @rssi_sec80: Rssi of secondary 80 Mhz 609 */ 610 struct target_if_spectral_perchain_rssi_info { 611 int8_t rssi_pri20; 612 int8_t rssi_sec20; 613 int8_t rssi_sec40; 614 int8_t rssi_sec80; 615 }; 616 617 /** 618 * struct target_if_spectral_rfqual_info - RF measurement information 619 * @rssi_comb: RSSI Information 620 * @pc_rssi_info: XXX : For now, we know we are getting information 621 * for only 4 chains at max. For future extensions 622 * use a define 623 * @noise_floor: Noise floor information 624 */ 625 struct target_if_spectral_rfqual_info { 626 int8_t rssi_comb; 627 struct target_if_spectral_perchain_rssi_info pc_rssi_info[4]; 628 int16_t noise_floor[4]; 629 }; 630 631 #define GET_TARGET_IF_SPECTRAL_OPS(spectral) \ 632 ((struct target_if_spectral_ops *)(&((spectral)->spectral_ops))) 633 634 /** 635 * struct target_if_spectral_ops - spectral low level ops table 636 * @get_tsf64: Get 64 bit TSF value 637 * @get_capability: Get capability info 638 * @set_rxfilter: Set rx filter 639 * @get_rxfilter: Get rx filter 640 * @is_spectral_active: Check whether icm is active 641 * @is_spectral_enabled: Check whether spectral is enabled 642 * @start_spectral_scan: Start spectral scan 643 * @stop_spectral_scan: Stop spectral scan 644 * @get_extension_channel: Get extension channel 645 * @get_ctl_noisefloor: Get control noise floor 646 * @get_ext_noisefloor: Get extension noise floor 647 * @configure_spectral: Set spectral configurations 648 * @get_spectral_config: Get spectral configurations 649 * @get_ent_spectral_mask: Get spectral mask 650 * @get_mac_address: Get mac address 651 * @get_current_channel: Get current channel 652 * @reset_hw: Reset HW 653 * @get_chain_noise_floor: Get Channel noise floor 654 * @spectral_process_phyerr: Process phyerr event 655 * @process_spectral_report: Process spectral report 656 */ 657 struct target_if_spectral_ops { 658 uint64_t (*get_tsf64)(void *arg); 659 uint32_t (*get_capability)( 660 void *arg, enum spectral_capability_type type); 661 uint32_t (*set_rxfilter)(void *arg, int rxfilter); 662 uint32_t (*get_rxfilter)(void *arg); 663 uint32_t (*is_spectral_active)(void *arg, 664 enum spectral_scan_mode smode); 665 uint32_t (*is_spectral_enabled)(void *arg, 666 enum spectral_scan_mode smode); 667 uint32_t (*start_spectral_scan)(void *arg, 668 enum spectral_scan_mode smode, 669 enum spectral_cp_error_code *err); 670 uint32_t (*stop_spectral_scan)(void *arg, 671 enum spectral_scan_mode smode); 672 uint32_t (*get_extension_channel)(void *arg, 673 enum spectral_scan_mode smode); 674 int8_t (*get_ctl_noisefloor)(void *arg); 675 int8_t (*get_ext_noisefloor)(void *arg); 676 uint32_t (*configure_spectral)( 677 void *arg, 678 struct spectral_config *params, 679 enum spectral_scan_mode smode); 680 uint32_t (*get_spectral_config)( 681 void *arg, 682 struct spectral_config *params, 683 enum spectral_scan_mode smode); 684 uint32_t (*get_ent_spectral_mask)(void *arg); 685 uint32_t (*get_mac_address)(void *arg, char *addr); 686 uint32_t (*get_current_channel)(void *arg, 687 enum spectral_scan_mode smode); 688 uint32_t (*reset_hw)(void *arg); 689 uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf); 690 int (*spectral_process_phyerr)(struct target_if_spectral *spectral, 691 uint8_t *data, uint32_t datalen, 692 struct target_if_spectral_rfqual_info *p_rfqual, 693 struct target_if_spectral_chan_info *p_chaninfo, 694 uint64_t tsf64, 695 struct target_if_spectral_acs_stats *acs_stats); 696 int (*process_spectral_report)(struct wlan_objmgr_pdev *pdev, 697 void *payload); 698 }; 699 700 /** 701 * struct target_if_spectral_stats - spectral stats info 702 * @num_spectral_detects: Total num. of spectral detects 703 * @total_phy_errors: Total number of phyerrors 704 * @owl_phy_errors: Indicated phyerrors in old gen1 chipsets 705 * @pri_phy_errors: Phyerrors in primary channel 706 * @ext_phy_errors: Phyerrors in secondary channel 707 * @dc_phy_errors: Phyerrors due to dc 708 * @early_ext_phy_errors: Early secondary channel phyerrors 709 * @bwinfo_errors: Bandwidth info errors 710 * @datalen_discards: Invalid data length errors, seen in gen1 chipsets 711 * @rssi_discards bw: Indicates reports dropped due to RSSI threshold 712 * @last_reset_tstamp: Last reset time stamp 713 */ 714 struct target_if_spectral_stats { 715 uint32_t num_spectral_detects; 716 uint32_t total_phy_errors; 717 uint32_t owl_phy_errors; 718 uint32_t pri_phy_errors; 719 uint32_t ext_phy_errors; 720 uint32_t dc_phy_errors; 721 uint32_t early_ext_phy_errors; 722 uint32_t bwinfo_errors; 723 uint32_t datalen_discards; 724 uint32_t rssi_discards; 725 uint64_t last_reset_tstamp; 726 }; 727 728 /** 729 * struct target_if_spectral_event - spectral event structure 730 * @se_ts: Original 15 bit recv timestamp 731 * @se_full_ts: 64-bit full timestamp from interrupt time 732 * @se_rssi: Rssi of spectral event 733 * @se_bwinfo: Rssi of spectral event 734 * @se_dur: Duration of spectral pulse 735 * @se_chanindex: Channel of event 736 * @se_list: List of spectral events 737 */ 738 struct target_if_spectral_event { 739 uint32_t se_ts; 740 uint64_t se_full_ts; 741 uint8_t se_rssi; 742 uint8_t se_bwinfo; 743 uint8_t se_dur; 744 uint8_t se_chanindex; 745 746 STAILQ_ENTRY(spectral_event) se_list; 747 }; 748 749 /** 750 * struct target_if_chain_noise_pwr_info - Noise power info for each channel 751 * @rptcount: Count of reports in pwr array 752 * @un_cal_nf: Uncalibrated noise floor 753 * @factory_cal_nf: Noise floor as calibrated at the factory for module 754 * @median_pwr: Median power (median of pwr array) 755 * @pwr: Power reports 756 */ 757 struct target_if_chain_noise_pwr_info { 758 int rptcount; 759 pwr_dbm un_cal_nf; 760 pwr_dbm factory_cal_nf; 761 pwr_dbm median_pwr; 762 pwr_dbm pwr[]; 763 } __ATTRIB_PACK; 764 765 /** 766 * struct target_if_spectral_chan_stats - Channel information 767 * @cycle_count: Cycle count 768 * @channel_load: Channel load 769 * @per: Period 770 * @noisefloor: Noise floor 771 * @comp_usablity: Computed usability 772 * @maxregpower: Maximum allowed regulatary power 773 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 774 * @maxregpower_sec80: Max regulatory power in secondary 80 Mhz 775 */ 776 struct target_if_spectral_chan_stats { 777 int cycle_count; 778 int channel_load; 779 int per; 780 int noisefloor; 781 uint16_t comp_usablity; 782 int8_t maxregpower; 783 uint16_t comp_usablity_sec80; 784 int8_t maxregpower_sec80; 785 }; 786 787 #if ATH_PERF_PWR_OFFLOAD 788 789 /** 790 * struct target_if_spectral_cache - Cache used to minimize WMI operations 791 * in offload architecture 792 * @osc_spectral_enabled: Whether Spectral is enabled 793 * @osc_spectral_active: Whether spectral is active 794 * XXX: Ideally, we should NOT cache this 795 * since the hardware can self clear the bit, 796 * the firmware can possibly stop spectral due to 797 * intermittent off-channel activity, etc 798 * A WMI read command should be introduced to handle 799 * this This will be discussed. 800 * @osc_params: Spectral parameters 801 * @osc_is_valid: Whether the cache is valid 802 */ 803 struct target_if_spectral_cache { 804 uint8_t osc_spectral_enabled; 805 uint8_t osc_spectral_active; 806 struct spectral_config osc_params; 807 uint8_t osc_is_valid; 808 }; 809 810 /** 811 * struct target_if_spectral_param_state_info - Structure used to represent and 812 * manage spectral information 813 * (parameters and states) 814 * @osps_lock: Lock to synchronize accesses to information 815 * @osps_cache: Cacheable' information 816 */ 817 struct target_if_spectral_param_state_info { 818 qdf_spinlock_t osps_lock; 819 struct target_if_spectral_cache osps_cache; 820 /* XXX - Non-cacheable information goes here, in the future */ 821 }; 822 #endif /* ATH_PERF_PWR_OFFLOAD */ 823 824 struct vdev_spectral_configure_params; 825 struct vdev_spectral_enable_params; 826 827 /** 828 * struct spectral_wmi_ops - structure used holding the operations 829 * related to Spectral WMI 830 * @wmi_spectral_configure_cmd_send: Configure Spectral parameters 831 * @wmi_spectral_enable_cmd_send: Enable/Disable Spectral 832 * @wmi_spectral_crash_inject: Inject FW crash 833 * @wmi_extract_pdev_sscan_fw_cmd_fixed_param: Extract Fixed params from 834 * start scan response event 835 * @wmi_extract_pdev_sscan_fft_bin_index: Extract TLV which describes FFT 836 * bin indices from start scan response event 837 * @wmi_unified_register_event_handler: Register WMI event handler 838 * @wmi_unified_unregister_event_handler: Unregister WMI event handler 839 */ 840 struct spectral_wmi_ops { 841 QDF_STATUS (*wmi_spectral_configure_cmd_send)( 842 wmi_unified_t wmi_hdl, 843 struct vdev_spectral_configure_params *param); 844 QDF_STATUS (*wmi_spectral_enable_cmd_send)( 845 wmi_unified_t wmi_hdl, 846 struct vdev_spectral_enable_params *param); 847 QDF_STATUS (*wmi_spectral_crash_inject)( 848 wmi_unified_t wmi_handle, struct crash_inject *param); 849 QDF_STATUS (*wmi_extract_pdev_sscan_fw_cmd_fixed_param)( 850 wmi_unified_t wmi_handle, uint8_t *evt_buf, 851 struct spectral_startscan_resp_params *param); 852 QDF_STATUS (*wmi_extract_pdev_sscan_fft_bin_index)( 853 wmi_unified_t wmi_handle, uint8_t *evt_buf, 854 struct spectral_fft_bin_markers_160_165mhz *param); 855 int (*wmi_unified_register_event_handler)( 856 wmi_unified_t wmi_handle, 857 wmi_conv_event_id event_id, 858 wmi_unified_event_handler handler_func, 859 uint8_t rx_ctx); 860 int (*wmi_unified_unregister_event_handler)(wmi_unified_t wmi_handle, 861 wmi_conv_event_id event_id); 862 }; 863 864 /** 865 * struct spectral_tgt_ops - structure used holding the operations 866 * related to target operations 867 * @tgt_get_psoc_from_scn_hdl: Function to get psoc from scn 868 */ 869 struct spectral_tgt_ops { 870 struct wlan_objmgr_psoc *(*tgt_get_psoc_from_scn_hdl)(void *scn_handle); 871 }; 872 873 /** 874 * struct spectral_param_properties - structure holding Spectral 875 * parameter properties 876 * @supported: Parameter is supported or not 877 * @common_all_modes: Parameter should be common for all modes or not 878 */ 879 struct spectral_param_properties { 880 bool supported; 881 bool common_all_modes; 882 }; 883 884 /** 885 * struct target_if_spectral - main spectral structure 886 * @pdev: Pointer to pdev 887 * @spectral_ops: Target if internal Spectral low level operations table 888 * @capability: Spectral capabilities structure 889 * @properties: Spectral parameter properties per mode 890 * @spectral_lock: Lock used for internal Spectral operations 891 * @vdev_id: VDEV id for all spectral modes 892 * @spectral_curchan_radindex: Current channel spectral index 893 * @spectral_extchan_radindex: Extension channel spectral index 894 * @spectraldomain: Current Spectral domain 895 * @spectral_proc_phyerr: Flags to process for PHY errors 896 * @spectral_defaultparams: Default PHY params per Spectral stat 897 * @spectral_stats: Spectral related stats 898 * @events: Events structure 899 * @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel? 900 * @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI? 901 * @sc_spectral_20_40_mode: Is AP in 20-40 mode? 902 * @sc_spectral_noise_pwr_cal: Noise power cal required? 903 * @sc_spectral_non_edma: Is the spectral capable device Non-EDMA? 904 * @upper_is_control: Upper segment is primary 905 * @upper_is_extension: Upper segment is secondary 906 * @lower_is_control: Lower segment is primary 907 * @lower_is_extension: Lower segment is secondary 908 * @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral 909 * mute test 910 * @spectral_numbins: Number of bins 911 * @spectral_fft_len: FFT length 912 * @spectral_data_len: Total phyerror report length 913 * @lb_edge_extrabins: Number of extra bins on left band edge 914 * @rb_edge_extrabins: Number of extra bins on right band edge 915 * @spectral_max_index_offset: Max FFT index offset (20 MHz mode) 916 * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode) 917 * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode) 918 * @spectral_dc_index: At which index DC is present 919 * @send_single_packet: Deprecated 920 * @spectral_sent_msg: Indicates whether we send report to upper layers 921 * @params: Spectral parameters 922 * @last_capture_time: Indicates timestamp of previouse report 923 * @num_spectral_data: Number of Spectral samples received in current session 924 * @total_spectral_data: Total number of Spectral samples received 925 * @max_rssi: Maximum RSSI 926 * @detects_control_channel: NA 927 * @detects_extension_channel: NA 928 * @detects_below_dc: NA 929 * @detects_above_dc: NA 930 * @sc_scanning: Indicates active wifi scan 931 * @sc_spectral_scan: Indicates active specral scan 932 * @sc_spectral_full_scan: Deprecated 933 * @scan_start_tstamp: Deprecated 934 * @last_tstamp: Deprecated 935 * @first_tstamp: Deprecated 936 * @spectral_samp_count: Deprecated 937 * @sc_spectral_samp_count: Deprecated 938 * @noise_pwr_reports_reqd: Number of noise power reports required 939 * @noise_pwr_reports_recv: Number of noise power reports received 940 * @noise_pwr_reports_lock: Lock used for Noise power report processing 941 * @noise_pwr_chain_ctl: Noise power report - control channel 942 * @noise_pwr_chain_ext: Noise power report - extension channel 943 * @chaninfo: Channel statistics 944 * @tsf64: Latest TSF Value 945 * @param_info: Offload architecture Spectral parameter cache information 946 * @ch_width: Indicates Channel Width 20/40/80/160 MHz for each Spectral mode 947 * @diag_stats: Diagnostic statistics 948 * @is_160_format: Indicates whether information provided by HW is in altered 949 * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) 950 * @is_lb_edge_extrabins_format: Indicates whether information provided by 951 * HW has 4 extra bins, at left band edge, for report mode 2 952 * @is_rb_edge_extrabins_format: Indicates whether information provided 953 * by HW has 4 extra bins, at right band edge, for report mode 2 954 * @is_sec80_rssi_war_required: Indicates whether the software workaround is 955 * required to obtain approximate combined RSSI for secondary 80Mhz segment 956 * @simctx: Spectral Simulation context 957 * @spectral_gen: Spectral hardware generation 958 * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware 959 * generation 960 * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV 961 * header, for the given hardware generation 962 * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV 963 * header, for the given hardware generation 964 * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware 965 * generation 966 * @nl_cb: Netlink callbacks 967 * @use_nl_bcast: Whether to use Netlink broadcast/unicast 968 * @send_phy_data: Send data to the application layer for a particular msg type 969 * @len_adj_swar: Spectral fft bin length adjustment SWAR related info 970 * @timestamp_war: Spectral time stamp WAR related info 971 * @dbr_ring_debug: Whether Spectral DBR ring debug is enabled 972 * @dbr_buff_debug: Whether Spectral DBR buffer debug is enabled 973 * @direct_dma_support: Whether Direct-DMA is supported on the current radio 974 * @prev_tstamp: Timestamp of the previously received sample, which has to be 975 * compared with the current tstamp to check descrepancy 976 * @rparams: Parameters related to Spectral report structure 977 * @param_min_max: Spectral parameter's minimum and maximum values 978 */ 979 struct target_if_spectral { 980 struct wlan_objmgr_pdev *pdev_obj; 981 struct target_if_spectral_ops spectral_ops; 982 struct spectral_caps capability; 983 struct spectral_param_properties 984 properties[SPECTRAL_SCAN_MODE_MAX][SPECTRAL_PARAM_MAX]; 985 qdf_spinlock_t spectral_lock; 986 uint8_t vdev_id[SPECTRAL_SCAN_MODE_MAX]; 987 int16_t spectral_curchan_radindex; 988 int16_t spectral_extchan_radindex; 989 uint32_t spectraldomain; 990 uint32_t spectral_proc_phyerr; 991 struct spectral_config spectral_defaultparams; 992 struct target_if_spectral_stats spectral_stats; 993 struct target_if_spectral_event *events; 994 unsigned int sc_spectral_ext_chan_ok:1, 995 sc_spectral_combined_rssi_ok:1, 996 sc_spectral_20_40_mode:1, 997 sc_spectral_noise_pwr_cal:1, 998 sc_spectral_non_edma:1; 999 int upper_is_control; 1000 int upper_is_extension; 1001 int lower_is_control; 1002 int lower_is_extension; 1003 uint8_t sc_spectraltest_ieeechan; 1004 int spectral_numbins; 1005 int spectral_fft_len; 1006 int spectral_data_len; 1007 1008 /* 1009 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are 1010 * delivered. However, there can be additional bins reported for 1011 * AR900B version 2.0 and QCA9984 as described next: 1012 * 1013 * AR900B version 2.0: An additional tone is processed on the right 1014 * hand side in order to facilitate detection of radar pulses out to 1015 * the extreme band-edge of the channel frequency. Since the HW design 1016 * processes four tones at a time, this requires one additional Dword 1017 * to be added to the search FFT report. 1018 * 1019 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary + 1020 * 1x-oversampled bins (in-band) per FFT, then 8 more bins 1021 * (4 more on left side and 4 more on right side)are added. 1022 */ 1023 1024 int lb_edge_extrabins; 1025 int rb_edge_extrabins; 1026 int spectral_max_index_offset; 1027 int spectral_upper_max_index_offset; 1028 int spectral_lower_max_index_offset; 1029 int spectral_dc_index; 1030 int send_single_packet; 1031 int spectral_sent_msg; 1032 int classify_scan; 1033 qdf_timer_t classify_timer; 1034 struct spectral_config params[SPECTRAL_SCAN_MODE_MAX]; 1035 bool params_valid[SPECTRAL_SCAN_MODE_MAX]; 1036 struct spectral_classifier_params classifier_params; 1037 int last_capture_time; 1038 int num_spectral_data; 1039 int total_spectral_data; 1040 int max_rssi; 1041 int detects_control_channel; 1042 int detects_extension_channel; 1043 int detects_below_dc; 1044 int detects_above_dc; 1045 int sc_scanning; 1046 int sc_spectral_scan; 1047 int sc_spectral_full_scan; 1048 uint64_t scan_start_tstamp; 1049 uint32_t last_tstamp; 1050 uint32_t first_tstamp; 1051 uint32_t spectral_samp_count; 1052 uint32_t sc_spectral_samp_count; 1053 int noise_pwr_reports_reqd; 1054 int noise_pwr_reports_recv; 1055 qdf_spinlock_t noise_pwr_reports_lock; 1056 struct target_if_chain_noise_pwr_info 1057 *noise_pwr_chain_ctl[HOST_MAX_ANTENNA]; 1058 struct target_if_chain_noise_pwr_info 1059 *noise_pwr_chain_ext[HOST_MAX_ANTENNA]; 1060 uint64_t tsf64; 1061 #if ATH_PERF_PWR_OFFLOAD 1062 struct target_if_spectral_param_state_info 1063 param_info[SPECTRAL_SCAN_MODE_MAX]; 1064 #endif 1065 enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX]; 1066 struct spectral_diag_stats diag_stats; 1067 bool is_160_format; 1068 bool is_lb_edge_extrabins_format; 1069 bool is_rb_edge_extrabins_format; 1070 bool is_sec80_rssi_war_required; 1071 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 1072 void *simctx; 1073 #endif 1074 enum spectral_gen spectral_gen; 1075 uint8_t hdr_sig_exp; 1076 uint8_t tag_sscan_summary_exp; 1077 uint8_t tag_sscan_fft_exp; 1078 uint8_t tlvhdr_size; 1079 struct spectral_nl_cb nl_cb; 1080 bool use_nl_bcast; 1081 int (*send_phy_data)(struct wlan_objmgr_pdev *pdev, 1082 enum spectral_msg_type smsg_type); 1083 struct spectral_fft_bin_len_adj_swar len_adj_swar; 1084 struct spectral_timestamp_war timestamp_war; 1085 enum spectral_160mhz_report_delivery_state 1086 state_160mhz_delivery[SPECTRAL_SCAN_MODE_MAX]; 1087 bool dbr_ring_debug; 1088 bool dbr_buff_debug; 1089 bool direct_dma_support; 1090 uint32_t prev_tstamp; 1091 struct spectral_report_params rparams; 1092 struct spectral_param_min_max param_min_max; 1093 }; 1094 1095 /** 1096 * struct target_if_psoc_spectral - Target if psoc Spectral object 1097 * @psoc_obj: psoc object 1098 * @wmi_ops: Spectral WMI operations 1099 */ 1100 struct target_if_psoc_spectral { 1101 struct wlan_objmgr_psoc *psoc_obj; 1102 struct spectral_wmi_ops wmi_ops; 1103 }; 1104 1105 /** 1106 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 1107 * data format 1108 * @rssi: RSSI (except for secondary 80 segment) 1109 * @rssi_sec80: RSSI for secondary 80 segment 1110 * @lower_rssi: RSSI of lower band 1111 * @upper_rssi: RSSI of upper band 1112 * @chain_ctl_rssi: RSSI for control channel, for all antennas 1113 * @chain_ext_rssi: RSSI for extension channel, for all antennas 1114 * @bwinfo: bandwidth info 1115 * @data_len: length of FFT data (except for secondary 80 segment) 1116 * @data_len_sec80: length of FFT data for secondary 80 segment 1117 * @tstamp: timestamp 1118 * @last_tstamp: last time stamp 1119 * @max_mag: maximum magnitude (except for secondary 80 segment) 1120 * @max_mag_sec80: maximum magnitude for secondary 80 segment 1121 * @max_index: index of max magnitude (except for secondary 80 segment) 1122 * @max_index_sec80: index of max magnitude for secondary 80 segment 1123 * @max_exp: max exp 1124 * @peak: peak frequency (obsolete) 1125 * @pwr_count: number of FFT bins (except for secondary 80 segment) 1126 * @pwr_count_5mhz: number of FFT bins in extra 5 MHz in 1127 * 165 MHz/restricted 80p80 mode 1128 * @pwr_count_sec80: number of FFT bins in secondary 80 segment 1129 * @nb_lower: This is deprecated 1130 * @nb_upper: This is deprecated 1131 * @max_upper_index: index of max mag in upper band 1132 * @max_lower_index: index of max mag in lower band 1133 * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment) 1134 * @bin_pwr_data_5mhz: Contains FFT magnitudes for the extra 5 MHz 1135 * in 165 MHz/restricted 80p80 mode 1136 * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment 1137 * @freq: Center frequency of primary 20MHz channel in MHz 1138 * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz 1139 * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz 1140 * @agile_freq1: Center frequency in MHz of the entire span(for 80+80 MHz 1141 * agile Scan it is primary 80 MHz span) across which 1142 * Agile Spectral is carried out. Applicable only for Agile 1143 * Spectral samples. 1144 * @agile_freq2: Center frequency in MHz of the secondary 80 MHz span 1145 * across which Agile Spectral is carried out. Applicable 1146 * only for Agile Spectral samples in 80+80 MHz mode. 1147 * @freq_loading: spectral control duty cycles 1148 * @noise_floor: current noise floor (except for secondary 80 segment) 1149 * @noise_floor_sec80: current noise floor for secondary 80 segment 1150 * @interf_list: List of interfernce sources 1151 * @classifier_params: classifier parameters 1152 * @sc: classifier parameters 1153 * @pri80ind: Indication from hardware that the sample was received on the 1154 * primary 80 MHz segment. If this is set when smode = 1155 * SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried out on 1156 * pri80 instead of the Agile frequency due to a channel switch - Software may 1157 * choose to ignore the sample in this case. 1158 * @pri80ind_sec80: Indication from hardware that the sample was received on the 1159 * primary 80 MHz segment instead of the secondary 80 MHz segment due to a 1160 * channel switch - Software may choose to ignore the sample if this is set. 1161 * Applicable only if smode = SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz 1162 * Spectral operation and if the chipset supports fragmented 160/80+80 MHz 1163 * operation. 1164 * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of 160MHz 1165 * it will be primary 80 segment's timestamp as both primary & secondary 1166 * segment's timestamps are expected to be almost equal 1167 * @timestamp_war_offset: Offset calculated based on reset_delay and 1168 * last_raw_stamp. It will be added to raw_timestamp to get tstamp. 1169 * @raw_timestamp: FFT timestamp reported by HW on primary segment. 1170 * @raw_timestamp_sec80: FFT timestamp reported by HW on secondary 80 segment. 1171 * @reset_delay: Time gap between the last spectral report before reset and the 1172 * end of reset. 1173 * @target_reset_count: Indicates the the number of times the target went 1174 * through reset routine after spectral was enabled. 1175 */ 1176 struct target_if_samp_msg_params { 1177 int8_t rssi; 1178 int8_t rssi_sec80; 1179 int8_t lower_rssi; 1180 int8_t upper_rssi; 1181 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 1182 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 1183 uint16_t bwinfo; 1184 uint16_t datalen; 1185 uint16_t datalen_sec80; 1186 uint32_t tstamp; 1187 uint32_t last_tstamp; 1188 uint16_t max_mag; 1189 uint16_t max_mag_sec80; 1190 uint16_t max_index; 1191 uint16_t max_index_sec80; 1192 uint8_t max_exp; 1193 int peak; 1194 int pwr_count; 1195 int pwr_count_5mhz; 1196 int pwr_count_sec80; 1197 int8_t nb_lower; 1198 int8_t nb_upper; 1199 uint16_t max_lower_index; 1200 uint16_t max_upper_index; 1201 uint8_t *bin_pwr_data; 1202 uint8_t *bin_pwr_data_5mhz; 1203 uint8_t *bin_pwr_data_sec80; 1204 uint16_t freq; 1205 uint16_t vhtop_ch_freq_seg1; 1206 uint16_t vhtop_ch_freq_seg2; 1207 uint16_t agile_freq1; 1208 uint16_t agile_freq2; 1209 uint16_t freq_loading; 1210 int16_t noise_floor; 1211 int16_t noise_floor_sec80; 1212 struct interf_src_rsp interf_list; 1213 struct spectral_classifier_params classifier_params; 1214 struct ath_softc *sc; 1215 uint8_t agc_total_gain; 1216 uint8_t agc_total_gain_sec80; 1217 uint8_t gainchange; 1218 uint8_t gainchange_sec80; 1219 enum spectral_scan_mode smode; 1220 uint8_t pri80ind; 1221 uint8_t pri80ind_sec80; 1222 uint32_t last_raw_timestamp; 1223 uint32_t timestamp_war_offset; 1224 uint32_t raw_timestamp; 1225 uint32_t raw_timestamp_sec80; 1226 uint32_t reset_delay; 1227 uint32_t target_reset_count; 1228 }; 1229 1230 #ifdef WLAN_CONV_SPECTRAL_ENABLE 1231 /** 1232 * target_if_spectral_dump_fft() - Dump Spectral FFT 1233 * @pfft: Pointer to Spectral Phyerr FFT 1234 * @fftlen: FFT length 1235 * 1236 * Return: Success or failure 1237 */ 1238 int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen); 1239 1240 /** 1241 * target_if_dbg_print_samp_param() - Print contents of SAMP struct 1242 * @p: Pointer to SAMP message 1243 * 1244 * Return: Void 1245 */ 1246 void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p); 1247 1248 /** 1249 * target_if_get_offset_swar_sec80() - Get offset for SWAR according to 1250 * the channel width 1251 * @channel_width: Channel width 1252 * 1253 * Return: Offset for SWAR 1254 */ 1255 uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width); 1256 1257 /** 1258 * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops 1259 * @tx_ops: Tx Ops 1260 * 1261 * Return: void 1262 */ 1263 void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); 1264 1265 /** 1266 * target_if_spectral_create_samp_msg() - Create the spectral samp message 1267 * @spectral : Pointer to spectral internal structure 1268 * @params : spectral samp message parameters 1269 * 1270 * API to create the spectral samp message 1271 * 1272 * Return: void 1273 */ 1274 void target_if_spectral_create_samp_msg( 1275 struct target_if_spectral *spectral, 1276 struct target_if_samp_msg_params *params); 1277 1278 /** 1279 * target_if_spectral_process_phyerr_gen3() - Process phyerror event for gen3 1280 * @pdev: Pointer to pdev object 1281 * @payload: Pointer to spectral report 1282 * 1283 * Process phyerror event for gen3 1284 * 1285 * Return: Success/Failure 1286 */ 1287 int target_if_spectral_process_report_gen3( 1288 struct wlan_objmgr_pdev *pdev, 1289 void *buf); 1290 1291 /** 1292 * target_if_process_phyerr_gen2() - Process PHY Error for gen2 1293 * @spectral: Pointer to Spectral object 1294 * @data: Pointer to phyerror event buffer 1295 * @datalen: Data length 1296 * @p_rfqual: RF quality info 1297 * @p_chaninfo: Channel info 1298 * @tsf64: 64 bit tsf timestamp 1299 * @acs_stats: ACS stats 1300 * 1301 * Process PHY Error for gen2 1302 * 1303 * Return: Success/Failure 1304 */ 1305 int target_if_process_phyerr_gen2( 1306 struct target_if_spectral *spectral, 1307 uint8_t *data, 1308 uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual, 1309 struct target_if_spectral_chan_info *p_chaninfo, 1310 uint64_t tsf64, 1311 struct target_if_spectral_acs_stats *acs_stats); 1312 1313 /** 1314 * target_if_spectral_send_intf_found_msg() - Indicate to application layer that 1315 * interference has been found 1316 * @pdev: Pointer to pdev 1317 * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found 1318 * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled 1319 * 1320 * Send message to application layer 1321 * indicating that interference has been found 1322 * 1323 * Return: None 1324 */ 1325 void target_if_spectral_send_intf_found_msg( 1326 struct wlan_objmgr_pdev *pdev, 1327 uint16_t cw_int, uint32_t dcs_enabled); 1328 1329 /** 1330 * target_if_stop_spectral_scan() - Stop spectral scan 1331 * @pdev: Pointer to pdev object 1332 * @smode: Spectral scan mode 1333 * @err: Pointer to error code 1334 * 1335 * API to stop the current on-going spectral scan 1336 * 1337 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 1338 */ 1339 QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, 1340 const enum spectral_scan_mode smode, 1341 enum spectral_cp_error_code *err); 1342 1343 /** 1344 * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral 1345 * operations 1346 * @spectral: Pointer to Spectral target_if internal private data 1347 * @smode: spectral scan mode 1348 * 1349 * Spectral operates on pdev. However, in order to retrieve some WLAN 1350 * properties, a vdev is required. To facilitate this, the function returns the 1351 * first vdev in our pdev. The caller should release the reference to the vdev 1352 * once it is done using it. 1353 * TODO: If the framework later provides an API to obtain the first active 1354 * vdev, then it would be preferable to use this API. 1355 * 1356 * Return: Pointer to vdev on success, NULL on failure 1357 */ 1358 struct wlan_objmgr_vdev *target_if_spectral_get_vdev( 1359 struct target_if_spectral *spectral, 1360 enum spectral_scan_mode smode); 1361 1362 /** 1363 * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2 1364 * @phdr: Pointer to Spectral Phyerr Header 1365 * 1366 * Dump Spectral header 1367 * 1368 * Return: Success/Failure 1369 */ 1370 int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr); 1371 1372 /** 1373 * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI 1374 * for Secondary 80 segment 1375 * @spectral: Pointer to spectral object 1376 * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment 1377 * 1378 * Get approximate combined RSSI for Secondary 80 segment 1379 * 1380 * Return: Combined RSSI for secondary 80Mhz segment 1381 */ 1382 int8_t target_if_get_combrssi_sec80_seg_gen2( 1383 struct target_if_spectral *spectral, 1384 struct spectral_search_fft_info_gen2 *p_sfft_sec80); 1385 1386 /** 1387 * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2 1388 * @ptlv: Pointer to Spectral Phyerr TLV 1389 * @is_160_format: Indicates 160 format 1390 * 1391 * Dump Spectral TLV for gen2 1392 * 1393 * Return: Success/Failure 1394 */ 1395 int target_if_spectral_dump_tlv_gen2( 1396 struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format); 1397 1398 /** 1399 * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral 1400 * related PHY Error for gen2 1401 * @data: Pointer to phyerror buffer 1402 * @datalen: Data length 1403 * @is_160_format: Indicates 160 format 1404 * 1405 * Dump Spectral related PHY Error for gen2 1406 * 1407 * Return: Success/Failure 1408 */ 1409 int target_if_spectral_dump_phyerr_data_gen2( 1410 uint8_t *data, 1411 uint32_t datalen, 1412 bool is_160_format); 1413 1414 /** 1415 * target_if_dbg_print_samp_msg() - Print contents of SAMP Message 1416 * @p: Pointer to SAMP message 1417 * 1418 * Print contents of SAMP Message 1419 * 1420 * Return: Void 1421 */ 1422 void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); 1423 1424 /** 1425 * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal 1426 * Spectral data 1427 * @pdev: Pointer to pdev 1428 * 1429 * Return: Handle to target_if internal Spectral data on success, NULL on 1430 * failure 1431 */ 1432 static inline 1433 struct target_if_spectral *get_target_if_spectral_handle_from_pdev( 1434 struct wlan_objmgr_pdev *pdev) 1435 { 1436 struct target_if_spectral *spectral; 1437 struct wlan_objmgr_psoc *psoc; 1438 struct wlan_lmac_if_rx_ops *rx_ops; 1439 1440 if (!pdev) { 1441 spectral_err("pdev is null"); 1442 return NULL; 1443 } 1444 1445 psoc = wlan_pdev_get_psoc(pdev); 1446 if (!psoc) { 1447 spectral_err("psoc is null"); 1448 return NULL; 1449 } 1450 1451 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1452 if (!rx_ops) { 1453 spectral_err("rx_ops is null"); 1454 return NULL; 1455 } 1456 1457 spectral = (struct target_if_spectral *) 1458 rx_ops->sptrl_rx_ops.sptrlro_get_pdev_target_handle(pdev); 1459 1460 return spectral; 1461 } 1462 1463 /** 1464 * get_target_if_spectral_handle_from_psoc() - Get handle to psoc target_if 1465 * internal Spectral data 1466 * @psoc: Pointer to psoc 1467 * 1468 * Return: Handle to target_if psoc internal Spectral data on success, NULL on 1469 * failure 1470 */ 1471 static inline 1472 struct target_if_psoc_spectral *get_target_if_spectral_handle_from_psoc( 1473 struct wlan_objmgr_psoc *psoc) 1474 { 1475 struct wlan_lmac_if_rx_ops *rx_ops; 1476 struct target_if_psoc_spectral *psoc_spectral; 1477 1478 if (!psoc) { 1479 spectral_err("psoc is null"); 1480 return NULL; 1481 } 1482 1483 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1484 if (!rx_ops) { 1485 spectral_err("rx_ops is null"); 1486 return NULL; 1487 } 1488 1489 psoc_spectral = (struct target_if_psoc_spectral *) 1490 rx_ops->sptrl_rx_ops.sptrlro_get_psoc_target_handle(psoc); 1491 1492 return psoc_spectral; 1493 } 1494 1495 /** 1496 * target_if_vdev_get_chan_freq() - Get the operating channel frequency of a 1497 * given vdev 1498 * @pdev: Pointer to vdev 1499 * 1500 * Get the operating channel frequency of a given vdev 1501 * 1502 * Return: Operating channel frequency of a vdev 1503 */ 1504 static inline 1505 int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) 1506 { 1507 struct wlan_objmgr_psoc *psoc = NULL; 1508 struct wlan_lmac_if_rx_ops *rx_ops; 1509 1510 psoc = wlan_vdev_get_psoc(vdev); 1511 if (!psoc) { 1512 spectral_err("psoc is NULL"); 1513 return -EINVAL; 1514 } 1515 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1516 if (!rx_ops) { 1517 spectral_err("rx_ops is null"); 1518 return -EINVAL; 1519 } 1520 1521 return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq( 1522 vdev); 1523 } 1524 1525 /** 1526 * target_if_vdev_get_chan_freq_seg2() - Get center frequency of secondary 80 of 1527 * given vdev 1528 * @vdev: Pointer to vdev 1529 * 1530 * Get the center frequency of secondary 80 of given vdev 1531 * 1532 * Return: center frequency of secondary 80 1533 */ 1534 static inline 1535 int16_t target_if_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev) 1536 { 1537 struct wlan_objmgr_psoc *psoc = NULL; 1538 struct wlan_lmac_if_rx_ops *rx_ops; 1539 1540 psoc = wlan_vdev_get_psoc(vdev); 1541 if (!psoc) { 1542 spectral_err("psoc is NULL"); 1543 return -EINVAL; 1544 } 1545 1546 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1547 if (!rx_ops) { 1548 spectral_err("rx_ops is null"); 1549 return -EINVAL; 1550 } 1551 1552 return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq_seg2(vdev); 1553 } 1554 1555 /** 1556 * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a 1557 * given vdev 1558 * @pdev: Pointer to vdev 1559 * 1560 * Get the operating channel bandwidth of a given vdev 1561 * 1562 * Return: channel bandwidth enumeration corresponding to the vdev 1563 */ 1564 static inline 1565 enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) 1566 { 1567 struct wlan_objmgr_psoc *psoc = NULL; 1568 enum phy_ch_width ch_width; 1569 struct wlan_lmac_if_rx_ops *rx_ops; 1570 1571 psoc = wlan_vdev_get_psoc(vdev); 1572 if (!psoc) { 1573 spectral_err("psoc is NULL"); 1574 return CH_WIDTH_INVALID; 1575 } 1576 1577 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1578 if (!rx_ops) { 1579 spectral_err("rx_ops is null"); 1580 return CH_WIDTH_INVALID; 1581 } 1582 1583 ch_width = rx_ops->sptrl_rx_ops.sptrlro_vdev_get_ch_width(vdev); 1584 1585 if (ch_width == CH_WIDTH_160MHZ) { 1586 int16_t cfreq2; 1587 1588 cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev); 1589 if (cfreq2 < 0) { 1590 spectral_err("Invalid value for cfreq2 %d", cfreq2); 1591 return CH_WIDTH_INVALID; 1592 } 1593 1594 /* Use non zero cfreq2 to identify 80p80 */ 1595 if (cfreq2) 1596 ch_width = CH_WIDTH_80P80MHZ; 1597 } 1598 1599 return ch_width; 1600 } 1601 1602 /** 1603 * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary 1604 * 20 MHz channel for a given vdev 1605 * @pdev: Pointer to vdev 1606 * 1607 * Get the frequency of secondary 20Mhz channel for a given vdev 1608 * 1609 * Return: Frequency of secondary 20Mhz channel for a given vdev 1610 */ 1611 static inline 1612 int target_if_vdev_get_sec20chan_freq_mhz( 1613 struct wlan_objmgr_vdev *vdev, 1614 uint16_t *sec20chan_freq) 1615 { 1616 struct wlan_objmgr_psoc *psoc = NULL; 1617 struct wlan_lmac_if_rx_ops *rx_ops; 1618 1619 psoc = wlan_vdev_get_psoc(vdev); 1620 if (!psoc) { 1621 spectral_err("psoc is NULL"); 1622 return -EINVAL; 1623 } 1624 1625 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1626 if (!rx_ops) { 1627 spectral_err("rx_ops is null"); 1628 return -EINVAL; 1629 } 1630 1631 return rx_ops->sptrl_rx_ops. 1632 sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); 1633 } 1634 1635 /** 1636 * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask 1637 * @pdev: Pointer to pdev 1638 * @spectral_rx_chainmask: Spectral Rx chainmask 1639 * 1640 * Return: None 1641 */ 1642 static inline 1643 void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, 1644 uint8_t spectral_rx_chainmask) 1645 { 1646 struct wlan_objmgr_psoc *psoc = NULL; 1647 struct target_if_spectral *spectral = NULL; 1648 enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL; 1649 struct wlan_lmac_if_rx_ops *rx_ops; 1650 1651 psoc = wlan_pdev_get_psoc(pdev); 1652 if (!psoc) { 1653 spectral_err("psoc is NULL"); 1654 return; 1655 } 1656 1657 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1658 if (!rx_ops) { 1659 spectral_err("rx_ops is null"); 1660 return; 1661 } 1662 1663 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 1664 spectral_err("Invalid Spectral mode %u", smode); 1665 return; 1666 } 1667 1668 if (rx_ops->sptrl_rx_ops. 1669 sptrlro_spectral_is_feature_disabled(psoc)) { 1670 spectral_info("Spectral is disabled"); 1671 return; 1672 } 1673 1674 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1675 if (!spectral) { 1676 spectral_err("Spectral target if object is null"); 1677 return; 1678 } 1679 1680 /* set chainmask for all the modes */ 1681 for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) 1682 spectral->params[smode].ss_chn_mask = spectral_rx_chainmask; 1683 } 1684 1685 /** 1686 * target_if_spectral_process_phyerr() - Process Spectral PHY error 1687 * @pdev: Pointer to pdev 1688 * @data: PHY error data received from FW 1689 * @datalen: Length of data 1690 * @p_rfqual: Pointer to RF Quality information 1691 * @p_chaninfo: Pointer to channel information 1692 * @tsf: TSF time instance at which the Spectral sample was received 1693 * @acs_stats: ACS stats 1694 * 1695 * Process Spectral PHY error by extracting necessary information from the data 1696 * sent by FW, and send the extracted information to application layer. 1697 * 1698 * Return: None 1699 */ 1700 static inline 1701 void target_if_spectral_process_phyerr( 1702 struct wlan_objmgr_pdev *pdev, 1703 uint8_t *data, uint32_t datalen, 1704 struct target_if_spectral_rfqual_info *p_rfqual, 1705 struct target_if_spectral_chan_info *p_chaninfo, 1706 uint64_t tsf64, 1707 struct target_if_spectral_acs_stats *acs_stats) 1708 { 1709 struct target_if_spectral *spectral = NULL; 1710 struct target_if_spectral_ops *p_sops = NULL; 1711 1712 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1713 if (!spectral) { 1714 spectral_err("Spectral target if object is null"); 1715 return; 1716 } 1717 1718 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1719 p_sops->spectral_process_phyerr(spectral, data, datalen, 1720 p_rfqual, p_chaninfo, 1721 tsf64, acs_stats); 1722 } 1723 1724 static QDF_STATUS 1725 target_if_get_spectral_msg_type(enum spectral_scan_mode smode, 1726 enum spectral_msg_type *msg_type) { 1727 1728 switch (smode) { 1729 case SPECTRAL_SCAN_MODE_NORMAL: 1730 *msg_type = SPECTRAL_MSG_NORMAL_MODE; 1731 break; 1732 1733 case SPECTRAL_SCAN_MODE_AGILE: 1734 *msg_type = SPECTRAL_MSG_AGILE_MODE; 1735 break; 1736 1737 default: 1738 spectral_err("Invalid spectral mode"); 1739 return QDF_STATUS_E_FAILURE; 1740 } 1741 1742 return QDF_STATUS_SUCCESS; 1743 } 1744 1745 static inline bool 1746 is_ch_width_160_or_80p80(enum phy_ch_width ch_width) 1747 { 1748 return (ch_width == CH_WIDTH_160MHZ || ch_width == CH_WIDTH_80P80MHZ); 1749 } 1750 1751 /** 1752 * init_160mhz_delivery_state_machine() - Initialize 160MHz Spectral 1753 * state machine 1754 * @spectral: Pointer to Spectral 1755 * 1756 * Initialize 160MHz Spectral state machine 1757 * 1758 * Return: void 1759 */ 1760 static inline void 1761 init_160mhz_delivery_state_machine(struct target_if_spectral *spectral) 1762 { 1763 uint8_t smode; 1764 1765 smode = 0; 1766 for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) 1767 spectral->state_160mhz_delivery[smode] = 1768 SPECTRAL_REPORT_WAIT_PRIMARY80; 1769 } 1770 1771 /** 1772 * reset_160mhz_delivery_state_machine() - Reset 160MHz Spectral state machine 1773 * @spectral: Pointer to Spectral 1774 * 1775 * Reset 160MHz Spectral state machine 1776 * 1777 * Return: void 1778 */ 1779 static inline void 1780 reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, 1781 enum spectral_scan_mode smode) 1782 { 1783 enum spectral_msg_type smsg_type; 1784 QDF_STATUS ret; 1785 1786 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 1787 spectral_err_rl("Invalid Spectral mode %d", smode); 1788 return; 1789 } 1790 1791 if (is_ch_width_160_or_80p80(spectral->ch_width[smode])) { 1792 spectral->state_160mhz_delivery[smode] = 1793 SPECTRAL_REPORT_WAIT_PRIMARY80; 1794 1795 ret = target_if_get_spectral_msg_type(smode, &smsg_type); 1796 if (QDF_IS_STATUS_ERROR(ret)) { 1797 spectral_err("Failed to get spectral message type"); 1798 return; 1799 } 1800 1801 spectral->nl_cb.free_sbuff(spectral->pdev_obj, 1802 smsg_type); 1803 } 1804 } 1805 1806 /** 1807 * is_secondaryseg_expected() - Is waiting for secondary 80 report 1808 * @spectral: Pointer to Spectral 1809 * @smode: Spectral scan mode 1810 * 1811 * Return true if secondary 80 report expected and mode is 160 MHz 1812 * 1813 * Return: true or false 1814 */ 1815 static inline 1816 bool is_secondaryseg_expected(struct target_if_spectral *spectral, 1817 enum spectral_scan_mode smode) 1818 { 1819 return 1820 (is_ch_width_160_or_80p80(spectral->ch_width[smode]) && 1821 spectral->rparams.fragmentation_160[smode] && 1822 (spectral->state_160mhz_delivery[smode] == 1823 SPECTRAL_REPORT_WAIT_SECONDARY80)); 1824 } 1825 1826 /** 1827 * is_primaryseg_expected() - Is waiting for primary 80 report 1828 * @spectral: Pointer to Spectral 1829 * @smode: Spectral scan mode 1830 * 1831 * Return true if mode is 160 Mhz and primary 80 report expected or 1832 * mode is not 160 Mhz 1833 * 1834 * Return: true or false 1835 */ 1836 static inline 1837 bool is_primaryseg_expected(struct target_if_spectral *spectral, 1838 enum spectral_scan_mode smode) 1839 { 1840 return 1841 (!is_ch_width_160_or_80p80(spectral->ch_width[smode]) || 1842 !spectral->rparams.fragmentation_160[smode] || 1843 (spectral->state_160mhz_delivery[smode] == 1844 SPECTRAL_REPORT_WAIT_PRIMARY80)); 1845 } 1846 1847 /** 1848 * is_primaryseg_rx_inprog() - Is primary 80 report processing is in progress 1849 * @spectral: Pointer to Spectral 1850 * @smode: Spectral scan mode 1851 * 1852 * Is primary 80 report processing is in progress 1853 * 1854 * Return: true or false 1855 */ 1856 static inline 1857 bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral, 1858 enum spectral_scan_mode smode) 1859 { 1860 return 1861 (!is_ch_width_160_or_80p80(spectral->ch_width[smode]) || 1862 spectral->spectral_gen == SPECTRAL_GEN2 || 1863 (spectral->spectral_gen == SPECTRAL_GEN3 && 1864 (!spectral->rparams.fragmentation_160[smode] || 1865 spectral->state_160mhz_delivery[smode] == 1866 SPECTRAL_REPORT_RX_PRIMARY80))); 1867 } 1868 1869 /** 1870 * is_secondaryseg_rx_inprog() - Is secondary80 report processing is in progress 1871 * @spectral: Pointer to Spectral 1872 * @smode: Spectral scan mode 1873 * 1874 * Is secondary 80 report processing is in progress 1875 * 1876 * Return: true or false 1877 */ 1878 static inline 1879 bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral, 1880 enum spectral_scan_mode smode) 1881 { 1882 return 1883 (is_ch_width_160_or_80p80(spectral->ch_width[smode]) && 1884 (spectral->spectral_gen == SPECTRAL_GEN2 || 1885 ((spectral->spectral_gen == SPECTRAL_GEN3) && 1886 (!spectral->rparams.fragmentation_160[smode] || 1887 spectral->state_160mhz_delivery[smode] == 1888 SPECTRAL_REPORT_RX_SECONDARY80)))); 1889 } 1890 1891 /** 1892 * target_if_160mhz_delivery_state_change() - State transition for 160Mhz 1893 * Spectral 1894 * @spectral: Pointer to spectral object 1895 * @smode: Spectral scan mode 1896 * @detector_id: Detector id 1897 * 1898 * Move the states of state machine for 160MHz spectral scan report receive 1899 * 1900 * Return: QDF_STATUS 1901 */ 1902 QDF_STATUS 1903 target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, 1904 enum spectral_scan_mode smode, 1905 uint8_t detector_id); 1906 1907 /** 1908 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 1909 * @arg: Pointer to handle for Spectral target_if internal private data 1910 * @smode: Spectral scan mode 1911 * 1912 * Function to check whether Spectral is enabled 1913 * 1914 * Return: True if Spectral is enabled, false if Spectral is not enabled 1915 */ 1916 uint32_t target_if_sops_is_spectral_enabled(void *arg, 1917 enum spectral_scan_mode smode); 1918 1919 /** 1920 * target_if_sops_is_spectral_active() - Get whether Spectral is active 1921 * @arg: Pointer to handle for Spectral target_if internal private data 1922 * @smode: Spectral scan mode 1923 * 1924 * Function to check whether Spectral is active 1925 * 1926 * Return: True if Spectral is active, false if Spectral is not active 1927 */ 1928 uint32_t target_if_sops_is_spectral_active(void *arg, 1929 enum spectral_scan_mode smode); 1930 1931 /** 1932 * target_if_sops_start_spectral_scan() - Start Spectral scan 1933 * @arg: Pointer to handle for Spectral target_if internal private data 1934 * @smode: Spectral scan mode 1935 * @err: Pointer to error code 1936 * 1937 * Function to start spectral scan 1938 * 1939 * Return: 0 on success else failure 1940 */ 1941 uint32_t target_if_sops_start_spectral_scan(void *arg, 1942 enum spectral_scan_mode smode, 1943 enum spectral_cp_error_code *err); 1944 1945 /** 1946 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 1947 * @arg: Pointer to handle for Spectral target_if internal private data 1948 * @smode: Spectral scan mode 1949 * 1950 * Function to stop spectral scan 1951 * 1952 * Return: 0 in case of success, -1 on failure 1953 */ 1954 uint32_t target_if_sops_stop_spectral_scan(void *arg, 1955 enum spectral_scan_mode smode); 1956 1957 /** 1958 * target_if_spectral_get_extension_channel() - Get the current Extension 1959 * channel (in MHz) 1960 * @arg: Pointer to handle for Spectral target_if internal private data 1961 * @smode: Spectral scan mode 1962 * 1963 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 1964 * extension channel is not present. 1965 */ 1966 uint32_t 1967 target_if_spectral_get_extension_channel(void *arg, 1968 enum spectral_scan_mode smode); 1969 1970 /** 1971 * target_if_spectral_get_current_channel() - Get the current channel (in MHz) 1972 * @arg: Pointer to handle for Spectral target_if internal private data 1973 * @smode: Spectral scan mode 1974 * 1975 * Return: Current channel (in MHz) on success, 0 on failure 1976 */ 1977 uint32_t 1978 target_if_spectral_get_current_channel(void *arg, 1979 enum spectral_scan_mode smode); 1980 1981 1982 /** 1983 * target_if_spectral_reset_hw() - Reset the hardware 1984 * @arg: Pointer to handle for Spectral target_if internal private data 1985 * 1986 * This is only a placeholder since it is not currently required in the offload 1987 * case. 1988 * 1989 * Return: 0 1990 */ 1991 uint32_t target_if_spectral_reset_hw(void *arg); 1992 1993 /** 1994 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 1995 * Noisefloor history buffer 1996 * @arg: Pointer to handle for Spectral target_if internal private data 1997 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 1998 * 1999 * This is only a placeholder since it is not currently required in the offload 2000 * case. 2001 * 2002 * Return: 0 2003 */ 2004 uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf); 2005 2006 /** 2007 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 2008 * noisefloor 2009 * @arg: Pointer to handle for Spectral target_if internal private data 2010 * 2011 * This is only a placeholder since it is not currently required in the offload 2012 * case. 2013 * 2014 * Return: 0 2015 */ 2016 int8_t target_if_spectral_get_ext_noisefloor(void *arg); 2017 2018 /** 2019 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 2020 * @arg: Pointer to handle for Spectral target_if internal private data 2021 * 2022 * This is only a placeholder since it is not currently required in the offload 2023 * case. 2024 * 2025 * Return: 0 2026 */ 2027 int8_t target_if_spectral_get_ctl_noisefloor(void *arg); 2028 2029 /** 2030 * target_if_spectral_get_capability() - Get whether a given Spectral hardware 2031 * capability is available 2032 * @arg: Pointer to handle for Spectral target_if internal private data 2033 * @type: Spectral hardware capability type 2034 * 2035 * Return: True if the capability is available, false if the capability is not 2036 * available 2037 */ 2038 uint32_t target_if_spectral_get_capability( 2039 void *arg, enum spectral_capability_type type); 2040 2041 /** 2042 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 2043 * @arg: Pointer to handle for Spectral target_if internal private data 2044 * @rxfilter: Rx filter to be used 2045 * 2046 * Note: This is only a placeholder function. It is not currently required since 2047 * FW should be taking care of setting the required filters. 2048 * 2049 * Return: 0 2050 */ 2051 uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter); 2052 2053 /** 2054 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 2055 * parameters 2056 * @arg: Pointer to handle for Spectral target_if internal private data 2057 * @params: Spectral parameters 2058 * @smode: Spectral scan mode 2059 * 2060 * Return: 0 in case of success, -1 on failure 2061 */ 2062 uint32_t target_if_spectral_sops_configure_params( 2063 void *arg, struct spectral_config *params, 2064 enum spectral_scan_mode smode); 2065 2066 /** 2067 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 2068 * @arg: Pointer to handle for Spectral target_if internal private data 2069 * 2070 * Note: This is only a placeholder function. It is not currently required since 2071 * FW should be taking care of setting the required filters. 2072 * 2073 * Return: 0 2074 */ 2075 uint32_t target_if_spectral_get_rxfilter(void *arg); 2076 2077 /** 2078 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 2079 * functionality for the given pdev 2080 * @pdev: Pointer to pdev object 2081 * 2082 * Return: None 2083 */ 2084 void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev); 2085 2086 /** 2087 * target_if_set_spectral_config() - Set spectral config 2088 * @pdev: Pointer to pdev object 2089 * @param: Spectral parameter id and value 2090 * @smode: Spectral scan mode 2091 * @err: Pointer to Spectral error code 2092 * 2093 * API to set spectral configurations 2094 * 2095 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2096 */ 2097 QDF_STATUS target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 2098 const struct spectral_cp_param *param, 2099 const enum spectral_scan_mode smode, 2100 enum spectral_cp_error_code *err); 2101 2102 /** 2103 * target_if_pdev_spectral_init() - Initialize target_if Spectral 2104 * functionality for the given pdev 2105 * @pdev: Pointer to pdev object 2106 * 2107 * Return: On success, pointer to Spectral target_if internal private data, on 2108 * failure, NULL 2109 */ 2110 void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev); 2111 2112 /** 2113 * target_if_spectral_sops_get_params() - Get user configured Spectral 2114 * parameters 2115 * @arg: Pointer to handle for Spectral target_if internal private data 2116 * @params: Pointer to buffer into which Spectral parameters should be copied 2117 * @smode: Spectral scan mode 2118 * 2119 * Return: 0 in case of success, -1 on failure 2120 */ 2121 uint32_t target_if_spectral_sops_get_params( 2122 void *arg, struct spectral_config *params, 2123 enum spectral_scan_mode smode); 2124 2125 /** 2126 * target_if_init_spectral_capability() - Initialize Spectral capability 2127 * 2128 * @spectral: Pointer to Spectral target_if internal private data 2129 * @target_type: target type 2130 * 2131 * This is a workaround. 2132 * 2133 * Return: QDF_STATUS 2134 */ 2135 QDF_STATUS 2136 target_if_init_spectral_capability(struct target_if_spectral *spectral, 2137 uint32_t target_type); 2138 2139 /** 2140 * target_if_start_spectral_scan() - Start spectral scan 2141 * @pdev: Pointer to pdev object 2142 * @vdev_id: VDEV id 2143 * @smode: Spectral scan mode 2144 * @err: Spectral error code 2145 * 2146 * API to start spectral scan 2147 * 2148 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2149 */ 2150 QDF_STATUS target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, 2151 uint8_t vdev_id, 2152 enum spectral_scan_mode smode, 2153 enum spectral_cp_error_code *err); 2154 2155 /** 2156 * target_if_get_spectral_config() - Get spectral configuration 2157 * @pdev: Pointer to pdev object 2158 * @param: Pointer to spectral_config structure in which the configuration 2159 * should be returned 2160 * @smode: Spectral scan mode 2161 * 2162 * API to get the current spectral configuration 2163 * 2164 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2165 */ 2166 QDF_STATUS target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 2167 struct spectral_config *param, 2168 enum spectral_scan_mode smode); 2169 2170 /** 2171 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 2172 * parameters 2173 * @spectral: Pointer to Spectral target_if internal private data 2174 * @spectral_params: Pointer to Spectral parameters 2175 * @smode: Spectral scan mode 2176 * @err: Spectral error code 2177 * 2178 * Enable use of desired Spectral parameters by configuring them into HW, and 2179 * starting Spectral scan 2180 * 2181 * Return: 0 on success, 1 on failure 2182 */ 2183 int target_if_spectral_scan_enable_params( 2184 struct target_if_spectral *spectral, 2185 struct spectral_config *spectral_params, 2186 enum spectral_scan_mode smode, 2187 enum spectral_cp_error_code *err); 2188 2189 /** 2190 * target_if_is_spectral_active() - Get whether Spectral is active 2191 * @pdev: Pointer to pdev object 2192 * @smode: Spectral scan mode 2193 * 2194 * Return: True if Spectral is active, false if Spectral is not active 2195 */ 2196 bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev, 2197 enum spectral_scan_mode smode); 2198 2199 /** 2200 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 2201 * @pdev: Pointer to pdev object 2202 * @smode: Spectral scan mode 2203 * 2204 * Return: True if Spectral is enabled, false if Spectral is not enabled 2205 */ 2206 bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev, 2207 enum spectral_scan_mode smode); 2208 2209 /** 2210 * target_if_set_debug_level() - Set debug level for Spectral 2211 * @pdev: Pointer to pdev object 2212 * @debug_level: Debug level 2213 * 2214 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2215 * 2216 */ 2217 QDF_STATUS target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, 2218 uint32_t debug_level); 2219 2220 /** 2221 * target_if_get_debug_level() - Get debug level for Spectral 2222 * @pdev: Pointer to pdev object 2223 * 2224 * Return: Current debug level 2225 */ 2226 uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev); 2227 2228 2229 /** 2230 * target_if_get_spectral_capinfo() - Get Spectral capability information 2231 * @pdev: Pointer to pdev object 2232 * @scaps: Buffer into which data should be copied 2233 * 2234 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2235 */ 2236 QDF_STATUS target_if_get_spectral_capinfo(struct wlan_objmgr_pdev *pdev, 2237 struct spectral_caps *scaps); 2238 2239 2240 /** 2241 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 2242 * @pdev: Pointer to pdev object 2243 * @stats: Buffer into which data should be copied 2244 * 2245 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2246 */ 2247 QDF_STATUS target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, 2248 struct spectral_diag_stats *stats); 2249 2250 QDF_STATUS 2251 target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, 2252 enum spectral_scan_mode smode, 2253 uint8_t detector_id); 2254 #ifdef DIRECT_BUF_RX_ENABLE 2255 /** 2256 * target_if_consume_sfft_report_gen3() - Process fft report for gen3 2257 * @spectral: Pointer to spectral object 2258 * @report: Pointer to spectral report 2259 * 2260 * Process fft report for gen3 2261 * 2262 * Return: Success/Failure 2263 */ 2264 int 2265 target_if_consume_spectral_report_gen3( 2266 struct target_if_spectral *spectral, 2267 struct spectral_report *report); 2268 #endif 2269 2270 /** 2271 * target_if_spectral_fw_hang() - Crash the FW from Spectral module 2272 * @spectral: Pointer to Spectral LMAC object 2273 * 2274 * Return: QDF_STATUS of operation 2275 */ 2276 QDF_STATUS target_if_spectral_fw_hang(struct target_if_spectral *spectral); 2277 2278 #ifdef WIN32 2279 #pragma pack(pop, target_if_spectral) 2280 #endif 2281 #ifdef __ATTRIB_PACK 2282 #undef __ATTRIB_PACK 2283 #endif 2284 2285 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 2286 #endif /* _TARGET_IF_SPECTRAL_H_ */ 2287