From: Vamsi Attunuru <[email protected]>

Adds DMA driver support for O20 hardware.

Signed-off-by: Vamsi Attunuru <[email protected]>
---
 drivers/dma/cnxk/cnxk_dmadev.c    | 527 +++++++++++++++++++++++++++++-
 drivers/dma/cnxk/cnxk_dmadev.h    |  72 +++-
 drivers/dma/cnxk/cnxk_dmadev_fp.c | 214 ++++++++++++
 3 files changed, 791 insertions(+), 22 deletions(-)

diff --git a/drivers/dma/cnxk/cnxk_dmadev.c b/drivers/dma/cnxk/cnxk_dmadev.c
index 6ae7fdca3b..3970abe1c3 100644
--- a/drivers/dma/cnxk/cnxk_dmadev.c
+++ b/drivers/dma/cnxk/cnxk_dmadev.c
@@ -2,6 +2,9 @@
  * Copyright (C) 2021 Marvell International Ltd.
  */
 
+#include <errno.h>
+#include <stdlib.h>
+
 #include <rte_event_dma_adapter.h>
 
 #include <cnxk_dmadev.h>
@@ -9,6 +12,68 @@
 static int cnxk_stats_reset(struct rte_dma_dev *dev, uint16_t vchan);
 static void cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t enable_enq_deq);
 
+static int
+parse_val_u16(const char *key, const char *value, void *extra_args)
+{
+       unsigned long val;
+       char *end;
+
+       RTE_SET_USED(key);
+
+       if (value == NULL || extra_args == NULL)
+               return -EINVAL;
+
+       errno = 0;
+       val = strtoul(value, &end, 0);
+       if (errno != 0 || end == value || *end != '\0' || val > UINT16_MAX)
+               return -EINVAL;
+
+       *(uint16_t *)extra_args = (uint16_t)val;
+
+       return 0;
+}
+
+static int
+cn20k_dmadev_parse_devargs(struct rte_devargs *devargs, struct cnxk_dpi_vf_s 
*dpivf)
+{
+       uint16_t num_vchans = CN20K_DPI_DEF_VCHANS;
+       uint16_t num_lfs = num_vchans >> 1; /* Each LF has 2 rings */
+       struct rte_kvargs *kvlist = NULL;
+
+       if (devargs == NULL) {
+               dpivf->max_vchans = num_vchans;
+               dpivf->max_lfs = num_lfs;
+               return 0;
+       }
+
+       kvlist = rte_kvargs_parse(devargs->args, NULL);
+       if (kvlist == NULL)
+               goto exit;
+
+       if (rte_kvargs_process(kvlist, CN20K_DPI_NUM_VCHANS, &parse_val_u16, 
&num_vchans) < 0)
+               goto exit;
+       if (rte_kvargs_process(kvlist, CN20K_DPI_NUM_LFS, &parse_val_u16, 
&num_lfs) < 0)
+               goto exit;
+
+       if (!num_vchans || !num_lfs || num_vchans > CN20K_DPI_MAX_VCHANS ||
+           num_lfs > CN20K_DPI_MAX_LFS)
+               goto exit;
+
+       if (!rte_is_power_of_2(num_vchans) || !rte_is_power_of_2(num_lfs)) {
+               plt_err("num_vchans or num_lfs is not a power of 2");
+               goto exit;
+       }
+
+       dpivf->max_vchans = num_vchans;
+       dpivf->max_lfs = num_lfs;
+
+       rte_kvargs_free(kvlist);
+       return 0;
+exit:
+       rte_kvargs_free(kvlist);
+       return -EINVAL;
+}
+
 static int
 cnxk_dmadev_info_get(const struct rte_dma_dev *dev, struct rte_dma_info 
*dev_info, uint32_t size)
 {
@@ -25,9 +90,21 @@ cnxk_dmadev_info_get(const struct rte_dma_dev *dev, struct 
rte_dma_info *dev_inf
                dev_info->dev_capa |= RTE_DMA_CAPA_PRI_POLICY_SP;
                dev_info->nb_priorities = CN10K_DPI_MAX_PRI;
        }
-       dev_info->max_desc = CNXK_DPI_MAX_DESC;
-       dev_info->min_desc = CNXK_DPI_MIN_DESC;
-       dev_info->max_sges = CNXK_DPI_MAX_POINTER;
+
+       if (roc_model_is_cn20k()) {
+               const uint16_t vpr = dpivf->vchans_per_ring ? 
dpivf->vchans_per_ring : 1;
+
+               dev_info->max_desc = CN20K_DPI_MAX_DESC / vpr;
+               dev_info->min_desc = CN20K_DPI_MIN_DESC;
+               dev_info->max_sges = CN20K_DPI_MAX_POINTER;
+               dev_info->max_vchans = dpivf->max_vchans;
+               dev_info->dev_capa |= RTE_DMA_CAPA_OPS_FILL;
+       } else {
+               dev_info->max_desc = CNXK_DPI_MAX_DESC;
+               dev_info->min_desc = CNXK_DPI_MIN_DESC;
+               dev_info->max_sges = CNXK_DPI_MAX_POINTER;
+               dev_info->max_vchans = CNXK_DPI_MAX_VCHANS_PER_QUEUE;
+       }
 
        return 0;
 }
@@ -52,8 +129,10 @@ cnxk_dmadev_vchan_free(struct cnxk_dpi_vf_s *dpivf, 
uint16_t vchan)
 
        for (; i < num_vchans; i++) {
                dpi_conf = &dpivf->conf[i];
-               rte_free(dpi_conf->c_desc.compl_ptr);
-               dpi_conf->c_desc.compl_ptr = NULL;
+               if (dpi_conf->c_desc.compl_ptr) {
+                       rte_free(dpi_conf->c_desc.compl_ptr);
+                       dpi_conf->c_desc.compl_ptr = NULL;
+               }
        }
 
        return 0;
@@ -99,10 +178,42 @@ cnxk_dmadev_chunk_pool_create(struct rte_dma_dev *dev, 
uint32_t nb_chunks, uint3
        return rc;
 }
 
