xref: /dpdk/drivers/crypto/mlx5/mlx5_crypto.c (revision 3455ed860d66aa53c8fb8a10eabda3dc308c6500)
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