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 uint16_t
126 : 0 : cn9k_cpt_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
127 : : {
128 : : struct cpt_inflight_req *infl_req_1, *infl_req_2;
129 : : struct cpt_inst_s inst[2] __rte_cache_aligned;
130 : : struct rte_crypto_op *op_1, *op_2;
131 : : uint16_t nb_allowed, count = 0;
132 : : struct cnxk_cpt_qp *qp = qptr;
133 : : struct pending_queue *pend_q;
134 : : uint64_t head;
135 : : int ret;
136 : :
137 : : const union cpt_res_s res = {
138 : : .cn10k.compcode = CPT_COMP_NOT_DONE,
139 : : };
140 : :
141 : 0 : pend_q = &qp->pend_q;
142 : : rte_prefetch2(pend_q);
143 : :
144 : : /* Clear w0, w2, w3 of both inst */
145 : :
146 : : #if defined(RTE_ARCH_ARM64)
147 : : uint64x2_t zero = vdupq_n_u64(0);
148 : :
149 : : vst1q_u64(&inst[0].w0.u64, zero);
150 : : vst1q_u64(&inst[1].w0.u64, zero);
151 : : vst1q_u64(&inst[0].w2.u64, zero);
152 : : vst1q_u64(&inst[1].w2.u64, zero);
153 : : #else
154 : 0 : inst[0].w0.u64 = 0;
155 : 0 : inst[0].w2.u64 = 0;
156 : 0 : inst[0].w3.u64 = 0;
157 : 0 : inst[1].w0.u64 = 0;
158 : 0 : inst[1].w2.u64 = 0;
159 : 0 : inst[1].w3.u64 = 0;
160 : : #endif
161 : :
162 : : const uint64_t lmt_base = qp->lf.lmt_base;
163 : : const uint64_t io_addr = qp->lf.io_addr;
164 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
165 : :
166 : 0 : head = pend_q->head;
167 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
168 : 0 : nb_ops = RTE_MIN(nb_ops, nb_allowed);
169 : :
170 [ # # ]: 0 : if (unlikely(nb_ops & 1)) {
171 : 0 : op_1 = ops[0];
172 : 0 : infl_req_1 = &pend_q->req_queue[head];
173 : 0 : infl_req_1->op_flags = 0;
174 : :
175 : 0 : ret = cn9k_cpt_inst_prep(qp, op_1, infl_req_1, &inst[0]);
176 [ # # ]: 0 : if (unlikely(ret)) {
177 : 0 : plt_dp_err("Could not process op: %p", op_1);
178 : 0 : return 0;
179 : : }
180 : :
181 : 0 : infl_req_1->cop = op_1;
182 : 0 : infl_req_1->res.cn9k.compcode = CPT_COMP_NOT_DONE;
183 : 0 : inst[0].res_addr = (uint64_t)&infl_req_1->res;
184 : :
185 : : cn9k_cpt_inst_submit(&inst[0], lmt_base, io_addr);
186 : : pending_queue_advance(&head, pq_mask);
187 : : count++;
188 : : }
189 : :
190 [ # # ]: 0 : while (count < nb_ops) {
191 : 0 : op_1 = ops[count];
192 : 0 : op_2 = ops[count + 1];
193 : :
194 : 0 : infl_req_1 = &pend_q->req_queue[head];
195 : : pending_queue_advance(&head, pq_mask);
196 : 0 : infl_req_2 = &pend_q->req_queue[head];
197 : : pending_queue_advance(&head, pq_mask);
198 : :
199 : 0 : infl_req_1->cop = op_1;
200 : 0 : infl_req_2->cop = op_2;
201 : 0 : infl_req_1->op_flags = 0;
202 : 0 : infl_req_2->op_flags = 0;
203 : :
204 : 0 : __atomic_store_n(&infl_req_1->res.u64[0], res.u64[0],
205 : : __ATOMIC_RELAXED);
206 : 0 : inst[0].res_addr = (uint64_t)&infl_req_1->res;
207 : :
208 : 0 : __atomic_store_n(&infl_req_2->res.u64[0], res.u64[0],
209 : : __ATOMIC_RELAXED);
210 : 0 : inst[1].res_addr = (uint64_t)&infl_req_2->res;
211 : :
212 : 0 : ret = cn9k_cpt_inst_prep(qp, op_1, infl_req_1, &inst[0]);
213 [ # # ]: 0 : if (unlikely(ret)) {
214 : 0 : plt_dp_err("Could not process op: %p", op_1);
215 : : pending_queue_retreat(&head, pq_mask, 2);
216 : : break;
217 : : }
218 : :
219 : 0 : ret = cn9k_cpt_inst_prep(qp, op_2, infl_req_2, &inst[1]);
220 [ # # ]: 0 : if (unlikely(ret)) {
221 : 0 : plt_dp_err("Could not process op: %p", op_2);
222 : : pending_queue_retreat(&head, pq_mask, 1);
223 : : cn9k_cpt_inst_submit(&inst[0], lmt_base, io_addr);
224 : : count++;
225 : : break;
226 : : }
227 : :
228 : : cn9k_cpt_inst_submit_dual(&inst[0], lmt_base, io_addr);
229 : :
230 : : count += 2;
231 : : }
232 : :
233 : : rte_atomic_thread_fence(__ATOMIC_RELEASE);
234 : :
235 : 0 : pend_q->head = head;
236 : 0 : pend_q->time_out = rte_get_timer_cycles() +
237 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
238 : :
239 : 0 : return count;
240 : : }
241 : :
242 : : static int
243 : 0 : cn9k_cpt_crypto_adapter_ev_mdata_set(struct rte_cryptodev *dev __rte_unused,
244 : : void *sess,
245 : : enum rte_crypto_op_type op_type,
246 : : enum rte_crypto_op_sess_type sess_type,
247 : : void *mdata)
248 : : {
249 : : union rte_event_crypto_metadata *ec_mdata = mdata;
250 : : struct rte_event *rsp_info;
251 : : struct cnxk_cpt_qp *qp;
252 : : uint8_t cdev_id;
253 : : uint16_t qp_id;
254 : : uint64_t w2;
255 : :
256 : : /* Get queue pair */
257 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
258 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
259 : 0 : qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
260 : :
261 : : /* Prepare w2 */
262 : : rsp_info = &ec_mdata->response_info;
263 : 0 : w2 = CNXK_CPT_INST_W2((RTE_EVENT_TYPE_CRYPTODEV << 28) |
264 : : (rsp_info->sub_event_type << 20) |
265 : : rsp_info->flow_id,
266 : : rsp_info->sched_type, rsp_info->queue_id, 0);
267 : :
268 : : /* Set meta according to session type */
269 [ # # ]: 0 : if (op_type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
270 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
271 : : struct cn9k_sec_session *priv;
272 : :
273 : : priv = (struct cn9k_sec_session *)sess;
274 : 0 : priv->qp = qp;
275 : 0 : priv->inst.w2 = w2;
276 [ # # ]: 0 : } else if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
277 : : struct cnxk_se_sess *priv;
278 : :
279 : : priv = (struct cnxk_se_sess *)sess;
280 : 0 : priv->qp = qp;
281 : 0 : priv->cpt_inst_w2 = w2;
282 : : } else
283 : : return -EINVAL;
284 [ # # ]: 0 : } else if (op_type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
285 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
286 : : struct rte_cryptodev_asym_session *asym_sess = sess;
287 : : struct cnxk_ae_sess *priv;
288 : :
289 : : priv = (struct cnxk_ae_sess *)asym_sess;
290 : 0 : priv->qp = qp;
291 : 0 : priv->cpt_inst_w2 = w2;
292 : : } else
293 : : return -EINVAL;
294 : : } else
295 : : return -EINVAL;
296 : :
297 : : return 0;
298 : : }
299 : :
300 : : static inline int
301 : 0 : cn9k_ca_meta_info_extract(struct rte_crypto_op *op,
302 : : struct cnxk_cpt_qp **qp, struct cpt_inst_s *inst)
303 : : {
304 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
305 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
306 : : struct cn9k_sec_session *priv;
307 : :
308 : 0 : priv = (struct cn9k_sec_session *)(op->sym->session);
309 : 0 : *qp = priv->qp;
310 : 0 : inst->w2.u64 = priv->inst.w2;
311 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
312 : : struct cnxk_se_sess *priv;
313 : :
314 : 0 : priv = (struct cnxk_se_sess *)op->sym->session;
315 : 0 : *qp = priv->qp;
316 : 0 : inst->w2.u64 = priv->cpt_inst_w2;
317 : : } else {
318 : : union rte_event_crypto_metadata *ec_mdata;
319 : : struct rte_event *rsp_info;
320 : : uint8_t cdev_id;
321 : : uint16_t qp_id;
322 : :
323 [ # # ]: 0 : if (unlikely(op->private_data_offset == 0))
324 : : return -EINVAL;
325 : 0 : ec_mdata = (union rte_event_crypto_metadata *)
326 : 0 : ((uint8_t *)op + op->private_data_offset);
327 : : rsp_info = &ec_mdata->response_info;
328 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
329 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
330 : 0 : *qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
331 : 0 : inst->w2.u64 = CNXK_CPT_INST_W2(
332 : : (RTE_EVENT_TYPE_CRYPTODEV << 28) | rsp_info->flow_id,
333 : : rsp_info->sched_type, rsp_info->queue_id, 0);
334 : : }
335 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
336 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
337 : : struct cnxk_ae_sess *priv;
338 : :
339 : 0 : priv = (struct cnxk_ae_sess *)op->asym->session;
340 : 0 : *qp = priv->qp;
341 : 0 : inst->w2.u64 = priv->cpt_inst_w2;
342 : : } else
343 : : return -EINVAL;
344 : : } else
345 : : return -EINVAL;
346 : :
347 : : return 0;
348 : : }
349 : :
350 : : uint16_t
351 : 0 : cn9k_cpt_crypto_adapter_enqueue(uintptr_t base, struct rte_crypto_op *op)
352 : : {
353 : : struct cpt_inflight_req *infl_req;
354 : : union cpt_fc_write_s fc;
355 : : struct cnxk_cpt_qp *qp;
356 : : struct cpt_inst_s inst;
357 : : uint64_t *fc_addr;
358 : : int ret;
359 : :
360 : 0 : ret = cn9k_ca_meta_info_extract(op, &qp, &inst);
361 [ # # ]: 0 : if (unlikely(ret)) {
362 : 0 : rte_errno = EINVAL;
363 : 0 : return 0;
364 : : }
365 : :
366 [ # # ]: 0 : if (unlikely(!qp->ca.enabled)) {
367 : 0 : rte_errno = EINVAL;
368 : 0 : return 0;
369 : : }
370 : :
371 [ # # # # ]: 0 : if (unlikely(rte_mempool_get(qp->ca.req_mp, (void **)&infl_req))) {
372 : 0 : rte_errno = ENOMEM;
373 : 0 : return 0;
374 : : }
375 : 0 : infl_req->op_flags = 0;
376 : :
377 : 0 : ret = cn9k_cpt_inst_prep(qp, op, infl_req, &inst);
378 [ # # ]: 0 : if (unlikely(ret)) {
379 : 0 : plt_dp_err("Could not process op: %p", op);
380 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
381 : 0 : return 0;
382 : : }
383 : :
384 : 0 : infl_req->cop = op;
385 : 0 : infl_req->res.cn9k.compcode = CPT_COMP_NOT_DONE;
386 : 0 : infl_req->qp = qp;
387 : 0 : inst.w0.u64 = 0;
388 : 0 : inst.res_addr = (uint64_t)&infl_req->res;
389 : 0 : inst.w3.u64 = CNXK_CPT_INST_W3(1, infl_req);
390 : :
391 : 0 : fc_addr = qp->lmtline.fc_addr;
392 : :
393 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
394 : :
395 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
396 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
397 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
398 : 0 : rte_errno = EAGAIN;
399 : 0 : return 0;
400 : : }
401 : :
402 [ # # ]: 0 : if (inst.w2.s.tt == RTE_SCHED_TYPE_ORDERED)
403 : : roc_sso_hws_head_wait(base);
404 : :
405 : : cn9k_cpt_inst_submit(&inst, qp->lmtline.lmt_base, qp->lmtline.io_addr);
406 : :
407 : : return 1;
408 : : }
409 : :
410 : : static inline int
411 : 0 : ipsec_antireplay_check(struct cn9k_sec_session *sess, uint32_t win_sz,
412 : : struct roc_ie_on_inb_hdr *data)
413 : : {
414 : : uint32_t esn_low, esn_hi, seql, seqh = 0;
415 : : struct roc_ie_on_common_sa *common_sa;
416 : : struct roc_ie_on_inb_sa *in_sa;
417 : : uint64_t seq, seq_in_sa;
418 : : uint8_t esn;
419 : : int ret;
420 : :
421 : : in_sa = &sess->sa.in_sa;
422 : : common_sa = &in_sa->common_sa;
423 : :
424 : 0 : esn = common_sa->ctl.esn_en;
425 [ # # ]: 0 : seql = rte_be_to_cpu_32(data->seql);
426 : :
427 [ # # ]: 0 : if (!esn) {
428 : 0 : seq = (uint64_t)seql;
429 : : } else {
430 [ # # ]: 0 : seqh = rte_be_to_cpu_32(data->seqh);
431 : 0 : seq = ((uint64_t)seqh << 32) | seql;
432 : : }
433 : :
434 [ # # ]: 0 : if (unlikely(seq == 0))
435 : : return IPSEC_ANTI_REPLAY_FAILED;
436 : :
437 : 0 : rte_spinlock_lock(&sess->ar.lock);
438 : 0 : ret = cnxk_on_anti_replay_check(seq, &sess->ar, win_sz);
439 [ # # ]: 0 : if (esn && !ret) {
440 [ # # ]: 0 : esn_low = rte_be_to_cpu_32(common_sa->seq_t.tl);
441 [ # # ]: 0 : esn_hi = rte_be_to_cpu_32(common_sa->seq_t.th);
442 : 0 : seq_in_sa = ((uint64_t)esn_hi << 32) | esn_low;
443 [ # # ]: 0 : if (seq > seq_in_sa) {
444 [ # # ]: 0 : common_sa->seq_t.tl = rte_cpu_to_be_32(seql);
445 [ # # ]: 0 : common_sa->seq_t.th = rte_cpu_to_be_32(seqh);
446 : : }
447 : : }
448 : : rte_spinlock_unlock(&sess->ar.lock);
449 : :
450 : 0 : return ret;
451 : : }
452 : :
453 : : static inline void
454 : 0 : cn9k_cpt_sec_post_process(struct rte_crypto_op *cop,
455 : : struct cpt_inflight_req *infl_req)
456 : : {
457 : : struct rte_crypto_sym_op *sym_op = cop->sym;
458 : 0 : struct rte_mbuf *m = sym_op->m_src;
459 : : struct roc_ie_on_inb_hdr *hdr;
460 : : struct cn9k_sec_session *priv;
461 : : struct rte_ipv6_hdr *ip6;
462 : : struct rte_ipv4_hdr *ip;
463 : : uint16_t m_len = 0;
464 : :
465 [ # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_IPSEC_DIR_INBOUND) {
466 : :
467 : 0 : hdr = rte_pktmbuf_mtod(m, struct roc_ie_on_inb_hdr *);
468 : :
469 [ # # ]: 0 : if (likely(m->next == NULL)) {
470 : 0 : ip = PLT_PTR_ADD(hdr, ROC_IE_ON_INB_RPTR_HDR);
471 : : } else {
472 : : ip = (struct rte_ipv4_hdr *)hdr;
473 : 0 : hdr = infl_req->mdata;
474 : : }
475 : :
476 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_IPSEC_INB_REPLAY)) {
477 : : int ret;
478 : :
479 : 0 : priv = (struct cn9k_sec_session *)(sym_op->session);
480 : :
481 : 0 : ret = ipsec_antireplay_check(priv, priv->replay_win_sz, hdr);
482 [ # # ]: 0 : if (unlikely(ret)) {
483 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
484 : 0 : return;
485 : : }
486 : : }
487 : :
488 [ # # ]: 0 : if (ip->version == IPVERSION) {
489 [ # # ]: 0 : m_len = rte_be_to_cpu_16(ip->total_length);
490 : : } else {
491 : : PLT_ASSERT((ip->version == 6));
492 : : ip6 = (struct rte_ipv6_hdr *)ip;
493 [ # # ]: 0 : m_len = rte_be_to_cpu_16(ip6->payload_len) + sizeof(struct rte_ipv6_hdr);
494 : : }
495 : :
496 [ # # ]: 0 : if (likely(m->next == NULL)) {
497 : 0 : m->data_len = m_len;
498 : 0 : m->pkt_len = m_len;
499 : :
500 : 0 : m->data_off += ROC_IE_ON_INB_RPTR_HDR;
501 : : } else {
502 : : struct rte_mbuf *temp = m;
503 : 0 : uint8_t m_len_s = m_len;
504 : :
505 [ # # ]: 0 : while (m_len_s - temp->data_len > 0) {
506 : 0 : m_len_s -= temp->data_len;
507 : 0 : temp = temp->next;
508 : : }
509 : :
510 : 0 : temp->data_len = m_len_s;
511 : 0 : m->pkt_len = m_len;
512 : : }
513 : : }
514 : : }
515 : :
516 : : static inline void
517 : 0 : cn9k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp, struct rte_crypto_op *cop,
518 : : struct cpt_inflight_req *infl_req,
519 : : struct cpt_cn9k_res_s *res)
520 : : {
521 [ # # ]: 0 : if (likely(res->compcode == CPT_COMP_GOOD)) {
522 [ # # ]: 0 : if (unlikely(res->uc_compcode)) {
523 [ # # ]: 0 : if (res->uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
524 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
525 [ # # ]: 0 : else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC &&
526 : 0 : cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION &&
527 [ # # ]: 0 : cop->asym->ecdh.ke_type == RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY) {
528 [ # # ]: 0 : if (res->uc_compcode == ROC_AE_ERR_ECC_POINT_NOT_ON_CURVE) {
529 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
530 : 0 : return;
531 [ # # ]: 0 : } else if (res->uc_compcode == ROC_AE_ERR_ECC_PAI) {
532 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
533 : 0 : return;
534 : : }
535 : : } else
536 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
537 : :
538 : 0 : plt_dp_info("Request failed with microcode error");
539 : 0 : plt_dp_info("MC completion code 0x%x",
540 : : res->uc_compcode);
541 : 0 : goto temp_sess_free;
542 : : }
543 : :
544 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
545 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
546 [ # # ]: 0 : if (cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
547 : 0 : cn9k_cpt_sec_post_process(cop, infl_req);
548 : 0 : return;
549 : : }
550 : :
551 : : /* Verify authentication data if required */
552 [ # # ]: 0 : if (unlikely(infl_req->op_flags &
553 : : CPT_OP_FLAGS_AUTH_VERIFY)) {
554 : 0 : uintptr_t *rsp = infl_req->mdata;
555 [ # # ]: 0 : compl_auth_verify(cop, (uint8_t *)rsp[0],
556 : : rsp[1]);
557 : : }
558 [ # # ]: 0 : } else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
559 : : struct rte_crypto_asym_op *op = cop->asym;
560 : 0 : uintptr_t *mdata = infl_req->mdata;
561 : 0 : struct cnxk_ae_sess *sess = (struct cnxk_ae_sess *)op->session;
562 : :
563 [ # # # # : 0 : cnxk_ae_post_process(cop, sess, (uint8_t *)mdata[0]);
# # # ]
564 : : }
565 : : } else {
566 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
567 : 0 : plt_dp_info("HW completion code 0x%x", res->compcode);
568 : :
569 [ # # # # ]: 0 : switch (res->compcode) {
570 : 0 : case CPT_COMP_INSTERR:
571 : 0 : plt_dp_err("Request failed with instruction error");
572 : 0 : break;
573 : 0 : case CPT_COMP_FAULT:
574 : 0 : plt_dp_err("Request failed with DMA fault");
575 : 0 : break;
576 : 0 : case CPT_COMP_HWERR:
577 : 0 : plt_dp_err("Request failed with hardware error");
578 : 0 : break;
579 : 0 : default:
580 : 0 : plt_dp_err(
581 : : "Request failed with unknown completion code");
582 : : }
583 : : }
584 : :
585 : 0 : temp_sess_free:
586 [ # # ]: 0 : if (unlikely(cop->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {
587 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
588 : 0 : sym_session_clear(cop->sym->session, true);
589 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, cop->sym->session);
590 : 0 : cop->sym->session = NULL;
591 : : }
592 : : }
593 : : }
594 : :
595 : : uintptr_t
596 : 0 : cn9k_cpt_crypto_adapter_dequeue(uintptr_t get_work1)
597 : : {
598 : : struct cpt_inflight_req *infl_req;
599 : : struct rte_crypto_op *cop;
600 : : struct cnxk_cpt_qp *qp;
601 : : union cpt_res_s res;
602 : :
603 : 0 : infl_req = (struct cpt_inflight_req *)(get_work1);
604 : 0 : cop = infl_req->cop;
605 : 0 : qp = infl_req->qp;
606 : :
607 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0], __ATOMIC_RELAXED);
608 : :
609 : 0 : cn9k_cpt_dequeue_post_process(qp, infl_req->cop, infl_req, &res.cn9k);
610 : :
611 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
612 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
613 : :
614 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
615 : 0 : return (uintptr_t)cop;
616 : : }
617 : :
618 : : static uint16_t
619 : 0 : cn9k_cpt_dequeue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
620 : : {
621 : : struct cpt_inflight_req *infl_req;
622 : : struct cnxk_cpt_qp *qp = qptr;
623 : : struct pending_queue *pend_q;
624 : : uint64_t infl_cnt, pq_tail;
625 : : struct rte_crypto_op *cop;
626 : : union cpt_res_s res;
627 : : int i;
628 : :
629 : : pend_q = &qp->pend_q;
630 : :
631 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
632 : :
633 : 0 : pq_tail = pend_q->tail;
634 : 0 : infl_cnt = pending_queue_infl_cnt(pend_q->head, pq_tail, pq_mask);
635 : 0 : nb_ops = RTE_MIN(nb_ops, infl_cnt);
636 : :
637 : : /* Ensure infl_cnt isn't read before data lands */
638 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
639 : :
640 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
641 : 0 : infl_req = &pend_q->req_queue[pq_tail];
642 : :
643 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0],
644 : : __ATOMIC_RELAXED);
645 : :
646 [ # # ]: 0 : if (unlikely(res.cn9k.compcode == CPT_COMP_NOT_DONE)) {
647 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() >
648 : : pend_q->time_out)) {
649 : 0 : plt_err("Request timed out");
650 : 0 : cnxk_cpt_dump_on_err(qp);
651 : 0 : pend_q->time_out = rte_get_timer_cycles() +
652 : 0 : DEFAULT_COMMAND_TIMEOUT *
653 : : rte_get_timer_hz();
654 : : }
655 : : break;
656 : : }
657 : :
658 : : pending_queue_advance(&pq_tail, pq_mask);
659 : :
660 : 0 : cop = infl_req->cop;
661 : :
662 : 0 : ops[i] = cop;
663 : :
664 : 0 : cn9k_cpt_dequeue_post_process(qp, cop, infl_req, &res.cn9k);
665 : :
666 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
667 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
668 : : }
669 : :
670 : 0 : pend_q->tail = pq_tail;
671 : :
672 : 0 : return i;
673 : : }
674 : : void
675 : 0 : cn9k_cpt_set_enqdeq_fns(struct rte_cryptodev *dev)
676 : : {
677 : 0 : dev->enqueue_burst = cn9k_cpt_enqueue_burst;
678 : 0 : dev->dequeue_burst = cn9k_cpt_dequeue_burst;
679 : :
680 : : rte_mb();
681 : 0 : }
682 : :
683 : : static void
684 : 0 : cn9k_cpt_dev_info_get(struct rte_cryptodev *dev,
685 : : struct rte_cryptodev_info *info)
686 : : {
687 [ # # ]: 0 : if (info != NULL) {
688 : 0 : cnxk_cpt_dev_info_get(dev, info);
689 : 0 : info->driver_id = cn9k_cryptodev_driver_id;
690 : : }
691 : 0 : }
692 : :
693 : : struct rte_cryptodev_ops cn9k_cpt_ops = {
694 : : /* Device control ops */
695 : : .dev_configure = cnxk_cpt_dev_config,
696 : : .dev_start = cnxk_cpt_dev_start,
697 : : .dev_stop = cnxk_cpt_dev_stop,
698 : : .dev_close = cnxk_cpt_dev_close,
699 : : .dev_infos_get = cn9k_cpt_dev_info_get,
700 : :
701 : : .stats_get = NULL,
702 : : .stats_reset = NULL,
703 : : .queue_pair_setup = cnxk_cpt_queue_pair_setup,
704 : : .queue_pair_release = cnxk_cpt_queue_pair_release,
705 : :
706 : : /* Symmetric crypto ops */
707 : : .sym_session_get_size = cnxk_cpt_sym_session_get_size,
708 : : .sym_session_configure = cnxk_cpt_sym_session_configure,
709 : : .sym_session_clear = cnxk_cpt_sym_session_clear,
710 : :
711 : : /* Asymmetric crypto ops */
712 : : .asym_session_get_size = cnxk_ae_session_size_get,
713 : : .asym_session_configure = cnxk_ae_session_cfg,
714 : : .asym_session_clear = cnxk_ae_session_clear,
715 : :
716 : : /* Event crypto ops */
717 : : .session_ev_mdata_set = cn9k_cpt_crypto_adapter_ev_mdata_set,
718 : : .queue_pair_event_error_query = cnxk_cpt_queue_pair_event_error_query,
719 : :
720 : : };
|