All of lore.kernel.org
 help / color / mirror / Atom feed
From: "WanRenyong" <wanry@yunsilicon.com>
To: <dev@dpdk.org>
Cc: <ferruh.yigit@amd.com>, <thomas@monjalon.net>,
	 <stephen@networkplumber.org>, <qianr@yunsilicon.com>,
	 <nana@yunsilicon.com>, <zhangxx@yunsilicon.com>,
	 <zhangxx@yunsilicon.com>, <xudw@yunsilicon.com>,
	<jacky@yunsilicon.com>,  <weihg@yunsilicon.com>
Subject: [PATCH v5 03/15] net/xsc: add xsc mailbox
Date: Tue, 07 Jan 2025 10:49:45 +0800	[thread overview]
Message-ID: <20250107024944.1962467-4-wanry@yunsilicon.com> (raw)
In-Reply-To: <20250107024939.1962467-1-wanry@yunsilicon.com>

XSC mailbox is a mechanism used for interaction between PMD and firmware.

Signed-off-by: WanRenyong <wanry@yunsilicon.com>
Signed-off-by: Rong Qian <qianr@yunsilicon.com>
---
 drivers/net/xsc/meson.build     |   1 +
 drivers/net/xsc/xsc_cmd.h       | 387 ++++++++++++++++++
 drivers/net/xsc/xsc_defs.h      |   2 +
 drivers/net/xsc/xsc_vfio_mbox.c | 691 ++++++++++++++++++++++++++++++++
 drivers/net/xsc/xsc_vfio_mbox.h | 142 +++++++
 5 files changed, 1223 insertions(+)
 create mode 100644 drivers/net/xsc/xsc_cmd.h
 create mode 100644 drivers/net/xsc/xsc_vfio_mbox.c
 create mode 100644 drivers/net/xsc/xsc_vfio_mbox.h

diff --git a/drivers/net/xsc/meson.build b/drivers/net/xsc/meson.build
index 683a1f6632..df4c8ea499 100644
--- a/drivers/net/xsc/meson.build
+++ b/drivers/net/xsc/meson.build
@@ -9,4 +9,5 @@ endif
 sources = files(
         'xsc_ethdev.c',
         'xsc_dev.c',
+        'xsc_vfio_mbox.c',
 )