+static int
+cnxk_dmadev_vchan_rsrc_free(struct cnxk_dpi_vf_s *dpivf)
+{
+       struct roc_dpi *rdpi = &dpivf->rdpi;
+       int rc;
+
+       if (dpivf->ring_conf) {
+               rte_free(dpivf->ring_conf);
+               dpivf->ring_conf = NULL;
+       }
+
+       if (rdpi->lfs == NULL)
+               return 0;
+
+       rc = roc_dpi_lf_chan_tbl_free(&(rdpi->lfs[0]));
+       if (rc < 0) {
+               plt_err("Failed to free dpi lf channel table");
+               goto error;
+       }
+
+       rc = roc_dpi_rsrc_fini(rdpi);
+       if (rc < 0)
+               plt_err("Failed to free dpi lfs");
+
+       dpivf->is_ring_conf_done = false;
+error:
+       return rc;
+}
+
 static int
 cnxk_dmadev_configure(struct rte_dma_dev *dev, const struct rte_dma_conf 
*conf, uint32_t conf_sz)
 {
        struct cnxk_dpi_vf_s *dpivf = NULL;
+       struct roc_dpi_lf *lf;
+       uint16_t num_rings;
+       int rc = 0;
 
        RTE_SET_USED(conf_sz);
        dpivf = dev->fp_obj->dev_private;
@@ -111,13 +222,78 @@ cnxk_dmadev_configure(struct rte_dma_dev *dev, const 
struct rte_dma_conf *conf,
         * Free up vchan memory if any, before configuring num_vchans.
         */
        cnxk_dmadev_vchan_free(dpivf, RTE_DMA_ALL_VCHAN);
+
        dpivf->num_vchans = conf->nb_vchans;
+       if (roc_model_is_cn20k()) {
+               if (!rte_is_power_of_2(dpivf->num_vchans))
+                       dpivf->num_vchans = rte_align32pow2(dpivf->num_vchans);
+
+               if (dpivf->num_vchans > dpivf->max_vchans) {
+                       plt_info("Limiting vchans from %u to max_vchans %u",
+                                dpivf->num_vchans, dpivf->max_vchans);
+                       dpivf->num_vchans = dpivf->max_vchans;
+               }
+       }
        if (roc_feature_dpi_has_priority())
                dpivf->rdpi.priority = conf->priority;
 
        cnxk_set_fp_ops(dev, conf->flags & RTE_DMA_CFG_FLAG_ENQ_DEQ);
 
-       return 0;
+       if (roc_model_is_cn20k()) {
+               rc = cnxk_dmadev_vchan_rsrc_free(dpivf);
+               if (rc < 0)
+                       goto error;
+
+               dpivf->rdpi.nr_lfs = dpivf->max_lfs;
+               num_rings = dpivf->rdpi.nr_lfs << 1;
+
+               if (dpivf->num_vchans > num_rings) {
+                       dpivf->vchans_per_ring = dpivf->num_vchans / num_rings;
+               } else {
+                       /* Each vchan has got it's own hardware ring */
+                       dpivf->vchans_per_ring = 1;
+                       dpivf->rdpi.nr_lfs = dpivf->num_vchans >> 1;
+                       if (!dpivf->rdpi.nr_lfs)
+                               dpivf->rdpi.nr_lfs = 1;
+               }
+
+               if ((CN20K_DPI_MAX_DESC / dpivf->vchans_per_ring) < 
CN20K_DPI_MIN_DESC) {
+                       rc = -EINVAL;
+                       plt_err("Very few LFs are requested than required");
+                       goto error;
+               }
+
+               num_rings = dpivf->rdpi.nr_lfs << 1;
+               dpivf->ring_conf = rte_zmalloc("dpi_ring_conf", sizeof(struct 
cn20k_ring_conf) *
+                                              num_rings, 0);
+               if (dpivf->ring_conf == NULL) {
+                       plt_err("Failed to allocate memory for ring conf");
+                       rc = -ENOMEM;
+                       goto error;
+               }
+
+               rc = roc_dpi_rsrc_init(&dpivf->rdpi);
+               if (rc < 0) {
+                       plt_err("rsrc alloc failed");
+                       goto error;
+               }
+
+               lf = &(dpivf->rdpi.lfs[0]);
+               rc = roc_dpi_lf_chan_tbl_alloc(lf, dpivf->num_vchans);
+               if (rc < 0) {
+                       plt_err("Failed to allocate chan tbl");
+                       goto error;
+               }
+
+               dpivf->chan_tbl = lf->chan_tbl;
+               dpivf->is_ring_conf_done = false;
+       }
+
+error:
+       if (roc_model_is_cn20k() && rc < 0)
+               cnxk_dmadev_vchan_rsrc_free(dpivf);
+
+       return rc;
 }
 
 static int
@@ -232,6 +408,87 @@ cn10k_dmadev_setup_hdr(union cnxk_dpi_instr_cmd *header, 
const struct rte_dma_vc
        return 0;
 }
 
+static int
+cn20k_dmadev_setup(struct cnxk_dpi_vf_s *dpivf, uint16_t vchan,
+                   const struct rte_dma_vchan_conf *conf)
+{
+       struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       struct cn20k_ring_conf *rconf = dpivf->ring_conf;
+       uint16_t ridx, max_desc, num_rings;
+       union cnxk_dpi_instr_cmd *header;
+       int rc = 0;
+       int aura;
+
+       header = (union cnxk_dpi_instr_cmd *)&dpi_conf->cmd.u;
+       header->cn20k.ct = DPI_HDR_PT_ZBW_CA;
+       header->cn20k.xt = 0;
+
+       switch (conf->direction) {
+       case RTE_DMA_DIR_DEV_TO_MEM:
+               dpi_conf->cfg.xtype = DPI_XTYPE_INBOUND;
+               dpi_conf->cfg.rport = conf->src_port.pcie.coreid;
+               dpi_conf->cfg.wport = 0;
+               dpi_conf->chan_cfg.pf_func = conf->src_port.pcie.pfid;
+               dpi_conf->chan_cfg.vf_func = conf->src_port.pcie.vfid;
+               dpi_conf->chan_cfg.valid = 1;
+               break;
+       case RTE_DMA_DIR_MEM_TO_DEV:
+               dpi_conf->cfg.xtype = DPI_XTYPE_OUTBOUND;
+               dpi_conf->cfg.rport = 0;
+               dpi_conf->cfg.wport = conf->dst_port.pcie.coreid;
+               dpi_conf->chan_cfg.pf_func = conf->dst_port.pcie.pfid;
+               dpi_conf->chan_cfg.vf_func = conf->dst_port.pcie.vfid;
+               dpi_conf->chan_cfg.valid = 1;
+               aura = dmadev_src_buf_aura_get(conf->auto_free.m2d.pool, 
"cn20k_mempool_ops");
+               if (aura < 0)
+                       return aura;
+               header->cn20k.aura = aura;
+               break;
+       case RTE_DMA_DIR_MEM_TO_MEM:
+               dpi_conf->cfg.xtype = DPI_XTYPE_INTERNAL_ONLY;
+               dpi_conf->cfg.rport = 0;
+               dpi_conf->cfg.wport = 0;
+               break;
+       case RTE_DMA_DIR_DEV_TO_DEV:
+               dpi_conf->cfg.xtype = DPI_XTYPE_EXTERNAL_ONLY;
+               dpi_conf->cfg.rport = conf->src_port.pcie.coreid;
+               dpi_conf->cfg.wport = conf->dst_port.pcie.coreid;
+       };
+
+       max_desc = conf->nb_desc;
+       if (!rte_is_power_of_2(max_desc))
+               max_desc = rte_align32pow2(max_desc);
+
+       num_rings = dpivf->rdpi.nr_lfs << 1;
+
+       for (ridx = 0; ridx < num_rings; ridx++) {
+               if (!rconf[ridx].used) {
+                       if (!rconf[ridx].num_vchans) {
+                               rconf[ridx].direction = conf->direction;
+                               rconf[ridx].num_desc = max_desc;
+                       } else if ((rconf[ridx].direction == conf->direction) &&
+                                  (rconf[ridx].num_vchans < 
dpivf->vchans_per_ring)) {
+                               rconf[ridx].num_desc += max_desc;
+                       } else {
+                               continue;
+                       }
+
+                       rconf[ridx].num_vchans++;
+                       dpi_conf->ridx = ridx;
+
+                       if (rconf[ridx].num_vchans == dpivf->vchans_per_ring)
+                               rconf[ridx].used = true;
+
+                       break;
+               }
+       }
+
+       if (ridx == num_rings)
+               rc = -ENODEV;
+
+       return rc;
+}
+
 static int
 cnxk_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
                        const struct rte_dma_vchan_conf *conf, uint32_t conf_sz)
