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: m...@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_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to