diff options
author | Felix Fietkau <nbd@nbd.name> | 2020-08-21 18:30:43 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2020-08-27 10:28:21 +0200 |
commit | 8ed37e79196033dbdb09a4eea9465af6a0e29fe9 (patch) | |
tree | dd641ba383352d7c1069baf544f52e76a69139c0 /net/mac80211/airtime.c | |
parent | fce2ff728f95b8894db14f51c9274dc56c37616f (diff) | |
download | lwn-8ed37e79196033dbdb09a4eea9465af6a0e29fe9.tar.gz lwn-8ed37e79196033dbdb09a4eea9465af6a0e29fe9.zip |
mac80211: use rate provided via status->rate on ieee80211_tx_status_ext for AQL
Since ieee80211_tx_info does not have enough room to encode HE rates, HE
drivers use status->rate to provide rate info.
Store it in struct sta_info and use it for AQL.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/r/20200821163045.62140-1-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/airtime.c')
-rw-r--r-- | net/mac80211/airtime.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c index 366f76c9003d..656c9a033714 100644 --- a/net/mac80211/airtime.c +++ b/net/mac80211/airtime.c @@ -487,14 +487,61 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw, } EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime); +static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw, + struct ieee80211_rx_status *stat, u8 band, + struct rate_info *ri) +{ + struct ieee80211_supported_band *sband = hw->wiphy->bands[band]; + int i; + + if (!ri || !sband) + return false; + + stat->bw = ri->bw; + stat->nss = ri->nss; + stat->rate_idx = ri->mcs; + + 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; + else if (ri->flags & RATE_INFO_FLAGS_MCS) + stat->encoding = RX_ENC_HT; + else + stat->encoding = RX_ENC_LEGACY; + + if (ri->flags & RATE_INFO_FLAGS_SHORT_GI) + stat->enc_flags |= RX_ENC_FLAG_SHORT_GI; + + stat->he_gi = ri->he_gi; + + if (stat->encoding != RX_ENC_LEGACY) + return true; + + stat->rate_idx = 0; + for (i = 0; i < sband->n_bitrates; i++) { + if (ri->legacy != sband->bitrates[i].bitrate) + continue; + + stat->rate_idx = i; + return true; + } + + return false; +} + static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw, struct ieee80211_tx_rate *rate, + struct rate_info *ri, u8 band, int len) { struct ieee80211_rx_status stat = { .band = band, }; + if (ieee80211_fill_rate_info(hw, &stat, band, ri)) + goto out; + if (rate->idx < 0 || !rate->count) return 0; @@ -522,6 +569,7 @@ static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw, stat.encoding = RX_ENC_LEGACY; } +out: return ieee80211_calc_rx_airtime(hw, &stat, len); } @@ -536,7 +584,7 @@ u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw, struct ieee80211_tx_rate *rate = &info->status.rates[i]; u32 cur_duration; - cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate, + cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate, NULL, info->band, len); if (!cur_duration) break; @@ -573,6 +621,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct ieee80211_tx_rate *rate = &sta->tx_stats.last_rate; + struct rate_info *ri = &sta->tx_stats.last_rate_info; u32 airtime; if (!(rate->flags & (IEEE80211_TX_RC_VHT_MCS | @@ -586,7 +635,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, * This will not be very accurate, but much better than simply * assuming un-aggregated tx. */ - airtime = ieee80211_calc_tx_airtime_rate(hw, rate, band, + airtime = ieee80211_calc_tx_airtime_rate(hw, rate, ri, band, ampdu ? len * 16 : len); if (ampdu) airtime /= 16; |