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