1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 #include <stdlib.h> 6 #include <stdio.h> 7 8 #include <rte_cryptodev.h> 9 #include <cryptodev_pmd.h> 10 #include <rte_string_fns.h> 11 12 #include "rte_eth_softnic_internals.h" 13 14 #define SOFTNIC_CRYPTO_SESSION_CACHE_SIZE 128 15 16 int 17 softnic_cryptodev_init(struct pmd_internals *p) 18 { 19 TAILQ_INIT(&p->cryptodev_list); 20 21 return 0; 22 } 23 24 void 25 softnic_cryptodev_free(struct pmd_internals *p) 26 { 27 for ( ; ; ) { 28 struct softnic_cryptodev *cryptodev; 29 30 cryptodev = TAILQ_FIRST(&p->cryptodev_list); 31 if (cryptodev == NULL) 32 break; 33 34 TAILQ_REMOVE(&p->cryptodev_list, cryptodev, node); 35 free(cryptodev); 36 } 37 } 38 39 struct softnic_cryptodev * 40 softnic_cryptodev_find(struct pmd_internals *p, 41 const char *name) 42 { 43 struct softnic_cryptodev *cryptodev; 44 45 if (name == NULL) 46 return NULL; 47 48 TAILQ_FOREACH(cryptodev, &p->cryptodev_list, node) 49 if (strcmp(cryptodev->name, name) == 0) 50 return cryptodev; 51 52 return NULL; 53 } 54 55 struct softnic_cryptodev * 56 softnic_cryptodev_create(struct pmd_internals *p, 57 const char *name, 58 struct softnic_cryptodev_params *params) 59 { 60 struct rte_cryptodev_info dev_info; 61 struct rte_cryptodev_config dev_conf; 62 struct rte_cryptodev_qp_conf queue_conf; 63 struct softnic_cryptodev *cryptodev; 64 uint32_t dev_id, i; 65 uint32_t socket_id; 66 uint32_t cache_size; 67 char mp_name[NAME_SIZE]; 68 int status; 69 70 /* Check input params */ 71 if ((name == NULL) || 72 softnic_cryptodev_find(p, name) || 73 (params->n_queues == 0) || 74 (params->queue_size == 0) || 75 (params->session_pool_size == 0)) 76 return NULL; 77 78 if (params->dev_name) { 79 status = rte_cryptodev_get_dev_id(params->dev_name); 80 if (status == -1) 81 return NULL; 82 83 dev_id = (uint32_t)status; 84 } else { 85 if (rte_cryptodev_is_valid_dev(params->dev_id) == 0) 86 return NULL; 87 88 dev_id = params->dev_id; 89 } 90 91 cache_size = (params->session_pool_size / 2 < 92 SOFTNIC_CRYPTO_SESSION_CACHE_SIZE) ? 93 (params->session_pool_size / 2) : 94 SOFTNIC_CRYPTO_SESSION_CACHE_SIZE; 95 96 socket_id = rte_cryptodev_socket_id(dev_id); 97 rte_cryptodev_info_get(dev_id, &dev_info); 98 99 if (dev_info.max_nb_queue_pairs < params->n_queues) 100 return NULL; 101 if (dev_info.feature_flags & RTE_CRYPTODEV_FF_HW_ACCELERATED) 102 return NULL; 103 104 dev_conf.socket_id = socket_id; 105 dev_conf.nb_queue_pairs = params->n_queues; 106 107 status = rte_cryptodev_configure(dev_id, &dev_conf); 108 if (status < 0) 109 return NULL; 110 111 queue_conf.nb_descriptors = params->queue_size; 112 for (i = 0; i < params->n_queues; i++) { 113 status = rte_cryptodev_queue_pair_setup(dev_id, i, 114 &queue_conf, socket_id); 115 if (status < 0) 116 return NULL; 117 } 118 119 if (rte_cryptodev_start(dev_id) < 0) 120 return NULL; 121 122 cryptodev = calloc(1, sizeof(struct softnic_cryptodev)); 123 if (cryptodev == NULL) { 124 rte_cryptodev_stop(dev_id); 125 return NULL; 126 } 127 128 strlcpy(cryptodev->name, name, sizeof(cryptodev->name)); 129 cryptodev->dev_id = dev_id; 130 cryptodev->n_queues = params->n_queues; 131 132 snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id); 133 cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(mp_name, 134 params->session_pool_size, 135 0, 136 cache_size, 137 0, 138 socket_id); 139 if (!cryptodev->mp_create) 140 goto error_exit; 141 142 snprintf(mp_name, NAME_SIZE, "%s_priv_mp%u", name, dev_id); 143 cryptodev->mp_init = rte_mempool_create(mp_name, 144 params->session_pool_size, 145 rte_cryptodev_sym_get_private_session_size(dev_id), 146 cache_size, 147 0, 148 NULL, 149 NULL, 150 NULL, 151 NULL, 152 socket_id, 153 0); 154 if (!cryptodev->mp_init) 155 goto error_exit; 156 157 TAILQ_INSERT_TAIL(&p->cryptodev_list, cryptodev, node); 158 159 return cryptodev; 160 161 error_exit: 162 rte_mempool_free(cryptodev->mp_create); 163 rte_mempool_free(cryptodev->mp_init); 164 165 free(cryptodev); 166 167 return NULL; 168 } 169