svn commit: r303418 - head/sys/dev/iwm

Imre Vadász ivadasz at FreeBSD.org
Wed Jul 27 20:51:32 UTC 2016


Author: ivadasz
Date: Wed Jul 27 20:51:31 2016
New Revision: 303418
URL: https://svnweb.freebsd.org/changeset/base/303418

Log:
  [iwm] When stopping TX DMA, wait for all channels at once.
  
      * Makes the TX DMA stopping more similar to Linux code, and potentially
        a bit faster. Also, output an error message when TX DMA idling fails.
  
      Taken-From: Linux iwlwifi
  
  Tested:
  
  * AC3165, STA mode
  
  Approved by:	adrian (mentor)
  Obtained from:	DragonFlyBSD git 2ee486ddff973ac552ff787c17e8d83e8ae0f24c
  Differential Revision:	https://reviews.freebsd.org/D7325

Modified:
  head/sys/dev/iwm/if_iwm.c

Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c	Wed Jul 27 20:48:15 2016	(r303417)
+++ head/sys/dev/iwm/if_iwm.c	Wed Jul 27 20:51:31 2016	(r303418)
@@ -911,12 +911,9 @@ iwm_free_fwmem(struct iwm_softc *sc)
 static int
 iwm_alloc_sched(struct iwm_softc *sc)
 {
-	int rv;
-
 	/* TX scheduler rings must be aligned on a 1KB boundary. */
-	rv = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
+	return iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
 	    nitems(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024);
-	return rv;
 }
 
 static void
@@ -1281,8 +1278,8 @@ iwm_stop_device(struct iwm_softc *sc)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-	int chnl, ntries;
-	int qid;
+	int chnl, qid;
+	uint32_t mask = 0;
 
 	/* tell the device to stop sending interrupts */
 	iwm_disable_interrupts(sc);
@@ -1304,20 +1301,20 @@ iwm_stop_device(struct iwm_softc *sc)
 
 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
 
-	/* Stop all DMA channels. */
 	if (iwm_nic_lock(sc)) {
+		/* Stop each Tx DMA channel */
 		for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
 			IWM_WRITE(sc,
 			    IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl), 0);
-			for (ntries = 0; ntries < 200; ntries++) {
-				uint32_t r;
+			mask |= IWM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(chnl);
+		}
 
-				r = IWM_READ(sc, IWM_FH_TSSR_TX_STATUS_REG);
-				if (r & IWM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(
-				    chnl))
-					break;
-				DELAY(20);
-			}
+		/* Wait for DMA channels to be idle */
+		if (iwm_poll_bit(sc, IWM_FH_TSSR_TX_STATUS_REG, mask, mask,
+		    5000) < 0) {
+			device_printf(sc->sc_dev,
+			    "Failing on timeout while stopping DMA channel: [0x%08x]\n",
+			    IWM_READ(sc, IWM_FH_TSSR_TX_STATUS_REG));
 		}
 		iwm_nic_unlock(sc);
 	}


More information about the svn-src-all mailing list