[PATCH v6 1/9] wifi: ath12k: Add HAL_PHYRX_GENERIC_U_SIG TLV parsing support
Vasanthakumar Thiagarajan
quic_vthiagar at quicinc.com
Wed Jan 29 03:18:49 PST 2025
On 1/29/2025 4:28 PM, Karthikeyan Periyasamy wrote:
> Currently, monitor is not enabled. However, in the future, the monitor
> will be enabled. Therefore, add the necessary HAL_PHYRX_GENERIC_U_SIG TLV
> parsing support in monitor Rx path, which help to populate the EHT
> radiotap data.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
>
> Co-developed-by: P Praneesh <quic_ppranees at quicinc.com>
> Signed-off-by: P Praneesh <quic_ppranees at quicinc.com>
> Signed-off-by: Karthikeyan Periyasamy <quic_periyasa at quicinc.com>
> ---
> drivers/net/wireless/ath/ath12k/dp_mon.c | 205 ++++++++++++++++++++++-
> drivers/net/wireless/ath/ath12k/hal_rx.h | 60 +++++++
> 2 files changed, 264 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c
> index 4e9a60181c06..61fd481b7a3b 100644
> --- a/drivers/net/wireless/ath/ath12k/dp_mon.c
> +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c
> @@ -10,6 +10,9 @@
> #include "dp_tx.h"
> #include "peer.h"
>
> +#define ATH12K_LE32_DEC_ENC(value, dec_bits, enc_bits) \
> + u32_encode_bits(le32_get_bits(value, dec_bits), enc_bits)
> +
> static void
> ath12k_dp_mon_rx_handle_ofdma_info(const struct hal_rx_ppdu_end_user_stats *ppdu_end_user,
> struct hal_rx_user_status *rx_user_status)
> @@ -562,6 +565,187 @@ static void ath12k_dp_mon_parse_he_sig_su(const struct hal_rx_he_sig_a_su_info *
> ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
> }
>
> +static void
> +ath12k_dp_mon_hal_rx_parse_u_sig_cmn(const struct hal_mon_usig_cmn *cmn,
> + struct hal_rx_mon_ppdu_info *ppdu_info)
> +{
> + u32 common;
> + u8 bw;
> +
> + bw = le32_get_bits(cmn->info0, HAL_RX_USIG_CMN_INFO0_BW);
> +
> + common = __le32_to_cpu(ppdu_info->usig.common);
> + common |= IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN |
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN |
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN |
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN |
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN |
> + ATH12K_LE32_DEC_ENC(cmn->info0,
> + HAL_RX_USIG_CMN_INFO0_PHY_VERSION,
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER) |
> + u32_encode_bits(bw, IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW) |
> + ATH12K_LE32_DEC_ENC(cmn->info0,
> + HAL_RX_USIG_CMN_INFO0_UL_DL,
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL) |
> + ATH12K_LE32_DEC_ENC(cmn->info0,
> + HAL_RX_USIG_CMN_INFO0_BSS_COLOR,
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR) |
> + ATH12K_LE32_DEC_ENC(cmn->info0,
> + HAL_RX_USIG_CMN_INFO0_TXOP,
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP);
> + ppdu_info->usig.common = cpu_to_le32(common);
> +
> + switch (bw) {
> + default:
> + fallthrough;
> + case HAL_EHT_BW_20:
> + ppdu_info->bw = HAL_RX_BW_20MHZ;
> + break;
> + case HAL_EHT_BW_40:
> + ppdu_info->bw = HAL_RX_BW_40MHZ;
> + break;
> + case HAL_EHT_BW_80:
> + ppdu_info->bw = HAL_RX_BW_80MHZ;
> + break;
> + case HAL_EHT_BW_160:
> + ppdu_info->bw = HAL_RX_BW_160MHZ;
> + break;
> + case HAL_EHT_BW_320_1:
> + case HAL_EHT_BW_320_2:
> + ppdu_info->bw = HAL_RX_BW_320MHZ;
> + break;
> + }
> +}
> +
> +static void
> +ath12k_dp_mon_hal_rx_parse_u_sig_tb(const struct hal_mon_usig_tb *usig_tb,
> + struct hal_rx_mon_ppdu_info *ppdu_info)
> +{
> + enum ieee80211_radiotap_eht_usig_tb spatial_reuse1, spatial_reuse2;
> + u32 common, value, mask;
> +
> + spatial_reuse1 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1;
> + spatial_reuse2 = IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2;
> +
> + common = __le32_to_cpu(ppdu_info->usig.common);
> + value = __le32_to_cpu(ppdu_info->usig.value);
> + mask = __le32_to_cpu(ppdu_info->usig.mask);
> +
> + common |= ATH12K_LE32_DEC_ENC(usig_tb->info0,
> + HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS,
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC);
> +
> + value |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD |
> + ATH12K_LE32_DEC_ENC(usig_tb->info0,
> + HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE,
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE) |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE |
> + ATH12K_LE32_DEC_ENC(usig_tb->info0,
> + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1,
> + spatial_reuse1) |
> + ATH12K_LE32_DEC_ENC(usig_tb->info0,
> + HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2,
> + spatial_reuse2) |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD |
> + ATH12K_LE32_DEC_ENC(usig_tb->info0,
> + HAL_RX_USIG_TB_INFO0_CRC,
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC) |
> + ATH12K_LE32_DEC_ENC(usig_tb->info0,
> + HAL_RX_USIG_TB_INFO0_TAIL,
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL);
> +
> + mask |= IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE |
> + spatial_reuse1 | spatial_reuse2 |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC |
> + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL;
> +
> + ppdu_info->usig.common = cpu_to_le32(common);
> + ppdu_info->usig.value = cpu_to_le32(value);
> + ppdu_info->usig.mask = cpu_to_le32(mask);
> +}
> +
> +static void
> +ath12k_dp_mon_hal_rx_parse_u_sig_mu(const struct hal_mon_usig_mu *usig_mu,
> + struct hal_rx_mon_ppdu_info *ppdu_info)
> +{
> + enum ieee80211_radiotap_eht_usig_mu sig_symb, punc;
> + u32 common, value, mask;
> +
> + sig_symb = IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS;
> + punc = IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO;
> +
> + common = __le32_to_cpu(ppdu_info->usig.common);
> + value = __le32_to_cpu(ppdu_info->usig.value);
> + mask = __le32_to_cpu(ppdu_info->usig.mask);
> +
> + common |= ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS,
> + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC);
> +
> + value |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD |
> + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE |
> + ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE,
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE) |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE |
> + ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO,
> + punc) |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE |
> + ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS,
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS) |
> + ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM,
> + sig_symb) |
> + ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_CRC,
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC) |
> + ATH12K_LE32_DEC_ENC(usig_mu->info0,
> + HAL_RX_USIG_MU_INFO0_TAIL,
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL);
> +
> + mask |= IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD |
> + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE |
> + punc |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS |
> + sig_symb |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC |
> + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL;
> +
> + ppdu_info->usig.common = cpu_to_le32(common);
> + ppdu_info->usig.value = cpu_to_le32(value);
> + ppdu_info->usig.mask = cpu_to_le32(mask);
> +}
> +
> +static void
> +ath12k_dp_mon_hal_rx_parse_u_sig_hdr(const struct hal_mon_usig_hdr *usig,
> + struct hal_rx_mon_ppdu_info *ppdu_info)
> +{
> + const struct hal_mon_usig_cmn *usig_cmn = &usig->cmn;
> + u8 comp_mode;
> + bool ap_ppdu;
> +
> + ppdu_info->eht_usig = true;
> +
> + ath12k_dp_mon_hal_rx_parse_u_sig_cmn(&usig->cmn, ppdu_info);
> +
> + ap_ppdu = le32_get_bits(usig_cmn->info0, HAL_RX_USIG_CMN_INFO0_UL_DL);
> + comp_mode = le32_get_bits(usig->non_cmn.mu.info0,
> + HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE);
> +
> + if (comp_mode == 0 && ap_ppdu)
> + ath12k_dp_mon_hal_rx_parse_u_sig_tb(&usig->non_cmn.tb, ppdu_info);
> + else
> + ath12k_dp_mon_hal_rx_parse_u_sig_mu(&usig->non_cmn.mu, ppdu_info);
> +}
> +
> static enum hal_rx_mon_status
> ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar,
> struct ath12k_mon_data *pmon,
> @@ -774,6 +958,9 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar,
> return HAL_RX_MON_STATUS_MSDU_END;
> case HAL_RX_MPDU_END:
> return HAL_RX_MON_STATUS_MPDU_END;
> + case HAL_PHYRX_GENERIC_U_SIG:
> + ath12k_dp_mon_hal_rx_parse_u_sig_hdr(tlv_data, ppdu_info);
> + break;
> case HAL_DUMMY:
> return HAL_RX_MON_STATUS_BUF_DONE;
> case HAL_RX_PPDU_END_STATUS_DONE:
> @@ -971,7 +1158,23 @@ static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,
> rxs->ampdu_reference = ampdu_id;
> }
>
> - if (ppduinfo->he_mu_flags) {
> + if (ppduinfo->eht_usig) {
> + struct ieee80211_radiotap_tlv *tlv;
> + struct ieee80211_radiotap_eht_usig *usig;
> + u16 len = sizeof(*usig);
> +
> + rxs->flag |= RX_FLAG_RADIOTAP_TLV_AT_END;
> + rxs->encoding = RX_ENC_EHT;
> +
> + skb_reset_mac_header(mon_skb);
> +
> + tlv = skb_push(mon_skb, sizeof(*tlv) + len);
> + tlv->type = cpu_to_le16(IEEE80211_RADIOTAP_EHT_USIG);
> + tlv->len = cpu_to_le16(len);
> +
> + usig = (struct ieee80211_radiotap_eht_usig *)tlv->data;
> + *usig = ppduinfo->usig;
> + } else if (ppduinfo->he_mu_flags) {
> rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;
> rxs->encoding = RX_ENC_HE;
> ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));
> diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.h b/drivers/net/wireless/ath/ath12k/hal_rx.h
> index 96954b2f7ca6..2da16f27e76c 100644
> --- a/drivers/net/wireless/ath/ath12k/hal_rx.h
> +++ b/drivers/net/wireless/ath/ath12k/hal_rx.h
> @@ -235,6 +235,8 @@ struct hal_rx_mon_ppdu_info {
> bool is_ampdu;
> u8 medium_prot_type;
> bool ppdu_continuation;
> + bool eht_usig;
> + struct ieee80211_radiotap_eht_usig usig;
> };
>
> #define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0)
> @@ -678,6 +680,64 @@ enum nl80211_he_ru_alloc ath12k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones)
> return ret;
> }
>
> +enum hal_eht_bw {
> + HAL_EHT_BW_20,
> + HAL_EHT_BW_40,
> + HAL_EHT_BW_80,
> + HAL_EHT_BW_160,
> + HAL_EHT_BW_320_1,
> + HAL_EHT_BW_320_2,
> +};
> +
> +#define HAL_RX_USIG_CMN_INFO0_PHY_VERSION GENMASK(2, 0)
> +#define HAL_RX_USIG_CMN_INFO0_BW GENMASK(5, 3)
> +#define HAL_RX_USIG_CMN_INFO0_UL_DL BIT(6)
> +#define HAL_RX_USIG_CMN_INFO0_BSS_COLOR GENMASK(12, 7)
> +#define HAL_RX_USIG_CMN_INFO0_TXOP GENMASK(19, 13)
> +#define HAL_RX_USIG_CMN_INFO0_DISREGARD GENMASK(25, 20)
> +#define HAL_RX_USIG_CMN_INFO0_VALIDATE BIT(26)
> +
> +struct hal_mon_usig_cmn {
> + __le32 info0;
> +} __packed;
> +
> +#define HAL_RX_USIG_TB_INFO0_PPDU_TYPE_COMP_MODE GENMASK(1, 0)
> +#define HAL_RX_USIG_TB_INFO0_VALIDATE BIT(2)
> +#define HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_1 GENMASK(6, 3)
> +#define HAL_RX_USIG_TB_INFO0_SPATIAL_REUSE_2 GENMASK(10, 7)
> +#define HAL_RX_USIG_TB_INFO0_DISREGARD_1 GENMASK(15, 11)
> +#define HAL_RX_USIG_TB_INFO0_CRC GENMASK(19, 16)
> +#define HAL_RX_USIG_TB_INFO0_TAIL GENMASK(25, 20)
> +#define HAL_RX_USIG_TB_INFO0_RX_INTEG_CHECK_PASS BIT(31)
> +
> +struct hal_mon_usig_tb {
> + __le32 info0;
> +} __packed;
> +
> +#define HAL_RX_USIG_MU_INFO0_PPDU_TYPE_COMP_MODE GENMASK(1, 0)
> +#define HAL_RX_USIG_MU_INFO0_VALIDATE_1 BIT(2)
> +#define HAL_RX_USIG_MU_INFO0_PUNC_CH_INFO GENMASK(7, 3)
> +#define HAL_RX_USIG_MU_INFO0_VALIDATE_2 BIT(8)
> +#define HAL_RX_USIG_MU_INFO0_EHT_SIG_MCS GENMASK(10, 9)
> +#define HAL_RX_USIG_MU_INFO0_NUM_EHT_SIG_SYM GENMASK(15, 11)
> +#define HAL_RX_USIG_MU_INFO0_CRC GENMASK(20, 16)
> +#define HAL_RX_USIG_MU_INFO0_TAIL GENMASK(26, 21)
> +#define HAL_RX_USIG_MU_INFO0_RX_INTEG_CHECK_PASS BIT(31)
> +
> +struct hal_mon_usig_mu {
> + __le32 info0;
> +} __packed;
> +
> +union hal_mon_usig_non_cmn {
> + struct hal_mon_usig_tb tb;
> + struct hal_mon_usig_mu mu;
> +};
> +
> +struct hal_mon_usig_hdr {
> + struct hal_mon_usig_cmn cmn;
> + union hal_mon_usig_non_cmn non_cmn;
> +} __packed;
> +
> void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab,
> struct hal_tlv_64_hdr *tlv,
> struct hal_reo_status *status);
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan at oss.qualcomm.com>
More information about the ath12k
mailing list