xref: /dpdk/drivers/crypto/mvsam/rte_mrvl_pmd_ops.c (revision 7244858b290028ca188c869262fb3fb062ac71e1)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Marvell International Ltd.
3  * Copyright(c) 2017 Semihalf.
4  * All rights reserved.
5  */
6 
7 #include <string.h>
8 
9 #include <rte_common.h>
10 #include <rte_malloc.h>
11 #include <cryptodev_pmd.h>
12 #include <rte_security_driver.h>
13 
14 #include "mrvl_pmd_private.h"
15 
16 /**
17  * Capabilities list to be used in reporting to DPDK.
18  */
19 static const struct rte_cryptodev_capabilities
20 	mrvl_crypto_pmd_capabilities[] = {
21 	{	/* MD5 HMAC */
22 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
23 		{.sym = {
24 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
25 			{.auth = {
26 				.algo = RTE_CRYPTO_AUTH_MD5_HMAC,
27 				.block_size = 64,
28 				.key_size = {
29 					.min = 1,
30 					.max = 64,
31 					.increment = 1
32 				},
33 				.digest_size = {
34 					.min = 12,
35 					.max = 16,
36 					.increment = 4
37 				},
38 			}, }
39 		}, }
40 	},
41 	{	/* MD5 */
42 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
43 			{.sym = {
44 				.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
45 				{.auth = {
46 					.algo = RTE_CRYPTO_AUTH_MD5,
47 					.block_size = 64,
48 					.key_size = {
49 						.min = 0,
50 						.max = 0,
51 						.increment = 0
52 					},
53 					.digest_size = {
54 						.min = 12,
55 						.max = 16,
56 						.increment = 4
57 					},
58 				}, }
59 			}, }
60 	},
61 	{	/* SHA1 HMAC */
62 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
63 			{.sym = {
64 				.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
65 				{.auth = {
66 					.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
67 					.block_size = 64,
68 					.key_size = {
69 						.min = 1,
70 						.max = 64,
71 						.increment = 1
72 					},
73 					.digest_size = {
74 						.min = 12,
75 						.max = 20,
76 						.increment = 4
77 					},
78 				}, }
79 			}, }
80 	},
81 	{	/* SHA1 */
82 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
83 		{.sym = {
84 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
85 			{.auth = {
86 				.algo = RTE_CRYPTO_AUTH_SHA1,
87 				.block_size = 64,
88 				.key_size = {
89 					.min = 0,
90 					.max = 0,
91 					.increment = 0
92 				},
93 				.digest_size = {
94 					.min = 12,
95 					.max = 20,
96 					.increment = 4
97 				},
98 			}, }
99 		}, }
100 	},
101 	{
102 		/* SHA224 HMAC */
103 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
104 		{.sym = {
105 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
106 			{.auth = {
107 				.algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
108 				.block_size = 64,
109 				.key_size = {
110 					.min = 1,
111 					.max = 64,
112 					.increment = 1
113 				},
114 				.digest_size = {
115 					.min = 12,
116 					.max = 28,
117 					.increment = 0
118 				},
119 			}, }
120 		}, }
121 	},
122 	{	/* SHA224 */
123 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
124 		{.sym = {
125 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
126 			{.auth = {
127 				.algo = RTE_CRYPTO_AUTH_SHA224,
128 				.block_size = 64,
129 				.key_size = {
130 					.min = 0,
131 					.max = 0,
132 					.increment = 0
133 				},
134 				.digest_size = {
135 					.min = 12,
136 					.max = 28,
137 					.increment = 4
138 				},
139 			}, }
140 		}, }
141 	},
142 	{	/* SHA256 HMAC */
143 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
144 			{.sym = {
145 				.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
146 				{.auth = {
147 					.algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
148 					.block_size = 64,
149 					.key_size = {
150 						.min = 1,
151 						.max = 64,
152 						.increment = 1
153 					},
154 					.digest_size = {
155 						.min = 12,
156 						.max = 32,
157 						.increment = 4
158 					},
159 				}, }
160 			}, }
161 	},
162 	{	/* SHA256 */
163 			.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
164 			{.sym = {
165 				.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
166 				{.auth = {
167 					.algo = RTE_CRYPTO_AUTH_SHA256,
168 					.block_size = 64,
169 					.key_size = {
170 						.min = 0,
171 						.max = 0,
172 						.increment = 0
173 					},
174 					.digest_size = {
175 						.min = 12,
176 						.max = 32,
177 						.increment = 4
178 					},
179 				}, }
180 			}, }
181 		},
182 	{	/* SHA384 HMAC */
183 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
184 		{.sym = {
185 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
186 			{.auth = {
187 				.algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
188 				.block_size = 128,
189 				.key_size = {
190 					.min = 1,
191 					.max = 128,
192 					.increment = 1
193 				},
194 				.digest_size = {
195 					.min = 12,
196 					.max = 48,
197 					.increment = 4
198 				},
199 			}, }
200 		}, }
201 	},
202 	{	/* SHA384 */
203 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
204 		{.sym = {
205 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
206 			{.auth = {
207 				.algo = RTE_CRYPTO_AUTH_SHA384,
208 				.block_size = 128,
209 				.key_size = {
210 					.min = 0,
211 					.max = 0,
212 					.increment = 0
213 				},
214 				.digest_size = {
215 					.min = 12,
216 					.max = 48,
217 					.increment = 4
218 				},
219 			}, }
220 		}, }
221 	},
222 	{	/* SHA512 HMAC */
223 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
224 		{.sym = {
225 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
226 			{.auth = {
227 				.algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
228 				.block_size = 128,
229 				.key_size = {
230 					.min = 1,
231 					.max = 128,
232 					.increment = 1
233 				},
234 				.digest_size = {
235 					.min = 12,
236 					.max = 64,
237 					.increment = 4
238 				},
239 			}, }
240 		}, }
241 	},
242 	{	/* SHA512  */
243 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
244 		{.sym = {
245 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
246 			{.auth = {
247 				.algo = RTE_CRYPTO_AUTH_SHA512,
248 				.block_size = 128,
249 				.key_size = {
250 					.min = 0,
251 					.max = 0,
252 					.increment = 0
253 				},
254 				.digest_size = {
255 					.min = 12,
256 					.max = 64,
257 					.increment = 0
258 				},
259 			}, }
260 		}, }
261 	},
262 	{	/* AES CBC */
263 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
264 			{.sym = {
265 				.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
266 				{.cipher = {
267 					.algo = RTE_CRYPTO_CIPHER_AES_CBC,
268 					.block_size = 16,
269 					.key_size = {
270 						.min = 16,
271 						.max = 32,
272 						.increment = 8
273 					},
274 					.iv_size = {
275 						.min = 16,
276 						.max = 16,
277 						.increment = 0
278 					}
279 				}, }
280 			}, }
281 	},
282 	{	/* AES CTR */
283 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
284 		{.sym = {
285 			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
286 			{.cipher = {
287 				.algo = RTE_CRYPTO_CIPHER_AES_CTR,
288 				.block_size = 16,
289 				.key_size = {
290 					.min = 16,
291 					.max = 32,
292 					.increment = 8
293 				},
294 				.iv_size = {
295 					.min = 16,
296 					.max = 16,
297 					.increment = 0
298 				}
299 			}, }
300 		}, }
301 	},
302 	{	/* AES ECB */
303 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
304 		{.sym = {
305 			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
306 			{.cipher = {
307 				.algo = RTE_CRYPTO_CIPHER_AES_ECB,
308 				.block_size = 16,
309 				.key_size = {
310 					.min = 16,
311 					.max = 32,
312 					.increment = 8
313 				},
314 				.iv_size = {
315 					.min = 0,
316 					.max = 0,
317 					.increment = 0
318 				}
319 			}, }
320 		}, }
321 	},
322 	{	/* AES GCM */
323 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
324 		{.sym = {
325 			.xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
326 			{.aead = {
327 				.algo = RTE_CRYPTO_AEAD_AES_GCM,
328 				.block_size = 16,
329 				.key_size = {
330 					.min = 16,
331 					.max = 32,
332 					.increment = 8
333 				},
334 				.digest_size = {
335 					.min = 16,
336 					.max = 16,
337 					.increment = 0
338 				},
339 				.aad_size = {
340 					.min = 0,
341 					.max = 64,
342 					.increment = 1
343 				},
344 				.iv_size = {
345 					.min = 12,
346 					.max = 16,
347 					.increment = 4
348 				}
349 			}, }
350 		}, }
351 	},
352 	{	/* AES GMAC (AUTH) */
353 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
354 		{.sym = {
355 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
356 			{.auth = {
357 				.algo = RTE_CRYPTO_AUTH_AES_GMAC,
358 				.block_size = 16,
359 				.key_size = {
360 					.min = 16,
361 					.max = 32,
362 					.increment = 8
363 				},
364 				.digest_size = {
365 					.min = 16,
366 					.max = 16,
367 					.increment = 0
368 				},
369 				.iv_size = {
370 					.min = 8,
371 					.max = 65532,
372 					.increment = 4
373 				}
374 			}, }
375 		}, }
376 	},
377 	{	/* 3DES CBC */
378 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
379 		{.sym = {
380 			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
381 			{.cipher = {
382 				.algo = RTE_CRYPTO_CIPHER_3DES_CBC,
383 				.block_size = 8,
384 				.key_size = {
385 					.min = 24,
386 					.max = 24,
387 					.increment = 0
388 				},
389 				.iv_size = {
390 					.min = 8,
391 					.max = 8,
392 					.increment = 0
393 				}
394 			}, }
395 		}, }
396 	},
397 	{	/* 3DES CTR */
398 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
399 		{.sym = {
400 			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
401 			{.cipher = {
402 				.algo = RTE_CRYPTO_CIPHER_3DES_CTR,
403 				.block_size = 8,
404 				.key_size = {
405 					.min = 24,
406 					.max = 24,
407 					.increment = 0
408 				},
409 				.iv_size = {
410 					.min = 8,
411 					.max = 8,
412 					.increment = 0
413 				}
414 			}, }
415 		}, }
416 	},
417 	{	/* 3DES ECB */
418 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
419 		{.sym = {
420 			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
421 			{.cipher = {
422 				.algo = RTE_CRYPTO_CIPHER_3DES_ECB,
423 				.block_size = 8,
424 				.key_size = {
425 					.min = 24,
426 					.max = 24,
427 					.increment = 0
428 				},
429 				.iv_size = {
430 					.min = 0,
431 					.max = 0,
432 					.increment = 0
433 				}
434 			}, }
435 		}, }
436 	},
437 	{	/* NULL (AUTH) */
438 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
439 		{.sym = {
440 			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
441 			{.auth = {
442 				.algo = RTE_CRYPTO_AUTH_NULL,
443 				.block_size = 1,
444 				.key_size = {
445 					.min = 0,
446 					.max = 0,
447 					.increment = 0
448 				},
449 				.digest_size = {
450 					.min = 0,
451 					.max = 0,
452 					.increment = 0
453 				},
454 				.iv_size = {
455 					.min = 0,
456 					.max = 0,
457 					.increment = 0
458 				}
459 			}, },
460 		}, },
461 	},
462 	{	/* NULL (CIPHER) */
463 		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
464 		{.sym = {
465 			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
466 			{.cipher = {
467 				.algo = RTE_CRYPTO_CIPHER_NULL,
468 				.block_size = 1,
469 				.key_size = {
470 					.min = 0,
471 					.max = 0,
472 					.increment = 0
473 				},
474 				.iv_size = {
475 					.min = 0,
476 					.max = 0,
477 					.increment = 0
478 				}
479 			}, },
480 		}, }
481 	},
482 
483 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
484 };
485 
486 
487 /**
488  * Configure device (PMD ops callback).
489  *
490  * @param dev Pointer to the device structure.
491  * @param config Pointer to configuration structure.
492  * @returns 0. Always.
493  */
494 static int
mrvl_crypto_pmd_config(__rte_unused struct rte_cryptodev * dev,__rte_unused struct rte_cryptodev_config * config)495 mrvl_crypto_pmd_config(__rte_unused struct rte_cryptodev *dev,
496 		__rte_unused struct rte_cryptodev_config *config)
497 {
498 	return 0;
499 }
500 
501 /**
502  * Start device (PMD ops callback).
503  *
504  * @param dev Pointer to the device structure.
505  * @returns 0. Always.
506  */
507 static int
mrvl_crypto_pmd_start(__rte_unused struct rte_cryptodev * dev)508 mrvl_crypto_pmd_start(__rte_unused struct rte_cryptodev *dev)
509 {
510 	return 0;
511 }
512 
513 /**
514  * Stop device (PMD ops callback).
515  *
516  * @param dev Pointer to the device structure.
517  * @returns 0. Always.
518  */
519 static void
mrvl_crypto_pmd_stop(__rte_unused struct rte_cryptodev * dev)520 mrvl_crypto_pmd_stop(__rte_unused struct rte_cryptodev *dev)
521 {
522 }
523 
524 /**
525  * Get device statistics (PMD ops callback).
526  *
527  * @param dev Pointer to the device structure.
528  * @param stats Pointer to statistics structure [out].
529  */
530 static void
mrvl_crypto_pmd_stats_get(struct rte_cryptodev * dev,struct rte_cryptodev_stats * stats)531 mrvl_crypto_pmd_stats_get(struct rte_cryptodev *dev,
532 		struct rte_cryptodev_stats *stats)
533 {
534 	int qp_id;
535 
536 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
537 		struct mrvl_crypto_qp *qp = dev->data->queue_pairs[qp_id];
538 
539 		stats->enqueued_count += qp->stats.enqueued_count;
540 		stats->dequeued_count += qp->stats.dequeued_count;
541 
542 		stats->enqueue_err_count += qp->stats.enqueue_err_count;
543 		stats->dequeue_err_count += qp->stats.dequeue_err_count;
544 	}
545 }
546 
547 /**
548  * Reset device statistics (PMD ops callback).
549  *
550  * @param dev Pointer to the device structure.
551  */
552 static void
mrvl_crypto_pmd_stats_reset(struct rte_cryptodev * dev)553 mrvl_crypto_pmd_stats_reset(struct rte_cryptodev *dev)
554 {
555 	int qp_id;
556 
557 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
558 		struct mrvl_crypto_qp *qp = dev->data->queue_pairs[qp_id];
559 
560 		memset(&qp->stats, 0, sizeof(qp->stats));
561 	}
562 }
563 
564 /**
565  * Get device info (PMD ops callback).
566  *
567  * @param dev Pointer to the device structure.
568  * @param dev_info Pointer to the device info structure [out].
569  */
570 static void
mrvl_crypto_pmd_info_get(struct rte_cryptodev * dev,struct rte_cryptodev_info * dev_info)571 mrvl_crypto_pmd_info_get(struct rte_cryptodev *dev,
572 		struct rte_cryptodev_info *dev_info)
573 {
574 	struct mrvl_crypto_private *internals = dev->data->dev_private;
575 
576 	if (dev_info != NULL) {
577 		dev_info->driver_id = dev->driver_id;
578 		dev_info->feature_flags = dev->feature_flags;
579 		dev_info->capabilities = mrvl_crypto_pmd_capabilities;
580 		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
581 		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
582 	}
583 }
584 
585 /**
586  * Release queue pair (PMD ops callback).
587  *
588  * @param dev Pointer to the device structure.
589  * @param qp_id ID of Queue Pair to release.
590  * @returns 0. Always.
591  */
592 static int
mrvl_crypto_pmd_qp_release(struct rte_cryptodev * dev,uint16_t qp_id)593 mrvl_crypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
594 {
595 	struct mrvl_crypto_qp *qp =
596 			(struct mrvl_crypto_qp *)dev->data->queue_pairs[qp_id];
597 
598 	if (dev->data->queue_pairs[qp_id] != NULL) {
599 		sam_cio_flush(qp->cio);
600 		sam_cio_deinit(qp->cio);
601 		rte_free(dev->data->queue_pairs[qp_id]);
602 		dev->data->queue_pairs[qp_id] = NULL;
603 	}
604 
605 	return 0;
606 }
607 
608 /**
609  * Close device (PMD ops callback).
610  *
611  * @param dev Pointer to the device structure.
612  * @returns 0. Always.
613  */
614 static int
mrvl_crypto_pmd_close(struct rte_cryptodev * dev)615 mrvl_crypto_pmd_close(struct rte_cryptodev *dev)
616 {
617 	int qp_id;
618 
619 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++)
620 		mrvl_crypto_pmd_qp_release(dev, qp_id);
621 
622 	return 0;
623 }
624 
625 /**
626  * Setup a queue pair (PMD ops callback).
627  *
628  * @param dev Pointer to the device structure.
629  * @param qp_id ID of the Queue Pair.
630  * @param qp_conf Queue pair configuration (nb of descriptors).
631  * @param socket_id NUMA socket to allocate memory on.
632  * @returns 0 upon success, negative value otherwise.
633  */
634 static int
mrvl_crypto_pmd_qp_setup(struct rte_cryptodev * dev,uint16_t qp_id,const struct rte_cryptodev_qp_conf * qp_conf,int socket_id)635 mrvl_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
636 		const struct rte_cryptodev_qp_conf *qp_conf,
637 		int socket_id)
638 {
639 	struct mrvl_crypto_qp *qp = NULL;
640 	char match[RTE_CRYPTODEV_NAME_MAX_LEN];
641 	unsigned int n;
642 
643 	/* Allocate the queue pair data structure. */
644 	qp = rte_zmalloc_socket("MRVL Crypto PMD Queue Pair", sizeof(*qp),
645 					RTE_CACHE_LINE_SIZE, socket_id);
646 	if (qp == NULL)
647 		return -ENOMEM;
648 
649 	/* Free old qp prior setup if needed. */
650 	if (dev->data->queue_pairs[qp_id] != NULL)
651 		mrvl_crypto_pmd_qp_release(dev, qp_id);
652 
653 	do { /* Error handling block */
654 
655 		/*
656 		 * This extra check is necessary due to a bug in
657 		 * crypto library.
658 		 */
659 		int num = sam_get_num_inst();
660 		if (num == 0) {
661 			MRVL_LOG(ERR, "No crypto engines detected!");
662 			return -1;
663 		}
664 
665 		/*
666 		 * In case just one engine is enabled mapping will look as
667 		 * follows:
668 		 * qp:      0        1        2        3
669 		 * cio-x:y: cio-0:0, cio-0:1, cio-0:2, cio-0:3
670 		 *
671 		 * In case two crypto engines are enabled qps will
672 		 * be evenly spread among them. Even and odd qps will
673 		 * be handled by cio-0 and cio-1 respectively. qp-cio mapping
674 		 * will look as follows:
675 		 *
676 		 * qp:      0        1        2        3
677 		 * cio-x:y: cio-0:0, cio-1:0, cio-0:1, cio-1:1
678 		 *
679 		 * qp:      4        5        6        7
680 		 * cio-x:y: cio-0:2, cio-1:2, cio-0:3, cio-1:3
681 		 *
682 		 * In case of three crypto engines are enabled qps will
683 		 * be mapped as following:
684 		 *
685 		 * qp:      0        1        2        3
686 		 * cio-x:y: cio-0:0, cio-1:0, cio-2:0, cio-0:1
687 		 *
688 		 * qp:      4        5        6        7
689 		 * cio-x:y: cio-1:1, cio-2:1, cio-0:2, cio-1:2
690 		 *
691 		 * qp:      8        9        10       11
692 		 * cio-x:y: cio-2:2, cio-0:3, cio-1:3, cio-2:3
693 		 */
694 		n = snprintf(match, sizeof(match), "cio-%u:%u",
695 				qp_id % num, qp_id / num);
696 
697 		if (n >= sizeof(match))
698 			break;
699 
700 		qp->cio_params.match = match;
701 		qp->cio_params.size = qp_conf->nb_descriptors;
702 
703 		if (sam_cio_init(&qp->cio_params, &qp->cio) < 0)
704 			break;
705 
706 		qp->sess_mp = qp_conf->mp_session;
707 
708 		memset(&qp->stats, 0, sizeof(qp->stats));
709 		dev->data->queue_pairs[qp_id] = qp;
710 		return 0;
711 	} while (0);
712 
713 	rte_free(qp);
714 	return -1;
715 }
716 
717 /** Returns the size of the session structure (PMD ops callback).
718  *
719  * @param dev Pointer to the device structure [Unused].
720  * @returns Size of Marvell crypto session.
721  */
722 static unsigned
mrvl_crypto_pmd_sym_session_get_size(__rte_unused struct rte_cryptodev * dev)723 mrvl_crypto_pmd_sym_session_get_size(__rte_unused struct rte_cryptodev *dev)
724 {
725 	return sizeof(struct mrvl_crypto_session);
726 }
727 
728 /** Configure the session from a crypto xform chain (PMD ops callback).
729  *
730  * @param dev Pointer to the device structure.
731  * @param xform Pointer to the crypto configuration structure.
732  * @param sess Pointer to the empty session structure.
733  * @returns 0 upon success, negative value otherwise.
734  */
735 static int
mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev * dev,struct rte_crypto_sym_xform * xform,struct rte_cryptodev_sym_session * sess)736 mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev,
737 		struct rte_crypto_sym_xform *xform,
738 		struct rte_cryptodev_sym_session *sess)
739 {
740 	struct mrvl_crypto_session *mrvl_sess;
741 	void *sess_private_data;
742 	int ret;
743 
744 	if (sess == NULL) {
745 		MRVL_LOG(ERR, "Invalid session struct!");
746 		return -EINVAL;
747 	}
748 
749 	sess_private_data = sess->driver_priv_data;
750 	memset(sess_private_data, 0, sizeof(struct mrvl_crypto_session));
751 
752 	ret = mrvl_crypto_set_session_parameters(sess_private_data, xform);
753 	if (ret != 0) {
754 		MRVL_LOG(ERR, "Failed to configure session parameters!");
755 		return ret;
756 	}
757 
758 
759 	mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
760 	if (sam_session_create(&mrvl_sess->sam_sess_params,
761 				&mrvl_sess->sam_sess) < 0) {
762 		MRVL_LOG(DEBUG, "Failed to create session!");
763 		return -EIO;
764 	}
765 
766 	/* free the keys memory allocated for session creation */
767 	free(mrvl_sess->sam_sess_params.cipher_key);
768 	free(mrvl_sess->sam_sess_params.auth_key);
769 
770 	return 0;
771 }
772 
773 /**
774  * Clear the memory of session so it doesn't leave key material behind.
775  *
776  * @param dev Pointer to the device structure.
777  * @returns 0. Always.
778  */
779 static void
mrvl_crypto_pmd_sym_session_clear(struct rte_cryptodev * dev __rte_unused,struct rte_cryptodev_sym_session * sess)780 mrvl_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev __rte_unused,
781 		struct rte_cryptodev_sym_session *sess)
782 {
783 
784 	void *sess_priv = sess->driver_priv_data;
785 
786 	/* Zero out the whole structure */
787 	if (sess_priv) {
788 		struct mrvl_crypto_session *mrvl_sess =
789 			(struct mrvl_crypto_session *)sess_priv;
790 
791 		if (mrvl_sess->sam_sess &&
792 		    sam_session_destroy(mrvl_sess->sam_sess) < 0) {
793 			MRVL_LOG(ERR, "Error while destroying session!");
794 		}
795 	}
796 }
797 
798 /**
799  * PMD handlers for crypto ops.
800  */
801 static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
802 		.dev_configure		= mrvl_crypto_pmd_config,
803 		.dev_start		= mrvl_crypto_pmd_start,
804 		.dev_stop		= mrvl_crypto_pmd_stop,
805 		.dev_close		= mrvl_crypto_pmd_close,
806 
807 		.dev_infos_get		= mrvl_crypto_pmd_info_get,
808 
809 		.stats_get		= mrvl_crypto_pmd_stats_get,
810 		.stats_reset		= mrvl_crypto_pmd_stats_reset,
811 
812 		.queue_pair_setup	= mrvl_crypto_pmd_qp_setup,
813 		.queue_pair_release	= mrvl_crypto_pmd_qp_release,
814 
815 		.sym_session_get_size	= mrvl_crypto_pmd_sym_session_get_size,
816 		.sym_session_configure	= mrvl_crypto_pmd_sym_session_configure,
817 		.sym_session_clear	= mrvl_crypto_pmd_sym_session_clear
818 };
819 
820 struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops = &mrvl_crypto_pmd_ops;
821 
822 /* IPSEC full offloading */
823 
824 /** Configure the session from a crypto xform chain (PMD ops callback).
825  *
826  * @param dev Pointer to the device structure.
827  * @param conf Pointer to the security session configuration structure.
828  * @param sess Pointer to the empty session structure.
829  * @param mempool Pointer to memory pool.
830  * @returns 0 upon success, negative value otherwise.
831  */
832 static int
mrvl_crypto_pmd_security_session_create(__rte_unused void * dev,struct rte_security_session_conf * conf,struct rte_security_session * sess)833 mrvl_crypto_pmd_security_session_create(__rte_unused void *dev,
834 				 struct rte_security_session_conf *conf,
835 				 struct rte_security_session *sess)
836 {
837 	struct mrvl_crypto_session *mrvl_sess;
838 	void *sess_private_data = SECURITY_GET_SESS_PRIV(sess);
839 	int ret;
840 
841 	if (sess == NULL) {
842 		MRVL_LOG(ERR, "Invalid session struct.");
843 		return -EINVAL;
844 	}
845 
846 	switch (conf->protocol) {
847 	case RTE_SECURITY_PROTOCOL_IPSEC:
848 		mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
849 
850 		struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
851 		struct rte_crypto_sym_xform *crypto_xform = conf->crypto_xform;
852 
853 		ret = mrvl_ipsec_set_session_parameters(mrvl_sess,
854 							ipsec_xform,
855 							crypto_xform);
856 		if (ret != 0) {
857 			MRVL_LOG(ERR, "Failed to configure session parameters.");
858 
859 			return ret;
860 		}
861 
862 		if (mrvl_sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM) {
863 			/* Nonce is must for all counter modes */
864 			mrvl_sess->sam_sess_params.cipher_iv =
865 				(uint8_t *)&(conf->ipsec.salt);
866 		}
867 
868 		ret = sam_session_create(&mrvl_sess->sam_sess_params,
869 				&mrvl_sess->sam_sess);
870 		if (ret < 0) {
871 			MRVL_LOG(ERR, "PMD: failed to create IPSEC session.");
872 			return ret;
873 		}
874 		break;
875 	case RTE_SECURITY_PROTOCOL_MACSEC:
876 		return -ENOTSUP;
877 	default:
878 		return -EINVAL;
879 	}
880 
881 	return ret;
882 }
883 
884 /** Clear the memory of session so it doesn't leave key material behind */
885 static int
mrvl_crypto_pmd_security_session_destroy(void * dev __rte_unused,struct rte_security_session * sess)886 mrvl_crypto_pmd_security_session_destroy(void *dev __rte_unused,
887 		struct rte_security_session *sess)
888 {
889 	void *sess_priv = SECURITY_GET_SESS_PRIV(sess);
890 
891 	/* Zero out the whole structure */
892 	if (sess_priv) {
893 		struct mrvl_crypto_session *mrvl_sess =
894 			(struct mrvl_crypto_session *)sess_priv;
895 
896 		if (mrvl_sess->sam_sess &&
897 		    sam_session_destroy(mrvl_sess->sam_sess) < 0) {
898 			MRVL_LOG(ERR, "Error while destroying session!");
899 		}
900 
901 		rte_free(mrvl_sess->sam_sess_params.cipher_key);
902 		rte_free(mrvl_sess->sam_sess_params.auth_key);
903 		rte_free(mrvl_sess->sam_sess_params.cipher_iv);
904 		memset(sess, 0, sizeof(struct rte_security_session));
905 	}
906 	return 0;
907 }
908 
909 static unsigned int
mrvl_crypto_pmd_security_session_get_size(void * device __rte_unused)910 mrvl_crypto_pmd_security_session_get_size(void *device __rte_unused)
911 {
912 	return sizeof(struct mrvl_crypto_session);
913 }
914 
915 static const
916 struct rte_security_capability mrvl_crypto_pmd_sec_security_cap[] = {
917 	{ /* IPsec Lookaside Protocol offload ESP Tunnel Egress */
918 		.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
919 		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
920 		.ipsec = {
921 			.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
922 			.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
923 			.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
924 			.options = { 0 },
925 			.replay_win_sz_max = 128
926 		},
927 		.crypto_capabilities = mrvl_crypto_pmd_capabilities
928 	},
929 	{ /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */
930 		.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
931 		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
932 		.ipsec = {
933 			.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
934 			.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
935 			.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
936 			.options = { 0 },
937 			.replay_win_sz_max = 128
938 		},
939 		.crypto_capabilities = mrvl_crypto_pmd_capabilities
940 	},
941 	{ /* IPsec Lookaside Protocol offload ESP Transport Egress */
942 		.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
943 		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
944 		.ipsec = {
945 			.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
946 			.mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
947 			.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
948 			.options = { 0 },
949 			.replay_win_sz_max = 128
950 		},
951 		.crypto_capabilities = mrvl_crypto_pmd_capabilities
952 	},
953 	{ /* IPsec Lookaside Protocol offload ESP Transport Ingress */
954 		.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
955 		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
956 		.ipsec = {
957 			.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
958 			.mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
959 			.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
960 			.options = { 0 },
961 			.replay_win_sz_max = 128
962 		},
963 		.crypto_capabilities = mrvl_crypto_pmd_capabilities
964 	},
965 	{
966 		.action = RTE_SECURITY_ACTION_TYPE_NONE
967 	}
968 };
969 
970 static const struct rte_security_capability *
mrvl_crypto_pmd_security_capabilities_get(void * device __rte_unused)971 mrvl_crypto_pmd_security_capabilities_get(void *device __rte_unused)
972 {
973 	return mrvl_crypto_pmd_sec_security_cap;
974 }
975 
976 struct rte_security_ops mrvl_sec_security_pmd_ops = {
977 	.session_create = mrvl_crypto_pmd_security_session_create,
978 	.session_update = NULL,
979 	.session_get_size = mrvl_crypto_pmd_security_session_get_size,
980 	.session_stats_get = NULL,
981 	.session_destroy = mrvl_crypto_pmd_security_session_destroy,
982 	.set_pkt_metadata = NULL,
983 	.capabilities_get = mrvl_crypto_pmd_security_capabilities_get
984 };
985 
986 struct rte_security_ops *rte_mrvl_security_pmd_ops = &mrvl_sec_security_pmd_ops;
987