diff --git a/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch new file mode 100644 index 0000000000..0a3c8ec53b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch @@ -0,0 +1,233 @@ +From: Ming Yen Hsieh +Date: Wed, 4 Sep 2024 19:12:56 +0800 +Subject: [PATCH] wifi: mac80211: introduce EHT rate support in AQL airtime + +Add definitions related to EHT mode and airtime calculation +according to the 802.11BE_D4.0. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Signed-off-by: Deren Wu +Signed-off-by: Quan Zhou +Signed-off-by: Ming Yen Hsieh +Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/airtime.c ++++ b/net/mac80211/airtime.c +@@ -55,10 +55,21 @@ + #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 +@@ -68,17 +79,26 @@ + #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 + \ +@@ -203,6 +223,69 @@ + #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_mc + 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(s + 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(s + 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(str + 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(str + 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;