svn commit: r227854 - head/sys/dev/re

Pyun YongHyeon yongari at FreeBSD.org
Wed Nov 23 02:08:05 UTC 2011


Author: yongari
Date: Wed Nov 23 02:08:05 2011
New Revision: 227854
URL: http://svn.freebsd.org/changeset/base/227854

Log:
  Disable accepting frames in re_stop() to put RX MAC into idle state.
  Because there is no reliable way to know whether RX MAC is in
  stopped state, rejecting all frames would be the only way to
  minimize possible races.
  Otherwise it's possible to receive frames while stop command
  execution is in progress and controller can DMA the frame to freed
  RX buffer during that period.
  This was observed on recent PCIe controllers(i.e. RTL8111F).
  
  While this change may not be required on old controllers it
  wouldn't make negative effects on old controllers.  One side effect
  of this change is disabling receive so driver reprograms RL_RXCFG
  to receive WOL frames when it is put into suspend or shutdown.
  
  This should address occasional 'memory modified free' errors seen
  on recent RealTek controllers.

Modified:
  head/sys/dev/re/if_re.c

Modified: head/sys/dev/re/if_re.c
==============================================================================
--- head/sys/dev/re/if_re.c	Wed Nov 23 00:01:45 2011	(r227853)
+++ head/sys/dev/re/if_re.c	Wed Nov 23 02:08:05 2011	(r227854)
@@ -3456,6 +3456,16 @@ re_stop(struct rl_softc *sc)
 	callout_stop(&sc->rl_stat_callout);
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
+	/*
+	 * Disable accepting frames to put RX MAC into idle state.
+	 * Otherwise it's possible to get frames while stop command
+	 * execution is in progress and controller can DMA the frame
+	 * to already freed RX buffer during that period.
+	 */
+	CSR_WRITE_4(sc, RL_RXCFG, CSR_READ_4(sc, RL_RXCFG) &
+	    ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI |
+	    RL_RXCFG_RX_BROAD));
+
 	if ((sc->rl_flags & RL_FLAG_CMDSTOP) != 0)
 		CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_STOPREQ | RL_CMD_TX_ENB |
 		    RL_CMD_RX_ENB);
@@ -3604,9 +3614,11 @@ re_setwol(struct rl_softc *sc)
 			CSR_WRITE_1(sc, RL_GPIO,
 			    CSR_READ_1(sc, RL_GPIO) & ~0x01);
 	}
-	if ((ifp->if_capenable & IFCAP_WOL) != 0 &&
-	    (sc->rl_flags & RL_FLAG_WOLRXENB) != 0)
-		CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RX_ENB);
+	if ((ifp->if_capenable & IFCAP_WOL) != 0) {
+		re_set_rxmode(sc);
+		if ((sc->rl_flags & RL_FLAG_WOLRXENB) != 0)
+			CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RX_ENB);
+	}
 	/* Enable config register write. */
 	CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE);
 


More information about the svn-src-head mailing list