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