tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

please test: ethernet media-handling patch



I have attached a patch that makes many ethernet drivers share the common
code for MII media handling, ether_mediastatus() and ether_mediachange(),
and which checks for a non-ENXIO error return from mii_mediachg().

I want everyone to have the opportunity to test this patch before I
commit it in about a week, because it affects more architectures than
I can feasibly compile and run.

The patch contains a few miscellaneous changes, too:

gem(4): use LIST_EMPTY(), LIST_FOREACH().
mtd(4): handle media ioctls, for a change!
axe(4): do not track link status in sc->axe_link any longer
nfe(4), aue(4), axe(4), udav(4), url(4): do not reset all PHYs
        on a change of media

I have compiled macppc, sparc64, and i386.  I am compiling for evbmips
(MERAKI), now.  I have run the patches on i386 boxen with bnx(4)
and sip(4).

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 278-3933 ext 24
Index: sys/arch/arm/ep93xx/epe.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/ep93xx/epe.c,v
retrieving revision 1.13
diff -p -u -u -p -r1.13 epe.c
--- sys/arch/arm/ep93xx/epe.c   17 Oct 2007 19:53:40 -0000      1.13
+++ sys/arch/arm/ep93xx/epe.c   2 Jan 2008 02:17:58 -0000
@@ -118,7 +118,6 @@ static void epe_init(struct epe_softc *)
 static int      epe_intr(void* arg);
 static int     epe_gctx(struct epe_softc *);
 static int     epe_mediachange(struct ifnet *);
-static void    epe_mediastatus(struct ifnet *, struct ifmediareq *);
 int            epe_mii_readreg (struct device *, int, int);
 void           epe_mii_writereg (struct device *, int, int, int);
 void           epe_statchg (struct device *);
@@ -428,8 +427,9 @@ epe_init(struct epe_softc *sc)
        sc->sc_mii.mii_readreg = epe_mii_readreg;
        sc->sc_mii.mii_writereg = epe_mii_writereg;
        sc->sc_mii.mii_statchg = epe_statchg;
+       sc->sc_ec.ec_mii = &sc->sc_mii;
        ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, epe_mediachange,
-               epe_mediastatus);
+               ether_mediastatus);
        mii_attach((struct device *)sc, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
                MII_OFFSET_ANY, 0);
        ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
@@ -474,19 +474,6 @@ epe_mediachange(ifp)
        return (0);
 }
 
-static void
-epe_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct epe_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-}
-
-
 int
 epe_mii_readreg(self, phy, reg)
        struct device *self;
@@ -728,15 +715,21 @@ epe_ifinit(ifp)
        struct ifnet *ifp;
 {
        struct epe_softc *sc = ifp->if_softc;
-       int s = splnet();
+       int rc, s = splnet();
 
        callout_stop(&sc->epe_tick_ch);
        EPE_WRITE(RXCtl, RXCtl_IA0|RXCtl_BA|RXCtl_RCRCA|RXCtl_SRxON);
        EPE_WRITE(TXCtl, TXCtl_STxON);
        EPE_WRITE(GIIntMsk, GIIntMsk_INT); /* start interrupting */
-       mii_mediachg(&sc->sc_mii);
+
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               rc = 0;
+       else if (rc != 0)
+               goto out;
+
        callout_reset(&sc->epe_tick_ch, hz, epe_tick, sc);
         ifp->if_flags |= IFF_RUNNING;
+out:
        splx(s);
        return 0;
 }
