From: Jun Yang <jun.y...@nxp.com> Support copy_sg operation for scatter gather.
Signed-off-by: Jun Yang <jun.y...@nxp.com> Signed-off-by: Gagandeep Singh <g.si...@nxp.com> --- drivers/dma/dpaa/dpaa_qdma.c | 55 ++++++++++++++++++++++++++++++++++++ drivers/dma/dpaa/dpaa_qdma.h | 10 ++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/dma/dpaa/dpaa_qdma.c b/drivers/dma/dpaa/dpaa_qdma.c index b2e96432fb..7c199b6dd0 100644 --- a/drivers/dma/dpaa/dpaa_qdma.c +++ b/drivers/dma/dpaa/dpaa_qdma.c @@ -1021,6 +1021,60 @@ dpaa_qdma_enqueue(void *dev_private, uint16_t vchan, return ret; } +static int +dpaa_qdma_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 ret; + uint16_t i, start, idx; + struct fsl_qdma_engine *fsl_qdma = dev_private; + struct fsl_qdma_queue *fsl_queue = fsl_qdma->chan[vchan]; + const uint16_t *idx_addr = NULL; + + if (unlikely(nb_src != nb_dst)) { + DPAA_QDMA_ERR("%s: nb_src(%d) != nb_dst(%d) on queue%d", + __func__, nb_src, nb_dst, vchan); + return -EINVAL; + } + + if ((fsl_queue->pending_num + nb_src) > FSL_QDMA_SG_MAX_ENTRY) { + DPAA_QDMA_ERR("Too many pending jobs on queue%d", + vchan); + return -ENOSPC; + } + start = fsl_queue->pending_start + fsl_queue->pending_num; + start = start & (fsl_queue->pending_max - 1); + idx = start; + + idx_addr = DPAA_QDMA_IDXADDR_FROM_SG_FLAG(flags); + + for (i = 0; i < nb_src; i++) { + if (unlikely(src[i].length != dst[i].length)) { + DPAA_QDMA_ERR("src.len(%d) != dst.len(%d)", + src[i].length, dst[i].length); + return -EINVAL; + } + idx = (start + i) & (fsl_queue->pending_max - 1); + fsl_queue->pending_desc[idx].src = src[i].addr; + fsl_queue->pending_desc[idx].dst = dst[i].addr; + fsl_queue->pending_desc[idx].len = dst[i].length; + fsl_queue->pending_desc[idx].flag = idx_addr[i]; + } + fsl_queue->pending_num += nb_src; + + if (!(flags & RTE_DMA_OP_FLAG_SUBMIT)) + return idx; + + ret = fsl_qdma_enqueue_desc(fsl_queue); + if (!ret) + return fsl_queue->pending_start; + + return ret; +} static uint16_t dpaa_qdma_dequeue_status(void *dev_private, uint16_t vchan, @@ -1235,6 +1289,7 @@ dpaa_qdma_probe(__rte_unused struct rte_dpaa_driver *dpaa_drv, dmadev->device = &dpaa_dev->device; dmadev->fp_obj->dev_private = dmadev->data->dev_private; dmadev->fp_obj->copy = dpaa_qdma_enqueue; + dmadev->fp_obj->copy_sg = dpaa_qdma_copy_sg; dmadev->fp_obj->submit = dpaa_qdma_submit; dmadev->fp_obj->completed = dpaa_qdma_dequeue; dmadev->fp_obj->completed_status = dpaa_qdma_dequeue_status; diff --git a/drivers/dma/dpaa/dpaa_qdma.h b/drivers/dma/dpaa/dpaa_qdma.h index 171c093117..1e820d0207 100644 --- a/drivers/dma/dpaa/dpaa_qdma.h +++ b/drivers/dma/dpaa/dpaa_qdma.h @@ -24,8 +24,13 @@ #define QDMA_STATUS_REGION_OFFSET \ (QDMA_CTRL_REGION_OFFSET + QDMA_CTRL_REGION_SIZE) #define QDMA_STATUS_REGION_SIZE 0x10000 -#define DPAA_QDMA_COPY_IDX_OFFSET 8 + #define DPAA_QDMA_FLAGS_INDEX RTE_BIT64(63) +#define DPAA_QDMA_COPY_IDX_OFFSET 8 +#define DPAA_QDMA_SG_IDX_ADDR_ALIGN \ + RTE_BIT64(DPAA_QDMA_COPY_IDX_OFFSET) +#define DPAA_QDMA_SG_IDX_ADDR_MASK \ + (DPAA_QDMA_SG_IDX_ADDR_ALIGN - 1) #define FSL_QDMA_DMR 0x0 #define FSL_QDMA_DSR 0x4 @@ -194,6 +199,9 @@ struct fsl_qdma_cmpd_ft { uint64_t phy_df; } __rte_packed; +#define DPAA_QDMA_IDXADDR_FROM_SG_FLAG(flag) \ + ((void *)(uintptr_t)((flag) - ((flag) & DPAA_QDMA_SG_IDX_ADDR_MASK))) + #define DPAA_QDMA_IDX_FROM_FLAG(flag) \ ((flag) >> DPAA_QDMA_COPY_IDX_OFFSET) -- 2.25.1