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