]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* SPDX-License-Identifier: BSD-3-Clause |
2 | * Copyright(c) 2016-2018 Intel Corporation | |
7c673cae FG |
3 | */ |
4 | ||
5 | #include <string.h> | |
6 | ||
7 | #include <rte_common.h> | |
8 | #include <rte_malloc.h> | |
9 | #include <rte_cryptodev_pmd.h> | |
10 | ||
11 | #include "rte_zuc_pmd_private.h" | |
12 | ||
13 | static const struct rte_cryptodev_capabilities zuc_pmd_capabilities[] = { | |
14 | { /* ZUC (EIA3) */ | |
15 | .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, | |
16 | {.sym = { | |
17 | .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, | |
18 | {.auth = { | |
19 | .algo = RTE_CRYPTO_AUTH_ZUC_EIA3, | |
20 | .block_size = 16, | |
21 | .key_size = { | |
22 | .min = 16, | |
23 | .max = 16, | |
24 | .increment = 0 | |
25 | }, | |
26 | .digest_size = { | |
27 | .min = 4, | |
28 | .max = 4, | |
29 | .increment = 0 | |
30 | }, | |
11fdf7f2 | 31 | .iv_size = { |
7c673cae FG |
32 | .min = 16, |
33 | .max = 16, | |
34 | .increment = 0 | |
35 | } | |
36 | }, } | |
37 | }, } | |
38 | }, | |
39 | { /* ZUC (EEA3) */ | |
40 | .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, | |
41 | {.sym = { | |
42 | .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, | |
43 | {.cipher = { | |
44 | .algo = RTE_CRYPTO_CIPHER_ZUC_EEA3, | |
45 | .block_size = 16, | |
46 | .key_size = { | |
47 | .min = 16, | |
48 | .max = 16, | |
49 | .increment = 0 | |
50 | }, | |
51 | .iv_size = { | |
52 | .min = 16, | |
53 | .max = 16, | |
54 | .increment = 0 | |
11fdf7f2 | 55 | }, |
7c673cae FG |
56 | }, } |
57 | }, } | |
58 | }, | |
59 | RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() | |
60 | }; | |
61 | ||
62 | /** Configure device */ | |
63 | static int | |
11fdf7f2 TL |
64 | zuc_pmd_config(__rte_unused struct rte_cryptodev *dev, |
65 | __rte_unused struct rte_cryptodev_config *config) | |
7c673cae FG |
66 | { |
67 | return 0; | |
68 | } | |
69 | ||
70 | /** Start device */ | |
71 | static int | |
72 | zuc_pmd_start(__rte_unused struct rte_cryptodev *dev) | |
73 | { | |
74 | return 0; | |
75 | } | |
76 | ||
77 | /** Stop device */ | |
78 | static void | |
79 | zuc_pmd_stop(__rte_unused struct rte_cryptodev *dev) | |
80 | { | |
81 | } | |
82 | ||
83 | /** Close device */ | |
84 | static int | |
85 | zuc_pmd_close(__rte_unused struct rte_cryptodev *dev) | |
86 | { | |
87 | return 0; | |
88 | } | |
89 | ||
90 | ||
91 | /** Get device statistics */ | |
92 | static void | |
93 | zuc_pmd_stats_get(struct rte_cryptodev *dev, | |
94 | struct rte_cryptodev_stats *stats) | |
95 | { | |
96 | int qp_id; | |
97 | ||
98 | for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { | |
99 | struct zuc_qp *qp = dev->data->queue_pairs[qp_id]; | |
100 | ||
101 | stats->enqueued_count += qp->qp_stats.enqueued_count; | |
102 | stats->dequeued_count += qp->qp_stats.dequeued_count; | |
103 | ||
104 | stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; | |
105 | stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; | |
106 | } | |
107 | } | |
108 | ||
109 | /** Reset device statistics */ | |
110 | static void | |
111 | zuc_pmd_stats_reset(struct rte_cryptodev *dev) | |
112 | { | |
113 | int qp_id; | |
114 | ||
115 | for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { | |
116 | struct zuc_qp *qp = dev->data->queue_pairs[qp_id]; | |
117 | ||
118 | memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); | |
119 | } | |
120 | } | |
121 | ||
122 | ||
123 | /** Get device info */ | |
124 | static void | |
125 | zuc_pmd_info_get(struct rte_cryptodev *dev, | |
126 | struct rte_cryptodev_info *dev_info) | |
127 | { | |
128 | struct zuc_private *internals = dev->data->dev_private; | |
129 | ||
130 | if (dev_info != NULL) { | |
11fdf7f2 | 131 | dev_info->driver_id = dev->driver_id; |
7c673cae | 132 | dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs; |
11fdf7f2 TL |
133 | /* No limit of number of sessions */ |
134 | dev_info->sym.max_nb_sessions = 0; | |
7c673cae FG |
135 | dev_info->feature_flags = dev->feature_flags; |
136 | dev_info->capabilities = zuc_pmd_capabilities; | |
137 | } | |
138 | } | |
139 | ||
140 | /** Release queue pair */ | |
141 | static int | |
142 | zuc_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) | |
143 | { | |
144 | if (dev->data->queue_pairs[qp_id] != NULL) { | |
9f95a23c TL |
145 | struct zuc_qp *qp = dev->data->queue_pairs[qp_id]; |
146 | ||
147 | if (qp->processed_ops) | |
148 | rte_ring_free(qp->processed_ops); | |
149 | ||
7c673cae FG |
150 | rte_free(dev->data->queue_pairs[qp_id]); |
151 | dev->data->queue_pairs[qp_id] = NULL; | |
152 | } | |
153 | return 0; | |
154 | } | |
155 | ||
156 | /** set a unique name for the queue pair based on its name, dev_id and qp_id */ | |
157 | static int | |
158 | zuc_pmd_qp_set_unique_name(struct rte_cryptodev *dev, | |
159 | struct zuc_qp *qp) | |
160 | { | |
161 | unsigned n = snprintf(qp->name, sizeof(qp->name), | |
162 | "zuc_pmd_%u_qp_%u", | |
163 | dev->data->dev_id, qp->id); | |
164 | ||
11fdf7f2 | 165 | if (n >= sizeof(qp->name)) |
7c673cae FG |
166 | return -1; |
167 | ||
168 | return 0; | |
169 | } | |
170 | ||
171 | /** Create a ring to place processed ops on */ | |
172 | static struct rte_ring * | |
173 | zuc_pmd_qp_create_processed_ops_ring(struct zuc_qp *qp, | |
174 | unsigned ring_size, int socket_id) | |
175 | { | |
176 | struct rte_ring *r; | |
177 | ||
178 | r = rte_ring_lookup(qp->name); | |
179 | if (r) { | |
11fdf7f2 TL |
180 | if (rte_ring_get_size(r) >= ring_size) { |
181 | ZUC_LOG(INFO, "Reusing existing ring %s" | |
7c673cae FG |
182 | " for processed packets", |
183 | qp->name); | |
184 | return r; | |
185 | } | |
186 | ||
11fdf7f2 | 187 | ZUC_LOG(ERR, "Unable to reuse existing ring %s" |
7c673cae FG |
188 | " for processed packets", |
189 | qp->name); | |
190 | return NULL; | |
191 | } | |
192 | ||
193 | return rte_ring_create(qp->name, ring_size, socket_id, | |
194 | RING_F_SP_ENQ | RING_F_SC_DEQ); | |
195 | } | |
196 | ||
197 | /** Setup a queue pair */ | |
198 | static int | |
199 | zuc_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, | |
200 | const struct rte_cryptodev_qp_conf *qp_conf, | |
9f95a23c | 201 | int socket_id) |
7c673cae FG |
202 | { |
203 | struct zuc_qp *qp = NULL; | |
204 | ||
205 | /* Free memory prior to re-allocation if needed. */ | |
206 | if (dev->data->queue_pairs[qp_id] != NULL) | |
207 | zuc_pmd_qp_release(dev, qp_id); | |
208 | ||
209 | /* Allocate the queue pair data structure. */ | |
210 | qp = rte_zmalloc_socket("ZUC PMD Queue Pair", sizeof(*qp), | |
211 | RTE_CACHE_LINE_SIZE, socket_id); | |
212 | if (qp == NULL) | |
213 | return (-ENOMEM); | |
214 | ||
215 | qp->id = qp_id; | |
216 | dev->data->queue_pairs[qp_id] = qp; | |
217 | ||
218 | if (zuc_pmd_qp_set_unique_name(dev, qp)) | |
219 | goto qp_setup_cleanup; | |
220 | ||
221 | qp->processed_ops = zuc_pmd_qp_create_processed_ops_ring(qp, | |
222 | qp_conf->nb_descriptors, socket_id); | |
223 | if (qp->processed_ops == NULL) | |
224 | goto qp_setup_cleanup; | |
225 | ||
9f95a23c TL |
226 | qp->sess_mp = qp_conf->mp_session; |
227 | qp->sess_mp_priv = qp_conf->mp_session_private; | |
7c673cae FG |
228 | |
229 | memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); | |
230 | ||
231 | return 0; | |
232 | ||
233 | qp_setup_cleanup: | |
234 | if (qp) | |
235 | rte_free(qp); | |
236 | ||
237 | return -1; | |
238 | } | |
239 | ||
7c673cae FG |
240 | /** Return the number of allocated queue pairs */ |
241 | static uint32_t | |
242 | zuc_pmd_qp_count(struct rte_cryptodev *dev) | |
243 | { | |
244 | return dev->data->nb_queue_pairs; | |
245 | } | |
246 | ||
247 | /** Returns the size of the ZUC session structure */ | |
248 | static unsigned | |
11fdf7f2 | 249 | zuc_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused) |
7c673cae FG |
250 | { |
251 | return sizeof(struct zuc_session); | |
252 | } | |
253 | ||
254 | /** Configure a ZUC session from a crypto xform chain */ | |
11fdf7f2 TL |
255 | static int |
256 | zuc_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused, | |
257 | struct rte_crypto_sym_xform *xform, | |
258 | struct rte_cryptodev_sym_session *sess, | |
259 | struct rte_mempool *mempool) | |
7c673cae | 260 | { |
11fdf7f2 TL |
261 | void *sess_private_data; |
262 | int ret; | |
263 | ||
7c673cae | 264 | if (unlikely(sess == NULL)) { |
11fdf7f2 TL |
265 | ZUC_LOG(ERR, "invalid session struct"); |
266 | return -EINVAL; | |
7c673cae FG |
267 | } |
268 | ||
11fdf7f2 TL |
269 | if (rte_mempool_get(mempool, &sess_private_data)) { |
270 | ZUC_LOG(ERR, | |
271 | "Couldn't get object from session mempool"); | |
272 | ||
273 | return -ENOMEM; | |
7c673cae FG |
274 | } |
275 | ||
11fdf7f2 TL |
276 | ret = zuc_set_session_parameters(sess_private_data, xform); |
277 | if (ret != 0) { | |
278 | ZUC_LOG(ERR, "failed configure session parameters"); | |
279 | ||
280 | /* Return session to mempool */ | |
281 | rte_mempool_put(mempool, sess_private_data); | |
282 | return ret; | |
283 | } | |
284 | ||
285 | set_sym_session_private_data(sess, dev->driver_id, | |
286 | sess_private_data); | |
287 | ||
288 | return 0; | |
7c673cae FG |
289 | } |
290 | ||
291 | /** Clear the memory of session so it doesn't leave key material behind */ | |
292 | static void | |
11fdf7f2 TL |
293 | zuc_pmd_sym_session_clear(struct rte_cryptodev *dev, |
294 | struct rte_cryptodev_sym_session *sess) | |
7c673cae | 295 | { |
11fdf7f2 TL |
296 | uint8_t index = dev->driver_id; |
297 | void *sess_priv = get_sym_session_private_data(sess, index); | |
298 | ||
299 | /* Zero out the whole structure */ | |
300 | if (sess_priv) { | |
301 | memset(sess_priv, 0, sizeof(struct zuc_session)); | |
302 | struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv); | |
303 | set_sym_session_private_data(sess, index, NULL); | |
304 | rte_mempool_put(sess_mp, sess_priv); | |
305 | } | |
7c673cae FG |
306 | } |
307 | ||
308 | struct rte_cryptodev_ops zuc_pmd_ops = { | |
309 | .dev_configure = zuc_pmd_config, | |
310 | .dev_start = zuc_pmd_start, | |
311 | .dev_stop = zuc_pmd_stop, | |
312 | .dev_close = zuc_pmd_close, | |
313 | ||
314 | .stats_get = zuc_pmd_stats_get, | |
315 | .stats_reset = zuc_pmd_stats_reset, | |
316 | ||
317 | .dev_infos_get = zuc_pmd_info_get, | |
318 | ||
319 | .queue_pair_setup = zuc_pmd_qp_setup, | |
320 | .queue_pair_release = zuc_pmd_qp_release, | |
7c673cae FG |
321 | .queue_pair_count = zuc_pmd_qp_count, |
322 | ||
11fdf7f2 TL |
323 | .sym_session_get_size = zuc_pmd_sym_session_get_size, |
324 | .sym_session_configure = zuc_pmd_sym_session_configure, | |
325 | .sym_session_clear = zuc_pmd_sym_session_clear | |
7c673cae FG |
326 | }; |
327 | ||
328 | struct rte_cryptodev_ops *rte_zuc_pmd_ops = &zuc_pmd_ops; |