diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index f16e517476f..d94a6884206 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -573,20 +573,8 @@ ed_init_locked(struct ed_softc *sc) */ ed_nic_outb(sc, ED_P0_TCR, 0); -#ifdef ED_3C503 - /* - * If this is a 3Com board, the tranceiver must be software enabled - * (there is no settable hardware default). - */ - if (sc->vendor == ED_VENDOR_3COM) { - if (ifp->if_flags & IFF_LINK2) - ed_asic_outb(sc, ED_3COM_CR, 0); - else - ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); - } -#endif if (sc->sc_mediachg) - sc->sc_mediachg(sc); + sc->sc_mediachg(sc); /* * Set 'running' flag, and clear output active flag. @@ -1227,12 +1215,15 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFFLAGS: /* * If the interface is marked up and stopped, then start it. + * If we're up and already running, then it may be a mediachg. * If it is marked down and running, then stop it. */ ED_LOCK(sc); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) ed_init_locked(sc); + else if (sc->sc_mediachg) + sc->sc_mediachg(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { ed_stop(sc); @@ -1245,23 +1236,6 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data) */ ed_setrcr(sc); -#ifdef ED_3C503 - /* - * An unfortunate hack to provide the (required) software - * control of the tranceiver for 3Com/HP boards. - * The LINK2 flag disables the tranceiver if set. - */ - if (sc->vendor == ED_VENDOR_3COM) { - if (ifp->if_flags & IFF_LINK2) - ed_asic_outb(sc, ED_3COM_CR, 0); - else - ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); - } -#endif -#ifdef ED_HPP - if (sc->vendor == ED_VENDOR_HP) - ed_hpp_set_physical_link(sc); -#endif ED_UNLOCK(sc); break; diff --git a/sys/dev/ed/if_ed_3c503.c b/sys/dev/ed/if_ed_3c503.c index c0fcd67f44b..55b7046a84f 100644 --- a/sys/dev/ed/if_ed_3c503.c +++ b/sys/dev/ed/if_ed_3c503.c @@ -60,6 +60,8 @@ __FBSDID("$FreeBSD$"); #include #include +static void ed_3c503_mediachg(struct ed_softc *sc); + /* * Probe and vendor-specific initialization routine for 3Com 3c503 boards */ @@ -335,7 +337,25 @@ ed_probe_3Com(device_t dev, int port_rid, int flags) ed_asic_outb(sc, ED_3COM_VPTR1, 0xff); ed_asic_outb(sc, ED_3COM_VPTR0, 0x00); - return (ed_clear_memory(dev)); + error = ed_clear_memory(dev); + if (error == 0) + sc->sc_mediachg = ed_3c503_mediachg; + return (error); +} + +static void +ed_3c503_mediachg(struct ed_softc *sc) +{ + struct ifnet *ifp = sc->ifp; + + /* + * If this is a 3Com board, the tranceiver must be software enabled + * (there is no settable hardware default). + */ + if (ifp->if_flags & IFF_LINK2) + ed_asic_outb(sc, ED_3COM_CR, 0); + else + ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); } #endif /* ED_3C503 */ diff --git a/sys/dev/ed/if_ed_hpp.c b/sys/dev/ed/if_ed_hpp.c index 2dac21d26f2..c54170502cb 100644 --- a/sys/dev/ed/if_ed_hpp.c +++ b/sys/dev/ed/if_ed_hpp.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); static void ed_hpp_writemem(struct ed_softc *, uint8_t *, uint16_t, uint16_t); +static void ed_hpp_set_physical_link(struct ed_softc *sc); /* * Interrupt conversion table for the HP PC LAN+ @@ -355,6 +356,7 @@ ed_probe_HP_pclanp(device_t dev, int port_rid, int flags) return (ENXIO); } + sc->sc_mediachg = ed_hpp_set_physical_link; return (0); } @@ -362,7 +364,7 @@ ed_probe_HP_pclanp(device_t dev, int port_rid, int flags) * HP PC Lan+ : Set the physical link to use AUI or TP/TL. */ -void +static void ed_hpp_set_physical_link(struct ed_softc *sc) { struct ifnet *ifp = sc->ifp; diff --git a/sys/dev/ed/if_edvar.h b/sys/dev/ed/if_edvar.h index 7f8f0868f40..66ca79b7dc5 100644 --- a/sys/dev/ed/if_edvar.h +++ b/sys/dev/ed/if_edvar.h @@ -220,7 +220,6 @@ void ed_pio_writemem(struct ed_softc *, uint8_t *, uint16_t, uint16_t); /* The following is unsatisfying XXX */ #ifdef ED_HPP -void ed_hpp_set_physical_link(struct ed_softc *); void ed_hpp_readmem(struct ed_softc *, bus_size_t, uint8_t *, uint16_t); u_short ed_hpp_write_mbufs(struct ed_softc *, struct mbuf *, int); #endif