1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
5 #include <rte_string_fns.h>
6 #include <rte_bus_pci.h>
7 #include <rte_bus_vdev.h>
8 #include <rte_common.h>
9 #include <rte_config.h>
10 #include <rte_cryptodev.h>
11 #include <rte_cryptodev_pmd.h>
14 #include <rte_malloc.h>
16 #include "ccp_crypto.h"
18 #include "ccp_pmd_private.h"
21 * Global static parameter used to find if CCP device is already initialized.
23 static unsigned int ccp_pmd_init_done
;
24 uint8_t ccp_cryptodev_driver_id
;
26 struct ccp_pmd_init_params
{
27 struct rte_cryptodev_pmd_init_params def_p
;
31 #define CCP_CRYPTODEV_PARAM_NAME ("name")
32 #define CCP_CRYPTODEV_PARAM_SOCKET_ID ("socket_id")
33 #define CCP_CRYPTODEV_PARAM_MAX_NB_QP ("max_nb_queue_pairs")
34 #define CCP_CRYPTODEV_PARAM_AUTH_OPT ("ccp_auth_opt")
36 const char *ccp_pmd_valid_params
[] = {
37 CCP_CRYPTODEV_PARAM_NAME
,
38 CCP_CRYPTODEV_PARAM_SOCKET_ID
,
39 CCP_CRYPTODEV_PARAM_MAX_NB_QP
,
40 CCP_CRYPTODEV_PARAM_AUTH_OPT
,
43 /** ccp pmd auth option */
44 enum ccp_pmd_auth_opt
{
45 CCP_PMD_AUTH_OPT_CCP
= 0,
49 /** parse integer from integer argument */
51 parse_integer_arg(const char *key __rte_unused
,
52 const char *value
, void *extra_args
)
54 int *i
= (int *) extra_args
;
58 CCP_LOG_ERR("Argument has to be positive.\n");
65 /** parse name argument */
67 parse_name_arg(const char *key __rte_unused
,
68 const char *value
, void *extra_args
)
70 struct rte_cryptodev_pmd_init_params
*params
= extra_args
;
72 if (strlen(value
) >= RTE_CRYPTODEV_NAME_MAX_LEN
- 1) {
73 CCP_LOG_ERR("Invalid name %s, should be less than "
75 RTE_CRYPTODEV_NAME_MAX_LEN
- 1);
79 strncpy(params
->name
, value
, RTE_CRYPTODEV_NAME_MAX_LEN
);
84 /** parse authentication operation option */
86 parse_auth_opt_arg(const char *key __rte_unused
,
87 const char *value
, void *extra_args
)
89 struct ccp_pmd_init_params
*params
= extra_args
;
93 if (i
< CCP_PMD_AUTH_OPT_CCP
|| i
> CCP_PMD_AUTH_OPT_CPU
) {
94 CCP_LOG_ERR("Invalid ccp pmd auth option. "
95 "0->auth on CCP(default), "
104 ccp_pmd_parse_input_args(struct ccp_pmd_init_params
*params
,
105 const char *input_args
)
107 struct rte_kvargs
*kvlist
= NULL
;
114 kvlist
= rte_kvargs_parse(input_args
,
115 ccp_pmd_valid_params
);
119 ret
= rte_kvargs_process(kvlist
,
120 CCP_CRYPTODEV_PARAM_MAX_NB_QP
,
122 ¶ms
->def_p
.max_nb_queue_pairs
);
126 ret
= rte_kvargs_process(kvlist
,
127 CCP_CRYPTODEV_PARAM_SOCKET_ID
,
129 ¶ms
->def_p
.socket_id
);
133 ret
= rte_kvargs_process(kvlist
,
134 CCP_CRYPTODEV_PARAM_NAME
,
140 ret
= rte_kvargs_process(kvlist
,
141 CCP_CRYPTODEV_PARAM_AUTH_OPT
,
150 rte_kvargs_free(kvlist
);
154 static struct ccp_session
*
155 get_ccp_session(struct ccp_qp
*qp
, struct rte_crypto_op
*op
)
157 struct ccp_session
*sess
= NULL
;
159 if (op
->sess_type
== RTE_CRYPTO_OP_WITH_SESSION
) {
160 if (unlikely(op
->sym
->session
== NULL
))
163 sess
= (struct ccp_session
*)
164 get_sym_session_private_data(
166 ccp_cryptodev_driver_id
);
167 } else if (op
->sess_type
== RTE_CRYPTO_OP_SESSIONLESS
) {
169 void *_sess_private_data
= NULL
;
170 struct ccp_private
*internals
;
172 if (rte_mempool_get(qp
->sess_mp
, &_sess
))
174 if (rte_mempool_get(qp
->sess_mp
, (void **)&_sess_private_data
))
177 sess
= (struct ccp_session
*)_sess_private_data
;
179 internals
= (struct ccp_private
*)qp
->dev
->data
->dev_private
;
180 if (unlikely(ccp_set_session_parameters(sess
, op
->sym
->xform
,
182 rte_mempool_put(qp
->sess_mp
, _sess
);
183 rte_mempool_put(qp
->sess_mp_priv
, _sess_private_data
);
186 op
->sym
->session
= (struct rte_cryptodev_sym_session
*)_sess
;
187 set_sym_session_private_data(op
->sym
->session
,
188 ccp_cryptodev_driver_id
,
196 ccp_pmd_enqueue_burst(void *queue_pair
, struct rte_crypto_op
**ops
,
199 struct ccp_session
*sess
= NULL
;
200 struct ccp_qp
*qp
= queue_pair
;
201 struct ccp_queue
*cmd_q
;
202 struct rte_cryptodev
*dev
= qp
->dev
;
203 uint16_t i
, enq_cnt
= 0, slots_req
= 0;
208 if (unlikely(rte_ring_full(qp
->processed_pkts
) != 0))
211 for (i
= 0; i
< nb_ops
; i
++) {
212 sess
= get_ccp_session(qp
, ops
[i
]);
213 if (unlikely(sess
== NULL
) && (i
== 0)) {
214 qp
->qp_stats
.enqueue_err_count
++;
216 } else if (sess
== NULL
) {
220 slots_req
+= ccp_compute_slot_count(sess
);
223 cmd_q
= ccp_allot_queue(dev
, slots_req
);
224 if (unlikely(cmd_q
== NULL
))
227 enq_cnt
= process_ops_to_enqueue(qp
, ops
, cmd_q
, nb_ops
, slots_req
);
228 qp
->qp_stats
.enqueued_count
+= enq_cnt
;
233 ccp_pmd_dequeue_burst(void *queue_pair
, struct rte_crypto_op
**ops
,
236 struct ccp_qp
*qp
= queue_pair
;
237 uint16_t nb_dequeued
= 0, i
;
239 nb_dequeued
= process_ops_to_dequeue(qp
, ops
, nb_ops
);
241 /* Free session if a session-less crypto op */
242 for (i
= 0; i
< nb_dequeued
; i
++)
243 if (unlikely(ops
[i
]->sess_type
==
244 RTE_CRYPTO_OP_SESSIONLESS
)) {
245 struct ccp_session
*sess
= (struct ccp_session
*)
246 get_sym_session_private_data(
247 ops
[i
]->sym
->session
,
248 ccp_cryptodev_driver_id
);
250 rte_mempool_put(qp
->sess_mp_priv
,
252 rte_mempool_put(qp
->sess_mp
,
253 ops
[i
]->sym
->session
);
254 ops
[i
]->sym
->session
= NULL
;
256 qp
->qp_stats
.dequeued_count
+= nb_dequeued
;
262 * The set of PCI devices this driver supports
264 static struct rte_pci_id ccp_pci_id
[] = {
266 RTE_PCI_DEVICE(0x1022, 0x1456), /* AMD CCP-5a */
269 RTE_PCI_DEVICE(0x1022, 0x1468), /* AMD CCP-5b */
274 /** Remove ccp pmd */
276 cryptodev_ccp_remove(struct rte_vdev_device
*dev
)
280 ccp_pmd_init_done
= 0;
281 name
= rte_vdev_device_name(dev
);
285 RTE_LOG(INFO
, PMD
, "Closing ccp device %s on numa socket %u\n",
286 name
, rte_socket_id());
291 /** Create crypto device */
293 cryptodev_ccp_create(const char *name
,
294 struct rte_vdev_device
*vdev
,
295 struct ccp_pmd_init_params
*init_params
)
297 struct rte_cryptodev
*dev
;
298 struct ccp_private
*internals
;
299 uint8_t cryptodev_cnt
= 0;
301 if (init_params
->def_p
.name
[0] == '\0')
302 strlcpy(init_params
->def_p
.name
, name
,
303 sizeof(init_params
->def_p
.name
));
305 dev
= rte_cryptodev_pmd_create(init_params
->def_p
.name
,
307 &init_params
->def_p
);
309 CCP_LOG_ERR("failed to create cryptodev vdev");
313 cryptodev_cnt
= ccp_probe_devices(ccp_pci_id
);
315 if (cryptodev_cnt
== 0) {
316 CCP_LOG_ERR("failed to detect CCP crypto device");
320 printf("CCP : Crypto device count = %d\n", cryptodev_cnt
);
321 dev
->driver_id
= ccp_cryptodev_driver_id
;
323 /* register rx/tx burst functions for data path */
324 dev
->dev_ops
= ccp_pmd_ops
;
325 dev
->enqueue_burst
= ccp_pmd_enqueue_burst
;
326 dev
->dequeue_burst
= ccp_pmd_dequeue_burst
;
328 dev
->feature_flags
= RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO
|
329 RTE_CRYPTODEV_FF_HW_ACCELERATED
|
330 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING
;
332 internals
= dev
->data
->dev_private
;
334 internals
->max_nb_qpairs
= init_params
->def_p
.max_nb_queue_pairs
;
335 internals
->auth_opt
= init_params
->auth_opt
;
336 internals
->crypto_num_dev
= cryptodev_cnt
;
341 CCP_LOG_ERR("driver %s: %s() failed",
342 init_params
->def_p
.name
, __func__
);
343 cryptodev_ccp_remove(vdev
);
350 cryptodev_ccp_probe(struct rte_vdev_device
*vdev
)
354 struct ccp_pmd_init_params init_params
= {
357 sizeof(struct ccp_private
),
359 CCP_PMD_MAX_QUEUE_PAIRS
361 .auth_opt
= CCP_PMD_AUTH_OPT_CCP
,
363 const char *input_args
;
365 if (ccp_pmd_init_done
) {
366 RTE_LOG(INFO
, PMD
, "CCP PMD already initialized\n");
369 name
= rte_vdev_device_name(vdev
);
373 input_args
= rte_vdev_device_args(vdev
);
374 ccp_pmd_parse_input_args(&init_params
, input_args
);
375 init_params
.def_p
.max_nb_queue_pairs
= CCP_PMD_MAX_QUEUE_PAIRS
;
377 RTE_LOG(INFO
, PMD
, "Initialising %s on NUMA node %d\n", name
,
378 init_params
.def_p
.socket_id
);
379 RTE_LOG(INFO
, PMD
, "Max number of queue pairs = %d\n",
380 init_params
.def_p
.max_nb_queue_pairs
);
381 RTE_LOG(INFO
, PMD
, "Authentication offload to %s\n",
382 ((init_params
.auth_opt
== 0) ? "CCP" : "CPU"));
384 rc
= cryptodev_ccp_create(name
, vdev
, &init_params
);
387 ccp_pmd_init_done
= 1;
391 static struct rte_vdev_driver cryptodev_ccp_pmd_drv
= {
392 .probe
= cryptodev_ccp_probe
,
393 .remove
= cryptodev_ccp_remove
396 static struct cryptodev_driver ccp_crypto_drv
;
398 RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_CCP_PMD
, cryptodev_ccp_pmd_drv
);
399 RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_CCP_PMD
,
400 "max_nb_queue_pairs=<int> "
402 "ccp_auth_opt=<int>");
403 RTE_PMD_REGISTER_CRYPTO_DRIVER(ccp_crypto_drv
, cryptodev_ccp_pmd_drv
.driver
,
404 ccp_cryptodev_driver_id
);