Module Name: src
Committed By: bouyer
Date: Tue Mar 31 18:22:02 UTC 2009
Modified Files:
src/sys/dev/ic [netbsd-4]: rtl8169.c rtl81x9reg.h rtl81x9var.h
src/sys/dev/pci [netbsd-4]: if_re_pci.c
Log Message:
Pull up following revision(s) (requested by tsutsui in ticket #1297):
src/sys/dev/ic/rtl8169.c 1.104 (via patch), 1.105 (via patch),
1.106 (via patch), 1.108, 1.109 (via patch),
1.110, 1.111, 1.112, 1.113
sys/dev/ic/rtl81x9reg.h: revision 1.30 - 1.35
sys/dev/ic/rtl81x9var.h: revision 1.42 - 1.45
sys/dev/pci/if_re_pci.c: revision 1.35
Add support for 8168C/8111C/8102E chips.
Fix MAC reset issue (PR kern/41009)
Add/fix HW checksum support (PR kern/40955)
To generate a diff of this commit:
cvs rdiff -u -r1.72.2.9 -r1.72.2.10 src/sys/dev/ic/rtl8169.c
cvs rdiff -u -r1.25.2.3 -r1.25.2.4 src/sys/dev/ic/rtl81x9reg.h
cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/sys/dev/ic/rtl81x9var.h
cvs rdiff -u -r1.21.2.4 -r1.21.2.5 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.72.2.9 src/sys/dev/ic/rtl8169.c:1.72.2.10
--- src/sys/dev/ic/rtl8169.c:1.72.2.9 Mon Mar 24 20:50:33 2008
+++ src/sys/dev/ic/rtl8169.c Tue Mar 31 18:22:02 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl8169.c,v 1.72.2.9 2008/03/24 20:50:33 bouyer Exp $ */
+/* $NetBSD: rtl8169.c,v 1.72.2.10 2009/03/31 18:22:02 bouyer Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -397,10 +397,10 @@
sc->sc_dev.dv_xname);
/*
- * NB: Realtek-supplied Linux driver does this only for
- * MCFG_METHOD_2, which corresponds to sc->sc_rev == 2.
+ * NB: Realtek-supplied FreeBSD driver does this only for MACFG_3,
+ * but also says "Rtl8169s sigle chip detected".
*/
- if (1) /* XXX check softc flag for 8169s version */
+ if ((sc->sc_quirk & RTKQ_MACLDPS) != 0)
CSR_WRITE_1(sc, RTK_LDPS, 1);
return;
@@ -531,22 +531,18 @@
if (memcmp((char *)&eh->ether_dhost, (char *)&dst, ETHER_ADDR_LEN) ||
memcmp((char *)&eh->ether_shost, (char *)&src, ETHER_ADDR_LEN) ||
ntohs(eh->ether_type) != ETHERTYPE_IP) {
- aprint_error("%s: WARNING, DMA FAILURE!\n",
- sc->sc_dev.dv_xname);
- aprint_error("%s: expected TX data: %s",
- sc->sc_dev.dv_xname, ether_sprintf(dst));
- aprint_error("/%s/0x%x\n", ether_sprintf(src), ETHERTYPE_IP);
- aprint_error("%s: received RX data: %s",
+ aprint_error("%s: WARNING, DMA FAILURE!\n"
+ "expected TX data: %s/%s/0x%x\n"
+ "received RX data: %s/%s/0x%x\n"
+ "You may have a defective 32-bit NIC plugged "
+ "into a 64-bit PCI slot.\n"
+ "Please re-install the NIC in a 32-bit slot "
+ "for proper operation.\n"
+ "Read the re(4) man page for more details.\n" ,
sc->sc_dev.dv_xname,
- ether_sprintf(eh->ether_dhost));
- aprint_error("/%s/0x%x\n", ether_sprintf(eh->ether_shost),
- ntohs(eh->ether_type));
- aprint_error("%s: You may have a defective 32-bit NIC plugged "
- "into a 64-bit PCI slot.\n", sc->sc_dev.dv_xname);
- aprint_error("%s: Please re-install the NIC in a 32-bit slot "
- "for proper operation.\n", sc->sc_dev.dv_xname);
- aprint_error("%s: Read the re(4) man page for more details.\n",
- sc->sc_dev.dv_xname);
+ ether_sprintf(dst), ether_sprintf(src), ETHERTYPE_IP,
+ ether_sprintf(eh->ether_dhost),
+ ether_sprintf(eh->ether_shost), ntohs(eh->ether_type));
error = EIO;
}
@@ -575,67 +571,120 @@
struct ifnet *ifp;
int error = 0, i, addr_len;
- /* Reset the adapter. */
- re_reset(sc);
-
- if (rtk_read_eeprom(sc, RTK_EE_ID, RTK_EEADDR_LEN1) == 0x8129)
- addr_len = RTK_EEADDR_LEN1;
- else
- addr_len = RTK_EEADDR_LEN0;
-
- /*
- * Get station address from the EEPROM.
- */
- for (i = 0; i < 3; i++) {
- val = rtk_read_eeprom(sc, RTK_EE_EADDR0 + i, addr_len);
- eaddr[(i * 2) + 0] = val & 0xff;
- eaddr[(i * 2) + 1] = val >> 8;
- }
-
if ((sc->sc_quirk & RTKQ_8139CPLUS) == 0) {
uint32_t hwrev;
/* 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 */
- if ( hwrev == RTK_HWREV_8100E_SPIN2) {
- sc->sc_rev = 15;
- } else if (hwrev == RTK_HWREV_8100E) {
- sc->sc_rev = 14;
- } else if (hwrev == RTK_HWREV_8101E) {
- sc->sc_rev = 13;
- } else if (hwrev == RTK_HWREV_8168_SPIN2 ||
- hwrev == RTK_HWREV_8168_SPIN3) {
- sc->sc_rev = 12;
- } else if (hwrev == RTK_HWREV_8168_SPIN1) {
- sc->sc_rev = 11;
- } else if (hwrev == RTK_HWREV_8169_8110SC) {
- sc->sc_rev = 5;
- } else if (hwrev == RTK_HWREV_8169_8110SB) {
- sc->sc_rev = 4;
- } else if (hwrev == RTK_HWREV_8169S) {
- sc->sc_rev = 3;
- } else if (hwrev == RTK_HWREV_8110S) {
- sc->sc_rev = 2;
- } else if (hwrev == RTK_HWREV_8169) {
+ switch (hwrev) {
+ case RTK_HWREV_8169:
+ /* XXX not in the Realtek driver */
sc->sc_rev = 1;
sc->sc_quirk |= RTKQ_8169NONS;
- } else {
+ 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;
+ break;
+ case RTK_HWREV_8168C:
+ case RTK_HWREV_8168C_SPIN2:
+ sc->sc_rev = 24;
+ sc->sc_quirk |= RTKQ_DESCV2 | RTKQ_NOEECMD;
+ /*
+ * From FreeBSD driver:
+ *
+ * These (8168/8111) controllers support jumbo frame
+ * but it seems that enabling it requires touching
+ * additional magic registers. Depending on MAC
+ * revisions some controllers need to disable
+ * checksum offload. So disable jumbo frame until
+ * I have better idea what it really requires to
+ * make it support.
+ * RTL8168C/CP : supports up to 6KB jumbo frame.
+ * RTL8111C/CP : supports up to 9KB jumbo frame.
+ */
+ 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;
+ sc->sc_quirk |= RTKQ_NOJUMBO;
+ break;
+ default:
aprint_normal("%s: Unknown revision (0x%08x)\n",
sc->sc_dev.dv_xname, hwrev);
- /* assume the latest one */
- sc->sc_rev = 15;
+ sc->sc_rev = 0;
}
/* Set RX length mask */
sc->re_rxlenmask = RE_RDESC_STAT_GFRAGLEN;
sc->re_ldata.re_tx_desc_cnt = RE_TX_DESC_CNT_8169;
} else {
+ sc->sc_quirk |= RTKQ_NOJUMBO;
+
/* Set RX length mask */
sc->re_rxlenmask = RE_RDESC_STAT_FRAGLEN;
sc->re_ldata.re_tx_desc_cnt = RE_TX_DESC_CNT_8139;
}
+ /* Reset the adapter. */
+ re_reset(sc);
+
+ if ((sc->sc_quirk & RTKQ_NOEECMD) != 0) {
+ /*
+ * Get station address from ID registers.
+ */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ eaddr[i] = CSR_READ_1(sc, RTK_IDR0 + i);
+ } else {
+ /*
+ * Get station address from the EEPROM.
+ */
+ if (rtk_read_eeprom(sc, RTK_EE_ID, RTK_EEADDR_LEN1) == 0x8129)
+ addr_len = RTK_EEADDR_LEN1;
+ else
+ addr_len = RTK_EEADDR_LEN0;
+
+ /*
+ * Get station address from the EEPROM.
+ */
+ for (i = 0; i < ETHER_ADDR_LEN / 2; i++) {
+ val = rtk_read_eeprom(sc, RTK_EE_EADDR0 + i, addr_len);
+ eaddr[(i * 2) + 0] = val & 0xff;
+ eaddr[(i * 2) + 1] = val >> 8;
+ }
+ }
+
aprint_normal("%s: Ethernet address %s\n",
sc->sc_dev.dv_xname, ether_sprintf(eaddr));
@@ -773,6 +822,15 @@
IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
IFCAP_TSOv4;
+
+ /*
+ * XXX
+ * Still have no idea how to make TSO work on 8168C, 8168CP,
+ * 8102E, 8111C and 8111CP.
+ */
+ if ((sc->sc_quirk & RTKQ_DESCV2) != 0)
+ ifp->if_capabilities &= ~IFCAP_TSOv4;
+
ifp->if_watchdog = re_watchdog;
ifp->if_init = re_init;
ifp->if_snd.ifq_maxlen = RE_IFQ_MAXLEN;
@@ -1276,7 +1334,9 @@
/* Do RX checksumming */
/* Check IP header checksum */
- if (rxstat & RE_RDESC_STAT_PROTOID) {
+ 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;
@@ -1562,6 +1622,7 @@
* chip. I'm not sure if this is a requirement or a bug.)
*/
+ vlanctl = 0;
if ((m->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0) {
uint32_t segsz = m->m_pkthdr.segsz;
@@ -1577,12 +1638,28 @@
if ((m->m_pkthdr.csum_flags &
(M_CSUM_IPv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4))
!= 0) {
- re_flags |= RE_TDESC_CMD_IPCSUM;
- if (m->m_pkthdr.csum_flags & M_CSUM_TCPv4) {
- re_flags |= RE_TDESC_CMD_TCPCSUM;
- } else if (m->m_pkthdr.csum_flags &
- M_CSUM_UDPv4) {
- re_flags |= RE_TDESC_CMD_UDPCSUM;
+ if ((sc->sc_quirk & RTKQ_DESCV2) == 0) {
+ re_flags |= RE_TDESC_CMD_IPCSUM;
+ if (m->m_pkthdr.csum_flags &
+ M_CSUM_TCPv4) {
+ re_flags |=
+ RE_TDESC_CMD_TCPCSUM;
+ } else if (m->m_pkthdr.csum_flags &
+ M_CSUM_UDPv4) {
+ re_flags |=
+ RE_TDESC_CMD_UDPCSUM;
+ }
+ } else {
+ vlanctl |= RE_TDESC_VLANCTL_IPCSUM;
+ if (m->m_pkthdr.csum_flags &
+ M_CSUM_TCPv4) {
+ vlanctl |=
+ RE_TDESC_VLANCTL_TCPCSUM;
+ } else if (m->m_pkthdr.csum_flags &
+ M_CSUM_UDPv4) {
+ vlanctl |=
+ RE_TDESC_VLANCTL_UDPCSUM;
+ }
}
}
}
@@ -1606,7 +1683,8 @@
nsegs = map->dm_nsegs;
pad = FALSE;
if (__predict_false(m->m_pkthdr.len <= RE_IP4CSUMTX_PADLEN &&
- (re_flags & RE_TDESC_CMD_IPCSUM) != 0)) {
+ (re_flags & RE_TDESC_CMD_IPCSUM) != 0 &&
+ (sc->sc_quirk & RTKQ_DESCV2) == 0)) {
pad = TRUE;
nsegs++;
}
@@ -1634,9 +1712,8 @@
* appear in all descriptors of a multi-descriptor
* transmission attempt.
*/
- vlanctl = 0;
if ((mtag = VLAN_OUTPUT_TAG(&sc->ethercom, m)) != NULL)
- vlanctl = bswap16(VLAN_TAG_VALUE(mtag)) |
+ vlanctl |= bswap16(VLAN_TAG_VALUE(mtag)) |
RE_TDESC_VLANCTL_TAG;
/*
@@ -2003,7 +2080,16 @@
switch (command) {
case SIOCSIFMTU:
- if (ifr->ifr_mtu > RE_JUMBO_MTU)
+ /*
+ * Disable jumbo frames if it's not supported.
+ */
+ if ((sc->sc_quirk & RTKQ_NOJUMBO) != 0 &&
+ ifr->ifr_mtu > ETHERMTU) {
+ error = EINVAL;
+ break;
+ }
+
+ if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU_JUMBO)
error = EINVAL;
ifp->if_mtu = ifr->ifr_mtu;
break;
Index: src/sys/dev/ic/rtl81x9reg.h
diff -u src/sys/dev/ic/rtl81x9reg.h:1.25.2.3 src/sys/dev/ic/rtl81x9reg.h:1.25.2.4
--- src/sys/dev/ic/rtl81x9reg.h:1.25.2.3 Mon Mar 24 20:50:33 2008
+++ src/sys/dev/ic/rtl81x9reg.h Tue Mar 31 18:22:02 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9reg.h,v 1.25.2.3 2008/03/24 20:50:33 bouyer Exp $ */
+/* $NetBSD: rtl81x9reg.h,v 1.25.2.4 2009/03/31 18:22:02 bouyer Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -126,11 +126,13 @@
#define RTK_GTXSTART 0x0038 /* 8 bits */
#define RTK_TIMERINT_8169 0x0058 /* different offset than 8139 */
#define RTK_PHYAR 0x0060
-#define RTK_TBICSR 0x0064
-#define RTK_TBI_ANAR 0x0068
+#define RTK_CSIDR 0x0064
+#define RTK_CSIAR 0x0068
#define RTK_TBI_LPAR 0x006A
#define RTK_GMEDIASTAT 0x006C /* 8 bits */
+#define RTK_EPHYAR 0x0080
#define RTK_LDPS 0x0082 /* Link Down Power Saving */
+#define RTK_DBG_REG 0x00D1
#define RTK_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */
#define RTK_IM 0x00E2
@@ -155,12 +157,16 @@
#define RTK_HWREV_8169S 0x04000000
#define RTK_HWREV_8169_8110SB 0x10000000
#define RTK_HWREV_8169_8110SC 0x18000000
+#define RTK_HWREV_8102EL 0x24800000
#define RTK_HWREV_8168_SPIN1 0x30000000
#define RTK_HWREV_8100E 0x30800000
#define RTK_HWREV_8101E 0x34000000
+#define RTK_HWREV_8102E 0x34800000
#define RTK_HWREV_8168_SPIN2 0x38000000
#define RTK_HWREV_8168_SPIN3 0x38400000
#define RTK_HWREV_8100E_SPIN2 0x38800000
+#define RTK_HWREV_8168C 0x3C000000
+#define RTK_HWREV_8168C_SPIN2 0x3C400000
#define RTK_HWREV_8139 0x60000000
#define RTK_HWREV_8139A 0x70000000
#define RTK_HWREV_8139AG 0x70800000
Index: src/sys/dev/ic/rtl81x9var.h
diff -u src/sys/dev/ic/rtl81x9var.h:1.37.2.1 src/sys/dev/ic/rtl81x9var.h:1.37.2.2
--- src/sys/dev/ic/rtl81x9var.h:1.37.2.1 Wed May 16 20:47:35 2007
+++ src/sys/dev/ic/rtl81x9var.h Tue Mar 31 18:22:02 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9var.h,v 1.37.2.1 2007/05/16 20:47:35 jdc Exp $ */
+/* $NetBSD: rtl81x9var.h,v 1.37.2.2 2009/03/31 18:22:02 bouyer Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -188,6 +188,10 @@
#define RTKQ_8139CPLUS 0x00000002 /* 8139C+ */
#define RTKQ_8169NONS 0x00000004 /* old non-single 8169 */
#define RTKQ_PCIE 0x00000008 /* PCIe variants */
+#define RTKQ_MACLDPS 0x00000010 /* has LDPS register */
+#define RTKQ_DESCV2 0x00000020 /* has V2 TX/RX descriptor */
+#define RTKQ_NOJUMBO 0x00000040 /* no jumbo MTU support */
+#define RTKQ_NOEECMD 0x00000080 /* unusable EEPROM command */
bus_dma_tag_t sc_dmat;
Index: src/sys/dev/pci/if_re_pci.c
diff -u src/sys/dev/pci/if_re_pci.c:1.21.2.4 src/sys/dev/pci/if_re_pci.c:1.21.2.5
--- src/sys/dev/pci/if_re_pci.c:1.21.2.4 Wed May 16 20:48:07 2007
+++ src/sys/dev/pci/if_re_pci.c Tue Mar 31 18:22:02 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: if_re_pci.c,v 1.21.2.4 2007/05/16 20:48:07 jdc Exp $ */
+/* $NetBSD: if_re_pci.c,v 1.21.2.5 2009/03/31 18:22:02 bouyer Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -100,7 +100,7 @@
"RealTek 8139C+ 10/100BaseTX" },
{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8101E,
RTK_8101E,
- "RealTek 8100E/8101E PCIe 10/100BaseTX" },
+ "RealTek 8100E/8101E/8102E/8102EL PCIe 10/100BaseTX" },
{ PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8168,
RTK_8168,
"RealTek 8168B/8111B PCIe Gigabit Ethernet" },