Module Name: src Committed By: snj Date: Fri Jun 19 21:51:44 UTC 2009
Modified Files: src/sys/dev/ic [netbsd-5]: rtl8169.c rtl81x9reg.h rtl81x9var.h src/sys/dev/mii [netbsd-5]: rgephy.c src/sys/dev/pci [netbsd-5]: if_re_pci.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.105.4.7 -r1.105.4.8 src/sys/dev/ic/rtl8169.c cvs rdiff -u -r1.32.4.3 -r1.32.4.4 src/sys/dev/ic/rtl81x9reg.h cvs rdiff -u -r1.41.12.4 -r1.41.12.5 src/sys/dev/ic/rtl81x9var.h cvs rdiff -u -r1.21 -r1.21.10.1 src/sys/dev/mii/rgephy.c cvs rdiff -u -r1.35 -r1.35.4.1 src/sys/dev/pci/if_re_pci.c 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.105.4.7 src/sys/dev/ic/rtl8169.c:1.105.4.8 --- src/sys/dev/ic/rtl8169.c:1.105.4.7 Fri May 1 02:11:15 2009 +++ src/sys/dev/ic/rtl8169.c Fri Jun 19 21:51:43 2009 @@ -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 */ - - /* 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; + 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 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 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; - - /* - * 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) @@ -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); Index: src/sys/dev/ic/rtl81x9reg.h diff -u src/sys/dev/ic/rtl81x9reg.h:1.32.4.3 src/sys/dev/ic/rtl81x9reg.h:1.32.4.4 --- src/sys/dev/ic/rtl81x9reg.h:1.32.4.3 Fri May 1 02:10:03 2009 +++ src/sys/dev/ic/rtl81x9reg.h Fri Jun 19 21:51:43 2009 @@ -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 */ Index: src/sys/dev/ic/rtl81x9var.h diff -u src/sys/dev/ic/rtl81x9var.h:1.41.12.4 src/sys/dev/ic/rtl81x9var.h:1.41.12.5 --- src/sys/dev/ic/rtl81x9var.h:1.41.12.4 Fri May 1 02:08:29 2009 +++ src/sys/dev/ic/rtl81x9var.h Fri Jun 19 21:51:43 2009 @@ -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; Index: src/sys/dev/mii/rgephy.c diff -u src/sys/dev/mii/rgephy.c:1.21 src/sys/dev/mii/rgephy.c:1.21.10.1 --- src/sys/dev/mii/rgephy.c:1.21 Sun May 4 17:06:10 2008 +++ src/sys/dev/mii/rgephy.c Fri Jun 19 21:51:43 2009 @@ -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); } Index: src/sys/dev/pci/if_re_pci.c diff -u src/sys/dev/pci/if_re_pci.c:1.35 src/sys/dev/pci/if_re_pci.c:1.35.4.1 --- src/sys/dev/pci/if_re_pci.c:1.35 Sat Aug 23 14:27:45 2008 +++ src/sys/dev/pci/if_re_pci.c Fri Jun 19 21:51:44 2009 @@ -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" },