From owner-svn-src-user@FreeBSD.ORG Tue Oct 18 07:13:08 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 294ED106566B; Tue, 18 Oct 2011 07:13:08 +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 0E62A8FC0A; Tue, 18 Oct 2011 07:13:08 +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 p9I7D7xo061075; Tue, 18 Oct 2011 07:13:07 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9I7D7eo061073; Tue, 18 Oct 2011 07:13:07 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201110180713.p9I7D7eo061073@svn.freebsd.org> From: Adrian Chadd Date: Tue, 18 Oct 2011 07:13:07 +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: r226493 - 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: Tue, 18 Oct 2011 07:13:08 -0000 Author: adrian Date: Tue Oct 18 07:13:07 2011 New Revision: 226493 URL: http://svn.freebsd.org/changeset/base/226493 Log: Break out the ath_draintxq() code into two halves - the half that drains the queue, and another half which stops the TX DMA. Call the new function ath_stoptxdma(). It requires the sc lock to be held. Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Tue Oct 18 03:57:44 2011 (r226492) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath.c Tue Oct 18 07:13:07 2011 (r226493) @@ -182,6 +182,7 @@ static void ath_tx_proc_q0(void *, int); static void ath_tx_proc_q0123(void *, int); static void ath_tx_proc(void *, int); static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *); +static int ath_stoptxdma(struct ath_softc *); static void ath_draintxq(struct ath_softc *, ATH_RESET_TYPE reset_type); static void ath_stoprecv(struct ath_softc *); static int ath_startrecv(struct ath_softc *); @@ -1138,7 +1139,8 @@ ath_vap_delete(struct ieee80211vap *vap) * the vap state by any frames pending on the tx queues. */ ath_hal_intrset(ah, 0); /* disable interrupts */ - ath_draintxq(sc, ATH_RESET_DEFAULT); /* stop hw xmit side */ + ath_stoptxdma(sc); /* stop TX DMA */ + ath_draintxq(sc, ATH_RESET_DEFAULT); /* Drain TX queues */ /* XXX Do all frames from all vaps/nodes need draining here? */ ath_stoprecv(sc); /* stop recv side */ ath_rx_proc(sc, 0); @@ -1164,7 +1166,11 @@ ath_vap_delete(struct ieee80211vap *vap) * call!) */ - ath_draintxq(sc, ATH_RESET_DEFAULT); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + ATH_LOCK(sc); + ath_draintxq(sc, ATH_RESET_DEFAULT); + ATH_UNLOCK(sc); + } ATH_LOCK(sc); /* @@ -1795,7 +1801,8 @@ ath_stop_locked(struct ifnet *ifp) } ath_hal_intrset(ah, 0); } - ath_draintxq(sc, ATH_RESET_DEFAULT); + ath_stoptxdma(sc); /* stop TX dma */ + ath_draintxq(sc, ATH_RESET_DEFAULT); /* drain TX queues */ if (!sc->sc_invalid) { ath_stoprecv(sc); ath_rx_proc(sc, 0); @@ -1848,7 +1855,8 @@ ath_reset_locked(struct ifnet *ifp, ATH_ DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__); ath_hal_intrset(ah, 0); /* disable interrupts */ - ath_draintxq(sc, reset_type); /* stop xmit side */ + ath_stoptxdma(sc); /* stop TX side */ + ath_draintxq(sc, reset_type); /* drain TXQs if needed */ /* * XXX Don't flush if ATH_RESET_NOLOSS;but we have to first * XXX need to ensure this doesn't race with an outstanding @@ -4883,6 +4891,36 @@ ath_tx_stopdma(struct ath_softc *sc, str } /* + * Stop TX DMA. + * + * The sc lock must be held. + */ +static int +ath_stoptxdma(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + int i; + + ATH_LOCK_ASSERT(sc); + + /* XXX return value */ + if (!sc->sc_invalid) + return 0; + + /* don't touch the hardware if marked invalid */ + DPRINTF(sc, ATH_DEBUG_RESET, "%s: tx queue [%u] %p, link %p\n", + __func__, sc->sc_bhalq, + (caddr_t)(uintptr_t) ath_hal_gettxbuf(ah, sc->sc_bhalq), + NULL); + (void) ath_hal_stoptxdma(ah, sc->sc_bhalq); + for (i = 0; i < HAL_NUM_TX_QUEUES; i++) + if (ATH_TXQ_SETUP(sc, i)) + ath_tx_stopdma(sc, &sc->sc_txq[i]); + + return 1; +} + +/* * Drain the transmit queues and reclaim resources. */ static void @@ -4892,18 +4930,6 @@ ath_draintxq(struct ath_softc *sc, ATH_R struct ifnet *ifp = sc->sc_ifp; int i; - /* XXX return value */ - if (!sc->sc_invalid) { - /* don't touch the hardware if marked invalid */ - DPRINTF(sc, ATH_DEBUG_RESET, "%s: tx queue [%u] %p, link %p\n", - __func__, sc->sc_bhalq, - (caddr_t)(uintptr_t) ath_hal_gettxbuf(ah, sc->sc_bhalq), - NULL); - (void) ath_hal_stoptxdma(ah, sc->sc_bhalq); - for (i = 0; i < HAL_NUM_TX_QUEUES; i++) - if (ATH_TXQ_SETUP(sc, i)) - ath_tx_stopdma(sc, &sc->sc_txq[i]); - } for (i = 0; i < HAL_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_draintxq(sc, &sc->sc_txq[i]); @@ -5044,6 +5070,7 @@ ath_chan_set(struct ath_softc *sc, struc * the relevant bits of the h/w. */ ath_hal_intrset(ah, 0); /* disable interrupts */ + ath_stoptxdma(sc); /* stop TX side */ ath_draintxq(sc, ATH_RESET_FULL); /* clear pending tx frames */ ath_stoprecv(sc); /* turn off frame recv */ ath_rx_proc(sc, 0); /* handle RX'ed frames */