Index: sbin/ifconfig/ifmedia.c =================================================================== --- sbin/ifconfig/ifmedia.c +++ sbin/ifconfig/ifmedia.c @@ -109,11 +109,17 @@ { 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 @@ 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 @@ { static struct ifmediareq *ifmr = NULL; int *mwords; + int xmedia = 1; if (ifmr == NULL) { ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq)); @@ -213,7 +225,10 @@ * 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 @@ 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; Index: sys/dev/virtio/network/if_vtnet.c =================================================================== --- sys/dev/virtio/network/if_vtnet.c +++ sys/dev/virtio/network/if_vtnet.c @@ -938,6 +938,7 @@ ifmedia_init(&sc->vtnet_media, IFM_IMASK, vtnet_ifmedia_upd, vtnet_ifmedia_sts); ifmedia_add(&sc->vtnet_media, VTNET_MEDIATYPE, 0, NULL); + ifmedia_add(&sc->vtnet_media, IFM_ETHER | IFM_VFAST, 0, NULL); ifmedia_set(&sc->vtnet_media, VTNET_MEDIATYPE); /* Read (or generate) the MAC address for the adapter. */ @@ -1103,9 +1104,9 @@ case SIOCSIFMEDIA: case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->vtnet_media, cmd); break; - case SIOCSIFCAP: VTNET_CORE_LOCK(sc); mask = ifr->ifr_reqcap ^ ifp->if_capenable; Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -2561,6 +2561,7 @@ case SIOCGIFPSRCADDR: case SIOCGIFPDSTADDR: case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: case SIOCGIFGENERIC: if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); Index: sys/net/if_media.h =================================================================== --- sys/net/if_media.h +++ sys/net/if_media.h @@ -120,15 +120,29 @@ * 5-7 Media type * 8-15 Type specific options * 16-18 Mode (for multi-mode devices) - * 19 RFU + * 19 "extended" bit for media variant * 20-27 Shared (global) options * 28-31 Instance */ /* + * As we have used all of the original values for the media variant (subtype) + * for Ethernet, extended subtypes have been added, marked with XSUBTYPE, + * which is effectively the "high bit" of the media variant (subtype) field. + * IFM_OTHER (the highest basic type) is reserved to indicate use of an + * extended type when using an old SIOCGIFMEDIA operation. This is true + * for all media types, not just Ethernet. + */ +#define XSUBTYPE 0x80000 /* extended variant high bit */ +#define _X(var) ((var) | XSUBTYPE) /* extended variant */ +#define IFM_OTHER 31 /* Other: some extended type */ +#define OMEDIA(var) (((var) & XSUBTYPE) ? IFM_OTHER : (var)) + +/* * Ethernet */ #define IFM_ETHER 0x00000020 +/* NB: 0,1,2 are auto, manual, none defined below */ #define IFM_10_T 3 /* 10BaseT - RJ45 */ #define IFM_10_2 4 /* 10Base2 - Thinnet */ #define IFM_10_5 5 /* 10Base5 - AUI */ @@ -156,11 +170,30 @@ #define IFM_40G_CR4 27 /* 40GBase-CR4 */ #define IFM_40G_SR4 28 /* 40GBase-SR4 */ #define IFM_40G_LR4 29 /* 40GBase-LR4 */ +#define IFM_40G_KR4 30 /* 40GBase-KR4 backplane */ +/* #define IFM_OTHER 31 Other: some extended type */ +/* note 31 is the max! */ + +/* Extended variants/subtypes */ +#define IFM_VFAST _X(0) /* test "V.fast" */ +#define IFM_1000_KX _X(1) /* 1000Base-KX backplane */ +#define IFM_10G_KX4 _X(2) /* 10GBase-KX4 backplane */ +#define IFM_10G_KR _X(3) /* 10GBase-KR backplane */ +#define IFM_10G_CR1 _X(4) /* 10GBase-CR1 Twinax splitter */ +#define IFM_20G_KR2 _X(5) /* 20GBase-KR2 backplane */ +#define IFM_2500_KX _X(6) /* 2500Base-KX backplane */ +#define IFM_2500_T _X(7) /* 2500Base-T - RJ45 (NBaseT) */ +#define IFM_5000_T _X(8) /* 5000Base-T - RJ45 (NBaseT) */ +#define IFM_50G_PCIE _X(9) /* 50G Ethernet over PCIE */ +#define IFM_25G_PCIE _X(10) /* 25G Ethernet over PCIE */ +#define IFM_SGMII _X(11) /* 1G media interface */ +#define IFM_SFI _X(12) /* 10G media interface */ +#define IFM_XLPPI _X(13) /* 40G media interface */ +/* note _X(31) is the max! */ /* * Please update ieee8023ad_lacp.c:lacp_compose_key() * after adding new Ethernet media types. */ -/* note 31 is the max! */ #define IFM_ETH_MASTER 0x00000100 /* master mode (1000baseT) */ #define IFM_ETH_RXPAUSE 0x00000200 /* receive PAUSE frames */ @@ -170,6 +203,7 @@ * Token ring */ #define IFM_TOKEN 0x00000040 +/* NB: 0,1,2 are auto, manual, none defined below */ #define IFM_TOK_STP4 3 /* Shielded twisted pair 4m - DB9 */ #define IFM_TOK_STP16 4 /* Shielded twisted pair 16m - DB9 */ #define IFM_TOK_UTP4 5 /* Unshielded twisted pair 4m - RJ45 */ @@ -187,6 +221,7 @@ * FDDI */ #define IFM_FDDI 0x00000060 +/* NB: 0,1,2 are auto, manual, none defined below */ #define IFM_FDDI_SMF 3 /* Single-mode fiber */ #define IFM_FDDI_MMF 4 /* Multi-mode fiber */ #define IFM_FDDI_UTP 5 /* CDDI / UTP */ @@ -220,6 +255,7 @@ #define IFM_IEEE80211_OFDM27 23 /* OFDM 27Mbps */ /* NB: not enough bits to express MCS fully */ #define IFM_IEEE80211_MCS 24 /* HT MCS rate */ +/* #define IFM_OTHER 31 Other: some extended type */ #define IFM_IEEE80211_ADHOC 0x00000100 /* Operate in Adhoc mode */ #define IFM_IEEE80211_HOSTAP 0x00000200 /* Operate in Host AP mode */ @@ -241,6 +277,7 @@ * ATM */ #define IFM_ATM 0x000000a0 +/* NB: 0,1,2 are auto, manual, none defined below */ #define IFM_ATM_UNKNOWN 3 #define IFM_ATM_UTP_25 4 #define IFM_ATM_TAXI_100 5 @@ -277,7 +314,7 @@ * Masks */ #define IFM_NMASK 0x000000e0 /* Network type */ -#define IFM_TMASK 0x0000001f /* Media sub-type */ +#define IFM_TMASK 0x0008001f /* Media sub-type */ #define IFM_IMASK 0xf0000000 /* Instance */ #define IFM_ISHIFT 28 /* Instance shift */ #define IFM_OMASK 0x0000ff00 /* Type specific options */ @@ -372,6 +409,21 @@ { IFM_40G_CR4, "40Gbase-CR4" }, \ { IFM_40G_SR4, "40Gbase-SR4" }, \ { IFM_40G_LR4, "40Gbase-LR4" }, \ + { IFM_40G_KR4, "40Gbase-KR4" }, \ + { IFM_VFAST, "V.fast" }, \ + { IFM_1000_KX, "1000Base-KX" }, \ + { 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_SGMII, "SGMII" }, \ + { IFM_SFI, "SFI" }, \ + { IFM_XLPPI, "XLPPI" }, \ { 0, NULL }, \ } @@ -603,6 +655,7 @@ { IFM_AUTO, "autoselect" }, \ { IFM_MANUAL, "manual" }, \ { IFM_NONE, "none" }, \ + { IFM_OTHER, "other" }, \ { 0, NULL }, \ } @@ -673,6 +726,20 @@ { 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_VFAST, 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_SGMII, IF_Mbps(1000) }, \ + { IFM_ETHER | IFM_SFI, IF_Gbps(10ULL) }, \ + { IFM_ETHER | IFM_XLPPI, IF_Gbps(40ULL) }, \ \ { IFM_TOKEN | IFM_TOK_STP4, IF_Mbps(4) }, \ { IFM_TOKEN | IFM_TOK_STP16, IF_Mbps(16) }, \ Index: sys/net/if_media.c =================================================================== --- sys/net/if_media.c +++ sys/net/if_media.c @@ -67,7 +67,9 @@ static struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm, int flags, int mask); +#define IFMEDIA_DEBUG #ifdef IFMEDIA_DEBUG +#include int ifmedia_debug = 0; SYSCTL_INT(_debug, OID_AUTO, ifmedia, CTLFLAG_RW, &ifmedia_debug, 0, "if_media debugging msgs"); @@ -271,6 +273,7 @@ * Get list of available media and current media on interface. */ case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: { struct ifmedia_entry *ep; int *kptr, count; @@ -278,8 +281,13 @@ kptr = NULL; /* XXX gcc */ - 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 ? + OMEDIA(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); @@ -317,7 +325,10 @@ ep = LIST_FIRST(&ifm->ifm_list); for (; ep != NULL && count < ifmr->ifm_count; ep = LIST_NEXT(ep, ifm_list), count++) - kptr[count] = ep->ifm_media; + if (cmd == SIOCGIFMEDIA) + kptr[count] = OMEDIA(ep->ifm_media); + else + kptr[count] = ep->ifm_media; if (ep != NULL) error = E2BIG; /* oops! */ @@ -505,7 +516,7 @@ printf("\n"); return; } - printf(desc->ifmt_string); + printf("%s", desc->ifmt_string); /* Any mode. */ for (desc = ttos->modes; desc && desc->ifmt_string != NULL; desc++) Index: sys/sys/sockio.h =================================================================== --- sys/sys/sockio.h +++ 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_ */