summaryrefslogtreecommitdiff
path: root/sys/dev/le/lance.c
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2007-01-20 10:47:16 +0000
committerMarius Strobl <marius@FreeBSD.org>2007-01-20 10:47:16 +0000
commit17792f45fb0e6b12c8b95342d861fc41e317abc0 (patch)
tree8606f79689e4024c144fa70d49e3b09decc1d48d /sys/dev/le/lance.c
parentd2255d0286ce038f4fb5a85a06bd5a330a55eaad (diff)
Notes
Diffstat (limited to 'sys/dev/le/lance.c')
-rw-r--r--sys/dev/le/lance.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/sys/dev/le/lance.c b/sys/dev/le/lance.c
index 32576373571f..68673a9c5b01 100644
--- a/sys/dev/le/lance.c
+++ b/sys/dev/le/lance.c
@@ -299,6 +299,10 @@ lance_init_locked(struct lance_softc *sc)
/* Set the correct byte swapping mode, etc. */
(*sc->sc_wrcsr)(sc, LE_CSR3, sc->sc_conf3);
+ /* Set the current media. This may require the chip to be stopped. */
+ if (sc->sc_mediachange)
+ (void)(*sc->sc_mediachange)(sc);
+
/*
* Update our private copy of the Ethernet address.
* We NEED the copy so we can ensure its alignment!
@@ -322,10 +326,6 @@ lance_init_locked(struct lance_softc *sc)
if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON)
break;
- /* Set the current media. */
- if (sc->sc_mediachange)
- (void)(*sc->sc_mediachange)(sc);
-
if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) {
/* Start the LANCE. */
(*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT);
@@ -460,13 +460,21 @@ static int
lance_mediachange(struct ifnet *ifp)
{
struct lance_softc *sc = ifp->if_softc;
- int error;
if (sc->sc_mediachange) {
+ /*
+ * For setting the port in LE_CSR15 the PCnet chips must
+ * be powered down or stopped and unlike documented may
+ * not take effect without an initialization. So don't
+ * invoke (*sc_mediachange) directly here but go through
+ * lance_init_locked().
+ */
LE_LOCK(sc);
- error = (*sc->sc_mediachange)(sc);
+ lance_stop(sc);
+ lance_init_locked(sc);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ (*sc->sc_start_locked)(sc);
LE_UNLOCK(sc);
- return (error);
}
return (0);
}