DPDK patches and discussions
 help / color / mirror / Atom feed
* [v4,1/5] raw/gdtc: introduce gdtc raw device driver
@ 2024-10-29 13:45 Yong Zhang
  2024-10-29 13:45 ` [v4,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
                   ` (9 more replies)
  0 siblings, 10 replies; 25+ messages in thread
From: Yong Zhang @ 2024-10-29 13:45 UTC (permalink / raw)
  To: thomas; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 12797 bytes --]

Introduce rawdev driver support for GDTC which
can help to connect two separate hosts with each other.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 MAINTAINERS                    |   5 +
 doc/guides/rawdevs/gdtc.rst    |  35 ++++++
 doc/guides/rawdevs/index.rst   |   1 +
 drivers/raw/gdtc/gdtc_rawdev.c | 212 +++++++++++++++++++++++++++++++++
 drivers/raw/gdtc/gdtc_rawdev.h | 120 +++++++++++++++++++
 drivers/raw/gdtc/meson.build   |   5 +
 drivers/raw/meson.build        |   1 +
 7 files changed, 379 insertions(+)
 create mode 100644 doc/guides/rawdevs/gdtc.rst
 create mode 100644 drivers/raw/gdtc/gdtc_rawdev.c
 create mode 100644 drivers/raw/gdtc/gdtc_rawdev.h
 create mode 100644 drivers/raw/gdtc/meson.build

diff --git a/MAINTAINERS b/MAINTAINERS
index c5a703b5c0..32fc4c801e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1511,6 +1511,11 @@ M: Gagandeep Singh <g.singh@nxp.com>
 F: drivers/raw/dpaa2_cmdif/
 F: doc/guides/rawdevs/dpaa2_cmdif.rst
 
+ZTE GDTC
+M: Yong Zhang <zhang.yong25@zte.com.cn>
+F: drivers/raw/gdtc/
+F: doc/guides/rawdevs/gdtc.rst
+
 
 Packet processing
 -----------------
diff --git a/doc/guides/rawdevs/gdtc.rst b/doc/guides/rawdevs/gdtc.rst
new file mode 100644
index 0000000000..7e4e648c89
--- /dev/null
+++ b/doc/guides/rawdevs/gdtc.rst
@@ -0,0 +1,35 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2024 ZTE Corporation
+
+GDTC Rawdev Driver
+======================
+
+The ``gdtc`` rawdev driver is an implementation of the rawdev API,
+that provides communication between two separate hosts.
+This is achieved via using the GDMA controller of Dinghai SoC,
+which can be configured through exposed MPF device.
+
+Device Setup
+-------------
+
+Using the GDTC PMD driver does not require the MPF device to bind
+additional user-space IO driver.
+
+Before performing actual data transmission, it is necessary to
+call ``rte_rawdev_queue_setup()`` to obtain an available queue ID.
+
+For data transfer, utilize the standard ``rte_rawdev_enqueue_buffers()`` API.
+The data transfer status can be queried via ``rte_rawdev_dequeue_buffers()``,
+which will return the number of successfully transferred data items.
+
+Initialization
+--------------
+
+The ``gdtc`` rawdev driver needs to work in IOVA PA mode.
+Consider using ``--iova-mode=pa`` in the EAL options.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+This PMD is only supported on ZTE Neo Platforms:
+- Neo X510/X512
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index f34315f051..921f3a120c 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -16,3 +16,4 @@ application through rawdev API.
     dpaa2_cmdif
     ifpga
     ntb
+    gdtc
diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
new file mode 100644
index 0000000000..436658d850
--- /dev/null
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 ZTE Corporation
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <bus_pci_driver.h>
+#include <rte_atomic.h>
+#include <rte_common.h>
+#include <rte_dev.h>
+#include <rte_eal_paging.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_spinlock.h>
+#include <rte_branch_prediction.h>
+
+#include "gdtc_rawdev.h"
+
+/* Register offset */
+#define ZXDH_GDMA_BASE_OFFSET                   0x100000
+
+#define ZXDH_GDMA_CHAN_SHIFT                    0x80
+char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
+char dev_name[] = "zxdh_gdma";
+
+uint32_t
+zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)
+{
+	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	uint32_t addr = 0;
+	uint32_t val = 0;
+
+	addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
+	val = *(uint32_t *)(gdmadev->base_addr + addr);
+
+	return val;
+}
+
+void
+zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)
+{
+	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	uint32_t addr = 0;
+
+	addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
+	*(uint32_t *)(gdmadev->base_addr + addr) = val;
+}
+
+static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
+};
+
+static int
+zxdh_gdma_map_resource(struct rte_pci_device *dev)
+{
+	int fd = -1;
+	char devname[PATH_MAX];
+	void *mapaddr = NULL;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+	snprintf(devname, sizeof(devname), "%s/" PCI_PRI_FMT "/resource0",
+		rte_pci_get_sysfs_path(),
+		loc->domain, loc->bus, loc->devid,
+		loc->function);
+
+		fd = open(devname, O_RDWR);
+		if (fd < 0) {
+			ZXDH_PMD_LOG(ERR, "Cannot open %s: %s", devname, strerror(errno));
+			return -1;
+		}
+
+	/* Map the PCI memory resource of device */
+	mapaddr = rte_mem_map(NULL, (size_t)dev->mem_resource[0].len,
+				RTE_PROT_READ | RTE_PROT_WRITE,
+				RTE_MAP_SHARED, fd, 0);
+	if (mapaddr == NULL) {
+		ZXDH_PMD_LOG(ERR, "cannot map resource(%d, 0x%zx): %s (%p)",
+				fd, (size_t)dev->mem_resource[0].len,
+				rte_strerror(rte_errno), mapaddr);
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+	dev->mem_resource[0].addr = mapaddr;
+
+	return 0;
+}
+
+static void
+zxdh_gdma_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (rte_mem_unmap(requested_addr, size))
+		ZXDH_PMD_LOG(ERR, "cannot mem unmap(%p, %#zx): %s",
+			requested_addr, size, rte_strerror(rte_errno));
+	else
+		ZXDH_PMD_LOG(DEBUG, "PCI memory unmapped at %p", requested_addr);
+}
+
+static int
+zxdh_gdma_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+						struct rte_pci_device *pci_dev)
+{
+	struct rte_rawdev *dev = NULL;
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	uint8_t i = 0;
+	int ret;
+
+	if (pci_dev->mem_resource[0].phys_addr == 0) {
+		ZXDH_PMD_LOG(ERR, "PCI bar0 resource is invalid");
+		return -1;
+	}
+
+	ret = zxdh_gdma_map_resource(pci_dev);
+	if (ret != 0) {
+		ZXDH_PMD_LOG(ERR, "Failed to mmap pci device(%s)", pci_dev->name);
+		return -1;
+	}
+	ZXDH_PMD_LOG(INFO, "%s bar0 0x%"PRIx64" mapped at %p",
+				pci_dev->name, pci_dev->mem_resource[0].phys_addr,
+				pci_dev->mem_resource[0].addr);
+
+	dev = rte_rawdev_pmd_allocate(dev_name, sizeof(struct zxdh_gdma_rawdev), rte_socket_id());
+	if (dev == NULL) {
+		ZXDH_PMD_LOG(ERR, "Unable to allocate gdma rawdev");
+		goto err_out;
+	}
+	ZXDH_PMD_LOG(INFO, "Init %s on NUMA node %d, dev_id is %d",
+						dev_name, rte_socket_id(), dev->dev_id);
+
+	dev->dev_ops = &zxdh_gdma_rawdev_ops;
+	dev->device = &pci_dev->device;
+	dev->driver_name = zxdh_gdma_driver_name;
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
+	gdmadev->rawdev = dev;
+	gdmadev->queue_num = ZXDH_GDMA_TOTAL_CHAN_NUM;
+	gdmadev->used_num = 0;
+	gdmadev->base_addr = (uintptr_t)pci_dev->mem_resource[0].addr + ZXDH_GDMA_BASE_OFFSET;
+
+	for (i = 0; i < ZXDH_GDMA_TOTAL_CHAN_NUM; i++) {
+		queue = &(gdmadev->vqs[i]);
+		queue->enable = 0;
+		queue->queue_size = ZXDH_GDMA_QUEUE_SIZE;
+		rte_spinlock_init(&(queue->enqueue_lock));
+	}
+
+	return 0;
+
+err_out:
+	zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
+		(size_t)pci_dev->mem_resource[0].len);
+	return -1;
+}
+
+static int
+zxdh_gdma_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+	struct rte_rawdev *dev = NULL;
+	int ret = 0;
+
+	dev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (dev == NULL)
+		return -EINVAL;
+
+	/* rte_rawdev_close is called by pmd_release */
+	ret = rte_rawdev_pmd_release(dev);
+	if (ret != 0) {
+		ZXDH_PMD_LOG(ERR, "Device cleanup failed");
+		return -1;
+	}
+
+	zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
+		(size_t)pci_dev->mem_resource[0].len);
+
+	ZXDH_PMD_LOG(DEBUG, "rawdev %s remove done!", dev_name);
+
+	return ret;
+}
+
+static const struct rte_pci_id zxdh_gdma_rawdev_map[] = {
+	{ RTE_PCI_DEVICE(ZXDH_GDMA_VENDORID, ZXDH_GDMA_DEVICEID) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+static struct rte_pci_driver zxdh_gdma_rawdev_pmd = {
+	.id_table = zxdh_gdma_rawdev_map,
+	.drv_flags = 0,
+	.probe = zxdh_gdma_rawdev_probe,
+	.remove = zxdh_gdma_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(zxdh_gdma_rawdev_pci_driver, zxdh_gdma_rawdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(zxdh_gdma_rawdev_pci_driver, zxdh_gdma_rawdev_map);
+RTE_LOG_REGISTER_DEFAULT(zxdh_gdma_rawdev_logtype, NOTICE);
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
new file mode 100644
index 0000000000..1c502694f4
--- /dev/null
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 ZTE Corporation
+ */
+
+#ifndef __GDTC_RAWDEV_H__
+#define __GDTC_RAWDEV_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rte_log.h>
+#include <rte_common.h>
+#include <generic/rte_spinlock.h>
+
+extern int zxdh_gdma_rawdev_logtype;
+#define RTE_LOGTYPE_ZXDH_GDMA                   zxdh_gdma_rawdev_logtype
+
+#define ZXDH_PMD_LOG(level, ...) \
+	RTE_LOG_LINE_PREFIX(level, ZXDH_GDMA, \
+		"%s() line %u: ", __func__ RTE_LOG_COMMA __LINE__, __VA_ARGS__)
+
+#define ZXDH_GDMA_VENDORID                      0x1cf2
+#define ZXDH_GDMA_DEVICEID                      0x8044
+
+#define ZXDH_GDMA_TOTAL_CHAN_NUM                58
+#define ZXDH_GDMA_QUEUE_SIZE                    16384
+#define ZXDH_GDMA_RING_SIZE                     32768
+
+enum zxdh_gdma_device_state {
+	ZXDH_GDMA_DEV_RUNNING,
+	ZXDH_GDMA_DEV_STOPPED
+};
+
+struct zxdh_gdma_buff_desc {
+	uint32_t SrcAddr_L;
+	uint32_t DstAddr_L;
+	uint32_t Xpara;
+	uint32_t ZY_para;
+	uint32_t ZY_SrcStep;
+	uint32_t ZY_DstStep;
+	uint32_t ExtAddr;
+	uint32_t LLI_Addr_L;
+	uint32_t LLI_Addr_H;
+	uint32_t ChCont;
+	uint32_t LLI_User;
+	uint32_t ErrAddr;
+	uint32_t Control;
+	uint32_t SrcAddr_H;
+	uint32_t DstAddr_H;
+	uint32_t Reserved;
+};
+
+struct zxdh_gdma_job {
+	uint64_t src;
+	uint64_t dest;
+	uint32_t len;
+	uint32_t flags;
+	uint64_t cnxt;
+	uint16_t status;
+	uint16_t vq_id;
+	void *usr_elem;
+	uint8_t ep_id;
+	uint8_t pf_id;
+	uint16_t vf_id;
+};
+
+struct zxdh_gdma_queue {
+	uint8_t   enable;
+	uint8_t   is_txq;
+	uint16_t  vq_id;
+	uint16_t  queue_size;
+	/* 0:GDMA needs to be configured through the APB interface */
+	uint16_t  flag;
+	uint32_t  user;
+	uint16_t  tc_cnt;
+	rte_spinlock_t enqueue_lock;
+	struct {
+		uint16_t avail_idx;
+		uint16_t last_avail_idx;
+		rte_iova_t ring_mem;
+		const struct rte_memzone *ring_mz;
+		struct zxdh_gdma_buff_desc *desc;
+	} ring;
+	struct {
+		uint16_t  free_cnt;
+		uint16_t  deq_cnt;
+		uint16_t  pend_cnt;
+		uint16_t  enq_idx;
+		uint16_t  deq_idx;
+		uint16_t  used_idx;
+		struct zxdh_gdma_job **job;
+	} sw_ring;
+};
+
+struct zxdh_gdma_rawdev {
+	struct rte_device *device;
+	struct rte_rawdev *rawdev;
+	uintptr_t base_addr;
+	uint8_t queue_num; /* total queue num */
+	uint8_t used_num;  /* used  queue num */
+	enum zxdh_gdma_device_state device_state;
+	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
+};
+
+static inline struct zxdh_gdma_rawdev *
+zxdh_gdma_rawdev_get_priv(const struct rte_rawdev *rawdev)
+{
+	return rawdev->dev_private;
+}
+
+uint32_t zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t qidx, uint32_t offset);
+void zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t qidx, uint32_t offset, uint32_t val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GDTC_RAWDEV_H__ */
diff --git a/drivers/raw/gdtc/meson.build b/drivers/raw/gdtc/meson.build
new file mode 100644
index 0000000000..7a4c92f34c
--- /dev/null
+++ b/drivers/raw/gdtc/meson.build
@@ -0,0 +1,5 @@
+#SPDX-License-Identifier: BSD-3-Clause
+#Copyright 2024 ZTE Corporation
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_pci']
+sources = files('gdtc_rawdev.c')
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 05cad143fe..f1480c3158 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -12,5 +12,6 @@ drivers = [
         'ifpga',
         'ntb',
         'skeleton',
+        'gdtc',
 ]
 std_deps = ['rawdev']
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 26604 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v4,2/5] raw/gdtc: add support for queue setup operation
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
@ 2024-10-29 13:45 ` Yong Zhang
  2024-11-12  5:05   ` Stephen Hemminger
  2024-10-29 13:45 ` [v4,3/5] raw/gdtc: add support for standard rawdev operations Yong Zhang
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Yong Zhang @ 2024-10-29 13:45 UTC (permalink / raw)
  To: thomas; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 9845 bytes --]

Add queue initialization and release interface.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 242 +++++++++++++++++++++++++++++++++
 drivers/raw/gdtc/gdtc_rawdev.h |  19 +++
 2 files changed, 261 insertions(+)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index 436658d850..c4f02cfd20 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -28,13 +28,58 @@
 
 #include "gdtc_rawdev.h"
 
+/*
+ * User define:
+ * ep_id-bit[15:12] vfunc_num-bit[11:4] func_num-bit[3:1] vfunc_active-bit0
+ * host ep_id:5~8   zf ep_id:9
+ */
+#define ZXDH_GDMA_ZF_USER                       0x9000      /* ep4 pf0 */
+#define ZXDH_GDMA_PF_NUM_SHIFT                  1
+#define ZXDH_GDMA_VF_NUM_SHIFT                  4
+#define ZXDH_GDMA_EP_ID_SHIFT                   12
+#define ZXDH_GDMA_VF_EN                         1
+#define ZXDH_GDMA_EPID_OFFSET                   5
+
 /* Register offset */
 #define ZXDH_GDMA_BASE_OFFSET                   0x100000
+#define ZXDH_GDMA_EXT_ADDR_OFFSET               0x218
+#define ZXDH_GDMA_CONTROL_OFFSET                0x230
+#define ZXDH_GDMA_TC_CNT_OFFSET                 0x23c
+#define ZXDH_GDMA_LLI_USER_OFFSET               0x228
+
+#define ZXDH_GDMA_CHAN_FORCE_CLOSE              (1 << 31)
+
+/* TC count & Error interrupt status register */
+#define ZXDH_GDMA_SRC_LLI_ERR                   (1 << 16)
+#define ZXDH_GDMA_SRC_DATA_ERR                  (1 << 17)
+#define ZXDH_GDMA_DST_ADDR_ERR                  (1 << 18)
+#define ZXDH_GDMA_ERR_STATUS                    (1 << 19)
+#define ZXDH_GDMA_ERR_INTR_ENABLE               (1 << 20)
+#define ZXDH_GDMA_TC_CNT_CLEAN                  (1)
 
 #define ZXDH_GDMA_CHAN_SHIFT                    0x80
+#define LOW32_MASK                              0xffffffff
+#define LOW16_MASK                              0xffff
+
+static int zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id);
+static int zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id);
+
 char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
 char dev_name[] = "zxdh_gdma";
 
+static inline struct zxdh_gdma_queue *
+zxdh_gdma_get_queue(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+
+	if (queue_id >= ZXDH_GDMA_TOTAL_CHAN_NUM) {
+		ZXDH_PMD_LOG(ERR, "queue id %d is invalid", queue_id);
+		return NULL;
+	}
+
+	return &(gdmadev->vqs[queue_id]);
+}
+
 uint32_t
 zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)
 {
@@ -58,9 +103,206 @@ zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset,
 	*(uint32_t *)(gdmadev->base_addr + addr) = val;
 }
 
+static int
+zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
+							 uint16_t queue_id,
+							 rte_rawdev_obj_t queue_conf,
+							 size_t conf_size)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	struct zxdh_gdma_queue_config *qconfig = NULL;
+	struct zxdh_gdma_rbp *rbp = NULL;
+	uint16_t i = 0;
+	uint8_t is_txq = 0;
+	uint32_t src_user = 0;
+	uint32_t dst_user = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	if ((queue_conf == NULL) || (conf_size != sizeof(struct zxdh_gdma_queue_config)))
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	qconfig = (struct zxdh_gdma_queue_config *)queue_conf;
+
+	for (i = 0; i < ZXDH_GDMA_TOTAL_CHAN_NUM; i++) {
+		if (gdmadev->vqs[i].enable == 0)
+			break;
+	}
+	if (i >= ZXDH_GDMA_TOTAL_CHAN_NUM) {
+		ZXDH_PMD_LOG(ERR, "Failed to setup queue, no avail queues");
+		return -1;
+	}
+	queue_id = i;
+	if (zxdh_gdma_queue_init(dev, queue_id) != 0) {
+		ZXDH_PMD_LOG(ERR, "Failed to init queue");
+		return -1;
+	}
+	queue = &(gdmadev->vqs[queue_id]);
+
+	rbp = qconfig->rbp;
+	if ((rbp->srbp != 0) && (rbp->drbp == 0)) {
+		is_txq = 0;
+		dst_user = ZXDH_GDMA_ZF_USER;
+		src_user = ((rbp->spfid << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((rbp->sportid + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (rbp->svfid != 0)
+			src_user |= (ZXDH_GDMA_VF_EN |
+						 ((rbp->svfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+
+		ZXDH_PMD_LOG(DEBUG, "rxq->qidx:%d setup src_user(ep:%d pf:%d vf:%d) success",
+					queue_id, (uint8_t)rbp->sportid, (uint8_t)rbp->spfid,
+					(uint8_t)rbp->svfid);
+	} else if ((rbp->srbp == 0) && (rbp->drbp != 0)) {
+		is_txq = 1;
+		src_user = ZXDH_GDMA_ZF_USER;
+		dst_user = ((rbp->dpfid << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((rbp->dportid + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (rbp->dvfid != 0)
+			dst_user |= (ZXDH_GDMA_VF_EN |
+						 ((rbp->dvfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+
+		ZXDH_PMD_LOG(DEBUG, "txq->qidx:%d setup dst_user(ep:%d pf:%d vf:%d) success",
+					queue_id, (uint8_t)rbp->dportid, (uint8_t)rbp->dpfid,
+					(uint8_t)rbp->dvfid);
+	} else {
+		ZXDH_PMD_LOG(ERR, "Failed to setup queue, srbp/drbp is invalid");
+		return -EINVAL;
+	}
+	queue->is_txq = is_txq;
+
+	/* setup queue user info */
+	queue->user = (src_user & LOW16_MASK) | (dst_user << 16);
+
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_EXT_ADDR_OFFSET, queue->user);
+	gdmadev->used_num++;
+
+	return queue_id;
+}
+
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
+	.queue_setup = zxdh_gdma_rawdev_queue_setup,
 };
 
+static int
+zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+	struct zxdh_gdma_queue *queue = NULL;
+	const struct rte_memzone *mz = NULL;
+	uint32_t size = 0;
+	int ret = 0;
+
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if (queue == NULL)
+		return -EINVAL;
+
+	queue->enable = 1;
+	queue->vq_id  = queue_id;
+	queue->flag   = 0;
+	queue->tc_cnt = 0;
+
+	/* Init sw_ring */
+	memset(name, 0, sizeof(name));
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "gdma_vq%d_sw_ring", queue_id);
+	size = queue->queue_size * sizeof(struct zxdh_gdma_job *);
+	queue->sw_ring.job = rte_zmalloc(name, size, 0);
+	if (queue->sw_ring.job == NULL) {
+		ZXDH_PMD_LOG(ERR, "can not allocate sw_ring %s", name);
+		ret = -ENOMEM;
+		goto free_queue;
+	}
+
+	/* Cache up to size-1 job in the ring to prevent overwriting hardware prefetching */
+	queue->sw_ring.free_cnt = queue->queue_size - 1;
+	queue->sw_ring.deq_cnt  = 0;
+	queue->sw_ring.pend_cnt = 0;
+	queue->sw_ring.enq_idx  = 0;
+	queue->sw_ring.deq_idx  = 0;
+	queue->sw_ring.used_idx = 0;
+
+	/* Init ring */
+	memset(name, 0, sizeof(name));
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "gdma_vq%d_ring", queue_id);
+	size = ZXDH_GDMA_RING_SIZE * sizeof(struct zxdh_gdma_buff_desc);
+	mz = rte_memzone_reserve_aligned(name, size, rte_socket_id(),
+							RTE_MEMZONE_IOVA_CONTIG, size);
+	if (mz == NULL) {
+		if (rte_errno == EEXIST)
+			mz = rte_memzone_lookup(name);
+		if (mz == NULL) {
+			ZXDH_PMD_LOG(ERR, "can not allocate ring %s", name);
+			ret = -ENOMEM;
+			goto free_queue;
+		}
+	}
+	memset(mz->addr, 0, size);
+	queue->ring.ring_mz   = mz;
+	queue->ring.desc      = (struct zxdh_gdma_buff_desc *)(mz->addr);
+	queue->ring.ring_mem  = mz->iova;
+	queue->ring.avail_idx = 0;
+	ZXDH_PMD_LOG(INFO, "queue%u ring phy addr:0x%"PRIx64" virt addr:%p",
+						queue_id, mz->iova, mz->addr);
+
+	/* Initialize the hardware channel */
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET,
+		ZXDH_GDMA_CHAN_FORCE_CLOSE);
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET,
+		ZXDH_GDMA_ERR_INTR_ENABLE | ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_TC_CNT_CLEAN);
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_USER_OFFSET,
+		ZXDH_GDMA_ZF_USER);
+
+	return 0;
+
+free_queue:
+	zxdh_gdma_queue_free(dev, queue_id);
+	return ret;
+}
+
+static int
+zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	uint32_t val = 0;
+
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if (queue == NULL)
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->used_num--;
+
+	/* disable gdma channel */
+	val = ZXDH_GDMA_CHAN_FORCE_CLOSE;
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
+
+	queue->enable           = 0;
+	queue->is_txq           = 0;
+	queue->flag             = 0;
+	queue->user             = 0;
+	queue->tc_cnt           = 0;
+	queue->ring.avail_idx   = 0;
+	queue->sw_ring.free_cnt = 0;
+	queue->sw_ring.deq_cnt  = 0;
+	queue->sw_ring.pend_cnt = 0;
+	queue->sw_ring.enq_idx  = 0;
+	queue->sw_ring.deq_idx  = 0;
+	queue->sw_ring.used_idx = 0;
+
+	if (queue->sw_ring.job != NULL)
+		rte_free(queue->sw_ring.job);
+
+	if (queue->ring.ring_mz != NULL)
+		rte_memzone_free(queue->ring.ring_mz);
+
+	return 0;
+}
+
 static int
 zxdh_gdma_map_resource(struct rte_pci_device *dev)
 {
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
index 1c502694f4..6519b50831 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.h
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -104,6 +104,25 @@ struct zxdh_gdma_rawdev {
 	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
 };
 
+struct zxdh_gdma_rbp {
+	uint32_t use_ultrashort:1;
+	uint32_t enable:1;
+	uint32_t dportid:3;
+	uint32_t dpfid:3;
+	uint32_t dvfid:8; /*using route by port for destination */
+	uint32_t drbp:1;
+	uint32_t sportid:3;
+	uint32_t spfid:3;
+	uint32_t svfid:8;
+	uint32_t srbp:1;
+};
+
+struct zxdh_gdma_queue_config {
+	uint32_t lcore_id;
+	uint32_t flags;
+	struct zxdh_gdma_rbp *rbp;
+};
+
 static inline struct zxdh_gdma_rawdev *
 zxdh_gdma_rawdev_get_priv(const struct rte_rawdev *rawdev)
 {
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 23942 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v4,3/5] raw/gdtc: add support for standard rawdev operations
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
  2024-10-29 13:45 ` [v4,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
@ 2024-10-29 13:45 ` Yong Zhang
  2024-10-29 13:45 ` [v4,4/5] raw/gdtc: add support for enqueue operation Yong Zhang
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Yong Zhang @ 2024-10-29 13:45 UTC (permalink / raw)
  To: thomas; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 5409 bytes --]

Add support for rawdev operations such as dev_start and dev_stop.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 136 ++++++++++++++++++++++++++++++++-
 drivers/raw/gdtc/gdtc_rawdev.h |  10 +++
 2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index c4f02cfd20..9a1f939ee8 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -103,6 +103,96 @@ zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset,
 	*(uint32_t *)(gdmadev->base_addr + addr) = val;
 }
 
+static int
+zxdh_gdma_rawdev_info_get(struct rte_rawdev *dev,
+						  __rte_unused rte_rawdev_obj_t dev_info,
+						  __rte_unused size_t dev_info_size)
+{
+	if (dev == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_configure(const struct rte_rawdev *dev,
+						   rte_rawdev_obj_t config,
+						   size_t config_size)
+{
+	struct zxdh_gdma_config *gdma_config = NULL;
+
+	if ((dev == NULL) ||
+		(config == NULL) ||
+		(config_size != sizeof(struct zxdh_gdma_config)))
+		return -EINVAL;
+
+	gdma_config = (struct zxdh_gdma_config *)config;
+	if (gdma_config->max_vqs > ZXDH_GDMA_TOTAL_CHAN_NUM) {
+		ZXDH_PMD_LOG(ERR, "gdma supports up to %d queues", ZXDH_GDMA_TOTAL_CHAN_NUM);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_start(struct rte_rawdev *dev)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_RUNNING;
+
+	return 0;
+}
+
+static void
+zxdh_gdma_rawdev_stop(struct rte_rawdev *dev)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+
+	if (dev == NULL)
+		return;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
+}
+
+static int
+zxdh_gdma_rawdev_reset(struct rte_rawdev *dev)
+{
+	if (dev == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_close(struct rte_rawdev *dev)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	uint16_t queue_id = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	for (queue_id = 0; queue_id < ZXDH_GDMA_TOTAL_CHAN_NUM; queue_id++) {
+		queue = zxdh_gdma_get_queue(dev, queue_id);
+		if ((queue == NULL) || (queue->enable == 0))
+			continue;
+
+		zxdh_gdma_queue_free(dev, queue_id);
+	}
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
+
+	return 0;
+}
+
 static int
 zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
 							 uint16_t queue_id,
@@ -184,8 +274,52 @@ zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
 	return queue_id;
 }
 
+static int
+zxdh_gdma_rawdev_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct zxdh_gdma_queue *queue = NULL;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if ((queue == NULL) || (queue->enable == 0))
+		return -EINVAL;
+
+	zxdh_gdma_queue_free(dev, queue_id);
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_get_attr(struct rte_rawdev *dev,
+						  __rte_unused const char *attr_name,
+						  uint64_t *attr_value)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_attr *gdma_attr = NULL;
+
+	if ((dev == NULL) || (attr_value == NULL))
+		return -EINVAL;
+
+	gdmadev   = zxdh_gdma_rawdev_get_priv(dev);
+	gdma_attr = (struct zxdh_gdma_attr *)attr_value;
+	gdma_attr->num_hw_queues = gdmadev->used_num;
+
+	return 0;
+}
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
+	.dev_info_get = zxdh_gdma_rawdev_info_get,
+	.dev_configure = zxdh_gdma_rawdev_configure,
+	.dev_start = zxdh_gdma_rawdev_start,
+	.dev_stop = zxdh_gdma_rawdev_stop,
+	.dev_close = zxdh_gdma_rawdev_close,
+	.dev_reset = zxdh_gdma_rawdev_reset,
+
 	.queue_setup = zxdh_gdma_rawdev_queue_setup,
+	.queue_release = zxdh_gdma_rawdev_queue_release,
+
+	.attr_get = zxdh_gdma_rawdev_get_attr,
 };
 
 static int
@@ -248,7 +382,7 @@ zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
 	ZXDH_PMD_LOG(INFO, "queue%u ring phy addr:0x%"PRIx64" virt addr:%p",
 						queue_id, mz->iova, mz->addr);
 
-	/* Initialize the hardware channel */
+	/* Configure the hardware channel to the initial state */
 	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET,
 		ZXDH_GDMA_CHAN_FORCE_CLOSE);
 	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET,
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
index 6519b50831..c44a9ae22f 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.h
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -104,6 +104,12 @@ struct zxdh_gdma_rawdev {
 	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
 };
 
+struct zxdh_gdma_config {
+	uint16_t max_hw_queues_per_core;
+	uint16_t max_vqs;
+	int queue_pool_cnt;
+};
+
 struct zxdh_gdma_rbp {
 	uint32_t use_ultrashort:1;
 	uint32_t enable:1;
@@ -123,6 +129,10 @@ struct zxdh_gdma_queue_config {
 	struct zxdh_gdma_rbp *rbp;
 };
 
+struct zxdh_gdma_attr {
+	uint16_t num_hw_queues;
+};
+
 static inline struct zxdh_gdma_rawdev *
 zxdh_gdma_rawdev_get_priv(const struct rte_rawdev *rawdev)
 {
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 11773 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v4,4/5] raw/gdtc: add support for enqueue operation
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
  2024-10-29 13:45 ` [v4,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
  2024-10-29 13:45 ` [v4,3/5] raw/gdtc: add support for standard rawdev operations Yong Zhang
@ 2024-10-29 13:45 ` Yong Zhang
  2024-10-29 13:45 ` [v4,5/5] raw/gdtc: add support for dequeue operation Yong Zhang
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Yong Zhang @ 2024-10-29 13:45 UTC (permalink / raw)
  To: thomas; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 10994 bytes --]

Add rawdev enqueue operation for gdtc devices.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 220 +++++++++++++++++++++++++++++++++
 drivers/raw/gdtc/gdtc_rawdev.h |  19 +++
 2 files changed, 239 insertions(+)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index 9a1f939ee8..03f7cc1a8e 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -43,10 +43,34 @@
 /* Register offset */
 #define ZXDH_GDMA_BASE_OFFSET                   0x100000
 #define ZXDH_GDMA_EXT_ADDR_OFFSET               0x218
+#define ZXDH_GDMA_SAR_LOW_OFFSET                0x200
+#define ZXDH_GDMA_DAR_LOW_OFFSET                0x204
+#define ZXDH_GDMA_SAR_HIGH_OFFSET               0x234
+#define ZXDH_GDMA_DAR_HIGH_OFFSET               0x238
+#define ZXDH_GDMA_XFERSIZE_OFFSET               0x208
 #define ZXDH_GDMA_CONTROL_OFFSET                0x230
+#define ZXDH_GDMA_TC_STATUS_OFFSET              0x0
+#define ZXDH_GDMA_STATUS_CLEAN_OFFSET           0x80
+#define ZXDH_GDMA_LLI_L_OFFSET                  0x21c
+#define ZXDH_GDMA_LLI_H_OFFSET                  0x220
+#define ZXDH_GDMA_CHAN_CONTINUE_OFFSET          0x224
 #define ZXDH_GDMA_TC_CNT_OFFSET                 0x23c
 #define ZXDH_GDMA_LLI_USER_OFFSET               0x228
 
