1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Intel Corporation 3 */ 4 5 #include <string.h> 6 7 #include <rte_common.h> 8 #include <rte_bus_vdev.h> 9 #include <rte_malloc.h> 10 #include <rte_ring.h> 11 #include <rte_kvargs.h> 12 13 #include <rte_bbdev.h> 14 #include <rte_bbdev_pmd.h> 15 16 #define DRIVER_NAME baseband_null 17 18 /* NULL BBDev logging ID */ 19 static int bbdev_null_logtype; 20 21 /* Helper macro for logging */ 22 #define rte_bbdev_log(level, fmt, ...) \ 23 rte_log(RTE_LOG_ ## level, bbdev_null_logtype, fmt "\n", ##__VA_ARGS__) 24 25 #define rte_bbdev_log_debug(fmt, ...) \ 26 rte_bbdev_log(DEBUG, RTE_STR(__LINE__) ":%s() " fmt, __func__, \ 27 ##__VA_ARGS__) 28 29 /* Initialisation params structure that can be used by null BBDEV driver */ 30 struct bbdev_null_params { 31 int socket_id; /*< Null BBDEV socket */ 32 uint16_t queues_num; /*< Null BBDEV queues number */ 33 }; 34 35 /* Accecptable params for null BBDEV devices */ 36 #define BBDEV_NULL_MAX_NB_QUEUES_ARG "max_nb_queues" 37 #define BBDEV_NULL_SOCKET_ID_ARG "socket_id" 38 39 static const char * const bbdev_null_valid_params[] = { 40 BBDEV_NULL_MAX_NB_QUEUES_ARG, 41 BBDEV_NULL_SOCKET_ID_ARG 42 }; 43 44 /* private data structure */ 45 struct bbdev_private { 46 unsigned int max_nb_queues; /**< Max number of queues */ 47 }; 48 49 /* queue */ 50 struct bbdev_queue { 51 struct rte_ring *processed_pkts; /* Ring for processed packets */ 52 } __rte_cache_aligned; 53 54 /* Get device info */ 55 static void 56 info_get(struct rte_bbdev *dev, struct rte_bbdev_driver_info *dev_info) 57 { 58 struct bbdev_private *internals = dev->data->dev_private; 59 60 static const struct rte_bbdev_op_cap bbdev_capabilities[] = { 61 RTE_BBDEV_END_OF_CAPABILITIES_LIST(), 62 }; 63 64 static struct rte_bbdev_queue_conf default_queue_conf = { 65 .queue_size = RTE_BBDEV_QUEUE_SIZE_LIMIT, 66 }; 67 68 default_queue_conf.socket = dev->data->socket_id; 69 70 dev_info->driver_name = RTE_STR(DRIVER_NAME); 71 dev_info->max_num_queues = internals->max_nb_queues; 72 dev_info->queue_size_lim = RTE_BBDEV_QUEUE_SIZE_LIMIT; 73 dev_info->hardware_accelerated = false; 74 dev_info->max_dl_queue_priority = 0; 75 dev_info->max_ul_queue_priority = 0; 76 dev_info->default_queue_conf = default_queue_conf; 77 dev_info->capabilities = bbdev_capabilities; 78 dev_info->cpu_flag_reqs = NULL; 79 dev_info->min_alignment = 0; 80 81 rte_bbdev_log_debug("got device info from %u", dev->data->dev_id); 82 } 83 84 /* Release queue */ 85 static int 86 q_release(struct rte_bbdev *dev, uint16_t q_id) 87 { 88 struct bbdev_queue *q = dev->data->queues[q_id].queue_private; 89 90 if (q != NULL) { 91 rte_ring_free(q->processed_pkts); 92 rte_free(q); 93 dev->data->queues[q_id].queue_private = NULL; 94 } 95 96 rte_bbdev_log_debug("released device queue %u:%u", 97 dev->data->dev_id, q_id); 98 return 0; 99 } 100 101 /* Setup a queue */ 102 static int 103 q_setup(struct rte_bbdev *dev, uint16_t q_id, 104 const struct rte_bbdev_queue_conf *queue_conf) 105 { 106 struct bbdev_queue *q; 107 char ring_name[RTE_RING_NAMESIZE]; 108 snprintf(ring_name, RTE_RING_NAMESIZE, RTE_STR(DRIVER_NAME) "%u:%u", 109 dev->data->dev_id, q_id); 110 111 /* Allocate the queue data structure. */ 112 q = rte_zmalloc_socket(RTE_STR(DRIVER_NAME), sizeof(*q), 113 RTE_CACHE_LINE_SIZE, queue_conf->socket); 114 if (q == NULL) { 115 rte_bbdev_log(ERR, "Failed to allocate queue memory"); 116 return -ENOMEM; 117 } 118 119 q->processed_pkts = rte_ring_create(ring_name, queue_conf->queue_size, 120 queue_conf->socket, RING_F_SP_ENQ | RING_F_SC_DEQ); 121 if (q->processed_pkts == NULL) { 122 rte_bbdev_log(ERR, "Failed to create ring"); 123 goto free_q; 124 } 125 126 dev->data->queues[q_id].queue_private = q; 127 rte_bbdev_log_debug("setup device queue %s", ring_name); 128 return 0; 129 130 free_q: 131 rte_free(q); 132 return -EFAULT; 133 } 134 135 static const struct rte_bbdev_ops pmd_ops = { 136 .info_get = info_get, 137 .queue_setup = q_setup, 138 .queue_release = q_release 139 }; 140 141 /* Enqueue decode burst */ 142 static uint16_t 143 enqueue_dec_ops(struct rte_bbdev_queue_data *q_data, 144 struct rte_bbdev_dec_op **ops, uint16_t nb_ops) 145 { 146 struct bbdev_queue *q = q_data->queue_private; 147 uint16_t nb_enqueued = rte_ring_enqueue_burst(q->processed_pkts, 148 (void **)ops, nb_ops, NULL); 149 150 q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued; 151 q_data->queue_stats.enqueued_count += nb_enqueued; 152 153 return nb_enqueued; 154 } 155 156 /* Enqueue encode burst */ 157 static uint16_t 158 enqueue_enc_ops(struct rte_bbdev_queue_data *q_data, 159 struct rte_bbdev_enc_op **ops, uint16_t nb_ops) 160 { 161 struct bbdev_queue *q = q_data->queue_private; 162 uint16_t nb_enqueued = rte_ring_enqueue_burst(q->processed_pkts, 163 (void **)ops, nb_ops, NULL); 164 165 q_data->queue_stats.enqueue_err_count += nb_ops - nb_enqueued; 166 q_data->queue_stats.enqueued_count += nb_enqueued; 167 168 return nb_enqueued; 169 } 170 171 /* Dequeue decode burst */ 172 static uint16_t 173 dequeue_dec_ops(struct rte_bbdev_queue_data *q_data, 174 struct rte_bbdev_dec_op **ops, uint16_t nb_ops) 175 { 176 struct bbdev_queue *q = q_data->queue_private; 177 uint16_t nb_dequeued = rte_ring_dequeue_burst(q->processed_pkts, 178 (void **)ops, nb_ops, NULL); 179 q_data->queue_stats.dequeued_count += nb_dequeued; 180 181 return nb_dequeued; 182 } 183 184 /* Dequeue encode burst */ 185 static uint16_t 186 dequeue_enc_ops(struct rte_bbdev_queue_data *q_data, 187 struct rte_bbdev_enc_op **ops, uint16_t nb_ops) 188 { 189 struct bbdev_queue *q = q_data->queue_private; 190 uint16_t nb_dequeued = rte_ring_dequeue_burst(q->processed_pkts, 191 (void **)ops, nb_ops, NULL); 192 q_data->queue_stats.dequeued_count += nb_dequeued; 193 194 return nb_dequeued; 195 } 196 197 /* Parse 16bit integer from string argument */ 198 static inline int 199 parse_u16_arg(const char *key, const char *value, void *extra_args) 200 { 201 uint16_t *u16 = extra_args; 202 unsigned int long result; 203 204 if ((value == NULL) || (extra_args == NULL)) 205 return -EINVAL; 206 errno = 0; 207 result = strtoul(value, NULL, 0); 208 if ((result >= (1 << 16)) || (errno != 0)) { 209 rte_bbdev_log(ERR, "Invalid value %lu for %s", result, key); 210 return -ERANGE; 211 } 212 *u16 = (uint16_t)result; 213 return 0; 214 } 215 216 /* Parse parameters used to create device */ 217 static int 218 parse_bbdev_null_params(struct bbdev_null_params *params, 219 const char *input_args) 220 { 221 struct rte_kvargs *kvlist = NULL; 222 int ret = 0; 223 224 if (params == NULL) 225 return -EINVAL; 226 if (input_args) { 227 kvlist = rte_kvargs_parse(input_args, bbdev_null_valid_params); 228 if (kvlist == NULL) 229 return -EFAULT; 230 231 ret = rte_kvargs_process(kvlist, bbdev_null_valid_params[0], 232 &parse_u16_arg, ¶ms->queues_num); 233 if (ret < 0) 234 goto exit; 235 236 ret = rte_kvargs_process(kvlist, bbdev_null_valid_params[1], 237 &parse_u16_arg, ¶ms->socket_id); 238 if (ret < 0) 239 goto exit; 240 241 if (params->socket_id >= RTE_MAX_NUMA_NODES) { 242 rte_bbdev_log(ERR, "Invalid socket, must be < %u", 243 RTE_MAX_NUMA_NODES); 244 goto exit; 245 } 246 } 247 248 exit: 249 if (kvlist) 250 rte_kvargs_free(kvlist); 251 return ret; 252 } 253 254 /* Create device */ 255 static int 256 null_bbdev_create(struct rte_vdev_device *vdev, 257 struct bbdev_null_params *init_params) 258 { 259 struct rte_bbdev *bbdev; 260 const char *name = rte_vdev_device_name(vdev); 261 262 bbdev = rte_bbdev_allocate(name); 263 if (bbdev == NULL) 264 return -ENODEV; 265 266 bbdev->data->dev_private = rte_zmalloc_socket(name, 267 sizeof(struct bbdev_private), RTE_CACHE_LINE_SIZE, 268 init_params->socket_id); 269 if (bbdev->data->dev_private == NULL) { 270 rte_bbdev_release(bbdev); 271 return -ENOMEM; 272 } 273 274 bbdev->dev_ops = &pmd_ops; 275 bbdev->device = &vdev->device; 276 bbdev->data->socket_id = init_params->socket_id; 277 bbdev->intr_handle = NULL; 278 279 /* register rx/tx burst functions for data path */ 280 bbdev->dequeue_enc_ops = dequeue_enc_ops; 281 bbdev->dequeue_dec_ops = dequeue_dec_ops; 282 bbdev->enqueue_enc_ops = enqueue_enc_ops; 283 bbdev->enqueue_dec_ops = enqueue_dec_ops; 284 ((struct bbdev_private *) bbdev->data->dev_private)->max_nb_queues = 285 init_params->queues_num; 286 287 return 0; 288 } 289 290 /* Initialise device */ 291 static int 292 null_bbdev_probe(struct rte_vdev_device *vdev) 293 { 294 struct bbdev_null_params init_params = { 295 rte_socket_id(), 296 RTE_BBDEV_DEFAULT_MAX_NB_QUEUES 297 }; 298 const char *name; 299 const char *input_args; 300 301 if (vdev == NULL) 302 return -EINVAL; 303 304 name = rte_vdev_device_name(vdev); 305 if (name == NULL) 306 return -EINVAL; 307 308 input_args = rte_vdev_device_args(vdev); 309 parse_bbdev_null_params(&init_params, input_args); 310 311 rte_bbdev_log_debug("Init %s on NUMA node %d with max queues: %d", 312 name, init_params.socket_id, init_params.queues_num); 313 314 return null_bbdev_create(vdev, &init_params); 315 } 316 317 /* Uninitialise device */ 318 static int 319 null_bbdev_remove(struct rte_vdev_device *vdev) 320 { 321 struct rte_bbdev *bbdev; 322 const char *name; 323 324 if (vdev == NULL) 325 return -EINVAL; 326 327 name = rte_vdev_device_name(vdev); 328 if (name == NULL) 329 return -EINVAL; 330 331 bbdev = rte_bbdev_get_named_dev(name); 332 if (bbdev == NULL) 333 return -EINVAL; 334 335 rte_free(bbdev->data->dev_private); 336 337 return rte_bbdev_release(bbdev); 338 } 339 340 static struct rte_vdev_driver bbdev_null_pmd_drv = { 341 .probe = null_bbdev_probe, 342 .remove = null_bbdev_remove 343 }; 344 345 RTE_PMD_REGISTER_VDEV(DRIVER_NAME, bbdev_null_pmd_drv); 346 RTE_PMD_REGISTER_PARAM_STRING(DRIVER_NAME, 347 BBDEV_NULL_MAX_NB_QUEUES_ARG"=<int> " 348 BBDEV_NULL_SOCKET_ID_ARG"=<int>"); 349 RTE_PMD_REGISTER_ALIAS(DRIVER_NAME, bbdev_null); 350 351 RTE_INIT(null_bbdev_init_log) 352 { 353 bbdev_null_logtype = rte_log_register("pmd.bb.null"); 354 if (bbdev_null_logtype >= 0) 355 rte_log_set_level(bbdev_null_logtype, RTE_LOG_NOTICE); 356 } 357