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