]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: Add HAL_PHYRX_GENERIC_U_SIG TLV parsing support
authorKarthikeyan Periyasamy <quic_periyasa@quicinc.com>
Thu, 6 Feb 2025 01:38:46 +0000 (07:08 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Tue, 11 Feb 2025 15:27:08 +0000 (07:27 -0800)
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@quicinc.com>
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Link: https://patch.msgid.link/20250206013854.174765-2-quic_periyasa@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/dp_mon.c
drivers/net/wireless/ath/ath12k/hal_rx.h

index d529229f2d0fa309316017ace2849395758d1f21..3b0b759585890e76e89e267be2b9d2456876a043 100644 (file)
@@ -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));
index 96954b2f7ca66567bec183732611c2c8de53e950..2da16f27e76c98f8cb46a460a1c6ae369687e18c 100644 (file)
@@ -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);