+/* Control register */
+#define ZXDH_GDMA_CHAN_ENABLE                   0x1
+#define ZXDH_GDMA_CHAN_DISABLE                  0
+#define ZXDH_GDMA_SOFT_CHAN                     0x2
+#define ZXDH_GDMA_TC_INTR_ENABLE                0x10
+#define ZXDH_GDMA_ALL_INTR_ENABLE               0x30
+#define ZXDH_GDMA_SBS_SHIFT                     6           /* src burst size */
+#define ZXDH_GDMA_SBL_SHIFT                     9           /* src burst length */
+#define ZXDH_GDMA_DBS_SHIFT                     13          /* dest burst size */
+#define ZXDH_GDMA_BURST_SIZE_MIN                0x1         /* 1 byte */
+#define ZXDH_GDMA_BURST_SIZE_MEDIUM             0x4         /* 4 word */
+#define ZXDH_GDMA_BURST_SIZE_MAX                0x6         /* 16 word */
+#define ZXDH_GDMA_DEFAULT_BURST_LEN             0xf         /* 16 beats */
+#define ZXDH_GDMA_TC_CNT_ENABLE                 (1 << 27)
 #define ZXDH_GDMA_CHAN_FORCE_CLOSE              (1 << 31)
 
 /* TC count & Error interrupt status register */
@@ -58,9 +82,15 @@
 #define ZXDH_GDMA_TC_CNT_CLEAN                  (1)
 
 #define ZXDH_GDMA_CHAN_SHIFT                    0x80
+#define ZXDH_GDMA_LINK_END_NODE                 (1 << 30)
+#define ZXDH_GDMA_CHAN_CONTINUE                 (1)
+
 #define LOW32_MASK                              0xffffffff
 #define LOW16_MASK                              0xffff
 
+#define IDX_TO_ADDR(addr, idx, t) \
+	((t)((uintptr_t)(addr) + (idx) * sizeof(struct zxdh_gdma_buff_desc)))
+
 static int zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id);
 static int zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id);
 
@@ -308,6 +338,194 @@ zxdh_gdma_rawdev_get_attr(struct rte_rawdev *dev,
 
 	return 0;
 }
