Commit a3835e9f authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

ath9k: Fix RTS threshold

Currently, RTS threshold is not handled for HT. Handle
user-specified threshold values for both aggregated
and unaggregated frames. Use the wiphy's threshold
parameter for now, it can be made per-VIF later on.
Signed-off-by: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 74e13060
...@@ -999,7 +999,7 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop) ...@@ -999,7 +999,7 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
} }
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
struct ath_tx_info *info, int len) struct ath_tx_info *info, int len, bool rts)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1008,6 +1008,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1008,6 +1008,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
const struct ieee80211_rate *rate; const struct ieee80211_rate *rate;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
u32 rts_thresh = sc->hw->wiphy->rts_threshold;
int i; int i;
u8 rix = 0; u8 rix = 0;
...@@ -1030,7 +1031,17 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1030,7 +1031,17 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
rix = rates[i].idx; rix = rates[i].idx;
info->rates[i].Tries = rates[i].count; info->rates[i].Tries = rates[i].count;
if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { /*
* Handle RTS threshold for unaggregated HT frames.
*/
if (bf_isampdu(bf) && !bf_isaggr(bf) &&
(rates[i].flags & IEEE80211_TX_RC_MCS) &&
unlikely(rts_thresh != (u32) -1)) {
if (!rts_thresh || (len > rts_thresh))
rts = true;
}
if (rts || rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
info->flags |= ATH9K_TXDESC_RTSENA; info->flags |= ATH9K_TXDESC_RTSENA;
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
...@@ -1123,6 +1134,8 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1123,6 +1134,8 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf_first = NULL; struct ath_buf *bf_first = NULL;
struct ath_tx_info info; struct ath_tx_info info;
u32 rts_thresh = sc->hw->wiphy->rts_threshold;
bool rts = false;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.is_first = true; info.is_first = true;
...@@ -1159,7 +1172,22 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1159,7 +1172,22 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
info.flags |= (u32) bf->bf_state.bfs_paprd << info.flags |= (u32) bf->bf_state.bfs_paprd <<
ATH9K_TXDESC_PAPRD_S; ATH9K_TXDESC_PAPRD_S;
ath_buf_set_rate(sc, bf, &info, len); /*
* mac80211 doesn't handle RTS threshold for HT because
* the decision has to be taken based on AMPDU length
* and aggregation is done entirely inside ath9k.
* Set the RTS/CTS flag for the first subframe based
* on the threshold.
*/
if (aggr && (bf == bf_first) &&
unlikely(rts_thresh != (u32) -1)) {
/*
* "len" is the size of the entire AMPDU.
*/
if (!rts_thresh || (len > rts_thresh))
rts = true;
}
ath_buf_set_rate(sc, bf, &info, len, rts);
} }
info.buf_addr[0] = bf->bf_buf_addr; info.buf_addr[0] = bf->bf_buf_addr;
...@@ -2142,7 +2170,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -2142,7 +2170,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
bf->bf_lastbf = bf; bf->bf_lastbf = bf;
ath_set_rates(vif, NULL, bf); ath_set_rates(vif, NULL, bf);
ath_buf_set_rate(sc, bf, &info, fi->framelen); ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
duration += info.rates[0].PktDuration; duration += info.rates[0].PktDuration;
if (bf_tail) if (bf_tail)
bf_tail->bf_next = bf; bf_tail->bf_next = bf;
......
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