cryptodev: do not create session mempool internally
[dpdk.git] / lib / librte_cryptodev / rte_cryptodev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2015-2017 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 <sys/types.h>
34 #include <sys/queue.h>
35 #include <ctype.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdarg.h>
40 #include <errno.h>
41 #include <stdint.h>
42 #include <inttypes.h>
43 #include <netinet/in.h>
44
45 #include <rte_byteorder.h>
46 #include <rte_log.h>
47 #include <rte_debug.h>
48 #include <rte_dev.h>
49 #include <rte_interrupts.h>
50 #include <rte_memory.h>
51 #include <rte_memcpy.h>
52 #include <rte_memzone.h>
53 #include <rte_launch.h>
54 #include <rte_tailq.h>
55 #include <rte_eal.h>
56 #include <rte_per_lcore.h>
57 #include <rte_lcore.h>
58 #include <rte_atomic.h>
59 #include <rte_branch_prediction.h>
60 #include <rte_common.h>
61 #include <rte_mempool.h>
62 #include <rte_malloc.h>
63 #include <rte_mbuf.h>
64 #include <rte_errno.h>
65 #include <rte_spinlock.h>
66 #include <rte_string_fns.h>
67
68 #include "rte_crypto.h"
69 #include "rte_cryptodev.h"
70 #include "rte_cryptodev_pmd.h"
71
72 struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
73
74 struct rte_cryptodev *rte_cryptodevs = &rte_crypto_devices[0];
75
76 static struct rte_cryptodev_global cryptodev_globals = {
77                 .devs                   = &rte_crypto_devices[0],
78                 .data                   = { NULL },
79                 .nb_devs                = 0,
80                 .max_devs               = RTE_CRYPTO_MAX_DEVS
81 };
82
83 struct rte_cryptodev_global *rte_cryptodev_globals = &cryptodev_globals;
84
85 /* spinlock for crypto device callbacks */
86 static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
87
88
89 /**
90  * The user application callback description.
91  *
92  * It contains callback address to be registered by user application,
93  * the pointer to the parameters for callback, and the event type.
94  */
95 struct rte_cryptodev_callback {
96         TAILQ_ENTRY(rte_cryptodev_callback) next; /**< Callbacks list */
97         rte_cryptodev_cb_fn cb_fn;              /**< Callback address */
98         void *cb_arg;                           /**< Parameter for callback */
99         enum rte_cryptodev_event_type event;    /**< Interrupt event type */
100         uint32_t active;                        /**< Callback is executing */
101 };
102
103 /**
104  * The crypto cipher algorithm strings identifiers.
105  * It could be used in application command line.
106  */
107 const char *
108 rte_crypto_cipher_algorithm_strings[] = {
109         [RTE_CRYPTO_CIPHER_3DES_CBC]    = "3des-cbc",
110         [RTE_CRYPTO_CIPHER_3DES_ECB]    = "3des-ecb",
111         [RTE_CRYPTO_CIPHER_3DES_CTR]    = "3des-ctr",
112
113         [RTE_CRYPTO_CIPHER_AES_CBC]     = "aes-cbc",
114         [RTE_CRYPTO_CIPHER_AES_CTR]     = "aes-ctr",
115         [RTE_CRYPTO_CIPHER_AES_DOCSISBPI]       = "aes-docsisbpi",
116         [RTE_CRYPTO_CIPHER_AES_ECB]     = "aes-ecb",
117         [RTE_CRYPTO_CIPHER_AES_F8]      = "aes-f8",
118         [RTE_CRYPTO_CIPHER_AES_XTS]     = "aes-xts",
119
120         [RTE_CRYPTO_CIPHER_ARC4]        = "arc4",
121
122         [RTE_CRYPTO_CIPHER_DES_CBC]     = "des-cbc",
123         [RTE_CRYPTO_CIPHER_DES_DOCSISBPI]       = "des-docsisbpi",
124
125         [RTE_CRYPTO_CIPHER_NULL]        = "null",
126
127         [RTE_CRYPTO_CIPHER_KASUMI_F8]   = "kasumi-f8",
128         [RTE_CRYPTO_CIPHER_SNOW3G_UEA2] = "snow3g-uea2",
129         [RTE_CRYPTO_CIPHER_ZUC_EEA3]    = "zuc-eea3"
130 };
131
132 /**
133  * The crypto cipher operation strings identifiers.
134  * It could be used in application command line.
135  */
136 const char *
137 rte_crypto_cipher_operation_strings[] = {
138                 [RTE_CRYPTO_CIPHER_OP_ENCRYPT]  = "encrypt",
139                 [RTE_CRYPTO_CIPHER_OP_DECRYPT]  = "decrypt"
140 };
141
142 /**
143  * The crypto auth algorithm strings identifiers.
144  * It could be used in application command line.
145  */
146 const char *
147 rte_crypto_auth_algorithm_strings[] = {
148         [RTE_CRYPTO_AUTH_AES_CBC_MAC]   = "aes-cbc-mac",
149         [RTE_CRYPTO_AUTH_AES_CMAC]      = "aes-cmac",
150         [RTE_CRYPTO_AUTH_AES_GMAC]      = "aes-gmac",
151         [RTE_CRYPTO_AUTH_AES_XCBC_MAC]  = "aes-xcbc-mac",
152
153         [RTE_CRYPTO_AUTH_MD5]           = "md5",
154         [RTE_CRYPTO_AUTH_MD5_HMAC]      = "md5-hmac",
155
156         [RTE_CRYPTO_AUTH_NULL]          = "null",
157
158         [RTE_CRYPTO_AUTH_SHA1]          = "sha1",
159         [RTE_CRYPTO_AUTH_SHA1_HMAC]     = "sha1-hmac",
160
161         [RTE_CRYPTO_AUTH_SHA224]        = "sha2-224",
162         [RTE_CRYPTO_AUTH_SHA224_HMAC]   = "sha2-224-hmac",
163         [RTE_CRYPTO_AUTH_SHA256]        = "sha2-256",
164         [RTE_CRYPTO_AUTH_SHA256_HMAC]   = "sha2-256-hmac",
165         [RTE_CRYPTO_AUTH_SHA384]        = "sha2-384",
166         [RTE_CRYPTO_AUTH_SHA384_HMAC]   = "sha2-384-hmac",
167         [RTE_CRYPTO_AUTH_SHA512]        = "sha2-512",
168         [RTE_CRYPTO_AUTH_SHA512_HMAC]   = "sha2-512-hmac",
169
170         [RTE_CRYPTO_AUTH_KASUMI_F9]     = "kasumi-f9",
171         [RTE_CRYPTO_AUTH_SNOW3G_UIA2]   = "snow3g-uia2",
172         [RTE_CRYPTO_AUTH_ZUC_EIA3]      = "zuc-eia3"
173 };
174
175 /**
176  * The crypto AEAD algorithm strings identifiers.
177  * It could be used in application command line.
178  */
179 const char *
180 rte_crypto_aead_algorithm_strings[] = {
181         [RTE_CRYPTO_AEAD_AES_CCM]       = "aes-ccm",
182         [RTE_CRYPTO_AEAD_AES_GCM]       = "aes-gcm",
183 };
184
185 /**
186  * The crypto AEAD operation strings identifiers.
187  * It could be used in application command line.
188  */
189 const char *
190 rte_crypto_aead_operation_strings[] = {
191         [RTE_CRYPTO_AEAD_OP_ENCRYPT]    = "encrypt",
192         [RTE_CRYPTO_AEAD_OP_DECRYPT]    = "decrypt"
193 };
194
195 int
196 rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
197                 const char *algo_string)
198 {
199         unsigned int i;
200
201         for (i = 1; i < RTE_DIM(rte_crypto_cipher_algorithm_strings); i++) {
202                 if (strcmp(algo_string, rte_crypto_cipher_algorithm_strings[i]) == 0) {
203                         *algo_enum = (enum rte_crypto_cipher_algorithm) i;
204                         return 0;
205                 }
206         }
207
208         /* Invalid string */
209         return -1;
210 }
211
212 int
213 rte_cryptodev_get_auth_algo_enum(enum rte_crypto_auth_algorithm *algo_enum,
214                 const char *algo_string)
215 {
216         unsigned int i;
217
218         for (i = 1; i < RTE_DIM(rte_crypto_auth_algorithm_strings); i++) {
219                 if (strcmp(algo_string, rte_crypto_auth_algorithm_strings[i]) == 0) {
220                         *algo_enum = (enum rte_crypto_auth_algorithm) i;
221                         return 0;
222                 }
223         }
224
225         /* Invalid string */
226         return -1;
227 }
228
229 int
230 rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm *algo_enum,
231                 const char *algo_string)
232 {
233         unsigned int i;
234
235         for (i = 1; i < RTE_DIM(rte_crypto_aead_algorithm_strings); i++) {
236                 if (strcmp(algo_string, rte_crypto_aead_algorithm_strings[i]) == 0) {
237                         *algo_enum = (enum rte_crypto_aead_algorithm) i;
238                         return 0;
239                 }
240         }
241
242         /* Invalid string */
243         return -1;
244 }
245
246 /**
247  * The crypto auth operation strings identifiers.
248  * It could be used in application command line.
249  */
250 const char *
251 rte_crypto_auth_operation_strings[] = {
252                 [RTE_CRYPTO_AUTH_OP_VERIFY]     = "verify",
253                 [RTE_CRYPTO_AUTH_OP_GENERATE]   = "generate"
254 };
255
256 const struct rte_cryptodev_symmetric_capability *
257 rte_cryptodev_sym_capability_get(uint8_t dev_id,
258                 const struct rte_cryptodev_sym_capability_idx *idx)
259 {
260         const struct rte_cryptodev_capabilities *capability;
261         struct rte_cryptodev_info dev_info;
262         int i = 0;
263
264         rte_cryptodev_info_get(dev_id, &dev_info);
265
266         while ((capability = &dev_info.capabilities[i++])->op !=
267                         RTE_CRYPTO_OP_TYPE_UNDEFINED) {
268                 if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
269                         continue;
270
271                 if (capability->sym.xform_type != idx->type)
272                         continue;
273
274                 if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
275                         capability->sym.auth.algo == idx->algo.auth)
276                         return &capability->sym;
277
278                 if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
279                         capability->sym.cipher.algo == idx->algo.cipher)
280                         return &capability->sym;
281
282                 if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD &&
283                                 capability->sym.aead.algo == idx->algo.aead)
284                         return &capability->sym;
285         }
286
287         return NULL;
288
289 }
290
291 #define param_range_check(x, y) \
292         (((x < y.min) || (x > y.max)) || \
293         (y.increment != 0 && (x % y.increment) != 0))
294
295 int
296 rte_cryptodev_sym_capability_check_cipher(
297                 const struct rte_cryptodev_symmetric_capability *capability,
298                 uint16_t key_size, uint16_t iv_size)
299 {
300         if (param_range_check(key_size, capability->cipher.key_size))
301                 return -1;
302
303         if (param_range_check(iv_size, capability->cipher.iv_size))
304                 return -1;
305
306         return 0;
307 }
308
309 int
310 rte_cryptodev_sym_capability_check_auth(
311                 const struct rte_cryptodev_symmetric_capability *capability,
312                 uint16_t key_size, uint16_t digest_size, uint16_t aad_size,
313                 uint16_t iv_size)
314 {
315         if (param_range_check(key_size, capability->auth.key_size))
316                 return -1;
317
318         if (param_range_check(digest_size, capability->auth.digest_size))
319                 return -1;
320
321         if (param_range_check(aad_size, capability->auth.aad_size))
322                 return -1;
323
324         if (param_range_check(iv_size, capability->auth.iv_size))
325                 return -1;
326
327         return 0;
328 }
329
330 int
331 rte_cryptodev_sym_capability_check_aead(
332                 const struct rte_cryptodev_symmetric_capability *capability,
333                 uint16_t key_size, uint16_t digest_size, uint16_t aad_size,
334                 uint16_t iv_size)
335 {
336         if (param_range_check(key_size, capability->aead.key_size))
337                 return -1;
338
339         if (param_range_check(digest_size, capability->aead.digest_size))
340                 return -1;
341
342         if (param_range_check(aad_size, capability->aead.aad_size))
343                 return -1;
344
345         if (param_range_check(iv_size, capability->aead.iv_size))
346                 return -1;
347
348         return 0;
349 }
350
351 const char *
352 rte_cryptodev_get_feature_name(uint64_t flag)
353 {
354         switch (flag) {
355         case RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO:
356                 return "SYMMETRIC_CRYPTO";
357         case RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO:
358                 return "ASYMMETRIC_CRYPTO";
359         case RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING:
360                 return "SYM_OPERATION_CHAINING";
361         case RTE_CRYPTODEV_FF_CPU_SSE:
362                 return "CPU_SSE";
363         case RTE_CRYPTODEV_FF_CPU_AVX:
364                 return "CPU_AVX";
365         case RTE_CRYPTODEV_FF_CPU_AVX2:
366                 return "CPU_AVX2";
367         case RTE_CRYPTODEV_FF_CPU_AESNI:
368                 return "CPU_AESNI";
369         case RTE_CRYPTODEV_FF_HW_ACCELERATED:
370                 return "HW_ACCELERATED";
371         case RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER:
372                 return "MBUF_SCATTER_GATHER";
373         case RTE_CRYPTODEV_FF_CPU_NEON:
374                 return "CPU_NEON";
375         case RTE_CRYPTODEV_FF_CPU_ARM_CE:
376                 return "CPU_ARM_CE";
377         default:
378                 return NULL;
379         }
380 }
381
382 int
383 rte_cryptodev_create_vdev(const char *name, const char *args)
384 {
385         return rte_vdev_init(name, args);
386 }
387
388 struct rte_cryptodev *
389 rte_cryptodev_pmd_get_dev(uint8_t dev_id)
390 {
391         return &rte_cryptodev_globals->devs[dev_id];
392 }
393
394 struct rte_cryptodev *
395 rte_cryptodev_pmd_get_named_dev(const char *name)
396 {
397         struct rte_cryptodev *dev;
398         unsigned int i;
399
400         if (name == NULL)
401                 return NULL;
402
403         for (i = 0; i < rte_cryptodev_globals->max_devs; i++) {
404                 dev = &rte_cryptodev_globals->devs[i];
405
406                 if ((dev->attached == RTE_CRYPTODEV_ATTACHED) &&
407                                 (strcmp(dev->data->name, name) == 0))
408                         return dev;
409         }
410
411         return NULL;
412 }
413
414 unsigned int
415 rte_cryptodev_pmd_is_valid_dev(uint8_t dev_id)
416 {
417         struct rte_cryptodev *dev = NULL;
418
419         if (dev_id >= rte_cryptodev_globals->nb_devs)
420                 return 0;
421
422         dev = rte_cryptodev_pmd_get_dev(dev_id);
423         if (dev->attached != RTE_CRYPTODEV_ATTACHED)
424                 return 0;
425         else
426                 return 1;
427 }
428
429
430 int
431 rte_cryptodev_get_dev_id(const char *name)
432 {
433         unsigned i;
434
435         if (name == NULL)
436                 return -1;
437
438         for (i = 0; i < rte_cryptodev_globals->nb_devs; i++)
439                 if ((strcmp(rte_cryptodev_globals->devs[i].data->name, name)
440                                 == 0) &&
441                                 (rte_cryptodev_globals->devs[i].attached ==
442                                                 RTE_CRYPTODEV_ATTACHED))
443                         return i;
444
445         return -1;
446 }
447
448 uint8_t
449 rte_cryptodev_count(void)
450 {
451         return rte_cryptodev_globals->nb_devs;
452 }
453
454 uint8_t
455 rte_cryptodev_device_count_by_driver(uint8_t driver_id)
456 {
457         uint8_t i, dev_count = 0;
458
459         for (i = 0; i < rte_cryptodev_globals->max_devs; i++)
460                 if (rte_cryptodev_globals->devs[i].driver_id == driver_id &&
461                         rte_cryptodev_globals->devs[i].attached ==
462                                         RTE_CRYPTODEV_ATTACHED)
463                         dev_count++;
464
465         return dev_count;
466 }
467
468 uint8_t
469 rte_cryptodev_devices_get(const char *driver_name, uint8_t *devices,
470         uint8_t nb_devices)
471 {
472         uint8_t i, count = 0;
473         struct rte_cryptodev *devs = rte_cryptodev_globals->devs;
474         uint8_t max_devs = rte_cryptodev_globals->max_devs;
475
476         for (i = 0; i < max_devs && count < nb_devices; i++) {
477
478                 if (devs[i].attached == RTE_CRYPTODEV_ATTACHED) {
479                         int cmp;
480
481                         cmp = strncmp(devs[i].device->driver->name,
482                                         driver_name,
483                                         strlen(driver_name));
484
485                         if (cmp == 0)
486                                 devices[count++] = devs[i].data->dev_id;
487                 }
488         }
489
490         return count;
491 }
492
493 int
494 rte_cryptodev_socket_id(uint8_t dev_id)
495 {
496         struct rte_cryptodev *dev;
497
498         if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
499                 return -1;
500
501         dev = rte_cryptodev_pmd_get_dev(dev_id);
502
503         return dev->data->socket_id;
504 }
505
506 static inline int
507 rte_cryptodev_data_alloc(uint8_t dev_id, struct rte_cryptodev_data **data,
508                 int socket_id)
509 {
510         char mz_name[RTE_CRYPTODEV_NAME_MAX_LEN];
511         const struct rte_memzone *mz;
512         int n;
513
514         /* generate memzone name */
515         n = snprintf(mz_name, sizeof(mz_name), "rte_cryptodev_data_%u", dev_id);
516         if (n >= (int)sizeof(mz_name))
517                 return -EINVAL;
518
519         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
520                 mz = rte_memzone_reserve(mz_name,
521                                 sizeof(struct rte_cryptodev_data),
522                                 socket_id, 0);
523         } else
524                 mz = rte_memzone_lookup(mz_name);
525
526         if (mz == NULL)
527                 return -ENOMEM;
528
529         *data = mz->addr;
530         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
531                 memset(*data, 0, sizeof(struct rte_cryptodev_data));
532
533         return 0;
534 }
535
536 static uint8_t
537 rte_cryptodev_find_free_device_index(void)
538 {
539         uint8_t dev_id;
540
541         for (dev_id = 0; dev_id < RTE_CRYPTO_MAX_DEVS; dev_id++) {
542                 if (rte_crypto_devices[dev_id].attached ==
543                                 RTE_CRYPTODEV_DETACHED)
544                         return dev_id;
545         }
546         return RTE_CRYPTO_MAX_DEVS;
547 }
548
549 struct rte_cryptodev *
550 rte_cryptodev_pmd_allocate(const char *name, int socket_id)
551 {
552         struct rte_cryptodev *cryptodev;
553         uint8_t dev_id;
554
555         if (rte_cryptodev_pmd_get_named_dev(name) != NULL) {
556                 CDEV_LOG_ERR("Crypto device with name %s already "
557                                 "allocated!", name);
558                 return NULL;
559         }
560
561         dev_id = rte_cryptodev_find_free_device_index();
562         if (dev_id == RTE_CRYPTO_MAX_DEVS) {
563                 CDEV_LOG_ERR("Reached maximum number of crypto devices");
564                 return NULL;
565         }
566
567         cryptodev = rte_cryptodev_pmd_get_dev(dev_id);
568
569         if (cryptodev->data == NULL) {
570                 struct rte_cryptodev_data *cryptodev_data =
571                                 cryptodev_globals.data[dev_id];
572
573                 int retval = rte_cryptodev_data_alloc(dev_id, &cryptodev_data,
574                                 socket_id);
575
576                 if (retval < 0 || cryptodev_data == NULL)
577                         return NULL;
578
579                 cryptodev->data = cryptodev_data;
580
581                 snprintf(cryptodev->data->name, RTE_CRYPTODEV_NAME_MAX_LEN,
582                                 "%s", name);
583
584                 cryptodev->data->dev_id = dev_id;
585                 cryptodev->data->socket_id = socket_id;
586                 cryptodev->data->dev_started = 0;
587
588                 cryptodev->attached = RTE_CRYPTODEV_ATTACHED;
589
590                 cryptodev_globals.nb_devs++;
591         }
592
593         return cryptodev;
594 }
595
596 int
597 rte_cryptodev_pmd_release_device(struct rte_cryptodev *cryptodev)
598 {
599         int ret;
600
601         if (cryptodev == NULL)
602                 return -EINVAL;
603
604         /* Close device only if device operations have been set */
605         if (cryptodev->dev_ops) {
606                 ret = rte_cryptodev_close(cryptodev->data->dev_id);
607                 if (ret < 0)
608                         return ret;
609         }
610
611         cryptodev->attached = RTE_CRYPTODEV_DETACHED;
612         cryptodev_globals.nb_devs--;
613         return 0;
614 }
615
616 uint16_t
617 rte_cryptodev_queue_pair_count(uint8_t dev_id)
618 {
619         struct rte_cryptodev *dev;
620
621         dev = &rte_crypto_devices[dev_id];
622         return dev->data->nb_queue_pairs;
623 }
624
625 static int
626 rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
627                 int socket_id)
628 {
629         struct rte_cryptodev_info dev_info;
630         void **qp;
631         unsigned i;
632
633         if ((dev == NULL) || (nb_qpairs < 1)) {
634                 CDEV_LOG_ERR("invalid param: dev %p, nb_queues %u",
635                                                         dev, nb_qpairs);
636                 return -EINVAL;
637         }
638
639         CDEV_LOG_DEBUG("Setup %d queues pairs on device %u",
640                         nb_qpairs, dev->data->dev_id);
641
642         memset(&dev_info, 0, sizeof(struct rte_cryptodev_info));
643
644         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
645         (*dev->dev_ops->dev_infos_get)(dev, &dev_info);
646
647         if (nb_qpairs > (dev_info.max_nb_queue_pairs)) {
648                 CDEV_LOG_ERR("Invalid num queue_pairs (%u) for dev %u",
649                                 nb_qpairs, dev->data->dev_id);
650             return -EINVAL;
651         }
652
653         if (dev->data->queue_pairs == NULL) { /* first time configuration */
654                 dev->data->queue_pairs = rte_zmalloc_socket(
655                                 "cryptodev->queue_pairs",
656                                 sizeof(dev->data->queue_pairs[0]) * nb_qpairs,
657                                 RTE_CACHE_LINE_SIZE, socket_id);
658
659                 if (dev->data->queue_pairs == NULL) {
660                         dev->data->nb_queue_pairs = 0;
661                         CDEV_LOG_ERR("failed to get memory for qp meta data, "
662                                                         "nb_queues %u",
663                                                         nb_qpairs);
664                         return -(ENOMEM);
665                 }
666         } else { /* re-configure */
667                 int ret;
668                 uint16_t old_nb_queues = dev->data->nb_queue_pairs;
669
670                 qp = dev->data->queue_pairs;
671
672                 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_release,
673                                 -ENOTSUP);
674
675                 for (i = nb_qpairs; i < old_nb_queues; i++) {
676                         ret = (*dev->dev_ops->queue_pair_release)(dev, i);
677                         if (ret < 0)
678                                 return ret;
679                 }
680
681                 qp = rte_realloc(qp, sizeof(qp[0]) * nb_qpairs,
682                                 RTE_CACHE_LINE_SIZE);
683                 if (qp == NULL) {
684                         CDEV_LOG_ERR("failed to realloc qp meta data,"
685                                                 " nb_queues %u", nb_qpairs);
686                         return -(ENOMEM);
687                 }
688
689                 if (nb_qpairs > old_nb_queues) {
690                         uint16_t new_qs = nb_qpairs - old_nb_queues;
691
692                         memset(qp + old_nb_queues, 0,
693                                 sizeof(qp[0]) * new_qs);
694                 }
695
696                 dev->data->queue_pairs = qp;
697
698         }
699         dev->data->nb_queue_pairs = nb_qpairs;
700         return 0;
701 }
702
703 int
704 rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id)
705 {
706         struct rte_cryptodev *dev;
707
708         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
709                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
710                 return -EINVAL;
711         }
712
713         dev = &rte_crypto_devices[dev_id];
714         if (queue_pair_id >= dev->data->nb_queue_pairs) {
715                 CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
716                 return -EINVAL;
717         }
718
719         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_start, -ENOTSUP);
720
721         return dev->dev_ops->queue_pair_start(dev, queue_pair_id);
722
723 }
724
725 int
726 rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id)
727 {
728         struct rte_cryptodev *dev;
729
730         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
731                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
732                 return -EINVAL;
733         }
734
735         dev = &rte_crypto_devices[dev_id];
736         if (queue_pair_id >= dev->data->nb_queue_pairs) {
737                 CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
738                 return -EINVAL;
739         }
740
741         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_stop, -ENOTSUP);
742
743         return dev->dev_ops->queue_pair_stop(dev, queue_pair_id);
744
745 }
746
747 int
748 rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config,
749                 struct rte_mempool *session_pool)
750 {
751         struct rte_cryptodev *dev;
752         int diag;
753
754         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
755                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
756                 return -EINVAL;
757         }
758
759         dev = &rte_crypto_devices[dev_id];
760
761         if (dev->data->dev_started) {
762                 CDEV_LOG_ERR(
763                     "device %d must be stopped to allow configuration", dev_id);
764                 return -EBUSY;
765         }
766
767         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
768
769         dev->data->session_pool = session_pool;
770
771         /* Setup new number of queue pairs and reconfigure device. */
772         diag = rte_cryptodev_queue_pairs_config(dev, config->nb_queue_pairs,
773                         config->socket_id);
774         if (diag != 0) {
775                 CDEV_LOG_ERR("dev%d rte_crypto_dev_queue_pairs_config = %d",
776                                 dev_id, diag);
777                 return diag;
778         }
779
780         return (*dev->dev_ops->dev_configure)(dev, config);
781 }
782
783
784 int
785 rte_cryptodev_start(uint8_t dev_id)
786 {
787         struct rte_cryptodev *dev;
788         int diag;
789
790         CDEV_LOG_DEBUG("Start dev_id=%" PRIu8, dev_id);
791
792         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
793                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
794                 return -EINVAL;
795         }
796
797         dev = &rte_crypto_devices[dev_id];
798
799         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
800
801         if (dev->data->dev_started != 0) {
802                 CDEV_LOG_ERR("Device with dev_id=%" PRIu8 " already started",
803                         dev_id);
804                 return 0;
805         }
806
807         diag = (*dev->dev_ops->dev_start)(dev);
808         if (diag == 0)
809                 dev->data->dev_started = 1;
810         else
811                 return diag;
812
813         return 0;
814 }
815
816 void
817 rte_cryptodev_stop(uint8_t dev_id)
818 {
819         struct rte_cryptodev *dev;
820
821         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
822                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
823                 return;
824         }
825
826         dev = &rte_crypto_devices[dev_id];
827
828         RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
829
830         if (dev->data->dev_started == 0) {
831                 CDEV_LOG_ERR("Device with dev_id=%" PRIu8 " already stopped",
832                         dev_id);
833                 return;
834         }
835
836         (*dev->dev_ops->dev_stop)(dev);
837         dev->data->dev_started = 0;
838 }
839
840 int
841 rte_cryptodev_close(uint8_t dev_id)
842 {
843         struct rte_cryptodev *dev;
844         int retval;
845
846         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
847                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
848                 return -1;
849         }
850
851         dev = &rte_crypto_devices[dev_id];
852
853         /* Device must be stopped before it can be closed */
854         if (dev->data->dev_started == 1) {
855                 CDEV_LOG_ERR("Device %u must be stopped before closing",
856                                 dev_id);
857                 return -EBUSY;
858         }
859
860         /* We can't close the device if there are outstanding sessions in use */
861         if (dev->data->session_pool != NULL) {
862                 if (!rte_mempool_full(dev->data->session_pool)) {
863                         CDEV_LOG_ERR("dev_id=%u close failed, session mempool "
864                                         "has sessions still in use, free "
865                                         "all sessions before calling close",
866                                         (unsigned)dev_id);
867                         return -EBUSY;
868                 }
869         }
870
871         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
872         retval = (*dev->dev_ops->dev_close)(dev);
873
874         if (retval < 0)
875                 return retval;
876
877         return 0;
878 }
879
880 int
881 rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
882                 const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
883 {
884         struct rte_cryptodev *dev;
885
886         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
887                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
888                 return -EINVAL;
889         }
890
891         dev = &rte_crypto_devices[dev_id];
892         if (queue_pair_id >= dev->data->nb_queue_pairs) {
893                 CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
894                 return -EINVAL;
895         }
896
897         if (dev->data->dev_started) {
898                 CDEV_LOG_ERR(
899                     "device %d must be stopped to allow configuration", dev_id);
900                 return -EBUSY;
901         }
902
903         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
904
905         return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf,
906                         socket_id);
907 }
908
909
910 int
911 rte_cryptodev_stats_get(uint8_t dev_id, struct rte_cryptodev_stats *stats)
912 {
913         struct rte_cryptodev *dev;
914
915         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
916                 CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
917                 return -ENODEV;
918         }
919
920         if (stats == NULL) {
921                 CDEV_LOG_ERR("Invalid stats ptr");
922                 return -EINVAL;
923         }
924
925         dev = &rte_crypto_devices[dev_id];
926         memset(stats, 0, sizeof(*stats));
927
928         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
929         (*dev->dev_ops->stats_get)(dev, stats);
930         return 0;
931 }
932
933 void
934 rte_cryptodev_stats_reset(uint8_t dev_id)
935 {
936         struct rte_cryptodev *dev;
937
938         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
939                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
940                 return;
941         }
942
943         dev = &rte_crypto_devices[dev_id];
944
945         RTE_FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset);
946         (*dev->dev_ops->stats_reset)(dev);
947 }
948
949
950 void
951 rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
952 {
953         struct rte_cryptodev *dev;
954
955         if (dev_id >= cryptodev_globals.nb_devs) {
956                 CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
957                 return;
958         }
959
960         dev = &rte_crypto_devices[dev_id];
961
962         memset(dev_info, 0, sizeof(struct rte_cryptodev_info));
963
964         RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
965         (*dev->dev_ops->dev_infos_get)(dev, dev_info);
966
967         dev_info->driver_name = dev->device->driver->name;
968 }
969
970
971 int
972 rte_cryptodev_callback_register(uint8_t dev_id,
973                         enum rte_cryptodev_event_type event,
974                         rte_cryptodev_cb_fn cb_fn, void *cb_arg)
975 {
976         struct rte_cryptodev *dev;
977         struct rte_cryptodev_callback *user_cb;
978
979         if (!cb_fn)
980                 return -EINVAL;
981
982         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
983                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
984                 return -EINVAL;
985         }
986
987         dev = &rte_crypto_devices[dev_id];
988         rte_spinlock_lock(&rte_cryptodev_cb_lock);
989
990         TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
991                 if (user_cb->cb_fn == cb_fn &&
992                         user_cb->cb_arg == cb_arg &&
993                         user_cb->event == event) {
994                         break;
995                 }
996         }
997
998         /* create a new callback. */
999         if (user_cb == NULL) {
1000                 user_cb = rte_zmalloc("INTR_USER_CALLBACK",
1001                                 sizeof(struct rte_cryptodev_callback), 0);
1002                 if (user_cb != NULL) {
1003                         user_cb->cb_fn = cb_fn;
1004                         user_cb->cb_arg = cb_arg;
1005                         user_cb->event = event;
1006                         TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), user_cb, next);
1007                 }
1008         }
1009
1010         rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1011         return (user_cb == NULL) ? -ENOMEM : 0;
1012 }
1013
1014 int
1015 rte_cryptodev_callback_unregister(uint8_t dev_id,
1016                         enum rte_cryptodev_event_type event,
1017                         rte_cryptodev_cb_fn cb_fn, void *cb_arg)
1018 {
1019         int ret;
1020         struct rte_cryptodev *dev;
1021         struct rte_cryptodev_callback *cb, *next;
1022
1023         if (!cb_fn)
1024                 return -EINVAL;
1025
1026         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1027                 CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1028                 return -EINVAL;
1029         }
1030
1031         dev = &rte_crypto_devices[dev_id];
1032         rte_spinlock_lock(&rte_cryptodev_cb_lock);
1033
1034         ret = 0;
1035         for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; cb = next) {
1036
1037                 next = TAILQ_NEXT(cb, next);
1038
1039                 if (cb->cb_fn != cb_fn || cb->event != event ||
1040                                 (cb->cb_arg != (void *)-1 &&
1041                                 cb->cb_arg != cb_arg))
1042                         continue;
1043
1044                 /*
1045                  * if this callback is not executing right now,
1046                  * then remove it.
1047                  */
1048                 if (cb->active == 0) {
1049                         TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
1050                         rte_free(cb);
1051                 } else {
1052                         ret = -EAGAIN;
1053                 }
1054         }
1055
1056         rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1057         return ret;
1058 }
1059
1060 void
1061 rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev,
1062         enum rte_cryptodev_event_type event)
1063 {
1064         struct rte_cryptodev_callback *cb_lst;
1065         struct rte_cryptodev_callback dev_cb;
1066
1067         rte_spinlock_lock(&rte_cryptodev_cb_lock);
1068         TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
1069                 if (cb_lst->cb_fn == NULL || cb_lst->event != event)
1070                         continue;
1071                 dev_cb = *cb_lst;
1072                 cb_lst->active = 1;
1073                 rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1074                 dev_cb.cb_fn(dev->data->dev_id, dev_cb.event,
1075                                                 dev_cb.cb_arg);
1076                 rte_spinlock_lock(&rte_cryptodev_cb_lock);
1077                 cb_lst->active = 0;
1078         }
1079         rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1080 }
1081
1082
1083 static void
1084 rte_cryptodev_sym_session_init(struct rte_mempool *mp,
1085                 const struct rte_cryptodev *dev,
1086                 struct rte_cryptodev_sym_session *sess)
1087 {
1088         memset(sess, 0, mp->elt_size);
1089
1090         sess->dev_id = dev->data->dev_id;
1091         sess->driver_id = dev->driver_id;
1092         sess->mp = mp;
1093
1094         if (dev->dev_ops->session_initialize)
1095                 (*dev->dev_ops->session_initialize)(mp, sess);
1096 }
1097
1098
1099 struct rte_cryptodev_sym_session *
1100 rte_cryptodev_sym_session_create(uint8_t dev_id,
1101                 struct rte_crypto_sym_xform *xform)
1102 {
1103         struct rte_cryptodev *dev;
1104         struct rte_cryptodev_sym_session *sess;
1105         void *_sess;
1106
1107         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1108                 CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
1109                 return NULL;
1110         }
1111
1112         dev = &rte_crypto_devices[dev_id];
1113
1114         /* Allocate a session structure from the session pool */
1115         if (rte_mempool_get(dev->data->session_pool, &_sess)) {
1116                 CDEV_LOG_ERR("Couldn't get object from session mempool");
1117                 return NULL;
1118         }
1119
1120         sess = _sess;
1121
1122         rte_cryptodev_sym_session_init(dev->data->session_pool, dev,
1123                                         sess);
1124         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_configure, NULL);
1125         if (dev->dev_ops->session_configure(dev, xform, sess->_private) ==
1126                         NULL) {
1127                 CDEV_LOG_ERR("dev_id %d failed to configure session details",
1128                                 dev_id);
1129
1130                 /* Return session to mempool */
1131                 rte_mempool_put(sess->mp, _sess);
1132                 return NULL;
1133         }
1134
1135         return sess;
1136 }
1137
1138 int
1139 rte_cryptodev_queue_pair_attach_sym_session(uint16_t qp_id,
1140                 struct rte_cryptodev_sym_session *sess)
1141 {
1142         struct rte_cryptodev *dev;
1143
1144         if (!rte_cryptodev_pmd_is_valid_dev(sess->dev_id)) {
1145                 CDEV_LOG_ERR("Invalid dev_id=%d", sess->dev_id);
1146                 return -EINVAL;
1147         }
1148
1149         dev = &rte_crypto_devices[sess->dev_id];
1150
1151         /* The API is optional, not returning error if driver do not suuport */
1152         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->qp_attach_session, 0);
1153         if (dev->dev_ops->qp_attach_session(dev, qp_id, sess->_private)) {
1154                 CDEV_LOG_ERR("dev_id %d failed to attach qp: %d with session",
1155                                 sess->dev_id, qp_id);
1156                 return -EPERM;
1157         }
1158
1159         return 0;
1160 }
1161
1162 int
1163 rte_cryptodev_queue_pair_detach_sym_session(uint16_t qp_id,
1164                 struct rte_cryptodev_sym_session *sess)
1165 {
1166         struct rte_cryptodev *dev;
1167
1168         if (!rte_cryptodev_pmd_is_valid_dev(sess->dev_id)) {
1169                 CDEV_LOG_ERR("Invalid dev_id=%d", sess->dev_id);
1170                 return -EINVAL;
1171         }
1172
1173         dev = &rte_crypto_devices[sess->dev_id];
1174
1175         /* The API is optional, not returning error if driver do not suuport */
1176         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->qp_detach_session, 0);
1177         if (dev->dev_ops->qp_detach_session(dev, qp_id, sess->_private)) {
1178                 CDEV_LOG_ERR("dev_id %d failed to detach qp: %d from session",
1179                                 sess->dev_id, qp_id);
1180                 return -EPERM;
1181         }
1182
1183         return 0;
1184 }
1185 struct rte_cryptodev_sym_session *
1186 rte_cryptodev_sym_session_free(uint8_t dev_id,
1187                 struct rte_cryptodev_sym_session *sess)
1188 {
1189         struct rte_cryptodev *dev;
1190
1191         if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1192                 CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
1193                 return sess;
1194         }
1195
1196         dev = &rte_crypto_devices[dev_id];
1197
1198         /* Check the session belongs to this device type */
1199         if (sess->driver_id != dev->driver_id)
1200                 return sess;
1201
1202         /* Let device implementation clear session material */
1203         RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_clear, sess);
1204         dev->dev_ops->session_clear(dev, (void *)sess->_private);
1205
1206         /* Return session to mempool */
1207         rte_mempool_put(sess->mp, (void *)sess);
1208
1209         return NULL;
1210 }
1211
1212 unsigned int
1213 rte_cryptodev_get_private_session_size(uint8_t dev_id)
1214 {
1215         struct rte_cryptodev *dev;
1216         unsigned int priv_sess_size;
1217
1218         if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
1219                 return 0;
1220
1221         dev = rte_cryptodev_pmd_get_dev(dev_id);
1222
1223         if (*dev->dev_ops->session_get_size == NULL)
1224                 return 0;
1225
1226         priv_sess_size = (*dev->dev_ops->session_get_size)(dev);
1227
1228         return priv_sess_size;
1229
1230 }
1231
1232 /** Initialise rte_crypto_op mempool element */
1233 static void
1234 rte_crypto_op_init(struct rte_mempool *mempool,
1235                 void *opaque_arg,
1236                 void *_op_data,
1237                 __rte_unused unsigned i)
1238 {
1239         struct rte_crypto_op *op = _op_data;
1240         enum rte_crypto_op_type type = *(enum rte_crypto_op_type *)opaque_arg;
1241
1242         memset(_op_data, 0, mempool->elt_size);
1243
1244         __rte_crypto_op_reset(op, type);
1245
1246         op->phys_addr = rte_mem_virt2phy(_op_data);
1247         op->mempool = mempool;
1248 }
1249
1250
1251 struct rte_mempool *
1252 rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type,
1253                 unsigned nb_elts, unsigned cache_size, uint16_t priv_size,
1254                 int socket_id)
1255 {
1256         struct rte_crypto_op_pool_private *priv;
1257
1258         unsigned elt_size = sizeof(struct rte_crypto_op) +
1259                         sizeof(struct rte_crypto_sym_op) +
1260                         priv_size;
1261
1262         /* lookup mempool in case already allocated */
1263         struct rte_mempool *mp = rte_mempool_lookup(name);
1264
1265         if (mp != NULL) {
1266                 priv = (struct rte_crypto_op_pool_private *)
1267                                 rte_mempool_get_priv(mp);
1268
1269                 if (mp->elt_size != elt_size ||
1270                                 mp->cache_size < cache_size ||
1271                                 mp->size < nb_elts ||
1272                                 priv->priv_size <  priv_size) {
1273                         mp = NULL;
1274                         CDEV_LOG_ERR("Mempool %s already exists but with "
1275                                         "incompatible parameters", name);
1276                         return NULL;
1277                 }
1278                 return mp;
1279         }
1280
1281         mp = rte_mempool_create(
1282                         name,
1283                         nb_elts,
1284                         elt_size,
1285                         cache_size,
1286                         sizeof(struct rte_crypto_op_pool_private),
1287                         NULL,
1288                         NULL,
1289                         rte_crypto_op_init,
1290                         &type,
1291                         socket_id,
1292                         0);
1293
1294         if (mp == NULL) {
1295                 CDEV_LOG_ERR("Failed to create mempool %s", name);
1296                 return NULL;
1297         }
1298
1299         priv = (struct rte_crypto_op_pool_private *)
1300                         rte_mempool_get_priv(mp);
1301
1302         priv->priv_size = priv_size;
1303         priv->type = type;
1304
1305         return mp;
1306 }
1307
1308 int
1309 rte_cryptodev_pmd_create_dev_name(char *name, const char *dev_name_prefix)
1310 {
1311         struct rte_cryptodev *dev = NULL;
1312         uint32_t i = 0;
1313
1314         if (name == NULL)
1315                 return -EINVAL;
1316
1317         for (i = 0; i < RTE_CRYPTO_MAX_DEVS; i++) {
1318                 int ret = snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN,
1319                                 "%s_%u", dev_name_prefix, i);
1320
1321                 if (ret < 0)
1322                         return ret;
1323
1324                 dev = rte_cryptodev_pmd_get_named_dev(name);
1325                 if (!dev)
1326                         return 0;
1327         }
1328
1329         return -1;
1330 }
1331
1332 TAILQ_HEAD(cryptodev_driver_list, cryptodev_driver);
1333
1334 static struct cryptodev_driver_list cryptodev_driver_list =
1335         TAILQ_HEAD_INITIALIZER(cryptodev_driver_list);
1336
1337 struct cryptodev_driver {
1338         TAILQ_ENTRY(cryptodev_driver) next; /**< Next in list. */
1339         const struct rte_driver *driver;
1340         uint8_t id;
1341 };
1342
1343 static uint8_t nb_drivers;
1344
1345 int
1346 rte_cryptodev_driver_id_get(const char *name)
1347 {
1348         struct cryptodev_driver *driver;
1349         const char *driver_name;
1350
1351         if (name == NULL) {
1352                 RTE_LOG(DEBUG, CRYPTODEV, "name pointer NULL");
1353                 return -1;
1354         }
1355
1356         TAILQ_FOREACH(driver, &cryptodev_driver_list, next) {
1357                 driver_name = driver->driver->name;
1358                 if (strncmp(driver_name, name, strlen(driver_name)) == 0)
1359                         return driver->id;
1360         }
1361         return -1;
1362 }
1363
1364 const char *
1365 rte_cryptodev_driver_name_get(uint8_t driver_id)
1366 {
1367         struct cryptodev_driver *driver;
1368
1369         TAILQ_FOREACH(driver, &cryptodev_driver_list, next)
1370                 if (driver->id == driver_id)
1371                         return driver->driver->name;
1372         return NULL;
1373 }
1374
1375 uint8_t
1376 rte_cryptodev_allocate_driver(const struct rte_driver *drv)
1377 {
1378         struct cryptodev_driver *driver;
1379
1380         driver = malloc(sizeof(*driver));
1381         driver->driver = drv;
1382         driver->id = nb_drivers;
1383
1384         TAILQ_INSERT_TAIL(&cryptodev_driver_list, driver, next);
1385
1386         return nb_drivers++;
1387 }