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