Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Cavium, Inc
3 : : */
4 : :
5 : : #include <eal_export.h>
6 : : #include <rte_alarm.h>
7 : : #include <bus_pci_driver.h>
8 : : #include <rte_cryptodev.h>
9 : : #include <cryptodev_pmd.h>
10 : : #include <rte_eventdev.h>
11 : : #include <rte_event_crypto_adapter.h>
12 : : #include <rte_errno.h>
13 : : #include <rte_malloc.h>
14 : : #include <rte_mempool.h>
15 : : #include <rte_memory.h>
16 : :
17 : : #include "otx_cryptodev.h"
18 : : #include "otx_cryptodev_capabilities.h"
19 : : #include "otx_cryptodev_hw_access.h"
20 : : #include "otx_cryptodev_mbox.h"
21 : : #include "otx_cryptodev_ops.h"
22 : :
23 : : #include "cpt_pmd_logs.h"
24 : : #include "cpt_pmd_ops_helper.h"
25 : : #include "cpt_ucode.h"
26 : : #include "cpt_ucode_asym.h"
27 : :
28 : : #include "ssovf_worker.h"
29 : :
30 : : static uint64_t otx_fpm_iova[CPT_EC_ID_PMAX];
31 : :
32 : : /* Forward declarations */
33 : :
34 : : static int
35 : : otx_cpt_que_pair_release(struct rte_cryptodev *dev, uint16_t que_pair_id);
36 : :
37 : : /* Alarm routines */
38 : :
39 : : static void
40 : 0 : otx_cpt_alarm_cb(void *arg)
41 : : {
42 : : struct cpt_vf *cptvf = arg;
43 : 0 : otx_cpt_poll_misc(cptvf);
44 : 0 : rte_eal_alarm_set(CPT_INTR_POLL_INTERVAL_MS * 1000,
45 : : otx_cpt_alarm_cb, cptvf);
46 : 0 : }
47 : :
48 : : static int
49 : : otx_cpt_periodic_alarm_start(void *arg)
50 : : {
51 : 0 : return rte_eal_alarm_set(CPT_INTR_POLL_INTERVAL_MS * 1000,
52 : : otx_cpt_alarm_cb, arg);
53 : : }
54 : :
55 : : static int
56 : : otx_cpt_periodic_alarm_stop(void *arg)
57 : : {
58 : 0 : return rte_eal_alarm_cancel(otx_cpt_alarm_cb, arg);
59 : : }
60 : :
61 : : /* PMD ops */
62 : :
63 : : static int
64 : 0 : otx_cpt_dev_config(struct rte_cryptodev *dev,
65 : : struct rte_cryptodev_config *config __rte_unused)
66 : : {
67 : : int ret = 0;
68 : :
69 : 0 : CPT_PMD_INIT_FUNC_TRACE();
70 : :
71 [ # # ]: 0 : if (dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
72 : : /* Initialize shared FPM table */
73 : 0 : ret = cpt_fpm_init(otx_fpm_iova);
74 : :
75 : 0 : return ret;
76 : : }
77 : :
78 : : static int
79 : 0 : otx_cpt_dev_start(struct rte_cryptodev *c_dev)
80 : : {
81 : 0 : void *cptvf = c_dev->data->dev_private;
82 : :
83 : 0 : CPT_PMD_INIT_FUNC_TRACE();
84 : :
85 : 0 : return otx_cpt_start_device(cptvf);
86 : : }
87 : :
88 : : static void
89 : 0 : otx_cpt_dev_stop(struct rte_cryptodev *c_dev)
90 : : {
91 : 0 : void *cptvf = c_dev->data->dev_private;
92 : :
93 : 0 : CPT_PMD_INIT_FUNC_TRACE();
94 : :
95 [ # # ]: 0 : if (c_dev->feature_flags & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO)
96 : 0 : cpt_fpm_clear();
97 : :
98 : 0 : otx_cpt_stop_device(cptvf);
99 : 0 : }
100 : :
101 : : static int
102 : 0 : otx_cpt_dev_close(struct rte_cryptodev *c_dev)
103 : : {
104 : 0 : void *cptvf = c_dev->data->dev_private;
105 : : int i, ret;
106 : :
107 : 0 : CPT_PMD_INIT_FUNC_TRACE();
108 : :
109 [ # # ]: 0 : for (i = 0; i < c_dev->data->nb_queue_pairs; i++) {
110 : 0 : ret = otx_cpt_que_pair_release(c_dev, i);
111 [ # # ]: 0 : if (ret)
112 : 0 : return ret;
113 : : }
114 : :
115 : : otx_cpt_periodic_alarm_stop(cptvf);
116 : 0 : otx_cpt_deinit_device(cptvf);
117 : :
118 : 0 : return 0;
119 : : }
120 : :
121 : : static void
122 : 0 : otx_cpt_dev_info_get(struct rte_cryptodev *dev, struct rte_cryptodev_info *info)
123 : : {
124 : 0 : CPT_PMD_INIT_FUNC_TRACE();
125 [ # # ]: 0 : if (info != NULL) {
126 : 0 : info->max_nb_queue_pairs = CPT_NUM_QS_PER_VF;
127 : 0 : info->feature_flags = dev->feature_flags;
128 : 0 : info->capabilities = otx_get_capabilities(info->feature_flags);
129 : 0 : info->sym.max_nb_sessions = 0;
130 : 0 : info->driver_id = otx_cryptodev_driver_id;
131 : 0 : info->min_mbuf_headroom_req = OTX_CPT_MIN_HEADROOM_REQ;
132 : 0 : info->min_mbuf_tailroom_req = OTX_CPT_MIN_TAILROOM_REQ;
133 : : }
134 : 0 : }
135 : :
136 : : static int
137 : 0 : otx_cpt_que_pair_setup(struct rte_cryptodev *dev,
138 : : uint16_t que_pair_id,
139 : : const struct rte_cryptodev_qp_conf *qp_conf,
140 : : int socket_id __rte_unused)
141 : : {
142 : 0 : struct cpt_instance *instance = NULL;
143 : : struct rte_pci_device *pci_dev;
144 : : int ret = -1;
145 : :
146 : 0 : CPT_PMD_INIT_FUNC_TRACE();
147 : :
148 [ # # ]: 0 : if (dev->data->queue_pairs[que_pair_id] != NULL) {
149 : 0 : ret = otx_cpt_que_pair_release(dev, que_pair_id);
150 [ # # ]: 0 : if (ret)
151 : : return ret;
152 : : }
153 : :
154 [ # # ]: 0 : if (qp_conf->nb_descriptors > DEFAULT_CMD_QLEN) {
155 : 0 : CPT_LOG_INFO("Number of descriptors too big %d, using default "
156 : : "queue length of %d", qp_conf->nb_descriptors,
157 : : DEFAULT_CMD_QLEN);
158 : : }
159 : :
160 : 0 : pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
161 : :
162 [ # # ]: 0 : if (pci_dev->mem_resource[0].addr == NULL) {
163 : 0 : CPT_LOG_ERR("PCI mem address null");
164 : 0 : return -EIO;
165 : : }
166 : :
167 : 0 : ret = otx_cpt_get_resource(dev, 0, &instance, que_pair_id);
168 [ # # # # ]: 0 : if (ret != 0 || instance == NULL) {
169 : 0 : CPT_LOG_ERR("Error getting instance handle from device %s : "
170 : : "ret = %d", dev->data->name, ret);
171 : 0 : return ret;
172 : : }
173 : :
174 : 0 : instance->queue_id = que_pair_id;
175 : 0 : instance->sess_mp = qp_conf->mp_session;
176 : 0 : dev->data->queue_pairs[que_pair_id] = instance;
177 : :
178 : 0 : return 0;
179 : : }
180 : :
181 : : static int
182 : 0 : otx_cpt_que_pair_release(struct rte_cryptodev *dev, uint16_t que_pair_id)
183 : : {
184 : 0 : struct cpt_instance *instance = dev->data->queue_pairs[que_pair_id];
185 : : int ret;
186 : :
187 : 0 : CPT_PMD_INIT_FUNC_TRACE();
188 : :
189 : 0 : ret = otx_cpt_put_resource(instance);
190 [ # # ]: 0 : if (ret != 0) {
191 : 0 : CPT_LOG_ERR("Error putting instance handle of device %s : "
192 : : "ret = %d", dev->data->name, ret);
193 : 0 : return ret;
194 : : }
195 : :
196 : 0 : dev->data->queue_pairs[que_pair_id] = NULL;
197 : :
198 : 0 : return 0;
199 : : }
200 : :
201 : : static unsigned int
202 : 0 : otx_cpt_get_session_size(struct rte_cryptodev *dev __rte_unused)
203 : : {
204 : 0 : return cpt_get_session_size();
205 : : }
206 : :
207 : : static int
208 : 0 : sym_xform_verify(struct rte_crypto_sym_xform *xform)
209 : : {
210 [ # # ]: 0 : if (xform->next) {
211 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
212 [ # # ]: 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
213 [ # # ]: 0 : xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
214 [ # # ]: 0 : (xform->auth.algo != RTE_CRYPTO_AUTH_SHA1_HMAC ||
215 [ # # ]: 0 : xform->next->cipher.algo != RTE_CRYPTO_CIPHER_AES_CBC))
216 : : return -ENOTSUP;
217 : :
218 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
219 [ # # ]: 0 : xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
220 [ # # ]: 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
221 [ # # ]: 0 : (xform->cipher.algo != RTE_CRYPTO_CIPHER_AES_CBC ||
222 [ # # ]: 0 : xform->next->auth.algo != RTE_CRYPTO_AUTH_SHA1_HMAC))
223 : : return -ENOTSUP;
224 : :
225 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
226 [ # # ]: 0 : xform->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC &&
227 [ # # ]: 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
228 [ # # ]: 0 : xform->next->auth.algo == RTE_CRYPTO_AUTH_SHA1)
229 : : return -ENOTSUP;
230 : :
231 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
232 [ # # ]: 0 : xform->auth.algo == RTE_CRYPTO_AUTH_SHA1 &&
233 [ # # ]: 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
234 [ # # ]: 0 : xform->next->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC)
235 : 0 : return -ENOTSUP;
236 : :
237 : : } else {
238 [ # # ]: 0 : if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
239 [ # # ]: 0 : xform->auth.algo == RTE_CRYPTO_AUTH_NULL &&
240 : : xform->auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
241 : 0 : return -ENOTSUP;
242 : : }
243 : : return 0;
244 : : }
245 : :
246 : : static int
247 : 0 : sym_session_configure(struct rte_crypto_sym_xform *xform,
248 : : struct rte_cryptodev_sym_session *sess)
249 : : {
250 : : struct rte_crypto_sym_xform *temp_xform = xform;
251 : : struct cpt_sess_misc *misc;
252 : : vq_cmd_word3_t vq_cmd_w3;
253 : 0 : void *priv = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
254 : : int ret;
255 : :
256 : 0 : ret = sym_xform_verify(xform);
257 [ # # ]: 0 : if (unlikely(ret))
258 : : return ret;
259 : :
260 : : memset(priv, 0, sizeof(struct cpt_sess_misc) +
261 : : offsetof(struct cpt_ctx, mc_ctx));
262 : :
263 : : misc = priv;
264 : :
265 [ # # ]: 0 : for ( ; xform != NULL; xform = xform->next) {
266 [ # # # # ]: 0 : switch (xform->type) {
267 : : case RTE_CRYPTO_SYM_XFORM_AEAD:
268 : : ret = fill_sess_aead(xform, misc);
269 : : break;
270 : : case RTE_CRYPTO_SYM_XFORM_CIPHER:
271 : : ret = fill_sess_cipher(xform, misc);
272 : : break;
273 : 0 : case RTE_CRYPTO_SYM_XFORM_AUTH:
274 [ # # ]: 0 : if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC)
275 : : ret = fill_sess_gmac(xform, misc);
276 : : else
277 : : ret = fill_sess_auth(xform, misc);
278 : : break;
279 : : default:
280 : : ret = -1;
281 : : }
282 : :
283 : : if (ret)
284 : 0 : goto priv_put;
285 : : }
286 : :
287 [ # # ]: 0 : if ((GET_SESS_FC_TYPE(misc) == HASH_HMAC) &&
288 : : cpt_mac_len_verify(&temp_xform->auth)) {
289 : 0 : CPT_LOG_ERR("MAC length is not supported");
290 : : struct cpt_ctx *ctx = SESS_PRIV(misc);
291 [ # # ]: 0 : if (ctx->auth_key != NULL) {
292 : 0 : rte_free(ctx->auth_key);
293 : 0 : ctx->auth_key = NULL;
294 : : }
295 : : ret = -ENOTSUP;
296 : 0 : goto priv_put;
297 : : }
298 : :
299 : 0 : misc->ctx_dma_addr = CRYPTODEV_GET_SYM_SESS_PRIV_IOVA(sess) +
300 : : sizeof(struct cpt_sess_misc);
301 : :
302 : 0 : vq_cmd_w3.u64 = 0;
303 : : vq_cmd_w3.s.grp = 0;
304 : 0 : vq_cmd_w3.s.cptr = misc->ctx_dma_addr + offsetof(struct cpt_ctx,
305 : : mc_ctx);
306 : :
307 : 0 : misc->cpt_inst_w7 = vq_cmd_w3.u64;
308 : :
309 : 0 : return 0;
310 : :
311 : : priv_put:
312 : : return -ENOTSUP;
313 : : }
314 : :
315 : : static void
316 : : sym_session_clear(struct rte_cryptodev_sym_session *sess)
317 : : {
318 : : void *priv = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
319 : : struct cpt_sess_misc *misc;
320 : : struct cpt_ctx *ctx;
321 : :
322 : : if (priv == NULL)
323 : : return;
324 : :
325 : : misc = priv;
326 : : ctx = SESS_PRIV(misc);
327 : :
328 : 0 : rte_free(ctx->auth_key);
329 : : }
330 : :
331 : : static int
332 : 0 : otx_cpt_session_cfg(struct rte_cryptodev *dev __rte_unused,
333 : : struct rte_crypto_sym_xform *xform,
334 : : struct rte_cryptodev_sym_session *sess)
335 : : {
336 : 0 : CPT_PMD_INIT_FUNC_TRACE();
337 : :
338 : 0 : return sym_session_configure(xform, sess);
339 : : }
340 : :
341 : :
342 : : static void
343 : 0 : otx_cpt_session_clear(struct rte_cryptodev *dev __rte_unused,
344 : : struct rte_cryptodev_sym_session *sess)
345 : : {
346 : 0 : CPT_PMD_INIT_FUNC_TRACE();
347 : :
348 : 0 : return sym_session_clear(sess);
349 : : }
350 : :
351 : : static unsigned int
352 : 0 : otx_cpt_asym_session_size_get(struct rte_cryptodev *dev __rte_unused)
353 : : {
354 : 0 : return sizeof(struct cpt_asym_sess_misc);
355 : : }
356 : :
357 : : static int
358 : 0 : otx_cpt_asym_session_cfg(struct rte_cryptodev *dev __rte_unused,
359 : : struct rte_crypto_asym_xform *xform __rte_unused,
360 : : struct rte_cryptodev_asym_session *sess)
361 : : {
362 : : struct cpt_asym_sess_misc *priv = (struct cpt_asym_sess_misc *)
363 : : sess->sess_private_data;
364 : : int ret;
365 : :
366 : 0 : CPT_PMD_INIT_FUNC_TRACE();
367 : :
368 : : ret = cpt_fill_asym_session_parameters(priv, xform);
369 : : if (ret) {
370 : 0 : CPT_LOG_ERR("Could not configure session parameters");
371 : 0 : return ret;
372 : : }
373 : :
374 : 0 : priv->cpt_inst_w7 = 0;
375 : :
376 : 0 : return 0;
377 : : }
378 : :
379 : : static void
380 : 0 : otx_cpt_asym_session_clear(struct rte_cryptodev *dev,
381 : : struct rte_cryptodev_asym_session *sess)
382 : : {
383 : : struct cpt_asym_sess_misc *priv;
384 : :
385 : 0 : CPT_PMD_INIT_FUNC_TRACE();
386 : :
387 [ # # # # ]: 0 : priv = (struct cpt_asym_sess_misc *) sess->sess_private_data;
388 : :
389 : : if (priv == NULL)
390 : : return;
391 : :
392 : : /* Free resources allocated during session configure */
393 : : cpt_free_asym_session_parameters(priv);
394 : : memset(priv, 0, otx_cpt_asym_session_size_get(dev));
395 : : }
396 : :
397 : : static __rte_always_inline void * __rte_hot
398 : : otx_cpt_request_enqueue(struct cpt_instance *instance,
399 : : void *req, uint64_t cpt_inst_w7)
400 : : {
401 : : struct cpt_request_info *user_req = (struct cpt_request_info *)req;
402 : :
403 : : fill_cpt_inst(instance, req, cpt_inst_w7);
404 : :
405 : : CPT_LOG_DP_DEBUG("req: %p op: %p ", req, user_req->op);
406 : :
407 : : /* Fill time_out cycles */
408 : 0 : user_req->time_out = rte_get_timer_cycles() +
409 : 0 : DEFAULT_COMMAND_TIMEOUT * rte_get_timer_hz();
410 [ # # # # : 0 : user_req->extra_time = 0;
# # # # #
# # # ]
411 : :
412 : : /* Default mode of software queue */
413 : : mark_cpt_inst(instance);
414 : :
415 : : CPT_LOG_DP_DEBUG("Submitted NB cmd with request: %p "
416 : : "op: %p", user_req, user_req->op);
417 : : return req;
418 : : }
419 : :
420 : : static __rte_always_inline void * __rte_hot
421 : : otx_cpt_enq_single_asym(struct cpt_instance *instance,
422 : : struct rte_crypto_op *op)
423 : : {
424 : : struct cpt_qp_meta_info *minfo = &instance->meta_info;
425 : : struct rte_crypto_asym_op *asym_op = op->asym;
426 : : struct asym_op_params params = {0};
427 : : struct cpt_asym_sess_misc *sess;
428 : : uintptr_t *cop;
429 : : void *mdata;
430 : : void *req;
431 : : int ret;
432 : :
433 [ # # # # : 0 : if (unlikely(rte_mempool_get(minfo->pool, &mdata) < 0)) {
# # # # ]
434 : 0 : CPT_LOG_DP_ERR("Could not allocate meta buffer for request");
435 : 0 : rte_errno = ENOMEM;
436 : 0 : return NULL;
437 : : }
438 : :
439 : : sess = (struct cpt_asym_sess_misc *)
440 : 0 : asym_op->session->sess_private_data;
441 : :
442 : : /* Store phys_addr of the mdata to meta_buf */
443 : 0 : params.meta_buf = rte_mempool_virt2iova(mdata);
444 : :
445 : : cop = mdata;
446 : 0 : cop[0] = (uintptr_t)mdata;
447 : 0 : cop[1] = (uintptr_t)op;
448 : 0 : cop[2] = cop[3] = 0ULL;
449 : :
450 : 0 : params.req = RTE_PTR_ADD(cop, 4 * sizeof(uintptr_t));
451 : 0 : params.req->op = cop;
452 : :
453 : : /* Adjust meta_buf by crypto_op data and request_info struct */
454 : 0 : params.meta_buf += (4 * sizeof(uintptr_t)) +
455 : : sizeof(struct cpt_request_info);
456 : :
457 [ # # # # : 0 : switch (sess->xfrm_type) {
# # # # #
# ]
458 [ # # # # ]: 0 : case RTE_CRYPTO_ASYM_XFORM_MODEX:
459 : : ret = cpt_modex_prep(¶ms, &sess->mod_ctx);
460 [ # # # # ]: 0 : if (unlikely(ret))
461 : 0 : goto req_fail;
462 : : break;
463 : : case RTE_CRYPTO_ASYM_XFORM_RSA:
464 : : ret = cpt_enqueue_rsa_op(op, ¶ms, sess);
465 [ # # # # ]: 0 : if (unlikely(ret))
466 : 0 : goto req_fail;
467 : : break;
468 : : case RTE_CRYPTO_ASYM_XFORM_ECDSA:
469 : : ret = cpt_enqueue_ecdsa_op(op, ¶ms, sess, otx_fpm_iova);
470 [ # # # # ]: 0 : if (unlikely(ret))
471 : 0 : goto req_fail;
472 : : break;
473 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECPM:
474 : 0 : ret = cpt_ecpm_prep(&asym_op->ecpm, ¶ms,
475 : 0 : sess->ec_ctx.curveid);
476 : : if (unlikely(ret))
477 : : goto req_fail;
478 : : break;
479 : :
480 : 0 : default:
481 : 0 : op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
482 : 0 : rte_errno = EINVAL;
483 : 0 : goto req_fail;
484 : : }
485 : :
486 : 0 : req = otx_cpt_request_enqueue(instance, params.req, sess->cpt_inst_w7);
487 : : if (unlikely(req == NULL)) {
488 : : CPT_LOG_DP_ERR("Could not enqueue crypto req");
489 : : goto req_fail;
490 : : }
491 : :
492 : : return req;
493 : :
494 : 0 : req_fail:
495 [ # # # # ]: 0 : free_op_meta(mdata, minfo->pool);
496 : :
497 : : return NULL;
498 : : }
499 : :
500 : : static __rte_always_inline void * __rte_hot
501 : : otx_cpt_enq_single_sym(struct cpt_instance *instance,
502 : : struct rte_crypto_op *op)
503 : : {
504 : : struct cpt_sess_misc *sess;
505 : : struct rte_crypto_sym_op *sym_op = op->sym;
506 : : struct cpt_request_info *prep_req;
507 : : void *mdata = NULL;
508 : : int ret = 0;
509 : : void *req;
510 : : uint64_t cpt_op;
511 : :
512 : 0 : sess = CRYPTODEV_GET_SYM_SESS_PRIV(sym_op->session);
513 : 0 : cpt_op = sess->cpt_op;
514 : :
515 [ # # # # ]: 0 : if (likely(cpt_op & CPT_OP_CIPHER_MASK))
516 : : ret = fill_fc_params(op, sess, &instance->meta_info, &mdata,
517 : : (void **)&prep_req);
518 : : else
519 : : ret = fill_digest_params(op, sess, &instance->meta_info,
520 : : &mdata, (void **)&prep_req);
521 : :
522 [ # # # # : 0 : if (unlikely(ret)) {
# # # # ]
523 : 0 : CPT_LOG_DP_ERR("prep crypto req : op %p, cpt_op 0x%x "
524 : : "ret 0x%x", op, (unsigned int)cpt_op, ret);
525 : 0 : return NULL;
526 : : }
527 : :
528 : : /* Enqueue prepared instruction to h/w */
529 : 0 : req = otx_cpt_request_enqueue(instance, prep_req, sess->cpt_inst_w7);
530 : : if (unlikely(req == NULL))
531 : : /* Buffer allocated for request preparation need to be freed */
532 : : free_op_meta(mdata, instance->meta_info.pool);
533 : :
534 : : return req;
535 : : }
536 : :
537 : : static __rte_always_inline void * __rte_hot
538 : : otx_cpt_enq_single_sym_sessless(struct cpt_instance *instance,
539 : : struct rte_crypto_op *op)
540 : : {
541 : : struct rte_crypto_sym_op *sym_op = op->sym;
542 : : struct rte_cryptodev_sym_session *sess;
543 : : void *req;
544 : : int ret;
545 : :
546 : : /* Create temporary session */
547 [ # # # # : 0 : if (rte_mempool_get(instance->sess_mp, (void **)&sess) < 0) {
# # # # ]
548 : 0 : rte_errno = ENOMEM;
549 : 0 : return NULL;
550 : : }
551 : :
552 : 0 : ret = sym_session_configure(sym_op->xform, sess);
553 [ # # # # ]: 0 : if (ret)
554 : 0 : goto sess_put;
555 : :
556 [ # # # # ]: 0 : sym_op->session = sess;
557 : :
558 : : /* Enqueue op with the tmp session set */
559 : : req = otx_cpt_enq_single_sym(instance, op);
560 [ # # # # ]: 0 : if (unlikely(req == NULL))
561 : 0 : goto sess_put;
562 : :
563 : : return req;
564 : :
565 : 0 : sess_put:
566 [ # # # # ]: 0 : rte_mempool_put(instance->sess_mp, sess);
567 : 0 : return NULL;
568 : : }
569 : :
570 : : #define OP_TYPE_SYM 0
571 : : #define OP_TYPE_ASYM 1
572 : :
573 : : static __rte_always_inline void *__rte_hot
574 : : otx_cpt_enq_single(struct cpt_instance *inst,
575 : : struct rte_crypto_op *op,
576 : : const uint8_t op_type)
577 : : {
578 : : /* Check for the type */
579 : :
580 : 0 : if (op_type == OP_TYPE_SYM) {
581 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
582 : : return otx_cpt_enq_single_sym(inst, op);
583 : : else
584 : 0 : return otx_cpt_enq_single_sym_sessless(inst, op);
585 : : }
586 : :
587 : : if (op_type == OP_TYPE_ASYM) {
588 [ # # ]: 0 : if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
589 : 0 : return otx_cpt_enq_single_asym(inst, op);
590 : : }
591 : :
592 : : /* Should not reach here */
593 : 0 : rte_errno = ENOTSUP;
594 : 0 : return NULL;
595 : : }
596 : :
597 : : static __rte_always_inline uint16_t __rte_hot
598 : : otx_cpt_pkt_enqueue(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops,
599 : : const uint8_t op_type)
600 : : {
601 : : struct cpt_instance *instance = (struct cpt_instance *)qptr;
602 : : uint16_t count, free_slots;
603 : : void *req;
604 : : struct cpt_vf *cptvf = (struct cpt_vf *)instance;
605 : : struct pending_queue *pqueue = &cptvf->pqueue;
606 : :
607 : 0 : free_slots = pending_queue_free_slots(pqueue, DEFAULT_CMD_QLEN,
608 : : DEFAULT_CMD_QRSVD_SLOTS);
609 : : if (nb_ops > free_slots)
610 : : nb_ops = free_slots;
611 : :
612 : : count = 0;
613 [ # # # # ]: 0 : while (likely(count < nb_ops)) {
614 : :
615 : : /* Enqueue single op */
616 [ # # # # ]: 0 : req = otx_cpt_enq_single(instance, ops[count], op_type);
617 : :
618 [ # # # # ]: 0 : if (unlikely(req == NULL))
619 : : break;
620 : :
621 : 0 : pending_queue_push(pqueue, req, count, DEFAULT_CMD_QLEN);
622 : 0 : count++;
623 : : }
624 : :
625 [ # # # # ]: 0 : if (likely(count)) {
626 : 0 : pending_queue_commit(pqueue, count, DEFAULT_CMD_QLEN);
627 : : otx_cpt_ring_dbell(instance, count);
628 : : }
629 : : return count;
630 : : }
631 : :
632 : : static uint16_t
633 [ # # ]: 0 : otx_cpt_enqueue_asym(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
634 : : {
635 : 0 : return otx_cpt_pkt_enqueue(qptr, ops, nb_ops, OP_TYPE_ASYM);
636 : : }
637 : :
638 : : static uint16_t
639 [ # # ]: 0 : otx_cpt_enqueue_sym(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
640 : : {
641 : 0 : return otx_cpt_pkt_enqueue(qptr, ops, nb_ops, OP_TYPE_SYM);
642 : : }
643 : :
644 : : static __rte_always_inline void
645 : : submit_request_to_sso(struct ssows *ws, uintptr_t req,
646 : : struct rte_event *rsp_info)
647 : : {
648 : : uint64_t add_work;
649 : :
650 : 0 : add_work = rsp_info->flow_id | (RTE_EVENT_TYPE_CRYPTODEV << 28) |
651 : 0 : (rsp_info->sub_event_type << 20) |
652 : 0 : ((uint64_t)(rsp_info->sched_type) << 32);
653 : :
654 : 0 : if (!rsp_info->sched_type)
655 : : ssows_head_wait(ws);
656 : :
657 : : rte_atomic_thread_fence(rte_memory_order_release);
658 : 0 : ssovf_store_pair(add_work, req, ws->grps[rsp_info->queue_id]);
659 : : }
660 : :
661 : : RTE_EXPORT_INTERNAL_SYMBOL(otx_crypto_adapter_enqueue)
662 : : uint16_t __rte_hot
663 : 0 : otx_crypto_adapter_enqueue(void *port, struct rte_crypto_op *op)
664 : : {
665 : : union rte_event_crypto_metadata *ec_mdata;
666 : : struct cpt_instance *instance;
667 : : struct cpt_request_info *req;
668 : : struct rte_event *rsp_info;
669 : : uint8_t op_type, cdev_id;
670 : : uint16_t qp_id;
671 : :
672 : 0 : ec_mdata = rte_cryptodev_session_event_mdata_get(op);
673 [ # # ]: 0 : if (unlikely(ec_mdata == NULL)) {
674 : 0 : rte_errno = EINVAL;
675 : 0 : return 0;
676 : : }
677 : :
678 : 0 : cdev_id = ec_mdata->request_info.cdev_id;
679 : 0 : qp_id = ec_mdata->request_info.queue_pair_id;
680 : : rsp_info = &ec_mdata->response_info;
681 : 0 : instance = rte_cryptodevs[cdev_id].data->queue_pairs[qp_id];
682 : :
683 [ # # ]: 0 : if (unlikely(!instance->ca_enabled)) {
684 : 0 : rte_errno = EINVAL;
685 : 0 : return 0;
686 : : }
687 : :
688 [ # # ]: 0 : op_type = op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC ? OP_TYPE_SYM :
689 : : OP_TYPE_ASYM;
690 : : req = otx_cpt_enq_single(instance, op, op_type);
691 [ # # ]: 0 : if (unlikely(req == NULL))
692 : : return 0;
693 : :
694 : : otx_cpt_ring_dbell(instance, 1);
695 : 0 : req->qp = instance;
696 [ # # ]: 0 : submit_request_to_sso(port, (uintptr_t)req, rsp_info);
697 : :
698 : 0 : return 1;
699 : : }
700 : :
701 : : static inline void
702 : 0 : otx_cpt_asym_rsa_op(struct rte_crypto_op *cop, struct cpt_request_info *req,
703 : : struct rte_crypto_rsa_xform *rsa_ctx)
704 : :
705 : : {
706 : : struct rte_crypto_rsa_op_param *rsa = &cop->asym->rsa;
707 : :
708 [ # # # # : 0 : switch (rsa->op_type) {
# ]
709 : 0 : case RTE_CRYPTO_ASYM_OP_ENCRYPT:
710 : 0 : rsa->cipher.length = rsa_ctx->n.length;
711 : 0 : memcpy(rsa->cipher.data, req->rptr, rsa->cipher.length);
712 : : break;
713 : 0 : case RTE_CRYPTO_ASYM_OP_DECRYPT:
714 [ # # ]: 0 : if (rsa_ctx->padding.type == RTE_CRYPTO_RSA_PADDING_NONE)
715 : 0 : rsa->message.length = rsa_ctx->n.length;
716 : : else {
717 : : /* Get length of decrypted output */
718 [ # # ]: 0 : rsa->message.length = rte_cpu_to_be_16
719 : : (*((uint16_t *)req->rptr));
720 : :
721 : : /* Offset data pointer by length fields */
722 : 0 : req->rptr += 2;
723 : : }
724 : 0 : memcpy(rsa->message.data, req->rptr, rsa->message.length);
725 : : break;
726 : 0 : case RTE_CRYPTO_ASYM_OP_SIGN:
727 : 0 : rsa->sign.length = rsa_ctx->n.length;
728 : 0 : memcpy(rsa->sign.data, req->rptr, rsa->sign.length);
729 : : break;
730 : 0 : case RTE_CRYPTO_ASYM_OP_VERIFY:
731 [ # # ]: 0 : if (rsa_ctx->padding.type == RTE_CRYPTO_RSA_PADDING_NONE)
732 : 0 : rsa->sign.length = rsa_ctx->n.length;
733 : : else {
734 : : /* Get length of decrypted output */
735 [ # # ]: 0 : rsa->sign.length = rte_cpu_to_be_16
736 : : (*((uint16_t *)req->rptr));
737 : :
738 : : /* Offset data pointer by length fields */
739 : 0 : req->rptr += 2;
740 : : }
741 : 0 : memcpy(rsa->sign.data, req->rptr, rsa->sign.length);
742 : :
743 [ # # ]: 0 : if (!rte_memeq_timingsafe(rsa->sign.data, rsa->message.data,
744 : : rsa->message.length)) {
745 : 0 : CPT_LOG_DP_ERR("RSA verification failed");
746 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
747 : : }
748 : : break;
749 : 0 : default:
750 : : CPT_LOG_DP_DEBUG("Invalid RSA operation type");
751 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
752 : 0 : break;
753 : : }
754 : 0 : }
755 : :
756 : : static __rte_always_inline void
757 : : otx_cpt_asym_dequeue_ecdsa_op(struct rte_crypto_ecdsa_op_param *ecdsa,
758 : : struct cpt_request_info *req,
759 : : struct cpt_asym_ec_ctx *ec)
760 : :
761 : : {
762 : 0 : int prime_len = ec_grp[ec->curveid].prime.length;
763 : :
764 : 0 : if (ecdsa->op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
765 : : return;
766 : :
767 : : /* Separate out sign r and s components */
768 : 0 : memcpy(ecdsa->r.data, req->rptr, prime_len);
769 : 0 : memcpy(ecdsa->s.data, req->rptr + RTE_ALIGN_CEIL(prime_len, 8),
770 : : prime_len);
771 : 0 : ecdsa->r.length = prime_len;
772 : 0 : ecdsa->s.length = prime_len;
773 : : }
774 : :
775 : : static __rte_always_inline void
776 : : otx_cpt_asym_dequeue_ecpm_op(struct rte_crypto_ecpm_op_param *ecpm,
777 : : struct cpt_request_info *req,
778 : : struct cpt_asym_ec_ctx *ec)
779 : : {
780 : 0 : int prime_len = ec_grp[ec->curveid].prime.length;
781 : :
782 : 0 : memcpy(ecpm->r.x.data, req->rptr, prime_len);
783 : 0 : memcpy(ecpm->r.y.data, req->rptr + RTE_ALIGN_CEIL(prime_len, 8),
784 : : prime_len);
785 : 0 : ecpm->r.x.length = prime_len;
786 : 0 : ecpm->r.y.length = prime_len;
787 : 0 : }
788 : :
789 : : static __rte_always_inline void __rte_hot
790 : : otx_cpt_asym_post_process(struct rte_crypto_op *cop,
791 : : struct cpt_request_info *req)
792 : : {
793 : : struct rte_crypto_asym_op *op = cop->asym;
794 : : struct cpt_asym_sess_misc *sess;
795 : :
796 : 0 : sess = (struct cpt_asym_sess_misc *) op->session->sess_private_data;
797 : :
798 : 0 : switch (sess->xfrm_type) {
799 : 0 : case RTE_CRYPTO_ASYM_XFORM_RSA:
800 : 0 : otx_cpt_asym_rsa_op(cop, req, &sess->rsa_ctx);
801 : 0 : break;
802 : 0 : case RTE_CRYPTO_ASYM_XFORM_MODEX:
803 : 0 : op->modex.result.length = sess->mod_ctx.modulus.length;
804 : 0 : memcpy(op->modex.result.data, req->rptr,
805 : : op->modex.result.length);
806 : : break;
807 [ # # # # ]: 0 : case RTE_CRYPTO_ASYM_XFORM_ECDSA:
808 : : otx_cpt_asym_dequeue_ecdsa_op(&op->ecdsa, req, &sess->ec_ctx);
809 : : break;
810 : 0 : case RTE_CRYPTO_ASYM_XFORM_ECPM:
811 : : otx_cpt_asym_dequeue_ecpm_op(&op->ecpm, req, &sess->ec_ctx);
812 : : break;
813 : 0 : default:
814 : : CPT_LOG_DP_DEBUG("Invalid crypto xform type");
815 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
816 : 0 : break;
817 : : }
818 : : }
819 : :
820 : : static __rte_always_inline void __rte_hot
821 : : otx_cpt_dequeue_post_process(struct rte_crypto_op *cop, uintptr_t *rsp,
822 : : const uint8_t op_type)
823 : : {
824 : : /* H/w has returned success */
825 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
826 : :
827 : : /* Perform further post processing */
828 : :
829 [ # # ]: 0 : if ((op_type == OP_TYPE_SYM) &&
830 [ # # # # ]: 0 : (cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC)) {
831 : : /* Check if auth verify need to be completed */
832 [ # # # # ]: 0 : if (unlikely(rsp[2]))
833 [ # # # # ]: 0 : compl_auth_verify(cop, (uint8_t *)rsp[2], rsp[3]);
834 : : return;
835 : : }
836 : :
837 [ # # ]: 0 : if ((op_type == OP_TYPE_ASYM) &&
838 [ # # # # ]: 0 : (cop->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC)) {
839 [ # # # # : 0 : rsp = RTE_PTR_ADD(rsp, 4 * sizeof(uintptr_t));
# # # # #
# ]
840 : : otx_cpt_asym_post_process(cop, (struct cpt_request_info *)rsp);
841 : : }
842 : :
843 : : return;
844 : : }
845 : :
846 : : static inline void
847 : 0 : free_sym_session_data(const struct cpt_instance *instance,
848 : : struct rte_crypto_op *cop)
849 : : {
850 [ # # ]: 0 : void *sess_private_data_t = CRYPTODEV_GET_SYM_SESS_PRIV(cop->sym->session);
851 : :
852 : : memset(sess_private_data_t, 0, cpt_get_session_size());
853 [ # # ]: 0 : rte_mempool_put(instance->sess_mp, cop->sym->session);
854 : 0 : cop->sym->session = NULL;
855 : 0 : }
856 : :
857 : : static __rte_always_inline struct rte_crypto_op *
858 : : otx_cpt_process_response(const struct cpt_instance *instance, uintptr_t *rsp,
859 : : uint8_t cc, const uint8_t op_type)
860 : : {
861 : : struct rte_crypto_op *cop;
862 : : void *metabuf;
863 : :
864 : 0 : metabuf = (void *)rsp[0];
865 : 0 : cop = (void *)rsp[1];
866 : :
867 : : /* Check completion code */
868 : 0 : if (likely(cc == 0)) {
869 : : /* H/w success pkt. Post process */
870 : : otx_cpt_dequeue_post_process(cop, rsp, op_type);
871 [ # # # # : 0 : } else if (cc == ERR_GC_ICV_MISCOMPARE) {
# # ]
872 : : /* auth data mismatch */
873 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
874 : : } else {
875 : : /* Error */
876 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
877 : : }
878 : :
879 [ # # # # : 0 : if (unlikely(cop->sess_type == RTE_CRYPTO_OP_SESSIONLESS))
# # ]
880 : 0 : free_sym_session_data(instance, cop);
881 [ # # # # : 0 : free_op_meta(metabuf, instance->meta_info.pool);
# # ]
882 : :
883 : : return cop;
884 : : }
885 : :
886 : : static __rte_always_inline uint16_t __rte_hot
887 : : otx_cpt_pkt_dequeue(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops,
888 : : const uint8_t op_type)
889 : 0 : {
890 : : struct cpt_instance *instance = (struct cpt_instance *)qptr;
891 : : struct cpt_request_info *user_req;
892 : : struct cpt_vf *cptvf = (struct cpt_vf *)instance;
893 : 0 : uint8_t cc[nb_ops];
894 : : int i, count, pcount;
895 : : uint8_t ret;
896 : : int nb_completed;
897 : : struct pending_queue *pqueue = &cptvf->pqueue;
898 : :
899 : 0 : pcount = pending_queue_level(pqueue, DEFAULT_CMD_QLEN);
900 : :
901 : : /* Ensure pcount isn't read before data lands */
902 : : rte_atomic_thread_fence(rte_memory_order_acquire);
903 : :
904 : 0 : count = (nb_ops > pcount) ? pcount : nb_ops;
905 : :
906 [ # # # # ]: 0 : for (i = 0; i < count; i++) {
907 : 0 : pending_queue_peek(pqueue, (void **) &user_req,
908 [ # # # # ]: 0 : DEFAULT_CMD_QLEN, i + 1 < count);
909 : :
910 : : ret = check_nb_command_id(user_req, instance);
911 : :
912 [ # # # # ]: 0 : if (unlikely(ret == ERR_REQ_PENDING)) {
913 : : /* Stop checking for completions */
914 : : break;
915 : : }
916 : :
917 : : /* Return completion code and op handle */
918 : 0 : cc[i] = ret;
919 : 0 : ops[i] = user_req->op;
920 : :
921 : : CPT_LOG_DP_DEBUG("Request %p Op %p completed with code %d",
922 : : user_req, user_req->op, ret);
923 : :
924 : : pending_queue_pop(pqueue, DEFAULT_CMD_QLEN);
925 : : }
926 : :
927 : : nb_completed = i;
928 : :
929 [ # # # # ]: 0 : for (i = 0; i < nb_completed; i++) {
930 [ # # # # ]: 0 : if (likely((i + 1) < nb_completed))
931 : 0 : rte_prefetch0(ops[i+1]);
932 : :
933 : 0 : ops[i] = otx_cpt_process_response(instance, (void *)ops[i],
934 [ # # # # ]: 0 : cc[i], op_type);
935 : : }
936 : :
937 : 0 : return nb_completed;
938 : : }
939 : :
940 : : static uint16_t
941 : 0 : otx_cpt_dequeue_asym(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
942 : : {
943 : 0 : return otx_cpt_pkt_dequeue(qptr, ops, nb_ops, OP_TYPE_ASYM);
944 : : }
945 : :
946 : : static uint16_t
947 : 0 : otx_cpt_dequeue_sym(void *qptr, struct rte_crypto_op **ops, uint16_t nb_ops)
948 : : {
949 : 0 : return otx_cpt_pkt_dequeue(qptr, ops, nb_ops, OP_TYPE_SYM);
950 : : }
951 : :
952 : : RTE_EXPORT_INTERNAL_SYMBOL(otx_crypto_adapter_dequeue)
953 : : uintptr_t __rte_hot
954 : 0 : otx_crypto_adapter_dequeue(uintptr_t get_work1)
955 : : {
956 : : const struct cpt_instance *instance;
957 : : struct cpt_request_info *req;
958 : : struct rte_crypto_op *cop;
959 : : uint8_t cc, op_type;
960 : : uintptr_t *rsp;
961 : :
962 : 0 : req = (struct cpt_request_info *)get_work1;
963 : 0 : instance = req->qp;
964 : 0 : rsp = req->op;
965 : 0 : cop = (void *)rsp[1];
966 : 0 : op_type = cop->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC ? OP_TYPE_SYM :
967 : : OP_TYPE_ASYM;
968 : :
969 : : do {
970 : : cc = check_nb_command_id(
971 : : req, (struct cpt_instance *)(uintptr_t)instance);
972 [ # # ]: 0 : } while (cc == ERR_REQ_PENDING);
973 : :
974 [ # # ]: 0 : cop = otx_cpt_process_response(instance, (void *)req->op, cc, op_type);
975 : :
976 : 0 : return (uintptr_t)(cop);
977 : : }
978 : :
979 : : static struct rte_cryptodev_ops cptvf_ops = {
980 : : /* Device related operations */
981 : : .dev_configure = otx_cpt_dev_config,
982 : : .dev_start = otx_cpt_dev_start,
983 : : .dev_stop = otx_cpt_dev_stop,
984 : : .dev_close = otx_cpt_dev_close,
985 : : .dev_infos_get = otx_cpt_dev_info_get,
986 : :
987 : : .stats_get = NULL,
988 : : .stats_reset = NULL,
989 : : .queue_pair_setup = otx_cpt_que_pair_setup,
990 : : .queue_pair_release = otx_cpt_que_pair_release,
991 : :
992 : : /* Crypto related operations */
993 : : .sym_session_get_size = otx_cpt_get_session_size,
994 : : .sym_session_configure = otx_cpt_session_cfg,
995 : : .sym_session_clear = otx_cpt_session_clear,
996 : :
997 : : .asym_session_get_size = otx_cpt_asym_session_size_get,
998 : : .asym_session_configure = otx_cpt_asym_session_cfg,
999 : : .asym_session_clear = otx_cpt_asym_session_clear,
1000 : : };
1001 : :
1002 : : int
1003 : 0 : otx_cpt_dev_create(struct rte_cryptodev *c_dev)
1004 : : {
1005 : 0 : struct rte_pci_device *pdev = RTE_CLASS_TO_BUS_DEVICE(c_dev, *pdev);
1006 : : struct cpt_vf *cptvf = NULL;
1007 : : void *reg_base;
1008 : : char dev_name[32];
1009 : : int ret;
1010 : :
1011 [ # # ]: 0 : if (pdev->mem_resource[0].phys_addr == 0ULL)
1012 : : return -EIO;
1013 : :
1014 : : /* for secondary processes, we don't initialise any further as primary
1015 : : * has already done this work.
1016 : : */
1017 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1018 : : return 0;
1019 : :
1020 : 0 : cptvf = rte_zmalloc_socket("otx_cryptodev_private_mem",
1021 : : sizeof(struct cpt_vf), RTE_CACHE_LINE_SIZE,
1022 : 0 : rte_socket_id());
1023 : :
1024 [ # # ]: 0 : if (cptvf == NULL) {
1025 : 0 : CPT_LOG_ERR("Cannot allocate memory for device private data");
1026 : 0 : return -ENOMEM;
1027 : : }
1028 : :
1029 : 0 : snprintf(dev_name, 32, "%02x:%02x.%x",
1030 [ # # ]: 0 : pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
1031 : :
1032 : 0 : reg_base = pdev->mem_resource[0].addr;
1033 [ # # ]: 0 : if (!reg_base) {
1034 : 0 : CPT_LOG_ERR("Failed to map BAR0 of %s", dev_name);
1035 : : ret = -ENODEV;
1036 : 0 : goto fail;
1037 : : }
1038 : :
1039 : 0 : ret = otx_cpt_hw_init(cptvf, pdev, reg_base, dev_name);
1040 [ # # ]: 0 : if (ret) {
1041 : 0 : CPT_LOG_ERR("Failed to init cptvf %s", dev_name);
1042 : : ret = -EIO;
1043 : 0 : goto fail;
1044 : : }
1045 : :
1046 [ # # # ]: 0 : switch (cptvf->vftype) {
1047 : 0 : case OTX_CPT_VF_TYPE_AE:
1048 : : /* Set asymmetric cpt feature flags */
1049 : 0 : c_dev->feature_flags = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
1050 : : RTE_CRYPTODEV_FF_HW_ACCELERATED |
1051 : : RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT;
1052 : 0 : break;
1053 : 0 : case OTX_CPT_VF_TYPE_SE:
1054 : : /* Set symmetric cpt feature flags */
1055 : 0 : c_dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
1056 : : RTE_CRYPTODEV_FF_HW_ACCELERATED |
1057 : : RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
1058 : : RTE_CRYPTODEV_FF_IN_PLACE_SGL |
1059 : : RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
1060 : : RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
1061 : : RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT |
1062 : : RTE_CRYPTODEV_FF_SYM_SESSIONLESS |
1063 : : RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED;
1064 : 0 : break;
1065 : 0 : default:
1066 : : /* Feature not supported. Abort */
1067 : 0 : CPT_LOG_ERR("VF type not supported by %s", dev_name);
1068 : : ret = -EIO;
1069 : 0 : goto deinit_dev;
1070 : : }
1071 : :
1072 : : /* Start off timer for mailbox interrupts */
1073 : : otx_cpt_periodic_alarm_start(cptvf);
1074 : :
1075 : 0 : c_dev->dev_ops = &cptvf_ops;
1076 : :
1077 [ # # ]: 0 : if (c_dev->feature_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) {
1078 : 0 : c_dev->enqueue_burst = otx_cpt_enqueue_sym;
1079 : 0 : c_dev->dequeue_burst = otx_cpt_dequeue_sym;
1080 : : } else {
1081 : 0 : c_dev->enqueue_burst = otx_cpt_enqueue_asym;
1082 : 0 : c_dev->dequeue_burst = otx_cpt_dequeue_asym;
1083 : : }
1084 : :
1085 : : /* Save dev private data */
1086 : 0 : c_dev->data->dev_private = cptvf;
1087 : :
1088 : 0 : return 0;
1089 : :
1090 : : deinit_dev:
1091 : 0 : otx_cpt_deinit_device(cptvf);
1092 : :
1093 : 0 : fail:
1094 : : if (cptvf) {
1095 : : /* Free private data allocated */
1096 : 0 : rte_free(cptvf);
1097 : : }
1098 : :
1099 : 0 : return ret;
1100 : : }
|