aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-09-20 13:35:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-09-21 11:05:31 -0400
commit231c3a1f0630c07a584905507a1cb7b705a56ab7 (patch)
tree10ad974e6c1b55aa986fe2136fbbea2125e1eff3 /drivers/net/wireless/ath/ath9k/xmit.c
parent81ee13ba7ef8c9eaebe91ed06edb844ab6403d4e (diff)
ath9k: fix an aggregation start related race condition
A new aggregation session start can be issued by mac80211, even when the cleanup of the previous session has not completed yet. Since the data structure for the session is not recreated, this could corrupt the block ack window and lock up the aggregation session. Fix this by delaying the new session until the old one has been cleaned up. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Cc: stable@kernel.org 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.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5323a4d9ebb8..d629bfbdfab4 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -783,17 +783,23 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
783 status != ATH_AGGR_BAW_CLOSED); 783 status != ATH_AGGR_BAW_CLOSED);
784} 784}
785 785
786void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, 786int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
787 u16 tid, u16 *ssn) 787 u16 tid, u16 *ssn)
788{ 788{
789 struct ath_atx_tid *txtid; 789 struct ath_atx_tid *txtid;
790 struct ath_node *an; 790 struct ath_node *an;
791 791
792 an = (struct ath_node *)sta->drv_priv; 792 an = (struct ath_node *)sta->drv_priv;
793 txtid = ATH_AN_2_TID(an, tid); 793 txtid = ATH_AN_2_TID(an, tid);
794
795 if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
796 return -EAGAIN;
797
794 txtid->state |= AGGR_ADDBA_PROGRESS; 798 txtid->state |= AGGR_ADDBA_PROGRESS;
795 txtid->paused = true; 799 txtid->paused = true;
796 *ssn = txtid->seq_start; 800 *ssn = txtid->seq_start;
801
802 return 0;
797} 803}
798 804
799void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) 805void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)