Module Name:    src
Committed By:   tsutsui
Date:           Wed Apr 29 15:10:58 UTC 2009

Modified Files:
        src/sys/dev/ic: rtl8169.c rtl81x9reg.h rtl81x9var.h

Log Message:
Pull some changes for newer chips from FreeBSD:
- pull MACSTAT and CMDSTOP quirks for 8168/8111 chips
- always set CPLUSCMD_PCI_MRW on reset
- set VLANSTRIP and RXCSUM_ENB bits on CPLUS register per if_capenable

Tested on 8111C and 8111D by several users, and
no bad side effect on my old 8169S.


To generate a diff of this commit:
cvs rdiff -u -r1.116 -r1.117 src/sys/dev/ic/rtl8169.c
cvs rdiff -u -r1.37 -r1.38 src/sys/dev/ic/rtl81x9reg.h
cvs rdiff -u -r1.46 -r1.47 src/sys/dev/ic/rtl81x9var.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/rtl8169.c
diff -u src/sys/dev/ic/rtl8169.c:1.116 src/sys/dev/ic/rtl8169.c:1.117
--- src/sys/dev/ic/rtl8169.c:1.116	Mon Apr 13 12:38:06 2009
+++ src/sys/dev/ic/rtl8169.c	Wed Apr 29 15:10:57 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl8169.c,v 1.116 2009/04/13 12:38:06 tsutsui Exp $	*/
+/*	$NetBSD: rtl8169.c,v 1.117 2009/04/29 15:10:57 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998-2003
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.116 2009/04/13 12:38:06 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.117 2009/04/29 15:10:57 tsutsui Exp $");
 /* $FreeBSD: /repoman/r/ncvs/src/sys/dev/re/if_re.c,v 1.20 2004/04/11 20:34:08 ru Exp $ */
 
 /*
@@ -593,19 +593,23 @@
 			break;
 		case RTK_HWREV_8168_SPIN1:
 			sc->sc_rev = 21;
+			sc->sc_quirk |= RTKQ_MACSTAT;
 			break;
 		case RTK_HWREV_8168_SPIN2:
 			sc->sc_rev = 22;
+			sc->sc_quirk |= RTKQ_MACSTAT;
 			break;
 		case RTK_HWREV_8168_SPIN3:
 			sc->sc_rev = 23;
+			sc->sc_quirk |= RTKQ_MACSTAT;
 			break;
 		case RTK_HWREV_8168C:
 		case RTK_HWREV_8168C_SPIN2:
 		case RTK_HWREV_8168CP:
 		case RTK_HWREV_8168D:
 			sc->sc_rev = 24;
-			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD;
+			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD |
+			    RTKQ_MACSTAT | RTKQ_CMDSTOP;
 			/*
 			 * From FreeBSD driver:
 			 * 
@@ -625,8 +629,8 @@
 		case RTK_HWREV_8102EL:
 		case RTK_HWREV_8102EL_SPIN2:
 			sc->sc_rev = 25;
-			sc->sc_quirk |=
-			    RTKQ_DESCV2 | RTKQ_NOEECMD | RTKQ_NOJUMBO;
+			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD |
+			    RTKQ_MACSTAT | RTKQ_CMDSTOP | RTKQ_NOJUMBO;
 			break;
 		case RTK_HWREV_8100E:
 		case RTK_HWREV_8100E_SPIN2:
@@ -1719,6 +1723,7 @@
 	const uint8_t *enaddr;
 	uint32_t rxcfg = 0;
 	uint32_t reg;
+	uint16_t cfg;
 	int error;
 
 	if ((error = re_enable(sc)) != 0)
@@ -1736,32 +1741,27 @@
 	 * RX checksum offload. We must configure the C+ register
 	 * before all others.
 	 */
-	reg = 0;
-
-	/*
-	 * XXX: Realtek docs say bits 0 and 1 are reserved, for 8169S/8110S.
-	 * FreeBSD  drivers set these bits anyway (for 8139C+?).
-	 * So far, it works.
-	 */
+	cfg = RE_CPLUSCMD_PCI_MRW;
 
 	/*
 	 * XXX: For old 8169 set bit 14.
 	 *      For 8169S/8110S and above, do not set bit 14.
 	 */
 	if ((sc->sc_quirk & RTKQ_8169NONS) != 0)
-		reg |= (0x1 << 14) | RTK_CPLUSCMD_PCI_MRW;
+		cfg |= (0x1 << 14);
 
-	if (1)  {/* not for 8169S ? */
-		reg |=
-		    RTK_CPLUSCMD_VLANSTRIP |
-		    (ifp->if_capenable &
-		    (IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_TCPv4_Rx |
-		     IFCAP_CSUM_UDPv4_Rx) ?
-		    RTK_CPLUSCMD_RXCSUM_ENB : 0);
-	}
+	if ((ifp->if_capenable & ETHERCAP_VLAN_HWTAGGING) != 0)
+		cfg |= RE_CPLUSCMD_VLANSTRIP;
+	if ((ifp->if_capenable & (IFCAP_CSUM_IPv4_Rx |
+	     IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) != 0)
+		cfg |= RE_CPLUSCMD_RXCSUM_ENB;
+	if ((sc->sc_quirk & RTKQ_MACSTAT) != 0) {
+		cfg |= RE_CPLUSCMD_MACSTAT_DIS;
+		cfg |= RE_CPLUSCMD_TXENB;
+	} else
+		cfg |= RE_CPLUSCMD_RXENB | RE_CPLUSCMD_TXENB;
 
-	CSR_WRITE_2(sc, RTK_CPLUS_CMD,
-	    reg | RTK_CPLUSCMD_RXENB | RTK_CPLUSCMD_TXENB);
+	CSR_WRITE_2(sc, RTK_CPLUS_CMD, cfg);
 
 	/* XXX: from Realtek-supplied Linux driver. Wholly undocumented. */
 	if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0)