@@ -245,9 +502,14 @@ cnxk_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t 
vchan,
 
        RTE_SET_USED(conf_sz);
 
+       if (conf->auto_free.m2d.pool != NULL && conf->direction != 
RTE_DMA_DIR_MEM_TO_DEV)
+               return -EINVAL;
+
        header = (union cnxk_dpi_instr_cmd *)&dpi_conf->cmd.u;
 
-       if (dpivf->is_cn10k)
+       if (roc_model_is_cn20k())
+               ret = cn20k_dmadev_setup(dpivf, vchan, conf);
+       else if (roc_model_is_cn10k())
                ret = cn10k_dmadev_setup_hdr(header, conf);
        else
                ret = cn9k_dmadev_setup_hdr(header, conf);
@@ -262,7 +524,7 @@ cnxk_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t 
vchan,
        if (!rte_is_power_of_2(max_desc))
                max_desc = rte_align32pow2(max_desc);
 
-       if (max_desc > CNXK_DPI_MAX_DESC)
+       if (!roc_model_is_cn20k() && (max_desc > CNXK_DPI_MAX_DESC))
                max_desc = CNXK_DPI_MAX_DESC;
 
        size = (max_desc * sizeof(uint8_t) * CNXK_DPI_COMPL_OFFSET);
@@ -285,10 +547,121 @@ cnxk_dmadev_vchan_setup(struct rte_dma_dev *dev, 
uint16_t vchan,
                dpi_conf->c_desc.compl_ptr[i * CNXK_DPI_COMPL_OFFSET] = 
CNXK_DPI_REQ_CDATA;
 
        dpi_conf->c_desc.max_cnt = (max_desc - 1);
+       dpi_conf->cfg_done = true;
 
        return 0;
 }
 
