New upstream version 18.08
[deb_dpdk.git] / drivers / crypto / armv8 / rte_armv8_pmd_ops.c
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,
223                 int socket_id, struct rte_mempool *session_pool)
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
248         qp->sess_mp = session_pool;
249
250         memset(&qp->stats, 0, sizeof(qp->stats));
251
252         return 0;
253
254 qp_setup_cleanup:
255         if (qp)
256                 rte_free(qp);
257
258         return -1;
259 }
260
261 /** Return the number of allocated queue pairs */
262 static uint32_t
263 armv8_crypto_pmd_qp_count(struct rte_cryptodev *dev)
264 {
265         return dev->data->nb_queue_pairs;
266 }
267
268 /** Returns the size of the session structure */
269 static unsigned
270 armv8_crypto_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
271 {
272         return sizeof(struct armv8_crypto_session);
273 }
274
275 /** Configure the session from a crypto xform chain */
276 static int
277 armv8_crypto_pmd_sym_session_configure(struct rte_cryptodev *dev,
278                 struct rte_crypto_sym_xform *xform,
279                 struct rte_cryptodev_sym_session *sess,
280                 struct rte_mempool *mempool)
281 {
282         void *sess_private_data;
283         int ret;
284
285         if (unlikely(sess == NULL)) {
286                 ARMV8_CRYPTO_LOG_ERR("invalid session struct");
287                 return -EINVAL;
288         }
289
290         if (rte_mempool_get(mempool, &sess_private_data)) {
291                 CDEV_LOG_ERR(
292                         "Couldn't get object from session mempool");
293                 return -ENOMEM;
294         }
295
296         ret = armv8_crypto_set_session_parameters(sess_private_data, xform);
297         if (ret != 0) {
298                 ARMV8_CRYPTO_LOG_ERR("failed configure session parameters");
299
300                 /* Return session to mempool */
301                 rte_mempool_put(mempool, sess_private_data);
302                 return ret;
303         }
304
305         set_sym_session_private_data(sess, dev->driver_id,
306                         sess_private_data);
307
308         return 0;
309 }
310
311 /** Clear the memory of session so it doesn't leave key material behind */
312 static void
313 armv8_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev,
314                 struct rte_cryptodev_sym_session *sess)
315 {
316         uint8_t index = dev->driver_id;
317         void *sess_priv = get_sym_session_private_data(sess, index);
318
319         /* Zero out the whole structure */
320         if (sess_priv) {
321                 memset(sess_priv, 0, sizeof(struct armv8_crypto_session));
322                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
323                 set_sym_session_private_data(sess, index, NULL);
324                 rte_mempool_put(sess_mp, sess_priv);
325         }
326 }
327
328 struct rte_cryptodev_ops armv8_crypto_pmd_ops = {
329                 .dev_configure          = armv8_crypto_pmd_config,
330                 .dev_start              = armv8_crypto_pmd_start,
331                 .dev_stop               = armv8_crypto_pmd_stop,
332                 .dev_close              = armv8_crypto_pmd_close,
333
334                 .stats_get              = armv8_crypto_pmd_stats_get,
335                 .stats_reset            = armv8_crypto_pmd_stats_reset,
336
337                 .dev_infos_get          = armv8_crypto_pmd_info_get,
338
339                 .queue_pair_setup       = armv8_crypto_pmd_qp_setup,
340                 .queue_pair_release     = armv8_crypto_pmd_qp_release,
341                 .queue_pair_count       = armv8_crypto_pmd_qp_count,
342
343                 .sym_session_get_size   = armv8_crypto_pmd_sym_session_get_size,
344                 .sym_session_configure  = armv8_crypto_pmd_sym_session_configure,
345                 .sym_session_clear      = armv8_crypto_pmd_sym_session_clear
346 };
347
348 struct rte_cryptodev_ops *rte_armv8_crypto_pmd_ops = &armv8_crypto_pmd_ops;