ee1db716e0fa904b1b14873cf74d1696b0957b02
[openwrt/staging/linusw.git] /
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Wed, 12 Aug 2020 17:04:22 +0200
3 Subject: [PATCH] mac80211: use rate provided via status->rate on
4 ieee80211_tx_status_ext for AQL
5
6 Since ieee80211_tx_info does not have enough room to encode HE rates, HE
7 drivers use status->rate to provide rate info.
8 Store it in struct sta_info and use it for AQL.
9
10 Signed-off-by: Felix Fietkau <nbd@nbd.name>
11 ---
12
13 --- a/net/mac80211/airtime.c
14 +++ b/net/mac80211/airtime.c
15 @@ -487,14 +487,61 @@ u32 ieee80211_calc_rx_airtime(struct iee
16 }
17 EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime);
18
19 +static bool ieee80211_fill_rate_info(struct ieee80211_hw *hw,
20 + struct ieee80211_rx_status *stat, u8 band,
21 + struct rate_info *ri)
22 +{
23 + struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
24 + int i;
25 +
26 + if (!ri || !sband)
27 + return false;
28 +
29 + stat->bw = ri->bw;
30 + stat->nss = ri->nss;
31 + stat->rate_idx = ri->mcs;
32 +
33 + if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
34 + stat->encoding = RX_ENC_HE;
35 + else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
36 + stat->encoding = RX_ENC_VHT;
37 + else if (ri->flags & RATE_INFO_FLAGS_MCS)
38 + stat->encoding = RX_ENC_HT;
39 + else
40 + stat->encoding = RX_ENC_LEGACY;
41 +
42 + if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
43 + stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
44 +
45 + stat->he_gi = ri->he_gi;
46 +
47 + if (stat->encoding != RX_ENC_LEGACY)
48 + return true;
49 +
50 + stat->rate_idx = 0;
51 + for (i = 0; i < sband->n_bitrates; i++) {
52 + if (ri->legacy != sband->bitrates[i].bitrate)
53 + continue;
54 +
55 + stat->rate_idx = i;
56 + return true;
57 + }
58 +
59 + return false;
60 +}
61 +
62 static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw,
63 struct ieee80211_tx_rate *rate,
64 + struct rate_info *ri,
65 u8 band, int len)
66 {
67 struct ieee80211_rx_status stat = {
68 .band = band,
69 };
70
71 + if (ieee80211_fill_rate_info(hw, &stat, band, ri))
72 + goto out;
73 +
74 if (rate->idx < 0 || !rate->count)
75 return 0;
76
77 @@ -522,6 +569,7 @@ static u32 ieee80211_calc_tx_airtime_rat
78 stat.encoding = RX_ENC_LEGACY;
79 }
80
81 +out:
82 return ieee80211_calc_rx_airtime(hw, &stat, len);
83 }
84
85 @@ -536,7 +584,7 @@ u32 ieee80211_calc_tx_airtime(struct iee
86 struct ieee80211_tx_rate *rate = &info->status.rates[i];
87 u32 cur_duration;
88
89 - cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate,
90 + cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate, NULL,
91 info->band, len);
92 if (!cur_duration)
93 break;
94 @@ -573,6 +621,7 @@ u32 ieee80211_calc_expected_tx_airtime(s
95 struct sta_info *sta = container_of(pubsta, struct sta_info,
96 sta);
97 struct ieee80211_tx_rate *rate = &sta->tx_stats.last_rate;
98 + struct rate_info *ri = &sta->tx_stats.last_rate_info;
99 u32 airtime;
100
101 if (!(rate->flags & (IEEE80211_TX_RC_VHT_MCS |
102 @@ -586,7 +635,7 @@ u32 ieee80211_calc_expected_tx_airtime(s
103 * This will not be very accurate, but much better than simply
104 * assuming un-aggregated tx.
105 */
106 - airtime = ieee80211_calc_tx_airtime_rate(hw, rate, band,
107 + airtime = ieee80211_calc_tx_airtime_rate(hw, rate, ri, band,
108 ampdu ? len * 16 : len);
109 if (ampdu)
110 airtime /= 16;
111 --- a/net/mac80211/sta_info.h
112 +++ b/net/mac80211/sta_info.h
113 @@ -609,6 +609,7 @@ struct sta_info {
114 u64 packets[IEEE80211_NUM_ACS];
115 u64 bytes[IEEE80211_NUM_ACS];
116 struct ieee80211_tx_rate last_rate;
117 + struct rate_info last_rate_info;
118 u64 msdu[IEEE80211_NUM_TIDS + 1];
119 } tx_stats;
120 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
121 --- a/net/mac80211/status.c
122 +++ b/net/mac80211/status.c
123 @@ -1147,9 +1147,17 @@ void ieee80211_tx_status_ext(struct ieee
124 struct ieee80211_tx_info *info = status->info;
125 struct ieee80211_sta *pubsta = status->sta;
126 struct ieee80211_supported_band *sband;
127 + struct sta_info *sta;
128 int retry_count;
129 bool acked, noack_success;
130
131 + if (pubsta) {
132 + sta = container_of(pubsta, struct sta_info, sta);
133 +
134 + if (status->rate)
135 + sta->tx_stats.last_rate_info = *status->rate;
136 + }
137 +
138 if (status->skb)
139 return __ieee80211_tx_status(hw, status);
140
141 @@ -1164,10 +1172,6 @@ void ieee80211_tx_status_ext(struct ieee
142 noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
143
144 if (pubsta) {
145 - struct sta_info *sta;
146 -
147 - sta = container_of(pubsta, struct sta_info, sta);
148 -
149 if (!acked && !noack_success)
150 sta->status_stats.retry_failed++;
151 sta->status_stats.retry_count += retry_count;