svn commit: r281236 - in head: sbin/ifconfig sys/net sys/sys

Eric Joyner erj at FreeBSD.org
Tue Apr 7 21:31:20 UTC 2015


Author: erj
Date: Tue Apr  7 21:31:17 2015
New Revision: 281236
URL: https://svnweb.freebsd.org/changeset/base/281236

Log:
  ifmedia changes:
  
  - Extend the number of available subtypes for Ethernet media by using some
  of the ifmedia word's option bits to help denote subtypes. As a result, the
  number of possible Ethernet subtype values increases from 31 to 511.
  
  - Use some of those new values to define new media types.
  
  - lacp_compose_key() recgonizes the new Ethernet media types added.
    (Change made as required by a comment in if_media.h)
  
  - New ioctl, SIOGIFXMEDIA, to handle getting the new extended media types.
    SIOCGIFMEDIA is retained for backwards compatibility.
  
  - Changes to ifconfig to allow it to handle the new extended media types.
  
  Submitted by:	mike at karels.net (original), hselasky
  Reviewed by:	jfvogel, gnn, hselasky
  Approved by:	jfvogel (mentor), gnn (mentor)
  Differential Revision: http://reviews.freebsd.org/D1965

Modified:
  head/sbin/ifconfig/ifmedia.c
  head/sys/net/ieee8023ad_lacp.c
  head/sys/net/if.c
  head/sys/net/if_media.c
  head/sys/net/if_media.h
  head/sys/sys/sockio.h

Modified: head/sbin/ifconfig/ifmedia.c
==============================================================================
--- head/sbin/ifconfig/ifmedia.c	Tue Apr  7 21:05:52 2015	(r281235)
+++ head/sbin/ifconfig/ifmedia.c	Tue Apr  7 21:31:17 2015	(r281236)
@@ -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;

Modified: head/sys/net/ieee8023ad_lacp.c
==============================================================================
--- head/sys/net/ieee8023ad_lacp.c	Tue Apr  7 21:05:52 2015	(r281235)
+++ head/sys/net/ieee8023ad_lacp.c	Tue Apr  7 21:31:17 2015	(r281236)
@@ -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);

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Tue Apr  7 21:05:52 2015	(r281235)
+++ head/sys/net/if.c	Tue Apr  7 21:31:17 2015	(r281236)
@@ -2582,6 +2582,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp,
 	case SIOCGIFPSRCADDR:
 	case SIOCGIFPDSTADDR:
 	case SIOCGIFMEDIA:
+	case SIOCGIFXMEDIA:
 	case SIOCGIFGENERIC:
 		if (ifp->if_ioctl == NULL)
 			return (EOPNOTSUPP);

Modified: head/sys/net/if_media.c
==============================================================================
--- head/sys/net/if_media.c	Tue Apr  7 21:05:52 2015	(r281235)
+++ head/sys/net/if_media.c	Tue Apr  7 21:31:17 2015	(r281236)
@@ -68,6 +68,7 @@ static struct ifmedia_entry *ifmedia_mat
     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++)

Modified: head/sys/net/if_media.h
==============================================================================
--- head/sys/net/if_media.h	Tue Apr  7 21:05:52 2015	(r281235)
+++ head/sys/net/if_media.h	Tue Apr  7 21:31:17 2015	(r281236)
@@ -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) },			\

Modified: head/sys/sys/sockio.h
==============================================================================
--- head/sys/sys/sockio.h	Tue Apr  7 21:05:52 2015	(r281235)
+++ head/sys/sys/sockio.h	Tue Apr  7 21:31:17 2015	(r281236)
@@ -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_ */


More information about the svn-src-all mailing list