replace snprintf with strlcpy
[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
33 #include "rte_rawdev.h"
34 #include "rte_rawdev_pmd.h"
35
36 /* dynamic log identifier */
37 int librawdev_logtype;
38
39 static struct rte_rawdev rte_rawdevices[RTE_RAWDEV_MAX_DEVS];
40
41 struct rte_rawdev *rte_rawdevs = rte_rawdevices;
42
43 static struct rte_rawdev_global rawdev_globals = {
44         .nb_devs                = 0
45 };
46
47 /* Raw device, northbound API implementation */
48 uint8_t
49 rte_rawdev_count(void)
50 {
51         return rawdev_globals.nb_devs;
52 }
53
54 uint16_t
55 rte_rawdev_get_dev_id(const char *name)
56 {
57         uint16_t i;
58
59         if (!name)
60                 return -EINVAL;
61
62         for (i = 0; i < rawdev_globals.nb_devs; i++)
63                 if ((strcmp(rte_rawdevices[i].name, name)
64                                 == 0) &&
65                                 (rte_rawdevices[i].attached ==
66                                                 RTE_RAWDEV_ATTACHED))
67                         return i;
68         return -ENODEV;
69 }
70
71 int
72 rte_rawdev_socket_id(uint16_t dev_id)
73 {
74         struct rte_rawdev *dev;
75
76         RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
77         dev = &rte_rawdevs[dev_id];
78
79         return dev->socket_id;
80 }
81
82 int
83 rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info)
84 {
85         struct rte_rawdev *rawdev;
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         RTE_FUNC_PTR_OR_ERR_RET(*rawdev->dev_ops->dev_info_get, -ENOTSUP);
93         (*rawdev->dev_ops->dev_info_get)(rawdev, dev_info->dev_private);
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)();
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         rawdev->dev_private = rte_zmalloc_socket("rawdev private",
500                                      dev_priv_size,
501                                      RTE_CACHE_LINE_SIZE,
502                                      socket_id);
503         if (!rawdev->dev_private) {
504                 RTE_RDEV_ERR("Unable to allocate memory to Skeleton dev");
505                 return NULL;
506         }
507
508
509         rawdev->dev_id = dev_id;
510         rawdev->socket_id = socket_id;
511         rawdev->started = 0;
512         strlcpy(rawdev->name, name, RTE_RAWDEV_NAME_MAX_LEN);
513
514         rawdev->attached = RTE_RAWDEV_ATTACHED;
515         rawdev_globals.nb_devs++;
516
517         return rawdev;
518 }
519
520 int
521 rte_rawdev_pmd_release(struct rte_rawdev *rawdev)
522 {
523         int ret;
524
525         if (rawdev == NULL)
526                 return -EINVAL;
527
528         ret = rte_rawdev_close(rawdev->dev_id);
529         if (ret < 0)
530                 return ret;
531
532         rawdev->attached = RTE_RAWDEV_DETACHED;
533         rawdev_globals.nb_devs--;
534
535         rawdev->dev_id = 0;
536         rawdev->socket_id = 0;
537         rawdev->dev_ops = NULL;
538         if (rawdev->dev_private) {
539                 rte_free(rawdev->dev_private);
540                 rawdev->dev_private = NULL;
541         }
542
543         return 0;
544 }
545
546 RTE_INIT(librawdev_init_log)
547 {
548         librawdev_logtype = rte_log_register("lib.rawdev");
549         if (librawdev_logtype >= 0)
550                 rte_log_set_level(librawdev_logtype, RTE_LOG_INFO);
551 }