From nobody Sat Oct 31 01:41:26 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 4jGgft1z5Jz6xjQX for ; Sat, 31 Oct 2026 01:41:26 +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 4jGgft1NMGz50Wj for ; Sat, 31 Oct 2026 01:41:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793410886; 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=tkrK3LD0nnXhEFsFfIdwI1SJwufHsO9yRQm/V9sN+8E=; b=xj7TBI9IqadsF5CxDK9moX2YW6+cKpu4Dkl8OQKVGr6lKnNa4+C+94dBtbBQUeloIJ+wFw hqnoWGUcGbNQfqTuw/JPASIJ42PR0b2YbRJn+2xK5VUGJhHMEsD5k/ubU4KBEkzWPwmCN8 dsvPVUy8vf0zS5dbFSSpeSfpNRyawuipZVYxtUGKI5pglMEssbEdaO1Uq7GSLVhd/A1RUx TXfewgS7YyLircSw+piUsYT4Fu345jmfj8eulDxfcgcsxYT3RLbdXaktfN9rNeVCoGp+KX Tj1l2VAUWkLpZ4tdEg7lCOgQOR24eIZqcCS1IC7HLBY8yrGhYStQkrOEwJG9Gg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793410886; b=D7vfFeRM12YoJ/ZdUWgc/LlNlCfd7IVJBlPdqvYRFEjB6PSVBq5qlVwOzk1edlj/QgqQX1 4R1XRDzKtH13I1EIEV/xj6nKFF6fXZiK7DkzbdM5Wm7t/rcYAxYi2SwKwH0R4yINQpZHgg oYNSB0GrIfmwn4bEUNv8F40Bza7/wcASn9w0EiMaQmylParRFo0afcDW/Pys49EMEiTX+O kf3tUk/O6C4yJ8mXFlmrUdA8L/OMJCSrv4WjsSUNxUJaFK3VVe5e96QhQp3dgw5tH43SD8 CPjzR9MfZSq28/A47PPz38R5APtrVeKppHerv7SnTxf41OVMalU1aGeeAqLd4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793410886; 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=tkrK3LD0nnXhEFsFfIdwI1SJwufHsO9yRQm/V9sN+8E=; b=lnqBcemdtwl+vkNXrnX5/lhSbXtbup8pzCxkp39QyagFb1LqRnYJhFtRWs6/QcTBlT6am+ SutxdJzjbs67dpiV5nE9lI++MVaZfZ82aam4tBkGi2Eqn2N8/hrlAh1nOR8+to279yUlQK uwqm4QwtfKmOZtKj0cxiOR4vRTN7aFMOQwO1yMOIywoSVHEWoeqUGV5OsvB7+jlzHcDwAr 7SH3/3JcLHUf0qBf2G1VTNqPZRNrYyJiEvH9LbD7j0B/rix8RR9vSM7UAYfZy8jQIBHswY 1hc1NY6pFyMnI+rTsOGPe/R3f9P7E6+4S5/33umC4TGAcORyRzOmjQIgWy3l0g== 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 4jGgft0kplztps for ; Sat, 31 Oct 2026 01:41:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 25e05 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 31 Oct 2026 01:41:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 9b8bc7b827ef - main - 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/main X-Git-Reftype: branch X-Git-Commit: 9b8bc7b827ef99a0488d0bed32293bad323e8cdb Auto-Submitted: auto-generated Date: Sat, 31 Oct 2026 01:41:26 +0000 Message-Id: <6ae54746.25e05.6464e3e5@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=9b8bc7b827ef99a0488d0bed32293bad323e8cdb commit 9b8bc7b827ef99a0488d0bed32293bad323e8cdb Author: Kevin Bowling AuthorDate: 2026-08-08 18:00:44 +0000 Commit: Kevin Bowling CommitDate: 2026-10-31 01:41:13 +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 Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D58742 --- 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..bdda4384abe0 100644 --- a/sys/dev/qlnx/qlnxe/qlnx_def.h +++ b/sys/dev/qlnx/qlnxe/qlnx_def.h @@ -327,6 +327,8 @@ typedef struct _qlnx_mcast { typedef struct _qlnx_vf_attr { uint8_t mac_addr[ETHER_ADDR_LEN]; uint32_t num_rings; + bool configured; + bool queues_valid; } qlnx_vf_attr_t; typedef struct _qlnx_sriov_task { 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) {