aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Joyner <erj@FreeBSD.org>2015-04-07 21:31:17 +0000
committerEric Joyner <erj@FreeBSD.org>2015-04-07 21:31:17 +0000
commiteb7e25b22f1c2eaa6fbab19a04d4623e70ed8fc9 (patch)
tree1b63cfe3c66ab0529a46da0bf5f434d22404da4c
parent53deb05c362697471b8672a5ab4d4187cac0532b (diff)
downloadsrc-eb7e25b22f1c2eaa6fbab19a04d4623e70ed8fc9.tar.gz
src-eb7e25b22f1c2eaa6fbab19a04d4623e70ed8fc9.zip
Notes
-rw-r--r--sbin/ifconfig/ifmedia.c32
-rw-r--r--sys/net/ieee8023ad_lacp.c42
-rw-r--r--sys/net/if.c1
-rw-r--r--sys/net/if_media.c31
-rw-r--r--sys/net/if_media.h108
-rw-r--r--sys/sys/sockio.h1
6 files changed, 201 insertions, 14 deletions
diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c
index 0b0daa3086a1..eee33918f778 100644
--- a/sbin/ifconfig/ifmedia.c
+++ b/sbin/ifconfig/ifmedia.c
@@ -109,11 +109,17 @@ media_status(int s)
{
struct ifmediareq ifmr;
int *media_list, i;
+ int xmedia = 1;
(void) memset(&ifmr, 0, sizeof(ifmr));
(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+ /*
+ * Check if interface supports extended media types.
+ */
+ if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
+ xmedia = 0;
+ if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
@@ -130,8 +136,13 @@ media_status(int s)
err(1, "malloc");
ifmr.ifm_ulist = media_list;
- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
- err(1, "SIOCGIFMEDIA");
+ if (xmedia) {
+ if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
+ err(1, "SIOCGIFXMEDIA");
+ } else {
+ if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
+ err(1, "SIOCGIFMEDIA");
+ }
printf("\tmedia: ");
print_media_word(ifmr.ifm_current, 1);
@@ -194,6 +205,7 @@ ifmedia_getstate(int s)
{
static struct ifmediareq *ifmr = NULL;
int *mwords;
+ int xmedia = 1;
if (ifmr == NULL) {
ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq));
@@ -213,7 +225,10 @@ ifmedia_getstate(int s)
* the current media type and the top-level type.
*/
- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) {
+ if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0) {
+ xmedia = 0;
+ }
+ if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) {
err(1, "SIOCGIFMEDIA");
}
@@ -225,8 +240,13 @@ ifmedia_getstate(int s)
err(1, "malloc");
ifmr->ifm_ulist = mwords;
- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0)
- err(1, "SIOCGIFMEDIA");
+ if (xmedia) {
+ if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)ifmr) < 0)
+ err(1, "SIOCGIFXMEDIA");
+ } else {
+ if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0)
+ err(1, "SIOCGIFMEDIA");
+ }
}
return ifmr;
diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c
index c422c25201a3..64aafb152151 100644
--- a/sys/net/ieee8023ad_lacp.c
+++ b/sys/net/ieee8023ad_lacp.c
@@ -1066,12 +1066,16 @@ lacp_compose_key(struct lacp_port *lp)
case IFM_100_T4:
case IFM_100_VG:
case IFM_100_T2:
+ case IFM_100_T:
key = IFM_100_TX;
break;
case IFM_1000_SX:
case IFM_1000_LX:
case IFM_1000_CX:
case IFM_1000_T:
+ case IFM_1000_KX:
+ case IFM_1000_SGMII:
+ case IFM_1000_CX_SGMII:
key = IFM_1000_SX;
break;
case IFM_10G_LR:
@@ -1081,15 +1085,53 @@ lacp_compose_key(struct lacp_port *lp)
case IFM_10G_TWINAX_LONG:
case IFM_10G_LRM:
case IFM_10G_T:
+ case IFM_10G_KX4:
+ case IFM_10G_KR:
+ case IFM_10G_CR1:
+ case IFM_10G_ER:
+ case IFM_10G_SFI:
key = IFM_10G_LR;
break;
+ case IFM_20G_KR2:
+ key = IFM_20G_KR2;
+ break;
+ case IFM_2500_KX:
+ case IFM_2500_T:
+ key = IFM_2500_KX;
+ break;
+ case IFM_5000_T:
+ key = IFM_5000_T;
+ break;
+ case IFM_50G_PCIE:
+ case IFM_50G_CR2:
+ case IFM_50G_KR2:
+ key = IFM_50G_PCIE;
+ break;
+ case IFM_56G_R4:
+ key = IFM_56G_R4;
+ break;
+ case IFM_25G_PCIE:
+ case IFM_25G_CR:
+ case IFM_25G_KR:
+ case IFM_25G_SR:
+ key = IFM_25G_PCIE;
+ break;
case IFM_40G_CR4:
case IFM_40G_SR4:
case IFM_40G_LR4:
+ case IFM_40G_XLPPI:
+ case IFM_40G_KR4:
key = IFM_40G_CR4;
break;
+ case IFM_100G_CR4:
+ case IFM_100G_SR4:
+ case IFM_100G_KR4:
+ case IFM_100G_LR4:
+ key = IFM_100G_CR4;
+ break;
default:
key = subtype;
+ break;
}
/* bit 5..14: (some bits of) if_index of lagg device */
key |= 0x7fe0 & ((sc->sc_ifp->if_index) << 5);
diff --git a/sys/net/if.c b/sys/net/if.c
index 9d56803863ee..1dec451df5c7 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2582,6 +2582,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
case SIOCGIFPSRCADDR:
case SIOCGIFPDSTADDR:
case SIOCGIFMEDIA:
+ case SIOCGIFXMEDIA:
case SIOCGIFGENERIC:
if (ifp->if_ioctl == NULL)
return (EOPNOTSUPP);
diff --git a/sys/net/if_media.c b/sys/net/if_media.c
index 810db3f4e012..a76ec90ffcaa 100644
--- a/sys/net/if_media.c
+++ b/sys/net/if_media.c
@@ -68,6 +68,7 @@ static struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm,
int flags, int mask);
#ifdef IFMEDIA_DEBUG
+#include <net/if_var.h>
int ifmedia_debug = 0;
SYSCTL_INT(_debug, OID_AUTO, ifmedia, CTLFLAG_RW, &ifmedia_debug,
0, "if_media debugging msgs");
@@ -193,6 +194,21 @@ ifmedia_set(ifm, target)
}
/*
+ * Given a media word, return one suitable for an application
+ * using the original encoding.
+ */
+static int
+compat_media(int media)
+{
+
+ if (IFM_TYPE(media) == IFM_ETHER && IFM_SUBTYPE(media) > IFM_OTHER) {
+ media &= ~(IFM_ETH_XTYPE|IFM_TMASK);
+ media |= IFM_OTHER;
+ }
+ return (media);
+}
+
+/*
* Device-independent media ioctl support function.
*/
int
@@ -271,6 +287,7 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
* Get list of available media and current media on interface.
*/
case SIOCGIFMEDIA:
+ case SIOCGIFXMEDIA:
{
struct ifmedia_entry *ep;
int i;
@@ -278,8 +295,13 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
if (ifmr->ifm_count < 0)
return (EINVAL);
- ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
- ifm->ifm_cur->ifm_media : IFM_NONE;
+ if (cmd == SIOCGIFMEDIA) {
+ ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
+ compat_media(ifm->ifm_cur->ifm_media) : IFM_NONE;
+ } else {
+ ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
+ ifm->ifm_cur->ifm_media : IFM_NONE;
+ }
ifmr->ifm_mask = ifm->ifm_mask;
ifmr->ifm_status = 0;
(*ifm->ifm_status)(ifp, ifmr);
@@ -354,8 +376,7 @@ 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)
+ if (IFM_TYPE_MATCH(mword, ifmedia_baudrate_descriptions[i].ifmb_word))
return (ifmedia_baudrate_descriptions[i].ifmb_baudrate);
}
@@ -461,7 +482,7 @@ ifmedia_printword(ifmw)
printf("<unknown type>\n");
return;
}
- printf(desc->ifmt_string);
+ printf("%s", desc->ifmt_string);
/* Any mode. */
for (desc = ttos->modes; desc && desc->ifmt_string != NULL; desc++)
diff --git a/sys/net/if_media.h b/sys/net/if_media.h
index 88384f331b4d..86439950c320 100644
--- a/sys/net/if_media.h
+++ b/sys/net/if_media.h
@@ -118,7 +118,7 @@ uint64_t ifmedia_baudrate(int);
* ---- -------
* 0-4 Media variant
* 5-7 Media type
- * 8-15 Type specific options
+ * 8-15 Type specific options (includes added variant bits on Ethernet)
* 16-18 Mode (for multi-mode devices)
* 19 RFU
* 20-27 Shared (global) options
@@ -127,8 +127,18 @@ uint64_t ifmedia_baudrate(int);
/*
* Ethernet
+ * In order to use more than 31 subtypes, Ethernet uses some of the option
+ * bits as part of the subtype field. See the options section below for
+ * relevant definitions
*/
#define IFM_ETHER 0x00000020
+#define IFM_ETHER_SUBTYPE(x) (((x) & IFM_TMASK) | \
+ (((x) & (IFM_ETH_XTYPE >> IFM_ETH_XSHIFT)) << IFM_ETH_XSHIFT))
+#define IFM_X(x) IFM_ETHER_SUBTYPE(x) /* internal shorthand */
+#define IFM_ETHER_SUBTYPE_SET(x) (IFM_ETHER_SUBTYPE(x) | IFM_ETHER)
+#define IFM_ETHER_SUBTYPE_GET(x) ((x) & (IFM_TMASK|IFM_ETH_XTYPE))
+#define IFM_ETHER_IS_EXTENDED(x) ((x) & IFM_ETH_XTYPE)
+
#define IFM_10_T 3 /* 10BaseT - RJ45 */
#define IFM_10_2 4 /* 10Base2 - Thinnet */
#define IFM_10_5 5 /* 10Base5 - AUI */
@@ -156,15 +166,49 @@ uint64_t ifmedia_baudrate(int);
#define IFM_40G_CR4 27 /* 40GBase-CR4 */
#define IFM_40G_SR4 28 /* 40GBase-SR4 */
#define IFM_40G_LR4 29 /* 40GBase-LR4 */
+#define IFM_1000_KX 30 /* 1000Base-KX backplane */
+#define IFM_OTHER 31 /* Other: one of the following */
+
+/* following types are not visible to old binaries using only IFM_TMASK */
+#define IFM_10G_KX4 IFM_X(32) /* 10GBase-KX4 backplane */
+#define IFM_10G_KR IFM_X(33) /* 10GBase-KR backplane */
+#define IFM_10G_CR1 IFM_X(34) /* 10GBase-CR1 Twinax splitter */
+#define IFM_20G_KR2 IFM_X(35) /* 20GBase-KR2 backplane */
+#define IFM_2500_KX IFM_X(36) /* 2500Base-KX backplane */
+#define IFM_2500_T IFM_X(37) /* 2500Base-T - RJ45 (NBaseT) */
+#define IFM_5000_T IFM_X(38) /* 5000Base-T - RJ45 (NBaseT) */
+#define IFM_50G_PCIE IFM_X(39) /* 50G Ethernet over PCIE */
+#define IFM_25G_PCIE IFM_X(40) /* 25G Ethernet over PCIE */
+#define IFM_1000_SGMII IFM_X(41) /* 1G media interface */
+#define IFM_10G_SFI IFM_X(42) /* 10G media interface */
+#define IFM_40G_XLPPI IFM_X(43) /* 40G media interface */
+#define IFM_1000_CX_SGMII IFM_X(44) /* 1000Base-CX-SGMII */
+#define IFM_40G_KR4 IFM_X(45) /* 40GBase-KR4 */
+#define IFM_10G_ER IFM_X(46) /* 10GBase-ER */
+#define IFM_100G_CR4 IFM_X(47) /* 100GBase-CR4 */
+#define IFM_100G_SR4 IFM_X(48) /* 100GBase-SR4 */
+#define IFM_100G_KR4 IFM_X(49) /* 100GBase-KR4 */
+#define IFM_100G_LR4 IFM_X(50) /* 100GBase-LR4 */
+#define IFM_56G_R4 IFM_X(51) /* 56GBase-R4 */
+#define IFM_100_T IFM_X(52) /* 100BaseT - RJ45 */
+#define IFM_25G_CR IFM_X(53) /* 25GBase-CR */
+#define IFM_25G_KR IFM_X(54) /* 25GBase-KR */
+#define IFM_25G_SR IFM_X(55) /* 25GBase-SR */
+#define IFM_50G_CR2 IFM_X(56) /* 50GBase-CR2 */
+#define IFM_50G_KR2 IFM_X(57) /* 50GBase-KR2 */
+
/*
* Please update ieee8023ad_lacp.c:lacp_compose_key()
* after adding new Ethernet media types.
*/
-/* note 31 is the max! */
+/* Note IFM_X(511) is the max! */
+/* Ethernet option values; includes bits used for extended variant field */
#define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */
#define IFM_ETH_RXPAUSE 0x00000200 /* receive PAUSE frames */
#define IFM_ETH_TXPAUSE 0x00000400 /* transmit PAUSE frames */
+#define IFM_ETH_XTYPE 0x00007800 /* extended media variants */
+#define IFM_ETH_XSHIFT 6 /* shift XTYPE next to TMASK */
/*
* Token ring
@@ -307,7 +351,10 @@ uint64_t ifmedia_baudrate(int);
* Macros to extract various bits of information from the media word.
*/
#define IFM_TYPE(x) ((x) & IFM_NMASK)
-#define IFM_SUBTYPE(x) ((x) & IFM_TMASK)
+#define IFM_SUBTYPE(x) \
+ (IFM_TYPE(x) == IFM_ETHER ? IFM_ETHER_SUBTYPE_GET(x) : ((x) & IFM_TMASK))
+#define IFM_TYPE_MATCH(x,y) \
+ (IFM_TYPE(x) == IFM_TYPE(y) && IFM_SUBTYPE(x) == IFM_SUBTYPE(y))
#define IFM_TYPE_OPTIONS(x) ((x) & IFM_OMASK)
#define IFM_INST(x) (((x) & IFM_IMASK) >> IFM_ISHIFT)
#define IFM_OPTIONS(x) ((x) & (IFM_OMASK | IFM_GMASK))
@@ -372,6 +419,34 @@ struct ifmedia_description {
{ IFM_40G_CR4, "40Gbase-CR4" }, \
{ IFM_40G_SR4, "40Gbase-SR4" }, \
{ IFM_40G_LR4, "40Gbase-LR4" }, \
+ { IFM_1000_KX, "1000Base-KX" }, \
+ { IFM_OTHER, "Other" }, \
+ { IFM_10G_KX4, "10GBase-KX4" }, \
+ { IFM_10G_KR, "10GBase-KR" }, \
+ { IFM_10G_CR1, "10GBase-CR1" }, \
+ { IFM_20G_KR2, "20GBase-KR2" }, \
+ { IFM_2500_KX, "2500Base-KX" }, \
+ { IFM_2500_T, "2500Base-T" }, \
+ { IFM_5000_T, "5000Base-T" }, \
+ { IFM_50G_PCIE, "PCIExpress-50G" }, \
+ { IFM_25G_PCIE, "PCIExpress-25G" }, \
+ { IFM_1000_SGMII, "1000Base-SGMII" }, \
+ { IFM_10G_SFI, "10GBase-SFI" }, \
+ { IFM_40G_XLPPI, "40GBase-XLPPI" }, \
+ { IFM_1000_CX_SGMII, "1000Base-CX-SGMII" }, \
+ { IFM_40G_KR4, "40GBase-KR4" }, \
+ { IFM_10G_ER, "10GBase-ER" }, \
+ { IFM_100G_CR4, "100GBase-CR4" }, \
+ { IFM_100G_SR4, "100GBase-SR4" }, \
+ { IFM_100G_KR4, "100GBase-KR4" }, \
+ { IFM_100G_LR4, "100GBase-LR4" }, \
+ { IFM_56G_R4, "56GBase-R4" }, \
+ { IFM_100_T, "100BaseT" }, \
+ { IFM_25G_CR, "25GBase-CR" }, \
+ { IFM_25G_KR, "25GBase-KR" }, \
+ { IFM_25G_SR, "25GBase-SR" }, \
+ { IFM_50G_CR2, "50GBase-CR2" }, \
+ { IFM_50G_KR2, "50GBase-KR2" }, \
{ 0, NULL }, \
}
@@ -673,6 +748,33 @@ struct ifmedia_baudrate {
{ IFM_ETHER | IFM_40G_CR4, IF_Gbps(40ULL) }, \
{ IFM_ETHER | IFM_40G_SR4, IF_Gbps(40ULL) }, \
{ IFM_ETHER | IFM_40G_LR4, IF_Gbps(40ULL) }, \
+ { IFM_ETHER | IFM_1000_KX, IF_Mbps(1000) }, \
+ { IFM_ETHER | IFM_10G_KX4, IF_Gbps(10ULL) }, \
+ { IFM_ETHER | IFM_10G_KR, IF_Gbps(10ULL) }, \
+ { IFM_ETHER | IFM_10G_CR1, IF_Gbps(10ULL) }, \
+ { IFM_ETHER | IFM_20G_KR2, IF_Gbps(20ULL) }, \
+ { IFM_ETHER | IFM_2500_KX, IF_Mbps(2500) }, \
+ { IFM_ETHER | IFM_2500_T, IF_Mbps(2500) }, \
+ { IFM_ETHER | IFM_5000_T, IF_Mbps(5000) }, \
+ { IFM_ETHER | IFM_50G_PCIE, IF_Gbps(50ULL) }, \
+ { IFM_ETHER | IFM_25G_PCIE, IF_Gbps(25ULL) }, \
+ { IFM_ETHER | IFM_1000_SGMII, IF_Mbps(1000) }, \
+ { IFM_ETHER | IFM_10G_SFI, IF_Gbps(10ULL) }, \
+ { IFM_ETHER | IFM_40G_XLPPI, IF_Gbps(40ULL) }, \
+ { IFM_ETHER | IFM_1000_CX_SGMII, IF_Mbps(1000) }, \
+ { IFM_ETHER | IFM_40G_KR4, IF_Gbps(40ULL) }, \
+ { IFM_ETHER | IFM_10G_ER, IF_Gbps(10ULL) }, \
+ { IFM_ETHER | IFM_100G_CR4, IF_Gbps(100ULL) }, \
+ { IFM_ETHER | IFM_100G_SR4, IF_Gbps(100ULL) }, \
+ { IFM_ETHER | IFM_100G_KR4, IF_Gbps(100ULL) }, \
+ { IFM_ETHER | IFM_100G_LR4, IF_Gbps(100ULL) }, \
+ { IFM_ETHER | IFM_56G_R4, IF_Gbps(56ULL) }, \
+ { IFM_ETHER | IFM_100_T, IF_Mbps(100ULL) }, \
+ { IFM_ETHER | IFM_25G_CR, IF_Gbps(25ULL) }, \
+ { IFM_ETHER | IFM_25G_KR, IF_Gbps(25ULL) }, \
+ { IFM_ETHER | IFM_25G_SR, IF_Gbps(25ULL) }, \
+ { IFM_ETHER | IFM_50G_CR2, IF_Gbps(50ULL) }, \
+ { IFM_ETHER | IFM_50G_KR2, IF_Gbps(50ULL) }, \
\
{ IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \
{ IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 7b09acfaa779..f04bb1233749 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -128,5 +128,6 @@
#define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) /* get ifgroups */
#define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) /* delete ifgroup */
#define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get members */
+#define SIOCGIFXMEDIA _IOWR('i', 139, struct ifmediareq) /* get net xmedia */
#endif /* !_SYS_SOCKIO_H_ */