+
+static inline void
+zxdh_gdma_control_cal(uint32_t *val, uint8_t tc_enable)
+{
+	*val = (ZXDH_GDMA_CHAN_ENABLE |
+			ZXDH_GDMA_SOFT_CHAN |
+			(ZXDH_GDMA_DEFAULT_BURST_LEN << ZXDH_GDMA_SBL_SHIFT) |
+			(ZXDH_GDMA_BURST_SIZE_MAX << ZXDH_GDMA_SBS_SHIFT) |
+			(ZXDH_GDMA_BURST_SIZE_MAX << ZXDH_GDMA_DBS_SHIFT));
+
+	if (tc_enable != 0)
+		*val |= ZXDH_GDMA_TC_CNT_ENABLE;
+}
+
+static inline uint32_t
+zxdh_gdma_user_get(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
+{
+	uint32_t src_user = 0;
+	uint32_t dst_user = 0;
+
+	if ((job->flags & ZXDH_GDMA_JOB_DIR_MASK) == 0) {
+		ZXDH_PMD_LOG(DEBUG, "job flags:0x%x default user:0x%x",
+							job->flags, queue->user);
+		return queue->user;
+	} else if ((job->flags & ZXDH_GDMA_JOB_DIR_TX) != 0) {
+		src_user = ZXDH_GDMA_ZF_USER;
+		dst_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((job->ep_id + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (job->vf_id != 0)
+			dst_user |= (ZXDH_GDMA_VF_EN |
+						 ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+	} else {
+		dst_user = ZXDH_GDMA_ZF_USER;
+		src_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((job->ep_id + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (job->vf_id != 0)
+			src_user |= (ZXDH_GDMA_VF_EN |
+						 ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+	}
+	ZXDH_PMD_LOG(DEBUG, "job flags:0x%x ep_id:%u, pf_id:%u, vf_id:%u, user:0x%x",
+						job->flags, job->ep_id, job->pf_id, job->vf_id,
+						(src_user & LOW16_MASK) | (dst_user << 16));
+
+	return (src_user & LOW16_MASK) | (dst_user << 16);
+}
+
+static inline void
+zxdh_gdma_fill_bd(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
+{
+	struct zxdh_gdma_buff_desc *bd = NULL;
+	uint32_t val = 0;
+	uint64_t next_bd_addr = 0;
+	uint16_t avail_idx = 0;
+
+	avail_idx = queue->ring.avail_idx;
+	bd = &(queue->ring.desc[avail_idx]);
+	memset(bd, 0, sizeof(struct zxdh_gdma_buff_desc));
+
+	/* data bd */
+	if (job != NULL) {
+		zxdh_gdma_control_cal(&val, 1);
+		next_bd_addr   = IDX_TO_ADDR(queue->ring.ring_mem,
+							(avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
+							uint64_t);
+		bd->SrcAddr_L  = job->src & LOW32_MASK;
+		bd->DstAddr_L  = job->dest & LOW32_MASK;
+		bd->SrcAddr_H  = (job->src >> 32) & LOW32_MASK;
+		bd->DstAddr_H  = (job->dest >> 32) & LOW32_MASK;
+		bd->Xpara      = job->len;
+		bd->ExtAddr    = zxdh_gdma_user_get(queue, job);
+		bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
+		bd->LLI_Addr_H = next_bd_addr >> 38;
+		bd->LLI_User   = ZXDH_GDMA_ZF_USER;
+		bd->Control    = val;
+	} else {
+		zxdh_gdma_control_cal(&val, 0);
+		next_bd_addr   = IDX_TO_ADDR(queue->ring.ring_mem, avail_idx, uint64_t);
+		bd->ExtAddr    = queue->user;
+		bd->LLI_User   = ZXDH_GDMA_ZF_USER;
+		bd->Control    = val;
+		bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
+		bd->LLI_Addr_H = (next_bd_addr >> 38) | ZXDH_GDMA_LINK_END_NODE;
+		if (queue->flag != 0) {
+			bd = IDX_TO_ADDR(queue->ring.desc,
+					queue->ring.last_avail_idx,
+					struct zxdh_gdma_buff_desc*);
+			next_bd_addr = IDX_TO_ADDR(queue->ring.ring_mem,
+					(queue->ring.last_avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
+					uint64_t);
+			bd->LLI_Addr_L  = (next_bd_addr >> 6) & LOW32_MASK;
+			bd->LLI_Addr_H  = next_bd_addr >> 38;
+			rte_wmb();
+			bd->LLI_Addr_H &= ~ZXDH_GDMA_LINK_END_NODE;
+		}
+		/* Record the index of empty bd for dynamic chaining */
+		queue->ring.last_avail_idx = avail_idx;
+	}
+
+	if (++avail_idx >= ZXDH_GDMA_RING_SIZE)
+		avail_idx -= ZXDH_GDMA_RING_SIZE;
+
+	queue->ring.avail_idx = avail_idx;
+}
+
+static int
+zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *dev,
+						__rte_unused struct rte_rawdev_buf **buffers,
+						uint32_t count,
+						rte_rawdev_obj_t context)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	struct zxdh_gdma_enqdeq *e_context = NULL;
+	struct zxdh_gdma_job *job = NULL;
+	uint16_t queue_id = 0;
+	uint32_t val = 0;
+	uint16_t i = 0;
+	uint16_t free_cnt = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	if (unlikely((count < 1) || (context == NULL)))
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	if (gdmadev->device_state == ZXDH_GDMA_DEV_STOPPED) {
+		ZXDH_PMD_LOG(ERR, "gdma dev is stop");
+		return 0;
+	}
+
+	e_context = (struct zxdh_gdma_enqdeq *)context;
+	queue_id = e_context->vq_id;
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if ((queue == NULL) || (queue->enable == 0))
+		return -EINVAL;
+
+	free_cnt = queue->sw_ring.free_cnt;
+	if (free_cnt == 0) {
+		ZXDH_PMD_LOG(ERR, "queue %u is full, enq_idx:%u deq_idx:%u used_idx:%u",
+						   queue_id, queue->sw_ring.enq_idx,
+						   queue->sw_ring.deq_idx, queue->sw_ring.used_idx);
+		return 0;
+	} else if (free_cnt < count) {
+		ZXDH_PMD_LOG(DEBUG, "job num %u > free_cnt, change to %u", count, free_cnt);
+		count = free_cnt;
+	}
+
+	rte_spinlock_lock(&queue->enqueue_lock);
+
+	/* Build bd list, the last bd is empty bd */
+	for (i = 0; i < count; i++) {
+		job = e_context->job[i];
+		zxdh_gdma_fill_bd(queue, job);
+	}
+	zxdh_gdma_fill_bd(queue, NULL);
+
+	if (unlikely(queue->flag == 0)) {
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_L_OFFSET,
+							(queue->ring.ring_mem >> 6) & LOW32_MASK);
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_H_OFFSET,
+							 queue->ring.ring_mem >> 38);
+		/* Start hardware handling */
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0);
+		zxdh_gdma_control_cal(&val, 0);
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
+		queue->flag = 1;
+	} else {
+		val = ZXDH_GDMA_CHAN_CONTINUE;
+		zxdh_gdma_write_reg(dev, queue->vq_id, ZXDH_GDMA_CHAN_CONTINUE_OFFSET, val);
+	}
+
+    /* job enqueue */
+	for (i = 0; i < count; i++) {
+		queue->sw_ring.job[queue->sw_ring.enq_idx] = e_context->job[i];
+		if (++queue->sw_ring.enq_idx >= queue->queue_size)
+			queue->sw_ring.enq_idx -= queue->queue_size;
+
+		free_cnt--;
+	}
+	queue->sw_ring.free_cnt = free_cnt;
+	queue->sw_ring.pend_cnt += count;
+	rte_spinlock_unlock(&queue->enqueue_lock);
+
+	return count;
+}
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.dev_info_get = zxdh_gdma_rawdev_info_get,
 	.dev_configure = zxdh_gdma_rawdev_configure,
@@ -320,6 +538,8 @@ static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.queue_release = zxdh_gdma_rawdev_queue_release,
 
 	.attr_get = zxdh_gdma_rawdev_get_attr,
+
+	.enqueue_bufs = zxdh_gdma_rawdev_enqueue_bufs,
 };
 
 static int
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
index c44a9ae22f..9213a248d4 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.h
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -28,6 +28,20 @@ extern int zxdh_gdma_rawdev_logtype;
 #define ZXDH_GDMA_QUEUE_SIZE                    16384
 #define ZXDH_GDMA_RING_SIZE                     32768
 
+/* States if the source addresses is physical. */
+#define ZXDH_GDMA_JOB_SRC_PHY                   (1UL)
+
+/* States if the destination addresses is physical. */
+#define ZXDH_GDMA_JOB_DEST_PHY                  (1UL << 1)
+
+/* ZF->HOST */
+#define ZXDH_GDMA_JOB_DIR_TX                    (1UL << 2)
+
+/* HOST->ZF */
+#define ZXDH_GDMA_JOB_DIR_RX                    (1UL << 3)
+
+#define ZXDH_GDMA_JOB_DIR_MASK                  (ZXDH_GDMA_JOB_DIR_TX | ZXDH_GDMA_JOB_DIR_RX)
+
 enum zxdh_gdma_device_state {
 	ZXDH_GDMA_DEV_RUNNING,
 	ZXDH_GDMA_DEV_STOPPED
@@ -104,6 +118,11 @@ struct zxdh_gdma_rawdev {
 	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
 };
 
+struct zxdh_gdma_enqdeq {
+	uint16_t vq_id;
+	struct zxdh_gdma_job **job;
+};
+
 struct zxdh_gdma_config {
 	uint16_t max_hw_queues_per_core;
 	uint16_t max_vqs;
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 28516 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v4,5/5] raw/gdtc: add support for dequeue operation
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (2 preceding siblings ...)
  2024-10-29 13:45 ` [v4,4/5] raw/gdtc: add support for enqueue operation Yong Zhang
@ 2024-10-29 13:45 ` Yong Zhang
  2024-11-04  2:15 ` Re:[PATCH] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Yong Zhang @ 2024-10-29 13:45 UTC (permalink / raw)
  To: thomas; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 4716 bytes --]

Add rawdev dequeue operation for gdtc devices.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 113 +++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index 03f7cc1a8e..8e9543f402 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -88,6 +88,8 @@
 #define LOW32_MASK                              0xffffffff
 #define LOW16_MASK                              0xffff
 
+#define ZXDH_GDMA_TC_CNT_MAX                    0x10000
+
 #define IDX_TO_ADDR(addr, idx, t) \
 	((t)((uintptr_t)(addr) + (idx) * sizeof(struct zxdh_gdma_buff_desc)))
 
@@ -526,6 +528,116 @@ zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *dev,
 
 	return count;
 }
+
+static inline void
+zxdh_gdma_used_idx_update(struct zxdh_gdma_queue *queue, uint16_t cnt, uint8_t data_bd_err)
+{
+	uint16_t idx = 0;
+
+	if (queue->sw_ring.used_idx + cnt < queue->queue_size)
+		queue->sw_ring.used_idx += cnt;
+	else
+		queue->sw_ring.used_idx = queue->sw_ring.used_idx + cnt - queue->queue_size;
+
+	if (data_bd_err == 1) {
+		/* Update job status, the last job status is error */
+		if (queue->sw_ring.used_idx == 0)
+			idx = queue->queue_size - 1;
+		else
+			idx = queue->sw_ring.used_idx - 1;
+
+		queue->sw_ring.job[idx]->status = 1;
+	}
+}
+
+static int
+zxdh_gdma_rawdev_dequeue_bufs(struct rte_rawdev *dev,
+						__rte_unused struct rte_rawdev_buf **buffers,
+						uint32_t count,
+						rte_rawdev_obj_t context)
+{
+	struct zxdh_gdma_queue *queue = NULL;
+	struct zxdh_gdma_enqdeq *e_context = NULL;
+	uint16_t queue_id = 0;
+	uint32_t val = 0;
+	uint16_t tc_cnt = 0;
+	uint16_t diff_cnt = 0;
+	uint16_t i = 0;
+	uint16_t bd_idx = 0;
+	uint64_t next_bd_addr = 0;
+	uint8_t data_bd_err = 0;
+
+	if ((dev == NULL) || (context == NULL))
+		return -EINVAL;
+
+	e_context = (struct zxdh_gdma_enqdeq *)context;
+	queue_id = e_context->vq_id;
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if ((queue == NULL) || (queue->enable == 0))
+		return -EINVAL;
+
+	if (queue->sw_ring.pend_cnt == 0)
+		goto deq_job;
+
+	/* Get data transmit count */
+	val = zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET);
+	tc_cnt = val & LOW16_MASK;
+	if (tc_cnt >= queue->tc_cnt)
+		diff_cnt = tc_cnt - queue->tc_cnt;
+	else
+		diff_cnt = tc_cnt + ZXDH_GDMA_TC_CNT_MAX - queue->tc_cnt;
+
+	queue->tc_cnt = tc_cnt;
+
+	/* Data transmit error, channel stopped */
+	if ((val & ZXDH_GDMA_ERR_STATUS) != 0) {
+		next_bd_addr  = zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_LLI_L_OFFSET);
+		next_bd_addr |= ((uint64_t)zxdh_gdma_read_reg(dev, queue_id,
+							ZXDH_GDMA_LLI_H_OFFSET) << 32);
+		next_bd_addr  = next_bd_addr << 6;
+		bd_idx = (next_bd_addr - queue->ring.ring_mem) / sizeof(struct zxdh_gdma_buff_desc);
+		if ((val & ZXDH_GDMA_SRC_DATA_ERR) || (val & ZXDH_GDMA_DST_ADDR_ERR)) {
+			diff_cnt++;
+			data_bd_err = 1;
+		}
+		ZXDH_PMD_LOG(INFO, "queue%d is err(0x%x) next_bd_idx:%u ll_addr:0x%"PRIx64" def user:0x%x",
+					queue_id, val, bd_idx, next_bd_addr, queue->user);
+
+		ZXDH_PMD_LOG(INFO, "Clean up error status");
+		val = ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_ERR_INTR_ENABLE;
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET, val);
+
+		ZXDH_PMD_LOG(INFO, "Restart channel");
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0);
+		zxdh_gdma_control_cal(&val, 0);
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
+	}
+
+	if (diff_cnt != 0) {
+		zxdh_gdma_used_idx_update(queue, diff_cnt, data_bd_err);
+		queue->sw_ring.deq_cnt += diff_cnt;
+		queue->sw_ring.pend_cnt -= diff_cnt;
+	}
+
+deq_job:
+	if (queue->sw_ring.deq_cnt == 0)
+		return 0;
+	else if (queue->sw_ring.deq_cnt < count)
+		count = queue->sw_ring.deq_cnt;
+
+	queue->sw_ring.deq_cnt -= count;
+
+	for (i = 0; i < count; i++) {
+		e_context->job[i] = queue->sw_ring.job[queue->sw_ring.deq_idx];
+		queue->sw_ring.job[queue->sw_ring.deq_idx] = NULL;
+		if (++queue->sw_ring.deq_idx >= queue->queue_size)
+			queue->sw_ring.deq_idx -= queue->queue_size;
+	}
+	queue->sw_ring.free_cnt += count;
+
+	return count;
+}
+
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.dev_info_get = zxdh_gdma_rawdev_info_get,
 	.dev_configure = zxdh_gdma_rawdev_configure,
@@ -540,6 +652,7 @@ static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.attr_get = zxdh_gdma_rawdev_get_attr,
 
 	.enqueue_bufs = zxdh_gdma_rawdev_enqueue_bufs,
+	.dequeue_bufs = zxdh_gdma_rawdev_dequeue_bufs,
 };
 
 static int
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 11317 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re:[PATCH] raw/gdtc: introduce gdtc raw device driver
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (3 preceding siblings ...)
  2024-10-29 13:45 ` [v4,5/5] raw/gdtc: add support for dequeue operation Yong Zhang
@ 2024-11-04  2:15 ` Yong Zhang
  2024-11-12  4:12   ` [PATCH] " Thomas Monjalon
  2024-11-12  5:08 ` [v4,1/5] " Stephen Hemminger
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Yong Zhang @ 2024-11-04  2:15 UTC (permalink / raw)
  To: thomas; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 228 bytes --]

Hi thomas,

I submitted a patch on October 29 and haven't received response.
Wondering if any modifications are needed? Could you provide an update on the review?
Thanks. Looking forward to hearing from you.

Best regards,

[-- Attachment #1.1.2: Type: text/html , Size: 414 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] raw/gdtc: introduce gdtc raw device driver
  2024-11-04  2:15 ` Re:[PATCH] raw/gdtc: introduce gdtc raw device driver Yong Zhang
@ 2024-11-12  4:12   ` Thomas Monjalon
  2024-11-12  5:13     ` Stephen Hemminger
  2024-11-14  9:36     ` zhang.yong25
  0 siblings, 2 replies; 25+ messages in thread
From: Thomas Monjalon @ 2024-11-12  4:12 UTC (permalink / raw)
  To: Yong Zhang; +Cc: dev, zhang.yong25, wang.yong19, li.min10, ran.ming

Hello,

04/11/2024 03:15, Yong Zhang:
> Hi thomas,
> 
> I submitted a patch on October 29 and haven't received response.
> Wondering if any modifications are needed? Could you provide an update on the review?
> Thanks. Looking forward to hearing from you.

I cannot apply your patches because the format looks wrong.
It looks there an issue with line ending. Windows?



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,2/5] raw/gdtc: add support for queue setup operation
  2024-10-29 13:45 ` [v4,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
@ 2024-11-12  5:05   ` Stephen Hemminger
  0 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-12  5:05 UTC (permalink / raw)
  To: Yong Zhang; +Cc: thomas, dev, wang.yong19, li.min10, ran.ming

On Tue, 29 Oct 2024 21:45:24 +0800
Yong Zhang <zhang.yong25@zte.com.cn> wrote:

> +	/* Init sw_ring */
> +	memset(name, 0, sizeof(name));
> +	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "gdma_vq%d_sw_ring", queue_id);
> +	size = queue->queue_size * sizeof(struct zxdh_gdma_job *);
> +	queue->sw_ring.job = rte_zmalloc(name, size, 0);

This works as is, but:
	1. Do not need memset() before snprintf since snprintf will create null terminated string
	2. rte_zmalloc() doesn't really care about the name arg
	3. You should be using rte_calloc() if it is an array, because that is more common
           and may help some checkers in future when DPDK can tell compiler that rte_calloc is functional
	   equivalent of calloc().
	4. The name is being used as a memzone name, and not a rawdev name.
		RTE_RAWDEV_NAME_MAX_LEN = 64
                RTE_MEMZONE_NAMESIZE = 32
           so you are at some risk of future bug where memzone names becomes too long.


		> +
> +	if (queue->sw_ring.job != NULL)
> +		rte_free(queue->sw_ring.job);
> +
> +	if (queue->ring.ring_mz != NULL)
> +		rte_memzone_free(queue->ring.ring_mz);

Both these function handle NULL as a no-op, so the check for NULL is unnecessary.
There is a coccinelle script that finds these.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (4 preceding siblings ...)
  2024-11-04  2:15 ` Re:[PATCH] raw/gdtc: introduce gdtc raw device driver Yong Zhang
@ 2024-11-12  5:08 ` Stephen Hemminger
  2024-11-12  5:08 ` Stephen Hemminger
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-12  5:08 UTC (permalink / raw)
  To: Yong Zhang; +Cc: thomas, dev, wang.yong19, li.min10, ran.ming

On Tue, 29 Oct 2024 21:45:22 +0800
Yong Zhang <zhang.yong25@zte.com.cn> wrote:

> diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
> new file mode 100644
> index 0000000000..1c502694f4
> --- /dev/null
> +++ b/drivers/raw/gdtc/gdtc_rawdev.h
> @@ -0,0 +1,120 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2024 ZTE Corporation
> + */
> +
> +#ifndef __GDTC_RAWDEV_H__
> +#define __GDTC_RAWDEV_H__
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif


This file is only include by gdtc_rawdev.c therefore the C++ guards
are not needed.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (5 preceding siblings ...)
  2024-11-12  5:08 ` [v4,1/5] " Stephen Hemminger
@ 2024-11-12  5:08 ` Stephen Hemminger
  2024-11-13  9:22   ` zhang.yong25
  2024-11-12  5:09 ` Stephen Hemminger
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-12  5:08 UTC (permalink / raw)
  To: Yong Zhang; +Cc: thomas, dev, wang.yong19, li.min10, ran.ming

On Tue, 29 Oct 2024 21:45:22 +0800
Yong Zhang <zhang.yong25@zte.com.cn> wrote:

> +char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
> +char dev_name[] = "zxdh_gdma";
> +
> +uint32_t
> +zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)
> +{
> +	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
> +	uint32_t addr = 0;
> +	uint32_t val = 0;
> +
> +	addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
> +	val = *(uint32_t *)(gdmadev->base_addr + addr);
> +
> +	return val;
> +}
> +
> +void
> +zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)
> +{
> +	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
> +	uint32_t addr = 0;
> +
> +	addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
> +	*(uint32_t *)(gdmadev->base_addr + addr) = val;
> +}

This driver is made up one C file. Please make all these helper functions
and the names static. If static checkers and optimizers can work better.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (6 preceding siblings ...)
  2024-11-12  5:08 ` Stephen Hemminger
@ 2024-11-12  5:09 ` Stephen Hemminger
  2024-11-12  5:48 ` Stephen Hemminger
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
  9 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-12  5:09 UTC (permalink / raw)
  To: Yong Zhang; +Cc: thomas, dev, wang.yong19, li.min10, ran.ming

On Tue, 29 Oct 2024 21:45:22 +0800
Yong Zhang <zhang.yong25@zte.com.cn> wrote:

> diff --git a/drivers/raw/gdtc/meson.build b/drivers/raw/gdtc/meson.build
> new file mode 100644
> index 0000000000..7a4c92f34c
> --- /dev/null
> +++ b/drivers/raw/gdtc/meson.build
> @@ -0,0 +1,5 @@
> +#SPDX-License-Identifier: BSD-3-Clause
> +#Copyright 2024 ZTE Corporation
> +

Space required in these comment headers.
I.e
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2024 ZTE Corporation

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] raw/gdtc: introduce gdtc raw device driver
  2024-11-12  4:12   ` [PATCH] " Thomas Monjalon
@ 2024-11-12  5:13     ` Stephen Hemminger
  2024-11-14  9:36     ` zhang.yong25
  1 sibling, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-12  5:13 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Yong Zhang, dev, wang.yong19, li.min10, ran.ming

On Tue, 12 Nov 2024 05:12:32 +0100
Thomas Monjalon <thomas@monjalon.net> wrote:

> Hello,
> 
> 04/11/2024 03:15, Yong Zhang:
> > Hi thomas,
> > 
> > I submitted a patch on October 29 and haven't received response.
> > Wondering if any modifications are needed? Could you provide an update on the review?
> > Thanks. Looking forward to hearing from you.  
> 
> I cannot apply your patches because the format looks wrong.
> It looks there an issue with line ending. Windows?

I made a bundle in patchwork, then downloaded it and did:

 $ git am ~/Downloads/bundle-1307-gdtc.mbox

And it worked for me, no whitespace or new line issues.
I wonder if there is some hidden setting in patchwork or git cleaning it for me?

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (7 preceding siblings ...)
  2024-11-12  5:09 ` Stephen Hemminger
@ 2024-11-12  5:48 ` Stephen Hemminger
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
  9 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-12  5:48 UTC (permalink / raw)
  To: Yong Zhang; +Cc: thomas, dev, wang.yong19, li.min10, ran.ming

On Tue, 29 Oct 2024 21:45:22 +0800
Yong Zhang <zhang.yong25@zte.com.cn> wrote:

> diff --git a/MAINTAINERS b/MAINTAINERS
> index c5a703b5c0..32fc4c801e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1511,6 +1511,11 @@ M: Gagandeep Singh <g.singh@nxp.com>
>  F: drivers/raw/dpaa2_cmdif/
>  F: doc/guides/rawdevs/dpaa2_cmdif.rst
>  
> +ZTE GDTC
> +M: Yong Zhang <zhang.yong25@zte.com.cn>
> +F: drivers/raw/gdtc/
> +F: doc/guides/rawdevs/gdtc.rst
> +

Please add your mail address to .mailmap as well.

$ ./devtools/check-git-log.sh -n5
Contributor name/email mismatch with .mailmap: 
	Yong Zhang <zhang.yong25@zte.com.cn> is unknown in .mailmap

Invalid patch(es) found - checked 5 patches

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-11-12  5:08 ` Stephen Hemminger
@ 2024-11-13  9:22   ` zhang.yong25
  2024-11-13 14:59     ` Stephen Hemminger
  0 siblings, 1 reply; 25+ messages in thread
From: zhang.yong25 @ 2024-11-13  9:22 UTC (permalink / raw)
  To: stephen; +Cc: dev, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 2731 bytes --]

Hi Stephen,

>> +char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";>> +char dev_name[] = "zxdh_gdma";>> +>> +uint32_t>> +zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)>> +{>> +    struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);>> +    uint32_t addr = 0;>> +    uint32_t val = 0;>> +>> +    addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;>> +    val = *(uint32_t *)(gdmadev->base_addr + addr);>> +>> +    return val;>> +}>> +>> +void>> +zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)>> +{>> +    struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);>> +    uint32_t addr = 0;>> +>> +    addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;>> +    *(uint32_t *)(gdmadev->base_addr + addr) = val;>> +}>>This driver is made up one C file. Please make all these helper functions>and the names static. If static checkers and optimizers can work better.

Thanks for your suggestion, I will check other functions. But these two functions will also 
be called by the test application(Not Submitted), so it is not appropriate to names static.







张勇 zhangyong


RCH八部/无线及算力研究院/无线及算力产品经营部
RCH Dept. VIII/Wireless and Computing Product R&D Institute/Wireless and Computing Product Operation Division




Original


From: StephenHemminger <stephen@networkplumber.org>
To: 张勇10313449;
Cc: thomas@monjalon.net <thomas@monjalon.net>;dev@dpdk.org <dev@dpdk.org>;汪勇10032886;李敏10314441;冉明10033339;
Date: 2024年11月12日 13:11
Subject: Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver

On Tue, 29 Oct 2024 21:45:22 +0800
Yong Zhang <zhang.yong25@zte.com.cn> wrote:
 
> +char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
> +char dev_name[] = "zxdh_gdma";
> +
> +uint32_t
> +zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)
> +{
> +    struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
> +    uint32_t addr = 0;
> +    uint32_t val = 0;
> +
> +    addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
> +    val = *(uint32_t *)(gdmadev->base_addr + addr);
> +
> +    return val;
> +}
> +
> +void
> +zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)
> +{
> +    struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
> +    uint32_t addr = 0;
> +
> +    addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
> +    *(uint32_t *)(gdmadev->base_addr + addr) = val;
> +}
 
This driver is made up one C file. Please make all these helper functions
and the names static. If static checkers and optimizers can work better.

[-- Attachment #1.1.2: Type: text/html , Size: 13634 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v4,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-11-13  9:22   ` zhang.yong25
@ 2024-11-13 14:59     ` Stephen Hemminger
  0 siblings, 0 replies; 25+ messages in thread
From: Stephen Hemminger @ 2024-11-13 14:59 UTC (permalink / raw)
  To: zhang.yong25; +Cc: dev, wang.yong19, li.min10, ran.ming

On Wed, 13 Nov 2024 17:22:57 +0800 (CST)
<zhang.yong25@zte.com.cn> wrote:

> Hi Stephen,
> 
> >> +char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";>> +char dev_name[] = "zxdh_gdma";>> +>> +uint32_t>> +zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)>> +{>> +    struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);>> +    uint32_t addr = 0;>> +    uint32_t val = 0;>> +>> +    addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;>> +    val = *(uint32_t *)(gdmadev->base_addr + addr);>> +>> +    return val;>> +}>> +>> +void>> +zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)>> +{>> +    struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);>> +    uint32_t addr = 0;>> +>> +    addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;>> +    *(uint32_t *)(gdmadev->base_addr + addr) = val;>> +}>>This driver is made up one C file. Please make all these helper functions>and the names static. If static checkers and optimizers can work better.  
> 
> Thanks for your suggestion, I will check other functions. But these two functions will also 
> be called by the test application(Not Submitted), so it is not appropriate to names static.


If you need the functions for a test app then they need to be in version.map and
in a user API header file. It is ok to have PMD specific hooks, but they need to
be treated as real API's.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v5,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
                   ` (8 preceding siblings ...)
  2024-11-12  5:48 ` Stephen Hemminger
@ 2024-11-14  9:20 ` Yong Zhang
  2024-11-14  9:20   ` [v5,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
                     ` (4 more replies)
  9 siblings, 5 replies; 25+ messages in thread
From: Yong Zhang @ 2024-11-14  9:20 UTC (permalink / raw)
  To: thomas, stephen, dev; +Cc: zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 12393 bytes --]

Introduce rawdev driver support for GDTC which
can help to connect two separate hosts with each other.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 .mailmap                       |   1 +
 MAINTAINERS                    |   5 +
 doc/guides/rawdevs/gdtc.rst    |  35 ++++++
 doc/guides/rawdevs/index.rst   |   1 +
 drivers/raw/gdtc/gdtc_rawdev.c | 195 +++++++++++++++++++++++++++++++++
 drivers/raw/gdtc/gdtc_rawdev.h | 103 +++++++++++++++++
 drivers/raw/gdtc/meson.build   |   5 +
 drivers/raw/meson.build        |   1 +
 8 files changed, 346 insertions(+)
 create mode 100644 doc/guides/rawdevs/gdtc.rst
 create mode 100644 drivers/raw/gdtc/gdtc_rawdev.c
 create mode 100644 drivers/raw/gdtc/gdtc_rawdev.h
 create mode 100644 drivers/raw/gdtc/meson.build

diff --git a/.mailmap b/.mailmap
index 4dbb8cf8a7..95ee83c6bf 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1768,6 +1768,7 @@ Yu Wenjun <yuwenjun@cmss.chinamobile.com> <yuwenjun0x@163.com>
 Yuying Zhang <yuying.zhang@intel.com>
 Yu Zhang <zhangyu31@baidu.com>
 Yvonne Yang <yvonnex.yang@intel.com>
+Yong Zhang <zhang.yong25@zte.com.cn>
 Zalfresso-Jundzillo <marekx.zalfresso-jundzillo@intel.com>
 Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
 Zengmo Gao <gaozengmo@jd.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index f84ca3ea68..3c413f952b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1552,6 +1552,11 @@ M: Gagandeep Singh <g.singh@nxp.com>
 F: drivers/raw/dpaa2_cmdif/
 F: doc/guides/rawdevs/dpaa2_cmdif.rst
 
+ZTE GDTC
+M: Yong Zhang <zhang.yong25@zte.com.cn>
+F: drivers/raw/gdtc/
+F: doc/guides/rawdevs/gdtc.rst
+
 
 Packet processing
 -----------------
diff --git a/doc/guides/rawdevs/gdtc.rst b/doc/guides/rawdevs/gdtc.rst
new file mode 100644
index 0000000000..7e4e648c89
--- /dev/null
+++ b/doc/guides/rawdevs/gdtc.rst
@@ -0,0 +1,35 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright 2024 ZTE Corporation
+
+GDTC Rawdev Driver
+======================
+
+The ``gdtc`` rawdev driver is an implementation of the rawdev API,
+that provides communication between two separate hosts.
+This is achieved via using the GDMA controller of Dinghai SoC,
+which can be configured through exposed MPF device.
+
+Device Setup
+-------------
+
+Using the GDTC PMD driver does not require the MPF device to bind
+additional user-space IO driver.
+
+Before performing actual data transmission, it is necessary to
+call ``rte_rawdev_queue_setup()`` to obtain an available queue ID.
+
+For data transfer, utilize the standard ``rte_rawdev_enqueue_buffers()`` API.
+The data transfer status can be queried via ``rte_rawdev_dequeue_buffers()``,
+which will return the number of successfully transferred data items.
+
+Initialization
+--------------
+
+The ``gdtc`` rawdev driver needs to work in IOVA PA mode.
+Consider using ``--iova-mode=pa`` in the EAL options.
+
+Platform Requirement
+~~~~~~~~~~~~~~~~~~~~
+
+This PMD is only supported on ZTE Neo Platforms:
+- Neo X510/X512
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 8e07cf4d6c..2d8606d742 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -17,3 +17,4 @@ application through rawdev API.
     dpaa2_cmdif
     ifpga
     ntb
+    gdtc
diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
new file mode 100644
index 0000000000..6f20ecdad6
--- /dev/null
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 ZTE Corporation
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <bus_pci_driver.h>
+#include <rte_atomic.h>
+#include <rte_common.h>
+#include <rte_dev.h>
+#include <rte_eal_paging.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+#include <rte_spinlock.h>
+#include <rte_branch_prediction.h>
+
+#include "gdtc_rawdev.h"
+
+/* Register offset */
+#define ZXDH_GDMA_BASE_OFFSET                   0x100000
+
+#define ZXDH_GDMA_CHAN_SHIFT                    0x80
+char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
+char dev_name[] = "zxdh_gdma";
+
+static inline struct zxdh_gdma_rawdev *
+zxdh_gdma_rawdev_get_priv(const struct rte_rawdev *rawdev)
+{
+	return rawdev->dev_private;
+}
+
+static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
+};
+
+static int
+zxdh_gdma_map_resource(struct rte_pci_device *dev)
+{
+	int fd = -1;
+	char devname[PATH_MAX];
+	void *mapaddr = NULL;
+	struct rte_pci_addr *loc;
+
+	loc = &dev->addr;
+	snprintf(devname, sizeof(devname), "%s/" PCI_PRI_FMT "/resource0",
+		rte_pci_get_sysfs_path(),
+		loc->domain, loc->bus, loc->devid,
+		loc->function);
+
+		fd = open(devname, O_RDWR);
+		if (fd < 0) {
+			ZXDH_PMD_LOG(ERR, "Cannot open %s: %s", devname, strerror(errno));
+			return -1;
+		}
+
+	/* Map the PCI memory resource of device */
+	mapaddr = rte_mem_map(NULL, (size_t)dev->mem_resource[0].len,
+				RTE_PROT_READ | RTE_PROT_WRITE,
+				RTE_MAP_SHARED, fd, 0);
+	if (mapaddr == NULL) {
+		ZXDH_PMD_LOG(ERR, "cannot map resource(%d, 0x%zx): %s (%p)",
+				fd, (size_t)dev->mem_resource[0].len,
+				rte_strerror(rte_errno), mapaddr);
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+	dev->mem_resource[0].addr = mapaddr;
+
+	return 0;
+}
+
+static void
+zxdh_gdma_unmap_resource(void *requested_addr, size_t size)
+{
+	if (requested_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (rte_mem_unmap(requested_addr, size))
+		ZXDH_PMD_LOG(ERR, "cannot mem unmap(%p, %#zx): %s",
+			requested_addr, size, rte_strerror(rte_errno));
+	else
+		ZXDH_PMD_LOG(DEBUG, "PCI memory unmapped at %p", requested_addr);
+}
+
+static int
+zxdh_gdma_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+			struct rte_pci_device *pci_dev)
+{
+	struct rte_rawdev *dev = NULL;
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	uint8_t i = 0;
+	int ret;
+
+	if (pci_dev->mem_resource[0].phys_addr == 0) {
+		ZXDH_PMD_LOG(ERR, "PCI bar0 resource is invalid");
+		return -1;
+	}
+
+	ret = zxdh_gdma_map_resource(pci_dev);
+	if (ret != 0) {
+		ZXDH_PMD_LOG(ERR, "Failed to mmap pci device(%s)", pci_dev->name);
+		return -1;
+	}
+	ZXDH_PMD_LOG(INFO, "%s bar0 0x%"PRIx64" mapped at %p",
+				pci_dev->name, pci_dev->mem_resource[0].phys_addr,
+				pci_dev->mem_resource[0].addr);
+
+	dev = rte_rawdev_pmd_allocate(dev_name, sizeof(struct zxdh_gdma_rawdev), rte_socket_id());
+	if (dev == NULL) {
+		ZXDH_PMD_LOG(ERR, "Unable to allocate gdma rawdev");
+		goto err_out;
+	}
+	ZXDH_PMD_LOG(INFO, "Init %s on NUMA node %d, dev_id is %d",
+			dev_name, rte_socket_id(), dev->dev_id);
+
+	dev->dev_ops = &zxdh_gdma_rawdev_ops;
+	dev->device = &pci_dev->device;
+	dev->driver_name = zxdh_gdma_driver_name;
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
+	gdmadev->rawdev = dev;
+	gdmadev->queue_num = ZXDH_GDMA_TOTAL_CHAN_NUM;
+	gdmadev->used_num = 0;
+	gdmadev->base_addr = (uintptr_t)pci_dev->mem_resource[0].addr + ZXDH_GDMA_BASE_OFFSET;
+
+	for (i = 0; i < ZXDH_GDMA_TOTAL_CHAN_NUM; i++) {
+		queue = &(gdmadev->vqs[i]);
+		queue->enable = 0;
+		queue->queue_size = ZXDH_GDMA_QUEUE_SIZE;
+		rte_spinlock_init(&(queue->enqueue_lock));
+	}
+
+	return 0;
+
+err_out:
+	zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
+		(size_t)pci_dev->mem_resource[0].len);
+	return -1;
+}
+
+static int
+zxdh_gdma_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+	struct rte_rawdev *dev = NULL;
+	int ret = 0;
+
+	dev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (dev == NULL)
+		return -EINVAL;
+
+	/* rte_rawdev_close is called by pmd_release */
+	ret = rte_rawdev_pmd_release(dev);
+	if (ret != 0) {
+		ZXDH_PMD_LOG(ERR, "Device cleanup failed");
+		return -1;
+	}
+
+	zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
+		(size_t)pci_dev->mem_resource[0].len);
+
+	ZXDH_PMD_LOG(DEBUG, "rawdev %s remove done!", dev_name);
+
+	return ret;
+}
+
+static const struct rte_pci_id zxdh_gdma_rawdev_map[] = {
+	{ RTE_PCI_DEVICE(ZXDH_GDMA_VENDORID, ZXDH_GDMA_DEVICEID) },
+	{ .vendor_id = 0, /* sentinel */ },
+};
+
+static struct rte_pci_driver zxdh_gdma_rawdev_pmd = {
+	.id_table = zxdh_gdma_rawdev_map,
+	.drv_flags = 0,
+	.probe = zxdh_gdma_rawdev_probe,
+	.remove = zxdh_gdma_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(zxdh_gdma_rawdev_pci_driver, zxdh_gdma_rawdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(zxdh_gdma_rawdev_pci_driver, zxdh_gdma_rawdev_map);
+RTE_LOG_REGISTER_DEFAULT(zxdh_gdma_rawdev_logtype, NOTICE);
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
new file mode 100644
index 0000000000..9f943c49c6
--- /dev/null
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2024 ZTE Corporation
+ */
+
+#ifndef __GDTC_RAWDEV_H__
+#define __GDTC_RAWDEV_H__
+
+#include <stdint.h>
+#include <rte_log.h>
+#include <rte_common.h>
+#include <generic/rte_spinlock.h>
+
+extern int zxdh_gdma_rawdev_logtype;
+#define RTE_LOGTYPE_ZXDH_GDMA                   zxdh_gdma_rawdev_logtype
+
+#define ZXDH_PMD_LOG(level, ...) \
+	RTE_LOG_LINE_PREFIX(level, ZXDH_GDMA, \
+		"%s() line %u: ", __func__ RTE_LOG_COMMA __LINE__, __VA_ARGS__)
+
+#define ZXDH_GDMA_VENDORID                      0x1cf2
+#define ZXDH_GDMA_DEVICEID                      0x8044
+
+#define ZXDH_GDMA_TOTAL_CHAN_NUM                58
+#define ZXDH_GDMA_QUEUE_SIZE                    16384
+#define ZXDH_GDMA_RING_SIZE                     32768
+
+enum zxdh_gdma_device_state {
+	ZXDH_GDMA_DEV_RUNNING,
+	ZXDH_GDMA_DEV_STOPPED
+};
+
+struct zxdh_gdma_buff_desc {
+	uint32_t SrcAddr_L;
+	uint32_t DstAddr_L;
+	uint32_t Xpara;
+	uint32_t ZY_para;
+	uint32_t ZY_SrcStep;
+	uint32_t ZY_DstStep;
+	uint32_t ExtAddr;
+	uint32_t LLI_Addr_L;
+	uint32_t LLI_Addr_H;
+	uint32_t ChCont;
+	uint32_t LLI_User;
+	uint32_t ErrAddr;
+	uint32_t Control;
+	uint32_t SrcAddr_H;
+	uint32_t DstAddr_H;
+	uint32_t Reserved;
+};
+
+struct zxdh_gdma_job {
+	uint64_t src;
+	uint64_t dest;
+	uint32_t len;
+	uint32_t flags;
+	uint64_t cnxt;
+	uint16_t status;
+	uint16_t vq_id;
+	void *usr_elem;
+	uint8_t ep_id;
+	uint8_t pf_id;
+	uint16_t vf_id;
+};
+
+struct zxdh_gdma_queue {
+	uint8_t   enable;
+	uint8_t   is_txq;
+	uint16_t  vq_id;
+	uint16_t  queue_size;
+	/* 0:GDMA needs to be configured through the APB interface */
+	uint16_t  flag;
+	uint32_t  user;
+	uint16_t  tc_cnt;
+	rte_spinlock_t enqueue_lock;
+	struct {
+		uint16_t avail_idx;
+		uint16_t last_avail_idx;
+		rte_iova_t ring_mem;
+		const struct rte_memzone *ring_mz;
+		struct zxdh_gdma_buff_desc *desc;
+	} ring;
+	struct {
+		uint16_t  free_cnt;
+		uint16_t  deq_cnt;
+		uint16_t  pend_cnt;
+		uint16_t  enq_idx;
+		uint16_t  deq_idx;
+		uint16_t  used_idx;
+		struct zxdh_gdma_job **job;
+	} sw_ring;
+};
+
+struct zxdh_gdma_rawdev {
+	struct rte_device *device;
+	struct rte_rawdev *rawdev;
+	uintptr_t base_addr;
+	uint8_t queue_num; /* total queue num */
+	uint8_t used_num;  /* used  queue num */
+	enum zxdh_gdma_device_state device_state;
+	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
+};
+
+#endif /* __GDTC_RAWDEV_H__ */
diff --git a/drivers/raw/gdtc/meson.build b/drivers/raw/gdtc/meson.build
new file mode 100644
index 0000000000..3e748ca58d
--- /dev/null
+++ b/drivers/raw/gdtc/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2024 ZTE Corporation
+
+deps += ['rawdev', 'kvargs', 'mbuf', 'bus_pci']
+sources = files('gdtc_rawdev.c')
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 54221643d5..9cc2cba9e1 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -13,5 +13,6 @@ drivers = [
         'ifpga',
         'ntb',
         'skeleton',
+        'gdtc',
 ]
 std_deps = ['rawdev']
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 25739 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v5,2/5] raw/gdtc: add support for queue setup operation
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
@ 2024-11-14  9:20   ` Yong Zhang
  2024-11-20  0:46     ` Thomas Monjalon
  2024-11-14  9:20   ` [v5,3/5] raw/gdtc: add support for standard rawdev operations Yong Zhang
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 25+ messages in thread
From: Yong Zhang @ 2024-11-14  9:20 UTC (permalink / raw)
  To: thomas, stephen, dev; +Cc: zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 9685 bytes --]

Add queue initialization and release interface.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 244 +++++++++++++++++++++++++++++++++
 drivers/raw/gdtc/gdtc_rawdev.h |  19 +++
 2 files changed, 263 insertions(+)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index 6f20ecdad6..c3e59fcdab 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -28,10 +28,42 @@
 
 #include "gdtc_rawdev.h"
 
+/*
+ * User define:
+ * ep_id-bit[15:12] vfunc_num-bit[11:4] func_num-bit[3:1] vfunc_active-bit0
+ * host ep_id:5~8   zf ep_id:9
+ */
+#define ZXDH_GDMA_ZF_USER                       0x9000      /* ep4 pf0 */
+#define ZXDH_GDMA_PF_NUM_SHIFT                  1
+#define ZXDH_GDMA_VF_NUM_SHIFT                  4
+#define ZXDH_GDMA_EP_ID_SHIFT                   12
+#define ZXDH_GDMA_VF_EN                         1
+#define ZXDH_GDMA_EPID_OFFSET                   5
+
 /* Register offset */
 #define ZXDH_GDMA_BASE_OFFSET                   0x100000
+#define ZXDH_GDMA_EXT_ADDR_OFFSET               0x218
+#define ZXDH_GDMA_CONTROL_OFFSET                0x230
+#define ZXDH_GDMA_TC_CNT_OFFSET                 0x23c
+#define ZXDH_GDMA_LLI_USER_OFFSET               0x228
+
+#define ZXDH_GDMA_CHAN_FORCE_CLOSE              (1 << 31)
+
+/* TC count & Error interrupt status register */
+#define ZXDH_GDMA_SRC_LLI_ERR                   (1 << 16)
+#define ZXDH_GDMA_SRC_DATA_ERR                  (1 << 17)
+#define ZXDH_GDMA_DST_ADDR_ERR                  (1 << 18)
+#define ZXDH_GDMA_ERR_STATUS                    (1 << 19)
+#define ZXDH_GDMA_ERR_INTR_ENABLE               (1 << 20)
+#define ZXDH_GDMA_TC_CNT_CLEAN                  (1)
 
 #define ZXDH_GDMA_CHAN_SHIFT                    0x80
+#define LOW32_MASK                              0xffffffff
+#define LOW16_MASK                              0xffff
+
+static int zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id);
+static int zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id);
+
 char zxdh_gdma_driver_name[] = "rawdev_zxdh_gdma";
 char dev_name[] = "zxdh_gdma";
 
@@ -41,9 +73,221 @@ zxdh_gdma_rawdev_get_priv(const struct rte_rawdev *rawdev)
 	return rawdev->dev_private;
 }
 
+static inline struct zxdh_gdma_queue *
+zxdh_gdma_get_queue(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+
+	if (queue_id >= ZXDH_GDMA_TOTAL_CHAN_NUM) {
+		ZXDH_PMD_LOG(ERR, "queue id %d is invalid", queue_id);
+		return NULL;
+	}
+
+	return &(gdmadev->vqs[queue_id]);
+}
+
+static void
+zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)
+{
+	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	uint32_t addr = 0;
+
+	addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
+	*(uint32_t *)(gdmadev->base_addr + addr) = val;
+}
+
+static int
+zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
+				uint16_t queue_id,
+				rte_rawdev_obj_t queue_conf,
+				size_t conf_size)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	struct zxdh_gdma_queue_config *qconfig = NULL;
+	struct zxdh_gdma_rbp *rbp = NULL;
+	uint16_t i = 0;
+	uint8_t is_txq = 0;
+	uint32_t src_user = 0;
+	uint32_t dst_user = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	if ((queue_conf == NULL) || (conf_size != sizeof(struct zxdh_gdma_queue_config)))
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	qconfig = (struct zxdh_gdma_queue_config *)queue_conf;
+
+	for (i = 0; i < ZXDH_GDMA_TOTAL_CHAN_NUM; i++) {
+		if (gdmadev->vqs[i].enable == 0)
+			break;
+	}
+	if (i >= ZXDH_GDMA_TOTAL_CHAN_NUM) {
+		ZXDH_PMD_LOG(ERR, "Failed to setup queue, no avail queues");
+		return -1;
+	}
+	queue_id = i;
+	if (zxdh_gdma_queue_init(dev, queue_id) != 0) {
+		ZXDH_PMD_LOG(ERR, "Failed to init queue");
+		return -1;
+	}
+	queue = &(gdmadev->vqs[queue_id]);
+
+	rbp = qconfig->rbp;
+	if ((rbp->srbp != 0) && (rbp->drbp == 0)) {
+		is_txq = 0;
+		dst_user = ZXDH_GDMA_ZF_USER;
+		src_user = ((rbp->spfid << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((rbp->sportid + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (rbp->svfid != 0)
+			src_user |= (ZXDH_GDMA_VF_EN |
+						 ((rbp->svfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+
+		ZXDH_PMD_LOG(DEBUG, "rxq->qidx:%d setup src_user(ep:%d pf:%d vf:%d) success",
+					queue_id, (uint8_t)rbp->sportid, (uint8_t)rbp->spfid,
+					(uint8_t)rbp->svfid);
+	} else if ((rbp->srbp == 0) && (rbp->drbp != 0)) {
+		is_txq = 1;
+		src_user = ZXDH_GDMA_ZF_USER;
+		dst_user = ((rbp->dpfid << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((rbp->dportid + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (rbp->dvfid != 0)
+			dst_user |= (ZXDH_GDMA_VF_EN |
+						 ((rbp->dvfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+
+		ZXDH_PMD_LOG(DEBUG, "txq->qidx:%d setup dst_user(ep:%d pf:%d vf:%d) success",
+					queue_id, (uint8_t)rbp->dportid, (uint8_t)rbp->dpfid,
+					(uint8_t)rbp->dvfid);
+	} else {
+		ZXDH_PMD_LOG(ERR, "Failed to setup queue, srbp/drbp is invalid");
+		return -EINVAL;
+	}
+	queue->is_txq = is_txq;
+
+	/* setup queue user info */
+	queue->user = (src_user & LOW16_MASK) | (dst_user << 16);
+
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_EXT_ADDR_OFFSET, queue->user);
+	gdmadev->used_num++;
+
+	return queue_id;
+}
+
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
+	.queue_setup = zxdh_gdma_rawdev_queue_setup,
 };
 
+static int
+zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	char name[RTE_MEMZONE_NAMESIZE];
+	struct zxdh_gdma_queue *queue = NULL;
+	const struct rte_memzone *mz = NULL;
+	uint32_t size = 0;
+	int ret = 0;
+
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if (queue == NULL)
+		return -EINVAL;
+
+	queue->enable = 1;
+	queue->vq_id  = queue_id;
+	queue->flag   = 0;
+	queue->tc_cnt = 0;
+
+	/* Init sw_ring */
+	queue->sw_ring.job = rte_calloc(NULL, queue->queue_size, sizeof(struct zxdh_gdma_job *), 0);
+	if (queue->sw_ring.job == NULL) {
+		ZXDH_PMD_LOG(ERR, "can not allocate sw_ring");
+		ret = -ENOMEM;
+		goto free_queue;
+	}
+
+	/* Cache up to size-1 job in the ring to prevent overwriting hardware prefetching */
+	queue->sw_ring.free_cnt = queue->queue_size - 1;
+	queue->sw_ring.deq_cnt  = 0;
+	queue->sw_ring.pend_cnt = 0;
+	queue->sw_ring.enq_idx  = 0;
+	queue->sw_ring.deq_idx  = 0;
+	queue->sw_ring.used_idx = 0;
+
+	/* Init ring */
+	snprintf(name, RTE_MEMZONE_NAMESIZE, "gdma_vq%d_ring", queue_id);
+	size = ZXDH_GDMA_RING_SIZE * sizeof(struct zxdh_gdma_buff_desc);
+	mz = rte_memzone_reserve_aligned(name, size, rte_socket_id(),
+							RTE_MEMZONE_IOVA_CONTIG, size);
+	if (mz == NULL) {
+		if (rte_errno == EEXIST)
+			mz = rte_memzone_lookup(name);
+		if (mz == NULL) {
+			ZXDH_PMD_LOG(ERR, "can not allocate ring %s", name);
+			ret = -ENOMEM;
+			goto free_queue;
+		}
+	}
+	memset(mz->addr, 0, size);
+	queue->ring.ring_mz   = mz;
+	queue->ring.desc      = (struct zxdh_gdma_buff_desc *)(mz->addr);
+	queue->ring.ring_mem  = mz->iova;
+	queue->ring.avail_idx = 0;
+	ZXDH_PMD_LOG(INFO, "queue%u ring phy addr:0x%"PRIx64" virt addr:%p",
+						queue_id, mz->iova, mz->addr);
+
+	/* Initialize the hardware channel */
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET,
+		ZXDH_GDMA_CHAN_FORCE_CLOSE);
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET,
+		ZXDH_GDMA_ERR_INTR_ENABLE | ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_TC_CNT_CLEAN);
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_USER_OFFSET,
+		ZXDH_GDMA_ZF_USER);
+
+	return 0;
+
+free_queue:
+	zxdh_gdma_queue_free(dev, queue_id);
+	return ret;
+}
+
+static int
+zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	uint32_t val = 0;
+
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if (queue == NULL)
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->used_num--;
+
+	/* disable gdma channel */
+	val = ZXDH_GDMA_CHAN_FORCE_CLOSE;
+	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
+
+	queue->enable           = 0;
+	queue->is_txq           = 0;
+	queue->flag             = 0;
+	queue->user             = 0;
+	queue->tc_cnt           = 0;
+	queue->ring.avail_idx   = 0;
+	queue->sw_ring.free_cnt = 0;
+	queue->sw_ring.deq_cnt  = 0;
+	queue->sw_ring.pend_cnt = 0;
+	queue->sw_ring.enq_idx  = 0;
+	queue->sw_ring.deq_idx  = 0;
+	queue->sw_ring.used_idx = 0;
+	rte_free(queue->sw_ring.job);
+	rte_memzone_free(queue->ring.ring_mz);
+
+	return 0;
+}
+
 static int
 zxdh_gdma_map_resource(struct rte_pci_device *dev)
 {
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
index 9f943c49c6..29b169d079 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.h
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -100,4 +100,23 @@ struct zxdh_gdma_rawdev {
 	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
 };
 
+struct zxdh_gdma_rbp {
+	uint32_t use_ultrashort:1;
+	uint32_t enable:1;
+	uint32_t dportid:3;
+	uint32_t dpfid:3;
+	uint32_t dvfid:8; /*using route by port for destination */
+	uint32_t drbp:1;
+	uint32_t sportid:3;
+	uint32_t spfid:3;
+	uint32_t svfid:8;
+	uint32_t srbp:1;
+};
+
+struct zxdh_gdma_queue_config {
+	uint32_t lcore_id;
+	uint32_t flags;
+	struct zxdh_gdma_rbp *rbp;
+};
+
 #endif /* __GDTC_RAWDEV_H__ */
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 23378 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v5,3/5] raw/gdtc: add support for standard rawdev operations
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
  2024-11-14  9:20   ` [v5,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
@ 2024-11-14  9:20   ` Yong Zhang
  2024-11-14  9:20   ` [v5,4/5] raw/gdtc: add support for enqueue operation Yong Zhang
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 25+ messages in thread
From: Yong Zhang @ 2024-11-14  9:20 UTC (permalink / raw)
  To: thomas, stephen, dev; +Cc: zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 5302 bytes --]

Add support for rawdev operations such as dev_start and dev_stop.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 136 ++++++++++++++++++++++++++++++++-
 drivers/raw/gdtc/gdtc_rawdev.h |  10 +++
 2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index c3e59fcdab..8512bd8413 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -96,6 +96,96 @@ zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset,
 	*(uint32_t *)(gdmadev->base_addr + addr) = val;
 }
 
