Module Name:    src
Committed By:   msaitoh
Date:           Fri May 17 07:37:12 UTC 2019

Modified Files:
        src/sys/compat/common: Makefile.sysio compat_80_mod.c compat_mod.h
            files.common if_43.c
        src/sys/compat/netbsd32: netbsd32_ioctl.c netbsd32_ioctl.h
        src/sys/compat/sys: sockio.h
        src/sys/kern: compat_stub.c
        src/sys/net: if.c if_media.c if_media.h
        src/sys/sys: compat_stub.h sockio.h
Added Files:
        src/sys/compat/common: if_media_80.c

Log Message:
 The max subtype of the ifmedia word is 31. It's too small for Ethernet now.
We currently use use it up to 30. We should extend the limit to be able to use
more than 10Gbps speeds. Our ifmedia(4) is inconvenience and have some problem
so we should redesign the interface, but it's too late for netbsd-9 to do it.
So, we keep the data structure size and modify the structure a bit. The
strategy is almost the same as FreeBSD. Many bits of IFM_OMASK for Ethernet
have not used, so use some of them for Ethernet's subtype.

The differences against FreeBSD are:
 - We use NetBSD style compat code (i.e. no SIOCGIFXMEDIA).
 - FreeBSD's IFM_ETH_XTYPE's bit location is from 11 to "14" even though
   IFM_OMASK is from 8 to "15". We use _IFM_ETH_XTMASK from bit 13 to "15".
 - FreeBSD changed the meaning of IFM_TYPE_MATCH(). I think we should
   not do it. We keep it not changing and added new IFM_TYPE_SUBTYPE_MATCH()
   macro for matching both TYPE and SUBTYPE.
 - Added up to 400GBASE-SR16.

New layout of the media word is as follows (from ifmedia_h):

 * if_media Options word:
 *      Bits    Use
 *      ----    -------
 *      0-4     Media subtype   MAX SUBTYPE == 255 for ETH and 31 for others
 *      5-7     Media type
 *      8-15    Type specific options
 *      16-18   Mode (for multi-mode devices)
 *      19      (Reserved for Future Use)
 *      20-27   Shared (global) options
 *      28-31   Instance
 *
 *   3                     2                   1
 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 *  +-------+---------------+-+-----+---------------+-----+---------+
 *  |       |               |R|     |               |     |         |
 *  | IMASK |     GMASK     |F|MMASK+-----+ OMASK   |NMASK|  TMASK  |
 *  |       |               |U|     |XTMSK|         |     |         |
 *  +-------+---------------+-+-----+-----+---------+-----+---------+
 *   <----->                   <--->                 <--->
 *  IFM_INST()               IFM_MODE()            IFM_TYPE()
 *
 *                              IFM_SUBTYPE(other than ETH)<------->
 *
 *                                   <---> IFM_SUBTYPE(ETH)<------->
 *
 *
 *           <------------->         <------------->
 *                        IFM_OPTIONS()


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/compat/common/Makefile.sysio
cvs rdiff -u -r1.3 -r1.4 src/sys/compat/common/compat_80_mod.c \
    src/sys/compat/common/files.common
cvs rdiff -u -r1.4 -r1.5 src/sys/compat/common/compat_mod.h
cvs rdiff -u -r1.21 -r1.22 src/sys/compat/common/if_43.c
cvs rdiff -u -r0 -r1.1 src/sys/compat/common/if_media_80.c
cvs rdiff -u -r1.102 -r1.103 src/sys/compat/netbsd32/netbsd32_ioctl.c
cvs rdiff -u -r1.66 -r1.67 src/sys/compat/netbsd32/netbsd32_ioctl.h
cvs rdiff -u -r1.18 -r1.19 src/sys/compat/sys/sockio.h
cvs rdiff -u -r1.11 -r1.12 src/sys/kern/compat_stub.c
cvs rdiff -u -r1.453 -r1.454 src/sys/net/if.c
cvs rdiff -u -r1.44 -r1.45 src/sys/net/if_media.c
cvs rdiff -u -r1.64 -r1.65 src/sys/net/if_media.h
cvs rdiff -u -r1.15 -r1.16 src/sys/sys/compat_stub.h
cvs rdiff -u -r1.36 -r1.37 src/sys/sys/sockio.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/common/Makefile.sysio
diff -u src/sys/compat/common/Makefile.sysio:1.11 src/sys/compat/common/Makefile.sysio:1.12
--- src/sys/compat/common/Makefile.sysio:1.11	Sun Jan 27 02:08:39 2019
+++ src/sys/compat/common/Makefile.sysio	Fri May 17 07:37:11 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.sysio,v 1.11 2019/01/27 02:08:39 pgoyette Exp $
+#	$NetBSD: Makefile.sysio,v 1.12 2019/05/17 07:37:11 msaitoh Exp $
 
 # Sources for syscall and ioctl compatibility across the versions.
 
@@ -47,7 +47,7 @@ SRCS+=	kern_sa_60.c tty_60.c kern_time_6
 SRCS+=	rtsock_70.c uipc_usrreq_70.c
 
 # Compatability code for NetBSD 8.0
-SRCS+=	kern_mod_80.c
+SRCS+=	kern_mod_80.c if_media_80.c
 
 # More compatibility code for NetBSD 5.0
 .PATH:	${S}/opencrypto

