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 09/15] net/xsc: add ethdev start
Date: Tue, 07 Jan 2025 10:49:59 +0800 [thread overview]
Message-ID: <20250107024958.1962467-10-wanry@yunsilicon.com> (raw)
In-Reply-To: <20250107024939.1962467-1-wanry@yunsilicon.com>
Implement xsc ethdev start function.
Signed-off-by: WanRenyong <wanry@yunsilicon.com>
Signed-off-by: Rong Qian <qianr@yunsilicon.com>
---
v5:
* Remove unnecessary call of rte_wmb.
---
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 | 172 +++++++++++++++++++++
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, 652 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 74d577c7d0..054a08bf84 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 2072f9ccb8..d867084d78 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 7867b63f41..c940669fca 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,
@@ -86,6 +88,175 @@ 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;
+ 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,
@@ -193,6 +364,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
next prev 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 ` [PATCH v5 03/15] net/xsc: add xsc mailbox WanRenyong
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 ` WanRenyong [this message]
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=20250107024958.1962467-10-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.