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