Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jan 2016 01:41:34 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r293720 - head/sys/dev/hyperv/netvsc
Message-ID:  <201601120141.u0C1fYbC080237@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Tue Jan 12 01:41:34 2016
New Revision: 293720
URL: https://svnweb.freebsd.org/changeset/base/293720

Log:
  hyperv/hn: Implement SIOC[SG]IFMEDIA support
  
  Many applications and kernel modules (e.g. bridge) rely on the ifmedia
  status report; give them what they want.
  
  Submitted by:		Dexuan Cui <decui microsoft com>
  Reviewed by:		Jun Su <junsu microsoftc com>, me, adrian
  Modified by:		me (minor)
  Original differential:	https://reviews.freebsd.org/D4611
  Differential Revision:	https://reviews.freebsd.org/D4852
  Approved by:		adrian (mentor)
  Sponsored by:		Microsoft OSTC

Modified:
  head/sys/dev/hyperv/netvsc/hv_net_vsc.h
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c

Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h	Tue Jan 12 01:30:51 2016	(r293719)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h	Tue Jan 12 01:41:34 2016	(r293720)
@@ -43,9 +43,13 @@
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/sx.h>
+
 #include <netinet/in.h>
 #include <netinet/tcp_lro.h>
 
+#include <net/if.h>
+#include <net/if_media.h>
+
 #include <dev/hyperv/include/hyperv.h>
 
 MALLOC_DECLARE(M_NETVSC);
@@ -985,6 +989,7 @@ typedef struct {
  */
 typedef struct hn_softc {
 	struct ifnet    *hn_ifp;
+	struct ifmedia	hn_media;
 	device_t        hn_dev;
 	uint8_t         hn_unit;
 	int             hn_carrier;

Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Tue Jan 12 01:30:51 2016	(r293719)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Tue Jan 12 01:41:34 2016	(r293720)
@@ -194,6 +194,8 @@ static void hn_ifinit(void *xsc);
 static int  hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
 static int  hn_start_locked(struct ifnet *ifp);
 static void hn_start(struct ifnet *ifp);
+static int hn_ifmedia_upd(struct ifnet *ifp);
+static void hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
 #ifdef HN_LRO_HIWAT
 static int hn_lro_hiwat_sysctl(SYSCTL_HANDLER_ARGS);
 #endif
@@ -264,6 +266,29 @@ static uint32_t get_transport_proto_type
 	return (ret_val);
 }
 
+static int
+hn_ifmedia_upd(struct ifnet *ifp __unused)
+{
+
+	return EOPNOTSUPP;
+}
+
+static void
+hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct hn_softc *sc = ifp->if_softc;
+
+	ifmr->ifm_status = IFM_AVALID;
+	ifmr->ifm_active = IFM_ETHER;
+
+	if (!sc->hn_carrier) {
+		ifmr->ifm_active |= IFM_NONE;
+		return;
+	}
+	ifmr->ifm_status |= IFM_ACTIVE;
+	ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
+}
+
 /*
  * NetVsc driver initialization
  * Note:  Filter init is no longer required
@@ -374,6 +399,12 @@ netvsc_attach(device_t dev)
 	ifp->if_snd.ifq_drv_maxlen = 511;
 	IFQ_SET_READY(&ifp->if_snd);
 
+	ifmedia_init(&sc->hn_media, 0, hn_ifmedia_upd, hn_ifmedia_sts);
+	ifmedia_add(&sc->hn_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+	ifmedia_set(&sc->hn_media, IFM_ETHER | IFM_AUTO);
+	/* XXX ifmedia_set really should do this for us */
+	sc->hn_media.ifm_media = sc->hn_media.ifm_cur->ifm_media;
+
 	/*
 	 * Tell upper layers that we support full VLAN capability.
 	 */
@@ -485,6 +516,7 @@ netvsc_detach(device_t dev)
 
 	hv_rf_on_device_remove(hv_device, HV_RF_NV_DESTROY_CHANNEL);
 
+	ifmedia_removeall(&sc->hn_media);
 	tcp_lro_free(&sc->hn_lro);
 
 	return (0);
@@ -1332,10 +1364,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 			error = 0;
 		}
 #endif
-		/* FALLTHROUGH */
+		error = EINVAL;
+		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:
-		error = EINVAL;
+		error = ifmedia_ioctl(ifp, ifr, &sc->hn_media, cmd);
 		break;
 	default:
 		error = ether_ioctl(ifp, cmd, data);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601120141.u0C1fYbC080237>