From efd19b8fd01ab0d5b10c78c8eddbd9bed512b11f Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 14 Feb 2006 12:10:03 +0000 Subject: [PATCH] - Introduce ifmedia_baudrate(), which returns correct baudrate of the given media status. [1] - Utilize ifmedia_baudrate() in miibus_statchg() to update ifp->if_baudrate. Obtained from: NetBSD [1] --- sys/dev/mii/mii.c | 11 ++++++++ sys/net/if_media.c | 22 ++++++++++++++++ sys/net/if_media.h | 62 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c index c640e1358eba..25110687b6c2 100644 --- a/sys/dev/mii/mii.c +++ b/sys/dev/mii/mii.c @@ -240,9 +240,20 @@ static void miibus_statchg(device_t dev) { device_t parent; + struct mii_data *mii; + struct ifnet *ifp; parent = device_get_parent(dev); MIIBUS_STATCHG(parent); + + mii = device_get_softc(dev); + + /* + * Note that each NIC's softc must start with an ifnet pointer. + * XXX: EVIL HACK! + */ + ifp = *(struct ifnet **)device_get_softc(parent); + ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active); return; } diff --git a/sys/net/if_media.c b/sys/net/if_media.c index bc49dccdbe08..392813665d35 100644 --- a/sys/net/if_media.c +++ b/sys/net/if_media.c @@ -385,6 +385,28 @@ ifmedia_match(ifm, target, mask) return match; } +/* + * Compute the interface `baudrate' from the media, for the interface + * metrics (used by routing daemons). + */ +static const struct ifmedia_baudrate ifmedia_baudrate_descriptions[] = + IFM_BAUDRATE_DESCRIPTIONS; + +uint64_t +ifmedia_baudrate(int mword) +{ + int i; + + for (i = 0; ifmedia_baudrate_descriptions[i].ifmb_word != 0; i++) { + if ((mword & (IFM_NMASK|IFM_TMASK)) == + ifmedia_baudrate_descriptions[i].ifmb_word) + return (ifmedia_baudrate_descriptions[i].ifmb_baudrate); + } + + /* Not known. */ + return (0); +} + #ifdef IFMEDIA_DEBUG struct ifmedia_description ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS; diff --git a/sys/net/if_media.h b/sys/net/if_media.h index 4f7389b3db9b..848165dc8ec6 100644 --- a/sys/net/if_media.h +++ b/sys/net/if_media.h @@ -104,6 +104,9 @@ void ifmedia_set(struct ifmedia *ifm, int mword); int ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm, u_long cmd); +/* Compute baudrate for a given media. */ +uint64_t ifmedia_baudrate(int); + #endif /*_KERNEL */ /* @@ -138,8 +141,8 @@ int ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, #define IFM_1000_CX 15 /* 1000baseCX - 150ohm STP */ #define IFM_1000_T 16 /* 1000baseT - 4 pair cat 5 */ #define IFM_HPNA_1 17 /* HomePNA 1.0 (1Mb/s) */ -#define IFM_10GBASE_SR 18 /* 10GBASE-SR 850nm Multi-mode Fiber */ -#define IFM_10GBASE_LR 19 /* 10GBASE-LR 1310nm Single-mode Fiber */ +#define IFM_10G_LR 18 /* 10GBase-LR 1310nm Single-mode */ +#define IFM_10G_SR 19 /* 10GBase-SR 850nm Multi-mode */ /* note 31 is the max! */ @@ -543,4 +546,59 @@ struct ifmedia_description { { 0, NULL }, \ } +/* + * Baudrate descriptions for the various media types. + */ +struct ifmedia_baudrate { + int ifmb_word; /* media word */ + uint64_t ifmb_baudrate; /* corresponding baudrate */ +}; + +#define IFM_BAUDRATE_DESCRIPTIONS { \ + { IFM_ETHER | IFM_10_T, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_10_2, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_10_5, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_100_TX, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_FX, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_T4, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_VG, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_100_T2, IF_Mbps(100) }, \ + { IFM_ETHER | IFM_1000_SX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_10_STP, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_10_FL, IF_Mbps(10) }, \ + { IFM_ETHER | IFM_1000_LX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_1000_CX, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_1000_T, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_HPNA_1, IF_Mbps(1) }, \ + { IFM_ETHER | IFM_10G_LR, IF_Gbps(10ULL) }, \ + \ + { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ + { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \ + { IFM_TOKEN | IFM_TOK_UTP4, IF_Mbps(4) }, \ + { IFM_TOKEN | IFM_TOK_UTP16, IF_Mbps(16) }, \ + \ + { IFM_FDDI | IFM_FDDI_SMF, IF_Mbps(100) }, \ + { IFM_FDDI | IFM_FDDI_MMF, IF_Mbps(100) }, \ + { IFM_FDDI | IFM_FDDI_UTP, IF_Mbps(100) }, \ + \ + { IFM_IEEE80211 | IFM_IEEE80211_FH1, IF_Mbps(1) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_FH2, IF_Mbps(2) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS2, IF_Mbps(2) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS5, IF_Kbps(5500) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS11, IF_Mbps(11) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS1, IF_Mbps(1) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_DS22, IF_Mbps(22) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM6, IF_Mbps(6) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM9, IF_Mbps(9) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM12, IF_Mbps(12) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM18, IF_Mbps(18) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM24, IF_Mbps(24) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM36, IF_Mbps(36) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM48, IF_Mbps(48) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM54, IF_Mbps(54) }, \ + { IFM_IEEE80211 | IFM_IEEE80211_OFDM72, IF_Mbps(72) }, \ + \ + { 0, 0 }, \ +} + #endif /* _NET_IF_MEDIA_H_ */