14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang  * Copyright 2017 NXP
34418919fSjohnjiang  */
44418919fSjohnjiang 
54418919fSjohnjiang #include <assert.h>
64418919fSjohnjiang #include <stdio.h>
74418919fSjohnjiang #include <stdbool.h>
84418919fSjohnjiang #include <errno.h>
94418919fSjohnjiang #include <stdint.h>
104418919fSjohnjiang #include <inttypes.h>
114418919fSjohnjiang #include <string.h>
124418919fSjohnjiang 
134418919fSjohnjiang #include <rte_byteorder.h>
144418919fSjohnjiang #include <rte_common.h>
154418919fSjohnjiang #include <rte_debug.h>
164418919fSjohnjiang #include <rte_dev.h>
174418919fSjohnjiang #include <rte_eal.h>
184418919fSjohnjiang #include <rte_kvargs.h>
194418919fSjohnjiang #include <rte_log.h>
204418919fSjohnjiang #include <rte_malloc.h>
214418919fSjohnjiang #include <rte_memory.h>
224418919fSjohnjiang #include <rte_memcpy.h>
234418919fSjohnjiang #include <rte_lcore.h>
244418919fSjohnjiang #include <rte_bus_vdev.h>
254418919fSjohnjiang 
264418919fSjohnjiang #include <rte_rawdev.h>
274418919fSjohnjiang #include <rte_rawdev_pmd.h>
284418919fSjohnjiang 
294418919fSjohnjiang #include "skeleton_rawdev.h"
304418919fSjohnjiang 
314418919fSjohnjiang /* Count of instances */
324418919fSjohnjiang static uint16_t skeldev_init_once;
334418919fSjohnjiang 
344418919fSjohnjiang /**< Rawdev Skeleton dummy driver name */
354418919fSjohnjiang #define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
364418919fSjohnjiang 
374418919fSjohnjiang struct queue_buffers {
384418919fSjohnjiang 	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
394418919fSjohnjiang };
404418919fSjohnjiang 
414418919fSjohnjiang static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {};
424418919fSjohnjiang static void clear_queue_bufs(int queue_id);
434418919fSjohnjiang 
skeleton_rawdev_info_get(struct rte_rawdev * dev,rte_rawdev_obj_t dev_info,size_t dev_info_size)44*2d9fd380Sjfb8856606 static int skeleton_rawdev_info_get(struct rte_rawdev *dev,
45*2d9fd380Sjfb8856606 				     rte_rawdev_obj_t dev_info,
46*2d9fd380Sjfb8856606 				     size_t dev_info_size)
474418919fSjohnjiang {
484418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
494418919fSjohnjiang 	struct skeleton_rawdev_conf *skeldev_conf;
504418919fSjohnjiang 
514418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
524418919fSjohnjiang 
53*2d9fd380Sjfb8856606 	if (!dev_info || dev_info_size != sizeof(*skeldev_conf)) {
544418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid request");
55*2d9fd380Sjfb8856606 		return -EINVAL;
564418919fSjohnjiang 	}
574418919fSjohnjiang 
584418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
594418919fSjohnjiang 
604418919fSjohnjiang 	skeldev_conf = dev_info;
614418919fSjohnjiang 
624418919fSjohnjiang 	skeldev_conf->num_queues = skeldev->num_queues;
634418919fSjohnjiang 	skeldev_conf->capabilities = skeldev->capabilities;
644418919fSjohnjiang 	skeldev_conf->device_state = skeldev->device_state;
654418919fSjohnjiang 	skeldev_conf->firmware_state = skeldev->fw.firmware_state;
66*2d9fd380Sjfb8856606 
67*2d9fd380Sjfb8856606 	return 0;
684418919fSjohnjiang }
694418919fSjohnjiang 
skeleton_rawdev_configure(const struct rte_rawdev * dev,rte_rawdev_obj_t config,size_t config_size)704418919fSjohnjiang static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
71*2d9fd380Sjfb8856606 				     rte_rawdev_obj_t config,
72*2d9fd380Sjfb8856606 				     size_t config_size)
734418919fSjohnjiang {
744418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
754418919fSjohnjiang 	struct skeleton_rawdev_conf *skeldev_conf;
764418919fSjohnjiang 
774418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
784418919fSjohnjiang 
794418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
804418919fSjohnjiang 
81*2d9fd380Sjfb8856606 	if (config == NULL || config_size != sizeof(*skeldev_conf)) {
824418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid configuration");
834418919fSjohnjiang 		return -EINVAL;
844418919fSjohnjiang 	}
854418919fSjohnjiang 
864418919fSjohnjiang 	skeldev_conf = config;
874418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
884418919fSjohnjiang 
894418919fSjohnjiang 	if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
904418919fSjohnjiang 		skeldev->num_queues = skeldev_conf->num_queues;
914418919fSjohnjiang 	else
924418919fSjohnjiang 		return -EINVAL;
934418919fSjohnjiang 
944418919fSjohnjiang 	skeldev->capabilities = skeldev_conf->capabilities;
954418919fSjohnjiang 	skeldev->num_queues = skeldev_conf->num_queues;
964418919fSjohnjiang 
974418919fSjohnjiang 	return 0;
984418919fSjohnjiang }
994418919fSjohnjiang 
skeleton_rawdev_start(struct rte_rawdev * dev)1004418919fSjohnjiang static int skeleton_rawdev_start(struct rte_rawdev *dev)
1014418919fSjohnjiang {
1024418919fSjohnjiang 	int ret = 0;
1034418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
1044418919fSjohnjiang 	enum skeleton_firmware_state fw_state;
1054418919fSjohnjiang 	enum skeleton_device_state device_state;
1064418919fSjohnjiang 
1074418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
1084418919fSjohnjiang 
1094418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
1104418919fSjohnjiang 
1114418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
1124418919fSjohnjiang 
1134418919fSjohnjiang 	fw_state = skeldev->fw.firmware_state;
1144418919fSjohnjiang 	device_state = skeldev->device_state;
1154418919fSjohnjiang 
1164418919fSjohnjiang 	if (fw_state == SKELETON_FW_LOADED &&
1174418919fSjohnjiang 		device_state == SKELETON_DEV_STOPPED) {
1184418919fSjohnjiang 		skeldev->device_state = SKELETON_DEV_RUNNING;
1194418919fSjohnjiang 	} else {
1204418919fSjohnjiang 		SKELETON_PMD_ERR("Device not ready for starting");
1214418919fSjohnjiang 		ret = -EINVAL;
1224418919fSjohnjiang 	}
1234418919fSjohnjiang 
1244418919fSjohnjiang 	return ret;
1254418919fSjohnjiang }
1264418919fSjohnjiang 
skeleton_rawdev_stop(struct rte_rawdev * dev)1274418919fSjohnjiang static void skeleton_rawdev_stop(struct rte_rawdev *dev)
1284418919fSjohnjiang {
1294418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
1304418919fSjohnjiang 
1314418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
1324418919fSjohnjiang 
1334418919fSjohnjiang 	if (dev) {
1344418919fSjohnjiang 		skeldev = skeleton_rawdev_get_priv(dev);
1354418919fSjohnjiang 		skeldev->device_state = SKELETON_DEV_STOPPED;
1364418919fSjohnjiang 	}
1374418919fSjohnjiang }
1384418919fSjohnjiang 
1394418919fSjohnjiang static void
reset_queues(struct skeleton_rawdev * skeldev)1404418919fSjohnjiang reset_queues(struct skeleton_rawdev *skeldev)
1414418919fSjohnjiang {
1424418919fSjohnjiang 	int i;
1434418919fSjohnjiang 
1444418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
1454418919fSjohnjiang 		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
1464418919fSjohnjiang 		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
1474418919fSjohnjiang 	}
1484418919fSjohnjiang }
1494418919fSjohnjiang 
1504418919fSjohnjiang static void
reset_attribute_table(struct skeleton_rawdev * skeldev)1514418919fSjohnjiang reset_attribute_table(struct skeleton_rawdev *skeldev)
1524418919fSjohnjiang {
1534418919fSjohnjiang 	int i;
1544418919fSjohnjiang 
1554418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
1564418919fSjohnjiang 		if (skeldev->attr[i].name) {
1574418919fSjohnjiang 			free(skeldev->attr[i].name);
1584418919fSjohnjiang 			skeldev->attr[i].name = NULL;
1594418919fSjohnjiang 		}
1604418919fSjohnjiang 	}
1614418919fSjohnjiang }
1624418919fSjohnjiang 
skeleton_rawdev_close(struct rte_rawdev * dev)1634418919fSjohnjiang static int skeleton_rawdev_close(struct rte_rawdev *dev)
1644418919fSjohnjiang {
1654418919fSjohnjiang 	int ret = 0, i;
1664418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
1674418919fSjohnjiang 	enum skeleton_firmware_state fw_state;
1684418919fSjohnjiang 	enum skeleton_device_state device_state;
1694418919fSjohnjiang 
1704418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
1714418919fSjohnjiang 
1724418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
1734418919fSjohnjiang 
1744418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
1754418919fSjohnjiang 
1764418919fSjohnjiang 	fw_state = skeldev->fw.firmware_state;
1774418919fSjohnjiang 	device_state = skeldev->device_state;
1784418919fSjohnjiang 
1794418919fSjohnjiang 	reset_queues(skeldev);
1804418919fSjohnjiang 	reset_attribute_table(skeldev);
1814418919fSjohnjiang 
1824418919fSjohnjiang 	switch (fw_state) {
1834418919fSjohnjiang 	case SKELETON_FW_LOADED:
1844418919fSjohnjiang 		if (device_state == SKELETON_DEV_RUNNING) {
1854418919fSjohnjiang 			SKELETON_PMD_ERR("Cannot close running device");
1864418919fSjohnjiang 			ret = -EINVAL;
1874418919fSjohnjiang 		} else {
1884418919fSjohnjiang 			/* Probably call fw reset here */
1894418919fSjohnjiang 			skeldev->fw.firmware_state = SKELETON_FW_READY;
1904418919fSjohnjiang 		}
1914418919fSjohnjiang 		break;
1924418919fSjohnjiang 	case SKELETON_FW_READY:
1930c6bd470Sfengbojiang 		SKELETON_PMD_DEBUG("Device already in stopped state");
1940c6bd470Sfengbojiang 		break;
1954418919fSjohnjiang 	case SKELETON_FW_ERROR:
1964418919fSjohnjiang 	default:
1970c6bd470Sfengbojiang 		SKELETON_PMD_DEBUG("Device in impossible state");
1984418919fSjohnjiang 		ret = -EINVAL;
1994418919fSjohnjiang 		break;
2004418919fSjohnjiang 	}
2014418919fSjohnjiang 
2024418919fSjohnjiang 	/* Clear all allocated queues */
2034418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
2044418919fSjohnjiang 		clear_queue_bufs(i);
2054418919fSjohnjiang 
2064418919fSjohnjiang 	return ret;
2074418919fSjohnjiang }
2084418919fSjohnjiang 
skeleton_rawdev_reset(struct rte_rawdev * dev)2094418919fSjohnjiang static int skeleton_rawdev_reset(struct rte_rawdev *dev)
2104418919fSjohnjiang {
2114418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
2124418919fSjohnjiang 
2134418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
2144418919fSjohnjiang 
2154418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
2164418919fSjohnjiang 
2174418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
2184418919fSjohnjiang 
2194418919fSjohnjiang 	SKELETON_PMD_DEBUG("Resetting device");
2204418919fSjohnjiang 	skeldev->fw.firmware_state = SKELETON_FW_READY;
2214418919fSjohnjiang 
2224418919fSjohnjiang 	return 0;
2234418919fSjohnjiang }
2244418919fSjohnjiang 
skeleton_rawdev_queue_def_conf(struct rte_rawdev * dev,uint16_t queue_id,rte_rawdev_obj_t queue_conf,size_t conf_size)225*2d9fd380Sjfb8856606 static int skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
2264418919fSjohnjiang 					  uint16_t queue_id,
227*2d9fd380Sjfb8856606 					  rte_rawdev_obj_t queue_conf,
228*2d9fd380Sjfb8856606 					  size_t conf_size)
2294418919fSjohnjiang {
2304418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
2314418919fSjohnjiang 	struct skeleton_rawdev_queue *skelq;
2324418919fSjohnjiang 
2334418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
2344418919fSjohnjiang 
235*2d9fd380Sjfb8856606 	if (!dev || !queue_conf ||
236*2d9fd380Sjfb8856606 			conf_size != sizeof(struct skeleton_rawdev_queue))
237*2d9fd380Sjfb8856606 		return -EINVAL;
2384418919fSjohnjiang 
2394418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
2404418919fSjohnjiang 	skelq = &skeldev->queues[queue_id];
2414418919fSjohnjiang 
2424418919fSjohnjiang 	if (queue_id < SKELETON_MAX_QUEUES)
2434418919fSjohnjiang 		rte_memcpy(queue_conf, skelq,
2444418919fSjohnjiang 			sizeof(struct skeleton_rawdev_queue));
245*2d9fd380Sjfb8856606 
246*2d9fd380Sjfb8856606 	return 0;
2474418919fSjohnjiang }
2484418919fSjohnjiang 
2494418919fSjohnjiang static void
clear_queue_bufs(int queue_id)2504418919fSjohnjiang clear_queue_bufs(int queue_id)
2514418919fSjohnjiang {
2524418919fSjohnjiang 	int i;
2534418919fSjohnjiang 
2544418919fSjohnjiang 	/* Clear buffers for queue_id */
2554418919fSjohnjiang 	for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
2564418919fSjohnjiang 		queue_buf[queue_id].bufs[i] = NULL;
2574418919fSjohnjiang }
2584418919fSjohnjiang 
skeleton_rawdev_queue_setup(struct rte_rawdev * dev,uint16_t queue_id,rte_rawdev_obj_t queue_conf,size_t conf_size)2594418919fSjohnjiang static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
2604418919fSjohnjiang 				       uint16_t queue_id,
261*2d9fd380Sjfb8856606 				       rte_rawdev_obj_t queue_conf,
262*2d9fd380Sjfb8856606 				       size_t conf_size)
2634418919fSjohnjiang {
2644418919fSjohnjiang 	int ret = 0;
2654418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
2664418919fSjohnjiang 	struct skeleton_rawdev_queue *q;
2674418919fSjohnjiang 
2684418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
2694418919fSjohnjiang 
270*2d9fd380Sjfb8856606 	if (!dev || !queue_conf ||
271*2d9fd380Sjfb8856606 			conf_size != sizeof(struct skeleton_rawdev_queue))
2724418919fSjohnjiang 		return -EINVAL;
2734418919fSjohnjiang 
2744418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
2754418919fSjohnjiang 	q = &skeldev->queues[queue_id];
2764418919fSjohnjiang 
2774418919fSjohnjiang 	if (skeldev->num_queues > queue_id &&
2784418919fSjohnjiang 	    q->depth < SKELETON_QUEUE_MAX_DEPTH) {
2794418919fSjohnjiang 		rte_memcpy(q, queue_conf,
2804418919fSjohnjiang 			   sizeof(struct skeleton_rawdev_queue));
2814418919fSjohnjiang 		clear_queue_bufs(queue_id);
2824418919fSjohnjiang 	} else {
2834418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid queue configuration");
2844418919fSjohnjiang 		ret = -EINVAL;
2854418919fSjohnjiang 	}
2864418919fSjohnjiang 
2874418919fSjohnjiang 	return ret;
2884418919fSjohnjiang }
2894418919fSjohnjiang 
skeleton_rawdev_queue_release(struct rte_rawdev * dev,uint16_t queue_id)2904418919fSjohnjiang static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
2914418919fSjohnjiang 					 uint16_t queue_id)
2924418919fSjohnjiang {
2934418919fSjohnjiang 	int ret = 0;
2944418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
2954418919fSjohnjiang 
2964418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
2974418919fSjohnjiang 
2984418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
2994418919fSjohnjiang 
3004418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
3014418919fSjohnjiang 
3024418919fSjohnjiang 	if (skeldev->num_queues > queue_id) {
3034418919fSjohnjiang 		skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
3044418919fSjohnjiang 		skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
3054418919fSjohnjiang 		clear_queue_bufs(queue_id);
3064418919fSjohnjiang 	} else {
3074418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid queue configuration");
3084418919fSjohnjiang 		ret = -EINVAL;
3094418919fSjohnjiang 	}
3104418919fSjohnjiang 
3114418919fSjohnjiang 	return ret;
3124418919fSjohnjiang }
3134418919fSjohnjiang 
skeleton_rawdev_queue_count(struct rte_rawdev * dev)3144418919fSjohnjiang static uint16_t skeleton_rawdev_queue_count(struct rte_rawdev *dev)
3154418919fSjohnjiang {
3164418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
3174418919fSjohnjiang 
3184418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
3194418919fSjohnjiang 
3204418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
3214418919fSjohnjiang 
3224418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
3234418919fSjohnjiang 	return skeldev->num_queues;
3244418919fSjohnjiang }
3254418919fSjohnjiang 
skeleton_rawdev_get_attr(struct rte_rawdev * dev,const char * attr_name,uint64_t * attr_value)3264418919fSjohnjiang static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
3274418919fSjohnjiang 				    const char *attr_name,
3284418919fSjohnjiang 				    uint64_t *attr_value)
3294418919fSjohnjiang {
3304418919fSjohnjiang 	int i;
3314418919fSjohnjiang 	uint8_t done = 0;
3324418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
3334418919fSjohnjiang 
3344418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
3354418919fSjohnjiang 
3364418919fSjohnjiang 	if (!dev || !attr_name || !attr_value) {
3374418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid arguments for getting attributes");
3384418919fSjohnjiang 		return -EINVAL;
3394418919fSjohnjiang 	}
3404418919fSjohnjiang 
3414418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
3424418919fSjohnjiang 
3434418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
3444418919fSjohnjiang 		if (!skeldev->attr[i].name)
3454418919fSjohnjiang 			continue;
3464418919fSjohnjiang 
3474418919fSjohnjiang 		if (!strncmp(skeldev->attr[i].name, attr_name,
3484418919fSjohnjiang 			    SKELETON_ATTRIBUTE_NAME_MAX)) {
3494418919fSjohnjiang 			*attr_value = skeldev->attr[i].value;
3504418919fSjohnjiang 			done = 1;
3514418919fSjohnjiang 			SKELETON_PMD_DEBUG("Attribute (%s) Value (%" PRIu64 ")",
3524418919fSjohnjiang 					   attr_name, *attr_value);
3534418919fSjohnjiang 			break;
3544418919fSjohnjiang 		}
3554418919fSjohnjiang 	}
3564418919fSjohnjiang 
3574418919fSjohnjiang 	if (done)
3584418919fSjohnjiang 		return 0;
3594418919fSjohnjiang 
3604418919fSjohnjiang 	/* Attribute not found */
3614418919fSjohnjiang 	return -EINVAL;
3624418919fSjohnjiang }
3634418919fSjohnjiang 
skeleton_rawdev_set_attr(struct rte_rawdev * dev,const char * attr_name,const uint64_t attr_value)3644418919fSjohnjiang static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
3654418919fSjohnjiang 				     const char *attr_name,
3664418919fSjohnjiang 				     const uint64_t attr_value)
3674418919fSjohnjiang {
3684418919fSjohnjiang 	int i;
3694418919fSjohnjiang 	uint8_t done = 0;
3704418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
3714418919fSjohnjiang 
3724418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
3734418919fSjohnjiang 
3744418919fSjohnjiang 	if (!dev || !attr_name) {
3754418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid arguments for setting attributes");
3764418919fSjohnjiang 		return -EINVAL;
3774418919fSjohnjiang 	}
3784418919fSjohnjiang 
3794418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
3804418919fSjohnjiang 
3814418919fSjohnjiang 	/* Check if attribute already exists */
3824418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
3834418919fSjohnjiang 		if (!skeldev->attr[i].name)
3844418919fSjohnjiang 			break;
3854418919fSjohnjiang 
3864418919fSjohnjiang 		if (!strncmp(skeldev->attr[i].name, attr_name,
3874418919fSjohnjiang 			     SKELETON_ATTRIBUTE_NAME_MAX)) {
3884418919fSjohnjiang 			/* Update value */
3894418919fSjohnjiang 			skeldev->attr[i].value = attr_value;
3904418919fSjohnjiang 			done = 1;
3914418919fSjohnjiang 			break;
3924418919fSjohnjiang 		}
3934418919fSjohnjiang 	}
3944418919fSjohnjiang 
3954418919fSjohnjiang 	if (!done) {
3964418919fSjohnjiang 		if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
3974418919fSjohnjiang 			/* There is still space to insert one more */
3984418919fSjohnjiang 			skeldev->attr[i].name = strdup(attr_name);
3994418919fSjohnjiang 			if (!skeldev->attr[i].name)
4004418919fSjohnjiang 				return -ENOMEM;
4014418919fSjohnjiang 
4024418919fSjohnjiang 			skeldev->attr[i].value = attr_value;
4034418919fSjohnjiang 			return 0;
4044418919fSjohnjiang 		}
4054418919fSjohnjiang 	}
4064418919fSjohnjiang 
4074418919fSjohnjiang 	return -EINVAL;
4084418919fSjohnjiang }
4094418919fSjohnjiang 
skeleton_rawdev_enqueue_bufs(struct rte_rawdev * dev,struct rte_rawdev_buf ** buffers,unsigned int count,rte_rawdev_obj_t context)4104418919fSjohnjiang static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
4114418919fSjohnjiang 					struct rte_rawdev_buf **buffers,
4124418919fSjohnjiang 					unsigned int count,
4134418919fSjohnjiang 					rte_rawdev_obj_t context)
4144418919fSjohnjiang {
4154418919fSjohnjiang 	unsigned int i;
4164418919fSjohnjiang 	uint16_t q_id;
4174418919fSjohnjiang 	RTE_SET_USED(dev);
4184418919fSjohnjiang 
4194418919fSjohnjiang 	/* context is essentially the queue_id which is
4204418919fSjohnjiang 	 * transferred as opaque object through the library layer. This can
4214418919fSjohnjiang 	 * help in complex implementation which require more information than
4224418919fSjohnjiang 	 * just an integer - for example, a queue-pair.
4234418919fSjohnjiang 	 */
4244418919fSjohnjiang 	q_id = *((int *)context);
4254418919fSjohnjiang 
4264418919fSjohnjiang 	for (i = 0; i < count; i++)
4274418919fSjohnjiang 		queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
4284418919fSjohnjiang 
4294418919fSjohnjiang 	return i;
4304418919fSjohnjiang }
4314418919fSjohnjiang 
skeleton_rawdev_dequeue_bufs(struct rte_rawdev * dev,struct rte_rawdev_buf ** buffers,unsigned int count,rte_rawdev_obj_t context)4324418919fSjohnjiang static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
4334418919fSjohnjiang 					struct rte_rawdev_buf **buffers,
4344418919fSjohnjiang 					unsigned int count,
4354418919fSjohnjiang 					rte_rawdev_obj_t context)
4364418919fSjohnjiang {
4374418919fSjohnjiang 	unsigned int i;
4384418919fSjohnjiang 	uint16_t q_id;
4394418919fSjohnjiang 	RTE_SET_USED(dev);
4404418919fSjohnjiang 
4414418919fSjohnjiang 	/* context is essentially the queue_id which is
4424418919fSjohnjiang 	 * transferred as opaque object through the library layer. This can
4434418919fSjohnjiang 	 * help in complex implementation which require more information than
4444418919fSjohnjiang 	 * just an integer - for example, a queue-pair.
4454418919fSjohnjiang 	 */
4464418919fSjohnjiang 	q_id = *((int *)context);
4474418919fSjohnjiang 
4484418919fSjohnjiang 	for (i = 0; i < count; i++)
4494418919fSjohnjiang 		buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
4504418919fSjohnjiang 
4514418919fSjohnjiang 	return i;
4524418919fSjohnjiang }
4534418919fSjohnjiang 
skeleton_rawdev_dump(struct rte_rawdev * dev,FILE * f)4544418919fSjohnjiang static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
4554418919fSjohnjiang {
4564418919fSjohnjiang 	RTE_SET_USED(dev);
4574418919fSjohnjiang 	RTE_SET_USED(f);
4584418919fSjohnjiang 
4594418919fSjohnjiang 	return 0;
4604418919fSjohnjiang }
4614418919fSjohnjiang 
skeleton_rawdev_firmware_status_get(struct rte_rawdev * dev,rte_rawdev_obj_t status_info)4624418919fSjohnjiang static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
4634418919fSjohnjiang 					       rte_rawdev_obj_t status_info)
4644418919fSjohnjiang {
4654418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
4664418919fSjohnjiang 
4674418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
4684418919fSjohnjiang 
4694418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
4704418919fSjohnjiang 
4714418919fSjohnjiang 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
4724418919fSjohnjiang 
4734418919fSjohnjiang 	if (status_info)
4744418919fSjohnjiang 		memcpy(status_info, &skeldev->fw.firmware_state,
4754418919fSjohnjiang 			sizeof(enum skeleton_firmware_state));
4764418919fSjohnjiang 
4774418919fSjohnjiang 	return 0;
4784418919fSjohnjiang }
4794418919fSjohnjiang 
4804418919fSjohnjiang 
skeleton_rawdev_firmware_version_get(struct rte_rawdev * dev,rte_rawdev_obj_t version_info)4814418919fSjohnjiang static int skeleton_rawdev_firmware_version_get(
4824418919fSjohnjiang 					struct rte_rawdev *dev,
4834418919fSjohnjiang 					rte_rawdev_obj_t version_info)
4844418919fSjohnjiang {
4854418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
4864418919fSjohnjiang 	struct skeleton_firmware_version_info *vi;
4874418919fSjohnjiang 
4884418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
4894418919fSjohnjiang 
4904418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
4914418919fSjohnjiang 	vi = version_info;
4924418919fSjohnjiang 
4934418919fSjohnjiang 	vi->major = skeldev->fw.firmware_version.major;
4944418919fSjohnjiang 	vi->minor = skeldev->fw.firmware_version.minor;
4954418919fSjohnjiang 	vi->subrel = skeldev->fw.firmware_version.subrel;
4964418919fSjohnjiang 
4974418919fSjohnjiang 	return 0;
4984418919fSjohnjiang }
4994418919fSjohnjiang 
skeleton_rawdev_firmware_load(struct rte_rawdev * dev,rte_rawdev_obj_t firmware_buf)5004418919fSjohnjiang static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
5014418919fSjohnjiang 					 rte_rawdev_obj_t firmware_buf)
5024418919fSjohnjiang {
5034418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
5044418919fSjohnjiang 
5054418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
5064418919fSjohnjiang 
5074418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
5084418919fSjohnjiang 
5094418919fSjohnjiang 	/* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
5104418919fSjohnjiang 	 * dummy, all this does is check if firmware_buf is not NULL and
5114418919fSjohnjiang 	 * sets the state of the firmware.
5124418919fSjohnjiang 	 */
5134418919fSjohnjiang 	if (!firmware_buf)
5144418919fSjohnjiang 		return -EINVAL;
5154418919fSjohnjiang 
5164418919fSjohnjiang 	skeldev->fw.firmware_state = SKELETON_FW_LOADED;
5174418919fSjohnjiang 
5184418919fSjohnjiang 	return 0;
5194418919fSjohnjiang }
5204418919fSjohnjiang 
skeleton_rawdev_firmware_unload(struct rte_rawdev * dev)5214418919fSjohnjiang static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
5224418919fSjohnjiang {
5234418919fSjohnjiang 	struct skeleton_rawdev *skeldev;
5244418919fSjohnjiang 
5254418919fSjohnjiang 	SKELETON_PMD_FUNC_TRACE();
5264418919fSjohnjiang 
5274418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(dev);
5284418919fSjohnjiang 
5294418919fSjohnjiang 	skeldev->fw.firmware_state = SKELETON_FW_READY;
5304418919fSjohnjiang 
5314418919fSjohnjiang 	return 0;
5324418919fSjohnjiang }
5334418919fSjohnjiang 
5344418919fSjohnjiang static const struct rte_rawdev_ops skeleton_rawdev_ops = {
5354418919fSjohnjiang 	.dev_info_get = skeleton_rawdev_info_get,
5364418919fSjohnjiang 	.dev_configure = skeleton_rawdev_configure,
5374418919fSjohnjiang 	.dev_start = skeleton_rawdev_start,
5384418919fSjohnjiang 	.dev_stop = skeleton_rawdev_stop,
5394418919fSjohnjiang 	.dev_close = skeleton_rawdev_close,
5404418919fSjohnjiang 	.dev_reset = skeleton_rawdev_reset,
5414418919fSjohnjiang 
5424418919fSjohnjiang 	.queue_def_conf = skeleton_rawdev_queue_def_conf,
5434418919fSjohnjiang 	.queue_setup = skeleton_rawdev_queue_setup,
5444418919fSjohnjiang 	.queue_release = skeleton_rawdev_queue_release,
5454418919fSjohnjiang 	.queue_count = skeleton_rawdev_queue_count,
5464418919fSjohnjiang 
5474418919fSjohnjiang 	.attr_get = skeleton_rawdev_get_attr,
5484418919fSjohnjiang 	.attr_set = skeleton_rawdev_set_attr,
5494418919fSjohnjiang 
5504418919fSjohnjiang 	.enqueue_bufs = skeleton_rawdev_enqueue_bufs,
5514418919fSjohnjiang 	.dequeue_bufs = skeleton_rawdev_dequeue_bufs,
5524418919fSjohnjiang 
5534418919fSjohnjiang 	.dump = skeleton_rawdev_dump,
5544418919fSjohnjiang 
5554418919fSjohnjiang 	.xstats_get = NULL,
5564418919fSjohnjiang 	.xstats_get_names = NULL,
5574418919fSjohnjiang 	.xstats_get_by_name = NULL,
5584418919fSjohnjiang 	.xstats_reset = NULL,
5594418919fSjohnjiang 
5604418919fSjohnjiang 	.firmware_status_get = skeleton_rawdev_firmware_status_get,
5614418919fSjohnjiang 	.firmware_version_get = skeleton_rawdev_firmware_version_get,
5624418919fSjohnjiang 	.firmware_load = skeleton_rawdev_firmware_load,
5634418919fSjohnjiang 	.firmware_unload = skeleton_rawdev_firmware_unload,
5644418919fSjohnjiang 
5654418919fSjohnjiang 	.dev_selftest = test_rawdev_skeldev,
5664418919fSjohnjiang };
5674418919fSjohnjiang 
5684418919fSjohnjiang static int
skeleton_rawdev_create(const char * name,struct rte_vdev_device * vdev,int socket_id)5694418919fSjohnjiang skeleton_rawdev_create(const char *name,
5704418919fSjohnjiang 		       struct rte_vdev_device *vdev,
5714418919fSjohnjiang 		       int socket_id)
5724418919fSjohnjiang {
5734418919fSjohnjiang 	int ret = 0, i;
5744418919fSjohnjiang 	struct rte_rawdev *rawdev = NULL;
5754418919fSjohnjiang 	struct skeleton_rawdev *skeldev = NULL;
5764418919fSjohnjiang 
5774418919fSjohnjiang 	if (!name) {
5784418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid name of the device!");
5794418919fSjohnjiang 		ret = -EINVAL;
5804418919fSjohnjiang 		goto cleanup;
5814418919fSjohnjiang 	}
5824418919fSjohnjiang 
5834418919fSjohnjiang 	/* Allocate device structure */
5844418919fSjohnjiang 	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
5854418919fSjohnjiang 					 socket_id);
5864418919fSjohnjiang 	if (rawdev == NULL) {
5874418919fSjohnjiang 		SKELETON_PMD_ERR("Unable to allocate rawdevice");
5884418919fSjohnjiang 		ret = -EINVAL;
5894418919fSjohnjiang 		goto cleanup;
5904418919fSjohnjiang 	}
5914418919fSjohnjiang 
5924418919fSjohnjiang 	ret = rawdev->dev_id; /* return the rawdev id of new device */
5934418919fSjohnjiang 
5944418919fSjohnjiang 	rawdev->dev_ops = &skeleton_rawdev_ops;
5954418919fSjohnjiang 	rawdev->device = &vdev->device;
5964418919fSjohnjiang 
5974418919fSjohnjiang 	skeldev = skeleton_rawdev_get_priv(rawdev);
5984418919fSjohnjiang 
5994418919fSjohnjiang 	skeldev->device_id = SKELETON_DEVICE_ID;
6004418919fSjohnjiang 	skeldev->vendor_id = SKELETON_VENDOR_ID;
6014418919fSjohnjiang 	skeldev->capabilities = SKELETON_DEFAULT_CAPA;
6024418919fSjohnjiang 
6034418919fSjohnjiang 	memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
6044418919fSjohnjiang 
6054418919fSjohnjiang 	skeldev->fw.firmware_state = SKELETON_FW_READY;
6064418919fSjohnjiang 	skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
6074418919fSjohnjiang 	skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
6084418919fSjohnjiang 	skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
6094418919fSjohnjiang 
6104418919fSjohnjiang 	skeldev->device_state = SKELETON_DEV_STOPPED;
6114418919fSjohnjiang 
6124418919fSjohnjiang 	/* Reset/set to default queue configuration for this device */
6134418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
6144418919fSjohnjiang 		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
6154418919fSjohnjiang 		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
6164418919fSjohnjiang 	}
6174418919fSjohnjiang 
6184418919fSjohnjiang 	/* Clear all allocated queue buffers */
6194418919fSjohnjiang 	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
6204418919fSjohnjiang 		clear_queue_bufs(i);
6214418919fSjohnjiang 
6224418919fSjohnjiang 	return ret;
6234418919fSjohnjiang 
6244418919fSjohnjiang cleanup:
6254418919fSjohnjiang 	if (rawdev)
6264418919fSjohnjiang 		rte_rawdev_pmd_release(rawdev);
6274418919fSjohnjiang 
6284418919fSjohnjiang 	return ret;
6294418919fSjohnjiang }
6304418919fSjohnjiang 
6314418919fSjohnjiang static int
skeleton_rawdev_destroy(const char * name)6324418919fSjohnjiang skeleton_rawdev_destroy(const char *name)
6334418919fSjohnjiang {
6344418919fSjohnjiang 	int ret;
6354418919fSjohnjiang 	struct rte_rawdev *rdev;
6364418919fSjohnjiang 
6374418919fSjohnjiang 	if (!name) {
6384418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid device name");
6394418919fSjohnjiang 		return -EINVAL;
6404418919fSjohnjiang 	}
6414418919fSjohnjiang 
6424418919fSjohnjiang 	rdev = rte_rawdev_pmd_get_named_dev(name);
6434418919fSjohnjiang 	if (!rdev) {
6444418919fSjohnjiang 		SKELETON_PMD_ERR("Invalid device name (%s)", name);
6454418919fSjohnjiang 		return -EINVAL;
6464418919fSjohnjiang 	}
6474418919fSjohnjiang 
6484418919fSjohnjiang 	/* rte_rawdev_close is called by pmd_release */
6494418919fSjohnjiang 	ret = rte_rawdev_pmd_release(rdev);
6504418919fSjohnjiang 	if (ret)
6514418919fSjohnjiang 		SKELETON_PMD_DEBUG("Device cleanup failed");
6524418919fSjohnjiang 
6534418919fSjohnjiang 	return 0;
6544418919fSjohnjiang }
6554418919fSjohnjiang 
6564418919fSjohnjiang static int
skeldev_get_selftest(const char * key __rte_unused,const char * value,void * opaque)6574418919fSjohnjiang skeldev_get_selftest(const char *key __rte_unused,
6584418919fSjohnjiang 		     const char *value,
6594418919fSjohnjiang 		     void *opaque)
6604418919fSjohnjiang {
6614418919fSjohnjiang 	int *flag = opaque;
6624418919fSjohnjiang 	*flag = atoi(value);
6634418919fSjohnjiang 	return 0;
6644418919fSjohnjiang }
6654418919fSjohnjiang 
6664418919fSjohnjiang static int
skeldev_parse_vdev_args(struct rte_vdev_device * vdev)6674418919fSjohnjiang skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
6684418919fSjohnjiang {
6694418919fSjohnjiang 	int selftest = 0;
6704418919fSjohnjiang 	const char *name;
6714418919fSjohnjiang 	const char *params;
6724418919fSjohnjiang 
6734418919fSjohnjiang 	static const char *const args[] = {
6744418919fSjohnjiang 		SKELETON_SELFTEST_ARG,
6754418919fSjohnjiang 		NULL
6764418919fSjohnjiang 	};
6774418919fSjohnjiang 
6784418919fSjohnjiang 	name = rte_vdev_device_name(vdev);
6794418919fSjohnjiang 
6804418919fSjohnjiang 	params = rte_vdev_device_args(vdev);
6814418919fSjohnjiang 	if (params != NULL && params[0] != '\0') {
6824418919fSjohnjiang 		struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
6834418919fSjohnjiang 
6844418919fSjohnjiang 		if (!kvlist) {
6854418919fSjohnjiang 			SKELETON_PMD_INFO(
6864418919fSjohnjiang 				"Ignoring unsupported params supplied '%s'",
6874418919fSjohnjiang 				name);
6884418919fSjohnjiang 		} else {
6894418919fSjohnjiang 			int ret = rte_kvargs_process(kvlist,
6904418919fSjohnjiang 					SKELETON_SELFTEST_ARG,
6914418919fSjohnjiang 					skeldev_get_selftest, &selftest);
6924418919fSjohnjiang 			if (ret != 0 || (selftest < 0 || selftest > 1)) {
6934418919fSjohnjiang 				SKELETON_PMD_ERR("%s: Error in parsing args",
6944418919fSjohnjiang 						 name);
6954418919fSjohnjiang 				rte_kvargs_free(kvlist);
6964418919fSjohnjiang 				ret = -1; /* enforce if selftest is invalid */
6974418919fSjohnjiang 				return ret;
6984418919fSjohnjiang 			}
6994418919fSjohnjiang 		}
7004418919fSjohnjiang 
7014418919fSjohnjiang 		rte_kvargs_free(kvlist);
7024418919fSjohnjiang 	}
7034418919fSjohnjiang 
7044418919fSjohnjiang 	return selftest;
7054418919fSjohnjiang }
7064418919fSjohnjiang 
7074418919fSjohnjiang static int
skeleton_rawdev_probe(struct rte_vdev_device * vdev)7084418919fSjohnjiang skeleton_rawdev_probe(struct rte_vdev_device *vdev)
7094418919fSjohnjiang {
7104418919fSjohnjiang 	const char *name;
7114418919fSjohnjiang 	int selftest = 0, ret = 0;
7124418919fSjohnjiang 
7134418919fSjohnjiang 
7144418919fSjohnjiang 	name = rte_vdev_device_name(vdev);
7154418919fSjohnjiang 	if (name == NULL)
7164418919fSjohnjiang 		return -EINVAL;
7174418919fSjohnjiang 
7184418919fSjohnjiang 	/* More than one instance is not supported */
7194418919fSjohnjiang 	if (skeldev_init_once) {
7204418919fSjohnjiang 		SKELETON_PMD_ERR("Multiple instance not supported for %s",
7214418919fSjohnjiang 				 name);
7224418919fSjohnjiang 		return -EINVAL;
7234418919fSjohnjiang 	}
7244418919fSjohnjiang 
7254418919fSjohnjiang 	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
7264418919fSjohnjiang 
7274418919fSjohnjiang 	selftest = skeldev_parse_vdev_args(vdev);
7284418919fSjohnjiang 	/* In case of invalid argument, selftest != 1; ignore other values */
7294418919fSjohnjiang 
7304418919fSjohnjiang 	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
7314418919fSjohnjiang 	if (ret >= 0) {
7324418919fSjohnjiang 		/* In case command line argument for 'selftest' was passed;
7334418919fSjohnjiang 		 * if invalid arguments were passed, execution continues but
7344418919fSjohnjiang 		 * without selftest.
7354418919fSjohnjiang 		 */
7364418919fSjohnjiang 		if (selftest == 1)
7374418919fSjohnjiang 			test_rawdev_skeldev(ret);
7384418919fSjohnjiang 	}
7394418919fSjohnjiang 
7404418919fSjohnjiang 	/* Device instance created; Second instance not possible */
7414418919fSjohnjiang 	skeldev_init_once = 1;
7424418919fSjohnjiang 
7434418919fSjohnjiang 	return ret < 0 ? ret : 0;
7444418919fSjohnjiang }
7454418919fSjohnjiang 
7464418919fSjohnjiang static int
skeleton_rawdev_remove(struct rte_vdev_device * vdev)7474418919fSjohnjiang skeleton_rawdev_remove(struct rte_vdev_device *vdev)
7484418919fSjohnjiang {
7494418919fSjohnjiang 	const char *name;
7504418919fSjohnjiang 	int ret;
7514418919fSjohnjiang 
7524418919fSjohnjiang 	name = rte_vdev_device_name(vdev);
7534418919fSjohnjiang 	if (name == NULL)
7544418919fSjohnjiang 		return -1;
7554418919fSjohnjiang 
7564418919fSjohnjiang 	SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
7574418919fSjohnjiang 
7584418919fSjohnjiang 	ret = skeleton_rawdev_destroy(name);
7594418919fSjohnjiang 	if (!ret)
7604418919fSjohnjiang 		skeldev_init_once = 0;
7614418919fSjohnjiang 
7624418919fSjohnjiang 	return ret;
7634418919fSjohnjiang }
7644418919fSjohnjiang 
7654418919fSjohnjiang static struct rte_vdev_driver skeleton_pmd_drv = {
7664418919fSjohnjiang 	.probe = skeleton_rawdev_probe,
7674418919fSjohnjiang 	.remove = skeleton_rawdev_remove
7684418919fSjohnjiang };
7694418919fSjohnjiang 
7704418919fSjohnjiang RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
771*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(skeleton_pmd_logtype, rawdev.skeleton, INFO);
772