Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2017 NXP
3 : : */
4 : :
5 : : #include <assert.h>
6 : : #include <stdio.h>
7 : : #include <stdbool.h>
8 : : #include <stdlib.h>
9 : : #include <errno.h>
10 : : #include <stdint.h>
11 : : #include <inttypes.h>
12 : : #include <string.h>
13 : :
14 : : #include <rte_byteorder.h>
15 : : #include <rte_common.h>
16 : : #include <rte_debug.h>
17 : : #include <dev_driver.h>
18 : : #include <rte_eal.h>
19 : : #include <rte_kvargs.h>
20 : : #include <rte_log.h>
21 : : #include <rte_malloc.h>
22 : : #include <rte_memory.h>
23 : : #include <rte_memcpy.h>
24 : : #include <rte_lcore.h>
25 : : #include <bus_vdev_driver.h>
26 : :
27 : : #include <rte_rawdev.h>
28 : : #include <rte_rawdev_pmd.h>
29 : :
30 : : #include "skeleton_rawdev.h"
31 : :
32 : : /* Count of instances */
33 : : static uint16_t skeldev_init_once;
34 : :
35 : : /**< Rawdev Skeleton dummy driver name */
36 : : #define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton
37 : :
38 : : struct queue_buffers {
39 : : void *bufs[SKELETON_QUEUE_MAX_DEPTH];
40 : : };
41 : :
42 : : static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {};
43 : : static void clear_queue_bufs(int queue_id);
44 : :
45 : 10 : static int skeleton_rawdev_info_get(struct rte_rawdev *dev,
46 : : rte_rawdev_obj_t dev_info,
47 : : size_t dev_info_size)
48 : : {
49 : : struct skeleton_rawdev *skeldev;
50 : : struct skeleton_rawdev_conf *skeldev_conf;
51 : :
52 : 10 : SKELETON_PMD_FUNC_TRACE();
53 : :
54 [ - + ]: 10 : if (!dev_info || dev_info_size != sizeof(*skeldev_conf)) {
55 : 0 : SKELETON_PMD_ERR("Invalid request");
56 : 0 : return -EINVAL;
57 : : }
58 : :
59 : : skeldev = skeleton_rawdev_get_priv(dev);
60 : :
61 : : skeldev_conf = dev_info;
62 : :
63 : 10 : skeldev_conf->num_queues = skeldev->num_queues;
64 : 10 : skeldev_conf->capabilities = skeldev->capabilities;
65 : 10 : skeldev_conf->device_state = skeldev->device_state;
66 : 10 : skeldev_conf->firmware_state = skeldev->fw.firmware_state;
67 : :
68 : 10 : return 0;
69 : : }
70 : :
71 : 3 : static int skeleton_rawdev_configure(const struct rte_rawdev *dev,
72 : : rte_rawdev_obj_t config,
73 : : size_t config_size)
74 : : {
75 : : struct skeleton_rawdev *skeldev;
76 : : struct skeleton_rawdev_conf *skeldev_conf;
77 : :
78 : 3 : SKELETON_PMD_FUNC_TRACE();
79 : :
80 [ + - ]: 3 : if (dev == NULL)
81 : : return -EINVAL;
82 : :
83 [ - + ]: 3 : if (config == NULL || config_size != sizeof(*skeldev_conf)) {
84 : 0 : SKELETON_PMD_ERR("Invalid configuration");
85 : 0 : return -EINVAL;
86 : : }
87 : :
88 : : skeldev_conf = config;
89 : : skeldev = skeleton_rawdev_get_priv(dev);
90 : :
91 [ + - ]: 3 : if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES)
92 : 3 : skeldev->num_queues = skeldev_conf->num_queues;
93 : : else
94 : : return -EINVAL;
95 : :
96 : 3 : skeldev->capabilities = skeldev_conf->capabilities;
97 : : skeldev->num_queues = skeldev_conf->num_queues;
98 : :
99 : 3 : return 0;
100 : : }
101 : :
102 : 1 : static int skeleton_rawdev_start(struct rte_rawdev *dev)
103 : : {
104 : : int ret = 0;
105 : : struct skeleton_rawdev *skeldev;
106 : : enum skeleton_firmware_state fw_state;
107 : : enum skeleton_device_state device_state;
108 : :
109 : 1 : SKELETON_PMD_FUNC_TRACE();
110 : :
111 [ + - ]: 1 : if (dev == NULL)
112 : : return -EINVAL;
113 : :
114 : : skeldev = skeleton_rawdev_get_priv(dev);
115 : :
116 : 1 : fw_state = skeldev->fw.firmware_state;
117 : 1 : device_state = skeldev->device_state;
118 : :
119 : 1 : if (fw_state == SKELETON_FW_LOADED &&
120 [ + - ]: 1 : device_state == SKELETON_DEV_STOPPED) {
121 : 1 : skeldev->device_state = SKELETON_DEV_RUNNING;
122 : : } else {
123 : 0 : SKELETON_PMD_ERR("Device not ready for starting");
124 : : ret = -EINVAL;
125 : : }
126 : :
127 : : return ret;
128 : : }
129 : :
130 : 1 : static void skeleton_rawdev_stop(struct rte_rawdev *dev)
131 : : {
132 : : struct skeleton_rawdev *skeldev;
133 : :
134 : 1 : SKELETON_PMD_FUNC_TRACE();
135 : :
136 [ + - ]: 1 : if (dev) {
137 : : skeldev = skeleton_rawdev_get_priv(dev);
138 : 1 : skeldev->device_state = SKELETON_DEV_STOPPED;
139 : : }
140 : 1 : }
141 : :
142 : : static void
143 : : reset_queues(struct skeleton_rawdev *skeldev)
144 : : {
145 : : int i;
146 : :
147 : : for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
148 : 2 : skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
149 : 2 : skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
150 : : }
151 : : }
152 : :
153 : : static void
154 : 2 : reset_attribute_table(struct skeleton_rawdev *skeldev)
155 : : {
156 : : int i;
157 : :
158 [ + + ]: 22 : for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
159 [ + + ]: 20 : if (skeldev->attr[i].name) {
160 : 2 : free(skeldev->attr[i].name);
161 : 2 : skeldev->attr[i].name = NULL;
162 : : }
163 : : }
164 : 2 : }
165 : :
166 : 2 : static int skeleton_rawdev_close(struct rte_rawdev *dev)
167 : : {
168 : : int ret = 0, i;
169 : : struct skeleton_rawdev *skeldev;
170 : : enum skeleton_firmware_state fw_state;
171 : : enum skeleton_device_state device_state;
172 : :
173 : 2 : SKELETON_PMD_FUNC_TRACE();
174 : :
175 [ + - ]: 2 : if (dev == NULL)
176 : : return -EINVAL;
177 : :
178 : : skeldev = skeleton_rawdev_get_priv(dev);
179 : :
180 : 2 : fw_state = skeldev->fw.firmware_state;
181 : 2 : device_state = skeldev->device_state;
182 : :
183 : : reset_queues(skeldev);
184 : 2 : reset_attribute_table(skeldev);
185 : :
186 [ - + - ]: 2 : switch (fw_state) {
187 : 0 : case SKELETON_FW_LOADED:
188 [ # # ]: 0 : if (device_state == SKELETON_DEV_RUNNING) {
189 : 0 : SKELETON_PMD_ERR("Cannot close running device");
190 : : ret = -EINVAL;
191 : : } else {
192 : : /* Probably call fw reset here */
193 : 0 : skeldev->fw.firmware_state = SKELETON_FW_READY;
194 : : }
195 : : break;
196 : 2 : case SKELETON_FW_READY:
197 : 2 : SKELETON_PMD_DEBUG("Device already in stopped state");
198 : 2 : break;
199 : 0 : case SKELETON_FW_ERROR:
200 : : default:
201 : 0 : SKELETON_PMD_DEBUG("Device in impossible state");
202 : : ret = -EINVAL;
203 : 0 : break;
204 : : }
205 : :
206 : : /* Clear all allocated queues */
207 [ + + ]: 4 : for (i = 0; i < SKELETON_MAX_QUEUES; i++)
208 : : clear_queue_bufs(i);
209 : :
210 : : return ret;
211 : : }
212 : :
213 : 0 : static int skeleton_rawdev_reset(struct rte_rawdev *dev)
214 : : {
215 : : struct skeleton_rawdev *skeldev;
216 : :
217 : 0 : SKELETON_PMD_FUNC_TRACE();
218 : :
219 [ # # ]: 0 : if (dev == NULL)
220 : : return -EINVAL;
221 : :
222 : : skeldev = skeleton_rawdev_get_priv(dev);
223 : :
224 : 0 : SKELETON_PMD_DEBUG("Resetting device");
225 : 0 : skeldev->fw.firmware_state = SKELETON_FW_READY;
226 : :
227 : 0 : return 0;
228 : : }
229 : :
230 : 5 : static int skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev,
231 : : uint16_t queue_id,
232 : : rte_rawdev_obj_t queue_conf,
233 : : size_t conf_size)
234 : : {
235 : : struct skeleton_rawdev *skeldev;
236 : : struct skeleton_rawdev_queue *skelq;
237 : :
238 : 5 : SKELETON_PMD_FUNC_TRACE();
239 : :
240 [ + - + - ]: 5 : if (!dev || !queue_conf ||
241 : : conf_size != sizeof(struct skeleton_rawdev_queue))
242 : : return -EINVAL;
243 : :
244 : : skeldev = skeleton_rawdev_get_priv(dev);
245 : 5 : skelq = &skeldev->queues[queue_id];
246 : :
247 [ + - ]: 5 : if (queue_id < SKELETON_MAX_QUEUES)
248 : : rte_memcpy(queue_conf, skelq,
249 : : sizeof(struct skeleton_rawdev_queue));
250 : :
251 : : return 0;
252 : : }
253 : :
254 : : static void
255 : : clear_queue_bufs(int queue_id)
256 : : {
257 : : int i;
258 : :
259 : : /* Clear buffers for queue_id */
260 [ + + + + : 208 : for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++)
+ + + + ]
261 : 200 : queue_buf[queue_id].bufs[i] = NULL;
262 : : }
263 : :
264 : 3 : static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev,
265 : : uint16_t queue_id,
266 : : rte_rawdev_obj_t queue_conf,
267 : : size_t conf_size)
268 : : {
269 : : int ret = 0;
270 : : struct skeleton_rawdev *skeldev;
271 : : struct skeleton_rawdev_queue *q;
272 : :
273 : 3 : SKELETON_PMD_FUNC_TRACE();
274 : :
275 [ + - + - ]: 3 : if (!dev || !queue_conf ||
276 : : conf_size != sizeof(struct skeleton_rawdev_queue))
277 : : return -EINVAL;
278 : :
279 : : skeldev = skeleton_rawdev_get_priv(dev);
280 : 3 : q = &skeldev->queues[queue_id];
281 : :
282 [ + - ]: 3 : if (skeldev->num_queues > queue_id &&
283 [ + - ]: 3 : q->depth < SKELETON_QUEUE_MAX_DEPTH) {
284 : : rte_memcpy(q, queue_conf,
285 : : sizeof(struct skeleton_rawdev_queue));
286 : : clear_queue_bufs(queue_id);
287 : : } else {
288 : 0 : SKELETON_PMD_ERR("Invalid queue configuration");
289 : : ret = -EINVAL;
290 : : }
291 : :
292 : : return ret;
293 : : }
294 : :
295 : 1 : static int skeleton_rawdev_queue_release(struct rte_rawdev *dev,
296 : : uint16_t queue_id)
297 : : {
298 : : int ret = 0;
299 : : struct skeleton_rawdev *skeldev;
300 : :
301 : 1 : SKELETON_PMD_FUNC_TRACE();
302 : :
303 [ + - ]: 1 : if (dev == NULL)
304 : : return -EINVAL;
305 : :
306 : : skeldev = skeleton_rawdev_get_priv(dev);
307 : :
308 [ + - ]: 1 : if (skeldev->num_queues > queue_id) {
309 : 1 : skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH;
310 : 1 : skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH;
311 : : clear_queue_bufs(queue_id);
312 : : } else {
313 : 0 : SKELETON_PMD_ERR("Invalid queue configuration");
314 : : ret = -EINVAL;
315 : : }
316 : :
317 : : return ret;
318 : : }
319 : :
320 : 1 : static uint16_t skeleton_rawdev_queue_count(struct rte_rawdev *dev)
321 : : {
322 : : struct skeleton_rawdev *skeldev;
323 : :
324 : 1 : SKELETON_PMD_FUNC_TRACE();
325 : :
326 [ + - ]: 1 : if (dev == NULL)
327 : : return -EINVAL;
328 : :
329 : : skeldev = skeleton_rawdev_get_priv(dev);
330 : 1 : return skeldev->num_queues;
331 : : }
332 : :
333 : 2 : static int skeleton_rawdev_get_attr(struct rte_rawdev *dev,
334 : : const char *attr_name,
335 : : uint64_t *attr_value)
336 : : {
337 : : int i;
338 : : uint8_t done = 0;
339 : : struct skeleton_rawdev *skeldev;
340 : :
341 : 2 : SKELETON_PMD_FUNC_TRACE();
342 : :
343 [ + - - + ]: 2 : if (!dev || !attr_name || !attr_value) {
344 : 0 : SKELETON_PMD_ERR("Invalid arguments for getting attributes");
345 : 0 : return -EINVAL;
346 : : }
347 : :
348 : : skeldev = skeleton_rawdev_get_priv(dev);
349 : :
350 [ + - ]: 3 : for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
351 [ - + ]: 3 : if (!skeldev->attr[i].name)
352 : 0 : continue;
353 : :
354 [ + + ]: 3 : if (!strncmp(skeldev->attr[i].name, attr_name,
355 : : SKELETON_ATTRIBUTE_NAME_MAX)) {
356 : 2 : *attr_value = skeldev->attr[i].value;
357 : : done = 1;
358 : 2 : SKELETON_PMD_DEBUG("Attribute (%s) Value (%" PRIu64 ")",
359 : : attr_name, *attr_value);
360 : : break;
361 : : }
362 : : }
363 : :
364 : : if (done)
365 : 2 : return 0;
366 : :
367 : : /* Attribute not found */
368 : : return -EINVAL;
369 : : }
370 : :
371 : 2 : static int skeleton_rawdev_set_attr(struct rte_rawdev *dev,
372 : : const char *attr_name,
373 : : const uint64_t attr_value)
374 : : {
375 : : int i;
376 : : uint8_t done = 0;
377 : : struct skeleton_rawdev *skeldev;
378 : :
379 : 2 : SKELETON_PMD_FUNC_TRACE();
380 : :
381 [ - + ]: 2 : if (!dev || !attr_name) {
382 : 0 : SKELETON_PMD_ERR("Invalid arguments for setting attributes");
383 : 0 : return -EINVAL;
384 : : }
385 : :
386 : : skeldev = skeleton_rawdev_get_priv(dev);
387 : :
388 : : /* Check if attribute already exists */
389 [ + - ]: 3 : for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) {
390 [ + + ]: 3 : if (!skeldev->attr[i].name)
391 : : break;
392 : :
393 [ - + ]: 1 : if (!strncmp(skeldev->attr[i].name, attr_name,
394 : : SKELETON_ATTRIBUTE_NAME_MAX)) {
395 : : /* Update value */
396 : 0 : skeldev->attr[i].value = attr_value;
397 : : done = 1;
398 : : break;
399 : : }
400 : : }
401 : :
402 : : if (!done) {
403 [ + - ]: 2 : if (i < (SKELETON_MAX_ATTRIBUTES - 1)) {
404 : : /* There is still space to insert one more */
405 : 2 : skeldev->attr[i].name = strdup(attr_name);
406 [ + - ]: 2 : if (!skeldev->attr[i].name)
407 : : return -ENOMEM;
408 : :
409 : 2 : skeldev->attr[i].value = attr_value;
410 : 2 : return 0;
411 : : }
412 : : }
413 : :
414 : : return -EINVAL;
415 : : }
416 : :
417 : 1 : static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev,
418 : : struct rte_rawdev_buf **buffers,
419 : : unsigned int count,
420 : : rte_rawdev_obj_t context)
421 : : {
422 : : unsigned int i;
423 : : uint16_t q_id;
424 : : RTE_SET_USED(dev);
425 : :
426 : : /* context is essentially the queue_id which is
427 : : * transferred as opaque object through the library layer. This can
428 : : * help in complex implementation which require more information than
429 : : * just an integer - for example, a queue-pair.
430 : : */
431 : 1 : q_id = *((uint16_t *)context);
432 : :
433 [ + + ]: 2 : for (i = 0; i < count; i++)
434 : 1 : queue_buf[q_id].bufs[i] = buffers[i]->buf_addr;
435 : :
436 : 1 : return i;
437 : : }
438 : :
439 : 1 : static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev,
440 : : struct rte_rawdev_buf **buffers,
441 : : unsigned int count,
442 : : rte_rawdev_obj_t context)
443 : : {
444 : : unsigned int i;
445 : : uint16_t q_id;
446 : : RTE_SET_USED(dev);
447 : :
448 : : /* context is essentially the queue_id which is
449 : : * transferred as opaque object through the library layer. This can
450 : : * help in complex implementation which require more information than
451 : : * just an integer - for example, a queue-pair.
452 : : */
453 : 1 : q_id = *((uint16_t *)context);
454 : :
455 [ + + ]: 2 : for (i = 0; i < count; i++)
456 : 1 : buffers[i]->buf_addr = queue_buf[q_id].bufs[i];
457 : :
458 : 1 : return i;
459 : : }
460 : :
461 : 0 : static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f)
462 : : {
463 : : RTE_SET_USED(dev);
464 : : RTE_SET_USED(f);
465 : :
466 : 0 : return 0;
467 : : }
468 : :
469 : 0 : static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev,
470 : : rte_rawdev_obj_t status_info)
471 : : {
472 : : struct skeleton_rawdev *skeldev;
473 : :
474 : 0 : SKELETON_PMD_FUNC_TRACE();
475 : :
476 : : skeldev = skeleton_rawdev_get_priv(dev);
477 : :
478 [ # # ]: 0 : if (status_info)
479 : 0 : memcpy(status_info, &skeldev->fw.firmware_state,
480 : : sizeof(enum skeleton_firmware_state));
481 : :
482 : 0 : return 0;
483 : : }
484 : :
485 : :
486 : 0 : static int skeleton_rawdev_firmware_version_get(
487 : : struct rte_rawdev *dev,
488 : : rte_rawdev_obj_t version_info)
489 : : {
490 : : struct skeleton_rawdev *skeldev;
491 : : struct skeleton_firmware_version_info *vi;
492 : :
493 : 0 : SKELETON_PMD_FUNC_TRACE();
494 : :
495 : : skeldev = skeleton_rawdev_get_priv(dev);
496 : : vi = version_info;
497 : :
498 : 0 : vi->major = skeldev->fw.firmware_version.major;
499 : 0 : vi->minor = skeldev->fw.firmware_version.minor;
500 : 0 : vi->subrel = skeldev->fw.firmware_version.subrel;
501 : :
502 : 0 : return 0;
503 : : }
504 : :
505 : 1 : static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev,
506 : : rte_rawdev_obj_t firmware_buf)
507 : : {
508 : : struct skeleton_rawdev *skeldev;
509 : :
510 : 1 : SKELETON_PMD_FUNC_TRACE();
511 : :
512 : : skeldev = skeleton_rawdev_get_priv(dev);
513 : :
514 : : /* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being
515 : : * dummy, all this does is check if firmware_buf is not NULL and
516 : : * sets the state of the firmware.
517 : : */
518 [ + - ]: 1 : if (!firmware_buf)
519 : : return -EINVAL;
520 : :
521 : 1 : skeldev->fw.firmware_state = SKELETON_FW_LOADED;
522 : :
523 : 1 : return 0;
524 : : }
525 : :
526 : 1 : static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev)
527 : : {
528 : : struct skeleton_rawdev *skeldev;
529 : :
530 : 1 : SKELETON_PMD_FUNC_TRACE();
531 : :
532 : : skeldev = skeleton_rawdev_get_priv(dev);
533 : :
534 : 1 : skeldev->fw.firmware_state = SKELETON_FW_READY;
535 : :
536 : 1 : return 0;
537 : : }
538 : :
539 : : static const struct rte_rawdev_ops skeleton_rawdev_ops = {
540 : : .dev_info_get = skeleton_rawdev_info_get,
541 : : .dev_configure = skeleton_rawdev_configure,
542 : : .dev_start = skeleton_rawdev_start,
543 : : .dev_stop = skeleton_rawdev_stop,
544 : : .dev_close = skeleton_rawdev_close,
545 : : .dev_reset = skeleton_rawdev_reset,
546 : :
547 : : .queue_def_conf = skeleton_rawdev_queue_def_conf,
548 : : .queue_setup = skeleton_rawdev_queue_setup,
549 : : .queue_release = skeleton_rawdev_queue_release,
550 : : .queue_count = skeleton_rawdev_queue_count,
551 : :
552 : : .attr_get = skeleton_rawdev_get_attr,
553 : : .attr_set = skeleton_rawdev_set_attr,
554 : :
555 : : .enqueue_bufs = skeleton_rawdev_enqueue_bufs,
556 : : .dequeue_bufs = skeleton_rawdev_dequeue_bufs,
557 : :
558 : : .dump = skeleton_rawdev_dump,
559 : :
560 : : .xstats_get = NULL,
561 : : .xstats_get_names = NULL,
562 : : .xstats_get_by_name = NULL,
563 : : .xstats_reset = NULL,
564 : :
565 : : .firmware_status_get = skeleton_rawdev_firmware_status_get,
566 : : .firmware_version_get = skeleton_rawdev_firmware_version_get,
567 : : .firmware_load = skeleton_rawdev_firmware_load,
568 : : .firmware_unload = skeleton_rawdev_firmware_unload,
569 : :
570 : : .dev_selftest = test_rawdev_skeldev,
571 : : };
572 : :
573 : : static int
574 : 2 : skeleton_rawdev_create(const char *name,
575 : : struct rte_vdev_device *vdev,
576 : : int socket_id)
577 : : {
578 : : int ret = 0, i;
579 : : struct rte_rawdev *rawdev = NULL;
580 : : struct skeleton_rawdev *skeldev = NULL;
581 : :
582 [ - + ]: 2 : if (!name) {
583 : 0 : SKELETON_PMD_ERR("Invalid name of the device!");
584 : : ret = -EINVAL;
585 : 0 : goto cleanup;
586 : : }
587 : :
588 : : /* Allocate device structure */
589 : 2 : rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev),
590 : : socket_id);
591 [ - + ]: 2 : if (rawdev == NULL) {
592 : 0 : SKELETON_PMD_ERR("Unable to allocate rawdevice");
593 : : ret = -EINVAL;
594 : 0 : goto cleanup;
595 : : }
596 : :
597 : 2 : ret = rawdev->dev_id; /* return the rawdev id of new device */
598 : :
599 : 2 : rawdev->dev_ops = &skeleton_rawdev_ops;
600 : 2 : rawdev->device = &vdev->device;
601 : :
602 : : skeldev = skeleton_rawdev_get_priv(rawdev);
603 : :
604 : 2 : skeldev->device_id = SKELETON_DEVICE_ID;
605 : 2 : skeldev->vendor_id = SKELETON_VENDOR_ID;
606 : 2 : skeldev->capabilities = SKELETON_DEFAULT_CAPA;
607 : :
608 : 2 : memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware));
609 : :
610 : : skeldev->fw.firmware_state = SKELETON_FW_READY;
611 : 2 : skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER;
612 : : skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER;
613 : : skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER;
614 : :
615 : 2 : skeldev->device_state = SKELETON_DEV_STOPPED;
616 : :
617 : : /* Reset/set to default queue configuration for this device */
618 [ + + ]: 4 : for (i = 0; i < SKELETON_MAX_QUEUES; i++) {
619 : 2 : skeldev->queues[i].state = SKELETON_QUEUE_DETACH;
620 : 2 : skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH;
621 : : }
622 : :
623 : : /* Clear all allocated queue buffers */
624 [ + + ]: 4 : for (i = 0; i < SKELETON_MAX_QUEUES; i++)
625 : : clear_queue_bufs(i);
626 : :
627 : : return ret;
628 : :
629 : : cleanup:
630 : : if (rawdev)
631 : : rte_rawdev_pmd_release(rawdev);
632 : :
633 : : return ret;
634 : : }
635 : :
636 : : static int
637 : 2 : skeleton_rawdev_destroy(const char *name)
638 : : {
639 : : int ret;
640 : : struct rte_rawdev *rdev;
641 : :
642 [ - + ]: 2 : if (!name) {
643 : 0 : SKELETON_PMD_ERR("Invalid device name");
644 : 0 : return -EINVAL;
645 : : }
646 : :
647 : 2 : rdev = rte_rawdev_pmd_get_named_dev(name);
648 [ - + ]: 2 : if (!rdev) {
649 : 0 : SKELETON_PMD_ERR("Invalid device name (%s)", name);
650 : 0 : return -EINVAL;
651 : : }
652 : :
653 : : /* rte_rawdev_close is called by pmd_release */
654 : 2 : ret = rte_rawdev_pmd_release(rdev);
655 [ - + ]: 2 : if (ret)
656 : 0 : SKELETON_PMD_DEBUG("Device cleanup failed");
657 : :
658 : : return 0;
659 : : }
660 : :
661 : : static int
662 : 0 : skeldev_get_selftest(const char *key __rte_unused,
663 : : const char *value,
664 : : void *opaque)
665 : : {
666 : : int *flag = opaque;
667 [ # # ]: 0 : if (value == NULL || opaque == NULL)
668 : : return -EINVAL;
669 : 0 : *flag = atoi(value);
670 : 0 : return 0;
671 : : }
672 : :
673 : : static int
674 : 2 : skeldev_parse_vdev_args(struct rte_vdev_device *vdev)
675 : : {
676 [ + - ]: 2 : int selftest = 0;
677 : : const char *name;
678 : : const char *params;
679 : :
680 : : static const char *const args[] = {
681 : : SKELETON_SELFTEST_ARG,
682 : : NULL
683 : : };
684 : :
685 : : name = rte_vdev_device_name(vdev);
686 : :
687 : : params = rte_vdev_device_args(vdev);
688 [ + - - + ]: 2 : if (params != NULL && params[0] != '\0') {
689 : 0 : struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
690 : :
691 [ # # ]: 0 : if (!kvlist) {
692 : 0 : SKELETON_PMD_INFO(
693 : : "Ignoring unsupported params supplied '%s'",
694 : : name);
695 : : } else {
696 : 0 : int ret = rte_kvargs_process(kvlist,
697 : : SKELETON_SELFTEST_ARG,
698 : : skeldev_get_selftest, &selftest);
699 [ # # # # ]: 0 : if (ret != 0 || (selftest < 0 || selftest > 1)) {
700 : 0 : SKELETON_PMD_ERR("%s: Error in parsing args",
701 : : name);
702 : 0 : rte_kvargs_free(kvlist);
703 : : ret = -1; /* enforce if selftest is invalid */
704 : 0 : return ret;
705 : : }
706 : : }
707 : :
708 : 0 : rte_kvargs_free(kvlist);
709 : : }
710 : :
711 : 2 : return selftest;
712 : : }
713 : :
714 : : static int
715 [ + - ]: 2 : skeleton_rawdev_probe(struct rte_vdev_device *vdev)
716 : : {
717 : : const char *name;
718 : : int selftest = 0, ret = 0;
719 : :
720 : :
721 : : name = rte_vdev_device_name(vdev);
722 : : if (name == NULL)
723 : : return -EINVAL;
724 : :
725 : : /* More than one instance is not supported */
726 [ - + ]: 2 : if (skeldev_init_once) {
727 : 0 : SKELETON_PMD_ERR("Multiple instance not supported for %s",
728 : : name);
729 : 0 : return -EINVAL;
730 : : }
731 : :
732 : 2 : SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
733 : :
734 : 2 : selftest = skeldev_parse_vdev_args(vdev);
735 : : /* In case of invalid argument, selftest != 1; ignore other values */
736 : :
737 : 2 : ret = skeleton_rawdev_create(name, vdev, rte_socket_id());
738 [ + - ]: 2 : if (ret >= 0) {
739 : : /* In case command line argument for 'selftest' was passed;
740 : : * if invalid arguments were passed, execution continues but
741 : : * without selftest.
742 : : */
743 [ - + ]: 2 : if (selftest == 1)
744 : 0 : test_rawdev_skeldev(ret);
745 : : }
746 : :
747 : : /* Device instance created; Second instance not possible */
748 : 2 : skeldev_init_once = 1;
749 : :
750 : 2 : return ret < 0 ? ret : 0;
751 : : }
752 : :
753 : : static int
754 [ + - ]: 2 : skeleton_rawdev_remove(struct rte_vdev_device *vdev)
755 : : {
756 : : const char *name;
757 : : int ret;
758 : :
759 : : name = rte_vdev_device_name(vdev);
760 : : if (name == NULL)
761 : : return -1;
762 : :
763 : 2 : SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id());
764 : :
765 : 2 : ret = skeleton_rawdev_destroy(name);
766 [ + - ]: 2 : if (!ret)
767 : 2 : skeldev_init_once = 0;
768 : :
769 : : return ret;
770 : : }
771 : :
772 : : static struct rte_vdev_driver skeleton_pmd_drv = {
773 : : .probe = skeleton_rawdev_probe,
774 : : .remove = skeleton_rawdev_remove
775 : : };
776 : :
777 : 252 : RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv);
778 [ - + ]: 252 : RTE_LOG_REGISTER_DEFAULT(skeleton_pmd_logtype, INFO);
|