Index: src/sys/compat/common/compat_80_mod.c
diff -u src/sys/compat/common/compat_80_mod.c:1.3 src/sys/compat/common/compat_80_mod.c:1.4
--- src/sys/compat/common/compat_80_mod.c:1.3	Wed Apr 17 09:21:57 2019
+++ src/sys/compat/common/compat_80_mod.c	Fri May 17 07:37:11 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_80_mod.c,v 1.3 2019/04/17 09:21:57 msaitoh Exp $	*/
+/*	$NetBSD: compat_80_mod.c,v 1.4 2019/05/17 07:37:11 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: compat_80_mod.c,v 1.3 2019/04/17 09:21:57 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: compat_80_mod.c,v 1.4 2019/05/17 07:37:11 msaitoh Exp $");
 
 #include <sys/systm.h>
 #include <sys/module.h>
@@ -51,6 +51,7 @@ compat_80_init(void)
 {
 
 	kern_mod_80_init();
+	ifmedia_80_init();
 
 	return 0;
 }
@@ -59,6 +60,7 @@ int
 compat_80_fini(void)
 {
 
+	ifmedia_80_fini();
 	kern_mod_80_fini();
 
 	return 0;
Index: src/sys/compat/common/files.common
diff -u src/sys/compat/common/files.common:1.3 src/sys/compat/common/files.common:1.4
--- src/sys/compat/common/files.common:1.3	Mon Apr 15 02:07:11 2019
+++ src/sys/compat/common/files.common	Fri May 17 07:37:11 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.common,v 1.3 2019/04/15 02:07:11 pgoyette Exp $
+#	$NetBSD: files.common,v 1.4 2019/05/17 07:37:11 msaitoh Exp $
 
 #
 # Generic utility files, used by various compat options.
@@ -103,6 +103,7 @@ file	compat/common/uipc_usrreq_70.c		com
 # Compatability code for NetBSD 8.0
 file	compat/common/compat_80_mod.c		compat_80
 file	compat/common/kern_mod_80.c		compat_80
+file	compat/common/if_media_80.c		compat_80
 
 #
 # Sources for sysv ipc compatibility across the versions.

Index: src/sys/compat/common/compat_mod.h
diff -u src/sys/compat/common/compat_mod.h:1.4 src/sys/compat/common/compat_mod.h:1.5
--- src/sys/compat/common/compat_mod.h:1.4	Mon Apr 15 02:07:11 2019
+++ src/sys/compat/common/compat_mod.h	Fri May 17 07:37:11 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_mod.h,v 1.4 2019/04/15 02:07:11 pgoyette Exp $	*/
+/*	$NetBSD: compat_mod.h,v 1.5 2019/05/17 07:37:11 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -37,6 +37,8 @@ int compat_80_init(void);
 int compat_80_fini(void);
 void kern_mod_80_init(void);
 void kern_mod_80_fini(void);
+void ifmedia_80_init(void);
+void ifmedia_80_fini(void);
 #endif
 
 #ifdef COMPAT_70

Index: src/sys/compat/common/if_43.c
diff -u src/sys/compat/common/if_43.c:1.21 src/sys/compat/common/if_43.c:1.22
--- src/sys/compat/common/if_43.c:1.21	Tue Apr 16 04:31:42 2019
+++ src/sys/compat/common/if_43.c	Fri May 17 07:37:11 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_43.c,v 1.21 2019/04/16 04:31:42 msaitoh Exp $	*/
+/*	$NetBSD: if_43.c,v 1.22 2019/05/17 07:37:11 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1990, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_43.c,v 1.21 2019/04/16 04:31:42 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_43.c,v 1.22 2019/05/17 07:37:11 msaitoh Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -126,8 +126,8 @@ compat_cvtcmd(u_long cmd)
 		return SIOCADDMULTI;
 	case OSIOCDELMULTI:
 		return SIOCDELMULTI;
-	case OSIOCSIFMEDIA:
-		return SIOCSIFMEDIA;
+	case SIOCSIFMEDIA_43:
+		return SIOCSIFMEDIA_80;
 	case OSIOCGIFMTU:
 		return SIOCGIFMTU;
 	case OSIOCGIFDATA:

Index: src/sys/compat/netbsd32/netbsd32_ioctl.c
diff -u src/sys/compat/netbsd32/netbsd32_ioctl.c:1.102 src/sys/compat/netbsd32/netbsd32_ioctl.c:1.103
--- src/sys/compat/netbsd32/netbsd32_ioctl.c:1.102	Tue Apr 23 07:45:06 2019
+++ src/sys/compat/netbsd32/netbsd32_ioctl.c	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_ioctl.c,v 1.102 2019/04/23 07:45:06 msaitoh Exp $	*/
+/*	$NetBSD: netbsd32_ioctl.c,v 1.103 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.102 2019/04/23 07:45:06 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_ioctl.c,v 1.103 2019/05/17 07:37:12 msaitoh Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ntp.h"
@@ -1346,6 +1346,8 @@ netbsd32_ioctl(struct lwp *l,
 	case OSIOCSIFFLAGS32:
 		IOCTL_STRUCT_CONV_TO(OSIOCSIFFLAGS, oifreq);
 
+	case SIOCGIFMEDIA32_80:
+		IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA_80, ifmediareq);
 	case SIOCGIFMEDIA32:
 		IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq);
 

Index: src/sys/compat/netbsd32/netbsd32_ioctl.h
diff -u src/sys/compat/netbsd32/netbsd32_ioctl.h:1.66 src/sys/compat/netbsd32/netbsd32_ioctl.h:1.67
--- src/sys/compat/netbsd32/netbsd32_ioctl.h:1.66	Sun Nov 25 17:58:29 2018
+++ src/sys/compat/netbsd32/netbsd32_ioctl.h	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_ioctl.h,v 1.66 2018/11/25 17:58:29 mlelstv Exp $	*/
+/*	$NetBSD: netbsd32_ioctl.h,v 1.67 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -354,8 +354,9 @@ struct netbsd32_if_clonereq {
 #define	SIOCDELMULTI32	 _IOW('i', 50, struct netbsd32_ifreq)	/* del m'cast addr */
 #define	OSIOCDELMULTI32	 _IOW('i', 50, struct netbsd32_oifreq)	/* del m'cast addr */
 
-#define	SIOCSIFMEDIA32	_IOWR('i', 53, struct netbsd32_ifreq)	/* set net media */
-#define	OSIOCSIFMEDIA32	_IOWR('i', 53, struct netbsd32_oifreq)	/* set net media */
+#define	SIOCSIFMEDIA32_80	_IOWR('i', 53, struct netbsd32_ifreq)	/* set net media */
+#define	SIOCSIFMEDIA32_43	_IOWR('i', 53, struct netbsd32_oifreq)	/* set net media */
+#define	SIOCSIFMEDIA32		_IOWR('i', 55, struct netbsd32_ifreq)	/* set net media */
 
 #define	SIOCSIFGENERIC32 _IOW('i', 57, struct netbsd32_ifreq)	/* generic IF set op */
 #define	SIOCGIFGENERIC32 _IOWR('i', 58, struct netbsd32_ifreq)	/* generic IF get op */
@@ -403,7 +404,8 @@ struct netbsd32_ifmediareq {
 	netbsd32_intp	ifm_ulist;		/* media words */
 };
 /* from <sys/sockio.h> */
