mac80211: factor out code to look up the average packet length duration for a rate
authorFelix Fietkau <nbd@nbd.name>
Fri, 21 Aug 2020 16:30:44 +0000 (18:30 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 27 Aug 2020 08:28:34 +0000 (10:28 +0200)
This will be used to enhance AQL estimated aggregation length

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-2-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/airtime.c

index 656c9a0..ba95f4e 100644 (file)
@@ -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);
 }