1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2018 Intel Corporation
3d30ea906Sjfb8856606  */
4d30ea906Sjfb8856606 
5d30ea906Sjfb8856606 #include <stdlib.h>
6d30ea906Sjfb8856606 #include <stdio.h>
7d30ea906Sjfb8856606 
8d30ea906Sjfb8856606 #include <rte_cryptodev.h>
9d30ea906Sjfb8856606 #include <rte_cryptodev_pmd.h>
10d30ea906Sjfb8856606 #include <rte_string_fns.h>
11d30ea906Sjfb8856606 
12d30ea906Sjfb8856606 #include "cryptodev.h"
13d30ea906Sjfb8856606 
14*4418919fSjohnjiang #define PIPELINE_CRYPTO_SESSION_CACHE_SIZE	128
15*4418919fSjohnjiang 
16d30ea906Sjfb8856606 static struct cryptodev_list cryptodev_list;
17d30ea906Sjfb8856606 
18d30ea906Sjfb8856606 int
cryptodev_init(void)19d30ea906Sjfb8856606 cryptodev_init(void)
20d30ea906Sjfb8856606 {
21d30ea906Sjfb8856606 	TAILQ_INIT(&cryptodev_list);
22d30ea906Sjfb8856606 
23d30ea906Sjfb8856606 	return 0;
24d30ea906Sjfb8856606 }
25d30ea906Sjfb8856606 
26d30ea906Sjfb8856606 struct cryptodev *
cryptodev_find(const char * name)27d30ea906Sjfb8856606 cryptodev_find(const char *name)
28d30ea906Sjfb8856606 {
29d30ea906Sjfb8856606 	struct cryptodev *cryptodev;
30d30ea906Sjfb8856606 
31d30ea906Sjfb8856606 	if (name == NULL)
32d30ea906Sjfb8856606 		return NULL;
33d30ea906Sjfb8856606 
34d30ea906Sjfb8856606 	TAILQ_FOREACH(cryptodev, &cryptodev_list, node)
35d30ea906Sjfb8856606 		if (strcmp(cryptodev->name, name) == 0)
36d30ea906Sjfb8856606 			return cryptodev;
37d30ea906Sjfb8856606 
38d30ea906Sjfb8856606 	return NULL;
39d30ea906Sjfb8856606 }
40d30ea906Sjfb8856606 
41d30ea906Sjfb8856606 struct cryptodev *
cryptodev_next(struct cryptodev * cryptodev)42d30ea906Sjfb8856606 cryptodev_next(struct cryptodev *cryptodev)
43d30ea906Sjfb8856606 {
44d30ea906Sjfb8856606 	return (cryptodev == NULL) ?
45d30ea906Sjfb8856606 			TAILQ_FIRST(&cryptodev_list) :
46d30ea906Sjfb8856606 			TAILQ_NEXT(cryptodev, node);
47d30ea906Sjfb8856606 }
48d30ea906Sjfb8856606 
49d30ea906Sjfb8856606 struct cryptodev *
cryptodev_create(const char * name,struct cryptodev_params * params)50d30ea906Sjfb8856606 cryptodev_create(const char *name, struct cryptodev_params *params)
51d30ea906Sjfb8856606 {
52d30ea906Sjfb8856606 	struct rte_cryptodev_info dev_info;
53d30ea906Sjfb8856606 	struct rte_cryptodev_config dev_conf;
54d30ea906Sjfb8856606 	struct rte_cryptodev_qp_conf queue_conf;
55d30ea906Sjfb8856606 	struct cryptodev *cryptodev;
56d30ea906Sjfb8856606 	uint32_t dev_id, i;
57d30ea906Sjfb8856606 	uint32_t socket_id;
58*4418919fSjohnjiang 	uint32_t cache_size;
59*4418919fSjohnjiang 	char mp_name[NAME_SIZE];
60d30ea906Sjfb8856606 	int status;
61d30ea906Sjfb8856606 
62d30ea906Sjfb8856606 	/* Check input params */
63d30ea906Sjfb8856606 	if ((name == NULL) ||
64d30ea906Sjfb8856606 		cryptodev_find(name) ||
65d30ea906Sjfb8856606 		(params->n_queues == 0) ||
66*4418919fSjohnjiang 		(params->queue_size == 0) ||
67*4418919fSjohnjiang 		(params->session_pool_size == 0))
68d30ea906Sjfb8856606 		return NULL;
69d30ea906Sjfb8856606 
70d30ea906Sjfb8856606 	if (params->dev_name) {
71d30ea906Sjfb8856606 		status = rte_cryptodev_get_dev_id(params->dev_name);
72d30ea906Sjfb8856606 		if (status == -1)
73d30ea906Sjfb8856606 			return NULL;
74d30ea906Sjfb8856606 
75d30ea906Sjfb8856606 		dev_id = (uint32_t)status;
76d30ea906Sjfb8856606 	} else {
77d30ea906Sjfb8856606 		if (rte_cryptodev_pmd_is_valid_dev(params->dev_id) == 0)
78d30ea906Sjfb8856606 			return NULL;
79d30ea906Sjfb8856606 
80d30ea906Sjfb8856606 		dev_id = params->dev_id;
81d30ea906Sjfb8856606 	}
82d30ea906Sjfb8856606 
83*4418919fSjohnjiang 	cache_size = (params->session_pool_size / 2 <
84*4418919fSjohnjiang 			PIPELINE_CRYPTO_SESSION_CACHE_SIZE) ?
85*4418919fSjohnjiang 					(params->session_pool_size / 2) :
86*4418919fSjohnjiang 					PIPELINE_CRYPTO_SESSION_CACHE_SIZE;
87*4418919fSjohnjiang 
88d30ea906Sjfb8856606 	socket_id = rte_cryptodev_socket_id(dev_id);
89d30ea906Sjfb8856606 	rte_cryptodev_info_get(dev_id, &dev_info);
90d30ea906Sjfb8856606 
91d30ea906Sjfb8856606 	if (dev_info.max_nb_queue_pairs < params->n_queues)
92d30ea906Sjfb8856606 		return NULL;
93d30ea906Sjfb8856606 
94d30ea906Sjfb8856606 	dev_conf.socket_id = socket_id;
95d30ea906Sjfb8856606 	dev_conf.nb_queue_pairs = params->n_queues;
96*4418919fSjohnjiang 	dev_conf.ff_disable = 0;
97d30ea906Sjfb8856606 
98d30ea906Sjfb8856606 	status = rte_cryptodev_configure(dev_id, &dev_conf);
99d30ea906Sjfb8856606 	if (status < 0)
100d30ea906Sjfb8856606 		return NULL;
101d30ea906Sjfb8856606 
102d30ea906Sjfb8856606 	queue_conf.nb_descriptors = params->queue_size;
103d30ea906Sjfb8856606 	for (i = 0; i < params->n_queues; i++) {
104d30ea906Sjfb8856606 		status = rte_cryptodev_queue_pair_setup(dev_id, i,
105*4418919fSjohnjiang 				&queue_conf, socket_id);
106d30ea906Sjfb8856606 		if (status < 0)
107d30ea906Sjfb8856606 			return NULL;
108d30ea906Sjfb8856606 	}
109d30ea906Sjfb8856606 
110d30ea906Sjfb8856606 	if (rte_cryptodev_start(dev_id) < 0)
111d30ea906Sjfb8856606 		return NULL;
112d30ea906Sjfb8856606 
113d30ea906Sjfb8856606 	cryptodev = calloc(1, sizeof(struct cryptodev));
114d30ea906Sjfb8856606 	if (cryptodev == NULL) {
115d30ea906Sjfb8856606 		rte_cryptodev_stop(dev_id);
116d30ea906Sjfb8856606 		return NULL;
117d30ea906Sjfb8856606 	}
118d30ea906Sjfb8856606 
119d30ea906Sjfb8856606 	strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
120d30ea906Sjfb8856606 	cryptodev->dev_id = dev_id;
121d30ea906Sjfb8856606 	cryptodev->n_queues = params->n_queues;
122d30ea906Sjfb8856606 
123*4418919fSjohnjiang 	snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
124*4418919fSjohnjiang 	cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
125*4418919fSjohnjiang 			mp_name,
126*4418919fSjohnjiang 			params->session_pool_size,
127*4418919fSjohnjiang 			0,
128*4418919fSjohnjiang 			cache_size,
129*4418919fSjohnjiang 			0,
130*4418919fSjohnjiang 			socket_id);
131*4418919fSjohnjiang 	if (!cryptodev->mp_create)
132*4418919fSjohnjiang 		goto error_exit;
133*4418919fSjohnjiang 
134*4418919fSjohnjiang 	snprintf(mp_name, NAME_SIZE, "%s_mp_priv%u", name, dev_id);
135*4418919fSjohnjiang 	cryptodev->mp_init = rte_mempool_create(
136*4418919fSjohnjiang 			NULL,
137*4418919fSjohnjiang 			params->session_pool_size,
138*4418919fSjohnjiang 			rte_cryptodev_sym_get_private_session_size(dev_id),
139*4418919fSjohnjiang 			cache_size,
140*4418919fSjohnjiang 			0,
141*4418919fSjohnjiang 			NULL,
142*4418919fSjohnjiang 			NULL,
143*4418919fSjohnjiang 			NULL,
144*4418919fSjohnjiang 			NULL,
145*4418919fSjohnjiang 			socket_id,
146*4418919fSjohnjiang 			0);
147*4418919fSjohnjiang 	if (!cryptodev->mp_init)
148*4418919fSjohnjiang 		goto error_exit;
149*4418919fSjohnjiang 
150d30ea906Sjfb8856606 	TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
151d30ea906Sjfb8856606 
152d30ea906Sjfb8856606 	return cryptodev;
153*4418919fSjohnjiang 
154*4418919fSjohnjiang error_exit:
155*4418919fSjohnjiang 	if (cryptodev->mp_create)
156*4418919fSjohnjiang 		rte_mempool_free(cryptodev->mp_create);
157*4418919fSjohnjiang 	if (cryptodev->mp_init)
158*4418919fSjohnjiang 		rte_mempool_free(cryptodev->mp_init);
159*4418919fSjohnjiang 
160*4418919fSjohnjiang 	free(cryptodev);
161*4418919fSjohnjiang 
162*4418919fSjohnjiang 	return NULL;
163d30ea906Sjfb8856606 }
164