-#define	SIOCGIFMEDIA32	_IOWR('i', 54, struct netbsd32_ifmediareq) /* get net media */
+#define	SIOCGIFMEDIA32_80 _IOWR('i', 54, struct netbsd32_ifmediareq) /* get net media */
+#define	SIOCGIFMEDIA32	_IOWR('i', 56, struct netbsd32_ifmediareq) /* get net media */
 
 /* from net/if_pppoe.h */
 struct netbsd32_pppoediscparms {

Index: src/sys/compat/sys/sockio.h
diff -u src/sys/compat/sys/sockio.h:1.18 src/sys/compat/sys/sockio.h:1.19
--- src/sys/compat/sys/sockio.h:1.18	Tue Apr 16 04:31:42 2019
+++ src/sys/compat/sys/sockio.h	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: sockio.h,v 1.18 2019/04/16 04:31:42 msaitoh Exp $	*/
+/*	$NetBSD: sockio.h,v 1.19 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1990, 1993, 1994
@@ -112,7 +112,9 @@ struct oifdatareq {
 #define	OSIOCGIFCONF	 _IOWR('i', 36, struct ifconf)	/* get ifnet list */
 #define	OSIOCADDMULTI	 _IOW('i', 49, struct oifreq)	/* add m'cast addr */
 #define	OSIOCDELMULTI	 _IOW('i', 50, struct oifreq)	/* del m'cast addr */
-#define	OSIOCSIFMEDIA	 _IOWR('i', 53, struct oifreq)	/* set net media */
+#define	SIOCSIFMEDIA_43	 _IOWR('i', 53, struct oifreq)	/* set net media */
+#define	SIOCSIFMEDIA_80	 _IOWR('i', 53, struct ifreq)	/* set net media */
+#define	SIOCGIFMEDIA_80	 _IOWR('i', 54, struct ifmediareq) /* set net media */
 #define	OSIOCGIFMTU	 _IOWR('i', 126, struct oifreq)	/* get ifnet mtu */
 #define	OSIOCGIFDATA	 _IOWR('i', 128, struct oifdatareq) /* get if_data */
 #define	OSIOCZIFDATA	 _IOWR('i', 129, struct oifdatareq) /* get if_data then

Index: src/sys/kern/compat_stub.c
diff -u src/sys/kern/compat_stub.c:1.11 src/sys/kern/compat_stub.c:1.12
--- src/sys/kern/compat_stub.c:1.11	Mon Apr 29 16:12:30 2019
+++ src/sys/kern/compat_stub.c	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_stub.c,v 1.11 2019/04/29 16:12:30 roy Exp $	*/
+/* $NetBSD: compat_stub.c,v 1.12 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -264,6 +264,12 @@ struct uipc_unp_70_hook_t uipc_unp_70_ho
 struct sysvipc_sysctl_50_hook_t sysvipc_sysctl_50_hook;
 
 /*
+ * ifmedia_80 compatability
+ */
+struct ifmedia_80_pre_hook_t ifmedia_80_pre_hook;
+struct ifmedia_80_post_hook_t ifmedia_80_post_hook;
+
+/*
  * Hook for 32-bit machine name
  *
  * This probably would be better placed in compat/netbsd32/netbsd32_mod.c

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.453 src/sys/net/if.c:1.454
--- src/sys/net/if.c:1.453	Fri May 17 03:34:26 2019
+++ src/sys/net/if.c	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.453 2019/05/17 03:34:26 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.454 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.453 2019/05/17 03:34:26 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.454 2019/05/17 07:37:12 msaitoh Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -3134,7 +3134,7 @@ doifioctl(struct socket *so, u_long cmd,
 {
 	struct ifnet *ifp;
 	struct ifreq *ifr;
-	int error = 0, hook;
+	int error = 0;
 	u_long ocmd = cmd;
 	short oif_flags;
 	struct ifreq ifrb;
@@ -3142,6 +3142,8 @@ doifioctl(struct socket *so, u_long cmd,
 	int r;
 	struct psref psref;
 	int bound;
+	bool do_if43_post = false;
+	bool do_ifm80_post = false;
 
 	switch (cmd) {
 	case SIOCGIFCONF:
@@ -3163,14 +3165,15 @@ doifioctl(struct socket *so, u_long cmd,
 
 	ifr = data;
 	/* Pre-conversion */
-	MODULE_HOOK_CALL(if_cvtcmd_43_hook, (&cmd, ocmd), enosys(), hook);
-	if (hook != ENOSYS) {
-		if (cmd != ocmd) {
-			oifr = data;
-			data = ifr = &ifrb;
-			IFREQO2N_43(oifr, ifr);
-		}
+	MODULE_HOOK_CALL(if_cvtcmd_43_hook, (&cmd, ocmd), enosys(), error);
+	if (cmd != ocmd) {
+		oifr = data;
+		data = ifr = &ifrb;
+		IFREQO2N_43(oifr, ifr);
+		do_if43_post = true;
 	}
+	MODULE_HOOK_CALL(ifmedia_80_pre_hook, (ifr, &cmd, &do_ifm80_post),
+	    enosys(), error);
 
 	switch (cmd) {
 	case SIOCIFCREATE:
@@ -3281,7 +3284,10 @@ doifioctl(struct socket *so, u_long cmd,
 	}
 
 	/* Post-conversion */
-	if (cmd != ocmd)
+	if (do_ifm80_post && (error == 0))
+		MODULE_HOOK_CALL(ifmedia_80_post_hook, (ifr, cmd),
+		    enosys(), error);
+	if (do_if43_post)
 		IFREQN2O_43(oifr, ifr);
 
 	IFNET_UNLOCK(ifp);

Index: src/sys/net/if_media.c
diff -u src/sys/net/if_media.c:1.44 src/sys/net/if_media.c:1.45
--- src/sys/net/if_media.c:1.44	Fri May 10 08:24:54 2019
+++ src/sys/net/if_media.c	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_media.c,v 1.44 2019/05/10 08:24:54 msaitoh Exp $	*/
+/*	$NetBSD: if_media.c,v 1.45 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.44 2019/05/10 08:24:54 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.45 2019/05/17 07:37:12 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -350,6 +350,7 @@ _ifmedia_ioctl(struct ifnet *ifp, struct
 				error = E2BIG;	/* oops! */
 			free(kptr, M_TEMP);
 		}
+		/* Update with the real number */
 		ifmr->ifm_count = nwords;
 		break;
 	}
@@ -447,8 +448,8 @@ 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_SUBTYPE_MATCH(mword,
+		    ifmedia_baudrate_descriptions[i].ifmb_word))
 			return ifmedia_baudrate_descriptions[i].ifmb_baudrate;
 	}
 

