New upstream version 18.02
[deb_dpdk.git] / drivers / raw / skeleton_rawdev / skeleton_rawdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017 NXP
3  */
4
5 #include <assert.h>
6 #include <stdio.h>
7 #include <stdbool.h>
8 #include <errno.h>
9 #include <stdint.h>
10 #include <inttypes.h>
11 #include <string.h>
12
13 #include <rte_byteorder.h>
14 #include <rte_common.h>
15 #include <rte_debug.h>
16 #include <rte_dev.h>
17 #include <rte_eal.h>
18 #include <rte_kvargs.h>
19 #include <rte_log.h>
20 #include <rte_malloc.h>
21 #include <rte_memory.h>
22 #include <rte_memcpy.h>
23 #include <rte_lcore.h>
24 #include <rte_bus_vdev.h>
25
26 #include <rte_rawdev.h>
27 #include <rte_rawdev_pmd.h>
28
29 #include "skeleton_rawdev.h"
30
31 /* Dynamic log type identifier */
32 int skeleton_pmd_logtype;
33
34 /* Count of instances */
35 uint16_t skeldev_init_once;
36
37 /**< Rawdev Skeleton dummy driver name */
38 #define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
39
40 /**< Skeleton rawdev driver object */
41 static struct rte_vdev_driver skeleton_pmd_drv;
42
43 struct queue_buffers {
44         void *bufs[SKELETON_QUEUE_MAX_DEPTH];
45 };
46
47 static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {};
48 static void clear_queue_bufs(int queue_id);
49
50 static void skeleton_rawdev_info_get(struct rte_rawdev *dev,
51                                      rte_rawdev_obj_t dev_info)
52 {
53         struct skeleton_rawdev *skeldev;
54         struct skeleton_rawdev_conf *skeldev_conf;
55
56         SKELETON_PMD_FUNC_TRACE();
57
58         if (!dev_info) {
59                 SKELETON_PMD_ERR("Invalid request");
60                 return;
61         }
62
63         skeldev = skeleton_rawdev_get_priv(dev);
64
65         skeldev_conf = dev_info;
66
67         skeldev_conf->num_queues = skeldev->num_queues;
68         skeldev_conf->capabilities = skeldev->capabilities;
69         skeldev_conf->device_state = skeldev->device_state;
70         skeldev_conf->firmware_state = skeldev->fw.firmware_state;
71 }
72
73 static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
74                                      rte_rawdev_obj_t config)
75 {
76         struct skeleton_rawdev *skeldev;
77         struct skeleton_rawdev_conf *skeldev_conf;
78
79         SKELETON_PMD_FUNC_TRACE();
80
81         RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
82
83         if (!config) {
84                 SKELETON_PMD_ERR("Invalid configuration");
85                 return -EINVAL;
86         }
87
88         skeldev_conf = config;
89         skeldev = skeleton_rawdev_get_priv(dev);
90
91         if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
92                 skeldev->num_queues = skeldev_conf->num_queues;
93         else
94                 return -EINVAL;
95
96         skeldev->capabilities = skeldev_conf->capabilities;
97         skeldev->num_queues = skeldev_conf->num_queues;
98
99         return 0;
100 }
101
102 static int skeleton_rawdev_start(struct rte_rawdev *dev)
103 {
104         int ret = 0;
105         struct skeleton_rawdev *skeldev;
106         enum skeleton_firmware_state fw_state;
107         enum skeleton_device_state device_state;
108
109         SKELETON_PMD_FUNC_TRACE();
110
111         RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
112
113         skeldev = skeleton_rawdev_get_priv(dev);
114
115         fw_state = skeldev->fw.firmware_state;
116         device_state = skeldev->device_state;
117
118         if (fw_state == SKELETON_FW_LOADED &&
119                 device_state == SKELETON_DEV_STOPPED) {
120                 skeldev->device_state = SKELETON_DEV_RUNNING;
121         } else {
122                 SKELETON_PMD_ERR("Device not ready for starting");
123                 ret = -EINVAL;
124         }
125
126         return ret;
127 }
128
129 static void skeleton_rawdev_stop(struct rte_rawdev *dev)
130 {
131         struct skeleton_rawdev *skeldev;
132
133         SKELETON_PMD_FUNC_TRACE();
134
135         if (dev) {
136                 skeldev = skeleton_rawdev_get_priv(dev);
137                 skeldev->device_state = SKELETON_DEV_STOPPED;
138         }
139 }
140
141 static void
142 reset_queues(struct skeleton_rawdev *skeldev)
143 {
144         int i;
145
146         for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
147                 skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
148                 skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
149         }
150 }
151
152 static void
153 reset_attribute_table(struct skeleton_rawdev *skeldev)
154 {
155         int i;
156
157         for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
158                 if (skeldev->attr[i].name) {
159                         free(skeldev->attr[i].name);
160                         skeldev->attr[i].name = NULL;
161                 }
162         }
163 }
164
165 static int skeleton_rawdev_close(struct rte_rawdev *dev)
166 {
167         int ret = 0, i;
168         struct skeleton_rawdev *skeldev;
169         enum skeleton_firmware_state fw_state;
170         enum skeleton_device_state device_state;
171
172         SKELETON_PMD_FUNC_TRACE();
173
174         RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
175
176         skeldev = skeleton_rawdev_get_priv(dev);
177
178         fw_state = skeldev->fw.firmware_state;
179         device_state = skeldev->device_state;
180
181         reset_queues(skeldev);
182         reset_attribute_table(skeldev);
183
184         switch (fw_state) {
185         case SKELETON_FW_LOADED:
186                 if (device_state == SKELETON_DEV_RUNNING) {
187                         SKELETON_PMD_ERR("Cannot close running device");
188                         ret = -EINVAL;
189                 } else {
190                         /* Probably call fw reset here */
191                         skeldev->fw.firmware_state = SKELETON_FW_READY;
192                 }
193                 break;
194         case SKELETON_FW_READY:
195         case SKELETON_FW_ERROR:
196         default:
197                 SKELETON_PMD_DEBUG("Device already in stopped state");
198                 ret = -EINVAL;
199                 break;
200         }
201
202         /* Clear all allocated queues */
203         for (i = 0; i < SKELETON_MAX_QUEUES; i++)
204                 clear_queue_bufs(i);
205
206         return ret;
207 }
208
209 static int skeleton_rawdev_reset(struct rte_rawdev *dev)
210 {
211         struct skeleton_rawdev *skeldev;
212
213         SKELETON_PMD_FUNC_TRACE();
214
215         RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
216
217         skeldev = skeleton_rawdev_get_priv(dev);
218
219         SKELETON_PMD_DEBUG("Resetting device");
220         skeldev->fw.firmware_state = SKELETON_FW_READY;
221
222         return 0;
223 }
224
225 static void skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
226                                            uint16_t queue_id,
227                                            rte_rawdev_obj_t queue_conf)
228 {
229         struct skeleton_rawdev *skeldev;
230         struct skeleton_rawdev_queue *skelq;
231
232         SKELETON_PMD_FUNC_TRACE();
233
234         if (!dev || !queue_conf)
235                 return;
236
237         skeldev = skeleton_rawdev_get_priv(dev);
238         skelq = &skeldev->queues[queue_id];
239
240         if (queue_id < SKELETON_MAX_QUEUES)
241                 rte_memcpy(queue_conf, skelq,
242                         sizeof(struct skeleton_rawdev_queue));
243 }
244
245 static void
246 clear_queue_bufs(int queue_id)
247 {
248         int i;
249
250         /* Clear buffers for queue_id */
251         for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
252                 queue_buf[queue_id].bufs[i] = NULL;
253 }
254
255 static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
256                                        uint16_t queue_id,
257                                        rte_rawdev_obj_t queue_conf)
258 {
259         int ret = 0;
260         struct skeleton_rawdev *skeldev;
261         struct skeleton_rawdev_queue *q;
262
263         SKELETON_PMD_FUNC_TRACE();
264
265         if (!dev || !queue_conf)
266                 return -EINVAL;
267
268         skeldev = skeleton_rawdev_get_priv(dev);
269         q = &skeldev->queues[queue_id];
270
271         if (skeldev->num_queues > queue_id &&
272             q->depth < SKELETON_QUEUE_MAX_DEPTH) {
273                 rte_memcpy(q, queue_conf,
274                            sizeof(struct skeleton_rawdev_queue));
275                 clear_queue_bufs(queue_id);
276         } else {
277                 SKELETON_PMD_ERR("Invalid queue configuration");
278                 ret = -EINVAL;
279         }
280
281         return ret;
282 }
283
284 static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
285                                          uint16_t queue_id)
286 {
287         int ret = 0;
288         struct skeleton_rawdev *skeldev;
289
290         SKELETON_PMD_FUNC_TRACE();
291
292         RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
293
294         skeldev = skeleton_rawdev_get_priv(dev);
295
296         if (skeldev->num_queues > queue_id) {
297                 skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
298                 skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
299                 clear_queue_bufs(queue_id);
300         } else {
301                 SKELETON_PMD_ERR("Invalid queue configuration");
302                 ret = -EINVAL;
303         }
304
305         return ret;
306 }
307
308 static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
309                                     const char *attr_name,
310                                     uint64_t *attr_value)
311 {
312         int i;
313         uint8_t done = 0;
314         struct skeleton_rawdev *skeldev;
315
316         SKELETON_PMD_FUNC_TRACE();
317
318         if (!dev || !attr_name || !attr_value) {
319                 SKELETON_PMD_ERR("Invalid arguments for getting attributes");
320                 return -EINVAL;
321         }
322
323         skeldev = skeleton_rawdev_get_priv(dev);
324
325         for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
326                 if (!skeldev->attr[i].name)
327                         continue;
328
329                 if (!strncmp(skeldev->attr[i].name, attr_name,
330                             SKELETON_ATTRIBUTE_NAME_MAX)) {
331                         *attr_value = skeldev->attr[i].value;
332                         done = 1;
333                         SKELETON_PMD_DEBUG("Attribute (%s) Value (%" PRIu64 ")",
334                                            attr_name, *attr_value);
335                         break;
336                 }
337         }
338
339         if (done)
340                 return 0;
341
342         /* Attribute not found */
343         return -EINVAL;
344 }
345
346 static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
347                                      const char *attr_name,
348                                      const uint64_t attr_value)
349 {
350         int i;
351         uint8_t done = 0;
352         struct skeleton_rawdev *skeldev;
353
354         SKELETON_PMD_FUNC_TRACE();
355
356         if (!dev || !attr_name) {
357                 SKELETON_PMD_ERR("Invalid arguments for setting attributes");
358                 return -EINVAL;
359         }
360
361         skeldev = skeleton_rawdev_get_priv(dev);
362
363         /* Check if attribute already exists */
364         for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
365                 if (!skeldev->attr[i].name)
366                         break;
367
368                 if (!strncmp(skeldev->attr[i].name, attr_name,
369                              SKELETON_ATTRIBUTE_NAME_MAX)) {
370                         /* Update value */
371                         skeldev->attr[i].value = attr_value;
372                         done = 1;
373                         break;
374                 }
375         }
376
377         if (!done) {
378                 if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
379                         /* There is still space to insert one more */
380                         skeldev->attr[i].name = strdup(attr_name);
381                         if (!skeldev->attr[i].name)
382                                 return -ENOMEM;
383
384                         skeldev->attr[i].value = attr_value;
385                         return 0;
386                 }
387         }
388
389         return -EINVAL;
390 }
391
392 static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
393                                         struct rte_rawdev_buf **buffers,
394                                         unsigned int count,
395                                         rte_rawdev_obj_t context)
396 {
397         unsigned int i;
398         uint16_t q_id;
399         RTE_SET_USED(dev);
400
401         /* context is essentially the queue_id which is
402          * transferred as opaque object through the library layer. This can
403          * help in complex implementation which require more information than
404          * just an integer - for example, a queue-pair.
405          */
406         q_id = *((int *)context);
407
408         for (i = 0; i < count; i++)
409                 queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
410
411         return i;
412 }
413
414 static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
415                                         struct rte_rawdev_buf **buffers,
416                                         unsigned int count,
417                                         rte_rawdev_obj_t context)
418 {
419         unsigned int i;
420         uint16_t q_id;
421         RTE_SET_USED(dev);
422
423         /* context is essentially the queue_id which is
424          * transferred as opaque object through the library layer. This can
425          * help in complex implementation which require more information than
426          * just an integer - for example, a queue-pair.
427          */
428         q_id = *((int *)context);
429
430         for (i = 0; i < count; i++)
431                 buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
432
433         return i;
434 }
435
436 static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
437 {
438         RTE_SET_USED(dev);
439         RTE_SET_USED(f);
440
441         return 0;
442 }
443
444 static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
445                                                rte_rawdev_obj_t status_info)
446 {
447         struct skeleton_rawdev *skeldev;
448
449         SKELETON_PMD_FUNC_TRACE();
450
451         skeldev = skeleton_rawdev_get_priv(dev);
452
453         RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
454
455         if (status_info)
456                 memcpy(status_info, &skeldev->fw.firmware_state,
457                         sizeof(enum skeleton_firmware_state));
458
459         return 0;
460 }
461
462
463 static int skeleton_rawdev_firmware_version_get(
464                                         struct rte_rawdev *dev,
465                                         rte_rawdev_obj_t version_info)
466 {
467         struct skeleton_rawdev *skeldev;
468         struct skeleton_firmware_version_info *vi;
469
470         SKELETON_PMD_FUNC_TRACE();
471
472         skeldev = skeleton_rawdev_get_priv(dev);
473         vi = version_info;
474
475         vi->major = skeldev->fw.firmware_version.major;
476         vi->minor = skeldev->fw.firmware_version.minor;
477         vi->subrel = skeldev->fw.firmware_version.subrel;
478
479         return 0;
480 }
481
482 static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
483                                          rte_rawdev_obj_t firmware_buf)
484 {
485         struct skeleton_rawdev *skeldev;
486
487         SKELETON_PMD_FUNC_TRACE();
488
489         skeldev = skeleton_rawdev_get_priv(dev);
490
491         /* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
492          * dummy, all this does is check if firmware_buf is not NULL and
493          * sets the state of the firmware.
494          */
495         if (!firmware_buf)
496                 return -EINVAL;
497
498         skeldev->fw.firmware_state = SKELETON_FW_LOADED;
499
500         return 0;
501 }
502
503 static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
504 {
505         struct skeleton_rawdev *skeldev;
506
507         SKELETON_PMD_FUNC_TRACE();
508
509         skeldev = skeleton_rawdev_get_priv(dev);
510
511         skeldev->fw.firmware_state = SKELETON_FW_READY;
512
513         return 0;
514 }
515
516 static const struct rte_rawdev_ops skeleton_rawdev_ops = {
517         .dev_info_get = skeleton_rawdev_info_get,
518         .dev_configure = skeleton_rawdev_configure,
519         .dev_start = skeleton_rawdev_start,
520         .dev_stop = skeleton_rawdev_stop,
521         .dev_close = skeleton_rawdev_close,
522         .dev_reset = skeleton_rawdev_reset,
523
524         .queue_def_conf = skeleton_rawdev_queue_def_conf,
525         .queue_setup = skeleton_rawdev_queue_setup,
526         .queue_release = skeleton_rawdev_queue_release,
527
528         .attr_get = skeleton_rawdev_get_attr,
529         .attr_set = skeleton_rawdev_set_attr,
530
531         .enqueue_bufs = skeleton_rawdev_enqueue_bufs,
532         .dequeue_bufs = skeleton_rawdev_dequeue_bufs,
533
534         .dump = skeleton_rawdev_dump,
535
536         .xstats_get = NULL,
537         .xstats_get_names = NULL,
538         .xstats_get_by_name = NULL,
539         .xstats_reset = NULL,
540
541         .firmware_status_get = skeleton_rawdev_firmware_status_get,
542         .firmware_version_get = skeleton_rawdev_firmware_version_get,
543         .firmware_load = skeleton_rawdev_firmware_load,
544         .firmware_unload = skeleton_rawdev_firmware_unload,
545
546         .dev_selftest = test_rawdev_skeldev,
547 };
548
549 static int
550 skeleton_rawdev_create(const char *name,
551                        struct rte_vdev_device *vdev,
552                        int socket_id)
553 {
554         int ret = 0, i;
555         struct rte_rawdev *rawdev = NULL;
556         struct skeleton_rawdev *skeldev = NULL;
557
558         if (!name) {
559                 SKELETON_PMD_ERR("Invalid name of the device!");
560                 ret = -EINVAL;
561                 goto cleanup;
562         }
563
564         /* Allocate device structure */
565         rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
566                                          socket_id);
567         if (rawdev == NULL) {
568                 SKELETON_PMD_ERR("Unable to allocate rawdevice");
569                 ret = -EINVAL;
570                 goto cleanup;
571         }
572
573         rawdev->dev_ops = &skeleton_rawdev_ops;
574         rawdev->device = &vdev->device;
575         rawdev->driver_name = vdev->device.driver->name;
576
577         skeldev = skeleton_rawdev_get_priv(rawdev);
578
579         skeldev->device_id = SKELETON_DEVICE_ID;
580         skeldev->vendor_id = SKELETON_VENDOR_ID;
581         skeldev->capabilities = SKELETON_DEFAULT_CAPA;
582
583         memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
584
585         skeldev->fw.firmware_state = SKELETON_FW_READY;
586         skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
587         skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
588         skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
589
590         skeldev->device_state = SKELETON_DEV_STOPPED;
591
592         /* Reset/set to default queue configuration for this device */
593         for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
594                 skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
595                 skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
596         }
597
598         /* Clear all allocated queue buffers */
599         for (i = 0; i < SKELETON_MAX_QUEUES; i++)
600                 clear_queue_bufs(i);
601
602         return ret;
603
604 cleanup:
605         if (rawdev)
606                 rte_rawdev_pmd_release(rawdev);
607
608         return ret;
609 }
610
611 static int
612 skeleton_rawdev_destroy(const char *name)
613 {
614         int ret;
615         struct rte_rawdev *rdev;
616
617         if (!name) {
618                 SKELETON_PMD_ERR("Invalid device name");
619                 return -EINVAL;
620         }
621
622         rdev = rte_rawdev_pmd_get_named_dev(name);
623         if (!rdev) {
624                 SKELETON_PMD_ERR("Invalid device name (%s)", name);
625                 return -EINVAL;
626         }
627
628         /* rte_rawdev_close is called by pmd_release */
629         ret = rte_rawdev_pmd_release(rdev);
630         if (ret)
631                 SKELETON_PMD_DEBUG("Device cleanup failed");
632
633         return 0;
634 }
635
636 static int
637 skeldev_get_selftest(const char *key __rte_unused,
638                      const char *value,
639                      void *opaque)
640 {
641         int *flag = opaque;
642         *flag = atoi(value);
643         return 0;
644 }
645
646 static int
647 skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
648 {
649         int selftest = 0;
650         const char *name;
651         const char *params;
652
653         static const char *const args[] = {
654                 SKELETON_SELFTEST_ARG,
655                 NULL
656         };
657
658         name = rte_vdev_device_name(vdev);
659
660         params = rte_vdev_device_args(vdev);
661         if (params != NULL && params[0] != '\0') {
662                 struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
663
664                 if (!kvlist) {
665                         SKELETON_PMD_INFO(
666                                 "Ignoring unsupported params supplied '%s'",
667                                 name);
668                 } else {
669                         int ret = rte_kvargs_process(kvlist,
670                                         SKELETON_SELFTEST_ARG,
671                                         skeldev_get_selftest, &selftest);
672                         if (ret != 0 || (selftest < 0 || selftest > 1)) {
673                                 SKELETON_PMD_ERR("%s: Error in parsing args",
674                                                  name);
675                                 rte_kvargs_free(kvlist);
676                                 ret = -1; /* enforce if selftest is invalid */
677                                 return ret;
678                         }
679                 }
680
681                 rte_kvargs_free(kvlist);
682         }
683
684         return selftest;
685 }
686
687 static int
688 skeleton_rawdev_probe(struct rte_vdev_device *vdev)
689 {
690         const char *name;
691         int selftest = 0, ret = 0;
692
693
694         name = rte_vdev_device_name(vdev);
695         /* More than one instance is not supported */
696         if (skeldev_init_once) {
697                 SKELETON_PMD_ERR("Multiple instance not supported for %s",
698                                  name);
699                 return -EINVAL;
700         }
701
702         SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
703
704         selftest = skeldev_parse_vdev_args(vdev);
705         /* In case of invalid argument, selftest != 1; ignore other values */
706
707         ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
708         if (!ret) {
709                 /* In case command line argument for 'selftest' was passed;
710                  * if invalid arguments were passed, execution continues but
711                  * without selftest.
712                  */
713                 if (selftest == 1)
714                         test_rawdev_skeldev();
715         }
716
717         /* Device instance created; Second instance not possible */
718         skeldev_init_once = 1;
719
720         return ret;
721 }
722
723 static int
724 skeleton_rawdev_remove(struct rte_vdev_device *vdev)
725 {
726         const char *name;
727         int ret;
728
729         name = rte_vdev_device_name(vdev);
730
731         SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
732
733         ret = skeleton_rawdev_destroy(name);
734         if (!ret)
735                 skeldev_init_once = 0;
736
737         return ret;
738 }
739
740 static struct rte_vdev_driver skeleton_pmd_drv = {
741         .probe = skeleton_rawdev_probe,
742         .remove = skeleton_rawdev_remove
743 };
744
745 RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
746
747 RTE_INIT(skeleton_pmd_init_log);
748
749 static void
750 skeleton_pmd_init_log(void)
751 {
752         skeleton_pmd_logtype = rte_log_register("rawdev.skeleton");
753         if (skeleton_pmd_logtype >= 0)
754                 rte_log_set_level(skeleton_pmd_logtype, RTE_LOG_INFO);
755 }