From: = Hanxiao Li <li.hanxiao@zte.com.cn> <br /> <br />Signed-off-by: Hanxiao Li <li.hanxiao@zte.com.cn> <br />---<br /> MAINTAINERS                                   |  14 +<br /> config/rte_config.h                           |   6 +-<br /> drivers/common/zsda/meson.build               |  35 +<br /> drivers/common/zsda/version.map               |   3 +<br /> drivers/common/zsda/zsda_common.c             | 226 +++++<br /> drivers/common/zsda/zsda_common.h             | 345 ++++++++<br /> drivers/common/zsda/zsda_device.c             | 661 +++++++++++++++<br /> drivers/common/zsda/zsda_device.h             | 207 +++++<br /> drivers/common/zsda/zsda_logs.c               |  21 +<br /> drivers/common/zsda/zsda_logs.h               |  32 +<br /> drivers/common/zsda/zsda_qp.c                 | 703 ++++++++++++++++<br /> drivers/common/zsda/zsda_qp.h                 | 208 +++++<br /> drivers/compress/zsda/zsda_comp.c             | 273 ++++++<br /> drivers/compress/zsda/zsda_comp.h             |  34 +<br /> drivers/compress/zsda/zsda_comp_pmd.c         | 430 ++++++++++<br /> drivers/compress/zsda/zsda_comp_pmd.h         |  42 +<br /> drivers/crypto/zsda/meson.build               |  26 +<br /> drivers/crypto/zsda/version.map               |   6 +<br /> drivers/crypto/zsda/zsda_sym.c                | 734 ++++++++++++++++<br /> drivers/crypto/zsda/zsda_sym.h                |  42 +<br /> drivers/crypto/zsda/zsda_sym_capabilities.h   | 136 +++<br /> drivers/crypto/zsda/zsda_sym_pmd.c            | 431 ++++++++++<br /> drivers/crypto/zsda/zsda_sym_pmd.h            |  44 +<br /> drivers/meson.build                           |   1 +<br /> examples/meson.build                          |   1 +<br /> examples/zsda/Makefile                        |  56 ++<br /> examples/zsda/commands.c                      | 321 +++++++<br /> examples/zsda/meson.build                     |  30 +<br /> examples/zsda/test.c                          | 198 +++++<br /> examples/zsda/test.h                          | 236 ++++++<br /> examples/zsda/test_zsda.c                     | 309 +++++++<br /> examples/zsda/test_zsda.h                     | 457 ++++++++++<br /> examples/zsda/test_zsda_compressdev.c         | 678 +++++++++++++++<br /> examples/zsda/test_zsda_compressdev.h         |  93 ++<br /> examples/zsda/test_zsda_cryptodev.c           | 794 ++++++++++++++++++<br /> examples/zsda/test_zsda_cryptodev.h           | 144 ++++<br /> .../test_zsda_cryptodev_aes_test_vectors.h    | 139 +++<br /> examples/zsda/test_zsda_cryptodev_data.h      | 184 ++++<br /> .../test_zsda_cryptodev_hash_test_vectors.h   | 210 +++++<br /> lib/compressdev/rte_compressdev.h             |  15 +-<br /> lib/compressdev/rte_compressdev_pmd.h         |   3 +<br /> lib/cryptodev/rte_crypto_sym.h                |   4 +<br /> lib/cryptodev/rte_cryptodev_pmd.h             | 325 +++++++<br /> usertools/dpdk-devbind.py                     | 117 +--<br /> 44 files changed, 8900 insertions(+), 74 deletions(-)<br /> create mode 100644 drivers/common/zsda/meson.build<br /> create mode 100644 drivers/common/zsda/version.map<br /> create mode 100644 drivers/common/zsda/zsda_common.c<br /> create mode 100644 drivers/common/zsda/zsda_common.h<br /> create mode 100644 drivers/common/zsda/zsda_device.c<br /> create mode 100644 drivers/common/zsda/zsda_device.h<br /> create mode 100644 drivers/common/zsda/zsda_logs.c<br /> create mode 100644 drivers/common/zsda/zsda_logs.h<br /> create mode 100644 drivers/common/zsda/zsda_qp.c<br /> create mode 100644 drivers/common/zsda/zsda_qp.h<br /> create mode 100644 drivers/compress/zsda/zsda_comp.c<br /> create mode 100644 drivers/compress/zsda/zsda_comp.h<br /> create mode 100644 drivers/compress/zsda/zsda_comp_pmd.c<br /> create mode 100644 drivers/compress/zsda/zsda_comp_pmd.h<br /> create mode 100644 drivers/crypto/zsda/meson.build<br /> create mode 100644 drivers/crypto/zsda/version.map<br /> create mode 100644 drivers/crypto/zsda/zsda_sym.c<br /> create mode 100644 drivers/crypto/zsda/zsda_sym.h<br /> create mode 100644 drivers/crypto/zsda/zsda_sym_capabilities.h<br /> create mode 100644 drivers/crypto/zsda/zsda_sym_pmd.c<br /> create mode 100644 drivers/crypto/zsda/zsda_sym_pmd.h<br /> create mode 100644 examples/zsda/Makefile<br /> create mode 100644 examples/zsda/commands.c<br /> create mode 100644 examples/zsda/meson.build<br /> create mode 100644 examples/zsda/test.c<br /> create mode 100644 examples/zsda/test.h<br /> create mode 100644 examples/zsda/test_zsda.c<br /> create mode 100644 examples/zsda/test_zsda.h<br /> create mode 100644 examples/zsda/test_zsda_compressdev.c<br /> create mode 100644 examples/zsda/test_zsda_compressdev.h<br /> create mode 100644 examples/zsda/test_zsda_cryptodev.c<br /> create mode 100644 examples/zsda/test_zsda_cryptodev.h<br /> create mode 100644 examples/zsda/test_zsda_cryptodev_aes_test_vectors.h<br /> create mode 100644 examples/zsda/test_zsda_cryptodev_data.h<br /> create mode 100644 examples/zsda/test_zsda_cryptodev_hash_test_vectors.h<br /> create mode 100644 lib/cryptodev/rte_cryptodev_pmd.h<br /> <br />diff --git a/MAINTAINERS b/MAINTAINERS<br />index 22ef2ea..9503cfa 100644<br />--- a/MAINTAINERS<br />+++ b/MAINTAINERS<br />@@ -1088,6 +1088,11 @@ F: drivers/common/qat/<br /> F: doc/guides/cryptodevs/qat.rst<br /> F: doc/guides/cryptodevs/features/qat.ini<br />  <br />+ZTE Storage Data Accelerator<br />+M: Hanxiao Li <li.hanxiao@zte.com.cn> <br />+F: drivers/crypto/zsda/<br />+F: drivers/common/zsda/<br />+<br /> IPsec MB<br /> M: Kai Ji <kai.ji@intel.com> <br /> M: Pablo de Lara <pablo.de.lara.guarch@intel.com> <br />@@ -1205,6 +1210,15 @@ F: drivers/compress/zlib/<br /> F: doc/guides/compressdevs/zlib.rst<br /> F: doc/guides/compressdevs/features/zlib.ini<br />  <br />+ZTE Storage Data Accelerator<br />+M: Hanxiao Li <li.hanxiao@zte.com.cn> <br />+F: drivers/compress/zsda/<br />+F: drivers/common/zsda/<br />+<br />+ZTE Storage Data Accelerator<br />+M: Hanxiao Li <li.hanxiao@zte.com.cn> <br />+F: drivers/crypto/zsda/<br />+F: drivers/common/zsda/<br />  <br /> DMAdev Drivers<br /> --------------<br />diff --git a/config/rte_config.h b/config/rte_config.h<br />index 3c4876d..b097360 100644<br />--- a/config/rte_config.h<br />+++ b/config/rte_config.h<br />@@ -37,7 +37,7 @@<br /> #define RTE_MAX_MEMZONE 2560<br /> #define RTE_MAX_TAILQ 32<br /> #define RTE_LOG_DP_LEVEL RTE_LOG_INFO<br />-#define RTE_BACKTRACE 1<br />+// #define RTE_BACKTRACE 1<br /> #define RTE_MAX_VFIO_CONTAINERS 64<br />  <br /> /* bsd module defines */<br />@@ -105,6 +105,10 @@<br /> #define RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS 16<br /> #define RTE_PMD_QAT_COMP_IM_BUFFER_SIZE 65536<br />  <br />+/* ZSDA device */<br />+/* Max. number of ZSDA devices which can be attached */<br />+#define RTE_PMD_ZSDA_MAX_PCI_DEVICES 256<br />+<br /> /* virtio crypto defines */<br /> #define RTE_MAX_VIRTIO_CRYPTO 32<br />  <br />diff --git a/drivers/common/zsda/meson.build b/drivers/common/zsda/meson.build<br />new file mode 100644<br />index 0000000..093965b<br />--- /dev/null<br />+++ b/drivers/common/zsda/meson.build<br />@@ -0,0 +1,35 @@<br />+# SPDX-License-Identifier: BSD-3-Clause<br />+# Copyright(c) 2017-2018 Intel Corporation<br />+<br />+config_flag_fmt = 'RTE_LIBRTE_@0@_COMMON' <br />+<br />+zsda_crypto = true<br />+zsda_crypto_path = 'crypto/zsda' <br />+zsda_crypto_relpath = '../../' + zsda_crypto_path<br />+zsda_compress = true<br />+zsda_compress_path = 'compress/zsda' <br />+zsda_compress_relpath = '../../' + zsda_compress_path<br />+<br />+deps += ['bus_pci', 'cryptodev', 'net', 'compressdev']<br />+sources += files('zsda_common.c','zsda_qp.c',<br />+        'zsda_device.c',<br />+        'zsda_logs.c')<br />+includes += include_directories(zsda_crypto_relpath,<br />+        zsda_compress_relpath)<br />+<br />+if zsda_compress<br />+    foreach f: ['zsda_comp_pmd.c','zsda_comp.c']<br />+        sources += files(join_paths(zsda_compress_relpath, f))<br />+    endforeach<br />+endif<br />+<br />+if zsda_crypto<br />+libcrypto = dependency('libcrypto', required: false, method: 'pkg-config')<br />+    foreach f: ['zsda_sym_pmd.c', 'zsda_sym.c']<br />+        sources += files(join_paths(zsda_crypto_relpath, f))<br />+    endforeach<br />+    deps += ['security']<br />+    ext_deps += libcrypto<br />+    cflags += ['-DBUILD_ZSDA_SYM']<br />+endif<br />+<br />diff --git a/drivers/common/zsda/version.map b/drivers/common/zsda/version.map<br />new file mode 100644<br />index 0000000..4a76d1d<br />--- /dev/null<br />+++ b/drivers/common/zsda/version.map<br />@@ -0,0 +1,3 @@<br />+DPDK_21 {<br />+    local: *;<br />+};<br />diff --git a/drivers/common/zsda/zsda_common.c b/drivers/common/zsda/zsda_common.c<br />new file mode 100644<br />index 0000000..c8f34b0<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_common.c<br />@@ -0,0 +1,226 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include "zsda_common.h" <br />+#include "zsda_device.h" <br />+<br />+#define MAGIC_SEND 0xab<br />+#define MAGIC_RECV 0xcd<br />+#define ADMIN_VER 1<br />+<br />+static uint8_t crc8_table[256] = {<br />+    0x00, 0x41, 0x13, 0x52, 0x26, 0x67, 0x35, 0x74, 0x4c, 0x0d, 0x5f, 0x1e,<br />+    0x6a, 0x2b, 0x79, 0x38, 0x09, 0x48, 0x1a, 0x5b, 0x2f, 0x6e, 0x3c, 0x7d,<br />+    0x45, 0x04, 0x56, 0x17, 0x63, 0x22, 0x70, 0x31, 0x12, 0x53, 0x01, 0x40,<br />+    0x34, 0x75, 0x27, 0x66, 0x5e, 0x1f, 0x4d, 0x0c, 0x78, 0x39, 0x6b, 0x2a,<br />+    0x1b, 0x5a, 0x08, 0x49, 0x3d, 0x7c, 0x2e, 0x6f, 0x57, 0x16, 0x44, 0x05,<br />+    0x71, 0x30, 0x62, 0x23, 0x24, 0x65, 0x37, 0x76, 0x02, 0x43, 0x11, 0x50,<br />+    0x68, 0x29, 0x7b, 0x3a, 0x4e, 0x0f, 0x5d, 0x1c, 0x2d, 0x6c, 0x3e, 0x7f,<br />+    0x0b, 0x4a, 0x18, 0x59, 0x61, 0x20, 0x72, 0x33, 0x47, 0x06, 0x54, 0x15,<br />+    0x36, 0x77, 0x25, 0x64, 0x10, 0x51, 0x03, 0x42, 0x7a, 0x3b, 0x69, 0x28,<br />+    0x5c, 0x1d, 0x4f, 0x0e, 0x3f, 0x7e, 0x2c, 0x6d, 0x19, 0x58, 0x0a, 0x4b,<br />+    0x73, 0x32, 0x60, 0x21, 0x55, 0x14, 0x46, 0x07, 0x48, 0x09, 0x5b, 0x1a,<br />+    0x6e, 0x2f, 0x7d, 0x3c, 0x04, 0x45, 0x17, 0x56, 0x22, 0x63, 0x31, 0x70,<br />+    0x41, 0x00, 0x52, 0x13, 0x67, 0x26, 0x74, 0x35, 0x0d, 0x4c, 0x1e, 0x5f,<br />+    0x2b, 0x6a, 0x38, 0x79, 0x5a, 0x1b, 0x49, 0x08, 0x7c, 0x3d, 0x6f, 0x2e,<br />+    0x16, 0x57, 0x05, 0x44, 0x30, 0x71, 0x23, 0x62, 0x53, 0x12, 0x40, 0x01,<br />+    0x75, 0x34, 0x66, 0x27, 0x1f, 0x5e, 0x0c, 0x4d, 0x39, 0x78, 0x2a, 0x6b,<br />+    0x6c, 0x2d, 0x7f, 0x3e, 0x4a, 0x0b, 0x59, 0x18, 0x20, 0x61, 0x33, 0x72,<br />+    0x06, 0x47, 0x15, 0x54, 0x65, 0x24, 0x76, 0x37, 0x43, 0x02, 0x50, 0x11,<br />+    0x29, 0x68, 0x3a, 0x7b, 0x0f, 0x4e, 0x1c, 0x5d, 0x7e, 0x3f, 0x6d, 0x2c,<br />+    0x58, 0x19, 0x4b, 0x0a, 0x32, 0x73, 0x21, 0x60, 0x14, 0x55, 0x07, 0x46,<br />+    0x77, 0x36, 0x64, 0x25, 0x51, 0x10, 0x42, 0x03, 0x3b, 0x7a, 0x28, 0x69,<br />+    0x1d, 0x5c, 0x0e, 0x4f};<br />+<br />+static uint8_t<br />+zsda_crc8(uint8_t *message, int length)<br />+{<br />+    uint8_t crc = 0;<br />+    int i;<br />+<br />+    for (i = 0; i < length; i++)<br />+        crc = crc8_table[crc ^ message[i]];<br />+    return crc;<br />+}<br />+<br />+uint32_t set_reg_8(void *addr, uint8_t val0, uint8_t val1, uint8_t val2, uint8_t val3)<br />+{<br />+    uint8_t val[4];<br />+    val[0] = val0;<br />+    val[1] = val1;<br />+    val[2] = val2;<br />+    val[3] = val3;<br />+    ZSDA_CSR_WRITE32(addr, *(uint32_t *)val);<br />+    return *(uint32_t *)val;<br />+}<br />+<br />+uint8_t<br />+get_reg_8(void *addr, uint8_t offset)<br />+{<br />+    uint32_t val = ZSDA_CSR_READ32(addr);<br />+<br />+    return *(((uint8_t *)&val) + offset);<br />+}<br />+<br />+int<br />+zsda_admin_msg_init(struct rte_pci_device *pci_dev)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+<br />+    set_reg_8(mmio_base + ZSDA_ADMIN_WQ_BASE7, 0, 0, MAGIC_RECV, 0);<br />+    set_reg_8(mmio_base + ZSDA_ADMIN_CQ_BASE7, 0, 0, MAGIC_RECV, 0);<br />+    return 0;<br />+}<br />+<br />+int<br />+zsda_send_admin_msg(struct rte_pci_device *pci_dev, void *req, uint32_t len)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t wq_flag = 0;<br />+    uint8_t crc = 0;<br />+    uint16_t admin_db = 0;<br />+    uint32_t retry = 1000;<br />+    uint32_t i = 0;<br />+    uint16_t db = 0;<br />+<br />+<br />+    if (len > ADMIN_BUF_DATA_LEN)<br />+        return -EINVAL;<br />+<br />+    for (i = 0; i < 7; i++) {<br />+        ZSDA_CSR_WRITE32(((uint32_t *)(mmio_base + ZSDA_ADMIN_WQ) + i),<br />+                 *((uint32_t *)req + i));<br />+    }<br />+<br />+    crc = zsda_crc8((uint8_t *)req, ADMIN_BUF_DATA_LEN);<br />+    set_reg_8(mmio_base + ZSDA_ADMIN_WQ_BASE7, crc, ADMIN_VER, MAGIC_SEND, 0);<br />+    rte_delay_us_sleep(100);<br />+    rte_wmb();<br />+<br />+    admin_db = ZSDA_CSR_READ32(mmio_base + ZSDA_ADMIN_WQ_TAIL);<br />+    db = zsda_modulo_32(admin_db, 0x1ff);<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_WQ_TAIL, db);<br />+<br />+    do {<br />+        rte_delay_us_sleep(100);<br />+        wq_flag = get_reg_8(mmio_base + ZSDA_ADMIN_WQ_BASE7, 2);<br />+        if (wq_flag == MAGIC_RECV)<br />+            break;<br />+<br />+        retry--;<br />+        if (!retry) {<br />+            printf("wq_flag 0x%X \n", wq_flag);<br />+            set_reg_8(mmio_base + ZSDA_ADMIN_WQ_BASE7, 0, crc,<br />+                  ADMIN_VER, 0);<br />+            return -EIO;<br />+        }<br />+    } while (1);<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+zsda_recv_admin_msg(struct rte_pci_device *pci_dev, void *resp, uint32_t len)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t cq_flag = 0;<br />+    uint32_t retry = 100;<br />+    uint8_t crc = 0;<br />+    uint8_t buf[ADMIN_BUF_TOTAL_LEN] = {0};<br />+    uint32_t i = 0;<br />+<br />+    if (len > ADMIN_BUF_DATA_LEN)<br />+        return -EINVAL;<br />+<br />+    do {<br />+        rte_delay_us_sleep(50);<br />+<br />+        cq_flag = get_reg_8(mmio_base + ZSDA_ADMIN_CQ_BASE7, 2);<br />+        if (cq_flag == MAGIC_SEND)<br />+            break;<br />+<br />+        retry--;<br />+        if (!retry)<br />+            return -EIO;<br />+    } while (1);<br />+<br />+    for (i = 0; i < len; i++)<br />+        buf[i] = ZSDA_CSR_READ8(<br />+            (uint8_t *)(mmio_base + ZSDA_ADMIN_CQ + i));<br />+<br />+    crc = ZSDA_CSR_READ8(mmio_base + ZSDA_ADMIN_CQ_CRC);<br />+    rte_rmb();<br />+    ZSDA_CSR_WRITE8(mmio_base + ZSDA_ADMIN_CQ_FLAG, MAGIC_RECV);<br />+    if (crc != zsda_crc8(buf, ADMIN_BUF_DATA_LEN)) {<br />+        ZSDA_LOG(ERR, "[%d] Failed! crc error!", __LINE__);<br />+        return -EIO;<br />+    }<br />+<br />+    memcpy(resp, buf, len);<br />+<br />+    return 0;<br />+}<br />+<br />+void<br />+zsda_stats_get(void **queue_pairs, uint32_t nb_queue_pairs,<br />+          struct zsda_common_stat *stats)<br />+{<br />+    enum zsda_service_type type;<br />+    uint32_t i = 0;<br />+    struct zsda_qp *qp;<br />+<br />+    if ((stats == NULL) || (queue_pairs == NULL)) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return;<br />+    }<br />+<br />+    for (i = 0; i < nb_queue_pairs; i++) {<br />+        qp = queue_pairs[i];<br />+<br />+        if (qp == NULL) {<br />+            ZSDA_LOG(ERR, E_NULL);<br />+            break;<br />+        }<br />+<br />+        for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {<br />+            if (qp->srv[type].used) {<br />+                stats->enqueued_count +=<br />+                    qp->srv[type].stats.enqueued_count;<br />+                stats->dequeued_count +=<br />+                    qp->srv[type].stats.dequeued_count;<br />+                stats->enqueue_err_count +=<br />+                    qp->srv[type].stats.enqueue_err_count;<br />+                stats->dequeue_err_count +=<br />+                    qp->srv[type].stats.dequeue_err_count;<br />+            }<br />+        }<br />+    }<br />+}<br />+<br />+void<br />+zsda_stats_reset(void **queue_pairs, uint32_t nb_queue_pairs)<br />+{<br />+    enum zsda_service_type type;<br />+    uint32_t i = 0;<br />+    struct zsda_qp *qp;<br />+<br />+    if (queue_pairs == NULL) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return;<br />+    }<br />+<br />+    for (i = 0; i < nb_queue_pairs; i++) {<br />+        qp = queue_pairs[i];<br />+<br />+        if (qp == NULL) {<br />+            ZSDA_LOG(ERR, E_NULL);<br />+            break;<br />+        }<br />+        for (type = 0; type < ZSDA_MAX_SERVICES; type++) {<br />+            if (qp->srv[type].used)<br />+                memset(&(qp->srv[type].stats), 0,<br />+                       sizeof(struct zsda_common_stats));<br />+        }<br />+    }<br />+}<br />diff --git a/drivers/common/zsda/zsda_common.h b/drivers/common/zsda/zsda_common.h<br />new file mode 100644<br />index 0000000..4c6b983<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_common.h<br />@@ -0,0 +1,345 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_COMMON_H_<br />+#define _ZSDA_COMMON_H_<br />+<br />+#include <stdint.h> <br />+<br />+#include <rte_bus_pci.h> <br />+#include <rte_mbuf.h> <br />+<br />+#include "eal_interrupts.h" <br />+#include "zsda_logs.h" <br />+#define ZSDA_PCI_NAME           zsda<br />+#define ZSDA_64_BTYE_ALIGN_MASK (~0x3f)<br />+#define ZSDA_SGL_MAX_NUMBER     512<br />+#define ZSDA_MAX_NUM_SEGS       (ZSDA_SGL_MAX_NUMBER / 32 * 31 + 1)<br />+#define ZSDA_SGL_FRAGMENT_SIZE  32<br />+#define NB_DES               512<br />+<br />+#define ZSDA_SUCCESS EXIT_SUCCESS<br />+#define ZSDA_FAILED  (-1)<br />+<br />+#define E_NULL      "Failed! Addr is NULL" <br />+#define E_CREATE  "Failed! Create" <br />+#define E_FUNC      "Failed! Function" <br />+#define E_START_Q "Failed! START q" <br />+#define E_MALLOC  "Failed! malloc" <br />+#define E_FREE      "Failed! free" <br />+<br />+#define E_COMPARE "Failed! compare" <br />+#define E_START      "Failed! start/setup" <br />+#define E_CLOSE      "Failed! stop/close" <br />+#define E_CONFIG  "Failed! config" <br />+#define E_RESULT  "Failed! result wrong" <br />+<br />+#define W_MAY_EXCEPT_TEST "Wrong situation, may be execption test" <br />+<br />+#define CHECK_ADDR_NULL(addr)                                                  \<br />+    do {                                                                   \<br />+        if (NULL == addr) {                                            \<br />+            ZSDA_LOG(ERR, "Failed! ADDR is NULL!");                 \<br />+            return ZSDA_FAILED;                                     \<br />+        }                                                              \<br />+    } while (0)<br />+<br />+enum zsda_device_gen {<br />+    ZSDA_GEN1 = 1,<br />+    ZSDA_GEN2,<br />+    ZSDA_GEN3,<br />+};<br />+<br />+enum zsda_service_type {<br />+    ZSDA_SERVICE_COMPRESSION = 0,<br />+    ZSDA_SERVICE_DECOMPRESSION,<br />+    ZSDA_SERVICE_SYMMETRIC_ENCRYPT,<br />+    ZSDA_SERVICE_SYMMETRIC_DECRYPT,<br />+    ZSDA_SERVICE_HASH_ENCODE = 6,<br />+    ZSDA_SERVICE_INVALID,<br />+};<br />+<br />+#define ZSDA_MAX_SERVICES (ZSDA_SERVICE_INVALID)<br />+<br />+#define ZSDA_OPC_EC_AES_XTS_256 0x0  //Encry AES-XTS-256<br />+#define ZSDA_OPC_EC_AES_XTS_512 0x01 //Encry AES-XTS-512<br />+#define ZSDA_OPC_EC_SM4_XTS_256 0x02 //Encry SM4-XTS-256<br />+#define ZSDA_OPC_DC_AES_XTS_256 0x08 //Decry AES-XTS-256<br />+#define ZSDA_OPC_DC_AES_XTS_512 0x09 //Decry AES-XTS-512<br />+#define ZSDA_OPC_DC_SM4_XTS_256 0x0A //Decry SM4-XTS-256<br />+#define ZSDA_OPC_EC_GZIP           0x10 //Encomp deflate-Gzip<br />+#define ZSDA_OPC_EC_ZLIB           0x11 //Encomp deflate-Zlib<br />+#define ZSDA_OPC_DC_GZIP           0x18 //Decompinfalte-Gzip<br />+#define ZSDA_OPC_DC_ZLIB           0x19 //Decompinfalte-Zlib<br />+#define ZSDA_OPC_HASH_SHA1      0x20 // Hash-SHA1<br />+#define ZSDA_OPC_HASH_SHA2_224  0x21 // Hash-SHA2-224<br />+#define ZSDA_OPC_HASH_SHA2_256  0x22 // Hash-SHA2-256<br />+#define ZSDA_OPC_HASH_SHA2_384  0x23 // Hash-SHA2-384<br />+#define ZSDA_OPC_HASH_SHA2_512  0x24 // Hash-SHA2-512<br />+#define ZSDA_OPC_HASH_SM3       0x25 // Hash-SM3<br />+#define ZSDA_OPC_INVALID           0xff<br />+<br />+#define ZSDA_DIGEST_SIZE_SHA1     (20)<br />+#define ZSDA_DIGEST_SIZE_SHA2_224 (28)<br />+#define ZSDA_DIGEST_SIZE_SHA2_256 (32)<br />+#define ZSDA_DIGEST_SIZE_SHA2_384 (48)<br />+#define ZSDA_DIGEST_SIZE_SHA2_512 (64)<br />+#define ZSDA_DIGEST_SIZE_SM3     (32)<br />+<br />+#define ZSDA_AES_LBADS_INDICATE_0       (0x0)<br />+#define ZSDA_AES_LBADS_INDICATE_512     (0x9)<br />+#define ZSDA_AES_LBADS_INDICATE_4096    (0xC)<br />+#define ZSDA_AES_LBADS_INDICATE_8192    (0xD)<br />+#define ZSDA_AES_LBADS_INDICATE_INVALID (0xff)<br />+<br />+#define LEN_MIN_CIPHER        16<br />+#define LEN_MIN_HASH        16<br />+#define LEN_MIN_HASH_RESULT 16<br />+#define LEN_MAX_COMP        (0x1000000)<br />+#define LEN_MAX_COMP_8M        (0x800000)<br />+#define LEN_MIN_COMP        4<br />+#define LBADS_MAX_REMAINDER (16 - 1)<br />+<br />+#define DATA_SIZE_1K      1024<br />+#define DATA_LEN_TEST_4G  0x0100000000<br />+#define DATA_LEN_TEST_8M  (0x7ffff8 - 7)<br />+#define DATA_LEN_TEST_8B  7<br />+#define DATA_LEN_TEST_16B 15<br />+#define SET_CYCLE      0xff<br />+#define SET_HEAD_INTI      0x0<br />+#define ZSDA_IF_ERROR_TEST 1<br />+<br />+#define ZSDA_Q_START      0x1<br />+#define ZSDA_Q_STOP      0x0<br />+#define ZSDA_CLEAR_VALID      0x1<br />+#define ZSDA_CLEAR_INVALID 0x0<br />+#define ZSDA_RESP_VALID      0x1<br />+#define ZSDA_RESP_INVALID  0x0<br />+<br />+struct zsda_pci_device;<br />+<br />+enum sgl_elment_type_wqe {<br />+    SGL_ELM_TYPE_PHYS_ADDR = 1,<br />+    SGL_ELM_TYPE_LIST,<br />+    SGL_ELM_TYPE_LIST_ADDR,<br />+    SGL_ELM_TYPE_LIST_SGL32,<br />+};<br />+<br />+enum sgl_elment_type {<br />+    SGL_TYPE_PHYS_ADDR = 0,<br />+    SGL_TYPE_LAST_PHYS_ADDR,<br />+    SGL_TYPE_NEXT_LIST,<br />+    SGL_TYPE_EC_LEVEL1_SGL32,<br />+};<br />+<br />+enum zsda_admin_msg_id {<br />+    // Version information<br />+    ZSDA_ADMIN_VERSION_REQ = 0,<br />+    ZSDA_ADMIN_VERSION_RESP,<br />+    // algo type<br />+    ZSDA_ADMIN_QUEUE_CFG_REQ,<br />+    ZSDA_ADMIN_QUEUE_CFG_RESP,<br />+    // get cycle<br />+    ZSDA_ADMIN_QUEUE_CYCLE_REQ,<br />+    ZSDA_ADMIN_QUEUE_CYCLE_RESP,<br />+    // set cyclr<br />+    ZSDA_ADMIN_SET_CYCLE_REQ,<br />+    ZSDA_ADMIN_SET_CYCLE_RESP,<br />+<br />+    ZSDA_MIG_STATE_WARNING,<br />+    ZSDA_ADMIN_RESERVE,<br />+    // set close flr register<br />+    ZSDA_FLR_SET_FUNCTION,<br />+    ZSDA_ADMIN_MSG_VALID,<br />+    ZSDA_ADMIN_INT_TEST<br />+};<br />+<br />+struct zsda_admin_req {<br />+    uint16_t msg_type;<br />+    uint8_t data[26];<br />+};<br />+<br />+struct zsda_admin_resp {<br />+    uint16_t msg_type;<br />+    uint8_t data[26];<br />+};<br />+<br />+struct zsda_test_msg {<br />+    uint32_t msg_type;<br />+    uint32_t data_in;<br />+    uint8_t data[20];<br />+};<br />+<br />+struct zsda_admin_req_qcfg {<br />+    uint16_t msg_type;<br />+    uint8_t qid;<br />+    uint8_t data[25];<br />+};<br />+<br />+#pragma pack(1)<br />+typedef struct {<br />+    uint16_t q_type;<br />+    uint16_t wq_tail;<br />+    uint16_t wq_head;<br />+    uint16_t cq_tail;<br />+    uint16_t cq_head;<br />+    uint16_t cycle;<br />+} qinfo;<br />+<br />+struct zsda_admin_resp_qcfg {<br />+    uint16_t msg_type;<br />+    qinfo qcfg;<br />+    uint8_t data[14];<br />+};<br />+#pragma pack()<br />+<br />+enum flr_clr_mask {<br />+    unmask = 0,<br />+    mask,<br />+};<br />+<br />+/**< Common struct for scatter-gather list operations */<br />+struct zsda_buf {<br />+    uint64_t addr;<br />+    uint32_t len;<br />+    uint8_t resrvd[3];<br />+    uint8_t type;<br />+} __rte_packed;<br />+<br />+struct zsda_sgl {<br />+    struct zsda_buf buffers[ZSDA_SGL_MAX_NUMBER];<br />+} __rte_packed __rte_cache_aligned;<br />+<br />+struct zsda_op_cookie {<br />+    bool used;<br />+    void *op;<br />+    uint8_t valid;<br />+    uint16_t sid;<br />+    struct zsda_sgl sgl_src;<br />+    struct zsda_sgl sgl_dst;<br />+    phys_addr_t sgl_src_phys_addr;<br />+    phys_addr_t sgl_dst_phys_addr;<br />+} __rte_packed;<br />+<br />+struct zsda_mul_sgl {<br />+    struct zsda_buf point_to_sgl[ZSDA_SGL_FRAGMENT_SIZE];<br />+    struct zsda_sgl sgls[ZSDA_SGL_FRAGMENT_SIZE];<br />+} __rte_packed __rte_cache_aligned;<br />+<br />+struct zsda_ec_op_cookie {<br />+    bool used;<br />+    void *op;<br />+    uint8_t valid;<br />+    uint16_t sid;<br />+    struct zsda_mul_sgl sgl_src;<br />+    struct zsda_mul_sgl sgl_dst;<br />+    phys_addr_t sgl_src_phys_addr;<br />+    phys_addr_t sgl_dst_phys_addr;<br />+} __rte_packed;<br />+<br />+struct crypto_cfg {<br />+    uint8_t slba[8];<br />+    uint8_t key[64];<br />+    uint8_t lbads : 4;<br />+    uint8_t resv1 : 4;<br />+    uint8_t resv2[23];<br />+} __rte_packed;<br />+<br />+struct compress_cfg {<br />+} __rte_packed;<br />+<br />+struct zsda_wqe_crpt {<br />+    uint8_t valid;<br />+    uint8_t op_code;<br />+    uint16_t sid;<br />+    uint8_t resv[3];<br />+    uint8_t rx_sgl_type : 4;<br />+    uint8_t tx_sgl_type : 4;<br />+    uint64_t rx_addr;<br />+    uint32_t rx_length;<br />+    uint64_t tx_addr;<br />+    uint32_t tx_length;<br />+    struct crypto_cfg cfg;<br />+} __rte_packed;<br />+<br />+struct zsda_wqe_comp {<br />+    uint8_t valid;<br />+    uint8_t op_code;<br />+    uint16_t sid;<br />+    uint8_t resv[3];<br />+    uint8_t rx_sgl_type : 4;<br />+    uint8_t tx_sgl_type : 4;<br />+    uint64_t rx_addr;<br />+    uint32_t rx_length;<br />+    uint64_t tx_addr;<br />+    uint32_t tx_length;<br />+    struct compress_cfg cfg;<br />+} __rte_packed;<br />+<br />+struct zsda_wqe_common {<br />+    uint8_t valid;<br />+    uint8_t op_code;<br />+    uint16_t sid;<br />+    uint8_t resv[3];<br />+    uint8_t rx_sgl_type : 4;<br />+    uint8_t tx_sgl_type : 4;<br />+    uint64_t rx_addr;<br />+    uint32_t rx_length;<br />+    uint64_t tx_addr;<br />+    uint32_t tx_length;<br />+} __rte_packed;<br />+<br />+struct zsda_cqe {<br />+    uint8_t valid; // cqe_cycle<br />+    uint8_t op_code;<br />+    uint16_t sid;<br />+    uint8_t state;<br />+    uint8_t result;<br />+    uint16_t zsda_wq_id;<br />+    uint32_t tx_real_length;<br />+    uint16_t err0;<br />+    uint16_t err1; // bit15 cqe flag<br />+} __rte_packed;<br />+<br />+struct zsda_common_stat {<br />+    /**< Count of all operations enqueued */<br />+    uint64_t enqueued_count;<br />+    /**< Count of all operations dequeued */<br />+    uint64_t dequeued_count;<br />+<br />+    /**< Total error count on operations enqueued */<br />+    uint64_t enqueue_err_count;<br />+    /**< Total error count on operations dequeued */<br />+    uint64_t dequeue_err_count;<br />+};<br />+<br />+enum zsda_algo_core {<br />+    ZSDA_CORE_COMP,<br />+    ZSDA_CORE_DECOMP,<br />+    ZSDA_CORE_ENCRY,<br />+    ZSDA_CORE_DECRY,<br />+    ZSDA_CORE_HASH,<br />+    ZSDA_CORE_INVALID,<br />+<br />+};<br />+<br />+#define CQE_VALID(value) (value & 0x8000)<br />+#define CQE_ERR1(value)     (value & 0x7fff)<br />+<br />+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]));<br />+<br />+uint32_t set_reg_8(void *addr, uint8_t val0, uint8_t val1, uint8_t val2,<br />+           uint8_t val3);<br />+uint8_t get_reg_8(void *addr, uint8_t offset);<br />+<br />+int zsda_admin_msg_init(struct rte_pci_device *pci_dev);<br />+int zsda_send_admin_msg(struct rte_pci_device *pci_dev, void *req, uint32_t len);<br />+int zsda_recv_admin_msg(struct rte_pci_device *pci_dev, void *resp,<br />+               uint32_t len);<br />+<br />+void zsda_stats_get(void **queue_pairs, uint32_t nb_queue_pairs,<br />+           struct zsda_common_stat *stats);<br />+void zsda_stats_reset(void **queue_pairs, uint32_t nb_queue_pairs);<br />+<br />+#endif /* _ZSDA_COMMON_H_ */<br />diff --git a/drivers/common/zsda/zsda_device.c b/drivers/common/zsda/zsda_device.c<br />new file mode 100644<br />index 0000000..214c00d<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_device.c<br />@@ -0,0 +1,661 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <ctype.h> <br />+#include <errno.h> <br />+#include <stdint.h> <br />+#include <unistd.h> <br />+<br />+#include <rte_devargs.h> <br />+#include <rte_string_fns.h> <br />+<br />+#include "zsda_device.h" <br />+#include "zsda_qp.h" <br />+<br />+/* per-process array of device data */<br />+struct zsda_device_info zsda_devs[RTE_PMD_ZSDA_MAX_PCI_DEVICES];<br />+static int zsda_nb_pci_devices;<br />+static int zsda_num_used_qps;<br />+#define MAX_EVENT 10<br />+<br />+/*<br />+ * The set of PCI devices this driver supports<br />+ */<br />+static const struct rte_pci_id pci_id_zsda_map[] = {<br />+    {<br />+        RTE_PCI_DEVICE(0x1cf2, 0x8050),<br />+    },<br />+    {<br />+        RTE_PCI_DEVICE(0x1cf2, 0x8051),<br />+    },<br />+    {.device_id = 0},<br />+};<br />+<br />+static int<br />+zsda_check_write(uint8_t *addr, uint32_t dst_value)<br />+{<br />+    int times = 500;<br />+    uint32_t ret = 0;<br />+<br />+    ret = ZSDA_CSR_READ32(addr);<br />+<br />+    while ((ret != dst_value) && times--) {<br />+        ret = ZSDA_CSR_READ32(addr);<br />+        rte_delay_us_sleep(100);<br />+    }<br />+    if (ret == dst_value)<br />+        return ZSDA_SUCCESS;<br />+    else<br />+        return ZSDA_FAILED;<br />+}<br />+<br />+static uint8_t<br />+zsda_get_num_used_qps(const struct rte_pci_device *pci_dev)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t num_used_qps;<br />+    num_used_qps = ZSDA_CSR_READ8(mmio_base + 0);<br />+<br />+    return num_used_qps;<br />+}<br />+<br />+int<br />+zsda_admin_q_start(const struct rte_pci_device *pci_dev)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    int ret = 0;<br />+<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_START, 0);<br />+<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_START, ZSDA_Q_START);<br />+    ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_START, ZSDA_Q_START);<br />+<br />+    return ret;<br />+}<br />+<br />+int<br />+zsda_admin_q_stop(const struct rte_pci_device *pci_dev)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    int ret = 0;<br />+<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_STOP_RESP, ZSDA_RESP_INVALID);<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_STOP, ZSDA_Q_STOP);<br />+<br />+    ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_STOP_RESP,<br />+                   ZSDA_RESP_VALID);<br />+<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(INFO, "Failed! zsda_admin q stop");<br />+        return ZSDA_FAILED;<br />+    }<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+zsda_admin_q_clear(const struct rte_pci_device *pci_dev)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    int ret = 0;<br />+<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_CLR_RESP, ZSDA_RESP_INVALID);<br />+    ZSDA_CSR_WRITE32(mmio_base + ZSDA_ADMIN_Q_CLR, ZSDA_RESP_VALID);<br />+<br />+    ret = zsda_check_write(mmio_base + ZSDA_ADMIN_Q_CLR_RESP,<br />+                   ZSDA_RESP_VALID);<br />+<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(INFO, "Failed! zsda_admin q clear");<br />+        return ZSDA_FAILED;<br />+    }<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+static int<br />+zsda_queue_stop_single(uint8_t *mmio_base, uint8_t id)<br />+{<br />+    int ret = ZSDA_SUCCESS;<br />+    uint8_t *addr_stop = mmio_base + ZSDA_IO_Q_STOP + (4 * id);<br />+    uint8_t *addr_resp = mmio_base + ZSDA_IO_Q_STOP_RESP + (4 * id);<br />+<br />+    ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);<br />+    ZSDA_CSR_WRITE32(addr_stop, ZSDA_Q_STOP);<br />+<br />+    ret = zsda_check_write(addr_resp, ZSDA_RESP_VALID);<br />+    ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);<br />+<br />+    return ret;<br />+}<br />+<br />+int<br />+zsda_queue_stop(const struct rte_pci_device *pci_dev,<br />+        const struct zsda_qp_hw *qp_hw __rte_unused)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t id = 0;<br />+    int ret = ZSDA_SUCCESS;<br />+<br />+    for (id = 0; id < zsda_num_used_qps; id++)<br />+        ret |= zsda_queue_stop_single(mmio_base, id);<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+zsda_queue_start_single(uint8_t *mmio_base, uint8_t id)<br />+{<br />+    uint8_t *addr_start = mmio_base + ZSDA_IO_Q_START + (4 * id);<br />+<br />+    ZSDA_CSR_WRITE32(addr_start, ZSDA_Q_START);<br />+    return zsda_check_write(addr_start, ZSDA_Q_START);<br />+}<br />+<br />+int<br />+zsda_queue_start(const struct rte_pci_device *pci_dev,<br />+         const struct zsda_qp_hw *qp_hw __rte_unused)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t id = 0;<br />+    int ret = ZSDA_SUCCESS;<br />+<br />+    for (id = 0; id < zsda_num_used_qps; id++)<br />+        ret |= zsda_queue_start_single(mmio_base, id);<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+zsda_queue_clear_single(uint8_t *mmio_base, uint8_t id)<br />+{<br />+    int ret = ZSDA_SUCCESS;<br />+    uint8_t *addr_clear = mmio_base + ZSDA_IO_Q_CLR + (4 * id);<br />+    uint8_t *addr_resp = mmio_base + ZSDA_IO_Q_CLR_RESP + (4 * id);<br />+<br />+    ZSDA_CSR_WRITE32(addr_resp, ZSDA_RESP_INVALID);<br />+    ZSDA_CSR_WRITE32(addr_clear, ZSDA_CLEAR_VALID);<br />+    ret = zsda_check_write(addr_resp, ZSDA_RESP_VALID);<br />+    ZSDA_CSR_WRITE32(addr_clear, ZSDA_CLEAR_INVALID);<br />+<br />+    return ret;<br />+}<br />+<br />+int<br />+zsda_queue_clear(const struct rte_pci_device *pci_dev,<br />+         const struct zsda_qp_hw *qp_hw __rte_unused)<br />+{<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t id = 0;<br />+    int ret = ZSDA_SUCCESS;<br />+<br />+    for (id = 0; id < zsda_num_used_qps; id++)<br />+        ret |= zsda_queue_clear_single(mmio_base, id);<br />+<br />+    return ret;<br />+}<br />+<br />+static struct zsda_pci_device *<br />+zsda_pci_get_named_dev(const char *name)<br />+{<br />+    unsigned int i;<br />+<br />+    if (name == NULL) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return NULL;<br />+    }<br />+<br />+    for (i = 0; i < RTE_PMD_ZSDA_MAX_PCI_DEVICES; i++) {<br />+        if (zsda_devs[i].mz && <br />+            (strcmp(((struct zsda_pci_device *)zsda_devs[i].mz->addr)<br />+                    ->name,<br />+                name) == 0))<br />+            return (struct zsda_pci_device *)zsda_devs[i].mz->addr;<br />+    }<br />+<br />+    return NULL;<br />+}<br />+<br />+static uint8_t<br />+zsda_pci_find_free_device_index(void)<br />+{<br />+    uint32_t dev_id;<br />+<br />+    for (dev_id = 0; dev_id < RTE_PMD_ZSDA_MAX_PCI_DEVICES; dev_id++)<br />+        if (zsda_devs[dev_id].mz == NULL)<br />+            break;<br />+<br />+    return dev_id & 0xff;<br />+}<br />+<br />+struct zsda_pci_device *<br />+zsda_get_zsda_dev_from_pci_dev(struct rte_pci_device *pci_dev)<br />+{<br />+    char name[ZSDA_DEV_NAME_MAX_LEN];<br />+<br />+    rte_pci_device_name(&pci_dev->addr, name, sizeof(name));<br />+<br />+    return zsda_pci_get_named_dev(name);<br />+}<br />+<br />+struct zsda_pci_device *<br />+zsda_pci_device_allocate(struct rte_pci_device *pci_dev)<br />+{<br />+    struct zsda_pci_device *zsda_pci_dev;<br />+    uint8_t zsda_dev_id = 0;<br />+    char name[ZSDA_DEV_NAME_MAX_LEN];<br />+<br />+    rte_pci_device_name(&pci_dev->addr, name, sizeof(name));<br />+    snprintf(name + strlen(name), (ZSDA_DEV_NAME_MAX_LEN - strlen(name)),<br />+         "_zsda");<br />+    if (rte_eal_process_type() == RTE_PROC_SECONDARY) {<br />+        const struct rte_memzone *mz = rte_memzone_lookup(name);<br />+<br />+        if (mz == NULL) {<br />+            ZSDA_LOG(ERR, "Secondary can't find %s mz", name);<br />+            return NULL;<br />+        }<br />+        zsda_pci_dev = mz->addr;<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].mz = mz;<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev = pci_dev;<br />+        zsda_nb_pci_devices++;<br />+        return zsda_pci_dev;<br />+    }<br />+<br />+    if (zsda_pci_get_named_dev(name) != NULL) {<br />+        ZSDA_LOG(ERR, E_CONFIG);<br />+        return NULL;<br />+    }<br />+<br />+    zsda_dev_id = zsda_pci_find_free_device_index();<br />+<br />+    if (zsda_dev_id == (RTE_PMD_ZSDA_MAX_PCI_DEVICES - 1)) {<br />+        ZSDA_LOG(ERR, "Reached maximum number of ZSDA devices");<br />+        return NULL;<br />+    }<br />+<br />+    unsigned int socket_id = rte_socket_id();<br />+<br />+    zsda_devs[zsda_dev_id].mz =<br />+        rte_memzone_reserve(name, sizeof(struct zsda_pci_device),<br />+                    (int)(socket_id & 0xfff), 0);<br />+<br />+    if (zsda_devs[zsda_dev_id].mz == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        return NULL;<br />+    }<br />+<br />+    zsda_pci_dev = zsda_devs[zsda_dev_id].mz->addr;<br />+    memset(zsda_pci_dev, 0, sizeof(*zsda_pci_dev));<br />+    strlcpy(zsda_pci_dev->name, name, ZSDA_DEV_NAME_MAX_LEN);<br />+    zsda_pci_dev->zsda_dev_id = zsda_dev_id;<br />+    zsda_pci_dev->pci_dev = pci_dev;<br />+    zsda_devs[zsda_dev_id].pci_dev = pci_dev;<br />+<br />+    switch (pci_dev->id.device_id) {<br />+<br />+    case 0x8000 ... 0x9000:<br />+        break;<br />+<br />+    default:<br />+        ZSDA_LOG(ERR, "Invalid dev_id");<br />+        rte_memzone_free(zsda_devs[zsda_pci_dev->zsda_dev_id].mz);<br />+        return NULL;<br />+    }<br />+<br />+    rte_spinlock_init(&zsda_pci_dev->arb_csr_lock);<br />+    zsda_nb_pci_devices++;<br />+<br />+    return zsda_pci_dev;<br />+}<br />+<br />+static int<br />+zsda_pci_device_release(struct rte_pci_device *pci_dev)<br />+{<br />+    struct zsda_pci_device *zsda_pci_dev;<br />+    struct zsda_device_info *inst;<br />+    char name[ZSDA_DEV_NAME_MAX_LEN];<br />+<br />+    if (pci_dev == NULL)<br />+        return -EINVAL;<br />+<br />+    rte_pci_device_name(&pci_dev->addr, name, sizeof(name));<br />+<br />+    snprintf(name + strlen(name),<br />+         ZSDA_DEV_NAME_MAX_LEN - (strlen(name) - 1), "_zsda");<br />+    zsda_pci_dev = zsda_pci_get_named_dev(name);<br />+    if (zsda_pci_dev != NULL) {<br />+        inst = &zsda_devs[zsda_pci_dev->zsda_dev_id];<br />+<br />+        if (rte_eal_process_type() == RTE_PROC_PRIMARY) {<br />+            if ((zsda_pci_dev->sym_dev != NULL) ||<br />+                (zsda_pci_dev->comp_dev != NULL)) {<br />+                ZSDA_LOG(DEBUG, "ZSDA device %s is busy", name);<br />+                return -EBUSY;<br />+            }<br />+            rte_memzone_free(inst->mz);<br />+        }<br />+        memset(inst, 0, sizeof(struct zsda_device_info));<br />+        zsda_nb_pci_devices--;<br />+    }<br />+    return 0;<br />+}<br />+<br />+static int<br />+zsda_pci_dev_destroy(struct zsda_pci_device *zsda_pci_dev,<br />+             struct rte_pci_device *pci_dev)<br />+{<br />+    zsda_sym_dev_destroy(zsda_pci_dev);<br />+    zsda_comp_dev_destroy(zsda_pci_dev);<br />+<br />+    return zsda_pci_device_release(pci_dev);<br />+}<br />+<br />+static void<br />+zsda_set_queue_head_tail(struct zsda_pci_device *zsda_pci_dev, uint8_t qid)<br />+{<br />+    struct rte_pci_device *pci_dev =<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+<br />+    ZSDA_CSR_WRITE32(mmio_base + IO_DB_INITIAL_CONFIG + (qid * 4),<br />+             SET_HEAD_INTI);<br />+}<br />+<br />+int<br />+zsda_set_queue_cycle(struct zsda_pci_device *zsda_pci_dev, uint8_t qid)<br />+{<br />+    struct zsda_admin_req_qcfg req = {0};<br />+    struct zsda_admin_resp_qcfg resp = {0};<br />+    int ret = 0;<br />+    struct rte_pci_device *pci_dev =<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;<br />+<br />+    zsda_admin_msg_init(pci_dev);<br />+    req.msg_type = ZSDA_ADMIN_SET_CYCLE_REQ;<br />+    req.qid = qid;<br />+    req.data[0] = SET_CYCLE;<br />+    ret = zsda_send_admin_msg(pci_dev, &req, sizeof(req));<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! Send msg");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = zsda_recv_admin_msg(pci_dev, &resp, sizeof(resp));<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! Receive msg");<br />+        return ZSDA_FAILED;<br />+    }<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+zsda_set_cycle_head_tail(struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    struct rte_pci_device *pci_dev =<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;<br />+    uint8_t *mmio_base = pci_dev->mem_resource[0].addr;<br />+    uint8_t id = 0;<br />+    uint8_t num_used_ioqp = ZSDA_CSR_READ8(mmio_base + 0);<br />+    int ret = ZSDA_SUCCESS;<br />+<br />+    for (id = 0; id < num_used_ioqp; id++) {<br />+        zsda_set_queue_head_tail(zsda_pci_dev, id);<br />+        ret |= zsda_set_queue_cycle(zsda_pci_dev, id);<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+enum zsda_service_type<br />+zsda_get_queue_cfg_by_id(struct zsda_pci_device *zsda_pci_dev, uint8_t qid,<br />+             qinfo *qcfg)<br />+{<br />+    struct zsda_admin_req_qcfg req = {0};<br />+    struct zsda_admin_resp_qcfg resp = {0};<br />+    int ret = 0;<br />+    struct rte_pci_device *pci_dev =<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;<br />+<br />+    zsda_admin_msg_init(pci_dev);<br />+    req.msg_type = ZSDA_ADMIN_QUEUE_CFG_REQ;<br />+<br />+    req.qid = qid;<br />+<br />+    ret = zsda_send_admin_msg(pci_dev, &req, sizeof(req));<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! Send msg");<br />+        return ZSDA_SERVICE_INVALID;<br />+    }<br />+<br />+    ret = zsda_recv_admin_msg(pci_dev, &resp, sizeof(resp));<br />+    if (ret)<br />+        ZSDA_LOG(ERR, "Failed! Receive msg");<br />+<br />+    if (resp.msg_type == ZSDA_ADMIN_QUEUE_CFG_RESP) {<br />+        memcpy(qcfg, &resp.qcfg, sizeof(*qcfg));<br />+        return resp.qcfg.q_type;<br />+    }<br />+    return ZSDA_SERVICE_INVALID;<br />+}<br />+<br />+int<br />+zsda_close_flr(const struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    struct zsda_admin_req_qcfg req = {0};<br />+    struct zsda_admin_resp_qcfg resp = {0};<br />+<br />+    int ret = 0;<br />+    struct rte_pci_device *pci_dev =<br />+        zsda_devs[zsda_pci_dev->zsda_dev_id].pci_dev;<br />+<br />+    zsda_admin_msg_init(pci_dev);<br />+<br />+    req.msg_type = ZSDA_FLR_SET_FUNCTION;<br />+<br />+    ret = zsda_send_admin_msg(pci_dev, &req, sizeof(req));<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! Send msg");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = zsda_recv_admin_msg(pci_dev, &resp, sizeof(resp));<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! Receive msg");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+static void<br />+zsda_interrupt_handler(__rte_unused void *param)<br />+{<br />+    return;<br />+}<br />+<br />+static void *<br />+intr_loop(void *dummy)<br />+{<br />+    uint32_t i = 0;<br />+    __rte_unused int n = 0;<br />+    struct rte_epoll_event event[MAX_EVENT];<br />+    uint32_t vector_total = 10;<br />+    struct rte_pci_device *pci_dev = (struct rte_pci_device *)dummy;<br />+    struct rte_intr_handle *intr_handle = pci_dev->intr_handle;<br />+    int ret;<br />+    ret = rte_intr_efd_enable(intr_handle, vector_total);<br />+    if (ret)<br />+        return NULL;<br />+<br />+    ret = rte_intr_callback_register(intr_handle, zsda_interrupt_handler,<br />+                     (void *)0);<br />+    if (ret)<br />+        return NULL;<br />+<br />+    for (i = 0; i < vector_total; ++i) {<br />+        rte_intr_rx_ctl(intr_handle, RTE_EPOLL_PER_THREAD,<br />+                RTE_INTR_EVENT_ADD, i, (void *)&i);<br />+    }<br />+<br />+    ret = rte_intr_enable(intr_handle);<br />+    if (ret != 0)<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+<br />+    while (1) {<br />+        n = rte_epoll_wait(RTE_EPOLL_PER_THREAD, event, MAX_EVENT,<br />+                   3000);<br />+    }<br />+    return NULL;<br />+}<br />+<br />+static void<br />+zsda_hot_unplug_callback(const char *device_name,<br />+             __rte_unused enum rte_dev_event_type type, void *arg)<br />+{<br />+    const struct rte_pci_device *pci_dev = (struct rte_pci_device *)arg;<br />+    const struct zsda_qp_hw *qp_hw = NULL;<br />+    int ret;<br />+<br />+    ret = zsda_queue_clear(pci_dev, qp_hw);<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, "Failed! used zsda_io q clear");<br />+        return;<br />+    }<br />+    ret = zsda_queue_stop(pci_dev, qp_hw);<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, "Failed! used zsda_io q stop");<br />+        return;<br />+    }<br />+<br />+    zsda_admin_q_clear(pci_dev);<br />+    zsda_admin_q_stop(pci_dev);<br />+<br />+    ZSDA_LOG(DEBUG, "The device: %s has been removed!", device_name);<br />+}<br />+<br />+static int<br />+zsda_hot_plug_handler(struct rte_pci_device *pci_dev)<br />+{<br />+    int ret = 0;<br />+<br />+    ret = rte_dev_hotplug_handle_enable();<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Fail to enable hotplug handling.");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = rte_dev_event_monitor_start();<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Fail to start device event monitoring.");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = rte_dev_event_callback_register(NULL, zsda_hot_unplug_callback,<br />+                          (void *)pci_dev);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Fail to register device event callback");<br />+        return ZSDA_FAILED;<br />+    }<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+static int<br />+zsda_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,<br />+           struct rte_pci_device *pci_dev)<br />+{<br />+    int sym_ret = 0;<br />+    int comp_ret = 0;<br />+    int ret;<br />+    pthread_t id;<br />+    struct zsda_pci_device *zsda_pci_dev;<br />+    struct zsda_dev_cmd_param zsda_dev_cmd_param[] = {<br />+        {SYM_ENQ_THRESHOLD_NAME, 0},<br />+        {HASH_ENQ_THRESHOLD_NAME, 0},<br />+        {COMP_ENQ_THRESHOLD_NAME, 0},<br />+        {EC_ENQ_THRESHOLD_NAME, 0},<br />+        {NULL, 0},<br />+    };<br />+<br />+    zsda_pci_dev = zsda_pci_device_allocate(pci_dev);<br />+    if (zsda_pci_dev == NULL) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return -ENODEV;<br />+    }<br />+<br />+    zsda_num_used_qps = zsda_get_num_used_qps(zsda_pci_dev->pci_dev);<br />+<br />+    ret = zsda_admin_q_start(zsda_pci_dev->pci_dev);<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, "Failed! admin q start");<br />+        return ZSDA_FAILED;<br />+    }<br />+    const struct zsda_qp_hw *qp_hw = NULL;<br />+    ret = zsda_queue_clear(zsda_pci_dev->pci_dev, qp_hw);<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, "Failed! used zsda_io q clear");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = zsda_close_flr(zsda_pci_dev);<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, "Failed! flr close");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = zsda_hot_plug_handler(zsda_pci_dev->pci_dev);<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, "Failed! zsda_hot_plug_handler");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    zsda_get_queue_cfg(zsda_pci_dev);<br />+<br />+    sym_ret = zsda_sym_dev_create(zsda_pci_dev, zsda_dev_cmd_param);<br />+    comp_ret = zsda_comp_dev_create(zsda_pci_dev, zsda_dev_cmd_param);<br />+<br />+    if (sym_ret | comp_ret) {<br />+        ZSDA_LOG(ERR, "Failed! dev create");<br />+        zsda_pci_dev_destroy(zsda_pci_dev, pci_dev);<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    ret = pthread_create(&id, NULL, intr_loop, pci_dev);<br />+    if (ret)<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+static int<br />+zsda_pci_remove(struct rte_pci_device *pci_dev)<br />+{<br />+    struct zsda_pci_device *zsda_pci_dev;<br />+<br />+    if (pci_dev == NULL)<br />+        return -EINVAL;<br />+<br />+    zsda_pci_dev = zsda_get_zsda_dev_from_pci_dev(pci_dev);<br />+    if (zsda_pci_dev == NULL)<br />+        return 0;<br />+<br />+    if (zsda_admin_q_clear(zsda_pci_dev->pci_dev) == ZSDA_FAILED)<br />+        ZSDA_LOG(ERR, "Failed! q clear");<br />+<br />+    if (zsda_admin_q_stop(zsda_pci_dev->pci_dev) == ZSDA_FAILED)<br />+        ZSDA_LOG(ERR, "Failed! q stop");<br />+<br />+    return zsda_pci_dev_destroy(zsda_pci_dev, pci_dev);<br />+}<br />+<br />+/* clang-format off */<br />+static struct rte_pci_driver rte_zsda_pmd = {<br />+    .id_table = pci_id_zsda_map,<br />+    .drv_flags = RTE_PCI_DRV_NEED_MAPPING,<br />+    .probe = zsda_pci_probe,<br />+    .remove = zsda_pci_remove };<br />+/* clang-format on */<br />+<br />+RTE_PMD_REGISTER_PCI(ZSDA_PCI_NAME, rte_zsda_pmd);<br />+RTE_PMD_REGISTER_PCI_TABLE(ZSDA_PCI_NAME, pci_id_zsda_map);<br />+RTE_PMD_REGISTER_KMOD_DEP(ZSDA_PCI_NAME,<br />+              "* igb_uio | uio_pci_generic | vfio-pci");<br />diff --git a/drivers/common/zsda/zsda_device.h b/drivers/common/zsda/zsda_device.h<br />new file mode 100644<br />index 0000000..5558506<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_device.h<br />@@ -0,0 +1,207 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_DEVICE_H_<br />+#define _ZSDA_DEVICE_H_<br />+<br />+#include "bus_pci_driver.h" <br />+<br />+#include <rte_bus_pci.h> <br />+#include <rte_io.h> <br />+<br />+#include "zsda_common.h" <br />+#include "zsda_logs.h" <br />+#include "zsda_qp.h" <br />+<br />+#include "dev_driver.h" <br />+<br />+#define ZSDA_DETACHED (0)<br />+#define ZSDA_ATTACHED (1)<br />+<br />+#define MAGIC_FLR_CLR_SUCCESS 0xff<br />+#define MAGIC_FLR_CLR_FAIL    0xfe<br />+#define ZSDA_DEV_NAME_MAX_LEN 64<br />+#define MAX_QPS_ON_FUNCTION   8<br />+#define NUM_QPS              128<br />+<br />+#define SYM_ENQ_THRESHOLD_NAME    "zsda_sym_enq_threshold" <br />+#define HASH_ENQ_THRESHOLD_NAME "zsda_hash_enq_threshold" <br />+#define COMP_ENQ_THRESHOLD_NAME "zsda_comp_enq_threshold" <br />+#define EC_ENQ_THRESHOLD_NAME    "zsda_ec_enq_threshold" <br />+#define MAX_QP_THRESHOLD_SIZE    32<br />+<br />+#define ADMIN_WQ_BASE_ADDR_0 0x40<br />+#define ADMIN_WQ_BASE_ADDR_1 0x44<br />+#define ADMIN_WQ_BASE_ADDR_2 0x48<br />+#define ADMIN_WQ_BASE_ADDR_3 0x4C<br />+#define ADMIN_WQ_BASE_ADDR_4 0x50<br />+#define ADMIN_WQ_BASE_ADDR_5 0x54<br />+#define ADMIN_WQ_BASE_ADDR_6 0x58<br />+#define ADMIN_WQ_BASE_ADDR_7 0x5C<br />+<br />+#define ADMIN_CQ_BASE_ADDR_0 0x60<br />+#define ADMIN_CQ_BASE_ADDR_1 0x64<br />+#define ADMIN_CQ_BASE_ADDR_2 0x68<br />+#define ADMIN_CQ_BASE_ADDR_3 0x6C<br />+#define ADMIN_CQ_BASE_ADDR_4 0x70<br />+#define ADMIN_CQ_BASE_ADDR_5 0x74<br />+#define ADMIN_CQ_BASE_ADDR_6 0x78<br />+#define ADMIN_CQ_BASE_ADDR_7 0x7C<br />+<br />+#define IO_DB_INITIAL_CONFIG 0x1C00<br />+<br />+#define ADMIN_BUF_DATA_LEN  0x1C<br />+#define ADMIN_BUF_TOTAL_LEN 0x20<br />+<br />+#define ZSDA_CSR_VERSION      0x0<br />+#define ZSDA_ADMIN_WQ          0x40<br />+#define ZSDA_ADMIN_WQ_BASE7   0x5C<br />+#define ZSDA_ADMIN_WQ_CRC     0x5C<br />+#define ZSDA_ADMIN_WQ_VERSION 0x5D<br />+#define ZSDA_ADMIN_WQ_FLAG    0x5E<br />+#define ZSDA_ADMIN_CQ          0x60<br />+#define ZSDA_ADMIN_CQ_BASE7   0x7C<br />+#define ZSDA_ADMIN_CQ_CRC     0x7C<br />+#define ZSDA_ADMIN_CQ_VERSION 0x7D<br />+#define ZSDA_ADMIN_CQ_FLAG    0x7E<br />+<br />+#define ZSDA_ADMIN_WQ_TAIL 0x80<br />+#define ZSDA_ADMIN_CQ_HEAD 0x84<br />+<br />+#define ZSDA_ADMIN_Q_START     0x100<br />+#define ZSDA_ADMIN_Q_STOP      0x100<br />+#define ZSDA_ADMIN_Q_STOP_RESP 0x104<br />+#define ZSDA_ADMIN_Q_CLR       0x108<br />+#define ZSDA_ADMIN_Q_CLR_RESP  0x10C<br />+<br />+#define ZSDA_IO_Q_START        0x200<br />+#define ZSDA_IO_Q_STOP        0x200<br />+#define ZSDA_IO_Q_STOP_RESP 0x400<br />+#define ZSDA_IO_Q_CLR        0x600<br />+#define ZSDA_IO_Q_CLR_RESP  0x800<br />+<br />+#define ZSDA_CSR_READ32(addr)          rte_read32((addr))<br />+#define ZSDA_CSR_WRITE32(addr, value) rte_write32((value), (addr))<br />+#define ZSDA_CSR_READ16(addr)          rte_read16((addr))<br />+#define ZSDA_CSR_WRITE16(addr, value) rte_write16((value), (addr))<br />+#define ZSDA_CSR_READ8(addr)          rte_read8((addr))<br />+#define ZSDA_CSR_WRITE8(addr, value)  rte_write8_relaxed((value), (addr))<br />+<br />+struct zsda_dev_cmd_param {<br />+    const char *name;<br />+    uint16_t val;<br />+};<br />+<br />+struct zsda_device_info {<br />+    const struct rte_memzone *mz;<br />+    /**< mz to store the:  struct zsda_pci_device ,    so it can be<br />+     * shared across processes<br />+     */<br />+<br />+    struct rte_pci_device *pci_dev;<br />+<br />+    // struct rte_device sym_rte_dev;<br />+    struct rte_device sym_rte_dev;<br />+    /**< This represents the crypto sym subset of this pci device.<br />+     * Register with this rather than with the one in<br />+     * pci_dev so that its driver can have a crypto-specific name<br />+     */<br />+<br />+    struct rte_device comp_rte_dev;<br />+    /**< This represents the compression subset of this pci device.<br />+     * Register with this rather than with the one in<br />+     * pci_dev so that its driver can have a compression-specific name<br />+     */<br />+};<br />+<br />+extern struct zsda_device_info zsda_devs[];<br />+<br />+struct zsda_sym_dev_private;<br />+struct zsda_comp_dev_private;<br />+<br />+struct zsda_qp_hw {<br />+    struct zsda_qp_hw_data data[MAX_QPS_ON_FUNCTION];<br />+};<br />+<br />+struct zsda_register_opt {<br />+    char op_type;<br />+    uint64_t addr;<br />+    uint32_t data;<br />+};<br />+<br />+/*<br />+ * This struct holds all the data about a ZSDA pci device<br />+ * including data about all services it supports.<br />+ * It contains<br />+ *  - hw_data<br />+ *  - config data<br />+ *  - runtime data<br />+ * Note: as this data can be shared in a multi-process scenario,<br />+ * any pointers in it must also point to shared memory.<br />+ */<br />+struct zsda_pci_device {<br />+    /* Data used by all services */<br />+    char name[ZSDA_DEV_NAME_MAX_LEN];<br />+    /**< Name of zsda pci device */<br />+    uint8_t zsda_dev_id;<br />+    /**< Id of device instance for this zsda pci device */<br />+<br />+    rte_spinlock_t arb_csr_lock;<br />+    /**< lock to protect accesses to the arbiter CSR */<br />+<br />+    struct rte_pci_device *pci_dev;<br />+<br />+    /* Data relating to symmetric crypto service */<br />+    struct zsda_sym_dev_private *sym_dev;<br />+    /**< link back to cryptodev private data */<br />+<br />+    /* Data relating to compression service */<br />+    struct zsda_comp_dev_private *comp_dev;<br />+    /**< link back to compressdev private data */<br />+<br />+    struct zsda_qp_hw zsda_hw_qps[ZSDA_MAX_SERVICES];<br />+    uint16_t zsda_qp_hw_num[ZSDA_MAX_SERVICES];<br />+};<br />+<br />+struct zsda_pci_device *<br />+zsda_pci_device_allocate(struct rte_pci_device *pci_dev);<br />+<br />+struct zsda_pci_device *<br />+zsda_get_zsda_dev_from_pci_dev(struct rte_pci_device *pci_dev);<br />+<br />+__rte_weak int<br />+zsda_sym_dev_create(struct zsda_pci_device *zsda_pci_dev __rte_unused,<br />+            struct zsda_dev_cmd_param *zsda_dev_cmd_param);<br />+<br />+__rte_weak int<br />+zsda_sym_dev_destroy(struct zsda_pci_device *zsda_pci_dev __rte_unused);<br />+<br />+__rte_weak int<br />+zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev __rte_unused,<br />+             struct zsda_dev_cmd_param *zsda_dev_cmd_param);<br />+<br />+__rte_weak int<br />+zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev __rte_unused);<br />+<br />+enum zsda_service_type<br />+zsda_get_queue_cfg_by_id(struct zsda_pci_device *zsda_pci_dev, uint8_t qid,<br />+             qinfo *qcfg);<br />+int zsda_set_queue_cycle(struct zsda_pci_device *zsda_pci_dev, uint8_t qid);<br />+<br />+int zsda_queue_start(const struct rte_pci_device *pci_dev,<br />+             const struct zsda_qp_hw *qp_hw __rte_unused);<br />+int zsda_queue_stop(const struct rte_pci_device *pci_dev,<br />+            const struct zsda_qp_hw *qp_hw __rte_unused);<br />+int zsda_queue_clear(const struct rte_pci_device *pci_dev,<br />+             const struct zsda_qp_hw *qp_hw __rte_unused);<br />+<br />+int zsda_admin_q_start(const struct rte_pci_device *pci_dev);<br />+int zsda_admin_q_stop(const struct rte_pci_device *pci_dev);<br />+int zsda_admin_q_clear(const struct rte_pci_device *pci_dev);<br />+<br />+int zsda_set_cycle_head_tail(struct zsda_pci_device *zsda_pci_dev);<br />+<br />+int zsda_close_flr(const struct zsda_pci_device *zsda_pci_dev);<br />+<br />+#endif /* _ZSDA_DEVICE_H_ */<br />diff --git a/drivers/common/zsda/zsda_logs.c b/drivers/common/zsda/zsda_logs.c<br />new file mode 100644<br />index 0000000..045c168<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_logs.c<br />@@ -0,0 +1,21 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <rte_log.h> <br />+#include <rte_hexdump.h> <br />+<br />+#include "zsda_logs.h" <br />+<br />+int<br />+zsda_hexdump_log(uint32_t level, uint32_t logtype, const char *title,<br />+        const void *buf, unsigned int len)<br />+{<br />+    if (rte_log_can_log(logtype, level))<br />+        rte_hexdump(rte_log_get_stream(), title, buf, len);<br />+<br />+    return 0;<br />+}<br />+<br />+RTE_LOG_REGISTER(zsda_gen_logtype, pmd.zsda_general, NOTICE);<br />+RTE_LOG_REGISTER(zsda_dp_logtype, pmd.zsda_dp, NOTICE);<br />diff --git a/drivers/common/zsda/zsda_logs.h b/drivers/common/zsda/zsda_logs.h<br />new file mode 100644<br />index 0000000..f6b27e2<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_logs.h<br />@@ -0,0 +1,32 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_LOGS_H_<br />+#define _ZSDA_LOGS_H_<br />+<br />+extern int zsda_gen_logtype;<br />+extern int zsda_dp_logtype;<br />+<br />+#define ZSDA_LOG(level, fmt, args...)                                          \<br />+    rte_log(RTE_LOG_##level, (zsda_gen_logtype & 0xff),                    \<br />+        "%s(): [%d] " fmt "\n", __func__, __LINE__, ##args)<br />+<br />+#define ZSDA_DP_LOG(level, fmt, args...)                                       \<br />+    rte_log(RTE_LOG_##level, zsda_dp_logtype, "%s(): " fmt "\n", __func__, \<br />+        ##args)<br />+<br />+#define ZSDA_DP_HEXDUMP_LOG(level, title, buf, len)                            \<br />+    zsda_hexdump_log(RTE_LOG_##level, zsda_dp_logtype, title, buf, len)<br />+<br />+/**<br />+ * zsda_hexdump_log - Dump out memory in a special hex dump format.<br />+ *<br />+ * Dump out the message buffer in a special hex dump output format with<br />+ * characters printed for each line of 16 hex values. The message will be sent<br />+ * to the stream used by the rte_log infrastructure.<br />+ */<br />+int zsda_hexdump_log(uint32_t level, uint32_t logtype, const char *title,<br />+             const void *buf, unsigned int len);<br />+<br />+#endif /* _ZSDA_LOGS_H_ */<br />diff --git a/drivers/common/zsda/zsda_qp.c b/drivers/common/zsda/zsda_qp.c<br />new file mode 100644<br />index 0000000..fb6c638<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_qp.c<br />@@ -0,0 +1,703 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <asm-generic/errno.h> <br />+#include <bits/stdint-uintn.h> <br />+#include <limits.h> <br />+#include <stdint.h> <br />+<br />+#include <rte_atomic.h> <br />+#include <rte_bus_pci.h> <br />+#include <rte_common.h> <br />+#include <rte_cycles.h> <br />+#include <rte_dev.h> <br />+#include <rte_malloc.h> <br />+#include <rte_memzone.h> <br />+#include <rte_pci.h> <br />+#include <rte_prefetch.h> <br />+<br />+#include "zsda_common.h" <br />+#include "zsda_device.h" <br />+#include "zsda_logs.h" <br />+#include "zsda_qp.h" <br />+#include "zsda_sym.h" <br />+<br />+#define ZSDA_MAX_DESC 512<br />+#define MAX_NUM_OPS   0x1FF<br />+<br />+#define RING_DIR_TX 0<br />+#define RING_DIR_RX 1<br />+<br />+struct ring_size {<br />+    uint16_t tx_msg_size;<br />+    uint16_t rx_msg_size;<br />+};<br />+<br />+struct ring_size zsda_qp_hw_ring_size[ZSDA_MAX_SERVICES] = {<br />+    [ZSDA_SERVICE_SYMMETRIC_ENCRYPT] = {128, 16},<br />+    [ZSDA_SERVICE_SYMMETRIC_DECRYPT] = {128, 16},<br />+    [ZSDA_SERVICE_COMPRESSION] = {32, 16},<br />+    [ZSDA_SERVICE_DECOMPRESSION] = {32, 16},<br />+    [ZSDA_SERVICE_HASH_ENCODE] = {32, 16},<br />+};<br />+<br />+void<br />+zsda_get_queue_cfg(struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    uint8_t i = 0;<br />+    uint32_t index = 0;<br />+    enum zsda_service_type type = ZSDA_SERVICE_INVALID;<br />+    struct zsda_qp_hw *zsda_hw_qps = zsda_pci_dev->zsda_hw_qps;<br />+    qinfo qcfg;<br />+<br />+    for (i = 0; i < MAX_QPS_ON_FUNCTION; i++) {<br />+        type = zsda_get_queue_cfg_by_id(zsda_pci_dev, i, &qcfg);<br />+        if (type >= ZSDA_SERVICE_INVALID)<br />+            continue;<br />+<br />+        index = zsda_pci_dev->zsda_qp_hw_num[type];<br />+        zsda_hw_qps[type].data[index].used = 1;<br />+        zsda_hw_qps[type].data[index].tx_ring_num = i;<br />+        zsda_hw_qps[type].data[index].rx_ring_num = i;<br />+        zsda_hw_qps[type].data[index].tx_msg_size =<br />+            zsda_qp_hw_ring_size[type].tx_msg_size;<br />+        zsda_hw_qps[type].data[index].rx_msg_size =<br />+            zsda_qp_hw_ring_size[type].rx_msg_size & 0xffff;<br />+<br />+        zsda_pci_dev->zsda_qp_hw_num[type]++;<br />+    }<br />+}<br />+<br />+struct zsda_qp_hw *<br />+zsda_qps_hw_per_service(struct zsda_pci_device *zsda_pci_dev,<br />+            enum zsda_service_type service)<br />+{<br />+    if (service < ZSDA_SERVICE_INVALID)<br />+        return &(zsda_pci_dev->zsda_hw_qps[service]);<br />+    else {<br />+        ZSDA_LOG(ERR, "Failed! service type is wrong");<br />+        return NULL;<br />+    }<br />+}<br />+<br />+uint16_t<br />+zsda_qps_per_service(struct zsda_pci_device *zsda_pci_dev,<br />+             enum zsda_service_type service)<br />+{<br />+    if (service < ZSDA_SERVICE_INVALID)<br />+        return zsda_pci_dev->zsda_qp_hw_num[service];<br />+    else<br />+        return 0;<br />+}<br />+<br />+uint16_t<br />+zsda_crypto_max_nb_qps(struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    uint16_t encrypt = zsda_qps_per_service(zsda_pci_dev,<br />+                        ZSDA_SERVICE_SYMMETRIC_ENCRYPT);<br />+    uint16_t decrypt = zsda_qps_per_service(zsda_pci_dev,<br />+                        ZSDA_SERVICE_SYMMETRIC_DECRYPT);<br />+    uint16_t hash =<br />+        zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_HASH_ENCODE);<br />+    uint16_t min = 0;<br />+<br />+    if ((encrypt == MAX_QPS_ON_FUNCTION) ||<br />+        (decrypt == MAX_QPS_ON_FUNCTION) ||<br />+        (hash == MAX_QPS_ON_FUNCTION))<br />+        min = MAX_QPS_ON_FUNCTION;<br />+    else {<br />+        min = (encrypt < decrypt) ? encrypt : decrypt;<br />+        min = (min < hash) ? min : hash;<br />+    }<br />+<br />+    if (min == 0)<br />+        return MAX_QPS_ON_FUNCTION;<br />+    return min;<br />+}<br />+<br />+uint16_t<br />+zsda_comp_max_nb_qps(struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    uint16_t comp =<br />+        zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_COMPRESSION);<br />+    uint16_t decomp =<br />+        zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_DECOMPRESSION);<br />+    uint16_t min = 0;<br />+<br />+    if ((comp == MAX_QPS_ON_FUNCTION) ||<br />+        (decomp == MAX_QPS_ON_FUNCTION))<br />+        min = MAX_QPS_ON_FUNCTION;<br />+    else<br />+        min = (comp < decomp) ? comp : decomp;<br />+<br />+    if (min == 0)<br />+        return MAX_QPS_ON_FUNCTION;<br />+    return min;<br />+}<br />+<br />+static const struct rte_memzone *<br />+queue_dma_zone_reserve(const char *queue_name, unsigned int queue_size,<br />+               unsigned int socket_id)<br />+{<br />+    const struct rte_memzone *mz;<br />+<br />+    mz = rte_memzone_lookup(queue_name);<br />+    if (mz != 0) {<br />+        if (((size_t)queue_size <= mz->len) && <br />+            ((socket_id == (SOCKET_ID_ANY & 0xffff)) ||<br />+             (socket_id == (mz->socket_id & 0xffff)))) {<br />+            ZSDA_LOG(DEBUG,<br />+                 "re-use memzone already allocated for %s",<br />+                 queue_name);<br />+            return mz;<br />+        }<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        return NULL;<br />+    }<br />+<br />+    return rte_memzone_reserve_aligned(queue_name, queue_size,<br />+                       (int)(socket_id & 0xfff),<br />+                       RTE_MEMZONE_IOVA_CONTIG, queue_size);<br />+}<br />+<br />+static int<br />+zsda_queue_create(uint32_t dev_id, struct zsda_queue *queue,<br />+          struct zsda_qp_config *qp_conf, uint8_t dir)<br />+{<br />+    void *io_addr;<br />+    const struct rte_memzone *qp_mz;<br />+    qinfo qcfg;<br />+    int ret = 0;<br />+<br />+    uint16_t desc_size = ((dir == RING_DIR_TX) ? qp_conf->hw->tx_msg_size<br />+                           : qp_conf->hw->rx_msg_size);<br />+<br />+    unsigned int queue_size_bytes = qp_conf->nb_descriptors * desc_size;<br />+<br />+    queue->hw_queue_number =<br />+        ((dir == RING_DIR_TX) ? qp_conf->hw->tx_ring_num<br />+                      : qp_conf->hw->rx_ring_num);<br />+<br />+    struct rte_pci_device *pci_dev = zsda_devs[dev_id].pci_dev;<br />+    struct zsda_pci_device *zsda_dev =<br />+        (struct zsda_pci_device *)zsda_devs[dev_id].mz->addr;<br />+<br />+    ret = zsda_set_cycle_head_tail(zsda_dev);<br />+    if (ret == ZSDA_FAILED)<br />+        ZSDA_LOG(ERR, "Failed! set cytcle");<br />+<br />+    zsda_get_queue_cfg_by_id(zsda_dev, queue->hw_queue_number, &qcfg);<br />+<br />+    if (dir == RING_DIR_TX)<br />+        snprintf(queue->memz_name, sizeof(queue->memz_name),<br />+             "%s_%d_%s_%s_%d", pci_dev->driver->driver.name, dev_id,<br />+             qp_conf->service_str, "qptxmem",<br />+             queue->hw_queue_number);<br />+    else<br />+        snprintf(queue->memz_name, sizeof(queue->memz_name),<br />+             "%s_%d_%s_%s_%d", pci_dev->driver->driver.name, dev_id,<br />+             qp_conf->service_str, "qprxmem",<br />+             queue->hw_queue_number);<br />+<br />+    qp_mz = queue_dma_zone_reserve(queue->memz_name, queue_size_bytes,<br />+                       rte_socket_id());<br />+    if (qp_mz == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        return -ENOMEM;<br />+    }<br />+<br />+    queue->base_addr = (uint8_t *)qp_mz->addr;<br />+    queue->base_phys_addr = qp_mz->iova;<br />+    queue->modulo_mask = MAX_NUM_OPS;<br />+    queue->msg_size = desc_size;<br />+<br />+    queue->head = (dir == RING_DIR_TX) ? qcfg.wq_head : qcfg.cq_head;<br />+    queue->tail = (dir == RING_DIR_TX) ? qcfg.wq_tail : qcfg.cq_tail;<br />+<br />+    if ((queue->head == 0) && (queue->tail == 0))<br />+        qcfg.cycle += 1;<br />+<br />+    queue->valid = qcfg.cycle & 0xff;<br />+    queue->queue_size = ZSDA_MAX_DESC;<br />+    queue->io_addr = pci_dev->mem_resource[0].addr;<br />+<br />+    memset(queue->base_addr, 0x0, queue_size_bytes);<br />+<br />+    io_addr = pci_dev->mem_resource[0].addr;<br />+<br />+    if (dir == RING_DIR_TX)<br />+        ZSDA_CSR_WQ_RING_BASE(io_addr, queue->hw_queue_number,<br />+                      queue->base_phys_addr);<br />+    else<br />+        ZSDA_CSR_CQ_RING_BASE(io_addr, queue->hw_queue_number,<br />+                      queue->base_phys_addr);<br />+<br />+    return 0;<br />+}<br />+<br />+static void<br />+zsda_queue_delete(const struct zsda_queue *queue)<br />+{<br />+    const struct rte_memzone *mz;<br />+    int status = 0;<br />+<br />+    if (queue == NULL) {<br />+        ZSDA_LOG(DEBUG, "Invalid queue");<br />+        return;<br />+    }<br />+<br />+    mz = rte_memzone_lookup(queue->memz_name);<br />+    if (mz != NULL) {<br />+        /* Write an unused pattern to the queue memory. */<br />+        memset(queue->base_addr, 0x0,<br />+               (uint16_t)(queue->queue_size * queue->msg_size));<br />+        status = rte_memzone_free(mz);<br />+        if (status != 0)<br />+            ZSDA_LOG(ERR, E_FREE);<br />+    } else<br />+        ZSDA_LOG(DEBUG, "queue %s doesn't exist", queue->memz_name);<br />+}<br />+<br />+static int<br />+cookie_init(uint32_t dev_id, struct zsda_qp **qp_addr, uint16_t queue_pair_id,<br />+        struct zsda_qp_config *zsda_qp_conf)<br />+{<br />+    struct zsda_qp *qp = *qp_addr;<br />+    struct rte_pci_device *pci_dev = zsda_devs[dev_id].pci_dev;<br />+    char op_cookie_pool_name[RTE_RING_NAMESIZE];<br />+    uint32_t i;<br />+    enum zsda_service_type type = zsda_qp_conf->service_type;<br />+<br />+    if (zsda_qp_conf->nb_descriptors != ZSDA_MAX_DESC)<br />+        ZSDA_LOG(ERR, "Can't create qp for %u descriptors",<br />+             zsda_qp_conf->nb_descriptors);<br />+<br />+    qp->srv[type].nb_descriptors = zsda_qp_conf->nb_descriptors;<br />+    qp->srv[type].enqueued = qp->srv[type].dequeued = 0;<br />+<br />+    qp->srv[type].op_cookies = rte_zmalloc_socket(<br />+        "zsda PMD op cookie pointer",<br />+        zsda_qp_conf->nb_descriptors *<br />+            sizeof(*qp->srv[type].op_cookies),<br />+        RTE_CACHE_LINE_SIZE, zsda_qp_conf->socket_id);<br />+<br />+    if (qp->srv[type].op_cookies == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        return -ENOMEM;<br />+    }<br />+<br />+    snprintf(op_cookie_pool_name, RTE_RING_NAMESIZE, "%s%d_cks_%s_qp%hu",<br />+         pci_dev->driver->driver.name, dev_id,<br />+         zsda_qp_conf->service_str, queue_pair_id);<br />+<br />+    qp->srv[type].op_cookie_pool = rte_mempool_lookup(op_cookie_pool_name);<br />+    if (qp->srv[type].op_cookie_pool == NULL)<br />+        qp->srv[type].op_cookie_pool = rte_mempool_create(<br />+            op_cookie_pool_name, qp->srv[type].nb_descriptors,<br />+            zsda_qp_conf->cookie_size, 64, 0, NULL, NULL, NULL,<br />+            NULL, (int)(rte_socket_id() & 0xfff), 0);<br />+    if (!qp->srv[type].op_cookie_pool) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        goto create_err;<br />+    }<br />+<br />+    for (i = 0; i < qp->srv[type].nb_descriptors; i++) {<br />+        if (rte_mempool_get(qp->srv[type].op_cookie_pool,<br />+                    &qp->srv[type].op_cookies[i])) {<br />+            ZSDA_LOG(ERR, "ZSDA PMD Cannot get op_cookie");<br />+            goto create_err;<br />+        }<br />+        memset(qp->srv[type].op_cookies[i], 0,<br />+               zsda_qp_conf->cookie_size);<br />+    }<br />+    return 0;<br />+<br />+create_err:<br />+    if (qp->srv[type].op_cookie_pool)<br />+        rte_mempool_free(qp->srv[type].op_cookie_pool);<br />+    rte_free(qp->srv[type].op_cookies);<br />+<br />+    return -EFAULT;<br />+}<br />+<br />+int<br />+zsda_queue_pair_setup(uint32_t dev_id, struct zsda_qp **qp_addr,<br />+              uint16_t queue_pair_id,<br />+              struct zsda_qp_config *zsda_qp_conf)<br />+{<br />+    struct zsda_qp *qp = *qp_addr;<br />+    struct rte_pci_device *pci_dev = zsda_devs[dev_id].pci_dev;<br />+    int ret = 0;<br />+    enum zsda_service_type type = zsda_qp_conf->service_type;<br />+<br />+    if (type >= ZSDA_SERVICE_INVALID) {<br />+        ZSDA_LOG(ERR, "Failed! servie type");<br />+        return -EINVAL;<br />+    }<br />+<br />+    if (pci_dev->mem_resource[0].addr == NULL) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return -EINVAL;<br />+    }<br />+<br />+    if (zsda_queue_create(dev_id, &(qp->srv[type].tx_q), zsda_qp_conf,<br />+                  RING_DIR_TX) != 0) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        return -EFAULT;<br />+    }<br />+<br />+    if (zsda_queue_create(dev_id, &(qp->srv[type].rx_q), zsda_qp_conf,<br />+                  RING_DIR_RX) != 0) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        zsda_queue_delete(&(qp->srv[type].tx_q));<br />+        return -EFAULT;<br />+    }<br />+<br />+    ret = cookie_init(dev_id, qp_addr, queue_pair_id, zsda_qp_conf);<br />+    if (ret) {<br />+        zsda_queue_delete(&(qp->srv[type].tx_q));<br />+        zsda_queue_delete(&(qp->srv[type].rx_q));<br />+        qp->srv[type].used = 0;<br />+    }<br />+    qp->srv[type].used = 1;<br />+    return ret;<br />+}<br />+<br />+int<br />+zsda_queue_pair_release(struct zsda_qp **qp_addr)<br />+{<br />+    struct zsda_qp *qp = *qp_addr;<br />+    uint32_t i;<br />+    enum zsda_service_type type = 0;<br />+<br />+    if (qp == NULL) {<br />+        ZSDA_LOG(DEBUG, "qp already freed");<br />+        return 0;<br />+    }<br />+<br />+    for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {<br />+        if (qp->srv[type].enqueued != qp->srv[type].dequeued)<br />+            return -EAGAIN;<br />+    }<br />+<br />+    for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {<br />+        if (!qp->srv[type].used)<br />+            continue;<br />+<br />+        zsda_queue_delete(&(qp->srv[type].tx_q));<br />+        zsda_queue_delete(&(qp->srv[type].rx_q));<br />+        qp->srv[type].used = 0;<br />+        for (i = 0; i < qp->srv[type].nb_descriptors; i++)<br />+            rte_mempool_put(qp->srv[type].op_cookie_pool,<br />+                    qp->srv[type].op_cookies[i]);<br />+<br />+        if (qp->srv[type].op_cookie_pool)<br />+            rte_mempool_free(qp->srv[type].op_cookie_pool);<br />+<br />+        rte_free(qp->srv[type].op_cookies);<br />+    }<br />+<br />+    rte_free(qp);<br />+    *qp_addr = NULL;<br />+<br />+    return 0;<br />+}<br />+<br />+int<br />+zsda_fill_sgl_offset(struct rte_mbuf *buf, uint32_t offset,<br />+             struct zsda_sgl *sgl, phys_addr_t sgl_phy_addr,<br />+             uint32_t op_src_dst_length, const uint32_t max_segs)<br />+{<br />+    uint32_t nr = 0;<br />+    uint32_t buffer_len;<br />+<br />+    if (max_segs > (ZSDA_SGL_MAX_NUMBER - 1)) {<br />+        ZSDA_LOG(ERR, "Failed! overflow!");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    for (nr = 0; (buf && (nr < max_segs));) {<br />+        if (offset >= rte_pktmbuf_data_len(buf)) {<br />+            offset -= rte_pktmbuf_data_len(buf);<br />+            buf = buf->next;<br />+            continue;<br />+        }<br />+        memset(&(sgl->buffers[nr]), 0, sizeof(struct zsda_buf));<br />+        if ((nr > 0) && (((nr + 1) % ZSDA_SGL_FRAGMENT_SIZE) == 0) && <br />+            (buf->next != NULL)) {<br />+            sgl->buffers[nr].len = SGL_TYPE_PHYS_ADDR;<br />+            sgl->buffers[nr].addr =<br />+                sgl_phy_addr +<br />+                ((nr + 1) * sizeof(struct zsda_buf));<br />+            sgl->buffers[nr].type = SGL_TYPE_NEXT_LIST;<br />+            ++nr;<br />+            continue;<br />+        }<br />+        sgl->buffers[nr].len =<br />+            rte_pktmbuf_data_len(buf) - (offset & 0xffff);<br />+        sgl->buffers[nr].addr = rte_pktmbuf_iova_offset(buf, offset);<br />+        sgl->buffers[nr].type = SGL_TYPE_PHYS_ADDR;<br />+        buffer_len += sgl->buffers[nr].len;<br />+<br />+        buf = buf->next;<br />+        offset = 0;<br />+        ++nr;<br />+    }<br />+<br />+    if (buffer_len > op_src_dst_length) {<br />+        ZSDA_LOG(ERR, "len wrong! 0x%x != 0x%x", buffer_len,<br />+            op_src_dst_length);<br />+        return -EINVAL;<br />+    }<br />+<br />+    if (nr == 0) {<br />+        ZSDA_LOG(ERR, E_RESULT);<br />+        return -EINVAL;<br />+    }<br />+    sgl->buffers[nr - 1].type = SGL_TYPE_LAST_PHYS_ADDR;<br />+<br />+    if (buf) {<br />+        if (unlikely(buf->next)) {<br />+            if (nr == max_segs) {<br />+                ZSDA_LOG(ERR, "max_segs (%u)", max_segs);<br />+                return -EINVAL;<br />+            }<br />+        }<br />+    }<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+zsda_get_sgl_num(struct zsda_sgl *sgl)<br />+{<br />+    int sgl_num = 0;<br />+<br />+    while (sgl->buffers[sgl_num].type != 1) {<br />+        sgl_num++;<br />+        if (sgl_num >= ZSDA_SGL_MAX_NUMBER)<br />+            return ZSDA_FAILED;<br />+    }<br />+    sgl_num++;<br />+    return sgl_num;<br />+}<br />+<br />+int<br />+find_next_free_cookie(struct zsda_queue *queue, void **op_cookie, uint16_t *idx)<br />+{<br />+    uint16_t old_tail = queue->tail;<br />+    uint16_t tail = queue->tail;<br />+    struct zsda_op_cookie *cookie = NULL;<br />+<br />+    do {<br />+        cookie = (struct zsda_op_cookie *)op_cookie[tail];<br />+        if (!cookie->used) {<br />+            *idx = tail & 0xffff;<br />+            return 0;<br />+        } else if (queue->valid == cookie->valid)<br />+            return -EINVAL;<br />+        tail = zsda_modulo_16(tail++, queue->modulo_mask);<br />+<br />+    } while (old_tail != tail);<br />+<br />+    return -EINVAL;<br />+}<br />+<br />+static int<br />+enqueue(void *op, struct zsda_qp *qp)<br />+{<br />+    uint16_t new_tail;<br />+    enum zsda_service_type type;<br />+    uint16_t num_enqueue;<br />+    uint16_t num_dequeue;<br />+    void **op_cookie;<br />+    int ret = 0;<br />+    register struct zsda_queue *queue;<br />+<br />+    for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {<br />+        if (qp->srv[type].used) {<br />+            if (!qp->srv[type].match(op))<br />+                continue;<br />+<br />+            queue = &qp->srv[type].tx_q;<br />+            num_enqueue = qp->srv[type].enqueued;<br />+            num_dequeue = qp->srv[type].dequeued;<br />+<br />+            if (zsda_modulo_16(num_enqueue - num_dequeue,<br />+                       queue->queue_size - (uint16_t)1) ==<br />+                (queue->queue_size - 1)) {<br />+                ret = -EBUSY;<br />+                break;<br />+            }<br />+            if (queue->pushed_wqe == (queue->queue_size - 1)) {<br />+                ret = -EBUSY;<br />+                break;<br />+            }<br />+<br />+            op_cookie = qp->srv[type].op_cookies;<br />+<br />+            if (find_next_free_cookie(queue, op_cookie,<br />+                          &new_tail)) {<br />+                ret = -EBUSY;<br />+                break;<br />+            }<br />+            ret = qp->srv[type].tx_cb(op, queue, op_cookie,<br />+                          new_tail);<br />+            if (ret)<br />+                break;<br />+            queue->tail = zsda_modulo_16(new_tail + 1,<br />+                             queue->queue_size - 1);<br />+<br />+            if (new_tail > queue->tail)<br />+                queue->valid =<br />+                    zsda_modulo_8(queue->valid + 1, 0xff);<br />+<br />+            qp->srv[type].enqueued++;<br />+            queue->pushed_wqe++;<br />+            break;<br />+        }<br />+    }<br />+<br />+    if (type < ZSDA_SERVICE_INVALID) {<br />+        if (ret)<br />+            qp->srv[type].stats.enqueue_err_count++;<br />+        else<br />+            qp->srv[type].stats.enqueued_count++;<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+void<br />+tx_write_tail(struct zsda_queue *queue)<br />+{<br />+    if (queue->pushed_wqe)<br />+        WRITE_CSR_WQ_TAIL(queue->io_addr, queue->hw_queue_number,<br />+                  queue->tail);<br />+<br />+    queue->pushed_wqe = 0;<br />+}<br />+<br />+uint16_t<br />+zsda_enqueue_op_burst(struct zsda_qp *qp, void **ops, uint16_t nb_ops)<br />+{<br />+    register int ret = -1;<br />+    enum zsda_service_type type = 0;<br />+    uint16_t i = 0;<br />+    uint16_t nb_send = 0;<br />+    void *op;<br />+<br />+    for (i = 0; i < nb_ops; i++) {<br />+        op = ops[i];<br />+        ret = enqueue(op, qp);<br />+        if (ret < 0)<br />+            break;<br />+        nb_send++;<br />+    }<br />+<br />+    for (type = 0; type < ZSDA_SERVICE_INVALID; type++)<br />+        if (qp->srv[type].used)<br />+            tx_write_tail(&qp->srv[type].tx_q);<br />+<br />+    return nb_send;<br />+}<br />+<br />+static void<br />+dequeue(struct qp_srv *srv, void **ops, uint32_t nb_ops, uint32_t *nb)<br />+{<br />+    uint16_t head;<br />+    struct zsda_cqe *cqe = NULL;<br />+    struct zsda_queue *queue = &srv->rx_q;<br />+    struct zsda_op_cookie *cookie = NULL;<br />+<br />+    head = queue->head;<br />+<br />+    while (*nb < nb_ops) {<br />+        cqe = (struct zsda_cqe *)((uint8_t *)queue->base_addr +<br />+                      head * queue->msg_size);<br />+<br />+        if (!CQE_VALID(cqe->err1))<br />+            break;<br />+<br />+        printf("Cqe , opcode - 0x%x, sid - 0x%x, tx_real_length - 0x%x, err0 - 0x%x, err1 - 0x%x\n",<br />+                cqe->op_code, cqe->sid, cqe->tx_real_length, cqe->err0, cqe->err1);<br />+<br />+        if (cqe->sid >= queue->queue_size) {<br />+            head = zsda_modulo_16(head++, queue->modulo_mask);<br />+            break;<br />+        }<br />+        cookie = (struct zsda_op_cookie *)srv->op_cookies[cqe->sid];<br />+<br />+        if (cqe->sid == cookie->sid) {<br />+            ops[*nb] = cookie->op;<br />+        } else {<br />+            ZSDA_LOG(ERR, "unequal");<br />+            srv->stats.dequeue_err_count++;<br />+            break;<br />+        }<br />+<br />+        if (!cookie->used) {<br />+            ZSDA_LOG(DEBUG, "Failed! Cookie unused");<br />+        } else {<br />+            srv->rx_cb(ops[*nb], cqe);<br />+            cookie->used = false;<br />+            (*nb)++;<br />+            srv->dequeued++;<br />+        }<br />+<br />+        memset(cqe, 0x0, sizeof(struct zsda_cqe));<br />+<br />+        head = zsda_modulo_16(head + 1, queue->modulo_mask);<br />+        queue->head = head;<br />+<br />+        WRITE_CSR_CQ_HEAD(queue->io_addr, queue->hw_queue_number, head);<br />+    }<br />+}<br />+<br />+uint16_t<br />+zsda_dequeue_op_burst(struct zsda_qp *qp, void **ops, uint16_t nb_ops)<br />+{<br />+    uint32_t nb = 0;<br />+    uint32_t type = 0;<br />+    struct qp_srv *srv;<br />+<br />+    for (type = 0; type < ZSDA_SERVICE_INVALID; type++) {<br />+        if (!qp->srv[type].used)<br />+            continue;<br />+        srv = &qp->srv[type];<br />+        dequeue(srv, ops, nb_ops, &nb);<br />+        if (nb >= nb_ops)<br />+            return nb_ops;<br />+    }<br />+    return nb;<br />+}<br />+<br />+int<br />+common_setup_qp(uint32_t zsda_dev_id, struct zsda_qp **qp_addr,<br />+        uint16_t queue_pair_id, struct zsda_qp_config *conf)<br />+{<br />+    uint32_t i;<br />+    int ret = 0;<br />+    struct zsda_qp *qp;<br />+<br />+    ret = zsda_queue_pair_setup(zsda_dev_id, qp_addr, queue_pair_id, conf);<br />+    if (ret != 0)<br />+        return ret;<br />+<br />+    qp = (struct zsda_qp *)*qp_addr;<br />+<br />+    for (i = 0; i < qp->srv[conf->service_type].nb_descriptors; i++) {<br />+        struct zsda_op_cookie *cookie =<br />+            qp->srv[conf->service_type].op_cookies[i];<br />+<br />+        cookie->sgl_src_phys_addr =<br />+            rte_mempool_virt2iova(cookie) +<br />+            offsetof(struct zsda_op_cookie, sgl_src);<br />+<br />+        cookie->sgl_dst_phys_addr =<br />+            rte_mempool_virt2iova(cookie) +<br />+            offsetof(struct zsda_op_cookie, sgl_dst);<br />+    }<br />+    return 0;<br />+}<br />diff --git a/drivers/common/zsda/zsda_qp.h b/drivers/common/zsda/zsda_qp.h<br />new file mode 100644<br />index 0000000..f5eba50<br />--- /dev/null<br />+++ b/drivers/common/zsda/zsda_qp.h<br />@@ -0,0 +1,208 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_QP_H_<br />+#define _ZSDA_QP_H_<br />+<br />+#include <rte_bus_pci.h> <br />+<br />+#include "zsda_common.h" <br />+<br />+#define WQ_CSR_LBASE 0x1000<br />+#define WQ_CSR_UBASE 0x1004<br />+#define CQ_CSR_LBASE 0x1400<br />+#define CQ_CSR_UBASE 0x1404<br />+#define WQ_TAIL         0x1800<br />+#define CQ_HEAD         0x1804<br />+<br />+/** Common, i.e. not service-specific, statistics */<br />+struct zsda_common_stats {<br />+    uint64_t enqueued_count;<br />+    /**< Count of all operations enqueued */<br />+    uint64_t dequeued_count;<br />+    /**< Count of all operations dequeued */<br />+<br />+    uint64_t enqueue_err_count;<br />+    /**< Total error count on operations enqueued */<br />+    uint64_t dequeue_err_count;<br />+    /**< Total error count on operations dequeued */<br />+    uint64_t threshold_hit_count;<br />+    /**< Total number of times min qp threshold condition was fulfilled */<br />+};<br />+<br />+/**<br />+ * Structure associated with each queue.<br />+ */<br />+struct zsda_queue {<br />+    char memz_name[RTE_MEMZONE_NAMESIZE];<br />+    uint8_t *io_addr;<br />+    uint8_t *base_addr;       /* Base address */<br />+    rte_iova_t base_phys_addr; /* Queue physical address */<br />+    uint16_t head;           /* Shadow copy of the head */<br />+    uint16_t tail;           /* Shadow copy of the tail */<br />+    uint16_t modulo_mask;<br />+    uint16_t msg_size;<br />+    uint16_t queue_size;<br />+    uint16_t pushed_wqe;<br />+<br />+    uint32_t hw_queue_number;<br />+    uint32_t csr_head; /* last written head value */<br />+    uint32_t csr_tail; /* last written tail value */<br />+<br />+    uint8_t valid;<br />+    uint16_t sid;<br />+    uint16_t enqueued;<br />+    uint16_t dequeued __rte_aligned(4);<br />+};<br />+<br />+typedef void (*rx_callback)(void *op_in, struct zsda_cqe *cqe);<br />+typedef int (*tx_callback)(void *op_in, const struct zsda_queue *queue,<br />+               void **op_cookies, uint16_t new_tail);<br />+typedef int (*srv_match)(void *op_in);<br />+<br />+struct qp_srv {<br />+    uint32_t used;<br />+    struct zsda_queue tx_q;<br />+    struct zsda_queue rx_q;<br />+    rx_callback rx_cb;<br />+    tx_callback tx_cb;<br />+    srv_match match;<br />+    struct zsda_common_stats stats;<br />+    struct rte_mempool *op_cookie_pool;<br />+    void **op_cookies;<br />+    uint16_t nb_descriptors;<br />+    /**< zsda device this qp is on */<br />+    uint16_t enqueued;<br />+    uint16_t dequeued;<br />+};<br />+<br />+struct zsda_qp {<br />+    void *mmap_bar_addr;<br />+    struct qp_srv srv[ZSDA_MAX_SERVICES];<br />+<br />+    uint16_t max_inflights;<br />+    uint16_t min_enq_burst_threshold;<br />+<br />+} __rte_cache_aligned;<br />+<br />+struct zsda_hw_qp {<br />+    void *mmap_bar_addr;<br />+    uint32_t used;<br />+    uint16_t tx_q[2];<br />+    uint16_t rx_q[2];<br />+    enum zsda_service_type service_type;<br />+} __rte_cache_aligned;<br />+<br />+struct zsda_qp_hw_data {<br />+    uint32_t used;<br />+    uint8_t tx_ring_num;<br />+    uint8_t rx_ring_num;<br />+    uint16_t tx_msg_size;<br />+    uint16_t rx_msg_size;<br />+};<br />+<br />+struct zsda_qp_config {<br />+    enum zsda_service_type service_type;<br />+    const struct zsda_qp_hw_data *hw;<br />+    uint32_t nb_descriptors;<br />+    uint32_t cookie_size;<br />+    int socket_id;<br />+    const char *service_str;<br />+};<br />+<br />+struct zsda_qp_hw *zsda_qps_hw_per_service(struct zsda_pci_device *zsda_pci_dev,<br />+                       enum zsda_service_type service);<br />+uint16_t zsda_qps_per_service(struct zsda_pci_device *zsda_pci_dev,<br />+                  enum zsda_service_type service);<br />+<br />+uint16_t zsda_comp_max_nb_qps(struct zsda_pci_device *zsda_pci_dev);<br />+uint16_t zsda_crypto_max_nb_qps(struct zsda_pci_device *zsda_pci_dev);<br />+<br />+void zsda_get_queue_cfg(struct zsda_pci_device *zsda_pci_dev);<br />+<br />+static inline uint32_t<br />+zsda_modulo_32(uint32_t data, uint32_t modulo_mask)<br />+{<br />+    return (data) & (modulo_mask);<br />+}<br />+static inline uint16_t<br />+zsda_modulo_16(uint16_t data, uint16_t modulo_mask)<br />+{<br />+    return (data) & (modulo_mask);<br />+}<br />+static inline uint8_t<br />+zsda_modulo_8(uint8_t data, uint8_t modulo_mask)<br />+{<br />+    return (data) & (modulo_mask);<br />+}<br />+<br />+/* CSR write macro */<br />+#define ZSDA_CSR_WR(csrAddr, csrOffset, val)                                   \<br />+    rte_write32(val, (((uint8_t *)csrAddr) + csrOffset))<br />+#define ZSDA_CSR_WC_WR(csrAddr, csrOffset, val)                                \<br />+    rte_write32_wc(val, (((uint8_t *)csrAddr) + csrOffset))<br />+<br />+/* CSR read macro */<br />+#define ZSDA_CSR_RD(csrAddr, csrOffset)                                        \<br />+    rte_read32((((uint8_t *)csrAddr) + csrOffset))<br />+<br />+#define ZSDA_CSR_WQ_RING_BASE(csr_base_addr, ring, value)                      \<br />+    do {                                                                   \<br />+        uint32_t l_base = 0, u_base = 0;                               \<br />+        l_base = (uint32_t)(value & 0xFFFFFFFF);                       \<br />+        u_base = (uint32_t)((value & 0xFFFFFFFF00000000ULL) >> 32);    \<br />+        ZSDA_CSR_WR(csr_base_addr, (ring << 3) + WQ_CSR_LBASE,         \<br />+                l_base);                                           \<br />+        ZSDA_LOG(INFO, "l_basg - offest:0x%x, value:0x%x",             \<br />+             ((ring << 3) + WQ_CSR_LBASE), l_base);                \<br />+        ZSDA_CSR_WR(csr_base_addr, (ring << 3) + WQ_CSR_UBASE,         \<br />+                u_base);                                           \<br />+        ZSDA_LOG(INFO, "h_base - offest:0x%x, value:0x%x",             \<br />+             ((ring << 3) + WQ_CSR_UBASE), u_base);                \<br />+    } while (0)<br />+<br />+#define ZSDA_CSR_CQ_RING_BASE(csr_base_addr, ring, value)                      \<br />+    do {                                                                   \<br />+        uint32_t l_base = 0, u_base = 0;                               \<br />+        l_base = (uint32_t)(value & 0xFFFFFFFF);                       \<br />+        u_base = (uint32_t)((value & 0xFFFFFFFF00000000ULL) >> 32);    \<br />+        ZSDA_CSR_WR(csr_base_addr, (ring << 3) + CQ_CSR_LBASE,         \<br />+                l_base);                                           \<br />+        ZSDA_CSR_WR(csr_base_addr, (ring << 3) + CQ_CSR_UBASE,         \<br />+                u_base);                                           \<br />+    } while (0)<br />+<br />+#define READ_CSR_WQ_HEAD(csr_base_addr, ring)                                  \<br />+    ZSDA_CSR_RD(csr_base_addr, WQ_TAIL + (ring << 3))<br />+#define WRITE_CSR_WQ_TAIL(csr_base_addr, ring, value)                          \<br />+    ZSDA_CSR_WC_WR(csr_base_addr, WQ_TAIL + (ring << 3), value)<br />+#define READ_CSR_CQ_HEAD(csr_base_addr, ring)                                  \<br />+    ZSDA_CSR_RD(csr_base_addr, WQ_TAIL + (ring << 3))<br />+#define WRITE_CSR_CQ_HEAD(csr_base_addr, ring, value)                          \<br />+    ZSDA_CSR_WC_WR(csr_base_addr, CQ_HEAD + (ring << 3), value)<br />+<br />+#define WRITE_CSR_WQ_HEAD()<br />+<br />+uint16_t zsda_enqueue_op_burst(struct zsda_qp *qp, void **ops, uint16_t nb_ops);<br />+uint16_t zsda_dequeue_op_burst(struct zsda_qp *qp, void **ops, uint16_t nb_ops);<br />+<br />+void tx_write_tail(struct zsda_queue *queue);<br />+int zsda_queue_pair_setup(uint32_t dev_id, struct zsda_qp **qp_addr,<br />+              uint16_t queue_pair_id,<br />+              struct zsda_qp_config *zsda_qp_conf);<br />+<br />+int zsda_queue_pair_release(struct zsda_qp **qp_addr);<br />+int zsda_fill_sgl_offset(struct rte_mbuf *buf, uint32_t offset,<br />+             struct zsda_sgl *sgl, phys_addr_t sgl_phy_addr,<br />+             uint32_t op_src_dst_length, const uint32_t max_segs);<br />+<br />+int zsda_get_sgl_num(struct zsda_sgl *sgl);<br />+int zsda_sgl_opt_addr_lost(struct rte_mbuf *mbuf);<br />+<br />+int find_next_free_cookie(struct zsda_queue *queue, void **op_cookie,<br />+              uint16_t *idx);<br />+int common_setup_qp(uint32_t dev_id, struct zsda_qp **qp_addr,<br />+            uint16_t queue_pair_id, struct zsda_qp_config *conf);<br />+<br />+#endif /* _ZSDA_QP_H_ */<br />diff --git a/drivers/compress/zsda/zsda_comp.c b/drivers/compress/zsda/zsda_comp.c<br />new file mode 100644<br />index 0000000..c13378a<br />--- /dev/null<br />+++ b/drivers/compress/zsda/zsda_comp.c<br />@@ -0,0 +1,273 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <rte_bus_pci.h> <br />+#include <rte_byteorder.h> <br />+#include <rte_common.h> <br />+#include <rte_comp.h> <br />+#include <rte_hexdump.h> <br />+#include <rte_log.h> <br />+#include <rte_malloc.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_memcpy.h> <br />+#include <rte_mempool.h> <br />+#include <rte_memzone.h> <br />+#include <rte_spinlock.h> <br />+<br />+#include "zsda_comp.h" <br />+#include "zsda_comp_pmd.h" <br />+#include "zsda_logs.h" <br />+<br />+int<br />+comp_match(void *op_in)<br />+{<br />+    const struct rte_comp_op *op = (struct rte_comp_op *)op_in;<br />+    const struct zsda_comp_xform *xform =<br />+        (struct zsda_comp_xform *)op->private_xform;<br />+<br />+    if (op->op_type != RTE_COMP_OP_STATELESS)<br />+        return 0;<br />+<br />+    if (xform->type != RTE_COMP_COMPRESS)<br />+        return 0;<br />+<br />+    return 1;<br />+}<br />+<br />+static uint8_t<br />+get_opcode(const struct zsda_comp_xform *xform)<br />+{<br />+    if (xform->type == RTE_COMP_COMPRESS) {<br />+        if (xform->checksum_type == RTE_COMP_CHECKSUM_CRC32)<br />+            return ZSDA_OPC_EC_GZIP;<br />+        if (xform->checksum_type == RTE_COMP_CHECKSUM_ADLER32)<br />+            return ZSDA_OPC_EC_ZLIB;<br />+    }<br />+    if (xform->type == RTE_COMP_DECOMPRESS) {<br />+        if (xform->checksum_type == RTE_COMP_CHECKSUM_CRC32)<br />+            return ZSDA_OPC_DC_GZIP;<br />+        if (xform->checksum_type == RTE_COMP_CHECKSUM_ADLER32)<br />+            return ZSDA_OPC_DC_ZLIB;<br />+    }<br />+<br />+    return ZSDA_OPC_INVALID;<br />+}<br />+<br />+int<br />+build_comp_request(void *op_in, const struct zsda_queue *queue,<br />+           void **op_cookies, uint16_t new_tail)<br />+{<br />+    uint8_t opcode = ZSDA_OPC_INVALID;<br />+    struct rte_comp_op *op = op_in;<br />+    struct zsda_comp_xform *xform =<br />+        (struct zsda_comp_xform *)op->private_xform;<br />+    struct zsda_wqe_comp *wqe =<br />+        (struct zsda_wqe_comp *)(queue->base_addr +<br />+                     (new_tail * queue->msg_size));<br />+<br />+    struct zsda_op_cookie *cookie =<br />+        (struct zsda_op_cookie *)op_cookies[new_tail];<br />+    int ret = 0;<br />+    uint32_t op_src_dst_offset = 0;<br />+    uint32_t op_src_dst_length = 0;<br />+    struct zsda_sgl *sgl_src = (struct zsda_sgl *)&cookie->sgl_src;<br />+    struct zsda_sgl *sgl_dst = (struct zsda_sgl *)&cookie->sgl_dst;<br />+<br />+    if ((op->m_dst == NULL) || (op->m_dst == op->m_src)) {<br />+        ZSDA_LOG(ERR, "Failed! m_dst");<br />+        return -EINVAL;<br />+    }<br />+<br />+    opcode = get_opcode(xform);<br />+    if (opcode == ZSDA_OPC_INVALID) {<br />+        ZSDA_LOG(ERR, E_CONFIG);<br />+        return -EINVAL;<br />+    }<br />+<br />+    op_src_dst_offset = op->src.offset;<br />+    op_src_dst_length = op->m_src->pkt_len - op_src_dst_offset;<br />+    ret = zsda_fill_sgl_offset(op->m_src, op_src_dst_offset, sgl_src,<br />+                   cookie->sgl_src_phys_addr, op_src_dst_length,<br />+                   ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    op_src_dst_offset = op->dst.offset;<br />+    op_src_dst_length = op->m_dst->pkt_len - op_src_dst_offset;<br />+    ret |= zsda_fill_sgl_offset(op->m_dst, op_src_dst_offset, sgl_dst,<br />+                    cookie->sgl_dst_phys_addr,<br />+                    op_src_dst_length, ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+        return -EINVAL;<br />+    }<br />+<br />+    cookie->valid = queue->valid;<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_comp));<br />+    wqe->rx_length = op->m_src->pkt_len - op->src.offset;<br />+    wqe->tx_length = op->m_dst->pkt_len - op->dst.offset;<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = opcode;<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr = cookie->sgl_dst_phys_addr;<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+decomp_match(void *op_in)<br />+{<br />+    const struct rte_comp_op *op = (struct rte_comp_op *)op_in;<br />+    const struct zsda_comp_xform *xform =<br />+        (struct zsda_comp_xform *)op->private_xform;<br />+<br />+    if (op->op_type != RTE_COMP_OP_STATELESS)<br />+        return 0;<br />+<br />+    if (xform->type != RTE_COMP_DECOMPRESS)<br />+        return 0;<br />+    return 1;<br />+}<br />+<br />+int<br />+build_decomp_request(void *op_in, const struct zsda_queue *queue,<br />+             void **op_cookies, uint16_t new_tail)<br />+{<br />+    uint8_t opcode = ZSDA_OPC_INVALID;<br />+    struct rte_comp_op *op = op_in;<br />+    struct zsda_comp_xform *xform =<br />+        (struct zsda_comp_xform *)op->private_xform;<br />+<br />+    struct zsda_wqe_comp *wqe =<br />+        (struct zsda_wqe_comp *)(queue->base_addr +<br />+                     (new_tail * queue->msg_size));<br />+    struct zsda_op_cookie *cookie =<br />+        (struct zsda_op_cookie *)op_cookies[new_tail];<br />+    struct zsda_sgl *sgl_src = (struct zsda_sgl *)&cookie->sgl_src;<br />+    struct zsda_sgl *sgl_dst = (struct zsda_sgl *)&cookie->sgl_dst;<br />+    int ret = 0;<br />+<br />+    uint32_t op_src_dst_offset = 0;<br />+    uint32_t op_src_dst_length = 0;<br />+<br />+    if ((op->m_dst == NULL) || (op->m_dst == op->m_src)) {<br />+        ZSDA_LOG(ERR, "Failed! m_dst");<br />+        return -EINVAL;<br />+    }<br />+<br />+    opcode = get_opcode(xform);<br />+    if (opcode == ZSDA_OPC_INVALID) {<br />+        ZSDA_LOG(ERR, E_CONFIG);<br />+        return -EINVAL;<br />+    }<br />+<br />+    op_src_dst_offset = op->src.offset;<br />+    op_src_dst_length = op->m_src->pkt_len - op_src_dst_offset;<br />+<br />+    ret = zsda_fill_sgl_offset(op->m_src, op_src_dst_offset, sgl_src,<br />+                   cookie->sgl_src_phys_addr, op_src_dst_length,<br />+                   ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    op_src_dst_offset = op->dst.offset;<br />+    op_src_dst_length = op->m_dst->pkt_len - op_src_dst_offset;<br />+<br />+    ret |= zsda_fill_sgl_offset(op->m_dst, op_src_dst_offset, sgl_dst,<br />+                    cookie->sgl_dst_phys_addr,<br />+                    op_src_dst_length, ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+        return -EINVAL;<br />+    }<br />+<br />+    cookie->valid = queue->valid;<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_comp));<br />+<br />+    wqe->rx_length = op->m_src->pkt_len - op->src.offset;<br />+    wqe->tx_length = op->m_dst->pkt_len - op->dst.offset;<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = opcode;<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr = cookie->sgl_dst_phys_addr;<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+unsigned int<br />+zsda_comp_xform_size(void)<br />+{<br />+    return RTE_ALIGN_CEIL(sizeof(struct zsda_comp_xform), 8);<br />+}<br />+<br />+int<br />+zsda_comp_private_xform_create(struct rte_compressdev *dev,<br />+                   const struct rte_comp_xform *xform,<br />+                   void **private_xform)<br />+{<br />+    struct zsda_comp_dev_private *zsda = dev->data->dev_private;<br />+<br />+    if (unlikely(private_xform == NULL)) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return -EINVAL;<br />+    }<br />+    if (unlikely(zsda->xformpool == NULL)) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return -ENOMEM;<br />+    }<br />+    if (rte_mempool_get(zsda->xformpool, private_xform)) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return -ENOMEM;<br />+    }<br />+<br />+    struct zsda_comp_xform *zsda_xform =<br />+        (struct zsda_comp_xform *)*private_xform;<br />+    zsda_xform->type = xform->type;<br />+<br />+    if (zsda_xform->type == RTE_COMP_COMPRESS) {<br />+        zsda_xform->checksum_type = xform->compress.chksum;<br />+        if (xform->compress.deflate.huffman !=<br />+            RTE_COMP_HUFFMAN_DYNAMIC) {<br />+            ZSDA_LOG(ERR, "Huffman code not supported");<br />+            return -ENOTSUP;<br />+        }<br />+    } else {<br />+        zsda_xform->checksum_type = xform->decompress.chksum;<br />+    }<br />+<br />+    if ((zsda_xform->checksum_type != RTE_COMP_CHECKSUM_CRC32) && <br />+        (zsda_xform->checksum_type != RTE_COMP_CHECKSUM_ADLER32))<br />+        return -EINVAL;<br />+<br />+    return 0;<br />+}<br />+<br />+int<br />+zsda_comp_private_xform_free(struct rte_compressdev *dev __rte_unused,<br />+                 void *private_xform)<br />+{<br />+    struct zsda_comp_xform *zsda_xform =<br />+        (struct zsda_comp_xform *)private_xform;<br />+<br />+    if (zsda_xform) {<br />+        memset(zsda_xform, 0, zsda_comp_xform_size());<br />+        struct rte_mempool *mp = rte_mempool_from_obj(zsda_xform);<br />+<br />+        rte_mempool_put(mp, zsda_xform);<br />+        return 0;<br />+    }<br />+    return -EINVAL;<br />+}<br />diff --git a/drivers/compress/zsda/zsda_comp.h b/drivers/compress/zsda/zsda_comp.h<br />new file mode 100644<br />index 0000000..5a91a5e<br />--- /dev/null<br />+++ b/drivers/compress/zsda/zsda_comp.h<br />@@ -0,0 +1,34 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_COMP_H_<br />+#define _ZSDA_COMP_H_<br />+<br />+#include <rte_compressdev.h> <br />+#include <rte_compressdev_pmd.h> <br />+<br />+#include "zsda_common.h" <br />+#include "zsda_device.h" <br />+#include "zsda_qp.h" <br />+<br />+struct zsda_comp_xform {<br />+    enum rte_comp_xform_type type;<br />+    enum rte_comp_checksum_type checksum_type;<br />+};<br />+<br />+int comp_match(void *op_in);<br />+int build_comp_request(void *op_in, const struct zsda_queue *queue,<br />+               void **op_cookies, uint16_t new_tail);<br />+int decomp_match(void *op_in);<br />+int build_decomp_request(void *op_in, const struct zsda_queue *queue,<br />+             void **op_cookies, uint16_t new_tail);<br />+int zsda_comp_private_xform_create(struct rte_compressdev *dev,<br />+                   const struct rte_comp_xform *xform,<br />+                   void **private_xform);<br />+<br />+int zsda_comp_private_xform_free(struct rte_compressdev *dev __rte_unused,<br />+                 void *private_xform);<br />+unsigned int zsda_comp_xform_size(void);<br />+<br />+#endif<br />diff --git a/drivers/compress/zsda/zsda_comp_pmd.c b/drivers/compress/zsda/zsda_comp_pmd.c<br />new file mode 100644<br />index 0000000..5b48153<br />--- /dev/null<br />+++ b/drivers/compress/zsda/zsda_comp_pmd.c<br />@@ -0,0 +1,430 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <rte_malloc.h> <br />+<br />+#include "zsda_comp.h" <br />+#include "zsda_comp_pmd.h" <br />+<br />+static const struct rte_compressdev_capabilities zsda_comp_capabilities[] = {<br />+    {<br />+        .algo = RTE_COMP_ALGO_DEFLATE,<br />+        .comp_feature_flags = RTE_COMP_FF_HUFFMAN_DYNAMIC |<br />+                      RTE_COMP_FF_OOP_SGL_IN_SGL_OUT |<br />+                      RTE_COMP_FF_OOP_SGL_IN_LB_OUT |<br />+                      RTE_COMP_FF_OOP_LB_IN_SGL_OUT |<br />+                      RTE_COMP_FF_CRC32_CHECKSUM |<br />+                      RTE_COMP_FF_ADLER32_CHECKSUM,<br />+        .window_size = {.min = 15, .max = 15, .increment = 0},<br />+    },<br />+    {<br />+        RTE_COMP_ALGO_LIST_END,<br />+        0,<br />+        {0, 0, 0},<br />+    },<br />+};<br />+<br />+static void<br />+zsda_comp_stats_get(struct rte_compressdev *dev,<br />+            struct rte_compressdev_stats *stats)<br />+{<br />+    struct zsda_common_stat comm = {0};<br />+<br />+    zsda_stats_get(dev->data->queue_pairs, dev->data->nb_queue_pairs,<br />+               &comm);<br />+    stats->enqueued_count = comm.enqueued_count;<br />+    stats->dequeued_count = comm.dequeued_count;<br />+    stats->enqueue_err_count = comm.enqueue_err_count;<br />+    stats->dequeue_err_count = comm.dequeue_err_count;<br />+}<br />+<br />+static void<br />+zsda_comp_stats_reset(struct rte_compressdev *dev)<br />+{<br />+    zsda_stats_reset(dev->data->queue_pairs, dev->data->nb_queue_pairs);<br />+}<br />+<br />+static int<br />+zsda_comp_qp_release(struct rte_compressdev *dev, uint16_t queue_pair_id)<br />+{<br />+    return zsda_queue_pair_release(<br />+        (struct zsda_qp **)&(dev->data->queue_pairs[queue_pair_id]));<br />+}<br />+<br />+static void<br />+comp_callbak(void *op, struct zsda_cqe *cqe)<br />+{<br />+    struct rte_comp_op *tmp_op = (struct rte_comp_op *)op;<br />+<br />+    tmp_op->produced = cqe->tx_real_length;<br />+<br />+    if (cqe->err0 || CQE_ERR1(cqe->err1))<br />+        tmp_op->status = RTE_COMP_OP_STATUS_ERROR;<br />+    else<br />+        tmp_op->status = RTE_COMP_OP_STATUS_SUCCESS;<br />+}<br />+<br />+static int<br />+setup_comp_queue(struct zsda_pci_device *zsda_pci_dev, uint16_t qp_id,<br />+         struct zsda_qp *qp, uint32_t nb_des, int socket_id)<br />+{<br />+    enum zsda_service_type type = ZSDA_SERVICE_COMPRESSION;<br />+    struct zsda_qp_config conf;<br />+    int ret = 0;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(zsda_pci_dev, type);<br />+    conf.hw = qp_hw->data + qp_id;<br />+    conf.service_type = type;<br />+    conf.cookie_size = sizeof(struct zsda_op_cookie);<br />+    conf.nb_descriptors = nb_des;<br />+    conf.socket_id = socket_id;<br />+    conf.service_str = "comp";<br />+<br />+    ret = common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />+    qp->srv[type].rx_cb = comp_callbak;<br />+    qp->srv[type].tx_cb = build_comp_request;<br />+    qp->srv[type].match = comp_match;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+setup_decomp_queue(struct zsda_pci_device *zsda_pci_dev, uint16_t qp_id,<br />+           struct zsda_qp *qp, uint32_t nb_des, int socket_id)<br />+{<br />+    enum zsda_service_type type = ZSDA_SERVICE_DECOMPRESSION;<br />+    struct zsda_qp_config conf;<br />+    int ret = 0;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(zsda_pci_dev, type);<br />+    conf.hw = qp_hw->data + qp_id;<br />+    conf.service_type = type;<br />+    conf.cookie_size = sizeof(struct zsda_op_cookie);<br />+    conf.nb_descriptors = nb_des;<br />+    conf.socket_id = socket_id;<br />+    conf.service_str = "decomp";<br />+<br />+    ret = common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />+    qp->srv[type].rx_cb = comp_callbak;<br />+    qp->srv[type].tx_cb = build_decomp_request;<br />+    qp->srv[type].match = decomp_match;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+zsda_comp_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,<br />+           uint32_t max_inflight_ops, int socket_id)<br />+{<br />+    int ret = 0;<br />+    struct zsda_qp *qp_new;<br />+<br />+    struct zsda_qp **qp_addr =<br />+        (struct zsda_qp **)&(dev->data->queue_pairs[qp_id]);<br />+    struct zsda_comp_dev_private *comp_priv = dev->data->dev_private;<br />+    struct zsda_pci_device *zsda_pci_dev = comp_priv->zsda_pci_dev;<br />+    uint16_t num_qps_comp =<br />+        zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_COMPRESSION);<br />+    uint16_t num_qps_decomp =<br />+        zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_DECOMPRESSION);<br />+    uint32_t nb_des = max_inflight_ops;<br />+<br />+    nb_des = (nb_des == NB_DES) ? nb_des : NB_DES;<br />+<br />+    if (*qp_addr != NULL) {<br />+        ret = zsda_comp_qp_release(dev, qp_id);<br />+        if (ret < 0)<br />+            return ret;<br />+    }<br />+<br />+    qp_new = rte_zmalloc_socket("zsda PMD qp metadata", sizeof(*qp_new),<br />+                    RTE_CACHE_LINE_SIZE, socket_id);<br />+    if (qp_new == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        return -ENOMEM;<br />+    }<br />+<br />+    if (num_qps_comp == MAX_QPS_ON_FUNCTION)<br />+        ret |= setup_comp_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                    socket_id);<br />+    else if (num_qps_decomp == MAX_QPS_ON_FUNCTION)<br />+        ret |= setup_decomp_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                      socket_id);<br />+    else {<br />+        ret |= setup_comp_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                    socket_id);<br />+        ret |= setup_decomp_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                      socket_id);<br />+    }<br />+<br />+    if (ret) {<br />+        rte_free(qp_new);<br />+        return ret;<br />+    }<br />+<br />+    qp_new->mmap_bar_addr =<br />+        comp_priv->zsda_pci_dev->pci_dev->mem_resource[0].addr;<br />+    *qp_addr = qp_new;<br />+<br />+    return ret;<br />+}<br />+<br />+static struct rte_mempool *<br />+zsda_comp_create_xform_pool(struct zsda_comp_dev_private *comp_dev,<br />+                struct rte_compressdev_config *config,<br />+                uint32_t num_elements)<br />+{<br />+    char xform_pool_name[RTE_MEMPOOL_NAMESIZE];<br />+    struct rte_mempool *mp;<br />+<br />+    snprintf(xform_pool_name, RTE_MEMPOOL_NAMESIZE, "%s_xforms",<br />+         comp_dev->zsda_pci_dev->name);<br />+<br />+    ZSDA_LOG(DEBUG, "xformpool: %s", xform_pool_name);<br />+    mp = rte_mempool_lookup(xform_pool_name);<br />+<br />+    if (mp != NULL) {<br />+        ZSDA_LOG(DEBUG, "xformpool already created");<br />+        if (mp->size != num_elements) {<br />+            ZSDA_LOG(DEBUG, "xformpool wrong size - delete it");<br />+            rte_mempool_free(mp);<br />+            mp = NULL;<br />+            comp_dev->xformpool = NULL;<br />+        }<br />+    }<br />+<br />+    if (mp == NULL)<br />+        mp = rte_mempool_create(xform_pool_name, num_elements,<br />+                    zsda_comp_xform_size(), 0, 0, NULL,<br />+                    NULL, NULL, NULL, config->socket_id, 0);<br />+    if (mp == NULL) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        return NULL;<br />+    }<br />+<br />+    return mp;<br />+}<br />+<br />+static int<br />+zsda_comp_dev_close(struct rte_compressdev *dev)<br />+{<br />+    int ret = 0;<br />+    uint16_t i = 0;<br />+    struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;<br />+<br />+    for (i = 0; i < dev->data->nb_queue_pairs; i++) {<br />+        ret = zsda_comp_qp_release(dev, i);<br />+        if (ret < 0)<br />+            return ret;<br />+    }<br />+<br />+    rte_mempool_free(comp_dev->xformpool);<br />+    comp_dev->xformpool = NULL;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+zsda_comp_dev_config(struct rte_compressdev *dev,<br />+             struct rte_compressdev_config *config)<br />+{<br />+    struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;<br />+<br />+    if (config->max_nb_priv_xforms) {<br />+        comp_dev->xformpool = zsda_comp_create_xform_pool(<br />+            comp_dev, config, config->max_nb_priv_xforms);<br />+        if (comp_dev->xformpool == NULL)<br />+            return -ENOMEM;<br />+    } else<br />+        comp_dev->xformpool = NULL;<br />+<br />+    return 0;<br />+}<br />+<br />+static int<br />+zsda_comp_dev_start(struct rte_compressdev *dev)<br />+{<br />+    struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+    int ret = 0;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(comp_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_COMPRESSION);<br />+    ret = zsda_queue_start(comp_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+    qp_hw = zsda_qps_hw_per_service(comp_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_DECOMPRESSION);<br />+    ret |= zsda_queue_start(comp_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, E_START_Q);<br />+        return ZSDA_FAILED;<br />+    }<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+static void<br />+zsda_comp_dev_stop(struct rte_compressdev *dev)<br />+{<br />+    struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(comp_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_COMPRESSION);<br />+    zsda_queue_stop(comp_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+    qp_hw = zsda_qps_hw_per_service(comp_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_DECOMPRESSION);<br />+    zsda_queue_stop(comp_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+}<br />+<br />+static void<br />+zsda_comp_dev_info_get(struct rte_compressdev *dev,<br />+               struct rte_compressdev_info *info)<br />+{<br />+    struct zsda_comp_dev_private *comp_dev = dev->data->dev_private;<br />+<br />+    if (info != NULL) {<br />+        info->max_nb_queue_pairs =<br />+            zsda_comp_max_nb_qps(comp_dev->zsda_pci_dev);<br />+        info->feature_flags = dev->feature_flags;<br />+        info->capabilities = comp_dev->zsda_dev_capabilities;<br />+    }<br />+}<br />+<br />+static uint16_t<br />+zsda_comp_pmd_enqueue_op_burst(void *qp, struct rte_comp_op **ops,<br />+                   uint16_t nb_ops)<br />+{<br />+    return zsda_enqueue_op_burst((struct zsda_qp *)qp, (void **)ops,<br />+                     nb_ops);<br />+}<br />+<br />+static uint16_t<br />+zsda_comp_pmd_dequeue_op_burst(void *qp, struct rte_comp_op **ops,<br />+                   uint16_t nb_ops)<br />+{<br />+    return zsda_dequeue_op_burst((struct zsda_qp *)qp, (void **)ops,<br />+                     nb_ops);<br />+}<br />+<br />+static struct rte_compressdev_ops compress_zsda_ops = {<br />+<br />+    .dev_configure = zsda_comp_dev_config,<br />+    .dev_start = zsda_comp_dev_start,<br />+    .dev_stop = zsda_comp_dev_stop,<br />+    .dev_close = zsda_comp_dev_close,<br />+    .dev_infos_get = zsda_comp_dev_info_get,<br />+<br />+    .stats_get = zsda_comp_stats_get,<br />+    .stats_reset = zsda_comp_stats_reset,<br />+    .queue_pair_setup = zsda_comp_qp_setup,<br />+    .queue_pair_release = zsda_comp_qp_release,<br />+<br />+    .private_xform_create = zsda_comp_private_xform_create,<br />+    .private_xform_free = zsda_comp_private_xform_free};<br />+<br />+/* An rte_driver is needed in the registration of the device with compressdev.<br />+ * The actual zsda pci's rte_driver can't be used as its name represents<br />+ * the whole pci device with all services. Think of this as a holder for a name<br />+ * for the compression part of the pci device.<br />+ */<br />+static const char zsda_comp_drv_name[] = RTE_STR(COMPRESSDEV_NAME_ZSDA_PMD);<br />+static const struct rte_driver compdev_zsda_driver = {<br />+    .name = zsda_comp_drv_name, .alias = zsda_comp_drv_name};<br />+<br />+int<br />+zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev,<br />+             __rte_unused struct zsda_dev_cmd_param *zsda_dev_cmd_param)<br />+{<br />+    struct zsda_device_info *dev_info =<br />+        &zsda_devs[zsda_pci_dev->zsda_dev_id];<br />+<br />+    struct rte_compressdev_pmd_init_params init_params = {<br />+        .name = "",<br />+        .socket_id = rte_socket_id(),<br />+    };<br />+<br />+    char name[RTE_COMPRESSDEV_NAME_MAX_LEN];<br />+    char capa_memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];<br />+    struct rte_compressdev *compressdev;<br />+    struct zsda_comp_dev_private *comp_dev;<br />+    const struct rte_compressdev_capabilities *capabilities;<br />+    uint64_t capa_size = sizeof(struct rte_compressdev_capabilities);<br />+<br />+    snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",<br />+         zsda_pci_dev->name, "comp");<br />+<br />+    if (rte_eal_process_type() != RTE_PROC_PRIMARY)<br />+        return 0;<br />+<br />+    dev_info->comp_rte_dev.driver = &compdev_zsda_driver;<br />+    dev_info->comp_rte_dev.numa_node = dev_info->pci_dev->device.numa_node;<br />+    dev_info->comp_rte_dev.devargs = NULL;<br />+<br />+    compressdev = rte_compressdev_pmd_create(<br />+        name, &(dev_info->comp_rte_dev),<br />+        sizeof(struct zsda_comp_dev_private), &init_params);<br />+<br />+    if (compressdev == NULL)<br />+        return -ENODEV;<br />+<br />+    compressdev->dev_ops = &compress_zsda_ops;<br />+<br />+    compressdev->enqueue_burst = zsda_comp_pmd_enqueue_op_burst;<br />+    compressdev->dequeue_burst = zsda_comp_pmd_dequeue_op_burst;<br />+<br />+    compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;<br />+<br />+    snprintf(capa_memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN,<br />+         "ZSDA_COMP_CAPA");<br />+<br />+    comp_dev = compressdev->data->dev_private;<br />+    comp_dev->zsda_pci_dev = zsda_pci_dev;<br />+    comp_dev->compressdev = compressdev;<br />+    capabilities = zsda_comp_capabilities;<br />+<br />+    comp_dev->capa_mz = rte_memzone_lookup(capa_memz_name);<br />+    if (comp_dev->capa_mz == NULL) {<br />+        comp_dev->capa_mz = rte_memzone_reserve(<br />+            capa_memz_name, capa_size, rte_socket_id(), 0);<br />+    }<br />+    if (comp_dev->capa_mz == NULL) {<br />+        ZSDA_LOG(DEBUG, E_MALLOC);<br />+        memset(&dev_info->comp_rte_dev, 0,<br />+               sizeof(dev_info->comp_rte_dev));<br />+        rte_compressdev_pmd_destroy(compressdev);<br />+        return -EFAULT;<br />+    }<br />+<br />+    memcpy(comp_dev->capa_mz->addr, capabilities, capa_size);<br />+    comp_dev->zsda_dev_capabilities = comp_dev->capa_mz->addr;<br />+<br />+    zsda_pci_dev->comp_dev = comp_dev;<br />+<br />+    return 0;<br />+}<br />+<br />+int<br />+zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    struct zsda_comp_dev_private *comp_dev;<br />+<br />+    if (zsda_pci_dev == NULL)<br />+        return -ENODEV;<br />+<br />+    comp_dev = zsda_pci_dev->comp_dev;<br />+    if (comp_dev == NULL)<br />+        return 0;<br />+<br />+    if (rte_eal_process_type() == RTE_PROC_PRIMARY)<br />+        rte_memzone_free(zsda_pci_dev->comp_dev->capa_mz);<br />+<br />+    zsda_comp_dev_close(comp_dev->compressdev);<br />+<br />+    rte_compressdev_pmd_destroy(comp_dev->compressdev);<br />+    zsda_pci_dev->comp_dev = NULL;<br />+<br />+    return 0;<br />+}<br />diff --git a/drivers/compress/zsda/zsda_comp_pmd.h b/drivers/compress/zsda/zsda_comp_pmd.h<br />new file mode 100644<br />index 0000000..46e39f5<br />--- /dev/null<br />+++ b/drivers/compress/zsda/zsda_comp_pmd.h<br />@@ -0,0 +1,42 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_COMP_PMD_H_<br />+#define _ZSDA_COMP_PMD_H_<br />+<br />+#include <rte_compressdev.h> <br />+#include <rte_compressdev_pmd.h> <br />+<br />+/**< ZSDA Compression PMD driver name */<br />+#define COMPRESSDEV_NAME_ZSDA_PMD compress_zsda<br />+<br />+/** private data structure for a ZSDA compression device.<br />+ * This ZSDA device is a device offering only a compression service,<br />+ * there can be one of these on each zsda_pci_device (VF).<br />+ */<br />+struct zsda_comp_dev_private {<br />+    struct zsda_pci_device *zsda_pci_dev;<br />+    /**< The zsda pci device hosting the service */<br />+    struct rte_compressdev *compressdev;<br />+    /**< The pointer to this compression device structure */<br />+    const struct rte_compressdev_capabilities *zsda_dev_capabilities;<br />+    /* ZSDA device compression capabilities */<br />+    const struct rte_memzone *interm_buff_mz;<br />+    /**< The device's memory for intermediate buffers */<br />+    struct rte_mempool *xformpool;<br />+    /**< The device's pool for zsda_comp_xforms */<br />+    struct rte_mempool *streampool;<br />+    /**< The device's pool for zsda_comp_streams */<br />+    const struct rte_memzone *capa_mz;<br />+    /* Shared memzone for storing capabilities */<br />+    uint16_t min_enq_burst_threshold;<br />+};<br />+<br />+int zsda_comp_dev_create(<br />+    struct zsda_pci_device *zsda_pci_dev,<br />+    __rte_unused struct zsda_dev_cmd_param *zsda_dev_cmd_param);<br />+<br />+int zsda_comp_dev_destroy(struct zsda_pci_device *zsda_pci_dev);<br />+<br />+#endif /* _ZSDA_COMP_PMD_H_ */<br />diff --git a/drivers/crypto/zsda/meson.build b/drivers/crypto/zsda/meson.build<br />new file mode 100644<br />index 0000000..58a701c<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/meson.build<br />@@ -0,0 +1,26 @@<br />+# SPDX-License-Identifier: BSD-3-Clause<br />+# Copyright(c) 2017-2018 Intel Corporation<br />+<br />+dep = dependency('libcrypto', required: false, method: 'pkg-config')<br />+if not dep.found()<br />+    build = false<br />+    reason = 'missing dependency, "libcrypto"' <br />+endif<br />+<br />+headers = files(<br />+    'zsda_sym_capabilities.h',<br />+    'zsda_sym_pmd.h',<br />+    'zsda_sym.h' <br />+)<br />+<br />+<br />+sources = files('zsda_sym_pmd.c',<br />+                 'zsda_sym.c',<br />+)<br />+<br />+<br />+<br />+<br />+<br />+<br />+<br />diff --git a/drivers/crypto/zsda/version.map b/drivers/crypto/zsda/version.map<br />new file mode 100644<br />index 0000000..2a95c45<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/version.map<br />@@ -0,0 +1,6 @@<br />+DPDK_21 {<br />+    global:<br />+<br />+<br />+    local: *;<br />+};<br />diff --git a/drivers/crypto/zsda/zsda_sym.c b/drivers/crypto/zsda/zsda_sym.c<br />new file mode 100644<br />index 0000000..2cff408<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/zsda_sym.c<br />@@ -0,0 +1,734 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <rte_bus_pci.h> <br />+#include <rte_byteorder.h> <br />+#include <rte_crypto_sym.h> <br />+#include <rte_hexdump.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_mempool.h> <br />+<br />+#include "zsda_logs.h" <br />+#include "zsda_sym.h" <br />+<br />+/**************** AES KEY EXPANSION ****************/<br />+/**<br />+ * AES S-boxes<br />+ * Sbox table: 8bits input convert to 8bits output<br />+ **/<br />+static const unsigned char aes_sbox[256] = {<br />+    // 0     1    2      3     4    5     6     7      8    9     A      B<br />+    // C     D     E     F<br />+    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,<br />+    0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,<br />+    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,<br />+    0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,<br />+    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,<br />+    0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,<br />+    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,<br />+    0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,<br />+    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,<br />+    0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,<br />+    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,<br />+    0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,<br />+    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,<br />+    0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,<br />+    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,<br />+    0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,<br />+    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,<br />+    0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,<br />+    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,<br />+    0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,<br />+    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,<br />+    0xb0, 0x54, 0xbb, 0x16};<br />+<br />+/**<br />+ * The round constant word array, Rcon[i]<br />+ *<br />+ * From Wikipedia's article on the Rijndael key schedule @<br />+ * https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon "Only the first some<br />+ * of these constants are actually used â€“ up to rcon[10] for AES-128 (as 11<br />+ * round keys are needed), up to rcon[8] for AES-192, up to rcon[7] for AES-256.<br />+ * rcon[0] is not used in AES algorithm." <br />+ */<br />+static const unsigned char Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,<br />+                       0x20, 0x40, 0x80, 0x1b, 0x36};<br />+<br />+#define GET_AES_SBOX_VAL(num) (aes_sbox[(num)])<br />+<br />+/**************** SM4 KEY EXPANSION ****************/<br />+/*<br />+ * 32-bit integer manipulation macros (big endian)<br />+ */<br />+#ifndef GET_ULONG_BE<br />+#define GET_ULONG_BE(n, b, i)                                                  \<br />+    {                                                                      \<br />+        (n) = ((unsigned int)(b)[(i)] << 24) |                         \<br />+              ((unsigned int)(b)[(i) + 1] << 16) |                     \<br />+              ((unsigned int)(b)[(i) + 2] << 8) |                      \<br />+              ((unsigned int)(b)[(i) + 3]);                            \<br />+    }<br />+#endif<br />+<br />+#ifndef PUT_ULONG_BE<br />+#define PUT_ULONG_BE(n, b, i)                                                  \<br />+    {                                                                      \<br />+        (b)[(i)] = (unsigned char)((n) >> 24);                         \<br />+        (b)[(i) + 1] = (unsigned char)((n) >> 16);                     \<br />+        (b)[(i) + 2] = (unsigned char)((n) >> 8);                      \<br />+        (b)[(i) + 3] = (unsigned char)((n));                           \<br />+    }<br />+#endif<br />+<br />+/**<br />+ *rotate shift left marco definition<br />+ *<br />+ **/<br />+#define SHL(x, n)  (((x) & 0xFFFFFFFF) << n)<br />+#define ROTL(x, n) (SHL((x), n) | ((x) >> (32 - n)))<br />+<br />+/**<br />+ * SM4 S-boxes<br />+ * Sbox table: 8bits input convert to 8 bitg288s output<br />+ **/<br />+static const unsigned char sm4_sbox[16][16] = {<br />+    {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2,<br />+     0x28, 0xfb, 0x2c, 0x05},<br />+    {0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26,<br />+     0x49, 0x86, 0x06, 0x99},<br />+    {0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43,<br />+     0xed, 0xcf, 0xac, 0x62},<br />+    {0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa,<br />+     0x75, 0x8f, 0x3f, 0xa6},<br />+    {0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19,<br />+     0xe6, 0x85, 0x4f, 0xa8},<br />+    {0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b,<br />+     0x70, 0x56, 0x9d, 0x35},<br />+    {0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b,<br />+     0x01, 0x21, 0x78, 0x87},<br />+    {0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7,<br />+     0xa0, 0xc4, 0xc8, 0x9e},<br />+    {0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce,<br />+     0xf9, 0x61, 0x15, 0xa1},<br />+    {0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30,<br />+     0xf5, 0x8c, 0xb1, 0xe3},<br />+    {0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab,<br />+     0x0d, 0x53, 0x4e, 0x6f},<br />+    {0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72,<br />+     0x6d, 0x6c, 0x5b, 0x51},<br />+    {0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41,<br />+     0x1f, 0x10, 0x5a, 0xd8},<br />+    {0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12,<br />+     0xb8, 0xe5, 0xb4, 0xb0},<br />+    {0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09,<br />+     0xc5, 0x6e, 0xc6, 0x84},<br />+    {0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e,<br />+     0xd7, 0xcb, 0x39, 0x48},<br />+};<br />+<br />+/* System parameter */<br />+static const unsigned int FK[4] = {0xa3b1bac6, 0x56aa3350, 0x677d9197,<br />+                   0xb27022dc};<br />+<br />+/* fixed parameter */<br />+static const unsigned int CK[32] = {<br />+    0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1,<br />+    0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,<br />+    0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1,<br />+    0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,<br />+    0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41,<br />+    0x484f565d, 0x646b7279};<br />+<br />+/*<br />+ * private function:<br />+ * look up in SM4 S-boxes and get the related value.<br />+ * args:    [in] inch: 0x00~0xFF (8 bits unsigned value).<br />+ */<br />+static unsigned char<br />+sm4Sbox(unsigned char inch)<br />+{<br />+    unsigned char *pTable = (unsigned char *)sm4_sbox;<br />+    unsigned char retVal = (unsigned char)(pTable[inch]);<br />+    return retVal;<br />+}<br />+<br />+/* private function:<br />+ * Calculating round encryption key.<br />+ * args:    [in] ka: ka is a 32 bits unsigned value;<br />+ * return:  sk[i]: i{0,1,2,3,...31}.<br />+ */<br />+static unsigned int<br />+sm4CalciRK(unsigned int ka)<br />+{<br />+    unsigned int bb = 0;<br />+    unsigned int rk = 0;<br />+    unsigned char a[4];<br />+    unsigned char b[4];<br />+<br />+    PUT_ULONG_BE(ka, a, 0)<br />+    b[0] = sm4Sbox(a[0]);<br />+    b[1] = sm4Sbox(a[1]);<br />+    b[2] = sm4Sbox(a[2]);<br />+    b[3] = sm4Sbox(a[3]);<br />+    GET_ULONG_BE(bb, b, 0)<br />+    rk = bb ^ (ROTL(bb, 13)) ^ (ROTL(bb, 23));<br />+    return rk;<br />+}<br />+<br />+static void<br />+zsda_sm4_key_expansion(unsigned int SK[32], const uint8_t key[16])<br />+{<br />+    unsigned int MK[4];<br />+    unsigned int k[36];<br />+    unsigned int i = 0;<br />+<br />+    GET_ULONG_BE(MK[0], key, 0);<br />+    GET_ULONG_BE(MK[1], key, 4);<br />+    GET_ULONG_BE(MK[2], key, 8);<br />+    GET_ULONG_BE(MK[3], key, 12);<br />+    k[0] = MK[0] ^ FK[0];<br />+    k[1] = MK[1] ^ FK[1];<br />+    k[2] = MK[2] ^ FK[2];<br />+    k[3] = MK[3] ^ FK[3];<br />+    for (; i < 32; i++) {<br />+        k[i + 4] = k[i] ^<br />+               (sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i]));<br />+        SK[i] = k[i + 4];<br />+    }<br />+}<br />+<br />+static void<br />+u32_to_u8(uint32_t *u_int32_t_data, uint8_t *u8_data)<br />+{<br />+    *(u8_data + 0) = ((*u_int32_t_data & 0xFF000000) >> 24) & (0xFF);<br />+    *(u8_data + 1) = ((*u_int32_t_data & 0x00FF0000) >> 16) & (0xFF);<br />+    *(u8_data + 2) = ((*u_int32_t_data & 0x0000FF00) >> 8) & (0xFF);<br />+    *(u8_data + 3) = (*u_int32_t_data & 0x000000FF);<br />+}<br />+<br />+static void<br />+zsda_aes_key_expansion(uint8_t *round_key, uint32_t round_num,<br />+               const uint8_t *key, uint32_t key_len)<br />+{<br />+    uint32_t i, j, k, nk, nr;<br />+    uint8_t tempa[4];<br />+<br />+    nk = key_len >> 2;<br />+    nr = round_num;<br />+<br />+    // The first round key is the key itself.<br />+    for (i = 0; i < nk; ++i) {<br />+        round_key[(i * 4) + 0] = key[(i * 4) + 0];<br />+<br />+        round_key[(i * 4) + 1] = key[(i * 4) + 1];<br />+<br />+        round_key[(i * 4) + 2] = key[(i * 4) + 2];<br />+        round_key[(i * 4) + 3] = key[(i * 4) + 3];<br />+    }<br />+<br />+    // All other round keys are found from the previous round keys.<br />+    for (i = nk; i < (4 * (nr + 1)); ++i) {<br />+        k = (i - 1) * 4;<br />+        tempa[0] = round_key[k + 0];<br />+        tempa[1] = round_key[k + 1];<br />+        tempa[2] = round_key[k + 2];<br />+        tempa[3] = round_key[k + 3];<br />+<br />+        if ((nk != 0) && ((i % nk) == 0)) {<br />+            // This function shifts the 4 bytes in a word to the<br />+            // left once. [a0,a1,a2,a3] becomes [a1,a2,a3,a0]<br />+            // Function RotWord()<br />+            {<br />+                const u_int8_t u8tmp = tempa[0];<br />+<br />+                tempa[0] = tempa[1];<br />+                tempa[1] = tempa[2];<br />+                tempa[2] = tempa[3];<br />+                tempa[3] = u8tmp;<br />+            }<br />+<br />+            // SubWord() is a function that takes a four-byte input<br />+            // word and applies the S-box to each of the four bytes<br />+            // to produce an output word. Function Subword()<br />+            {<br />+                tempa[0] = GET_AES_SBOX_VAL(tempa[0]);<br />+                tempa[1] = GET_AES_SBOX_VAL(tempa[1]);<br />+                tempa[2] = GET_AES_SBOX_VAL(tempa[2]);<br />+                tempa[3] = GET_AES_SBOX_VAL(tempa[3]);<br />+            }<br />+<br />+            tempa[0] = tempa[0] ^ Rcon[i / nk];<br />+        }<br />+<br />+        if (nk == 8) {<br />+            if ((i % nk) == 4) {<br />+                // Function Subword()<br />+                {<br />+                    tempa[0] = GET_AES_SBOX_VAL(tempa[0]);<br />+                    tempa[1] = GET_AES_SBOX_VAL(tempa[1]);<br />+                    tempa[2] = GET_AES_SBOX_VAL(tempa[2]);<br />+                    tempa[3] = GET_AES_SBOX_VAL(tempa[3]);<br />+                }<br />+            }<br />+        }<br />+<br />+        j = i * 4;<br />+        k = (i - nk) * 4;<br />+        round_key[j + 0] = round_key[k + 0] ^ tempa[0];<br />+        round_key[j + 1] = round_key[k + 1] ^ tempa[1];<br />+        round_key[j + 2] = round_key[k + 2] ^ tempa[2];<br />+        round_key[j + 3] = round_key[k + 3] ^ tempa[3];<br />+    }<br />+}<br />+<br />+static void<br />+reverse_memcpy(uint8_t *restrict dst, const uint8_t *restrict src, size_t n)<br />+{<br />+    size_t i;<br />+<br />+    for (i = 0; i < n; ++i)<br />+        dst[n - 1 - i] = src[i];<br />+}<br />+<br />+static uint8_t<br />+get_opcode_hash(struct rte_crypto_op *op)<br />+{<br />+    if ((op->sym->xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) && <br />+        (op->sym->xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE)) {<br />+        switch (op->sym->xform->auth.algo) {<br />+        case RTE_CRYPTO_AUTH_SHA1:<br />+            return ZSDA_OPC_HASH_SHA1;<br />+<br />+        case RTE_CRYPTO_AUTH_SHA224:<br />+            return ZSDA_OPC_HASH_SHA2_224;<br />+<br />+        case RTE_CRYPTO_AUTH_SHA256:<br />+            return ZSDA_OPC_HASH_SHA2_256;<br />+<br />+        case RTE_CRYPTO_AUTH_SHA384:<br />+            return ZSDA_OPC_HASH_SHA2_384;<br />+<br />+        case RTE_CRYPTO_AUTH_SHA512:<br />+            return ZSDA_OPC_HASH_SHA2_512;<br />+<br />+        case RTE_CRYPTO_AUTH_SM3:<br />+            return ZSDA_OPC_HASH_SM3;<br />+        default:<br />+            break;<br />+        }<br />+    }<br />+<br />+    return ZSDA_OPC_INVALID;<br />+}<br />+<br />+static uint8_t<br />+get_opcode_crypto(struct rte_crypto_op *op)<br />+{<br />+    if (op->sym->xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {<br />+        if ((op->sym->xform->cipher.algo ==<br />+             RTE_CRYPTO_CIPHER_AES_XTS) && <br />+            (op->sym->xform->cipher.key.length == 32))<br />+            return ZSDA_OPC_EC_AES_XTS_256;<br />+        else if ((op->sym->xform->cipher.algo ==<br />+              RTE_CRYPTO_CIPHER_AES_XTS) && <br />+             (op->sym->xform->cipher.key.length == 64))<br />+            return ZSDA_OPC_EC_AES_XTS_512;<br />+        else if ((op->sym->xform->cipher.algo ==<br />+              RTE_CRYPTO_CIPHER_SM4_XTS) && <br />+             (op->sym->xform->cipher.key.length == 32))<br />+            return ZSDA_OPC_EC_SM4_XTS_256;<br />+    } else if (op->sym->xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {<br />+        if ((op->sym->xform->cipher.algo ==<br />+             RTE_CRYPTO_CIPHER_AES_XTS) && <br />+            (op->sym->xform->cipher.key.length == 32))<br />+            return ZSDA_OPC_DC_AES_XTS_256;<br />+        else if ((op->sym->xform->cipher.algo ==<br />+              RTE_CRYPTO_CIPHER_AES_XTS) && <br />+             (op->sym->xform->cipher.key.length == 64))<br />+            return ZSDA_OPC_DC_AES_XTS_512;<br />+        else if ((op->sym->xform->cipher.algo ==<br />+              RTE_CRYPTO_CIPHER_SM4_XTS) && <br />+             (op->sym->xform->cipher.key.length == 32))<br />+            return ZSDA_OPC_DC_SM4_XTS_256;<br />+    }<br />+<br />+    return ZSDA_OPC_INVALID;<br />+}<br />+<br />+static uint32_t<br />+get_hash_dst_len(uint32_t opcode)<br />+{<br />+    switch (opcode) {<br />+    case ZSDA_OPC_HASH_SHA1:<br />+        return ZSDA_DIGEST_SIZE_SHA1;<br />+    case ZSDA_OPC_HASH_SHA2_224:<br />+        return ZSDA_DIGEST_SIZE_SHA2_224;<br />+    case ZSDA_OPC_HASH_SHA2_256:<br />+        return ZSDA_DIGEST_SIZE_SHA2_256;<br />+    case ZSDA_OPC_HASH_SHA2_384:<br />+        return ZSDA_DIGEST_SIZE_SHA2_384;<br />+    case ZSDA_OPC_HASH_SHA2_512:<br />+        return ZSDA_DIGEST_SIZE_SHA2_512;<br />+    case ZSDA_OPC_HASH_SM3:<br />+        return ZSDA_DIGEST_SIZE_SM3;<br />+    default:<br />+        return ZSDA_OPC_INVALID;<br />+    }<br />+}<br />+<br />+static void<br />+check_len_lbads(uint32_t data_len, uint32_t lbads_size)<br />+{<br />+    if (data_len < 16)<br />+        ZSDA_LOG(WARNING, W_MAY_EXCEPT_TEST);<br />+    if (lbads_size != 0) {<br />+        if (!(((data_len % lbads_size) == 0) ||<br />+              ((data_len % lbads_size) > LBADS_MAX_REMAINDER))) {<br />+            ZSDA_LOG(WARNING, W_MAY_EXCEPT_TEST);<br />+        }<br />+    }<br />+}<br />+<br />+static uint8_t<br />+zsda_sym_lbads(uint32_t dataunit_len, uint32_t data_len)<br />+{<br />+    uint8_t lbads;<br />+<br />+    switch (dataunit_len) {<br />+    case ZSDA_AES_LBADS_512:<br />+        lbads = ZSDA_AES_LBADS_INDICATE_512;<br />+        check_len_lbads(data_len, ZSDA_AES_LBADS_512);<br />+        break;<br />+<br />+    case ZSDA_AES_LBADS_4096:<br />+        lbads = ZSDA_AES_LBADS_INDICATE_4096;<br />+        check_len_lbads(data_len, ZSDA_AES_LBADS_4096);<br />+        break;<br />+<br />+    case ZSDA_AES_LBADS_8192:<br />+        lbads = ZSDA_AES_LBADS_INDICATE_8192;<br />+        check_len_lbads(data_len, ZSDA_AES_LBADS_8192);<br />+        break;<br />+<br />+    case ZSDA_AES_LBADS_0:<br />+        lbads = ZSDA_AES_LBADS_INDICATE_0;<br />+        check_len_lbads(data_len, ZSDA_AES_LBADS_0);<br />+        break;<br />+<br />+    default:<br />+        ZSDA_LOG(ERR, "dataunit_len should be 0/512/4096/8192 - %d.",<br />+             dataunit_len);<br />+        lbads = ZSDA_AES_LBADS_INDICATE_INVALID;<br />+        break;<br />+    }<br />+    return lbads;<br />+}<br />+<br />+int<br />+encry_match(void *op_in)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+<br />+    if (op->sym->xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER)<br />+        return 0;<br />+    if (op->sym->xform->cipher.op != RTE_CRYPTO_CIPHER_OP_ENCRYPT)<br />+        return 0;<br />+<br />+    return 1;<br />+}<br />+<br />+int<br />+build_encry_request(void *op_in, const struct zsda_queue *queue,<br />+            void **op_cookies, uint16_t new_tail)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+    struct zsda_wqe_crpt *wqe =<br />+        (struct zsda_wqe_crpt *)(queue->base_addr +<br />+                     (new_tail * queue->msg_size));<br />+    struct zsda_op_cookie *cookie =<br />+        (struct zsda_op_cookie *)op_cookies[new_tail];<br />+    struct zsda_sgl *sgl_src = (struct zsda_sgl *)&cookie->sgl_src;<br />+    struct zsda_sgl *sgl_dst = (struct zsda_sgl *)&cookie->sgl_dst;<br />+<br />+    int ret = 0;<br />+    uint32_t op_src_dst_offset = 0;<br />+    uint32_t op_src_dst_length = 0;<br />+    uint8_t skey_len = 0;<br />+<br />+    if ((op->sym->m_dst == NULL) || (op->sym->m_dst == op->sym->m_src)) {<br />+        ZSDA_LOG(ERR, "Failed! m_dst");<br />+        return -EINVAL;<br />+    }<br />+<br />+    op_src_dst_offset = op->sym->cipher.data.offset;<br />+    op_src_dst_length = op->sym->m_src->pkt_len - op_src_dst_offset;<br />+    ret = zsda_fill_sgl_offset(op->sym->m_src, op_src_dst_offset, sgl_src,<br />+                   cookie->sgl_src_phys_addr, op_src_dst_length,<br />+                   ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    op_src_dst_length = op->sym->m_dst->pkt_len - op_src_dst_offset;<br />+    ret |= zsda_fill_sgl_offset(op->sym->m_dst, op_src_dst_offset, sgl_dst,<br />+                    cookie->sgl_dst_phys_addr,<br />+                    op_src_dst_length, ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+        return -EINVAL;<br />+    }<br />+<br />+    cookie->valid = queue->valid;<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_crpt));<br />+    wqe->rx_length = op->sym->m_src->pkt_len - op_src_dst_offset;<br />+    wqe->tx_length = op->sym->m_dst->pkt_len - op_src_dst_offset;<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = get_opcode_crypto(op);<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr = cookie->sgl_dst_phys_addr;<br />+<br />+    wqe->cfg.lbads = zsda_sym_lbads(op->sym->xform->cipher.dataunit_len,<br />+                    wqe->rx_length);<br />+    if (wqe->cfg.lbads == ZSDA_AES_LBADS_INDICATE_INVALID) {<br />+        ZSDA_LOG(ERR, E_CONFIG);<br />+        return ZSDA_FAILED;<br />+    }<br />+    /* clang-format off */<br />+    reverse_memcpy((uint8_t *restrict) wqe->cfg.slba,<br />+               (const uint8_t *restrict)rte_crypto_op_ctod_offset(<br />+                   op, char *, op->sym->xform->cipher.iv.offset) +<br />+                   ZSDA_SYM_XTS_IV_SLBA_OFF,<br />+               sizeof(wqe->cfg.slba));<br />+<br />+    skey_len = (op->sym->xform->cipher.key.length / 2) & 0xff;<br />+    if (skey_len == ZSDA_SYM_XTS_256_SKEY_LEN) {<br />+        reverse_memcpy((uint8_t *restrict)(wqe->cfg.key +<br />+                            ZSDA_SYM_XTS_256_KEY2_OFF),<br />+                   (op->sym->xform->cipher.key.data + skey_len),<br />+                   skey_len);<br />+        reverse_memcpy((uint8_t *restrict)(wqe->cfg.key +<br />+                            ZSDA_SYM_XTS_256_KEY1_OFF),<br />+                   op->sym->xform->cipher.key.data, skey_len);<br />+    } else<br />+        reverse_memcpy((uint8_t *restrict) wqe->cfg.key,<br />+                   op->sym->xform->cipher.key.data,<br />+                   op->sym->xform->cipher.key.length);<br />+    /* clang-format on */<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+decry_match(void *op_in)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+<br />+    if (op->sym->xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER)<br />+        return 0;<br />+    if (op->sym->xform->cipher.op != RTE_CRYPTO_CIPHER_OP_DECRYPT)<br />+        return 0;<br />+<br />+    return 1;<br />+}<br />+<br />+static void<br />+decry_set_key(uint8_t key[64], const uint8_t *key1_ptr, uint8_t skey_len,<br />+          struct rte_crypto_op *op)<br />+{<br />+    uint8_t round_num;<br />+    uint8_t dec_key1[ZSDA_AES_MAX_KEY_BYTE_LEN] = {0};<br />+    uint8_t aes_round_key[ZSDA_AES_MAX_EXP_BYTE_SIZE] = {0};<br />+    uint32_t sm4_round_key[ZSDA_SM4_MAX_EXP_DWORD_SIZE] = {0};<br />+<br />+    switch (op->sym->xform->cipher.algo) {<br />+    case RTE_CRYPTO_CIPHER_AES_XTS:<br />+        round_num = (skey_len == ZSDA_SYM_XTS_256_SKEY_LEN)<br />+                    ? ZSDA_AES256_ROUND_NUM<br />+                    : ZSDA_AES512_ROUND_NUM;<br />+        zsda_aes_key_expansion(aes_round_key, round_num, key1_ptr,<br />+                       skey_len);<br />+        rte_memcpy(dec_key1, (aes_round_key + (16 * round_num)), 16);<br />+        if (skey_len > ZSDA_SYM_XTS_256_SKEY_LEN)<br />+            rte_memcpy((dec_key1 + 16),<br />+                   (aes_round_key + (16 * round_num) -<br />+                    (skey_len - 16)),<br />+                   skey_len - 16);<br />+        break;<br />+    case RTE_CRYPTO_CIPHER_SM4_XTS:<br />+        zsda_sm4_key_expansion(sm4_round_key, key1_ptr);<br />+        for (size_t i = 0; i < 4; i++)<br />+            u32_to_u8(sm4_round_key + ZSDA_SM4_MAX_EXP_DWORD_SIZE -<br />+                      1 - i,<br />+                  dec_key1 + (4 * i));<br />+        break;<br />+    default:<br />+        ZSDA_LOG(ERR, "unknow cipher algo!");<br />+        return;<br />+    }<br />+<br />+    if (skey_len == ZSDA_SYM_XTS_256_SKEY_LEN) {<br />+        reverse_memcpy(key + ZSDA_SYM_XTS_256_KEY2_OFF,<br />+                   key1_ptr + skey_len, skey_len);<br />+        reverse_memcpy(key + ZSDA_SYM_XTS_256_KEY1_OFF, dec_key1,<br />+                   skey_len);<br />+    } else {<br />+        reverse_memcpy(key, key1_ptr + skey_len, skey_len);<br />+        reverse_memcpy(key + ZSDA_SYM_XTS_512_KEY1_OFF, dec_key1,<br />+                   skey_len);<br />+    }<br />+}<br />+<br />+int<br />+build_decry_request(void *op_in, const struct zsda_queue *queue,<br />+            void **op_cookies, uint16_t new_tail)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+    struct zsda_wqe_crpt *wqe =<br />+        (struct zsda_wqe_crpt *)(queue->base_addr +<br />+                     (new_tail * queue->msg_size));<br />+    struct zsda_op_cookie *cookie =<br />+        (struct zsda_op_cookie *)op_cookies[new_tail];<br />+    struct zsda_sgl *sgl_src = (struct zsda_sgl *)&cookie->sgl_src;<br />+    struct zsda_sgl *sgl_dst = (struct zsda_sgl *)&cookie->sgl_dst;<br />+<br />+    uint32_t op_src_dst_offset = 0;<br />+    uint32_t op_src_dst_length = 0;<br />+    uint8_t skey_len = 0;<br />+    const uint8_t *key1_ptr = NULL;<br />+    int ret = 0;<br />+<br />+    if ((op->sym->m_dst == NULL) || (op->sym->m_dst == op->sym->m_src)) {<br />+        ZSDA_LOG(ERR, "Failed! m_dst");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    op_src_dst_offset = op->sym->cipher.data.offset;<br />+    op_src_dst_length = op->sym->m_src->pkt_len - op_src_dst_offset;<br />+    ret = zsda_fill_sgl_offset(op->sym->m_src, op_src_dst_offset, sgl_src,<br />+                   cookie->sgl_src_phys_addr, op_src_dst_length,<br />+                   ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    op_src_dst_length = op->sym->m_dst->pkt_len - op_src_dst_offset;<br />+    ret |= zsda_fill_sgl_offset(op->sym->m_dst, op_src_dst_offset, sgl_dst,<br />+                    cookie->sgl_dst_phys_addr,<br />+                    op_src_dst_length, ZSDA_SGL_MAX_NUMBER - 1);<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    cookie->valid = queue->valid;<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_crpt));<br />+    wqe->rx_length = op->sym->m_src->pkt_len - op_src_dst_offset;<br />+    wqe->tx_length = op->sym->m_dst->pkt_len - op_src_dst_offset;<br />+<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = get_opcode_crypto(op);<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr = cookie->sgl_dst_phys_addr;<br />+<br />+    wqe->cfg.lbads = zsda_sym_lbads(op->sym->xform->cipher.dataunit_len,<br />+                    wqe->rx_length);<br />+    if (wqe->cfg.lbads == ZSDA_AES_LBADS_INDICATE_INVALID)<br />+        return ZSDA_FAILED;<br />+<br />+    /* clang-format off */<br />+    reverse_memcpy((uint8_t *restrict)wqe->cfg.slba,<br />+               (uint8_t *restrict)rte_crypto_op_ctod_offset(<br />+                   op, char *, op->sym->xform->cipher.iv.offset) +<br />+                   ZSDA_SYM_XTS_IV_SLBA_OFF,<br />+               sizeof(wqe->cfg.slba));<br />+    /* clang-format on */<br />+<br />+    skey_len = (op->sym->xform->cipher.key.length / 2) & 0xff;<br />+    key1_ptr = op->sym->xform->cipher.key.data;<br />+<br />+    decry_set_key(wqe->cfg.key, key1_ptr, skey_len, op);<br />+    return ZSDA_SUCCESS;<br />+}<br />+<br />+int<br />+hash_match(void *op_in)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+<br />+    if (op->sym->xform->type != RTE_CRYPTO_SYM_XFORM_AUTH)<br />+        return 0;<br />+    if (op->sym->xform->auth.op != RTE_CRYPTO_AUTH_OP_GENERATE)<br />+        return 0;<br />+<br />+    return 1;<br />+}<br />+<br />+int<br />+build_hash_request(void *op_in, const struct zsda_queue *queue,<br />+           void **op_cookies, uint16_t new_tail)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+    struct zsda_wqe_crpt *wqe =<br />+        (struct zsda_wqe_crpt *)(queue->base_addr +<br />+                     (new_tail * queue->msg_size));<br />+    struct zsda_op_cookie *cookie =<br />+        (struct zsda_op_cookie *)op_cookies[new_tail];<br />+    struct zsda_sgl *sgl_src = (struct zsda_sgl *)&cookie->sgl_src;<br />+    uint8_t opcode = ZSDA_OPC_INVALID;<br />+    uint32_t op_src_dst_offset = 0;<br />+    uint32_t op_src_dst_length = 0;<br />+    int ret = 0;<br />+<br />+    if ((op->sym->m_dst == NULL) || (op->sym->m_dst == op->sym->m_src)) {<br />+        ZSDA_LOG(ERR, "Failed! m_dst");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_crpt));<br />+    wqe->rx_length = op->sym->m_src->pkt_len - op->sym->auth.data.offset;<br />+    wqe->tx_length = op->sym->m_dst->pkt_len - op->sym->auth.data.offset;<br />+<br />+    opcode = get_opcode_hash(op);<br />+    if (opcode == ZSDA_OPC_INVALID) {<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+        return ZSDA_FAILED;<br />+    }<br />+    if (wqe->tx_length < get_hash_dst_len(opcode)) {<br />+        ZSDA_LOG(WARNING, W_MAY_EXCEPT_TEST);<br />+    }<br />+<br />+    op_src_dst_offset = op->sym->auth.data.offset;<br />+    op_src_dst_length = op->sym->auth.data.length;<br />+    ret = zsda_fill_sgl_offset(op->sym->m_src, op_src_dst_offset, sgl_src,<br />+                   cookie->sgl_src_phys_addr, op_src_dst_length,<br />+                   ZSDA_SGL_MAX_NUMBER - 1);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, E_FUNC);<br />+        return -ZSDA_FAILED;<br />+    }<br />+<br />+    cookie->valid = queue->valid;<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = opcode;<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = SGL_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = SGL_ELM_TYPE_PHYS_ADDR;<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr =<br />+        rte_pktmbuf_iova_offset(op->sym->m_dst, op_src_dst_offset);<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />diff --git a/drivers/crypto/zsda/zsda_sym.h b/drivers/crypto/zsda/zsda_sym.h<br />new file mode 100644<br />index 0000000..a98fa2a<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/zsda_sym.h<br />@@ -0,0 +1,42 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_SYM_H_<br />+#define _ZSDA_SYM_H_<br />+<br />+#include <rte_cryptodev_pmd.h> <br />+<br />+#include "zsda_common.h" <br />+#include "zsda_logs.h" <br />+#include "zsda_sym_pmd.h" <br />+<br />+#define ZSDA_SYM_XTS_IV_SLBA_OFF  (8)<br />+#define ZSDA_SYM_XTS_256_SKEY_LEN (16)<br />+#define ZSDA_SYM_XTS_256_KEY2_OFF (16)<br />+#define ZSDA_SYM_XTS_256_KEY1_OFF (48)<br />+#define ZSDA_SYM_XTS_512_KEY1_OFF (32)<br />+#define ZSDA_SYM_MIN_SRC_LEN_HASH (16)<br />+#define ZSDA_AES_LBADS_0      (0)<br />+#define ZSDA_AES_LBADS_512      (512)<br />+#define ZSDA_AES_LBADS_4096      (4096)<br />+#define ZSDA_AES_LBADS_8192      (8192)<br />+<br />+#define ZSDA_AES256_ROUND_NUM        (10)<br />+#define ZSDA_AES512_ROUND_NUM        (14)<br />+#define ZSDA_AES_MAX_EXP_BYTE_SIZE  (240)<br />+#define ZSDA_AES_MAX_KEY_BYTE_LEN   (32)<br />+#define ZSDA_SM4_MAX_EXP_DWORD_SIZE (32)<br />+<br />+int build_encry_request(void *op_in, const struct zsda_queue *queue,<br />+            void **op_cookies, uint16_t new_tail);<br />+int build_decry_request(void *op_in, const struct zsda_queue *queue,<br />+            void **op_cookies, uint16_t new_tail);<br />+int build_hash_request(void *op_in, const struct zsda_queue *queue,<br />+               void **op_cookies, uint16_t new_tail);<br />+<br />+int encry_match(void *op_in);<br />+int decry_match(void *op_in);<br />+int hash_match(void *op_in);<br />+<br />+#endif /* _ZSDA_SYM_H_ */<br />diff --git a/drivers/crypto/zsda/zsda_sym_capabilities.h b/drivers/crypto/zsda/zsda_sym_capabilities.h<br />new file mode 100644<br />index 0000000..6ed8ad6<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/zsda_sym_capabilities.h<br />@@ -0,0 +1,136 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_SYM_CAPABILITIES_H_<br />+#define _ZSDA_SYM_CAPABILITIES_H_<br />+<br />+static const struct rte_cryptodev_capabilities zsda_crypto_sym_capabilities[] = {<br />+    {/* SHA1 */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,<br />+              {<br />+                  .auth = {.algo = RTE_CRYPTO_AUTH_SHA1,<br />+                       .block_size = 64,<br />+                       .key_size = {.min = 0,<br />+                            .max = 0,<br />+                            .increment = 0},<br />+                       .digest_size = {.min = 1,<br />+                               .max = 20,<br />+                               .increment = 1},<br />+                       .iv_size = {0} },<br />+              } },<br />+      } },<br />+     {/* SHA224 */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,<br />+              {<br />+                  .auth = {.algo = RTE_CRYPTO_AUTH_SHA224,<br />+                       .block_size = 64,<br />+                       .key_size = {.min = 0,<br />+                            .max = 0,<br />+                            .increment = 0},<br />+                       .digest_size = {.min = 1,<br />+                               .max = 28,<br />+                               .increment = 1},<br />+                       .iv_size = {0} },<br />+              } },<br />+      } },<br />+     {/* SHA256 */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,<br />+              {<br />+                  .auth = {.algo = RTE_CRYPTO_AUTH_SHA256,<br />+                       .block_size = 64,<br />+                       .key_size = {.min = 0,<br />+                            .max = 0,<br />+                            .increment = 0},<br />+                       .digest_size = {.min = 1,<br />+                               .max = 32,<br />+                               .increment = 1},<br />+                       .iv_size = {0} },<br />+              } },<br />+      } },<br />+     {/* SHA384 */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,<br />+              {<br />+                  .auth = {.algo = RTE_CRYPTO_AUTH_SHA384,<br />+                       .block_size = 128,<br />+                       .key_size = {.min = 0,<br />+                            .max = 0,<br />+                            .increment = 0},<br />+                       .digest_size = {.min = 1,<br />+                               .max = 48,<br />+                               .increment = 1},<br />+                       .iv_size = {0} },<br />+              } },<br />+      } },<br />+     {/* SHA512 */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,<br />+              {<br />+                  .auth = {.algo = RTE_CRYPTO_AUTH_SHA512,<br />+                       .block_size = 128,<br />+                       .key_size = {.min = 0,<br />+                            .max = 0,<br />+                            .increment = 0},<br />+                       .digest_size = {.min = 1,<br />+                               .max = 64,<br />+                               .increment = 1},<br />+                       .iv_size = {0} },<br />+              } },<br />+      } },<br />+     {/* SM3 */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,<br />+              {<br />+                  .auth = {.algo = RTE_CRYPTO_AUTH_SM3,<br />+                       .block_size = 64,<br />+                       .key_size = {.min = 0,<br />+                            .max = 0,<br />+                            .increment = 0},<br />+                       .digest_size = {.min = 1,<br />+                               .max = 32,<br />+                               .increment = 1},<br />+                       .iv_size = {0} },<br />+              } },<br />+      } },<br />+     {/* AES XTS */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,<br />+              {<br />+                  .cipher = {.algo = RTE_CRYPTO_CIPHER_AES_XTS,<br />+                         .block_size = 16,<br />+                         .key_size = {.min = 32,<br />+                              .max = 64,<br />+                              .increment = 32},<br />+                         .iv_size = {.min = 16,<br />+                             .max = 16,<br />+                             .increment = 0} },<br />+              } },<br />+      } },<br />+     {/* SM4 XTS */<br />+      .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,<br />+      {<br />+          .sym = {.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,<br />+              {<br />+                  .cipher = {.algo = RTE_CRYPTO_CIPHER_SM4_XTS,<br />+                         .block_size = 16,<br />+                         .key_size = {.min = 32,<br />+                              .max = 64,<br />+                              .increment = 32},<br />+                         .iv_size = {.min = 16,<br />+                             .max = 16,<br />+                             .increment = 0} },<br />+              } },<br />+    } }<br />+};<br />+#endif /* _ZSDA_SYM_CAPABILITIES_H_ */<br />\ No newline at end of file<br />diff --git a/drivers/crypto/zsda/zsda_sym_pmd.c b/drivers/crypto/zsda/zsda_sym_pmd.c<br />new file mode 100644<br />index 0000000..5e34851<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/zsda_sym_pmd.c<br />@@ -0,0 +1,431 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <rte_bus_pci.h> <br />+#include <rte_common.h> <br />+#include <rte_cryptodev.h> <br />+#include <rte_cryptodev_pmd.h> <br />+#include <rte_dev.h> <br />+#include <rte_malloc.h> <br />+#include <rte_pci.h> <br />+<br />+#include "cryptodev_pmd.h" <br />+#include "zsda_logs.h" <br />+#include "zsda_qp.h" <br />+#include "zsda_sym.h" <br />+#include "zsda_sym_pmd.h" <br />+<br />+uint8_t zsda_sym_driver_id;<br />+<br />+static int<br />+zsda_sym_dev_config(__rte_unused struct rte_cryptodev *dev,<br />+            __rte_unused struct rte_cryptodev_config *config)<br />+{<br />+    return 0;<br />+}<br />+<br />+static int zsda_sym_qp_release(__rte_unused struct rte_cryptodev *dev,<br />+                   __rte_unused uint16_t queue_pair_id);<br />+<br />+static int<br />+zsda_sym_dev_start(struct rte_cryptodev *dev)<br />+{<br />+    struct zsda_sym_dev_private *sym_dev = dev->data->dev_private;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+    int ret = 0;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(sym_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_SYMMETRIC_ENCRYPT);<br />+    ret = zsda_queue_start(sym_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+    qp_hw = zsda_qps_hw_per_service(sym_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_SYMMETRIC_DECRYPT);<br />+    ret |= zsda_queue_start(sym_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+    qp_hw = zsda_qps_hw_per_service(sym_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_HASH_ENCODE);<br />+    ret |= zsda_queue_start(sym_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+<br />+    if (ret == ZSDA_FAILED) {<br />+        ZSDA_LOG(ERR, E_START_Q);<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    return 0;<br />+}<br />+<br />+static void<br />+zsda_sym_dev_stop(struct rte_cryptodev *dev)<br />+{<br />+    struct zsda_sym_dev_private *sym_dev = dev->data->dev_private;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(sym_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_SYMMETRIC_ENCRYPT);<br />+    zsda_queue_stop(sym_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+    qp_hw = zsda_qps_hw_per_service(sym_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_SYMMETRIC_DECRYPT);<br />+    zsda_queue_stop(sym_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+    qp_hw = zsda_qps_hw_per_service(sym_dev->zsda_pci_dev,<br />+                    ZSDA_SERVICE_HASH_ENCODE);<br />+    zsda_queue_stop(sym_dev->zsda_pci_dev->pci_dev, qp_hw);<br />+}<br />+<br />+static int<br />+zsda_sym_dev_close(struct rte_cryptodev *dev)<br />+{<br />+    int ret = 0;<br />+    uint16_t i = 0;<br />+<br />+    for (i = 0; i < dev->data->nb_queue_pairs; i++) {<br />+        ret = zsda_sym_qp_release(dev, i);<br />+        if (ret < 0)<br />+            return ret;<br />+    }<br />+    return ret;<br />+}<br />+<br />+static void<br />+zsda_sym_dev_info_get(struct rte_cryptodev *dev,<br />+              struct rte_cryptodev_info *info)<br />+{<br />+    struct zsda_sym_dev_private *sym_priv = dev->data->dev_private;<br />+<br />+    if (info != NULL) {<br />+        info->max_nb_queue_pairs =<br />+            zsda_crypto_max_nb_qps(sym_priv->zsda_pci_dev);<br />+        info->feature_flags = dev->feature_flags;<br />+        info->capabilities = sym_priv->zsda_dev_capabilities;<br />+        info->driver_id = zsda_sym_driver_id;<br />+        info->sym.max_nb_sessions = 0;<br />+    }<br />+}<br />+<br />+static void<br />+zsda_sym_stats_get(struct rte_cryptodev *dev, struct rte_cryptodev_stats *stats)<br />+{<br />+    struct zsda_common_stat comm = {0};<br />+<br />+    zsda_stats_get(dev->data->queue_pairs, dev->data->nb_queue_pairs,<br />+               &comm);<br />+    stats->enqueued_count = comm.enqueued_count;<br />+    stats->dequeued_count = comm.dequeued_count;<br />+    stats->enqueue_err_count = comm.enqueue_err_count;<br />+    stats->dequeue_err_count = comm.dequeue_err_count;<br />+}<br />+<br />+static void<br />+zsda_sym_stats_reset(struct rte_cryptodev *dev)<br />+{<br />+    zsda_stats_reset(dev->data->queue_pairs, dev->data->nb_queue_pairs);<br />+}<br />+<br />+static int<br />+zsda_sym_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)<br />+{<br />+    ZSDA_LOG(DEBUG, "Release sym qp %u on device %d", queue_pair_id,<br />+         dev->data->dev_id);<br />+<br />+    return zsda_queue_pair_release(<br />+        (struct zsda_qp **)&(dev->data->queue_pairs[queue_pair_id]));<br />+}<br />+<br />+static void<br />+crypto_callbak(void *op_in, struct zsda_cqe *cqe)<br />+{<br />+    struct rte_crypto_op *op = (struct rte_crypto_op *)op_in;<br />+<br />+    if (cqe->err0 || CQE_ERR1(cqe->err1))<br />+        op->status = RTE_CRYPTO_OP_STATUS_ERROR;<br />+    else<br />+        op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;<br />+}<br />+<br />+static int<br />+setup_encrypto_queue(struct zsda_pci_device *zsda_pci_dev, uint16_t qp_id,<br />+             struct zsda_qp *qp, uint32_t nb_des, int socket_id)<br />+{<br />+    enum zsda_service_type type = ZSDA_SERVICE_SYMMETRIC_ENCRYPT;<br />+    struct zsda_qp_config conf;<br />+    int ret = 0;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(zsda_pci_dev, type);<br />+    conf.hw = qp_hw->data + qp_id;<br />+    conf.service_type = type;<br />+    conf.cookie_size = sizeof(struct zsda_op_cookie);<br />+    conf.nb_descriptors = nb_des;<br />+    conf.socket_id = socket_id;<br />+    conf.service_str = "sym_encrypt";<br />+<br />+    ret = common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />+    qp->srv[type].rx_cb = crypto_callbak;<br />+    qp->srv[type].tx_cb = build_encry_request;<br />+    qp->srv[type].match = encry_match;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+setup_decrypto_queue(struct zsda_pci_device *zsda_pci_dev, uint16_t qp_id,<br />+             struct zsda_qp *qp, uint32_t nb_des, int socket_id)<br />+{<br />+    enum zsda_service_type type = ZSDA_SERVICE_SYMMETRIC_DECRYPT;<br />+    struct zsda_qp_config conf;<br />+    int ret = 0;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(zsda_pci_dev, type);<br />+    conf.hw = qp_hw->data + qp_id;<br />+    conf.service_type = type;<br />+<br />+    conf.cookie_size = sizeof(struct zsda_op_cookie);<br />+    conf.nb_descriptors = nb_des;<br />+    conf.socket_id = socket_id;<br />+    conf.service_str = "sym_decrypt";<br />+<br />+    ret = common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />+    qp->srv[type].rx_cb = crypto_callbak;<br />+    qp->srv[type].tx_cb = build_decry_request;<br />+    qp->srv[type].match = decry_match;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+setup_hash_queue(struct zsda_pci_device *zsda_pci_dev, uint16_t qp_id,<br />+         struct zsda_qp *qp, uint32_t nb_des, int socket_id)<br />+{<br />+    enum zsda_service_type type = ZSDA_SERVICE_HASH_ENCODE;<br />+    struct zsda_qp_config conf;<br />+    int ret = 0;<br />+    struct zsda_qp_hw *qp_hw = NULL;<br />+<br />+    qp_hw = zsda_qps_hw_per_service(zsda_pci_dev, type);<br />+    conf.hw = qp_hw->data + qp_id;<br />+    conf.service_type = type;<br />+    conf.cookie_size = sizeof(struct zsda_op_cookie);<br />+    conf.nb_descriptors = nb_des;<br />+    conf.socket_id = socket_id;<br />+    conf.service_str = "sym_hash";<br />+<br />+    ret = common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />+    qp->srv[type].rx_cb = crypto_callbak;<br />+    qp->srv[type].tx_cb = build_hash_request;<br />+    qp->srv[type].match = hash_match;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+zsda_sym_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,<br />+          __rte_unused const struct rte_cryptodev_qp_conf *qp_conf,<br />+          int socket_id)<br />+{<br />+    int ret = 0;<br />+    struct zsda_qp *qp_new;<br />+<br />+    struct zsda_qp **qp_addr =<br />+        (struct zsda_qp **)&(dev->data->queue_pairs[qp_id]);<br />+    struct zsda_sym_dev_private *sym_priv = dev->data->dev_private;<br />+    struct zsda_pci_device *zsda_pci_dev = sym_priv->zsda_pci_dev;<br />+    uint16_t num_qps_encrypt = zsda_qps_per_service(<br />+        zsda_pci_dev, ZSDA_SERVICE_SYMMETRIC_ENCRYPT);<br />+    uint16_t num_qps_decrypt = zsda_qps_per_service(<br />+        zsda_pci_dev, ZSDA_SERVICE_SYMMETRIC_DECRYPT);<br />+    uint16_t num_qps_hash =<br />+        zsda_qps_per_service(zsda_pci_dev, ZSDA_SERVICE_HASH_ENCODE);<br />+<br />+    uint32_t nb_des = NB_DES;<br />+<br />+    if (*qp_addr != NULL) {<br />+        ret = zsda_sym_qp_release(dev, qp_id);<br />+        if (ret < 0)<br />+            return ret;<br />+    }<br />+<br />+    qp_new = rte_zmalloc_socket("zsda PMD qp metadata", sizeof(*qp_new),<br />+                    RTE_CACHE_LINE_SIZE, socket_id);<br />+    if (qp_new == NULL) {<br />+        ZSDA_LOG(ERR, "Failed to alloc mem for qp struct");<br />+        return -ENOMEM;<br />+    }<br />+<br />+    if (num_qps_encrypt == MAX_QPS_ON_FUNCTION)<br />+        ret |= setup_encrypto_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                        socket_id);<br />+    else if (num_qps_decrypt == MAX_QPS_ON_FUNCTION)<br />+        ret |= setup_decrypto_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                        socket_id);<br />+    else if (num_qps_hash == MAX_QPS_ON_FUNCTION)<br />+        ret |= setup_hash_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                    socket_id);<br />+    else {<br />+        ret |= setup_encrypto_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                        socket_id);<br />+        ret |= setup_decrypto_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                        socket_id);<br />+        ret |= setup_hash_queue(zsda_pci_dev, qp_id, qp_new, nb_des,<br />+                    socket_id);<br />+    }<br />+<br />+    if (ret) {<br />+        rte_free(qp_new);<br />+        return ret;<br />+    }<br />+<br />+    qp_new->mmap_bar_addr =<br />+        sym_priv->zsda_pci_dev->pci_dev->mem_resource[0].addr;<br />+    *qp_addr = qp_new;<br />+<br />+    return ret;<br />+}<br />+<br />+static struct rte_cryptodev_ops crypto_zsda_ops = {<br />+<br />+    .dev_configure = zsda_sym_dev_config,<br />+    .dev_start = zsda_sym_dev_start,<br />+    .dev_stop = zsda_sym_dev_stop,<br />+    .dev_close = zsda_sym_dev_close,<br />+    .dev_infos_get = zsda_sym_dev_info_get,<br />+<br />+    .stats_get = zsda_sym_stats_get,<br />+    .stats_reset = zsda_sym_stats_reset,<br />+    .queue_pair_setup = zsda_sym_qp_setup,<br />+    .queue_pair_release = zsda_sym_qp_release,<br />+<br />+};<br />+<br />+static uint16_t<br />+zsda_sym_pmd_enqueue_op_burst(void *qp, struct rte_crypto_op **ops,<br />+                  uint16_t nb_ops)<br />+{<br />+    return zsda_enqueue_op_burst((struct zsda_qp *)qp, (void **)ops,<br />+                     nb_ops);<br />+}<br />+<br />+static uint16_t<br />+zsda_sym_pmd_dequeue_op_burst(void *qp, struct rte_crypto_op **ops,<br />+                  uint16_t nb_ops)<br />+{<br />+    return zsda_dequeue_op_burst((struct zsda_qp *)qp, (void **)ops,<br />+                     nb_ops);<br />+}<br />+<br />+static const char zsda_sym_drv_name[] = RTE_STR(CRYPTODEV_NAME_ZSDA_SYM_PMD);<br />+static const struct rte_driver cryptodev_zsda_sym_driver = {<br />+    .name = zsda_sym_drv_name, .alias = zsda_sym_drv_name};<br />+<br />+int<br />+zsda_sym_dev_create(struct zsda_pci_device *zsda_pci_dev,<br />+            struct zsda_dev_cmd_param *zsda_dev_cmd_param __rte_unused)<br />+{<br />+    int ret = 0;<br />+    struct zsda_device_info *dev_info =<br />+        &zsda_devs[zsda_pci_dev->zsda_dev_id];<br />+<br />+    struct rte_cryptodev_pmd_init_params init_params = {<br />+        .name = "",<br />+        .socket_id = (int)rte_socket_id(),<br />+        .private_data_size = sizeof(struct zsda_sym_dev_private)};<br />+<br />+    char name[RTE_CRYPTODEV_NAME_MAX_LEN];<br />+    char capa_memz_name[RTE_CRYPTODEV_NAME_MAX_LEN];<br />+    struct rte_cryptodev *cryptodev;<br />+    struct zsda_sym_dev_private *sym_priv;<br />+    const struct rte_cryptodev_capabilities *capabilities;<br />+    uint64_t capa_size;<br />+<br />+    init_params.max_nb_queue_pairs = zsda_crypto_max_nb_qps(zsda_pci_dev);<br />+    snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s", zsda_pci_dev->name,<br />+         "sym_encrypt");<br />+    ZSDA_LOG(DEBUG, "Creating ZSDA SYM device %s", name);<br />+<br />+    if (rte_eal_process_type() != RTE_PROC_PRIMARY)<br />+        return 0;<br />+<br />+    dev_info->sym_rte_dev.driver = &cryptodev_zsda_sym_driver;<br />+    dev_info->sym_rte_dev.numa_node = dev_info->pci_dev->device.numa_node;<br />+    dev_info->sym_rte_dev.devargs = NULL;<br />+<br />+    cryptodev = rte_cryptodev_pmd_create(name, &(dev_info->sym_rte_dev),<br />+                         &init_params);<br />+<br />+    if (cryptodev == NULL)<br />+        return -ENODEV;<br />+<br />+    dev_info->sym_rte_dev.name = cryptodev->data->name;<br />+    cryptodev->driver_id = zsda_sym_driver_id;<br />+<br />+    cryptodev->dev_ops = &crypto_zsda_ops;<br />+<br />+    cryptodev->enqueue_burst = zsda_sym_pmd_enqueue_op_burst;<br />+    cryptodev->dequeue_burst = zsda_sym_pmd_dequeue_op_burst;<br />+<br />+    cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |<br />+                   RTE_CRYPTODEV_FF_SYM_SESSIONLESS |<br />+                   RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |<br />+                   RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT |<br />+                   RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |<br />+                   RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT |<br />+                   RTE_CRYPTODEV_FF_HW_ACCELERATED;<br />+<br />+    if (rte_eal_process_type() != RTE_PROC_PRIMARY)<br />+        return 0;<br />+<br />+    sym_priv = cryptodev->data->dev_private;<br />+    sym_priv->zsda_pci_dev = zsda_pci_dev;<br />+    capabilities = zsda_crypto_sym_capabilities;<br />+    capa_size = sizeof(zsda_crypto_sym_capabilities);<br />+<br />+    snprintf(capa_memz_name, RTE_CRYPTODEV_NAME_MAX_LEN, "ZSDA_SYM_CAPA");<br />+<br />+    sym_priv->capa_mz = rte_memzone_lookup(capa_memz_name);<br />+    if (sym_priv->capa_mz == NULL)<br />+        sym_priv->capa_mz = rte_memzone_reserve(<br />+            capa_memz_name, capa_size, rte_socket_id(), 0);<br />+<br />+    if (sym_priv->capa_mz == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        ret = -EFAULT;<br />+        goto error;<br />+    }<br />+<br />+    memcpy(sym_priv->capa_mz->addr, capabilities, capa_size);<br />+    sym_priv->zsda_dev_capabilities = sym_priv->capa_mz->addr;<br />+<br />+    zsda_pci_dev->sym_dev = sym_priv;<br />+<br />+    return 0;<br />+<br />+error:<br />+<br />+    rte_cryptodev_pmd_destroy(cryptodev);<br />+    memset(&dev_info->sym_rte_dev, 0, sizeof(dev_info->sym_rte_dev));<br />+<br />+    return ret;<br />+}<br />+<br />+int<br />+zsda_sym_dev_destroy(struct zsda_pci_device *zsda_pci_dev)<br />+{<br />+    struct rte_cryptodev *cryptodev;<br />+<br />+    if (zsda_pci_dev == NULL)<br />+        return -ENODEV;<br />+    if (zsda_pci_dev->sym_dev == NULL)<br />+        return 0;<br />+    if (rte_eal_process_type() == RTE_PROC_PRIMARY)<br />+        rte_memzone_free(zsda_pci_dev->sym_dev->capa_mz);<br />+<br />+    cryptodev = rte_cryptodev_pmd_get_dev(zsda_pci_dev->zsda_dev_id);<br />+<br />+    rte_cryptodev_pmd_destroy(cryptodev);<br />+    zsda_devs[zsda_pci_dev->zsda_dev_id].sym_rte_dev.name = NULL;<br />+    zsda_pci_dev->sym_dev = NULL;<br />+<br />+    return 0;<br />+}<br />+<br />+static struct cryptodev_driver zsda_crypto_drv;<br />+RTE_PMD_REGISTER_CRYPTO_DRIVER(zsda_crypto_drv, cryptodev_zsda_sym_driver,<br />+                   zsda_sym_driver_id);<br />diff --git a/drivers/crypto/zsda/zsda_sym_pmd.h b/drivers/crypto/zsda/zsda_sym_pmd.h<br />new file mode 100644<br />index 0000000..e508794<br />--- /dev/null<br />+++ b/drivers/crypto/zsda/zsda_sym_pmd.h<br />@@ -0,0 +1,44 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _ZSDA_SYM_PMD_H_<br />+#define _ZSDA_SYM_PMD_H_<br />+<br />+#include <rte_cryptodev.h> <br />+#include <rte_ether.h> <br />+<br />+#include "zsda_device.h" <br />+#include "zsda_sym_capabilities.h" <br />+<br />+/** Intel(R) ZSDA Symmetric Crypto PMD driver name */<br />+#define CRYPTODEV_NAME_ZSDA_SYM_PMD crypto_zsda<br />+<br />+/* Internal capabilities */<br />+#define ZSDA_SYM_CAP_MIXED_CRYPTO (1 << 0)<br />+#define ZSDA_SYM_CAP_VALID      (1 << 31)<br />+<br />+extern uint8_t zsda_sym_driver_id;<br />+<br />+/** private data structure for a ZSDA device.<br />+ * This ZSDA device is a device offering only symmetric crypto service,<br />+ * there can be one of these on each zsda_pci_device (VF).<br />+ */<br />+struct zsda_sym_dev_private {<br />+    struct zsda_pci_device *zsda_pci_dev;<br />+    /**< The zsda pci device hosting the service */<br />+<br />+    const struct rte_cryptodev_capabilities *zsda_dev_capabilities;<br />+    /* ZSDA device symmetric crypto capabilities */<br />+    const struct rte_memzone *capa_mz;<br />+    /* Shared memzone for storing capabilities */<br />+    uint16_t min_enq_burst_threshold;<br />+    uint32_t internal_capabilities; /* see flags ZSDA_SYM_CAP_xxx */<br />+};<br />+<br />+int zsda_sym_dev_create(struct zsda_pci_device *zsda_pci_dev,<br />+            struct zsda_dev_cmd_param *zsda_dev_cmd_param);<br />+<br />+int zsda_sym_dev_destroy(struct zsda_pci_device *zsda_pci_dev);<br />+<br />+#endif /* _ZSDA_SYM_PMD_H_ */<br />diff --git a/drivers/meson.build b/drivers/meson.build<br />index c4ff3ff..74c4840 100644<br />--- a/drivers/meson.build<br />+++ b/drivers/meson.build<br />@@ -11,6 +11,7 @@ subdirs = [<br />         'common/mlx5',    # depends on bus.<br />         'common/qat',     # depends on bus.<br />         'common/sfc_efx', # depends on bus.<br />+        'common/zsda',    # depends on common and bus.<br />         'mempool',        # depends on common and bus.<br />         'dma',            # depends on common and bus.<br />         'net',            # depends on common, bus, mempool<br />diff --git a/examples/meson.build b/examples/meson.build<br />index 6968c09..cf80855 100644<br />--- a/examples/meson.build<br />+++ b/examples/meson.build<br />@@ -59,6 +59,7 @@ all_examples = [<br />         'vm_power_manager/guest_cli',<br />         'vmdq',<br />         'vmdq_dcb',<br />+        'zsda',<br /> ]<br />  <br /> # on install, skip copying all meson.build files<br />diff --git a/examples/zsda/Makefile b/examples/zsda/Makefile<br />new file mode 100644<br />index 0000000..b8971ad<br />--- /dev/null<br />+++ b/examples/zsda/Makefile<br />@@ -0,0 +1,56 @@<br />+ifeq ($(RTE_SDK),)<br />+$(error "Please define RTE_SDK environment variable")<br />+endif<br />+<br />+# Default target, can be overriden by command line or environment<br />+RTE_TARGET ?= build<br />+<br />+# binary name<br />+APP = zsdaapp<br />+<br />+# all source are stored in SRCS-y<br />+SRCS-y := test.c<br />+<br />+# Build using pkg-config variables if possible<br />+ifneq ($(shell pkg-config --exists libdpdk && echo 0),0)<br />+$(error "no installation of DPDK found")<br />+endif<br />+<br />+all: shared<br />+.PHONY: shared static<br />+shared: build/$(APP)-shared<br />+    ln -sf $(APP)-shared build/$(APP)<br />+static: build/$(APP)-static<br />+    ln -sf $(APP)-static build/$(APP)<br />+<br />+PKGCONF ?= pkg-config<br />+<br />+CFLAGS += -DDPDK=1<br />+<br />+# Add flag to allow experimental API as zsda uses rte_ethdev_set_ptype API<br />+CFLAGS += -DALLOW_EXPERIMENTAL_API<br />+<br />+PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)<br />+CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)<br />+LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)<br />+LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)<br />+LDFLAGS += $(shell $(PKGCONF) --libs libdpdk)<br />+<br />+LDFLAGS += -lrte_common_zsda -lrte_cryptodev -lrte_compressdev<br />+<br />+# for shared library builds, we need to explicitly link these PMDs<br />+LDFLAGS_SHARED += -lrte_common_zsda -lrte_common_zsda -lrte_cryptodev -lrte_compressdev<br />+<br />+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build<br />+    $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)<br />+<br />+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build<br />+    $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)<br />+<br />+build:<br />+    @mkdir -p $@<br />+<br />+.PHONY: clean<br />+clean:<br />+    rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared<br />+    test -d build && rmdir -p build || true<br />\ No newline at end of file<br />diff --git a/examples/zsda/commands.c b/examples/zsda/commands.c<br />new file mode 100644<br />index 0000000..a9730f5<br />--- /dev/null<br />+++ b/examples/zsda/commands.c<br />@@ -0,0 +1,321 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <errno.h> <br />+#include <inttypes.h> <br />+#include <netinet/in.h> <br />+#include <stdarg.h> <br />+#include <stdint.h> <br />+#include <stdio.h> <br />+#include <stdlib.h> <br />+#include <string.h> <br />+#include <sys/queue.h> <br />+#include <termios.h> <br />+<br />+#include <rte_atomic.h> <br />+#include <rte_branch_prediction.h> <br />+#include <rte_common.h> <br />+#include <rte_cycles.h> <br />+#include <rte_debug.h> <br />+#include <rte_devargs.h> <br />+#include <rte_eal.h> <br />+#include <rte_launch.h> <br />+#include <rte_lcore.h> <br />+#include <rte_log.h> <br />+#include <rte_malloc.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_memcpy.h> <br />+#include <rte_memory.h> <br />+#include <rte_mempool.h> <br />+#include <rte_memzone.h> <br />+#include <rte_per_lcore.h> <br />+#include <rte_ring.h> <br />+<br />+#include <cmdline.h> <br />+#include <cmdline_parse.h> <br />+#include <cmdline_parse_ipaddr.h> <br />+#include <cmdline_parse_num.h> <br />+#include <cmdline_parse_string.h> <br />+#include <cmdline_rdline.h> <br />+#include <rte_string_fns.h> <br />+<br />+#include "test.h" <br />+#include "test_zsda.h" <br />+<br />+static struct test_commands_list commands_list =<br />+    TAILQ_HEAD_INITIALIZER(commands_list);<br />+<br />+void<br />+add_test_command(struct test_command *t)<br />+{<br />+    TAILQ_INSERT_TAIL(&commands_list, t, next);<br />+}<br />+<br />+struct cmd_autotest_result {<br />+    cmdline_fixed_string_t autotest;<br />+};<br />+<br />+static void<br />+cmd_autotest_parsed(void *parsed_result, __rte_unused struct cmdline *cl,<br />+            __rte_unused void *data)<br />+{<br />+    struct test_command *t;<br />+    struct cmd_autotest_result *res = parsed_result;<br />+    int ret = 0;<br />+<br />+    TAILQ_FOREACH(t, &commands_list, next)<br />+    {<br />+        if (!strcmp(res->autotest, t->command))<br />+            ret = t->callback();<br />+    }<br />+<br />+    last_test_result = ret;<br />+    if (ret == 0)<br />+        printf("Test OK\n");<br />+    else if (ret == TEST_SKIPPED)<br />+        printf("Test Skipped\n");<br />+    else<br />+        printf("Test Failed\n");<br />+    fflush(stdout);<br />+}<br />+<br />+cmdline_parse_token_string_t cmd_autotest_autotest =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, "");<br />+<br />+cmdline_parse_inst_t cmd_autotest = {<br />+    .f = cmd_autotest_parsed, /* function to call */<br />+    .data = NULL,          /* 2nd arg of func */<br />+    .help_str = "launch autotest",<br />+    .tokens = {(void *)&cmd_autotest_autotest, NULL},<br />+};<br />+<br />+struct cmd_dump_result {<br />+    cmdline_fixed_string_t dump;<br />+};<br />+<br />+static void<br />+dump_struct_sizes(void)<br />+{<br />+#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned int)sizeof(t))<br />+    DUMP_SIZE(struct rte_mbuf);<br />+    DUMP_SIZE(struct rte_mempool);<br />+    DUMP_SIZE(struct rte_ring);<br />+#undef DUMP_SIZE<br />+}<br />+<br />+static void<br />+cmd_dump_parsed(void *parsed_result, __rte_unused struct cmdline *cl,<br />+        __rte_unused void *data)<br />+{<br />+    struct cmd_dump_result *res = parsed_result;<br />+<br />+    if (!strcmp(res->dump, "dump_physmem"))<br />+        rte_dump_physmem_layout(stdout);<br />+    else if (!strcmp(res->dump, "dump_memzone"))<br />+        rte_memzone_dump(stdout);<br />+    else if (!strcmp(res->dump, "dump_struct_sizes"))<br />+        dump_struct_sizes();<br />+    else if (!strcmp(res->dump, "dump_ring"))<br />+        rte_ring_list_dump(stdout);<br />+    else if (!strcmp(res->dump, "dump_mempool"))<br />+        rte_mempool_list_dump(stdout);<br />+    else if (!strcmp(res->dump, "dump_devargs"))<br />+        rte_devargs_dump(stdout);<br />+    else if (!strcmp(res->dump, "dump_log_types"))<br />+        rte_log_dump(stdout);<br />+    else if (!strcmp(res->dump, "dump_malloc_stats"))<br />+        rte_malloc_dump_stats(stdout, NULL);<br />+    else if (!strcmp(res->dump, "dump_malloc_heaps"))<br />+        rte_malloc_dump_heaps(stdout);<br />+}<br />+<br />+cmdline_parse_token_string_t cmd_dump_dump =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,<br />+                 "dump_physmem#" <br />+                 "dump_memzone#" <br />+                 "dump_struct_sizes#" <br />+                 "dump_ring#" <br />+                 "dump_mempool#" <br />+                 "dump_malloc_stats#" <br />+                 "dump_malloc_heaps#" <br />+                 "dump_devargs#" <br />+                 "dump_log_types");<br />+<br />+cmdline_parse_inst_t cmd_dump = {<br />+    .f = cmd_dump_parsed,<br />+    .data = NULL,<br />+    .help_str = "dump status",<br />+    .tokens = {(void *)&cmd_dump_dump, NULL},<br />+};<br />+<br />+struct cmd_dump_one_result {<br />+    cmdline_fixed_string_t dump;<br />+    cmdline_fixed_string_t name;<br />+    cmdline_fixed_string_t arg0;<br />+};<br />+<br />+static void<br />+cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,<br />+            __rte_unused void *data)<br />+{<br />+    struct cmd_dump_one_result *res = parsed_result;<br />+<br />+    if (!strcmp(res->dump, "dump_ring")) {<br />+        struct rte_ring *r;<br />+<br />+        r = rte_ring_lookup(res->name);<br />+        if (r == NULL) {<br />+            cmdline_printf(cl, "Cannot find ring\n");<br />+            return;<br />+        }<br />+        rte_ring_dump(stdout, r);<br />+    } else if (!strcmp(res->dump, "dump_mempool")) {<br />+        struct rte_mempool *mp;<br />+<br />+        mp = rte_mempool_lookup(res->name);<br />+        if (mp == NULL) {<br />+            cmdline_printf(cl, "Cannot find mempool\n");<br />+            return;<br />+        }<br />+        rte_mempool_dump(stdout, mp);<br />+    }<br />+}<br />+<br />+cmdline_parse_token_string_t cmd_dump_one_dump = TOKEN_STRING_INITIALIZER(<br />+    struct cmd_dump_one_result, dump, "dump_mempool");<br />+<br />+cmdline_parse_token_string_t cmd_dump_one_name =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);<br />+<br />+cmdline_parse_inst_t cmd_dump_one = {<br />+    .f = cmd_dump_one_parsed,<br />+    .data = NULL,<br />+    .help_str = "dump one mempool: dump_mempool <name>",<br />+    .tokens = {(void *)&cmd_dump_one_dump, (void *)&cmd_dump_one_name,<br />+           NULL},<br />+};<br />+<br />+struct cmd_quit_result {<br />+    cmdline_fixed_string_t quit;<br />+};<br />+<br />+static void<br />+cmd_quit_parsed(__rte_unused void *parsed_result, struct cmdline *cl,<br />+        __rte_unused void *data)<br />+{<br />+    cmdline_quit(cl);<br />+}<br />+<br />+cmdline_parse_token_string_t cmd_quit_quit =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");<br />+<br />+cmdline_parse_inst_t cmd_quit = {<br />+    .f = cmd_quit_parsed,<br />+    .data = NULL,<br />+    .help_str = "exit application",<br />+    .tokens = {(cmdline_parse_token_hdr_t *)&cmd_quit_quit, NULL},<br />+};<br />+<br />+struct cmd_run_test_result {<br />+    cmdline_fixed_string_t func;<br />+    cmdline_fixed_string_t name;<br />+    cmdline_fixed_string_t arg0;<br />+    cmdline_fixed_string_t arg1;<br />+    cmdline_fixed_string_t arg2;<br />+};<br />+<br />+static void<br />+run_test_group_parse(void *parsed_result, __rte_unused struct cmdline *cl,<br />+             __rte_unused void *data)<br />+{<br />+    struct cmd_run_test_result *res = parsed_result;<br />+    enum test_type zsda_test_type = run_test_invalid;<br />+    uint8_t arg0 = (uint8_t)(atoi(res->arg0) & 0xff);<br />+    uint8_t arg1 = (uint8_t)(atoi(res->arg1) & 0xff);<br />+    uint8_t arg2 = (uint8_t)(atoi(res->arg2) & 0xff);<br />+<br />+    if (!strcmp(res->func, "run_test"))<br />+        zsda_test_type = run_test;<br />+<br />+    if (atoi(res->arg1) > atoi(res->arg2))<br />+        printf("error: arg1 is greater than arg2 !\n");<br />+<br />+    if (atoi(res->arg2) >= 128)<br />+        printf("error: arg2 is greater than 128 !\n");<br />+<br />+    if (run_test_invalid == zsda_test_type) {<br />+        ZSDA_LOG(ERR, "[%d] Failed! zsda_test_type is invalid",<br />+             __LINE__);<br />+        return;<br />+    }<br />+    if (!strcmp(res->name, "crypto"))<br />+        zsda_run_test(zsda_test_type, arg0, arg1, arg2, zsda_crypto);<br />+    else if (!strcmp(res->name, "comp"))<br />+        zsda_run_test(zsda_test_type, arg0, arg1, arg2, zsda_compress);<br />+}<br />+<br />+cmdline_parse_token_string_t cmd_run_test =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_run_test_result, func, "run_test");<br />+<br />+cmdline_parse_token_string_t cmd_name =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_run_test_result, name, NULL);<br />+<br />+cmdline_parse_token_string_t cmd_arg0 =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_run_test_result, arg0, NULL);<br />+<br />+cmdline_parse_token_string_t cmd_arg1 =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_run_test_result, arg1, NULL);<br />+<br />+cmdline_parse_token_string_t cmd_arg2 =<br />+    TOKEN_STRING_INITIALIZER(struct cmd_run_test_result, arg2, NULL);<br />+<br />+cmdline_parse_inst_t cmd_parse_run_one = {<br />+    .f = run_test_group_parse,<br />+    .data = NULL,<br />+    .help_str = "run one testcase: run_test <name> -- comp/crypto <dev> " <br />+            "<ring> <cpu>",<br />+    .tokens = {(cmdline_parse_token_hdr_t *)&cmd_run_test,<br />+           (cmdline_parse_token_hdr_t *)&cmd_name,<br />+           (cmdline_parse_token_hdr_t *)&cmd_arg0,<br />+           (cmdline_parse_token_hdr_t *)&cmd_arg1,<br />+           (cmdline_parse_token_hdr_t *)&cmd_arg2, NULL},<br />+};<br />+/****************/<br />+<br />+cmdline_parse_ctx_t main_ctx[] = {<br />+    (cmdline_parse_inst_t *)&cmd_autotest,<br />+    (cmdline_parse_inst_t *)&cmd_parse_run_one,<br />+    (cmdline_parse_inst_t *)&cmd_dump,<br />+    (cmdline_parse_inst_t *)&cmd_dump_one,<br />+    (cmdline_parse_inst_t *)&cmd_quit,<br />+<br />+    NULL,<br />+};<br />+<br />+int<br />+commands_init(void)<br />+{<br />+    struct test_command *t;<br />+    char *commands;<br />+    int commands_len = 0;<br />+<br />+    TAILQ_FOREACH(t, &commands_list, next)<br />+    {<br />+        commands_len += strlen(t->command) + 1;<br />+    }<br />+<br />+    commands = (char *)calloc(commands_len, sizeof(char));<br />+    if (!commands)<br />+        return -1;<br />+<br />+    TAILQ_FOREACH(t, &commands_list, next)<br />+    {<br />+        strlcat(commands, t->command, commands_len);<br />+        if (TAILQ_NEXT(t, next) != NULL)<br />+            strlcat(commands, "#", commands_len);<br />+    }<br />+<br />+    cmd_autotest_autotest.string_data.str = commands;<br />+    return 0;<br />+}<br />diff --git a/examples/zsda/meson.build b/examples/zsda/meson.build<br />new file mode 100644<br />index 0000000..c713330<br />--- /dev/null<br />+++ b/examples/zsda/meson.build<br />@@ -0,0 +1,30 @@<br />+# SPDX-License-Identifier: BSD-3-Clause<br />+# Copyright(c) 2024 ZTE Corporation<br />+<br />+<br />+# meson file, for building this example as part of a main DPDK build.<br />+#<br />+# To build this example as a standalone application with an already-installed<br />+# DPDK instance, use 'make' <br />+<br />+<br />+includes = include_directories(<br />+    '../../../lib/eal/common',<br />+    '../../drivers/bus/pci',<br />+    '../../lib/pci',<br />+    '../../lib/timer',<br />+    '../../lib/rcu',<br />+    '../../lib/cryptodev',<br />+    '../../lib/compressdev',<br />+    '../../drivers/bus/vdev',<br />+    '../../drivers/common/zsda',<br />+    )<br />+<br />+allow_experimental_apis = true<br />+sources = files(<br />+    'test.c',<br />+    'commands.c',<br />+    'test_zsda.c',<br />+    'test_zsda_cryptodev.c',<br />+    'test_zsda_compressdev.c',<br />+)<br />diff --git a/examples/zsda/test.c b/examples/zsda/test.c<br />new file mode 100644<br />index 0000000..f1826ce<br />--- /dev/null<br />+++ b/examples/zsda/test.c<br />@@ -0,0 +1,198 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <ctype.h> <br />+#include <errno.h> <br />+#include <stdarg.h> <br />+#include <stdint.h> <br />+#include <stdio.h> <br />+#include <stdlib.h> <br />+#include <string.h> <br />+#include <sys/queue.h> <br />+#include <termios.h> <br />+<br />+#ifdef RTE_LIB_CMDLINE<br />+#include <cmdline.h> <br />+#include <cmdline_parse.h> <br />+#include <cmdline_rdline.h> <br />+#include <cmdline_socket.h> <br />+extern cmdline_parse_ctx_t main_ctx[];<br />+#endif<br />+<br />+#include <rte_cycles.h> <br />+#include <rte_eal.h> <br />+#include <rte_log.h> <br />+#include <rte_memory.h> <br />+#include <rte_string_fns.h> <br />+#ifdef RTE_LIB_TIMER<br />+#include <rte_timer.h> <br />+#endif<br />+<br />+#include "test.h" <br />+#include "zsda_logs.h" <br />+#ifdef RTE_LIB_PDUMP<br />+#endif<br />+<br />+#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1<br />+#define MAX_EXTRA_ARGS 32<br />+<br />+const char *prgname;<br />+int last_test_result;<br />+<br />+/* used in linux for MP and other tests */<br />+static const char *recursive_call;<br />+<br />+static int<br />+no_action(void)<br />+{<br />+    return 0;<br />+}<br />+<br />+static int<br />+do_recursive_call(void)<br />+{<br />+    unsigned int i;<br />+    struct {<br />+        const char *env_var;<br />+        int (*action_fn)(void);<br />+    } actions[] = {<br />+        {"test_missing_c_flag", no_action},<br />+        {"test_main_lcore_flag", no_action},<br />+        {"test_invalid_n_flag", no_action},<br />+        {"test_no_hpet_flag", no_action},<br />+        {"test_allow_flag", no_action},<br />+        {"test_invalid_b_flag", no_action},<br />+        {"test_invalid_vdev_flag", no_action},<br />+        {"test_invalid_r_flag", no_action},<br />+        {"test_misc_flags", no_action},<br />+        {"test_memory_flags", no_action},<br />+        {"test_file_prefix", no_action},<br />+        {"test_no_huge_flag", no_action},<br />+    };<br />+<br />+    if (recursive_call == NULL)<br />+        return -1;<br />+    for (i = 0; i < RTE_DIM(actions); i++) {<br />+        if (strcmp(actions[i].env_var, recursive_call) == 0)<br />+            return (actions[i].action_fn)();<br />+    }<br />+    printf("ERROR - missing action to take for %s\n", recursive_call);<br />+    return -1;<br />+}<br />+<br />+<br />+<br />+int<br />+main(int argc, char **argv)<br />+{<br />+#ifdef RTE_LIB_CMDLINE<br />+    struct cmdline *cl;<br />+#endif<br />+    char *extra_args;<br />+    int ret;<br />+<br />+    extra_args = getenv("DPDK_TEST_PARAMS");<br />+    if (extra_args != NULL && strlen(extra_args) > 0) {<br />+        char **all_argv;<br />+        char *eargv[MAX_EXTRA_ARGS];<br />+        int all_argc;<br />+        int eargc;<br />+        int i;<br />+<br />+        ZSDA_LOG(INFO, "Using additional DPDK_TEST_PARAMS: '%s'",<br />+             extra_args);<br />+        eargc = rte_strsplit(extra_args,<br />+                     strlen(extra_args) & (0xffffffff), eargv,<br />+                     MAX_EXTRA_ARGS, ' ');<br />+<br />+        /* merge argc/argv and the environment args */<br />+        all_argc = argc + eargc;<br />+        all_argv = malloc(sizeof(*all_argv) * (all_argc + 1));<br />+        if (all_argv == NULL) {<br />+            ret = -1;<br />+            goto out;<br />+        }<br />+<br />+        for (i = 0; i < argc; i++)<br />+            all_argv[i] = argv[i];<br />+        for (i = 0; i < eargc; i++)<br />+            all_argv[argc + i] = eargv[i];<br />+        all_argv[all_argc] = NULL;<br />+<br />+        /* call eal_init with combined args */<br />+        ret = rte_eal_init(all_argc, all_argv);<br />+        free(all_argv);<br />+    } else<br />+        ret = rte_eal_init(argc, argv);<br />+    if (ret < 0) {<br />+        ret = -1;<br />+        goto out;<br />+    }<br />+<br />+    if (commands_init() < 0) {<br />+        ret = -1;<br />+        goto out;<br />+    }<br />+<br />+    argv += ret;<br />+<br />+    prgname = argv[0];<br />+<br />+    recursive_call = getenv(RECURSIVE_ENV_VAR);<br />+    if (recursive_call != NULL) {<br />+        ret = do_recursive_call();<br />+        goto out;<br />+    }<br />+<br />+#ifdef RTE_LIBEAL_USE_HPET<br />+    if (rte_eal_hpet_init(1) < 0)<br />+#endif<br />+        ZSDA_LOG(INFO,<br />+             "HPET is not enabled, using TSC as default timer");<br />+<br />+#ifdef RTE_LIB_CMDLINE<br />+    char *dpdk_test = getenv("DPDK_TEST");<br />+<br />+    if (dpdk_test && strlen(dpdk_test)) {<br />+        char buf[1024];<br />+<br />+        cl = cmdline_new(main_ctx, "RTE>>", 0, 1);<br />+        if (cl == NULL) {<br />+            ret = -1;<br />+            goto out;<br />+        }<br />+<br />+        snprintf(buf, sizeof(buf), "%s\n", dpdk_test);<br />+        if (cmdline_in(cl, buf, strlen(buf) & (0xffffffff)) < 0) {<br />+            printf("error on cmdline input\n");<br />+<br />+            ret = -1;<br />+        } else {<br />+            ret = last_test_result;<br />+        }<br />+        cmdline_free(cl);<br />+        goto out;<br />+    } else {<br />+        /* if no DPDK_TEST env variable, go interactive */<br />+        cl = cmdline_stdin_new(main_ctx, "RTE>>");<br />+        if (cl == NULL) {<br />+            ret = -1;<br />+            goto out;<br />+        }<br />+<br />+        cmdline_interact(cl);<br />+        cmdline_stdin_exit(cl);<br />+        // cmdline_free(cl);<br />+    }<br />+#endif<br />+<br />+    ret = 0;<br />+<br />+out:<br />+#ifdef RTE_LIB_TIMER<br />+    rte_timer_subsystem_finalize();<br />+#endif<br />+    rte_eal_cleanup();<br />+    return ret;<br />+}<br />diff --git a/examples/zsda/test.h b/examples/zsda/test.h<br />new file mode 100644<br />index 0000000..98db2e5<br />--- /dev/null<br />+++ b/examples/zsda/test.h<br />@@ -0,0 +1,236 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _TEST_H_<br />+#define _TEST_H_<br />+<br />+#include <stddef.h> <br />+#include <sys/queue.h> <br />+<br />+#include <rte_hexdump.h> <br />+#include <rte_test.h> <br />+#include <rte_common.h> <br />+<br />+#include <cmdline_parse.h> <br />+#include <cmdline_parse_string.h> <br />+<br />+#include <zsda_common.h> <br />+<br />+#ifndef TEST_SUCCESS<br />+#define TEST_SUCCESS EXIT_SUCCESS<br />+#endif<br />+<br />+#ifndef TEST_FAILED<br />+#define TEST_FAILED -1<br />+#endif<br />+<br />+#ifndef CHECK_ADDR_NULL<br />+#define CHECK_ADDR_NULL(addr)                                                  \<br />+    do {                                                                   \<br />+        if (addr == NULL) {                                            \<br />+            ZSDA_LOG(ERR, E_NULL);  \<br />+            return TEST_FAILED;                                    \<br />+        }                                                              \<br />+    } while (0)<br />+#endif<br />+<br />+#define TEST_SKIPPED 77<br />+#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE" <br />+<br />+/** Before including test.h file you can define<br />+  * TEST_TRACE_FAILURE(_file, _line, _func) macro to better trace/debug test<br />+  * failures. Mostly useful in test development phase.<br />+  **/<br />+#ifndef TEST_TRACE_FAILURE<br />+#define TEST_TRACE_FAILURE(_file, _line, _func)<br />+#endif<br />+<br />+<br />+#define TEST_ASSERT RTE_TEST_ASSERT<br />+<br />+#define TEST_ASSERT_EQUAL RTE_TEST_ASSERT_EQUAL<br />+<br />+/* Compare two buffers (length in bytes) */<br />+#define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len, msg, ...)                     \<br />+    do {                                                                   \<br />+        if (memcmp(a, b, len)) {                                       \<br />+            printf("TestCase %s() line %d failed: " msg "\n",      \<br />+                   __func__, __LINE__, ##__VA_ARGS__);             \<br />+            TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);      \<br />+            return TEST_FAILED;                                    \<br />+        }                                                              \<br />+    } while (0)<br />+<br />+/* Compare two buffers with offset (length and offset in bytes) */<br />+#define TEST_ASSERT_BUFFERS_ARE_EQUAL_OFFSET(a, b, len, off, msg, ...)         \<br />+    do {                                                                   \<br />+        const uint8_t *_a_with_off = (const uint8_t *)a + off;         \<br />+        const uint8_t *_b_with_off = (const uint8_t *)b + off;         \<br />+        TEST_ASSERT_BUFFERS_ARE_EQUAL(_a_with_off, _b_with_off, len,   \<br />+                          msg);                            \<br />+    } while (0)<br />+<br />+/* Compare two buffers (length in bits) */<br />+#define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(a, b, len, msg, ...)                 \<br />+    do {                                                                   \<br />+        uint8_t _last_byte_a, _last_byte_b;                            \<br />+        uint8_t _last_byte_mask, _last_byte_bits;                      \<br />+        TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, (len >> 3), msg);          \<br />+        if (len % 8) {                                                 \<br />+            _last_byte_bits = len % 8;                             \<br />+            _last_byte_mask = ~((1 << (8 - _last_byte_bits)) - 1); \<br />+            _last_byte_a = ((const uint8_t *)a)[len >> 3];         \<br />+            _last_byte_b = ((const uint8_t *)b)[len >> 3];         \<br />+            _last_byte_a &= _last_byte_mask;                       \<br />+            _last_byte_b &= _last_byte_mask;                       \<br />+            if (_last_byte_a != _last_byte_b) {                    \<br />+                printf("TestCase %s() line %d failed: " msg    \<br />+                       "\n",                                   \<br />+                       __func__, __LINE__, ##__VA_ARGS__);     \<br />+                TEST_TRACE_FAILURE(__FILE__, __LINE__,         \<br />+                           __func__);                  \<br />+                return TEST_FAILED;                            \<br />+            }                                                      \<br />+        }                                                              \<br />+    } while (0)<br />+<br />+/* Compare two buffers with offset (length and offset in bits) */<br />+#define TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT_OFFSET(a, b, len, off, msg, ...)     \<br />+    do {                                                                   \<br />+        uint8_t _first_byte_a, _first_byte_b;                          \<br />+        uint8_t _first_byte_mask, _first_byte_bits;                    \<br />+        uint32_t _len_without_first_byte =                             \<br />+            (off % 8) ? len - (8 - (off % 8)) : len;               \<br />+        uint32_t _off_in_bytes =                                       \<br />+            (off % 8) ? (off >> 3) + 1 : (off >> 3);               \<br />+        const uint8_t *_a_with_off =                                   \<br />+            (const uint8_t *)a + _off_in_bytes;                    \<br />+        const uint8_t *_b_with_off =                                   \<br />+            (const uint8_t *)b + _off_in_bytes;                    \<br />+        TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(_a_with_off, _b_with_off,    \<br />+                          _len_without_first_byte,     \<br />+                          msg);                        \<br />+        if (off % 8) {                                                 \<br />+            _first_byte_bits = 8 - (off % 8);                      \<br />+            _first_byte_mask = (1 << _first_byte_bits) - 1;        \<br />+            _first_byte_a = *(_a_with_off - 1);                    \<br />+            _first_byte_b = *(_b_with_off - 1);                    \<br />+            _first_byte_a &= _first_byte_mask;                     \<br />+            _first_byte_b &= _first_byte_mask;                     \<br />+            if (_first_byte_a != _first_byte_b) {                  \<br />+                printf("TestCase %s() line %d failed: " msg    \<br />+                       "\n",                                   \<br />+                       __func__, __LINE__, ##__VA_ARGS__);     \<br />+                TEST_TRACE_FAILURE(__FILE__, __LINE__,         \<br />+                           __func__);                  \<br />+                return TEST_FAILED;                            \<br />+            }                                                      \<br />+        }                                                              \<br />+    } while (0)<br />+<br />+#define TEST_ASSERT_NOT_EQUAL RTE_TEST_ASSERT_NOT_EQUAL<br />+<br />+#define TEST_ASSERT_SUCCESS RTE_TEST_ASSERT_SUCCESS<br />+<br />+#define TEST_ASSERT_FAIL RTE_TEST_ASSERT_FAIL<br />+<br />+#define TEST_ASSERT_NULL RTE_TEST_ASSERT_NULL<br />+<br />+#define TEST_ASSERT_NOT_NULL RTE_TEST_ASSERT_NOT_NULL<br />+<br />+struct unit_test_case {<br />+    int (*setup)(void);<br />+    void (*teardown)(void);<br />+    int (*testcase)(void);<br />+    const char *name;<br />+    unsigned int enabled;<br />+};<br />+<br />+#define TEST_CASE(fn)                                                          \<br />+    {                                                                      \<br />+        NULL, NULL, fn, #fn, 1                                         \<br />+    }<br />+<br />+#define TEST_CASE_NAMED(name, fn)                                              \<br />+    {                                                                      \<br />+        NULL, NULL, fn, name, 1                                        \<br />+    }<br />+<br />+#define TEST_CASE_ST(setup, teardown, testcase)                                \<br />+    {                                                                      \<br />+        setup, teardown, testcase, #testcase, 1                        \<br />+    }<br />+<br />+#define TEST_CASE_DISABLED(fn)                                                 \<br />+    {                                                                      \<br />+        NULL, NULL, fn, #fn, 0                                         \<br />+    }<br />+<br />+#define TEST_CASE_ST_DISABLED(setup, teardown, testcase)                       \<br />+    {                                                                      \<br />+        setup, teardown, testcase, #testcase, 0                        \<br />+    }<br />+<br />+#define TEST_CASES_END()                                                       \<br />+    {                                                                      \<br />+        NULL, NULL, NULL, NULL, 0                                      \<br />+    }<br />+<br />+static inline void debug_hexdump(FILE *file, const char *title, const void *buf,<br />+                 size_t len)<br />+{<br />+    if (rte_log_get_global_level() == RTE_LOG_DEBUG)<br />+        rte_hexdump(file, title, buf, len);<br />+}<br />+<br />+struct unit_test_suite {<br />+    const char *suite_name;<br />+    int (*setup)(void);<br />+    void (*teardown)(void);<br />+    struct unit_test_case unit_test_cases[];<br />+};<br />+<br />+int unit_test_suite_runner(struct unit_test_suite *suite);<br />+extern int last_test_result;<br />+<br />+extern const char *prgname;<br />+<br />+int commands_init(void);<br />+int test_set_rxtx_conf(cmdline_fixed_string_t mode);<br />+int test_set_rxtx_anchor(cmdline_fixed_string_t type);<br />+int test_set_rxtx_sc(cmdline_fixed_string_t type);<br />+<br />+typedef int(test_callback)(void);<br />+TAILQ_HEAD(test_commands_list, test_command);<br />+struct test_command {<br />+    TAILQ_ENTRY(test_command) next;<br />+    const char *command;<br />+    test_callback *callback;<br />+};<br />+<br />+void add_test_command(struct test_command *t);<br />+<br />+struct cml_run_test {<br />+    char func[128];<br />+    char name[128];<br />+    int arg0;<br />+    int arg1;<br />+    int arg2;<br />+};<br />+<br />+/* Register a test function with its command string */<br />+#define REGISTER_TEST_COMMAND(cmd, func)                                       \<br />+    static struct test_command test_struct_##cmd = {                       \<br />+        .command = RTE_STR(cmd),                                       \<br />+        .callback = func,                                              \<br />+    };                                                                     \<br />+    RTE_INIT(test_register_##cmd)                                          \<br />+    {                                                                      \<br />+        add_test_command(&test_struct_##cmd);                          \<br />+    }<br />+<br />+extern uint8_t *g_name_core;<br />+extern void zsda_test_func_cmdline(struct cml_run_test *res);<br />+<br />+#endif<br />diff --git a/examples/zsda/test_zsda.c b/examples/zsda/test_zsda.c<br />new file mode 100644<br />index 0000000..748dd9b<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda.c<br />@@ -0,0 +1,309 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <dirent.h> <br />+#include <fcntl.h> <br />+#include <sys/mman.h> <br />+<br />+#include "rte_lcore.h" <br />+<br />+#include "test_zsda.h" <br />+#include "test_zsda_cryptodev.h" <br />+#include "zsda_device.h" <br />+<br />+#define DPU_PCI_DEVICES_DIR "/sys/bus/pci/devices" <br />+#define FILE_PATH_LEN        (100)<br />+<br />+const char *zsda_device_name[4] = {<br />+    "crypto",<br />+    "comp",<br />+};<br />+<br />+struct zsda_test_dev_info zsda_info[ZSDA_MAX_QUEUE];<br />+struct zsda_thread zsda_data[ZSDA_MAX_QUEUE];<br />+uint32_t global_zsda_idx;<br />+<br />+static int<br />+zsda_unit_test_suite_runner(struct zsda_unit_test_suite *suite,<br />+                struct zsda_test_dev_info *dev_info)<br />+{<br />+    unsigned int total = 0;<br />+    unsigned int failed = 0;<br />+    unsigned int executed = 0;<br />+    unsigned int skipped = 0;<br />+    unsigned int succeeded = 0;<br />+    unsigned int unsupported = 0;<br />+    int test_success;<br />+    const char *status;<br />+<br />+    if (suite->suite_name) {<br />+        printf("\n");<br />+        printf(" + " <br />+               "---------------------------*---------------------------" <br />+               "- +\n");<br />+        printf(" + Test Suite : %s\n", suite->suite_name);<br />+    }<br />+<br />+    if (suite->setup) {<br />+        test_success = suite->setup(dev_info);<br />+        if (test_success != 0) {<br />+            while (suite->unit_test_cases[total].testcase) {<br />+                if (!suite->unit_test_cases[total].enabled ||<br />+                    test_success == TEST_SKIPPED)<br />+                    skipped++;<br />+                else<br />+                    failed++;<br />+                total++;<br />+            }<br />+            goto suite_summary;<br />+        }<br />+    }<br />+<br />+    printf(" + ---------------------------*--------------------------- " <br />+           "+\n\n");<br />+<br />+    while (suite->unit_test_cases[total].testcase) {<br />+        if (!suite->unit_test_cases[total].enabled) {<br />+            skipped++;<br />+            total++;<br />+            continue;<br />+        } else<br />+            executed++;<br />+<br />+        if (suite->unit_test_cases[total].setup)<br />+            test_success =<br />+                suite->unit_test_cases[total].setup(dev_info);<br />+        else<br />+            test_success = TEST_SUCCESS;<br />+<br />+        if (test_success == TEST_SUCCESS) {<br />+            test_success = suite->unit_test_cases[total].testcase(<br />+                dev_info);<br />+            if (test_success == TEST_SUCCESS)<br />+                succeeded++;<br />+            else if (test_success == TEST_SKIPPED)<br />+                skipped++;<br />+            else if (test_success == -ENOTSUP)<br />+                unsupported++;<br />+            else<br />+                failed++;<br />+        } else if (test_success == -ENOTSUP)<br />+            unsupported++;<br />+        else<br />+            failed++;<br />+<br />+        if (suite->unit_test_cases[total].teardown)<br />+            suite->unit_test_cases[total].teardown(dev_info);<br />+<br />+        if (test_success == TEST_SUCCESS)<br />+            status = "succeeded";<br />+        else if (test_success == TEST_SKIPPED)<br />+            status = "skipped";<br />+        else if (test_success == -ENOTSUP)<br />+            status = "unsupported";<br />+        else<br />+            status = "failed";<br />+<br />+        printf(" +++++ TestCase [%2d] : %s %s\n\n", total,<br />+               suite->unit_test_cases[total].name, status);<br />+<br />+        total++;<br />+    }<br />+<br />+    if (suite->teardown)<br />+        suite->teardown(dev_info);<br />+<br />+    goto suite_summary;<br />+<br />+suite_summary:<br />+    printf("\n");<br />+    printf(" + ------------------------------------------------------- " <br />+           "+\n");<br />+    printf(" + Test Suite Summary\n");<br />+    printf(" + Tests Total :       %2d\n", total);<br />+    printf(" + Tests Skipped :     %2d\n", skipped);<br />+    printf(" + Tests Executed :    %2d\n", executed);<br />+    printf(" + Tests Unsupported:  %2d\n", unsupported);<br />+    printf(" + Tests Passed :      %2d\n", succeeded);<br />+    printf(" + Tests Failed :      %2d\n", failed);<br />+    printf(" + ------------------------------------------------------- " <br />+           "+\n");<br />+<br />+    printf("test cases finished!\n");<br />+    last_test_result = (int)failed;<br />+<br />+    if (failed)<br />+        return TEST_FAILED;<br />+    if (total == skipped)<br />+        return TEST_SKIPPED;<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int<br />+zsda_launch_one_lcore(__rte_unused void *dummy)<br />+{<br />+    uint32_t id = rte_lcore_id();<br />+    uint32_t index = id - rte_get_main_lcore();<br />+<br />+    if (false == zsda_info[index].used)<br />+        return TEST_FAILED;<br />+    if (zsda_info[index].testing)<br />+        return TEST_FAILED;<br />+<br />+    zsda_info[index].testing = true;<br />+<br />+    switch (zsda_info[index].dev_type) {<br />+    case zsda_crypto:<br />+        zsda_unit_test_suite_runner(&cryptodev_zsda_testsuite_private,<br />+                        &zsda_info[index]);<br />+        break;<br />+    case zsda_compress:<br />+        zsda_unit_test_suite_runner(&compressdev_zsda_testsuite_private,<br />+                        &zsda_info[index]);<br />+        break;<br />+    default:<br />+        break;<br />+    }<br />+<br />+    zsda_info[id - rte_get_main_lcore()].testing = false;<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static void<br />+rebuild_device_info(void)<br />+{<br />+    uint8_t nb_devs = 0;<br />+    uint8_t i = 0;<br />+    uint16_t j = 0;<br />+    struct rte_cryptodev_info cryp_info;<br />+    struct rte_compressdev_info comp_info;<br />+<br />+    global_zsda_idx = 0;<br />+    memset(zsda_info, 0, sizeof(zsda_info));<br />+<br />+    nb_devs = rte_cryptodev_count();<br />+    if (nb_devs)<br />+        for (i = 0; i < nb_devs; i++) {<br />+            rte_cryptodev_info_get(i, &cryp_info);<br />+            for (j = 0; j < cryp_info.max_nb_queue_pairs; j++) {<br />+                zsda_info[global_zsda_idx].used = true;<br />+                zsda_info[global_zsda_idx].dev_type =<br />+                    zsda_crypto;<br />+                zsda_info[global_zsda_idx].dev_id = i;<br />+                zsda_info[global_zsda_idx].ring_id = (uint8_t)j;<br />+                global_zsda_idx++;<br />+            }<br />+        }<br />+<br />+    nb_devs = rte_compressdev_count();<br />+    if (nb_devs)<br />+        for (i = 0; i < nb_devs; i++) {<br />+            rte_compressdev_info_get(i, &comp_info);<br />+            for (j = 0; j < comp_info.max_nb_queue_pairs; j++) {<br />+                zsda_info[global_zsda_idx].used = true;<br />+                zsda_info[global_zsda_idx].dev_type =<br />+                    zsda_compress;<br />+                zsda_info[global_zsda_idx].dev_id = i;<br />+                zsda_info[global_zsda_idx].ring_id = (uint8_t)j;<br />+                global_zsda_idx++;<br />+            }<br />+        }<br />+}<br />+<br />+static int<br />+test_zsda_bind_cpu_test(void)<br />+{<br />+    rte_eal_mp_remote_launch(zsda_launch_one_lcore, NULL, CALL_MAIN);<br />+    rte_eal_mp_wait_lcore();<br />+    return 0;<br />+}<br />+<br />+static void *<br />+thread_normal_group_test(void *p)<br />+{<br />+    struct zsda_test_info data;<br />+    struct zsda_test_dev_info info = {0};<br />+    rte_cpuset_t cpuset;<br />+    char thread_name[RTE_MAX_THREAD_NAME_LEN];<br />+<br />+    CPU_ZERO(&cpuset);<br />+    memcpy(&data, p, sizeof(data));<br />+    info.dev_id = 0;<br />+    info.ring_id = data.arg1;<br />+    info.ring_id_start = 0;<br />+    info.ring_id_end = (info.ring_id == 0) ? 1 : info.ring_id;<br />+    CPU_SET(data.cpu_id, &cpuset);<br />+    snprintf(thread_name, sizeof(thread_name), "test-d%d-r%d-c0x%x",<br />+         data.arg0, data.arg1, data.cpu_id);<br />+    rte_thread_setname(pthread_self(), thread_name);<br />+    rte_thread_set_affinity(&cpuset);<br />+<br />+    if (data.zsda_test_type == run_test) {<br />+        switch (data.type) {<br />+        case zsda_crypto:<br />+            zsda_unit_test_suite_runner(<br />+                &cryptodev_zsda_testsuite_private, &info);<br />+            break;<br />+        case zsda_compress:<br />+            zsda_unit_test_suite_runner(<br />+                &compressdev_zsda_testsuite_private, &info);<br />+            break;<br />+        default:<br />+            break;<br />+        }<br />+    }<br />+    return NULL;<br />+}<br />+<br />+static int<br />+test_zsda_mul_thread_test(void)<br />+{<br />+    uint32_t i = 0;<br />+<br />+    for (i = 1; i < 10; i++) {<br />+        if (pthread_create(&zsda_data[i].id, NULL,<br />+                   thread_normal_group_test, &i) != 0)<br />+            break;<br />+    }<br />+<br />+    return 0;<br />+}<br />+<br />+static int<br />+test_rebuild_zsda_deviceinfo(void)<br />+{<br />+    rebuild_device_info();<br />+    return 0;<br />+}<br />+<br />+void<br />+zsda_run_test(enum test_type type, uint8_t arg0, uint8_t arg1, uint8_t arg2,<br />+          enum zsda_group_test_type zsda_test_group_type)<br />+{<br />+    struct zsda_test_info data = {0};<br />+    pthread_t id;<br />+<br />+    data.arg0 = arg0;<br />+    data.arg1 = arg1;<br />+    data.arg2 = arg2;<br />+    data.type = zsda_test_group_type;<br />+    data.zsda_test_type = type;<br />+    data.cpu_id = RTE_PER_LCORE(_lcore_id);<br />+<br />+    switch (type) {<br />+    case run_test:<br />+        pthread_create(&id, NULL, thread_normal_group_test, &data);<br />+        break;<br />+    case run_test_invalid:<br />+        ZSDA_LOG(ERR, "Wrong command");<br />+        break;<br />+    default:<br />+        break;<br />+    }<br />+    return;<br />+}<br />+<br />+REGISTER_TEST_COMMAND(zsda_mul_thread_test, test_zsda_mul_thread_test);<br />+REGISTER_TEST_COMMAND(zsda_bind_cpu_test, test_zsda_bind_cpu_test);<br />+REGISTER_TEST_COMMAND(rebuild_zsda_deviceinfo, test_rebuild_zsda_deviceinfo);<br />diff --git a/examples/zsda/test_zsda.h b/examples/zsda/test_zsda.h<br />new file mode 100644<br />index 0000000..66417f4<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda.h<br />@@ -0,0 +1,457 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef TEST_ZSDA_H_<br />+#define TEST_ZSDA_H_<br />+<br />+#include <math.h> <br />+#include <sys/time.h> <br />+#include <time.h> <br />+#include <unistd.h> <br />+<br />+#include <rte_bus_vdev.h> <br />+#include <rte_common.h> <br />+#include <rte_compressdev.h> <br />+#include <rte_crypto.h> <br />+#include <rte_cryptodev.h> <br />+#include <rte_cryptodev_pmd.h> <br />+#include <rte_ether.h> <br />+#include <rte_hexdump.h> <br />+#include <rte_lcore.h> <br />+#include <rte_malloc.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_memcpy.h> <br />+#include <rte_pause.h> <br />+#include <rte_string_fns.h> <br />+<br />+#include "rte_lcore.h" <br />+#include "test.h" <br />+#include "zsda_common.h" <br />+<br />+#define NO_COMPILE_CI         0<br />+#define MAX_NUM_OPS_INFLIGHT     (4096)<br />+#define MIN_NUM_OPS_INFLIGHT     (128)<br />+#define DEFAULT_NUM_OPS_INFLIGHT (128)<br />+<br />+#define NUM_MBUFS    (8191)<br />+#define MBUF_CACHE_SIZE (256)<br />+<br />+#define MBUF_DATAPAYLOAD_SIZE (8192 * 2)<br />+#define MBUF_SIZE                                                              \<br />+    (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM + MBUF_DATAPAYLOAD_SIZE)<br />+<br />+#define MAX_MBUF_SEGMENT_SIZE 65535<br />+#define MAX_DATA_MBUF_SIZE    (MAX_MBUF_SEGMENT_SIZE - RTE_PKTMBUF_HEADROOM)<br />+#define ZSDA_MAX_QUEUE          2048<br />+<br />+#define RTE_COMP_LEVEL_ZSDA_DEFAULT (9)<br />+#define TIMES_DEQUEUE            3<br />+#define MAX_OP_NUM_ONE_CASE        511<br />+#define NUM_BIG_MBUFS            (512 + 1)<br />+<br />+#define DESCR_CRYPTO_CYCLE "Crypto Cycle" <br />+<br />+#define MAX_NUM_CYCLE        10<br />+#define MAX_NUM_WQE        512<br />+#define ZSDA_SGL_MAX_NUMBER 512<br />+#define MAX_NUM_SEGS        (ZSDA_SGL_MAX_NUMBER / 32 * 31 + 1)<br />+#define SET_NUM_WQE_100        100<br />+<br />+#define EC_BLOCK_LEN_1K (1024)<br />+<br />+#define DATA_LEN_512  (512)<br />+#define DATA_LEN_4096 (4096)<br />+#define DATA_LEN_8192 (8192)<br />+<br />+#define SRC_PATTERN 0xa5<br />+#define DST_PATTERN 0xb6<br />+<br />+enum zsda_group_test_type {<br />+    zsda_crypto = 0,<br />+    zsda_compress,<br />+};<br />+<br />+struct zsda_thread {<br />+    pthread_t id;<br />+};<br />+<br />+enum test_type {<br />+    run_test = 0,<br />+    run_test_invalid,<br />+};<br />+<br />+struct zsda_test_info {<br />+    enum zsda_group_test_type type;<br />+    enum zsda_algo_core zsda_core;<br />+    enum test_type zsda_test_type;<br />+    int cpu_id;<br />+    uint8_t arg0;<br />+    uint8_t arg1;<br />+    uint8_t arg2;<br />+};<br />+<br />+struct crypto_testsuite_params {<br />+    struct rte_mempool *mbuf_pool;<br />+    struct rte_mempool *large_mbuf_pool;<br />+    struct rte_mempool *op_mpool;<br />+    struct rte_mempool *session_mpool;<br />+    struct rte_mempool *session_priv_mpool;<br />+    struct rte_cryptodev_config conf;<br />+    struct rte_cryptodev_qp_conf qp_conf;<br />+<br />+    uint8_t valid_devid;<br />+    uint8_t valid_ringid;<br />+};<br />+<br />+struct crypto_unittest_params {<br />+    struct rte_crypto_sym_xform cipher_xform;<br />+    struct rte_crypto_sym_xform auth_xform;<br />+    struct rte_crypto_sym_xform aead_xform;<br />+<br />+    union {<br />+        struct rte_cryptodev_sym_session *sess;<br />+    };<br />+<br />+    struct rte_crypto_op *op;<br />+    struct rte_mbuf *obuf, *ibuf;<br />+    uint8_t *digest;<br />+};<br />+<br />+struct comp_testsuite_params {<br />+    struct rte_mempool *mbuf_pool;<br />+    struct rte_mempool *op_mpool;<br />+    struct rte_comp_xform *def_comp_xform;<br />+    struct rte_comp_xform *def_decomp_xform;<br />+<br />+    struct rte_compressdev_config conf;<br />+    struct rte_compressdev_qp_conf qp_conf;<br />+<br />+    uint8_t valid_devid;<br />+    uint8_t valid_ringid;<br />+};<br />+<br />+struct comp_unittest_params {<br />+    struct rte_comp_op *op;<br />+    struct rte_mbuf *obuf, *ibuf;<br />+};<br />+<br />+struct zsda_test_dev_info {<br />+    bool used;<br />+    bool testing;<br />+    enum zsda_group_test_type dev_type;<br />+    uint8_t dev_id;<br />+    uint8_t ring_id;<br />+<br />+    uint8_t dev_id_start;<br />+    uint8_t dev_id_end;<br />+    uint8_t ring_id_start;<br />+    uint8_t ring_id_end;<br />+    enum zsda_algo_core algo_core_id;<br />+<br />+    struct crypto_testsuite_params ts_crypto_params;<br />+    struct crypto_unittest_params ut_crypto_params;<br />+    struct comp_testsuite_params ts_comp_params;<br />+    struct comp_unittest_params ut_comp_params;<br />+};<br />+<br />+struct zsda_unit_test_case {<br />+    int (*setup)(struct zsda_test_dev_info *dev_info);<br />+    void (*teardown)(struct zsda_test_dev_info *dev_info);<br />+    int (*testcase)(struct zsda_test_dev_info *dev_info);<br />+    const char *name;<br />+    unsigned int enabled;<br />+};<br />+<br />+struct zsda_unit_test_suite {<br />+    const char *suite_name;<br />+    int (*setup)(struct zsda_test_dev_info *dev_info);<br />+    void (*teardown)(struct zsda_test_dev_info *dev_info);<br />+    struct zsda_unit_test_case unit_test_cases[];<br />+};<br />+<br />+extern struct zsda_unit_test_suite compressdev_zsda_testsuite_private;<br />+extern struct zsda_unit_test_suite cryptodev_zsda_testsuite_private;<br />+<br />+enum zsda_algo_crypto {<br />+    AES_XTS_256,<br />+    AES_XTS_512,<br />+    SM4,<br />+};<br />+<br />+enum zsda_algo_hash {<br />+    HASH_SHA1,<br />+    HASH_SHA224,<br />+    HASH_SHA256,<br />+    HASH_SHA384,<br />+    HASH_SHA512,<br />+    HASH_SM3,<br />+};<br />+<br />+struct data_text {<br />+    uint8_t *data;<br />+    uint32_t len;<br />+};<br />+<br />+struct crypto_data_config {<br />+    struct data_text plaintext;<br />+<br />+    struct data_text aes256_ct;<br />+    struct data_text aes512_ct;<br />+    struct data_text sm4_ct;<br />+<br />+    struct {<br />+        uint8_t data[64];<br />+        uint16_t len;<br />+    } key;<br />+<br />+    struct {<br />+        uint8_t data[16];<br />+        uint16_t len;<br />+    } iv;<br />+    uint32_t lbads;<br />+};<br />+<br />+/**<br />+ * Write (spread) data from buffer to mbuf data<br />+ *<br />+ * @param mbuf<br />+ *   Destination mbuf<br />+ * @param offset<br />+ *   Start offset in mbuf<br />+ * @param len<br />+ *   Number of bytes to copy<br />+ * @param buffer<br />+ *   Continuous source buffer<br />+ */<br />+static inline void<br />+pktmbuf_write(struct rte_mbuf *mbuf, uint32_t offset, uint32_t len,<br />+          const uint8_t *buffer)<br />+{<br />+    uint32_t n = len;<br />+    uint32_t l;<br />+    struct rte_mbuf *m;<br />+    char *dst;<br />+<br />+    for (m = mbuf; (m != NULL) && (offset > m->data_len); m = m->next)<br />+        offset -= m->data_len;<br />+<br />+    if (m == NULL) {<br />+        ZSDA_LOG(ERR, E_NULL);<br />+        return;<br />+    }<br />+<br />+    l = m->data_len - offset;<br />+<br />+    dst = rte_pktmbuf_mtod_offset(m, char *, offset);<br />+    if (len <= l) {<br />+        rte_memcpy(dst, buffer, len);<br />+        return;<br />+    }<br />+<br />+    rte_memcpy(dst, buffer, l);<br />+    buffer += l;<br />+    n -= l;<br />+<br />+    for (m = m->next; (m != NULL) && (n > 0); m = m->next) {<br />+        dst = rte_pktmbuf_mtod(m, char *);<br />+        l = m->data_len;<br />+        if (n < l) {<br />+            rte_memcpy(dst, buffer, n);<br />+            return;<br />+        }<br />+        rte_memcpy(dst, buffer, l);<br />+        buffer += l;<br />+        n -= l;<br />+    }<br />+}<br />+<br />+static inline struct rte_mbuf *<br />+create_segmented_mbuf(struct rte_mempool *mbuf_pool, uint32_t pkt_len,<br />+              uint32_t nb_segs, uint8_t pattern)<br />+{<br />+    struct rte_mbuf *m = NULL, *mbuf = NULL;<br />+    uint8_t *dst;<br />+    uint16_t data_len = 0;<br />+    uint32_t i;<br />+    uint32_t size;<br />+    uint16_t t_len;<br />+<br />+    if (pkt_len < 1) {<br />+        ZSDA_LOG(ERR, "Failed! pkt_len");<br />+        return NULL;<br />+    }<br />+<br />+    if (nb_segs < 1) {<br />+        ZSDA_LOG(ERR, "Failed! nb_segs");<br />+        return NULL;<br />+    }<br />+    t_len = (pkt_len >= nb_segs) ? pkt_len / nb_segs : 1;<br />+    size = pkt_len;<br />+<br />+    /* Create chained mbuf_src and fill it generated data */<br />+    for (i = 0; size > 0; i++) {<br />+        m = rte_pktmbuf_alloc(mbuf_pool);<br />+        if (i == 0)<br />+            mbuf = m;<br />+<br />+        if (m == NULL) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            goto fail;<br />+        }<br />+<br />+        /* Make sure if tailroom is zeroed */<br />+        memset(m->buf_addr, pattern, m->buf_len);<br />+<br />+        data_len = (size > t_len) ? t_len : size & (0xffff);<br />+        if ((i == (nb_segs - 1)) && (size < MAX_DATA_MBUF_SIZE))<br />+            data_len = size & (0xffff);<br />+        dst = (uint8_t *)rte_pktmbuf_append(m, data_len);<br />+        if (dst == NULL) {<br />+            ZSDA_LOG(ERR, E_FUNC);<br />+            goto fail;<br />+        }<br />+<br />+        if (mbuf != m)<br />+            rte_pktmbuf_chain(mbuf, m);<br />+<br />+        size -= data_len;<br />+    }<br />+    return mbuf;<br />+<br />+fail:<br />+    if (mbuf)<br />+        rte_pktmbuf_free(mbuf);<br />+    return NULL;<br />+}<br />+<br />+static inline int<br />+compare_buffers(uint8_t *buffer1, uint32_t buffer1_len, const uint8_t *buffer2,<br />+        uint32_t buffer2_len)<br />+{<br />+    if (buffer1_len != buffer2_len) {<br />+        ZSDA_LOG(ERR, "Len unequal");<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    if (memcmp(buffer1, buffer2, buffer1_len) != 0) {<br />+        ZSDA_LOG(ERR, "Buffers are different");<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+struct Enqueue_dequeue_config {<br />+    uint8_t dev_id;<br />+    uint8_t queue_id;<br />+    uint16_t op_num;<br />+    void **op_array;<br />+    void **cq_array;<br />+    enum zsda_algo_core zsda_core;<br />+};<br />+<br />+struct Op_config {<br />+    void *int_data;<br />+    struct rte_mempool *mbuf_pool;<br />+    struct rte_mempool *op_mpool;<br />+    void **op_array;<br />+    enum zsda_algo_core zsda_core;<br />+};<br />+<br />+struct zsda_buf_config {<br />+    struct rte_mbuf *buf;<br />+    struct rte_mempool *mbuf_pool;<br />+    uint8_t *data;<br />+    uint32_t data_len;<br />+    uint32_t nb_segs;<br />+};<br />+<br />+struct Sgl_offset_config {<br />+    uint32_t *sgls;<br />+    uint32_t *offset;<br />+    uint32_t num_sgls;<br />+    uint32_t num_offset;<br />+    uint32_t *mul_sgls;<br />+    uint32_t *mul_offsets;<br />+};<br />+<br />+static int __rte_unused<br />+buf_create_process(struct zsda_buf_config *buf_config)<br />+{<br />+    struct rte_mbuf *buf = NULL;<br />+    struct rte_mempool *mbuf_pool = buf_config->mbuf_pool;<br />+    uint8_t *data = buf_config->data;<br />+    uint32_t data_len = buf_config->data_len;<br />+    uint32_t nb_segs = buf_config->nb_segs;<br />+<br />+    buf = create_segmented_mbuf(mbuf_pool, data_len, nb_segs,<br />+                    SRC_PATTERN);<br />+    if (buf == NULL) {<br />+        ZSDA_LOG(ERR, "Cannot create mbuf!");<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    pktmbuf_write(buf, 0, data_len, data);<br />+<br />+    buf_config->buf = buf;<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int __rte_unused<br />+buf_create(struct zsda_buf_config *buf_config, bool need_malloc_room)<br />+{<br />+    uint32_t data_len = buf_config->data_len;<br />+    uint32_t nb_segs = buf_config->nb_segs;<br />+    uint8_t *data = buf_config->data;<br />+    uint8_t *str;<br />+<br />+    if (need_malloc_room) {<br />+        str = (uint8_t *)malloc(buf_config->data_len);<br />+        memset(str, DST_PATTERN, buf_config->data_len);<br />+        buf_config->data = str;<br />+    }<br />+<br />+    buf_create_process(buf_config);<br />+<br />+    if (need_malloc_room) {<br />+        free(str);<br />+        str = NULL;<br />+        buf_config->data = data;<br />+        buf_config->data_len = data_len;<br />+        buf_config->nb_segs = nb_segs;<br />+    }<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static inline uint32_t<br />+set_nb_segs(uint32_t int_data_nb_segs, uint32_t data_len)<br />+{<br />+    uint32_t ret_nb_segs;<br />+<br />+    if (int_data_nb_segs == 0)<br />+        ret_nb_segs = ((data_len % MAX_DATA_MBUF_SIZE) == 0)<br />+                      ? (data_len / MAX_DATA_MBUF_SIZE)<br />+                      : ((data_len / MAX_DATA_MBUF_SIZE) + 1);<br />+    else<br />+        ret_nb_segs = int_data_nb_segs;<br />+    if (ret_nb_segs > (ZSDA_SGL_MAX_NUMBER / 32 * 31)) {<br />+        ZSDA_LOG(DEBUG, "Wrong number");<br />+        return 0;<br />+    }<br />+    return ret_nb_segs;<br />+}<br />+<br />+static inline uint32_t<br />+cal_num_sgl(uint32_t nb_segs)<br />+{<br />+    return (nb_segs % 31) + (nb_segs / 31 * 32);<br />+}<br />+<br />+void zsda_run_test(enum test_type type, uint8_t arg0, uint8_t arg1,<br />+           uint8_t arg2,<br />+           enum zsda_group_test_type zsda_test_group_type);<br />+<br />+#endif /* TEST_ZSDA_H_ */<br />diff --git a/examples/zsda/test_zsda_compressdev.c b/examples/zsda/test_zsda_compressdev.c<br />new file mode 100644<br />index 0000000..8be7227<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_compressdev.c<br />@@ -0,0 +1,678 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <string.h> <br />+#include <time.h> <br />+#include <unistd.h> <br />+<br />+#include <rte_build_config.h> <br />+#include <rte_bus_vdev.h> <br />+#include <rte_common.h> <br />+#include <rte_comp.h> <br />+#include <rte_compressdev.h> <br />+#include <rte_compressdev_pmd.h> <br />+#include <rte_ether.h> <br />+#include <rte_hexdump.h> <br />+#include <rte_lcore.h> <br />+#include <rte_malloc.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_memcpy.h> <br />+#include <rte_pause.h> <br />+#include <rte_string_fns.h> <br />+#include <zlib.h> <br />+<br />+#include "test.h" <br />+#include "test_zsda.h" <br />+#include "test_zsda_compressdev.h" <br />+<br />+#define DEFAULT_WINDOW_SIZE          15<br />+#define ZLIB_CRC_CHECKSUM_WINDOW_BITS 31<br />+#define NUM_OPS                  (512 * 2)<br />+#define NUM_MAX_XFORMS              (512 * 2)<br />+#define NUM_MAX_INFLIGHT_OPS          128<br />+#define CACHE_SIZE              0<br />+<br />+char test_msg[COMPRESSDEV_TEST_MSG_LEN + 1];<br />+<br />+static void<br />+testsuite_teardown(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct comp_testsuite_params *ts_params = &(dev_info->ts_comp_params);<br />+<br />+    rte_mempool_free(ts_params->mbuf_pool);<br />+    rte_mempool_free(ts_params->op_mpool);<br />+    rte_free(ts_params->def_comp_xform);<br />+    rte_free(ts_params->def_decomp_xform);<br />+}<br />+<br />+static int<br />+testsuite_setup(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct comp_testsuite_params *ts_params = &(dev_info->ts_comp_params);<br />+    uint8_t nb_devs;<br />+    char name[256] = {0};<br />+<br />+    memset(ts_params, 0, sizeof(*ts_params));<br />+    ts_params->valid_devid = dev_info->dev_id;<br />+    ts_params->valid_ringid = dev_info->ring_id;<br />+    ts_params->conf.socket_id = (int)(rte_socket_id() & 0xffff);<br />+    nb_devs = rte_compressdev_count();<br />+<br />+    if (nb_devs < 1) {<br />+        ZSDA_LOG(ERR, "No compress devices found.\n");<br />+        return TEST_SKIPPED;<br />+    }<br />+<br />+    snprintf(name, sizeof(name), "COMP_POOL_D%d", ts_params->valid_devid);<br />+<br />+    ts_params->mbuf_pool = rte_mempool_lookup(name);<br />+    ts_params->mbuf_pool = rte_pktmbuf_pool_create(<br />+        name, (NUM_BIG_MBUFS * 30) + 1, CACHE_SIZE, 0,<br />+        MAX_MBUF_SEGMENT_SIZE, (int)rte_socket_id());<br />+    if (ts_params->mbuf_pool == NULL) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    snprintf(name, sizeof(name), "COMP_OPPOOL_D%d", ts_params->valid_devid);<br />+    ts_params->op_mpool = rte_comp_op_pool_create(<br />+        name, NUM_OPS * 2, 0, sizeof(uint16_t), rte_socket_id());<br />+    if (ts_params->op_mpool == NULL) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    ts_params->def_comp_xform =<br />+        rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);<br />+    if (ts_params->def_comp_xform == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        goto exit_func;<br />+    }<br />+<br />+    ts_params->def_decomp_xform =<br />+        rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);<br />+    if (ts_params->def_decomp_xform == NULL) {<br />+        ZSDA_LOG(ERR, E_MALLOC);<br />+        goto exit_func;<br />+    }<br />+<br />+    ts_params->def_comp_xform->type = RTE_COMP_COMPRESS;<br />+    ts_params->def_comp_xform->compress.algo = RTE_COMP_ALGO_DEFLATE;<br />+    ts_params->def_comp_xform->compress.deflate.huffman =<br />+        RTE_COMP_HUFFMAN_DEFAULT;<br />+    ts_params->def_comp_xform->compress.level = RTE_COMP_LEVEL_ZSDA_DEFAULT;<br />+    ts_params->def_comp_xform->compress.chksum = RTE_COMP_CHECKSUM_NONE;<br />+    ts_params->def_comp_xform->compress.window_size = DEFAULT_WINDOW_SIZE;<br />+<br />+    ts_params->def_decomp_xform->type = RTE_COMP_DECOMPRESS;<br />+    ts_params->def_decomp_xform->decompress.algo = RTE_COMP_ALGO_DEFLATE;<br />+    ts_params->def_decomp_xform->decompress.chksum = RTE_COMP_CHECKSUM_NONE;<br />+    ts_params->def_decomp_xform->decompress.window_size =<br />+        DEFAULT_WINDOW_SIZE;<br />+<br />+    return TEST_SUCCESS;<br />+<br />+exit_func:<br />+    testsuite_teardown(dev_info);<br />+    return TEST_FAILED;<br />+}<br />+<br />+static int<br />+ut_setup(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct comp_testsuite_params *ts_params = &(dev_info->ts_comp_params);<br />+    struct rte_compressdev_info info;<br />+    uint8_t ring_id_start = dev_info->ring_id_start;<br />+    uint8_t ring_id_end = dev_info->ring_id_end;<br />+    uint16_t qp_id;<br />+    int value = 0;<br />+<br />+    rte_compressdev_info_get(dev_info->dev_id, &info);<br />+    ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;<br />+<br />+    ts_params->conf.socket_id = (int)(rte_socket_id() & 0xffff);<br />+    ts_params->conf.max_nb_priv_xforms = NUM_MAX_XFORMS;<br />+    ts_params->conf.max_nb_streams = 1;<br />+    ts_params->conf.socket_id = SOCKET_ID_ANY;<br />+    ts_params->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT;<br />+<br />+    value = rte_compressdev_configure(ts_params->valid_devid,<br />+                      &(ts_params->conf));<br />+    if (value < 0) {<br />+        ZSDA_LOG(ERR, E_CONFIG);<br />+        return -1;<br />+    }<br />+    if (dev_info->ring_id_end == 0)<br />+        ring_id_end = 1;<br />+<br />+    for (qp_id = ring_id_start; qp_id < ring_id_end; qp_id++) {<br />+        value = rte_compressdev_queue_pair_setup(<br />+            ts_params->valid_devid, qp_id, NUM_MAX_INFLIGHT_OPS,<br />+            rte_socket_id());<br />+        if (value < 0) {<br />+            ZSDA_LOG(ERR, E_START);<br />+            return TEST_FAILED;<br />+        }<br />+    }<br />+<br />+    if (rte_compressdev_start(ts_params->valid_devid) < 0) {<br />+        ZSDA_LOG(ERR, E_START);<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    return 0;<br />+}<br />+<br />+static void<br />+ut_teardown(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct comp_testsuite_params *ts_params = &(dev_info->ts_comp_params);<br />+<br />+    rte_compressdev_stop(ts_params->valid_devid);<br />+    if (rte_compressdev_close(ts_params->valid_devid) < 0)<br />+        ZSDA_LOG(ERR, E_CLOSE);<br />+}<br />+<br />+static int<br />+prepare_test_data(struct Interim_data_params *int_data)<br />+{<br />+    uint32_t i = 0;<br />+<br />+    uint8_t *data_pt = NULL;<br />+    uint8_t *data_ct = NULL;<br />+<br />+    uint32_t len_pt = 0;<br />+    uint32_t len_ct = 0;<br />+    uint8_t data_set;<br />+    uint32_t data_len;<br />+<br />+    enum zsda_comp_test_cases_type test_type = int_data->test_type;<br />+<br />+    switch (test_type) {<br />+    case ZSDA_COMP_SINGLE_CASE:<br />+<br />+        data_len = 2048;<br />+        len_pt = data_len;<br />+        len_ct = data_len;<br />+<br />+        data_set = SRC_PATTERN;<br />+        data_pt = (uint8_t *)malloc(len_pt);<br />+        CHECK_ADDR_NULL(data_pt);<br />+        data_ct = (uint8_t *)malloc(len_ct);<br />+        CHECK_ADDR_NULL(data_ct);<br />+        memset(data_pt, data_set, len_pt);<br />+        memset(data_ct, data_set, len_ct);<br />+        int_data->op_num = 1;<br />+        int_data->num_repeat = 1;<br />+        break;<br />+<br />+    default:<br />+        break;<br />+    }<br />+<br />+    int_data->flag_comp_then_decomp = true;<br />+    for (i = 0; i < int_data->op_num; i++)<br />+        int_data->xforms[i] = int_data->compress_xforms;<br />+<br />+    for (i = 0; i < int_data->op_num; i++) {<br />+        int_data->data_pts[i] = data_pt;<br />+        int_data->data_cts[i] = data_ct;<br />+        int_data->len_pts[i] = len_pt;<br />+        int_data->len_cts[i] = len_ct;<br />+    }<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int<br />+test_run_enqueue_dequeue(struct rte_comp_op **ops,<br />+             struct rte_comp_op **cq_array,<br />+             struct Interim_data_params *int_data)<br />+{<br />+    uint16_t num_enqd = 0;<br />+    uint16_t num_deqd = 0;<br />+    uint16_t op_num = int_data->op_num & 0xffff;<br />+    uint8_t dev_id = int_data->dev_id;<br />+    uint8_t queue_id = int_data->queue_id;<br />+<br />+    num_enqd = rte_compressdev_enqueue_burst(dev_id, queue_id, ops, op_num);<br />+    if (num_enqd < op_num) {<br />+        ZSDA_LOG(ERR, "Some operations could not be enqueued");<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    while (num_deqd != op_num) {<br />+        num_deqd += rte_compressdev_dequeue_burst(dev_id, queue_id,<br />+                              &cq_array[num_deqd],<br />+                              (op_num - num_deqd));<br />+    }<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int<br />+test_results_validation(const struct Interim_data_params *int_data,<br />+            const struct test_private_arrays *test_priv_data)<br />+{<br />+    unsigned int loop;<br />+<br />+    uint8_t *buf1;<br />+    const uint8_t *buf2;<br />+    uint8_t *contig_buf;<br />+    int ret = 0;<br />+<br />+    uint16_t op_num = int_data->op_num;<br />+    struct rte_comp_op **cq_array = test_priv_data->cq_array;<br />+    uint32_t offset = int_data->offset;<br />+    struct rte_comp_xform **xform = int_data->xforms;<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        buf1 = int_data->data_pts[loop];<br />+<br />+        if (xform[loop]->type == RTE_COMP_COMPRESS)<br />+            buf1 = int_data->data_cts[loop];<br />+        else if (xform[loop]->type == RTE_COMP_DECOMPRESS)<br />+            buf1 = int_data->data_pts[loop];<br />+<br />+        contig_buf = rte_malloc(NULL, cq_array[loop]->produced, 0);<br />+        if (contig_buf == NULL) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            return TEST_FAILED;<br />+        }<br />+        buf2 = rte_pktmbuf_read(cq_array[loop]->m_dst, offset,<br />+                    cq_array[loop]->produced, contig_buf);<br />+        CHECK_ADDR_NULL(buf2);<br />+<br />+        ret |= compare_buffers(buf1, cq_array[loop]->produced, buf2,<br />+                       cq_array[loop]->produced);<br />+<br />+        if (ret != TEST_SUCCESS) {<br />+            ZSDA_LOG(ERR, E_COMPARE);<br />+            return TEST_FAILED;<br />+        }<br />+        rte_free(contig_buf);<br />+    }<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int<br />+test_setup_com_bufs(const struct Interim_data_params *int_data,<br />+            struct test_private_arrays *test_priv_data,<br />+            struct rte_mempool *mbuf_pool)<br />+{<br />+    uint16_t loop;<br />+    uint16_t op_num = int_data->op_num;<br />+    uint8_t *data_srcs = NULL;<br />+    uint8_t *data_dsts = NULL;<br />+    uint32_t len_srcs = 0;<br />+    uint32_t len_dsts = 0;<br />+    uint32_t nb_segs_ibuf = 0;<br />+    uint32_t nb_segs_obuf = 0;<br />+    struct rte_comp_xform **xforms = int_data->xforms;<br />+    bool is_need_new_mem = false;<br />+    int ret = 0;<br />+<br />+    struct zsda_buf_config buf_config = {<br />+        .mbuf_pool = mbuf_pool,<br />+    };<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        if (xforms[loop]->type == RTE_COMP_COMPRESS) {<br />+            data_srcs = int_data->data_pts[loop];<br />+            data_dsts = int_data->data_cts[loop];<br />+            len_srcs = int_data->len_pts[loop];<br />+            len_dsts = int_data->len_cts[loop];<br />+            nb_segs_ibuf = set_nb_segs(int_data->nb_segs_plaintext,<br />+                           len_srcs);<br />+            nb_segs_obuf = set_nb_segs(int_data->nb_segs_ciphertext,<br />+                           len_dsts);<br />+            test_priv_data->zsda_core = ZSDA_CORE_COMP;<br />+<br />+        } else if (xforms[loop]->type == RTE_COMP_DECOMPRESS) {<br />+            data_srcs = int_data->data_cts[loop];<br />+            data_dsts = int_data->data_pts[loop];<br />+            len_srcs = int_data->len_cts[loop];<br />+            len_dsts = int_data->len_pts[loop];<br />+            nb_segs_ibuf = set_nb_segs(int_data->nb_segs_ciphertext,<br />+                           len_srcs);<br />+            nb_segs_obuf = set_nb_segs(int_data->nb_segs_plaintext,<br />+                           len_dsts);<br />+            test_priv_data->zsda_core = ZSDA_CORE_DECOMP;<br />+        }<br />+<br />+        buf_config.data = data_srcs;<br />+        buf_config.data_len = len_srcs;<br />+        buf_config.nb_segs = nb_segs_ibuf;<br />+        is_need_new_mem = false;<br />+        ret |= buf_create(&buf_config, is_need_new_mem);<br />+        int_data->ibuf[loop] = buf_config.buf;<br />+<br />+        buf_config.data = data_dsts;<br />+        buf_config.data_len = len_dsts;<br />+        is_need_new_mem = true;<br />+        buf_config.nb_segs = nb_segs_obuf;<br />+        ret |= buf_create(&buf_config, is_need_new_mem);<br />+        int_data->obuf[loop] = buf_config.buf;<br />+    }<br />+<br />+    if (ret != TEST_SUCCESS)<br />+        ret = TEST_FAILED;<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+test_comp_copy_to_dst(const struct Interim_data_params *int_data,<br />+              const struct test_private_arrays *test_priv_data)<br />+<br />+{<br />+    struct rte_comp_op **ops = test_priv_data->ops;<br />+    struct rte_comp_op **cq_array = test_priv_data->cq_array;<br />+    uint8_t *contig_buf = NULL;<br />+    const uint8_t *buf2 = NULL;<br />+    uint16_t loop;<br />+    uint16_t op_num = int_data->op_num;<br />+    uint32_t offset = int_data->offset;<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        contig_buf = rte_malloc(NULL, cq_array[loop]->produced, 0);<br />+        CHECK_ADDR_NULL(contig_buf);<br />+        buf2 = rte_pktmbuf_read(cq_array[loop]->m_dst, offset,<br />+                    cq_array[loop]->produced, contig_buf);<br />+        CHECK_ADDR_NULL(buf2);<br />+        if (int_data->len_cts[loop] >= cq_array[loop]->produced) {<br />+            memcpy(int_data->data_cts[loop], buf2,<br />+                   cq_array[loop]->produced);<br />+            int_data->len_cts[loop] = cq_array[loop]->produced;<br />+        } else<br />+            ZSDA_LOG(ERR, E_COMPARE);<br />+<br />+        rte_free(contig_buf);<br />+    }<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        rte_pktmbuf_free(int_data->ibuf[loop]);<br />+        rte_pktmbuf_free(int_data->obuf[loop]);<br />+        int_data->ibuf[loop] = NULL;<br />+        int_data->obuf[loop] = NULL;<br />+    }<br />+    rte_comp_op_bulk_free(ops, op_num);<br />+    ops[loop] = NULL;<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int<br />+test_deflate_comp_decomp_run(struct Interim_data_params *int_data,<br />+                 const struct test_private_arrays *test_priv_data,<br />+                 struct rte_mempool *op_mpool)<br />+{<br />+    uint16_t loop = 0;<br />+    int ret = 0;<br />+    uint16_t op_num = int_data->op_num;<br />+    struct rte_comp_op **ops = test_priv_data->ops;<br />+    struct rte_comp_op **cq_array = test_priv_data->cq_array;<br />+    void **priv_xforms = test_priv_data->priv_xforms;<br />+    uint8_t dev_id = int_data->dev_id;<br />+    struct rte_comp_xform **xforms = int_data->xforms;<br />+    struct rte_mbuf **ibuf = int_data->ibuf;<br />+    struct rte_mbuf **obuf = int_data->obuf;<br />+<br />+    ret = rte_comp_op_bulk_alloc(op_mpool, ops, op_num);<br />+    if (ret < 0) {<br />+        ZSDA_LOG(ERR, E_COMPARE);<br />+        ret = TEST_FAILED;<br />+        goto exit_func;<br />+    }<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        ops[loop]->src.offset = int_data->offset;<br />+        ops[loop]->src.length =<br />+            rte_pktmbuf_pkt_len(ibuf[loop]) - ops[loop]->src.offset;<br />+        ops[loop]->dst.offset = int_data->offset;<br />+<br />+        ops[loop]->m_src = ibuf[loop];<br />+        ops[loop]->m_dst = obuf[loop];<br />+        ops[loop]->input_chksum = 0;<br />+        ops[loop]->flush_flag = RTE_COMP_FLUSH_FINAL;<br />+        ops[loop]->output_chksum = 0;<br />+<br />+        ret = rte_compressdev_private_xform_create(dev_id, xforms[loop],<br />+                               &priv_xforms[loop]);<br />+        if (ret < 0) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+        ops[loop]->private_xform = priv_xforms[loop];<br />+    }<br />+<br />+    ret = test_run_enqueue_dequeue(ops, cq_array, int_data);<br />+    if (ret < 0) {<br />+        ZSDA_LOG(ERR, "Compression: enqueue/dequeue operation failed");<br />+        return TEST_FAILED;<br />+    }<br />+<br />+exit_func:<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        rte_compressdev_private_xform_free(dev_id, priv_xforms[loop]);<br />+        rte_compressdev_private_xform_free(dev_id,<br />+                           ops[loop]->private_xform);<br />+        priv_xforms[loop] = NULL;<br />+        ops[loop]->private_xform = NULL;<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+test_case_comp_decomp(struct Interim_data_params *int_data,<br />+              struct rte_mempool *mbuf_pool,<br />+              struct rte_mempool *op_mpool)<br />+{<br />+    int ret = 0;<br />+    unsigned int i;<br />+    uint16_t op_num = int_data->op_num;<br />+    struct test_private_arrays test_priv_data;<br />+    struct rte_comp_op *ops[MAX_NUM_WQE];<br />+    struct rte_comp_op *cq_array[MAX_NUM_WQE];<br />+    void *priv_xforms[MAX_NUM_WQE];<br />+    bool flag_comp_then_decomp = int_data->flag_comp_then_decomp;<br />+    uint16_t loop;<br />+<br />+    test_priv_data.ops = ops;<br />+    test_priv_data.cq_array = cq_array;<br />+    test_priv_data.priv_xforms = priv_xforms;<br />+<br />+    ret = test_setup_com_bufs(int_data, &test_priv_data, mbuf_pool);<br />+    if (ret < 0) {<br />+        ret = TEST_FAILED;<br />+        goto exit_func;<br />+    }<br />+<br />+    /* Run compression */<br />+    ret = test_deflate_comp_decomp_run(int_data, &test_priv_data, op_mpool);<br />+    if (ret < 0) {<br />+        ret = TEST_FAILED;<br />+        goto exit_func;<br />+    }<br />+<br />+    /* only be used to - decomp after comp */<br />+    if (flag_comp_then_decomp) {<br />+        test_comp_copy_to_dst(int_data, &test_priv_data);<br />+<br />+        for (i = 0; i < int_data->op_num; i++)<br />+            int_data->xforms[i]->type = RTE_COMP_DECOMPRESS;<br />+<br />+        ret = test_setup_com_bufs(int_data, &test_priv_data, mbuf_pool);<br />+        if (ret < 0) {<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+<br />+        /* Run decompression */<br />+        ret = test_deflate_comp_decomp_run(int_data, &test_priv_data,<br />+                           op_mpool);<br />+        if (ret < 0) {<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+    }<br />+<br />+    ret = test_results_validation(int_data, &test_priv_data);<br />+    if (ret < 0) {<br />+        ZSDA_LOG(ERR, E_COMPARE);<br />+        ret = TEST_FAILED;<br />+        goto exit_func;<br />+    }<br />+<br />+exit_func:<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        rte_pktmbuf_free(int_data->ibuf[loop]);<br />+        rte_pktmbuf_free(int_data->obuf[loop]);<br />+        rte_comp_op_bulk_free(ops, op_num);<br />+        int_data->ibuf[loop] = NULL;<br />+        int_data->obuf[loop] = NULL;<br />+        ops[loop] = NULL;<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+test_zsda_one_case_Comp(struct Interim_data_params *int_data,<br />+            struct rte_mempool *mbuf_pool,<br />+            struct rte_mempool *op_mpool, char *test_msg)<br />+{<br />+    uint32_t repeat_one_case;<br />+    uint32_t i = 0;<br />+    int ret = 0;<br />+<br />+    repeat_one_case = int_data->num_repeat == 0 ? 1 : int_data->num_repeat;<br />+<br />+    for (i = 0; i < repeat_one_case; i++) {<br />+        ret = test_case_comp_decomp(int_data, mbuf_pool, op_mpool);<br />+<br />+        if (ret == TEST_SUCCESS)<br />+            snprintf(test_msg, COMPRESSDEV_TEST_MSG_LEN, "PASS");<br />+        else<br />+            snprintf(test_msg, COMPRESSDEV_TEST_MSG_LEN, "FAIL");<br />+    }<br />+    return ret;<br />+}<br />+<br />+static int<br />+test_compressdev(struct zsda_test_dev_info *dev_info,<br />+         enum rte_comp_checksum_type checksum_type,<br />+         enum zsda_comp_test_cases_type test_type)<br />+{<br />+    int test_index = 0;<br />+    uint16_t i;<br />+    int ret = 0;<br />+    struct comp_testsuite_params *ts_params = &(dev_info->ts_comp_params);<br />+    const struct rte_compressdev_capabilities *capab;<br />+<br />+    struct rte_mempool *mbuf_pool = ts_params->mbuf_pool;<br />+    struct rte_mempool *op_mpool = ts_params->op_mpool;<br />+<br />+    capab = rte_compressdev_capability_get(0, RTE_COMP_ALGO_DEFLATE);<br />+    TEST_ASSERT(capab != NULL, "Failed to retrieve device capabilities");<br />+<br />+    struct rte_comp_xform *compress_xform =<br />+        rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);<br />+    CHECK_ADDR_NULL(compress_xform);<br />+    memcpy(compress_xform, ts_params->def_comp_xform,<br />+           sizeof(struct rte_comp_xform));<br />+    compress_xform->compress.deflate.huffman = RTE_COMP_HUFFMAN_DYNAMIC;<br />+<br />+    struct rte_comp_xform *decompress_xform =<br />+        rte_malloc(NULL, sizeof(struct rte_comp_xform), 0);<br />+    CHECK_ADDR_NULL(decompress_xform);<br />+    memcpy(decompress_xform, ts_params->def_decomp_xform,<br />+           sizeof(struct rte_comp_xform));<br />+<br />+    uint8_t *data_plaintext_mul[512];<br />+    uint8_t *data_ciphertext_mul[512];<br />+    uint32_t len_plaintext_mul[512];<br />+    uint32_t len_ciphertext_mul[512];<br />+<br />+    struct rte_mbuf *ibuf[512];<br />+    struct rte_mbuf *obuf[512];<br />+<br />+    struct rte_comp_xform *xforms[512] = {NULL};<br />+<br />+    compress_xform->compress.chksum = checksum_type;<br />+    decompress_xform->decompress.chksum = checksum_type;<br />+<br />+    struct Interim_data_params int_data = {<br />+        .data_pts = data_plaintext_mul,<br />+        .data_cts = data_ciphertext_mul,<br />+        .len_pts = len_plaintext_mul,<br />+        .len_cts = len_ciphertext_mul,<br />+        .ibuf = ibuf,<br />+        .obuf = obuf,<br />+        .dev_id = ts_params->valid_devid,<br />+        .queue_id = ts_params->valid_ringid,<br />+        .test_type = test_type,<br />+        .num_repeat = 1,<br />+        .zlib_dir = ZLIB_NONE,<br />+        .xforms = xforms,<br />+        .compress_xforms = compress_xform,<br />+        .decompress_xforms = decompress_xform,<br />+    };<br />+<br />+    prepare_test_data(&int_data);<br />+<br />+    for (i = 0; i < int_data.num_repeat; i++) {<br />+        ret = test_zsda_one_case_Comp(&int_data, mbuf_pool, op_mpool,<br />+                          test_msg);<br />+        ZSDA_LOG(INFO, "  %u) TestCase %s\n", test_index++, test_msg);<br />+        goto exit_func;<br />+    }<br />+<br />+exit_func:<br />+    for (i = 0; i < int_data.op_num; i++) {<br />+        free(int_data.data_pts[i]);<br />+        free(int_data.data_cts[i]);<br />+        int_data.data_pts[i] = NULL;<br />+        int_data.data_cts[i] = NULL;<br />+    }<br />+<br />+    rte_free(compress_xform);<br />+    rte_free(decompress_xform);<br />+    compress_xform = NULL;<br />+    decompress_xform = NULL;<br />+<br />+    return ret;<br />+}<br />+<br />+static int __rte_unused<br />+test_zsda_compress_single_case_ZLIB(struct zsda_test_dev_info *dev_info)<br />+{<br />+    return test_compressdev(dev_info, RTE_COMP_CHECKSUM_ADLER32,<br />+                ZSDA_COMP_SINGLE_CASE);<br />+}<br />+static int __rte_unused<br />+test_zsda_compress_single_case_GZIP(struct zsda_test_dev_info *dev_info)<br />+{<br />+    return test_compressdev(dev_info, RTE_COMP_CHECKSUM_CRC32,<br />+                ZSDA_COMP_SINGLE_CASE);<br />+}<br />+/* clang-format off */<br />+struct zsda_unit_test_suite compressdev_zsda_testsuite_private = {<br />+    .suite_name = "Compressdev Unit Test Suite",<br />+    .setup = testsuite_setup,<br />+    .teardown = testsuite_teardown,<br />+    .unit_test_cases = {<br />+        TEST_CASE_ST(ut_setup, ut_teardown,<br />+                 test_zsda_compress_single_case_ZLIB),<br />+        TEST_CASE_ST(ut_setup, ut_teardown,<br />+                 test_zsda_compress_single_case_GZIP),<br />+<br />+        TEST_CASES_END(), /**< NULL terminate unit test array */<br />+    },<br />+};<br />+/* clang-format on */<br />diff --git a/examples/zsda/test_zsda_compressdev.h b/examples/zsda/test_zsda_compressdev.h<br />new file mode 100644<br />index 0000000..e8f80d1<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_compressdev.h<br />@@ -0,0 +1,93 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef TEST_ZSDA_COMPRESSDEV_H_<br />+#define TEST_ZSDA_COMPRESSDEV_H_<br />+<br />+#ifndef COMPRESSDEV_TEST_MSG_LEN<br />+#define COMPRESSDEV_TEST_MSG_LEN 256<br />+#endif<br />+<br />+enum zsda_comp_test_cases_type {<br />+    ZSDA_COMP_ONLY_COMP,<br />+    ZSDA_COMP_ONLY_DECOMP,<br />+    ZSDA_COMP_SINGLE_CASE,<br />+    ZSDA_COMP_ONLY_DECOMP_FLOW_4k,<br />+    ZSDA_COMP_ONLY_COMP_FLOW_4k_SAME,<br />+};<br />+<br />+enum zlib_direction {<br />+    ZLIB_NONE,<br />+    ZLIB_COMPRESS,<br />+    ZLIB_DECOMPRESS,<br />+    ZLIB_ALL,<br />+};<br />+<br />+enum Operate_type {<br />+    OPERATE_COMPRESSION,<br />+    OPERATE_DECOMPRESSION,<br />+    OPERATE_MIX,<br />+};<br />+<br />+struct Interim_data_params {<br />+    uint8_t **data_pts;<br />+    uint8_t **data_cts;<br />+    uint32_t *len_pts;<br />+    uint32_t *len_cts;<br />+<br />+    struct rte_mbuf **ibuf;<br />+    struct rte_mbuf **obuf;<br />+<br />+    uint32_t nb_segs_plaintext;<br />+    uint32_t nb_segs_ciphertext;<br />+    uint8_t dev_id;<br />+    uint8_t queue_id;<br />+<br />+    bool flag_comp_then_decomp;<br />+<br />+    uint16_t op_num;<br />+    uint32_t num_repeat;<br />+    uint32_t offset;<br />+<br />+    enum zsda_algo_core core;<br />+    double rate;<br />+<br />+    enum zsda_comp_test_cases_type test_type;<br />+    enum zlib_direction zlib_dir;<br />+<br />+    struct rte_comp_xform *compress_xforms;<br />+    struct rte_comp_xform *decompress_xforms;<br />+    struct rte_comp_xform **xforms;<br />+};<br />+<br />+struct test_private_arrays {<br />+    struct rte_comp_op **ops;<br />+    struct rte_comp_op **cq_array;<br />+    void **priv_xforms;<br />+    uint64_t *compress_checksum;<br />+    enum zsda_algo_core zsda_core;<br />+};<br />+<br />+struct compdev_test_data {<br />+    uint8_t *plaintext_data;<br />+    uint32_t plaintext_len;<br />+<br />+    uint8_t *ciphertext_data;<br />+    uint32_t ciphertext_len;<br />+};<br />+<br />+enum zsda_comp_checksum_type {<br />+    ZSDA_COMP_CHECKSUM_NONE,<br />+    ZSDA_COMP_CHECKSUM_CRC32_GZIP,<br />+    ZSDA_COMP_CHECKSUM_ADLER32_ZLIB,<br />+    ZSDA_COMP_CHECKSUM_CRC32_ADLER32,<br />+<br />+};<br />+<br />+struct compdev_test_case {<br />+    const char *test_descr;<br />+    struct compdev_test_data *test_data;<br />+};<br />+<br />+#endif<br />diff --git a/examples/zsda/test_zsda_cryptodev.c b/examples/zsda/test_zsda_cryptodev.c<br />new file mode 100644<br />index 0000000..9b9c357<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_cryptodev.c<br />@@ -0,0 +1,794 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include <stdint.h> <br />+#include <stdio.h> <br />+#include <stdlib.h> <br />+#include <time.h> <br />+<br />+#include <rte_bus_vdev.h> <br />+#include <rte_common.h> <br />+#include <rte_crypto.h> <br />+#include <rte_cryptodev.h> <br />+#include <rte_ether.h> <br />+#include <rte_hexdump.h> <br />+#include <rte_lcore.h> <br />+#include <rte_malloc.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_memcpy.h> <br />+#include <rte_pause.h> <br />+#include <rte_string_fns.h> <br />+<br />+#include "test.h" <br />+#include "test_zsda.h" <br />+#include "test_zsda_cryptodev.h" <br />+#include "test_zsda_cryptodev_aes_test_vectors.h" <br />+#include "test_zsda_cryptodev_hash_test_vectors.h" <br />+<br />+static int<br />+testsuite_setup(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct crypto_testsuite_params *ts_params =<br />+        &(dev_info->ts_crypto_params);<br />+    struct rte_cryptodev_info info;<br />+    uint32_t nb_devs;<br />+    uint8_t dev_id;<br />+    char name[256] = {0};<br />+<br />+    memset(ts_params, 0, sizeof(*ts_params));<br />+    ts_params->valid_devid = dev_info->dev_id;<br />+    ts_params->valid_ringid = dev_info->ring_id;<br />+    dev_id = dev_info->dev_id;<br />+<br />+    snprintf(name, sizeof(name), "CRY_POOL_D%d", ts_params->valid_devid);<br />+    ts_params->mbuf_pool = rte_mempool_lookup(name);<br />+    if (ts_params->mbuf_pool == NULL) {<br />+        ts_params->mbuf_pool = rte_pktmbuf_pool_create(<br />+            name, NUM_BIG_MBUFS * 30, MBUF_CACHE_SIZE, 0,<br />+            MAX_MBUF_SEGMENT_SIZE, (int)(rte_socket_id() & 0x0fff));<br />+        if (ts_params->mbuf_pool == NULL) {<br />+            ZSDA_LOG(ERR, E_CREATE);<br />+            return TEST_FAILED;<br />+        }<br />+    }<br />+    snprintf(name, sizeof(name), "CRY_OPPOOL_D%d", ts_params->valid_devid);<br />+    ts_params->op_mpool = rte_crypto_op_pool_create(<br />+        name, RTE_CRYPTO_OP_TYPE_SYMMETRIC, NUM_MBUFS * QP_NUMS,<br />+        MBUF_CACHE_SIZE,<br />+        (DEFAULT_NUM_XFORMS * sizeof(struct rte_crypto_sym_xform)) +<br />+            MAXIMUM_IV_LENGTH,<br />+        (int)(rte_socket_id() & 0xffff));<br />+    if (ts_params->op_mpool == NULL) {<br />+        ZSDA_LOG(ERR, E_CREATE);<br />+        return TEST_FAILED;<br />+    }<br />+<br />+    nb_devs = rte_cryptodev_count();<br />+    if (nb_devs < 1) {<br />+        ZSDA_LOG(WARNING, "No crypto devices found?");<br />+        return TEST_SKIPPED;<br />+    }<br />+<br />+    rte_cryptodev_info_get(dev_id, &info);<br />+<br />+    ts_params->conf.nb_queue_pairs = info.max_nb_queue_pairs;<br />+    ts_params->conf.socket_id = SOCKET_ID_ANY;<br />+    ts_params->conf.ff_disable = RTE_CRYPTODEV_FF_SECURITY;<br />+<br />+    unsigned int session_size =<br />+        rte_cryptodev_sym_get_private_session_size(dev_id);<br />+<br />+    snprintf(name, sizeof(name), "CRY_SESS_MPOOL_D%d",<br />+         ts_params->valid_devid);<br />+    ts_params->session_mpool = rte_cryptodev_sym_session_pool_create(<br />+        name, MAX_NB_SESSIONS, 0, 0, 0, SOCKET_ID_ANY);<br />+    TEST_ASSERT_NOT_NULL(ts_params->session_mpool,<br />+                 "session mempool allocation failed");<br />+<br />+    snprintf(name, sizeof(name), "CRY_SESS_MPOOL_PRIV_D%d",<br />+         ts_params->valid_devid);<br />+    ts_params->session_priv_mpool =<br />+        rte_mempool_create(name, MAX_NB_SESSIONS, session_size, 0, 0,<br />+                   NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);<br />+    TEST_ASSERT_NOT_NULL(ts_params->session_priv_mpool,<br />+                 "session mempool allocation failed");<br />+<br />+    TEST_ASSERT_SUCCESS(rte_cryptodev_configure(dev_id, &ts_params->conf),<br />+                "Failed to configure cryptodev %u with %u qps",<br />+                dev_id, ts_params->conf.nb_queue_pairs);<br />+<br />+    ts_params->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT;<br />+    ts_params->qp_conf.mp_session = ts_params->session_mpool;<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static void<br />+testsuite_teardown(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct crypto_testsuite_params *ts_params =<br />+        &(dev_info->ts_crypto_params);<br />+<br />+    rte_mempool_free(ts_params->mbuf_pool);<br />+    rte_mempool_free(ts_params->op_mpool);<br />+    ts_params->mbuf_pool = NULL;<br />+    ts_params->op_mpool = NULL;<br />+<br />+    if (ts_params->session_priv_mpool != NULL) {<br />+        rte_mempool_free(ts_params->session_priv_mpool);<br />+        ts_params->session_priv_mpool = NULL;<br />+    }<br />+<br />+    if (ts_params->session_mpool != NULL) {<br />+        rte_mempool_free(ts_params->session_mpool);<br />+        ts_params->session_mpool = NULL;<br />+    }<br />+}<br />+<br />+static int<br />+dev_configure_and_start(struct zsda_test_dev_info *dev_info,<br />+            uint64_t ff_disable)<br />+{<br />+    struct crypto_testsuite_params *ts_params =<br />+        &(dev_info->ts_crypto_params);<br />+    struct crypto_unittest_params *ut_params =<br />+        &(dev_info->ut_crypto_params);<br />+    uint16_t qp_id;<br />+<br />+    memset(ut_params, 0, sizeof(*ut_params));<br />+<br />+    ts_params->conf.socket_id = SOCKET_ID_ANY;<br />+    ts_params->conf.ff_disable = ff_disable;<br />+    ts_params->qp_conf.nb_descriptors = MAX_NUM_OPS_INFLIGHT;<br />+    ts_params->qp_conf.mp_session = ts_params->session_mpool;<br />+<br />+    TEST_ASSERT_SUCCESS(rte_cryptodev_configure(ts_params->valid_devid,<br />+                            &ts_params->conf),<br />+                "Failed to configure cryptodev %u",<br />+                ts_params->valid_devid);<br />+<br />+    if (dev_info->ring_id_end == 0)<br />+        dev_info->ring_id_end = 1;<br />+<br />+    for (qp_id = dev_info->ring_id_start; qp_id < dev_info->ring_id_end;<br />+         qp_id++) {<br />+        TEST_ASSERT_SUCCESS(<br />+            rte_cryptodev_queue_pair_setup(<br />+                ts_params->valid_devid, qp_id,<br />+                &ts_params->qp_conf,<br />+                (int)(rte_socket_id() & 0x0fff)),<br />+            "Failed to setup queue pair %u on cryptodev %u", qp_id,<br />+            ts_params->valid_devid);<br />+    }<br />+<br />+    rte_cryptodev_stats_reset(ts_params->valid_devid);<br />+<br />+    TEST_ASSERT_SUCCESS(rte_cryptodev_start(ts_params->valid_devid),<br />+                "Failed to start cryptodev %u",<br />+                ts_params->valid_devid);<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+static int<br />+ut_setup(struct zsda_test_dev_info *dev_info)<br />+{<br />+    return dev_configure_and_start(dev_info, RTE_CRYPTODEV_FF_SECURITY);<br />+}<br />+<br />+static void<br />+ut_teardown(struct zsda_test_dev_info *dev_info)<br />+{<br />+    struct crypto_testsuite_params *ts_params =<br />+        &(dev_info->ts_crypto_params);<br />+    struct rte_cryptodev_stats stats;<br />+<br />+    rte_cryptodev_stats_get(ts_params->valid_devid, &stats);<br />+    rte_cryptodev_stop(ts_params->valid_devid);<br />+    if (rte_cryptodev_close(ts_params->valid_devid) < 0)<br />+        ZSDA_LOG(ERR, E_CLOSE);<br />+}<br />+<br />+static int<br />+crypto_check_result(struct Interim_data_params *int_data,<br />+            struct rte_crypto_op **cq_array)<br />+{<br />+    struct rte_crypto_sym_op *sym_op;<br />+    int ret = 0;<br />+    uint16_t loop = 0;<br />+    const struct blockcipher_test_case *tc = int_data->tc;<br />+    uint16_t op_num = int_data->op_num;<br />+<br />+    uint8_t *buf1 = NULL;<br />+    const uint8_t *buf2 = NULL;<br />+    uint32_t len_buf1 = 0;<br />+    uint32_t len_buf2 = 0;<br />+    uint8_t *contig_buf;<br />+<br />+    if (cq_array[0]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)<br />+        return TEST_FAILED;<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        sym_op = cq_array[loop]->sym;<br />+        if (tc->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) {<br />+            buf1 = int_data->data_cts[loop];<br />+            len_buf1 = int_data->len_cts[loop];<br />+            len_buf2 = int_data->len_pts[loop];<br />+        } else if (tc->op_mask & BLOCKCIPHER_TEST_OP_DECRYPT) {<br />+            buf1 = int_data->data_pts[loop];<br />+            len_buf1 = int_data->len_pts[loop];<br />+            len_buf2 = int_data->len_cts[loop];<br />+        }<br />+        contig_buf = rte_malloc(NULL, len_buf2, 0);<br />+        CHECK_ADDR_NULL(contig_buf);<br />+        buf2 = rte_pktmbuf_read(sym_op->m_dst, 0, len_buf2, contig_buf);<br />+        CHECK_ADDR_NULL(buf2);<br />+        ret = compare_buffers(buf1, len_buf1, buf2, len_buf2);<br />+<br />+        if (ret != 0) {<br />+            ZSDA_LOG(ERR, E_COMPARE);<br />+            return TEST_FAILED;<br />+        }<br />+        rte_free(contig_buf);<br />+        contig_buf = NULL;<br />+    }<br />+    return ret;<br />+}<br />+<br />+static int<br />+hash_check_result(struct Interim_data_params *int_data,<br />+          struct rte_crypto_op **cq_array)<br />+{<br />+    struct rte_crypto_sym_op *sym_op;<br />+    int ret = 0;<br />+    uint16_t loop = 0;<br />+    uint16_t op_num = int_data->op_num;<br />+<br />+    uint8_t *buf1;<br />+    const uint8_t *buf2;<br />+    uint32_t len_buf1;<br />+    uint32_t len_buf2;<br />+    uint8_t *contig_buf;<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        if (cq_array[0]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)<br />+            return TEST_FAILED;<br />+<br />+        sym_op = cq_array[loop]->sym;<br />+        buf1 = int_data->data_cts[loop];<br />+        len_buf1 = int_data->len_cts[loop];<br />+        len_buf2 = int_data->len_cts[loop];<br />+<br />+        contig_buf = rte_malloc(NULL, len_buf2, 0);<br />+        CHECK_ADDR_NULL(contig_buf);<br />+<br />+        buf2 = rte_pktmbuf_read(sym_op->m_dst, 0, len_buf2,<br />+                    contig_buf);<br />+        CHECK_ADDR_NULL(buf2);<br />+<br />+        ret = compare_buffers(buf1, len_buf1, buf2, len_buf2);<br />+        if (ret != TEST_SUCCESS) {<br />+            ZSDA_LOG(ERR, E_COMPARE);<br />+            return TEST_FAILED;<br />+        }<br />+        rte_free(contig_buf);<br />+        contig_buf = NULL;<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static void<br />+prepare_test_data(struct Interim_data_params *int_data)<br />+{<br />+    uint32_t n_test_cases = 0;<br />+    enum zsda_blockcipher_test_type test_type = int_data->test_type;<br />+<br />+    switch (test_type) {<br />+<br />+    case ZSDA_ONLY_ENCRY:<br />+    case ZSDA_ONLY_DECRY:<br />+<br />+        if (test_type == ZSDA_ONLY_ENCRY) {<br />+            n_test_cases = RTE_DIM(zsda_test_cases_encry);<br />+            int_data->tcs = zsda_test_cases_encry;<br />+        } else {<br />+            n_test_cases = RTE_DIM(zsda_test_cases_decry);<br />+            int_data->tcs = zsda_test_cases_decry;<br />+        }<br />+        int_data->op_num = 1;<br />+        int_data->num_repeat = 1;<br />+        int_data->num_test_cases = n_test_cases;<br />+    break;<br />+<br />+    case ZSDA_HASH:<br />+        n_test_cases = RTE_DIM(zsda_test_cases_hash);<br />+        int_data->tcs = zsda_test_cases_hash;<br />+<br />+        int_data->op_num = 1;<br />+        int_data->num_repeat = 1;<br />+        int_data->num_test_cases = n_test_cases;<br />+    break;<br />+<br />+    default:<br />+        break;<br />+    }<br />+}<br />+<br />+static int<br />+cipheronly_op_config(struct Op_config *op_config)<br />+{<br />+    struct Interim_data_params *int_data = op_config->int_data;<br />+    struct rte_crypto_op **op_array =<br />+        (struct rte_crypto_op **)op_config->op_array;<br />+    struct blockcipher_test_case *tc = int_data->tc;<br />+    struct blockcipher_test_data *tdata = int_data->tc->test_data;<br />+    uint32_t nb_segs = int_data->nb_segs;<br />+    uint16_t op_num = int_data->op_num;<br />+    struct rte_crypto_op *op = NULL;<br />+    uint16_t loop = 0;<br />+<br />+    int ret = 0;<br />+    struct rte_mbuf *ibuf = NULL;<br />+    struct rte_mbuf *obuf = NULL;<br />+    uint8_t *data_pt = NULL;<br />+    uint8_t *data_ct = NULL;<br />+    uint32_t len_pt;<br />+    uint32_t len_ct;<br />+    struct rte_crypto_sym_op *sym_op = NULL;<br />+    struct rte_crypto_sym_xform *cipher_xform = NULL;<br />+    bool is_need_new_mem = false;<br />+<br />+    struct zsda_buf_config buf_config = {<br />+        .mbuf_pool = op_config->mbuf_pool,<br />+    };<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        data_pt = int_data->data_pts[loop];<br />+        data_ct = int_data->data_cts[loop];<br />+        len_pt = int_data->len_pts[loop];<br />+        len_ct = int_data->len_cts[loop];<br />+        op = op_array[loop];<br />+<br />+        if (tc->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {<br />+            op_config->zsda_core = ZSDA_CORE_ENCRY;<br />+            op->sym->xform->cipher.op =<br />+                RTE_CRYPTO_CIPHER_OP_ENCRYPT;<br />+<br />+            buf_config.data = data_pt;<br />+            buf_config.data_len = len_pt;<br />+            buf_config.nb_segs = set_nb_segs(nb_segs, len_pt);<br />+            is_need_new_mem = false;<br />+            ret = buf_create(&buf_config, is_need_new_mem);<br />+            ibuf = buf_config.buf;<br />+<br />+            buf_config.data_len = len_ct;<br />+            buf_config.nb_segs = set_nb_segs(nb_segs, len_ct);<br />+            is_need_new_mem = true;<br />+            ret |= buf_create(&buf_config, is_need_new_mem);<br />+            obuf = buf_config.buf;<br />+<br />+        } else if (tc->op_mask & BLOCKCIPHER_TEST_OP_DECRYPT) {<br />+            op_config->zsda_core = ZSDA_CORE_DECRY;<br />+            op->sym->xform->cipher.op =<br />+                RTE_CRYPTO_CIPHER_OP_DECRYPT;<br />+<br />+            buf_config.data = data_ct;<br />+            buf_config.data_len = len_ct;<br />+            buf_config.nb_segs = set_nb_segs(nb_segs, len_ct);<br />+            is_need_new_mem = false;<br />+            ret = buf_create(&buf_config, is_need_new_mem);<br />+            ibuf = buf_config.buf;<br />+<br />+            buf_config.data_len = len_pt;<br />+            buf_config.nb_segs = set_nb_segs(nb_segs, len_pt);<br />+            is_need_new_mem = true;<br />+            ret |= buf_create(&buf_config, is_need_new_mem);<br />+            obuf = buf_config.buf;<br />+        }<br />+<br />+        sym_op = op->sym;<br />+        sym_op->m_src = ibuf;<br />+        sym_op->m_dst = obuf;<br />+<br />+        cipher_xform = op->sym->xform;<br />+        cipher_xform->next = NULL;<br />+<br />+        cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;<br />+        cipher_xform->cipher.algo = tdata->crypto_algo;<br />+<br />+        cipher_xform->cipher.key.data = tdata->cipher_key.data;<br />+        cipher_xform->cipher.key.length = tdata->cipher_key.len;<br />+        cipher_xform->cipher.iv.offset = IV_OFFSET;<br />+<br />+        cipher_xform->cipher.dataunit_len = tdata->xts_dataunit_len;<br />+        cipher_xform->cipher.iv.length = tdata->iv.len;<br />+<br />+        rte_memcpy(rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET),<br />+               tdata->iv.data, tdata->iv.len);<br />+<br />+        sym_op->cipher.data.length = int_data->len_pts[loop];<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static void<br />+cipheronly_enqueue_and_dequeue(struct Enqueue_dequeue_config *endequeue_config)<br />+{<br />+    uint8_t dev_id = endequeue_config->dev_id;<br />+    uint8_t queue_id = endequeue_config->queue_id;<br />+    uint16_t op_num = endequeue_config->op_num;<br />+    struct rte_crypto_op **op_array =<br />+        (struct rte_crypto_op **)endequeue_config->op_array;<br />+    struct rte_crypto_op **cq_array =<br />+        (struct rte_crypto_op **)endequeue_config->cq_array;<br />+    uint16_t num_dequeue = 0;<br />+<br />+    rte_cryptodev_enqueue_burst(dev_id, queue_id, op_array, op_num);<br />+<br />+    while (num_dequeue < op_num) {<br />+        num_dequeue += rte_cryptodev_dequeue_burst(<br />+            dev_id, queue_id, &cq_array[num_dequeue],<br />+            op_num - num_dequeue);<br />+    }<br />+}<br />+<br />+static int<br />+zsda_cipheronly_config_run(struct Interim_data_params *int_data,<br />+               struct rte_mempool *mbuf_pool,<br />+               struct rte_mempool *op_mpool)<br />+{<br />+    struct rte_crypto_op *op_array[512] = {NULL};<br />+    struct rte_crypto_op *cq_array[512] = {NULL};<br />+<br />+    uint8_t dev_id = int_data->dev_id;<br />+    uint8_t queue_id = int_data->queue_id;<br />+    uint16_t op_num = int_data->op_num;<br />+    int ret = TEST_SUCCESS;<br />+    uint16_t loop = 0;<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        op_array[loop] = rte_crypto_op_alloc(<br />+            op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);<br />+        if (!op_array[loop]) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+<br />+        if (rte_crypto_op_sym_xforms_alloc(op_array[loop], 1) ==<br />+            NULL) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+    }<br />+<br />+    struct Op_config op_config = {<br />+        .int_data = int_data,<br />+        .mbuf_pool = mbuf_pool,<br />+        .op_mpool = op_mpool,<br />+        .op_array = (void **)op_array,<br />+    };<br />+<br />+    struct Enqueue_dequeue_config endequeue_config = {<br />+        .dev_id = dev_id,<br />+        .queue_id = queue_id,<br />+        .op_num = op_num,<br />+        .op_array = (void **)op_array,<br />+        .cq_array = (void **)cq_array,<br />+    };<br />+<br />+    ret = cipheronly_op_config(&op_config);<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, E_CONFIG);<br />+        ret = TEST_FAILED;<br />+        goto exit_func;<br />+    }<br />+<br />+    int_data->core = op_config.zsda_core;<br />+<br />+    endequeue_config.zsda_core = op_config.zsda_core;<br />+    cipheronly_enqueue_and_dequeue(&endequeue_config);<br />+<br />+    ret = crypto_check_result(int_data, cq_array);<br />+<br />+exit_func:<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        if (op_array[loop]) {<br />+            rte_pktmbuf_free(op_array[loop]->sym->m_src);<br />+            rte_pktmbuf_free(op_array[loop]->sym->m_dst);<br />+            rte_crypto_op_free(op_array[loop]);<br />+<br />+            op_array[loop]->sym->m_src = NULL;<br />+            op_array[loop]->sym->m_dst = NULL;<br />+            op_array[loop] = NULL;<br />+        }<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static void<br />+hash_enqueue_and_dequeue(struct Enqueue_dequeue_config *endequeue_config)<br />+{<br />+    uint8_t dev_id = endequeue_config->dev_id;<br />+    uint8_t queue_id = endequeue_config->queue_id;<br />+    uint32_t op_num = endequeue_config->op_num;<br />+    struct rte_crypto_op **op_array =<br />+        (struct rte_crypto_op **)endequeue_config->op_array;<br />+    struct rte_crypto_op **cq_array =<br />+        (struct rte_crypto_op **)endequeue_config->cq_array;<br />+    uint16_t sum_dequeue = 0;<br />+<br />+    rte_cryptodev_enqueue_burst(dev_id, queue_id, op_array, op_num);<br />+<br />+    while (sum_dequeue < op_num) {<br />+        sum_dequeue += rte_cryptodev_dequeue_burst(<br />+            dev_id, queue_id, &cq_array[sum_dequeue], op_num);<br />+    }<br />+}<br />+<br />+<br />+static int<br />+hash_op_config(struct Op_config *op_config)<br />+{<br />+    struct Interim_data_params *int_data = op_config->int_data;<br />+    struct rte_mempool *mbuf_pool = op_config->mbuf_pool;<br />+    struct rte_crypto_op **op_array = (struct rte_crypto_op **)op_config->op_array;<br />+    struct blockcipher_test_data *tdata = int_data->tc->test_data;<br />+    uint32_t nb_segs = int_data->nb_segs;<br />+    uint32_t op_num = int_data->op_num;<br />+<br />+    struct rte_crypto_op *op = NULL;<br />+    uint32_t loop = 0;<br />+    int ret = 0;<br />+    struct rte_mbuf *ibuf = NULL;<br />+    struct rte_mbuf *obuf = NULL;<br />+    bool is_need_new_mem = false;<br />+<br />+    uint8_t *data_pt = NULL;<br />+    uint8_t *data_ct = NULL;<br />+    uint32_t len_pt;<br />+    uint32_t len_ct;<br />+    struct rte_crypto_sym_op *sym_op = NULL;<br />+    struct rte_crypto_sym_xform *auth_xform = NULL;<br />+<br />+    struct zsda_buf_config buf_config = {<br />+        .mbuf_pool = mbuf_pool,<br />+    };<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        op = op_array[loop];<br />+        data_pt = int_data->data_pts[loop];<br />+        data_ct = int_data->data_cts[loop];<br />+        len_pt = int_data->len_pts[loop];<br />+        len_ct = int_data->len_cts[loop];<br />+        op_config->zsda_core = ZSDA_CORE_HASH;<br />+<br />+        buf_config.data = data_pt;<br />+        buf_config.data_len = len_pt;<br />+        buf_config.nb_segs = set_nb_segs(nb_segs, len_pt);<br />+        is_need_new_mem = false;<br />+        ret = buf_create(&buf_config, is_need_new_mem);<br />+        ibuf = buf_config.buf;<br />+<br />+        buf_config.data = data_ct;<br />+        buf_config.data_len = len_ct;<br />+        buf_config.nb_segs = 1;<br />+        ret |= buf_create_process(&buf_config);<br />+        obuf = buf_config.buf;<br />+<br />+        sym_op = op->sym;<br />+        sym_op->m_src = ibuf;<br />+        sym_op->m_dst = obuf;<br />+<br />+        if (ret) {<br />+            ZSDA_LOG(ERR, "Hash cannot create ibuf/obuf");<br />+            return TEST_FAILED;<br />+        }<br />+<br />+        sym_op->auth.data.length = len_pt;<br />+        auth_xform = op->sym->xform;<br />+        auth_xform->next = NULL;<br />+        auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;<br />+        auth_xform->auth.algo = tdata->auth_algo;<br />+        auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;<br />+    }<br />+<br />+    return TEST_SUCCESS;<br />+}<br />+<br />+<br />+static int<br />+zsda_hash_config_run(struct Interim_data_params *int_data,<br />+                    struct rte_mempool *mbuf_pool,<br />+                    struct rte_mempool *op_mpool)<br />+{<br />+    uint8_t dev_id = int_data->dev_id;<br />+    uint8_t queue_id = int_data->queue_id;<br />+    uint32_t op_num = int_data->op_num;<br />+    struct rte_crypto_op *op_array[512] = {NULL};<br />+    struct rte_crypto_op *cq_array[512] = {NULL};<br />+    int ret = TEST_SUCCESS;<br />+    uint32_t loop = 0;<br />+<br />+    struct Op_config op_config = {<br />+        .int_data = int_data,<br />+        .mbuf_pool = mbuf_pool,<br />+        .op_mpool = op_mpool,<br />+        .op_array = (void **)op_array,<br />+    };<br />+<br />+    struct Enqueue_dequeue_config endequeue_config = {<br />+        .dev_id = dev_id,<br />+        .queue_id = queue_id,<br />+        .op_num = op_num,<br />+        .op_array = (void **)op_array,<br />+        .cq_array = (void **)cq_array,<br />+    };<br />+<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        op_array[loop] = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);<br />+        if (!op_array[loop]) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+<br />+        if (rte_crypto_op_sym_xforms_alloc(op_array[loop], 1) == NULL) {<br />+            ZSDA_LOG(ERR, E_MALLOC);<br />+            ret = TEST_FAILED;<br />+            goto exit_func;<br />+        }<br />+    }<br />+<br />+    hash_op_config(&op_config);<br />+    int_data->core = op_config.zsda_core;<br />+<br />+    endequeue_config.zsda_core = op_config.zsda_core;<br />+<br />+    hash_enqueue_and_dequeue(&endequeue_config);<br />+<br />+    ret = hash_check_result(int_data, cq_array);<br />+<br />+exit_func:<br />+    for (loop = 0; loop < op_num; loop++) {<br />+        if (op_array[loop]) {<br />+            rte_pktmbuf_free(op_array[loop]->sym->m_src);<br />+            rte_pktmbuf_free(op_array[loop]->sym->m_dst);<br />+<br />+            op_array[loop]->sym->m_src = NULL;<br />+            op_array[loop]->sym->m_dst = NULL;<br />+<br />+            rte_crypto_op_free(op_array[loop]);<br />+            op_array[loop] = NULL;<br />+        }<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static int<br />+test_zsda_one_case_cipher(struct Interim_data_params *int_data,<br />+              struct rte_mempool *mbuf_pool,<br />+              struct rte_mempool *op_mpool, char *test_msg)<br />+{<br />+    const struct blockcipher_test_case *tc = int_data->tc;<br />+    uint16_t repeat_one_case;<br />+    uint16_t i = 0;<br />+    int ret = 0;<br />+<br />+    repeat_one_case = (int_data->num_repeat == 0) ? 1 : int_data->num_repeat;<br />+<br />+    if ((tc->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) ||<br />+        (tc->op_mask & BLOCKCIPHER_TEST_OP_DECRYPT)) {<br />+        for (i = 0; i < int_data->op_num; i++) {<br />+            int_data->data_pts[i] = tc->test_data->plaintext.data;<br />+            int_data->data_cts[i] = tc->test_data->ciphertext.data;<br />+            int_data->len_pts[i] = tc->test_data->plaintext.len;<br />+            int_data->len_cts[i] = tc->test_data->ciphertext.len;<br />+        }<br />+<br />+    } else if (tc->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {<br />+        for (i = 0; i < int_data->op_num; i++) {<br />+            int_data->data_pts[i] = tc->test_data->plaintext.data;<br />+            int_data->data_cts[i] = tc->test_data->digest.data;<br />+            int_data->len_pts[i] = tc->test_data->plaintext.len;<br />+            int_data->len_cts[i] = tc->test_data->digest.len;<br />+        }<br />+    }<br />+<br />+    for (i = 0; i < repeat_one_case; i++) {<br />+<br />+        if ((tc->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) ||<br />+            (tc->op_mask & BLOCKCIPHER_TEST_OP_DECRYPT)) {<br />+            ret |= zsda_cipheronly_config_run(int_data, mbuf_pool,<br />+                              op_mpool);<br />+        } else if (tc->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {<br />+<br />+            ret |= zsda_hash_config_run(int_data, mbuf_pool,<br />+                            op_mpool);<br />+        }<br />+    }<br />+<br />+    if (ret == TEST_SUCCESS)<br />+        snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");<br />+    else<br />+        snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "FAIL");<br />+    return ret;<br />+}<br />+<br />+static int<br />+test_blockcipher(struct zsda_test_dev_info *dev_info,<br />+         enum zsda_blockcipher_test_type test_type)<br />+{<br />+    struct crypto_testsuite_params *ts_params =<br />+        &(dev_info->ts_crypto_params);<br />+<br />+    struct rte_mempool *mbuf_pool = ts_params->mbuf_pool;<br />+    struct rte_mempool *op_mpool = ts_params->op_mpool;<br />+<br />+    int ret = 0;<br />+    uint32_t i = 0, test_index = 0;<br />+    char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];<br />+<br />+    uint8_t *data_plaintext_mul[MAX_NUM_WQE];<br />+    uint8_t *data_ciphertext_mul[MAX_NUM_WQE];<br />+    uint32_t len_plaintext_mul[MAX_NUM_WQE];<br />+    uint32_t len_ciphertext_mul[MAX_NUM_WQE];<br />+<br />+    struct Interim_data_params int_data = {<br />+        .dev_id = ts_params->valid_devid,<br />+        .queue_id = ts_params->valid_ringid,<br />+        .test_type = test_type,<br />+        .data_pts = data_plaintext_mul,<br />+        .data_cts = data_ciphertext_mul,<br />+        .len_pts = len_plaintext_mul,<br />+        .len_cts = len_ciphertext_mul,<br />+    };<br />+<br />+    prepare_test_data(&int_data);<br />+<br />+    for (i = 0; i < int_data.num_test_cases; i++) {<br />+        int_data.tc = &int_data.tcs[i % int_data.num_test_cases];<br />+        ret |= test_zsda_one_case_cipher(&int_data, mbuf_pool, op_mpool,<br />+                        test_msg);<br />+        ZSDA_LOG(INFO, "  %u) TestCase <%s> %s\n", test_index++,<br />+             int_data.tc->test_descr, test_msg);<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static int __rte_unused<br />+test_zsda_Only_Encry(struct zsda_test_dev_info *dev_info)<br />+{<br />+    return test_blockcipher(dev_info, ZSDA_ONLY_ENCRY);<br />+}<br />+static int __rte_unused<br />+test_zsda_Only_Decry(struct zsda_test_dev_info *dev_info)<br />+{<br />+    return test_blockcipher(dev_info, ZSDA_ONLY_DECRY);<br />+}<br />+static int __rte_unused<br />+test_zsda_Hash(struct zsda_test_dev_info *dev_info)<br />+{<br />+    return test_blockcipher(dev_info, ZSDA_HASH);<br />+}<br />+<br />+<br />+struct zsda_unit_test_suite cryptodev_zsda_testsuite_private = {<br />+    .suite_name = "Crypto Unit Test Suite",<br />+    .setup = testsuite_setup,<br />+    .teardown = testsuite_teardown,<br />+    .unit_test_cases = {<br />+        TEST_CASE_ST(ut_setup, ut_teardown, test_zsda_Only_Encry),<br />+        TEST_CASE_ST(ut_setup, ut_teardown, test_zsda_Only_Decry),<br />+        TEST_CASE_ST(ut_setup, ut_teardown, test_zsda_Hash),<br />+    },<br />+};<br />+<br />+<br />diff --git a/examples/zsda/test_zsda_cryptodev.h b/examples/zsda/test_zsda_cryptodev.h<br />new file mode 100644<br />index 0000000..e86d3e2<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_cryptodev.h<br />@@ -0,0 +1,144 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef TEST_ZSDA_CRYPTODEV_H_<br />+#define TEST_ZSDA_CRYPTODEV_H_<br />+<br />+#include "test_zsda.h" <br />+<br />+#ifndef BLOCKCIPHER_TEST_MSG_LEN<br />+#define BLOCKCIPHER_TEST_MSG_LEN 256<br />+#endif<br />+<br />+#define BLOCKCIPHER_TEST_OP_ENCRYPT    0x01<br />+#define BLOCKCIPHER_TEST_OP_DECRYPT    0x02<br />+#define BLOCKCIPHER_TEST_OP_AUTH_GEN    0x04<br />+#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY 0x08<br />+<br />+#define BLOCKCIPHER_TEST_FEATURE_OOP         0x01<br />+#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS 0x02<br />+#define BLOCKCIPHER_TEST_FEATURE_STOPPER     0x04 /* stop upon failing */<br />+#define BLOCKCIPHER_TEST_FEATURE_SG         0x08 /* Scatter Gather */<br />+#define BLOCKCIPHER_TEST_FEATURE_MULTI_SG     0x10 /* MULTI-LEVEL Scatter Gather  */<br />+#define BLOCKCIPHER_TEST_FEATURE_LARGE_PKT_SG  0x20 /* Large Packet MULTI-LEVEL Scatter Gather */<br />+#define BLOCKCIPHER_TEST_FEATURE_WINDING 0x40<br />+<br />+#define BLOCKCIPHER_TEST_OP_CIPHER                                             \<br />+    (BLOCKCIPHER_TEST_OP_ENCRYPT | BLOCKCIPHER_TEST_OP_DECRYPT)<br />+<br />+#define BLOCKCIPHER_TEST_OP_AUTH                                               \<br />+    (BLOCKCIPHER_TEST_OP_AUTH_GEN | BLOCKCIPHER_TEST_OP_AUTH_VERIFY)<br />+<br />+#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN                                       \<br />+    (BLOCKCIPHER_TEST_OP_ENCRYPT | BLOCKCIPHER_TEST_OP_AUTH_GEN)<br />+<br />+#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC                                    \<br />+    (BLOCKCIPHER_TEST_OP_DECRYPT | BLOCKCIPHER_TEST_OP_AUTH_VERIFY)<br />+<br />+#define DEFAULT_NUM_XFORMS (2)<br />+#define MAXIMUM_IV_LENGTH  (16)<br />+#define IV_OFFSET                                                              \<br />+    (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op) +     \<br />+     (DEFAULT_NUM_XFORMS * sizeof(struct rte_crypto_sym_xform)))<br />+<br />+#define QP_NUMS        16<br />+#define VDEV_ARGS_SIZE    100<br />+#define MAX_NB_SESSIONS 4<br />+<br />+enum blockcipher_test_type {<br />+    BLKCIPHER_AES_CHAIN_TYPE,  /* use aes_chain_test_cases[] */<br />+    BLKCIPHER_AES_TYPE,       /* use aes_cipheronly_test_cases[] */<br />+    BLKCIPHER_AES_DOCSIS_TYPE, /* use aes_docsis_test_cases[] */<br />+    BLKCIPHER_3DES_CHAIN_TYPE, /* use triple_des_chain_test_cases[] */<br />+    BLKCIPHER_3DES_TYPE,       /* triple_des_cipheronly_test_cases[] */<br />+    BLKCIPHER_AUTHONLY_TYPE,   /* use hash_test_cases[] */<br />+    BLKCIPHER_DES_TYPE,       /* use des_cipheronly_test_cases[] */<br />+    BLKCIPHER_DES_DOCSIS_TYPE  /* use des_docsis_test_cases[] */<br />+};<br />+<br />+struct blockcipher_test_case {<br />+    const char *test_descr;<br />+    struct blockcipher_test_data *test_data;<br />+    uint8_t op_mask;<br />+};<br />+<br />+struct blockcipher_test_data {<br />+    enum rte_crypto_cipher_algorithm crypto_algo;<br />+<br />+    struct {<br />+        uint8_t data[64];<br />+        uint16_t len;<br />+    } cipher_key;<br />+<br />+    struct {<br />+        uint8_t data[16];<br />+        uint16_t len;<br />+    } iv;<br />+<br />+    struct {<br />+        uint8_t *data;<br />+        uint32_t len;<br />+    } plaintext;<br />+<br />+    struct {<br />+        uint8_t *data;<br />+        uint32_t len;<br />+    } ciphertext;<br />+<br />+    enum rte_crypto_auth_algorithm auth_algo;<br />+<br />+    struct {<br />+        uint8_t data[128];<br />+        uint16_t len;<br />+    } auth_key;<br />+<br />+    struct {<br />+        uint8_t data[128];<br />+        uint16_t len;<br />+        uint16_t truncated_len;<br />+    } digest;<br />+<br />+    unsigned int cipher_offset;<br />+    uint32_t xts_dataunit_len;<br />+    bool wrapped_key;<br />+<br />+};<br />+<br />+enum zsda_blockcipher_test_type {<br />+    ZSDA_ONLY_ENCRY,<br />+    ZSDA_ONLY_DECRY,<br />+    ZSDA_HASH,<br />+};<br />+<br />+struct hash_mul_results_check {<br />+    uint32_t num;<br />+    uint8_t **mul_results;<br />+    uint32_t *digest_lens;<br />+};<br />+<br />+struct Interim_data_params {<br />+    struct blockcipher_test_case *tcs;<br />+    struct blockcipher_test_case *tc;<br />+    uint8_t dev_id;<br />+    uint8_t queue_id;<br />+    uint32_t nb_segs;<br />+    uint16_t op_num;<br />+    uint16_t num_repeat;<br />+    uint32_t num_test_cases;<br />+    uint32_t len_plaintext;<br />+    uint32_t len_ciphertext;<br />+    uint32_t xts_dataunit_len;<br />+<br />+    enum zsda_algo_core core;<br />+<br />+    uint8_t **data_pts;<br />+    uint8_t **data_cts;<br />+    uint32_t *len_pts;<br />+    uint32_t *len_cts;<br />+<br />+    uint8_t *data_pt;<br />+    uint8_t *data_ct;<br />+    enum zsda_blockcipher_test_type test_type;<br />+};<br />+#endif /* TEST_ZSDA_CRYPTODEV_H_ */<br />diff --git a/examples/zsda/test_zsda_cryptodev_aes_test_vectors.h b/examples/zsda/test_zsda_cryptodev_aes_test_vectors.h<br />new file mode 100644<br />index 0000000..e92a149<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_cryptodev_aes_test_vectors.h<br />@@ -0,0 +1,139 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef TEST_ZSDA_CRYPTODEV_AES_TEST_VECTORS_H_<br />+#define TEST_ZSDA_CRYPTODEV_AES_TEST_VECTORS_H_<br />+<br />+#include "test_zsda_cryptodev_data.h" <br />+<br />+static struct<br />+blockcipher_test_data zsda_test_data_xts_key_32_pt_512 = {<br />+    .crypto_algo = RTE_CRYPTO_CIPHER_AES_XTS,<br />+    .cipher_key = {<br />+        .data = { /* key1 | key2 */<br />+            0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,<br />+            0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,<br />+        },<br />+        .len = 32<br />+    },<br />+    .iv = {<br />+        .data = {<br />+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x01,<br />+        },<br />+        .len = 16<br />+    },<br />+    .plaintext = {<br />+        .data = plaintext_zsda_0x44_512B,<br />+        .len = DATA_LEN_512<br />+    },<br />+    .ciphertext = {<br />+        .data = ciphertext_zsda_aes256xts_512bytes,<br />+        .len = DATA_LEN_512<br />+    },<br />+    .xts_dataunit_len = DATA_LEN_512,<br />+    .wrapped_key = false<br />+};<br />+<br />+static struct<br />+blockcipher_test_data zsda_test_data_xts_key_64_pt_512 = {<br />+    .crypto_algo = RTE_CRYPTO_CIPHER_AES_XTS,<br />+    .cipher_key = {<br />+        .data = { /* key1 | key2 */<br />+            0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,<br />+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,<br />+            0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,<br />+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,<br />+        },<br />+        .len = 64<br />+    },<br />+    .iv = {<br />+        .data = {<br />+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x01},<br />+        .len = 16<br />+    },<br />+    .plaintext = {<br />+        .data = plaintext_zsda_0x44_512B,<br />+        .len = DATA_LEN_512<br />+    },<br />+    .ciphertext = {<br />+        .data = ciphertext_zsda_aes512xts_512bytes,<br />+        .len = DATA_LEN_512<br />+    },<br />+    .xts_dataunit_len = DATA_LEN_512,<br />+    .wrapped_key = false<br />+};<br />+<br />+static struct<br />+blockcipher_test_data sm4_zsda_test_data_xts_key_32_pt_512 = {<br />+    .crypto_algo = RTE_CRYPTO_CIPHER_SM4_XTS,<br />+    .cipher_key = {<br />+        .data = { /* key1 | key2 */<br />+            0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,<br />+            0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,<br />+        },<br />+        .len = 32<br />+    },<br />+    .iv = {<br />+        .data = {<br />+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x01},<br />+        .len = 16<br />+    },<br />+    .plaintext = {<br />+        .data = plaintext_zsda_0x44_512B,<br />+        .len = DATA_LEN_512<br />+    },<br />+    .ciphertext = {<br />+        .data = ciphertext_zsda_sm4xts256_512bytes,<br />+        .len = DATA_LEN_512<br />+    },<br />+    .xts_dataunit_len = DATA_LEN_512,<br />+    .wrapped_key = false<br />+};<br />+<br />+<br />+static struct blockcipher_test_case __rte_unused<br />+    zsda_test_cases_encry[] = {<br />+        {<br />+            .test_descr =<br />+                "AES-256-XTS Encryption (512-byte plaintext)",<br />+            .test_data = &zsda_test_data_xts_key_32_pt_512,<br />+            .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,<br />+        },<br />+        {<br />+            .test_descr =<br />+                "AES-512-XTS Encryption (512-byte plaintext)",<br />+            .test_data = &zsda_test_data_xts_key_64_pt_512,<br />+            .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,<br />+        },<br />+        {<br />+            .test_descr =<br />+                "SM4-XTS-256 Encryption (512-byte plaintext)",<br />+            .test_data = &sm4_zsda_test_data_xts_key_32_pt_512,<br />+            .op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,<br />+        },<br />+    };<br />+<br />+static struct blockcipher_test_case __rte_unused<br />+    zsda_test_cases_decry[] = {<br />+        {<br />+            .test_descr =<br />+                "AES-256-XTS Decryption (512-byte plaintext)",<br />+            .test_data = &zsda_test_data_xts_key_32_pt_512,<br />+            .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,<br />+        },<br />+        {<br />+            .test_descr =<br />+                "AES-512-XTS Decryption (512-byte plaintext)",<br />+            .test_data = &zsda_test_data_xts_key_64_pt_512,<br />+            .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,<br />+        },<br />+        {<br />+            .test_descr =<br />+                "SM4-XTS-256 Decryption (512-byte plaintext)",<br />+            .test_data = &sm4_zsda_test_data_xts_key_32_pt_512,<br />+            .op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,<br />+        },<br />+    };<br />+<br />+#endif /* TEST_ZSDA_CRYPTODEV_AES_TEST_VECTORS_H_ */<br />diff --git a/examples/zsda/test_zsda_cryptodev_data.h b/examples/zsda/test_zsda_cryptodev_data.h<br />new file mode 100644<br />index 0000000..526a329<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_cryptodev_data.h<br />@@ -0,0 +1,184 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+static uint8_t plaintext_zsda_0x44_512B[] = {<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+    0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,<br />+};<br />+static uint8_t ciphertext_zsda_aes256xts_512bytes[] = {<br />+    0x57, 0x99, 0xd9, 0x04, 0x1b, 0x6b, 0x18, 0xcb, 0x34, 0x14, 0x2f, 0xec,<br />+    0x4d, 0x35, 0xe6, 0x44, 0x84, 0x79, 0x48, 0x3d, 0xec, 0x25, 0x07, 0x29,<br />+    0xc9, 0xd9, 0x84, 0x1e, 0x66, 0x4d, 0x5f, 0x78, 0x1b, 0x02, 0x65, 0x01,<br />+    0xf5, 0x5e, 0xf0, 0xd8, 0x0a, 0x0c, 0x40, 0xae, 0x40, 0x88, 0x3b, 0x05,<br />+    0x07, 0x0e, 0x12, 0xad, 0xfb, 0xca, 0x1a, 0xb6, 0x9c, 0xda, 0x8f, 0xf1,<br />+    0x18, 0x66, 0xb1, 0xdf, 0x76, 0x84, 0xca, 0xcb, 0xd3, 0x08, 0xe8, 0xb6,<br />+    0x4e, 0x31, 0xee, 0x1e, 0x6e, 0xab, 0x94, 0x98, 0xcf, 0x1c, 0xe3, 0xd7,<br />+    0x91, 0xdd, 0x70, 0x5b, 0xd3, 0x52, 0xfd, 0xd5, 0x98, 0x07, 0xb7, 0x80,<br />+    0x40, 0xe3, 0x63, 0x5f, 0xe1, 0x3d, 0x12, 0x5f, 0x30, 0x80, 0x16, 0x9e,<br />+    0x9e, 0x60, 0xb0, 0x43, 0xf6, 0x2b, 0x51, 0x7c, 0xa5, 0x7f, 0x47, 0x3a,<br />+    0x39, 0x7a, 0xd5, 0x21, 0x70, 0x44, 0x63, 0xb4, 0xe2, 0xc9, 0xce, 0xb0,<br />+    0xb3, 0xce, 0x0a, 0xe8, 0x99, 0x3d, 0x13, 0xa6, 0x74, 0x67, 0xe5, 0x66,<br />+    0x5f, 0x24, 0xe3, 0x08, 0xbf, 0x40, 0xdb, 0x7c, 0xff, 0x03, 0xf1, 0x9e,<br />+    0x3f, 0x66, 0x2d, 0xc1, 0xe4, 0x2a, 0xd9, 0x8f, 0xcf, 0xea, 0xb0, 0x2f,<br />+    0xb8, 0x03, 0xbd, 0xa7, 0x33, 0x40, 0x88, 0x11, 0x71, 0xd5, 0x3e, 0xe3,<br />+    0x05, 0x80, 0x7c, 0xe7, 0xb7, 0x68, 0x29, 0xd1, 0x12, 0x74, 0x02, 0xac,<br />+    0xa0, 0x25, 0x0a, 0x25, 0x66, 0xe8, 0x4f, 0xae, 0x3d, 0x8c, 0xb1, 0xba,<br />+    0xc5, 0xdc, 0xc2, 0x68, 0x93, 0xb5, 0x8e, 0x98, 0x7a, 0x5a, 0x68, 0x61,<br />+    0x45, 0xd0, 0x7d, 0x6a, 0x5a, 0xe2, 0x21, 0x80, 0x44, 0x97, 0xf2, 0x52,<br />+    0xc3, 0x05, 0xea, 0x52, 0xd6, 0x56, 0x95, 0x54, 0xf6, 0xc7, 0x1b, 0xe9,<br />+    0xd8, 0x5a, 0x8c, 0xb7, 0x66, 0x60, 0x13, 0x66, 0x74, 0xcf, 0xba, 0xfd,<br />+    0x72, 0xd2, 0xee, 0xaf, 0xfa, 0x48, 0x4b, 0x2a, 0x45, 0xac, 0x8e, 0x23,<br />+    0x96, 0x68, 0x7f, 0xb9, 0xd9, 0x53, 0x9a, 0x08, 0xe8, 0x3b, 0xeb, 0x01,<br />+    0xe6, 0x2a, 0xe2, 0x8d, 0x3d, 0x9a, 0x2b, 0xd7, 0x8d, 0x29, 0xd1, 0xa1,<br />+    0x71, 0xb7, 0x74, 0x14, 0x6a, 0x60, 0xd6, 0xbe, 0xbe, 0xa7, 0x22, 0x24,<br />+    0x88, 0x49, 0x50, 0x5a, 0x6e, 0xb0, 0xc0, 0xcf, 0x35, 0x7a, 0x5b, 0xa9,<br />+    0xd0, 0x92, 0x0d, 0x30, 0x90, 0x7c, 0x56, 0xc6, 0xa6, 0x18, 0xd2, 0x45,<br />+    0xff, 0x23, 0xfa, 0x88, 0xb2, 0x1a, 0x49, 0x09, 0x33, 0x54, 0x39, 0x89,<br />+    0x81, 0x32, 0x91, 0x8a, 0x5f, 0x7d, 0xa2, 0x27, 0x6a, 0xf1, 0xc2, 0x3c,<br />+    0x2c, 0x11, 0x42, 0xe5, 0x88, 0x36, 0xdc, 0x08, 0xa9, 0x15, 0x37, 0x87,<br />+    0x5a, 0x20, 0x4f, 0x9e, 0xca, 0x61, 0xeb, 0x30, 0x90, 0x9e, 0x9e, 0x21,<br />+    0xc3, 0x52, 0x3a, 0xb0, 0x83, 0x04, 0x01, 0x82, 0xbc, 0x4c, 0x82, 0x36,<br />+    0x7c, 0xba, 0xaf, 0x1a, 0x94, 0xf7, 0xa1, 0x25, 0x8f, 0x38, 0x7d, 0x79,<br />+    0x47, 0x27, 0x37, 0xcc, 0xa8, 0xee, 0x68, 0x12, 0x91, 0x24, 0x78, 0xf6,<br />+    0xba, 0x91, 0x6c, 0x92, 0x79, 0x00, 0xaa, 0xdd, 0x5b, 0x2d, 0x98, 0x5b,<br />+    0x6d, 0x5c, 0xc3, 0x9f, 0x86, 0xb5, 0x4d, 0x4e, 0x71, 0xa9, 0xc1, 0x0c,<br />+    0xfd, 0x4f, 0x3b, 0xda, 0xc8, 0x30, 0x3b, 0xc7, 0xff, 0x04, 0xdb, 0x29,<br />+    0x70, 0xff, 0x13, 0x5f, 0xe4, 0x4b, 0xfb, 0x2a, 0x06, 0x2e, 0xa5, 0x99,<br />+    0x9f, 0x1e, 0xb8, 0xc7, 0x83, 0x60, 0xc3, 0xd5, 0xee, 0x75, 0xb6, 0xe1,<br />+    0xe4, 0xac, 0x50, 0x2b, 0x2b, 0xe3, 0xa8, 0x84, 0x52, 0x24, 0xa8, 0x95,<br />+    0xc3, 0xb0, 0x81, 0x2d, 0xce, 0x9a, 0x28, 0xdf, 0x15, 0xbe, 0x80, 0x6a,<br />+    0xf5, 0x0c, 0x9c, 0x0b, 0xe9, 0x72, 0xb6, 0x1b, 0x18, 0x3a, 0x86, 0xfb,<br />+    0x90, 0xf5, 0x03, 0xa4, 0xf8, 0xbb, 0x47, 0x58,<br />+};<br />+<br />+static uint8_t ciphertext_zsda_sm4xts256_512bytes[] = {<br />+    0x5c, 0x34, 0xf1, 0x1b, 0x07, 0x11, 0x11, 0x0f, 0x5d, 0xa8, 0x6e, 0xcb,<br />+    0xd9, 0x23, 0x12, 0x76, 0xca, 0x40, 0xb3, 0xe6, 0x89, 0x01, 0x33, 0x80,<br />+    0x9e, 0x63, 0x34, 0x4a, 0x21, 0x73, 0x4d, 0xe6, 0x4d, 0x7b, 0x5a, 0x24,<br />+    0xb4, 0xbc, 0x9b, 0xdf, 0xb6, 0x12, 0x37, 0xb2, 0x89, 0xbc, 0x9a, 0xe3,<br />+    0xd5, 0xbd, 0x9c, 0x17, 0x69, 0x65, 0x71, 0x27, 0x13, 0xf6, 0x78, 0x1e,<br />+    0xfe, 0x31, 0x35, 0xbb, 0x17, 0xe0, 0x69, 0xfc, 0x33, 0x79, 0xfe, 0x1e,<br />+    0x8c, 0x97, 0x3f, 0x16, 0xbf, 0xfd, 0x82, 0x38, 0x31, 0x35, 0x76, 0x76,<br />+    0x76, 0xf2, 0x2b, 0x9d, 0xa4, 0x3c, 0x80, 0xdc, 0xca, 0x97, 0x02, 0x9e,<br />+    0x0e, 0x57, 0x48, 0xed, 0x8b, 0x7e, 0x00, 0x77, 0xef, 0x98, 0x44, 0x86,<br />+    0x08, 0x11, 0x56, 0x6a, 0x8c, 0x47, 0x72, 0x1d, 0xcc, 0xe6, 0x23, 0xd3,<br />+    0x29, 0xa2, 0xf5, 0xb3, 0x11, 0x00, 0x87, 0x26, 0x29, 0xe3, 0x25, 0x4b,<br />+    0x8f, 0x13, 0xfe, 0xc6, 0xfb, 0xa4, 0x71, 0x38, 0xea, 0x06, 0x34, 0xae,<br />+    0xbd, 0xae, 0x8a, 0x84, 0xab, 0x42, 0x7c, 0x7d, 0x85, 0x3f, 0x00, 0xc0,<br />+    0x8d, 0x63, 0x72, 0xbb, 0x4e, 0xbf, 0x21, 0x68, 0x1e, 0x6a, 0xc9, 0x32,<br />+    0xfc, 0x02, 0x2d, 0xbd, 0x44, 0xc3, 0x9e, 0xf5, 0x41, 0x5d, 0x9d, 0xc7,<br />+    0x98, 0x8e, 0xc3, 0x69, 0xb5, 0x44, 0x6a, 0xfc, 0xe2, 0x08, 0x3d, 0xe5,<br />+    0x86, 0x89, 0x35, 0x34, 0x34, 0x27, 0xc9, 0x2e, 0x19, 0x69, 0xeb, 0x8a,<br />+    0x32, 0x75, 0x2e, 0xbe, 0x2b, 0x09, 0x53, 0x24, 0x58, 0x17, 0x11, 0xd0,<br />+    0xa6, 0x21, 0xee, 0x79, 0x0c, 0x25, 0xb7, 0xe6, 0x1c, 0x4e, 0x42, 0x6b,<br />+    0x6f, 0x5f, 0xee, 0xbc, 0xea, 0x39, 0xed, 0x44, 0x54, 0xe0, 0x66, 0x33,<br />+    0xf8, 0x6f, 0x5b, 0xdd, 0x85, 0x66, 0xf2, 0xd7, 0x6a, 0x82, 0xc3, 0xe9,<br />+    0xb1, 0x47, 0xcd, 0x0d, 0xae, 0x3c, 0xa5, 0xf6, 0x48, 0x00, 0xec, 0x74,<br />+    0xa8, 0xf8, 0xa8, 0xf8, 0x93, 0x27, 0xe1, 0x01, 0xb0, 0xfd, 0x3c, 0x53,<br />+    0xe9, 0x24, 0x0b, 0x71, 0x2f, 0x4b, 0x91, 0x92, 0x88, 0x2a, 0x8a, 0xb6,<br />+    0xad, 0xac, 0x0f, 0xcc, 0xe2, 0xc6, 0xa1, 0x7a, 0x23, 0xe5, 0x14, 0x67,<br />+    0x4f, 0xe1, 0x11, 0x8a, 0xa5, 0x1a, 0xe5, 0xf6, 0x03, 0xf1, 0x8e, 0x8b,<br />+    0x79, 0x1b, 0xc3, 0x6c, 0x5e, 0x70, 0xfd, 0xc7, 0xc4, 0x7c, 0xf3, 0x97,<br />+    0x8a, 0x58, 0x08, 0xae, 0x4a, 0xd3, 0x0e, 0xdf, 0xc8, 0xcc, 0xef, 0x4e,<br />+    0x0c, 0xa4, 0xd8, 0x7d, 0x9e, 0xeb, 0xc4, 0x6d, 0xac, 0x17, 0xd9, 0x56,<br />+    0x5a, 0x11, 0x91, 0xcb, 0x10, 0x1c, 0x63, 0x84, 0xaa, 0x37, 0xef, 0xb0,<br />+    0x66, 0xff, 0xae, 0x6f, 0x0c, 0x21, 0x18, 0xf4, 0xe5, 0xc3, 0x76, 0x15,<br />+    0xfd, 0x76, 0xf5, 0xb7, 0x06, 0xe7, 0x4e, 0x22, 0x05, 0x53, 0x49, 0x04,<br />+    0xa7, 0x64, 0x19, 0xa5, 0x93, 0xc3, 0xff, 0xff, 0xf0, 0x13, 0x9a, 0xca,<br />+    0x61, 0xb0, 0xf5, 0x55, 0x9b, 0x1b, 0x2f, 0xb9, 0xb3, 0x10, 0x47, 0x4e,<br />+    0x0e, 0xd9, 0xc2, 0xd7, 0x82, 0xe3, 0xa8, 0xbc, 0xd7, 0xa6, 0x87, 0x88,<br />+    0xe7, 0x74, 0x27, 0xb9, 0xde, 0xf6, 0x58, 0x06, 0x10, 0x89, 0xd2, 0x38,<br />+    0x4b, 0x7b, 0xf9, 0xd3, 0xa3, 0x86, 0xb1, 0xcc, 0x55, 0x79, 0xd9, 0xa0,<br />+    0x97, 0xe6, 0x7c, 0xc0, 0x5e, 0x78, 0x05, 0x16, 0xcd, 0xa8, 0x2f, 0x33,<br />+    0xe5, 0x5e, 0xb8, 0x52, 0x6b, 0x0d, 0x5f, 0xd4, 0xb5, 0x67, 0xd6, 0x3b,<br />+    0x75, 0x43, 0xce, 0x2f, 0x8c, 0x1f, 0xba, 0x12, 0x20, 0xae, 0xa3, 0xeb,<br />+    0xcf, 0x31, 0x7a, 0x65, 0xd2, 0xba, 0x47, 0x8f, 0xee, 0x2e, 0x39, 0xe9,<br />+    0x2b, 0xa3, 0x2d, 0x86, 0x57, 0x3f, 0x87, 0xe7, 0xff, 0x0d, 0x8d, 0x17,<br />+    0x17, 0x98, 0x28, 0xae, 0x55, 0xcf, 0xcf, 0x2d,<br />+};<br />+<br />+static uint8_t ciphertext_zsda_aes512xts_512bytes[] = {<br />+    0xc5, 0x47, 0x28, 0x8d, 0x26, 0x64, 0x8f, 0xe4, 0x83, 0x45, 0xe5, 0xe2,<br />+    0x0d, 0xb9, 0xa7, 0xe3, 0x72, 0x1d, 0x10, 0x5d, 0x5f, 0x5d, 0x12, 0x1e,<br />+    0x26, 0xa5, 0x15, 0x55, 0x3b, 0xfd, 0xbb, 0xde, 0x80, 0x89, 0x37, 0x6e,<br />+    0x5d, 0x2d, 0xfa, 0xcc, 0x64, 0x33, 0xca, 0x4a, 0xf1, 0xb2, 0x81, 0xb0,<br />+    0x39, 0xb4, 0x24, 0x4d, 0x04, 0x39, 0x35, 0x04, 0x28, 0x58, 0xea, 0x6a,<br />+    0x51, 0xfa, 0x1b, 0xcf, 0x97, 0xd4, 0xae, 0xc2, 0x84, 0xdc, 0xf9, 0x89,<br />+    0x9d, 0xa0, 0x27, 0x6f, 0x9f, 0xf8, 0xc6, 0xdc, 0xe1, 0x3b, 0xc5, 0xe1,<br />+    0x01, 0x75, 0x53, 0x37, 0x91, 0x84, 0x32, 0x3b, 0x8c, 0x19, 0xd6, 0x03,<br />+    0x5d, 0xb8, 0x8c, 0x31, 0x1f, 0x88, 0xae, 0x3c, 0x62, 0x0a, 0xf4, 0x0d,<br />+    0xf6, 0x4a, 0x01, 0x5f, 0x76, 0xbb, 0xaf, 0x35, 0x46, 0x7c, 0xde, 0xd1,<br />+    0xe7, 0xf7, 0x89, 0xe8, 0x80, 0x55, 0x39, 0x0c, 0x40, 0x68, 0x82, 0x27,<br />+    0x6c, 0xbf, 0x84, 0xf8, 0x9d, 0x46, 0xeb, 0x85, 0x46, 0x88, 0xd1, 0xe3,<br />+    0xc0, 0xf5, 0x9c, 0x08, 0x62, 0xd6, 0x80, 0x01, 0xf5, 0xa8, 0x3e, 0x96,<br />+    0xee, 0x4f, 0x7b, 0xf5, 0x71, 0x09, 0xd9, 0xcd, 0x47, 0xba, 0x6f, 0xf6,<br />+    0x63, 0xaf, 0x9d, 0x04, 0xcd, 0xc5, 0x78, 0xee, 0x40, 0x4c, 0x51, 0xef,<br />+    0xa8, 0xf1, 0x68, 0x00, 0xc7, 0x45, 0x5a, 0x18, 0x95, 0x9c, 0x06, 0x35,<br />+    0x32, 0x90, 0x32, 0x1b, 0xf9, 0x0d, 0x9a, 0xe9, 0x85, 0x25, 0x2b, 0x3d,<br />+    0x28, 0x00, 0x67, 0x57, 0xe2, 0x17, 0xd1, 0x15, 0xd8, 0xbd, 0xa5, 0xc1,<br />+    0xbc, 0xba, 0x97, 0x49, 0x55, 0xc4, 0x1f, 0xd2, 0x0d, 0xb4, 0x04, 0x5d,<br />+    0xb4, 0xc7, 0xfd, 0x38, 0xc0, 0x3b, 0x8a, 0xfa, 0xce, 0x98, 0x07, 0x09,<br />+    0x9d, 0xb0, 0xe8, 0x7f, 0xc6, 0x35, 0x32, 0x9e, 0x67, 0x6f, 0x3d, 0xd1,<br />+    0x4e, 0x59, 0x3d, 0x56, 0xe6, 0x47, 0x1f, 0xcc, 0x4a, 0xcf, 0x78, 0x7c,<br />+    0x41, 0xcd, 0xd7, 0xc0, 0x21, 0xe9, 0xaf, 0xac, 0xa9, 0x12, 0x50, 0x19,<br />+    0xc8, 0xf7, 0x97, 0xe8, 0x61, 0x35, 0x65, 0xf2, 0x81, 0xb8, 0xed, 0x17,<br />+    0xcf, 0xc8, 0xbf, 0x55, 0x0a, 0xcb, 0xa1, 0x8f, 0x24, 0x99, 0x12, 0x76,<br />+    0xb5, 0x77, 0x56, 0xb9, 0x23, 0xfd, 0x77, 0x34, 0xf0, 0x21, 0x32, 0x73,<br />+    0x2c, 0x85, 0x42, 0x52, 0x26, 0x65, 0x30, 0xe0, 0xd0, 0x8a, 0x07, 0xf3,<br />+    0xe0, 0x7d, 0xc7, 0xc6, 0x2b, 0x56, 0x27, 0xcb, 0x9c, 0xca, 0x22, 0xca,<br />+    0xb7, 0xc1, 0x1f, 0x45, 0xb7, 0xad, 0x48, 0x14, 0x1d, 0xba, 0x2c, 0xcd,<br />+    0x31, 0x7d, 0x1e, 0x2f, 0x1e, 0x04, 0x8d, 0x0b, 0x75, 0x93, 0x42, 0x86,<br />+    0x3c, 0xb3, 0xa4, 0x38, 0x6d, 0xc0, 0x1e, 0xe7, 0x65, 0x9e, 0x5a, 0x3b,<br />+    0x98, 0x69, 0xc9, 0x7d, 0x64, 0x25, 0x9c, 0xe1, 0x52, 0x7b, 0xfd, 0x68,<br />+    0xc0, 0x8e, 0xe3, 0x62, 0xb6, 0x1f, 0x74, 0x58, 0x10, 0xb7, 0x9e, 0x51,<br />+    0x08, 0xb2, 0x5d, 0x57, 0xfd, 0x3d, 0xb1, 0xbc, 0x84, 0xc8, 0x38, 0x92,<br />+    0x3a, 0x10, 0x98, 0x2c, 0xb2, 0x10, 0x6d, 0xe2, 0xb4, 0x88, 0x8c, 0x23,<br />+    0x4e, 0x80, 0x9b, 0x02, 0x40, 0x34, 0xfb, 0x86, 0x88, 0x6a, 0x5e, 0x7c,<br />+    0x62, 0x2f, 0xa0, 0x3d, 0x51, 0xe4, 0x04, 0x35, 0xde, 0x80, 0x98, 0x2f,<br />+    0xce, 0xa2, 0x0a, 0x94, 0x2d, 0x7f, 0x57, 0x5f, 0x34, 0x55, 0x55, 0x9d,<br />+    0x82, 0xc6, 0xbe, 0x18, 0x90, 0xc0, 0x46, 0x9d, 0xda, 0x72, 0xd4, 0x24,<br />+    0x5f, 0xce, 0xa8, 0x1e, 0x34, 0xfe, 0x99, 0x26, 0x69, 0xcd, 0x70, 0x96,<br />+    0x69, 0xc4, 0x1a, 0x82, 0x50, 0x8c, 0x78, 0xef, 0xee, 0xf3, 0x92, 0x6e,<br />+    0xe9, 0x57, 0xa6, 0xe2, 0x66, 0x11, 0x1c, 0xf7, 0x4e, 0x9b, 0xd7, 0xa9,<br />+    0xd6, 0xeb, 0xcf, 0xc8, 0x51, 0x7e, 0x02, 0x42};<br />diff --git a/examples/zsda/test_zsda_cryptodev_hash_test_vectors.h b/examples/zsda/test_zsda_cryptodev_hash_test_vectors.h<br />new file mode 100644<br />index 0000000..4236d90<br />--- /dev/null<br />+++ b/examples/zsda/test_zsda_cryptodev_hash_test_vectors.h<br />@@ -0,0 +1,210 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef TEST_ZSDA_CRYPTODEV_HASH_TEST_VECTORS_H_<br />+#define TEST_ZSDA_CRYPTODEV_HASH_TEST_VECTORS_H_<br />+<br />+#define LEN_HASH_PLAINTEXT 512<br />+<br />+static uint8_t plaintext_hash[] = {<br />+    0x63, 0x67, 0x08, 0x2d, 0x68, 0x75, 0x6e, 0xf4, 0x68, 0x9f, 0xef, 0xc9,<br />+    0x4c, 0xa2, 0x2e, 0xbb, 0xa6, 0x00, 0x72, 0xa6, 0x59, 0x1f, 0x39, 0x4f,<br />+    0x4c, 0xa6, 0xe0, 0x10, 0x38, 0x5e, 0x5e, 0x87, 0x44, 0xb3, 0xc6, 0x60,<br />+    0xfe, 0x76, 0xba, 0xe8, 0x13, 0x70, 0xc5, 0xba, 0xce, 0xb1, 0x7e, 0xaa,<br />+    0x38, 0x55, 0xac, 0x74, 0xa3, 0xd7, 0xbd, 0x7b, 0x0c, 0x17, 0x06, 0xdc,<br />+    0x48, 0x23, 0xe8, 0xde, 0xca, 0x8b, 0xf6, 0x3e, 0x96, 0xdc, 0x7a, 0x7f,<br />+    0xb1, 0x49, 0x28, 0x8d, 0x67, 0x81, 0x7b, 0x28, 0x76, 0x8d, 0x00, 0xde,<br />+    0xa6, 0x7d, 0x0e, 0xbd, 0x99, 0x71, 0xeb, 0x7c, 0xbe, 0x32, 0x6d, 0x2a,<br />+    0xc9, 0x1a, 0x0a, 0xcc, 0x05, 0x46, 0xe0, 0x65, 0x88, 0x00, 0xde, 0x30,<br />+    0xf5, 0xcf, 0x3c, 0x6b, 0x76, 0x8d, 0x00, 0xde, 0xa6, 0x7d, 0x0e, 0xbd,<br />+    0x99, 0x71, 0xeb, 0x7c, 0xbe, 0x32, 0x6d, 0x2a, 0x42, 0x54, 0xf7, 0xff,<br />+    0x93, 0xc9, 0xcd, 0x03, 0xd6, 0x90, 0x55, 0xb9, 0xf3, 0xdf, 0x6c, 0x65,<br />+    0xd7, 0x35, 0xc0, 0x82, 0xb1, 0x02, 0x15, 0xb2, 0x36, 0x95, 0x99, 0xb6,<br />+    0x45, 0x13, 0xf6, 0xbe, 0x99, 0x16, 0x45, 0x4f, 0xba, 0x83, 0x9b, 0x72,<br />+    0xf2, 0x2a, 0x3f, 0xfa, 0x77, 0xe4, 0xe2, 0x7e, 0xd4, 0x5a, 0x8a, 0xc9,<br />+    0xdf, 0xbf, 0xd8, 0x5b, 0x30, 0x1a, 0x58, 0xd9, 0xfd, 0xcf, 0xf1, 0xfb,<br />+    0xba, 0xfa, 0xc5, 0xff, 0x06, 0xf2, 0x96, 0xe2, 0x1e, 0x4c, 0x8c, 0x48,<br />+    0x68, 0xe5, 0xaf, 0xe8, 0x77, 0x92, 0xa0, 0x64, 0x1c, 0xea, 0x1f, 0x37,<br />+    0xf8, 0xe8, 0x24, 0x32, 0x52, 0xb5, 0x00, 0x31, 0x1c, 0x0d, 0xf7, 0x34,<br />+    0x96, 0x06, 0x98, 0x34, 0x2a, 0x76, 0x50, 0xfe, 0x46, 0xa5, 0x23, 0xf5,<br />+    0x5d, 0xbc, 0x41, 0xc2, 0x2a, 0xc6, 0x43, 0x9a, 0x5e, 0x7f, 0xdb, 0x16,<br />+    0x18, 0x8c, 0x6c, 0x14, 0xc8, 0xe0, 0x9f, 0x36, 0x24, 0x9a, 0xfd, 0x86,<br />+    0x59, 0x36, 0xc3, 0x6f, 0xa6, 0x99, 0xc0, 0x08, 0x6f, 0x22, 0xbd, 0x25,<br />+    0xb2, 0x72, 0x60, 0xa7, 0xa1, 0x18, 0x2d, 0x0c, 0x9c, 0x2b, 0xf8, 0x73,<br />+    0xed, 0x03, 0xa0, 0x97, 0xd7, 0xbc, 0x0e, 0x78, 0xca, 0xcb, 0x56, 0x8f,<br />+    0x39, 0x3c, 0x3b, 0xec, 0xed, 0x03, 0xa0, 0x97, 0xd7, 0xbc, 0x0e, 0x78,<br />+    0xca, 0xcb, 0x56, 0x8f, 0x39, 0x3c, 0x3b, 0xec, 0x4e, 0xa9, 0x04, 0xff,<br />+    0x40, 0xf3, 0x4b, 0x97, 0xa9, 0x4a, 0xb8, 0xd5, 0xed, 0x5c, 0x93, 0x43,<br />+    0x76, 0x8d, 0x00, 0xde, 0xa6, 0x7d, 0x0e, 0xbd, 0x99, 0x71, 0xeb, 0x7c,<br />+    0xbe, 0x32, 0x6d, 0x2a, 0x76, 0x8d, 0x00, 0xde, 0xa6, 0x7d, 0x0e, 0xbd,<br />+    0x99, 0x71, 0xeb, 0x7c, 0xbe, 0x32, 0x6d, 0x2a, 0x83, 0x55, 0x5e, 0x23,<br />+    0xfe, 0xc5, 0x64, 0xb6, 0xea, 0x31, 0x03, 0xe9, 0xc0, 0x1e, 0x05, 0x02,<br />+    0x42, 0x54, 0xf7, 0xff, 0x93, 0xc9, 0xcd, 0x03, 0xd6, 0x90, 0x55, 0xb9,<br />+    0xf3, 0xdf, 0x6c, 0x65, 0xd7, 0x35, 0xc0, 0x82, 0xb1, 0x02, 0x15, 0xb2,<br />+    0x36, 0x95, 0x99, 0xb6, 0x45, 0x13, 0xf6, 0xbe, 0x68, 0x7f, 0xe0, 0x36,<br />+    0x00, 0x17, 0x21, 0x5d, 0x0b, 0x3c, 0x8b, 0x05, 0x03, 0xf2, 0xbe, 0x88,<br />+    0x6b, 0x02, 0x51, 0x64, 0x21, 0x48, 0x55, 0xc3, 0x14, 0x2e, 0x6a, 0x6a,<br />+    0x22, 0x22, 0x69, 0xf6, 0x27, 0x73, 0xf2, 0x9e, 0xe0, 0xc9, 0xf0, 0x04,<br />+    0x48, 0x23, 0x7d, 0xb6, 0x55, 0x81, 0x21, 0xf2, 0xed, 0x03, 0xa0, 0x97,<br />+    0xd7, 0xbc, 0x0e, 0x78, 0xca, 0xcb, 0x56, 0x8f, 0x39, 0x3c, 0x3b, 0xec,<br />+    0x42, 0x54, 0xf7, 0xff, 0x93, 0xc9, 0xcd, 0x03, 0xd6, 0x90, 0x55, 0xb9,<br />+    0xf3, 0xdf, 0x6c, 0x65, 0xd7, 0x35, 0xc0, 0x82, 0xb1, 0x02, 0x15, 0xb2,<br />+    0x36, 0x95, 0x99, 0xb6, 0x45, 0x13, 0xf6, 0xbe,<br />+};<br />+<br />+static struct blockcipher_test_data<br />+sha1_test_vector = {<br />+    .auth_algo = RTE_CRYPTO_AUTH_SHA1,<br />+    .plaintext = {<br />+        .data = plaintext_hash,<br />+        .len = LEN_HASH_PLAINTEXT<br />+    },<br />+    .digest = {<br />+        .data = {<br />+            0x27, 0x57, 0xFE, 0xCD, 0x0B, 0x06, 0x3D, 0x40,<br />+            0xF8, 0x25, 0x82, 0x5D, 0xB6, 0xCD, 0x70, 0xAF,<br />+            0x93, 0xCF, 0xFB, 0x2C,<br />+        },<br />+        .len = 20,<br />+        .truncated_len = 20<br />+    }<br />+};<br />+<br />+static struct blockcipher_test_data<br />+sha224_test_vector = {<br />+    .auth_algo = RTE_CRYPTO_AUTH_SHA224,<br />+    .plaintext = {<br />+        .data = plaintext_hash,<br />+        .len = LEN_HASH_PLAINTEXT<br />+    },<br />+    .digest = {<br />+        .data = {<br />+            0xD7, 0x6A, 0x90, 0x9E, 0x08, 0xC9, 0x72, 0x9A,<br />+            0x93, 0x36, 0xB5, 0x40, 0x7E, 0x8B, 0xCB, 0xEA,<br />+            0x7E, 0x64, 0xA9, 0x64, 0x4B, 0xCE, 0x6E, 0x82,<br />+            0x0E, 0x8C, 0x0D, 0x97<br />+        },<br />+        .len = 28,<br />+        .truncated_len = 28<br />+    }<br />+};<br />+<br />+static struct blockcipher_test_data<br />+sha256_test_vector = {<br />+    .auth_algo = RTE_CRYPTO_AUTH_SHA256,<br />+    .plaintext = {<br />+        .data = plaintext_hash,<br />+        .len = LEN_HASH_PLAINTEXT<br />+    },<br />+    .digest = {<br />+        .data = {<br />+            0x72, 0xA6, 0x6D, 0x01, 0x2B, 0x51, 0xDA, 0xE0,<br />+            0x37, 0x7B, 0x30, 0x71, 0xC8, 0x1C, 0xD4, 0x15,<br />+            0x5A, 0x8A, 0x44, 0x28, 0xFA, 0x9E, 0x20, 0x5F,<br />+            0xA6, 0x86, 0xA0, 0x6D, 0xFA, 0xB9, 0x16, 0x76<br />+        },<br />+        .len = 32,<br />+        .truncated_len = 32<br />+    }<br />+};<br />+<br />+static struct blockcipher_test_data<br />+sha384_test_vector = {<br />+    .auth_algo = RTE_CRYPTO_AUTH_SHA384,<br />+    .plaintext = {<br />+        .data = plaintext_hash,<br />+        .len = LEN_HASH_PLAINTEXT<br />+    },<br />+    .digest = {<br />+        .data = {<br />+            0xF7, 0x87, 0xB9, 0xE0, 0xC1, 0x59, 0xA3, 0x3C,<br />+            0x47, 0xC6, 0x9B, 0x68, 0x3C, 0x43, 0x9D, 0xB0,<br />+            0xD7, 0x02, 0x40, 0xF0, 0xD6, 0xC9, 0x39, 0x07,<br />+            0x7A, 0x2B, 0xEE, 0x3E, 0x51, 0x09, 0xD7, 0x1E,<br />+            0x5E, 0xCE, 0xAB, 0x42, 0xC6, 0x6A, 0x0C, 0x91,<br />+            0x0E, 0x75, 0x83, 0x35, 0x9C, 0x49, 0x64, 0xC2<br />+        },<br />+        .len = 48,<br />+        .truncated_len = 48<br />+    }<br />+};<br />+<br />+static struct blockcipher_test_data<br />+sha512_test_vector = {<br />+    .auth_algo = RTE_CRYPTO_AUTH_SHA512,<br />+    .plaintext = {<br />+        .data = plaintext_hash,<br />+        .len = LEN_HASH_PLAINTEXT<br />+    },<br />+    .digest = {<br />+        .data = {<br />+            0xC9, 0xE5, 0x79, 0x46, 0x2C, 0x73, 0xBF, 0x94,<br />+            0x6A, 0x3B, 0x2F, 0xBE, 0x1B, 0x52, 0x15, 0xBC,<br />+            0xA6, 0xA0, 0x55, 0xD7, 0x11, 0x5F, 0xD3, 0xD4,<br />+            0xB9, 0x5E, 0x3A, 0xCA, 0xE9, 0x4A, 0x0A, 0xF4,<br />+            0x98, 0x01, 0xDA, 0x2A, 0x22, 0x71, 0xB2, 0x18,<br />+            0x5C, 0xEA, 0xF1, 0x89, 0xE7, 0xF5, 0x2D, 0xF2,<br />+            0x60, 0x41, 0xE6, 0x51, 0x53, 0x89, 0x2D, 0xF4,<br />+            0x05, 0x77, 0xE0, 0xB3, 0xE6, 0x80, 0x43, 0xE1<br />+        },<br />+        .len = 64,<br />+        .truncated_len = 64<br />+    }<br />+};<br />+<br />+static struct blockcipher_test_data<br />+sm3_test_vector = {<br />+    .auth_algo = RTE_CRYPTO_AUTH_SM3,<br />+    .plaintext = {<br />+        .data = plaintext_hash,<br />+        .len = LEN_HASH_PLAINTEXT<br />+    },<br />+    .digest = {<br />+        .data = {<br />+            0x00, 0xDD, 0x55, 0x6D, 0x24, 0xFB, 0x95, 0x9B,<br />+            0xA3, 0x32, 0x26, 0x66, 0xB8, 0x96, 0xD6, 0x13,<br />+            0xFE, 0xCC, 0xBF, 0xBC, 0x81, 0x3E, 0x6A, 0x47,<br />+            0xB0, 0xE7, 0x06, 0x59, 0xC8, 0xA1, 0x48, 0x95<br />+        },<br />+        .len = 32,<br />+        .truncated_len = 32<br />+    }<br />+};<br />+<br />+static struct blockcipher_test_case zsda_test_cases_hash[] = {<br />+    {<br />+        .test_descr = "SHA1 Digest",<br />+        .test_data = &sha1_test_vector,<br />+        .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,<br />+    },<br />+    {<br />+        .test_descr = "SHA224 Digest",<br />+        .test_data = &sha224_test_vector,<br />+        .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,<br />+    },<br />+    {<br />+        .test_descr = "SHA256 Digest",<br />+        .test_data = &sha256_test_vector,<br />+        .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,<br />+    },<br />+    {<br />+        .test_descr = "SHA384 Digest",<br />+        .test_data = &sha384_test_vector,<br />+        .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,<br />+    },<br />+    {<br />+        .test_descr = "SHA512 Digest",<br />+        .test_data = &sha512_test_vector,<br />+        .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,<br />+    },<br />+    {<br />+        .test_descr = "SM3 Digest",<br />+        .test_data = &sm3_test_vector,<br />+        .op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,<br />+    },<br />+};<br />+<br />+<br />+<br />+#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */<br />diff --git a/lib/compressdev/rte_compressdev.h b/lib/compressdev/rte_compressdev.h<br />index 42bda9f..84eded2 100644<br />--- a/lib/compressdev/rte_compressdev.h<br />+++ b/lib/compressdev/rte_compressdev.h<br />@@ -21,6 +21,7 @@<br /> extern "C" {<br /> #endif<br />  <br />+#include <rte_common.h> <br />  <br /> #include <rte_compat.h> <br /> #include "rte_comp.h" <br />@@ -205,7 +206,10 @@ struct rte_compressdev_config {<br />     uint16_t max_nb_streams;<br />     /**< Max number of streams which will be created on the device */<br /> };<br />-<br />+/** Compress device queue pair configuration structure. */<br />+struct rte_compressdev_qp_conf {<br />+    uint32_t nb_descriptors; /**< Number of descriptors per queue pair */<br />+};<br /> /**<br />  * Configure a device.<br />  *<br />@@ -313,6 +317,15 @@ __rte_experimental<br /> uint16_t<br /> rte_compressdev_queue_pair_count(uint8_t dev_id);<br />  <br />+/**<br />+     * Get the number of queue pairs on a specific comp device<br />+     *<br />+     * @param dev_id<br />+     *   Compress device identifier<br />+     * @return<br />+     *   - The number of configured queue pairs.<br />+     */<br />+__rte_experimental uint16_t rte_compressdev_queue_pair_count(uint8_t dev_id);<br />  <br /> /**<br />  * Retrieve the general I/O statistics of a device.<br />diff --git a/lib/compressdev/rte_compressdev_pmd.h b/lib/compressdev/rte_compressdev_pmd.h<br />index ea01290..c3f787e 100644<br />--- a/lib/compressdev/rte_compressdev_pmd.h<br />+++ b/lib/compressdev/rte_compressdev_pmd.h<br />@@ -21,6 +21,9 @@ extern "C" {<br />  <br /> #include <dev_driver.h> <br />  <br />+#include <rte_dev.h> <br />+#include <rte_common.h> <br />+<br /> #include <rte_compat.h> <br /> #include "rte_compressdev.h" <br /> #include "rte_compressdev_internal.h" <br />diff --git a/lib/cryptodev/rte_crypto_sym.h b/lib/cryptodev/rte_crypto_sym.h<br />index 33b4966..2c2d171 100644<br />--- a/lib/cryptodev/rte_crypto_sym.h<br />+++ b/lib/cryptodev/rte_crypto_sym.h<br />@@ -71,6 +71,7 @@ struct rte_crypto_va_iova_ptr {<br /> struct rte_crypto_sym_vec {<br />     /** number of operations to perform */<br />     uint32_t num;<br />+    struct rte_crypto_sgl *sgl;<br />     /** array of SGL vectors */<br />     struct rte_crypto_sgl *src_sgl;<br />     /** array of SGL vectors for OOP, keep it NULL for inplace*/<br />@@ -168,6 +169,7 @@ enum rte_crypto_cipher_algorithm {<br />      * for m_src and m_dst in the rte_crypto_sym_op must be NULL.<br />      */<br />  <br />+    RTE_CRYPTO_CIPHER_SM4_XTS,<br />     RTE_CRYPTO_CIPHER_SM4_ECB,<br />     /**< ShangMi 4 (SM4) algorithm in ECB mode */<br />     RTE_CRYPTO_CIPHER_SM4_CBC,<br />@@ -590,6 +592,8 @@ struct rte_crypto_sym_xform {<br />     };<br /> };<br />  <br />+struct rte_cryptodev_sym_session;<br />+<br /> /**<br />  * Symmetric Cryptographic Operation.<br />  *<br />diff --git a/lib/cryptodev/rte_cryptodev_pmd.h b/lib/cryptodev/rte_cryptodev_pmd.h<br />new file mode 100644<br />index 0000000..5086124<br />--- /dev/null<br />+++ b/lib/cryptodev/rte_cryptodev_pmd.h<br />@@ -0,0 +1,325 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#ifndef _RTE_CRYPTODEV_PMD_H_<br />+#define _RTE_CRYPTODEV_PMD_H_<br />+<br />+/** @file<br />+ * RTE Crypto PMD APIs<br />+ *<br />+ * @note<br />+ * These API are from crypto PMD only and user applications should not call<br />+ * them directly.<br />+ */<br />+<br />+#ifdef __cplusplus<br />+extern "C" {<br />+#endif<br />+<br />+#include <string.h> <br />+<br />+#include <rte_config.h> <br />+#include <rte_dev.h> <br />+#include <rte_malloc.h> <br />+#include <rte_mbuf.h> <br />+#include <rte_mempool.h> <br />+#include <rte_log.h> <br />+#include <rte_common.h> <br />+<br />+#include "rte_crypto.h" <br />+#include "rte_cryptodev.h" <br />+<br />+#define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS 8<br />+<br />+#define RTE_CRYPTODEV_PMD_NAME_ARG ("name")<br />+#define RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG ("max_nb_queue_pairs")<br />+#define RTE_CRYPTODEV_PMD_SOCKET_ID_ARG ("socket_id")<br />+<br />+/**<br />+ * Get the rte_cryptodev structure device pointer for the device. Assumes a<br />+ * valid device index.<br />+ *<br />+ * @param    dev_id    Device ID value to select the device structure.<br />+ *<br />+ * @return<br />+ *   - The rte_cryptodev structure pointer for the given device ID.<br />+ */<br />+struct rte_cryptodev *rte_cryptodev_pmd_get_dev(uint8_t dev_id);<br />+<br />+/**<br />+ * Get the rte_cryptodev structure device pointer for the named device.<br />+ *<br />+ * @param    name    device name to select the device structure.<br />+ *<br />+ * @return<br />+ *   - The rte_cryptodev structure pointer for the given device ID.<br />+ */<br />+struct rte_cryptodev *rte_cryptodev_pmd_get_named_dev(const char *name);<br />+<br />+/**<br />+ * Validate if the crypto device index is valid attached crypto device.<br />+ *<br />+ * @param    dev_id    Crypto device index.<br />+ *<br />+ * @return<br />+ *   - If the device index is valid (1) or not (0).<br />+ */<br />+unsigned int rte_cryptodev_pmd_is_valid_dev(uint8_t dev_id);<br />+<br />+/**<br />+ * The pool of rte_cryptodev structures.<br />+ */<br />+extern struct rte_cryptodev *rte_cryptodevs;<br />+<br />+/**<br />+ * Definitions of all functions exported by a driver through the<br />+ * the generic structure of type *crypto_dev_ops* supplied in the<br />+ * *rte_cryptodev* structure associated with a device.<br />+ */<br />+<br />+/**<br />+ *    Function used to configure device.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ * @param    config    Crypto device configurations<br />+ *<br />+ * @return    Returns 0 on success<br />+ */<br />+typedef int (*cryptodev_configure_t)(struct rte_cryptodev *dev,<br />+                     struct rte_cryptodev_config *config);<br />+<br />+/**<br />+ * Function used to start a configured device.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ *<br />+ * @return    Returns 0 on success<br />+ */<br />+typedef int (*cryptodev_start_t)(struct rte_cryptodev *dev);<br />+<br />+/**<br />+ * Function used to stop a configured device.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ */<br />+typedef void (*cryptodev_stop_t)(struct rte_cryptodev *dev);<br />+<br />+/**<br />+ * Function used to close a configured device.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ * @return<br />+ * - 0 on success.<br />+ * - EAGAIN if can't close as device is busy<br />+ */<br />+typedef int (*cryptodev_close_t)(struct rte_cryptodev *dev);<br />+<br />+/**<br />+ * Function used to get statistics of a device.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ * @param    stats    Pointer to crypto device stats structure to populate<br />+ */<br />+typedef void (*cryptodev_stats_get_t)(struct rte_cryptodev *dev,<br />+                      struct rte_cryptodev_stats *stats);<br />+<br />+/**<br />+ * Function used to reset statistics of a device.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ */<br />+typedef void (*cryptodev_stats_reset_t)(struct rte_cryptodev *dev);<br />+<br />+/**<br />+ * Function used to get specific information of a device.<br />+ *<br />+ * @param    dev        Crypto device pointer<br />+ * @param    dev_info    Pointer to infos structure to populate<br />+ */<br />+typedef void (*cryptodev_info_get_t)(struct rte_cryptodev *dev,<br />+                     struct rte_cryptodev_info *dev_info);<br />+<br />+/**<br />+ * Setup a queue pair for a device.<br />+ *<br />+ * @param    dev        Crypto device pointer<br />+ * @param    qp_id        Queue Pair Index<br />+ * @param    qp_conf        Queue configuration structure<br />+ * @param    socket_id    Socket Index<br />+ *<br />+ * @return    Returns 0 on success.<br />+ */<br />+typedef int (*cryptodev_queue_pair_setup_t)(<br />+    struct rte_cryptodev *dev, uint16_t qp_id,<br />+    const struct rte_cryptodev_qp_conf *qp_conf, int socket_id);<br />+<br />+/**<br />+ * Release memory resources allocated by given queue pair.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ * @param    qp_id    Queue Pair Index<br />+ *<br />+ * @return<br />+ * - 0 on success.<br />+ * - EAGAIN if can't close as device is busy<br />+ */<br />+typedef int (*cryptodev_queue_pair_release_t)(struct rte_cryptodev *dev,<br />+                          uint16_t qp_id);<br />+<br />+/**<br />+ * Create a session mempool to allocate sessions from<br />+ *<br />+ * @param    dev        Crypto device pointer<br />+ * @param    nb_objs        number of sessions objects in mempool<br />+ * @param    obj_cache_size    l-core object cache size, see *rte_ring_create*<br />+ * @param    socket_id    Socket Id to allocate  mempool on.<br />+ *<br />+ * @return<br />+ * - On success returns a pointer to a rte_mempool<br />+ * - On failure returns a NULL pointer<br />+ */<br />+typedef int (*cryptodev_sym_create_session_pool_t)(struct rte_cryptodev *dev,<br />+                           unsigned int nb_objs,<br />+                           unsigned int obj_cache_size,<br />+                           int socket_id);<br />+<br />+/**<br />+ * Get the size of a cryptodev session<br />+ *<br />+ * @param    dev        Crypto device pointer<br />+ *<br />+ * @return<br />+ *  - On success returns the size of the session structure for device<br />+ *  - On failure returns 0<br />+ */<br />+typedef unsigned int (*cryptodev_sym_get_session_private_size_t)(<br />+    struct rte_cryptodev *dev);<br />+/**<br />+ * Get the size of a asymmetric cryptodev session<br />+ *<br />+ * @param    dev        Crypto device pointer<br />+ *<br />+ * @return<br />+ *  - On success returns the size of the session structure for device<br />+ *  - On failure returns 0<br />+ */<br />+typedef unsigned int (*cryptodev_asym_get_session_private_size_t)(<br />+    struct rte_cryptodev *dev);<br />+<br />+/**<br />+ * Perform actual crypto processing (encrypt/digest or auth/decrypt)<br />+ * on user provided data.<br />+ *<br />+ * @param    dev    Crypto device pointer<br />+ * @param    sess    Cryptodev session structure<br />+ * @param    ofs    Start and stop offsets for auth and cipher operations<br />+ * @param    vec    Vectorized operation descriptor<br />+ *<br />+ * @return<br />+ *  - Returns number of successfully processed packets.<br />+ *<br />+ */<br />+typedef uint32_t (*cryptodev_sym_cpu_crypto_process_t)(<br />+    struct rte_cryptodev *dev, struct rte_cryptodev_sym_session *sess,<br />+    union rte_crypto_sym_ofs ofs, struct rte_crypto_sym_vec *vec);<br />+<br />+/**<br />+ * Typedef that the driver provided to get service context private date size.<br />+ *<br />+ * @param    dev    Crypto device pointer.<br />+ *<br />+ * @return<br />+ *   - On success return the size of the device's service context private data.<br />+ *   - On failure return negative integer.<br />+ */<br />+typedef int (*cryptodev_sym_get_raw_dp_ctx_size_t)(struct rte_cryptodev *dev);<br />+<br />+/**<br />+ * Typedef that the driver provided to configure raw data-path context.<br />+ *<br />+ * @param    dev        Crypto device pointer.<br />+ * @param    qp_id        Crypto device queue pair index.<br />+ * @param    ctx        The raw data-path context data.<br />+ * @param    sess_type    session type.<br />+ * @param    session_ctx    Session context data. If NULL the driver<br />+ *                shall only configure the drv_ctx_data in<br />+ *                ctx buffer. Otherwise the driver shall only<br />+ *                parse the session_ctx to set appropriate<br />+ *                function pointers in ctx.<br />+ * @param    is_update    Set 0 if it is to initialize the ctx.<br />+ *                Set 1 if ctx is initialized and only to update<br />+ *                session context data.<br />+ * @return<br />+ *   - On success return 0.<br />+ *   - On failure return negative integer.<br />+ */<br />+typedef int (*cryptodev_sym_configure_raw_dp_ctx_t)(<br />+    struct rte_cryptodev *dev, uint16_t qp_id,<br />+    struct rte_crypto_raw_dp_ctx *ctx,<br />+    enum rte_crypto_op_sess_type sess_type,<br />+    union rte_cryptodev_session_ctx session_ctx, uint8_t is_update);<br />+<br />+/**<br />+ * Function for internal use by dummy drivers primarily, e.g. ring-based<br />+ * driver.<br />+ * Allocates a new cryptodev slot for an crypto device and returns the pointer<br />+ * to that slot for the driver to use.<br />+ *<br />+ * @param    name        Unique identifier name for each device<br />+ * @param    socket_id    Socket to allocate resources on.<br />+ * @return<br />+ *   - Slot in the rte_dev_devices array for a new device;<br />+ */<br />+struct rte_cryptodev *rte_cryptodev_pmd_allocate(const char *name,<br />+                         int socket_id);<br />+<br />+/**<br />+ * Function for internal use by dummy drivers primarily, e.g. ring-based<br />+ * driver.<br />+ * Release the specified cryptodev device.<br />+ *<br />+ * @param cryptodev<br />+ * The *cryptodev* pointer is the address of the *rte_cryptodev* structure.<br />+ * @return<br />+ *   - 0 on success, negative on error<br />+ */<br />+extern int rte_cryptodev_pmd_release_device(struct rte_cryptodev *cryptodev);<br />+<br />+/**<br />+ * @internal<br />+ *<br />+ * PMD assist function to provide boiler plate code for crypto driver to<br />+ * destroy and free resources associated with a crypto PMD device instance.<br />+ *<br />+ * @param    cryptodev    crypto device handle.<br />+ *<br />+ * @return<br />+ *  - 0 on success<br />+ *  - errno on failure<br />+ */<br />+int rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev);<br />+<br />+/**<br />+ * Executes all the user application registered callbacks for the specific<br />+ * device.<br />+ *  *<br />+ * @param    dev    Pointer to cryptodev struct<br />+ * @param    event    Crypto device interrupt event type.<br />+ *<br />+ * @return<br />+ *  void<br />+ */<br />+void rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev,<br />+                    enum rte_cryptodev_event_type event);<br />+<br />+/**<br />+ * @internal<br />+ * Create unique device name<br />+ */<br />+int rte_cryptodev_pmd_create_dev_name(char *name, const char *dev_name_prefix);<br />+<br />+#ifdef __cplusplus<br />+#endif<br />+<br />+#endif /* _RTE_CRYPTODEV_PMD_H_ */<br />diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py<br />index 4d9c1be..1179d8e 100755<br />--- a/usertools/dpdk-devbind.py<br />+++ b/usertools/dpdk-devbind.py<br />@@ -37,20 +37,15 @@<br /> avp_vnic = {'Class': '05', 'Vendor': '1af4', 'Device': '1110',<br />             'SVendor': None, 'SDevice': None}<br />  <br />-cnxk_bphy = {'Class': '08', 'Vendor': '177d', 'Device': 'a089',<br />-             'SVendor': None, 'SDevice': None}<br />-cnxk_bphy_cgx = {'Class': '08', 'Vendor': '177d', 'Device': 'a059,a060',<br />+octeontx2_sso = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f9,a0fa',<br />                  'SVendor': None, 'SDevice': None}<br />-cnxk_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',<br />-            'SVendor': None, 'SDevice': None}<br />-cnxk_inl_dev = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f0,a0f1',<br />-                'SVendor': None, 'SDevice': None}<br />-<br />-hisilicon_dma = {'Class': '08', 'Vendor': '19e5', 'Device': 'a122',<br />+octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',<br />+                 'SVendor': None, 'SDevice': None}<br />+octeontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',<br />+                 'SVendor': None, 'SDevice': None}<br />+octeontx2_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',<br />                  'SVendor': None, 'SDevice': None}<br />  <br />-intel_dlb = {'Class': '0b', 'Vendor': '8086', 'Device': '270b,2710,2714',<br />-             'SVendor': None, 'SDevice': None}<br /> intel_ioat_bdw = {'Class': '08', 'Vendor': '8086',<br />                   'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f',<br />                   'SVendor': None, 'SDevice': None}<br />@@ -65,28 +60,19 @@<br /> intel_ntb_icx = {'Class': '06', 'Vendor': '8086', 'Device': '347e',<br />                  'SVendor': None, 'SDevice': None}<br />  <br />-cnxk_sso = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f9,a0fa',<br />-                 'SVendor': None, 'SDevice': None}<br />-cnxk_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',<br />-                 'SVendor': None, 'SDevice': None}<br />-cn9k_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',<br />-                 'SVendor': None, 'SDevice': None}<br />-<br />-virtio_blk = {'Class': '01', 'Vendor': "1af4", 'Device': '1001,1042',<br />-                    'SVendor': None, 'SDevice': None}<br />+zte_zsda = {'Class': '01', 'Vendor': '1cf2', 'Device': None,<br />+                         'SVendor': None, 'SDevice': None}<br />  <br /> network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]<br /> baseband_devices = [acceleration_class]<br /> crypto_devices = [encryption_class, intel_processor_class]<br />-dma_devices = [cnxk_dma, hisilicon_dma,<br />-               intel_idxd_spr, intel_ioat_bdw, intel_ioat_icx, intel_ioat_skx]<br />-eventdev_devices = [cavium_sso, cavium_tim, intel_dlb, cnxk_sso]<br />-mempool_devices = [cavium_fpa, cnxk_npa]<br />+eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]<br />+mempool_devices = [cavium_fpa, octeontx2_npa]<br /> compress_devices = [cavium_zip]<br />-regex_devices = [cn9k_ree]<br />-misc_devices = [cnxk_bphy, cnxk_bphy_cgx, cnxk_inl_dev,<br />+regex_devices = [octeontx2_ree]<br />+misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_idxd_spr,<br />                 intel_ntb_skx, intel_ntb_icx,<br />-                virtio_blk]<br />+                octeontx2_dma, zte_zsda]<br />  <br /> # global dict ethernet devices present. Dictionary indexed by PCI address.<br /> # Each device within this is itself a dictionary of device properties<br />@@ -102,7 +88,6 @@<br /> force_flag = False<br /> args = []<br />  <br />-<br /> # check if a specific kernel module is loaded<br /> def module_is_loaded(module):<br />     global loaded_modules<br />@@ -190,13 +175,11 @@ def get_pci_device_details(dev_id, probe_lspci):<br />  <br />     return device<br />  <br />-<br /> def clear_data():<br />     '''This function clears any old data''' <br />     global devices<br />     devices = {}<br />  <br />-<br /> def get_device_details(devices_type):<br />     '''This function populates the "devices" dictionary. The keys used are<br />     the pci addresses (domain:bus:slot.func). The values are themselves<br />@@ -242,7 +225,7 @@ def get_device_details(devices_type):<br />         rt_info = route.split()<br />         for i in range(len(rt_info) - 1):<br />             if rt_info[i] == "dev":<br />-                ssh_if.append(rt_info[i + 1])<br />+                ssh_if.append(rt_info[i+1])<br />  <br />     # based on the basic info, get extended text details<br />     for d in devices.keys():<br />@@ -296,7 +279,6 @@ def device_type_match(dev, devices_type):<br />                 return True<br />     return False<br />  <br />-<br /> def dev_id_from_dev_name(dev_name):<br />     '''Take a device "name" - a string passed in by user to identify a NIC<br />     device, and determine the device id - i.e. the domain:bus:slot.func - for<br />@@ -336,9 +318,9 @@ def unbind_one(dev_id, force):<br />     filename = "/sys/bus/pci/drivers/%s/unbind" % dev["Driver_str"]<br />     try:<br />         f = open(filename, "a")<br />-    except OSError as err:<br />-        sys.exit("Error: unbind failed for %s - Cannot open %s: %s" %<br />-                 (dev_id, filename, err))<br />+    except:<br />+        sys.exit("Error: unbind failed for %s - Cannot open %s" %<br />+                 (dev_id, filename))<br />     f.write(dev_id)<br />     f.close()<br />  <br />@@ -376,58 +358,58 @@ def bind_one(dev_id, driver, force):<br />         if exists(filename):<br />             try:<br />                 f = open(filename, "w")<br />-            except OSError as err:<br />-                print("Error: bind failed for %s - Cannot open %s: %s" <br />-                      % (dev_id, filename, err), file=sys.stderr)<br />+            except:<br />+                print("Error: bind failed for %s - Cannot open %s" <br />+                      % (dev_id, filename), file=sys.stderr)<br />                 return<br />             try:<br />                 f.write("%s" % driver)<br />                 f.close()<br />-            except OSError as err:<br />+            except:<br />                 print("Error: bind failed for %s - Cannot write driver %s to " <br />-                      "PCI ID: %s" % (dev_id, driver, err), file=sys.stderr)<br />+                      "PCI ID " % (dev_id, driver), file=sys.stderr)<br />                 return<br />         # For kernels < 3.15 use new_id to add PCI id's to the driver<br />         else:<br />             filename = "/sys/bus/pci/drivers/%s/new_id" % driver<br />             try:<br />                 f = open(filename, "w")<br />-            except OSError as err:<br />-                print("Error: bind failed for %s - Cannot open %s: %s" <br />-                      % (dev_id, filename, err), file=sys.stderr)<br />+            except:<br />+                print("Error: bind failed for %s - Cannot open %s" <br />+                      % (dev_id, filename), file=sys.stderr)<br />                 return<br />             try:<br />                 # Convert Device and Vendor Id to int to write to new_id<br />                 f.write("%04x %04x" % (int(dev["Vendor"], 16),<br />                                        int(dev["Device"], 16)))<br />                 f.close()<br />-            except OSError as err:<br />+            except:<br />                 print("Error: bind failed for %s - Cannot write new PCI ID to " <br />-                      "driver %s: %s" % (dev_id, driver, err), file=sys.stderr)<br />+                      "driver %s" % (dev_id, driver), file=sys.stderr)<br />                 return<br />  <br />     # do the bind by writing to /sys<br />     filename = "/sys/bus/pci/drivers/%s/bind" % driver<br />     try:<br />         f = open(filename, "a")<br />-    except OSError as err:<br />-        print("Error: bind failed for %s - Cannot open %s: %s" <br />-              % (dev_id, filename, err), file=sys.stderr)<br />+    except:<br />+        print("Error: bind failed for %s - Cannot open %s" <br />+              % (dev_id, filename), file=sys.stderr)<br />         if saved_driver is not None:  # restore any previous driver<br />             bind_one(dev_id, saved_driver, force)<br />         return<br />     try:<br />         f.write(dev_id)<br />         f.close()<br />-    except OSError as err:<br />+    except:<br />         # for some reason, closing dev_id after adding a new PCI ID to new_id<br />         # results in IOError. however, if the device was successfully bound,<br />         # we don't care for any errors and can safely ignore IOError<br />         tmp = get_pci_device_details(dev_id, True)<br />         if "Driver_str" in tmp and tmp["Driver_str"] == driver:<br />             return<br />-        print("Error: bind failed for %s - Cannot bind to driver %s: %s" <br />-              % (dev_id, driver, err), file=sys.stderr)<br />+        print("Error: bind failed for %s - Cannot bind to driver %s" <br />+              % (dev_id, driver), file=sys.stderr)<br />         if saved_driver is not None:  # restore any previous driver<br />             bind_one(dev_id, saved_driver, force)<br />         return<br />@@ -439,15 +421,15 @@ def bind_one(dev_id, driver, force):<br />     if exists(filename):<br />         try:<br />             f = open(filename, "w")<br />-        except OSError as err:<br />-            sys.exit("Error: unbind failed for %s - Cannot open %s: %s" <br />-                     % (dev_id, filename, err))<br />+        except:<br />+            sys.exit("Error: unbind failed for %s - Cannot open %s" <br />+                     % (dev_id, filename))<br />         try:<br />             f.write("\00")<br />             f.close()<br />-        except OSError as err:<br />-            sys.exit("Error: unbind failed for %s - Cannot write %s: %s" <br />-                     % (dev_id, filename, err))<br />+        except:<br />+            sys.exit("Error: unbind failed for %s - Cannot open %s" <br />+                     % (dev_id, filename))<br />  <br />  <br /> def unbind_all(dev_list, force=False):<br />@@ -481,7 +463,7 @@ def bind_all(dev_list, driver, force=False):<br />         dev_id_from_dev_name(driver)<br />         # if we've made it this far, this means that the "driver" was a valid<br />         # device string, so it's probably not a valid driver name.<br />-        sys.exit("Error: Driver '%s' does not look like a valid driver. " <br />+        sys.exit("Error: Driver '%s' does not look like a valid driver. " \<br />                  "Did you forget to specify the driver to bind devices to?" % driver)<br />     except ValueError:<br />         # driver generated error - it's not a valid device ID, so all is well<br />@@ -511,8 +493,8 @@ def bind_all(dev_list, driver, force=False):<br />                 continue<br />  <br />             # update information about this device<br />-            devices[d] = dict(devices[d].items()<br />-                              + get_pci_device_details(d, True).items())<br />+            devices[d] = dict(devices[d].items() +<br />+                              get_pci_device_details(d, True).items())<br />  <br />             # check if updated information indicates that the device was bound<br />             if "Driver_str" in devices[d]:<br />@@ -526,7 +508,7 @@ def display_devices(title, dev_list, extra_params=None):<br />      device's dictionary.''' <br />     strings = []  # this holds the strings to print. We sort before printing<br />     print("\n%s" % title)<br />-    print("=" * len(title))<br />+    print("="*len(title))<br />     if not dev_list:<br />         strings.append("<none>")<br />     else:<br />@@ -542,7 +524,6 @@ def display_devices(title, dev_list, extra_params=None):<br />     strings.sort()<br />     print("\n".join(strings))  # print one per line<br />  <br />-<br /> def show_device_status(devices_type, device_name, if_field=False):<br />     global dpdk_drivers<br />     kernel_drv = []<br />@@ -585,7 +566,6 @@ def show_device_status(devices_type, device_name, if_field=False):<br />         display_devices("Other %s devices" % device_name, no_drv,<br />                         "unused=%(Module_str)s")<br />  <br />-<br /> def show_status():<br />     '''Function called when the script is passed the "--status" option.<br />     Displays to the user what devices are bound to the igb_uio driver, the<br />@@ -600,9 +580,6 @@ def show_status():<br />     if status_dev in ["crypto", "all"]:<br />         show_device_status(crypto_devices, "Crypto")<br />  <br />-    if status_dev in ["dma", "all"]:<br />-        show_device_status(dma_devices, "DMA")<br />-<br />     if status_dev in ["event", "all"]:<br />         show_device_status(eventdev_devices, "Eventdev")<br />  <br />@@ -671,8 +648,8 @@ def parse_args():<br />     parser.add_argument(<br />         '--status-dev',<br />         help="Print the status of given device group.",<br />-        choices=['baseband', 'compress', 'crypto', 'dma', 'event',<br />-                 'mempool', 'misc', 'net', 'regex'])<br />+        choices=['baseband', 'compress', 'crypto', 'event',<br />+                'mempool', 'misc', 'net', 'regex'])<br />     bind_group = parser.add_mutually_exclusive_group()<br />     bind_group.add_argument(<br />         '-b',<br />@@ -734,7 +711,6 @@ def parse_args():<br />         new_args.extend(pci_glob(arg))<br />     args = new_args<br />  <br />-<br /> def do_arg_actions():<br />     '''do the actual action requested by the user''' <br />     global b_flag<br />@@ -753,7 +729,6 @@ def do_arg_actions():<br />             get_device_details(network_devices)<br />             get_device_details(baseband_devices)<br />             get_device_details(crypto_devices)<br />-            get_device_details(dma_devices)<br />             get_device_details(eventdev_devices)<br />             get_device_details(mempool_devices)<br />             get_device_details(compress_devices)<br />@@ -776,7 +751,6 @@ def main():<br />     get_device_details(network_devices)<br />     get_device_details(baseband_devices)<br />     get_device_details(crypto_devices)<br />-    get_device_details(dma_devices)<br />     get_device_details(eventdev_devices)<br />     get_device_details(mempool_devices)<br />     get_device_details(compress_devices)<br />@@ -784,6 +758,5 @@ def main():<br />     get_device_details(misc_devices)<br />     do_arg_actions()<br />  <br />-<br /> if __name__ == "__main__":<br />     main()<br />--  <br />2.27.0<br />