1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016-2017 Intel Corporation 3 */ 4 5 #include <rte_common.h> 6 #include <rte_cryptodev_pmd.h> 7 #include <rte_bus_vdev.h> 8 #include <rte_malloc.h> 9 10 #include "null_crypto_pmd_private.h" 11 12 static uint8_t cryptodev_driver_id; 13 int null_logtype_driver; 14 15 /** verify and set session parameters */ 16 int 17 null_crypto_set_session_parameters( 18 struct null_crypto_session *sess __rte_unused, 19 const struct rte_crypto_sym_xform *xform) 20 { 21 if (xform == NULL) { 22 return -EINVAL; 23 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 24 xform->next == NULL) { 25 /* Authentication Only */ 26 if (xform->auth.algo == RTE_CRYPTO_AUTH_NULL) 27 return 0; 28 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 29 xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 30 /* Authentication then Cipher */ 31 if (xform->auth.algo == RTE_CRYPTO_AUTH_NULL && 32 xform->next->cipher.algo == RTE_CRYPTO_CIPHER_NULL) 33 return 0; 34 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 35 xform->next == NULL) { 36 /* Cipher Only */ 37 if (xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL) 38 return 0; 39 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 40 xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 41 /* Cipher then Authentication */ 42 if (xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL && 43 xform->next->auth.algo == RTE_CRYPTO_AUTH_NULL) 44 return 0; 45 } 46 47 return -ENOTSUP; 48 } 49 50 /** Process crypto operation for mbuf */ 51 static int 52 process_op(const struct null_crypto_qp *qp, struct rte_crypto_op *op, 53 struct null_crypto_session *sess __rte_unused) 54 { 55 /* set status as successful by default */ 56 op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 57 58 /* Free session if a session-less crypto op. */ 59 if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { 60 memset(op->sym->session, 0, 61 sizeof(struct null_crypto_session)); 62 rte_cryptodev_sym_session_free(op->sym->session); 63 op->sym->session = NULL; 64 } 65 66 /* 67 * if crypto session and operation are valid just enqueue the packet 68 * in the processed ring 69 */ 70 return rte_ring_enqueue(qp->processed_pkts, (void *)op); 71 } 72 73 static struct null_crypto_session * 74 get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op) 75 { 76 struct null_crypto_session *sess = NULL; 77 struct rte_crypto_sym_op *sym_op = op->sym; 78 79 if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 80 if (likely(sym_op->session != NULL)) 81 sess = (struct null_crypto_session *) 82 get_sym_session_private_data( 83 sym_op->session, cryptodev_driver_id); 84 } else { 85 void *_sess = NULL; 86 void *_sess_private_data = NULL; 87 88 if (rte_mempool_get(qp->sess_mp, (void **)&_sess)) 89 return NULL; 90 91 if (rte_mempool_get(qp->sess_mp_priv, 92 (void **)&_sess_private_data)) 93 return NULL; 94 95 sess = (struct null_crypto_session *)_sess_private_data; 96 97 if (unlikely(null_crypto_set_session_parameters(sess, 98 sym_op->xform) != 0)) { 99 rte_mempool_put(qp->sess_mp, _sess); 100 rte_mempool_put(qp->sess_mp_priv, _sess_private_data); 101 sess = NULL; 102 } 103 sym_op->session = (struct rte_cryptodev_sym_session *)_sess; 104 set_sym_session_private_data(op->sym->session, 105 cryptodev_driver_id, _sess_private_data); 106 } 107 108 return sess; 109 } 110 111 /** Enqueue burst */ 112 static uint16_t 113 null_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, 114 uint16_t nb_ops) 115 { 116 struct null_crypto_session *sess; 117 struct null_crypto_qp *qp = queue_pair; 118 119 int i, retval; 120 121 for (i = 0; i < nb_ops; i++) { 122 sess = get_session(qp, ops[i]); 123 if (unlikely(sess == NULL)) 124 goto enqueue_err; 125 126 retval = process_op(qp, ops[i], sess); 127 if (unlikely(retval < 0)) 128 goto enqueue_err; 129 } 130 131 qp->qp_stats.enqueued_count += i; 132 return i; 133 134 enqueue_err: 135 if (ops[i]) 136 ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 137 138 qp->qp_stats.enqueue_err_count++; 139 return i; 140 } 141 142 /** Dequeue burst */ 143 static uint16_t 144 null_crypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, 145 uint16_t nb_ops) 146 { 147 struct null_crypto_qp *qp = queue_pair; 148 149 unsigned nb_dequeued; 150 151 nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts, 152 (void **)ops, nb_ops, NULL); 153 qp->qp_stats.dequeued_count += nb_dequeued; 154 155 return nb_dequeued; 156 } 157 158 /** Create crypto device */ 159 static int 160 cryptodev_null_create(const char *name, 161 struct rte_vdev_device *vdev, 162 struct rte_cryptodev_pmd_init_params *init_params) 163 { 164 struct rte_cryptodev *dev; 165 struct null_crypto_private *internals; 166 dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params); 167 if (dev == NULL) { 168 NULL_LOG(ERR, "failed to create cryptodev vdev"); 169 return -EFAULT; 170 } 171 172 dev->driver_id = cryptodev_driver_id; 173 dev->dev_ops = null_crypto_pmd_ops; 174 175 /* register rx/tx burst functions for data path */ 176 dev->dequeue_burst = null_crypto_pmd_dequeue_burst; 177 dev->enqueue_burst = null_crypto_pmd_enqueue_burst; 178 179 dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | 180 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | 181 RTE_CRYPTODEV_FF_IN_PLACE_SGL | 182 RTE_CRYPTODEV_FF_SYM_SESSIONLESS; 183 184 internals = dev->data->dev_private; 185 186 internals->max_nb_qpairs = init_params->max_nb_queue_pairs; 187 188 return 0; 189 } 190 191 /** Initialise null crypto device */ 192 static int 193 cryptodev_null_probe(struct rte_vdev_device *dev) 194 { 195 struct rte_cryptodev_pmd_init_params init_params = { 196 "", 197 sizeof(struct null_crypto_private), 198 rte_socket_id(), 199 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS 200 }; 201 const char *name, *args; 202 int retval; 203 204 name = rte_vdev_device_name(dev); 205 if (name == NULL) 206 return -EINVAL; 207 208 args = rte_vdev_device_args(dev); 209 210 retval = rte_cryptodev_pmd_parse_input_args(&init_params, args); 211 if (retval) { 212 NULL_LOG(ERR, 213 "Failed to parse initialisation arguments[%s]", 214 args); 215 return -EINVAL; 216 } 217 218 return cryptodev_null_create(name, dev, &init_params); 219 } 220 221 static int 222 cryptodev_null_remove_dev(struct rte_vdev_device *vdev) 223 { 224 struct rte_cryptodev *cryptodev; 225 const char *name; 226 227 name = rte_vdev_device_name(vdev); 228 if (name == NULL) 229 return -EINVAL; 230 231 cryptodev = rte_cryptodev_pmd_get_named_dev(name); 232 if (cryptodev == NULL) 233 return -ENODEV; 234 235 return rte_cryptodev_pmd_destroy(cryptodev); 236 } 237 238 static struct rte_vdev_driver cryptodev_null_pmd_drv = { 239 .probe = cryptodev_null_probe, 240 .remove = cryptodev_null_remove_dev, 241 }; 242 243 static struct cryptodev_driver null_crypto_drv; 244 245 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd_drv); 246 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd); 247 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_NULL_PMD, 248 "max_nb_queue_pairs=<int> " 249 "socket_id=<int>"); 250 RTE_PMD_REGISTER_CRYPTO_DRIVER(null_crypto_drv, cryptodev_null_pmd_drv.driver, 251 cryptodev_driver_id); 252 253 RTE_INIT(null_init_log) 254 { 255 null_logtype_driver = rte_log_register("pmd.crypto.null"); 256 } 257