Commit 8ed37e79 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

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: 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-1-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent fce2ff72
...@@ -487,14 +487,61 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw, ...@@ -487,14 +487,61 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
} }
EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime); 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, static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw,
struct ieee80211_tx_rate *rate, struct ieee80211_tx_rate *rate,
struct rate_info *ri,
u8 band, int len) u8 band, int len)
{ {
struct ieee80211_rx_status stat = { struct ieee80211_rx_status stat = {
.band = band, .band = band,
}; };
if (ieee80211_fill_rate_info(hw, &stat, band, ri))
goto out;
if (rate->idx < 0 || !rate->count) if (rate->idx < 0 || !rate->count)
return 0; return 0;
...@@ -522,6 +569,7 @@ static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw, ...@@ -522,6 +569,7 @@ static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw,
stat.encoding = RX_ENC_LEGACY; stat.encoding = RX_ENC_LEGACY;
} }
out:
return ieee80211_calc_rx_airtime(hw, &stat, len); return ieee80211_calc_rx_airtime(hw, &stat, len);
} }
...@@ -536,7 +584,7 @@ u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw, ...@@ -536,7 +584,7 @@ u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
struct ieee80211_tx_rate *rate = &info->status.rates[i]; struct ieee80211_tx_rate *rate = &info->status.rates[i];
u32 cur_duration; 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); info->band, len);
if (!cur_duration) if (!cur_duration)
break; break;
...@@ -573,6 +621,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, ...@@ -573,6 +621,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
struct sta_info *sta = container_of(pubsta, struct sta_info, struct sta_info *sta = container_of(pubsta, struct sta_info,
sta); sta);
struct ieee80211_tx_rate *rate = &sta->tx_stats.last_rate; struct ieee80211_tx_rate *rate = &sta->tx_stats.last_rate;
struct rate_info *ri = &sta->tx_stats.last_rate_info;
u32 airtime; u32 airtime;
if (!(rate->flags & (IEEE80211_TX_RC_VHT_MCS | if (!(rate->flags & (IEEE80211_TX_RC_VHT_MCS |
...@@ -586,7 +635,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, ...@@ -586,7 +635,7 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
* This will not be very accurate, but much better than simply * This will not be very accurate, but much better than simply
* assuming un-aggregated tx. * 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); ampdu ? len * 16 : len);
if (ampdu) if (ampdu)
airtime /= 16; airtime /= 16;
......
...@@ -611,6 +611,7 @@ struct sta_info { ...@@ -611,6 +611,7 @@ struct sta_info {
u64 packets[IEEE80211_NUM_ACS]; u64 packets[IEEE80211_NUM_ACS];
u64 bytes[IEEE80211_NUM_ACS]; u64 bytes[IEEE80211_NUM_ACS];
struct ieee80211_tx_rate last_rate; struct ieee80211_tx_rate last_rate;
struct rate_info last_rate_info;
u64 msdu[IEEE80211_NUM_TIDS + 1]; u64 msdu[IEEE80211_NUM_TIDS + 1];
} tx_stats; } tx_stats;
u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
......
...@@ -1137,9 +1137,17 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, ...@@ -1137,9 +1137,17 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
struct ieee80211_tx_info *info = status->info; struct ieee80211_tx_info *info = status->info;
struct ieee80211_sta *pubsta = status->sta; struct ieee80211_sta *pubsta = status->sta;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct sta_info *sta;
int retry_count; int retry_count;
bool acked, noack_success; 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) if (status->skb)
return __ieee80211_tx_status(hw, status); return __ieee80211_tx_status(hw, status);
...@@ -1154,10 +1162,6 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw, ...@@ -1154,10 +1162,6 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED); noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
if (pubsta) { if (pubsta) {
struct sta_info *sta;
sta = container_of(pubsta, struct sta_info, sta);
if (!acked && !noack_success) if (!acked && !noack_success)
sta->status_stats.retry_failed++; sta->status_stats.retry_failed++;
sta->status_stats.retry_count += retry_count; sta->status_stats.retry_count += retry_count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment