Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <rte_cryptodev.h>
6 : : #include <cryptodev_pmd.h>
7 : : #include <rte_errno.h>
8 : :
9 : : #include "roc_ae_fpm_tables.h"
10 : : #include "roc_cpt.h"
11 : : #include "roc_errata.h"
12 : : #include "roc_ie_on.h"
13 : :
14 : : #include "cnxk_ae.h"
15 : : #include "cnxk_cryptodev.h"
16 : : #include "cnxk_cryptodev_capabilities.h"
17 : : #include "cnxk_cryptodev_ops.h"
18 : : #include "cnxk_se.h"
19 : :
20 : : #define CNXK_CPT_MAX_ASYM_OP_NUM_PARAMS 5
21 : : #define CNXK_CPT_MAX_ASYM_OP_MOD_LEN 1024
22 : : #define CNXK_CPT_META_BUF_MAX_CACHE_SIZE 128
23 : :
24 : : static int
25 : : cnxk_cpt_get_mlen(void)
26 : : {
27 : : uint32_t len;
28 : :
29 : : /* For MAC */
30 : : len = 2 * sizeof(uint64_t);
31 : : len += ROC_SE_MAX_MAC_LEN * sizeof(uint8_t);
32 : :
33 : : /* For PDCP_CHAIN passthrough alignment */
34 : : len += 8;
35 : : len += ROC_SE_OFF_CTRL_LEN + ROC_CPT_AES_CBC_IV_LEN;
36 : : len += RTE_ALIGN_CEIL((ROC_SG_LIST_HDR_SIZE +
37 : : (RTE_ALIGN_CEIL(ROC_MAX_SG_IN_OUT_CNT, 4) >> 2) * ROC_SG_ENTRY_SIZE),
38 : : 8);
39 : :
40 : : return len;
41 : : }
42 : :
43 : : static int
44 : : cnxk_cpt_sec_get_mlen(void)
45 : : {
46 : : uint32_t len;
47 : :
48 : : len = ROC_IE_ON_OUTB_DPTR_HDR + ROC_IE_ON_MAX_IV_LEN;
49 : : len += RTE_ALIGN_CEIL((ROC_SG_LIST_HDR_SIZE +
50 : : (RTE_ALIGN_CEIL(ROC_MAX_SG_IN_OUT_CNT, 4) >> 2) * ROC_SG_ENTRY_SIZE),
51 : : 8);
52 : :
53 : : return len;
54 : : }
55 : :
56 : : static int
57 : : cnxk_cpt_asym_get_mlen(void)
58 : : {
59 : : uint32_t len;
60 : :
61 : : /* To hold RPTR */
62 : : len = sizeof(uint64_t);
63 : :
64 : : /* Get meta len for asymmetric operations */
65 : : len += CNXK_CPT_MAX_ASYM_OP_NUM_PARAMS * CNXK_CPT_MAX_ASYM_OP_MOD_LEN;
66 : :
67 : : return len;
68 : : }
69 : :
70 : : static int
71 : 0 : cnxk_cpt_dev_clear(struct rte_cryptodev *dev)
72 : : {
73 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
74 : : int ret;
75 : :
76 [ # # ]: 0 : if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) {
77 : 0 : roc_ae_fpm_put();
78 : 0 : roc_ae_ec_grp_put();
79 : : }
80 : :
81 : 0 : ret = roc_cpt_int_misc_cb_unregister(cnxk_cpt_int_misc_cb, NULL);
82 [ # # ]: 0 : if (ret < 0) {
83 : 0 : plt_err("Could not unregister CPT_MISC_INT cb");
84 : 0 : return ret;
85 : : }
86 : :
87 : 0 : roc_cpt_dev_clear(&vf->cpt);
88 : :
89 : 0 : return 0;
90 : : }
91 : :
92 : : int
93 : 0 : cnxk_cpt_dev_config(struct rte_cryptodev *dev, struct rte_cryptodev_config *conf)
94 : : {
95 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
96 : 0 : struct roc_cpt *roc_cpt = &vf->cpt;
97 : : uint16_t nb_lf_avail, nb_lf;
98 : : int ret;
99 : :
100 : : /* If this is a reconfigure attempt, clear the device and configure again */
101 [ # # ]: 0 : if (roc_cpt->nb_lf > 0) {
102 : 0 : cnxk_cpt_dev_clear(dev);
103 : 0 : roc_cpt->opaque = NULL;
104 : : }
105 : :
106 : 0 : dev->feature_flags = cnxk_cpt_default_ff_get() & ~conf->ff_disable;
107 : :
108 : 0 : nb_lf_avail = roc_cpt->nb_lf_avail;
109 : 0 : nb_lf = conf->nb_queue_pairs;
110 : :
111 [ # # ]: 0 : if (nb_lf > nb_lf_avail)
112 : : return -ENOTSUP;
113 : :
114 : 0 : ret = roc_cpt_dev_configure(roc_cpt, nb_lf);
115 [ # # ]: 0 : if (ret) {
116 : 0 : plt_err("Could not configure device");
117 : 0 : return ret;
118 : : }
119 : :
120 [ # # ]: 0 : if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) {
121 : : /* Initialize shared FPM table */
122 : 0 : ret = roc_ae_fpm_get(vf->cnxk_fpm_iova);
123 [ # # ]: 0 : if (ret) {
124 : 0 : plt_err("Could not get FPM table");
125 : 0 : return ret;
126 : : }
127 : :
128 : : /* Init EC grp table */
129 : 0 : ret = roc_ae_ec_grp_get(vf->ec_grp);
130 [ # # ]: 0 : if (ret) {
131 : 0 : plt_err("Could not get EC grp table");
132 : 0 : roc_ae_fpm_put();
133 : 0 : return ret;
134 : : }
135 : : }
136 : 0 : roc_cpt->opaque = dev;
137 : : /* Register callback to handle CPT_MISC_INT */
138 : 0 : roc_cpt_int_misc_cb_register(cnxk_cpt_int_misc_cb, NULL);
139 : :
140 : 0 : return 0;
141 : : }
142 : :
143 : : int
144 : 0 : cnxk_cpt_dev_start(struct rte_cryptodev *dev)
145 : : {
146 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
147 : : struct roc_cpt *roc_cpt = &vf->cpt;
148 : 0 : uint16_t nb_lf = roc_cpt->nb_lf;
149 : : uint16_t qp_id;
150 : :
151 [ # # ]: 0 : for (qp_id = 0; qp_id < nb_lf; qp_id++) {
152 : : /* Application may not setup all queue pair */
153 [ # # ]: 0 : if (roc_cpt->lf[qp_id] == NULL)
154 : 0 : continue;
155 : :
156 : 0 : roc_cpt_iq_enable(roc_cpt->lf[qp_id]);
157 : : }
158 : :
159 : 0 : return 0;
160 : : }
161 : :
162 : : void
163 : 0 : cnxk_cpt_dev_stop(struct rte_cryptodev *dev)
164 : : {
165 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
166 : : struct roc_cpt *roc_cpt = &vf->cpt;
167 : 0 : uint16_t nb_lf = roc_cpt->nb_lf;
168 : : uint16_t qp_id;
169 : :
170 [ # # ]: 0 : for (qp_id = 0; qp_id < nb_lf; qp_id++) {
171 [ # # ]: 0 : if (roc_cpt->lf[qp_id] == NULL)
172 : 0 : continue;
173 : :
174 : 0 : roc_cpt_iq_disable(roc_cpt->lf[qp_id]);
175 : : }
176 : 0 : }
177 : :
178 : : int
179 : 0 : cnxk_cpt_dev_close(struct rte_cryptodev *dev)
180 : : {
181 : : uint16_t i;
182 : : int ret;
183 : :
184 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
185 : 0 : ret = cnxk_cpt_queue_pair_release(dev, i);
186 [ # # ]: 0 : if (ret < 0) {
187 : 0 : plt_err("Could not release queue pair %u", i);
188 : 0 : return ret;
189 : : }
190 : : }
191 : :
192 : 0 : return cnxk_cpt_dev_clear(dev);
193 : : }
194 : :
195 : : void
196 : 0 : cnxk_cpt_dev_info_get(struct rte_cryptodev *dev,
197 : : struct rte_cryptodev_info *info)
198 : : {
199 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
200 : : struct roc_cpt *roc_cpt = &vf->cpt;
201 : :
202 : 0 : info->max_nb_queue_pairs =
203 : 0 : RTE_MIN(roc_cpt->nb_lf_avail, vf->max_qps_limit);
204 : 0 : plt_cpt_dbg("max_nb_queue_pairs %u", info->max_nb_queue_pairs);
205 : :
206 : 0 : info->feature_flags = cnxk_cpt_default_ff_get();
207 : 0 : info->capabilities = cnxk_crypto_capabilities_get(vf);
208 : 0 : info->sym.max_nb_sessions = 0;
209 : 0 : info->min_mbuf_headroom_req = CNXK_CPT_MIN_HEADROOM_REQ;
210 : 0 : info->min_mbuf_tailroom_req = CNXK_CPT_MIN_TAILROOM_REQ;
211 : 0 : }
212 : :
213 : : static void
214 : : qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
215 : : {
216 : : snprintf(name, size, "cnxk_cpt_pq_mem_%u:%u", dev_id, qp_id);
217 : : }
218 : :
219 : : static int
220 : 0 : cnxk_cpt_metabuf_mempool_create(const struct rte_cryptodev *dev,
221 : : struct cnxk_cpt_qp *qp, uint8_t qp_id,
222 : : uint32_t nb_elements)
223 : : {
224 : : char mempool_name[RTE_MEMPOOL_NAMESIZE];
225 : : struct cpt_qp_meta_info *meta_info;
226 : 0 : int lcore_cnt = rte_lcore_count();
227 : : struct rte_mempool *pool;
228 : : int mb_pool_sz, mlen = 8;
229 : : uint32_t cache_sz;
230 : :
231 [ # # ]: 0 : if (dev->feature_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) {
232 : : /* Get meta len */
233 : : mlen = cnxk_cpt_get_mlen();
234 : : }
235 : :
236 [ # # ]: 0 : if (dev->feature_flags & RTE_CRYPTODEV_FF_SECURITY) {
237 : : /* Get meta len for security operations */
238 : : mlen = cnxk_cpt_sec_get_mlen();
239 : : }
240 : :
241 [ # # ]: 0 : if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) {
242 : :
243 : : /* Get meta len required for asymmetric operations */
244 : : mlen = RTE_MAX(mlen, cnxk_cpt_asym_get_mlen());
245 : : }
246 : :
247 : : mb_pool_sz = nb_elements;
248 [ # # ]: 0 : cache_sz = RTE_MIN(CNXK_CPT_META_BUF_MAX_CACHE_SIZE, nb_elements / 1.5);
249 : :
250 : : /* For poll mode, core that enqueues and core that dequeues can be
251 : : * different. For event mode, all cores are allowed to use same crypto
252 : : * queue pair.
253 : : */
254 : :
255 : 0 : mb_pool_sz += (RTE_MAX(2, lcore_cnt) * cache_sz);
256 : :
257 : : /* Allocate mempool */
258 : :
259 : 0 : snprintf(mempool_name, RTE_MEMPOOL_NAMESIZE, "cnxk_cpt_mb_%u:%u",
260 : 0 : dev->data->dev_id, qp_id);
261 : :
262 : 0 : pool = rte_mempool_create(mempool_name, mb_pool_sz, mlen, cache_sz, 0,
263 : 0 : NULL, NULL, NULL, NULL, rte_socket_id(), 0);
264 : :
265 [ # # ]: 0 : if (pool == NULL) {
266 : 0 : plt_err("Could not create mempool for metabuf");
267 : 0 : return rte_errno;
268 : : }
269 : :
270 : : meta_info = &qp->meta_info;
271 : :
272 : 0 : meta_info->pool = pool;
273 : 0 : meta_info->mlen = mlen;
274 : :
275 : 0 : return 0;
276 : : }
277 : :
278 : : static void
279 : : cnxk_cpt_metabuf_mempool_destroy(struct cnxk_cpt_qp *qp)
280 : : {
281 : : struct cpt_qp_meta_info *meta_info = &qp->meta_info;
282 : :
283 : 0 : rte_mempool_free(meta_info->pool);
284 : :
285 : 0 : meta_info->pool = NULL;
286 : 0 : meta_info->mlen = 0;
287 : : }
288 : :
289 : : static struct cnxk_cpt_qp *
290 : 0 : cnxk_cpt_qp_create(const struct rte_cryptodev *dev, uint16_t qp_id,
291 : : uint32_t iq_len)
292 : : {
293 : : const struct rte_memzone *pq_mem;
294 : : char name[RTE_MEMZONE_NAMESIZE];
295 : : struct cnxk_cpt_qp *qp;
296 : : uint32_t len;
297 : : uint8_t *va;
298 : : int ret;
299 : :
300 : : /* Allocate queue pair */
301 : 0 : qp = rte_zmalloc_socket("CNXK Crypto PMD Queue Pair", sizeof(*qp),
302 : : ROC_ALIGN, 0);
303 [ # # ]: 0 : if (qp == NULL) {
304 : 0 : plt_err("Could not allocate queue pair");
305 : 0 : return NULL;
306 : : }
307 : :
308 : : /* For pending queue */
309 : 0 : len = iq_len * sizeof(struct cpt_inflight_req);
310 : :
311 : 0 : qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
312 : : qp_id);
313 : :
314 : 0 : pq_mem = rte_memzone_reserve_aligned(name, len, rte_socket_id(),
315 : : RTE_MEMZONE_SIZE_HINT_ONLY |
316 : : RTE_MEMZONE_256MB,
317 : : RTE_CACHE_LINE_SIZE);
318 [ # # ]: 0 : if (pq_mem == NULL) {
319 : 0 : plt_err("Could not allocate reserved memzone");
320 : 0 : goto qp_free;
321 : : }
322 : :
323 : 0 : va = pq_mem->addr;
324 : :
325 : : memset(va, 0, len);
326 : :
327 : 0 : ret = cnxk_cpt_metabuf_mempool_create(dev, qp, qp_id, iq_len);
328 [ # # ]: 0 : if (ret) {
329 : 0 : plt_err("Could not create mempool for metabuf");
330 : 0 : goto pq_mem_free;
331 : : }
332 : :
333 : : /* Initialize pending queue */
334 : 0 : qp->pend_q.req_queue = pq_mem->addr;
335 : 0 : qp->pend_q.head = 0;
336 : 0 : qp->pend_q.tail = 0;
337 : :
338 : 0 : return qp;
339 : :
340 : : pq_mem_free:
341 : 0 : rte_memzone_free(pq_mem);
342 : 0 : qp_free:
343 : 0 : rte_free(qp);
344 : 0 : return NULL;
345 : : }
346 : :
347 : : static int
348 : 0 : cnxk_cpt_qp_destroy(const struct rte_cryptodev *dev, struct cnxk_cpt_qp *qp)
349 : : {
350 : : const struct rte_memzone *pq_mem;
351 : : char name[RTE_MEMZONE_NAMESIZE];
352 : : int ret;
353 : :
354 : : cnxk_cpt_metabuf_mempool_destroy(qp);
355 : :
356 : 0 : qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
357 : 0 : qp->lf.lf_id);
358 : :
359 : 0 : pq_mem = rte_memzone_lookup(name);
360 : :
361 : 0 : ret = rte_memzone_free(pq_mem);
362 [ # # ]: 0 : if (ret)
363 : : return ret;
364 : :
365 : 0 : rte_free(qp);
366 : :
367 : 0 : return 0;
368 : : }
369 : :
370 : : int
371 : 0 : cnxk_cpt_queue_pair_release(struct rte_cryptodev *dev, uint16_t qp_id)
372 : : {
373 : 0 : struct cnxk_cpt_qp *qp = dev->data->queue_pairs[qp_id];
374 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
375 : : struct roc_cpt *roc_cpt = &vf->cpt;
376 : : struct roc_cpt_lf *lf;
377 : : int ret;
378 : :
379 [ # # ]: 0 : if (qp == NULL)
380 : : return -EINVAL;
381 : :
382 : 0 : lf = roc_cpt->lf[qp_id];
383 [ # # ]: 0 : if (lf == NULL)
384 : : return -ENOTSUP;
385 : :
386 : 0 : roc_cpt_lf_fini(lf);
387 : :
388 : 0 : ret = cnxk_cpt_qp_destroy(dev, qp);
389 [ # # ]: 0 : if (ret) {
390 : 0 : plt_err("Could not destroy queue pair %d", qp_id);
391 : 0 : return ret;
392 : : }
393 : :
394 : 0 : roc_cpt->lf[qp_id] = NULL;
395 : 0 : dev->data->queue_pairs[qp_id] = NULL;
396 : :
397 : 0 : return 0;
398 : : }
399 : :
400 : : int
401 : 0 : cnxk_cpt_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id,
402 : : const struct rte_cryptodev_qp_conf *conf,
403 : : int socket_id __rte_unused)
404 : : {
405 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
406 : 0 : struct roc_cpt *roc_cpt = &vf->cpt;
407 : : struct rte_pci_device *pci_dev;
408 : : struct cnxk_cpt_qp *qp;
409 : : uint32_t nb_desc;
410 : : int ret;
411 : :
412 [ # # ]: 0 : if (dev->data->queue_pairs[qp_id] != NULL)
413 : 0 : cnxk_cpt_queue_pair_release(dev, qp_id);
414 : :
415 : 0 : pci_dev = RTE_DEV_TO_PCI(dev->device);
416 : :
417 [ # # ]: 0 : if (pci_dev->mem_resource[2].addr == NULL) {
418 : 0 : plt_err("Invalid PCI mem address");
419 : 0 : return -EIO;
420 : : }
421 : :
422 : : /* Update nb_desc to next power of 2 to aid in pending queue checks */
423 : 0 : nb_desc = plt_align32pow2(conf->nb_descriptors);
424 : :
425 : 0 : qp = cnxk_cpt_qp_create(dev, qp_id, nb_desc);
426 [ # # ]: 0 : if (qp == NULL) {
427 : 0 : plt_err("Could not create queue pair %d", qp_id);
428 : 0 : return -ENOMEM;
429 : : }
430 : :
431 : 0 : qp->lf.lf_id = qp_id;
432 : 0 : qp->lf.nb_desc = nb_desc;
433 : :
434 : 0 : ret = roc_cpt_lf_init(roc_cpt, &qp->lf);
435 [ # # ]: 0 : if (ret < 0) {
436 : 0 : plt_err("Could not initialize queue pair %d", qp_id);
437 : : ret = -EINVAL;
438 : 0 : goto exit;
439 : : }
440 : :
441 : 0 : qp->pend_q.pq_mask = qp->lf.nb_desc - 1;
442 : :
443 : 0 : roc_cpt->lf[qp_id] = &qp->lf;
444 : :
445 : 0 : ret = roc_cpt_lmtline_init(roc_cpt, &qp->lmtline, qp_id);
446 [ # # ]: 0 : if (ret < 0) {
447 : 0 : roc_cpt->lf[qp_id] = NULL;
448 : 0 : plt_err("Could not init lmtline for queue pair %d", qp_id);
449 : 0 : goto exit;
450 : : }
451 : :
452 : 0 : qp->sess_mp = conf->mp_session;
453 : 0 : dev->data->queue_pairs[qp_id] = qp;
454 : :
455 : 0 : return 0;
456 : :
457 : 0 : exit:
458 : 0 : cnxk_cpt_qp_destroy(dev, qp);
459 : 0 : return ret;
460 : : }
461 : :
462 : : unsigned int
463 : 0 : cnxk_cpt_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
464 : : {
465 : 0 : return sizeof(struct cnxk_se_sess);
466 : : }
467 : :
468 : : static bool
469 : : is_valid_pdcp_cipher_alg(struct rte_crypto_sym_xform *c_xfrm,
470 : : struct cnxk_se_sess *sess)
471 : : {
472 [ # # # # : 0 : switch (c_xfrm->cipher.algo) {
# # ]
473 : : case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
474 : : case RTE_CRYPTO_CIPHER_ZUC_EEA3:
475 : : break;
476 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
477 : 0 : sess->aes_ctr_eea2 = 1;
478 : : break;
479 : : default:
480 : : return false;
481 : : }
482 : :
483 : : return true;
484 : : }
485 : :
486 : : static int
487 : 0 : cnxk_sess_fill(struct roc_cpt *roc_cpt, struct rte_crypto_sym_xform *xform,
488 : : struct cnxk_se_sess *sess)
489 : : {
490 : : struct rte_crypto_sym_xform *aead_xfrm = NULL;
491 : : struct rte_crypto_sym_xform *c_xfrm = NULL;
492 : : struct rte_crypto_sym_xform *a_xfrm = NULL;
493 : : bool ciph_then_auth = false;
494 : :
495 [ # # ]: 0 : if (roc_cpt->hw_caps[CPT_ENG_TYPE_SE].pdcp_chain_zuc256)
496 : 0 : sess->roc_se_ctx.pdcp_iv_offset = 24;
497 : : else
498 : 0 : sess->roc_se_ctx.pdcp_iv_offset = 16;
499 : :
500 [ # # ]: 0 : if (xform == NULL)
501 : : return -EINVAL;
502 : :
503 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
504 : : c_xfrm = xform;
505 : 0 : a_xfrm = xform->next;
506 : : ciph_then_auth = true;
507 [ # # ]: 0 : } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
508 : 0 : c_xfrm = xform->next;
509 : : a_xfrm = xform;
510 : : ciph_then_auth = false;
511 : : } else {
512 : : aead_xfrm = xform;
513 : : }
514 : :
515 [ # # # # ]: 0 : if (c_xfrm != NULL && c_xfrm->type != RTE_CRYPTO_SYM_XFORM_CIPHER) {
516 : 0 : plt_dp_err("Invalid type in cipher xform");
517 : 0 : return -EINVAL;
518 : : }
519 : :
520 [ # # # # ]: 0 : if (a_xfrm != NULL && a_xfrm->type != RTE_CRYPTO_SYM_XFORM_AUTH) {
521 : 0 : plt_dp_err("Invalid type in auth xform");
522 : 0 : return -EINVAL;
523 : : }
524 : :
525 [ # # # # ]: 0 : if (aead_xfrm != NULL && aead_xfrm->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
526 : 0 : plt_dp_err("Invalid type in AEAD xform");
527 : 0 : return -EINVAL;
528 : : }
529 : :
530 [ # # # # ]: 0 : if ((aead_xfrm == NULL) &&
531 [ # # # # ]: 0 : (c_xfrm == NULL || c_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_NULL) &&
532 [ # # ]: 0 : (a_xfrm == NULL || a_xfrm->auth.algo == RTE_CRYPTO_AUTH_NULL))
533 : 0 : sess->passthrough = 1;
534 : :
535 : : /* Cipher only */
536 [ # # # # : 0 : if (c_xfrm != NULL && (a_xfrm == NULL || a_xfrm->auth.algo == RTE_CRYPTO_AUTH_NULL)) {
# # ]
537 : : if (fill_sess_cipher(c_xfrm, sess))
538 : 0 : return -ENOTSUP;
539 : : else
540 : 0 : return 0;
541 : : }
542 : :
543 : : /* Auth only */
544 [ # # # # ]: 0 : if (a_xfrm != NULL &&
545 [ # # ]: 0 : (c_xfrm == NULL || c_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_NULL)) {
546 : : if (fill_sess_auth(a_xfrm, sess))
547 : 0 : return -ENOTSUP;
548 : : else
549 : 0 : return 0;
550 : : }
551 : :
552 : : /* AEAD */
553 [ # # ]: 0 : if (aead_xfrm != NULL) {
554 : : if (fill_sess_aead(aead_xfrm, sess))
555 : 0 : return -ENOTSUP;
556 : : else
557 : 0 : return 0;
558 : : }
559 : :
560 : : /* Chained ops */
561 [ # # ]: 0 : if (c_xfrm == NULL || a_xfrm == NULL) {
562 : 0 : plt_dp_err("Invalid xforms");
563 : 0 : return -EINVAL;
564 : : }
565 : :
566 [ # # ]: 0 : if (c_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_XTS) {
567 : 0 : plt_err("AES XTS with auth algorithm is not supported");
568 : 0 : return -ENOTSUP;
569 : : }
570 : :
571 [ # # ]: 0 : if (c_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC &&
572 [ # # ]: 0 : a_xfrm->auth.algo == RTE_CRYPTO_AUTH_SHA1) {
573 : 0 : plt_dp_err("3DES-CBC + SHA1 is not supported");
574 : 0 : return -ENOTSUP;
575 : : }
576 : :
577 : : /* Cipher then auth */
578 [ # # ]: 0 : if (ciph_then_auth) {
579 [ # # ]: 0 : if (c_xfrm->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
580 [ # # ]: 0 : if (a_xfrm->auth.op != RTE_CRYPTO_AUTH_OP_VERIFY)
581 : : return -EINVAL;
582 : 0 : sess->auth_first = 1;
583 [ # # # ]: 0 : switch (a_xfrm->auth.algo) {
584 [ # # ]: 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
585 : : switch (c_xfrm->cipher.algo) {
586 : : case RTE_CRYPTO_CIPHER_AES_CBC:
587 : : break;
588 : : default:
589 : : return -ENOTSUP;
590 : : }
591 : : break;
592 : : case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
593 : : case RTE_CRYPTO_AUTH_ZUC_EIA3:
594 : : case RTE_CRYPTO_AUTH_AES_CMAC:
595 : : if (!is_valid_pdcp_cipher_alg(c_xfrm, sess))
596 : : return -ENOTSUP;
597 : : break;
598 : : default:
599 : : return -ENOTSUP;
600 : : }
601 : : }
602 : 0 : sess->roc_se_ctx.ciph_then_auth = 1;
603 [ # # ]: 0 : sess->chained_op = 1;
604 : : if (fill_sess_cipher(c_xfrm, sess))
605 : 0 : return -ENOTSUP;
606 : : if (fill_sess_auth(a_xfrm, sess))
607 : 0 : return -ENOTSUP;
608 : : else
609 : 0 : return 0;
610 : : }
611 : :
612 : : /* else */
613 : :
614 [ # # ]: 0 : if (c_xfrm->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
615 [ # # ]: 0 : if (a_xfrm->auth.op != RTE_CRYPTO_AUTH_OP_GENERATE)
616 : : return -EINVAL;
617 : 0 : sess->auth_first = 1;
618 [ # # # ]: 0 : switch (a_xfrm->auth.algo) {
619 [ # # ]: 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
620 : : switch (c_xfrm->cipher.algo) {
621 : : case RTE_CRYPTO_CIPHER_AES_CBC:
622 : : break;
623 : : default:
624 : : return -ENOTSUP;
625 : : }
626 : : break;
627 : : case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
628 : : case RTE_CRYPTO_AUTH_ZUC_EIA3:
629 : : case RTE_CRYPTO_AUTH_AES_CMAC:
630 : : if (!is_valid_pdcp_cipher_alg(c_xfrm, sess))
631 : : return -ENOTSUP;
632 : : break;
633 : : default:
634 : : return -ENOTSUP;
635 : : }
636 : : }
637 : :
638 : 0 : sess->roc_se_ctx.auth_then_ciph = 1;
639 [ # # ]: 0 : sess->chained_op = 1;
640 : : if (fill_sess_auth(a_xfrm, sess))
641 : 0 : return -ENOTSUP;
642 : : if (fill_sess_cipher(c_xfrm, sess))
643 : 0 : return -ENOTSUP;
644 : : else
645 : 0 : return 0;
646 : : }
647 : :
648 : : static uint64_t
649 : 0 : cnxk_cpt_inst_w7_get(struct cnxk_se_sess *sess, struct roc_cpt *roc_cpt)
650 : : {
651 : : union cpt_inst_w7 inst_w7;
652 : :
653 [ # # ]: 0 : inst_w7.s.cptr = (uint64_t)&sess->roc_se_ctx.se_ctx;
654 : :
655 [ # # ]: 0 : if (hw_ctx_cache_enable())
656 : 0 : inst_w7.s.ctx_val = 1;
657 : : else
658 : 0 : inst_w7.s.cptr += 8;
659 : :
660 : : /* Set the engine group */
661 : 0 : if (sess->zsk_flag || sess->aes_ctr_eea2 || sess->is_sha3 || sess->is_sm3 ||
662 [ # # ]: 0 : sess->passthrough || sess->is_sm4)
663 : 0 : inst_w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_SE];
664 : : else
665 : 0 : inst_w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_IE];
666 : :
667 : 0 : return inst_w7.u64;
668 : : }
669 : :
670 : : int
671 : 0 : sym_session_configure(struct roc_cpt *roc_cpt, struct rte_crypto_sym_xform *xform,
672 : : struct rte_cryptodev_sym_session *sess, bool is_session_less)
673 : : {
674 : : enum cpt_dp_thread_type thr_type;
675 : : struct cnxk_se_sess *sess_priv = (struct cnxk_se_sess *)sess;
676 : : int ret;
677 : :
678 [ # # ]: 0 : if (is_session_less)
679 : : memset(sess_priv, 0, sizeof(struct cnxk_se_sess));
680 : :
681 : 0 : ret = cnxk_sess_fill(roc_cpt, xform, sess_priv);
682 [ # # ]: 0 : if (ret)
683 : 0 : goto priv_put;
684 : :
685 : 0 : sess_priv->lf = roc_cpt->lf[0];
686 : :
687 [ # # ]: 0 : if (sess_priv->passthrough)
688 : : thr_type = CPT_DP_THREAD_TYPE_PT;
689 [ # # ]: 0 : else if (sess_priv->cpt_op & ROC_SE_OP_CIPHER_MASK) {
690 [ # # # # : 0 : switch (sess_priv->roc_se_ctx.fc_type) {
# # ]
691 : 0 : case ROC_SE_FC_GEN:
692 [ # # ]: 0 : if (sess_priv->aes_gcm || sess_priv->aes_ccm || sess_priv->chacha_poly)
693 : : thr_type = CPT_DP_THREAD_TYPE_FC_AEAD;
694 : : else
695 : : thr_type = CPT_DP_THREAD_TYPE_FC_CHAIN;
696 : : break;
697 : : case ROC_SE_PDCP:
698 : : thr_type = CPT_DP_THREAD_TYPE_PDCP;
699 : : break;
700 : 0 : case ROC_SE_KASUMI:
701 : : thr_type = CPT_DP_THREAD_TYPE_KASUMI;
702 : 0 : break;
703 : 0 : case ROC_SE_PDCP_CHAIN:
704 : : thr_type = CPT_DP_THREAD_TYPE_PDCP_CHAIN;
705 : 0 : break;
706 : 0 : case ROC_SE_SM:
707 : : thr_type = CPT_DP_THREAD_TYPE_SM;
708 : 0 : break;
709 : 0 : default:
710 : 0 : plt_err("Invalid op type");
711 : : ret = -ENOTSUP;
712 : 0 : goto priv_put;
713 : : }
714 : : } else {
715 : : thr_type = CPT_DP_THREAD_AUTH_ONLY;
716 : : }
717 : :
718 : 0 : sess_priv->dp_thr_type = thr_type;
719 : :
720 [ # # ]: 0 : if ((sess_priv->roc_se_ctx.fc_type == ROC_SE_HASH_HMAC) &&
721 : : cpt_mac_len_verify(&xform->auth)) {
722 : 0 : plt_dp_err("MAC length is not supported");
723 [ # # ]: 0 : if (sess_priv->roc_se_ctx.auth_key != NULL) {
724 : 0 : plt_free(sess_priv->roc_se_ctx.auth_key);
725 : 0 : sess_priv->roc_se_ctx.auth_key = NULL;
726 : : }
727 : :
728 : : ret = -ENOTSUP;
729 : 0 : goto priv_put;
730 : : }
731 : :
732 [ # # ]: 0 : sess_priv->cpt_inst_w7 = cnxk_cpt_inst_w7_get(sess_priv, roc_cpt);
733 : :
734 [ # # ]: 0 : if (hw_ctx_cache_enable())
735 : 0 : roc_se_ctx_init(&sess_priv->roc_se_ctx);
736 : :
737 : : return 0;
738 : :
739 : : priv_put:
740 : : return ret;
741 : : }
742 : :
743 : : int
744 : 0 : cnxk_cpt_sym_session_configure(struct rte_cryptodev *dev,
745 : : struct rte_crypto_sym_xform *xform,
746 : : struct rte_cryptodev_sym_session *sess)
747 : : {
748 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
749 : 0 : struct roc_cpt *roc_cpt = &vf->cpt;
750 : :
751 : 0 : return sym_session_configure(roc_cpt, xform, sess, false);
752 : : }
753 : :
754 : : void
755 [ # # ]: 0 : sym_session_clear(struct rte_cryptodev_sym_session *sess, bool is_session_less)
756 : : {
757 : : struct cnxk_se_sess *sess_priv = (struct cnxk_se_sess *)sess;
758 : :
759 : : /* Trigger CTX flush + invalidate to remove from CTX_CACHE */
760 [ # # ]: 0 : if (hw_ctx_cache_enable())
761 : 0 : roc_cpt_lf_ctx_flush(sess_priv->lf, &sess_priv->roc_se_ctx.se_ctx, true);
762 : :
763 [ # # ]: 0 : if (sess_priv->roc_se_ctx.auth_key != NULL)
764 : 0 : plt_free(sess_priv->roc_se_ctx.auth_key);
765 : :
766 [ # # ]: 0 : if (is_session_less)
767 : 0 : memset(sess_priv, 0, cnxk_cpt_sym_session_get_size(NULL));
768 : 0 : }
769 : :
770 : : void
771 : 0 : cnxk_cpt_sym_session_clear(struct rte_cryptodev *dev __rte_unused,
772 : : struct rte_cryptodev_sym_session *sess)
773 : : {
774 : 0 : return sym_session_clear(sess, false);
775 : : }
776 : :
777 : : unsigned int
778 : 0 : cnxk_ae_session_size_get(struct rte_cryptodev *dev __rte_unused)
779 : : {
780 : 0 : return sizeof(struct cnxk_ae_sess);
781 : : }
782 : :
783 : : void
784 [ # # ]: 0 : cnxk_ae_session_clear(struct rte_cryptodev *dev, struct rte_cryptodev_asym_session *sess)
785 : : {
786 : : struct cnxk_ae_sess *priv = (struct cnxk_ae_sess *)sess;
787 : :
788 : : /* Trigger CTX flush + invalidate to remove from CTX_CACHE */
789 [ # # ]: 0 : if (roc_errata_cpt_hang_on_mixed_ctx_val())
790 : 0 : roc_cpt_lf_ctx_flush(priv->lf, &priv->hw_ctx, true);
791 : :
792 : : /* Free resources allocated in session_cfg */
793 : 0 : cnxk_ae_free_session_parameters(priv);
794 : :
795 : : /* Reset and free object back to pool */
796 : 0 : memset(priv, 0, cnxk_ae_session_size_get(dev));
797 : 0 : }
798 : :
799 : : int
800 : 0 : cnxk_ae_session_cfg(struct rte_cryptodev *dev, struct rte_crypto_asym_xform *xform,
801 : : struct rte_cryptodev_asym_session *sess)
802 : : {
803 : : struct cnxk_ae_sess *priv = (struct cnxk_ae_sess *)sess;
804 [ # # # # ]: 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
805 : : struct roc_cpt *roc_cpt = &vf->cpt;
806 : : union cpt_inst_w7 w7;
807 : : struct hw_ctx_s *hwc;
808 : : int ret;
809 : :
810 : : ret = cnxk_ae_fill_session_parameters(priv, xform);
811 : : if (ret)
812 : 0 : return ret;
813 : :
814 : 0 : priv->lf = roc_cpt->lf[0];
815 : :
816 : 0 : w7.u64 = 0;
817 [ # # ]: 0 : w7.s.egrp = roc_cpt->eng_grp[CPT_ENG_TYPE_AE];
818 : :
819 [ # # ]: 0 : if (roc_errata_cpt_hang_on_mixed_ctx_val()) {
820 : 0 : hwc = &priv->hw_ctx;
821 : 0 : hwc->w0.s.aop_valid = 1;
822 : 0 : hwc->w0.s.ctx_hdr_size = 0;
823 : 0 : hwc->w0.s.ctx_size = 1;
824 : 0 : hwc->w0.s.ctx_push_size = 1;
825 : :
826 : 0 : w7.s.cptr = (uint64_t)hwc;
827 : 0 : w7.s.ctx_val = 1;
828 : : }
829 : :
830 : 0 : priv->cpt_inst_w7 = w7.u64;
831 : 0 : priv->cnxk_fpm_iova = vf->cnxk_fpm_iova;
832 : 0 : priv->ec_grp = vf->ec_grp;
833 : :
834 : 0 : return 0;
835 : : }
836 : :
837 : : void
838 : 0 : cnxk_cpt_dump_on_err(struct cnxk_cpt_qp *qp)
839 : : {
840 : : struct pending_queue *pend_q = &qp->pend_q;
841 : : uint64_t inflight, enq_ptr, deq_ptr, insts;
842 : : union cpt_lf_q_inst_ptr inst_ptr;
843 : : union cpt_lf_inprog lf_inprog;
844 : :
845 : 0 : plt_print("Lcore ID: %d, LF/QP ID: %d", rte_lcore_id(), qp->lf.lf_id);
846 : 0 : plt_print("");
847 : 0 : plt_print("S/w pending queue:");
848 : 0 : plt_print("\tHead: %"PRIu64"", pend_q->head);
849 : 0 : plt_print("\tTail: %"PRIu64"", pend_q->tail);
850 : 0 : plt_print("\tMask: 0x%"PRIx64"", pend_q->pq_mask);
851 : 0 : plt_print("\tInflight count: %"PRIu64"",
852 : : pending_queue_infl_cnt(pend_q->head, pend_q->tail,
853 : : pend_q->pq_mask));
854 : :
855 : 0 : plt_print("");
856 : 0 : plt_print("H/w pending queue:");
857 : :
858 : 0 : lf_inprog.u = plt_read64(qp->lf.rbase + CPT_LF_INPROG);
859 : 0 : inflight = lf_inprog.s.inflight;
860 : 0 : plt_print("\tInflight in engines: %"PRIu64"", inflight);
861 : :
862 [ # # ]: 0 : inst_ptr.u = plt_read64(qp->lf.rbase + CPT_LF_Q_INST_PTR);
863 : :
864 : 0 : enq_ptr = inst_ptr.s.nq_ptr;
865 : 0 : deq_ptr = inst_ptr.s.dq_ptr;
866 : :
867 [ # # ]: 0 : if (enq_ptr >= deq_ptr)
868 : 0 : insts = enq_ptr - deq_ptr;
869 : : else
870 : 0 : insts = (enq_ptr + pend_q->pq_mask + 1 + 320 + 40) - deq_ptr;
871 : :
872 : 0 : plt_print("\tNQ ptr: 0x%"PRIx64"", enq_ptr);
873 : 0 : plt_print("\tDQ ptr: 0x%"PRIx64"", deq_ptr);
874 : 0 : plt_print("Insts waiting in CPT: %"PRIu64"", insts);
875 : :
876 : 0 : plt_print("");
877 : 0 : roc_cpt_afs_print(qp->lf.roc_cpt);
878 : 0 : }
879 : :
880 : : int
881 : 0 : cnxk_cpt_queue_pair_event_error_query(struct rte_cryptodev *dev, uint16_t qp_id)
882 : : {
883 : 0 : struct cnxk_cpt_vf *vf = dev->data->dev_private;
884 : : struct roc_cpt *roc_cpt = &vf->cpt;
885 : : struct roc_cpt_lf *lf;
886 : :
887 : 0 : lf = roc_cpt->lf[qp_id];
888 [ # # # # ]: 0 : if (lf && lf->error_event_pending) {
889 : 0 : lf->error_event_pending = 0;
890 : 0 : return 1;
891 : : }
892 : : return 0;
893 : : }
|