xref: /dpdk/drivers/crypto/scheduler/scheduler_pmd.c (revision e5e193acf09c9d4b08e8ed7f2bf9a61b5c204fff)
15566a3e3SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
25566a3e3SBruce Richardson  * Copyright(c) 2017 Intel Corporation
3503e9c5aSFan Zhang  */
4503e9c5aSFan Zhang #include <rte_common.h>
5503e9c5aSFan Zhang #include <rte_hexdump.h>
6503e9c5aSFan Zhang #include <rte_cryptodev.h>
7503e9c5aSFan Zhang #include <rte_cryptodev_pmd.h>
8d4a586d2SJianfeng Tan #include <rte_bus_vdev.h>
9503e9c5aSFan Zhang #include <rte_malloc.h>
10503e9c5aSFan Zhang #include <rte_cpuflags.h>
11503e9c5aSFan Zhang #include <rte_reorder.h>
12ee9586ddSFan Zhang #include <rte_string_fns.h>
13503e9c5aSFan Zhang 
14b88161beSBruce Richardson #include "rte_cryptodev_scheduler.h"
15503e9c5aSFan Zhang #include "scheduler_pmd_private.h"
16503e9c5aSFan Zhang 
17520dd992SFerruh Yigit uint8_t cryptodev_scheduler_driver_id;
187a364faeSSlawomir Mrozowicz 
19503e9c5aSFan Zhang struct scheduler_init_params {
20f2f020d2SDeclan Doherty 	struct rte_cryptodev_pmd_init_params def_p;
21503e9c5aSFan Zhang 	uint32_t nb_slaves;
22a0e805eeSFan Zhang 	enum rte_cryptodev_scheduler_mode mode;
23ee9586ddSFan Zhang 	char mode_param_str[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN];
24a0e805eeSFan Zhang 	uint32_t enable_ordering;
251b78e3f2SKirill Rybalchenko 	uint16_t wc_pool[RTE_MAX_LCORE];
261b78e3f2SKirill Rybalchenko 	uint16_t nb_wc;
2750e14527SFan Zhang 	char slave_names[RTE_CRYPTODEV_SCHEDULER_MAX_NB_SLAVES]
2850e14527SFan Zhang 			[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN];
29503e9c5aSFan Zhang };
30503e9c5aSFan Zhang 
31503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_NAME			("name")
32503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_SLAVE		("slave")
33a0e805eeSFan Zhang #define RTE_CRYPTODEV_VDEV_MODE			("mode")
34ee9586ddSFan Zhang #define RTE_CRYPTODEV_VDEV_MODE_PARAM		("mode_param")
35a0e805eeSFan Zhang #define RTE_CRYPTODEV_VDEV_ORDERING		("ordering")
36503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG	("max_nb_queue_pairs")
37503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_SOCKET_ID		("socket_id")
384c07e055SKirill Rybalchenko #define RTE_CRYPTODEV_VDEV_COREMASK		("coremask")
394c07e055SKirill Rybalchenko #define RTE_CRYPTODEV_VDEV_CORELIST		("corelist")
40503e9c5aSFan Zhang 
41b74fd6b8SFerruh Yigit static const char * const scheduler_valid_params[] = {
42503e9c5aSFan Zhang 	RTE_CRYPTODEV_VDEV_NAME,
43503e9c5aSFan Zhang 	RTE_CRYPTODEV_VDEV_SLAVE,
44a0e805eeSFan Zhang 	RTE_CRYPTODEV_VDEV_MODE,
45ee9586ddSFan Zhang 	RTE_CRYPTODEV_VDEV_MODE_PARAM,
46a0e805eeSFan Zhang 	RTE_CRYPTODEV_VDEV_ORDERING,
47503e9c5aSFan Zhang 	RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
484c07e055SKirill Rybalchenko 	RTE_CRYPTODEV_VDEV_SOCKET_ID,
494c07e055SKirill Rybalchenko 	RTE_CRYPTODEV_VDEV_COREMASK,
504c07e055SKirill Rybalchenko 	RTE_CRYPTODEV_VDEV_CORELIST
51503e9c5aSFan Zhang };
52503e9c5aSFan Zhang 
53a0e805eeSFan Zhang struct scheduler_parse_map {
54a0e805eeSFan Zhang 	const char *name;
55a0e805eeSFan Zhang 	uint32_t val;
56a0e805eeSFan Zhang };
57a0e805eeSFan Zhang 
58a0e805eeSFan Zhang const struct scheduler_parse_map scheduler_mode_map[] = {
59a0e805eeSFan Zhang 	{RTE_STR(SCHEDULER_MODE_NAME_ROUND_ROBIN),
60a0e805eeSFan Zhang 			CDEV_SCHED_MODE_ROUNDROBIN},
61a0e805eeSFan Zhang 	{RTE_STR(SCHEDULER_MODE_NAME_PKT_SIZE_DISTR),
62a0e805eeSFan Zhang 			CDEV_SCHED_MODE_PKT_SIZE_DISTR},
63a0e805eeSFan Zhang 	{RTE_STR(SCHEDULER_MODE_NAME_FAIL_OVER),
644c07e055SKirill Rybalchenko 			CDEV_SCHED_MODE_FAILOVER},
654c07e055SKirill Rybalchenko 	{RTE_STR(SCHEDULER_MODE_NAME_MULTI_CORE),
664c07e055SKirill Rybalchenko 			CDEV_SCHED_MODE_MULTICORE}
67a0e805eeSFan Zhang };
68a0e805eeSFan Zhang 
69a0e805eeSFan Zhang const struct scheduler_parse_map scheduler_ordering_map[] = {
70a0e805eeSFan Zhang 		{"enable", 1},
71a0e805eeSFan Zhang 		{"disable", 0}
72a0e805eeSFan Zhang };
73a0e805eeSFan Zhang 
746760463cSFan Zhang #define CDEV_SCHED_MODE_PARAM_SEP_CHAR		':'
756760463cSFan Zhang 
76503e9c5aSFan Zhang static int
77503e9c5aSFan Zhang cryptodev_scheduler_create(const char *name,
78917ac9c4SPablo de Lara 		struct rte_vdev_device *vdev,
79503e9c5aSFan Zhang 		struct scheduler_init_params *init_params)
80503e9c5aSFan Zhang {
81503e9c5aSFan Zhang 	struct rte_cryptodev *dev;
82503e9c5aSFan Zhang 	struct scheduler_ctx *sched_ctx;
83a0e805eeSFan Zhang 	uint32_t i;
84a0e805eeSFan Zhang 	int ret;
85503e9c5aSFan Zhang 
86f2f020d2SDeclan Doherty 	dev = rte_cryptodev_pmd_create(name, &vdev->device,
87f2f020d2SDeclan Doherty 			&init_params->def_p);
88503e9c5aSFan Zhang 	if (dev == NULL) {
8985aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "driver %s: failed to create cryptodev vdev",
90503e9c5aSFan Zhang 			name);
91503e9c5aSFan Zhang 		return -EFAULT;
92503e9c5aSFan Zhang 	}
93503e9c5aSFan Zhang 
94520dd992SFerruh Yigit 	dev->driver_id = cryptodev_scheduler_driver_id;
95503e9c5aSFan Zhang 	dev->dev_ops = rte_crypto_scheduler_pmd_ops;
96503e9c5aSFan Zhang 
97503e9c5aSFan Zhang 	sched_ctx = dev->data->dev_private;
98503e9c5aSFan Zhang 	sched_ctx->max_nb_queue_pairs =
99503e9c5aSFan Zhang 			init_params->def_p.max_nb_queue_pairs;
100503e9c5aSFan Zhang 
1014c07e055SKirill Rybalchenko 	if (init_params->mode == CDEV_SCHED_MODE_MULTICORE) {
1024c07e055SKirill Rybalchenko 		uint16_t i;
1034c07e055SKirill Rybalchenko 
1041b78e3f2SKirill Rybalchenko 		sched_ctx->nb_wc = init_params->nb_wc;
1054c07e055SKirill Rybalchenko 
1061b78e3f2SKirill Rybalchenko 		for (i = 0; i < sched_ctx->nb_wc; i++) {
1071b78e3f2SKirill Rybalchenko 			sched_ctx->wc_pool[i] = init_params->wc_pool[i];
10885aa6d34SHari Kumar 			CR_SCHED_LOG(INFO, "  Worker core[%u]=%u added",
1091b78e3f2SKirill Rybalchenko 				i, sched_ctx->wc_pool[i]);
1104c07e055SKirill Rybalchenko 		}
1114c07e055SKirill Rybalchenko 	}
1124c07e055SKirill Rybalchenko 
113a0e805eeSFan Zhang 	if (init_params->mode > CDEV_SCHED_MODE_USERDEFINED &&
114a0e805eeSFan Zhang 			init_params->mode < CDEV_SCHED_MODE_COUNT) {
1156760463cSFan Zhang 		union {
1166760463cSFan Zhang 			struct rte_cryptodev_scheduler_threshold_option
1176760463cSFan Zhang 					threshold_option;
1186760463cSFan Zhang 		} option;
1196760463cSFan Zhang 		enum rte_cryptodev_schedule_option_type option_type;
1206760463cSFan Zhang 		char param_name[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN] = {0};
1216760463cSFan Zhang 		char param_val[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN] = {0};
1226760463cSFan Zhang 		char *s, *end;
1236760463cSFan Zhang 
1243fb45fdbSFan Zhang 		ret = rte_cryptodev_scheduler_mode_set(dev->data->dev_id,
125a0e805eeSFan Zhang 			init_params->mode);
126a0e805eeSFan Zhang 		if (ret < 0) {
127a0e805eeSFan Zhang 			rte_cryptodev_pmd_release_device(dev);
128a0e805eeSFan Zhang 			return ret;
129a0e805eeSFan Zhang 		}
130a0e805eeSFan Zhang 
131a0e805eeSFan Zhang 		for (i = 0; i < RTE_DIM(scheduler_mode_map); i++) {
132a0e805eeSFan Zhang 			if (scheduler_mode_map[i].val != sched_ctx->mode)
133a0e805eeSFan Zhang 				continue;
134a0e805eeSFan Zhang 
13585aa6d34SHari Kumar 			CR_SCHED_LOG(INFO, "  Scheduling mode = %s",
136a0e805eeSFan Zhang 					scheduler_mode_map[i].name);
137a0e805eeSFan Zhang 			break;
138a0e805eeSFan Zhang 		}
1396760463cSFan Zhang 
1406760463cSFan Zhang 		if (strlen(init_params->mode_param_str) > 0) {
1416760463cSFan Zhang 			s = strchr(init_params->mode_param_str,
1426760463cSFan Zhang 					CDEV_SCHED_MODE_PARAM_SEP_CHAR);
1436760463cSFan Zhang 			if (s == NULL) {
1446760463cSFan Zhang 				CR_SCHED_LOG(ERR, "Invalid mode param");
1456760463cSFan Zhang 				return -EINVAL;
1466760463cSFan Zhang 			}
1476760463cSFan Zhang 
1486760463cSFan Zhang 			strlcpy(param_name, init_params->mode_param_str,
1496760463cSFan Zhang 					s - init_params->mode_param_str + 1);
1506760463cSFan Zhang 			s++;
1516760463cSFan Zhang 			strlcpy(param_val, s,
1526760463cSFan Zhang 					RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN);
1536760463cSFan Zhang 
1546760463cSFan Zhang 			switch (init_params->mode) {
1556760463cSFan Zhang 			case CDEV_SCHED_MODE_PKT_SIZE_DISTR:
1566760463cSFan Zhang 				if (strcmp(param_name,
1576760463cSFan Zhang 					RTE_CRYPTODEV_SCHEDULER_PARAM_THRES)
1586760463cSFan Zhang 						!= 0) {
1596760463cSFan Zhang 					CR_SCHED_LOG(ERR, "Invalid mode param");
1606760463cSFan Zhang 					return -EINVAL;
1616760463cSFan Zhang 				}
1626760463cSFan Zhang 				option_type = CDEV_SCHED_OPTION_THRESHOLD;
1636760463cSFan Zhang 
1646760463cSFan Zhang 				option.threshold_option.threshold =
1656760463cSFan Zhang 						strtoul(param_val, &end, 0);
1666760463cSFan Zhang 				break;
1676760463cSFan Zhang 			default:
1686760463cSFan Zhang 				CR_SCHED_LOG(ERR, "Invalid mode param");
1696760463cSFan Zhang 				return -EINVAL;
1706760463cSFan Zhang 			}
1716760463cSFan Zhang 
1726760463cSFan Zhang 			if (sched_ctx->ops.option_set(dev, option_type,
1736760463cSFan Zhang 					(void *)&option) < 0) {
1746760463cSFan Zhang 				CR_SCHED_LOG(ERR, "Invalid mode param");
1756760463cSFan Zhang 				return -EINVAL;
1766760463cSFan Zhang 			}
1776760463cSFan Zhang 
1786760463cSFan Zhang 			RTE_LOG(INFO, PMD, "  Sched mode param (%s = %s)\n",
1796760463cSFan Zhang 					param_name, param_val);
1806760463cSFan Zhang 		}
181a0e805eeSFan Zhang 	}
182a0e805eeSFan Zhang 
183a0e805eeSFan Zhang 	sched_ctx->reordering_enabled = init_params->enable_ordering;
184a0e805eeSFan Zhang 
185a0e805eeSFan Zhang 	for (i = 0; i < RTE_DIM(scheduler_ordering_map); i++) {
186a0e805eeSFan Zhang 		if (scheduler_ordering_map[i].val !=
187a0e805eeSFan Zhang 				sched_ctx->reordering_enabled)
188a0e805eeSFan Zhang 			continue;
189a0e805eeSFan Zhang 
19085aa6d34SHari Kumar 		CR_SCHED_LOG(INFO, "  Packet ordering = %s",
191a0e805eeSFan Zhang 				scheduler_ordering_map[i].name);
192a0e805eeSFan Zhang 
193a0e805eeSFan Zhang 		break;
194a0e805eeSFan Zhang 	}
195a0e805eeSFan Zhang 
19650e14527SFan Zhang 	for (i = 0; i < init_params->nb_slaves; i++) {
19750e14527SFan Zhang 		sched_ctx->init_slave_names[sched_ctx->nb_init_slaves] =
19850e14527SFan Zhang 			rte_zmalloc_socket(
19950e14527SFan Zhang 				NULL,
20050e14527SFan Zhang 				RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN, 0,
20150e14527SFan Zhang 				SOCKET_ID_ANY);
20250e14527SFan Zhang 
20350e14527SFan Zhang 		if (!sched_ctx->init_slave_names[
20450e14527SFan Zhang 				sched_ctx->nb_init_slaves]) {
20585aa6d34SHari Kumar 			CR_SCHED_LOG(ERR, "driver %s: Insufficient memory",
20650e14527SFan Zhang 					name);
20750e14527SFan Zhang 			return -ENOMEM;
20850e14527SFan Zhang 		}
20950e14527SFan Zhang 
21050e14527SFan Zhang 		strncpy(sched_ctx->init_slave_names[
21150e14527SFan Zhang 					sched_ctx->nb_init_slaves],
21250e14527SFan Zhang 				init_params->slave_names[i],
21350e14527SFan Zhang 				RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN - 1);
21450e14527SFan Zhang 
21550e14527SFan Zhang 		sched_ctx->nb_init_slaves++;
21650e14527SFan Zhang 	}
21750e14527SFan Zhang 
218c570f262SPablo de Lara 	/*
219c570f262SPablo de Lara 	 * Initialize capabilities structure as an empty structure,
220c570f262SPablo de Lara 	 * in case device information is requested when no slaves are attached
221c570f262SPablo de Lara 	 */
222c570f262SPablo de Lara 	sched_ctx->capabilities = rte_zmalloc_socket(NULL,
223c570f262SPablo de Lara 			sizeof(struct rte_cryptodev_capabilities),
224c570f262SPablo de Lara 			0, SOCKET_ID_ANY);
225c570f262SPablo de Lara 
226c570f262SPablo de Lara 	if (!sched_ctx->capabilities) {
22785aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Not enough memory for capability "
22885aa6d34SHari Kumar 				"information");
229c570f262SPablo de Lara 		return -ENOMEM;
230c570f262SPablo de Lara 	}
231c570f262SPablo de Lara 
232a0e805eeSFan Zhang 	return 0;
233503e9c5aSFan Zhang }
234503e9c5aSFan Zhang 
235503e9c5aSFan Zhang static int
2365d2aa461SJan Blunck cryptodev_scheduler_remove(struct rte_vdev_device *vdev)
237503e9c5aSFan Zhang {
2385d2aa461SJan Blunck 	const char *name;
239503e9c5aSFan Zhang 	struct rte_cryptodev *dev;
240503e9c5aSFan Zhang 	struct scheduler_ctx *sched_ctx;
241503e9c5aSFan Zhang 
2425d2aa461SJan Blunck 	if (vdev == NULL)
243503e9c5aSFan Zhang 		return -EINVAL;
244503e9c5aSFan Zhang 
2455d2aa461SJan Blunck 	name = rte_vdev_device_name(vdev);
246503e9c5aSFan Zhang 	dev = rte_cryptodev_pmd_get_named_dev(name);
247503e9c5aSFan Zhang 	if (dev == NULL)
248503e9c5aSFan Zhang 		return -EINVAL;
249503e9c5aSFan Zhang 
250503e9c5aSFan Zhang 	sched_ctx = dev->data->dev_private;
251503e9c5aSFan Zhang 
252503e9c5aSFan Zhang 	if (sched_ctx->nb_slaves) {
253503e9c5aSFan Zhang 		uint32_t i;
254503e9c5aSFan Zhang 
255503e9c5aSFan Zhang 		for (i = 0; i < sched_ctx->nb_slaves; i++)
256503e9c5aSFan Zhang 			rte_cryptodev_scheduler_slave_detach(dev->data->dev_id,
257503e9c5aSFan Zhang 					sched_ctx->slaves[i].dev_id);
258503e9c5aSFan Zhang 	}
259503e9c5aSFan Zhang 
260f2f020d2SDeclan Doherty 	return rte_cryptodev_pmd_destroy(dev);
261503e9c5aSFan Zhang }
262503e9c5aSFan Zhang 
263503e9c5aSFan Zhang /** Parse integer from integer argument */
264503e9c5aSFan Zhang static int
265503e9c5aSFan Zhang parse_integer_arg(const char *key __rte_unused,
266503e9c5aSFan Zhang 		const char *value, void *extra_args)
267503e9c5aSFan Zhang {
268503e9c5aSFan Zhang 	int *i = (int *) extra_args;
269503e9c5aSFan Zhang 
270503e9c5aSFan Zhang 	*i = atoi(value);
271503e9c5aSFan Zhang 	if (*i < 0) {
27285aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Argument has to be positive.");
273a0e805eeSFan Zhang 		return -EINVAL;
274503e9c5aSFan Zhang 	}
275503e9c5aSFan Zhang 
276503e9c5aSFan Zhang 	return 0;
277503e9c5aSFan Zhang }
278503e9c5aSFan Zhang 
2794c07e055SKirill Rybalchenko /** Parse integer from hexadecimal integer argument */
2804c07e055SKirill Rybalchenko static int
2814c07e055SKirill Rybalchenko parse_coremask_arg(const char *key __rte_unused,
2824c07e055SKirill Rybalchenko 		const char *value, void *extra_args)
2834c07e055SKirill Rybalchenko {
2841b78e3f2SKirill Rybalchenko 	int i, j, val;
2851b78e3f2SKirill Rybalchenko 	uint16_t idx = 0;
2861b78e3f2SKirill Rybalchenko 	char c;
2874c07e055SKirill Rybalchenko 	struct scheduler_init_params *params = extra_args;
2884c07e055SKirill Rybalchenko 
2891b78e3f2SKirill Rybalchenko 	params->nb_wc = 0;
2901b78e3f2SKirill Rybalchenko 
2911b78e3f2SKirill Rybalchenko 	if (value == NULL)
2921b78e3f2SKirill Rybalchenko 		return -1;
2931b78e3f2SKirill Rybalchenko 	/* Remove all blank characters ahead and after .
2941b78e3f2SKirill Rybalchenko 	 * Remove 0x/0X if exists.
2951b78e3f2SKirill Rybalchenko 	 */
2961b78e3f2SKirill Rybalchenko 	while (isblank(*value))
2971b78e3f2SKirill Rybalchenko 		value++;
2981b78e3f2SKirill Rybalchenko 	if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X')))
2991b78e3f2SKirill Rybalchenko 		value += 2;
3001b78e3f2SKirill Rybalchenko 	i = strlen(value);
3011b78e3f2SKirill Rybalchenko 	while ((i > 0) && isblank(value[i - 1]))
3021b78e3f2SKirill Rybalchenko 		i--;
3031b78e3f2SKirill Rybalchenko 
3041b78e3f2SKirill Rybalchenko 	if (i == 0)
3051b78e3f2SKirill Rybalchenko 		return -1;
3061b78e3f2SKirill Rybalchenko 
3071b78e3f2SKirill Rybalchenko 	for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
3081b78e3f2SKirill Rybalchenko 		c = value[i];
3091b78e3f2SKirill Rybalchenko 		if (isxdigit(c) == 0) {
3101b78e3f2SKirill Rybalchenko 			/* invalid characters */
3111b78e3f2SKirill Rybalchenko 			return -1;
3121b78e3f2SKirill Rybalchenko 		}
3131b78e3f2SKirill Rybalchenko 		if (isdigit(c))
3141b78e3f2SKirill Rybalchenko 			val = c - '0';
3151b78e3f2SKirill Rybalchenko 		else if (isupper(c))
3161b78e3f2SKirill Rybalchenko 			val = c - 'A' + 10;
3171b78e3f2SKirill Rybalchenko 		else
3181b78e3f2SKirill Rybalchenko 			val = c - 'a' + 10;
3191b78e3f2SKirill Rybalchenko 
3201b78e3f2SKirill Rybalchenko 		for (j = 0; j < 4 && idx < RTE_MAX_LCORE; j++, idx++) {
3211b78e3f2SKirill Rybalchenko 			if ((1 << j) & val)
3221b78e3f2SKirill Rybalchenko 				params->wc_pool[params->nb_wc++] = idx;
3231b78e3f2SKirill Rybalchenko 		}
3241b78e3f2SKirill Rybalchenko 	}
3254c07e055SKirill Rybalchenko 
3264c07e055SKirill Rybalchenko 	return 0;
3274c07e055SKirill Rybalchenko }
3284c07e055SKirill Rybalchenko 
3294c07e055SKirill Rybalchenko /** Parse integer from list of integers argument */
3304c07e055SKirill Rybalchenko static int
3314c07e055SKirill Rybalchenko parse_corelist_arg(const char *key __rte_unused,
3324c07e055SKirill Rybalchenko 		const char *value, void *extra_args)
3334c07e055SKirill Rybalchenko {
3344c07e055SKirill Rybalchenko 	struct scheduler_init_params *params = extra_args;
3354c07e055SKirill Rybalchenko 
3361b78e3f2SKirill Rybalchenko 	params->nb_wc = 0;
3374c07e055SKirill Rybalchenko 
3384c07e055SKirill Rybalchenko 	const char *token = value;
3394c07e055SKirill Rybalchenko 
3404c07e055SKirill Rybalchenko 	while (isdigit(token[0])) {
3414c07e055SKirill Rybalchenko 		char *rval;
3424c07e055SKirill Rybalchenko 		unsigned int core = strtoul(token, &rval, 10);
3434c07e055SKirill Rybalchenko 
3441b78e3f2SKirill Rybalchenko 		if (core >= RTE_MAX_LCORE) {
34585aa6d34SHari Kumar 			CR_SCHED_LOG(ERR, "Invalid worker core %u, should be smaller "
34685aa6d34SHari Kumar 				   "than %u.", core, RTE_MAX_LCORE);
3471b78e3f2SKirill Rybalchenko 		}
3481b78e3f2SKirill Rybalchenko 		params->wc_pool[params->nb_wc++] = (uint16_t)core;
3494c07e055SKirill Rybalchenko 		token = (const char *)rval;
3504c07e055SKirill Rybalchenko 		if (token[0] == '\0')
3514c07e055SKirill Rybalchenko 			break;
3524c07e055SKirill Rybalchenko 		token++;
3534c07e055SKirill Rybalchenko 	}
3544c07e055SKirill Rybalchenko 
3554c07e055SKirill Rybalchenko 	return 0;
3564c07e055SKirill Rybalchenko }
3574c07e055SKirill Rybalchenko 
358503e9c5aSFan Zhang /** Parse name */
359503e9c5aSFan Zhang static int
360503e9c5aSFan Zhang parse_name_arg(const char *key __rte_unused,
361503e9c5aSFan Zhang 		const char *value, void *extra_args)
362503e9c5aSFan Zhang {
363f2f020d2SDeclan Doherty 	struct rte_cryptodev_pmd_init_params *params = extra_args;
364503e9c5aSFan Zhang 
365503e9c5aSFan Zhang 	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
36685aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Invalid name %s, should be less than "
36785aa6d34SHari Kumar 				"%u bytes.", value,
368503e9c5aSFan Zhang 				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
369a0e805eeSFan Zhang 		return -EINVAL;
370503e9c5aSFan Zhang 	}
371503e9c5aSFan Zhang 
372*e5e193acSJerin Jacob 	strlcpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
373503e9c5aSFan Zhang 
374503e9c5aSFan Zhang 	return 0;
375503e9c5aSFan Zhang }
376503e9c5aSFan Zhang 
377503e9c5aSFan Zhang /** Parse slave */
378503e9c5aSFan Zhang static int
379503e9c5aSFan Zhang parse_slave_arg(const char *key __rte_unused,
380503e9c5aSFan Zhang 		const char *value, void *extra_args)
381503e9c5aSFan Zhang {
382503e9c5aSFan Zhang 	struct scheduler_init_params *param = extra_args;
383503e9c5aSFan Zhang 
384829d1327SFan Zhang 	if (param->nb_slaves >= RTE_CRYPTODEV_SCHEDULER_MAX_NB_SLAVES) {
38585aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Too many slaves.");
386a0e805eeSFan Zhang 		return -ENOMEM;
387503e9c5aSFan Zhang 	}
388503e9c5aSFan Zhang 
38950e14527SFan Zhang 	strncpy(param->slave_names[param->nb_slaves++], value,
39050e14527SFan Zhang 			RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN - 1);
391503e9c5aSFan Zhang 
392503e9c5aSFan Zhang 	return 0;
393503e9c5aSFan Zhang }
394503e9c5aSFan Zhang 
395503e9c5aSFan Zhang static int
396a0e805eeSFan Zhang parse_mode_arg(const char *key __rte_unused,
397a0e805eeSFan Zhang 		const char *value, void *extra_args)
398a0e805eeSFan Zhang {
399a0e805eeSFan Zhang 	struct scheduler_init_params *param = extra_args;
400a0e805eeSFan Zhang 	uint32_t i;
401a0e805eeSFan Zhang 
402a0e805eeSFan Zhang 	for (i = 0; i < RTE_DIM(scheduler_mode_map); i++) {
403a0e805eeSFan Zhang 		if (strcmp(value, scheduler_mode_map[i].name) == 0) {
404a0e805eeSFan Zhang 			param->mode = (enum rte_cryptodev_scheduler_mode)
405a0e805eeSFan Zhang 					scheduler_mode_map[i].val;
406ee9586ddSFan Zhang 
407a0e805eeSFan Zhang 			break;
408a0e805eeSFan Zhang 		}
409a0e805eeSFan Zhang 	}
410a0e805eeSFan Zhang 
411a0e805eeSFan Zhang 	if (i == RTE_DIM(scheduler_mode_map)) {
41285aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Unrecognized input.");
413a0e805eeSFan Zhang 		return -EINVAL;
414a0e805eeSFan Zhang 	}
415a0e805eeSFan Zhang 
416a0e805eeSFan Zhang 	return 0;
417a0e805eeSFan Zhang }
418a0e805eeSFan Zhang 
419a0e805eeSFan Zhang static int
420ee9586ddSFan Zhang parse_mode_param_arg(const char *key __rte_unused,
421ee9586ddSFan Zhang 		const char *value, void *extra_args)
422ee9586ddSFan Zhang {
423ee9586ddSFan Zhang 	struct scheduler_init_params *param = extra_args;
424ee9586ddSFan Zhang 
425ee9586ddSFan Zhang 	strlcpy(param->mode_param_str, value,
426ee9586ddSFan Zhang 			RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN);
427ee9586ddSFan Zhang 
428ee9586ddSFan Zhang 	return 0;
429ee9586ddSFan Zhang }
430ee9586ddSFan Zhang 
431ee9586ddSFan Zhang static int
432a0e805eeSFan Zhang parse_ordering_arg(const char *key __rte_unused,
433a0e805eeSFan Zhang 		const char *value, void *extra_args)
434a0e805eeSFan Zhang {
435a0e805eeSFan Zhang 	struct scheduler_init_params *param = extra_args;
436a0e805eeSFan Zhang 	uint32_t i;
437a0e805eeSFan Zhang 
438a0e805eeSFan Zhang 	for (i = 0; i < RTE_DIM(scheduler_ordering_map); i++) {
439a0e805eeSFan Zhang 		if (strcmp(value, scheduler_ordering_map[i].name) == 0) {
440a0e805eeSFan Zhang 			param->enable_ordering =
441a0e805eeSFan Zhang 					scheduler_ordering_map[i].val;
442a0e805eeSFan Zhang 			break;
443a0e805eeSFan Zhang 		}
444a0e805eeSFan Zhang 	}
445a0e805eeSFan Zhang 
446a0e805eeSFan Zhang 	if (i == RTE_DIM(scheduler_ordering_map)) {
44785aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Unrecognized input.");
448a0e805eeSFan Zhang 		return -EINVAL;
449a0e805eeSFan Zhang 	}
450a0e805eeSFan Zhang 
451a0e805eeSFan Zhang 	return 0;
452a0e805eeSFan Zhang }
453a0e805eeSFan Zhang 
454a0e805eeSFan Zhang static int
455503e9c5aSFan Zhang scheduler_parse_init_params(struct scheduler_init_params *params,
456503e9c5aSFan Zhang 		const char *input_args)
457503e9c5aSFan Zhang {
458503e9c5aSFan Zhang 	struct rte_kvargs *kvlist = NULL;
459503e9c5aSFan Zhang 	int ret = 0;
460503e9c5aSFan Zhang 
461503e9c5aSFan Zhang 	if (params == NULL)
462503e9c5aSFan Zhang 		return -EINVAL;
463503e9c5aSFan Zhang 
464503e9c5aSFan Zhang 	if (input_args) {
465503e9c5aSFan Zhang 		kvlist = rte_kvargs_parse(input_args,
466503e9c5aSFan Zhang 				scheduler_valid_params);
467503e9c5aSFan Zhang 		if (kvlist == NULL)
468503e9c5aSFan Zhang 			return -1;
469503e9c5aSFan Zhang 
470503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist,
471503e9c5aSFan Zhang 				RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
472503e9c5aSFan Zhang 				&parse_integer_arg,
473503e9c5aSFan Zhang 				&params->def_p.max_nb_queue_pairs);
474503e9c5aSFan Zhang 		if (ret < 0)
475503e9c5aSFan Zhang 			goto free_kvlist;
476503e9c5aSFan Zhang 
477503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
478503e9c5aSFan Zhang 				&parse_integer_arg,
479503e9c5aSFan Zhang 				&params->def_p.socket_id);
480503e9c5aSFan Zhang 		if (ret < 0)
481503e9c5aSFan Zhang 			goto free_kvlist;
482503e9c5aSFan Zhang 
4834c07e055SKirill Rybalchenko 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_COREMASK,
4844c07e055SKirill Rybalchenko 				&parse_coremask_arg,
4854c07e055SKirill Rybalchenko 				params);
4864c07e055SKirill Rybalchenko 		if (ret < 0)
4874c07e055SKirill Rybalchenko 			goto free_kvlist;
4884c07e055SKirill Rybalchenko 
4894c07e055SKirill Rybalchenko 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_CORELIST,
4904c07e055SKirill Rybalchenko 				&parse_corelist_arg,
4914c07e055SKirill Rybalchenko 				params);
4924c07e055SKirill Rybalchenko 		if (ret < 0)
4934c07e055SKirill Rybalchenko 			goto free_kvlist;
4944c07e055SKirill Rybalchenko 
495503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
496503e9c5aSFan Zhang 				&parse_name_arg,
497503e9c5aSFan Zhang 				&params->def_p);
498503e9c5aSFan Zhang 		if (ret < 0)
499503e9c5aSFan Zhang 			goto free_kvlist;
500503e9c5aSFan Zhang 
501503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SLAVE,
502503e9c5aSFan Zhang 				&parse_slave_arg, params);
503503e9c5aSFan Zhang 		if (ret < 0)
504503e9c5aSFan Zhang 			goto free_kvlist;
505503e9c5aSFan Zhang 
506a0e805eeSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_MODE,
507a0e805eeSFan Zhang 				&parse_mode_arg, params);
508a0e805eeSFan Zhang 		if (ret < 0)
509a0e805eeSFan Zhang 			goto free_kvlist;
510a0e805eeSFan Zhang 
511ee9586ddSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_MODE_PARAM,
512ee9586ddSFan Zhang 				&parse_mode_param_arg, params);
513ee9586ddSFan Zhang 		if (ret < 0)
514ee9586ddSFan Zhang 			goto free_kvlist;
515ee9586ddSFan Zhang 
516a0e805eeSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_ORDERING,
517a0e805eeSFan Zhang 				&parse_ordering_arg, params);
518a0e805eeSFan Zhang 		if (ret < 0)
519a0e805eeSFan Zhang 			goto free_kvlist;
520503e9c5aSFan Zhang 	}
521503e9c5aSFan Zhang 
522503e9c5aSFan Zhang free_kvlist:
523503e9c5aSFan Zhang 	rte_kvargs_free(kvlist);
524503e9c5aSFan Zhang 	return ret;
525503e9c5aSFan Zhang }
526503e9c5aSFan Zhang 
527503e9c5aSFan Zhang static int
5285d2aa461SJan Blunck cryptodev_scheduler_probe(struct rte_vdev_device *vdev)
529503e9c5aSFan Zhang {
530503e9c5aSFan Zhang 	struct scheduler_init_params init_params = {
531503e9c5aSFan Zhang 		.def_p = {
532f2f020d2SDeclan Doherty 			"",
533f2f020d2SDeclan Doherty 			sizeof(struct scheduler_ctx),
534503e9c5aSFan Zhang 			rte_socket_id(),
535e1fc5b76SPablo de Lara 			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
536503e9c5aSFan Zhang 		},
537503e9c5aSFan Zhang 		.nb_slaves = 0,
538a0e805eeSFan Zhang 		.mode = CDEV_SCHED_MODE_NOT_SET,
53950e14527SFan Zhang 		.enable_ordering = 0,
54050e14527SFan Zhang 		.slave_names = { {0} }
541503e9c5aSFan Zhang 	};
5427e214771SPablo de Lara 	const char *name;
5437e214771SPablo de Lara 
5447e214771SPablo de Lara 	name = rte_vdev_device_name(vdev);
5457e214771SPablo de Lara 	if (name == NULL)
5467e214771SPablo de Lara 		return -EINVAL;
547503e9c5aSFan Zhang 
5485d2aa461SJan Blunck 	scheduler_parse_init_params(&init_params,
5495d2aa461SJan Blunck 				    rte_vdev_device_args(vdev));
550503e9c5aSFan Zhang 
551503e9c5aSFan Zhang 
552168b9e76SPablo de Lara 	return cryptodev_scheduler_create(name,
553917ac9c4SPablo de Lara 					vdev,
5545d2aa461SJan Blunck 					&init_params);
555503e9c5aSFan Zhang }
556503e9c5aSFan Zhang 
557503e9c5aSFan Zhang static struct rte_vdev_driver cryptodev_scheduler_pmd_drv = {
558503e9c5aSFan Zhang 	.probe = cryptodev_scheduler_probe,
559503e9c5aSFan Zhang 	.remove = cryptodev_scheduler_remove
560503e9c5aSFan Zhang };
561503e9c5aSFan Zhang 
562effd3b9fSPablo de Lara static struct cryptodev_driver scheduler_crypto_drv;
563effd3b9fSPablo de Lara 
564503e9c5aSFan Zhang RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SCHEDULER_PMD,
565503e9c5aSFan Zhang 	cryptodev_scheduler_pmd_drv);
566503e9c5aSFan Zhang RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SCHEDULER_PMD,
567503e9c5aSFan Zhang 	"max_nb_queue_pairs=<int> "
568503e9c5aSFan Zhang 	"socket_id=<int> "
569503e9c5aSFan Zhang 	"slave=<name>");
570effd3b9fSPablo de Lara RTE_PMD_REGISTER_CRYPTO_DRIVER(scheduler_crypto_drv,
571f737f5ceSFiona Trahe 		cryptodev_scheduler_pmd_drv.driver,
572520dd992SFerruh Yigit 		cryptodev_scheduler_driver_id);
573