diff mbox series

[v2] ath9k: switch to rate table based lookup

Message ID 20211128090753.958-1-jelonek.jonas@gmail.com
State New
Headers show
Series [v2] ath9k: switch to rate table based lookup | expand

Commit Message

Jonas Jelonek Nov. 28, 2021, 9:07 a.m. UTC
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
0d528d85c519b755b6f4e1bafa3a39984370e1c1) 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 <thomas.huehn@hs-nordhausen.de>
Signed-off-by: Thomas Huehn <thomas.huehn@hs-nordhausen.de>
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>

---
v2: Improved commit message with context information and testing
---
 drivers/net/wireless/ath/ath9k/xmit.c | 45 +++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

Comments

Kalle Valo Dec. 7, 2021, 3:16 p.m. UTC | #1
Jonas Jelonek <jelonek.jonas@gmail.com> wrote:

> 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 <thomas.huehn@hs-nordhausen.de>
> Signed-off-by: Thomas Huehn <thomas.huehn@hs-nordhausen.de>
> Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
> Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>

Patch applied to ath-next branch of ath.git, thanks.

7f3a6f5dd207 ath9k: switch to rate table based lookup
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5691bd6eb82c..d0caf1de2bde 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,