summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1998-09-09 19:23:35 +0000
committerJason Wright <jason@cvs.openbsd.org>1998-09-09 19:23:35 +0000
commitce18e094617392fd5341a872e281724ac82e5d3f (patch)
treea3f36ae0dca3be5b0ef24a0d60b6d1ad593434c2
parent4c3369f64fe36ebcfa9b4b88e0ba8f33e7619f21 (diff)
Better if_media support (actually works consistently now for non-autoneg)
-rw-r--r--sys/arch/sparc/dev/hme.c135
1 files changed, 50 insertions, 85 deletions
diff --git a/sys/arch/sparc/dev/hme.c b/sys/arch/sparc/dev/hme.c
index 939c000913b..5dbd3de4002 100644
--- a/sys/arch/sparc/dev/hme.c
+++ b/sys/arch/sparc/dev/hme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hme.c,v 1.6 1998/09/08 04:48:38 jason Exp $ */
+/* $OpenBSD: hme.c,v 1.7 1998/09/09 19:23:34 jason Exp $ */
/*
* Copyright (c) 1998 Jason L. Wright (jason@thought.net)
@@ -740,7 +740,7 @@ hme_tcvr_reset(sc)
sc->sc_sw.bmcr = result;
if (!(result & BMCR_RESET))
break;
- DELAY(200);
+ DELAY(20);
}
if (!tries) {
printf("%s: bmcr reset failed\n", sc->sc_dev.dv_xname);
@@ -762,7 +762,7 @@ hme_tcvr_reset(sc)
return -1;
if (!(result & BMCR_ISOLATE))
break;
- DELAY(200);
+ DELAY(20);
}
if (!tries) {
printf("%s: bmcr unisolate failed\n", sc->sc_dev.dv_xname);
@@ -841,7 +841,7 @@ hme_poll_stop(sc)
tcvr->int_mask = 0xffff;
tcvr->cfg &= ~(TCVR_CFG_PENABLE);
sc->sc_flags &= ~(HME_FLAG_POLL);
- DELAY(200);
+ DELAY(20);
}
#define XCVR_WRITE_TRIES 16
@@ -865,7 +865,7 @@ hme_tcvr_write(sc, reg, val)
(val & 0xffff);
while (!(tcvr->frame & 0x10000) && (tries != 0)) {
tries--;
- DELAY(200);
+ DELAY(20);
}
if (!tries)
@@ -896,7 +896,7 @@ hme_tcvr_read(sc, reg)
((reg & 0xff) << 18);
while (!(tcvr->frame & 0x10000) && (tries != 0)) {
tries--;
- DELAY(200);
+ DELAY(20);
}
if (!tries) {
@@ -1025,29 +1025,6 @@ hme_auto_negotiate(sc)
if (! (sc->sc_sw.bmsr & BMSR_ANC))
return;
- /* advertise -everything- supported */
- if (sc->sc_sw.bmsr & BMSR_10BASET_HALF)
- sc->sc_sw.anar |= ANAR_10;
- else
- sc->sc_sw.anar &= ~(ANAR_10);
-
- if (sc->sc_sw.bmsr & BMSR_10BASET_FULL)
- sc->sc_sw.anar |= ANAR_10_FD;
- else
- sc->sc_sw.anar &= ~(ANAR_10_FD);
-
- if (sc->sc_sw.bmsr & BMSR_100BASETX_HALF)
- sc->sc_sw.anar |= ANAR_TX;
- else
- sc->sc_sw.anar &= ~(ANAR_TX);
-
- if (sc->sc_sw.bmsr & BMSR_100BASETX_FULL)
- sc->sc_sw.anar |= ANAR_TX_FD;
- else
- sc->sc_sw.anar &= ~(ANAR_TX_FD);
-
- hme_tcvr_write(sc, DP83840_ANAR, sc->sc_sw.anar);
-
/* Start autonegoiation */
sc->sc_sw.bmcr |= BMCR_ANE; /* enable auto-neg */
hme_tcvr_write(sc, DP83840_BMCR, sc->sc_sw.bmcr);
@@ -1091,7 +1068,6 @@ hme_negotiate_watchdog(arg)
case HME_TIMER_DONE:
return;
case HME_TIMER_AUTONEG:
- printf("%s: tick: autoneg...\n", sc->sc_dev.dv_xname);
sc->sc_sw.bmsr = hme_tcvr_read(sc, DP83840_BMSR);
if (sc->sc_sw.bmsr & BMSR_ANCOMPLETE) {
sc->sc_an_state = HME_TIMER_LINKUP;
@@ -1102,12 +1078,12 @@ hme_negotiate_watchdog(arg)
if (sc->sc_an_ticks > 10) {
printf("%s: auto-negotiation failed.\n",
sc->sc_dev.dv_xname);
+ hme_auto_negotiate(sc);
return;
}
timeout(hme_negotiate_watchdog, sc, (12 * hz)/10);
break;
case HME_TIMER_LINKUP:
- printf("%s: tick: linkup..\n", sc->sc_dev.dv_xname);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_timer = 0;
@@ -1131,12 +1107,12 @@ static void
hme_print_link_mode(sc)
struct hme_softc *sc;
{
- sc->sc_sw.anlpar = hme_tcvr_read(sc, DP83840_ANLPAR);
+ sc->sc_sw.bmcr = hme_tcvr_read(sc, DP83840_BMCR);
printf("%s: %s transceiver up %dMb/s %s duplex\n",
sc->sc_dev.dv_xname,
(sc->sc_tcvr_type == HME_TCVR_EXTERNAL) ? "external" : "internal",
- (sc->sc_sw.anlpar & (ANLPAR_TX_FD | ANLPAR_TX)) ? 100 : 10,
- (sc->sc_sw.anlpar & (ANLPAR_TX_FD | ANLPAR_10_FD)) ? "full" : "half");
+ (sc->sc_sw.bmcr & BMCR_SPEED) ? 100 : 10,
+ (sc->sc_sw.bmcr & BMCR_DUPLEX) ? "full" : "half");
}
#define RESET_TRIES 32
@@ -1598,73 +1574,62 @@ hme_ifmedia_upd(ifp)
{
struct hme_softc *sc = ifp->if_softc;
struct ifmedia *ifm = &sc->sc_ifmedia;
- int tries, result;
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
return (EINVAL);
+ sc->sc_sw.bmsr = hme_tcvr_read(sc, DP83840_BMSR);
+
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO &&
sc->sc_sw.bmsr & BMSR_ANC) {
+
+ /* advertise -everything- supported */
+ if (sc->sc_sw.bmsr & BMSR_10BASET_HALF)
+ sc->sc_sw.anar |= ANAR_10;
+ else
+ sc->sc_sw.anar &= ~(ANAR_10);
+
+ if (sc->sc_sw.bmsr & BMSR_10BASET_FULL)
+ sc->sc_sw.anar |= ANAR_10_FD;
+ else
+ sc->sc_sw.anar &= ~(ANAR_10_FD);
+
+ if (sc->sc_sw.bmsr & BMSR_100BASETX_HALF)
+ sc->sc_sw.anar |= ANAR_TX;
+ else
+ sc->sc_sw.anar &= ~(ANAR_TX);
+
+ if (sc->sc_sw.bmsr & BMSR_100BASETX_FULL)
+ sc->sc_sw.anar |= ANAR_TX_FD;
+ else
+ sc->sc_sw.anar &= ~(ANAR_TX_FD);
+
+ hme_tcvr_write(sc, DP83840_ANAR, sc->sc_sw.anar);
hme_auto_negotiate(sc);
return (0);
}
if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
return (EINVAL);
- hme_tcvr_write(sc, DP83840_BMCR,
- (BMCR_LOOPBACK | BMCR_PDOWN | BMCR_ISOLATE));
- if (result == TCVR_FAILURE) {
- printf("%s: tcvr_reset failed\n", sc->sc_dev.dv_xname);
- return (EIO);
- }
- hme_tcvr_write(sc, DP83840_BMCR, BMCR_RESET);
-
- tries = 32;
- while (--tries) {
- result = hme_tcvr_read(sc, DP83840_BMCR);
- if (result == TCVR_FAILURE)
- return (EIO);
- sc->sc_sw.bmcr = result;
- if (!(result & BMCR_RESET))
- break;
- DELAY(200);
- }
- if (!tries) {
- printf("%s: bmcr reset failed\n", sc->sc_dev.dv_xname);
- return -1;
- }
-
- sc->sc_sw.bmcr = hme_tcvr_read(sc, DP83840_BMCR);
+ sc->sc_sw.anar = hme_tcvr_read(sc, DP83840_ANAR);
+ sc->sc_sw.anar &= ~(ANAR_T4 | ANAR_TX_FD | ANAR_TX
+ | ANAR_10_FD | ANAR_10);
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_T4) {
- sc->sc_sw.bmcr |= BMCR_SPEED;
- sc->sc_sw.bmcr &= ~BMCR_DUPLEX;
+ if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) {
+ if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
+ sc->sc_sw.anar |= ANAR_TX_FD;
+ else
+ sc->sc_sw.anar |= ANAR_TX;
}
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX)
- sc->sc_sw.bmcr |= BMCR_SPEED;
-
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T)
- sc->sc_sw.bmcr &= ~BMCR_SPEED;
-
- if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
- sc->sc_sw.bmcr |= BMCR_DUPLEX;
- else
- sc->sc_sw.bmcr &= ~BMCR_DUPLEX;
-
- sc->sc_sw.bmcr &= ~(BMCR_ISOLATE);
- hme_tcvr_write(sc, DP83840_BMCR, sc->sc_sw.bmcr);
- tries = 32;
- while (--tries) {
- sc->sc_sw.bmcr = hme_tcvr_read(sc, DP83840_BMCR);
- if ((sc->sc_sw.bmcr & BMCR_ISOLATE) == 0)
- break;
- DELAY(20);
- }
- if (!tries) {
- printf("%s: bmcr unisolate failed\n", sc->sc_dev.dv_xname);
- return (EIO);
+ if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10_T) {
+ if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
+ sc->sc_sw.anar |= ANAR_10_FD;
+ else
+ sc->sc_sw.anar |= ANAR_10;
}
+ hme_tcvr_write(sc, DP83840_ANAR, sc->sc_sw.anar);
+ hme_auto_negotiate(sc);
return (0);
}