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