1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright 2017-2020 NXP 4 * 5 */ 6 /* System headers */ 7 #include <stdio.h> 8 #include <inttypes.h> 9 #include <unistd.h> 10 #include <limits.h> 11 #include <sched.h> 12 #include <signal.h> 13 #include <pthread.h> 14 #include <sys/types.h> 15 #include <sys/eventfd.h> 16 17 #include <rte_byteorder.h> 18 #include <rte_common.h> 19 #include <rte_interrupts.h> 20 #include <rte_log.h> 21 #include <rte_debug.h> 22 #include <rte_atomic.h> 23 #include <rte_branch_prediction.h> 24 #include <rte_memory.h> 25 #include <rte_tailq.h> 26 #include <rte_eal.h> 27 #include <rte_alarm.h> 28 #include <rte_ether.h> 29 #include <ethdev_driver.h> 30 #include <rte_malloc.h> 31 #include <rte_ring.h> 32 #include <rte_bus.h> 33 #include <rte_mbuf_pool_ops.h> 34 #include <rte_mbuf_dyn.h> 35 36 #include <dpaa_of.h> 37 #include <rte_dpaa_bus.h> 38 #include <rte_dpaa_logs.h> 39 #include <dpaax_iova_table.h> 40 41 #include <fsl_usd.h> 42 #include <fsl_qman.h> 43 #include <fsl_bman.h> 44 #include <netcfg.h> 45 46 static struct rte_dpaa_bus rte_dpaa_bus; 47 struct netcfg_info *dpaa_netcfg; 48 49 /* define a variable to hold the portal_key, once created.*/ 50 static pthread_key_t dpaa_portal_key; 51 52 unsigned int dpaa_svr_family; 53 54 #define FSL_DPAA_BUS_NAME dpaa_bus 55 56 RTE_DEFINE_PER_LCORE(struct dpaa_portal *, dpaa_io); 57 58 #define DPAA_SEQN_DYNFIELD_NAME "dpaa_seqn_dynfield" 59 int dpaa_seqn_dynfield_offset = -1; 60 61 struct fm_eth_port_cfg * 62 dpaa_get_eth_port_cfg(int dev_id) 63 { 64 return &dpaa_netcfg->port_cfg[dev_id]; 65 } 66 67 static int 68 compare_dpaa_devices(struct rte_dpaa_device *dev1, 69 struct rte_dpaa_device *dev2) 70 { 71 int comp = 0; 72 73 /* Segregating ETH from SEC devices */ 74 if (dev1->device_type > dev2->device_type) 75 comp = 1; 76 else if (dev1->device_type < dev2->device_type) 77 comp = -1; 78 else 79 comp = 0; 80 81 if ((comp != 0) || (dev1->device_type != FSL_DPAA_ETH)) 82 return comp; 83 84 if (dev1->id.fman_id > dev2->id.fman_id) { 85 comp = 1; 86 } else if (dev1->id.fman_id < dev2->id.fman_id) { 87 comp = -1; 88 } else { 89 /* FMAN ids match, check for mac_id */ 90 if (dev1->id.mac_id > dev2->id.mac_id) 91 comp = 1; 92 else if (dev1->id.mac_id < dev2->id.mac_id) 93 comp = -1; 94 else 95 comp = 0; 96 } 97 98 return comp; 99 } 100 101 static inline void 102 dpaa_add_to_device_list(struct rte_dpaa_device *newdev) 103 { 104 int comp, inserted = 0; 105 struct rte_dpaa_device *dev = NULL; 106 struct rte_dpaa_device *tdev = NULL; 107 108 RTE_TAILQ_FOREACH_SAFE(dev, &rte_dpaa_bus.device_list, next, tdev) { 109 comp = compare_dpaa_devices(newdev, dev); 110 if (comp < 0) { 111 TAILQ_INSERT_BEFORE(dev, newdev, next); 112 inserted = 1; 113 break; 114 } 115 } 116 117 if (!inserted) 118 TAILQ_INSERT_TAIL(&rte_dpaa_bus.device_list, newdev, next); 119 } 120 121 /* 122 * Reads the SEC device from DTS 123 * Returns -1 if SEC devices not available, 0 otherwise 124 */ 125 static inline int 126 dpaa_sec_available(void) 127 { 128 const struct device_node *caam_node; 129 130 for_each_compatible_node(caam_node, NULL, "fsl,sec-v4.0") { 131 return 0; 132 } 133 134 return -1; 135 } 136 137 static void dpaa_clean_device_list(void); 138 139 static struct rte_devargs * 140 dpaa_devargs_lookup(struct rte_dpaa_device *dev) 141 { 142 struct rte_devargs *devargs; 143 char dev_name[32]; 144 145 RTE_EAL_DEVARGS_FOREACH("dpaa_bus", devargs) { 146 devargs->bus->parse(devargs->name, &dev_name); 147 if (strcmp(dev_name, dev->device.name) == 0) { 148 DPAA_BUS_INFO("**Devargs matched %s", dev_name); 149 return devargs; 150 } 151 } 152 return NULL; 153 } 154 155 static int 156 dpaa_create_device_list(void) 157 { 158 int i; 159 int ret; 160 struct rte_dpaa_device *dev; 161 struct fm_eth_port_cfg *cfg; 162 struct fman_if *fman_intf; 163 164 /* Creating Ethernet Devices */ 165 for (i = 0; i < dpaa_netcfg->num_ethports; i++) { 166 dev = calloc(1, sizeof(struct rte_dpaa_device)); 167 if (!dev) { 168 DPAA_BUS_LOG(ERR, "Failed to allocate ETH devices"); 169 ret = -ENOMEM; 170 goto cleanup; 171 } 172 173 dev->device.bus = &rte_dpaa_bus.bus; 174 175 /* Allocate interrupt handle instance */ 176 dev->intr_handle = 177 rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); 178 if (dev->intr_handle == NULL) { 179 DPAA_BUS_LOG(ERR, "Failed to allocate intr handle"); 180 ret = -ENOMEM; 181 goto cleanup; 182 } 183 184 cfg = &dpaa_netcfg->port_cfg[i]; 185 fman_intf = cfg->fman_if; 186 187 /* Device identifiers */ 188 dev->id.fman_id = fman_intf->fman_idx + 1; 189 dev->id.mac_id = fman_intf->mac_idx; 190 dev->device_type = FSL_DPAA_ETH; 191 dev->id.dev_id = i; 192 193 /* Create device name */ 194 memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN); 195 sprintf(dev->name, "fm%d-mac%d", (fman_intf->fman_idx + 1), 196 fman_intf->mac_idx); 197 DPAA_BUS_LOG(INFO, "%s netdev added", dev->name); 198 dev->device.name = dev->name; 199 dev->device.devargs = dpaa_devargs_lookup(dev); 200 201 dpaa_add_to_device_list(dev); 202 } 203 204 rte_dpaa_bus.device_count = i; 205 206 /* Unlike case of ETH, RTE_LIBRTE_DPAA_MAX_CRYPTODEV SEC devices are 207 * constantly created only if "sec" property is found in the device 208 * tree. Logically there is no limit for number of devices (QI 209 * interfaces) that can be created. 210 */ 211 212 if (dpaa_sec_available()) { 213 DPAA_BUS_LOG(INFO, "DPAA SEC devices are not available"); 214 return 0; 215 } 216 217 /* Creating SEC Devices */ 218 for (i = 0; i < RTE_LIBRTE_DPAA_MAX_CRYPTODEV; i++) { 219 dev = calloc(1, sizeof(struct rte_dpaa_device)); 220 if (!dev) { 221 DPAA_BUS_LOG(ERR, "Failed to allocate SEC devices"); 222 ret = -1; 223 goto cleanup; 224 } 225 226 /* Allocate interrupt handle instance */ 227 dev->intr_handle = 228 rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); 229 if (dev->intr_handle == NULL) { 230 DPAA_BUS_LOG(ERR, "Failed to allocate intr handle"); 231 ret = -ENOMEM; 232 goto cleanup; 233 } 234 235 dev->device_type = FSL_DPAA_CRYPTO; 236 dev->id.dev_id = rte_dpaa_bus.device_count + i; 237 238 /* Even though RTE_CRYPTODEV_NAME_MAX_LEN is valid length of 239 * crypto PMD, using RTE_ETH_NAME_MAX_LEN as that is the size 240 * allocated for dev->name/ 241 */ 242 memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN); 243 sprintf(dev->name, "dpaa_sec-%d", i+1); 244 DPAA_BUS_LOG(INFO, "%s cryptodev added", dev->name); 245 dev->device.name = dev->name; 246 dev->device.devargs = dpaa_devargs_lookup(dev); 247 248 dpaa_add_to_device_list(dev); 249 } 250 251 rte_dpaa_bus.device_count += i; 252 253 /* Creating QDMA Device */ 254 for (i = 0; i < RTE_DPAA_QDMA_DEVICES; i++) { 255 dev = calloc(1, sizeof(struct rte_dpaa_device)); 256 if (!dev) { 257 DPAA_BUS_LOG(ERR, "Failed to allocate QDMA device"); 258 ret = -1; 259 goto cleanup; 260 } 261 262 dev->device_type = FSL_DPAA_QDMA; 263 dev->id.dev_id = rte_dpaa_bus.device_count + i; 264 265 memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN); 266 sprintf(dev->name, "dpaa_qdma-%d", i+1); 267 DPAA_BUS_LOG(INFO, "%s qdma device added", dev->name); 268 dev->device.name = dev->name; 269 dev->device.devargs = dpaa_devargs_lookup(dev); 270 271 dpaa_add_to_device_list(dev); 272 } 273 rte_dpaa_bus.device_count += i; 274 275 return 0; 276 277 cleanup: 278 dpaa_clean_device_list(); 279 return ret; 280 } 281 282 static void 283 dpaa_clean_device_list(void) 284 { 285 struct rte_dpaa_device *dev = NULL; 286 struct rte_dpaa_device *tdev = NULL; 287 288 RTE_TAILQ_FOREACH_SAFE(dev, &rte_dpaa_bus.device_list, next, tdev) { 289 TAILQ_REMOVE(&rte_dpaa_bus.device_list, dev, next); 290 rte_intr_instance_free(dev->intr_handle); 291 free(dev); 292 dev = NULL; 293 } 294 } 295 296 int rte_dpaa_portal_init(void *arg) 297 { 298 static const struct rte_mbuf_dynfield dpaa_seqn_dynfield_desc = { 299 .name = DPAA_SEQN_DYNFIELD_NAME, 300 .size = sizeof(dpaa_seqn_t), 301 .align = __alignof__(dpaa_seqn_t), 302 }; 303 unsigned int cpu, lcore = rte_lcore_id(); 304 int ret; 305 306 BUS_INIT_FUNC_TRACE(); 307 308 if ((size_t)arg == 1 || lcore == LCORE_ID_ANY) 309 lcore = rte_get_main_lcore(); 310 else 311 if (lcore >= RTE_MAX_LCORE) 312 return -1; 313 314 cpu = rte_lcore_to_cpu_id(lcore); 315 316 dpaa_seqn_dynfield_offset = 317 rte_mbuf_dynfield_register(&dpaa_seqn_dynfield_desc); 318 if (dpaa_seqn_dynfield_offset < 0) { 319 DPAA_BUS_LOG(ERR, "Failed to register mbuf field for dpaa sequence number\n"); 320 return -rte_errno; 321 } 322 323 /* Initialise bman thread portals */ 324 ret = bman_thread_init(); 325 if (ret) { 326 DPAA_BUS_LOG(ERR, "bman_thread_init failed on core %u" 327 " (lcore=%u) with ret: %d", cpu, lcore, ret); 328 return ret; 329 } 330 331 DPAA_BUS_LOG(DEBUG, "BMAN thread initialized - CPU=%d lcore=%d", 332 cpu, lcore); 333 334 /* Initialise qman thread portals */ 335 ret = qman_thread_init(); 336 if (ret) { 337 DPAA_BUS_LOG(ERR, "qman_thread_init failed on core %u" 338 " (lcore=%u) with ret: %d", cpu, lcore, ret); 339 bman_thread_finish(); 340 return ret; 341 } 342 343 DPAA_BUS_LOG(DEBUG, "QMAN thread initialized - CPU=%d lcore=%d", 344 cpu, lcore); 345 346 DPAA_PER_LCORE_PORTAL = rte_malloc(NULL, sizeof(struct dpaa_portal), 347 RTE_CACHE_LINE_SIZE); 348 if (!DPAA_PER_LCORE_PORTAL) { 349 DPAA_BUS_LOG(ERR, "Unable to allocate memory"); 350 bman_thread_finish(); 351 qman_thread_finish(); 352 return -ENOMEM; 353 } 354 355 DPAA_PER_LCORE_PORTAL->qman_idx = qman_get_portal_index(); 356 DPAA_PER_LCORE_PORTAL->bman_idx = bman_get_portal_index(); 357 DPAA_PER_LCORE_PORTAL->tid = rte_gettid(); 358 359 ret = pthread_setspecific(dpaa_portal_key, 360 (void *)DPAA_PER_LCORE_PORTAL); 361 if (ret) { 362 DPAA_BUS_LOG(ERR, "pthread_setspecific failed on core %u" 363 " (lcore=%u) with ret: %d", cpu, lcore, ret); 364 dpaa_portal_finish(NULL); 365 366 return ret; 367 } 368 369 DPAA_BUS_LOG(DEBUG, "QMAN thread initialized"); 370 371 return 0; 372 } 373 374 int 375 rte_dpaa_portal_fq_init(void *arg, struct qman_fq *fq) 376 { 377 /* Affine above created portal with channel*/ 378 u32 sdqcr; 379 int ret; 380 381 if (unlikely(!DPAA_PER_LCORE_PORTAL)) { 382 ret = rte_dpaa_portal_init(arg); 383 if (ret < 0) { 384 DPAA_BUS_LOG(ERR, "portal initialization failure"); 385 return ret; 386 } 387 } 388 389 /* Initialise qman specific portals */ 390 ret = fsl_qman_fq_portal_init(fq->qp); 391 if (ret) { 392 DPAA_BUS_LOG(ERR, "Unable to init fq portal"); 393 return -1; 394 } 395 396 sdqcr = QM_SDQCR_CHANNELS_POOL_CONV(fq->ch_id); 397 qman_static_dequeue_add(sdqcr, fq->qp); 398 399 return 0; 400 } 401 402 int rte_dpaa_portal_fq_close(struct qman_fq *fq) 403 { 404 return fsl_qman_fq_portal_destroy(fq->qp); 405 } 406 407 void 408 dpaa_portal_finish(void *arg) 409 { 410 struct dpaa_portal *dpaa_io_portal = (struct dpaa_portal *)arg; 411 412 if (!dpaa_io_portal) { 413 DPAA_BUS_LOG(DEBUG, "Portal already cleaned"); 414 return; 415 } 416 417 bman_thread_finish(); 418 qman_thread_finish(); 419 420 pthread_setspecific(dpaa_portal_key, NULL); 421 422 rte_free(dpaa_io_portal); 423 dpaa_io_portal = NULL; 424 DPAA_PER_LCORE_PORTAL = NULL; 425 } 426 427 static int 428 rte_dpaa_bus_parse(const char *name, void *out) 429 { 430 unsigned int i, j; 431 size_t delta; 432 size_t max_name_len; 433 434 /* There are two ways of passing device name, with and without 435 * separator. "dpaa_bus:fm1-mac3" with separator, and "fm1-mac3" 436 * without separator. Both need to be handled. 437 * It is also possible that "name=fm1-mac3" is passed along. 438 */ 439 DPAA_BUS_DEBUG("Parse device name (%s)", name); 440 441 delta = 0; 442 if (strncmp(name, "dpaa_bus:", 9) == 0) { 443 delta = 9; 444 } else if (strncmp(name, "name=", 5) == 0) { 445 delta = 5; 446 } 447 448 if (strncmp("dpaa_sec", &name[delta], 8) == 0) { 449 if (sscanf(&name[delta], "dpaa_sec-%u", &i) != 1 || 450 i < 1 || i > 4) 451 return -EINVAL; 452 max_name_len = sizeof("dpaa_sec-.") - 1; 453 } else { 454 if (sscanf(&name[delta], "fm%u-mac%u", &i, &j) != 2 || 455 i >= 2 || j >= 16) 456 return -EINVAL; 457 458 max_name_len = sizeof("fm.-mac..") - 1; 459 } 460 461 if (out != NULL) { 462 char *out_name = out; 463 464 /* Do not check for truncation, either name ends with 465 * '\0' or the device name is followed by parameters and there 466 * will be a ',' instead. Not copying past this comma is not an 467 * error. 468 */ 469 strlcpy(out_name, &name[delta], max_name_len + 1); 470 471 /* Second digit of mac%u could instead be ','. */ 472 if ((strlen(out_name) == max_name_len) && 473 out_name[max_name_len] == ',') 474 out_name[max_name_len] = '\0'; 475 } 476 477 return 0; 478 } 479 480 #define DPAA_DEV_PATH1 "/sys/devices/platform/soc/soc:fsl,dpaa" 481 #define DPAA_DEV_PATH2 "/sys/devices/platform/fsl,dpaa" 482 483 static int 484 rte_dpaa_bus_scan(void) 485 { 486 int ret; 487 488 BUS_INIT_FUNC_TRACE(); 489 490 if ((access(DPAA_DEV_PATH1, F_OK) != 0) && 491 (access(DPAA_DEV_PATH2, F_OK) != 0)) { 492 RTE_LOG(DEBUG, EAL, "DPAA Bus not present. Skipping.\n"); 493 return 0; 494 } 495 496 if (rte_dpaa_bus.detected) 497 return 0; 498 499 rte_dpaa_bus.detected = 1; 500 501 /* create the key, supplying a function that'll be invoked 502 * when a portal affined thread will be deleted. 503 */ 504 ret = pthread_key_create(&dpaa_portal_key, dpaa_portal_finish); 505 if (ret) { 506 DPAA_BUS_LOG(DEBUG, "Unable to create pthread key. (%d)", ret); 507 dpaa_clean_device_list(); 508 return ret; 509 } 510 511 return 0; 512 } 513 514 /* register a dpaa bus based dpaa driver */ 515 void 516 rte_dpaa_driver_register(struct rte_dpaa_driver *driver) 517 { 518 RTE_VERIFY(driver); 519 520 BUS_INIT_FUNC_TRACE(); 521 522 TAILQ_INSERT_TAIL(&rte_dpaa_bus.driver_list, driver, next); 523 /* Update Bus references */ 524 driver->dpaa_bus = &rte_dpaa_bus; 525 } 526 527 /* un-register a dpaa bus based dpaa driver */ 528 void 529 rte_dpaa_driver_unregister(struct rte_dpaa_driver *driver) 530 { 531 struct rte_dpaa_bus *dpaa_bus; 532 533 BUS_INIT_FUNC_TRACE(); 534 535 dpaa_bus = driver->dpaa_bus; 536 537 TAILQ_REMOVE(&dpaa_bus->driver_list, driver, next); 538 /* Update Bus references */ 539 driver->dpaa_bus = NULL; 540 } 541 542 static int 543 rte_dpaa_device_match(struct rte_dpaa_driver *drv, 544 struct rte_dpaa_device *dev) 545 { 546 if (!drv || !dev) { 547 DPAA_BUS_DEBUG("Invalid drv or dev received."); 548 return -1; 549 } 550 551 if (drv->drv_type == dev->device_type) 552 return 0; 553 554 return -1; 555 } 556 557 static int 558 rte_dpaa_bus_dev_build(void) 559 { 560 int ret; 561 562 /* Load the device-tree driver */ 563 ret = of_init(); 564 if (ret) { 565 DPAA_BUS_LOG(ERR, "of_init failed with ret: %d", ret); 566 return -1; 567 } 568 569 /* Get the interface configurations from device-tree */ 570 dpaa_netcfg = netcfg_acquire(); 571 if (!dpaa_netcfg) { 572 DPAA_BUS_LOG(ERR, 573 "netcfg failed: /dev/fsl_usdpaa device not available"); 574 DPAA_BUS_WARN( 575 "Check if you are using USDPAA based device tree"); 576 return -EINVAL; 577 } 578 579 RTE_LOG(NOTICE, EAL, "DPAA Bus Detected\n"); 580 581 if (!dpaa_netcfg->num_ethports) { 582 DPAA_BUS_LOG(INFO, "NO DPDK mapped net interfaces available"); 583 /* This is not an error */ 584 } 585 586 #ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER 587 dump_netcfg(dpaa_netcfg); 588 #endif 589 590 DPAA_BUS_LOG(DEBUG, "Number of ethernet devices = %d", 591 dpaa_netcfg->num_ethports); 592 ret = dpaa_create_device_list(); 593 if (ret) { 594 DPAA_BUS_LOG(ERR, "Unable to create device list. (%d)", ret); 595 return ret; 596 } 597 return 0; 598 } 599 600 static int rte_dpaa_setup_intr(struct rte_intr_handle *intr_handle) 601 { 602 int fd; 603 604 fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 605 if (fd < 0) { 606 DPAA_BUS_ERR("Cannot set up eventfd, error %i (%s)", 607 errno, strerror(errno)); 608 return errno; 609 } 610 611 if (rte_intr_fd_set(intr_handle, fd)) 612 return rte_errno; 613 614 if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_EXT)) 615 return rte_errno; 616 617 return 0; 618 } 619 620 static int 621 rte_dpaa_bus_probe(void) 622 { 623 int ret = -1; 624 struct rte_dpaa_device *dev; 625 struct rte_dpaa_driver *drv; 626 FILE *svr_file = NULL; 627 unsigned int svr_ver; 628 int probe_all = rte_dpaa_bus.bus.conf.scan_mode != RTE_BUS_SCAN_ALLOWLIST; 629 static int process_once; 630 631 /* If DPAA bus is not present nothing needs to be done */ 632 if (!rte_dpaa_bus.detected) 633 return 0; 634 635 /* Device list creation is only done once */ 636 if (!process_once) { 637 rte_dpaa_bus_dev_build(); 638 /* One time load of Qman/Bman drivers */ 639 ret = qman_global_init(); 640 if (ret) { 641 DPAA_BUS_ERR("QMAN initialization failed: %d", 642 ret); 643 return ret; 644 } 645 ret = bman_global_init(); 646 if (ret) { 647 DPAA_BUS_ERR("BMAN initialization failed: %d", 648 ret); 649 return ret; 650 } 651 } 652 process_once = 1; 653 654 /* If no device present on DPAA bus nothing needs to be done */ 655 if (TAILQ_EMPTY(&rte_dpaa_bus.device_list)) 656 return 0; 657 658 svr_file = fopen(DPAA_SOC_ID_FILE, "r"); 659 if (svr_file) { 660 if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) 661 dpaa_svr_family = svr_ver & SVR_MASK; 662 fclose(svr_file); 663 } 664 665 TAILQ_FOREACH(dev, &rte_dpaa_bus.device_list, next) { 666 if (dev->device_type == FSL_DPAA_ETH) { 667 ret = rte_dpaa_setup_intr(dev->intr_handle); 668 if (ret) 669 DPAA_BUS_ERR("Error setting up interrupt.\n"); 670 } 671 } 672 673 /* And initialize the PA->VA translation table */ 674 dpaax_iova_table_populate(); 675 676 /* For each registered driver, and device, call the driver->probe */ 677 TAILQ_FOREACH(dev, &rte_dpaa_bus.device_list, next) { 678 TAILQ_FOREACH(drv, &rte_dpaa_bus.driver_list, next) { 679 ret = rte_dpaa_device_match(drv, dev); 680 if (ret) 681 continue; 682 683 if (rte_dev_is_probed(&dev->device)) 684 continue; 685 686 if (!drv->probe || 687 (dev->device.devargs && 688 dev->device.devargs->policy == RTE_DEV_BLOCKED)) 689 continue; 690 691 if (probe_all || 692 (dev->device.devargs && 693 dev->device.devargs->policy == RTE_DEV_ALLOWED)) { 694 ret = drv->probe(drv, dev); 695 if (ret) { 696 DPAA_BUS_ERR("unable to probe:%s", 697 dev->name); 698 } else { 699 dev->driver = drv; 700 dev->device.driver = &drv->driver; 701 } 702 } 703 break; 704 } 705 } 706 707 /* Register DPAA mempool ops only if any DPAA device has 708 * been detected. 709 */ 710 rte_mbuf_set_platform_mempool_ops(DPAA_MEMPOOL_OPS_NAME); 711 712 return 0; 713 } 714 715 static struct rte_device * 716 rte_dpaa_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, 717 const void *data) 718 { 719 struct rte_dpaa_device *dev; 720 const struct rte_dpaa_device *dstart; 721 722 /* find_device is called with 'data' as an opaque object - just call 723 * cmp with this and each device object on bus. 724 */ 725 726 if (start != NULL) { 727 dstart = RTE_DEV_TO_DPAA_CONST(start); 728 dev = TAILQ_NEXT(dstart, next); 729 } else { 730 dev = TAILQ_FIRST(&rte_dpaa_bus.device_list); 731 } 732 733 while (dev != NULL) { 734 if (cmp(&dev->device, data) == 0) { 735 DPAA_BUS_DEBUG("Found dev=(%s)\n", dev->device.name); 736 return &dev->device; 737 } 738 dev = TAILQ_NEXT(dev, next); 739 } 740 741 DPAA_BUS_DEBUG("Unable to find any device\n"); 742 return NULL; 743 } 744 745 /* 746 * Get iommu class of DPAA2 devices on the bus. 747 */ 748 static enum rte_iova_mode 749 rte_dpaa_get_iommu_class(void) 750 { 751 if ((access(DPAA_DEV_PATH1, F_OK) != 0) && 752 (access(DPAA_DEV_PATH2, F_OK) != 0)) { 753 return RTE_IOVA_DC; 754 } 755 return RTE_IOVA_PA; 756 } 757 758 static int 759 dpaa_bus_plug(struct rte_device *dev __rte_unused) 760 { 761 /* No operation is performed while plugging the device */ 762 return 0; 763 } 764 765 static int 766 dpaa_bus_unplug(struct rte_device *dev __rte_unused) 767 { 768 /* No operation is performed while unplugging the device */ 769 return 0; 770 } 771 772 static void * 773 dpaa_bus_dev_iterate(const void *start, const char *str, 774 const struct rte_dev_iterator *it __rte_unused) 775 { 776 const struct rte_dpaa_device *dstart; 777 struct rte_dpaa_device *dev; 778 char *dup, *dev_name = NULL; 779 780 if (str == NULL) { 781 DPAA_BUS_DEBUG("No device string"); 782 return NULL; 783 } 784 785 /* Expectation is that device would be name=device_name */ 786 if (strncmp(str, "name=", 5) != 0) { 787 DPAA_BUS_DEBUG("Invalid device string (%s)\n", str); 788 return NULL; 789 } 790 791 /* Now that name=device_name format is available, split */ 792 dup = strdup(str); 793 dev_name = dup + strlen("name="); 794 795 if (start != NULL) { 796 dstart = RTE_DEV_TO_DPAA_CONST(start); 797 dev = TAILQ_NEXT(dstart, next); 798 } else { 799 dev = TAILQ_FIRST(&rte_dpaa_bus.device_list); 800 } 801 802 while (dev != NULL) { 803 if (strcmp(dev->device.name, dev_name) == 0) { 804 free(dup); 805 return &dev->device; 806 } 807 dev = TAILQ_NEXT(dev, next); 808 } 809 810 free(dup); 811 return NULL; 812 } 813 814 static struct rte_dpaa_bus rte_dpaa_bus = { 815 .bus = { 816 .scan = rte_dpaa_bus_scan, 817 .probe = rte_dpaa_bus_probe, 818 .parse = rte_dpaa_bus_parse, 819 .find_device = rte_dpaa_find_device, 820 .get_iommu_class = rte_dpaa_get_iommu_class, 821 .plug = dpaa_bus_plug, 822 .unplug = dpaa_bus_unplug, 823 .dev_iterate = dpaa_bus_dev_iterate, 824 }, 825 .device_list = TAILQ_HEAD_INITIALIZER(rte_dpaa_bus.device_list), 826 .driver_list = TAILQ_HEAD_INITIALIZER(rte_dpaa_bus.driver_list), 827 .device_count = 0, 828 }; 829 830 RTE_REGISTER_BUS(FSL_DPAA_BUS_NAME, rte_dpaa_bus.bus); 831 RTE_LOG_REGISTER_DEFAULT(dpaa_logtype_bus, NOTICE); 832