svn commit: r224692 - user/adrian/if_ath_tx/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Sun Aug 7 13:17:36 UTC 2011
Author: adrian
Date: Sun Aug 7 13:17:35 2011
New Revision: 224692
URL: http://svn.freebsd.org/changeset/base/224692
Log:
Fix a subtle race condition in addba setup - make sure the net80211
addba state is updated before the TID is unpaused, or some frames
may get queued as normal when they should get queued as aggregate.
This completely breaks the BAW tracking.
Add some further debugging to expose race conditions.
Flesh out some other, currently unused stuff.
This finally(!) makes BAW tracking work and has eliminated
the last obvious race conditions. It works until the first
interface reset (where buffers are flushed w/out updating
the BAW), or addba session teardown.
Modified:
user/adrian/if_ath_tx/sys/dev/ath/if_ath_debug.h
user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_debug.h
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_debug.h Sun Aug 7 08:42:36 2011 (r224691)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_debug.h Sun Aug 7 13:17:35 2011 (r224692)
@@ -57,8 +57,9 @@ enum {
ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */
ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */
ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */
- ATH_DEBUG_SW_TX = 0x04000000,
- ATH_DEBUG_SW_TX_BAW = 0x08000000,
+ ATH_DEBUG_SW_TX = 0x04000000, /* per-packet software TX */
+ ATH_DEBUG_SW_TX_BAW = 0x08000000, /* BAW handling */
+ ATH_DEBUG_SW_TX_CTRL = 0x10000000, /* queue control */
ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */
ATH_DEBUG_ANY = 0xffffffff
};
Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Sun Aug 7 08:42:36 2011 (r224691)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Sun Aug 7 13:17:35 2011 (r224692)
@@ -1748,6 +1748,8 @@ ath_tx_tid_pause(struct ath_softc *sc, s
ATH_TXQ_LOCK_ASSERT(txq);
tid->paused++;
+ DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: paused = %d\n",
+ __func__, tid->paused);
}
static void
@@ -1758,6 +1760,8 @@ ath_tx_tid_resume(struct ath_softc *sc,
ATH_TXQ_LOCK_ASSERT(txq);
tid->paused--;
+ DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: unpaused = %d\n",
+ __func__, tid->paused);
if (tid->paused)
return;
if (tid->axq_depth == 0)
@@ -1884,6 +1888,28 @@ ath_tx_tid_cleanup(struct ath_softc *sc,
}
}
+#ifdef notyet
+/*
+ * Handle completion of non-aggregate frames.
+ */
+static void
+ath_tx_normal_comp(struct ath_softc *sc, struct ath_buf *bf)
+{
+ struct ieee80211_node *ni = bf->bf_node;
+ struct ath_node *an;
+ struct ath_tid *atid;
+ int tid;
+
+ if (ni != NULL) {
+ tid = bf->bf_state.bfs_tid;
+ an = ATH_NODE(ni);
+ atid = &an->an_tid[tid];
+
+ ath_tx_default_comp(sc, bf);
+ }
+}
+#endif
+
/*
* Handle completion of aggregate frames.
*/
@@ -1996,6 +2022,14 @@ ath_tx_tid_hw_queue_norm(struct ath_soft
struct ath_txq *txq;
struct ath_tid *atid = &an->an_tid[tid];
+ /* Check - is AMPDU pending or running? then print out something */
+ if (ath_tx_ampdu_pending(sc, an, tid))
+ device_printf(sc->sc_dev, "%s: tid=%d, ampdu pending?\n",
+ __func__, tid);
+ if (ath_tx_ampdu_running(sc, an, tid))
+ device_printf(sc->sc_dev, "%s: tid=%d, ampdu running?\n",
+ __func__, tid);
+
for (;;) {
bf = STAILQ_FIRST(&atid->axq_q);
if (bf == NULL) {
@@ -2133,6 +2167,7 @@ ath_addba_request(struct ieee80211_node
struct ath_tid *atid = &an->an_tid[tid];
ATH_TXQ_LOCK(sc->sc_ac2q[tap->txa_ac]);
+ DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: called\n", __func__);
ath_tx_tid_pause(sc, atid);
ATH_TXQ_UNLOCK(sc->sc_ac2q[tap->txa_ac]);
@@ -2150,17 +2185,27 @@ ath_addba_request(struct ieee80211_node
*/
int
ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
- int dialogtoken, int code, int batimeout)
+ int status, int code, int batimeout)
{
struct ath_softc *sc = ni->ni_ic->ic_ifp->if_softc;
int tid = WME_AC_TO_TID(tap->txa_ac);
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = &an->an_tid[tid];
+ int r;
+
+ /*
+ * Call this first, so the interface flags get updated
+ * before the TID is unpaused. Otherwise a race condition
+ * exists where the unpaused TID still doesn't yet have
+ * IEEE80211_AGGR_RUNNING set.
+ */
+ r = sc->sc_addba_response(ni, tap, status, code, batimeout);
ATH_TXQ_LOCK(sc->sc_ac2q[tap->txa_ac]);
+ DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: called\n", __func__);
ath_tx_tid_resume(sc, atid);
ATH_TXQ_UNLOCK(sc->sc_ac2q[tap->txa_ac]);
- return sc->sc_addba_response(ni, tap, dialogtoken, code, batimeout);
+ return r;
}
@@ -2180,6 +2225,6 @@ ath_addba_stop(struct ieee80211_node *ni
struct ath_node *an = ATH_NODE(ni);
struct ath_tid *atid = an->an_tid[tid];
#endif
-
+ DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: called\n", __func__);
sc->sc_addba_stop(ni, tap);
}
More information about the svn-src-user
mailing list