@@ -1981,8 +1981,14 @@
 
 	mii_down(&sc->mii);
 
-	CSR_WRITE_1(sc, RTK_COMMAND, 0x00);
+	if ((sc->sc_quirk & RTKQ_CMDSTOP) != 0)
+		CSR_WRITE_1(sc, RTK_COMMAND, RTK_CMD_STOPREQ | RTK_CMD_TX_ENB |
+		    RTK_CMD_RX_ENB);
+	else
+		CSR_WRITE_1(sc, RTK_COMMAND, 0x00);
+	DELAY(1000);
 	CSR_WRITE_2(sc, RTK_IMR, 0x0000);
+	CSR_WRITE_2(sc, RTK_ISR, 0xFFFF);
 
 	if (sc->re_head != NULL) {
 		m_freem(sc->re_head);

Index: src/sys/dev/ic/rtl81x9reg.h
diff -u src/sys/dev/ic/rtl81x9reg.h:1.37 src/sys/dev/ic/rtl81x9reg.h:1.38
--- src/sys/dev/ic/rtl81x9reg.h:1.37	Mon Apr 13 12:33:05 2009
+++ src/sys/dev/ic/rtl81x9reg.h	Wed Apr 29 15:10:57 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl81x9reg.h,v 1.37 2009/04/13 12:33:05 tsutsui Exp $	*/
+/*	$NetBSD: rtl81x9reg.h,v 1.38 2009/04/29 15:10:57 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998
@@ -309,6 +309,7 @@
 #define RTK_CMD_TX_ENB		0x0004
 #define RTK_CMD_RX_ENB		0x0008
 #define RTK_CMD_RESET		0x0010
+#define RTK_CMD_STOPREQ		0x0080
 
 /*
  * EEPROM control register
@@ -403,12 +404,21 @@
 
 /* C+ mode command register */
 
-#define RTK_CPLUSCMD_TXENB	0x0001	/* enable C+ transmit mode */
-#define RTK_CPLUSCMD_RXENB	0x0002	/* enable C+ receive mode */
-#define RTK_CPLUSCMD_PCI_MRW	0x0008	/* enable PCI multi-read/write */
-#define RTK_CPLUSCMD_PCI_DAC	0x0010	/* PCI dual-address cycle only */
-#define RTK_CPLUSCMD_RXCSUM_ENB	0x0020	/* enable RX checksum offload */
-#define RTK_CPLUSCMD_VLANSTRIP	0x0040	/* enable VLAN tag stripping */
+#define RE_CPLUSCMD_TXENB	0x0001	/* enable C+ transmit mode */
+#define RE_CPLUSCMD_RXENB	0x0002	/* enable C+ receive mode */
+#define RE_CPLUSCMD_PCI_MRW	0x0008	/* enable PCI multi-read/write */
+#define RE_CPLUSCMD_PCI_DAC	0x0010	/* PCI dual-address cycle only */
+#define RE_CPLUSCMD_RXCSUM_ENB	0x0020	/* enable RX checksum offload */
+#define RE_CPLUSCMD_VLANSTRIP	0x0040	/* enable VLAN tag stripping */
+#define RE_CPLUSCMD_MACSTAT_DIS	0x0080	/* 8168B/C/CP */
+#define RE_CPLUSCMD_ASF		0x0100	/* 8168C/CP */
+#define RE_CPLUSCMD_DBG_SEL	0x0200	/* 8168C/CP */
+#define RE_CPLUSCMD_FORCE_TXFC	0x0400	/* 8168C/CP */
+#define RE_CPLUSCMD_FORCE_RXFC	0x0800	/* 8168C/CP */
+#define RE_CPLUSCMD_FORCE_HDPX	0x1000	/* 8168C/CP */
+#define RE_CPLUSCMD_NORMAL_MODE	0x2000	/* 8168C/CP */
+#define RE_CPLUSCMD_DBG_ENB	0x4000	/* 8168C/CP */
+#define RE_CPLUSCMD_BIST_ENB	0x8000	/* 8168C/CP */
 
 /* C+ early transmit threshold */
 

Index: src/sys/dev/ic/rtl81x9var.h
diff -u src/sys/dev/ic/rtl81x9var.h:1.46 src/sys/dev/ic/rtl81x9var.h:1.47
--- src/sys/dev/ic/rtl81x9var.h:1.46	Sun Apr 26 02:25:57 2009
+++ src/sys/dev/ic/rtl81x9var.h	Wed Apr 29 15:10:57 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl81x9var.h,v 1.46 2009/04/26 02:25:57 tsutsui Exp $	*/
+/*	$NetBSD: rtl81x9var.h,v 1.47 2009/04/29 15:10:57 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998
@@ -192,6 +192,8 @@
 #define RTKQ_DESCV2		0x00000020	/* has V2 TX/RX descriptor */
 #define RTKQ_NOJUMBO		0x00000040	/* no jumbo MTU support */
 #define RTKQ_NOEECMD		0x00000080	/* unusable EEPROM command */
+#define RTKQ_MACSTAT		0x00000100	/* set MACSTAT_DIS on init */
+#define RTKQ_CMDSTOP		0x00000200	/* set STOPREQ on stop */
 
 	bus_dma_tag_t 		sc_dmat;
 

Reply via email to