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

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.name


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent fce2ff72
Loading
Loading
Loading
Loading
+51 −2
Original line number Diff line number Diff line
@@ -487,14 +487,61 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
}
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_rate(struct ieee80211_hw *hw,
		stat.encoding = RX_ENC_LEGACY;
	}

out:
	return ieee80211_calc_rx_airtime(hw, &stat, len);
}

@@ -536,7 +584,7 @@ u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
		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(struct ieee80211_hw *hw,
		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(struct ieee80211_hw *hw,
		 * 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;
+1 −0
Original line number Diff line number Diff line
@@ -611,6 +611,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];
+8 −4
Original line number Diff line number Diff line
@@ -1137,9 +1137,17 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
	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);

@@ -1154,10 +1162,6 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
	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;