[10/19] net/xsc: add ethdev configure and rxtx queue setup ops

Message ID 20240906121405.3404357-11-wanry@yunsilicon.com (mailing list archive)
State Superseded
Delegated to: Ferruh Yigit
Headers
Series XSC PMD for Yunsilicon NICs |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

WanRenyong Sept. 6, 2024, 12:13 p.m. UTC
Implement xsc ethdev configure, Rx and Tx queue setup functions.

Signed-off-by: WanRenyong <wanry@yunsilicon.com>
---
 drivers/net/xsc/xsc_ethdev.c | 171 +++++++++++++++++++++++++++++++++++
 drivers/net/xsc/xsc_ethdev.h |   6 ++
 drivers/net/xsc/xsc_rxtx.h   | 115 +++++++++++++++++++++++
 3 files changed, 292 insertions(+)
 create mode 100644 drivers/net/xsc/xsc_rxtx.h
  

Patch

diff --git a/drivers/net/xsc/xsc_ethdev.c b/drivers/net/xsc/xsc_ethdev.c
index aacce8b90d..5ad9567eb3 100644
--- a/drivers/net/xsc/xsc_ethdev.c
+++ b/drivers/net/xsc/xsc_ethdev.c
@@ -11,8 +11,179 @@ 
 #include "xsc_utils.h"
 
 #include "xsc_ctrl.h"
+#include "xsc_rxtx.h"
+
+static int
+xsc_rss_modify_cmd(struct xsc_ethdev_priv *priv, uint8_t *rss_key,
+		   uint8_t rss_key_len)
+{
+	return 0;
+}
+
+static int
+xsc_ethdev_rss_hash_update(struct rte_eth_dev *dev,
+			   struct rte_eth_rss_conf *rss_conf)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	int ret = 0;
+
+	if (rss_conf->rss_key_len > XSC_RSS_HASH_KEY_LEN ||
+		rss_conf->rss_key == NULL) {
+		PMD_DRV_LOG(ERR, "Xsc pmd key len is %d bigger than %d",
+				rss_conf->rss_key_len, XSC_RSS_HASH_KEY_LEN);
+		return -EINVAL;
+	}
+
+	ret = xsc_rss_modify_cmd(priv, rss_conf->rss_key, rss_conf->rss_key_len);
+	if (ret == 0) {
+		rte_memcpy(priv->rss_conf.rss_key, rss_conf->rss_key,
+				priv->rss_conf.rss_key_len);
+		priv->rss_conf.rss_key_len = rss_conf->rss_key_len;
+		priv->rss_conf.rss_hf = rss_conf->rss_hf;
+	}
+
+	return ret;
+}
+
+static int
+xsc_ethdev_configure(struct rte_eth_dev *dev)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+	int ret;
+	struct rte_eth_rss_conf *rss_conf;
+
+	priv->num_sq = dev->data->nb_tx_queues;
+	priv->num_rq = dev->data->nb_rx_queues;
+
+	if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
+		dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
+
+	if (priv->rss_conf.rss_key == NULL) {
+		priv->rss_conf.rss_key = rte_zmalloc(NULL, XSC_RSS_HASH_KEY_LEN,
+						RTE_CACHE_LINE_SIZE);
+		if (priv->rss_conf.rss_key == NULL) {
+			PMD_DRV_LOG(ERR, "Failed to alloc rss_key");
+			rte_errno = ENOMEM;
+			ret = -rte_errno;
+			goto error;
+		}
+		priv->rss_conf.rss_key_len = XSC_RSS_HASH_KEY_LEN;
+	}
+
+	if (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key != NULL) {
+		rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf;
+		ret = xsc_ethdev_rss_hash_update(dev, rss_conf);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "Xsc pmd set rss key error!");
+			rte_errno = -ENOEXEC;
+			goto error;
+		}
+	}
+
+	if (rxmode->offloads && RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
+		PMD_DRV_LOG(ERR, "xsc pmd do not support vlan filter now!");
+		rte_errno = EINVAL;
+		goto error;
+	}
+
+	if (rxmode->offloads && RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
+		PMD_DRV_LOG(ERR, "xsc pmd do not support vlan strip now!");
+		rte_errno = EINVAL;
+		goto error;
+	}
+
+	priv->txqs = (void *)dev->data->tx_queues;
+	priv->rxqs = (void *)dev->data->rx_queues;
+	return 0;
+
+error:
+	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,
+			  struct rte_mempool *mp)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	struct xsc_rxq_data *rxq_data = NULL;
+	uint16_t desc_n;
+	uint16_t rx_free_thresh;
+	uint64_t offloads = conf->offloads |
+			    dev->data->dev_conf.rxmode.offloads;
+
+	desc = (desc > XSC_MAX_DESC_NUMBER) ? XSC_MAX_DESC_NUMBER : desc;
+	desc_n = desc;
+
+	if (!rte_is_power_of_2(desc))
+		desc_n = 1 << rte_log2_u32(desc);
+
+	rxq_data = rte_malloc_socket(NULL, sizeof(*rxq_data) + desc_n * sizeof(struct rte_mbuf *),
+					RTE_CACHE_LINE_SIZE, socket);
+	if (rxq_data == NULL) {
+		PMD_DRV_LOG(ERR, "Port %u create rxq idx %d failure",
+				dev->data->port_id, idx);
+		rte_errno = ENOMEM;
+		return -rte_errno;
+	}
+	rxq_data->idx = idx;
+	rxq_data->priv = priv;
+	(*priv->rxqs)[idx] = rxq_data;
+
+	rx_free_thresh = (conf->rx_free_thresh) ? conf->rx_free_thresh : XSC_RX_FREE_THRESH;
+	rxq_data->rx_free_thresh = rx_free_thresh;
+
+	rxq_data->elts = (struct rte_mbuf *(*)[desc_n])(rxq_data + 1);
+	rxq_data->mp = mp;
+	rxq_data->socket = socket;
+
+	rxq_data->csum = !!(offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM);
+	rxq_data->hw_timestamp = !!(offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP);
+	rxq_data->crc_present = 0;
+
+	rxq_data->wqe_n = rte_log2_u32(desc_n);
+	rxq_data->wqe_s = desc_n;
+	rxq_data->wqe_m = desc_n - 1;
+
+	dev->data->rx_queues[idx] = rxq_data;
+	return 0;
+}
+
+static int
+xsc_ethdev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
+			  uint32_t socket, const struct rte_eth_txconf *conf)
+{
+	struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(dev);
+	struct xsc_txq_data *txq;
+	uint16_t desc_n;
+
+	desc = (desc > XSC_MAX_DESC_NUMBER) ? XSC_MAX_DESC_NUMBER : desc;
+	desc_n = desc;
+
+	if (!rte_is_power_of_2(desc))
+		desc_n = 1 << rte_log2_u32(desc);
+
+	txq = rte_malloc_socket(NULL, sizeof(*txq) + desc_n * sizeof(struct rte_mbuf *),
+					RTE_CACHE_LINE_SIZE, socket);
+	txq->offloads = conf->offloads | dev->data->dev_conf.txmode.offloads;
+	txq->priv = priv;
+	txq->socket = socket;
+
+	txq->elts_n = rte_log2_u32(desc_n);
+	txq->elts_s = desc_n;
+	txq->elts_m = desc_n - 1;
+	txq->port_id = dev->data->port_id;
+	txq->idx = idx;
+
+	(*priv->txqs)[idx] = txq;
+	return 0;
+}
 
 const struct eth_dev_ops xsc_dev_ops = {
+	.dev_configure = xsc_ethdev_configure,
+	.rx_queue_setup = xsc_ethdev_rx_queue_setup,
+	.tx_queue_setup = xsc_ethdev_tx_queue_setup,
 };
 
 static int
