From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6C5F645FD7; Fri, 3 Jan 2025 16:04:30 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4C6CD40395; Fri, 3 Jan 2025 16:04:23 +0100 (CET) Received: from lf-2-14.ptr.blmpb.com (lf-2-14.ptr.blmpb.com [101.36.218.14]) by mails.dpdk.org (Postfix) with ESMTP id F3309402EE for ; Fri, 3 Jan 2025 16:04:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2403070942; d=yunsilicon.com; t=1735916653; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=EUQecD4GZef0L2yejfnYVgYVRfY9nUIlG68vU3TgeVI=; b=b3biBoFBGscwkZePkU1mdB1/ezvQ/QbqAmKDmCOezxj46qJJOKq9ZNfa5vWbfmrCkhe64U lwzJ25WwkrOVwlmFQbSWTPvfU2Hs1SnkqyGXcapsx8bSoWSwOlwZ4Va01u0oefEbNLlFvU 6ofY4PnvwpquI/nO/kyCaUvnlVoWOiomWj1PVvHQDgOBMV9fqLPerDlUUFBVF81xYUe1TR 5b3jx+T26fNvrPnd0A8dsZhzvG5skX2jX1U/9EaTELpEyhj/1VWInGzluaucNqKqN1t/yg yOa9SkfRTX8InTTvMEhhIUsJYtGLjdFdYfCz0y3VET+8LKHXhosHobufUbzTWQ== Date: Fri, 03 Jan 2025 23:04:10 +0800 Message-Id: <20250103150409.1529663-4-wanry@yunsilicon.com> Content-Type: text/plain; charset=UTF-8 References: <20250103150404.1529663-1-wanry@yunsilicon.com> Content-Transfer-Encoding: 7bit To: Cc: , , , , , , , , , Mime-Version: 1.0 X-Mailer: git-send-email 2.25.1 From: "WanRenyong" Subject: [PATCH v4 03/15] net/xsc: add xsc mailbox Received: from ubuntu-liun.yunsilicon.com ([58.34.192.114]) by smtp.feishu.cn with ESMTPS; Fri, 03 Jan 2025 23:04:10 +0800 In-Reply-To: <20250103150404.1529663-1-wanry@yunsilicon.com> X-Lms-Return-Path: X-Original-From: WanRenyong X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org XSC mailbox is a mechanism used for interaction between PMD and firmware. Signed-off-by: WanRenyong Signed-off-by: Rong Qian --- 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 +#include +#include +#include +#include + +#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 +#include + +#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 +#include +#include +#include +#include +#include + +#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