]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright(c) 2016 Intel Corporation. All rights reserved. | |
5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * | |
10 | * * Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | |
12 | * * Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in | |
14 | * the documentation and/or other materials provided with the | |
15 | * distribution. | |
16 | * * Neither the name of Intel Corporation nor the names of its | |
17 | * contributors may be used to endorse or promote products derived | |
18 | * from this software without specific prior written permission. | |
19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | |
32 | ||
33 | #include <string.h> | |
34 | ||
35 | #include <rte_common.h> | |
36 | #include <rte_malloc.h> | |
37 | #include <rte_cryptodev_pmd.h> | |
38 | ||
39 | #include "rte_snow3g_pmd_private.h" | |
40 | ||
41 | static const struct rte_cryptodev_capabilities snow3g_pmd_capabilities[] = { | |
42 | { /* SNOW 3G (UIA2) */ | |
43 | .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, | |
44 | {.sym = { | |
45 | .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, | |
46 | {.auth = { | |
47 | .algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2, | |
48 | .block_size = 16, | |
49 | .key_size = { | |
50 | .min = 16, | |
51 | .max = 16, | |
52 | .increment = 0 | |
53 | }, | |
54 | .digest_size = { | |
55 | .min = 4, | |
56 | .max = 4, | |
57 | .increment = 0 | |
58 | }, | |
59 | .aad_size = { | |
60 | .min = 16, | |
61 | .max = 16, | |
62 | .increment = 0 | |
63 | } | |
64 | }, } | |
65 | }, } | |
66 | }, | |
67 | { /* SNOW 3G (UEA2) */ | |
68 | .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, | |
69 | {.sym = { | |
70 | .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, | |
71 | {.cipher = { | |
72 | .algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2, | |
73 | .block_size = 16, | |
74 | .key_size = { | |
75 | .min = 16, | |
76 | .max = 16, | |
77 | .increment = 0 | |
78 | }, | |
79 | .iv_size = { | |
80 | .min = 16, | |
81 | .max = 16, | |
82 | .increment = 0 | |
83 | } | |
84 | }, } | |
85 | }, } | |
86 | }, | |
87 | RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() | |
88 | }; | |
89 | ||
90 | /** Configure device */ | |
91 | static int | |
92 | snow3g_pmd_config(__rte_unused struct rte_cryptodev *dev) | |
93 | { | |
94 | return 0; | |
95 | } | |
96 | ||
97 | /** Start device */ | |
98 | static int | |
99 | snow3g_pmd_start(__rte_unused struct rte_cryptodev *dev) | |
100 | { | |
101 | return 0; | |
102 | } | |
103 | ||
104 | /** Stop device */ | |
105 | static void | |
106 | snow3g_pmd_stop(__rte_unused struct rte_cryptodev *dev) | |
107 | { | |
108 | } | |
109 | ||
110 | /** Close device */ | |
111 | static int | |
112 | snow3g_pmd_close(__rte_unused struct rte_cryptodev *dev) | |
113 | { | |
114 | return 0; | |
115 | } | |
116 | ||
117 | ||
118 | /** Get device statistics */ | |
119 | static void | |
120 | snow3g_pmd_stats_get(struct rte_cryptodev *dev, | |
121 | struct rte_cryptodev_stats *stats) | |
122 | { | |
123 | int qp_id; | |
124 | ||
125 | for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { | |
126 | struct snow3g_qp *qp = dev->data->queue_pairs[qp_id]; | |
127 | ||
128 | stats->enqueued_count += qp->qp_stats.enqueued_count; | |
129 | stats->dequeued_count += qp->qp_stats.dequeued_count; | |
130 | ||
131 | stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; | |
132 | stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; | |
133 | } | |
134 | } | |
135 | ||
136 | /** Reset device statistics */ | |
137 | static void | |
138 | snow3g_pmd_stats_reset(struct rte_cryptodev *dev) | |
139 | { | |
140 | int qp_id; | |
141 | ||
142 | for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { | |
143 | struct snow3g_qp *qp = dev->data->queue_pairs[qp_id]; | |
144 | ||
145 | memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); | |
146 | } | |
147 | } | |
148 | ||
149 | ||
150 | /** Get device info */ | |
151 | static void | |
152 | snow3g_pmd_info_get(struct rte_cryptodev *dev, | |
153 | struct rte_cryptodev_info *dev_info) | |
154 | { | |
155 | struct snow3g_private *internals = dev->data->dev_private; | |
156 | ||
157 | if (dev_info != NULL) { | |
158 | dev_info->dev_type = dev->dev_type; | |
159 | dev_info->max_nb_queue_pairs = internals->max_nb_queue_pairs; | |
160 | dev_info->sym.max_nb_sessions = internals->max_nb_sessions; | |
161 | dev_info->feature_flags = dev->feature_flags; | |
162 | dev_info->capabilities = snow3g_pmd_capabilities; | |
163 | } | |
164 | } | |
165 | ||
166 | /** Release queue pair */ | |
167 | static int | |
168 | snow3g_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) | |
169 | { | |
170 | if (dev->data->queue_pairs[qp_id] != NULL) { | |
171 | rte_free(dev->data->queue_pairs[qp_id]); | |
172 | dev->data->queue_pairs[qp_id] = NULL; | |
173 | } | |
174 | return 0; | |
175 | } | |
176 | ||
177 | /** set a unique name for the queue pair based on its name, dev_id and qp_id */ | |
178 | static int | |
179 | snow3g_pmd_qp_set_unique_name(struct rte_cryptodev *dev, | |
180 | struct snow3g_qp *qp) | |
181 | { | |
182 | unsigned n = snprintf(qp->name, sizeof(qp->name), | |
183 | "snow3g_pmd_%u_qp_%u", | |
184 | dev->data->dev_id, qp->id); | |
185 | ||
186 | if (n > sizeof(qp->name)) | |
187 | return -1; | |
188 | ||
189 | return 0; | |
190 | } | |
191 | ||
192 | /** Create a ring to place processed ops on */ | |
193 | static struct rte_ring * | |
194 | snow3g_pmd_qp_create_processed_ops_ring(struct snow3g_qp *qp, | |
195 | unsigned ring_size, int socket_id) | |
196 | { | |
197 | struct rte_ring *r; | |
198 | ||
199 | r = rte_ring_lookup(qp->name); | |
200 | if (r) { | |
201 | if (r->prod.size >= ring_size) { | |
202 | SNOW3G_LOG_INFO("Reusing existing ring %s" | |
203 | " for processed packets", | |
204 | qp->name); | |
205 | return r; | |
206 | } | |
207 | ||
208 | SNOW3G_LOG_ERR("Unable to reuse existing ring %s" | |
209 | " for processed packets", | |
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 | /** Setup a queue pair */ | |
219 | static int | |
220 | snow3g_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, | |
221 | const struct rte_cryptodev_qp_conf *qp_conf, | |
222 | int socket_id) | |
223 | { | |
224 | struct snow3g_qp *qp = NULL; | |
225 | ||
226 | /* Free memory prior to re-allocation if needed. */ | |
227 | if (dev->data->queue_pairs[qp_id] != NULL) | |
228 | snow3g_pmd_qp_release(dev, qp_id); | |
229 | ||
230 | /* Allocate the queue pair data structure. */ | |
231 | qp = rte_zmalloc_socket("SNOW 3G PMD Queue Pair", sizeof(*qp), | |
232 | RTE_CACHE_LINE_SIZE, socket_id); | |
233 | if (qp == NULL) | |
234 | return (-ENOMEM); | |
235 | ||
236 | qp->id = qp_id; | |
237 | dev->data->queue_pairs[qp_id] = qp; | |
238 | ||
239 | if (snow3g_pmd_qp_set_unique_name(dev, qp)) | |
240 | goto qp_setup_cleanup; | |
241 | ||
242 | qp->processed_ops = snow3g_pmd_qp_create_processed_ops_ring(qp, | |
243 | qp_conf->nb_descriptors, socket_id); | |
244 | if (qp->processed_ops == NULL) | |
245 | goto qp_setup_cleanup; | |
246 | ||
247 | qp->sess_mp = dev->data->session_pool; | |
248 | ||
249 | memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); | |
250 | ||
251 | return 0; | |
252 | ||
253 | qp_setup_cleanup: | |
254 | if (qp) | |
255 | rte_free(qp); | |
256 | ||
257 | return -1; | |
258 | } | |
259 | ||
260 | /** Start queue pair */ | |
261 | static int | |
262 | snow3g_pmd_qp_start(__rte_unused struct rte_cryptodev *dev, | |
263 | __rte_unused uint16_t queue_pair_id) | |
264 | { | |
265 | return -ENOTSUP; | |
266 | } | |
267 | ||
268 | /** Stop queue pair */ | |
269 | static int | |
270 | snow3g_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev, | |
271 | __rte_unused uint16_t queue_pair_id) | |
272 | { | |
273 | return -ENOTSUP; | |
274 | } | |
275 | ||
276 | /** Return the number of allocated queue pairs */ | |
277 | static uint32_t | |
278 | snow3g_pmd_qp_count(struct rte_cryptodev *dev) | |
279 | { | |
280 | return dev->data->nb_queue_pairs; | |
281 | } | |
282 | ||
283 | /** Returns the size of the SNOW 3G session structure */ | |
284 | static unsigned | |
285 | snow3g_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) | |
286 | { | |
287 | return sizeof(struct snow3g_session); | |
288 | } | |
289 | ||
290 | /** Configure a SNOW 3G session from a crypto xform chain */ | |
291 | static void * | |
292 | snow3g_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, | |
293 | struct rte_crypto_sym_xform *xform, void *sess) | |
294 | { | |
295 | if (unlikely(sess == NULL)) { | |
296 | SNOW3G_LOG_ERR("invalid session struct"); | |
297 | return NULL; | |
298 | } | |
299 | ||
300 | if (snow3g_set_session_parameters(sess, xform) != 0) { | |
301 | SNOW3G_LOG_ERR("failed configure session parameters"); | |
302 | return NULL; | |
303 | } | |
304 | ||
305 | return sess; | |
306 | } | |
307 | ||
308 | /** Clear the memory of session so it doesn't leave key material behind */ | |
309 | static void | |
310 | snow3g_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess) | |
311 | { | |
312 | /* | |
313 | * Current just resetting the whole data structure, need to investigate | |
314 | * whether a more selective reset of key would be more performant | |
315 | */ | |
316 | if (sess) | |
317 | memset(sess, 0, sizeof(struct snow3g_session)); | |
318 | } | |
319 | ||
320 | struct rte_cryptodev_ops snow3g_pmd_ops = { | |
321 | .dev_configure = snow3g_pmd_config, | |
322 | .dev_start = snow3g_pmd_start, | |
323 | .dev_stop = snow3g_pmd_stop, | |
324 | .dev_close = snow3g_pmd_close, | |
325 | ||
326 | .stats_get = snow3g_pmd_stats_get, | |
327 | .stats_reset = snow3g_pmd_stats_reset, | |
328 | ||
329 | .dev_infos_get = snow3g_pmd_info_get, | |
330 | ||
331 | .queue_pair_setup = snow3g_pmd_qp_setup, | |
332 | .queue_pair_release = snow3g_pmd_qp_release, | |
333 | .queue_pair_start = snow3g_pmd_qp_start, | |
334 | .queue_pair_stop = snow3g_pmd_qp_stop, | |
335 | .queue_pair_count = snow3g_pmd_qp_count, | |
336 | ||
337 | .session_get_size = snow3g_pmd_session_get_size, | |
338 | .session_configure = snow3g_pmd_session_configure, | |
339 | .session_clear = snow3g_pmd_session_clear | |
340 | }; | |
341 | ||
342 | struct rte_cryptodev_ops *rte_snow3g_pmd_ops = &snow3g_pmd_ops; |