+static int
+cn20k_dmadev_queue_setup(struct cnxk_dpi_vf_s *dpivf)
+{
+       struct cn20k_ring_conf *rconf = dpivf->ring_conf;
+       struct roc_dpi *rdpi = &dpivf->rdpi;
+       struct cnxk_dpi_conf *dpi_conf;
+       struct roc_dpi_lf_que *que;
+       struct roc_dpi_lf_ring_cfg cfg;
+       struct roc_dpi_lf *lf;
+       uint16_t idx, qidx, ridx, vchan;
+       int rc = 0;
+
+       for (idx = 0; idx < rdpi->nr_lfs; idx++) {
+               lf = &rdpi->lfs[idx];
+               lf->chan_tbl = dpivf->chan_tbl;
+
+               for (qidx = 0; qidx < 2; qidx++) {
+                       ridx = (idx << 1) + qidx;
+
+                       if (!rconf[ridx].used)
+                               continue;
+
+                       que = &lf->queue[qidx];
+
+                       que->qsize = rconf[ridx].num_desc;
+                       que->cmd_len = DPI_CMD_SIZE_128B;
+                       que->first_skip = 0;
+                       que->later_skip = 0;
+                       memset(&cfg, 0, sizeof(cfg));
+                       cfg.ring_idx = qidx;
+                       cfg.isize = que->cmd_len / DPI_CMD_SIZE_128B;
+                       cfg.xtype = DPI_XTYPE_INTERNAL_ONLY;
+                       cfg.rport = 0; /* Default is PEM:0 */
+                       cfg.wport = 0; /* Default is PEM:0 */
+                       cfg.pri = 0;   /* 0 - High Priority */
+                       for (vchan = 0; vchan < dpivf->num_vchans; vchan++) {
+                               dpi_conf = &dpivf->conf[vchan];
+
+                               if (dpi_conf->ridx == ridx)
+                                       cfg.xtype = dpi_conf->cfg.xtype;
+                       }
+
+                       rc = roc_dpi_lf_ring_init(que, &cfg);
+                       if (rc)
+                               return rc;
+
+                       for (vchan = 0; vchan < dpivf->num_vchans; vchan++) {
+                               dpi_conf = &dpivf->conf[vchan];
+
+                               if (dpi_conf->ridx == ridx) {
+                                       dpi_conf->que = que;
+                                       dpi_conf->dbell = lf->rbase + 
DPI_LF_RINGX_WIDX(qidx);
+                               }
+                       }
+               }
+
+               rc = roc_dpi_lf_chan_tbl_select(lf);
+               if (rc)
+                       return rc;
+
+               /* FIX ME */
+               rc = roc_dpi_lf_pffunc_cfg(lf);
+               if (rc)
+                       return rc;
+       }
+
+       return rc;
+}
+
+static int
+cn20k_dmadev_chan_tbl_setup(struct cnxk_dpi_vf_s *dpivf)
+{
+       uint16_t vchan, idx = 0, offset = 0;
+       struct cnxk_dpi_conf *dpi_conf;
+       uint64_t config[64] = {0};
+       struct roc_dpi_lf *lf;
+       int rc = 0;
+
+       lf = &(dpivf->rdpi.lfs[0]);
+
+       for (vchan = 0; vchan < dpivf->num_vchans; vchan++) {
+               dpi_conf = &dpivf->conf[vchan];
+               if (!dpi_conf->cfg_done || (dpi_conf->cfg.xtype == 
DPI_XTYPE_INTERNAL_ONLY))
+                       continue;
+
+               dpi_conf->cmd.cn20k.chan = idx;
+               config[idx++] = dpi_conf->chan_cfg.u;
+
+               if (idx == 64) {
+                       rc = roc_dpi_lf_chan_tbl_update(lf, config, offset, 
idx);
+                       if (rc < 0) {
+                               plt_err("Failed to update chan tbl = %d", rc);
+                               return rc;
+                       }
+                       offset += idx;
+                       idx = 0;
+               }
+       }
+
+       if (idx) {
+               rc = roc_dpi_lf_chan_tbl_update(lf, config, offset, idx);
+               if (rc < 0) {
+                       plt_err("Failed to update chan tbl = %d", rc);
+                       return rc;
+               }
+       }
+
+       return rc;
+}
+
 static int
 cnxk_dmadev_start(struct rte_dma_dev *dev)
 {
@@ -306,6 +679,10 @@ cnxk_dmadev_start(struct rte_dma_dev *dev)
                dpi_conf->c_desc.head = 0;
                dpi_conf->c_desc.tail = 0;
                dpi_conf->desc_idx = 0;
+
+               if (dpi_conf->c_desc.compl_ptr == NULL)
+                       continue;
+
                for (j = 0; j < dpi_conf->c_desc.max_cnt + 1; j++)
                        dpi_conf->c_desc.compl_ptr[j * CNXK_DPI_COMPL_OFFSET] = 
CNXK_DPI_REQ_CDATA;
                nb_desc += dpi_conf->c_desc.max_cnt + 1;
@@ -313,6 +690,27 @@ cnxk_dmadev_start(struct rte_dma_dev *dev)
                dpi_conf->completed_offset = 0;
        }
 
+       if (roc_model_is_cn20k()) {
+               for (i = 0; i < (dpivf->rdpi.nr_lfs << 1); i++)
+                       dpivf->ring_conf[i].pending = 0;
+               roc_dpi_reset(&dpivf->rdpi);
+
+               if (dpivf->is_ring_conf_done)
+                       goto enable_dpi;
+
+               rc = cn20k_dmadev_queue_setup(dpivf);
+               if (rc)
+                       goto error;
+
+               rc = cn20k_dmadev_chan_tbl_setup(dpivf);
+               if (rc)
+                       goto error;
+
+               dpivf->is_ring_conf_done = true;
+
+               goto enable_dpi;
+       }
+
        queue_buf_sz = CNXK_DPI_QUEUE_BUF_SIZE_V2;
        /* Max block size allowed by cnxk mempool driver is (128 * 1024).
         * Block size = elt_size + mp->header + mp->trailer.
@@ -349,6 +747,7 @@ cnxk_dmadev_start(struct rte_dma_dev *dev)
        dpivf->chunk_head = 0;
        dpivf->chunk_size_m1 = (queue_buf_sz >> 3) - 2;
 
+enable_dpi:
        roc_dpi_enable(&dpivf->rdpi);
 error:
        return rc;
@@ -359,14 +758,18 @@ cnxk_dmadev_stop(struct rte_dma_dev *dev)
 {
        struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
 
-       if (roc_dpi_wait_queue_idle(&dpivf->rdpi))
-               return -EAGAIN;
+       if (!roc_model_is_cn20k()) {
+               if (roc_dpi_wait_queue_idle(&dpivf->rdpi))
+                       return -EAGAIN;
+       }
 
        roc_dpi_disable(&dpivf->rdpi);
-       rte_mempool_free(dpivf->chunk_pool);
-       dpivf->chunk_pool = NULL;
-       dpivf->chunk_base = NULL;
-       dpivf->chunk_size_m1 = 0;
+       if (!roc_model_is_cn20k()) {
+               rte_mempool_free(dpivf->chunk_pool);
+               dpivf->chunk_pool = NULL;
+               dpivf->chunk_base = NULL;
+               dpivf->chunk_size_m1 = 0;
+       }
 
        return 0;
 }
@@ -378,6 +781,10 @@ cnxk_dmadev_close(struct rte_dma_dev *dev)
 
        roc_dpi_disable(&dpivf->rdpi);
        cnxk_dmadev_vchan_free(dpivf, RTE_DMA_ALL_VCHAN);
+
+       if (roc_model_is_cn20k())
+               cnxk_dmadev_vchan_rsrc_free(dpivf);
+
        roc_dpi_dev_fini(&dpivf->rdpi);
 
        /* Clear all flags as we close the device. */
