Skip to content

Commit

Permalink
ath9k: fix an aggregation start related race condition
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Felix Fietkau authored and John W. Linville committed Sep 21, 2010
1 parent 81ee13b commit 231c3a1
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 6 deletions.
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ void ath_tx_tasklet(struct ath_softc *sc);
void ath_tx_edma_tasklet(struct ath_softc *sc);
void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn);
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
void ath9k_enable_ps(struct ath_softc *sc);
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1970,8 +1970,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
break;
case IEEE80211_AMPDU_TX_START:
ath9k_ps_wakeup(sc);
ath_tx_aggr_start(sc, sta, tid, ssn);
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
ret = ath_tx_aggr_start(sc, sta, tid, ssn);
if (!ret)
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
ath9k_ps_restore(sc);
break;
case IEEE80211_AMPDU_TX_STOP:
Expand Down
10 changes: 8 additions & 2 deletions drivers/net/wireless/ath/ath9k/xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,17 +783,23 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
status != ATH_AGGR_BAW_CLOSED);
}

void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn)
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn)
{
struct ath_atx_tid *txtid;
struct ath_node *an;

an = (struct ath_node *)sta->drv_priv;
txtid = ATH_AN_2_TID(an, tid);

if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
return -EAGAIN;

txtid->state |= AGGR_ADDBA_PROGRESS;
txtid->paused = true;
*ssn = txtid->seq_start;

return 0;
}

void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
Expand Down

0 comments on commit 231c3a1

Please sign in to comment.