From owner-svn-src-user@FreeBSD.ORG Sun Aug 7 13:17:36 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 40B88106564A; Sun, 7 Aug 2011 13:17:36 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 30B948FC08; Sun, 7 Aug 2011 13:17:36 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p77DHa8V002097; Sun, 7 Aug 2011 13:17:36 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p77DHaQ4002094; Sun, 7 Aug 2011 13:17:36 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201108071317.p77DHaQ4002094@svn.freebsd.org> From: Adrian Chadd Date: Sun, 7 Aug 2011 13:17:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r224692 - user/adrian/if_ath_tx/sys/dev/ath X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Aug 2011 13:17:36 -0000 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); }