From f251063dfeb6d6ab15a8a426b6b9238b406704f0 Mon Sep 17 00:00:00 2001 From: Venkateswara Naralasetty Date: Wed, 17 Feb 2021 12:10:24 +0530 Subject: [PATCH] ath11k: add new parameters for tx based capture This change add new parameters as part of cfr metadata for tx based capture dumps. Newly added parameters, * CFO measurement * per chain AGC gain * rx start timestamp Signed-off-by: Venkateswara Naralasetty --- drivers/net/wireless/ath/ath11k/cfr.c | 8 +-- drivers/net/wireless/ath/ath11k/cfr.h | 59 +++++++++++++++++++++- drivers/net/wireless/ath/ath11k/debugfs_sta.c | 6 +-- drivers/net/wireless/ath/ath11k/hw.c | 70 +++++++++++++++------------ drivers/net/wireless/ath/ath11k/wmi.c | 13 ++++- drivers/net/wireless/ath/ath11k/wmi.h | 5 +- 6 files changed, 121 insertions(+), 40 deletions(-) --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -276,7 +276,7 @@ static int ath11k_cfr_enh_process_data(s struct ath11k_cfr_look_up_table *lut; struct ath11k_csi_cfr_header *header; struct ath11k_cfir_enh_dma_hdr dma_hdr; - struct cfr_metadata_version_3 *meta; + struct cfr_metadata_version_5 *meta; void *mu_rx_user_info = NULL, *freeze_tlv = NULL; u8 *peer_macaddr; u8 *data; @@ -343,7 +343,7 @@ static int ath11k_cfr_enh_process_data(s memcpy(&lut->dma_hdr.enh_hdr, &dma_hdr, sizeof(struct ath11k_cfir_enh_dma_hdr)); header = &lut->header; - meta = &header->u.meta_v3; + meta = &header->u.meta_v5; meta->channel_bw = FIELD_GET(CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW, dma_hdr.hdr.info1); meta->num_rx_chain = @@ -450,9 +450,9 @@ static int ath11k_cfr_process_data(struc memcpy(&lut->dma_hdr.hdr, &dma_hdr, sizeof(struct ath11k_cfir_dma_hdr)); header = &lut->header; - header->u.meta_v2.channel_bw = FIELD_GET(CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW, + header->u.meta_v4.channel_bw = FIELD_GET(CFIR_DMA_HDR_INFO1_UPLOAD_PKT_BW, dma_hdr.info1); - header->u.meta_v2.length = length; + header->u.meta_v4.length = length; status = ath11k_cfr_correlate_and_relay(ar, lut, ATH11K_CORRELATE_DBR_EVENT); --- a/drivers/net/wireless/ath/ath11k/cfr.h +++ b/drivers/net/wireless/ath/ath11k/cfr.h @@ -35,6 +35,8 @@ enum ath11k_cfr_meta_version { ATH11K_CFR_META_VERSION_1, ATH11K_CFR_META_VERSION_2, ATH11K_CFR_META_VERSION_3, + ATH11K_CFR_META_VERSION_4, + ATH11K_CFR_META_VERSION_5, ATH11K_CFR_META_VERSION_MAX = 0xFF, }; @@ -77,6 +79,10 @@ struct ath11k_cfr_peer_tx_param { u32 counter; u32 chain_rssi[WMI_MAX_CHAINS]; u16 chain_phase[WMI_MAX_CHAINS]; + u32 cfo_measurement; + u8 agc_gain[WMI_MAX_CHAINS]; + u32 rx_start_ts; + u32 rx_ts_reset; }; struct cfr_metadata_version_1 { @@ -142,6 +148,55 @@ struct cfr_metadata_version_3 { u16 chain_phase[HOST_MAX_CHAINS]; } __packed; +struct cfr_metadata_version_4 { + 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 cfr_metadata_version_5 { + 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; + u64 timestamp; + u32 length; + u8 is_mu_ppdu; + u8 num_mu_users; + union { + u8 su_peer_addr[ETH_ALEN]; + u8 mu_peer_addr[MAX_CFR_MU_USERS][ETH_ALEN]; + } peer_addr; + 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; @@ -149,11 +204,13 @@ struct ath11k_csi_cfr_header { u8 cfr_data_version; u8 chip_type; u8 pltform_type; - u32 Reserved; + u32 cfr_metadata_len; union { struct cfr_metadata_version_1 meta_v1; struct cfr_metadata_version_2 meta_v2; struct cfr_metadata_version_3 meta_v3; + struct cfr_metadata_version_4 meta_v4; + struct cfr_metadata_version_5 meta_v5; } u; } __packed; --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c @@ -1386,14 +1386,7 @@ static ssize_t ath11k_dbg_sta_write_cfr_ if (cfr_capture_enable > WMI_PEER_CFR_CAPTURE_ENABLE || cfr_capture_bw > sta->bandwidth || cfr_capture_method > CFR_CAPURE_METHOD_NULL_FRAME_WITH_PHASE || - cfr_capture_period > WMI_PEER_CFR_PERIODICITY_MAX) { - ret = -EINVAL; - goto out; - } - - /* Target expects cfr period in multiple of 10 */ - if (cfr_capture_period % 10) { - ath11k_err(ar->ab, "periodicity should be 10x\n"); + cfr_capture_period > WMI_PEER_CFR_PERIODICITY_MAX) { ret = -EINVAL; goto out; } --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -852,60 +852,70 @@ void ath11k_hw_ipq8074_fill_cfr_hdr_info struct ath11k_csi_cfr_header *header, struct ath11k_cfr_peer_tx_param *params) { - header->cfr_metadata_version = ATH11K_CFR_META_VERSION_2; + header->cfr_metadata_version = ATH11K_CFR_META_VERSION_4; header->cfr_data_version = ATH11K_CFR_DATA_VERSION_1; + header->cfr_metadata_len =sizeof(struct cfr_metadata_version_4); /* TODO: can we add this chip_type to hw param table */ header->chip_type = ATH11K_CFR_RADIO_IPQ8074; - header->u.meta_v2.status = FIELD_GET(WMI_CFR_PEER_CAPTURE_STATUS, + header->u.meta_v4.status = FIELD_GET(WMI_CFR_PEER_CAPTURE_STATUS, params->status); - header->u.meta_v2.capture_bw = params->bandwidth; - header->u.meta_v2.phy_mode = params->phy_mode; - header->u.meta_v2.prim20_chan = params->primary_20mhz_chan; - header->u.meta_v2.center_freq1 = params->band_center_freq1; - header->u.meta_v2.center_freq2 = params->band_center_freq2; + header->u.meta_v4.capture_bw = params->bandwidth; + header->u.meta_v4.phy_mode = params->phy_mode; + header->u.meta_v4.prim20_chan = params->primary_20mhz_chan; + header->u.meta_v4.center_freq1 = params->band_center_freq1; + header->u.meta_v4.center_freq2 = params->band_center_freq2; /* Currently CFR data is captured on ACK of a Qos NULL frame. * For 20 MHz, ACK is Legacy and for 40/80/160, ACK is DUP Legacy. */ - header->u.meta_v2.capture_mode = params->bandwidth ? + header->u.meta_v4.capture_mode = params->bandwidth ? ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK : ATH11K_CFR_CAPTURE_LEGACY_ACK; - header->u.meta_v2.capture_type = params->capture_method; - header->u.meta_v2.num_rx_chain = ar->cfg_rx_chainmask; - header->u.meta_v2.sts_count = params->spatial_streams; - header->u.meta_v2.timestamp = params->timestamp_us; - memcpy(header->u.meta_v2.peer_addr, params->peer_mac_addr, ETH_ALEN); - memcpy(header->u.meta_v2.chain_rssi, params->chain_rssi, + header->u.meta_v4.capture_type = params->capture_method; + header->u.meta_v4.num_rx_chain = ar->cfg_rx_chainmask; + header->u.meta_v4.sts_count = params->spatial_streams; + header->u.meta_v4.timestamp = params->timestamp_us; + header->u.meta_v4.cfo_measurement = params->cfo_measurement; + header->u.meta_v4.rx_start_ts = params->rx_start_ts; + memcpy(header->u.meta_v4.peer_addr, params->peer_mac_addr, ETH_ALEN); + memcpy(header->u.meta_v4.chain_rssi, params->chain_rssi, sizeof(params->chain_rssi)); - memcpy(header->u.meta_v2.chain_phase, params->chain_phase, + memcpy(header->u.meta_v4.chain_phase, params->chain_phase, sizeof(params->chain_phase)); + memcpy(header->u.meta_v4.agc_gain, params->agc_gain, + sizeof(params->agc_gain)); } void ath11k_hw_qcn9074_fill_cfr_hdr_info(struct ath11k *ar, struct ath11k_csi_cfr_header *header, struct ath11k_cfr_peer_tx_param *params) { - header->cfr_metadata_version = ATH11K_CFR_META_VERSION_3; + header->cfr_metadata_version = ATH11K_CFR_META_VERSION_5; header->cfr_data_version = ATH11K_CFR_DATA_VERSION_1; header->chip_type = ATH11K_CFR_RADIO_QCN9074; - header->u.meta_v3.status = FIELD_GET(WMI_CFR_PEER_CAPTURE_STATUS, + header->cfr_metadata_len = sizeof(struct cfr_metadata_version_5); + header->u.meta_v5.status = FIELD_GET(WMI_CFR_PEER_CAPTURE_STATUS, params->status); - header->u.meta_v3.capture_bw = params->bandwidth; - header->u.meta_v3.phy_mode = params->phy_mode; - header->u.meta_v3.prim20_chan = params->primary_20mhz_chan; - header->u.meta_v3.center_freq1 = params->band_center_freq1; - header->u.meta_v3.center_freq2 = params->band_center_freq2; - header->u.meta_v3.capture_mode = params->bandwidth ? + header->u.meta_v5.capture_bw = params->bandwidth; + header->u.meta_v5.phy_mode = params->phy_mode; + header->u.meta_v5.prim20_chan = params->primary_20mhz_chan; + header->u.meta_v5.center_freq1 = params->band_center_freq1; + header->u.meta_v5.center_freq2 = params->band_center_freq2; + header->u.meta_v5.capture_mode = params->bandwidth ? ATH11K_CFR_CAPTURE_DUP_LEGACY_ACK : ATH11K_CFR_CAPTURE_LEGACY_ACK; - header->u.meta_v3.capture_type = params->capture_method; - header->u.meta_v3.num_rx_chain = ar->cfg_rx_chainmask; - header->u.meta_v3.sts_count = params->spatial_streams; - header->u.meta_v3.timestamp = params->timestamp_us; - memcpy(header->u.meta_v3.peer_addr.su_peer_addr, + header->u.meta_v5.capture_type = params->capture_method; + header->u.meta_v5.num_rx_chain = ar->cfg_rx_chainmask; + header->u.meta_v5.sts_count = params->spatial_streams; + header->u.meta_v5.timestamp = params->timestamp_us; + header->u.meta_v5.cfo_measurement = params->cfo_measurement; + header->u.meta_v5.rx_start_ts = params->rx_start_ts; + memcpy(header->u.meta_v5.peer_addr.su_peer_addr, params->peer_mac_addr, ETH_ALEN); - memcpy(header->u.meta_v3.chain_rssi, params->chain_rssi, + memcpy(header->u.meta_v5.chain_rssi, params->chain_rssi, sizeof(params->chain_rssi)); - memcpy(header->u.meta_v3.chain_phase, params->chain_phase, + memcpy(header->u.meta_v5.chain_phase, params->chain_phase, sizeof(params->chain_phase)); + memcpy(header->u.meta_v5.agc_gain, params->agc_gain, + sizeof(params->agc_gain)); } const struct ath11k_hw_ops ipq8074_ops = { @@ -955,6 +965,7 @@ const struct ath11k_hw_ops ipq8074_ops = .rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid, .rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr, .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, + .fill_cfr_hdr_info = ath11k_hw_ipq8074_fill_cfr_hdr_info, }; const struct ath11k_hw_ops ipq6018_ops = { @@ -1004,7 +1015,6 @@ const struct ath11k_hw_ops ipq6018_ops = .rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid, .rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr, .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, - .fill_cfr_hdr_info = ath11k_hw_ipq8074_fill_cfr_hdr_info, }; const struct ath11k_hw_ops qca6390_ops = { --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -9043,6 +9043,15 @@ static void ath11k_wmi_tlv_cfr_cpature_e tx_params->counter = params->counter; memcpy(tx_params->chain_rssi, params->chain_rssi, sizeof(tx_params->chain_rssi)); + + if (WMI_CFR_CFO_MEASUREMENT_VALID & params->cfo_measurement) + tx_params->cfo_measurement = FIELD_GET(WMI_CFR_CFO_MEASUREMENT_RAW_DATA, + params->cfo_measurement); + else + tx_params->cfo_measurement = 0; + + tx_params->rx_start_ts = params->rx_start_ts; + tx_params->rx_ts_reset = params->rx_ts_reset; } static void ath11k_wmi_tlv_cfr_cpature_phase_fixed_param(const void *ptr, @@ -9054,8 +9063,10 @@ static void ath11k_wmi_tlv_cfr_cpature_p (struct ath11k_wmi_cfr_peer_tx_event_phase_param *)ptr; int i; - for (i = 0; i < WMI_MAX_CHAINS; i++) + for (i = 0; i < WMI_MAX_CHAINS; i++) { tx_params->chain_phase[i] = params->chain_phase[i]; + tx_params->agc_gain[i] = params->agc_gain[i]; + } } static int ath11k_wmi_tlv_cfr_capture_evt_parse(struct ath11k_base *ab, --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -3569,7 +3569,7 @@ struct wmi_peer_cfr_capture_cmd_fixed_pa #define WMI_CFR_CORRELATION_INFO2_BUF_ADDR_HIGH GENMASK(3, 0) #define WMI_CFR_CORRELATION_INFO2_PPDU_ID GENMASK(31, 16) -#define WMI_CFR_CFO_MEASUREMENT_VALID GENMASK(0, 0) +#define WMI_CFR_CFO_MEASUREMENT_VALID BIT(0) #define WMI_CFR_CFO_MEASUREMENT_RAW_DATA GENMASK(14, 1) struct ath11k_wmi_cfr_peer_tx_event_param { @@ -3589,10 +3589,13 @@ struct ath11k_wmi_cfr_peer_tx_event_para u32 counter; u32 chain_rssi[WMI_MAX_CHAINS]; u32 cfo_measurement; + u32 rx_start_ts; + u32 rx_ts_reset; } __packed; struct ath11k_wmi_cfr_peer_tx_event_phase_param { u32 chain_phase[WMI_MAX_CHAINS]; + u8 agc_gain[WMI_MAX_CHAINS]; } __packed; enum ath11k_wmi_cfr_capture_bw {