diff options
author | andre <andre@FreeBSD.org> | 2004-05-03 13:48:35 +0000 |
---|---|---|
committer | andre <andre@FreeBSD.org> | 2004-05-03 13:48:35 +0000 |
commit | 25ae331e1251bd9562a10f53fdb2f054f7b21dfe (patch) | |
tree | 26d69d96320d4278394e06ff25df74de9314a2fc /sys/dev/mii/mii.c | |
parent | f8ee348f1d1b903d0b117c893b5f73aed4e5bce8 (diff) | |
download | FreeBSD-src-25ae331e1251bd9562a10f53fdb2f054f7b21dfe.zip FreeBSD-src-25ae331e1251bd9562a10f53fdb2f054f7b21dfe.tar.gz |
Link state change notification of ethernet media to the routing socket.
o Extend the if_data structure with an ifi_link_state field and
provide the corresponding defines for the valid states.
o The mii_linkchg() callback updates the ifi_link_state field
and calls rt_ifmsg() to notify listeners on the routing socket
in addition to the kqueue KNOTE.
o If vlans are configured on a physical interface notify and update
all vlan pseudo devices as well with the vlan_link_state() callback.
No objections by: sam, wpaul, ru, bms
Brucification by: bde
Diffstat (limited to 'sys/dev/mii/mii.c')
-rw-r--r-- | sys/dev/mii/mii.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c index 4771cc5..a22330b 100644 --- a/sys/dev/mii/mii.c +++ b/sys/dev/mii/mii.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <net/if_media.h> +#include <net/route.h> #include <dev/mii/mii.h> #include <dev/mii/miivar.h> @@ -230,6 +231,8 @@ 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; @@ -237,7 +240,7 @@ miibus_linkchg(dev) struct mii_data *mii; struct ifnet *ifp; device_t parent; - int link; + int link, link_state; parent = device_get_parent(dev); MIIBUS_LINKCHG(parent); @@ -249,15 +252,26 @@ miibus_linkchg(dev) ifp = device_get_softc(parent); if (mii->mii_media_status & IFM_AVALID) { - if (mii->mii_media_status & IFM_ACTIVE) + if (mii->mii_media_status & IFM_ACTIVE) { link = NOTE_LINKUP; - else + link_state = LINK_STATE_UP; + } else { link = NOTE_LINKDOWN; + link_state = LINK_STATE_DOWN; + } } else { link = NOTE_LINKINV; + link_state = LINK_STATE_UNKNOWN; } - KNOTE(&ifp->if_klist, link); + /* Notify that the link state has changed. */ + if (ifp->if_link_state != link_state) { + ifp->if_link_state = link_state; + rt_ifmsg(ifp); + KNOTE(&ifp->if_klist, link); + if (ifp->if_nvlans != 0) + (*vlan_link_state_p)(ifp, link); + } } static void |