crypto/octeontx2: enable CPT to share QP with ethdev
[dpdk.git] / drivers / net / octeontx2 / otx2_ethdev_sec.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2020 Marvell International Ltd.
3  */
4
5 #include <rte_cryptodev.h>
6 #include <rte_ethdev.h>
7 #include <rte_eventdev.h>
8 #include <rte_malloc.h>
9 #include <rte_memzone.h>
10 #include <rte_security.h>
11 #include <rte_security_driver.h>
12
13 #include "otx2_cryptodev_qp.h"
14 #include "otx2_ethdev.h"
15 #include "otx2_ethdev_sec.h"
16 #include "otx2_ipsec_fp.h"
17 #include "otx2_sec_idev.h"
18
19 #define ETH_SEC_MAX_PKT_LEN     1450
20
21 struct eth_sec_tag_const {
22         RTE_STD_C11
23         union {
24                 struct {
25                         uint32_t rsvd_11_0  : 12;
26                         uint32_t port       : 8;
27                         uint32_t event_type : 4;
28                         uint32_t rsvd_31_24 : 8;
29                 };
30                 uint32_t u32;
31         };
32 };
33
34 static struct rte_cryptodev_capabilities otx2_eth_sec_crypto_caps[] = {
35         {       /* AES GCM */
36                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
37                 {.sym = {
38                         .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
39                         {.aead = {
40                                 .algo = RTE_CRYPTO_AEAD_AES_GCM,
41                                 .block_size = 16,
42                                 .key_size = {
43                                         .min = 16,
44                                         .max = 32,
45                                         .increment = 8
46                                 },
47                                 .digest_size = {
48                                         .min = 16,
49                                         .max = 16,
50                                         .increment = 0
51                                 },
52                                 .aad_size = {
53                                         .min = 8,
54                                         .max = 12,
55                                         .increment = 4
56                                 },
57                                 .iv_size = {
58                                         .min = 12,
59                                         .max = 12,
60                                         .increment = 0
61                                 }
62                         }, }
63                 }, }
64         },
65         {       /* AES CBC */
66                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
67                 {.sym = {
68                         .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
69                         {.cipher = {
70                                 .algo = RTE_CRYPTO_CIPHER_AES_CBC,
71                                 .block_size = 16,
72                                 .key_size = {
73                                         .min = 16,
74                                         .max = 32,
75                                         .increment = 8
76                                 },
77                                 .iv_size = {
78                                         .min = 16,
79                                         .max = 16,
80                                         .increment = 0
81                                 }
82                         }, }
83                 }, }
84         },
85         {       /* SHA1 HMAC */
86                 .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
87                 {.sym = {
88                         .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
89                         {.auth = {
90                                 .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
91                                 .block_size = 64,
92                                 .key_size = {
93                                         .min = 20,
94                                         .max = 64,
95                                         .increment = 1
96                                 },
97                                 .digest_size = {
98                                         .min = 12,
99                                         .max = 12,
100                                         .increment = 0
101                                 },
102                         }, }
103                 }, }
104         },
105         RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
106 };
107
108 static const struct rte_security_capability otx2_eth_sec_capabilities[] = {
109         {       /* IPsec Inline Protocol ESP Tunnel Ingress */
110                 .action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
111                 .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
112                 .ipsec = {
113                         .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
114                         .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
115                         .direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
116                         .options = { 0 }
117                 },
118                 .crypto_capabilities = otx2_eth_sec_crypto_caps,
119                 .ol_flags = RTE_SECURITY_TX_OLOAD_NEED_MDATA
120         },
121         {       /* IPsec Inline Protocol ESP Tunnel Egress */
122                 .action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
123                 .protocol = RTE_SECURITY_PROTOCOL_IPSEC,
124                 .ipsec = {
125                         .proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
126                         .mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
127                         .direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
128                         .options = { 0 }
129                 },
130                 .crypto_capabilities = otx2_eth_sec_crypto_caps,
131                 .ol_flags = RTE_SECURITY_TX_OLOAD_NEED_MDATA
132         },
133         {
134                 .action = RTE_SECURITY_ACTION_TYPE_NONE
135         }
136 };
137
138 static inline void
139 in_sa_mz_name_get(char *name, int size, uint16_t port)
140 {
141         snprintf(name, size, "otx2_ipsec_in_sadb_%u", port);
142 }
143
144 static unsigned int
145 otx2_eth_sec_session_get_size(void *device __rte_unused)
146 {
147         return sizeof(struct otx2_sec_session);
148 }
149
150 static const struct rte_security_capability *
151 otx2_eth_sec_capabilities_get(void *device __rte_unused)
152 {
153         return otx2_eth_sec_capabilities;
154 }
155
156 static struct rte_security_ops otx2_eth_sec_ops = {
157         .session_get_size       = otx2_eth_sec_session_get_size,
158         .capabilities_get       = otx2_eth_sec_capabilities_get
159 };
160
161 int
162 otx2_eth_sec_ctx_create(struct rte_eth_dev *eth_dev)
163 {
164         struct rte_security_ctx *ctx;
165         int ret;
166
167         ctx = rte_malloc("otx2_eth_sec_ctx",
168                          sizeof(struct rte_security_ctx), 0);
169         if (ctx == NULL)
170                 return -ENOMEM;
171
172         ret = otx2_sec_idev_cfg_init(eth_dev->data->port_id);
173         if (ret) {
174                 rte_free(ctx);
175                 return ret;
176         }
177
178         /* Populate ctx */
179
180         ctx->device = eth_dev;
181         ctx->ops = &otx2_eth_sec_ops;
182         ctx->sess_cnt = 0;
183
184         eth_dev->security_ctx = ctx;
185
186         return 0;
187 }
188
189 void
190 otx2_eth_sec_ctx_destroy(struct rte_eth_dev *eth_dev)
191 {
192         rte_free(eth_dev->security_ctx);
193 }
194
195 static int
196 eth_sec_ipsec_cfg(struct rte_eth_dev *eth_dev, uint8_t tt)
197 {
198         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
199         uint16_t port = eth_dev->data->port_id;
200         struct nix_inline_ipsec_lf_cfg *req;
201         struct otx2_mbox *mbox = dev->mbox;
202         struct eth_sec_tag_const tag_const;
203         char name[RTE_MEMZONE_NAMESIZE];
204         const struct rte_memzone *mz;
205
206         in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
207         mz = rte_memzone_lookup(name);
208         if (mz == NULL)
209                 return -EINVAL;
210
211         req = otx2_mbox_alloc_msg_nix_inline_ipsec_lf_cfg(mbox);
212         req->enable = 1;
213         req->sa_base_addr = mz->iova;
214
215         req->ipsec_cfg0.tt = tt;
216
217         tag_const.u32 = 0;
218         tag_const.event_type = RTE_EVENT_TYPE_ETHDEV;
219         tag_const.port = port;
220         req->ipsec_cfg0.tag_const = tag_const.u32;
221
222         req->ipsec_cfg0.sa_pow2_size =
223                         rte_log2_u32(sizeof(struct otx2_ipsec_fp_in_sa));
224         req->ipsec_cfg0.lenm1_max = ETH_SEC_MAX_PKT_LEN - 1;
225
226         req->ipsec_cfg1.sa_idx_w = rte_log2_u32(dev->ipsec_in_max_spi);
227         req->ipsec_cfg1.sa_idx_max = dev->ipsec_in_max_spi - 1;
228
229         return otx2_mbox_process(mbox);
230 }
231
232 int
233 otx2_eth_sec_init(struct rte_eth_dev *eth_dev)
234 {
235         const size_t sa_width = sizeof(struct otx2_ipsec_fp_in_sa);
236         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
237         uint16_t port = eth_dev->data->port_id;
238         char name[RTE_MEMZONE_NAMESIZE];
239         const struct rte_memzone *mz;
240         int mz_sz, ret;
241         uint16_t nb_sa;
242
243         RTE_BUILD_BUG_ON(sa_width < 32 || sa_width > 512 ||
244                          !RTE_IS_POWER_OF_2(sa_width));
245
246         if (!(dev->tx_offloads & DEV_TX_OFFLOAD_SECURITY) &&
247             !(dev->rx_offloads & DEV_RX_OFFLOAD_SECURITY))
248                 return 0;
249
250         nb_sa = dev->ipsec_in_max_spi;
251         mz_sz = nb_sa * sa_width;
252         in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
253         mz = rte_memzone_reserve_aligned(name, mz_sz, rte_socket_id(),
254                                          RTE_MEMZONE_IOVA_CONTIG, OTX2_ALIGN);
255
256         if (mz == NULL) {
257                 otx2_err("Could not allocate inbound SA DB");
258                 return -ENOMEM;
259         }
260
261         memset(mz->addr, 0, mz_sz);
262
263         ret = eth_sec_ipsec_cfg(eth_dev, SSO_TT_ORDERED);
264         if (ret < 0) {
265                 otx2_err("Could not configure inline IPsec");
266                 goto sec_fini;
267         }
268
269         return 0;
270
271 sec_fini:
272         otx2_err("Could not configure device for security");
273         otx2_eth_sec_fini(eth_dev);
274         return ret;
275 }
276
277 void
278 otx2_eth_sec_fini(struct rte_eth_dev *eth_dev)
279 {
280         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
281         uint16_t port = eth_dev->data->port_id;
282         char name[RTE_MEMZONE_NAMESIZE];
283
284         if (!(dev->tx_offloads & DEV_TX_OFFLOAD_SECURITY) &&
285             !(dev->rx_offloads & DEV_RX_OFFLOAD_SECURITY))
286                 return;
287
288         in_sa_mz_name_get(name, RTE_MEMZONE_NAMESIZE, port);
289         rte_memzone_free(rte_memzone_lookup(name));
290 }