Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Feb 2012 03:46:38 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r231857 - head/sys/dev/ath
Message-ID:  <201202170346.q1H3kcv0048479@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri Feb 17 03:46:38 2012
New Revision: 231857
URL: http://svn.freebsd.org/changeset/base/231857

Log:
  Enforce some consistent ordering and handling of interrupt disable/enable
  with RX/TX halting.
  
  * Always disable/enable interrupts during a channel change, just to simply
    things.
  
  * Ensure that the ath taskqueue has completed and is paused before
    continuing.
  
  This dramatically reduces the instances of overlapping RX and reset
  conditions.
  
  PR:	kern/165220

Modified:
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Fri Feb 17 03:39:06 2012	(r231856)
+++ head/sys/dev/ath/if_ath.c	Fri Feb 17 03:46:38 2012	(r231857)
@@ -1934,6 +1934,7 @@ ath_txrx_stop_locked(struct ath_softc *s
 }
 #undef	MAX_TXRX_ITERATIONS
 
+#if 0
 static void
 ath_txrx_stop(struct ath_softc *sc)
 {
@@ -1944,6 +1945,7 @@ ath_txrx_stop(struct ath_softc *sc)
 	ath_txrx_stop_locked(sc);
 	ATH_PCU_UNLOCK(sc);
 }
+#endif
 
 static void
 ath_txrx_start(struct ath_softc *sc)
@@ -2049,11 +2051,12 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T
 	ATH_UNLOCK_ASSERT(sc);
 
 	ATH_PCU_LOCK(sc);
+	ath_hal_intrset(ah, 0);		/* disable interrupts */
+	ath_txrx_stop_locked(sc);	/* Ensure TX/RX is stopped */
 	if (ath_reset_grablock(sc, 1) == 0) {
 		device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n",
 		    __func__);
 	}
-	ath_hal_intrset(ah, 0);		/* disable interrupts */
 	ATH_PCU_UNLOCK(sc);
 
 	/*
@@ -2061,7 +2064,6 @@ ath_reset(struct ifnet *ifp, ATH_RESET_T
 	 * and block future ones from occuring. This needs to be
 	 * done before the TX queue is drained.
 	 */
-	ath_txrx_stop(sc);
 	ath_draintxq(sc, reset_type);	/* stop xmit side */
 
 	/*
@@ -5383,21 +5385,16 @@ ath_chan_set(struct ath_softc *sc, struc
 	struct ieee80211com *ic = ifp->if_l2com;
 	struct ath_hal *ah = sc->sc_ah;
 	int ret = 0;
-	int dointr = 0;
 
 	/* Treat this as an interface reset */
 	ATH_PCU_LOCK(sc);
+	ath_hal_intrset(ah, 0);		/* Stop new RX/TX completion */
+	ath_txrx_stop_locked(sc);	/* Stop pending RX/TX completion */
 	if (ath_reset_grablock(sc, 1) == 0) {
 		device_printf(sc->sc_dev, "%s: concurrent reset! Danger!\n",
 		    __func__);
 	}
-	if (chan != sc->sc_curchan) {
-		dointr = 1;
-		/* XXX only do this if inreset_cnt is 1? */
-		ath_hal_intrset(ah, 0);
-	}
 	ATH_PCU_UNLOCK(sc);
-	ath_txrx_stop(sc);
 
 	DPRINTF(sc, ATH_DEBUG_RESET, "%s: %u (%u MHz, flags 0x%x)\n",
 	    __func__, ieee80211_chan2ieee(ic, chan),
@@ -5466,10 +5463,10 @@ ath_chan_set(struct ath_softc *sc, struc
 			ath_beacon_config(sc, NULL);
 		}
 
-#if 0
 		/*
 		 * Re-enable interrupts.
 		 */
+#if 0
 		ath_hal_intrset(ah, sc->sc_imask);
 #endif
 	}
@@ -5478,8 +5475,7 @@ finish:
 	ATH_PCU_LOCK(sc);
 	sc->sc_inreset_cnt--;
 	/* XXX only do this if sc_inreset_cnt == 0? */
-	if (dointr)
-		ath_hal_intrset(ah, sc->sc_imask);
+	ath_hal_intrset(ah, sc->sc_imask);
 	ATH_PCU_UNLOCK(sc);
 
 	/* XXX do this inside of IF_LOCK? */



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