From nobody Sat Oct 31 18:58:52 2026 X-Original-To: dev-commits-src-all@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 4jH6gw3BKdz6x67R for ; Sat, 31 Oct 2026 18:58:52 +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 4jH6gw28FSz3Hxd for ; Sat, 31 Oct 2026 18:58:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793473132; 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=5VBrMJRvS9vgQLMQziXRWZgdkmWLS7NP6gfkZ6pAfS4=; b=hNPA2cQWOMud+dIvwPKbywmm49ojPY9LPbbPpc2AdfTfe+L6JKu9gfaM8avKh347asCxzj PdxDntLkEqHFXpQt1HJtDNmG4n2DcUYHISmodbQvwYOMCRHM2+RJbOhH+AniFD1LR7MqDF Sm3kugPVTQ7Yd8zcLMFMCpn++xZGLA1v67fW4vUFdD+z+kRne0Mc+n2GljjRqwmWVUErNb Q8FEmoaBZ5+JYF+tn5+Ps4bhxpLihw4Tc6F7qbbEFwlsttoMP7+VdJ+YDU5MYtlt+UMIJo tU5dj21SdZhLGA6BwLzEVQrNiIF0i/QB7/QzkDSZrv/VNRZBG+IqJy4tSssPbg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793473132; b=XCzOvubIvQDgCmhImoeUnM3h7GNefOPZLvWWkZ0OamXM3n4RF/uQlAuRFrJEo52Ap8O2Z7 Sr/718YSECGoi5sPLu7w3bhK/CcxjvJQ221ojYrUZ6fg743iZu2cFZxEueAr8TjbfGszYf sC/Ie6n3gzk0tQf/vSxHVB48qY/QQmUaLRlsEruI+sqp0YTlAoyxXyWZ1sSVV5qlW0hmoM tFiZrNbMPAT0aqI3xpxWpAVct7lhQrixx/3FCbJRDbKem7iDg/tMeJQjABDil9T7lt7fj7 /sU9DS5PREwOqooTlXXWQZxYR0L5GcfbH8hFci8teyhebrZerXyh5EAdoo2UKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793473132; 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=5VBrMJRvS9vgQLMQziXRWZgdkmWLS7NP6gfkZ6pAfS4=; b=yhE3CwAr1UlJ4ALLyg4c58MbbO/NLWvK+NCu8N3VUGLUzDV5taqFgRBRXdwuwa1+oVriQE cadVFCLrFTHo78ghfDslVxWe4RfV4ABtYuRYHLOcxfZ5TSI0qIQSkeWyBFKqrzzwPfD9vQ Q92LVyc8cWGbS6iMZsR3C4am2qUCvZUiEDCgW0Bv648t8xCoBkqKrl1IrGdv5Hq4VH5OeL Y2MpHBF00cUy4UZnu7HQ3lAk5uuTbClfkzDv4uugCHUccd/pUQFftOlOESuH9OWQKOlO81 DrbfspjD3PCsLKtkre+2ctar0iGFFSn+6mByAwcsusZ/7ZFfS5zFHsBbznWokg== 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 4jH6gw1WV9zPZ5 for ; Sat, 31 Oct 2026 18:58:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 24aba by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 31 Oct 2026 18:58:52 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 47bf0dc861b6 - stable/15 - qlnx: Report SR-IOV VF status List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the 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: 47bf0dc861b69b4a2cd1bf18c0fc5cca96eed17d Auto-Submitted: auto-generated Date: Sat, 31 Oct 2026 18:58:52 +0000 Message-Id: <6ae63a6c.24aba.54c56660@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=47bf0dc861b69b4a2cd1bf18c0fc5cca96eed17d commit 47bf0dc861b69b4a2cd1bf18c0fc5cca96eed17d Author: Kevin Bowling AuthorDate: 2026-08-08 18:00:44 +0000 Commit: Kevin Bowling CommitDate: 2026-10-31 18:57:04 +0000 qlnx: Report SR-IOV VF status Retain the PF-known MAC and allocated transmit and receive queue counts for each VF and expose them through the PF ifnet. Sum queues across all hardware functions rather than reporting only the first one. Publish and snapshot the VF cache under the existing hardware lock. Unpublish it before hardware teardown, and invalidate queue-allocation knowledge when error recovery releases the underlying VF resources. Initialize the cache, release it on failed initialization, and reject an out-of-range VF index instead of continuing into the array. Tested by: zlei Place the new status flags in existing padding on stable/15, preserving the VF attribute array stride and existing member offsets. Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D58742 (cherry picked from commit 9b8bc7b827ef99a0488d0bed32293bad323e8cdb) --- sys/dev/qlnx/qlnxe/qlnx_def.h | 2 + sys/dev/qlnx/qlnxe/qlnx_os.c | 166 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 145 insertions(+), 23 deletions(-) diff --git a/sys/dev/qlnx/qlnxe/qlnx_def.h b/sys/dev/qlnx/qlnxe/qlnx_def.h index f895487c47e4..3489dc70893f 100644 --- a/sys/dev/qlnx/qlnxe/qlnx_def.h +++ b/sys/dev/qlnx/qlnxe/qlnx_def.h @@ -326,6 +326,8 @@ typedef struct _qlnx_mcast { typedef struct _qlnx_vf_attr { uint8_t mac_addr[ETHER_ADDR_LEN]; + bool configured; + bool queues_valid; uint32_t num_rings; } qlnx_vf_attr_t; diff --git a/sys/dev/qlnx/qlnxe/qlnx_os.c b/sys/dev/qlnx/qlnxe/qlnx_os.c index 6b896729bf67..8c7d2027d905 100644 --- a/sys/dev/qlnx/qlnxe/qlnx_os.c +++ b/sys/dev/qlnx/qlnxe/qlnx_os.c @@ -72,6 +72,7 @@ #include #include #include +#include #endif /* #ifdef CONFIG_ECORE_SRIOV */ #include @@ -174,6 +175,7 @@ static int qlnx_pci_detach (device_t); static int qlnx_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *params); static void qlnx_iov_uninit(device_t dev); static int qlnx_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params); +static int qlnx_vf_status(if_t ifp, struct if_vf_status **statusp); static void qlnx_initialize_sriov(qlnx_host_t *ha); static void qlnx_pf_taskqueue(void *context, int pending); static int qlnx_create_pf_taskqueues(qlnx_host_t *ha); @@ -651,6 +653,21 @@ qlnx_get_params(qlnx_host_t *ha) return; } +#if !defined(QLNX_VF) && defined(CONFIG_ECORE_SRIOV) +static void +qlnx_invalidate_vf_queue_status(qlnx_host_t *ha) +{ + int i; + + QLNX_LOCK(ha); + if (ha->vf_attr != NULL) { + for (i = 0; i < ha->num_vfs; i++) + ha->vf_attr[i].queues_valid = false; + } + QLNX_UNLOCK(ha); +} +#endif + static void qlnx_error_recovery_taskqueue(void *context, int pending) { @@ -668,6 +685,9 @@ qlnx_error_recovery_taskqueue(void *context, int pending) qlnx_rdma_dev_remove(ha); #endif /* #ifdef QLNX_ENABLE_IWARP */ +#if !defined(QLNX_VF) && defined(CONFIG_ECORE_SRIOV) + qlnx_invalidate_vf_queue_status(ha); +#endif qlnx_slowpath_stop(ha); qlnx_slowpath_start(ha); @@ -2313,6 +2333,11 @@ qlnx_init_ifnet(device_t dev, qlnx_host_t *ha) if_setsoftc(ifp, ha); if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); if_setioctlfn(ifp, qlnx_ioctl); +#ifndef QLNX_VF +#ifdef CONFIG_ECORE_SRIOV + if_setvfstatusfn(ifp, qlnx_vf_status); +#endif +#endif if_settransmitfn(ifp, qlnx_transmit); if_setqflushfn(ifp, qlnx_qflush); @@ -7914,11 +7939,14 @@ static int qlnx_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *nvlist_params) { qlnx_host_t *ha; + qlnx_vf_attr_t *vf_attrs; struct ecore_dev *cdev; struct ecore_iov_vf_init_params params; int ret, j, i; uint32_t max_vfs; + vf_attrs = NULL; + if ((ha = device_get_softc(dev)) == NULL) { device_printf(dev, "%s: cannot get softc\n", __func__); return (-1); @@ -7940,10 +7968,10 @@ qlnx_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *nvlist_params) goto qlnx_iov_init_err0; } - ha->vf_attr = malloc(((sizeof (qlnx_vf_attr_t) * num_vfs)), M_QLNXBUF, - M_NOWAIT); + vf_attrs = mallocarray(num_vfs, sizeof(*vf_attrs), M_QLNXBUF, + M_NOWAIT | M_ZERO); - if (ha->vf_attr == NULL) + if (vf_attrs == NULL) goto qlnx_iov_init_err0; memset(¶ms, 0, sizeof(params)); @@ -7978,10 +8006,20 @@ qlnx_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *nvlist_params) } } - ecore_ptt_release(hwfn, ptt); - } + ecore_ptt_release(hwfn, ptt); + } + for (i = 0; i < num_vfs; i++) { + for_each_hwfn(cdev, j) + vf_attrs[i].num_rings += ecore_iov_get_vf_num_rxqs( + &cdev->hwfns[j], i); + vf_attrs[i].queues_valid = true; + } + + QLNX_LOCK(ha); + ha->vf_attr = vf_attrs; ha->num_vfs = num_vfs; + QLNX_UNLOCK(ha); qlnx_inform_vf_link_state(&cdev->hwfns[0], ha); QL_DPRINT2(ha," dev = %p exit num_vfs = %d\n", dev, num_vfs); @@ -7993,7 +8031,7 @@ qlnx_iov_init_err1: qlnx_iov_init_err0: qlnx_destroy_pf_taskqueues(ha); - ha->num_vfs = 0; + free(vf_attrs, M_QLNXBUF); return (-1); } @@ -8002,6 +8040,7 @@ static void qlnx_iov_uninit(device_t dev) { qlnx_host_t *ha; + qlnx_vf_attr_t *vf_attrs; if ((ha = device_get_softc(dev)) == NULL) { device_printf(dev, "%s: cannot get softc\n", __func__); @@ -8010,13 +8049,15 @@ qlnx_iov_uninit(device_t dev) QL_DPRINT2(ha," dev = %p enter\n", dev); - qlnx_sriov_disable(ha); - qlnx_destroy_pf_taskqueues(ha); - - free(ha->vf_attr, M_QLNXBUF); + QLNX_LOCK(ha); + vf_attrs = ha->vf_attr; ha->vf_attr = NULL; - ha->num_vfs = 0; + QLNX_UNLOCK(ha); + + qlnx_sriov_disable(ha); + qlnx_destroy_pf_taskqueues(ha); + free(vf_attrs, M_QLNXBUF); QL_DPRINT2(ha," dev = %p exit\n", dev); return; @@ -8028,8 +8069,10 @@ qlnx_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) qlnx_host_t *ha; qlnx_vf_attr_t *vf_attr; unsigned const char *mac; + uint8_t mac_addr[ETHER_ADDR_LEN]; size_t size; struct ecore_hwfn *p_hwfn; + enum _ecore_status_t rc; if ((ha = device_get_softc(dev)) == NULL) { device_printf(dev, "%s: cannot get softc\n", __func__); @@ -8038,31 +8081,108 @@ qlnx_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) QL_DPRINT2(ha," dev = %p enter vfnum = %d\n", dev, vfnum); - if (vfnum > (ha->num_vfs - 1)) { - QL_DPRINT1(ha, " VF[%d] is greater than max allowed [%d]\n", - vfnum, (ha->num_vfs - 1)); + QLNX_LOCK(ha); + if (ha->vf_attr == NULL || vfnum >= ha->num_vfs) { + QL_DPRINT1(ha, "VF[%u] is not configured\n", vfnum); + QLNX_UNLOCK(ha); + return (EINVAL); } - - vf_attr = &ha->vf_attr[vfnum]; + QLNX_UNLOCK(ha); + bzero(mac_addr, sizeof(mac_addr)); if (nvlist_exists_binary(params, "mac-addr")) { mac = nvlist_get_binary(params, "mac-addr", &size); - bcopy(mac, vf_attr->mac_addr, ETHER_ADDR_LEN); + if (size != ETHER_ADDR_LEN) + return (EINVAL); + memcpy(mac_addr, mac, ETHER_ADDR_LEN); device_printf(dev, "%s: mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", - __func__, vf_attr->mac_addr[0], - vf_attr->mac_addr[1], vf_attr->mac_addr[2], - vf_attr->mac_addr[3], vf_attr->mac_addr[4], - vf_attr->mac_addr[5]); + __func__, mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); p_hwfn = &ha->cdev.hwfns[0]; - ecore_iov_bulletin_set_mac(p_hwfn, vf_attr->mac_addr, - vfnum); + rc = ecore_iov_bulletin_set_mac(p_hwfn, mac_addr, vfnum); + if (rc != ECORE_SUCCESS) + return (EIO); + } + + QLNX_LOCK(ha); + if (ha->vf_attr == NULL || vfnum >= ha->num_vfs) { + QLNX_UNLOCK(ha); + return (ENXIO); } + vf_attr = &ha->vf_attr[vfnum]; + memcpy(vf_attr->mac_addr, mac_addr, ETHER_ADDR_LEN); + vf_attr->configured = true; + QLNX_UNLOCK(ha); QL_DPRINT2(ha," dev = %p exit vfnum = %d\n", dev, vfnum); return (0); } +static int +qlnx_vf_status(if_t ifp, struct if_vf_status **statusp) +{ + qlnx_vf_attr_t *snapshot; + struct if_vf_info *vf; + struct if_vf_status *status; + qlnx_host_t *ha; + uint16_t num_vfs; + int i; + + ha = if_getsoftc(ifp); + QLNX_LOCK(ha); + if (!ha->sriov_initialized) { + QLNX_UNLOCK(ha); + return (EOPNOTSUPP); + } + num_vfs = ha->num_vfs; + if (num_vfs == 0) { + QLNX_UNLOCK(ha); + status = if_vf_status_alloc(0); + if (status == NULL) + return (ENOMEM); + *statusp = status; + return (0); + } + if (ha->vf_attr == NULL) { + QLNX_UNLOCK(ha); + return (EIO); + } + snapshot = mallocarray(num_vfs, sizeof(*snapshot), M_QLNXBUF, + M_NOWAIT); + if (snapshot == NULL) { + QLNX_UNLOCK(ha); + return (ENOMEM); + } + memcpy(snapshot, ha->vf_attr, num_vfs * sizeof(*snapshot)); + QLNX_UNLOCK(ha); + + status = if_vf_status_alloc(num_vfs); + if (status == NULL) { + free(snapshot, M_QLNXBUF); + return (ENOMEM); + } + 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 (!ETHER_IS_ZERO(snapshot[i].mac_addr)) { + memcpy(vf->mac, snapshot[i].mac_addr, sizeof(vf->mac)); + vf->fields |= IFVF_F_MAC; + } + if (snapshot[i].queues_valid) { + vf->tx_queue_count = snapshot[i].num_rings; + vf->rx_queue_count = snapshot[i].num_rings; + vf->fields |= IFVF_F_NUM_TX_QUEUES | + IFVF_F_NUM_RX_QUEUES; + } + } + free(snapshot, M_QLNXBUF); + *statusp = status; + return (0); +} + static void qlnx_handle_vf_msg(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn) {