All of lore.kernel.org
 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 related	[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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.