xref: /dpdk/drivers/crypto/mlx5/mlx5_crypto.c (revision a27f6a2e1f30c44753832bd1ec70f5a416e9f16c)
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 | \
288e196c08SSuanming Mou 	 RTE_CRYPTODEV_FF_IN_PLACE_SGL | RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT | \
298e196c08SSuanming Mou 	 RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT | \
308e196c08SSuanming Mou 	 RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT | \
318e196c08SSuanming Mou 	 RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT | \
32f12c41bfSRaja Zidane 	 (wrapped_mode ? RTE_CRYPTODEV_FF_CIPHER_WRAPPED_KEY : 0) | \
331004be3cSShiri Kuzin 	 RTE_CRYPTODEV_FF_CIPHER_MULTIPLE_DATA_UNITS)
34a7c86884SShiri Kuzin 
35a7c86884SShiri Kuzin TAILQ_HEAD(mlx5_crypto_privs, mlx5_crypto_priv) mlx5_crypto_priv_list =
36a7c86884SShiri Kuzin 				TAILQ_HEAD_INITIALIZER(mlx5_crypto_priv_list);
372f5dceffSTal Shnaiderman static pthread_mutex_t priv_list_lock;
38a7c86884SShiri Kuzin 
39a7c86884SShiri Kuzin int mlx5_crypto_logtype;
40a7c86884SShiri Kuzin 
41a7c86884SShiri Kuzin uint8_t mlx5_crypto_driver_id;
42a7c86884SShiri Kuzin 
43a7c86884SShiri Kuzin static const char mlx5_crypto_drv_name[] = RTE_STR(MLX5_CRYPTO_DRIVER_NAME);
44a7c86884SShiri Kuzin 
45a7c86884SShiri Kuzin static const struct rte_driver mlx5_drv = {
46a7c86884SShiri Kuzin 	.name = mlx5_crypto_drv_name,
47a7c86884SShiri Kuzin 	.alias = mlx5_crypto_drv_name
48a7c86884SShiri Kuzin };
49a7c86884SShiri Kuzin 
50a7c86884SShiri Kuzin static struct cryptodev_driver mlx5_cryptodev_driver;
51a7c86884SShiri Kuzin 
5290646d6cSShiri Kuzin static void
5390646d6cSShiri Kuzin mlx5_crypto_dev_infos_get(struct rte_cryptodev *dev,
5490646d6cSShiri Kuzin 			  struct rte_cryptodev_info *dev_info)
5590646d6cSShiri Kuzin {
56f12c41bfSRaja Zidane 	struct mlx5_crypto_priv *priv = dev->data->dev_private;
57f12c41bfSRaja Zidane 
5890646d6cSShiri Kuzin 	RTE_SET_USED(dev);
5990646d6cSShiri Kuzin 	if (dev_info != NULL) {
6090646d6cSShiri Kuzin 		dev_info->driver_id = mlx5_crypto_driver_id;
61f12c41bfSRaja Zidane 		dev_info->feature_flags =
62f12c41bfSRaja Zidane 			MLX5_CRYPTO_FEATURE_FLAGS(priv->is_wrapped_mode);
63*a27f6a2eSSuanming Mou 		dev_info->capabilities = priv->caps;
646152534eSShiri Kuzin 		dev_info->max_nb_queue_pairs = MLX5_CRYPTO_MAX_QPS;
6590646d6cSShiri Kuzin 		dev_info->min_mbuf_headroom_req = 0;
6690646d6cSShiri Kuzin 		dev_info->min_mbuf_tailroom_req = 0;
6790646d6cSShiri Kuzin 		dev_info->sym.max_nb_sessions = 0;
6890646d6cSShiri Kuzin 		/*
6990646d6cSShiri Kuzin 		 * If 0, the device does not have any limitation in number of
7090646d6cSShiri Kuzin 		 * sessions that can be used.
7190646d6cSShiri Kuzin 		 */
7290646d6cSShiri Kuzin 	}
7390646d6cSShiri Kuzin }
7490646d6cSShiri Kuzin 
75*a27f6a2eSSuanming Mou void
76*a27f6a2eSSuanming Mou mlx5_crypto_indirect_mkeys_release(struct mlx5_crypto_qp *qp,
77*a27f6a2eSSuanming Mou 				   uint16_t n)
78*a27f6a2eSSuanming Mou {
79*a27f6a2eSSuanming Mou 	uint32_t i;
80*a27f6a2eSSuanming Mou 
81*a27f6a2eSSuanming Mou 	for (i = 0; i < n; i++)
82*a27f6a2eSSuanming Mou 		if (qp->mkey[i])
83*a27f6a2eSSuanming Mou 			claim_zero(mlx5_devx_cmd_destroy(qp->mkey[i]));
84*a27f6a2eSSuanming Mou }
85*a27f6a2eSSuanming Mou 
86*a27f6a2eSSuanming Mou int
87*a27f6a2eSSuanming Mou mlx5_crypto_indirect_mkeys_prepare(struct mlx5_crypto_priv *priv,
88*a27f6a2eSSuanming Mou 				   struct mlx5_crypto_qp *qp,
89*a27f6a2eSSuanming Mou 				   struct mlx5_devx_mkey_attr *attr,
90*a27f6a2eSSuanming Mou 				   mlx5_crypto_mkey_update_t update_cb)
91*a27f6a2eSSuanming Mou {
92*a27f6a2eSSuanming Mou 	uint32_t i;
93*a27f6a2eSSuanming Mou 
94*a27f6a2eSSuanming Mou 	for (i = 0; i < qp->entries_n; i++) {
95*a27f6a2eSSuanming Mou 		attr->klm_array = update_cb(priv, qp, i);
96*a27f6a2eSSuanming Mou 		qp->mkey[i] = mlx5_devx_cmd_mkey_create(priv->cdev->ctx, attr);
97*a27f6a2eSSuanming Mou 		if (!qp->mkey[i])
98*a27f6a2eSSuanming Mou 			goto error;
99*a27f6a2eSSuanming Mou 	}
100*a27f6a2eSSuanming Mou 	return 0;
101*a27f6a2eSSuanming Mou error:
102*a27f6a2eSSuanming Mou 	DRV_LOG(ERR, "Failed to allocate indirect mkey.");
103*a27f6a2eSSuanming Mou 	mlx5_crypto_indirect_mkeys_release(qp, i);
104*a27f6a2eSSuanming Mou 	return -1;
105*a27f6a2eSSuanming Mou }
106*a27f6a2eSSuanming Mou 
10790646d6cSShiri Kuzin static int
10890646d6cSShiri Kuzin mlx5_crypto_dev_configure(struct rte_cryptodev *dev,
10990646d6cSShiri Kuzin 			  struct rte_cryptodev_config *config)
11090646d6cSShiri Kuzin {
11190646d6cSShiri Kuzin 	struct mlx5_crypto_priv *priv = dev->data->dev_private;
11290646d6cSShiri Kuzin 
11390646d6cSShiri Kuzin 	if (config == NULL) {
11490646d6cSShiri Kuzin 		DRV_LOG(ERR, "Invalid crypto dev configure parameters.");
11590646d6cSShiri Kuzin 		return -EINVAL;
11690646d6cSShiri Kuzin 	}
11790646d6cSShiri Kuzin 	if ((config->ff_disable & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) != 0) {
11890646d6cSShiri Kuzin 		DRV_LOG(ERR,
11990646d6cSShiri Kuzin 			"Disabled symmetric crypto feature is not supported.");
12090646d6cSShiri Kuzin 		return -ENOTSUP;
12190646d6cSShiri Kuzin 	}
12290646d6cSShiri Kuzin 	if (mlx5_crypto_dek_setup(priv) != 0) {
12390646d6cSShiri Kuzin 		DRV_LOG(ERR, "Dek hash list creation has failed.");
12490646d6cSShiri Kuzin 		return -ENOMEM;
12590646d6cSShiri Kuzin 	}
12690646d6cSShiri Kuzin 	priv->dev_config = *config;
12790646d6cSShiri Kuzin 	DRV_LOG(DEBUG, "Device %u was configured.", dev->driver_id);
12890646d6cSShiri Kuzin 	return 0;
12990646d6cSShiri Kuzin }
13090646d6cSShiri Kuzin 
13190646d6cSShiri Kuzin static void
13290646d6cSShiri Kuzin mlx5_crypto_dev_stop(struct rte_cryptodev *dev)
13390646d6cSShiri Kuzin {
13490646d6cSShiri Kuzin 	RTE_SET_USED(dev);
13590646d6cSShiri Kuzin }
13690646d6cSShiri Kuzin 
13790646d6cSShiri Kuzin static int
13890646d6cSShiri Kuzin mlx5_crypto_dev_start(struct rte_cryptodev *dev)
13990646d6cSShiri Kuzin {
140fc59a1ecSMichael Baum 	struct mlx5_crypto_priv *priv = dev->data->dev_private;
141fc59a1ecSMichael Baum 
142fc59a1ecSMichael Baum 	return mlx5_dev_mempool_subscribe(priv->cdev);
14390646d6cSShiri Kuzin }
14490646d6cSShiri Kuzin 
14590646d6cSShiri Kuzin static int
14690646d6cSShiri Kuzin mlx5_crypto_dev_close(struct rte_cryptodev *dev)
14790646d6cSShiri Kuzin {
14890646d6cSShiri Kuzin 	struct mlx5_crypto_priv *priv = dev->data->dev_private;
14990646d6cSShiri Kuzin 
15090646d6cSShiri Kuzin 	mlx5_crypto_dek_unset(priv);
15190646d6cSShiri Kuzin 	DRV_LOG(DEBUG, "Device %u was closed.", dev->driver_id);
15290646d6cSShiri Kuzin 	return 0;
15390646d6cSShiri Kuzin }
15490646d6cSShiri Kuzin 
1551004be3cSShiri Kuzin static unsigned int
1561004be3cSShiri Kuzin mlx5_crypto_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
1571004be3cSShiri Kuzin {
1581004be3cSShiri Kuzin 	return sizeof(struct mlx5_crypto_session);
1591004be3cSShiri Kuzin }
1601004be3cSShiri Kuzin 
1611004be3cSShiri Kuzin static void
1621004be3cSShiri Kuzin mlx5_crypto_sym_session_clear(struct rte_cryptodev *dev,
1631004be3cSShiri Kuzin 			      struct rte_cryptodev_sym_session *sess)
1641004be3cSShiri Kuzin {
1651004be3cSShiri Kuzin 	struct mlx5_crypto_priv *priv = dev->data->dev_private;
1662a440d6aSAkhil Goyal 	struct mlx5_crypto_session *spriv = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
1671004be3cSShiri Kuzin 
1681004be3cSShiri Kuzin 	if (unlikely(spriv == NULL)) {
1691004be3cSShiri Kuzin 		DRV_LOG(ERR, "Failed to get session %p private data.", spriv);
1701004be3cSShiri Kuzin 		return;
1711004be3cSShiri Kuzin 	}
1721004be3cSShiri Kuzin 	mlx5_crypto_dek_destroy(priv, spriv->dek);
1731004be3cSShiri Kuzin 	DRV_LOG(DEBUG, "Session %p was cleared.", spriv);
1741004be3cSShiri Kuzin }
1751004be3cSShiri Kuzin 
176be5aa65cSMichael Baum static void
1779dfc2d6fSSuanming Mou mlx5_crypto_stats_get(struct rte_cryptodev *dev,
1789dfc2d6fSSuanming Mou 		      struct rte_cryptodev_stats *stats)
1799dfc2d6fSSuanming Mou {
1809dfc2d6fSSuanming Mou 	int qp_id;
1819dfc2d6fSSuanming Mou 
1829dfc2d6fSSuanming Mou 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
1839dfc2d6fSSuanming Mou 		struct mlx5_crypto_qp *qp = dev->data->queue_pairs[qp_id];
1849dfc2d6fSSuanming Mou 
1859dfc2d6fSSuanming Mou 		stats->enqueued_count += qp->stats.enqueued_count;
1869dfc2d6fSSuanming Mou 		stats->dequeued_count += qp->stats.dequeued_count;
1879dfc2d6fSSuanming Mou 		stats->enqueue_err_count += qp->stats.enqueue_err_count;
1889dfc2d6fSSuanming Mou 		stats->dequeue_err_count += qp->stats.dequeue_err_count;
1899dfc2d6fSSuanming Mou 	}
1909dfc2d6fSSuanming Mou }
1919dfc2d6fSSuanming Mou 
1929dfc2d6fSSuanming Mou static void
1939dfc2d6fSSuanming Mou mlx5_crypto_stats_reset(struct rte_cryptodev *dev)
1949dfc2d6fSSuanming Mou {
1959dfc2d6fSSuanming Mou 	int qp_id;
1969dfc2d6fSSuanming Mou 
1979dfc2d6fSSuanming Mou 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
1989dfc2d6fSSuanming Mou 		struct mlx5_crypto_qp *qp = dev->data->queue_pairs[qp_id];
1999dfc2d6fSSuanming Mou 
2009dfc2d6fSSuanming Mou 		memset(&qp->stats, 0, sizeof(qp->stats));
2019dfc2d6fSSuanming Mou 	}
2029dfc2d6fSSuanming Mou }
2039dfc2d6fSSuanming Mou 
204a7c86884SShiri Kuzin static struct rte_cryptodev_ops mlx5_crypto_ops = {
20590646d6cSShiri Kuzin 	.dev_configure			= mlx5_crypto_dev_configure,
20690646d6cSShiri Kuzin 	.dev_start			= mlx5_crypto_dev_start,
20790646d6cSShiri Kuzin 	.dev_stop			= mlx5_crypto_dev_stop,
20890646d6cSShiri Kuzin 	.dev_close			= mlx5_crypto_dev_close,
20990646d6cSShiri Kuzin 	.dev_infos_get			= mlx5_crypto_dev_infos_get,
2109dfc2d6fSSuanming Mou 	.stats_get			= mlx5_crypto_stats_get,
2119dfc2d6fSSuanming Mou 	.stats_reset			= mlx5_crypto_stats_reset,
2121004be3cSShiri Kuzin 	.sym_session_get_size		= mlx5_crypto_sym_session_get_size,
2131004be3cSShiri Kuzin 	.sym_session_clear		= mlx5_crypto_sym_session_clear,
214a7c86884SShiri Kuzin 	.sym_get_raw_dp_ctx_size	= NULL,
215a7c86884SShiri Kuzin 	.sym_configure_raw_dp_ctx	= NULL,
216a7c86884SShiri Kuzin };
217a7c86884SShiri Kuzin 
218debb27eaSShiri Kuzin static int
219debb27eaSShiri Kuzin mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
220debb27eaSShiri Kuzin {
221debb27eaSShiri Kuzin 	struct mlx5_crypto_devarg_params *devarg_prms = opaque;
222debb27eaSShiri Kuzin 	struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
223debb27eaSShiri Kuzin 	unsigned long tmp;
224debb27eaSShiri Kuzin 	FILE *file;
225debb27eaSShiri Kuzin 	int ret;
226debb27eaSShiri Kuzin 	int i;
227debb27eaSShiri Kuzin 
228debb27eaSShiri Kuzin 	if (strcmp(key, "wcs_file") == 0) {
229debb27eaSShiri Kuzin 		file = fopen(val, "rb");
230debb27eaSShiri Kuzin 		if (file == NULL) {
231debb27eaSShiri Kuzin 			rte_errno = ENOTSUP;
232debb27eaSShiri Kuzin 			return -rte_errno;
233debb27eaSShiri Kuzin 		}
234debb27eaSShiri Kuzin 		for (i = 0 ; i < MLX5_CRYPTO_CREDENTIAL_SIZE ; i++) {
235debb27eaSShiri Kuzin 			ret = fscanf(file, "%02hhX", &attr->credential[i]);
236debb27eaSShiri Kuzin 			if (ret <= 0) {
237debb27eaSShiri Kuzin 				fclose(file);
238debb27eaSShiri Kuzin 				DRV_LOG(ERR,
239debb27eaSShiri Kuzin 					"Failed to read credential from file.");
240debb27eaSShiri Kuzin 				rte_errno = EINVAL;
241debb27eaSShiri Kuzin 				return -rte_errno;
242debb27eaSShiri Kuzin 			}
243debb27eaSShiri Kuzin 		}
244debb27eaSShiri Kuzin 		fclose(file);
245debb27eaSShiri Kuzin 		devarg_prms->login_devarg = true;
246debb27eaSShiri Kuzin 		return 0;
247debb27eaSShiri Kuzin 	}
248debb27eaSShiri Kuzin 	errno = 0;
249debb27eaSShiri Kuzin 	tmp = strtoul(val, NULL, 0);
250debb27eaSShiri Kuzin 	if (errno) {
251debb27eaSShiri Kuzin 		DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.", key, val);
252debb27eaSShiri Kuzin 		return -errno;
253debb27eaSShiri Kuzin 	}
254a1978aa2SSuanming Mou 	if (strcmp(key, "max_segs_num") == 0) {
255ba707cdbSRaja Zidane 		if (!tmp) {
256ba707cdbSRaja Zidane 			DRV_LOG(ERR, "max_segs_num must be greater than 0.");
257a1978aa2SSuanming Mou 			rte_errno = EINVAL;
258a1978aa2SSuanming Mou 			return -rte_errno;
259a1978aa2SSuanming Mou 		}
260a1978aa2SSuanming Mou 		devarg_prms->max_segs_num = (uint32_t)tmp;
261a1978aa2SSuanming Mou 	} else if (strcmp(key, "import_kek_id") == 0) {
262debb27eaSShiri Kuzin 		attr->session_import_kek_ptr = (uint32_t)tmp;
263a1978aa2SSuanming Mou 	} else if (strcmp(key, "credential_id") == 0) {
264debb27eaSShiri Kuzin 		attr->credential_pointer = (uint32_t)tmp;
265a1978aa2SSuanming Mou 	} else if (strcmp(key, "keytag") == 0) {
266e8db4413SSuanming Mou 		devarg_prms->keytag = tmp;
267a1978aa2SSuanming Mou 	}
268debb27eaSShiri Kuzin 	return 0;
269debb27eaSShiri Kuzin }
270debb27eaSShiri Kuzin 
271e8db4413SSuanming Mou static int
272a729d2f0SMichael Baum mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl *mkvlist,
273f12c41bfSRaja Zidane 			  struct mlx5_crypto_devarg_params *devarg_prms,
274f12c41bfSRaja Zidane 			  bool wrapped_mode)
275debb27eaSShiri Kuzin {
276e8db4413SSuanming Mou 	struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
277a729d2f0SMichael Baum 	const char **params = (const char *[]){
278a729d2f0SMichael Baum 		"credential_id",
279a729d2f0SMichael Baum 		"import_kek_id",
280a729d2f0SMichael Baum 		"keytag",
281a729d2f0SMichael Baum 		"max_segs_num",
282a729d2f0SMichael Baum 		"wcs_file",
283a729d2f0SMichael Baum 		NULL,
284a729d2f0SMichael Baum 	};
285debb27eaSShiri Kuzin 
286e8db4413SSuanming Mou 	/* Default values. */
287e8db4413SSuanming Mou 	attr->credential_pointer = 0;
288e8db4413SSuanming Mou 	attr->session_import_kek_ptr = 0;
289e8db4413SSuanming Mou 	devarg_prms->keytag = 0;
290a1978aa2SSuanming Mou 	devarg_prms->max_segs_num = 8;
291a729d2f0SMichael Baum 	if (mkvlist == NULL) {
292f12c41bfSRaja Zidane 		if (!wrapped_mode)
293f12c41bfSRaja Zidane 			return 0;
294debb27eaSShiri Kuzin 		DRV_LOG(ERR,
295debb27eaSShiri Kuzin 			"No login devargs in order to enable crypto operations in the device.");
296debb27eaSShiri Kuzin 		rte_errno = EINVAL;
297e8db4413SSuanming Mou 		return -1;
298debb27eaSShiri Kuzin 	}
299a729d2f0SMichael Baum 	if (mlx5_kvargs_process(mkvlist, params, mlx5_crypto_args_check_handler,
300e8db4413SSuanming Mou 				devarg_prms) != 0) {
301debb27eaSShiri Kuzin 		DRV_LOG(ERR, "Devargs handler function Failed.");
302debb27eaSShiri Kuzin 		rte_errno = EINVAL;
303e8db4413SSuanming Mou 		return -1;
304debb27eaSShiri Kuzin 	}
305f12c41bfSRaja Zidane 	if (devarg_prms->login_devarg == false && wrapped_mode) {
306debb27eaSShiri Kuzin 		DRV_LOG(ERR,
307f12c41bfSRaja Zidane 			"No login credential devarg in order to enable crypto operations in the device while in wrapped import method.");
308debb27eaSShiri Kuzin 		rte_errno = EINVAL;
309e8db4413SSuanming Mou 		return -1;
310debb27eaSShiri Kuzin 	}
311e8db4413SSuanming Mou 	return 0;
312debb27eaSShiri Kuzin }
313debb27eaSShiri Kuzin 
314a7c86884SShiri Kuzin static int
315a729d2f0SMichael Baum mlx5_crypto_dev_probe(struct mlx5_common_device *cdev,
316a729d2f0SMichael Baum 		      struct mlx5_kvargs_ctrl *mkvlist)
317a7c86884SShiri Kuzin {
318a7c86884SShiri Kuzin 	struct rte_cryptodev *crypto_dev;
319debb27eaSShiri Kuzin 	struct mlx5_devx_obj *login;
320a7c86884SShiri Kuzin 	struct mlx5_crypto_priv *priv;
321e8db4413SSuanming Mou 	struct mlx5_crypto_devarg_params devarg_prms = { 0 };
322a7c86884SShiri Kuzin 	struct rte_cryptodev_pmd_init_params init_params = {
323a7c86884SShiri Kuzin 		.name = "",
324a7c86884SShiri Kuzin 		.private_data_size = sizeof(struct mlx5_crypto_priv),
3257af08c8fSMichael Baum 		.socket_id = cdev->dev->numa_node,
326a7c86884SShiri Kuzin 		.max_nb_queue_pairs =
327a7c86884SShiri Kuzin 				RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
328a7c86884SShiri Kuzin 	};
329ca1418ceSMichael Baum 	const char *ibdev_name = mlx5_os_get_ctx_device_name(cdev->ctx);
330e8db4413SSuanming Mou 	int ret;
331f12c41bfSRaja Zidane 	bool wrapped_mode;
332e8db4413SSuanming Mou 
333a7c86884SShiri Kuzin 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
334a7c86884SShiri Kuzin 		DRV_LOG(ERR, "Non-primary process type is not supported.");
335a7c86884SShiri Kuzin 		rte_errno = ENOTSUP;
336a7c86884SShiri Kuzin 		return -rte_errno;
337a7c86884SShiri Kuzin 	}
338fe46b20cSMichael Baum 	if (!cdev->config.hca_attr.crypto || !cdev->config.hca_attr.aes_xts) {
339a7c86884SShiri Kuzin 		DRV_LOG(ERR, "Not enough capabilities to support crypto "
340a7c86884SShiri Kuzin 			"operations, maybe old FW/OFED version?");
341a7c86884SShiri Kuzin 		rte_errno = ENOTSUP;
342a7c86884SShiri Kuzin 		return -ENOTSUP;
343a7c86884SShiri Kuzin 	}
344f12c41bfSRaja Zidane 	wrapped_mode = !!cdev->config.hca_attr.crypto_wrapped_import_method;
345f12c41bfSRaja Zidane 	ret = mlx5_crypto_parse_devargs(mkvlist, &devarg_prms, wrapped_mode);
346e8db4413SSuanming Mou 	if (ret) {
347e8db4413SSuanming Mou 		DRV_LOG(ERR, "Failed to parse devargs.");
348e8db4413SSuanming Mou 		return -rte_errno;
349e8db4413SSuanming Mou 	}
350ca1418ceSMichael Baum 	crypto_dev = rte_cryptodev_pmd_create(ibdev_name, cdev->dev,
351a7c86884SShiri Kuzin 					      &init_params);
352a7c86884SShiri Kuzin 	if (crypto_dev == NULL) {
353ca1418ceSMichael Baum 		DRV_LOG(ERR, "Failed to create device \"%s\".", ibdev_name);
354a7c86884SShiri Kuzin 		return -ENODEV;
355a7c86884SShiri Kuzin 	}
356a7c86884SShiri Kuzin 	DRV_LOG(INFO,
357ca1418ceSMichael Baum 		"Crypto device %s was created successfully.", ibdev_name);
358a7c86884SShiri Kuzin 	crypto_dev->dev_ops = &mlx5_crypto_ops;
359f12c41bfSRaja Zidane 	crypto_dev->feature_flags = MLX5_CRYPTO_FEATURE_FLAGS(wrapped_mode);
360a7c86884SShiri Kuzin 	crypto_dev->driver_id = mlx5_crypto_driver_id;
361a7c86884SShiri Kuzin 	priv = crypto_dev->data->dev_private;
362ca1418ceSMichael Baum 	priv->cdev = cdev;
363a7c86884SShiri Kuzin 	priv->crypto_dev = crypto_dev;
364f12c41bfSRaja Zidane 	priv->is_wrapped_mode = wrapped_mode;
365*a27f6a2eSSuanming Mou 	priv->max_segs_num = devarg_prms.max_segs_num;
366*a27f6a2eSSuanming Mou 	ret = mlx5_crypto_xts_init(priv);
367*a27f6a2eSSuanming Mou 	if (ret) {
368*a27f6a2eSSuanming Mou 		DRV_LOG(ERR, "Failed to init AES-XTS crypto.");
369*a27f6a2eSSuanming Mou 		return -ENOTSUP;
370*a27f6a2eSSuanming Mou 	}
3715dfa003dSMichael Baum 	if (mlx5_devx_uar_prepare(cdev, &priv->uar) != 0) {
372a7c86884SShiri Kuzin 		rte_cryptodev_pmd_destroy(priv->crypto_dev);
373a7c86884SShiri Kuzin 		return -1;
374a7c86884SShiri Kuzin 	}
375f12c41bfSRaja Zidane 	if (wrapped_mode) {
376801b4885SMichael Baum 		login = mlx5_devx_cmd_create_crypto_login_obj(cdev->ctx,
377801b4885SMichael Baum 						      &devarg_prms.login_attr);
378801b4885SMichael Baum 		if (login == NULL) {
379801b4885SMichael Baum 			DRV_LOG(ERR, "Failed to configure login.");
3805dfa003dSMichael Baum 			mlx5_devx_uar_release(&priv->uar);
381801b4885SMichael Baum 			rte_cryptodev_pmd_destroy(priv->crypto_dev);
382801b4885SMichael Baum 			return -rte_errno;
383801b4885SMichael Baum 		}
384801b4885SMichael Baum 		priv->login_obj = login;
385f12c41bfSRaja Zidane 	}
386f12c41bfSRaja Zidane 	priv->keytag = rte_cpu_to_be_64(devarg_prms.keytag);
387ba707cdbSRaja Zidane 	DRV_LOG(INFO, "Max number of segments: %u.",
388ba707cdbSRaja Zidane 		(unsigned int)RTE_MIN(
389ba707cdbSRaja Zidane 			MLX5_CRYPTO_KLM_SEGS_NUM(priv->umr_wqe_size),
390ba707cdbSRaja Zidane 			(uint16_t)(priv->max_rdmar_ds - 2)));
391a7c86884SShiri Kuzin 	pthread_mutex_lock(&priv_list_lock);
392a7c86884SShiri Kuzin 	TAILQ_INSERT_TAIL(&mlx5_crypto_priv_list, priv, next);
393a7c86884SShiri Kuzin 	pthread_mutex_unlock(&priv_list_lock);
394d54c72ecSAkhil Goyal 
395d54c72ecSAkhil Goyal 	rte_cryptodev_pmd_probing_finish(crypto_dev);
396d54c72ecSAkhil Goyal 
397a7c86884SShiri Kuzin 	return 0;
398a7c86884SShiri Kuzin }
399a7c86884SShiri Kuzin 
400a7c86884SShiri Kuzin static int
4017af08c8fSMichael Baum mlx5_crypto_dev_remove(struct mlx5_common_device *cdev)
402a7c86884SShiri Kuzin {
403a7c86884SShiri Kuzin 	struct mlx5_crypto_priv *priv = NULL;
404a7c86884SShiri Kuzin 
405a7c86884SShiri Kuzin 	pthread_mutex_lock(&priv_list_lock);
406a7c86884SShiri Kuzin 	TAILQ_FOREACH(priv, &mlx5_crypto_priv_list, next)
4077af08c8fSMichael Baum 		if (priv->crypto_dev->device == cdev->dev)
408a7c86884SShiri Kuzin 			break;
409a7c86884SShiri Kuzin 	if (priv)
410a7c86884SShiri Kuzin 		TAILQ_REMOVE(&mlx5_crypto_priv_list, priv, next);
411a7c86884SShiri Kuzin 	pthread_mutex_unlock(&priv_list_lock);
412a7c86884SShiri Kuzin 	if (priv) {
413801b4885SMichael Baum 		claim_zero(mlx5_devx_cmd_destroy(priv->login_obj));
4145dfa003dSMichael Baum 		mlx5_devx_uar_release(&priv->uar);
415a7c86884SShiri Kuzin 		rte_cryptodev_pmd_destroy(priv->crypto_dev);
416a7c86884SShiri Kuzin 	}
417a7c86884SShiri Kuzin 	return 0;
418a7c86884SShiri Kuzin }
419a7c86884SShiri Kuzin 
420a7c86884SShiri Kuzin static const struct rte_pci_id mlx5_crypto_pci_id_map[] = {
421a7c86884SShiri Kuzin 		{
422a7c86884SShiri Kuzin 			RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
423a7c86884SShiri Kuzin 					PCI_DEVICE_ID_MELLANOX_CONNECTX6)
424a7c86884SShiri Kuzin 		},
425a7c86884SShiri Kuzin 		{
4264b2cc736SRaja Zidane 			RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
4274b2cc736SRaja Zidane 					PCI_DEVICE_ID_MELLANOX_CONNECTX6DX)
4284b2cc736SRaja Zidane 		},
4294b2cc736SRaja Zidane 		{
4304b2cc736SRaja Zidane 			RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
4310a9fff95SRaslan Darawsheh 					PCI_DEVICE_ID_MELLANOX_BLUEFIELD2)
4324b2cc736SRaja Zidane 		},
4334b2cc736SRaja Zidane 		{
434a0c33299SRaslan Darawsheh 			RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
435a0c33299SRaslan Darawsheh 					PCI_DEVICE_ID_MELLANOX_CONNECTX7)
436a0c33299SRaslan Darawsheh 		},
437a0c33299SRaslan Darawsheh 		{
438a0c33299SRaslan Darawsheh 			RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
439a0c33299SRaslan Darawsheh 					PCI_DEVICE_ID_MELLANOX_BLUEFIELD3)
440a0c33299SRaslan Darawsheh 		},
441a0c33299SRaslan Darawsheh 		{
442a7c86884SShiri Kuzin 			.vendor_id = 0
443a7c86884SShiri Kuzin 		}
444a7c86884SShiri Kuzin };
445a7c86884SShiri Kuzin 
44637d3bde4SXueming Li static struct mlx5_class_driver mlx5_crypto_driver = {
44737d3bde4SXueming Li 	.drv_class = MLX5_CLASS_CRYPTO,
448a7c86884SShiri Kuzin 	.name = RTE_STR(MLX5_CRYPTO_DRIVER_NAME),
449a7c86884SShiri Kuzin 	.id_table = mlx5_crypto_pci_id_map,
45037d3bde4SXueming Li 	.probe = mlx5_crypto_dev_probe,
45137d3bde4SXueming Li 	.remove = mlx5_crypto_dev_remove,
452a7c86884SShiri Kuzin };
453a7c86884SShiri Kuzin 
454a7c86884SShiri Kuzin RTE_INIT(rte_mlx5_crypto_init)
455a7c86884SShiri Kuzin {
4562f5dceffSTal Shnaiderman 	pthread_mutex_init(&priv_list_lock, NULL);
457a7c86884SShiri Kuzin 	mlx5_common_init();
458a7c86884SShiri Kuzin 	if (mlx5_glue != NULL)
45937d3bde4SXueming Li 		mlx5_class_driver_register(&mlx5_crypto_driver);
460a7c86884SShiri Kuzin }
461a7c86884SShiri Kuzin 
462a7c86884SShiri Kuzin RTE_PMD_REGISTER_CRYPTO_DRIVER(mlx5_cryptodev_driver, mlx5_drv,
463a7c86884SShiri Kuzin 			       mlx5_crypto_driver_id);
464a7c86884SShiri Kuzin 
465a7c86884SShiri Kuzin RTE_LOG_REGISTER_DEFAULT(mlx5_crypto_logtype, NOTICE)
466a7c86884SShiri Kuzin RTE_PMD_EXPORT_NAME(MLX5_CRYPTO_DRIVER_NAME, __COUNTER__);
467a7c86884SShiri Kuzin RTE_PMD_REGISTER_PCI_TABLE(MLX5_CRYPTO_DRIVER_NAME, mlx5_crypto_pci_id_map);
468a7c86884SShiri Kuzin RTE_PMD_REGISTER_KMOD_DEP(MLX5_CRYPTO_DRIVER_NAME, "* ib_uverbs & mlx5_core & mlx5_ib");
469