Index: src/sys/net/if_media.h
diff -u src/sys/net/if_media.h:1.64 src/sys/net/if_media.h:1.65
--- src/sys/net/if_media.h:1.64	Fri May 10 06:33:14 2019
+++ src/sys/net/if_media.h	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_media.h,v 1.64 2019/05/10 06:33:14 msaitoh Exp $	*/
+/*	$NetBSD: if_media.h,v 1.65 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
@@ -93,7 +93,8 @@
  * if_media Options word:
  *	Bits	Use
  *	----	-------
- *	0-4	Media subtype		MAX SUBTYPE == 31!
+ *	0-4	Media subtype	MAX SUBTYPE == 255 for ETH and 31 for others
+ *				See below (IFM_ETHER part) for the detail.
  *	5-7	Media type
  *	8-15	Type specific options
  *	16-18	Mode (for multi-mode devices)
@@ -105,14 +106,19 @@
  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  *  +-------+---------------+-+-----+---------------+-----+---------+
  *  |       |               |R|     |               |     |         |
- *  | IMASK |     GMASK     |F|MMASK|     OMASK     |NMASK|  TMASK  |
- *  |       |               |U|     |               |     |         |
- *  +-------+---------------+-+-----+---------------+-----+---------+
+ *  | IMASK |     GMASK     |F|MMASK+-----+ OMASK   |NMASK|  TMASK  |
+ *  |       |               |U|     |XTMSK|         |     |         |
+ *  +-------+---------------+-+-----+-----+---------+-----+---------+
  *   <----->                   <--->                 <--->
  *  IFM_INST()               IFM_MODE()            IFM_TYPE()
  *
- *           <------------->         <------------->       <------->
- *                        IFM_OPTIONS()                  IFM_SUBTYPE()
+ *                              IFM_SUBTYPE(other than ETH)<------->
+ *
+ *                                   <---> IFM_SUBTYPE(ETH)<------->
+ *                                         
+ *
+ *           <------------->         <------------->
+ *                        IFM_OPTIONS()
  */
 
 /*
@@ -131,14 +137,16 @@
  * 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(dt, t)						      \
+	(IFM_TYPE(dt) == 0 || IFM_TYPE(dt) == IFM_TYPE(t))
+#define	IFM_TYPE_SUBTYPE_MATCH(dt, t)					      \
+	(IFM_TYPE(dt) == IFM_TYPE(t) && IFM_SUBTYPE(dt) == IFM_SUBTYPE(t))
 #define	IFM_INST(x)	(((x) & IFM_IMASK) >> IFM_ISHIFT)
 #define	IFM_OPTIONS(x)	((x) & (IFM_OMASK | IFM_GMASK))
 #define	IFM_MODE(x)	((x) & IFM_MMASK)
 
-#define	IFM_TYPE_MATCH(dt, t)						\
-	(IFM_TYPE(dt) == 0 || IFM_TYPE(dt) == IFM_TYPE(t))
-
 #define	IFM_INST_MAX	IFM_INST(IFM_IMASK)
 #define	IFM_INST_ANY	((u_int) -1)
 
@@ -197,7 +205,16 @@
 
 /*
  * 1: Ethernet (IFM_ETHER)
- */
+ *
+ * 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_SUBTYPE(x) (((x) & IFM_TMASK) |			      \
+	    (((x) & (_IFM_ETH_XTMASK >> IFM_ETH_XSHIFT)) << IFM_ETH_XSHIFT))
+#define IFM_ETHER_SUBTYPE_GET(x) ((x) & (IFM_TMASK | _IFM_ETH_XTMASK))
+#define _IFM_EX(x)	IFM_ETHER_SUBTYPE(x) /* internal shorthand */
+
 #define	IFM_10_T	3		/* 10BaseT - RJ45 */
 #define	IFM_10_2	4		/* 10Base2 - Thinnet */
 #define	IFM_10_5	5		/* 10Base5 - AUI */
@@ -226,10 +243,86 @@
 #define	IFM_2500_KX	28		/* 2500base-KX backplane */
 #define	IFM_2500_T	29		/* 2500base-T - RJ45 */
 #define	IFM_5000_T	30		/* 5Gbase-T - RJ45 */
