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