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