+#define	IFM_OTHER	31		/*
+					 * This number indicates "Not listed".
+					 * and also used for backward
+					 * compatibility.
+					 */
+#define	IFM_1000_SGMII	_IFM_EX(32)	/* 1G SGMII */
+#define	IFM_5000_KR	_IFM_EX(33)	/* 5GBASE-KR backplane */
+#define	IFM_10G_AOC	_IFM_EX(34)	/* 10G active optical cable */
+#define	IFM_10G_CR1	_IFM_EX(35)	/* 10GBASE-CR1 Twinax splitter */
+#define	IFM_10G_ER	_IFM_EX(36)	/* 10GBASE-ER */
+#define	IFM_10G_KR	_IFM_EX(37)	/* 10GBASE-KR backplane */
+#define	IFM_10G_KX4	_IFM_EX(38)	/* 10GBASE-KX4 backplane */
+#define	IFM_10G_LX4	_IFM_EX(39)	/* 10GBASE-LX4 */
+#define	IFM_10G_SFI	_IFM_EX(40)	/* 10G SFI */
+#define	IFM_10G_ZR	_IFM_EX(41)	/* 10GBASE-ZR */
+#define	IFM_20G_KR2	_IFM_EX(42)	/* 20GBASE-KR2 backplane */
+#define	IFM_25G_AOC	_IFM_EX(43)	/* 25G active optical cable */
+#define	IFM_25G_AUI	_IFM_EX(44)	/* 25G-AUI-C2C (chip to chip) */
+#define	IFM_25G_CR	_IFM_EX(45)	/* 25GBASE-CR (twinax) */
+#define	IFM_25G_CR_S	_IFM_EX(47)	/* 25GBASE-CR-S (CR short) */
+#define	IFM_25G_ER	_IFM_EX(48)	/* 25GBASE-ER */
+#define	IFM_25G_KR	_IFM_EX(49)	/* 25GBASE-KR */
+#define	IFM_25G_KR_S	_IFM_EX(50)	/* 25GBASE-KR-S (KR short) */
+#define	IFM_25G_LR	_IFM_EX(51)	/* 25GBASE-LR */
+#define	IFM_25G_SR	_IFM_EX(52)	/* 25GBASE-SR */
+#define	IFM_25G_T	_IFM_EX(53)	/* 25GBASE-T - RJ45 */
+#define	IFM_40G_AOC	_IFM_EX(54)	/* 40G Active Optical Cable */
+#define	IFM_40G_CR4	_IFM_EX(55)	/* 40GBASE-CR4 */
+#define	IFM_40G_ER4	_IFM_EX(56)	/* 40GBASE-ER4 */
+#define	IFM_40G_FR	_IFM_EX(57)	/* 40GBASE-FR */
+#define	IFM_40G_KR4	_IFM_EX(58)	/* 40GBASE-KR4 */
+#define	IFM_40G_LR4	_IFM_EX(59)	/* 40GBASE-LR4 */
+#define	IFM_40G_SR4	_IFM_EX(60)	/* 40GBASE-SR4 */
+#define	IFM_40G_T	_IFM_EX(61)	/* 40GBASE-T */
+#define	IFM_40G_XLPPI	_IFM_EX(62)	/* 40G XLPPI */
+#define	IFM_50G_AUI1	_IFM_EX(63)	/* 50GAUI-1 */
+#define	IFM_50G_AUI2	_IFM_EX(64)	/* 50GAUI-2 */
+#define	IFM_50G_CR	_IFM_EX(65)	/* 50GBASE-CR */
+#define	IFM_50G_CR2	_IFM_EX(66)	/* 50GBASE-CR2 */
+#define	IFM_50G_FR	_IFM_EX(67)	/* 50GBASE-FR */
+#define	IFM_50G_KR	_IFM_EX(68)	/* 50GBASE-KR */
+#define	IFM_50G_KR2	_IFM_EX(69)	/* 50GBASE-KR2 */
+#define	IFM_50G_LAUI2	_IFM_EX(70)	/* 50GLAUI-2 */
+#define	IFM_50G_LR	_IFM_EX(71)	/* 50GBASE-LR (2Km) */
+#define	IFM_50G_LR10	_IFM_EX(72)	/* 50GBASE-LR10 (10Km) */
+#define	IFM_50G_SR	_IFM_EX(73)	/* 50GBASE-SR */
+#define	IFM_50G_SR2	_IFM_EX(74)	/* 50GBASE-SR2 */
+#define	IFM_56G_R4	_IFM_EX(75)	/* 56GBASE-R4 */
+#define	IFM_100G_CR2	_IFM_EX(76)	/* 100GBASE-CR2 (CP2?) */
+#define	IFM_100G_CR4	_IFM_EX(77)	/* 100GBASE-CR4 */
+#define	IFM_100G_CR10	_IFM_EX(78)	/* 100GBASE-CR10 */
+#define	IFM_100G_DR	_IFM_EX(79)	/* 100GBASE-DR */
+#define	IFM_100G_ER4	_IFM_EX(80)	/* 100GBASE-ER4 */
+#define	IFM_100G_KP4	_IFM_EX(81)	/* 100GBASE-KP4 */
+#define	IFM_100G_KR2	_IFM_EX(82)	/* 100GBASE-KR2 */
+#define	IFM_100G_KR4	_IFM_EX(83)	/* 100GBASE-KR4 */
+#define	IFM_100G_LR4	_IFM_EX(84)	/* 100GBASE-LR4 */
+#define	IFM_100G_SR2	_IFM_EX(85)	/* 100GBASE-SR2 */
+#define	IFM_100G_SR4	_IFM_EX(86)	/* 100GBASE-SR4 */
+#define	IFM_100G_SR10	_IFM_EX(87)	/* 100GBASE-SR10 */
+#define	IFM_200G_CR2	_IFM_EX(88)	/* 200GBASE-CR2 */
+#define	IFM_200G_CR4	_IFM_EX(89)	/* 200GBASE-CR4 */
+#define	IFM_200G_DR4	_IFM_EX(90)	/* 200GBASE-DR4 */
+#define	IFM_200G_FR4	_IFM_EX(91)	/* 200GBASE-FR4 */
+#define	IFM_200G_KR2	_IFM_EX(92)	/* 200GBASE-KR2 */
+#define	IFM_200G_KR4	_IFM_EX(93)	/* 200GBASE-KR4 */
+#define	IFM_200G_LR4	_IFM_EX(94)	/* 200GBASE-LR4 */
+#define	IFM_200G_SR4	_IFM_EX(95)	/* 200GBASE-SR4 */
+#define	IFM_400G_CR4	_IFM_EX(96)	/* 400GBASE-CR4 */
+#define	IFM_400G_DR4	_IFM_EX(97)	/* 400GBASE-DR4 */
+#define	IFM_400G_FR8	_IFM_EX(98)	/* 400GBASE-FR8 */
+#define	IFM_400G_KR4	_IFM_EX(99)	/* 400GBASE-KR4 */
+#define	IFM_400G_LR8	_IFM_EX(100)	/* 400GBASE-LR8 */
+#define	IFM_400G_SR16	_IFM_EX(101)	/* 400GBASE-SR16 */
 /* IFM_OMASK bits */
 #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_XTMASK	0x0000e000	/* Media sub-type (MSB) */
+#define	IFM_ETH_XSHIFT	(13 - 5)	/* shift XTYPE next to TMASK */
 
 /* Ethernet flow control mask */
 #define	IFM_ETH_FMASK	(IFM_FLOW | IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE)
