Fri Jun 19 21:51:44 2009 UTC ()
Pull up following revision(s) (requested by tsutsui in ticket #821):
	sys/dev/ic/rtl8169.c: revisions 1.107, 1.114-1.119, 1.121
	sys/dev/ic/rtl81x9reg.h: revisions 1.36-1.39
	sys/dev/ic/rtl81x9var.h: revision 1.47
	sys/dev/mii/rgephy.c: revision 1.27 via patch
	sys/dev/pci/if_re_pci.c: revision 1.36
remove extra semicolons.
--
Add HWREV values of RTL8168CP and RTL8168D.  From FreeBSD.

XXX: needs more quirk handling after wakeup for newer chips.
--
Add HWREV of RTL8102EL variant.  From FUKAUMI Naoki.
--
Assume an unknown HWREV chip has the same features with the latest one.
--
Remove suffix "B" from rtk_name of PCI_PRODUCT_REALTEK_RT8168 devices.
All 8168/8111 variants (8168/8168B/8168C/8168CP/8168D/8111B/8111C/8111CP)
have the same PCI device ID.
--
Remove magic reset sequence except wakeup for rev 2 chips which breaks 8111D.
Problem reported and fix confirmed by Thomas Bieg on current-users.

Also tested on 8111C (no bad side effect) by several users privately.
--
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.
--
Remove unused sc_rev settings (all quirks are handled by sc_quirk)
and merge HWREV cases which have the same quirks.
--
- rename RTK_HWREV_8102EL_SPIN2 -> RTK_HWREV_8103E
- add a HWREV value for 8168DP
Per Realtek's Linux drivers.
--
Two fixes for RX hwcsum on DESCV2 chips:
 * On checking TCPv4/UDPv4 RX checksum on DESCV2 chips, also check
   RE_RDESC_VLANCTL_IPV4 bit because those DESCV2 chips may also recognize
   IPv6 packets and set RE_PROTOID_TCPIP or RE_PROTOID_UDPIP bits for
   TCPv6/UDPv6 packets.  This may fix PR kern/40605.
 * According to Realtek's Linux driver, DESCV2 chips don't set RE_PROTOID_IP
   for non-TCP/UDP IP packets (set only RE_RDESC_VLANCTL_IPV[46]) so
   remove PROTOID check for IPv4 RX cheksum on DESCV2 chips.


(snj)
diff -r1.105.4.7 -r1.105.4.8 src/sys/dev/ic/rtl8169.c
diff -r1.32.4.3 -r1.32.4.4 src/sys/dev/ic/rtl81x9reg.h
diff -r1.41.12.4 -r1.41.12.5 src/sys/dev/ic/rtl81x9var.h
diff -r1.21 -r1.21.10.1 src/sys/dev/mii/rgephy.c
diff -r1.35 -r1.35.4.1 src/sys/dev/pci/if_re_pci.c

cvs diff -r1.105.4.7 -r1.105.4.8 src/sys/dev/ic/rtl8169.c (expand / switch to context diff)
--- src/sys/dev/ic/rtl8169.c 2009/05/01 02:11:15 1.105.4.7
+++ src/sys/dev/ic/rtl8169.c 2009/06/19 21:51:43 1.105.4.8
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl8169.c,v 1.105.4.7 2009/05/01 02:11:15 snj Exp $	*/
+/*	$NetBSD: rtl8169.c,v 1.105.4.8 2009/06/19 21:51:43 snj Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998-2003
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.105.4.7 2009/05/01 02:11:15 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtl8169.c,v 1.105.4.8 2009/06/19 21:51:43 snj Exp $");
 /* $FreeBSD: /repoman/r/ncvs/src/sys/dev/re/if_re.c,v 1.20 2004/04/11 20:34:08 ru Exp $ */
 
 /*
@@ -567,43 +567,27 @@
 
 		/* Revision of 8169/8169S/8110s in bits 30..26, 23 */
 		hwrev = CSR_READ_4(sc, RTK_TXCFG) & RTK_TXCFG_HWREV;
-		/* These rev numbers are taken from Realtek's driver */
 		switch (hwrev) {
 		case RTK_HWREV_8169:
-			/* XXX not in the Realtek driver */
-			sc->sc_rev = 1;
 			sc->sc_quirk |= RTKQ_8169NONS;
 			break;
 		case RTK_HWREV_8169S:
 		case RTK_HWREV_8110S:
-			sc->sc_rev = 3;
-			sc->sc_quirk |= RTKQ_MACLDPS;
-			break;
 		case RTK_HWREV_8169_8110SB:
-			sc->sc_rev = 4;
-			sc->sc_quirk |= RTKQ_MACLDPS;
-			break;
 		case RTK_HWREV_8169_8110SC:
-			sc->sc_rev = 5;
 			sc->sc_quirk |= RTKQ_MACLDPS;
 			break;
-		case RTK_HWREV_8101E:
-			sc->sc_rev = 11;
-			sc->sc_quirk |= RTKQ_NOJUMBO;
-			break;
 		case RTK_HWREV_8168_SPIN1:
-			sc->sc_rev = 21;
-			break;
 		case RTK_HWREV_8168_SPIN2:
-			sc->sc_rev = 22;
-			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:
-			sc->sc_rev = 24;
-			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD;
+		case RTK_HWREV_8168CP:
+		case RTK_HWREV_8168D:
+			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD |
+			    RTKQ_MACSTAT | RTKQ_CMDSTOP;
 			/*
 			 * From FreeBSD driver:
 			 * 
@@ -619,22 +603,23 @@
 			 */
 			sc->sc_quirk |= RTKQ_NOJUMBO;
 			break;
-		case RTK_HWREV_8102E:
-		case RTK_HWREV_8102EL:
-			sc->sc_rev = 25;
-			sc->sc_quirk |=
-			    RTKQ_DESCV2 | RTKQ_NOEECMD | RTKQ_NOJUMBO;
-			break;
 		case RTK_HWREV_8100E:
 		case RTK_HWREV_8100E_SPIN2:
-			/* XXX not in the Realtek driver */
-			sc->sc_rev = 0;
+		case RTK_HWREV_8101E:
 			sc->sc_quirk |= RTKQ_NOJUMBO;
 			break;
+		case RTK_HWREV_8102E:
+		case RTK_HWREV_8102EL:
+		case RTK_HWREV_8103E:
+			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD |
+			    RTKQ_MACSTAT | RTKQ_CMDSTOP | RTKQ_NOJUMBO;
+			break;
 		default:
 			aprint_normal_dev(sc->sc_dev,
 			    "Unknown revision (0x%08x)\n", hwrev);
-			sc->sc_rev = 0;
+			/* assume the latest features */
+			sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD;
+			sc->sc_quirk |= RTKQ_NOJUMBO;
 		}
 
 		/* Set RX length mask */
@@ -1266,25 +1251,49 @@
 		m->m_pkthdr.rcvif = ifp;
 
 		/* Do RX checksumming */
+		if ((sc->sc_quirk & RTKQ_DESCV2) == 0) {
+			/* Check IP header checksum */
+			if ((rxstat & RE_RDESC_STAT_PROTOID) != 0) {
+				m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
+				if (rxstat & RE_RDESC_STAT_IPSUMBAD)
+					m->m_pkthdr.csum_flags |=
+					    M_CSUM_IPv4_BAD;
 
-		/* Check IP header checksum */
-		if ((rxstat & RE_RDESC_STAT_PROTOID) != 0 &&
-		    ((sc->sc_quirk & RTKQ_DESCV2) == 0 ||
-		     (rxvlan & RE_RDESC_VLANCTL_IPV4) != 0)) {
-			m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
-			if (rxstat & RE_RDESC_STAT_IPSUMBAD)
-				m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
-		}
+				/* Check TCP/UDP checksum */
+				if (RE_TCPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
+					if (rxstat & RE_RDESC_STAT_TCPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				} else if (RE_UDPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
+					if (rxstat & RE_RDESC_STAT_UDPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				}
+			}
+		} else {
+			/* Check IPv4 header checksum */
+			if ((rxvlan & RE_RDESC_VLANCTL_IPV4) != 0) {
+				m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
+				if (rxstat & RE_RDESC_STAT_IPSUMBAD)
+					m->m_pkthdr.csum_flags |=
+					    M_CSUM_IPv4_BAD;
 
-		/* Check TCP/UDP checksum */
-		if (RE_TCPPKT(rxstat)) {
-			m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
-			if (rxstat & RE_RDESC_STAT_TCPSUMBAD)
-				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
-		} else if (RE_UDPPKT(rxstat)) {
-			m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
-			if (rxstat & RE_RDESC_STAT_UDPSUMBAD)
-				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
+				/* Check TCPv4/UDPv4 checksum */
+				if (RE_TCPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_TCPv4;
+					if (rxstat & RE_RDESC_STAT_TCPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				} else if (RE_UDPPKT(rxstat)) {
+					m->m_pkthdr.csum_flags |= M_CSUM_UDPv4;
+					if (rxstat & RE_RDESC_STAT_UDPSUMBAD)
+						m->m_pkthdr.csum_flags |=
+						    M_CSUM_TCP_UDP_BAD;
+				}
+			}
+			/* XXX Check TCPv6/UDPv6 checksum? */
 		}
 
 		if (rxvlan & RE_RDESC_VLANCTL_TAG) {
@@ -1713,6 +1722,7 @@
 	const uint8_t *enaddr;
 	uint32_t rxcfg = 0;
 	uint32_t reg;
+	uint16_t cfg;
 	int error;
 
 	if ((error = re_enable(sc)) != 0)
@@ -1730,32 +1740,27 @@
 	 * RX checksum offload. We must configure the C+ register
 	 * before all others.
 	 */
-	reg = 0;
+	cfg = RE_CPLUSCMD_PCI_MRW;
 
 	/*
-	 * 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.
-	 */
-
-	/*
 	 * 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)
@@ -1975,8 +1980,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);

cvs diff -r1.32.4.3 -r1.32.4.4 src/sys/dev/ic/rtl81x9reg.h (expand / switch to context diff)
--- src/sys/dev/ic/rtl81x9reg.h 2009/05/01 02:10:03 1.32.4.3
+++ src/sys/dev/ic/rtl81x9reg.h 2009/06/19 21:51:43 1.32.4.4
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl81x9reg.h,v 1.32.4.3 2009/05/01 02:10:03 snj Exp $	*/
+/*	$NetBSD: rtl81x9reg.h,v 1.32.4.4 2009/06/19 21:51:43 snj Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998
@@ -158,6 +158,9 @@
 #define RTK_HWREV_8169_8110SB	0x10000000
 #define RTK_HWREV_8169_8110SC	0x18000000
 #define RTK_HWREV_8102EL	0x24800000
+#define RTK_HWREV_8103E		0x24C00000
+#define RTK_HWREV_8168D		0x28000000
+#define RTK_HWREV_8168DP	0x28800000
 #define RTK_HWREV_8168_SPIN1	0x30000000
 #define RTK_HWREV_8100E		0x30800000
 #define RTK_HWREV_8101E		0x34000000
@@ -167,6 +170,7 @@
 #define RTK_HWREV_8100E_SPIN2	0x38800000
 #define RTK_HWREV_8168C		0x3C000000
 #define RTK_HWREV_8168C_SPIN2	0x3C400000
+#define RTK_HWREV_8168CP	0x3C800000
 #define RTK_HWREV_8139		0x60000000
 #define RTK_HWREV_8139A		0x70000000
 #define RTK_HWREV_8139AG	0x70800000
@@ -306,6 +310,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
@@ -400,12 +405,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 */
 

cvs diff -r1.41.12.4 -r1.41.12.5 src/sys/dev/ic/rtl81x9var.h (expand / switch to context diff)
--- src/sys/dev/ic/rtl81x9var.h 2009/05/01 02:08:29 1.41.12.4
+++ src/sys/dev/ic/rtl81x9var.h 2009/06/19 21:51:43 1.41.12.5
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtl81x9var.h,v 1.41.12.4 2009/05/01 02:08:29 snj Exp $	*/
+/*	$NetBSD: rtl81x9var.h,v 1.41.12.5 2009/06/19 21:51:43 snj 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;
 

cvs diff -r1.21 -r1.21.10.1 src/sys/dev/mii/rgephy.c (expand / switch to context diff)
--- src/sys/dev/mii/rgephy.c 2008/05/04 17:06:10 1.21
+++ src/sys/dev/mii/rgephy.c 2009/06/19 21:51:43 1.21.10.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: rgephy.c,v 1.21 2008/05/04 17:06:10 xtraeme Exp $	*/
+/*	$NetBSD: rgephy.c,v 1.21.10.1 2009/06/19 21:51:43 snj Exp $	*/
 
 /*
  * Copyright (c) 2003
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.21 2008/05/04 17:06:10 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.21.10.1 2009/06/19 21:51:43 snj Exp $");
 
 
 /*
@@ -589,13 +589,6 @@
 	if (rsc->mii_revision < 2)
 		rgephy_load_dspcode(sc);
 	else {
-		PHY_WRITE(sc, 0x1F, 0x0001);
-		PHY_WRITE(sc, 0x09, 0x273a);
-		PHY_WRITE(sc, 0x0e, 0x7bfb);
-		PHY_WRITE(sc, 0x1b, 0x841e);
-
-		PHY_WRITE(sc, 0x1F, 0x0002);
-		PHY_WRITE(sc, 0x01, 0x90D0);
 		PHY_WRITE(sc, 0x1F, 0x0000);
 		PHY_WRITE(sc, 0x0e, 0x0000);
 	}

cvs diff -r1.35 -r1.35.4.1 src/sys/dev/pci/if_re_pci.c (expand / switch to context diff)
--- src/sys/dev/pci/if_re_pci.c 2008/08/23 14:27:45 1.35
+++ src/sys/dev/pci/if_re_pci.c 2009/06/19 21:51:44 1.35.4.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_re_pci.c,v 1.35 2008/08/23 14:27:45 tnn Exp $	*/
+/*	$NetBSD: if_re_pci.c,v 1.35.4.1 2009/06/19 21:51:44 snj Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998-2003
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_re_pci.c,v 1.35 2008/08/23 14:27:45 tnn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_re_pci.c,v 1.35.4.1 2009/06/19 21:51:44 snj Exp $");
 
 #include "bpfilter.h"
 #include "vlan.h"
@@ -109,7 +109,7 @@
 	    "RealTek 8100E/8101E/8102E/8102EL PCIe 10/100BaseTX" },
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8168,
 	    RTK_8168,
-	    "RealTek 8168B/8111B PCIe Gigabit Ethernet" },
+	    "RealTek 8168/8111 PCIe Gigabit Ethernet" },
 	{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8169,
 	    RTK_8169,
 	    "RealTek 8169/8110 Gigabit Ethernet" },