From nobody Tue Sep 29 07:20:28 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hv8hr6TF5z6WqjJ for ; Tue, 29 Sep 2026 07:20:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hv8hr5wQ2z4MDw for ; Tue, 29 Sep 2026 07:20:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790666428; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OfudIJ47TDJMlZaoNpVHKjiVi2srE3RfsDMIPGlOvJs=; b=noOsXMKjhMnx7FU4jSvC2sSMB9e4FIHh1y9sDlCYbVlbn8hbZM77mSqD/qZj0jM3KVgYeE EPlwicRhj4yVtoP93L/FmdsCTxryrmxpiDZ+6EhzfNNu+aJVeTwj/VP7gfLImGBdnmHjRH ik1sGWor+hUliSPOQn/xAJOLhG+zOZXqNMtx12yqWEefEYBMR33X+lX68zU90mFdGmnK69 zNBz+lc3uWw0fm6R7NqOR8romP7X/CghOEojbT9idRYl6mgoQF8p9RyhXCO7jvqVaeMnTh q4eYsNB/y9lMqDSzzJek7yyi49U0IfpnUVvXM7/zODziVxwaV2FCfP3/HTOBsw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1790666428; b=FC0Ho89B2CEnPa4VOPJSDHo6eV+6pf13dmKU/z2pfOG6UCLZAbNX1CVfTBTL//BbFneB+m +kjXdOnh403wtWVQYYQ6Ku1SJtqSYzaDXV6GrKdC4Jd+seACslR/VrTqJiLgaGoyOPX9ba AIHLzkIog9YdsIX5S+puSi49OCkpkZmwEnPRrnlZMUNjCu7z4TIBhFQgQfwCI6x0ke9gM8 jgDF6HHkY5gAzCf2+dU2LypPCXkFTIJz6e5RGrCVsbl+m7iHabmhAumKumqz+dcixPkm2z lkcTdnLAywmPS0IKy8YOd8exGAaZDrzc1kRd7l63LlawMusxMMh3PGCzXIo3XQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790666428; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OfudIJ47TDJMlZaoNpVHKjiVi2srE3RfsDMIPGlOvJs=; b=C/97M8bGc7VX9Lon+l0kqrweEljUmmnKMh13uphmgGyhLLQgoeTFfrhwfgB2lPH1Vg+LDe gndg1j5jRj0eBK8Xcb5JQfI+CcEYeK9IyYPuCovm6rNL6kHD36IFz2QJsQtMT/W7+CrWO3 dqVhklpVe20mL7yBAzuEz7DDal0Z1ym5oupcBHq0hQI18CnrRfD/SDFqfx+vwL3R3QFEN/ q+Lu1t8bKXBTbxUOwcroBZrPLZ9+5BvwL58pWvgC4qkzkfe1Sm/4Asiyjelaf2khRd2z7A lj3bygNIo4FpTih2gUTJi1rcG5yUP+DtmRE3RUK7gF8T/ngWM9dYedEmD0H6uQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hv8hr4zdCz141n for ; Tue, 29 Sep 2026 07:20:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 47e1f by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 29 Sep 2026 07:20:28 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: e1c59c909d63 - main - cxgbe: Report SR-IOV VF status List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e1c59c909d63931dae999479ecd01e3cf1855543 Auto-Submitted: auto-generated Date: Tue, 29 Sep 2026 07:20:28 +0000 Message-Id: <6abb66bc.47e1f.4d8a4c41@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=e1c59c909d63931dae999479ecd01e3cf1855543 commit e1c59c909d63931dae999479ecd01e3cf1855543 Author: Kevin Bowling AuthorDate: 2026-08-08 17:53:29 +0000 Commit: Kevin Bowling CommitDate: 2026-09-29 07:19:24 +0000 cxgbe: Report SR-IOV VF status Retain the PF-accepted MAC and VLAN settings from the per-port t4iov companion and expose them through the corresponding cxgbe ifnet. Publish, snapshot, and destroy the cache under the existing adapter synchronized-operation mechanism so status queries cannot race IOV configuration or teardown. Track successful t4iov attachment independently of the active VF count. Restrict reporting to the port main VI, return an empty status for a supported but unconfigured PF, and omit status from VF and auxiliary VIs. Reviewed by: jhb Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D58741 --- sys/dev/cxgbe/adapter.h | 10 +++++ sys/dev/cxgbe/t4_iov.c | 115 +++++++++++++++++++++++++++++++++++++++--------- sys/dev/cxgbe/t4_main.c | 66 +++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 22 deletions(-) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 8c5cf052b689..df2ab0d946f9 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -312,6 +312,13 @@ struct tx_sched_params { struct tx_cl_rl_params cl_rl[]; }; +struct t4_vf_info { + uint8_t mac[ETHER_ADDR_LEN]; + uint16_t vlan; + bool configured; + bool access_vlan; +}; + struct port_info { device_t dev; struct adapter *adapter; @@ -323,6 +330,9 @@ struct port_info { bool vxlan_tcam_entry; struct tx_sched_params *sched_params; + struct t4_vf_info *iov_vfs; + uint16_t iov_num_vfs; + bool iov_status_supported; struct mtx pi_lock; char lockname[16]; diff --git a/sys/dev/cxgbe/t4_iov.c b/sys/dev/cxgbe/t4_iov.c index 9ccf63fd6516..f40b2e986b33 100644 --- a/sys/dev/cxgbe/t4_iov.c +++ b/sys/dev/cxgbe/t4_iov.c @@ -49,6 +49,7 @@ struct t4iov_softc { device_t sc_dev; device_t sc_main; + struct port_info *sc_port; bool sc_attached; int pf; @@ -277,6 +278,7 @@ t4iov_attach_child(device_t dev) { struct t4iov_softc *sc; #ifdef PCI_IOV + struct adapter *adap; nvlist_t *pf_schema, *vf_schema; #endif device_t pdev; @@ -306,6 +308,16 @@ t4iov_attach_child(device_t dev) device_printf(dev, "Failed to initialize SR-IOV: %d\n", error); return (0); } + sc->sc_port = device_get_softc(pdev); + adap = device_get_softc(sc->sc_main); + error = begin_synchronized_op(adap, NULL, SLEEP_OK, "t4iovatt"); + if (error != 0) { + (void)pci_iov_detach(dev); + sc->sc_port = NULL; + return (error); + } + sc->sc_port->iov_status_supported = true; + end_synchronized_op(adap, 0); #endif sc->sc_attached = true; @@ -317,6 +329,7 @@ t4iov_detach_child(device_t dev) { struct t4iov_softc *sc; #ifdef PCI_IOV + struct adapter *adap; int error; #endif @@ -330,6 +343,13 @@ t4iov_detach_child(device_t dev) device_printf(dev, "Failed to disable SR-IOV\n"); return (error); } + adap = device_get_softc(sc->sc_main); + error = begin_synchronized_op(adap, NULL, SLEEP_OK, "t4iovdet"); + if (error != 0) + return (error); + sc->sc_port->iov_status_supported = false; + end_synchronized_op(adap, 0); + sc->sc_port = NULL; #endif sc->sc_attached = false; @@ -359,14 +379,46 @@ t4iov_detach(device_t dev) static int t4iov_iov_init(device_t dev, uint16_t num_vfs, const struct nvlist *config) { + struct t4iov_softc *sc; + struct t4_vf_info *vfs; + struct adapter *adap; + int error; /* XXX: The Linux driver sets up a vf_monitor task on T4 adapters. */ + sc = device_get_softc(dev); + MPASS(sc->sc_port != NULL); + vfs = mallocarray(num_vfs, sizeof(*vfs), M_CXGBE, + M_WAITOK | M_ZERO); + adap = device_get_softc(sc->sc_main); + error = begin_synchronized_op(adap, NULL, SLEEP_OK, "t4vfinit"); + if (error != 0) { + free(vfs, M_CXGBE); + return (error); + } + MPASS(sc->sc_port->iov_vfs == NULL); + sc->sc_port->iov_vfs = vfs; + sc->sc_port->iov_num_vfs = num_vfs; + end_synchronized_op(adap, 0); return (0); } static void t4iov_iov_uninit(device_t dev) { + struct t4iov_softc *sc; + struct t4_vf_info *vfs; + struct adapter *adap; + + sc = device_get_softc(dev); + MPASS(sc->sc_port != NULL); + adap = device_get_softc(sc->sc_main); + if (begin_synchronized_op(adap, NULL, SLEEP_OK, "t4vffini") != 0) + return; + vfs = sc->sc_port->iov_vfs; + sc->sc_port->iov_vfs = NULL; + sc->sc_port->iov_num_vfs = 0; + end_synchronized_op(adap, 0); + free(vfs, M_CXGBE); } static int @@ -376,6 +428,8 @@ t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config) struct t4iov_softc *sc; struct adapter *adap; uint8_t ma[ETHER_ADDR_LEN]; + uint16_t vlan; + bool access_vlan, has_mac, has_vlan; size_t size; int rc; @@ -383,27 +437,19 @@ t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config) MPASS(sc->sc_attached); MPASS(sc->sc_main != NULL); adap = device_get_softc(sc->sc_main); + memset(ma, 0, sizeof(ma)); + vlan = 0; + access_vlan = false; + has_mac = nvlist_exists_binary(config, "mac-addr"); + has_vlan = nvlist_exists_number(config, "vlan"); - if (nvlist_exists_binary(config, "mac-addr")) { + if (has_mac) { mac = nvlist_get_binary(config, "mac-addr", &size); bcopy(mac, ma, ETHER_ADDR_LEN); - - if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK, - "t4vfma") != 0) - return (ENXIO); - rc = -t4_set_vf_mac(adap, sc->pf, vfnum + 1, 1, ma); - end_synchronized_op(adap, 0); - if (rc != 0) { - device_printf(dev, - "Failed to set VF%d MAC address to " - "%02x:%02x:%02x:%02x:%02x:%02x, rc = %d\n", vfnum, - ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], rc); - return (rc); - } } - if (nvlist_exists_number(config, "vlan")) { - uint16_t vlan = nvlist_get_number(config, "vlan"); + if (has_vlan) { + vlan = nvlist_get_number(config, "vlan"); /* We can't restrict to VID 0 */ if (vlan == DOT1Q_VID_NULL) @@ -411,21 +457,46 @@ t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config) if (vlan == VF_VLAN_TRUNK) vlan = DOT1Q_VID_NULL; + else + access_vlan = true; + } + + if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK, + "t4vfadd") != 0) + return (ENXIO); - if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK, - "t4vfvl") != 0) - return (ENXIO); + if (has_mac) { + rc = -t4_set_vf_mac(adap, sc->pf, vfnum + 1, 1, ma); + if (rc != 0) { + device_printf(dev, + "Failed to set VF%d MAC address to " + "%02x:%02x:%02x:%02x:%02x:%02x, rc = %d\n", vfnum, + ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], rc); + goto out; + } + } + + if (has_vlan) { rc = t4_set_vlan_acl(adap, sc->pf, vfnum + 1, vlan); - end_synchronized_op(adap, 0); if (rc != 0) { device_printf(dev, "Failed to set VF%d VLAN to %d, rc = %d\n", vfnum, vlan, rc); - return (rc); + goto out; } } - return (0); + if (has_mac) + memcpy(sc->sc_port->iov_vfs[vfnum].mac, ma, + ETHER_ADDR_LEN); + sc->sc_port->iov_vfs[vfnum].vlan = vlan; + sc->sc_port->iov_vfs[vfnum].access_vlan = access_vlan; + sc->sc_port->iov_vfs[vfnum].configured = true; + rc = 0; + +out: + end_synchronized_op(adap, 0); + return (rc); } #endif diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 4aca284415df..726a5259dede 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -280,6 +282,7 @@ static driver_t vche_driver = { /* ifnet interface */ static void cxgbe_init(void *); static int cxgbe_ioctl(if_t, unsigned long, caddr_t); +static int cxgbe_vf_status(if_t, struct if_vf_status **); static int cxgbe_transmit(if_t, struct mbuf *); static void cxgbe_qflush(if_t); #if defined(KERN_TLS) || defined(RATELIMIT) @@ -2868,6 +2871,7 @@ cxgbe_vi_attach(device_t dev, struct vi_info *vi) if_setinitfn(ifp, cxgbe_init); if_setioctlfn(ifp, cxgbe_ioctl); + if_setvfstatusfn(ifp, cxgbe_vf_status); if_settransmitfn(ifp, cxgbe_transmit); if_setqflushfn(ifp, cxgbe_qflush); if (vi->pi->nvi > 1 || sc->flags & IS_VF) @@ -3058,6 +3062,68 @@ cxgbe_init(void *arg) end_synchronized_op(sc, 0); } +static int +cxgbe_vf_status(if_t ifp, struct if_vf_status **statusp) +{ + struct port_info *pi; + struct adapter *sc; + struct t4_vf_info *snapshot; + struct if_vf_info *vf; + struct if_vf_status *status; + struct vi_info *vi; + uint16_t num_vfs; + int error, i; + + vi = if_getsoftc(ifp); + pi = vi->pi; + sc = pi->adapter; + if (!IS_MAIN_VI(vi)) + return (EOPNOTSUPP); + error = begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, + "t4vfstat"); + if (error != 0) + return (error); + if (!pi->iov_status_supported) { + end_synchronized_op(sc, 0); + return (EOPNOTSUPP); + } + num_vfs = pi->iov_num_vfs; + snapshot = NULL; + if (num_vfs != 0) { + snapshot = mallocarray(num_vfs, sizeof(*snapshot), M_CXGBE, + M_WAITOK); + memcpy(snapshot, pi->iov_vfs, num_vfs * sizeof(*snapshot)); + } + end_synchronized_op(sc, 0); + + status = if_vf_status_alloc(num_vfs); + for (i = 0; i < num_vfs; i++) { + vf = &status->vfs[i]; + vf->fields = IFVF_F_CONFIGURED; + vf->index = i; + vf->configured = snapshot[i].configured; + if (!vf->configured) + continue; + vf->fields |= IFVF_F_VLAN_MODE; + if (!ETHER_IS_ZERO(snapshot[i].mac)) { + memcpy(vf->mac, snapshot[i].mac, sizeof(vf->mac)); + vf->fields |= IFVF_F_MAC; + } + if (snapshot[i].access_vlan) { + vf->vlan_mode = IFVF_VLAN_ACCESS; + vf->vlan = snapshot[i].vlan; + vf->vlan_proto = ETHERTYPE_VLAN; + vf->vlan_count = 1; + vf->fields |= IFVF_F_VLAN | IFVF_F_VLAN_PROTO | + IFVF_F_VLAN_COUNT; + } else + vf->vlan_mode = IFVF_VLAN_TRUNK; + } + free(snapshot, M_CXGBE); + *statusp = status; + return (0); +} + static int cxgbe_ioctl(if_t ifp, unsigned long cmd, caddr_t data) {