Add zsda compressdev enqueue datapath.<br /> <br />Signed-off-by: Hanxiao Li <li.hanxiao@zte.com.cn> <br />---<br /> drivers/common/zsda/meson.build       |   2 +-<br /> drivers/common/zsda/zsda_qp.c         | 107 ++++++++++++<br /> drivers/common/zsda/zsda_qp.h         |  23 ++-<br /> drivers/common/zsda/zsda_qp_common.c  |  72 ++++++++<br /> drivers/common/zsda/zsda_qp_common.h  |  41 +++++<br /> drivers/compress/zsda/zsda_comp.c     | 233 ++++++++++++++++++++++++++<br /> drivers/compress/zsda/zsda_comp.h     |  36 ++++<br /> drivers/compress/zsda/zsda_comp_pmd.c |  19 ++-<br /> 8 files changed, 515 insertions(+), 18 deletions(-)<br /> create mode 100644 drivers/compress/zsda/zsda_comp.c<br /> create mode 100644 drivers/compress/zsda/zsda_comp.h<br /> <br />diff --git a/drivers/common/zsda/meson.build b/drivers/common/zsda/meson.build<br />index 6e6d5ab006..152150e5ef 100644<br />--- a/drivers/common/zsda/meson.build<br />+++ b/drivers/common/zsda/meson.build<br />@@ -20,7 +20,7 @@ zsda_compress_path = 'compress/zsda' <br /> zsda_compress_relpath = '../../' + zsda_compress_path<br /> includes += include_directories(zsda_compress_relpath)<br /> if zsda_compress<br />-    foreach f: ['zsda_comp_pmd.c']<br />+    foreach f: ['zsda_comp_pmd.c', 'zsda_comp.c']<br />         sources += files(join_paths(zsda_compress_relpath, f))<br />     endforeach<br /> endif<br />diff --git a/drivers/common/zsda/zsda_qp.c b/drivers/common/zsda/zsda_qp.c<br />index 658b0b69e3..c2a7d9b28b 100644<br />--- a/drivers/common/zsda/zsda_qp.c<br />+++ b/drivers/common/zsda/zsda_qp.c<br />@@ -771,3 +771,110 @@ zsda_common_setup_qp(uint32_t zsda_dev_id, struct zsda_qp **qp_addr,<br />     }<br />     return ret;<br /> }<br />+<br />+<br />+static int<br />+zsda_find_next_free_cookie(const struct zsda_queue *queue, void **op_cookie,<br />+              uint16_t *idx)<br />+{<br />+    uint16_t old_tail = queue->tail;<br />+    uint16_t tail = queue->tail;<br />+    struct zsda_op_cookie *cookie;<br />+<br />+    do {<br />+        cookie = op_cookie[tail];<br />+        if (!cookie->used) {<br />+            *idx = tail & (queue->queue_size - 1);<br />+            return ZSDA_SUCCESS;<br />+        }<br />+        tail = zsda_modulo_16(tail++, queue->modulo_mask);<br />+    } while (old_tail != tail);<br />+<br />+    return -EINVAL;<br />+}<br />+<br />+static int<br />+zsda_enqueue(void *op, struct zsda_qp *qp)<br />+{<br />+    uint16_t new_tail;<br />+    enum zsda_service_type type;<br />+    void **op_cookie;<br />+    int ret = ZSDA_SUCCESS;<br />+    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 />+            queue = &qp->srv[type].tx_q;<br />+            op_cookie = qp->srv[type].op_cookies;<br />+<br />+            if (zsda_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 />+                qp->srv[type].stats.enqueue_err_count++;<br />+                ZSDA_LOG(ERR, "Failed! config wqe");<br />+                break;<br />+            }<br />+            qp->srv[type].stats.enqueued_count++;<br />+<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,<br />+                    (uint8_t)(queue->cycle_size - 1));<br />+<br />+            queue->pushed_wqe++;<br />+            break;<br />+        }<br />+    }<br />+<br />+    return ret;<br />+}<br />+<br />+static void<br />+zsda_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, const uint16_t nb_ops)<br />+{<br />+    int ret = ZSDA_SUCCESS;<br />+    enum zsda_service_type type;<br />+    uint16_t i;<br />+    uint16_t nb_send = 0;<br />+    void *op;<br />+<br />+    if (nb_ops > ZSDA_MAX_DESC) {<br />+        ZSDA_LOG(ERR, "Enqueue number bigger than %d", ZSDA_MAX_DESC);<br />+        return 0;<br />+    }<br />+<br />+    for (i = 0; i < nb_ops; i++) {<br />+        op = ops[i];<br />+        ret = zsda_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 />+            zsda_tx_write_tail(&qp->srv[type].tx_q);<br />+<br />+    return nb_send;<br />+}<br />+<br />diff --git a/drivers/common/zsda/zsda_qp.h b/drivers/common/zsda/zsda_qp.h<br />index c9c78f4a8c..012ed19c62 100644<br />--- a/drivers/common/zsda/zsda_qp.h<br />+++ b/drivers/common/zsda/zsda_qp.h<br />@@ -48,7 +48,6 @@<br /> #define SET_CYCLE            0xff<br /> #define SET_HEAD_INTI        0x0<br />  <br />-<br /> #define ZSDA_TIME_SLEEP_US    100<br /> #define ZSDA_TIME_NUM        500<br />  <br />@@ -95,6 +94,15 @@<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 /> extern struct zsda_num_qps zsda_nb_qps;<br />  <br /> enum zsda_admin_msg_id {<br />@@ -141,17 +149,6 @@ struct zsda_qp_config {<br />     const char *service_str;<br /> };<br />  <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 __rte_cache_aligned zsda_sgl {<br />-    struct zsda_buf buffers[ZSDA_SGL_MAX_NUMBER];<br />-};<br />-<br /> struct zsda_op_cookie {<br />     struct zsda_sgl sgl_src;<br />     struct zsda_sgl sgl_dst;<br />@@ -179,4 +176,6 @@ zsda_qps_hw_per_service(struct zsda_pci_device *zsda_pci_dev,<br /> int zsda_common_setup_qp(uint32_t dev_id, struct zsda_qp **qp_addr,<br />         const uint16_t queue_pair_id, const struct zsda_qp_config *conf);<br />  <br />+uint16_t zsda_enqueue_op_burst(struct zsda_qp *qp, void **ops, const uint16_t nb_ops);<br />+<br /> #endif /* _ZSDA_QP_H_ */<br />diff --git a/drivers/common/zsda/zsda_qp_common.c b/drivers/common/zsda/zsda_qp_common.c<br />index 577392871f..8eff8a5485 100644<br />--- a/drivers/common/zsda/zsda_qp_common.c<br />+++ b/drivers/common/zsda/zsda_qp_common.c<br />@@ -118,3 +118,75 @@ zsda_stats_reset(void **queue_pairs, const uint32_t nb_queue_pairs)<br />         }<br />     }<br /> }<br />+<br />+int<br />+zsda_fill_sgl(const struct rte_mbuf *buf, uint32_t offset, struct zsda_sgl *sgl,<br />+          const phys_addr_t sgl_phy_addr, uint32_t remain_len,<br />+          struct comp_head_info *comp_head_info)<br />+{<br />+    uint32_t nr;<br />+    uint16_t put_in_len;<br />+    bool head_set = false;<br />+<br />+    for (nr = 0; (buf && (nr < (ZSDA_SGL_MAX_NUMBER - 1)));) {<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 />+        if (comp_head_info && !head_set) {<br />+            sgl->buffers[nr].len = comp_head_info->head_len;<br />+            sgl->buffers[nr].addr = comp_head_info->head_phys_addr;<br />+            sgl->buffers[nr].type = SGL_TYPE_PHYS_ADDR;<br />+            ++nr;<br />+            head_set = true;<br />+            remain_len -= comp_head_info->head_len;<br />+            continue;<br />+        } else {<br />+            put_in_len = rte_pktmbuf_data_len(buf) - (offset & 0xffff);<br />+            if (remain_len <= put_in_len)<br />+                put_in_len = remain_len;<br />+            remain_len -= put_in_len;<br />+<br />+            sgl->buffers[nr].len = put_in_len;<br />+            sgl->buffers[nr].addr = rte_pktmbuf_iova_offset(buf, offset);<br />+            sgl->buffers[nr].type = SGL_TYPE_PHYS_ADDR;<br />+        }<br />+        offset = 0;<br />+        ++nr;<br />+        buf = buf->next;<br />+<br />+        if (remain_len == 0)<br />+            break;<br />+    }<br />+<br />+    if (nr == 0) {<br />+        ZSDA_LOG(ERR, "In fill_sgl, nr == 0");<br />+        return ZSDA_FAILED;<br />+    }<br />+<br />+    sgl->buffers[nr - 1].type = SGL_TYPE_LAST_PHYS_ADDR;<br />+<br />+    if (buf) {<br />+        if (unlikely(buf->next)) {<br />+            if (nr == (ZSDA_SGL_MAX_NUMBER - 1)) {<br />+                ZSDA_LOG(ERR, "ERR! segs size (%u)",<br />+                     (ZSDA_SGL_MAX_NUMBER));<br />+                return -EINVAL;<br />+            }<br />+        }<br />+    }<br />+<br />+    return ZSDA_SUCCESS;<br />+}<br />diff --git a/drivers/common/zsda/zsda_qp_common.h b/drivers/common/zsda/zsda_qp_common.h<br />index de746ad00b..c67de6b04d 100644<br />--- a/drivers/common/zsda/zsda_qp_common.h<br />+++ b/drivers/common/zsda/zsda_qp_common.h<br />@@ -39,6 +39,27 @@ enum zsda_service_type {<br /> #define ZSDA_MAX_CYCLE        256<br /> #define ZSDA_MAX_DEV        RTE_PMD_ZSDA_MAX_PCI_DEVICES<br /> #define MAX_NUM_OPS            0x1FF<br />+#define ZSDA_SGL_FRAGMENT_SIZE    32<br />+<br />+#define ZSDA_OPC_COMP_GZIP        0x10 /* Encomp deflate-Gzip */<br />+#define ZSDA_OPC_COMP_ZLIB        0x11 /* Encomp deflate-Zlib */<br />+#define ZSDA_OPC_DECOMP_GZIP    0x18 /* Decompinfalte-Gzip */<br />+#define ZSDA_OPC_DECOMP_ZLIB    0x19 /* Decompinfalte-Zlib */<br />+#define ZSDA_OPC_INVALID        0xff<br />+<br />+enum wqe_element_type {<br />+    WQE_ELM_TYPE_PHYS_ADDR = 1,<br />+    WQE_ELM_TYPE_LIST,<br />+    WQE_ELM_TYPE_LIST_ADDR,<br />+    WQE_ELM_TYPE_LIST_SGL32,<br />+};<br />+<br />+enum sgl_element_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 /> struct zsda_admin_req {<br />     uint16_t msg_type;<br />@@ -144,10 +165,30 @@ struct zsda_qp {<br />     struct qp_srv srv[ZSDA_MAX_SERVICES];<br /> };<br />  <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 __rte_cache_aligned zsda_sgl {<br />+    struct zsda_buf buffers[ZSDA_SGL_MAX_NUMBER];<br />+};<br />+<br />+struct comp_head_info {<br />+    uint32_t head_len;<br />+    phys_addr_t head_phys_addr;<br />+};<br />+<br /> int zsda_queue_pair_release(struct zsda_qp **qp_addr);<br /> void zsda_stats_get(void **queue_pairs, const uint32_t nb_queue_pairs,<br />           struct zsda_qp_stat *stats);<br /> void zsda_stats_reset(void **queue_pairs, const uint32_t nb_queue_pairs);<br /> void zsda_queue_delete(const struct zsda_queue *queue);<br />  <br />+int zsda_fill_sgl(const struct rte_mbuf *buf, uint32_t offset,<br />+          struct zsda_sgl *sgl, const phys_addr_t sgl_phy_addr,<br />+          uint32_t remain_len, struct comp_head_info *comp_head_info);<br />+<br /> #endif /* _ZSDA_QP_COMMON_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 0000000000..c00e0c2a4b<br />--- /dev/null<br />+++ b/drivers/compress/zsda/zsda_comp.c<br />@@ -0,0 +1,233 @@<br />+/* SPDX-License-Identifier: BSD-3-Clause<br />+ * Copyright(c) 2024 ZTE Corporation<br />+ */<br />+<br />+#include "zsda_comp.h" <br />+<br />+#define ZLIB_HEADER_SIZE 2<br />+#define ZLIB_TRAILER_SIZE 4<br />+#define GZIP_HEADER_SIZE 10<br />+#define GZIP_TRAILER_SIZE 8<br />+#define CHECKSUM_SIZE 4<br />+<br />+int<br />+zsda_comp_match(const void *op_in)<br />+{<br />+    const struct rte_comp_op *op = op_in;<br />+    const struct zsda_comp_xform *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 />+int<br />+zsda_decomp_match(const void *op_in)<br />+{<br />+    const struct rte_comp_op *op = op_in;<br />+    const struct zsda_comp_xform *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 />+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_NONE ||<br />+            xform->checksum_type == RTE_COMP_CHECKSUM_CRC32)<br />+            return ZSDA_OPC_COMP_GZIP;<br />+        else if (xform->checksum_type == RTE_COMP_CHECKSUM_ADLER32)<br />+            return ZSDA_OPC_COMP_ZLIB;<br />+    }<br />+    if (xform->type == RTE_COMP_DECOMPRESS) {<br />+        if (xform->checksum_type == RTE_COMP_CHECKSUM_CRC32 ||<br />+            xform->checksum_type == RTE_COMP_CHECKSUM_NONE)<br />+            return ZSDA_OPC_DECOMP_GZIP;<br />+        else if (xform->checksum_type == RTE_COMP_CHECKSUM_ADLER32)<br />+            return ZSDA_OPC_DECOMP_ZLIB;<br />+    }<br />+<br />+    return ZSDA_OPC_INVALID;<br />+}<br />+<br />+int<br />+zsda_build_comp_request(void *op_in, const struct zsda_queue *queue,<br />+           void **op_cookies, const uint16_t new_tail)<br />+{<br />+    struct rte_comp_op *op = op_in;<br />+    struct zsda_comp_xform *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 = 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 />+    struct comp_head_info comp_head_info;<br />+<br />+    uint8_t opcode;<br />+    int ret;<br />+    uint32_t op_offset;<br />+    uint32_t op_src_len;<br />+    uint32_t op_dst_len;<br />+    uint32_t head_len;<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, "Failed! get_opcode");<br />+        return -EINVAL;<br />+    }<br />+<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+<br />+    if (opcode == ZSDA_OPC_COMP_GZIP)<br />+        head_len = GZIP_HEADER_SIZE;<br />+    else if (opcode == ZSDA_OPC_COMP_ZLIB)<br />+        head_len = ZLIB_HEADER_SIZE;<br />+    else {<br />+        ZSDA_LOG(ERR, "Comp, op_code error!");<br />+        return -EINVAL;<br />+    }<br />+<br />+    comp_head_info.head_len = head_len;<br />+    comp_head_info.head_phys_addr = cookie->comp_head_phys_addr;<br />+<br />+    op_offset = op->src.offset;<br />+    op_src_len = op->src.length;<br />+    ret = zsda_fill_sgl(op->m_src, op_offset, sgl_src,<br />+                   cookie->sgl_src_phys_addr, op_src_len, NULL);<br />+<br />+    op_offset = op->dst.offset;<br />+    op_dst_len = op->m_dst->pkt_len - op_offset;<br />+    op_dst_len += head_len;<br />+    ret |= zsda_fill_sgl(op->m_dst, op_offset, sgl_dst,<br />+                    cookie->sgl_dst_phys_addr, op_dst_len,<br />+                    &comp_head_info);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! zsda_fill_sgl");<br />+        return ret;<br />+    }<br />+<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_comp));<br />+    wqe->rx_length = op_src_len;<br />+    wqe->tx_length = op_dst_len;<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = opcode;<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = WQE_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = WQE_ELM_TYPE_LIST;<br />+<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr = cookie->sgl_dst_phys_addr;<br />+<br />+    return ret;<br />+}<br />+<br />+int<br />+zsda_build_decomp_request(void *op_in, const struct zsda_queue *queue,<br />+             void **op_cookies, const uint16_t new_tail)<br />+{<br />+    struct rte_comp_op *op = op_in;<br />+    struct zsda_comp_xform *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 = 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 />+    uint8_t opcode;<br />+    int ret;<br />+<br />+    uint32_t op_offset;<br />+    uint32_t op_src_len;<br />+    uint32_t op_dst_len;<br />+<br />+    uint8_t *head_data;<br />+    uint16_t head_len;<br />+    struct comp_head_info comp_head_info;<br />+    uint8_t head_zlib[ZLIB_HEADER_SIZE] = {0x78, 0xDA};<br />+    uint8_t head_gzip[GZIP_HEADER_SIZE] = {0x1F, 0x8B, 0x08, 0x00, 0x00,<br />+                           0x00, 0x00, 0x00, 0x00, 0x03};<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, "Failed! get_opcode");<br />+        return -EINVAL;<br />+    }<br />+<br />+    cookie->used = true;<br />+    cookie->sid = new_tail;<br />+    cookie->op = op;<br />+<br />+    if (opcode == ZSDA_OPC_DECOMP_GZIP) {<br />+        head_data = head_gzip;<br />+        head_len = GZIP_HEADER_SIZE;<br />+    } else if (opcode == ZSDA_OPC_DECOMP_ZLIB) {<br />+        head_data = head_zlib;<br />+        head_len = ZLIB_HEADER_SIZE;<br />+    } else {<br />+        ZSDA_LOG(ERR, "Comp, op_code error!");<br />+        return -EINVAL;<br />+    }<br />+<br />+    op_offset = op->src.offset;<br />+    op_src_len = op->src.length;<br />+    op_src_len += head_len;<br />+    comp_head_info.head_len = head_len;<br />+    comp_head_info.head_phys_addr = cookie->comp_head_phys_addr;<br />+    cookie->decomp_no_tail = true;<br />+    for (int i = 0; i < head_len; i++)<br />+        cookie->comp_head[i] = head_data[i];<br />+<br />+    ret = zsda_fill_sgl(op->m_src, op_offset, sgl_src,<br />+                cookie->sgl_src_phys_addr, op_src_len,<br />+                &comp_head_info);<br />+<br />+    op_offset = op->dst.offset;<br />+    op_dst_len = op->m_dst->pkt_len - op_offset;<br />+    ret |= zsda_fill_sgl(op->m_dst, op_offset, sgl_dst,<br />+                 cookie->sgl_dst_phys_addr, op_dst_len, NULL);<br />+<br />+    if (ret) {<br />+        ZSDA_LOG(ERR, "Failed! zsda_fill_sgl");<br />+        return ret;<br />+    }<br />+<br />+    memset(wqe, 0, sizeof(struct zsda_wqe_comp));<br />+<br />+    wqe->rx_length = op_src_len;<br />+    wqe->tx_length = op_dst_len;<br />+    wqe->valid = queue->valid;<br />+    wqe->op_code = opcode;<br />+    wqe->sid = cookie->sid;<br />+    wqe->rx_sgl_type = WQE_ELM_TYPE_LIST;<br />+    wqe->tx_sgl_type = WQE_ELM_TYPE_LIST;<br />+    wqe->rx_addr = cookie->sgl_src_phys_addr;<br />+    wqe->tx_addr = cookie->sgl_dst_phys_addr;<br />+<br />+    return ret;<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 0000000000..e7dea7e5a4<br />--- /dev/null<br />+++ b/drivers/compress/zsda/zsda_comp.h<br />@@ -0,0 +1,36 @@<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 "zsda_comp_pmd.h" <br />+<br />+struct compress_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 />+int zsda_comp_match(const void *op_in);<br />+int zsda_decomp_match(const void *op_in);<br />+<br />+int zsda_build_comp_request(void *op_in, const struct zsda_queue *queue,<br />+               void **op_cookies, const uint16_t new_tail);<br />+<br />+int zsda_build_decomp_request(void *op_in, const struct zsda_queue *queue,<br />+             void **op_cookies, const uint16_t new_tail);<br />+<br />+#endif /* _ZSDA_COMP_H_ */<br />diff --git a/drivers/compress/zsda/zsda_comp_pmd.c b/drivers/compress/zsda/zsda_comp_pmd.c<br />index 9824f7c83f..9cb2169d68 100644<br />--- a/drivers/compress/zsda/zsda_comp_pmd.c<br />+++ b/drivers/compress/zsda/zsda_comp_pmd.c<br />@@ -7,6 +7,7 @@<br /> #include "zsda_logs.h" <br /> #include "zsda_qp_common.h" <br /> #include "zsda_comp_pmd.h" <br />+#include "zsda_comp.h" <br />  <br /> static int<br /> zsda_comp_xform_size(void)<br />@@ -229,8 +230,8 @@ zsda_setup_comp_queue(struct zsda_pci_device *zsda_pci_dev, const uint16_t qp_id<br />  <br />     ret = zsda_common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />     qp->srv[type].rx_cb = NULL;<br />-    qp->srv[type].tx_cb = NULL;<br />-    qp->srv[type].match = NULL;<br />+    qp->srv[type].tx_cb = zsda_build_comp_request;<br />+    qp->srv[type].match = zsda_comp_match;<br />  <br />     return ret;<br /> }<br />@@ -254,8 +255,8 @@ zsda_setup_decomp_queue(struct zsda_pci_device *zsda_pci_dev, const uint16_t qp_<br />  <br />     ret = zsda_common_setup_qp(zsda_pci_dev->zsda_dev_id, &qp, qp_id, &conf);<br />     qp->srv[type].rx_cb = NULL;<br />-    qp->srv[type].tx_cb = NULL;<br />-    qp->srv[type].match = NULL;<br />+    qp->srv[type].tx_cb = zsda_build_decomp_request;<br />+    qp->srv[type].match = zsda_decomp_match;<br />  <br />     return ret;<br /> }<br />@@ -339,6 +340,14 @@ 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 />+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 /> int<br /> zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev)<br /> {<br />@@ -376,7 +385,7 @@ zsda_comp_dev_create(struct zsda_pci_device *zsda_pci_dev)<br />  <br />     compressdev->dev_ops = &compress_zsda_ops;<br />  <br />-    compressdev->enqueue_burst = NULL;<br />+    compressdev->enqueue_burst = zsda_comp_pmd_enqueue_op_burst;<br />     compressdev->dequeue_burst = NULL;<br />  <br />     compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;<br />--  <br />2.27.0<br />