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