net/cnxk: add TM shaper and node operations
[dpdk.git] / drivers / 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 #ifdef LA_IPSEC_DEBUG
61         /* Use IV from application in debug mode */
62         if (ipsec_xfrm->options.iv_gen_disable == 1) {
63                 out_sa->w2.s.iv_src = ROC_IE_OT_SA_IV_SRC_FROM_SA;
64                 if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
65                         sa->iv_offset = crypto_xfrm->aead.iv.offset;
66                         sa->iv_length = crypto_xfrm->aead.iv.length;
67                 }
68         }
69 #else
70         if (ipsec_xfrm->options.iv_gen_disable != 0) {
71                 plt_err("Application provided IV not supported");
72                 return -ENOTSUP;
73         }
74 #endif
75
76         /* Get Rlen calculation data */
77         ret = cnxk_ipsec_outb_rlens_get(&rlens, ipsec_xfrm, crypto_xfrm);
78         if (ret)
79                 return ret;
80
81         sa->max_extended_len = rlens.max_extended_len;
82
83         /* pre-populate CPT INST word 4 */
84         inst_w4.u64 = 0;
85         inst_w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_PROCESS_OUTBOUND_IPSEC;
86         inst_w4.s.param1 = 0;
87         sa->inst.w4 = inst_w4.u64;
88
89         return 0;
90 }
91
92 static int
93 cn10k_ipsec_inb_sa_create(struct roc_cpt *roc_cpt,
94                           struct rte_security_ipsec_xform *ipsec_xfrm,
95                           struct rte_crypto_sym_xform *crypto_xfrm,
96                           struct rte_security_session *sec_sess)
97 {
98         struct roc_ot_ipsec_inb_sa *in_sa;
99         struct cn10k_sec_session *sess;
100         struct cn10k_ipsec_sa *sa;
101         union cpt_inst_w4 inst_w4;
102         int ret;
103
104         sess = get_sec_session_private_data(sec_sess);
105         sa = &sess->sa;
106         in_sa = &sa->in_sa;
107
108         /* Translate security parameters to SA */
109         ret = cnxk_ot_ipsec_inb_sa_fill(in_sa, ipsec_xfrm, crypto_xfrm);
110         if (ret)
111                 return ret;
112
113         /* TODO add support for antireplay */
114         sa->in_sa.w0.s.ar_win = 0;
115
116         /* TODO add support for udp encap */
117
118         sa->inst.w7 = ipsec_cpt_inst_w7_get(roc_cpt, sa);
119
120         /* pre-populate CPT INST word 4 */
121         inst_w4.u64 = 0;
122         inst_w4.s.opcode_major = ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC;
123
124         /* Disable checksum verification for now */
125         inst_w4.s.param1 = 7;
126         sa->inst.w4 = inst_w4.u64;
127
128         return 0;
129 }
130
131 static int
132 cn10k_ipsec_session_create(void *dev,
133                            struct rte_security_ipsec_xform *ipsec_xfrm,
134                            struct rte_crypto_sym_xform *crypto_xfrm,
135                            struct rte_security_session *sess)
136 {
137         struct rte_cryptodev *crypto_dev = dev;
138         struct roc_cpt *roc_cpt;
139         struct cnxk_cpt_vf *vf;
140         int ret;
141
142         vf = crypto_dev->data->dev_private;
143         roc_cpt = &vf->cpt;
144
145         if (crypto_dev->data->queue_pairs[0] == NULL) {
146                 plt_err("Setup cpt queue pair before creating security session");
147                 return -EPERM;
148         }
149
150         ret = cnxk_ipsec_xform_verify(ipsec_xfrm, crypto_xfrm);
151         if (ret)
152                 return ret;
153
154         if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS)
155                 return cn10k_ipsec_inb_sa_create(roc_cpt, ipsec_xfrm,
156                                                  crypto_xfrm, sess);
157         else
158                 return cn10k_ipsec_outb_sa_create(roc_cpt, ipsec_xfrm,
159                                                   crypto_xfrm, sess);
160 }
161
162 static int
163 cn10k_sec_session_create(void *device, struct rte_security_session_conf *conf,
164                          struct rte_security_session *sess,
165                          struct rte_mempool *mempool)
166 {
167         struct cn10k_sec_session *priv;
168         int ret;
169
170         if (conf->action_type != RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL)
171                 return -EINVAL;
172
173         if (rte_mempool_get(mempool, (void **)&priv)) {
174                 plt_err("Could not allocate security session private data");
175                 return -ENOMEM;
176         }
177
178         set_sec_session_private_data(sess, priv);
179
180         if (conf->protocol != RTE_SECURITY_PROTOCOL_IPSEC) {
181                 ret = -ENOTSUP;
182                 goto mempool_put;
183         }
184         ret = cn10k_ipsec_session_create(device, &conf->ipsec,
185                                          conf->crypto_xform, sess);
186         if (ret)
187                 goto mempool_put;
188
189         return 0;
190
191 mempool_put:
192         rte_mempool_put(mempool, priv);
193         set_sec_session_private_data(sess, NULL);
194         return ret;
195 }
196
197 static int
198 cn10k_sec_session_destroy(void *device __rte_unused,
199                           struct rte_security_session *sess)
200 {
201         struct cn10k_sec_session *priv;
202         struct rte_mempool *sess_mp;
203
204         priv = get_sec_session_private_data(sess);
205
206         if (priv == NULL)
207                 return 0;
208
209         sess_mp = rte_mempool_from_obj(priv);
210
211         set_sec_session_private_data(sess, NULL);
212         rte_mempool_put(sess_mp, priv);
213
214         return 0;
215 }
216
217 static unsigned int
218 cn10k_sec_session_get_size(void *device __rte_unused)
219 {
220         return sizeof(struct cn10k_sec_session);
221 }
222
223 /* Update platform specific security ops */
224 void
225 cn10k_sec_ops_override(void)
226 {
227         /* Update platform specific ops */
228         cnxk_sec_ops.session_create = cn10k_sec_session_create;
229         cnxk_sec_ops.session_destroy = cn10k_sec_session_destroy;
230         cnxk_sec_ops.session_get_size = cn10k_sec_session_get_size;
231 }