git: 6a73339365cf - main - if_vtnet: Support VIRTIO_NET_F_SPEED_DUPLEX
Bryan Venteicher
bryanv at FreeBSD.org
Tue Jan 19 05:08:19 UTC 2021
The branch main has been updated by bryanv:
URL: https://cgit.FreeBSD.org/src/commit/?id=6a73339365cf625b983355e4c5d960184cd09224
commit 6a73339365cf625b983355e4c5d960184cd09224
Author: Bryan Venteicher <bryanv at FreeBSD.org>
AuthorDate: 2021-01-19 04:55:24 +0000
Commit: Bryan Venteicher <bryanv at 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)
More information about the dev-commits-src-all
mailing list