diff --git a/drivers/net/xsc/xsc_cmd.h b/drivers/net/xsc/xsc_cmd.h
new file mode 100644
index 0000000000..433dcd0afa
--- /dev/null
+++ b/drivers/net/xsc/xsc_cmd.h
@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2025 Yunsilicon Technology Co., Ltd.
+ */
+
+#ifndef _XSC_CMD_H_
+#define _XSC_CMD_H_
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <net/if.h>
+
+#define XSC_BOARD_SN_LEN		32
+#define XSC_CMD_QUERY_HCA_CAP_V1	1
+
+enum xsc_cmd_opcode {
+	XSC_CMD_OP_QUERY_HCA_CAP	= 0x100,
+	XSC_CMD_OP_CREATE_CQ		= 0x400,
+	XSC_CMD_OP_DESTROY_CQ		= 0x401,
+	XSC_CMD_OP_CREATE_QP		= 0x500,
+	XSC_CMD_OP_DESTROY_QP		= 0x501,
+	XSC_CMD_OP_RTR2RTS_QP		= 0x504,
+	XSC_CMD_OP_QP_2RST		= 0x50A,
+	XSC_CMD_OP_CREATE_MULTI_QP	= 0x515,
+	XSC_CMD_OP_MODIFY_NIC_HCA	= 0x812,
+	XSC_CMD_OP_MODIFY_RAW_QP	= 0x81f,
+	XSC_CMD_OP_EXEC_NP		= 0x900,
+	XSC_CMD_OP_SET_MTU		= 0x1100,
+	XSC_CMD_OP_QUERY_ETH_MAC	= 0X1101,
+	XSC_CMD_OP_MAX
+};
+
+enum xsc_cmd_status {
+	XSC_CMD_SUCC = 0,
+	XSC_CMD_FAIL,
+	XSC_CMD_TIMEOUT,
+};
+
+struct xsc_cmd_inbox_hdr {
+	rte_be16_t opcode;
+	uint8_t rsvd[4];
+	rte_be16_t ver;
+};
+
+struct xsc_cmd_outbox_hdr {
+	uint8_t status;
+	uint8_t rsvd[5];
+	rte_be16_t ver;
+};
+
+struct xsc_cmd_fw_version {
+	uint8_t major;
+	uint8_t minor;
+	rte_be16_t patch;
+	rte_be32_t tweak;
+	uint8_t extra_flag;
+	uint8_t rsv[7];
+};
+
+struct xsc_cmd_hca_cap {
+	uint8_t rsvd1[12];
+	uint8_t send_seg_num;
+	uint8_t send_wqe_shift;
+	uint8_t recv_seg_num;
+	uint8_t recv_wqe_shift;
+	uint8_t log_max_srq_sz;
+	uint8_t log_max_qp_sz;
+	uint8_t log_max_mtt;
+	uint8_t log_max_qp;
+	uint8_t log_max_strq_sz;
+	uint8_t log_max_srqs;
+	uint8_t rsvd2[2];
+	uint8_t log_max_tso;
+	uint8_t log_max_cq_sz;
+	uint8_t rsvd3;
+	uint8_t log_max_cq;
+	uint8_t log_max_eq_sz;
+	uint8_t log_max_mkey;
+	uint8_t log_max_msix;
+	uint8_t log_max_eq;
+	uint8_t max_indirection;
+	uint8_t log_max_mrw_sz;
+	uint8_t log_max_bsf_list_sz;
+	uint8_t log_max_klm_list_sz;
+	uint8_t rsvd4;
+	uint8_t log_max_ra_req_dc;
+	uint8_t rsvd5;
+	uint8_t log_max_ra_res_dc;
+	uint8_t rsvd6;
+	uint8_t log_max_ra_req_qp;
+	uint8_t log_max_qp_depth;
+	uint8_t log_max_ra_res_qp;
+	rte_be16_t max_vfs;
+	rte_be16_t raweth_qp_id_end;
+	rte_be16_t raw_tpe_qp_num;
+	rte_be16_t max_qp_count;
+	rte_be16_t raweth_qp_id_base;
+	uint8_t rsvd7;
+	uint8_t local_ca_ack_delay;
+	uint8_t max_num_eqs;
+	uint8_t num_ports;
+	uint8_t log_max_msg;
+	uint8_t mac_port;
+	rte_be16_t raweth_rss_qp_id_base;
+	rte_be16_t stat_rate_support;
+	uint8_t rsvd8[2];
+	rte_be64_t flags;
+	uint8_t rsvd9;
+	uint8_t uar_sz;
+	uint8_t rsvd10;
+	uint8_t log_pg_sz;
+	rte_be16_t bf_log_bf_reg_size;
+	rte_be16_t msix_base;
+	rte_be16_t msix_num;
+	rte_be16_t max_desc_sz_sq;
+	uint8_t rsvd11[2];
+	rte_be16_t max_desc_sz_rq;
+	uint8_t rsvd12[2];
+	rte_be16_t max_desc_sz_sq_dc;
+	uint8_t rsvd13[4];
+	rte_be16_t max_qp_mcg;
+	uint8_t rsvd14;
+	uint8_t log_max_mcg;
+	uint8_t rsvd15;
+	uint8_t log_max_pd;
+	uint8_t rsvd16;
+	uint8_t log_max_xrcd;
+	uint8_t rsvd17[40];
+	rte_be32_t uar_page_sz;
+	uint8_t rsvd18[8];
+	rte_be32_t hw_feature_flag;
+	rte_be16_t pf0_vf_funcid_base;
+	rte_be16_t pf0_vf_funcid_top;
+	rte_be16_t pf1_vf_funcid_base;
+	rte_be16_t pf1_vf_funcid_top;
+	rte_be16_t pcie0_pf_funcid_base;
+	rte_be16_t pcie0_pf_funcid_top;
+	rte_be16_t pcie1_pf_funcid_base;
+	rte_be16_t pcie1_pf_funcid_top;
+	uint8_t log_msx_atomic_size_qp;
+	uint8_t pcie_host;
+	uint8_t rsvd19;
+	uint8_t log_msx_atomic_size_dc;
+	uint8_t board_sn[XSC_BOARD_SN_LEN];
+	uint8_t max_tc;
+	uint8_t mac_bit;
+	rte_be16_t funcid_to_logic_port;
+	uint8_t rsvd20[6];
+	uint8_t nif_port_num;
+	uint8_t reg_mr_via_cmdq;
+	rte_be32_t hca_core_clock;
+	rte_be32_t max_rwq_indirection_tables;
+	rte_be32_t max_rwq_indirection_table_size;
+	rte_be32_t chip_ver_h;
+	rte_be32_t chip_ver_m;
+	rte_be32_t chip_ver_l;
+	rte_be32_t hotfix_num;
+	rte_be32_t feature_flag;
+	rte_be32_t rx_pkt_len_max;
+	rte_be32_t glb_func_id;
+	rte_be64_t tx_db;
+	rte_be64_t rx_db;
+	rte_be64_t complete_db;
+	rte_be64_t complete_reg;
+	rte_be64_t event_db;
+	rte_be32_t qp_rate_limit_min;
+	rte_be32_t qp_rate_limit_max;
+	struct xsc_cmd_fw_version fw_ver;
+	uint8_t lag_logic_port_ofst;
+	rte_be64_t max_mr_size;
+	rte_be16_t max_cmd_in_len;
+	rte_be16_t max_cmd_out_len;
+};
+
+struct xsc_cmd_query_hca_cap_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	rte_be16_t cpu_num;
+	uint8_t rsvd[6];
+};
+
+struct xsc_cmd_query_hca_cap_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t rsvd[8];
+	struct xsc_cmd_hca_cap hca_cap;
+};
+
+struct xsc_cmd_cq_context {
+	uint16_t eqn;
+	uint16_t pa_num;
+	uint16_t glb_func_id;
+	uint8_t log_cq_sz;
+	uint8_t cq_type;
+};
+
+struct xsc_cmd_create_cq_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	struct xsc_cmd_cq_context ctx;
+	uint64_t pas[];
+};
+
+struct xsc_cmd_create_cq_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint32_t cqn;
+	uint8_t rsvd[4];
+};
+
+struct xsc_cmd_destroy_cq_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	uint32_t cqn;
+	uint8_t rsvd[4];
+};
+
+struct xsc_cmd_destroy_cq_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t rsvd[8];
+};
+
+struct xsc_cmd_create_qp_request {
+	rte_be16_t input_qpn;
+	rte_be16_t pa_num;
+	uint8_t qp_type;
+	uint8_t log_sq_sz;
+	uint8_t log_rq_sz;
+	uint8_t dma_direct;
+	rte_be32_t pdn;
+	rte_be16_t cqn_send;
+	rte_be16_t cqn_recv;
+	rte_be16_t glb_funcid;
+	uint8_t page_shift;
+	uint8_t rsvd;
+	rte_be64_t pas[];
+};
+
+struct xsc_cmd_create_qp_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	struct xsc_cmd_create_qp_request req;
+};
+
+struct xsc_cmd_create_qp_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint32_t qpn;
+	uint8_t rsvd[4];
+};
+
+struct xsc_cmd_create_multiqp_mbox_in {
+	struct xsc_cmd_inbox_hdr  hdr;
+	rte_be16_t qp_num;
+	uint8_t qp_type;
+	uint8_t rsvd;
+	rte_be32_t req_len;
+	uint8_t data[];
+};
+
+struct xsc_cmd_create_multiqp_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	rte_be32_t qpn_base;
+};
+
+struct xsc_cmd_destroy_qp_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	rte_be32_t qpn;
+	uint8_t rsvd[4];
+};
+
+struct xsc_cmd_destroy_qp_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t rsvd[8];
+};
+
+struct xsc_cmd_qp_context {
+	rte_be32_t remote_qpn;
+	rte_be32_t cqn_send;
+	rte_be32_t cqn_recv;
+	rte_be32_t next_send_psn;
+	rte_be32_t next_recv_psn;
+	rte_be32_t pdn;
+	rte_be16_t src_udp_port;
+	rte_be16_t path_id;
+	uint8_t mtu_mode;
+	uint8_t lag_sel;
+	uint8_t lag_sel_en;
+	uint8_t retry_cnt;
+	uint8_t rnr_retry;
+	uint8_t dscp;
+	uint8_t state;
+	uint8_t hop_limit;
+	uint8_t dmac[6];
+	uint8_t smac[6];
+	rte_be32_t dip[4];
+	rte_be32_t sip[4];
+	rte_be16_t ip_type;
+	rte_be16_t grp_id;
+	uint8_t vlan_valid;
+	uint8_t dci_cfi_prio_sl;
+	rte_be16_t vlan_id;
+	uint8_t qp_out_port;
+	uint8_t pcie_no;
+	rte_be16_t lag_id;
+	rte_be16_t func_id;
+	rte_be16_t rsvd;
+};
+
+struct xsc_cmd_modify_qp_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	rte_be32_t qpn;
+	struct xsc_cmd_qp_context ctx;
+	uint8_t no_need_wait;
+};
+
+struct xsc_cmd_modify_qp_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t rsvd[8];
+};
+
+struct xsc_cmd_modify_raw_qp_request {
+	uint16_t qpn;
+	uint16_t lag_id;
+	uint16_t func_id;
+	uint8_t dma_direct;
+	uint8_t prio;
+	uint8_t qp_out_port;
+	uint8_t rsvd[7];
+};
+
+struct xsc_cmd_modify_raw_qp_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	uint8_t pcie_no;
+	uint8_t rsv[7];
+	struct xsc_cmd_modify_raw_qp_request req;
+};
+
+struct xsc_cmd_modify_raw_qp_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t rsvd[8];
+};
+
+struct xsc_cmd_set_mtu_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	rte_be16_t mtu;
+	rte_be16_t rx_buf_sz_min;
+	uint8_t mac_port;
+	uint8_t rsvd;
+};
+
+struct xsc_cmd_set_mtu_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+};
+
+struct xsc_cmd_query_eth_mac_mbox_in {
+	struct xsc_cmd_inbox_hdr  hdr;
+	uint8_t index;
+};
+
+struct xsc_cmd_query_eth_mac_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t mac[6];
+};
+
+struct xsc_cmd_nic_attr {
+	rte_be16_t caps;
+	rte_be16_t caps_mask;
+	uint8_t mac_addr[6];
+};
+
+struct xsc_cmd_rss_modify_attr {
+	uint8_t caps_mask;
+	uint8_t rss_en;
+	rte_be16_t rqn_base;
+	rte_be16_t rqn_num;
+	uint8_t hfunc;
+	rte_be32_t hash_tmpl;
+	uint8_t hash_key[52];
+};
+
+struct xsc_cmd_modify_nic_hca_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	struct xsc_cmd_nic_attr nic;
+	struct xsc_cmd_rss_modify_attr rss;
+};
+
+struct xsc_cmd_modify_nic_hca_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t rsvd[4];
+};
+
+#endif /* _XSC_CMD_H_ */
diff --git a/drivers/net/xsc/xsc_defs.h b/drivers/net/xsc/xsc_defs.h
index 60244425cd..a4b36685a6 100644
--- a/drivers/net/xsc/xsc_defs.h
+++ b/drivers/net/xsc/xsc_defs.h
@@ -5,6 +5,8 @@
 #ifndef XSC_DEFS_H_
 #define XSC_DEFS_H_
 
