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