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