+static int
+zxdh_gdma_rawdev_info_get(struct rte_rawdev *dev,
+				__rte_unused rte_rawdev_obj_t dev_info,
+				__rte_unused size_t dev_info_size)
+{
+	if (dev == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_configure(const struct rte_rawdev *dev,
+				rte_rawdev_obj_t config,
+				size_t config_size)
+{
+	struct zxdh_gdma_config *gdma_config = NULL;
+
+	if ((dev == NULL) ||
+		(config == NULL) ||
+		(config_size != sizeof(struct zxdh_gdma_config)))
+		return -EINVAL;
+
+	gdma_config = (struct zxdh_gdma_config *)config;
+	if (gdma_config->max_vqs > ZXDH_GDMA_TOTAL_CHAN_NUM) {
+		ZXDH_PMD_LOG(ERR, "gdma supports up to %d queues", ZXDH_GDMA_TOTAL_CHAN_NUM);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_start(struct rte_rawdev *dev)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_RUNNING;
+
+	return 0;
+}
+
+static void
+zxdh_gdma_rawdev_stop(struct rte_rawdev *dev)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+
+	if (dev == NULL)
+		return;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
+}
+
+static int
+zxdh_gdma_rawdev_reset(struct rte_rawdev *dev)
+{
+	if (dev == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_close(struct rte_rawdev *dev)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	uint16_t queue_id = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	for (queue_id = 0; queue_id < ZXDH_GDMA_TOTAL_CHAN_NUM; queue_id++) {
+		queue = zxdh_gdma_get_queue(dev, queue_id);
+		if ((queue == NULL) || (queue->enable == 0))
+			continue;
+
+		zxdh_gdma_queue_free(dev, queue_id);
+	}
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	gdmadev->device_state = ZXDH_GDMA_DEV_STOPPED;
+
+	return 0;
+}
+
 static int
 zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
 				uint16_t queue_id,
@@ -177,8 +267,52 @@ zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
 	return queue_id;
 }
 
+static int
+zxdh_gdma_rawdev_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
+{
+	struct zxdh_gdma_queue *queue = NULL;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if ((queue == NULL) || (queue->enable == 0))
+		return -EINVAL;
+
+	zxdh_gdma_queue_free(dev, queue_id);
+
+	return 0;
+}
+
+static int
+zxdh_gdma_rawdev_get_attr(struct rte_rawdev *dev,
+				__rte_unused const char *attr_name,
+				uint64_t *attr_value)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_attr *gdma_attr = NULL;
+
+	if ((dev == NULL) || (attr_value == NULL))
+		return -EINVAL;
+
+	gdmadev   = zxdh_gdma_rawdev_get_priv(dev);
+	gdma_attr = (struct zxdh_gdma_attr *)attr_value;
+	gdma_attr->num_hw_queues = gdmadev->used_num;
+
+	return 0;
+}
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
+	.dev_info_get = zxdh_gdma_rawdev_info_get,
+	.dev_configure = zxdh_gdma_rawdev_configure,
+	.dev_start = zxdh_gdma_rawdev_start,
+	.dev_stop = zxdh_gdma_rawdev_stop,
+	.dev_close = zxdh_gdma_rawdev_close,
+	.dev_reset = zxdh_gdma_rawdev_reset,
+
 	.queue_setup = zxdh_gdma_rawdev_queue_setup,
+	.queue_release = zxdh_gdma_rawdev_queue_release,
+
+	.attr_get = zxdh_gdma_rawdev_get_attr,
 };
 
 static int
