1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2016-2017 Intel Corporation. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Intel Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <rte_common.h> 34 #include <rte_config.h> 35 #include <rte_cryptodev_pmd.h> 36 #include <rte_vdev.h> 37 #include <rte_malloc.h> 38 39 #include "null_crypto_pmd_private.h" 40 41 static uint8_t cryptodev_driver_id; 42 43 /** verify and set session parameters */ 44 int 45 null_crypto_set_session_parameters( 46 struct null_crypto_session *sess __rte_unused, 47 const struct rte_crypto_sym_xform *xform) 48 { 49 if (xform == NULL) { 50 return -EINVAL; 51 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 52 xform->next == NULL) { 53 /* Authentication Only */ 54 if (xform->auth.algo == RTE_CRYPTO_AUTH_NULL) 55 return 0; 56 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 57 xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 58 /* Authentication then Cipher */ 59 if (xform->auth.algo == RTE_CRYPTO_AUTH_NULL && 60 xform->next->cipher.algo == RTE_CRYPTO_CIPHER_NULL) 61 return 0; 62 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 63 xform->next == NULL) { 64 /* Cipher Only */ 65 if (xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL) 66 return 0; 67 } else if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 68 xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 69 /* Cipher then Authentication */ 70 if (xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL && 71 xform->next->auth.algo == RTE_CRYPTO_AUTH_NULL) 72 return 0; 73 } 74 75 return -ENOTSUP; 76 } 77 78 /** Process crypto operation for mbuf */ 79 static int 80 process_op(const struct null_crypto_qp *qp, struct rte_crypto_op *op, 81 struct null_crypto_session *sess __rte_unused) 82 { 83 /* set status as successful by default */ 84 op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 85 86 /* Free session if a session-less crypto op. */ 87 if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { 88 memset(op->sym->session, 0, 89 sizeof(struct null_crypto_session)); 90 rte_cryptodev_sym_session_free(op->sym->session); 91 op->sym->session = NULL; 92 } 93 94 /* 95 * if crypto session and operation are valid just enqueue the packet 96 * in the processed ring 97 */ 98 return rte_ring_enqueue(qp->processed_pkts, (void *)op); 99 } 100 101 static struct null_crypto_session * 102 get_session(struct null_crypto_qp *qp, struct rte_crypto_op *op) 103 { 104 struct null_crypto_session *sess = NULL; 105 struct rte_crypto_sym_op *sym_op = op->sym; 106 107 if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { 108 if (likely(sym_op->session != NULL)) 109 sess = (struct null_crypto_session *) 110 get_session_private_data( 111 sym_op->session, cryptodev_driver_id); 112 } else { 113 void *_sess = NULL; 114 void *_sess_private_data = NULL; 115 116 if (rte_mempool_get(qp->sess_mp, (void **)&_sess)) 117 return NULL; 118 119 if (rte_mempool_get(qp->sess_mp, (void **)&_sess_private_data)) 120 return NULL; 121 122 sess = (struct null_crypto_session *)_sess_private_data; 123 124 if (unlikely(null_crypto_set_session_parameters(sess, 125 sym_op->xform) != 0)) { 126 rte_mempool_put(qp->sess_mp, _sess); 127 rte_mempool_put(qp->sess_mp, _sess_private_data); 128 sess = NULL; 129 } 130 sym_op->session = (struct rte_cryptodev_sym_session *)_sess; 131 set_session_private_data(sym_op->session, cryptodev_driver_id, 132 _sess_private_data); 133 } 134 135 return sess; 136 } 137 138 /** Enqueue burst */ 139 static uint16_t 140 null_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops, 141 uint16_t nb_ops) 142 { 143 struct null_crypto_session *sess; 144 struct null_crypto_qp *qp = queue_pair; 145 146 int i, retval; 147 148 for (i = 0; i < nb_ops; i++) { 149 sess = get_session(qp, ops[i]); 150 if (unlikely(sess == NULL)) 151 goto enqueue_err; 152 153 retval = process_op(qp, ops[i], sess); 154 if (unlikely(retval < 0)) 155 goto enqueue_err; 156 } 157 158 qp->qp_stats.enqueued_count += i; 159 return i; 160 161 enqueue_err: 162 if (ops[i]) 163 ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS; 164 165 qp->qp_stats.enqueue_err_count++; 166 return i; 167 } 168 169 /** Dequeue burst */ 170 static uint16_t 171 null_crypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops, 172 uint16_t nb_ops) 173 { 174 struct null_crypto_qp *qp = queue_pair; 175 176 unsigned nb_dequeued; 177 178 nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts, 179 (void **)ops, nb_ops, NULL); 180 qp->qp_stats.dequeued_count += nb_dequeued; 181 182 return nb_dequeued; 183 } 184 185 /** Create crypto device */ 186 static int 187 cryptodev_null_create(const char *name, 188 struct rte_vdev_device *vdev, 189 struct rte_cryptodev_pmd_init_params *init_params) 190 { 191 struct rte_cryptodev *dev; 192 struct null_crypto_private *internals; 193 194 dev = rte_cryptodev_pmd_create(name, &vdev->device, init_params); 195 if (dev == NULL) { 196 NULL_CRYPTO_LOG_ERR("failed to create cryptodev vdev"); 197 return -EFAULT; 198 } 199 200 dev->driver_id = cryptodev_driver_id; 201 dev->dev_ops = null_crypto_pmd_ops; 202 203 /* register rx/tx burst functions for data path */ 204 dev->dequeue_burst = null_crypto_pmd_dequeue_burst; 205 dev->enqueue_burst = null_crypto_pmd_enqueue_burst; 206 207 dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | 208 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | 209 RTE_CRYPTODEV_FF_MBUF_SCATTER_GATHER; 210 211 internals = dev->data->dev_private; 212 213 internals->max_nb_qpairs = init_params->max_nb_queue_pairs; 214 internals->max_nb_sessions = init_params->max_nb_sessions; 215 216 return 0; 217 } 218 219 /** Initialise null crypto device */ 220 static int 221 cryptodev_null_probe(struct rte_vdev_device *dev) 222 { 223 struct rte_cryptodev_pmd_init_params init_params = { 224 "", 225 sizeof(struct null_crypto_private), 226 rte_socket_id(), 227 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS, 228 RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS 229 }; 230 const char *name, *args; 231 int retval; 232 233 name = rte_vdev_device_name(dev); 234 if (name == NULL) 235 return -EINVAL; 236 237 args = rte_vdev_device_args(dev); 238 239 retval = rte_cryptodev_pmd_parse_input_args(&init_params, args); 240 if (retval) { 241 RTE_LOG(ERR, PMD, 242 "Failed to parse initialisation arguments[%s]\n", args); 243 return -EINVAL; 244 } 245 246 return cryptodev_null_create(name, dev, &init_params); 247 } 248 249 static int 250 cryptodev_null_remove_dev(struct rte_vdev_device *vdev) 251 { 252 struct rte_cryptodev *cryptodev; 253 const char *name; 254 255 name = rte_vdev_device_name(vdev); 256 if (name == NULL) 257 return -EINVAL; 258 259 cryptodev = rte_cryptodev_pmd_get_named_dev(name); 260 if (cryptodev == NULL) 261 return -ENODEV; 262 263 return rte_cryptodev_pmd_destroy(cryptodev); 264 } 265 266 static struct rte_vdev_driver cryptodev_null_pmd_drv = { 267 .probe = cryptodev_null_probe, 268 .remove = cryptodev_null_remove_dev, 269 }; 270 271 static struct cryptodev_driver null_crypto_drv; 272 273 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd_drv); 274 RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_NULL_PMD, cryptodev_null_pmd); 275 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_NULL_PMD, 276 "max_nb_queue_pairs=<int> " 277 "max_nb_sessions=<int> " 278 "socket_id=<int>"); 279 RTE_PMD_REGISTER_CRYPTO_DRIVER(null_crypto_drv, cryptodev_null_pmd_drv, 280 cryptodev_driver_id); 281