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