aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2012-10-29 08:25:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-10-30 15:58:54 -0400
commit6fe7cc71bbf3a0bc28c9cec3c00bc11e81344412 (patch)
tree8d5830aaa80aeefcfc079f21ca0d7368c1b5ab7a /drivers/net
parentbf7e1abe434ba9e22e8dc04a4cba4ab504b788b8 (diff)
ath9k: Test for TID only in BlockAcks while checking tx status
The ath9k xmit functions for AMPDUs can send frames as non-aggregate in case only one frame is currently available. The client will then answer using a normal Ack instead of a BlockAck. This acknowledgement has no TID stored and therefore the hardware is not able to provide us the corresponding TID. The TID set by the hardware in the tx status descriptor has to be seen as undefined and not as a valid TID value for normal acknowledgements. Doing otherwise results in a massive amount of retransmissions and stalls of connections. Users may experience low bandwidth and complete connection stalls in environments with transfers using multiple TIDs. This regression was introduced in b11b160defc48e4daa283f785192ea3a23a51f8e ("ath9k: validate the TID in the tx status information"). Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de> Cc: stable@vger.kernel.org Acked-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 1ffca7511fa8..741918a2027b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -394,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
394 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; 394 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
395 u32 ba[WME_BA_BMP_SIZE >> 5]; 395 u32 ba[WME_BA_BMP_SIZE >> 5];
396 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; 396 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
397 bool rc_update = true; 397 bool rc_update = true, isba;
398 struct ieee80211_tx_rate rates[4]; 398 struct ieee80211_tx_rate rates[4];
399 struct ath_frame_info *fi; 399 struct ath_frame_info *fi;
400 int nframes; 400 int nframes;
@@ -438,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
438 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; 438 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
439 tid = ATH_AN_2_TID(an, tidno); 439 tid = ATH_AN_2_TID(an, tidno);
440 seq_first = tid->seq_start; 440 seq_first = tid->seq_start;
441 isba = ts->ts_flags & ATH9K_TX_BA;
441 442
442 /* 443 /*
443 * The hardware occasionally sends a tx status for the wrong TID. 444 * The hardware occasionally sends a tx status for the wrong TID.
444 * In this case, the BA status cannot be considered valid and all 445 * In this case, the BA status cannot be considered valid and all
445 * subframes need to be retransmitted 446 * subframes need to be retransmitted
447 *
448 * Only BlockAcks have a TID and therefore normal Acks cannot be
449 * checked
446 */ 450 */
447 if (tidno != ts->tid) 451 if (isba && tidno != ts->tid)
448 txok = false; 452 txok = false;
449 453
450 isaggr = bf_isaggr(bf); 454 isaggr = bf_isaggr(bf);