xref: /f-stack/dpdk/drivers/crypto/qat/qat_asym_pmd.c (revision 2d9fd380)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4 
5 #include <rte_cryptodev_pmd.h>
6 
7 #include "qat_logs.h"
8 
9 #include "qat_asym.h"
10 #include "qat_asym_pmd.h"
11 #include "qat_sym_capabilities.h"
12 #include "qat_asym_capabilities.h"
13 
14 uint8_t qat_asym_driver_id;
15 
16 static const struct rte_cryptodev_capabilities qat_gen1_asym_capabilities[] = {
17 	QAT_BASE_GEN1_ASYM_CAPABILITIES,
18 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
19 };
20 
21 static int qat_asym_qp_release(struct rte_cryptodev *dev,
22 			       uint16_t queue_pair_id);
23 
qat_asym_dev_config(__rte_unused struct rte_cryptodev * dev,__rte_unused struct rte_cryptodev_config * config)24 static int qat_asym_dev_config(__rte_unused struct rte_cryptodev *dev,
25 			       __rte_unused struct rte_cryptodev_config *config)
26 {
27 	return 0;
28 }
29 
qat_asym_dev_start(__rte_unused struct rte_cryptodev * dev)30 static int qat_asym_dev_start(__rte_unused struct rte_cryptodev *dev)
31 {
32 	return 0;
33 }
34 
qat_asym_dev_stop(__rte_unused struct rte_cryptodev * dev)35 static void qat_asym_dev_stop(__rte_unused struct rte_cryptodev *dev)
36 {
37 
38 }
39 
qat_asym_dev_close(struct rte_cryptodev * dev)40 static int qat_asym_dev_close(struct rte_cryptodev *dev)
41 {
42 	int i, ret;
43 
44 	for (i = 0; i < dev->data->nb_queue_pairs; i++) {
45 		ret = qat_asym_qp_release(dev, i);
46 		if (ret < 0)
47 			return ret;
48 	}
49 
50 	return 0;
51 }
52 
qat_asym_dev_info_get(struct rte_cryptodev * dev,struct rte_cryptodev_info * info)53 static void qat_asym_dev_info_get(struct rte_cryptodev *dev,
54 				  struct rte_cryptodev_info *info)
55 {
56 	struct qat_asym_dev_private *internals = dev->data->dev_private;
57 	const struct qat_qp_hw_data *asym_hw_qps =
58 		qat_gen_config[internals->qat_dev->qat_dev_gen]
59 			      .qp_hw_data[QAT_SERVICE_ASYMMETRIC];
60 
61 	if (info != NULL) {
62 		info->max_nb_queue_pairs = qat_qps_per_service(asym_hw_qps,
63 							QAT_SERVICE_ASYMMETRIC);
64 		info->feature_flags = dev->feature_flags;
65 		info->capabilities = internals->qat_dev_capabilities;
66 		info->driver_id = qat_asym_driver_id;
67 		/* No limit of number of sessions */
68 		info->sym.max_nb_sessions = 0;
69 	}
70 }
71 
qat_asym_stats_get(struct rte_cryptodev * dev,struct rte_cryptodev_stats * stats)72 static void qat_asym_stats_get(struct rte_cryptodev *dev,
73 			       struct rte_cryptodev_stats *stats)
74 {
75 	struct qat_common_stats qat_stats = {0};
76 	struct qat_asym_dev_private *qat_priv;
77 
78 	if (stats == NULL || dev == NULL) {
79 		QAT_LOG(ERR, "invalid ptr: stats %p, dev %p", stats, dev);
80 		return;
81 	}
82 	qat_priv = dev->data->dev_private;
83 
84 	qat_stats_get(qat_priv->qat_dev, &qat_stats, QAT_SERVICE_ASYMMETRIC);
85 	stats->enqueued_count = qat_stats.enqueued_count;
86 	stats->dequeued_count = qat_stats.dequeued_count;
87 	stats->enqueue_err_count = qat_stats.enqueue_err_count;
88 	stats->dequeue_err_count = qat_stats.dequeue_err_count;
89 }
90 
qat_asym_stats_reset(struct rte_cryptodev * dev)91 static void qat_asym_stats_reset(struct rte_cryptodev *dev)
92 {
93 	struct qat_asym_dev_private *qat_priv;
94 
95 	if (dev == NULL) {
96 		QAT_LOG(ERR, "invalid asymmetric cryptodev ptr %p", dev);
97 		return;
98 	}
99 	qat_priv = dev->data->dev_private;
100 
101 	qat_stats_reset(qat_priv->qat_dev, QAT_SERVICE_ASYMMETRIC);
102 }
103 
qat_asym_qp_release(struct rte_cryptodev * dev,uint16_t queue_pair_id)104 static int qat_asym_qp_release(struct rte_cryptodev *dev,
105 			       uint16_t queue_pair_id)
106 {
107 	struct qat_asym_dev_private *qat_private = dev->data->dev_private;
108 
109 	QAT_LOG(DEBUG, "Release asym qp %u on device %d",
110 				queue_pair_id, dev->data->dev_id);
111 
112 	qat_private->qat_dev->qps_in_use[QAT_SERVICE_ASYMMETRIC][queue_pair_id]
113 						= NULL;
114 
115 	return qat_qp_release((struct qat_qp **)
116 			&(dev->data->queue_pairs[queue_pair_id]));
117 }
118 
qat_asym_qp_setup(struct rte_cryptodev * dev,uint16_t qp_id,const struct rte_cryptodev_qp_conf * qp_conf,int socket_id)119 static int qat_asym_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
120 			     const struct rte_cryptodev_qp_conf *qp_conf,
121 			     int socket_id)
122 {
123 	struct qat_qp_config qat_qp_conf;
124 	struct qat_qp *qp;
125 	int ret = 0;
126 	uint32_t i;
127 
128 	struct qat_qp **qp_addr =
129 			(struct qat_qp **)&(dev->data->queue_pairs[qp_id]);
130 	struct qat_asym_dev_private *qat_private = dev->data->dev_private;
131 	const struct qat_qp_hw_data *asym_hw_qps =
132 			qat_gen_config[qat_private->qat_dev->qat_dev_gen]
133 				      .qp_hw_data[QAT_SERVICE_ASYMMETRIC];
134 	const struct qat_qp_hw_data *qp_hw_data = asym_hw_qps + qp_id;
135 
136 	/* If qp is already in use free ring memory and qp metadata. */
137 	if (*qp_addr != NULL) {
138 		ret = qat_asym_qp_release(dev, qp_id);
139 		if (ret < 0)
140 			return ret;
141 	}
142 	if (qp_id >= qat_qps_per_service(asym_hw_qps, QAT_SERVICE_ASYMMETRIC)) {
143 		QAT_LOG(ERR, "qp_id %u invalid for this device", qp_id);
144 		return -EINVAL;
145 	}
146 
147 	qat_qp_conf.hw = qp_hw_data;
148 	qat_qp_conf.cookie_size = sizeof(struct qat_asym_op_cookie);
149 	qat_qp_conf.nb_descriptors = qp_conf->nb_descriptors;
150 	qat_qp_conf.socket_id = socket_id;
151 	qat_qp_conf.service_str = "asym";
152 
153 	ret = qat_qp_setup(qat_private->qat_dev, qp_addr, qp_id, &qat_qp_conf);
154 	if (ret != 0)
155 		return ret;
156 
157 	/* store a link to the qp in the qat_pci_device */
158 	qat_private->qat_dev->qps_in_use[QAT_SERVICE_ASYMMETRIC][qp_id]
159 							= *qp_addr;
160 
161 	qp = (struct qat_qp *)*qp_addr;
162 	qp->min_enq_burst_threshold = qat_private->min_enq_burst_threshold;
163 
164 	for (i = 0; i < qp->nb_descriptors; i++) {
165 		int j;
166 
167 		struct qat_asym_op_cookie __rte_unused *cookie =
168 				qp->op_cookies[i];
169 		cookie->input_addr = rte_mempool_virt2iova(cookie) +
170 				offsetof(struct qat_asym_op_cookie,
171 						input_params_ptrs);
172 
173 		cookie->output_addr = rte_mempool_virt2iova(cookie) +
174 				offsetof(struct qat_asym_op_cookie,
175 						output_params_ptrs);
176 
177 		for (j = 0; j < 8; j++) {
178 			cookie->input_params_ptrs[j] =
179 					rte_mempool_virt2iova(cookie) +
180 					offsetof(struct qat_asym_op_cookie,
181 							input_array[j]);
182 			cookie->output_params_ptrs[j] =
183 					rte_mempool_virt2iova(cookie) +
184 					offsetof(struct qat_asym_op_cookie,
185 							output_array[j]);
186 		}
187 	}
188 
189 	return ret;
190 }
191 
192 struct rte_cryptodev_ops crypto_qat_ops = {
193 
194 	/* Device related operations */
195 	.dev_configure		= qat_asym_dev_config,
196 	.dev_start		= qat_asym_dev_start,
197 	.dev_stop		= qat_asym_dev_stop,
198 	.dev_close		= qat_asym_dev_close,
199 	.dev_infos_get		= qat_asym_dev_info_get,
200 
201 	.stats_get		= qat_asym_stats_get,
202 	.stats_reset		= qat_asym_stats_reset,
203 	.queue_pair_setup	= qat_asym_qp_setup,
204 	.queue_pair_release	= qat_asym_qp_release,
205 
206 	/* Crypto related operations */
207 	.asym_session_get_size	= qat_asym_session_get_private_size,
208 	.asym_session_configure	= qat_asym_session_configure,
209 	.asym_session_clear	= qat_asym_session_clear
210 };
211 
qat_asym_pmd_enqueue_op_burst(void * qp,struct rte_crypto_op ** ops,uint16_t nb_ops)212 uint16_t qat_asym_pmd_enqueue_op_burst(void *qp, struct rte_crypto_op **ops,
213 				       uint16_t nb_ops)
214 {
215 	return qat_enqueue_op_burst(qp, (void **)ops, nb_ops);
216 }
217 
qat_asym_pmd_dequeue_op_burst(void * qp,struct rte_crypto_op ** ops,uint16_t nb_ops)218 uint16_t qat_asym_pmd_dequeue_op_burst(void *qp, struct rte_crypto_op **ops,
219 				       uint16_t nb_ops)
220 {
221 	return qat_dequeue_op_burst(qp, (void **)ops, nb_ops);
222 }
223 
224 /* An rte_driver is needed in the registration of both the device and the driver
225  * with cryptodev.
226  * The actual qat pci's rte_driver can't be used as its name represents
227  * the whole pci device with all services. Think of this as a holder for a name
228  * for the crypto part of the pci device.
229  */
230 static const char qat_asym_drv_name[] = RTE_STR(CRYPTODEV_NAME_QAT_ASYM_PMD);
231 static const struct rte_driver cryptodev_qat_asym_driver = {
232 	.name = qat_asym_drv_name,
233 	.alias = qat_asym_drv_name
234 };
235 
236 int
qat_asym_dev_create(struct qat_pci_device * qat_pci_dev,struct qat_dev_cmd_param * qat_dev_cmd_param)237 qat_asym_dev_create(struct qat_pci_device *qat_pci_dev,
238 		struct qat_dev_cmd_param *qat_dev_cmd_param)
239 {
240 	int i = 0;
241 	struct qat_device_info *qat_dev_instance =
242 			&qat_pci_devs[qat_pci_dev->qat_dev_id];
243 	struct rte_cryptodev_pmd_init_params init_params = {
244 			.name = "",
245 			.socket_id =
246 				qat_dev_instance->pci_dev->device.numa_node,
247 			.private_data_size = sizeof(struct qat_asym_dev_private)
248 	};
249 	char name[RTE_CRYPTODEV_NAME_MAX_LEN];
250 	char capa_memz_name[RTE_CRYPTODEV_NAME_MAX_LEN];
251 	struct rte_cryptodev *cryptodev;
252 	struct qat_asym_dev_private *internals;
253 
254 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
255 		qat_pci_dev->qat_asym_driver_id =
256 				qat_asym_driver_id;
257 	} else if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
258 		if (qat_pci_dev->qat_asym_driver_id !=
259 				qat_asym_driver_id) {
260 			QAT_LOG(ERR,
261 				"Device %s have different driver id than corresponding device in primary process",
262 				name);
263 			return -(EFAULT);
264 		}
265 	}
266 
267 	snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s_%s",
268 			qat_pci_dev->name, "asym");
269 	QAT_LOG(DEBUG, "Creating QAT ASYM device %s\n", name);
270 
271 	/* Populate subset device to use in cryptodev device creation */
272 	qat_dev_instance->asym_rte_dev.driver = &cryptodev_qat_asym_driver;
273 	qat_dev_instance->asym_rte_dev.numa_node =
274 			qat_dev_instance->pci_dev->device.numa_node;
275 	qat_dev_instance->asym_rte_dev.devargs = NULL;
276 
277 	cryptodev = rte_cryptodev_pmd_create(name,
278 			&(qat_dev_instance->asym_rte_dev), &init_params);
279 
280 	if (cryptodev == NULL)
281 		return -ENODEV;
282 
283 	qat_dev_instance->asym_rte_dev.name = cryptodev->data->name;
284 	cryptodev->driver_id = qat_asym_driver_id;
285 	cryptodev->dev_ops = &crypto_qat_ops;
286 
287 	cryptodev->enqueue_burst = qat_asym_pmd_enqueue_op_burst;
288 	cryptodev->dequeue_burst = qat_asym_pmd_dequeue_op_burst;
289 
290 	cryptodev->feature_flags = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
291 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
292 			RTE_CRYPTODEV_FF_ASYM_SESSIONLESS |
293 			RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP |
294 			RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT;
295 
296 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
297 		return 0;
298 
299 	snprintf(capa_memz_name, RTE_CRYPTODEV_NAME_MAX_LEN,
300 			"QAT_ASYM_CAPA_GEN_%d",
301 			qat_pci_dev->qat_dev_gen);
302 
303 	internals = cryptodev->data->dev_private;
304 	internals->qat_dev = qat_pci_dev;
305 	internals->asym_dev_id = cryptodev->data->dev_id;
306 	internals->qat_dev_capabilities = qat_gen1_asym_capabilities;
307 
308 	internals->capa_mz = rte_memzone_lookup(capa_memz_name);
309 	if (internals->capa_mz == NULL) {
310 		internals->capa_mz = rte_memzone_reserve(capa_memz_name,
311 			sizeof(qat_gen1_asym_capabilities),
312 			rte_socket_id(), 0);
313 	}
314 	if (internals->capa_mz == NULL) {
315 		QAT_LOG(DEBUG,
316 			"Error allocating memzone for capabilities, destroying PMD for %s",
317 			name);
318 		rte_cryptodev_pmd_destroy(cryptodev);
319 		memset(&qat_dev_instance->asym_rte_dev, 0,
320 			sizeof(qat_dev_instance->asym_rte_dev));
321 		return -EFAULT;
322 	}
323 
324 	memcpy(internals->capa_mz->addr, qat_gen1_asym_capabilities,
325 			sizeof(qat_gen1_asym_capabilities));
326 	internals->qat_dev_capabilities = internals->capa_mz->addr;
327 
328 	while (1) {
329 		if (qat_dev_cmd_param[i].name == NULL)
330 			break;
331 		if (!strcmp(qat_dev_cmd_param[i].name, ASYM_ENQ_THRESHOLD_NAME))
332 			internals->min_enq_burst_threshold =
333 					qat_dev_cmd_param[i].val;
334 		i++;
335 	}
336 
337 	qat_pci_dev->asym_dev = internals;
338 	QAT_LOG(DEBUG, "Created QAT ASYM device %s as cryptodev instance %d",
339 			cryptodev->data->name, internals->asym_dev_id);
340 	return 0;
341 }
342 
343 int
qat_asym_dev_destroy(struct qat_pci_device * qat_pci_dev)344 qat_asym_dev_destroy(struct qat_pci_device *qat_pci_dev)
345 {
346 	struct rte_cryptodev *cryptodev;
347 
348 	if (qat_pci_dev == NULL)
349 		return -ENODEV;
350 	if (qat_pci_dev->asym_dev == NULL)
351 		return 0;
352 	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
353 		rte_memzone_free(qat_pci_dev->asym_dev->capa_mz);
354 
355 	/* free crypto device */
356 	cryptodev = rte_cryptodev_pmd_get_dev(
357 			qat_pci_dev->asym_dev->asym_dev_id);
358 	rte_cryptodev_pmd_destroy(cryptodev);
359 	qat_pci_devs[qat_pci_dev->qat_dev_id].asym_rte_dev.name = NULL;
360 	qat_pci_dev->asym_dev = NULL;
361 
362 	return 0;
363 }
364 
365 static struct cryptodev_driver qat_crypto_drv;
366 RTE_PMD_REGISTER_CRYPTO_DRIVER(qat_crypto_drv,
367 		cryptodev_qat_asym_driver,
368 		qat_asym_driver_id);
369