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 72AD345FD7; Fri, 3 Jan 2025 16:05:20 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DF4324065F; Fri, 3 Jan 2025 16:04:34 +0100 (CET) Received: from lf-2-47.ptr.blmpb.com (lf-2-47.ptr.blmpb.com [101.36.218.47]) by mails.dpdk.org (Postfix) with ESMTP id 644534065C for ; Fri, 3 Jan 2025 16:04:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2403070942; d=yunsilicon.com; t=1735916666; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=pamGjuRwzeFW8GfPNMf9qOneBnvJyYE4pcwaB0QOD0g=; b=cm39n5Jl/IVAj2e+dxNvUFcRG45HsAi/XK4loevlXjobpw57Y7C0WA0IkKDFpWG8x5Oqgk s7z/15b+n4oh8SObmiydvcvtXYh0csiR3Vx9XDAV6Hz7c/O7PohmJVm7S0Az5rGkoi5efh btTqZPAFlFqbv2qaBBkaYRaSPzfO/YMI7qhWHeyAxjoiRVO9Za2SShJv7mt54Jzwst5swG DhGL3OLWL+eqTmDtruJ+NgfY8jJ0fGia1nM29UznjmrfAT3ehB+gtLDdpKpVFNOqpLnqGX LSG2Dn1a9fgaJBKUXk5TX6fG/DRJpSriPy+zA40V7PZ7u8ft0Lp29Di0Xybu8w== From: "WanRenyong" Mime-Version: 1.0 X-Mailer: git-send-email 2.25.1 Date: Fri, 03 Jan 2025 23:04:23 +0800 Message-Id: <20250103150422.1529663-10-wanry@yunsilicon.com> Received: from ubuntu-liun.yunsilicon.com ([58.34.192.114]) by smtp.feishu.cn with ESMTPS; Fri, 03 Jan 2025 23:04:23 +0800 References: <20250103150404.1529663-1-wanry@yunsilicon.com> Content-Type: text/plain; charset=UTF-8 To: Cc: , , , , , , , , , X-Original-From: WanRenyong Content-Transfer-Encoding: 7bit Subject: [PATCH v4 09/15] net/xsc: add ethdev start In-Reply-To: <20250103150404.1529663-1-wanry@yunsilicon.com> X-Lms-Return-Path: 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 Implement xsc ethdev start function. Signed-off-by: WanRenyong Signed-off-by: Rong Qian --- drivers/net/xsc/meson.build | 2 + drivers/net/xsc/xsc_dev.c | 33 ++++ drivers/net/xsc/xsc_dev.h | 8 + drivers/net/xsc/xsc_ethdev.c | 174 +++++++++++++++++++++ drivers/net/xsc/xsc_ethdev.h | 19 +++ drivers/net/xsc/xsc_rx.c | 291 +++++++++++++++++++++++++++++++++++ drivers/net/xsc/xsc_rx.h | 3 + drivers/net/xsc/xsc_rxtx.h | 27 ++++ drivers/net/xsc/xsc_tx.c | 93 +++++++++++ drivers/net/xsc/xsc_tx.h | 4 + 10 files changed, 654 insertions(+) create mode 100644 drivers/net/xsc/xsc_rx.c create mode 100644 drivers/net/xsc/xsc_tx.c diff --git a/drivers/net/xsc/meson.build b/drivers/net/xsc/meson.build index 5ee03ea835..79664374e3 100644 --- a/drivers/net/xsc/meson.build +++ b/drivers/net/xsc/meson.build @@ -12,4 +12,6 @@ sources = files( 'xsc_vfio_mbox.c', 'xsc_vfio.c', 'xsc_np.c', + 'xsc_rx.c', + 'xsc_tx.c', ) diff --git a/drivers/net/xsc/xsc_dev.c b/drivers/net/xsc/xsc_dev.c index 84bab2bb93..45e93e1a85 100644 --- a/drivers/net/xsc/xsc_dev.c +++ b/drivers/net/xsc/xsc_dev.c @@ -68,6 +68,39 @@ xsc_dev_get_mac(struct xsc_dev *xdev, uint8_t *mac) return xdev->dev_ops->get_mac(xdev, mac); } +int +xsc_dev_modify_qp_status(struct xsc_dev *xdev, uint32_t qpn, int num, int opcode) +{ + return xdev->dev_ops->modify_qp_status(xdev, qpn, num, opcode); +} + +int +xsc_dev_modify_qp_qostree(struct xsc_dev *xdev, uint16_t qpn) +{ + return xdev->dev_ops->modify_qp_qostree(xdev, qpn); +} + +int +xsc_dev_rx_cq_create(struct xsc_dev *xdev, struct xsc_rx_cq_params *cq_params, + struct xsc_rx_cq_info *cq_info) +{ + return xdev->dev_ops->rx_cq_create(xdev, cq_params, cq_info); +} + +int +xsc_dev_tx_cq_create(struct xsc_dev *xdev, struct xsc_tx_cq_params *cq_params, + struct xsc_tx_cq_info *cq_info) +{ + return xdev->dev_ops->tx_cq_create(xdev, cq_params, cq_info); +} + +int +xsc_dev_tx_qp_create(struct xsc_dev *xdev, struct xsc_tx_qp_params *qp_params, + struct xsc_tx_qp_info *qp_info) +{ + return xdev->dev_ops->tx_qp_create(xdev, qp_params, qp_info); +} + int xsc_dev_close(struct xsc_dev *xdev, int repr_id) { diff --git a/drivers/net/xsc/xsc_dev.h b/drivers/net/xsc/xsc_dev.h index 3bebb18b98..5aa1d8704e 100644 --- a/drivers/net/xsc/xsc_dev.h +++ b/drivers/net/xsc/xsc_dev.h @@ -158,6 +158,14 @@ struct xsc_dev_ops { int xsc_dev_mailbox_exec(struct xsc_dev *xdev, void *data_in, int in_len, void *data_out, int out_len); void xsc_dev_ops_register(struct xsc_dev_ops *new_ops); +int xsc_dev_modify_qp_status(struct xsc_dev *xdev, uint32_t qpn, int num, int opcode); +int xsc_dev_modify_qp_qostree(struct xsc_dev *xdev, uint16_t qpn); +int xsc_dev_rx_cq_create(struct xsc_dev *xdev, struct xsc_rx_cq_params *cq_params, + struct xsc_rx_cq_info *cq_info); +int xsc_dev_tx_cq_create(struct xsc_dev *xdev, struct xsc_tx_cq_params *cq_params, + struct xsc_tx_cq_info *cq_info); +int xsc_dev_tx_qp_create(struct xsc_dev *xdev, struct xsc_tx_qp_params *qp_params, + struct xsc_tx_qp_info *qp_info); int xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **dev); void xsc_dev_uninit(struct xsc_dev *xdev); int xsc_dev_close(struct xsc_dev *xdev, int repr_id); diff --git a/drivers/net/xsc/xsc_ethdev.c b/drivers/net/xsc/xsc_ethdev.c index 0a16b4338c..0443460cf7 100644 --- a/drivers/net/xsc/xsc_ethdev.c +++ b/drivers/net/xsc/xsc_ethdev.c @@ -10,6 +10,8 @@ #include "xsc_ethdev.h" #include "xsc_rx.h" #include "xsc_tx.h" +#include "xsc_dev.h" +#include "xsc_cmd.h" static int xsc_ethdev_rss_hash_conf_get(struct rte_eth_dev *dev, @@ -110,6 +112,177 @@ xsc_ethdev_configure(struct rte_eth_dev *dev) return -rte_errno; } +static int +xsc_ethdev_enable(struct rte_eth_dev *dev) +{ + struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev); + struct xsc_hwinfo *hwinfo; + int peer_dstinfo = 0; + int peer_logicalport = 0; + int logical_port = 0; + int local_dstinfo = 0; + int pcie_logic_port = 0; + int qp_set_id; + int repr_id; + struct xsc_rxq_data *rxq = xsc_rxq_get(priv, 0); + uint16_t rx_qpn = (uint16_t)rxq->qpn; + int i, vld; + struct xsc_txq_data *txq; + struct xsc_repr_port *repr; + struct xsc_repr_info *repr_info; + + if (priv->funcid_type != XSC_PHYPORT_MAC_FUNCID) + return -ENODEV; + + hwinfo = &priv->xdev->hwinfo; + repr_id = priv->representor_id; + repr = &priv->xdev->repr_ports[repr_id]; + repr_info = &repr->info; + + qp_set_id = xsc_dev_qp_set_id_get(priv->xdev, repr_id); + logical_port = repr_info->logical_port; + local_dstinfo = repr_info->local_dstinfo; + peer_logicalport = repr_info->peer_logical_port; + peer_dstinfo = repr_info->peer_dstinfo; + + pcie_logic_port = hwinfo->pcie_no + 8; + + for (i = 0; i < priv->num_sq; i++) { + txq = xsc_txq_get(priv, i); + xsc_dev_modify_qp_status(priv->xdev, txq->qpn, 1, XSC_CMD_OP_RTR2RTS_QP); + xsc_dev_modify_qp_qostree(priv->xdev, txq->qpn); + xsc_dev_set_qpsetid(priv->xdev, txq->qpn, qp_set_id); + } + + if (!xsc_dev_is_vf(priv->xdev)) { + xsc_dev_create_ipat(priv->xdev, logical_port, peer_dstinfo); + xsc_dev_create_vfos_baselp(priv->xdev); + xsc_dev_create_epat(priv->xdev, local_dstinfo, pcie_logic_port, + rx_qpn - hwinfo->raw_rss_qp_id_base, + priv->num_rq, &priv->rss_conf); + xsc_dev_create_pct(priv->xdev, repr_id, logical_port, peer_dstinfo); + xsc_dev_create_pct(priv->xdev, repr_id, peer_logicalport, local_dstinfo); + } else { + vld = xsc_dev_get_ipat_vld(priv->xdev, logical_port); + if (vld == 0) + xsc_dev_create_ipat(priv->xdev, logical_port, peer_dstinfo); + xsc_dev_vf_modify_epat(priv->xdev, local_dstinfo, + rx_qpn - hwinfo->raw_rss_qp_id_base, + priv->num_rq, &priv->rss_conf); + } + + return 0; +} + +static int +xsc_txq_start(struct xsc_ethdev_priv *priv) +{ + struct xsc_txq_data *txq_data; + struct rte_eth_dev *dev = priv->eth_dev; + uint64_t offloads = dev->data->dev_conf.txmode.offloads; + uint16_t i; + int ret; + size_t size; + + if (priv->flags & XSC_FLAG_TX_QUEUE_INIT) { + for (i = 0; i != priv->num_sq; ++i) + dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; + return 0; + } + + for (i = 0; i != priv->num_sq; ++i) { + txq_data = xsc_txq_get(priv, i); + xsc_txq_elts_alloc(txq_data); + ret = xsc_txq_obj_new(priv->xdev, txq_data, offloads, i); + if (ret < 0) + goto error; + dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; + PMD_DRV_LOG(INFO, "Port %u create tx success", dev->data->port_id); + + size = txq_data->cqe_s * sizeof(*txq_data->fcqs); + txq_data->fcqs = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE); + if (!txq_data->fcqs) { + PMD_DRV_LOG(ERR, "Port %u txq %u alloc fcqs memory failed", + dev->data->port_id, i); + rte_errno = ENOMEM; + goto error; + } + } + + priv->flags |= XSC_FLAG_TX_QUEUE_INIT; + return 0; + +error: + /* Queue resources are released by xsc_ethdev_start calling the stop interface */ + return -rte_errno; +} + +static int +xsc_rxq_start(struct xsc_ethdev_priv *priv) +{ + struct xsc_rxq_data *rxq_data; + struct rte_eth_dev *dev = priv->eth_dev; + uint16_t i; + int ret; + + if (priv->flags & XSC_FLAG_RX_QUEUE_INIT) { + for (i = 0; i != priv->num_sq; ++i) + dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; + return 0; + } + + for (i = 0; i != priv->num_rq; ++i) { + rxq_data = xsc_rxq_get(priv, i); + if (dev->data->rx_queue_state[i] != RTE_ETH_QUEUE_STATE_STARTED) { + ret = xsc_rxq_elts_alloc(rxq_data); + if (ret != 0) + goto error; + } + } + + ret = xsc_rxq_rss_obj_new(priv, priv->dev_data->port_id); + if (ret != 0) + goto error; + + priv->flags |= XSC_FLAG_RX_QUEUE_INIT; + return 0; +error: + /* Queue resources are released by xsc_ethdev_start calling the stop interface */ + return -rte_errno; +} + +static int +xsc_ethdev_start(struct rte_eth_dev *dev) +{ + int ret; + struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev); + + ret = xsc_txq_start(priv); + if (ret) { + PMD_DRV_LOG(ERR, "Port %u txq start failed: %s", + dev->data->port_id, strerror(rte_errno)); + goto error; + } + + ret = xsc_rxq_start(priv); + if (ret) { + PMD_DRV_LOG(ERR, "Port %u Rx queue start failed: %s", + dev->data->port_id, strerror(rte_errno)); + goto error; + } + + dev->data->dev_started = 1; + + rte_wmb(); + ret = xsc_ethdev_enable(dev); + + return 0; + +error: + dev->data->dev_started = 0; + return -rte_errno; +} + static int xsc_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc, uint32_t socket, const struct rte_eth_rxconf *conf, @@ -217,6 +390,7 @@ xsc_ethdev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac, uin const struct eth_dev_ops xsc_eth_dev_ops = { .dev_configure = xsc_ethdev_configure, + .dev_start = xsc_ethdev_start, .rx_queue_setup = xsc_ethdev_rx_queue_setup, .tx_queue_setup = xsc_ethdev_tx_queue_setup, .rss_hash_update = xsc_ethdev_rss_hash_update, diff --git a/drivers/net/xsc/xsc_ethdev.h b/drivers/net/xsc/xsc_ethdev.h index bc0fc54d50..0b307c2828 100644 --- a/drivers/net/xsc/xsc_ethdev.h +++ b/drivers/net/xsc/xsc_ethdev.h @@ -7,6 +7,9 @@ #include "xsc_dev.h" +#define XSC_FLAG_RX_QUEUE_INIT 0x1 +#define XSC_FLAG_TX_QUEUE_INIT 0x2 + struct xsc_ethdev_priv { struct rte_eth_dev *eth_dev; struct rte_pci_device *pci_dev; @@ -41,4 +44,20 @@ struct xsc_ethdev_priv { #define TO_XSC_ETHDEV_PRIV(dev) ((struct xsc_ethdev_priv *)(dev)->data->dev_private) +static __rte_always_inline struct xsc_txq_data * +xsc_txq_get(struct xsc_ethdev_priv *priv, uint16_t idx) +{ + if (priv->txqs != NULL && (*priv->txqs)[idx] != NULL) + return (*priv->txqs)[idx]; + return NULL; +} + +static __rte_always_inline struct xsc_rxq_data * +xsc_rxq_get(struct xsc_ethdev_priv *priv, uint16_t idx) +{ + if (priv->rxqs != NULL && (*priv->rxqs)[idx] != NULL) + return (*priv->rxqs)[idx]; + return NULL; +} + #endif /* _XSC_ETHDEV_H_ */ diff --git a/drivers/net/xsc/xsc_rx.c b/drivers/net/xsc/xsc_rx.c new file mode 100644 index 0000000000..f3667313be --- /dev/null +++ b/drivers/net/xsc/xsc_rx.c @@ -0,0 +1,291 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2025 Yunsilicon Technology Co., Ltd. + */ + +#include + +#include "xsc_log.h" +#include "xsc_defs.h" +#include "xsc_dev.h" +#include "xsc_ethdev.h" +#include "xsc_cmd.h" +#include "xsc_rx.h" + +#define XSC_MAX_RECV_LEN 9800 + +static void +xsc_rxq_initialize(struct xsc_dev *xdev, struct xsc_rxq_data *rxq_data) +{ + const uint32_t wqe_n = rxq_data->wqe_s; + uint32_t i; + uint32_t seg_len = 0; + struct xsc_hwinfo *hwinfo = &xdev->hwinfo; + uint32_t rx_ds_num = hwinfo->recv_seg_num; + uint32_t log2ds = rte_log2_u32(rx_ds_num); + uintptr_t addr; + struct rte_mbuf *mbuf; + void *jumbo_buffer_pa = xdev->jumbo_buffer_pa; + void *jumbo_buffer_va = xdev->jumbo_buffer_va; + volatile struct xsc_wqe_data_seg *seg; + volatile struct xsc_wqe_data_seg *seg_next; + + for (i = 0; (i != wqe_n); ++i) { + mbuf = (*rxq_data->elts)[i]; + seg = &((volatile struct xsc_wqe_data_seg *)rxq_data->wqes)[i * rx_ds_num]; + addr = (uintptr_t)rte_pktmbuf_iova(mbuf); + if (rx_ds_num == 1) + seg_len = XSC_MAX_RECV_LEN; + else + seg_len = rte_pktmbuf_data_len(mbuf); + *seg = (struct xsc_wqe_data_seg){ + .va = rte_cpu_to_le_64(addr), + .seg_len = rte_cpu_to_le_32(seg_len), + .lkey = 0, + }; + + if (rx_ds_num != 1) { + seg_next = seg + 1; + if (jumbo_buffer_va == NULL) { + jumbo_buffer_pa = rte_malloc(NULL, XSC_MAX_RECV_LEN, 0); + if (jumbo_buffer_pa == NULL) { + /* Rely on mtu */ + seg->seg_len = XSC_MAX_RECV_LEN; + PMD_DRV_LOG(ERR, "Failed to malloc jumbo_buffer"); + continue; + } else { + jumbo_buffer_va = + (void *)rte_malloc_virt2iova(jumbo_buffer_pa); + if ((rte_iova_t)jumbo_buffer_va == RTE_BAD_IOVA) { + seg->seg_len = XSC_MAX_RECV_LEN; + PMD_DRV_LOG(ERR, "Failed to turn jumbo_buffer"); + continue; + } + } + xdev->jumbo_buffer_pa = jumbo_buffer_pa; + xdev->jumbo_buffer_va = jumbo_buffer_va; + } + *seg_next = (struct xsc_wqe_data_seg){ + .va = rte_cpu_to_le_64((uint64_t)jumbo_buffer_va), + .seg_len = rte_cpu_to_le_32(XSC_MAX_RECV_LEN - seg_len), + .lkey = 0, + }; + } + } + + rxq_data->rq_ci = wqe_n; + rxq_data->sge_n = log2ds; + + union xsc_recv_doorbell recv_db = { + .recv_data = 0 + }; + + recv_db.next_pid = wqe_n << log2ds; + recv_db.qp_num = rxq_data->qpn; + rte_write32(rte_cpu_to_le_32(recv_db.recv_data), rxq_data->rq_db); +} + +static int +xsc_rss_qp_create(struct xsc_ethdev_priv *priv, int port_id) +{ + struct xsc_cmd_create_multiqp_mbox_in *in; + struct xsc_cmd_create_qp_request *req; + struct xsc_cmd_create_multiqp_mbox_out *out; + uint8_t log_ele; + uint64_t iova; + int wqe_n; + int in_len, out_len, cmd_len; + int entry_total_len, entry_len; + uint8_t log_rq_sz, log_sq_sz = 0; + uint32_t wqe_total_len; + int j, ret; + uint16_t i, pa_num; + int rqn_base; + struct xsc_rxq_data *rxq_data; + struct xsc_dev *xdev = priv->xdev; + struct xsc_hwinfo *hwinfo = &xdev->hwinfo; + char name[RTE_ETH_NAME_MAX_LEN] = { 0 }; + + rxq_data = xsc_rxq_get(priv, 0); + log_ele = rte_log2_u32(sizeof(struct xsc_wqe_data_seg)); + wqe_n = rxq_data->wqe_s; + log_rq_sz = rte_log2_u32(wqe_n * hwinfo->recv_seg_num); + wqe_total_len = 1 << (log_rq_sz + log_sq_sz + log_ele); + + pa_num = (wqe_total_len + XSC_PAGE_SIZE - 1) / XSC_PAGE_SIZE; + entry_len = sizeof(struct xsc_cmd_create_qp_request) + sizeof(uint64_t) * pa_num; + entry_total_len = entry_len * priv->num_rq; + + in_len = sizeof(struct xsc_cmd_create_multiqp_mbox_in) + entry_total_len; + out_len = sizeof(struct xsc_cmd_create_multiqp_mbox_out) + entry_total_len; + cmd_len = RTE_MAX(in_len, out_len); + in = malloc(cmd_len); + memset(in, 0, cmd_len); + if (in == NULL) { + rte_errno = ENOMEM; + PMD_DRV_LOG(ERR, "Alloc rss qp create cmd memory failed"); + goto error; + } + + in->qp_num = rte_cpu_to_be_16((uint16_t)priv->num_rq); + in->qp_type = XSC_QUEUE_TYPE_RAW; + in->req_len = rte_cpu_to_be_32(cmd_len); + + for (i = 0; i < priv->num_rq; i++) { + rxq_data = (*priv->rxqs)[i]; + req = (struct xsc_cmd_create_qp_request *)(&in->data[0] + entry_len * i); + req->input_qpn = rte_cpu_to_be_16(0); /* useless for eth */ + req->pa_num = rte_cpu_to_be_16(pa_num); + req->qp_type = XSC_QUEUE_TYPE_RAW; + req->log_rq_sz = log_rq_sz; + req->cqn_recv = rte_cpu_to_be_16((uint16_t)rxq_data->cqn); + req->cqn_send = req->cqn_recv; + req->glb_funcid = rte_cpu_to_be_16((uint16_t)hwinfo->func_id); + /* Alloc pas addr */ + snprintf(name, sizeof(name), "wqe_mem_rx_%d_%d", port_id, i); + rxq_data->rq_pas = rte_memzone_reserve_aligned(name, + (XSC_PAGE_SIZE * pa_num), + SOCKET_ID_ANY, + 0, XSC_PAGE_SIZE); + if (rxq_data->rq_pas == NULL) { + rte_errno = ENOMEM; + PMD_DRV_LOG(ERR, "Alloc rxq pas memory failed"); + goto error; + } + + iova = rxq_data->rq_pas->iova; + for (j = 0; j < pa_num; j++) + req->pas[j] = rte_cpu_to_be_64(iova + j * XSC_PAGE_SIZE); + } + + in->hdr.opcode = rte_cpu_to_be_16(XSC_CMD_OP_CREATE_MULTI_QP); + out = (struct xsc_cmd_create_multiqp_mbox_out *)in; + ret = xsc_dev_mailbox_exec(xdev, in, in_len, out, out_len); + if (ret != 0 || out->hdr.status != 0) { + PMD_DRV_LOG(ERR, + "Create rss rq failed, port id=%d, qp_num=%d, ret=%d, out.status=%u", + port_id, priv->num_rq, ret, out->hdr.status); + rte_errno = ENOEXEC; + goto error; + } + rqn_base = rte_be_to_cpu_32(out->qpn_base) & 0xffffff; + + for (i = 0; i < priv->num_rq; i++) { + rxq_data = xsc_rxq_get(priv, i); + rxq_data->wqes = rxq_data->rq_pas->addr; + if (!xsc_dev_is_vf(xdev)) + rxq_data->rq_db = (uint32_t *)((uint8_t *)xdev->bar_addr + + XSC_PF_RX_DB_ADDR); + else + rxq_data->rq_db = (uint32_t *)((uint8_t *)xdev->bar_addr + + XSC_VF_RX_DB_ADDR); + + rxq_data->qpn = rqn_base + i; + xsc_dev_modify_qp_status(xdev, rxq_data->qpn, 1, XSC_CMD_OP_RTR2RTS_QP); + xsc_rxq_initialize(xdev, rxq_data); + rxq_data->cq_ci = 0; + priv->dev_data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; + PMD_DRV_LOG(INFO, "Port %u create rx qp, wqe_s:%d, wqe_n:%d, qp_db=%p, qpn:%d", + port_id, + rxq_data->wqe_s, rxq_data->wqe_n, + rxq_data->rq_db, rxq_data->qpn); + } + + free(in); + return 0; + +error: + free(in); + return -rte_errno; +} + +int +xsc_rxq_rss_obj_new(struct xsc_ethdev_priv *priv, uint16_t port_id) +{ + int ret; + uint32_t i; + struct xsc_dev *xdev = priv->xdev; + struct xsc_rxq_data *rxq_data; + struct xsc_rx_cq_params cq_params = {0}; + struct xsc_rx_cq_info cq_info = {0}; + + /* Create CQ */ + for (i = 0; i < priv->num_rq; ++i) { + rxq_data = xsc_rxq_get(priv, i); + + memset(&cq_params, 0, sizeof(cq_params)); + memset(&cq_info, 0, sizeof(cq_info)); + cq_params.port_id = rxq_data->port_id; + cq_params.qp_id = rxq_data->idx; + cq_params.wqe_s = rxq_data->wqe_s; + + ret = xsc_dev_rx_cq_create(xdev, &cq_params, &cq_info); + if (ret) { + PMD_DRV_LOG(ERR, "Port %u rxq %u create cq fail", port_id, i); + rte_errno = errno; + goto error; + } + + rxq_data->cq = cq_info.cq; + rxq_data->cqe_n = cq_info.cqe_n; + rxq_data->cqe_s = 1 << rxq_data->cqe_n; + rxq_data->cqe_m = rxq_data->cqe_s - 1; + rxq_data->cqes = cq_info.cqes; + rxq_data->cq_db = cq_info.cq_db; + rxq_data->cqn = cq_info.cqn; + + PMD_DRV_LOG(INFO, "Port %u create rx cq, cqe_s:%d, cqe_n:%d, cq_db=%p, cqn:%d", + port_id, + rxq_data->cqe_s, rxq_data->cqe_n, + rxq_data->cq_db, rxq_data->cqn); + } + + ret = xsc_rss_qp_create(priv, port_id); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Port %u rss rxq create fail", port_id); + goto error; + } + return 0; + +error: + return -rte_errno; +} + +int +xsc_rxq_elts_alloc(struct xsc_rxq_data *rxq_data) +{ + uint32_t elts_s = rxq_data->wqe_s; + struct rte_mbuf *mbuf; + uint32_t i; + + for (i = 0; (i != elts_s); ++i) { + mbuf = rte_pktmbuf_alloc(rxq_data->mp); + if (mbuf == NULL) { + PMD_DRV_LOG(ERR, "Port %u rxq %u empty mbuf pool", + rxq_data->port_id, rxq_data->idx); + rte_errno = ENOMEM; + goto error; + } + + mbuf->port = rxq_data->port_id; + mbuf->nb_segs = 1; + rte_pktmbuf_data_len(mbuf) = rte_pktmbuf_data_room_size(rxq_data->mp) + - mbuf->data_off; + rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_room_size(rxq_data->mp) + - mbuf->data_off; + (*rxq_data->elts)[i] = mbuf; + } + + return 0; +error: + elts_s = i; + for (i = 0; (i != elts_s); ++i) { + if ((*rxq_data->elts)[i] != NULL) + rte_pktmbuf_free_seg((*rxq_data->elts)[i]); + (*rxq_data->elts)[i] = NULL; + } + + PMD_DRV_LOG(ERR, "Port %u rxq %u start failed, free elts", + rxq_data->port_id, rxq_data->idx); + + return -rte_errno; +} diff --git a/drivers/net/xsc/xsc_rx.h b/drivers/net/xsc/xsc_rx.h index 3653c0e335..5a2c4839ce 100644 --- a/drivers/net/xsc/xsc_rx.h +++ b/drivers/net/xsc/xsc_rx.h @@ -56,4 +56,7 @@ struct __rte_cache_aligned xsc_rxq_data { uint16_t rsv1:11; }; +int xsc_rxq_elts_alloc(struct xsc_rxq_data *rxq_data); +int xsc_rxq_rss_obj_new(struct xsc_ethdev_priv *priv, uint16_t port_id); + #endif /* _XSC_RX_H_ */ diff --git a/drivers/net/xsc/xsc_rxtx.h b/drivers/net/xsc/xsc_rxtx.h index 6311ed12d2..2771efafc6 100644 --- a/drivers/net/xsc/xsc_rxtx.h +++ b/drivers/net/xsc/xsc_rxtx.h @@ -102,6 +102,24 @@ struct xsc_cqe_u64 { struct xsc_cqe cqe1; }; +union xsc_cq_doorbell { + struct { + uint32_t next_cid:16; + uint32_t cq_num:15; + uint32_t cq_sta:1; + }; + uint32_t cq_data; +}; + +union xsc_send_doorbell { + struct { + uint32_t next_pid:16; + uint32_t qp_num:15; + uint32_t rsv:1; + }; + uint32_t send_data; +}; + struct xsc_tx_cq_params { uint16_t port_id; uint16_t qp_id; @@ -134,6 +152,15 @@ struct xsc_tx_qp_info { uint16_t wqe_n; }; +union xsc_recv_doorbell { + struct { + uint32_t next_pid:13; + uint32_t qp_num:15; + uint32_t rsv:4; + }; + uint32_t recv_data; +}; + struct xsc_rx_cq_params { uint16_t port_id; uint16_t qp_id; diff --git a/drivers/net/xsc/xsc_tx.c b/drivers/net/xsc/xsc_tx.c new file mode 100644 index 0000000000..ba80488010 --- /dev/null +++ b/drivers/net/xsc/xsc_tx.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2025 Yunsilicon Technology Co., Ltd. + */ + +#include + +#include "xsc_log.h" +#include "xsc_defs.h" +#include "xsc_dev.h" +#include "xsc_ethdev.h" +#include "xsc_cmd.h" +#include "xsc_tx.h" +#include "xsc_np.h" + +void +xsc_txq_elts_alloc(struct xsc_txq_data *txq_data) +{ + const uint32_t elts_s = 1 << txq_data->elts_n; + uint32_t i; + + for (i = 0; i < elts_s; ++i) + txq_data->elts[i] = NULL; + txq_data->elts_head = 0; + txq_data->elts_tail = 0; + txq_data->elts_comp = 0; +} + +int +xsc_txq_obj_new(struct xsc_dev *xdev, struct xsc_txq_data *txq_data, + uint64_t offloads, uint16_t idx) +{ + int ret = 0; + struct xsc_tx_cq_params cq_params = {0}; + struct xsc_tx_cq_info cq_info = {0}; + struct xsc_tx_qp_params qp_params = {0}; + struct xsc_tx_qp_info qp_info = {0}; + + cq_params.port_id = txq_data->port_id; + cq_params.qp_id = txq_data->idx; + cq_params.elts_n = txq_data->elts_n; + ret = xsc_dev_tx_cq_create(xdev, &cq_params, &cq_info); + if (ret) { + rte_errno = errno; + goto error; + } + + txq_data->cq = cq_info.cq; + txq_data->cqe_n = cq_info.cqe_n; + txq_data->cqe_s = cq_info.cqe_s; + txq_data->cq_db = cq_info.cq_db; + txq_data->cqn = cq_info.cqn; + txq_data->cqes = cq_info.cqes; + txq_data->cqe_m = txq_data->cqe_s - 1; + + PMD_DRV_LOG(INFO, "Create tx cq, cqe_s:%d, cqe_n:%d, cq_db=%p, cqn:%d", + txq_data->cqe_s, txq_data->cqe_n, + txq_data->cq_db, txq_data->cqn); + + qp_params.cq = txq_data->cq; + qp_params.tx_offloads = offloads; + qp_params.port_id = txq_data->port_id; + qp_params.qp_id = idx; + qp_params.elts_n = txq_data->elts_n; + ret = xsc_dev_tx_qp_create(xdev, &qp_params, &qp_info); + + if (ret != 0) { + rte_errno = errno; + goto error; + } + + txq_data->qp = qp_info.qp; + txq_data->qpn = qp_info.qpn; + txq_data->wqes = qp_info.wqes; + txq_data->wqe_n = qp_info.wqe_n; + txq_data->wqe_s = 1 << txq_data->wqe_n; + txq_data->wqe_m = txq_data->wqe_s - 1; + txq_data->wqe_ds_n = rte_log2_u32(xdev->hwinfo.send_seg_num); + txq_data->qp_db = qp_info.qp_db; + + txq_data->cq_ci = 0; + txq_data->cq_pi = 0; + txq_data->wqe_ci = 0; + txq_data->wqe_pi = 0; + txq_data->wqe_comp = 0; + + PMD_DRV_LOG(INFO, "Create tx qp, wqe_s:%d, wqe_n:%d, qp_db=%p, qpn:%d", + txq_data->wqe_s, txq_data->wqe_n, + txq_data->qp_db, txq_data->qpn); + return 0; + +error: + return -rte_errno; +} diff --git a/drivers/net/xsc/xsc_tx.h b/drivers/net/xsc/xsc_tx.h index 11e249a4e3..674b65a555 100644 --- a/drivers/net/xsc/xsc_tx.h +++ b/drivers/net/xsc/xsc_tx.h @@ -52,4 +52,8 @@ struct __rte_cache_aligned xsc_txq_data { struct rte_mbuf *elts[]; /* Storage for queued packets, for free */ }; +int xsc_txq_obj_new(struct xsc_dev *xdev, struct xsc_txq_data *txq_data, + uint64_t offloads, uint16_t idx); +void xsc_txq_elts_alloc(struct xsc_txq_data *txq_data); + #endif /* _XSC_TX_H_ */ -- 2.25.1