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 334 #ifdef DIRECT_BUF_RX_ENABLE 335 /** 336 * struct Spectral_report - spectral report 337 * @data: Report buffer 338 * @noisefloor: Noise floor values 339 */ 340 struct spectral_report { 341 uint8_t *data; 342 int32_t noisefloor[DBR_MAX_CHAINS]; 343 }; 344 #endif 345 /* END of spectral GEN III HW specific details */ 346 347 typedef signed char pwr_dbm; 348 349 /** 350 * enum spectral_gen - spectral hw generation 351 * @SPECTRAL_GEN1 : spectral hw gen 1 352 * @SPECTRAL_GEN2 : spectral hw gen 2 353 * @SPECTRAL_GEN3 : spectral hw gen 3 354 */ 355 enum spectral_gen { 356 SPECTRAL_GEN1, 357 SPECTRAL_GEN2, 358 SPECTRAL_GEN3, 359 }; 360 361 #if ATH_PERF_PWR_OFFLOAD 362 /** 363 * enum target_if_spectral_info - Enumerations for specifying which spectral 364 * information (among parameters and states) 365 * is desired. 366 * @TARGET_IF_SPECTRAL_INFO_ACTIVE: Indicated whether spectral is active 367 * @TARGET_IF_SPECTRAL_INFO_ENABLED: Indicated whether spectral is enabled 368 * @TARGET_IF_SPECTRAL_INFO_PARAMS: Config params 369 */ 370 enum target_if_spectral_info { 371 TARGET_IF_SPECTRAL_INFO_ACTIVE, 372 TARGET_IF_SPECTRAL_INFO_ENABLED, 373 TARGET_IF_SPECTRAL_INFO_PARAMS, 374 }; 375 #endif /* ATH_PERF_PWR_OFFLOAD */ 376 377 /* forward declaration */ 378 struct target_if_spectral; 379 380 /** 381 * struct target_if_spectral_chan_info - Channel information 382 * @center_freq1: center frequency 1 in MHz 383 * @center_freq2: center frequency 2 in MHz -valid only for 384 * 11ACVHT 80PLUS80 mode 385 * @chan_width: channel width in MHz 386 */ 387 struct target_if_spectral_chan_info { 388 uint16_t center_freq1; 389 uint16_t center_freq2; 390 uint8_t chan_width; 391 }; 392 393 /** 394 * struct target_if_spectral_acs_stats - EACS stats from spectral samples 395 * @nfc_ctl_rssi: Control chan rssi 396 * @nfc_ext_rssi: Extension chan rssi 397 * @ctrl_nf: Control chan Noise Floor 398 * @ext_nf: Extension chan Noise Floor 399 */ 400 struct target_if_spectral_acs_stats { 401 int8_t nfc_ctl_rssi; 402 int8_t nfc_ext_rssi; 403 int8_t ctrl_nf; 404 int8_t ext_nf; 405 }; 406 407 /** 408 * struct target_if_spectral_perchain_rssi_info - per chain rssi info 409 * @rssi_pri20: Rssi of primary 20 Mhz 410 * @rssi_sec20: Rssi of secondary 20 Mhz 411 * @rssi_sec40: Rssi of secondary 40 Mhz 412 * @rssi_sec80: Rssi of secondary 80 Mhz 413 */ 414 struct target_if_spectral_perchain_rssi_info { 415 int8_t rssi_pri20; 416 int8_t rssi_sec20; 417 int8_t rssi_sec40; 418 int8_t rssi_sec80; 419 }; 420 421 /** 422 * struct target_if_spectral_rfqual_info - RF measurement information 423 * @rssi_comb: RSSI Information 424 * @pc_rssi_info: XXX : For now, we know we are getting information 425 * for only 4 chains at max. For future extensions 426 * use a define 427 * @noise_floor: Noise floor information 428 */ 429 struct target_if_spectral_rfqual_info { 430 int8_t rssi_comb; 431 struct target_if_spectral_perchain_rssi_info pc_rssi_info[4]; 432 int16_t noise_floor[4]; 433 }; 434 435 #define GET_TARGET_IF_SPECTRAL_OPS(spectral) \ 436 ((struct target_if_spectral_ops *)(&((spectral)->spectral_ops))) 437 438 /** 439 * struct target_if_spectral_ops - spectral low level ops table 440 * @get_tsf64: Get 64 bit TSF value 441 * @get_capability: Get capability info 442 * @set_rxfilter: Set rx filter 443 * @get_rxfilter: Get rx filter 444 * @is_spectral_active: Check whether icm is active 445 * @is_spectral_enabled: Check whether spectral is enabled 446 * @start_spectral_scan: Start spectral scan 447 * @stop_spectral_scan: Stop spectral scan 448 * @get_extension_channel: Get extension channel 449 * @get_ctl_noisefloor: Get control noise floor 450 * @get_ext_noisefloor: Get extension noise floor 451 * @configure_spectral: Set spectral configurations 452 * @get_spectral_config: Get spectral configurations 453 * @get_ent_spectral_mask: Get spectral mask 454 * @get_mac_address: Get mac address 455 * @get_current_channel: Get current channel 456 * @reset_hw: Reset HW 457 * @get_chain_noise_floor: Get Channel noise floor 458 * @spectral_process_phyerr: Process phyerr event 459 * @process_spectral_report: Process spectral report 460 */ 461 struct target_if_spectral_ops { 462 uint64_t (*get_tsf64)(void *arg); 463 uint32_t (*get_capability)( 464 void *arg, enum spectral_capability_type type); 465 uint32_t (*set_rxfilter)(void *arg, int rxfilter); 466 uint32_t (*get_rxfilter)(void *arg); 467 uint32_t (*is_spectral_active)(void *arg); 468 uint32_t (*is_spectral_enabled)(void *arg); 469 uint32_t (*start_spectral_scan)(void *arg); 470 uint32_t (*stop_spectral_scan)(void *arg); 471 uint32_t (*get_extension_channel)(void *arg); 472 int8_t (*get_ctl_noisefloor)(void *arg); 473 int8_t (*get_ext_noisefloor)(void *arg); 474 uint32_t (*configure_spectral)( 475 void *arg, 476 struct spectral_config *params); 477 uint32_t (*get_spectral_config)( 478 void *arg, 479 struct spectral_config *params); 480 uint32_t (*get_ent_spectral_mask)(void *arg); 481 uint32_t (*get_mac_address)(void *arg, char *addr); 482 uint32_t (*get_current_channel)(void *arg); 483 uint32_t (*reset_hw)(void *arg); 484 uint32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf); 485 int (*spectral_process_phyerr)(struct target_if_spectral *spectral, 486 uint8_t *data, uint32_t datalen, 487 struct target_if_spectral_rfqual_info *p_rfqual, 488 struct target_if_spectral_chan_info *p_chaninfo, 489 uint64_t tsf64, 490 struct target_if_spectral_acs_stats *acs_stats); 491 int (*process_spectral_report)(struct wlan_objmgr_pdev *pdev, 492 void *payload); 493 }; 494 495 /** 496 * struct target_if_spectral_stats - spectral stats info 497 * @num_spectral_detects: Total num. of spectral detects 498 * @total_phy_errors: Total number of phyerrors 499 * @owl_phy_errors: Indicated phyerrors in old gen1 chipsets 500 * @pri_phy_errors: Phyerrors in primary channel 501 * @ext_phy_errors: Phyerrors in secondary channel 502 * @dc_phy_errors: Phyerrors due to dc 503 * @early_ext_phy_errors: Early secondary channel phyerrors 504 * @bwinfo_errors: Bandwidth info errors 505 * @datalen_discards: Invalid data length errors, seen in gen1 chipsets 506 * @rssi_discards bw: Indicates reports dropped due to RSSI threshold 507 * @last_reset_tstamp: Last reset time stamp 508 */ 509 struct target_if_spectral_stats { 510 uint32_t num_spectral_detects; 511 uint32_t total_phy_errors; 512 uint32_t owl_phy_errors; 513 uint32_t pri_phy_errors; 514 uint32_t ext_phy_errors; 515 uint32_t dc_phy_errors; 516 uint32_t early_ext_phy_errors; 517 uint32_t bwinfo_errors; 518 uint32_t datalen_discards; 519 uint32_t rssi_discards; 520 uint64_t last_reset_tstamp; 521 }; 522 523 /** 524 * struct target_if_spectral_event - spectral event structure 525 * @se_ts: Original 15 bit recv timestamp 526 * @se_full_ts: 64-bit full timestamp from interrupt time 527 * @se_rssi: Rssi of spectral event 528 * @se_bwinfo: Rssi of spectral event 529 * @se_dur: Duration of spectral pulse 530 * @se_chanindex: Channel of event 531 * @se_list: List of spectral events 532 */ 533 struct target_if_spectral_event { 534 uint32_t se_ts; 535 uint64_t se_full_ts; 536 uint8_t se_rssi; 537 uint8_t se_bwinfo; 538 uint8_t se_dur; 539 uint8_t se_chanindex; 540 541 STAILQ_ENTRY(spectral_event) se_list; 542 }; 543 544 /** 545 * struct target_if_chain_noise_pwr_info - Noise power info for each channel 546 * @rptcount: Count of reports in pwr array 547 * @un_cal_nf: Uncalibrated noise floor 548 * @factory_cal_nf: Noise floor as calibrated at the factory for module 549 * @median_pwr: Median power (median of pwr array) 550 * @pwr: Power reports 551 */ 552 struct target_if_chain_noise_pwr_info { 553 int rptcount; 554 pwr_dbm un_cal_nf; 555 pwr_dbm factory_cal_nf; 556 pwr_dbm median_pwr; 557 pwr_dbm pwr[]; 558 } __ATTRIB_PACK; 559 560 /** 561 * struct target_if_spectral_chan_stats - Channel information 562 * @cycle_count: Cycle count 563 * @channel_load: Channel load 564 * @per: Period 565 * @noisefloor: Noise floor 566 * @comp_usablity: Computed usability 567 * @maxregpower: Maximum allowed regulatary power 568 * @comp_usablity_sec80: Computed usability of secondary 80 Mhz 569 * @maxregpower_sec80: Max regulatory power in secondary 80 Mhz 570 */ 571 struct target_if_spectral_chan_stats { 572 int cycle_count; 573 int channel_load; 574 int per; 575 int noisefloor; 576 uint16_t comp_usablity; 577 int8_t maxregpower; 578 uint16_t comp_usablity_sec80; 579 int8_t maxregpower_sec80; 580 }; 581 582 #if ATH_PERF_PWR_OFFLOAD 583 584 /** 585 * struct target_if_spectral_cache - Cache used to minimize WMI operations 586 * in offload architecture 587 * @osc_spectral_enabled: Whether Spectral is enabled 588 * @osc_spectral_active: Whether spectral is active 589 * XXX: Ideally, we should NOT cache this 590 * since the hardware can self clear the bit, 591 * the firmware can possibly stop spectral due to 592 * intermittent off-channel activity, etc 593 * A WMI read command should be introduced to handle 594 * this This will be discussed. 595 * @osc_params: Spectral parameters 596 * @osc_is_valid: Whether the cache is valid 597 */ 598 struct target_if_spectral_cache { 599 uint8_t osc_spectral_enabled; 600 uint8_t osc_spectral_active; 601 struct spectral_config osc_params; 602 uint8_t osc_is_valid; 603 }; 604 605 /** 606 * struct target_if_spectral_param_state_info - Structure used to represent and 607 * manage spectral information 608 * (parameters and states) 609 * @osps_lock: Lock to synchronize accesses to information 610 * @osps_cache: Cacheable' information 611 */ 612 struct target_if_spectral_param_state_info { 613 qdf_spinlock_t osps_lock; 614 struct target_if_spectral_cache osps_cache; 615 /* XXX - Non-cacheable information goes here, in the future */ 616 }; 617 #endif /* ATH_PERF_PWR_OFFLOAD */ 618 619 struct vdev_spectral_configure_params; 620 struct vdev_spectral_enable_params; 621 622 /** 623 * struct wmi_spectral_cmd_ops - structure used holding the operations 624 * related to wmi commands on spectral parameters. 625 * @wmi_spectral_configure_cmd_send: 626 * @wmi_spectral_enable_cmd_send: 627 */ 628 struct wmi_spectral_cmd_ops { 629 QDF_STATUS (*wmi_spectral_configure_cmd_send)( 630 void *wmi_hdl, 631 struct vdev_spectral_configure_params *param); 632 QDF_STATUS (*wmi_spectral_enable_cmd_send)( 633 void *wmi_hdl, 634 struct vdev_spectral_enable_params *param); 635 }; 636 637 /** 638 * struct target_if_spectral - main spectral structure 639 * @pdev: Pointer to pdev 640 * @spectral_ops: Target if internal Spectral low level operations table 641 * @capability: Spectral capabilities structure 642 * @spectral_lock: Lock used for internal Spectral operations 643 * @spectral_curchan_radindex: Current channel spectral index 644 * @spectral_extchan_radindex: Extension channel spectral index 645 * @spectraldomain: Current Spectral domain 646 * @spectral_proc_phyerr: Flags to process for PHY errors 647 * @spectral_defaultparams: Default PHY params per Spectral stat 648 * @spectral_stats: Spectral related stats 649 * @events: Events structure 650 * @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel? 651 * @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI? 652 * @sc_spectral_20_40_mode: Is AP in 20-40 mode? 653 * @sc_spectral_noise_pwr_cal: Noise power cal required? 654 * @sc_spectral_non_edma: Is the spectral capable device Non-EDMA? 655 * @upper_is_control: Upper segment is primary 656 * @upper_is_extension: Upper segment is secondary 657 * @lower_is_control: Lower segment is primary 658 * @lower_is_extension: Lower segment is secondary 659 * @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral 660 * mute test 661 * @spectral_numbins: Number of bins 662 * @spectral_fft_len: FFT length 663 * @spectral_data_len: Total phyerror report length 664 * @lb_edge_extrabins: Number of extra bins on left band edge 665 * @rb_edge_extrabins: Number of extra bins on right band edge 666 * @spectral_max_index_offset: Max FFT index offset (20 MHz mode) 667 * @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode) 668 * @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode) 669 * @spectral_dc_index: At which index DC is present 670 * @send_single_packet: Deprecated 671 * @spectral_sent_msg: Indicates whether we send report to upper layers 672 * @params: Spectral parameters 673 * @last_capture_time: Indicates timestamp of previouse report 674 * @num_spectral_data: Number of Spectral samples received in current session 675 * @total_spectral_data: Total number of Spectral samples received 676 * @max_rssi: Maximum RSSI 677 * @detects_control_channel: NA 678 * @detects_extension_channel: NA 679 * @detects_below_dc: NA 680 * @detects_above_dc: NA 681 * @sc_scanning: Indicates active wifi scan 682 * @sc_spectral_scan: Indicates active specral scan 683 * @sc_spectral_full_scan: Deprecated 684 * @scan_start_tstamp: Deprecated 685 * @last_tstamp: Deprecated 686 * @first_tstamp: Deprecated 687 * @spectral_samp_count: Deprecated 688 * @sc_spectral_samp_count: Deprecated 689 * @noise_pwr_reports_reqd: Number of noise power reports required 690 * @noise_pwr_reports_recv: Number of noise power reports received 691 * @noise_pwr_reports_lock: Lock used for Noise power report processing 692 * @noise_pwr_chain_ctl: Noise power report - control channel 693 * @noise_pwr_chain_ext: Noise power report - extension channel 694 * @chaninfo: Channel statistics 695 * @tsf64: Latest TSF Value 696 * @param_info: Offload architecture Spectral parameter cache information 697 * @ch_width: Indicates Channel Width 20/40/80/160 MHz with values 0, 1, 2, 3 698 * respectively 699 * @diag_stats: Diagnostic statistics 700 * @is_160_format: Indicates whether information provided by HW is in altered 701 * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards) 702 * @is_lb_edge_extrabins_format: Indicates whether information provided by 703 * HW has 4 extra bins, at left band edge, for report mode 2 704 * @is_rb_edge_extrabins_format: Indicates whether information provided 705 * by HW has 4 extra bins, at right band edge, for report mode 2 706 * @is_sec80_rssi_war_required: Indicates whether the software workaround is 707 * required to obtain approximate combined RSSI for secondary 80Mhz segment 708 * @simctx: Spectral Simulation context 709 * @spectral_gen: Spectral hardware generation 710 * @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware 711 * generation 712 * @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV 713 * header, for the given hardware generation 714 * @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV 715 * header, for the given hardware generation 716 * @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware 717 * generation 718 * @nl_cb: Netlink callbacks 719 * @use_nl_bcast: Whether to use Netlink broadcast/unicast 720 * @send_phy_data: Send data to the applicaton layer 721 * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for 722 * in-band report format. This would be required on some chipsets under the 723 * following circumstances: In report mode 2 only the in-band bins are DMA'ed. 724 * Scatter/gather is used. However, the HW generates all bins, not just in-band, 725 * and reports the number of bins accordingly. The subsystem arranging for the 726 * DMA cannot change this value. On such chipsets the adjustment required at the 727 * host driver is to check if report format is 2, and if so halve the number of 728 * bins reported to get the number actually DMA'ed. 729 */ 730 struct target_if_spectral { 731 struct wlan_objmgr_pdev *pdev_obj; 732 struct target_if_spectral_ops spectral_ops; 733 struct spectral_caps capability; 734 qdf_spinlock_t spectral_lock; 735 int16_t spectral_curchan_radindex; 736 int16_t spectral_extchan_radindex; 737 uint32_t spectraldomain; 738 uint32_t spectral_proc_phyerr; 739 struct spectral_config spectral_defaultparams; 740 struct target_if_spectral_stats spectral_stats; 741 struct target_if_spectral_event *events; 742 unsigned int sc_spectral_ext_chan_ok:1, 743 sc_spectral_combined_rssi_ok:1, 744 sc_spectral_20_40_mode:1, 745 sc_spectral_noise_pwr_cal:1, 746 sc_spectral_non_edma:1; 747 int upper_is_control; 748 int upper_is_extension; 749 int lower_is_control; 750 int lower_is_extension; 751 uint8_t sc_spectraltest_ieeechan; 752 int spectral_numbins; 753 int spectral_fft_len; 754 int spectral_data_len; 755 756 /* 757 * For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are 758 * delivered. However, there can be additional bins reported for 759 * AR900B version 2.0 and QCA9984 as described next: 760 * 761 * AR900B version 2.0: An additional tone is processed on the right 762 * hand side in order to facilitate detection of radar pulses out to 763 * the extreme band-edge of the channel frequency. Since the HW design 764 * processes four tones at a time, this requires one additional Dword 765 * to be added to the search FFT report. 766 * 767 * QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary + 768 * 1x-oversampled bins (in-band) per FFT, then 8 more bins 769 * (4 more on left side and 4 more on right side)are added. 770 */ 771 772 int lb_edge_extrabins; 773 int rb_edge_extrabins; 774 int spectral_max_index_offset; 775 int spectral_upper_max_index_offset; 776 int spectral_lower_max_index_offset; 777 int spectral_dc_index; 778 int send_single_packet; 779 int spectral_sent_msg; 780 int classify_scan; 781 os_timer_t classify_timer; 782 struct spectral_config params; 783 struct spectral_classifier_params classifier_params; 784 int last_capture_time; 785 int num_spectral_data; 786 int total_spectral_data; 787 int max_rssi; 788 int detects_control_channel; 789 int detects_extension_channel; 790 int detects_below_dc; 791 int detects_above_dc; 792 int sc_scanning; 793 int sc_spectral_scan; 794 int sc_spectral_full_scan; 795 uint64_t scan_start_tstamp; 796 uint32_t last_tstamp; 797 uint32_t first_tstamp; 798 uint32_t spectral_samp_count; 799 uint32_t sc_spectral_samp_count; 800 int noise_pwr_reports_reqd; 801 int noise_pwr_reports_recv; 802 qdf_spinlock_t noise_pwr_reports_lock; 803 struct target_if_chain_noise_pwr_info 804 *noise_pwr_chain_ctl[HOST_MAX_ANTENNA]; 805 struct target_if_chain_noise_pwr_info 806 *noise_pwr_chain_ext[HOST_MAX_ANTENNA]; 807 uint64_t tsf64; 808 #if ATH_PERF_PWR_OFFLOAD 809 struct target_if_spectral_param_state_info param_info; 810 #endif 811 uint32_t ch_width; 812 struct spectral_diag_stats diag_stats; 813 bool is_160_format; 814 bool is_lb_edge_extrabins_format; 815 bool is_rb_edge_extrabins_format; 816 bool is_sec80_rssi_war_required; 817 #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION 818 void *simctx; 819 #endif 820 enum spectral_gen spectral_gen; 821 uint8_t hdr_sig_exp; 822 uint8_t tag_sscan_summary_exp; 823 uint8_t tag_sscan_fft_exp; 824 uint8_t tlvhdr_size; 825 struct wmi_spectral_cmd_ops param_wmi_cmd_ops; 826 struct spectral_nl_cb nl_cb; 827 bool use_nl_bcast; 828 int (*send_phy_data)(struct wlan_objmgr_pdev *pdev); 829 u_int8_t fftbin_size_war; 830 u_int8_t inband_fftbin_size_adj; 831 }; 832 833 /** 834 * struct target_if_samp_msg_params - Spectral Analysis Messaging Protocol 835 * data format 836 * @rssi: RSSI (except for secondary 80 segment) 837 * @rssi_sec80: RSSI for secondary 80 segment 838 * @lower_rssi: RSSI of lower band 839 * @upper_rssi: RSSI of upper band 840 * @chain_ctl_rssi: RSSI for control channel, for all antennas 841 * @chain_ext_rssi: RSSI for extension channel, for all antennas 842 * @bwinfo: bandwidth info 843 * @data_len: length of FFT data (except for secondary 80 segment) 844 * @data_len_sec80: length of FFT data for secondary 80 segment 845 * @tstamp: timestamp 846 * @last_tstamp: last time stamp 847 * @max_mag: maximum magnitude (except for secondary 80 segment) 848 * @max_mag_sec80: maximum magnitude for secondary 80 segment 849 * @max_index: index of max magnitude (except for secondary 80 segment) 850 * @max_index_sec80: index of max magnitude for secondary 80 segment 851 * @max_exp: max exp 852 * @peak: peak frequency (obsolete) 853 * @pwr_count: number of FFT bins (except for secondary 80 segment) 854 * @pwr_count_sec80: number of FFT bins in secondary 80 segment 855 * @nb_lower: This is deprecated 856 * @nb_upper: This is deprecated 857 * @max_upper_index: index of max mag in upper band 858 * @max_lower_index: index of max mag in lower band 859 * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment) 860 * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment 861 * @freq: Center frequency of primary 20MHz channel in MHz 862 * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz 863 * @vhtop_ch_freq_seg2: VHT operation second segment center frequency in MHz 864 * @freq_loading: spectral control duty cycles 865 * @noise_floor: current noise floor (except for secondary 80 segment) 866 * @noise_floor_sec80: current noise floor for secondary 80 segment 867 * @interf_list: List of interfernce sources 868 * @classifier_params: classifier parameters 869 * @sc: classifier parameters 870 */ 871 struct target_if_samp_msg_params { 872 int8_t rssi; 873 int8_t rssi_sec80; 874 int8_t lower_rssi; 875 int8_t upper_rssi; 876 int8_t chain_ctl_rssi[HOST_MAX_ANTENNA]; 877 int8_t chain_ext_rssi[HOST_MAX_ANTENNA]; 878 uint16_t bwinfo; 879 uint16_t datalen; 880 uint16_t datalen_sec80; 881 uint32_t tstamp; 882 uint32_t last_tstamp; 883 uint16_t max_mag; 884 uint16_t max_mag_sec80; 885 uint16_t max_index; 886 uint16_t max_index_sec80; 887 uint8_t max_exp; 888 int peak; 889 int pwr_count; 890 int pwr_count_sec80; 891 int8_t nb_lower; 892 int8_t nb_upper; 893 uint16_t max_lower_index; 894 uint16_t max_upper_index; 895 uint8_t *bin_pwr_data; 896 uint8_t *bin_pwr_data_sec80; 897 uint16_t freq; 898 uint16_t vhtop_ch_freq_seg1; 899 uint16_t vhtop_ch_freq_seg2; 900 uint16_t freq_loading; 901 int16_t noise_floor; 902 int16_t noise_floor_sec80; 903 struct interf_src_rsp interf_list; 904 struct spectral_classifier_params classifier_params; 905 struct ath_softc *sc; 906 }; 907 908 #ifdef WLAN_CONV_SPECTRAL_ENABLE 909 /** 910 * target_if_spectral_dump_fft() - Dump Spectral FFT 911 * @pfft: Pointer to Spectral Phyerr FFT 912 * @fftlen: FFT length 913 * 914 * Return: Success or failure 915 */ 916 int target_if_spectral_dump_fft(uint8_t *pfft, int fftlen); 917 918 /** 919 * target_if_dbg_print_samp_param() - Print contents of SAMP struct 920 * @p: Pointer to SAMP message 921 * 922 * Return: Void 923 */ 924 void target_if_dbg_print_samp_param(struct target_if_samp_msg_params *p); 925 926 /** 927 * target_if_get_offset_swar_sec80() - Get offset for SWAR according to 928 * the channel width 929 * @channel_width: Channel width 930 * 931 * Return: Offset for SWAR 932 */ 933 uint32_t target_if_get_offset_swar_sec80(uint32_t channel_width); 934 935 /** 936 * target_if_sptrl_register_tx_ops() - Register Spectral target_if Tx Ops 937 * @tx_ops: Tx Ops 938 * 939 * Return: void 940 */ 941 void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); 942 943 /** 944 * target_if_spectral_create_samp_msg() - Create the spectral samp message 945 * @spectral : Pointer to spectral internal structure 946 * @params : spectral samp message parameters 947 * 948 * API to create the spectral samp message 949 * 950 * Return: void 951 */ 952 void target_if_spectral_create_samp_msg( 953 struct target_if_spectral *spectral, 954 struct target_if_samp_msg_params *params); 955 956 /** 957 * target_if_spectral_process_phyerr_gen3() - Process phyerror event for gen3 958 * @pdev: Pointer to pdev object 959 * @payload: Pointer to spectral report 960 * 961 * Process phyerror event for gen3 962 * 963 * Return: Success/Failure 964 */ 965 int target_if_spectral_process_report_gen3( 966 struct wlan_objmgr_pdev *pdev, 967 void *buf); 968 969 /** 970 * target_if_process_phyerr_gen2() - Process PHY Error for gen2 971 * @spectral: Pointer to Spectral object 972 * @data: Pointer to phyerror event buffer 973 * @datalen: Data length 974 * @p_rfqual: RF quality info 975 * @p_chaninfo: Channel info 976 * @tsf64: 64 bit tsf timestamp 977 * @acs_stats: ACS stats 978 * 979 * Process PHY Error for gen2 980 * 981 * Return: Success/Failure 982 */ 983 int target_if_process_phyerr_gen2( 984 struct target_if_spectral *spectral, 985 uint8_t *data, 986 uint32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual, 987 struct target_if_spectral_chan_info *p_chaninfo, 988 uint64_t tsf64, 989 struct target_if_spectral_acs_stats *acs_stats); 990 991 /** 992 * target_if_spectral_send_intf_found_msg() - Indicate to application layer that 993 * interference has been found 994 * @pdev: Pointer to pdev 995 * @cw_int: 1 if CW interference is found, 0 if WLAN interference is found 996 * @dcs_enabled: 1 if DCS is enabled, 0 if DCS is disabled 997 * 998 * Send message to application layer 999 * indicating that interference has been found 1000 * 1001 * Return: None 1002 */ 1003 void target_if_spectral_send_intf_found_msg( 1004 struct wlan_objmgr_pdev *pdev, 1005 uint16_t cw_int, uint32_t dcs_enabled); 1006 1007 /** 1008 * target_if_stop_spectral_scan() - Stop spectral scan 1009 * @pdev: Pointer to pdev object 1010 * 1011 * API to stop the current on-going spectral scan 1012 * 1013 * Return: None 1014 */ 1015 void target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev); 1016 1017 /** 1018 * target_if_spectral_get_vdev() - Get pointer to vdev to be used for Spectral 1019 * operations 1020 * @spectral: Pointer to Spectral target_if internal private data 1021 * 1022 * Spectral operates on pdev. However, in order to retrieve some WLAN 1023 * properties, a vdev is required. To facilitate this, the function returns the 1024 * first vdev in our pdev. The caller should release the reference to the vdev 1025 * once it is done using it. 1026 * TODO: If the framework later provides an API to obtain the first active 1027 * vdev, then it would be preferable to use this API. 1028 * 1029 * Return: Pointer to vdev on success, NULL on failure 1030 */ 1031 struct wlan_objmgr_vdev *target_if_spectral_get_vdev( 1032 struct target_if_spectral *spectral); 1033 1034 /** 1035 * target_if_spectral_dump_hdr_gen2() - Dump Spectral header for gen2 1036 * @phdr: Pointer to Spectral Phyerr Header 1037 * 1038 * Dump Spectral header 1039 * 1040 * Return: Success/Failure 1041 */ 1042 int target_if_spectral_dump_hdr_gen2(struct spectral_phyerr_hdr_gen2 *phdr); 1043 1044 /** 1045 * target_if_get_combrssi_sec80_seg_gen2() - Get approximate combined RSSI 1046 * for Secondary 80 segment 1047 * @spectral: Pointer to spectral object 1048 * @p_sfft_sec80: Pointer to search fft info of secondary 80 segment 1049 * 1050 * Get approximate combined RSSI for Secondary 80 segment 1051 * 1052 * Return: Combined RSSI for secondary 80Mhz segment 1053 */ 1054 int8_t target_if_get_combrssi_sec80_seg_gen2( 1055 struct target_if_spectral *spectral, 1056 struct spectral_search_fft_info_gen2 *p_sfft_sec80); 1057 1058 /** 1059 * target_if_spectral_dump_tlv_gen2() - Dump Spectral TLV for gen2 1060 * @ptlv: Pointer to Spectral Phyerr TLV 1061 * @is_160_format: Indicates 160 format 1062 * 1063 * Dump Spectral TLV for gen2 1064 * 1065 * Return: Success/Failure 1066 */ 1067 int target_if_spectral_dump_tlv_gen2( 1068 struct spectral_phyerr_tlv_gen2 *ptlv, bool is_160_format); 1069 1070 /** 1071 * target_if_spectral_dump_phyerr_data_gen2() - Dump Spectral 1072 * related PHY Error for gen2 1073 * @data: Pointer to phyerror buffer 1074 * @datalen: Data length 1075 * @is_160_format: Indicates 160 format 1076 * 1077 * Dump Spectral related PHY Error for gen2 1078 * 1079 * Return: Success/Failure 1080 */ 1081 int target_if_spectral_dump_phyerr_data_gen2( 1082 uint8_t *data, 1083 uint32_t datalen, 1084 bool is_160_format); 1085 1086 /** 1087 * target_if_dump_fft_report_gen3() - Dump FFT Report for gen3 1088 * @spectral: Pointer to Spectral object 1089 * @p_fft_report: Pointer to fft report 1090 * @p_sfft: Pointer to search fft report 1091 * 1092 * Dump FFT Report for gen3 1093 * 1094 * Return: Success/Failure 1095 */ 1096 int target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, 1097 struct spectral_phyerr_fft_report_gen3 *p_fft_report, 1098 struct spectral_search_fft_info_gen3 *p_sfft); 1099 1100 /** 1101 * target_if_dbg_print_samp_msg() - Print contents of SAMP Message 1102 * @p: Pointer to SAMP message 1103 * 1104 * Print contents of SAMP Message 1105 * 1106 * Return: Void 1107 */ 1108 void target_if_dbg_print_samp_msg(struct spectral_samp_msg *pmsg); 1109 1110 /** 1111 * target_if_process_sfft_report_gen3() - Process Search FFT Report for gen3 1112 * @p_fft_report: Pointer to fft report 1113 * @p_sfft: Pointer to search fft report 1114 * 1115 * Process Search FFT Report for gen3 1116 * 1117 * Return: Success/Failure 1118 */ 1119 int target_if_process_sfft_report_gen3( 1120 struct spectral_phyerr_fft_report_gen3 *p_fft_report, 1121 struct spectral_search_fft_info_gen3 *p_fft_info); 1122 1123 /** 1124 * get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal 1125 * Spectral data 1126 * @pdev: Pointer to pdev 1127 * 1128 * Return: Handle to target_if internal Spectral data on success, NULL on 1129 * failure 1130 */ 1131 static inline 1132 struct target_if_spectral *get_target_if_spectral_handle_from_pdev( 1133 struct wlan_objmgr_pdev *pdev) 1134 { 1135 struct target_if_spectral *spectral = NULL; 1136 struct wlan_objmgr_psoc *psoc = NULL; 1137 1138 psoc = wlan_pdev_get_psoc(pdev); 1139 1140 spectral = (struct target_if_spectral *) 1141 psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_get_target_handle( 1142 pdev); 1143 return spectral; 1144 } 1145 1146 /** 1147 * target_if_vdev_get_chan_freq() - Get the operating channel frequency of a 1148 * given vdev 1149 * @pdev: Pointer to vdev 1150 * 1151 * Get the operating channel frequency of a given vdev 1152 * 1153 * Return: Operating channel frequency of a vdev 1154 */ 1155 static inline 1156 int16_t target_if_vdev_get_chan_freq(struct wlan_objmgr_vdev *vdev) 1157 { 1158 struct wlan_objmgr_psoc *psoc = NULL; 1159 1160 psoc = wlan_vdev_get_psoc(vdev); 1161 if (!psoc) { 1162 spectral_err("psoc is NULL"); 1163 return -EINVAL; 1164 } 1165 1166 return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_chan_freq( 1167 vdev); 1168 } 1169 1170 /** 1171 * target_if_vdev_get_ch_width() - Get the operating channel bandwidth of a 1172 * given vdev 1173 * @pdev: Pointer to vdev 1174 * 1175 * Get the operating channel bandwidth of a given vdev 1176 * 1177 * Return: channel bandwidth enumeration corresponding to the vdev 1178 */ 1179 static inline 1180 enum phy_ch_width target_if_vdev_get_ch_width(struct wlan_objmgr_vdev *vdev) 1181 { 1182 struct wlan_objmgr_psoc *psoc = NULL; 1183 1184 psoc = wlan_vdev_get_psoc(vdev); 1185 if (!psoc) { 1186 spectral_err("psoc is NULL"); 1187 return CH_WIDTH_INVALID; 1188 } 1189 1190 return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_vdev_get_ch_width( 1191 vdev); 1192 } 1193 1194 /** 1195 * target_if_vdev_get_sec20chan_freq_mhz() - Get the frequency of secondary 1196 * 20 MHz channel for a given vdev 1197 * @pdev: Pointer to vdev 1198 * 1199 * Get the frequency of secondary 20Mhz channel for a given vdev 1200 * 1201 * Return: Frequency of secondary 20Mhz channel for a given vdev 1202 */ 1203 static inline 1204 int target_if_vdev_get_sec20chan_freq_mhz( 1205 struct wlan_objmgr_vdev *vdev, 1206 uint16_t *sec20chan_freq) 1207 { 1208 struct wlan_objmgr_psoc *psoc = NULL; 1209 1210 psoc = wlan_vdev_get_psoc(vdev); 1211 if (!psoc) { 1212 spectral_err("psoc is NULL"); 1213 return -EINVAL; 1214 } 1215 1216 return psoc->soc_cb.rx_ops.sptrl_rx_ops. 1217 sptrlro_vdev_get_sec20chan_freq_mhz(vdev, sec20chan_freq); 1218 } 1219 1220 /** 1221 * target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask 1222 * @pdev: Pointer to pdev 1223 * @spectral_rx_chainmask: Spectral Rx chainmask 1224 * 1225 * Return: None 1226 */ 1227 static inline 1228 void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev, 1229 uint8_t spectral_rx_chainmask) 1230 { 1231 struct target_if_spectral *spectral = NULL; 1232 1233 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1234 spectral->params.ss_chn_mask = spectral_rx_chainmask; 1235 } 1236 1237 /** 1238 * target_if_spectral_process_phyerr() - Process Spectral PHY error 1239 * @pdev: Pointer to pdev 1240 * @data: PHY error data received from FW 1241 * @datalen: Length of data 1242 * @p_rfqual: Pointer to RF Quality information 1243 * @p_chaninfo: Pointer to channel information 1244 * @tsf: TSF time instance at which the Spectral sample was received 1245 * @acs_stats: ACS stats 1246 * 1247 * Process Spectral PHY error by extracting necessary information from the data 1248 * sent by FW, and send the extracted information to application layer. 1249 * 1250 * Return: None 1251 */ 1252 static inline 1253 void target_if_spectral_process_phyerr( 1254 struct wlan_objmgr_pdev *pdev, 1255 uint8_t *data, uint32_t datalen, 1256 struct target_if_spectral_rfqual_info *p_rfqual, 1257 struct target_if_spectral_chan_info *p_chaninfo, 1258 uint64_t tsf64, 1259 struct target_if_spectral_acs_stats *acs_stats) 1260 { 1261 struct target_if_spectral *spectral = NULL; 1262 struct target_if_spectral_ops *p_sops = NULL; 1263 1264 spectral = get_target_if_spectral_handle_from_pdev(pdev); 1265 p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); 1266 p_sops->spectral_process_phyerr(spectral, data, datalen, 1267 p_rfqual, p_chaninfo, 1268 tsf64, acs_stats); 1269 } 1270 1271 /** 1272 * target_if_sops_is_spectral_enabled() - Get whether Spectral is enabled 1273 * @arg: Pointer to handle for Spectral target_if internal private data 1274 * 1275 * Function to check whether Spectral is enabled 1276 * 1277 * Return: True if Spectral is enabled, false if Spectral is not enabled 1278 */ 1279 uint32_t target_if_sops_is_spectral_enabled(void *arg); 1280 1281 /** 1282 * target_if_sops_is_spectral_active() - Get whether Spectral is active 1283 * @arg: Pointer to handle for Spectral target_if internal private data 1284 * 1285 * Function to check whether Spectral is active 1286 * 1287 * Return: True if Spectral is active, false if Spectral is not active 1288 */ 1289 uint32_t target_if_sops_is_spectral_active(void *arg); 1290 1291 /** 1292 * target_if_sops_start_spectral_scan() - Start Spectral scan 1293 * @arg: Pointer to handle for Spectral target_if internal private data 1294 * 1295 * Function to start spectral scan 1296 * 1297 * Return: 0 on success else failure 1298 */ 1299 uint32_t target_if_sops_start_spectral_scan(void *arg); 1300 1301 /** 1302 * target_if_sops_stop_spectral_scan() - Stop Spectral scan 1303 * @arg: Pointer to handle for Spectral target_if internal private data 1304 * 1305 * Function to stop spectral scan 1306 * 1307 * Return: 0 in case of success, -1 on failure 1308 */ 1309 uint32_t target_if_sops_stop_spectral_scan(void *arg); 1310 1311 /** 1312 * target_if_spectral_get_extension_channel() - Get the current Extension 1313 * channel (in MHz) 1314 * @arg: Pointer to handle for Spectral target_if internal private data 1315 * 1316 * Return: Current Extension channel (in MHz) on success, 0 on failure or if 1317 * extension channel is not present. 1318 */ 1319 uint32_t target_if_spectral_get_extension_channel(void *arg); 1320 1321 /** 1322 * target_if_spectral_get_current_channel() - Get the current channel (in MHz) 1323 * @arg: Pointer to handle for Spectral target_if internal private data 1324 * 1325 * Return: Current channel (in MHz) on success, 0 on failure 1326 */ 1327 uint32_t target_if_spectral_get_current_channel(void *arg); 1328 1329 1330 /** 1331 * target_if_spectral_reset_hw() - Reset the hardware 1332 * @arg: Pointer to handle for Spectral target_if internal private data 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_reset_hw(void *arg); 1340 1341 /** 1342 * target_if_spectral_get_chain_noise_floor() - Get the Chain noise floor from 1343 * Noisefloor history buffer 1344 * @arg: Pointer to handle for Spectral target_if internal private data 1345 * @nf_buf: Pointer to buffer into which chain Noise Floor data should be copied 1346 * 1347 * This is only a placeholder since it is not currently required in the offload 1348 * case. 1349 * 1350 * Return: 0 1351 */ 1352 uint32_t target_if_spectral_get_chain_noise_floor(void *arg, int16_t *nf_buf); 1353 1354 /** 1355 * target_if_spectral_get_ext_noisefloor() - Get the extension channel 1356 * noisefloor 1357 * @arg: Pointer to handle for Spectral target_if internal private data 1358 * 1359 * This is only a placeholder since it is not currently required in the offload 1360 * case. 1361 * 1362 * Return: 0 1363 */ 1364 int8_t target_if_spectral_get_ext_noisefloor(void *arg); 1365 1366 /** 1367 * target_if_spectral_get_ctl_noisefloor() - Get the control channel noisefloor 1368 * @arg: Pointer to handle for Spectral target_if internal private data 1369 * 1370 * This is only a placeholder since it is not currently required in the offload 1371 * case. 1372 * 1373 * Return: 0 1374 */ 1375 int8_t target_if_spectral_get_ctl_noisefloor(void *arg); 1376 1377 /** 1378 * target_if_spectral_get_capability() - Get whether a given Spectral hardware 1379 * capability is available 1380 * @arg: Pointer to handle for Spectral target_if internal private data 1381 * @type: Spectral hardware capability type 1382 * 1383 * Return: True if the capability is available, false if the capability is not 1384 * available 1385 */ 1386 uint32_t target_if_spectral_get_capability( 1387 void *arg, enum spectral_capability_type type); 1388 1389 /** 1390 * target_if_spectral_set_rxfilter() - Set the RX Filter before Spectral start 1391 * @arg: Pointer to handle for Spectral target_if internal private data 1392 * @rxfilter: Rx filter to be used 1393 * 1394 * Note: This is only a placeholder function. It is not currently required since 1395 * FW should be taking care of setting the required filters. 1396 * 1397 * Return: 0 1398 */ 1399 uint32_t target_if_spectral_set_rxfilter(void *arg, int rxfilter); 1400 1401 /** 1402 * target_if_spectral_sops_configure_params() - Configure user supplied Spectral 1403 * parameters 1404 * @arg: Pointer to handle for Spectral target_if internal private data 1405 * @params: Spectral parameters 1406 * 1407 * Return: 0 in case of success, -1 on failure 1408 */ 1409 uint32_t target_if_spectral_sops_configure_params( 1410 void *arg, struct spectral_config *params); 1411 1412 /** 1413 * target_if_spectral_get_rxfilter() - Get the current RX Filter settings 1414 * @arg: Pointer to handle for Spectral target_if internal private data 1415 * 1416 * Note: This is only a placeholder function. It is not currently required since 1417 * FW should be taking care of setting the required filters. 1418 * 1419 * Return: 0 1420 */ 1421 uint32_t target_if_spectral_get_rxfilter(void *arg); 1422 1423 /** 1424 * target_if_pdev_spectral_deinit() - De-initialize target_if Spectral 1425 * functionality for the given pdev 1426 * @pdev: Pointer to pdev object 1427 * 1428 * Return: None 1429 */ 1430 void target_if_pdev_spectral_deinit(struct wlan_objmgr_pdev *pdev); 1431 1432 /** 1433 * target_if_set_spectral_config() - Set spectral config 1434 * @pdev: Pointer to pdev object 1435 * @threshtype: config type 1436 * @value: config value 1437 * 1438 * API to set spectral configurations 1439 * 1440 * Return: 0 in case of success, -1 on failure 1441 */ 1442 int target_if_set_spectral_config(struct wlan_objmgr_pdev *pdev, 1443 const uint32_t threshtype, 1444 const uint32_t value); 1445 1446 /** 1447 * target_if_pdev_spectral_init() - Initialize target_if Spectral 1448 * functionality for the given pdev 1449 * @pdev: Pointer to pdev object 1450 * 1451 * Return: On success, pointer to Spectral target_if internal private data, on 1452 * failure, NULL 1453 */ 1454 void *target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev); 1455 1456 /** 1457 * target_if_spectral_sops_get_params() - Get user configured Spectral 1458 * parameters 1459 * @arg: Pointer to handle for Spectral target_if internal private data 1460 * @params: Pointer to buffer into which Spectral parameters should be copied 1461 * 1462 * Return: 0 in case of success, -1 on failure 1463 */ 1464 uint32_t target_if_spectral_sops_get_params( 1465 void *arg, struct spectral_config *params); 1466 1467 /** 1468 * target_if_init_spectral_capability() - Initialize Spectral capability 1469 * @spectral: Pointer to Spectral target_if internal private data 1470 * 1471 * This is a workaround. 1472 * 1473 * Return: None 1474 */ 1475 void target_if_init_spectral_capability(struct target_if_spectral *spectral); 1476 1477 /** 1478 * target_if_start_spectral_scan() - Start spectral scan 1479 * @pdev: Pointer to pdev object 1480 * 1481 * API to start spectral scan 1482 * 1483 * Return: 0 in case of success, -1 on failure 1484 */ 1485 int target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev); 1486 1487 /** 1488 * target_if_get_spectral_config() - Get spectral configuration 1489 * @pdev: Pointer to pdev object 1490 * @param: Pointer to spectral_config structure in which the configuration 1491 * should be returned 1492 * 1493 * API to get the current spectral configuration 1494 * 1495 * Return: 0 in case of success, -1 on failure 1496 */ 1497 void target_if_get_spectral_config(struct wlan_objmgr_pdev *pdev, 1498 struct spectral_config *param); 1499 1500 /** 1501 * target_if_spectral_scan_enable_params() - Enable use of desired Spectral 1502 * parameters 1503 * @spectral: Pointer to Spectral target_if internal private data 1504 * @spectral_params: Pointer to Spectral parameters 1505 * 1506 * Enable use of desired Spectral parameters by configuring them into HW, and 1507 * starting Spectral scan 1508 * 1509 * Return: 0 on success, 1 on failure 1510 */ 1511 int target_if_spectral_scan_enable_params( 1512 struct target_if_spectral *spectral, struct spectral_config *spectral_params); 1513 1514 /** 1515 * target_if_is_spectral_active() - Get whether Spectral is active 1516 * @pdev: Pointer to pdev object 1517 * 1518 * Return: True if Spectral is active, false if Spectral is not active 1519 */ 1520 bool target_if_is_spectral_active(struct wlan_objmgr_pdev *pdev); 1521 1522 /** 1523 * target_if_is_spectral_enabled() - Get whether Spectral is enabled 1524 * @pdev: Pointer to pdev object 1525 * 1526 * Return: True if Spectral is enabled, false if Spectral is not enabled 1527 */ 1528 bool target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev); 1529 1530 /** 1531 * target_if_set_debug_level() - Set debug level for Spectral 1532 * @pdev: Pointer to pdev object 1533 * @debug_level: Debug level 1534 * 1535 * Return: 0 in case of success 1536 */ 1537 int target_if_set_debug_level(struct wlan_objmgr_pdev *pdev, 1538 uint32_t debug_level); 1539 1540 /** 1541 * target_if_get_debug_level() - Get debug level for Spectral 1542 * @pdev: Pointer to pdev object 1543 * 1544 * Return: Current debug level 1545 */ 1546 uint32_t target_if_get_debug_level(struct wlan_objmgr_pdev *pdev); 1547 1548 1549 /** 1550 * target_if_get_spectral_capinfo() - Get Spectral capability information 1551 * @pdev: Pointer to pdev object 1552 * @outdata: Buffer into which data should be copied 1553 * 1554 * Return: void 1555 */ 1556 void target_if_get_spectral_capinfo( 1557 struct wlan_objmgr_pdev *pdev, 1558 void *outdata); 1559 1560 1561 /** 1562 * target_if_get_spectral_diagstats() - Get Spectral diagnostic statistics 1563 * @pdev: Pointer to pdev object 1564 * @outdata: Buffer into which data should be copied 1565 * 1566 * Return: void 1567 */ 1568 void target_if_get_spectral_diagstats(struct wlan_objmgr_pdev *pdev, 1569 void *outdata); 1570 1571 /* 1572 * target_if_spectral_send_tlv_to_host - target_if_spectral_send_tlv_to_host 1573 * @spectral: Send the TLV information to Host 1574 * @data: Pointer to the TLV 1575 * @datalen: tlv length 1576 * 1577 * Return: Success/Failure 1578 * 1579 */ 1580 int target_if_spectral_send_tlv_to_host( 1581 struct target_if_spectral *spectral, 1582 uint8_t *data, uint32_t datalen); 1583 1584 void target_if_register_wmi_spectral_cmd_ops( 1585 struct wlan_objmgr_pdev *pdev, 1586 struct wmi_spectral_cmd_ops *cmd_ops); 1587 1588 #ifdef DIRECT_BUF_RX_ENABLE 1589 /** 1590 * target_if_consume_sfft_report_gen3() - Process fft report for gen3 1591 * @spectral: Pointer to spectral object 1592 * @report: Pointer to spectral report 1593 * 1594 * Process fft report for gen3 1595 * 1596 * Return: Success/Failure 1597 */ 1598 int 1599 target_if_consume_spectral_report_gen3( 1600 struct target_if_spectral *spectral, 1601 struct spectral_report *report); 1602 #endif 1603 1604 #ifdef WIN32 1605 #pragma pack(pop, target_if_spectral) 1606 #endif 1607 #ifdef __ATTRIB_PACK 1608 #undef __ATTRIB_PACK 1609 #endif 1610 1611 #endif /* WLAN_CONV_SPECTRAL_ENABLE */ 1612 #endif /* _TARGET_IF_SPECTRAL_H_ */ 1613