@@ -237,7 +371,7 @@ zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
 	ZXDH_PMD_LOG(INFO, "queue%u ring phy addr:0x%"PRIx64" virt addr:%p",
 						queue_id, mz->iova, mz->addr);
 
-	/* Initialize the hardware channel */
+	/* Configure the hardware channel to the initial state */
 	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET,
 		ZXDH_GDMA_CHAN_FORCE_CLOSE);
 	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET,
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
index 29b169d079..92b35fcf14 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.h
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -100,6 +100,12 @@ struct zxdh_gdma_rawdev {
 	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
 };
 
+struct zxdh_gdma_config {
+	uint16_t max_hw_queues_per_core;
+	uint16_t max_vqs;
+	int queue_pool_cnt;
+};
+
 struct zxdh_gdma_rbp {
 	uint32_t use_ultrashort:1;
 	uint32_t enable:1;
@@ -119,4 +125,8 @@ struct zxdh_gdma_queue_config {
 	struct zxdh_gdma_rbp *rbp;
 };
 
+struct zxdh_gdma_attr {
+	uint16_t num_hw_queues;
+};
+
 #endif /* __GDTC_RAWDEV_H__ */
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 11208 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v5,4/5] raw/gdtc: add support for enqueue operation
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
  2024-11-14  9:20   ` [v5,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
  2024-11-14  9:20   ` [v5,3/5] raw/gdtc: add support for standard rawdev operations Yong Zhang
