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

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.name


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 8ed37e79
Loading
Loading
Loading
Loading
+74 −47
Original line number Diff line number Diff line
@@ -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,
static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
				       struct ieee80211_rx_status *status,
			      int len)
				       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,
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 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;
	}

	return 0;
}

out:
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);
}