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
--- 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);
--- 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 */
--- 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;
--- 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);
}
--- 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" },