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 ¶ms->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 ¶ms->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 ¶ms->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