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 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 182 internals = dev->data->dev_private; 183 184 internals->max_nb_qpairs = init_params->max_nb_queue_pairs; 185 186 return 0; 187 } 188 189 /** Initialise null crypto device */ 190 static int 191 cryptodev_null_probe(struct rte_vdev_device *dev) 192 { 193 struct rte_cryptodev_pmd_init_params init_params = { 194 "", 195 sizeof(struct null_crypto_private), 196 rte_socket_id(), 197 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS 198 }; 199 const char *name, *args; 200 int retval; 201 202 name = rte_vdev_device_name(dev); 203 if (name == NULL) 204 return -EINVAL; 205 206 args = rte_vdev_device_args(dev); 207 208 retval = rte_cryptodev_pmd_parse_input_args(&init_params, args); 209 if (retval) { 210 NULL_LOG(ERR, 211 "Failed to parse initialisation arguments[%s]", 212 args); 213 return -EINVAL; 214 } 215 216 return cryptodev_null_create(name, dev, &init_params); 217 } 218 219 static int 220 cryptodev_null_remove_dev(struct rte_vdev_device *vdev) 221 { 222 struct rte_cryptodev *cryptodev; 223 const char *name; 224 225 name = rte_vdev_device_name(vdev); 226 if (name == NULL) 227 return -EINVAL; 228 229 cryptodev = rte_cryptodev_pmd_get_named_dev(name); 230 if (cryptodev == NULL) 231 return -ENODEV; 232 233 return rte_cryptodev_pmd_destroy(cryptodev); 234 } 235 236 static struct rte_vdev_driver cryptodev_null_pmd_drv = { 237 .probe = cryptodev_null_probe, 238 .remove = cryptodev_null_remove_dev, 239 }; 240 241 static struct cryptodev_driver null_crypto_drv; 242 243 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd_drv); 244 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd); 245 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_NULL_PMD, 246 "max_nb_queue_pairs=<int> " 247 "socket_id=<int>"); 248 RTE_PMD_REGISTER_CRYPTO_DRIVER(null_crypto_drv, cryptodev_null_pmd_drv.driver, 249 cryptodev_driver_id); 250 251 RTE_INIT(null_init_log) 252 { 253 null_logtype_driver = rte_log_register("pmd.crypto.null"); 254 } 255