@@ -454,11 +861,17 @@ cnxk_damdev_burst_capacity(const void *dev_private, 
uint16_t vchan)
 {
        const struct cnxk_dpi_vf_s *dpivf = (const struct cnxk_dpi_vf_s 
*)dev_private;
        const struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       struct cn20k_ring_conf *ring_conf;
        uint16_t burst_cap;
 
        burst_cap = dpi_conf->c_desc.max_cnt -
                    (dpi_conf->stats.submitted - dpi_conf->stats.completed) + 1;
 
+       if (roc_model_is_cn20k()) {
+               ring_conf = &dpivf->ring_conf[dpi_conf->ridx];
+               burst_cap -= ring_conf->pending;
+       }
+
        return burst_cap;
 }
 
@@ -480,6 +893,26 @@ cnxk_dmadev_submit(void *dev_private, uint16_t vchan)
        return 0;
 }
 
+static int
+cn20k_dmadev_submit(void *dev_private, uint16_t vchan)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev_private;
+       struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       struct cn20k_ring_conf *ring_conf = &dpivf->ring_conf[dpi_conf->ridx];
+       uint16_t num_words = ring_conf->pending;
+
+       if (!num_words)
+               return 0;
+
+       rte_wmb();
+       plt_write64(num_words, dpi_conf->dbell);
+       dpi_conf->stats.submitted += num_words;
+
+       ring_conf->pending = 0;
+
+       return 0;
+}
+
 static int
 cnxk_stats_get(const struct rte_dma_dev *dev, uint16_t vchan, struct 
rte_dma_stats *rte_stats,
               uint32_t size)
@@ -552,11 +985,16 @@ cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t 
ena_enq_deq)
        dev->fp_obj->submit = cnxk_dmadev_submit;
        dev->fp_obj->completed = cnxk_dmadev_completed;
        dev->fp_obj->completed_status = cnxk_dmadev_completed_status;
-       dev->fp_obj->burst_capacity = cnxk_damdev_burst_capacity;
+               dev->fp_obj->burst_capacity = cnxk_damdev_burst_capacity;
 
        if (roc_model_is_cn10k()) {
                dev->fp_obj->copy = cn10k_dmadev_copy;
                dev->fp_obj->copy_sg = cn10k_dmadev_copy_sg;
+       } else if (roc_model_is_cn20k()) {
+               dev->fp_obj->submit = cn20k_dmadev_submit;
+               dev->fp_obj->copy = cn20k_dmadev_copy;
+               dev->fp_obj->copy_sg = cn20k_dmadev_copy_sg;
+               dev->fp_obj->fill = cn20k_dmadev_fill;
        }
 
        if (ena_enq_deq) {
@@ -571,6 +1009,9 @@ cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t 
ena_enq_deq)
 
                if (roc_model_is_cn10k())
                        dev->fp_obj->enqueue = cn10k_dma_ops_enqueue;
+
+               if (roc_model_is_cn20k())
+                       dev->fp_obj->enqueue = cn20k_dma_ops_enqueue;
        }
 }
 
@@ -594,8 +1035,10 @@ cnxk_dmadev_probe(struct rte_pci_driver *pci_drv 
__rte_unused, struct rte_pci_de
        struct roc_dpi *rdpi = NULL;
        int rc;
 
-       if (!pci_dev->mem_resource[0].addr)
-               return -ENODEV;
+       if (!roc_model_is_cn20k()) {
+               if (!pci_dev->mem_resource[0].addr)
+                       return -ENODEV;
+       }
 
        rc = roc_plt_init();
        if (rc) {
@@ -612,19 +1055,65 @@ cnxk_dmadev_probe(struct rte_pci_driver *pci_drv 
__rte_unused, struct rte_pci_de
        }
 
        dpivf = dmadev->data->dev_private;
+       dmadev->device = &pci_dev->device;
+
+       if (roc_model_is_cn20k()) {
+               /* Parse devargs string */
+               rc = cn20k_dmadev_parse_devargs(dmadev->device->devargs, dpivf);
+               if (rc) {
+                       plt_err("Failed to parse devargs rc=%d", rc);
+                       goto err_out_free;
+               }
+               dpivf->num_vchans = dpivf->max_vchans;
+       }
 
        dmadev->device = &pci_dev->device;
        dmadev->fp_obj->dev_private = dpivf;
        dmadev->dev_ops = &cnxk_dmadev_ops;
 
+       /*
+        * dev_private (and the roc_dpi it holds) lives in shared memory. Only
+        * the primary owns the HW and the per-process pci_dev pointer; a
+        * secondary must not run roc_dpi_dev_init nor overwrite rdpi->pci_dev,
+        * otherwise the primary later dereferences the secondary's stale
+        * pointer during rte_eal_cleanup() and crashes.
+        */
        if (rte_eal_process_type() != RTE_PROC_PRIMARY)
                return 0;
 
-       dpivf->is_cn10k = roc_model_is_cn10k();
+       dmadev->fp_obj->submit = cnxk_dmadev_submit;
+       dmadev->fp_obj->completed = cnxk_dmadev_completed;
+       dmadev->fp_obj->completed_status = cnxk_dmadev_completed_status;
+       dmadev->fp_obj->burst_capacity = cnxk_damdev_burst_capacity;
+
+       if (roc_model_is_cn10k()) {
+               dmadev->fp_obj->copy = cn10k_dmadev_copy;
+               dmadev->fp_obj->copy_sg = cn10k_dmadev_copy_sg;
+               dpivf->num_vchans = CNXK_DPI_MAX_VCHANS_PER_QUEUE;
+       } else if (roc_model_is_cn20k()) {
+               dmadev->fp_obj->submit = cn20k_dmadev_submit;
+               dmadev->fp_obj->copy = cn20k_dmadev_copy;
+               dmadev->fp_obj->copy_sg = cn20k_dmadev_copy_sg;
+               dmadev->fp_obj->fill = cn20k_dmadev_fill;
+       } else {
+               dmadev->fp_obj->copy = cnxk_dmadev_copy;
+               dmadev->fp_obj->copy_sg = cnxk_dmadev_copy_sg;
+               dpivf->num_vchans = CNXK_DPI_MAX_VCHANS_PER_QUEUE;
+       }
+
+       dpivf->conf = rte_zmalloc("dpi_vchan_conf", dpivf->num_vchans *
+                                 sizeof(struct cnxk_dpi_conf), 0);
+       if (dpivf->conf == NULL) {
+               plt_err("Failed to allocate memory for vchan conf");
+               rc = -ENOMEM;
+               goto err_out_free;
+       }
+
        dpivf->mcs_lock = NULL;
        rdpi = &dpivf->rdpi;
 
        rdpi->pci_dev = pci_dev;
+
        rc = roc_dpi_dev_init(rdpi, offsetof(struct rte_dma_op, impl_opaque));
        if (rc < 0)
                goto err_out_free;
@@ -653,6 +1142,8 @@ cnxk_dmadev_remove(struct rte_pci_device *pci_dev)
 
 static const struct rte_pci_id cnxk_dma_pci_map[] = {
        {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_DPI_VF)},
+       {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN20K_DPI_PF)},
+       {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN20K_DPI_VF)},
        {
                .vendor_id = 0,
        },
