xref: /dpdk/lib/cryptodev/cryptodev_pmd.c (revision 23d6f76d31474eeaafed752e377c109f803c287b)
1af668035SAkhil Goyal /* SPDX-License-Identifier: BSD-3-Clause
2af668035SAkhil Goyal  * Copyright(c) 2017 Intel Corporation
3af668035SAkhil Goyal  */
4af668035SAkhil Goyal 
572b452c5SDmitry Kozlyuk #include <stdlib.h>
6cb7b6898STal Shnaiderman #include <sys/queue.h>
7770ebc06SDavid Marchand 
81acb7f54SDavid Marchand #include <dev_driver.h>
92fd66f75SAkhil Goyal #include <rte_errno.h>
10af668035SAkhil Goyal #include <rte_string_fns.h>
11af668035SAkhil Goyal #include <rte_malloc.h>
12af668035SAkhil Goyal 
13af668035SAkhil Goyal #include "cryptodev_pmd.h"
14af668035SAkhil Goyal 
15af668035SAkhil Goyal /**
16af668035SAkhil Goyal  * Parse name from argument
17af668035SAkhil Goyal  */
18af668035SAkhil Goyal static int
rte_cryptodev_pmd_parse_name_arg(const char * key __rte_unused,const char * value,void * extra_args)19af668035SAkhil Goyal rte_cryptodev_pmd_parse_name_arg(const char *key __rte_unused,
20af668035SAkhil Goyal 		const char *value, void *extra_args)
21af668035SAkhil Goyal {
22af668035SAkhil Goyal 	struct rte_cryptodev_pmd_init_params *params = extra_args;
23af668035SAkhil Goyal 	int n;
24af668035SAkhil Goyal 
258146454cSChengwen Feng 	if (value == NULL || extra_args == NULL)
268146454cSChengwen Feng 		return -EINVAL;
278146454cSChengwen Feng 
28af668035SAkhil Goyal 	n = strlcpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
29af668035SAkhil Goyal 	if (n >= RTE_CRYPTODEV_NAME_MAX_LEN)
30af668035SAkhil Goyal 		return -EINVAL;
31af668035SAkhil Goyal 
32af668035SAkhil Goyal 	return 0;
33af668035SAkhil Goyal }
34af668035SAkhil Goyal 
35af668035SAkhil Goyal /**
36af668035SAkhil Goyal  * Parse unsigned integer from argument
37af668035SAkhil Goyal  */
38af668035SAkhil Goyal static int
rte_cryptodev_pmd_parse_uint_arg(const char * key __rte_unused,const char * value,void * extra_args)39af668035SAkhil Goyal rte_cryptodev_pmd_parse_uint_arg(const char *key __rte_unused,
40af668035SAkhil Goyal 		const char *value, void *extra_args)
41af668035SAkhil Goyal {
42af668035SAkhil Goyal 	int i;
43af668035SAkhil Goyal 	char *end;
448146454cSChengwen Feng 
458146454cSChengwen Feng 	if (value == NULL || extra_args == NULL)
468146454cSChengwen Feng 		return -EINVAL;
478146454cSChengwen Feng 
48af668035SAkhil Goyal 	errno = 0;
49af668035SAkhil Goyal 
50af668035SAkhil Goyal 	i = strtol(value, &end, 10);
51af668035SAkhil Goyal 	if (*end != 0 || errno != 0 || i < 0)
52af668035SAkhil Goyal 		return -EINVAL;
53af668035SAkhil Goyal 
54af668035SAkhil Goyal 	*((uint32_t *)extra_args) = i;
55af668035SAkhil Goyal 	return 0;
56af668035SAkhil Goyal }
57af668035SAkhil Goyal 
58af668035SAkhil Goyal int
rte_cryptodev_pmd_parse_input_args(struct rte_cryptodev_pmd_init_params * params,const char * args)59af668035SAkhil Goyal rte_cryptodev_pmd_parse_input_args(
60af668035SAkhil Goyal 		struct rte_cryptodev_pmd_init_params *params,
61af668035SAkhil Goyal 		const char *args)
62af668035SAkhil Goyal {
63af668035SAkhil Goyal 	struct rte_kvargs *kvlist = NULL;
64af668035SAkhil Goyal 	int ret = 0;
65af668035SAkhil Goyal 
66af668035SAkhil Goyal 	if (params == NULL)
67af668035SAkhil Goyal 		return -EINVAL;
68af668035SAkhil Goyal 
69af668035SAkhil Goyal 	if (args) {
70af668035SAkhil Goyal 		kvlist = rte_kvargs_parse(args,	cryptodev_pmd_valid_params);
71af668035SAkhil Goyal 		if (kvlist == NULL)
72af668035SAkhil Goyal 			return -EINVAL;
73af668035SAkhil Goyal 
74af668035SAkhil Goyal 		ret = rte_kvargs_process(kvlist,
75af668035SAkhil Goyal 				RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG,
76af668035SAkhil Goyal 				&rte_cryptodev_pmd_parse_uint_arg,
77af668035SAkhil Goyal 				&params->max_nb_queue_pairs);
78af668035SAkhil Goyal 		if (ret < 0)
79af668035SAkhil Goyal 			goto free_kvlist;
80af668035SAkhil Goyal 
81af668035SAkhil Goyal 		ret = rte_kvargs_process(kvlist,
82af668035SAkhil Goyal 				RTE_CRYPTODEV_PMD_SOCKET_ID_ARG,
83af668035SAkhil Goyal 				&rte_cryptodev_pmd_parse_uint_arg,
84af668035SAkhil Goyal 				&params->socket_id);
85af668035SAkhil Goyal 		if (ret < 0)
86af668035SAkhil Goyal 			goto free_kvlist;
87af668035SAkhil Goyal 
88af668035SAkhil Goyal 		ret = rte_kvargs_process(kvlist,
89af668035SAkhil Goyal 				RTE_CRYPTODEV_PMD_NAME_ARG,
90af668035SAkhil Goyal 				&rte_cryptodev_pmd_parse_name_arg,
91af668035SAkhil Goyal 				params);
92af668035SAkhil Goyal 		if (ret < 0)
93af668035SAkhil Goyal 			goto free_kvlist;
94af668035SAkhil Goyal 	}
95af668035SAkhil Goyal 
96af668035SAkhil Goyal free_kvlist:
97af668035SAkhil Goyal 	rte_kvargs_free(kvlist);
98af668035SAkhil Goyal 	return ret;
99af668035SAkhil Goyal }
100af668035SAkhil Goyal 
101af668035SAkhil Goyal struct rte_cryptodev *
rte_cryptodev_pmd_create(const char * name,struct rte_device * device,struct rte_cryptodev_pmd_init_params * params)102af668035SAkhil Goyal rte_cryptodev_pmd_create(const char *name,
103af668035SAkhil Goyal 		struct rte_device *device,
104af668035SAkhil Goyal 		struct rte_cryptodev_pmd_init_params *params)
105af668035SAkhil Goyal {
106af668035SAkhil Goyal 	struct rte_cryptodev *cryptodev;
107af668035SAkhil Goyal 
108af668035SAkhil Goyal 	if (params->name[0] != '\0') {
109a0a17e2aSOlivier Matz 		CDEV_LOG_INFO("User specified device name = %s", params->name);
110af668035SAkhil Goyal 		name = params->name;
111af668035SAkhil Goyal 	}
112af668035SAkhil Goyal 
113a0a17e2aSOlivier Matz 	CDEV_LOG_INFO("Creating cryptodev %s", name);
114af668035SAkhil Goyal 
115af668035SAkhil Goyal 	CDEV_LOG_INFO("Initialisation parameters - name: %s,"
116af668035SAkhil Goyal 			"socket id: %d, max queue pairs: %u",
117af668035SAkhil Goyal 			name, params->socket_id, params->max_nb_queue_pairs);
118af668035SAkhil Goyal 
119af668035SAkhil Goyal 	/* allocate device structure */
120af668035SAkhil Goyal 	cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id);
121af668035SAkhil Goyal 	if (cryptodev == NULL) {
122af668035SAkhil Goyal 		CDEV_LOG_ERR("Failed to allocate crypto device for %s", name);
123af668035SAkhil Goyal 		return NULL;
124af668035SAkhil Goyal 	}
125af668035SAkhil Goyal 
126af668035SAkhil Goyal 	/* allocate private device structure */
127af668035SAkhil Goyal 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
128af668035SAkhil Goyal 		cryptodev->data->dev_private =
129af668035SAkhil Goyal 				rte_zmalloc_socket("cryptodev device private",
130af668035SAkhil Goyal 						params->private_data_size,
131af668035SAkhil Goyal 						RTE_CACHE_LINE_SIZE,
132af668035SAkhil Goyal 						params->socket_id);
133af668035SAkhil Goyal 
134af668035SAkhil Goyal 		if (cryptodev->data->dev_private == NULL) {
135af668035SAkhil Goyal 			CDEV_LOG_ERR("Cannot allocate memory for cryptodev %s"
136af668035SAkhil Goyal 					" private data", name);
137af668035SAkhil Goyal 
138af668035SAkhil Goyal 			rte_cryptodev_pmd_release_device(cryptodev);
139af668035SAkhil Goyal 			return NULL;
140af668035SAkhil Goyal 		}
141af668035SAkhil Goyal 	}
142af668035SAkhil Goyal 
143af668035SAkhil Goyal 	cryptodev->device = device;
144af668035SAkhil Goyal 
145af668035SAkhil Goyal 	/* initialise user call-back tail queue */
146af668035SAkhil Goyal 	TAILQ_INIT(&(cryptodev->link_intr_cbs));
147af668035SAkhil Goyal 
148af668035SAkhil Goyal 	return cryptodev;
149af668035SAkhil Goyal }
150af668035SAkhil Goyal 
151af668035SAkhil Goyal int
rte_cryptodev_pmd_destroy(struct rte_cryptodev * cryptodev)152af668035SAkhil Goyal rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev)
153af668035SAkhil Goyal {
154af668035SAkhil Goyal 	int retval;
155af668035SAkhil Goyal 	void *dev_priv = cryptodev->data->dev_private;
156af668035SAkhil Goyal 
157af668035SAkhil Goyal 	CDEV_LOG_INFO("Closing crypto device %s", cryptodev->device->name);
158af668035SAkhil Goyal 
159af668035SAkhil Goyal 	/* free crypto device */
160af668035SAkhil Goyal 	retval = rte_cryptodev_pmd_release_device(cryptodev);
161af668035SAkhil Goyal 	if (retval)
162af668035SAkhil Goyal 		return retval;
163af668035SAkhil Goyal 
164af668035SAkhil Goyal 	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
165af668035SAkhil Goyal 		rte_free(dev_priv);
166af668035SAkhil Goyal 
167af668035SAkhil Goyal 
168af668035SAkhil Goyal 	cryptodev->device = NULL;
169af668035SAkhil Goyal 	cryptodev->data = NULL;
170af668035SAkhil Goyal 
171af668035SAkhil Goyal 	return 0;
172af668035SAkhil Goyal }
1732fd66f75SAkhil Goyal 
17433cd3fd5SAkhil Goyal void
rte_cryptodev_pmd_probing_finish(struct rte_cryptodev * cryptodev)17533cd3fd5SAkhil Goyal rte_cryptodev_pmd_probing_finish(struct rte_cryptodev *cryptodev)
17633cd3fd5SAkhil Goyal {
17733cd3fd5SAkhil Goyal 	if (cryptodev == NULL)
17833cd3fd5SAkhil Goyal 		return;
17933cd3fd5SAkhil Goyal 	/*
18033cd3fd5SAkhil Goyal 	 * for secondary process, at that point we expect device
18133cd3fd5SAkhil Goyal 	 * to be already 'usable', so shared data and all function
18233cd3fd5SAkhil Goyal 	 * pointers for fast-path devops have to be setup properly
18333cd3fd5SAkhil Goyal 	 * inside rte_cryptodev.
18433cd3fd5SAkhil Goyal 	 */
18533cd3fd5SAkhil Goyal 	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
18633cd3fd5SAkhil Goyal 		cryptodev_fp_ops_set(rte_crypto_fp_ops +
18733cd3fd5SAkhil Goyal 				cryptodev->data->dev_id, cryptodev);
18833cd3fd5SAkhil Goyal }
18933cd3fd5SAkhil Goyal 
1902fd66f75SAkhil Goyal static uint16_t
dummy_crypto_enqueue_burst(__rte_unused void * qp,__rte_unused struct rte_crypto_op ** ops,__rte_unused uint16_t nb_ops)1912fd66f75SAkhil Goyal dummy_crypto_enqueue_burst(__rte_unused void *qp,
1922fd66f75SAkhil Goyal 			   __rte_unused struct rte_crypto_op **ops,
1932fd66f75SAkhil Goyal 			   __rte_unused uint16_t nb_ops)
1942fd66f75SAkhil Goyal {
1952fd66f75SAkhil Goyal 	CDEV_LOG_ERR(
1962fd66f75SAkhil Goyal 		"crypto enqueue burst requested for unconfigured device");
1972fd66f75SAkhil Goyal 	rte_errno = ENOTSUP;
1982fd66f75SAkhil Goyal 	return 0;
1992fd66f75SAkhil Goyal }
2002fd66f75SAkhil Goyal 
2012fd66f75SAkhil Goyal static uint16_t
dummy_crypto_dequeue_burst(__rte_unused void * qp,__rte_unused struct rte_crypto_op ** ops,__rte_unused uint16_t nb_ops)2022fd66f75SAkhil Goyal dummy_crypto_dequeue_burst(__rte_unused void *qp,
2032fd66f75SAkhil Goyal 			   __rte_unused struct rte_crypto_op **ops,
2042fd66f75SAkhil Goyal 			   __rte_unused uint16_t nb_ops)
2052fd66f75SAkhil Goyal {
2062fd66f75SAkhil Goyal 	CDEV_LOG_ERR(
2072fd66f75SAkhil Goyal 		"crypto dequeue burst requested for unconfigured device");
2082fd66f75SAkhil Goyal 	rte_errno = ENOTSUP;
2092fd66f75SAkhil Goyal 	return 0;
2102fd66f75SAkhil Goyal }
2112fd66f75SAkhil Goyal 
2122fd66f75SAkhil Goyal void
cryptodev_fp_ops_reset(struct rte_crypto_fp_ops * fp_ops)2132fd66f75SAkhil Goyal cryptodev_fp_ops_reset(struct rte_crypto_fp_ops *fp_ops)
2142fd66f75SAkhil Goyal {
2152fd66f75SAkhil Goyal 	static struct rte_cryptodev_cb_rcu dummy_cb[RTE_MAX_QUEUES_PER_PORT];
2162fd66f75SAkhil Goyal 	static void *dummy_data[RTE_MAX_QUEUES_PER_PORT];
2172fd66f75SAkhil Goyal 	static const struct rte_crypto_fp_ops dummy = {
2182fd66f75SAkhil Goyal 		.enqueue_burst = dummy_crypto_enqueue_burst,
2192fd66f75SAkhil Goyal 		.dequeue_burst = dummy_crypto_dequeue_burst,
2202fd66f75SAkhil Goyal 		.qp = {
2212fd66f75SAkhil Goyal 			.data = dummy_data,
2222fd66f75SAkhil Goyal 			.enq_cb = dummy_cb,
2232fd66f75SAkhil Goyal 			.deq_cb = dummy_cb,
2242fd66f75SAkhil Goyal 		},
2252fd66f75SAkhil Goyal 	};
2262fd66f75SAkhil Goyal 
2272fd66f75SAkhil Goyal 	*fp_ops = dummy;
2282fd66f75SAkhil Goyal }
2292fd66f75SAkhil Goyal 
2302fd66f75SAkhil Goyal void
cryptodev_fp_ops_set(struct rte_crypto_fp_ops * fp_ops,const struct rte_cryptodev * dev)2312fd66f75SAkhil Goyal cryptodev_fp_ops_set(struct rte_crypto_fp_ops *fp_ops,
2322fd66f75SAkhil Goyal 		     const struct rte_cryptodev *dev)
2332fd66f75SAkhil Goyal {
2342fd66f75SAkhil Goyal 	fp_ops->enqueue_burst = dev->enqueue_burst;
2352fd66f75SAkhil Goyal 	fp_ops->dequeue_burst = dev->dequeue_burst;
2362fd66f75SAkhil Goyal 	fp_ops->qp.data = dev->data->queue_pairs;
2372fd66f75SAkhil Goyal 	fp_ops->qp.enq_cb = dev->enq_cbs;
2382fd66f75SAkhil Goyal 	fp_ops->qp.deq_cb = dev->deq_cbs;
239*23d6f76dSAkhil Goyal 	fp_ops->qp_depth_used = dev->qp_depth_used;
2402fd66f75SAkhil Goyal }
241a7ddfa9cSVolodymyr Fialko 
242a7ddfa9cSVolodymyr Fialko void *
rte_cryptodev_session_event_mdata_get(struct rte_crypto_op * op)243a7ddfa9cSVolodymyr Fialko rte_cryptodev_session_event_mdata_get(struct rte_crypto_op *op)
244a7ddfa9cSVolodymyr Fialko {
245a7ddfa9cSVolodymyr Fialko 	if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
246a7ddfa9cSVolodymyr Fialko 			op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
247a7ddfa9cSVolodymyr Fialko 		return rte_cryptodev_sym_session_get_user_data(op->sym->session);
248a7ddfa9cSVolodymyr Fialko 	else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC &&
249a7ddfa9cSVolodymyr Fialko 			op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
250a7ddfa9cSVolodymyr Fialko 		return op->asym->session->event_mdata;
251a7ddfa9cSVolodymyr Fialko 	else if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS &&
252a7ddfa9cSVolodymyr Fialko 			op->private_data_offset)
253a7ddfa9cSVolodymyr Fialko 		return ((uint8_t *)op + op->private_data_offset);
254a7ddfa9cSVolodymyr Fialko 	else
255a7ddfa9cSVolodymyr Fialko 		return NULL;
256a7ddfa9cSVolodymyr Fialko }
257