Commit 27032059 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

ath9k: fix RTS/CTS handling

The Tx DMA descriptor has two kinds of flags that select RTS/CTS usage.
The first one (global for the frame) selects whether RTS/CTS or
CTS-to-self should be used, the second one enables RTS/CTS or
CTS-to-self usage for an individual multi-rate-retry entry.
Previously the code preparing the descriptor only enabled the global
flag, if the first MRR series selected the local one.
Fix this by enabling the global flag if any of the MRR entries need it.
With this patch, rate control can properly select the use of RTS/CTS
for all MRR entries except the first one, which is the default behavior.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5f2aa25e
......@@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
ctsrate |= rate->hw_value_short;
/*
* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
* Check the first rate in the series to decide whether RTS/CTS
* or CTS-to-self has to be used.
*/
if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
flags = ATH9K_TXDESC_CTSENA;
else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
flags = ATH9K_TXDESC_RTSENA;
/* FIXME: Handle aggregation protection */
if (sc->config.ath_aggr_prot &&
(!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
flags = ATH9K_TXDESC_RTSENA;
}
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
flags &= ~(ATH9K_TXDESC_RTSENA);
for (i = 0; i < 4; i++) {
bool is_40, is_sgi, is_sp;
int phy;
......@@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
series[i].Tries = rates[i].count;
series[i].ChSel = common->tx_chainmask;
if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
(rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
flags |= ATH9K_TXDESC_RTSENA;
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
flags |= ATH9K_TXDESC_CTSENA;
}
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
series[i].RateFlags |= ATH9K_RATESERIES_2040;
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
......@@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp);
}
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
flags &= ~ATH9K_TXDESC_RTSENA;
/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
if (flags & ATH9K_TXDESC_RTSENA)
flags &= ~ATH9K_TXDESC_CTSENA;
/* set dur_update_en for l-sig computation except for PS-Poll frames */
ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
bf->bf_lastbf->bf_desc,
......
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