net/txgbe: add IPsec context creation
[dpdk.git] / drivers / net / txgbe / txgbe_ipsec.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2020
3  */
4
5 #include <rte_ethdev_pci.h>
6 #include <rte_security_driver.h>
7 #include <rte_cryptodev.h>
8
9 #include "base/txgbe.h"
10 #include "txgbe_ethdev.h"
11
12 static const struct rte_security_capability *
13 txgbe_crypto_capabilities_get(void *device __rte_unused)
14 {
15         static const struct rte_cryptodev_capabilities
16         aes_gcm_gmac_crypto_capabilities[] = {
17                 {       /* AES GMAC (128-bit) */
18                         .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
19                         {.sym = {
20                                 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
21                                 {.auth = {
22                                         .algo = RTE_CRYPTO_AUTH_AES_GMAC,
23                                         .block_size = 16,
24                                         .key_size = {
25                                                 .min = 16,
26                                                 .max = 16,
27                                                 .increment = 0
28                                         },
29                                         .digest_size = {
30                                                 .min = 16,
31                                                 .max = 16,
32                                                 .increment = 0
33                                         },
34                                         .iv_size = {
35                                                 .min = 12,
36                                                 .max = 12,
37                                                 .increment = 0
38                                         }
39                                 }, }
40                         }, }
41                 },
42                 {       /* AES GCM (128-bit) */
43                         .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
44                         {.sym = {
45                                 .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
46                                 {.aead = {
47                                         .algo = RTE_CRYPTO_AEAD_AES_GCM,
48                                         .block_size = 16,
49                                         .key_size = {
50                                                 .min = 16,
51                                                 .max = 16,
52                                                 .increment = 0
53                                         },
54                                         .digest_size = {
55                                                 .min = 16,
56                                                 .max = 16,
57                                                 .increment = 0
58                                         },
59                                         .aad_size = {
60                                                 .min = 0,
61                                                 .max = 65535,
62                                                 .increment = 1
63                                         },
64                                         .iv_size = {
65                                                 .min = 12,
66                                                 .max = 12,
67                                                 .increment = 0
68                                         }
69                                 }, }
70                         }, }
71                 },
72                 {
73                         .op = RTE_CRYPTO_OP_TYPE_UNDEFINED,
74                         {.sym = {
75                                 .xform_type = RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED
76                         }, }
77                 },
78         };
79
80         static const struct rte_security_capability
81         txgbe_security_capabilities[] = {
82                 { /* IPsec Inline Crypto ESP Transport Egress */
83                         .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
84                         .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
85                         {.ipsec = {
86                                 .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
87                                 .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
88                                 .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
89                                 .options = { 0 }
90                         } },
91                         .crypto_capabilities = aes_gcm_gmac_crypto_capabilities,
92                         .ol_flags = RTE_SECURITY_TX_OLOAD_NEED_MDATA
93                 },
94                 { /* IPsec Inline Crypto ESP Transport Ingress */
95                         .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
96                         .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
97                         {.ipsec = {
98                                 .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
99                                 .mode = RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
100                                 .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
101                                 .options = { 0 }
102                         } },
103                         .crypto_capabilities = aes_gcm_gmac_crypto_capabilities,
104                         .ol_flags = 0
105                 },
106                 { /* IPsec Inline Crypto ESP Tunnel Egress */
107                         .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
108                         .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
109                         {.ipsec = {
110                                 .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
111                                 .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
112                                 .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
113                                 .options = { 0 }
114                         } },
115                         .crypto_capabilities = aes_gcm_gmac_crypto_capabilities,
116                         .ol_flags = RTE_SECURITY_TX_OLOAD_NEED_MDATA
117                 },
118                 { /* IPsec Inline Crypto ESP Tunnel Ingress */
119                         .action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO,
120                         .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
121                         {.ipsec = {
122                                 .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
123                                 .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
124                                 .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
125                                 .options = { 0 }
126                         } },
127                         .crypto_capabilities = aes_gcm_gmac_crypto_capabilities,
128                         .ol_flags = 0
129                 },
130                 {
131                         .action = RTE_SECURITY_ACTION_TYPE_NONE
132                 }
133         };
134
135         return txgbe_security_capabilities;
136 }
137
138 static struct rte_security_ops txgbe_security_ops = {
139         .capabilities_get = txgbe_crypto_capabilities_get
140 };
141
142 static int
143 txgbe_crypto_capable(struct rte_eth_dev *dev)
144 {
145         struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
146         uint32_t reg_i, reg, capable = 1;
147         /* test if rx crypto can be enabled and then write back initial value*/
148         reg_i = rd32(hw, TXGBE_SECRXCTL);
149         wr32m(hw, TXGBE_SECRXCTL, TXGBE_SECRXCTL_ODSA, 0);
150         reg = rd32m(hw, TXGBE_SECRXCTL, TXGBE_SECRXCTL_ODSA);
151         if (reg != 0)
152                 capable = 0;
153         wr32(hw, TXGBE_SECRXCTL, reg_i);
154         return capable;
155 }
156
157 int
158 txgbe_ipsec_ctx_create(struct rte_eth_dev *dev)
159 {
160         struct rte_security_ctx *ctx = NULL;
161
162         if (txgbe_crypto_capable(dev)) {
163                 ctx = rte_malloc("rte_security_instances_ops",
164                                  sizeof(struct rte_security_ctx), 0);
165                 if (ctx) {
166                         ctx->device = (void *)dev;
167                         ctx->ops = &txgbe_security_ops;
168                         ctx->sess_cnt = 0;
169                         dev->security_ctx = ctx;
170                 } else {
171                         return -ENOMEM;
172                 }
173         }
174         if (rte_security_dynfield_register() < 0)
175                 return -rte_errno;
176         return 0;
177 }