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