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