mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
ath5k: switch to rate table based lookup
Switching from legacy usage of ieee80211_get_tx_rates() lookup to direct rate table lookup in struct ieee80211_sta->rates. The current rate control API allows drivers to directly get rates from ieee80211_sta->rates. ath5k is currently one of the legacy drivers that perform translation/merge with the internal rate table via ieee80211_get_tx_rates provided by rate control API. For our upcoming changes to rate control API and the implementation of transmit power control, this patch changes the behaviour. The call to ieee80211_get_tx_rates and subsequent calls are also avoided. ath5k now directly reads rates from sta->rates into its internal rate table. Cause ath5k does not rely on the rate array in SKB->CB, this is not considered anymore except for the first entry (used for probing). Tested this on a PCEngines ALIX with CMP9-GP miniPCI wifi card (Atheros AR5213A). Generated traffic between AP and multiple STAs before and after applying the patch and simultaneously measured throughput and captured rc_stats. Comparison resulted in same rate selection and no performance loss between both runs. 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> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://lore.kernel.org/r/20211215215042.637-1-jelonek.jonas@gmail.com
This commit is contained in:
committed by
Kalle Valo
parent
f75c1d55ec
commit
a5d862da91
@@ -727,6 +727,43 @@ ath5k_get_rate_hw_value(const struct ieee80211_hw *hw,
|
||||
return hw_rate;
|
||||
}
|
||||
|
||||
static bool ath5k_merge_ratetbl(struct ieee80211_sta *sta,
|
||||
struct ath5k_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 int
|
||||
ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
|
||||
struct ath5k_txq *txq, int padsize,
|
||||
@@ -737,6 +774,7 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
|
||||
struct ieee80211_rate *rate;
|
||||
struct ieee80211_sta *sta;
|
||||
unsigned int mrr_rate[3], mrr_tries[3];
|
||||
int i, ret;
|
||||
u16 hw_rate;
|
||||
@@ -753,8 +791,16 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
|
||||
if (dma_mapping_error(ah->dev, bf->skbaddr))
|
||||
return -ENOSPC;
|
||||
|
||||
ieee80211_get_tx_rates(info->control.vif, (control) ? control->sta : NULL, skb, bf->rates,
|
||||
ARRAY_SIZE(bf->rates));
|
||||
if (control)
|
||||
sta = control->sta;
|
||||
else
|
||||
sta = NULL;
|
||||
|
||||
if (!ath5k_merge_ratetbl(sta, bf, info)) {
|
||||
ieee80211_get_tx_rates(info->control.vif,
|
||||
sta, skb, bf->rates,
|
||||
ARRAY_SIZE(bf->rates));
|
||||
}
|
||||
|
||||
rate = ath5k_get_rate(ah->hw, info, bf, 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user