crypto/mvsam: support IPsec offload
[dpdk.git] / drivers / crypto / mvsam / rte_mrvl_pmd_ops.c
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 <rte_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
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
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
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
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
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
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
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
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
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                 qp->sess_mp_priv = qp_conf->mp_session_private;
708
709                 memset(&qp->stats, 0, sizeof(qp->stats));
710                 dev->data->queue_pairs[qp_id] = qp;
711                 return 0;
712         } while (0);
713
714         rte_free(qp);
715         return -1;
716 }
717
718 /** Returns the size of the session structure (PMD ops callback).
719  *
720  * @param dev Pointer to the device structure [Unused].
721  * @returns Size of Marvell crypto session.
722  */
723 static unsigned
724 mrvl_crypto_pmd_sym_session_get_size(__rte_unused struct rte_cryptodev *dev)
725 {
726         return sizeof(struct mrvl_crypto_session);
727 }
728
729 /** Configure the session from a crypto xform chain (PMD ops callback).
730  *
731  * @param dev Pointer to the device structure.
732  * @param xform Pointer to the crypto configuration structure.
733  * @param sess Pointer to the empty session structure.
734  * @returns 0 upon success, negative value otherwise.
735  */
736 static int
737 mrvl_crypto_pmd_sym_session_configure(__rte_unused struct rte_cryptodev *dev,
738                 struct rte_crypto_sym_xform *xform,
739                 struct rte_cryptodev_sym_session *sess,
740                 struct rte_mempool *mp)
741 {
742         struct mrvl_crypto_session *mrvl_sess;
743         void *sess_private_data;
744         int ret;
745
746         if (sess == NULL) {
747                 MRVL_LOG(ERR, "Invalid session struct!");
748                 return -EINVAL;
749         }
750
751         if (rte_mempool_get(mp, &sess_private_data)) {
752                 CDEV_LOG_ERR("Couldn't get object from session mempool.");
753                 return -ENOMEM;
754         }
755
756         memset(sess_private_data, 0, sizeof(struct mrvl_crypto_session));
757
758         ret = mrvl_crypto_set_session_parameters(sess_private_data, xform);
759         if (ret != 0) {
760                 MRVL_LOG(ERR, "Failed to configure session parameters!");
761
762                 /* Return session to mempool */
763                 rte_mempool_put(mp, sess_private_data);
764                 return ret;
765         }
766
767         set_sym_session_private_data(sess, dev->driver_id, sess_private_data);
768
769         mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
770         if (sam_session_create(&mrvl_sess->sam_sess_params,
771                                 &mrvl_sess->sam_sess) < 0) {
772                 MRVL_LOG(DEBUG, "Failed to create session!");
773                 return -EIO;
774         }
775
776         /* free the keys memory allocated for session creation */
777         if (mrvl_sess->sam_sess_params.cipher_key != NULL)
778                 free(mrvl_sess->sam_sess_params.cipher_key);
779         if (mrvl_sess->sam_sess_params.auth_key != NULL)
780                 free(mrvl_sess->sam_sess_params.auth_key);
781
782         return 0;
783 }
784
785 /**
786  * Clear the memory of session so it doesn't leave key material behind.
787  *
788  * @param dev Pointer to the device structure.
789  * @returns 0. Always.
790  */
791 static void
792 mrvl_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev,
793                 struct rte_cryptodev_sym_session *sess)
794 {
795
796         uint8_t index = dev->driver_id;
797         void *sess_priv = get_sym_session_private_data(sess, index);
798
799         /* Zero out the whole structure */
800         if (sess_priv) {
801                 struct mrvl_crypto_session *mrvl_sess =
802                         (struct mrvl_crypto_session *)sess_priv;
803
804                 if (mrvl_sess->sam_sess &&
805                     sam_session_destroy(mrvl_sess->sam_sess) < 0) {
806                         MRVL_LOG(ERR, "Error while destroying session!");
807                 }
808
809                 memset(mrvl_sess, 0, sizeof(struct mrvl_crypto_session));
810                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
811                 set_sym_session_private_data(sess, index, NULL);
812                 rte_mempool_put(sess_mp, sess_priv);
813         }
814 }
815
816 /**
817  * PMD handlers for crypto ops.
818  */
819 static struct rte_cryptodev_ops mrvl_crypto_pmd_ops = {
820                 .dev_configure          = mrvl_crypto_pmd_config,
821                 .dev_start              = mrvl_crypto_pmd_start,
822                 .dev_stop               = mrvl_crypto_pmd_stop,
823                 .dev_close              = mrvl_crypto_pmd_close,
824
825                 .dev_infos_get          = mrvl_crypto_pmd_info_get,
826
827                 .stats_get              = mrvl_crypto_pmd_stats_get,
828                 .stats_reset            = mrvl_crypto_pmd_stats_reset,
829
830                 .queue_pair_setup       = mrvl_crypto_pmd_qp_setup,
831                 .queue_pair_release     = mrvl_crypto_pmd_qp_release,
832
833                 .sym_session_get_size   = mrvl_crypto_pmd_sym_session_get_size,
834                 .sym_session_configure  = mrvl_crypto_pmd_sym_session_configure,
835                 .sym_session_clear      = mrvl_crypto_pmd_sym_session_clear
836 };
837
838 struct rte_cryptodev_ops *rte_mrvl_crypto_pmd_ops = &mrvl_crypto_pmd_ops;
839
840 /* IPSEC full offloading */
841
842 /** Configure the session from a crypto xform chain (PMD ops callback).
843  *
844  * @param dev Pointer to the device structure.
845  * @param conf Pointer to the security session configuration structure.
846  * @param sess Pointer to the empty session structure.
847  * @param mempool Pointer to memory pool.
848  * @returns 0 upon success, negative value otherwise.
849  */
850 static int
851 mrvl_crypto_pmd_security_session_create(__rte_unused void *dev,
852                                  struct rte_security_session_conf *conf,
853                                  struct rte_security_session *sess,
854                                  struct rte_mempool *mempool)
855 {
856         struct mrvl_crypto_session *mrvl_sess;
857         void *sess_private_data;
858         int ret;
859
860         if (sess == NULL) {
861                 MRVL_LOG(ERR, "Invalid session struct.");
862                 return -EINVAL;
863         }
864
865         if (rte_mempool_get(mempool, &sess_private_data)) {
866                 MRVL_LOG(ERR, "Couldn't get object from session mempool.");
867                 return -ENOMEM;
868         }
869
870         switch (conf->protocol) {
871         case RTE_SECURITY_PROTOCOL_IPSEC:
872                 mrvl_sess = (struct mrvl_crypto_session *)sess_private_data;
873
874                 struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
875                 struct rte_crypto_sym_xform *crypto_xform = conf->crypto_xform;
876
877                 ret = mrvl_ipsec_set_session_parameters(mrvl_sess,
878                                                         ipsec_xform,
879                                                         crypto_xform);
880                 if (ret != 0) {
881                         MRVL_LOG(ERR, "Failed to configure session parameters.");
882
883                         /* Return session to mempool */
884                         rte_mempool_put(mempool, sess_private_data);
885                         return ret;
886                 }
887
888                 if (mrvl_sess->sam_sess_params.cipher_mode == SAM_CIPHER_GCM) {
889                         /* Nonce is must for all counter modes */
890                         mrvl_sess->sam_sess_params.cipher_iv =
891                                 (uint8_t *)&(conf->ipsec.salt);
892                 }
893
894                 ret = sam_session_create(&mrvl_sess->sam_sess_params,
895                                 &mrvl_sess->sam_sess);
896                 if (ret < 0) {
897                         MRVL_LOG(ERR, "PMD: failed to create IPSEC session.");
898                         /* Return session to mempool */
899                         rte_mempool_put(mempool, sess_private_data);
900                         return ret;
901                 }
902                 break;
903         case RTE_SECURITY_PROTOCOL_MACSEC:
904                 return -ENOTSUP;
905         default:
906                 return -EINVAL;
907         }
908
909         set_sec_session_private_data(sess, sess_private_data);
910
911         return ret;
912 }
913
914 /** Clear the memory of session so it doesn't leave key material behind */
915 static int
916 mrvl_crypto_pmd_security_session_destroy(void *dev __rte_unused,
917                 struct rte_security_session *sess)
918 {
919         void *sess_priv = get_sec_session_private_data(sess);
920
921         /* Zero out the whole structure */
922         if (sess_priv) {
923                 struct mrvl_crypto_session *mrvl_sess =
924                         (struct mrvl_crypto_session *)sess_priv;
925                 struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
926
927                 if (mrvl_sess->sam_sess &&
928                     sam_session_destroy(mrvl_sess->sam_sess) < 0) {
929                         MRVL_LOG(ERR, "Error while destroying session!");
930                 }
931
932                 rte_free(mrvl_sess->sam_sess_params.cipher_key);
933                 rte_free(mrvl_sess->sam_sess_params.auth_key);
934                 rte_free(mrvl_sess->sam_sess_params.cipher_iv);
935                 memset(sess, 0, sizeof(struct rte_security_session));
936                 set_sec_session_private_data(sess, NULL);
937                 rte_mempool_put(sess_mp, sess_priv);
938         }
939         return 0;
940 }
941
942 static const
943 struct rte_security_capability mrvl_crypto_pmd_sec_security_cap[] = {
944         { /* IPsec Lookaside Protocol offload ESP Tunnel Egress */
945                 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
946                 .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
947                 .ipsec = {
948                         .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
949                         .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
950                         .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
951                         .options = { 0 },
952                         .replay_win_sz_max = 128
953                 },
954                 .crypto_capabilities = mrvl_crypto_pmd_capabilities
955         },
956         { /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */
957                 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
958                 .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
959                 .ipsec = {
960                         .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
961                         .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
962                         .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
963                         .options = { 0 },
964                         .replay_win_sz_max = 128
965                 },
966                 .crypto_capabilities = mrvl_crypto_pmd_capabilities
967         },
968         { /* IPsec Lookaside Protocol offload ESP Transport Egress */
969                 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
970                 .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
971                 .ipsec = {
972                         .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
973                         .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
974                         .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
975                         .options = { 0 },
976                         .replay_win_sz_max = 128
977                 },
978                 .crypto_capabilities = mrvl_crypto_pmd_capabilities
979         },
980         { /* IPsec Lookaside Protocol offload ESP Transport Ingress */
981                 .action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
982                 .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
983                 .ipsec = {
984                         .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
985                         .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
986                         .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
987                         .options = { 0 },
988                         .replay_win_sz_max = 128
989                 },
990                 .crypto_capabilities = mrvl_crypto_pmd_capabilities
991         },
992         {
993                 .action = RTE_SECURITY_ACTION_TYPE_NONE
994         }
995 };
996
997 static const struct rte_security_capability *
998 mrvl_crypto_pmd_security_capabilities_get(void *device __rte_unused)
999 {
1000         return mrvl_crypto_pmd_sec_security_cap;
1001 }
1002
1003 struct rte_security_ops mrvl_sec_security_pmd_ops = {
1004         .session_create = mrvl_crypto_pmd_security_session_create,
1005         .session_update = NULL,
1006         .session_stats_get = NULL,
1007         .session_destroy = mrvl_crypto_pmd_security_session_destroy,
1008         .set_pkt_metadata = NULL,
1009         .capabilities_get = mrvl_crypto_pmd_security_capabilities_get
1010 };
1011
1012 struct rte_security_ops *rte_mrvl_security_pmd_ops = &mrvl_sec_security_pmd_ops;