diff --git a/drivers/net/xsc/xsc_ethdev.h b/drivers/net/xsc/xsc_ethdev.h
index 7c7e71d618..10c3d8cc87 100644
--- a/drivers/net/xsc/xsc_ethdev.h
+++ b/drivers/net/xsc/xsc_ethdev.h
@@ -5,6 +5,10 @@ 
 #ifndef _XSC_ETHDEV_H_
 #define _XSC_ETHDEV_H_
 
+#define XSC_RSS_HASH_KEY_LEN 52
+#define XSC_MAX_DESC_NUMBER 1024
+#define XSC_RX_FREE_THRESH 32
+
 struct xsc_dev_config {
 	uint8_t pph_flag;
 	unsigned int hw_csum:1;
@@ -40,6 +44,8 @@  struct xsc_ethdev_priv {
 	uint16_t num_sq;
 	uint16_t num_rq;
 
+	struct xsc_txq_data *(*txqs)[];
+	struct xsc_rxq_data *(*rxqs)[];
 };
 
 #define TO_XSC_ETHDEV_PRIV(dev) \
diff --git a/drivers/net/xsc/xsc_rxtx.h b/drivers/net/xsc/xsc_rxtx.h
new file mode 100644
index 0000000000..9b072e06e0
--- /dev/null
+++ b/drivers/net/xsc/xsc_rxtx.h
@@ -0,0 +1,115 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 Yunsilicon Technology Co., Ltd.
+ */
+
+#ifndef _XSC_RXTX_H_
+#define _XSC_RXTX_H_
+
+struct xsc_cqe {
+	union {
+		uint8_t		msg_opcode;
+		struct {
+			uint8_t		error_code:7;
+			uint8_t		is_error:1;
+		};
+	};
+	__le32		qp_id:15;
+	uint8_t		rsv:1;
+	uint8_t		se:1;
+	uint8_t		has_pph:1;
+	uint8_t		type:1;
+	uint8_t		with_immdt:1;
+	uint8_t		csum_err:4;
+	__le32		imm_data;
+	__le32		msg_len;
+	__le32		vni;
+	__le64		ts:48;
+	__le16		wqe_id;
+	__le16		rsv2[3];
+	__le16		rsv3:15;
+	uint8_t		owner:1;
+};
+
+struct __rte_cache_aligned xsc_txq_data {
+	uint16_t idx;  /*QP idx */
+	uint16_t port_id;
+	void *cq; /* CQ pointer */
+	void *qp; /* QP pointer */
+	uint32_t cqn; /* CQ serial number */
+	uint32_t qpn; /* QP serial number */
+	uint16_t elts_head; /* Current pos in (*elts)[] */
+	uint16_t elts_tail; /* Counter of first element awaiting completion */
+	uint16_t elts_comp; /* Elts index since last completion request */
+	uint16_t elts_s; /* Number of (*elts)[] */
+	uint16_t elts_m; /* Mask of (*elts)[] number */
+	uint16_t wqe_ci; /* Consumer index for TXQ */
+	uint16_t wqe_pi; /* Producer index for TXQ */
+	uint16_t wqe_s; /* Number of WQE */
+	uint16_t wqe_m; /* Mask of WQE number */
+	uint16_t wqe_comp; /* WQE index since last completion request */
+	uint16_t cq_ci; /* Consumer index for CQ */
+	uint16_t cq_pi; /* Production index for CQ */
+	uint16_t cqe_s; /* Number of CQE */
+	uint16_t cqe_m; /* Mask of CQE number */
+	uint16_t elts_n:4; /* Log 2 of (*elts)[] number */
+	uint16_t cqe_n:4; /* Log 2 of CQE number */
+	uint16_t wqe_n:4; /* Log 2 of WQE number */
+	uint16_t wqe_ds_n:4; /* Log 2 of each WQE DS number */
+	uint64_t offloads; /* TXQ offloads */
+	struct xsc_wqe *wqes;
+	volatile struct xsc_cqe *cqes;
+	volatile uint32_t *qp_db;
+	volatile uint32_t *cq_db;
+	struct xsc_ethdev_priv *priv;
+	uint32_t socket;
+	uint8_t tso_en:1; /* TSO enable 0-off 1-on */
+	uint16_t *fcqs; /* Free completion queue. */
+	struct rte_mbuf *elts[0]; /* Storage for queued packets, for free */
+};
+
+struct xsc_cqe_u64 {
+	struct xsc_cqe cqe0;
+	struct xsc_cqe cqe1;
+};
+
+struct __rte_cache_aligned xsc_rxq_data {
+	uint16_t idx; /*QP idx */
+	uint16_t port_id;
+	void *cq; /* CQ pointer */
+	void *qp; /* QP pointer */
+	uint32_t cqn; /* CQ serial number */
+	uint32_t qpn; /* QP serial number */
+	uint16_t wqe_s; /* Number of WQE */
+	uint16_t wqe_m; /* Mask of WQE number */
+	uint16_t cqe_s; /* Number of CQE */
+	uint16_t cqe_m; /* Mask of CQE number */
+	uint16_t wqe_n:4; /* Log 2 of WQE number */
+	uint16_t sge_n:4; /* Log 2 of each WQE DS number */
+	uint16_t cqe_n:4; /* Log 2 of CQE number */
+	volatile uint32_t *rq_db;
+	volatile uint32_t *cq_db;
+	uint32_t rq_ci;
+	uint32_t rq_pi;
+	uint16_t cq_ci;
+	uint16_t rx_free_thresh;
+	uint16_t nb_rx_hold;
+	volatile void *wqes;
+	union {
+		volatile struct xsc_cqe(*cqes)[];
+		volatile struct xsc_cqe_u64(*cqes_u64)[];
+	};
+	struct rte_mbuf *(*elts)[]; /* Record the mbuf of wqe addr */
+	struct rte_mempool *mp;
+	const struct rte_memzone *rq_pas;  /* Palist memory */
+	uint32_t socket;
+	struct xsc_ethdev_priv *priv;
+	/* attr */
+	uint32_t csum:1;  /* Checksum offloading enable */
+	uint32_t hw_timestamp:1;
+	uint32_t vlan_strip:1;
+	uint32_t crc_present:1; /* CRC flag */
+	uint32_t rss_hash:1; /* RSS hash enabled */
+};
+
+#endif /* _XSC_RXTX_H_ */
+