mempool: fix slow allocation of large mempools
[dpdk.git] / lib / librte_eventdev / rte_eventdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016 Cavium, Inc
3  */
4
5 #include <ctype.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <stdarg.h>
10 #include <errno.h>
11 #include <stdint.h>
12 #include <inttypes.h>
13 #include <sys/types.h>
14 #include <sys/queue.h>
15
16 #include <rte_string_fns.h>
17 #include <rte_byteorder.h>
18 #include <rte_log.h>
19 #include <rte_debug.h>
20 #include <rte_dev.h>
21 #include <rte_memory.h>
22 #include <rte_memcpy.h>
23 #include <rte_memzone.h>
24 #include <rte_eal.h>
25 #include <rte_per_lcore.h>
26 #include <rte_lcore.h>
27 #include <rte_atomic.h>
28 #include <rte_branch_prediction.h>
29 #include <rte_common.h>
30 #include <rte_malloc.h>
31 #include <rte_errno.h>
32 #include <rte_ethdev.h>
33 #include <rte_cryptodev.h>
34 #include <rte_cryptodev_pmd.h>
35
36 #include "rte_eventdev.h"
37 #include "rte_eventdev_pmd.h"
38
39 static struct rte_eventdev rte_event_devices[RTE_EVENT_MAX_DEVS];
40
41 struct rte_eventdev *rte_eventdevs = rte_event_devices;
42
43 static struct rte_eventdev_global eventdev_globals = {
44         .nb_devs                = 0
45 };
46
47 /* Event dev north bound API implementation */
48
49 uint8_t
50 rte_event_dev_count(void)
51 {
52         return eventdev_globals.nb_devs;
53 }
54
55 int
56 rte_event_dev_get_dev_id(const char *name)
57 {
58         int i;
59         uint8_t cmp;
60
61         if (!name)
62                 return -EINVAL;
63
64         for (i = 0; i < eventdev_globals.nb_devs; i++) {
65                 cmp = (strncmp(rte_event_devices[i].data->name, name,
66                                 RTE_EVENTDEV_NAME_MAX_LEN) == 0) ||
67                         (rte_event_devices[i].dev ? (strncmp(
68                                 rte_event_devices[i].dev->driver->name, name,
69                                          RTE_EVENTDEV_NAME_MAX_LEN) == 0) : 0);
70                 if (cmp && (rte_event_devices[i].attached ==
71                                         RTE_EVENTDEV_ATTACHED))
72                         return i;
73         }
74         return -ENODEV;
75 }
76
77 int
78 rte_event_dev_socket_id(uint8_t dev_id)
79 {
80         struct rte_eventdev *dev;
81
82         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
83         dev = &rte_eventdevs[dev_id];
84
85         return dev->data->socket_id;
86 }
87
88 int
89 rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info)
90 {
91         struct rte_eventdev *dev;
92
93         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
94         dev = &rte_eventdevs[dev_id];
95
96         if (dev_info == NULL)
97                 return -EINVAL;
98
99         memset(dev_info, 0, sizeof(struct rte_event_dev_info));
100
101         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
102         (*dev->dev_ops->dev_infos_get)(dev, dev_info);
103
104         dev_info->dequeue_timeout_ns = dev->data->dev_conf.dequeue_timeout_ns;
105
106         dev_info->dev = dev->dev;
107         return 0;
108 }
109
110 int
111 rte_event_eth_rx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
112                                 uint32_t *caps)
113 {
114         struct rte_eventdev *dev;
115
116         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
117         RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_port_id, -EINVAL);
118
119         dev = &rte_eventdevs[dev_id];
120
121         if (caps == NULL)
122                 return -EINVAL;
123         *caps = 0;
124
125         return dev->dev_ops->eth_rx_adapter_caps_get ?
126                                 (*dev->dev_ops->eth_rx_adapter_caps_get)(dev,
127                                                 &rte_eth_devices[eth_port_id],
128                                                 caps)
129                                 : 0;
130 }
131
132 int
133 rte_event_timer_adapter_caps_get(uint8_t dev_id, uint32_t *caps)
134 {
135         struct rte_eventdev *dev;
136         const struct rte_event_timer_adapter_ops *ops;
137
138         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
139
140         dev = &rte_eventdevs[dev_id];
141
142         if (caps == NULL)
143                 return -EINVAL;
144         *caps = 0;
145
146         return dev->dev_ops->timer_adapter_caps_get ?
147                                 (*dev->dev_ops->timer_adapter_caps_get)(dev,
148                                                                         0,
149                                                                         caps,
150                                                                         &ops)
151                                 : 0;
152 }
153
154 int
155 rte_event_crypto_adapter_caps_get(uint8_t dev_id, uint8_t cdev_id,
156                                   uint32_t *caps)
157 {
158         struct rte_eventdev *dev;
159         struct rte_cryptodev *cdev;
160
161         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
162         if (!rte_cryptodev_pmd_is_valid_dev(cdev_id))
163                 return -EINVAL;
164
165         dev = &rte_eventdevs[dev_id];
166         cdev = rte_cryptodev_pmd_get_dev(cdev_id);
167
168         if (caps == NULL)
169                 return -EINVAL;
170         *caps = 0;
171
172         return dev->dev_ops->crypto_adapter_caps_get ?
173                 (*dev->dev_ops->crypto_adapter_caps_get)
174                 (dev, cdev, caps) : -ENOTSUP;
175 }
176
177 int
178 rte_event_eth_tx_adapter_caps_get(uint8_t dev_id, uint16_t eth_port_id,
179                                 uint32_t *caps)
180 {
181         struct rte_eventdev *dev;
182         struct rte_eth_dev *eth_dev;
183
184         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
185         RTE_ETH_VALID_PORTID_OR_ERR_RET(eth_port_id, -EINVAL);
186
187         dev = &rte_eventdevs[dev_id];
188         eth_dev = &rte_eth_devices[eth_port_id];
189
190         if (caps == NULL)
191                 return -EINVAL;
192
193         *caps = 0;
194
195         return dev->dev_ops->eth_tx_adapter_caps_get ?
196                         (*dev->dev_ops->eth_tx_adapter_caps_get)(dev,
197                                                                 eth_dev,
198                                                                 caps)
199                         : 0;
200 }
201
202 static inline int
203 rte_event_dev_queue_config(struct rte_eventdev *dev, uint8_t nb_queues)
204 {
205         uint8_t old_nb_queues = dev->data->nb_queues;
206         struct rte_event_queue_conf *queues_cfg;
207         unsigned int i;
208
209         RTE_EDEV_LOG_DEBUG("Setup %d queues on device %u", nb_queues,
210                          dev->data->dev_id);
211
212         /* First time configuration */
213         if (dev->data->queues_cfg == NULL && nb_queues != 0) {
214                 /* Allocate memory to store queue configuration */
215                 dev->data->queues_cfg = rte_zmalloc_socket(
216                                 "eventdev->data->queues_cfg",
217                                 sizeof(dev->data->queues_cfg[0]) * nb_queues,
218                                 RTE_CACHE_LINE_SIZE, dev->data->socket_id);
219                 if (dev->data->queues_cfg == NULL) {
220                         dev->data->nb_queues = 0;
221                         RTE_EDEV_LOG_ERR("failed to get mem for queue cfg,"
222                                         "nb_queues %u", nb_queues);
223                         return -(ENOMEM);
224                 }
225         /* Re-configure */
226         } else if (dev->data->queues_cfg != NULL && nb_queues != 0) {
227                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_release, -ENOTSUP);
228
229                 for (i = nb_queues; i < old_nb_queues; i++)
230                         (*dev->dev_ops->queue_release)(dev, i);
231
232                 /* Re allocate memory to store queue configuration */
233                 queues_cfg = dev->data->queues_cfg;
234                 queues_cfg = rte_realloc(queues_cfg,
235                                 sizeof(queues_cfg[0]) * nb_queues,
236                                 RTE_CACHE_LINE_SIZE);
237                 if (queues_cfg == NULL) {
238                         RTE_EDEV_LOG_ERR("failed to realloc queue cfg memory,"
239                                                 " nb_queues %u", nb_queues);
240                         return -(ENOMEM);
241                 }
242                 dev->data->queues_cfg = queues_cfg;
243
244                 if (nb_queues > old_nb_queues) {
245                         uint8_t new_qs = nb_queues - old_nb_queues;
246
247                         memset(queues_cfg + old_nb_queues, 0,
248                                 sizeof(queues_cfg[0]) * new_qs);
249                 }
250         } else if (dev->data->queues_cfg != NULL && nb_queues == 0) {
251                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_release, -ENOTSUP);
252
253                 for (i = nb_queues; i < old_nb_queues; i++)
254                         (*dev->dev_ops->queue_release)(dev, i);
255         }
256
257         dev->data->nb_queues = nb_queues;
258         return 0;
259 }
260
261 #define EVENT_QUEUE_SERVICE_PRIORITY_INVALID (0xdead)
262
263 static inline int
264 rte_event_dev_port_config(struct rte_eventdev *dev, uint8_t nb_ports)
265 {
266         uint8_t old_nb_ports = dev->data->nb_ports;
267         void **ports;
268         uint16_t *links_map;
269         struct rte_event_port_conf *ports_cfg;
270         unsigned int i;
271
272         RTE_EDEV_LOG_DEBUG("Setup %d ports on device %u", nb_ports,
273                          dev->data->dev_id);
274
275         /* First time configuration */
276         if (dev->data->ports == NULL && nb_ports != 0) {
277                 dev->data->ports = rte_zmalloc_socket("eventdev->data->ports",
278                                 sizeof(dev->data->ports[0]) * nb_ports,
279                                 RTE_CACHE_LINE_SIZE, dev->data->socket_id);
280                 if (dev->data->ports == NULL) {
281                         dev->data->nb_ports = 0;
282                         RTE_EDEV_LOG_ERR("failed to get mem for port meta data,"
283                                         "nb_ports %u", nb_ports);
284                         return -(ENOMEM);
285                 }
286
287                 /* Allocate memory to store port configurations */
288                 dev->data->ports_cfg =
289                         rte_zmalloc_socket("eventdev->ports_cfg",
290                         sizeof(dev->data->ports_cfg[0]) * nb_ports,
291                         RTE_CACHE_LINE_SIZE, dev->data->socket_id);
292                 if (dev->data->ports_cfg == NULL) {
293                         dev->data->nb_ports = 0;
294                         RTE_EDEV_LOG_ERR("failed to get mem for port cfg,"
295                                         "nb_ports %u", nb_ports);
296                         return -(ENOMEM);
297                 }
298
299                 /* Allocate memory to store queue to port link connection */
300                 dev->data->links_map =
301                         rte_zmalloc_socket("eventdev->links_map",
302                         sizeof(dev->data->links_map[0]) * nb_ports *
303                         RTE_EVENT_MAX_QUEUES_PER_DEV,
304                         RTE_CACHE_LINE_SIZE, dev->data->socket_id);
305                 if (dev->data->links_map == NULL) {
306                         dev->data->nb_ports = 0;
307                         RTE_EDEV_LOG_ERR("failed to get mem for port_map area,"
308                                         "nb_ports %u", nb_ports);
309                         return -(ENOMEM);
310                 }
311                 for (i = 0; i < nb_ports * RTE_EVENT_MAX_QUEUES_PER_DEV; i++)
312                         dev->data->links_map[i] =
313                                 EVENT_QUEUE_SERVICE_PRIORITY_INVALID;
314         } else if (dev->data->ports != NULL && nb_ports != 0) {/* re-config */
315                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_release, -ENOTSUP);
316
317                 ports = dev->data->ports;
318                 ports_cfg = dev->data->ports_cfg;
319                 links_map = dev->data->links_map;
320
321                 for (i = nb_ports; i < old_nb_ports; i++)
322                         (*dev->dev_ops->port_release)(ports[i]);
323
324                 /* Realloc memory for ports */
325                 ports = rte_realloc(ports, sizeof(ports[0]) * nb_ports,
326                                 RTE_CACHE_LINE_SIZE);
327                 if (ports == NULL) {
328                         RTE_EDEV_LOG_ERR("failed to realloc port meta data,"
329                                                 " nb_ports %u", nb_ports);
330                         return -(ENOMEM);
331                 }
332
333                 /* Realloc memory for ports_cfg */
334                 ports_cfg = rte_realloc(ports_cfg,
335                         sizeof(ports_cfg[0]) * nb_ports,
336                         RTE_CACHE_LINE_SIZE);
337                 if (ports_cfg == NULL) {
338                         RTE_EDEV_LOG_ERR("failed to realloc port cfg mem,"
339                                                 " nb_ports %u", nb_ports);
340                         return -(ENOMEM);
341                 }
342
343                 /* Realloc memory to store queue to port link connection */
344                 links_map = rte_realloc(links_map,
345                         sizeof(dev->data->links_map[0]) * nb_ports *
346                         RTE_EVENT_MAX_QUEUES_PER_DEV,
347                         RTE_CACHE_LINE_SIZE);
348                 if (links_map == NULL) {
349                         dev->data->nb_ports = 0;
350                         RTE_EDEV_LOG_ERR("failed to realloc mem for port_map,"
351                                         "nb_ports %u", nb_ports);
352                         return -(ENOMEM);
353                 }
354
355                 if (nb_ports > old_nb_ports) {
356                         uint8_t new_ps = nb_ports - old_nb_ports;
357                         unsigned int old_links_map_end =
358                                 old_nb_ports * RTE_EVENT_MAX_QUEUES_PER_DEV;
359                         unsigned int links_map_end =
360                                 nb_ports * RTE_EVENT_MAX_QUEUES_PER_DEV;
361
362                         memset(ports + old_nb_ports, 0,
363                                 sizeof(ports[0]) * new_ps);
364                         memset(ports_cfg + old_nb_ports, 0,
365                                 sizeof(ports_cfg[0]) * new_ps);
366                         for (i = old_links_map_end; i < links_map_end; i++)
367                                 links_map[i] =
368                                         EVENT_QUEUE_SERVICE_PRIORITY_INVALID;
369                 }
370
371                 dev->data->ports = ports;
372                 dev->data->ports_cfg = ports_cfg;
373                 dev->data->links_map = links_map;
374         } else if (dev->data->ports != NULL && nb_ports == 0) {
375                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_release, -ENOTSUP);
376
377                 ports = dev->data->ports;
378                 for (i = nb_ports; i < old_nb_ports; i++)
379                         (*dev->dev_ops->port_release)(ports[i]);
380         }
381
382         dev->data->nb_ports = nb_ports;
383         return 0;
384 }
385
386 int
387 rte_event_dev_configure(uint8_t dev_id,
388                         const struct rte_event_dev_config *dev_conf)
389 {
390         struct rte_eventdev *dev;
391         struct rte_event_dev_info info;
392         int diag;
393
394         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
395         dev = &rte_eventdevs[dev_id];
396
397         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
398         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
399
400         if (dev->data->dev_started) {
401                 RTE_EDEV_LOG_ERR(
402                     "device %d must be stopped to allow configuration", dev_id);
403                 return -EBUSY;
404         }
405
406         if (dev_conf == NULL)
407                 return -EINVAL;
408
409         (*dev->dev_ops->dev_infos_get)(dev, &info);
410
411         /* Check dequeue_timeout_ns value is in limit */
412         if (!(dev_conf->event_dev_cfg & RTE_EVENT_DEV_CFG_PER_DEQUEUE_TIMEOUT)) {
413                 if (dev_conf->dequeue_timeout_ns &&
414                     (dev_conf->dequeue_timeout_ns < info.min_dequeue_timeout_ns
415                         || dev_conf->dequeue_timeout_ns >
416                                  info.max_dequeue_timeout_ns)) {
417                         RTE_EDEV_LOG_ERR("dev%d invalid dequeue_timeout_ns=%d"
418                         " min_dequeue_timeout_ns=%d max_dequeue_timeout_ns=%d",
419                         dev_id, dev_conf->dequeue_timeout_ns,
420                         info.min_dequeue_timeout_ns,
421                         info.max_dequeue_timeout_ns);
422                         return -EINVAL;
423                 }
424         }
425
426         /* Check nb_events_limit is in limit */
427         if (dev_conf->nb_events_limit > info.max_num_events) {
428                 RTE_EDEV_LOG_ERR("dev%d nb_events_limit=%d > max_num_events=%d",
429                 dev_id, dev_conf->nb_events_limit, info.max_num_events);
430                 return -EINVAL;
431         }
432
433         /* Check nb_event_queues is in limit */
434         if (!dev_conf->nb_event_queues) {
435                 RTE_EDEV_LOG_ERR("dev%d nb_event_queues cannot be zero",
436                                         dev_id);
437                 return -EINVAL;
438         }
439         if (dev_conf->nb_event_queues > info.max_event_queues) {
440                 RTE_EDEV_LOG_ERR("%d nb_event_queues=%d > max_event_queues=%d",
441                 dev_id, dev_conf->nb_event_queues, info.max_event_queues);
442                 return -EINVAL;
443         }
444
445         /* Check nb_event_ports is in limit */
446         if (!dev_conf->nb_event_ports) {
447                 RTE_EDEV_LOG_ERR("dev%d nb_event_ports cannot be zero", dev_id);
448                 return -EINVAL;
449         }
450         if (dev_conf->nb_event_ports > info.max_event_ports) {
451                 RTE_EDEV_LOG_ERR("id%d nb_event_ports=%d > max_event_ports= %d",
452                 dev_id, dev_conf->nb_event_ports, info.max_event_ports);
453                 return -EINVAL;
454         }
455
456         /* Check nb_event_queue_flows is in limit */
457         if (!dev_conf->nb_event_queue_flows) {
458                 RTE_EDEV_LOG_ERR("dev%d nb_flows cannot be zero", dev_id);
459                 return -EINVAL;
460         }
461         if (dev_conf->nb_event_queue_flows > info.max_event_queue_flows) {
462                 RTE_EDEV_LOG_ERR("dev%d nb_flows=%x > max_flows=%x",
463                 dev_id, dev_conf->nb_event_queue_flows,
464                 info.max_event_queue_flows);
465                 return -EINVAL;
466         }
467
468         /* Check nb_event_port_dequeue_depth is in limit */
469         if (!dev_conf->nb_event_port_dequeue_depth) {
470                 RTE_EDEV_LOG_ERR("dev%d nb_dequeue_depth cannot be zero",
471                                         dev_id);
472                 return -EINVAL;
473         }
474         if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) &&
475                  (dev_conf->nb_event_port_dequeue_depth >
476                          info.max_event_port_dequeue_depth)) {
477                 RTE_EDEV_LOG_ERR("dev%d nb_dq_depth=%d > max_dq_depth=%d",
478                 dev_id, dev_conf->nb_event_port_dequeue_depth,
479                 info.max_event_port_dequeue_depth);
480                 return -EINVAL;
481         }
482
483         /* Check nb_event_port_enqueue_depth is in limit */
484         if (!dev_conf->nb_event_port_enqueue_depth) {
485                 RTE_EDEV_LOG_ERR("dev%d nb_enqueue_depth cannot be zero",
486                                         dev_id);
487                 return -EINVAL;
488         }
489         if ((info.event_dev_cap & RTE_EVENT_DEV_CAP_BURST_MODE) &&
490                 (dev_conf->nb_event_port_enqueue_depth >
491                          info.max_event_port_enqueue_depth)) {
492                 RTE_EDEV_LOG_ERR("dev%d nb_enq_depth=%d > max_enq_depth=%d",
493                 dev_id, dev_conf->nb_event_port_enqueue_depth,
494                 info.max_event_port_enqueue_depth);
495                 return -EINVAL;
496         }
497
498         /* Copy the dev_conf parameter into the dev structure */
499         memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf));
500
501         /* Setup new number of queues and reconfigure device. */
502         diag = rte_event_dev_queue_config(dev, dev_conf->nb_event_queues);
503         if (diag != 0) {
504                 RTE_EDEV_LOG_ERR("dev%d rte_event_dev_queue_config = %d",
505                                 dev_id, diag);
506                 return diag;
507         }
508
509         /* Setup new number of ports and reconfigure device. */
510         diag = rte_event_dev_port_config(dev, dev_conf->nb_event_ports);
511         if (diag != 0) {
512                 rte_event_dev_queue_config(dev, 0);
513                 RTE_EDEV_LOG_ERR("dev%d rte_event_dev_port_config = %d",
514                                 dev_id, diag);
515                 return diag;
516         }
517
518         /* Configure the device */
519         diag = (*dev->dev_ops->dev_configure)(dev);
520         if (diag != 0) {
521                 RTE_EDEV_LOG_ERR("dev%d dev_configure = %d", dev_id, diag);
522                 rte_event_dev_queue_config(dev, 0);
523                 rte_event_dev_port_config(dev, 0);
524         }
525
526         dev->data->event_dev_cap = info.event_dev_cap;
527         return diag;
528 }
529
530 static inline int
531 is_valid_queue(struct rte_eventdev *dev, uint8_t queue_id)
532 {
533         if (queue_id < dev->data->nb_queues && queue_id <
534                                 RTE_EVENT_MAX_QUEUES_PER_DEV)
535                 return 1;
536         else
537                 return 0;
538 }
539
540 int
541 rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id,
542                                  struct rte_event_queue_conf *queue_conf)
543 {
544         struct rte_eventdev *dev;
545
546         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
547         dev = &rte_eventdevs[dev_id];
548
549         if (queue_conf == NULL)
550                 return -EINVAL;
551
552         if (!is_valid_queue(dev, queue_id)) {
553                 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id);
554                 return -EINVAL;
555         }
556
557         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf, -ENOTSUP);
558         memset(queue_conf, 0, sizeof(struct rte_event_queue_conf));
559         (*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf);
560         return 0;
561 }
562
563 static inline int
564 is_valid_atomic_queue_conf(const struct rte_event_queue_conf *queue_conf)
565 {
566         if (queue_conf &&
567                 !(queue_conf->event_queue_cfg &
568                   RTE_EVENT_QUEUE_CFG_SINGLE_LINK) &&
569                 ((queue_conf->event_queue_cfg &
570                          RTE_EVENT_QUEUE_CFG_ALL_TYPES) ||
571                 (queue_conf->schedule_type
572                         == RTE_SCHED_TYPE_ATOMIC)
573                 ))
574                 return 1;
575         else
576                 return 0;
577 }
578
579 static inline int
580 is_valid_ordered_queue_conf(const struct rte_event_queue_conf *queue_conf)
581 {
582         if (queue_conf &&
583                 !(queue_conf->event_queue_cfg &
584                   RTE_EVENT_QUEUE_CFG_SINGLE_LINK) &&
585                 ((queue_conf->event_queue_cfg &
586                          RTE_EVENT_QUEUE_CFG_ALL_TYPES) ||
587                 (queue_conf->schedule_type
588                         == RTE_SCHED_TYPE_ORDERED)
589                 ))
590                 return 1;
591         else
592                 return 0;
593 }
594
595
596 int
597 rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
598                       const struct rte_event_queue_conf *queue_conf)
599 {
600         struct rte_eventdev *dev;
601         struct rte_event_queue_conf def_conf;
602
603         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
604         dev = &rte_eventdevs[dev_id];
605
606         if (!is_valid_queue(dev, queue_id)) {
607                 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id);
608                 return -EINVAL;
609         }
610
611         /* Check nb_atomic_flows limit */
612         if (is_valid_atomic_queue_conf(queue_conf)) {
613                 if (queue_conf->nb_atomic_flows == 0 ||
614                     queue_conf->nb_atomic_flows >
615                         dev->data->dev_conf.nb_event_queue_flows) {
616                         RTE_EDEV_LOG_ERR(
617                 "dev%d queue%d Invalid nb_atomic_flows=%d max_flows=%d",
618                         dev_id, queue_id, queue_conf->nb_atomic_flows,
619                         dev->data->dev_conf.nb_event_queue_flows);
620                         return -EINVAL;
621                 }
622         }
623
624         /* Check nb_atomic_order_sequences limit */
625         if (is_valid_ordered_queue_conf(queue_conf)) {
626                 if (queue_conf->nb_atomic_order_sequences == 0 ||
627                     queue_conf->nb_atomic_order_sequences >
628                         dev->data->dev_conf.nb_event_queue_flows) {
629                         RTE_EDEV_LOG_ERR(
630                 "dev%d queue%d Invalid nb_atomic_order_seq=%d max_flows=%d",
631                         dev_id, queue_id, queue_conf->nb_atomic_order_sequences,
632                         dev->data->dev_conf.nb_event_queue_flows);
633                         return -EINVAL;
634                 }
635         }
636
637         if (dev->data->dev_started) {
638                 RTE_EDEV_LOG_ERR(
639                     "device %d must be stopped to allow queue setup", dev_id);
640                 return -EBUSY;
641         }
642
643         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_setup, -ENOTSUP);
644
645         if (queue_conf == NULL) {
646                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf,
647                                         -ENOTSUP);
648                 (*dev->dev_ops->queue_def_conf)(dev, queue_id, &def_conf);
649                 queue_conf = &def_conf;
650         }
651
652         dev->data->queues_cfg[queue_id] = *queue_conf;
653         return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf);
654 }
655
656 static inline int
657 is_valid_port(struct rte_eventdev *dev, uint8_t port_id)
658 {
659         if (port_id < dev->data->nb_ports)
660                 return 1;
661         else
662                 return 0;
663 }
664
665 int
666 rte_event_port_default_conf_get(uint8_t dev_id, uint8_t port_id,
667                                  struct rte_event_port_conf *port_conf)
668 {
669         struct rte_eventdev *dev;
670
671         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
672         dev = &rte_eventdevs[dev_id];
673
674         if (port_conf == NULL)
675                 return -EINVAL;
676
677         if (!is_valid_port(dev, port_id)) {
678                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
679                 return -EINVAL;
680         }
681
682         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_def_conf, -ENOTSUP);
683         memset(port_conf, 0, sizeof(struct rte_event_port_conf));
684         (*dev->dev_ops->port_def_conf)(dev, port_id, port_conf);
685         return 0;
686 }
687
688 int
689 rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
690                      const struct rte_event_port_conf *port_conf)
691 {
692         struct rte_eventdev *dev;
693         struct rte_event_port_conf def_conf;
694         int diag;
695
696         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
697         dev = &rte_eventdevs[dev_id];
698
699         if (!is_valid_port(dev, port_id)) {
700                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
701                 return -EINVAL;
702         }
703
704         /* Check new_event_threshold limit */
705         if ((port_conf && !port_conf->new_event_threshold) ||
706                         (port_conf && port_conf->new_event_threshold >
707                                  dev->data->dev_conf.nb_events_limit)) {
708                 RTE_EDEV_LOG_ERR(
709                    "dev%d port%d Invalid event_threshold=%d nb_events_limit=%d",
710                         dev_id, port_id, port_conf->new_event_threshold,
711                         dev->data->dev_conf.nb_events_limit);
712                 return -EINVAL;
713         }
714
715         /* Check dequeue_depth limit */
716         if ((port_conf && !port_conf->dequeue_depth) ||
717                         (port_conf && port_conf->dequeue_depth >
718                 dev->data->dev_conf.nb_event_port_dequeue_depth)) {
719                 RTE_EDEV_LOG_ERR(
720                    "dev%d port%d Invalid dequeue depth=%d max_dequeue_depth=%d",
721                         dev_id, port_id, port_conf->dequeue_depth,
722                         dev->data->dev_conf.nb_event_port_dequeue_depth);
723                 return -EINVAL;
724         }
725
726         /* Check enqueue_depth limit */
727         if ((port_conf && !port_conf->enqueue_depth) ||
728                         (port_conf && port_conf->enqueue_depth >
729                 dev->data->dev_conf.nb_event_port_enqueue_depth)) {
730                 RTE_EDEV_LOG_ERR(
731                    "dev%d port%d Invalid enqueue depth=%d max_enqueue_depth=%d",
732                         dev_id, port_id, port_conf->enqueue_depth,
733                         dev->data->dev_conf.nb_event_port_enqueue_depth);
734                 return -EINVAL;
735         }
736
737         if (port_conf && port_conf->disable_implicit_release &&
738             !(dev->data->event_dev_cap &
739               RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE)) {
740                 RTE_EDEV_LOG_ERR(
741                    "dev%d port%d Implicit release disable not supported",
742                         dev_id, port_id);
743                 return -EINVAL;
744         }
745
746         if (dev->data->dev_started) {
747                 RTE_EDEV_LOG_ERR(
748                     "device %d must be stopped to allow port setup", dev_id);
749                 return -EBUSY;
750         }
751
752         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_setup, -ENOTSUP);
753
754         if (port_conf == NULL) {
755                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_def_conf,
756                                         -ENOTSUP);
757                 (*dev->dev_ops->port_def_conf)(dev, port_id, &def_conf);
758                 port_conf = &def_conf;
759         }
760
761         dev->data->ports_cfg[port_id] = *port_conf;
762
763         diag = (*dev->dev_ops->port_setup)(dev, port_id, port_conf);
764
765         /* Unlink all the queues from this port(default state after setup) */
766         if (!diag)
767                 diag = rte_event_port_unlink(dev_id, port_id, NULL, 0);
768
769         if (diag < 0)
770                 return diag;
771
772         return 0;
773 }
774
775 int
776 rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id,
777                        uint32_t *attr_value)
778 {
779         struct rte_eventdev *dev;
780
781         if (!attr_value)
782                 return -EINVAL;
783         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
784         dev = &rte_eventdevs[dev_id];
785
786         switch (attr_id) {
787         case RTE_EVENT_DEV_ATTR_PORT_COUNT:
788                 *attr_value = dev->data->nb_ports;
789                 break;
790         case RTE_EVENT_DEV_ATTR_QUEUE_COUNT:
791                 *attr_value = dev->data->nb_queues;
792                 break;
793         case RTE_EVENT_DEV_ATTR_STARTED:
794                 *attr_value = dev->data->dev_started;
795                 break;
796         default:
797                 return -EINVAL;
798         }
799
800         return 0;
801 }
802
803 int
804 rte_event_port_attr_get(uint8_t dev_id, uint8_t port_id, uint32_t attr_id,
805                         uint32_t *attr_value)
806 {
807         struct rte_eventdev *dev;
808
809         if (!attr_value)
810                 return -EINVAL;
811
812         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
813         dev = &rte_eventdevs[dev_id];
814         if (!is_valid_port(dev, port_id)) {
815                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
816                 return -EINVAL;
817         }
818
819         switch (attr_id) {
820         case RTE_EVENT_PORT_ATTR_ENQ_DEPTH:
821                 *attr_value = dev->data->ports_cfg[port_id].enqueue_depth;
822                 break;
823         case RTE_EVENT_PORT_ATTR_DEQ_DEPTH:
824                 *attr_value = dev->data->ports_cfg[port_id].dequeue_depth;
825                 break;
826         case RTE_EVENT_PORT_ATTR_NEW_EVENT_THRESHOLD:
827                 *attr_value = dev->data->ports_cfg[port_id].new_event_threshold;
828                 break;
829         default:
830                 return -EINVAL;
831         };
832         return 0;
833 }
834
835 int
836 rte_event_queue_attr_get(uint8_t dev_id, uint8_t queue_id, uint32_t attr_id,
837                         uint32_t *attr_value)
838 {
839         struct rte_event_queue_conf *conf;
840         struct rte_eventdev *dev;
841
842         if (!attr_value)
843                 return -EINVAL;
844
845         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
846         dev = &rte_eventdevs[dev_id];
847         if (!is_valid_queue(dev, queue_id)) {
848                 RTE_EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id);
849                 return -EINVAL;
850         }
851
852         conf = &dev->data->queues_cfg[queue_id];
853
854         switch (attr_id) {
855         case RTE_EVENT_QUEUE_ATTR_PRIORITY:
856                 *attr_value = RTE_EVENT_DEV_PRIORITY_NORMAL;
857                 if (dev->data->event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS)
858                         *attr_value = conf->priority;
859                 break;
860         case RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_FLOWS:
861                 *attr_value = conf->nb_atomic_flows;
862                 break;
863         case RTE_EVENT_QUEUE_ATTR_NB_ATOMIC_ORDER_SEQUENCES:
864                 *attr_value = conf->nb_atomic_order_sequences;
865                 break;
866         case RTE_EVENT_QUEUE_ATTR_EVENT_QUEUE_CFG:
867                 *attr_value = conf->event_queue_cfg;
868                 break;
869         case RTE_EVENT_QUEUE_ATTR_SCHEDULE_TYPE:
870                 if (conf->event_queue_cfg & RTE_EVENT_QUEUE_CFG_ALL_TYPES)
871                         return -EOVERFLOW;
872
873                 *attr_value = conf->schedule_type;
874                 break;
875         default:
876                 return -EINVAL;
877         };
878         return 0;
879 }
880
881 int
882 rte_event_port_link(uint8_t dev_id, uint8_t port_id,
883                     const uint8_t queues[], const uint8_t priorities[],
884                     uint16_t nb_links)
885 {
886         struct rte_eventdev *dev;
887         uint8_t queues_list[RTE_EVENT_MAX_QUEUES_PER_DEV];
888         uint8_t priorities_list[RTE_EVENT_MAX_QUEUES_PER_DEV];
889         uint16_t *links_map;
890         int i, diag;
891
892         RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, EINVAL, 0);
893         dev = &rte_eventdevs[dev_id];
894
895         if (*dev->dev_ops->port_link == NULL) {
896                 RTE_EDEV_LOG_ERR("Function not supported\n");
897                 rte_errno = ENOTSUP;
898                 return 0;
899         }
900
901         if (!is_valid_port(dev, port_id)) {
902                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
903                 rte_errno = EINVAL;
904                 return 0;
905         }
906
907         if (queues == NULL) {
908                 for (i = 0; i < dev->data->nb_queues; i++)
909                         queues_list[i] = i;
910
911                 queues = queues_list;
912                 nb_links = dev->data->nb_queues;
913         }
914
915         if (priorities == NULL) {
916                 for (i = 0; i < nb_links; i++)
917                         priorities_list[i] = RTE_EVENT_DEV_PRIORITY_NORMAL;
918
919                 priorities = priorities_list;
920         }
921
922         for (i = 0; i < nb_links; i++)
923                 if (queues[i] >= dev->data->nb_queues) {
924                         rte_errno = EINVAL;
925                         return 0;
926                 }
927
928         diag = (*dev->dev_ops->port_link)(dev, dev->data->ports[port_id],
929                                                 queues, priorities, nb_links);
930         if (diag < 0)
931                 return diag;
932
933         links_map = dev->data->links_map;
934         /* Point links_map to this port specific area */
935         links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);
936         for (i = 0; i < diag; i++)
937                 links_map[queues[i]] = (uint8_t)priorities[i];
938
939         return diag;
940 }
941
942 int
943 rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
944                       uint8_t queues[], uint16_t nb_unlinks)
945 {
946         struct rte_eventdev *dev;
947         uint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV];
948         int i, diag, j;
949         uint16_t *links_map;
950
951         RTE_EVENTDEV_VALID_DEVID_OR_ERRNO_RET(dev_id, EINVAL, 0);
952         dev = &rte_eventdevs[dev_id];
953
954         if (*dev->dev_ops->port_unlink == NULL) {
955                 RTE_EDEV_LOG_ERR("Function not supported");
956                 rte_errno = ENOTSUP;
957                 return 0;
958         }
959
960         if (!is_valid_port(dev, port_id)) {
961                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
962                 rte_errno = EINVAL;
963                 return 0;
964         }
965
966         links_map = dev->data->links_map;
967         /* Point links_map to this port specific area */
968         links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);
969
970         if (queues == NULL) {
971                 j = 0;
972                 for (i = 0; i < dev->data->nb_queues; i++) {
973                         if (links_map[i] !=
974                                         EVENT_QUEUE_SERVICE_PRIORITY_INVALID) {
975                                 all_queues[j] = i;
976                                 j++;
977                         }
978                 }
979                 queues = all_queues;
980         } else {
981                 for (j = 0; j < nb_unlinks; j++) {
982                         if (links_map[queues[j]] ==
983                                         EVENT_QUEUE_SERVICE_PRIORITY_INVALID)
984                                 break;
985                 }
986         }
987
988         nb_unlinks = j;
989         for (i = 0; i < nb_unlinks; i++)
990                 if (queues[i] >= dev->data->nb_queues) {
991                         rte_errno = EINVAL;
992                         return 0;
993                 }
994
995         diag = (*dev->dev_ops->port_unlink)(dev, dev->data->ports[port_id],
996                                         queues, nb_unlinks);
997
998         if (diag < 0)
999                 return diag;
1000
1001         for (i = 0; i < diag; i++)
1002                 links_map[queues[i]] = EVENT_QUEUE_SERVICE_PRIORITY_INVALID;
1003
1004         return diag;
1005 }
1006
1007 int
1008 rte_event_port_unlinks_in_progress(uint8_t dev_id, uint8_t port_id)
1009 {
1010         struct rte_eventdev *dev;
1011
1012         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1013         dev = &rte_eventdevs[dev_id];
1014         if (!is_valid_port(dev, port_id)) {
1015                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
1016                 return -EINVAL;
1017         }
1018
1019         /* Return 0 if the PMD does not implement unlinks in progress.
1020          * This allows PMDs which handle unlink synchronously to not implement
1021          * this function at all.
1022          */
1023         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_unlinks_in_progress, 0);
1024
1025         return (*dev->dev_ops->port_unlinks_in_progress)(dev,
1026                         dev->data->ports[port_id]);
1027 }
1028
1029 int
1030 rte_event_port_links_get(uint8_t dev_id, uint8_t port_id,
1031                          uint8_t queues[], uint8_t priorities[])
1032 {
1033         struct rte_eventdev *dev;
1034         uint16_t *links_map;
1035         int i, count = 0;
1036
1037         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1038         dev = &rte_eventdevs[dev_id];
1039         if (!is_valid_port(dev, port_id)) {
1040                 RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
1041                 return -EINVAL;
1042         }
1043
1044         links_map = dev->data->links_map;
1045         /* Point links_map to this port specific area */
1046         links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);
1047         for (i = 0; i < dev->data->nb_queues; i++) {
1048                 if (links_map[i] != EVENT_QUEUE_SERVICE_PRIORITY_INVALID) {
1049                         queues[count] = i;
1050                         priorities[count] = (uint8_t)links_map[i];
1051                         ++count;
1052                 }
1053         }
1054         return count;
1055 }
1056
1057 int
1058 rte_event_dequeue_timeout_ticks(uint8_t dev_id, uint64_t ns,
1059                                  uint64_t *timeout_ticks)
1060 {
1061         struct rte_eventdev *dev;
1062
1063         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1064         dev = &rte_eventdevs[dev_id];
1065         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->timeout_ticks, -ENOTSUP);
1066
1067         if (timeout_ticks == NULL)
1068                 return -EINVAL;
1069
1070         return (*dev->dev_ops->timeout_ticks)(dev, ns, timeout_ticks);
1071 }
1072
1073 int
1074 rte_event_dev_service_id_get(uint8_t dev_id, uint32_t *service_id)
1075 {
1076         struct rte_eventdev *dev;
1077
1078         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1079         dev = &rte_eventdevs[dev_id];
1080
1081         if (service_id == NULL)
1082                 return -EINVAL;
1083
1084         if (dev->data->service_inited)
1085                 *service_id = dev->data->service_id;
1086
1087         return dev->data->service_inited ? 0 : -ESRCH;
1088 }
1089
1090 int
1091 rte_event_dev_dump(uint8_t dev_id, FILE *f)
1092 {
1093         struct rte_eventdev *dev;
1094
1095         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1096         dev = &rte_eventdevs[dev_id];
1097         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dump, -ENOTSUP);
1098
1099         (*dev->dev_ops->dump)(dev, f);
1100         return 0;
1101
1102 }
1103
1104 static int
1105 xstats_get_count(uint8_t dev_id, enum rte_event_dev_xstats_mode mode,
1106                 uint8_t queue_port_id)
1107 {
1108         struct rte_eventdev *dev = &rte_eventdevs[dev_id];
1109         if (dev->dev_ops->xstats_get_names != NULL)
1110                 return (*dev->dev_ops->xstats_get_names)(dev, mode,
1111                                                         queue_port_id,
1112                                                         NULL, NULL, 0);
1113         return 0;
1114 }
1115
1116 int
1117 rte_event_dev_xstats_names_get(uint8_t dev_id,
1118                 enum rte_event_dev_xstats_mode mode, uint8_t queue_port_id,
1119                 struct rte_event_dev_xstats_name *xstats_names,
1120                 unsigned int *ids, unsigned int size)
1121 {
1122         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
1123         const int cnt_expected_entries = xstats_get_count(dev_id, mode,
1124                                                           queue_port_id);
1125         if (xstats_names == NULL || cnt_expected_entries < 0 ||
1126                         (int)size < cnt_expected_entries)
1127                 return cnt_expected_entries;
1128
1129         /* dev_id checked above */
1130         const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
1131
1132         if (dev->dev_ops->xstats_get_names != NULL)
1133                 return (*dev->dev_ops->xstats_get_names)(dev, mode,
1134                                 queue_port_id, xstats_names, ids, size);
1135
1136         return -ENOTSUP;
1137 }
1138
1139 /* retrieve eventdev extended statistics */
1140 int
1141 rte_event_dev_xstats_get(uint8_t dev_id, enum rte_event_dev_xstats_mode mode,
1142                 uint8_t queue_port_id, const unsigned int ids[],
1143                 uint64_t values[], unsigned int n)
1144 {
1145         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
1146         const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
1147
1148         /* implemented by the driver */
1149         if (dev->dev_ops->xstats_get != NULL)
1150                 return (*dev->dev_ops->xstats_get)(dev, mode, queue_port_id,
1151                                 ids, values, n);
1152         return -ENOTSUP;
1153 }
1154
1155 uint64_t
1156 rte_event_dev_xstats_by_name_get(uint8_t dev_id, const char *name,
1157                 unsigned int *id)
1158 {
1159         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, 0);
1160         const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
1161         unsigned int temp = -1;
1162
1163         if (id != NULL)
1164                 *id = (unsigned int)-1;
1165         else
1166                 id = &temp; /* ensure driver never gets a NULL value */
1167
1168         /* implemented by driver */
1169         if (dev->dev_ops->xstats_get_by_name != NULL)
1170                 return (*dev->dev_ops->xstats_get_by_name)(dev, name, id);
1171         return -ENOTSUP;
1172 }
1173
1174 int rte_event_dev_xstats_reset(uint8_t dev_id,
1175                 enum rte_event_dev_xstats_mode mode, int16_t queue_port_id,
1176                 const uint32_t ids[], uint32_t nb_ids)
1177 {
1178         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1179         struct rte_eventdev *dev = &rte_eventdevs[dev_id];
1180
1181         if (dev->dev_ops->xstats_reset != NULL)
1182                 return (*dev->dev_ops->xstats_reset)(dev, mode, queue_port_id,
1183                                                         ids, nb_ids);
1184         return -ENOTSUP;
1185 }
1186
1187 int rte_event_dev_selftest(uint8_t dev_id)
1188 {
1189         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1190         struct rte_eventdev *dev = &rte_eventdevs[dev_id];
1191
1192         if (dev->dev_ops->dev_selftest != NULL)
1193                 return (*dev->dev_ops->dev_selftest)();
1194         return -ENOTSUP;
1195 }
1196
1197 int
1198 rte_event_dev_start(uint8_t dev_id)
1199 {
1200         struct rte_eventdev *dev;
1201         int diag;
1202
1203         RTE_EDEV_LOG_DEBUG("Start dev_id=%" PRIu8, dev_id);
1204
1205         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1206         dev = &rte_eventdevs[dev_id];
1207         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
1208
1209         if (dev->data->dev_started != 0) {
1210                 RTE_EDEV_LOG_ERR("Device with dev_id=%" PRIu8 "already started",
1211                         dev_id);
1212                 return 0;
1213         }
1214
1215         diag = (*dev->dev_ops->dev_start)(dev);
1216         if (diag == 0)
1217                 dev->data->dev_started = 1;
1218         else
1219                 return diag;
1220
1221         return 0;
1222 }
1223
1224 int
1225 rte_event_dev_stop_flush_callback_register(uint8_t dev_id,
1226                 eventdev_stop_flush_t callback, void *userdata)
1227 {
1228         struct rte_eventdev *dev;
1229
1230         RTE_EDEV_LOG_DEBUG("Stop flush register dev_id=%" PRIu8, dev_id);
1231
1232         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1233         dev = &rte_eventdevs[dev_id];
1234
1235         dev->dev_ops->dev_stop_flush = callback;
1236         dev->data->dev_stop_flush_arg = userdata;
1237
1238         return 0;
1239 }
1240
1241 void
1242 rte_event_dev_stop(uint8_t dev_id)
1243 {
1244         struct rte_eventdev *dev;
1245
1246         RTE_EDEV_LOG_DEBUG("Stop dev_id=%" PRIu8, dev_id);
1247
1248         RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id);
1249         dev = &rte_eventdevs[dev_id];
1250         RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
1251
1252         if (dev->data->dev_started == 0) {
1253                 RTE_EDEV_LOG_ERR("Device with dev_id=%" PRIu8 "already stopped",
1254                         dev_id);
1255                 return;
1256         }
1257
1258         dev->data->dev_started = 0;
1259         (*dev->dev_ops->dev_stop)(dev);
1260 }
1261
1262 int
1263 rte_event_dev_close(uint8_t dev_id)
1264 {
1265         struct rte_eventdev *dev;
1266
1267         RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
1268         dev = &rte_eventdevs[dev_id];
1269         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
1270
1271         /* Device must be stopped before it can be closed */
1272         if (dev->data->dev_started == 1) {
1273                 RTE_EDEV_LOG_ERR("Device %u must be stopped before closing",
1274                                 dev_id);
1275                 return -EBUSY;
1276         }
1277
1278         return (*dev->dev_ops->dev_close)(dev);
1279 }
1280
1281 static inline int
1282 rte_eventdev_data_alloc(uint8_t dev_id, struct rte_eventdev_data **data,
1283                 int socket_id)
1284 {
1285         char mz_name[RTE_EVENTDEV_NAME_MAX_LEN];
1286         const struct rte_memzone *mz;
1287         int n;
1288
1289         /* Generate memzone name */
1290         n = snprintf(mz_name, sizeof(mz_name), "rte_eventdev_data_%u", dev_id);
1291         if (n >= (int)sizeof(mz_name))
1292                 return -EINVAL;
1293
1294         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1295                 mz = rte_memzone_reserve(mz_name,
1296                                 sizeof(struct rte_eventdev_data),
1297                                 socket_id, 0);
1298         } else
1299                 mz = rte_memzone_lookup(mz_name);
1300
1301         if (mz == NULL)
1302                 return -ENOMEM;
1303
1304         *data = mz->addr;
1305         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
1306                 memset(*data, 0, sizeof(struct rte_eventdev_data));
1307
1308         return 0;
1309 }
1310
1311 static inline uint8_t
1312 rte_eventdev_find_free_device_index(void)
1313 {
1314         uint8_t dev_id;
1315
1316         for (dev_id = 0; dev_id < RTE_EVENT_MAX_DEVS; dev_id++) {
1317                 if (rte_eventdevs[dev_id].attached ==
1318                                 RTE_EVENTDEV_DETACHED)
1319                         return dev_id;
1320         }
1321         return RTE_EVENT_MAX_DEVS;
1322 }
1323
1324 static uint16_t
1325 rte_event_tx_adapter_enqueue(__rte_unused void *port,
1326                         __rte_unused struct rte_event ev[],
1327                         __rte_unused uint16_t nb_events)
1328 {
1329         rte_errno = ENOTSUP;
1330         return 0;
1331 }
1332
1333 struct rte_eventdev *
1334 rte_event_pmd_allocate(const char *name, int socket_id)
1335 {
1336         struct rte_eventdev *eventdev;
1337         uint8_t dev_id;
1338
1339         if (rte_event_pmd_get_named_dev(name) != NULL) {
1340                 RTE_EDEV_LOG_ERR("Event device with name %s already "
1341                                 "allocated!", name);
1342                 return NULL;
1343         }
1344
1345         dev_id = rte_eventdev_find_free_device_index();
1346         if (dev_id == RTE_EVENT_MAX_DEVS) {
1347                 RTE_EDEV_LOG_ERR("Reached maximum number of event devices");
1348                 return NULL;
1349         }
1350
1351         eventdev = &rte_eventdevs[dev_id];
1352
1353         eventdev->txa_enqueue = rte_event_tx_adapter_enqueue;
1354         eventdev->txa_enqueue_same_dest = rte_event_tx_adapter_enqueue;
1355
1356         if (eventdev->data == NULL) {
1357                 struct rte_eventdev_data *eventdev_data = NULL;
1358
1359                 int retval = rte_eventdev_data_alloc(dev_id, &eventdev_data,
1360                                 socket_id);
1361
1362                 if (retval < 0 || eventdev_data == NULL)
1363                         return NULL;
1364
1365                 eventdev->data = eventdev_data;
1366
1367                 strlcpy(eventdev->data->name, name, RTE_EVENTDEV_NAME_MAX_LEN);
1368
1369                 eventdev->data->dev_id = dev_id;
1370                 eventdev->data->socket_id = socket_id;
1371                 eventdev->data->dev_started = 0;
1372
1373                 eventdev->attached = RTE_EVENTDEV_ATTACHED;
1374
1375                 eventdev_globals.nb_devs++;
1376         }
1377
1378         return eventdev;
1379 }
1380
1381 int
1382 rte_event_pmd_release(struct rte_eventdev *eventdev)
1383 {
1384         int ret;
1385         char mz_name[RTE_EVENTDEV_NAME_MAX_LEN];
1386         const struct rte_memzone *mz;
1387
1388         if (eventdev == NULL)
1389                 return -EINVAL;
1390
1391         eventdev->attached = RTE_EVENTDEV_DETACHED;
1392         eventdev_globals.nb_devs--;
1393
1394         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1395                 rte_free(eventdev->data->dev_private);
1396
1397                 /* Generate memzone name */
1398                 ret = snprintf(mz_name, sizeof(mz_name), "rte_eventdev_data_%u",
1399                                 eventdev->data->dev_id);
1400                 if (ret >= (int)sizeof(mz_name))
1401                         return -EINVAL;
1402
1403                 mz = rte_memzone_lookup(mz_name);
1404                 if (mz == NULL)
1405                         return -ENOMEM;
1406
1407                 ret = rte_memzone_free(mz);
1408                 if (ret)
1409                         return ret;
1410         }
1411
1412         eventdev->data = NULL;
1413         return 0;
1414 }