xref: /dpdk/drivers/raw/skeleton/skeleton_rawdev.c (revision eeded204)
1473c88f9SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2473c88f9SBruce Richardson  * Copyright 2017 NXP
3473c88f9SBruce Richardson  */
4473c88f9SBruce Richardson 
5473c88f9SBruce Richardson #include <assert.h>
6473c88f9SBruce Richardson #include <stdio.h>
7473c88f9SBruce Richardson #include <stdbool.h>
8473c88f9SBruce Richardson #include <errno.h>
9473c88f9SBruce Richardson #include <stdint.h>
10473c88f9SBruce Richardson #include <inttypes.h>
11473c88f9SBruce Richardson #include <string.h>
12473c88f9SBruce Richardson 
13473c88f9SBruce Richardson #include <rte_byteorder.h>
14473c88f9SBruce Richardson #include <rte_common.h>
15473c88f9SBruce Richardson #include <rte_debug.h>
16473c88f9SBruce Richardson #include <rte_dev.h>
17473c88f9SBruce Richardson #include <rte_eal.h>
18473c88f9SBruce Richardson #include <rte_kvargs.h>
19473c88f9SBruce Richardson #include <rte_log.h>
20473c88f9SBruce Richardson #include <rte_malloc.h>
21473c88f9SBruce Richardson #include <rte_memory.h>
22473c88f9SBruce Richardson #include <rte_memcpy.h>
23473c88f9SBruce Richardson #include <rte_lcore.h>
24473c88f9SBruce Richardson #include <rte_bus_vdev.h>
25473c88f9SBruce Richardson 
26473c88f9SBruce Richardson #include <rte_rawdev.h>
27473c88f9SBruce Richardson #include <rte_rawdev_pmd.h>
28473c88f9SBruce Richardson 
29473c88f9SBruce Richardson #include "skeleton_rawdev.h"
30473c88f9SBruce Richardson 
31473c88f9SBruce Richardson /* Count of instances */
32473c88f9SBruce Richardson static uint16_t skeldev_init_once;
33473c88f9SBruce Richardson 
34473c88f9SBruce Richardson /**< Rawdev Skeleton dummy driver name */
35473c88f9SBruce Richardson #define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
36473c88f9SBruce Richardson 
37473c88f9SBruce Richardson struct queue_buffers {
38473c88f9SBruce Richardson 	void *bufs[SKELETON_QUEUE_MAX_DEPTH];
39473c88f9SBruce Richardson };
40473c88f9SBruce Richardson 
41473c88f9SBruce Richardson static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {};
42473c88f9SBruce Richardson static void clear_queue_bufs(int queue_id);
43473c88f9SBruce Richardson 
skeleton_rawdev_info_get(struct rte_rawdev * dev,rte_rawdev_obj_t dev_info,size_t dev_info_size)44f150dd88SBruce Richardson static int skeleton_rawdev_info_get(struct rte_rawdev *dev,
4510b71caeSBruce Richardson 				     rte_rawdev_obj_t dev_info,
4610b71caeSBruce Richardson 				     size_t dev_info_size)
47473c88f9SBruce Richardson {
48473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
49473c88f9SBruce Richardson 	struct skeleton_rawdev_conf *skeldev_conf;
50473c88f9SBruce Richardson 
51473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
52473c88f9SBruce Richardson 
5310b71caeSBruce Richardson 	if (!dev_info || dev_info_size != sizeof(*skeldev_conf)) {
54473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid request");
55f150dd88SBruce Richardson 		return -EINVAL;
56473c88f9SBruce Richardson 	}
57473c88f9SBruce Richardson 
58473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
59473c88f9SBruce Richardson 
60473c88f9SBruce Richardson 	skeldev_conf = dev_info;
61473c88f9SBruce Richardson 
62473c88f9SBruce Richardson 	skeldev_conf->num_queues = skeldev->num_queues;
63473c88f9SBruce Richardson 	skeldev_conf->capabilities = skeldev->capabilities;
64473c88f9SBruce Richardson 	skeldev_conf->device_state = skeldev->device_state;
65473c88f9SBruce Richardson 	skeldev_conf->firmware_state = skeldev->fw.firmware_state;
66f150dd88SBruce Richardson 
67f150dd88SBruce Richardson 	return 0;
68473c88f9SBruce Richardson }
69473c88f9SBruce Richardson 
skeleton_rawdev_configure(const struct rte_rawdev * dev,rte_rawdev_obj_t config,size_t config_size)70473c88f9SBruce Richardson static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
718db9dce7SBruce Richardson 				     rte_rawdev_obj_t config,
728db9dce7SBruce Richardson 				     size_t config_size)
73473c88f9SBruce Richardson {
74473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
75473c88f9SBruce Richardson 	struct skeleton_rawdev_conf *skeldev_conf;
76473c88f9SBruce Richardson 
77473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
78473c88f9SBruce Richardson 
79473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
80473c88f9SBruce Richardson 
818db9dce7SBruce Richardson 	if (config == NULL || config_size != sizeof(*skeldev_conf)) {
82473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid configuration");
83473c88f9SBruce Richardson 		return -EINVAL;
84473c88f9SBruce Richardson 	}
85473c88f9SBruce Richardson 
86473c88f9SBruce Richardson 	skeldev_conf = config;
87473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
88473c88f9SBruce Richardson 
89473c88f9SBruce Richardson 	if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
90473c88f9SBruce Richardson 		skeldev->num_queues = skeldev_conf->num_queues;
91473c88f9SBruce Richardson 	else
92473c88f9SBruce Richardson 		return -EINVAL;
93473c88f9SBruce Richardson 
94473c88f9SBruce Richardson 	skeldev->capabilities = skeldev_conf->capabilities;
95473c88f9SBruce Richardson 	skeldev->num_queues = skeldev_conf->num_queues;
96473c88f9SBruce Richardson 
97473c88f9SBruce Richardson 	return 0;
98473c88f9SBruce Richardson }
99473c88f9SBruce Richardson 
skeleton_rawdev_start(struct rte_rawdev * dev)100473c88f9SBruce Richardson static int skeleton_rawdev_start(struct rte_rawdev *dev)
101473c88f9SBruce Richardson {
102473c88f9SBruce Richardson 	int ret = 0;
103473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
104473c88f9SBruce Richardson 	enum skeleton_firmware_state fw_state;
105473c88f9SBruce Richardson 	enum skeleton_device_state device_state;
106473c88f9SBruce Richardson 
107473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
108473c88f9SBruce Richardson 
109473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
110473c88f9SBruce Richardson 
111473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
112473c88f9SBruce Richardson 
113473c88f9SBruce Richardson 	fw_state = skeldev->fw.firmware_state;
114473c88f9SBruce Richardson 	device_state = skeldev->device_state;
115473c88f9SBruce Richardson 
116473c88f9SBruce Richardson 	if (fw_state == SKELETON_FW_LOADED &&
117473c88f9SBruce Richardson 		device_state == SKELETON_DEV_STOPPED) {
118473c88f9SBruce Richardson 		skeldev->device_state = SKELETON_DEV_RUNNING;
119473c88f9SBruce Richardson 	} else {
120473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Device not ready for starting");
121473c88f9SBruce Richardson 		ret = -EINVAL;
122473c88f9SBruce Richardson 	}
123473c88f9SBruce Richardson 
124473c88f9SBruce Richardson 	return ret;
125473c88f9SBruce Richardson }
126473c88f9SBruce Richardson 
skeleton_rawdev_stop(struct rte_rawdev * dev)127473c88f9SBruce Richardson static void skeleton_rawdev_stop(struct rte_rawdev *dev)
128473c88f9SBruce Richardson {
129473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
130473c88f9SBruce Richardson 
131473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
132473c88f9SBruce Richardson 
133473c88f9SBruce Richardson 	if (dev) {
134473c88f9SBruce Richardson 		skeldev = skeleton_rawdev_get_priv(dev);
135473c88f9SBruce Richardson 		skeldev->device_state = SKELETON_DEV_STOPPED;
136473c88f9SBruce Richardson 	}
137473c88f9SBruce Richardson }
138473c88f9SBruce Richardson 
139473c88f9SBruce Richardson static void
reset_queues(struct skeleton_rawdev * skeldev)140473c88f9SBruce Richardson reset_queues(struct skeleton_rawdev *skeldev)
141473c88f9SBruce Richardson {
142473c88f9SBruce Richardson 	int i;
143473c88f9SBruce Richardson 
144473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
145473c88f9SBruce Richardson 		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
146473c88f9SBruce Richardson 		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
147473c88f9SBruce Richardson 	}
148473c88f9SBruce Richardson }
149473c88f9SBruce Richardson 
150473c88f9SBruce Richardson static void
reset_attribute_table(struct skeleton_rawdev * skeldev)151473c88f9SBruce Richardson reset_attribute_table(struct skeleton_rawdev *skeldev)
152473c88f9SBruce Richardson {
153473c88f9SBruce Richardson 	int i;
154473c88f9SBruce Richardson 
155473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
156473c88f9SBruce Richardson 		if (skeldev->attr[i].name) {
157473c88f9SBruce Richardson 			free(skeldev->attr[i].name);
158473c88f9SBruce Richardson 			skeldev->attr[i].name = NULL;
159473c88f9SBruce Richardson 		}
160473c88f9SBruce Richardson 	}
161473c88f9SBruce Richardson }
162473c88f9SBruce Richardson 
skeleton_rawdev_close(struct rte_rawdev * dev)163473c88f9SBruce Richardson static int skeleton_rawdev_close(struct rte_rawdev *dev)
164473c88f9SBruce Richardson {
165473c88f9SBruce Richardson 	int ret = 0, i;
166473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
167473c88f9SBruce Richardson 	enum skeleton_firmware_state fw_state;
168473c88f9SBruce Richardson 	enum skeleton_device_state device_state;
169473c88f9SBruce Richardson 
170473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
171473c88f9SBruce Richardson 
172473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
173473c88f9SBruce Richardson 
174473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
175473c88f9SBruce Richardson 
176473c88f9SBruce Richardson 	fw_state = skeldev->fw.firmware_state;
177473c88f9SBruce Richardson 	device_state = skeldev->device_state;
178473c88f9SBruce Richardson 
179473c88f9SBruce Richardson 	reset_queues(skeldev);
180473c88f9SBruce Richardson 	reset_attribute_table(skeldev);
181473c88f9SBruce Richardson 
182473c88f9SBruce Richardson 	switch (fw_state) {
183473c88f9SBruce Richardson 	case SKELETON_FW_LOADED:
184473c88f9SBruce Richardson 		if (device_state == SKELETON_DEV_RUNNING) {
185473c88f9SBruce Richardson 			SKELETON_PMD_ERR("Cannot close running device");
186473c88f9SBruce Richardson 			ret = -EINVAL;
187473c88f9SBruce Richardson 		} else {
188473c88f9SBruce Richardson 			/* Probably call fw reset here */
189473c88f9SBruce Richardson 			skeldev->fw.firmware_state = SKELETON_FW_READY;
190473c88f9SBruce Richardson 		}
191473c88f9SBruce Richardson 		break;
192473c88f9SBruce Richardson 	case SKELETON_FW_READY:
193e640362bSLukasz Wojciechowski 		SKELETON_PMD_DEBUG("Device already in stopped state");
194e640362bSLukasz Wojciechowski 		break;
195473c88f9SBruce Richardson 	case SKELETON_FW_ERROR:
196473c88f9SBruce Richardson 	default:
197e640362bSLukasz Wojciechowski 		SKELETON_PMD_DEBUG("Device in impossible state");
198473c88f9SBruce Richardson 		ret = -EINVAL;
199473c88f9SBruce Richardson 		break;
200473c88f9SBruce Richardson 	}
201473c88f9SBruce Richardson 
202473c88f9SBruce Richardson 	/* Clear all allocated queues */
203473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
204473c88f9SBruce Richardson 		clear_queue_bufs(i);
205473c88f9SBruce Richardson 
206473c88f9SBruce Richardson 	return ret;
207473c88f9SBruce Richardson }
208473c88f9SBruce Richardson 
skeleton_rawdev_reset(struct rte_rawdev * dev)209473c88f9SBruce Richardson static int skeleton_rawdev_reset(struct rte_rawdev *dev)
210473c88f9SBruce Richardson {
211473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
212473c88f9SBruce Richardson 
213473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
214473c88f9SBruce Richardson 
215473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
216473c88f9SBruce Richardson 
217473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
218473c88f9SBruce Richardson 
219473c88f9SBruce Richardson 	SKELETON_PMD_DEBUG("Resetting device");
220473c88f9SBruce Richardson 	skeldev->fw.firmware_state = SKELETON_FW_READY;
221473c88f9SBruce Richardson 
222473c88f9SBruce Richardson 	return 0;
223473c88f9SBruce Richardson }
224473c88f9SBruce Richardson 
skeleton_rawdev_queue_def_conf(struct rte_rawdev * dev,uint16_t queue_id,rte_rawdev_obj_t queue_conf,size_t conf_size)22513f8e4a2SBruce Richardson static int skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
226473c88f9SBruce Richardson 					  uint16_t queue_id,
227f574ed81SBruce Richardson 					  rte_rawdev_obj_t queue_conf,
228f574ed81SBruce Richardson 					  size_t conf_size)
229473c88f9SBruce Richardson {
230473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
231473c88f9SBruce Richardson 	struct skeleton_rawdev_queue *skelq;
232473c88f9SBruce Richardson 
233473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
234473c88f9SBruce Richardson 
235f574ed81SBruce Richardson 	if (!dev || !queue_conf ||
236f574ed81SBruce Richardson 			conf_size != sizeof(struct skeleton_rawdev_queue))
23713f8e4a2SBruce Richardson 		return -EINVAL;
238473c88f9SBruce Richardson 
239473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
240473c88f9SBruce Richardson 	skelq = &skeldev->queues[queue_id];
241473c88f9SBruce Richardson 
242473c88f9SBruce Richardson 	if (queue_id < SKELETON_MAX_QUEUES)
243473c88f9SBruce Richardson 		rte_memcpy(queue_conf, skelq,
244473c88f9SBruce Richardson 			sizeof(struct skeleton_rawdev_queue));
24513f8e4a2SBruce Richardson 
24613f8e4a2SBruce Richardson 	return 0;
247473c88f9SBruce Richardson }
248473c88f9SBruce Richardson 
249473c88f9SBruce Richardson static void
clear_queue_bufs(int queue_id)250473c88f9SBruce Richardson clear_queue_bufs(int queue_id)
251473c88f9SBruce Richardson {
252473c88f9SBruce Richardson 	int i;
253473c88f9SBruce Richardson 
254473c88f9SBruce Richardson 	/* Clear buffers for queue_id */
255473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
256473c88f9SBruce Richardson 		queue_buf[queue_id].bufs[i] = NULL;
257473c88f9SBruce Richardson }
258473c88f9SBruce Richardson 
skeleton_rawdev_queue_setup(struct rte_rawdev * dev,uint16_t queue_id,rte_rawdev_obj_t queue_conf,size_t conf_size)259473c88f9SBruce Richardson static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
260473c88f9SBruce Richardson 				       uint16_t queue_id,
261f574ed81SBruce Richardson 				       rte_rawdev_obj_t queue_conf,
262f574ed81SBruce Richardson 				       size_t conf_size)
263473c88f9SBruce Richardson {
264473c88f9SBruce Richardson 	int ret = 0;
265473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
266473c88f9SBruce Richardson 	struct skeleton_rawdev_queue *q;
267473c88f9SBruce Richardson 
268473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
269473c88f9SBruce Richardson 
270f574ed81SBruce Richardson 	if (!dev || !queue_conf ||
271f574ed81SBruce Richardson 			conf_size != sizeof(struct skeleton_rawdev_queue))
272473c88f9SBruce Richardson 		return -EINVAL;
273473c88f9SBruce Richardson 
274473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
275473c88f9SBruce Richardson 	q = &skeldev->queues[queue_id];
276473c88f9SBruce Richardson 
277473c88f9SBruce Richardson 	if (skeldev->num_queues > queue_id &&
278473c88f9SBruce Richardson 	    q->depth < SKELETON_QUEUE_MAX_DEPTH) {
279473c88f9SBruce Richardson 		rte_memcpy(q, queue_conf,
280473c88f9SBruce Richardson 			   sizeof(struct skeleton_rawdev_queue));
281473c88f9SBruce Richardson 		clear_queue_bufs(queue_id);
282473c88f9SBruce Richardson 	} else {
283473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid queue configuration");
284473c88f9SBruce Richardson 		ret = -EINVAL;
285473c88f9SBruce Richardson 	}
286473c88f9SBruce Richardson 
287473c88f9SBruce Richardson 	return ret;
288473c88f9SBruce Richardson }
289473c88f9SBruce Richardson 
skeleton_rawdev_queue_release(struct rte_rawdev * dev,uint16_t queue_id)290473c88f9SBruce Richardson static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
291473c88f9SBruce Richardson 					 uint16_t queue_id)
292473c88f9SBruce Richardson {
293473c88f9SBruce Richardson 	int ret = 0;
294473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
295473c88f9SBruce Richardson 
296473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
297473c88f9SBruce Richardson 
298473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
299473c88f9SBruce Richardson 
300473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
301473c88f9SBruce Richardson 
302473c88f9SBruce Richardson 	if (skeldev->num_queues > queue_id) {
303473c88f9SBruce Richardson 		skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
304473c88f9SBruce Richardson 		skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
305473c88f9SBruce Richardson 		clear_queue_bufs(queue_id);
306473c88f9SBruce Richardson 	} else {
307473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid queue configuration");
308473c88f9SBruce Richardson 		ret = -EINVAL;
309473c88f9SBruce Richardson 	}
310473c88f9SBruce Richardson 
311473c88f9SBruce Richardson 	return ret;
312473c88f9SBruce Richardson }
313473c88f9SBruce Richardson 
skeleton_rawdev_queue_count(struct rte_rawdev * dev)314473c88f9SBruce Richardson static uint16_t skeleton_rawdev_queue_count(struct rte_rawdev *dev)
315473c88f9SBruce Richardson {
316473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
317473c88f9SBruce Richardson 
318473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
319473c88f9SBruce Richardson 
320473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
321473c88f9SBruce Richardson 
322473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
323473c88f9SBruce Richardson 	return skeldev->num_queues;
324473c88f9SBruce Richardson }
325473c88f9SBruce Richardson 
skeleton_rawdev_get_attr(struct rte_rawdev * dev,const char * attr_name,uint64_t * attr_value)326473c88f9SBruce Richardson static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
327473c88f9SBruce Richardson 				    const char *attr_name,
328473c88f9SBruce Richardson 				    uint64_t *attr_value)
329473c88f9SBruce Richardson {
330473c88f9SBruce Richardson 	int i;
331473c88f9SBruce Richardson 	uint8_t done = 0;
332473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
333473c88f9SBruce Richardson 
334473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
335473c88f9SBruce Richardson 
336473c88f9SBruce Richardson 	if (!dev || !attr_name || !attr_value) {
337473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid arguments for getting attributes");
338473c88f9SBruce Richardson 		return -EINVAL;
339473c88f9SBruce Richardson 	}
340473c88f9SBruce Richardson 
341473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
342473c88f9SBruce Richardson 
343473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
344473c88f9SBruce Richardson 		if (!skeldev->attr[i].name)
345473c88f9SBruce Richardson 			continue;
346473c88f9SBruce Richardson 
347473c88f9SBruce Richardson 		if (!strncmp(skeldev->attr[i].name, attr_name,
348473c88f9SBruce Richardson 			    SKELETON_ATTRIBUTE_NAME_MAX)) {
349473c88f9SBruce Richardson 			*attr_value = skeldev->attr[i].value;
350473c88f9SBruce Richardson 			done = 1;
351473c88f9SBruce Richardson 			SKELETON_PMD_DEBUG("Attribute (%s) Value (%" PRIu64 ")",
352473c88f9SBruce Richardson 					   attr_name, *attr_value);
353473c88f9SBruce Richardson 			break;
354473c88f9SBruce Richardson 		}
355473c88f9SBruce Richardson 	}
356473c88f9SBruce Richardson 
357473c88f9SBruce Richardson 	if (done)
358473c88f9SBruce Richardson 		return 0;
359473c88f9SBruce Richardson 
360473c88f9SBruce Richardson 	/* Attribute not found */
361473c88f9SBruce Richardson 	return -EINVAL;
362473c88f9SBruce Richardson }
363473c88f9SBruce Richardson 
skeleton_rawdev_set_attr(struct rte_rawdev * dev,const char * attr_name,const uint64_t attr_value)364473c88f9SBruce Richardson static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
365473c88f9SBruce Richardson 				     const char *attr_name,
366473c88f9SBruce Richardson 				     const uint64_t attr_value)
367473c88f9SBruce Richardson {
368473c88f9SBruce Richardson 	int i;
369473c88f9SBruce Richardson 	uint8_t done = 0;
370473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
371473c88f9SBruce Richardson 
372473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
373473c88f9SBruce Richardson 
374473c88f9SBruce Richardson 	if (!dev || !attr_name) {
375473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid arguments for setting attributes");
376473c88f9SBruce Richardson 		return -EINVAL;
377473c88f9SBruce Richardson 	}
378473c88f9SBruce Richardson 
379473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
380473c88f9SBruce Richardson 
381473c88f9SBruce Richardson 	/* Check if attribute already exists */
382473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
383473c88f9SBruce Richardson 		if (!skeldev->attr[i].name)
384473c88f9SBruce Richardson 			break;
385473c88f9SBruce Richardson 
386473c88f9SBruce Richardson 		if (!strncmp(skeldev->attr[i].name, attr_name,
387473c88f9SBruce Richardson 			     SKELETON_ATTRIBUTE_NAME_MAX)) {
388473c88f9SBruce Richardson 			/* Update value */
389473c88f9SBruce Richardson 			skeldev->attr[i].value = attr_value;
390473c88f9SBruce Richardson 			done = 1;
391473c88f9SBruce Richardson 			break;
392473c88f9SBruce Richardson 		}
393473c88f9SBruce Richardson 	}
394473c88f9SBruce Richardson 
395473c88f9SBruce Richardson 	if (!done) {
396473c88f9SBruce Richardson 		if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
397473c88f9SBruce Richardson 			/* There is still space to insert one more */
398473c88f9SBruce Richardson 			skeldev->attr[i].name = strdup(attr_name);
399473c88f9SBruce Richardson 			if (!skeldev->attr[i].name)
400473c88f9SBruce Richardson 				return -ENOMEM;
401473c88f9SBruce Richardson 
402473c88f9SBruce Richardson 			skeldev->attr[i].value = attr_value;
403473c88f9SBruce Richardson 			return 0;
404473c88f9SBruce Richardson 		}
405473c88f9SBruce Richardson 	}
406473c88f9SBruce Richardson 
407473c88f9SBruce Richardson 	return -EINVAL;
408473c88f9SBruce Richardson }
409473c88f9SBruce Richardson 
skeleton_rawdev_enqueue_bufs(struct rte_rawdev * dev,struct rte_rawdev_buf ** buffers,unsigned int count,rte_rawdev_obj_t context)410473c88f9SBruce Richardson static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
411473c88f9SBruce Richardson 					struct rte_rawdev_buf **buffers,
412473c88f9SBruce Richardson 					unsigned int count,
413473c88f9SBruce Richardson 					rte_rawdev_obj_t context)
414473c88f9SBruce Richardson {
415473c88f9SBruce Richardson 	unsigned int i;
416473c88f9SBruce Richardson 	uint16_t q_id;
417473c88f9SBruce Richardson 	RTE_SET_USED(dev);
418473c88f9SBruce Richardson 
419473c88f9SBruce Richardson 	/* context is essentially the queue_id which is
420473c88f9SBruce Richardson 	 * transferred as opaque object through the library layer. This can
421473c88f9SBruce Richardson 	 * help in complex implementation which require more information than
422473c88f9SBruce Richardson 	 * just an integer - for example, a queue-pair.
423473c88f9SBruce Richardson 	 */
424473c88f9SBruce Richardson 	q_id = *((int *)context);
425473c88f9SBruce Richardson 
426473c88f9SBruce Richardson 	for (i = 0; i < count; i++)
427473c88f9SBruce Richardson 		queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
428473c88f9SBruce Richardson 
429473c88f9SBruce Richardson 	return i;
430473c88f9SBruce Richardson }
431473c88f9SBruce Richardson 
skeleton_rawdev_dequeue_bufs(struct rte_rawdev * dev,struct rte_rawdev_buf ** buffers,unsigned int count,rte_rawdev_obj_t context)432473c88f9SBruce Richardson static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
433473c88f9SBruce Richardson 					struct rte_rawdev_buf **buffers,
434473c88f9SBruce Richardson 					unsigned int count,
435473c88f9SBruce Richardson 					rte_rawdev_obj_t context)
436473c88f9SBruce Richardson {
437473c88f9SBruce Richardson 	unsigned int i;
438473c88f9SBruce Richardson 	uint16_t q_id;
439473c88f9SBruce Richardson 	RTE_SET_USED(dev);
440473c88f9SBruce Richardson 
441473c88f9SBruce Richardson 	/* context is essentially the queue_id which is
442473c88f9SBruce Richardson 	 * transferred as opaque object through the library layer. This can
443473c88f9SBruce Richardson 	 * help in complex implementation which require more information than
444473c88f9SBruce Richardson 	 * just an integer - for example, a queue-pair.
445473c88f9SBruce Richardson 	 */
446473c88f9SBruce Richardson 	q_id = *((int *)context);
447473c88f9SBruce Richardson 
448473c88f9SBruce Richardson 	for (i = 0; i < count; i++)
449473c88f9SBruce Richardson 		buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
450473c88f9SBruce Richardson 
451473c88f9SBruce Richardson 	return i;
452473c88f9SBruce Richardson }
453473c88f9SBruce Richardson 
skeleton_rawdev_dump(struct rte_rawdev * dev,FILE * f)454473c88f9SBruce Richardson static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
455473c88f9SBruce Richardson {
456473c88f9SBruce Richardson 	RTE_SET_USED(dev);
457473c88f9SBruce Richardson 	RTE_SET_USED(f);
458473c88f9SBruce Richardson 
459473c88f9SBruce Richardson 	return 0;
460473c88f9SBruce Richardson }
461473c88f9SBruce Richardson 
skeleton_rawdev_firmware_status_get(struct rte_rawdev * dev,rte_rawdev_obj_t status_info)462473c88f9SBruce Richardson static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
463473c88f9SBruce Richardson 					       rte_rawdev_obj_t status_info)
464473c88f9SBruce Richardson {
465473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
466473c88f9SBruce Richardson 
467473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
468473c88f9SBruce Richardson 
469473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
470473c88f9SBruce Richardson 
471473c88f9SBruce Richardson 	RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL);
472473c88f9SBruce Richardson 
473473c88f9SBruce Richardson 	if (status_info)
474473c88f9SBruce Richardson 		memcpy(status_info, &skeldev->fw.firmware_state,
475473c88f9SBruce Richardson 			sizeof(enum skeleton_firmware_state));
476473c88f9SBruce Richardson 
477473c88f9SBruce Richardson 	return 0;
478473c88f9SBruce Richardson }
479473c88f9SBruce Richardson 
480473c88f9SBruce Richardson 
skeleton_rawdev_firmware_version_get(struct rte_rawdev * dev,rte_rawdev_obj_t version_info)481473c88f9SBruce Richardson static int skeleton_rawdev_firmware_version_get(
482473c88f9SBruce Richardson 					struct rte_rawdev *dev,
483473c88f9SBruce Richardson 					rte_rawdev_obj_t version_info)
484473c88f9SBruce Richardson {
485473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
486473c88f9SBruce Richardson 	struct skeleton_firmware_version_info *vi;
487473c88f9SBruce Richardson 
488473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
489473c88f9SBruce Richardson 
490473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
491473c88f9SBruce Richardson 	vi = version_info;
492473c88f9SBruce Richardson 
493473c88f9SBruce Richardson 	vi->major = skeldev->fw.firmware_version.major;
494473c88f9SBruce Richardson 	vi->minor = skeldev->fw.firmware_version.minor;
495473c88f9SBruce Richardson 	vi->subrel = skeldev->fw.firmware_version.subrel;
496473c88f9SBruce Richardson 
497473c88f9SBruce Richardson 	return 0;
498473c88f9SBruce Richardson }
499473c88f9SBruce Richardson 
skeleton_rawdev_firmware_load(struct rte_rawdev * dev,rte_rawdev_obj_t firmware_buf)500473c88f9SBruce Richardson static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
501473c88f9SBruce Richardson 					 rte_rawdev_obj_t firmware_buf)
502473c88f9SBruce Richardson {
503473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
504473c88f9SBruce Richardson 
505473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
506473c88f9SBruce Richardson 
507473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
508473c88f9SBruce Richardson 
509473c88f9SBruce Richardson 	/* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
510473c88f9SBruce Richardson 	 * dummy, all this does is check if firmware_buf is not NULL and
511473c88f9SBruce Richardson 	 * sets the state of the firmware.
512473c88f9SBruce Richardson 	 */
513473c88f9SBruce Richardson 	if (!firmware_buf)
514473c88f9SBruce Richardson 		return -EINVAL;
515473c88f9SBruce Richardson 
516473c88f9SBruce Richardson 	skeldev->fw.firmware_state = SKELETON_FW_LOADED;
517473c88f9SBruce Richardson 
518473c88f9SBruce Richardson 	return 0;
519473c88f9SBruce Richardson }
520473c88f9SBruce Richardson 
skeleton_rawdev_firmware_unload(struct rte_rawdev * dev)521473c88f9SBruce Richardson static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
522473c88f9SBruce Richardson {
523473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev;
524473c88f9SBruce Richardson 
525473c88f9SBruce Richardson 	SKELETON_PMD_FUNC_TRACE();
526473c88f9SBruce Richardson 
527473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(dev);
528473c88f9SBruce Richardson 
529473c88f9SBruce Richardson 	skeldev->fw.firmware_state = SKELETON_FW_READY;
530473c88f9SBruce Richardson 
531473c88f9SBruce Richardson 	return 0;
532473c88f9SBruce Richardson }
533473c88f9SBruce Richardson 
534473c88f9SBruce Richardson static const struct rte_rawdev_ops skeleton_rawdev_ops = {
535473c88f9SBruce Richardson 	.dev_info_get = skeleton_rawdev_info_get,
536473c88f9SBruce Richardson 	.dev_configure = skeleton_rawdev_configure,
537473c88f9SBruce Richardson 	.dev_start = skeleton_rawdev_start,
538473c88f9SBruce Richardson 	.dev_stop = skeleton_rawdev_stop,
539473c88f9SBruce Richardson 	.dev_close = skeleton_rawdev_close,
540473c88f9SBruce Richardson 	.dev_reset = skeleton_rawdev_reset,
541473c88f9SBruce Richardson 
542473c88f9SBruce Richardson 	.queue_def_conf = skeleton_rawdev_queue_def_conf,
543473c88f9SBruce Richardson 	.queue_setup = skeleton_rawdev_queue_setup,
544473c88f9SBruce Richardson 	.queue_release = skeleton_rawdev_queue_release,
545473c88f9SBruce Richardson 	.queue_count = skeleton_rawdev_queue_count,
546473c88f9SBruce Richardson 
547473c88f9SBruce Richardson 	.attr_get = skeleton_rawdev_get_attr,
548473c88f9SBruce Richardson 	.attr_set = skeleton_rawdev_set_attr,
549473c88f9SBruce Richardson 
550473c88f9SBruce Richardson 	.enqueue_bufs = skeleton_rawdev_enqueue_bufs,
551473c88f9SBruce Richardson 	.dequeue_bufs = skeleton_rawdev_dequeue_bufs,
552473c88f9SBruce Richardson 
553473c88f9SBruce Richardson 	.dump = skeleton_rawdev_dump,
554473c88f9SBruce Richardson 
555473c88f9SBruce Richardson 	.xstats_get = NULL,
556473c88f9SBruce Richardson 	.xstats_get_names = NULL,
557473c88f9SBruce Richardson 	.xstats_get_by_name = NULL,
558473c88f9SBruce Richardson 	.xstats_reset = NULL,
559473c88f9SBruce Richardson 
560473c88f9SBruce Richardson 	.firmware_status_get = skeleton_rawdev_firmware_status_get,
561473c88f9SBruce Richardson 	.firmware_version_get = skeleton_rawdev_firmware_version_get,
562473c88f9SBruce Richardson 	.firmware_load = skeleton_rawdev_firmware_load,
563473c88f9SBruce Richardson 	.firmware_unload = skeleton_rawdev_firmware_unload,
564473c88f9SBruce Richardson 
565473c88f9SBruce Richardson 	.dev_selftest = test_rawdev_skeldev,
566473c88f9SBruce Richardson };
567473c88f9SBruce Richardson 
568473c88f9SBruce Richardson static int
skeleton_rawdev_create(const char * name,struct rte_vdev_device * vdev,int socket_id)569473c88f9SBruce Richardson skeleton_rawdev_create(const char *name,
570473c88f9SBruce Richardson 		       struct rte_vdev_device *vdev,
571473c88f9SBruce Richardson 		       int socket_id)
572473c88f9SBruce Richardson {
573473c88f9SBruce Richardson 	int ret = 0, i;
574473c88f9SBruce Richardson 	struct rte_rawdev *rawdev = NULL;
575473c88f9SBruce Richardson 	struct skeleton_rawdev *skeldev = NULL;
576473c88f9SBruce Richardson 
577473c88f9SBruce Richardson 	if (!name) {
578473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid name of the device!");
579473c88f9SBruce Richardson 		ret = -EINVAL;
580473c88f9SBruce Richardson 		goto cleanup;
581473c88f9SBruce Richardson 	}
582473c88f9SBruce Richardson 
583473c88f9SBruce Richardson 	/* Allocate device structure */
584473c88f9SBruce Richardson 	rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
585473c88f9SBruce Richardson 					 socket_id);
586473c88f9SBruce Richardson 	if (rawdev == NULL) {
587473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Unable to allocate rawdevice");
588473c88f9SBruce Richardson 		ret = -EINVAL;
589473c88f9SBruce Richardson 		goto cleanup;
590473c88f9SBruce Richardson 	}
591473c88f9SBruce Richardson 
592473c88f9SBruce Richardson 	ret = rawdev->dev_id; /* return the rawdev id of new device */
593473c88f9SBruce Richardson 
594473c88f9SBruce Richardson 	rawdev->dev_ops = &skeleton_rawdev_ops;
595473c88f9SBruce Richardson 	rawdev->device = &vdev->device;
596473c88f9SBruce Richardson 
597473c88f9SBruce Richardson 	skeldev = skeleton_rawdev_get_priv(rawdev);
598473c88f9SBruce Richardson 
599473c88f9SBruce Richardson 	skeldev->device_id = SKELETON_DEVICE_ID;
600473c88f9SBruce Richardson 	skeldev->vendor_id = SKELETON_VENDOR_ID;
601473c88f9SBruce Richardson 	skeldev->capabilities = SKELETON_DEFAULT_CAPA;
602473c88f9SBruce Richardson 
603473c88f9SBruce Richardson 	memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
604473c88f9SBruce Richardson 
605473c88f9SBruce Richardson 	skeldev->fw.firmware_state = SKELETON_FW_READY;
606473c88f9SBruce Richardson 	skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
607473c88f9SBruce Richardson 	skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
608473c88f9SBruce Richardson 	skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
609473c88f9SBruce Richardson 
610473c88f9SBruce Richardson 	skeldev->device_state = SKELETON_DEV_STOPPED;
611473c88f9SBruce Richardson 
612473c88f9SBruce Richardson 	/* Reset/set to default queue configuration for this device */
613473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
614473c88f9SBruce Richardson 		skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
615473c88f9SBruce Richardson 		skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
616473c88f9SBruce Richardson 	}
617473c88f9SBruce Richardson 
618473c88f9SBruce Richardson 	/* Clear all allocated queue buffers */
619473c88f9SBruce Richardson 	for (i = 0; i < SKELETON_MAX_QUEUES; i++)
620473c88f9SBruce Richardson 		clear_queue_bufs(i);
621473c88f9SBruce Richardson 
622473c88f9SBruce Richardson 	return ret;
623473c88f9SBruce Richardson 
624473c88f9SBruce Richardson cleanup:
625473c88f9SBruce Richardson 	if (rawdev)
626473c88f9SBruce Richardson 		rte_rawdev_pmd_release(rawdev);
627473c88f9SBruce Richardson 
628473c88f9SBruce Richardson 	return ret;
629473c88f9SBruce Richardson }
630473c88f9SBruce Richardson 
631473c88f9SBruce Richardson static int
skeleton_rawdev_destroy(const char * name)632473c88f9SBruce Richardson skeleton_rawdev_destroy(const char *name)
633473c88f9SBruce Richardson {
634473c88f9SBruce Richardson 	int ret;
635473c88f9SBruce Richardson 	struct rte_rawdev *rdev;
636473c88f9SBruce Richardson 
637473c88f9SBruce Richardson 	if (!name) {
638473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid device name");
639473c88f9SBruce Richardson 		return -EINVAL;
640473c88f9SBruce Richardson 	}
641473c88f9SBruce Richardson 
642473c88f9SBruce Richardson 	rdev = rte_rawdev_pmd_get_named_dev(name);
643473c88f9SBruce Richardson 	if (!rdev) {
644473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Invalid device name (%s)", name);
645473c88f9SBruce Richardson 		return -EINVAL;
646473c88f9SBruce Richardson 	}
647473c88f9SBruce Richardson 
648473c88f9SBruce Richardson 	/* rte_rawdev_close is called by pmd_release */
649473c88f9SBruce Richardson 	ret = rte_rawdev_pmd_release(rdev);
650473c88f9SBruce Richardson 	if (ret)
651473c88f9SBruce Richardson 		SKELETON_PMD_DEBUG("Device cleanup failed");
652473c88f9SBruce Richardson 
653473c88f9SBruce Richardson 	return 0;
654473c88f9SBruce Richardson }
655473c88f9SBruce Richardson 
656473c88f9SBruce Richardson static int
skeldev_get_selftest(const char * key __rte_unused,const char * value,void * opaque)657473c88f9SBruce Richardson skeldev_get_selftest(const char *key __rte_unused,
658473c88f9SBruce Richardson 		     const char *value,
659473c88f9SBruce Richardson 		     void *opaque)
660473c88f9SBruce Richardson {
661473c88f9SBruce Richardson 	int *flag = opaque;
662473c88f9SBruce Richardson 	*flag = atoi(value);
663473c88f9SBruce Richardson 	return 0;
664473c88f9SBruce Richardson }
665473c88f9SBruce Richardson 
666473c88f9SBruce Richardson static int
skeldev_parse_vdev_args(struct rte_vdev_device * vdev)667473c88f9SBruce Richardson skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
668473c88f9SBruce Richardson {
669473c88f9SBruce Richardson 	int selftest = 0;
670473c88f9SBruce Richardson 	const char *name;
671473c88f9SBruce Richardson 	const char *params;
672473c88f9SBruce Richardson 
673473c88f9SBruce Richardson 	static const char *const args[] = {
674473c88f9SBruce Richardson 		SKELETON_SELFTEST_ARG,
675473c88f9SBruce Richardson 		NULL
676473c88f9SBruce Richardson 	};
677473c88f9SBruce Richardson 
678473c88f9SBruce Richardson 	name = rte_vdev_device_name(vdev);
679473c88f9SBruce Richardson 
680473c88f9SBruce Richardson 	params = rte_vdev_device_args(vdev);
681473c88f9SBruce Richardson 	if (params != NULL && params[0] != '\0') {
682473c88f9SBruce Richardson 		struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
683473c88f9SBruce Richardson 
684473c88f9SBruce Richardson 		if (!kvlist) {
685473c88f9SBruce Richardson 			SKELETON_PMD_INFO(
686473c88f9SBruce Richardson 				"Ignoring unsupported params supplied '%s'",
687473c88f9SBruce Richardson 				name);
688473c88f9SBruce Richardson 		} else {
689473c88f9SBruce Richardson 			int ret = rte_kvargs_process(kvlist,
690473c88f9SBruce Richardson 					SKELETON_SELFTEST_ARG,
691473c88f9SBruce Richardson 					skeldev_get_selftest, &selftest);
692473c88f9SBruce Richardson 			if (ret != 0 || (selftest < 0 || selftest > 1)) {
693473c88f9SBruce Richardson 				SKELETON_PMD_ERR("%s: Error in parsing args",
694473c88f9SBruce Richardson 						 name);
695473c88f9SBruce Richardson 				rte_kvargs_free(kvlist);
696473c88f9SBruce Richardson 				ret = -1; /* enforce if selftest is invalid */
697473c88f9SBruce Richardson 				return ret;
698473c88f9SBruce Richardson 			}
699473c88f9SBruce Richardson 		}
700473c88f9SBruce Richardson 
701473c88f9SBruce Richardson 		rte_kvargs_free(kvlist);
702473c88f9SBruce Richardson 	}
703473c88f9SBruce Richardson 
704473c88f9SBruce Richardson 	return selftest;
705473c88f9SBruce Richardson }
706473c88f9SBruce Richardson 
707473c88f9SBruce Richardson static int
skeleton_rawdev_probe(struct rte_vdev_device * vdev)708473c88f9SBruce Richardson skeleton_rawdev_probe(struct rte_vdev_device *vdev)
709473c88f9SBruce Richardson {
710473c88f9SBruce Richardson 	const char *name;
711473c88f9SBruce Richardson 	int selftest = 0, ret = 0;
712473c88f9SBruce Richardson 
713473c88f9SBruce Richardson 
714473c88f9SBruce Richardson 	name = rte_vdev_device_name(vdev);
715473c88f9SBruce Richardson 	if (name == NULL)
716473c88f9SBruce Richardson 		return -EINVAL;
717473c88f9SBruce Richardson 
718473c88f9SBruce Richardson 	/* More than one instance is not supported */
719473c88f9SBruce Richardson 	if (skeldev_init_once) {
720473c88f9SBruce Richardson 		SKELETON_PMD_ERR("Multiple instance not supported for %s",
721473c88f9SBruce Richardson 				 name);
722473c88f9SBruce Richardson 		return -EINVAL;
723473c88f9SBruce Richardson 	}
724473c88f9SBruce Richardson 
725473c88f9SBruce Richardson 	SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
726473c88f9SBruce Richardson 
727473c88f9SBruce Richardson 	selftest = skeldev_parse_vdev_args(vdev);
728473c88f9SBruce Richardson 	/* In case of invalid argument, selftest != 1; ignore other values */
729473c88f9SBruce Richardson 
730473c88f9SBruce Richardson 	ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
731473c88f9SBruce Richardson 	if (ret >= 0) {
732473c88f9SBruce Richardson 		/* In case command line argument for 'selftest' was passed;
733473c88f9SBruce Richardson 		 * if invalid arguments were passed, execution continues but
734473c88f9SBruce Richardson 		 * without selftest.
735473c88f9SBruce Richardson 		 */
736473c88f9SBruce Richardson 		if (selftest == 1)
737473c88f9SBruce Richardson 			test_rawdev_skeldev(ret);
738473c88f9SBruce Richardson 	}
739473c88f9SBruce Richardson 
740473c88f9SBruce Richardson 	/* Device instance created; Second instance not possible */
741473c88f9SBruce Richardson 	skeldev_init_once = 1;
742473c88f9SBruce Richardson 
743473c88f9SBruce Richardson 	return ret < 0 ? ret : 0;
744473c88f9SBruce Richardson }
745473c88f9SBruce Richardson 
746473c88f9SBruce Richardson static int
skeleton_rawdev_remove(struct rte_vdev_device * vdev)747473c88f9SBruce Richardson skeleton_rawdev_remove(struct rte_vdev_device *vdev)
748473c88f9SBruce Richardson {
749473c88f9SBruce Richardson 	const char *name;
750473c88f9SBruce Richardson 	int ret;
751473c88f9SBruce Richardson 
752473c88f9SBruce Richardson 	name = rte_vdev_device_name(vdev);
753473c88f9SBruce Richardson 	if (name == NULL)
754473c88f9SBruce Richardson 		return -1;
755473c88f9SBruce Richardson 
756473c88f9SBruce Richardson 	SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
757473c88f9SBruce Richardson 
758473c88f9SBruce Richardson 	ret = skeleton_rawdev_destroy(name);
759473c88f9SBruce Richardson 	if (!ret)
760473c88f9SBruce Richardson 		skeldev_init_once = 0;
761473c88f9SBruce Richardson 
762473c88f9SBruce Richardson 	return ret;
763473c88f9SBruce Richardson }
764473c88f9SBruce Richardson 
765473c88f9SBruce Richardson static struct rte_vdev_driver skeleton_pmd_drv = {
766473c88f9SBruce Richardson 	.probe = skeleton_rawdev_probe,
767473c88f9SBruce Richardson 	.remove = skeleton_rawdev_remove
768473c88f9SBruce Richardson };
769473c88f9SBruce Richardson 
770473c88f9SBruce Richardson RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
771*eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(skeleton_pmd_logtype, INFO);
772