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

Generated by: LCOV version 1.14