1a7c86884SShiri Kuzin /* SPDX-License-Identifier: BSD-3-Clause
2a7c86884SShiri Kuzin * Copyright (c) 2021 NVIDIA Corporation & Affiliates
3a7c86884SShiri Kuzin */
4a7c86884SShiri Kuzin
5a7c86884SShiri Kuzin #include <rte_malloc.h>
61004be3cSShiri Kuzin #include <rte_mempool.h>
72f5dceffSTal Shnaiderman #include <rte_eal_paging.h>
8a7c86884SShiri Kuzin #include <rte_errno.h>
9a7c86884SShiri Kuzin #include <rte_log.h>
101f37cb2bSDavid Marchand #include <bus_pci_driver.h>
116152534eSShiri Kuzin #include <rte_memory.h>
12a7c86884SShiri Kuzin
13a7c86884SShiri Kuzin #include <mlx5_glue.h>
14a7c86884SShiri Kuzin #include <mlx5_common.h>
15a7c86884SShiri Kuzin #include <mlx5_devx_cmds.h>
16a7c86884SShiri Kuzin #include <mlx5_common_os.h>
17a7c86884SShiri Kuzin
18a7c86884SShiri Kuzin #include "mlx5_crypto_utils.h"
19a7c86884SShiri Kuzin #include "mlx5_crypto.h"
20a7c86884SShiri Kuzin
21a7c86884SShiri Kuzin #define MLX5_CRYPTO_DRIVER_NAME crypto_mlx5
22a7c86884SShiri Kuzin #define MLX5_CRYPTO_LOG_NAME pmd.crypto.mlx5
2315083724SRaja Zidane #define MLX5_CRYPTO_MAX_QPS 128
24a1978aa2SSuanming Mou #define MLX5_CRYPTO_MAX_SEGS 56
25a7c86884SShiri Kuzin
26f12c41bfSRaja Zidane #define MLX5_CRYPTO_FEATURE_FLAGS(wrapped_mode) \
271004be3cSShiri Kuzin (RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | RTE_CRYPTODEV_FF_HW_ACCELERATED | \
28*3455ed86SSuanming Mou RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT | \
29f12c41bfSRaja Zidane (wrapped_mode ? RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY : 0) | \
301004be3cSShiri Kuzin RTE_CRYPTODEV_FF_CIPHER_MULTIPLE_DATA_UNITS)
31a7c86884SShiri Kuzin
32a7c86884SShiri Kuzin TAILQ_HEAD(mlx5_crypto_privs, mlx5_crypto_priv) mlx5_crypto_priv_list =
33a7c86884SShiri Kuzin TAILQ_HEAD_INITIALIZER(mlx5_crypto_priv_list);
342f5dceffSTal Shnaiderman static pthread_mutex_t priv_list_lock;
35a7c86884SShiri Kuzin
36a7c86884SShiri Kuzin int mlx5_crypto_logtype;
37a7c86884SShiri Kuzin
38a7c86884SShiri Kuzin uint8_t mlx5_crypto_driver_id;
39a7c86884SShiri Kuzin
40a7c86884SShiri Kuzin static const char mlx5_crypto_drv_name[] = RTE_STR(MLX5_CRYPTO_DRIVER_NAME);
41a7c86884SShiri Kuzin
42a7c86884SShiri Kuzin static const struct rte_driver mlx5_drv = {
43a7c86884SShiri Kuzin .name = mlx5_crypto_drv_name,
44a7c86884SShiri Kuzin .alias = mlx5_crypto_drv_name
45a7c86884SShiri Kuzin };
46a7c86884SShiri Kuzin
47a7c86884SShiri Kuzin static struct cryptodev_driver mlx5_cryptodev_driver;
48a7c86884SShiri Kuzin
4990646d6cSShiri Kuzin static void
mlx5_crypto_dev_infos_get(struct rte_cryptodev * dev,struct rte_cryptodev_info * dev_info)5090646d6cSShiri Kuzin mlx5_crypto_dev_infos_get(struct rte_cryptodev *dev,
5190646d6cSShiri Kuzin struct rte_cryptodev_info *dev_info)
5290646d6cSShiri Kuzin {
53f12c41bfSRaja Zidane struct mlx5_crypto_priv *priv = dev->data->dev_private;
54f12c41bfSRaja Zidane
5590646d6cSShiri Kuzin RTE_SET_USED(dev);
5690646d6cSShiri Kuzin if (dev_info != NULL) {
5790646d6cSShiri Kuzin dev_info->driver_id = mlx5_crypto_driver_id;
58f12c41bfSRaja Zidane dev_info->feature_flags =
59f12c41bfSRaja Zidane MLX5_CRYPTO_FEATURE_FLAGS(priv->is_wrapped_mode);
600750c8b1SSuanming Mou if (!mlx5_crypto_is_ipsec_opt(priv))
610750c8b1SSuanming Mou dev_info->feature_flags |=
620750c8b1SSuanming Mou RTE_CRYPTODEV_FF_IN_PLACE_SGL |
630750c8b1SSuanming Mou RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT |
640750c8b1SSuanming Mou RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
650750c8b1SSuanming Mou RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT;
660750c8b1SSuanming Mou
67a27f6a2eSSuanming Mou dev_info->capabilities = priv->caps;
686152534eSShiri Kuzin dev_info->max_nb_queue_pairs = MLX5_CRYPTO_MAX_QPS;
69b0109583SSuanming Mou if (priv->caps->sym.xform_type == RTE_CRYPTO_SYM_XFORM_AEAD) {
70b0109583SSuanming Mou dev_info->min_mbuf_headroom_req = MLX5_CRYPTO_GCM_MAX_AAD;
71b0109583SSuanming Mou dev_info->min_mbuf_tailroom_req = MLX5_CRYPTO_GCM_MAX_DIGEST;
72b0109583SSuanming Mou } else {
7390646d6cSShiri Kuzin dev_info->min_mbuf_headroom_req = 0;
7490646d6cSShiri Kuzin dev_info->min_mbuf_tailroom_req = 0;
75b0109583SSuanming Mou }
7690646d6cSShiri Kuzin dev_info->sym.max_nb_sessions = 0;
7790646d6cSShiri Kuzin /*
7890646d6cSShiri Kuzin * If 0, the device does not have any limitation in number of
7990646d6cSShiri Kuzin * sessions that can be used.
8090646d6cSShiri Kuzin */
8190646d6cSShiri Kuzin }
8290646d6cSShiri Kuzin }
8390646d6cSShiri Kuzin
84a27f6a2eSSuanming Mou void
mlx5_crypto_indirect_mkeys_release(struct mlx5_crypto_qp * qp,uint16_t n)85a27f6a2eSSuanming Mou mlx5_crypto_indirect_mkeys_release(struct mlx5_crypto_qp *qp,
86a27f6a2eSSuanming Mou uint16_t n)
87a27f6a2eSSuanming Mou {
88a27f6a2eSSuanming Mou uint32_t i;
89a27f6a2eSSuanming Mou
90a27f6a2eSSuanming Mou for (i = 0; i < n; i++)
91a27f6a2eSSuanming Mou if (qp->mkey[i])
92a27f6a2eSSuanming Mou claim_zero(mlx5_devx_cmd_destroy(qp->mkey[i]));
93a27f6a2eSSuanming Mou }
94a27f6a2eSSuanming Mou
95a27f6a2eSSuanming Mou int
mlx5_crypto_indirect_mkeys_prepare(struct mlx5_crypto_priv * priv,struct mlx5_crypto_qp * qp,struct mlx5_devx_mkey_attr * attr,mlx5_crypto_mkey_update_t update_cb)96a27f6a2eSSuanming Mou mlx5_crypto_indirect_mkeys_prepare(struct mlx5_crypto_priv *priv,
97a27f6a2eSSuanming Mou struct mlx5_crypto_qp *qp,
98a27f6a2eSSuanming Mou struct mlx5_devx_mkey_attr *attr,
99a27f6a2eSSuanming Mou mlx5_crypto_mkey_update_t update_cb)
100a27f6a2eSSuanming Mou {
101a27f6a2eSSuanming Mou uint32_t i;
102a27f6a2eSSuanming Mou
103a27f6a2eSSuanming Mou for (i = 0; i < qp->entries_n; i++) {
104a27f6a2eSSuanming Mou attr->klm_array = update_cb(priv, qp, i);
105a27f6a2eSSuanming Mou qp->mkey[i] = mlx5_devx_cmd_mkey_create(priv->cdev->ctx, attr);
106a27f6a2eSSuanming Mou if (!qp->mkey[i])
107a27f6a2eSSuanming Mou goto error;
108a27f6a2eSSuanming Mou }
109a27f6a2eSSuanming Mou return 0;
110a27f6a2eSSuanming Mou error:
111a27f6a2eSSuanming Mou DRV_LOG(ERR, "Failed to allocate indirect mkey.");
112a27f6a2eSSuanming Mou mlx5_crypto_indirect_mkeys_release(qp, i);
113a27f6a2eSSuanming Mou return -1;
114a27f6a2eSSuanming Mou }
115a27f6a2eSSuanming Mou
11690646d6cSShiri Kuzin static int
mlx5_crypto_dev_configure(struct rte_cryptodev * dev,struct rte_cryptodev_config * config)11790646d6cSShiri Kuzin mlx5_crypto_dev_configure(struct rte_cryptodev *dev,
11890646d6cSShiri Kuzin struct rte_cryptodev_config *config)
11990646d6cSShiri Kuzin {
12090646d6cSShiri Kuzin struct mlx5_crypto_priv *priv = dev->data->dev_private;
12190646d6cSShiri Kuzin
12290646d6cSShiri Kuzin if (config == NULL) {
12390646d6cSShiri Kuzin DRV_LOG(ERR, "Invalid crypto dev configure parameters.");
12490646d6cSShiri Kuzin return -EINVAL;
12590646d6cSShiri Kuzin }
12690646d6cSShiri Kuzin if ((config->ff_disable & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) != 0) {
12790646d6cSShiri Kuzin DRV_LOG(ERR,
12890646d6cSShiri Kuzin "Disabled symmetric crypto feature is not supported.");
12990646d6cSShiri Kuzin return -ENOTSUP;
13090646d6cSShiri Kuzin }
13190646d6cSShiri Kuzin if (mlx5_crypto_dek_setup(priv) != 0) {
13290646d6cSShiri Kuzin DRV_LOG(ERR, "Dek hash list creation has failed.");
13390646d6cSShiri Kuzin return -ENOMEM;
13490646d6cSShiri Kuzin }
13590646d6cSShiri Kuzin priv->dev_config = *config;
13690646d6cSShiri Kuzin DRV_LOG(DEBUG, "Device %u was configured.", dev->driver_id);
13790646d6cSShiri Kuzin return 0;
13890646d6cSShiri Kuzin }
13990646d6cSShiri Kuzin
14090646d6cSShiri Kuzin static void
mlx5_crypto_dev_stop(struct rte_cryptodev * dev)14190646d6cSShiri Kuzin mlx5_crypto_dev_stop(struct rte_cryptodev *dev)
14290646d6cSShiri Kuzin {
14390646d6cSShiri Kuzin RTE_SET_USED(dev);
14490646d6cSShiri Kuzin }
14590646d6cSShiri Kuzin
14690646d6cSShiri Kuzin static int
mlx5_crypto_dev_start(struct rte_cryptodev * dev)14790646d6cSShiri Kuzin mlx5_crypto_dev_start(struct rte_cryptodev *dev)
14890646d6cSShiri Kuzin {
149fc59a1ecSMichael Baum struct mlx5_crypto_priv *priv = dev->data->dev_private;
150fc59a1ecSMichael Baum
151fc59a1ecSMichael Baum return mlx5_dev_mempool_subscribe(priv->cdev);
15290646d6cSShiri Kuzin }
15390646d6cSShiri Kuzin
15490646d6cSShiri Kuzin static int
mlx5_crypto_dev_close(struct rte_cryptodev * dev)15590646d6cSShiri Kuzin mlx5_crypto_dev_close(struct rte_cryptodev *dev)
15690646d6cSShiri Kuzin {
15790646d6cSShiri Kuzin struct mlx5_crypto_priv *priv = dev->data->dev_private;
15890646d6cSShiri Kuzin
15990646d6cSShiri Kuzin mlx5_crypto_dek_unset(priv);
16090646d6cSShiri Kuzin DRV_LOG(DEBUG, "Device %u was closed.", dev->driver_id);
16190646d6cSShiri Kuzin return 0;
16290646d6cSShiri Kuzin }
16390646d6cSShiri Kuzin
1641004be3cSShiri Kuzin static unsigned int
mlx5_crypto_sym_session_get_size(struct rte_cryptodev * dev __rte_unused)1651004be3cSShiri Kuzin mlx5_crypto_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
1661004be3cSShiri Kuzin {
1671004be3cSShiri Kuzin return sizeof(struct mlx5_crypto_session);
1681004be3cSShiri Kuzin }
1691004be3cSShiri Kuzin
1701004be3cSShiri Kuzin static void
mlx5_crypto_sym_session_clear(struct rte_cryptodev * dev,struct rte_cryptodev_sym_session * sess)1711004be3cSShiri Kuzin mlx5_crypto_sym_session_clear(struct rte_cryptodev *dev,
1721004be3cSShiri Kuzin struct rte_cryptodev_sym_session *sess)
1731004be3cSShiri Kuzin {
1741004be3cSShiri Kuzin struct mlx5_crypto_priv *priv = dev->data->dev_private;
1752a440d6aSAkhil Goyal struct mlx5_crypto_session *spriv = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
1761004be3cSShiri Kuzin
1771004be3cSShiri Kuzin if (unlikely(spriv == NULL)) {
1781004be3cSShiri Kuzin DRV_LOG(ERR, "Failed to get session %p private data.", spriv);
1791004be3cSShiri Kuzin return;
1801004be3cSShiri Kuzin }
1811004be3cSShiri Kuzin mlx5_crypto_dek_destroy(priv, spriv->dek);
1821004be3cSShiri Kuzin DRV_LOG(DEBUG, "Session %p was cleared.", spriv);
1831004be3cSShiri Kuzin }
1841004be3cSShiri Kuzin
185be5aa65cSMichael Baum static void
mlx5_crypto_stats_get(struct rte_cryptodev * dev,struct rte_cryptodev_stats * stats)1869dfc2d6fSSuanming Mou mlx5_crypto_stats_get(struct rte_cryptodev *dev,
1879dfc2d6fSSuanming Mou struct rte_cryptodev_stats *stats)
1889dfc2d6fSSuanming Mou {
1899dfc2d6fSSuanming Mou int qp_id;
1909dfc2d6fSSuanming Mou
1919dfc2d6fSSuanming Mou for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
1929dfc2d6fSSuanming Mou struct mlx5_crypto_qp *qp = dev->data->queue_pairs[qp_id];
1939dfc2d6fSSuanming Mou
1949dfc2d6fSSuanming Mou stats->enqueued_count += qp->stats.enqueued_count;
1959dfc2d6fSSuanming Mou stats->dequeued_count += qp->stats.dequeued_count;
1969dfc2d6fSSuanming Mou stats->enqueue_err_count += qp->stats.enqueue_err_count;
1979dfc2d6fSSuanming Mou stats->dequeue_err_count += qp->stats.dequeue_err_count;
1989dfc2d6fSSuanming Mou }
1999dfc2d6fSSuanming Mou }
2009dfc2d6fSSuanming Mou
2019dfc2d6fSSuanming Mou static void
mlx5_crypto_stats_reset(struct rte_cryptodev * dev)2029dfc2d6fSSuanming Mou mlx5_crypto_stats_reset(struct rte_cryptodev *dev)
2039dfc2d6fSSuanming Mou {
2049dfc2d6fSSuanming Mou int qp_id;
2059dfc2d6fSSuanming Mou
2069dfc2d6fSSuanming Mou for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
2079dfc2d6fSSuanming Mou struct mlx5_crypto_qp *qp = dev->data->queue_pairs[qp_id];
2089dfc2d6fSSuanming Mou
2099dfc2d6fSSuanming Mou memset(&qp->stats, 0, sizeof(qp->stats));
2109dfc2d6fSSuanming Mou }
2119dfc2d6fSSuanming Mou }
2129dfc2d6fSSuanming Mou
213a7c86884SShiri Kuzin static struct rte_cryptodev_ops mlx5_crypto_ops = {
21490646d6cSShiri Kuzin .dev_configure = mlx5_crypto_dev_configure,
21590646d6cSShiri Kuzin .dev_start = mlx5_crypto_dev_start,
21690646d6cSShiri Kuzin .dev_stop = mlx5_crypto_dev_stop,
21790646d6cSShiri Kuzin .dev_close = mlx5_crypto_dev_close,
21890646d6cSShiri Kuzin .dev_infos_get = mlx5_crypto_dev_infos_get,
2199dfc2d6fSSuanming Mou .stats_get = mlx5_crypto_stats_get,
2209dfc2d6fSSuanming Mou .stats_reset = mlx5_crypto_stats_reset,
2211004be3cSShiri Kuzin .sym_session_get_size = mlx5_crypto_sym_session_get_size,
2221004be3cSShiri Kuzin .sym_session_clear = mlx5_crypto_sym_session_clear,
223a7c86884SShiri Kuzin .sym_get_raw_dp_ctx_size = NULL,
224a7c86884SShiri Kuzin .sym_configure_raw_dp_ctx = NULL,
225a7c86884SShiri Kuzin };
226a7c86884SShiri Kuzin
227debb27eaSShiri Kuzin static int
mlx5_crypto_args_check_handler(const char * key,const char * val,void * opaque)228debb27eaSShiri Kuzin mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
229debb27eaSShiri Kuzin {
230debb27eaSShiri Kuzin struct mlx5_crypto_devarg_params *devarg_prms = opaque;
231debb27eaSShiri Kuzin struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
232debb27eaSShiri Kuzin unsigned long tmp;
233debb27eaSShiri Kuzin FILE *file;
234debb27eaSShiri Kuzin int ret;
235debb27eaSShiri Kuzin int i;
236debb27eaSShiri Kuzin
237debb27eaSShiri Kuzin if (strcmp(key, "wcs_file") == 0) {
238debb27eaSShiri Kuzin file = fopen(val, "rb");
239debb27eaSShiri Kuzin if (file == NULL) {
240debb27eaSShiri Kuzin rte_errno = ENOTSUP;
241debb27eaSShiri Kuzin return -rte_errno;
242debb27eaSShiri Kuzin }
243debb27eaSShiri Kuzin for (i = 0 ; i < MLX5_CRYPTO_CREDENTIAL_SIZE ; i++) {
244debb27eaSShiri Kuzin ret = fscanf(file, "%02hhX", &attr->credential[i]);
245debb27eaSShiri Kuzin if (ret <= 0) {
246debb27eaSShiri Kuzin fclose(file);
247debb27eaSShiri Kuzin DRV_LOG(ERR,
248debb27eaSShiri Kuzin "Failed to read credential from file.");
249debb27eaSShiri Kuzin rte_errno = EINVAL;
250debb27eaSShiri Kuzin return -rte_errno;
251debb27eaSShiri Kuzin }
252debb27eaSShiri Kuzin }
253debb27eaSShiri Kuzin fclose(file);
254debb27eaSShiri Kuzin devarg_prms->login_devarg = true;
255debb27eaSShiri Kuzin return 0;
2560750c8b1SSuanming Mou } else if (strcmp(key, "crypto_mode") == 0) {
2570750c8b1SSuanming Mou if (strcmp(val, "full_capable") == 0) {
2580750c8b1SSuanming Mou devarg_prms->crypto_mode = MLX5_CRYPTO_FULL_CAPABLE;
2590750c8b1SSuanming Mou } else if (strcmp(val, "ipsec_opt") == 0) {
2600750c8b1SSuanming Mou devarg_prms->crypto_mode = MLX5_CRYPTO_IPSEC_OPT;
2610750c8b1SSuanming Mou } else {
2620750c8b1SSuanming Mou DRV_LOG(ERR, "Invalid crypto mode: %s", val);
2630750c8b1SSuanming Mou rte_errno = EINVAL;
2640750c8b1SSuanming Mou return -rte_errno;
2650750c8b1SSuanming Mou }
266debb27eaSShiri Kuzin }
267debb27eaSShiri Kuzin errno = 0;
268debb27eaSShiri Kuzin tmp = strtoul(val, NULL, 0);
269debb27eaSShiri Kuzin if (errno) {
270debb27eaSShiri Kuzin DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.", key, val);
271debb27eaSShiri Kuzin return -errno;
272debb27eaSShiri Kuzin }
273a1978aa2SSuanming Mou if (strcmp(key, "max_segs_num") == 0) {
274ba707cdbSRaja Zidane if (!tmp) {
275ba707cdbSRaja Zidane DRV_LOG(ERR, "max_segs_num must be greater than 0.");
276a1978aa2SSuanming Mou rte_errno = EINVAL;
277a1978aa2SSuanming Mou return -rte_errno;
278a1978aa2SSuanming Mou }
279a1978aa2SSuanming Mou devarg_prms->max_segs_num = (uint32_t)tmp;
280a1978aa2SSuanming Mou } else if (strcmp(key, "import_kek_id") == 0) {
281debb27eaSShiri Kuzin attr->session_import_kek_ptr = (uint32_t)tmp;
282a1978aa2SSuanming Mou } else if (strcmp(key, "credential_id") == 0) {
283debb27eaSShiri Kuzin attr->credential_pointer = (uint32_t)tmp;
284a1978aa2SSuanming Mou } else if (strcmp(key, "keytag") == 0) {
285e8db4413SSuanming Mou devarg_prms->keytag = tmp;
2866c948396SSuanming Mou } else if (strcmp(key, "algo") == 0) {
2876c948396SSuanming Mou if (tmp == 1) {
2886c948396SSuanming Mou devarg_prms->is_aes_gcm = 1;
2896c948396SSuanming Mou } else if (tmp > 1) {
2906c948396SSuanming Mou DRV_LOG(ERR, "Invalid algo.");
2916c948396SSuanming Mou rte_errno = EINVAL;
2926c948396SSuanming Mou return -rte_errno;
2936c948396SSuanming Mou }
294a1978aa2SSuanming Mou }
295debb27eaSShiri Kuzin return 0;
296debb27eaSShiri Kuzin }
297debb27eaSShiri Kuzin
298e8db4413SSuanming Mou static int
mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl * mkvlist,struct mlx5_crypto_devarg_params * devarg_prms,bool wrapped_mode)299a729d2f0SMichael Baum mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl *mkvlist,
300f12c41bfSRaja Zidane struct mlx5_crypto_devarg_params *devarg_prms,
301f12c41bfSRaja Zidane bool wrapped_mode)
302debb27eaSShiri Kuzin {
303e8db4413SSuanming Mou struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
304a729d2f0SMichael Baum const char **params = (const char *[]){
305a729d2f0SMichael Baum "credential_id",
306a729d2f0SMichael Baum "import_kek_id",
307a729d2f0SMichael Baum "keytag",
308a729d2f0SMichael Baum "max_segs_num",
309a729d2f0SMichael Baum "wcs_file",
3106c948396SSuanming Mou "algo",
3110750c8b1SSuanming Mou "crypto_mode",
312a729d2f0SMichael Baum NULL,
313a729d2f0SMichael Baum };
314debb27eaSShiri Kuzin
315e8db4413SSuanming Mou /* Default values. */
316e8db4413SSuanming Mou attr->credential_pointer = 0;
317e8db4413SSuanming Mou attr->session_import_kek_ptr = 0;
318e8db4413SSuanming Mou devarg_prms->keytag = 0;
319a1978aa2SSuanming Mou devarg_prms->max_segs_num = 8;
320a729d2f0SMichael Baum if (mkvlist == NULL) {
321f12c41bfSRaja Zidane if (!wrapped_mode)
322f12c41bfSRaja Zidane return 0;
323debb27eaSShiri Kuzin DRV_LOG(ERR,
324debb27eaSShiri Kuzin "No login devargs in order to enable crypto operations in the device.");
325debb27eaSShiri Kuzin rte_errno = EINVAL;
326e8db4413SSuanming Mou return -1;
327debb27eaSShiri Kuzin }
328a729d2f0SMichael Baum if (mlx5_kvargs_process(mkvlist, params, mlx5_crypto_args_check_handler,
329e8db4413SSuanming Mou devarg_prms) != 0) {
330debb27eaSShiri Kuzin DRV_LOG(ERR, "Devargs handler function Failed.");
331debb27eaSShiri Kuzin rte_errno = EINVAL;
332e8db4413SSuanming Mou return -1;
333debb27eaSShiri Kuzin }
334f12c41bfSRaja Zidane if (devarg_prms->login_devarg == false && wrapped_mode) {
335debb27eaSShiri Kuzin DRV_LOG(ERR,
336f12c41bfSRaja Zidane "No login credential devarg in order to enable crypto operations in the device while in wrapped import method.");
337debb27eaSShiri Kuzin rte_errno = EINVAL;
338e8db4413SSuanming Mou return -1;
339debb27eaSShiri Kuzin }
340e8db4413SSuanming Mou return 0;
341debb27eaSShiri Kuzin }
342debb27eaSShiri Kuzin
343a7c86884SShiri Kuzin static int
mlx5_crypto_dev_probe(struct mlx5_common_device * cdev,struct mlx5_kvargs_ctrl * mkvlist)344a729d2f0SMichael Baum mlx5_crypto_dev_probe(struct mlx5_common_device *cdev,
345a729d2f0SMichael Baum struct mlx5_kvargs_ctrl *mkvlist)
346a7c86884SShiri Kuzin {
347a7c86884SShiri Kuzin struct rte_cryptodev *crypto_dev;
348debb27eaSShiri Kuzin struct mlx5_devx_obj *login;
349a7c86884SShiri Kuzin struct mlx5_crypto_priv *priv;
350e8db4413SSuanming Mou struct mlx5_crypto_devarg_params devarg_prms = { 0 };
351a7c86884SShiri Kuzin struct rte_cryptodev_pmd_init_params init_params = {
352a7c86884SShiri Kuzin .name = "",
353a7c86884SShiri Kuzin .private_data_size = sizeof(struct mlx5_crypto_priv),
3547af08c8fSMichael Baum .socket_id = cdev->dev->numa_node,
355a7c86884SShiri Kuzin .max_nb_queue_pairs =
356a7c86884SShiri Kuzin RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
357a7c86884SShiri Kuzin };
358ca1418ceSMichael Baum const char *ibdev_name = mlx5_os_get_ctx_device_name(cdev->ctx);
359e8db4413SSuanming Mou int ret;
360f12c41bfSRaja Zidane bool wrapped_mode;
361e8db4413SSuanming Mou
362a7c86884SShiri Kuzin if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
363a7c86884SShiri Kuzin DRV_LOG(ERR, "Non-primary process type is not supported.");
364a7c86884SShiri Kuzin rte_errno = ENOTSUP;
365a7c86884SShiri Kuzin return -rte_errno;
366a7c86884SShiri Kuzin }
36704da07e6SSuanming Mou if (!cdev->config.hca_attr.crypto ||
36804da07e6SSuanming Mou (!cdev->config.hca_attr.aes_xts &&
36904da07e6SSuanming Mou !cdev->config.hca_attr.crypto_mmo.crypto_mmo_qp)) {
370a7c86884SShiri Kuzin DRV_LOG(ERR, "Not enough capabilities to support crypto "
371a7c86884SShiri Kuzin "operations, maybe old FW/OFED version?");
372a7c86884SShiri Kuzin rte_errno = ENOTSUP;
373a7c86884SShiri Kuzin return -ENOTSUP;
374a7c86884SShiri Kuzin }
375f12c41bfSRaja Zidane wrapped_mode = !!cdev->config.hca_attr.crypto_wrapped_import_method;
376f12c41bfSRaja Zidane ret = mlx5_crypto_parse_devargs(mkvlist, &devarg_prms, wrapped_mode);
377e8db4413SSuanming Mou if (ret) {
378e8db4413SSuanming Mou DRV_LOG(ERR, "Failed to parse devargs.");
379e8db4413SSuanming Mou return -rte_errno;
380e8db4413SSuanming Mou }
381ca1418ceSMichael Baum crypto_dev = rte_cryptodev_pmd_create(ibdev_name, cdev->dev,
382a7c86884SShiri Kuzin &init_params);
383a7c86884SShiri Kuzin if (crypto_dev == NULL) {
384ca1418ceSMichael Baum DRV_LOG(ERR, "Failed to create device \"%s\".", ibdev_name);
385a7c86884SShiri Kuzin return -ENODEV;
386a7c86884SShiri Kuzin }
387a7c86884SShiri Kuzin DRV_LOG(INFO,
388ca1418ceSMichael Baum "Crypto device %s was created successfully.", ibdev_name);
389a7c86884SShiri Kuzin crypto_dev->dev_ops = &mlx5_crypto_ops;
390f12c41bfSRaja Zidane crypto_dev->feature_flags = MLX5_CRYPTO_FEATURE_FLAGS(wrapped_mode);
391a7c86884SShiri Kuzin crypto_dev->driver_id = mlx5_crypto_driver_id;
392a7c86884SShiri Kuzin priv = crypto_dev->data->dev_private;
393ca1418ceSMichael Baum priv->cdev = cdev;
394a7c86884SShiri Kuzin priv->crypto_dev = crypto_dev;
395f12c41bfSRaja Zidane priv->is_wrapped_mode = wrapped_mode;
396a27f6a2eSSuanming Mou priv->max_segs_num = devarg_prms.max_segs_num;
3970750c8b1SSuanming Mou priv->crypto_mode = devarg_prms.crypto_mode;
3986c948396SSuanming Mou /* Init and override AES-GCM configuration. */
3996c948396SSuanming Mou if (devarg_prms.is_aes_gcm) {
4006c948396SSuanming Mou ret = mlx5_crypto_gcm_init(priv);
4016c948396SSuanming Mou if (ret) {
4024fd4eb01SSuanming Mou rte_cryptodev_pmd_destroy(priv->crypto_dev);
4036c948396SSuanming Mou DRV_LOG(ERR, "Failed to init AES-GCM crypto.");
4046c948396SSuanming Mou return -ENOTSUP;
4056c948396SSuanming Mou }
4066c948396SSuanming Mou } else {
407a27f6a2eSSuanming Mou ret = mlx5_crypto_xts_init(priv);
408a27f6a2eSSuanming Mou if (ret) {
4094fd4eb01SSuanming Mou rte_cryptodev_pmd_destroy(priv->crypto_dev);
410a27f6a2eSSuanming Mou DRV_LOG(ERR, "Failed to init AES-XTS crypto.");
411a27f6a2eSSuanming Mou return -ENOTSUP;
412a27f6a2eSSuanming Mou }
4136c948396SSuanming Mou }
4145dfa003dSMichael Baum if (mlx5_devx_uar_prepare(cdev, &priv->uar) != 0) {
415a7c86884SShiri Kuzin rte_cryptodev_pmd_destroy(priv->crypto_dev);
416a7c86884SShiri Kuzin return -1;
417a7c86884SShiri Kuzin }
418f12c41bfSRaja Zidane if (wrapped_mode) {
419801b4885SMichael Baum login = mlx5_devx_cmd_create_crypto_login_obj(cdev->ctx,
420801b4885SMichael Baum &devarg_prms.login_attr);
421801b4885SMichael Baum if (login == NULL) {
422801b4885SMichael Baum DRV_LOG(ERR, "Failed to configure login.");
4235dfa003dSMichael Baum mlx5_devx_uar_release(&priv->uar);
424801b4885SMichael Baum rte_cryptodev_pmd_destroy(priv->crypto_dev);
425801b4885SMichael Baum return -rte_errno;
426801b4885SMichael Baum }
427801b4885SMichael Baum priv->login_obj = login;
428f12c41bfSRaja Zidane }
429f12c41bfSRaja Zidane priv->keytag = rte_cpu_to_be_64(devarg_prms.keytag);
430ba707cdbSRaja Zidane DRV_LOG(INFO, "Max number of segments: %u.",
431ba707cdbSRaja Zidane (unsigned int)RTE_MIN(
432ba707cdbSRaja Zidane MLX5_CRYPTO_KLM_SEGS_NUM(priv->umr_wqe_size),
433ba707cdbSRaja Zidane (uint16_t)(priv->max_rdmar_ds - 2)));
434a7c86884SShiri Kuzin pthread_mutex_lock(&priv_list_lock);
435a7c86884SShiri Kuzin TAILQ_INSERT_TAIL(&mlx5_crypto_priv_list, priv, next);
436a7c86884SShiri Kuzin pthread_mutex_unlock(&priv_list_lock);
437d54c72ecSAkhil Goyal
438d54c72ecSAkhil Goyal rte_cryptodev_pmd_probing_finish(crypto_dev);
439d54c72ecSAkhil Goyal
440a7c86884SShiri Kuzin return 0;
441a7c86884SShiri Kuzin }
442a7c86884SShiri Kuzin
443a7c86884SShiri Kuzin static int
mlx5_crypto_dev_remove(struct mlx5_common_device * cdev)4447af08c8fSMichael Baum mlx5_crypto_dev_remove(struct mlx5_common_device *cdev)
445a7c86884SShiri Kuzin {
446a7c86884SShiri Kuzin struct mlx5_crypto_priv *priv = NULL;
447a7c86884SShiri Kuzin
448a7c86884SShiri Kuzin pthread_mutex_lock(&priv_list_lock);
449a7c86884SShiri Kuzin TAILQ_FOREACH(priv, &mlx5_crypto_priv_list, next)
4507af08c8fSMichael Baum if (priv->crypto_dev->device == cdev->dev)
451a7c86884SShiri Kuzin break;
452a7c86884SShiri Kuzin if (priv)
453a7c86884SShiri Kuzin TAILQ_REMOVE(&mlx5_crypto_priv_list, priv, next);
454a7c86884SShiri Kuzin pthread_mutex_unlock(&priv_list_lock);
455a7c86884SShiri Kuzin if (priv) {
456801b4885SMichael Baum claim_zero(mlx5_devx_cmd_destroy(priv->login_obj));
4575dfa003dSMichael Baum mlx5_devx_uar_release(&priv->uar);
458a7c86884SShiri Kuzin rte_cryptodev_pmd_destroy(priv->crypto_dev);
459a7c86884SShiri Kuzin }
460a7c86884SShiri Kuzin return 0;
461a7c86884SShiri Kuzin }
462a7c86884SShiri Kuzin
463a7c86884SShiri Kuzin static const struct rte_pci_id mlx5_crypto_pci_id_map[] = {
464a7c86884SShiri Kuzin {
465a7c86884SShiri Kuzin RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
466a7c86884SShiri Kuzin PCI_DEVICE_ID_MELLANOX_CONNECTX6)
467a7c86884SShiri Kuzin },
468a7c86884SShiri Kuzin {
4694b2cc736SRaja Zidane RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
4704b2cc736SRaja Zidane PCI_DEVICE_ID_MELLANOX_CONNECTX6DX)
4714b2cc736SRaja Zidane },
4724b2cc736SRaja Zidane {
4734b2cc736SRaja Zidane RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
4740a9fff95SRaslan Darawsheh PCI_DEVICE_ID_MELLANOX_BLUEFIELD2)
4754b2cc736SRaja Zidane },
4764b2cc736SRaja Zidane {
477a0c33299SRaslan Darawsheh RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
478a0c33299SRaslan Darawsheh PCI_DEVICE_ID_MELLANOX_CONNECTX7)
479a0c33299SRaslan Darawsheh },
480a0c33299SRaslan Darawsheh {
481a0c33299SRaslan Darawsheh RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
482a0c33299SRaslan Darawsheh PCI_DEVICE_ID_MELLANOX_BLUEFIELD3)
483a0c33299SRaslan Darawsheh },
484a0c33299SRaslan Darawsheh {
485f31ad925SSuanming Mou RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
486f31ad925SSuanming Mou PCI_DEVICE_ID_MELLANOX_CONNECTXVF)
487f31ad925SSuanming Mou },
488f31ad925SSuanming Mou {
489a7c86884SShiri Kuzin .vendor_id = 0
490a7c86884SShiri Kuzin }
491a7c86884SShiri Kuzin };
492a7c86884SShiri Kuzin
49337d3bde4SXueming Li static struct mlx5_class_driver mlx5_crypto_driver = {
49437d3bde4SXueming Li .drv_class = MLX5_CLASS_CRYPTO,
495a7c86884SShiri Kuzin .name = RTE_STR(MLX5_CRYPTO_DRIVER_NAME),
496a7c86884SShiri Kuzin .id_table = mlx5_crypto_pci_id_map,
49737d3bde4SXueming Li .probe = mlx5_crypto_dev_probe,
49837d3bde4SXueming Li .remove = mlx5_crypto_dev_remove,
499a7c86884SShiri Kuzin };
500a7c86884SShiri Kuzin
RTE_INIT(rte_mlx5_crypto_init)501a7c86884SShiri Kuzin RTE_INIT(rte_mlx5_crypto_init)
502a7c86884SShiri Kuzin {
5032f5dceffSTal Shnaiderman pthread_mutex_init(&priv_list_lock, NULL);
504a7c86884SShiri Kuzin mlx5_common_init();
505a7c86884SShiri Kuzin if (mlx5_glue != NULL)
50637d3bde4SXueming Li mlx5_class_driver_register(&mlx5_crypto_driver);
507a7c86884SShiri Kuzin }
508a7c86884SShiri Kuzin
509a7c86884SShiri Kuzin RTE_PMD_REGISTER_CRYPTO_DRIVER(mlx5_cryptodev_driver, mlx5_drv,
510a7c86884SShiri Kuzin mlx5_crypto_driver_id);
511a7c86884SShiri Kuzin
512a7c86884SShiri Kuzin RTE_LOG_REGISTER_DEFAULT(mlx5_crypto_logtype, NOTICE)
513a7c86884SShiri Kuzin RTE_PMD_EXPORT_NAME(MLX5_CRYPTO_DRIVER_NAME, __COUNTER__);
514a7c86884SShiri Kuzin RTE_PMD_REGISTER_PCI_TABLE(MLX5_CRYPTO_DRIVER_NAME, mlx5_crypto_pci_id_map);
515a7c86884SShiri Kuzin RTE_PMD_REGISTER_KMOD_DEP(MLX5_CRYPTO_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
516