diff options
Diffstat (limited to 'net/mac80211/airtime.c')
| -rw-r--r-- | net/mac80211/airtime.c | 150 |
1 files changed, 138 insertions, 12 deletions
diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c index e8ebd343e2bf..c61df637232a 100644 --- 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_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; @@ -557,7 +685,7 @@ static int ieee80211_fill_rx_status(struct ieee80211_rx_status *stat, if (ieee80211_fill_rate_info(hw, stat, band, ri)) return 0; - if (rate->idx < 0 || !rate->count) + if (!ieee80211_rate_valid(rate)) return -1; if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) @@ -632,7 +760,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, { struct ieee80211_supported_band *sband; struct ieee80211_chanctx_conf *conf; - int rateidx, shift = 0; + int rateidx; bool cck, short_pream; u32 basic_rates; u8 band = 0; @@ -641,10 +769,8 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, len += 38; /* Ethernet header length */ conf = rcu_dereference(vif->bss_conf.chanctx_conf); - if (conf) { + if (conf) band = conf->def.chan->band; - shift = ieee80211_chandef_get_shift(&conf->def); - } if (pubsta) { struct sta_info *sta = container_of(pubsta, struct sta_info, @@ -704,7 +830,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, short_pream = vif->bss_conf.use_short_preamble; rateidx = basic_rates ? ffs(basic_rates) - 1 : 0; - rate = sband->bitrates[rateidx].bitrate << shift; + rate = sband->bitrates[rateidx].bitrate; cck = sband->bitrates[rateidx].flags & IEEE80211_RATE_MANDATORY_B; return ieee80211_calc_legacy_rate_duration(rate, short_pream, cck, len); |
