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 : :
10 : : #include "roc_cpt.h"
11 : : #if defined(__aarch64__)
12 : : #include "roc_io.h"
13 : : #else
14 : : #include "roc_io_generic.h"
15 : : #endif
16 : : #include "roc_sso.h"
17 : : #include "roc_sso_dp.h"
18 : :
19 : : #include "cn10k_cryptodev.h"
20 : : #include "cn10k_cryptodev_ops.h"
21 : : #include "cn10k_cryptodev_event_dp.h"
22 : : #include "cn10k_eventdev.h"
23 : : #include "cn10k_ipsec.h"
24 : : #include "cn10k_ipsec_la_ops.h"
25 : : #include "cnxk_ae.h"
26 : : #include "cnxk_cryptodev.h"
27 : : #include "cnxk_cryptodev_ops.h"
28 : : #include "cnxk_eventdev.h"
29 : : #include "cnxk_se.h"
30 : :
31 : : #define PKTS_PER_LOOP 32
32 : : #define PKTS_PER_STEORL 16
33 : :
34 : : /* Holds information required to send crypto operations in one burst */
35 : : struct ops_burst {
36 : : struct rte_crypto_op *op[PKTS_PER_LOOP];
37 : : uint64_t w2[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 __rte_always_inline int __rte_hot
80 : : cpt_sec_inst_fill(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op, struct cn10k_sec_session *sess,
81 : : struct cpt_inst_s *inst, struct cpt_inflight_req *infl_req, const bool is_sg_ver2)
82 : : {
83 : : struct rte_crypto_sym_op *sym_op = op->sym;
84 : : int ret;
85 : :
86 [ # # ]: 0 : if (unlikely(sym_op->m_dst && sym_op->m_dst != sym_op->m_src)) {
87 : 0 : plt_dp_err("Out of place is not supported");
88 : 0 : return -ENOTSUP;
89 : : }
90 : :
91 [ # # ]: 0 : if (sess->is_outbound)
92 : : ret = process_outb_sa(&qp->lf, op, sess, &qp->meta_info, infl_req, inst,
93 : : is_sg_ver2);
94 : : else
95 : : ret = process_inb_sa(op, sess, inst, &qp->meta_info, infl_req, is_sg_ver2);
96 : :
97 : : return ret;
98 : : }
99 : :
100 : : static inline int
101 : 0 : cn10k_cpt_fill_inst(struct cnxk_cpt_qp *qp, struct rte_crypto_op *ops[], struct cpt_inst_s inst[],
102 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2)
103 : : {
104 : : struct cn10k_sec_session *sec_sess;
105 : : struct rte_crypto_asym_op *asym_op;
106 : : struct rte_crypto_sym_op *sym_op;
107 : : struct cnxk_ae_sess *ae_sess;
108 : : struct cnxk_se_sess *sess;
109 : : struct rte_crypto_op *op;
110 : : uint64_t w7;
111 : : int ret;
112 : :
113 : : const union cpt_res_s res = {
114 : : .cn10k.compcode = CPT_COMP_NOT_DONE,
115 : : };
116 : :
117 : 0 : op = ops[0];
118 : :
119 : 0 : inst[0].w0.u64 = 0;
120 : 0 : inst[0].w2.u64 = 0;
121 : 0 : inst[0].w3.u64 = 0;
122 : :
123 : : sym_op = op->sym;
124 : :
125 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
126 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
127 [ # # ]: 0 : sec_sess = (struct cn10k_sec_session *)sym_op->session;
128 : : ret = cpt_sec_inst_fill(qp, op, sec_sess, &inst[0], infl_req, is_sg_ver2);
129 [ # # ]: 0 : if (unlikely(ret))
130 : : return 0;
131 : 0 : w7 = sec_sess->inst.w7;
132 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
133 [ # # ]: 0 : sess = (struct cnxk_se_sess *)(sym_op->session);
134 : : ret = cpt_sym_inst_fill(qp, op, sess, infl_req, &inst[0], is_sg_ver2);
135 [ # # ]: 0 : if (unlikely(ret))
136 : : return 0;
137 : 0 : w7 = sess->cpt_inst_w7;
138 : : } else {
139 : 0 : sess = cn10k_cpt_sym_temp_sess_create(qp, op);
140 [ # # ]: 0 : if (unlikely(sess == NULL)) {
141 : 0 : plt_dp_err("Could not create temp session");
142 : 0 : return 0;
143 : : }
144 : :
145 : : ret = cpt_sym_inst_fill(qp, op, sess, infl_req, &inst[0], is_sg_ver2);
146 [ # # ]: 0 : if (unlikely(ret)) {
147 : 0 : sym_session_clear(op->sym->session, true);
148 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, op->sym->session);
149 : 0 : return 0;
150 : : }
151 : 0 : w7 = sess->cpt_inst_w7;
152 : : }
153 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
154 : :
155 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
156 : : asym_op = op->asym;
157 [ # # ]: 0 : ae_sess = (struct cnxk_ae_sess *)asym_op->session;
158 : : ret = cnxk_ae_enqueue(qp, op, infl_req, &inst[0], ae_sess);
159 [ # # ]: 0 : if (unlikely(ret))
160 : : return 0;
161 : 0 : w7 = ae_sess->cpt_inst_w7;
162 : : } else {
163 : 0 : plt_dp_err("Not supported Asym op without session");
164 : 0 : return 0;
165 : : }
166 : : } else {
167 : 0 : plt_dp_err("Unsupported op type");
168 : 0 : return 0;
169 : : }
170 : :
171 : 0 : inst[0].res_addr = (uint64_t)&infl_req->res;
172 : 0 : __atomic_store_n(&infl_req->res.u64[0], res.u64[0], __ATOMIC_RELAXED);
173 : 0 : infl_req->cop = op;
174 : :
175 : 0 : inst[0].w7.u64 = w7;
176 : :
177 : 0 : return 1;
178 : : }
179 : :
180 : : static uint16_t
181 : 0 : cn10k_cpt_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops,
182 : : const bool is_sg_ver2)
183 : : {
184 : : uint64_t lmt_base, lmt_arg, io_addr;
185 : : struct cpt_inflight_req *infl_req;
186 : : uint16_t nb_allowed, count = 0;
187 : : struct cnxk_cpt_qp *qp = qptr;
188 : : struct pending_queue *pend_q;
189 : : struct cpt_inst_s *inst;
190 : : union cpt_fc_write_s fc;
191 : : uint64_t *fc_addr;
192 : : uint16_t lmt_id;
193 : : uint64_t head;
194 : : int ret, i;
195 : :
196 : : pend_q = &qp->pend_q;
197 : :
198 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
199 : :
200 : 0 : head = pend_q->head;
201 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
202 : 0 : nb_ops = RTE_MIN(nb_ops, nb_allowed);
203 : :
204 [ # # ]: 0 : if (unlikely(nb_ops == 0))
205 : : return 0;
206 : :
207 : 0 : lmt_base = qp->lmtline.lmt_base;
208 : : io_addr = qp->lmtline.io_addr;
209 : 0 : fc_addr = qp->lmtline.fc_addr;
210 : :
211 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
212 : :
213 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
214 : 0 : inst = (struct cpt_inst_s *)lmt_base;
215 : :
216 : 0 : again:
217 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
218 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
219 : : i = 0;
220 : 0 : goto pend_q_commit;
221 : : }
222 : :
223 [ # # ]: 0 : for (i = 0; i < RTE_MIN(PKTS_PER_LOOP, nb_ops); i++) {
224 : 0 : infl_req = &pend_q->req_queue[head];
225 : 0 : infl_req->op_flags = 0;
226 : :
227 : 0 : ret = cn10k_cpt_fill_inst(qp, ops + i, &inst[2 * i], infl_req, is_sg_ver2);
228 [ # # ]: 0 : if (unlikely(ret != 1)) {
229 : 0 : plt_dp_err("Could not process op: %p", ops + i);
230 [ # # ]: 0 : if (i == 0)
231 : 0 : goto pend_q_commit;
232 : : break;
233 : : }
234 : :
235 : : pending_queue_advance(&head, pq_mask);
236 : : }
237 : :
238 : : if (i > PKTS_PER_STEORL) {
239 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (PKTS_PER_STEORL - 1) << 12 |
240 : : (uint64_t)lmt_id;
241 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
242 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG |
243 : : (i - PKTS_PER_STEORL - 1) << 12 |
244 : : (uint64_t)(lmt_id + PKTS_PER_STEORL);
245 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
246 : : } else {
247 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - 1) << 12 |
248 : : (uint64_t)lmt_id;
249 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
250 : : }
251 : :
252 : 0 : rte_io_wmb();
253 : :
254 [ # # # # ]: 0 : if (nb_ops - i > 0 && i == PKTS_PER_LOOP) {
255 : 0 : nb_ops -= i;
256 : 0 : ops += i;
257 : 0 : count += i;
258 : 0 : goto again;
259 : : }
260 : :
261 : 0 : pend_q_commit:
262 : : rte_atomic_thread_fence(__ATOMIC_RELEASE);
263 : :
264 : 0 : pend_q->head = head;
265 : 0 : pend_q->time_out = rte_get_timer_cycles() +
266 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
267 : :
268 : 0 : return count + i;
269 : : }
270 : :
271 : : static uint16_t
272 : 0 : cn10k_cpt_sg_ver1_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
273 : : {
274 : 0 : return cn10k_cpt_enqueue_burst(qptr, ops, nb_ops, false);
275 : : }
276 : :
277 : : static uint16_t
278 : 0 : cn10k_cpt_sg_ver2_enqueue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
279 : : {
280 : 0 : return cn10k_cpt_enqueue_burst(qptr, ops, nb_ops, true);
281 : : }
282 : :
283 : : static int
284 : 0 : cn10k_cpt_crypto_adapter_ev_mdata_set(struct rte_cryptodev *dev __rte_unused, void *sess,
285 : : enum rte_crypto_op_type op_type,
286 : : enum rte_crypto_op_sess_type sess_type, void *mdata)
287 : : {
288 : : union rte_event_crypto_metadata *ec_mdata = mdata;
289 : : struct rte_event *rsp_info;
290 : : struct cnxk_cpt_qp *qp;
291 : : uint64_t w2, tag_type;
292 : : uint8_t cdev_id;
293 : : int16_t qp_id;
294 : :
295 : : /* Get queue pair */
296 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
297 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
298 : 0 : qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
299 : :
300 [ # # ]: 0 : if (!qp->ca.enabled)
301 : : return -EINVAL;
302 : :
303 : : /* Prepare w2 */
304 [ # # ]: 0 : tag_type = qp->ca.vector_sz ? RTE_EVENT_TYPE_CRYPTODEV_VECTOR : RTE_EVENT_TYPE_CRYPTODEV;
305 : : rsp_info = &ec_mdata->response_info;
306 : 0 : w2 = CNXK_CPT_INST_W2((tag_type << 28) | (rsp_info->sub_event_type << 20) |
307 : : rsp_info->flow_id,
308 : : rsp_info->sched_type, rsp_info->queue_id, 0);
309 : :
310 : : /* Set meta according to session type */
311 [ # # ]: 0 : if (op_type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
312 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
313 : : struct cn10k_sec_session *sec_sess = (struct cn10k_sec_session *)sess;
314 : :
315 : 0 : sec_sess->qp = qp;
316 : 0 : sec_sess->inst.w2 = w2;
317 [ # # ]: 0 : } else if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
318 : : struct cnxk_se_sess *priv;
319 : :
320 : : priv = (struct cnxk_se_sess *)sess;
321 : 0 : priv->qp = qp;
322 : 0 : priv->cpt_inst_w2 = w2;
323 : : } else
324 : : return -EINVAL;
325 [ # # ]: 0 : } else if (op_type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
326 [ # # ]: 0 : if (sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
327 : : struct cnxk_ae_sess *priv;
328 : :
329 : : priv = (struct cnxk_ae_sess *)sess;
330 : 0 : priv->qp = qp;
331 : 0 : priv->cpt_inst_w2 = w2;
332 : : } else
333 : : return -EINVAL;
334 : : } else
335 : : return -EINVAL;
336 : :
337 : : return 0;
338 : : }
339 : :
340 : : static inline int
341 : 0 : cn10k_ca_meta_info_extract(struct rte_crypto_op *op, struct cnxk_cpt_qp **qp, uint64_t *w2)
342 : : {
343 [ # # ]: 0 : if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
344 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
345 : : struct cn10k_sec_session *sec_sess;
346 : :
347 : 0 : sec_sess = (struct cn10k_sec_session *)op->sym->session;
348 : :
349 : 0 : *qp = sec_sess->qp;
350 : 0 : *w2 = sec_sess->inst.w2;
351 [ # # ]: 0 : } else if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
352 : : struct cnxk_se_sess *priv;
353 : :
354 : 0 : priv = (struct cnxk_se_sess *)op->sym->session;
355 : 0 : *qp = priv->qp;
356 : 0 : *w2 = priv->cpt_inst_w2;
357 : : } else {
358 : : union rte_event_crypto_metadata *ec_mdata;
359 : : struct rte_event *rsp_info;
360 : : uint8_t cdev_id;
361 : : uint16_t qp_id;
362 : :
363 [ # # ]: 0 : if (unlikely(op->private_data_offset == 0))
364 : : return -EINVAL;
365 : 0 : ec_mdata = (union rte_event_crypto_metadata *)
366 : 0 : ((uint8_t *)op + op->private_data_offset);
367 : : rsp_info = &ec_mdata->response_info;
368 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
369 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
370 : 0 : *qp = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
371 : 0 : *w2 = CNXK_CPT_INST_W2(
372 : : (RTE_EVENT_TYPE_CRYPTODEV << 28) | rsp_info->flow_id,
373 : : rsp_info->sched_type, rsp_info->queue_id, 0);
374 : : }
375 [ # # ]: 0 : } else if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
376 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) {
377 : : struct cnxk_ae_sess *priv;
378 : :
379 : 0 : priv = (struct cnxk_ae_sess *)op->asym->session;
380 : 0 : *qp = priv->qp;
381 : 0 : *w2 = priv->cpt_inst_w2;
382 : : } else
383 : : return -EINVAL;
384 : : } else
385 : : return -EINVAL;
386 : :
387 : : return 0;
388 : : }
389 : :
390 : : static inline void
391 : 0 : cn10k_cpt_vec_inst_fill(struct vec_request *vec_req, struct cpt_inst_s *inst,
392 : : struct cnxk_cpt_qp *qp, union cpt_inst_w7 w7)
393 : : {
394 : : const union cpt_res_s res = {.cn10k.compcode = CPT_COMP_NOT_DONE};
395 : 0 : struct cpt_inflight_req *infl_req = vec_req->req;
396 : :
397 : : const union cpt_inst_w4 w4 = {
398 : : .s.opcode_major = ROC_SE_MAJOR_OP_MISC,
399 : : .s.opcode_minor = ROC_SE_MISC_MINOR_OP_PASSTHROUGH,
400 : : .s.param1 = 1,
401 : : .s.param2 = 1,
402 : : .s.dlen = 0,
403 : : };
404 : :
405 : 0 : w7.s.egrp = ROC_CPT_DFLT_ENG_GRP_SE;
406 : :
407 : 0 : infl_req->vec = vec_req->vec;
408 : 0 : infl_req->qp = qp;
409 : :
410 : 0 : inst->res_addr = (uint64_t)&infl_req->res;
411 : 0 : __atomic_store_n(&infl_req->res.u64[0], res.u64[0], __ATOMIC_RELAXED);
412 : :
413 : 0 : inst->w0.u64 = 0;
414 : 0 : inst->w2.u64 = vec_req->w2;
415 : 0 : inst->w3.u64 = CNXK_CPT_INST_W3(1, infl_req);
416 : 0 : inst->w4.u64 = w4.u64;
417 : 0 : inst->w5.u64 = 0;
418 : 0 : inst->w6.u64 = 0;
419 : 0 : inst->w7.u64 = w7.u64;
420 : 0 : }
421 : :
422 : : static void
423 : 0 : cn10k_cpt_vec_pkt_submission_timeout_handle(void)
424 : : {
425 : 0 : plt_dp_err("Vector packet submission timedout");
426 : 0 : abort();
427 : : }
428 : :
429 : : static inline void
430 : 0 : cn10k_cpt_vec_submit(struct vec_request vec_tbl[], uint16_t vec_tbl_len, struct cnxk_cpt_qp *qp)
431 : : {
432 : : uint64_t lmt_base, lmt_arg, lmt_id, io_addr;
433 : : union cpt_fc_write_s fc;
434 : : struct cpt_inst_s *inst;
435 : : uint16_t burst_size;
436 : : uint64_t *fc_addr;
437 : : int i;
438 : :
439 [ # # ]: 0 : if (vec_tbl_len == 0)
440 : : return;
441 : :
442 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
443 : : /*
444 : : * Use 10 mins timeout for the poll. It is not possible to recover from partial submission
445 : : * of vector packet. Actual packets for processing are submitted to CPT prior to this
446 : : * routine. Hence, any failure for submission of vector packet would indicate an
447 : : * unrecoverable error for the application.
448 : : */
449 : 0 : const uint64_t timeout = rte_get_timer_cycles() + 10 * 60 * rte_get_timer_hz();
450 : :
451 : 0 : lmt_base = qp->lmtline.lmt_base;
452 : : io_addr = qp->lmtline.io_addr;
453 : 0 : fc_addr = qp->lmtline.fc_addr;
454 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
455 : 0 : inst = (struct cpt_inst_s *)lmt_base;
456 : :
457 : 0 : again:
458 : 0 : burst_size = RTE_MIN(PKTS_PER_STEORL, vec_tbl_len);
459 [ # # ]: 0 : for (i = 0; i < burst_size; i++)
460 : 0 : cn10k_cpt_vec_inst_fill(&vec_tbl[i], &inst[i * 2], qp, vec_tbl[0].w7);
461 : :
462 : : do {
463 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
464 [ # # ]: 0 : if (likely(fc.s.qsize < fc_thresh))
465 : : break;
466 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() > timeout))
467 : 0 : cn10k_cpt_vec_pkt_submission_timeout_handle();
468 : : } while (true);
469 : :
470 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - 1) << 12 | lmt_id;
471 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
472 : :
473 : 0 : rte_io_wmb();
474 : :
475 : 0 : vec_tbl_len -= i;
476 : :
477 [ # # ]: 0 : if (vec_tbl_len > 0) {
478 : 0 : vec_tbl += i;
479 : 0 : goto again;
480 : : }
481 : : }
482 : :
483 : : static inline int
484 : 0 : ca_lmtst_vec_submit(struct ops_burst *burst, struct vec_request vec_tbl[], uint16_t *vec_tbl_len,
485 : : const bool is_sg_ver2)
486 : : {
487 : : struct cpt_inflight_req *infl_reqs[PKTS_PER_LOOP];
488 : : uint64_t lmt_base, lmt_arg, io_addr;
489 : 0 : uint16_t lmt_id, len = *vec_tbl_len;
490 : : struct cpt_inst_s *inst, *inst_base;
491 : : struct cpt_inflight_req *infl_req;
492 : : struct rte_event_vector *vec;
493 : : union cpt_fc_write_s fc;
494 : : struct cnxk_cpt_qp *qp;
495 : : uint64_t *fc_addr;
496 : : int ret, i, vi;
497 : :
498 : 0 : qp = burst->qp;
499 : :
500 : 0 : lmt_base = qp->lmtline.lmt_base;
501 : : io_addr = qp->lmtline.io_addr;
502 : 0 : fc_addr = qp->lmtline.fc_addr;
503 : :
504 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
505 : :
506 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
507 : 0 : inst_base = (struct cpt_inst_s *)lmt_base;
508 : :
509 : : #ifdef CNXK_CRYPTODEV_DEBUG
510 : : if (unlikely(!qp->ca.enabled)) {
511 : : rte_errno = EINVAL;
512 : : return 0;
513 : : }
514 : : #endif
515 : :
516 : : /* Perform fc check before putting packets into vectors */
517 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
518 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
519 : 0 : rte_errno = EAGAIN;
520 : 0 : return 0;
521 : : }
522 : :
523 [ # # # # ]: 0 : if (unlikely(rte_mempool_get_bulk(qp->ca.req_mp, (void **)infl_reqs, burst->nb_ops))) {
524 : 0 : rte_errno = ENOMEM;
525 : 0 : return 0;
526 : : }
527 : :
528 [ # # ]: 0 : for (i = 0; i < burst->nb_ops; i++) {
529 : 0 : inst = &inst_base[2 * i];
530 : 0 : infl_req = infl_reqs[i];
531 : 0 : infl_req->op_flags = 0;
532 : :
533 : 0 : ret = cn10k_cpt_fill_inst(qp, &burst->op[i], inst, infl_req, is_sg_ver2);
534 [ # # ]: 0 : if (unlikely(ret != 1)) {
535 : 0 : plt_cpt_dbg("Could not process op: %p", burst->op[i]);
536 [ # # ]: 0 : if (i != 0)
537 : 0 : goto submit;
538 : : else
539 : 0 : goto put;
540 : : }
541 : :
542 : 0 : infl_req->res.cn10k.compcode = CPT_COMP_NOT_DONE;
543 : 0 : infl_req->qp = qp;
544 : 0 : inst->w3.u64 = 0x1;
545 : :
546 : : /* Lookup for existing vector by w2 */
547 [ # # ]: 0 : for (vi = len - 1; vi >= 0; vi--) {
548 [ # # ]: 0 : if (vec_tbl[vi].w2 != burst->w2[i])
549 : 0 : continue;
550 : 0 : vec = vec_tbl[vi].vec;
551 [ # # ]: 0 : if (unlikely(vec->nb_elem == qp->ca.vector_sz))
552 : 0 : continue;
553 : 0 : vec->ptrs[vec->nb_elem++] = infl_req;
554 : 0 : goto next_op; /* continue outer loop */
555 : : }
556 : :
557 : : /* No available vectors found, allocate a new one */
558 [ # # # # ]: 0 : if (unlikely(rte_mempool_get(qp->ca.vector_mp, (void **)&vec_tbl[len].vec))) {
559 : 0 : rte_errno = ENOMEM;
560 [ # # ]: 0 : if (i != 0)
561 : 0 : goto submit;
562 : : else
563 : 0 : goto put;
564 : : }
565 : : /* Also preallocate in-flight request, that will be used to
566 : : * submit misc passthrough instruction
567 : : */
568 [ # # # # ]: 0 : if (unlikely(rte_mempool_get(qp->ca.req_mp, (void **)&vec_tbl[len].req))) {
569 [ # # ]: 0 : rte_mempool_put(qp->ca.vector_mp, vec_tbl[len].vec);
570 : 0 : rte_errno = ENOMEM;
571 [ # # ]: 0 : if (i != 0)
572 : 0 : goto submit;
573 : : else
574 : 0 : goto put;
575 : : }
576 : 0 : vec_tbl[len].w2 = burst->w2[i];
577 : 0 : vec_tbl[len].vec->ptrs[0] = infl_req;
578 : 0 : vec_tbl[len].vec->nb_elem = 1;
579 : 0 : len++;
580 : :
581 : 0 : next_op:;
582 : : }
583 : :
584 : : /* Submit operations in burst */
585 : 0 : submit:
586 [ # # ]: 0 : if (CNXK_TT_FROM_TAG(burst->ws->gw_rdata) == SSO_TT_ORDERED)
587 : 0 : roc_sso_hws_head_wait(burst->ws->base);
588 : :
589 : : if (i > PKTS_PER_STEORL) {
590 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (PKTS_PER_STEORL - 1) << 12 | (uint64_t)lmt_id;
591 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
592 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - PKTS_PER_STEORL - 1) << 12 |
593 : : (uint64_t)(lmt_id + PKTS_PER_STEORL);
594 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
595 : : } else {
596 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - 1) << 12 | (uint64_t)lmt_id;
597 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
598 : : }
599 : :
600 : : /* Store w7 of last successfully filled instruction */
601 : 0 : inst = &inst_base[2 * (i - 1)];
602 : 0 : vec_tbl[0].w7 = inst->w7;
603 : :
604 : 0 : rte_io_wmb();
605 : :
606 : 0 : put:
607 [ # # ]: 0 : if (i != burst->nb_ops)
608 [ # # ]: 0 : rte_mempool_put_bulk(qp->ca.req_mp, (void *)&infl_reqs[i], burst->nb_ops - i);
609 : :
610 : 0 : *vec_tbl_len = len;
611 : :
612 : 0 : return i;
613 : : }
614 : :
615 : : static inline uint16_t
616 : 0 : ca_lmtst_burst_submit(struct ops_burst *burst, const bool is_sg_ver2)
617 : : {
618 : : struct cpt_inflight_req *infl_reqs[PKTS_PER_LOOP];
619 : : uint64_t lmt_base, lmt_arg, io_addr;
620 : : struct cpt_inst_s *inst, *inst_base;
621 : : struct cpt_inflight_req *infl_req;
622 : : union cpt_fc_write_s fc;
623 : : struct cnxk_cpt_qp *qp;
624 : : uint64_t *fc_addr;
625 : : uint16_t lmt_id;
626 : : int ret, i, j;
627 : :
628 : 0 : qp = burst->qp;
629 : :
630 : 0 : lmt_base = qp->lmtline.lmt_base;
631 : : io_addr = qp->lmtline.io_addr;
632 : 0 : fc_addr = qp->lmtline.fc_addr;
633 : :
634 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
635 : :
636 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
637 : 0 : inst_base = (struct cpt_inst_s *)lmt_base;
638 : :
639 : : #ifdef CNXK_CRYPTODEV_DEBUG
640 : : if (unlikely(!qp->ca.enabled)) {
641 : : rte_errno = EINVAL;
642 : : return 0;
643 : : }
644 : : #endif
645 : :
646 [ # # # # ]: 0 : if (unlikely(rte_mempool_get_bulk(qp->ca.req_mp, (void **)infl_reqs, burst->nb_ops))) {
647 : 0 : rte_errno = ENOMEM;
648 : 0 : return 0;
649 : : }
650 : :
651 [ # # ]: 0 : for (i = 0; i < burst->nb_ops; i++) {
652 : 0 : inst = &inst_base[2 * i];
653 : 0 : infl_req = infl_reqs[i];
654 : 0 : infl_req->op_flags = 0;
655 : :
656 : 0 : ret = cn10k_cpt_fill_inst(qp, &burst->op[i], inst, infl_req, is_sg_ver2);
657 [ # # ]: 0 : if (unlikely(ret != 1)) {
658 : : plt_dp_dbg("Could not process op: %p", burst->op[i]);
659 [ # # ]: 0 : if (i != 0)
660 : 0 : goto submit;
661 : : else
662 : 0 : goto put;
663 : : }
664 : :
665 : 0 : infl_req->res.cn10k.compcode = CPT_COMP_NOT_DONE;
666 : 0 : infl_req->qp = qp;
667 : 0 : inst->w0.u64 = 0;
668 : 0 : inst->res_addr = (uint64_t)&infl_req->res;
669 : 0 : inst->w2.u64 = burst->w2[i];
670 : 0 : inst->w3.u64 = CNXK_CPT_INST_W3(1, infl_req);
671 : : }
672 : :
673 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
674 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
675 : 0 : rte_errno = EAGAIN;
676 [ # # ]: 0 : for (j = 0; j < i; j++) {
677 : 0 : infl_req = infl_reqs[j];
678 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
679 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
680 : : }
681 : : i = 0;
682 : 0 : goto put;
683 : : }
684 : :
685 : 0 : submit:
686 [ # # ]: 0 : if (CNXK_TT_FROM_TAG(burst->ws->gw_rdata) == SSO_TT_ORDERED)
687 : 0 : roc_sso_hws_head_wait(burst->ws->base);
688 : :
689 : : if (i > PKTS_PER_STEORL) {
690 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (PKTS_PER_STEORL - 1) << 12 | (uint64_t)lmt_id;
691 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
692 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - PKTS_PER_STEORL - 1) << 12 |
693 : : (uint64_t)(lmt_id + PKTS_PER_STEORL);
694 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
695 : : } else {
696 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - 1) << 12 | (uint64_t)lmt_id;
697 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
698 : : }
699 : :
700 : 0 : rte_io_wmb();
701 : :
702 : 0 : put:
703 [ # # ]: 0 : if (unlikely(i != burst->nb_ops))
704 [ # # ]: 0 : rte_mempool_put_bulk(qp->ca.req_mp, (void *)&infl_reqs[i], burst->nb_ops - i);
705 : :
706 : 0 : return i;
707 : : }
708 : :
709 : : static inline uint16_t __rte_hot
710 : 0 : cn10k_cpt_crypto_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events,
711 : : const bool is_sg_ver2)
712 : 0 : {
713 : 0 : uint16_t submitted, count = 0, vec_tbl_len = 0;
714 : 0 : struct vec_request vec_tbl[nb_events];
715 : : struct rte_crypto_op *op;
716 : : struct ops_burst burst;
717 : : struct cnxk_cpt_qp *qp;
718 : : bool is_vector = false;
719 : : uint64_t w2;
720 : : int ret, i;
721 : :
722 : 0 : burst.ws = ws;
723 : 0 : burst.qp = NULL;
724 : 0 : burst.nb_ops = 0;
725 : :
726 [ # # ]: 0 : for (i = 0; i < nb_events; i++) {
727 : 0 : op = ev[i].event_ptr;
728 : 0 : ret = cn10k_ca_meta_info_extract(op, &qp, &w2);
729 [ # # ]: 0 : if (unlikely(ret)) {
730 : 0 : rte_errno = EINVAL;
731 : 0 : goto vec_submit;
732 : : }
733 : :
734 : : /* Queue pair change check */
735 [ # # ]: 0 : if (qp != burst.qp) {
736 [ # # ]: 0 : if (burst.nb_ops) {
737 [ # # ]: 0 : if (is_vector) {
738 : 0 : submitted = ca_lmtst_vec_submit(&burst, vec_tbl,
739 : : &vec_tbl_len, is_sg_ver2);
740 : : /*
741 : : * Vector submission is required on qp change, but not in
742 : : * other cases, since we could send several vectors per
743 : : * lmtst instruction only for same qp
744 : : */
745 : 0 : cn10k_cpt_vec_submit(vec_tbl, vec_tbl_len, burst.qp);
746 : 0 : vec_tbl_len = 0;
747 : : } else {
748 : 0 : submitted = ca_lmtst_burst_submit(&burst, is_sg_ver2);
749 : : }
750 : 0 : count += submitted;
751 [ # # ]: 0 : if (unlikely(submitted != burst.nb_ops))
752 : 0 : goto vec_submit;
753 : 0 : burst.nb_ops = 0;
754 : : }
755 : 0 : is_vector = qp->ca.vector_sz;
756 : 0 : burst.qp = qp;
757 : : }
758 : 0 : burst.w2[burst.nb_ops] = w2;
759 : 0 : burst.op[burst.nb_ops] = op;
760 : :
761 : : /* Max nb_ops per burst check */
762 [ # # ]: 0 : if (++burst.nb_ops == PKTS_PER_LOOP) {
763 [ # # ]: 0 : if (is_vector)
764 : 0 : submitted = ca_lmtst_vec_submit(&burst, vec_tbl, &vec_tbl_len,
765 : : is_sg_ver2);
766 : : else
767 : 0 : submitted = ca_lmtst_burst_submit(&burst, is_sg_ver2);
768 : 0 : count += submitted;
769 [ # # ]: 0 : if (unlikely(submitted != burst.nb_ops))
770 : 0 : goto vec_submit;
771 : 0 : burst.nb_ops = 0;
772 : : }
773 : : }
774 : : /* Submit the rest of crypto operations */
775 [ # # ]: 0 : if (burst.nb_ops) {
776 [ # # ]: 0 : if (is_vector)
777 : 0 : count += ca_lmtst_vec_submit(&burst, vec_tbl, &vec_tbl_len, is_sg_ver2);
778 : : else
779 : 0 : count += ca_lmtst_burst_submit(&burst, is_sg_ver2);
780 : : }
781 : :
782 : 0 : vec_submit:
783 : 0 : cn10k_cpt_vec_submit(vec_tbl, vec_tbl_len, burst.qp);
784 : 0 : return count;
785 : : }
786 : :
787 : : uint16_t __rte_hot
788 : 0 : cn10k_cpt_sg_ver1_crypto_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
789 : : {
790 : 0 : return cn10k_cpt_crypto_adapter_enqueue(ws, ev, nb_events, false);
791 : : }
792 : :
793 : : uint16_t __rte_hot
794 : 0 : cn10k_cpt_sg_ver2_crypto_adapter_enqueue(void *ws, struct rte_event ev[], uint16_t nb_events)
795 : : {
796 : 0 : return cn10k_cpt_crypto_adapter_enqueue(ws, ev, nb_events, true);
797 : : }
798 : :
799 : : static inline void
800 : 0 : cn10k_cpt_sec_post_process(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
801 : : {
802 : 0 : struct rte_mbuf *mbuf = cop->sym->m_src;
803 : 0 : const uint16_t m_len = res->rlen;
804 : :
805 [ # # # # : 0 : switch (res->uc_compcode) {
# # ]
806 : 0 : case ROC_IE_OT_UCC_SUCCESS_PKT_IP_BADCSUM:
807 : 0 : mbuf->ol_flags &= ~RTE_MBUF_F_RX_IP_CKSUM_GOOD;
808 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
809 : 0 : break;
810 : 0 : case ROC_IE_OT_UCC_SUCCESS_PKT_L4_GOODCSUM:
811 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD |
812 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD;
813 : 0 : break;
814 : 0 : case ROC_IE_OT_UCC_SUCCESS_PKT_L4_BADCSUM:
815 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD |
816 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD;
817 : 0 : break;
818 : : case ROC_IE_OT_UCC_SUCCESS_PKT_IP_GOODCSUM:
819 : : break;
820 : 0 : case ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_FIRST:
821 : : case ROC_IE_OT_UCC_SUCCESS_SA_SOFTEXP_AGAIN:
822 : 0 : cop->aux_flags = RTE_CRYPTO_OP_AUX_FLAGS_IPSEC_SOFT_EXPIRY;
823 : 0 : break;
824 : 0 : default:
825 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
826 : 0 : return;
827 : : }
828 : :
829 [ # # ]: 0 : if (mbuf->next == NULL)
830 : 0 : mbuf->data_len = m_len;
831 : :
832 : 0 : mbuf->pkt_len = m_len;
833 : : }
834 : :
835 : : static inline void
836 : 0 : cn10k_cpt_dequeue_post_process(struct cnxk_cpt_qp *qp,
837 : : struct rte_crypto_op *cop,
838 : : struct cpt_inflight_req *infl_req,
839 : : struct cpt_cn10k_res_s *res)
840 : : {
841 : 0 : const uint8_t uc_compcode = res->uc_compcode;
842 : 0 : const uint8_t compcode = res->compcode;
843 : :
844 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
845 : :
846 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
847 : : cop->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
848 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD || compcode == CPT_COMP_WARN)) {
849 : : /* Success with additional info */
850 : 0 : cn10k_cpt_sec_post_process(cop, res);
851 : : } else {
852 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
853 : 0 : plt_dp_info("HW completion code 0x%x", res->compcode);
854 [ # # ]: 0 : if (compcode == CPT_COMP_GOOD) {
855 : 0 : plt_dp_info(
856 : : "Request failed with microcode error");
857 : 0 : plt_dp_info("MC completion code 0x%x",
858 : : uc_compcode);
859 : : }
860 : : }
861 : :
862 : 0 : return;
863 [ # # ]: 0 : } else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC &&
864 : 0 : cop->sess_type == RTE_CRYPTO_OP_WITH_SESSION &&
865 [ # # ]: 0 : cop->asym->ecdh.ke_type == RTE_CRYPTO_ASYM_KE_PUB_KEY_VERIFY) {
866 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD)) {
867 [ # # ]: 0 : if (uc_compcode == ROC_AE_ERR_ECC_POINT_NOT_ON_CURVE) {
868 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
869 : 0 : return;
870 [ # # ]: 0 : } else if (uc_compcode == ROC_AE_ERR_ECC_PAI) {
871 : : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
872 : : return;
873 : : }
874 : : }
875 : : }
876 : :
877 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD)) {
878 [ # # ]: 0 : if (unlikely(uc_compcode)) {
879 [ # # ]: 0 : if (uc_compcode == ROC_SE_ERR_GC_ICV_MISCOMPARE)
880 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
881 : : else
882 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
883 : :
884 : 0 : plt_dp_info("Request failed with microcode error");
885 : 0 : plt_dp_info("MC completion code 0x%x",
886 : : res->uc_compcode);
887 : 0 : goto temp_sess_free;
888 : : }
889 : :
890 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
891 : : /* Verify authentication data if required */
892 [ # # ]: 0 : if (unlikely(infl_req->op_flags &
893 : : CPT_OP_FLAGS_AUTH_VERIFY)) {
894 : 0 : uintptr_t *rsp = infl_req->mdata;
895 [ # # ]: 0 : compl_auth_verify(cop, (uint8_t *)rsp[0],
896 : : rsp[1]);
897 : : }
898 [ # # ]: 0 : } else if (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
899 : : struct rte_crypto_asym_op *op = cop->asym;
900 : 0 : uintptr_t *mdata = infl_req->mdata;
901 : 0 : struct cnxk_ae_sess *sess = (struct cnxk_ae_sess *)op->session;
902 : :
903 [ # # # # : 0 : cnxk_ae_post_process(cop, sess, (uint8_t *)mdata[0]);
# # # ]
904 : : }
905 : : } else {
906 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
907 : 0 : plt_dp_info("HW completion code 0x%x", res->compcode);
908 : :
909 [ # # # # ]: 0 : switch (compcode) {
910 : 0 : case CPT_COMP_INSTERR:
911 : 0 : plt_dp_err("Request failed with instruction error");
912 : 0 : break;
913 : 0 : case CPT_COMP_FAULT:
914 : 0 : plt_dp_err("Request failed with DMA fault");
915 : 0 : break;
916 : 0 : case CPT_COMP_HWERR:
917 : 0 : plt_dp_err("Request failed with hardware error");
918 : 0 : break;
919 : 0 : default:
920 : 0 : plt_dp_err(
921 : : "Request failed with unknown completion code");
922 : : }
923 : : }
924 : :
925 : 0 : temp_sess_free:
926 [ # # ]: 0 : if (unlikely(cop->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {
927 [ # # ]: 0 : if (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
928 : 0 : sym_session_clear(cop->sym->session, true);
929 [ # # ]: 0 : rte_mempool_put(qp->sess_mp, cop->sym->session);
930 : 0 : cop->sym->session = NULL;
931 : : }
932 : : }
933 : : }
934 : :
935 : : uintptr_t
936 : 0 : cn10k_cpt_crypto_adapter_dequeue(uintptr_t get_work1)
937 : : {
938 : : struct cpt_inflight_req *infl_req;
939 : : struct rte_crypto_op *cop;
940 : : struct cnxk_cpt_qp *qp;
941 : : union cpt_res_s res;
942 : :
943 : 0 : infl_req = (struct cpt_inflight_req *)(get_work1);
944 : 0 : cop = infl_req->cop;
945 : 0 : qp = infl_req->qp;
946 : :
947 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0], __ATOMIC_RELAXED);
948 : :
949 : 0 : cn10k_cpt_dequeue_post_process(qp, infl_req->cop, infl_req, &res.cn10k);
950 : :
951 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
952 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
953 : :
954 [ # # ]: 0 : rte_mempool_put(qp->ca.req_mp, infl_req);
955 : 0 : return (uintptr_t)cop;
956 : : }
957 : :
958 : : uintptr_t
959 : 0 : cn10k_cpt_crypto_adapter_vector_dequeue(uintptr_t get_work1)
960 : : {
961 : : struct cpt_inflight_req *infl_req, *vec_infl_req;
962 : : struct rte_mempool *meta_mp, *req_mp;
963 : : struct rte_event_vector *vec;
964 : : struct rte_crypto_op *cop;
965 : : struct cnxk_cpt_qp *qp;
966 : : union cpt_res_s res;
967 : : int i;
968 : :
969 : 0 : vec_infl_req = (struct cpt_inflight_req *)(get_work1);
970 : :
971 : 0 : vec = vec_infl_req->vec;
972 : 0 : qp = vec_infl_req->qp;
973 : 0 : meta_mp = qp->meta_info.pool;
974 : 0 : req_mp = qp->ca.req_mp;
975 : :
976 : : #ifdef CNXK_CRYPTODEV_DEBUG
977 : : res.u64[0] = __atomic_load_n(&vec_infl_req->res.u64[0], __ATOMIC_RELAXED);
978 : : PLT_ASSERT(res.cn10k.compcode == CPT_COMP_GOOD);
979 : : PLT_ASSERT(res.cn10k.uc_compcode == 0);
980 : : #endif
981 : :
982 [ # # ]: 0 : for (i = 0; i < vec->nb_elem; i++) {
983 : 0 : infl_req = vec->ptrs[i];
984 : 0 : cop = infl_req->cop;
985 : :
986 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0], __ATOMIC_RELAXED);
987 : 0 : cn10k_cpt_dequeue_post_process(qp, cop, infl_req, &res.cn10k);
988 : :
989 : 0 : vec->ptrs[i] = cop;
990 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
991 [ # # ]: 0 : rte_mempool_put(meta_mp, infl_req->mdata);
992 : :
993 : 0 : rte_mempool_put(req_mp, infl_req);
994 : : }
995 : :
996 : 0 : rte_mempool_put(req_mp, vec_infl_req);
997 : :
998 : 0 : return (uintptr_t)vec;
999 : : }
1000 : :
1001 : : static uint16_t
1002 : 0 : cn10k_cpt_dequeue_burst(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
1003 : : {
1004 : : struct cpt_inflight_req *infl_req;
1005 : : struct cnxk_cpt_qp *qp = qptr;
1006 : : struct pending_queue *pend_q;
1007 : : uint64_t infl_cnt, pq_tail;
1008 : : struct rte_crypto_op *cop;
1009 : : union cpt_res_s res;
1010 : : int i;
1011 : :
1012 : : pend_q = &qp->pend_q;
1013 : :
1014 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1015 : :
1016 : 0 : pq_tail = pend_q->tail;
1017 : 0 : infl_cnt = pending_queue_infl_cnt(pend_q->head, pq_tail, pq_mask);
1018 : 0 : nb_ops = RTE_MIN(nb_ops, infl_cnt);
1019 : :
1020 : : /* Ensure infl_cnt isn't read before data lands */
1021 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
1022 : :
1023 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
1024 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1025 : :
1026 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0],
1027 : : __ATOMIC_RELAXED);
1028 : :
1029 [ # # ]: 0 : if (unlikely(res.cn10k.compcode == CPT_COMP_NOT_DONE)) {
1030 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() >
1031 : : pend_q->time_out)) {
1032 : 0 : plt_err("Request timed out");
1033 : 0 : cnxk_cpt_dump_on_err(qp);
1034 : 0 : pend_q->time_out = rte_get_timer_cycles() +
1035 : 0 : DEFAULT_COMMAND_TIMEOUT *
1036 : : rte_get_timer_hz();
1037 : : }
1038 : : break;
1039 : : }
1040 : :
1041 : : pending_queue_advance(&pq_tail, pq_mask);
1042 : :
1043 : 0 : cop = infl_req->cop;
1044 : :
1045 : 0 : ops[i] = cop;
1046 : :
1047 : 0 : cn10k_cpt_dequeue_post_process(qp, cop, infl_req, &res.cn10k);
1048 : :
1049 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1050 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1051 : : }
1052 : :
1053 : 0 : pend_q->tail = pq_tail;
1054 : :
1055 : 0 : return i;
1056 : : }
1057 : :
1058 : : void
1059 : 0 : cn10k_cpt_set_enqdeq_fns(struct rte_cryptodev *dev, struct cnxk_cpt_vf *vf)
1060 : : {
1061 [ # # # # ]: 0 : if (vf->cpt.hw_caps[CPT_ENG_TYPE_SE].sg_ver2 && vf->cpt.hw_caps[CPT_ENG_TYPE_IE].sg_ver2)
1062 : 0 : dev->enqueue_burst = cn10k_cpt_sg_ver2_enqueue_burst;
1063 : : else
1064 : 0 : dev->enqueue_burst = cn10k_cpt_sg_ver1_enqueue_burst;
1065 : :
1066 : 0 : dev->dequeue_burst = cn10k_cpt_dequeue_burst;
1067 : :
1068 : : rte_mb();
1069 : 0 : }
1070 : :
1071 : : static void
1072 : 0 : cn10k_cpt_dev_info_get(struct rte_cryptodev *dev,
1073 : : struct rte_cryptodev_info *info)
1074 : : {
1075 [ # # ]: 0 : if (info != NULL) {
1076 : 0 : cnxk_cpt_dev_info_get(dev, info);
1077 : 0 : info->driver_id = cn10k_cryptodev_driver_id;
1078 : : }
1079 : 0 : }
1080 : :
1081 : : static inline int
1082 : 0 : cn10k_cpt_raw_fill_inst(struct cnxk_iov *iov, struct cnxk_cpt_qp *qp,
1083 : : struct cnxk_sym_dp_ctx *dp_ctx, struct cpt_inst_s inst[],
1084 : : struct cpt_inflight_req *infl_req, void *opaque, const bool is_sg_ver2)
1085 : : {
1086 : : struct cnxk_se_sess *sess;
1087 : : int ret;
1088 : :
1089 : : const union cpt_res_s res = {
1090 : : .cn10k.compcode = CPT_COMP_NOT_DONE,
1091 : : };
1092 : :
1093 : 0 : inst[0].w0.u64 = 0;
1094 : 0 : inst[0].w2.u64 = 0;
1095 : 0 : inst[0].w3.u64 = 0;
1096 : :
1097 : 0 : sess = dp_ctx->sess;
1098 : :
1099 [ # # # # : 0 : switch (sess->dp_thr_type) {
# ]
1100 : 0 : case CPT_DP_THREAD_TYPE_PT:
1101 : 0 : ret = fill_raw_passthrough_params(iov, inst);
1102 : 0 : break;
1103 [ # # ]: 0 : case CPT_DP_THREAD_TYPE_FC_CHAIN:
1104 : : ret = fill_raw_fc_params(iov, sess, &qp->meta_info, infl_req, &inst[0], false,
1105 : : false, is_sg_ver2);
1106 : 0 : break;
1107 [ # # ]: 0 : case CPT_DP_THREAD_TYPE_FC_AEAD:
1108 : : ret = fill_raw_fc_params(iov, sess, &qp->meta_info, infl_req, &inst[0], false, true,
1109 : : is_sg_ver2);
1110 : 0 : break;
1111 [ # # ]: 0 : case CPT_DP_THREAD_AUTH_ONLY:
1112 : : ret = fill_raw_digest_params(iov, sess, &qp->meta_info, infl_req, &inst[0],
1113 : : is_sg_ver2);
1114 : 0 : break;
1115 : : default:
1116 : : ret = -EINVAL;
1117 : : }
1118 : :
1119 [ # # ]: 0 : if (unlikely(ret))
1120 : : return 0;
1121 : :
1122 : 0 : inst[0].res_addr = (uint64_t)&infl_req->res;
1123 : 0 : __atomic_store_n(&infl_req->res.u64[0], res.u64[0], __ATOMIC_RELAXED);
1124 : 0 : infl_req->opaque = opaque;
1125 : :
1126 : 0 : inst[0].w7.u64 = sess->cpt_inst_w7;
1127 : :
1128 : 0 : return 1;
1129 : : }
1130 : :
1131 : : static uint32_t
1132 : 0 : cn10k_cpt_raw_enqueue_burst(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym_vec *vec,
1133 : : union rte_crypto_sym_ofs ofs, void *user_data[], int *enqueue_status,
1134 : : const bool is_sgv2)
1135 : : {
1136 : 0 : uint16_t lmt_id, nb_allowed, nb_ops = vec->num;
1137 : : uint64_t lmt_base, lmt_arg, io_addr, head;
1138 : : struct cpt_inflight_req *infl_req;
1139 : : struct cnxk_cpt_qp *qp = qpair;
1140 : : struct cnxk_sym_dp_ctx *dp_ctx;
1141 : : struct pending_queue *pend_q;
1142 : : uint32_t count = 0, index;
1143 : : union cpt_fc_write_s fc;
1144 : : struct cpt_inst_s *inst;
1145 : : uint64_t *fc_addr;
1146 : : int ret, i;
1147 : :
1148 : : pend_q = &qp->pend_q;
1149 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1150 : :
1151 : 0 : head = pend_q->head;
1152 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
1153 : 0 : nb_ops = RTE_MIN(nb_ops, nb_allowed);
1154 : :
1155 [ # # ]: 0 : if (unlikely(nb_ops == 0))
1156 : : return 0;
1157 : :
1158 : 0 : lmt_base = qp->lmtline.lmt_base;
1159 : : io_addr = qp->lmtline.io_addr;
1160 : 0 : fc_addr = qp->lmtline.fc_addr;
1161 : :
1162 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
1163 : :
1164 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
1165 : 0 : inst = (struct cpt_inst_s *)lmt_base;
1166 : :
1167 : : dp_ctx = (struct cnxk_sym_dp_ctx *)drv_ctx;
1168 : 0 : again:
1169 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
1170 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh)) {
1171 : : i = 0;
1172 : 0 : goto pend_q_commit;
1173 : : }
1174 : :
1175 [ # # ]: 0 : for (i = 0; i < RTE_MIN(PKTS_PER_LOOP, nb_ops); i++) {
1176 : : struct cnxk_iov iov;
1177 : :
1178 : 0 : index = count + i;
1179 : 0 : infl_req = &pend_q->req_queue[head];
1180 : 0 : infl_req->op_flags = 0;
1181 : :
1182 : 0 : cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
1183 : 0 : ret = cn10k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[2 * i], infl_req,
1184 : 0 : user_data[index], is_sgv2);
1185 [ # # ]: 0 : if (unlikely(ret != 1)) {
1186 : 0 : plt_dp_err("Could not process vec: %d", index);
1187 [ # # ]: 0 : if (i == 0 && count == 0)
1188 : 0 : return -1;
1189 [ # # ]: 0 : else if (i == 0)
1190 : 0 : goto pend_q_commit;
1191 : : else
1192 : : break;
1193 : : }
1194 : : pending_queue_advance(&head, pq_mask);
1195 : : }
1196 : :
1197 : : if (i > PKTS_PER_STEORL) {
1198 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (PKTS_PER_STEORL - 1) << 12 | (uint64_t)lmt_id;
1199 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
1200 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - PKTS_PER_STEORL - 1) << 12 |
1201 : : (uint64_t)(lmt_id + PKTS_PER_STEORL);
1202 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
1203 : : } else {
1204 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (i - 1) << 12 | (uint64_t)lmt_id;
1205 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
1206 : : }
1207 : :
1208 : 0 : rte_io_wmb();
1209 : :
1210 [ # # # # ]: 0 : if (nb_ops - i > 0 && i == PKTS_PER_LOOP) {
1211 : 0 : nb_ops -= i;
1212 : 0 : count += i;
1213 : 0 : goto again;
1214 : : }
1215 : :
1216 : 0 : pend_q_commit:
1217 : : rte_atomic_thread_fence(__ATOMIC_RELEASE);
1218 : :
1219 : 0 : pend_q->head = head;
1220 : 0 : pend_q->time_out = rte_get_timer_cycles() + DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1221 : :
1222 : 0 : *enqueue_status = 1;
1223 : 0 : return count + i;
1224 : : }
1225 : :
1226 : : static uint32_t
1227 : 0 : cn10k_cpt_raw_enqueue_burst_sgv2(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym_vec *vec,
1228 : : union rte_crypto_sym_ofs ofs, void *user_data[],
1229 : : int *enqueue_status)
1230 : : {
1231 : 0 : return cn10k_cpt_raw_enqueue_burst(qpair, drv_ctx, vec, ofs, user_data, enqueue_status,
1232 : : true);
1233 : : }
1234 : :
1235 : : static uint32_t
1236 : 0 : cn10k_cpt_raw_enqueue_burst_sgv1(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym_vec *vec,
1237 : : union rte_crypto_sym_ofs ofs, void *user_data[],
1238 : : int *enqueue_status)
1239 : : {
1240 : 0 : return cn10k_cpt_raw_enqueue_burst(qpair, drv_ctx, vec, ofs, user_data, enqueue_status,
1241 : : false);
1242 : : }
1243 : :
1244 : : static int
1245 : 0 : cn10k_cpt_raw_enqueue(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data_vec,
1246 : : uint16_t n_data_vecs, union rte_crypto_sym_ofs ofs,
1247 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
1248 : : struct rte_crypto_va_iova_ptr *aad_or_auth_iv, void *user_data,
1249 : : const bool is_sgv2)
1250 : : {
1251 : : uint64_t lmt_base, lmt_arg, io_addr, head;
1252 : : struct cpt_inflight_req *infl_req;
1253 : : struct cnxk_cpt_qp *qp = qpair;
1254 : : struct cnxk_sym_dp_ctx *dp_ctx;
1255 : : uint16_t lmt_id, nb_allowed;
1256 : : struct cpt_inst_s *inst;
1257 : : union cpt_fc_write_s fc;
1258 : : struct cnxk_iov iov;
1259 : : uint64_t *fc_addr;
1260 : : int ret;
1261 : :
1262 : : struct pending_queue *pend_q = &qp->pend_q;
1263 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1264 : 0 : const uint32_t fc_thresh = qp->lmtline.fc_thresh;
1265 : :
1266 : 0 : head = pend_q->head;
1267 [ # # ]: 0 : nb_allowed = pending_queue_free_cnt(head, pend_q->tail, pq_mask);
1268 : :
1269 [ # # ]: 0 : if (unlikely(nb_allowed == 0))
1270 : : return -1;
1271 : :
1272 : : cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
1273 : :
1274 : 0 : lmt_base = qp->lmtline.lmt_base;
1275 : : io_addr = qp->lmtline.io_addr;
1276 : 0 : fc_addr = qp->lmtline.fc_addr;
1277 : :
1278 : : ROC_LMT_BASE_ID_GET(lmt_base, lmt_id);
1279 : 0 : inst = (struct cpt_inst_s *)lmt_base;
1280 : :
1281 : 0 : fc.u64[0] = __atomic_load_n(fc_addr, __ATOMIC_RELAXED);
1282 [ # # ]: 0 : if (unlikely(fc.s.qsize > fc_thresh))
1283 : : return -1;
1284 : :
1285 : : dp_ctx = (struct cnxk_sym_dp_ctx *)drv_ctx;
1286 : 0 : infl_req = &pend_q->req_queue[head];
1287 : 0 : infl_req->op_flags = 0;
1288 : :
1289 : 0 : ret = cn10k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[0], infl_req, user_data, is_sgv2);
1290 [ # # ]: 0 : if (unlikely(ret != 1)) {
1291 : 0 : plt_dp_err("Could not process vec");
1292 : 0 : return -1;
1293 : : }
1294 : :
1295 : : pending_queue_advance(&head, pq_mask);
1296 : :
1297 : : lmt_arg = ROC_CN10K_CPT_LMT_ARG | (uint64_t)lmt_id;
1298 : : roc_lmt_submit_steorl(lmt_arg, io_addr);
1299 : :
1300 : 0 : rte_io_wmb();
1301 : :
1302 : 0 : pend_q->head = head;
1303 : 0 : pend_q->time_out = rte_get_timer_cycles() + DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1304 : :
1305 : 0 : return 1;
1306 : : }
1307 : :
1308 : : static int
1309 : 0 : cn10k_cpt_raw_enqueue_sgv2(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data_vec,
1310 : : uint16_t n_data_vecs, union rte_crypto_sym_ofs ofs,
1311 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
1312 : : struct rte_crypto_va_iova_ptr *aad_or_auth_iv, void *user_data)
1313 : : {
1314 : 0 : return cn10k_cpt_raw_enqueue(qpair, drv_ctx, data_vec, n_data_vecs, ofs, iv, digest,
1315 : : aad_or_auth_iv, user_data, true);
1316 : : }
1317 : :
1318 : : static int
1319 : 0 : cn10k_cpt_raw_enqueue_sgv1(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data_vec,
1320 : : uint16_t n_data_vecs, union rte_crypto_sym_ofs ofs,
1321 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
1322 : : struct rte_crypto_va_iova_ptr *aad_or_auth_iv, void *user_data)
1323 : : {
1324 : 0 : return cn10k_cpt_raw_enqueue(qpair, drv_ctx, data_vec, n_data_vecs, ofs, iv, digest,
1325 : : aad_or_auth_iv, user_data, false);
1326 : : }
1327 : :
1328 : : static inline int
1329 : 0 : cn10k_cpt_raw_dequeue_post_process(struct cpt_cn10k_res_s *res)
1330 : : {
1331 : 0 : const uint8_t uc_compcode = res->uc_compcode;
1332 : 0 : const uint8_t compcode = res->compcode;
1333 : : int ret = 1;
1334 : :
1335 [ # # ]: 0 : if (likely(compcode == CPT_COMP_GOOD)) {
1336 [ # # ]: 0 : if (unlikely(uc_compcode))
1337 : 0 : plt_dp_info("Request failed with microcode error: 0x%x", res->uc_compcode);
1338 : : else
1339 : : ret = 0;
1340 : : }
1341 : :
1342 : 0 : return ret;
1343 : : }
1344 : :
1345 : : static uint32_t
1346 : 0 : cn10k_cpt_sym_raw_dequeue_burst(void *qptr, uint8_t *drv_ctx,
1347 : : rte_cryptodev_raw_get_dequeue_count_t get_dequeue_count,
1348 : : uint32_t max_nb_to_dequeue,
1349 : : rte_cryptodev_raw_post_dequeue_t post_dequeue, void **out_user_data,
1350 : : uint8_t is_user_data_array, uint32_t *n_success,
1351 : : int *dequeue_status)
1352 : : {
1353 : : struct cpt_inflight_req *infl_req;
1354 : : struct cnxk_cpt_qp *qp = qptr;
1355 : : struct pending_queue *pend_q;
1356 : : uint64_t infl_cnt, pq_tail;
1357 : : union cpt_res_s res;
1358 : : int is_op_success;
1359 : : uint16_t nb_ops;
1360 : : void *opaque;
1361 : : int i = 0;
1362 : :
1363 : : pend_q = &qp->pend_q;
1364 : :
1365 : 0 : const uint64_t pq_mask = pend_q->pq_mask;
1366 : :
1367 : : RTE_SET_USED(drv_ctx);
1368 : 0 : pq_tail = pend_q->tail;
1369 [ # # ]: 0 : infl_cnt = pending_queue_infl_cnt(pend_q->head, pq_tail, pq_mask);
1370 : :
1371 : : /* Ensure infl_cnt isn't read before data lands */
1372 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
1373 : :
1374 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1375 : :
1376 : 0 : opaque = infl_req->opaque;
1377 [ # # ]: 0 : if (get_dequeue_count)
1378 : 0 : nb_ops = get_dequeue_count(opaque);
1379 : : else
1380 : 0 : nb_ops = max_nb_to_dequeue;
1381 : 0 : nb_ops = RTE_MIN(nb_ops, infl_cnt);
1382 : :
1383 [ # # ]: 0 : for (i = 0; i < nb_ops; i++) {
1384 : : is_op_success = 0;
1385 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1386 : :
1387 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0], __ATOMIC_RELAXED);
1388 : :
1389 [ # # ]: 0 : if (unlikely(res.cn10k.compcode == CPT_COMP_NOT_DONE)) {
1390 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() > pend_q->time_out)) {
1391 : 0 : plt_err("Request timed out");
1392 : 0 : cnxk_cpt_dump_on_err(qp);
1393 : 0 : pend_q->time_out = rte_get_timer_cycles() +
1394 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1395 : : }
1396 : : break;
1397 : : }
1398 : :
1399 : : pending_queue_advance(&pq_tail, pq_mask);
1400 : :
1401 [ # # ]: 0 : if (!cn10k_cpt_raw_dequeue_post_process(&res.cn10k)) {
1402 : : is_op_success = 1;
1403 : 0 : *n_success += 1;
1404 : : }
1405 : :
1406 [ # # ]: 0 : if (is_user_data_array) {
1407 : 0 : out_user_data[i] = infl_req->opaque;
1408 : 0 : post_dequeue(out_user_data[i], i, is_op_success);
1409 : : } else {
1410 [ # # ]: 0 : if (i == 0)
1411 : 0 : out_user_data[0] = opaque;
1412 : 0 : post_dequeue(out_user_data[0], i, is_op_success);
1413 : : }
1414 : :
1415 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1416 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1417 : : }
1418 : :
1419 : 0 : pend_q->tail = pq_tail;
1420 : 0 : *dequeue_status = 1;
1421 : :
1422 : 0 : return i;
1423 : : }
1424 : :
1425 : : static void *
1426 : 0 : cn10k_cpt_sym_raw_dequeue(void *qptr, uint8_t *drv_ctx, int *dequeue_status,
1427 : : enum rte_crypto_op_status *op_status)
1428 : : {
1429 : : struct cpt_inflight_req *infl_req;
1430 : : struct cnxk_cpt_qp *qp = qptr;
1431 : : struct pending_queue *pend_q;
1432 : : uint64_t pq_tail;
1433 : : union cpt_res_s res;
1434 : : void *opaque = NULL;
1435 : :
1436 : : pend_q = &qp->pend_q;
1437 : :
1438 : : const uint64_t pq_mask = pend_q->pq_mask;
1439 : :
1440 : : RTE_SET_USED(drv_ctx);
1441 : :
1442 [ # # ]: 0 : pq_tail = pend_q->tail;
1443 : :
1444 : : rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
1445 : :
1446 : 0 : infl_req = &pend_q->req_queue[pq_tail];
1447 : :
1448 : 0 : res.u64[0] = __atomic_load_n(&infl_req->res.u64[0], __ATOMIC_RELAXED);
1449 : :
1450 [ # # ]: 0 : if (unlikely(res.cn10k.compcode == CPT_COMP_NOT_DONE)) {
1451 [ # # ]: 0 : if (unlikely(rte_get_timer_cycles() > pend_q->time_out)) {
1452 : 0 : plt_err("Request timed out");
1453 : 0 : cnxk_cpt_dump_on_err(qp);
1454 : 0 : pend_q->time_out = rte_get_timer_cycles() +
1455 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
1456 : : }
1457 : 0 : goto exit;
1458 : : }
1459 : :
1460 : : pending_queue_advance(&pq_tail, pq_mask);
1461 : :
1462 : 0 : opaque = infl_req->opaque;
1463 : :
1464 [ # # ]: 0 : if (!cn10k_cpt_raw_dequeue_post_process(&res.cn10k))
1465 : 0 : *op_status = RTE_CRYPTO_OP_STATUS_SUCCESS;
1466 : : else
1467 : 0 : *op_status = RTE_CRYPTO_OP_STATUS_ERROR;
1468 : :
1469 [ # # ]: 0 : if (unlikely(infl_req->op_flags & CPT_OP_FLAGS_METABUF))
1470 [ # # ]: 0 : rte_mempool_put(qp->meta_info.pool, infl_req->mdata);
1471 : :
1472 : 0 : *dequeue_status = 1;
1473 : 0 : exit:
1474 : 0 : return opaque;
1475 : : }
1476 : :
1477 : : static int
1478 : 0 : cn10k_sym_get_raw_dp_ctx_size(struct rte_cryptodev *dev __rte_unused)
1479 : : {
1480 : 0 : return sizeof(struct cnxk_sym_dp_ctx);
1481 : : }
1482 : :
1483 : : static int
1484 : 0 : cn10k_sym_configure_raw_dp_ctx(struct rte_cryptodev *dev, uint16_t qp_id,
1485 : : struct rte_crypto_raw_dp_ctx *raw_dp_ctx,
1486 : : enum rte_crypto_op_sess_type sess_type,
1487 : : union rte_cryptodev_session_ctx session_ctx, uint8_t is_update)
1488 : : {
1489 : 0 : struct cnxk_se_sess *sess = (struct cnxk_se_sess *)session_ctx.crypto_sess;
1490 : : struct cnxk_sym_dp_ctx *dp_ctx;
1491 : :
1492 [ # # ]: 0 : if (sess_type != RTE_CRYPTO_OP_WITH_SESSION)
1493 : : return -ENOTSUP;
1494 : :
1495 [ # # ]: 0 : if (sess == NULL)
1496 : : return -EINVAL;
1497 : :
1498 : 0 : if ((sess->dp_thr_type == CPT_DP_THREAD_TYPE_PDCP) ||
1499 : : (sess->dp_thr_type == CPT_DP_THREAD_TYPE_PDCP_CHAIN) ||
1500 [ # # ]: 0 : (sess->dp_thr_type == CPT_DP_THREAD_TYPE_KASUMI) ||
1501 : : (sess->dp_thr_type == CPT_DP_THREAD_TYPE_SM))
1502 : : return -ENOTSUP;
1503 : :
1504 [ # # ]: 0 : if ((sess->dp_thr_type == CPT_DP_THREAD_AUTH_ONLY) &&
1505 [ # # ]: 0 : ((sess->roc_se_ctx.fc_type == ROC_SE_KASUMI) ||
1506 : : (sess->roc_se_ctx.fc_type == ROC_SE_PDCP)))
1507 : : return -ENOTSUP;
1508 : :
1509 [ # # ]: 0 : if (sess->roc_se_ctx.hash_type == ROC_SE_SHA1_TYPE)
1510 : : return -ENOTSUP;
1511 : :
1512 : : dp_ctx = (struct cnxk_sym_dp_ctx *)raw_dp_ctx->drv_ctx_data;
1513 : 0 : dp_ctx->sess = sess;
1514 : :
1515 [ # # ]: 0 : if (!is_update) {
1516 : : struct cnxk_cpt_vf *vf;
1517 : :
1518 : 0 : raw_dp_ctx->qp_data = (struct cnxk_cpt_qp *)dev->data->queue_pairs[qp_id];
1519 : 0 : raw_dp_ctx->dequeue = cn10k_cpt_sym_raw_dequeue;
1520 : 0 : raw_dp_ctx->dequeue_burst = cn10k_cpt_sym_raw_dequeue_burst;
1521 : :
1522 : 0 : vf = dev->data->dev_private;
1523 [ # # ]: 0 : if (vf->cpt.hw_caps[CPT_ENG_TYPE_SE].sg_ver2 &&
1524 [ # # ]: 0 : vf->cpt.hw_caps[CPT_ENG_TYPE_IE].sg_ver2) {
1525 : 0 : raw_dp_ctx->enqueue = cn10k_cpt_raw_enqueue_sgv2;
1526 : 0 : raw_dp_ctx->enqueue_burst = cn10k_cpt_raw_enqueue_burst_sgv2;
1527 : : } else {
1528 : 0 : raw_dp_ctx->enqueue = cn10k_cpt_raw_enqueue_sgv1;
1529 : 0 : raw_dp_ctx->enqueue_burst = cn10k_cpt_raw_enqueue_burst_sgv1;
1530 : : }
1531 : : }
1532 : :
1533 : : return 0;
1534 : : }
1535 : :
1536 : : struct rte_cryptodev_ops cn10k_cpt_ops = {
1537 : : /* Device control ops */
1538 : : .dev_configure = cnxk_cpt_dev_config,
1539 : : .dev_start = cnxk_cpt_dev_start,
1540 : : .dev_stop = cnxk_cpt_dev_stop,
1541 : : .dev_close = cnxk_cpt_dev_close,
1542 : : .dev_infos_get = cn10k_cpt_dev_info_get,
1543 : :
1544 : : .stats_get = NULL,
1545 : : .stats_reset = NULL,
1546 : : .queue_pair_setup = cnxk_cpt_queue_pair_setup,
1547 : : .queue_pair_release = cnxk_cpt_queue_pair_release,
1548 : :
1549 : : /* Symmetric crypto ops */
1550 : : .sym_session_get_size = cnxk_cpt_sym_session_get_size,
1551 : : .sym_session_configure = cnxk_cpt_sym_session_configure,
1552 : : .sym_session_clear = cnxk_cpt_sym_session_clear,
1553 : :
1554 : : /* Asymmetric crypto ops */
1555 : : .asym_session_get_size = cnxk_ae_session_size_get,
1556 : : .asym_session_configure = cnxk_ae_session_cfg,
1557 : : .asym_session_clear = cnxk_ae_session_clear,
1558 : :
1559 : : /* Event crypto ops */
1560 : : .session_ev_mdata_set = cn10k_cpt_crypto_adapter_ev_mdata_set,
1561 : : .queue_pair_event_error_query = cnxk_cpt_queue_pair_event_error_query,
1562 : :
1563 : : /* Raw data-path API related operations */
1564 : : .sym_get_raw_dp_ctx_size = cn10k_sym_get_raw_dp_ctx_size,
1565 : : .sym_configure_raw_dp_ctx = cn10k_sym_configure_raw_dp_ctx,
1566 : : };
|