diff --git a/drivers/dma/cnxk/cnxk_dmadev.h b/drivers/dma/cnxk/cnxk_dmadev.h
index 18039e43fb..3ba404dda8 100644
--- a/drivers/dma/cnxk/cnxk_dmadev.h
+++ b/drivers/dma/cnxk/cnxk_dmadev.h
@@ -9,9 +9,11 @@
 
 #include <bus_pci_driver.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
 #include <rte_dmadev.h>
 #include <rte_dmadev_pmd.h>
 #include <rte_eal.h>
+#include <rte_kvargs.h>
 #include <rte_lcore.h>
 #include <rte_mbuf_pool_ops.h>
 #include <rte_mcslock.h>
@@ -31,15 +33,31 @@
 #define CN10K_DPI_MAX_PRI                  2
 #define CNXK_DPI_MAX_VCHANS_PER_QUEUE      128
 #define CNXK_DPI_QUEUE_BUF_SIZE                    16256
-#define CNXK_DPI_QUEUE_BUF_SIZE_V2         130944
+/* Maximum pool size supported by device is 128 * 1024. When 
RTE_LIBRTE_MEMPOOL_DEBUG is enabled
+ * mempool->trailer size will be increased by 8B. Additionally if the pool is 
not created with
+ * RTE_MEMPOOL_F_NO_CACHE_ALIGN, trailer will be expanded to cache line size.
+ * To allow future needs, limit the max size to 127KB
+ */
+#define CNXK_DPI_QUEUE_BUF_SIZE_V2         130048
 #define CNXK_DPI_POOL_MAX_CACHE_SZ         (16)
 #define CNXK_DPI_DW_PER_SINGLE_CMD         8
 #define CNXK_DPI_HDR_LEN                   4
 #define CNXK_DPI_CMD_LEN(src, dst)         (CNXK_DPI_HDR_LEN + ((src) << 1) + 
((dst) << 1))
-#define CNXK_DPI_MAX_CMD_SZ                
CNXK_DPI_CMD_LEN(CNXK_DPI_MAX_POINTER,              \
+#define CNXK_DPI_MAX_CMD_SZ                
CNXK_DPI_CMD_LEN(CNXK_DPI_MAX_POINTER,              \
                                                             
CNXK_DPI_MAX_POINTER)
 #define CNXK_DPI_CHUNKS_FROM_DESC(cz, desc) (((desc) / (((cz) / 8) / 
CNXK_DPI_MAX_CMD_SZ)) + 1)
 #define CNXK_DPI_COMPL_OFFSET              ROC_CACHE_LINE_SZ
+
+#define CN20K_DPI_MAX_POINTER              4
+#define CN20K_DPI_MAX_DESC                 2048
+#define CN20K_DPI_MIN_DESC                 128
+#define CN20K_DPI_MAX_VCHANS               512
+#define CN20K_DPI_DEF_VCHANS               8
+#define CN20K_DPI_MAX_LFS                  256
+
+#define CN20K_DPI_NUM_VCHANS   "num_vchans"
+#define CN20K_DPI_NUM_LFS      "num_lfs"
+
 /* Set Completion data to 0xFF when request submitted,
  * upon successful request completion engine reset to completion status
  */
@@ -86,6 +104,32 @@ union cnxk_dpi_instr_cmd {
                uint64_t reserved_62_63 : 2;
                /* Word 0 - End */
        } cn10k;
