Module Name: src
Committed By: bouyer
Date: Tue Aug 18 09:46:51 UTC 2009
Modified Files:
src/sys/dev/ic [netbsd-4]: rtl8169.c rtl81x9reg.h rtl81x9var.h
src/sys/dev/mii [netbsd-4]: rgephy.c rgephyreg.h
src/sys/dev/pci [netbsd-4]: if_re_pci.c
Log Message:
Pull up following revision(s) (requested by tsutsui in ticket #1339):
sys/dev/ic/rtl8169.c: revisions 1.107, 1.114, 1.115, 1.116,
1.117 (via patch), 1.118 (via patch),
1.119, 1.121
sys/dev/ic/rtl81x9reg.h: revisions 1.36, 1.37, 1.38, 1.39
sys/dev/ic/rtl81x9var.h: revision 1.47
sys/dev/mii/rgephy.c: revisions 1.16, 1.18, 1.19, 1.27 (via patch)
sys/dev/mii/rgephyreg.h: revision 1.3
sys/dev/pci/if_re_pci.c: revision 1.36
- add support for RTL8211B(L) to rgephy(4)
- add a wakeup instruction for rgephy(4) on newer re(4) chips
- detect RTL8169CP, RTL8168D/8111D, and RTL8103E variants
- fix rgephy(4) problem on RTL8111D reported on current-users:
http://mail-index.NetBSD.org/current-users/2009/04/12/msg008977.html
http://mail-index.NetBSD.org/current-users/2009/04/19/msg009096.html
- pull more quirk handling from FreeBSD
- fix RX hwcksum for DESCV2 chips for PR kern/40605
- remove "B" suffix from RTL8168 device names in attach message
To generate a diff of this commit:
cvs rdiff -u -r1.72.2.10 -r1.72.2.11 src/sys/dev/ic/rtl8169.c
cvs rdiff -u -r1.25.2.5 -r1.25.2.6 src/sys/dev/ic/rtl81x9reg.h
cvs rdiff -u -r1.37.2.2 -r1.37.2.3 src/sys/dev/ic/rtl81x9var.h
cvs rdiff -u -r1.15 -r1.15.2.1 src/sys/dev/mii/rgephy.c
cvs rdiff -u -r1.2 -r1.2.2.1 src/sys/dev/mii/rgephyreg.h
cvs rdiff -u -r1.21.2.5 -r1.21.2.6 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.10 src/sys/dev/ic/rtl8169.c:1.72.2.11
--- src/sys/dev/ic/rtl8169.c:1.72.2.10 Tue Mar 31 18:22:02 2009
+++ src/sys/dev/ic/rtl8169.c Tue Aug 18 09:46:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl8169.c,v 1.72.2.10 2009/03/31 18:22:02 bouyer Exp $ */
+/* $NetBSD: rtl8169.c,v 1.72.2.11 2009/08/18 09:46:51 bouyer Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -576,43 +576,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:
*
@@ -628,22 +612,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("%s: Unknown revision (0x%08x)\n",
sc->sc_dev.dv_xname, 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 */
@@ -1332,25 +1317,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) {
@@ -1850,6 +1859,7 @@
uint8_t *enaddr;
uint32_t rxcfg = 0;
uint32_t reg;
+ uint16_t cfg;
int error;
if ((error = re_enable(sc)) != 0)
@@ -1867,32 +1877,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)
@@ -2149,8 +2154,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.25.2.5 src/sys/dev/ic/rtl81x9reg.h:1.25.2.6
--- src/sys/dev/ic/rtl81x9reg.h:1.25.2.5 Wed Apr 1 20:27:08 2009
+++ src/sys/dev/ic/rtl81x9reg.h Tue Aug 18 09:46:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9reg.h,v 1.25.2.5 2009/04/01 20:27:08 bouyer Exp $ */
+/* $NetBSD: rtl81x9reg.h,v 1.25.2.6 2009/08/18 09:46:51 bouyer 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.37.2.2 src/sys/dev/ic/rtl81x9var.h:1.37.2.3
--- src/sys/dev/ic/rtl81x9var.h:1.37.2.2 Tue Mar 31 18:22:02 2009
+++ src/sys/dev/ic/rtl81x9var.h Tue Aug 18 09:46:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9var.h,v 1.37.2.2 2009/03/31 18:22:02 bouyer Exp $ */
+/* $NetBSD: rtl81x9var.h,v 1.37.2.3 2009/08/18 09:46:51 bouyer 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.15 src/sys/dev/mii/rgephy.c:1.15.2.1
--- src/sys/dev/mii/rgephy.c:1.15 Wed Nov 29 13:57:59 2006
+++ src/sys/dev/mii/rgephy.c Tue Aug 18 09:46:50 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: rgephy.c,v 1.15 2006/11/29 13:57:59 tsutsui Exp $ */
+/* $NetBSD: rgephy.c,v 1.15.2.1 2009/08/18 09:46:50 bouyer Exp $ */
/*
* Copyright (c) 2003
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.15 2006/11/29 13:57:59 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.15.2.1 2009/08/18 09:46:50 bouyer Exp $");
/*
@@ -61,7 +61,12 @@
static int rgephy_match(struct device *, struct cfdata *, void *);
static void rgephy_attach(struct device *, struct device *, void *);
-CFATTACH_DECL(rgephy, sizeof(struct mii_softc),
+struct rgephy_softc {
+ struct mii_softc mii_sc;
+ int mii_revision;
+};
+
+CFATTACH_DECL(rgephy, sizeof(struct rgephy_softc),
rgephy_match, rgephy_attach, mii_phy_detach, mii_phy_activate);
@@ -72,8 +77,6 @@
static void rgephy_loop(struct mii_softc *);
static void rgephy_load_dspcode(struct mii_softc *);
-static int rgephy_mii_model;
-
static const struct mii_phy_funcs rgephy_funcs = {
rgephy_service, rgephy_status, rgephy_reset,
};
@@ -103,19 +106,26 @@
static void
rgephy_attach(struct device *parent, struct device *self, void *aux)
{
- struct mii_softc *sc = device_private(self);
+ struct rgephy_softc *rsc = device_private(self);
+ struct mii_softc *sc = &rsc->mii_sc;
struct mii_attach_args *ma = aux;
struct mii_data *mii = ma->mii_data;
const struct mii_phydesc *mpd;
int rev;
const char *sep = "";
+ rsc = device_private(self);
+ sc = &rsc->mii_sc;
+ ma = aux;
+ mii = ma->mii_data;
+
rev = MII_REV(ma->mii_id2);
mpd = mii_phy_match(ma, rgephys);
aprint_naive(": Media interface\n");
aprint_normal(": %s, rev. %d\n", mpd->mpd_name, rev);
- sc->mii_mpd_model = rev; /* XXX miivar.h comment vs usage? */
+ rsc->mii_revision = rev;
+
sc->mii_inst = mii->mii_instance;
sc->mii_phy = ma->mii_phyno;
sc->mii_pdata = mii;
@@ -124,23 +134,14 @@
sc->mii_funcs = &rgephy_funcs;
- /* Don't do isolate on this PHY. */
- sc->mii_flags |= MIIF_NOISOLATE;
-
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
#define PRINT(n) aprint_normal("%s%s", sep, (n)); sep = ", "
-#if 0
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
- BMCR_ISO);
-#endif
#ifdef __FreeBSD__
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
BMCR_LOOP|BMCR_S100);
#endif
- rgephy_mii_model = MII_MODEL(ma->mii_id2);
-
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
sc->mii_capabilities &= ~BMSR_ANEG;
@@ -149,19 +150,11 @@
* media explicitly. Why?
*/
aprint_normal("%s: ", sc->mii_dev.dv_xname);
-#ifdef __FreeBSD__
- mii_phy_add_media(sc);
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
- RGEPHY_BMCR_FDX);
- PRINT(", 1000baseTX");
- ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0);
- PRINT("1000baseTX-FDX");
-#else
if (sc->mii_capabilities & BMSR_EXTSTAT) {
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
}
mii_phy_add_media(sc);
-#endif
+
/* rtl8169S does not report auto-sense; add manually. */
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), MII_NMEDIA);
sep =", ";
@@ -177,9 +170,12 @@
static int
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
+ struct rgephy_softc *rsc;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int reg, speed, gig, anar;
+ rsc = (struct rgephy_softc *)sc;
+
switch (cmd) {
case MII_POLLSTAT:
/*
@@ -254,7 +250,7 @@
}
/*
- * When settning the link manually, one side must
+ * When setting the link manually, one side must
* be the master and the other the slave. However
* ifmedia doesn't give us a good way to specify
* this, so we fake it by using one of the LINK
@@ -271,11 +267,9 @@
PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
break;
-#ifdef foo
case IFM_NONE:
PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN);
break;
-#endif
case IFM_100_T4:
default:
return EINVAL;
@@ -306,9 +300,20 @@
* need to restart the autonegotiation process. Read
* the BMSR twice in case it's latched.
*/
- reg = PHY_READ(sc, RTK_GMEDIASTAT);
- if ((reg & RTK_GMEDIASTAT_LINK) != 0)
- break;
+ if (rsc->mii_revision >= 2) {
+ /* RTL8211B(L) */
+ reg = PHY_READ(sc, RGEPHY_MII_SSR);
+ if (reg & RGEPHY_SSR_LINK) {
+ sc->mii_ticks = 0;
+ break;
+ }
+ } else {
+ reg = PHY_READ(sc, RTK_GMEDIASTAT);
+ if ((reg & RTK_GMEDIASTAT_LINK) != 0) {
+ sc->mii_ticks = 0;
+ break;
+ }
+ }
/*
* Only retry autonegotiation every 5 seconds.
@@ -333,7 +338,7 @@
sc->mii_media_status != mii->mii_media_status ||
cmd == MII_MEDIACHG) {
/* XXX only for v0/v1 phys. */
- if (sc->mii_mpd_model < 2)
+ if (rsc->mii_revision < 2)
rgephy_load_dspcode(sc);
}
mii_phy_update(sc, cmd);
@@ -343,18 +348,27 @@
static void
rgephy_status(struct mii_softc *sc)
{
+ struct rgephy_softc *rsc;
struct mii_data *mii = sc->mii_pdata;
- int bmsr, bmcr;
+ int gstat, bmsr, bmcr;
+ uint16_t ssr;
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ(sc, RTK_GMEDIASTAT);
+ rsc = (struct rgephy_softc *)sc;
+ if (rsc->mii_revision >= 2) {
+ ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+ if (ssr & RGEPHY_SSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+ } else {
+ gstat = PHY_READ(sc, RTK_GMEDIASTAT);
+ if ((gstat & RTK_GMEDIASTAT_LINK) != 0)
+ mii->mii_media_status |= IFM_ACTIVE;
+ }
- if ((bmsr & RTK_GMEDIASTAT_LINK) != 0)
- mii->mii_media_status |= IFM_ACTIVE;
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
-
+ bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
if ((bmcr & RGEPHY_BMCR_ISO) != 0) {
@@ -374,19 +388,39 @@
}
}
- bmsr = PHY_READ(sc, RTK_GMEDIASTAT);
- if ((bmsr & RTK_GMEDIASTAT_1000MBPS) != 0)
- mii->mii_media_active |= IFM_1000_T;
- else if ((bmsr & RTK_GMEDIASTAT_100MBPS) != 0)
- mii->mii_media_active |= IFM_100_TX;
- else if ((bmsr & RTK_GMEDIASTAT_10MBPS) != 0)
- mii->mii_media_active |= IFM_10_T;
- else
- mii->mii_media_active |= IFM_NONE;
- if ((bmsr & RTK_GMEDIASTAT_FDX) != 0)
- mii->mii_media_active |= IFM_FDX;
-
- return;
+ if (rsc->mii_revision >= 2) {
+ ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+ switch (ssr & RGEPHY_SSR_SPD_MASK) {
+ case RGEPHY_SSR_S1000:
+ mii->mii_media_active |= IFM_1000_T;
+ break;
+ case RGEPHY_SSR_S100:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
+ case RGEPHY_SSR_S10:
+ mii->mii_media_active |= IFM_10_T;
+ break;
+ default:
+ mii->mii_media_active |= IFM_NONE;
+ break;
+ }
+ if (ssr & RGEPHY_SSR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
+ } else {
+ gstat = PHY_READ(sc, RTK_GMEDIASTAT);
+ if ((gstat & RTK_GMEDIASTAT_1000MBPS) != 0)
+ mii->mii_media_active |= IFM_1000_T;
+ else if ((gstat & RTK_GMEDIASTAT_100MBPS) != 0)
+ mii->mii_media_active |= IFM_100_TX;
+ else if ((gstat & RTK_GMEDIASTAT_10MBPS) != 0)
+ mii->mii_media_active |= IFM_10_T;
+ else
+ mii->mii_media_active |= IFM_NONE;
+ if ((gstat & RTK_GMEDIASTAT_FDX) != 0)
+ mii->mii_media_active |= IFM_FDX;
+ }
}
@@ -413,11 +447,15 @@
static void
rgephy_loop(struct mii_softc *sc)
{
+ struct rgephy_softc *rsc;
uint32_t bmsr;
int i;
- PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
- DELAY(1000);
+ rsc = (struct rgephy_softc *)sc;
+ if (rsc->mii_revision < 2) {
+ PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
+ DELAY(1000);
+ }
for (i = 0; i < 15000; i++) {
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
@@ -540,21 +578,17 @@
static void
rgephy_reset(struct mii_softc *sc)
{
+ struct rgephy_softc *rsc;
mii_phy_reset(sc);
DELAY(1000);
- if (sc->mii_mpd_model < 2)
+ rsc = (struct rgephy_softc *)sc;
+ 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);
}
/* Reset capabilities */
Index: src/sys/dev/mii/rgephyreg.h
diff -u src/sys/dev/mii/rgephyreg.h:1.2 src/sys/dev/mii/rgephyreg.h:1.2.2.1
--- src/sys/dev/mii/rgephyreg.h:1.2 Wed Nov 29 14:01:53 2006
+++ src/sys/dev/mii/rgephyreg.h Tue Aug 18 09:46:50 2009
@@ -137,6 +137,17 @@
#define RGEPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */
#define RGEPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */
-
+/* RTL8211B(L) */
+#define RGEPHY_MII_SSR 0x11 /* PHY Specific status register */
+#define RGEPHY_SSR_S1000 0x8000 /* 1000Mbps */
+#define RGEPHY_SSR_S100 0x4000 /* 100Mbps */
+#define RGEPHY_SSR_S10 0x0000 /* 10Mbps */
+#define RGEPHY_SSR_SPD_MASK 0xc000
+#define RGEPHY_SSR_FDX 0x2000 /* full duplex */
+#define RGEPHY_SSR_PAGE_RECEIVED 0x1000 /* new page received */
+#define RGEPHY_SSR_SPD_DPLX_RESOLVED 0x0800 /* speed/duplex resolved */
+#define RGEPHY_SSR_LINK 0x0400 /* link up */
+#define RGEPHY_SSR_MDI_XOVER 0x0040 /* MDI crossover */
+#define RGEPHY_SSR_JABBER 0x0001 /* Jabber */
#endif /* _DEV_MII_RGEPHYREG_H_ */
Index: src/sys/dev/pci/if_re_pci.c
diff -u src/sys/dev/pci/if_re_pci.c:1.21.2.5 src/sys/dev/pci/if_re_pci.c:1.21.2.6
--- src/sys/dev/pci/if_re_pci.c:1.21.2.5 Tue Mar 31 18:22:02 2009
+++ src/sys/dev/pci/if_re_pci.c Tue Aug 18 09:46:51 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: if_re_pci.c,v 1.21.2.5 2009/03/31 18:22:02 bouyer Exp $ */
+/* $NetBSD: if_re_pci.c,v 1.21.2.6 2009/08/18 09:46:51 bouyer Exp $ */
/*
* Copyright (c) 1997, 1998-2003
@@ -103,7 +103,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" },