1 /* 2 * Copyright (c) 2011,2017-2018 The Linux Foundation. All rights reserved. 3 * 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #ifndef _TARGET_IF_SPECTRAL_H_ 21 #define _TARGET_IF_SPECTRAL_H_ 22 23 #include <wlan_objmgr_cmn.h> 24 #include <wlan_objmgr_psoc_obj.h> 25 #include <wlan_objmgr_pdev_obj.h> 26 #include <wlan_objmgr_vdev_obj.h> 27 #include <qdf_lock.h> 28 #include <wlan_spectral_public_structs.h> 29 #include <reg_services_public_struct.h> 30 #ifdef DIRECT_BUF_RX_ENABLE 31 #include <target_if_direct_buf_rx_api.h> 32 #endif 33 #ifdef WIN32 34 #pragma pack(push, target_if_spectral, 1) 35 #define __ATTRIB_PACK 36 #else 37 #ifndef __ATTRIB_PACK 38 #define __ATTRIB_PACK __attribute__ ((packed)) 39 #endif 40 #endif 41 42 #define spectral_log(level, args...) \ 43 QDF_PRINT_INFO(QDF_PRINT_IDX_SHARED, QDF_MODULE_ID_SPECTRAL, level, ## args) 44 45 #define spectral_logfl(level, format, args...) \ 46 spectral_log(level, FL(format), ## args) 47 48 #define spectral_fatal(format, args...) \ 49 spectral_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) 50 #define spectral_err(format, args...) \ 51 spectral_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) 52 #define spectral_warn(format, args...) \ 53 spectral_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) 54 #define spectral_info(format, args...) \ 55 spectral_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) 56 #define spectral_debug(format, args...) \ 57 spectral_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) 58 59 #define STATUS_PASS 1 60 #define STATUS_FAIL 0 61 #undef spectral_dbg_line 62 #define spectral_dbg_line() \ 63 spectral_debug("----------------------------------------------------\n") 64 65 #undef spectral_ops_not_registered 66 #define spectral_ops_not_registered(str) \ 67 spectral_info("SPECTRAL : %s not registered\n", (str)) 68 #undef not_yet_implemented 69 #define not_yet_implemented() \ 70 spectral_info("SPECTRAL : %s : %d Not yet implemented\n", \ 71 __func__, __LINE__) 72 73 #define SPECTRAL_HT20_NUM_BINS 56 74 #define SPECTRAL_HT20_FFT_LEN 56 75 #define SPECTRAL_HT20_DC_INDEX (SPECTRAL_HT20_FFT_LEN / 2) 76 #define SPECTRAL_HT20_DATA_LEN 60 77 #define SPECTRAL_HT20_TOTAL_DATA_LEN (SPECTRAL_HT20_DATA_LEN + 3) 78 #define SPECTRAL_HT40_TOTAL_NUM_BINS 128 79 #define SPECTRAL_HT40_DATA_LEN 135 80 #define SPECTRAL_HT40_TOTAL_DATA_LEN (SPECTRAL_HT40_DATA_LEN + 3) 81 #define SPECTRAL_HT40_FFT_LEN 128 82 #define SPECTRAL_HT40_DC_INDEX (SPECTRAL_HT40_FFT_LEN / 2) 83 84 /* 85 * Used for the SWAR to obtain approximate combined rssi 86 * in secondary 80Mhz segment 87 */ 88 #define OFFSET_CH_WIDTH_20 65 89 #define OFFSET_CH_WIDTH_40 62 90 #define OFFSET_CH_WIDTH_80 56 91 #define OFFSET_CH_WIDTH_160 50 92 93 #ifdef BIG_ENDIAN_HOST 94 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) do { \ 95 int j; \ 96 uint32_t *src, *dest; \ 97 src = (uint32_t *)(srcp); \ 98 dest = (uint32_t *)(destp); \ 99 for (j = 0; j < roundup((len), sizeof(uint32_t)) / 4; j++) { \ 100 *(dest + j) = qdf_le32_to_cpu(*(src + j)); \ 101 } \ 102 } while (0) 103 #else 104 #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) \ 105 OS_MEMCPY((destp), (srcp), (len)); 106 #endif 107 108 #define DUMMY_NF_VALUE (-123) 109 /* 5 categories x (lower + upper) bands */ 110 #define MAX_INTERF 10 111 #define HOST_MAX_ANTENNA 3 112 /* Mask for time stamp from descriptor */ 113 #define SPECTRAL_TSMASK 0xFFFFFFFF 114 #define SPECTRAL_SIGNATURE 0xdeadbeef 115 116 /* START of spectral GEN II HW specific details */ 117 #define SPECTRAL_PHYERR_SIGNATURE_GEN2 0xbb 118 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2 0xF9 119 #define TLV_TAG_ADC_REPORT_GEN2 0xFA 120 #define TLV_TAG_SEARCH_FFT_REPORT_GEN2 0xFB 121 122 /** 123 * struct spectral_search_fft_info_gen2 - spectral search fft report for gen2 124 * @relpwr_db: Total bin power in db 125 * @num_str_bins_ib: Number of strong bins 126 * @base_pwr: Base power 127 * @total_gain_info: Total gain 128 * @fft_chn_idx: FFT chain on which report is originated 129 * @avgpwr_db: Average power in db 130 * @peak_mag: Peak power seen in the bins 131 * @peak_inx: Index of bin holding peak power 132 */ 133 struct spectral_search_fft_info_gen2 { 134 uint32_t relpwr_db; 135 uint32_t num_str_bins_ib; 136 uint32_t base_pwr; 137 uint32_t total_gain_info; 138 uint32_t fft_chn_idx; 139 uint32_t avgpwr_db; 140 uint32_t peak_mag; 141 int16_t peak_inx; 142 }; 143 144 /* 145 * XXX Check if we should be handling the endinness difference in some 146 * other way opaque to the host 147 */ 148 #ifdef BIG_ENDIAN_HOST 149 150 /** 151 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for big endian host 152 * @signature: signature 153 * @tag: tag 154 * @length: length 155 */ 156 struct spectral_phyerr_tlv_gen2 { 157 uint8_t signature; 158 uint8_t tag; 159 uint16_t length; 160 } __ATTRIB_PACK; 161 162 #else 163 164 /** 165 * struct spectral_phyerr_tlv_gen2 - phyerr tlv info for little endian host 166 * @length: length 167 * @tag: tag 168 * @signature: signature 169 */ 170 struct spectral_phyerr_tlv_gen2 { 171 uint16_t length; 172 uint8_t tag; 173 uint8_t signature; 174 } __ATTRIB_PACK; 175 176 #endif /* BIG_ENDIAN_HOST */ 177 178 /** 179 * struct spectral_phyerr_hdr_gen2 - phyerr header for gen2 HW 180 * @hdr_a: Header[0:31] 181 * @hdr_b: Header[32:63] 182 */ 183 struct spectral_phyerr_hdr_gen2 { 184 uint32_t hdr_a; 185 uint32_t hdr_b; 186 }; 187 188 /* 189 * Segment ID information for 80+80. 190 * 191 * If the HW micro-architecture specification extends this DWORD for other 192 * purposes, then redefine+rename accordingly. For now, the specification 193 * mentions only segment ID (though this doesn't require an entire DWORD) 194 * without mention of any generic terminology for the DWORD, or any reservation. 195 * We use nomenclature accordingly. 196 */ 197 typedef uint32_t SPECTRAL_SEGID_INFO; 198 199 /** 200 * struct spectral_phyerr_fft_gen2 - fft info in phyerr event 201 * @buf: fft report 202 */ 203 struct spectral_phyerr_fft_gen2 { 204 uint8_t buf[0]; 205 }; 206 /* END of spectral GEN II HW specific details */ 207 208 /* START of spectral GEN III HW specific details */ 209 210 #define get_bitfield(value, size, pos) \ 211 (((value) >> (pos)) & ((1 << (size)) - 1)) 212 #define unsigned_to_signed(value, width) \ 213 (((value) >= (1 << ((width) - 1))) ? \ 214 (value - (1 << (width))) : (value)) 215 216 #define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) 217 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) 218 #define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) 219 #define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) 220 221 #define PHYERR_HDR_SIG_POS \ 222 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig)) 223 #define PHYERR_HDR_TAG_POS \ 224 (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_tag)) 225 #define SPECTRAL_FFT_BINS_POS \ 226 (offsetof(struct spectral_phyerr_fft_report_gen3, buf)) 227 228 /** 229 * struct phyerr_info - spectral search fft report for gen3 230 * @data: handle to phyerror buffer 231 * @datalen: length of phyerror bufer 232 * @p_rfqual: rf quality matrices 233 * @p_chaninfo: pointer to chaninfo 234 * @tsf64: 64 bit TSF 235 * @acs_stats: acs stats 236 */ 237 struct phyerr_info { 238 uint8_t *data; 239 uint32_t datalen; 240 struct target_if_spectral_rfqual_info *p_rfqual; 241 struct target_if_spectral_chan_info *p_chaninfo; 242 uint64_t tsf64; 243 struct target_if_spectral_acs_stats *acs_stats; 244 }; 245 246 /** 247 * struct spectral_search_fft_info_gen3 - spectral search fft report for gen3 248 * @timestamp: Timestamp at which fft report was generated 249 * @fft_detector_id: Which radio generated this report 250 * @fft_num: The FFT count number. Set to 0 for short FFT. 251 * @fft_radar_check: NA for spectral 252 * @fft_peak_sidx: Index of bin with maximum power 253 * @fft_chn_idx: Rx chain index 254 * @fft_base_pwr_db: Base power in dB 255 * @fft_total_gain_db: Total gain in dB 256 * @fft_num_str_bins_ib: Number of strong bins in the report 257 * @fft_peak_mag: Peak magnitude 258 * @fft_avgpwr_db: Average power in dB 259 * @fft_relpwr_db: Relative power in dB 260 */ 261 struct spectral_search_fft_info_gen3 { 262 uint32_t timestamp; 263 uint32_t fft_detector_id; 264 uint32_t fft_num; 265 uint32_t fft_radar_check; 266 int32_t fft_peak_sidx; 267 uint32_t fft_chn_idx; 268 uint32_t fft_base_pwr_db; 269 uint32_t fft_total_gain_db; 270 uint32_t fft_num_str_bins_ib; 271 int32_t fft_peak_mag; 272 uint32_t fft_avgpwr_db; 273 uint32_t fft_relpwr_db; 274 }; 275 276 /** 277 * struct spectral_phyerr_sfftreport_gen3 - fft info in phyerr event 278 * @fft_timestamp: Timestamp at which fft report was generated 279 * @fft_hdr_sig: signature 280 * @fft_hdr_tag: tag 281 * @fft_hdr_length: length 282 * @hdr_a: Header[0:31] 283 * @hdr_b: Header[32:63] 284 * @hdr_c: Header[64:95] 285 * @resv: Header[96:127] 286 * @buf: fft bins 287 */ 288 struct spectral_phyerr_fft_report_gen3 { 289 uint32_t fft_timestamp; 290 #ifdef BIG_ENDIAN_HOST 291 uint8_t fft_hdr_sig; 292 uint8_t fft_hdr_tag; 293 uint16_t fft_hdr_length; 294 #else 295 uint16_t fft_hdr_length; 296 uint8_t fft_hdr_tag; 297 uint8_t fft_hdr_sig; 298 #endif /* BIG_ENDIAN_HOST */ 299 uint32_t hdr_a; 300 uint32_t hdr_b; 301 uint32_t hdr_c; 302 uint32_t resv; 303 uint8_t buf[0]; 304 } __ATTRIB_PACK; 305 306 /** 307 * struct spectral_sscan_report_gen3 - spectral report in phyerr event 308 * @sscan_timestamp: Timestamp at which fft report was generated 309 * @sscan_hdr_sig: signature 310 * @sscan_hdr_tag: tag 311 * @sscan_hdr_length: length 312 * @hdr_a: Header[0:31] 313 * @resv: Header[32:63] 314 * @hdr_b: Header[64:95] 315 * @resv: Header[96:127] 316 */ 317 struct spectral_sscan_report_gen3 { 318 u_int32_t sscan_timestamp; 319 #ifdef BIG_ENDIAN_HOST 320 u_int8_t sscan_hdr_sig; 321 u_int8_t sscan_hdr_tag; 322 u_int16_t sscan_hdr_length; 323 #else 324 u_int16_t sscan_hdr_length; 325 u_int8_t sscan_hdr_tag; 326 u_int8_t sscan_hdr_sig; 327 #endif /* BIG_ENDIAN_HOST */ 328 u_int32_t hdr_a; 329 u_int32_t res1; 330 u_int32_t hdr_b; 331 u_int32_t res2; 332 } __ATTRIB_PACK; 333 /* END of spectral GEN III HW specific details */ 334 335 typedef signed char pwr_dbm; 336 337 /** 338 * enum spectral_gen - spectral hw generation 339 * @SPECTRAL_GEN1 : spectral hw gen 1 340 * @SPECTRAL_GEN2 : spectral hw gen 2 341 * @SPECTRAL_GEN3 : spectral hw gen 3 342 */ 343 enum spectral_gen { 344 SPECTRAL_GEN1, 345 SPECTRAL_GEN2, 346 SPECTRAL_GEN3, 347 }; 348 349 #if ATH_PERF_PWR_OFFLOAD 350 /** 351 * enum target_if_spectral_info - Enumerations for specifying which spectral 352 * information (among parameters and states) 353 * is desired. 354 * @TARGET_IF_SPECTRAL_INFO_ACTIVE: Indicated whether spectral is active 355 * @TARGET_IF_SPECTRAL_INFO_ENABLED: Indicated whether spectral is enabled 356 * @TARGET_IF_SPECTRAL_INFO_PARAMS: Config params 357 */ 358 enum target_if_spectral_info { 359 TARGET_IF_SPECTRAL_INFO_ACTIVE, 360 TARGET_IF_SPECTRAL_INFO_ENABLED, 361 TARGET_IF_SPECTRAL_INFO_PARAMS, 362 }; 363 #endif /* ATH_PERF_PWR_OFFLOAD */ 364 365 /* forward declaration */ 366 struct target_if_spectral; 367 368 /** 369 * struct target_if_spectral_chan_info - Channel information 370 * @center_freq1: center frequency 1 in MHz 371 * @center_freq2: center frequency 2 in MHz -valid only for 372 * 11ACVHT 80PLUS80 mode 373 * @chan_width: channel width in MHz 374 */ 375 struct target_if_spectral_chan_info { 376 uint16_t center_freq1; 377 uint16_t center_freq2; 378 uint8_t chan_width; 379 }; 380 381 /** 382 * struct target_if_spectral_acs_stats - EACS stats from spectral samples 383 * @nfc_ctl_rssi: Control chan rssi 384 * @nfc_ext_rssi: Extension chan rssi 385 * @ctrl_nf: Control chan Noise Floor 386 * @ext_nf: Extension chan Noise Floor 387 */ 388 struct target_if_spectral_acs_stats { 389 int8_t nfc_ctl_rssi; 390 int8_t nfc_ext_rssi; 391 int8_t ctrl_nf; 392 int8_t ext_nf; 393 }; 394 395 /** 396 * struct target_if_spectral_perchain_rssi_info - per chain rssi info 397 * @rssi_pri20: Rssi of primary 20 Mhz 398 * @rssi_sec20: Rssi of secondary 20 Mhz 399 * @rssi_sec40: Rssi of secondary 40 Mhz 400 * @rssi_sec80: Rssi of secondary 80 Mhz 401 */ 402 struct target_if_spectral_perchain_rssi_info { 403 int8_t rssi_pri20; 404 int8_t rssi_sec20; 405 int8_t rssi_sec40; 406 int8_t rssi_sec80; 407 }; 408 409 /** 410 * struct target_if_spectral_rfqual_info - RF measurement information 411 * @rssi_comb: RSSI Information 412 * @pc_rssi_info: XXX : For now, we know we are getting information 413 * for only 4 chains at max. For future extensions 414 * use a define 415 * @noise_floor: Noise floor information 416 */ 417 struct target_if_spectral_rfqual_info { 418 int8_t rssi_comb; 419 struct target_if_spectral_perchain_rssi_info pc_rssi_info[4]; 420 int16_t noise_floor[4]; 421 }; 422 423 #define GET_TARGET_IF_SPECTRAL_OPS(spectral) \ 424 ((struct target_if_spectral_ops *)(&((spectral)->spectral_ops))) 425 426 /** 427 * struct target_if_spectral_ops - spectral low level ops table 428 * @get_tsf64: Get 64 bit TSF value 429 * @get_capability: Get capability info 430 * @set_rxfilter: Set rx filter 431 * @get_rxfilter: Get rx filter 432 * @is_spectral_active: Check whether icm is active 433 * @is_spectral_enabled: Check whether spectral is enabled 434 * @start_spectral_scan: Start spectral scan 435 * @stop_spectral_scan: Stop spectral scan 436 * @get_extension_channel: Get extension channel 437 * @get_ctl_noisefloor: Get control noise floor 438 * @get_ext_noisefloor: Get extension noise floor 439 * @configure_spectral: Set spectral configurations 440 * @get_spectral_config: Get spectral configurations 441 * @get_ent_spectral_mask: Get spectral mask 442 * @get_mac_address: Get mac address 443 * @get_current_channel: Get current channel 444 * @reset_hw: Reset HW 445 * @get_chain_noise_floor: Get Channel noise floor 446 * @spectral_process_phyerr: Process phyerr event 447 * @process_spectral_report: Process spectral report 448 */ 449 struct target_if_spectral_ops { 450 uint64_t (*get_tsf64)(void *arg); 451 uint32_t (*get_capability)( 452 void *arg, enum spectral_capability_type type); 453 uint32_t (*set_rxfilter)(void *arg, int rxfilter); 454 uint32_t (*get_rxfilter)(void *arg); 455 uint32_t (*is_spectral_active)(void *arg); 456 uint32_t (*is_spectral_enabled)(void *arg); 457 uint32_t (*start_spectral_scan)(void *arg); 458 uint32_t (*stop_spectral_scan)(void *arg); 459 uint32_t (*get_extension_channel)(void *arg); 460 int8_t (*get_ctl_noisefloor)(void *arg); 461 int8_t (*get_ext_noisefloor)(void *arg); 462 uint32_t (*configure_spectral)( 463 void *arg, 464 struct spectral_config *params); 465 uint32_t (*get_spectral_config)( 466 void *arg, 467 struct spectral_config *params); 468 uint32_t (*get_ent_spectral_mask)(void *arg); 469 uint32_t (*get_mac_address)(void *arg, char *addr); 470 uint32_t (*get_current_channel)(void *arg); 471 uint32_t (*reset_hw)(void *arg); 472 uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf); 473 int (*spectral_process_phyerr)(struct target_if_spectral *spectral, 474 uint8_t *data, uint32_t datalen, 475 struct target_if_spectral_rfqual_info *p_rfqual, 476 struct target_if_spectral_chan_info *p_chaninfo, 477 uint64_t tsf64, 478 struct target_if_spectral_acs_stats *acs_stats); 479 int (*process_spectral_report)(struct wlan_objmgr_pdev *pdev, 480 void *payload); 481 }; 482 483 /** 484 * struct target_if_spectral_stats - spectral stats info 485 * @num_spectral_detects: Total num. of spectral detects 486 * @total_phy_errors: Total number of phyerrors 487 * @owl_phy_errors: Indicated phyerrors in old gen1 chipsets 488 * @pri_phy_errors: Phyerrors in primary channel 489 * @ext_phy_errors: Phyerrors in secondary channel 490 * @dc_phy_errors: Phyerrors due to dc 491 * @early_ext_phy_errors: Early secondary channel phyerrors 492 * @bwinfo_errors: Bandwidth info errors 493 * @datalen_discards: Invalid data length errors, seen in gen1 chipsets 494 * @rssi_discards bw: Indicates reports dropped due to RSSI threshold 495 * @last_reset_tstamp: Last reset time stamp 496 */ 497 struct target_if_spectral_stats { 498 uint32_t num_spectral_detects; 499 uint32_t total_phy_errors; 500 uint32_t owl_phy_errors; 501 uint32_t pri_phy_errors; 502 uint32_t ext_phy_errors; 503 uint32_t dc_phy_errors; 504 uint32_t early_ext_phy_errors; 505 uint32_t bwinfo_errors; 506 uint32_t datalen_discards; 507 uint32_t rssi_discards; 508 uint64_t last_reset_tstamp; 509 }; 510 511 /** 512 * struct target_if_spectral_event - spectral event structure 513 * @se_ts: Original 15 bit recv timestamp 514 * @se_full_ts: 64-bit full timestamp from interrupt time 515 * @se_rssi: Rssi of spectral event 516 * @se_bwinfo: Rssi of spectral event 517 * @se_dur: Duration of spectral pulse 518 * @se_chanindex: Channel of event 519 * @se_list: List of spectral events 520 */ 521 struct target_if_spectral_event { 522 uint32_t se_ts; 523 uint64_t se_full_ts; 524 uint8_t se_rssi; 525 uint8_t se_bwinfo; 526 uint8_t se_dur; 527 uint8_t se_chanindex; 528 529 STAILQ_ENTRY(spectral_event) se_list; 530 }; 531 532 /** 533 * struct target_if_chain_noise_pwr_info - Noise power info for each channel 534 * @rptcount: Count of reports in pwr array 535 * @un_cal_nf: Uncalibrated noise floor 536 * @factory_cal_nf: Noise floor as calibrated at the factory for module 537 * @median_pwr: Median power (median of pwr array) 538 * @pwr: Power reports 539 */ 540 struct target_if_chain_noise_pwr_info { 541 int rptcount; 542 pwr_dbm un_cal_nf; 543 pwr_dbm factory_cal_nf; 544 pwr_dbm median_pwr; 545 pwr_dbm pwr[]; 546 } __ATTRIB_PACK; 547 548 /** 549 * struct target_if_spectral_chan_stats - Channel information 550 * @cycle_count: Cycle count 551 * @channel_load: Channel load 552 * @per: Period 553 * @noisefloor: Noise floor 554 * @comp_usablity: Computed usability 555 * @maxregpower: Maximum allowed regulatary power 556 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 557 * @maxregpower_sec80: Max regulatory power in secondary 80 Mhz 558 */ 559 struct target_if_spectral_chan_stats { 560 int cycle_count; 561 int channel_load; 562 int per; 563 int noisefloor; 564 uint16_t comp_usablity; 565 int8_t maxregpower; 566 uint16_t comp_usablity_sec80; 567 int8_t maxregpower_sec80; 568 }; 569 570 #if ATH_PERF_PWR_OFFLOAD 571 572 /** 573 * struct target_if_spectral_cache - Cache used to minimize WMI operations 574 * in offload architecture 575 * @osc_spectral_enabled: Whether Spectral is enabled 576 * @osc_spectral_active: Whether spectral is active 577 * XXX: Ideally, we should NOT cache this 578 * since the hardware can self clear the bit, 579 * the firmware can possibly stop spectral due to 580 * intermittent off-channel activity, etc 581 * A WMI read command should be introduced to handle 582 * this This will be discussed. 583 * @osc_params: Spectral parameters 584 * @osc_is_valid: Whether the cache is valid 585 */ 586 struct target_if_spectral_cache { 587 uint8_t osc_spectral_enabled; 588 uint8_t osc_spectral_active; 589 struct spectral_config osc_params; 590 uint8_t osc_is_valid; 591 }; 592 593 /** 594 * struct target_if_spectral_param_state_info - Structure used to represent and 595 * manage spectral information 596 * (parameters and states) 597 * @osps_lock: Lock to synchronize accesses to information 598 * @osps_cache: Cacheable' information 599 */ 600 struct target_if_spectral_param_state_info { 601 qdf_spinlock_t osps_lock; 602 struct target_if_spectral_cache osps_cache; 603 /* XXX - Non-cacheable information goes here, in the future */ 604 }; 605 #endif /* ATH_PERF_PWR_OFFLOAD */ 606 607 struct vdev_spectral_configure_params; 608 struct vdev_spectral_enable_params; 609 610 /** 611 * struct wmi_spectral_cmd_ops - structure used holding the operations 612 * related to wmi commands on spectral parameters. 613 * @wmi_spectral_configure_cmd_send: 614 * @wmi_spectral_enable_cmd_send: 615 */ 616 struct wmi_spectral_cmd_ops { 617 QDF_STATUS (*wmi_spectral_configure_cmd_send)( 618 void *wmi_hdl, 619 struct vdev_spectral_configure_params *param); 620 QDF_STATUS (*wmi_spectral_enable_cmd_send)( 621 void *wmi_hdl, 622 struct vdev_spectral_enable_params *param); 623 }; 624 625 /** 626 * struct target_if_spectral - main spectral structure 627 * @pdev: Pointer to pdev 628 * @spectral_ops: Target if internal Spectral low level operations table 629 * @capability: Spectral capabilities structure 630 * @spectral_lock: Lock used for internal Spectral operations 631 * @spectral_curchan_radindex: Current channel spectral index 632 * @spectral_extchan_radindex: Extension channel spectral index 633 * @spectraldomain: Current Spectral domain 634 * @spectral_proc_phyerr: Flags to process for PHY errors 635 * @spectral_defaultparams: Default PHY params per Spectral stat 636 * @spectral_stats: Spectral related stats 637 * @events: Events structure 638 * @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel? 639 * @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI? 640 * @sc_spectral_20_40_mode: Is AP in 20-40 mode? 641 * @sc_spectral_noise_pwr_cal: Noise power cal required? 642 * @sc_spectral_non_edma: Is the spectral capable device Non-EDMA? 643 * @upper_is_control: Upper segment is primary 644 * @upper_is_extension: Upper segment is secondary 645 * @lower_is_control: Lower segment is primary 646 * @lower_is_extension: Lower segment is secondary 647 * @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral 648 * mute test 649 * @spectral_numbins: Number of bins 650 * @spectral_fft_len: FFT length 651 * @spectral_data_len: Total phyerror report length 652 * @lb_edge_extrabins: Number of extra bins on left band edge 653 * @rb_edge_extrabins: Number of extra bins on right band edge 654 * @spectral_max_index_offset: Max FFT index offset (20 MHz mode) 655 * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode) 656 * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode) 657 * @spectral_dc_index: At which index DC is present 658 * @send_single_packet: Deprecated 659 * @spectral_sent_msg: Indicates whether we send report to upper layers 660 * @params: Spectral parameters 661 * @last_capture_time: Indicates timestamp of previouse report 662 * @num_spectral_data: Number of Spectral samples received in current session 663 * @total_spectral_data: Total number of Spectral samples received 664 * @max_rssi: Maximum RSSI 665 * @detects_control_channel: NA 666 * @detects_extension_channel: NA 667 * @detects_below_dc: NA 668 * @detects_above_dc: NA 669 * @sc_scanning: Indicates active wifi scan 670 * @sc_spectral_scan: Indicates active specral scan 671 * @sc_spectral_full_scan: Deprecated 672 * @scan_start_tstamp: Deprecated 673 * @last_tstamp: Deprecated 674 * @first_tstamp: Deprecated 675 * @spectral_samp_count: Deprecated 676 * @sc_spectral_samp_count: Deprecated 677 * @noise_pwr_reports_reqd: Number of noise power reports required 678 * @noise_pwr_reports_recv: Number of noise power reports received 679 * @noise_pwr_reports_lock: Lock used for Noise power report processing 680 * @noise_pwr_chain_ctl: Noise power report - control channel 681 * @noise_pwr_chain_ext: Noise power report - extension channel 682 * @chaninfo: Channel statistics 683 * @tsf64: Latest TSF Value 684 * @param_info: Offload architecture Spectral parameter cache information 685 * @ch_width: Indicates Channel Width 20/40/80/160 MHz with values 0, 1, 2, 3 686 * respectively 687 * @diag_stats: Diagnostic statistics 688 * @is_160_format: Indicates whether information provided by HW is in altered 689 * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) 690 * @is_lb_edge_extrabins_format: Indicates whether information provided by 691 * HW has 4 extra bins, at left band edge, for report mode 2 692 * @is_rb_edge_extrabins_format: Indicates whether information provided 693 * by HW has 4 extra bins, at right band edge, for report mode 2 694 * @is_sec80_rssi_war_required: Indicates whether the software workaround is 695 * required to obtain approximate combined RSSI for secondary 80Mhz segment 696 * @simctx: Spectral Simulation context 697 * @spectral_gen: Spectral hardware generation 698 * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware 699 * generation 700 * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV 701 * header, for the given hardware generation 702 * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV 703 * header, for the given hardware generation 704 * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware 705 * generation 706 * @nl_cb: Netlink callbacks 707 * @use_nl_bcast: Whether to use Netlink broadcast/unicast 708 * @send_phy_data: Send data to the applicaton layer 709 * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for 710 * in-band report format. This would be required on some chipsets under the 711 * following circumstances: In report mode 2 only the in-band bins are DMA'ed. 712 * Scatter/gather is used. However, the HW generates all bins, not just in-band, 713 * and reports the number of bins accordingly. The subsystem arranging for the 714 * DMA cannot change this value. On such chipsets the adjustment required at the 715 * host driver is to check if report format is 2, and if so halve the number of 716 * bins reported to get the number actually DMA'ed. 717 */ 718 struct target_if_spectral { 719 struct wlan_objmgr_pdev *pdev_obj; 720 struct target_if_spectral_ops spectral_ops; 721 struct spectral_caps capability; 722 qdf_spinlock_t spectral_lock; 723 int16_t spectral_curchan_radindex; 724 int16_t spectral_extchan_radindex; 725 uint32_t spectraldomain; 726 uint32_t spectral_proc_phyerr; 727 struct spectral_config spectral_defaultparams; 728 struct target_if_spectral_stats spectral_stats; 729 struct target_if_spectral_event *events; 730 unsigned int sc_spectral_ext_chan_ok:1, 731 sc_spectral_combined_rssi_ok:1, 732 sc_spectral_20_40_mode:1, 733 sc_spectral_noise_pwr_cal:1, 734 sc_spectral_non_edma:1; 735 int upper_is_control; 736 int upper_is_extension; 737 int lower_is_control; 738 int lower_is_extension; 739 uint8_t sc_spectraltest_ieeechan; 740 int spectral_numbins; 741 int spectral_fft_len; 742 int spectral_data_len; 743 744 /* 745 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are 746 * delivered. However, there can be additional bins reported for 747 * AR900B version 2.0 and QCA9984 as described next: 748 * 749 * AR900B version 2.0: An additional tone is processed on the right 750 * hand side in order to facilitate detection of radar pulses out to 751 * the extreme band-edge of the channel frequency. Since the HW design 752 * processes four tones at a time, this requires one additional Dword 753 * to be added to the search FFT report. 754 * 755 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary + 756 * 1x-oversampled bins (in-band) per FFT, then 8 more bins 757 * (4 more on left side and 4 more on right side)are added. 758 */ 759 760 int lb_edge_extrabins; 761 int rb_edge_extrabins; 762 int spectral_max_index_offset; 763 int spectral_upper_max_index_offset; 764 int spectral_lower_max_index_offset; 765 int spectral_dc_index; 766 int send_single_packet; 767 int spectral_sent_msg; 768 int classify_scan; 769 os_timer_t classify_timer; 770 struct spectral_config params; 771 struct spectral_classifier_params classifier_params; 772 int last_capture_time; 773 int num_spectral_data; 774 int total_spectral_data; 775 int max_rssi; 776 int detects_control_channel; 777 int detects_extension_channel; 778 int detects_below_dc; 779 int detects_above_dc; 780 int sc_scanning; 781 int sc_spectral_scan; 782 int sc_spectral_full_scan; 783 uint64_t scan_start_tstamp; 784 uint32_t last_tstamp; 785 uint32_t first_tstamp; 786 uint32_t spectral_samp_count; 787 uint32_t sc_spectral_samp_count; 788 int noise_pwr_reports_reqd; 789 int noise_pwr_reports_recv; 790 qdf_spinlock_t noise_pwr_reports_lock; 791 struct target_if_chain_noise_pwr_info 792 *noise_pwr_chain_ctl[HOST_MAX_ANTENNA]; 793 struct target_if_chain_noise_pwr_info 794 *noise_pwr_chain_ext[HOST_MAX_ANTENNA]; 795 uint64_t tsf64; 796 #if ATH_PERF_PWR_OFFLOAD 797 struct target_if_spectral_param_state_info param_info; 798 #endif 799 uint32_t ch_width; 800 struct spectral_diag_stats diag_stats; 801 bool is_160_format; 802 bool is_lb_edge_extrabins_format; 803 bool is_rb_edge_extrabins_format; 804 bool is_sec80_rssi_war_required; 805 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 806 void *simctx; 807 #endif 808 enum spectral_gen spectral_gen; 809 uint8_t hdr_sig_exp; 810 uint8_t tag_sscan_summary_exp; 811 uint8_t tag_sscan_fft_exp; 812 uint8_t tlvhdr_size; 813 struct wmi_spectral_cmd_ops param_wmi_cmd_ops; 814 struct spectral_nl_cb nl_cb; 815 bool use_nl_bcast; 816 int (*send_phy_data)(struct wlan_objmgr_pdev *pdev); 817 u_int8_t fftbin_size_war; 818 u_int8_t inband_fftbin_size_adj; 819 }; 820 821 /** 822 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 823 * data format 824 * @rssi: RSSI (except for secondary 80 segment) 825 * @rssi_sec80: RSSI for secondary 80 segment 826 * @lower_rssi: RSSI of lower band 827 * @upper_rssi: RSSI of upper band 828 * @chain_ctl_rssi: RSSI for control channel, for all antennas 829 * @chain_ext_rssi: RSSI for extension channel, for all antennas 830 * @bwinfo: bandwidth info 831 * @data_len: length of FFT data (except for secondary 80 segment) 832 * @data_len_sec80: length of FFT data for secondary 80 segment 833 * @tstamp: timestamp 834 * @last_tstamp: last time stamp 835 * @max_mag: maximum magnitude (except for secondary 80 segment) 836 * @max_mag_sec80: maximum magnitude for secondary 80 segment 837 * @max_index: index of max magnitude (except for secondary 80 segment) 838 * @max_index_sec80: index of max magnitude for secondary 80 segment 839 * @max_exp: max exp 840 * @peak: peak frequency (obsolete) 841 * @pwr_count: number of FFT bins (except for secondary 80 segment) 842 * @pwr_count_sec80: number of FFT bins in secondary 80 segment 843 * @nb_lower: This is deprecated 844 * @nb_upper: This is deprecated 845 * @max_upper_index: index of max mag in upper band 846 * @max_lower_index: index of max mag in lower band 847 * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment) 848 * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment 849 * @freq: Center frequency of primary 20MHz channel in MHz 850 * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz 851 * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz 852 * @freq_loading: spectral control duty cycles 853 * @noise_floor: current noise floor (except for secondary 80 segment) 854 * @noise_floor_sec80: current noise floor for secondary 80 segment 855 * @interf_list: List of interfernce sources 856 * @classifier_params: classifier parameters 857 * @sc: classifier parameters 858 */ 859 struct target_if_samp_msg_params { 860 int8_t rssi; 861 int8_t rssi_sec80; 862 int8_t lower_rssi; 863 int8_t upper_rssi; 864 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 865 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 866 uint16_t bwinfo; 867 uint16_t datalen; 868 uint16_t datalen_sec80; 869 uint32_t tstamp; 870 uint32_t last_tstamp; 871 uint16_t max_mag; 872 uint16_t max_mag_sec80; 873 uint16_t max_index; 874 uint16_t max_index_sec80; 875 uint8_t max_exp; 876 int peak; 877 int pwr_count; 878 int pwr_count_sec80; 879 int8_t nb_lower; 880 int8_t nb_upper; 881 uint16_t max_lower_index; 882 uint16_t max_upper_index; 883 uint8_t *bin_pwr_data; 884 uint8_t *bin_pwr_data_sec80; 885 uint16_t freq; 886 uint16_t vhtop_ch_freq_seg1; 887 uint16_t vhtop_ch_freq_seg2; 888 uint16_t freq_loading; 889 int16_t noise_floor; 890 int16_t noise_floor_sec80; 891 struct interf_src_rsp interf_list; 892 struct spectral_classifier_params classifier_params; 893 struct ath_softc *sc; 894 }; 895 896 /** 897 * target_if_spectral_dump_fft() - Dump Spectral FFT 898 * @pfft: Pointer to Spectral Phyerr FFT 899 * @fftlen: FFT length 900 * 901 * Return: Success or failure 902 */ 903 int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen); 904 905 /** 906 * target_if_dbg_print_samp_param() - Print contents of SAMP struct 907 * @p: Pointer to SAMP message 908 * 909 * Return: Void 910 */ 911 void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p); 912 913 /** 914 * target_if_get_offset_swar_sec80() - Get offset for SWAR according to 915 * the channel width 916 * @channel_width: Channel width 917 * 918 * Return: Offset for SWAR 919 */ 920 uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width); 921 922 /** 923 * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops 924 * @tx_ops: Tx Ops 925 * 926 * Return: void 927 */ 928 void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); 929 930 /** 931 * target_if_spectral_create_samp_msg() - Create the spectral samp message 932 * @spectral : Pointer to spectral internal structure 933 * @params : spectral samp message parameters 934 * 935 * API to create the spectral samp message 936 * 937 * Return: void 938 */ 939 void target_if_spectral_create_samp_msg( 940 struct target_if_spectral *spectral, 941 struct target_if_samp_msg_params *params); 942 943 /** 944 * target_if_spectral_process_phyerr_gen3() - Process phyerror event for gen3 945 * @pdev: Pointer to pdev object 946 * @payload: Pointer to spectral report 947 * 948 * Process phyerror event for gen3 949 * 950 * Return: Success/Failure 951 */ 952 int target_if_spectral_process_report_gen3( 953 struct wlan_objmgr_pdev *pdev, 954 void *buf); 955 956 /** 957 * target_if_process_phyerr_gen2() - Process PHY Error for gen2 958 * @spectral: Pointer to Spectral object 959 * @data: Pointer to phyerror event buffer 960 * @datalen: Data length 961 * @p_rfqual: RF quality info 962 * @p_chaninfo: Channel info 963 * @tsf64: 64 bit tsf timestamp 964 * @acs_stats: ACS stats 965 * 966 * Process PHY Error for gen2 967 * 968 * Return: Success/Failure 969 */ 970 int target_if_process_phyerr_gen2( 971 struct target_if_spectral *spectral, 972 uint8_t *data, 973 uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual, 974 struct target_if_spectral_chan_info *p_chaninfo, 975 uint64_t tsf64, 976 struct target_if_spectral_acs_stats *acs_stats); 977 978 /** 979 * target_if_spectral_send_intf_found_msg() - Indicate to application layer that 980 * interference has been found 981 * @pdev: Pointer to pdev 982 * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found 983 * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled 984 * 985 * Send message to application layer 986 * indicating that interference has been found 987 * 988 * Return: None 989 */ 990 void target_if_spectral_send_intf_found_msg( 991 struct wlan_objmgr_pdev *pdev, 992 uint16_t cw_int, uint32_t dcs_enabled); 993 994 /** 995 * target_if_stop_spectral_scan() - Stop spectral scan 996 * @pdev: Pointer to pdev object 997 * 998 * API to stop the current on-going spectral scan 999 * 1000 * Return: None 1001 */ 1002 void target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev); 1003 1004 /** 1005 * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral 1006 * operations 1007 * @spectral: Pointer to Spectral target_if internal private data 1008 * 1009 * Spectral operates on pdev. However, in order to retrieve some WLAN 1010 * properties, a vdev is required. To facilitate this, the function returns the 1011 * first vdev in our pdev. The caller should release the reference to the vdev 1012 * once it is done using it. 1013 * TODO: If the framework later provides an API to obtain the first active 1014 * vdev, then it would be preferable to use this API. 1015 * 1016 * Return: Pointer to vdev on success, NULL on failure 1017 */ 1018 struct wlan_objmgr_vdev *target_if_spectral_get_vdev( 1019 struct target_if_spectral *spectral); 1020 1021 /** 1022 * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2 1023 * @phdr: Pointer to Spectral Phyerr Header 1024 * 1025 * Dump Spectral header 1026 * 1027 * Return: Success/Failure 1028 */ 1029 int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr); 1030 1031 /** 1032 * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI 1033 * for Secondary 80 segment 1034 * @spectral: Pointer to spectral object 1035 * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment 1036 * 1037 * Get approximate combined RSSI for Secondary 80 segment 1038 * 1039 * Return: Combined RSSI for secondary 80Mhz segment 1040 */ 1041 int8_t target_if_get_combrssi_sec80_seg_gen2( 1042 struct target_if_spectral *spectral, 1043 struct spectral_search_fft_info_gen2 *p_sfft_sec80); 1044 1045 /** 1046 * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2 1047 * @ptlv: Pointer to Spectral Phyerr TLV 1048 * @is_160_format: Indicates 160 format 1049 * 1050 * Dump Spectral TLV for gen2 1051 * 1052 * Return: Success/Failure 1053 */ 1054 int target_if_spectral_dump_tlv_gen2( 1055 struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format); 1056 1057 /** 1058 * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral 1059 * related PHY Error for gen2 1060 * @data: Pointer to phyerror buffer 1061 * @datalen: Data length 1062 * @is_160_format: Indicates 160 format 1063 * 1064 * Dump Spectral related PHY Error for gen2 1065 * 1066 * Return: Success/Failure 1067 */ 1068 int target_if_spectral_dump_phyerr_data_gen2( 1069 uint8_t *data, 1070 uint32_t datalen, 1071 bool is_160_format); 1072 1073 /** 1074 * target_if_dump_fft_report_gen3() - Dump FFT Report for gen3 1075 * @spectral: Pointer to Spectral object 1076 * @p_fft_report: Pointer to fft report 1077 * @p_sfft: Pointer to search fft report 1078 * 1079 * Dump FFT Report for gen3 1080 * 1081 * Return: Success/Failure 1082 */ 1083 int target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, 1084 struct spectral_phyerr_fft_report_gen3 *p_fft_report, 1085 struct spectral_search_fft_info_gen3 *p_sfft); 1086 1087 /** 1088 * target_if_dbg_print_samp_msg() - Print contents of SAMP Message 1089 * @p: Pointer to SAMP message 1090 * 1091 * Print contents of SAMP Message 1092 * 1093 * Return: Void 1094 */ 1095 void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); 1096 1097 /** 1098 * target_if_process_sfft_report_gen3() - Process Search FFT Report for gen3 1099 * @p_fft_report: Pointer to fft report 1100 * @p_sfft: Pointer to search fft report 1101 * 1102 * Process Search FFT Report for gen3 1103 * 1104 * Return: Success/Failure 1105 */ 1106 int target_if_process_sfft_report_gen3( 1107 struct spectral_phyerr_fft_report_gen3 *p_fft_report, 1108 struct spectral_search_fft_info_gen3 *p_fft_info); 1109 1110 /** 1111 * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal 1112 * Spectral data 1113 * @pdev: Pointer to pdev 1114 * 1115 * Return: Handle to target_if internal Spectral data on success, NULL on 1116 * failure 1117 */ 1118 static inline 1119 struct target_if_spectral *get_target_if_spectral_handle_from_pdev( 1120 struct wlan_objmgr_pdev *pdev) 1121 { 1122 struct target_if_spectral *spectral = NULL; 1123 struct wlan_objmgr_psoc *psoc = NULL; 1124 1125 psoc = wlan_pdev_get_psoc(pdev); 1126 1127 spectral = (struct target_if_spectral *) 1128 psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_get_target_handle( 1129 pdev); 1130 return spectral; 1131 } 1132 1133 /** 1134 * target_if_vdev_get_chan_freq() - Get the operating channel frequency of a 1135 * given vdev 1136 * @pdev: Pointer to vdev 1137 * 1138 * Get the operating channel frequency of a given vdev 1139 * 1140 * Return: Operating channel frequency of a vdev 1141 */ 1142 static inline 1143 int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) 1144 { 1145 struct wlan_objmgr_psoc *psoc = NULL; 1146 1147 psoc = wlan_vdev_get_psoc(vdev); 1148 if (!psoc) { 1149 spectral_err("psoc is NULL"); 1150 return -EINVAL; 1151 } 1152 1153 return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_chan_freq( 1154 vdev); 1155 } 1156 1157 /** 1158 * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a 1159 * given vdev 1160 * @pdev: Pointer to vdev 1161 * 1162 * Get the operating channel bandwidth of a given vdev 1163 * 1164 * Return: channel bandwidth enumeration corresponding to the vdev 1165 */ 1166 static inline 1167 enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) 1168 { 1169 struct wlan_objmgr_psoc *psoc = NULL; 1170 1171 psoc = wlan_vdev_get_psoc(vdev); 1172 if (!psoc) { 1173 spectral_err("psoc is NULL"); 1174 return CH_WIDTH_INVALID; 1175 } 1176 1177 return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_ch_width( 1178 vdev); 1179 } 1180 1181 /** 1182 * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary 1183 * 20 MHz channel for a given vdev 1184 * @pdev: Pointer to vdev 1185 * 1186 * Get the frequency of secondary 20Mhz channel for a given vdev 1187 * 1188 * Return: Frequency of secondary 20Mhz channel for a given vdev 1189 */ 1190 static inline 1191 int target_if_vdev_get_sec20chan_freq_mhz( 1192 struct wlan_objmgr_vdev *vdev, 1193 uint16_t *sec20chan_freq) 1194 { 1195 struct wlan_objmgr_psoc *psoc = NULL; 1196 1197 psoc = wlan_vdev_get_psoc(vdev); 1198 if (!psoc) { 1199 spectral_err("psoc is NULL"); 1200 return -EINVAL; 1201 } 1202 1203 return psoc->soc_cb.rx_ops.sptrl_rx_ops. 1204 sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); 1205 } 1206 1207 /** 1208 * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask 1209 * @pdev: Pointer to pdev 1210 * @spectral_rx_chainmask: Spectral Rx chainmask 1211 * 1212 * Return: None 1213 */ 1214 static inline 1215 void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, 1216 uint8_t spectral_rx_chainmask) 1217 { 1218 struct target_if_spectral *spectral = NULL; 1219 1220 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1221 spectral->params.ss_chn_mask = spectral_rx_chainmask; 1222 } 1223 1224 /** 1225 * target_if_spectral_process_phyerr() - Process Spectral PHY error 1226 * @pdev: Pointer to pdev 1227 * @data: PHY error data received from FW 1228 * @datalen: Length of data 1229 * @p_rfqual: Pointer to RF Quality information 1230 * @p_chaninfo: Pointer to channel information 1231 * @tsf: TSF time instance at which the Spectral sample was received 1232 * @acs_stats: ACS stats 1233 * 1234 * Process Spectral PHY error by extracting necessary information from the data 1235 * sent by FW, and send the extracted information to application layer. 1236 * 1237 * Return: None 1238 */ 1239 static inline 1240 void target_if_spectral_process_phyerr( 1241 struct wlan_objmgr_pdev *pdev, 1242 uint8_t *data, uint32_t datalen, 1243 struct target_if_spectral_rfqual_info *p_rfqual, 1244 struct target_if_spectral_chan_info *p_chaninfo, 1245 uint64_t tsf64, 1246 struct target_if_spectral_acs_stats *acs_stats) 1247 { 1248 struct target_if_spectral *spectral = NULL; 1249 struct target_if_spectral_ops *p_sops = NULL; 1250 1251 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1252 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1253 p_sops->spectral_process_phyerr(spectral, data, datalen, 1254 p_rfqual, p_chaninfo, 1255 tsf64, acs_stats); 1256 } 1257 1258 /** 1259 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 1260 * @arg: Pointer to handle for Spectral target_if internal private data 1261 * 1262 * Function to check whether Spectral is enabled 1263 * 1264 * Return: True if Spectral is enabled, false if Spectral is not enabled 1265 */ 1266 uint32_t target_if_sops_is_spectral_enabled(void *arg); 1267 1268 /** 1269 * target_if_sops_is_spectral_active() - Get whether Spectral is active 1270 * @arg: Pointer to handle for Spectral target_if internal private data 1271 * 1272 * Function to check whether Spectral is active 1273 * 1274 * Return: True if Spectral is active, false if Spectral is not active 1275 */ 1276 uint32_t target_if_sops_is_spectral_active(void *arg); 1277 1278 /** 1279 * target_if_sops_start_spectral_scan() - Start Spectral scan 1280 * @arg: Pointer to handle for Spectral target_if internal private data 1281 * 1282 * Function to start spectral scan 1283 * 1284 * Return: 0 on success else failure 1285 */ 1286 uint32_t target_if_sops_start_spectral_scan(void *arg); 1287 1288 /** 1289 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 1290 * @arg: Pointer to handle for Spectral target_if internal private data 1291 * 1292 * Function to stop spectral scan 1293 * 1294 * Return: 0 in case of success, -1 on failure 1295 */ 1296 uint32_t target_if_sops_stop_spectral_scan(void *arg); 1297 1298 /** 1299 * target_if_spectral_get_extension_channel() - Get the current Extension 1300 * channel (in MHz) 1301 * @arg: Pointer to handle for Spectral target_if internal private data 1302 * 1303 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 1304 * extension channel is not present. 1305 */ 1306 uint32_t target_if_spectral_get_extension_channel(void *arg); 1307 1308 /** 1309 * target_if_spectral_get_current_channel() - Get the current channel (in MHz) 1310 * @arg: Pointer to handle for Spectral target_if internal private data 1311 * 1312 * Return: Current channel (in MHz) on success, 0 on failure 1313 */ 1314 uint32_t target_if_spectral_get_current_channel(void *arg); 1315 1316 1317 /** 1318 * target_if_spectral_reset_hw() - Reset the hardware 1319 * @arg: Pointer to handle for Spectral target_if internal private data 1320 * 1321 * This is only a placeholder since it is not currently required in the offload 1322 * case. 1323 * 1324 * Return: 0 1325 */ 1326 uint32_t target_if_spectral_reset_hw(void *arg); 1327 1328 /** 1329 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 1330 * Noisefloor history buffer 1331 * @arg: Pointer to handle for Spectral target_if internal private data 1332 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 1333 * 1334 * This is only a placeholder since it is not currently required in the offload 1335 * case. 1336 * 1337 * Return: 0 1338 */ 1339 uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf); 1340 1341 /** 1342 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 1343 * noisefloor 1344 * @arg: Pointer to handle for Spectral target_if internal private data 1345 * 1346 * This is only a placeholder since it is not currently required in the offload 1347 * case. 1348 * 1349 * Return: 0 1350 */ 1351 int8_t target_if_spectral_get_ext_noisefloor(void *arg); 1352 1353 /** 1354 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 1355 * @arg: Pointer to handle for Spectral target_if internal private data 1356 * 1357 * This is only a placeholder since it is not currently required in the offload 1358 * case. 1359 * 1360 * Return: 0 1361 */ 1362 int8_t target_if_spectral_get_ctl_noisefloor(void *arg); 1363 1364 /** 1365 * target_if_spectral_get_capability() - Get whether a given Spectral hardware 1366 * capability is available 1367 * @arg: Pointer to handle for Spectral target_if internal private data 1368 * @type: Spectral hardware capability type 1369 * 1370 * Return: True if the capability is available, false if the capability is not 1371 * available 1372 */ 1373 uint32_t target_if_spectral_get_capability( 1374 void *arg, enum spectral_capability_type type); 1375 1376 /** 1377 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 1378 * @arg: Pointer to handle for Spectral target_if internal private data 1379 * @rxfilter: Rx filter to be used 1380 * 1381 * Note: This is only a placeholder function. It is not currently required since 1382 * FW should be taking care of setting the required filters. 1383 * 1384 * Return: 0 1385 */ 1386 uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter); 1387 1388 /** 1389 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 1390 * parameters 1391 * @arg: Pointer to handle for Spectral target_if internal private data 1392 * @params: Spectral parameters 1393 * 1394 * Return: 0 in case of success, -1 on failure 1395 */ 1396 uint32_t target_if_spectral_sops_configure_params( 1397 void *arg, struct spectral_config *params); 1398 1399 /** 1400 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 1401 * @arg: Pointer to handle for Spectral target_if internal private data 1402 * 1403 * Note: This is only a placeholder function. It is not currently required since 1404 * FW should be taking care of setting the required filters. 1405 * 1406 * Return: 0 1407 */ 1408 uint32_t target_if_spectral_get_rxfilter(void *arg); 1409 1410 /** 1411 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 1412 * functionality for the given pdev 1413 * @pdev: Pointer to pdev object 1414 * 1415 * Return: None 1416 */ 1417 void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev); 1418 1419 /** 1420 * target_if_set_spectral_config() - Set spectral config 1421 * @pdev: Pointer to pdev object 1422 * @threshtype: config type 1423 * @value: config value 1424 * 1425 * API to set spectral configurations 1426 * 1427 * Return: 0 in case of success, -1 on failure 1428 */ 1429 int target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 1430 const uint32_t threshtype, 1431 const uint32_t value); 1432 1433 /** 1434 * target_if_pdev_spectral_init() - Initialize target_if Spectral 1435 * functionality for the given pdev 1436 * @pdev: Pointer to pdev object 1437 * 1438 * Return: On success, pointer to Spectral target_if internal private data, on 1439 * failure, NULL 1440 */ 1441 void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev); 1442 1443 /** 1444 * target_if_spectral_sops_get_params() - Get user configured Spectral 1445 * parameters 1446 * @arg: Pointer to handle for Spectral target_if internal private data 1447 * @params: Pointer to buffer into which Spectral parameters should be copied 1448 * 1449 * Return: 0 in case of success, -1 on failure 1450 */ 1451 uint32_t target_if_spectral_sops_get_params( 1452 void *arg, struct spectral_config *params); 1453 1454 /** 1455 * target_if_init_spectral_capability() - Initialize Spectral capability 1456 * @spectral: Pointer to Spectral target_if internal private data 1457 * 1458 * This is a workaround. 1459 * 1460 * Return: None 1461 */ 1462 void target_if_init_spectral_capability(struct target_if_spectral *spectral); 1463 1464 /** 1465 * target_if_start_spectral_scan() - Start spectral scan 1466 * @pdev: Pointer to pdev object 1467 * 1468 * API to start spectral scan 1469 * 1470 * Return: 0 in case of success, -1 on failure 1471 */ 1472 int target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev); 1473 1474 /** 1475 * target_if_get_spectral_config() - Get spectral configuration 1476 * @pdev: Pointer to pdev object 1477 * @param: Pointer to spectral_config structure in which the configuration 1478 * should be returned 1479 * 1480 * API to get the current spectral configuration 1481 * 1482 * Return: 0 in case of success, -1 on failure 1483 */ 1484 void target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 1485 struct spectral_config *param); 1486 1487 /** 1488 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 1489 * parameters 1490 * @spectral: Pointer to Spectral target_if internal private data 1491 * @spectral_params: Pointer to Spectral parameters 1492 * 1493 * Enable use of desired Spectral parameters by configuring them into HW, and 1494 * starting Spectral scan 1495 * 1496 * Return: 0 on success, 1 on failure 1497 */ 1498 int target_if_spectral_scan_enable_params( 1499 struct target_if_spectral *spectral, struct spectral_config *spectral_params); 1500 1501 /** 1502 * target_if_is_spectral_active() - Get whether Spectral is active 1503 * @pdev: Pointer to pdev object 1504 * 1505 * Return: True if Spectral is active, false if Spectral is not active 1506 */ 1507 bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev); 1508 1509 /** 1510 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 1511 * @pdev: Pointer to pdev object 1512 * 1513 * Return: True if Spectral is enabled, false if Spectral is not enabled 1514 */ 1515 bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev); 1516 1517 /** 1518 * target_if_set_debug_level() - Set debug level for Spectral 1519 * @pdev: Pointer to pdev object 1520 * @debug_level: Debug level 1521 * 1522 * Return: 0 in case of success 1523 */ 1524 int target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, 1525 uint32_t debug_level); 1526 1527 /** 1528 * target_if_get_debug_level() - Get debug level for Spectral 1529 * @pdev: Pointer to pdev object 1530 * 1531 * Return: Current debug level 1532 */ 1533 uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev); 1534 1535 1536 /** 1537 * target_if_get_spectral_capinfo() - Get Spectral capability information 1538 * @pdev: Pointer to pdev object 1539 * @outdata: Buffer into which data should be copied 1540 * 1541 * Return: void 1542 */ 1543 void target_if_get_spectral_capinfo( 1544 struct wlan_objmgr_pdev *pdev, 1545 void *outdata); 1546 1547 1548 /** 1549 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 1550 * @pdev: Pointer to pdev object 1551 * @outdata: Buffer into which data should be copied 1552 * 1553 * Return: void 1554 */ 1555 void target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, 1556 void *outdata); 1557 1558 /* 1559 * target_if_spectral_send_tlv_to_host - target_if_spectral_send_tlv_to_host 1560 * @spectral: Send the TLV information to Host 1561 * @data: Pointer to the TLV 1562 * @datalen: tlv length 1563 * 1564 * Return: Success/Failure 1565 * 1566 */ 1567 int target_if_spectral_send_tlv_to_host( 1568 struct target_if_spectral *spectral, 1569 uint8_t *data, uint32_t datalen); 1570 1571 void target_if_register_wmi_spectral_cmd_ops( 1572 struct wlan_objmgr_pdev *pdev, 1573 struct wmi_spectral_cmd_ops *cmd_ops); 1574 1575 /** 1576 * target_if_consume_sfft_report_gen3() - Process fft report for gen3 1577 * @spectral: Pointer to spectral object 1578 * @data: Pointer to phyerror data 1579 * 1580 * Process fft report for gen3 1581 * 1582 * Return: Success/Failure 1583 */ 1584 int 1585 target_if_consume_spectral_report_gen3(struct target_if_spectral *spectral, 1586 uint8_t *data); 1587 1588 #ifdef WIN32 1589 #pragma pack(pop, target_if_spectral) 1590 #endif 1591 #ifdef __ATTRIB_PACK 1592 #undef __ATTRIB_PACK 1593 #endif 1594 1595 #endif /* _TARGET_IF_SPECTRAL_H_ */ 1596