wifi: iwlwifi: mvm: add EHT RU allocation to radiotap
authorMordechay Goodstein <mordechay.goodstein@intel.com>
Sun, 5 Mar 2023 12:16:33 +0000 (14:16 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 7 Mar 2023 19:15:18 +0000 (20:15 +0100)
FW new API added the info missing for update RU allocation,
so use the new API to update radiotap information.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230305124407.b16acaa4bad1.I53afa03058dbd2cd8afbaf5e82596c8ed501a476@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index 97e946e..fdd8b01 100644 (file)
@@ -414,7 +414,7 @@ enum iwl_rx_phy_eht_data2 {
        /* OFDM_RX_VECTOR_COMMON_RU_ALLOC_0_OUT */
        IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_A1 = 0x000001ff,
        IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_A2 = 0x0003fe00,
-       IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_A3 = 0x01fc0000,
+       IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_B1 = 0x07fc0000,
 
        /* info type: EHT-TB-EXT */
        IWL_RX_PHY_DATA2_EHT_TB_EXT_TRIG_SIGA1  = 0xffffffff,
@@ -424,19 +424,18 @@ enum iwl_rx_phy_eht_data2 {
 enum iwl_rx_phy_eht_data3 {
        /* info type: EHT-MU-EXT */
        /* OFDM_RX_VECTOR_COMMON_RU_ALLOC_1_OUT */
-       IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B1 = 0x000001ff,
-       IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B2 = 0x0003fe00,
-       IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B3 = 0x01fc0000,
+       IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B2 = 0x000001ff,
+       IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_C1 = 0x0003fe00,
+       IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_C2 = 0x07fc0000,
 };
 
 /* goes into Metadata DW 4 */
 enum iwl_rx_phy_eht_data4 {
        /* info type: EHT-MU-EXT */
        /* OFDM_RX_VECTOR_COMMON_RU_ALLOC_2_OUT */
-       IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_C1 = 0x000001ff,
-       IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_C2 = 0x0003fe00,
-       IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_C3 = 0x01fc0000,
-       IWL_RX_PHY_DATA4_EHT_MU_EXT_SIGB_MCS    = 0x18000000,
+       IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_D1 = 0x000001ff,
+       IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_D2 = 0x0003fe00,
+       IWL_RX_PHY_DATA4_EHT_MU_EXT_SIGB_MCS    = 0x000c0000,
 };
 
 /* goes into Metadata DW 16 */
index b545673..c07ed33 100644 (file)
@@ -1468,17 +1468,54 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
        (_usig)->value |= LE32_DEC_ENC(in_value, dec_bits, _enc_bits); \
 } while (0)
 
+#define __IWL_MVM_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \
+       eht->data[(rt_data)] |= \
+               (cpu_to_le32 \
+                (IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru ## _KNOWN) | \
+                LE32_DEC_ENC(data ## fw_data, \
+                             IWL_RX_PHY_DATA ## fw_data ## _EHT_MU_EXT_RU_ALLOC_ ## fw_ru, \
+                             IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru))
+
+#define _IWL_MVM_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru)    \
+       __IWL_MVM_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru)
+
+#define IEEE80211_RADIOTAP_RU_DATA_1_1_1       1
+#define IEEE80211_RADIOTAP_RU_DATA_2_1_1       2
+#define IEEE80211_RADIOTAP_RU_DATA_1_1_2       2
+#define IEEE80211_RADIOTAP_RU_DATA_2_1_2       2
+#define IEEE80211_RADIOTAP_RU_DATA_1_2_1       3
+#define IEEE80211_RADIOTAP_RU_DATA_2_2_1       3
+#define IEEE80211_RADIOTAP_RU_DATA_1_2_2       3
+#define IEEE80211_RADIOTAP_RU_DATA_2_2_2       4
+
+#define IWL_RX_RU_DATA_A1                      2
+#define IWL_RX_RU_DATA_A2                      2
+#define IWL_RX_RU_DATA_B1                      2
+#define IWL_RX_RU_DATA_B2                      3
+#define IWL_RX_RU_DATA_C1                      3
+#define IWL_RX_RU_DATA_C2                      3
+#define IWL_RX_RU_DATA_D1                      4
+#define IWL_RX_RU_DATA_D2                      4
+
+#define IWL_MVM_ENC_EHT_RU(rt_ru, fw_ru)                               \
+       _IWL_MVM_ENC_EHT_RU(IEEE80211_RADIOTAP_RU_DATA_ ## rt_ru,       \
+                           rt_ru,                                      \
+                           IWL_RX_RU_DATA_ ## fw_ru,                   \
+                           fw_ru)
+
 static void iwl_mvm_decode_eht_ext_mu(struct iwl_mvm *mvm,
                                      struct iwl_mvm_rx_phy_data *phy_data,
                                      struct ieee80211_rx_status *rx_status,
                                      struct ieee80211_radiotap_eht *eht,
                                      struct ieee80211_radiotap_eht_usig *usig)
 {
-       __le32 data1 = phy_data->d1;
-
        if (phy_data->with_data) {
+               __le32 data1 = phy_data->d1;
+               __le32 data2 = phy_data->d2;
+               __le32 data3 = phy_data->d3;
                __le32 data4 = phy_data->eht_d4;
                __le32 data5 = phy_data->d5;
+               u32 phy_bw = phy_data->rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK;
 
                IWL_MVM_ENC_USIG_VALUE_MASK(usig, data5,
                                            IWL_RX_PHY_DATA5_EHT_TYPE_AND_COMP,
@@ -1493,6 +1530,55 @@ static void iwl_mvm_decode_eht_ext_mu(struct iwl_mvm *mvm,
                        (usig, data1, IWL_RX_PHY_DATA1_EHT_MU_NUM_SIG_SYM_USIGA2,
                         IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS);
 
+               eht->user_info[0] |=
+                       cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN) |
+                       LE32_DEC_ENC(data5, IWL_RX_PHY_DATA5_EHT_MU_STA_ID_USR,
+                                    IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID);
+
+               eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M);
+               eht->data[7] |= LE32_DEC_ENC
+                       (data5, IWL_RX_PHY_DATA5_EHT_MU_NUM_USR_NON_OFDMA,
+                        IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS);
+
+               /*
+                * Hardware labels the content channels/RU allocation values
+                * as follows:
+                *           Content Channel 1          Content Channel 2
+                *   20 MHz: A1
+                *   40 MHz: A1                         B1
+                *   80 MHz: A1 C1                      B1 D1
+                *  160 MHz: A1 C1 A2 C2                B1 D1 B2 D2
+                *  320 MHz: A1 C1 A2 C2 A3 C3 A4 C4    B1 D1 B2 D2 B3 D3 B4 D4
+                *
+                * However firmware can only give us A1-D2, so the higher
+                * frequencies are missing.
+                */
+
+               switch (phy_bw) {
+               case RATE_MCS_CHAN_WIDTH_320:
+                       /* additional values are missing in RX metadata */
+               case RATE_MCS_CHAN_WIDTH_160:
+                       /* content channel 1 */
+                       IWL_MVM_ENC_EHT_RU(1_2_1, A2);
+                       IWL_MVM_ENC_EHT_RU(1_2_2, C2);
+                       /* content channel 2 */
+                       IWL_MVM_ENC_EHT_RU(2_2_1, B2);
+                       IWL_MVM_ENC_EHT_RU(2_2_2, D2);
+                       fallthrough;
+               case RATE_MCS_CHAN_WIDTH_80:
+                       /* content channel 1 */
+                       IWL_MVM_ENC_EHT_RU(1_1_2, C1);
+                       /* content channel 2 */
+                       IWL_MVM_ENC_EHT_RU(2_1_2, D1);
+                       fallthrough;
+               case RATE_MCS_CHAN_WIDTH_40:
+                       /* content channel 2 */
+                       IWL_MVM_ENC_EHT_RU(2_1_1, B1);
+                       fallthrough;
+               case RATE_MCS_CHAN_WIDTH_20:
+                       IWL_MVM_ENC_EHT_RU(1_1_1, A1);
+                       break;
+               }
        } else {
                __le32 usig_a1 = phy_data->rx_vec[0];
                __le32 usig_a2 = phy_data->rx_vec[1];