LCOV - code coverage report
Current view: top level - drivers/dma/cnxk - cnxk_dmadev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 1 315 0.3 %
Date: 2025-11-01 17:50:34 Functions: 1 20 5.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 124 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (C) 2021 Marvell International Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_event_dma_adapter.h>
       6                 :            : 
       7                 :            : #include <cnxk_dmadev.h>
       8                 :            : 
       9                 :            : static int cnxk_stats_reset(struct rte_dma_dev *dev, uint16_t vchan);
      10                 :            : static void cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t enable_enq_deq);
      11                 :            : 
      12                 :            : static int
      13                 :          0 : cnxk_dmadev_info_get(const struct rte_dma_dev *dev, struct rte_dma_info *dev_info, uint32_t size)
      14                 :            : {
      15                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
      16                 :            :         RTE_SET_USED(size);
      17                 :            : 
      18                 :          0 :         dev_info->max_vchans = CNXK_DPI_MAX_VCHANS_PER_QUEUE;
      19                 :          0 :         dev_info->nb_vchans = dpivf->num_vchans;
      20         [ #  # ]:          0 :         dev_info->dev_capa = RTE_DMA_CAPA_MEM_TO_MEM | RTE_DMA_CAPA_MEM_TO_DEV |
      21                 :            :                              RTE_DMA_CAPA_DEV_TO_MEM | RTE_DMA_CAPA_DEV_TO_DEV |
      22                 :            :                              RTE_DMA_CAPA_OPS_COPY | RTE_DMA_CAPA_OPS_COPY_SG |
      23                 :            :                              RTE_DMA_CAPA_M2D_AUTO_FREE | RTE_DMA_CAPA_OPS_ENQ_DEQ;
      24         [ #  # ]:          0 :         if (roc_feature_dpi_has_priority()) {
      25                 :          0 :                 dev_info->dev_capa |= RTE_DMA_CAPA_PRI_POLICY_SP;
      26                 :          0 :                 dev_info->nb_priorities = CN10K_DPI_MAX_PRI;
      27                 :            :         }
      28                 :          0 :         dev_info->max_desc = CNXK_DPI_MAX_DESC;
      29                 :          0 :         dev_info->min_desc = CNXK_DPI_MIN_DESC;
      30                 :          0 :         dev_info->max_sges = CNXK_DPI_MAX_POINTER;
      31                 :            : 
      32                 :          0 :         return 0;
      33                 :            : }
      34                 :            : 
      35                 :            : static int
      36                 :          0 : cnxk_dmadev_vchan_free(struct cnxk_dpi_vf_s *dpivf, uint16_t vchan)
      37                 :            : {
      38                 :            :         struct cnxk_dpi_conf *dpi_conf;
      39                 :            :         uint16_t num_vchans;
      40                 :            :         int i;
      41                 :            : 
      42         [ #  # ]:          0 :         if (vchan == RTE_DMA_ALL_VCHAN) {
      43                 :          0 :                 num_vchans = dpivf->num_vchans;
      44                 :            :                 i = 0;
      45                 :            :         } else {
      46         [ #  # ]:          0 :                 if (vchan >= CNXK_DPI_MAX_VCHANS_PER_QUEUE)
      47                 :            :                         return -EINVAL;
      48                 :            : 
      49                 :          0 :                 num_vchans = vchan + 1;
      50                 :          0 :                 i = vchan;
      51                 :            :         }
      52                 :            : 
      53   [ #  #  #  #  :          0 :         for (; i < num_vchans; i++) {
                   #  # ]
      54                 :            :                 dpi_conf = &dpivf->conf[i];
      55                 :          0 :                 rte_free(dpi_conf->c_desc.compl_ptr);
      56                 :          0 :                 dpi_conf->c_desc.compl_ptr = NULL;
      57                 :            :         }
      58                 :            : 
      59                 :            :         return 0;
      60                 :            : }
      61                 :            : 
      62                 :            : static int
      63                 :          0 : cnxk_dmadev_chunk_pool_create(struct rte_dma_dev *dev, uint32_t nb_chunks, uint32_t chunk_sz)
      64                 :            : {
      65                 :            :         char pool_name[RTE_MEMPOOL_NAMESIZE];
      66                 :            :         struct cnxk_dpi_vf_s *dpivf = NULL;
      67                 :            :         int rc;
      68                 :            : 
      69                 :          0 :         dpivf = dev->fp_obj->dev_private;
      70                 :            :         /* Create chunk pool. */
      71                 :          0 :         snprintf(pool_name, sizeof(pool_name), "cnxk_dma_chunk_pool%d", dev->data->dev_id);
      72                 :            : 
      73                 :          0 :         nb_chunks += (CNXK_DPI_POOL_MAX_CACHE_SZ * rte_lcore_count());
      74                 :          0 :         dpivf->chunk_pool = rte_mempool_create_empty(
      75                 :          0 :                 pool_name, nb_chunks, chunk_sz, CNXK_DPI_POOL_MAX_CACHE_SZ, 0, rte_socket_id(), 0);
      76                 :            : 
      77         [ #  # ]:          0 :         if (dpivf->chunk_pool == NULL) {
      78                 :          0 :                 plt_err("Unable to create chunkpool.");
      79                 :          0 :                 return -ENOMEM;
      80                 :            :         }
      81                 :            : 
      82                 :          0 :         rc = rte_mempool_set_ops_byname(dpivf->chunk_pool, rte_mbuf_platform_mempool_ops(), NULL);
      83         [ #  # ]:          0 :         if (rc < 0) {
      84                 :          0 :                 plt_err("Unable to set chunkpool ops");
      85                 :          0 :                 goto free;
      86                 :            :         }
      87                 :            : 
      88                 :          0 :         rc = rte_mempool_populate_default(dpivf->chunk_pool);
      89         [ #  # ]:          0 :         if (rc < 0) {
      90                 :          0 :                 plt_err("Unable to set populate chunkpool.");
      91                 :          0 :                 goto free;
      92                 :            :         }
      93                 :          0 :         dpivf->aura = roc_npa_aura_handle_to_aura(dpivf->chunk_pool->pool_id);
      94                 :            : 
      95                 :          0 :         return 0;
      96                 :            : 
      97                 :          0 : free:
      98                 :          0 :         rte_mempool_free(dpivf->chunk_pool);
      99                 :          0 :         return rc;
     100                 :            : }
     101                 :            : 
     102                 :            : static int
     103                 :          0 : cnxk_dmadev_configure(struct rte_dma_dev *dev, const struct rte_dma_conf *conf, uint32_t conf_sz)
     104                 :            : {
     105                 :            :         struct cnxk_dpi_vf_s *dpivf = NULL;
     106                 :            : 
     107                 :            :         RTE_SET_USED(conf_sz);
     108                 :          0 :         dpivf = dev->fp_obj->dev_private;
     109                 :            : 
     110                 :            :         /* After config function, vchan setup function has to be called.
     111                 :            :          * Free up vchan memory if any, before configuring num_vchans.
     112                 :            :          */
     113                 :            :         cnxk_dmadev_vchan_free(dpivf, RTE_DMA_ALL_VCHAN);
     114         [ #  # ]:          0 :         dpivf->num_vchans = conf->nb_vchans;
     115         [ #  # ]:          0 :         if (roc_feature_dpi_has_priority())
     116                 :          0 :                 dpivf->rdpi.priority = conf->priority;
     117                 :            : 
     118                 :          0 :         cnxk_set_fp_ops(dev, conf->flags & RTE_DMA_CFG_FLAG_ENQ_DEQ);
     119                 :            : 
     120                 :          0 :         return 0;
     121                 :            : }
     122                 :            : 
     123                 :            : static int
     124                 :            : dmadev_src_buf_aura_get(struct rte_mempool *sb_mp, const char *mp_ops_name)
     125                 :            : {
     126                 :            :         struct rte_mempool_ops *ops;
     127                 :            : 
     128                 :          0 :         if (sb_mp == NULL)
     129                 :            :                 return 0;
     130                 :            : 
     131                 :          0 :         ops = rte_mempool_get_ops(sb_mp->ops_index);
     132   [ #  #  #  # ]:          0 :         if (strcmp(ops->name, mp_ops_name) != 0)
     133                 :            :                 return -EINVAL;
     134                 :            : 
     135                 :          0 :         return roc_npa_aura_handle_to_aura(sb_mp->pool_id);
     136                 :            : }
     137                 :            : 
     138                 :            : static int
     139                 :          0 : cn9k_dmadev_setup_hdr(union cnxk_dpi_instr_cmd *header, const struct rte_dma_vchan_conf *conf)
     140                 :            : {
     141                 :            :         int aura;
     142                 :            : 
     143                 :          0 :         header->cn9k.pt = DPI_HDR_PT_ZBW_CA;
     144                 :            : 
     145   [ #  #  #  #  :          0 :         switch (conf->direction) {
                      # ]
     146                 :          0 :         case RTE_DMA_DIR_DEV_TO_MEM:
     147                 :          0 :                 header->cn9k.xtype = DPI_XTYPE_INBOUND;
     148                 :          0 :                 header->cn9k.lport = conf->src_port.pcie.coreid;
     149                 :          0 :                 header->cn9k.fport = 0;
     150                 :          0 :                 header->cn9k.pvfe = conf->src_port.pcie.vfen;
     151         [ #  # ]:          0 :                 if (header->cn9k.pvfe) {
     152                 :          0 :                         header->cn9k.func = conf->src_port.pcie.pfid << 12;
     153                 :          0 :                         header->cn9k.func |= conf->src_port.pcie.vfid;
     154                 :            :                 }
     155                 :            :                 break;
     156                 :          0 :         case RTE_DMA_DIR_MEM_TO_DEV:
     157                 :          0 :                 header->cn9k.xtype = DPI_XTYPE_OUTBOUND;
     158                 :          0 :                 header->cn9k.lport = 0;
     159                 :          0 :                 header->cn9k.fport = conf->dst_port.pcie.coreid;
     160                 :          0 :                 header->cn9k.pvfe = conf->dst_port.pcie.vfen;
     161         [ #  # ]:          0 :                 if (header->cn9k.pvfe) {
     162                 :          0 :                         header->cn9k.func = conf->dst_port.pcie.pfid << 12;
     163                 :          0 :                         header->cn9k.func |= conf->dst_port.pcie.vfid;
     164                 :            :                 }
     165         [ #  # ]:          0 :                 aura = dmadev_src_buf_aura_get(conf->auto_free.m2d.pool, "cn9k_mempool_ops");
     166                 :            :                 if (aura < 0)
     167                 :          0 :                         return aura;
     168                 :          0 :                 header->cn9k.aura = aura;
     169                 :          0 :                 header->cn9k.ii = 1;
     170                 :          0 :                 break;
     171                 :          0 :         case RTE_DMA_DIR_MEM_TO_MEM:
     172                 :          0 :                 header->cn9k.xtype = DPI_XTYPE_INTERNAL_ONLY;
     173                 :          0 :                 header->cn9k.lport = 0;
     174                 :          0 :                 header->cn9k.fport = 0;
     175                 :          0 :                 header->cn9k.pvfe = 0;
     176                 :          0 :                 break;
     177                 :          0 :         case RTE_DMA_DIR_DEV_TO_DEV:
     178                 :          0 :                 header->cn9k.xtype = DPI_XTYPE_EXTERNAL_ONLY;
     179                 :          0 :                 header->cn9k.lport = conf->src_port.pcie.coreid;
     180                 :          0 :                 header->cn9k.fport = conf->dst_port.pcie.coreid;
     181                 :          0 :                 header->cn9k.pvfe = 0;
     182                 :            :         };
     183                 :            : 
     184                 :            :         return 0;
     185                 :            : }
     186                 :            : 
     187                 :            : static int
     188                 :          0 : cn10k_dmadev_setup_hdr(union cnxk_dpi_instr_cmd *header, const struct rte_dma_vchan_conf *conf)
     189                 :            : {
     190                 :            :         int aura;
     191                 :            : 
     192                 :          0 :         header->cn10k.pt = DPI_HDR_PT_ZBW_CA;
     193                 :            : 
     194   [ #  #  #  #  :          0 :         switch (conf->direction) {
                      # ]
     195                 :          0 :         case RTE_DMA_DIR_DEV_TO_MEM:
     196                 :          0 :                 header->cn10k.xtype = DPI_XTYPE_INBOUND;
     197                 :          0 :                 header->cn10k.lport = conf->src_port.pcie.coreid;
     198                 :          0 :                 header->cn10k.fport = 0;
     199                 :          0 :                 header->cn10k.pvfe = conf->src_port.pcie.vfen;
     200         [ #  # ]:          0 :                 if (header->cn10k.pvfe) {
     201                 :          0 :                         header->cn10k.func = conf->src_port.pcie.pfid << 12;
     202                 :          0 :                         header->cn10k.func |= conf->src_port.pcie.vfid;
     203                 :            :                 }
     204                 :            :                 break;
     205                 :          0 :         case RTE_DMA_DIR_MEM_TO_DEV:
     206                 :          0 :                 header->cn10k.xtype = DPI_XTYPE_OUTBOUND;
     207                 :          0 :                 header->cn10k.lport = 0;
     208                 :          0 :                 header->cn10k.fport = conf->dst_port.pcie.coreid;
     209                 :          0 :                 header->cn10k.pvfe = conf->dst_port.pcie.vfen;
     210         [ #  # ]:          0 :                 if (header->cn10k.pvfe) {
     211                 :          0 :                         header->cn10k.func = conf->dst_port.pcie.pfid << 12;
     212                 :          0 :                         header->cn10k.func |= conf->dst_port.pcie.vfid;
     213                 :            :                 }
     214         [ #  # ]:          0 :                 aura = dmadev_src_buf_aura_get(conf->auto_free.m2d.pool, "cn10k_mempool_ops");
     215                 :            :                 if (aura < 0)
     216                 :          0 :                         return aura;
     217                 :          0 :                 header->cn10k.aura = aura;
     218                 :          0 :                 break;
     219                 :          0 :         case RTE_DMA_DIR_MEM_TO_MEM:
     220                 :          0 :                 header->cn10k.xtype = DPI_XTYPE_INTERNAL_ONLY;
     221                 :          0 :                 header->cn10k.lport = 0;
     222                 :          0 :                 header->cn10k.fport = 0;
     223                 :          0 :                 header->cn10k.pvfe = 0;
     224                 :          0 :                 break;
     225                 :          0 :         case RTE_DMA_DIR_DEV_TO_DEV:
     226                 :          0 :                 header->cn10k.xtype = DPI_XTYPE_EXTERNAL_ONLY;
     227                 :          0 :                 header->cn10k.lport = conf->src_port.pcie.coreid;
     228                 :          0 :                 header->cn10k.fport = conf->dst_port.pcie.coreid;
     229                 :          0 :                 header->cn10k.pvfe = 0;
     230                 :            :         };
     231                 :            : 
     232                 :            :         return 0;
     233                 :            : }
     234                 :            : 
     235                 :            : static int
     236                 :          0 : cnxk_dmadev_vchan_setup(struct rte_dma_dev *dev, uint16_t vchan,
     237                 :            :                         const struct rte_dma_vchan_conf *conf, uint32_t conf_sz)
     238                 :            : {
     239                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
     240                 :          0 :         struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
     241                 :            :         union cnxk_dpi_instr_cmd *header;
     242                 :            :         uint16_t max_desc;
     243                 :            :         uint32_t size;
     244                 :            :         int i, ret;
     245                 :            : 
     246                 :            :         RTE_SET_USED(conf_sz);
     247                 :            : 
     248                 :          0 :         header = (union cnxk_dpi_instr_cmd *)&dpi_conf->cmd.u;
     249                 :            : 
     250         [ #  # ]:          0 :         if (dpivf->is_cn10k)
     251                 :          0 :                 ret = cn10k_dmadev_setup_hdr(header, conf);
     252                 :            :         else
     253                 :          0 :                 ret = cn9k_dmadev_setup_hdr(header, conf);
     254                 :            : 
     255         [ #  # ]:          0 :         if (ret)
     256                 :            :                 return ret;
     257                 :            : 
     258                 :            :         /* Free up descriptor memory before allocating. */
     259                 :          0 :         cnxk_dmadev_vchan_free(dpivf, vchan);
     260                 :            : 
     261                 :          0 :         max_desc = conf->nb_desc;
     262         [ #  # ]:          0 :         if (!rte_is_power_of_2(max_desc))
     263                 :          0 :                 max_desc = rte_align32pow2(max_desc);
     264                 :            : 
     265                 :            :         if (max_desc > CNXK_DPI_MAX_DESC)
     266                 :            :                 max_desc = CNXK_DPI_MAX_DESC;
     267                 :            : 
     268                 :          0 :         size = (max_desc * sizeof(uint8_t) * CNXK_DPI_COMPL_OFFSET);
     269                 :          0 :         dpi_conf->c_desc.compl_ptr = rte_zmalloc(NULL, size, 0);
     270                 :            : 
     271         [ #  # ]:          0 :         if (dpi_conf->c_desc.compl_ptr == NULL) {
     272                 :          0 :                 plt_err("Failed to allocate for comp_data");
     273                 :          0 :                 return -ENOMEM;
     274                 :            :         }
     275                 :            : 
     276                 :          0 :         size = (max_desc * sizeof(struct rte_dma_op *));
     277                 :          0 :         dpi_conf->c_desc.ops = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
     278         [ #  # ]:          0 :         if (dpi_conf->c_desc.ops == NULL) {
     279                 :          0 :                 plt_err("Failed to allocate for ops array");
     280                 :          0 :                 rte_free(dpi_conf->c_desc.compl_ptr);
     281                 :          0 :                 return -ENOMEM;
     282                 :            :         }
     283                 :            : 
     284         [ #  # ]:          0 :         for (i = 0; i < max_desc; i++)
     285                 :          0 :                 dpi_conf->c_desc.compl_ptr[i * CNXK_DPI_COMPL_OFFSET] = CNXK_DPI_REQ_CDATA;
     286                 :            : 
     287                 :          0 :         dpi_conf->c_desc.max_cnt = (max_desc - 1);
     288                 :            : 
     289                 :          0 :         return 0;
     290                 :            : }
     291                 :            : 
     292                 :            : static int
     293                 :          0 : cnxk_dmadev_start(struct rte_dma_dev *dev)
     294                 :            : {
     295                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
     296                 :            :         struct cnxk_dpi_conf *dpi_conf;
     297                 :            :         uint32_t chunks, nb_desc = 0;
     298                 :            :         uint32_t queue_buf_sz;
     299                 :            :         int i, j, rc = 0;
     300                 :            :         void *chunk;
     301                 :            : 
     302                 :          0 :         dpivf->total_pnum_words = 0;
     303                 :            : 
     304         [ #  # ]:          0 :         for (i = 0; i < dpivf->num_vchans; i++) {
     305                 :            :                 dpi_conf = &dpivf->conf[i];
     306                 :          0 :                 dpi_conf->c_desc.head = 0;
     307                 :          0 :                 dpi_conf->c_desc.tail = 0;
     308                 :          0 :                 dpi_conf->desc_idx = 0;
     309         [ #  # ]:          0 :                 for (j = 0; j < dpi_conf->c_desc.max_cnt + 1; j++)
     310                 :          0 :                         dpi_conf->c_desc.compl_ptr[j * CNXK_DPI_COMPL_OFFSET] = CNXK_DPI_REQ_CDATA;
     311                 :          0 :                 nb_desc += dpi_conf->c_desc.max_cnt + 1;
     312                 :          0 :                 cnxk_stats_reset(dev, i);
     313                 :          0 :                 dpi_conf->completed_offset = 0;
     314                 :            :         }
     315                 :            : 
     316                 :            :         queue_buf_sz = CNXK_DPI_QUEUE_BUF_SIZE_V2;
     317                 :            :         /* Max block size allowed by cnxk mempool driver is (128 * 1024).
     318                 :            :          * Block size = elt_size + mp->header + mp->trailer.
     319                 :            :          *
     320                 :            :          * Note from cn9k mempool driver:
     321                 :            :          * In cn9k additional padding of 128 bytes is added to mempool->trailer to
     322                 :            :          * ensure that the element size always occupies odd number of cachelines
     323                 :            :          * to ensure even distribution of elements among L1D cache sets.
     324                 :            :          */
     325         [ #  # ]:          0 :         if (!roc_model_is_cn10k())
     326                 :            :                 queue_buf_sz = CNXK_DPI_QUEUE_BUF_SIZE_V2 - 128;
     327                 :            : 
     328                 :          0 :         chunks = CNXK_DPI_CHUNKS_FROM_DESC(queue_buf_sz, nb_desc);
     329                 :          0 :         rc = cnxk_dmadev_chunk_pool_create(dev, chunks, queue_buf_sz);
     330         [ #  # ]:          0 :         if (rc < 0) {
     331                 :          0 :                 plt_err("DMA pool configure failed err = %d", rc);
     332                 :          0 :                 goto error;
     333                 :            :         }
     334                 :            : 
     335         [ #  # ]:          0 :         rc = rte_mempool_get(dpivf->chunk_pool, &chunk);
     336         [ #  # ]:          0 :         if (rc < 0) {
     337                 :          0 :                 plt_err("DMA failed to get chunk pointer err = %d", rc);
     338                 :          0 :                 rte_mempool_free(dpivf->chunk_pool);
     339                 :          0 :                 goto error;
     340                 :            :         }
     341                 :            : 
     342                 :          0 :         rc = roc_dpi_configure_v2(&dpivf->rdpi, queue_buf_sz, dpivf->aura, (uint64_t)chunk);
     343         [ #  # ]:          0 :         if (rc < 0) {
     344                 :          0 :                 plt_err("DMA configure failed err = %d", rc);
     345                 :          0 :                 rte_mempool_free(dpivf->chunk_pool);
     346                 :          0 :                 goto error;
     347                 :            :         }
     348                 :          0 :         dpivf->chunk_base = chunk;
     349                 :          0 :         dpivf->chunk_head = 0;
     350                 :          0 :         dpivf->chunk_size_m1 = (queue_buf_sz >> 3) - 2;
     351                 :            : 
     352                 :          0 :         roc_dpi_enable(&dpivf->rdpi);
     353                 :          0 : error:
     354                 :          0 :         return rc;
     355                 :            : }
     356                 :            : 
     357                 :            : static int
     358                 :          0 : cnxk_dmadev_stop(struct rte_dma_dev *dev)
     359                 :            : {
     360                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
     361                 :            : 
     362         [ #  # ]:          0 :         if (roc_dpi_wait_queue_idle(&dpivf->rdpi))
     363                 :            :                 return -EAGAIN;
     364                 :            : 
     365                 :          0 :         roc_dpi_disable(&dpivf->rdpi);
     366                 :          0 :         rte_mempool_free(dpivf->chunk_pool);
     367                 :          0 :         dpivf->chunk_pool = NULL;
     368                 :          0 :         dpivf->chunk_base = NULL;
     369                 :          0 :         dpivf->chunk_size_m1 = 0;
     370                 :            : 
     371                 :          0 :         return 0;
     372                 :            : }
     373                 :            : 
     374                 :            : static int
     375                 :          0 : cnxk_dmadev_close(struct rte_dma_dev *dev)
     376                 :            : {
     377                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
     378                 :            : 
     379                 :          0 :         roc_dpi_disable(&dpivf->rdpi);
     380                 :            :         cnxk_dmadev_vchan_free(dpivf, RTE_DMA_ALL_VCHAN);
     381                 :          0 :         roc_dpi_dev_fini(&dpivf->rdpi);
     382                 :            : 
     383                 :            :         /* Clear all flags as we close the device. */
     384                 :          0 :         dpivf->flag = 0;
     385                 :            : 
     386                 :          0 :         return 0;
     387                 :            : }
     388                 :            : 
     389                 :            : static uint16_t
     390                 :          0 : cnxk_dmadev_completed(void *dev_private, uint16_t vchan, const uint16_t nb_cpls, uint16_t *last_idx,
     391                 :            :                       bool *has_error)
     392                 :            : {
     393                 :            :         struct cnxk_dpi_vf_s *dpivf = dev_private;
     394                 :          0 :         struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
     395                 :            :         struct cnxk_dpi_cdesc_data_s *c_desc = &dpi_conf->c_desc;
     396                 :          0 :         const uint16_t max_cnt = c_desc->max_cnt;
     397                 :            :         uint8_t status;
     398                 :            :         int cnt;
     399                 :            : 
     400         [ #  # ]:          0 :         for (cnt = 0; cnt < nb_cpls; cnt++) {
     401                 :          0 :                 status = c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET];
     402         [ #  # ]:          0 :                 if (status) {
     403         [ #  # ]:          0 :                         if (status == CNXK_DPI_REQ_CDATA)
     404                 :            :                                 break;
     405                 :          0 :                         *has_error = 1;
     406                 :          0 :                         dpi_conf->stats.errors++;
     407                 :          0 :                         c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
     408                 :            :                                 CNXK_DPI_REQ_CDATA;
     409                 :          0 :                         c_desc->head++;
     410                 :          0 :                         break;
     411                 :            :                 }
     412                 :          0 :                 c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
     413                 :            :                         CNXK_DPI_REQ_CDATA;
     414                 :          0 :                 c_desc->head++;
     415                 :            :         }
     416                 :            : 
     417                 :          0 :         dpi_conf->stats.completed += cnt;
     418                 :          0 :         *last_idx = (dpi_conf->completed_offset + dpi_conf->stats.completed - 1) & 0xffff;
     419                 :            : 
     420                 :          0 :         return cnt;
     421                 :            : }
     422                 :            : 
     423                 :            : static uint16_t
     424                 :          0 : cnxk_dmadev_completed_status(void *dev_private, uint16_t vchan, const uint16_t nb_cpls,
     425                 :            :                              uint16_t *last_idx, enum rte_dma_status_code *status)
     426                 :            : {
     427                 :            :         struct cnxk_dpi_vf_s *dpivf = dev_private;
     428                 :          0 :         struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
     429                 :            :         struct cnxk_dpi_cdesc_data_s *c_desc = &dpi_conf->c_desc;
     430                 :          0 :         const uint16_t max_cnt = dpi_conf->c_desc.max_cnt;
     431                 :            :         int cnt;
     432                 :            : 
     433         [ #  # ]:          0 :         for (cnt = 0; cnt < nb_cpls; cnt++) {
     434                 :          0 :                 status[cnt] = c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET];
     435         [ #  # ]:          0 :                 if (status[cnt]) {
     436         [ #  # ]:          0 :                         if (status[cnt] == CNXK_DPI_REQ_CDATA)
     437                 :            :                                 break;
     438                 :            : 
     439                 :          0 :                         dpi_conf->stats.errors++;
     440                 :            :                 }
     441                 :          0 :                 c_desc->compl_ptr[(c_desc->head & max_cnt) * CNXK_DPI_COMPL_OFFSET] =
     442                 :            :                         CNXK_DPI_REQ_CDATA;
     443                 :          0 :                 c_desc->head++;
     444                 :            :         }
     445                 :            : 
     446                 :          0 :         dpi_conf->stats.completed += cnt;
     447                 :          0 :         *last_idx = (dpi_conf->completed_offset + dpi_conf->stats.completed - 1) & 0xffff;
     448                 :            : 
     449                 :          0 :         return cnt;
     450                 :            : }
     451                 :            : 
     452                 :            : static uint16_t
     453                 :          0 : cnxk_damdev_burst_capacity(const void *dev_private, uint16_t vchan)
     454                 :            : {
     455                 :            :         const struct cnxk_dpi_vf_s *dpivf = (const struct cnxk_dpi_vf_s *)dev_private;
     456                 :          0 :         const struct cnxk_dpi_conf *dpi_conf = &dpivf->conf[vchan];
     457                 :            :         uint16_t burst_cap;
     458                 :            : 
     459                 :          0 :         burst_cap = dpi_conf->c_desc.max_cnt -
     460                 :          0 :                     (dpi_conf->stats.submitted - dpi_conf->stats.completed) + 1;
     461                 :            : 
     462                 :          0 :         return burst_cap;
     463                 :            : }
     464                 :            : 
     465                 :            : static int
     466                 :          0 : cnxk_dmadev_submit(void *dev_private, uint16_t vchan)
     467                 :            : {
     468                 :            :         struct cnxk_dpi_vf_s *dpivf = dev_private;
     469                 :          0 :         uint32_t num_words = dpivf->total_pnum_words;
     470                 :            :         RTE_SET_USED(vchan);
     471                 :            : 
     472         [ #  # ]:          0 :         if (!num_words)
     473                 :            :                 return 0;
     474                 :            : 
     475                 :            :         rte_wmb();
     476                 :          0 :         plt_write64(num_words, dpivf->rdpi.rbase + DPI_VDMA_DBELL);
     477                 :            : 
     478                 :          0 :         dpivf->total_pnum_words = 0;
     479                 :            : 
     480                 :          0 :         return 0;
     481                 :            : }
     482                 :            : 
     483                 :            : static int
     484                 :          0 : cnxk_stats_get(const struct rte_dma_dev *dev, uint16_t vchan, struct rte_dma_stats *rte_stats,
     485                 :            :                uint32_t size)
     486                 :            : {
     487                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
     488                 :            :         struct cnxk_dpi_conf *dpi_conf;
     489                 :            :         int i;
     490                 :            : 
     491         [ #  # ]:          0 :         if (size < sizeof(rte_stats))
     492                 :            :                 return -EINVAL;
     493         [ #  # ]:          0 :         if (rte_stats == NULL)
     494                 :            :                 return -EINVAL;
     495                 :            : 
     496                 :            :         /* Stats of all vchans requested. */
     497         [ #  # ]:          0 :         if (vchan == RTE_DMA_ALL_VCHAN) {
     498         [ #  # ]:          0 :                 for (i = 0; i < dpivf->num_vchans; i++) {
     499                 :            :                         dpi_conf = &dpivf->conf[i];
     500                 :          0 :                         rte_stats->submitted += dpi_conf->stats.submitted;
     501                 :          0 :                         rte_stats->completed += dpi_conf->stats.completed;
     502                 :          0 :                         rte_stats->errors += dpi_conf->stats.errors;
     503                 :            :                 }
     504                 :            : 
     505                 :          0 :                 goto done;
     506                 :            :         }
     507                 :            : 
     508         [ #  # ]:          0 :         if (vchan >= CNXK_DPI_MAX_VCHANS_PER_QUEUE)
     509                 :            :                 return -EINVAL;
     510                 :            : 
     511                 :          0 :         dpi_conf = &dpivf->conf[vchan];
     512                 :          0 :         *rte_stats = dpi_conf->stats;
     513                 :            : 
     514                 :            : done:
     515                 :            :         return 0;
     516                 :            : }
     517                 :            : 
     518                 :            : static int
     519                 :          0 : cnxk_stats_reset(struct rte_dma_dev *dev, uint16_t vchan)
     520                 :            : {
     521                 :          0 :         struct cnxk_dpi_vf_s *dpivf = dev->fp_obj->dev_private;
     522                 :            :         struct cnxk_dpi_conf *dpi_conf;
     523                 :            :         int i;
     524                 :            : 
     525                 :            :         /* clear stats of all vchans. */
     526         [ #  # ]:          0 :         if (vchan == RTE_DMA_ALL_VCHAN) {
     527         [ #  # ]:          0 :                 for (i = 0; i < dpivf->num_vchans; i++) {
     528                 :            :                         dpi_conf = &dpivf->conf[i];
     529                 :          0 :                         dpi_conf->completed_offset += dpi_conf->stats.completed;
     530                 :          0 :                         dpi_conf->stats = (struct rte_dma_stats){0};
     531                 :            :                 }
     532                 :            : 
     533                 :            :                 return 0;
     534                 :            :         }
     535                 :            : 
     536         [ #  # ]:          0 :         if (vchan >= CNXK_DPI_MAX_VCHANS_PER_QUEUE)
     537                 :            :                 return -EINVAL;
     538                 :            : 
     539                 :          0 :         dpi_conf = &dpivf->conf[vchan];
     540                 :          0 :         dpi_conf->completed_offset += dpi_conf->stats.completed;
     541                 :          0 :         dpi_conf->stats = (struct rte_dma_stats){0};
     542                 :            : 
     543                 :          0 :         return 0;
     544                 :            : }
     545                 :            : 
     546                 :            : static void
     547                 :          0 : cnxk_set_fp_ops(struct rte_dma_dev *dev, uint8_t ena_enq_deq)
     548                 :            : {
     549                 :            : 
     550                 :          0 :         dev->fp_obj->copy = cnxk_dmadev_copy;
     551                 :          0 :         dev->fp_obj->copy_sg = cnxk_dmadev_copy_sg;
     552                 :          0 :         dev->fp_obj->submit = cnxk_dmadev_submit;
     553                 :          0 :         dev->fp_obj->completed = cnxk_dmadev_completed;
     554                 :          0 :         dev->fp_obj->completed_status = cnxk_dmadev_completed_status;
     555         [ #  # ]:          0 :         dev->fp_obj->burst_capacity = cnxk_damdev_burst_capacity;
     556                 :            : 
     557         [ #  # ]:          0 :         if (roc_model_is_cn10k()) {
     558                 :          0 :                 dev->fp_obj->copy = cn10k_dmadev_copy;
     559                 :          0 :                 dev->fp_obj->copy_sg = cn10k_dmadev_copy_sg;
     560                 :            :         }
     561                 :            : 
     562         [ #  # ]:          0 :         if (ena_enq_deq) {
     563                 :          0 :                 dev->fp_obj->copy = NULL;
     564                 :          0 :                 dev->fp_obj->copy_sg = NULL;
     565                 :          0 :                 dev->fp_obj->submit = NULL;
     566                 :          0 :                 dev->fp_obj->completed = NULL;
     567                 :          0 :                 dev->fp_obj->completed_status = NULL;
     568                 :            : 
     569                 :          0 :                 dev->fp_obj->enqueue = cnxk_dma_ops_enqueue;
     570                 :          0 :                 dev->fp_obj->dequeue = cnxk_dma_ops_dequeue;
     571                 :            : 
     572         [ #  # ]:          0 :                 if (roc_model_is_cn10k())
     573                 :          0 :                         dev->fp_obj->enqueue = cn10k_dma_ops_enqueue;
     574                 :            :         }
     575                 :          0 : }
     576                 :            : 
     577                 :            : static const struct rte_dma_dev_ops cnxk_dmadev_ops = {
     578                 :            :         .dev_close = cnxk_dmadev_close,
     579                 :            :         .dev_configure = cnxk_dmadev_configure,
     580                 :            :         .dev_info_get = cnxk_dmadev_info_get,
     581                 :            :         .dev_start = cnxk_dmadev_start,
     582                 :            :         .dev_stop = cnxk_dmadev_stop,
     583                 :            :         .stats_get = cnxk_stats_get,
     584                 :            :         .stats_reset = cnxk_stats_reset,
     585                 :            :         .vchan_setup = cnxk_dmadev_vchan_setup,
     586                 :            : };
     587                 :            : 
     588                 :            : static int
     589                 :          0 : cnxk_dmadev_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev)
     590                 :            : {
     591                 :            :         struct cnxk_dpi_vf_s *dpivf = NULL;
     592                 :            :         char name[RTE_DEV_NAME_MAX_LEN];
     593                 :            :         struct rte_dma_dev *dmadev;
     594                 :            :         struct roc_dpi *rdpi = NULL;
     595                 :            :         int rc;
     596                 :            : 
     597         [ #  # ]:          0 :         if (!pci_dev->mem_resource[0].addr)
     598                 :            :                 return -ENODEV;
     599                 :            : 
     600                 :          0 :         rc = roc_plt_init();
     601         [ #  # ]:          0 :         if (rc) {
     602                 :          0 :                 plt_err("Failed to initialize platform model, rc=%d", rc);
     603                 :          0 :                 return rc;
     604                 :            :         }
     605                 :            :         memset(name, 0, sizeof(name));
     606                 :          0 :         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
     607                 :            : 
     608                 :          0 :         dmadev = rte_dma_pmd_allocate(name, pci_dev->device.numa_node, sizeof(*dpivf));
     609         [ #  # ]:          0 :         if (dmadev == NULL) {
     610                 :          0 :                 plt_err("dma device allocation failed for %s", name);
     611                 :          0 :                 return -ENOMEM;
     612                 :            :         }
     613                 :            : 
     614                 :          0 :         dpivf = dmadev->data->dev_private;
     615                 :            : 
     616                 :          0 :         dmadev->device = &pci_dev->device;
     617                 :          0 :         dmadev->fp_obj->dev_private = dpivf;
     618                 :          0 :         dmadev->dev_ops = &cnxk_dmadev_ops;
     619                 :            : 
     620                 :          0 :         dpivf->is_cn10k = roc_model_is_cn10k();
     621                 :          0 :         dpivf->mcs_lock = NULL;
     622                 :          0 :         rdpi = &dpivf->rdpi;
     623                 :            : 
     624                 :          0 :         rdpi->pci_dev = pci_dev;
     625                 :          0 :         rc = roc_dpi_dev_init(rdpi, offsetof(struct rte_dma_op, impl_opaque));
     626         [ #  # ]:          0 :         if (rc < 0)
     627                 :          0 :                 goto err_out_free;
     628                 :            : 
     629                 :          0 :         dmadev->state = RTE_DMA_DEV_READY;
     630                 :            : 
     631                 :          0 :         return 0;
     632                 :            : 
     633                 :            : err_out_free:
     634                 :            :         if (dmadev)
     635                 :          0 :                 rte_dma_pmd_release(name);
     636                 :            : 
     637                 :          0 :         return rc;
     638                 :            : }
     639                 :            : 
     640                 :            : static int
     641                 :          0 : cnxk_dmadev_remove(struct rte_pci_device *pci_dev)
     642                 :            : {
     643                 :            :         char name[RTE_DEV_NAME_MAX_LEN];
     644                 :            : 
     645                 :            :         memset(name, 0, sizeof(name));
     646                 :          0 :         rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
     647                 :            : 
     648                 :          0 :         return rte_dma_pmd_release(name);
     649                 :            : }
     650                 :            : 
     651                 :            : static const struct rte_pci_id cnxk_dma_pci_map[] = {
     652                 :            :         {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_DPI_VF)},
     653                 :            :         {
     654                 :            :                 .vendor_id = 0,
     655                 :            :         },
     656                 :            : };
     657                 :            : 
     658                 :            : static struct rte_pci_driver cnxk_dmadev = {
     659                 :            :         .id_table = cnxk_dma_pci_map,
     660                 :            :         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
     661                 :            :         .probe = cnxk_dmadev_probe,
     662                 :            :         .remove = cnxk_dmadev_remove,
     663                 :            : };
     664                 :            : 
     665                 :        253 : RTE_PMD_REGISTER_PCI(cnxk_dmadev_pci_driver, cnxk_dmadev);
     666                 :            : RTE_PMD_REGISTER_PCI_TABLE(cnxk_dmadev_pci_driver, cnxk_dma_pci_map);
     667                 :            : RTE_PMD_REGISTER_KMOD_DEP(cnxk_dmadev_pci_driver, "vfio-pci");

Generated by: LCOV version 1.14