Commit 43cd72c5 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

mac80211: factor out code to look up the average packet length duration for a rate

This will be used to enhance AQL estimated aggregation length
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Acked-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/r/20200821163045.62140-2-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 8ed37e79
......@@ -405,18 +405,14 @@ ieee80211_calc_legacy_rate_duration(u16 bitrate, bool short_pre,
return duration;
}
u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
struct ieee80211_rx_status *status,
int len)
static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
struct ieee80211_rx_status *status,
u32 *overhead)
{
struct ieee80211_supported_band *sband;
const struct ieee80211_rate *rate;
bool sgi = status->enc_flags & RX_ENC_FLAG_SHORT_GI;
bool sp = status->enc_flags & RX_ENC_FLAG_SHORTPRE;
int bw, streams;
int group, idx;
u32 duration;
bool cck;
switch (status->bw) {
case RATE_INFO_BW_20:
......@@ -437,20 +433,6 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
}
switch (status->encoding) {
case RX_ENC_LEGACY:
if (WARN_ON_ONCE(status->band > NL80211_BAND_5GHZ))
return 0;
sband = hw->wiphy->bands[status->band];
if (!sband || status->rate_idx >= sband->n_bitrates)
return 0;
rate = &sband->bitrates[status->rate_idx];
cck = rate->flags & IEEE80211_RATE_MANDATORY_B;
return ieee80211_calc_legacy_rate_duration(rate->bitrate, sp,
cck, len);
case RX_ENC_VHT:
streams = status->nss;
idx = status->rate_idx;
......@@ -477,13 +459,47 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
duration = airtime_mcs_groups[group].duration[idx];
duration <<= airtime_mcs_groups[group].shift;
*overhead = 36 + (streams << 2);
return duration;
}
u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
struct ieee80211_rx_status *status,
int len)
{
struct ieee80211_supported_band *sband;
u32 duration, overhead = 0;
if (status->encoding == RX_ENC_LEGACY) {
const struct ieee80211_rate *rate;
bool sp = status->enc_flags & RX_ENC_FLAG_SHORTPRE;
bool cck;
if (WARN_ON_ONCE(status->band > NL80211_BAND_5GHZ))
return 0;
sband = hw->wiphy->bands[status->band];
if (!sband || status->rate_idx >= sband->n_bitrates)
return 0;
rate = &sband->bitrates[status->rate_idx];
cck = rate->flags & IEEE80211_RATE_MANDATORY_B;
return ieee80211_calc_legacy_rate_duration(rate->bitrate, sp,
cck, len);
}
duration = ieee80211_get_rate_duration(hw, status, &overhead);
if (!duration)
return 0;
duration *= len;
duration /= AVG_PKT_SIZE;
duration /= 1024;
duration += 36 + (streams << 2);
return duration;
return duration + overhead;
}
EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime);
......@@ -530,46 +546,57 @@ static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
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)
static int ieee80211_fill_rx_status(struct ieee80211_rx_status *stat,
struct ieee80211_hw *hw,
struct ieee80211_tx_rate *rate,
struct rate_info *ri, u8 band, int len)
{
struct ieee80211_rx_status stat = {
.band = band,
};
memset(stat, 0, sizeof(*stat));
stat->band = band;
if (ieee80211_fill_rate_info(hw, &stat, band, ri))
goto out;
if (ieee80211_fill_rate_info(hw, stat, band, ri))
return 0;
if (rate->idx < 0 || !rate->count)
return 0;
return -1;
if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
stat.bw = RATE_INFO_BW_80;
stat->bw = RATE_INFO_BW_80;
else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
stat.bw = RATE_INFO_BW_40;
stat->bw = RATE_INFO_BW_40;
else
stat.bw = RATE_INFO_BW_20;
stat->bw = RATE_INFO_BW_20;
stat.enc_flags = 0;
stat->enc_flags = 0;
if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
stat.enc_flags |= RX_ENC_FLAG_SHORTPRE;
stat->enc_flags |= RX_ENC_FLAG_SHORTPRE;
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
stat.enc_flags |= RX_ENC_FLAG_SHORT_GI;
stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
stat.rate_idx = rate->idx;
stat->rate_idx = rate->idx;
if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
stat.encoding = RX_ENC_VHT;
stat.rate_idx = ieee80211_rate_get_vht_mcs(rate);
stat.nss = ieee80211_rate_get_vht_nss(rate);
stat->encoding = RX_ENC_VHT;
stat->rate_idx = ieee80211_rate_get_vht_mcs(rate);
stat->nss = ieee80211_rate_get_vht_nss(rate);
} else if (rate->flags & IEEE80211_TX_RC_MCS) {
stat.encoding = RX_ENC_HT;
stat->encoding = RX_ENC_HT;
} else {
stat.encoding = RX_ENC_LEGACY;
stat->encoding = RX_ENC_LEGACY;
}
out:
return 0;
}
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;
if (ieee80211_fill_rx_status(&stat, hw, rate, ri, band, len))
return 0;
return ieee80211_calc_rx_airtime(hw, &stat, len);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment