diff options
author | adrian <adrian@FreeBSD.org> | 2012-03-26 16:05:19 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2012-03-26 16:05:19 +0000 |
commit | 06ce35f781145696c6a7625be0518bbc94dd6e2f (patch) | |
tree | 2893edb6b82e1302cdb4e09ea77b8674a2dd1b83 /sys/dev | |
parent | 5879f1f169ab3be592f6e540ef2a0a6ad454d642 (diff) | |
download | FreeBSD-src-06ce35f781145696c6a7625be0518bbc94dd6e2f.zip FreeBSD-src-06ce35f781145696c6a7625be0518bbc94dd6e2f.tar.gz |
Use the assigned sequence number when checking if a retried packet is
within the BAW.
This regression was introduced in ane earlier commit by me to fix the
BAW seqno allocation-but-not-insertion-into-BAW race. Since it was only
ever using the to-be allocated sequence number, any frame retries
with the first frame in the BAW still in the software queue would
have constantly failed, as ni_txseqs[tid] would always be outside
the BAW.
TODO:
* Extract out the mostly common code here in the agg and non-agg ADDBA
case and stuff it into a single function.
PR: kern/166357
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ath/if_ath_tx.c | 23 | ||||
-rw-r--r-- | sys/dev/ath/if_ath_tx_ht.c | 22 |
2 files changed, 40 insertions, 5 deletions
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c index 72e84cf..57f3a13 100644 --- a/sys/dev/ath/if_ath_tx.c +++ b/sys/dev/ath/if_ath_tx.c @@ -2348,7 +2348,6 @@ ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_buf *bf) struct ath_tid *tid = &an->an_tid[bf->bf_state.bfs_tid]; struct ath_txq *txq = bf->bf_state.bfs_txq; struct ieee80211_tx_ampdu *tap; - int seqno; ATH_TXQ_LOCK_ASSERT(txq); @@ -2384,13 +2383,31 @@ ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_buf *bf) * the TIDs that map to it. Ugh. */ if (bf->bf_state.bfs_dobaw) { - if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd, - ni->ni_txseqs[bf->bf_state.bfs_tid])) { + ieee80211_seq seqno; + + /* + * If the sequence number is allocated, use it. + * Otherwise, use the sequence number we WOULD + * allocate. + */ + if (bf->bf_state.bfs_seqno_assigned) + seqno = SEQNO(bf->bf_state.bfs_seqno); + else + seqno = ni->ni_txseqs[bf->bf_state.bfs_tid]; + + /* + * Check whether either the currently allocated + * sequence number _OR_ the to-be allocated + * sequence number is inside the BAW. + */ + if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd, seqno)) { ATH_TXQ_INSERT_TAIL(tid, bf, bf_list); ath_tx_tid_sched(sc, tid); return; } if (! bf->bf_state.bfs_seqno_assigned) { + int seqno; + seqno = ath_tx_tid_seqno_assign(sc, ni, bf, bf->bf_m); if (seqno < 0) { device_printf(sc->sc_dev, diff --git a/sys/dev/ath/if_ath_tx_ht.c b/sys/dev/ath/if_ath_tx_ht.c index 7d61ed4..9a0487f 100644 --- a/sys/dev/ath/if_ath_tx_ht.c +++ b/sys/dev/ath/if_ath_tx_ht.c @@ -652,7 +652,6 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, int status = ATH_AGGR_DONE; int prev_frames = 0; /* XXX for AR5416 burst, not done here */ int prev_al = 0; /* XXX also for AR5416 burst */ - int seqno; ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); @@ -747,13 +746,32 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, * see ath_tx_xmit_aggr() for more info. */ if (bf->bf_state.bfs_dobaw) { + ieee80211_seq seqno; + + /* + * If the sequence number is allocated, use it. + * Otherwise, use the sequence number we WOULD + * allocate. + */ + if (bf->bf_state.bfs_seqno_assigned) + seqno = SEQNO(bf->bf_state.bfs_seqno); + else + seqno = ni->ni_txseqs[bf->bf_state.bfs_tid]; + + /* + * Check whether either the currently allocated + * sequence number _OR_ the to-be allocated + * sequence number is inside the BAW. + */ if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd, - ni->ni_txseqs[bf->bf_state.bfs_tid])) { + seqno)) { status = ATH_AGGR_BAW_CLOSED; break; } + /* XXX check for bfs_need_seqno? */ if (! bf->bf_state.bfs_seqno_assigned) { + int seqno; seqno = ath_tx_tid_seqno_assign(sc, ni, bf, bf->bf_m); if (seqno < 0) { device_printf(sc->sc_dev, |