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" },