1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2017 NXP 3 */ 4 5 #include <ctype.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <stdarg.h> 10 #include <errno.h> 11 #include <stdint.h> 12 #include <inttypes.h> 13 #include <sys/types.h> 14 #include <sys/queue.h> 15 16 #include <rte_string_fns.h> 17 #include <rte_byteorder.h> 18 #include <rte_log.h> 19 #include <rte_debug.h> 20 #include <rte_dev.h> 21 #include <rte_memory.h> 22 #include <rte_memcpy.h> 23 #include <rte_memzone.h> 24 #include <rte_eal.h> 25 #include <rte_per_lcore.h> 26 #include <rte_lcore.h> 27 #include <rte_atomic.h> 28 #include <rte_branch_prediction.h> 29 #include <rte_common.h> 30 #include <rte_malloc.h> 31 #include <rte_errno.h> 32 #include <rte_telemetry.h> 33 34 #include "rte_rawdev.h" 35 #include "rte_rawdev_pmd.h" 36 37 static struct rte_rawdev rte_rawdevices[RTE_RAWDEV_MAX_DEVS]; 38 39 struct rte_rawdev *rte_rawdevs = rte_rawdevices; 40 41 static struct rte_rawdev_global rawdev_globals = { 42 .nb_devs = 0 43 }; 44 45 /* Raw device, northbound API implementation */ 46 uint8_t 47 rte_rawdev_count(void) 48 { 49 return rawdev_globals.nb_devs; 50 } 51 52 uint16_t 53 rte_rawdev_get_dev_id(const char *name) 54 { 55 uint16_t i; 56 57 if (!name) 58 return -EINVAL; 59 60 for (i = 0; i < rawdev_globals.nb_devs; i++) 61 if ((strcmp(rte_rawdevices[i].name, name) 62 == 0) && 63 (rte_rawdevices[i].attached == 64 RTE_RAWDEV_ATTACHED)) 65 return i; 66 return -ENODEV; 67 } 68 69 int 70 rte_rawdev_socket_id(uint16_t dev_id) 71 { 72 struct rte_rawdev *dev; 73 74 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 75 dev = &rte_rawdevs[dev_id]; 76 77 return dev->socket_id; 78 } 79 80 int 81 rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info, 82 size_t dev_private_size) 83 { 84 struct rte_rawdev *rawdev; 85 int ret = 0; 86 87 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 88 RTE_FUNC_PTR_OR_ERR_RET(dev_info, -EINVAL); 89 90 rawdev = &rte_rawdevs[dev_id]; 91 92 if (dev_info->dev_private != NULL) { 93 RTE_FUNC_PTR_OR_ERR_RET(*rawdev->dev_ops->dev_info_get, -ENOTSUP); 94 ret = (*rawdev->dev_ops->dev_info_get)(rawdev, 95 dev_info->dev_private, 96 dev_private_size); 97 } 98 99 dev_info->driver_name = rawdev->driver_name; 100 dev_info->device = rawdev->device; 101 dev_info->socket_id = rawdev->socket_id; 102 103 return ret; 104 } 105 106 int 107 rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf, 108 size_t dev_private_size) 109 { 110 struct rte_rawdev *dev; 111 int diag; 112 113 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 114 RTE_FUNC_PTR_OR_ERR_RET(dev_conf, -EINVAL); 115 116 dev = &rte_rawdevs[dev_id]; 117 118 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP); 119 120 if (dev->started) { 121 RTE_RDEV_ERR( 122 "device %d must be stopped to allow configuration", dev_id); 123 return -EBUSY; 124 } 125 126 /* Configure the device */ 127 diag = (*dev->dev_ops->dev_configure)(dev, dev_conf->dev_private, 128 dev_private_size); 129 if (diag != 0) 130 RTE_RDEV_ERR("dev%d dev_configure = %d", dev_id, diag); 131 else 132 dev->attached = 1; 133 134 return diag; 135 } 136 137 int 138 rte_rawdev_queue_conf_get(uint16_t dev_id, 139 uint16_t queue_id, 140 rte_rawdev_obj_t queue_conf, 141 size_t queue_conf_size) 142 { 143 struct rte_rawdev *dev; 144 145 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 146 dev = &rte_rawdevs[dev_id]; 147 148 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf, -ENOTSUP); 149 return (*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf, 150 queue_conf_size); 151 } 152 153 int 154 rte_rawdev_queue_setup(uint16_t dev_id, 155 uint16_t queue_id, 156 rte_rawdev_obj_t queue_conf, 157 size_t queue_conf_size) 158 { 159 struct rte_rawdev *dev; 160 161 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 162 dev = &rte_rawdevs[dev_id]; 163 164 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_setup, -ENOTSUP); 165 return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf, 166 queue_conf_size); 167 } 168 169 int 170 rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id) 171 { 172 struct rte_rawdev *dev; 173 174 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 175 dev = &rte_rawdevs[dev_id]; 176 177 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_release, -ENOTSUP); 178 return (*dev->dev_ops->queue_release)(dev, queue_id); 179 } 180 181 uint16_t 182 rte_rawdev_queue_count(uint16_t dev_id) 183 { 184 struct rte_rawdev *dev; 185 186 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 187 dev = &rte_rawdevs[dev_id]; 188 189 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_count, -ENOTSUP); 190 return (*dev->dev_ops->queue_count)(dev); 191 } 192 193 int 194 rte_rawdev_get_attr(uint16_t dev_id, 195 const char *attr_name, 196 uint64_t *attr_value) 197 { 198 struct rte_rawdev *dev; 199 200 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 201 dev = &rte_rawdevs[dev_id]; 202 203 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_get, -ENOTSUP); 204 return (*dev->dev_ops->attr_get)(dev, attr_name, attr_value); 205 } 206 207 int 208 rte_rawdev_set_attr(uint16_t dev_id, 209 const char *attr_name, 210 const uint64_t attr_value) 211 { 212 struct rte_rawdev *dev; 213 214 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 215 dev = &rte_rawdevs[dev_id]; 216 217 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_set, -ENOTSUP); 218 return (*dev->dev_ops->attr_set)(dev, attr_name, attr_value); 219 } 220 221 int 222 rte_rawdev_enqueue_buffers(uint16_t dev_id, 223 struct rte_rawdev_buf **buffers, 224 unsigned int count, 225 rte_rawdev_obj_t context) 226 { 227 struct rte_rawdev *dev; 228 229 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 230 dev = &rte_rawdevs[dev_id]; 231 232 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->enqueue_bufs, -ENOTSUP); 233 return (*dev->dev_ops->enqueue_bufs)(dev, buffers, count, context); 234 } 235 236 int 237 rte_rawdev_dequeue_buffers(uint16_t dev_id, 238 struct rte_rawdev_buf **buffers, 239 unsigned int count, 240 rte_rawdev_obj_t context) 241 { 242 struct rte_rawdev *dev; 243 244 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 245 dev = &rte_rawdevs[dev_id]; 246 247 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dequeue_bufs, -ENOTSUP); 248 return (*dev->dev_ops->dequeue_bufs)(dev, buffers, count, context); 249 } 250 251 int 252 rte_rawdev_dump(uint16_t dev_id, FILE *f) 253 { 254 struct rte_rawdev *dev; 255 256 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 257 dev = &rte_rawdevs[dev_id]; 258 259 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dump, -ENOTSUP); 260 return (*dev->dev_ops->dump)(dev, f); 261 } 262 263 static int 264 xstats_get_count(uint16_t dev_id) 265 { 266 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 267 268 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP); 269 return (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); 270 } 271 272 int 273 rte_rawdev_xstats_names_get(uint16_t dev_id, 274 struct rte_rawdev_xstats_name *xstats_names, 275 unsigned int size) 276 { 277 const struct rte_rawdev *dev; 278 int cnt_expected_entries; 279 280 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV); 281 282 cnt_expected_entries = xstats_get_count(dev_id); 283 284 if (xstats_names == NULL || cnt_expected_entries < 0 || 285 (int)size < cnt_expected_entries || size <= 0) 286 return cnt_expected_entries; 287 288 dev = &rte_rawdevs[dev_id]; 289 290 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP); 291 return (*dev->dev_ops->xstats_get_names)(dev, xstats_names, size); 292 } 293 294 /* retrieve rawdev extended statistics */ 295 int 296 rte_rawdev_xstats_get(uint16_t dev_id, 297 const unsigned int ids[], 298 uint64_t values[], 299 unsigned int n) 300 { 301 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV); 302 const struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 303 304 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get, -ENOTSUP); 305 return (*dev->dev_ops->xstats_get)(dev, ids, values, n); 306 } 307 308 uint64_t 309 rte_rawdev_xstats_by_name_get(uint16_t dev_id, 310 const char *name, 311 unsigned int *id) 312 { 313 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, 0); 314 const struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 315 unsigned int temp = -1; 316 317 if (id != NULL) 318 *id = (unsigned int)-1; 319 else 320 id = &temp; /* driver never gets a NULL value */ 321 322 /* implemented by driver */ 323 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_by_name, -ENOTSUP); 324 return (*dev->dev_ops->xstats_get_by_name)(dev, name, id); 325 } 326 327 int 328 rte_rawdev_xstats_reset(uint16_t dev_id, 329 const uint32_t ids[], uint32_t nb_ids) 330 { 331 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 332 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 333 334 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_reset, -ENOTSUP); 335 return (*dev->dev_ops->xstats_reset)(dev, ids, nb_ids); 336 } 337 338 int 339 rte_rawdev_firmware_status_get(uint16_t dev_id, rte_rawdev_obj_t status_info) 340 { 341 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 342 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 343 344 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_status_get, -ENOTSUP); 345 return (*dev->dev_ops->firmware_status_get)(dev, status_info); 346 } 347 348 int 349 rte_rawdev_firmware_version_get(uint16_t dev_id, rte_rawdev_obj_t version_info) 350 { 351 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 352 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 353 354 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_version_get, -ENOTSUP); 355 return (*dev->dev_ops->firmware_version_get)(dev, version_info); 356 } 357 358 int 359 rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image) 360 { 361 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 362 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 363 364 if (!firmware_image) 365 return -EINVAL; 366 367 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP); 368 return (*dev->dev_ops->firmware_load)(dev, firmware_image); 369 } 370 371 int 372 rte_rawdev_firmware_unload(uint16_t dev_id) 373 { 374 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 375 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 376 377 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP); 378 return (*dev->dev_ops->firmware_unload)(dev); 379 } 380 381 int 382 rte_rawdev_selftest(uint16_t dev_id) 383 { 384 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 385 struct rte_rawdev *dev = &rte_rawdevs[dev_id]; 386 387 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_selftest, -ENOTSUP); 388 return (*dev->dev_ops->dev_selftest)(dev_id); 389 } 390 391 int 392 rte_rawdev_start(uint16_t dev_id) 393 { 394 struct rte_rawdev *dev; 395 int diag; 396 397 RTE_RDEV_DEBUG("Start dev_id=%" PRIu8, dev_id); 398 399 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 400 dev = &rte_rawdevs[dev_id]; 401 if (dev->started != 0) { 402 RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already started", 403 dev_id); 404 return 0; 405 } 406 407 if (dev->dev_ops->dev_start == NULL) 408 goto mark_started; 409 410 diag = (*dev->dev_ops->dev_start)(dev); 411 if (diag != 0) 412 return diag; 413 414 mark_started: 415 dev->started = 1; 416 return 0; 417 } 418 419 void 420 rte_rawdev_stop(uint16_t dev_id) 421 { 422 struct rte_rawdev *dev; 423 424 RTE_RDEV_DEBUG("Stop dev_id=%" PRIu8, dev_id); 425 426 RTE_RAWDEV_VALID_DEVID_OR_RET(dev_id); 427 dev = &rte_rawdevs[dev_id]; 428 429 if (dev->started == 0) { 430 RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already stopped", 431 dev_id); 432 return; 433 } 434 435 if (dev->dev_ops->dev_stop == NULL) 436 goto mark_stopped; 437 438 (*dev->dev_ops->dev_stop)(dev); 439 440 mark_stopped: 441 dev->started = 0; 442 } 443 444 int 445 rte_rawdev_close(uint16_t dev_id) 446 { 447 struct rte_rawdev *dev; 448 449 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 450 dev = &rte_rawdevs[dev_id]; 451 452 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP); 453 /* Device must be stopped before it can be closed */ 454 if (dev->started == 1) { 455 RTE_RDEV_ERR("Device %u must be stopped before closing", 456 dev_id); 457 return -EBUSY; 458 } 459 460 return (*dev->dev_ops->dev_close)(dev); 461 } 462 463 int 464 rte_rawdev_reset(uint16_t dev_id) 465 { 466 struct rte_rawdev *dev; 467 468 RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); 469 dev = &rte_rawdevs[dev_id]; 470 471 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP); 472 /* Reset is not dependent on state of the device */ 473 return (*dev->dev_ops->dev_reset)(dev); 474 } 475 476 static inline uint8_t 477 rte_rawdev_find_free_device_index(void) 478 { 479 uint16_t dev_id; 480 481 for (dev_id = 0; dev_id < RTE_RAWDEV_MAX_DEVS; dev_id++) { 482 if (rte_rawdevs[dev_id].attached == 483 RTE_RAWDEV_DETACHED) 484 return dev_id; 485 } 486 487 return RTE_RAWDEV_MAX_DEVS; 488 } 489 490 struct rte_rawdev * 491 rte_rawdev_pmd_allocate(const char *name, size_t dev_priv_size, int socket_id) 492 { 493 struct rte_rawdev *rawdev; 494 uint16_t dev_id; 495 496 if (rte_rawdev_pmd_get_named_dev(name) != NULL) { 497 RTE_RDEV_ERR("Event device with name %s already allocated!", 498 name); 499 return NULL; 500 } 501 502 dev_id = rte_rawdev_find_free_device_index(); 503 if (dev_id == RTE_RAWDEV_MAX_DEVS) { 504 RTE_RDEV_ERR("Reached maximum number of raw devices"); 505 return NULL; 506 } 507 508 rawdev = &rte_rawdevs[dev_id]; 509 510 if (dev_priv_size > 0) { 511 rawdev->dev_private = rte_zmalloc_socket("rawdev private", 512 dev_priv_size, 513 RTE_CACHE_LINE_SIZE, 514 socket_id); 515 if (!rawdev->dev_private) { 516 RTE_RDEV_ERR("Unable to allocate memory for rawdev"); 517 return NULL; 518 } 519 } 520 521 rawdev->dev_id = dev_id; 522 rawdev->socket_id = socket_id; 523 rawdev->started = 0; 524 strlcpy(rawdev->name, name, RTE_RAWDEV_NAME_MAX_LEN); 525 526 rawdev->attached = RTE_RAWDEV_ATTACHED; 527 rawdev_globals.nb_devs++; 528 529 return rawdev; 530 } 531 532 int 533 rte_rawdev_pmd_release(struct rte_rawdev *rawdev) 534 { 535 int ret; 536 537 if (rawdev == NULL) 538 return -EINVAL; 539 540 ret = rte_rawdev_close(rawdev->dev_id); 541 if (ret < 0) 542 return ret; 543 544 rawdev->attached = RTE_RAWDEV_DETACHED; 545 rawdev_globals.nb_devs--; 546 547 rawdev->dev_id = 0; 548 rawdev->socket_id = 0; 549 rawdev->dev_ops = NULL; 550 if (rawdev->dev_private) { 551 rte_free(rawdev->dev_private); 552 rawdev->dev_private = NULL; 553 } 554 555 return 0; 556 } 557 558 static int 559 handle_dev_list(const char *cmd __rte_unused, 560 const char *params __rte_unused, 561 struct rte_tel_data *d) 562 { 563 int i; 564 565 rte_tel_data_start_array(d, RTE_TEL_INT_VAL); 566 for (i = 0; i < rawdev_globals.nb_devs; i++) 567 if (rte_rawdevices[i].attached == RTE_RAWDEV_ATTACHED) 568 rte_tel_data_add_array_int(d, i); 569 return 0; 570 } 571 572 static int 573 handle_dev_xstats(const char *cmd __rte_unused, 574 const char *params, 575 struct rte_tel_data *d) 576 { 577 uint64_t *rawdev_xstats; 578 struct rte_rawdev_xstats_name *xstat_names; 579 int dev_id, num_xstats, i, ret; 580 unsigned int *ids; 581 char *end_param; 582 583 if (params == NULL || strlen(params) == 0 || !isdigit(*params)) 584 return -1; 585 586 dev_id = strtoul(params, &end_param, 0); 587 if (*end_param != '\0') 588 RTE_RDEV_LOG(NOTICE, 589 "Extra parameters passed to rawdev telemetry command, ignoring"); 590 if (!rte_rawdev_pmd_is_valid_dev(dev_id)) 591 return -1; 592 593 num_xstats = xstats_get_count(dev_id); 594 if (num_xstats < 0) 595 return -1; 596 597 /* use one malloc for names, stats and ids */ 598 rawdev_xstats = malloc((sizeof(uint64_t) + 599 sizeof(struct rte_rawdev_xstats_name) + 600 sizeof(unsigned int)) * num_xstats); 601 if (rawdev_xstats == NULL) 602 return -1; 603 xstat_names = (void *)&rawdev_xstats[num_xstats]; 604 ids = (void *)&xstat_names[num_xstats]; 605 606 ret = rte_rawdev_xstats_names_get(dev_id, xstat_names, num_xstats); 607 if (ret < 0 || ret > num_xstats) { 608 free(rawdev_xstats); 609 return -1; 610 } 611 612 for (i = 0; i < num_xstats; i++) 613 ids[i] = i; 614 615 ret = rte_rawdev_xstats_get(dev_id, ids, rawdev_xstats, num_xstats); 616 if (ret < 0 || ret > num_xstats) { 617 free(rawdev_xstats); 618 return -1; 619 } 620 621 rte_tel_data_start_dict(d); 622 for (i = 0; i < num_xstats; i++) 623 rte_tel_data_add_dict_u64(d, xstat_names[i].name, 624 rawdev_xstats[i]); 625 626 free(rawdev_xstats); 627 return 0; 628 } 629 630 RTE_LOG_REGISTER_DEFAULT(librawdev_logtype, INFO); 631 632 RTE_INIT(librawdev_init_telemetry) 633 { 634 rte_telemetry_register_cmd("/rawdev/list", handle_dev_list, 635 "Returns list of available rawdev ports. Takes no parameters"); 636 rte_telemetry_register_cmd("/rawdev/xstats", handle_dev_xstats, 637 "Returns the xstats for a rawdev port. Parameters: int port_id"); 638 } 639