@ 2024-11-14  9:20   ` Yong Zhang
  2024-11-14  9:20   ` [v5,5/5] raw/gdtc: add support for dequeue operation Yong Zhang
  2024-11-20  0:45   ` [v5,1/5] raw/gdtc: introduce gdtc raw device driver Thomas Monjalon
  4 siblings, 0 replies; 25+ messages in thread
From: Yong Zhang @ 2024-11-14  9:20 UTC (permalink / raw)
  To: thomas, stephen, dev; +Cc: zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 10988 bytes --]

Add rawdev enqueue operation for gdtc devices.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 220 +++++++++++++++++++++++++++++++++
 drivers/raw/gdtc/gdtc_rawdev.h |  19 +++
 2 files changed, 239 insertions(+)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index 8512bd8413..f58b034e58 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -43,10 +43,34 @@
 /* Register offset */
 #define ZXDH_GDMA_BASE_OFFSET                   0x100000
 #define ZXDH_GDMA_EXT_ADDR_OFFSET               0x218
+#define ZXDH_GDMA_SAR_LOW_OFFSET                0x200
+#define ZXDH_GDMA_DAR_LOW_OFFSET                0x204
+#define ZXDH_GDMA_SAR_HIGH_OFFSET               0x234
+#define ZXDH_GDMA_DAR_HIGH_OFFSET               0x238
+#define ZXDH_GDMA_XFERSIZE_OFFSET               0x208
 #define ZXDH_GDMA_CONTROL_OFFSET                0x230
+#define ZXDH_GDMA_TC_STATUS_OFFSET              0x0
+#define ZXDH_GDMA_STATUS_CLEAN_OFFSET           0x80
+#define ZXDH_GDMA_LLI_L_OFFSET                  0x21c
+#define ZXDH_GDMA_LLI_H_OFFSET                  0x220
+#define ZXDH_GDMA_CHAN_CONTINUE_OFFSET          0x224
 #define ZXDH_GDMA_TC_CNT_OFFSET                 0x23c
 #define ZXDH_GDMA_LLI_USER_OFFSET               0x228
 
+/* Control register */
+#define ZXDH_GDMA_CHAN_ENABLE                   0x1
+#define ZXDH_GDMA_CHAN_DISABLE                  0
+#define ZXDH_GDMA_SOFT_CHAN                     0x2
+#define ZXDH_GDMA_TC_INTR_ENABLE                0x10
+#define ZXDH_GDMA_ALL_INTR_ENABLE               0x30
+#define ZXDH_GDMA_SBS_SHIFT                     6           /* src burst size */
+#define ZXDH_GDMA_SBL_SHIFT                     9           /* src burst length */
+#define ZXDH_GDMA_DBS_SHIFT                     13          /* dest burst size */
+#define ZXDH_GDMA_BURST_SIZE_MIN                0x1         /* 1 byte */
+#define ZXDH_GDMA_BURST_SIZE_MEDIUM             0x4         /* 4 word */
+#define ZXDH_GDMA_BURST_SIZE_MAX                0x6         /* 16 word */
+#define ZXDH_GDMA_DEFAULT_BURST_LEN             0xf         /* 16 beats */
+#define ZXDH_GDMA_TC_CNT_ENABLE                 (1 << 27)
 #define ZXDH_GDMA_CHAN_FORCE_CLOSE              (1 << 31)
 
 /* TC count & Error interrupt status register */
@@ -58,9 +82,15 @@
 #define ZXDH_GDMA_TC_CNT_CLEAN                  (1)
 
 #define ZXDH_GDMA_CHAN_SHIFT                    0x80
+#define ZXDH_GDMA_LINK_END_NODE                 (1 << 30)
+#define ZXDH_GDMA_CHAN_CONTINUE                 (1)
+
 #define LOW32_MASK                              0xffffffff
 #define LOW16_MASK                              0xffff
 
+#define IDX_TO_ADDR(addr, idx, t) \
+	((t)((uintptr_t)(addr) + (idx) * sizeof(struct zxdh_gdma_buff_desc)))
+
 static int zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id);
 static int zxdh_gdma_queue_free(struct rte_rawdev *dev, uint16_t queue_id);
 
@@ -301,6 +331,194 @@ zxdh_gdma_rawdev_get_attr(struct rte_rawdev *dev,
 
 	return 0;
 }
+
+static inline void
+zxdh_gdma_control_cal(uint32_t *val, uint8_t tc_enable)
+{
+	*val = (ZXDH_GDMA_CHAN_ENABLE |
+			ZXDH_GDMA_SOFT_CHAN |
+			(ZXDH_GDMA_DEFAULT_BURST_LEN << ZXDH_GDMA_SBL_SHIFT) |
+			(ZXDH_GDMA_BURST_SIZE_MAX << ZXDH_GDMA_SBS_SHIFT) |
+			(ZXDH_GDMA_BURST_SIZE_MAX << ZXDH_GDMA_DBS_SHIFT));
+
+	if (tc_enable != 0)
+		*val |= ZXDH_GDMA_TC_CNT_ENABLE;
+}
+
+static inline uint32_t
+zxdh_gdma_user_get(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
+{
+	uint32_t src_user = 0;
+	uint32_t dst_user = 0;
+
+	if ((job->flags & ZXDH_GDMA_JOB_DIR_MASK) == 0) {
+		ZXDH_PMD_LOG(DEBUG, "job flags:0x%x default user:0x%x",
+							job->flags, queue->user);
+		return queue->user;
+	} else if ((job->flags & ZXDH_GDMA_JOB_DIR_TX) != 0) {
+		src_user = ZXDH_GDMA_ZF_USER;
+		dst_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((job->ep_id + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (job->vf_id != 0)
+			dst_user |= (ZXDH_GDMA_VF_EN |
+						 ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+	} else {
+		dst_user = ZXDH_GDMA_ZF_USER;
+		src_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
+			((job->ep_id + ZXDH_GDMA_EPID_OFFSET) << ZXDH_GDMA_EP_ID_SHIFT));
+
+		if (job->vf_id != 0)
+			src_user |= (ZXDH_GDMA_VF_EN |
+						 ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+	}
+	ZXDH_PMD_LOG(DEBUG, "job flags:0x%x ep_id:%u, pf_id:%u, vf_id:%u, user:0x%x",
+						job->flags, job->ep_id, job->pf_id, job->vf_id,
+						(src_user & LOW16_MASK) | (dst_user << 16));
+
+	return (src_user & LOW16_MASK) | (dst_user << 16);
+}
+
+static inline void
+zxdh_gdma_fill_bd(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
+{
+	struct zxdh_gdma_buff_desc *bd = NULL;
+	uint32_t val = 0;
+	uint64_t next_bd_addr = 0;
+	uint16_t avail_idx = 0;
+
+	avail_idx = queue->ring.avail_idx;
+	bd = &(queue->ring.desc[avail_idx]);
+	memset(bd, 0, sizeof(struct zxdh_gdma_buff_desc));
+
+	/* data bd */
+	if (job != NULL) {
+		zxdh_gdma_control_cal(&val, 1);
+		next_bd_addr   = IDX_TO_ADDR(queue->ring.ring_mem,
+							(avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
+							uint64_t);
+		bd->SrcAddr_L  = job->src & LOW32_MASK;
+		bd->DstAddr_L  = job->dest & LOW32_MASK;
+		bd->SrcAddr_H  = (job->src >> 32) & LOW32_MASK;
+		bd->DstAddr_H  = (job->dest >> 32) & LOW32_MASK;
+		bd->Xpara      = job->len;
+		bd->ExtAddr    = zxdh_gdma_user_get(queue, job);
+		bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
+		bd->LLI_Addr_H = next_bd_addr >> 38;
+		bd->LLI_User   = ZXDH_GDMA_ZF_USER;
+		bd->Control    = val;
+	} else {
+		zxdh_gdma_control_cal(&val, 0);
+		next_bd_addr   = IDX_TO_ADDR(queue->ring.ring_mem, avail_idx, uint64_t);
+		bd->ExtAddr    = queue->user;
+		bd->LLI_User   = ZXDH_GDMA_ZF_USER;
+		bd->Control    = val;
+		bd->LLI_Addr_L = (next_bd_addr >> 6) & LOW32_MASK;
+		bd->LLI_Addr_H = (next_bd_addr >> 38) | ZXDH_GDMA_LINK_END_NODE;
+		if (queue->flag != 0) {
+			bd = IDX_TO_ADDR(queue->ring.desc,
+					queue->ring.last_avail_idx,
+					struct zxdh_gdma_buff_desc*);
+			next_bd_addr = IDX_TO_ADDR(queue->ring.ring_mem,
+					(queue->ring.last_avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
+					uint64_t);
+			bd->LLI_Addr_L  = (next_bd_addr >> 6) & LOW32_MASK;
+			bd->LLI_Addr_H  = next_bd_addr >> 38;
+			rte_wmb();
+			bd->LLI_Addr_H &= ~ZXDH_GDMA_LINK_END_NODE;
+		}
+		/* Record the index of empty bd for dynamic chaining */
+		queue->ring.last_avail_idx = avail_idx;
+	}
+
+	if (++avail_idx >= ZXDH_GDMA_RING_SIZE)
+		avail_idx -= ZXDH_GDMA_RING_SIZE;
+
+	queue->ring.avail_idx = avail_idx;
+}
+
+static int
+zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *dev,
+				__rte_unused struct rte_rawdev_buf **buffers,
+				uint32_t count,
+				rte_rawdev_obj_t context)
+{
+	struct zxdh_gdma_rawdev *gdmadev = NULL;
+	struct zxdh_gdma_queue *queue = NULL;
+	struct zxdh_gdma_enqdeq *e_context = NULL;
+	struct zxdh_gdma_job *job = NULL;
+	uint16_t queue_id = 0;
+	uint32_t val = 0;
+	uint16_t i = 0;
+	uint16_t free_cnt = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+
+	if (unlikely((count < 1) || (context == NULL)))
+		return -EINVAL;
+
+	gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	if (gdmadev->device_state == ZXDH_GDMA_DEV_STOPPED) {
+		ZXDH_PMD_LOG(ERR, "gdma dev is stop");
+		return 0;
+	}
+
+	e_context = (struct zxdh_gdma_enqdeq *)context;
+	queue_id = e_context->vq_id;
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if ((queue == NULL) || (queue->enable == 0))
+		return -EINVAL;
+
+	free_cnt = queue->sw_ring.free_cnt;
+	if (free_cnt == 0) {
+		ZXDH_PMD_LOG(ERR, "queue %u is full, enq_idx:%u deq_idx:%u used_idx:%u",
+						   queue_id, queue->sw_ring.enq_idx,
+						   queue->sw_ring.deq_idx, queue->sw_ring.used_idx);
+		return 0;
+	} else if (free_cnt < count) {
+		ZXDH_PMD_LOG(DEBUG, "job num %u > free_cnt, change to %u", count, free_cnt);
+		count = free_cnt;
+	}
+
+	rte_spinlock_lock(&queue->enqueue_lock);
+
+	/* Build bd list, the last bd is empty bd */
+	for (i = 0; i < count; i++) {
+		job = e_context->job[i];
+		zxdh_gdma_fill_bd(queue, job);
+	}
+	zxdh_gdma_fill_bd(queue, NULL);
+
+	if (unlikely(queue->flag == 0)) {
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_L_OFFSET,
+							(queue->ring.ring_mem >> 6) & LOW32_MASK);
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_LLI_H_OFFSET,
+							 queue->ring.ring_mem >> 38);
+		/* Start hardware handling */
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0);
+		zxdh_gdma_control_cal(&val, 0);
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
+		queue->flag = 1;
+	} else {
+		val = ZXDH_GDMA_CHAN_CONTINUE;
+		zxdh_gdma_write_reg(dev, queue->vq_id, ZXDH_GDMA_CHAN_CONTINUE_OFFSET, val);
+	}
+
+    /* job enqueue */
+	for (i = 0; i < count; i++) {
+		queue->sw_ring.job[queue->sw_ring.enq_idx] = e_context->job[i];
+		if (++queue->sw_ring.enq_idx >= queue->queue_size)
+			queue->sw_ring.enq_idx -= queue->queue_size;
+
+		free_cnt--;
+	}
+	queue->sw_ring.free_cnt = free_cnt;
+	queue->sw_ring.pend_cnt += count;
+	rte_spinlock_unlock(&queue->enqueue_lock);
+
+	return count;
+}
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.dev_info_get = zxdh_gdma_rawdev_info_get,
 	.dev_configure = zxdh_gdma_rawdev_configure,
@@ -313,6 +531,8 @@ static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.queue_release = zxdh_gdma_rawdev_queue_release,
 
 	.attr_get = zxdh_gdma_rawdev_get_attr,
+
+	.enqueue_bufs = zxdh_gdma_rawdev_enqueue_bufs,
 };
 
 static int
diff --git a/drivers/raw/gdtc/gdtc_rawdev.h b/drivers/raw/gdtc/gdtc_rawdev.h
index 92b35fcf14..12ce8a04c7 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.h
+++ b/drivers/raw/gdtc/gdtc_rawdev.h
@@ -24,6 +24,20 @@ extern int zxdh_gdma_rawdev_logtype;
 #define ZXDH_GDMA_QUEUE_SIZE                    16384
 #define ZXDH_GDMA_RING_SIZE                     32768
 
+/* States if the source addresses is physical. */
+#define ZXDH_GDMA_JOB_SRC_PHY                   (1UL)
+
+/* States if the destination addresses is physical. */
+#define ZXDH_GDMA_JOB_DEST_PHY                  (1UL << 1)
+
+/* ZF->HOST */
+#define ZXDH_GDMA_JOB_DIR_TX                    (1UL << 2)
+
+/* HOST->ZF */
+#define ZXDH_GDMA_JOB_DIR_RX                    (1UL << 3)
+
+#define ZXDH_GDMA_JOB_DIR_MASK                  (ZXDH_GDMA_JOB_DIR_TX | ZXDH_GDMA_JOB_DIR_RX)
+
 enum zxdh_gdma_device_state {
 	ZXDH_GDMA_DEV_RUNNING,
 	ZXDH_GDMA_DEV_STOPPED
@@ -100,6 +114,11 @@ struct zxdh_gdma_rawdev {
 	struct zxdh_gdma_queue vqs[ZXDH_GDMA_TOTAL_CHAN_NUM];
 };
 
+struct zxdh_gdma_enqdeq {
+	uint16_t vq_id;
+	struct zxdh_gdma_job **job;
+};
+
 struct zxdh_gdma_config {
 	uint16_t max_hw_queues_per_core;
 	uint16_t max_vqs;
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 28372 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [v5,5/5] raw/gdtc: add support for dequeue operation
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
                     ` (2 preceding siblings ...)
  2024-11-14  9:20   ` [v5,4/5] raw/gdtc: add support for enqueue operation Yong Zhang
@ 2024-11-14  9:20   ` Yong Zhang
  2024-11-20  0:45   ` [v5,1/5] raw/gdtc: introduce gdtc raw device driver Thomas Monjalon
  4 siblings, 0 replies; 25+ messages in thread
From: Yong Zhang @ 2024-11-14  9:20 UTC (permalink / raw)
  To: thomas, stephen, dev; +Cc: zhang.yong25, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 11029 bytes --]

Add rawdev dequeue operation for gdtc devices.

Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>
---
 drivers/raw/gdtc/gdtc_rawdev.c | 168 ++++++++++++++++++++++++++++-----
 1 file changed, 147 insertions(+), 21 deletions(-)

diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawdev.c
index f58b034e58..bc94bad827 100644
--- a/drivers/raw/gdtc/gdtc_rawdev.c
+++ b/drivers/raw/gdtc/gdtc_rawdev.c
@@ -88,6 +88,8 @@
 #define LOW32_MASK                              0xffffffff
 #define LOW16_MASK                              0xffff
 
+#define ZXDH_GDMA_TC_CNT_MAX                    0x10000
+
 #define IDX_TO_ADDR(addr, idx, t) \
 	((t)((uintptr_t)(addr) + (idx) * sizeof(struct zxdh_gdma_buff_desc)))
 
@@ -116,6 +118,19 @@ zxdh_gdma_get_queue(struct rte_rawdev *dev, uint16_t queue_id)
 	return &(gdmadev->vqs[queue_id]);
 }
 
+static uint32_t
+zxdh_gdma_read_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset)
+{
+	struct zxdh_gdma_rawdev *gdmadev = zxdh_gdma_rawdev_get_priv(dev);
+	uint32_t addr = 0;
+	uint32_t val = 0;
+
+	addr = offset + queue_id * ZXDH_GDMA_CHAN_SHIFT;
+	val = *(uint32_t *)(gdmadev->base_addr + addr);
+
+	return val;
+}
+
 static void
 zxdh_gdma_write_reg(struct rte_rawdev *dev, uint16_t queue_id, uint32_t offset, uint32_t val)
 {
@@ -264,11 +279,11 @@ zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
 
 		if (rbp->svfid != 0)
 			src_user |= (ZXDH_GDMA_VF_EN |
-						 ((rbp->svfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+					((rbp->svfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
 
 		ZXDH_PMD_LOG(DEBUG, "rxq->qidx:%d setup src_user(ep:%d pf:%d vf:%d) success",
-					queue_id, (uint8_t)rbp->sportid, (uint8_t)rbp->spfid,
-					(uint8_t)rbp->svfid);
+				queue_id, (uint8_t)rbp->sportid, (uint8_t)rbp->spfid,
+				(uint8_t)rbp->svfid);
 	} else if ((rbp->srbp == 0) && (rbp->drbp != 0)) {
 		is_txq = 1;
 		src_user = ZXDH_GDMA_ZF_USER;
@@ -277,11 +292,11 @@ zxdh_gdma_rawdev_queue_setup(struct rte_rawdev *dev,
 
 		if (rbp->dvfid != 0)
 			dst_user |= (ZXDH_GDMA_VF_EN |
-						 ((rbp->dvfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+					((rbp->dvfid - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
 
 		ZXDH_PMD_LOG(DEBUG, "txq->qidx:%d setup dst_user(ep:%d pf:%d vf:%d) success",
-					queue_id, (uint8_t)rbp->dportid, (uint8_t)rbp->dpfid,
-					(uint8_t)rbp->dvfid);
+				queue_id, (uint8_t)rbp->dportid, (uint8_t)rbp->dpfid,
+				(uint8_t)rbp->dvfid);
 	} else {
 		ZXDH_PMD_LOG(ERR, "Failed to setup queue, srbp/drbp is invalid");
 		return -EINVAL;
@@ -353,7 +368,7 @@ zxdh_gdma_user_get(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
 
 	if ((job->flags & ZXDH_GDMA_JOB_DIR_MASK) == 0) {
 		ZXDH_PMD_LOG(DEBUG, "job flags:0x%x default user:0x%x",
-							job->flags, queue->user);
+				job->flags, queue->user);
 		return queue->user;
 	} else if ((job->flags & ZXDH_GDMA_JOB_DIR_TX) != 0) {
 		src_user = ZXDH_GDMA_ZF_USER;
@@ -362,7 +377,7 @@ zxdh_gdma_user_get(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
 
 		if (job->vf_id != 0)
 			dst_user |= (ZXDH_GDMA_VF_EN |
-						 ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+					((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
 	} else {
 		dst_user = ZXDH_GDMA_ZF_USER;
 		src_user = ((job->pf_id << ZXDH_GDMA_PF_NUM_SHIFT) |
@@ -370,11 +385,11 @@ zxdh_gdma_user_get(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
 
 		if (job->vf_id != 0)
 			src_user |= (ZXDH_GDMA_VF_EN |
-						 ((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
+					((job->vf_id - 1) << ZXDH_GDMA_VF_NUM_SHIFT));
 	}
 	ZXDH_PMD_LOG(DEBUG, "job flags:0x%x ep_id:%u, pf_id:%u, vf_id:%u, user:0x%x",
-						job->flags, job->ep_id, job->pf_id, job->vf_id,
-						(src_user & LOW16_MASK) | (dst_user << 16));
+			job->flags, job->ep_id, job->pf_id, job->vf_id,
+			(src_user & LOW16_MASK) | (dst_user << 16));
 
 	return (src_user & LOW16_MASK) | (dst_user << 16);
 }
@@ -395,8 +410,8 @@ zxdh_gdma_fill_bd(struct zxdh_gdma_queue *queue, struct zxdh_gdma_job *job)
 	if (job != NULL) {
 		zxdh_gdma_control_cal(&val, 1);
 		next_bd_addr   = IDX_TO_ADDR(queue->ring.ring_mem,
-							(avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
-							uint64_t);
+						(avail_idx + 1) % ZXDH_GDMA_RING_SIZE,
+						uint64_t);
 		bd->SrcAddr_L  = job->src & LOW32_MASK;
 		bd->DstAddr_L  = job->dest & LOW32_MASK;
 		bd->SrcAddr_H  = (job->src >> 32) & LOW32_MASK;
@@ -473,8 +488,8 @@ zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *dev,
 	free_cnt = queue->sw_ring.free_cnt;
 	if (free_cnt == 0) {
 		ZXDH_PMD_LOG(ERR, "queue %u is full, enq_idx:%u deq_idx:%u used_idx:%u",
-						   queue_id, queue->sw_ring.enq_idx,
-						   queue->sw_ring.deq_idx, queue->sw_ring.used_idx);
+				queue_id, queue->sw_ring.enq_idx,
+				queue->sw_ring.deq_idx, queue->sw_ring.used_idx);
 		return 0;
 	} else if (free_cnt < count) {
 		ZXDH_PMD_LOG(DEBUG, "job num %u > free_cnt, change to %u", count, free_cnt);
@@ -519,6 +534,116 @@ zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *dev,
 
 	return count;
 }
+
+static inline void
+zxdh_gdma_used_idx_update(struct zxdh_gdma_queue *queue, uint16_t cnt, uint8_t data_bd_err)
+{
+	uint16_t idx = 0;
+
+	if (queue->sw_ring.used_idx + cnt < queue->queue_size)
+		queue->sw_ring.used_idx += cnt;
+	else
+		queue->sw_ring.used_idx = queue->sw_ring.used_idx + cnt - queue->queue_size;
+
+	if (data_bd_err == 1) {
+		/* Update job status, the last job status is error */
+		if (queue->sw_ring.used_idx == 0)
+			idx = queue->queue_size - 1;
+		else
+			idx = queue->sw_ring.used_idx - 1;
+
+		queue->sw_ring.job[idx]->status = 1;
+	}
+}
+
+static int
+zxdh_gdma_rawdev_dequeue_bufs(struct rte_rawdev *dev,
+				__rte_unused struct rte_rawdev_buf **buffers,
+				uint32_t count,
+				rte_rawdev_obj_t context)
+{
+	struct zxdh_gdma_queue *queue = NULL;
+	struct zxdh_gdma_enqdeq *e_context = NULL;
+	uint16_t queue_id = 0;
+	uint32_t val = 0;
+	uint16_t tc_cnt = 0;
+	uint16_t diff_cnt = 0;
+	uint16_t i = 0;
+	uint16_t bd_idx = 0;
+	uint64_t next_bd_addr = 0;
+	uint8_t data_bd_err = 0;
+
+	if ((dev == NULL) || (context == NULL))
+		return -EINVAL;
+
+	e_context = (struct zxdh_gdma_enqdeq *)context;
+	queue_id = e_context->vq_id;
+	queue = zxdh_gdma_get_queue(dev, queue_id);
+	if ((queue == NULL) || (queue->enable == 0))
+		return -EINVAL;
+
+	if (queue->sw_ring.pend_cnt == 0)
+		goto deq_job;
+
+	/* Get data transmit count */
+	val = zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET);
+	tc_cnt = val & LOW16_MASK;
+	if (tc_cnt >= queue->tc_cnt)
+		diff_cnt = tc_cnt - queue->tc_cnt;
+	else
+		diff_cnt = tc_cnt + ZXDH_GDMA_TC_CNT_MAX - queue->tc_cnt;
+
+	queue->tc_cnt = tc_cnt;
+
+	/* Data transmit error, channel stopped */
+	if ((val & ZXDH_GDMA_ERR_STATUS) != 0) {
+		next_bd_addr  = zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_LLI_L_OFFSET);
+		next_bd_addr |= ((uint64_t)zxdh_gdma_read_reg(dev, queue_id,
+							ZXDH_GDMA_LLI_H_OFFSET) << 32);
+		next_bd_addr  = next_bd_addr << 6;
+		bd_idx = (next_bd_addr - queue->ring.ring_mem) / sizeof(struct zxdh_gdma_buff_desc);
+		if ((val & ZXDH_GDMA_SRC_DATA_ERR) || (val & ZXDH_GDMA_DST_ADDR_ERR)) {
+			diff_cnt++;
+			data_bd_err = 1;
+		}
+		ZXDH_PMD_LOG(INFO, "queue%d is err(0x%x) next_bd_idx:%u ll_addr:0x%"PRIx64" def user:0x%x",
+				queue_id, val, bd_idx, next_bd_addr, queue->user);
+
+		ZXDH_PMD_LOG(INFO, "Clean up error status");
+		val = ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_ERR_INTR_ENABLE;
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET, val);
+
+		ZXDH_PMD_LOG(INFO, "Restart channel");
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0);
+		zxdh_gdma_control_cal(&val, 0);
+		zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val);
+	}
+
+	if (diff_cnt != 0) {
+		zxdh_gdma_used_idx_update(queue, diff_cnt, data_bd_err);
+		queue->sw_ring.deq_cnt += diff_cnt;
+		queue->sw_ring.pend_cnt -= diff_cnt;
+	}
+
+deq_job:
+	if (queue->sw_ring.deq_cnt == 0)
+		return 0;
+	else if (queue->sw_ring.deq_cnt < count)
+		count = queue->sw_ring.deq_cnt;
+
+	queue->sw_ring.deq_cnt -= count;
+
+	for (i = 0; i < count; i++) {
+		e_context->job[i] = queue->sw_ring.job[queue->sw_ring.deq_idx];
+		queue->sw_ring.job[queue->sw_ring.deq_idx] = NULL;
+		if (++queue->sw_ring.deq_idx >= queue->queue_size)
+			queue->sw_ring.deq_idx -= queue->queue_size;
+	}
+	queue->sw_ring.free_cnt += count;
+
+	return count;
+}
+
 static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.dev_info_get = zxdh_gdma_rawdev_info_get,
 	.dev_configure = zxdh_gdma_rawdev_configure,
@@ -533,6 +658,7 @@ static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops = {
 	.attr_get = zxdh_gdma_rawdev_get_attr,
 
 	.enqueue_bufs = zxdh_gdma_rawdev_enqueue_bufs,
+	.dequeue_bufs = zxdh_gdma_rawdev_dequeue_bufs,
 };
 
 static int
@@ -573,7 +699,7 @@ zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
 	snprintf(name, RTE_MEMZONE_NAMESIZE, "gdma_vq%d_ring", queue_id);
 	size = ZXDH_GDMA_RING_SIZE * sizeof(struct zxdh_gdma_buff_desc);
 	mz = rte_memzone_reserve_aligned(name, size, rte_socket_id(),
-							RTE_MEMZONE_IOVA_CONTIG, size);
+						RTE_MEMZONE_IOVA_CONTIG, size);
 	if (mz == NULL) {
 		if (rte_errno == EEXIST)
 			mz = rte_memzone_lookup(name);
@@ -589,7 +715,7 @@ zxdh_gdma_queue_init(struct rte_rawdev *dev, uint16_t queue_id)
 	queue->ring.ring_mem  = mz->iova;
 	queue->ring.avail_idx = 0;
 	ZXDH_PMD_LOG(INFO, "queue%u ring phy addr:0x%"PRIx64" virt addr:%p",
-						queue_id, mz->iova, mz->addr);
+			queue_id, mz->iova, mz->addr);
 
 	/* Configure the hardware channel to the initial state */
 	zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET,
@@ -689,7 +815,7 @@ zxdh_gdma_unmap_resource(void *requested_addr, size_t size)
 	/* Unmap the PCI memory resource of device */
 	if (rte_mem_unmap(requested_addr, size))
 		ZXDH_PMD_LOG(ERR, "cannot mem unmap(%p, %#zx): %s",
-			requested_addr, size, rte_strerror(rte_errno));
+				requested_addr, size, rte_strerror(rte_errno));
 	else
 		ZXDH_PMD_LOG(DEBUG, "PCI memory unmapped at %p", requested_addr);
 }
@@ -715,8 +841,8 @@ zxdh_gdma_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
 		return -1;
 	}
 	ZXDH_PMD_LOG(INFO, "%s bar0 0x%"PRIx64" mapped at %p",
-				pci_dev->name, pci_dev->mem_resource[0].phys_addr,
-				pci_dev->mem_resource[0].addr);
+			pci_dev->name, pci_dev->mem_resource[0].phys_addr,
+			pci_dev->mem_resource[0].addr);
 
 	dev = rte_rawdev_pmd_allocate(dev_name, sizeof(struct zxdh_gdma_rawdev), rte_socket_id());
 	if (dev == NULL) {
@@ -747,7 +873,7 @@ zxdh_gdma_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 err_out:
 	zxdh_gdma_unmap_resource(pci_dev->mem_resource[0].addr,
-		(size_t)pci_dev->mem_resource[0].len);
+				(size_t)pci_dev->mem_resource[0].len);
 	return -1;
 }
 
-- 
2.43.0

[-- Attachment #1.1.2: Type: text/html , Size: 28510 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] raw/gdtc: introduce gdtc raw device driver
  2024-11-12  4:12   ` [PATCH] " Thomas Monjalon
  2024-11-12  5:13     ` Stephen Hemminger
@ 2024-11-14  9:36     ` zhang.yong25
  1 sibling, 0 replies; 25+ messages in thread
