6c4d783cc545917abd6bf03b64b45ae9700c4ffc
[dpdk.git] / lib / librte_rawdev / rte_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017 NXP
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_telemetry.h>
33
34 #include "rte_rawdev.h"
35 #include "rte_rawdev_pmd.h"
36
37 static struct rte_rawdev rte_rawdevices[RTE_RAWDEV_MAX_DEVS];
38
39 struct rte_rawdev *rte_rawdevs = rte_rawdevices;
40
41 static struct rte_rawdev_global rawdev_globals = {
42         .nb_devs                = 0
43 };
44
45 /* Raw device, northbound API implementation */
46 uint8_t
47 rte_rawdev_count(void)
48 {
49         return rawdev_globals.nb_devs;
50 }
51
52 uint16_t
53 rte_rawdev_get_dev_id(const char *name)
54 {
55         uint16_t i;
56
57         if (!name)
58                 return -EINVAL;
59
60         for (i = 0; i < rawdev_globals.nb_devs; i++)
61                 if ((strcmp(rte_rawdevices[i].name, name)
62                                 == 0) &&
63                                 (rte_rawdevices[i].attached ==
64                                                 RTE_RAWDEV_ATTACHED))
65                         return i;
66         return -ENODEV;
67 }
68
69 int
70 rte_rawdev_socket_id(uint16_t dev_id)
71 {
72         struct rte_rawdev *dev;
73
74         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
75         dev = &rte_rawdevs[dev_id];
76
77         return dev->socket_id;
78 }
79
80 int
81 rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info,
82                 size_t dev_private_size)
83 {
84         struct rte_rawdev *rawdev;
85         int ret = 0;
86
87         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
88         RTE_FUNC_PTR_OR_ERR_RET(dev_info, -EINVAL);
89
90         rawdev = &rte_rawdevs[dev_id];
91
92         if (dev_info->dev_private != NULL) {
93                 RTE_FUNC_PTR_OR_ERR_RET(*rawdev->dev_ops->dev_info_get, -ENOTSUP);
94                 ret = (*rawdev->dev_ops->dev_info_get)(rawdev,
95                                 dev_info->dev_private,
96                                 dev_private_size);
97         }
98
99         dev_info->driver_name = rawdev->driver_name;
100         dev_info->device = rawdev->device;
101         dev_info->socket_id = rawdev->socket_id;
102
103         return ret;
104 }
105
106 int
107 rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf,
108                 size_t dev_private_size)
109 {
110         struct rte_rawdev *dev;
111         int diag;
112
113         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
114         RTE_FUNC_PTR_OR_ERR_RET(dev_conf, -EINVAL);
115
116         dev = &rte_rawdevs[dev_id];
117
118         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
119
120         if (dev->started) {
121                 RTE_RDEV_ERR(
122                    "device %d must be stopped to allow configuration", dev_id);
123                 return -EBUSY;
124         }
125
126         /* Configure the device */
127         diag = (*dev->dev_ops->dev_configure)(dev, dev_conf->dev_private,
128                         dev_private_size);
129         if (diag != 0)
130                 RTE_RDEV_ERR("dev%d dev_configure = %d", dev_id, diag);
131         else
132                 dev->attached = 1;
133
134         return diag;
135 }
136
137 int
138 rte_rawdev_queue_conf_get(uint16_t dev_id,
139                           uint16_t queue_id,
140                           rte_rawdev_obj_t queue_conf)
141 {
142         struct rte_rawdev *dev;
143
144         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
145         dev = &rte_rawdevs[dev_id];
146
147         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf, -ENOTSUP);
148         (*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf);
149         return 0;
150 }
151
152 int
153 rte_rawdev_queue_setup(uint16_t dev_id,
154                        uint16_t queue_id,
155                        rte_rawdev_obj_t queue_conf)
156 {
157         struct rte_rawdev *dev;
158
159         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
160         dev = &rte_rawdevs[dev_id];
161
162         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_setup, -ENOTSUP);
163         return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf);
164 }
165
166 int
167 rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id)
168 {
169         struct rte_rawdev *dev;
170
171         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
172         dev = &rte_rawdevs[dev_id];
173
174         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_release, -ENOTSUP);
175         return (*dev->dev_ops->queue_release)(dev, queue_id);
176 }
177
178 uint16_t
179 rte_rawdev_queue_count(uint16_t dev_id)
180 {
181         struct rte_rawdev *dev;
182
183         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
184         dev = &rte_rawdevs[dev_id];
185
186         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_count, -ENOTSUP);
187         return (*dev->dev_ops->queue_count)(dev);
188 }
189
190 int
191 rte_rawdev_get_attr(uint16_t dev_id,
192                     const char *attr_name,
193                     uint64_t *attr_value)
194 {
195         struct rte_rawdev *dev;
196
197         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
198         dev = &rte_rawdevs[dev_id];
199
200         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_get, -ENOTSUP);
201         return (*dev->dev_ops->attr_get)(dev, attr_name, attr_value);
202 }
203
204 int
205 rte_rawdev_set_attr(uint16_t dev_id,
206                     const char *attr_name,
207                     const uint64_t attr_value)
208 {
209         struct rte_rawdev *dev;
210
211         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
212         dev = &rte_rawdevs[dev_id];
213
214         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_set, -ENOTSUP);
215         return (*dev->dev_ops->attr_set)(dev, attr_name, attr_value);
216 }
217
218 int
219 rte_rawdev_enqueue_buffers(uint16_t dev_id,
220                            struct rte_rawdev_buf **buffers,
221                            unsigned int count,
222                            rte_rawdev_obj_t context)
223 {
224         struct rte_rawdev *dev;
225
226         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
227         dev = &rte_rawdevs[dev_id];
228
229         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->enqueue_bufs, -ENOTSUP);
230         return (*dev->dev_ops->enqueue_bufs)(dev, buffers, count, context);
231 }
232
233 int
234 rte_rawdev_dequeue_buffers(uint16_t dev_id,
235                            struct rte_rawdev_buf **buffers,
236                            unsigned int count,
237                            rte_rawdev_obj_t context)
238 {
239         struct rte_rawdev *dev;
240
241         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
242         dev = &rte_rawdevs[dev_id];
243
244         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dequeue_bufs, -ENOTSUP);
245         return (*dev->dev_ops->dequeue_bufs)(dev, buffers, count, context);
246 }
247
248 int
249 rte_rawdev_dump(uint16_t dev_id, FILE *f)
250 {
251         struct rte_rawdev *dev;
252
253         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
254         dev = &rte_rawdevs[dev_id];
255
256         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dump, -ENOTSUP);
257         return (*dev->dev_ops->dump)(dev, f);
258 }
259
260 static int
261 xstats_get_count(uint16_t dev_id)
262 {
263         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
264
265         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP);
266         return (*dev->dev_ops->xstats_get_names)(dev, NULL, 0);
267 }
268
269 int
270 rte_rawdev_xstats_names_get(uint16_t dev_id,
271                 struct rte_rawdev_xstats_name *xstats_names,
272                 unsigned int size)
273 {
274         const struct rte_rawdev *dev;
275         int cnt_expected_entries;
276
277         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
278
279         cnt_expected_entries = xstats_get_count(dev_id);
280
281         if (xstats_names == NULL || cnt_expected_entries < 0 ||
282             (int)size < cnt_expected_entries || size <= 0)
283                 return cnt_expected_entries;
284
285         dev = &rte_rawdevs[dev_id];
286
287         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP);
288         return (*dev->dev_ops->xstats_get_names)(dev, xstats_names, size);
289 }
290
291 /* retrieve rawdev extended statistics */
292 int
293 rte_rawdev_xstats_get(uint16_t dev_id,
294                       const unsigned int ids[],
295                       uint64_t values[],
296                       unsigned int n)
297 {
298         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV);
299         const struct rte_rawdev *dev = &rte_rawdevs[dev_id];
300
301         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get, -ENOTSUP);
302         return (*dev->dev_ops->xstats_get)(dev, ids, values, n);
303 }
304
305 uint64_t
306 rte_rawdev_xstats_by_name_get(uint16_t dev_id,
307                               const char *name,
308                               unsigned int *id)
309 {
310         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, 0);
311         const struct rte_rawdev *dev = &rte_rawdevs[dev_id];
312         unsigned int temp = -1;
313
314         if (id != NULL)
315                 *id = (unsigned int)-1;
316         else
317                 id = &temp; /* driver never gets a NULL value */
318
319         /* implemented by driver */
320         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_by_name, -ENOTSUP);
321         return (*dev->dev_ops->xstats_get_by_name)(dev, name, id);
322 }
323
324 int
325 rte_rawdev_xstats_reset(uint16_t dev_id,
326                         const uint32_t ids[], uint32_t nb_ids)
327 {
328         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
329         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
330
331         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_reset, -ENOTSUP);
332         return (*dev->dev_ops->xstats_reset)(dev, ids, nb_ids);
333 }
334
335 int
336 rte_rawdev_firmware_status_get(uint16_t dev_id, rte_rawdev_obj_t status_info)
337 {
338         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
339         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
340
341         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_status_get, -ENOTSUP);
342         return (*dev->dev_ops->firmware_status_get)(dev, status_info);
343 }
344
345 int
346 rte_rawdev_firmware_version_get(uint16_t dev_id, rte_rawdev_obj_t version_info)
347 {
348         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
349         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
350
351         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_version_get, -ENOTSUP);
352         return (*dev->dev_ops->firmware_version_get)(dev, version_info);
353 }
354
355 int
356 rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image)
357 {
358         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
359         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
360
361         if (!firmware_image)
362                 return -EINVAL;
363
364         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP);
365         return (*dev->dev_ops->firmware_load)(dev, firmware_image);
366 }
367
368 int
369 rte_rawdev_firmware_unload(uint16_t dev_id)
370 {
371         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
372         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
373
374         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP);
375         return (*dev->dev_ops->firmware_unload)(dev);
376 }
377
378 int
379 rte_rawdev_selftest(uint16_t dev_id)
380 {
381         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
382         struct rte_rawdev *dev = &rte_rawdevs[dev_id];
383
384         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_selftest, -ENOTSUP);
385         return (*dev->dev_ops->dev_selftest)(dev_id);
386 }
387
388 int
389 rte_rawdev_start(uint16_t dev_id)
390 {
391         struct rte_rawdev *dev;
392         int diag;
393
394         RTE_RDEV_DEBUG("Start dev_id=%" PRIu8, dev_id);
395
396         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
397         dev = &rte_rawdevs[dev_id];
398         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
399
400         if (dev->started != 0) {
401                 RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already started",
402                              dev_id);
403                 return 0;
404         }
405
406         diag = (*dev->dev_ops->dev_start)(dev);
407         if (diag == 0)
408                 dev->started = 1;
409         else
410                 return diag;
411
412         return 0;
413 }
414
415 void
416 rte_rawdev_stop(uint16_t dev_id)
417 {
418         struct rte_rawdev *dev;
419
420         RTE_RDEV_DEBUG("Stop dev_id=%" PRIu8, dev_id);
421
422         RTE_RAWDEV_VALID_DEVID_OR_RET(dev_id);
423         dev = &rte_rawdevs[dev_id];
424
425         RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
426
427         if (dev->started == 0) {
428                 RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already stopped",
429                         dev_id);
430                 return;
431         }
432
433         (*dev->dev_ops->dev_stop)(dev);
434         dev->started = 0;
435 }
436
437 int
438 rte_rawdev_close(uint16_t dev_id)
439 {
440         struct rte_rawdev *dev;
441
442         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
443         dev = &rte_rawdevs[dev_id];
444
445         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
446         /* Device must be stopped before it can be closed */
447         if (dev->started == 1) {
448                 RTE_RDEV_ERR("Device %u must be stopped before closing",
449                              dev_id);
450                 return -EBUSY;
451         }
452
453         return (*dev->dev_ops->dev_close)(dev);
454 }
455
456 int
457 rte_rawdev_reset(uint16_t dev_id)
458 {
459         struct rte_rawdev *dev;
460
461         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
462         dev = &rte_rawdevs[dev_id];
463
464         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP);
465         /* Reset is not dependent on state of the device */
466         return (*dev->dev_ops->dev_reset)(dev);
467 }
468
469 static inline uint8_t
470 rte_rawdev_find_free_device_index(void)
471 {
472         uint16_t dev_id;
473
474         for (dev_id = 0; dev_id < RTE_RAWDEV_MAX_DEVS; dev_id++) {
475                 if (rte_rawdevs[dev_id].attached ==
476                                 RTE_RAWDEV_DETACHED)
477                         return dev_id;
478         }
479
480         return RTE_RAWDEV_MAX_DEVS;
481 }
482
483 struct rte_rawdev *
484 rte_rawdev_pmd_allocate(const char *name, size_t dev_priv_size, int socket_id)
485 {
486         struct rte_rawdev *rawdev;
487         uint16_t dev_id;
488
489         if (rte_rawdev_pmd_get_named_dev(name) != NULL) {
490                 RTE_RDEV_ERR("Event device with name %s already allocated!",
491                              name);
492                 return NULL;
493         }
494
495         dev_id = rte_rawdev_find_free_device_index();
496         if (dev_id == RTE_RAWDEV_MAX_DEVS) {
497                 RTE_RDEV_ERR("Reached maximum number of raw devices");
498                 return NULL;
499         }
500
501         rawdev = &rte_rawdevs[dev_id];
502
503         if (dev_priv_size > 0) {
504                 rawdev->dev_private = rte_zmalloc_socket("rawdev private",
505                                      dev_priv_size,
506                                      RTE_CACHE_LINE_SIZE,
507                                      socket_id);
508                 if (!rawdev->dev_private) {
509                         RTE_RDEV_ERR("Unable to allocate memory for rawdev");
510                         return NULL;
511                 }
512         }
513
514         rawdev->dev_id = dev_id;
515         rawdev->socket_id = socket_id;
516         rawdev->started = 0;
517         strlcpy(rawdev->name, name, RTE_RAWDEV_NAME_MAX_LEN);
518
519         rawdev->attached = RTE_RAWDEV_ATTACHED;
520         rawdev_globals.nb_devs++;
521
522         return rawdev;
523 }
524
525 int
526 rte_rawdev_pmd_release(struct rte_rawdev *rawdev)
527 {
528         int ret;
529
530         if (rawdev == NULL)
531                 return -EINVAL;
532
533         ret = rte_rawdev_close(rawdev->dev_id);
534         if (ret < 0)
535                 return ret;
536
537         rawdev->attached = RTE_RAWDEV_DETACHED;
538         rawdev_globals.nb_devs--;
539
540         rawdev->dev_id = 0;
541         rawdev->socket_id = 0;
542         rawdev->dev_ops = NULL;
543         if (rawdev->dev_private) {
544                 rte_free(rawdev->dev_private);
545                 rawdev->dev_private = NULL;
546         }
547
548         return 0;
549 }
550
551 static int
552 handle_dev_list(const char *cmd __rte_unused,
553                 const char *params __rte_unused,
554                 struct rte_tel_data *d)
555 {
556         int i;
557
558         rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
559         for (i = 0; i < rawdev_globals.nb_devs; i++)
560                 if (rte_rawdevices[i].attached == RTE_RAWDEV_ATTACHED)
561                         rte_tel_data_add_array_int(d, i);
562         return 0;
563 }
564
565 static int
566 handle_dev_xstats(const char *cmd __rte_unused,
567                 const char *params,
568                 struct rte_tel_data *d)
569 {
570         uint64_t *rawdev_xstats;
571         struct rte_rawdev_xstats_name *xstat_names;
572         int dev_id, num_xstats, i, ret;
573         unsigned int *ids;
574
575         if (params == NULL || strlen(params) == 0 || !isdigit(*params))
576                 return -1;
577
578         dev_id = atoi(params);
579         if (!rte_rawdev_pmd_is_valid_dev(dev_id))
580                 return -1;
581
582         num_xstats = xstats_get_count(dev_id);
583         if (num_xstats < 0)
584                 return -1;
585
586         /* use one malloc for names, stats and ids */
587         rawdev_xstats = malloc((sizeof(uint64_t) +
588                         sizeof(struct rte_rawdev_xstats_name) +
589                         sizeof(unsigned int)) * num_xstats);
590         if (rawdev_xstats == NULL)
591                 return -1;
592         xstat_names = (void *)&rawdev_xstats[num_xstats];
593         ids = (void *)&xstat_names[num_xstats];
594
595         ret = rte_rawdev_xstats_names_get(dev_id, xstat_names, num_xstats);
596         if (ret < 0 || ret > num_xstats) {
597                 free(rawdev_xstats);
598                 return -1;
599         }
600
601         for (i = 0; i < num_xstats; i++)
602                 ids[i] = i;
603
604         ret = rte_rawdev_xstats_get(dev_id, ids, rawdev_xstats, num_xstats);
605         if (ret < 0 || ret > num_xstats) {
606                 free(rawdev_xstats);
607                 return -1;
608         }
609
610         rte_tel_data_start_dict(d);
611         for (i = 0; i < num_xstats; i++)
612                 rte_tel_data_add_dict_u64(d, xstat_names[i].name,
613                                 rawdev_xstats[i]);
614
615         free(rawdev_xstats);
616         return 0;
617 }
618
619 RTE_LOG_REGISTER(librawdev_logtype, lib.rawdev, INFO);
620
621 RTE_INIT(librawdev_init_telemetry)
622 {
623         rte_telemetry_register_cmd("/rawdev/list", handle_dev_list,
624                         "Returns list of available rawdev ports. Takes no parameters");
625         rte_telemetry_register_cmd("/rawdev/xstats", handle_dev_xstats,
626                         "Returns the xstats for a rawdev port. Parameters: int port_id");
627 }