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