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