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