Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <eal_export.h>
6 : : #include <rte_cryptodev.h>
7 : : #include <cryptodev_pmd.h>
8 : : #include <rte_event_crypto_adapter.h>
9 : : #include <rte_ip.h>
10 : : #include <rte_vect.h>
11 : :
12 : : #include "roc_api.h"
13 : :
14 : : #include "cn9k_cryptodev.h"
15 : : #include "cn9k_cryptodev_ops.h"
16 : : #include "cn9k_ipsec.h"
17 : : #include "cn9k_ipsec_la_ops.h"
18 : : #include "cnxk_ae.h"
19 : : #include "cnxk_cryptodev.h"
20 : : #include "cnxk_cryptodev_ops.h"
21 : : #include "cnxk_se.h"
22 : :
23 : : static __rte_always_inline int __rte_hot
24 : : cn9k_cpt_sec_inst_fill(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
25 : : struct cpt_inflight_req *infl_req, struct cpt_inst_s *inst)
26 : : {
27 : : struct rte_crypto_sym_op *sym_op = op->sym;
28 : : struct cn9k_sec_session *sec_sess;
29 : :
30 : 0 : sec_sess = (struct cn9k_sec_session *)(op->sym->session);
31 : :
32 [ # # # # ]: 0 : if (unlikely(sym_op->m_dst && sym_op->m_dst != sym_op->m_src)) {
33 : 0 : plt_dp_err("Out of place is not supported");
34 : 0 : return -ENOTSUP;
35 : : }
36 : :
37 [ # # ]: 0 : if (sec_sess->is_outbound)
38 : : return process_outb_sa(&qp->meta_info, op, sec_sess, inst, infl_req);
39 : : else
40 : : return process_inb_sa(&qp->meta_info, op, sec_sess, inst, infl_req);
41 : : }
42 : :
43 : : static inline struct cnxk_se_sess *
44 : 0 : cn9k_cpt_sym_temp_sess_create(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op)
45 : : {
46 : : struct rte_crypto_sym_op *sym_op = op->sym;
47 : : struct rte_cryptodev_sym_session *sess;
48 : : struct cnxk_se_sess *priv;
49 : : int ret;
50 : :
51 : : /* Create temporary session */
52 [ # # # # ]: 0 : if (rte_mempool_get(qp->sess_mp, (void **)&sess) < 0)
53 : : return NULL;
54 : :
55 : 0 : ret = sym_session_configure(qp->lf.roc_cpt, sym_op->xform, sess, true);
56 [ # # ]: 0 : if (ret)
57 : 0 : goto sess_put;
58 : :
59 : 0 : priv = (struct cnxk_se_sess *)sess;
60 : :
61 : 0 : sym_op->session = sess;
62 : :
63 : 0 : return priv;
64 : :
65 : : sess_put:
66 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, sess);
67 : 0 : return NULL;
68 : : }
69 : :
70 : : static inline struct cnxk_ae_sess *
71 : 0 : cn9k_cpt_asym_temp_sess_create(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op)
72 : : {
73 : : struct rte_crypto_asym_op *asym_op = op->asym;
74 : 0 : struct roc_cpt *roc_cpt = qp->lf.roc_cpt;
75 : : struct rte_cryptodev_asym_session *sess;
76 : : struct cnxk_ae_sess *priv;
77 : : struct cnxk_cpt_vf *vf;
78 : : union cpt_inst_w7 w7;
79 : :
80 : : /* Create temporary session */
81 [ # # # # ]: 0 : if (rte_mempool_get(qp->sess_mp, (void **)&sess) < 0)
82 : : return NULL;
83 : :
84 : 0 : priv = (struct cnxk_ae_sess *)sess;
85 : 0 : if (cnxk_ae_fill_session_parameters(priv, asym_op->xform))
86 : 0 : goto sess_put;
87 : :
88 : 0 : priv->lf = &qp->lf;
89 : :
90 : 0 : w7.u64 = 0;
91 : 0 : w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_AE];
92 : :
93 : 0 : vf = container_of(roc_cpt, struct cnxk_cpt_vf, cpt);
94 : 0 : priv->cpt_inst_w7 = w7.u64;
95 : 0 : priv->cnxk_fpm_iova = vf->cnxk_fpm_iova;
96 : 0 : priv->ec_grp = vf->ec_grp;
97 : :
98 : 0 : asym_op->session = sess;
99 : :
100 : 0 : return priv;
101 : :
102 : : sess_put:
103 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, sess);
104 : 0 : return NULL;
105 : : }
106 : :
107 : : static inline int
108 : 0 : cn9k_cpt_inst_prep(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
109 : : struct cpt_inflight_req *infl_req, struct cpt_inst_s *inst)
110 : : {
111 : : int ret;
112 : :
113 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
114 : : struct rte_crypto_sym_op *sym_op;
115 : : struct cnxk_se_sess *sess;
116 : :
117 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
118 : : sym_op = op->sym;
119 [ # # ]: 0 : sess = (struct cnxk_se_sess *)sym_op->session;
120 : : ret = cpt_sym_inst_fill(qp, op, sess, infl_req, inst, false);
121 : 0 : inst->w7.u64 = sess->cpt_inst_w7;
122 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION)
123 : : ret = cn9k_cpt_sec_inst_fill(qp, op, infl_req, inst);
124 : : else {
125 : 0 : sess = cn9k_cpt_sym_temp_sess_create(qp, op);
126 [ # # ]: 0 : if (unlikely(sess == NULL)) {
127 : 0 : plt_dp_err("Could not create temp session");
128 : 0 : return -1;
129 : : }
130 : :
131 : : ret = cpt_sym_inst_fill(qp, op, sess, infl_req, inst, false);
132 [ # # ]: 0 : if (unlikely(ret)) {
133 : 0 : sym_session_clear(op->sym->session, true);
134 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, op->sym->session);
135 : : }
136 : 0 : inst->w7.u64 = sess->cpt_inst_w7;
137 : : }
138 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
139 : : struct cnxk_ae_sess *sess;
140 : :
141 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
142 [ # # ]: 0 : sess = (struct cnxk_ae_sess *)op->asym->session;
143 : : ret = cnxk_ae_enqueue(qp, op, infl_req, inst, sess);
144 : 0 : inst->w7.u64 = sess->cpt_inst_w7;
145 : : } else {
146 : 0 : sess = cn9k_cpt_asym_temp_sess_create(qp, op);
147 [ # # ]: 0 : if (unlikely(sess == NULL)) {
148 : 0 : plt_dp_err("Could not create temp session");
149 : 0 : return 0;
150 : : }
151 : :
152 : : ret = cnxk_ae_enqueue(qp, op, infl_req, inst, sess);
153 [ # # ]: 0 : if (unlikely(ret)) {
154 : 0 : cnxk_ae_session_clear(NULL,
155 : : (struct rte_cryptodev_asym_session *)sess);
156 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, sess);
157 : 0 : return 0;
158 : : }
159 : 0 : inst->w7.u64 = sess->cpt_inst_w7;
160 : : }
161 : : } else {
162 : : ret = -EINVAL;
163 : 0 : plt_dp_err("Unsupported op type");
164 : : }
165 : :
166 : : return ret;
167 : : }
168 : :
169 : : static uint16_t
170 : 0 : cn9k_cpt_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
171 : : {
172 : : struct cpt_inflight_req *infl_req_1, *infl_req_2;
173 : : alignas(RTE_CACHE_LINE_SIZE) struct cpt_inst_s inst[2];
174 : : struct rte_crypto_op *op_1, *op_2;
175 : : uint16_t nb_allowed, count = 0;
176 : : struct cnxk_cpt_qp *qp = qptr;
177 : : struct pending_queue *pend_q;
178 : : uint64_t head;
179 : : int ret;
180 : :
181 : : const union cpt_res_s res = {
182 : : .cn10k.compcode = CPT_COMP_NOT_DONE,
183 : : };
184 : :
185 : 0 : pend_q = &qp->pend_q;
186 : : rte_prefetch2(pend_q);
187 : :
188 : : /* Clear w0, w2, w3 of both inst */
189 : :
190 : : #if defined(RTE_ARCH_ARM64)
191 : : uint64x2_t zero = vdupq_n_u64(0);
192 : :
193 : : vst1q_u64(&inst[0].w0.u64, zero);
194 : : vst1q_u64(&inst[1].w0.u64, zero);
195 : : vst1q_u64(&inst[0].w2.u64, zero);
196 : : vst1q_u64(&inst[1].w2.u64, zero);
197 : : #else
198 : 0 : inst[0].w0.u64 = 0;
199 : 0 : inst[0].w2.u64 = 0;
200 : 0 : inst[0].w3.u64 = 0;
201 : 0 : inst[1].w0.u64 = 0;
202 : 0 : inst[1].w2.u64 = 0;
203 : 0 : inst[1].w3.u64 = 0;
204 : : #endif
205 : :
206 : : const uint64_t lmt_base = qp->lf.lmt_base;
207 : : const uint64_t io_addr = qp->lf.io_addr;
208 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
209 : :
210 : 0 : head = pend_q->head;
211 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
212 : 0 : nb_ops = RTE_MIN(nb_ops, nb_allowed);
213 : :
214 [ # # ]: 0 : if (unlikely(nb_ops & 1)) {
215 : 0 : op_1 = ops[0];
216 : 0 : infl_req_1 = &pend_q->req_queue[head];
217 : 0 : infl_req_1->op_flags = 0;
218 : :
219 : 0 : ret = cn9k_cpt_inst_prep(qp, op_1, infl_req_1, &inst[0]);
220 [ # # ]: 0 : if (unlikely(ret)) {
221 : 0 : plt_dp_err("Could not process op: %p", op_1);
222 : 0 : return 0;
223 : : }
224 : :
225 : 0 : infl_req_1->cop = op_1;
226 : 0 : infl_req_1->res.cn9k.compcode = CPT_COMP_NOT_DONE;
227 : 0 : inst[0].res_addr = (uint64_t)&infl_req_1->res;
228 : :
229 : : cn9k_cpt_inst_submit(&inst[0], lmt_base, io_addr);
230 : : pending_queue_advance(&head, pq_mask);
231 : : count++;
232 : : }
233 : :
234 [ # # ]: 0 : while (count < nb_ops) {
235 : 0 : op_1 = ops[count];
236 : 0 : op_2 = ops[count + 1];
237 : :
238 : 0 : infl_req_1 = &pend_q->req_queue[head];
239 : : pending_queue_advance(&head, pq_mask);
240 : 0 : infl_req_2 = &pend_q->req_queue[head];
241 : : pending_queue_advance(&head, pq_mask);
242 : :
243 : 0 : infl_req_1->cop = op_1;
244 : 0 : infl_req_2->cop = op_2;
245 : 0 : infl_req_1->op_flags = 0;
246 : 0 : infl_req_2->op_flags = 0;
247 : :
248 : 0 : rte_atomic_store_explicit((uint64_t __rte_atomic *)&infl_req_1->res.u64[0],
249 : : res.u64[0], rte_memory_order_relaxed);
250 : 0 : inst[0].res_addr = (uint64_t)&infl_req_1->res;
251 : :
252 : 0 : rte_atomic_store_explicit((uint64_t __rte_atomic *)&infl_req_2->res.u64[0],
253 : : res.u64[0], rte_memory_order_relaxed);
254 : 0 : inst[1].res_addr = (uint64_t)&infl_req_2->res;
255 : :
256 : 0 : ret = cn9k_cpt_inst_prep(qp, op_1, infl_req_1, &inst[0]);
257 [ # # ]: 0 : if (unlikely(ret)) {
258 : 0 : plt_dp_err("Could not process op: %p", op_1);
259 : : pending_queue_retreat(&head, pq_mask, 2);
260 : : break;
261 : : }
262 : :
263 : 0 : ret = cn9k_cpt_inst_prep(qp, op_2, infl_req_2, &inst[1]);
264 [ # # ]: 0 : if (unlikely(ret)) {
265 : 0 : plt_dp_err("Could not process op: %p", op_2);
266 : : pending_queue_retreat(&head, pq_mask, 1);
267 : : cn9k_cpt_inst_submit(&inst[0], lmt_base, io_addr);
268 : : count++;
269 : : break;
270 : : }
271 : :
272 : : cn9k_cpt_inst_submit_dual(&inst[0], lmt_base, io_addr);
273 : :
274 : : count += 2;
275 : : }
276 : :
277 : : rte_atomic_thread_fence(rte_memory_order_release);
278 : :
279 : 0 : pend_q->head = head;
280 : 0 : pend_q->time_out = rte_get_timer_cycles() +
281 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
282 : :
283 : 0 : return count;
284 : : }
285 : :
286 : : static int
287 : 0 : cn9k_cpt_crypto_adapter_ev_mdata_set(struct rte_cryptodev *dev __rte_unused,
288 : : void *sess,
289 : : enum rte_crypto_op_type op_type,
290 : : enum rte_crypto_op_sess_type sess_type,
291 : : void *mdata)
292 : : {
293 : : union rte_event_crypto_metadata *ec_mdata = mdata;
294 : : struct rte_event *rsp_info;
295 : : struct cnxk_cpt_qp *qp;
296 : : uint8_t cdev_id;
297 : : uint16_t qp_id;
298 : : uint64_t w2;
299 : :
300 : : /* Get queue pair */
301 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
302 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
303 : 0 : qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
304 : :
305 : : /* Prepare w2 */
306 : : rsp_info = &ec_mdata->response_info;
307 : 0 : w2 = CNXK_CPT_INST_W2((RTE_EVENT_TYPE_CRYPTODEV << 28) |
308 : : (rsp_info->sub_event_type << 20) |
309 : : rsp_info->flow_id,
310 : : rsp_info->sched_type, rsp_info->queue_id, 0);
311 : :
312 : : /* Set meta according to session type */
313 [ # # ]: 0 : if (op_type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
314 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
315 : : struct cn9k_sec_session *priv;
316 : :
317 : : priv = (struct cn9k_sec_session *)sess;
318 : 0 : priv->qp = qp;
319 : 0 : priv->inst.w2 = w2;
320 [ # # ]: 0 : } else if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
321 : : struct cnxk_se_sess *priv;
322 : :
323 : : priv = (struct cnxk_se_sess *)sess;
324 : 0 : priv->qp = qp;
325 : 0 : priv->cpt_inst_w2 = w2;
326 : : } else
327 : : return -EINVAL;
328 [ # # ]: 0 : } else if (op_type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
329 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
330 : : struct rte_cryptodev_asym_session *asym_sess = sess;
331 : : struct cnxk_ae_sess *priv;
332 : :
333 : : priv = (struct cnxk_ae_sess *)asym_sess;
334 : 0 : priv->qp = qp;
335 : 0 : priv->cpt_inst_w2 = w2;
336 : : } else
337 : : return -EINVAL;
338 : : } else
339 : : return -EINVAL;
340 : :
341 : : return 0;
342 : : }
343 : :
344 : : static inline int
345 : 0 : cn9k_ca_meta_info_extract(struct rte_crypto_op *op,
346 : : struct cnxk_cpt_qp **qp, struct cpt_inst_s *inst)
347 : : {
348 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
349 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
350 : : struct cn9k_sec_session *priv;
351 : :
352 : 0 : priv = (struct cn9k_sec_session *)(op->sym->session);
353 : 0 : *qp = priv->qp;
354 : 0 : inst->w2.u64 = priv->inst.w2;
355 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
356 : : struct cnxk_se_sess *priv;
357 : :
358 : 0 : priv = (struct cnxk_se_sess *)op->sym->session;
359 : 0 : *qp = priv->qp;
360 : 0 : inst->w2.u64 = priv->cpt_inst_w2;
361 : : } else {
362 : : union rte_event_crypto_metadata *ec_mdata;
363 : : struct rte_event *rsp_info;
364 : : uint8_t cdev_id;
365 : : uint16_t qp_id;
366 : :
367 [ # # ]: 0 : if (unlikely(op->private_data_offset == 0))
368 : : return -EINVAL;
369 : 0 : ec_mdata = (union rte_event_crypto_metadata *)
370 : 0 : ((uint8_t *)op + op->private_data_offset);
371 : : rsp_info = &ec_mdata->response_info;
372 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
373 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
374 : 0 : *qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
375 : 0 : inst->w2.u64 = CNXK_CPT_INST_W2(
376 : : (RTE_EVENT_TYPE_CRYPTODEV << 28) | rsp_info->flow_id,
377 : : rsp_info->sched_type, rsp_info->queue_id, 0);
378 : : }
379 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
380 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
381 : : struct cnxk_ae_sess *priv;
382 : :
383 : 0 : priv = (struct cnxk_ae_sess *)op->asym->session;
384 : 0 : *qp = priv->qp;
385 : 0 : inst->w2.u64 = priv->cpt_inst_w2;
386 : : } else {
387 : : union rte_event_crypto_metadata *ec_mdata;
388 : : struct rte_event *rsp_info;
389 : : uint8_t cdev_id;
390 : : uint16_t qp_id;
391 : :
392 [ # # ]: 0 : if (unlikely(op->private_data_offset == 0))
393 : : return -EINVAL;
394 : 0 : ec_mdata = (union rte_event_crypto_metadata *)((uint8_t *)op +
395 : 0 : op->private_data_offset);
396 : : rsp_info = &ec_mdata->response_info;
397 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
398 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
399 : 0 : *qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
400 : 0 : inst->w2.u64 = CNXK_CPT_INST_W2(
401 : : (RTE_EVENT_TYPE_CRYPTODEV << 28) | rsp_info->flow_id,
402 : : rsp_info->sched_type, rsp_info->queue_id, 0);
403 : : }
404 : : } else
405 : : return -EINVAL;
406 : :
407 : : return 0;
408 : : }
409 : :
410 : : RTE_EXPORT_INTERNAL_SYMBOL(cn9k_cpt_crypto_adapter_enqueue)
411 : : uint16_t
412 : 0 : cn9k_cpt_crypto_adapter_enqueue(uintptr_t base, struct rte_crypto_op *op)
413 : : {
414 : : struct cpt_inflight_req *infl_req;
415 : : uint64_t __rte_atomic *fc_addr;
416 : : union cpt_fc_write_s fc;
417 : : struct cnxk_cpt_qp *qp;
418 : : struct cpt_inst_s inst;
419 : : int ret;
420 : :
421 : 0 : ret = cn9k_ca_meta_info_extract(op, &qp, &inst);
422 [ # # ]: 0 : if (unlikely(ret)) {
423 : 0 : rte_errno = EINVAL;
424 : 0 : return 0;
425 : : }
426 : :
427 [ # # ]: 0 : if (unlikely(!qp->ca.enabled)) {
428 : 0 : rte_errno = EINVAL;
429 : 0 : return 0;
430 : : }
431 : :
432 [ # # # # ]: 0 : if (unlikely(rte_mempool_get(qp->ca.req_mp, (void **)&infl_req))) {
433 : 0 : rte_errno = ENOMEM;
434 : 0 : return 0;
435 : : }
436 : 0 : infl_req->op_flags = 0;
437 : :
438 : 0 : ret = cn9k_cpt_inst_prep(qp, op, infl_req, &inst);
439 [ # # ]: 0 : if (unlikely(ret)) {
440 : 0 : plt_dp_err("Could not process op: %p", op);
441 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
442 : 0 : return 0;
443 : : }
444 : :
445 : 0 : infl_req->cop = op;
446 : 0 : infl_req->res.cn9k.compcode = CPT_COMP_NOT_DONE;
447 : 0 : infl_req->qp = qp;
448 : 0 : inst.w0.u64 = 0;
449 : 0 : inst.res_addr = (uint64_t)&infl_req->res;
450 : 0 : inst.w3.u64 = CNXK_CPT_INST_W3(1, infl_req);
451 : :
452 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
453 : :
454 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
455 : :
456 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
457 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
458 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
459 : 0 : rte_errno = EAGAIN;
460 : 0 : return 0;
461 : : }
462 : :
463 [ # # ]: 0 : if (inst.w2.s.tt == RTE_SCHED_TYPE_ORDERED)
464 : : roc_sso_hws_head_wait(base);
465 : :
466 : : cn9k_cpt_inst_submit(&inst, qp->lmtline.lmt_base, qp->lmtline.io_addr);
467 : :
468 : : return 1;
469 : : }
470 : :
471 : : static inline int
472 : 0 : ipsec_antireplay_check(struct cn9k_sec_session *sess, uint32_t win_sz,
473 : : struct roc_ie_on_inb_hdr *data)
474 : : {
475 : : uint32_t esn_low, esn_hi, seql, seqh = 0;
476 : : struct roc_ie_on_common_sa *common_sa;
477 : : struct roc_ie_on_inb_sa *in_sa;
478 : : uint64_t seq, seq_in_sa;
479 : : uint8_t esn;
480 : : int ret;
481 : :
482 : : in_sa = &sess->sa.in_sa;
483 : : common_sa = &in_sa->common_sa;
484 : :
485 : 0 : esn = common_sa->ctl.esn_en;
486 [ # # ]: 0 : seql = rte_be_to_cpu_32(data->seql);
487 : :
488 [ # # ]: 0 : if (!esn) {
489 : 0 : seq = (uint64_t)seql;
490 : : } else {
491 [ # # ]: 0 : seqh = rte_be_to_cpu_32(data->seqh);
492 : 0 : seq = ((uint64_t)seqh << 32) | seql;
493 : : }
494 : :
495 [ # # ]: 0 : if (unlikely(seq == 0))
496 : : return IPSEC_ANTI_REPLAY_FAILED;
497 : :
498 : 0 : rte_spinlock_lock(&sess->ar.lock);
499 : 0 : ret = cnxk_on_anti_replay_check(seq, &sess->ar, win_sz);
500 [ # # ]: 0 : if (esn && !ret) {
501 [ # # ]: 0 : esn_low = rte_be_to_cpu_32(common_sa->seq_t.tl);
502 [ # # ]: 0 : esn_hi = rte_be_to_cpu_32(common_sa->seq_t.th);
503 : 0 : seq_in_sa = ((uint64_t)esn_hi << 32) | esn_low;
504 [ # # ]: 0 : if (seq > seq_in_sa) {
505 [ # # ]: 0 : common_sa->seq_t.tl = rte_cpu_to_be_32(seql);
506 [ # # ]: 0 : common_sa->seq_t.th = rte_cpu_to_be_32(seqh);
507 : : }
508 : : }
509 : : rte_spinlock_unlock(&sess->ar.lock);
510 : :
511 : 0 : return ret;
512 : : }
513 : :
514 : : static inline void
515 : 0 : cn9k_cpt_sec_post_process(struct rte_crypto_op *cop,
516 : : struct cpt_inflight_req *infl_req)
517 : : {
518 : : struct rte_crypto_sym_op *sym_op = cop->sym;
519 : 0 : struct rte_mbuf *m = sym_op->m_src;
520 : : struct roc_ie_on_inb_hdr *hdr;
521 : : struct cn9k_sec_session *priv;
522 : : struct rte_ipv6_hdr *ip6;
523 : : struct rte_ipv4_hdr *ip;
524 : : uint16_t m_len = 0;
525 : :
526 [ # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_IPSEC_DIR_INBOUND) {
527 : :
528 : 0 : hdr = rte_pktmbuf_mtod(m, struct roc_ie_on_inb_hdr *);
529 : :
530 [ # # ]: 0 : if (likely(m->next == NULL)) {
531 : 0 : ip = PLT_PTR_ADD(hdr, ROC_IE_ON_INB_RPTR_HDR);
532 : : } else {
533 : : ip = (struct rte_ipv4_hdr *)hdr;
534 : 0 : hdr = infl_req->mdata;
535 : : }
536 : :
537 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_IPSEC_INB_REPLAY)) {
538 : : int ret;
539 : :
540 : 0 : priv = (struct cn9k_sec_session *)(sym_op->session);
541 : :
542 : 0 : ret = ipsec_antireplay_check(priv, priv->replay_win_sz, hdr);
543 [ # # ]: 0 : if (unlikely(ret)) {
544 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
545 : 0 : return;
546 : : }
547 : : }
548 : :
549 [ # # ]: 0 : if (ip->version == IPVERSION) {
550 [ # # ]: 0 : m_len = rte_be_to_cpu_16(ip->total_length);
551 : : } else {
552 : : PLT_ASSERT((ip->version == 6));
553 : : ip6 = (struct rte_ipv6_hdr *)ip;
554 [ # # ]: 0 : m_len = rte_be_to_cpu_16(ip6->payload_len) + sizeof(struct rte_ipv6_hdr);
555 : : }
556 : :
557 [ # # ]: 0 : if (likely(m->next == NULL)) {
558 : 0 : m->data_len = m_len;
559 : 0 : m->pkt_len = m_len;
560 : :
561 : 0 : m->data_off += ROC_IE_ON_INB_RPTR_HDR;
562 : : } else {
563 : : struct rte_mbuf *temp = m;
564 : 0 : uint8_t m_len_s = m_len;
565 : :
566 [ # # ]: 0 : while (m_len_s - temp->data_len > 0) {
567 : 0 : m_len_s -= temp->data_len;
568 : 0 : temp = temp->next;
569 : : }
570 : :
571 : 0 : temp->data_len = m_len_s;
572 : 0 : m->pkt_len = m_len;
573 : : }
574 : : }
575 : : }
576 : :
577 : : static inline void
578 : 0 : cn9k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp, struct rte_crypto_op *cop,
579 : : struct cpt_inflight_req *infl_req,
580 : : struct cpt_cn9k_res_s *res)
581 : : {
582 [ # # ]: 0 : if (likely(res->compcode == CPT_COMP_GOOD)) {
583 [ # # ]: 0 : if (unlikely(res->uc_compcode)) {
584 [ # # ]: 0 : if (res->uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
585 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
586 [ # # ]: 0 : else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC &&
587 : : cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
588 : : struct cnxk_ae_sess *sess;
589 : :
590 : 0 : sess = (struct cnxk_ae_sess *)cop->asym->session;
591 [ # # ]: 0 : if (sess->xfrm_type == RTE_CRYPTO_ASYM_XFORM_ECDH &&
592 [ # # ]: 0 : cop->asym->ecdh.ke_type == RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY) {
593 [ # # ]: 0 : if (res->uc_compcode == ROC_AE_ERR_ECC_POINT_NOT_ON_CURVE) {
594 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
595 : 0 : return;
596 [ # # ]: 0 : } else if (res->uc_compcode == ROC_AE_ERR_ECC_PAI) {
597 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
598 : 0 : return;
599 : : }
600 : : } else {
601 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
602 : : }
603 : : } else
604 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
605 : :
606 : 0 : plt_dp_info("Request failed with microcode error");
607 : 0 : plt_dp_info("MC completion code 0x%x",
608 : : res->uc_compcode);
609 : 0 : goto temp_sess_free;
610 : : }
611 : :
612 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
613 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
614 [ # # ]: 0 : if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
615 : 0 : cn9k_cpt_sec_post_process(cop, infl_req);
616 : 0 : return;
617 : : }
618 : :
619 : : /* Verify authentication data if required */
620 [ # # ]: 0 : if (unlikely(infl_req->op_flags &
621 : : CPT_OP_FLAGS_AUTH_VERIFY)) {
622 : 0 : uintptr_t *rsp = infl_req->mdata;
623 [ # # ]: 0 : compl_auth_verify(cop, (uint8_t *)rsp[0],
624 : : rsp[1]);
625 : : }
626 [ # # ]: 0 : } else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
627 : : struct rte_crypto_asym_op *op = cop->asym;
628 : 0 : uintptr_t *mdata = infl_req->mdata;
629 : 0 : struct cnxk_ae_sess *sess = (struct cnxk_ae_sess *)op->session;
630 : :
631 [ # # # # : 0 : cnxk_ae_post_process(cop, sess, (uint8_t *)mdata[0]);
# # # # ]
632 : : }
633 : : } else {
634 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
635 : 0 : plt_dp_info("HW completion code 0x%x", res->compcode);
636 : :
637 [ # # # # ]: 0 : switch (res->compcode) {
638 : 0 : case CPT_COMP_INSTERR:
639 : 0 : plt_dp_err("Request failed with instruction error");
640 : 0 : break;
641 : 0 : case CPT_COMP_FAULT:
642 : 0 : plt_dp_err("Request failed with DMA fault");
643 : 0 : break;
644 : 0 : case CPT_COMP_HWERR:
645 : 0 : plt_dp_err("Request failed with hardware error");
646 : 0 : break;
647 : 0 : default:
648 : 0 : plt_dp_err(
649 : : "Request failed with unknown completion code");
650 : : }
651 : : }
652 : :
653 : 0 : temp_sess_free:
654 [ # # ]: 0 : if (unlikely(cop->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {
655 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
656 : 0 : sym_session_clear(cop->sym->session, true);
657 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, cop->sym->session);
658 : 0 : cop->sym->session = NULL;
659 : : }
660 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
661 : 0 : cnxk_ae_session_clear(NULL, cop->asym->session);
662 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, cop->asym->session);
663 : 0 : cop->asym->session = NULL;
664 : : }
665 : : }
666 : : }
667 : :
668 : : RTE_EXPORT_INTERNAL_SYMBOL(cn9k_cpt_crypto_adapter_dequeue)
669 : : uintptr_t
670 : 0 : cn9k_cpt_crypto_adapter_dequeue(uintptr_t get_work1)
671 : : {
672 : : struct cpt_inflight_req *infl_req;
673 : : struct rte_crypto_op *cop;
674 : : struct cnxk_cpt_qp *qp;
675 : : union cpt_res_s res;
676 : :
677 : 0 : infl_req = (struct cpt_inflight_req *)(get_work1);
678 : 0 : cop = infl_req->cop;
679 : 0 : qp = infl_req->qp;
680 : :
681 : 0 : res.u64[0] = rte_atomic_load_explicit((uint64_t __rte_atomic *)&infl_req->res.u64[0],
682 : : rte_memory_order_relaxed);
683 : :
684 : 0 : cn9k_cpt_dequeue_post_process(qp, infl_req->cop, infl_req, &res.cn9k);
685 : :
686 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
687 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
688 : :
689 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
690 : 0 : return (uintptr_t)cop;
691 : : }
692 : :
693 : : static uint16_t
694 : 0 : cn9k_cpt_dequeue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
695 : : {
696 : : struct cpt_inflight_req *infl_req;
697 : : struct cnxk_cpt_qp *qp = qptr;
698 : : struct pending_queue *pend_q;
699 : : uint64_t infl_cnt, pq_tail;
700 : : struct rte_crypto_op *cop;
701 : : union cpt_res_s res;
702 : : int i;
703 : :
704 : : pend_q = &qp->pend_q;
705 : :
706 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
707 : :
708 : 0 : pq_tail = pend_q->tail;
709 : 0 : infl_cnt = pending_queue_infl_cnt(pend_q->head, pq_tail, pq_mask);
710 : 0 : nb_ops = RTE_MIN(nb_ops, infl_cnt);
711 : :
712 : : /* Ensure infl_cnt isn't read before data lands */
713 : : rte_atomic_thread_fence(rte_memory_order_acquire);
714 : :
715 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
716 : 0 : infl_req = &pend_q->req_queue[pq_tail];
717 : :
718 : 0 : res.u64[0] = rte_atomic_load_explicit(
719 : : (uint64_t __rte_atomic *)&infl_req->res.u64[0], rte_memory_order_relaxed);
720 : :
721 [ # # ]: 0 : if (unlikely(res.cn9k.compcode == CPT_COMP_NOT_DONE)) {
722 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() >
723 : : pend_q->time_out)) {
724 : 0 : plt_err("Request timed out");
725 : 0 : cnxk_cpt_dump_on_err(qp);
726 : 0 : pend_q->time_out = rte_get_timer_cycles() +
727 : 0 : DEFAULT_COMMAND_TIMEOUT *
728 : : rte_get_timer_hz();
729 : : }
730 : : break;
731 : : }
732 : :
733 : : pending_queue_advance(&pq_tail, pq_mask);
734 : :
735 : 0 : cop = infl_req->cop;
736 : :
737 : 0 : ops[i] = cop;
738 : :
739 : 0 : cn9k_cpt_dequeue_post_process(qp, cop, infl_req, &res.cn9k);
740 : :
741 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
742 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
743 : : }
744 : :
745 : 0 : pend_q->tail = pq_tail;
746 : :
747 : 0 : return i;
748 : : }
749 : : void
750 : 0 : cn9k_cpt_set_enqdeq_fns(struct rte_cryptodev *dev)
751 : : {
752 : 0 : dev->enqueue_burst = cn9k_cpt_enqueue_burst;
753 : 0 : dev->dequeue_burst = cn9k_cpt_dequeue_burst;
754 : :
755 : : rte_mb();
756 : 0 : }
757 : :
758 : : static void
759 : 0 : cn9k_cpt_dev_info_get(struct rte_cryptodev *dev,
760 : : struct rte_cryptodev_info *info)
761 : : {
762 [ # # ]: 0 : if (info != NULL) {
763 : 0 : cnxk_cpt_dev_info_get(dev, info);
764 : 0 : info->driver_id = cn9k_cryptodev_driver_id;
765 : : }
766 : 0 : }
767 : :
768 : : struct rte_cryptodev_ops cn9k_cpt_ops = {
769 : : /* Device control ops */
770 : : .dev_configure = cnxk_cpt_dev_config,
771 : : .dev_start = cnxk_cpt_dev_start,
772 : : .dev_stop = cnxk_cpt_dev_stop,
773 : : .dev_close = cnxk_cpt_dev_close,
774 : : .dev_infos_get = cn9k_cpt_dev_info_get,
775 : :
776 : : .stats_get = NULL,
777 : : .stats_reset = NULL,
778 : : .queue_pair_setup = cnxk_cpt_queue_pair_setup,
779 : : .queue_pair_release = cnxk_cpt_queue_pair_release,
780 : : .queue_pair_reset = cnxk_cpt_queue_pair_reset,
781 : :
782 : : /* Symmetric crypto ops */
783 : : .sym_session_get_size = cnxk_cpt_sym_session_get_size,
784 : : .sym_session_configure = cnxk_cpt_sym_session_configure,
785 : : .sym_session_clear = cnxk_cpt_sym_session_clear,
786 : :
787 : : /* Asymmetric crypto ops */
788 : : .asym_session_get_size = cnxk_ae_session_size_get,
789 : : .asym_session_configure = cnxk_ae_session_cfg,
790 : : .asym_session_clear = cnxk_ae_session_clear,
791 : :
792 : : /* Event crypto ops */
793 : : .session_ev_mdata_set = cn9k_cpt_crypto_adapter_ev_mdata_set,
794 : : .queue_pair_event_error_query = cnxk_cpt_queue_pair_event_error_query,
795 : :
796 : : };
|