123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- From: Felix Fietkau <[email protected]>
- 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 <[email protected]>
- ---
- --- 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;
|