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 int8_t (*get_ctl_noisefloor)(void *arg); 674 int8_t (*get_ext_noisefloor)(void *arg); 675 uint32_t (*configure_spectral)( 676 void *arg, 677 struct spectral_config *params, 678 enum spectral_scan_mode smode); 679 uint32_t (*get_spectral_config)( 680 void *arg, 681 struct spectral_config *params, 682 enum spectral_scan_mode smode); 683 uint32_t (*get_ent_spectral_mask)(void *arg); 684 uint32_t (*get_mac_address)(void *arg, char *addr); 685 uint32_t (*get_current_channel)(void *arg); 686 uint32_t (*reset_hw)(void *arg); 687 uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf); 688 int (*spectral_process_phyerr)(struct target_if_spectral *spectral, 689 uint8_t *data, uint32_t datalen, 690 struct target_if_spectral_rfqual_info *p_rfqual, 691 struct target_if_spectral_chan_info *p_chaninfo, 692 uint64_t tsf64, 693 struct target_if_spectral_acs_stats *acs_stats); 694 int (*process_spectral_report)(struct wlan_objmgr_pdev *pdev, 695 void *payload); 696 }; 697 698 /** 699 * struct target_if_spectral_stats - spectral stats info 700 * @num_spectral_detects: Total num. of spectral detects 701 * @total_phy_errors: Total number of phyerrors 702 * @owl_phy_errors: Indicated phyerrors in old gen1 chipsets 703 * @pri_phy_errors: Phyerrors in primary channel 704 * @ext_phy_errors: Phyerrors in secondary channel 705 * @dc_phy_errors: Phyerrors due to dc 706 * @early_ext_phy_errors: Early secondary channel phyerrors 707 * @bwinfo_errors: Bandwidth info errors 708 * @datalen_discards: Invalid data length errors, seen in gen1 chipsets 709 * @rssi_discards bw: Indicates reports dropped due to RSSI threshold 710 * @last_reset_tstamp: Last reset time stamp 711 */ 712 struct target_if_spectral_stats { 713 uint32_t num_spectral_detects; 714 uint32_t total_phy_errors; 715 uint32_t owl_phy_errors; 716 uint32_t pri_phy_errors; 717 uint32_t ext_phy_errors; 718 uint32_t dc_phy_errors; 719 uint32_t early_ext_phy_errors; 720 uint32_t bwinfo_errors; 721 uint32_t datalen_discards; 722 uint32_t rssi_discards; 723 uint64_t last_reset_tstamp; 724 }; 725 726 /** 727 * struct target_if_spectral_event - spectral event structure 728 * @se_ts: Original 15 bit recv timestamp 729 * @se_full_ts: 64-bit full timestamp from interrupt time 730 * @se_rssi: Rssi of spectral event 731 * @se_bwinfo: Rssi of spectral event 732 * @se_dur: Duration of spectral pulse 733 * @se_chanindex: Channel of event 734 * @se_list: List of spectral events 735 */ 736 struct target_if_spectral_event { 737 uint32_t se_ts; 738 uint64_t se_full_ts; 739 uint8_t se_rssi; 740 uint8_t se_bwinfo; 741 uint8_t se_dur; 742 uint8_t se_chanindex; 743 744 STAILQ_ENTRY(spectral_event) se_list; 745 }; 746 747 /** 748 * struct target_if_chain_noise_pwr_info - Noise power info for each channel 749 * @rptcount: Count of reports in pwr array 750 * @un_cal_nf: Uncalibrated noise floor 751 * @factory_cal_nf: Noise floor as calibrated at the factory for module 752 * @median_pwr: Median power (median of pwr array) 753 * @pwr: Power reports 754 */ 755 struct target_if_chain_noise_pwr_info { 756 int rptcount; 757 pwr_dbm un_cal_nf; 758 pwr_dbm factory_cal_nf; 759 pwr_dbm median_pwr; 760 pwr_dbm pwr[]; 761 } __ATTRIB_PACK; 762 763 /** 764 * struct target_if_spectral_chan_stats - Channel information 765 * @cycle_count: Cycle count 766 * @channel_load: Channel load 767 * @per: Period 768 * @noisefloor: Noise floor 769 * @comp_usablity: Computed usability 770 * @maxregpower: Maximum allowed regulatary power 771 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 772 * @maxregpower_sec80: Max regulatory power in secondary 80 Mhz 773 */ 774 struct target_if_spectral_chan_stats { 775 int cycle_count; 776 int channel_load; 777 int per; 778 int noisefloor; 779 uint16_t comp_usablity; 780 int8_t maxregpower; 781 uint16_t comp_usablity_sec80; 782 int8_t maxregpower_sec80; 783 }; 784 785 #if ATH_PERF_PWR_OFFLOAD 786 787 /** 788 * struct target_if_spectral_cache - Cache used to minimize WMI operations 789 * in offload architecture 790 * @osc_spectral_enabled: Whether Spectral is enabled 791 * @osc_spectral_active: Whether spectral is active 792 * XXX: Ideally, we should NOT cache this 793 * since the hardware can self clear the bit, 794 * the firmware can possibly stop spectral due to 795 * intermittent off-channel activity, etc 796 * A WMI read command should be introduced to handle 797 * this This will be discussed. 798 * @osc_params: Spectral parameters 799 * @osc_is_valid: Whether the cache is valid 800 */ 801 struct target_if_spectral_cache { 802 uint8_t osc_spectral_enabled; 803 uint8_t osc_spectral_active; 804 struct spectral_config osc_params; 805 uint8_t osc_is_valid; 806 }; 807 808 /** 809 * struct target_if_spectral_param_state_info - Structure used to represent and 810 * manage spectral information 811 * (parameters and states) 812 * @osps_lock: Lock to synchronize accesses to information 813 * @osps_cache: Cacheable' information 814 */ 815 struct target_if_spectral_param_state_info { 816 qdf_spinlock_t osps_lock; 817 struct target_if_spectral_cache osps_cache; 818 /* XXX - Non-cacheable information goes here, in the future */ 819 }; 820 #endif /* ATH_PERF_PWR_OFFLOAD */ 821 822 struct vdev_spectral_configure_params; 823 struct vdev_spectral_enable_params; 824 825 /** 826 * struct spectral_wmi_ops - structure used holding the operations 827 * related to Spectral WMI 828 * @wmi_spectral_configure_cmd_send: Configure Spectral parameters 829 * @wmi_spectral_enable_cmd_send: Enable/Disable Spectral 830 * @wmi_spectral_crash_inject: Inject FW crash 831 * @wmi_extract_pdev_sscan_fw_cmd_fixed_param: Extract Fixed params from 832 * start scan response event 833 * @wmi_extract_pdev_sscan_fft_bin_index: Extract TLV which describes FFT 834 * bin indices from start scan response event 835 * @wmi_unified_register_event_handler: Register WMI event handler 836 * @wmi_unified_unregister_event_handler: Unregister WMI event handler 837 */ 838 struct spectral_wmi_ops { 839 QDF_STATUS (*wmi_spectral_configure_cmd_send)( 840 wmi_unified_t wmi_hdl, 841 struct vdev_spectral_configure_params *param); 842 QDF_STATUS (*wmi_spectral_enable_cmd_send)( 843 wmi_unified_t wmi_hdl, 844 struct vdev_spectral_enable_params *param); 845 QDF_STATUS (*wmi_spectral_crash_inject)( 846 wmi_unified_t wmi_handle, struct crash_inject *param); 847 QDF_STATUS (*wmi_extract_pdev_sscan_fw_cmd_fixed_param)( 848 wmi_unified_t wmi_handle, uint8_t *evt_buf, 849 struct spectral_startscan_resp_params *param); 850 QDF_STATUS (*wmi_extract_pdev_sscan_fft_bin_index)( 851 wmi_unified_t wmi_handle, uint8_t *evt_buf, 852 struct spectral_fft_bin_markers_160_165mhz *param); 853 int (*wmi_unified_register_event_handler)( 854 wmi_unified_t wmi_handle, 855 wmi_conv_event_id event_id, 856 wmi_unified_event_handler handler_func, 857 uint8_t rx_ctx); 858 int (*wmi_unified_unregister_event_handler)(wmi_unified_t wmi_handle, 859 wmi_conv_event_id event_id); 860 }; 861 862 /** 863 * struct spectral_tgt_ops - structure used holding the operations 864 * related to target operations 865 * @tgt_get_psoc_from_scn_hdl: Function to get psoc from scn 866 */ 867 struct spectral_tgt_ops { 868 struct wlan_objmgr_psoc *(*tgt_get_psoc_from_scn_hdl)(void *scn_handle); 869 }; 870 871 /** 872 * struct spectral_param_properties - structure holding Spectral 873 * parameter properties 874 * @supported: Parameter is supported or not 875 * @common_all_modes: Parameter should be common for all modes or not 876 */ 877 struct spectral_param_properties { 878 bool supported; 879 bool common_all_modes; 880 }; 881 882 /** 883 * struct target_if_spectral - main spectral structure 884 * @pdev: Pointer to pdev 885 * @spectral_ops: Target if internal Spectral low level operations table 886 * @capability: Spectral capabilities structure 887 * @properties: Spectral parameter properties per mode 888 * @spectral_lock: Lock used for internal Spectral operations 889 * @spectral_curchan_radindex: Current channel spectral index 890 * @spectral_extchan_radindex: Extension channel spectral index 891 * @spectraldomain: Current Spectral domain 892 * @spectral_proc_phyerr: Flags to process for PHY errors 893 * @spectral_defaultparams: Default PHY params per Spectral stat 894 * @spectral_stats: Spectral related stats 895 * @events: Events structure 896 * @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel? 897 * @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI? 898 * @sc_spectral_20_40_mode: Is AP in 20-40 mode? 899 * @sc_spectral_noise_pwr_cal: Noise power cal required? 900 * @sc_spectral_non_edma: Is the spectral capable device Non-EDMA? 901 * @upper_is_control: Upper segment is primary 902 * @upper_is_extension: Upper segment is secondary 903 * @lower_is_control: Lower segment is primary 904 * @lower_is_extension: Lower segment is secondary 905 * @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral 906 * mute test 907 * @spectral_numbins: Number of bins 908 * @spectral_fft_len: FFT length 909 * @spectral_data_len: Total phyerror report length 910 * @lb_edge_extrabins: Number of extra bins on left band edge 911 * @rb_edge_extrabins: Number of extra bins on right band edge 912 * @spectral_max_index_offset: Max FFT index offset (20 MHz mode) 913 * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode) 914 * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode) 915 * @spectral_dc_index: At which index DC is present 916 * @send_single_packet: Deprecated 917 * @spectral_sent_msg: Indicates whether we send report to upper layers 918 * @params: Spectral parameters 919 * @last_capture_time: Indicates timestamp of previouse report 920 * @num_spectral_data: Number of Spectral samples received in current session 921 * @total_spectral_data: Total number of Spectral samples received 922 * @max_rssi: Maximum RSSI 923 * @detects_control_channel: NA 924 * @detects_extension_channel: NA 925 * @detects_below_dc: NA 926 * @detects_above_dc: NA 927 * @sc_scanning: Indicates active wifi scan 928 * @sc_spectral_scan: Indicates active specral scan 929 * @sc_spectral_full_scan: Deprecated 930 * @scan_start_tstamp: Deprecated 931 * @last_tstamp: Deprecated 932 * @first_tstamp: Deprecated 933 * @spectral_samp_count: Deprecated 934 * @sc_spectral_samp_count: Deprecated 935 * @noise_pwr_reports_reqd: Number of noise power reports required 936 * @noise_pwr_reports_recv: Number of noise power reports received 937 * @noise_pwr_reports_lock: Lock used for Noise power report processing 938 * @noise_pwr_chain_ctl: Noise power report - control channel 939 * @noise_pwr_chain_ext: Noise power report - extension channel 940 * @chaninfo: Channel statistics 941 * @tsf64: Latest TSF Value 942 * @param_info: Offload architecture Spectral parameter cache information 943 * @ch_width: Indicates Channel Width 20/40/80/160 MHz for each Spectral mode 944 * @diag_stats: Diagnostic statistics 945 * @is_160_format: Indicates whether information provided by HW is in altered 946 * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) 947 * @is_lb_edge_extrabins_format: Indicates whether information provided by 948 * HW has 4 extra bins, at left band edge, for report mode 2 949 * @is_rb_edge_extrabins_format: Indicates whether information provided 950 * by HW has 4 extra bins, at right band edge, for report mode 2 951 * @is_sec80_rssi_war_required: Indicates whether the software workaround is 952 * required to obtain approximate combined RSSI for secondary 80Mhz segment 953 * @simctx: Spectral Simulation context 954 * @spectral_gen: Spectral hardware generation 955 * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware 956 * generation 957 * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV 958 * header, for the given hardware generation 959 * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV 960 * header, for the given hardware generation 961 * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware 962 * generation 963 * @nl_cb: Netlink callbacks 964 * @use_nl_bcast: Whether to use Netlink broadcast/unicast 965 * @send_phy_data: Send data to the application layer for a particular msg type 966 * @len_adj_swar: Spectral fft bin length adjustment SWAR related info 967 * @timestamp_war: Spectral time stamp WAR related info 968 * @dbr_ring_debug: Whether Spectral DBR ring debug is enabled 969 * @dbr_buff_debug: Whether Spectral DBR buffer debug is enabled 970 * @direct_dma_support: Whether Direct-DMA is supported on the current radio 971 * @prev_tstamp: Timestamp of the previously received sample, which has to be 972 * compared with the current tstamp to check descrepancy 973 * @rparams: Parameters related to Spectral report structure 974 * @param_min_max: Spectral parameter's minimum and maximum values 975 */ 976 struct target_if_spectral { 977 struct wlan_objmgr_pdev *pdev_obj; 978 struct target_if_spectral_ops spectral_ops; 979 struct spectral_caps capability; 980 struct spectral_param_properties 981 properties[SPECTRAL_SCAN_MODE_MAX][SPECTRAL_PARAM_MAX]; 982 qdf_spinlock_t spectral_lock; 983 int16_t spectral_curchan_radindex; 984 int16_t spectral_extchan_radindex; 985 uint32_t spectraldomain; 986 uint32_t spectral_proc_phyerr; 987 struct spectral_config spectral_defaultparams; 988 struct target_if_spectral_stats spectral_stats; 989 struct target_if_spectral_event *events; 990 unsigned int sc_spectral_ext_chan_ok:1, 991 sc_spectral_combined_rssi_ok:1, 992 sc_spectral_20_40_mode:1, 993 sc_spectral_noise_pwr_cal:1, 994 sc_spectral_non_edma:1; 995 int upper_is_control; 996 int upper_is_extension; 997 int lower_is_control; 998 int lower_is_extension; 999 uint8_t sc_spectraltest_ieeechan; 1000 int spectral_numbins; 1001 int spectral_fft_len; 1002 int spectral_data_len; 1003 1004 /* 1005 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are 1006 * delivered. However, there can be additional bins reported for 1007 * AR900B version 2.0 and QCA9984 as described next: 1008 * 1009 * AR900B version 2.0: An additional tone is processed on the right 1010 * hand side in order to facilitate detection of radar pulses out to 1011 * the extreme band-edge of the channel frequency. Since the HW design 1012 * processes four tones at a time, this requires one additional Dword 1013 * to be added to the search FFT report. 1014 * 1015 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary + 1016 * 1x-oversampled bins (in-band) per FFT, then 8 more bins 1017 * (4 more on left side and 4 more on right side)are added. 1018 */ 1019 1020 int lb_edge_extrabins; 1021 int rb_edge_extrabins; 1022 int spectral_max_index_offset; 1023 int spectral_upper_max_index_offset; 1024 int spectral_lower_max_index_offset; 1025 int spectral_dc_index; 1026 int send_single_packet; 1027 int spectral_sent_msg; 1028 int classify_scan; 1029 qdf_timer_t classify_timer; 1030 struct spectral_config params[SPECTRAL_SCAN_MODE_MAX]; 1031 bool params_valid[SPECTRAL_SCAN_MODE_MAX]; 1032 struct spectral_classifier_params classifier_params; 1033 int last_capture_time; 1034 int num_spectral_data; 1035 int total_spectral_data; 1036 int max_rssi; 1037 int detects_control_channel; 1038 int detects_extension_channel; 1039 int detects_below_dc; 1040 int detects_above_dc; 1041 int sc_scanning; 1042 int sc_spectral_scan; 1043 int sc_spectral_full_scan; 1044 uint64_t scan_start_tstamp; 1045 uint32_t last_tstamp; 1046 uint32_t first_tstamp; 1047 uint32_t spectral_samp_count; 1048 uint32_t sc_spectral_samp_count; 1049 int noise_pwr_reports_reqd; 1050 int noise_pwr_reports_recv; 1051 qdf_spinlock_t noise_pwr_reports_lock; 1052 struct target_if_chain_noise_pwr_info 1053 *noise_pwr_chain_ctl[HOST_MAX_ANTENNA]; 1054 struct target_if_chain_noise_pwr_info 1055 *noise_pwr_chain_ext[HOST_MAX_ANTENNA]; 1056 uint64_t tsf64; 1057 #if ATH_PERF_PWR_OFFLOAD 1058 struct target_if_spectral_param_state_info 1059 param_info[SPECTRAL_SCAN_MODE_MAX]; 1060 #endif 1061 enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX]; 1062 struct spectral_diag_stats diag_stats; 1063 bool is_160_format; 1064 bool is_lb_edge_extrabins_format; 1065 bool is_rb_edge_extrabins_format; 1066 bool is_sec80_rssi_war_required; 1067 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 1068 void *simctx; 1069 #endif 1070 enum spectral_gen spectral_gen; 1071 uint8_t hdr_sig_exp; 1072 uint8_t tag_sscan_summary_exp; 1073 uint8_t tag_sscan_fft_exp; 1074 uint8_t tlvhdr_size; 1075 struct spectral_nl_cb nl_cb; 1076 bool use_nl_bcast; 1077 int (*send_phy_data)(struct wlan_objmgr_pdev *pdev, 1078 enum spectral_msg_type smsg_type); 1079 struct spectral_fft_bin_len_adj_swar len_adj_swar; 1080 struct spectral_timestamp_war timestamp_war; 1081 enum spectral_160mhz_report_delivery_state 1082 state_160mhz_delivery[SPECTRAL_SCAN_MODE_MAX]; 1083 bool dbr_ring_debug; 1084 bool dbr_buff_debug; 1085 bool direct_dma_support; 1086 uint32_t prev_tstamp; 1087 struct spectral_report_params rparams; 1088 struct spectral_param_min_max param_min_max; 1089 }; 1090 1091 /** 1092 * struct target_if_psoc_spectral - Target if psoc Spectral object 1093 * @psoc_obj: psoc object 1094 * @wmi_ops: Spectral WMI operations 1095 */ 1096 struct target_if_psoc_spectral { 1097 struct wlan_objmgr_psoc *psoc_obj; 1098 struct spectral_wmi_ops wmi_ops; 1099 }; 1100 1101 /** 1102 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 1103 * data format 1104 * @rssi: RSSI (except for secondary 80 segment) 1105 * @rssi_sec80: RSSI for secondary 80 segment 1106 * @lower_rssi: RSSI of lower band 1107 * @upper_rssi: RSSI of upper band 1108 * @chain_ctl_rssi: RSSI for control channel, for all antennas 1109 * @chain_ext_rssi: RSSI for extension channel, for all antennas 1110 * @bwinfo: bandwidth info 1111 * @data_len: length of FFT data (except for secondary 80 segment) 1112 * @data_len_sec80: length of FFT data for secondary 80 segment 1113 * @tstamp: timestamp 1114 * @last_tstamp: last time stamp 1115 * @max_mag: maximum magnitude (except for secondary 80 segment) 1116 * @max_mag_sec80: maximum magnitude for secondary 80 segment 1117 * @max_index: index of max magnitude (except for secondary 80 segment) 1118 * @max_index_sec80: index of max magnitude for secondary 80 segment 1119 * @max_exp: max exp 1120 * @peak: peak frequency (obsolete) 1121 * @pwr_count: number of FFT bins (except for secondary 80 segment) 1122 * @pwr_count_5mhz: number of FFT bins in extra 5 MHz in 1123 * 165 MHz/restricted 80p80 mode 1124 * @pwr_count_sec80: number of FFT bins in secondary 80 segment 1125 * @nb_lower: This is deprecated 1126 * @nb_upper: This is deprecated 1127 * @max_upper_index: index of max mag in upper band 1128 * @max_lower_index: index of max mag in lower band 1129 * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment) 1130 * @bin_pwr_data_5mhz: Contains FFT magnitudes for the extra 5 MHz 1131 * in 165 MHz/restricted 80p80 mode 1132 * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment 1133 * @freq: Center frequency of primary 20MHz channel in MHz 1134 * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz 1135 * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz 1136 * @agile_freq1: Center frequency in MHz of the entire span(for 80+80 MHz 1137 * agile Scan it is primary 80 MHz span) across which 1138 * Agile Spectral is carried out. Applicable only for Agile 1139 * Spectral samples. 1140 * @agile_freq2: Center frequency in MHz of the secondary 80 MHz span 1141 * across which Agile Spectral is carried out. Applicable 1142 * only for Agile Spectral samples in 80+80 MHz mode. 1143 * @freq_loading: spectral control duty cycles 1144 * @noise_floor: current noise floor (except for secondary 80 segment) 1145 * @noise_floor_sec80: current noise floor for secondary 80 segment 1146 * @interf_list: List of interfernce sources 1147 * @classifier_params: classifier parameters 1148 * @sc: classifier parameters 1149 * @pri80ind: Indication from hardware that the sample was received on the 1150 * primary 80 MHz segment. If this is set when smode = 1151 * SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried out on 1152 * pri80 instead of the Agile frequency due to a channel switch - Software may 1153 * choose to ignore the sample in this case. 1154 * @pri80ind_sec80: Indication from hardware that the sample was received on the 1155 * primary 80 MHz segment instead of the secondary 80 MHz segment due to a 1156 * channel switch - Software may choose to ignore the sample if this is set. 1157 * Applicable only if smode = SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz 1158 * Spectral operation and if the chipset supports fragmented 160/80+80 MHz 1159 * operation. 1160 * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of 160MHz 1161 * it will be primary 80 segment's timestamp as both primary & secondary 1162 * segment's timestamps are expected to be almost equal 1163 * @timestamp_war_offset: Offset calculated based on reset_delay and 1164 * last_raw_stamp. It will be added to raw_timestamp to get tstamp. 1165 * @raw_timestamp: FFT timestamp reported by HW on primary segment. 1166 * @raw_timestamp_sec80: FFT timestamp reported by HW on secondary 80 segment. 1167 * @reset_delay: Time gap between the last spectral report before reset and the 1168 * end of reset. 1169 * @target_reset_count: Indicates the the number of times the target went 1170 * through reset routine after spectral was enabled. 1171 */ 1172 struct target_if_samp_msg_params { 1173 int8_t rssi; 1174 int8_t rssi_sec80; 1175 int8_t lower_rssi; 1176 int8_t upper_rssi; 1177 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 1178 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 1179 uint16_t bwinfo; 1180 uint16_t datalen; 1181 uint16_t datalen_sec80; 1182 uint32_t tstamp; 1183 uint32_t last_tstamp; 1184 uint16_t max_mag; 1185 uint16_t max_mag_sec80; 1186 uint16_t max_index; 1187 uint16_t max_index_sec80; 1188 uint8_t max_exp; 1189 int peak; 1190 int pwr_count; 1191 int pwr_count_5mhz; 1192 int pwr_count_sec80; 1193 int8_t nb_lower; 1194 int8_t nb_upper; 1195 uint16_t max_lower_index; 1196 uint16_t max_upper_index; 1197 uint8_t *bin_pwr_data; 1198 uint8_t *bin_pwr_data_5mhz; 1199 uint8_t *bin_pwr_data_sec80; 1200 uint16_t freq; 1201 uint16_t vhtop_ch_freq_seg1; 1202 uint16_t vhtop_ch_freq_seg2; 1203 uint16_t agile_freq1; 1204 uint16_t agile_freq2; 1205 uint16_t freq_loading; 1206 int16_t noise_floor; 1207 int16_t noise_floor_sec80; 1208 struct interf_src_rsp interf_list; 1209 struct spectral_classifier_params classifier_params; 1210 struct ath_softc *sc; 1211 uint8_t agc_total_gain; 1212 uint8_t agc_total_gain_sec80; 1213 uint8_t gainchange; 1214 uint8_t gainchange_sec80; 1215 enum spectral_scan_mode smode; 1216 uint8_t pri80ind; 1217 uint8_t pri80ind_sec80; 1218 uint32_t last_raw_timestamp; 1219 uint32_t timestamp_war_offset; 1220 uint32_t raw_timestamp; 1221 uint32_t raw_timestamp_sec80; 1222 uint32_t reset_delay; 1223 uint32_t target_reset_count; 1224 }; 1225 1226 #ifdef WLAN_CONV_SPECTRAL_ENABLE 1227 /** 1228 * target_if_spectral_dump_fft() - Dump Spectral FFT 1229 * @pfft: Pointer to Spectral Phyerr FFT 1230 * @fftlen: FFT length 1231 * 1232 * Return: Success or failure 1233 */ 1234 int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen); 1235 1236 /** 1237 * target_if_dbg_print_samp_param() - Print contents of SAMP struct 1238 * @p: Pointer to SAMP message 1239 * 1240 * Return: Void 1241 */ 1242 void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p); 1243 1244 /** 1245 * target_if_get_offset_swar_sec80() - Get offset for SWAR according to 1246 * the channel width 1247 * @channel_width: Channel width 1248 * 1249 * Return: Offset for SWAR 1250 */ 1251 uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width); 1252 1253 /** 1254 * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops 1255 * @tx_ops: Tx Ops 1256 * 1257 * Return: void 1258 */ 1259 void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); 1260 1261 /** 1262 * target_if_spectral_create_samp_msg() - Create the spectral samp message 1263 * @spectral : Pointer to spectral internal structure 1264 * @params : spectral samp message parameters 1265 * 1266 * API to create the spectral samp message 1267 * 1268 * Return: void 1269 */ 1270 void target_if_spectral_create_samp_msg( 1271 struct target_if_spectral *spectral, 1272 struct target_if_samp_msg_params *params); 1273 1274 /** 1275 * target_if_spectral_process_phyerr_gen3() - Process phyerror event for gen3 1276 * @pdev: Pointer to pdev object 1277 * @payload: Pointer to spectral report 1278 * 1279 * Process phyerror event for gen3 1280 * 1281 * Return: Success/Failure 1282 */ 1283 int target_if_spectral_process_report_gen3( 1284 struct wlan_objmgr_pdev *pdev, 1285 void *buf); 1286 1287 /** 1288 * target_if_process_phyerr_gen2() - Process PHY Error for gen2 1289 * @spectral: Pointer to Spectral object 1290 * @data: Pointer to phyerror event buffer 1291 * @datalen: Data length 1292 * @p_rfqual: RF quality info 1293 * @p_chaninfo: Channel info 1294 * @tsf64: 64 bit tsf timestamp 1295 * @acs_stats: ACS stats 1296 * 1297 * Process PHY Error for gen2 1298 * 1299 * Return: Success/Failure 1300 */ 1301 int target_if_process_phyerr_gen2( 1302 struct target_if_spectral *spectral, 1303 uint8_t *data, 1304 uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual, 1305 struct target_if_spectral_chan_info *p_chaninfo, 1306 uint64_t tsf64, 1307 struct target_if_spectral_acs_stats *acs_stats); 1308 1309 /** 1310 * target_if_spectral_send_intf_found_msg() - Indicate to application layer that 1311 * interference has been found 1312 * @pdev: Pointer to pdev 1313 * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found 1314 * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled 1315 * 1316 * Send message to application layer 1317 * indicating that interference has been found 1318 * 1319 * Return: None 1320 */ 1321 void target_if_spectral_send_intf_found_msg( 1322 struct wlan_objmgr_pdev *pdev, 1323 uint16_t cw_int, uint32_t dcs_enabled); 1324 1325 /** 1326 * target_if_stop_spectral_scan() - Stop spectral scan 1327 * @pdev: Pointer to pdev object 1328 * @smode: Spectral scan mode 1329 * @err: Pointer to error code 1330 * 1331 * API to stop the current on-going spectral scan 1332 * 1333 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 1334 */ 1335 QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, 1336 const enum spectral_scan_mode smode, 1337 enum spectral_cp_error_code *err); 1338 1339 /** 1340 * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral 1341 * operations 1342 * @spectral: Pointer to Spectral target_if internal private data 1343 * 1344 * Spectral operates on pdev. However, in order to retrieve some WLAN 1345 * properties, a vdev is required. To facilitate this, the function returns the 1346 * first vdev in our pdev. The caller should release the reference to the vdev 1347 * once it is done using it. 1348 * TODO: If the framework later provides an API to obtain the first active 1349 * vdev, then it would be preferable to use this API. 1350 * 1351 * Return: Pointer to vdev on success, NULL on failure 1352 */ 1353 struct wlan_objmgr_vdev *target_if_spectral_get_vdev( 1354 struct target_if_spectral *spectral); 1355 1356 /** 1357 * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2 1358 * @phdr: Pointer to Spectral Phyerr Header 1359 * 1360 * Dump Spectral header 1361 * 1362 * Return: Success/Failure 1363 */ 1364 int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr); 1365 1366 /** 1367 * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI 1368 * for Secondary 80 segment 1369 * @spectral: Pointer to spectral object 1370 * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment 1371 * 1372 * Get approximate combined RSSI for Secondary 80 segment 1373 * 1374 * Return: Combined RSSI for secondary 80Mhz segment 1375 */ 1376 int8_t target_if_get_combrssi_sec80_seg_gen2( 1377 struct target_if_spectral *spectral, 1378 struct spectral_search_fft_info_gen2 *p_sfft_sec80); 1379 1380 /** 1381 * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2 1382 * @ptlv: Pointer to Spectral Phyerr TLV 1383 * @is_160_format: Indicates 160 format 1384 * 1385 * Dump Spectral TLV for gen2 1386 * 1387 * Return: Success/Failure 1388 */ 1389 int target_if_spectral_dump_tlv_gen2( 1390 struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format); 1391 1392 /** 1393 * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral 1394 * related PHY Error for gen2 1395 * @data: Pointer to phyerror buffer 1396 * @datalen: Data length 1397 * @is_160_format: Indicates 160 format 1398 * 1399 * Dump Spectral related PHY Error for gen2 1400 * 1401 * Return: Success/Failure 1402 */ 1403 int target_if_spectral_dump_phyerr_data_gen2( 1404 uint8_t *data, 1405 uint32_t datalen, 1406 bool is_160_format); 1407 1408 /** 1409 * target_if_dbg_print_samp_msg() - Print contents of SAMP Message 1410 * @p: Pointer to SAMP message 1411 * 1412 * Print contents of SAMP Message 1413 * 1414 * Return: Void 1415 */ 1416 void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); 1417 1418 /** 1419 * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal 1420 * Spectral data 1421 * @pdev: Pointer to pdev 1422 * 1423 * Return: Handle to target_if internal Spectral data on success, NULL on 1424 * failure 1425 */ 1426 static inline 1427 struct target_if_spectral *get_target_if_spectral_handle_from_pdev( 1428 struct wlan_objmgr_pdev *pdev) 1429 { 1430 struct target_if_spectral *spectral; 1431 struct wlan_objmgr_psoc *psoc; 1432 struct wlan_lmac_if_rx_ops *rx_ops; 1433 1434 if (!pdev) { 1435 spectral_err("pdev is null"); 1436 return NULL; 1437 } 1438 1439 psoc = wlan_pdev_get_psoc(pdev); 1440 if (!psoc) { 1441 spectral_err("psoc is null"); 1442 return NULL; 1443 } 1444 1445 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1446 if (!rx_ops) { 1447 spectral_err("rx_ops is null"); 1448 return NULL; 1449 } 1450 1451 spectral = (struct target_if_spectral *) 1452 rx_ops->sptrl_rx_ops.sptrlro_get_pdev_target_handle(pdev); 1453 1454 return spectral; 1455 } 1456 1457 /** 1458 * get_target_if_spectral_handle_from_psoc() - Get handle to psoc target_if 1459 * internal Spectral data 1460 * @psoc: Pointer to psoc 1461 * 1462 * Return: Handle to target_if psoc internal Spectral data on success, NULL on 1463 * failure 1464 */ 1465 static inline 1466 struct target_if_psoc_spectral *get_target_if_spectral_handle_from_psoc( 1467 struct wlan_objmgr_psoc *psoc) 1468 { 1469 struct wlan_lmac_if_rx_ops *rx_ops; 1470 struct target_if_psoc_spectral *psoc_spectral; 1471 1472 if (!psoc) { 1473 spectral_err("psoc is null"); 1474 return NULL; 1475 } 1476 1477 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1478 if (!rx_ops) { 1479 spectral_err("rx_ops is null"); 1480 return NULL; 1481 } 1482 1483 psoc_spectral = (struct target_if_psoc_spectral *) 1484 rx_ops->sptrl_rx_ops.sptrlro_get_psoc_target_handle(psoc); 1485 1486 return psoc_spectral; 1487 } 1488 1489 /** 1490 * target_if_vdev_get_chan_freq() - Get the operating channel frequency of a 1491 * given vdev 1492 * @pdev: Pointer to vdev 1493 * 1494 * Get the operating channel frequency of a given vdev 1495 * 1496 * Return: Operating channel frequency of a vdev 1497 */ 1498 static inline 1499 int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) 1500 { 1501 struct wlan_objmgr_psoc *psoc = NULL; 1502 struct wlan_lmac_if_rx_ops *rx_ops; 1503 1504 psoc = wlan_vdev_get_psoc(vdev); 1505 if (!psoc) { 1506 spectral_err("psoc is NULL"); 1507 return -EINVAL; 1508 } 1509 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1510 if (!rx_ops) { 1511 spectral_err("rx_ops is null"); 1512 return -EINVAL; 1513 } 1514 1515 return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq( 1516 vdev); 1517 } 1518 1519 /** 1520 * target_if_vdev_get_chan_freq_seg2() - Get center frequency of secondary 80 of 1521 * given vdev 1522 * @vdev: Pointer to vdev 1523 * 1524 * Get the center frequency of secondary 80 of given vdev 1525 * 1526 * Return: center frequency of secondary 80 1527 */ 1528 static inline 1529 int16_t target_if_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev) 1530 { 1531 struct wlan_objmgr_psoc *psoc = NULL; 1532 struct wlan_lmac_if_rx_ops *rx_ops; 1533 1534 psoc = wlan_vdev_get_psoc(vdev); 1535 if (!psoc) { 1536 spectral_err("psoc is NULL"); 1537 return -EINVAL; 1538 } 1539 1540 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1541 if (!rx_ops) { 1542 spectral_err("rx_ops is null"); 1543 return -EINVAL; 1544 } 1545 1546 return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq_seg2(vdev); 1547 } 1548 1549 /** 1550 * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a 1551 * given vdev 1552 * @pdev: Pointer to vdev 1553 * 1554 * Get the operating channel bandwidth of a given vdev 1555 * 1556 * Return: channel bandwidth enumeration corresponding to the vdev 1557 */ 1558 static inline 1559 enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) 1560 { 1561 struct wlan_objmgr_psoc *psoc = NULL; 1562 enum phy_ch_width ch_width; 1563 struct wlan_lmac_if_rx_ops *rx_ops; 1564 1565 psoc = wlan_vdev_get_psoc(vdev); 1566 if (!psoc) { 1567 spectral_err("psoc is NULL"); 1568 return CH_WIDTH_INVALID; 1569 } 1570 1571 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1572 if (!rx_ops) { 1573 spectral_err("rx_ops is null"); 1574 return CH_WIDTH_INVALID; 1575 } 1576 1577 ch_width = rx_ops->sptrl_rx_ops.sptrlro_vdev_get_ch_width(vdev); 1578 1579 if (ch_width == CH_WIDTH_160MHZ) { 1580 int16_t cfreq2; 1581 1582 cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev); 1583 if (cfreq2 < 0) { 1584 spectral_err("Invalid value for cfreq2 %d", cfreq2); 1585 return CH_WIDTH_INVALID; 1586 } 1587 1588 /* Use non zero cfreq2 to identify 80p80 */ 1589 if (cfreq2) 1590 ch_width = CH_WIDTH_80P80MHZ; 1591 } 1592 1593 return ch_width; 1594 } 1595 1596 /** 1597 * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary 1598 * 20 MHz channel for a given vdev 1599 * @pdev: Pointer to vdev 1600 * 1601 * Get the frequency of secondary 20Mhz channel for a given vdev 1602 * 1603 * Return: Frequency of secondary 20Mhz channel for a given vdev 1604 */ 1605 static inline 1606 int target_if_vdev_get_sec20chan_freq_mhz( 1607 struct wlan_objmgr_vdev *vdev, 1608 uint16_t *sec20chan_freq) 1609 { 1610 struct wlan_objmgr_psoc *psoc = NULL; 1611 struct wlan_lmac_if_rx_ops *rx_ops; 1612 1613 psoc = wlan_vdev_get_psoc(vdev); 1614 if (!psoc) { 1615 spectral_err("psoc is NULL"); 1616 return -EINVAL; 1617 } 1618 1619 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1620 if (!rx_ops) { 1621 spectral_err("rx_ops is null"); 1622 return -EINVAL; 1623 } 1624 1625 return rx_ops->sptrl_rx_ops. 1626 sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); 1627 } 1628 1629 /** 1630 * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask 1631 * @pdev: Pointer to pdev 1632 * @spectral_rx_chainmask: Spectral Rx chainmask 1633 * 1634 * Return: None 1635 */ 1636 static inline 1637 void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, 1638 uint8_t spectral_rx_chainmask) 1639 { 1640 struct wlan_objmgr_psoc *psoc = NULL; 1641 struct target_if_spectral *spectral = NULL; 1642 enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL; 1643 struct wlan_lmac_if_rx_ops *rx_ops; 1644 1645 psoc = wlan_pdev_get_psoc(pdev); 1646 if (!psoc) { 1647 spectral_err("psoc is NULL"); 1648 return; 1649 } 1650 1651 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1652 if (!rx_ops) { 1653 spectral_err("rx_ops is null"); 1654 return; 1655 } 1656 1657 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 1658 spectral_err("Invalid Spectral mode %u", smode); 1659 return; 1660 } 1661 1662 if (rx_ops->sptrl_rx_ops. 1663 sptrlro_spectral_is_feature_disabled(psoc)) { 1664 spectral_info("Spectral is disabled"); 1665 return; 1666 } 1667 1668 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1669 if (!spectral) { 1670 spectral_err("Spectral target if object is null"); 1671 return; 1672 } 1673 1674 /* set chainmask for all the modes */ 1675 for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) 1676 spectral->params[smode].ss_chn_mask = spectral_rx_chainmask; 1677 } 1678 1679 /** 1680 * target_if_spectral_process_phyerr() - Process Spectral PHY error 1681 * @pdev: Pointer to pdev 1682 * @data: PHY error data received from FW 1683 * @datalen: Length of data 1684 * @p_rfqual: Pointer to RF Quality information 1685 * @p_chaninfo: Pointer to channel information 1686 * @tsf: TSF time instance at which the Spectral sample was received 1687 * @acs_stats: ACS stats 1688 * 1689 * Process Spectral PHY error by extracting necessary information from the data 1690 * sent by FW, and send the extracted information to application layer. 1691 * 1692 * Return: None 1693 */ 1694 static inline 1695 void target_if_spectral_process_phyerr( 1696 struct wlan_objmgr_pdev *pdev, 1697 uint8_t *data, uint32_t datalen, 1698 struct target_if_spectral_rfqual_info *p_rfqual, 1699 struct target_if_spectral_chan_info *p_chaninfo, 1700 uint64_t tsf64, 1701 struct target_if_spectral_acs_stats *acs_stats) 1702 { 1703 struct target_if_spectral *spectral = NULL; 1704 struct target_if_spectral_ops *p_sops = NULL; 1705 1706 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1707 if (!spectral) { 1708 spectral_err("Spectral target if object is null"); 1709 return; 1710 } 1711 1712 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1713 p_sops->spectral_process_phyerr(spectral, data, datalen, 1714 p_rfqual, p_chaninfo, 1715 tsf64, acs_stats); 1716 } 1717 1718 static QDF_STATUS 1719 target_if_get_spectral_msg_type(enum spectral_scan_mode smode, 1720 enum spectral_msg_type *msg_type) { 1721 1722 switch (smode) { 1723 case SPECTRAL_SCAN_MODE_NORMAL: 1724 *msg_type = SPECTRAL_MSG_NORMAL_MODE; 1725 break; 1726 1727 case SPECTRAL_SCAN_MODE_AGILE: 1728 *msg_type = SPECTRAL_MSG_AGILE_MODE; 1729 break; 1730 1731 default: 1732 spectral_err("Invalid spectral mode"); 1733 return QDF_STATUS_E_FAILURE; 1734 } 1735 1736 return QDF_STATUS_SUCCESS; 1737 } 1738 1739 static inline bool 1740 is_ch_width_160_or_80p80(enum phy_ch_width ch_width) 1741 { 1742 return (ch_width == CH_WIDTH_160MHZ || ch_width == CH_WIDTH_80P80MHZ); 1743 } 1744 1745 /** 1746 * init_160mhz_delivery_state_machine() - Initialize 160MHz Spectral 1747 * state machine 1748 * @spectral: Pointer to Spectral 1749 * 1750 * Initialize 160MHz Spectral state machine 1751 * 1752 * Return: void 1753 */ 1754 static inline void 1755 init_160mhz_delivery_state_machine(struct target_if_spectral *spectral) 1756 { 1757 uint8_t smode; 1758 1759 smode = 0; 1760 for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) 1761 spectral->state_160mhz_delivery[smode] = 1762 SPECTRAL_REPORT_WAIT_PRIMARY80; 1763 } 1764 1765 /** 1766 * reset_160mhz_delivery_state_machine() - Reset 160MHz Spectral state machine 1767 * @spectral: Pointer to Spectral 1768 * 1769 * Reset 160MHz Spectral state machine 1770 * 1771 * Return: void 1772 */ 1773 static inline void 1774 reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, 1775 enum spectral_scan_mode smode) 1776 { 1777 enum spectral_msg_type smsg_type; 1778 QDF_STATUS ret; 1779 1780 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 1781 spectral_err_rl("Invalid Spectral mode %d", smode); 1782 return; 1783 } 1784 1785 if (is_ch_width_160_or_80p80(spectral->ch_width[smode])) { 1786 spectral->state_160mhz_delivery[smode] = 1787 SPECTRAL_REPORT_WAIT_PRIMARY80; 1788 1789 ret = target_if_get_spectral_msg_type(smode, &smsg_type); 1790 if (QDF_IS_STATUS_ERROR(ret)) { 1791 spectral_err("Failed to get spectral message type"); 1792 return; 1793 } 1794 1795 spectral->nl_cb.free_sbuff(spectral->pdev_obj, 1796 smsg_type); 1797 } 1798 } 1799 1800 /** 1801 * is_secondaryseg_expected() - Is waiting for secondary 80 report 1802 * @spectral: Pointer to Spectral 1803 * @smode: Spectral scan mode 1804 * 1805 * Return true if secondary 80 report expected and mode is 160 MHz 1806 * 1807 * Return: true or false 1808 */ 1809 static inline 1810 bool is_secondaryseg_expected(struct target_if_spectral *spectral, 1811 enum spectral_scan_mode smode) 1812 { 1813 return 1814 (is_ch_width_160_or_80p80(spectral->ch_width[smode]) && 1815 spectral->rparams.fragmentation_160[smode] && 1816 (spectral->state_160mhz_delivery[smode] == 1817 SPECTRAL_REPORT_WAIT_SECONDARY80)); 1818 } 1819 1820 /** 1821 * is_primaryseg_expected() - Is waiting for primary 80 report 1822 * @spectral: Pointer to Spectral 1823 * @smode: Spectral scan mode 1824 * 1825 * Return true if mode is 160 Mhz and primary 80 report expected or 1826 * mode is not 160 Mhz 1827 * 1828 * Return: true or false 1829 */ 1830 static inline 1831 bool is_primaryseg_expected(struct target_if_spectral *spectral, 1832 enum spectral_scan_mode smode) 1833 { 1834 return 1835 (!is_ch_width_160_or_80p80(spectral->ch_width[smode]) || 1836 !spectral->rparams.fragmentation_160[smode] || 1837 (spectral->state_160mhz_delivery[smode] == 1838 SPECTRAL_REPORT_WAIT_PRIMARY80)); 1839 } 1840 1841 /** 1842 * is_primaryseg_rx_inprog() - Is primary 80 report processing is in progress 1843 * @spectral: Pointer to Spectral 1844 * @smode: Spectral scan mode 1845 * 1846 * Is primary 80 report processing is in progress 1847 * 1848 * Return: true or false 1849 */ 1850 static inline 1851 bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral, 1852 enum spectral_scan_mode smode) 1853 { 1854 return 1855 (!is_ch_width_160_or_80p80(spectral->ch_width[smode]) || 1856 spectral->spectral_gen == SPECTRAL_GEN2 || 1857 (spectral->spectral_gen == SPECTRAL_GEN3 && 1858 (!spectral->rparams.fragmentation_160[smode] || 1859 spectral->state_160mhz_delivery[smode] == 1860 SPECTRAL_REPORT_RX_PRIMARY80))); 1861 } 1862 1863 /** 1864 * is_secondaryseg_rx_inprog() - Is secondary80 report processing is in progress 1865 * @spectral: Pointer to Spectral 1866 * @smode: Spectral scan mode 1867 * 1868 * Is secondary 80 report processing is in progress 1869 * 1870 * Return: true or false 1871 */ 1872 static inline 1873 bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral, 1874 enum spectral_scan_mode smode) 1875 { 1876 return 1877 (is_ch_width_160_or_80p80(spectral->ch_width[smode]) && 1878 (spectral->spectral_gen == SPECTRAL_GEN2 || 1879 ((spectral->spectral_gen == SPECTRAL_GEN3) && 1880 (!spectral->rparams.fragmentation_160[smode] || 1881 spectral->state_160mhz_delivery[smode] == 1882 SPECTRAL_REPORT_RX_SECONDARY80)))); 1883 } 1884 1885 /** 1886 * target_if_160mhz_delivery_state_change() - State transition for 160Mhz 1887 * Spectral 1888 * @spectral: Pointer to spectral object 1889 * @smode: Spectral scan mode 1890 * @detector_id: Detector id 1891 * 1892 * Move the states of state machine for 160MHz spectral scan report receive 1893 * 1894 * Return: QDF_STATUS 1895 */ 1896 QDF_STATUS 1897 target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, 1898 enum spectral_scan_mode smode, 1899 uint8_t detector_id); 1900 1901 /** 1902 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 1903 * @arg: Pointer to handle for Spectral target_if internal private data 1904 * @smode: Spectral scan mode 1905 * 1906 * Function to check whether Spectral is enabled 1907 * 1908 * Return: True if Spectral is enabled, false if Spectral is not enabled 1909 */ 1910 uint32_t target_if_sops_is_spectral_enabled(void *arg, 1911 enum spectral_scan_mode smode); 1912 1913 /** 1914 * target_if_sops_is_spectral_active() - Get whether Spectral is active 1915 * @arg: Pointer to handle for Spectral target_if internal private data 1916 * @smode: Spectral scan mode 1917 * 1918 * Function to check whether Spectral is active 1919 * 1920 * Return: True if Spectral is active, false if Spectral is not active 1921 */ 1922 uint32_t target_if_sops_is_spectral_active(void *arg, 1923 enum spectral_scan_mode smode); 1924 1925 /** 1926 * target_if_sops_start_spectral_scan() - Start Spectral scan 1927 * @arg: Pointer to handle for Spectral target_if internal private data 1928 * @smode: Spectral scan mode 1929 * @err: Pointer to error code 1930 * 1931 * Function to start spectral scan 1932 * 1933 * Return: 0 on success else failure 1934 */ 1935 uint32_t target_if_sops_start_spectral_scan(void *arg, 1936 enum spectral_scan_mode smode, 1937 enum spectral_cp_error_code *err); 1938 1939 /** 1940 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 1941 * @arg: Pointer to handle for Spectral target_if internal private data 1942 * @smode: Spectral scan mode 1943 * 1944 * Function to stop spectral scan 1945 * 1946 * Return: 0 in case of success, -1 on failure 1947 */ 1948 uint32_t target_if_sops_stop_spectral_scan(void *arg, 1949 enum spectral_scan_mode smode); 1950 1951 /** 1952 * target_if_spectral_get_extension_channel() - Get the current Extension 1953 * channel (in MHz) 1954 * @arg: Pointer to handle for Spectral target_if internal private data 1955 * 1956 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 1957 * extension channel is not present. 1958 */ 1959 uint32_t target_if_spectral_get_extension_channel(void *arg); 1960 1961 /** 1962 * target_if_spectral_get_current_channel() - Get the current channel (in MHz) 1963 * @arg: Pointer to handle for Spectral target_if internal private data 1964 * 1965 * Return: Current channel (in MHz) on success, 0 on failure 1966 */ 1967 uint32_t target_if_spectral_get_current_channel(void *arg); 1968 1969 1970 /** 1971 * target_if_spectral_reset_hw() - Reset the hardware 1972 * @arg: Pointer to handle for Spectral target_if internal private data 1973 * 1974 * This is only a placeholder since it is not currently required in the offload 1975 * case. 1976 * 1977 * Return: 0 1978 */ 1979 uint32_t target_if_spectral_reset_hw(void *arg); 1980 1981 /** 1982 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 1983 * Noisefloor history buffer 1984 * @arg: Pointer to handle for Spectral target_if internal private data 1985 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 1986 * 1987 * This is only a placeholder since it is not currently required in the offload 1988 * case. 1989 * 1990 * Return: 0 1991 */ 1992 uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf); 1993 1994 /** 1995 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 1996 * noisefloor 1997 * @arg: Pointer to handle for Spectral target_if internal private data 1998 * 1999 * This is only a placeholder since it is not currently required in the offload 2000 * case. 2001 * 2002 * Return: 0 2003 */ 2004 int8_t target_if_spectral_get_ext_noisefloor(void *arg); 2005 2006 /** 2007 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 2008 * @arg: Pointer to handle for Spectral target_if internal private data 2009 * 2010 * This is only a placeholder since it is not currently required in the offload 2011 * case. 2012 * 2013 * Return: 0 2014 */ 2015 int8_t target_if_spectral_get_ctl_noisefloor(void *arg); 2016 2017 /** 2018 * target_if_spectral_get_capability() - Get whether a given Spectral hardware 2019 * capability is available 2020 * @arg: Pointer to handle for Spectral target_if internal private data 2021 * @type: Spectral hardware capability type 2022 * 2023 * Return: True if the capability is available, false if the capability is not 2024 * available 2025 */ 2026 uint32_t target_if_spectral_get_capability( 2027 void *arg, enum spectral_capability_type type); 2028 2029 /** 2030 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 2031 * @arg: Pointer to handle for Spectral target_if internal private data 2032 * @rxfilter: Rx filter to be used 2033 * 2034 * Note: This is only a placeholder function. It is not currently required since 2035 * FW should be taking care of setting the required filters. 2036 * 2037 * Return: 0 2038 */ 2039 uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter); 2040 2041 /** 2042 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 2043 * parameters 2044 * @arg: Pointer to handle for Spectral target_if internal private data 2045 * @params: Spectral parameters 2046 * @smode: Spectral scan mode 2047 * 2048 * Return: 0 in case of success, -1 on failure 2049 */ 2050 uint32_t target_if_spectral_sops_configure_params( 2051 void *arg, struct spectral_config *params, 2052 enum spectral_scan_mode smode); 2053 2054 /** 2055 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 2056 * @arg: Pointer to handle for Spectral target_if internal private data 2057 * 2058 * Note: This is only a placeholder function. It is not currently required since 2059 * FW should be taking care of setting the required filters. 2060 * 2061 * Return: 0 2062 */ 2063 uint32_t target_if_spectral_get_rxfilter(void *arg); 2064 2065 /** 2066 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 2067 * functionality for the given pdev 2068 * @pdev: Pointer to pdev object 2069 * 2070 * Return: None 2071 */ 2072 void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev); 2073 2074 /** 2075 * target_if_set_spectral_config() - Set spectral config 2076 * @pdev: Pointer to pdev object 2077 * @param: Spectral parameter id and value 2078 * @smode: Spectral scan mode 2079 * @err: Pointer to Spectral error code 2080 * 2081 * API to set spectral configurations 2082 * 2083 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2084 */ 2085 QDF_STATUS target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 2086 const struct spectral_cp_param *param, 2087 const enum spectral_scan_mode smode, 2088 enum spectral_cp_error_code *err); 2089 2090 /** 2091 * target_if_pdev_spectral_init() - Initialize target_if Spectral 2092 * functionality for the given pdev 2093 * @pdev: Pointer to pdev object 2094 * 2095 * Return: On success, pointer to Spectral target_if internal private data, on 2096 * failure, NULL 2097 */ 2098 void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev); 2099 2100 /** 2101 * target_if_spectral_sops_get_params() - Get user configured Spectral 2102 * parameters 2103 * @arg: Pointer to handle for Spectral target_if internal private data 2104 * @params: Pointer to buffer into which Spectral parameters should be copied 2105 * @smode: Spectral scan mode 2106 * 2107 * Return: 0 in case of success, -1 on failure 2108 */ 2109 uint32_t target_if_spectral_sops_get_params( 2110 void *arg, struct spectral_config *params, 2111 enum spectral_scan_mode smode); 2112 2113 /** 2114 * target_if_init_spectral_capability() - Initialize Spectral capability 2115 * 2116 * @spectral: Pointer to Spectral target_if internal private data 2117 * @target_type: target type 2118 * 2119 * This is a workaround. 2120 * 2121 * Return: QDF_STATUS 2122 */ 2123 QDF_STATUS 2124 target_if_init_spectral_capability(struct target_if_spectral *spectral, 2125 uint32_t target_type); 2126 2127 /** 2128 * target_if_start_spectral_scan() - Start spectral scan 2129 * @pdev: Pointer to pdev object 2130 * @smode: Spectral scan mode 2131 * @err: Spectral error code 2132 * 2133 * API to start spectral scan 2134 * 2135 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2136 */ 2137 QDF_STATUS target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, 2138 enum spectral_scan_mode smode, 2139 enum spectral_cp_error_code *err); 2140 2141 /** 2142 * target_if_get_spectral_config() - Get spectral configuration 2143 * @pdev: Pointer to pdev object 2144 * @param: Pointer to spectral_config structure in which the configuration 2145 * should be returned 2146 * @smode: Spectral scan mode 2147 * 2148 * API to get the current spectral configuration 2149 * 2150 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2151 */ 2152 QDF_STATUS target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 2153 struct spectral_config *param, 2154 enum spectral_scan_mode smode); 2155 2156 /** 2157 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 2158 * parameters 2159 * @spectral: Pointer to Spectral target_if internal private data 2160 * @spectral_params: Pointer to Spectral parameters 2161 * @smode: Spectral scan mode 2162 * @err: Spectral error code 2163 * 2164 * Enable use of desired Spectral parameters by configuring them into HW, and 2165 * starting Spectral scan 2166 * 2167 * Return: 0 on success, 1 on failure 2168 */ 2169 int target_if_spectral_scan_enable_params( 2170 struct target_if_spectral *spectral, 2171 struct spectral_config *spectral_params, 2172 enum spectral_scan_mode smode, 2173 enum spectral_cp_error_code *err); 2174 2175 /** 2176 * target_if_is_spectral_active() - Get whether Spectral is active 2177 * @pdev: Pointer to pdev object 2178 * @smode: Spectral scan mode 2179 * 2180 * Return: True if Spectral is active, false if Spectral is not active 2181 */ 2182 bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev, 2183 enum spectral_scan_mode smode); 2184 2185 /** 2186 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 2187 * @pdev: Pointer to pdev object 2188 * @smode: Spectral scan mode 2189 * 2190 * Return: True if Spectral is enabled, false if Spectral is not enabled 2191 */ 2192 bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev, 2193 enum spectral_scan_mode smode); 2194 2195 /** 2196 * target_if_set_debug_level() - Set debug level for Spectral 2197 * @pdev: Pointer to pdev object 2198 * @debug_level: Debug level 2199 * 2200 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2201 * 2202 */ 2203 QDF_STATUS target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, 2204 uint32_t debug_level); 2205 2206 /** 2207 * target_if_get_debug_level() - Get debug level for Spectral 2208 * @pdev: Pointer to pdev object 2209 * 2210 * Return: Current debug level 2211 */ 2212 uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev); 2213 2214 2215 /** 2216 * target_if_get_spectral_capinfo() - Get Spectral capability information 2217 * @pdev: Pointer to pdev object 2218 * @scaps: Buffer into which data should be copied 2219 * 2220 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2221 */ 2222 QDF_STATUS target_if_get_spectral_capinfo(struct wlan_objmgr_pdev *pdev, 2223 struct spectral_caps *scaps); 2224 2225 2226 /** 2227 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 2228 * @pdev: Pointer to pdev object 2229 * @stats: Buffer into which data should be copied 2230 * 2231 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2232 */ 2233 QDF_STATUS target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, 2234 struct spectral_diag_stats *stats); 2235 2236 QDF_STATUS 2237 target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, 2238 enum spectral_scan_mode smode, 2239 uint8_t detector_id); 2240 #ifdef DIRECT_BUF_RX_ENABLE 2241 /** 2242 * target_if_consume_sfft_report_gen3() - Process fft report for gen3 2243 * @spectral: Pointer to spectral object 2244 * @report: Pointer to spectral report 2245 * 2246 * Process fft report for gen3 2247 * 2248 * Return: Success/Failure 2249 */ 2250 int 2251 target_if_consume_spectral_report_gen3( 2252 struct target_if_spectral *spectral, 2253 struct spectral_report *report); 2254 #endif 2255 2256 /** 2257 * target_if_spectral_fw_hang() - Crash the FW from Spectral module 2258 * @spectral: Pointer to Spectral LMAC object 2259 * 2260 * Return: QDF_STATUS of operation 2261 */ 2262 QDF_STATUS target_if_spectral_fw_hang(struct target_if_spectral *spectral); 2263 2264 #ifdef WIN32 2265 #pragma pack(pop, target_if_spectral) 2266 #endif 2267 #ifdef __ATTRIB_PACK 2268 #undef __ATTRIB_PACK 2269 #endif 2270 2271 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 2272 #endif /* _TARGET_IF_SPECTRAL_H_ */ 2273