wifi: mac80211: introduce EHT rate support in AQL airtime
authorMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Wed, 4 Sep 2024 11:12:56 +0000 (19:12 +0800)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 6 Sep 2024 10:58:36 +0000 (12:58 +0200)
Add definitions related to EHT mode and airtime calculation
according to the 802.11BE_D4.0.

Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Quan Zhou <quan.zhou@mediatek.com>
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/airtime.c

index fdf8b658fede8eff75ea4f676fb03bfb6baba0ff..c61df637232a9bc42369c3ce84f67e0fdc9ca370 100644 (file)
 #define HE_DURATION_S(shift, streams, gi, bps)         \
        (HE_DURATION(streams, gi, bps) >> shift)
 
+/* gi in HE/EHT is identical. It matches enum nl80211_eht_gi as well */
+#define EHT_GI_08 HE_GI_08
+#define EHT_GI_16 HE_GI_16
+#define EHT_GI_32 HE_GI_32
+
+#define EHT_DURATION(streams, gi, bps)                 \
+       HE_DURATION(streams, gi, bps)
+#define EHT_DURATION_S(shift, streams, gi, bps)                \
+       HE_DURATION_S(shift, streams, gi, bps)
+
 #define BW_20                  0
 #define BW_40                  1
 #define BW_80                  2
 #define BW_160                 3
+#define BW_320                 4
 
 /*
  * Define group sort order: HT40 -> SGI -> #streams
 #define IEEE80211_VHT_STREAM_GROUPS    8 /* BW(=4) * SGI(=2) */
 
 #define IEEE80211_HE_MAX_STREAMS       8
+#define IEEE80211_HE_STREAM_GROUPS     12 /* BW(=4) * GI(=3) */
+
+#define IEEE80211_EHT_MAX_STREAMS      8
+#define IEEE80211_EHT_STREAM_GROUPS    15 /* BW(=5) * GI(=3) */
 
 #define IEEE80211_HT_GROUPS_NB (IEEE80211_MAX_STREAMS *        \
                                 IEEE80211_HT_STREAM_GROUPS)
 #define IEEE80211_VHT_GROUPS_NB        (IEEE80211_MAX_STREAMS *        \
                                         IEEE80211_VHT_STREAM_GROUPS)
+#define IEEE80211_HE_GROUPS_NB (IEEE80211_HE_MAX_STREAMS *     \
+                                IEEE80211_HE_STREAM_GROUPS)
+#define IEEE80211_EHT_GROUPS_NB        (IEEE80211_EHT_MAX_STREAMS *    \
+                                IEEE80211_EHT_STREAM_GROUPS)
 
 #define IEEE80211_HT_GROUP_0   0
 #define IEEE80211_VHT_GROUP_0  (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
 #define IEEE80211_HE_GROUP_0   (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
+#define IEEE80211_EHT_GROUP_0  (IEEE80211_HE_GROUP_0 + IEEE80211_HE_GROUPS_NB)
 
-#define MCS_GROUP_RATES                12
+#define MCS_GROUP_RATES                14
 
 #define HT_GROUP_IDX(_streams, _sgi, _ht40)    \
        IEEE80211_HT_GROUP_0 +                  \
 #define HE_GROUP(_streams, _gi, _bw)                                   \
        __HE_GROUP(_streams, _gi, _bw,                          \
                   HE_GROUP_SHIFT(_streams, _gi, _bw))
