diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c index 4a5b07c46f5e..e3bd5d463861 100644 --- a/sys/dev/mii/mii.c +++ b/sys/dev/mii/mii.c @@ -228,47 +228,30 @@ miibus_statchg(dev) return; } -void (*vlan_link_state_p)(struct ifnet *, int); /* XXX: private from if_vlan */ - static void miibus_linkchg(dev) - device_t dev; + device_t dev; { - struct mii_data *mii; - struct ifnet *ifp; - device_t parent; - int link, link_state; + struct mii_data *mii; + device_t parent; + int link_state; parent = device_get_parent(dev); MIIBUS_LINKCHG(parent); mii = device_get_softc(dev); + + if (mii->mii_media_status & IFM_AVALID) { + if (mii->mii_media_status & IFM_ACTIVE) + link_state = LINK_STATE_UP; + else + link_state = LINK_STATE_DOWN; + } else + link_state = LINK_STATE_UNKNOWN; /* * Note that each NIC's softc must start with an ifnet structure. */ - ifp = device_get_softc(parent); - - if (mii->mii_media_status & IFM_AVALID) { - if (mii->mii_media_status & IFM_ACTIVE) { - link = NOTE_LINKUP; - link_state = LINK_STATE_UP; - } else { - link = NOTE_LINKDOWN; - link_state = LINK_STATE_DOWN; - } - } else { - link = NOTE_LINKINV; - link_state = LINK_STATE_UNKNOWN; - } - - /* Notify that the link state has changed. */ - if (ifp->if_link_state != link_state) { - ifp->if_link_state = link_state; - rt_ifmsg(ifp); - KNOTE_UNLOCKED(&ifp->if_klist, link); - if (ifp->if_nvlans != 0) - (*vlan_link_state_p)(ifp, link); - } + if_link_state_change(device_get_softc(parent), link_state); } static void diff --git a/sys/net/if.c b/sys/net/if.c index b21701d8843a..3968345079b3 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -955,6 +955,32 @@ if_route(struct ifnet *ifp, int flag, int fam) #endif } +void (*vlan_link_state_p)(struct ifnet *, int); /* XXX: private from if_vlan */ + +/* + * Handle a change in the interface link state. + */ +void +if_link_state_change(struct ifnet *ifp, int link_state) +{ + int link; + + /* Notify that the link state has changed. */ + if (ifp->if_link_state != link_state) { + ifp->if_link_state = link_state; + rt_ifmsg(ifp); + if (link_state == LINK_STATE_UP) + link = NOTE_LINKUP; + else if (link_state == LINK_STATE_DOWN) + link = NOTE_LINKDOWN; + else + link = NOTE_LINKINV; + KNOTE_UNLOCKED(&ifp->if_klist, link); + if (ifp->if_nvlans != 0) + (*vlan_link_state_p)(ifp, link); + } +} + /* * Mark an interface down and notify protocols of * the transition. diff --git a/sys/net/if_var.h b/sys/net/if_var.h index f3517c63f054..ebbaa2506e34 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -629,6 +629,7 @@ int if_delmulti(struct ifnet *, struct sockaddr *); void if_detach(struct ifnet *); void if_down(struct ifnet *); void if_initname(struct ifnet *, const char *, int); +void if_link_state_change(struct ifnet *, int); int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); int if_setlladdr(struct ifnet *, const u_char *, int); void if_up(struct ifnet *);