aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/311-mac80211-use-rate-provided-via-status-rate-on-ieee80.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/311-mac80211-use-rate-provided-via-status-rate-on-ieee80.patch')
-rw-r--r--package/kernel/mac80211/patches/subsys/311-mac80211-use-rate-provided-via-status-rate-on-ieee80.patch151
1 files changed, 151 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-use-rate-provided-via-status-rate-on-ieee80.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-use-rate-provided-via-status-rate-on-ieee80.patch
new file mode 100644
index 0000000000..ee1db716e0
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/311-mac80211-use-rate-provided-via-status-rate-on-ieee80.patch
@@ -0,0 +1,151 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 12 Aug 2020 17:04:22 +0200
+Subject: [PATCH] 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>
+---
+
+--- a/net/mac80211/airtime.c
++++ b/net/mac80211/airtime.c
+@@ -487,14 +487,61 @@ u32 ieee80211_calc_rx_airtime(struct iee
+ }
+ 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_rat
+ stat.encoding = RX_ENC_LEGACY;
+ }
+
++out:
+ return ieee80211_calc_rx_airtime(hw, &stat, len);
+ }
+
+@@ -536,7 +584,7 @@ u32 ieee80211_calc_tx_airtime(struct iee
+ 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(s
+ 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(s
+ * 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;
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -609,6 +609,7 @@ struct sta_info {
+ u64 packets[IEEE80211_NUM_ACS];
+ u64 bytes[IEEE80211_NUM_ACS];
+ struct ieee80211_tx_rate last_rate;
++ struct rate_info last_rate_info;
+ u64 msdu[IEEE80211_NUM_TIDS + 1];
+ } tx_stats;
+ u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -1147,9 +1147,17 @@ void ieee80211_tx_status_ext(struct ieee
+ struct ieee80211_tx_info *info = status->info;
+ struct ieee80211_sta *pubsta = status->sta;
+ struct ieee80211_supported_band *sband;
++ struct sta_info *sta;
+ int retry_count;
+ bool acked, noack_success;
+
++ if (pubsta) {
++ sta = container_of(pubsta, struct sta_info, sta);
++
++ if (status->rate)
++ sta->tx_stats.last_rate_info = *status->rate;
++ }
++
+ if (status->skb)
+ return __ieee80211_tx_status(hw, status);
+
+@@ -1164,10 +1172,6 @@ void ieee80211_tx_status_ext(struct ieee
+ noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
+
+ if (pubsta) {
+- struct sta_info *sta;
+-
+- sta = container_of(pubsta, struct sta_info, sta);
+-
+ if (!acked && !noack_success)
+ sta->status_stats.retry_failed++;
+ sta->status_stats.retry_count += retry_count;