1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2017 Intel Corporation. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of the copyright holder nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <rte_malloc.h> 34 35 #include "rte_cryptodev_pmd.h" 36 37 /** 38 * Parse name from argument 39 */ 40 static int 41 rte_cryptodev_pmd_parse_name_arg(const char *key __rte_unused, 42 const char *value, void *extra_args) 43 { 44 struct rte_cryptodev_pmd_init_params *params = extra_args; 45 int n; 46 47 n = snprintf(params->name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s", value); 48 if (n >= RTE_CRYPTODEV_NAME_MAX_LEN) 49 return -EINVAL; 50 51 return 0; 52 } 53 54 /** 55 * Parse unsigned integer from argument 56 */ 57 static int 58 rte_cryptodev_pmd_parse_uint_arg(const char *key __rte_unused, 59 const char *value, void *extra_args) 60 { 61 int i; 62 char *end; 63 errno = 0; 64 65 i = strtol(value, &end, 10); 66 if (*end != 0 || errno != 0 || i < 0) 67 return -EINVAL; 68 69 *((uint32_t *)extra_args) = i; 70 return 0; 71 } 72 73 int 74 rte_cryptodev_pmd_parse_input_args( 75 struct rte_cryptodev_pmd_init_params *params, 76 const char *args) 77 { 78 struct rte_kvargs *kvlist = NULL; 79 int ret = 0; 80 81 if (params == NULL) 82 return -EINVAL; 83 84 if (args) { 85 kvlist = rte_kvargs_parse(args, cryptodev_pmd_valid_params); 86 if (kvlist == NULL) 87 return -EINVAL; 88 89 ret = rte_kvargs_process(kvlist, 90 RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG, 91 &rte_cryptodev_pmd_parse_uint_arg, 92 ¶ms->max_nb_queue_pairs); 93 if (ret < 0) 94 goto free_kvlist; 95 96 ret = rte_kvargs_process(kvlist, 97 RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG, 98 &rte_cryptodev_pmd_parse_uint_arg, 99 ¶ms->max_nb_sessions); 100 if (ret < 0) 101 goto free_kvlist; 102 103 ret = rte_kvargs_process(kvlist, 104 RTE_CRYPTODEV_PMD_SOCKET_ID_ARG, 105 &rte_cryptodev_pmd_parse_uint_arg, 106 ¶ms->socket_id); 107 if (ret < 0) 108 goto free_kvlist; 109 110 ret = rte_kvargs_process(kvlist, 111 RTE_CRYPTODEV_PMD_NAME_ARG, 112 &rte_cryptodev_pmd_parse_name_arg, 113 params); 114 if (ret < 0) 115 goto free_kvlist; 116 } 117 118 free_kvlist: 119 rte_kvargs_free(kvlist); 120 return ret; 121 } 122 123 struct rte_cryptodev * 124 rte_cryptodev_pmd_create(const char *name, 125 struct rte_device *device, 126 struct rte_cryptodev_pmd_init_params *params) 127 { 128 struct rte_cryptodev *cryptodev; 129 130 if (params->name[0] != '\0') { 131 CDEV_LOG_INFO("[%s] User specified device name = %s\n", 132 device->driver->name, params->name); 133 name = params->name; 134 } 135 136 CDEV_LOG_INFO("[%s] - Creating cryptodev %s\n", 137 device->driver->name, name); 138 139 CDEV_LOG_INFO("[%s] - Initialisation parameters - name: %s," 140 "socket id: %d, max queue pairs: %u, max sessions: %u", 141 device->driver->name, name, 142 params->socket_id, params->max_nb_queue_pairs, 143 params->max_nb_sessions); 144 145 /* allocate device structure */ 146 cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id); 147 if (cryptodev == NULL) { 148 CDEV_LOG_ERR("[%s] Failed to allocate crypto device for %s", 149 device->driver->name, name); 150 return NULL; 151 } 152 153 /* allocate private device structure */ 154 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 155 cryptodev->data->dev_private = 156 rte_zmalloc_socket("cryptodev device private", 157 params->private_data_size, 158 RTE_CACHE_LINE_SIZE, 159 params->socket_id); 160 161 if (cryptodev->data->dev_private == NULL) { 162 CDEV_LOG_ERR("[%s] Cannot allocate memory for " 163 "cryptodev %s private data", 164 device->driver->name, name); 165 166 rte_cryptodev_pmd_release_device(cryptodev); 167 return NULL; 168 } 169 } 170 171 cryptodev->device = device; 172 173 /* initialise user call-back tail queue */ 174 TAILQ_INIT(&(cryptodev->link_intr_cbs)); 175 176 return cryptodev; 177 } 178 179 int 180 rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev) 181 { 182 int retval; 183 184 CDEV_LOG_INFO("[%s] Closing crypto device %s", 185 cryptodev->device->driver->name, 186 cryptodev->device->name); 187 188 /* free crypto device */ 189 retval = rte_cryptodev_pmd_release_device(cryptodev); 190 if (retval) 191 return retval; 192 193 if (rte_eal_process_type() == RTE_PROC_PRIMARY) 194 rte_free(cryptodev->data->dev_private); 195 196 197 cryptodev->device = NULL; 198 cryptodev->data = NULL; 199 200 return 0; 201 } 202