1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4 
5 #include <stdlib.h>
6 #include <stdio.h>
7 
8 #include <rte_cryptodev.h>
9 #include <rte_cryptodev_pmd.h>
10 #include <rte_string_fns.h>
11 
12 #include "rte_eth_softnic_internals.h"
13 
14 int
15 softnic_cryptodev_init(struct pmd_internals *p)
16 {
17 	TAILQ_INIT(&p->cryptodev_list);
18 
19 	return 0;
20 }
21 
22 void
23 softnic_cryptodev_free(struct pmd_internals *p)
24 {
25 	for ( ; ; ) {
26 		struct softnic_cryptodev *cryptodev;
27 
28 		cryptodev = TAILQ_FIRST(&p->cryptodev_list);
29 		if (cryptodev == NULL)
30 			break;
31 
32 		TAILQ_REMOVE(&p->cryptodev_list, cryptodev, node);
33 		free(cryptodev);
34 	}
35 }
36 
37 struct softnic_cryptodev *
38 softnic_cryptodev_find(struct pmd_internals *p,
39 	const char *name)
40 {
41 	struct softnic_cryptodev *cryptodev;
42 
43 	if (name == NULL)
44 		return NULL;
45 
46 	TAILQ_FOREACH(cryptodev, &p->cryptodev_list, node)
47 		if (strcmp(cryptodev->name, name) == 0)
48 			return cryptodev;
49 
50 	return NULL;
51 }
52 
53 struct softnic_cryptodev *
54 softnic_cryptodev_create(struct pmd_internals *p,
55 	const char *name,
56 	struct softnic_cryptodev_params *params)
57 {
58 	struct rte_cryptodev_info dev_info;
59 	struct rte_cryptodev_config dev_conf;
60 	struct rte_cryptodev_qp_conf queue_conf;
61 	struct softnic_cryptodev *cryptodev;
62 	uint32_t dev_id, i;
63 	uint32_t socket_id;
64 	int status;
65 
66 	/* Check input params */
67 	if ((name == NULL) ||
68 		softnic_cryptodev_find(p, name) ||
69 		(params->n_queues == 0) ||
70 		(params->queue_size == 0))
71 		return NULL;
72 
73 	if (params->dev_name) {
74 		status = rte_cryptodev_get_dev_id(params->dev_name);
75 		if (status == -1)
76 			return NULL;
77 
78 		dev_id = (uint32_t)status;
79 	} else {
80 		if (rte_cryptodev_pmd_is_valid_dev(params->dev_id) == 0)
81 			return NULL;
82 
83 		dev_id = params->dev_id;
84 	}
85 
86 	socket_id = rte_cryptodev_socket_id(dev_id);
87 	rte_cryptodev_info_get(dev_id, &dev_info);
88 
89 	if (dev_info.max_nb_queue_pairs < params->n_queues)
90 		return NULL;
91 	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED)
92 		return NULL;
93 
94 	dev_conf.socket_id = socket_id;
95 	dev_conf.nb_queue_pairs = params->n_queues;
96 
97 	status = rte_cryptodev_configure(dev_id, &dev_conf);
98 	if (status < 0)
99 		return NULL;
100 
101 	queue_conf.nb_descriptors = params->queue_size;
102 	for (i = 0; i < params->n_queues; i++) {
103 		status = rte_cryptodev_queue_pair_setup(dev_id, i,
104 				&queue_conf, socket_id, NULL);
105 		if (status < 0)
106 			return NULL;
107 	}
108 
109 	if (rte_cryptodev_start(dev_id) < 0)
110 		return NULL;
111 
112 	cryptodev = calloc(1, sizeof(struct softnic_cryptodev));
113 	if (cryptodev == NULL) {
114 		rte_cryptodev_stop(dev_id);
115 		return NULL;
116 	}
117 
118 	strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
119 	cryptodev->dev_id = dev_id;
120 	cryptodev->n_queues = params->n_queues;
121 
122 	TAILQ_INSERT_TAIL(&p->cryptodev_list, cryptodev, node);
123 
124 	return cryptodev;
125 }
126