LCOV - code coverage report
Current view: top level - lib/eventdev - rte_event_dma_adapter.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 526 0.0 %
Date: 2025-05-01 17:49:45 Functions: 0 33 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 380 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2023 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <eventdev_pmd.h>
       6                 :            : #include <eal_export.h>
       7                 :            : #include <rte_service_component.h>
       8                 :            : 
       9                 :            : #include "rte_event_dma_adapter.h"
      10                 :            : 
      11                 :            : #define DMA_BATCH_SIZE 32
      12                 :            : #define DMA_DEFAULT_MAX_NB 128
      13                 :            : #define DMA_ADAPTER_NAME_LEN 32
      14                 :            : #define DMA_ADAPTER_BUFFER_SIZE 1024
      15                 :            : 
      16                 :            : #define DMA_ADAPTER_OPS_BUFFER_SIZE (DMA_BATCH_SIZE + DMA_BATCH_SIZE)
      17                 :            : 
      18                 :            : #define DMA_ADAPTER_ARRAY "event_dma_adapter_array"
      19                 :            : 
      20                 :            : /* Macros to check for valid adapter */
      21                 :            : #define EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, retval) \
      22                 :            :         do { \
      23                 :            :                 if (!edma_adapter_valid_id(id)) { \
      24                 :            :                         RTE_EDEV_LOG_ERR("Invalid DMA adapter id = %d", id); \
      25                 :            :                         return retval; \
      26                 :            :                 } \
      27                 :            :         } while (0)
      28                 :            : 
      29                 :            : /* DMA ops circular buffer */
      30                 :            : struct __rte_cache_aligned dma_ops_circular_buffer {
      31                 :            :         /* Index of head element */
      32                 :            :         uint16_t head;
      33                 :            : 
      34                 :            :         /* Index of tail element */
      35                 :            :         uint16_t tail;
      36                 :            : 
      37                 :            :         /* Number of elements in buffer */
      38                 :            :         uint16_t count;
      39                 :            : 
      40                 :            :         /* Size of circular buffer */
      41                 :            :         uint16_t size;
      42                 :            : 
      43                 :            :         /* Pointer to hold rte_event_dma_adapter_op for processing */
      44                 :            :         struct rte_event_dma_adapter_op **op_buffer;
      45                 :            : };
      46                 :            : 
      47                 :            : /* Vchan information */
      48                 :            : struct __rte_cache_aligned dma_vchan_info {
      49                 :            :         /* Set to indicate vchan queue is enabled */
      50                 :            :         bool vq_enabled;
      51                 :            : 
      52                 :            :         /* Circular buffer for batching DMA ops to dma_dev */
      53                 :            :         struct dma_ops_circular_buffer dma_buf;
      54                 :            : };
      55                 :            : 
      56                 :            : /* DMA device information */
      57                 :            : struct __rte_cache_aligned dma_device_info {
      58                 :            :         /* Pointer to vchan queue info */
      59                 :            :         struct dma_vchan_info *vchanq;
      60                 :            : 
      61                 :            :         /* Pointer to vchan queue info.
      62                 :            :          * This holds ops passed by application till the
      63                 :            :          * dma completion is done.
      64                 :            :          */
      65                 :            :         struct dma_vchan_info *tqmap;
      66                 :            : 
      67                 :            :         /* If num_vchanq > 0, the start callback will
      68                 :            :          * be invoked if not already invoked
      69                 :            :          */
      70                 :            :         uint16_t num_vchanq;
      71                 :            : 
      72                 :            :         /* Number of vchans configured for a DMA device. */
      73                 :            :         uint16_t num_dma_dev_vchan;
      74                 :            : 
      75                 :            :         /* Next queue pair to be processed */
      76                 :            :         uint16_t next_vchan_id;
      77                 :            : 
      78                 :            :         /* Set to indicate processing has been started */
      79                 :            :         uint8_t dev_started;
      80                 :            : 
      81                 :            :         /* Set to indicate dmadev->eventdev packet
      82                 :            :          * transfer uses a hardware mechanism
      83                 :            :          */
      84                 :            :         uint8_t internal_event_port;
      85                 :            : };
      86                 :            : 
      87                 :            : struct __rte_cache_aligned event_dma_adapter {
      88                 :            :         /* Event device identifier */
      89                 :            :         uint8_t eventdev_id;
      90                 :            : 
      91                 :            :         /* Event port identifier */
      92                 :            :         uint8_t event_port_id;
      93                 :            : 
      94                 :            :         /* Adapter mode */
      95                 :            :         enum rte_event_dma_adapter_mode mode;
      96                 :            : 
      97                 :            :         /* Memory allocation name */
      98                 :            :         char mem_name[DMA_ADAPTER_NAME_LEN];
      99                 :            : 
     100                 :            :         /* Socket identifier cached from eventdev */
     101                 :            :         int socket_id;
     102                 :            : 
     103                 :            :         /* Lock to serialize config updates with service function */
     104                 :            :         rte_spinlock_t lock;
     105                 :            : 
     106                 :            :         /* Next dma device to be processed */
     107                 :            :         uint16_t next_dmadev_id;
     108                 :            : 
     109                 :            :         /* DMA device structure array */
     110                 :            :         struct dma_device_info *dma_devs;
     111                 :            : 
     112                 :            :         /* Circular buffer for processing DMA ops to eventdev */
     113                 :            :         struct dma_ops_circular_buffer ebuf;
     114                 :            : 
     115                 :            :         /* Configuration callback for rte_service configuration */
     116                 :            :         rte_event_dma_adapter_conf_cb conf_cb;
     117                 :            : 
     118                 :            :         /* Configuration callback argument */
     119                 :            :         void *conf_arg;
     120                 :            : 
     121                 :            :         /* Set if  default_cb is being used */
     122                 :            :         int default_cb_arg;
     123                 :            : 
     124                 :            :         /* No. of vchan queue configured */
     125                 :            :         uint16_t nb_vchanq;
     126                 :            : 
     127                 :            :         /* Per adapter EAL service ID */
     128                 :            :         uint32_t service_id;
     129                 :            : 
     130                 :            :         /* Service initialization state */
     131                 :            :         uint8_t service_initialized;
     132                 :            : 
     133                 :            :         /* Max DMA ops processed in any service function invocation */
     134                 :            :         uint32_t max_nb;
     135                 :            : 
     136                 :            :         /* Store event port's implicit release capability */
     137                 :            :         uint8_t implicit_release_disabled;
     138                 :            : 
     139                 :            :         /* Flag to indicate backpressure at dma_dev
     140                 :            :          * Stop further dequeuing events from eventdev
     141                 :            :          */
     142                 :            :         bool stop_enq_to_dma_dev;
     143                 :            : 
     144                 :            :         /* Loop counter to flush dma ops */
     145                 :            :         uint16_t transmit_loop_count;
     146                 :            : 
     147                 :            :         /* Per instance stats structure */
     148                 :            :         struct rte_event_dma_adapter_stats dma_stats;
     149                 :            : };
     150                 :            : 
     151                 :            : static struct event_dma_adapter **event_dma_adapter;
     152                 :            : 
     153                 :            : static inline int
     154                 :            : edma_adapter_valid_id(uint8_t id)
     155                 :            : {
     156                 :            :         return id < RTE_EVENT_DMA_ADAPTER_MAX_INSTANCE;
     157                 :            : }
     158                 :            : 
     159                 :            : static inline struct event_dma_adapter *
     160                 :            : edma_id_to_adapter(uint8_t id)
     161                 :            : {
     162   [ #  #  #  #  :          0 :         return event_dma_adapter ? event_dma_adapter[id] : NULL;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     163                 :            : }
     164                 :            : 
     165                 :            : static int
     166                 :          0 : edma_array_init(void)
     167                 :            : {
     168                 :            :         const struct rte_memzone *mz;
     169                 :            :         uint32_t sz;
     170                 :            : 
     171                 :          0 :         mz = rte_memzone_lookup(DMA_ADAPTER_ARRAY);
     172         [ #  # ]:          0 :         if (mz == NULL) {
     173                 :            :                 sz = sizeof(struct event_dma_adapter *) * RTE_EVENT_DMA_ADAPTER_MAX_INSTANCE;
     174                 :            :                 sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
     175                 :            : 
     176                 :          0 :                 mz = rte_memzone_reserve_aligned(DMA_ADAPTER_ARRAY, sz, rte_socket_id(), 0,
     177                 :            :                                                  RTE_CACHE_LINE_SIZE);
     178         [ #  # ]:          0 :                 if (mz == NULL) {
     179                 :          0 :                         RTE_EDEV_LOG_ERR("Failed to reserve memzone : %s, err = %d",
     180                 :            :                                          DMA_ADAPTER_ARRAY, rte_errno);
     181                 :          0 :                         return -rte_errno;
     182                 :            :                 }
     183                 :            :         }
     184                 :            : 
     185                 :          0 :         event_dma_adapter = mz->addr;
     186                 :            : 
     187                 :          0 :         return 0;
     188                 :            : }
     189                 :            : 
     190                 :            : static inline bool
     191                 :            : edma_circular_buffer_batch_ready(struct dma_ops_circular_buffer *bufp)
     192                 :            : {
     193                 :            :         return bufp->count >= DMA_BATCH_SIZE;
     194                 :            : }
     195                 :            : 
     196                 :            : static inline bool
     197                 :            : edma_circular_buffer_space_for_batch(struct dma_ops_circular_buffer *bufp)
     198                 :            : {
     199                 :          0 :         return (bufp->size - bufp->count) >= DMA_BATCH_SIZE;
     200                 :            : }
     201                 :            : 
     202                 :            : static inline int
     203                 :            : edma_circular_buffer_init(const char *name, struct dma_ops_circular_buffer *buf, uint16_t sz)
     204                 :            : {
     205                 :          0 :         buf->op_buffer = rte_zmalloc(name, sizeof(struct rte_event_dma_adapter_op *) * sz, 0);
     206   [ #  #  #  #  :          0 :         if (buf->op_buffer == NULL)
                   #  # ]
     207                 :            :                 return -ENOMEM;
     208                 :            : 
     209                 :          0 :         buf->size = sz;
     210                 :            : 
     211                 :            :         return 0;
     212                 :            : }
     213                 :            : 
     214                 :            : static inline void
     215                 :            : edma_circular_buffer_free(struct dma_ops_circular_buffer *buf)
     216                 :            : {
     217                 :          0 :         rte_free(buf->op_buffer);
     218                 :            : }
     219                 :            : 
     220                 :            : static inline int
     221                 :            : edma_circular_buffer_add(struct dma_ops_circular_buffer *bufp, struct rte_event_dma_adapter_op *op)
     222                 :            : {
     223                 :            :         uint16_t *tail = &bufp->tail;
     224                 :            : 
     225                 :          0 :         bufp->op_buffer[*tail] = op;
     226                 :            : 
     227                 :            :         /* circular buffer, go round */
     228                 :          0 :         *tail = (*tail + 1) % bufp->size;
     229                 :          0 :         bufp->count++;
     230                 :            : 
     231                 :            :         return 0;
     232                 :            : }
     233                 :            : 
     234                 :            : static inline int
     235                 :          0 : edma_circular_buffer_flush_to_dma_dev(struct event_dma_adapter *adapter,
     236                 :            :                                       struct dma_ops_circular_buffer *bufp, uint8_t dma_dev_id,
     237                 :            :                                       uint16_t vchan, uint16_t *nb_ops_flushed)
     238                 :            : {
     239                 :            :         struct rte_event_dma_adapter_op *op;
     240                 :            :         uint16_t *head = &bufp->head;
     241                 :            :         uint16_t *tail = &bufp->tail;
     242                 :            :         struct dma_vchan_info *tq;
     243                 :            :         uint16_t n;
     244                 :            :         uint16_t i;
     245                 :            :         int ret;
     246                 :            : 
     247         [ #  # ]:          0 :         if (*tail > *head)
     248                 :          0 :                 n = *tail - *head;
     249         [ #  # ]:          0 :         else if (*tail < *head)
     250                 :          0 :                 n = bufp->size - *head;
     251                 :            :         else {
     252                 :          0 :                 *nb_ops_flushed = 0;
     253                 :          0 :                 return 0; /* buffer empty */
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         tq = &adapter->dma_devs[dma_dev_id].tqmap[vchan];
     257                 :            : 
     258         [ #  # ]:          0 :         for (i = 0; i < n; i++)      {
     259                 :          0 :                 op = bufp->op_buffer[*head];
     260         [ #  # ]:          0 :                 if (op->nb_src == 1 && op->nb_dst == 1)
     261                 :          0 :                         ret = rte_dma_copy(dma_dev_id, vchan, op->src_dst_seg[0].addr,
     262                 :            :                                            op->src_dst_seg[1].addr, op->src_dst_seg[0].length,
     263                 :            :                                            op->flags);
     264                 :            :                 else
     265                 :          0 :                         ret = rte_dma_copy_sg(dma_dev_id, vchan, &op->src_dst_seg[0],
     266                 :          0 :                                               &op->src_dst_seg[op->nb_src], op->nb_src, op->nb_dst,
     267                 :            :                                               op->flags);
     268         [ #  # ]:          0 :                 if (ret < 0)
     269                 :            :                         break;
     270                 :            : 
     271                 :            :                 /* Enqueue in transaction queue. */
     272                 :            :                 edma_circular_buffer_add(&tq->dma_buf, op);
     273                 :            : 
     274                 :          0 :                 *head = (*head + 1) % bufp->size;
     275                 :            :         }
     276                 :            : 
     277                 :          0 :         *nb_ops_flushed = i;
     278                 :          0 :         bufp->count -= *nb_ops_flushed;
     279         [ #  # ]:          0 :         if (!bufp->count) {
     280                 :          0 :                 *head = 0;
     281                 :          0 :                 *tail = 0;
     282                 :            :         }
     283                 :            : 
     284         [ #  # ]:          0 :         return *nb_ops_flushed == n ? 0 : -1;
     285                 :            : }
     286                 :            : 
     287                 :            : static int
     288         [ #  # ]:          0 : edma_default_config_cb(uint8_t id, uint8_t evdev_id, struct rte_event_dma_adapter_conf *conf,
     289                 :            :                        void *arg)
     290                 :            : {
     291                 :            :         struct rte_event_port_conf *port_conf;
     292                 :            :         struct rte_event_dev_config dev_conf;
     293                 :            :         struct event_dma_adapter *adapter;
     294                 :            :         struct rte_eventdev *dev;
     295                 :            :         uint8_t port_id;
     296                 :            :         int started;
     297                 :            :         int ret;
     298                 :            : 
     299                 :            :         adapter = edma_id_to_adapter(id);
     300         [ #  # ]:          0 :         if (adapter == NULL)
     301                 :            :                 return -EINVAL;
     302                 :            : 
     303                 :          0 :         dev = &rte_eventdevs[adapter->eventdev_id];
     304                 :          0 :         dev_conf = dev->data->dev_conf;
     305                 :            : 
     306                 :          0 :         started = dev->data->dev_started;
     307         [ #  # ]:          0 :         if (started)
     308                 :          0 :                 rte_event_dev_stop(evdev_id);
     309                 :            : 
     310                 :          0 :         port_id = dev_conf.nb_event_ports;
     311                 :          0 :         dev_conf.nb_event_ports += 1;
     312                 :            : 
     313                 :            :         port_conf = arg;
     314         [ #  # ]:          0 :         if (port_conf->event_port_cfg & RTE_EVENT_PORT_CFG_SINGLE_LINK)
     315                 :          0 :                 dev_conf.nb_single_link_event_port_queues += 1;
     316                 :            : 
     317                 :          0 :         ret = rte_event_dev_configure(evdev_id, &dev_conf);
     318         [ #  # ]:          0 :         if (ret) {
     319                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to configure event dev %u", evdev_id);
     320         [ #  # ]:          0 :                 if (started) {
     321         [ #  # ]:          0 :                         if (rte_event_dev_start(evdev_id))
     322                 :            :                                 return -EIO;
     323                 :            :                 }
     324                 :          0 :                 return ret;
     325                 :            :         }
     326                 :            : 
     327                 :          0 :         ret = rte_event_port_setup(evdev_id, port_id, port_conf);
     328         [ #  # ]:          0 :         if (ret) {
     329                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to setup event port %u", port_id);
     330                 :          0 :                 return ret;
     331                 :            :         }
     332                 :            : 
     333                 :          0 :         conf->event_port_id = port_id;
     334                 :          0 :         conf->max_nb = DMA_DEFAULT_MAX_NB;
     335         [ #  # ]:          0 :         if (started)
     336                 :          0 :                 ret = rte_event_dev_start(evdev_id);
     337                 :            : 
     338                 :          0 :         adapter->default_cb_arg = 1;
     339                 :          0 :         adapter->event_port_id = conf->event_port_id;
     340                 :            : 
     341                 :          0 :         return ret;
     342                 :            : }
     343                 :            : 
     344                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_create_ext, 23.11)
     345                 :            : int
     346                 :          0 : rte_event_dma_adapter_create_ext(uint8_t id, uint8_t evdev_id,
     347                 :            :                                  rte_event_dma_adapter_conf_cb conf_cb,
     348                 :            :                                  enum rte_event_dma_adapter_mode mode, void *conf_arg)
     349                 :            : {
     350                 :            :         struct rte_event_dev_info dev_info;
     351                 :            :         struct event_dma_adapter *adapter;
     352                 :            :         char name[DMA_ADAPTER_NAME_LEN];
     353                 :            :         struct rte_dma_info info;
     354                 :            :         uint16_t num_dma_dev;
     355                 :            :         int socket_id;
     356                 :            :         uint8_t i;
     357                 :            :         int ret;
     358                 :            : 
     359         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
     360         [ #  # ]:          0 :         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(evdev_id, -EINVAL);
     361                 :            : 
     362         [ #  # ]:          0 :         if (conf_cb == NULL)
     363                 :            :                 return -EINVAL;
     364                 :            : 
     365         [ #  # ]:          0 :         if (event_dma_adapter == NULL) {
     366                 :          0 :                 ret = edma_array_init();
     367         [ #  # ]:          0 :                 if (ret)
     368                 :            :                         return ret;
     369                 :            :         }
     370                 :            : 
     371                 :            :         adapter = edma_id_to_adapter(id);
     372         [ #  # ]:          0 :         if (adapter != NULL) {
     373                 :          0 :                 RTE_EDEV_LOG_ERR("ML adapter ID %d already exists!", id);
     374                 :          0 :                 return -EEXIST;
     375                 :            :         }
     376                 :            : 
     377                 :          0 :         socket_id = rte_event_dev_socket_id(evdev_id);
     378                 :            :         snprintf(name, DMA_ADAPTER_NAME_LEN, "rte_event_dma_adapter_%d", id);
     379                 :          0 :         adapter = rte_zmalloc_socket(name, sizeof(struct event_dma_adapter), RTE_CACHE_LINE_SIZE,
     380                 :            :                                      socket_id);
     381         [ #  # ]:          0 :         if (adapter == NULL) {
     382                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get mem for event ML adapter!");
     383                 :          0 :                 return -ENOMEM;
     384                 :            :         }
     385                 :            : 
     386                 :            :         if (edma_circular_buffer_init("edma_circular_buffer", &adapter->ebuf,
     387                 :            :                                       DMA_ADAPTER_BUFFER_SIZE)) {
     388                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get memory for event adapter circular buffer");
     389                 :          0 :                 rte_free(adapter);
     390                 :          0 :                 return -ENOMEM;
     391                 :            :         }
     392                 :            : 
     393                 :          0 :         ret = rte_event_dev_info_get(evdev_id, &dev_info);
     394         [ #  # ]:          0 :         if (ret < 0) {
     395                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get info for eventdev %d: %s", evdev_id,
     396                 :            :                                  dev_info.driver_name);
     397                 :            :                 edma_circular_buffer_free(&adapter->ebuf);
     398                 :          0 :                 rte_free(adapter);
     399                 :          0 :                 return ret;
     400                 :            :         }
     401                 :            : 
     402                 :          0 :         num_dma_dev = rte_dma_count_avail();
     403                 :            : 
     404                 :          0 :         adapter->eventdev_id = evdev_id;
     405                 :          0 :         adapter->mode = mode;
     406                 :          0 :         rte_strscpy(adapter->mem_name, name, DMA_ADAPTER_NAME_LEN);
     407                 :          0 :         adapter->socket_id = socket_id;
     408                 :          0 :         adapter->conf_cb = conf_cb;
     409                 :          0 :         adapter->conf_arg = conf_arg;
     410                 :          0 :         adapter->dma_devs = rte_zmalloc_socket(adapter->mem_name,
     411                 :            :                                                num_dma_dev * sizeof(struct dma_device_info), 0,
     412                 :            :                                                socket_id);
     413         [ #  # ]:          0 :         if (adapter->dma_devs == NULL) {
     414                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get memory for DMA devices");
     415                 :            :                 edma_circular_buffer_free(&adapter->ebuf);
     416                 :          0 :                 rte_free(adapter);
     417                 :          0 :                 return -ENOMEM;
     418                 :            :         }
     419                 :            : 
     420                 :            :         rte_spinlock_init(&adapter->lock);
     421         [ #  # ]:          0 :         for (i = 0; i < num_dma_dev; i++) {
     422                 :          0 :                 ret = rte_dma_info_get(i, &info);
     423         [ #  # ]:          0 :                 if (ret) {
     424                 :          0 :                         RTE_EDEV_LOG_ERR("Failed to get dma device info");
     425                 :            :                         edma_circular_buffer_free(&adapter->ebuf);
     426                 :          0 :                         rte_free(adapter);
     427                 :          0 :                         return ret;
     428                 :            :                 }
     429                 :            : 
     430                 :          0 :                 adapter->dma_devs[i].num_dma_dev_vchan = info.nb_vchans;
     431                 :            :         }
     432                 :            : 
     433                 :          0 :         event_dma_adapter[id] = adapter;
     434                 :            : 
     435                 :          0 :         return 0;
     436                 :            : }
     437                 :            : 
     438                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_create, 23.11)
     439                 :            : int
     440                 :          0 : rte_event_dma_adapter_create(uint8_t id, uint8_t evdev_id, struct rte_event_port_conf *port_config,
     441                 :            :                             enum rte_event_dma_adapter_mode mode)
     442                 :            : {
     443                 :            :         struct rte_event_port_conf *pc;
     444                 :            :         int ret;
     445                 :            : 
     446         [ #  # ]:          0 :         if (port_config == NULL)
     447                 :            :                 return -EINVAL;
     448                 :            : 
     449         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
     450                 :            : 
     451                 :          0 :         pc = rte_malloc(NULL, sizeof(struct rte_event_port_conf), 0);
     452         [ #  # ]:          0 :         if (pc == NULL)
     453                 :            :                 return -ENOMEM;
     454                 :            : 
     455                 :            :         rte_memcpy(pc, port_config, sizeof(struct rte_event_port_conf));
     456                 :          0 :         ret = rte_event_dma_adapter_create_ext(id, evdev_id, edma_default_config_cb, mode, pc);
     457         [ #  # ]:          0 :         if (ret != 0)
     458                 :          0 :                 rte_free(pc);
     459                 :            : 
     460                 :            :         return ret;
     461                 :            : }
     462                 :            : 
     463                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_free, 23.11)
     464                 :            : int
     465                 :          0 : rte_event_dma_adapter_free(uint8_t id)
     466                 :            : {
     467                 :            :         struct event_dma_adapter *adapter;
     468                 :            : 
     469         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
     470                 :            : 
     471                 :            :         adapter = edma_id_to_adapter(id);
     472         [ #  # ]:          0 :         if (adapter == NULL)
     473                 :            :                 return -EINVAL;
     474                 :            : 
     475                 :          0 :         rte_free(adapter->conf_arg);
     476                 :          0 :         rte_free(adapter->dma_devs);
     477                 :            :         edma_circular_buffer_free(&adapter->ebuf);
     478                 :          0 :         rte_free(adapter);
     479                 :          0 :         event_dma_adapter[id] = NULL;
     480                 :            : 
     481                 :          0 :         return 0;
     482                 :            : }
     483                 :            : 
     484                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_event_port_get, 23.11)
     485                 :            : int
     486                 :          0 : rte_event_dma_adapter_event_port_get(uint8_t id, uint8_t *event_port_id)
     487                 :            : {
     488                 :            :         struct event_dma_adapter *adapter;
     489                 :            : 
     490         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
     491                 :            : 
     492                 :            :         adapter = edma_id_to_adapter(id);
     493         [ #  # ]:          0 :         if (adapter == NULL || event_port_id == NULL)
     494                 :            :                 return -EINVAL;
     495                 :            : 
     496                 :          0 :         *event_port_id = adapter->event_port_id;
     497                 :            : 
     498                 :          0 :         return 0;
     499                 :            : }
     500                 :            : 
     501                 :            : static inline unsigned int
     502                 :          0 : edma_enq_to_dma_dev(struct event_dma_adapter *adapter, struct rte_event *ev, unsigned int cnt)
     503                 :            : {
     504                 :            :         struct rte_event_dma_adapter_stats *stats = &adapter->dma_stats;
     505                 :            :         struct dma_vchan_info *vchan_qinfo = NULL;
     506                 :            :         struct rte_event_dma_adapter_op *dma_op;
     507                 :          0 :         uint16_t vchan, nb_enqueued = 0;
     508                 :            :         int16_t dma_dev_id;
     509                 :            :         unsigned int i, n;
     510                 :            :         int ret;
     511                 :            : 
     512                 :            :         ret = 0;
     513                 :            :         n = 0;
     514                 :          0 :         stats->event_deq_count += cnt;
     515                 :            : 
     516         [ #  # ]:          0 :         for (i = 0; i < cnt; i++) {
     517                 :          0 :                 dma_op = ev[i].event_ptr;
     518         [ #  # ]:          0 :                 if (dma_op == NULL)
     519                 :          0 :                         continue;
     520                 :            : 
     521                 :          0 :                 dma_op->impl_opaque[0] = ev[i].event;
     522                 :          0 :                 dma_dev_id = dma_op->dma_dev_id;
     523                 :          0 :                 vchan = dma_op->vchan;
     524                 :          0 :                 vchan_qinfo = &adapter->dma_devs[dma_dev_id].vchanq[vchan];
     525         [ #  # ]:          0 :                 if (!vchan_qinfo->vq_enabled) {
     526         [ #  # ]:          0 :                         if (dma_op != NULL && dma_op->op_mp != NULL)
     527                 :          0 :                                 rte_mempool_put(dma_op->op_mp, dma_op);
     528                 :          0 :                         continue;
     529                 :            :                 }
     530                 :          0 :                 edma_circular_buffer_add(&vchan_qinfo->dma_buf, dma_op);
     531                 :            : 
     532         [ #  # ]:          0 :                 if (edma_circular_buffer_batch_ready(&vchan_qinfo->dma_buf)) {
     533                 :          0 :                         ret = edma_circular_buffer_flush_to_dma_dev(adapter, &vchan_qinfo->dma_buf,
     534                 :            :                                                                     dma_dev_id, vchan,
     535                 :            :                                                                     &nb_enqueued);
     536                 :          0 :                         stats->dma_enq_count += nb_enqueued;
     537                 :          0 :                         n += nb_enqueued;
     538                 :            : 
     539                 :            :                         /**
     540                 :            :                          * If some dma ops failed to flush to dma_dev and
     541                 :            :                          * space for another batch is not available, stop
     542                 :            :                          * dequeue from eventdev momentarily
     543                 :            :                          */
     544   [ #  #  #  # ]:          0 :                         if (unlikely(ret < 0 &&
     545                 :            :                                      !edma_circular_buffer_space_for_batch(&vchan_qinfo->dma_buf)))
     546                 :          0 :                                 adapter->stop_enq_to_dma_dev = true;
     547                 :            :                 }
     548                 :            :         }
     549                 :            : 
     550                 :          0 :         return n;
     551                 :            : }
     552                 :            : 
     553                 :            : static unsigned int
     554                 :          0 : edma_adapter_dev_flush(struct event_dma_adapter *adapter, int16_t dma_dev_id,
     555                 :            :                        uint16_t *nb_ops_flushed)
     556                 :            : {
     557                 :            :         struct dma_vchan_info *vchan_info;
     558                 :            :         struct dma_device_info *dev_info;
     559                 :          0 :         uint16_t nb = 0, nb_enqueued = 0;
     560                 :            :         uint16_t vchan, nb_vchans;
     561                 :            : 
     562                 :          0 :         dev_info = &adapter->dma_devs[dma_dev_id];
     563                 :          0 :         nb_vchans = dev_info->num_vchanq;
     564                 :            : 
     565         [ #  # ]:          0 :         for (vchan = 0; vchan < nb_vchans; vchan++) {
     566                 :            : 
     567                 :          0 :                 vchan_info = &dev_info->vchanq[vchan];
     568   [ #  #  #  # ]:          0 :                 if (unlikely(vchan_info == NULL || !vchan_info->vq_enabled))
     569                 :          0 :                         continue;
     570                 :            : 
     571                 :          0 :                 edma_circular_buffer_flush_to_dma_dev(adapter, &vchan_info->dma_buf, dma_dev_id,
     572                 :            :                                                       vchan, &nb_enqueued);
     573                 :          0 :                 *nb_ops_flushed += vchan_info->dma_buf.count;
     574                 :          0 :                 nb += nb_enqueued;
     575                 :            :         }
     576                 :            : 
     577                 :          0 :         return nb;
     578                 :            : }
     579                 :            : 
     580                 :            : static unsigned int
     581                 :          0 : edma_adapter_enq_flush(struct event_dma_adapter *adapter)
     582                 :            : {
     583                 :            :         struct rte_event_dma_adapter_stats *stats = &adapter->dma_stats;
     584                 :            :         int16_t dma_dev_id;
     585                 :            :         uint16_t nb_enqueued = 0;
     586                 :          0 :         uint16_t nb_ops_flushed = 0;
     587                 :          0 :         uint16_t num_dma_dev = rte_dma_count_avail();
     588                 :            : 
     589         [ #  # ]:          0 :         for (dma_dev_id = 0; dma_dev_id < num_dma_dev; dma_dev_id++)
     590                 :          0 :                 nb_enqueued += edma_adapter_dev_flush(adapter, dma_dev_id, &nb_ops_flushed);
     591                 :            :         /**
     592                 :            :          * Enable dequeue from eventdev if all ops from circular
     593                 :            :          * buffer flushed to dma_dev
     594                 :            :          */
     595         [ #  # ]:          0 :         if (!nb_ops_flushed)
     596                 :          0 :                 adapter->stop_enq_to_dma_dev = false;
     597                 :            : 
     598                 :          0 :         stats->dma_enq_count += nb_enqueued;
     599                 :            : 
     600                 :          0 :         return nb_enqueued;
     601                 :            : }
     602                 :            : 
     603                 :            : /* Flush an instance's enqueue buffers every DMA_ENQ_FLUSH_THRESHOLD
     604                 :            :  * iterations of edma_adapter_enq_run()
     605                 :            :  */
     606                 :            : #define DMA_ENQ_FLUSH_THRESHOLD 1024
     607                 :            : 
     608                 :            : static int
     609                 :          0 : edma_adapter_enq_run(struct event_dma_adapter *adapter, unsigned int max_enq)
     610                 :            : {
     611                 :            :         struct rte_event_dma_adapter_stats *stats = &adapter->dma_stats;
     612                 :          0 :         uint8_t event_port_id = adapter->event_port_id;
     613                 :          0 :         uint8_t event_dev_id = adapter->eventdev_id;
     614                 :            :         struct rte_event ev[DMA_BATCH_SIZE];
     615                 :            :         unsigned int nb_enq, nb_enqueued;
     616                 :            :         uint16_t n;
     617                 :            : 
     618         [ #  # ]:          0 :         if (adapter->mode == RTE_EVENT_DMA_ADAPTER_OP_NEW)
     619                 :            :                 return 0;
     620                 :            : 
     621                 :            :         nb_enqueued = 0;
     622         [ #  # ]:          0 :         for (nb_enq = 0; nb_enq < max_enq; nb_enq += n) {
     623                 :            : 
     624         [ #  # ]:          0 :                 if (unlikely(adapter->stop_enq_to_dma_dev)) {
     625                 :          0 :                         nb_enqueued += edma_adapter_enq_flush(adapter);
     626                 :            : 
     627         [ #  # ]:          0 :                         if (unlikely(adapter->stop_enq_to_dma_dev))
     628                 :            :                                 break;
     629                 :            :                 }
     630                 :            : 
     631                 :          0 :                 stats->event_poll_count++;
     632                 :          0 :                 n = rte_event_dequeue_burst(event_dev_id, event_port_id, ev, DMA_BATCH_SIZE, 0);
     633                 :            : 
     634         [ #  # ]:          0 :                 if (!n)
     635                 :            :                         break;
     636                 :            : 
     637                 :          0 :                 nb_enqueued += edma_enq_to_dma_dev(adapter, ev, n);
     638                 :            :         }
     639                 :            : 
     640         [ #  # ]:          0 :         if ((++adapter->transmit_loop_count & (DMA_ENQ_FLUSH_THRESHOLD - 1)) == 0)
     641                 :          0 :                 nb_enqueued += edma_adapter_enq_flush(adapter);
     642                 :            : 
     643                 :          0 :         return nb_enqueued;
     644                 :            : }
     645                 :            : 
     646                 :            : #define DMA_ADAPTER_MAX_EV_ENQ_RETRIES 100
     647                 :            : 
     648                 :            : static inline uint16_t
     649                 :          0 : edma_ops_enqueue_burst(struct event_dma_adapter *adapter, struct rte_event_dma_adapter_op **ops,
     650                 :            :                        uint16_t num)
     651                 :            : {
     652                 :            :         struct rte_event_dma_adapter_stats *stats = &adapter->dma_stats;
     653                 :          0 :         uint8_t event_port_id = adapter->event_port_id;
     654                 :          0 :         uint8_t event_dev_id = adapter->eventdev_id;
     655                 :            :         struct rte_event events[DMA_BATCH_SIZE];
     656                 :            :         uint16_t nb_enqueued, nb_ev;
     657                 :            :         uint8_t retry;
     658                 :            :         uint8_t i;
     659                 :            : 
     660                 :            :         nb_ev = 0;
     661                 :            :         retry = 0;
     662                 :            :         nb_enqueued = 0;
     663                 :          0 :         num = RTE_MIN(num, DMA_BATCH_SIZE);
     664         [ #  # ]:          0 :         for (i = 0; i < num; i++) {
     665                 :          0 :                 struct rte_event *ev = &events[nb_ev++];
     666                 :            : 
     667                 :          0 :                 ev->event = ops[i]->impl_opaque[0];
     668                 :          0 :                 ev->event_ptr = ops[i];
     669                 :          0 :                 ev->event_type = RTE_EVENT_TYPE_DMADEV;
     670         [ #  # ]:          0 :                 if (adapter->implicit_release_disabled)
     671                 :          0 :                         ev->op = RTE_EVENT_OP_FORWARD;
     672                 :            :                 else
     673                 :          0 :                         ev->op = RTE_EVENT_OP_NEW;
     674                 :          0 :                 ev->event = ops[i]->event_meta;
     675                 :            :         }
     676                 :            : 
     677                 :            :         do {
     678                 :          0 :                 nb_enqueued += rte_event_enqueue_burst(event_dev_id, event_port_id,
     679                 :          0 :                                                        &events[nb_enqueued], nb_ev - nb_enqueued);
     680                 :            : 
     681   [ #  #  #  # ]:          0 :         } while (retry++ < DMA_ADAPTER_MAX_EV_ENQ_RETRIES && nb_enqueued < nb_ev);
     682                 :            : 
     683                 :          0 :         stats->event_enq_fail_count += nb_ev - nb_enqueued;
     684                 :          0 :         stats->event_enq_count += nb_enqueued;
     685                 :          0 :         stats->event_enq_retry_count += retry - 1;
     686                 :            : 
     687                 :          0 :         return nb_enqueued;
     688                 :            : }
     689                 :            : 
     690                 :            : static int
     691                 :          0 : edma_circular_buffer_flush_to_evdev(struct event_dma_adapter *adapter,
     692                 :            :                                     struct dma_ops_circular_buffer *bufp,
     693                 :            :                                     uint16_t *enqueue_count)
     694                 :            : {
     695                 :          0 :         struct rte_event_dma_adapter_op **ops = bufp->op_buffer;
     696                 :            :         uint16_t n = 0, nb_ops_flushed;
     697                 :            :         uint16_t *head = &bufp->head;
     698                 :            :         uint16_t *tail = &bufp->tail;
     699                 :            : 
     700         [ #  # ]:          0 :         if (*tail > *head)
     701                 :          0 :                 n = *tail - *head;
     702         [ #  # ]:          0 :         else if (*tail < *head)
     703                 :          0 :                 n = bufp->size - *head;
     704                 :            :         else {
     705         [ #  # ]:          0 :                 if (enqueue_count)
     706                 :          0 :                         *enqueue_count = 0;
     707                 :          0 :                 return 0; /* buffer empty */
     708                 :            :         }
     709                 :            : 
     710         [ #  # ]:          0 :         if (enqueue_count && n > *enqueue_count)
     711                 :            :                 n = *enqueue_count;
     712                 :            : 
     713                 :          0 :         nb_ops_flushed = edma_ops_enqueue_burst(adapter, &ops[*head], n);
     714         [ #  # ]:          0 :         if (enqueue_count)
     715                 :          0 :                 *enqueue_count = nb_ops_flushed;
     716                 :            : 
     717                 :          0 :         bufp->count -= nb_ops_flushed;
     718         [ #  # ]:          0 :         if (!bufp->count) {
     719                 :          0 :                 *head = 0;
     720                 :          0 :                 *tail = 0;
     721                 :          0 :                 return 0; /* buffer empty */
     722                 :            :         }
     723                 :            : 
     724                 :          0 :         *head = (*head + nb_ops_flushed) % bufp->size;
     725                 :          0 :         return 1;
     726                 :            : }
     727                 :            : 
     728                 :            : static void
     729                 :          0 : edma_ops_buffer_flush(struct event_dma_adapter *adapter)
     730                 :            : {
     731         [ #  # ]:          0 :         if (likely(adapter->ebuf.count == 0))
     732                 :            :                 return;
     733                 :            : 
     734         [ #  # ]:          0 :         while (edma_circular_buffer_flush_to_evdev(adapter, &adapter->ebuf, NULL))
     735                 :            :                 ;
     736                 :            : }
     737                 :            : 
     738                 :            : static inline unsigned int
     739                 :          0 : edma_adapter_deq_run(struct event_dma_adapter *adapter, unsigned int max_deq)
     740                 :            : {
     741                 :            :         struct rte_event_dma_adapter_stats *stats = &adapter->dma_stats;
     742                 :            :         struct dma_vchan_info *vchan_info;
     743                 :            :         struct dma_ops_circular_buffer *tq_buf;
     744                 :            :         struct rte_event_dma_adapter_op *ops;
     745                 :            :         uint16_t n, nb_deq, nb_enqueued, i;
     746                 :            :         struct dma_device_info *dev_info;
     747                 :            :         uint16_t vchan, num_vchan;
     748                 :            :         uint16_t num_dma_dev;
     749                 :            :         int16_t dma_dev_id;
     750                 :            :         uint16_t index;
     751                 :            :         bool done;
     752                 :            :         bool err;
     753                 :            : 
     754                 :            :         nb_deq = 0;
     755                 :          0 :         edma_ops_buffer_flush(adapter);
     756                 :            : 
     757                 :          0 :         num_dma_dev = rte_dma_count_avail();
     758                 :            :         do {
     759                 :            :                 done = true;
     760                 :            : 
     761         [ #  # ]:          0 :                 for (dma_dev_id = adapter->next_dmadev_id; dma_dev_id < num_dma_dev; dma_dev_id++) {
     762                 :            :                         uint16_t queues = 0;
     763                 :          0 :                         dev_info = &adapter->dma_devs[dma_dev_id];
     764                 :          0 :                         num_vchan = dev_info->num_vchanq;
     765                 :            : 
     766         [ #  # ]:          0 :                         for (vchan = dev_info->next_vchan_id; queues < num_vchan;
     767                 :          0 :                              vchan = (vchan + 1) % num_vchan, queues++) {
     768                 :            : 
     769                 :          0 :                                 vchan_info = &dev_info->vchanq[vchan];
     770   [ #  #  #  # ]:          0 :                                 if (unlikely(vchan_info == NULL || !vchan_info->vq_enabled))
     771                 :          0 :                                         continue;
     772                 :            : 
     773                 :          0 :                                 n = rte_dma_completed(dma_dev_id, vchan, DMA_BATCH_SIZE,
     774                 :            :                                                 &index, &err);
     775         [ #  # ]:          0 :                                 if (!n)
     776                 :          0 :                                         continue;
     777                 :            : 
     778                 :            :                                 done = false;
     779                 :          0 :                                 stats->dma_deq_count += n;
     780                 :            : 
     781                 :          0 :                                 tq_buf = &dev_info->tqmap[vchan].dma_buf;
     782                 :            : 
     783                 :          0 :                                 nb_enqueued = n;
     784         [ #  # ]:          0 :                                 if (unlikely(!adapter->ebuf.count))
     785                 :          0 :                                         edma_circular_buffer_flush_to_evdev(adapter, tq_buf,
     786                 :            :                                                                             &nb_enqueued);
     787                 :            : 
     788         [ #  # ]:          0 :                                 if (likely(nb_enqueued == n))
     789                 :          0 :                                         goto check;
     790                 :            : 
     791                 :            :                                 /* Failed to enqueue events case */
     792         [ #  # ]:          0 :                                 for (i = nb_enqueued; i < n; i++) {
     793                 :          0 :                                         ops = tq_buf->op_buffer[tq_buf->head];
     794                 :            :                                         edma_circular_buffer_add(&adapter->ebuf, ops);
     795                 :          0 :                                         tq_buf->head = (tq_buf->head + 1) % tq_buf->size;
     796                 :            :                                 }
     797                 :            : 
     798                 :          0 : check:
     799                 :          0 :                                 nb_deq += n;
     800         [ #  # ]:          0 :                                 if (nb_deq >= max_deq) {
     801         [ #  # ]:          0 :                                         if ((vchan + 1) == num_vchan)
     802                 :          0 :                                                 adapter->next_dmadev_id =
     803                 :          0 :                                                                 (dma_dev_id + 1) % num_dma_dev;
     804                 :            : 
     805                 :          0 :                                         dev_info->next_vchan_id = (vchan + 1) % num_vchan;
     806                 :            : 
     807                 :          0 :                                         return nb_deq;
     808                 :            :                                 }
     809                 :            :                         }
     810                 :            :                 }
     811                 :          0 :                 adapter->next_dmadev_id = 0;
     812                 :            : 
     813         [ #  # ]:          0 :         } while (done == false);
     814                 :            : 
     815                 :          0 :         return nb_deq;
     816                 :            : }
     817                 :            : 
     818                 :            : static int
     819                 :          0 : edma_adapter_run(struct event_dma_adapter *adapter, unsigned int max_ops)
     820                 :            : {
     821                 :            :         unsigned int ops_left = max_ops;
     822                 :            : 
     823         [ #  # ]:          0 :         while (ops_left > 0) {
     824                 :            :                 unsigned int e_cnt, d_cnt;
     825                 :            : 
     826                 :          0 :                 e_cnt = edma_adapter_deq_run(adapter, ops_left);
     827                 :          0 :                 ops_left -= RTE_MIN(ops_left, e_cnt);
     828                 :            : 
     829                 :          0 :                 d_cnt = edma_adapter_enq_run(adapter, ops_left);
     830                 :          0 :                 ops_left -= RTE_MIN(ops_left, d_cnt);
     831                 :            : 
     832         [ #  # ]:          0 :                 if (e_cnt == 0 && d_cnt == 0)
     833                 :            :                         break;
     834                 :            :         }
     835                 :            : 
     836         [ #  # ]:          0 :         if (ops_left == max_ops) {
     837         [ #  # ]:          0 :                 rte_event_maintain(adapter->eventdev_id, adapter->event_port_id, 0);
     838                 :          0 :                 return -EAGAIN;
     839                 :            :         } else
     840                 :            :                 return 0;
     841                 :            : }
     842                 :            : 
     843                 :            : static int
     844                 :          0 : edma_service_func(void *args)
     845                 :            : {
     846                 :            :         struct event_dma_adapter *adapter = args;
     847                 :            :         int ret;
     848                 :            : 
     849         [ #  # ]:          0 :         if (rte_spinlock_trylock(&adapter->lock) == 0)
     850                 :            :                 return 0;
     851                 :          0 :         ret = edma_adapter_run(adapter, adapter->max_nb);
     852                 :            :         rte_spinlock_unlock(&adapter->lock);
     853                 :            : 
     854                 :          0 :         return ret;
     855                 :            : }
     856                 :            : 
     857                 :            : static int
     858                 :          0 : edma_init_service(struct event_dma_adapter *adapter, uint8_t id)
     859                 :            : {
     860                 :            :         struct rte_event_dma_adapter_conf adapter_conf;
     861                 :            :         struct rte_service_spec service;
     862                 :            :         uint32_t impl_rel;
     863                 :            :         int ret;
     864                 :            : 
     865         [ #  # ]:          0 :         if (adapter->service_initialized)
     866                 :            :                 return 0;
     867                 :            : 
     868                 :            :         memset(&service, 0, sizeof(service));
     869                 :          0 :         snprintf(service.name, DMA_ADAPTER_NAME_LEN, "rte_event_dma_adapter_%d", id);
     870                 :          0 :         service.socket_id = adapter->socket_id;
     871                 :          0 :         service.callback = edma_service_func;
     872                 :          0 :         service.callback_userdata = adapter;
     873                 :            : 
     874                 :            :         /* Service function handles locking for queue add/del updates */
     875                 :          0 :         service.capabilities = RTE_SERVICE_CAP_MT_SAFE;
     876                 :          0 :         ret = rte_service_component_register(&service, &adapter->service_id);
     877         [ #  # ]:          0 :         if (ret) {
     878                 :          0 :                 RTE_EDEV_LOG_ERR("failed to register service %s err = %" PRId32, service.name, ret);
     879                 :          0 :                 return ret;
     880                 :            :         }
     881                 :            : 
     882                 :          0 :         ret = adapter->conf_cb(id, adapter->eventdev_id, &adapter_conf, adapter->conf_arg);
     883         [ #  # ]:          0 :         if (ret) {
     884                 :          0 :                 RTE_EDEV_LOG_ERR("configuration callback failed err = %" PRId32, ret);
     885                 :          0 :                 return ret;
     886                 :            :         }
     887                 :            : 
     888                 :          0 :         adapter->max_nb = adapter_conf.max_nb;
     889                 :          0 :         adapter->event_port_id = adapter_conf.event_port_id;
     890                 :            : 
     891         [ #  # ]:          0 :         if (rte_event_port_attr_get(adapter->eventdev_id, adapter->event_port_id,
     892                 :            :                                     RTE_EVENT_PORT_ATTR_IMPLICIT_RELEASE_DISABLE, &impl_rel)) {
     893                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get port info for eventdev %" PRId32,
     894                 :            :                                  adapter->eventdev_id);
     895                 :            :                 edma_circular_buffer_free(&adapter->ebuf);
     896                 :          0 :                 rte_free(adapter);
     897                 :          0 :                 return -EINVAL;
     898                 :            :         }
     899                 :            : 
     900                 :          0 :         adapter->implicit_release_disabled = (uint8_t)impl_rel;
     901                 :          0 :         adapter->service_initialized = 1;
     902                 :            : 
     903                 :          0 :         return ret;
     904                 :            : }
     905                 :            : 
     906                 :            : static void
     907                 :          0 : edma_update_vchanq_info(struct event_dma_adapter *adapter, struct dma_device_info *dev_info,
     908                 :            :                         uint16_t vchan, uint8_t add)
     909                 :            : {
     910                 :            :         struct dma_vchan_info *vchan_info;
     911                 :            :         struct dma_vchan_info *tqmap_info;
     912                 :            :         int enabled;
     913                 :            :         uint16_t i;
     914                 :            : 
     915         [ #  # ]:          0 :         if (dev_info->vchanq == NULL)
     916                 :            :                 return;
     917                 :            : 
     918         [ #  # ]:          0 :         if (vchan == RTE_DMA_ALL_VCHAN) {
     919         [ #  # ]:          0 :                 for (i = 0; i < dev_info->num_dma_dev_vchan; i++)
     920                 :          0 :                         edma_update_vchanq_info(adapter, dev_info, i, add);
     921                 :            :         } else {
     922                 :          0 :                 tqmap_info = &dev_info->tqmap[vchan];
     923                 :          0 :                 vchan_info = &dev_info->vchanq[vchan];
     924                 :          0 :                 enabled = vchan_info->vq_enabled;
     925         [ #  # ]:          0 :                 if (add) {
     926                 :          0 :                         adapter->nb_vchanq += !enabled;
     927                 :          0 :                         dev_info->num_vchanq += !enabled;
     928                 :            :                 } else {
     929                 :          0 :                         adapter->nb_vchanq -= enabled;
     930                 :          0 :                         dev_info->num_vchanq -= enabled;
     931                 :            :                 }
     932                 :          0 :                 vchan_info->vq_enabled = !!add;
     933                 :          0 :                 tqmap_info->vq_enabled = !!add;
     934                 :            :         }
     935                 :            : }
     936                 :            : 
     937                 :            : static int
     938                 :          0 : edma_add_vchan(struct event_dma_adapter *adapter, int16_t dma_dev_id, uint16_t vchan)
     939                 :            : {
     940                 :          0 :         struct dma_device_info *dev_info = &adapter->dma_devs[dma_dev_id];
     941                 :            :         struct dma_vchan_info *vchanq;
     942                 :            :         struct dma_vchan_info *tqmap;
     943                 :            :         uint16_t nb_vchans;
     944                 :            :         uint32_t i;
     945                 :            : 
     946         [ #  # ]:          0 :         if (dev_info->vchanq == NULL) {
     947                 :          0 :                 nb_vchans = dev_info->num_dma_dev_vchan;
     948                 :            : 
     949                 :          0 :                 dev_info->vchanq = rte_zmalloc_socket(adapter->mem_name,
     950                 :            :                                 nb_vchans * sizeof(struct dma_vchan_info),
     951                 :            :                                 0, adapter->socket_id);
     952         [ #  # ]:          0 :                 if (dev_info->vchanq == NULL)
     953                 :            :                         return -ENOMEM;
     954                 :            : 
     955                 :          0 :                 dev_info->tqmap = rte_zmalloc_socket(adapter->mem_name,
     956                 :            :                                 nb_vchans * sizeof(struct dma_vchan_info),
     957                 :            :                                 0, adapter->socket_id);
     958         [ #  # ]:          0 :                 if (dev_info->tqmap == NULL)
     959                 :            :                         return -ENOMEM;
     960                 :            : 
     961         [ #  # ]:          0 :                 for (i = 0; i < nb_vchans; i++) {
     962                 :          0 :                         vchanq = &dev_info->vchanq[i];
     963                 :            : 
     964                 :            :                         if (edma_circular_buffer_init("dma_dev_circular_buffer", &vchanq->dma_buf,
     965                 :            :                                                 DMA_ADAPTER_OPS_BUFFER_SIZE)) {
     966                 :          0 :                                 RTE_EDEV_LOG_ERR("Failed to get memory for dma_dev buffer");
     967                 :          0 :                                 rte_free(vchanq);
     968                 :          0 :                                 return -ENOMEM;
     969                 :            :                         }
     970                 :            : 
     971                 :          0 :                         tqmap = &dev_info->tqmap[i];
     972                 :            :                         if (edma_circular_buffer_init("dma_dev_circular_trans_buf", &tqmap->dma_buf,
     973                 :            :                                                 DMA_ADAPTER_OPS_BUFFER_SIZE)) {
     974                 :          0 :                                 RTE_EDEV_LOG_ERR(
     975                 :            :                                         "Failed to get memory for dma_dev transaction buffer");
     976                 :          0 :                                 rte_free(tqmap);
     977                 :          0 :                                 return -ENOMEM;
     978                 :            :                         }
     979                 :            :                 }
     980                 :            :         }
     981                 :            : 
     982         [ #  # ]:          0 :         if (vchan == RTE_DMA_ALL_VCHAN) {
     983         [ #  # ]:          0 :                 for (i = 0; i < dev_info->num_dma_dev_vchan; i++)
     984                 :          0 :                         edma_update_vchanq_info(adapter, dev_info, i, 1);
     985                 :            :         } else
     986                 :          0 :                 edma_update_vchanq_info(adapter, dev_info, vchan, 1);
     987                 :            : 
     988                 :            :         return 0;
     989                 :            : }
     990                 :            : 
     991                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_vchan_add, 23.11)
     992                 :            : int
     993                 :          0 : rte_event_dma_adapter_vchan_add(uint8_t id, int16_t dma_dev_id, uint16_t vchan,
     994                 :            :                                 const struct rte_event *event)
     995                 :            : {
     996                 :            :         struct event_dma_adapter *adapter;
     997                 :            :         struct dma_device_info *dev_info;
     998                 :            :         struct rte_eventdev *dev;
     999                 :            :         uint32_t cap;
    1000                 :            :         int ret;
    1001                 :            : 
    1002         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1003                 :            : 
    1004         [ #  # ]:          0 :         if (!rte_dma_is_valid(dma_dev_id)) {
    1005                 :          0 :                 RTE_EDEV_LOG_ERR("Invalid dma_dev_id = %" PRId16, dma_dev_id);
    1006                 :          0 :                 return -EINVAL;
    1007                 :            :         }
    1008                 :            : 
    1009                 :            :         adapter = edma_id_to_adapter(id);
    1010         [ #  # ]:          0 :         if (adapter == NULL)
    1011                 :            :                 return -EINVAL;
    1012                 :            : 
    1013                 :          0 :         dev = &rte_eventdevs[adapter->eventdev_id];
    1014                 :          0 :         ret = rte_event_dma_adapter_caps_get(adapter->eventdev_id, dma_dev_id, &cap);
    1015         [ #  # ]:          0 :         if (ret) {
    1016                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get adapter caps dev %u dma_dev %u", id, dma_dev_id);
    1017                 :          0 :                 return ret;
    1018                 :            :         }
    1019                 :            : 
    1020   [ #  #  #  # ]:          0 :         if ((cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND) && (event == NULL)) {
    1021                 :          0 :                 RTE_EDEV_LOG_ERR("Event can not be NULL for dma_dev_id = %u", dma_dev_id);
    1022                 :          0 :                 return -EINVAL;
    1023                 :            :         }
    1024                 :            : 
    1025                 :          0 :         dev_info = &adapter->dma_devs[dma_dev_id];
    1026   [ #  #  #  # ]:          0 :         if (vchan != RTE_DMA_ALL_VCHAN && vchan >= dev_info->num_dma_dev_vchan) {
    1027                 :          0 :                 RTE_EDEV_LOG_ERR("Invalid vhcan %u", vchan);
    1028                 :          0 :                 return -EINVAL;
    1029                 :            :         }
    1030                 :            : 
    1031                 :            :         /* In case HW cap is RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD, no
    1032                 :            :          * need of service core as HW supports event forward capability.
    1033                 :            :          */
    1034   [ #  #  #  # ]:          0 :         if ((cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) ||
    1035                 :          0 :             (cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND &&
    1036         [ #  # ]:          0 :              adapter->mode == RTE_EVENT_DMA_ADAPTER_OP_NEW) ||
    1037         [ #  # ]:          0 :             (cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW &&
    1038         [ #  # ]:          0 :              adapter->mode == RTE_EVENT_DMA_ADAPTER_OP_NEW)) {
    1039         [ #  # ]:          0 :                 if (dev->dev_ops->dma_adapter_vchan_add == NULL)
    1040                 :            :                         return -ENOTSUP;
    1041         [ #  # ]:          0 :                 if (dev_info->vchanq == NULL) {
    1042                 :          0 :                         dev_info->vchanq = rte_zmalloc_socket(adapter->mem_name,
    1043                 :          0 :                                                         dev_info->num_dma_dev_vchan *
    1044                 :            :                                                         sizeof(struct dma_vchan_info),
    1045                 :            :                                                         0, adapter->socket_id);
    1046         [ #  # ]:          0 :                         if (dev_info->vchanq == NULL) {
    1047                 :          0 :                                 RTE_EDEV_LOG_ERR("Queue pair add not supported");
    1048                 :          0 :                                 return -ENOMEM;
    1049                 :            :                         }
    1050                 :            :                 }
    1051                 :            : 
    1052         [ #  # ]:          0 :                 if (dev_info->tqmap == NULL) {
    1053                 :          0 :                         dev_info->tqmap = rte_zmalloc_socket(adapter->mem_name,
    1054                 :          0 :                                                 dev_info->num_dma_dev_vchan *
    1055                 :            :                                                 sizeof(struct dma_vchan_info),
    1056                 :            :                                                 0, adapter->socket_id);
    1057         [ #  # ]:          0 :                         if (dev_info->tqmap == NULL) {
    1058                 :          0 :                                 RTE_EDEV_LOG_ERR("tq pair add not supported");
    1059                 :          0 :                                 return -ENOMEM;
    1060                 :            :                         }
    1061                 :            :                 }
    1062                 :            : 
    1063                 :          0 :                 ret = dev->dev_ops->dma_adapter_vchan_add(dev, dma_dev_id, vchan, event);
    1064         [ #  # ]:          0 :                 if (ret)
    1065                 :            :                         return ret;
    1066                 :            : 
    1067                 :            :                 else
    1068                 :          0 :                         edma_update_vchanq_info(adapter, &adapter->dma_devs[dma_dev_id], vchan, 1);
    1069                 :            :         }
    1070                 :            : 
    1071                 :            :         /* In case HW cap is RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW, or SW adapter, initiate
    1072                 :            :          * services so the application can choose which ever way it wants to use the adapter.
    1073                 :            :          *
    1074                 :            :          * Case 1: RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW. Application may wants to use one
    1075                 :            :          * of below two modes
    1076                 :            :          *
    1077                 :            :          * a. OP_FORWARD mode -> HW Dequeue + SW enqueue
    1078                 :            :          * b. OP_NEW mode -> HW Dequeue
    1079                 :            :          *
    1080                 :            :          * Case 2: No HW caps, use SW adapter
    1081                 :            :          *
    1082                 :            :          * a. OP_FORWARD mode -> SW enqueue & dequeue
    1083                 :            :          * b. OP_NEW mode -> SW Dequeue
    1084                 :            :          */
    1085         [ #  # ]:          0 :         if ((cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW &&
    1086                 :          0 :              !(cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) &&
    1087         [ #  # ]:          0 :              adapter->mode == RTE_EVENT_DMA_ADAPTER_OP_FORWARD) ||
    1088                 :            :             (!(cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW) &&
    1089         [ #  # ]:          0 :              !(cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) &&
    1090                 :            :              !(cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND))) {
    1091                 :          0 :                 rte_spinlock_lock(&adapter->lock);
    1092                 :          0 :                 ret = edma_init_service(adapter, id);
    1093         [ #  # ]:          0 :                 if (ret == 0)
    1094                 :          0 :                         ret = edma_add_vchan(adapter, dma_dev_id, vchan);
    1095                 :            :                 rte_spinlock_unlock(&adapter->lock);
    1096                 :            : 
    1097         [ #  # ]:          0 :                 if (ret)
    1098                 :            :                         return ret;
    1099                 :            : 
    1100                 :          0 :                 rte_service_component_runstate_set(adapter->service_id, 1);
    1101                 :            :         }
    1102                 :            : 
    1103                 :            :         return 0;
    1104                 :            : }
    1105                 :            : 
    1106                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_vchan_del, 23.11)
    1107                 :            : int
    1108                 :          0 : rte_event_dma_adapter_vchan_del(uint8_t id, int16_t dma_dev_id, uint16_t vchan)
    1109                 :            : {
    1110                 :            :         struct event_dma_adapter *adapter;
    1111                 :            :         struct dma_device_info *dev_info;
    1112                 :            :         struct rte_eventdev *dev;
    1113                 :            :         uint32_t cap;
    1114                 :            :         int ret;
    1115                 :            : 
    1116         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1117                 :            : 
    1118         [ #  # ]:          0 :         if (!rte_dma_is_valid(dma_dev_id)) {
    1119                 :          0 :                 RTE_EDEV_LOG_ERR("Invalid dma_dev_id = %" PRId16, dma_dev_id);
    1120                 :          0 :                 return -EINVAL;
    1121                 :            :         }
    1122                 :            : 
    1123                 :            :         adapter = edma_id_to_adapter(id);
    1124         [ #  # ]:          0 :         if (adapter == NULL)
    1125                 :            :                 return -EINVAL;
    1126                 :            : 
    1127                 :          0 :         dev = &rte_eventdevs[adapter->eventdev_id];
    1128                 :          0 :         ret = rte_event_dma_adapter_caps_get(adapter->eventdev_id, dma_dev_id, &cap);
    1129         [ #  # ]:          0 :         if (ret)
    1130                 :            :                 return ret;
    1131                 :            : 
    1132                 :          0 :         dev_info = &adapter->dma_devs[dma_dev_id];
    1133                 :            : 
    1134   [ #  #  #  # ]:          0 :         if (vchan != RTE_DMA_ALL_VCHAN && vchan >= dev_info->num_dma_dev_vchan) {
    1135                 :          0 :                 RTE_EDEV_LOG_ERR("Invalid vhcan %" PRIu16, vchan);
    1136                 :          0 :                 return -EINVAL;
    1137                 :            :         }
    1138                 :            : 
    1139         [ #  # ]:          0 :         if ((cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) ||
    1140         [ #  # ]:          0 :             (cap & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW &&
    1141         [ #  # ]:          0 :              adapter->mode == RTE_EVENT_DMA_ADAPTER_OP_NEW)) {
    1142         [ #  # ]:          0 :                 if (dev->dev_ops->dma_adapter_vchan_del == NULL)
    1143                 :            :                         return -ENOTSUP;
    1144                 :          0 :                 ret = dev->dev_ops->dma_adapter_vchan_del(dev, dma_dev_id, vchan);
    1145         [ #  # ]:          0 :                 if (ret == 0) {
    1146                 :          0 :                         edma_update_vchanq_info(adapter, dev_info, vchan, 0);
    1147         [ #  # ]:          0 :                         if (dev_info->num_vchanq == 0) {
    1148                 :          0 :                                 rte_free(dev_info->vchanq);
    1149                 :          0 :                                 dev_info->vchanq = NULL;
    1150                 :            :                         }
    1151                 :            :                 }
    1152                 :            :         } else {
    1153         [ #  # ]:          0 :                 if (adapter->nb_vchanq == 0)
    1154                 :            :                         return 0;
    1155                 :            : 
    1156                 :          0 :                 rte_spinlock_lock(&adapter->lock);
    1157                 :          0 :                 edma_update_vchanq_info(adapter, dev_info, vchan, 0);
    1158                 :            : 
    1159         [ #  # ]:          0 :                 if (dev_info->num_vchanq == 0) {
    1160                 :          0 :                         rte_free(dev_info->vchanq);
    1161                 :          0 :                         rte_free(dev_info->tqmap);
    1162                 :          0 :                         dev_info->vchanq = NULL;
    1163                 :          0 :                         dev_info->tqmap = NULL;
    1164                 :            :                 }
    1165                 :            : 
    1166                 :            :                 rte_spinlock_unlock(&adapter->lock);
    1167                 :          0 :                 rte_service_component_runstate_set(adapter->service_id, adapter->nb_vchanq);
    1168                 :            :         }
    1169                 :            : 
    1170                 :            :         return ret;
    1171                 :            : }
    1172                 :            : 
    1173                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_service_id_get, 23.11)
    1174                 :            : int
    1175                 :          0 : rte_event_dma_adapter_service_id_get(uint8_t id, uint32_t *service_id)
    1176                 :            : {
    1177                 :            :         struct event_dma_adapter *adapter;
    1178                 :            : 
    1179         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1180                 :            : 
    1181                 :            :         adapter = edma_id_to_adapter(id);
    1182         [ #  # ]:          0 :         if (adapter == NULL || service_id == NULL)
    1183                 :            :                 return -EINVAL;
    1184                 :            : 
    1185         [ #  # ]:          0 :         if (adapter->service_initialized)
    1186                 :          0 :                 *service_id = adapter->service_id;
    1187                 :            : 
    1188         [ #  # ]:          0 :         return adapter->service_initialized ? 0 : -ESRCH;
    1189                 :            : }
    1190                 :            : 
    1191                 :            : static int
    1192                 :          0 : edma_adapter_ctrl(uint8_t id, int start)
    1193                 :            : {
    1194                 :            :         struct event_dma_adapter *adapter;
    1195                 :            :         struct dma_device_info *dev_info;
    1196                 :            :         struct rte_eventdev *dev;
    1197                 :            :         uint16_t num_dma_dev;
    1198                 :            :         int stop = !start;
    1199                 :            :         int use_service;
    1200                 :            :         uint32_t i;
    1201                 :            : 
    1202                 :            :         use_service = 0;
    1203         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1204                 :            :         adapter = edma_id_to_adapter(id);
    1205         [ #  # ]:          0 :         if (adapter == NULL)
    1206                 :            :                 return -EINVAL;
    1207                 :            : 
    1208                 :          0 :         num_dma_dev = rte_dma_count_avail();
    1209                 :          0 :         dev = &rte_eventdevs[adapter->eventdev_id];
    1210                 :            : 
    1211         [ #  # ]:          0 :         for (i = 0; i < num_dma_dev; i++) {
    1212                 :          0 :                 dev_info = &adapter->dma_devs[i];
    1213                 :            :                 /* start check for num queue pairs */
    1214   [ #  #  #  # ]:          0 :                 if (start && !dev_info->num_vchanq)
    1215                 :          0 :                         continue;
    1216                 :            :                 /* stop check if dev has been started */
    1217   [ #  #  #  # ]:          0 :                 if (stop && !dev_info->dev_started)
    1218                 :          0 :                         continue;
    1219                 :          0 :                 use_service |= !dev_info->internal_event_port;
    1220                 :          0 :                 dev_info->dev_started = start;
    1221         [ #  # ]:          0 :                 if (dev_info->internal_event_port == 0)
    1222                 :          0 :                         continue;
    1223         [ #  # ]:          0 :                 start ? dev->dev_ops->dma_adapter_start(dev, i) :
    1224                 :          0 :                         dev->dev_ops->dma_adapter_stop(dev, i);
    1225                 :            :         }
    1226                 :            : 
    1227         [ #  # ]:          0 :         if (use_service)
    1228                 :          0 :                 rte_service_runstate_set(adapter->service_id, start);
    1229                 :            : 
    1230                 :            :         return 0;
    1231                 :            : }
    1232                 :            : 
    1233                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_start, 23.11)
    1234                 :            : int
    1235                 :          0 : rte_event_dma_adapter_start(uint8_t id)
    1236                 :            : {
    1237                 :            :         struct event_dma_adapter *adapter;
    1238                 :            : 
    1239         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1240                 :            : 
    1241                 :            :         adapter = edma_id_to_adapter(id);
    1242         [ #  # ]:          0 :         if (adapter == NULL)
    1243                 :            :                 return -EINVAL;
    1244                 :            : 
    1245                 :          0 :         return edma_adapter_ctrl(id, 1);
    1246                 :            : }
    1247                 :            : 
    1248                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_stop, 23.11)
    1249                 :            : int
    1250                 :          0 : rte_event_dma_adapter_stop(uint8_t id)
    1251                 :            : {
    1252                 :          0 :         return edma_adapter_ctrl(id, 0);
    1253                 :            : }
    1254                 :            : 
    1255                 :            : #define DEFAULT_MAX_NB 128
    1256                 :            : 
    1257                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_runtime_params_init, 23.11)
    1258                 :            : int
    1259                 :          0 : rte_event_dma_adapter_runtime_params_init(struct rte_event_dma_adapter_runtime_params *params)
    1260                 :            : {
    1261         [ #  # ]:          0 :         if (params == NULL)
    1262                 :            :                 return -EINVAL;
    1263                 :            : 
    1264                 :            :         memset(params, 0, sizeof(*params));
    1265                 :          0 :         params->max_nb = DEFAULT_MAX_NB;
    1266                 :            : 
    1267                 :          0 :         return 0;
    1268                 :            : }
    1269                 :            : 
    1270                 :            : static int
    1271                 :          0 : dma_adapter_cap_check(struct event_dma_adapter *adapter)
    1272                 :            : {
    1273                 :            :         uint32_t caps;
    1274                 :            :         int ret;
    1275                 :            : 
    1276         [ #  # ]:          0 :         if (!adapter->nb_vchanq)
    1277                 :            :                 return -EINVAL;
    1278                 :            : 
    1279                 :          0 :         ret = rte_event_dma_adapter_caps_get(adapter->eventdev_id, adapter->next_dmadev_id, &caps);
    1280         [ #  # ]:          0 :         if (ret) {
    1281                 :          0 :                 RTE_EDEV_LOG_ERR("Failed to get adapter caps dev %" PRIu8 " cdev %" PRIu16,
    1282                 :            :                                  adapter->eventdev_id, adapter->next_dmadev_id);
    1283                 :          0 :                 return ret;
    1284                 :            :         }
    1285                 :            : 
    1286         [ #  # ]:          0 :         if ((caps & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD) ||
    1287                 :            :             (caps & RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW))
    1288                 :          0 :                 return -ENOTSUP;
    1289                 :            : 
    1290                 :            :         return 0;
    1291                 :            : }
    1292                 :            : 
    1293                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_runtime_params_set, 23.11)
    1294                 :            : int
    1295                 :          0 : rte_event_dma_adapter_runtime_params_set(uint8_t id,
    1296                 :            :                                          struct rte_event_dma_adapter_runtime_params *params)
    1297                 :            : {
    1298                 :            :         struct event_dma_adapter *adapter;
    1299                 :            :         int ret;
    1300                 :            : 
    1301         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1302                 :            : 
    1303         [ #  # ]:          0 :         if (params == NULL) {
    1304                 :          0 :                 RTE_EDEV_LOG_ERR("params pointer is NULL");
    1305                 :          0 :                 return -EINVAL;
    1306                 :            :         }
    1307                 :            : 
    1308                 :            :         adapter = edma_id_to_adapter(id);
    1309         [ #  # ]:          0 :         if (adapter == NULL)
    1310                 :            :                 return -EINVAL;
    1311                 :            : 
    1312                 :          0 :         ret = dma_adapter_cap_check(adapter);
    1313         [ #  # ]:          0 :         if (ret)
    1314                 :            :                 return ret;
    1315                 :            : 
    1316                 :          0 :         rte_spinlock_lock(&adapter->lock);
    1317                 :          0 :         adapter->max_nb = params->max_nb;
    1318                 :            :         rte_spinlock_unlock(&adapter->lock);
    1319                 :            : 
    1320                 :          0 :         return 0;
    1321                 :            : }
    1322                 :            : 
    1323                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_runtime_params_get, 23.11)
    1324                 :            : int
    1325                 :          0 : rte_event_dma_adapter_runtime_params_get(uint8_t id,
    1326                 :            :                                          struct rte_event_dma_adapter_runtime_params *params)
    1327                 :            : {
    1328                 :            :         struct event_dma_adapter *adapter;
    1329                 :            :         int ret;
    1330                 :            : 
    1331         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1332                 :            : 
    1333         [ #  # ]:          0 :         if (params == NULL) {
    1334                 :          0 :                 RTE_EDEV_LOG_ERR("params pointer is NULL");
    1335                 :          0 :                 return -EINVAL;
    1336                 :            :         }
    1337                 :            : 
    1338                 :            :         adapter = edma_id_to_adapter(id);
    1339         [ #  # ]:          0 :         if (adapter == NULL)
    1340                 :            :                 return -EINVAL;
    1341                 :            : 
    1342                 :          0 :         ret = dma_adapter_cap_check(adapter);
    1343         [ #  # ]:          0 :         if (ret)
    1344                 :            :                 return ret;
    1345                 :            : 
    1346                 :          0 :         params->max_nb = adapter->max_nb;
    1347                 :            : 
    1348                 :          0 :         return 0;
    1349                 :            : }
    1350                 :            : 
    1351                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_stats_get, 23.11)
    1352                 :            : int
    1353                 :          0 : rte_event_dma_adapter_stats_get(uint8_t id, struct rte_event_dma_adapter_stats *stats)
    1354                 :            : {
    1355                 :            :         struct rte_event_dma_adapter_stats dev_stats_sum = {0};
    1356                 :            :         struct rte_event_dma_adapter_stats dev_stats;
    1357                 :            :         struct event_dma_adapter *adapter;
    1358                 :            :         struct dma_device_info *dev_info;
    1359                 :            :         struct rte_eventdev *dev;
    1360                 :            :         uint16_t num_dma_dev;
    1361                 :            :         uint32_t i;
    1362                 :            :         int ret;
    1363                 :            : 
    1364         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1365                 :            : 
    1366                 :            :         adapter = edma_id_to_adapter(id);
    1367         [ #  # ]:          0 :         if (adapter == NULL || stats == NULL)
    1368                 :            :                 return -EINVAL;
    1369                 :            : 
    1370                 :          0 :         num_dma_dev = rte_dma_count_avail();
    1371                 :          0 :         dev = &rte_eventdevs[adapter->eventdev_id];
    1372                 :            :         memset(stats, 0, sizeof(*stats));
    1373         [ #  # ]:          0 :         for (i = 0; i < num_dma_dev; i++) {
    1374                 :          0 :                 dev_info = &adapter->dma_devs[i];
    1375                 :            : 
    1376         [ #  # ]:          0 :                 if (dev_info->internal_event_port == 0 ||
    1377         [ #  # ]:          0 :                     dev->dev_ops->dma_adapter_stats_get == NULL)
    1378                 :          0 :                         continue;
    1379                 :            : 
    1380                 :          0 :                 ret = dev->dev_ops->dma_adapter_stats_get(dev, i, &dev_stats);
    1381         [ #  # ]:          0 :                 if (ret)
    1382                 :          0 :                         continue;
    1383                 :            : 
    1384                 :          0 :                 dev_stats_sum.dma_deq_count += dev_stats.dma_deq_count;
    1385                 :          0 :                 dev_stats_sum.event_enq_count += dev_stats.event_enq_count;
    1386                 :            :         }
    1387                 :            : 
    1388         [ #  # ]:          0 :         if (adapter->service_initialized)
    1389                 :          0 :                 *stats = adapter->dma_stats;
    1390                 :            : 
    1391                 :          0 :         stats->dma_deq_count += dev_stats_sum.dma_deq_count;
    1392                 :          0 :         stats->event_enq_count += dev_stats_sum.event_enq_count;
    1393                 :            : 
    1394                 :          0 :         return 0;
    1395                 :            : }
    1396                 :            : 
    1397                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_stats_reset, 23.11)
    1398                 :            : int
    1399                 :          0 : rte_event_dma_adapter_stats_reset(uint8_t id)
    1400                 :            : {
    1401                 :            :         struct event_dma_adapter *adapter;
    1402                 :            :         struct dma_device_info *dev_info;
    1403                 :            :         struct rte_eventdev *dev;
    1404                 :            :         uint16_t num_dma_dev;
    1405                 :            :         uint32_t i;
    1406                 :            : 
    1407         [ #  # ]:          0 :         EVENT_DMA_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL);
    1408                 :            : 
    1409                 :            :         adapter = edma_id_to_adapter(id);
    1410         [ #  # ]:          0 :         if (adapter == NULL)
    1411                 :            :                 return -EINVAL;
    1412                 :            : 
    1413                 :          0 :         num_dma_dev = rte_dma_count_avail();
    1414                 :          0 :         dev = &rte_eventdevs[adapter->eventdev_id];
    1415         [ #  # ]:          0 :         for (i = 0; i < num_dma_dev; i++) {
    1416                 :          0 :                 dev_info = &adapter->dma_devs[i];
    1417                 :            : 
    1418         [ #  # ]:          0 :                 if (dev_info->internal_event_port == 0 ||
    1419         [ #  # ]:          0 :                     dev->dev_ops->dma_adapter_stats_reset == NULL)
    1420                 :          0 :                         continue;
    1421                 :            : 
    1422                 :          0 :                 dev->dev_ops->dma_adapter_stats_reset(dev, i);
    1423                 :            :         }
    1424                 :            : 
    1425                 :          0 :         memset(&adapter->dma_stats, 0, sizeof(adapter->dma_stats));
    1426                 :            : 
    1427                 :          0 :         return 0;
    1428                 :            : }
    1429                 :            : 
    1430                 :            : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_event_dma_adapter_enqueue, 23.11)
    1431                 :            : uint16_t
    1432                 :          0 : rte_event_dma_adapter_enqueue(uint8_t dev_id, uint8_t port_id, struct rte_event ev[],
    1433                 :            :                               uint16_t nb_events)
    1434                 :            : {
    1435                 :            :         const struct rte_event_fp_ops *fp_ops;
    1436                 :            :         void *port;
    1437                 :            : 
    1438                 :          0 :         fp_ops = &rte_event_fp_ops[dev_id];
    1439                 :          0 :         port = fp_ops->data[port_id];
    1440                 :            : 
    1441                 :          0 :         return fp_ops->dma_enqueue(port, ev, nb_events);
    1442                 :            : }

Generated by: LCOV version 1.14