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