1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  * Copyright(c) 2015-2020 Intel Corporation
3a9643ea8Slogwang  */
4a9643ea8Slogwang 
5a9643ea8Slogwang #include <sys/types.h>
6a9643ea8Slogwang #include <sys/queue.h>
7a9643ea8Slogwang #include <ctype.h>
8a9643ea8Slogwang #include <stdio.h>
9a9643ea8Slogwang #include <stdlib.h>
10a9643ea8Slogwang #include <string.h>
11a9643ea8Slogwang #include <stdarg.h>
12a9643ea8Slogwang #include <errno.h>
13a9643ea8Slogwang #include <stdint.h>
14a9643ea8Slogwang #include <inttypes.h>
15a9643ea8Slogwang #include <netinet/in.h>
16a9643ea8Slogwang 
17a9643ea8Slogwang #include <rte_byteorder.h>
18a9643ea8Slogwang #include <rte_log.h>
19a9643ea8Slogwang #include <rte_debug.h>
20a9643ea8Slogwang #include <rte_dev.h>
21a9643ea8Slogwang #include <rte_interrupts.h>
22a9643ea8Slogwang #include <rte_memory.h>
23a9643ea8Slogwang #include <rte_memcpy.h>
24a9643ea8Slogwang #include <rte_memzone.h>
25a9643ea8Slogwang #include <rte_launch.h>
26a9643ea8Slogwang #include <rte_tailq.h>
27a9643ea8Slogwang #include <rte_eal.h>
28a9643ea8Slogwang #include <rte_per_lcore.h>
29a9643ea8Slogwang #include <rte_lcore.h>
30a9643ea8Slogwang #include <rte_atomic.h>
31a9643ea8Slogwang #include <rte_branch_prediction.h>
32a9643ea8Slogwang #include <rte_common.h>
33a9643ea8Slogwang #include <rte_mempool.h>
34a9643ea8Slogwang #include <rte_malloc.h>
35a9643ea8Slogwang #include <rte_mbuf.h>
36a9643ea8Slogwang #include <rte_errno.h>
37a9643ea8Slogwang #include <rte_spinlock.h>
38a9643ea8Slogwang #include <rte_string_fns.h>
39a9643ea8Slogwang 
40a9643ea8Slogwang #include "rte_crypto.h"
41a9643ea8Slogwang #include "rte_cryptodev.h"
42a9643ea8Slogwang #include "rte_cryptodev_pmd.h"
43*2d9fd380Sjfb8856606 #include "rte_cryptodev_trace.h"
44a9643ea8Slogwang 
452bfe3f2eSlogwang static uint8_t nb_drivers;
462bfe3f2eSlogwang 
47d30ea906Sjfb8856606 static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
48a9643ea8Slogwang 
49d30ea906Sjfb8856606 struct rte_cryptodev *rte_cryptodevs = rte_crypto_devices;
50a9643ea8Slogwang 
51a9643ea8Slogwang static struct rte_cryptodev_global cryptodev_globals = {
52d30ea906Sjfb8856606 		.devs			= rte_crypto_devices,
53a9643ea8Slogwang 		.data			= { NULL },
544418919fSjohnjiang 		.nb_devs		= 0
55a9643ea8Slogwang };
56a9643ea8Slogwang 
57a9643ea8Slogwang /* spinlock for crypto device callbacks */
58a9643ea8Slogwang static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
59a9643ea8Slogwang 
60a9643ea8Slogwang /**
61a9643ea8Slogwang  * The user application callback description.
62a9643ea8Slogwang  *
63a9643ea8Slogwang  * It contains callback address to be registered by user application,
64a9643ea8Slogwang  * the pointer to the parameters for callback, and the event type.
65a9643ea8Slogwang  */
66a9643ea8Slogwang struct rte_cryptodev_callback {
67a9643ea8Slogwang 	TAILQ_ENTRY(rte_cryptodev_callback) next; /**< Callbacks list */
68a9643ea8Slogwang 	rte_cryptodev_cb_fn cb_fn;		/**< Callback address */
69a9643ea8Slogwang 	void *cb_arg;				/**< Parameter for callback */
70a9643ea8Slogwang 	enum rte_cryptodev_event_type event;	/**< Interrupt event type */
71a9643ea8Slogwang 	uint32_t active;			/**< Callback is executing */
72a9643ea8Slogwang };
73a9643ea8Slogwang 
742bfe3f2eSlogwang /**
752bfe3f2eSlogwang  * The crypto cipher algorithm strings identifiers.
762bfe3f2eSlogwang  * It could be used in application command line.
772bfe3f2eSlogwang  */
782bfe3f2eSlogwang const char *
792bfe3f2eSlogwang rte_crypto_cipher_algorithm_strings[] = {
802bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_3DES_CBC]	= "3des-cbc",
812bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_3DES_ECB]	= "3des-ecb",
822bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_3DES_CTR]	= "3des-ctr",
83a9643ea8Slogwang 
842bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_AES_CBC]	= "aes-cbc",
852bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_AES_CTR]	= "aes-ctr",
862bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_AES_DOCSISBPI]	= "aes-docsisbpi",
872bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_AES_ECB]	= "aes-ecb",
882bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_AES_F8]	= "aes-f8",
892bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_AES_XTS]	= "aes-xts",
902bfe3f2eSlogwang 
912bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_ARC4]	= "arc4",
922bfe3f2eSlogwang 
932bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_DES_CBC]     = "des-cbc",
942bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_DES_DOCSISBPI]	= "des-docsisbpi",
952bfe3f2eSlogwang 
962bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_NULL]	= "null",
972bfe3f2eSlogwang 
982bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_KASUMI_F8]	= "kasumi-f8",
992bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_SNOW3G_UEA2]	= "snow3g-uea2",
1002bfe3f2eSlogwang 	[RTE_CRYPTO_CIPHER_ZUC_EEA3]	= "zuc-eea3"
101a9643ea8Slogwang };
102a9643ea8Slogwang 
1032bfe3f2eSlogwang /**
1042bfe3f2eSlogwang  * The crypto cipher operation strings identifiers.
1052bfe3f2eSlogwang  * It could be used in application command line.
1062bfe3f2eSlogwang  */
1072bfe3f2eSlogwang const char *
1082bfe3f2eSlogwang rte_crypto_cipher_operation_strings[] = {
1092bfe3f2eSlogwang 		[RTE_CRYPTO_CIPHER_OP_ENCRYPT]	= "encrypt",
1102bfe3f2eSlogwang 		[RTE_CRYPTO_CIPHER_OP_DECRYPT]	= "decrypt"
1112bfe3f2eSlogwang };
112a9643ea8Slogwang 
1132bfe3f2eSlogwang /**
1142bfe3f2eSlogwang  * The crypto auth algorithm strings identifiers.
1152bfe3f2eSlogwang  * It could be used in application command line.
1162bfe3f2eSlogwang  */
1172bfe3f2eSlogwang const char *
1182bfe3f2eSlogwang rte_crypto_auth_algorithm_strings[] = {
1192bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_AES_CBC_MAC]	= "aes-cbc-mac",
1202bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_AES_CMAC]	= "aes-cmac",
1212bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_AES_GMAC]	= "aes-gmac",
1222bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_AES_XCBC_MAC]	= "aes-xcbc-mac",
1232bfe3f2eSlogwang 
1242bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_MD5]		= "md5",
1252bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_MD5_HMAC]	= "md5-hmac",
1262bfe3f2eSlogwang 
1272bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_NULL]		= "null",
1282bfe3f2eSlogwang 
1292bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA1]		= "sha1",
1302bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA1_HMAC]	= "sha1-hmac",
1312bfe3f2eSlogwang 
1322bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA224]	= "sha2-224",
1332bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA224_HMAC]	= "sha2-224-hmac",
1342bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA256]	= "sha2-256",
1352bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA256_HMAC]	= "sha2-256-hmac",
1362bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA384]	= "sha2-384",
1372bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA384_HMAC]	= "sha2-384-hmac",
1382bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA512]	= "sha2-512",
1392bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SHA512_HMAC]	= "sha2-512-hmac",
1402bfe3f2eSlogwang 
1412bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_KASUMI_F9]	= "kasumi-f9",
1422bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_SNOW3G_UIA2]	= "snow3g-uia2",
1432bfe3f2eSlogwang 	[RTE_CRYPTO_AUTH_ZUC_EIA3]	= "zuc-eia3"
1442bfe3f2eSlogwang };
1452bfe3f2eSlogwang 
1462bfe3f2eSlogwang /**
1472bfe3f2eSlogwang  * The crypto AEAD algorithm strings identifiers.
1482bfe3f2eSlogwang  * It could be used in application command line.
1492bfe3f2eSlogwang  */
1502bfe3f2eSlogwang const char *
1512bfe3f2eSlogwang rte_crypto_aead_algorithm_strings[] = {
1522bfe3f2eSlogwang 	[RTE_CRYPTO_AEAD_AES_CCM]	= "aes-ccm",
1532bfe3f2eSlogwang 	[RTE_CRYPTO_AEAD_AES_GCM]	= "aes-gcm",
154*2d9fd380Sjfb8856606 	[RTE_CRYPTO_AEAD_CHACHA20_POLY1305] = "chacha20-poly1305"
1552bfe3f2eSlogwang };
1562bfe3f2eSlogwang 
1572bfe3f2eSlogwang /**
1582bfe3f2eSlogwang  * The crypto AEAD operation strings identifiers.
1592bfe3f2eSlogwang  * It could be used in application command line.
1602bfe3f2eSlogwang  */
1612bfe3f2eSlogwang const char *
1622bfe3f2eSlogwang rte_crypto_aead_operation_strings[] = {
1632bfe3f2eSlogwang 	[RTE_CRYPTO_AEAD_OP_ENCRYPT]	= "encrypt",
1642bfe3f2eSlogwang 	[RTE_CRYPTO_AEAD_OP_DECRYPT]	= "decrypt"
1652bfe3f2eSlogwang };
1662bfe3f2eSlogwang 
167d30ea906Sjfb8856606 /**
168d30ea906Sjfb8856606  * Asymmetric crypto transform operation strings identifiers.
169d30ea906Sjfb8856606  */
170d30ea906Sjfb8856606 const char *rte_crypto_asym_xform_strings[] = {
171d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_NONE]	= "none",
172d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_RSA]	= "rsa",
173d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_MODEX]	= "modexp",
174d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
175d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
176d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
177*2d9fd380Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
178*2d9fd380Sjfb8856606 	[RTE_CRYPTO_ASYM_XFORM_ECPM]	= "ecpm",
179d30ea906Sjfb8856606 };
180d30ea906Sjfb8856606 
181d30ea906Sjfb8856606 /**
182d30ea906Sjfb8856606  * Asymmetric crypto operation strings identifiers.
183d30ea906Sjfb8856606  */
184d30ea906Sjfb8856606 const char *rte_crypto_asym_op_strings[] = {
185d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_ENCRYPT]	= "encrypt",
186d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_DECRYPT]	= "decrypt",
187d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_SIGN]	= "sign",
188d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_VERIFY]	= "verify",
189d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_PRIVATE_KEY_GENERATE]	= "priv_key_generate",
190d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE] = "pub_key_generate",
191d30ea906Sjfb8856606 	[RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE] = "sharedsecret_compute",
192d30ea906Sjfb8856606 };
193d30ea906Sjfb8856606 
1944418919fSjohnjiang /**
1954418919fSjohnjiang  * The private data structure stored in the session mempool private data.
1964418919fSjohnjiang  */
1974418919fSjohnjiang struct rte_cryptodev_sym_session_pool_private_data {
1984418919fSjohnjiang 	uint16_t nb_drivers;
1994418919fSjohnjiang 	/**< number of elements in sess_data array */
2004418919fSjohnjiang 	uint16_t user_data_sz;
2014418919fSjohnjiang 	/**< session user data will be placed after sess_data */
2024418919fSjohnjiang };
2034418919fSjohnjiang 
2042bfe3f2eSlogwang int
rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm * algo_enum,const char * algo_string)2052bfe3f2eSlogwang rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
2062bfe3f2eSlogwang 		const char *algo_string)
2072bfe3f2eSlogwang {
2082bfe3f2eSlogwang 	unsigned int i;
2092bfe3f2eSlogwang 
2102bfe3f2eSlogwang 	for (i = 1; i < RTE_DIM(rte_crypto_cipher_algorithm_strings); i++) {
2112bfe3f2eSlogwang 		if (strcmp(algo_string, rte_crypto_cipher_algorithm_strings[i]) == 0) {
2122bfe3f2eSlogwang 			*algo_enum = (enum rte_crypto_cipher_algorithm) i;
2132bfe3f2eSlogwang 			return 0;
2142bfe3f2eSlogwang 		}
215a9643ea8Slogwang 	}
216a9643ea8Slogwang 
2172bfe3f2eSlogwang 	/* Invalid string */
218a9643ea8Slogwang 	return -1;
219a9643ea8Slogwang }
220a9643ea8Slogwang 
2212bfe3f2eSlogwang int
rte_cryptodev_get_auth_algo_enum(enum rte_crypto_auth_algorithm * algo_enum,const char * algo_string)2222bfe3f2eSlogwang rte_cryptodev_get_auth_algo_enum(enum rte_crypto_auth_algorithm *algo_enum,
2232bfe3f2eSlogwang 		const char *algo_string)
2242bfe3f2eSlogwang {
2252bfe3f2eSlogwang 	unsigned int i;
2262bfe3f2eSlogwang 
2272bfe3f2eSlogwang 	for (i = 1; i < RTE_DIM(rte_crypto_auth_algorithm_strings); i++) {
2282bfe3f2eSlogwang 		if (strcmp(algo_string, rte_crypto_auth_algorithm_strings[i]) == 0) {
2292bfe3f2eSlogwang 			*algo_enum = (enum rte_crypto_auth_algorithm) i;
2302bfe3f2eSlogwang 			return 0;
2312bfe3f2eSlogwang 		}
2322bfe3f2eSlogwang 	}
2332bfe3f2eSlogwang 
2342bfe3f2eSlogwang 	/* Invalid string */
2352bfe3f2eSlogwang 	return -1;
2362bfe3f2eSlogwang }
2372bfe3f2eSlogwang 
2382bfe3f2eSlogwang int
rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm * algo_enum,const char * algo_string)2392bfe3f2eSlogwang rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm *algo_enum,
2402bfe3f2eSlogwang 		const char *algo_string)
2412bfe3f2eSlogwang {
2422bfe3f2eSlogwang 	unsigned int i;
2432bfe3f2eSlogwang 
2442bfe3f2eSlogwang 	for (i = 1; i < RTE_DIM(rte_crypto_aead_algorithm_strings); i++) {
2452bfe3f2eSlogwang 		if (strcmp(algo_string, rte_crypto_aead_algorithm_strings[i]) == 0) {
2462bfe3f2eSlogwang 			*algo_enum = (enum rte_crypto_aead_algorithm) i;
2472bfe3f2eSlogwang 			return 0;
2482bfe3f2eSlogwang 		}
2492bfe3f2eSlogwang 	}
2502bfe3f2eSlogwang 
2512bfe3f2eSlogwang 	/* Invalid string */
2522bfe3f2eSlogwang 	return -1;
2532bfe3f2eSlogwang }
2542bfe3f2eSlogwang 
2554418919fSjohnjiang int
rte_cryptodev_asym_get_xform_enum(enum rte_crypto_asym_xform_type * xform_enum,const char * xform_string)256d30ea906Sjfb8856606 rte_cryptodev_asym_get_xform_enum(enum rte_crypto_asym_xform_type *xform_enum,
257d30ea906Sjfb8856606 		const char *xform_string)
258d30ea906Sjfb8856606 {
259d30ea906Sjfb8856606 	unsigned int i;
260d30ea906Sjfb8856606 
261d30ea906Sjfb8856606 	for (i = 1; i < RTE_DIM(rte_crypto_asym_xform_strings); i++) {
262d30ea906Sjfb8856606 		if (strcmp(xform_string,
263d30ea906Sjfb8856606 			rte_crypto_asym_xform_strings[i]) == 0) {
264d30ea906Sjfb8856606 			*xform_enum = (enum rte_crypto_asym_xform_type) i;
265d30ea906Sjfb8856606 			return 0;
266d30ea906Sjfb8856606 		}
267d30ea906Sjfb8856606 	}
268d30ea906Sjfb8856606 
269d30ea906Sjfb8856606 	/* Invalid string */
270d30ea906Sjfb8856606 	return -1;
271d30ea906Sjfb8856606 }
272d30ea906Sjfb8856606 
2732bfe3f2eSlogwang /**
2742bfe3f2eSlogwang  * The crypto auth operation strings identifiers.
2752bfe3f2eSlogwang  * It could be used in application command line.
2762bfe3f2eSlogwang  */
2772bfe3f2eSlogwang const char *
2782bfe3f2eSlogwang rte_crypto_auth_operation_strings[] = {
2792bfe3f2eSlogwang 		[RTE_CRYPTO_AUTH_OP_VERIFY]	= "verify",
2802bfe3f2eSlogwang 		[RTE_CRYPTO_AUTH_OP_GENERATE]	= "generate"
2812bfe3f2eSlogwang };
2822bfe3f2eSlogwang 
2832bfe3f2eSlogwang const struct rte_cryptodev_symmetric_capability *
rte_cryptodev_sym_capability_get(uint8_t dev_id,const struct rte_cryptodev_sym_capability_idx * idx)2842bfe3f2eSlogwang rte_cryptodev_sym_capability_get(uint8_t dev_id,
2852bfe3f2eSlogwang 		const struct rte_cryptodev_sym_capability_idx *idx)
2862bfe3f2eSlogwang {
2872bfe3f2eSlogwang 	const struct rte_cryptodev_capabilities *capability;
2882bfe3f2eSlogwang 	struct rte_cryptodev_info dev_info;
2892bfe3f2eSlogwang 	int i = 0;
2902bfe3f2eSlogwang 
2912bfe3f2eSlogwang 	rte_cryptodev_info_get(dev_id, &dev_info);
2922bfe3f2eSlogwang 
2932bfe3f2eSlogwang 	while ((capability = &dev_info.capabilities[i++])->op !=
2942bfe3f2eSlogwang 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
2952bfe3f2eSlogwang 		if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
2962bfe3f2eSlogwang 			continue;
2972bfe3f2eSlogwang 
2982bfe3f2eSlogwang 		if (capability->sym.xform_type != idx->type)
2992bfe3f2eSlogwang 			continue;
3002bfe3f2eSlogwang 
3012bfe3f2eSlogwang 		if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
3022bfe3f2eSlogwang 			capability->sym.auth.algo == idx->algo.auth)
3032bfe3f2eSlogwang 			return &capability->sym;
3042bfe3f2eSlogwang 
3052bfe3f2eSlogwang 		if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
3062bfe3f2eSlogwang 			capability->sym.cipher.algo == idx->algo.cipher)
3072bfe3f2eSlogwang 			return &capability->sym;
3082bfe3f2eSlogwang 
3092bfe3f2eSlogwang 		if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD &&
3102bfe3f2eSlogwang 				capability->sym.aead.algo == idx->algo.aead)
3112bfe3f2eSlogwang 			return &capability->sym;
3122bfe3f2eSlogwang 	}
3132bfe3f2eSlogwang 
3142bfe3f2eSlogwang 	return NULL;
3152bfe3f2eSlogwang }
3162bfe3f2eSlogwang 
317579bf1e2Sjfb8856606 static int
param_range_check(uint16_t size,const struct rte_crypto_param_range * range)318579bf1e2Sjfb8856606 param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
319579bf1e2Sjfb8856606 {
320579bf1e2Sjfb8856606 	unsigned int next_size;
321579bf1e2Sjfb8856606 
322579bf1e2Sjfb8856606 	/* Check lower/upper bounds */
323579bf1e2Sjfb8856606 	if (size < range->min)
324579bf1e2Sjfb8856606 		return -1;
325579bf1e2Sjfb8856606 
326579bf1e2Sjfb8856606 	if (size > range->max)
327579bf1e2Sjfb8856606 		return -1;
328579bf1e2Sjfb8856606 
329579bf1e2Sjfb8856606 	/* If range is actually only one value, size is correct */
330579bf1e2Sjfb8856606 	if (range->increment == 0)
331579bf1e2Sjfb8856606 		return 0;
332579bf1e2Sjfb8856606 
333579bf1e2Sjfb8856606 	/* Check if value is one of the supported sizes */
334579bf1e2Sjfb8856606 	for (next_size = range->min; next_size <= range->max;
335579bf1e2Sjfb8856606 			next_size += range->increment)
336579bf1e2Sjfb8856606 		if (size == next_size)
337579bf1e2Sjfb8856606 			return 0;
338579bf1e2Sjfb8856606 
339579bf1e2Sjfb8856606 	return -1;
340579bf1e2Sjfb8856606 }
3412bfe3f2eSlogwang 
3424418919fSjohnjiang const struct rte_cryptodev_asymmetric_xform_capability *
rte_cryptodev_asym_capability_get(uint8_t dev_id,const struct rte_cryptodev_asym_capability_idx * idx)343d30ea906Sjfb8856606 rte_cryptodev_asym_capability_get(uint8_t dev_id,
344d30ea906Sjfb8856606 		const struct rte_cryptodev_asym_capability_idx *idx)
345d30ea906Sjfb8856606 {
346d30ea906Sjfb8856606 	const struct rte_cryptodev_capabilities *capability;
347d30ea906Sjfb8856606 	struct rte_cryptodev_info dev_info;
348d30ea906Sjfb8856606 	unsigned int i = 0;
349d30ea906Sjfb8856606 
350d30ea906Sjfb8856606 	memset(&dev_info, 0, sizeof(struct rte_cryptodev_info));
351d30ea906Sjfb8856606 	rte_cryptodev_info_get(dev_id, &dev_info);
352d30ea906Sjfb8856606 
353d30ea906Sjfb8856606 	while ((capability = &dev_info.capabilities[i++])->op !=
354d30ea906Sjfb8856606 			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
355d30ea906Sjfb8856606 		if (capability->op != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
356d30ea906Sjfb8856606 			continue;
357d30ea906Sjfb8856606 
358d30ea906Sjfb8856606 		if (capability->asym.xform_capa.xform_type == idx->type)
359d30ea906Sjfb8856606 			return &capability->asym.xform_capa;
360d30ea906Sjfb8856606 	}
361d30ea906Sjfb8856606 	return NULL;
362d30ea906Sjfb8856606 };
363d30ea906Sjfb8856606 
3642bfe3f2eSlogwang int
rte_cryptodev_sym_capability_check_cipher(const struct rte_cryptodev_symmetric_capability * capability,uint16_t key_size,uint16_t iv_size)3652bfe3f2eSlogwang rte_cryptodev_sym_capability_check_cipher(
3662bfe3f2eSlogwang 		const struct rte_cryptodev_symmetric_capability *capability,
3672bfe3f2eSlogwang 		uint16_t key_size, uint16_t iv_size)
3682bfe3f2eSlogwang {
369579bf1e2Sjfb8856606 	if (param_range_check(key_size, &capability->cipher.key_size) != 0)
3702bfe3f2eSlogwang 		return -1;
3712bfe3f2eSlogwang 
372579bf1e2Sjfb8856606 	if (param_range_check(iv_size, &capability->cipher.iv_size) != 0)
3732bfe3f2eSlogwang 		return -1;
3742bfe3f2eSlogwang 
375a9643ea8Slogwang 	return 0;
376a9643ea8Slogwang }
377a9643ea8Slogwang 
378a9643ea8Slogwang int
rte_cryptodev_sym_capability_check_auth(const struct rte_cryptodev_symmetric_capability * capability,uint16_t key_size,uint16_t digest_size,uint16_t iv_size)3792bfe3f2eSlogwang rte_cryptodev_sym_capability_check_auth(
3802bfe3f2eSlogwang 		const struct rte_cryptodev_symmetric_capability *capability,
3812bfe3f2eSlogwang 		uint16_t key_size, uint16_t digest_size, uint16_t iv_size)
382a9643ea8Slogwang {
383579bf1e2Sjfb8856606 	if (param_range_check(key_size, &capability->auth.key_size) != 0)
384a9643ea8Slogwang 		return -1;
385a9643ea8Slogwang 
386579bf1e2Sjfb8856606 	if (param_range_check(digest_size, &capability->auth.digest_size) != 0)
3872bfe3f2eSlogwang 		return -1;
388a9643ea8Slogwang 
389579bf1e2Sjfb8856606 	if (param_range_check(iv_size, &capability->auth.iv_size) != 0)
3902bfe3f2eSlogwang 		return -1;
391a9643ea8Slogwang 
3922bfe3f2eSlogwang 	return 0;
393a9643ea8Slogwang }
394a9643ea8Slogwang 
3952bfe3f2eSlogwang int
rte_cryptodev_sym_capability_check_aead(const struct rte_cryptodev_symmetric_capability * capability,uint16_t key_size,uint16_t digest_size,uint16_t aad_size,uint16_t iv_size)3962bfe3f2eSlogwang rte_cryptodev_sym_capability_check_aead(
3972bfe3f2eSlogwang 		const struct rte_cryptodev_symmetric_capability *capability,
3982bfe3f2eSlogwang 		uint16_t key_size, uint16_t digest_size, uint16_t aad_size,
3992bfe3f2eSlogwang 		uint16_t iv_size)
4002bfe3f2eSlogwang {
401579bf1e2Sjfb8856606 	if (param_range_check(key_size, &capability->aead.key_size) != 0)
4022bfe3f2eSlogwang 		return -1;
4032bfe3f2eSlogwang 
404579bf1e2Sjfb8856606 	if (param_range_check(digest_size, &capability->aead.digest_size) != 0)
4052bfe3f2eSlogwang 		return -1;
4062bfe3f2eSlogwang 
407579bf1e2Sjfb8856606 	if (param_range_check(aad_size, &capability->aead.aad_size) != 0)
4082bfe3f2eSlogwang 		return -1;
4092bfe3f2eSlogwang 
410579bf1e2Sjfb8856606 	if (param_range_check(iv_size, &capability->aead.iv_size) != 0)
4112bfe3f2eSlogwang 		return -1;
4122bfe3f2eSlogwang 
4132bfe3f2eSlogwang 	return 0;
414a9643ea8Slogwang }
4154418919fSjohnjiang int
rte_cryptodev_asym_xform_capability_check_optype(const struct rte_cryptodev_asymmetric_xform_capability * capability,enum rte_crypto_asym_op_type op_type)416d30ea906Sjfb8856606 rte_cryptodev_asym_xform_capability_check_optype(
417d30ea906Sjfb8856606 	const struct rte_cryptodev_asymmetric_xform_capability *capability,
418d30ea906Sjfb8856606 	enum rte_crypto_asym_op_type op_type)
419d30ea906Sjfb8856606 {
420d30ea906Sjfb8856606 	if (capability->op_types & (1 << op_type))
421d30ea906Sjfb8856606 		return 1;
422d30ea906Sjfb8856606 
423d30ea906Sjfb8856606 	return 0;
424d30ea906Sjfb8856606 }
425d30ea906Sjfb8856606 
4264418919fSjohnjiang int
rte_cryptodev_asym_xform_capability_check_modlen(const struct rte_cryptodev_asymmetric_xform_capability * capability,uint16_t modlen)427d30ea906Sjfb8856606 rte_cryptodev_asym_xform_capability_check_modlen(
428d30ea906Sjfb8856606 	const struct rte_cryptodev_asymmetric_xform_capability *capability,
429d30ea906Sjfb8856606 	uint16_t modlen)
430d30ea906Sjfb8856606 {
431d30ea906Sjfb8856606 	/* no need to check for limits, if min or max = 0 */
432d30ea906Sjfb8856606 	if (capability->modlen.min != 0) {
433d30ea906Sjfb8856606 		if (modlen < capability->modlen.min)
434d30ea906Sjfb8856606 			return -1;
435d30ea906Sjfb8856606 	}
436d30ea906Sjfb8856606 
437d30ea906Sjfb8856606 	if (capability->modlen.max != 0) {
438d30ea906Sjfb8856606 		if (modlen > capability->modlen.max)
439d30ea906Sjfb8856606 			return -1;
440d30ea906Sjfb8856606 	}
441d30ea906Sjfb8856606 
442d30ea906Sjfb8856606 	/* in any case, check if given modlen is module increment */
443d30ea906Sjfb8856606 	if (capability->modlen.increment != 0) {
444d30ea906Sjfb8856606 		if (modlen % (capability->modlen.increment))
445d30ea906Sjfb8856606 			return -1;
446d30ea906Sjfb8856606 	}
447d30ea906Sjfb8856606 
448d30ea906Sjfb8856606 	return 0;
449d30ea906Sjfb8856606 }
450d30ea906Sjfb8856606 
451a9643ea8Slogwang 
452a9643ea8Slogwang const char *
rte_cryptodev_get_feature_name(uint64_t flag)453a9643ea8Slogwang rte_cryptodev_get_feature_name(uint64_t flag)
454a9643ea8Slogwang {
455a9643ea8Slogwang 	switch (flag) {
456a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO:
457a9643ea8Slogwang 		return "SYMMETRIC_CRYPTO";
458a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO:
459a9643ea8Slogwang 		return "ASYMMETRIC_CRYPTO";
460a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING:
461a9643ea8Slogwang 		return "SYM_OPERATION_CHAINING";
462a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_CPU_SSE:
463a9643ea8Slogwang 		return "CPU_SSE";
464a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_CPU_AVX:
465a9643ea8Slogwang 		return "CPU_AVX";
466a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_CPU_AVX2:
467a9643ea8Slogwang 		return "CPU_AVX2";
4682bfe3f2eSlogwang 	case RTE_CRYPTODEV_FF_CPU_AVX512:
4692bfe3f2eSlogwang 		return "CPU_AVX512";
470a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_CPU_AESNI:
471a9643ea8Slogwang 		return "CPU_AESNI";
472a9643ea8Slogwang 	case RTE_CRYPTODEV_FF_HW_ACCELERATED:
473a9643ea8Slogwang 		return "HW_ACCELERATED";
474d30ea906Sjfb8856606 	case RTE_CRYPTODEV_FF_IN_PLACE_SGL:
475d30ea906Sjfb8856606 		return "IN_PLACE_SGL";
476d30ea906Sjfb8856606 	case RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT:
477d30ea906Sjfb8856606 		return "OOP_SGL_IN_SGL_OUT";
478d30ea906Sjfb8856606 	case RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT:
479d30ea906Sjfb8856606 		return "OOP_SGL_IN_LB_OUT";
480d30ea906Sjfb8856606 	case RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT:
481d30ea906Sjfb8856606 		return "OOP_LB_IN_SGL_OUT";
482d30ea906Sjfb8856606 	case RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT:
483d30ea906Sjfb8856606 		return "OOP_LB_IN_LB_OUT";
4842bfe3f2eSlogwang 	case RTE_CRYPTODEV_FF_CPU_NEON:
4852bfe3f2eSlogwang 		return "CPU_NEON";
4862bfe3f2eSlogwang 	case RTE_CRYPTODEV_FF_CPU_ARM_CE:
4872bfe3f2eSlogwang 		return "CPU_ARM_CE";
488d30ea906Sjfb8856606 	case RTE_CRYPTODEV_FF_SECURITY:
489d30ea906Sjfb8856606 		return "SECURITY_PROTOCOL";
4904418919fSjohnjiang 	case RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP:
4914418919fSjohnjiang 		return "RSA_PRIV_OP_KEY_EXP";
4924418919fSjohnjiang 	case RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT:
4934418919fSjohnjiang 		return "RSA_PRIV_OP_KEY_QT";
4944418919fSjohnjiang 	case RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED:
4954418919fSjohnjiang 		return "DIGEST_ENCRYPTED";
496*2d9fd380Sjfb8856606 	case RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO:
497*2d9fd380Sjfb8856606 		return "SYM_CPU_CRYPTO";
4980c6bd470Sfengbojiang 	case RTE_CRYPTODEV_FF_ASYM_SESSIONLESS:
4990c6bd470Sfengbojiang 		return "ASYM_SESSIONLESS";
500*2d9fd380Sjfb8856606 	case RTE_CRYPTODEV_FF_SYM_SESSIONLESS:
501*2d9fd380Sjfb8856606 		return "SYM_SESSIONLESS";
502*2d9fd380Sjfb8856606 	case RTE_CRYPTODEV_FF_NON_BYTE_ALIGNED_DATA:
503*2d9fd380Sjfb8856606 		return "NON_BYTE_ALIGNED_DATA";
504a9643ea8Slogwang 	default:
505a9643ea8Slogwang 		return NULL;
506a9643ea8Slogwang 	}
507a9643ea8Slogwang }
508a9643ea8Slogwang 
5092bfe3f2eSlogwang struct rte_cryptodev *
rte_cryptodev_pmd_get_dev(uint8_t dev_id)5102bfe3f2eSlogwang rte_cryptodev_pmd_get_dev(uint8_t dev_id)
511a9643ea8Slogwang {
512d30ea906Sjfb8856606 	return &cryptodev_globals.devs[dev_id];
513a9643ea8Slogwang }
514a9643ea8Slogwang 
5152bfe3f2eSlogwang struct rte_cryptodev *
rte_cryptodev_pmd_get_named_dev(const char * name)5162bfe3f2eSlogwang rte_cryptodev_pmd_get_named_dev(const char *name)
5172bfe3f2eSlogwang {
5182bfe3f2eSlogwang 	struct rte_cryptodev *dev;
5192bfe3f2eSlogwang 	unsigned int i;
5202bfe3f2eSlogwang 
5212bfe3f2eSlogwang 	if (name == NULL)
5222bfe3f2eSlogwang 		return NULL;
5232bfe3f2eSlogwang 
5244418919fSjohnjiang 	for (i = 0; i < RTE_CRYPTO_MAX_DEVS; i++) {
525d30ea906Sjfb8856606 		dev = &cryptodev_globals.devs[i];
5262bfe3f2eSlogwang 
5272bfe3f2eSlogwang 		if ((dev->attached == RTE_CRYPTODEV_ATTACHED) &&
5282bfe3f2eSlogwang 				(strcmp(dev->data->name, name) == 0))
5292bfe3f2eSlogwang 			return dev;
5302bfe3f2eSlogwang 	}
5312bfe3f2eSlogwang 
5322bfe3f2eSlogwang 	return NULL;
5332bfe3f2eSlogwang }
5342bfe3f2eSlogwang 
5354418919fSjohnjiang static inline uint8_t
rte_cryptodev_is_valid_device_data(uint8_t dev_id)5364418919fSjohnjiang rte_cryptodev_is_valid_device_data(uint8_t dev_id)
5374418919fSjohnjiang {
5380c6bd470Sfengbojiang 	if (dev_id >= RTE_CRYPTO_MAX_DEVS ||
5390c6bd470Sfengbojiang 			rte_crypto_devices[dev_id].data == NULL)
5404418919fSjohnjiang 		return 0;
5414418919fSjohnjiang 
5424418919fSjohnjiang 	return 1;
5434418919fSjohnjiang }
5444418919fSjohnjiang 
5452bfe3f2eSlogwang unsigned int
rte_cryptodev_pmd_is_valid_dev(uint8_t dev_id)5462bfe3f2eSlogwang rte_cryptodev_pmd_is_valid_dev(uint8_t dev_id)
5472bfe3f2eSlogwang {
5482bfe3f2eSlogwang 	struct rte_cryptodev *dev = NULL;
5492bfe3f2eSlogwang 
5504418919fSjohnjiang 	if (!rte_cryptodev_is_valid_device_data(dev_id))
5512bfe3f2eSlogwang 		return 0;
5522bfe3f2eSlogwang 
5532bfe3f2eSlogwang 	dev = rte_cryptodev_pmd_get_dev(dev_id);
5542bfe3f2eSlogwang 	if (dev->attached != RTE_CRYPTODEV_ATTACHED)
5552bfe3f2eSlogwang 		return 0;
5562bfe3f2eSlogwang 	else
5572bfe3f2eSlogwang 		return 1;
5582bfe3f2eSlogwang }
5592bfe3f2eSlogwang 
5602bfe3f2eSlogwang 
561a9643ea8Slogwang int
rte_cryptodev_get_dev_id(const char * name)5622bfe3f2eSlogwang rte_cryptodev_get_dev_id(const char *name)
5632bfe3f2eSlogwang {
564a9643ea8Slogwang 	unsigned i;
565a9643ea8Slogwang 
566a9643ea8Slogwang 	if (name == NULL)
567a9643ea8Slogwang 		return -1;
568a9643ea8Slogwang 
5694418919fSjohnjiang 	for (i = 0; i < RTE_CRYPTO_MAX_DEVS; i++) {
5704418919fSjohnjiang 		if (!rte_cryptodev_is_valid_device_data(i))
5714418919fSjohnjiang 			continue;
572d30ea906Sjfb8856606 		if ((strcmp(cryptodev_globals.devs[i].data->name, name)
573a9643ea8Slogwang 				== 0) &&
574d30ea906Sjfb8856606 				(cryptodev_globals.devs[i].attached ==
575a9643ea8Slogwang 						RTE_CRYPTODEV_ATTACHED))
576a9643ea8Slogwang 			return i;
5774418919fSjohnjiang 	}
578a9643ea8Slogwang 
579a9643ea8Slogwang 	return -1;
580a9643ea8Slogwang }
581a9643ea8Slogwang 
582a9643ea8Slogwang uint8_t
rte_cryptodev_count(void)583a9643ea8Slogwang rte_cryptodev_count(void)
584a9643ea8Slogwang {
585d30ea906Sjfb8856606 	return cryptodev_globals.nb_devs;
586a9643ea8Slogwang }
587a9643ea8Slogwang 
588a9643ea8Slogwang uint8_t
rte_cryptodev_device_count_by_driver(uint8_t driver_id)5892bfe3f2eSlogwang rte_cryptodev_device_count_by_driver(uint8_t driver_id)
590a9643ea8Slogwang {
591a9643ea8Slogwang 	uint8_t i, dev_count = 0;
592a9643ea8Slogwang 
5934418919fSjohnjiang 	for (i = 0; i < RTE_CRYPTO_MAX_DEVS; i++)
594d30ea906Sjfb8856606 		if (cryptodev_globals.devs[i].driver_id == driver_id &&
595d30ea906Sjfb8856606 			cryptodev_globals.devs[i].attached ==
596a9643ea8Slogwang 					RTE_CRYPTODEV_ATTACHED)
597a9643ea8Slogwang 			dev_count++;
598a9643ea8Slogwang 
599a9643ea8Slogwang 	return dev_count;
600a9643ea8Slogwang }
601a9643ea8Slogwang 
6022bfe3f2eSlogwang uint8_t
rte_cryptodev_devices_get(const char * driver_name,uint8_t * devices,uint8_t nb_devices)6032bfe3f2eSlogwang rte_cryptodev_devices_get(const char *driver_name, uint8_t *devices,
6042bfe3f2eSlogwang 	uint8_t nb_devices)
6052bfe3f2eSlogwang {
6062bfe3f2eSlogwang 	uint8_t i, count = 0;
607d30ea906Sjfb8856606 	struct rte_cryptodev *devs = cryptodev_globals.devs;
6082bfe3f2eSlogwang 
6094418919fSjohnjiang 	for (i = 0; i < RTE_CRYPTO_MAX_DEVS && count < nb_devices; i++) {
6104418919fSjohnjiang 		if (!rte_cryptodev_is_valid_device_data(i))
6114418919fSjohnjiang 			continue;
6122bfe3f2eSlogwang 
6132bfe3f2eSlogwang 		if (devs[i].attached == RTE_CRYPTODEV_ATTACHED) {
6142bfe3f2eSlogwang 			int cmp;
6152bfe3f2eSlogwang 
6162bfe3f2eSlogwang 			cmp = strncmp(devs[i].device->driver->name,
6172bfe3f2eSlogwang 					driver_name,
6181646932aSjfb8856606 					strlen(driver_name) + 1);
6192bfe3f2eSlogwang 
6202bfe3f2eSlogwang 			if (cmp == 0)
6212bfe3f2eSlogwang 				devices[count++] = devs[i].data->dev_id;
6222bfe3f2eSlogwang 		}
6232bfe3f2eSlogwang 	}
6242bfe3f2eSlogwang 
6252bfe3f2eSlogwang 	return count;
6262bfe3f2eSlogwang }
6272bfe3f2eSlogwang 
6282bfe3f2eSlogwang void *
rte_cryptodev_get_sec_ctx(uint8_t dev_id)6292bfe3f2eSlogwang rte_cryptodev_get_sec_ctx(uint8_t dev_id)
6302bfe3f2eSlogwang {
6310c6bd470Sfengbojiang 	if (dev_id < RTE_CRYPTO_MAX_DEVS &&
6320c6bd470Sfengbojiang 			(rte_crypto_devices[dev_id].feature_flags &
6330c6bd470Sfengbojiang 			RTE_CRYPTODEV_FF_SECURITY))
6342bfe3f2eSlogwang 		return rte_crypto_devices[dev_id].security_ctx;
6352bfe3f2eSlogwang 
6362bfe3f2eSlogwang 	return NULL;
6372bfe3f2eSlogwang }
6382bfe3f2eSlogwang 
639a9643ea8Slogwang int
rte_cryptodev_socket_id(uint8_t dev_id)640a9643ea8Slogwang rte_cryptodev_socket_id(uint8_t dev_id)
641a9643ea8Slogwang {
642a9643ea8Slogwang 	struct rte_cryptodev *dev;
643a9643ea8Slogwang 
644a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
645a9643ea8Slogwang 		return -1;
646a9643ea8Slogwang 
647a9643ea8Slogwang 	dev = rte_cryptodev_pmd_get_dev(dev_id);
648a9643ea8Slogwang 
649a9643ea8Slogwang 	return dev->data->socket_id;
650a9643ea8Slogwang }
651a9643ea8Slogwang 
652a9643ea8Slogwang static inline int
rte_cryptodev_data_alloc(uint8_t dev_id,struct rte_cryptodev_data ** data,int socket_id)653a9643ea8Slogwang rte_cryptodev_data_alloc(uint8_t dev_id, struct rte_cryptodev_data **data,
654a9643ea8Slogwang 		int socket_id)
655a9643ea8Slogwang {
6564418919fSjohnjiang 	char mz_name[RTE_MEMZONE_NAMESIZE];
657a9643ea8Slogwang 	const struct rte_memzone *mz;
658a9643ea8Slogwang 	int n;
659a9643ea8Slogwang 
660a9643ea8Slogwang 	/* generate memzone name */
661a9643ea8Slogwang 	n = snprintf(mz_name, sizeof(mz_name), "rte_cryptodev_data_%u", dev_id);
662a9643ea8Slogwang 	if (n >= (int)sizeof(mz_name))
663a9643ea8Slogwang 		return -EINVAL;
664a9643ea8Slogwang 
665a9643ea8Slogwang 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
666a9643ea8Slogwang 		mz = rte_memzone_reserve(mz_name,
667a9643ea8Slogwang 				sizeof(struct rte_cryptodev_data),
668a9643ea8Slogwang 				socket_id, 0);
669*2d9fd380Sjfb8856606 		CDEV_LOG_DEBUG("PRIMARY:reserved memzone for %s (%p)",
670*2d9fd380Sjfb8856606 				mz_name, mz);
671*2d9fd380Sjfb8856606 	} else {
672a9643ea8Slogwang 		mz = rte_memzone_lookup(mz_name);
673*2d9fd380Sjfb8856606 		CDEV_LOG_DEBUG("SECONDARY:looked up memzone for %s (%p)",
674*2d9fd380Sjfb8856606 				mz_name, mz);
675*2d9fd380Sjfb8856606 	}
676a9643ea8Slogwang 
677a9643ea8Slogwang 	if (mz == NULL)
678a9643ea8Slogwang 		return -ENOMEM;
679a9643ea8Slogwang 
680a9643ea8Slogwang 	*data = mz->addr;
681a9643ea8Slogwang 	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
682a9643ea8Slogwang 		memset(*data, 0, sizeof(struct rte_cryptodev_data));
683a9643ea8Slogwang 
684a9643ea8Slogwang 	return 0;
685a9643ea8Slogwang }
686a9643ea8Slogwang 
6874418919fSjohnjiang static inline int
rte_cryptodev_data_free(uint8_t dev_id,struct rte_cryptodev_data ** data)6884418919fSjohnjiang rte_cryptodev_data_free(uint8_t dev_id, struct rte_cryptodev_data **data)
6894418919fSjohnjiang {
6904418919fSjohnjiang 	char mz_name[RTE_MEMZONE_NAMESIZE];
6914418919fSjohnjiang 	const struct rte_memzone *mz;
6924418919fSjohnjiang 	int n;
6934418919fSjohnjiang 
6944418919fSjohnjiang 	/* generate memzone name */
6954418919fSjohnjiang 	n = snprintf(mz_name, sizeof(mz_name), "rte_cryptodev_data_%u", dev_id);
6964418919fSjohnjiang 	if (n >= (int)sizeof(mz_name))
6974418919fSjohnjiang 		return -EINVAL;
6984418919fSjohnjiang 
6994418919fSjohnjiang 	mz = rte_memzone_lookup(mz_name);
7004418919fSjohnjiang 	if (mz == NULL)
7014418919fSjohnjiang 		return -ENOMEM;
7024418919fSjohnjiang 
7034418919fSjohnjiang 	RTE_ASSERT(*data == mz->addr);
7044418919fSjohnjiang 	*data = NULL;
7054418919fSjohnjiang 
706*2d9fd380Sjfb8856606 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
707*2d9fd380Sjfb8856606 		CDEV_LOG_DEBUG("PRIMARY:free memzone of %s (%p)",
708*2d9fd380Sjfb8856606 				mz_name, mz);
7094418919fSjohnjiang 		return rte_memzone_free(mz);
710*2d9fd380Sjfb8856606 	} else {
711*2d9fd380Sjfb8856606 		CDEV_LOG_DEBUG("SECONDARY:don't free memzone of %s (%p)",
712*2d9fd380Sjfb8856606 				mz_name, mz);
713*2d9fd380Sjfb8856606 	}
7144418919fSjohnjiang 
7154418919fSjohnjiang 	return 0;
7164418919fSjohnjiang }
7174418919fSjohnjiang 
718a9643ea8Slogwang static uint8_t
rte_cryptodev_find_free_device_index(void)719a9643ea8Slogwang rte_cryptodev_find_free_device_index(void)
720a9643ea8Slogwang {
721a9643ea8Slogwang 	uint8_t dev_id;
722a9643ea8Slogwang 
723a9643ea8Slogwang 	for (dev_id = 0; dev_id < RTE_CRYPTO_MAX_DEVS; dev_id++) {
724a9643ea8Slogwang 		if (rte_crypto_devices[dev_id].attached ==
725a9643ea8Slogwang 				RTE_CRYPTODEV_DETACHED)
726a9643ea8Slogwang 			return dev_id;
727a9643ea8Slogwang 	}
728a9643ea8Slogwang 	return RTE_CRYPTO_MAX_DEVS;
729a9643ea8Slogwang }
730a9643ea8Slogwang 
731a9643ea8Slogwang struct rte_cryptodev *
rte_cryptodev_pmd_allocate(const char * name,int socket_id)7322bfe3f2eSlogwang rte_cryptodev_pmd_allocate(const char *name, int socket_id)
733a9643ea8Slogwang {
734a9643ea8Slogwang 	struct rte_cryptodev *cryptodev;
735a9643ea8Slogwang 	uint8_t dev_id;
736a9643ea8Slogwang 
737a9643ea8Slogwang 	if (rte_cryptodev_pmd_get_named_dev(name) != NULL) {
738a9643ea8Slogwang 		CDEV_LOG_ERR("Crypto device with name %s already "
739a9643ea8Slogwang 				"allocated!", name);
740a9643ea8Slogwang 		return NULL;
741a9643ea8Slogwang 	}
742a9643ea8Slogwang 
743a9643ea8Slogwang 	dev_id = rte_cryptodev_find_free_device_index();
744a9643ea8Slogwang 	if (dev_id == RTE_CRYPTO_MAX_DEVS) {
745a9643ea8Slogwang 		CDEV_LOG_ERR("Reached maximum number of crypto devices");
746a9643ea8Slogwang 		return NULL;
747a9643ea8Slogwang 	}
748a9643ea8Slogwang 
749a9643ea8Slogwang 	cryptodev = rte_cryptodev_pmd_get_dev(dev_id);
750a9643ea8Slogwang 
751a9643ea8Slogwang 	if (cryptodev->data == NULL) {
7524418919fSjohnjiang 		struct rte_cryptodev_data **cryptodev_data =
7534418919fSjohnjiang 				&cryptodev_globals.data[dev_id];
754a9643ea8Slogwang 
7554418919fSjohnjiang 		int retval = rte_cryptodev_data_alloc(dev_id, cryptodev_data,
756a9643ea8Slogwang 				socket_id);
757a9643ea8Slogwang 
7584418919fSjohnjiang 		if (retval < 0 || *cryptodev_data == NULL)
759a9643ea8Slogwang 			return NULL;
760a9643ea8Slogwang 
7614418919fSjohnjiang 		cryptodev->data = *cryptodev_data;
762a9643ea8Slogwang 
7634418919fSjohnjiang 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
7644418919fSjohnjiang 			strlcpy(cryptodev->data->name, name,
7654418919fSjohnjiang 				RTE_CRYPTODEV_NAME_MAX_LEN);
766a9643ea8Slogwang 
767a9643ea8Slogwang 			cryptodev->data->dev_id = dev_id;
768a9643ea8Slogwang 			cryptodev->data->socket_id = socket_id;
769a9643ea8Slogwang 			cryptodev->data->dev_started = 0;
770*2d9fd380Sjfb8856606 			CDEV_LOG_DEBUG("PRIMARY:init data");
7714418919fSjohnjiang 		}
772a9643ea8Slogwang 
773*2d9fd380Sjfb8856606 		CDEV_LOG_DEBUG("Data for %s: dev_id %d, socket %d, started %d",
774*2d9fd380Sjfb8856606 				cryptodev->data->name,
775*2d9fd380Sjfb8856606 				cryptodev->data->dev_id,
776*2d9fd380Sjfb8856606 				cryptodev->data->socket_id,
777*2d9fd380Sjfb8856606 				cryptodev->data->dev_started);
778*2d9fd380Sjfb8856606 
7792bfe3f2eSlogwang 		/* init user callbacks */
7802bfe3f2eSlogwang 		TAILQ_INIT(&(cryptodev->link_intr_cbs));
7812bfe3f2eSlogwang 
782a9643ea8Slogwang 		cryptodev->attached = RTE_CRYPTODEV_ATTACHED;
783a9643ea8Slogwang 
784a9643ea8Slogwang 		cryptodev_globals.nb_devs++;
785a9643ea8Slogwang 	}
786a9643ea8Slogwang 
787a9643ea8Slogwang 	return cryptodev;
788a9643ea8Slogwang }
789a9643ea8Slogwang 
790a9643ea8Slogwang int
rte_cryptodev_pmd_release_device(struct rte_cryptodev * cryptodev)791a9643ea8Slogwang rte_cryptodev_pmd_release_device(struct rte_cryptodev *cryptodev)
792a9643ea8Slogwang {
793a9643ea8Slogwang 	int ret;
7944418919fSjohnjiang 	uint8_t dev_id;
795a9643ea8Slogwang 
796a9643ea8Slogwang 	if (cryptodev == NULL)
797a9643ea8Slogwang 		return -EINVAL;
798a9643ea8Slogwang 
7994418919fSjohnjiang 	dev_id = cryptodev->data->dev_id;
8004418919fSjohnjiang 
8012bfe3f2eSlogwang 	/* Close device only if device operations have been set */
8022bfe3f2eSlogwang 	if (cryptodev->dev_ops) {
8034418919fSjohnjiang 		ret = rte_cryptodev_close(dev_id);
804a9643ea8Slogwang 		if (ret < 0)
805a9643ea8Slogwang 			return ret;
8062bfe3f2eSlogwang 	}
807a9643ea8Slogwang 
8084418919fSjohnjiang 	ret = rte_cryptodev_data_free(dev_id, &cryptodev_globals.data[dev_id]);
8094418919fSjohnjiang 	if (ret < 0)
8104418919fSjohnjiang 		return ret;
8114418919fSjohnjiang 
812a9643ea8Slogwang 	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
813a9643ea8Slogwang 	cryptodev_globals.nb_devs--;
814a9643ea8Slogwang 	return 0;
815a9643ea8Slogwang }
816a9643ea8Slogwang 
817a9643ea8Slogwang uint16_t
rte_cryptodev_queue_pair_count(uint8_t dev_id)818a9643ea8Slogwang rte_cryptodev_queue_pair_count(uint8_t dev_id)
819a9643ea8Slogwang {
820a9643ea8Slogwang 	struct rte_cryptodev *dev;
821a9643ea8Slogwang 
8220c6bd470Sfengbojiang 	if (!rte_cryptodev_is_valid_device_data(dev_id)) {
8230c6bd470Sfengbojiang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
8240c6bd470Sfengbojiang 		return 0;
8250c6bd470Sfengbojiang 	}
8260c6bd470Sfengbojiang 
827a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
828a9643ea8Slogwang 	return dev->data->nb_queue_pairs;
829a9643ea8Slogwang }
830a9643ea8Slogwang 
831a9643ea8Slogwang static int
rte_cryptodev_queue_pairs_config(struct rte_cryptodev * dev,uint16_t nb_qpairs,int socket_id)832a9643ea8Slogwang rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
833a9643ea8Slogwang 		int socket_id)
834a9643ea8Slogwang {
835a9643ea8Slogwang 	struct rte_cryptodev_info dev_info;
836a9643ea8Slogwang 	void **qp;
837a9643ea8Slogwang 	unsigned i;
838a9643ea8Slogwang 
839a9643ea8Slogwang 	if ((dev == NULL) || (nb_qpairs < 1)) {
840a9643ea8Slogwang 		CDEV_LOG_ERR("invalid param: dev %p, nb_queues %u",
841a9643ea8Slogwang 							dev, nb_qpairs);
842a9643ea8Slogwang 		return -EINVAL;
843a9643ea8Slogwang 	}
844a9643ea8Slogwang 
845a9643ea8Slogwang 	CDEV_LOG_DEBUG("Setup %d queues pairs on device %u",
846a9643ea8Slogwang 			nb_qpairs, dev->data->dev_id);
847a9643ea8Slogwang 
848a9643ea8Slogwang 	memset(&dev_info, 0, sizeof(struct rte_cryptodev_info));
849a9643ea8Slogwang 
850a9643ea8Slogwang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
851a9643ea8Slogwang 	(*dev->dev_ops->dev_infos_get)(dev, &dev_info);
852a9643ea8Slogwang 
853a9643ea8Slogwang 	if (nb_qpairs > (dev_info.max_nb_queue_pairs)) {
854a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid num queue_pairs (%u) for dev %u",
855a9643ea8Slogwang 				nb_qpairs, dev->data->dev_id);
856a9643ea8Slogwang 	    return -EINVAL;
857a9643ea8Slogwang 	}
858a9643ea8Slogwang 
859a9643ea8Slogwang 	if (dev->data->queue_pairs == NULL) { /* first time configuration */
860a9643ea8Slogwang 		dev->data->queue_pairs = rte_zmalloc_socket(
861a9643ea8Slogwang 				"cryptodev->queue_pairs",
862a9643ea8Slogwang 				sizeof(dev->data->queue_pairs[0]) * nb_qpairs,
863a9643ea8Slogwang 				RTE_CACHE_LINE_SIZE, socket_id);
864a9643ea8Slogwang 
865a9643ea8Slogwang 		if (dev->data->queue_pairs == NULL) {
866a9643ea8Slogwang 			dev->data->nb_queue_pairs = 0;
867a9643ea8Slogwang 			CDEV_LOG_ERR("failed to get memory for qp meta data, "
868a9643ea8Slogwang 							"nb_queues %u",
869a9643ea8Slogwang 							nb_qpairs);
870a9643ea8Slogwang 			return -(ENOMEM);
871a9643ea8Slogwang 		}
872a9643ea8Slogwang 	} else { /* re-configure */
873a9643ea8Slogwang 		int ret;
874a9643ea8Slogwang 		uint16_t old_nb_queues = dev->data->nb_queue_pairs;
875a9643ea8Slogwang 
876a9643ea8Slogwang 		qp = dev->data->queue_pairs;
877a9643ea8Slogwang 
878a9643ea8Slogwang 		RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_release,
879a9643ea8Slogwang 				-ENOTSUP);
880a9643ea8Slogwang 
881a9643ea8Slogwang 		for (i = nb_qpairs; i < old_nb_queues; i++) {
882a9643ea8Slogwang 			ret = (*dev->dev_ops->queue_pair_release)(dev, i);
883a9643ea8Slogwang 			if (ret < 0)
884a9643ea8Slogwang 				return ret;
885a9643ea8Slogwang 		}
886a9643ea8Slogwang 
887a9643ea8Slogwang 		qp = rte_realloc(qp, sizeof(qp[0]) * nb_qpairs,
888a9643ea8Slogwang 				RTE_CACHE_LINE_SIZE);
889a9643ea8Slogwang 		if (qp == NULL) {
890a9643ea8Slogwang 			CDEV_LOG_ERR("failed to realloc qp meta data,"
891a9643ea8Slogwang 						" nb_queues %u", nb_qpairs);
892a9643ea8Slogwang 			return -(ENOMEM);
893a9643ea8Slogwang 		}
894a9643ea8Slogwang 
895a9643ea8Slogwang 		if (nb_qpairs > old_nb_queues) {
896a9643ea8Slogwang 			uint16_t new_qs = nb_qpairs - old_nb_queues;
897a9643ea8Slogwang 
898a9643ea8Slogwang 			memset(qp + old_nb_queues, 0,
899a9643ea8Slogwang 				sizeof(qp[0]) * new_qs);
900a9643ea8Slogwang 		}
901a9643ea8Slogwang 
902a9643ea8Slogwang 		dev->data->queue_pairs = qp;
903a9643ea8Slogwang 
904a9643ea8Slogwang 	}
905a9643ea8Slogwang 	dev->data->nb_queue_pairs = nb_qpairs;
906a9643ea8Slogwang 	return 0;
907a9643ea8Slogwang }
908a9643ea8Slogwang 
909a9643ea8Slogwang int
rte_cryptodev_configure(uint8_t dev_id,struct rte_cryptodev_config * config)910a9643ea8Slogwang rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
911a9643ea8Slogwang {
912a9643ea8Slogwang 	struct rte_cryptodev *dev;
913a9643ea8Slogwang 	int diag;
914a9643ea8Slogwang 
915a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
916a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
917a9643ea8Slogwang 		return -EINVAL;
918a9643ea8Slogwang 	}
919a9643ea8Slogwang 
920a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
921a9643ea8Slogwang 
922a9643ea8Slogwang 	if (dev->data->dev_started) {
923a9643ea8Slogwang 		CDEV_LOG_ERR(
924a9643ea8Slogwang 		    "device %d must be stopped to allow configuration", dev_id);
925a9643ea8Slogwang 		return -EBUSY;
926a9643ea8Slogwang 	}
927a9643ea8Slogwang 
9282bfe3f2eSlogwang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
9292bfe3f2eSlogwang 
930a9643ea8Slogwang 	/* Setup new number of queue pairs and reconfigure device. */
931a9643ea8Slogwang 	diag = rte_cryptodev_queue_pairs_config(dev, config->nb_queue_pairs,
932a9643ea8Slogwang 			config->socket_id);
933a9643ea8Slogwang 	if (diag != 0) {
934a9643ea8Slogwang 		CDEV_LOG_ERR("dev%d rte_crypto_dev_queue_pairs_config = %d",
935a9643ea8Slogwang 				dev_id, diag);
936a9643ea8Slogwang 		return diag;
937a9643ea8Slogwang 	}
938a9643ea8Slogwang 
939*2d9fd380Sjfb8856606 	rte_cryptodev_trace_configure(dev_id, config);
9402bfe3f2eSlogwang 	return (*dev->dev_ops->dev_configure)(dev, config);
941a9643ea8Slogwang }
942a9643ea8Slogwang 
943a9643ea8Slogwang 
944a9643ea8Slogwang int
rte_cryptodev_start(uint8_t dev_id)945a9643ea8Slogwang rte_cryptodev_start(uint8_t dev_id)
946a9643ea8Slogwang {
947a9643ea8Slogwang 	struct rte_cryptodev *dev;
948a9643ea8Slogwang 	int diag;
949a9643ea8Slogwang 
950a9643ea8Slogwang 	CDEV_LOG_DEBUG("Start dev_id=%" PRIu8, dev_id);
951a9643ea8Slogwang 
952a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
953a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
954a9643ea8Slogwang 		return -EINVAL;
955a9643ea8Slogwang 	}
956a9643ea8Slogwang 
957a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
958a9643ea8Slogwang 
959a9643ea8Slogwang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
960a9643ea8Slogwang 
961a9643ea8Slogwang 	if (dev->data->dev_started != 0) {
962a9643ea8Slogwang 		CDEV_LOG_ERR("Device with dev_id=%" PRIu8 " already started",
963a9643ea8Slogwang 			dev_id);
964a9643ea8Slogwang 		return 0;
965a9643ea8Slogwang 	}
966a9643ea8Slogwang 
967a9643ea8Slogwang 	diag = (*dev->dev_ops->dev_start)(dev);
968*2d9fd380Sjfb8856606 	rte_cryptodev_trace_start(dev_id, diag);
969a9643ea8Slogwang 	if (diag == 0)
970a9643ea8Slogwang 		dev->data->dev_started = 1;
971a9643ea8Slogwang 	else
972a9643ea8Slogwang 		return diag;
973a9643ea8Slogwang 
974a9643ea8Slogwang 	return 0;
975a9643ea8Slogwang }
976a9643ea8Slogwang 
977a9643ea8Slogwang void
rte_cryptodev_stop(uint8_t dev_id)978a9643ea8Slogwang rte_cryptodev_stop(uint8_t dev_id)
979a9643ea8Slogwang {
980a9643ea8Slogwang 	struct rte_cryptodev *dev;
981a9643ea8Slogwang 
982a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
983a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
984a9643ea8Slogwang 		return;
985a9643ea8Slogwang 	}
986a9643ea8Slogwang 
987a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
988a9643ea8Slogwang 
989a9643ea8Slogwang 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
990a9643ea8Slogwang 
991a9643ea8Slogwang 	if (dev->data->dev_started == 0) {
992a9643ea8Slogwang 		CDEV_LOG_ERR("Device with dev_id=%" PRIu8 " already stopped",
993a9643ea8Slogwang 			dev_id);
994a9643ea8Slogwang 		return;
995a9643ea8Slogwang 	}
996a9643ea8Slogwang 
997a9643ea8Slogwang 	(*dev->dev_ops->dev_stop)(dev);
998*2d9fd380Sjfb8856606 	rte_cryptodev_trace_stop(dev_id);
9992bfe3f2eSlogwang 	dev->data->dev_started = 0;
1000a9643ea8Slogwang }
1001a9643ea8Slogwang 
1002a9643ea8Slogwang int
rte_cryptodev_close(uint8_t dev_id)1003a9643ea8Slogwang rte_cryptodev_close(uint8_t dev_id)
1004a9643ea8Slogwang {
1005a9643ea8Slogwang 	struct rte_cryptodev *dev;
1006a9643ea8Slogwang 	int retval;
1007a9643ea8Slogwang 
1008a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1009a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1010a9643ea8Slogwang 		return -1;
1011a9643ea8Slogwang 	}
1012a9643ea8Slogwang 
1013a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1014a9643ea8Slogwang 
1015a9643ea8Slogwang 	/* Device must be stopped before it can be closed */
1016a9643ea8Slogwang 	if (dev->data->dev_started == 1) {
1017a9643ea8Slogwang 		CDEV_LOG_ERR("Device %u must be stopped before closing",
1018a9643ea8Slogwang 				dev_id);
1019a9643ea8Slogwang 		return -EBUSY;
1020a9643ea8Slogwang 	}
1021a9643ea8Slogwang 
1022a9643ea8Slogwang 	/* We can't close the device if there are outstanding sessions in use */
1023a9643ea8Slogwang 	if (dev->data->session_pool != NULL) {
1024a9643ea8Slogwang 		if (!rte_mempool_full(dev->data->session_pool)) {
1025a9643ea8Slogwang 			CDEV_LOG_ERR("dev_id=%u close failed, session mempool "
1026a9643ea8Slogwang 					"has sessions still in use, free "
1027a9643ea8Slogwang 					"all sessions before calling close",
1028a9643ea8Slogwang 					(unsigned)dev_id);
1029a9643ea8Slogwang 			return -EBUSY;
1030a9643ea8Slogwang 		}
1031a9643ea8Slogwang 	}
1032a9643ea8Slogwang 
1033a9643ea8Slogwang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
1034a9643ea8Slogwang 	retval = (*dev->dev_ops->dev_close)(dev);
1035*2d9fd380Sjfb8856606 	rte_cryptodev_trace_close(dev_id, retval);
1036a9643ea8Slogwang 
1037a9643ea8Slogwang 	if (retval < 0)
1038a9643ea8Slogwang 		return retval;
1039a9643ea8Slogwang 
1040a9643ea8Slogwang 	return 0;
1041a9643ea8Slogwang }
1042a9643ea8Slogwang 
1043a9643ea8Slogwang int
rte_cryptodev_get_qp_status(uint8_t dev_id,uint16_t queue_pair_id)1044*2d9fd380Sjfb8856606 rte_cryptodev_get_qp_status(uint8_t dev_id, uint16_t queue_pair_id)
1045*2d9fd380Sjfb8856606 {
1046*2d9fd380Sjfb8856606 	struct rte_cryptodev *dev;
1047*2d9fd380Sjfb8856606 
1048*2d9fd380Sjfb8856606 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1049*2d9fd380Sjfb8856606 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1050*2d9fd380Sjfb8856606 		return -EINVAL;
1051*2d9fd380Sjfb8856606 	}
1052*2d9fd380Sjfb8856606 
1053*2d9fd380Sjfb8856606 	dev = &rte_crypto_devices[dev_id];
1054*2d9fd380Sjfb8856606 	if (queue_pair_id >= dev->data->nb_queue_pairs) {
1055*2d9fd380Sjfb8856606 		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
1056*2d9fd380Sjfb8856606 		return -EINVAL;
1057*2d9fd380Sjfb8856606 	}
1058*2d9fd380Sjfb8856606 	void **qps = dev->data->queue_pairs;
1059*2d9fd380Sjfb8856606 
1060*2d9fd380Sjfb8856606 	if (qps[queue_pair_id])	{
1061*2d9fd380Sjfb8856606 		CDEV_LOG_DEBUG("qp %d on dev %d is initialised",
1062*2d9fd380Sjfb8856606 			queue_pair_id, dev_id);
1063*2d9fd380Sjfb8856606 		return 1;
1064*2d9fd380Sjfb8856606 	}
1065*2d9fd380Sjfb8856606 
1066*2d9fd380Sjfb8856606 	CDEV_LOG_DEBUG("qp %d on dev %d is not initialised",
1067*2d9fd380Sjfb8856606 		queue_pair_id, dev_id);
1068*2d9fd380Sjfb8856606 
1069*2d9fd380Sjfb8856606 	return 0;
1070*2d9fd380Sjfb8856606 }
1071*2d9fd380Sjfb8856606 
1072*2d9fd380Sjfb8856606 int
rte_cryptodev_queue_pair_setup(uint8_t dev_id,uint16_t queue_pair_id,const struct rte_cryptodev_qp_conf * qp_conf,int socket_id)1073a9643ea8Slogwang rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
10744418919fSjohnjiang 		const struct rte_cryptodev_qp_conf *qp_conf, int socket_id)
10752bfe3f2eSlogwang 
1076a9643ea8Slogwang {
1077a9643ea8Slogwang 	struct rte_cryptodev *dev;
1078a9643ea8Slogwang 
1079a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1080a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1081a9643ea8Slogwang 		return -EINVAL;
1082a9643ea8Slogwang 	}
1083a9643ea8Slogwang 
1084a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1085a9643ea8Slogwang 	if (queue_pair_id >= dev->data->nb_queue_pairs) {
1086a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
1087a9643ea8Slogwang 		return -EINVAL;
1088a9643ea8Slogwang 	}
1089a9643ea8Slogwang 
10904418919fSjohnjiang 	if (!qp_conf) {
10914418919fSjohnjiang 		CDEV_LOG_ERR("qp_conf cannot be NULL\n");
10924418919fSjohnjiang 		return -EINVAL;
10934418919fSjohnjiang 	}
10944418919fSjohnjiang 
10954418919fSjohnjiang 	if ((qp_conf->mp_session && !qp_conf->mp_session_private) ||
10964418919fSjohnjiang 			(!qp_conf->mp_session && qp_conf->mp_session_private)) {
10974418919fSjohnjiang 		CDEV_LOG_ERR("Invalid mempools\n");
10984418919fSjohnjiang 		return -EINVAL;
10994418919fSjohnjiang 	}
11004418919fSjohnjiang 
11014418919fSjohnjiang 	if (qp_conf->mp_session) {
11024418919fSjohnjiang 		struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
11034418919fSjohnjiang 		uint32_t obj_size = qp_conf->mp_session->elt_size;
11044418919fSjohnjiang 		uint32_t obj_priv_size = qp_conf->mp_session_private->elt_size;
11054418919fSjohnjiang 		struct rte_cryptodev_sym_session s = {0};
11064418919fSjohnjiang 
11074418919fSjohnjiang 		pool_priv = rte_mempool_get_priv(qp_conf->mp_session);
11084418919fSjohnjiang 		if (!pool_priv || qp_conf->mp_session->private_data_size <
11094418919fSjohnjiang 				sizeof(*pool_priv)) {
11104418919fSjohnjiang 			CDEV_LOG_ERR("Invalid mempool\n");
11114418919fSjohnjiang 			return -EINVAL;
11124418919fSjohnjiang 		}
11134418919fSjohnjiang 
11144418919fSjohnjiang 		s.nb_drivers = pool_priv->nb_drivers;
11154418919fSjohnjiang 		s.user_data_sz = pool_priv->user_data_sz;
11164418919fSjohnjiang 
11174418919fSjohnjiang 		if ((rte_cryptodev_sym_get_existing_header_session_size(&s) >
11184418919fSjohnjiang 			obj_size) || (s.nb_drivers <= dev->driver_id) ||
11194418919fSjohnjiang 			rte_cryptodev_sym_get_private_session_size(dev_id) >
11204418919fSjohnjiang 				obj_priv_size) {
11214418919fSjohnjiang 			CDEV_LOG_ERR("Invalid mempool\n");
11224418919fSjohnjiang 			return -EINVAL;
11234418919fSjohnjiang 		}
11244418919fSjohnjiang 	}
11254418919fSjohnjiang 
1126a9643ea8Slogwang 	if (dev->data->dev_started) {
1127a9643ea8Slogwang 		CDEV_LOG_ERR(
1128a9643ea8Slogwang 		    "device %d must be stopped to allow configuration", dev_id);
1129a9643ea8Slogwang 		return -EBUSY;
1130a9643ea8Slogwang 	}
1131a9643ea8Slogwang 
1132a9643ea8Slogwang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP);
1133a9643ea8Slogwang 
1134*2d9fd380Sjfb8856606 	rte_cryptodev_trace_queue_pair_setup(dev_id, queue_pair_id, qp_conf);
1135a9643ea8Slogwang 	return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf,
11364418919fSjohnjiang 			socket_id);
1137a9643ea8Slogwang }
1138a9643ea8Slogwang 
1139a9643ea8Slogwang 
1140a9643ea8Slogwang int
rte_cryptodev_stats_get(uint8_t dev_id,struct rte_cryptodev_stats * stats)1141a9643ea8Slogwang rte_cryptodev_stats_get(uint8_t dev_id, struct rte_cryptodev_stats *stats)
1142a9643ea8Slogwang {
1143a9643ea8Slogwang 	struct rte_cryptodev *dev;
1144a9643ea8Slogwang 
1145a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1146a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
1147a9643ea8Slogwang 		return -ENODEV;
1148a9643ea8Slogwang 	}
1149a9643ea8Slogwang 
1150a9643ea8Slogwang 	if (stats == NULL) {
1151a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid stats ptr");
1152a9643ea8Slogwang 		return -EINVAL;
1153a9643ea8Slogwang 	}
1154a9643ea8Slogwang 
1155a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1156a9643ea8Slogwang 	memset(stats, 0, sizeof(*stats));
1157a9643ea8Slogwang 
1158a9643ea8Slogwang 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->stats_get, -ENOTSUP);
1159a9643ea8Slogwang 	(*dev->dev_ops->stats_get)(dev, stats);
1160a9643ea8Slogwang 	return 0;
1161a9643ea8Slogwang }
1162a9643ea8Slogwang 
1163a9643ea8Slogwang void
rte_cryptodev_stats_reset(uint8_t dev_id)1164a9643ea8Slogwang rte_cryptodev_stats_reset(uint8_t dev_id)
1165a9643ea8Slogwang {
1166a9643ea8Slogwang 	struct rte_cryptodev *dev;
1167a9643ea8Slogwang 
1168a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1169a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1170a9643ea8Slogwang 		return;
1171a9643ea8Slogwang 	}
1172a9643ea8Slogwang 
1173a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1174a9643ea8Slogwang 
1175a9643ea8Slogwang 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->stats_reset);
1176a9643ea8Slogwang 	(*dev->dev_ops->stats_reset)(dev);
1177a9643ea8Slogwang }
1178a9643ea8Slogwang 
1179a9643ea8Slogwang void
rte_cryptodev_info_get(uint8_t dev_id,struct rte_cryptodev_info * dev_info)1180a9643ea8Slogwang rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
1181a9643ea8Slogwang {
1182a9643ea8Slogwang 	struct rte_cryptodev *dev;
1183a9643ea8Slogwang 
11844418919fSjohnjiang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1185a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
1186a9643ea8Slogwang 		return;
1187a9643ea8Slogwang 	}
1188a9643ea8Slogwang 
1189a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1190a9643ea8Slogwang 
1191a9643ea8Slogwang 	memset(dev_info, 0, sizeof(struct rte_cryptodev_info));
1192a9643ea8Slogwang 
1193a9643ea8Slogwang 	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
1194a9643ea8Slogwang 	(*dev->dev_ops->dev_infos_get)(dev, dev_info);
1195a9643ea8Slogwang 
11962bfe3f2eSlogwang 	dev_info->driver_name = dev->device->driver->name;
1197d30ea906Sjfb8856606 	dev_info->device = dev->device;
1198a9643ea8Slogwang }
1199a9643ea8Slogwang 
1200a9643ea8Slogwang int
rte_cryptodev_callback_register(uint8_t dev_id,enum rte_cryptodev_event_type event,rte_cryptodev_cb_fn cb_fn,void * cb_arg)1201a9643ea8Slogwang rte_cryptodev_callback_register(uint8_t dev_id,
1202a9643ea8Slogwang 			enum rte_cryptodev_event_type event,
1203a9643ea8Slogwang 			rte_cryptodev_cb_fn cb_fn, void *cb_arg)
1204a9643ea8Slogwang {
1205a9643ea8Slogwang 	struct rte_cryptodev *dev;
1206a9643ea8Slogwang 	struct rte_cryptodev_callback *user_cb;
1207a9643ea8Slogwang 
1208a9643ea8Slogwang 	if (!cb_fn)
1209a9643ea8Slogwang 		return -EINVAL;
1210a9643ea8Slogwang 
1211a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1212a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1213a9643ea8Slogwang 		return -EINVAL;
1214a9643ea8Slogwang 	}
1215a9643ea8Slogwang 
1216a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1217a9643ea8Slogwang 	rte_spinlock_lock(&rte_cryptodev_cb_lock);
1218a9643ea8Slogwang 
1219a9643ea8Slogwang 	TAILQ_FOREACH(user_cb, &(dev->link_intr_cbs), next) {
1220a9643ea8Slogwang 		if (user_cb->cb_fn == cb_fn &&
1221a9643ea8Slogwang 			user_cb->cb_arg == cb_arg &&
1222a9643ea8Slogwang 			user_cb->event == event) {
1223a9643ea8Slogwang 			break;
1224a9643ea8Slogwang 		}
1225a9643ea8Slogwang 	}
1226a9643ea8Slogwang 
1227a9643ea8Slogwang 	/* create a new callback. */
1228a9643ea8Slogwang 	if (user_cb == NULL) {
1229a9643ea8Slogwang 		user_cb = rte_zmalloc("INTR_USER_CALLBACK",
1230a9643ea8Slogwang 				sizeof(struct rte_cryptodev_callback), 0);
1231a9643ea8Slogwang 		if (user_cb != NULL) {
1232a9643ea8Slogwang 			user_cb->cb_fn = cb_fn;
1233a9643ea8Slogwang 			user_cb->cb_arg = cb_arg;
1234a9643ea8Slogwang 			user_cb->event = event;
1235a9643ea8Slogwang 			TAILQ_INSERT_TAIL(&(dev->link_intr_cbs), user_cb, next);
1236a9643ea8Slogwang 		}
1237a9643ea8Slogwang 	}
1238a9643ea8Slogwang 
1239a9643ea8Slogwang 	rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1240a9643ea8Slogwang 	return (user_cb == NULL) ? -ENOMEM : 0;
1241a9643ea8Slogwang }
1242a9643ea8Slogwang 
1243a9643ea8Slogwang int
rte_cryptodev_callback_unregister(uint8_t dev_id,enum rte_cryptodev_event_type event,rte_cryptodev_cb_fn cb_fn,void * cb_arg)1244a9643ea8Slogwang rte_cryptodev_callback_unregister(uint8_t dev_id,
1245a9643ea8Slogwang 			enum rte_cryptodev_event_type event,
1246a9643ea8Slogwang 			rte_cryptodev_cb_fn cb_fn, void *cb_arg)
1247a9643ea8Slogwang {
1248a9643ea8Slogwang 	int ret;
1249a9643ea8Slogwang 	struct rte_cryptodev *dev;
1250a9643ea8Slogwang 	struct rte_cryptodev_callback *cb, *next;
1251a9643ea8Slogwang 
1252a9643ea8Slogwang 	if (!cb_fn)
1253a9643ea8Slogwang 		return -EINVAL;
1254a9643ea8Slogwang 
1255a9643ea8Slogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1256a9643ea8Slogwang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
1257a9643ea8Slogwang 		return -EINVAL;
1258a9643ea8Slogwang 	}
1259a9643ea8Slogwang 
1260a9643ea8Slogwang 	dev = &rte_crypto_devices[dev_id];
1261a9643ea8Slogwang 	rte_spinlock_lock(&rte_cryptodev_cb_lock);
1262a9643ea8Slogwang 
1263a9643ea8Slogwang 	ret = 0;
1264a9643ea8Slogwang 	for (cb = TAILQ_FIRST(&dev->link_intr_cbs); cb != NULL; cb = next) {
1265a9643ea8Slogwang 
1266a9643ea8Slogwang 		next = TAILQ_NEXT(cb, next);
1267a9643ea8Slogwang 
1268a9643ea8Slogwang 		if (cb->cb_fn != cb_fn || cb->event != event ||
1269a9643ea8Slogwang 				(cb->cb_arg != (void *)-1 &&
1270a9643ea8Slogwang 				cb->cb_arg != cb_arg))
1271a9643ea8Slogwang 			continue;
1272a9643ea8Slogwang 
1273a9643ea8Slogwang 		/*
1274a9643ea8Slogwang 		 * if this callback is not executing right now,
1275a9643ea8Slogwang 		 * then remove it.
1276a9643ea8Slogwang 		 */
1277a9643ea8Slogwang 		if (cb->active == 0) {
1278a9643ea8Slogwang 			TAILQ_REMOVE(&(dev->link_intr_cbs), cb, next);
1279a9643ea8Slogwang 			rte_free(cb);
1280a9643ea8Slogwang 		} else {
1281a9643ea8Slogwang 			ret = -EAGAIN;
1282a9643ea8Slogwang 		}
1283a9643ea8Slogwang 	}
1284a9643ea8Slogwang 
1285a9643ea8Slogwang 	rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1286a9643ea8Slogwang 	return ret;
1287a9643ea8Slogwang }
1288a9643ea8Slogwang 
1289a9643ea8Slogwang void
rte_cryptodev_pmd_callback_process(struct rte_cryptodev * dev,enum rte_cryptodev_event_type event)1290a9643ea8Slogwang rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev,
1291a9643ea8Slogwang 	enum rte_cryptodev_event_type event)
1292a9643ea8Slogwang {
1293a9643ea8Slogwang 	struct rte_cryptodev_callback *cb_lst;
1294a9643ea8Slogwang 	struct rte_cryptodev_callback dev_cb;
1295a9643ea8Slogwang 
1296a9643ea8Slogwang 	rte_spinlock_lock(&rte_cryptodev_cb_lock);
1297a9643ea8Slogwang 	TAILQ_FOREACH(cb_lst, &(dev->link_intr_cbs), next) {
1298a9643ea8Slogwang 		if (cb_lst->cb_fn == NULL || cb_lst->event != event)
1299a9643ea8Slogwang 			continue;
1300a9643ea8Slogwang 		dev_cb = *cb_lst;
1301a9643ea8Slogwang 		cb_lst->active = 1;
1302a9643ea8Slogwang 		rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1303a9643ea8Slogwang 		dev_cb.cb_fn(dev->data->dev_id, dev_cb.event,
1304a9643ea8Slogwang 						dev_cb.cb_arg);
1305a9643ea8Slogwang 		rte_spinlock_lock(&rte_cryptodev_cb_lock);
1306a9643ea8Slogwang 		cb_lst->active = 0;
1307a9643ea8Slogwang 	}
1308a9643ea8Slogwang 	rte_spinlock_unlock(&rte_cryptodev_cb_lock);
1309a9643ea8Slogwang }
1310a9643ea8Slogwang 
13112bfe3f2eSlogwang int
rte_cryptodev_sym_session_init(uint8_t dev_id,struct rte_cryptodev_sym_session * sess,struct rte_crypto_sym_xform * xforms,struct rte_mempool * mp)13122bfe3f2eSlogwang rte_cryptodev_sym_session_init(uint8_t dev_id,
13132bfe3f2eSlogwang 		struct rte_cryptodev_sym_session *sess,
13142bfe3f2eSlogwang 		struct rte_crypto_sym_xform *xforms,
13152bfe3f2eSlogwang 		struct rte_mempool *mp)
1316a9643ea8Slogwang {
13172bfe3f2eSlogwang 	struct rte_cryptodev *dev;
13184418919fSjohnjiang 	uint32_t sess_priv_sz = rte_cryptodev_sym_get_private_session_size(
13194418919fSjohnjiang 			dev_id);
13202bfe3f2eSlogwang 	uint8_t index;
13212bfe3f2eSlogwang 	int ret;
1322a9643ea8Slogwang 
13230c6bd470Sfengbojiang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
13240c6bd470Sfengbojiang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
13250c6bd470Sfengbojiang 		return -EINVAL;
13260c6bd470Sfengbojiang 	}
13270c6bd470Sfengbojiang 
13282bfe3f2eSlogwang 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1329a9643ea8Slogwang 
1330*2d9fd380Sjfb8856606 	if (sess == NULL || xforms == NULL || dev == NULL || mp == NULL)
13312bfe3f2eSlogwang 		return -EINVAL;
1332a9643ea8Slogwang 
13334418919fSjohnjiang 	if (mp->elt_size < sess_priv_sz)
13344418919fSjohnjiang 		return -EINVAL;
13354418919fSjohnjiang 
13362bfe3f2eSlogwang 	index = dev->driver_id;
13374418919fSjohnjiang 	if (index >= sess->nb_drivers)
13384418919fSjohnjiang 		return -EINVAL;
1339a9643ea8Slogwang 
1340d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_configure, -ENOTSUP);
1341d30ea906Sjfb8856606 
13424418919fSjohnjiang 	if (sess->sess_data[index].refcnt == 0) {
1343d30ea906Sjfb8856606 		ret = dev->dev_ops->sym_session_configure(dev, xforms,
1344d30ea906Sjfb8856606 							sess, mp);
1345d30ea906Sjfb8856606 		if (ret < 0) {
1346d30ea906Sjfb8856606 			CDEV_LOG_ERR(
1347d30ea906Sjfb8856606 				"dev_id %d failed to configure session details",
1348d30ea906Sjfb8856606 				dev_id);
1349d30ea906Sjfb8856606 			return ret;
1350d30ea906Sjfb8856606 		}
1351d30ea906Sjfb8856606 	}
1352d30ea906Sjfb8856606 
1353*2d9fd380Sjfb8856606 	rte_cryptodev_trace_sym_session_init(dev_id, sess, xforms, mp);
13544418919fSjohnjiang 	sess->sess_data[index].refcnt++;
1355d30ea906Sjfb8856606 	return 0;
1356d30ea906Sjfb8856606 }
1357d30ea906Sjfb8856606 
13584418919fSjohnjiang int
rte_cryptodev_asym_session_init(uint8_t dev_id,struct rte_cryptodev_asym_session * sess,struct rte_crypto_asym_xform * xforms,struct rte_mempool * mp)1359d30ea906Sjfb8856606 rte_cryptodev_asym_session_init(uint8_t dev_id,
1360d30ea906Sjfb8856606 		struct rte_cryptodev_asym_session *sess,
1361d30ea906Sjfb8856606 		struct rte_crypto_asym_xform *xforms,
1362d30ea906Sjfb8856606 		struct rte_mempool *mp)
1363d30ea906Sjfb8856606 {
1364d30ea906Sjfb8856606 	struct rte_cryptodev *dev;
1365d30ea906Sjfb8856606 	uint8_t index;
1366d30ea906Sjfb8856606 	int ret;
1367d30ea906Sjfb8856606 
13680c6bd470Sfengbojiang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
13690c6bd470Sfengbojiang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
13700c6bd470Sfengbojiang 		return -EINVAL;
13710c6bd470Sfengbojiang 	}
13720c6bd470Sfengbojiang 
1373d30ea906Sjfb8856606 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1374d30ea906Sjfb8856606 
1375d30ea906Sjfb8856606 	if (sess == NULL || xforms == NULL || dev == NULL)
1376d30ea906Sjfb8856606 		return -EINVAL;
1377d30ea906Sjfb8856606 
1378d30ea906Sjfb8856606 	index = dev->driver_id;
1379d30ea906Sjfb8856606 
1380d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_session_configure,
1381d30ea906Sjfb8856606 				-ENOTSUP);
1382d30ea906Sjfb8856606 
1383d30ea906Sjfb8856606 	if (sess->sess_private_data[index] == NULL) {
1384d30ea906Sjfb8856606 		ret = dev->dev_ops->asym_session_configure(dev,
1385d30ea906Sjfb8856606 							xforms,
1386d30ea906Sjfb8856606 							sess, mp);
13872bfe3f2eSlogwang 		if (ret < 0) {
13882bfe3f2eSlogwang 			CDEV_LOG_ERR(
13892bfe3f2eSlogwang 				"dev_id %d failed to configure session details",
13902bfe3f2eSlogwang 				dev_id);
13912bfe3f2eSlogwang 			return ret;
1392a9643ea8Slogwang 		}
1393a9643ea8Slogwang 	}
1394a9643ea8Slogwang 
1395*2d9fd380Sjfb8856606 	rte_cryptodev_trace_asym_session_init(dev_id, sess, xforms, mp);
1396a9643ea8Slogwang 	return 0;
1397a9643ea8Slogwang }
1398a9643ea8Slogwang 
13994418919fSjohnjiang struct rte_mempool *
rte_cryptodev_sym_session_pool_create(const char * name,uint32_t nb_elts,uint32_t elt_size,uint32_t cache_size,uint16_t user_data_size,int socket_id)14004418919fSjohnjiang rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts,
14014418919fSjohnjiang 	uint32_t elt_size, uint32_t cache_size, uint16_t user_data_size,
14024418919fSjohnjiang 	int socket_id)
14034418919fSjohnjiang {
14044418919fSjohnjiang 	struct rte_mempool *mp;
14054418919fSjohnjiang 	struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
14064418919fSjohnjiang 	uint32_t obj_sz;
14074418919fSjohnjiang 
14084418919fSjohnjiang 	obj_sz = rte_cryptodev_sym_get_header_session_size() + user_data_size;
14094418919fSjohnjiang 	if (obj_sz > elt_size)
14104418919fSjohnjiang 		CDEV_LOG_INFO("elt_size %u is expanded to %u\n", elt_size,
14114418919fSjohnjiang 				obj_sz);
14124418919fSjohnjiang 	else
14134418919fSjohnjiang 		obj_sz = elt_size;
14144418919fSjohnjiang 
14154418919fSjohnjiang 	mp = rte_mempool_create(name, nb_elts, obj_sz, cache_size,
14164418919fSjohnjiang 			(uint32_t)(sizeof(*pool_priv)),
14174418919fSjohnjiang 			NULL, NULL, NULL, NULL,
14184418919fSjohnjiang 			socket_id, 0);
14194418919fSjohnjiang 	if (mp == NULL) {
14204418919fSjohnjiang 		CDEV_LOG_ERR("%s(name=%s) failed, rte_errno=%d\n",
14214418919fSjohnjiang 			__func__, name, rte_errno);
14224418919fSjohnjiang 		return NULL;
14234418919fSjohnjiang 	}
14244418919fSjohnjiang 
14254418919fSjohnjiang 	pool_priv = rte_mempool_get_priv(mp);
14264418919fSjohnjiang 	if (!pool_priv) {
14274418919fSjohnjiang 		CDEV_LOG_ERR("%s(name=%s) failed to get private data\n",
14284418919fSjohnjiang 			__func__, name);
14294418919fSjohnjiang 		rte_mempool_free(mp);
14304418919fSjohnjiang 		return NULL;
14314418919fSjohnjiang 	}
14324418919fSjohnjiang 
14334418919fSjohnjiang 	pool_priv->nb_drivers = nb_drivers;
14344418919fSjohnjiang 	pool_priv->user_data_sz = user_data_size;
14354418919fSjohnjiang 
1436*2d9fd380Sjfb8856606 	rte_cryptodev_trace_sym_session_pool_create(name, nb_elts,
1437*2d9fd380Sjfb8856606 		elt_size, cache_size, user_data_size, mp);
14384418919fSjohnjiang 	return mp;
14394418919fSjohnjiang }
14404418919fSjohnjiang 
14414418919fSjohnjiang static unsigned int
rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session * sess)14424418919fSjohnjiang rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session *sess)
14434418919fSjohnjiang {
14444418919fSjohnjiang 	return (sizeof(sess->sess_data[0]) * sess->nb_drivers) +
14454418919fSjohnjiang 			sess->user_data_sz;
14464418919fSjohnjiang }
14474418919fSjohnjiang 
1448*2d9fd380Sjfb8856606 static uint8_t
rte_cryptodev_sym_is_valid_session_pool(struct rte_mempool * mp)1449*2d9fd380Sjfb8856606 rte_cryptodev_sym_is_valid_session_pool(struct rte_mempool *mp)
1450*2d9fd380Sjfb8856606 {
1451*2d9fd380Sjfb8856606 	struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
1452*2d9fd380Sjfb8856606 
1453*2d9fd380Sjfb8856606 	if (!mp)
1454*2d9fd380Sjfb8856606 		return 0;
1455*2d9fd380Sjfb8856606 
1456*2d9fd380Sjfb8856606 	pool_priv = rte_mempool_get_priv(mp);
1457*2d9fd380Sjfb8856606 
1458*2d9fd380Sjfb8856606 	if (!pool_priv || mp->private_data_size < sizeof(*pool_priv) ||
1459*2d9fd380Sjfb8856606 			pool_priv->nb_drivers != nb_drivers ||
1460*2d9fd380Sjfb8856606 			mp->elt_size <
1461*2d9fd380Sjfb8856606 				rte_cryptodev_sym_get_header_session_size()
1462*2d9fd380Sjfb8856606 				+ pool_priv->user_data_sz)
1463*2d9fd380Sjfb8856606 		return 0;
1464*2d9fd380Sjfb8856606 
1465*2d9fd380Sjfb8856606 	return 1;
1466*2d9fd380Sjfb8856606 }
1467*2d9fd380Sjfb8856606 
1468a9643ea8Slogwang struct rte_cryptodev_sym_session *
rte_cryptodev_sym_session_create(struct rte_mempool * mp)14692bfe3f2eSlogwang rte_cryptodev_sym_session_create(struct rte_mempool *mp)
1470a9643ea8Slogwang {
1471a9643ea8Slogwang 	struct rte_cryptodev_sym_session *sess;
14724418919fSjohnjiang 	struct rte_cryptodev_sym_session_pool_private_data *pool_priv;
14734418919fSjohnjiang 
1474*2d9fd380Sjfb8856606 	if (!rte_cryptodev_sym_is_valid_session_pool(mp)) {
14754418919fSjohnjiang 		CDEV_LOG_ERR("Invalid mempool\n");
14764418919fSjohnjiang 		return NULL;
14774418919fSjohnjiang 	}
14784418919fSjohnjiang 
14794418919fSjohnjiang 	pool_priv = rte_mempool_get_priv(mp);
14804418919fSjohnjiang 
1481a9643ea8Slogwang 	/* Allocate a session structure from the session pool */
14822bfe3f2eSlogwang 	if (rte_mempool_get(mp, (void **)&sess)) {
14832bfe3f2eSlogwang 		CDEV_LOG_ERR("couldn't get object from session mempool");
1484a9643ea8Slogwang 		return NULL;
1485a9643ea8Slogwang 	}
1486a9643ea8Slogwang 
14874418919fSjohnjiang 	sess->nb_drivers = pool_priv->nb_drivers;
14884418919fSjohnjiang 	sess->user_data_sz = pool_priv->user_data_sz;
14894418919fSjohnjiang 	sess->opaque_data = 0;
14904418919fSjohnjiang 
1491d30ea906Sjfb8856606 	/* Clear device session pointer.
1492d30ea906Sjfb8856606 	 * Include the flag indicating presence of user data
1493d30ea906Sjfb8856606 	 */
14944418919fSjohnjiang 	memset(sess->sess_data, 0,
14954418919fSjohnjiang 			rte_cryptodev_sym_session_data_size(sess));
1496a9643ea8Slogwang 
1497*2d9fd380Sjfb8856606 	rte_cryptodev_trace_sym_session_create(mp, sess);
1498a9643ea8Slogwang 	return sess;
1499a9643ea8Slogwang }
1500a9643ea8Slogwang 
15014418919fSjohnjiang struct rte_cryptodev_asym_session *
rte_cryptodev_asym_session_create(struct rte_mempool * mp)1502d30ea906Sjfb8856606 rte_cryptodev_asym_session_create(struct rte_mempool *mp)
1503a9643ea8Slogwang {
1504d30ea906Sjfb8856606 	struct rte_cryptodev_asym_session *sess;
1505*2d9fd380Sjfb8856606 	unsigned int session_size =
1506*2d9fd380Sjfb8856606 			rte_cryptodev_asym_get_header_session_size();
1507*2d9fd380Sjfb8856606 
1508*2d9fd380Sjfb8856606 	if (!mp) {
1509*2d9fd380Sjfb8856606 		CDEV_LOG_ERR("invalid mempool\n");
1510*2d9fd380Sjfb8856606 		return NULL;
1511*2d9fd380Sjfb8856606 	}
1512*2d9fd380Sjfb8856606 
1513*2d9fd380Sjfb8856606 	/* Verify if provided mempool can hold elements big enough. */
1514*2d9fd380Sjfb8856606 	if (mp->elt_size < session_size) {
1515*2d9fd380Sjfb8856606 		CDEV_LOG_ERR(
1516*2d9fd380Sjfb8856606 			"mempool elements too small to hold session objects");
1517*2d9fd380Sjfb8856606 		return NULL;
1518*2d9fd380Sjfb8856606 	}
1519a9643ea8Slogwang 
1520d30ea906Sjfb8856606 	/* Allocate a session structure from the session pool */
1521d30ea906Sjfb8856606 	if (rte_mempool_get(mp, (void **)&sess)) {
1522d30ea906Sjfb8856606 		CDEV_LOG_ERR("couldn't get object from session mempool");
1523d30ea906Sjfb8856606 		return NULL;
1524a9643ea8Slogwang 	}
1525a9643ea8Slogwang 
1526d30ea906Sjfb8856606 	/* Clear device session pointer.
1527d30ea906Sjfb8856606 	 * Include the flag indicating presence of private data
1528d30ea906Sjfb8856606 	 */
1529*2d9fd380Sjfb8856606 	memset(sess, 0, session_size);
1530a9643ea8Slogwang 
1531*2d9fd380Sjfb8856606 	rte_cryptodev_trace_asym_session_create(mp, sess);
1532d30ea906Sjfb8856606 	return sess;
15332bfe3f2eSlogwang }
15342bfe3f2eSlogwang 
15352bfe3f2eSlogwang int
rte_cryptodev_sym_session_clear(uint8_t dev_id,struct rte_cryptodev_sym_session * sess)15362bfe3f2eSlogwang rte_cryptodev_sym_session_clear(uint8_t dev_id,
15372bfe3f2eSlogwang 		struct rte_cryptodev_sym_session *sess)
15382bfe3f2eSlogwang {
15392bfe3f2eSlogwang 	struct rte_cryptodev *dev;
15404418919fSjohnjiang 	uint8_t driver_id;
15412bfe3f2eSlogwang 
15420c6bd470Sfengbojiang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
15430c6bd470Sfengbojiang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
15440c6bd470Sfengbojiang 		return -EINVAL;
15450c6bd470Sfengbojiang 	}
15460c6bd470Sfengbojiang 
15472bfe3f2eSlogwang 	dev = rte_cryptodev_pmd_get_dev(dev_id);
15482bfe3f2eSlogwang 
15492bfe3f2eSlogwang 	if (dev == NULL || sess == NULL)
15502bfe3f2eSlogwang 		return -EINVAL;
15512bfe3f2eSlogwang 
15524418919fSjohnjiang 	driver_id = dev->driver_id;
15534418919fSjohnjiang 	if (sess->sess_data[driver_id].refcnt == 0)
15544418919fSjohnjiang 		return 0;
15554418919fSjohnjiang 	if (--sess->sess_data[driver_id].refcnt != 0)
15564418919fSjohnjiang 		return -EBUSY;
15574418919fSjohnjiang 
1558d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->sym_session_clear, -ENOTSUP);
1559d30ea906Sjfb8856606 
1560d30ea906Sjfb8856606 	dev->dev_ops->sym_session_clear(dev, sess);
1561d30ea906Sjfb8856606 
1562*2d9fd380Sjfb8856606 	rte_cryptodev_trace_sym_session_clear(dev_id, sess);
1563d30ea906Sjfb8856606 	return 0;
1564d30ea906Sjfb8856606 }
1565d30ea906Sjfb8856606 
15664418919fSjohnjiang int
rte_cryptodev_asym_session_clear(uint8_t dev_id,struct rte_cryptodev_asym_session * sess)1567d30ea906Sjfb8856606 rte_cryptodev_asym_session_clear(uint8_t dev_id,
1568d30ea906Sjfb8856606 		struct rte_cryptodev_asym_session *sess)
1569d30ea906Sjfb8856606 {
1570d30ea906Sjfb8856606 	struct rte_cryptodev *dev;
1571d30ea906Sjfb8856606 
15720c6bd470Sfengbojiang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
15730c6bd470Sfengbojiang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
15740c6bd470Sfengbojiang 		return -EINVAL;
15750c6bd470Sfengbojiang 	}
15760c6bd470Sfengbojiang 
1577d30ea906Sjfb8856606 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1578d30ea906Sjfb8856606 
1579d30ea906Sjfb8856606 	if (dev == NULL || sess == NULL)
1580d30ea906Sjfb8856606 		return -EINVAL;
1581d30ea906Sjfb8856606 
1582d30ea906Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_session_clear, -ENOTSUP);
1583d30ea906Sjfb8856606 
1584d30ea906Sjfb8856606 	dev->dev_ops->asym_session_clear(dev, sess);
15852bfe3f2eSlogwang 
1586*2d9fd380Sjfb8856606 	rte_cryptodev_trace_sym_session_clear(dev_id, sess);
15872bfe3f2eSlogwang 	return 0;
15882bfe3f2eSlogwang }
15892bfe3f2eSlogwang 
15902bfe3f2eSlogwang int
rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session * sess)15912bfe3f2eSlogwang rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
15922bfe3f2eSlogwang {
15932bfe3f2eSlogwang 	uint8_t i;
15942bfe3f2eSlogwang 	struct rte_mempool *sess_mp;
15952bfe3f2eSlogwang 
15962bfe3f2eSlogwang 	if (sess == NULL)
15972bfe3f2eSlogwang 		return -EINVAL;
15982bfe3f2eSlogwang 
15992bfe3f2eSlogwang 	/* Check that all device private data has been freed */
16004418919fSjohnjiang 	for (i = 0; i < sess->nb_drivers; i++) {
16014418919fSjohnjiang 		if (sess->sess_data[i].refcnt != 0)
16022bfe3f2eSlogwang 			return -EBUSY;
16032bfe3f2eSlogwang 	}
1604a9643ea8Slogwang 
1605a9643ea8Slogwang 	/* Return session to mempool */
16062bfe3f2eSlogwang 	sess_mp = rte_mempool_from_obj(sess);
16072bfe3f2eSlogwang 	rte_mempool_put(sess_mp, sess);
1608a9643ea8Slogwang 
1609*2d9fd380Sjfb8856606 	rte_cryptodev_trace_sym_session_free(sess);
16102bfe3f2eSlogwang 	return 0;
16112bfe3f2eSlogwang }
16122bfe3f2eSlogwang 
16134418919fSjohnjiang int
rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session * sess)1614d30ea906Sjfb8856606 rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
1615d30ea906Sjfb8856606 {
1616d30ea906Sjfb8856606 	uint8_t i;
1617d30ea906Sjfb8856606 	void *sess_priv;
1618d30ea906Sjfb8856606 	struct rte_mempool *sess_mp;
1619d30ea906Sjfb8856606 
1620d30ea906Sjfb8856606 	if (sess == NULL)
1621d30ea906Sjfb8856606 		return -EINVAL;
1622d30ea906Sjfb8856606 
1623d30ea906Sjfb8856606 	/* Check that all device private data has been freed */
1624d30ea906Sjfb8856606 	for (i = 0; i < nb_drivers; i++) {
1625d30ea906Sjfb8856606 		sess_priv = get_asym_session_private_data(sess, i);
1626d30ea906Sjfb8856606 		if (sess_priv != NULL)
1627d30ea906Sjfb8856606 			return -EBUSY;
1628d30ea906Sjfb8856606 	}
1629d30ea906Sjfb8856606 
1630d30ea906Sjfb8856606 	/* Return session to mempool */
1631d30ea906Sjfb8856606 	sess_mp = rte_mempool_from_obj(sess);
1632d30ea906Sjfb8856606 	rte_mempool_put(sess_mp, sess);
1633d30ea906Sjfb8856606 
1634*2d9fd380Sjfb8856606 	rte_cryptodev_trace_asym_session_free(sess);
1635d30ea906Sjfb8856606 	return 0;
1636d30ea906Sjfb8856606 }
1637d30ea906Sjfb8856606 
16382bfe3f2eSlogwang unsigned int
rte_cryptodev_sym_get_header_session_size(void)1639d30ea906Sjfb8856606 rte_cryptodev_sym_get_header_session_size(void)
16402bfe3f2eSlogwang {
16412bfe3f2eSlogwang 	/*
16424418919fSjohnjiang 	 * Header contains pointers to the private data of all registered
16434418919fSjohnjiang 	 * drivers and all necessary information to ensure safely clear
16444418919fSjohnjiang 	 * or free al session.
16452bfe3f2eSlogwang 	 */
16464418919fSjohnjiang 	struct rte_cryptodev_sym_session s = {0};
16474418919fSjohnjiang 
16484418919fSjohnjiang 	s.nb_drivers = nb_drivers;
16494418919fSjohnjiang 
16504418919fSjohnjiang 	return (unsigned int)(sizeof(s) +
16514418919fSjohnjiang 			rte_cryptodev_sym_session_data_size(&s));
1652d30ea906Sjfb8856606 }
1653d30ea906Sjfb8856606 
16544418919fSjohnjiang unsigned int
rte_cryptodev_sym_get_existing_header_session_size(struct rte_cryptodev_sym_session * sess)16554418919fSjohnjiang rte_cryptodev_sym_get_existing_header_session_size(
16564418919fSjohnjiang 		struct rte_cryptodev_sym_session *sess)
16574418919fSjohnjiang {
16584418919fSjohnjiang 	if (!sess)
16594418919fSjohnjiang 		return 0;
16604418919fSjohnjiang 	else
16614418919fSjohnjiang 		return (unsigned int)(sizeof(*sess) +
16624418919fSjohnjiang 				rte_cryptodev_sym_session_data_size(sess));
16634418919fSjohnjiang }
16644418919fSjohnjiang 
16654418919fSjohnjiang unsigned int
rte_cryptodev_asym_get_header_session_size(void)1666d30ea906Sjfb8856606 rte_cryptodev_asym_get_header_session_size(void)
1667d30ea906Sjfb8856606 {
1668d30ea906Sjfb8856606 	/*
1669d30ea906Sjfb8856606 	 * Header contains pointers to the private data
1670d30ea906Sjfb8856606 	 * of all registered drivers, and a flag which
1671d30ea906Sjfb8856606 	 * indicates presence of private data
1672d30ea906Sjfb8856606 	 */
1673d30ea906Sjfb8856606 	return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
16742bfe3f2eSlogwang }
16752bfe3f2eSlogwang 
16762bfe3f2eSlogwang unsigned int
rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)1677d30ea906Sjfb8856606 rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
16782bfe3f2eSlogwang {
16792bfe3f2eSlogwang 	struct rte_cryptodev *dev;
16802bfe3f2eSlogwang 	unsigned int priv_sess_size;
16812bfe3f2eSlogwang 
16822bfe3f2eSlogwang 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
16832bfe3f2eSlogwang 		return 0;
16842bfe3f2eSlogwang 
16852bfe3f2eSlogwang 	dev = rte_cryptodev_pmd_get_dev(dev_id);
16862bfe3f2eSlogwang 
1687d30ea906Sjfb8856606 	if (*dev->dev_ops->sym_session_get_size == NULL)
16882bfe3f2eSlogwang 		return 0;
16892bfe3f2eSlogwang 
1690d30ea906Sjfb8856606 	priv_sess_size = (*dev->dev_ops->sym_session_get_size)(dev);
16912bfe3f2eSlogwang 
16922bfe3f2eSlogwang 	return priv_sess_size;
1693a9643ea8Slogwang }
1694a9643ea8Slogwang 
16954418919fSjohnjiang unsigned int
rte_cryptodev_asym_get_private_session_size(uint8_t dev_id)1696d30ea906Sjfb8856606 rte_cryptodev_asym_get_private_session_size(uint8_t dev_id)
1697d30ea906Sjfb8856606 {
1698d30ea906Sjfb8856606 	struct rte_cryptodev *dev;
1699d30ea906Sjfb8856606 	unsigned int header_size = sizeof(void *) * nb_drivers;
1700d30ea906Sjfb8856606 	unsigned int priv_sess_size;
1701d30ea906Sjfb8856606 
1702d30ea906Sjfb8856606 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
1703d30ea906Sjfb8856606 		return 0;
1704d30ea906Sjfb8856606 
1705d30ea906Sjfb8856606 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1706d30ea906Sjfb8856606 
1707d30ea906Sjfb8856606 	if (*dev->dev_ops->asym_session_get_size == NULL)
1708d30ea906Sjfb8856606 		return 0;
1709d30ea906Sjfb8856606 
1710d30ea906Sjfb8856606 	priv_sess_size = (*dev->dev_ops->asym_session_get_size)(dev);
1711d30ea906Sjfb8856606 	if (priv_sess_size < header_size)
1712d30ea906Sjfb8856606 		return header_size;
1713d30ea906Sjfb8856606 
1714d30ea906Sjfb8856606 	return priv_sess_size;
1715d30ea906Sjfb8856606 
1716d30ea906Sjfb8856606 }
1717d30ea906Sjfb8856606 
17184418919fSjohnjiang int
rte_cryptodev_sym_session_set_user_data(struct rte_cryptodev_sym_session * sess,void * data,uint16_t size)1719d30ea906Sjfb8856606 rte_cryptodev_sym_session_set_user_data(
1720d30ea906Sjfb8856606 					struct rte_cryptodev_sym_session *sess,
1721d30ea906Sjfb8856606 					void *data,
1722d30ea906Sjfb8856606 					uint16_t size)
1723d30ea906Sjfb8856606 {
1724d30ea906Sjfb8856606 	if (sess == NULL)
1725d30ea906Sjfb8856606 		return -EINVAL;
1726d30ea906Sjfb8856606 
17274418919fSjohnjiang 	if (sess->user_data_sz < size)
17284418919fSjohnjiang 		return -ENOMEM;
17294418919fSjohnjiang 
17304418919fSjohnjiang 	rte_memcpy(sess->sess_data + sess->nb_drivers, data, size);
1731d30ea906Sjfb8856606 	return 0;
1732d30ea906Sjfb8856606 }
1733d30ea906Sjfb8856606 
17344418919fSjohnjiang void *
rte_cryptodev_sym_session_get_user_data(struct rte_cryptodev_sym_session * sess)1735d30ea906Sjfb8856606 rte_cryptodev_sym_session_get_user_data(
1736d30ea906Sjfb8856606 					struct rte_cryptodev_sym_session *sess)
1737d30ea906Sjfb8856606 {
17384418919fSjohnjiang 	if (sess == NULL || sess->user_data_sz == 0)
1739d30ea906Sjfb8856606 		return NULL;
1740d30ea906Sjfb8856606 
17414418919fSjohnjiang 	return (void *)(sess->sess_data + sess->nb_drivers);
1742d30ea906Sjfb8856606 }
1743d30ea906Sjfb8856606 
1744*2d9fd380Sjfb8856606 static inline void
sym_crypto_fill_status(struct rte_crypto_sym_vec * vec,int32_t errnum)1745*2d9fd380Sjfb8856606 sym_crypto_fill_status(struct rte_crypto_sym_vec *vec, int32_t errnum)
1746*2d9fd380Sjfb8856606 {
1747*2d9fd380Sjfb8856606 	uint32_t i;
1748*2d9fd380Sjfb8856606 	for (i = 0; i < vec->num; i++)
1749*2d9fd380Sjfb8856606 		vec->status[i] = errnum;
1750*2d9fd380Sjfb8856606 }
1751*2d9fd380Sjfb8856606 
1752*2d9fd380Sjfb8856606 uint32_t
rte_cryptodev_sym_cpu_crypto_process(uint8_t dev_id,struct rte_cryptodev_sym_session * sess,union rte_crypto_sym_ofs ofs,struct rte_crypto_sym_vec * vec)1753*2d9fd380Sjfb8856606 rte_cryptodev_sym_cpu_crypto_process(uint8_t dev_id,
1754*2d9fd380Sjfb8856606 	struct rte_cryptodev_sym_session *sess, union rte_crypto_sym_ofs ofs,
1755*2d9fd380Sjfb8856606 	struct rte_crypto_sym_vec *vec)
1756*2d9fd380Sjfb8856606 {
1757*2d9fd380Sjfb8856606 	struct rte_cryptodev *dev;
1758*2d9fd380Sjfb8856606 
1759*2d9fd380Sjfb8856606 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
1760*2d9fd380Sjfb8856606 		sym_crypto_fill_status(vec, EINVAL);
1761*2d9fd380Sjfb8856606 		return 0;
1762*2d9fd380Sjfb8856606 	}
1763*2d9fd380Sjfb8856606 
1764*2d9fd380Sjfb8856606 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1765*2d9fd380Sjfb8856606 
1766*2d9fd380Sjfb8856606 	if (*dev->dev_ops->sym_cpu_process == NULL ||
1767*2d9fd380Sjfb8856606 		!(dev->feature_flags & RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO)) {
1768*2d9fd380Sjfb8856606 		sym_crypto_fill_status(vec, ENOTSUP);
1769*2d9fd380Sjfb8856606 		return 0;
1770*2d9fd380Sjfb8856606 	}
1771*2d9fd380Sjfb8856606 
1772*2d9fd380Sjfb8856606 	return dev->dev_ops->sym_cpu_process(dev, sess, ofs, vec);
1773*2d9fd380Sjfb8856606 }
1774*2d9fd380Sjfb8856606 
1775*2d9fd380Sjfb8856606 int
rte_cryptodev_get_raw_dp_ctx_size(uint8_t dev_id)1776*2d9fd380Sjfb8856606 rte_cryptodev_get_raw_dp_ctx_size(uint8_t dev_id)
1777*2d9fd380Sjfb8856606 {
1778*2d9fd380Sjfb8856606 	struct rte_cryptodev *dev;
1779*2d9fd380Sjfb8856606 	int32_t size = sizeof(struct rte_crypto_raw_dp_ctx);
1780*2d9fd380Sjfb8856606 	int32_t priv_size;
1781*2d9fd380Sjfb8856606 
1782*2d9fd380Sjfb8856606 	if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
1783*2d9fd380Sjfb8856606 		return -EINVAL;
1784*2d9fd380Sjfb8856606 
1785*2d9fd380Sjfb8856606 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1786*2d9fd380Sjfb8856606 
1787*2d9fd380Sjfb8856606 	if (*dev->dev_ops->sym_get_raw_dp_ctx_size == NULL ||
1788*2d9fd380Sjfb8856606 		!(dev->feature_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP)) {
1789*2d9fd380Sjfb8856606 		return -ENOTSUP;
1790*2d9fd380Sjfb8856606 	}
1791*2d9fd380Sjfb8856606 
1792*2d9fd380Sjfb8856606 	priv_size = (*dev->dev_ops->sym_get_raw_dp_ctx_size)(dev);
1793*2d9fd380Sjfb8856606 	if (priv_size < 0)
1794*2d9fd380Sjfb8856606 		return -ENOTSUP;
1795*2d9fd380Sjfb8856606 
1796*2d9fd380Sjfb8856606 	return RTE_ALIGN_CEIL((size + priv_size), 8);
1797*2d9fd380Sjfb8856606 }
1798*2d9fd380Sjfb8856606 
1799*2d9fd380Sjfb8856606 int
rte_cryptodev_configure_raw_dp_ctx(uint8_t dev_id,uint16_t qp_id,struct rte_crypto_raw_dp_ctx * ctx,enum rte_crypto_op_sess_type sess_type,union rte_cryptodev_session_ctx session_ctx,uint8_t is_update)1800*2d9fd380Sjfb8856606 rte_cryptodev_configure_raw_dp_ctx(uint8_t dev_id, uint16_t qp_id,
1801*2d9fd380Sjfb8856606 	struct rte_crypto_raw_dp_ctx *ctx,
1802*2d9fd380Sjfb8856606 	enum rte_crypto_op_sess_type sess_type,
1803*2d9fd380Sjfb8856606 	union rte_cryptodev_session_ctx session_ctx,
1804*2d9fd380Sjfb8856606 	uint8_t is_update)
1805*2d9fd380Sjfb8856606 {
1806*2d9fd380Sjfb8856606 	struct rte_cryptodev *dev;
1807*2d9fd380Sjfb8856606 
1808*2d9fd380Sjfb8856606 	if (!rte_cryptodev_get_qp_status(dev_id, qp_id))
1809*2d9fd380Sjfb8856606 		return -EINVAL;
1810*2d9fd380Sjfb8856606 
1811*2d9fd380Sjfb8856606 	dev = rte_cryptodev_pmd_get_dev(dev_id);
1812*2d9fd380Sjfb8856606 	if (!(dev->feature_flags & RTE_CRYPTODEV_FF_SYM_RAW_DP)
1813*2d9fd380Sjfb8856606 			|| dev->dev_ops->sym_configure_raw_dp_ctx == NULL)
1814*2d9fd380Sjfb8856606 		return -ENOTSUP;
1815*2d9fd380Sjfb8856606 
1816*2d9fd380Sjfb8856606 	return (*dev->dev_ops->sym_configure_raw_dp_ctx)(dev, qp_id, ctx,
1817*2d9fd380Sjfb8856606 			sess_type, session_ctx, is_update);
1818*2d9fd380Sjfb8856606 }
1819*2d9fd380Sjfb8856606 
1820*2d9fd380Sjfb8856606 uint32_t
rte_cryptodev_raw_enqueue_burst(struct rte_crypto_raw_dp_ctx * ctx,struct rte_crypto_sym_vec * vec,union rte_crypto_sym_ofs ofs,void ** user_data,int * enqueue_status)1821*2d9fd380Sjfb8856606 rte_cryptodev_raw_enqueue_burst(struct rte_crypto_raw_dp_ctx *ctx,
1822*2d9fd380Sjfb8856606 	struct rte_crypto_sym_vec *vec, union rte_crypto_sym_ofs ofs,
1823*2d9fd380Sjfb8856606 	void **user_data, int *enqueue_status)
1824*2d9fd380Sjfb8856606 {
1825*2d9fd380Sjfb8856606 	return (*ctx->enqueue_burst)(ctx->qp_data, ctx->drv_ctx_data, vec,
1826*2d9fd380Sjfb8856606 			ofs, user_data, enqueue_status);
1827*2d9fd380Sjfb8856606 }
1828*2d9fd380Sjfb8856606 
1829*2d9fd380Sjfb8856606 int
rte_cryptodev_raw_enqueue_done(struct rte_crypto_raw_dp_ctx * ctx,uint32_t n)1830*2d9fd380Sjfb8856606 rte_cryptodev_raw_enqueue_done(struct rte_crypto_raw_dp_ctx *ctx,
1831*2d9fd380Sjfb8856606 		uint32_t n)
1832*2d9fd380Sjfb8856606 {
1833*2d9fd380Sjfb8856606 	return (*ctx->enqueue_done)(ctx->qp_data, ctx->drv_ctx_data, n);
1834*2d9fd380Sjfb8856606 }
1835*2d9fd380Sjfb8856606 
1836*2d9fd380Sjfb8856606 uint32_t
rte_cryptodev_raw_dequeue_burst(struct rte_crypto_raw_dp_ctx * ctx,rte_cryptodev_raw_get_dequeue_count_t get_dequeue_count,rte_cryptodev_raw_post_dequeue_t post_dequeue,void ** out_user_data,uint8_t is_user_data_array,uint32_t * n_success_jobs,int * status)1837*2d9fd380Sjfb8856606 rte_cryptodev_raw_dequeue_burst(struct rte_crypto_raw_dp_ctx *ctx,
1838*2d9fd380Sjfb8856606 	rte_cryptodev_raw_get_dequeue_count_t get_dequeue_count,
1839*2d9fd380Sjfb8856606 	rte_cryptodev_raw_post_dequeue_t post_dequeue,
1840*2d9fd380Sjfb8856606 	void **out_user_data, uint8_t is_user_data_array,
1841*2d9fd380Sjfb8856606 	uint32_t *n_success_jobs, int *status)
1842*2d9fd380Sjfb8856606 {
1843*2d9fd380Sjfb8856606 	return (*ctx->dequeue_burst)(ctx->qp_data, ctx->drv_ctx_data,
1844*2d9fd380Sjfb8856606 		get_dequeue_count, post_dequeue, out_user_data,
1845*2d9fd380Sjfb8856606 		is_user_data_array, n_success_jobs, status);
1846*2d9fd380Sjfb8856606 }
1847*2d9fd380Sjfb8856606 
1848*2d9fd380Sjfb8856606 int
rte_cryptodev_raw_dequeue_done(struct rte_crypto_raw_dp_ctx * ctx,uint32_t n)1849*2d9fd380Sjfb8856606 rte_cryptodev_raw_dequeue_done(struct rte_crypto_raw_dp_ctx *ctx,
1850*2d9fd380Sjfb8856606 		uint32_t n)
1851*2d9fd380Sjfb8856606 {
1852*2d9fd380Sjfb8856606 	return (*ctx->dequeue_done)(ctx->qp_data, ctx->drv_ctx_data, n);
1853*2d9fd380Sjfb8856606 }
1854*2d9fd380Sjfb8856606 
1855a9643ea8Slogwang /** Initialise rte_crypto_op mempool element */
1856a9643ea8Slogwang static void
rte_crypto_op_init(struct rte_mempool * mempool,void * opaque_arg,void * _op_data,__rte_unused unsigned i)1857a9643ea8Slogwang rte_crypto_op_init(struct rte_mempool *mempool,
1858a9643ea8Slogwang 		void *opaque_arg,
1859a9643ea8Slogwang 		void *_op_data,
1860a9643ea8Slogwang 		__rte_unused unsigned i)
1861a9643ea8Slogwang {
1862a9643ea8Slogwang 	struct rte_crypto_op *op = _op_data;
1863a9643ea8Slogwang 	enum rte_crypto_op_type type = *(enum rte_crypto_op_type *)opaque_arg;
1864a9643ea8Slogwang 
1865a9643ea8Slogwang 	memset(_op_data, 0, mempool->elt_size);
1866a9643ea8Slogwang 
1867a9643ea8Slogwang 	__rte_crypto_op_reset(op, type);
1868a9643ea8Slogwang 
18692bfe3f2eSlogwang 	op->phys_addr = rte_mem_virt2iova(_op_data);
1870a9643ea8Slogwang 	op->mempool = mempool;
1871a9643ea8Slogwang }
1872a9643ea8Slogwang 
1873a9643ea8Slogwang 
1874a9643ea8Slogwang struct rte_mempool *
rte_crypto_op_pool_create(const char * name,enum rte_crypto_op_type type,unsigned nb_elts,unsigned cache_size,uint16_t priv_size,int socket_id)1875a9643ea8Slogwang rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type,
1876a9643ea8Slogwang 		unsigned nb_elts, unsigned cache_size, uint16_t priv_size,
1877a9643ea8Slogwang 		int socket_id)
1878a9643ea8Slogwang {
1879a9643ea8Slogwang 	struct rte_crypto_op_pool_private *priv;
1880a9643ea8Slogwang 
1881a9643ea8Slogwang 	unsigned elt_size = sizeof(struct rte_crypto_op) +
1882a9643ea8Slogwang 			priv_size;
1883a9643ea8Slogwang 
1884d30ea906Sjfb8856606 	if (type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
1885d30ea906Sjfb8856606 		elt_size += sizeof(struct rte_crypto_sym_op);
1886d30ea906Sjfb8856606 	} else if (type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
1887d30ea906Sjfb8856606 		elt_size += sizeof(struct rte_crypto_asym_op);
1888d30ea906Sjfb8856606 	} else if (type == RTE_CRYPTO_OP_TYPE_UNDEFINED) {
1889d30ea906Sjfb8856606 		elt_size += RTE_MAX(sizeof(struct rte_crypto_sym_op),
1890d30ea906Sjfb8856606 		                    sizeof(struct rte_crypto_asym_op));
1891d30ea906Sjfb8856606 	} else {
1892d30ea906Sjfb8856606 		CDEV_LOG_ERR("Invalid op_type\n");
1893d30ea906Sjfb8856606 		return NULL;
1894d30ea906Sjfb8856606 	}
1895d30ea906Sjfb8856606 
1896a9643ea8Slogwang 	/* lookup mempool in case already allocated */
1897a9643ea8Slogwang 	struct rte_mempool *mp = rte_mempool_lookup(name);
1898a9643ea8Slogwang 
1899a9643ea8Slogwang 	if (mp != NULL) {
1900a9643ea8Slogwang 		priv = (struct rte_crypto_op_pool_private *)
1901a9643ea8Slogwang 				rte_mempool_get_priv(mp);
1902a9643ea8Slogwang 
1903a9643ea8Slogwang 		if (mp->elt_size != elt_size ||
1904a9643ea8Slogwang 				mp->cache_size < cache_size ||
1905a9643ea8Slogwang 				mp->size < nb_elts ||
1906a9643ea8Slogwang 				priv->priv_size <  priv_size) {
1907a9643ea8Slogwang 			mp = NULL;
1908a9643ea8Slogwang 			CDEV_LOG_ERR("Mempool %s already exists but with "
1909a9643ea8Slogwang 					"incompatible parameters", name);
1910a9643ea8Slogwang 			return NULL;
1911a9643ea8Slogwang 		}
1912a9643ea8Slogwang 		return mp;
1913a9643ea8Slogwang 	}
1914a9643ea8Slogwang 
1915a9643ea8Slogwang 	mp = rte_mempool_create(
1916a9643ea8Slogwang 			name,
1917a9643ea8Slogwang 			nb_elts,
1918a9643ea8Slogwang 			elt_size,
1919a9643ea8Slogwang 			cache_size,
1920a9643ea8Slogwang 			sizeof(struct rte_crypto_op_pool_private),
1921a9643ea8Slogwang 			NULL,
1922a9643ea8Slogwang 			NULL,
1923a9643ea8Slogwang 			rte_crypto_op_init,
1924a9643ea8Slogwang 			&type,
1925a9643ea8Slogwang 			socket_id,
1926a9643ea8Slogwang 			0);
1927a9643ea8Slogwang 
1928a9643ea8Slogwang 	if (mp == NULL) {
1929a9643ea8Slogwang 		CDEV_LOG_ERR("Failed to create mempool %s", name);
1930a9643ea8Slogwang 		return NULL;
1931a9643ea8Slogwang 	}
1932a9643ea8Slogwang 
1933a9643ea8Slogwang 	priv = (struct rte_crypto_op_pool_private *)
1934a9643ea8Slogwang 			rte_mempool_get_priv(mp);
1935a9643ea8Slogwang 
1936a9643ea8Slogwang 	priv->priv_size = priv_size;
1937a9643ea8Slogwang 	priv->type = type;
1938a9643ea8Slogwang 
1939a9643ea8Slogwang 	return mp;
1940a9643ea8Slogwang }
19412bfe3f2eSlogwang 
19422bfe3f2eSlogwang int
rte_cryptodev_pmd_create_dev_name(char * name,const char * dev_name_prefix)19432bfe3f2eSlogwang rte_cryptodev_pmd_create_dev_name(char *name, const char *dev_name_prefix)
19442bfe3f2eSlogwang {
19452bfe3f2eSlogwang 	struct rte_cryptodev *dev = NULL;
19462bfe3f2eSlogwang 	uint32_t i = 0;
19472bfe3f2eSlogwang 
19482bfe3f2eSlogwang 	if (name == NULL)
19492bfe3f2eSlogwang 		return -EINVAL;
19502bfe3f2eSlogwang 
19512bfe3f2eSlogwang 	for (i = 0; i < RTE_CRYPTO_MAX_DEVS; i++) {
19522bfe3f2eSlogwang 		int ret = snprintf(name, RTE_CRYPTODEV_NAME_MAX_LEN,
19532bfe3f2eSlogwang 				"%s_%u", dev_name_prefix, i);
19542bfe3f2eSlogwang 
19552bfe3f2eSlogwang 		if (ret < 0)
19562bfe3f2eSlogwang 			return ret;
19572bfe3f2eSlogwang 
19582bfe3f2eSlogwang 		dev = rte_cryptodev_pmd_get_named_dev(name);
19592bfe3f2eSlogwang 		if (!dev)
19602bfe3f2eSlogwang 			return 0;
19612bfe3f2eSlogwang 	}
19622bfe3f2eSlogwang 
19632bfe3f2eSlogwang 	return -1;
19642bfe3f2eSlogwang }
19652bfe3f2eSlogwang 
19662bfe3f2eSlogwang TAILQ_HEAD(cryptodev_driver_list, cryptodev_driver);
19672bfe3f2eSlogwang 
19682bfe3f2eSlogwang static struct cryptodev_driver_list cryptodev_driver_list =
19692bfe3f2eSlogwang 	TAILQ_HEAD_INITIALIZER(cryptodev_driver_list);
19702bfe3f2eSlogwang 
19712bfe3f2eSlogwang int
rte_cryptodev_driver_id_get(const char * name)19722bfe3f2eSlogwang rte_cryptodev_driver_id_get(const char *name)
19732bfe3f2eSlogwang {
19742bfe3f2eSlogwang 	struct cryptodev_driver *driver;
19752bfe3f2eSlogwang 	const char *driver_name;
19762bfe3f2eSlogwang 
19772bfe3f2eSlogwang 	if (name == NULL) {
19782bfe3f2eSlogwang 		RTE_LOG(DEBUG, CRYPTODEV, "name pointer NULL");
19792bfe3f2eSlogwang 		return -1;
19802bfe3f2eSlogwang 	}
19812bfe3f2eSlogwang 
19822bfe3f2eSlogwang 	TAILQ_FOREACH(driver, &cryptodev_driver_list, next) {
19832bfe3f2eSlogwang 		driver_name = driver->driver->name;
19841646932aSjfb8856606 		if (strncmp(driver_name, name, strlen(driver_name) + 1) == 0)
19852bfe3f2eSlogwang 			return driver->id;
19862bfe3f2eSlogwang 	}
19872bfe3f2eSlogwang 	return -1;
19882bfe3f2eSlogwang }
19892bfe3f2eSlogwang 
19902bfe3f2eSlogwang const char *
rte_cryptodev_name_get(uint8_t dev_id)19912bfe3f2eSlogwang rte_cryptodev_name_get(uint8_t dev_id)
19922bfe3f2eSlogwang {
19930c6bd470Sfengbojiang 	struct rte_cryptodev *dev;
19942bfe3f2eSlogwang 
19950c6bd470Sfengbojiang 	if (!rte_cryptodev_is_valid_device_data(dev_id)) {
19960c6bd470Sfengbojiang 		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
19970c6bd470Sfengbojiang 		return NULL;
19980c6bd470Sfengbojiang 	}
19990c6bd470Sfengbojiang 
20000c6bd470Sfengbojiang 	dev = rte_cryptodev_pmd_get_dev(dev_id);
20012bfe3f2eSlogwang 	if (dev == NULL)
20022bfe3f2eSlogwang 		return NULL;
20032bfe3f2eSlogwang 
20042bfe3f2eSlogwang 	return dev->data->name;
20052bfe3f2eSlogwang }
20062bfe3f2eSlogwang 
20072bfe3f2eSlogwang const char *
rte_cryptodev_driver_name_get(uint8_t driver_id)20082bfe3f2eSlogwang rte_cryptodev_driver_name_get(uint8_t driver_id)
20092bfe3f2eSlogwang {
20102bfe3f2eSlogwang 	struct cryptodev_driver *driver;
20112bfe3f2eSlogwang 
20122bfe3f2eSlogwang 	TAILQ_FOREACH(driver, &cryptodev_driver_list, next)
20132bfe3f2eSlogwang 		if (driver->id == driver_id)
20142bfe3f2eSlogwang 			return driver->driver->name;
20152bfe3f2eSlogwang 	return NULL;
20162bfe3f2eSlogwang }
20172bfe3f2eSlogwang 
20182bfe3f2eSlogwang uint8_t
rte_cryptodev_allocate_driver(struct cryptodev_driver * crypto_drv,const struct rte_driver * drv)20192bfe3f2eSlogwang rte_cryptodev_allocate_driver(struct cryptodev_driver *crypto_drv,
20202bfe3f2eSlogwang 		const struct rte_driver *drv)
20212bfe3f2eSlogwang {
20222bfe3f2eSlogwang 	crypto_drv->driver = drv;
20232bfe3f2eSlogwang 	crypto_drv->id = nb_drivers;
20242bfe3f2eSlogwang 
20252bfe3f2eSlogwang 	TAILQ_INSERT_TAIL(&cryptodev_driver_list, crypto_drv, next);
20262bfe3f2eSlogwang 
20272bfe3f2eSlogwang 	return nb_drivers++;
20282bfe3f2eSlogwang }
2029