@@ -400,6 +493,7 @@ struct ifmedia_description {
 	{ IFM_ETHER | IFM_2500_T | IFM_FDX,	"2500baseT" },		\
 	{ IFM_ETHER | IFM_5000_T | IFM_FDX,	"5GBASE-T" },		\
 	{ IFM_ETHER | IFM_5000_T | IFM_FDX,	"5GbaseT" },		\
+	{ IFM_ETHER | IFM_OTHER,		"Other" },		\
 	{ IFM_ETHER | IFM_10G_LR | IFM_FDX,	"10GbaseLR" },		\
 	{ IFM_ETHER | IFM_10G_LR | IFM_FDX,	"10GLR" },		\
 	{ IFM_ETHER | IFM_10G_LR | IFM_FDX,	"10GBASE-LR" },		\
@@ -415,6 +509,75 @@ struct ifmedia_description {
 	{ IFM_ETHER | IFM_10G_CX4 | IFM_FDX,	"10GBASE-CX4" },	\
 	{ IFM_ETHER | IFM_2500_SX | IFM_FDX,	"2500baseSX" },		\
 	{ IFM_ETHER | IFM_2500_SX | IFM_FDX,	"2500SX" },		\
+	{ IFM_ETHER | IFM_1000_SGMII | IFM_FDX,	"1000BASE-SGMII" },	\
+	{ IFM_ETHER | IFM_5000_KR | IFM_FDX,	"5GBASE-KR" },		\
+	{ IFM_ETHER | IFM_10G_AOC | IFM_FDX,	"10GBASE-AOC" },	\
+	{ IFM_ETHER | IFM_10G_CR1 | IFM_FDX,	"10GBASE-CR1" },	\
+	{ IFM_ETHER | IFM_10G_ER | IFM_FDX,	"10GBASE-ER" },		\
+	{ IFM_ETHER | IFM_10G_KR | IFM_FDX,	"10GBASE-KR" },		\
+	{ IFM_ETHER | IFM_10G_KX4 | IFM_FDX,	"10GBASE-KX4" },	\
+	{ IFM_ETHER | IFM_10G_LX4 | IFM_FDX,	"10GBASE-LX4" },	\
+	{ IFM_ETHER | IFM_10G_SFI | IFM_FDX,	"10GBASE-SFI" },	\
+	{ IFM_ETHER | IFM_10G_ZR | IFM_FDX,	"10GBASE-ZR" },		\
+	{ IFM_ETHER | IFM_20G_KR2 | IFM_FDX,	"20GBASE-KR2" },	\
+	{ IFM_ETHER | IFM_25G_AOC | IFM_FDX,	"25GBASE-AOC" },	\
+	{ IFM_ETHER | IFM_25G_AUI | IFM_FDX,	"25G-AUI" },	\
+	{ IFM_ETHER | IFM_25G_CR | IFM_FDX,	"25GBASE-CR" },		\
+	{ IFM_ETHER | IFM_25G_CR_S | IFM_FDX,	"25GBASE-CR-S" },	\
+	{ IFM_ETHER | IFM_25G_ER | IFM_FDX,	"25GBASE-ER" },		\
+	{ IFM_ETHER | IFM_25G_KR | IFM_FDX,	"25GBASE-KR" },		\
+	{ IFM_ETHER | IFM_25G_KR_S | IFM_FDX,	"25GBASE-KR-S" },	\
+	{ IFM_ETHER | IFM_25G_LR | IFM_FDX,	"25GBASE-LR" },		\
+	{ IFM_ETHER | IFM_25G_SR | IFM_FDX,	"25GBASE-SR" },		\
+	{ IFM_ETHER | IFM_25G_T | IFM_FDX,	"25GBASE-T" },		\
+	{ IFM_ETHER | IFM_40G_AOC | IFM_FDX,	"40GBASE-AOC" },	\
+	{ IFM_ETHER | IFM_40G_CR4 | IFM_FDX,	"40GBASE-CR4" },	\
+	{ IFM_ETHER | IFM_40G_ER4 | IFM_FDX,	"40GBASE-ER4" },	\
+	{ IFM_ETHER | IFM_40G_FR | IFM_FDX,	"40GBASE-FR" },		\
+	{ IFM_ETHER | IFM_40G_KR4 | IFM_FDX,	"40GBASE-KR4" },	\
+	{ IFM_ETHER | IFM_40G_LR4 | IFM_FDX,	"40GBASE-LR4" },	\
+	{ IFM_ETHER | IFM_40G_SR4 | IFM_FDX,	"40GBASE-SR4" },	\
+	{ IFM_ETHER | IFM_40G_T | IFM_FDX,	"40GBASE-T" },		\
+	{ IFM_ETHER | IFM_40G_XLPPI | IFM_FDX,	"40G-XLPPI" },		\
+	{ IFM_ETHER | IFM_50G_AUI1 | IFM_FDX,	"50GAUI-1" },		\
+	{ IFM_ETHER | IFM_50G_AUI2 | IFM_FDX,	"50GAUI-2" },		\
+	{ IFM_ETHER | IFM_50G_CR | IFM_FDX,	"50GBASE-CR" },		\
+	{ IFM_ETHER | IFM_50G_CR2 | IFM_FDX,	"50GBASE-CR2" },	\
+	{ IFM_ETHER | IFM_50G_FR | IFM_FDX,	"50GBASE-FR" },		\
+	{ IFM_ETHER | IFM_50G_KR | IFM_FDX,	"50GBASE-KR" },		\
+	{ IFM_ETHER | IFM_50G_KR2 | IFM_FDX,	"50GBASE-KR2" },	\
+	{ IFM_ETHER | IFM_50G_LAUI2 | IFM_FDX,	"50GLAUI-2" },		\
+	{ IFM_ETHER | IFM_50G_LR | IFM_FDX,	"50GBASE-LR" },		\
+	{ IFM_ETHER | IFM_50G_LR10 | IFM_FDX,	"50GBASE-LR10" },	\
+	{ IFM_ETHER | IFM_50G_SR | IFM_FDX,	"50GBASE-SR" },		\
+	{ IFM_ETHER | IFM_50G_SR2 | IFM_FDX,	"50GBASE-SR2" },	\
+	{ IFM_ETHER | IFM_56G_R4 | IFM_FDX,	"56GBASE-R4" },		\
+	{ IFM_ETHER | IFM_100G_CR2 | IFM_FDX,	"100GBASE-CR2" },	\
+	{ IFM_ETHER | IFM_100G_CR4 | IFM_FDX,	"100GBASE-CR4" },	\
+	{ IFM_ETHER | IFM_100G_CR10 | IFM_FDX,	"100GBASE-CR10" },	\
+	{ IFM_ETHER | IFM_100G_DR | IFM_FDX,	"100GBASE-DR" },	\
+	{ IFM_ETHER | IFM_100G_ER4 | IFM_FDX,	"100GBASE-ER4" },	\
+	{ IFM_ETHER | IFM_100G_KP4 | IFM_FDX,	"100GBASE-KP4" },	\
+	{ IFM_ETHER | IFM_100G_KR2 | IFM_FDX,	"100GBASE-KR2" },	\
+	{ IFM_ETHER | IFM_100G_KR4 | IFM_FDX,	"100GBASE-KR4" },	\
+	{ IFM_ETHER | IFM_100G_LR4 | IFM_FDX,	"100GBASE-LR4" },	\
+	{ IFM_ETHER | IFM_100G_SR2 | IFM_FDX,	"100GBASE-SR2" },	\
+	{ IFM_ETHER | IFM_100G_SR4 | IFM_FDX,	"100GBASE-SR4" },	\
+	{ IFM_ETHER | IFM_100G_SR10 | IFM_FDX,	"100GBASE-SR10" },	\
+	{ IFM_ETHER | IFM_200G_CR2 | IFM_FDX,	"200GBASE-CR2" },	\
+	{ IFM_ETHER | IFM_200G_CR4 | IFM_FDX,	"200GBASE-CR4" },	\
+	{ IFM_ETHER | IFM_200G_DR4 | IFM_FDX,	"200GBASE-DR4" },	\
+	{ IFM_ETHER | IFM_200G_FR4 | IFM_FDX,	"200GBASE-FR4" },	\
+	{ IFM_ETHER | IFM_200G_KR2 | IFM_FDX,	"200GBASE-KR2" },	\
+	{ IFM_ETHER | IFM_200G_KR4 | IFM_FDX,	"200GBASE-KR4" },	\
+	{ IFM_ETHER | IFM_200G_LR4 | IFM_FDX,	"200GBASE-LR4" },	\
+	{ IFM_ETHER | IFM_200G_SR4 | IFM_FDX,	"200GBASE-SR4" },	\
+	{ IFM_ETHER | IFM_400G_CR4 | IFM_FDX,	"400GBASE-CR4" },	\
+	{ IFM_ETHER | IFM_400G_DR4 | IFM_FDX,	"400GBASE-DR4" },	\
+	{ IFM_ETHER | IFM_400G_FR8 | IFM_FDX,	"400GBASE-FR8" },	\
+	{ IFM_ETHER | IFM_400G_KR4 | IFM_FDX,	"400GBASE-KR4" },	\
+	{ IFM_ETHER | IFM_400G_LR8 | IFM_FDX,	"400GBASE-LR8" },	\
+	{ IFM_ETHER | IFM_400G_SR16 | IFM_FDX,	"400GBASE-SR16" },	\
 									\
 	{ IFM_TOKEN | IFM_TOK_STP4,	"DB9/4Mbit" },			\
 	{ IFM_TOKEN | IFM_TOK_STP4,	"4STP" },			\
@@ -556,7 +719,76 @@ struct ifmedia_baudrate {
 	{ IFM_ETHER | IFM_1000_KX,	IF_Mbps(1000ULL) },		\
 	{ IFM_ETHER | IFM_2500_KX,	IF_Mbps(2500ULL) },		\
 	{ IFM_ETHER | IFM_2500_T,	IF_Mbps(2500ULL) },		\
-	{ IFM_ETHER | IFM_5000_T,	IF_Mbps(5000ULL) },		\
+	{ IFM_ETHER | IFM_5000_T,	IF_Gbps(5) },			\
+	{ IFM_ETHER | IFM_1000_SGMII,	IF_Gbps(1) },			\
+	{ IFM_ETHER | IFM_5000_KR,	IF_Gbps(5) },			\
+	{ IFM_ETHER | IFM_10G_AOC,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_CR1,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_ER,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_KR,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_KX4,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_LX4,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_SFI,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_10G_ZR,	IF_Gbps(10) },			\
+	{ IFM_ETHER | IFM_20G_KR2,	IF_Gbps(20) },			\
+	{ IFM_ETHER | IFM_25G_AOC,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_AUI,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_CR,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_CR_S,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_ER,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_KR,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_KR_S,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_LR,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_SR,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_25G_T,	IF_Gbps(25) },			\
+	{ IFM_ETHER | IFM_40G_AOC,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_CR4,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_ER4,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_FR,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_KR4,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_LR4,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_SR4,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_T,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_40G_XLPPI,	IF_Gbps(40) },			\
+	{ IFM_ETHER | IFM_50G_AUI1,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_AUI2,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_CR,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_CR2,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_FR,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_KR,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_KR2,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_LAUI2,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_LR,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_LR10,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_SR,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_50G_SR2,	IF_Gbps(50) },			\
+	{ IFM_ETHER | IFM_56G_R4,	IF_Gbps(56) },			\
+	{ IFM_ETHER | IFM_100G_CR2,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_CR4,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_CR10,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_DR,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_ER4,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_KP4,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_KR2,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_KR4,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_LR4,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_SR2,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_SR4,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_100G_SR10,	IF_Gbps(100) },			\
+	{ IFM_ETHER | IFM_200G_CR2,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_CR4,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_DR4,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_FR4,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_KR2,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_KR4,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_LR4,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_200G_SR4,	IF_Gbps(200) },			\
+	{ IFM_ETHER | IFM_400G_CR4,	IF_Gbps(400) },			\
+	{ IFM_ETHER | IFM_400G_DR4,	IF_Gbps(400) },			\
+	{ IFM_ETHER | IFM_400G_FR8,	IF_Gbps(400) },			\
+	{ IFM_ETHER | IFM_400G_KR4,	IF_Gbps(400) },			\
+	{ IFM_ETHER | IFM_400G_LR8,	IF_Gbps(400) },			\
+	{ IFM_ETHER | IFM_400G_SR16,	IF_Gbps(400) },			\
 									\
 	{ IFM_TOKEN | IFM_TOK_STP4,	IF_Mbps(4) },			\
 	{ IFM_TOKEN | IFM_TOK_STP16,	IF_Mbps(16) },			\

Index: src/sys/sys/compat_stub.h
diff -u src/sys/sys/compat_stub.h:1.15 src/sys/sys/compat_stub.h:1.16
--- src/sys/sys/compat_stub.h:1.15	Mon Apr 29 16:12:30 2019
+++ src/sys/sys/compat_stub.h	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_stub.h,v 1.15 2019/04/29 16:12:30 roy Exp $	*/
+/*	$NetBSD: compat_stub.h,v 1.16 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -336,6 +336,15 @@ MODULE_HOOK(uipc_unp_70_hook, struct mbu
 #include <sys/sysctl.h>
 MODULE_HOOK(sysvipc_sysctl_50_hook, int, (SYSCTLFN_PROTO));
 
+/*
+ * ifmedia_80 compatibility
+ */
+
+struct ifmedia;
+struct ifreq;
+MODULE_HOOK(ifmedia_80_pre_hook, int, (struct ifreq *, u_long *, bool *));
+MODULE_HOOK(ifmedia_80_post_hook, int, (struct ifreq *, u_long));
+
 /* 
  * Hook for 32-bit machine name
  * 

Index: src/sys/sys/sockio.h
diff -u src/sys/sys/sockio.h:1.36 src/sys/sys/sockio.h:1.37
--- src/sys/sys/sockio.h:1.36	Fri Dec 21 08:58:08 2018
+++ src/sys/sys/sockio.h	Fri May 17 07:37:12 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: sockio.h,v 1.36 2018/12/21 08:58:08 msaitoh Exp $	*/
+/*	$NetBSD: sockio.h,v 1.37 2019/05/17 07:37:12 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1990, 1993, 1994
@@ -90,8 +90,8 @@
 #define	SIOCGETVIFCNT	_IOWR('u', 51, struct sioc_vif_req)/* vif pkt cnt */
 #define	SIOCGETSGCNT	_IOWR('u', 52, struct sioc_sg_req) /* sg pkt cnt */
 
-#define	SIOCSIFMEDIA	_IOWR('i', 53, struct ifreq)	/* set net media */
-#define	SIOCGIFMEDIA	_IOWR('i', 54, struct ifmediareq) /* get net media */
+#define	SIOCSIFMEDIA	_IOWR('i', 55, struct ifreq)	/* set net media */
+#define	SIOCGIFMEDIA	_IOWR('i', 56, struct ifmediareq) /* get net media */
 
 #define	SIOCSIFGENERIC	 _IOW('i', 57, struct ifreq)	/* generic IF set op */
 #define	SIOCGIFGENERIC	_IOWR('i', 58, struct ifreq)	/* generic IF get op */

Added files:

Index: src/sys/compat/common/if_media_80.c
diff -u /dev/null src/sys/compat/common/if_media_80.c:1.1
--- /dev/null	Fri May 17 07:37:12 2019
+++ src/sys/compat/common/if_media_80.c	Fri May 17 07:37:11 2019
@@ -0,0 +1,192 @@
+/*	$NetBSD: if_media_80.c,v 1.1 2019/05/17 07:37:11 msaitoh Exp $	*/
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997
+ *	Jonathan Stone and Jason R. Thorpe.  All rights reserved.
+ *
+ * This software is derived from information provided by Matt Thomas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Jonathan Stone
+ *	and Jason R. Thorpe for the NetBSD Project.
+ * 4. The names of the authors may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/syscallargs.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/compat_stub.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <compat/sys/sockio.h>
+#include <compat/common/compat_mod.h>
+
+static void
+ifmword_n2o(int *oldwd, int *newwd)
+{
+
+	if (IFM_SUBTYPE(*newwd) > IFM_OTHER)
+		*oldwd = (*newwd & ~(_IFM_ETH_XTMASK | IFM_TMASK)) | IFM_OTHER;
+	else
+		*oldwd = *newwd;
+}
+
+/*ARGSUSED*/
+static int
+compat_ifmediareq_pre(struct ifreq *ifr, u_long *cmd, bool *do_post)
+{
+	struct ifmediareq *ifmr = (struct ifmediareq *)ifr;
+
+	switch (*cmd) {
+	case SIOCSIFMEDIA_80:
+		*cmd = SIOCSIFMEDIA; /* Convert to new one */
+		if ((IFM_TYPE(ifr->ifr_media) == IFM_ETHER) &&
+		    IFM_SUBTYPE(ifr->ifr_media) > IFM_OTHER) {
+			/* Clear unused bits to not to change to wrong media */
+			ifr->ifr_media &= ~_IFM_ETH_XTMASK;
+		}
+		return 0;
+	case SIOCGIFMEDIA_80:
+		*cmd = SIOCGIFMEDIA; /* Convert to new one */
+		if (ifmr->ifm_count != 0) {
+			/*
+			 * Tell the upper layer to try to convert each ifmedia
+			 * entry in the post process.
+			 */
+			*do_post = true;
+		}
+		return 0;
+	default:
+		return 0;
+	}
+}
+
+/*ARGSUSED*/
+static int
+compat_ifmediareq_post(struct ifreq *ifr, u_long cmd)
+{
+	struct ifmediareq *ifmr = (struct ifmediareq *)ifr;
+	size_t minwords;
+	int count, *kptr;
+	int error;
+
+	switch (cmd) {
+	case SIOCSIFMEDIA:
+		return 0;
+	case SIOCGIFMEDIA:
+		if (ifmr->ifm_count < 0)
+			return EINVAL;
+		
+		/*
+		 * ifmr->ifm_count was already ajusted in ifmedia_ioctl(), so
+		 * there is no problem to trust ifm_count.
+		 */
+		minwords = ifmr->ifm_count;
+		kptr = malloc(minwords * sizeof(*kptr), M_TEMP, M_WAITOK);
+		if (kptr == NULL)
+			return ENOMEM;
+
+		/*
+		 * Convert ifm_current and ifm_active.
+		 * It's not required to convert ifm_mask.
+		 */
+		ifmword_n2o(&ifmr->ifm_current, &ifmr->ifm_current);
+		ifmword_n2o(&ifmr->ifm_active, &ifmr->ifm_active);
+
+		/* Convert ifm_ulist array */
+		for (count = 0; count < minwords; count++) {
+			int oldmwd;
+
+			error = ufetch_int(&ifmr->ifm_ulist[count], &oldmwd);
+			if (error != 0)
+				goto out;
+			ifmword_n2o(&kptr[count], &oldmwd);
+		}
+
+		/* Copy to userland in old format */
+		error = copyout(kptr, ifmr->ifm_ulist,
+		    minwords * sizeof(*kptr));
+out:
+		free(kptr, M_TEMP);
+		return error;
+	default:
+		return 0;
+	}
+}
+
+void
+ifmedia_80_init(void)
+{
+
+	MODULE_HOOK_SET(ifmedia_80_pre_hook, "ifmedia80",
+	    compat_ifmediareq_pre);
+	MODULE_HOOK_SET(ifmedia_80_post_hook, "ifmedia80",
+	    compat_ifmediareq_post);
+}
+
+void
+ifmedia_80_fini(void)
+{
+ 
+	MODULE_HOOK_UNSET(ifmedia_80_post_hook);
+	MODULE_HOOK_UNSET(ifmedia_80_pre_hook);
+}

Reply via email to