net/virtio: fix incorrect cast of void *
[dpdk.git] / crypto / cnxk / cn10k_ipsec.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include <rte_malloc.h>
6 #include <rte_cryptodev.h>
7 #include <rte_esp.h>
8 #include <rte_ip.h>
9 #include <rte_security.h>
10 #include <rte_security_driver.h>
11 #include <rte_udp.h>
12
13 #include "cnxk_cryptodev.h"
14 #include "cnxk_ipsec.h"
15 #include "cnxk_security.h"
16 #include "cn10k_ipsec.h"
17
18 #include "roc_api.h"
19
20 static uint64_t
21 ipsec_cpt_inst_w7_get(struct roc_cpt *roc_cpt, void *sa)
22 {
23         union cpt_inst_w7 w7;
24
25         w7.u64 = 0;
26         w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
27         w7.s.ctx_val = 1;
28         w7.s.cptr = (uint64_t)sa;
29         rte_mb();
30
31         return w7.u64;
32 }
33
34 static int
35 cn10k_ipsec_outb_sa_create(struct roc_cpt *roc_cpt,
36                            struct rte_security_ipsec_xform *ipsec_xfrm,
37                            struct rte_crypto_sym_xform *crypto_xfrm,
38                            struct rte_security_session *sec_sess)
39 {
40         struct roc_ot_ipsec_outb_sa *out_sa;
41         struct cnxk_ipsec_outb_rlens rlens;
42         struct cn10k_sec_session *sess;
43         struct cn10k_ipsec_sa *sa;
44         union cpt_inst_w4 inst_w4;
45         int ret;
46
47         sess = get_sec_session_private_data(sec_sess);
48         sa = &sess->sa;
49         out_sa = &sa->out_sa;
50
51         memset(out_sa, 0, sizeof(struct roc_ot_ipsec_outb_sa));
52
53         /* Translate security parameters to SA */
54         ret = cnxk_ot_ipsec_outb_sa_fill(out_sa, ipsec_xfrm, crypto_xfrm);
55         if (ret)
56                 return ret;
57
58         sa->inst.w7 = ipsec_cpt_inst_w7_get(roc_cpt, sa);
59
60         /* Get Rlen calculation data */
61         ret = cnxk_ipsec_outb_rlens_get(&rlens, ipsec_xfrm, crypto_xfrm);
62         if (ret)
63                 return ret;
64
65         sa->max_extended_len = rlens.max_extended_len;
66
67         /* pre-populate CPT INST word 4 */
68         inst_w4.u64 = 0;
69         inst_w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_PROCESS_OUTBOUND_IPSEC;
70         inst_w4.s.param1 = 0;
71         sa->inst.w4 = inst_w4.u64;
72
73         return 0;
74 }
75
76 static int
77 cn10k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt,
78                           struct rte_security_ipsec_xform *ipsec_xfrm,
79                           struct rte_crypto_sym_xform *crypto_xfrm,
80                           struct rte_security_session *sec_sess)
81 {
82         struct roc_ot_ipsec_inb_sa *in_sa;
83         struct cn10k_sec_session *sess;
84         struct cn10k_ipsec_sa *sa;
85         union cpt_inst_w4 inst_w4;
86         int ret;
87
88         sess = get_sec_session_private_data(sec_sess);
89         sa = &sess->sa;
90         in_sa = &sa->in_sa;
91
92         /* Translate security parameters to SA */
93         ret = cnxk_ot_ipsec_inb_sa_fill(in_sa, ipsec_xfrm, crypto_xfrm);
94         if (ret)
95                 return ret;
96
97         /* TODO add support for antireplay */
98         sa->in_sa.w0.s.ar_win = 0;
99
100         /* TODO add support for udp encap */
101
102         sa->inst.w7 = ipsec_cpt_inst_w7_get(roc_cpt, sa);
103
104         /* pre-populate CPT INST word 4 */
105         inst_w4.u64 = 0;
106         inst_w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC;
107
108         /* Disable checksum verification for now */
109         inst_w4.s.param1 = 7;
110         sa->inst.w4 = inst_w4.u64;
111
112         return 0;
113 }
114
115 static int
116 cn10k_ipsec_session_create(void *dev,
117                            struct rte_security_ipsec_xform *ipsec_xfrm,
118                            struct rte_crypto_sym_xform *crypto_xfrm,
119                            struct rte_security_session *sess)
120 {
121         struct rte_cryptodev *crypto_dev = dev;
122         struct roc_cpt *roc_cpt;
123         struct cnxk_cpt_vf *vf;
124         int ret;
125
126         vf = crypto_dev->data->dev_private;
127         roc_cpt = &vf->cpt;
128
129         if (crypto_dev->data->queue_pairs[0] == NULL) {
130                 plt_err("Setup cpt queue pair before creating security session");
131                 return -EPERM;
132         }
133
134         ret = cnxk_ipsec_xform_verify(ipsec_xfrm, crypto_xfrm);
135         if (ret)
136                 return ret;
137
138         if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS)
139                 return cn10k_ipsec_inb_sa_create(roc_cpt, ipsec_xfrm,
140                                                  crypto_xfrm, sess);
141         else
142                 return cn10k_ipsec_outb_sa_create(roc_cpt, ipsec_xfrm,
143                                                   crypto_xfrm, sess);
144 }
145
146 static int
147 cn10k_sec_session_create(void *device, struct rte_security_session_conf *conf,
148                          struct rte_security_session *sess,
149                          struct rte_mempool *mempool)
150 {
151         struct cn10k_sec_session *priv;
152         int ret;
153
154         if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL)
155                 return -EINVAL;
156
157         if (rte_mempool_get(mempool, (void **)&priv)) {
158                 plt_err("Could not allocate security session private data");
159                 return -ENOMEM;
160         }
161
162         set_sec_session_private_data(sess, priv);
163
164         if (conf->protocol != RTE_SECURITY_PROTOCOL_IPSEC) {
165                 ret = -ENOTSUP;
166                 goto mempool_put;
167         }
168         ret = cn10k_ipsec_session_create(device, &conf->ipsec,
169                                          conf->crypto_xform, sess);
170         if (ret)
171                 goto mempool_put;
172
173         return 0;
174
175 mempool_put:
176         rte_mempool_put(mempool, priv);
177         set_sec_session_private_data(sess, NULL);
178         return ret;
179 }
180
181 static int
182 cn10k_sec_session_destroy(void *device __rte_unused,
183                           struct rte_security_session *sess)
184 {
185         struct cn10k_sec_session *priv;
186         struct rte_mempool *sess_mp;
187
188         priv = get_sec_session_private_data(sess);
189
190         if (priv == NULL)
191                 return 0;
192
193         sess_mp = rte_mempool_from_obj(priv);
194
195         set_sec_session_private_data(sess, NULL);
196         rte_mempool_put(sess_mp, priv);
197
198         return 0;
199 }
200
201 static unsigned int
202 cn10k_sec_session_get_size(void *device __rte_unused)
203 {
204         return sizeof(struct cn10k_sec_session);
205 }
206
207 /* Update platform specific security ops */
208 void
209 cn10k_sec_ops_override(void)
210 {
211         /* Update platform specific ops */
212         cnxk_sec_ops.session_create = cn10k_sec_session_create;
213         cnxk_sec_ops.session_destroy = cn10k_sec_session_destroy;
214         cnxk_sec_ops.session_get_size = cn10k_sec_session_get_size;
215 }