Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Nov 2011 22:07:13 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r227914 - in head/sys: dev/re pci
Message-ID:  <201111232207.pANM7DAN065319@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Wed Nov 23 22:07:13 2011
New Revision: 227914
URL: http://svn.freebsd.org/changeset/base/227914

Log:
  Make sure to stop TX MAC before freeing queued TX frames.
  For RTL8111DP, check if the TX MAC is active by reading RL_GTXSTART
  register.  For RTL8402/8168E-VL/8168F/8411, wait until TX queue is
  empty.

Modified:
  head/sys/dev/re/if_re.c
  head/sys/pci/if_rlreg.h

Modified: head/sys/dev/re/if_re.c
==============================================================================
--- head/sys/dev/re/if_re.c	Wed Nov 23 22:05:44 2011	(r227913)
+++ head/sys/dev/re/if_re.c	Wed Nov 23 22:07:13 2011	(r227914)
@@ -1401,13 +1401,18 @@ re_attach(device_t dev)
 		    RL_FLAG_AUTOPAD | RL_FLAG_MACSLEEP;
 		break;
 	case RL_HWREV_8401E:
-	case RL_HWREV_8402:
 	case RL_HWREV_8105E:
 	case RL_HWREV_8105E_SPIN1:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
 		    RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
 		    RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD;
 		break;
+	case RL_HWREV_8402:
+		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
+		    RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
+		    RL_FLAG_FASTETHER | RL_FLAG_CMDSTOP | RL_FLAG_AUTOPAD |
+		    RL_FLAG_CMDSTOP_WAIT_TXQ;
+		break;
 	case RL_HWREV_8168B_SPIN1:
 	case RL_HWREV_8168B_SPIN2:
 		sc->rl_flags |= RL_FLAG_WOLRXENB;
@@ -1424,11 +1429,15 @@ re_attach(device_t dev)
 		/* FALLTHROUGH */
 	case RL_HWREV_8168CP:
 	case RL_HWREV_8168D:
-	case RL_HWREV_8168DP:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
 		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
 		    RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2;
 		break;
+	case RL_HWREV_8168DP:
+		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
+		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_AUTOPAD |
+		    RL_FLAG_JUMBOV2 | RL_FLAG_WAIT_TXPOLL;
+		break;
 	case RL_HWREV_8168E:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PHYWAKE_PM |
 		    RL_FLAG_PAR | RL_FLAG_DESCV2 | RL_FLAG_MACSTAT |
@@ -1439,7 +1448,8 @@ re_attach(device_t dev)
 	case RL_HWREV_8411:
 		sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
 		    RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
-		    RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2;
+		    RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
+		    RL_FLAG_CMDSTOP_WAIT_TXQ;
 		break;
 	case RL_HWREV_8169_8110SB:
 	case RL_HWREV_8169_8110SBL:
@@ -3466,10 +3476,32 @@ re_stop(struct rl_softc *sc)
 	    ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI |
 	    RL_RXCFG_RX_BROAD));
 
-	if ((sc->rl_flags & RL_FLAG_CMDSTOP) != 0)
+	if ((sc->rl_flags & RL_FLAG_WAIT_TXPOLL) != 0) {
+		for (i = RL_TIMEOUT; i > 0; i--) {
+			if ((CSR_READ_1(sc, sc->rl_txstart) &
+			    RL_TXSTART_START) == 0)
+				break;
+			DELAY(20);
+		}
+		if (i == 0)
+			device_printf(sc->rl_dev,
+			    "stopping TX poll timed out!\n");
+		CSR_WRITE_1(sc, RL_COMMAND, 0x00);
+	} else 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);
-	else
+		if ((sc->rl_flags & RL_FLAG_CMDSTOP_WAIT_TXQ) != 0) {
+			for (i = RL_TIMEOUT; i > 0; i--) {
+				if ((CSR_READ_4(sc, RL_TXCFG) &
+				    RL_TXCFG_QUEUE_EMPTY) != 0)
+					break;
+				DELAY(100);
+			}
+			if (i == 0)
+				device_printf(sc->rl_dev,
+				   "stopping TXQ timed out!\n");
+		}
+	} else
 		CSR_WRITE_1(sc, RL_COMMAND, 0x00);
 	DELAY(1000);
 	CSR_WRITE_2(sc, RL_IMR, 0x0000);

Modified: head/sys/pci/if_rlreg.h
==============================================================================
--- head/sys/pci/if_rlreg.h	Wed Nov 23 22:05:44 2011	(r227913)
+++ head/sys/pci/if_rlreg.h	Wed Nov 23 22:07:13 2011	(r227914)
@@ -143,6 +143,7 @@
  */
 #define	RL_TXCFG_CLRABRT	0x00000001	/* retransmit aborted pkt */
 #define	RL_TXCFG_MAXDMA		0x00000700	/* max DMA burst size */
+#define	RL_TXCFG_QUEUE_EMPTY	0x00000800	/* 8168E-VL or higher */
 #define	RL_TXCFG_CRCAPPEND	0x00010000	/* CRC append (0 = yes) */
 #define	RL_TXCFG_LOOPBKTST	0x00060000	/* loopback test */
 #define	RL_TXCFG_IFG2		0x00080000	/* 8169 only */
@@ -897,22 +898,24 @@ struct rl_softc {
 	int			rl_int_rx_act;
 	int			rl_int_rx_mod;
 	uint32_t		rl_flags;
-#define	RL_FLAG_MSI		0x0001
-#define	RL_FLAG_AUTOPAD		0x0002
-#define	RL_FLAG_PHYWAKE_PM	0x0004
-#define	RL_FLAG_PHYWAKE		0x0008
-#define	RL_FLAG_JUMBOV2		0x0010
-#define	RL_FLAG_PAR		0x0020
-#define	RL_FLAG_DESCV2		0x0040
-#define	RL_FLAG_MACSTAT		0x0080
-#define	RL_FLAG_FASTETHER	0x0100
-#define	RL_FLAG_CMDSTOP		0x0200
-#define	RL_FLAG_MACRESET	0x0400
-#define	RL_FLAG_MSIX		0x0800
-#define	RL_FLAG_WOLRXENB	0x1000
-#define	RL_FLAG_MACSLEEP	0x2000
-#define	RL_FLAG_PCIE		0x4000
-#define	RL_FLAG_LINK		0x8000
+#define	RL_FLAG_MSI		0x00000001
+#define	RL_FLAG_AUTOPAD		0x00000002
+#define	RL_FLAG_PHYWAKE_PM	0x00000004
+#define	RL_FLAG_PHYWAKE		0x00000008
+#define	RL_FLAG_JUMBOV2		0x00000010
+#define	RL_FLAG_PAR		0x00000020
+#define	RL_FLAG_DESCV2		0x00000040
+#define	RL_FLAG_MACSTAT		0x00000080
+#define	RL_FLAG_FASTETHER	0x00000100
+#define	RL_FLAG_CMDSTOP		0x00000200
+#define	RL_FLAG_MACRESET	0x00000400
+#define	RL_FLAG_MSIX		0x00000800
+#define	RL_FLAG_WOLRXENB	0x00001000
+#define	RL_FLAG_MACSLEEP	0x00002000
+#define	RL_FLAG_WAIT_TXPOLL	0x00004000
+#define	RL_FLAG_CMDSTOP_WAIT_TXQ	0x00008000
+#define	RL_FLAG_PCIE		0x40000000
+#define	RL_FLAG_LINK		0x80000000
 };
 
 #define	RL_LOCK(_sc)		mtx_lock(&(_sc)->rl_mtx)



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