b654f75286f95f4fccc002638678c113ba835d1b
[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 /** Start queue pair */
262 static int
263 armv8_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
264                 __rte_unused uint16_t queue_pair_id)
265 {
266         return -ENOTSUP;
267 }
268
269 /** Stop queue pair */
270 static int
271 armv8_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
272                 __rte_unused uint16_t queue_pair_id)
273 {
274         return -ENOTSUP;
275 }
276
277 /** Return the number of allocated queue pairs */
278 static uint32_t
279 armv8_crypto_pmd_qp_count(struct rte_cryptodev *dev)
280 {
281         return dev->data->nb_queue_pairs;
282 }
283
284 /** Returns the size of the session structure */
285 static unsigned
286 armv8_crypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused)
287 {
288         return sizeof(struct armv8_crypto_session);
289 }
290
291 /** Configure the session from a crypto xform chain */
292 static int
293 armv8_crypto_pmd_session_configure(struct rte_cryptodev *dev,
294                 struct rte_crypto_sym_xform *xform,
295                 struct rte_cryptodev_sym_session *sess,
296                 struct rte_mempool *mempool)
297 {
298         void *sess_private_data;
299         int ret;
300
301         if (unlikely(sess == NULL)) {
302                 ARMV8_CRYPTO_LOG_ERR("invalid session struct");
303                 return -EINVAL;
304         }
305
306         if (rte_mempool_get(mempool, &sess_private_data)) {
307                 CDEV_LOG_ERR(
308                         "Couldn't get object from session mempool");
309                 return -ENOMEM;
310         }
311
312         ret = armv8_crypto_set_session_parameters(sess_private_data, xform);
313         if (ret != 0) {
314                 ARMV8_CRYPTO_LOG_ERR("failed configure session parameters");
315
316                 /* Return session to mempool */
317                 rte_mempool_put(mempool, sess_private_data);
318                 return ret;
319         }
320
321         set_session_private_data(sess, dev->driver_id,
322                         sess_private_data);
323
324         return 0;
325 }
326
327 /** Clear the memory of session so it doesn't leave key material behind */
328 static void
329 armv8_crypto_pmd_session_clear(struct rte_cryptodev *dev,
330                 struct rte_cryptodev_sym_session *sess)
331 {
332         uint8_t index = dev->driver_id;
333         void *sess_priv = get_session_private_data(sess, index);
334
335         /* Zero out the whole structure */
336         if (sess_priv) {
337                 memset(sess_priv, 0, sizeof(struct armv8_crypto_session));
338                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
339                 set_session_private_data(sess, index, NULL);
340                 rte_mempool_put(sess_mp, sess_priv);
341         }
342 }
343
344 struct rte_cryptodev_ops armv8_crypto_pmd_ops = {
345                 .dev_configure          = armv8_crypto_pmd_config,
346                 .dev_start              = armv8_crypto_pmd_start,
347                 .dev_stop               = armv8_crypto_pmd_stop,
348                 .dev_close              = armv8_crypto_pmd_close,
349
350                 .stats_get              = armv8_crypto_pmd_stats_get,
351                 .stats_reset            = armv8_crypto_pmd_stats_reset,
352
353                 .dev_infos_get          = armv8_crypto_pmd_info_get,
354
355                 .queue_pair_setup       = armv8_crypto_pmd_qp_setup,
356                 .queue_pair_release     = armv8_crypto_pmd_qp_release,
357                 .queue_pair_start       = armv8_crypto_pmd_qp_start,
358                 .queue_pair_stop        = armv8_crypto_pmd_qp_stop,
359                 .queue_pair_count       = armv8_crypto_pmd_qp_count,
360
361                 .session_get_size       = armv8_crypto_pmd_session_get_size,
362                 .session_configure      = armv8_crypto_pmd_session_configure,
363                 .session_clear          = armv8_crypto_pmd_session_clear
364 };
365
366 struct rte_cryptodev_ops *rte_armv8_crypto_pmd_ops = &armv8_crypto_pmd_ops;