15566a3e3SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 25566a3e3SBruce Richardson * Copyright(c) 2017 Intel Corporation 3503e9c5aSFan Zhang */ 472b452c5SDmitry Kozlyuk #include <ctype.h> 572b452c5SDmitry Kozlyuk #include <stdlib.h> 672b452c5SDmitry Kozlyuk 7503e9c5aSFan Zhang #include <rte_common.h> 8503e9c5aSFan Zhang #include <rte_hexdump.h> 9503e9c5aSFan Zhang #include <rte_cryptodev.h> 10af668035SAkhil Goyal #include <cryptodev_pmd.h> 11*e2af4e40SDavid Coyle #include <rte_security_driver.h> 124851ef2bSDavid Marchand #include <bus_vdev_driver.h> 13503e9c5aSFan Zhang #include <rte_malloc.h> 14503e9c5aSFan Zhang #include <rte_cpuflags.h> 15503e9c5aSFan Zhang #include <rte_reorder.h> 16ee9586ddSFan Zhang #include <rte_string_fns.h> 17503e9c5aSFan Zhang 18b88161beSBruce Richardson #include "rte_cryptodev_scheduler.h" 19503e9c5aSFan Zhang #include "scheduler_pmd_private.h" 20503e9c5aSFan Zhang 21520dd992SFerruh Yigit uint8_t cryptodev_scheduler_driver_id; 227a364faeSSlawomir Mrozowicz 23503e9c5aSFan Zhang struct scheduler_init_params { 24f2f020d2SDeclan Doherty struct rte_cryptodev_pmd_init_params def_p; 2585b00824SAdam Dybkowski uint32_t nb_workers; 26a0e805eeSFan Zhang enum rte_cryptodev_scheduler_mode mode; 27ee9586ddSFan Zhang char mode_param_str[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN]; 28a0e805eeSFan Zhang uint32_t enable_ordering; 291b78e3f2SKirill Rybalchenko uint16_t wc_pool[RTE_MAX_LCORE]; 301b78e3f2SKirill Rybalchenko uint16_t nb_wc; 3185b00824SAdam Dybkowski char worker_names[RTE_CRYPTODEV_SCHEDULER_MAX_NB_WORKERS] 3250e14527SFan Zhang [RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN]; 33503e9c5aSFan Zhang }; 34503e9c5aSFan Zhang 35503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_NAME ("name") 3685b00824SAdam Dybkowski #define RTE_CRYPTODEV_VDEV_WORKER ("worker") 37a0e805eeSFan Zhang #define RTE_CRYPTODEV_VDEV_MODE ("mode") 38ee9586ddSFan Zhang #define RTE_CRYPTODEV_VDEV_MODE_PARAM ("mode_param") 39a0e805eeSFan Zhang #define RTE_CRYPTODEV_VDEV_ORDERING ("ordering") 40503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG ("max_nb_queue_pairs") 41503e9c5aSFan Zhang #define RTE_CRYPTODEV_VDEV_SOCKET_ID ("socket_id") 424c07e055SKirill Rybalchenko #define RTE_CRYPTODEV_VDEV_COREMASK ("coremask") 434c07e055SKirill Rybalchenko #define RTE_CRYPTODEV_VDEV_CORELIST ("corelist") 44503e9c5aSFan Zhang 45b74fd6b8SFerruh Yigit static const char * const scheduler_valid_params[] = { 46503e9c5aSFan Zhang RTE_CRYPTODEV_VDEV_NAME, 4785b00824SAdam Dybkowski RTE_CRYPTODEV_VDEV_WORKER, 48a0e805eeSFan Zhang RTE_CRYPTODEV_VDEV_MODE, 49ee9586ddSFan Zhang RTE_CRYPTODEV_VDEV_MODE_PARAM, 50a0e805eeSFan Zhang RTE_CRYPTODEV_VDEV_ORDERING, 51503e9c5aSFan Zhang RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG, 524c07e055SKirill Rybalchenko RTE_CRYPTODEV_VDEV_SOCKET_ID, 534c07e055SKirill Rybalchenko RTE_CRYPTODEV_VDEV_COREMASK, 5434019b7bSCiara Power RTE_CRYPTODEV_VDEV_CORELIST, 5534019b7bSCiara Power NULL 56503e9c5aSFan Zhang }; 57503e9c5aSFan Zhang 58a0e805eeSFan Zhang struct scheduler_parse_map { 59a0e805eeSFan Zhang const char *name; 60a0e805eeSFan Zhang uint32_t val; 61a0e805eeSFan Zhang }; 62a0e805eeSFan Zhang 63a0e805eeSFan Zhang const struct scheduler_parse_map scheduler_mode_map[] = { 64a0e805eeSFan Zhang {RTE_STR(SCHEDULER_MODE_NAME_ROUND_ROBIN), 65a0e805eeSFan Zhang CDEV_SCHED_MODE_ROUNDROBIN}, 66a0e805eeSFan Zhang {RTE_STR(SCHEDULER_MODE_NAME_PKT_SIZE_DISTR), 67a0e805eeSFan Zhang CDEV_SCHED_MODE_PKT_SIZE_DISTR}, 68a0e805eeSFan Zhang {RTE_STR(SCHEDULER_MODE_NAME_FAIL_OVER), 694c07e055SKirill Rybalchenko CDEV_SCHED_MODE_FAILOVER}, 704c07e055SKirill Rybalchenko {RTE_STR(SCHEDULER_MODE_NAME_MULTI_CORE), 714c07e055SKirill Rybalchenko CDEV_SCHED_MODE_MULTICORE} 72a0e805eeSFan Zhang }; 73a0e805eeSFan Zhang 74a0e805eeSFan Zhang const struct scheduler_parse_map scheduler_ordering_map[] = { 75a0e805eeSFan Zhang {"enable", 1}, 76a0e805eeSFan Zhang {"disable", 0} 77a0e805eeSFan Zhang }; 78a0e805eeSFan Zhang 796760463cSFan Zhang #define CDEV_SCHED_MODE_PARAM_SEP_CHAR ':' 806760463cSFan Zhang 81*e2af4e40SDavid Coyle static void 82*e2af4e40SDavid Coyle free_mem(struct rte_cryptodev *dev) 83*e2af4e40SDavid Coyle { 84*e2af4e40SDavid Coyle struct scheduler_ctx *sched_ctx = dev->data->dev_private; 85*e2af4e40SDavid Coyle int i; 86*e2af4e40SDavid Coyle 87*e2af4e40SDavid Coyle for (i = 0; i < sched_ctx->nb_init_workers; i++) { 88*e2af4e40SDavid Coyle rte_free(sched_ctx->init_worker_names[i]); 89*e2af4e40SDavid Coyle sched_ctx->init_worker_names[i] = NULL; 90*e2af4e40SDavid Coyle } 91*e2af4e40SDavid Coyle 92*e2af4e40SDavid Coyle scheduler_free_capabilities(sched_ctx); 93*e2af4e40SDavid Coyle 94*e2af4e40SDavid Coyle rte_free(dev->security_ctx); 95*e2af4e40SDavid Coyle dev->security_ctx = NULL; 96*e2af4e40SDavid Coyle } 97*e2af4e40SDavid Coyle 98503e9c5aSFan Zhang static int 99503e9c5aSFan Zhang cryptodev_scheduler_create(const char *name, 100917ac9c4SPablo de Lara struct rte_vdev_device *vdev, 101503e9c5aSFan Zhang struct scheduler_init_params *init_params) 102503e9c5aSFan Zhang { 103503e9c5aSFan Zhang struct rte_cryptodev *dev; 104503e9c5aSFan Zhang struct scheduler_ctx *sched_ctx; 105a0e805eeSFan Zhang uint32_t i; 106a0e805eeSFan Zhang int ret; 107503e9c5aSFan Zhang 108f2f020d2SDeclan Doherty dev = rte_cryptodev_pmd_create(name, &vdev->device, 109f2f020d2SDeclan Doherty &init_params->def_p); 110503e9c5aSFan Zhang if (dev == NULL) { 11185aa6d34SHari Kumar CR_SCHED_LOG(ERR, "driver %s: failed to create cryptodev vdev", 112503e9c5aSFan Zhang name); 113503e9c5aSFan Zhang return -EFAULT; 114503e9c5aSFan Zhang } 115503e9c5aSFan Zhang 116520dd992SFerruh Yigit dev->driver_id = cryptodev_scheduler_driver_id; 117503e9c5aSFan Zhang dev->dev_ops = rte_crypto_scheduler_pmd_ops; 118503e9c5aSFan Zhang 119503e9c5aSFan Zhang sched_ctx = dev->data->dev_private; 120503e9c5aSFan Zhang sched_ctx->max_nb_queue_pairs = 121503e9c5aSFan Zhang init_params->def_p.max_nb_queue_pairs; 122503e9c5aSFan Zhang 1234c07e055SKirill Rybalchenko if (init_params->mode == CDEV_SCHED_MODE_MULTICORE) { 1244c07e055SKirill Rybalchenko uint16_t i; 1254c07e055SKirill Rybalchenko 1261b78e3f2SKirill Rybalchenko sched_ctx->nb_wc = init_params->nb_wc; 1274c07e055SKirill Rybalchenko 1281b78e3f2SKirill Rybalchenko for (i = 0; i < sched_ctx->nb_wc; i++) { 1291b78e3f2SKirill Rybalchenko sched_ctx->wc_pool[i] = init_params->wc_pool[i]; 13085aa6d34SHari Kumar CR_SCHED_LOG(INFO, " Worker core[%u]=%u added", 1311b78e3f2SKirill Rybalchenko i, sched_ctx->wc_pool[i]); 1324c07e055SKirill Rybalchenko } 1334c07e055SKirill Rybalchenko } 1344c07e055SKirill Rybalchenko 135a0e805eeSFan Zhang if (init_params->mode > CDEV_SCHED_MODE_USERDEFINED && 136a0e805eeSFan Zhang init_params->mode < CDEV_SCHED_MODE_COUNT) { 1376760463cSFan Zhang union { 1386760463cSFan Zhang struct rte_cryptodev_scheduler_threshold_option 1396760463cSFan Zhang threshold_option; 1406760463cSFan Zhang } option; 1416760463cSFan Zhang enum rte_cryptodev_schedule_option_type option_type; 1426760463cSFan Zhang char param_name[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN] = {0}; 1436760463cSFan Zhang char param_val[RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN] = {0}; 1446760463cSFan Zhang char *s, *end; 1456760463cSFan Zhang 1463fb45fdbSFan Zhang ret = rte_cryptodev_scheduler_mode_set(dev->data->dev_id, 147a0e805eeSFan Zhang init_params->mode); 148a0e805eeSFan Zhang if (ret < 0) { 149a0e805eeSFan Zhang rte_cryptodev_pmd_release_device(dev); 150a0e805eeSFan Zhang return ret; 151a0e805eeSFan Zhang } 152a0e805eeSFan Zhang 153a0e805eeSFan Zhang for (i = 0; i < RTE_DIM(scheduler_mode_map); i++) { 154a0e805eeSFan Zhang if (scheduler_mode_map[i].val != sched_ctx->mode) 155a0e805eeSFan Zhang continue; 156a0e805eeSFan Zhang 15785aa6d34SHari Kumar CR_SCHED_LOG(INFO, " Scheduling mode = %s", 158a0e805eeSFan Zhang scheduler_mode_map[i].name); 159a0e805eeSFan Zhang break; 160a0e805eeSFan Zhang } 1616760463cSFan Zhang 1626760463cSFan Zhang if (strlen(init_params->mode_param_str) > 0) { 1636760463cSFan Zhang s = strchr(init_params->mode_param_str, 1646760463cSFan Zhang CDEV_SCHED_MODE_PARAM_SEP_CHAR); 1656760463cSFan Zhang if (s == NULL) { 1666760463cSFan Zhang CR_SCHED_LOG(ERR, "Invalid mode param"); 1676760463cSFan Zhang return -EINVAL; 1686760463cSFan Zhang } 1696760463cSFan Zhang 1706760463cSFan Zhang strlcpy(param_name, init_params->mode_param_str, 1716760463cSFan Zhang s - init_params->mode_param_str + 1); 1726760463cSFan Zhang s++; 1736760463cSFan Zhang strlcpy(param_val, s, 1746760463cSFan Zhang RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN); 1756760463cSFan Zhang 1766760463cSFan Zhang switch (init_params->mode) { 1776760463cSFan Zhang case CDEV_SCHED_MODE_PKT_SIZE_DISTR: 1786760463cSFan Zhang if (strcmp(param_name, 1796760463cSFan Zhang RTE_CRYPTODEV_SCHEDULER_PARAM_THRES) 1806760463cSFan Zhang != 0) { 1816760463cSFan Zhang CR_SCHED_LOG(ERR, "Invalid mode param"); 1826760463cSFan Zhang return -EINVAL; 1836760463cSFan Zhang } 1846760463cSFan Zhang option_type = CDEV_SCHED_OPTION_THRESHOLD; 1856760463cSFan Zhang 1866760463cSFan Zhang option.threshold_option.threshold = 1876760463cSFan Zhang strtoul(param_val, &end, 0); 1886760463cSFan Zhang break; 1896760463cSFan Zhang default: 1906760463cSFan Zhang CR_SCHED_LOG(ERR, "Invalid mode param"); 1916760463cSFan Zhang return -EINVAL; 1926760463cSFan Zhang } 1936760463cSFan Zhang 1946760463cSFan Zhang if (sched_ctx->ops.option_set(dev, option_type, 1956760463cSFan Zhang (void *)&option) < 0) { 1966760463cSFan Zhang CR_SCHED_LOG(ERR, "Invalid mode param"); 1976760463cSFan Zhang return -EINVAL; 1986760463cSFan Zhang } 1996760463cSFan Zhang 2006760463cSFan Zhang RTE_LOG(INFO, PMD, " Sched mode param (%s = %s)\n", 2016760463cSFan Zhang param_name, param_val); 2026760463cSFan Zhang } 203a0e805eeSFan Zhang } 204a0e805eeSFan Zhang 205a0e805eeSFan Zhang sched_ctx->reordering_enabled = init_params->enable_ordering; 206a0e805eeSFan Zhang 207a0e805eeSFan Zhang for (i = 0; i < RTE_DIM(scheduler_ordering_map); i++) { 208a0e805eeSFan Zhang if (scheduler_ordering_map[i].val != 209a0e805eeSFan Zhang sched_ctx->reordering_enabled) 210a0e805eeSFan Zhang continue; 211a0e805eeSFan Zhang 21285aa6d34SHari Kumar CR_SCHED_LOG(INFO, " Packet ordering = %s", 213a0e805eeSFan Zhang scheduler_ordering_map[i].name); 214a0e805eeSFan Zhang 215a0e805eeSFan Zhang break; 216a0e805eeSFan Zhang } 217a0e805eeSFan Zhang 21885b00824SAdam Dybkowski for (i = 0; i < init_params->nb_workers; i++) { 21985b00824SAdam Dybkowski sched_ctx->init_worker_names[sched_ctx->nb_init_workers] = 22050e14527SFan Zhang rte_zmalloc_socket( 22150e14527SFan Zhang NULL, 22250e14527SFan Zhang RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN, 0, 22350e14527SFan Zhang SOCKET_ID_ANY); 22450e14527SFan Zhang 22585b00824SAdam Dybkowski if (!sched_ctx->init_worker_names[ 22685b00824SAdam Dybkowski sched_ctx->nb_init_workers]) { 227*e2af4e40SDavid Coyle CR_SCHED_LOG(ERR, "Not enough memory for init worker name"); 228*e2af4e40SDavid Coyle free_mem(dev); 22950e14527SFan Zhang return -ENOMEM; 23050e14527SFan Zhang } 23150e14527SFan Zhang 23285b00824SAdam Dybkowski strncpy(sched_ctx->init_worker_names[ 23385b00824SAdam Dybkowski sched_ctx->nb_init_workers], 23485b00824SAdam Dybkowski init_params->worker_names[i], 23550e14527SFan Zhang RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN - 1); 23650e14527SFan Zhang 23785b00824SAdam Dybkowski sched_ctx->nb_init_workers++; 23850e14527SFan Zhang } 23950e14527SFan Zhang 240c570f262SPablo de Lara /* 241c570f262SPablo de Lara * Initialize capabilities structure as an empty structure, 24285b00824SAdam Dybkowski * in case device information is requested when no workers are attached 243c570f262SPablo de Lara */ 244c570f262SPablo de Lara sched_ctx->capabilities = rte_zmalloc_socket(NULL, 245c570f262SPablo de Lara sizeof(struct rte_cryptodev_capabilities), 246c570f262SPablo de Lara 0, SOCKET_ID_ANY); 247c570f262SPablo de Lara 248c570f262SPablo de Lara if (!sched_ctx->capabilities) { 249*e2af4e40SDavid Coyle CR_SCHED_LOG(ERR, "Not enough memory for capability information"); 250*e2af4e40SDavid Coyle free_mem(dev); 251*e2af4e40SDavid Coyle return -ENOMEM; 252*e2af4e40SDavid Coyle } 253*e2af4e40SDavid Coyle 254*e2af4e40SDavid Coyle /* Initialize security context */ 255*e2af4e40SDavid Coyle struct rte_security_ctx *security_instance; 256*e2af4e40SDavid Coyle security_instance = rte_zmalloc_socket(NULL, 257*e2af4e40SDavid Coyle sizeof(struct rte_security_ctx), 258*e2af4e40SDavid Coyle RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY); 259*e2af4e40SDavid Coyle if (!security_instance) { 260*e2af4e40SDavid Coyle CR_SCHED_LOG(ERR, "Not enough memory for security context"); 261*e2af4e40SDavid Coyle free_mem(dev); 262*e2af4e40SDavid Coyle return -ENOMEM; 263*e2af4e40SDavid Coyle } 264*e2af4e40SDavid Coyle 265*e2af4e40SDavid Coyle security_instance->device = dev; 266*e2af4e40SDavid Coyle security_instance->ops = rte_crypto_scheduler_pmd_sec_ops; 267*e2af4e40SDavid Coyle security_instance->sess_cnt = 0; 268*e2af4e40SDavid Coyle dev->security_ctx = security_instance; 269*e2af4e40SDavid Coyle 270*e2af4e40SDavid Coyle /* 271*e2af4e40SDavid Coyle * Initialize security capabilities structure as an empty structure, 272*e2af4e40SDavid Coyle * in case device information is requested when no workers are attached 273*e2af4e40SDavid Coyle */ 274*e2af4e40SDavid Coyle sched_ctx->sec_capabilities = rte_zmalloc_socket(NULL, 275*e2af4e40SDavid Coyle sizeof(struct rte_security_capability), 276*e2af4e40SDavid Coyle 0, SOCKET_ID_ANY); 277*e2af4e40SDavid Coyle 278*e2af4e40SDavid Coyle if (!sched_ctx->sec_capabilities) { 279*e2af4e40SDavid Coyle CR_SCHED_LOG(ERR, "Not enough memory for security capability information"); 280*e2af4e40SDavid Coyle free_mem(dev); 281c570f262SPablo de Lara return -ENOMEM; 282c570f262SPablo de Lara } 283c570f262SPablo de Lara 284d54c72ecSAkhil Goyal rte_cryptodev_pmd_probing_finish(dev); 285d54c72ecSAkhil Goyal 286a0e805eeSFan Zhang return 0; 287503e9c5aSFan Zhang } 288503e9c5aSFan Zhang 289503e9c5aSFan Zhang static int 2905d2aa461SJan Blunck cryptodev_scheduler_remove(struct rte_vdev_device *vdev) 291503e9c5aSFan Zhang { 2925d2aa461SJan Blunck const char *name; 293503e9c5aSFan Zhang struct rte_cryptodev *dev; 294503e9c5aSFan Zhang struct scheduler_ctx *sched_ctx; 295503e9c5aSFan Zhang 2965d2aa461SJan Blunck if (vdev == NULL) 297503e9c5aSFan Zhang return -EINVAL; 298503e9c5aSFan Zhang 2995d2aa461SJan Blunck name = rte_vdev_device_name(vdev); 300503e9c5aSFan Zhang dev = rte_cryptodev_pmd_get_named_dev(name); 301503e9c5aSFan Zhang if (dev == NULL) 302503e9c5aSFan Zhang return -EINVAL; 303503e9c5aSFan Zhang 304503e9c5aSFan Zhang sched_ctx = dev->data->dev_private; 305503e9c5aSFan Zhang 30685b00824SAdam Dybkowski if (sched_ctx->nb_workers) { 307503e9c5aSFan Zhang uint32_t i; 308503e9c5aSFan Zhang 30985b00824SAdam Dybkowski for (i = 0; i < sched_ctx->nb_workers; i++) 31085b00824SAdam Dybkowski rte_cryptodev_scheduler_worker_detach(dev->data->dev_id, 31185b00824SAdam Dybkowski sched_ctx->workers[i].dev_id); 312503e9c5aSFan Zhang } 313503e9c5aSFan Zhang 314*e2af4e40SDavid Coyle rte_free(dev->security_ctx); 315*e2af4e40SDavid Coyle dev->security_ctx = NULL; 316*e2af4e40SDavid Coyle 317f2f020d2SDeclan Doherty return rte_cryptodev_pmd_destroy(dev); 318503e9c5aSFan Zhang } 319503e9c5aSFan Zhang 320503e9c5aSFan Zhang /** Parse integer from integer argument */ 321503e9c5aSFan Zhang static int 322503e9c5aSFan Zhang parse_integer_arg(const char *key __rte_unused, 323503e9c5aSFan Zhang const char *value, void *extra_args) 324503e9c5aSFan Zhang { 325503e9c5aSFan Zhang int *i = (int *) extra_args; 326503e9c5aSFan Zhang 327503e9c5aSFan Zhang *i = atoi(value); 328503e9c5aSFan Zhang if (*i < 0) { 32985aa6d34SHari Kumar CR_SCHED_LOG(ERR, "Argument has to be positive."); 330a0e805eeSFan Zhang return -EINVAL; 331503e9c5aSFan Zhang } 332503e9c5aSFan Zhang 333503e9c5aSFan Zhang return 0; 334503e9c5aSFan Zhang } 335503e9c5aSFan Zhang 3364c07e055SKirill Rybalchenko /** Parse integer from hexadecimal integer argument */ 3374c07e055SKirill Rybalchenko static int 3384c07e055SKirill Rybalchenko parse_coremask_arg(const char *key __rte_unused, 3394c07e055SKirill Rybalchenko const char *value, void *extra_args) 3404c07e055SKirill Rybalchenko { 3411b78e3f2SKirill Rybalchenko int i, j, val; 3421b78e3f2SKirill Rybalchenko uint16_t idx = 0; 3431b78e3f2SKirill Rybalchenko char c; 3444c07e055SKirill Rybalchenko struct scheduler_init_params *params = extra_args; 3454c07e055SKirill Rybalchenko 3461b78e3f2SKirill Rybalchenko params->nb_wc = 0; 3471b78e3f2SKirill Rybalchenko 3481b78e3f2SKirill Rybalchenko if (value == NULL) 3491b78e3f2SKirill Rybalchenko return -1; 3501b78e3f2SKirill Rybalchenko /* Remove all blank characters ahead and after . 3511b78e3f2SKirill Rybalchenko * Remove 0x/0X if exists. 3521b78e3f2SKirill Rybalchenko */ 3531b78e3f2SKirill Rybalchenko while (isblank(*value)) 3541b78e3f2SKirill Rybalchenko value++; 3551b78e3f2SKirill Rybalchenko if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) 3561b78e3f2SKirill Rybalchenko value += 2; 3571b78e3f2SKirill Rybalchenko i = strlen(value); 3581b78e3f2SKirill Rybalchenko while ((i > 0) && isblank(value[i - 1])) 3591b78e3f2SKirill Rybalchenko i--; 3601b78e3f2SKirill Rybalchenko 3611b78e3f2SKirill Rybalchenko if (i == 0) 3621b78e3f2SKirill Rybalchenko return -1; 3631b78e3f2SKirill Rybalchenko 3641b78e3f2SKirill Rybalchenko for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) { 3651b78e3f2SKirill Rybalchenko c = value[i]; 3661b78e3f2SKirill Rybalchenko if (isxdigit(c) == 0) { 3671b78e3f2SKirill Rybalchenko /* invalid characters */ 3681b78e3f2SKirill Rybalchenko return -1; 3691b78e3f2SKirill Rybalchenko } 3701b78e3f2SKirill Rybalchenko if (isdigit(c)) 3711b78e3f2SKirill Rybalchenko val = c - '0'; 3721b78e3f2SKirill Rybalchenko else if (isupper(c)) 3731b78e3f2SKirill Rybalchenko val = c - 'A' + 10; 3741b78e3f2SKirill Rybalchenko else 3751b78e3f2SKirill Rybalchenko val = c - 'a' + 10; 3761b78e3f2SKirill Rybalchenko 3771b78e3f2SKirill Rybalchenko for (j = 0; j < 4 && idx < RTE_MAX_LCORE; j++, idx++) { 3781b78e3f2SKirill Rybalchenko if ((1 << j) & val) 3791b78e3f2SKirill Rybalchenko params->wc_pool[params->nb_wc++] = idx; 3801b78e3f2SKirill Rybalchenko } 3811b78e3f2SKirill Rybalchenko } 3824c07e055SKirill Rybalchenko 3834c07e055SKirill Rybalchenko return 0; 3844c07e055SKirill Rybalchenko } 3854c07e055SKirill Rybalchenko 3864c07e055SKirill Rybalchenko /** Parse integer from list of integers argument */ 3874c07e055SKirill Rybalchenko static int 3884c07e055SKirill Rybalchenko parse_corelist_arg(const char *key __rte_unused, 3894c07e055SKirill Rybalchenko const char *value, void *extra_args) 3904c07e055SKirill Rybalchenko { 3914c07e055SKirill Rybalchenko struct scheduler_init_params *params = extra_args; 3924c07e055SKirill Rybalchenko 3931b78e3f2SKirill Rybalchenko params->nb_wc = 0; 3944c07e055SKirill Rybalchenko 3954c07e055SKirill Rybalchenko const char *token = value; 3964c07e055SKirill Rybalchenko 3974c07e055SKirill Rybalchenko while (isdigit(token[0])) { 3984c07e055SKirill Rybalchenko char *rval; 3994c07e055SKirill Rybalchenko unsigned int core = strtoul(token, &rval, 10); 4004c07e055SKirill Rybalchenko 4011b78e3f2SKirill Rybalchenko if (core >= RTE_MAX_LCORE) { 40285aa6d34SHari Kumar CR_SCHED_LOG(ERR, "Invalid worker core %u, should be smaller " 40385aa6d34SHari Kumar "than %u.", core, RTE_MAX_LCORE); 4041b78e3f2SKirill Rybalchenko } 4051b78e3f2SKirill Rybalchenko params->wc_pool[params->nb_wc++] = (uint16_t)core; 4064c07e055SKirill Rybalchenko token = (const char *)rval; 4074c07e055SKirill Rybalchenko if (token[0] == '\0') 4084c07e055SKirill Rybalchenko break; 4094c07e055SKirill Rybalchenko token++; 4104c07e055SKirill Rybalchenko } 4114c07e055SKirill Rybalchenko 4124c07e055SKirill Rybalchenko return 0; 4134c07e055SKirill Rybalchenko } 4144c07e055SKirill Rybalchenko 415503e9c5aSFan Zhang /** Parse name */ 416503e9c5aSFan Zhang static int 417503e9c5aSFan Zhang parse_name_arg(const char *key __rte_unused, 418503e9c5aSFan Zhang const char *value, void *extra_args) 419503e9c5aSFan Zhang { 420f2f020d2SDeclan Doherty struct rte_cryptodev_pmd_init_params *params = extra_args; 421503e9c5aSFan Zhang 422503e9c5aSFan Zhang if (strlen(value) >= RTE_CRYPTODEV_NAME_MAX_LEN - 1) { 42385aa6d34SHari Kumar CR_SCHED_LOG(ERR, "Invalid name %s, should be less than " 42485aa6d34SHari Kumar "%u bytes.", value, 425503e9c5aSFan Zhang RTE_CRYPTODEV_NAME_MAX_LEN - 1); 426a0e805eeSFan Zhang return -EINVAL; 427503e9c5aSFan Zhang } 428503e9c5aSFan Zhang 429e5e193acSJerin Jacob strlcpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN); 430503e9c5aSFan Zhang 431503e9c5aSFan Zhang return 0; 432503e9c5aSFan Zhang } 433503e9c5aSFan Zhang 43485b00824SAdam Dybkowski /** Parse worker */ 435503e9c5aSFan Zhang static int 43685b00824SAdam Dybkowski parse_worker_arg(const char *key __rte_unused, 437503e9c5aSFan Zhang const char *value, void *extra_args) 438503e9c5aSFan Zhang { 439503e9c5aSFan Zhang struct scheduler_init_params *param = extra_args; 440503e9c5aSFan Zhang 44185b00824SAdam Dybkowski if (param->nb_workers >= RTE_CRYPTODEV_SCHEDULER_MAX_NB_WORKERS) { 44285b00824SAdam Dybkowski CR_SCHED_LOG(ERR, "Too many workers."); 443a0e805eeSFan Zhang return -ENOMEM; 444503e9c5aSFan Zhang } 445503e9c5aSFan Zhang 44685b00824SAdam Dybkowski strncpy(param->worker_names[param->nb_workers++], value, 44750e14527SFan Zhang RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN - 1); 448503e9c5aSFan Zhang 449503e9c5aSFan Zhang return 0; 450503e9c5aSFan Zhang } 451503e9c5aSFan Zhang 452503e9c5aSFan Zhang static int 453a0e805eeSFan Zhang parse_mode_arg(const char *key __rte_unused, 454a0e805eeSFan Zhang const char *value, void *extra_args) 455a0e805eeSFan Zhang { 456a0e805eeSFan Zhang struct scheduler_init_params *param = extra_args; 457a0e805eeSFan Zhang uint32_t i; 458a0e805eeSFan Zhang 459a0e805eeSFan Zhang for (i = 0; i < RTE_DIM(scheduler_mode_map); i++) { 460a0e805eeSFan Zhang if (strcmp(value, scheduler_mode_map[i].name) == 0) { 461a0e805eeSFan Zhang param->mode = (enum rte_cryptodev_scheduler_mode) 462a0e805eeSFan Zhang scheduler_mode_map[i].val; 463ee9586ddSFan Zhang 464a0e805eeSFan Zhang break; 465a0e805eeSFan Zhang } 466a0e805eeSFan Zhang } 467a0e805eeSFan Zhang 468a0e805eeSFan Zhang if (i == RTE_DIM(scheduler_mode_map)) { 46985aa6d34SHari Kumar CR_SCHED_LOG(ERR, "Unrecognized input."); 470a0e805eeSFan Zhang return -EINVAL; 471a0e805eeSFan Zhang } 472a0e805eeSFan Zhang 473a0e805eeSFan Zhang return 0; 474a0e805eeSFan Zhang } 475a0e805eeSFan Zhang 476a0e805eeSFan Zhang static int 477ee9586ddSFan Zhang parse_mode_param_arg(const char *key __rte_unused, 478ee9586ddSFan Zhang const char *value, void *extra_args) 479ee9586ddSFan Zhang { 480ee9586ddSFan Zhang struct scheduler_init_params *param = extra_args; 481ee9586ddSFan Zhang 482ee9586ddSFan Zhang strlcpy(param->mode_param_str, value, 483ee9586ddSFan Zhang RTE_CRYPTODEV_SCHEDULER_NAME_MAX_LEN); 484ee9586ddSFan Zhang 485ee9586ddSFan Zhang return 0; 486ee9586ddSFan Zhang } 487ee9586ddSFan Zhang 488ee9586ddSFan Zhang static int 489a0e805eeSFan Zhang parse_ordering_arg(const char *key __rte_unused, 490a0e805eeSFan Zhang const char *value, void *extra_args) 491a0e805eeSFan Zhang { 492a0e805eeSFan Zhang struct scheduler_init_params *param = extra_args; 493a0e805eeSFan Zhang uint32_t i; 494a0e805eeSFan Zhang 495a0e805eeSFan Zhang for (i = 0; i < RTE_DIM(scheduler_ordering_map); i++) { 496a0e805eeSFan Zhang if (strcmp(value, scheduler_ordering_map[i].name) == 0) { 497a0e805eeSFan Zhang param->enable_ordering = 498a0e805eeSFan Zhang scheduler_ordering_map[i].val; 499a0e805eeSFan Zhang break; 500a0e805eeSFan Zhang } 501a0e805eeSFan Zhang } 502a0e805eeSFan Zhang 503a0e805eeSFan Zhang if (i == RTE_DIM(scheduler_ordering_map)) { 50485aa6d34SHari Kumar CR_SCHED_LOG(ERR, "Unrecognized input."); 505a0e805eeSFan Zhang return -EINVAL; 506a0e805eeSFan Zhang } 507a0e805eeSFan Zhang 508a0e805eeSFan Zhang return 0; 509a0e805eeSFan Zhang } 510a0e805eeSFan Zhang 511a0e805eeSFan Zhang static int 512503e9c5aSFan Zhang scheduler_parse_init_params(struct scheduler_init_params *params, 513503e9c5aSFan Zhang const char *input_args) 514503e9c5aSFan Zhang { 515503e9c5aSFan Zhang struct rte_kvargs *kvlist = NULL; 516503e9c5aSFan Zhang int ret = 0; 517503e9c5aSFan Zhang 518503e9c5aSFan Zhang if (params == NULL) 519503e9c5aSFan Zhang return -EINVAL; 520503e9c5aSFan Zhang 521503e9c5aSFan Zhang if (input_args) { 522503e9c5aSFan Zhang kvlist = rte_kvargs_parse(input_args, 523503e9c5aSFan Zhang scheduler_valid_params); 524503e9c5aSFan Zhang if (kvlist == NULL) 525503e9c5aSFan Zhang return -1; 526503e9c5aSFan Zhang 527503e9c5aSFan Zhang ret = rte_kvargs_process(kvlist, 528503e9c5aSFan Zhang RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG, 529503e9c5aSFan Zhang &parse_integer_arg, 530503e9c5aSFan Zhang ¶ms->def_p.max_nb_queue_pairs); 531503e9c5aSFan Zhang if (ret < 0) 532503e9c5aSFan Zhang goto free_kvlist; 533503e9c5aSFan Zhang 534503e9c5aSFan Zhang ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID, 535503e9c5aSFan Zhang &parse_integer_arg, 536503e9c5aSFan Zhang ¶ms->def_p.socket_id); 537503e9c5aSFan Zhang if (ret < 0) 538503e9c5aSFan Zhang goto free_kvlist; 539503e9c5aSFan Zhang 5404c07e055SKirill Rybalchenko ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_COREMASK, 5414c07e055SKirill Rybalchenko &parse_coremask_arg, 5424c07e055SKirill Rybalchenko params); 5434c07e055SKirill Rybalchenko if (ret < 0) 5444c07e055SKirill Rybalchenko goto free_kvlist; 5454c07e055SKirill Rybalchenko 5464c07e055SKirill Rybalchenko ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_CORELIST, 5474c07e055SKirill Rybalchenko &parse_corelist_arg, 5484c07e055SKirill Rybalchenko params); 5494c07e055SKirill Rybalchenko if (ret < 0) 5504c07e055SKirill Rybalchenko goto free_kvlist; 5514c07e055SKirill Rybalchenko 552503e9c5aSFan Zhang ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_NAME, 553503e9c5aSFan Zhang &parse_name_arg, 554503e9c5aSFan Zhang ¶ms->def_p); 555503e9c5aSFan Zhang if (ret < 0) 556503e9c5aSFan Zhang goto free_kvlist; 557503e9c5aSFan Zhang 55885b00824SAdam Dybkowski ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_WORKER, 55985b00824SAdam Dybkowski &parse_worker_arg, params); 560503e9c5aSFan Zhang if (ret < 0) 561503e9c5aSFan Zhang goto free_kvlist; 562503e9c5aSFan Zhang 563a0e805eeSFan Zhang ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_MODE, 564a0e805eeSFan Zhang &parse_mode_arg, params); 565a0e805eeSFan Zhang if (ret < 0) 566a0e805eeSFan Zhang goto free_kvlist; 567a0e805eeSFan Zhang 568ee9586ddSFan Zhang ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_MODE_PARAM, 569ee9586ddSFan Zhang &parse_mode_param_arg, params); 570ee9586ddSFan Zhang if (ret < 0) 571ee9586ddSFan Zhang goto free_kvlist; 572ee9586ddSFan Zhang 573a0e805eeSFan Zhang ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_ORDERING, 574a0e805eeSFan Zhang &parse_ordering_arg, params); 575a0e805eeSFan Zhang if (ret < 0) 576a0e805eeSFan Zhang goto free_kvlist; 577503e9c5aSFan Zhang } 578503e9c5aSFan Zhang 579503e9c5aSFan Zhang free_kvlist: 580503e9c5aSFan Zhang rte_kvargs_free(kvlist); 581503e9c5aSFan Zhang return ret; 582503e9c5aSFan Zhang } 583503e9c5aSFan Zhang 584503e9c5aSFan Zhang static int 5855d2aa461SJan Blunck cryptodev_scheduler_probe(struct rte_vdev_device *vdev) 586503e9c5aSFan Zhang { 587503e9c5aSFan Zhang struct scheduler_init_params init_params = { 588503e9c5aSFan Zhang .def_p = { 589f2f020d2SDeclan Doherty "", 590f2f020d2SDeclan Doherty sizeof(struct scheduler_ctx), 591503e9c5aSFan Zhang rte_socket_id(), 592e1fc5b76SPablo de Lara RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS 593503e9c5aSFan Zhang }, 59485b00824SAdam Dybkowski .nb_workers = 0, 595a0e805eeSFan Zhang .mode = CDEV_SCHED_MODE_NOT_SET, 59650e14527SFan Zhang .enable_ordering = 0, 59785b00824SAdam Dybkowski .worker_names = { {0} } 598503e9c5aSFan Zhang }; 5997e214771SPablo de Lara const char *name; 6007e214771SPablo de Lara 6017e214771SPablo de Lara name = rte_vdev_device_name(vdev); 6027e214771SPablo de Lara if (name == NULL) 6037e214771SPablo de Lara return -EINVAL; 604503e9c5aSFan Zhang 6055d2aa461SJan Blunck scheduler_parse_init_params(&init_params, 6065d2aa461SJan Blunck rte_vdev_device_args(vdev)); 607503e9c5aSFan Zhang 608503e9c5aSFan Zhang 609168b9e76SPablo de Lara return cryptodev_scheduler_create(name, 610917ac9c4SPablo de Lara vdev, 6115d2aa461SJan Blunck &init_params); 612503e9c5aSFan Zhang } 613503e9c5aSFan Zhang 614503e9c5aSFan Zhang static struct rte_vdev_driver cryptodev_scheduler_pmd_drv = { 615503e9c5aSFan Zhang .probe = cryptodev_scheduler_probe, 616503e9c5aSFan Zhang .remove = cryptodev_scheduler_remove 617503e9c5aSFan Zhang }; 618503e9c5aSFan Zhang 619effd3b9fSPablo de Lara static struct cryptodev_driver scheduler_crypto_drv; 620effd3b9fSPablo de Lara 621503e9c5aSFan Zhang RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_SCHEDULER_PMD, 622503e9c5aSFan Zhang cryptodev_scheduler_pmd_drv); 623503e9c5aSFan Zhang RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_SCHEDULER_PMD, 624503e9c5aSFan Zhang "max_nb_queue_pairs=<int> " 625503e9c5aSFan Zhang "socket_id=<int> " 62685b00824SAdam Dybkowski "worker=<name>"); 627effd3b9fSPablo de Lara RTE_PMD_REGISTER_CRYPTO_DRIVER(scheduler_crypto_drv, 628f737f5ceSFiona Trahe cryptodev_scheduler_pmd_drv.driver, 629520dd992SFerruh Yigit cryptodev_scheduler_driver_id); 630