aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-11-24 02:53:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-28 15:04:49 -0500
commite7824a50662f7f79b1a739f705b4d906c31cf221 (patch)
tree20f92622698f9f07524db55691e0322b298031db /drivers/net/wireless/ath/ath9k/xmit.c
parent6b65b6ad016f048547127946d1afe4ba41c74296 (diff)
ath9k: fix processing of TX PS null data frames
When mac80211 was telling us to go into Powersave we listened and immediately turned RX off. This meant hardware would not see the ACKs from the AP we're associated with and hardware we'd end up retransmiting the null data frame in a loop helplessly. Fix this by keeping track of the transmitted nullfunc frames and only when we are sure the AP has sent back an ACK do we go ahead and shut RX off. Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: Vivek Natarajan <Vivek.Natarajan@atheros.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2bb8c91bf4f9..6f91a8ae616f 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1644,6 +1644,14 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1644 } 1644 }
1645 1645
1646 bf->bf_buf_addr = bf->bf_dmacontext; 1646 bf->bf_buf_addr = bf->bf_dmacontext;
1647
1648 /* tag if this is a nullfunc frame to enable PS when AP acks it */
1649 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
1650 bf->bf_isnullfunc = true;
1651 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED;
1652 } else
1653 bf->bf_isnullfunc = false;
1654
1647 return 0; 1655 return 0;
1648} 1656}
1649 1657
@@ -2039,6 +2047,19 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2039 } 2047 }
2040 2048
2041 /* 2049 /*
2050 * We now know the nullfunc frame has been ACKed so we
2051 * can disable RX.
2052 */
2053 if (bf->bf_isnullfunc &&
2054 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
2055 if ((sc->sc_flags & SC_OP_PS_ENABLED)) {
2056 sc->ps_enabled = true;
2057 ath9k_hw_setrxabort(sc->sc_ah, 1);
2058 } else
2059 sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED;
2060 }
2061
2062 /*
2042 * Remove ath_buf's of the same transmit unit from txq, 2063 * Remove ath_buf's of the same transmit unit from txq,
2043 * however leave the last descriptor back as the holding 2064 * however leave the last descriptor back as the holding
2044 * descriptor for hw. 2065 * descriptor for hw.