summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-03-26 16:05:19 +0000
committeradrian <adrian@FreeBSD.org>2012-03-26 16:05:19 +0000
commit06ce35f781145696c6a7625be0518bbc94dd6e2f (patch)
tree2893edb6b82e1302cdb4e09ea77b8674a2dd1b83 /sys/dev
parent5879f1f169ab3be592f6e540ef2a0a6ad454d642 (diff)
downloadFreeBSD-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.c23
-rw-r--r--sys/dev/ath/if_ath_tx_ht.c22
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,
OpenPOWER on IntegriCloud