From: zhang.yong25 @ 2024-11-14  9:36 UTC (permalink / raw)
  To: thomas; +Cc: dev, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 1110 bytes --]

Hi Thomas,

>> I submitted a patch on October 29 and haven't received response.>> Wondering if any modifications are needed? Could you provide an update on the review?>> Thanks. Looking forward to hearing from you.>>I cannot apply your patches because the format looks wrong.>It looks there an issue with line ending. Windows?

I just modified the patch and resubmitted it. The local git apply is OK. 
Can you please try again to see if it is OK?



Original


From: ThomasMonjalon <thomas@monjalon.net>
To: 张勇10313449;
Cc: dev@dpdk.org <dev@dpdk.org>;张勇10313449;汪勇10032886;李敏10314441;冉明10033339;
Date: 2024年11月12日 12:12
Subject: Re: [PATCH] raw/gdtc: introduce gdtc raw device driver

Hello,
 
04/11/2024 03:15, Yong Zhang:
> Hi thomas,
>  
> I submitted a patch on October 29 and haven't received response.
> Wondering if any modifications are needed? Could you provide an update on the review?
> Thanks. Looking forward to hearing from you.
 
I cannot apply your patches because the format looks wrong.
It looks there an issue with line ending. Windows?

[-- Attachment #1.1.2: Type: text/html , Size: 3519 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v5,1/5] raw/gdtc: introduce gdtc raw device driver
  2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
                     ` (3 preceding siblings ...)
  2024-11-14  9:20   ` [v5,5/5] raw/gdtc: add support for dequeue operation Yong Zhang
@ 2024-11-20  0:45   ` Thomas Monjalon
  4 siblings, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2024-11-20  0:45 UTC (permalink / raw)
  To: Yong Zhang; +Cc: stephen, dev, zhang.yong25, wang.yong19, li.min10, ran.ming

14/11/2024 10:20, Yong Zhang:
> Introduce rawdev driver support for GDTC which
> can help to connect two separate hosts with each other.
> 
> Signed-off-by: Yong Zhang <zhang.yong25@zte.com.cn>

I've sorted things, and avoided reindent in the last patch.

Series applied, thanks.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v5,2/5] raw/gdtc: add support for queue setup operation
  2024-11-14  9:20   ` [v5,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
@ 2024-11-20  0:46     ` Thomas Monjalon
  2024-11-20  1:45       ` zhang.yong25
  0 siblings, 1 reply; 25+ messages in thread
From: Thomas Monjalon @ 2024-11-20  0:46 UTC (permalink / raw)
  To: Yong Zhang; +Cc: stephen, dev, zhang.yong25, wang.yong19, li.min10, ran.ming

14/11/2024 10:20, Yong Zhang:
> +#define ZXDH_GDMA_SRC_LLI_ERR                   (1 << 16)
> +#define ZXDH_GDMA_SRC_DATA_ERR                  (1 << 17)
> +#define ZXDH_GDMA_DST_ADDR_ERR                  (1 << 18)
> +#define ZXDH_GDMA_ERR_STATUS                    (1 << 19)
> +#define ZXDH_GDMA_ERR_INTR_ENABLE               (1 << 20)

You should use RTE_BIT macros for this.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v5,2/5] raw/gdtc: add support for queue setup operation
  2024-11-20  0:46     ` Thomas Monjalon
@ 2024-11-20  1:45       ` zhang.yong25
  2024-11-20  1:59         ` Thomas Monjalon
  0 siblings, 1 reply; 25+ messages in thread
From: zhang.yong25 @ 2024-11-20  1:45 UTC (permalink / raw)
  To: thomas; +Cc: dev, wang.yong19, li.min10, ran.ming


[-- Attachment #1.1.1: Type: text/plain, Size: 483 bytes --]

Hi Thomas,

>> +#define ZXDH_GDMA_SRC_LLI_ERR                   (1 << 16)>> +#define ZXDH_GDMA_SRC_DATA_ERR                  (1 << 17)>> +#define ZXDH_GDMA_DST_ADDR_ERR                  (1 << 18)>> +#define ZXDH_GDMA_ERR_STATUS                    (1 << 19)>> +#define ZXDH_GDMA_ERR_INTR_ENABLE               (1 << 20)>>You should use RTE_BIT macros for this.

The patch is currently in the accepted state. 
Should I resubmit the patch or modify it in the next release?

thanks

[-- Attachment #1.1.2: Type: text/html , Size: 3099 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [v5,2/5] raw/gdtc: add support for queue setup operation
  2024-11-20  1:45       ` zhang.yong25
@ 2024-11-20  1:59         ` Thomas Monjalon
  0 siblings, 0 replies; 25+ messages in thread
From: Thomas Monjalon @ 2024-11-20  1:59 UTC (permalink / raw)
  To: zhang.yong25; +Cc: dev, wang.yong19, li.min10, ran.ming

20/11/2024 02:45, zhang.yong25@zte.com.cn:
> The patch is currently in the accepted state.

Yes I've merged it.

> Should I resubmit the patch or modify it in the next release?

You can modify with a new patch for the next release.



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2024-11-20  1:59 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-29 13:45 [v4,1/5] raw/gdtc: introduce gdtc raw device driver Yong Zhang
2024-10-29 13:45 ` [v4,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
2024-11-12  5:05   ` Stephen Hemminger
2024-10-29 13:45 ` [v4,3/5] raw/gdtc: add support for standard rawdev operations Yong Zhang
2024-10-29 13:45 ` [v4,4/5] raw/gdtc: add support for enqueue operation Yong Zhang
2024-10-29 13:45 ` [v4,5/5] raw/gdtc: add support for dequeue operation Yong Zhang
2024-11-04  2:15 ` Re:[PATCH] raw/gdtc: introduce gdtc raw device driver Yong Zhang
2024-11-12  4:12   ` [PATCH] " Thomas Monjalon
2024-11-12  5:13     ` Stephen Hemminger
2024-11-14  9:36     ` zhang.yong25
2024-11-12  5:08 ` [v4,1/5] " Stephen Hemminger
2024-11-12  5:08 ` Stephen Hemminger
2024-11-13  9:22   ` zhang.yong25
2024-11-13 14:59     ` Stephen Hemminger
2024-11-12  5:09 ` Stephen Hemminger
2024-11-12  5:48 ` Stephen Hemminger
2024-11-14  9:20 ` [v5,1/5] " Yong Zhang
2024-11-14  9:20   ` [v5,2/5] raw/gdtc: add support for queue setup operation Yong Zhang
2024-11-20  0:46     ` Thomas Monjalon
2024-11-20  1:45       ` zhang.yong25
2024-11-20  1:59         ` Thomas Monjalon
2024-11-14  9:20   ` [v5,3/5] raw/gdtc: add support for standard rawdev operations Yong Zhang
2024-11-14  9:20   ` [v5,4/5] raw/gdtc: add support for enqueue operation Yong Zhang
2024-11-14  9:20   ` [v5,5/5] raw/gdtc: add support for dequeue operation Yong Zhang
2024-11-20  0:45   ` [v5,1/5] raw/gdtc: introduce gdtc raw device driver Thomas Monjalon

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).