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