+#define XSC_PAGE_SIZE			4096
+
 #define XSC_PCI_VENDOR_ID		0x1f67
 #define XSC_PCI_DEV_ID_MS		0x1111
 #define XSC_PCI_DEV_ID_MSVF		0x1112
diff --git a/drivers/net/xsc/xsc_vfio_mbox.c b/drivers/net/xsc/xsc_vfio_mbox.c
new file mode 100644
index 0000000000..b1bb06feb8
--- /dev/null
+++ b/drivers/net/xsc/xsc_vfio_mbox.c
@@ -0,0 +1,691 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2025 Yunsilicon Technology Co., Ltd.
+ */
+#include <rte_malloc.h>
+#include <bus_pci_driver.h>
+
+#include "xsc_vfio_mbox.h"
+#include "xsc_log.h"
+
+#define XSC_MBOX_BUF_NUM		2048
+#define XSC_MBOX_BUF_CACHE_SIZE		256
+#define XSC_CMDQ_DEPTH_LOG		5
+#define XSC_CMDQ_ELEMENT_SIZE_LOG	6
+#define XSC_CMDQ_REQ_TYPE		7
+#define XSC_CMDQ_WAIT_TIMEOUT		10
+#define XSC_CMDQ_WAIT_DELAY_MS		100
+#define XSC_CMD_OP_DUMMY		0x10d
+
+#define XSC_PF_CMDQ_ELEMENT_SZ		0x1020020
+#define XSC_PF_CMDQ_REQ_BASE_H_ADDR	0x1022000
+#define XSC_PF_CMDQ_REQ_BASE_L_ADDR	0x1024000
+#define XSC_PF_CMDQ_RSP_BASE_H_ADDR	0x102a000
+#define XSC_PF_CMDQ_RSP_BASE_L_ADDR	0x102c000
+#define XSC_PF_CMDQ_REQ_PID		0x1026000
+#define XSC_PF_CMDQ_REQ_CID		0x1028000
+#define XSC_PF_CMDQ_RSP_PID		0x102e000
+#define XSC_PF_CMDQ_RSP_CID		0x1030000
+#define XSC_PF_CMDQ_DEPTH		0x1020028
+
+#define XSC_VF_CMDQ_REQ_BASE_H_ADDR	0x0
+#define XSC_VF_CMDQ_REQ_BASE_L_ADDR	0x4
+#define XSC_VF_CMDQ_RSP_BASE_H_ADDR	0x10
+#define XSC_VF_CMDQ_RSP_BASE_L_ADDR	0x14
+#define XSC_VF_CMDQ_REQ_PID		0x8
+#define XSC_VF_CMDQ_REQ_CID		0xc
+#define XSC_VF_CMDQ_RSP_PID		0x18
+#define XSC_VF_CMDQ_RSP_CID		0x1c
+#define XSC_VF_CMDQ_ELEMENT_SZ		0x28
+#define XSC_VF_CMDQ_DEPTH		0x2c
+
+static const char * const xsc_cmd_error[] = {
+	"xsc cmd success",
+	"xsc cmd fail",
+	"xsc cmd timeout"
+};
+
+static struct xsc_cmdq_config xsc_pf_config = {
+	.req_pid_addr = XSC_PF_CMDQ_REQ_PID,
+	.req_cid_addr = XSC_PF_CMDQ_REQ_CID,
+	.rsp_pid_addr = XSC_PF_CMDQ_RSP_PID,
+	.rsp_cid_addr = XSC_PF_CMDQ_RSP_CID,
+	.req_h_addr = XSC_PF_CMDQ_REQ_BASE_H_ADDR,
+	.req_l_addr = XSC_PF_CMDQ_REQ_BASE_L_ADDR,
+	.rsp_h_addr = XSC_PF_CMDQ_RSP_BASE_H_ADDR,
+	.rsp_l_addr = XSC_PF_CMDQ_RSP_BASE_L_ADDR,
+	.elt_sz_addr = XSC_PF_CMDQ_ELEMENT_SZ,
+	.depth_addr = XSC_PF_CMDQ_DEPTH,
+};
+
+static struct xsc_cmdq_config xsc_vf_config = {
+	.req_pid_addr = XSC_VF_CMDQ_REQ_PID,
+	.req_cid_addr = XSC_VF_CMDQ_REQ_CID,
+	.rsp_pid_addr = XSC_VF_CMDQ_RSP_PID,
+	.rsp_cid_addr = XSC_VF_CMDQ_RSP_CID,
+	.req_h_addr = XSC_VF_CMDQ_REQ_BASE_H_ADDR,
+	.req_l_addr = XSC_VF_CMDQ_REQ_BASE_L_ADDR,
+	.rsp_h_addr = XSC_VF_CMDQ_RSP_BASE_H_ADDR,
+	.rsp_l_addr = XSC_VF_CMDQ_RSP_BASE_L_ADDR,
+	.elt_sz_addr = XSC_VF_CMDQ_ELEMENT_SZ,
+	.depth_addr = XSC_VF_CMDQ_DEPTH,
+};
+
+static void
+xsc_cmdq_config_init(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	if (!xsc_dev_is_vf(xdev))
+		cmdq->config = &xsc_pf_config;
+	else
+		cmdq->config = &xsc_vf_config;
+}
+
+static void
+xsc_cmdq_rsp_cid_update(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	uint32_t rsp_pid;
+
+	cmdq->rsp_cid = rte_read32((uint8_t *)xdev->bar_addr + cmdq->config->rsp_cid_addr);
+	rsp_pid = rte_read32((uint8_t *)xdev->bar_addr + cmdq->config->rsp_pid_addr);
+	if (rsp_pid != cmdq->rsp_cid) {
+		PMD_DRV_LOG(INFO, "Update cid(%u) to latest pid(%u)",
+			    cmdq->rsp_cid, rsp_pid);
+		cmdq->rsp_cid = rsp_pid;
+		rte_write32(cmdq->rsp_cid, (uint8_t *)xdev->bar_addr + cmdq->config->rsp_cid_addr);
+	}
+}
+
+static void
+xsc_cmdq_depth_set(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	cmdq->depth_n = XSC_CMDQ_DEPTH_LOG;
+	cmdq->depth_m = (1 << XSC_CMDQ_DEPTH_LOG) - 1;
+	rte_write32(1 << cmdq->depth_n, (uint8_t *)xdev->bar_addr + cmdq->config->depth_addr);
+}
+
+static int
+xsc_cmdq_elt_size_check(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	uint32_t elts_n;
+
+	elts_n = rte_read32((uint8_t *)xdev->bar_addr + cmdq->config->elt_sz_addr);
+	if (elts_n != XSC_CMDQ_ELEMENT_SIZE_LOG) {
+		PMD_DRV_LOG(ERR, "The cmdq elt size log(%u) is error, should be %u",
+			    elts_n, XSC_CMDQ_ELEMENT_SIZE_LOG);
+		rte_errno = ENODEV;
+		return -1;
+	}
+
+	return 0;
+}
+
+static void
+xsc_cmdq_req_base_addr_set(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	uint32_t h_addr, l_addr;
+
+	h_addr = (uint32_t)(cmdq->req_mz->iova >> 32);
+	l_addr = (uint32_t)(cmdq->req_mz->iova);
+	rte_write32(h_addr, (uint8_t *)xdev->bar_addr + cmdq->config->req_h_addr);
+	rte_write32(l_addr, (uint8_t *)xdev->bar_addr + cmdq->config->req_l_addr);
+}
+
+static void
+xsc_cmdq_rsp_base_addr_set(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	uint32_t h_addr, l_addr;
+
+	h_addr = (uint32_t)(cmdq->rsp_mz->iova >> 32);
+	l_addr = (uint32_t)(cmdq->rsp_mz->iova);
+	rte_write32(h_addr, (uint8_t *)xdev->bar_addr + cmdq->config->rsp_h_addr);
+	rte_write32(l_addr, (uint8_t *)xdev->bar_addr + cmdq->config->rsp_l_addr);
+}
+
+static void
+xsc_cmdq_mbox_free(struct xsc_dev *xdev, struct xsc_cmdq_mbox *mbox)
+{
+	struct xsc_cmdq_mbox *next, *head;
+	struct xsc_vfio_priv *priv = (struct xsc_vfio_priv *)xdev->dev_priv;
+
+	head = mbox;
+	while (head != NULL) {
+		next = head->next;
+		if (head->buf != NULL)
+			rte_mempool_put(priv->cmdq->mbox_buf_pool, head->buf);
+		free(head);
+		head = next;
+	}
+}
+
+static struct xsc_cmdq_mbox *
+xsc_cmdq_mbox_alloc(struct xsc_dev *xdev)
+{
+	struct xsc_cmdq_mbox *mbox;
+	int ret;
+	struct xsc_vfio_priv *priv = (struct xsc_vfio_priv *)xdev->dev_priv;
+
+	mbox = (struct xsc_cmdq_mbox *)malloc(sizeof(*mbox));
+	if (mbox == NULL) {
+		rte_errno = -ENOMEM;
+		goto error;
+	}
+	memset(mbox, 0, sizeof(struct xsc_cmdq_mbox));
+
+	ret = rte_mempool_get(priv->cmdq->mbox_buf_pool, (void **)&mbox->buf);
+	if (ret != 0)
+		goto error;
+	mbox->buf_dma = rte_mempool_virt2iova(mbox->buf);
+	memset(mbox->buf, 0, sizeof(struct xsc_cmdq_mbox_buf));
+	mbox->next = NULL;
+
+	return mbox;
+
+error:
+	xsc_cmdq_mbox_free(xdev, mbox);
+	return NULL;
+}
+
+static struct xsc_cmdq_mbox *
+xsc_cmdq_mbox_alloc_bulk(struct xsc_dev *xdev, int n)
+{
+	int i;
+	struct xsc_cmdq_mbox *head = NULL;
+	struct xsc_cmdq_mbox *mbox;
+	struct xsc_cmdq_mbox_buf *mbox_buf;
+
+	for (i = 0; i < n; i++) {
+		mbox = xsc_cmdq_mbox_alloc(xdev);
+		if (mbox == NULL) {
+			PMD_DRV_LOG(ERR, "Failed to alloc mailbox");
+			goto error;
+		}
+
+		mbox_buf = mbox->buf;
+		mbox->next = head;
+		mbox_buf->next = rte_cpu_to_be_64(mbox->next ? mbox->next->buf_dma : 0);
+		mbox_buf->block_num = rte_cpu_to_be_32(n - i - 1);
+		head = mbox;
+	}
+
+	return head;
+
+error:
+	xsc_cmdq_mbox_free(xdev, head);
+	return NULL;
+}
+
+static void
+xsc_cmdq_req_msg_free(struct xsc_dev *xdev, struct xsc_cmdq_req_msg *msg)
+{
+	struct xsc_cmdq_mbox *head;
+
+	if (msg == NULL)
+		return;
+
+	head = msg->next;
+	xsc_cmdq_mbox_free(xdev, head);
+	free(msg);
+}
+
+static struct xsc_cmdq_req_msg *
+xsc_cmdq_req_msg_alloc(struct xsc_dev *xdev, int len)
+{
+	struct xsc_cmdq_req_msg *msg;
+	struct xsc_cmdq_mbox *head = NULL;
+	int cmd_len, nb_mbox;
+
+	msg = (struct xsc_cmdq_req_msg *)malloc(sizeof(*msg));
+	if (msg == NULL) {
+		rte_errno = -ENOMEM;
+		goto error;
+	}
+	memset(msg, 0, sizeof(*msg));
+
+	cmd_len = len - RTE_MIN(sizeof(msg->hdr.data), (uint32_t)len);
+	nb_mbox = (cmd_len + XSC_CMDQ_DATA_SIZE - 1) / XSC_CMDQ_DATA_SIZE;
+	head = xsc_cmdq_mbox_alloc_bulk(xdev, nb_mbox);
+	if (head == NULL && nb_mbox != 0)
+		goto error;
+
+	msg->next = head;
+	msg->len = len;
+
+	return msg;
+
+error:
+	xsc_cmdq_req_msg_free(xdev, msg);
+	return NULL;
+}
+
+static void
+xsc_cmdq_rsp_msg_free(struct xsc_dev *xdev, struct xsc_cmdq_rsp_msg *msg)
+{
+	struct xsc_cmdq_mbox *head;
+
+	if (msg == NULL)
+		return;
+
+	head = msg->next;
+	xsc_cmdq_mbox_free(xdev, head);
+	free(msg);
+}
+
+static struct xsc_cmdq_rsp_msg *
+xsc_cmdq_rsp_msg_alloc(struct xsc_dev *xdev, int len)
+{
+	struct xsc_cmdq_rsp_msg *msg;
+	struct xsc_cmdq_mbox *head = NULL;
+	int cmd_len, nb_mbox;
+
+	msg = (struct xsc_cmdq_rsp_msg *)malloc(sizeof(*msg));
+	if (msg == NULL) {
+		rte_errno = -ENOMEM;
+		goto error;
+	}
+	memset(msg, 0, sizeof(*msg));
+
+	cmd_len = len - RTE_MIN(sizeof(msg->hdr.data), (uint32_t)len);
+	nb_mbox = (cmd_len + XSC_CMDQ_DATA_SIZE - 1) / XSC_CMDQ_DATA_SIZE;
+	head = xsc_cmdq_mbox_alloc_bulk(xdev, nb_mbox);
+	if (head == NULL && nb_mbox != 0)
+		goto error;
+
+	msg->next = head;
+	msg->len = len;
+
+	return msg;
+
+error:
+	xsc_cmdq_rsp_msg_free(xdev, msg);
+	return NULL;
+}
+
+static void
+xsc_cmdq_msg_destruct(struct xsc_dev *xdev,
+		      struct xsc_cmdq_req_msg **req_msg,
+		      struct xsc_cmdq_rsp_msg **rsp_msg)
+{
+	xsc_cmdq_req_msg_free(xdev, *req_msg);
+	xsc_cmdq_rsp_msg_free(xdev, *rsp_msg);
+	*req_msg = NULL;
+	*rsp_msg = NULL;
+}
+
+static int
+xsc_cmdq_msg_construct(struct xsc_dev *xdev,
+		       struct xsc_cmdq_req_msg **req_msg, int in_len,
+		       struct xsc_cmdq_rsp_msg **rsp_msg, int out_len)
+{
+	*req_msg = xsc_cmdq_req_msg_alloc(xdev, in_len);
+	if (*req_msg == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to alloc xsc cmd request msg");
+		goto error;
+	}
+
+	*rsp_msg = xsc_cmdq_rsp_msg_alloc(xdev, out_len);
+	if (*rsp_msg == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to alloc xsc cmd response msg");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	xsc_cmdq_msg_destruct(xdev, req_msg, rsp_msg);
+	return -1;
+}
+
+static int
+xsc_cmdq_req_msg_copy(struct xsc_cmdq_req_msg *req_msg, void *data_in, int in_len)
+{
+	struct xsc_cmdq_mbox_buf *mbox_buf;
+	struct xsc_cmdq_mbox *mbox;
+	int copy;
+	uint8_t *data = data_in;
+
+	if (req_msg == NULL || data == NULL)
+		return -1;
+
+	copy = RTE_MIN((uint32_t)in_len, sizeof(req_msg->hdr.data));
+	memcpy(req_msg->hdr.data, data, copy);
+
+	in_len -= copy;
+	data += copy;
+
+	mbox = req_msg->next;
+	while (in_len > 0) {
+		if (mbox == NULL)
+			return -1;
+
+		copy = RTE_MIN(in_len, XSC_CMDQ_DATA_SIZE);
+		mbox_buf = mbox->buf;
+		memcpy(mbox_buf->data, data, copy);
+		mbox_buf->owner_status = 0;
+		data += copy;
+		in_len -= copy;
+		mbox = mbox->next;
+	}
+
+	return 0;
+}
+
+static int
+xsc_cmdq_rsp_msg_copy(void *data_out, struct xsc_cmdq_rsp_msg *rsp_msg, int out_len)
+{
+	struct xsc_cmdq_mbox_buf *mbox_buf;
+	struct xsc_cmdq_mbox *mbox;
+	int copy;
+	uint8_t *data = data_out;
+
+	if (data == NULL || rsp_msg == NULL)
+		return -1;
+
+	copy = RTE_MIN((uint32_t)out_len, sizeof(rsp_msg->hdr.data));
+	memcpy(data, rsp_msg->hdr.data, copy);
+	out_len -= copy;
+	data += copy;
+
+	mbox = rsp_msg->next;
+	while (out_len > 0) {
+		if (mbox == NULL)
+			return -1;
+		copy = RTE_MIN(out_len, XSC_CMDQ_DATA_SIZE);
+		mbox_buf = mbox->buf;
+		if (!mbox_buf->owner_status)
+			PMD_DRV_LOG(ERR, "Failed to check cmd owner");
+		memcpy(data, mbox_buf->data, copy);
+		data += copy;
+		out_len -= copy;
+		mbox = mbox->next;
+	}
+
+	return 0;
+}
+
+static enum xsc_cmd_status
+xsc_cmdq_wait_completion(struct xsc_dev *xdev, struct xsc_cmdq_rsp_msg *rsp_msg)
+{
+	struct xsc_vfio_priv *priv = (struct xsc_vfio_priv *)xdev->dev_priv;
+	struct xsc_cmd_queue *cmdq = priv->cmdq;
+	volatile struct xsc_cmdq_rsp_layout *rsp_lay;
+	struct xsc_cmd_outbox_hdr *out_hdr = (struct xsc_cmd_outbox_hdr *)rsp_msg->hdr.data;
+	int count = (XSC_CMDQ_WAIT_TIMEOUT * 1000) / XSC_CMDQ_WAIT_DELAY_MS;
+	uint32_t rsp_pid;
+	uint8_t cmd_status;
+	uint32_t i;
+
+	while (count-- > 0) {
+		rsp_pid = rte_read32((uint8_t *)xdev->bar_addr + cmdq->config->rsp_pid_addr);
+		if (rsp_pid == cmdq->rsp_cid) {
+			rte_delay_ms(XSC_CMDQ_WAIT_DELAY_MS);
+			continue;
+		}
+
+		rsp_lay = cmdq->rsp_lay + cmdq->rsp_cid;
+		if (cmdq->owner_learn == 0) {
+			/* First time learning owner_bit from hardware */
+			cmdq->owner_bit = rsp_lay->owner_bit;
+			cmdq->owner_learn = 1;
+		}
+
+		/* Waiting for dma to complete */
+		if (cmdq->owner_bit != rsp_lay->owner_bit)
+			continue;
+
+		for (i = 0; i < XSC_CMDQ_RSP_INLINE_SIZE; i++)
+			rsp_msg->hdr.data[i] = rsp_lay->out[i];
+
+		cmdq->rsp_cid = (cmdq->rsp_cid + 1) & cmdq->depth_m;
+		rte_write32(cmdq->rsp_cid, (uint8_t *)xdev->bar_addr + cmdq->config->rsp_cid_addr);
+
+		/* Change owner bit */
+		if (cmdq->rsp_cid == 0)
+			cmdq->owner_bit = !cmdq->owner_bit;
+
+		cmd_status = out_hdr->status;
+		if (cmd_status != 0)
+			return XSC_CMD_FAIL;
+		return XSC_CMD_SUCC;
+	}
+
+	return XSC_CMD_TIMEOUT;
+}
+
+static int
+xsc_cmdq_dummy_invoke(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq, uint32_t start, int num)
+{
+	struct xsc_cmdq_dummy_mbox_in in;
+	struct xsc_cmdq_dummy_mbox_out out;
+	struct xsc_cmdq_req_msg *req_msg = NULL;
+	struct xsc_cmdq_rsp_msg *rsp_msg = NULL;
+	struct xsc_cmdq_req_layout *req_lay;
+	int in_len = sizeof(in);
+	int out_len = sizeof(out);
+	int ret, i;
+	uint32_t start_pid = start;
+
+	memset(&in, 0, sizeof(in));
+	in.hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_DUMMY);
+
+	ret = xsc_cmdq_msg_construct(xdev, &req_msg, in_len, &rsp_msg, out_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Failed to construct cmd msg for dummy exec");
+		return -1;
+	}
+
+	ret = xsc_cmdq_req_msg_copy(req_msg, &in, in_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Failed to copy cmd buf to request msg for dummy exec");
+		goto error;
+	}
+
+	rte_spinlock_lock(&cmdq->lock);
+
+	for (i = 0; i < num; i++) {
+		req_lay = cmdq->req_lay + start_pid;
+		memset(req_lay, 0, sizeof(*req_lay));
+		memcpy(req_lay->in, req_msg->hdr.data, sizeof(req_lay->in));
+		req_lay->inlen = rte_cpu_to_be_32(req_msg->len);
+		req_lay->outlen = rte_cpu_to_be_32(rsp_msg->len);
+		req_lay->sig = 0xff;
+		req_lay->idx = 0;
+		req_lay->type = XSC_CMDQ_REQ_TYPE;
+		start_pid = (start_pid + 1) & cmdq->depth_m;
+	}
+
+	/* Ring doorbell after the descriptor is valid */
+	rte_write32(cmdq->req_pid, (uint8_t *)xdev->bar_addr + cmdq->config->req_pid_addr);
+
+	ret = xsc_cmdq_wait_completion(xdev, rsp_msg);
+	rte_spinlock_unlock(&cmdq->lock);
+
+error:
+	xsc_cmdq_msg_destruct(xdev, &req_msg, &rsp_msg);
+	return ret;
+}
+
+static int
+xsc_cmdq_req_status_restore(struct xsc_dev *xdev, struct xsc_cmd_queue *cmdq)
+{
+	uint32_t req_pid, req_cid;
+	uint32_t cnt;
+
+	req_pid = rte_read32((uint8_t *)xdev->bar_addr + cmdq->config->req_pid_addr);
+	req_cid = rte_read32((uint8_t *)xdev->bar_addr + cmdq->config->req_cid_addr);
+
+	if (req_pid >= (uint32_t)(1 << cmdq->depth_n) ||
+	    req_cid >= (uint32_t)(1 << cmdq->depth_n)) {
+		PMD_DRV_LOG(ERR, "Request pid %u and cid %u must be less than %u",
+			    req_pid, req_cid, 1 << cmdq->depth_n);
+		return -1;
+	}
+
+	cmdq->req_pid = req_pid;
+	if (req_pid == req_cid)
+		return 0;
+
+	cnt = (req_pid > req_cid) ? (req_pid - req_cid) :
+		((1 << cmdq->depth_n) + req_pid - req_cid);
+	if (xsc_cmdq_dummy_invoke(xdev, cmdq, req_cid, cnt) != 0) {
+		PMD_DRV_LOG(ERR, "Failed to dummy invoke xsc cmd");
+		return -1;
+	}
+
+	return 0;
+}
+
+void
+xsc_vfio_mbox_destroy(struct xsc_cmd_queue *cmdq)
+{
+	if (cmdq == NULL)
+		return;
+
+	rte_memzone_free(cmdq->req_mz);
+	rte_memzone_free(cmdq->rsp_mz);
+	rte_mempool_free(cmdq->mbox_buf_pool);
+	rte_free(cmdq);
+}
+
+int
+xsc_vfio_mbox_init(struct xsc_dev *xdev)
+{
+	struct xsc_cmd_queue *cmdq;
+	struct xsc_vfio_priv *priv = (struct xsc_vfio_priv *)xdev->dev_priv;
+	char name[RTE_MEMZONE_NAMESIZE] = { 0 };
+	uint32_t size;
+
+	cmdq = rte_zmalloc(NULL, sizeof(*cmdq), RTE_CACHE_LINE_SIZE);
+	if (cmdq == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to alloc memory for xsc_cmd_queue");
+		return -1;
+	}
+
+	snprintf(name, RTE_MEMZONE_NAMESIZE, "%s_cmdq", xdev->pci_dev->device.name);
+	size = (1 << XSC_CMDQ_DEPTH_LOG) * sizeof(struct xsc_cmdq_req_layout);
+	cmdq->req_mz = rte_memzone_reserve_aligned(name,
+						   size, SOCKET_ID_ANY,
+						   RTE_MEMZONE_IOVA_CONTIG,
+						   XSC_PAGE_SIZE);
+	if (cmdq->req_mz == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to alloc memory for cmd queue");
+		goto error;
+	}
+	cmdq->req_lay = cmdq->req_mz->addr;
+
+	snprintf(name, RTE_MEMZONE_NAMESIZE, "%s_cmd_cq", xdev->pci_dev->device.name);
+	size = (1 << XSC_CMDQ_DEPTH_LOG) * sizeof(struct xsc_cmdq_rsp_layout);
+	cmdq->rsp_mz = rte_memzone_reserve_aligned(name,
+						   size, SOCKET_ID_ANY,
+						   RTE_MEMZONE_IOVA_CONTIG,
+						   XSC_PAGE_SIZE);
+	if (cmdq->rsp_mz == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to alloc memory for cmd cq");
+		goto error;
+	}
+	cmdq->rsp_lay = cmdq->rsp_mz->addr;
+
+	snprintf(name, RTE_MEMZONE_NAMESIZE, "%s_mempool", xdev->pci_dev->device.name);
+	cmdq->mbox_buf_pool = rte_mempool_create(name, XSC_MBOX_BUF_NUM,
+						 sizeof(struct xsc_cmdq_mbox_buf),
+						 XSC_MBOX_BUF_CACHE_SIZE, 0,
+						 NULL, NULL, NULL, NULL,
+						 SOCKET_ID_ANY, 0);
+	if (cmdq->mbox_buf_pool == NULL) {
+		PMD_DRV_LOG(ERR, "Failed to create mailbox buf pool");
+		goto error;
+	}
+
+	xsc_cmdq_config_init(xdev, cmdq);
+	xsc_cmdq_rsp_cid_update(xdev, cmdq);
+	xsc_cmdq_depth_set(xdev, cmdq);
+	if (xsc_cmdq_elt_size_check(xdev, cmdq) != 0)
+		goto error;
+
+	xsc_cmdq_req_base_addr_set(xdev, cmdq);
+	xsc_cmdq_rsp_base_addr_set(xdev, cmdq);
+	/* Check request status and restore it */
+	if (xsc_cmdq_req_status_restore(xdev, cmdq) != 0)
+		goto error;
+
+	rte_spinlock_init(&cmdq->lock);
+	priv->cmdq = cmdq;
+	return 0;
+
+error:
+	xsc_vfio_mbox_destroy(cmdq);
+	return -1;
+}
+
+static enum xsc_cmd_status
+xsc_cmdq_invoke(struct xsc_dev *xdev, struct xsc_cmdq_req_msg *req_msg,
+		struct xsc_cmdq_rsp_msg *rsp_msg)
+{
+	struct xsc_vfio_priv *priv = (struct xsc_vfio_priv *)xdev->dev_priv;
+	struct xsc_cmd_queue *cmdq = priv->cmdq;
+	struct xsc_cmdq_req_layout *req_lay;
+	enum xsc_cmd_status status = XSC_CMD_FAIL;
+
+	rte_spinlock_lock(&cmdq->lock);
+	req_lay = cmdq->req_lay + cmdq->req_pid;
+	memset(req_lay, 0, sizeof(*req_lay));
+	memcpy(req_lay->in, req_msg->hdr.data, sizeof(req_lay->in));
+	if (req_msg->next != NULL)
+		req_lay->in_ptr = rte_cpu_to_be_64(req_msg->next->buf_dma);
+	req_lay->inlen = rte_cpu_to_be_32(req_msg->len);
+
+	if (rsp_msg->next != NULL)
+		req_lay->out_ptr = rte_cpu_to_be_64(rsp_msg->next->buf_dma);
+	req_lay->outlen = rte_cpu_to_be_32(rsp_msg->len);
+
+	req_lay->sig = 0xff;
+	req_lay->idx = 0;
+	req_lay->type = XSC_CMDQ_REQ_TYPE;
+
+	/* Ring doorbell after the descriptor is valid */
+	cmdq->req_pid = (cmdq->req_pid + 1) & cmdq->depth_m;
+	rte_write32(cmdq->req_pid, (uint8_t *)xdev->bar_addr + cmdq->config->req_pid_addr);
+
+	status = xsc_cmdq_wait_completion(xdev, rsp_msg);
+	rte_spinlock_unlock(&cmdq->lock);
+
+	return status;
+}
+
+int
+xsc_vfio_mbox_exec(struct xsc_dev *xdev, void *data_in,
+	      int in_len, void *data_out, int out_len)
+{
+	struct xsc_cmdq_req_msg *req_msg = NULL;
+	struct xsc_cmdq_rsp_msg *rsp_msg = NULL;
+	int ret;
+	enum xsc_cmd_status status;
+
+	ret = xsc_cmdq_msg_construct(xdev, &req_msg, in_len, &rsp_msg, out_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Failed to construct cmd msg");
+		return -1;
+	}
+
+	ret = xsc_cmdq_req_msg_copy(req_msg, data_in, in_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Failed to copy cmd buf to request msg");
+		goto error;
+	}
+
+	status = xsc_cmdq_invoke(xdev, req_msg, rsp_msg);
+	if (status != XSC_CMD_SUCC) {
+		PMD_DRV_LOG(ERR, "Failed to invoke xsc cmd, %s",
+			    xsc_cmd_error[status]);
+		ret = -1;
+		goto error;
+	}
+
+	ret = xsc_cmdq_rsp_msg_copy(data_out, rsp_msg, out_len);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Failed to copy response msg to out data");
+		goto error;
+	}
+
+error:
+	xsc_cmdq_msg_destruct(xdev, &req_msg, &rsp_msg);
+	return ret;
+}
diff --git a/drivers/net/xsc/xsc_vfio_mbox.h b/drivers/net/xsc/xsc_vfio_mbox.h
new file mode 100644
index 0000000000..49ca84f7ec
--- /dev/null
+++ b/drivers/net/xsc/xsc_vfio_mbox.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2025 Yunsilicon Technology Co., Ltd.
+ */
+
+#ifndef _XSC_CMDQ_H_
+#define _XSC_CMDQ_H_
+
+#include <rte_common.h>
+#include <rte_mempool.h>
+#include <rte_memzone.h>
+#include <rte_spinlock.h>
+#include <rte_byteorder.h>
+#include <rte_io.h>
+
+#include "xsc_dev.h"
+#include "xsc_cmd.h"
+
+#define XSC_CMDQ_DATA_SIZE		512
+#define XSC_CMDQ_REQ_INLINE_SIZE	8
+#define XSC_CMDQ_RSP_INLINE_SIZE	14
+
+struct xsc_cmdq_config {
+	uint32_t req_pid_addr;
+	uint32_t req_cid_addr;
+	uint32_t rsp_pid_addr;
+	uint32_t rsp_cid_addr;
+	uint32_t req_h_addr;
+	uint32_t req_l_addr;
+	uint32_t rsp_h_addr;
+	uint32_t rsp_l_addr;
+	uint32_t elt_sz_addr;
+	uint32_t depth_addr;
+};
+
+struct xsc_cmd_queue {
+	struct xsc_cmdq_req_layout *req_lay;
+	struct xsc_cmdq_rsp_layout *rsp_lay;
+	const struct rte_memzone *req_mz;
+	const struct rte_memzone *rsp_mz;
+	uint32_t req_pid;
+	uint32_t rsp_cid;
+	uint8_t  owner_bit; /* CMDQ owner bit */
+	uint8_t  owner_learn; /* Learn ownerbit from hw */
+	uint8_t  depth_n; /* Log 2 of CMDQ depth */
+	uint8_t  depth_m; /* CMDQ depth mask */
+	struct rte_mempool *mbox_buf_pool; /* CMDQ data pool */
+	struct xsc_cmdq_config *config;
+	rte_spinlock_t lock;
+};
+
+struct xsc_cmdq_mbox_buf {
+	uint8_t    data[XSC_CMDQ_DATA_SIZE];
+	uint8_t    rsv0[48];
+	rte_be64_t next; /* Next buf dma addr */
+	rte_be32_t block_num;
+	uint8_t    owner_status;
+	uint8_t    token;
+	uint8_t    ctrl_sig;
+	uint8_t    sig;
+};
+
+struct xsc_cmdq_mbox {
+	struct xsc_cmdq_mbox_buf *buf;
+	rte_iova_t buf_dma;
+	struct xsc_cmdq_mbox     *next;
+};
+
+/* CMDQ request msg inline */
+struct xsc_cmdq_req_hdr {
+	rte_be32_t data[XSC_CMDQ_REQ_INLINE_SIZE];
+};
+
+struct xsc_cmdq_req_msg {
+	uint32_t                  len;
+	struct xsc_cmdq_req_hdr    hdr;
+	struct xsc_cmdq_mbox       *next;
+};
+
+/* CMDQ response msg inline */
+struct xsc_cmdq_rsp_hdr {
+	rte_be32_t data[XSC_CMDQ_RSP_INLINE_SIZE];
+};
+
+struct xsc_cmdq_rsp_msg {
+	uint32_t                  len;
+	struct xsc_cmdq_rsp_hdr    hdr;
+	struct xsc_cmdq_mbox       *next;
+};
+
+/* HW will use this for some records(e.g. vf_id) */
+struct xsc_cmdq_rsv {
+	uint16_t vf_id;
+	uint8_t  rsv[2];
+};
+
+/* CMDQ request entry layout */
+struct xsc_cmdq_req_layout {
+	struct xsc_cmdq_rsv rsv0;
+	rte_be32_t          inlen;
+	rte_be64_t          in_ptr;
+	rte_be32_t          in[XSC_CMDQ_REQ_INLINE_SIZE];
+	rte_be64_t          out_ptr;
+	rte_be32_t          outlen;
+	uint8_t             token;
+	uint8_t             sig;
+	uint8_t             idx;
+	uint8_t             type:7;
+	uint8_t             owner_bit:1;
+};
+
+/* CMDQ response entry layout */
+struct xsc_cmdq_rsp_layout {
+	struct xsc_cmdq_rsv rsv0;
+	rte_be32_t          out[XSC_CMDQ_RSP_INLINE_SIZE];
+	uint8_t             token;
+	uint8_t             sig;
+	uint8_t             idx;
+	uint8_t             type:7;
+	uint8_t             owner_bit:1;
+};
+
+struct xsc_cmdq_dummy_mbox_in {
+	struct xsc_cmd_inbox_hdr hdr;
+	uint8_t                  rsv[8];
+};
+
+struct xsc_cmdq_dummy_mbox_out {
+	struct xsc_cmd_outbox_hdr hdr;
+	uint8_t                   rsv[8];
+};
+
+struct xsc_vfio_priv {
+	struct xsc_cmd_queue *cmdq;
+};
+
+int xsc_vfio_mbox_init(struct xsc_dev *xdev);
+void xsc_vfio_mbox_destroy(struct xsc_cmd_queue *cmdq);
+int xsc_vfio_mbox_exec(struct xsc_dev *xdev,
+		       void *data_in, int in_len,
+		       void *data_out, int out_len);
+
+#endif /* _XSC_CMDQ_H_ */
-- 
2.25.1

  parent reply	other threads:[~2025-01-07  2:50 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-07  2:50 [PATCH v5 00/15] XSC PMD for Yunsilicon NICs WanRenyong
2025-01-07  2:49 ` [PATCH v5 01/15] net/xsc: add xsc PMD framework WanRenyong
2025-01-16 18:18   ` Stephen Hemminger
2025-01-17  3:29     ` WanRenyong
2025-01-17 18:49   ` Stephen Hemminger
2025-01-18 12:43     ` WanRenyong
2025-01-07  2:49 ` [PATCH v5 02/15] net/xsc: add xsc device initialization WanRenyong
2025-01-07  2:49 ` WanRenyong [this message]
2025-01-07  2:49 ` [PATCH v5 04/15] net/xsc: add xsc dev ops to support VFIO driver WanRenyong
2025-01-07  2:49 ` [PATCH v5 05/15] net/xsc: add PCT interfaces WanRenyong
2025-01-07  2:49 ` [PATCH v5 06/15] net/xsc: initialize xsc representors WanRenyong
2025-01-07  2:49 ` [PATCH v5 07/15] net/xsc: add ethdev configure and RSS ops WanRenyong
2025-01-16 18:19   ` Stephen Hemminger
2025-01-17  2:07     ` WanRenyong
2025-01-07  2:49 ` [PATCH v5 08/15] net/xsc: add Rx and Tx queue setup WanRenyong
2025-01-07  2:49 ` [PATCH v5 09/15] net/xsc: add ethdev start WanRenyong
2025-01-07  2:50 ` [PATCH v5 10/15] net/xsc: add ethdev stop and close WanRenyong
2025-01-07  2:50 ` [PATCH v5 11/15] net/xsc: add ethdev Rx burst WanRenyong
2025-01-07  2:50 ` [PATCH v5 12/15] net/xsc: add ethdev Tx burst WanRenyong
2025-01-07  2:50 ` [PATCH v5 13/15] net/xsc: add basic stats ops WanRenyong
2025-01-16 17:58   ` Stephen Hemminger
2025-01-17  2:00     ` WanRenyong
2025-01-07  2:50 ` [PATCH v5 14/15] net/xsc: add ethdev infos get WanRenyong
2025-01-07  2:50 ` [PATCH v5 15/15] net/xsc: add ethdev link and MTU ops WanRenyong
2025-01-14  8:03 ` [PATCH v5 00/15] XSC PMD for Yunsilicon NICs WanRenyong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250107024944.1962467-4-wanry@yunsilicon.com \
    --to=wanry@yunsilicon.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=jacky@yunsilicon.com \
    --cc=nana@yunsilicon.com \
    --cc=qianr@yunsilicon.com \
    --cc=stephen@networkplumber.org \
    --cc=thomas@monjalon.net \
    --cc=weihg@yunsilicon.com \
    --cc=xudw@yunsilicon.com \
    --cc=zhangxx@yunsilicon.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.