From nobody Fri Oct 23 17:57:45 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 4jB9j53w4gz6xNY2 for ; Fri, 23 Oct 2026 17:57:45 +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 4jB9j53Mkwz3FNc for ; Fri, 23 Oct 2026 17:57:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792778265; 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=KeqeoIRs6ZsFqsg94p2dBKBZD+NcyQCPTKc02SO2j5c=; b=d6GvfDTQCPdoDjtlGfYp+OgW5JyoTzO3H3dt0KPiJMT52BTdaDyxSJPhE8Nx5P2xpiXp/X Blc17RF33R4hD9S3t8TfHeUy8RYAC+LexGgaZ1lij5riSgyck8gHx3sdoCTsvbg1JUZG4c +OsmHnSm/3NzhZcctJ2Jms8kYMqVt7+eNkqbKhLY0lO2PtUnXxyYBhsuejgGySO6ZbXuZs 6xXr1nS1dq8GSPV14WQHYT/6L7t1GToxjSNnQEIkkfSugRlwYcRvk6xrZvAtIQR8SRhGBA munS/QgIxwF+E7E/WCJiIypzaTh1tQx2nBdPlGdKNLDp6cOxm1h5GV1GWmQL0g== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1792778265; b=PxfKd06C1en+nO4ODSrqfADwdqG9AEkY4ZAl6OIBeX8T7TCLyFVRHKMBkconuYD8Ka1q7u MbqkyfSRAErtC0xTnuaDdqQwV9hiUpq/5yH3rLJ03TGOpY3eLdMmd+NyreTVeaB00/Lbtt cqWAl3OTlkz/MARmMZKvLPFuZa/Z+Lpss01Pa+cLezpVClpK0yuM729CYf9Fwr6EzGmPN4 yWuQcw7CS9Cr749C52dprcOq7mbN1htmEdruB3VbOVRI3HKEG/bJF1jn7UqdqKY65NEeB8 iin4bOnv/jQklEi1AFCb4pRYZMZChsamIVwtWPdCoJN9u7Q6OBiTFhSBbXEPBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1792778265; 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=KeqeoIRs6ZsFqsg94p2dBKBZD+NcyQCPTKc02SO2j5c=; b=EmhZI5DcoqmKKXiUDf30PHsF9r4WNDsBvkt78HUjCapN6fOIg1k/HjbruaH5p20p2KQkqD 5HaD3CPqARmrlPVT40mZ5EWSI0i6DJC4HeufvuK5POI7gcSCD3aWsDM0UhzXAG9e1vUzng ZDs6j+UX04ZTdtrq5FEdY0MACnwMN91Bl2/sa9esTw7gWBCWyStKSA9FpufTbungvbjuhG IjPE953K4MLq3lQIC9vJclSjYqjCjuIwc7Vs/cPxuowYg00/8arGBaouffNLvACyu+6mFw H6PHR5U+jdefQ24IbjgHZdg54VVFYAooDlqquzzZw/GdUpLUSnzYjnY88fFPhw== 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 4jB9j531P8zgYY for ; Fri, 23 Oct 2026 17:57:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1a8e6 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 23 Oct 2026 17:57:45 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Krzysztof Galazka Subject: git: 8e55febde6b5 - main - ixl(4): Fix NVM update API List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: Commit messages for the main branch 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: kgalazka X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8e55febde6b54685fe24c8b48ed6720bae97c491 Auto-Submitted: auto-generated Date: Fri, 23 Oct 2026 17:57:45 +0000 Message-Id: <6adba019.1a8e6.38fc6ae4@gitrepo.freebsd.org> The branch main has been updated by kgalazka: URL: https://cgit.FreeBSD.org/src/commit/?id=8e55febde6b54685fe24c8b48ed6720bae97c491 commit 8e55febde6b54685fe24c8b48ed6720bae97c491 Author: Krzysztof Galazka AuthorDate: 2026-10-05 09:22:10 +0000 Commit: Krzysztof Galazka CommitDate: 2026-10-23 17:57:17 +0000 ixl(4): Fix NVM update API Driver provides an interface for tools operating on adapters' Non-Volatile Memory using SIOC(G|S)DRVSPEC ioctls. It allows tools to issue Admin Queue commands to the firmware, which may return an error code encoded as a negative integer. The driver passed this negative integer as the return value of the ioctl handler. This was causing issues because the FreeBSD kernel reserves negative error codes in system calls for special purposes such as restarting the handler or detecting incorrect behavior in VFS operations. Simple remapping of negative values to positive integers caused currently available tools to misbehave and could break the NVM update process. Introduce a new API version, which allows new versions of tools to detect the fixed driver. Temporarily keep the old API, but issue a warning that tools need to be updated. Also refactor the code to use centralized cleanup and move the debug message from the firmware earlier to make sure it is not masked by an error from copyout. Signed-off-by: Krzysztof Galazka Tested by: Mateusz Moga MFC after: 2 weeks Assisted by: Copilot GPT 5.4 Sponsored by: Intel Corporation Differential Revision: https://reviews.freebsd.org/D57942 --- sys/dev/ixl/if_ixl.c | 3 ++- sys/dev/ixl/ixl_pf.h | 8 +++++- sys/dev/ixl/ixl_pf_main.c | 66 +++++++++++++++++++++++++++++------------------ 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 3822f4b5ace2..b0f89ae9a900 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -1983,7 +1983,8 @@ ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data) case SIOCGDRVSPEC: case SIOCSDRVSPEC: /* NVM update command */ - if (ifd->ifd_cmd == I40E_NVM_ACCESS) { + if (ifd->ifd_cmd == I40E_NVM_ACCESS || + ifd->ifd_cmd == I40E_NVM_ACCESS2) { error = priv_check(curthread, PRIV_DRIVER); if (error) break; diff --git a/sys/dev/ixl/ixl_pf.h b/sys/dev/ixl/ixl_pf.h index d244a2e36a38..3bc51e4c7459 100644 --- a/sys/dev/ixl/ixl_pf.h +++ b/sys/dev/ixl/ixl_pf.h @@ -93,6 +93,7 @@ enum ixl_state { IXL_STATE_EEE_ENABLED = 10, IXL_STATE_LINK_ACTIVE_ON_DOWN = 11, IXL_STATE_LINK_POLLING = 12, + IXL_STATE_NVMUPD_API_WARNED = 13, }; #define IXL_PF_IN_RECOVERY_MODE(pf) \ @@ -200,6 +201,12 @@ struct ixl_pf { */ #define I40E_NVM_ACCESS \ (((((((('E' << 4) + '1') << 4) + 'K') << 4) + 'G') << 4) | 5) +/* + * New version of tools API. Omitting '6' to not conflict + * with debug dump supported by other drivers. + */ +#define I40E_NVM_ACCESS2 \ + (((((((('E' << 4) + '1') << 4) + 'K') << 4) + 'G') << 4) | 7) #define IXL_DEFAULT_PHY_INT_MASK \ ((~(I40E_AQ_EVENT_LINK_UPDOWN | I40E_AQ_EVENT_MODULE_QUAL_FAIL \ @@ -310,7 +317,6 @@ void ixl_clear_state(volatile u32 *s, enum ixl_state bit); bool ixl_test_state(volatile u32 *s, enum ixl_state bit); u32 ixl_testandset_state(volatile u32 *s, enum ixl_state bit); int ixl_setup_interface(device_t, struct ixl_pf *); -void ixl_print_nvm_cmd(device_t, struct i40e_nvm_access *); void ixl_handle_que(void *context, int pending); diff --git a/sys/dev/ixl/ixl_pf_main.c b/sys/dev/ixl/ixl_pf_main.c index d2a2fb74fe69..cc71ec8a2270 100644 --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -50,6 +50,7 @@ static u_int ixl_add_maddr(void *, struct sockaddr_dl *, u_int); static u_int ixl_match_maddr(void *, struct sockaddr_dl *, u_int); static char * ixl_switch_element_string(struct sbuf *, u8, u16); static enum ixl_fw_mode ixl_get_fw_mode(struct ixl_pf *); +static void ixl_print_nvm_cmd(device_t, int, struct i40e_nvm_access *); /* Sysctls */ static int ixl_sysctl_set_advertise(SYSCTL_HANDLER_ARGS); @@ -3123,8 +3124,8 @@ ixl_sysctl_show_fw(SYSCTL_HANDLER_ARGS) return (0); } -void -ixl_print_nvm_cmd(device_t dev, struct i40e_nvm_access *nvma) +static void +ixl_print_nvm_cmd(device_t dev, int apiver, struct i40e_nvm_access *nvma) { u8 nvma_ptr = nvma->config & 0xFF; u8 nvma_flags = (nvma->config & 0xF00) >> 8; @@ -3134,7 +3135,7 @@ ixl_print_nvm_cmd(device_t dev, struct i40e_nvm_access *nvma) case I40E_NVM_READ: if (nvma_ptr == 0xF && nvma_flags == 0xF && nvma->offset == 0 && nvma->data_size == 1) { - device_printf(dev, "NVMUPD: Get Driver Status Command\n"); + device_printf(dev, "NVMUPD: API: v%d Get Driver Status Command\n", apiver); return; } cmd_str = "READ "; @@ -3143,12 +3144,12 @@ ixl_print_nvm_cmd(device_t dev, struct i40e_nvm_access *nvma) cmd_str = "WRITE"; break; default: - device_printf(dev, "NVMUPD: unknown command: 0x%08x\n", nvma->command); + device_printf(dev, "NVMUPD: API: v%d unknown command: 0x%08x\n", apiver, nvma->command); return; } device_printf(dev, - "NVMUPD: cmd: %s ptr: 0x%02x flags: 0x%01x offset: 0x%08x data_s: 0x%08x\n", - cmd_str, nvma_ptr, nvma_flags, nvma->offset, nvma->data_size); + "NVMUPD: API: v%d cmd: %s ptr: 0x%02x flags: 0x%01x offset: 0x%08x data_s: 0x%08x\n", + apiver, cmd_str, nvma_ptr, nvma_flags, nvma->offset, nvma->data_size); } int @@ -3159,7 +3160,7 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf, struct ifdrv *ifd) device_t dev = pf->dev; enum i40e_status_code status = 0; size_t nvma_size, ifd_len, exp_len; - int err, perrno; + int err, perrno, apiver; DEBUGFUNC("ixl_handle_nvmupd_cmd"); @@ -3175,20 +3176,26 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf, struct ifdrv *ifd) __func__, ifd_len, nvma_size); device_printf(dev, "%s: data pointer: %p\n", __func__, ifd->ifd_data); - return (EINVAL); + err = EINVAL; + goto out; } + if (ifd->ifd_cmd == I40E_NVM_ACCESS && + !ixl_testandset_state(&pf->state, IXL_STATE_NVMUPD_API_WARNED)) + device_printf(dev, + "Using deprecated tools API, please update the tool\n"); + nvma = malloc(ifd_len, M_IXL, M_WAITOK); err = copyin(ifd->ifd_data, nvma, ifd_len); if (err) { device_printf(dev, "%s: Cannot get request from user space\n", __func__); - free(nvma, M_IXL); - return (err); + goto out_free; } + apiver = ifd->ifd_cmd == I40E_NVM_ACCESS2 ? 2 : 1; if (pf->dbg_mask & IXL_DBG_NVMUPD) - ixl_print_nvm_cmd(dev, nvma); + ixl_print_nvm_cmd(dev, apiver, nvma); if (IXL_PF_IS_RESETTING(pf)) { int count = 0; @@ -3203,16 +3210,16 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf, struct ifdrv *ifd) device_printf(dev, "%s: timeout waiting for EMP reset to finish\n", __func__); - free(nvma, M_IXL); - return (-EBUSY); + perrno = -EBUSY; + goto out_sanitize; } if (nvma->data_size < 1 || nvma->data_size > 4096) { device_printf(dev, "%s: invalid request, data size not in supported range\n", __func__); - free(nvma, M_IXL); - return (EINVAL); + err = EINVAL; + goto out_free; } /* @@ -3230,8 +3237,7 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf, struct ifdrv *ifd) if (err) { device_printf(dev, "%s: Cannot get request from user space\n", __func__); - free(nvma, M_IXL); - return (err); + goto out_free; } } @@ -3240,27 +3246,37 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf, struct ifdrv *ifd) status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno); // IXL_PF_UNLOCK(pf); + /* Let the nvmupdate report errors, show them only when debug is enabled */ + if (status != 0 && (pf->dbg_mask & IXL_DBG_NVMUPD) != 0) + device_printf(dev, "i40e_nvmupd_command API: v%d status %s, perrno %d\n", + apiver, i40e_stat_str(hw, status), perrno); + err = copyout(nvma, ifd->ifd_data, ifd_len); - free(nvma, M_IXL); if (err) { device_printf(dev, "%s: Cannot return data to user space\n", __func__); - return (err); + goto out_free; } - /* Let the nvmupdate report errors, show them only when debug is enabled */ - if (status != 0 && (pf->dbg_mask & IXL_DBG_NVMUPD) != 0) - device_printf(dev, "i40e_nvmupd_command status %s, perrno %d\n", - i40e_stat_str(hw, status), perrno); +out_sanitize: + if (ifd->ifd_cmd == I40E_NVM_ACCESS2) { + err = -perrno; + goto out_free; + } /* * -EPERM is actually ERESTART, which the kernel interprets as it needing * to run this ioctl again. So use -EACCES for -EPERM instead. */ if (perrno == -EPERM) - return (-EACCES); + err = -EACCES; else - return (perrno); + err = perrno; + +out_free: + free(nvma, M_IXL); +out: + return (err); } int