Index: sys/arch/arm/xscale/ixp425_if_npe.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/xscale/ixp425_if_npe.c,v
retrieving revision 1.5
diff -p -u -u -p -r1.5 ixp425_if_npe.c
--- sys/arch/arm/xscale/ixp425_if_npe.c 17 Oct 2007 19:53:43 -0000      1.5
+++ sys/arch/arm/xscale/ixp425_if_npe.c 2 Jan 2008 02:17:58 -0000
@@ -296,6 +296,7 @@ npe_attach(struct device *parent, struct
                sc->sc_mii.mii_readreg = npe_miibus_readreg;
                sc->sc_mii.mii_writereg = npe_miibus_writereg;
                sc->sc_mii.mii_statchg = npe_miibus_statchg;
+               sc->sc_ethercom.ec_mii = &sc->sc_mii;
 
                mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff,
                    (sc->sc_phy > IXPNPECF_PHY_DEFAULT) ?
@@ -660,9 +661,9 @@ npe_ifmedia_change(struct ifnet *ifp)
 {
        struct npe_softc *sc = ifp->if_softc;
 
-       if (sc->sc_phy > IXPNPECF_PHY_DEFAULT && ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
+       if (sc->sc_phy > IXPNPECF_PHY_DEFAULT)
+               return ether_mediachange(ifp);
+       return 0;
 }
 
 /*
Index: sys/arch/evbppc/virtex/dev/if_temac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/dev/if_temac.c,v
retrieving revision 1.2
diff -p -u -u -p -r1.2 if_temac.c
--- sys/arch/evbppc/virtex/dev/if_temac.c       4 Mar 2007 05:59:46 -0000       
1.2
+++ sys/arch/evbppc/virtex/dev/if_temac.c       2 Jan 2008 02:17:58 -0000
@@ -205,8 +205,6 @@ static void         temac_start(struct ifnet *)
 static void    temac_stop(struct ifnet *, int);
 
 /* Media management. */
-static int     temac_mediachange(struct ifnet *);
-static void    temac_mediastatus(struct ifnet *, struct ifmediareq *);
 static int     temac_mii_readreg(struct device *, int, int);
 static void    temac_mii_statchg(struct device *);
 static void    temac_mii_tick(void *);
@@ -500,8 +498,8 @@ temac_attach(struct device *parent, stru
        mii->mii_readreg = temac_mii_readreg;
        mii->mii_writereg = temac_mii_writereg;
        mii->mii_statchg = temac_mii_statchg;
-       ifmedia_init(&mii->mii_media, 0, temac_mediachange,
-           temac_mediastatus);
+       sc->sc_ec.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
 
        mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
@@ -593,7 +591,9 @@ temac_init(struct ifnet *ifp)
        cdmac_rx_reset(sc);
 
        /* Set current media. */
-       mii_mediachg(&sc->sc_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               return error;
+
        callout_schedule(&sc->sc_mii_tick, hz);
 
        /* Enable EMAC engine. */
@@ -839,30 +839,6 @@ temac_stop(struct ifnet *ifp, int disabl
        ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
 }
 
-/*
- * Media management.
- */
-static int
-temac_mediachange(struct ifnet *ifp)
-{
-       struct temac_softc      *sc = (struct temac_softc *)ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
-
-static void
-temac_mediastatus(struct ifnet *ifp, struct ifmediareq *imr)
-{
-       struct temac_softc      *sc = (struct temac_softc *)ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-
-       imr->ifm_status = sc->sc_mii.mii_media_status;
-       imr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
 static int
 temac_mii_readreg(struct device *self, int phy, int reg)
 {
Index: sys/arch/macppc/dev/if_bm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/if_bm.c,v
retrieving revision 1.35
diff -p -u -u -p -r1.35 if_bm.c
--- sys/arch/macppc/dev/if_bm.c 29 Dec 2007 23:12:38 -0000      1.35
+++ sys/arch/macppc/dev/if_bm.c 2 Jan 2008 02:17:59 -0000
@@ -115,8 +115,6 @@ int bmac_put(struct bmac_softc *, void *
 struct mbuf *bmac_get(struct bmac_softc *, void *, int);
 void bmac_watchdog(struct ifnet *);
 int bmac_ioctl(struct ifnet *, u_long, void *);
-int bmac_mediachange(struct ifnet *);
-void bmac_mediastatus(struct ifnet *, struct ifmediareq *);
 void bmac_setladrf(struct bmac_softc *);
 
 int bmac_mii_readreg(struct device *, int, int);
@@ -248,7 +246,8 @@ bmac_attach(struct device *parent, struc
        mii->mii_writereg = bmac_mii_writereg;
        mii->mii_statchg = bmac_mii_statchg;
 
-       ifmedia_init(&mii->mii_media, 0, bmac_mediachange, bmac_mediastatus);
+       sc->sc_ethercom.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
        mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
                      MII_OFFSET_ANY, 0);
 
@@ -524,7 +523,7 @@ next:
                cmd->d_resid = 0;
                sc->sc_rxlast = i + 1;
        }
-       bmac_mediachange(ifp);
+       ether_mediachange(ifp);
 
        dbdma_continue(sc->sc_rxdma);
 
@@ -809,28 +808,6 @@ bmac_ioctl(ifp, cmd, data)
        return error;
 }
 
-int
-bmac_mediachange(ifp)
-       struct ifnet *ifp;
-{
-       struct bmac_softc *sc = ifp->if_softc;
-
-       return mii_mediachg(&sc->sc_mii);
-}
-
-void
-bmac_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct bmac_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
 /*
  * Set up the logical address filter.
  */
Index: sys/arch/macppc/dev/if_gm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/if_gm.c,v
retrieving revision 1.32
diff -p -u -u -p -r1.32 if_gm.c
--- sys/arch/macppc/dev/if_gm.c 29 Dec 2007 23:14:06 -0000      1.32
+++ sys/arch/macppc/dev/if_gm.c 2 Jan 2008 02:17:59 -0000
@@ -123,8 +123,6 @@ void gmac_setladrf(struct gmac_softc *);
 int gmac_ioctl(struct ifnet *, u_long, void *);
 void gmac_watchdog(struct ifnet *);
 
-int gmac_mediachange(struct ifnet *);
-void gmac_mediastatus(struct ifnet *, struct ifmediareq *);
 int gmac_mii_readreg(struct device *, int, int);
 void gmac_mii_writereg(struct device *, int, int, int);
 void gmac_mii_statchg(struct device *);
@@ -246,7 +244,8 @@ gmac_attach(parent, self, aux)
        mii->mii_writereg = gmac_mii_writereg;
        mii->mii_statchg = gmac_mii_statchg;
 
-       ifmedia_init(&mii->mii_media, 0, gmac_mediachange, gmac_mediastatus);
+       sc->sc_ethercom.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
        mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
 
        /* Choose a default media. */
@@ -894,28 +893,6 @@ gmac_watchdog(ifp)
 }
 
 int
-gmac_mediachange(ifp)
-       struct ifnet *ifp;
-{
-       struct gmac_softc *sc = ifp->if_softc;
-
-       return mii_mediachg(&sc->sc_mii);
-}
-
-void
-gmac_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct gmac_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-int
 gmac_mii_readreg(dev, phy, reg)
        struct device *dev;
        int phy, reg;
Index: sys/arch/mips/alchemy/dev/if_aumac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/if_aumac.c,v
retrieving revision 1.23
diff -p -u -u -p -r1.23 if_aumac.c
--- sys/arch/mips/alchemy/dev/if_aumac.c        17 Oct 2007 19:55:35 -0000      
1.23
+++ sys/arch/mips/alchemy/dev/if_aumac.c        2 Jan 2008 02:17:59 -0000
@@ -202,9 +202,6 @@ static void aumac_mii_writereg(struct de
 static void    aumac_mii_statchg(struct device *);
 static int     aumac_mii_wait(struct aumac_softc *, const char *);
 
-static int     aumac_mediachange(struct ifnet *);
-static void    aumac_mediastatus(struct ifnet *, struct ifmediareq *);
-
 static int     aumac_match(struct device *, struct cfdata *, void *);
 static void    aumac_attach(struct device *, struct device *, void *);
 
@@ -326,8 +323,9 @@ aumac_attach(struct device *parent, stru
        sc->sc_mii.mii_readreg = aumac_mii_readreg;
        sc->sc_mii.mii_writereg = aumac_mii_writereg;
        sc->sc_mii.mii_statchg = aumac_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, 0, aumac_mediachange,
-           aumac_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
 
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
@@ -828,7 +826,8 @@ aumac_init(struct ifnet *ifp)
 #endif
 
        /* Set the media. */
-       aumac_mediachange(ifp);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Set the receive filter.  This will actually start the transmit
@@ -843,6 +842,7 @@ aumac_init(struct ifnet *ifp)
        ifp->if_flags |= IFF_RUNNING; 
        ifp->if_flags &= ~IFF_OACTIVE;
 
+out:
        if (error)
                printf("%s: interface not running\n", sc->sc_dev.dv_xname);
        return (error);
@@ -996,36 +996,6 @@ aumac_set_filter(struct aumac_softc *sc)
 }
 
 /*
- * aumac_mediastatus:  [ifmedia interface function]
- *
- *     Get the current interface media status.
- */
-static void
-aumac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct aumac_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
- * aumac_mediachange:  [ifmedia interface function]
- *
- *     Set hardware to newly selected media.
- */
-static int
-aumac_mediachange(struct ifnet *ifp)
-{
-       struct aumac_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
-
-/*
  * aumac_mii_wait:
  *
  *     Wait for the MII interface to not be busy.
Index: sys/arch/mips/atheros/dev/if_ae.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/atheros/dev/if_ae.c,v
retrieving revision 1.9
diff -p -u -u -p -r1.9 if_ae.c
--- sys/arch/mips/atheros/dev/if_ae.c   17 Oct 2007 19:55:35 -0000      1.9
+++ sys/arch/mips/atheros/dev/if_ae.c   2 Jan 2008 02:17:59 -0000
@@ -164,9 +164,6 @@ static int  ae_activate(struct device *, 
 static void    ae_reset(struct ae_softc *);
 static void    ae_idle(struct ae_softc *, u_int32_t);
 
-static int     ae_mediachange(struct ifnet *);
-static void    ae_mediastatus(struct ifnet *, struct ifmediareq *);
-
 static void    ae_start(struct ifnet *);
 static void    ae_watchdog(struct ifnet *);
 static int     ae_ioctl(struct ifnet *, u_long, void *);
@@ -362,8 +359,9 @@ ae_attach(struct device *parent, struct 
        sc->sc_mii.mii_readreg = ae_mii_readreg;
        sc->sc_mii.mii_writereg = ae_mii_writereg;
        sc->sc_mii.mii_statchg = ae_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, 0, ae_mediachange,
-           ae_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
 
@@ -1465,7 +1463,8 @@ ae_init(struct ifnet *ifp)
        /*
         * Set the current media.
         */
-       ae_mediachange(ifp);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Start the mac.
@@ -1848,48 +1847,6 @@ ae_idle(struct ae_softc *sc, u_int32_t b
 }
 
 /*****************************************************************************
- * Generic media support functions.
- *****************************************************************************/
-
-/*
- * ae_mediastatus:     [ifmedia interface function]
- *
- *     Query the current media.
- */
-void
-ae_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct ae_softc *sc = ifp->if_softc;
-
-       if (AE_IS_ENABLED(sc) == 0) {
-               ifmr->ifm_active = IFM_ETHER | IFM_NONE;
-               ifmr->ifm_status = 0;
-               return;
-       }
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
- * ae_mediachange:     [ifmedia interface function]
- *
- *     Update the current media.
- */
-int
-ae_mediachange(struct ifnet *ifp)
-{
-       struct ae_softc *sc = ifp->if_softc;
-
-       if ((ifp->if_flags & IFF_UP) == 0)
-               return (0);
-
-       mii_mediachg(&sc->sc_mii);
-       return (0);
-}
-
-/*****************************************************************************
  * Support functions for MII-attached media.
  *****************************************************************************/
 
Index: sys/arch/mips/sibyte/dev/sbmac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/sibyte/dev/sbmac.c,v
retrieving revision 1.26
diff -p -u -u -p -r1.26 sbmac.c
--- sys/arch/mips/sibyte/dev/sbmac.c    17 Oct 2007 19:55:40 -0000      1.26
+++ sys/arch/mips/sibyte/dev/sbmac.c    2 Jan 2008 02:17:59 -0000
@@ -257,8 +257,6 @@ static void sbmac_start(struct ifnet *if
 static void sbmac_setmulti(struct sbmac_softc *sc);
 static int sbmac_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data);
 static int sbmac_ioctl(struct ifnet *ifp, u_long command, void *data);
-static int sbmac_mediachange(struct ifnet *ifp);
-static void sbmac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr);
 static void sbmac_watchdog(struct ifnet *ifp);
 static int sbmac_match(struct device *parent, struct cfdata *match, void *aux);
 static void sbmac_attach(struct device *parent, struct device *self, void 
*aux);
@@ -2096,16 +2094,6 @@ sbmac_ioctl(struct ifnet *ifp, u_long co
  *     else error code
  */
 
-static int
-sbmac_mediachange(struct ifnet *ifp)
-{
-       struct sbmac_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return(0);
-}
-
 /*
  *  SBMAC_IFMEDIA_STS(ifp, ifmr)
  *
@@ -2119,16 +2107,6 @@ sbmac_mediachange(struct ifnet *ifp)
  *     nothing
  */
 
-static void
-sbmac_mediastatus(struct ifnet *ifp, struct ifmediareq *req)
-{
-       struct sbmac_softc      *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       req->ifm_status = sc->sc_mii.mii_media_status;
-       req->ifm_active = sc->sc_mii.mii_media_active;
-}
-
 /*
  *  SBMAC_WATCHDOG(ifp)
  *
@@ -2387,8 +2365,9 @@ sbmac_attach(struct device *parent, stru
        sc->sc_mii.mii_readreg  = sbmac_mii_readreg;
        sc->sc_mii.mii_writereg = sbmac_mii_writereg;
        sc->sc_mii.mii_statchg  = sbmac_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, 0, sbmac_mediachange,
-           sbmac_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
 
Index: sys/arch/playstation2/dev/emac3.c
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/dev/emac3.c,v
retrieving revision 1.5
diff -p -u -u -p -r1.5 emac3.c
--- sys/arch/playstation2/dev/emac3.c   15 Dec 2007 00:39:21 -0000      1.5
+++ sys/arch/playstation2/dev/emac3.c   2 Jan 2008 02:17:59 -0000
@@ -313,28 +313,6 @@ emac3_config(const u_int8_t *eaddr)
 /*
  * PHY/MII
  */
-int
-emac3_ifmedia_upd(struct ifnet *ifp)
-{
-       struct emac3_softc *sc;
-
-       sc = ifp->if_softc;
-
-       return (mii_mediachg(&sc->mii));
-}
-
-void
-emac3_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct emac3_softc *sc;
-
-       sc = ifp->if_softc;
-
-       mii_pollstat(&sc->mii);
-       ifmr->ifm_status = sc->mii.mii_media_status;
-       ifmr->ifm_active = sc->mii.mii_media_active;
-}
-
 void
 emac3_phy_writereg(struct device *self, int phy, int reg, int data)
 {
Index: sys/arch/playstation2/dev/emac3var.h
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/dev/emac3var.h,v
retrieving revision 1.1
diff -p -u -u -p -r1.1 emac3var.h
--- sys/arch/playstation2/dev/emac3var.h        16 Oct 2001 15:38:33 -0000      
1.1
+++ sys/arch/playstation2/dev/emac3var.h        2 Jan 2008 02:17:59 -0000
@@ -60,8 +60,6 @@ int emac3_tx_done(void);
 
 void emac3_setmulti(struct emac3_softc *, struct ethercom *);
 
-int emac3_ifmedia_upd(struct ifnet *);
-void emac3_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 int emac3_phy_readreg(struct device *, int, int);
 void emac3_phy_writereg(struct device *, int, int, int);
 void emac3_phy_statchg(struct device *);
Index: sys/arch/playstation2/dev/if_smap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/dev/if_smap.c,v
retrieving revision 1.10
diff -p -u -u -p -r1.10 if_smap.c
--- sys/arch/playstation2/dev/if_smap.c 15 Dec 2007 00:39:21 -0000      1.10
+++ sys/arch/playstation2/dev/if_smap.c 2 Jan 2008 02:17:59 -0000
@@ -250,7 +250,8 @@ smap_attach(struct device *parent, struc
        mii->mii_readreg        = emac3_phy_readreg;
        mii->mii_writereg       = emac3_phy_writereg;
        mii->mii_statchg        = emac3_phy_statchg;
-       ifmedia_init(&mii->mii_media, 0, emac3_ifmedia_upd, emac3_ifmedia_sts);
+       sc->ethercom.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
        mii_attach(&emac3->dev, mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
            
@@ -615,6 +616,7 @@ smap_init(struct ifnet *ifp)
 {
        struct smap_softc *sc = ifp->if_softc;
        u_int16_t r16;
+       int rc;
 
        smap_fifo_init(sc);
        emac3_reset(&sc->emac3);
@@ -636,7 +638,10 @@ smap_init(struct ifnet *ifp)
        emac3_setmulti(&sc->emac3, &sc->ethercom);
 
        /* Set current media. */
-       mii_mediachg(&sc->emac3.mii);
+       if ((rc = mii_mediachg(&sc->emac3.mii)) == ENXIO)
+               rc = 0;
+       else if (rc != 0)
+               return rc;
 
        ifp->if_flags |= IFF_RUNNING;
 
Index: sys/arch/powerpc/ibm4xx/dev/if_emac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/dev/if_emac.c,v
retrieving revision 1.30
diff -p -u -u -p -r1.30 if_emac.c
--- sys/arch/powerpc/ibm4xx/dev/if_emac.c       17 Oct 2007 19:56:39 -0000      
1.30
+++ sys/arch/powerpc/ibm4xx/dev/if_emac.c       2 Jan 2008 02:17:59 -0000
@@ -270,8 +270,6 @@ static int  emac_txde_intr(void *);
 static int     emac_rxde_intr(void *);
 static int     emac_intr(void *);
 
-static int     emac_mediachange(struct ifnet *);
-static void    emac_mediastatus(struct ifnet *, struct ifmediareq *);
 static int     emac_mii_readreg(struct device *, int, int);
 static void    emac_mii_statchg(struct device *);
 static void    emac_mii_tick(void *);
@@ -419,8 +417,8 @@ emac_attach(struct device *parent, struc
        mii->mii_writereg = emac_mii_writereg;
        mii->mii_statchg = emac_mii_statchg;
 
-       ifmedia_init(&mii->mii_media, 0, emac_mediachange,
-           emac_mediastatus);
+       sc->sc_ethercom.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
        mii_attach(&sc->sc_dev, mii, 0xffffffff,
            MII_PHY_ANY, MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&mii->mii_phys) == NULL) {
@@ -778,7 +776,8 @@ emac_init(struct ifnet *ifp)
        /*
         * Set the current media.
         */
-       mii_mediachg(&sc->sc_mii);
+       if ((error = emac_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Give the transmit and receive rings to the MAL.
@@ -1564,26 +1563,3 @@ emac_mii_tick(void *arg)
 
        callout_reset(&sc->sc_callout, hz, emac_mii_tick, sc);
 }
-
-/* ifmedia interface function */
-static void
-emac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct emac_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/* ifmedia interface function */
-static int
-emac_mediachange(struct ifnet *ifp)
-{
-       struct emac_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
Index: sys/arch/sgimips/mace/if_mec.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/mace/if_mec.c,v
retrieving revision 1.13
diff -p -u -u -p -r1.13 if_mec.c
--- sys/arch/sgimips/mace/if_mec.c      17 Oct 2007 19:57:05 -0000      1.13
+++ sys/arch/sgimips/mace/if_mec.c      2 Jan 2008 02:17:59 -0000
@@ -338,8 +338,6 @@ STATIC int  mec_mii_readreg(struct device
 STATIC void    mec_mii_writereg(struct device *, int, int, int);
 STATIC int     mec_mii_wait(struct mec_softc *);
 STATIC void    mec_statchg(struct device *);
-STATIC void    mec_mediastatus(struct ifnet *, struct ifmediareq *);
-STATIC int     mec_mediachange(struct ifnet *);
 
 static void    enaddr_aton(const char *, uint8_t *);
 
@@ -475,8 +473,9 @@ mec_attach(struct device *parent, struct
        sc->sc_mii.mii_statchg = mec_statchg;
 
        /* Set up PHY properties */
-       ifmedia_init(&sc->sc_mii.mii_media, 0, mec_mediachange,
-           mec_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
 
@@ -642,30 +641,6 @@ mec_statchg(struct device *self)
        bus_space_write_8(st, sh, MEC_MAC_CONTROL, control);
 }
 
-STATIC void
-mec_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct mec_softc *sc = ifp->if_softc;
-
-       if ((ifp->if_flags & IFF_UP) == 0)
-               return;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-STATIC int
-mec_mediachange(struct ifnet *ifp)
-{
-       struct mec_softc *sc = ifp->if_softc;
-
-       if ((ifp->if_flags & IFF_UP) == 0)
-               return 0;
-
-       return mii_mediachg(&sc->sc_mii);
-}
-
 /*
  * XXX
  * maybe this function should be moved to common part
@@ -703,7 +678,7 @@ mec_init(struct ifnet *ifp)
        bus_space_tag_t st = sc->sc_st;
        bus_space_handle_t sh = sc->sc_sh;
        struct mec_rxdesc *rxd;
-       int i;
+       int i, rc;
 
        /* cancel any pending I/O */
        mec_stop(ifp, 0);
@@ -747,12 +722,13 @@ mec_init(struct ifnet *ifp)
 
        callout_reset(&sc->sc_tick_ch, hz, mec_tick, sc);
 
+       if ((rc = ether_mediachange(ifp)) != 0)
+               return rc;
+
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
        mec_start(ifp);
 
-       mii_mediachg(&sc->sc_mii);
-
        return 0;
 }
 
Index: sys/dev/ic/aic6915.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/aic6915.c,v
retrieving revision 1.19
diff -p -u -u -p -r1.19 aic6915.c
--- sys/dev/ic/aic6915.c        19 Oct 2007 11:59:46 -0000      1.19
+++ sys/dev/ic/aic6915.c        2 Jan 2008 02:17:59 -0000
@@ -101,9 +101,6 @@ static void sf_mii_statchg(struct device
 
 static void    sf_tick(void *);
 
-static int     sf_mediachange(struct ifnet *);
-static void    sf_mediastatus(struct ifnet *, struct ifmediareq *);
-
 #define        sf_funcreg_read(sc, reg)                                        
\
        bus_space_read_4((sc)->sc_st, (sc)->sc_sh_func, (reg))
 #define        sf_funcreg_write(sc, reg, val)                                  
\
@@ -271,8 +268,9 @@ sf_attach(struct sf_softc *sc)
        sc->sc_mii.mii_readreg = sf_mii_read;
        sc->sc_mii.mii_writereg = sf_mii_write;
        sc->sc_mii.mii_statchg = sf_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, sf_mediachange,
-           sf_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -1088,7 +1086,8 @@ sf_init(struct ifnet *ifp)
        /*
         * Set the media.
         */
-       mii_mediachg(&sc->sc_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Initialize the interrupt register.
@@ -1443,33 +1442,3 @@ sf_mii_statchg(struct device *self)
 
        sf_genreg_write(sc, SF_BkToBkIPG, ipg);
 }
-
-/*
- * sf_mediastatus:     [ifmedia interface function]
- *
- *     Callback from ifmedia to request current media status.
- */
-static void
-sf_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct sf_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
- * sf_mediachange:     [ifmedia interface function]
- *
- *     Callback from ifmedia to request new media setting.
- */
-static int
-sf_mediachange(struct ifnet *ifp)
-{
-       struct sf_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
Index: sys/dev/ic/ax88190.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ax88190.c,v
retrieving revision 1.8
diff -p -u -u -p -r1.8 ax88190.c
--- sys/dev/ic/ax88190.c        19 Oct 2007 11:59:48 -0000      1.8
+++ sys/dev/ic/ax88190.c        2 Jan 2008 02:17:59 -0000
@@ -120,9 +120,11 @@ ax88190_media_fini(struct dp8390_softc *
 int
 ax88190_mediachange(struct dp8390_softc *sc)
 {
+       int rc;
 
-       mii_mediachg(&sc->sc_mii);
-       return (0);
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 void
Index: sys/dev/ic/dl10019.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/dl10019.c,v
retrieving revision 1.8
diff -p -u -u -p -r1.8 dl10019.c
--- sys/dev/ic/dl10019.c        19 Oct 2007 11:59:50 -0000      1.8
+++ sys/dev/ic/dl10019.c        2 Jan 2008 02:17:59 -0000
@@ -154,9 +154,11 @@ dl10019_media_fini(struct dp8390_softc *
 int
 dl10019_mediachange(struct dp8390_softc *sc)
 {
+       int rc;
 
-       mii_mediachg(&sc->sc_mii);
-       return (0);
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 void
Index: sys/dev/ic/gem.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/gem.c,v
retrieving revision 1.67
diff -p -u -u -p -r1.67 gem.c
--- sys/dev/ic/gem.c    31 Dec 2007 21:43:57 -0000      1.67
+++ sys/dev/ic/gem.c    2 Jan 2008 02:17:59 -0000
@@ -113,7 +113,6 @@ static void gem_mii_writereg(struct devi
 static void    gem_mii_statchg(struct device *);
 
 int            gem_mediachange(struct ifnet *);
-void           gem_mediastatus(struct ifnet *, struct ifmediareq *);
 
 struct mbuf    *gem_get(struct gem_softc *, int, int);
 int            gem_put(struct gem_softc *, int, struct mbuf *);
@@ -146,7 +145,6 @@ gem_attach(sc, enaddr)
 {
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
        struct mii_data *mii = &sc->sc_mii;
-       struct mii_softc *child;
        struct ifmedia_entry *ifm;
        int i, error;
        u_int32_t v;
@@ -297,7 +295,9 @@ gem_attach(sc, enaddr)
        mii->mii_writereg = gem_mii_writereg;
        mii->mii_statchg = gem_mii_statchg;
 
-       ifmedia_init(&mii->mii_media, IFM_IMASK, gem_mediachange, 
gem_mediastatus);
+       sc->sc_ethercom.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, IFM_IMASK, gem_mediachange,
+           ether_mediastatus);
 
        gem_mifinit(sc);
 
@@ -309,12 +309,13 @@ gem_attach(sc, enaddr)
                        MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG);
 #endif
 
-       child = LIST_FIRST(&mii->mii_phys);
-       if (child == NULL) {
+       if (LIST_EMPTY(&mii->mii_phys)) {
                /* No PHY attached */
                ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
                ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
        } else {
+               struct mii_softc *child;
+
                /*
                 * Walk along the list of attached MII devices and
                 * establish an `MII instance' to `phy number'
@@ -322,7 +323,7 @@ gem_attach(sc, enaddr)
                 * requests to determine which phy to use to program
                 * the MIF configuration register.
                 */
-               for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
+               LIST_FOREACH(child, &mii->mii_phys, mii_list) {
                        /*
                         * Note: we support just two PHYs: the built-in
                         * internal device and an external on the MII
@@ -794,7 +795,7 @@ gem_init(struct ifnet *ifp)
        struct gem_softc *sc = (struct gem_softc *)ifp->if_softc;
        bus_space_tag_t t = sc->sc_bustag;
        bus_space_handle_t h = sc->sc_h1;
-       int s;
+       int rc = 0, s;
        u_int max_frame_size;
        u_int32_t v;
 
@@ -892,7 +893,8 @@ gem_init(struct ifnet *ifp)
        bus_space_write_4(t, h, GEM_RX_BLANKING, (6<<12)|6);
 
        /* step 11. Configure Media */
-       mii_mediachg(&sc->sc_mii);
+       if ((rc = gem_mediachange(ifp)) != 0)
+               goto out;
 
 /* XXXX Serial link needs a whole different setup. */
 
@@ -919,6 +921,7 @@ gem_init(struct ifnet *ifp)
        ifp->if_flags &= ~IFF_OACTIVE;
        ifp->if_timer = 0;
        sc->sc_if_flags = ifp->if_flags;
+out:
        splx(s);
 
        return (0);
@@ -2014,26 +2017,14 @@ gem_mediachange(ifp)
        struct ifnet *ifp;
 {
        struct gem_softc *sc = ifp->if_softc;
+       int rc;
 
        if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_ETHER)
                return (EINVAL);
 
-       return (mii_mediachg(&sc->sc_mii));
-}
-
-void
-gem_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct gem_softc *sc = ifp->if_softc;
-
-       if ((ifp->if_flags & IFF_UP) == 0)
-               return;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 /*
Index: sys/dev/ic/hme.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/hme.c,v
retrieving revision 1.60
diff -p -u -u -p -r1.60 hme.c
--- sys/dev/ic/hme.c    19 Oct 2007 11:59:52 -0000      1.60
+++ sys/dev/ic/hme.c    2 Jan 2008 02:18:00 -0000
@@ -98,7 +98,7 @@ int           hme_ioctl(struct ifnet *, u_long, v
 void           hme_tick(void *);
 void           hme_watchdog(struct ifnet *);
 void           hme_shutdown(void *);
-void           hme_init(struct hme_softc *);
+int            hme_init(struct hme_softc *);
 void           hme_meminit(struct hme_softc *);
 void           hme_mifinit(struct hme_softc *);
 void           hme_reset(struct hme_softc *);
@@ -110,7 +110,6 @@ static void hme_mii_writereg(struct devi
 static void    hme_mii_statchg(struct device *);
 
 int            hme_mediachange(struct ifnet *);
-void           hme_mediastatus(struct ifnet *, struct ifmediareq *);
 
 struct mbuf    *hme_get(struct hme_softc *, int, uint32_t);
 int            hme_put(struct hme_softc *, int, struct mbuf *);
@@ -263,7 +262,8 @@ hme_config(sc)
        mii->mii_writereg = hme_mii_writereg;
        mii->mii_statchg = hme_mii_statchg;
 
-       ifmedia_init(&mii->mii_media, 0, hme_mediachange, hme_mediastatus);
+       sc->sc_ethercom.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, hme_mediachange, ether_mediastatus);
 
        hme_mifinit(sc);
 
@@ -348,7 +348,7 @@ hme_reset(sc)
        int s;
 
        s = splnet();
-       hme_init(sc);
+       (void)hme_init(sc);
        splx(s);
 }
 
@@ -462,7 +462,7 @@ hme_meminit(sc)
  * Initialization of interface; set up initialization block
  * and transmit/receive descriptor rings.
  */
-void
+int
 hme_init(sc)
        struct hme_softc *sc;
 {
@@ -474,6 +474,7 @@ hme_init(sc)
        bus_space_handle_t mac = sc->sc_mac;
        u_int8_t *ea;
        u_int32_t v;
+       int rc;
 
        /*
         * Initialization sequence. The numbered steps below correspond
@@ -634,7 +635,8 @@ hme_init(sc)
                (*sc->sc_hwinit)(sc);
 
        /* Set the current media. */
-       mii_mediachg(&sc->sc_mii);
+       if ((rc = hme_mediachange(ifp)) != 0)
+               return rc;
 
        /* Start the one second timer. */
        callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
@@ -644,6 +646,7 @@ hme_init(sc)
        sc->sc_if_flags = ifp->if_flags;
        ifp->if_timer = 0;
        hme_start(ifp);
+       return 0;
 }
 
 /*
@@ -1374,6 +1377,7 @@ hme_mediachange(ifp)
        bus_space_handle_t mac = sc->sc_mac;
        int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
        int phy = sc->sc_phys[instance];
+       int rc;
        u_int32_t v;
 
 #ifdef HMEDEBUG
@@ -1397,22 +1401,9 @@ hme_mediachange(ifp)
                v |= HME_MAC_XIF_MIIENABLE;
        bus_space_write_4(t, mac, HME_MACI_XIF, v);
 
-       return (mii_mediachg(&sc->sc_mii));
-}
-
-void
-hme_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct hme_softc *sc = ifp->if_softc;
-
-       if ((ifp->if_flags & IFF_UP) == 0)
-               return;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 /*
@@ -1441,14 +1432,14 @@ hme_ioctl(ifp, cmd, data)
                                hme_setladrf(sc);
                        else {
                                ifp->if_flags |= IFF_UP;
-                               hme_init(sc);
+                               error = hme_init(sc);
                        }
                        arp_ifinit(ifp, ifa);
                        break;
 #endif
                default:
                        ifp->if_flags |= IFF_UP;
-                       hme_init(sc);
+                       error = hme_init(sc);
                        break;
                }
                break;
@@ -1472,7 +1463,7 @@ hme_ioctl(ifp, cmd, data)
                         * If interface is marked up and it is stopped, then
                         * start it.
                         */
-                       hme_init(sc);
+                       error = hme_init(sc);
                } else if ((ifp->if_flags & IFF_UP) != 0) {
                        /*
                         * If setting debug or promiscuous mode, do not reset
@@ -1485,13 +1476,13 @@ hme_ioctl(ifp, cmd, data)
                                    == (sc->sc_if_flags & (~RESETIGN)))
                                        hme_setladrf(sc);
                                else
-                                       hme_init(sc);
+                                       error = hme_init(sc);
                        }
 #undef RESETIGN
                }
 
                if (sc->sc_ec_capenable != sc->sc_ethercom.ec_capenable)
-                       hme_init(sc);
+                       error = hme_init(sc);
 
                break;
 
Index: sys/dev/ic/i82557.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/i82557.c,v
retrieving revision 1.108
diff -p -u -u -p -r1.108 i82557.c
--- sys/dev/ic/i82557.c 17 Dec 2007 12:18:31 -0000      1.108
+++ sys/dev/ic/i82557.c 2 Jan 2008 02:18:00 -0000
@@ -175,7 +175,6 @@ const u_int8_t fxp_cb_config_template[] 
 };
 
 void   fxp_mii_initmedia(struct fxp_softc *);
-int    fxp_mii_mediachange(struct ifnet *);
 void   fxp_mii_mediastatus(struct ifnet *, struct ifmediareq *);
 
 void   fxp_80c24_initmedia(struct fxp_softc *);
@@ -478,7 +477,9 @@ fxp_mii_initmedia(struct fxp_softc *sc)
        sc->sc_mii.mii_readreg = fxp_mdi_read;
        sc->sc_mii.mii_writereg = fxp_mdi_write;
        sc->sc_mii.mii_statchg = fxp_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, fxp_mii_mediachange,
+
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
            fxp_mii_mediastatus);
 
        flags = MIIF_NOISOLATE;
@@ -1895,7 +1896,8 @@ fxp_init(struct ifnet *ifp)
                /*
                 * Set current media.
                 */
-               mii_mediachg(&sc->sc_mii);
+               if ((error = (*sc->sc_mii.mii_media.ifm_change)(ifp)) != 0)
+                       goto out;
        }
 
        /*
@@ -1935,19 +1937,6 @@ fxp_init(struct ifnet *ifp)
 }
 
 /*
- * Change media according to request.
- */
-int
-fxp_mii_mediachange(struct ifnet *ifp)
-{
-       struct fxp_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
-
-/*
  * Notify the world which media we're using.
  */
 void
@@ -1961,9 +1950,7 @@ fxp_mii_mediastatus(struct ifnet *ifp, s
                return;
        }
 
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
+       ether_mediastatus(ifp, ifmr);
 
        /*
         * XXX Flow control is always turned on if the chip supports
Index: sys/dev/ic/mtd803.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mtd803.c,v
retrieving revision 1.16
diff -p -u -u -p -r1.16 mtd803.c
--- sys/dev/ic/mtd803.c 5 Dec 2007 07:58:30 -0000       1.16
+++ sys/dev/ic/mtd803.c 2 Jan 2008 02:18:00 -0000
@@ -125,8 +125,6 @@ void mtd_stop(struct ifnet *, int);
 int mtd_ioctl(struct ifnet *, u_long, void *);
 void mtd_setmulti(struct mtd_softc *);
 void mtd_watchdog(struct ifnet *);
-int mtd_mediachange(struct ifnet *);
-void mtd_mediastatus(struct ifnet *, struct ifmediareq *);
 
 int mtd_init(struct ifnet *);
 void mtd_reset(struct mtd_softc *);
@@ -168,7 +166,9 @@ mtd_config(sc)
        sc->mii.mii_writereg = mtd_mii_writereg;
        sc->mii.mii_statchg = mtd_mii_statchg;
 
-       ifmedia_init(&sc->mii.mii_media, 0, mtd_mediachange, mtd_mediastatus);
+       sc->ethercom.ec_mii = &sc->mii;
+       ifmedia_init(&sc->mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
 
        mii_attach(&sc->dev, &sc->mii, 0xffffffff, MII_PHY_ANY, 0, 0);
 
@@ -601,7 +601,11 @@ mtd_ioctl(ifp, cmd, data)
                         error = 0;
                }
                break;
-
+       case SIOCSIFMEDIA:
+       case SIOCGIFMEDIA:
+               error = ifmedia_ioctl(ifp, (struct ifreq *)data,
+                   &sc->mii.mii_media, cmd);
+               break;
        default:
                error = ether_ioctl(ifp, cmd, data);
                break;
@@ -946,35 +950,6 @@ mtd_reset(sc)
 }
 
 
-int
-mtd_mediachange(ifp)
-       struct ifnet *ifp;
-{
-       struct mtd_softc *sc = ifp->if_softc;
-
-       if (IFM_TYPE(sc->mii.mii_media.ifm_media) != IFM_ETHER)
-               return EINVAL;
-
-       return mii_mediachg(&sc->mii);
-}
-
-
-void
-mtd_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct mtd_softc *sc = ifp->if_softc;
-
-       if ((ifp->if_flags & IFF_UP) == 0)
-               return;
-
-       mii_pollstat(&sc->mii);
-       ifmr->ifm_active = sc->mii.mii_media_active;
-       ifmr->ifm_status = sc->mii.mii_media_status;
-}
-
-
 void
 mtd_shutdown (arg)
        void *arg;
Index: sys/dev/ic/rtl8169.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl8169.c,v
retrieving revision 1.91
diff -p -u -u -p -r1.91 rtl8169.c
--- sys/dev/ic/rtl8169.c        11 Dec 2007 11:52:26 -0000      1.91
+++ sys/dev/ic/rtl8169.c        2 Jan 2008 02:18:00 -0000
@@ -166,9 +166,6 @@ static void re_watchdog(struct ifnet *);
 static int re_enable(struct rtk_softc *);
 static void re_disable(struct rtk_softc *);
 
-static int re_ifmedia_upd(struct ifnet *);
-static void re_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
 static int re_gmii_readreg(struct device *, int, int);
 static void re_gmii_writereg(struct device *, int, int, int);
 
@@ -781,8 +778,9 @@ re_attach(struct rtk_softc *sc)
        sc->mii.mii_readreg = re_miibus_readreg;
        sc->mii.mii_writereg = re_miibus_writereg;
        sc->mii.mii_statchg = re_miibus_statchg;
-       ifmedia_init(&sc->mii.mii_media, IFM_IMASK, re_ifmedia_upd,
-           re_ifmedia_sts);
+       sc->ethercom.ec_mii = &sc->mii;
+       ifmedia_init(&sc->mii.mii_media, IFM_IMASK, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        ifmedia_set(&sc->mii.mii_media, IFM_ETHER | IFM_AUTO);
@@ -1888,34 +1886,6 @@ re_init(struct ifnet *ifp)
        return error;
 }
 
-/*
- * Set media options.
- */
-static int
-re_ifmedia_upd(struct ifnet *ifp)
-{
-       struct rtk_softc        *sc;
-
-       sc = ifp->if_softc;
-
-       return mii_mediachg(&sc->mii);
-}
-
-/*
- * Report current media status.
- */
-static void
-re_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct rtk_softc        *sc;
-
-       sc = ifp->if_softc;
-
-       mii_pollstat(&sc->mii);
-       ifmr->ifm_active = sc->mii.mii_media_active;
-       ifmr->ifm_status = sc->mii.mii_media_status;
-}
-
 static int
 re_ioctl(struct ifnet *ifp, u_long command, void *data)
 {
Index: sys/dev/ic/rtl81x9.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rtl81x9.c,v
retrieving revision 1.79
diff -p -u -u -p -r1.79 rtl81x9.c
--- sys/dev/ic/rtl81x9.c        9 Dec 2007 20:27:59 -0000       1.79
+++ sys/dev/ic/rtl81x9.c        2 Jan 2008 02:18:00 -0000
@@ -140,8 +140,6 @@ STATIC int rtk_init(struct ifnet *);
 STATIC void rtk_stop(struct ifnet *, int);
 
 STATIC void rtk_watchdog(struct ifnet *);
-STATIC int rtk_ifmedia_upd(struct ifnet *);
-STATIC void rtk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
 STATIC void rtk_eeprom_putbyte(struct rtk_softc *, int, int);
 STATIC void rtk_mii_sync(struct rtk_softc *);
@@ -734,8 +732,9 @@ rtk_attach(struct rtk_softc *sc)
        sc->mii.mii_readreg = rtk_phy_readreg;
        sc->mii.mii_writereg = rtk_phy_writereg;
        sc->mii.mii_statchg = rtk_phy_statchg;
-       ifmedia_init(&sc->mii.mii_media, IFM_IMASK, rtk_ifmedia_upd,
-           rtk_ifmedia_sts);
+       sc->ethercom.ec_mii = &sc->mii;
+       ifmedia_init(&sc->mii.mii_media, IFM_IMASK, ether_mediachange,
+           ether_mediastatus);
        mii_attach(self, &sc->mii, 0xffffffff,
            MII_PHY_ANY, MII_OFFSET_ANY, 0);
 
@@ -1434,7 +1433,8 @@ rtk_init(struct ifnet *ifp)
        /*
         * Set current media.
         */
-       mii_mediachg(&sc->mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
@@ -1450,34 +1450,6 @@ rtk_init(struct ifnet *ifp)
        return error;
 }
 
-/*
- * Set media options.
- */
-STATIC int
-rtk_ifmedia_upd(struct ifnet *ifp)
-{
-       struct rtk_softc *sc;
-
-       sc = ifp->if_softc;
-
-       return mii_mediachg(&sc->mii);
-}
-
-/*
- * Report current media status.
- */
-STATIC void
-rtk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct rtk_softc *sc;
-
-       sc = ifp->if_softc;
-
-       mii_pollstat(&sc->mii);
-       ifmr->ifm_status = sc->mii.mii_media_status;
-       ifmr->ifm_active = sc->mii.mii_media_active;
-}
-
 STATIC int
 rtk_ioctl(struct ifnet *ifp, u_long command, void *data)
 {
Index: sys/dev/ic/smc83c170.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/smc83c170.c,v
retrieving revision 1.70
diff -p -u -u -p -r1.70 smc83c170.c
--- sys/dev/ic/smc83c170.c      30 Dec 2007 00:04:47 -0000      1.70
+++ sys/dev/ic/smc83c170.c      2 Jan 2008 02:18:00 -0000
@@ -99,7 +99,6 @@ void  epic_tick(void *);
 
 void   epic_statchg(struct device *);
 int    epic_mediachange(struct ifnet *);
-void   epic_mediastatus(struct ifnet *, struct ifmediareq *);
 
 #define        INTMASK (INTSTAT_FATAL_INT | INTSTAT_TXU | \
            INTSTAT_TXC | INTSTAT_RXE | INTSTAT_RQE | INTSTAT_RCC)
@@ -262,8 +261,10 @@ epic_attach(sc)
        sc->sc_mii.mii_readreg = epic_mii_read;
        sc->sc_mii.mii_writereg = epic_mii_write;
        sc->sc_mii.mii_statchg = epic_statchg;
+
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
        ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, epic_mediachange,
-           epic_mediastatus);
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, miiflags);
        if (LIST_EMPTY(&sc->sc_mii.mii_phys)) {
@@ -996,7 +997,8 @@ epic_init(ifp)
        bus_space_write_4(st, sh, EPIC_RXCON, reg0);
 
        /* Set the current media. */
-       epic_mediachange(ifp);
+       if ((error = epic_mediachange(ifp)) != 0)
+               goto out;
 
        /* Set up the multicast hash table. */
        epic_set_mchash(sc);
@@ -1460,21 +1462,6 @@ epic_statchg(self)
 }
 
 /*
- * Callback from ifmedia to request current media status.
- */
-void
-epic_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       struct epic_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
  * Callback from ifmedia to request new media setting.
  *
  * XXX Looks to me like some of this complexity should move into
@@ -1490,7 +1477,7 @@ epic_mediachange(ifp)
        int media = ifm->ifm_cur->ifm_media;
        uint32_t miicfg;
        struct mii_softc *miisc;
-       int cfg;
+       int cfg, rc;
 
        if ((ifp->if_flags & IFF_UP) == 0)
                return (0);
@@ -1505,7 +1492,8 @@ epic_mediachange(ifp)
                bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MIICFG, miicfg);
        }
 
-       mii_mediachg(mii);
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               rc = 0;
 
        if (IFM_INST(media) == sc->sc_serinst) {
                /* select serial interface */
@@ -1557,5 +1545,5 @@ epic_mediachange(ifp)
                PHY_WRITE(miisc, MII_LXTPHY_CONFIG, cfg);
        }
 
-       return (0);
+       return rc;
 }
Index: sys/dev/ic/smc91cxx.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/smc91cxx.c,v
retrieving revision 1.63
diff -p -u -u -p -r1.63 smc91cxx.c
--- sys/dev/ic/smc91cxx.c       19 Oct 2007 12:00:01 -0000      1.63
+++ sys/dev/ic/smc91cxx.c       2 Jan 2008 02:18:00 -0000
@@ -396,6 +396,7 @@ smc91cxx_set_media(sc, media)
        bus_space_tag_t bst = sc->sc_bst;
        bus_space_handle_t bsh = sc->sc_bsh;
        u_int16_t tmp;
+       int rc;
 
        /*
         * If the interface is not currently powered on, just return.
@@ -408,8 +409,9 @@ smc91cxx_set_media(sc, media)
        if (IFM_TYPE(media) != IFM_ETHER)
                return (EINVAL);
 
-       if (sc->sc_flags & SMC_FLAGS_HAS_MII)
-               return (mii_mediachg(&sc->sc_mii));
+       if ((sc->sc_flags & SMC_FLAGS_HAS_MII) == 0 ||
+           (rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               rc = 0;
 
        switch (IFM_SUBTYPE(media)) {
        case IFM_10_T:
@@ -428,7 +430,7 @@ smc91cxx_set_media(sc, media)
                return (EINVAL);
        }
 
-       return (0);
+       return rc;
 }
 
 /*
Index: sys/dev/ic/tulip.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/tulip.c,v
retrieving revision 1.154
diff -p -u -u -p -r1.154 tulip.c
--- sys/dev/ic/tulip.c  19 Oct 2007 12:00:03 -0000      1.154
+++ sys/dev/ic/tulip.c  2 Jan 2008 02:18:01 -0000
@@ -3394,22 +3394,24 @@ static int
 tlp_mii_setmedia(struct tulip_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       int rc;
 
-       if (ifp->if_flags & IFF_UP) {
-               switch (sc->sc_chip) {
-               case TULIP_CHIP_21142:
-               case TULIP_CHIP_21143:
-                       /* Disable the internal Nway engine. */
-                       TULIP_WRITE(sc, CSR_SIATXRX, 0);
-                       break;
+       if ((ifp->if_flags & IFF_UP) == 0)
+               return 0;
+       switch (sc->sc_chip) {
+       case TULIP_CHIP_21142:
+       case TULIP_CHIP_21143:
+               /* Disable the internal Nway engine. */
+               TULIP_WRITE(sc, CSR_SIATXRX, 0);
+               break;
 
-               default:
-                       /* Nothing. */
-                       break;
-               }
-               mii_mediachg(&sc->sc_mii);
+       default:
+               /* Nothing. */
+               break;
        }
-       return (0);
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 /*
Index: sys/dev/marvell/if_gfe.c
===================================================================
RCS file: /cvsroot/src/sys/dev/marvell/if_gfe.c,v
retrieving revision 1.26
diff -p -u -u -p -r1.26 if_gfe.c
--- sys/dev/marvell/if_gfe.c    19 Oct 2007 12:00:33 -0000      1.26
+++ sys/dev/marvell/if_gfe.c    2 Jan 2008 02:18:01 -0000
@@ -155,8 +155,6 @@ STATIC int gfe_ifioctl (struct ifnet *, 
 STATIC void gfe_ifstart (struct ifnet *);
 STATIC void gfe_ifwatchdog (struct ifnet *);
 
-STATIC int gfe_mii_mediachange (struct ifnet *);
-STATIC void gfe_mii_mediastatus (struct ifnet *, struct ifmediareq *);
 STATIC int gfe_mii_read (struct device *, int, int);
 STATIC void gfe_mii_write (struct device *, int, int, int);
 STATIC void gfe_mii_statchg (struct device *);
@@ -309,8 +307,9 @@ gfe_attach(struct device *parent, struct
        sc->sc_mii.mii_writereg = gfe_mii_write;
        sc->sc_mii.mii_statchg = gfe_mii_statchg;
 
-       ifmedia_init(&sc->sc_mii.mii_media, 0, gfe_mii_mediachange,
-               gfe_mii_mediastatus);
+       sc->sc_ec.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+               ether_mediastatus);
 
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, phyaddr,
                MII_OFFSET_ANY, MIIF_NOISOLATE);
@@ -1481,29 +1480,6 @@ gfe_intr(void *arg)
 }
 
 int
-gfe_mii_mediachange (struct ifnet *ifp)
-{
-       struct gfe_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-
-       return (0);
-}
-void
-gfe_mii_mediastatus (struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct gfe_softc *sc = ifp->if_softc;
-
-       if (sc->sc_flags & GE_PHYSTSCHG) {
-               sc->sc_flags &= ~GE_PHYSTSCHG;
-               mii_pollstat(&sc->sc_mii);
-       }
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-int
 gfe_mii_read (struct device *self, int phy, int reg)
 {
        return gt_mii_read(self, device_parent(self), phy, reg);
Index: sys/dev/pci/if_bce.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bce.c,v
retrieving revision 1.18
diff -p -u -u -p -r1.18 if_bce.c
--- sys/dev/pci/if_bce.c        11 Dec 2007 11:25:50 -0000      1.18
+++ sys/dev/pci/if_bce.c        2 Jan 2008 02:18:02 -0000
@@ -186,8 +186,6 @@ static      void    bce_set_filter(struct ifnet 
 static int     bce_mii_read(struct device *, int, int);
 static void    bce_mii_write(struct device *, int, int, int);
 static void    bce_statchg(struct device *);
-static int     bce_mediachange(struct ifnet *);
-static void    bce_mediastatus(struct ifnet *, struct ifmediareq *);
 static void    bce_tick(void *);
 
 #define BCE_DEBUG
@@ -470,8 +468,10 @@ bce_attach(struct device *parent, struct
        sc->bce_mii.mii_readreg = bce_mii_read;
        sc->bce_mii.mii_writereg = bce_mii_write;
        sc->bce_mii.mii_statchg = bce_statchg;
-       ifmedia_init(&sc->bce_mii.mii_media, 0, bce_mediachange,
-           bce_mediastatus);
+
+       sc->ethercom.ec_mii = &sc->bce_mii;
+       ifmedia_init(&sc->bce_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->bce_dev, &sc->bce_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&sc->bce_mii.mii_phys) == NULL) {
@@ -1033,7 +1033,8 @@ bce_init(struct ifnet *ifp)
            BCE_NRXDESC * sizeof(struct bce_dma_slot));
 
        /* set media */
-       mii_mediachg(&sc->bce_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               return error;
 
        /* turn on the ethernet mac */
        bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_ENET_CTL,
@@ -1494,28 +1495,6 @@ bce_statchg(struct device *self)
            bce_mii_read((struct device *) sc, 1, 27) | (1 << 6));      /* 
MAGIC */
 }
 
-/* Set hardware to newly-selected media */
-int
-bce_mediachange(struct ifnet *ifp)
-{
-       struct bce_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->bce_mii);
-       return (0);
-}
-
-/* Get the current interface media status */
-static void
-bce_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct bce_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->bce_mii);
-       ifmr->ifm_active = sc->bce_mii.mii_media_active;
-       ifmr->ifm_status = sc->bce_mii.mii_media_status;
-}
-
 /* One second timer, checks link status */
 static void
 bce_tick(void *v)
Index: sys/dev/pci/if_bge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.141
diff -p -u -u -p -r1.141 if_bge.c
--- sys/dev/pci/if_bge.c        9 Dec 2007 20:28:08 -0000       1.141
+++ sys/dev/pci/if_bge.c        2 Jan 2008 02:18:03 -0000
@@ -3269,7 +3269,6 @@ bge_tick(void *xsc)
 {
        struct bge_softc *sc = xsc;
        struct mii_data *mii = &sc->bge_mii;
-       struct ifmedia *ifm = NULL;
        struct ifnet *ifp = &sc->ethercom.ec_if;
        int s;
 
@@ -3283,7 +3282,6 @@ bge_tick(void *xsc)
        }
 
        if (sc->bge_tbi) {
-               ifm = &sc->bge_ifmedia;
                if (CSR_READ_4(sc, BGE_MAC_STS) &
                    BGE_MACSTAT_TBI_PCS_SYNCHED) {
                        sc->bge_link++;
@@ -3924,7 +3922,7 @@ bge_init(struct ifnet *ifp)
 {
        struct bge_softc *sc = ifp->if_softc;
        const u_int16_t *m;
-       int s, error;
+       int s, error = 0;
 
        s = splnet();
 
@@ -3997,16 +3995,18 @@ bge_init(struct ifnet *ifp)
        BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR);
        CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0);
 
-       bge_ifmedia_upd(ifp);
+       if ((error = bge_ifmedia_upd(ifp)) != 0)
+               goto out;
 
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       splx(s);
-
        callout_reset(&sc->bge_timeout, hz, bge_tick, sc);
 
-       return 0;
+out:
+       splx(s);
+
+       return error;
 }
 
 /*
@@ -4018,6 +4018,7 @@ bge_ifmedia_upd(struct ifnet *ifp)
        struct bge_softc *sc = ifp->if_softc;
        struct mii_data *mii = &sc->bge_mii;
        struct ifmedia *ifm = &sc->bge_ifmedia;
+       int rc;
 
        /* If this is a 1000baseX NIC, enable the TBI port. */
        if (sc->bge_tbi) {
@@ -4043,9 +4044,9 @@ bge_ifmedia_upd(struct ifnet *ifp)
        }
 
        sc->bge_link = 0;
-       mii_mediachg(mii);
-
-       return(0);
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 /*
Index: sys/dev/pci/if_msk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_msk.c,v
retrieving revision 1.14
diff -p -u -u -p -r1.14 if_msk.c
--- sys/dev/pci/if_msk.c        11 Dec 2007 11:25:51 -0000      1.14
+++ sys/dev/pci/if_msk.c        2 Jan 2008 02:18:03 -0000
@@ -116,8 +116,6 @@ int msk_init(struct ifnet *);
 void msk_init_yukon(struct sk_if_softc *);
 void msk_stop(struct ifnet *, int);
 void msk_watchdog(struct ifnet *);
-int msk_ifmedia_upd(struct ifnet *);
-void msk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 void msk_reset(struct sk_softc *);
 int msk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
 int msk_alloc_jumbo_mem(struct sk_if_softc *);
@@ -690,31 +688,6 @@ msk_jfree(struct mbuf *m, void *buf, siz
        splx(s);
 }
 
-/*
- * Set media options.
- */
-int
-msk_ifmedia_upd(struct ifnet *ifp)
-{
-       struct sk_if_softc *sc_if = ifp->if_softc;
-
-       mii_mediachg(&sc_if->sk_mii);
-       return (0);
-}
-
-/*
- * Report current media status.
- */
-void
-msk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct sk_if_softc *sc_if = ifp->if_softc;
-
-       mii_pollstat(&sc_if->sk_mii);
-       ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
-       ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
-}
-
 int
 msk_ioctl(struct ifnet *ifp, u_long command, void *data)
 {
@@ -1106,8 +1079,9 @@ msk_attach(struct device *parent, struct
        sc_if->sk_mii.mii_writereg = msk_miibus_writereg;
        sc_if->sk_mii.mii_statchg = msk_miibus_statchg;
 
+       sc_if->sk_ethercom.ec_mii = &sc_if->sk_mii;
        ifmedia_init(&sc_if->sk_mii.mii_media, 0,
-           msk_ifmedia_upd, msk_ifmedia_sts);
+           ether_mediachange, ether_mediastatus);
        mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, MIIF_DOPAUSE|MIIF_FORCEANEG);
        if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
@@ -2073,8 +2047,7 @@ msk_init(struct ifnet *ifp)
 {
        struct sk_if_softc      *sc_if = ifp->if_softc;
        struct sk_softc         *sc = sc_if->sk_softc;
-       struct mii_data         *mii = &sc_if->sk_mii;
-       int                     s;
+       int                     rc = 0, s;
        uint32_t                imr, imtimer_ticks;
 
 
@@ -2089,7 +2062,8 @@ msk_init(struct ifnet *ifp)
 
        /* Configure XMAC(s) */
        msk_init_yukon(sc_if);
-       mii_mediachg(mii);
+       if ((rc = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /* Configure transmit arbiter(s) */
        SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_ON);
@@ -2204,8 +2178,9 @@ msk_init(struct ifnet *ifp)
 
        callout_schedule(&sc_if->sk_tick_ch, hz);
 
+out:
        splx(s);
-       return 0;
+       return rc;
 }
 
 void
Index: sys/dev/pci/if_nfe.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_nfe.c,v
retrieving revision 1.25
diff -p -u -u -p -r1.25 if_nfe.c
--- sys/dev/pci/if_nfe.c        17 Dec 2007 12:41:06 -0000      1.25
+++ sys/dev/pci/if_nfe.c        2 Jan 2008 02:18:03 -0000
@@ -104,8 +104,6 @@ void        nfe_free_rx_ring(struct nfe_softc *
 int    nfe_alloc_tx_ring(struct nfe_softc *, struct nfe_tx_ring *);
 void   nfe_reset_tx_ring(struct nfe_softc *, struct nfe_tx_ring *);
 void   nfe_free_tx_ring(struct nfe_softc *, struct nfe_tx_ring *);
-int    nfe_ifmedia_upd(struct ifnet *);
-void   nfe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 void   nfe_setmulti(struct nfe_softc *);
 void   nfe_get_macaddr(struct nfe_softc *, uint8_t *);
 void   nfe_set_macaddr(struct nfe_softc *, const uint8_t *);
@@ -352,8 +350,9 @@ nfe_attach(struct device *parent, struct
        sc->sc_mii.mii_writereg = nfe_miibus_writereg;
        sc->sc_mii.mii_statchg = nfe_miibus_statchg;
 
-       ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd,
-           nfe_ifmedia_sts);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
        mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -1173,7 +1172,7 @@ nfe_init(struct ifnet *ifp)
 {
        struct nfe_softc *sc = ifp->if_softc;
        uint32_t tmp;
-       int s;
+       int rc = 0, s;
 
        if (ifp->if_flags & IFF_RUNNING)
                return 0;
@@ -1266,7 +1265,8 @@ nfe_init(struct ifnet *ifp)
        /* set Rx filter */
        nfe_setmulti(sc);
 
-       nfe_ifmedia_upd(ifp);
+       if ((rc = ether_mediachange(ifp)) != 0)
+               goto out;
 
        nfe_tick(sc);
 
@@ -1286,7 +1286,8 @@ nfe_init(struct ifnet *ifp)
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       return 0;
+out:
+       return rc;
 }
 
 void
@@ -1787,31 +1788,6 @@ nfe_free_tx_ring(struct nfe_softc *sc, s
        }
 }
 
-int
-nfe_ifmedia_upd(struct ifnet *ifp)
-{
-       struct nfe_softc *sc = ifp->if_softc;
-       struct mii_data *mii = &sc->sc_mii;
-       struct mii_softc *miisc;
-
-       if (mii->mii_instance != 0) {
-               LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
-                       mii_phy_reset(miisc);
-       }
-       return mii_mediachg(mii);
-}
-
-void
-nfe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct nfe_softc *sc = ifp->if_softc;
-       struct mii_data *mii = &sc->sc_mii;
-
-       mii_pollstat(mii);
-       ifmr->ifm_status = mii->mii_media_status;
-       ifmr->ifm_active = mii->mii_media_active;
-}
-
 void
 nfe_setmulti(struct nfe_softc *sc)
 {
Index: sys/dev/pci/if_pcn.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_pcn.c,v
retrieving revision 1.41
diff -p -u -u -p -r1.41 if_pcn.c
--- sys/dev/pci/if_pcn.c        19 Oct 2007 12:00:47 -0000      1.41
+++ sys/dev/pci/if_pcn.c        2 Jan 2008 02:18:03 -0000
@@ -422,8 +422,6 @@ static int  pcn_79c970_mediachange(struct
 static void    pcn_79c970_mediastatus(struct ifnet *, struct ifmediareq *);
 
 static void    pcn_79c971_mediainit(struct pcn_softc *);
-static int     pcn_79c971_mediachange(struct ifnet *);
-static void    pcn_79c971_mediastatus(struct ifnet *, struct ifmediareq *);
 
 /*
  * Description of a PCnet-PCI variant.  Used to select media access
@@ -1824,7 +1822,8 @@ pcn_init(struct ifnet *ifp)
        }
 
        /* Set the media. */
-       (void) (*sc->sc_mii.mii_media.ifm_change)(ifp);
+       if ((error = (*sc->sc_mii.mii_media.ifm_change)(ifp)) != 0)
+               goto out;
 
        /* Enable interrupts and external activity (and ACK IDON). */
        pcn_csr_write(sc, LE_CSR0, LE_C0_INEA|LE_C0_STRT|LE_C0_IDON);
@@ -2142,8 +2141,10 @@ pcn_79c971_mediainit(struct pcn_softc *s
        sc->sc_mii.mii_readreg = pcn_mii_readreg;
        sc->sc_mii.mii_writereg = pcn_mii_writereg;
        sc->sc_mii.mii_statchg = pcn_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, 0, pcn_79c971_mediachange,
-           pcn_79c971_mediastatus);
+
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
 
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
@@ -2155,36 +2156,6 @@ pcn_79c971_mediainit(struct pcn_softc *s
 }
 
 /*
- * pcn_79c971_mediastatus:     [ifmedia interface function]
- *
- *     Get the current interface media status (Am79c971 version).
- */
-static void
-pcn_79c971_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct pcn_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
- * pcn_79c971_mediachange:     [ifmedia interface function]
- *
- *     Set hardware to newly-selected media (Am79c971 version).
- */
-static int
-pcn_79c971_mediachange(struct ifnet *ifp)
-{
-       struct pcn_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
-
-/*
  * pcn_mii_readreg:    [mii interface function]
  *
  *     Read a PHY register on the MII.
Index: sys/dev/pci/if_sip.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_sip.c,v
retrieving revision 1.124
diff -p -u -u -p -r1.124 if_sip.c
--- sys/dev/pci/if_sip.c        16 Dec 2007 21:17:00 -0000      1.124
+++ sys/dev/pci/if_sip.c        2 Jan 2008 02:18:03 -0000
@@ -610,7 +610,6 @@ static int  sipcom_dp83815_mii_readreg(st
 static void    sipcom_dp83815_mii_writereg(struct device *, int, int, int);
 static void    sipcom_dp83815_mii_statchg(struct device *);
 
-static int     sipcom_mediachange(struct ifnet *);
 static void    sipcom_mediastatus(struct ifnet *, struct ifmediareq *);
 
 static int     sipcom_match(struct device *, struct cfdata *, void *);
@@ -1230,7 +1229,8 @@ sipcom_attach(device_t parent, device_t 
        sc->sc_mii.mii_readreg = sip->sip_variant->sipv_mii_readreg;
        sc->sc_mii.mii_writereg = sip->sip_variant->sipv_mii_writereg;
        sc->sc_mii.mii_statchg = sip->sip_variant->sipv_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, sipcom_mediachange,
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
            sipcom_mediastatus);
 
        /*
@@ -2781,7 +2781,8 @@ sipcom_init(struct ifnet *ifp)
         * IMR, since sip_mii_statchg() modifies the IMR for 802.3x flow
         * control.
         */
-       mii_mediachg(&sc->sc_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Set the interrupt hold-off timer to 100us.
@@ -3954,23 +3955,7 @@ sipcom_mediastatus(struct ifnet *ifp, st
 {
        struct sip_softc *sc = ifp->if_softc;
 
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = (sc->sc_mii.mii_media_active & ~IFM_ETH_FMASK) |
+       ether_mediastatus(ifp, ifmr);
+       ifmr->ifm_active = (ifmr->ifm_active & ~IFM_ETH_FMASK) |
                           sc->sc_flowflags;
 }
-
-/*
- * sip_mediachange:    [ifmedia interface function]
- *
- *     Set hardware to newly-selected media.
- */
-static int
-sipcom_mediachange(struct ifnet *ifp)
-{
-       struct sip_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
Index: sys/dev/pci/if_sk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_sk.c,v
retrieving revision 1.45
diff -p -u -u -p -r1.45 if_sk.c
--- sys/dev/pci/if_sk.c 11 Dec 2007 11:25:52 -0000      1.45
+++ sys/dev/pci/if_sk.c 2 Jan 2008 02:18:03 -0000
@@ -187,7 +187,6 @@ void sk_stop(struct ifnet *, int);
 void sk_watchdog(struct ifnet *);
 void sk_shutdown(void *);
 int sk_ifmedia_upd(struct ifnet *);
-void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 void sk_reset(struct sk_softc *);
 int sk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
 int sk_alloc_jumbo_mem(struct sk_if_softc *);
@@ -979,23 +978,12 @@ int
 sk_ifmedia_upd(struct ifnet *ifp)
 {
        struct sk_if_softc *sc_if = ifp->if_softc;
+       int rc;
 
        (void) sk_init(ifp);
-       mii_mediachg(&sc_if->sk_mii);
-       return 0;
-}
-
-/*
- * Report current media status.
- */
-void
-sk_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct sk_if_softc *sc_if = ifp->if_softc;
-
-       mii_pollstat(&sc_if->sk_mii);
-       ifmr->ifm_active = sc_if->sk_mii.mii_media_active;
-       ifmr->ifm_status = sc_if->sk_mii.mii_media_status;
+       if ((rc = mii_mediachg(&sc_if->sk_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 int
@@ -1447,11 +1435,12 @@ sk_attach(struct device *parent, struct 
                break;
        }
 
+       sc_if->sk_ethercom.ec_mii = &sc_if->sk_mii;
        ifmedia_init(&sc_if->sk_mii.mii_media, 0,
-           sk_ifmedia_upd, sk_ifmedia_sts);
+           sk_ifmedia_upd, ether_mediastatus);
        mii_attach(self, &sc_if->sk_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
-       if (LIST_FIRST(&sc_if->sk_mii.mii_phys) == NULL) {
+       if (LIST_EMPTY(&sc_if->sk_mii.mii_phys)) {
                aprint_error("%s: no PHY found!\n", sc_if->sk_dev.dv_xname);
                ifmedia_add(&sc_if->sk_mii.mii_media, IFM_ETHER|IFM_MANUAL,
                            0, NULL);
@@ -2255,7 +2244,7 @@ sk_intr_bcom(struct sk_if_softc *sc_if)
                    SK_PHYADDR_BCOM, BRGPHY_MII_AUXSTS);
 
                if (!(lstat & BRGPHY_AUXSTS_LINK) && sc_if->sk_link) {
-                       mii_mediachg(mii);
+                       (void)mii_mediachg(mii);
                        /* Turn off the link LED. */
                        SK_IF_WRITE_1(sc_if, 0,
                            SK_LINKLED1_CTL, SK_LINKLED_OFF);
@@ -2714,7 +2703,7 @@ sk_init(struct ifnet *ifp)
        struct sk_if_softc      *sc_if = ifp->if_softc;
        struct sk_softc         *sc = sc_if->sk_softc;
        struct mii_data         *mii = &sc_if->sk_mii;
-       int                     s;
+       int                     rc = 0, s;
        u_int32_t               imr, imtimer_ticks;
 
        DPRINTFN(1, ("sk_init\n"));
@@ -2757,7 +2746,10 @@ sk_init(struct ifnet *ifp)
                sk_init_yukon(sc_if);
                break;
        }
-       mii_mediachg(mii);
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               rc = 0;
+       else if (rc != 0)
+               goto out;
 
        if (sc->sk_type == SK_GENESIS) {
                /* Configure MAC FIFOs */
@@ -2872,8 +2864,9 @@ sk_init(struct ifnet *ifp)
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
+out:
        splx(s);
-       return 0;
+       return rc;
 }
 
 void
Index: sys/dev/pci/if_ste.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_ste.c,v
retrieving revision 1.31
diff -p -u -u -p -r1.31 if_ste.c
--- sys/dev/pci/if_ste.c        19 Oct 2007 12:00:48 -0000      1.31
+++ sys/dev/pci/if_ste.c        2 Jan 2008 02:18:04 -0000
@@ -232,9 +232,6 @@ static int  ste_mii_readreg(struct device
 static void    ste_mii_writereg(struct device *, int, int, int);
 static void    ste_mii_statchg(struct device *);
 
-static int     ste_mediachange(struct ifnet *);
-static void    ste_mediastatus(struct ifnet *, struct ifmediareq *);
-
 static int     ste_match(struct device *, struct cfdata *, void *);
 static void    ste_attach(struct device *, struct device *, void *);
 
@@ -474,8 +471,9 @@ ste_attach(struct device *parent, struct
        sc->sc_mii.mii_readreg = ste_mii_readreg;
        sc->sc_mii.mii_writereg = ste_mii_writereg;
        sc->sc_mii.mii_statchg = ste_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ste_mediachange,
-           ste_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -1339,7 +1337,8 @@ ste_init(struct ifnet *ifp)
        /*
         * Set the current media.
         */
-       mii_mediachg(&sc->sc_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Start the MAC.
@@ -1683,33 +1682,3 @@ ste_mii_bitbang_write(struct device *sel
 
        bus_space_write_1(sc->sc_st, sc->sc_sh, STE_PhyCtrl, val);
 }
-
-/*
- * ste_mediastatus:    [ifmedia interface function]
- *
- *     Get the current interface media status.
- */
-static void
-ste_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct ste_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
- * ste_mediachange:    [ifmedia interface function]
- *
- *     Set hardware to newly-selected media.
- */
-static int
-ste_mediachange(struct ifnet *ifp)
-{
-       struct ste_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
Index: sys/dev/pci/if_stge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_stge.c,v
retrieving revision 1.39
diff -p -u -u -p -r1.39 if_stge.c
--- sys/dev/pci/if_stge.c       19 Oct 2007 12:00:48 -0000      1.39
+++ sys/dev/pci/if_stge.c       2 Jan 2008 02:18:04 -0000
@@ -293,9 +293,6 @@ static int  stge_mii_readreg(struct devic
 static void    stge_mii_writereg(struct device *, int, int, int);
 static void    stge_mii_statchg(struct device *);
 
-static int     stge_mediachange(struct ifnet *);
-static void    stge_mediastatus(struct ifnet *, struct ifmediareq *);
-
 static int     stge_match(struct device *, struct cfdata *, void *);
 static void    stge_attach(struct device *, struct device *, void *);
 
@@ -596,8 +593,9 @@ stge_attach(struct device *parent, struc
        sc->sc_mii.mii_readreg = stge_mii_readreg;
        sc->sc_mii.mii_writereg = stge_mii_writereg;
        sc->sc_mii.mii_statchg = stge_mii_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, stge_mediachange,
-           stge_mediastatus);
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, MIIF_DOPAUSE);
        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -1658,7 +1656,8 @@ stge_init(struct ifnet *ifp)
        /*
         * Set the current media.
         */
-       mii_mediachg(&sc->sc_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /*
         * Start the one second MII clock.
@@ -2002,33 +2001,3 @@ stge_mii_bitbang_write(struct device *se
        bus_space_write_1(sc->sc_st, sc->sc_sh, STGE_PhyCtrl,
            val | sc->sc_PhyCtrl);
 }
-
-/*
- * stge_mediastatus:   [ifmedia interface function]
- *
- *     Get the current interface media status.
- */
-static void
-stge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct stge_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = sc->sc_mii.mii_media_active;
-}
-
-/*
- * stge_mediachange:   [ifmedia interface function]
- *
- *     Set hardware to newly-selected media.
- */
-static int
-stge_mediachange(struct ifnet *ifp)
-{
-       struct stge_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->sc_mii);
-       return (0);
-}
Index: sys/dev/pci/if_tl.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_tl.c,v
retrieving revision 1.84
diff -p -u -u -p -r1.84 if_tl.c
--- sys/dev/pci/if_tl.c 19 Oct 2007 12:00:48 -0000      1.84
+++ sys/dev/pci/if_tl.c 2 Jan 2008 02:18:04 -0000
@@ -124,7 +124,6 @@ static int tl_intr(void *);
 
 static int tl_ifioctl(struct ifnet *, ioctl_cmd_t, void *);
 static int tl_mediachange(struct ifnet *);
-static void tl_mediastatus(struct ifnet *, struct ifmediareq *);
 static void tl_ifwatchdog(struct ifnet *);
 static void tl_shutdown(void*);
 
@@ -453,8 +452,9 @@ tl_pci_attach(struct device *parent, str
        sc->tl_mii.mii_readreg = tl_mii_read;
        sc->tl_mii.mii_writereg = tl_mii_write;
        sc->tl_mii.mii_statchg = tl_statchg;
+       sc->tl_ec.ec_mii = &sc->tl_mii;
        ifmedia_init(&sc->tl_mii.mii_media, IFM_IMASK, tl_mediachange,
-           tl_mediastatus);
+           ether_mediastatus);
        mii_attach(self, &sc->tl_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&sc->tl_mii.mii_phys) == NULL) {
@@ -751,7 +751,12 @@ static int tl_init(ifp)
            BUS_DMASYNC_PREWRITE);
 
        /* set media */
-       mii_mediachg(&sc->tl_mii);
+       if ((error = mii_mediachg(&sc->tl_mii)) == ENXIO)
+               error = 0;
+       else if (error != 0) {
+               errstring = "could not set media";
+               goto bad; 
+       }
 
        /* start ticks calls */
        callout_reset(&sc->tl_tick_ch, hz, tl_ticks, sc);
@@ -1478,18 +1483,6 @@ tl_mediachange(ifp)
        return (0);
 }
 
-static void
-tl_mediastatus(ifp, ifmr)
-       struct ifnet *ifp;
-       struct ifmediareq *ifmr;
-{
-       tl_softc_t *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->tl_mii);
-       ifmr->ifm_active = sc->tl_mii.mii_media_active;
-       ifmr->ifm_status = sc->tl_mii.mii_media_status;
-}
-
 static int tl_add_RxBuff(sc, Rx, oldm)
        tl_softc_t *sc;
        struct Rx_list *Rx;
Index: sys/dev/pci/if_vge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_vge.c,v
retrieving revision 1.38
diff -p -u -u -p -r1.38 if_vge.c
--- sys/dev/pci/if_vge.c        19 Oct 2007 12:00:49 -0000      1.38
+++ sys/dev/pci/if_vge.c        2 Jan 2008 02:18:04 -0000
@@ -319,8 +319,6 @@ static int vge_suspend(struct device *);
 static int vge_resume(struct device *);
 #endif
 static void vge_shutdown(void *);
-static int vge_ifmedia_upd(struct ifnet *);
-static void vge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
 static uint16_t vge_read_eeprom(struct vge_softc *, int);
 
@@ -1053,8 +1051,10 @@ vge_attach(struct device *parent, struct
        sc->sc_mii.mii_readreg = vge_miibus_readreg;
        sc->sc_mii.mii_writereg = vge_miibus_writereg;
        sc->sc_mii.mii_statchg = vge_miibus_statchg;
-       ifmedia_init(&sc->sc_mii.mii_media, 0, vge_ifmedia_upd,
-           vge_ifmedia_sts);
+
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
+           ether_mediastatus);
        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, MIIF_DOPAUSE);
        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -1781,7 +1781,7 @@ static int
 vge_init(struct ifnet *ifp)
 {
        struct vge_softc *sc;
-       int i;
+       int i, rc = 0;
 
        sc = ifp->if_softc;
 
@@ -1950,7 +1950,8 @@ vge_init(struct ifnet *ifp)
                CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
        }
 
-       mii_mediachg(&sc->sc_mii);
+       if ((rc = ether_mediachange(ifp)) != 0)
+               goto out;
 
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
@@ -1960,38 +1961,8 @@ vge_init(struct ifnet *ifp)
 
        callout_schedule(&sc->sc_timeout, hz);
 
-       return 0;
-}
-
-/*
- * Set media options.
- */
-static int
-vge_ifmedia_upd(struct ifnet *ifp)
-{
-       struct vge_softc *sc;
-
-       sc = ifp->if_softc;
-       mii_mediachg(&sc->sc_mii);
-
-       return 0;
-}
-
-/*
- * Report current media status.
- */
-static void
-vge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct vge_softc *sc;
-       struct mii_data *mii;
-
-       sc = ifp->if_softc;
-       mii = &sc->sc_mii;
-
-       mii_pollstat(mii);
-       ifmr->ifm_active = mii->mii_media_active;
-       ifmr->ifm_status = mii->mii_media_status;
+out:
+       return rc;
 }
 
 static void
Index: sys/dev/pci/if_vr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.88
diff -p -u -u -p -r1.88 if_vr.c
--- sys/dev/pci/if_vr.c 19 Oct 2007 12:00:49 -0000      1.88
+++ sys/dev/pci/if_vr.c 2 Jan 2008 02:18:04 -0000
@@ -324,9 +324,6 @@ static void vr_rxdrain(struct vr_softc *
 static void    vr_watchdog(struct ifnet *);
 static void    vr_tick(void *);
 
-static int     vr_ifmedia_upd(struct ifnet *);
-static void    vr_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
 static int     vr_mii_readreg(struct device *, int, int);
 static void    vr_mii_writereg(struct device *, int, int, int);
 static void    vr_mii_statchg(struct device *);
@@ -1261,7 +1258,8 @@ vr_init(struct ifnet *ifp)
        CSR_WRITE_4(sc, VR_TXADDR, VR_CDTXADDR(sc, VR_NEXTTX(sc->vr_txlast)));
 
        /* Set current media. */
-       mii_mediachg(&sc->vr_mii);
+       if ((error = ether_mediachange(ifp)) != 0)
+               goto out;
 
        /* Enable receiver and transmitter. */
        CSR_WRITE_2(sc, VR_COMMAND, VR_CMD_TX_NOPOLL|VR_CMD_START|
@@ -1287,32 +1285,6 @@ vr_init(struct ifnet *ifp)
        return (error);
 }
 
-/*
- * Set media options.
- */
-static int
-vr_ifmedia_upd(struct ifnet *ifp)
-{
-       struct vr_softc *sc = ifp->if_softc;
-
-       if (ifp->if_flags & IFF_UP)
-               mii_mediachg(&sc->vr_mii);
-       return (0);
-}
-
-/*
- * Report current media status.
- */
-static void
-vr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct vr_softc *sc = ifp->if_softc;
-
-       mii_pollstat(&sc->vr_mii);
-       ifmr->ifm_status = sc->vr_mii.mii_media_status;
-       ifmr->ifm_active = sc->vr_mii.mii_media_active;
-}
-
 static int
 vr_ioctl(struct ifnet *ifp, u_long command, void *data)
 {
@@ -1738,8 +1710,10 @@ vr_attach(struct device *parent, struct 
        sc->vr_mii.mii_readreg = vr_mii_readreg;
        sc->vr_mii.mii_writereg = vr_mii_writereg;
        sc->vr_mii.mii_statchg = vr_mii_statchg;
-       ifmedia_init(&sc->vr_mii.mii_media, IFM_IMASK, vr_ifmedia_upd,
-               vr_ifmedia_sts);
+
+       sc->vr_ec.ec_mii = &sc->vr_mii;
+       ifmedia_init(&sc->vr_mii.mii_media, IFM_IMASK, ether_mediachange,
+               ether_mediastatus);
        mii_attach(&sc->vr_dev, &sc->vr_mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, MIIF_FORCEANEG);
        if (LIST_FIRST(&sc->vr_mii.mii_phys) == NULL) {
Index: sys/dev/pci/if_wm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_wm.c,v
retrieving revision 1.150
diff -p -u -u -p -r1.150 if_wm.c
--- sys/dev/pci/if_wm.c 14 Dec 2007 00:23:49 -0000      1.150
+++ sys/dev/pci/if_wm.c 2 Jan 2008 02:18:05 -0000
@@ -3225,7 +3225,8 @@ wm_init(struct ifnet *ifp)
        CSR_WRITE(sc, WMREG_TCTL, sc->sc_tctl);
 
        /* Set the media. */
-       (void) (*sc->sc_mii.mii_media.ifm_change)(ifp);
+       if ((error = (*sc->sc_mii.mii_media.ifm_change)(ifp)) != 0)
+               goto out;
 
        /*
         * Set up the receive control register; we actually program
@@ -4306,6 +4307,7 @@ wm_gmii_mediainit(struct wm_softc *sc)
 
        wm_gmii_reset(sc);
 
+       sc->sc_ethercom.ec_mii = &sc->sc_mii;
        ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, wm_gmii_mediachange,
            wm_gmii_mediastatus);
 
@@ -4328,9 +4330,8 @@ wm_gmii_mediastatus(struct ifnet *ifp, s
 {
        struct wm_softc *sc = ifp->if_softc;
 
-       mii_pollstat(&sc->sc_mii);
-       ifmr->ifm_status = sc->sc_mii.mii_media_status;
-       ifmr->ifm_active = (sc->sc_mii.mii_media_active & ~IFM_ETH_FMASK) |
+       ether_mediastatus(ifp, ifmr);
+       ifmr->ifm_active = (ifmr->ifm_active & ~IFM_ETH_FMASK) |
                           sc->sc_flowflags;
 }
 
@@ -4344,39 +4345,43 @@ wm_gmii_mediachange(struct ifnet *ifp)
 {
        struct wm_softc *sc = ifp->if_softc;
        struct ifmedia_entry *ife = sc->sc_mii.mii_media.ifm_cur;
+       int rc;
 
-       if (ifp->if_flags & IFF_UP) {
-               sc->sc_ctrl &= ~(CTRL_SPEED_MASK | CTRL_FD);
-               sc->sc_ctrl |= CTRL_SLU;
-               if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
-                   || (sc->sc_type > WM_T_82543)) {
-                       sc->sc_ctrl &= ~(CTRL_FRCSPD | CTRL_FRCFDX);
-               } else {
-                       sc->sc_ctrl &= ~CTRL_ASDE;
-                       sc->sc_ctrl |= CTRL_FRCSPD | CTRL_FRCFDX;
-                       if (ife->ifm_media & IFM_FDX)
-                               sc->sc_ctrl |= CTRL_FD;
-                       switch(IFM_SUBTYPE(ife->ifm_media)) {
-                       case IFM_10_T:
-                               sc->sc_ctrl |= CTRL_SPEED_10;
-                               break;
-                       case IFM_100_TX:
-                               sc->sc_ctrl |= CTRL_SPEED_100;
-                               break;
-                       case IFM_1000_T:
-                               sc->sc_ctrl |= CTRL_SPEED_1000;
-                               break;
-                       default:
-                               panic("wm_gmii_mediachange: bad media 0x%x",
-                                   ife->ifm_media);
-                       }
+       if ((ifp->if_flags & IFF_UP) == 0)
+               return 0;
+
+       sc->sc_ctrl &= ~(CTRL_SPEED_MASK | CTRL_FD);
+       sc->sc_ctrl |= CTRL_SLU;
+       if ((IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)
+           || (sc->sc_type > WM_T_82543)) {
+               sc->sc_ctrl &= ~(CTRL_FRCSPD | CTRL_FRCFDX);
+       } else {
+               sc->sc_ctrl &= ~CTRL_ASDE;
+               sc->sc_ctrl |= CTRL_FRCSPD | CTRL_FRCFDX;
+               if (ife->ifm_media & IFM_FDX)
+                       sc->sc_ctrl |= CTRL_FD;
+               switch(IFM_SUBTYPE(ife->ifm_media)) {
+               case IFM_10_T:
+                       sc->sc_ctrl |= CTRL_SPEED_10;
+                       break;
+               case IFM_100_TX:
+                       sc->sc_ctrl |= CTRL_SPEED_100;
+                       break;
+               case IFM_1000_T:
+                       sc->sc_ctrl |= CTRL_SPEED_1000;
+                       break;
+               default:
+                       panic("wm_gmii_mediachange: bad media 0x%x",
+                           ife->ifm_media);
                }
-               CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
-               if (sc->sc_type <= WM_T_82543)
-                       wm_gmii_reset(sc);
-               mii_mediachg(&sc->sc_mii);
        }
-       return (0);
+       CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
+       if (sc->sc_type <= WM_T_82543)
+               wm_gmii_reset(sc);
+
+       if ((rc = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 #define        MDI_IO          CTRL_SWDPIN(2)
Index: sys/dev/sbus/be.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sbus/be.c,v
retrieving revision 1.55
diff -p -u -u -p -r1.55 be.c
--- sys/dev/sbus/be.c   19 Oct 2007 12:01:10 -0000      1.55
+++ sys/dev/sbus/be.c   2 Jan 2008 02:18:05 -0000
@@ -1077,7 +1077,7 @@ beinit(sc)
        u_int32_t v;
        u_int32_t qecaddr;
        u_int8_t *ea;
-       int s;
+       int rc, s;
 
        s = splnet();
 
@@ -1159,11 +1159,14 @@ beinit(sc)
        v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE;
        bus_space_write_4(t, br, BE_BRI_RXCFG, v);
 
+       if ((rc = be_ifmedia_upd(ifp)) != 0)
+               goto out;
+
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       be_ifmedia_upd(ifp);
        callout_reset(&sc->sc_tick_ch, hz, be_tick, sc);
+out:
        splx(s);
 }
 
@@ -1509,8 +1512,10 @@ be_ifmedia_upd(ifp)
        struct be_softc *sc = ifp->if_softc;
        int error;
 
-       if ((error = mii_mediachg(&sc->sc_mii)) != 0)
-               return (error);
+       if ((error = mii_mediachg(&sc->sc_mii)) == ENXIO)
+               error = 0;
+       else if (error != 0)
+               return error;
 
        return (be_intphy_service(sc, &sc->sc_mii, MII_MEDIACHG));
 }
Index: sys/dev/usb/if_aue.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_aue.c,v
retrieving revision 1.106
diff -p -u -u -p -r1.106 if_aue.c
--- sys/dev/usb/if_aue.c        5 Dec 2007 07:15:54 -0000       1.106
+++ sys/dev/usb/if_aue.c        2 Jan 2008 02:18:05 -0000
@@ -254,7 +254,6 @@ Static void aue_stop(struct aue_softc *)
 Static void aue_watchdog(struct ifnet *);
 Static int aue_openpipes(struct aue_softc *);
 Static int aue_ifmedia_upd(struct ifnet *);
-Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
 Static int aue_eeprom_getword(struct aue_softc *, int);
 Static void aue_read_mac(struct aue_softc *, u_char *);
@@ -863,7 +862,8 @@ USB_ATTACH(aue)
        mii->mii_writereg = aue_miibus_writereg;
        mii->mii_statchg = aue_miibus_statchg;
        mii->mii_flags = MIIF_AUTOTSLEEP;
-       ifmedia_init(&mii->mii_media, 0, aue_ifmedia_upd, aue_ifmedia_sts);
+       sc->aue_ec.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, aue_ifmedia_upd, ether_mediastatus);
        mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&mii->mii_phys) == NULL) {
                ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
@@ -1540,6 +1540,7 @@ aue_ifmedia_upd(struct ifnet *ifp)
 {
        struct aue_softc        *sc = ifp->if_softc;
        struct mii_data         *mii = GET_MII(sc);
+       int rc;
 
        DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
 
@@ -1547,31 +1548,10 @@ aue_ifmedia_upd(struct ifnet *ifp)
                return (0);
 
        sc->aue_link = 0;
-       if (mii->mii_instance) {
-               struct mii_softc        *miisc;
-               for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
-                   miisc = LIST_NEXT(miisc, mii_list))
-                        mii_phy_reset(miisc);
-       }
-       mii_mediachg(mii);
-
-       return (0);
-}
 
-/*
- * Report current media status.
- */
-Static void
-aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-       struct aue_softc        *sc = ifp->if_softc;
-       struct mii_data         *mii = GET_MII(sc);
-
-       DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __func__));
-
-       mii_pollstat(mii);
-       ifmr->ifm_active = mii->mii_media_active;
-       ifmr->ifm_status = mii->mii_media_status;
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 Static int
Index: sys/dev/usb/if_axe.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_axe.c,v
retrieving revision 1.21
diff -p -u -u -p -r1.21 if_axe.c
--- sys/dev/usb/if_axe.c        5 Dec 2007 07:58:32 -0000       1.21
+++ sys/dev/usb/if_axe.c        2 Jan 2008 02:18:05 -0000
@@ -186,8 +186,6 @@ Static int axe_miibus_readreg(device_ptr
 Static void axe_miibus_writereg(device_ptr_t, int, int, int);
 Static void axe_miibus_statchg(device_ptr_t);
 Static int axe_cmd(struct axe_softc *, int, int, int, void *);
-Static int axe_ifmedia_upd(struct ifnet *);
-Static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 Static void axe_reset(struct axe_softc *sc);
 
 Static void axe_setmulti(struct axe_softc *);
@@ -328,40 +326,6 @@ axe_miibus_statchg(device_ptr_t dev)
        }
 }
 
-/*
- * Set media options.
- */
-Static int
-axe_ifmedia_upd(struct ifnet *ifp)
-{
-        struct axe_softc        *sc = ifp->if_softc;
-        struct mii_data         *mii = GET_MII(sc);
-
-        sc->axe_link = 0;
-        if (mii->mii_instance) {
-                struct mii_softc        *miisc;
-                LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
-                         mii_phy_reset(miisc);
-        }
-        mii_mediachg(mii);
-
-        return (0);
-}
-
-/*
- * Report current media status.
- */
-Static void
-axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-        struct axe_softc        *sc = ifp->if_softc;
-        struct mii_data         *mii = GET_MII(sc);
-
-        mii_pollstat(mii);
-        ifmr->ifm_active = mii->mii_media_active;
-        ifmr->ifm_status = mii->mii_media_status;
-}
-
 Static void
 axe_setmulti(struct axe_softc *sc)
 {
@@ -555,10 +519,11 @@ USB_ATTACH(axe)
        mii->mii_statchg = axe_miibus_statchg;
        mii->mii_flags = MIIF_AUTOTSLEEP;
 
-       ifmedia_init(&mii->mii_media, 0, axe_ifmedia_upd, axe_ifmedia_sts);
+       sc->axe_ec.ec_mii = mii;
+       ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
        mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
 
-       if (LIST_FIRST(&mii->mii_phys) == NULL) {
+       if (LIST_EMPTY(&mii->mii_phys)) {
                ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
                ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
        } else
@@ -988,17 +953,6 @@ axe_tick_task(void *xsc)
        s = splnet();
 
        mii_tick(mii);
-       if (!sc->axe_link) {
-               mii_pollstat(mii);
-               if (mii->mii_media_status & IFM_ACTIVE &&
-                   IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
-                       DPRINTF(("%s: %s: got link\n",
-                                USBDEVNAME(sc->axe_dev), __func__));
-                       sc->axe_link++;
-                       if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
-                                  axe_start(ifp);
-               }
-       }
 
        usb_callout(sc->axe_stat_ch, hz, axe_tick, sc);
 
@@ -1044,13 +998,8 @@ axe_start(struct ifnet *ifp)
 
        sc = ifp->if_softc;
 
-       if (!sc->axe_link) {
+       if ((ifp->if_flags & (IFF_OACTIVE|IFF_RUNNING)) != IFF_RUNNING)
                return;
-       }
-
-       if (ifp->if_flags & IFF_OACTIVE) {
-               return;
-       }
 
        IF_DEQUEUE(&ifp->if_snd, m_head);
        if (m_head == NULL) {
@@ -1394,7 +1343,6 @@ axe_stop(struct axe_softc *sc)
                }
        }
 
-       sc->axe_link = 0;
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 }
 
Index: sys/dev/usb/if_axereg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_axereg.h,v
retrieving revision 1.4
diff -p -u -u -p -r1.4 if_axereg.h
--- sys/dev/usb/if_axereg.h     5 Dec 2007 07:58:32 -0000       1.4
+++ sys/dev/usb/if_axereg.h     2 Jan 2008 02:18:05 -0000
@@ -195,7 +195,6 @@ struct axe_softc {
 
        kmutex_t                axe_mii_lock;
 
-       int                     axe_link;
        unsigned char           axe_ipgs[3];
        unsigned char           axe_phyaddrs[2];
        struct timeval          axe_rx_notice;
Index: sys/dev/usb/if_udav.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_udav.c,v
retrieving revision 1.20
diff -p -u -u -p -r1.20 if_udav.c
--- sys/dev/usb/if_udav.c       20 Dec 2007 21:08:20 -0000      1.20
+++ sys/dev/usb/if_udav.c       2 Jan 2008 02:18:07 -0000
@@ -281,6 +281,7 @@ USB_ATTACH(udav)
        mii->mii_writereg = udav_miibus_writereg;
        mii->mii_statchg = udav_miibus_statchg;
        mii->mii_flags = MIIF_AUTOTSLEEP;
+       sc->sc_ec.ec_mii = mii;
        ifmedia_init(&mii->mii_media, 0,
                     udav_ifmedia_change, udav_ifmedia_status);
        mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
@@ -615,7 +616,7 @@ udav_init(struct ifnet *ifp)
        struct udav_softc *sc = ifp->if_softc;
        struct mii_data *mii = GET_MII(sc);
        uint8_t eaddr[ETHER_ADDR_LEN];
-       int s;
+       int rc, s;
 
        DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
 
@@ -667,7 +668,10 @@ udav_init(struct ifnet *ifp)
        UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
        UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
 
-       mii_mediachg(mii);
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               rc = 0;
+       else if (rc != 0)
+               goto out;
 
        if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
                if (udav_openpipes(sc)) {
@@ -679,11 +683,11 @@ udav_init(struct ifnet *ifp)
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       splx(s);
-
        usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
 
-       return (0);
+out:
+       splx(s);
+       return rc;
 }
 
 Static void
@@ -1367,6 +1371,7 @@ udav_ifmedia_change(struct ifnet *ifp)
 {
        struct udav_softc *sc = ifp->if_softc;
        struct mii_data *mii = GET_MII(sc);
+       int rc;
 
        DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
 
@@ -1374,14 +1379,9 @@ udav_ifmedia_change(struct ifnet *ifp)
                return (0);
 
        sc->sc_link = 0;
-       if (mii->mii_instance) {
-               struct mii_softc *miisc;
-               for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
-                    miisc = LIST_NEXT(miisc, mii_list))
-                       mii_phy_reset(miisc);
-       }
-
-       return (mii_mediachg(mii));
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 /* Report current media status. */
@@ -1389,22 +1389,13 @@ Static void
 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
        struct udav_softc *sc = ifp->if_softc;
-       struct mii_data *mii = GET_MII(sc);
 
        DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
 
        if (sc->sc_dying)
                return;
 
-       if ((ifp->if_flags & IFF_RUNNING) == 0) {
-               ifmr->ifm_active = IFM_ETHER | IFM_NONE;
-               ifmr->ifm_status = 0;
-               return;
-       }
-
-       mii_pollstat(mii);
-       ifmr->ifm_active = mii->mii_media_active;
-       ifmr->ifm_status = mii->mii_media_status;
+       ether_mediastatus(ifp, ifmr);
 }
 
 Static void
Index: sys/dev/usb/if_url.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/if_url.c,v
retrieving revision 1.29
diff -p -u -u -p -r1.29 if_url.c
--- sys/dev/usb/if_url.c        29 Aug 2007 22:33:44 -0000      1.29
+++ sys/dev/usb/if_url.c        2 Jan 2008 02:18:07 -0000
@@ -291,6 +291,7 @@ USB_ATTACH(url)
 #endif
        mii->mii_statchg = url_miibus_statchg;
        mii->mii_flags = MIIF_AUTOTSLEEP;
+       sc->sc_ec.ec_mii = mii;
        ifmedia_init(&mii->mii_media, 0,
                     url_ifmedia_change, url_ifmedia_status);
        mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
@@ -506,7 +507,7 @@ url_init(struct ifnet *ifp)
        struct url_softc *sc = ifp->if_softc;
        struct mii_data *mii = GET_MII(sc);
        const u_char *eaddr;
-       int i, s;
+       int i, rc, s;
 
        DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
 
@@ -562,7 +563,10 @@ url_init(struct ifnet *ifp)
        /* Enable RX and TX */
        URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE);
 
-       mii_mediachg(mii);
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               rc = 0;
+       else if (rc != 0)
+               goto out;
 
        if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
                if (url_openpipes(sc)) {
@@ -574,11 +578,11 @@ url_init(struct ifnet *ifp)
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
 
-       splx(s);
-
        usb_callout(sc->sc_stat_ch, hz, url_tick, sc);
 
-       return (0);
+out:
+       splx(s);
+       return rc;
 }
 
 Static void
@@ -1250,6 +1254,7 @@ url_ifmedia_change(struct ifnet *ifp)
 {
        struct url_softc *sc = ifp->if_softc;
        struct mii_data *mii = GET_MII(sc);
+       int rc;
 
        DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
 
@@ -1257,14 +1262,9 @@ url_ifmedia_change(struct ifnet *ifp)
                return (0);
 
        sc->sc_link = 0;
-       if (mii->mii_instance) {
-               struct mii_softc *miisc;
-               for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
-                    miisc = LIST_NEXT(miisc, mii_list))
-                       mii_phy_reset(miisc);
-       }
-
-       return (mii_mediachg(mii));
+       if ((rc = mii_mediachg(mii)) == ENXIO)
+               return 0;
+       return rc;
 }
 
 /* Report current media status. */
@@ -1272,22 +1272,13 @@ Static void
 url_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
        struct url_softc *sc = ifp->if_softc;
-       struct mii_data *mii = GET_MII(sc);
 
        DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
 
        if (sc->sc_dying)
                return;
 
-       if ((ifp->if_flags & IFF_RUNNING) == 0) {
-               ifmr->ifm_active = IFM_ETHER | IFM_NONE;
-               ifmr->ifm_status = 0;
-               return;
-       }
-
-       mii_pollstat(mii);
-       ifmr->ifm_active = mii->mii_media_active;
-       ifmr->ifm_status = mii->mii_media_status;
+       ether_mediastatus(ifp, ifmr);
 }
 
 Static void


Home | Main Index | Thread Index | Old Index