Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Jan 2021 05:08:14 GMT
From:      Bryan Venteicher <bryanv@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 6a73339365cf - main - if_vtnet: Support VIRTIO_NET_F_SPEED_DUPLEX
Message-ID:  <202101190508.10J58EK0085807@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by bryanv:

URL: https://cgit.FreeBSD.org/src/commit/?id=6a73339365cf625b983355e4c5d960184cd09224

commit 6a73339365cf625b983355e4c5d960184cd09224
Author:     Bryan Venteicher <bryanv@FreeBSD.org>
AuthorDate: 2021-01-19 04:55:24 +0000
Commit:     Bryan Venteicher <bryanv@FreeBSD.org>
CommitDate: 2021-01-19 04:55:24 +0000

    if_vtnet: Support VIRTIO_NET_F_SPEED_DUPLEX
    
    This features lets the guest driver know the speed and duplex of
    the "link". Instead of trying to support many media types based
    on the possible/likely speeds/duplexes, only use the speed to
    set the interface baudrate.
    
    Cleanup ifmedia code to match other drivers.
    
    Reviewed by: grehan (mentor)
    Differential Revision: https://reviews.freebsd.org/D27908
---
 sys/dev/virtio/network/if_vtnet.c    | 55 +++++++++++++++++++++++++-----------
 sys/dev/virtio/network/if_vtnetvar.h |  7 +----
 2 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index ca60e51c57d2..f20a798a16ed 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -210,6 +210,7 @@ static void	vtnet_update_vlan_filter(struct vtnet_softc *, int, uint16_t);
 static void	vtnet_register_vlan(void *, struct ifnet *, uint16_t);
 static void	vtnet_unregister_vlan(void *, struct ifnet *, uint16_t);
 
+static void	vtnet_update_speed_duplex(struct vtnet_softc *);
 static int	vtnet_is_link_up(struct vtnet_softc *);
 static void	vtnet_update_link_status(struct vtnet_softc *);
 static int	vtnet_ifmedia_upd(struct ifnet *);
@@ -987,7 +988,6 @@ vtnet_setup_interface(struct vtnet_softc *sc)
 	}
 
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-	ifp->if_baudrate = IF_Gbps(10);	/* Approx. */
 	ifp->if_softc = sc;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
 	    IFF_KNOWSEPOCH;
@@ -1005,10 +1005,19 @@ vtnet_setup_interface(struct vtnet_softc *sc)
 	IFQ_SET_READY(&ifp->if_snd);
 #endif
 
-	ifmedia_init(&sc->vtnet_media, IFM_IMASK, vtnet_ifmedia_upd,
-	    vtnet_ifmedia_sts);
-	ifmedia_add(&sc->vtnet_media, VTNET_MEDIATYPE, 0, NULL);
-	ifmedia_set(&sc->vtnet_media, VTNET_MEDIATYPE);
+	if (virtio_with_feature(dev, VIRTIO_NET_F_SPEED_DUPLEX)) {
+		uint32_t speed = virtio_read_dev_config_4(dev,
+		    offsetof(struct virtio_net_config, speed));
+		if (speed != -1)
+			ifp->if_baudrate = IF_Mbps(speed);
+		else
+			ifp->if_baudrate = IF_Gbps(10);	/* Approx. */
+	} else
+		ifp->if_baudrate = IF_Gbps(10);	/* Approx. */
+
+	ifmedia_init(&sc->vtnet_media, 0, vtnet_ifmedia_upd, vtnet_ifmedia_sts);
+	ifmedia_add(&sc->vtnet_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+	ifmedia_set(&sc->vtnet_media, IFM_ETHER | IFM_AUTO);
 
 	vtnet_get_hwaddr(sc);
 	ether_ifattach(ifp, sc->vtnet_hwaddr);
@@ -3598,6 +3607,27 @@ vtnet_unregister_vlan(void *arg, struct ifnet *ifp, uint16_t tag)
 	vtnet_update_vlan_filter(arg, 0, tag);
 }
 
+static void
+vtnet_update_speed_duplex(struct vtnet_softc *sc)
+{
+	device_t dev;
+	struct ifnet *ifp;
+	uint32_t speed;
+
+	dev = sc->vtnet_dev;
+	ifp = sc->vtnet_ifp;
+
+	/* BMV: Ignore duplex. */
+	if ((sc->vtnet_features & VIRTIO_NET_F_SPEED_DUPLEX) == 0)
+		speed = -1;
+	else
+		speed = virtio_read_dev_config_4(dev,
+		    offsetof(struct virtio_net_config, speed));
+
+	if (speed != -1)
+		ifp->if_baudrate = IF_Mbps(speed);
+}
+
 static int
 vtnet_is_link_up(struct vtnet_softc *sc)
 {
@@ -3624,12 +3654,12 @@ vtnet_update_link_status(struct vtnet_softc *sc)
 	int link;
 
 	ifp = sc->vtnet_ifp;
-
 	VTNET_CORE_LOCK_ASSERT(sc);
 	link = vtnet_is_link_up(sc);
 
 	/* Notify if the link status has changed. */
 	if (link != 0 && sc->vtnet_link_active == 0) {
+		vtnet_update_speed_duplex(sc);
 		sc->vtnet_link_active = 1;
 		if_link_state_change(ifp, LINK_STATE_UP);
 	} else if (link == 0 && sc->vtnet_link_active != 0) {
@@ -3641,16 +3671,7 @@ vtnet_update_link_status(struct vtnet_softc *sc)
 static int
 vtnet_ifmedia_upd(struct ifnet *ifp)
 {
-	struct vtnet_softc *sc;
-	struct ifmedia *ifm;
-
-	sc = ifp->if_softc;
-	ifm = &sc->vtnet_media;
-
-	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
-		return (EINVAL);
-
-	return (0);
+	return (EOPNOTSUPP);
 }
 
 static void
@@ -3666,7 +3687,7 @@ vtnet_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 	VTNET_CORE_LOCK(sc);
 	if (vtnet_is_link_up(sc) != 0) {
 		ifmr->ifm_status |= IFM_ACTIVE;
-		ifmr->ifm_active |= VTNET_MEDIATYPE;
+		ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
 	} else
 		ifmr->ifm_active |= IFM_NONE;
 	VTNET_CORE_UNLOCK(sc);
diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h
index 29a0dbbb734f..4189bb4d966f 100644
--- a/sys/dev/virtio/network/if_vtnetvar.h
+++ b/sys/dev/virtio/network/if_vtnetvar.h
@@ -211,12 +211,6 @@ vtnet_modern(struct vtnet_softc *sc)
  */
 #define VTNET_NOTIFY_RETRIES		4
 
-/*
- * Fake the media type. The host does not provide us with any real media
- * information.
- */
-#define VTNET_MEDIATYPE		 (IFM_ETHER | IFM_10G_T | IFM_FDX)
-
 /*
  * Number of words to allocate for the VLAN shadow table. There is one
  * bit for each VLAN.
@@ -313,6 +307,7 @@ CTASSERT(sizeof(struct vtnet_mac_filter) <= PAGE_SIZE);
      VIRTIO_NET_F_GUEST_ECN		| \
      VIRTIO_NET_F_MRG_RXBUF		| \
      VIRTIO_NET_F_MQ			| \
+     VIRTIO_NET_F_SPEED_DUPLEX		| \
      VIRTIO_RING_F_EVENT_IDX		| \
      VIRTIO_RING_F_INDIRECT_DESC)
 



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