xref: /dpdk/drivers/crypto/scheduler/scheduler_pmd.c (revision ee9586dd15fbd07d82bd674eb26b5c7bf4c309db)
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>
12*ee9586ddSFan Zhang #include <rte_string_fns.h>
13503e9c5aSFan Zhang 
14b88161beSBruce Richardson #include "rte_cryptodev_scheduler.h"
15503e9c5aSFan Zhang #include "scheduler_pmd_private.h"
16503e9c5aSFan Zhang 
177a364faeSSlawomir Mrozowicz uint8_t cryptodev_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;
23*ee9586ddSFan 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")
34*ee9586ddSFan 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 
41503e9c5aSFan Zhang const char *scheduler_valid_params[] = {
42503e9c5aSFan Zhang 	RTE_CRYPTODEV_VDEV_NAME,
43503e9c5aSFan Zhang 	RTE_CRYPTODEV_VDEV_SLAVE,
44a0e805eeSFan Zhang 	RTE_CRYPTODEV_VDEV_MODE,
45*ee9586ddSFan 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 
74503e9c5aSFan Zhang static int
75503e9c5aSFan Zhang cryptodev_scheduler_create(const char *name,
76917ac9c4SPablo de Lara 		struct rte_vdev_device *vdev,
77503e9c5aSFan Zhang 		struct scheduler_init_params *init_params)
78503e9c5aSFan Zhang {
79503e9c5aSFan Zhang 	struct rte_cryptodev *dev;
80503e9c5aSFan Zhang 	struct scheduler_ctx *sched_ctx;
81a0e805eeSFan Zhang 	uint32_t i;
82a0e805eeSFan Zhang 	int ret;
83503e9c5aSFan Zhang 
84f2f020d2SDeclan Doherty 	dev = rte_cryptodev_pmd_create(name, &vdev->device,
85f2f020d2SDeclan Doherty 			&init_params->def_p);
86503e9c5aSFan Zhang 	if (dev == NULL) {
8785aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "driver %s: failed to create cryptodev vdev",
88503e9c5aSFan Zhang 			name);
89503e9c5aSFan Zhang 		return -EFAULT;
90503e9c5aSFan Zhang 	}
91503e9c5aSFan Zhang 
927a364faeSSlawomir Mrozowicz 	dev->driver_id = cryptodev_driver_id;
93503e9c5aSFan Zhang 	dev->dev_ops = rte_crypto_scheduler_pmd_ops;
94503e9c5aSFan Zhang 
95503e9c5aSFan Zhang 	sched_ctx = dev->data->dev_private;
96503e9c5aSFan Zhang 	sched_ctx->max_nb_queue_pairs =
97503e9c5aSFan Zhang 			init_params->def_p.max_nb_queue_pairs;
98503e9c5aSFan Zhang 
994c07e055SKirill Rybalchenko 	if (init_params->mode == CDEV_SCHED_MODE_MULTICORE) {
1004c07e055SKirill Rybalchenko 		uint16_t i;
1014c07e055SKirill Rybalchenko 
1021b78e3f2SKirill Rybalchenko 		sched_ctx->nb_wc = init_params->nb_wc;
1034c07e055SKirill Rybalchenko 
1041b78e3f2SKirill Rybalchenko 		for (i = 0; i < sched_ctx->nb_wc; i++) {
1051b78e3f2SKirill Rybalchenko 			sched_ctx->wc_pool[i] = init_params->wc_pool[i];
10685aa6d34SHari Kumar 			CR_SCHED_LOG(INFO, "  Worker core[%u]=%u added",
1071b78e3f2SKirill Rybalchenko 				i, sched_ctx->wc_pool[i]);
1084c07e055SKirill Rybalchenko 		}
1094c07e055SKirill Rybalchenko 	}
1104c07e055SKirill Rybalchenko 
111a0e805eeSFan Zhang 	if (init_params->mode > CDEV_SCHED_MODE_USERDEFINED &&
112a0e805eeSFan Zhang 			init_params->mode < CDEV_SCHED_MODE_COUNT) {
1133fb45fdbSFan Zhang 		ret = rte_cryptodev_scheduler_mode_set(dev->data->dev_id,
114a0e805eeSFan Zhang 			init_params->mode);
115a0e805eeSFan Zhang 		if (ret < 0) {
116a0e805eeSFan Zhang 			rte_cryptodev_pmd_release_device(dev);
117a0e805eeSFan Zhang 			return ret;
118a0e805eeSFan Zhang 		}
119a0e805eeSFan Zhang 
120a0e805eeSFan Zhang 		for (i = 0; i < RTE_DIM(scheduler_mode_map); i++) {
121a0e805eeSFan Zhang 			if (scheduler_mode_map[i].val != sched_ctx->mode)
122a0e805eeSFan Zhang 				continue;
123a0e805eeSFan Zhang 
12485aa6d34SHari Kumar 			CR_SCHED_LOG(INFO, "  Scheduling mode = %s",
125a0e805eeSFan Zhang 					scheduler_mode_map[i].name);
126a0e805eeSFan Zhang 			break;
127a0e805eeSFan Zhang 		}
128a0e805eeSFan Zhang 	}
129a0e805eeSFan Zhang 
130a0e805eeSFan Zhang 	sched_ctx->reordering_enabled = init_params->enable_ordering;
131a0e805eeSFan Zhang 
132a0e805eeSFan Zhang 	for (i = 0; i < RTE_DIM(scheduler_ordering_map); i++) {
133a0e805eeSFan Zhang 		if (scheduler_ordering_map[i].val !=
134a0e805eeSFan Zhang 				sched_ctx->reordering_enabled)
135a0e805eeSFan Zhang 			continue;
136a0e805eeSFan Zhang 
13785aa6d34SHari Kumar 		CR_SCHED_LOG(INFO, "  Packet ordering = %s",
138a0e805eeSFan Zhang 				scheduler_ordering_map[i].name);
139a0e805eeSFan Zhang 
140a0e805eeSFan Zhang 		break;
141a0e805eeSFan Zhang 	}
142a0e805eeSFan Zhang 
14350e14527SFan Zhang 	for (i = 0; i < init_params->nb_slaves; i++) {
14450e14527SFan Zhang 		sched_ctx->init_slave_names[sched_ctx->nb_init_slaves] =
14550e14527SFan Zhang 			rte_zmalloc_socket(
14650e14527SFan Zhang 				NULL,
14750e14527SFan Zhang 				RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN, 0,
14850e14527SFan Zhang 				SOCKET_ID_ANY);
14950e14527SFan Zhang 
15050e14527SFan Zhang 		if (!sched_ctx->init_slave_names[
15150e14527SFan Zhang 				sched_ctx->nb_init_slaves]) {
15285aa6d34SHari Kumar 			CR_SCHED_LOG(ERR, "driver %s: Insufficient memory",
15350e14527SFan Zhang 					name);
15450e14527SFan Zhang 			return -ENOMEM;
15550e14527SFan Zhang 		}
15650e14527SFan Zhang 
15750e14527SFan Zhang 		strncpy(sched_ctx->init_slave_names[
15850e14527SFan Zhang 					sched_ctx->nb_init_slaves],
15950e14527SFan Zhang 				init_params->slave_names[i],
16050e14527SFan Zhang 				RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN - 1);
16150e14527SFan Zhang 
16250e14527SFan Zhang 		sched_ctx->nb_init_slaves++;
16350e14527SFan Zhang 	}
16450e14527SFan Zhang 
165c570f262SPablo de Lara 	/*
166c570f262SPablo de Lara 	 * Initialize capabilities structure as an empty structure,
167c570f262SPablo de Lara 	 * in case device information is requested when no slaves are attached
168c570f262SPablo de Lara 	 */
169c570f262SPablo de Lara 	sched_ctx->capabilities = rte_zmalloc_socket(NULL,
170c570f262SPablo de Lara 			sizeof(struct rte_cryptodev_capabilities),
171c570f262SPablo de Lara 			0, SOCKET_ID_ANY);
172c570f262SPablo de Lara 
173c570f262SPablo de Lara 	if (!sched_ctx->capabilities) {
17485aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Not enough memory for capability "
17585aa6d34SHari Kumar 				"information");
176c570f262SPablo de Lara 		return -ENOMEM;
177c570f262SPablo de Lara 	}
178c570f262SPablo de Lara 
179a0e805eeSFan Zhang 	return 0;
180503e9c5aSFan Zhang }
181503e9c5aSFan Zhang 
182503e9c5aSFan Zhang static int
1835d2aa461SJan Blunck cryptodev_scheduler_remove(struct rte_vdev_device *vdev)
184503e9c5aSFan Zhang {
1855d2aa461SJan Blunck 	const char *name;
186503e9c5aSFan Zhang 	struct rte_cryptodev *dev;
187503e9c5aSFan Zhang 	struct scheduler_ctx *sched_ctx;
188503e9c5aSFan Zhang 
1895d2aa461SJan Blunck 	if (vdev == NULL)
190503e9c5aSFan Zhang 		return -EINVAL;
191503e9c5aSFan Zhang 
1925d2aa461SJan Blunck 	name = rte_vdev_device_name(vdev);
193503e9c5aSFan Zhang 	dev = rte_cryptodev_pmd_get_named_dev(name);
194503e9c5aSFan Zhang 	if (dev == NULL)
195503e9c5aSFan Zhang 		return -EINVAL;
196503e9c5aSFan Zhang 
197503e9c5aSFan Zhang 	sched_ctx = dev->data->dev_private;
198503e9c5aSFan Zhang 
199503e9c5aSFan Zhang 	if (sched_ctx->nb_slaves) {
200503e9c5aSFan Zhang 		uint32_t i;
201503e9c5aSFan Zhang 
202503e9c5aSFan Zhang 		for (i = 0; i < sched_ctx->nb_slaves; i++)
203503e9c5aSFan Zhang 			rte_cryptodev_scheduler_slave_detach(dev->data->dev_id,
204503e9c5aSFan Zhang 					sched_ctx->slaves[i].dev_id);
205503e9c5aSFan Zhang 	}
206503e9c5aSFan Zhang 
207f2f020d2SDeclan Doherty 	return rte_cryptodev_pmd_destroy(dev);
208503e9c5aSFan Zhang }
209503e9c5aSFan Zhang 
210503e9c5aSFan Zhang /** Parse integer from integer argument */
211503e9c5aSFan Zhang static int
212503e9c5aSFan Zhang parse_integer_arg(const char *key __rte_unused,
213503e9c5aSFan Zhang 		const char *value, void *extra_args)
214503e9c5aSFan Zhang {
215503e9c5aSFan Zhang 	int *i = (int *) extra_args;
216503e9c5aSFan Zhang 
217503e9c5aSFan Zhang 	*i = atoi(value);
218503e9c5aSFan Zhang 	if (*i < 0) {
21985aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Argument has to be positive.");
220a0e805eeSFan Zhang 		return -EINVAL;
221503e9c5aSFan Zhang 	}
222503e9c5aSFan Zhang 
223503e9c5aSFan Zhang 	return 0;
224503e9c5aSFan Zhang }
225503e9c5aSFan Zhang 
2264c07e055SKirill Rybalchenko /** Parse integer from hexadecimal integer argument */
2274c07e055SKirill Rybalchenko static int
2284c07e055SKirill Rybalchenko parse_coremask_arg(const char *key __rte_unused,
2294c07e055SKirill Rybalchenko 		const char *value, void *extra_args)
2304c07e055SKirill Rybalchenko {
2311b78e3f2SKirill Rybalchenko 	int i, j, val;
2321b78e3f2SKirill Rybalchenko 	uint16_t idx = 0;
2331b78e3f2SKirill Rybalchenko 	char c;
2344c07e055SKirill Rybalchenko 	struct scheduler_init_params *params = extra_args;
2354c07e055SKirill Rybalchenko 
2361b78e3f2SKirill Rybalchenko 	params->nb_wc = 0;
2371b78e3f2SKirill Rybalchenko 
2381b78e3f2SKirill Rybalchenko 	if (value == NULL)
2391b78e3f2SKirill Rybalchenko 		return -1;
2401b78e3f2SKirill Rybalchenko 	/* Remove all blank characters ahead and after .
2411b78e3f2SKirill Rybalchenko 	 * Remove 0x/0X if exists.
2421b78e3f2SKirill Rybalchenko 	 */
2431b78e3f2SKirill Rybalchenko 	while (isblank(*value))
2441b78e3f2SKirill Rybalchenko 		value++;
2451b78e3f2SKirill Rybalchenko 	if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X')))
2461b78e3f2SKirill Rybalchenko 		value += 2;
2471b78e3f2SKirill Rybalchenko 	i = strlen(value);
2481b78e3f2SKirill Rybalchenko 	while ((i > 0) && isblank(value[i - 1]))
2491b78e3f2SKirill Rybalchenko 		i--;
2501b78e3f2SKirill Rybalchenko 
2511b78e3f2SKirill Rybalchenko 	if (i == 0)
2521b78e3f2SKirill Rybalchenko 		return -1;
2531b78e3f2SKirill Rybalchenko 
2541b78e3f2SKirill Rybalchenko 	for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
2551b78e3f2SKirill Rybalchenko 		c = value[i];
2561b78e3f2SKirill Rybalchenko 		if (isxdigit(c) == 0) {
2571b78e3f2SKirill Rybalchenko 			/* invalid characters */
2581b78e3f2SKirill Rybalchenko 			return -1;
2591b78e3f2SKirill Rybalchenko 		}
2601b78e3f2SKirill Rybalchenko 		if (isdigit(c))
2611b78e3f2SKirill Rybalchenko 			val = c - '0';
2621b78e3f2SKirill Rybalchenko 		else if (isupper(c))
2631b78e3f2SKirill Rybalchenko 			val = c - 'A' + 10;
2641b78e3f2SKirill Rybalchenko 		else
2651b78e3f2SKirill Rybalchenko 			val = c - 'a' + 10;
2661b78e3f2SKirill Rybalchenko 
2671b78e3f2SKirill Rybalchenko 		for (j = 0; j < 4 && idx < RTE_MAX_LCORE; j++, idx++) {
2681b78e3f2SKirill Rybalchenko 			if ((1 << j) & val)
2691b78e3f2SKirill Rybalchenko 				params->wc_pool[params->nb_wc++] = idx;
2701b78e3f2SKirill Rybalchenko 		}
2711b78e3f2SKirill Rybalchenko 	}
2724c07e055SKirill Rybalchenko 
2734c07e055SKirill Rybalchenko 	return 0;
2744c07e055SKirill Rybalchenko }
2754c07e055SKirill Rybalchenko 
2764c07e055SKirill Rybalchenko /** Parse integer from list of integers argument */
2774c07e055SKirill Rybalchenko static int
2784c07e055SKirill Rybalchenko parse_corelist_arg(const char *key __rte_unused,
2794c07e055SKirill Rybalchenko 		const char *value, void *extra_args)
2804c07e055SKirill Rybalchenko {
2814c07e055SKirill Rybalchenko 	struct scheduler_init_params *params = extra_args;
2824c07e055SKirill Rybalchenko 
2831b78e3f2SKirill Rybalchenko 	params->nb_wc = 0;
2844c07e055SKirill Rybalchenko 
2854c07e055SKirill Rybalchenko 	const char *token = value;
2864c07e055SKirill Rybalchenko 
2874c07e055SKirill Rybalchenko 	while (isdigit(token[0])) {
2884c07e055SKirill Rybalchenko 		char *rval;
2894c07e055SKirill Rybalchenko 		unsigned int core = strtoul(token, &rval, 10);
2904c07e055SKirill Rybalchenko 
2911b78e3f2SKirill Rybalchenko 		if (core >= RTE_MAX_LCORE) {
29285aa6d34SHari Kumar 			CR_SCHED_LOG(ERR, "Invalid worker core %u, should be smaller "
29385aa6d34SHari Kumar 				   "than %u.", core, RTE_MAX_LCORE);
2941b78e3f2SKirill Rybalchenko 		}
2951b78e3f2SKirill Rybalchenko 		params->wc_pool[params->nb_wc++] = (uint16_t)core;
2964c07e055SKirill Rybalchenko 		token = (const char *)rval;
2974c07e055SKirill Rybalchenko 		if (token[0] == '\0')
2984c07e055SKirill Rybalchenko 			break;
2994c07e055SKirill Rybalchenko 		token++;
3004c07e055SKirill Rybalchenko 	}
3014c07e055SKirill Rybalchenko 
3024c07e055SKirill Rybalchenko 	return 0;
3034c07e055SKirill Rybalchenko }
3044c07e055SKirill Rybalchenko 
305503e9c5aSFan Zhang /** Parse name */
306503e9c5aSFan Zhang static int
307503e9c5aSFan Zhang parse_name_arg(const char *key __rte_unused,
308503e9c5aSFan Zhang 		const char *value, void *extra_args)
309503e9c5aSFan Zhang {
310f2f020d2SDeclan Doherty 	struct rte_cryptodev_pmd_init_params *params = extra_args;
311503e9c5aSFan Zhang 
312503e9c5aSFan Zhang 	if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) {
31385aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Invalid name %s, should be less than "
31485aa6d34SHari Kumar 				"%u bytes.", value,
315503e9c5aSFan Zhang 				RTE_CRYPTODEV_NAME_MAX_LEN - 1);
316a0e805eeSFan Zhang 		return -EINVAL;
317503e9c5aSFan Zhang 	}
318503e9c5aSFan Zhang 
319503e9c5aSFan Zhang 	strncpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
320503e9c5aSFan Zhang 
321503e9c5aSFan Zhang 	return 0;
322503e9c5aSFan Zhang }
323503e9c5aSFan Zhang 
324503e9c5aSFan Zhang /** Parse slave */
325503e9c5aSFan Zhang static int
326503e9c5aSFan Zhang parse_slave_arg(const char *key __rte_unused,
327503e9c5aSFan Zhang 		const char *value, void *extra_args)
328503e9c5aSFan Zhang {
329503e9c5aSFan Zhang 	struct scheduler_init_params *param = extra_args;
330503e9c5aSFan Zhang 
331829d1327SFan Zhang 	if (param->nb_slaves >= RTE_CRYPTODEV_SCHEDULER_MAX_NB_SLAVES) {
33285aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Too many slaves.");
333a0e805eeSFan Zhang 		return -ENOMEM;
334503e9c5aSFan Zhang 	}
335503e9c5aSFan Zhang 
33650e14527SFan Zhang 	strncpy(param->slave_names[param->nb_slaves++], value,
33750e14527SFan Zhang 			RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN - 1);
338503e9c5aSFan Zhang 
339503e9c5aSFan Zhang 	return 0;
340503e9c5aSFan Zhang }
341503e9c5aSFan Zhang 
342503e9c5aSFan Zhang static int
343a0e805eeSFan Zhang parse_mode_arg(const char *key __rte_unused,
344a0e805eeSFan Zhang 		const char *value, void *extra_args)
345a0e805eeSFan Zhang {
346a0e805eeSFan Zhang 	struct scheduler_init_params *param = extra_args;
347a0e805eeSFan Zhang 	uint32_t i;
348a0e805eeSFan Zhang 
349a0e805eeSFan Zhang 	for (i = 0; i < RTE_DIM(scheduler_mode_map); i++) {
350a0e805eeSFan Zhang 		if (strcmp(value, scheduler_mode_map[i].name) == 0) {
351a0e805eeSFan Zhang 			param->mode = (enum rte_cryptodev_scheduler_mode)
352a0e805eeSFan Zhang 					scheduler_mode_map[i].val;
353*ee9586ddSFan Zhang 
354a0e805eeSFan Zhang 			break;
355a0e805eeSFan Zhang 		}
356a0e805eeSFan Zhang 	}
357a0e805eeSFan Zhang 
358a0e805eeSFan Zhang 	if (i == RTE_DIM(scheduler_mode_map)) {
35985aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Unrecognized input.");
360a0e805eeSFan Zhang 		return -EINVAL;
361a0e805eeSFan Zhang 	}
362a0e805eeSFan Zhang 
363a0e805eeSFan Zhang 	return 0;
364a0e805eeSFan Zhang }
365a0e805eeSFan Zhang 
366a0e805eeSFan Zhang static int
367*ee9586ddSFan Zhang parse_mode_param_arg(const char *key __rte_unused,
368*ee9586ddSFan Zhang 		const char *value, void *extra_args)
369*ee9586ddSFan Zhang {
370*ee9586ddSFan Zhang 	struct scheduler_init_params *param = extra_args;
371*ee9586ddSFan Zhang 
372*ee9586ddSFan Zhang 	strlcpy(param->mode_param_str, value,
373*ee9586ddSFan Zhang 			RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN);
374*ee9586ddSFan Zhang 
375*ee9586ddSFan Zhang 	return 0;
376*ee9586ddSFan Zhang }
377*ee9586ddSFan Zhang 
378*ee9586ddSFan Zhang static int
379a0e805eeSFan Zhang parse_ordering_arg(const char *key __rte_unused,
380a0e805eeSFan Zhang 		const char *value, void *extra_args)
381a0e805eeSFan Zhang {
382a0e805eeSFan Zhang 	struct scheduler_init_params *param = extra_args;
383a0e805eeSFan Zhang 	uint32_t i;
384a0e805eeSFan Zhang 
385a0e805eeSFan Zhang 	for (i = 0; i < RTE_DIM(scheduler_ordering_map); i++) {
386a0e805eeSFan Zhang 		if (strcmp(value, scheduler_ordering_map[i].name) == 0) {
387a0e805eeSFan Zhang 			param->enable_ordering =
388a0e805eeSFan Zhang 					scheduler_ordering_map[i].val;
389a0e805eeSFan Zhang 			break;
390a0e805eeSFan Zhang 		}
391a0e805eeSFan Zhang 	}
392a0e805eeSFan Zhang 
393a0e805eeSFan Zhang 	if (i == RTE_DIM(scheduler_ordering_map)) {
39485aa6d34SHari Kumar 		CR_SCHED_LOG(ERR, "Unrecognized input.");
395a0e805eeSFan Zhang 		return -EINVAL;
396a0e805eeSFan Zhang 	}
397a0e805eeSFan Zhang 
398a0e805eeSFan Zhang 	return 0;
399a0e805eeSFan Zhang }
400a0e805eeSFan Zhang 
401a0e805eeSFan Zhang static int
402503e9c5aSFan Zhang scheduler_parse_init_params(struct scheduler_init_params *params,
403503e9c5aSFan Zhang 		const char *input_args)
404503e9c5aSFan Zhang {
405503e9c5aSFan Zhang 	struct rte_kvargs *kvlist = NULL;
406503e9c5aSFan Zhang 	int ret = 0;
407503e9c5aSFan Zhang 
408503e9c5aSFan Zhang 	if (params == NULL)
409503e9c5aSFan Zhang 		return -EINVAL;
410503e9c5aSFan Zhang 
411503e9c5aSFan Zhang 	if (input_args) {
412503e9c5aSFan Zhang 		kvlist = rte_kvargs_parse(input_args,
413503e9c5aSFan Zhang 				scheduler_valid_params);
414503e9c5aSFan Zhang 		if (kvlist == NULL)
415503e9c5aSFan Zhang 			return -1;
416503e9c5aSFan Zhang 
417503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist,
418503e9c5aSFan Zhang 				RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
419503e9c5aSFan Zhang 				&parse_integer_arg,
420503e9c5aSFan Zhang 				&params->def_p.max_nb_queue_pairs);
421503e9c5aSFan Zhang 		if (ret < 0)
422503e9c5aSFan Zhang 			goto free_kvlist;
423503e9c5aSFan Zhang 
424503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
425503e9c5aSFan Zhang 				&parse_integer_arg,
426503e9c5aSFan Zhang 				&params->def_p.socket_id);
427503e9c5aSFan Zhang 		if (ret < 0)
428503e9c5aSFan Zhang 			goto free_kvlist;
429503e9c5aSFan Zhang 
4304c07e055SKirill Rybalchenko 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_COREMASK,
4314c07e055SKirill Rybalchenko 				&parse_coremask_arg,
4324c07e055SKirill Rybalchenko 				params);
4334c07e055SKirill Rybalchenko 		if (ret < 0)
4344c07e055SKirill Rybalchenko 			goto free_kvlist;
4354c07e055SKirill Rybalchenko 
4364c07e055SKirill Rybalchenko 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_CORELIST,
4374c07e055SKirill Rybalchenko 				&parse_corelist_arg,
4384c07e055SKirill Rybalchenko 				params);
4394c07e055SKirill Rybalchenko 		if (ret < 0)
4404c07e055SKirill Rybalchenko 			goto free_kvlist;
4414c07e055SKirill Rybalchenko 
442503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME,
443503e9c5aSFan Zhang 				&parse_name_arg,
444503e9c5aSFan Zhang 				&params->def_p);
445503e9c5aSFan Zhang 		if (ret < 0)
446503e9c5aSFan Zhang 			goto free_kvlist;
447503e9c5aSFan Zhang 
448503e9c5aSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SLAVE,
449503e9c5aSFan Zhang 				&parse_slave_arg, params);
450503e9c5aSFan Zhang 		if (ret < 0)
451503e9c5aSFan Zhang 			goto free_kvlist;
452503e9c5aSFan Zhang 
453a0e805eeSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_MODE,
454a0e805eeSFan Zhang 				&parse_mode_arg, params);
455a0e805eeSFan Zhang 		if (ret < 0)
456a0e805eeSFan Zhang 			goto free_kvlist;
457a0e805eeSFan Zhang 
458*ee9586ddSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_MODE_PARAM,
459*ee9586ddSFan Zhang 				&parse_mode_param_arg, params);
460*ee9586ddSFan Zhang 		if (ret < 0)
461*ee9586ddSFan Zhang 			goto free_kvlist;
462*ee9586ddSFan Zhang 
463a0e805eeSFan Zhang 		ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_ORDERING,
464a0e805eeSFan Zhang 				&parse_ordering_arg, params);
465a0e805eeSFan Zhang 		if (ret < 0)
466a0e805eeSFan Zhang 			goto free_kvlist;
467503e9c5aSFan Zhang 	}
468503e9c5aSFan Zhang 
469503e9c5aSFan Zhang free_kvlist:
470503e9c5aSFan Zhang 	rte_kvargs_free(kvlist);
471503e9c5aSFan Zhang 	return ret;
472503e9c5aSFan Zhang }
473503e9c5aSFan Zhang 
474503e9c5aSFan Zhang static int
4755d2aa461SJan Blunck cryptodev_scheduler_probe(struct rte_vdev_device *vdev)
476503e9c5aSFan Zhang {
477503e9c5aSFan Zhang 	struct scheduler_init_params init_params = {
478503e9c5aSFan Zhang 		.def_p = {
479f2f020d2SDeclan Doherty 			"",
480f2f020d2SDeclan Doherty 			sizeof(struct scheduler_ctx),
481503e9c5aSFan Zhang 			rte_socket_id(),
482e1fc5b76SPablo de Lara 			RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS
483503e9c5aSFan Zhang 		},
484503e9c5aSFan Zhang 		.nb_slaves = 0,
485a0e805eeSFan Zhang 		.mode = CDEV_SCHED_MODE_NOT_SET,
48650e14527SFan Zhang 		.enable_ordering = 0,
48750e14527SFan Zhang 		.slave_names = { {0} }
488503e9c5aSFan Zhang 	};
4897e214771SPablo de Lara 	const char *name;
4907e214771SPablo de Lara 
4917e214771SPablo de Lara 	name = rte_vdev_device_name(vdev);
4927e214771SPablo de Lara 	if (name == NULL)
4937e214771SPablo de Lara 		return -EINVAL;
494503e9c5aSFan Zhang 
4955d2aa461SJan Blunck 	scheduler_parse_init_params(&init_params,
4965d2aa461SJan Blunck 				    rte_vdev_device_args(vdev));
497503e9c5aSFan Zhang 
498503e9c5aSFan Zhang 
499168b9e76SPablo de Lara 	return cryptodev_scheduler_create(name,
500917ac9c4SPablo de Lara 					vdev,
5015d2aa461SJan Blunck 					&init_params);
502503e9c5aSFan Zhang }
503503e9c5aSFan Zhang 
504503e9c5aSFan Zhang static struct rte_vdev_driver cryptodev_scheduler_pmd_drv = {
505503e9c5aSFan Zhang 	.probe = cryptodev_scheduler_probe,
506503e9c5aSFan Zhang 	.remove = cryptodev_scheduler_remove
507503e9c5aSFan Zhang };
508503e9c5aSFan Zhang 
509effd3b9fSPablo de Lara static struct cryptodev_driver scheduler_crypto_drv;
510effd3b9fSPablo de Lara 
511503e9c5aSFan Zhang RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SCHEDULER_PMD,
512503e9c5aSFan Zhang 	cryptodev_scheduler_pmd_drv);
513503e9c5aSFan Zhang RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SCHEDULER_PMD,
514503e9c5aSFan Zhang 	"max_nb_queue_pairs=<int> "
515503e9c5aSFan Zhang 	"socket_id=<int> "
516503e9c5aSFan Zhang 	"slave=<name>");
517effd3b9fSPablo de Lara RTE_PMD_REGISTER_CRYPTO_DRIVER(scheduler_crypto_drv,
518f737f5ceSFiona Trahe 		cryptodev_scheduler_pmd_drv.driver,
5197a364faeSSlawomir Mrozowicz 		cryptodev_driver_id);
520