From 7f3a6f5dd207ecd582e1f02ebdb498493770a490 Mon Sep 17 00:00:00 2001 From: Jonas Jelonek Date: Sun, 28 Nov 2021 10:07:53 +0100 Subject: [PATCH] ath9k: switch to rate table based lookup MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch changes mac80211 rate control for the ath9k driver. The rate lookup per packet is changed from legacy usage of ieee80211_get_tx_rates() to the new rate table based lookup in struct ieee80211_sta->rates. The most recent rate control API, introduced with commit 0d528d85c519 ("mac80211: improve the rate control API"), allows drivers to directly get rates from ieee80211_sta->rates. This is not used by every driver yet, the translation/merge is currently performed in ieee80211_get_tx_rates. This patch changes the behaviour and avoids the call to ieee80211_get_tx_rates and subsequent calls. ath9k now directly reads rates from sta->rates into its rate table. Cause ath9k does not expect rate selection in SKB->CB, the table merge does not consider rate array in SKB->CB except for the first entry (used for probing). Tested with a 8devices Rambutan with QCA9558 SoC by performing two runs, one without the patch and one with. Generated traffic between AP and multiple STAs in each run, measured throughput and captured rc_stats. Comparison of both runs resulted in same rate selection and no performance loss or other negative effects. Co-developed-by: Thomas Huehn Signed-off-by: Thomas Huehn Signed-off-by: Jonas Jelonek Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211128090753.958-1-jelonek.jonas@gmail.com --- drivers/net/wireless/ath/ath9k/xmit.c | 45 +++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5691bd6eb82c2..d0caf1de2bdec 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -154,11 +154,52 @@ static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) seqno << IEEE80211_SEQ_SEQ_SHIFT); } +static bool ath_merge_ratetbl(struct ieee80211_sta *sta, struct ath_buf *bf, + struct ieee80211_tx_info *tx_info) +{ + struct ieee80211_sta_rates *ratetbl; + u8 i; + + if (!sta) + return false; + + ratetbl = rcu_dereference(sta->rates); + if (!ratetbl) + return false; + + if (tx_info->control.rates[0].idx < 0 || + tx_info->control.rates[0].count == 0) + { + i = 0; + } else { + bf->rates[0] = tx_info->control.rates[0]; + i = 1; + } + + for ( ; i < IEEE80211_TX_MAX_RATES; i++) { + bf->rates[i].idx = ratetbl->rate[i].idx; + bf->rates[i].flags = ratetbl->rate[i].flags; + if (tx_info->control.use_rts) + bf->rates[i].count = ratetbl->rate[i].count_rts; + else if (tx_info->control.use_cts_prot) + bf->rates[i].count = ratetbl->rate[i].count_cts; + else + bf->rates[i].count = ratetbl->rate[i].count; + } + + return true; +} + static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ath_buf *bf) { - ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates, - ARRAY_SIZE(bf->rates)); + struct ieee80211_tx_info *tx_info; + + tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); + + if (!ath_merge_ratetbl(sta, bf, tx_info)) + ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates, + ARRAY_SIZE(bf->rates)); } static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, -- 2.30.2