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