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