Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <cryptodev_pmd.h>
6 : : #include <eal_export.h>
7 : : #include <rte_cryptodev.h>
8 : : #include <rte_event_crypto_adapter.h>
9 : : #include <rte_hexdump.h>
10 : : #include <rte_ip.h>
11 : : #include <rte_vect.h>
12 : :
13 : : #include <ethdev_driver.h>
14 : :
15 : : #include "roc_api.h"
16 : :
17 : : #include "cn10k_cryptodev.h"
18 : : #include "cn10k_cryptodev_event_dp.h"
19 : : #include "cn10k_cryptodev_ops.h"
20 : : #include "cn10k_cryptodev_sec.h"
21 : : #include "cn10k_eventdev.h"
22 : : #include "cn10k_ipsec.h"
23 : : #include "cn10k_ipsec_la_ops.h"
24 : : #include "cn10k_tls.h"
25 : : #include "cn10k_tls_ops.h"
26 : : #include "cnxk_ae.h"
27 : : #include "cnxk_cryptodev.h"
28 : : #include "cnxk_cryptodev_ops.h"
29 : : #include "cnxk_eventdev.h"
30 : : #include "cnxk_se.h"
31 : :
32 : : #include "rte_pmd_cnxk_crypto.h"
33 : :
34 : : /* Holds information required to send crypto operations in one burst */
35 : : struct ops_burst {
36 : : struct rte_crypto_op *op[CN10K_CPT_PKTS_PER_LOOP];
37 : : uint64_t w2[CN10K_CPT_PKTS_PER_LOOP];
38 : : struct cn10k_sso_hws *ws;
39 : : struct cnxk_cpt_qp *qp;
40 : : uint16_t nb_ops;
41 : : };
42 : :
43 : : /* Holds information required to send vector of operations */
44 : : struct vec_request {
45 : : struct cpt_inflight_req *req;
46 : : struct rte_event_vector *vec;
47 : : union cpt_inst_w7 w7;
48 : : uint64_t w2;
49 : : };
50 : :
51 : : static inline struct cnxk_se_sess *
52 : 0 : cn10k_cpt_sym_temp_sess_create(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op)
53 : : {
54 : : struct rte_crypto_sym_op *sym_op = op->sym;
55 : : struct rte_cryptodev_sym_session *sess;
56 : : struct cnxk_se_sess *priv;
57 : : int ret;
58 : :
59 : : /* Create temporary session */
60 [ # # # # ]: 0 : if (rte_mempool_get(qp->sess_mp, (void **)&sess) < 0)
61 : : return NULL;
62 : :
63 : 0 : ret = sym_session_configure(qp->lf.roc_cpt, sym_op->xform, sess, true);
64 [ # # ]: 0 : if (ret) {
65 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, (void *)sess);
66 : 0 : goto sess_put;
67 : : }
68 : :
69 : 0 : priv = (void *)sess;
70 : 0 : sym_op->session = sess;
71 : :
72 : 0 : return priv;
73 : :
74 : : sess_put:
75 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, sess);
76 : 0 : return NULL;
77 : : }
78 : :
79 : : static inline struct cnxk_ae_sess *
80 : 0 : cn10k_cpt_asym_temp_sess_create(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op)
81 : : {
82 : : struct rte_crypto_asym_op *asym_op = op->asym;
83 : 0 : struct roc_cpt *roc_cpt = qp->lf.roc_cpt;
84 : : struct rte_cryptodev_asym_session *sess;
85 : : struct cnxk_ae_sess *priv;
86 : : struct cnxk_cpt_vf *vf;
87 : : union cpt_inst_w7 w7;
88 : : struct hw_ctx_s *hwc;
89 : :
90 : : /* Create temporary session */
91 [ # # # # ]: 0 : if (rte_mempool_get(qp->sess_mp, (void **)&sess) < 0)
92 : : return NULL;
93 : :
94 : 0 : priv = (struct cnxk_ae_sess *)sess;
95 : 0 : if (cnxk_ae_fill_session_parameters(priv, asym_op->xform))
96 : 0 : goto sess_put;
97 : :
98 [ # # ]: 0 : priv->lf = &qp->lf;
99 : :
100 [ # # ]: 0 : if (roc_errata_cpt_hang_on_mixed_ctx_val()) {
101 : : hwc = &priv->hw_ctx;
102 : 0 : hwc->w0.s.aop_valid = 1;
103 : 0 : hwc->w0.s.ctx_hdr_size = 0;
104 : 0 : hwc->w0.s.ctx_size = 1;
105 : 0 : hwc->w0.s.ctx_push_size = 1;
106 : :
107 : : w7.s.ctx_val = 1;
108 : : w7.s.cptr = (uint64_t)hwc;
109 : : }
110 : :
111 : 0 : w7.u64 = 0;
112 : 0 : w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_AE];
113 : :
114 : 0 : vf = container_of(roc_cpt, struct cnxk_cpt_vf, cpt);
115 : 0 : priv->cpt_inst_w7 = w7.u64;
116 : 0 : priv->cnxk_fpm_iova = vf->cnxk_fpm_iova;
117 : 0 : priv->ec_grp = vf->ec_grp;
118 : :
119 : 0 : asym_op->session = sess;
120 : :
121 : 0 : return priv;
122 : :
123 : : sess_put:
124 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, sess);
125 : 0 : return NULL;
126 : : }
127 : :
128 : : static __rte_always_inline int __rte_hot
129 : : cpt_sec_ipsec_inst_fill(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
130 : : struct cn10k_sec_session *sess, struct cpt_inst_s *inst,
131 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2)
132 : : {
133 : : struct rte_crypto_sym_op *sym_op = op->sym;
134 : : int ret;
135 : :
136 [ # # # # ]: 0 : if (unlikely(sym_op->m_dst && sym_op->m_dst != sym_op->m_src)) {
137 : 0 : plt_dp_err("Out of place is not supported");
138 : 0 : return -ENOTSUP;
139 : : }
140 : :
141 [ # # ]: 0 : if (sess->ipsec.is_outbound)
142 : : ret = process_outb_sa(&qp->lf, op, sess, &qp->meta_info, infl_req, inst,
143 : : is_sg_ver2);
144 : : else
145 : : ret = process_inb_sa(op, sess, inst, &qp->meta_info, infl_req, is_sg_ver2);
146 : :
147 : : return ret;
148 : : }
149 : :
150 : : static __rte_always_inline int __rte_hot
151 : : cpt_sec_tls_inst_fill(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op,
152 : : struct cn10k_sec_session *sess, struct cpt_inst_s *inst,
153 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2)
154 : : {
155 [ # # ]: 0 : if (sess->tls_opt.is_write)
156 : 0 : return process_tls_write(&qp->lf, op, sess, &qp->meta_info, infl_req, inst,
157 : : is_sg_ver2);
158 : : else
159 : 0 : return process_tls_read(op, sess, &qp->meta_info, infl_req, inst, is_sg_ver2);
160 : : }
161 : :
162 : : static __rte_always_inline int __rte_hot
163 : : cpt_sec_inst_fill(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op, struct cn10k_sec_session *sess,
164 : : struct cpt_inst_s *inst, struct cpt_inflight_req *infl_req, const bool is_sg_ver2)
165 : : {
166 : :
167 : 0 : if (sess->proto == RTE_SECURITY_PROTOCOL_IPSEC)
168 : : return cpt_sec_ipsec_inst_fill(qp, op, sess, &inst[0], infl_req, is_sg_ver2);
169 [ # # ]: 0 : else if (sess->proto == RTE_SECURITY_PROTOCOL_TLS_RECORD)
170 : : return cpt_sec_tls_inst_fill(qp, op, sess, &inst[0], infl_req, is_sg_ver2);
171 : :
172 : : return 0;
173 : : }
174 : :
175 : : static inline int
176 : 0 : cn10k_cpt_fill_inst(struct cnxk_cpt_qp *qp, struct rte_crypto_op *ops[], struct cpt_inst_s inst[],
177 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2)
178 : : {
179 : : struct cn10k_sec_session *sec_sess;
180 : : struct rte_crypto_asym_op *asym_op;
181 : : struct rte_crypto_sym_op *sym_op;
182 : : struct cnxk_ae_sess *ae_sess;
183 : : struct cnxk_se_sess *sess;
184 : : struct rte_crypto_op *op;
185 : : uint64_t w7;
186 : : int ret;
187 : :
188 : : const union cpt_res_s res = {
189 : : .cn10k.compcode = CPT_COMP_NOT_DONE,
190 : : };
191 : :
192 : 0 : op = ops[0];
193 : :
194 : 0 : inst[0].w0.u64 = 0;
195 : 0 : inst[0].w2.u64 = 0;
196 : 0 : inst[0].w3.u64 = 0;
197 : :
198 : : sym_op = op->sym;
199 : :
200 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
201 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
202 [ # # ]: 0 : sec_sess = (struct cn10k_sec_session *)sym_op->session;
203 : : ret = cpt_sec_inst_fill(qp, op, sec_sess, &inst[0], infl_req, is_sg_ver2);
204 [ # # ]: 0 : if (unlikely(ret))
205 : : return 0;
206 : 0 : w7 = sec_sess->inst.w7;
207 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
208 [ # # ]: 0 : sess = (struct cnxk_se_sess *)(sym_op->session);
209 : : ret = cpt_sym_inst_fill(qp, op, sess, infl_req, &inst[0], is_sg_ver2);
210 [ # # ]: 0 : if (unlikely(ret))
211 : : return 0;
212 : 0 : w7 = sess->cpt_inst_w7;
213 : : } else {
214 : 0 : sess = cn10k_cpt_sym_temp_sess_create(qp, op);
215 [ # # ]: 0 : if (unlikely(sess == NULL)) {
216 : 0 : plt_dp_err("Could not create temp session");
217 : 0 : return 0;
218 : : }
219 : :
220 : : ret = cpt_sym_inst_fill(qp, op, sess, infl_req, &inst[0], is_sg_ver2);
221 [ # # ]: 0 : if (unlikely(ret)) {
222 : 0 : sym_session_clear(op->sym->session, true);
223 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, op->sym->session);
224 : 0 : return 0;
225 : : }
226 : 0 : w7 = sess->cpt_inst_w7;
227 : : }
228 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
229 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
230 : : asym_op = op->asym;
231 [ # # ]: 0 : ae_sess = (struct cnxk_ae_sess *)asym_op->session;
232 : : ret = cnxk_ae_enqueue(qp, op, infl_req, &inst[0], ae_sess);
233 [ # # ]: 0 : if (unlikely(ret))
234 : : return 0;
235 : 0 : w7 = ae_sess->cpt_inst_w7;
236 : : } else {
237 : 0 : ae_sess = cn10k_cpt_asym_temp_sess_create(qp, op);
238 [ # # ]: 0 : if (unlikely(ae_sess == NULL)) {
239 : 0 : plt_dp_err("Could not create temp session");
240 : 0 : return 0;
241 : : }
242 : :
243 : : ret = cnxk_ae_enqueue(qp, op, infl_req, &inst[0], ae_sess);
244 [ # # ]: 0 : if (unlikely(ret)) {
245 : 0 : cnxk_ae_session_clear(NULL,
246 : : (struct rte_cryptodev_asym_session *)ae_sess);
247 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, ae_sess);
248 : 0 : return 0;
249 : : }
250 : 0 : w7 = ae_sess->cpt_inst_w7;
251 : : }
252 : :
253 : : } else {
254 : 0 : plt_dp_err("Unsupported op type");
255 : 0 : return 0;
256 : : }
257 : :
258 : 0 : inst[0].res_addr = (uint64_t)&infl_req->res;
259 : 0 : rte_atomic_store_explicit((uint64_t __rte_atomic *)&infl_req->res.u64[0], res.u64[0],
260 : : rte_memory_order_relaxed);
261 : 0 : infl_req->cop = op;
262 : :
263 : 0 : inst[0].w7.u64 = w7;
264 : :
265 : : #ifdef CPT_INST_DEBUG_ENABLE
266 : : infl_req->dptr = (uint8_t *)inst[0].dptr;
267 : : infl_req->rptr = (uint8_t *)inst[0].rptr;
268 : : infl_req->is_sg_ver2 = is_sg_ver2;
269 : : infl_req->scatter_sz = inst[0].w6.s.scatter_sz;
270 : : infl_req->opcode_major = inst[0].w4.s.opcode_major;
271 : :
272 : : rte_hexdump(rte_log_get_stream(), "cptr", (void *)(uint64_t)inst[0].w7.s.cptr, 128);
273 : : plt_err("major opcode:%d", inst[0].w4.s.opcode_major);
274 : : plt_err("minor opcode:%d", inst[0].w4.s.opcode_minor);
275 : : plt_err("param1:%d", inst[0].w4.s.param1);
276 : : plt_err("param2:%d", inst[0].w4.s.param2);
277 : : plt_err("dlen:%d", inst[0].w4.s.dlen);
278 : :
279 : : if (is_sg_ver2) {
280 : : cnxk_cpt_request_data_sgv2_mode_dump((void *)inst[0].dptr, 1,
281 : : inst[0].w5.s.gather_sz);
282 : : cnxk_cpt_request_data_sgv2_mode_dump((void *)inst[0].rptr, 0,
283 : : inst[0].w6.s.scatter_sz);
284 : : } else {
285 : : if (infl_req->opcode_major >> 7) {
286 : : cnxk_cpt_request_data_sg_mode_dump((void *)inst[0].dptr, 1);
287 : : cnxk_cpt_request_data_sg_mode_dump((void *)inst[0].dptr, 0);
288 : : }
289 : : }
290 : : #endif
291 : :
292 : 0 : return 1;
293 : : }
294 : :
295 : : static uint16_t
296 : 0 : cn10k_cpt_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops,
297 : : const bool is_sg_ver2)
298 : : {
299 : : struct cpt_inflight_req *infl_req;
300 : : uint64_t head, lmt_base, io_addr;
301 : : uint16_t nb_allowed, count = 0;
302 : : uint64_t __rte_atomic *fc_addr;
303 : : struct cnxk_cpt_qp *qp = qptr;
304 : : struct pending_queue *pend_q;
305 : : struct cpt_inst_s *inst;
306 : : union cpt_fc_write_s fc;
307 : : uint16_t lmt_id;
308 : : int ret, i;
309 : :
310 : : pend_q = &qp->pend_q;
311 : :
312 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
313 : :
314 : 0 : head = pend_q->head;
315 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
316 : 0 : nb_ops = RTE_MIN(nb_ops, nb_allowed);
317 : :
318 [ # # ]: 0 : if (unlikely(nb_ops == 0))
319 : : return 0;
320 : :
321 : 0 : lmt_base = qp->lmtline.lmt_base;
322 : : io_addr = qp->lmtline.io_addr;
323 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
324 : :
325 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
326 : :
327 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
328 : 0 : inst = (struct cpt_inst_s *)lmt_base;
329 : :
330 : 0 : again:
331 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
332 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
333 : : i = 0;
334 : 0 : goto pend_q_commit;
335 : : }
336 : :
337 [ # # ]: 0 : for (i = 0; i < RTE_MIN(CN10K_CPT_PKTS_PER_LOOP, nb_ops); i++) {
338 : 0 : infl_req = &pend_q->req_queue[head];
339 : 0 : infl_req->op_flags = 0;
340 : :
341 : 0 : ret = cn10k_cpt_fill_inst(qp, ops + i, &inst[i], infl_req, is_sg_ver2);
342 [ # # ]: 0 : if (unlikely(ret != 1)) {
343 : 0 : plt_dp_err("Could not process op: %p", ops + i);
344 [ # # ]: 0 : if (i == 0)
345 : 0 : goto pend_q_commit;
346 : : break;
347 : : }
348 : :
349 : : pending_queue_advance(&head, pq_mask);
350 : : }
351 : :
352 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
353 : :
354 [ # # # # ]: 0 : if (nb_ops - i > 0 && i == CN10K_CPT_PKTS_PER_LOOP) {
355 : 0 : nb_ops -= CN10K_CPT_PKTS_PER_LOOP;
356 : 0 : ops += CN10K_CPT_PKTS_PER_LOOP;
357 : 0 : count += CN10K_CPT_PKTS_PER_LOOP;
358 : 0 : goto again;
359 : : }
360 : :
361 : 0 : pend_q_commit:
362 : : rte_atomic_thread_fence(rte_memory_order_release);
363 : :
364 : 0 : pend_q->head = head;
365 : 0 : pend_q->time_out = rte_get_timer_cycles() +
366 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
367 : :
368 : 0 : return count + i;
369 : : }
370 : :
371 : : static uint16_t
372 : 0 : cn10k_cpt_sg_ver1_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
373 : : {
374 : 0 : return cn10k_cpt_enqueue_burst(qptr, ops, nb_ops, false);
375 : : }
376 : :
377 : : static uint16_t
378 : 0 : cn10k_cpt_sg_ver2_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
379 : : {
380 : 0 : return cn10k_cpt_enqueue_burst(qptr, ops, nb_ops, true);
381 : : }
382 : :
383 : : static int
384 : 0 : cn10k_cpt_crypto_adapter_ev_mdata_set(struct rte_cryptodev *dev __rte_unused, void *sess,
385 : : enum rte_crypto_op_type op_type,
386 : : enum rte_crypto_op_sess_type sess_type, void *mdata)
387 : : {
388 : : union rte_event_crypto_metadata *ec_mdata = mdata;
389 : : struct rte_event *rsp_info;
390 : : struct cnxk_cpt_qp *qp;
391 : : uint64_t w2, tag_type;
392 : : uint8_t cdev_id;
393 : : int16_t qp_id;
394 : :
395 : : /* Get queue pair */
396 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
397 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
398 : 0 : qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
399 : :
400 [ # # ]: 0 : if (!qp->ca.enabled)
401 : : return -EINVAL;
402 : :
403 : : /* Prepare w2 */
404 [ # # ]: 0 : tag_type = qp->ca.vector_sz ? RTE_EVENT_TYPE_CRYPTODEV_VECTOR : RTE_EVENT_TYPE_CRYPTODEV;
405 : : rsp_info = &ec_mdata->response_info;
406 : 0 : w2 = CNXK_CPT_INST_W2((tag_type << 28) | (rsp_info->sub_event_type << 20) |
407 : : rsp_info->flow_id,
408 : : rsp_info->sched_type, rsp_info->queue_id, 0);
409 : :
410 : : /* Set meta according to session type */
411 [ # # ]: 0 : if (op_type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
412 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
413 : : struct cn10k_sec_session *sec_sess = (struct cn10k_sec_session *)sess;
414 : :
415 : 0 : sec_sess->qp = qp;
416 : 0 : sec_sess->inst.w2 = w2;
417 [ # # ]: 0 : } else if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
418 : : struct cnxk_se_sess *priv;
419 : :
420 : : priv = (struct cnxk_se_sess *)sess;
421 : 0 : priv->qp = qp;
422 : 0 : priv->cpt_inst_w2 = w2;
423 : : } else
424 : : return -EINVAL;
425 [ # # ]: 0 : } else if (op_type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
426 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
427 : : struct cnxk_ae_sess *priv;
428 : :
429 : : priv = (struct cnxk_ae_sess *)sess;
430 : 0 : priv->qp = qp;
431 : 0 : priv->cpt_inst_w2 = w2;
432 : : } else
433 : : return -EINVAL;
434 : : } else
435 : : return -EINVAL;
436 : :
437 : : return 0;
438 : : }
439 : :
440 : : static inline int
441 : 0 : cn10k_ca_meta_info_extract(struct rte_crypto_op *op, struct cnxk_cpt_qp **qp, uint64_t *w2)
442 : : {
443 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
444 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
445 : : struct cn10k_sec_session *sec_sess;
446 : :
447 : 0 : sec_sess = (struct cn10k_sec_session *)op->sym->session;
448 : :
449 : 0 : *qp = sec_sess->qp;
450 : 0 : *w2 = sec_sess->inst.w2;
451 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
452 : : struct cnxk_se_sess *priv;
453 : :
454 : 0 : priv = (struct cnxk_se_sess *)op->sym->session;
455 : 0 : *qp = priv->qp;
456 : 0 : *w2 = priv->cpt_inst_w2;
457 : : } else {
458 : : union rte_event_crypto_metadata *ec_mdata;
459 : : struct rte_event *rsp_info;
460 : : uint8_t cdev_id;
461 : : uint16_t qp_id;
462 : :
463 [ # # ]: 0 : if (unlikely(op->private_data_offset == 0))
464 : : return -EINVAL;
465 : 0 : ec_mdata = (union rte_event_crypto_metadata *)
466 : 0 : ((uint8_t *)op + op->private_data_offset);
467 : : rsp_info = &ec_mdata->response_info;
468 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
469 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
470 : 0 : *qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
471 : 0 : *w2 = CNXK_CPT_INST_W2(
472 : : (RTE_EVENT_TYPE_CRYPTODEV << 28) | rsp_info->flow_id,
473 : : rsp_info->sched_type, rsp_info->queue_id, 0);
474 : : }
475 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
476 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
477 : : struct cnxk_ae_sess *priv;
478 : :
479 : 0 : priv = (struct cnxk_ae_sess *)op->asym->session;
480 : 0 : *qp = priv->qp;
481 : 0 : *w2 = priv->cpt_inst_w2;
482 : : } else {
483 : : union rte_event_crypto_metadata *ec_mdata;
484 : : struct rte_event *rsp_info;
485 : : uint8_t cdev_id;
486 : : uint16_t qp_id;
487 : :
488 [ # # ]: 0 : if (unlikely(op->private_data_offset == 0))
489 : : return -EINVAL;
490 : 0 : ec_mdata = (union rte_event_crypto_metadata *)((uint8_t *)op +
491 : 0 : op->private_data_offset);
492 : : rsp_info = &ec_mdata->response_info;
493 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
494 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
495 : 0 : *qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
496 : 0 : *w2 = CNXK_CPT_INST_W2((RTE_EVENT_TYPE_CRYPTODEV << 28) | rsp_info->flow_id,
497 : : rsp_info->sched_type, rsp_info->queue_id, 0);
498 : : }
499 : : } else
500 : : return -EINVAL;
501 : :
502 : : return 0;
503 : : }
504 : :
505 : : static inline void
506 : 0 : cn10k_cpt_vec_inst_fill(struct vec_request *vec_req, struct cpt_inst_s *inst,
507 : : struct cnxk_cpt_qp *qp, union cpt_inst_w7 w7)
508 : : {
509 : : const union cpt_res_s res = {.cn10k.compcode = CPT_COMP_NOT_DONE};
510 : 0 : struct cpt_inflight_req *infl_req = vec_req->req;
511 : :
512 : : const union cpt_inst_w4 w4 = {
513 : : .s.opcode_major = ROC_SE_MAJOR_OP_MISC,
514 : : .s.opcode_minor = ROC_SE_MISC_MINOR_OP_PASSTHROUGH,
515 : : .s.param1 = 1,
516 : : .s.param2 = 1,
517 : : .s.dlen = 0,
518 : : };
519 : :
520 : 0 : w7.s.egrp = ROC_CPT_DFLT_ENG_GRP_SE;
521 : :
522 : 0 : infl_req->vec = vec_req->vec;
523 : 0 : infl_req->qp = qp;
524 : :
525 : 0 : inst->res_addr = (uint64_t)&infl_req->res;
526 : 0 : rte_atomic_store_explicit((uint64_t __rte_atomic *)&infl_req->res.u64[0], res.u64[0],
527 : : rte_memory_order_relaxed);
528 : :
529 : 0 : inst->w0.u64 = 0;
530 : 0 : inst->w2.u64 = vec_req->w2;
531 : 0 : inst->w3.u64 = CNXK_CPT_INST_W3(1, infl_req);
532 : 0 : inst->w4.u64 = w4.u64;
533 : 0 : inst->w5.u64 = 0;
534 : 0 : inst->w6.u64 = 0;
535 : 0 : inst->w7.u64 = w7.u64;
536 : 0 : }
537 : :
538 : : static void
539 : 0 : cn10k_cpt_vec_pkt_submission_timeout_handle(void)
540 : : {
541 : 0 : plt_dp_err("Vector packet submission timedout");
542 : 0 : abort();
543 : : }
544 : :
545 : : static inline void
546 : 0 : cn10k_cpt_vec_submit(struct vec_request vec_tbl[], uint16_t vec_tbl_len, struct cnxk_cpt_qp *qp)
547 : : {
548 : : uint64_t lmt_base, lmt_id, io_addr;
549 : : uint64_t __rte_atomic *fc_addr;
550 : : union cpt_fc_write_s fc;
551 : : struct cpt_inst_s *inst;
552 : : uint16_t burst_size;
553 : : int i;
554 : :
555 [ # # ]: 0 : if (vec_tbl_len == 0)
556 : : return;
557 : :
558 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
559 : : /*
560 : : * Use 10 mins timeout for the poll. It is not possible to recover from partial submission
561 : : * of vector packet. Actual packets for processing are submitted to CPT prior to this
562 : : * routine. Hence, any failure for submission of vector packet would indicate an
563 : : * unrecoverable error for the application.
564 : : */
565 : 0 : const uint64_t timeout = rte_get_timer_cycles() + 10 * 60 * rte_get_timer_hz();
566 : :
567 : 0 : lmt_base = qp->lmtline.lmt_base;
568 : : io_addr = qp->lmtline.io_addr;
569 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
570 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
571 : 0 : inst = (struct cpt_inst_s *)lmt_base;
572 : :
573 : 0 : again:
574 : 0 : burst_size = RTE_MIN(CN10K_PKTS_PER_STEORL, vec_tbl_len);
575 [ # # ]: 0 : for (i = 0; i < burst_size; i++)
576 : 0 : cn10k_cpt_vec_inst_fill(&vec_tbl[i], &inst[i], qp, vec_tbl[0].w7);
577 : :
578 : : do {
579 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
580 [ # # ]: 0 : if (likely(fc.s.qsize < fc_thresh))
581 : : break;
582 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() > timeout))
583 : 0 : cn10k_cpt_vec_pkt_submission_timeout_handle();
584 : : } while (true);
585 : :
586 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
587 : :
588 : 0 : vec_tbl_len -= i;
589 : :
590 [ # # ]: 0 : if (vec_tbl_len > 0) {
591 : 0 : vec_tbl += i;
592 : 0 : goto again;
593 : : }
594 : : }
595 : :
596 : : static inline int
597 : 0 : ca_lmtst_vec_submit(struct ops_burst *burst, struct vec_request vec_tbl[], uint16_t *vec_tbl_len,
598 : : const bool is_sg_ver2)
599 : : {
600 : : struct cpt_inflight_req *infl_reqs[CN10K_CPT_PKTS_PER_LOOP];
601 : 0 : uint16_t lmt_id, len = *vec_tbl_len;
602 : : struct cpt_inst_s *inst, *inst_base;
603 : : struct cpt_inflight_req *infl_req;
604 : : uint64_t __rte_atomic *fc_addr;
605 : : struct rte_event_vector *vec;
606 : : uint64_t lmt_base, io_addr;
607 : : union cpt_fc_write_s fc;
608 : : struct cnxk_cpt_qp *qp;
609 : : int ret, i, vi;
610 : :
611 : 0 : qp = burst->qp;
612 : :
613 : 0 : lmt_base = qp->lmtline.lmt_base;
614 : : io_addr = qp->lmtline.io_addr;
615 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
616 : :
617 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
618 : :
619 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
620 : 0 : inst_base = (struct cpt_inst_s *)lmt_base;
621 : :
622 : : #ifdef CNXK_CRYPTODEV_DEBUG
623 : : if (unlikely(!qp->ca.enabled)) {
624 : : rte_errno = EINVAL;
625 : : return 0;
626 : : }
627 : : #endif
628 : :
629 : : /* Perform fc check before putting packets into vectors */
630 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
631 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
632 : 0 : rte_errno = EAGAIN;
633 : 0 : return 0;
634 : : }
635 : :
636 [ # # # # ]: 0 : if (unlikely(rte_mempool_get_bulk(qp->ca.req_mp, (void **)infl_reqs, burst->nb_ops))) {
637 : 0 : rte_errno = ENOMEM;
638 : 0 : return 0;
639 : : }
640 : :
641 [ # # ]: 0 : for (i = 0; i < burst->nb_ops; i++) {
642 : 0 : inst = &inst_base[i];
643 : 0 : infl_req = infl_reqs[i];
644 : 0 : infl_req->op_flags = 0;
645 : :
646 : 0 : ret = cn10k_cpt_fill_inst(qp, &burst->op[i], inst, infl_req, is_sg_ver2);
647 [ # # ]: 0 : if (unlikely(ret != 1)) {
648 : 0 : plt_cpt_dbg("Could not process op: %p", burst->op[i]);
649 [ # # ]: 0 : if (i != 0)
650 : 0 : goto submit;
651 : : else
652 : 0 : goto put;
653 : : }
654 : :
655 : 0 : infl_req->res.cn10k.compcode = CPT_COMP_NOT_DONE;
656 : 0 : infl_req->qp = qp;
657 : 0 : inst->w3.u64 = 0x1;
658 : :
659 : : /* Lookup for existing vector by w2 */
660 [ # # ]: 0 : for (vi = len - 1; vi >= 0; vi--) {
661 [ # # ]: 0 : if (vec_tbl[vi].w2 != burst->w2[i])
662 : 0 : continue;
663 : 0 : vec = vec_tbl[vi].vec;
664 [ # # ]: 0 : if (unlikely(vec->nb_elem == qp->ca.vector_sz))
665 : 0 : continue;
666 : 0 : vec->ptrs[vec->nb_elem++] = infl_req;
667 : 0 : goto next_op; /* continue outer loop */
668 : : }
669 : :
670 : : /* No available vectors found, allocate a new one */
671 [ # # # # ]: 0 : if (unlikely(rte_mempool_get(qp->ca.vector_mp, (void **)&vec_tbl[len].vec))) {
672 : 0 : rte_errno = ENOMEM;
673 [ # # ]: 0 : if (i != 0)
674 : 0 : goto submit;
675 : : else
676 : 0 : goto put;
677 : : }
678 : : /* Also preallocate in-flight request, that will be used to
679 : : * submit misc passthrough instruction
680 : : */
681 [ # # # # ]: 0 : if (unlikely(rte_mempool_get(qp->ca.req_mp, (void **)&vec_tbl[len].req))) {
682 [ # # ]: 0 : rte_mempool_put(qp->ca.vector_mp, vec_tbl[len].vec);
683 : 0 : rte_errno = ENOMEM;
684 [ # # ]: 0 : if (i != 0)
685 : 0 : goto submit;
686 : : else
687 : 0 : goto put;
688 : : }
689 : 0 : vec_tbl[len].w2 = burst->w2[i];
690 : 0 : vec_tbl[len].vec->ptrs[0] = infl_req;
691 : 0 : vec_tbl[len].vec->nb_elem = 1;
692 : 0 : len++;
693 : :
694 : 0 : next_op:;
695 : : }
696 : :
697 : : /* Submit operations in burst */
698 : 0 : submit:
699 [ # # ]: 0 : if (CNXK_TT_FROM_TAG(burst->ws->gw_rdata) == SSO_TT_ORDERED)
700 : 0 : roc_sso_hws_head_wait(burst->ws->base);
701 : :
702 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
703 : :
704 : : /* Store w7 of last successfully filled instruction */
705 : 0 : inst = &inst_base[2 * (i - 1)];
706 : 0 : vec_tbl[0].w7 = inst->w7;
707 : :
708 : 0 : put:
709 [ # # ]: 0 : if (i != burst->nb_ops)
710 [ # # ]: 0 : rte_mempool_put_bulk(qp->ca.req_mp, (void *)&infl_reqs[i], burst->nb_ops - i);
711 : :
712 : 0 : *vec_tbl_len = len;
713 : :
714 : 0 : return i;
715 : : }
716 : :
717 : : static inline uint16_t
718 : 0 : ca_lmtst_burst_submit(struct ops_burst *burst, const bool is_sg_ver2)
719 : : {
720 : : struct cpt_inflight_req *infl_reqs[CN10K_CPT_PKTS_PER_LOOP];
721 : : struct cpt_inst_s *inst, *inst_base;
722 : : struct cpt_inflight_req *infl_req;
723 : : uint64_t __rte_atomic *fc_addr;
724 : : uint64_t lmt_base, io_addr;
725 : : union cpt_fc_write_s fc;
726 : : struct cnxk_cpt_qp *qp;
727 : : uint16_t lmt_id;
728 : : int ret, i, j;
729 : :
730 : 0 : qp = burst->qp;
731 : :
732 : 0 : lmt_base = qp->lmtline.lmt_base;
733 : : io_addr = qp->lmtline.io_addr;
734 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
735 : :
736 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
737 : :
738 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
739 : 0 : inst_base = (struct cpt_inst_s *)lmt_base;
740 : :
741 : : #ifdef CNXK_CRYPTODEV_DEBUG
742 : : if (unlikely(!qp->ca.enabled)) {
743 : : rte_errno = EINVAL;
744 : : return 0;
745 : : }
746 : : #endif
747 : :
748 [ # # # # ]: 0 : if (unlikely(rte_mempool_get_bulk(qp->ca.req_mp, (void **)infl_reqs, burst->nb_ops))) {
749 : 0 : rte_errno = ENOMEM;
750 : 0 : return 0;
751 : : }
752 : :
753 [ # # ]: 0 : for (i = 0; i < burst->nb_ops; i++) {
754 : 0 : inst = &inst_base[i];
755 : 0 : infl_req = infl_reqs[i];
756 : 0 : infl_req->op_flags = 0;
757 : :
758 : 0 : ret = cn10k_cpt_fill_inst(qp, &burst->op[i], inst, infl_req, is_sg_ver2);
759 [ # # ]: 0 : if (unlikely(ret != 1)) {
760 : : plt_dp_dbg("Could not process op: %p", burst->op[i]);
761 [ # # ]: 0 : if (i != 0)
762 : 0 : goto submit;
763 : : else
764 : 0 : goto put;
765 : : }
766 : :
767 : 0 : infl_req->res.cn10k.compcode = CPT_COMP_NOT_DONE;
768 : 0 : infl_req->qp = qp;
769 : 0 : inst->w0.u64 = 0;
770 : 0 : inst->res_addr = (uint64_t)&infl_req->res;
771 : 0 : inst->w2.u64 = burst->w2[i];
772 : 0 : inst->w3.u64 = CNXK_CPT_INST_W3(1, infl_req);
773 : : }
774 : :
775 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
776 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
777 : 0 : rte_errno = EAGAIN;
778 [ # # ]: 0 : for (j = 0; j < i; j++) {
779 : 0 : infl_req = infl_reqs[j];
780 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
781 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
782 : : }
783 : : i = 0;
784 : 0 : goto put;
785 : : }
786 : :
787 : 0 : submit:
788 [ # # ]: 0 : if (CNXK_TT_FROM_TAG(burst->ws->gw_rdata) == SSO_TT_ORDERED)
789 : 0 : roc_sso_hws_head_wait(burst->ws->base);
790 : :
791 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
792 : :
793 : 0 : put:
794 [ # # ]: 0 : if (unlikely(i != burst->nb_ops))
795 [ # # ]: 0 : rte_mempool_put_bulk(qp->ca.req_mp, (void *)&infl_reqs[i], burst->nb_ops - i);
796 : :
797 : 0 : return i;
798 : : }
799 : :
800 : : static inline uint16_t __rte_hot
801 : 0 : cn10k_cpt_crypto_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events,
802 : : const bool is_sg_ver2)
803 : 0 : {
804 : 0 : uint16_t submitted, count = 0, vec_tbl_len = 0;
805 : 0 : struct vec_request vec_tbl[nb_events];
806 : : struct rte_crypto_op *op;
807 : : struct ops_burst burst;
808 : : struct cnxk_cpt_qp *qp;
809 : : bool is_vector = false;
810 : : uint64_t w2;
811 : : int ret, i;
812 : :
813 : 0 : burst.ws = ws;
814 : 0 : burst.qp = NULL;
815 : 0 : burst.nb_ops = 0;
816 : :
817 [ # # ]: 0 : for (i = 0; i < nb_events; i++) {
818 : 0 : op = ev[i].event_ptr;
819 : 0 : ret = cn10k_ca_meta_info_extract(op, &qp, &w2);
820 [ # # ]: 0 : if (unlikely(ret)) {
821 : 0 : rte_errno = EINVAL;
822 : 0 : goto vec_submit;
823 : : }
824 : :
825 : : /* Queue pair change check */
826 [ # # ]: 0 : if (qp != burst.qp) {
827 [ # # ]: 0 : if (burst.nb_ops) {
828 [ # # ]: 0 : if (is_vector) {
829 : 0 : submitted = ca_lmtst_vec_submit(&burst, vec_tbl,
830 : : &vec_tbl_len, is_sg_ver2);
831 : : /*
832 : : * Vector submission is required on qp change, but not in
833 : : * other cases, since we could send several vectors per
834 : : * lmtst instruction only for same qp
835 : : */
836 : 0 : cn10k_cpt_vec_submit(vec_tbl, vec_tbl_len, burst.qp);
837 : 0 : vec_tbl_len = 0;
838 : : } else {
839 : 0 : submitted = ca_lmtst_burst_submit(&burst, is_sg_ver2);
840 : : }
841 : 0 : count += submitted;
842 [ # # ]: 0 : if (unlikely(submitted != burst.nb_ops))
843 : 0 : goto vec_submit;
844 : 0 : burst.nb_ops = 0;
845 : : }
846 : 0 : is_vector = qp->ca.vector_sz;
847 : 0 : burst.qp = qp;
848 : : }
849 : 0 : burst.w2[burst.nb_ops] = w2;
850 : 0 : burst.op[burst.nb_ops] = op;
851 : :
852 : : /* Max nb_ops per burst check */
853 [ # # ]: 0 : if (++burst.nb_ops == CN10K_CPT_PKTS_PER_LOOP) {
854 [ # # ]: 0 : if (is_vector)
855 : 0 : submitted = ca_lmtst_vec_submit(&burst, vec_tbl, &vec_tbl_len,
856 : : is_sg_ver2);
857 : : else
858 : 0 : submitted = ca_lmtst_burst_submit(&burst, is_sg_ver2);
859 : 0 : count += submitted;
860 [ # # ]: 0 : if (unlikely(submitted != burst.nb_ops))
861 : 0 : goto vec_submit;
862 : 0 : burst.nb_ops = 0;
863 : : }
864 : : }
865 : : /* Submit the rest of crypto operations */
866 [ # # ]: 0 : if (burst.nb_ops) {
867 [ # # ]: 0 : if (is_vector)
868 : 0 : count += ca_lmtst_vec_submit(&burst, vec_tbl, &vec_tbl_len, is_sg_ver2);
869 : : else
870 : 0 : count += ca_lmtst_burst_submit(&burst, is_sg_ver2);
871 : : }
872 : :
873 : 0 : vec_submit:
874 : 0 : cn10k_cpt_vec_submit(vec_tbl, vec_tbl_len, burst.qp);
875 : 0 : return count;
876 : : }
877 : :
878 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cpt_sg_ver1_crypto_adapter_enqueue)
879 : : uint16_t __rte_hot
880 : 0 : cn10k_cpt_sg_ver1_crypto_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
881 : : {
882 : 0 : return cn10k_cpt_crypto_adapter_enqueue(ws, ev, nb_events, false);
883 : : }
884 : :
885 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cpt_sg_ver2_crypto_adapter_enqueue)
886 : : uint16_t __rte_hot
887 : 0 : cn10k_cpt_sg_ver2_crypto_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
888 : : {
889 : 0 : return cn10k_cpt_crypto_adapter_enqueue(ws, ev, nb_events, true);
890 : : }
891 : :
892 : : static inline void
893 : 0 : cn10k_cpt_ipsec_post_process(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
894 : : {
895 : 0 : struct rte_mbuf *mbuf = cop->sym->m_src;
896 : 0 : const uint16_t m_len = res->rlen;
897 : :
898 [ # # # # : 0 : switch (res->uc_compcode) {
# # ]
899 : 0 : case ROC_IE_OT_UCC_SUCCESS_PKT_IP_BADCSUM:
900 : 0 : mbuf->ol_flags &= ~RTE_MBUF_F_RX_IP_CKSUM_GOOD;
901 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
902 : 0 : break;
903 : 0 : case ROC_IE_OT_UCC_SUCCESS_PKT_L4_GOODCSUM:
904 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD |
905 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD;
906 : 0 : break;
907 : 0 : case ROC_IE_OT_UCC_SUCCESS_PKT_L4_BADCSUM:
908 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD |
909 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD;
910 : 0 : break;
911 : : case ROC_IE_OT_UCC_SUCCESS_PKT_IP_GOODCSUM:
912 : : break;
913 : 0 : case ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_FIRST:
914 : : case ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_AGAIN:
915 : 0 : cop->aux_flags = RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY;
916 : 0 : break;
917 : 0 : default:
918 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
919 : 0 : cop->aux_flags = res->uc_compcode;
920 : 0 : return;
921 : : }
922 : :
923 [ # # ]: 0 : if (mbuf->next == NULL)
924 : 0 : mbuf->data_len = m_len;
925 : :
926 : 0 : mbuf->pkt_len = m_len;
927 : : }
928 : :
929 : : static inline void
930 : 0 : cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res, uint8_t mac_len)
931 : : {
932 : : struct rte_mbuf *mac_prev_seg = NULL, *mac_seg = NULL, *seg;
933 : : uint32_t pad_len, trim_len, mac_offset, pad_offset;
934 : 0 : struct rte_mbuf *mbuf = cop->sym->m_src;
935 : 0 : uint16_t m_len = res->rlen;
936 : : uint32_t i, nb_segs = 1;
937 : : uint8_t pad_res = 0;
938 : : uint8_t pad_val;
939 : :
940 : 0 : pad_val = ((res->spi >> 16) & 0xff);
941 : 0 : pad_len = pad_val + 1;
942 : 0 : trim_len = pad_len + mac_len;
943 : 0 : mac_offset = m_len - trim_len;
944 : 0 : pad_offset = mac_offset + mac_len;
945 : :
946 : : /* Handle Direct Mode */
947 [ # # ]: 0 : if (mbuf->next == NULL) {
948 : 0 : uint8_t *ptr = rte_pktmbuf_mtod_offset(mbuf, uint8_t *, pad_offset);
949 : :
950 [ # # ]: 0 : for (i = 0; i < pad_len; i++)
951 : 0 : pad_res |= ptr[i] ^ pad_val;
952 : :
953 [ # # ]: 0 : if (pad_res) {
954 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
955 : 0 : cop->aux_flags = res->uc_compcode;
956 : : }
957 : 0 : mbuf->pkt_len = m_len - trim_len;
958 : 0 : mbuf->data_len = m_len - trim_len;
959 : :
960 : 0 : return;
961 : : }
962 : :
963 : : /* Handle SG mode */
964 : : seg = mbuf;
965 [ # # ]: 0 : while (mac_offset >= seg->data_len) {
966 : 0 : mac_offset -= seg->data_len;
967 : : mac_prev_seg = seg;
968 : 0 : seg = seg->next;
969 : 0 : nb_segs++;
970 : : }
971 : : mac_seg = seg;
972 : :
973 : 0 : pad_offset = mac_offset + mac_len;
974 [ # # ]: 0 : while (pad_offset >= seg->data_len) {
975 : 0 : pad_offset -= seg->data_len;
976 : 0 : seg = seg->next;
977 : : }
978 : :
979 [ # # ]: 0 : while (pad_len != 0) {
980 : 0 : uint8_t *ptr = rte_pktmbuf_mtod_offset(seg, uint8_t *, pad_offset);
981 : 0 : uint8_t len = RTE_MIN(seg->data_len - pad_offset, pad_len);
982 : :
983 [ # # ]: 0 : for (i = 0; i < len; i++)
984 : 0 : pad_res |= ptr[i] ^ pad_val;
985 : :
986 : : pad_offset = 0;
987 : 0 : pad_len -= len;
988 : 0 : seg = seg->next;
989 : : }
990 : :
991 [ # # ]: 0 : if (pad_res) {
992 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
993 : 0 : cop->aux_flags = res->uc_compcode;
994 : : }
995 : :
996 : 0 : mbuf->pkt_len = m_len - trim_len;
997 [ # # ]: 0 : if (mac_offset) {
998 : 0 : rte_pktmbuf_free(mac_seg->next);
999 : 0 : mac_seg->next = NULL;
1000 : 0 : mac_seg->data_len = mac_offset;
1001 : 0 : mbuf->nb_segs = nb_segs;
1002 : : } else {
1003 : 0 : rte_pktmbuf_free(mac_seg);
1004 : 0 : mac_prev_seg->next = NULL;
1005 : 0 : mbuf->nb_segs = nb_segs - 1;
1006 : : }
1007 : : }
1008 : :
1009 : : /* TLS-1.3:
1010 : : * Read from last until a non-zero value is encountered.
1011 : : * Return the non zero value as the content type.
1012 : : * Remove the MAC and content type and padding bytes.
1013 : : */
1014 : : static inline void
1015 : 0 : cn10k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
1016 : : {
1017 : 0 : struct rte_mbuf *mbuf = cop->sym->m_src;
1018 : : struct rte_mbuf *seg = mbuf;
1019 : 0 : uint16_t m_len = res->rlen;
1020 : : uint8_t *ptr, type = 0x0;
1021 : : int len, i, nb_segs = 1;
1022 : :
1023 [ # # ]: 0 : while (m_len && !type) {
1024 : 0 : len = m_len;
1025 : : seg = mbuf;
1026 : :
1027 : : /* get the last seg */
1028 [ # # ]: 0 : while (len > seg->data_len) {
1029 : 0 : len -= seg->data_len;
1030 : 0 : seg = seg->next;
1031 : 0 : nb_segs++;
1032 : : }
1033 : :
1034 : : /* walkthrough from last until a non zero value is found */
1035 : 0 : ptr = rte_pktmbuf_mtod(seg, uint8_t *);
1036 : : i = len;
1037 [ # # # # ]: 0 : while (i && (ptr[--i] == 0))
1038 : : ;
1039 : :
1040 : 0 : type = ptr[i];
1041 : 0 : m_len -= len;
1042 : : }
1043 : :
1044 [ # # ]: 0 : if (type) {
1045 : 0 : cop->param1.tls_record.content_type = type;
1046 : 0 : mbuf->pkt_len = m_len + i;
1047 : 0 : mbuf->nb_segs = nb_segs;
1048 : 0 : seg->data_len = i;
1049 : 0 : rte_pktmbuf_free(seg->next);
1050 : 0 : seg->next = NULL;
1051 : : } else {
1052 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1053 : : }
1054 : 0 : }
1055 : :
1056 : : static inline void
1057 : 0 : cn10k_cpt_tls_post_process(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res,
1058 : : struct cn10k_sec_session *sess)
1059 : : {
1060 : 0 : struct cn10k_tls_opt tls_opt = sess->tls_opt;
1061 : 0 : struct rte_mbuf *mbuf = cop->sym->m_src;
1062 : 0 : uint16_t m_len = res->rlen;
1063 : :
1064 [ # # ]: 0 : if (!res->uc_compcode) {
1065 [ # # ]: 0 : if (mbuf->next == NULL)
1066 : 0 : mbuf->data_len = m_len;
1067 : 0 : mbuf->pkt_len = m_len;
1068 : 0 : cop->param1.tls_record.content_type = (res->spi >> 24) & 0xff;
1069 : 0 : return;
1070 : : }
1071 : :
1072 : : /* Any error other than post process */
1073 [ # # ]: 0 : if (res->uc_compcode != ROC_SE_ERR_SSL_POST_PROCESS) {
1074 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1075 : 0 : cop->aux_flags = res->uc_compcode;
1076 : 0 : plt_err("crypto op failed with UC compcode: 0x%x", res->uc_compcode);
1077 : 0 : return;
1078 : : }
1079 : :
1080 : : /* Extra padding scenario: Verify padding. Remove padding and MAC */
1081 [ # # ]: 0 : if (tls_opt.tls_ver != RTE_SECURITY_VERSION_TLS_1_3)
1082 : 0 : cn10k_cpt_tls12_trim_mac(cop, res, (uint8_t)tls_opt.mac_len);
1083 : : else
1084 : 0 : cn10k_cpt_tls13_trim_mac(cop, res);
1085 : : }
1086 : :
1087 : : static inline void
1088 : 0 : cn10k_cpt_sec_post_process(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
1089 : : {
1090 : : struct rte_crypto_sym_op *sym_op = cop->sym;
1091 : : struct cn10k_sec_session *sess;
1092 : :
1093 : 0 : sess = sym_op->session;
1094 [ # # ]: 0 : if (sess->proto == RTE_SECURITY_PROTOCOL_IPSEC)
1095 : 0 : cn10k_cpt_ipsec_post_process(cop, res);
1096 [ # # ]: 0 : else if (sess->proto == RTE_SECURITY_PROTOCOL_TLS_RECORD)
1097 : 0 : cn10k_cpt_tls_post_process(cop, res, sess);
1098 : 0 : }
1099 : :
1100 : : static inline void
1101 : 0 : cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp, struct rte_crypto_op *cop,
1102 : : struct cpt_inflight_req *infl_req, struct cpt_cn10k_res_s *res)
1103 : : {
1104 : 0 : const uint8_t uc_compcode = res->uc_compcode;
1105 : 0 : const uint8_t compcode = res->compcode;
1106 : :
1107 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1108 : :
1109 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
1110 : : cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
1111 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD || compcode == CPT_COMP_WARN)) {
1112 : : /* Success with additional info */
1113 : 0 : cn10k_cpt_sec_post_process(cop, res);
1114 : : } else {
1115 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1116 : 0 : plt_dp_info("HW completion code 0x%x", res->compcode);
1117 [ # # ]: 0 : if (compcode == CPT_COMP_GOOD) {
1118 : 0 : plt_dp_info(
1119 : : "Request failed with microcode error");
1120 : 0 : plt_dp_info("MC completion code 0x%x",
1121 : : uc_compcode);
1122 : : }
1123 : : }
1124 : :
1125 : 0 : return;
1126 [ # # ]: 0 : } else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC &&
1127 : : cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
1128 : : struct cnxk_ae_sess *sess;
1129 : :
1130 : 0 : sess = (struct cnxk_ae_sess *)cop->asym->session;
1131 [ # # ]: 0 : if (sess->xfrm_type == RTE_CRYPTO_ASYM_XFORM_ECDH &&
1132 [ # # ]: 0 : cop->asym->ecdh.ke_type == RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY) {
1133 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD)) {
1134 [ # # ]: 0 : if (uc_compcode == ROC_AE_ERR_ECC_POINT_NOT_ON_CURVE) {
1135 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1136 : 0 : return;
1137 [ # # ]: 0 : } else if (uc_compcode == ROC_AE_ERR_ECC_PAI) {
1138 : : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1139 : : return;
1140 : : }
1141 : : }
1142 : : }
1143 : : }
1144 : :
1145 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD)) {
1146 : : #ifdef CPT_INST_DEBUG_ENABLE
1147 : : if (infl_req->is_sg_ver2)
1148 : : cnxk_cpt_request_data_sgv2_mode_dump(infl_req->rptr, 0,
1149 : : infl_req->scatter_sz);
1150 : : else {
1151 : : if (infl_req->opcode_major >> 7)
1152 : : cnxk_cpt_request_data_sg_mode_dump(infl_req->dptr, 0);
1153 : : }
1154 : : #endif
1155 : :
1156 [ # # ]: 0 : if (unlikely(uc_compcode)) {
1157 [ # # ]: 0 : if (uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
1158 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
1159 : : else
1160 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1161 : :
1162 : 0 : plt_dp_info("Request failed with microcode error");
1163 : 0 : plt_dp_info("MC completion code 0x%x",
1164 : : res->uc_compcode);
1165 : 0 : cop->aux_flags = uc_compcode;
1166 : 0 : goto temp_sess_free;
1167 : : }
1168 : :
1169 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
1170 : : /* Verify authentication data if required */
1171 [ # # ]: 0 : if (unlikely(infl_req->op_flags &
1172 : : CPT_OP_FLAGS_AUTH_VERIFY)) {
1173 : 0 : uintptr_t *rsp = infl_req->mdata;
1174 [ # # ]: 0 : compl_auth_verify(cop, (uint8_t *)rsp[0],
1175 : : rsp[1]);
1176 : : }
1177 [ # # ]: 0 : } else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
1178 : : struct rte_crypto_asym_op *op = cop->asym;
1179 : 0 : uintptr_t *mdata = infl_req->mdata;
1180 : 0 : struct cnxk_ae_sess *sess = (struct cnxk_ae_sess *)op->session;
1181 : :
1182 [ # # # # : 0 : cnxk_ae_post_process(cop, sess, (uint8_t *)mdata[0]);
# # # # ]
1183 : : }
1184 : : } else {
1185 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
1186 : 0 : plt_dp_info("HW completion code 0x%x", res->compcode);
1187 : :
1188 [ # # # # ]: 0 : switch (compcode) {
1189 : 0 : case CPT_COMP_INSTERR:
1190 : 0 : plt_dp_err("Request failed with instruction error");
1191 : 0 : break;
1192 : 0 : case CPT_COMP_FAULT:
1193 : 0 : plt_dp_err("Request failed with DMA fault");
1194 : 0 : break;
1195 : 0 : case CPT_COMP_HWERR:
1196 : 0 : plt_dp_err("Request failed with hardware error");
1197 : 0 : break;
1198 : 0 : default:
1199 : 0 : plt_dp_err(
1200 : : "Request failed with unknown completion code");
1201 : : }
1202 : : }
1203 : :
1204 : 0 : temp_sess_free:
1205 [ # # ]: 0 : if (unlikely(cop->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {
1206 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
1207 : 0 : sym_session_clear(cop->sym->session, true);
1208 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, cop->sym->session);
1209 : 0 : cop->sym->session = NULL;
1210 : : }
1211 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
1212 : 0 : cnxk_ae_session_clear(NULL, cop->asym->session);
1213 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, cop->asym->session);
1214 : 0 : cop->asym->session = NULL;
1215 : : }
1216 : : }
1217 : : }
1218 : :
1219 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cpt_crypto_adapter_dequeue)
1220 : : uintptr_t
1221 : 0 : cn10k_cpt_crypto_adapter_dequeue(uintptr_t get_work1)
1222 : : {
1223 : : struct cpt_inflight_req *infl_req;
1224 : : struct rte_crypto_op *cop;
1225 : : struct cnxk_cpt_qp *qp;
1226 : : union cpt_res_s res;
1227 : :
1228 : 0 : infl_req = (struct cpt_inflight_req *)(get_work1);
1229 : 0 : cop = infl_req->cop;
1230 : 0 : qp = infl_req->qp;
1231 : :
1232 : 0 : res.u64[0] = rte_atomic_load_explicit((uint64_t __rte_atomic *)&infl_req->res.u64[0],
1233 : : rte_memory_order_relaxed);
1234 : :
1235 : 0 : cn10k_cpt_dequeue_post_process(qp, infl_req->cop, infl_req, &res.cn10k);
1236 : :
1237 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1238 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1239 : :
1240 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
1241 : 0 : return (uintptr_t)cop;
1242 : : }
1243 : :
1244 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cpt_crypto_adapter_vector_dequeue)
1245 : : uintptr_t
1246 : 0 : cn10k_cpt_crypto_adapter_vector_dequeue(uintptr_t get_work1)
1247 : : {
1248 : : struct cpt_inflight_req *infl_req, *vec_infl_req;
1249 : : struct rte_mempool *meta_mp, *req_mp;
1250 : : struct rte_event_vector *vec;
1251 : : struct rte_crypto_op *cop;
1252 : : struct cnxk_cpt_qp *qp;
1253 : : union cpt_res_s res;
1254 : : int i;
1255 : :
1256 : 0 : vec_infl_req = (struct cpt_inflight_req *)(get_work1);
1257 : :
1258 : 0 : vec = vec_infl_req->vec;
1259 : 0 : qp = vec_infl_req->qp;
1260 : 0 : meta_mp = qp->meta_info.pool;
1261 : 0 : req_mp = qp->ca.req_mp;
1262 : :
1263 : : #ifdef CNXK_CRYPTODEV_DEBUG
1264 : : res.u64[0] = rte_atomic_load_explicit((uint64_t __rte_atomic *)&vec_infl_req->res.u64[0],
1265 : : rte_memory_order_relaxed);
1266 : : PLT_ASSERT(res.cn10k.compcode == CPT_COMP_GOOD);
1267 : : PLT_ASSERT(res.cn10k.uc_compcode == 0);
1268 : : #endif
1269 : :
1270 [ # # ]: 0 : for (i = 0; i < vec->nb_elem; i++) {
1271 : 0 : infl_req = vec->ptrs[i];
1272 : 0 : cop = infl_req->cop;
1273 : :
1274 : 0 : res.u64[0] = rte_atomic_load_explicit(
1275 : : (uint64_t __rte_atomic *)&infl_req->res.u64[0], rte_memory_order_relaxed);
1276 : 0 : cn10k_cpt_dequeue_post_process(qp, cop, infl_req, &res.cn10k);
1277 : :
1278 : 0 : vec->ptrs[i] = cop;
1279 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1280 [ # # ]: 0 : rte_mempool_put(meta_mp, infl_req->mdata);
1281 : :
1282 : 0 : rte_mempool_put(req_mp, infl_req);
1283 : : }
1284 : :
1285 : 0 : rte_mempool_put(req_mp, vec_infl_req);
1286 : :
1287 : 0 : return (uintptr_t)vec;
1288 : : }
1289 : :
1290 : : static uint16_t
1291 : 0 : cn10k_cpt_dequeue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
1292 : : {
1293 : : struct cpt_inflight_req *infl_req;
1294 : : struct cnxk_cpt_qp *qp = qptr;
1295 : : struct pending_queue *pend_q;
1296 : : uint64_t infl_cnt, pq_tail;
1297 : : struct rte_crypto_op *cop;
1298 : : union cpt_res_s res;
1299 : : int i;
1300 : :
1301 : : pend_q = &qp->pend_q;
1302 : :
1303 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1304 : :
1305 : 0 : pq_tail = pend_q->tail;
1306 : 0 : infl_cnt = pending_queue_infl_cnt(pend_q->head, pq_tail, pq_mask);
1307 : 0 : nb_ops = RTE_MIN(nb_ops, infl_cnt);
1308 : :
1309 : : /* Ensure infl_cnt isn't read before data lands */
1310 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
1311 : :
1312 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
1313 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1314 : :
1315 : 0 : res.u64[0] = rte_atomic_load_explicit(
1316 : : (uint64_t __rte_atomic *)&infl_req->res.u64[0], rte_memory_order_relaxed);
1317 : :
1318 [ # # ]: 0 : if (unlikely(res.cn10k.compcode == CPT_COMP_NOT_DONE)) {
1319 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() >
1320 : : pend_q->time_out)) {
1321 : 0 : plt_err("Request timed out");
1322 : 0 : cnxk_cpt_dump_on_err(qp);
1323 : 0 : pend_q->time_out = rte_get_timer_cycles() +
1324 : 0 : DEFAULT_COMMAND_TIMEOUT *
1325 : : rte_get_timer_hz();
1326 : : }
1327 : : break;
1328 : : }
1329 : :
1330 : : pending_queue_advance(&pq_tail, pq_mask);
1331 : :
1332 : 0 : cop = infl_req->cop;
1333 : :
1334 : 0 : ops[i] = cop;
1335 : :
1336 : 0 : cn10k_cpt_dequeue_post_process(qp, cop, infl_req, &res.cn10k);
1337 : :
1338 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1339 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1340 : : }
1341 : :
1342 : 0 : pend_q->tail = pq_tail;
1343 : :
1344 : 0 : return i;
1345 : : }
1346 : :
1347 : : #if defined(RTE_ARCH_ARM64)
1348 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cryptodev_sec_inb_rx_inject)
1349 : : uint16_t __rte_hot
1350 : : cn10k_cryptodev_sec_inb_rx_inject(void *dev, struct rte_mbuf **pkts,
1351 : : struct rte_security_session **sess, uint16_t nb_pkts)
1352 : : {
1353 : : uint64_t lmt_base, io_addr, u64_0, u64_1, l2_len, pf_func;
1354 : : uint64x2_t inst_01, inst_23, inst_45, inst_67;
1355 : : struct cn10k_sec_session *sec_sess;
1356 : : struct rte_cryptodev *cdev = dev;
1357 : : union cpt_res_s *hw_res = NULL;
1358 : : uint16_t lmt_id, count = 0;
1359 : : struct cpt_inst_s *inst;
1360 : : union cpt_fc_write_s fc;
1361 : : struct cnxk_cpt_vf *vf;
1362 : : struct rte_mbuf *m;
1363 : : uint64_t u64_dptr;
1364 : : uint64_t *fc_addr;
1365 : : int i;
1366 : :
1367 : : vf = cdev->data->dev_private;
1368 : :
1369 : : lmt_base = vf->rx_inj_lmtline.lmt_base;
1370 : : io_addr = vf->rx_inj_lmtline.io_addr;
1371 : : fc_addr = vf->rx_inj_lmtline.fc_addr;
1372 : :
1373 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
1374 : : pf_func = vf->rx_inj_sso_pf_func;
1375 : :
1376 : : const uint32_t fc_thresh = vf->rx_inj_lmtline.fc_thresh;
1377 : :
1378 : : again:
1379 : : fc.u64[0] =
1380 : : rte_atomic_load_explicit((RTE_ATOMIC(uint64_t) *)fc_addr, rte_memory_order_relaxed);
1381 : : inst = (struct cpt_inst_s *)lmt_base;
1382 : :
1383 : : i = 0;
1384 : :
1385 : : if (unlikely(fc.s.qsize > fc_thresh))
1386 : : goto exit;
1387 : :
1388 : : for (; i < RTE_MIN(CN10K_CPT_PKTS_PER_LOOP, nb_pkts); i++) {
1389 : :
1390 : : m = pkts[i];
1391 : : sec_sess = (struct cn10k_sec_session *)sess[i];
1392 : :
1393 : : if (unlikely(rte_pktmbuf_headroom(m) < 32)) {
1394 : : plt_dp_err("No space for CPT res_s");
1395 : : break;
1396 : : }
1397 : :
1398 : : l2_len = m->l2_len;
1399 : :
1400 : : *rte_security_dynfield(m) = (uint64_t)sec_sess->userdata;
1401 : :
1402 : : hw_res = rte_pktmbuf_mtod(m, void *);
1403 : : hw_res = RTE_PTR_SUB(hw_res, 32);
1404 : : hw_res = RTE_PTR_ALIGN_CEIL(hw_res, 16);
1405 : :
1406 : : /* Prepare CPT instruction */
1407 : : if (m->nb_segs > 1) {
1408 : : struct rte_mbuf *last = rte_pktmbuf_lastseg(m);
1409 : : uintptr_t dptr, rxphdr, wqe_hdr;
1410 : : uint16_t i;
1411 : :
1412 : : if ((m->nb_segs > CNXK_CPT_MAX_SG_SEGS) ||
1413 : : (rte_pktmbuf_tailroom(m) < CNXK_CPT_MIN_TAILROOM_REQ))
1414 : : goto exit;
1415 : :
1416 : : wqe_hdr = rte_pktmbuf_mtod_offset(last, uintptr_t, last->data_len);
1417 : : wqe_hdr += BIT_ULL(7);
1418 : : wqe_hdr = (wqe_hdr - 1) & ~(BIT_ULL(7) - 1);
1419 : :
1420 : : /* Pointer to WQE header */
1421 : : *(uint64_t *)(m + 1) = wqe_hdr;
1422 : :
1423 : : /* Reserve SG list after end of last mbuf data location. */
1424 : : rxphdr = wqe_hdr + 8;
1425 : : dptr = rxphdr + 7 * 8;
1426 : :
1427 : : /* Prepare Multiseg SG list */
1428 : : i = fill_sg2_comp_from_pkt((struct roc_sg2list_comp *)dptr, 0, m);
1429 : : u64_dptr = dptr | ((uint64_t)(i) << 60);
1430 : : } else {
1431 : : struct roc_sg2list_comp *sg2;
1432 : : uintptr_t dptr, wqe_hdr;
1433 : :
1434 : : /* Reserve space for WQE, NIX_RX_PARSE_S and SG_S.
1435 : : * Populate SG_S with num segs and seg length
1436 : : */
1437 : : wqe_hdr = (uintptr_t)(m + 1);
1438 : : *(uint64_t *)(m + 1) = wqe_hdr;
1439 : :
1440 : : sg2 = (struct roc_sg2list_comp *)(wqe_hdr + 8 * 8);
1441 : : sg2->u.s.len[0] = rte_pktmbuf_pkt_len(m);
1442 : : sg2->u.s.valid_segs = 1;
1443 : :
1444 : : dptr = (uint64_t)rte_pktmbuf_iova(m);
1445 : : u64_dptr = dptr;
1446 : : }
1447 : :
1448 : : /* Word 0 and 1 */
1449 : : inst_01 = vdupq_n_u64(0);
1450 : : u64_0 = pf_func << 48 | *(vf->rx_chan_base + m->port) << 4 | (l2_len - 2) << 24 |
1451 : : l2_len << 16;
1452 : : inst_01 = vsetq_lane_u64(u64_0, inst_01, 0);
1453 : : inst_01 = vsetq_lane_u64((uint64_t)hw_res, inst_01, 1);
1454 : : vst1q_u64(&inst->w0.u64, inst_01);
1455 : :
1456 : : /* Word 2 and 3 */
1457 : : inst_23 = vdupq_n_u64(0);
1458 : : u64_1 = (((uint64_t)m + sizeof(struct rte_mbuf)) >> 3) << 3 | 1;
1459 : : inst_23 = vsetq_lane_u64(u64_1, inst_23, 1);
1460 : : vst1q_u64(&inst->w2.u64, inst_23);
1461 : :
1462 : : /* Word 4 and 5 */
1463 : : inst_45 = vdupq_n_u64(0);
1464 : : u64_0 = sec_sess->inst.w4 | (rte_pktmbuf_pkt_len(m));
1465 : : inst_45 = vsetq_lane_u64(u64_0, inst_45, 0);
1466 : : inst_45 = vsetq_lane_u64(u64_dptr, inst_45, 1);
1467 : : vst1q_u64(&inst->w4.u64, inst_45);
1468 : :
1469 : : /* Word 6 and 7 */
1470 : : inst_67 = vdupq_n_u64(0);
1471 : : u64_1 = sec_sess->inst.w7;
1472 : : inst_67 = vsetq_lane_u64(u64_1, inst_67, 1);
1473 : : vst1q_u64(&inst->w6.u64, inst_67);
1474 : :
1475 : : inst++;
1476 : : }
1477 : :
1478 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
1479 : :
1480 : : if (nb_pkts - i > 0 && i == CN10K_CPT_PKTS_PER_LOOP) {
1481 : : nb_pkts -= CN10K_CPT_PKTS_PER_LOOP;
1482 : : pkts += CN10K_CPT_PKTS_PER_LOOP;
1483 : : count += CN10K_CPT_PKTS_PER_LOOP;
1484 : : sess += CN10K_CPT_PKTS_PER_LOOP;
1485 : : goto again;
1486 : : }
1487 : :
1488 : : exit:
1489 : : return count + i;
1490 : : }
1491 : : #else
1492 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cryptodev_sec_inb_rx_inject)
1493 : : uint16_t __rte_hot
1494 : 0 : cn10k_cryptodev_sec_inb_rx_inject(void *dev, struct rte_mbuf **pkts,
1495 : : struct rte_security_session **sess, uint16_t nb_pkts)
1496 : : {
1497 : : RTE_SET_USED(dev);
1498 : : RTE_SET_USED(pkts);
1499 : : RTE_SET_USED(sess);
1500 : : RTE_SET_USED(nb_pkts);
1501 : 0 : return 0;
1502 : : }
1503 : : #endif
1504 : :
1505 : : void
1506 : 0 : cn10k_cpt_set_enqdeq_fns(struct rte_cryptodev *dev, struct cnxk_cpt_vf *vf)
1507 : : {
1508 [ # # # # ]: 0 : if (vf->cpt.hw_caps[CPT_ENG_TYPE_SE].sg_ver2 && vf->cpt.hw_caps[CPT_ENG_TYPE_IE].sg_ver2)
1509 : 0 : dev->enqueue_burst = cn10k_cpt_sg_ver2_enqueue_burst;
1510 : : else
1511 : 0 : dev->enqueue_burst = cn10k_cpt_sg_ver1_enqueue_burst;
1512 : :
1513 : 0 : dev->dequeue_burst = cn10k_cpt_dequeue_burst;
1514 : :
1515 : : rte_mb();
1516 : 0 : }
1517 : :
1518 : : static void
1519 : 0 : cn10k_cpt_dev_info_get(struct rte_cryptodev *dev,
1520 : : struct rte_cryptodev_info *info)
1521 : : {
1522 [ # # ]: 0 : if (info != NULL) {
1523 : 0 : cnxk_cpt_dev_info_get(dev, info);
1524 : 0 : info->driver_id = cn10k_cryptodev_driver_id;
1525 : : }
1526 : 0 : }
1527 : :
1528 : : static inline int
1529 : 0 : cn10k_cpt_raw_fill_inst(struct cnxk_iov *iov, struct cnxk_cpt_qp *qp,
1530 : : struct cnxk_sym_dp_ctx *dp_ctx, struct cpt_inst_s inst[],
1531 : : struct cpt_inflight_req *infl_req, void *opaque, const bool is_sg_ver2)
1532 : : {
1533 : : struct cnxk_se_sess *sess;
1534 : : int ret;
1535 : :
1536 : : const union cpt_res_s res = {
1537 : : .cn10k.compcode = CPT_COMP_NOT_DONE,
1538 : : };
1539 : :
1540 : 0 : inst[0].w0.u64 = 0;
1541 : 0 : inst[0].w2.u64 = 0;
1542 : 0 : inst[0].w3.u64 = 0;
1543 : :
1544 : 0 : sess = dp_ctx->sess;
1545 : :
1546 [ # # # # : 0 : switch (sess->dp_thr_type) {
# ]
1547 : 0 : case CPT_DP_THREAD_TYPE_PT:
1548 : 0 : ret = fill_raw_passthrough_params(iov, inst);
1549 : 0 : break;
1550 [ # # ]: 0 : case CPT_DP_THREAD_TYPE_FC_CHAIN:
1551 : : ret = fill_raw_fc_params(iov, sess, &qp->meta_info, infl_req, &inst[0], false,
1552 : : false, is_sg_ver2);
1553 : 0 : break;
1554 [ # # ]: 0 : case CPT_DP_THREAD_TYPE_FC_AEAD:
1555 : : ret = fill_raw_fc_params(iov, sess, &qp->meta_info, infl_req, &inst[0], false, true,
1556 : : is_sg_ver2);
1557 : 0 : break;
1558 [ # # ]: 0 : case CPT_DP_THREAD_AUTH_ONLY:
1559 : : ret = fill_raw_digest_params(iov, sess, &qp->meta_info, infl_req, &inst[0],
1560 : : is_sg_ver2);
1561 : 0 : break;
1562 : : default:
1563 : : ret = -EINVAL;
1564 : : }
1565 : :
1566 [ # # ]: 0 : if (unlikely(ret))
1567 : : return 0;
1568 : :
1569 : 0 : inst[0].res_addr = (uint64_t)&infl_req->res;
1570 : 0 : rte_atomic_store_explicit((uint64_t __rte_atomic *)&infl_req->res.u64[0], res.u64[0],
1571 : : rte_memory_order_relaxed);
1572 : 0 : infl_req->opaque = opaque;
1573 : :
1574 : 0 : inst[0].w7.u64 = sess->cpt_inst_w7;
1575 : :
1576 : 0 : return 1;
1577 : : }
1578 : :
1579 : : static uint32_t
1580 : 0 : cn10k_cpt_raw_enqueue_burst(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym_vec *vec,
1581 : : union rte_crypto_sym_ofs ofs, void *user_data[], int *enqueue_status,
1582 : : const bool is_sgv2)
1583 : : {
1584 : 0 : uint16_t lmt_id, nb_allowed, nb_ops = vec->num;
1585 : : struct cpt_inflight_req *infl_req;
1586 : : uint64_t lmt_base, io_addr, head;
1587 : : struct cnxk_cpt_qp *qp = qpair;
1588 : : struct cnxk_sym_dp_ctx *dp_ctx;
1589 : : uint64_t __rte_atomic *fc_addr;
1590 : : struct pending_queue *pend_q;
1591 : : uint32_t count = 0, index;
1592 : : union cpt_fc_write_s fc;
1593 : : struct cpt_inst_s *inst;
1594 : : int ret, i;
1595 : :
1596 : : pend_q = &qp->pend_q;
1597 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1598 : :
1599 : 0 : head = pend_q->head;
1600 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
1601 : 0 : nb_ops = RTE_MIN(nb_ops, nb_allowed);
1602 : :
1603 [ # # ]: 0 : if (unlikely(nb_ops == 0))
1604 : : return 0;
1605 : :
1606 : 0 : lmt_base = qp->lmtline.lmt_base;
1607 : : io_addr = qp->lmtline.io_addr;
1608 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
1609 : :
1610 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
1611 : :
1612 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
1613 : 0 : inst = (struct cpt_inst_s *)lmt_base;
1614 : :
1615 : : dp_ctx = (struct cnxk_sym_dp_ctx *)drv_ctx;
1616 : 0 : again:
1617 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
1618 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
1619 : : i = 0;
1620 : 0 : goto pend_q_commit;
1621 : : }
1622 : :
1623 [ # # ]: 0 : for (i = 0; i < RTE_MIN(CN10K_CPT_PKTS_PER_LOOP, nb_ops); i++) {
1624 : : struct cnxk_iov iov;
1625 : :
1626 : 0 : index = count + i;
1627 : 0 : infl_req = &pend_q->req_queue[head];
1628 : 0 : infl_req->op_flags = 0;
1629 : :
1630 : 0 : cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
1631 : 0 : ret = cn10k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[i], infl_req,
1632 : 0 : user_data[index], is_sgv2);
1633 [ # # ]: 0 : if (unlikely(ret != 1)) {
1634 : 0 : plt_dp_err("Could not process vec: %d", index);
1635 [ # # ]: 0 : if (i == 0 && count == 0)
1636 : 0 : return -1;
1637 [ # # ]: 0 : else if (i == 0)
1638 : 0 : goto pend_q_commit;
1639 : : else
1640 : : break;
1641 : : }
1642 : : pending_queue_advance(&head, pq_mask);
1643 : : }
1644 : :
1645 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
1646 : :
1647 [ # # # # ]: 0 : if (nb_ops - i > 0 && i == CN10K_CPT_PKTS_PER_LOOP) {
1648 : 0 : nb_ops -= i;
1649 : 0 : count += i;
1650 : 0 : goto again;
1651 : : }
1652 : :
1653 : 0 : pend_q_commit:
1654 : : rte_atomic_thread_fence(__ATOMIC_RELEASE);
1655 : :
1656 : 0 : pend_q->head = head;
1657 : 0 : pend_q->time_out = rte_get_timer_cycles() + DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1658 : :
1659 : 0 : *enqueue_status = 1;
1660 : 0 : return count + i;
1661 : : }
1662 : :
1663 : : static uint32_t
1664 : 0 : cn10k_cpt_raw_enqueue_burst_sgv2(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym_vec *vec,
1665 : : union rte_crypto_sym_ofs ofs, void *user_data[],
1666 : : int *enqueue_status)
1667 : : {
1668 : 0 : return cn10k_cpt_raw_enqueue_burst(qpair, drv_ctx, vec, ofs, user_data, enqueue_status,
1669 : : true);
1670 : : }
1671 : :
1672 : : static uint32_t
1673 : 0 : cn10k_cpt_raw_enqueue_burst_sgv1(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym_vec *vec,
1674 : : union rte_crypto_sym_ofs ofs, void *user_data[],
1675 : : int *enqueue_status)
1676 : : {
1677 : 0 : return cn10k_cpt_raw_enqueue_burst(qpair, drv_ctx, vec, ofs, user_data, enqueue_status,
1678 : : false);
1679 : : }
1680 : :
1681 : : static int
1682 : 0 : cn10k_cpt_raw_enqueue(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data_vec,
1683 : : uint16_t n_data_vecs, union rte_crypto_sym_ofs ofs,
1684 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
1685 : : struct rte_crypto_va_iova_ptr *aad_or_auth_iv, void *user_data,
1686 : : const bool is_sgv2)
1687 : : {
1688 : : struct cpt_inflight_req *infl_req;
1689 : : uint64_t lmt_base, io_addr, head;
1690 : : struct cnxk_cpt_qp *qp = qpair;
1691 : : struct cnxk_sym_dp_ctx *dp_ctx;
1692 : : uint64_t __rte_atomic *fc_addr;
1693 : : uint16_t lmt_id, nb_allowed;
1694 : : struct cpt_inst_s *inst;
1695 : : union cpt_fc_write_s fc;
1696 : : struct cnxk_iov iov;
1697 : : int ret, i = 1;
1698 : :
1699 : : struct pending_queue *pend_q = &qp->pend_q;
1700 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1701 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
1702 : :
1703 : 0 : head = pend_q->head;
1704 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
1705 : :
1706 [ # # ]: 0 : if (unlikely(nb_allowed == 0))
1707 : : return -1;
1708 : :
1709 : : cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
1710 : :
1711 : 0 : lmt_base = qp->lmtline.lmt_base;
1712 : : io_addr = qp->lmtline.io_addr;
1713 : 0 : fc_addr = (uint64_t __rte_atomic *)qp->lmtline.fc_addr;
1714 : :
1715 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
1716 : 0 : inst = (struct cpt_inst_s *)lmt_base;
1717 : :
1718 : 0 : fc.u64[0] = rte_atomic_load_explicit(fc_addr, rte_memory_order_relaxed);
1719 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh))
1720 : : return -1;
1721 : :
1722 : : dp_ctx = (struct cnxk_sym_dp_ctx *)drv_ctx;
1723 : 0 : infl_req = &pend_q->req_queue[head];
1724 : 0 : infl_req->op_flags = 0;
1725 : :
1726 : 0 : ret = cn10k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[0], infl_req, user_data, is_sgv2);
1727 [ # # ]: 0 : if (unlikely(ret != 1)) {
1728 : 0 : plt_dp_err("Could not process vec");
1729 : 0 : return -1;
1730 : : }
1731 : :
1732 : : pending_queue_advance(&head, pq_mask);
1733 : :
1734 : : cn10k_cpt_lmtst_dual_submit(&io_addr, lmt_id, &i);
1735 : :
1736 : 0 : pend_q->head = head;
1737 : 0 : pend_q->time_out = rte_get_timer_cycles() + DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1738 : :
1739 : 0 : return 1;
1740 : : }
1741 : :
1742 : : static int
1743 : 0 : cn10k_cpt_raw_enqueue_sgv2(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data_vec,
1744 : : uint16_t n_data_vecs, union rte_crypto_sym_ofs ofs,
1745 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
1746 : : struct rte_crypto_va_iova_ptr *aad_or_auth_iv, void *user_data)
1747 : : {
1748 : 0 : return cn10k_cpt_raw_enqueue(qpair, drv_ctx, data_vec, n_data_vecs, ofs, iv, digest,
1749 : : aad_or_auth_iv, user_data, true);
1750 : : }
1751 : :
1752 : : static int
1753 : 0 : cn10k_cpt_raw_enqueue_sgv1(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data_vec,
1754 : : uint16_t n_data_vecs, union rte_crypto_sym_ofs ofs,
1755 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
1756 : : struct rte_crypto_va_iova_ptr *aad_or_auth_iv, void *user_data)
1757 : : {
1758 : 0 : return cn10k_cpt_raw_enqueue(qpair, drv_ctx, data_vec, n_data_vecs, ofs, iv, digest,
1759 : : aad_or_auth_iv, user_data, false);
1760 : : }
1761 : :
1762 : : static inline int
1763 : 0 : cn10k_cpt_raw_dequeue_post_process(struct cpt_cn10k_res_s *res)
1764 : : {
1765 : 0 : const uint8_t uc_compcode = res->uc_compcode;
1766 : 0 : const uint8_t compcode = res->compcode;
1767 : : int ret = 1;
1768 : :
1769 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD)) {
1770 [ # # ]: 0 : if (unlikely(uc_compcode))
1771 : 0 : plt_dp_info("Request failed with microcode error: 0x%x", res->uc_compcode);
1772 : : else
1773 : : ret = 0;
1774 : : }
1775 : :
1776 : 0 : return ret;
1777 : : }
1778 : :
1779 : : static uint32_t
1780 : 0 : cn10k_cpt_sym_raw_dequeue_burst(void *qptr, uint8_t *drv_ctx,
1781 : : rte_cryptodev_raw_get_dequeue_count_t get_dequeue_count,
1782 : : uint32_t max_nb_to_dequeue,
1783 : : rte_cryptodev_raw_post_dequeue_t post_dequeue, void **out_user_data,
1784 : : uint8_t is_user_data_array, uint32_t *n_success,
1785 : : int *dequeue_status)
1786 : : {
1787 : : struct cpt_inflight_req *infl_req;
1788 : : struct cnxk_cpt_qp *qp = qptr;
1789 : : struct pending_queue *pend_q;
1790 : : uint64_t infl_cnt, pq_tail;
1791 : : union cpt_res_s res;
1792 : : int is_op_success;
1793 : : uint16_t nb_ops;
1794 : : void *opaque;
1795 : : int i = 0;
1796 : :
1797 : : pend_q = &qp->pend_q;
1798 : :
1799 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1800 : :
1801 : : RTE_SET_USED(drv_ctx);
1802 : 0 : pq_tail = pend_q->tail;
1803 [ # # ]: 0 : infl_cnt = pending_queue_infl_cnt(pend_q->head, pq_tail, pq_mask);
1804 : :
1805 : : /* Ensure infl_cnt isn't read before data lands */
1806 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
1807 : :
1808 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1809 : :
1810 : 0 : opaque = infl_req->opaque;
1811 [ # # ]: 0 : if (get_dequeue_count)
1812 : 0 : nb_ops = get_dequeue_count(opaque);
1813 : : else
1814 : 0 : nb_ops = max_nb_to_dequeue;
1815 : 0 : nb_ops = RTE_MIN(nb_ops, infl_cnt);
1816 : :
1817 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
1818 : : is_op_success = 0;
1819 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1820 : :
1821 : 0 : res.u64[0] = rte_atomic_load_explicit(
1822 : : (uint64_t __rte_atomic *)&infl_req->res.u64[0], rte_memory_order_relaxed);
1823 : :
1824 [ # # ]: 0 : if (unlikely(res.cn10k.compcode == CPT_COMP_NOT_DONE)) {
1825 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() > pend_q->time_out)) {
1826 : 0 : plt_err("Request timed out");
1827 : 0 : cnxk_cpt_dump_on_err(qp);
1828 : 0 : pend_q->time_out = rte_get_timer_cycles() +
1829 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1830 : : }
1831 : : break;
1832 : : }
1833 : :
1834 : : pending_queue_advance(&pq_tail, pq_mask);
1835 : :
1836 [ # # ]: 0 : if (!cn10k_cpt_raw_dequeue_post_process(&res.cn10k)) {
1837 : : is_op_success = 1;
1838 : 0 : *n_success += 1;
1839 : : }
1840 : :
1841 [ # # ]: 0 : if (is_user_data_array) {
1842 : 0 : out_user_data[i] = infl_req->opaque;
1843 : 0 : post_dequeue(out_user_data[i], i, is_op_success);
1844 : : } else {
1845 [ # # ]: 0 : if (i == 0)
1846 : 0 : out_user_data[0] = opaque;
1847 : 0 : post_dequeue(out_user_data[0], i, is_op_success);
1848 : : }
1849 : :
1850 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1851 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1852 : : }
1853 : :
1854 : 0 : pend_q->tail = pq_tail;
1855 : 0 : *dequeue_status = 1;
1856 : :
1857 : 0 : return i;
1858 : : }
1859 : :
1860 : : static void *
1861 : 0 : cn10k_cpt_sym_raw_dequeue(void *qptr, uint8_t *drv_ctx, int *dequeue_status,
1862 : : enum rte_crypto_op_status *op_status)
1863 : : {
1864 : : struct cpt_inflight_req *infl_req;
1865 : : struct cnxk_cpt_qp *qp = qptr;
1866 : : struct pending_queue *pend_q;
1867 : : union cpt_res_s res;
1868 : : void *opaque = NULL;
1869 : : uint64_t pq_tail;
1870 : :
1871 : : pend_q = &qp->pend_q;
1872 : :
1873 : : const uint64_t pq_mask = pend_q->pq_mask;
1874 : :
1875 : : RTE_SET_USED(drv_ctx);
1876 : :
1877 [ # # ]: 0 : pq_tail = pend_q->tail;
1878 : :
1879 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
1880 : :
1881 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1882 : :
1883 : 0 : res.u64[0] = rte_atomic_load_explicit((uint64_t __rte_atomic *)&infl_req->res.u64[0],
1884 : : rte_memory_order_relaxed);
1885 : :
1886 [ # # ]: 0 : if (unlikely(res.cn10k.compcode == CPT_COMP_NOT_DONE)) {
1887 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() > pend_q->time_out)) {
1888 : 0 : plt_err("Request timed out");
1889 : 0 : cnxk_cpt_dump_on_err(qp);
1890 : 0 : pend_q->time_out = rte_get_timer_cycles() +
1891 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1892 : : }
1893 : 0 : goto exit;
1894 : : }
1895 : :
1896 : : pending_queue_advance(&pq_tail, pq_mask);
1897 : :
1898 : 0 : opaque = infl_req->opaque;
1899 : :
1900 [ # # ]: 0 : if (!cn10k_cpt_raw_dequeue_post_process(&res.cn10k))
1901 : 0 : *op_status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1902 : : else
1903 : 0 : *op_status = RTE_CRYPTO_OP_STATUS_ERROR;
1904 : :
1905 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1906 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1907 : :
1908 : 0 : *dequeue_status = 1;
1909 : 0 : exit:
1910 : 0 : return opaque;
1911 : : }
1912 : :
1913 : : static int
1914 : 0 : cn10k_sym_get_raw_dp_ctx_size(struct rte_cryptodev *dev __rte_unused)
1915 : : {
1916 : 0 : return sizeof(struct cnxk_sym_dp_ctx);
1917 : : }
1918 : :
1919 : : static int
1920 : 0 : cn10k_sym_configure_raw_dp_ctx(struct rte_cryptodev *dev, uint16_t qp_id,
1921 : : struct rte_crypto_raw_dp_ctx *raw_dp_ctx,
1922 : : enum rte_crypto_op_sess_type sess_type,
1923 : : union rte_cryptodev_session_ctx session_ctx, uint8_t is_update)
1924 : : {
1925 : 0 : struct cnxk_se_sess *sess = (struct cnxk_se_sess *)session_ctx.crypto_sess;
1926 : : struct cnxk_sym_dp_ctx *dp_ctx;
1927 : :
1928 [ # # ]: 0 : if (sess_type != RTE_CRYPTO_OP_WITH_SESSION)
1929 : : return -ENOTSUP;
1930 : :
1931 [ # # ]: 0 : if (sess == NULL)
1932 : : return -EINVAL;
1933 : :
1934 : 0 : if ((sess->dp_thr_type == CPT_DP_THREAD_TYPE_PDCP) ||
1935 : : (sess->dp_thr_type == CPT_DP_THREAD_TYPE_PDCP_CHAIN) ||
1936 [ # # ]: 0 : (sess->dp_thr_type == CPT_DP_THREAD_TYPE_KASUMI) ||
1937 : : (sess->dp_thr_type == CPT_DP_THREAD_TYPE_SM))
1938 : : return -ENOTSUP;
1939 : :
1940 [ # # ]: 0 : if ((sess->dp_thr_type == CPT_DP_THREAD_AUTH_ONLY) &&
1941 [ # # ]: 0 : ((sess->roc_se_ctx.fc_type == ROC_SE_KASUMI) ||
1942 : : (sess->roc_se_ctx.fc_type == ROC_SE_PDCP)))
1943 : : return -ENOTSUP;
1944 : :
1945 [ # # ]: 0 : if (sess->roc_se_ctx.hash_type == ROC_SE_SHA1_TYPE)
1946 : : return -ENOTSUP;
1947 : :
1948 : : dp_ctx = (struct cnxk_sym_dp_ctx *)raw_dp_ctx->drv_ctx_data;
1949 : 0 : dp_ctx->sess = sess;
1950 : :
1951 [ # # ]: 0 : if (!is_update) {
1952 : : struct cnxk_cpt_vf *vf;
1953 : :
1954 : 0 : raw_dp_ctx->qp_data = (struct cnxk_cpt_qp *)dev->data->queue_pairs[qp_id];
1955 : 0 : raw_dp_ctx->dequeue = cn10k_cpt_sym_raw_dequeue;
1956 : 0 : raw_dp_ctx->dequeue_burst = cn10k_cpt_sym_raw_dequeue_burst;
1957 : :
1958 : 0 : vf = dev->data->dev_private;
1959 [ # # ]: 0 : if (vf->cpt.hw_caps[CPT_ENG_TYPE_SE].sg_ver2 &&
1960 [ # # ]: 0 : vf->cpt.hw_caps[CPT_ENG_TYPE_IE].sg_ver2) {
1961 : 0 : raw_dp_ctx->enqueue = cn10k_cpt_raw_enqueue_sgv2;
1962 : 0 : raw_dp_ctx->enqueue_burst = cn10k_cpt_raw_enqueue_burst_sgv2;
1963 : : } else {
1964 : 0 : raw_dp_ctx->enqueue = cn10k_cpt_raw_enqueue_sgv1;
1965 : 0 : raw_dp_ctx->enqueue_burst = cn10k_cpt_raw_enqueue_burst_sgv1;
1966 : : }
1967 : : }
1968 : :
1969 : : return 0;
1970 : : }
1971 : :
1972 : : RTE_EXPORT_INTERNAL_SYMBOL(cn10k_cryptodev_sec_rx_inject_configure)
1973 : : int
1974 : 0 : cn10k_cryptodev_sec_rx_inject_configure(void *device, uint16_t port_id, bool enable)
1975 : : {
1976 : : struct rte_cryptodev *crypto_dev = device;
1977 : : struct rte_eth_dev *eth_dev;
1978 : : struct cnxk_cpt_vf *vf;
1979 : : int ret;
1980 : :
1981 [ # # ]: 0 : if (!rte_eth_dev_is_valid_port(port_id))
1982 : : return -EINVAL;
1983 : :
1984 [ # # ]: 0 : if (!(crypto_dev->feature_flags & RTE_CRYPTODEV_FF_SECURITY_RX_INJECT))
1985 : : return -ENOTSUP;
1986 : :
1987 : : /* Rx Inject is supported only with CPT05. sg_ver2 indicates that CPT05 is loaded */
1988 : 0 : vf = crypto_dev->data->dev_private;
1989 [ # # # # ]: 0 : if (!(vf->cpt.hw_caps[CPT_ENG_TYPE_SE].sg_ver2 && vf->cpt.hw_caps[CPT_ENG_TYPE_IE].sg_ver2))
1990 : : return -ENOTSUP;
1991 : :
1992 : : eth_dev = &rte_eth_devices[port_id];
1993 : :
1994 : 0 : ret = strncmp(eth_dev->device->driver->name, "net_cn10k", 8);
1995 [ # # ]: 0 : if (ret)
1996 : : return -ENOTSUP;
1997 : :
1998 : 0 : roc_idev_nix_rx_inject_set(port_id, enable);
1999 : :
2000 : 0 : return 0;
2001 : : }
2002 : :
2003 : : struct rte_cryptodev_ops cn10k_cpt_ops = {
2004 : : /* Device control ops */
2005 : : .dev_configure = cnxk_cpt_dev_config,
2006 : : .dev_start = cnxk_cpt_dev_start,
2007 : : .dev_stop = cnxk_cpt_dev_stop,
2008 : : .dev_close = cnxk_cpt_dev_close,
2009 : : .dev_infos_get = cn10k_cpt_dev_info_get,
2010 : :
2011 : : .stats_get = NULL,
2012 : : .stats_reset = NULL,
2013 : : .queue_pair_setup = cnxk_cpt_queue_pair_setup,
2014 : : .queue_pair_release = cnxk_cpt_queue_pair_release,
2015 : : .queue_pair_reset = cnxk_cpt_queue_pair_reset,
2016 : :
2017 : : /* Symmetric crypto ops */
2018 : : .sym_session_get_size = cnxk_cpt_sym_session_get_size,
2019 : : .sym_session_configure = cnxk_cpt_sym_session_configure,
2020 : : .sym_session_clear = cnxk_cpt_sym_session_clear,
2021 : :
2022 : : /* Asymmetric crypto ops */
2023 : : .asym_session_get_size = cnxk_ae_session_size_get,
2024 : : .asym_session_configure = cnxk_ae_session_cfg,
2025 : : .asym_session_clear = cnxk_ae_session_clear,
2026 : :
2027 : : /* Event crypto ops */
2028 : : .session_ev_mdata_set = cn10k_cpt_crypto_adapter_ev_mdata_set,
2029 : : .queue_pair_event_error_query = cnxk_cpt_queue_pair_event_error_query,
2030 : :
2031 : : /* Raw data-path API related operations */
2032 : : .sym_get_raw_dp_ctx_size = cn10k_sym_get_raw_dp_ctx_size,
2033 : : .sym_configure_raw_dp_ctx = cn10k_sym_configure_raw_dp_ctx,
2034 : : };
|