DPDK patches and discussions
 help / color / mirror / Atom feed
From: "WanRenyong" <wanry@yunsilicon.com>
To: <dev@dpdk.org>
Cc: <ferruh.yigit@amd.com>, <thomas@monjalon.net>,
	 <andrew.rybchenko@oktetlabs.ru>, <qianr@yunsilicon.com>,
	 <nana@yunsilicon.com>, <zhangxx@yunsilicon.com>,
	 <zhangxx@yunsilicon.com>, <xudw@yunsilicon.com>,
	<jacky@yunsilicon.com>,  <weihg@yunsilicon.com>
Subject: [PATCH v4 09/15] net/xsc: add ethdev start
Date: Fri, 03 Jan 2025 23:04:23 +0800	[thread overview]
Message-ID: <20250103150422.1529663-10-wanry@yunsilicon.com> (raw)
In-Reply-To: <20250103150404.1529663-1-wanry@yunsilicon.com>

Implement xsc ethdev start function.

Signed-off-by: WanRenyong <wanry@yunsilicon.com>
Signed-off-by: Rong Qian <qianr@yunsilicon.com>
---
 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 <rte_io.h>
+
+#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 <rte_io.h>
+
+#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

  parent reply	other threads:[~2025-01-03 15:05 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-03 15:04 [PATCH v4 00/15] XSC PMD for Yunsilicon NICs WanRenyong
2025-01-03 15:04 ` [PATCH v4 01/15] net/xsc: add xsc PMD framework WanRenyong
2025-01-03 19:00   ` Stephen Hemminger
2025-01-06  1:36     ` WanRenyong
2025-01-03 15:04 ` [PATCH v4 02/15] net/xsc: add xsc device initialization WanRenyong
2025-01-03 18:58   ` Stephen Hemminger
2025-01-06  3:29     ` WanRenyong
2025-01-03 15:04 ` [PATCH v4 03/15] net/xsc: add xsc mailbox WanRenyong
2025-01-03 15:04 ` [PATCH v4 04/15] net/xsc: add xsc dev ops to support VFIO driver WanRenyong
2025-01-03 19:02   ` Stephen Hemminger
2025-01-06  1:53     ` WanRenyong
2025-01-03 19:04   ` Stephen Hemminger
2025-01-06  2:01     ` WanRenyong
2025-01-03 19:06   ` Stephen Hemminger
2025-01-06  2:02     ` WanRenyong
2025-01-03 15:04 ` [PATCH v4 05/15] net/xsc: add PCT interfaces WanRenyong
2025-01-03 15:04 ` [PATCH v4 06/15] net/xsc: initialize xsc representors WanRenyong
2025-01-03 15:04 ` [PATCH v4 07/15] net/xsc: add ethdev configure and RSS ops WanRenyong
2025-01-03 19:14   ` Stephen Hemminger
2025-01-06  2:20     ` WanRenyong
2025-01-03 15:04 ` [PATCH v4 08/15] net/xsc: add Rx and Tx queue setup WanRenyong
2025-01-03 15:04 ` WanRenyong [this message]
2025-01-03 19:17   ` [PATCH v4 09/15] net/xsc: add ethdev start Stephen Hemminger
2025-01-06  3:01     ` WanRenyong
2025-01-03 15:04 ` [PATCH v4 10/15] net/xsc: add ethdev stop and close WanRenyong
2025-01-03 15:04 ` [PATCH v4 11/15] net/xsc: add ethdev Rx burst WanRenyong
2025-01-03 15:04 ` [PATCH v4 12/15] net/xsc: add ethdev Tx burst WanRenyong
2025-01-03 15:04 ` [PATCH v4 13/15] net/xsc: add basic stats ops WanRenyong
2025-01-03 15:04 ` [PATCH v4 14/15] net/xsc: add ethdev infos get WanRenyong
2025-01-03 19:22   ` Stephen Hemminger
2025-01-06  4:03     ` WanRenyong
2025-01-03 15:04 ` [PATCH v4 15/15] net/xsc: add ethdev link and MTU ops 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=20250103150422.1529663-10-wanry@yunsilicon.com \
    --to=wanry@yunsilicon.com \
    --cc=andrew.rybchenko@oktetlabs.ru \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=jacky@yunsilicon.com \
    --cc=nana@yunsilicon.com \
    --cc=qianr@yunsilicon.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).