1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016-2017 Intel Corporation 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 "null_crypto_pmd_private.h" 12 13 static const struct rte_cryptodev_capabilities null_crypto_pmd_capabilities[] = { 14 { /* NULL (AUTH) */ 15 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 16 {.sym = { 17 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH, 18 {.auth = { 19 .algo = RTE_CRYPTO_AUTH_NULL, 20 .block_size = 1, 21 .key_size = { 22 .min = 0, 23 .max = 0, 24 .increment = 0 25 }, 26 .digest_size = { 27 .min = 0, 28 .max = 0, 29 .increment = 0 30 }, 31 .iv_size = { 0 } 32 }, }, 33 }, }, 34 }, 35 { /* NULL (CIPHER) */ 36 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC, 37 {.sym = { 38 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER, 39 {.cipher = { 40 .algo = RTE_CRYPTO_CIPHER_NULL, 41 .block_size = 1, 42 .key_size = { 43 .min = 0, 44 .max = 0, 45 .increment = 0 46 }, 47 .iv_size = { 0 } 48 }, }, 49 }, } 50 }, 51 RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() 52 }; 53 54 /** Configure device */ 55 static int 56 null_crypto_pmd_config(__rte_unused struct rte_cryptodev *dev, 57 __rte_unused struct rte_cryptodev_config *config) 58 { 59 return 0; 60 } 61 62 /** Start device */ 63 static int 64 null_crypto_pmd_start(__rte_unused struct rte_cryptodev *dev) 65 { 66 return 0; 67 } 68 69 /** Stop device */ 70 static void 71 null_crypto_pmd_stop(__rte_unused struct rte_cryptodev *dev) 72 { 73 } 74 75 /** Close device */ 76 static int 77 null_crypto_pmd_close(__rte_unused struct rte_cryptodev *dev) 78 { 79 return 0; 80 } 81 82 /** Get device statistics */ 83 static void 84 null_crypto_pmd_stats_get(struct rte_cryptodev *dev, 85 struct rte_cryptodev_stats *stats) 86 { 87 int qp_id; 88 89 for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 90 struct null_crypto_qp *qp = dev->data->queue_pairs[qp_id]; 91 92 stats->enqueued_count += qp->qp_stats.enqueued_count; 93 stats->dequeued_count += qp->qp_stats.dequeued_count; 94 95 stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; 96 stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; 97 } 98 } 99 100 /** Reset device statistics */ 101 static void 102 null_crypto_pmd_stats_reset(struct rte_cryptodev *dev) 103 { 104 int qp_id; 105 106 for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 107 struct null_crypto_qp *qp = dev->data->queue_pairs[qp_id]; 108 109 memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 110 } 111 } 112 113 114 /** Get device info */ 115 static void 116 null_crypto_pmd_info_get(struct rte_cryptodev *dev, 117 struct rte_cryptodev_info *dev_info) 118 { 119 struct null_crypto_private *internals = dev->data->dev_private; 120 121 if (dev_info != NULL) { 122 dev_info->driver_id = dev->driver_id; 123 dev_info->max_nb_queue_pairs = internals->max_nb_qpairs; 124 /* No limit of number of sessions */ 125 dev_info->sym.max_nb_sessions = 0; 126 dev_info->feature_flags = dev->feature_flags; 127 dev_info->capabilities = null_crypto_pmd_capabilities; 128 } 129 } 130 131 /** Release queue pair */ 132 static int 133 null_crypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) 134 { 135 if (dev->data->queue_pairs[qp_id] != NULL) { 136 rte_free(dev->data->queue_pairs[qp_id]); 137 dev->data->queue_pairs[qp_id] = NULL; 138 } 139 return 0; 140 } 141 142 /** set a unique name for the queue pair based on it's name, dev_id and qp_id */ 143 static int 144 null_crypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev, 145 struct null_crypto_qp *qp) 146 { 147 unsigned n = snprintf(qp->name, sizeof(qp->name), 148 "null_crypto_pmd_%u_qp_%u", 149 dev->data->dev_id, qp->id); 150 151 if (n >= sizeof(qp->name)) 152 return -1; 153 154 return 0; 155 } 156 157 /** Create a ring to place process packets on */ 158 static struct rte_ring * 159 null_crypto_pmd_qp_create_processed_pkts_ring(struct null_crypto_qp *qp, 160 unsigned ring_size, int socket_id) 161 { 162 struct rte_ring *r; 163 164 r = rte_ring_lookup(qp->name); 165 if (r) { 166 if (rte_ring_get_size(r) >= ring_size) { 167 NULL_LOG(INFO, 168 "Reusing existing ring %s for " 169 " processed packets", qp->name); 170 return r; 171 } 172 173 NULL_LOG(INFO, 174 "Unable to reuse existing ring %s for " 175 " processed packets", qp->name); 176 return NULL; 177 } 178 179 return rte_ring_create(qp->name, ring_size, socket_id, 180 RING_F_SP_ENQ | RING_F_SC_DEQ); 181 } 182 183 /** Setup a queue pair */ 184 static int 185 null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, 186 const struct rte_cryptodev_qp_conf *qp_conf, 187 int socket_id, struct rte_mempool *session_pool) 188 { 189 struct null_crypto_private *internals = dev->data->dev_private; 190 struct null_crypto_qp *qp; 191 int retval; 192 193 if (qp_id >= internals->max_nb_qpairs) { 194 NULL_LOG(ERR, "Invalid qp_id %u, greater than maximum " 195 "number of queue pairs supported (%u).", 196 qp_id, internals->max_nb_qpairs); 197 return (-EINVAL); 198 } 199 200 /* Free memory prior to re-allocation if needed. */ 201 if (dev->data->queue_pairs[qp_id] != NULL) 202 null_crypto_pmd_qp_release(dev, qp_id); 203 204 /* Allocate the queue pair data structure. */ 205 qp = rte_zmalloc_socket("Null Crypto PMD Queue Pair", sizeof(*qp), 206 RTE_CACHE_LINE_SIZE, socket_id); 207 if (qp == NULL) { 208 NULL_LOG(ERR, "Failed to allocate queue pair memory"); 209 return (-ENOMEM); 210 } 211 212 qp->id = qp_id; 213 dev->data->queue_pairs[qp_id] = qp; 214 215 retval = null_crypto_pmd_qp_set_unique_name(dev, qp); 216 if (retval) { 217 NULL_LOG(ERR, "Failed to create unique name for null " 218 "crypto device"); 219 220 goto qp_setup_cleanup; 221 } 222 223 qp->processed_pkts = null_crypto_pmd_qp_create_processed_pkts_ring(qp, 224 qp_conf->nb_descriptors, socket_id); 225 if (qp->processed_pkts == NULL) { 226 NULL_LOG(ERR, "Failed to create unique name for null " 227 "crypto device"); 228 goto qp_setup_cleanup; 229 } 230 231 qp->sess_mp = session_pool; 232 233 memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 234 235 return 0; 236 237 qp_setup_cleanup: 238 if (qp) 239 rte_free(qp); 240 241 return -1; 242 } 243 244 /** Return the number of allocated queue pairs */ 245 static uint32_t 246 null_crypto_pmd_qp_count(struct rte_cryptodev *dev) 247 { 248 return dev->data->nb_queue_pairs; 249 } 250 251 /** Returns the size of the NULL crypto session structure */ 252 static unsigned 253 null_crypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused) 254 { 255 return sizeof(struct null_crypto_session); 256 } 257 258 /** Configure a null crypto session from a crypto xform chain */ 259 static int 260 null_crypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused, 261 struct rte_crypto_sym_xform *xform, 262 struct rte_cryptodev_sym_session *sess, 263 struct rte_mempool *mp) 264 { 265 void *sess_private_data; 266 int ret; 267 268 if (unlikely(sess == NULL)) { 269 NULL_LOG(ERR, "invalid session struct"); 270 return -EINVAL; 271 } 272 273 if (rte_mempool_get(mp, &sess_private_data)) { 274 NULL_LOG(ERR, 275 "Couldn't get object from session mempool"); 276 return -ENOMEM; 277 } 278 279 ret = null_crypto_set_session_parameters(sess_private_data, xform); 280 if (ret != 0) { 281 NULL_LOG(ERR, "failed configure session parameters"); 282 283 /* Return session to mempool */ 284 rte_mempool_put(mp, sess_private_data); 285 return ret; 286 } 287 288 set_session_private_data(sess, dev->driver_id, 289 sess_private_data); 290 291 return 0; 292 } 293 294 /** Clear the memory of session so it doesn't leave key material behind */ 295 static void 296 null_crypto_pmd_session_clear(struct rte_cryptodev *dev, 297 struct rte_cryptodev_sym_session *sess) 298 { 299 uint8_t index = dev->driver_id; 300 void *sess_priv = get_session_private_data(sess, index); 301 302 /* Zero out the whole structure */ 303 if (sess_priv) { 304 memset(sess_priv, 0, sizeof(struct null_crypto_session)); 305 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv); 306 set_session_private_data(sess, index, NULL); 307 rte_mempool_put(sess_mp, sess_priv); 308 } 309 } 310 311 struct rte_cryptodev_ops pmd_ops = { 312 .dev_configure = null_crypto_pmd_config, 313 .dev_start = null_crypto_pmd_start, 314 .dev_stop = null_crypto_pmd_stop, 315 .dev_close = null_crypto_pmd_close, 316 317 .stats_get = null_crypto_pmd_stats_get, 318 .stats_reset = null_crypto_pmd_stats_reset, 319 320 .dev_infos_get = null_crypto_pmd_info_get, 321 322 .queue_pair_setup = null_crypto_pmd_qp_setup, 323 .queue_pair_release = null_crypto_pmd_qp_release, 324 .queue_pair_count = null_crypto_pmd_qp_count, 325 326 .session_get_size = null_crypto_pmd_session_get_size, 327 .session_configure = null_crypto_pmd_session_configure, 328 .session_clear = null_crypto_pmd_session_clear 329 }; 330 331 struct rte_cryptodev_ops *null_crypto_pmd_ops = &pmd_ops; 332