| /* SPDX-License-Identifier: BSD-3-Clause-Clear */ |
| /* |
| * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. |
| * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. |
| */ |
| |
| #ifndef ATH11K_CFR_H |
| #define ATH11K_CFR_H |
| |
| #include "dbring.h" |
| #include "wmi.h" |
| |
| #define ATH11K_CFR_NUM_RESP_PER_EVENT 1 |
| #define ATH11K_CFR_EVENT_TIMEOUT_MS 1 |
| #define ATH11K_CFR_NUM_RING_ENTRIES 1 |
| |
| #define ATH11K_MAX_CFR_ENABLED_CLIENTS 10 |
| #define CFR_MAX_LUT_ENTRIES 136 |
| |
| #define HOST_MAX_CHAINS 8 |
| |
| enum ath11k_cfr_correlate_event_type { |
| ATH11K_CORRELATE_DBR_EVENT, |
| ATH11K_CORRELATE_TX_EVENT, |
| }; |
| |
| struct ath11k_sta; |
| struct ath11k_per_peer_cfr_capture; |
| |
| #define ATH11K_CFR_START_MAGIC 0xDEADBEAF |
| #define ATH11K_CFR_END_MAGIC 0xBEAFDEAD |
| |
| #define VENDOR_QCA 0x8cfdf0 |
| #define PLATFORM_TYPE_ARM 2 |
| |
| enum ath11k_cfr_meta_version { |
| ATH11K_CFR_META_VERSION_NONE, |
| ATH11K_CFR_META_VERSION_1, |
| ATH11K_CFR_META_VERSION_2, |
| ATH11K_CFR_META_VERSION_3, |
| ATH11K_CFR_META_VERSION_4, |
| ATH11K_CFR_META_VERSION_MAX = 0xFF, |
| }; |
| |
| enum ath11k_cfr_data_version { |
| ATH11K_CFR_DATA_VERSION_NONE, |
| ATH11K_CFR_DATA_VERSION_1, |
| ATH11K_CFR_DATA_VERSION_MAX = 0xFF, |
| }; |
| |
| enum ath11k_cfr_capture_ack_mode { |
| ATH11K_CFR_CAPTURE_LEGACY_ACK, |
| ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK, |
| ATH11K_CFR_CAPTURE_HT_ACK, |
| ATH11K_CFR_CAPTURE_VHT_ACK, |
| |
| /*Always keep this at last*/ |
| ATH11K_CFR_CAPTURE_INVALID_ACK |
| }; |
| |
| enum ath11k_cfr_correlate_status { |
| ATH11K_CORRELATE_STATUS_RELEASE, |
| ATH11K_CORRELATE_STATUS_HOLD, |
| ATH11K_CORRELATE_STATUS_ERR, |
| }; |
| |
| enum ath11k_cfr_preamble_type { |
| ATH11K_CFR_PREAMBLE_TYPE_LEGACY, |
| ATH11K_CFR_PREAMBLE_TYPE_HT, |
| ATH11K_CFR_PREAMBLE_TYPE_VHT, |
| }; |
| |
| struct ath11k_cfr_peer_tx_param { |
| u32 capture_method; |
| u32 vdev_id; |
| u8 peer_mac_addr[ETH_ALEN]; |
| u32 primary_20mhz_chan; |
| u32 bandwidth; |
| u32 phy_mode; |
| u32 band_center_freq1; |
| u32 band_center_freq2; |
| u32 spatial_streams; |
| u32 correlation_info_1; |
| u32 correlation_info_2; |
| u32 status; |
| u32 timestamp_us; |
| u32 counter; |
| u32 chain_rssi[WMI_MAX_CHAINS]; |
| u16 chain_phase[WMI_MAX_CHAINS]; |
| u32 cfo_measurement; |
| u8 agc_gain[HOST_MAX_CHAINS]; |
| u32 rx_start_ts; |
| }; |
| |
| struct cfr_metadata { |
| u8 peer_addr[ETH_ALEN]; |
| u8 status; |
| u8 capture_bw; |
| u8 channel_bw; |
| u8 phy_mode; |
| u16 prim20_chan; |
| u16 center_freq1; |
| u16 center_freq2; |
| u8 capture_mode; |
| u8 capture_type; |
| u8 sts_count; |
| u8 num_rx_chain; |
| u32 timestamp; |
| u32 length; |
| u32 chain_rssi[HOST_MAX_CHAINS]; |
| u16 chain_phase[HOST_MAX_CHAINS]; |
| u32 cfo_measurement; |
| u8 agc_gain[HOST_MAX_CHAINS]; |
| u32 rx_start_ts; |
| } __packed; |
| |
| struct ath11k_csi_cfr_header { |
| u32 start_magic_num; |
| u32 vendorid; |
| u8 cfr_metadata_version; |
| u8 cfr_data_version; |
| u8 chip_type; |
| u8 platform_type; |
| u32 cfr_metadata_len; |
| struct cfr_metadata meta_data; |
| } __packed; |
| |
| #define TONES_IN_20MHZ 256 |
| #define TONES_IN_40MHZ 512 |
| #define TONES_IN_80MHZ 1024 |
| #define TONES_IN_160MHZ 2048 /* 160 MHz isn't supported yet */ |
| #define TONES_INVALID 0 |
| |
| #define CFIR_DMA_HDR_INFO0_TAG GENMASK(7, 0) |
| #define CFIR_DMA_HDR_INFO0_LEN GENMASK(13, 8) |
| |
| #define CFIR_DMA_HDR_INFO1_UPLOAD_DONE GENMASK(0, 0) |
| #define CFIR_DMA_HDR_INFO1_CAPTURE_TYPE GENMASK(3, 1) |
| #define CFIR_DMA_HDR_INFO1_PREAMBLE_TYPE GENMASK(5, 4) |
| #define CFIR_DMA_HDR_INFO1_NSS GENMASK(8, 6) |
| #define CFIR_DMA_HDR_INFO1_NUM_CHAINS GENMASK(11, 9) |
| #define CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW GENMASK(14, 12) |
| #define CFIR_DMA_HDR_INFO1_SW_PEER_ID_VALID GENMASK(15, 15) |
| |
| struct ath11k_cfr_dma_hdr { |
| u16 info0; |
| u16 info1; |
| u16 sw_peer_id; |
| u16 phy_ppdu_id; |
| }; |
| |
| struct ath11k_look_up_table { |
| bool dbr_recv; |
| bool tx_recv; |
| u8 *data; |
| u32 data_len; |
| u16 dbr_ppdu_id; |
| u16 tx_ppdu_id; |
| dma_addr_t dbr_address; |
| struct ath11k_csi_cfr_header header; |
| struct ath11k_cfr_dma_hdr hdr; |
| u64 txrx_tstamp; |
| u64 dbr_tstamp; |
| u32 header_length; |
| u32 payload_length; |
| struct ath11k_dbring_element *buff; |
| }; |
| |
| struct cfr_unassoc_pool_entry { |
| u8 peer_mac[ETH_ALEN]; |
| u32 period; |
| bool is_valid; |
| }; |
| |
| struct ath11k_cfr { |
| struct ath11k_dbring rx_ring; |
| /* Protects cfr data */ |
| spinlock_t lock; |
| /* Protect for lut entries */ |
| spinlock_t lut_lock; |
| struct ath11k_look_up_table *lut; |
| struct dentry *enable_cfr; |
| struct dentry *cfr_unassoc; |
| struct rchan *rfs_cfr_capture; |
| u8 cfr_enabled_peer_cnt; |
| u32 lut_num; |
| u64 tx_evt_cnt; |
| u64 dbr_evt_cnt; |
| u64 release_cnt; |
| u64 tx_peer_status_cfr_fail; |
| u64 tx_evt_status_cfr_fail; |
| u64 tx_dbr_lookup_fail; |
| u64 last_success_tstamp; |
| u64 flush_dbr_cnt; |
| u64 clear_txrx_event; |
| u64 cfr_dma_aborts; |
| bool enabled; |
| enum wmi_phy_mode phymode; |
| struct cfr_unassoc_pool_entry unassoc_pool[ATH11K_MAX_CFR_ENABLED_CLIENTS]; |
| }; |
| |
| enum ath11k_cfr_capture_method { |
| ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME, |
| ATH11K_CFR_CAPTURE_METHOD_NULL_FRAME_WITH_PHASE, |
| ATH11K_CFR_CAPTURE_METHOD_PROBE_RESP, |
| ATH11K_CFR_CAPTURE_METHOD_MAX, |
| }; |
| |
| enum ath11k_cfr_capture_bw { |
| ATH11K_CFR_CAPTURE_BW_20, |
| ATH11K_CFR_CAPTURE_BW_40, |
| ATH11K_CFR_CAPTURE_BW_80, |
| ATH11K_CFR_CAPTURE_BW_MAX, |
| }; |
| |
| #ifdef CONFIG_ATH11K_CFR |
| int ath11k_cfr_init(struct ath11k_base *ab); |
| void ath11k_cfr_deinit(struct ath11k_base *ab); |
| void ath11k_cfr_lut_update_paddr(struct ath11k *ar, dma_addr_t paddr, |
| u32 buf_id); |
| void ath11k_cfr_decrement_peer_count(struct ath11k *ar, |
| struct ath11k_sta *arsta); |
| void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar, |
| const u8 *peer_mac); |
| bool ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, |
| const u8 *peer_mac); |
| void ath11k_cfr_update_unassoc_pool(struct ath11k *ar, |
| struct ath11k_per_peer_cfr_capture *params, |
| u8 *peer_mac); |
| int ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, |
| struct ath11k_sta *arsta, |
| struct ath11k_per_peer_cfr_capture *params, |
| const u8 *peer_mac); |
| struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar); |
| void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut); |
| int ath11k_process_cfr_capture_event(struct ath11k_base *ab, |
| struct ath11k_cfr_peer_tx_param *params); |
| void ath11k_cfr_update_phymode(struct ath11k *ar, enum wmi_phy_mode phymode); |
| #else |
| static inline void ath11k_cfr_update_phymode(struct ath11k *ar, |
| enum wmi_phy_mode phymode) |
| { |
| } |
| |
| static inline int ath11k_cfr_init(struct ath11k_base *ab) |
| { |
| return 0; |
| } |
| |
| static inline void ath11k_cfr_deinit(struct ath11k_base *ab) |
| { |
| } |
| |
| static inline void ath11k_cfr_lut_update_paddr(struct ath11k *ar, |
| dma_addr_t paddr, u32 buf_id) |
| { |
| } |
| |
| static inline void ath11k_cfr_decrement_peer_count(struct ath11k *ar, |
| struct ath11k_sta *arsta) |
| { |
| } |
| |
| static inline void ath11k_cfr_update_unassoc_pool_entry(struct ath11k *ar, |
| const u8 *peer_mac) |
| { |
| } |
| |
| static inline bool |
| ath11k_cfr_peer_is_in_cfr_unassoc_pool(struct ath11k *ar, const u8 *peer_mac) |
| { |
| return false; |
| } |
| |
| static inline void |
| ath11k_cfr_update_unassoc_pool(struct ath11k *ar, |
| struct ath11k_per_peer_cfr_capture *params, |
| u8 *peer_mac) |
| { |
| } |
| |
| static inline int |
| ath11k_cfr_send_peer_cfr_capture_cmd(struct ath11k *ar, |
| struct ath11k_sta *arsta, |
| struct ath11k_per_peer_cfr_capture *params, |
| const u8 *peer_mac) |
| { |
| return 0; |
| } |
| |
| static inline void ath11k_cfr_release_lut_entry(struct ath11k_look_up_table *lut) |
| { |
| } |
| |
| static inline |
| struct ath11k_dbring *ath11k_cfr_get_dbring(struct ath11k *ar) |
| { |
| return NULL; |
| } |
| |
| static inline |
| int ath11k_process_cfr_capture_event(struct ath11k_base *ab, |
| struct ath11k_cfr_peer_tx_param *params) |
| { |
| return 0; |
| } |
| #endif /* CONFIG_ATH11K_CFR */ |
| #endif /* ATH11K_CFR_H */ |