[v4,1/5] raw/gdtc: introduce gdtc raw device driver

Message ID 20241029134609.2499338-1-zhang.yong25@zte.com.cn (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v4,1/5] raw/gdtc: introduce gdtc raw device driver |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Yong Zhang Oct. 29, 2024, 1:45 p.m. UTC
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

-- 
2.43.0
  

Comments

Yong Zhang Nov. 4, 2024, 2:15 a.m. UTC | #1
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,
  
Thomas Monjalon Nov. 12, 2024, 4:12 a.m. UTC | #2
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?
  
Stephen Hemminger Nov. 12, 2024, 5:08 a.m. UTC | #3
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.
  
Stephen Hemminger Nov. 12, 2024, 5:08 a.m. UTC | #4
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.
  
Stephen Hemminger Nov. 12, 2024, 5:09 a.m. UTC | #5
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
  
Stephen Hemminger Nov. 12, 2024, 5:13 a.m. UTC | #6
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?
  
Stephen Hemminger Nov. 12, 2024, 5:48 a.m. UTC | #7
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
  
Yong Zhang Nov. 13, 2024, 9:22 a.m. UTC | #8
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.
  
Stephen Hemminger Nov. 13, 2024, 2:59 p.m. UTC | #9
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.
  
Yong Zhang Nov. 14, 2024, 9:36 a.m. UTC | #10
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?
  

Patch

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']