1 /* 2 * Copyright (c) 2011,2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 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 <wlan_reg_services_api.h> 28 #include <qdf_lock.h> 29 #include <wlan_spectral_public_structs.h> 30 #include <reg_services_public_struct.h> 31 #ifdef DIRECT_BUF_RX_ENABLE 32 #include <target_if_direct_buf_rx_api.h> 33 #endif 34 #ifdef WIN32 35 #pragma pack(push, target_if_spectral, 1) 36 #define __ATTRIB_PACK 37 #else 38 #ifndef __ATTRIB_PACK 39 #define __ATTRIB_PACK __attribute__ ((packed)) 40 #endif 41 #endif 42 43 #include <spectral_defs_i.h> 44 #include <wmi_unified_param.h> 45 46 #define FREQ_OFFSET_10MHZ (10) 47 #define FREQ_OFFSET_40MHZ (40) 48 #define FREQ_OFFSET_80MHZ (80) 49 #define FREQ_OFFSET_85MHZ (85) 50 #ifndef SPECTRAL_USE_NL_BCAST 51 #define SPECTRAL_USE_NL_BCAST (0) 52 #endif 53 54 #define STATUS_PASS 1 55 #define STATUS_FAIL 0 56 #undef spectral_dbg_line 57 #define spectral_dbg_line() \ 58 spectral_debug("----------------------------------------------------") 59 60 #undef spectral_ops_not_registered 61 #define spectral_ops_not_registered(str) \ 62 spectral_info("SPECTRAL : %s not registered\n", (str)) 63 #undef not_yet_implemented 64 #define not_yet_implemented() \ 65 spectral_info("SPECTRAL : %s : %d Not yet implemented\n", \ 66 __func__, __LINE__) 67 68 #define SPECTRAL_HT20_NUM_BINS 56 69 #define SPECTRAL_HT20_FFT_LEN 56 70 #define SPECTRAL_HT20_DC_INDEX (SPECTRAL_HT20_FFT_LEN / 2) 71 #define SPECTRAL_HT20_DATA_LEN 60 72 #define SPECTRAL_HT20_TOTAL_DATA_LEN (SPECTRAL_HT20_DATA_LEN + 3) 73 #define SPECTRAL_HT40_TOTAL_NUM_BINS 128 74 #define SPECTRAL_HT40_DATA_LEN 135 75 #define SPECTRAL_HT40_TOTAL_DATA_LEN (SPECTRAL_HT40_DATA_LEN + 3) 76 #define SPECTRAL_HT40_FFT_LEN 128 77 #define SPECTRAL_HT40_DC_INDEX (SPECTRAL_HT40_FFT_LEN / 2) 78 79 /* 80 * Used for the SWAR to obtain approximate combined rssi 81 * in secondary 80Mhz segment 82 */ 83 #define OFFSET_CH_WIDTH_20 65 84 #define OFFSET_CH_WIDTH_40 62 85 #define OFFSET_CH_WIDTH_80 56 86 #define OFFSET_CH_WIDTH_160 50 87 88 /* Min and max for relevant Spectral params */ 89 #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2 (1) 90 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2 (9) 91 #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3 (5) 92 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT (9) 93 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000 (10) 94 #define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3_BE (5) 95 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_BE (11) 96 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_BE_20MHZ (9) 97 #define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_BE_40MHZ (10) 98 #define INVALID_FFT_SIZE (0xFFFF) 99 #define SPECTRAL_PARAM_RPT_MODE_MIN (0) 100 #define SPECTRAL_PARAM_RPT_MODE_MAX (3) 101 #define SPECTRAL_DWORD_SIZE (4) 102 103 #define MAX_FFTBIN_VALUE_LINEAR_MODE (U8_MAX) 104 #define MAX_FFTBIN_VALUE_DBM_MODE (S8_MAX) 105 #define MIN_FFTBIN_VALUE_DBM_MODE (S8_MIN) 106 #define MAX_FFTBIN_VALUE (255) 107 108 /* DBR ring debug size for Spectral */ 109 #define SPECTRAL_DBR_RING_DEBUG_SIZE 512 110 111 #ifdef BIG_ENDIAN_HOST 112 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) do { \ 113 int j; \ 114 uint32_t *src, *dest; \ 115 src = (uint32_t *)(srcp); \ 116 dest = (uint32_t *)(destp); \ 117 for (j = 0; j < roundup((len), sizeof(uint32_t)) / 4; j++) { \ 118 *(dest + j) = qdf_le32_to_cpu(*(src + j)); \ 119 } \ 120 } while (0) 121 #else 122 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) \ 123 OS_MEMCPY((destp), (srcp), (len)); 124 #endif 125 126 #define DUMMY_NF_VALUE (-123) 127 /* 5 categories x (lower + upper) bands */ 128 #define MAX_INTERF 10 129 #define HOST_MAX_ANTENNA 3 130 /* Mask for time stamp from descriptor */ 131 #define SPECTRAL_TSMASK 0xFFFFFFFF 132 #define SPECTRAL_SIGNATURE 0xdeadbeef 133 /* Signature to write onto spectral buffer and then later validate */ 134 #define MEM_POISON_SIGNATURE (htobe32(0xdeadbeef)) 135 136 /* START of spectral GEN II HW specific details */ 137 #define SPECTRAL_PHYERR_SIGNATURE_GEN2 0xbb 138 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2 0xF9 139 #define TLV_TAG_ADC_REPORT_GEN2 0xFA 140 #define TLV_TAG_SEARCH_FFT_REPORT_GEN2 0xFB 141 142 /** 143 * The Maximum number of detector information to be filled in the SAMP msg 144 * is 3, only for 165MHz case. For all other cases this value will be 1. 145 */ 146 #define MAX_NUM_DEST_DETECTOR_INFO (3) 147 #define MAX_DETECTORS_PER_PDEV (3) 148 #define FFT_BIN_SIZE_1BYTE (1) 149 150 #ifdef OPTIMIZED_SAMP_MESSAGE 151 /** 152 * enum spectral_160mhz_report_delivery_state - 160 MHz state machine states 153 * @SPECTRAL_REPORT_WAIT_PRIMARY80: Wait for primary80 report 154 * @SPECTRAL_REPORT_WAIT_SECONDARY80: Wait for secondory 80 report 155 */ 156 enum spectral_160mhz_report_delivery_state { 157 SPECTRAL_REPORT_WAIT_PRIMARY80, 158 SPECTRAL_REPORT_WAIT_SECONDARY80, 159 }; 160 #else 161 /** 162 * enum spectral_160mhz_report_delivery_state - 160 MHz state machine states 163 * @SPECTRAL_REPORT_WAIT_PRIMARY80: Wait for primary80 report 164 * @SPECTRAL_REPORT_RX_PRIMARY80: Receive primary 80 report 165 * @SPECTRAL_REPORT_WAIT_SECONDARY80: Wait for secondory 80 report 166 * @SPECTRAL_REPORT_RX_SECONDARY80: Receive secondary 80 report 167 */ 168 enum spectral_160mhz_report_delivery_state { 169 SPECTRAL_REPORT_WAIT_PRIMARY80, 170 SPECTRAL_REPORT_RX_PRIMARY80, 171 SPECTRAL_REPORT_WAIT_SECONDARY80, 172 SPECTRAL_REPORT_RX_SECONDARY80, 173 }; 174 #endif /* OPTIMIZED_SAMP_MESSAGE */ 175 176 /** 177 * enum spectral_freq_span_id - Spectral frequency span id 178 * @SPECTRAL_FREQ_SPAN_ID_0: Frequency span 0 179 * @SPECTRAL_FREQ_SPAN_ID_1: Frequency span 1 180 * @SPECTRAL_FREQ_SPAN_ID_2: Frequency span 2 181 */ 182 enum spectral_freq_span_id { 183 SPECTRAL_FREQ_SPAN_ID_0, 184 SPECTRAL_FREQ_SPAN_ID_1, 185 SPECTRAL_FREQ_SPAN_ID_2, 186 }; 187 188 /** 189 * enum spectral_detector_id - Spectral detector id 190 * @SPECTRAL_DETECTOR_ID_0: Spectral detector 0 191 * @SPECTRAL_DETECTOR_ID_1: Spectral detector 1 192 * @SPECTRAL_DETECTOR_ID_2: Spectral detector 2 193 * @SPECTRAL_DETECTOR_ID_MAX: Max Spectral detector ID 194 * @SPECTRAL_DETECTOR_ID_INVALID: Invalid Spectral detector ID 195 */ 196 enum spectral_detector_id { 197 SPECTRAL_DETECTOR_ID_0, 198 SPECTRAL_DETECTOR_ID_1, 199 SPECTRAL_DETECTOR_ID_2, 200 SPECTRAL_DETECTOR_ID_MAX, 201 SPECTRAL_DETECTOR_ID_INVALID = 0xff, 202 }; 203 204 /** 205 * struct spectral_search_fft_info_gen2 - spectral search fft report for gen2 206 * @relpwr_db: Total bin power in db 207 * @num_str_bins_ib: Number of strong bins 208 * @base_pwr: Base power 209 * @total_gain_info: Total gain 210 * @fft_chn_idx: FFT chain on which report is originated 211 * @avgpwr_db: Average power in db 212 * @peak_mag: Peak power seen in the bins 213 * @peak_inx: Index of bin holding peak power 214 */ 215 struct spectral_search_fft_info_gen2 { 216 uint32_t relpwr_db; 217 uint32_t num_str_bins_ib; 218 uint32_t base_pwr; 219 uint32_t total_gain_info; 220 uint32_t fft_chn_idx; 221 uint32_t avgpwr_db; 222 uint32_t peak_mag; 223 int16_t peak_inx; 224 }; 225 226 /* 227 * XXX Check if we should be handling the endinness difference in some 228 * other way opaque to the host 229 */ 230 #ifdef BIG_ENDIAN_HOST 231 232 /** 233 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for big endian host 234 * @signature: signature 235 * @tag: tag 236 * @length: length 237 */ 238 struct spectral_phyerr_tlv_gen2 { 239 uint8_t signature; 240 uint8_t tag; 241 uint16_t length; 242 } __ATTRIB_PACK; 243 244 #else 245 246 /** 247 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for little endian host 248 * @length: length 249 * @tag: tag 250 * @signature: signature 251 */ 252 struct spectral_phyerr_tlv_gen2 { 253 uint16_t length; 254 uint8_t tag; 255 uint8_t signature; 256 } __ATTRIB_PACK; 257 258 #endif /* BIG_ENDIAN_HOST */ 259 260 /** 261 * struct spectral_phyerr_hdr_gen2 - phyerr header for gen2 HW 262 * @hdr_a: Header[0:31] 263 * @hdr_b: Header[32:63] 264 */ 265 struct spectral_phyerr_hdr_gen2 { 266 uint32_t hdr_a; 267 uint32_t hdr_b; 268 }; 269 270 /* 271 * Segment ID information for 80+80. 272 * 273 * If the HW micro-architecture specification extends this DWORD for other 274 * purposes, then redefine+rename accordingly. For now, the specification 275 * mentions only segment ID (though this doesn't require an entire DWORD) 276 * without mention of any generic terminology for the DWORD, or any reservation. 277 * We use nomenclature accordingly. 278 */ 279 typedef uint32_t SPECTRAL_SEGID_INFO; 280 281 /** 282 * struct spectral_phyerr_fft_gen2 - fft info in phyerr event 283 * @buf: fft report 284 */ 285 struct spectral_phyerr_fft_gen2 { 286 uint8_t buf[0]; 287 }; 288 289 /** 290 * struct spectral_process_phyerr_info_gen2 - Processed phyerr info structures 291 * needed to fill SAMP params for gen2 292 * @p_rfqual: Pointer to RF quality info 293 * @p_sfft: Pointer to Search fft report info 294 * @pfft: Pointer to FFT info in Phyerr event 295 * @acs_stats: Pointer to ACS stats struct 296 * @tsf64: 64 bit TSF value 297 * @seg_d : Segment ID 298 */ 299 struct spectral_process_phyerr_info_gen2 { 300 struct target_if_spectral_rfqual_info *p_rfqual; 301 struct spectral_search_fft_info_gen2 *p_sfft; 302 struct spectral_phyerr_fft_gen2 *pfft; 303 struct target_if_spectral_acs_stats *acs_stats; 304 uint64_t tsf64; 305 uint8_t seg_id; 306 }; 307 308 /* END of spectral GEN II HW specific details */ 309 310 /* START of spectral GEN III HW specific details */ 311 312 #define get_bitfield(value, size, pos) \ 313 (((value) >> (pos)) & ((1 << (size)) - 1)) 314 #define unsigned_to_signed(value, width) \ 315 (((value) >= (1 << ((width) - 1))) ? \ 316 (value - (1 << (width))) : (value)) 317 318 #define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_POS_GEN3 (29) 319 #define SSCAN_SUMMARY_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3 (2) 320 #define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_POS_GEN3 (0) 321 #define SSCAN_SUMMARY_REPORT_HDR_A_AGC_TOTAL_GAIN_SIZE_GEN3 (8) 322 #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_POS_GEN3 (18) 323 #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3 (10) 324 #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3 (31) 325 #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3 (1) 326 #define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1 (30) 327 #define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1 (1) 328 #define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2 (16) 329 #define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2 (1) 330 #define SPECTRAL_REPORT_LTS_HDR_LENGTH_POS_GEN3 (0) 331 #define SPECTRAL_REPORT_LTS_HDR_LENGTH_SIZE_GEN3 (16) 332 #define SPECTRAL_REPORT_LTS_TAG_POS_GEN3 (16) 333 #define SPECTRAL_REPORT_LTS_TAG_SIZE_GEN3 (8) 334 #define SPECTRAL_REPORT_LTS_SIGNATURE_POS_GEN3 (24) 335 #define SPECTRAL_REPORT_LTS_SIGNATURE_SIZE_GEN3 (8) 336 #define FFT_REPORT_HDR_A_DETECTOR_ID_POS_GEN3 (0) 337 #define FFT_REPORT_HDR_A_DETECTOR_ID_SIZE_GEN3 (2) 338 #define FFT_REPORT_HDR_A_FFT_NUM_POS_GEN3 (2) 339 #define FFT_REPORT_HDR_A_FFT_NUM_SIZE_GEN3 (3) 340 #define FFT_REPORT_HDR_A_RADAR_CHECK_POS_GEN3_V1 (5) 341 #define FFT_REPORT_HDR_A_RADAR_CHECK_SIZE_GEN3_V1 (12) 342 #define FFT_REPORT_HDR_A_RADAR_CHECK_POS_GEN3_V2 (5) 343 #define FFT_REPORT_HDR_A_RADAR_CHECK_SIZE_GEN3_V2 (14) 344 #define FFT_REPORT_HDR_A_PEAK_INDEX_POS_GEN3_V1 (17) 345 #define FFT_REPORT_HDR_A_PEAK_INDEX_SIZE_GEN3_V1 (11) 346 #define FFT_REPORT_HDR_A_PEAK_INDEX_POS_GEN3_V2 (19) 347 #define FFT_REPORT_HDR_A_PEAK_INDEX_SIZE_GEN3_V2 (11) 348 #define FFT_REPORT_HDR_A_CHAIN_INDEX_POS_GEN3_V1 (28) 349 #define FFT_REPORT_HDR_A_CHAIN_INDEX_SIZE_GEN3_V1 (3) 350 #define FFT_REPORT_HDR_B_CHAIN_INDEX_POS_GEN3_V2 (0) 351 #define FFT_REPORT_HDR_B_CHAIN_INDEX_SIZE_GEN3_V2 (3) 352 #define FFT_REPORT_HDR_B_BASE_PWR_POS_GEN3_V1 (0) 353 #define FFT_REPORT_HDR_B_BASE_PWR_SIZE_GEN3_V1 (9) 354 #define FFT_REPORT_HDR_B_BASE_PWR_POS_GEN3_V2 (3) 355 #define FFT_REPORT_HDR_B_BASE_PWR_SIZE_GEN3_V2 (9) 356 #define FFT_REPORT_HDR_B_TOTAL_GAIN_POS_GEN3_V1 (9) 357 #define FFT_REPORT_HDR_B_TOTAL_GAIN_SIZE_GEN3_V1 (8) 358 #define FFT_REPORT_HDR_B_TOTAL_GAIN_POS_GEN3_V2 (12) 359 #define FFT_REPORT_HDR_B_TOTAL_GAIN_SIZE_GEN3_V2 (8) 360 #define FFT_REPORT_HDR_C_NUM_STRONG_BINS_POS_GEN3 (0) 361 #define FFT_REPORT_HDR_C_NUM_STRONG_BINS_SIZE_GEN3 (8) 362 #define FFT_REPORT_HDR_C_PEAK_MAGNITUDE_POS_GEN3 (8) 363 #define FFT_REPORT_HDR_C_PEAK_MAGNITUDE_SIZE_GEN3 (10) 364 #define FFT_REPORT_HDR_C_AVG_PWR_POS_GEN3 (18) 365 #define FFT_REPORT_HDR_C_AVG_PWR_SIZE_GEN3 (7) 366 #define FFT_REPORT_HDR_C_RELATIVE_PWR_POS_GEN3 (25) 367 #define FFT_REPORT_HDR_C_RELATIVE_PWR_SIZE_GEN3 (7) 368 369 #define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) 370 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) 371 #define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) 372 #define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) 373 374 #define NUM_SPECTRAL_DETECTORS_GEN3_V1 (3) 375 #define NUM_SPECTRAL_DETECTORS_GEN3_V2 (2) 376 #define FFT_REPORT_HEADER_LENGTH_GEN3_V2 (24) 377 #define FFT_REPORT_HEADER_LENGTH_GEN3_V1 (16) 378 #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1 (0) 379 #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2 (16) 380 381 #define SPECTRAL_PHYERR_HDR_LTS_POS \ 382 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_lts)) 383 #define SPECTRAL_FFT_BINS_POS \ 384 (offsetof(struct spectral_phyerr_fft_report_gen3, buf)) 385 386 /** 387 * struct phyerr_info - spectral search fft report for gen3 388 * @data: handle to phyerror buffer 389 * @datalen: length of phyerror buffer 390 * @p_rfqual: rf quality matrices 391 * @p_chaninfo: pointer to chaninfo 392 * @tsf64: 64 bit TSF 393 * @acs_stats: acs stats 394 */ 395 struct phyerr_info { 396 uint8_t *data; 397 uint32_t datalen; 398 struct target_if_spectral_rfqual_info *p_rfqual; 399 struct target_if_spectral_chan_info *p_chaninfo; 400 uint64_t tsf64; 401 struct target_if_spectral_acs_stats *acs_stats; 402 }; 403 404 /** 405 * struct spectral_search_fft_info_gen3 - spectral search fft report for gen3 406 * @timestamp: Timestamp at which fft report was generated 407 * @last_raw_timestamp: Previous FFT report's raw timestamp 408 * @adjusted_timestamp: Adjusted timestamp to account for target reset 409 * @fft_detector_id: Which radio generated this report 410 * @fft_num: The FFT count number. Set to 0 for short FFT. 411 * @fft_radar_check: NA for spectral 412 * @fft_peak_sidx: Index of bin with maximum power 413 * @fft_chn_idx: Rx chain index 414 * @fft_base_pwr_db: Base power in dB 415 * @fft_total_gain_db: Total gain in dB 416 * @fft_num_str_bins_ib: Number of strong bins in the report 417 * @fft_peak_mag: Peak magnitude 418 * @fft_avgpwr_db: Average power in dB 419 * @fft_relpwr_db: Relative power in dB 420 * @fft_bin_count: Number of FFT bins in the FFT report 421 * @fft_bin_size: Size of one FFT bin in bytes 422 * @bin_pwr_data: Contains FFT bins extracted from the report 423 */ 424 struct spectral_search_fft_info_gen3 { 425 uint32_t timestamp; 426 uint32_t last_raw_timestamp; 427 uint32_t adjusted_timestamp; 428 uint32_t fft_detector_id; 429 uint32_t fft_num; 430 uint32_t fft_radar_check; 431 int32_t fft_peak_sidx; 432 uint32_t fft_chn_idx; 433 uint32_t fft_base_pwr_db; 434 uint32_t fft_total_gain_db; 435 uint32_t fft_num_str_bins_ib; 436 int32_t fft_peak_mag; 437 uint32_t fft_avgpwr_db; 438 uint32_t fft_relpwr_db; 439 uint32_t fft_bin_count; 440 uint8_t fft_bin_size; 441 uint8_t *bin_pwr_data; 442 }; 443 444 /** 445 * struct spectral_phyerr_sfftreport_gen3 - fft info in phyerr event 446 * @fft_timestamp: Timestamp at which fft report was generated 447 * @fft_hdr_lts: length, tag, signature fields 448 * @hdr_a: Header[0:31] 449 * @hdr_b: Header[32:63] 450 * @hdr_c: Header[64:95] 451 * @resv: Header[96:127] 452 * @buf: fft bins 453 */ 454 struct spectral_phyerr_fft_report_gen3 { 455 uint32_t fft_timestamp; 456 uint32_t fft_hdr_lts; 457 uint32_t hdr_a; 458 uint32_t hdr_b; 459 uint32_t hdr_c; 460 uint32_t resv; 461 uint8_t buf[0]; 462 } __ATTRIB_PACK; 463 464 /** 465 * struct sscan_report_fields_gen3 - Fields of spectral report 466 * @sscan_agc_total_gain: The AGC total gain in DB. 467 * @inband_pwr_db: The in-band power of the signal in 1/2 DB steps 468 * @sscan_gainchange: This bit is set to 1 if a gainchange occurred during 469 * the spectral scan FFT. Software may choose to 470 * disregard the results. 471 * @sscan_pri80: This is set to 1 to indicate that the Spectral scan was 472 * performed on the pri80 segment. Software may choose to 473 * disregard the FFT sample if this is set to 1 but detector ID 474 * does not correspond to the ID for the pri80 segment. 475 * @sscan_detector_id: Detector ID in Spectral scan report 476 */ 477 struct sscan_report_fields_gen3 { 478 uint8_t sscan_agc_total_gain; 479 int16_t inband_pwr_db; 480 uint8_t sscan_gainchange; 481 uint8_t sscan_pri80; 482 uint8_t sscan_detector_id; 483 }; 484 485 /** 486 * struct spectral_sscan_summary_report_gen3 - Spectral summary report 487 * event 488 * @sscan_timestamp: Timestamp at which fft report was generated 489 * @sscan_hdr_lts: length, tag, signature fields 490 * @hdr_a: Header[0:31] 491 * @resv: Header[32:63] 492 * @hdr_b: Header[64:95] 493 * @hdr_c: Header[96:127] 494 */ 495 struct spectral_sscan_summary_report_gen3 { 496 u_int32_t sscan_timestamp; 497 u_int32_t sscan_hdr_lts; 498 u_int32_t hdr_a; 499 u_int32_t res1; 500 u_int32_t hdr_b; 501 u_int32_t hdr_c; 502 } __ATTRIB_PACK; 503 504 #ifdef DIRECT_BUF_RX_ENABLE 505 /** 506 * struct Spectral_report - spectral report 507 * @data: Report buffer 508 * @noisefloor: Noise floor values 509 * @reset_delay: Time taken for warm reset in us 510 * @cfreq1: center frequency 1 511 * @cfreq2: center frequency 2 512 * @ch_width: channel width 513 */ 514 struct spectral_report { 515 uint8_t *data; 516 int32_t noisefloor[DBR_MAX_CHAINS]; 517 uint32_t reset_delay; 518 uint32_t cfreq1; 519 uint32_t cfreq2; 520 uint32_t ch_width; 521 }; 522 #endif 523 /* END of spectral GEN III HW specific details */ 524 525 typedef signed char pwr_dbm; 526 527 /** 528 * enum spectral_gen - spectral hw generation 529 * @SPECTRAL_GEN1 : spectral hw gen 1 530 * @SPECTRAL_GEN2 : spectral hw gen 2 531 * @SPECTRAL_GEN3 : spectral hw gen 3 532 */ 533 enum spectral_gen { 534 SPECTRAL_GEN1, 535 SPECTRAL_GEN2, 536 SPECTRAL_GEN3, 537 }; 538 539 /** 540 * enum spectral_fftbin_size_war - spectral fft bin size war 541 * @SPECTRAL_FFTBIN_SIZE_NO_WAR : No WAR applicable for Spectral FFT bin size 542 * @SPECTRAL_FFTBIN_SIZE_2BYTE_TO_1BYTE : Spectral FFT bin size: Retain only 543 * least significant byte from 2 byte 544 * FFT bin transferred by HW 545 * @SPECTRAL_FFTBIN_SIZE_4BYTE_TO_1BYTE : Spectral FFT bin size: Retain only 546 * least significant byte from 4 byte 547 * FFT bin transferred by HW 548 */ 549 enum spectral_fftbin_size_war { 550 SPECTRAL_FFTBIN_SIZE_NO_WAR = 0, 551 SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE = 1, 552 SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE = 2, 553 }; 554 555 /** 556 * enum spectral_report_format_version - This represents the report format 557 * version number within each Spectral generation. 558 * @SPECTRAL_REPORT_FORMAT_VERSION_1 : version 1 559 * @SPECTRAL_REPORT_FORMAT_VERSION_2 : version 2 560 */ 561 enum spectral_report_format_version { 562 SPECTRAL_REPORT_FORMAT_VERSION_1, 563 SPECTRAL_REPORT_FORMAT_VERSION_2, 564 }; 565 566 /** 567 * struct spectral_fft_bin_len_adj_swar - Encapsulate information required for 568 * Spectral FFT bin length adjusting software WARS. 569 * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for 570 * in-band report format. This would be required on some chipsets under the 571 * following circumstances: In report mode 2 only the in-band bins are DMA'ed. 572 * Scatter/gather is used. However, the HW generates all bins, not just in-band, 573 * and reports the number of bins accordingly. The subsystem arranging for the 574 * DMA cannot change this value. On such chipsets the adjustment required at the 575 * host driver is to check if report format is 2, and if so halve the number of 576 * bins reported to get the number actually DMA'ed. 577 * @null_fftbin_adj: Whether to remove NULL FFT bins for report mode (1) in 578 * which only summary of metrics for each completed FFT + spectral scan summary 579 * report are to be provided. This would be required on some chipsets under the 580 * following circumstances: In report mode 1, HW reports a length corresponding 581 * to all bins, and provides bins with value 0. This is because the subsystem 582 * arranging for the FFT information does not arrange for DMA of FFT bin values 583 * (as expected), but cannot arrange for a smaller length to be reported by HW. 584 * In these circumstances, the driver would have to disregard the NULL bins and 585 * report a bin count of 0 to higher layers. 586 * @packmode_fftbin_size_adj: Pack mode in HW refers to packing of each Spectral 587 * FFT bin into 2 bytes. But due to a bug HW reports 2 times the expected length 588 * when packmode is enabled. This SWAR compensates this bug by dividing the 589 * length with 2. 590 * @fftbin_size_war: Type of FFT bin size SWAR 591 */ 592 struct spectral_fft_bin_len_adj_swar { 593 u_int8_t inband_fftbin_size_adj; 594 u_int8_t null_fftbin_adj; 595 uint8_t packmode_fftbin_size_adj; 596 enum spectral_fftbin_size_war fftbin_size_war; 597 }; 598 599 /** 600 * struct spectral_report_params - Parameters related to format of Spectral 601 * report. 602 * @version: This represents the report format version number within each 603 * Spectral generation. 604 * @ssumaary_padding_bytes: Number of bytes of padding after Spectral summary 605 * report 606 * @fft_report_hdr_len: Number of bytes in the header of the FFT report. This 607 * has to be subtracted from the length field of FFT report to find the length 608 * of FFT bins. 609 * @fragmentation_160: This indicates whether Spectral reports in 160/80p80 is 610 * fragmented. 611 * @detid_mode_table: Detector ID to Spectral scan mode table 612 * @num_spectral_detectors: Total number of Spectral detectors 613 * @marker: Describes the boundaries of pri80, 5 MHz and sec80 bins 614 * @hw_fft_bin_width: FFT bin width reported by the HW 615 */ 616 struct spectral_report_params { 617 enum spectral_report_format_version version; 618 uint8_t ssumaary_padding_bytes; 619 uint8_t fft_report_hdr_len; 620 bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX]; 621 enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX]; 622 uint8_t num_spectral_detectors; 623 struct spectral_fft_bin_markers_160_165mhz 624 marker[SPECTRAL_SCAN_MODE_MAX]; 625 uint8_t hw_fft_bin_width; 626 }; 627 628 /** 629 * struct spectral_param_min_max - Spectral parameter minimum and maximum values 630 * @fft_size_min: Minimum value of fft_size 631 * @fft_size_max: Maximum value of fft_size for each BW 632 */ 633 struct spectral_param_min_max { 634 uint16_t fft_size_min; 635 uint16_t fft_size_max[CH_WIDTH_MAX]; 636 }; 637 638 /** 639 * struct spectral_timestamp_swar - Spectral time stamp WAR related parameters 640 * @timestamp_war_offset: Offset to be added to correct timestamp 641 * @target_reset_count: Number of times target exercised the reset routine 642 * @last_fft_timestamp: last fft report timestamp 643 */ 644 struct spectral_timestamp_war { 645 uint32_t timestamp_war_offset[SPECTRAL_SCAN_MODE_MAX]; 646 uint64_t target_reset_count; 647 uint32_t last_fft_timestamp[SPECTRAL_SCAN_MODE_MAX]; 648 }; 649 650 #if ATH_PERF_PWR_OFFLOAD 651 /** 652 * enum target_if_spectral_info - Enumerations for specifying which spectral 653 * information (among parameters and states) 654 * is desired. 655 * @TARGET_IF_SPECTRAL_INFO_ACTIVE: Indicated whether spectral is active 656 * @TARGET_IF_SPECTRAL_INFO_ENABLED: Indicated whether spectral is enabled 657 * @TARGET_IF_SPECTRAL_INFO_PARAMS: Config params 658 */ 659 enum target_if_spectral_info { 660 TARGET_IF_SPECTRAL_INFO_ACTIVE, 661 TARGET_IF_SPECTRAL_INFO_ENABLED, 662 TARGET_IF_SPECTRAL_INFO_PARAMS, 663 }; 664 #endif /* ATH_PERF_PWR_OFFLOAD */ 665 666 /* forward declaration */ 667 struct target_if_spectral; 668 669 /** 670 * struct target_if_spectral_chan_info - Channel information 671 * @center_freq1: center frequency 1 in MHz 672 * @center_freq2: center frequency 2 in MHz -valid only for 673 * 11ACVHT 80PLUS80 mode 674 * @chan_width: channel width in MHz 675 */ 676 struct target_if_spectral_chan_info { 677 uint16_t center_freq1; 678 uint16_t center_freq2; 679 uint8_t chan_width; 680 }; 681 682 /** 683 * struct target_if_spectral_acs_stats - EACS stats from spectral samples 684 * @nfc_ctl_rssi: Control chan rssi 685 * @nfc_ext_rssi: Extension chan rssi 686 * @ctrl_nf: Control chan Noise Floor 687 * @ext_nf: Extension chan Noise Floor 688 */ 689 struct target_if_spectral_acs_stats { 690 int8_t nfc_ctl_rssi; 691 int8_t nfc_ext_rssi; 692 int8_t ctrl_nf; 693 int8_t ext_nf; 694 }; 695 696 /** 697 * struct target_if_spectral_perchain_rssi_info - per chain rssi info 698 * @rssi_pri20: Rssi of primary 20 Mhz 699 * @rssi_sec20: Rssi of secondary 20 Mhz 700 * @rssi_sec40: Rssi of secondary 40 Mhz 701 * @rssi_sec80: Rssi of secondary 80 Mhz 702 */ 703 struct target_if_spectral_perchain_rssi_info { 704 int8_t rssi_pri20; 705 int8_t rssi_sec20; 706 int8_t rssi_sec40; 707 int8_t rssi_sec80; 708 }; 709 710 /** 711 * struct target_if_spectral_rfqual_info - RF measurement information 712 * @rssi_comb: RSSI Information 713 * @pc_rssi_info: XXX : For now, we know we are getting information 714 * for only 4 chains at max. For future extensions 715 * use a define 716 * @noise_floor: Noise floor information 717 */ 718 struct target_if_spectral_rfqual_info { 719 int8_t rssi_comb; 720 struct target_if_spectral_perchain_rssi_info pc_rssi_info[4]; 721 int16_t noise_floor[4]; 722 }; 723 724 #define GET_TARGET_IF_SPECTRAL_OPS(spectral) \ 725 ((struct target_if_spectral_ops *)(&((spectral)->spectral_ops))) 726 727 /** 728 * struct target_if_spectral_ops - spectral low level ops table 729 * @get_tsf64: Get 64 bit TSF value 730 * @get_capability: Get capability info 731 * @set_rxfilter: Set rx filter 732 * @get_rxfilter: Get rx filter 733 * @is_spectral_active: Check whether icm is active 734 * @is_spectral_enabled: Check whether spectral is enabled 735 * @start_spectral_scan: Start spectral scan 736 * @stop_spectral_scan: Stop spectral scan 737 * @get_extension_channel: Get extension channel 738 * @get_ctl_noisefloor: Get control noise floor 739 * @get_ext_noisefloor: Get extension noise floor 740 * @configure_spectral: Set spectral configurations 741 * @get_spectral_config: Get spectral configurations 742 * @get_ent_spectral_mask: Get spectral mask 743 * @get_mac_address: Get mac address 744 * @get_current_channel: Get current channel 745 * @reset_hw: Reset HW 746 * @get_chain_noise_floor: Get Channel noise floor 747 * @spectral_process_phyerr: Process phyerr event 748 * @process_spectral_report: Process spectral report 749 * @byte_swap_headers: Apply byte-swap on report headers 750 * @byte_swap_fft_bins: Apply byte-swap on FFT bins 751 */ 752 struct target_if_spectral_ops { 753 uint64_t (*get_tsf64)(void *arg); 754 uint32_t (*get_capability)( 755 void *arg, enum spectral_capability_type type); 756 uint32_t (*set_rxfilter)(void *arg, int rxfilter); 757 uint32_t (*get_rxfilter)(void *arg); 758 uint32_t (*is_spectral_active)(void *arg, 759 enum spectral_scan_mode smode); 760 uint32_t (*is_spectral_enabled)(void *arg, 761 enum spectral_scan_mode smode); 762 uint32_t (*start_spectral_scan)(void *arg, 763 enum spectral_scan_mode smode, 764 enum spectral_cp_error_code *err); 765 uint32_t (*stop_spectral_scan)(void *arg, 766 enum spectral_scan_mode smode); 767 uint32_t (*get_extension_channel)(void *arg, 768 enum spectral_scan_mode smode); 769 int8_t (*get_ctl_noisefloor)(void *arg); 770 int8_t (*get_ext_noisefloor)(void *arg); 771 uint32_t (*configure_spectral)( 772 void *arg, 773 struct spectral_config *params, 774 enum spectral_scan_mode smode); 775 uint32_t (*get_spectral_config)( 776 void *arg, 777 struct spectral_config *params, 778 enum spectral_scan_mode smode); 779 uint32_t (*get_ent_spectral_mask)(void *arg); 780 uint32_t (*get_mac_address)(void *arg, char *addr); 781 uint32_t (*get_current_channel)(void *arg, 782 enum spectral_scan_mode smode); 783 uint32_t (*reset_hw)(void *arg); 784 uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf); 785 int (*spectral_process_phyerr)(struct target_if_spectral *spectral, 786 uint8_t *data, uint32_t datalen, 787 struct target_if_spectral_rfqual_info *p_rfqual, 788 struct target_if_spectral_chan_info *p_chaninfo, 789 uint64_t tsf64, 790 struct target_if_spectral_acs_stats *acs_stats); 791 int (*process_spectral_report)(struct wlan_objmgr_pdev *pdev, 792 void *payload); 793 QDF_STATUS (*byte_swap_headers)( 794 struct target_if_spectral *spectral, 795 void *data); 796 QDF_STATUS (*byte_swap_fft_bins)( 797 const struct spectral_report_params *rparams, 798 void *bin_pwr_data, size_t num_fftbins); 799 }; 800 801 /** 802 * struct target_if_spectral_stats - spectral stats info 803 * @num_spectral_detects: Total num. of spectral detects 804 * @total_phy_errors: Total number of phyerrors 805 * @owl_phy_errors: Indicated phyerrors in old gen1 chipsets 806 * @pri_phy_errors: Phyerrors in primary channel 807 * @ext_phy_errors: Phyerrors in secondary channel 808 * @dc_phy_errors: Phyerrors due to dc 809 * @early_ext_phy_errors: Early secondary channel phyerrors 810 * @bwinfo_errors: Bandwidth info errors 811 * @datalen_discards: Invalid data length errors, seen in gen1 chipsets 812 * @rssi_discards bw: Indicates reports dropped due to RSSI threshold 813 * @last_reset_tstamp: Last reset time stamp 814 */ 815 struct target_if_spectral_stats { 816 uint32_t num_spectral_detects; 817 uint32_t total_phy_errors; 818 uint32_t owl_phy_errors; 819 uint32_t pri_phy_errors; 820 uint32_t ext_phy_errors; 821 uint32_t dc_phy_errors; 822 uint32_t early_ext_phy_errors; 823 uint32_t bwinfo_errors; 824 uint32_t datalen_discards; 825 uint32_t rssi_discards; 826 uint64_t last_reset_tstamp; 827 }; 828 829 /** 830 * struct target_if_spectral_event - spectral event structure 831 * @se_ts: Original 15 bit recv timestamp 832 * @se_full_ts: 64-bit full timestamp from interrupt time 833 * @se_rssi: Rssi of spectral event 834 * @se_bwinfo: Rssi of spectral event 835 * @se_dur: Duration of spectral pulse 836 * @se_chanindex: Channel of event 837 * @se_list: List of spectral events 838 */ 839 struct target_if_spectral_event { 840 uint32_t se_ts; 841 uint64_t se_full_ts; 842 uint8_t se_rssi; 843 uint8_t se_bwinfo; 844 uint8_t se_dur; 845 uint8_t se_chanindex; 846 847 STAILQ_ENTRY(spectral_event) se_list; 848 }; 849 850 /** 851 * struct target_if_chain_noise_pwr_info - Noise power info for each channel 852 * @rptcount: Count of reports in pwr array 853 * @un_cal_nf: Uncalibrated noise floor 854 * @factory_cal_nf: Noise floor as calibrated at the factory for module 855 * @median_pwr: Median power (median of pwr array) 856 * @pwr: Power reports 857 */ 858 struct target_if_chain_noise_pwr_info { 859 int rptcount; 860 pwr_dbm un_cal_nf; 861 pwr_dbm factory_cal_nf; 862 pwr_dbm median_pwr; 863 pwr_dbm pwr[]; 864 } __ATTRIB_PACK; 865 866 /** 867 * struct target_if_spectral_chan_stats - Channel information 868 * @cycle_count: Cycle count 869 * @channel_load: Channel load 870 * @per: Period 871 * @noisefloor: Noise floor 872 * @comp_usablity: Computed usability 873 * @maxregpower: Maximum allowed regulatary power 874 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 875 * @maxregpower_sec80: Max regulatory power in secondary 80 Mhz 876 */ 877 struct target_if_spectral_chan_stats { 878 int cycle_count; 879 int channel_load; 880 int per; 881 int noisefloor; 882 uint16_t comp_usablity; 883 int8_t maxregpower; 884 uint16_t comp_usablity_sec80; 885 int8_t maxregpower_sec80; 886 }; 887 888 #if ATH_PERF_PWR_OFFLOAD 889 890 /** 891 * struct target_if_spectral_cache - Cache used to minimize WMI operations 892 * in offload architecture 893 * @osc_spectral_enabled: Whether Spectral is enabled 894 * @osc_spectral_active: Whether spectral is active 895 * XXX: Ideally, we should NOT cache this 896 * since the hardware can self clear the bit, 897 * the firmware can possibly stop spectral due to 898 * intermittent off-channel activity, etc 899 * A WMI read command should be introduced to handle 900 * this This will be discussed. 901 * @osc_params: Spectral parameters 902 * @osc_is_valid: Whether the cache is valid 903 */ 904 struct target_if_spectral_cache { 905 uint8_t osc_spectral_enabled; 906 uint8_t osc_spectral_active; 907 struct spectral_config osc_params; 908 uint8_t osc_is_valid; 909 }; 910 911 /** 912 * struct target_if_spectral_param_state_info - Structure used to represent and 913 * manage spectral information 914 * (parameters and states) 915 * @osps_lock: Lock to synchronize accesses to information 916 * @osps_cache: Cacheable' information 917 */ 918 struct target_if_spectral_param_state_info { 919 qdf_spinlock_t osps_lock; 920 struct target_if_spectral_cache osps_cache; 921 /* XXX - Non-cacheable information goes here, in the future */ 922 }; 923 #endif /* ATH_PERF_PWR_OFFLOAD */ 924 925 struct vdev_spectral_configure_params; 926 struct vdev_spectral_enable_params; 927 928 /** 929 * struct spectral_wmi_ops - structure used holding the operations 930 * related to Spectral WMI 931 * @wmi_spectral_configure_cmd_send: Configure Spectral parameters 932 * @wmi_spectral_enable_cmd_send: Enable/Disable Spectral 933 * @wmi_spectral_crash_inject: Inject FW crash 934 * @wmi_extract_pdev_sscan_fw_cmd_fixed_param: Extract Fixed params from 935 * start scan response event 936 * @wmi_extract_pdev_sscan_fft_bin_index: Extract TLV which describes FFT 937 * bin indices from start scan response event 938 * @wmi_unified_register_event_handler: Register WMI event handler 939 * @wmi_unified_unregister_event_handler: Unregister WMI event handler 940 * @wmi_service_enabled: API to check whether a given WMI service is enabled 941 * @extract_pdev_spectral_session_chan_info: Extract Spectral scan session 942 * channel information 943 * @extract_pdev_spectral_session_detector_info: Extract Spectral scan session 944 * detector information 945 * @extract_spectral_caps_fixed_param: Extract fixed parameters from Spectral 946 * capabilities event 947 * @extract_spectral_scan_bw_caps: Extract bandwidth capabilities from Spectral 948 * capabilities event 949 * @extract_spectral_fft_size_caps: Extract fft size capabilities from Spectral 950 * capabilities event 951 */ 952 struct spectral_wmi_ops { 953 QDF_STATUS (*wmi_spectral_configure_cmd_send)( 954 wmi_unified_t wmi_hdl, 955 struct vdev_spectral_configure_params *param); 956 QDF_STATUS (*wmi_spectral_enable_cmd_send)( 957 wmi_unified_t wmi_hdl, 958 struct vdev_spectral_enable_params *param); 959 QDF_STATUS (*wmi_spectral_crash_inject)( 960 wmi_unified_t wmi_handle, struct crash_inject *param); 961 QDF_STATUS (*wmi_extract_pdev_sscan_fw_cmd_fixed_param)( 962 wmi_unified_t wmi_handle, uint8_t *evt_buf, 963 struct spectral_startscan_resp_params *param); 964 QDF_STATUS (*wmi_extract_pdev_sscan_fft_bin_index)( 965 wmi_unified_t wmi_handle, uint8_t *evt_buf, 966 struct spectral_fft_bin_markers_160_165mhz *param); 967 QDF_STATUS (*wmi_unified_register_event_handler)( 968 wmi_unified_t wmi_handle, 969 wmi_conv_event_id event_id, 970 wmi_unified_event_handler handler_func, 971 uint8_t rx_ctx); 972 QDF_STATUS (*wmi_unified_unregister_event_handler)( 973 wmi_unified_t wmi_handle, 974 wmi_conv_event_id event_id); 975 bool (*wmi_service_enabled)(wmi_unified_t wmi_handle, 976 uint32_t service_id); 977 QDF_STATUS (*extract_pdev_spectral_session_chan_info)( 978 wmi_unified_t wmi_handle, void *event, 979 struct spectral_session_chan_info *chan_info); 980 QDF_STATUS (*extract_pdev_spectral_session_detector_info)( 981 wmi_unified_t wmi_handle, void *event, 982 struct spectral_session_det_info *det_info, 983 uint8_t det_info_idx); 984 QDF_STATUS (*extract_spectral_caps_fixed_param)( 985 wmi_unified_t wmi_handle, void *event, 986 struct spectral_capabilities_event_params *param); 987 QDF_STATUS (*extract_spectral_scan_bw_caps)( 988 wmi_unified_t wmi_handle, void *event, 989 struct spectral_scan_bw_capabilities *bw_caps); 990 QDF_STATUS (*extract_spectral_fft_size_caps)( 991 wmi_unified_t wmi_handle, void *event, 992 struct spectral_fft_size_capabilities *fft_size_caps); 993 }; 994 995 /** 996 * struct spectral_tgt_ops - structure used holding the operations 997 * related to target operations 998 * @tgt_get_psoc_from_scn_hdl: Function to get psoc from scn 999 */ 1000 struct spectral_tgt_ops { 1001 struct wlan_objmgr_psoc *(*tgt_get_psoc_from_scn_hdl)(void *scn_handle); 1002 }; 1003 1004 /** 1005 * struct spectral_param_properties - structure holding Spectral 1006 * parameter properties 1007 * @supported: Parameter is supported or not 1008 * @common_all_modes: Parameter should be common for all modes or not 1009 */ 1010 struct spectral_param_properties { 1011 bool supported; 1012 bool common_all_modes; 1013 }; 1014 1015 /** 1016 * struct target_if_finite_spectral_scan_params - Parameters related to finite 1017 * Spectral scan 1018 * @finite_spectral_scan: Indicates the Spectrl scan is finite/infinite 1019 * @num_reports_expected: Number of Spectral reports expected from target for a 1020 * finite Spectral scan 1021 */ 1022 struct target_if_finite_spectral_scan_params { 1023 bool finite_spectral_scan; 1024 uint32_t num_reports_expected; 1025 }; 1026 1027 /** 1028 * struct per_session_dest_det_info - Per-session Detector information to be 1029 * filled to samp_detector_info 1030 * @freq_span_id: Contiguous frequency span ID within the SAMP message 1031 * @is_sec80: Indicates pri80/sec80 segment for 160/80p80 BW 1032 * @det_id: Detector ID within samp_freq_span_info corresponding to 1033 * freq_span_id 1034 * @dest_start_bin_idx: Start index of FFT bins within SAMP msg's bin_pwr array 1035 * @dest_end_bin_idx: End index of FFT bins within SAMP msg's bin_pwr array 1036 * @lb_extrabins_start_idx: Left band edge extra bins start index 1037 * @lb_extrabins_num: Number of left band edge extra bins 1038 * @rb_extrabins_start_idx: Right band edge extra bins start index 1039 * @rb_extrabins_num: Number of right band edge extra bins 1040 * @start_freq: Indicates start frequency per-detector (in MHz) 1041 * @end_freq: Indicates last frequency per-detector (in MHz) 1042 * @src_start_bin_idx: Start index within the Spectral report's bin_pwr array, 1043 * where the FFT bins corresponding to this dest_det_id start 1044 */ 1045 struct per_session_dest_det_info { 1046 uint8_t freq_span_id; 1047 bool is_sec80; 1048 uint8_t det_id; 1049 uint16_t dest_start_bin_idx; 1050 uint16_t dest_end_bin_idx; 1051 uint16_t lb_extrabins_start_idx; 1052 uint16_t lb_extrabins_num; 1053 uint16_t rb_extrabins_start_idx; 1054 uint16_t rb_extrabins_num; 1055 uint32_t start_freq; 1056 uint32_t end_freq; 1057 uint16_t src_start_bin_idx; 1058 }; 1059 1060 /** 1061 * struct per_session_det_map - A map of per-session detector information, 1062 * keyed by the detector id obtained from the Spectral FFT report, mapping to 1063 * destination detector info in SAMP message. 1064 * @dest_det_info: Struct containing per-session detector information 1065 * @num_dest_det_info: Number of destination detectors to which information 1066 * of this detector is to be filled 1067 * @spectral_msg_buf_type: Spectral message buffer type 1068 * @send_to_upper_layers: Indicates whether to send SAMP msg to upper layers 1069 * @det_map_valid: Indicates whether detector map is valid or not 1070 */ 1071 struct per_session_det_map { 1072 struct per_session_dest_det_info 1073 dest_det_info[MAX_NUM_DEST_DETECTOR_INFO]; 1074 uint8_t num_dest_det_info; 1075 enum spectral_msg_buf_type buf_type; 1076 bool send_to_upper_layers; 1077 bool det_map_valid[SPECTRAL_SCAN_MODE_MAX]; 1078 }; 1079 1080 /** 1081 * struct per_session_report_info - Consists of per-session Spectral report 1082 * information to be filled at report level in SAMP message. 1083 * @pri20_freq: Primary 20MHz operating frequency in MHz 1084 * @cfreq1: Centre frequency of the frequency span for 20/40/80 MHz BW. 1085 * Segment 1 centre frequency in MHz for 80p80/160 BW. 1086 * @cfreq2: For 80p80, indicates segment 2 centre frequency in MHz. For 160MHz, 1087 * indicates the center frequency of 160MHz span. 1088 * @operating_bw: Device's operating bandwidth.Valid values = enum phy_ch_width 1089 * @sscan_cfreq1: Normal/Agile scan Centre frequency of the frequency span for 1090 * 20/40/80 MHz BW. Center frequency of Primary Segment in MHz for 80p80/160 BW 1091 * Based on Spectral scan mode. 1092 * @sscan_cfreq2: For 80p80, Normal/Agile scan Center frequency for Sec80 1093 * segment. For 160MHz, indicates the center frequency of 160MHz span. Based on 1094 * spectral scan mode 1095 * @sscan_bw: Normal/Agile Scan BW based on Spectral scan mode. 1096 * Valid values = enum phy_ch_width 1097 * @num_spans: Number of frequency spans 1098 * @valid: Indicated whether report info is valid 1099 */ 1100 struct per_session_report_info { 1101 uint32_t pri20_freq; 1102 uint32_t cfreq1; 1103 uint32_t cfreq2; 1104 enum phy_ch_width operating_bw; 1105 uint32_t sscan_cfreq1; 1106 uint32_t sscan_cfreq2; 1107 enum phy_ch_width sscan_bw; 1108 uint8_t num_spans; 1109 bool valid; 1110 }; 1111 1112 /** 1113 * struct sscan_detector_list - Spectral scan Detector list, for given Spectral 1114 * scan mode and operating BW 1115 * @detectors: List of detectors 1116 * @num_detectors: Number of detectors for given spectral scan mode, BW 1117 * and target type 1118 */ 1119 struct sscan_detector_list { 1120 uint8_t detectors[SPECTRAL_DETECTOR_ID_MAX]; 1121 uint8_t num_detectors; 1122 }; 1123 1124 /** 1125 * struct spectral_supported_bws - Supported sscan bandwidths 1126 * @bandwidths: bitmap of supported sscan bandwidths. Make sure to maintain this 1127 * bitmap in the increasing order of bandwidths. 1128 */ 1129 struct spectral_supported_bws { 1130 union { 1131 struct { 1132 uint32_t supports_sscan_bw_5:1, 1133 supports_sscan_bw_10:1, 1134 supports_sscan_bw_20:1, 1135 supports_sscan_bw_40:1, 1136 supports_sscan_bw_80:1, 1137 supports_sscan_bw_160:1, 1138 supports_sscan_bw_80_80:1, 1139 supports_sscan_bw_320:1, 1140 reserved:24; 1141 }; 1142 uint32_t bandwidths; 1143 }; 1144 }; 1145 1146 /** 1147 * get_supported_sscan_bw_pos() - Get the position of a given sscan_bw inside 1148 * the supported sscan bandwidths bitmap 1149 * @sscan_bw: Spectral scan bandwidth 1150 * 1151 * Return: bit position for a valid sscan bandwidth, else -1 1152 */ 1153 int get_supported_sscan_bw_pos(enum phy_ch_width sscan_bw); 1154 1155 /** 1156 * struct target_if_spectral - main spectral structure 1157 * @pdev: Pointer to pdev 1158 * @spectral_ops: Target if internal Spectral low level operations table 1159 * @capability: Spectral capabilities structure 1160 * @properties: Spectral parameter properties per mode 1161 * @spectral_lock: Lock used for internal Spectral operations 1162 * @vdev_id: VDEV id for all spectral modes 1163 * @spectral_curchan_radindex: Current channel spectral index 1164 * @spectral_extchan_radindex: Extension channel spectral index 1165 * @spectraldomain: Current Spectral domain 1166 * @spectral_proc_phyerr: Flags to process for PHY errors 1167 * @spectral_defaultparams: Default PHY params per Spectral stat 1168 * @spectral_stats: Spectral related stats 1169 * @events: Events structure 1170 * @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel? 1171 * @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI? 1172 * @sc_spectral_20_40_mode: Is AP in 20-40 mode? 1173 * @sc_spectral_noise_pwr_cal: Noise power cal required? 1174 * @sc_spectral_non_edma: Is the spectral capable device Non-EDMA? 1175 * @upper_is_control: Upper segment is primary 1176 * @upper_is_extension: Upper segment is secondary 1177 * @lower_is_control: Lower segment is primary 1178 * @lower_is_extension: Lower segment is secondary 1179 * @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral 1180 * mute test 1181 * @spectral_numbins: Number of bins 1182 * @spectral_fft_len: FFT length 1183 * @spectral_data_len: Total phyerror report length 1184 * @lb_edge_extrabins: Number of extra bins on left band edge 1185 * @rb_edge_extrabins: Number of extra bins on right band edge 1186 * @spectral_max_index_offset: Max FFT index offset (20 MHz mode) 1187 * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode) 1188 * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode) 1189 * @spectral_dc_index: At which index DC is present 1190 * @send_single_packet: Deprecated 1191 * @spectral_sent_msg: Indicates whether we send report to upper layers 1192 * @params: Spectral parameters 1193 * @last_capture_time: Indicates timestamp of previous report 1194 * @num_spectral_data: Number of Spectral samples received in current session 1195 * @total_spectral_data: Total number of Spectral samples received 1196 * @max_rssi: Maximum RSSI 1197 * @detects_control_channel: NA 1198 * @detects_extension_channel: NA 1199 * @detects_below_dc: NA 1200 * @detects_above_dc: NA 1201 * @sc_scanning: Indicates active wifi scan 1202 * @sc_spectral_scan: Indicates active specral scan 1203 * @sc_spectral_full_scan: Deprecated 1204 * @scan_start_tstamp: Deprecated 1205 * @last_tstamp: Deprecated 1206 * @first_tstamp: Deprecated 1207 * @spectral_samp_count: Deprecated 1208 * @sc_spectral_samp_count: Deprecated 1209 * @noise_pwr_reports_reqd: Number of noise power reports required 1210 * @noise_pwr_reports_recv: Number of noise power reports received 1211 * @noise_pwr_reports_lock: Lock used for Noise power report processing 1212 * @noise_pwr_chain_ctl: Noise power report - control channel 1213 * @noise_pwr_chain_ext: Noise power report - extension channel 1214 * @chaninfo: Channel statistics 1215 * @tsf64: Latest TSF Value 1216 * @param_info: Offload architecture Spectral parameter cache information 1217 * @ch_width: Indicates Channel Width 20/40/80/160 MHz for each Spectral mode 1218 * @sscan_width_configured: Whether user has configured sscan bandwidth 1219 * @diag_stats: Diagnostic statistics 1220 * @is_160_format: Indicates whether information provided by HW is in altered 1221 * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) 1222 * @is_lb_edge_extrabins_format: Indicates whether information provided by 1223 * HW has 4 extra bins, at left band edge, for report mode 2 1224 * @is_rb_edge_extrabins_format: Indicates whether information provided 1225 * by HW has 4 extra bins, at right band edge, for report mode 2 1226 * @is_sec80_rssi_war_required: Indicates whether the software workaround is 1227 * required to obtain approximate combined RSSI for secondary 80Mhz segment 1228 * @simctx: Spectral Simulation context 1229 * @spectral_gen: Spectral hardware generation 1230 * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware 1231 * generation 1232 * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV 1233 * header, for the given hardware generation 1234 * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV 1235 * header, for the given hardware generation 1236 * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware 1237 * generation 1238 * @nl_cb: Netlink callbacks 1239 * @use_nl_bcast: Whether to use Netlink broadcast/unicast 1240 * @send_phy_data: Send data to the application layer for a particular msg type 1241 * @len_adj_swar: Spectral fft bin length adjustment SWAR related info 1242 * @timestamp_war: Spectral time stamp WAR related info 1243 * @dbr_ring_debug: Whether Spectral DBR ring debug is enabled 1244 * @dbr_buff_debug: Whether Spectral DBR buffer debug is enabled 1245 * @direct_dma_support: Whether Direct-DMA is supported on the current radio 1246 * @prev_tstamp: Timestamp of the previously received sample, which has to be 1247 * compared with the current tstamp to check descrepancy 1248 * @rparams: Parameters related to Spectral report structure 1249 * @param_min_max: Spectral parameter's minimum and maximum values 1250 * @finite_scan: Parameters for finite Spectral scan 1251 * @detector_list: Detector list for a given Spectral scan mode and channel 1252 * width, based on the target type. 1253 * @detector_list_lock: Lock to synchronize accesses to detector list 1254 * @det_map: Map of per-session detector information keyed by the Spectral HW 1255 * detector id. 1256 * @session_det_map_lock: Lock to synchronize accesses to session detector map 1257 * @report_info: Per session info to be filled at report level in SAMP message 1258 * @session_report_info_lock: Lock to synchronize access to session report info 1259 * @supported_bws: Supported sscan bandwidths for all sscan modes and 1260 * operating widths 1261 * @supported_sscan_bw_list: List of supported sscan widths for all sscan modes 1262 * @data_stats: stats in Spectral data path 1263 */ 1264 struct target_if_spectral { 1265 struct wlan_objmgr_pdev *pdev_obj; 1266 struct target_if_spectral_ops spectral_ops; 1267 struct spectral_caps capability; 1268 struct spectral_param_properties 1269 properties[SPECTRAL_SCAN_MODE_MAX][SPECTRAL_PARAM_MAX]; 1270 qdf_spinlock_t spectral_lock; 1271 uint8_t vdev_id[SPECTRAL_SCAN_MODE_MAX]; 1272 int16_t spectral_curchan_radindex; 1273 int16_t spectral_extchan_radindex; 1274 uint32_t spectraldomain; 1275 uint32_t spectral_proc_phyerr; 1276 struct spectral_config spectral_defaultparams; 1277 struct target_if_spectral_stats spectral_stats; 1278 struct target_if_spectral_event *events; 1279 unsigned int sc_spectral_ext_chan_ok:1, 1280 sc_spectral_combined_rssi_ok:1, 1281 sc_spectral_20_40_mode:1, 1282 sc_spectral_noise_pwr_cal:1, 1283 sc_spectral_non_edma:1; 1284 int upper_is_control; 1285 int upper_is_extension; 1286 int lower_is_control; 1287 int lower_is_extension; 1288 uint8_t sc_spectraltest_ieeechan; 1289 int spectral_numbins; 1290 int spectral_fft_len; 1291 int spectral_data_len; 1292 1293 /* 1294 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are 1295 * delivered. However, there can be additional bins reported for 1296 * AR900B version 2.0 and QCA9984 as described next: 1297 * 1298 * AR900B version 2.0: An additional tone is processed on the right 1299 * hand side in order to facilitate detection of radar pulses out to 1300 * the extreme band-edge of the channel frequency. Since the HW design 1301 * processes four tones at a time, this requires one additional Dword 1302 * to be added to the search FFT report. 1303 * 1304 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary + 1305 * 1x-oversampled bins (in-band) per FFT, then 8 more bins 1306 * (4 more on left side and 4 more on right side)are added. 1307 */ 1308 1309 int lb_edge_extrabins; 1310 int rb_edge_extrabins; 1311 int spectral_max_index_offset; 1312 int spectral_upper_max_index_offset; 1313 int spectral_lower_max_index_offset; 1314 int spectral_dc_index; 1315 int send_single_packet; 1316 int spectral_sent_msg; 1317 int classify_scan; 1318 qdf_timer_t classify_timer; 1319 struct spectral_config params[SPECTRAL_SCAN_MODE_MAX]; 1320 bool params_valid[SPECTRAL_SCAN_MODE_MAX]; 1321 struct spectral_classifier_params classifier_params; 1322 int last_capture_time; 1323 int num_spectral_data; 1324 int total_spectral_data; 1325 int max_rssi; 1326 int detects_control_channel; 1327 int detects_extension_channel; 1328 int detects_below_dc; 1329 int detects_above_dc; 1330 int sc_scanning; 1331 int sc_spectral_scan; 1332 int sc_spectral_full_scan; 1333 uint64_t scan_start_tstamp; 1334 uint32_t last_tstamp; 1335 uint32_t first_tstamp; 1336 uint32_t spectral_samp_count; 1337 uint32_t sc_spectral_samp_count; 1338 int noise_pwr_reports_reqd; 1339 int noise_pwr_reports_recv; 1340 qdf_spinlock_t noise_pwr_reports_lock; 1341 struct target_if_chain_noise_pwr_info 1342 *noise_pwr_chain_ctl[HOST_MAX_ANTENNA]; 1343 struct target_if_chain_noise_pwr_info 1344 *noise_pwr_chain_ext[HOST_MAX_ANTENNA]; 1345 uint64_t tsf64; 1346 #if ATH_PERF_PWR_OFFLOAD 1347 struct target_if_spectral_param_state_info 1348 param_info[SPECTRAL_SCAN_MODE_MAX]; 1349 #endif 1350 enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX]; 1351 bool sscan_width_configured[SPECTRAL_SCAN_MODE_MAX]; 1352 struct spectral_diag_stats diag_stats; 1353 bool is_160_format; 1354 bool is_lb_edge_extrabins_format; 1355 bool is_rb_edge_extrabins_format; 1356 bool is_sec80_rssi_war_required; 1357 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 1358 void *simctx; 1359 #endif 1360 enum spectral_gen spectral_gen; 1361 uint8_t hdr_sig_exp; 1362 uint8_t tag_sscan_summary_exp; 1363 uint8_t tag_sscan_fft_exp; 1364 uint8_t tlvhdr_size; 1365 struct spectral_nl_cb nl_cb; 1366 bool use_nl_bcast; 1367 int (*send_phy_data)(struct wlan_objmgr_pdev *pdev, 1368 enum spectral_msg_type smsg_type); 1369 struct spectral_fft_bin_len_adj_swar len_adj_swar; 1370 struct spectral_timestamp_war timestamp_war; 1371 enum spectral_160mhz_report_delivery_state 1372 state_160mhz_delivery[SPECTRAL_SCAN_MODE_MAX]; 1373 bool dbr_ring_debug; 1374 bool dbr_buff_debug; 1375 bool direct_dma_support; 1376 #ifdef OPTIMIZED_SAMP_MESSAGE 1377 uint32_t prev_tstamp[MAX_DETECTORS_PER_PDEV]; 1378 #else 1379 uint32_t prev_tstamp; 1380 #endif 1381 struct spectral_report_params rparams; 1382 struct spectral_param_min_max param_min_max; 1383 struct target_if_finite_spectral_scan_params 1384 finite_scan[SPECTRAL_SCAN_MODE_MAX]; 1385 struct sscan_detector_list 1386 detector_list[SPECTRAL_SCAN_MODE_MAX][CH_WIDTH_MAX]; 1387 qdf_spinlock_t detector_list_lock; 1388 struct per_session_det_map det_map[MAX_DETECTORS_PER_PDEV]; 1389 qdf_spinlock_t session_det_map_lock; 1390 struct per_session_report_info report_info[SPECTRAL_SCAN_MODE_MAX]; 1391 qdf_spinlock_t session_report_info_lock; 1392 struct spectral_supported_bws 1393 supported_bws[SPECTRAL_SCAN_MODE_MAX][CH_WIDTH_MAX]; 1394 /* Whether a given sscan BW is supported on a given smode */ 1395 bool supported_sscan_bw_list[SPECTRAL_SCAN_MODE_MAX][CH_WIDTH_MAX]; 1396 struct spectral_data_stats data_stats; 1397 }; 1398 1399 /** 1400 * struct target_if_psoc_spectral - Target if psoc Spectral object 1401 * @psoc_obj: psoc object 1402 * @wmi_ops: Spectral WMI operations 1403 */ 1404 struct target_if_psoc_spectral { 1405 struct wlan_objmgr_psoc *psoc_obj; 1406 struct spectral_wmi_ops wmi_ops; 1407 }; 1408 1409 #ifdef OPTIMIZED_SAMP_MESSAGE 1410 /** 1411 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 1412 * data format 1413 * @hw_detector_id: Spectral HW detector ID 1414 * @rssi: Spectral RSSI 1415 * @lower_rssi: RSSI of lower band 1416 * @upper_rssi: RSSI of upper band 1417 * @chain_ctl_rssi: RSSI for control channel, for all antennas 1418 * @chain_ext_rssi: RSSI for extension channel, for all antennas 1419 * @last_raw_timestamp: Previous FFT report's raw timestamp. 1420 * @raw_timestamp: FFT timestamp reported by HW on primary segment. 1421 * @timestamp: timestamp 1422 * @reset_delay: Time gap between the last spectral report before reset and the 1423 * end of reset. 1424 * @max_mag: maximum magnitude 1425 * @max_index: index of max magnitude 1426 * @noise_floor: current noise floor 1427 * @pri80ind: Indication from hardware that the sample was received on the 1428 * primary 80 MHz segment. If this is set when smode = 1429 * SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried 1430 * out on pri80 instead of the Agile frequency due to a channel 1431 * switch - Software may choose to ignore the sample in this case. 1432 * @bin_pwr_data: Contains FFT magnitudes 1433 */ 1434 struct target_if_samp_msg_params { 1435 uint8_t hw_detector_id; 1436 int8_t rssi; 1437 int8_t lower_rssi; 1438 int8_t upper_rssi; 1439 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 1440 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 1441 uint32_t last_raw_timestamp; 1442 uint32_t raw_timestamp; 1443 uint32_t timestamp; 1444 uint32_t reset_delay; 1445 uint16_t max_mag; 1446 uint16_t max_index; 1447 int16_t noise_floor; 1448 uint8_t agc_total_gain; 1449 uint8_t gainchange; 1450 uint8_t pri80ind; 1451 uint8_t *bin_pwr_data; 1452 }; 1453 1454 #else 1455 /** 1456 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 1457 * data format 1458 * @rssi: RSSI (except for secondary 80 segment) 1459 * @rssi_sec80: RSSI for secondary 80 segment 1460 * @lower_rssi: RSSI of lower band 1461 * @upper_rssi: RSSI of upper band 1462 * @chain_ctl_rssi: RSSI for control channel, for all antennas 1463 * @chain_ext_rssi: RSSI for extension channel, for all antennas 1464 * @bwinfo: bandwidth info 1465 * @data_len: length of FFT data (except for secondary 80 segment) 1466 * @data_len_sec80: length of FFT data for secondary 80 segment 1467 * @tstamp: timestamp 1468 * @last_tstamp: last time stamp 1469 * @max_mag: maximum magnitude (except for secondary 80 segment) 1470 * @max_mag_sec80: maximum magnitude for secondary 80 segment 1471 * @max_index: index of max magnitude (except for secondary 80 segment) 1472 * @max_index_sec80: index of max magnitude for secondary 80 segment 1473 * @max_exp: max exp 1474 * @peak: peak frequency (obsolete) 1475 * @pwr_count: number of FFT bins (except for secondary 80 segment) 1476 * @pwr_count_5mhz: number of FFT bins in extra 5 MHz in 1477 * 165 MHz/restricted 80p80 mode 1478 * @pwr_count_sec80: number of FFT bins in secondary 80 segment 1479 * @nb_lower: This is deprecated 1480 * @nb_upper: This is deprecated 1481 * @max_upper_index: index of max mag in upper band 1482 * @max_lower_index: index of max mag in lower band 1483 * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment) 1484 * @bin_pwr_data_5mhz: Contains FFT magnitudes for the extra 5 MHz 1485 * in 165 MHz/restricted 80p80 mode 1486 * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment 1487 * @freq: Center frequency of primary 20MHz channel in MHz 1488 * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz 1489 * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz 1490 * @agile_freq1: Center frequency in MHz of the entire span(for 80+80 MHz 1491 * agile Scan it is primary 80 MHz span) across which 1492 * Agile Spectral is carried out. Applicable only for Agile 1493 * Spectral samples. 1494 * @agile_freq2: Center frequency in MHz of the secondary 80 MHz span 1495 * across which Agile Spectral is carried out. Applicable 1496 * only for Agile Spectral samples in 80+80 MHz mode. 1497 * @freq_loading: spectral control duty cycles 1498 * @noise_floor: current noise floor (except for secondary 80 segment) 1499 * @noise_floor_sec80: current noise floor for secondary 80 segment 1500 * @interf_list: List of interference sources 1501 * @classifier_params: classifier parameters 1502 * @sc: classifier parameters 1503 * @pri80ind: Indication from hardware that the sample was received on the 1504 * primary 80 MHz segment. If this is set when smode = 1505 * SPECTRAL_SCAN_MODE_AGILE, it indicates that Spectral was carried out on 1506 * pri80 instead of the Agile frequency due to a channel switch - Software may 1507 * choose to ignore the sample in this case. 1508 * @pri80ind_sec80: Indication from hardware that the sample was received on the 1509 * primary 80 MHz segment instead of the secondary 80 MHz segment due to a 1510 * channel switch - Software may choose to ignore the sample if this is set. 1511 * Applicable only if smode = SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz 1512 * Spectral operation and if the chipset supports fragmented 160/80+80 MHz 1513 * operation. 1514 * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of 160MHz 1515 * it will be primary 80 segment's timestamp as both primary & secondary 1516 * segment's timestamps are expected to be almost equal 1517 * @timestamp_war_offset: Offset calculated based on reset_delay and 1518 * last_raw_stamp. It will be added to raw_timestamp to get tstamp. 1519 * @raw_timestamp: FFT timestamp reported by HW on primary segment. 1520 * @raw_timestamp_sec80: FFT timestamp reported by HW on secondary 80 segment. 1521 * @reset_delay: Time gap between the last spectral report before reset and the 1522 * end of reset. 1523 * @target_reset_count: Indicates the the number of times the target went 1524 * through reset routine after spectral was enabled. 1525 */ 1526 struct target_if_samp_msg_params { 1527 int8_t rssi; 1528 int8_t rssi_sec80; 1529 int8_t lower_rssi; 1530 int8_t upper_rssi; 1531 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 1532 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 1533 uint16_t bwinfo; 1534 uint16_t datalen; 1535 uint16_t datalen_sec80; 1536 uint32_t tstamp; 1537 uint32_t last_tstamp; 1538 uint16_t max_mag; 1539 uint16_t max_mag_sec80; 1540 uint16_t max_index; 1541 uint16_t max_index_sec80; 1542 uint8_t max_exp; 1543 int peak; 1544 int pwr_count; 1545 int pwr_count_5mhz; 1546 int pwr_count_sec80; 1547 int8_t nb_lower; 1548 int8_t nb_upper; 1549 uint16_t max_lower_index; 1550 uint16_t max_upper_index; 1551 uint8_t *bin_pwr_data; 1552 uint8_t *bin_pwr_data_5mhz; 1553 uint8_t *bin_pwr_data_sec80; 1554 uint16_t freq; 1555 uint16_t vhtop_ch_freq_seg1; 1556 uint16_t vhtop_ch_freq_seg2; 1557 uint16_t agile_freq1; 1558 uint16_t agile_freq2; 1559 uint16_t freq_loading; 1560 int16_t noise_floor; 1561 int16_t noise_floor_sec80; 1562 struct interf_src_rsp interf_list; 1563 struct spectral_classifier_params classifier_params; 1564 struct ath_softc *sc; 1565 uint8_t agc_total_gain; 1566 uint8_t agc_total_gain_sec80; 1567 uint8_t gainchange; 1568 uint8_t gainchange_sec80; 1569 enum spectral_scan_mode smode; 1570 uint8_t pri80ind; 1571 uint8_t pri80ind_sec80; 1572 uint32_t last_raw_timestamp; 1573 uint32_t timestamp_war_offset; 1574 uint32_t raw_timestamp; 1575 uint32_t raw_timestamp_sec80; 1576 uint32_t reset_delay; 1577 uint32_t target_reset_count; 1578 }; 1579 #endif 1580 1581 /** 1582 * struct target_if_spectral_agile_mode_cap - Structure to hold agile 1583 * Spetcral scan capability 1584 * @agile_spectral_cap: agile Spectral scan capability for 20/40/80 MHz 1585 * @agile_spectral_cap_160: agile Spectral scan capability for 160 MHz 1586 * @agile_spectral_cap_80p80: agile Spectral scan capability for 80+80 MHz 1587 * @agile_spectral_cap_320: agile Spectral scan capability for 320 MHz 1588 */ 1589 struct target_if_spectral_agile_mode_cap { 1590 bool agile_spectral_cap; 1591 bool agile_spectral_cap_160; 1592 bool agile_spectral_cap_80p80; 1593 bool agile_spectral_cap_320; 1594 }; 1595 1596 #ifdef WLAN_CONV_SPECTRAL_ENABLE 1597 /** 1598 * target_if_spectral_dump_fft() - Dump Spectral FFT 1599 * @pfft: Pointer to Spectral Phyerr FFT 1600 * @fftlen: FFT length 1601 * 1602 * Return: Success or failure 1603 */ 1604 int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen); 1605 1606 /** 1607 * target_if_dbg_print_samp_param() - Print contents of SAMP struct 1608 * @p: Pointer to SAMP message 1609 * 1610 * Return: Void 1611 */ 1612 void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p); 1613 1614 /** 1615 * target_if_get_offset_swar_sec80() - Get offset for SWAR according to 1616 * the channel width 1617 * @channel_width: Channel width 1618 * 1619 * Return: Offset for SWAR 1620 */ 1621 uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width); 1622 1623 /** 1624 * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops 1625 * @tx_ops: Tx Ops 1626 * 1627 * Return: void 1628 */ 1629 void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); 1630 1631 #ifndef OPTIMIZED_SAMP_MESSAGE 1632 /** 1633 * target_if_spectral_create_samp_msg() - Create the spectral samp message 1634 * @spectral : Pointer to spectral internal structure 1635 * @params : spectral samp message parameters 1636 * 1637 * API to create the spectral samp message 1638 * 1639 * Return: void 1640 */ 1641 void target_if_spectral_create_samp_msg( 1642 struct target_if_spectral *spectral, 1643 struct target_if_samp_msg_params *params); 1644 #endif 1645 1646 #ifdef OPTIMIZED_SAMP_MESSAGE 1647 /** 1648 * target_if_spectral_fill_samp_msg() - Fill the Spectral SAMP message 1649 * @spectral : Pointer to spectral internal structure 1650 * @params: Spectral SAMP message fields 1651 * 1652 * Fill the spectral SAMP message fields using params and detector map. 1653 * 1654 * Return: Success/Failure 1655 */ 1656 QDF_STATUS target_if_spectral_fill_samp_msg( 1657 struct target_if_spectral *spectral, 1658 struct target_if_samp_msg_params *params); 1659 #endif 1660 1661 /** 1662 * target_if_spectral_process_phyerr_gen3() - Process phyerror event for gen3 1663 * @pdev: Pointer to pdev object 1664 * @payload: Pointer to spectral report 1665 * 1666 * Process phyerror event for gen3 1667 * 1668 * Return: Success/Failure 1669 */ 1670 int target_if_spectral_process_report_gen3( 1671 struct wlan_objmgr_pdev *pdev, 1672 void *buf); 1673 1674 /** 1675 * target_if_process_phyerr_gen2() - Process PHY Error for gen2 1676 * @spectral: Pointer to Spectral object 1677 * @data: Pointer to phyerror event buffer 1678 * @datalen: Data length 1679 * @p_rfqual: RF quality info 1680 * @p_chaninfo: Channel info 1681 * @tsf64: 64 bit tsf timestamp 1682 * @acs_stats: ACS stats 1683 * 1684 * Process PHY Error for gen2 1685 * 1686 * Return: Success/Failure 1687 */ 1688 int target_if_process_phyerr_gen2( 1689 struct target_if_spectral *spectral, 1690 uint8_t *data, 1691 uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual, 1692 struct target_if_spectral_chan_info *p_chaninfo, 1693 uint64_t tsf64, 1694 struct target_if_spectral_acs_stats *acs_stats); 1695 1696 /** 1697 * target_if_spectral_send_intf_found_msg() - Indicate to application layer that 1698 * interference has been found 1699 * @pdev: Pointer to pdev 1700 * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found 1701 * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled 1702 * 1703 * Send message to application layer 1704 * indicating that interference has been found 1705 * 1706 * Return: None 1707 */ 1708 void target_if_spectral_send_intf_found_msg( 1709 struct wlan_objmgr_pdev *pdev, 1710 uint16_t cw_int, uint32_t dcs_enabled); 1711 1712 /** 1713 * target_if_stop_spectral_scan() - Stop spectral scan 1714 * @pdev: Pointer to pdev object 1715 * @smode: Spectral scan mode 1716 * @err: Pointer to error code 1717 * 1718 * API to stop the current on-going spectral scan 1719 * 1720 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 1721 */ 1722 QDF_STATUS target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, 1723 const enum spectral_scan_mode smode, 1724 enum spectral_cp_error_code *err); 1725 1726 /** 1727 * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral 1728 * operations 1729 * @spectral: Pointer to Spectral target_if internal private data 1730 * @smode: spectral scan mode 1731 * 1732 * Spectral operates on pdev. However, in order to retrieve some WLAN 1733 * properties, a vdev is required. To facilitate this, the function returns the 1734 * first vdev in our pdev. The caller should release the reference to the vdev 1735 * once it is done using it. 1736 * TODO: If the framework later provides an API to obtain the first active 1737 * vdev, then it would be preferable to use this API. 1738 * 1739 * Return: Pointer to vdev on success, NULL on failure 1740 */ 1741 struct wlan_objmgr_vdev *target_if_spectral_get_vdev( 1742 struct target_if_spectral *spectral, 1743 enum spectral_scan_mode smode); 1744 1745 /** 1746 * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2 1747 * @phdr: Pointer to Spectral Phyerr Header 1748 * 1749 * Dump Spectral header 1750 * 1751 * Return: Success/Failure 1752 */ 1753 int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr); 1754 1755 /** 1756 * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI 1757 * for Secondary 80 segment 1758 * @spectral: Pointer to spectral object 1759 * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment 1760 * 1761 * Get approximate combined RSSI for Secondary 80 segment 1762 * 1763 * Return: Combined RSSI for secondary 80Mhz segment 1764 */ 1765 int8_t target_if_get_combrssi_sec80_seg_gen2( 1766 struct target_if_spectral *spectral, 1767 struct spectral_search_fft_info_gen2 *p_sfft_sec80); 1768 1769 /** 1770 * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2 1771 * @ptlv: Pointer to Spectral Phyerr TLV 1772 * @is_160_format: Indicates 160 format 1773 * 1774 * Dump Spectral TLV for gen2 1775 * 1776 * Return: Success/Failure 1777 */ 1778 int target_if_spectral_dump_tlv_gen2( 1779 struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format); 1780 1781 /** 1782 * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral 1783 * related PHY Error for gen2 1784 * @data: Pointer to phyerror buffer 1785 * @datalen: Data length 1786 * @is_160_format: Indicates 160 format 1787 * 1788 * Dump Spectral related PHY Error for gen2 1789 * 1790 * Return: Success/Failure 1791 */ 1792 int target_if_spectral_dump_phyerr_data_gen2( 1793 uint8_t *data, 1794 uint32_t datalen, 1795 bool is_160_format); 1796 1797 /** 1798 * target_if_dbg_print_samp_msg() - Print contents of SAMP Message 1799 * @p: Pointer to SAMP message 1800 * 1801 * Print contents of SAMP Message 1802 * 1803 * Return: Void 1804 */ 1805 void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); 1806 1807 /** 1808 * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal 1809 * Spectral data 1810 * @pdev: Pointer to pdev 1811 * 1812 * Return: Handle to target_if internal Spectral data on success, NULL on 1813 * failure 1814 */ 1815 struct target_if_spectral *get_target_if_spectral_handle_from_pdev( 1816 struct wlan_objmgr_pdev *pdev); 1817 1818 /** 1819 * get_target_if_spectral_handle_from_psoc() - Get handle to psoc target_if 1820 * internal Spectral data 1821 * @psoc: Pointer to psoc 1822 * 1823 * Return: Handle to target_if psoc internal Spectral data on success, NULL on 1824 * failure 1825 */ 1826 static inline 1827 struct target_if_psoc_spectral *get_target_if_spectral_handle_from_psoc( 1828 struct wlan_objmgr_psoc *psoc) 1829 { 1830 struct wlan_lmac_if_rx_ops *rx_ops; 1831 struct target_if_psoc_spectral *psoc_spectral; 1832 1833 if (!psoc) { 1834 spectral_err("psoc is null"); 1835 return NULL; 1836 } 1837 1838 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1839 if (!rx_ops) { 1840 spectral_err("rx_ops is null"); 1841 return NULL; 1842 } 1843 1844 psoc_spectral = (struct target_if_psoc_spectral *) 1845 rx_ops->sptrl_rx_ops.sptrlro_get_psoc_target_handle(psoc); 1846 1847 return psoc_spectral; 1848 } 1849 1850 /** 1851 * target_if_vdev_get_chan_freq() - Get the operating channel frequency of a 1852 * given vdev 1853 * @pdev: Pointer to vdev 1854 * 1855 * Get the operating channel frequency of a given vdev 1856 * 1857 * Return: Operating channel frequency of a vdev 1858 */ 1859 static inline 1860 int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) 1861 { 1862 struct wlan_objmgr_psoc *psoc = NULL; 1863 struct wlan_lmac_if_rx_ops *rx_ops; 1864 1865 psoc = wlan_vdev_get_psoc(vdev); 1866 if (!psoc) { 1867 spectral_err("psoc is NULL"); 1868 return -EINVAL; 1869 } 1870 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1871 if (!rx_ops) { 1872 spectral_err("rx_ops is null"); 1873 return -EINVAL; 1874 } 1875 1876 return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq( 1877 vdev); 1878 } 1879 1880 /** 1881 * target_if_vdev_get_chan_freq_seg2() - Get center frequency of secondary 80 of 1882 * given vdev 1883 * @vdev: Pointer to vdev 1884 * 1885 * Get the center frequency of secondary 80 of given vdev 1886 * 1887 * Return: center frequency of secondary 80 1888 */ 1889 static inline 1890 int16_t target_if_vdev_get_chan_freq_seg2(struct wlan_objmgr_vdev *vdev) 1891 { 1892 struct wlan_objmgr_psoc *psoc = NULL; 1893 struct wlan_lmac_if_rx_ops *rx_ops; 1894 1895 psoc = wlan_vdev_get_psoc(vdev); 1896 if (!psoc) { 1897 spectral_err("psoc is NULL"); 1898 return -EINVAL; 1899 } 1900 1901 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1902 if (!rx_ops) { 1903 spectral_err("rx_ops is null"); 1904 return -EINVAL; 1905 } 1906 1907 return rx_ops->sptrl_rx_ops.sptrlro_vdev_get_chan_freq_seg2(vdev); 1908 } 1909 1910 /** 1911 * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a 1912 * given vdev 1913 * @pdev: Pointer to vdev 1914 * 1915 * Get the operating channel bandwidth of a given vdev 1916 * 1917 * Return: channel bandwidth enumeration corresponding to the vdev 1918 */ 1919 static inline 1920 enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) 1921 { 1922 struct wlan_objmgr_psoc *psoc = NULL; 1923 enum phy_ch_width ch_width; 1924 struct wlan_lmac_if_rx_ops *rx_ops; 1925 1926 psoc = wlan_vdev_get_psoc(vdev); 1927 if (!psoc) { 1928 spectral_err("psoc is NULL"); 1929 return CH_WIDTH_INVALID; 1930 } 1931 1932 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1933 if (!rx_ops) { 1934 spectral_err("rx_ops is null"); 1935 return CH_WIDTH_INVALID; 1936 } 1937 1938 ch_width = rx_ops->sptrl_rx_ops.sptrlro_vdev_get_ch_width(vdev); 1939 1940 if (ch_width == CH_WIDTH_160MHZ) { 1941 int16_t cfreq2; 1942 1943 cfreq2 = target_if_vdev_get_chan_freq_seg2(vdev); 1944 if (cfreq2 < 0) { 1945 spectral_err("Invalid value for cfreq2 %d", cfreq2); 1946 return CH_WIDTH_INVALID; 1947 } 1948 1949 /* Use non zero cfreq2 to identify 80p80 */ 1950 if (cfreq2) 1951 ch_width = CH_WIDTH_80P80MHZ; 1952 } 1953 1954 return ch_width; 1955 } 1956 1957 /** 1958 * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary 1959 * 20 MHz channel for a given vdev 1960 * @pdev: Pointer to vdev 1961 * 1962 * Get the frequency of secondary 20Mhz channel for a given vdev 1963 * 1964 * Return: Frequency of secondary 20Mhz channel for a given vdev 1965 */ 1966 static inline 1967 int target_if_vdev_get_sec20chan_freq_mhz( 1968 struct wlan_objmgr_vdev *vdev, 1969 uint16_t *sec20chan_freq) 1970 { 1971 struct wlan_objmgr_psoc *psoc = NULL; 1972 struct wlan_lmac_if_rx_ops *rx_ops; 1973 1974 psoc = wlan_vdev_get_psoc(vdev); 1975 if (!psoc) { 1976 spectral_err("psoc is NULL"); 1977 return -EINVAL; 1978 } 1979 1980 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 1981 if (!rx_ops) { 1982 spectral_err("rx_ops is null"); 1983 return -EINVAL; 1984 } 1985 1986 return rx_ops->sptrl_rx_ops. 1987 sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); 1988 } 1989 1990 /** 1991 * target_if_spectral_is_feature_disabled_psoc() - Check if Spectral feature is 1992 * disabled for a given psoc 1993 * @psoc: Pointer to psoc 1994 * 1995 * Return: true or false 1996 */ 1997 static inline 1998 bool target_if_spectral_is_feature_disabled_psoc(struct wlan_objmgr_psoc *psoc) 1999 { 2000 struct wlan_lmac_if_rx_ops *rx_ops; 2001 2002 if (!psoc) { 2003 spectral_err("psoc is NULL"); 2004 return true; 2005 } 2006 2007 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 2008 if (!rx_ops) { 2009 spectral_err("rx_ops is null"); 2010 return true; 2011 } 2012 2013 if (rx_ops->sptrl_rx_ops. 2014 sptrlro_spectral_is_feature_disabled_psoc) 2015 return rx_ops->sptrl_rx_ops. 2016 sptrlro_spectral_is_feature_disabled_psoc(psoc); 2017 2018 return true; 2019 } 2020 2021 /** 2022 * target_if_spectral_is_feature_disabled_pdev() - Check if Spectral feature is 2023 * disabled for a given pdev 2024 * @pdev: Pointer to pdev 2025 * 2026 * Return: true or false 2027 */ 2028 static inline 2029 bool target_if_spectral_is_feature_disabled_pdev(struct wlan_objmgr_pdev *pdev) 2030 { 2031 struct wlan_lmac_if_rx_ops *rx_ops; 2032 struct wlan_objmgr_psoc *psoc; 2033 2034 if (!pdev) { 2035 spectral_err("pdev is NULL"); 2036 return true; 2037 } 2038 2039 psoc = wlan_pdev_get_psoc(pdev); 2040 if (!psoc) { 2041 spectral_err("psoc is NULL"); 2042 return true; 2043 } 2044 2045 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 2046 if (!rx_ops) { 2047 spectral_err("rx_ops is null"); 2048 return true; 2049 } 2050 2051 if (rx_ops->sptrl_rx_ops. 2052 sptrlro_spectral_is_feature_disabled_pdev) 2053 return rx_ops->sptrl_rx_ops. 2054 sptrlro_spectral_is_feature_disabled_pdev(pdev); 2055 2056 return true; 2057 } 2058 2059 /** 2060 * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask 2061 * @pdev: Pointer to pdev 2062 * @spectral_rx_chainmask: Spectral Rx chainmask 2063 * 2064 * Return: None 2065 */ 2066 static inline 2067 void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, 2068 uint8_t spectral_rx_chainmask) 2069 { 2070 struct wlan_objmgr_psoc *psoc = NULL; 2071 struct target_if_spectral *spectral = NULL; 2072 enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL; 2073 struct wlan_lmac_if_rx_ops *rx_ops; 2074 2075 psoc = wlan_pdev_get_psoc(pdev); 2076 if (!psoc) { 2077 spectral_err("psoc is NULL"); 2078 return; 2079 } 2080 2081 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 2082 if (!rx_ops) { 2083 spectral_err("rx_ops is null"); 2084 return; 2085 } 2086 2087 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 2088 spectral_err("Invalid Spectral mode %u", smode); 2089 return; 2090 } 2091 2092 if (rx_ops->sptrl_rx_ops. 2093 sptrlro_spectral_is_feature_disabled_pdev(pdev)) { 2094 spectral_info("Spectral feature is disabled"); 2095 return; 2096 } 2097 2098 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2099 if (!spectral) { 2100 spectral_err("Spectral target if object is null"); 2101 return; 2102 } 2103 2104 /* set chainmask for all the modes */ 2105 for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) 2106 spectral->params[smode].ss_chn_mask = spectral_rx_chainmask; 2107 } 2108 2109 /** 2110 * target_if_spectral_process_phyerr() - Process Spectral PHY error 2111 * @pdev: Pointer to pdev 2112 * @data: PHY error data received from FW 2113 * @datalen: Length of data 2114 * @p_rfqual: Pointer to RF Quality information 2115 * @p_chaninfo: Pointer to channel information 2116 * @tsf: TSF time instance at which the Spectral sample was received 2117 * @acs_stats: ACS stats 2118 * 2119 * Process Spectral PHY error by extracting necessary information from the data 2120 * sent by FW, and send the extracted information to application layer. 2121 * 2122 * Return: None 2123 */ 2124 static inline 2125 void target_if_spectral_process_phyerr( 2126 struct wlan_objmgr_pdev *pdev, 2127 uint8_t *data, uint32_t datalen, 2128 struct target_if_spectral_rfqual_info *p_rfqual, 2129 struct target_if_spectral_chan_info *p_chaninfo, 2130 uint64_t tsf64, 2131 struct target_if_spectral_acs_stats *acs_stats) 2132 { 2133 struct target_if_spectral *spectral = NULL; 2134 struct target_if_spectral_ops *p_sops = NULL; 2135 2136 spectral = get_target_if_spectral_handle_from_pdev(pdev); 2137 if (!spectral) { 2138 spectral_err("Spectral target if object is null"); 2139 return; 2140 } 2141 2142 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 2143 if (!p_sops->spectral_process_phyerr) { 2144 spectral_err("null spectral_process_phyerr"); 2145 return; 2146 } 2147 p_sops->spectral_process_phyerr(spectral, data, datalen, 2148 p_rfqual, p_chaninfo, 2149 tsf64, acs_stats); 2150 } 2151 2152 static QDF_STATUS 2153 target_if_get_spectral_msg_type(enum spectral_scan_mode smode, 2154 enum spectral_msg_type *msg_type) { 2155 2156 switch (smode) { 2157 case SPECTRAL_SCAN_MODE_NORMAL: 2158 *msg_type = SPECTRAL_MSG_NORMAL_MODE; 2159 break; 2160 2161 case SPECTRAL_SCAN_MODE_AGILE: 2162 *msg_type = SPECTRAL_MSG_AGILE_MODE; 2163 break; 2164 2165 default: 2166 spectral_err("Invalid spectral mode"); 2167 return QDF_STATUS_E_FAILURE; 2168 } 2169 2170 return QDF_STATUS_SUCCESS; 2171 } 2172 2173 static inline bool 2174 is_ch_width_160_or_80p80(enum phy_ch_width ch_width) 2175 { 2176 return (ch_width == CH_WIDTH_160MHZ || ch_width == CH_WIDTH_80P80MHZ); 2177 } 2178 2179 /** 2180 * free_samp_msg_skb() - Free SAMP message skb 2181 * @spectral: Pointer to Spectral 2182 * @smode: Spectral Scan mode 2183 * 2184 * Free SAMP message skb, if error in report processing 2185 * 2186 * Return: void 2187 */ 2188 static inline void 2189 free_samp_msg_skb(struct target_if_spectral *spectral, 2190 enum spectral_scan_mode smode) 2191 { 2192 enum spectral_msg_type smsg_type; 2193 QDF_STATUS ret; 2194 2195 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 2196 spectral_err_rl("Invalid Spectral mode %d", smode); 2197 return; 2198 } 2199 2200 if (is_ch_width_160_or_80p80(spectral->ch_width[smode])) { 2201 ret = target_if_get_spectral_msg_type(smode, &smsg_type); 2202 if (QDF_IS_STATUS_ERROR(ret)) { 2203 spectral_err("Failed to get spectral message type"); 2204 return; 2205 } 2206 spectral->nl_cb.free_sbuff(spectral->pdev_obj, 2207 smsg_type); 2208 } 2209 } 2210 2211 /** 2212 * init_160mhz_delivery_state_machine() - Initialize 160MHz Spectral 2213 * state machine 2214 * @spectral: Pointer to Spectral 2215 * 2216 * Initialize 160MHz Spectral state machine 2217 * 2218 * Return: void 2219 */ 2220 static inline void 2221 init_160mhz_delivery_state_machine(struct target_if_spectral *spectral) 2222 { 2223 uint8_t smode; 2224 2225 smode = 0; 2226 for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) 2227 spectral->state_160mhz_delivery[smode] = 2228 SPECTRAL_REPORT_WAIT_PRIMARY80; 2229 } 2230 2231 /** 2232 * reset_160mhz_delivery_state_machine() - Reset 160MHz Spectral state machine 2233 * @spectral: Pointer to Spectral 2234 * 2235 * Reset 160MHz Spectral state machine 2236 * 2237 * Return: void 2238 */ 2239 static inline void 2240 reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, 2241 enum spectral_scan_mode smode) 2242 { 2243 if (smode >= SPECTRAL_SCAN_MODE_MAX) { 2244 spectral_err_rl("Invalid Spectral mode %d", smode); 2245 return; 2246 } 2247 2248 free_samp_msg_skb(spectral, smode); 2249 2250 if (is_ch_width_160_or_80p80(spectral->ch_width[smode])) { 2251 spectral->state_160mhz_delivery[smode] = 2252 SPECTRAL_REPORT_WAIT_PRIMARY80; 2253 } 2254 } 2255 2256 /** 2257 * is_secondaryseg_expected() - Is waiting for secondary 80 report 2258 * @spectral: Pointer to Spectral 2259 * @smode: Spectral scan mode 2260 * 2261 * Return true if secondary 80 report expected and mode is 160 MHz 2262 * 2263 * Return: true or false 2264 */ 2265 static inline 2266 bool is_secondaryseg_expected(struct target_if_spectral *spectral, 2267 enum spectral_scan_mode smode) 2268 { 2269 return 2270 (is_ch_width_160_or_80p80(spectral->ch_width[smode]) && 2271 spectral->rparams.fragmentation_160[smode] && 2272 (spectral->state_160mhz_delivery[smode] == 2273 SPECTRAL_REPORT_WAIT_SECONDARY80)); 2274 } 2275 2276 /** 2277 * is_primaryseg_expected() - Is waiting for primary 80 report 2278 * @spectral: Pointer to Spectral 2279 * @smode: Spectral scan mode 2280 * 2281 * Return true if mode is 160 Mhz and primary 80 report expected or 2282 * mode is not 160 Mhz 2283 * 2284 * Return: true or false 2285 */ 2286 static inline 2287 bool is_primaryseg_expected(struct target_if_spectral *spectral, 2288 enum spectral_scan_mode smode) 2289 { 2290 return 2291 (!is_ch_width_160_or_80p80(spectral->ch_width[smode]) || 2292 !spectral->rparams.fragmentation_160[smode] || 2293 (spectral->state_160mhz_delivery[smode] == 2294 SPECTRAL_REPORT_WAIT_PRIMARY80)); 2295 } 2296 2297 #ifndef OPTIMIZED_SAMP_MESSAGE 2298 /** 2299 * is_primaryseg_rx_inprog() - Is primary 80 report processing is in progress 2300 * @spectral: Pointer to Spectral 2301 * @smode: Spectral scan mode 2302 * 2303 * Is primary 80 report processing is in progress 2304 * 2305 * Return: true or false 2306 */ 2307 static inline 2308 bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral, 2309 enum spectral_scan_mode smode) 2310 { 2311 return 2312 (!is_ch_width_160_or_80p80(spectral->ch_width[smode]) || 2313 spectral->spectral_gen == SPECTRAL_GEN2 || 2314 (spectral->spectral_gen == SPECTRAL_GEN3 && 2315 (!spectral->rparams.fragmentation_160[smode] || 2316 spectral->state_160mhz_delivery[smode] == 2317 SPECTRAL_REPORT_RX_PRIMARY80))); 2318 } 2319 2320 /** 2321 * is_secondaryseg_rx_inprog() - Is secondary80 report processing is in progress 2322 * @spectral: Pointer to Spectral 2323 * @smode: Spectral scan mode 2324 * 2325 * Is secondary 80 report processing is in progress 2326 * 2327 * Return: true or false 2328 */ 2329 static inline 2330 bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral, 2331 enum spectral_scan_mode smode) 2332 { 2333 return 2334 (is_ch_width_160_or_80p80(spectral->ch_width[smode]) && 2335 (spectral->spectral_gen == SPECTRAL_GEN2 || 2336 ((spectral->spectral_gen == SPECTRAL_GEN3) && 2337 (!spectral->rparams.fragmentation_160[smode] || 2338 spectral->state_160mhz_delivery[smode] == 2339 SPECTRAL_REPORT_RX_SECONDARY80)))); 2340 } 2341 #endif 2342 2343 /** 2344 * clamp_fft_bin_value() - Clamp the FFT bin value between min and max 2345 * @fft_bin_value: FFT bin value as reported by HW 2346 * @pwr_format: FFT bin format (linear or dBm format) 2347 * 2348 * Each FFT bin value is represented as an 8 bit integer in SAMP message. But 2349 * depending on the configuration, the FFT bin value reported by HW might 2350 * exceed 8 bits. Clamp the FFT bin value between the min and max value 2351 * which can be represented by 8 bits. For linear mode, min and max FFT bin 2352 * value which can be represented by 8 bit is 0 and U8_MAX respectively. For 2353 * dBm mode, min and max FFT bin value which can be represented by 8 bit is 2354 * S8_MIN and S8_MAX respectively. 2355 * 2356 * Return: Clamped FFT bin value 2357 */ 2358 static inline uint8_t 2359 clamp_fft_bin_value(uint16_t fft_bin_value, uint16_t pwr_format) 2360 { 2361 uint8_t clamped_fft_bin_value = 0; 2362 2363 switch (pwr_format) { 2364 case SPECTRAL_PWR_FORMAT_LINEAR: 2365 if (qdf_unlikely(fft_bin_value > MAX_FFTBIN_VALUE_LINEAR_MODE)) 2366 clamped_fft_bin_value = MAX_FFTBIN_VALUE_LINEAR_MODE; 2367 else 2368 clamped_fft_bin_value = fft_bin_value; 2369 break; 2370 2371 case SPECTRAL_PWR_FORMAT_DBM: 2372 if (qdf_unlikely((int16_t)fft_bin_value > 2373 MAX_FFTBIN_VALUE_DBM_MODE)) 2374 clamped_fft_bin_value = MAX_FFTBIN_VALUE_DBM_MODE; 2375 else if (qdf_unlikely((int16_t)fft_bin_value < 2376 MIN_FFTBIN_VALUE_DBM_MODE)) 2377 clamped_fft_bin_value = MIN_FFTBIN_VALUE_DBM_MODE; 2378 else 2379 clamped_fft_bin_value = fft_bin_value; 2380 break; 2381 2382 default: 2383 qdf_assert_always(0); 2384 } 2385 2386 return clamped_fft_bin_value; 2387 } 2388 2389 /** 2390 * target_if_160mhz_delivery_state_change() - State transition for 160Mhz 2391 * Spectral 2392 * @spectral: Pointer to spectral object 2393 * @smode: Spectral scan mode 2394 * @detector_id: Detector id 2395 * 2396 * Move the states of state machine for 160MHz spectral scan report receive 2397 * 2398 * Return: QDF_STATUS 2399 */ 2400 QDF_STATUS 2401 target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, 2402 enum spectral_scan_mode smode, 2403 uint8_t detector_id); 2404 2405 /** 2406 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 2407 * @arg: Pointer to handle for Spectral target_if internal private data 2408 * @smode: Spectral scan mode 2409 * 2410 * Function to check whether Spectral is enabled 2411 * 2412 * Return: True if Spectral is enabled, false if Spectral is not enabled 2413 */ 2414 uint32_t target_if_sops_is_spectral_enabled(void *arg, 2415 enum spectral_scan_mode smode); 2416 2417 /** 2418 * target_if_sops_is_spectral_active() - Get whether Spectral is active 2419 * @arg: Pointer to handle for Spectral target_if internal private data 2420 * @smode: Spectral scan mode 2421 * 2422 * Function to check whether Spectral is active 2423 * 2424 * Return: True if Spectral is active, false if Spectral is not active 2425 */ 2426 uint32_t target_if_sops_is_spectral_active(void *arg, 2427 enum spectral_scan_mode smode); 2428 2429 /** 2430 * target_if_sops_start_spectral_scan() - Start Spectral scan 2431 * @arg: Pointer to handle for Spectral target_if internal private data 2432 * @smode: Spectral scan mode 2433 * @err: Pointer to error code 2434 * 2435 * Function to start spectral scan 2436 * 2437 * Return: 0 on success else failure 2438 */ 2439 uint32_t target_if_sops_start_spectral_scan(void *arg, 2440 enum spectral_scan_mode smode, 2441 enum spectral_cp_error_code *err); 2442 2443 /** 2444 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 2445 * @arg: Pointer to handle for Spectral target_if internal private data 2446 * @smode: Spectral scan mode 2447 * 2448 * Function to stop spectral scan 2449 * 2450 * Return: 0 in case of success, -1 on failure 2451 */ 2452 uint32_t target_if_sops_stop_spectral_scan(void *arg, 2453 enum spectral_scan_mode smode); 2454 2455 /** 2456 * target_if_spectral_get_extension_channel() - Get the current Extension 2457 * channel (in MHz) 2458 * @arg: Pointer to handle for Spectral target_if internal private data 2459 * @smode: Spectral scan mode 2460 * 2461 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 2462 * extension channel is not present. 2463 */ 2464 uint32_t 2465 target_if_spectral_get_extension_channel(void *arg, 2466 enum spectral_scan_mode smode); 2467 2468 /** 2469 * target_if_spectral_get_current_channel() - Get the current channel (in MHz) 2470 * @arg: Pointer to handle for Spectral target_if internal private data 2471 * @smode: Spectral scan mode 2472 * 2473 * Return: Current channel (in MHz) on success, 0 on failure 2474 */ 2475 uint32_t 2476 target_if_spectral_get_current_channel(void *arg, 2477 enum spectral_scan_mode smode); 2478 2479 2480 /** 2481 * target_if_spectral_reset_hw() - Reset the hardware 2482 * @arg: Pointer to handle for Spectral target_if internal private data 2483 * 2484 * This is only a placeholder since it is not currently required in the offload 2485 * case. 2486 * 2487 * Return: 0 2488 */ 2489 uint32_t target_if_spectral_reset_hw(void *arg); 2490 2491 /** 2492 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 2493 * Noisefloor history buffer 2494 * @arg: Pointer to handle for Spectral target_if internal private data 2495 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 2496 * 2497 * This is only a placeholder since it is not currently required in the offload 2498 * case. 2499 * 2500 * Return: 0 2501 */ 2502 uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf); 2503 2504 /** 2505 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 2506 * noisefloor 2507 * @arg: Pointer to handle for Spectral target_if internal private data 2508 * 2509 * This is only a placeholder since it is not currently required in the offload 2510 * case. 2511 * 2512 * Return: 0 2513 */ 2514 int8_t target_if_spectral_get_ext_noisefloor(void *arg); 2515 2516 /** 2517 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 2518 * @arg: Pointer to handle for Spectral target_if internal private data 2519 * 2520 * This is only a placeholder since it is not currently required in the offload 2521 * case. 2522 * 2523 * Return: 0 2524 */ 2525 int8_t target_if_spectral_get_ctl_noisefloor(void *arg); 2526 2527 /** 2528 * target_if_spectral_get_capability() - Get whether a given Spectral hardware 2529 * capability is available 2530 * @arg: Pointer to handle for Spectral target_if internal private data 2531 * @type: Spectral hardware capability type 2532 * 2533 * Return: True if the capability is available, false if the capability is not 2534 * available 2535 */ 2536 uint32_t target_if_spectral_get_capability( 2537 void *arg, enum spectral_capability_type type); 2538 2539 /** 2540 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 2541 * @arg: Pointer to handle for Spectral target_if internal private data 2542 * @rxfilter: Rx filter to be used 2543 * 2544 * Note: This is only a placeholder function. It is not currently required since 2545 * FW should be taking care of setting the required filters. 2546 * 2547 * Return: 0 2548 */ 2549 uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter); 2550 2551 /** 2552 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 2553 * parameters 2554 * @arg: Pointer to handle for Spectral target_if internal private data 2555 * @params: Spectral parameters 2556 * @smode: Spectral scan mode 2557 * 2558 * Return: 0 in case of success, -1 on failure 2559 */ 2560 uint32_t target_if_spectral_sops_configure_params( 2561 void *arg, struct spectral_config *params, 2562 enum spectral_scan_mode smode); 2563 2564 /** 2565 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 2566 * @arg: Pointer to handle for Spectral target_if internal private data 2567 * 2568 * Note: This is only a placeholder function. It is not currently required since 2569 * FW should be taking care of setting the required filters. 2570 * 2571 * Return: 0 2572 */ 2573 uint32_t target_if_spectral_get_rxfilter(void *arg); 2574 2575 /** 2576 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 2577 * functionality for the given pdev 2578 * @pdev: Pointer to pdev object 2579 * 2580 * Return: None 2581 */ 2582 void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev); 2583 2584 /** 2585 * target_if_set_spectral_config() - Set spectral config 2586 * @pdev: Pointer to pdev object 2587 * @param: Spectral parameter id and value 2588 * @smode: Spectral scan mode 2589 * @err: Pointer to Spectral error code 2590 * 2591 * API to set spectral configurations 2592 * 2593 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2594 */ 2595 QDF_STATUS target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 2596 const struct spectral_cp_param *param, 2597 const enum spectral_scan_mode smode, 2598 enum spectral_cp_error_code *err); 2599 2600 /** 2601 * target_if_pdev_spectral_init() - Initialize target_if Spectral 2602 * functionality for the given pdev 2603 * @pdev: Pointer to pdev object 2604 * 2605 * Return: On success, pointer to Spectral target_if internal private data, on 2606 * failure, NULL 2607 */ 2608 void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev); 2609 2610 /** 2611 * target_if_spectral_sops_get_params() - Get user configured Spectral 2612 * parameters 2613 * @arg: Pointer to handle for Spectral target_if internal private data 2614 * @params: Pointer to buffer into which Spectral parameters should be copied 2615 * @smode: Spectral scan mode 2616 * 2617 * Return: 0 in case of success, -1 on failure 2618 */ 2619 uint32_t target_if_spectral_sops_get_params( 2620 void *arg, struct spectral_config *params, 2621 enum spectral_scan_mode smode); 2622 2623 /** 2624 * target_if_init_spectral_capability() - Initialize Spectral capability 2625 * 2626 * @spectral: Pointer to Spectral target_if internal private data 2627 * @target_type: target type 2628 * 2629 * This is a workaround. 2630 * 2631 * Return: QDF_STATUS 2632 */ 2633 QDF_STATUS 2634 target_if_init_spectral_capability(struct target_if_spectral *spectral, 2635 uint32_t target_type); 2636 2637 /** 2638 * target_if_start_spectral_scan() - Start spectral scan 2639 * @pdev: Pointer to pdev object 2640 * @vdev_id: VDEV id 2641 * @smode: Spectral scan mode 2642 * @err: Spectral error code 2643 * 2644 * API to start spectral scan 2645 * 2646 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2647 */ 2648 QDF_STATUS target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, 2649 uint8_t vdev_id, 2650 enum spectral_scan_mode smode, 2651 enum spectral_cp_error_code *err); 2652 2653 /** 2654 * target_if_get_spectral_config() - Get spectral configuration 2655 * @pdev: Pointer to pdev object 2656 * @param: Pointer to spectral_config structure in which the configuration 2657 * should be returned 2658 * @smode: Spectral scan mode 2659 * 2660 * API to get the current spectral configuration 2661 * 2662 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2663 */ 2664 QDF_STATUS target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 2665 struct spectral_config *param, 2666 enum spectral_scan_mode smode); 2667 2668 /** 2669 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 2670 * parameters 2671 * @spectral: Pointer to Spectral target_if internal private data 2672 * @spectral_params: Pointer to Spectral parameters 2673 * @smode: Spectral scan mode 2674 * @err: Spectral error code 2675 * 2676 * Enable use of desired Spectral parameters by configuring them into HW, and 2677 * starting Spectral scan 2678 * 2679 * Return: 0 on success, 1 on failure 2680 */ 2681 int target_if_spectral_scan_enable_params( 2682 struct target_if_spectral *spectral, 2683 struct spectral_config *spectral_params, 2684 enum spectral_scan_mode smode, 2685 enum spectral_cp_error_code *err); 2686 2687 /** 2688 * target_if_is_spectral_active() - Get whether Spectral is active 2689 * @pdev: Pointer to pdev object 2690 * @smode: Spectral scan mode 2691 * 2692 * Return: True if Spectral is active, false if Spectral is not active 2693 */ 2694 bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev, 2695 enum spectral_scan_mode smode); 2696 2697 /** 2698 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 2699 * @pdev: Pointer to pdev object 2700 * @smode: Spectral scan mode 2701 * 2702 * Return: True if Spectral is enabled, false if Spectral is not enabled 2703 */ 2704 bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev, 2705 enum spectral_scan_mode smode); 2706 2707 /** 2708 * target_if_set_debug_level() - Set debug level for Spectral 2709 * @pdev: Pointer to pdev object 2710 * @debug_level: Debug level 2711 * 2712 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2713 * 2714 */ 2715 QDF_STATUS target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, 2716 uint32_t debug_level); 2717 2718 /** 2719 * target_if_get_debug_level() - Get debug level for Spectral 2720 * @pdev: Pointer to pdev object 2721 * 2722 * Return: Current debug level 2723 */ 2724 uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev); 2725 2726 2727 /** 2728 * target_if_get_spectral_capinfo() - Get Spectral capability information 2729 * @pdev: Pointer to pdev object 2730 * @scaps: Buffer into which data should be copied 2731 * 2732 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2733 */ 2734 QDF_STATUS target_if_get_spectral_capinfo(struct wlan_objmgr_pdev *pdev, 2735 struct spectral_caps *scaps); 2736 2737 2738 /** 2739 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 2740 * @pdev: Pointer to pdev object 2741 * @stats: Buffer into which data should be copied 2742 * 2743 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2744 */ 2745 QDF_STATUS target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, 2746 struct spectral_diag_stats *stats); 2747 2748 QDF_STATUS 2749 target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, 2750 enum spectral_scan_mode smode, 2751 uint8_t detector_id); 2752 2753 #ifdef OPTIMIZED_SAMP_MESSAGE 2754 /** 2755 * target_if_spectral_get_num_fft_bins() - Get number of FFT bins from FFT size 2756 * according to the Spectral report mode. 2757 * @fft_size: FFT length 2758 * @report_mode: Spectral report mode 2759 * 2760 * Get number of FFT bins from FFT size according to the Spectral 2761 * report mode. 2762 * 2763 * Return: Number of FFT bins 2764 */ 2765 static inline uint32_t 2766 target_if_spectral_get_num_fft_bins(uint32_t fft_size, 2767 enum spectral_report_mode report_mode) 2768 { 2769 switch (report_mode) { 2770 case SPECTRAL_REPORT_MODE_0: 2771 case SPECTRAL_REPORT_MODE_1: 2772 return 0; 2773 case SPECTRAL_REPORT_MODE_2: 2774 return (1 << (fft_size - 1)); 2775 case SPECTRAL_REPORT_MODE_3: 2776 return (1 << fft_size); 2777 default: 2778 return -EINVAL; 2779 } 2780 } 2781 #endif /* OPTIMIZED_SAMP_MESSAGE */ 2782 2783 #ifdef OPTIMIZED_SAMP_MESSAGE 2784 /** 2785 * target_if_get_detector_chwidth() - Get per-detector bandwidth 2786 * based on channel width and fragmentation. 2787 * @ch_width: Spectral scan channel width 2788 * @fragmentation_160: Target type has fragmentation or not 2789 * 2790 * Get per-detector BW. 2791 * 2792 * Return: detector BW 2793 */ 2794 static inline 2795 enum phy_ch_width target_if_get_detector_chwidth(enum phy_ch_width ch_width, 2796 bool fragmentation_160) 2797 { 2798 return ((ch_width == CH_WIDTH_160MHZ && fragmentation_160) ? 2799 CH_WIDTH_80MHZ : ((ch_width == CH_WIDTH_80P80MHZ) ? 2800 CH_WIDTH_80MHZ : ch_width)); 2801 } 2802 2803 /** 2804 * target_if_spectral_set_start_end_freq() - Set start and end frequencies for 2805 * a given center frequency 2806 * @cfreq: Center frequency for which start and end freq need to be set 2807 * @ch_width: Spectral scan Channel width 2808 * @fragmentation_160: Target type has fragmentation or not 2809 * @start_end_freq: Array containing start and end frequency of detector 2810 * 2811 * Set the start and end frequencies for given center frequency in destination 2812 * detector info struct 2813 * 2814 * Return: void 2815 */ 2816 static inline 2817 void target_if_spectral_set_start_end_freq(uint32_t cfreq, 2818 enum phy_ch_width ch_width, 2819 bool fragmentation_160, 2820 uint32_t *start_end_freq) 2821 { 2822 enum phy_ch_width det_ch_width; 2823 2824 det_ch_width = target_if_get_detector_chwidth(ch_width, 2825 fragmentation_160); 2826 2827 start_end_freq[0] = cfreq - (wlan_reg_get_bw_value(det_ch_width) >> 1); 2828 start_end_freq[1] = cfreq + (wlan_reg_get_bw_value(det_ch_width) >> 1); 2829 } 2830 #endif /* OPTIMIZED_SAMP_MESSAGE */ 2831 2832 #ifdef DIRECT_BUF_RX_ENABLE 2833 /** 2834 * target_if_consume_sfft_report_gen3() - Process fft report for gen3 2835 * @spectral: Pointer to spectral object 2836 * @report: Pointer to spectral report 2837 * 2838 * Process fft report for gen3 2839 * 2840 * Return: Success/Failure 2841 */ 2842 int 2843 target_if_consume_spectral_report_gen3( 2844 struct target_if_spectral *spectral, 2845 struct spectral_report *report); 2846 #endif 2847 2848 /** 2849 * target_if_spectral_fw_hang() - Crash the FW from Spectral module 2850 * @spectral: Pointer to Spectral LMAC object 2851 * 2852 * Return: QDF_STATUS of operation 2853 */ 2854 QDF_STATUS target_if_spectral_fw_hang(struct target_if_spectral *spectral); 2855 2856 /** 2857 * target_if_spectral_finite_scan_update() - Update scan count for finite scan 2858 * and stop Spectral scan when required 2859 * @spectral: Pointer to Spectral target_if internal private data 2860 * @smode: Spectral scan mode 2861 * 2862 * This API decrements the number of Spectral reports expected from target for 2863 * a finite Spectral scan. When expected number of reports are received from 2864 * target Spectral scan is stopped. 2865 * 2866 * Return: QDF_STATUS on success 2867 */ 2868 QDF_STATUS 2869 target_if_spectral_finite_scan_update(struct target_if_spectral *spectral, 2870 enum spectral_scan_mode smode); 2871 2872 /** 2873 * target_if_spectral_is_finite_scan() - Check Spectral scan is finite/infinite 2874 * @spectral: Pointer to Spectral target_if internal private data 2875 * @smode: Spectral scan mode 2876 * 2877 * API to check whether Spectral scan is finite/infinite for the give mode. 2878 * A non zero scan count indicates that scan is finite. Scan count of 0 2879 * indicates an infinite Spectral scan. 2880 * 2881 * Return: QDF_STATUS on success 2882 */ 2883 QDF_STATUS 2884 target_if_spectral_is_finite_scan(struct target_if_spectral *spectral, 2885 enum spectral_scan_mode smode, 2886 bool *finite_spectral_scan); 2887 2888 #ifdef BIG_ENDIAN_HOST 2889 /** 2890 * target_if_byte_swap_spectral_headers_gen3() - Apply byte-swap on headers 2891 * @spectral: Pointer to Spectral target_if internal private data 2892 * @data: Pointer to the start of Spectral Scan Summary report 2893 * 2894 * This API is only required for Big-endian Host platforms. 2895 * It applies 32-bit byte-swap on Spectral Scan Summary and Search FFT reports 2896 * and copies them back to the source location. 2897 * Padding bytes that lie between the reports won't be touched. 2898 * 2899 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2900 */ 2901 QDF_STATUS target_if_byte_swap_spectral_headers_gen3( 2902 struct target_if_spectral *spectral, 2903 void *data); 2904 2905 /** 2906 * target_if_byte_swap_spectral_fft_bins_gen3() - Apply byte-swap on FFT bins 2907 * @rparams: Pointer to Spectral report parameters 2908 * @bin_pwr_data: Pointer to the start of FFT bins 2909 * @num_fftbins: Number of FFT bins 2910 * 2911 * This API is only required for Big-endian Host platforms. 2912 * It applies pack-mode-aware byte-swap on the FFT bins as below: 2913 * 1. pack-mode 0 (i.e., 1 FFT bin per DWORD): 2914 * Reads the least significant 2 bytes of each DWORD, applies 16-bit 2915 * byte-swap on that value, and copies it back to the source location. 2916 * 2. pack-mode 1 (i.e., 2 FFT bins per DWORD): 2917 * Reads each FFT bin, applies 16-bit byte-swap on that value, 2918 * and copies it back to the source location. 2919 * 3. pack-mode 2 (4 FFT bins per DWORD): 2920 * Nothing 2921 * 2922 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2923 */ 2924 QDF_STATUS target_if_byte_swap_spectral_fft_bins_gen3( 2925 const struct spectral_report_params *rparams, 2926 void *bin_pwr_data, size_t num_fftbins); 2927 #endif /* BIG_ENDIAN_HOST */ 2928 2929 #ifdef OPTIMIZED_SAMP_MESSAGE 2930 /** 2931 * target_if_populate_fft_bins_info() - Populate the start and end bin 2932 * indices, on per-detector level. 2933 * @spectral: Pointer to target_if spectral internal structure 2934 * @smode: Spectral scan mode 2935 * 2936 * Populate the start and end bin indices, on per-detector level. 2937 * 2938 * Return: Success/Failure 2939 */ 2940 QDF_STATUS 2941 target_if_populate_fft_bins_info(struct target_if_spectral *spectral, 2942 enum spectral_scan_mode smode); 2943 #else 2944 static inline QDF_STATUS 2945 target_if_populate_fft_bins_info(struct target_if_spectral *spectral, 2946 enum spectral_scan_mode smode) 2947 { 2948 return QDF_STATUS_SUCCESS; 2949 } 2950 #endif 2951 2952 /** 2953 * spectral_is_session_info_expected_from_target() - Check if spectral scan 2954 * session is expected from target 2955 * @pdev: pdev pointer 2956 * @is_session_info_expected: Pointer to caller variable 2957 * 2958 * Return: QDF_STATUS of operation 2959 */ 2960 QDF_STATUS 2961 spectral_is_session_info_expected_from_target(struct wlan_objmgr_pdev *pdev, 2962 bool *is_session_info_expected); 2963 2964 #ifdef WIN32 2965 #pragma pack(pop, target_if_spectral) 2966 #endif 2967 #ifdef __ATTRIB_PACK 2968 #undef __ATTRIB_PACK 2969 #endif 2970 2971 /** 2972 * target_if_spectral_copy_fft_bins() - Copy FFT bins from source buffer to 2973 * destination buffer 2974 * @spectral: Pointer to Spectral LMAC object 2975 * @src_fft_buf: Pointer to source FFT buffer 2976 * @dest_fft_buf: Pointer to destination FFT buffer 2977 * @fft_bin_count: Number of FFT bins to copy 2978 * @bytes_copied: Number of bytes copied by this API 2979 * @pwr_format: Spectral FFT bin format (linear/dBm mode) 2980 * 2981 * Different targets supports different FFT bin widths. This API encapsulates 2982 * all those details and copies 8-bit FFT value into the destination buffer. 2983 * Also, this API takes care of handling big-endian mode. 2984 * In essence, it does the following. 2985 * - Read DWORDs one by one 2986 * - Extract individual FFT bins out of it 2987 * - Copy the FFT bin to destination buffer 2988 * 2989 * Return: QDF_STATUS_SUCCESS in case of success, else QDF_STATUS_E_FAILURE 2990 */ 2991 QDF_STATUS 2992 target_if_spectral_copy_fft_bins(struct target_if_spectral *spectral, 2993 const void *src_fft_buf, 2994 void *dest_fft_buf, 2995 uint32_t fft_bin_count, 2996 uint32_t *bytes_copied, 2997 uint16_t pwr_format); 2998 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 2999 3000 struct spectral_capabilities_event_params; 3001 /** 3002 * target_if_wmi_extract_spectral_caps_fixed_param() - Wrapper function to 3003 * extract fixed params from Spectral capabilities WMI event 3004 * @psoc: Pointer to psoc object 3005 * @evt_buf: Event buffer 3006 * @param: Spectral capabilities event parameters data structure to be filled 3007 * by this API 3008 * 3009 * Return: QDF_STATUS of operation 3010 */ 3011 QDF_STATUS target_if_wmi_extract_spectral_caps_fixed_param( 3012 struct wlan_objmgr_psoc *psoc, 3013 uint8_t *evt_buf, 3014 struct spectral_capabilities_event_params *param); 3015 3016 struct spectral_scan_bw_capabilities; 3017 /** 3018 * target_if_wmi_extract_spectral_scan_bw_caps() - Wrapper function to 3019 * extract bandwidth capabilities from Spectral capabilities WMI event 3020 * @psoc: Pointer to psoc object 3021 * @evt_buf: Event buffer 3022 * @bw_caps: Data structure to be filled by this API after extraction 3023 * 3024 * Return: QDF_STATUS of operation 3025 */ 3026 QDF_STATUS 3027 target_if_wmi_extract_spectral_scan_bw_caps( 3028 struct wlan_objmgr_psoc *psoc, 3029 uint8_t *evt_buf, 3030 struct spectral_scan_bw_capabilities *bw_caps); 3031 3032 struct spectral_fft_size_capabilities; 3033 /** 3034 * target_if_wmi_extract_spectral_fft_size_caps() - Wrapper function to 3035 * extract fft size capabilities from Spectral capabilities WMI event 3036 * @psoc: Pointer to psoc object 3037 * @evt_buf: Event buffer 3038 * @fft_size_caps: Data structure to be filled by this API after extraction 3039 * 3040 * Return: QDF_STATUS of operation 3041 */ 3042 QDF_STATUS 3043 target_if_wmi_extract_spectral_fft_size_caps( 3044 struct wlan_objmgr_psoc *psoc, 3045 uint8_t *evt_buf, 3046 struct spectral_fft_size_capabilities *fft_size_caps); 3047 #endif /* _TARGET_IF_SPECTRAL_H_ */ 3048