Fixes throughput issues with some drivers (e.g. ath10k) Signed-off-by: Felix Fietkau <nbd@nbd.name>
		
			
				
	
	
		
			188 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From: Felix Fietkau <nbd@nbd.name>
 | 
						|
Date: Wed, 12 Aug 2020 17:06:12 +0200
 | 
						|
Subject: [PATCH] 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: Felix Fietkau <nbd@nbd.name>
 | 
						|
---
 | 
						|
 | 
						|
--- a/net/mac80211/airtime.c
 | 
						|
+++ b/net/mac80211/airtime.c
 | 
						|
@@ -405,18 +405,14 @@ ieee80211_calc_legacy_rate_duration(u16
 | 
						|
 	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 iee
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	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 iee
 | 
						|
 
 | 
						|
 	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(str
 | 
						|
 	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);
 | 
						|
 }
 | 
						|
 
 |