+
+       struct cn20k_dpi_instr_cmd {
+               uint64_t nfst : 3;
+               uint64_t reserved_3 : 1;
+               uint64_t nlst : 3;
+               uint64_t reserved_7 : 1;
+               uint64_t msix_int : 1;
+               uint64_t ct : 3;
+               uint64_t chan : 14;
+               uint64_t reserved_26_29 : 4;
+               uint64_t aura : 20;
+               uint64_t xt : 2;
+               uint64_t ivec : 9;
+               uint64_t fe : 1;
+               uint64_t reserved_62 : 1;
+               uint64_t vld : 1;
+               /* Word 0 - End */
+       } cn20k;
+};
+
+struct cn20k_ring_conf {
+       enum rte_dma_direction direction;
+       uint16_t pending;
+       uint16_t num_desc;
+       uint8_t num_vchans;
+       bool used;
 };
 
 struct cnxk_dpi_cdesc_data_s {
@@ -100,9 +144,15 @@ struct cnxk_dpi_conf {
        union cnxk_dpi_instr_cmd cmd;
        struct cnxk_dpi_cdesc_data_s c_desc;
        uint16_t desc_idx;
+       uintptr_t dbell;
        struct rte_dma_stats stats;
        uint64_t completed_offset;
+       struct roc_dpi_lf_que *que;
+       union roc_dpi_lf_ccfg chan_cfg;
+       struct roc_dpi_lf_ring_cfg cfg;
+       uint16_t ridx;
        bool adapter_enabled;
+       bool cfg_done;
 };
 
 struct cnxk_dpi_vf_s {
@@ -111,15 +161,21 @@ struct cnxk_dpi_vf_s {
        uint16_t chunk_head;
        uint16_t chunk_size_m1;
        uint16_t total_pnum_words;
+       uint16_t vchans_per_ring;
        struct rte_mempool *chunk_pool;
-       struct cnxk_dpi_conf conf[CNXK_DPI_MAX_VCHANS_PER_QUEUE];
+       struct cnxk_dpi_conf *conf;
+       struct cn20k_ring_conf *ring_conf;
        RTE_ATOMIC(rte_mcslock_t *) mcs_lock;
        /* Slow path */
        struct roc_dpi rdpi;
        uint32_t aura;
+       uint16_t max_lfs;
+       uint16_t max_vchans;
        uint16_t num_vchans;
+       uint16_t chan_tbl;
        uint16_t flag;
        uint8_t is_cn10k;
+       uint8_t is_ring_conf_done;
 } __plt_cache_aligned;
 
 int cnxk_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, 
rte_iova_t dst,
@@ -138,5 +194,13 @@ uint16_t cn10k_dma_ops_enqueue(void *dev_private, uint16_t 
vchan, struct rte_dma
                               uint16_t nb_ops);
 uint16_t cnxk_dma_ops_dequeue(void *dev_private, uint16_t vchan, struct 
rte_dma_op **ops,
                              uint16_t nb_ops);
-
+int cn20k_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, 
rte_iova_t dst,
+                     uint32_t length, uint64_t flags);
+int cn20k_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct 
rte_dma_sge *src,
+                        const struct rte_dma_sge *dst, uint16_t nb_src, 
uint16_t nb_dst,
+                        uint64_t flags);
+int cn20k_dmadev_fill(void *dev_private, uint16_t vchan, uint64_t pattern, 
rte_iova_t dst,
+                     uint32_t length, uint64_t flags);
+uint16_t cn20k_dma_ops_enqueue(void *dev_private, uint16_t vchan, struct 
rte_dma_op **ops,
+                              uint16_t nb_ops);
 #endif
diff --git a/drivers/dma/cnxk/cnxk_dmadev_fp.c 
b/drivers/dma/cnxk/cnxk_dmadev_fp.c
index 4435adc38b..29ce13c8e4 100644
--- a/drivers/dma/cnxk/cnxk_dmadev_fp.c
+++ b/drivers/dma/cnxk/cnxk_dmadev_fp.c
@@ -440,6 +440,163 @@ cn10k_dmadev_copy_sg(void *dev_private, uint16_t vchan, 
const struct rte_dma_sge
        return dpi_conf->desc_idx++;
 }
 
+int
+cn20k_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src, 
rte_iova_t dst,
+                 uint32_t length, uint64_t flags)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev_private;
+       struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
+       struct roc_dpi_lf_que *queue = dpi_conf->que;
+       struct cn20k_ring_conf *ring_conf;
+       uint8_t *comp_ptr;
+       uint64_t *cmd;
+
+       if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == 
(dpi_conf->c_desc.head & max_cnt)))
+               return -ENOSPC;
+
+       if (dpivf->vchans_per_ring == 1) {
+               cmd = queue->cmd_base + ((dpi_conf->c_desc.tail & max_cnt) << 
4);
+       } else {
+               cmd = queue->cmd_base + (queue->widx << 4);
+               queue->widx = (queue->widx + 1) & (queue->qsize - 1);
+       }
+
+       ring_conf = &(dpivf->ring_conf[dpi_conf->ridx]);
+       comp_ptr = &dpi_conf->c_desc
+                           .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * 
CNXK_DPI_COMPL_OFFSET];
+       dpi_conf->c_desc.tail++;
+
+       cmd[1] = (uint64_t)comp_ptr;
+       cmd[4] = ((uint64_t)length << 32) | length | ((flags & 
RTE_DMA_OP_FLAG_AUTO_FREE) << 28);
+       cmd[5] = src;
+       cmd[6] = dst;
+       cmd[0] = DPI_CMD_VLD_BIT | dpi_conf->cmd.u | 0x11U;
+
+       if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
+               rte_wmb();
+               plt_write64(ring_conf->pending + 1, dpi_conf->dbell);
+               dpi_conf->stats.submitted += (ring_conf->pending + 1);
+               ring_conf->pending = 0;
+       } else {
+               ring_conf->pending++;
+       }
+
+       return dpi_conf->desc_idx++;
+}
+
+/* Helper macro to write length and address */
+#define DPI_WRITE_SEGMENT(ptr, seg, i, idx, eidx, tmp)                         
                    \
