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