1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <dirent.h> 7 #include <sys/stat.h> 8 #include <unistd.h> 9 #include <sys/types.h> 10 #include <fcntl.h> 11 #include <rte_log.h> 12 #include <rte_bus.h> 13 #include <rte_malloc.h> 14 #include <rte_devargs.h> 15 #include <rte_memcpy.h> 16 #include <rte_pci.h> 17 #include <rte_bus_pci.h> 18 #include <rte_kvargs.h> 19 #include <rte_alarm.h> 20 21 #include <rte_errno.h> 22 #include <rte_per_lcore.h> 23 #include <rte_memory.h> 24 #include <rte_memzone.h> 25 #include <rte_eal.h> 26 #include <rte_common.h> 27 #include <rte_bus_vdev.h> 28 29 #include "base/opae_hw_api.h" 30 #include "rte_rawdev.h" 31 #include "rte_rawdev_pmd.h" 32 #include "rte_bus_ifpga.h" 33 #include "ifpga_common.h" 34 #include "ifpga_logs.h" 35 #include "ifpga_rawdev.h" 36 #include "ipn3ke_rawdev_api.h" 37 38 int ifpga_rawdev_logtype; 39 40 #define PCI_VENDOR_ID_INTEL 0x8086 41 /* PCI Device ID */ 42 #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD 43 #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0 44 #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4 45 #define PCIE_DEVICE_ID_PAC_N3000 0x0B30 46 /* VF Device */ 47 #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF 48 #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1 49 #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5 50 #define PCIE_DEVICE_ID_VF_PAC_N3000 0x0B31 51 #define RTE_MAX_RAW_DEVICE 10 52 53 static const struct rte_pci_id pci_ifpga_map[] = { 54 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X) }, 55 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X) }, 56 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X) }, 57 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X) }, 58 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X) }, 59 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X) }, 60 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PAC_N3000),}, 61 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_PAC_N3000),}, 62 { .vendor_id = 0, /* sentinel */ }, 63 }; 64 65 static int 66 ifpga_fill_afu_dev(struct opae_accelerator *acc, 67 struct rte_afu_device *afu_dev) 68 { 69 struct rte_mem_resource *res = afu_dev->mem_resource; 70 struct opae_acc_region_info region_info; 71 struct opae_acc_info info; 72 unsigned long i; 73 int ret; 74 75 ret = opae_acc_get_info(acc, &info); 76 if (ret) 77 return ret; 78 79 if (info.num_regions > PCI_MAX_RESOURCE) 80 return -EFAULT; 81 82 afu_dev->num_region = info.num_regions; 83 84 for (i = 0; i < info.num_regions; i++) { 85 region_info.index = i; 86 ret = opae_acc_get_region_info(acc, ®ion_info); 87 if (ret) 88 return ret; 89 90 if ((region_info.flags & ACC_REGION_MMIO) && 91 (region_info.flags & ACC_REGION_READ) && 92 (region_info.flags & ACC_REGION_WRITE)) { 93 res[i].phys_addr = region_info.phys_addr; 94 res[i].len = region_info.len; 95 res[i].addr = region_info.addr; 96 } else 97 return -EFAULT; 98 } 99 100 return 0; 101 } 102 103 static void 104 ifpga_rawdev_info_get(struct rte_rawdev *dev, 105 rte_rawdev_obj_t dev_info) 106 { 107 struct opae_adapter *adapter; 108 struct opae_accelerator *acc; 109 struct rte_afu_device *afu_dev; 110 struct opae_manager *mgr = NULL; 111 struct opae_eth_group_region_info opae_lside_eth_info; 112 struct opae_eth_group_region_info opae_nside_eth_info; 113 int lside_bar_idx, nside_bar_idx; 114 115 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 116 117 if (!dev_info) { 118 IFPGA_RAWDEV_PMD_ERR("Invalid request"); 119 return; 120 } 121 122 adapter = ifpga_rawdev_get_priv(dev); 123 if (!adapter) 124 return; 125 126 afu_dev = dev_info; 127 afu_dev->rawdev = dev; 128 129 /* find opae_accelerator and fill info into afu_device */ 130 opae_adapter_for_each_acc(adapter, acc) { 131 if (acc->index != afu_dev->id.port) 132 continue; 133 134 if (ifpga_fill_afu_dev(acc, afu_dev)) { 135 IFPGA_RAWDEV_PMD_ERR("cannot get info\n"); 136 return; 137 } 138 } 139 140 /* get opae_manager to rawdev */ 141 mgr = opae_adapter_get_mgr(adapter); 142 if (mgr) { 143 /* get LineSide BAR Index */ 144 if (opae_manager_get_eth_group_region_info(mgr, 0, 145 &opae_lside_eth_info)) { 146 return; 147 } 148 lside_bar_idx = opae_lside_eth_info.mem_idx; 149 150 /* get NICSide BAR Index */ 151 if (opae_manager_get_eth_group_region_info(mgr, 1, 152 &opae_nside_eth_info)) { 153 return; 154 } 155 nside_bar_idx = opae_nside_eth_info.mem_idx; 156 157 if (lside_bar_idx >= PCI_MAX_RESOURCE || 158 nside_bar_idx >= PCI_MAX_RESOURCE || 159 lside_bar_idx == nside_bar_idx) 160 return; 161 162 /* fill LineSide BAR Index */ 163 afu_dev->mem_resource[lside_bar_idx].phys_addr = 164 opae_lside_eth_info.phys_addr; 165 afu_dev->mem_resource[lside_bar_idx].len = 166 opae_lside_eth_info.len; 167 afu_dev->mem_resource[lside_bar_idx].addr = 168 opae_lside_eth_info.addr; 169 170 /* fill NICSide BAR Index */ 171 afu_dev->mem_resource[nside_bar_idx].phys_addr = 172 opae_nside_eth_info.phys_addr; 173 afu_dev->mem_resource[nside_bar_idx].len = 174 opae_nside_eth_info.len; 175 afu_dev->mem_resource[nside_bar_idx].addr = 176 opae_nside_eth_info.addr; 177 } 178 } 179 180 static int 181 ifpga_rawdev_configure(const struct rte_rawdev *dev, 182 rte_rawdev_obj_t config) 183 { 184 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 185 186 RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); 187 188 return config ? 0 : 1; 189 } 190 191 static int 192 ifpga_rawdev_start(struct rte_rawdev *dev) 193 { 194 int ret = 0; 195 struct opae_adapter *adapter; 196 197 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 198 199 RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); 200 201 adapter = ifpga_rawdev_get_priv(dev); 202 if (!adapter) 203 return -ENODEV; 204 205 return ret; 206 } 207 208 static void 209 ifpga_rawdev_stop(struct rte_rawdev *dev) 210 { 211 dev->started = 0; 212 } 213 214 static int 215 ifpga_rawdev_close(struct rte_rawdev *dev) 216 { 217 return dev ? 0:1; 218 } 219 220 static int 221 ifpga_rawdev_reset(struct rte_rawdev *dev) 222 { 223 return dev ? 0:1; 224 } 225 226 static int 227 fpga_pr(struct rte_rawdev *raw_dev, u32 port_id, const char *buffer, u32 size, 228 u64 *status) 229 { 230 231 struct opae_adapter *adapter; 232 struct opae_manager *mgr; 233 struct opae_accelerator *acc; 234 struct opae_bridge *br; 235 int ret; 236 237 adapter = ifpga_rawdev_get_priv(raw_dev); 238 if (!adapter) 239 return -ENODEV; 240 241 mgr = opae_adapter_get_mgr(adapter); 242 if (!mgr) 243 return -ENODEV; 244 245 acc = opae_adapter_get_acc(adapter, port_id); 246 if (!acc) 247 return -ENODEV; 248 249 br = opae_acc_get_br(acc); 250 if (!br) 251 return -ENODEV; 252 253 ret = opae_manager_flash(mgr, port_id, buffer, size, status); 254 if (ret) { 255 IFPGA_RAWDEV_PMD_ERR("%s pr error %d\n", __func__, ret); 256 return ret; 257 } 258 259 ret = opae_bridge_reset(br); 260 if (ret) { 261 IFPGA_RAWDEV_PMD_ERR("%s reset port:%d error %d\n", 262 __func__, port_id, ret); 263 return ret; 264 } 265 266 return ret; 267 } 268 269 static int 270 rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, 271 const char *file_name) 272 { 273 struct stat file_stat; 274 int file_fd; 275 int ret = 0; 276 ssize_t buffer_size; 277 void *buffer; 278 u64 pr_error; 279 280 if (!file_name) 281 return -EINVAL; 282 283 file_fd = open(file_name, O_RDONLY); 284 if (file_fd < 0) { 285 IFPGA_RAWDEV_PMD_ERR("%s: open file error: %s\n", 286 __func__, file_name); 287 IFPGA_RAWDEV_PMD_ERR("Message : %s\n", strerror(errno)); 288 return -EINVAL; 289 } 290 ret = stat(file_name, &file_stat); 291 if (ret) { 292 IFPGA_RAWDEV_PMD_ERR("stat on bitstream file failed: %s\n", 293 file_name); 294 ret = -EINVAL; 295 goto close_fd; 296 } 297 buffer_size = file_stat.st_size; 298 if (buffer_size <= 0) { 299 ret = -EINVAL; 300 goto close_fd; 301 } 302 303 IFPGA_RAWDEV_PMD_INFO("bitstream file size: %zu\n", buffer_size); 304 buffer = rte_malloc(NULL, buffer_size, 0); 305 if (!buffer) { 306 ret = -ENOMEM; 307 goto close_fd; 308 } 309 310 /*read the raw data*/ 311 if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) { 312 ret = -EINVAL; 313 goto free_buffer; 314 } 315 316 /*do PR now*/ 317 ret = fpga_pr(rawdev, port_id, buffer, buffer_size, &pr_error); 318 IFPGA_RAWDEV_PMD_INFO("downloading to device port %d....%s.\n", port_id, 319 ret ? "failed" : "success"); 320 if (ret) { 321 ret = -EINVAL; 322 goto free_buffer; 323 } 324 325 free_buffer: 326 if (buffer) 327 rte_free(buffer); 328 close_fd: 329 close(file_fd); 330 file_fd = 0; 331 return ret; 332 } 333 334 static int 335 ifpga_rawdev_pr(struct rte_rawdev *dev, 336 rte_rawdev_obj_t pr_conf) 337 { 338 struct opae_adapter *adapter; 339 struct rte_afu_pr_conf *afu_pr_conf; 340 int ret; 341 struct uuid uuid; 342 struct opae_accelerator *acc; 343 344 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 345 346 adapter = ifpga_rawdev_get_priv(dev); 347 if (!adapter) 348 return -ENODEV; 349 350 if (!pr_conf) 351 return -EINVAL; 352 353 afu_pr_conf = pr_conf; 354 355 if (afu_pr_conf->pr_enable) { 356 ret = rte_fpga_do_pr(dev, 357 afu_pr_conf->afu_id.port, 358 afu_pr_conf->bs_path); 359 if (ret) { 360 IFPGA_RAWDEV_PMD_ERR("do pr error %d\n", ret); 361 return ret; 362 } 363 } 364 365 acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port); 366 if (!acc) 367 return -ENODEV; 368 369 ret = opae_acc_get_uuid(acc, &uuid); 370 if (ret) 371 return ret; 372 373 memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64)); 374 memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64)); 375 376 IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__, 377 (unsigned long)afu_pr_conf->afu_id.uuid.uuid_low, 378 (unsigned long)afu_pr_conf->afu_id.uuid.uuid_high); 379 380 return 0; 381 } 382 383 static int 384 ifpga_rawdev_get_attr(struct rte_rawdev *dev, 385 const char *attr_name, uint64_t *attr_value) 386 { 387 struct opae_adapter *adapter; 388 struct opae_manager *mgr; 389 struct opae_retimer_info opae_rtm_info; 390 struct opae_retimer_status opae_rtm_status; 391 struct opae_eth_group_info opae_eth_grp_info; 392 struct opae_eth_group_region_info opae_eth_grp_reg_info; 393 int eth_group_num = 0; 394 uint64_t port_link_bitmap = 0, port_link_bit; 395 uint32_t i, j, p, q; 396 397 #define MAX_PORT_PER_RETIMER 4 398 399 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 400 401 if (!dev || !attr_name || !attr_value) { 402 IFPGA_RAWDEV_PMD_ERR("Invalid arguments for getting attributes"); 403 return -1; 404 } 405 406 adapter = ifpga_rawdev_get_priv(dev); 407 if (!adapter) { 408 IFPGA_RAWDEV_PMD_ERR("Adapter of dev %s is NULL", dev->name); 409 return -1; 410 } 411 412 mgr = opae_adapter_get_mgr(adapter); 413 if (!mgr) { 414 IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL"); 415 return -1; 416 } 417 418 /* currently, eth_group_num is always 2 */ 419 eth_group_num = opae_manager_get_eth_group_nums(mgr); 420 if (eth_group_num < 0) 421 return -1; 422 423 if (!strcmp(attr_name, "LineSideBaseMAC")) { 424 /* Currently FPGA not implement, so just set all zeros*/ 425 *attr_value = (uint64_t)0; 426 return 0; 427 } 428 if (!strcmp(attr_name, "LineSideMACType")) { 429 /* eth_group 0 on FPGA connect to LineSide */ 430 if (opae_manager_get_eth_group_info(mgr, 0, 431 &opae_eth_grp_info)) 432 return -1; 433 switch (opae_eth_grp_info.speed) { 434 case ETH_SPEED_10G: 435 *attr_value = 436 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI); 437 break; 438 case ETH_SPEED_25G: 439 *attr_value = 440 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI); 441 break; 442 default: 443 *attr_value = 444 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_UNKNOWN); 445 break; 446 } 447 return 0; 448 } 449 if (!strcmp(attr_name, "LineSideLinkSpeed")) { 450 if (opae_manager_get_retimer_status(mgr, &opae_rtm_status)) 451 return -1; 452 switch (opae_rtm_status.speed) { 453 case MXD_1GB: 454 *attr_value = 455 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 456 break; 457 case MXD_2_5GB: 458 *attr_value = 459 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 460 break; 461 case MXD_5GB: 462 *attr_value = 463 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 464 break; 465 case MXD_10GB: 466 *attr_value = 467 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_10GB); 468 break; 469 case MXD_25GB: 470 *attr_value = 471 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_25GB); 472 break; 473 case MXD_40GB: 474 *attr_value = 475 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_40GB); 476 break; 477 case MXD_100GB: 478 *attr_value = 479 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 480 break; 481 case MXD_SPEED_UNKNOWN: 482 *attr_value = 483 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 484 break; 485 default: 486 *attr_value = 487 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 488 break; 489 } 490 return 0; 491 } 492 if (!strcmp(attr_name, "LineSideLinkRetimerNum")) { 493 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 494 return -1; 495 *attr_value = (uint64_t)(opae_rtm_info.nums_retimer); 496 return 0; 497 } 498 if (!strcmp(attr_name, "LineSideLinkPortNum")) { 499 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 500 return -1; 501 uint64_t tmp = (uint64_t)opae_rtm_info.ports_per_retimer * 502 (uint64_t)opae_rtm_info.nums_retimer; 503 *attr_value = tmp; 504 return 0; 505 } 506 if (!strcmp(attr_name, "LineSideLinkStatus")) { 507 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 508 return -1; 509 if (opae_manager_get_retimer_status(mgr, &opae_rtm_status)) 510 return -1; 511 (*attr_value) = 0; 512 q = 0; 513 port_link_bitmap = (uint64_t)(opae_rtm_status.line_link_bitmap); 514 for (i = 0; i < opae_rtm_info.nums_retimer; i++) { 515 p = i * MAX_PORT_PER_RETIMER; 516 for (j = 0; j < opae_rtm_info.ports_per_retimer; j++) { 517 port_link_bit = 0; 518 IFPGA_BIT_SET(port_link_bit, (p+j)); 519 port_link_bit &= port_link_bitmap; 520 if (port_link_bit) 521 IFPGA_BIT_SET((*attr_value), q); 522 q++; 523 } 524 } 525 return 0; 526 } 527 if (!strcmp(attr_name, "LineSideBARIndex")) { 528 /* eth_group 0 on FPGA connect to LineSide */ 529 if (opae_manager_get_eth_group_region_info(mgr, 0, 530 &opae_eth_grp_reg_info)) 531 return -1; 532 *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx; 533 return 0; 534 } 535 if (!strcmp(attr_name, "NICSideMACType")) { 536 /* eth_group 1 on FPGA connect to NicSide */ 537 if (opae_manager_get_eth_group_info(mgr, 1, 538 &opae_eth_grp_info)) 539 return -1; 540 *attr_value = (uint64_t)(opae_eth_grp_info.speed); 541 return 0; 542 } 543 if (!strcmp(attr_name, "NICSideLinkSpeed")) { 544 /* eth_group 1 on FPGA connect to NicSide */ 545 if (opae_manager_get_eth_group_info(mgr, 1, 546 &opae_eth_grp_info)) 547 return -1; 548 *attr_value = (uint64_t)(opae_eth_grp_info.speed); 549 return 0; 550 } 551 if (!strcmp(attr_name, "NICSideLinkPortNum")) { 552 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 553 return -1; 554 uint64_t tmp = (uint64_t)opae_rtm_info.nums_fvl * 555 (uint64_t)opae_rtm_info.ports_per_fvl; 556 *attr_value = tmp; 557 return 0; 558 } 559 if (!strcmp(attr_name, "NICSideLinkStatus")) 560 return 0; 561 if (!strcmp(attr_name, "NICSideBARIndex")) { 562 /* eth_group 1 on FPGA connect to NicSide */ 563 if (opae_manager_get_eth_group_region_info(mgr, 1, 564 &opae_eth_grp_reg_info)) 565 return -1; 566 *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx; 567 return 0; 568 } 569 570 IFPGA_RAWDEV_PMD_ERR("%s not support", attr_name); 571 return -1; 572 } 573 574 static const struct rte_rawdev_ops ifpga_rawdev_ops = { 575 .dev_info_get = ifpga_rawdev_info_get, 576 .dev_configure = ifpga_rawdev_configure, 577 .dev_start = ifpga_rawdev_start, 578 .dev_stop = ifpga_rawdev_stop, 579 .dev_close = ifpga_rawdev_close, 580 .dev_reset = ifpga_rawdev_reset, 581 582 .queue_def_conf = NULL, 583 .queue_setup = NULL, 584 .queue_release = NULL, 585 586 .attr_get = ifpga_rawdev_get_attr, 587 .attr_set = NULL, 588 589 .enqueue_bufs = NULL, 590 .dequeue_bufs = NULL, 591 592 .dump = NULL, 593 594 .xstats_get = NULL, 595 .xstats_get_names = NULL, 596 .xstats_get_by_name = NULL, 597 .xstats_reset = NULL, 598 599 .firmware_status_get = NULL, 600 .firmware_version_get = NULL, 601 .firmware_load = ifpga_rawdev_pr, 602 .firmware_unload = NULL, 603 604 .dev_selftest = NULL, 605 }; 606 607 static int 608 ifpga_rawdev_create(struct rte_pci_device *pci_dev, 609 int socket_id) 610 { 611 int ret = 0; 612 struct rte_rawdev *rawdev = NULL; 613 struct opae_adapter *adapter = NULL; 614 struct opae_manager *mgr = NULL; 615 struct opae_adapter_data_pci *data = NULL; 616 char name[RTE_RAWDEV_NAME_MAX_LEN]; 617 int i; 618 619 if (!pci_dev) { 620 IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); 621 ret = -EINVAL; 622 goto cleanup; 623 } 624 625 memset(name, 0, sizeof(name)); 626 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x", 627 pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); 628 629 IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id()); 630 631 /* Allocate device structure */ 632 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct opae_adapter), 633 socket_id); 634 if (rawdev == NULL) { 635 IFPGA_RAWDEV_PMD_ERR("Unable to allocate rawdevice"); 636 ret = -EINVAL; 637 goto cleanup; 638 } 639 640 /* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */ 641 data = opae_adapter_data_alloc(OPAE_FPGA_PCI); 642 if (!data) { 643 ret = -ENOMEM; 644 goto cleanup; 645 } 646 647 /* init opae_adapter_data_pci for device specific information */ 648 for (i = 0; i < PCI_MAX_RESOURCE; i++) { 649 data->region[i].phys_addr = pci_dev->mem_resource[i].phys_addr; 650 data->region[i].len = pci_dev->mem_resource[i].len; 651 data->region[i].addr = pci_dev->mem_resource[i].addr; 652 } 653 data->device_id = pci_dev->id.device_id; 654 data->vendor_id = pci_dev->id.vendor_id; 655 656 adapter = rawdev->dev_private; 657 /* create a opae_adapter based on above device data */ 658 ret = opae_adapter_init(adapter, pci_dev->device.name, data); 659 if (ret) { 660 ret = -ENOMEM; 661 goto free_adapter_data; 662 } 663 664 rawdev->dev_ops = &ifpga_rawdev_ops; 665 rawdev->device = &pci_dev->device; 666 rawdev->driver_name = pci_dev->driver->driver.name; 667 668 /* must enumerate the adapter before use it */ 669 ret = opae_adapter_enumerate(adapter); 670 if (ret) 671 goto free_adapter_data; 672 673 /* get opae_manager to rawdev */ 674 mgr = opae_adapter_get_mgr(adapter); 675 if (mgr) { 676 /* PF function */ 677 IFPGA_RAWDEV_PMD_INFO("this is a PF function"); 678 } 679 680 return ret; 681 682 free_adapter_data: 683 if (data) 684 opae_adapter_data_free(data); 685 cleanup: 686 if (rawdev) 687 rte_rawdev_pmd_release(rawdev); 688 689 return ret; 690 } 691 692 static int 693 ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) 694 { 695 int ret; 696 struct rte_rawdev *rawdev; 697 char name[RTE_RAWDEV_NAME_MAX_LEN]; 698 struct opae_adapter *adapter; 699 700 if (!pci_dev) { 701 IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); 702 ret = -EINVAL; 703 return ret; 704 } 705 706 memset(name, 0, sizeof(name)); 707 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x", 708 pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); 709 710 IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d", 711 name, rte_socket_id()); 712 713 rawdev = rte_rawdev_pmd_get_named_dev(name); 714 if (!rawdev) { 715 IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); 716 return -EINVAL; 717 } 718 719 adapter = ifpga_rawdev_get_priv(rawdev); 720 if (!adapter) 721 return -ENODEV; 722 723 opae_adapter_data_free(adapter->data); 724 opae_adapter_free(adapter); 725 726 /* rte_rawdev_close is called by pmd_release */ 727 ret = rte_rawdev_pmd_release(rawdev); 728 if (ret) 729 IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed"); 730 731 return ret; 732 } 733 734 static int 735 ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 736 struct rte_pci_device *pci_dev) 737 { 738 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 739 return ifpga_rawdev_create(pci_dev, rte_socket_id()); 740 } 741 742 static int 743 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev) 744 { 745 return ifpga_rawdev_destroy(pci_dev); 746 } 747 748 static struct rte_pci_driver rte_ifpga_rawdev_pmd = { 749 .id_table = pci_ifpga_map, 750 .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 751 .probe = ifpga_rawdev_pci_probe, 752 .remove = ifpga_rawdev_pci_remove, 753 }; 754 755 RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); 756 RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); 757 RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci"); 758 759 RTE_INIT(ifpga_rawdev_init_log) 760 { 761 ifpga_rawdev_logtype = rte_log_register("driver.raw.init"); 762 if (ifpga_rawdev_logtype >= 0) 763 rte_log_set_level(ifpga_rawdev_logtype, RTE_LOG_NOTICE); 764 } 765 766 static const char * const valid_args[] = { 767 #define IFPGA_ARG_NAME "ifpga" 768 IFPGA_ARG_NAME, 769 #define IFPGA_ARG_PORT "port" 770 IFPGA_ARG_PORT, 771 #define IFPGA_AFU_BTS "afu_bts" 772 IFPGA_AFU_BTS, 773 NULL 774 }; 775 776 static int 777 ifpga_cfg_probe(struct rte_vdev_device *dev) 778 { 779 struct rte_devargs *devargs; 780 struct rte_kvargs *kvlist = NULL; 781 int port; 782 char *name = NULL; 783 char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; 784 int ret = -1; 785 786 devargs = dev->device.devargs; 787 788 kvlist = rte_kvargs_parse(devargs->args, valid_args); 789 if (!kvlist) { 790 IFPGA_RAWDEV_PMD_LOG(ERR, "error when parsing param"); 791 goto end; 792 } 793 794 if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) { 795 if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME, 796 &rte_ifpga_get_string_arg, &name) < 0) { 797 IFPGA_RAWDEV_PMD_ERR("error to parse %s", 798 IFPGA_ARG_NAME); 799 goto end; 800 } 801 } else { 802 IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", 803 IFPGA_ARG_NAME); 804 goto end; 805 } 806 807 if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) { 808 if (rte_kvargs_process(kvlist, 809 IFPGA_ARG_PORT, 810 &rte_ifpga_get_integer32_arg, 811 &port) < 0) { 812 IFPGA_RAWDEV_PMD_ERR("error to parse %s", 813 IFPGA_ARG_PORT); 814 goto end; 815 } 816 } else { 817 IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", 818 IFPGA_ARG_PORT); 819 goto end; 820 } 821 822 memset(dev_name, 0, sizeof(dev_name)); 823 snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", 824 port, name); 825 826 ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME), 827 dev_name, devargs->args); 828 end: 829 if (kvlist) 830 rte_kvargs_free(kvlist); 831 if (name) 832 free(name); 833 834 return ret; 835 } 836 837 static int 838 ifpga_cfg_remove(struct rte_vdev_device *vdev) 839 { 840 IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p", 841 vdev); 842 843 return 0; 844 } 845 846 static struct rte_vdev_driver ifpga_cfg_driver = { 847 .probe = ifpga_cfg_probe, 848 .remove = ifpga_cfg_remove, 849 }; 850 851 RTE_PMD_REGISTER_VDEV(ifpga_rawdev_cfg, ifpga_cfg_driver); 852 RTE_PMD_REGISTER_ALIAS(ifpga_rawdev_cfg, ifpga_cfg); 853 RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg, 854 "ifpga=<string> " 855 "port=<int> " 856 "afu_bts=<path>"); 857