+       do {                                                                    
                   \
+               if ((tmp) % 2 == 0) {                                           
                   \
+                       ptr[eidx] = seg[i].length;                              
                   \
+                       idx++;                                                  
                   \
+               } else {                                                        
                   \
+                       ptr[eidx] |= ((uint64_t)seg[i].length << 32);           
                   \
+                       eidx += 3;                                              
                   \
+               }                                                               
                   \
+               ptr[idx++] = (uint64_t)seg[i].addr;                             
                   \
+               tmp++;                                                          
                   \
+       } while (0)
+
+int
+cn20k_dmadev_copy_sg(void *dev_private, uint16_t vchan, const struct 
rte_dma_sge *src,
+                    const struct rte_dma_sge *dst, uint16_t nb_src, uint16_t 
nb_dst,
+                    uint64_t flags)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev_private;
+       struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
+       struct roc_dpi_lf_que *queue = dpi_conf->que;
+       struct cn20k_ring_conf *ring_conf = &dpivf->ring_conf[dpi_conf->ridx];
+       uint16_t idx = 4, eidx = 4, tmp = 0;
+       uint8_t *comp_ptr, i;
+       uint64_t *cmd;
+
+       if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == 
(dpi_conf->c_desc.head & max_cnt)))
+               return -ENOSPC;
+
+       if (dpivf->vchans_per_ring == 1) {
+               cmd = queue->cmd_base + ((dpi_conf->c_desc.tail & max_cnt) << 
4);
+       } else {
+               cmd = queue->cmd_base + (queue->widx << 4);
+               queue->widx = (queue->widx + 1) & (queue->qsize - 1);
+       }
+       comp_ptr = &dpi_conf->c_desc
+                           .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * 
CNXK_DPI_COMPL_OFFSET];
+       dpi_conf->c_desc.tail++;
+
+       cmd[1] = (uint64_t)comp_ptr;
+
+       /* Fill source segments */
+       for (i = 0; i < nb_src; i++)
+               DPI_WRITE_SEGMENT(cmd, src, i, idx, eidx, tmp);
+
+       /* Fill destination segments */
+       for (i = 0; i < nb_dst; i++)
+               DPI_WRITE_SEGMENT(cmd, dst, i, idx, eidx, tmp);
+
+       cmd[0] = DPI_CMD_VLD_BIT | dpi_conf->cmd.u | (nb_dst << 4) | nb_src;
+
+       if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
+               rte_wmb();
+               plt_write64(ring_conf->pending + 1, dpi_conf->dbell);
+               dpi_conf->stats.submitted += ring_conf->pending + 1;
+               ring_conf->pending = 0;
+       } else {
+               ring_conf->pending++;
+       }
+
+       return dpi_conf->desc_idx++;
+}
+
+int
+cn20k_dmadev_fill(void *dev_private, uint16_t vchan, uint64_t pattern, 
rte_iova_t dst,
+                 uint32_t length, uint64_t flags)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev_private;
+       struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
+       struct roc_dpi_lf_que *queue = dpi_conf->que;
+       struct cn20k_ring_conf *ring_conf;
+       uint8_t *comp_ptr;
+       uint64_t *cmd;
+
+#define DPI_XT_TYPE_FILL BIT_ULL(50)
+
+       if (unlikely(((dpi_conf->c_desc.tail + 1) & max_cnt) == 
(dpi_conf->c_desc.head & max_cnt)))
+               return -ENOSPC;
+
+       if (dpivf->vchans_per_ring == 1) {
+               cmd = queue->cmd_base + ((dpi_conf->c_desc.tail & max_cnt) << 
4);
+       } else {
+               cmd = queue->cmd_base + (queue->widx << 4);
+               queue->widx = (queue->widx + 1) & (queue->qsize - 1);
+       }
+
+       ring_conf = &(dpivf->ring_conf[dpi_conf->ridx]);
+       comp_ptr = &dpi_conf->c_desc
+                           .compl_ptr[(dpi_conf->c_desc.tail & max_cnt) * 
CNXK_DPI_COMPL_OFFSET];
+       dpi_conf->c_desc.tail++;
+
+       cmd[1] = (uint64_t)comp_ptr;
+       cmd[4] = (uint64_t)length << 32;
+       cmd[5] = pattern;
+       cmd[6] = dst;
+       cmd[0] = DPI_CMD_VLD_BIT | DPI_XT_TYPE_FILL | dpi_conf->cmd.u | 0x10U;
+
+       if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
+               rte_wmb();
+               plt_write64(ring_conf->pending + 1, dpi_conf->dbell);
+               dpi_conf->stats.submitted += (ring_conf->pending + 1);
+               ring_conf->pending = 0;
+       } else {
+               ring_conf->pending++;
+       }
+
+       return dpi_conf->desc_idx++;
+}
+
 static inline uint64_t
 cnxk_dma_adapter_format_event(uint64_t event)
 {
@@ -450,6 +607,63 @@ cnxk_dma_adapter_format_event(uint64_t event)
        return w0;
 }
 
+uint16_t
+cn20k_dma_ops_enqueue(void *dev_private, uint16_t vchan, struct rte_dma_op 
**ops, uint16_t nb_ops)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev_private;
+       struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
+       const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
+       struct roc_dpi_lf_que *queue = dpi_conf->que;
+       uint16_t idx, eidx, tmp;
+       struct rte_dma_op *op;
+       uint16_t space, i, j;
+       uint16_t src, dst;
+       uint8_t *comp_ptr;
+       uint64_t *cmd;
+
+       space = (max_cnt + dpi_conf->c_desc.head - dpi_conf->c_desc.tail) & 
max_cnt;
+       space = RTE_MIN(space, nb_ops);
+
+       for (j = 0; j < space; j++) {
+               op = ops[j];
+               src = op->nb_src;
+               dst = op->nb_dst;
+
+               idx = 4; eidx = 4; tmp = 0;
+
+               if (dpivf->vchans_per_ring == 1) {
+                       cmd = queue->cmd_base + ((dpi_conf->c_desc.tail & 
max_cnt) << 4);
+               } else {
+                       cmd = queue->cmd_base + (queue->widx << 4);
+                       queue->widx = (queue->widx + 1) & (queue->qsize - 1);
+               }
+               comp_ptr = &dpi_conf->c_desc.compl_ptr[(dpi_conf->c_desc.tail & 
max_cnt) *
+                                                      CNXK_DPI_COMPL_OFFSET];
+               dpi_conf->c_desc.ops[dpi_conf->c_desc.tail & max_cnt] = op;
+               dpi_conf->c_desc.tail++;
+
+               cmd[1] = (uint64_t)comp_ptr;
+
+               /* Fill source segments */
+               for (i = 0; i < src; i++)
+                       DPI_WRITE_SEGMENT(cmd, op->src_dst_seg, i, idx, eidx, 
tmp);
+
+               /* Fill destination segments */
+               for (i = 0; i < dst; i++)
+                       DPI_WRITE_SEGMENT(cmd, (op->src_dst_seg + src), i, idx, 
eidx, tmp);
+
+               cmd[0] = DPI_CMD_VLD_BIT | dpi_conf->cmd.u | (dst << 4) | src;
+       }
+
+       if (space) {
+               rte_wmb();
+               plt_write64(space, dpi_conf->dbell);
+               dpi_conf->stats.submitted += space;
+       }
+
+       return j;
+}
+
 RTE_EXPORT_INTERNAL_SYMBOL(cn10k_dma_adapter_enqueue)
 uint16_t
 cn10k_dma_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
-- 
2.34.1

Reply via email to