Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Oct 2011 07:13:07 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r226493 - user/adrian/if_ath_tx/sys/dev/ath
Message-ID:  <201110180713.p9I7D7eo061073@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110180713.p9I7D7eo061073>