+
+#define EHT_BW2VBPS(_bw, r5, r4, r3, r2, r1)                                   \
+       ((_bw) == BW_320 ? r5 : BW2VBPS(_bw, r4, r3, r2, r1))
+
+#define EHT_GROUP_IDX(_streams, _gi, _bw)                              \
+       (IEEE80211_EHT_GROUP_0 +                                        \
+        IEEE80211_EHT_MAX_STREAMS * 3 * (_bw) +                        \
+        IEEE80211_EHT_MAX_STREAMS * (_gi) +                            \
+        (_streams) - 1)
+
+#define __EHT_GROUP(_streams, _gi, _bw, _s)                                            \
+       [EHT_GROUP_IDX(_streams, _gi, _bw)] = {                                         \
+       .shift = _s,                                                                    \
+       .duration = {                                                                   \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw,  1960,   980,  490,  234,  117)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw,  3920,  1960,  980,  468,  234)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw,  5880,  2937, 1470,  702,  351)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw,  7840,  3920, 1960,  936,  468)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 11760,  5880, 2940, 1404,  702)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 15680,  7840, 3920, 1872,  936)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 17640,  8820, 4410, 2106, 1053)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 19600,  9800, 4900, 2340, 1170)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 23520, 11760, 5880, 2808, 1404)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 26133, 13066, 6533, 3120, 1560)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 29400, 14700, 7350, 3510, 1755)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 32666, 16333, 8166, 3900, 1950)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 35280, 17640, 8820, 4212, 2106)),       \
+               EHT_DURATION_S(_s, _streams, _gi,                                       \
+                              EHT_BW2VBPS(_bw, 39200, 19600, 9800, 4680, 2340))        \
+               }                                                                       \
+}
+
+#define EHT_GROUP_SHIFT(_streams, _gi, _bw)                                            \
+       GROUP_SHIFT(EHT_DURATION(_streams, _gi,                                         \
+                                EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117)))
+
+#define EHT_GROUP(_streams, _gi, _bw)                                  \
+       __EHT_GROUP(_streams, _gi, _bw,                         \
+                  EHT_GROUP_SHIFT(_streams, _gi, _bw))
+
+#define EHT_GROUP_RANGE(_gi, _bw)      \
+       EHT_GROUP(1, _gi, _bw),         \
+       EHT_GROUP(2, _gi, _bw),         \
+       EHT_GROUP(3, _gi, _bw),         \
+       EHT_GROUP(4, _gi, _bw),         \
+       EHT_GROUP(5, _gi, _bw),         \
+       EHT_GROUP(6, _gi, _bw),         \
+       EHT_GROUP(7, _gi, _bw),         \
+       EHT_GROUP(8, _gi, _bw)
+
 struct mcs_group {
        u8 shift;
        u16 duration[MCS_GROUP_RATES];
@@ -376,6 +459,26 @@ static const struct mcs_group airtime_mcs_groups[] = {
        HE_GROUP(6, HE_GI_32, BW_160),
        HE_GROUP(7, HE_GI_32, BW_160),
        HE_GROUP(8, HE_GI_32, BW_160),
+
+       EHT_GROUP_RANGE(EHT_GI_08, BW_20),
+       EHT_GROUP_RANGE(EHT_GI_16, BW_20),
+       EHT_GROUP_RANGE(EHT_GI_32, BW_20),
+
+       EHT_GROUP_RANGE(EHT_GI_08, BW_40),
+       EHT_GROUP_RANGE(EHT_GI_16, BW_40),
+       EHT_GROUP_RANGE(EHT_GI_32, BW_40),
+
+       EHT_GROUP_RANGE(EHT_GI_08, BW_80),
+       EHT_GROUP_RANGE(EHT_GI_16, BW_80),
+       EHT_GROUP_RANGE(EHT_GI_32, BW_80),
+
+       EHT_GROUP_RANGE(EHT_GI_08, BW_160),
+       EHT_GROUP_RANGE(EHT_GI_16, BW_160),
+       EHT_GROUP_RANGE(EHT_GI_32, BW_160),
+
+       EHT_GROUP_RANGE(EHT_GI_08, BW_320),
+       EHT_GROUP_RANGE(EHT_GI_16, BW_320),
+       EHT_GROUP_RANGE(EHT_GI_32, BW_320),
 };
 
 static u32
@@ -422,6 +525,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
        case RATE_INFO_BW_160:
                bw = BW_160;
                break;
+       case RATE_INFO_BW_320:
+               bw = BW_320;
+               break;
        default:
                WARN_ON_ONCE(1);
                return 0;
@@ -443,14 +549,27 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
                idx = status->rate_idx;
                group = HE_GROUP_IDX(streams, status->he_gi, bw);
                break;
+       case RX_ENC_EHT:
+               streams = status->nss;
+               idx = status->rate_idx;
+               group = EHT_GROUP_IDX(streams, status->eht.gi, bw);
+               break;
        default:
                WARN_ON_ONCE(1);
                return 0;
        }
 
-       if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
-                        (status->encoding == RX_ENC_HE && streams > 8)))
-               return 0;
+       switch (status->encoding) {
+       case RX_ENC_EHT:
+       case RX_ENC_HE:
+               if (WARN_ON_ONCE(streams > 8))
+                       return 0;
+               break;
+       default:
+               if (WARN_ON_ONCE(streams > 4))
+                       return 0;
+               break;
+       }
 
        if (idx >= MCS_GROUP_RATES)
                return 0;
@@ -517,7 +636,9 @@ static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
        stat->nss = ri->nss;
        stat->rate_idx = ri->mcs;
 
-       if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
+       if (ri->flags & RATE_INFO_FLAGS_EHT_MCS)
+               stat->encoding = RX_ENC_EHT;
+       else if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
                stat->encoding = RX_ENC_HE;
        else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
                stat->encoding = RX_ENC_VHT;
@@ -529,7 +650,14 @@ static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
        if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
                stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 
-       stat->he_gi = ri->he_gi;
+       switch (stat->encoding) {
+       case RX_ENC_EHT:
+               stat->eht.gi = ri->eht_gi;
+               break;
+       default:
+               stat->he_gi = ri->he_gi;
+               break;
+       }
 
        if (stat->encoding != RX_ENC_LEGACY)
                return true;