git: 8d14fc8ba7f5 - main - igb: Report SR-IOV VF status

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Sun, 06 Sep 2026 14:01:02 UTC
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=8d14fc8ba7f55c873e866f392c17113d514acce9

commit 8d14fc8ba7f55c873e866f392c17113d514acce9
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-10 22:29:37 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-09-06 14:00:17 +0000

    igb: Report SR-IOV VF status
    
    Expose cached per-VF configuration through the iflib VF status method.
    Report mailbox handshake state, MAC address, access or trunk VLAN mode,
    hardware transmit and receive queue counts, administrator policy, and
    fault-containment state.
    
    The query does not issue mailbox requests or read hardware registers.
    
    Sponsored by:   BBOX.io
---
 sys/dev/e1000/if_em.c      |  1 +
 sys/dev/e1000/if_igb_iov.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/e1000/if_igb_iov.h |  2 ++
 3 files changed, 70 insertions(+)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 97040cc49d94..5587920a47b5 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -708,6 +708,7 @@ static device_method_t igb_if_methods[] = {
 	DEVMETHOD(ifdi_iov_init, igb_if_iov_init),
 	DEVMETHOD(ifdi_iov_uninit, igb_if_iov_uninit),
 	DEVMETHOD(ifdi_iov_vf_add, igb_if_iov_vf_add),
+	DEVMETHOD(ifdi_vf_status, igb_if_vf_status),
 #endif
 	DEVMETHOD_END
 };
diff --git a/sys/dev/e1000/if_igb_iov.c b/sys/dev/e1000/if_igb_iov.c
index f75ba66d8987..48edf18f02b4 100644
--- a/sys/dev/e1000/if_igb_iov.c
+++ b/sys/dev/e1000/if_igb_iov.c
@@ -14,6 +14,8 @@
 #include <sys/sdt.h>
 #include <sys/time.h>
 
+#include <net/if_vf_status.h>
+
 #define	IGB_IOV_RAH_POOLSEL_SHIFT	18
 #define	IGB_IOV_RAH_POOLSEL_MASK	(0xffU << IGB_IOV_RAH_POOLSEL_SHIFT)
 #define	IGB_IOV_MAX_MAC_FILTERS		3
@@ -1993,6 +1995,71 @@ igb_iov_validate(struct e1000_softc *sc, u16 num_vfs)
 	return (0);
 }
 
+int
+igb_if_vf_status(if_ctx_t ctx, struct if_vf_status **statusp)
+{
+	struct e1000_softc *sc;
+	struct igb_vf *vf;
+	struct if_vf_info *info;
+	struct if_vf_status *status;
+	u_int num_queues;
+	int i;
+
+	sc = iflib_get_softc(ctx);
+	if (!sc->iov_mbx_retry_initialized)
+		return (EOPNOTSUPP);
+	num_queues = sc->hw.mac.type == e1000_82576 ?
+	    IGB_82576_VF_QUEUES : IGB_I350_VF_QUEUES;
+	status = if_vf_status_alloc(sc->num_vfs);
+	if (status == NULL)
+		return (ENOMEM);
+	for (i = 0; i < sc->num_vfs; i++) {
+		vf = &sc->vfs[i];
+		info = &status->vfs[i];
+		info->fields = IFVF_F_CONFIGURED | IFVF_F_INITIALIZED |
+		    IFVF_F_VLAN_MODE | IFVF_F_VLAN_COUNT |
+		    IFVF_F_NUM_TX_QUEUES | IFVF_F_NUM_RX_QUEUES |
+		    IFVF_F_ALLOW_SET_MAC |
+		    IFVF_F_ALLOW_SET_VLAN | IFVF_F_MAC_ANTI_SPOOF |
+		    IFVF_F_ALLOW_PROMISC | IFVF_F_TRAFFIC_ALLOWED |
+		    IFVF_F_FAULT_BLOCKED;
+		info->index = i;
+		info->configured = (vf->flags & IGB_VF_ACTIVE) != 0;
+		info->initialized = sc->iov_hw_active &&
+		    (vf->flags & IGB_VF_CTS) != 0;
+		if (!ETHER_IS_ZERO(vf->mac)) {
+			memcpy(info->mac, vf->mac, sizeof(info->mac));
+			info->fields |= IFVF_F_MAC;
+		}
+		if (vf->default_vlan == 0)
+			info->vlan_mode = IFVF_VLAN_TRUNK;
+		else {
+			info->vlan_mode = IFVF_VLAN_ACCESS;
+			info->vlan = vf->default_vlan;
+			info->vlan_pcp = 0;
+			info->vlan_proto = ETHERTYPE_VLAN;
+			info->fields |= IFVF_F_VLAN | IFVF_F_VLAN_PCP |
+			    IFVF_F_VLAN_PROTO;
+		}
+		info->vlan_count = vf->vlan_count;
+		info->tx_queue_count = num_queues;
+		info->rx_queue_count = num_queues;
+		info->allow_set_mac = (vf->flags & IGB_VF_CAP_MAC) != 0;
+		/* Access VFs cannot manage VLAN membership through the mailbox. */
+		info->allow_set_vlan = vf->default_vlan == 0;
+		info->mac_anti_spoof =
+		    (vf->flags & IGB_VF_MAC_ANTI_SPOOF) != 0;
+		info->allow_promisc =
+		    (vf->flags & IGB_VF_ALLOW_PROMISC) != 0;
+		info->fault_blocked =
+		    (vf->flags & IGB_VF_MDD_BLOCKED) != 0;
+		info->traffic_allowed = info->configured &&
+		    !info->fault_blocked;
+	}
+	*statusp = status;
+	return (0);
+}
+
 int
 igb_if_iov_init(if_ctx_t ctx, u16 num_vfs, const nvlist_t *config)
 {
diff --git a/sys/dev/e1000/if_igb_iov.h b/sys/dev/e1000/if_igb_iov.h
index 8bd576d47649..fd8053d9417f 100644
--- a/sys/dev/e1000/if_igb_iov.h
+++ b/sys/dev/e1000/if_igb_iov.h
@@ -24,6 +24,8 @@ int	igb_iov_validate(struct e1000_softc *, u16);
 int	igb_if_iov_init(if_ctx_t, u16, const nvlist_t *);
 void	igb_if_iov_uninit(if_ctx_t);
 int	igb_if_iov_vf_add(if_ctx_t, u16, const nvlist_t *);
+struct if_vf_status;
+int	igb_if_vf_status(if_ctx_t, struct if_vf_status **);
 void	igb_iov_initialize(struct e1000_softc *);
 void	igb_iov_handle_mbx(struct e1000_softc *);
 void	igb_iov_handle_mdd(struct e1000_softc *);