net/mlx5: fix multi-segment packet wraparound
[dpdk.git] / drivers / dma / cnxk / cnxk_dmadev.c
index ef1c1c6..2824c1b 100644 (file)
@@ -29,7 +29,8 @@ cnxk_dmadev_info_get(const struct rte_dma_dev *dev,
        dev_info->nb_vchans = 1;
        dev_info->dev_capa = RTE_DMA_CAPA_MEM_TO_MEM |
                RTE_DMA_CAPA_MEM_TO_DEV | RTE_DMA_CAPA_DEV_TO_MEM |
-               RTE_DMA_CAPA_DEV_TO_DEV | RTE_DMA_CAPA_OPS_COPY;
+               RTE_DMA_CAPA_DEV_TO_DEV | RTE_DMA_CAPA_OPS_COPY |
+               RTE_DMA_CAPA_OPS_COPY_SG;
        dev_info->max_desc = DPI_MAX_DESC;
        dev_info->min_desc = 1;
        dev_info->max_sges = DPI_MAX_POINTER;
@@ -270,6 +271,73 @@ cnxk_dmadev_copy(void *dev_private, uint16_t vchan, rte_iova_t src,
                        rte_wmb();
                        plt_write64(num_words,
                                    dpivf->rdpi.rbase + DPI_VDMA_DBELL);
+                       dpivf->stats.submitted++;
+               }
+               dpivf->num_words += num_words;
+       }
+
+       return dpivf->desc_idx++;
+}
+
+static int
+cnxk_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;
+       union dpi_instr_hdr_s *header = &dpivf->conf.hdr;
+       const struct rte_dma_sge *fptr, *lptr;
+       struct cnxk_dpi_compl_s *comp_ptr;
+       int num_words = 0;
+       int i, rc;
+
+       RTE_SET_USED(vchan);
+
+       comp_ptr = dpivf->conf.c_desc.compl_ptr[dpivf->conf.c_desc.tail];
+       comp_ptr->cdata = DPI_REQ_CDATA;
+       header->s.ptr = (uint64_t)comp_ptr;
+       STRM_INC(dpivf->conf.c_desc);
+
+       /*
+        * For inbound case, src pointers are last pointers.
+        * For all other cases, src pointers are first pointers.
+        */
+       if (header->s.xtype == DPI_XTYPE_INBOUND) {
+               header->s.nfst = nb_dst & 0xf;
+               header->s.nlst = nb_src & 0xf;
+               fptr = &dst[0];
+               lptr = &src[0];
+       } else {
+               header->s.nfst = nb_src & 0xf;
+               header->s.nlst = nb_dst & 0xf;
+               fptr = &src[0];
+               lptr = &dst[0];
+       }
+
+       dpivf->cmd[0] = header->u[0];
+       dpivf->cmd[1] = header->u[1];
+       dpivf->cmd[2] = header->u[2];
+       num_words += 4;
+       for (i = 0; i < header->s.nfst; i++) {
+               dpivf->cmd[num_words++] = (uint64_t)fptr->length;
+               dpivf->cmd[num_words++] = fptr->addr;
+               fptr++;
+       }
+
+       for (i = 0; i < header->s.nlst; i++) {
+               dpivf->cmd[num_words++] = (uint64_t)lptr->length;
+               dpivf->cmd[num_words++] = lptr->addr;
+               lptr++;
+       }
+
+       rc = __dpi_queue_write(&dpivf->rdpi, dpivf->cmd, num_words);
+       if (!rc) {
+               if (flags & RTE_DMA_OP_FLAG_SUBMIT) {
+                       rte_wmb();
+                       plt_write64(num_words,
+                                   dpivf->rdpi.rbase + DPI_VDMA_DBELL);
+                       dpivf->stats.submitted += nb_src;
                }
                dpivf->num_words += num_words;
        }
@@ -291,12 +359,14 @@ cnxk_dmadev_completed(void *dev_private, uint16_t vchan, const uint16_t nb_cpls,
 
                if (comp_ptr->cdata) {
                        *has_error = 1;
+                       dpivf->stats.errors++;
                        break;
                }
        }
 
        *last_idx = cnt - 1;
        dpivf->conf.c_desc.tail = cnt;
+       dpivf->stats.completed += cnt;
 
        return cnt;
 }
@@ -315,10 +385,13 @@ cnxk_dmadev_completed_status(void *dev_private, uint16_t vchan,
                struct cnxk_dpi_compl_s *comp_ptr =
                        dpivf->conf.c_desc.compl_ptr[cnt];
                status[cnt] = comp_ptr->cdata;
+               if (comp_ptr->cdata)
+                       dpivf->stats.errors++;
        }
 
        *last_idx = cnt - 1;
        dpivf->conf.c_desc.tail = 0;
+       dpivf->stats.completed += cnt;
 
        return cnt;
 }
@@ -330,7 +403,35 @@ cnxk_dmadev_submit(void *dev_private, uint16_t vchan __rte_unused)
 
        rte_wmb();
        plt_write64(dpivf->num_words, dpivf->rdpi.rbase + DPI_VDMA_DBELL);
+       dpivf->stats.submitted++;
+
+       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)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
+       struct rte_dma_stats *stats = &dpivf->stats;
+
+       RTE_SET_USED(vchan);
+
+       if (size < sizeof(rte_stats))
+               return -EINVAL;
+       if (rte_stats == NULL)
+               return -EINVAL;
+
+       *rte_stats = *stats;
+       return 0;
+}
+
+static int
+cnxk_stats_reset(struct rte_dma_dev *dev, uint16_t vchan __rte_unused)
+{
+       struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
 
+       dpivf->stats = (struct rte_dma_stats){0};
        return 0;
 }
 
@@ -340,6 +441,8 @@ static const struct rte_dma_dev_ops cnxk_dmadev_ops = {
        .dev_info_get = cnxk_dmadev_info_get,
        .dev_start = cnxk_dmadev_start,
        .dev_stop = cnxk_dmadev_stop,
+       .stats_get = cnxk_stats_get,
+       .stats_reset = cnxk_stats_reset,
        .vchan_setup = cnxk_dmadev_vchan_setup,
 };
 
@@ -378,6 +481,7 @@ cnxk_dmadev_probe(struct rte_pci_driver *pci_drv __rte_unused,
        dmadev->dev_ops = &cnxk_dmadev_ops;
 
        dmadev->fp_obj->copy = cnxk_dmadev_copy;
+       dmadev->fp_obj->copy_sg = cnxk_dmadev_copy_sg;
        dmadev->fp_obj->submit = cnxk_dmadev_submit;
        dmadev->fp_obj->completed = cnxk_dmadev_completed;
        dmadev->fp_obj->completed_status = cnxk_dmadev_completed_status;