From nobody Tue Dec 16 07:31:51 2025 Received: from smtpbgbr2.qq.com (smtpbgbr2.qq.com [54.207.22.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DCFDEEC0; Sat, 1 Nov 2025 01:39:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.207.22.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761961183; cv=none; b=QGoKvRkXGV11+NOPmFMdMYaC6nltx+cNFXT2L4zTIDidNKviwRqqK8gf1rLnv8CH1/vJjMAFA7jF4Y8KNrbqBSvQ+u3rxmbPQDoYH+mwjZPriAP/fWytW5IdrQrqW8SyCF6wmHMoA2GiIqnZoMnbobmYc8FmU7oIWE4mmSUzpLw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761961183; c=relaxed/simple; bh=SA1CFqd/bu0Kb+ZGC86AJ2jOKYl23Vae0S6UJZuwysY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jorU0LunUZqu4PunGbnP98vhlsZSPNJ06jIUAHG3BA9GCyRao6FPCAd5CZMoDTtB4pfSjASWt5gTDNTXCxgkDeLCaF1TQ7gCKDzZhXniVhE8H9MBpRHs4s7DdHbdWRQ4kO1X4r8aiG0I0vCUdEuxClqTBmqjexaAAioUhGo0zC8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=mucse.com; spf=pass smtp.mailfrom=mucse.com; arc=none smtp.client-ip=54.207.22.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=mucse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mucse.com X-QQ-mid: zesmtpsz9t1761961155tb8424320 X-QQ-Originating-IP: mXYEBWzVFoSRScETfVPlJVyYsDKHcruWHVuoN1r3rCY= Received: from localhost.localdomain ( [203.174.112.180]) by bizesmtp.qq.com (ESMTP) with id ; Sat, 01 Nov 2025 09:39:13 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 3149806804714217064 EX-QQ-RecipientCnt: 17 From: Dong Yibo To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, corbet@lwn.net, andrew+netdev@lunn.ch, danishanwar@ti.com, vadim.fedorenko@linux.dev, geert+renesas@glider.be, mpe@ellerman.id.au, lorenzo@kernel.org, lukas.bulwahn@redhat.com Cc: netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dong100@mucse.com Subject: [PATCH net-next v17 4/5] net: rnpgbe: Add basic mbx_fw support Date: Sat, 1 Nov 2025 09:38:48 +0800 Message-Id: <20251101013849.120565-5-dong100@mucse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20251101013849.120565-1-dong100@mucse.com> References: <20251101013849.120565-1-dong100@mucse.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:mucse.com:qybglogicsvrgz:qybglogicsvrgz3a-1 X-QQ-XMAILINFO: NxDhOhyC1N7yfkvLhODmuivZUNJXkLQaEZxbK5MZZRB/9vJR03MOZpwU C0muSi2dfUza+KZPZKyjEfaxFNPer+vdxQP4jLPMpHszpxUNeAG83eWqw1zaoDI8eCO1nxa 5o/PXUjNiBbbpMNpZtWnl3qngbiYyLWRD7hGkLOfrGbNSDe7FdNM0AsP2qHrURkLV1jWw4W Diz6XyVdcbzNgqLFFRgjGlKxuOeb7BhgYbJWyDrzq5+B7KMIgoWDRkrimz/nVwWrHuF4BTQ k2xfqJMRQqzMrYqxG4C58xmbe5cNnliAZtWghGqh4oAhu6QvxdicYKD2PtH+geT0igkSiOR MPeC1RrmzLrYiWPgSV05J5Riu9GKKU0owf2ow45U5Wdow7MEeJwCSdfRBMYRNEk8tXesiDk Ap//TIjnAYC6fosO0TpPKvENFk5oJzt9hZ9HNqQZU+e4PcfL9M4rdeqsxZbnfalZkbOQO5E +xepzkbd9nvf5Ww+z4YxqKPluIknjHEoM8mlNdeslz8Hi8130RR+x/a3Oe48OxvBNbMOfsU rFgs5mZEos/iAKQq7+4BzFaA0hvLE1SIaLzgHGWkDyoGT3d6SN3ycSE99zT3bmsZzvUgZnq ztvrFSKe9/rH+mvnC+qLY/1CVUL8eaWWxXIlIeyePHJFKVTIkfCsm1M0YRGM8mb/utl3V2S 73yjgehzP/oVb0XarQ09rbLJh4OMg/BtXQKw2/KQwXvU45GQku8rXPbHDEZQhOPxH5yZTMU UHVd2B40Wv6nzRWlp6yAUOBH5WHxMReNH8TuDec4we++KMF+COpNOymsUcjADhb78OgtLhP l7A7wq7iEczcems1zzQK6TXKYkwvG5gMtD7RYDf+Mu8uuTwMDJMd1HS156Te7/vXH7LN538 rAitDgW/qNjQcnYjTlWgJwqgeV/6eMPPTqBlmhxuCvrKN3jXHBHKQym52ofsFEYnojigswb 5Yn3njxb7DyeIzpma7vblUFQr2uko+mYsvUwZ4n+s8yDqkQNlE/36/pSdxbhzXKPyK9P07W SenEu0GXoRMVcwXKfrsuBaii4LYyk= X-QQ-XMRINFO: NI4Ajvh11aEj8Xl/2s1/T8w= X-QQ-RECHKSPAM: 0 Content-Type: text/plain; charset="utf-8" Add fundamental firmware (FW) communication operations via PF-FW mailbox, including: - FW sync (via HW info query with retries) - HW reset (post FW command to reset hardware) - MAC address retrieval (request FW for port-specific MAC) - Power management (powerup/powerdown notification to FW) Signed-off-by: Dong Yibo Reviewed-by: Vadim Fedorenko --- drivers/net/ethernet/mucse/rnpgbe/Makefile | 3 +- drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h | 4 + .../net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c | 1 + .../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c | 191 ++++++++++++++++++ .../net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h | 88 ++++++++ 5 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c create mode 100644 drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h diff --git a/drivers/net/ethernet/mucse/rnpgbe/Makefile b/drivers/net/ether= net/mucse/rnpgbe/Makefile index 5fc878ada4b1..de8bcb7772ab 100644 --- a/drivers/net/ethernet/mucse/rnpgbe/Makefile +++ b/drivers/net/ethernet/mucse/rnpgbe/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_MGBE) +=3D rnpgbe.o rnpgbe-objs :=3D rnpgbe_main.o\ rnpgbe_chip.o\ - rnpgbe_mbx.o + rnpgbe_mbx.o\ + rnpgbe_mbx_fw.o diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h b/drivers/net/ether= net/mucse/rnpgbe/rnpgbe.h index 4c70b0cedd1f..37bd9278beaa 100644 --- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h +++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe.h @@ -5,6 +5,7 @@ #define _RNPGBE_H =20 #include +#include =20 enum rnpgbe_boards { board_n500, @@ -16,6 +17,8 @@ struct mucse_mbx_info { u32 delay_us; u16 fw_req; u16 fw_ack; + /* lock for only one use mbx */ + struct mutex lock; /* fw <--> pf mbx */ u32 fwpf_shm_base; u32 pf2fw_mbx_ctrl; @@ -26,6 +29,7 @@ struct mucse_mbx_info { struct mucse_hw { void __iomem *hw_addr; struct mucse_mbx_info mbx; + u8 pfvfnum; }; =20 struct mucse { diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c b/drivers/net/e= thernet/mucse/rnpgbe/rnpgbe_mbx.c index 5de4b104455e..de5e29230b3c 100644 --- a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c +++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c @@ -401,5 +401,6 @@ void mucse_init_mbx_params_pf(struct mucse_hw *hw) =20 mbx->delay_us =3D 100; mbx->timeout_us =3D 4 * USEC_PER_SEC; + mutex_init(&mbx->lock); mucse_mbx_reset(hw); } diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c b/drivers/ne= t/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c new file mode 100644 index 000000000000..8c8bd5e8e1db --- /dev/null +++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2020 - 2025 Mucse Corporation. */ + +#include +#include + +#include "rnpgbe.h" +#include "rnpgbe_mbx.h" +#include "rnpgbe_mbx_fw.h" + +/** + * mucse_fw_send_cmd_wait_resp - Send cmd req and wait for response + * @hw: pointer to the HW structure + * @req: pointer to the cmd req structure + * @reply: pointer to the fw reply structure + * + * mucse_fw_send_cmd_wait_resp sends req to pf-fw mailbox and wait + * reply from fw. + * + * Return: 0 on success, negative errno on failure + **/ +static int mucse_fw_send_cmd_wait_resp(struct mucse_hw *hw, + struct mbx_fw_cmd_req *req, + struct mbx_fw_cmd_reply *reply) +{ + int len =3D le16_to_cpu(req->datalen); + int retry_cnt =3D 3; + int err; + + mutex_lock(&hw->mbx.lock); + err =3D mucse_write_and_wait_ack_mbx(hw, (u32 *)req, len); + if (err) + goto out; + do { + err =3D mucse_poll_and_read_mbx(hw, (u32 *)reply, + sizeof(*reply)); + if (err) + goto out; + /* mucse_write_and_wait_ack_mbx return 0 means fw has + * received request, wait for the expect opcode + * reply with 'retry_cnt' times. + */ + } while (--retry_cnt >=3D 0 && reply->opcode !=3D req->opcode); +out: + mutex_unlock(&hw->mbx.lock); + if (!err && retry_cnt < 0) + return -ETIMEDOUT; + if (!err && reply->error_code) + return -EIO; + + return err; +} + +/** + * mucse_mbx_get_info - Get hw info from fw + * @hw: pointer to the HW structure + * + * mucse_mbx_get_info tries to get hw info from hw. + * + * Return: 0 on success, negative errno on failure + **/ +static int mucse_mbx_get_info(struct mucse_hw *hw) +{ + struct mbx_fw_cmd_req req =3D { + .datalen =3D cpu_to_le16(MUCSE_MBX_REQ_HDR_LEN), + .opcode =3D cpu_to_le16(GET_HW_INFO), + }; + struct mbx_fw_cmd_reply reply =3D {}; + int err; + + err =3D mucse_fw_send_cmd_wait_resp(hw, &req, &reply); + if (!err) + hw->pfvfnum =3D FIELD_GET(GENMASK_U16(7, 0), + le16_to_cpu(reply.hw_info.pfnum)); + + return err; +} + +/** + * mucse_mbx_sync_fw - Try to sync with fw + * @hw: pointer to the HW structure + * + * mucse_mbx_sync_fw tries to sync with fw. It is only called in + * probe. Nothing (register network) todo if failed. + * Try more times to do sync. + * + * Return: 0 on success, negative errno on failure + **/ +int mucse_mbx_sync_fw(struct mucse_hw *hw) +{ + int try_cnt =3D 3; + int err; + + do { + err =3D mucse_mbx_get_info(hw); + } while (err =3D=3D -ETIMEDOUT && try_cnt--); + + return err; +} + +/** + * mucse_mbx_powerup - Echo fw to powerup + * @hw: pointer to the HW structure + * @is_powerup: true for powerup, false for powerdown + * + * mucse_mbx_powerup echo fw to change working frequency + * to normal after received true, and reduce working frequency + * if false. + * + * Return: 0 on success, negative errno on failure + **/ +int mucse_mbx_powerup(struct mucse_hw *hw, bool is_powerup) +{ + struct mbx_fw_cmd_req req =3D { + .datalen =3D cpu_to_le16(sizeof(req.powerup) + + MUCSE_MBX_REQ_HDR_LEN), + .opcode =3D cpu_to_le16(POWER_UP), + .powerup =3D { + /* fw needs this to reply correct cmd */ + .version =3D cpu_to_le32(GENMASK_U32(31, 0)), + .status =3D cpu_to_le32(is_powerup ? 1 : 0), + }, + }; + int len, err; + + len =3D le16_to_cpu(req.datalen); + mutex_lock(&hw->mbx.lock); + err =3D mucse_write_and_wait_ack_mbx(hw, (u32 *)&req, len); + mutex_unlock(&hw->mbx.lock); + + return err; +} + +/** + * mucse_mbx_reset_hw - Posts a mbx req to reset hw + * @hw: pointer to the HW structure + * + * mucse_mbx_reset_hw posts a mbx req to firmware to reset hw. + * We use mucse_fw_send_cmd_wait_resp to wait hw reset ok. + * + * Return: 0 on success, negative errno on failure + **/ +int mucse_mbx_reset_hw(struct mucse_hw *hw) +{ + struct mbx_fw_cmd_req req =3D { + .datalen =3D cpu_to_le16(MUCSE_MBX_REQ_HDR_LEN), + .opcode =3D cpu_to_le16(RESET_HW), + }; + struct mbx_fw_cmd_reply reply =3D {}; + + return mucse_fw_send_cmd_wait_resp(hw, &req, &reply); +} + +/** + * mucse_mbx_get_macaddr - Posts a mbx req to request macaddr + * @hw: pointer to the HW structure + * @pfvfnum: index of pf/vf num + * @mac_addr: pointer to store mac_addr + * @port: port index + * + * mucse_mbx_get_macaddr posts a mbx req to firmware to get mac_addr. + * + * Return: 0 on success, negative errno on failure + **/ +int mucse_mbx_get_macaddr(struct mucse_hw *hw, int pfvfnum, + u8 *mac_addr, + int port) +{ + struct mbx_fw_cmd_req req =3D { + .datalen =3D cpu_to_le16(sizeof(req.get_mac_addr) + + MUCSE_MBX_REQ_HDR_LEN), + .opcode =3D cpu_to_le16(GET_MAC_ADDRESS), + .get_mac_addr =3D { + .port_mask =3D cpu_to_le32(BIT(port)), + .pfvf_num =3D cpu_to_le32(pfvfnum), + }, + }; + struct mbx_fw_cmd_reply reply =3D {}; + int err; + + err =3D mucse_fw_send_cmd_wait_resp(hw, &req, &reply); + if (err) + return err; + + if (le32_to_cpu(reply.mac_addr.ports) & BIT(port)) + memcpy(mac_addr, reply.mac_addr.addrs[port].mac, ETH_ALEN); + else + return -ENODATA; + + return 0; +} diff --git a/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h b/drivers/ne= t/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h new file mode 100644 index 000000000000..fb24fc12b613 --- /dev/null +++ b/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx_fw.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2020 - 2025 Mucse Corporation. */ + +#ifndef _RNPGBE_MBX_FW_H +#define _RNPGBE_MBX_FW_H + +#include + +#include "rnpgbe.h" + +#define MUCSE_MBX_REQ_HDR_LEN 24 + +enum MUCSE_FW_CMD { + GET_HW_INFO =3D 0x0601, + GET_MAC_ADDRESS =3D 0x0602, + RESET_HW =3D 0x0603, + POWER_UP =3D 0x0803, +}; + +struct mucse_hw_info { + u8 link_stat; + u8 port_mask; + __le32 speed; + __le16 phy_type; + __le16 nic_mode; + __le16 pfnum; + __le32 fw_version; + __le32 axi_mhz; + union { + u8 port_id[4]; + __le32 port_ids; + }; + __le32 bd_uid; + __le32 phy_id; + __le32 wol_status; + __le32 ext_info; +} __packed; + +struct mbx_fw_cmd_req { + __le16 flags; + __le16 opcode; + __le16 datalen; + __le16 ret_value; + __le32 cookie_lo; + __le32 cookie_hi; + __le32 reply_lo; + __le32 reply_hi; + union { + u8 data[32]; + struct { + __le32 version; + __le32 status; + } powerup; + struct { + __le32 port_mask; + __le32 pfvf_num; + } get_mac_addr; + }; +} __packed; + +struct mbx_fw_cmd_reply { + __le16 flags; + __le16 opcode; + __le16 error_code; + __le16 datalen; + __le32 cookie_lo; + __le32 cookie_hi; + union { + u8 data[40]; + struct mac_addr { + __le32 ports; + struct _addr { + /* for macaddr:01:02:03:04:05:06 + * mac-hi=3D0x01020304 mac-lo=3D0x05060000 + */ + u8 mac[8]; + } addrs[4]; + } mac_addr; + struct mucse_hw_info hw_info; + }; +} __packed; + +int mucse_mbx_sync_fw(struct mucse_hw *hw); +int mucse_mbx_powerup(struct mucse_hw *hw, bool is_powerup); +int mucse_mbx_reset_hw(struct mucse_hw *hw); +int mucse_mbx_get_macaddr(struct mucse_hw *hw, int pfvfnum, + u8 *mac_addr, int port); +#endif /* _RNPGBE_MBX_FW_H */ --=20 2.25.1