Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2216524/?format=api
{ "id": 2216524, "url": "http://patchwork.ozlabs.org/api/patches/2216524/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260326162832.3135857-7-grzegorz.nitka@intel.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260326162832.3135857-7-grzegorz.nitka@intel.com>", "list_archive_url": null, "date": "2026-03-26T16:28:30", "name": "[v4,net-next,6/8] ice: implement CPI support for E825C", "commit_ref": null, "pull_url": null, "state": "handled-elsewhere", "archived": false, "hash": "f4f96200ee02e327e60297ab3154a9d2876cb070", "submitter": { "id": 82711, "url": "http://patchwork.ozlabs.org/api/people/82711/?format=api", "name": "Nitka, Grzegorz", "email": "grzegorz.nitka@intel.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260326162832.3135857-7-grzegorz.nitka@intel.com/mbox/", "series": [ { "id": 497620, "url": "http://patchwork.ozlabs.org/api/series/497620/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=497620", "date": "2026-03-26T16:28:24", "name": "dpll/ice: Add TXC DPLL type and full TX reference clock control for E825", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/497620/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2216524/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2216524/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=osuosl.org header.i=@osuosl.org header.a=rsa-sha256\n header.s=default header.b=IgXtxBGi;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=osuosl.org\n (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org;\n envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fhTq00NG4z1yGD\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 27 Mar 2026 03:33:16 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id AF8AA81206;\n\tThu, 26 Mar 2026 16:33:14 +0000 (UTC)", "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 9KvKQBUIRNpF; Thu, 26 Mar 2026 16:33:13 +0000 (UTC)", "from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142])\n\tby smtp1.osuosl.org (Postfix) with ESMTP id A31C18126D;\n\tThu, 26 Mar 2026 16:33:13 +0000 (UTC)", "from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n by lists1.osuosl.org (Postfix) with ESMTP id E14BDF5\n for <intel-wired-lan@lists.osuosl.org>; Thu, 26 Mar 2026 16:33:11 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id D32828126D\n for <intel-wired-lan@lists.osuosl.org>; Thu, 26 Mar 2026 16:33:11 +0000 (UTC)", "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id PeyjecHcmzAw for <intel-wired-lan@lists.osuosl.org>;\n Thu, 26 Mar 2026 16:33:10 +0000 (UTC)", "from mgamail.intel.com (mgamail.intel.com [192.198.163.19])\n by smtp1.osuosl.org (Postfix) with ESMTPS id C30EE81206\n for <intel-wired-lan@lists.osuosl.org>; Thu, 26 Mar 2026 16:33:10 +0000 (UTC)", "from orviesa007.jf.intel.com ([10.64.159.147])\n by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 26 Mar 2026 09:33:10 -0700", "from gklab-003-001.igk.intel.com ([10.91.173.48])\n by orviesa007.jf.intel.com with ESMTP; 26 Mar 2026 09:33:05 -0700" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections - client-ip=140.211.166.142;\n helo=lists1.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp1.osuosl.org A31C18126D", "OpenDKIM Filter v2.11.0 smtp1.osuosl.org C30EE81206" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=osuosl.org;\n\ts=default; t=1774542793;\n\tbh=cZTWFc3kG16ItsieiMm3jnTW1ho1fDt8Ykb8NoT4Rao=;\n\th=From:To:Date:In-Reply-To:References:Subject:List-Id:\n\t List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:\n\t Cc:From;\n\tb=IgXtxBGiLZWb8mo/bMfRiz9N/qe1OlKOEJtNlWaY8gjTnk8+d4lchidI7hffkGK2S\n\t wsiNIwZpYUVOqXR7ezZrazLK8maR2HPR0XOciOItZ1jB/pnMsXpFK8enL8rG19KuOm\n\t tMcccDWxQgpIwfMJVeK25i6f/Yb7MG5lKTio/HJJAFBY6nVF3ccjpnhkbA/YyDNp+C\n\t HNIby4JKa/0D2IEudLqCwWexJvo1WuHPqQcNjOtWeiIVx6lsDNhK6jgERI0MhP9v8G\n\t MGb7+SZ49tVw0sDYzzkB5yUWT1wvhecFX6w3UXd2HOSW6FCQWdYCv4Da82HdpX9L7V\n\t 2+hXjX+wUTjgw==", "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=192.198.163.19;\n helo=mgamail.intel.com; envelope-from=grzegorz.nitka@intel.com;\n receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp1.osuosl.org C30EE81206", "X-CSE-ConnectionGUID": [ "7hRch8LBTyCH4z2vcaXadA==", "06dnr0SJRoGxAQ1iFRumMg==" ], "X-CSE-MsgGUID": [ "MBvGmXOHQcKaK/sCgCuemA==", "y/jfD1TFR0eN4K+pN3EBqQ==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6800,10657,11741\"; a=\"74636717\"", "E=Sophos;i=\"6.23,142,1770624000\"; d=\"scan'208\";a=\"74636717\"", "E=Sophos;i=\"6.23,142,1770624000\"; d=\"scan'208\";a=\"225311228\"" ], "X-ExtLoop1": "1", "From": "Grzegorz Nitka <grzegorz.nitka@intel.com>", "To": "netdev@vger.kernel.org", "Date": "Thu, 26 Mar 2026 17:28:30 +0100", "Message-Id": "<20260326162832.3135857-7-grzegorz.nitka@intel.com>", "X-Mailer": "git-send-email 2.39.3", "In-Reply-To": "<20260326162832.3135857-1-grzegorz.nitka@intel.com>", "References": "<20260326162832.3135857-1-grzegorz.nitka@intel.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Mailman-Original-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1774542790; x=1806078790;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=RXeLAwQd/WhX+HnMNBfpNgz9UNtamMV0lERMiFBdSsM=;\n b=hAIyITwKp4ACYN/cRXj0w8pn1RS8FflpkBKWQar+eFgrs87SMtkUaQEC\n EyToFWtf4cZyuZ/St+lpcLaujydD74poUYbaSdTY9N6f7ENLqfvt1c3NN\n 7waW2XCNusa49cdt6KcxrGD5D/3nCXP32TnY5xMyep6StoWvkF8MkW1eT\n aWzEaKWdQR6W0kqg/LYI00TJdUjylAqwvfmiNmMmLBNMkXoEPprN5Eqym\n KDG1RLSSU7hR3ESu8XCEvqL5gg08lXa2mPMbqgxLYJdR4UKleljRZj7Im\n W2B087m/qEE/S85/pxVcGVWAdID9q/H63KqvExNpvtp66W48eJHGx+Nub\n w==;", "X-Mailman-Original-Authentication-Results": [ "smtp1.osuosl.org;\n dmarc=pass (p=none dis=none)\n header.from=intel.com", "smtp1.osuosl.org;\n dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com\n header.a=rsa-sha256 header.s=Intel header.b=hAIyITwK" ], "Subject": "[Intel-wired-lan] [PATCH v4 net-next 6/8] ice: implement CPI\n support for E825C", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n <intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Cc": "ivecera@redhat.com, vadim.fedorenko@linux.dev, kuba@kernel.org,\n jiri@resnulli.us, edumazet@google.com, przemyslaw.kitszel@intel.com,\n richardcochran@gmail.com, donald.hunter@gmail.com,\n linux-kernel@vger.kernel.org, arkadiusz.kubalewski@intel.com,\n andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org, horms@kernel.org,\n Prathosh.Satish@microchip.com, anthony.l.nguyen@intel.com, pabeni@redhat.com,\n davem@davemloft.net", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "Add full CPI (Converged PHY Interface) command handling required for\nE825C devices. The CPI interface allows the driver to interact with\nPHY-side control logic through the LM/PHY command registers, including\nenabling/disabling/selection of PHY reference clock.\n\nThis patch introduces:\n - a new CPI subsystem (ice_cpi.c / ice_cpi.h) implementing the CPI\n request/acknowledge state machine, including REQ/ACK protocol,\n command execution, and response handling\n - helper functions for reading/writing PHY registers over Sideband\n Queue\n - CPI command execution API (ice_cpi_exec) and a helper for enabling or\n disabling Tx reference clocks (CPI 0xF1 opcode 'Config PHY clocking')\n - addition of the non-posted write opcode (wr_np) to SBQ\n - Makefile integration to build CPI support together with the PTP stack\n\nThis provides the infrastructure necessary to support PHY-side\nconfiguration flows on E825C and is required for advanced link control\nand Tx reference clock management.\n\nReviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>\nSigned-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>\n---\n drivers/net/ethernet/intel/ice/Makefile | 2 +-\n drivers/net/ethernet/intel/ice/ice_cpi.c | 347 +++++++++++++++++++\n drivers/net/ethernet/intel/ice/ice_cpi.h | 69 ++++\n drivers/net/ethernet/intel/ice/ice_sbq_cmd.h | 5 +-\n 4 files changed, 420 insertions(+), 3 deletions(-)\n create mode 100644 drivers/net/ethernet/intel/ice/ice_cpi.c\n create mode 100644 drivers/net/ethernet/intel/ice/ice_cpi.h", "diff": "diff --git a/drivers/net/ethernet/intel/ice/Makefile b/drivers/net/ethernet/intel/ice/Makefile\nindex 5b2c666496e7..38db476ab2ec 100644\n--- a/drivers/net/ethernet/intel/ice/Makefile\n+++ b/drivers/net/ethernet/intel/ice/Makefile\n@@ -54,7 +54,7 @@ ice-$(CONFIG_PCI_IOV) +=\t\\\n \tice_vf_mbx.o\t\t\\\n \tice_vf_vsi_vlan_ops.o\t\\\n \tice_vf_lib.o\n-ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o ice_dpll.o ice_tspll.o\n+ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o ice_dpll.o ice_tspll.o ice_cpi.o\n ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o\n ice-$(CONFIG_RFS_ACCEL) += ice_arfs.o\n ice-$(CONFIG_XDP_SOCKETS) += ice_xsk.o\ndiff --git a/drivers/net/ethernet/intel/ice/ice_cpi.c b/drivers/net/ethernet/intel/ice/ice_cpi.c\nnew file mode 100644\nindex 000000000000..97fe2ebb99f3\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_cpi.c\n@@ -0,0 +1,347 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/* Copyright (C) 2018-2026 Intel Corporation */\n+\n+#include \"ice_type.h\"\n+#include \"ice_common.h\"\n+#include \"ice_ptp_hw.h\"\n+#include \"ice_cpi.h\"\n+\n+/**\n+ * ice_cpi_get_dest_dev - get destination PHY for given phy index\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ *\n+ * Return: sideband queue destination PHY device.\n+ */\n+static enum ice_sbq_dev_id ice_cpi_get_dest_dev(struct ice_hw *hw, u8 phy)\n+{\n+\tu8 curr_phy = hw->lane_num / hw->ptp.ports_per_phy;\n+\n+\t/* In the driver, lanes 4..7 are in fact 0..3 on a second PHY.\n+\t * On a single complex E825C, PHY 0 is always destination device phy_0\n+\t * and PHY 1 is phy_0_peer.\n+\t * On dual complex E825C, device phy_0 points to PHY on a current\n+\t * complex and phy_0_peer to PHY on a different complex.\n+\t */\n+\tif ((!ice_is_dual(hw) && phy) ||\n+\t (ice_is_dual(hw) && phy != curr_phy))\n+\t\treturn ice_sbq_dev_phy_0_peer;\n+\telse\n+\t\treturn ice_sbq_dev_phy_0;\n+}\n+\n+/**\n+ * ice_cpi_write_phy - Write a CPI port register\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ * @addr: PHY register address\n+ * @val: Value to write\n+ *\n+ * Return:\n+ * * 0 on success\n+ * * other error codes when failed to write to PHY\n+ */\n+static int ice_cpi_write_phy(struct ice_hw *hw, u8 phy, u32 addr, u32 val)\n+{\n+\tstruct ice_sbq_msg_input msg = {\n+\t\t.dest_dev = ice_cpi_get_dest_dev(hw, phy),\n+\t\t.opcode = ice_sbq_msg_wr_np,\n+\t\t.msg_addr_low = lower_16_bits(addr),\n+\t\t.msg_addr_high = upper_16_bits(addr),\n+\t\t.data = val\n+\t};\n+\tint err;\n+\n+\terr = ice_sbq_rw_reg(hw, &msg, LIBIE_AQ_FLAG_RD);\n+\tif (err)\n+\t\tice_debug(hw, ICE_DBG_PTP,\n+\t\t\t \"Failed to write CPI msg to phy %d, err: %d\\n\",\n+\t\t\t phy, err);\n+\n+\treturn err;\n+}\n+\n+/**\n+ * ice_cpi_read_phy - Read a CPI port register\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ * @addr: PHY register address\n+ * @val: storage for register value\n+ *\n+ * Return:\n+ * * 0 on success\n+ * * other error codes when failed to read from PHY\n+ */\n+static int ice_cpi_read_phy(struct ice_hw *hw, u8 phy, u32 addr, u32 *val)\n+{\n+\tstruct ice_sbq_msg_input msg = {\n+\t\t.dest_dev = ice_cpi_get_dest_dev(hw, phy),\n+\t\t.opcode = ice_sbq_msg_rd,\n+\t\t.msg_addr_low = lower_16_bits(addr),\n+\t\t.msg_addr_high = upper_16_bits(addr)\n+\t};\n+\tint err;\n+\n+\terr = ice_sbq_rw_reg(hw, &msg, LIBIE_AQ_FLAG_RD);\n+\tif (err) {\n+\t\tice_debug(hw, ICE_DBG_PTP,\n+\t\t\t \"Failed to read CPI msg from phy %d, err: %d\\n\",\n+\t\t\t phy, err);\n+\t\treturn err;\n+\t}\n+\n+\t*val = msg.data;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ice_cpi_wait_req0_ack0 - waits for CPI interface to be available\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ *\n+ * This function checks if CPI interface is ready to use by CPI client.\n+ * It's done by assuring LM.CMD.REQ and PHY.CMD.ACK bit in CPI\n+ * interface registers to be 0.\n+ *\n+ * Return: 0 on success, negative on error\n+ */\n+static int ice_cpi_wait_req0_ack0(struct ice_hw *hw, int phy)\n+{\n+\tunion cpi_reg_phy_cmd_data phy_regs;\n+\tunion cpi_reg_lm_cmd_data lm_regs;\n+\n+\tfor (int i = 0; i < CPI_RETRIES_COUNT; i++) {\n+\t\tint err;\n+\n+\t\t/* check if another CPI Client is also accessing CPI */\n+\t\terr = ice_cpi_read_phy(hw, phy, CPI0_LM1_CMD_DATA,\n+\t\t\t\t &lm_regs.val);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t\tif (lm_regs.field.cpi_req)\n+\t\t\treturn -EBUSY;\n+\n+\t\t/* check if PHY.ACK is deasserted */\n+\t\terr = ice_cpi_read_phy(hw, phy, CPI0_PHY1_CMD_DATA,\n+\t\t\t\t &phy_regs.val);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t\tif (phy_regs.field.error)\n+\t\t\treturn -EFAULT;\n+\t\tif (!phy_regs.field.ack)\n+\t\t\t/* req0 and ack0 at this point - ready to go */\n+\t\t\treturn 0;\n+\n+\t\tmsleep(CPI_RETRIES_CADENCE_MS);\n+\t}\n+\n+\treturn -ETIMEDOUT;\n+}\n+\n+/**\n+ * ice_cpi_wait_ack - Waits for the PHY.ACK bit to be asserted/deasserted\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ * @asserted: desired state of PHY.ACK bit\n+ * @data: pointer to the user data where PHY.data is stored\n+ *\n+ * This function checks if PHY.ACK bit is asserted or deasserted, depending\n+ * on the phase of CPI handshake. If 'asserted' state is required, PHY command\n+ * data is stored in the 'data' storage.\n+ *\n+ * Return: 0 on success, negative on error\n+ */\n+static int ice_cpi_wait_ack(struct ice_hw *hw, u8 phy, bool asserted,\n+\t\t\t u32 *data)\n+{\n+\tunion cpi_reg_phy_cmd_data phy_regs;\n+\n+\tfor (int i = 0; i < CPI_RETRIES_COUNT; i++) {\n+\t\tint err;\n+\n+\t\terr = ice_cpi_read_phy(hw, phy, CPI0_PHY1_CMD_DATA,\n+\t\t\t\t &phy_regs.val);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t\tif (phy_regs.field.error)\n+\t\t\treturn -EFAULT;\n+\t\tif (asserted && phy_regs.field.ack) {\n+\t\t\tif (data)\n+\t\t\t\t*data = phy_regs.val;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tif (!asserted && !phy_regs.field.ack)\n+\t\t\treturn 0;\n+\n+\t\tmsleep(CPI_RETRIES_CADENCE_MS);\n+\t}\n+\n+\treturn -ETIMEDOUT;\n+}\n+\n+#define ice_cpi_wait_ack0(hw, port) \\\n+\tice_cpi_wait_ack(hw, port, false, NULL)\n+\n+#define ice_cpi_wait_ack1(hw, port, data) \\\n+\tice_cpi_wait_ack(hw, port, true, data)\n+\n+/**\n+ * ice_cpi_req0 - deasserts LM.REQ bit\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ * @data: the command data\n+ *\n+ * Return: 0 on success, negative on CPI write error\n+ */\n+static int ice_cpi_req0(struct ice_hw *hw, u8 phy, u32 data)\n+{\n+\tunion cpi_reg_lm_cmd_data *lm_regs;\n+\tint err;\n+\n+\tlm_regs = (union cpi_reg_lm_cmd_data *)&data;\n+\tlm_regs->field.cpi_req = 0;\n+\n+\terr = ice_cpi_write_phy(hw, phy, CPI0_LM1_CMD_DATA, lm_regs->val);\n+\n+\treturn err;\n+}\n+\n+/**\n+ * ice_cpi_exec_cmd - writes command data to CPI interface\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ * @data: the command data\n+ *\n+ * Return: 0 on success, otherwise negative on error\n+ */\n+static int ice_cpi_exec_cmd(struct ice_hw *hw, int phy, u32 data)\n+{\n+\treturn ice_cpi_write_phy(hw, phy, CPI0_LM1_CMD_DATA, data);\n+}\n+\n+/**\n+ * ice_cpi_exec - executes CPI command\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port the CPI action is taken on\n+ * @cmd: pointer to the command struct to execute\n+ * @resp: pointer to user allocated CPI response struct\n+ *\n+ * This function executes CPI request with respect to CPI handshake\n+ * mechanism.\n+ *\n+ * Return: 0 on success, otherwise negative on error\n+ */\n+int ice_cpi_exec(struct ice_hw *hw, u8 phy,\n+\t\t const struct ice_cpi_cmd *cmd,\n+\t\t struct ice_cpi_resp *resp)\n+{\n+\tunion cpi_reg_phy_cmd_data phy_cmd_data;\n+\tunion cpi_reg_lm_cmd_data lm_cmd_data;\n+\tint err, err1 = 0;\n+\n+\tif (!cmd || !resp)\n+\t\treturn -EINVAL;\n+\n+\tmemset(&lm_cmd_data, 0, sizeof(lm_cmd_data));\n+\n+\tlm_cmd_data.field.cpi_req = CPI_LM_CMD_REQ;\n+\tlm_cmd_data.field.get_set = cmd->set;\n+\tlm_cmd_data.field.opcode = cmd->opcode;\n+\tlm_cmd_data.field.portlane = cmd->port;\n+\tlm_cmd_data.field.data = cmd->data;\n+\n+\t/* 1. Try to acquire the bus, PHY ACK should be low before we begin */\n+\terr = ice_cpi_wait_req0_ack0(hw, phy);\n+\tif (err)\n+\t\tgoto cpi_exec_exit;\n+\n+\t/* 2. We start the CPI request */\n+\terr = ice_cpi_exec_cmd(hw, phy, lm_cmd_data.val);\n+\tif (err)\n+\t\tgoto cpi_exec_exit;\n+\n+\t/*\n+\t * 3. Wait for CPI confirmation, PHY ACK should be asserted and opcode\n+\t * echoed in the response\n+\t */\n+\terr = ice_cpi_wait_ack1(hw, phy, &phy_cmd_data.val);\n+\tif (err)\n+\t\tgoto cpi_deassert;\n+\n+\tif (phy_cmd_data.field.ack &&\n+\t lm_cmd_data.field.opcode != phy_cmd_data.field.opcode) {\n+\t\terr = -EFAULT;\n+\t\tgoto cpi_deassert;\n+\t}\n+\n+\tresp->opcode = phy_cmd_data.field.opcode;\n+\tresp->data = phy_cmd_data.field.data;\n+\tresp->port = phy_cmd_data.field.portlane;\n+\n+cpi_deassert:\n+\t/* 4. We deassert REQ */\n+\terr1 = ice_cpi_req0(hw, phy, lm_cmd_data.val);\n+\tif (err1)\n+\t\tgoto cpi_exec_exit;\n+\n+\t/* 5. PHY ACK should be deasserted in response */\n+\terr1 = ice_cpi_wait_ack0(hw, phy);\n+\n+cpi_exec_exit:\n+\tif (!err)\n+\t\terr = err1;\n+\n+\treturn err;\n+}\n+\n+/**\n+ * ice_cpi_set_cmd - execute CPI SET command\n+ * @hw: pointer to the HW struct\n+ * @opcode: CPI command opcode\n+ * @phy: phy index CPI command is applied for\n+ * @port_lane: ephy index CPI command is applied for\n+ * @data: CPI opcode context specific data\n+ *\n+ * Return: 0 on success.\n+ */\n+static int ice_cpi_set_cmd(struct ice_hw *hw, u16 opcode, u8 phy, u8 port_lane,\n+\t\t\t u16 data)\n+{\n+\tstruct ice_cpi_resp cpi_resp = {0};\n+\tstruct ice_cpi_cmd cpi_cmd = {\n+\t\t.opcode = opcode,\n+\t\t.set = true,\n+\t\t.port = port_lane,\n+\t\t.data = data,\n+\t};\n+\n+\treturn ice_cpi_exec(hw, phy, &cpi_cmd, &cpi_resp);\n+}\n+\n+/**\n+ * ice_cpi_ena_dis_clk_ref - enables/disables Tx reference clock on port\n+ * @hw: pointer to the HW struct\n+ * @phy: phy index of port for which Tx reference clock is enabled/disabled\n+ * @clk: Tx reference clock to enable or disable\n+ * @enable: bool value to enable or disable Tx reference clock\n+ *\n+ * This function executes CPI request to enable or disable specific\n+ * Tx reference clock on given PHY.\n+ *\n+ * Return: 0 on success.\n+ */\n+int ice_cpi_ena_dis_clk_ref(struct ice_hw *hw, u8 phy,\n+\t\t\t enum ice_e825c_ref_clk clk, bool enable)\n+{\n+\tu16 val;\n+\n+\tval = FIELD_PREP(CPI_OPCODE_PHY_CLK_PHY_SEL_M, phy) |\n+\t FIELD_PREP(CPI_OPCODE_PHY_CLK_REF_CTRL_M,\n+\t\t\t enable ? CPI_OPCODE_PHY_CLK_ENABLE :\n+\t\t\t CPI_OPCODE_PHY_CLK_DISABLE) |\n+\t FIELD_PREP(CPI_OPCODE_PHY_CLK_REF_SEL_M, clk);\n+\n+\treturn ice_cpi_set_cmd(hw, CPI_OPCODE_PHY_CLK, phy, 0, val);\n+}\n+\ndiff --git a/drivers/net/ethernet/intel/ice/ice_cpi.h b/drivers/net/ethernet/intel/ice/ice_cpi.h\nnew file mode 100644\nindex 000000000000..767107fc18e5\n--- /dev/null\n+++ b/drivers/net/ethernet/intel/ice/ice_cpi.h\n@@ -0,0 +1,69 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Copyright (C) 2018-2025 Intel Corporation */\n+\n+#ifndef _ICE_CPI_H_\n+#define _ICE_CPI_H_\n+\n+#define CPI0_PHY1_CMD_DATA\t0x7FD028\n+#define CPI0_LM1_CMD_DATA\t0x7FD024\n+#define CPI_RETRIES_COUNT\t10\n+#define CPI_RETRIES_CADENCE_MS\t100\n+\n+#define CPI_OPCODE_PHY_CLK\t\t\t0xF1\n+#define CPI_OPCODE_PHY_CLK_PHY_SEL_M\t\tGENMASK(9, 6)\n+#define CPI_OPCODE_PHY_CLK_REF_CTRL_M\t\tGENMASK(5, 4)\n+#define CPI_OPCODE_PHY_CLK_PORT_SEL\t\t0\n+#define CPI_OPCODE_PHY_CLK_DISABLE\t\t1\n+#define CPI_OPCODE_PHY_CLK_ENABLE\t\t2\n+#define CPI_OPCODE_PHY_CLK_REF_SEL_M\t\tGENMASK(3, 0)\n+\n+#define CPI_OPCODE_PHY_PCS_RESET\t\t0xF0\n+#define CPI_OPCODE_PHY_PCS_ONPI_RESET_VAL\t0x3F\n+\n+#define CPI_LM_CMD_REQ\t\t1\n+#define CPI_LM_CMD_SET\t\t1\n+\n+union cpi_reg_phy_cmd_data {\n+\tstruct {\n+\t\tu16 data;\n+\t\tu16 opcode : 8;\n+\t\tu16 portlane : 3;\n+\t\tu16 reserved_13_11: 3;\n+\t\tu16 error : 1;\n+\t\tu16 ack : 1;\n+\t} __packed field;\n+\tu32 val;\n+};\n+\n+union cpi_reg_lm_cmd_data {\n+\tstruct {\n+\t\tu16 data;\n+\t\tu16 opcode : 8;\n+\t\tu16 portlane : 3;\n+\t\tu16 reserved_12_11: 2;\n+\t\tu16 get_set : 1;\n+\t\tu16 cpi_reset : 1;\n+\t\tu16 cpi_req : 1;\n+\t} __packed field;\n+\tu32 val;\n+};\n+\n+struct ice_cpi_cmd {\n+\tu8 port;\n+\tu8 opcode;\n+\tu16 data;\n+\tbool set;\n+};\n+\n+struct ice_cpi_resp {\n+\tu8 port;\n+\tu8 opcode;\n+\tu16 data;\n+};\n+\n+int ice_cpi_exec(struct ice_hw *hw, u8 phy,\n+\t\t const struct ice_cpi_cmd *cmd,\n+\t\t struct ice_cpi_resp *resp);\n+int ice_cpi_ena_dis_clk_ref(struct ice_hw *hw, u8 port,\n+\t\t\t enum ice_e825c_ref_clk clk, bool enable);\n+#endif /* _ICE_CPI_H_ */\ndiff --git a/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h b/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h\nindex 21bb861febbf..226243d32968 100644\n--- a/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h\n+++ b/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h\n@@ -54,8 +54,9 @@ enum ice_sbq_dev_id {\n };\n \n enum ice_sbq_msg_opcode {\n-\tice_sbq_msg_rd\t= 0x00,\n-\tice_sbq_msg_wr\t= 0x01\n+\tice_sbq_msg_rd\t\t= 0x00,\n+\tice_sbq_msg_wr\t\t= 0x01,\n+\tice_sbq_msg_wr_np\t= 0x02\n };\n \n #define ICE_SBQ_MSG_FLAGS\t0x40\n", "prefixes": [ "v4", "net-next", "6/8" ] }