From nobody Sat Oct 31 18:58:48 2026 X-Original-To: dev-commits-src-branches@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 4jH6gs08ckz6x5pj for ; Sat, 31 Oct 2026 18:58:49 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jH6gr6KP4z3Hvw for ; Sat, 31 Oct 2026 18:58:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793473128; 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=MQpHMKTwbI+hxYwfxiB7/Aou8X6EPYrawORK0jSbdFY=; b=t0cWSJ6Kio5GMeG9V0UVkXGztrruSbW+nias1Y3GpeyY9EHcNfvcRjzIqqYwTYUkcrrEHB 2u1k6fsEnsk7TG4arY4eqIsl5kCD/HO5FaTd+ipccm9LJnHG0plRZXn49ti5MSGjwQIl6a LRe/CVpgMtlxUR0qlymMW4C353cdsOZ2y2wTYq6J7CFWXnGh6Jm4f2UA2pcG35gzNcWn8j ehCG/rgrt0UVWkjYtXt4fvdWYFeggnRN4VowxhQcrEYVbpXK8IVeqb+AMc9X4Xg3nv3a/W 6+ihyKSBgq3OLlUNqHZUf39POlp9R6pkVTa3xyEtAbF8xUBLYx18loNNr1/4mA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793473128; b=d8vim1ITYA5EQn02fxN3uVtnUMod/Lgtf1yCuQKQUAhxaVD/pdnPLVvVd9bbCAYlZkIgVo Z1yzrW2cnzrAmyJSdiFfs+Rg5UV0Nnm4HmBFdYbbx5Fm79UMb7pAOU0wAooGbLUIxYdoUL 0L54H76GwI3QN0Kj5xCo1cKeguIkFQBsP2I0f8JWLtK9Uwp8cgw9WdND+6pwCxihebzK/2 Dcu0HbxJDmMtx6mMGXZBKPC5AC2kjobT2gFsF6k/CTVkxulbPdQWSB1MC6buxKyWxEgbu1 Qk1d/J0S/aiozz1Fqc56j0+EJk7nISlUqOTI87MD1XUd/PNEI4cC6F4tO2Ae5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793473128; 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=MQpHMKTwbI+hxYwfxiB7/Aou8X6EPYrawORK0jSbdFY=; b=Rq6ACCLaUj4Q3xEJWrxwsTTN3Eu1pjAenjW4ycTRKUiZaKKfF1H3yMcCGlWEAT8Z9+jnTo jSTPXI1qOgs+/gZkovR7iuhcjccWq2F9Q14bvnayrJ6TX1LmASnVa6z7f4dXVYRSfOyBQZ w3ya/ZE0gC1z/d5Q6bgtlLOk/h7p/6qqvV7LHL+T4cthLS71FnRZSHZlt5Fz72hgEmNoLO 1THOb9bl2bIydDdO9nanJZ11soAOwKxlUpX+vuvYl/F5mvENzMQBm7AggZ/dkYOc7iOZQ1 UpNHKIubNp/gDkWnDQVp6QZL300wbzSBSA2zHDl/LWJmHoL0Oybru7gs6KQmAw== 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 4jH6gr60C7zPCT for ; Sat, 31 Oct 2026 18:58:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 23d38 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 31 Oct 2026 18:58:48 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 85524d4891ab - stable/15 - cxgbe: Report SR-IOV VF status List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD src repository 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/stable/15 X-Git-Reftype: branch X-Git-Commit: 85524d4891abe3eb11ae79216d2dae2ca154fa36 Auto-Submitted: auto-generated Date: Sat, 31 Oct 2026 18:58:48 +0000 Message-Id: <6ae63a68.23d38.40b04b52@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=85524d4891abe3eb11ae79216d2dae2ca154fa36 commit 85524d4891abe3eb11ae79216d2dae2ca154fa36 Author: Kevin Bowling AuthorDate: 2026-08-08 17:53:29 +0000 Commit: Kevin Bowling CommitDate: 2026-10-31 18:57:04 +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. On stable/15, append the cached status fields to port_info to preserve all existing member offsets. Reject VF adapters before accessing the extended portion, which an older VF module does not allocate. Reviewed by: jhb Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D58741 (cherry picked from commit e1c59c909d63931dae999479ecd01e3cf1855543) --- sys/dev/cxgbe/adapter.h | 12 +++++ sys/dev/cxgbe/t4_iov.c | 115 +++++++++++++++++++++++++++++++++++++++--------- sys/dev/cxgbe/t4_main.c | 66 +++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 22 deletions(-) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 6ff1f07ddf50..b84c673f75ab 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -302,6 +302,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; @@ -338,6 +345,11 @@ struct port_info { uint64_t fcs_base; struct sysctl_ctx_list ctx; + + /* Keep existing member offsets for stable/15 module consumers. */ + struct t4_vf_info *iov_vfs; + uint16_t iov_num_vfs; + bool iov_status_supported; }; #define IS_MAIN_VI(vi) ((vi) == &((vi)->pi->vi[0])) 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 396bd5a8b6a6..77ff10bc861b 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) @@ -2865,6 +2868,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) @@ -3055,6 +3059,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 ((sc->flags & IS_VF) != 0 || !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) {