diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-06-27 07:41:06 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-06-27 07:41:06 +0000 |
commit | 211ae1b3c47dec67932f325705c574baa5ab27d8 (patch) | |
tree | 64390812ec3439a0ec409fe5cdd521573ac4a8af | |
parent | e8094e39ba939051e1d6fa45f83253d9aa84628a (diff) |
- Make re_diag() off by default.
- Update comment to mention newer chip revisions.
From wpaul FreeBSD
-rw-r--r-- | sys/dev/ic/re.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c index 23bda1f56c5..15b525aadd7 100644 --- a/sys/dev/ic/re.c +++ b/sys/dev/ic/re.c @@ -1,4 +1,4 @@ -/* $OpenBSD: re.c,v 1.29 2006/06/27 05:53:37 brad Exp $ */ +/* $OpenBSD: re.c,v 1.30 2006/06/27 07:41:05 brad Exp $ */ /* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */ /* * Copyright (c) 1997, 1998-2003 @@ -43,8 +43,8 @@ /* * This driver is designed to support RealTek's next generation of * 10/100 and 10/100/1000 PCI ethernet controllers. There are currently - * four devices in this family: the RTL8139C+, the RTL8169, the RTL8169S - * and the RTL8110S. + * seven devices in this family: the RTL8139C+, the RTL8169, the RTL8169S, + * RTL8110S, the RTL8168, the RTL8111 and the RTL8101E. * * The 8139C+ is a 10/100 ethernet chip. It is backwards compatible * with the older 8139 family, however it also supports a special @@ -190,7 +190,9 @@ void re_miibus_statchg(struct device *); void re_setmulti(struct rl_softc *); void re_reset(struct rl_softc *); +#ifdef RE_DIAG int re_diag(struct rl_softc *); +#endif struct cfdriver re_cd = { 0, "re", DV_IFNET @@ -539,6 +541,8 @@ re_reset(struct rl_softc *sc) CSR_WRITE_1(sc, 0x82, 1); } +#ifdef RE_DIAG + /* * The following routine is designed to test for a defect on some * 32-bit 8169 cards. Some of these NICs have the REQ64# and ACK64# @@ -569,7 +573,7 @@ re_diag(struct rl_softc *sc) bus_dmamap_t dmamap; u_int16_t status; u_int32_t rxstat; - int total_len, i, s, error = 0; + int total_len, i, s, error = 0, phyaddr; u_int8_t dst[] = { 0x00, 'h', 'e', 'l', 'l', 'o' }; u_int8_t src[] = { 0x00, 'w', 'o', 'r', 'l', 'd' }; @@ -591,10 +595,28 @@ re_diag(struct rl_softc *sc) ifp->if_flags |= IFF_PROMISC; sc->rl_testmode = 1; + re_reset(sc); re_init(ifp); - re_stop(sc); + sc->rl_link = 1; + if (sc->rl_type == RL_8169) + phyaddr = 1; + else + phyaddr = 0; + + re_miibus_writereg((struct device *)sc, phyaddr, MII_BMCR, + BMCR_RESET); + for (i = 0; i < RL_TIMEOUT; i++) { + status = re_miibus_readreg((struct device *)sc, + phyaddr, MII_BMCR); + if (!(status & BMCR_RESET)) + break; + } + + re_miibus_writereg((struct device *)sc, phyaddr, MII_BMCR, + BMCR_LOOP); + CSR_WRITE_2(sc, RL_ISR, RL_INTRS); + DELAY(100000); - re_init(ifp); /* Put some data in the mbuf */ @@ -622,6 +644,7 @@ re_diag(struct rl_softc *sc) DELAY(100000); for (i = 0; i < RL_TIMEOUT; i++) { status = CSR_READ_2(sc, RL_ISR); + CSR_WRITE_2(sc, RL_ISR, status); if ((status & (RL_ISR_TIMEOUT_EXPIRED|RL_ISR_RX_OK)) == (RL_ISR_TIMEOUT_EXPIRED|RL_ISR_RX_OK)) break; @@ -692,6 +715,7 @@ done: /* Turn interface off, release resources */ sc->rl_testmode = 0; + sc->rl_link = 0; ifp->if_flags &= ~IFF_PROMISC; re_stop(sc); if (m0 != NULL) @@ -701,6 +725,8 @@ done: return (error); } +#endif + int re_allocmem(struct rl_softc *sc) { @@ -808,13 +834,12 @@ re_attach_common(struct rl_softc *sc) re_reset(sc); if (sc->rl_type == RL_8169) { - /* Set RX length mask */ - sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN; - /* Force station address autoload from the EEPROM */ + sc->rl_txstart = RL_GTXSTART; + /* Force station address autoload from the EEPROM */ CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_AUTOLOAD); for (i = 0; i < RL_TIMEOUT; i++) { if (!(CSR_READ_1(sc, RL_EECMD) & RL_EEMODE_AUTOLOAD)) @@ -827,11 +852,11 @@ re_attach_common(struct rl_softc *sc) for (i = 0; i < ETHER_ADDR_LEN; i++) eaddr[i] = CSR_READ_1(sc, RL_IDR0 + i); } else { - /* Set RX length mask */ - sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN; + sc->rl_txstart = RL_TXSTART; + sc->rl_eecmd_read = RL_EECMD_READ_6BIT; re_read_eeprom(sc, (caddr_t)&re_did, 0, 1, 0); if (re_did != 0x8129) @@ -912,15 +937,20 @@ re_attach_common(struct rl_softc *sc) if_attach(ifp); ether_ifattach(ifp); - /* Perform hardware diagnostic. */ +#ifdef RE_DIAG + /* + * Perform hardware diagnostic on the original RTL8169. + * Some 32-bit cards were incorrectly wired and would + * malfunction if plugged into a 64-bit slot. + */ error = re_diag(sc); - if (error) { printf("%s: attach aborted due to hardware diag failure\n", sc->sc_dev.dv_xname); ether_ifdetach(ifp); return; } +#endif DPRINTF(("leaving re_attach\n")); } @@ -1331,9 +1361,8 @@ re_intr(void *arg) /* If the card has gone away the read returns 0xffff. */ if (status == 0xffff) break; - if (status) { + if (status) CSR_WRITE_2(sc, RL_ISR, status); - } if ((status & RL_INTRS_CPLUS) == 0) break; @@ -1553,11 +1582,7 @@ re_start(struct ifnet *ifp) * RealTek put the TX poll request register in a different * location on the 8169 gigE chip. I don't know why. */ - - if (sc->rl_type == RL_8169) - CSR_WRITE_2(sc, RL_GTXSTART, RL_TXSTART_START); - else - CSR_WRITE_2(sc, RL_TXSTART, RL_TXSTART_START); + CSR_WRITE_2(sc, sc->rl_txstart, RL_TXSTART_START); /* * Use the countdown timer for interrupt moderation. @@ -1869,11 +1894,14 @@ re_stop(struct rl_softc *sc) ifp = &sc->sc_arpcom.ac_if; ifp->if_timer = 0; + sc->rl_link = 0; + timeout_del(&sc->timer_handle); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); CSR_WRITE_1(sc, RL_COMMAND, 0x00); CSR_WRITE_2(sc, RL_IMR, 0x0000); + CSR_WRITE_2(sc, RL_ISR, 0xFFFF); if (sc->rl_head != NULL) { m_freem(sc->rl_head); |