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 <sys/ioctl.h> 12 #include <sys/epoll.h> 13 #include <rte_log.h> 14 #include <rte_bus.h> 15 #include <rte_malloc.h> 16 #include <rte_devargs.h> 17 #include <rte_memcpy.h> 18 #include <rte_pci.h> 19 #include <rte_bus_pci.h> 20 #include <rte_kvargs.h> 21 #include <rte_alarm.h> 22 #include <rte_interrupts.h> 23 #include <rte_errno.h> 24 #include <rte_per_lcore.h> 25 #include <rte_memory.h> 26 #include <rte_memzone.h> 27 #include <rte_eal.h> 28 #include <rte_common.h> 29 #include <rte_bus_vdev.h> 30 #include <rte_string_fns.h> 31 #include <rte_pmd_i40e.h> 32 33 #include "base/opae_hw_api.h" 34 #include "base/opae_ifpga_hw_api.h" 35 #include "base/ifpga_api.h" 36 #include "rte_rawdev.h" 37 #include "rte_rawdev_pmd.h" 38 #include "rte_bus_ifpga.h" 39 #include "ifpga_common.h" 40 #include "ifpga_logs.h" 41 #include "ifpga_rawdev.h" 42 #include "ipn3ke_rawdev_api.h" 43 44 #define RTE_PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */ 45 #define RTE_PCI_CFG_SPACE_SIZE 256 46 #define RTE_PCI_CFG_SPACE_EXP_SIZE 4096 47 #define RTE_PCI_EXT_CAP_ID(header) (int)(header & 0x0000ffff) 48 #define RTE_PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) 49 50 #define PCI_VENDOR_ID_INTEL 0x8086 51 /* PCI Device ID */ 52 #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD 53 #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0 54 #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4 55 #define PCIE_DEVICE_ID_PAC_N3000 0x0B30 56 /* VF Device */ 57 #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF 58 #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1 59 #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5 60 #define PCIE_DEVICE_ID_VF_PAC_N3000 0x0B31 61 #define RTE_MAX_RAW_DEVICE 10 62 63 static const struct rte_pci_id pci_ifpga_map[] = { 64 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X) }, 65 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X) }, 66 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X) }, 67 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X) }, 68 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X) }, 69 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X) }, 70 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PAC_N3000),}, 71 { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_PAC_N3000),}, 72 { .vendor_id = 0, /* sentinel */ }, 73 }; 74 75 static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM]; 76 77 static int ifpga_monitor_start; 78 static pthread_t ifpga_monitor_start_thread; 79 80 #define IFPGA_MAX_IRQ 12 81 /* 0 for FME interrupt, others are reserved for AFU irq */ 82 static struct rte_intr_handle ifpga_irq_handle[IFPGA_MAX_IRQ]; 83 84 static struct ifpga_rawdev * 85 ifpga_rawdev_allocate(struct rte_rawdev *rawdev); 86 static int set_surprise_link_check_aer( 87 struct ifpga_rawdev *ifpga_rdev, int force_disable); 88 static int ifpga_pci_find_next_ext_capability(unsigned int fd, 89 int start, int cap); 90 static int ifpga_pci_find_ext_capability(unsigned int fd, int cap); 91 92 struct ifpga_rawdev * 93 ifpga_rawdev_get(const struct rte_rawdev *rawdev) 94 { 95 struct ifpga_rawdev *dev; 96 unsigned int i; 97 98 if (rawdev == NULL) 99 return NULL; 100 101 for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { 102 dev = &ifpga_rawdevices[i]; 103 if (dev->rawdev == rawdev) 104 return dev; 105 } 106 107 return NULL; 108 } 109 110 static inline uint8_t 111 ifpga_rawdev_find_free_device_index(void) 112 { 113 uint16_t dev_id; 114 115 for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) { 116 if (ifpga_rawdevices[dev_id].rawdev == NULL) 117 return dev_id; 118 } 119 120 return IFPGA_RAWDEV_NUM; 121 } 122 static struct ifpga_rawdev * 123 ifpga_rawdev_allocate(struct rte_rawdev *rawdev) 124 { 125 struct ifpga_rawdev *dev; 126 uint16_t dev_id; 127 128 dev = ifpga_rawdev_get(rawdev); 129 if (dev != NULL) { 130 IFPGA_RAWDEV_PMD_ERR("Event device already allocated!"); 131 return NULL; 132 } 133 134 dev_id = ifpga_rawdev_find_free_device_index(); 135 if (dev_id == IFPGA_RAWDEV_NUM) { 136 IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices"); 137 return NULL; 138 } 139 140 dev = &ifpga_rawdevices[dev_id]; 141 dev->rawdev = rawdev; 142 dev->dev_id = dev_id; 143 144 return dev; 145 } 146 147 static int ifpga_pci_find_next_ext_capability(unsigned int fd, 148 int start, int cap) 149 { 150 uint32_t header; 151 int ttl; 152 int pos = RTE_PCI_CFG_SPACE_SIZE; 153 int ret; 154 155 /* minimum 8 bytes per capability */ 156 ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8; 157 158 if (start) 159 pos = start; 160 ret = pread(fd, &header, sizeof(header), pos); 161 if (ret == -1) 162 return -1; 163 164 /* 165 * If we have no capabilities, this is indicated by cap ID, 166 * cap version and next pointer all being 0. 167 */ 168 if (header == 0) 169 return 0; 170 171 while (ttl-- > 0) { 172 if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start) 173 return pos; 174 175 pos = RTE_PCI_EXT_CAP_NEXT(header); 176 if (pos < RTE_PCI_CFG_SPACE_SIZE) 177 break; 178 ret = pread(fd, &header, sizeof(header), pos); 179 if (ret == -1) 180 return -1; 181 } 182 183 return 0; 184 } 185 186 static int ifpga_pci_find_ext_capability(unsigned int fd, int cap) 187 { 188 return ifpga_pci_find_next_ext_capability(fd, 0, cap); 189 } 190 191 static int ifpga_get_dev_vendor_id(const char *bdf, 192 uint32_t *dev_id, uint32_t *vendor_id) 193 { 194 int fd; 195 char path[1024]; 196 int ret; 197 uint32_t header; 198 199 strlcpy(path, "/sys/bus/pci/devices/", sizeof(path)); 200 strlcat(path, bdf, sizeof(path)); 201 strlcat(path, "/config", sizeof(path)); 202 fd = open(path, O_RDWR); 203 if (fd < 0) 204 return -1; 205 ret = pread(fd, &header, sizeof(header), 0); 206 if (ret == -1) { 207 close(fd); 208 return -1; 209 } 210 (*vendor_id) = header & 0xffff; 211 (*dev_id) = (header >> 16) & 0xffff; 212 close(fd); 213 214 return 0; 215 } 216 static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev, 217 const char *bdf) 218 { 219 char path[1024] = "/sys/bus/pci/devices/0000:"; 220 char link[1024], link1[1024]; 221 char dir[1024] = "/sys/devices/"; 222 char *c; 223 int ret; 224 char sub_brg_bdf[4][16]; 225 int point; 226 DIR *dp = NULL; 227 struct dirent *entry; 228 int i, j; 229 230 unsigned int dom, bus, dev; 231 int func; 232 uint32_t dev_id, vendor_id; 233 234 strlcat(path, bdf, sizeof(path)); 235 memset(link, 0, sizeof(link)); 236 memset(link1, 0, sizeof(link1)); 237 ret = readlink(path, link, (sizeof(link)-1)); 238 if (ret == -1) 239 return -1; 240 strlcpy(link1, link, sizeof(link1)); 241 memset(ifpga_dev->parent_bdf, 0, 16); 242 point = strlen(link); 243 if (point < 39) 244 return -1; 245 point -= 39; 246 link[point] = 0; 247 if (point < 12) 248 return -1; 249 point -= 12; 250 rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12); 251 252 point = strlen(link1); 253 if (point < 26) 254 return -1; 255 point -= 26; 256 link1[point] = 0; 257 if (point < 12) 258 return -1; 259 point -= 12; 260 c = strchr(link1, 'p'); 261 if (!c) 262 return -1; 263 strlcat(dir, c, sizeof(dir)); 264 265 /* scan folder */ 266 dp = opendir(dir); 267 if (dp == NULL) 268 return -1; 269 i = 0; 270 while ((entry = readdir(dp)) != NULL) { 271 if (i >= 4) 272 break; 273 if (entry->d_name[0] == '.') 274 continue; 275 if (strlen(entry->d_name) > 12) 276 continue; 277 if (sscanf(entry->d_name, "%x:%x:%x.%d", 278 &dom, &bus, &dev, &func) < 4) 279 continue; 280 else { 281 strlcpy(sub_brg_bdf[i], 282 entry->d_name, 283 sizeof(sub_brg_bdf[i])); 284 i++; 285 } 286 } 287 closedir(dp); 288 289 /* get fpga and fvl */ 290 j = 0; 291 for (i = 0; i < 4; i++) { 292 strlcpy(link, dir, sizeof(link)); 293 strlcat(link, "/", sizeof(link)); 294 strlcat(link, sub_brg_bdf[i], sizeof(link)); 295 dp = opendir(link); 296 if (dp == NULL) 297 return -1; 298 while ((entry = readdir(dp)) != NULL) { 299 if (j >= 8) 300 break; 301 if (entry->d_name[0] == '.') 302 continue; 303 304 if (strlen(entry->d_name) > 12) 305 continue; 306 if (sscanf(entry->d_name, "%x:%x:%x.%d", 307 &dom, &bus, &dev, &func) < 4) 308 continue; 309 else { 310 if (ifpga_get_dev_vendor_id(entry->d_name, 311 &dev_id, &vendor_id)) 312 continue; 313 if (vendor_id == 0x8086 && 314 (dev_id == 0x0CF8 || 315 dev_id == 0x0D58 || 316 dev_id == 0x1580)) { 317 strlcpy(ifpga_dev->fvl_bdf[j], 318 entry->d_name, 319 sizeof(ifpga_dev->fvl_bdf[j])); 320 j++; 321 } 322 } 323 } 324 closedir(dp); 325 } 326 327 return 0; 328 } 329 330 #define HIGH_FATAL(_sens, value)\ 331 (((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\ 332 (value > (_sens)->high_fatal)) 333 334 #define HIGH_WARN(_sens, value)\ 335 (((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\ 336 (value > (_sens)->high_warn)) 337 338 #define LOW_FATAL(_sens, value)\ 339 (((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\ 340 (value > (_sens)->low_fatal)) 341 342 #define LOW_WARN(_sens, value)\ 343 (((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\ 344 (value > (_sens)->low_warn)) 345 346 #define AUX_VOLTAGE_WARN 11400 347 348 static int 349 ifpga_monitor_sensor(struct rte_rawdev *raw_dev, 350 bool *gsd_start) 351 { 352 struct opae_adapter *adapter; 353 struct opae_manager *mgr; 354 struct opae_sensor_info *sensor; 355 unsigned int value; 356 int ret; 357 358 adapter = ifpga_rawdev_get_priv(raw_dev); 359 if (!adapter) 360 return -ENODEV; 361 362 mgr = opae_adapter_get_mgr(adapter); 363 if (!mgr) 364 return -ENODEV; 365 366 opae_mgr_for_each_sensor(mgr, sensor) { 367 if (!(sensor->flags & OPAE_SENSOR_VALID)) 368 goto fail; 369 370 ret = opae_mgr_get_sensor_value(mgr, sensor, &value); 371 if (ret) 372 goto fail; 373 374 if (value == 0xdeadbeef) { 375 IFPGA_RAWDEV_PMD_ERR("dev_id %d sensor %s value %x\n", 376 raw_dev->dev_id, sensor->name, value); 377 continue; 378 } 379 380 /* monitor temperature sensors */ 381 if (!strcmp(sensor->name, "Board Temperature") || 382 !strcmp(sensor->name, "FPGA Die Temperature")) { 383 IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n", 384 sensor->name, value, sensor->high_warn, 385 sensor->high_fatal); 386 387 if (HIGH_WARN(sensor, value) || 388 LOW_WARN(sensor, value)) { 389 IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n", 390 sensor->name, value); 391 *gsd_start = true; 392 break; 393 } 394 } 395 396 /* monitor 12V AUX sensor */ 397 if (!strcmp(sensor->name, "12V AUX Voltage")) { 398 if (value < AUX_VOLTAGE_WARN) { 399 IFPGA_RAWDEV_PMD_INFO( 400 "%s reach theshold %d mV\n", 401 sensor->name, value); 402 *gsd_start = true; 403 break; 404 } 405 } 406 } 407 408 return 0; 409 fail: 410 return -EFAULT; 411 } 412 413 static int set_surprise_link_check_aer( 414 struct ifpga_rawdev *ifpga_rdev, int force_disable) 415 { 416 struct rte_rawdev *rdev; 417 int fd = -1; 418 char path[1024]; 419 int pos; 420 int ret; 421 uint32_t data; 422 bool enable = 0; 423 uint32_t aer_new0, aer_new1; 424 425 if (!ifpga_rdev) { 426 printf("\n device does not exist\n"); 427 return -EFAULT; 428 } 429 430 rdev = ifpga_rdev->rawdev; 431 if (ifpga_rdev->aer_enable) 432 return -EFAULT; 433 if (ifpga_monitor_sensor(rdev, &enable)) 434 return -EFAULT; 435 if (enable || force_disable) { 436 IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n"); 437 ifpga_rdev->aer_enable = 1; 438 /* get bridge fd */ 439 strlcpy(path, "/sys/bus/pci/devices/", sizeof(path)); 440 strlcat(path, ifpga_rdev->parent_bdf, sizeof(path)); 441 strlcat(path, "/config", sizeof(path)); 442 fd = open(path, O_RDWR); 443 if (fd < 0) 444 goto end; 445 pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR); 446 if (!pos) 447 goto end; 448 /* save previout ECAP_AER+0x08 */ 449 ret = pread(fd, &data, sizeof(data), pos+0x08); 450 if (ret == -1) 451 goto end; 452 ifpga_rdev->aer_old[0] = data; 453 /* save previout ECAP_AER+0x14 */ 454 ret = pread(fd, &data, sizeof(data), pos+0x14); 455 if (ret == -1) 456 goto end; 457 ifpga_rdev->aer_old[1] = data; 458 459 /* set ECAP_AER+0x08 to 0xFFFFFFFF */ 460 data = 0xffffffff; 461 ret = pwrite(fd, &data, 4, pos+0x08); 462 if (ret == -1) 463 goto end; 464 /* set ECAP_AER+0x14 to 0xFFFFFFFF */ 465 ret = pwrite(fd, &data, 4, pos+0x14); 466 if (ret == -1) 467 goto end; 468 469 /* read current ECAP_AER+0x08 */ 470 ret = pread(fd, &data, sizeof(data), pos+0x08); 471 if (ret == -1) 472 goto end; 473 aer_new0 = data; 474 /* read current ECAP_AER+0x14 */ 475 ret = pread(fd, &data, sizeof(data), pos+0x14); 476 if (ret == -1) 477 goto end; 478 aer_new1 = data; 479 480 if (fd != -1) 481 close(fd); 482 483 printf(">>>>>>Set AER %x,%x %x,%x\n", 484 ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1], 485 aer_new0, aer_new1); 486 487 return 1; 488 } 489 490 end: 491 if (fd != -1) 492 close(fd); 493 return -EFAULT; 494 } 495 496 static void * 497 ifpga_rawdev_gsd_handle(__rte_unused void *param) 498 { 499 struct ifpga_rawdev *ifpga_rdev; 500 int i; 501 int gsd_enable, ret; 502 #define MS 1000 503 504 while (1) { 505 gsd_enable = 0; 506 for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { 507 ifpga_rdev = &ifpga_rawdevices[i]; 508 if (ifpga_rdev->rawdev) { 509 ret = set_surprise_link_check_aer(ifpga_rdev, 510 gsd_enable); 511 if (ret == 1 && !gsd_enable) { 512 gsd_enable = 1; 513 i = -1; 514 } 515 } 516 } 517 518 if (gsd_enable) 519 printf(">>>>>>Pls Shutdown APP\n"); 520 521 rte_delay_us(100 * MS); 522 } 523 524 return NULL; 525 } 526 527 static int 528 ifpga_monitor_start_func(void) 529 { 530 int ret; 531 532 if (ifpga_monitor_start == 0) { 533 ret = pthread_create(&ifpga_monitor_start_thread, 534 NULL, 535 ifpga_rawdev_gsd_handle, NULL); 536 if (ret) { 537 IFPGA_RAWDEV_PMD_ERR( 538 "Fail to create ifpga nonitor thread"); 539 return -1; 540 } 541 ifpga_monitor_start = 1; 542 } 543 544 return 0; 545 } 546 static int 547 ifpga_monitor_stop_func(void) 548 { 549 int ret; 550 551 if (ifpga_monitor_start == 1) { 552 ret = pthread_cancel(ifpga_monitor_start_thread); 553 if (ret) 554 IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread"); 555 556 ret = pthread_join(ifpga_monitor_start_thread, NULL); 557 if (ret) 558 IFPGA_RAWDEV_PMD_ERR("Can't join the thread"); 559 560 ifpga_monitor_start = 0; 561 562 return ret; 563 } 564 565 return 0; 566 } 567 568 static int 569 ifpga_fill_afu_dev(struct opae_accelerator *acc, 570 struct rte_afu_device *afu_dev) 571 { 572 struct rte_mem_resource *res = afu_dev->mem_resource; 573 struct opae_acc_region_info region_info; 574 struct opae_acc_info info; 575 unsigned long i; 576 int ret; 577 578 ret = opae_acc_get_info(acc, &info); 579 if (ret) 580 return ret; 581 582 if (info.num_regions > PCI_MAX_RESOURCE) 583 return -EFAULT; 584 585 afu_dev->num_region = info.num_regions; 586 587 for (i = 0; i < info.num_regions; i++) { 588 region_info.index = i; 589 ret = opae_acc_get_region_info(acc, ®ion_info); 590 if (ret) 591 return ret; 592 593 if ((region_info.flags & ACC_REGION_MMIO) && 594 (region_info.flags & ACC_REGION_READ) && 595 (region_info.flags & ACC_REGION_WRITE)) { 596 res[i].phys_addr = region_info.phys_addr; 597 res[i].len = region_info.len; 598 res[i].addr = region_info.addr; 599 } else 600 return -EFAULT; 601 } 602 603 return 0; 604 } 605 606 static int 607 ifpga_rawdev_info_get(struct rte_rawdev *dev, 608 rte_rawdev_obj_t dev_info, 609 size_t dev_info_size) 610 { 611 struct opae_adapter *adapter; 612 struct opae_accelerator *acc; 613 struct rte_afu_device *afu_dev; 614 struct opae_manager *mgr = NULL; 615 struct opae_eth_group_region_info opae_lside_eth_info; 616 struct opae_eth_group_region_info opae_nside_eth_info; 617 int lside_bar_idx, nside_bar_idx; 618 619 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 620 621 if (!dev_info || dev_info_size != sizeof(*afu_dev)) { 622 IFPGA_RAWDEV_PMD_ERR("Invalid request"); 623 return -EINVAL; 624 } 625 626 adapter = ifpga_rawdev_get_priv(dev); 627 if (!adapter) 628 return -ENOENT; 629 630 afu_dev = dev_info; 631 afu_dev->rawdev = dev; 632 633 /* find opae_accelerator and fill info into afu_device */ 634 opae_adapter_for_each_acc(adapter, acc) { 635 if (acc->index != afu_dev->id.port) 636 continue; 637 638 if (ifpga_fill_afu_dev(acc, afu_dev)) { 639 IFPGA_RAWDEV_PMD_ERR("cannot get info\n"); 640 return -ENOENT; 641 } 642 } 643 644 /* get opae_manager to rawdev */ 645 mgr = opae_adapter_get_mgr(adapter); 646 if (mgr) { 647 /* get LineSide BAR Index */ 648 if (opae_manager_get_eth_group_region_info(mgr, 0, 649 &opae_lside_eth_info)) { 650 return -ENOENT; 651 } 652 lside_bar_idx = opae_lside_eth_info.mem_idx; 653 654 /* get NICSide BAR Index */ 655 if (opae_manager_get_eth_group_region_info(mgr, 1, 656 &opae_nside_eth_info)) { 657 return -ENOENT; 658 } 659 nside_bar_idx = opae_nside_eth_info.mem_idx; 660 661 if (lside_bar_idx >= PCI_MAX_RESOURCE || 662 nside_bar_idx >= PCI_MAX_RESOURCE || 663 lside_bar_idx == nside_bar_idx) 664 return -ENOENT; 665 666 /* fill LineSide BAR Index */ 667 afu_dev->mem_resource[lside_bar_idx].phys_addr = 668 opae_lside_eth_info.phys_addr; 669 afu_dev->mem_resource[lside_bar_idx].len = 670 opae_lside_eth_info.len; 671 afu_dev->mem_resource[lside_bar_idx].addr = 672 opae_lside_eth_info.addr; 673 674 /* fill NICSide BAR Index */ 675 afu_dev->mem_resource[nside_bar_idx].phys_addr = 676 opae_nside_eth_info.phys_addr; 677 afu_dev->mem_resource[nside_bar_idx].len = 678 opae_nside_eth_info.len; 679 afu_dev->mem_resource[nside_bar_idx].addr = 680 opae_nside_eth_info.addr; 681 } 682 return 0; 683 } 684 685 static int 686 ifpga_rawdev_configure(const struct rte_rawdev *dev, 687 rte_rawdev_obj_t config, 688 size_t config_size __rte_unused) 689 { 690 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 691 692 RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); 693 694 return config ? 0 : 1; 695 } 696 697 static int 698 ifpga_rawdev_start(struct rte_rawdev *dev) 699 { 700 int ret = 0; 701 struct opae_adapter *adapter; 702 703 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 704 705 RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); 706 707 adapter = ifpga_rawdev_get_priv(dev); 708 if (!adapter) 709 return -ENODEV; 710 711 return ret; 712 } 713 714 static void 715 ifpga_rawdev_stop(struct rte_rawdev *dev) 716 { 717 dev->started = 0; 718 } 719 720 static int 721 ifpga_rawdev_close(struct rte_rawdev *dev) 722 { 723 return dev ? 0:1; 724 } 725 726 static int 727 ifpga_rawdev_reset(struct rte_rawdev *dev) 728 { 729 return dev ? 0:1; 730 } 731 732 static int 733 fpga_pr(struct rte_rawdev *raw_dev, u32 port_id, const char *buffer, u32 size, 734 u64 *status) 735 { 736 737 struct opae_adapter *adapter; 738 struct opae_manager *mgr; 739 struct opae_accelerator *acc; 740 struct opae_bridge *br; 741 int ret; 742 743 adapter = ifpga_rawdev_get_priv(raw_dev); 744 if (!adapter) 745 return -ENODEV; 746 747 mgr = opae_adapter_get_mgr(adapter); 748 if (!mgr) 749 return -ENODEV; 750 751 acc = opae_adapter_get_acc(adapter, port_id); 752 if (!acc) 753 return -ENODEV; 754 755 br = opae_acc_get_br(acc); 756 if (!br) 757 return -ENODEV; 758 759 ret = opae_manager_flash(mgr, port_id, buffer, size, status); 760 if (ret) { 761 IFPGA_RAWDEV_PMD_ERR("%s pr error %d\n", __func__, ret); 762 return ret; 763 } 764 765 ret = opae_bridge_reset(br); 766 if (ret) { 767 IFPGA_RAWDEV_PMD_ERR("%s reset port:%d error %d\n", 768 __func__, port_id, ret); 769 return ret; 770 } 771 772 return ret; 773 } 774 775 static int 776 rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, 777 const char *file_name) 778 { 779 struct stat file_stat; 780 int file_fd; 781 int ret = 0; 782 ssize_t buffer_size; 783 void *buffer; 784 u64 pr_error; 785 786 if (!file_name) 787 return -EINVAL; 788 789 file_fd = open(file_name, O_RDONLY); 790 if (file_fd < 0) { 791 IFPGA_RAWDEV_PMD_ERR("%s: open file error: %s\n", 792 __func__, file_name); 793 IFPGA_RAWDEV_PMD_ERR("Message : %s\n", strerror(errno)); 794 return -EINVAL; 795 } 796 ret = stat(file_name, &file_stat); 797 if (ret) { 798 IFPGA_RAWDEV_PMD_ERR("stat on bitstream file failed: %s\n", 799 file_name); 800 ret = -EINVAL; 801 goto close_fd; 802 } 803 buffer_size = file_stat.st_size; 804 if (buffer_size <= 0) { 805 ret = -EINVAL; 806 goto close_fd; 807 } 808 809 IFPGA_RAWDEV_PMD_INFO("bitstream file size: %zu\n", buffer_size); 810 buffer = rte_malloc(NULL, buffer_size, 0); 811 if (!buffer) { 812 ret = -ENOMEM; 813 goto close_fd; 814 } 815 816 /*read the raw data*/ 817 if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) { 818 ret = -EINVAL; 819 goto free_buffer; 820 } 821 822 /*do PR now*/ 823 ret = fpga_pr(rawdev, port_id, buffer, buffer_size, &pr_error); 824 IFPGA_RAWDEV_PMD_INFO("downloading to device port %d....%s.\n", port_id, 825 ret ? "failed" : "success"); 826 if (ret) { 827 ret = -EINVAL; 828 goto free_buffer; 829 } 830 831 free_buffer: 832 if (buffer) 833 rte_free(buffer); 834 close_fd: 835 close(file_fd); 836 file_fd = 0; 837 return ret; 838 } 839 840 static int 841 ifpga_rawdev_pr(struct rte_rawdev *dev, 842 rte_rawdev_obj_t pr_conf) 843 { 844 struct opae_adapter *adapter; 845 struct opae_manager *mgr; 846 struct opae_board_info *info; 847 struct rte_afu_pr_conf *afu_pr_conf; 848 int ret; 849 struct uuid uuid; 850 struct opae_accelerator *acc; 851 852 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 853 854 adapter = ifpga_rawdev_get_priv(dev); 855 if (!adapter) 856 return -ENODEV; 857 858 if (!pr_conf) 859 return -EINVAL; 860 861 afu_pr_conf = pr_conf; 862 863 if (afu_pr_conf->pr_enable) { 864 ret = rte_fpga_do_pr(dev, 865 afu_pr_conf->afu_id.port, 866 afu_pr_conf->bs_path); 867 if (ret) { 868 IFPGA_RAWDEV_PMD_ERR("do pr error %d\n", ret); 869 return ret; 870 } 871 } 872 873 mgr = opae_adapter_get_mgr(adapter); 874 if (!mgr) { 875 IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL"); 876 return -1; 877 } 878 879 if (ifpga_mgr_ops.get_board_info(mgr, &info)) { 880 IFPGA_RAWDEV_PMD_ERR("ifpga manager get_board_info fail!"); 881 return -1; 882 } 883 884 if (info->lightweight) { 885 /* set uuid to all 0, when fpga is lightweight image */ 886 memset(&afu_pr_conf->afu_id.uuid.uuid_low, 0, sizeof(u64)); 887 memset(&afu_pr_conf->afu_id.uuid.uuid_high, 0, sizeof(u64)); 888 } else { 889 acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port); 890 if (!acc) 891 return -ENODEV; 892 893 ret = opae_acc_get_uuid(acc, &uuid); 894 if (ret) 895 return ret; 896 897 rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, 898 sizeof(u64)); 899 rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, 900 sizeof(u64)); 901 902 IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", 903 __func__, 904 (unsigned long)afu_pr_conf->afu_id.uuid.uuid_low, 905 (unsigned long)afu_pr_conf->afu_id.uuid.uuid_high); 906 } 907 return 0; 908 } 909 910 static int 911 ifpga_rawdev_get_attr(struct rte_rawdev *dev, 912 const char *attr_name, uint64_t *attr_value) 913 { 914 struct opae_adapter *adapter; 915 struct opae_manager *mgr; 916 struct opae_retimer_info opae_rtm_info; 917 struct opae_retimer_status opae_rtm_status; 918 struct opae_eth_group_info opae_eth_grp_info; 919 struct opae_eth_group_region_info opae_eth_grp_reg_info; 920 int eth_group_num = 0; 921 uint64_t port_link_bitmap = 0, port_link_bit; 922 uint32_t i, j, p, q; 923 924 #define MAX_PORT_PER_RETIMER 4 925 926 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 927 928 if (!dev || !attr_name || !attr_value) { 929 IFPGA_RAWDEV_PMD_ERR("Invalid arguments for getting attributes"); 930 return -1; 931 } 932 933 adapter = ifpga_rawdev_get_priv(dev); 934 if (!adapter) { 935 IFPGA_RAWDEV_PMD_ERR("Adapter of dev %s is NULL", dev->name); 936 return -1; 937 } 938 939 mgr = opae_adapter_get_mgr(adapter); 940 if (!mgr) { 941 IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL"); 942 return -1; 943 } 944 945 /* currently, eth_group_num is always 2 */ 946 eth_group_num = opae_manager_get_eth_group_nums(mgr); 947 if (eth_group_num < 0) 948 return -1; 949 950 if (!strcmp(attr_name, "LineSideBaseMAC")) { 951 /* Currently FPGA not implement, so just set all zeros*/ 952 *attr_value = (uint64_t)0; 953 return 0; 954 } 955 if (!strcmp(attr_name, "LineSideMACType")) { 956 /* eth_group 0 on FPGA connect to LineSide */ 957 if (opae_manager_get_eth_group_info(mgr, 0, 958 &opae_eth_grp_info)) 959 return -1; 960 switch (opae_eth_grp_info.speed) { 961 case ETH_SPEED_10G: 962 *attr_value = 963 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI); 964 break; 965 case ETH_SPEED_25G: 966 *attr_value = 967 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI); 968 break; 969 default: 970 *attr_value = 971 (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_UNKNOWN); 972 break; 973 } 974 return 0; 975 } 976 if (!strcmp(attr_name, "LineSideLinkSpeed")) { 977 if (opae_manager_get_retimer_status(mgr, &opae_rtm_status)) 978 return -1; 979 switch (opae_rtm_status.speed) { 980 case MXD_1GB: 981 *attr_value = 982 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 983 break; 984 case MXD_2_5GB: 985 *attr_value = 986 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 987 break; 988 case MXD_5GB: 989 *attr_value = 990 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 991 break; 992 case MXD_10GB: 993 *attr_value = 994 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_10GB); 995 break; 996 case MXD_25GB: 997 *attr_value = 998 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_25GB); 999 break; 1000 case MXD_40GB: 1001 *attr_value = 1002 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_40GB); 1003 break; 1004 case MXD_100GB: 1005 *attr_value = 1006 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1007 break; 1008 case MXD_SPEED_UNKNOWN: 1009 *attr_value = 1010 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1011 break; 1012 default: 1013 *attr_value = 1014 (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1015 break; 1016 } 1017 return 0; 1018 } 1019 if (!strcmp(attr_name, "LineSideLinkRetimerNum")) { 1020 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1021 return -1; 1022 *attr_value = (uint64_t)(opae_rtm_info.nums_retimer); 1023 return 0; 1024 } 1025 if (!strcmp(attr_name, "LineSideLinkPortNum")) { 1026 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1027 return -1; 1028 uint64_t tmp = (uint64_t)opae_rtm_info.ports_per_retimer * 1029 (uint64_t)opae_rtm_info.nums_retimer; 1030 *attr_value = tmp; 1031 return 0; 1032 } 1033 if (!strcmp(attr_name, "LineSideLinkStatus")) { 1034 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1035 return -1; 1036 if (opae_manager_get_retimer_status(mgr, &opae_rtm_status)) 1037 return -1; 1038 (*attr_value) = 0; 1039 q = 0; 1040 port_link_bitmap = (uint64_t)(opae_rtm_status.line_link_bitmap); 1041 for (i = 0; i < opae_rtm_info.nums_retimer; i++) { 1042 p = i * MAX_PORT_PER_RETIMER; 1043 for (j = 0; j < opae_rtm_info.ports_per_retimer; j++) { 1044 port_link_bit = 0; 1045 IFPGA_BIT_SET(port_link_bit, (p+j)); 1046 port_link_bit &= port_link_bitmap; 1047 if (port_link_bit) 1048 IFPGA_BIT_SET((*attr_value), q); 1049 q++; 1050 } 1051 } 1052 return 0; 1053 } 1054 if (!strcmp(attr_name, "LineSideBARIndex")) { 1055 /* eth_group 0 on FPGA connect to LineSide */ 1056 if (opae_manager_get_eth_group_region_info(mgr, 0, 1057 &opae_eth_grp_reg_info)) 1058 return -1; 1059 *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx; 1060 return 0; 1061 } 1062 if (!strcmp(attr_name, "NICSideMACType")) { 1063 /* eth_group 1 on FPGA connect to NicSide */ 1064 if (opae_manager_get_eth_group_info(mgr, 1, 1065 &opae_eth_grp_info)) 1066 return -1; 1067 *attr_value = (uint64_t)(opae_eth_grp_info.speed); 1068 return 0; 1069 } 1070 if (!strcmp(attr_name, "NICSideLinkSpeed")) { 1071 /* eth_group 1 on FPGA connect to NicSide */ 1072 if (opae_manager_get_eth_group_info(mgr, 1, 1073 &opae_eth_grp_info)) 1074 return -1; 1075 *attr_value = (uint64_t)(opae_eth_grp_info.speed); 1076 return 0; 1077 } 1078 if (!strcmp(attr_name, "NICSideLinkPortNum")) { 1079 if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1080 return -1; 1081 uint64_t tmp = (uint64_t)opae_rtm_info.nums_fvl * 1082 (uint64_t)opae_rtm_info.ports_per_fvl; 1083 *attr_value = tmp; 1084 return 0; 1085 } 1086 if (!strcmp(attr_name, "NICSideLinkStatus")) 1087 return 0; 1088 if (!strcmp(attr_name, "NICSideBARIndex")) { 1089 /* eth_group 1 on FPGA connect to NicSide */ 1090 if (opae_manager_get_eth_group_region_info(mgr, 1, 1091 &opae_eth_grp_reg_info)) 1092 return -1; 1093 *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx; 1094 return 0; 1095 } 1096 1097 IFPGA_RAWDEV_PMD_ERR("%s not support", attr_name); 1098 return -1; 1099 } 1100 1101 static const struct rte_rawdev_ops ifpga_rawdev_ops = { 1102 .dev_info_get = ifpga_rawdev_info_get, 1103 .dev_configure = ifpga_rawdev_configure, 1104 .dev_start = ifpga_rawdev_start, 1105 .dev_stop = ifpga_rawdev_stop, 1106 .dev_close = ifpga_rawdev_close, 1107 .dev_reset = ifpga_rawdev_reset, 1108 1109 .queue_def_conf = NULL, 1110 .queue_setup = NULL, 1111 .queue_release = NULL, 1112 1113 .attr_get = ifpga_rawdev_get_attr, 1114 .attr_set = NULL, 1115 1116 .enqueue_bufs = NULL, 1117 .dequeue_bufs = NULL, 1118 1119 .dump = NULL, 1120 1121 .xstats_get = NULL, 1122 .xstats_get_names = NULL, 1123 .xstats_get_by_name = NULL, 1124 .xstats_reset = NULL, 1125 1126 .firmware_status_get = NULL, 1127 .firmware_version_get = NULL, 1128 .firmware_load = ifpga_rawdev_pr, 1129 .firmware_unload = NULL, 1130 1131 .dev_selftest = NULL, 1132 }; 1133 1134 static int 1135 ifpga_get_fme_error_prop(struct opae_manager *mgr, 1136 u64 prop_id, u64 *val) 1137 { 1138 struct feature_prop prop; 1139 1140 prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR; 1141 prop.prop_id = prop_id; 1142 1143 if (opae_manager_ifpga_get_prop(mgr, &prop)) 1144 return -EINVAL; 1145 1146 *val = prop.data; 1147 1148 return 0; 1149 } 1150 1151 static int 1152 ifpga_set_fme_error_prop(struct opae_manager *mgr, 1153 u64 prop_id, u64 val) 1154 { 1155 struct feature_prop prop; 1156 1157 prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR; 1158 prop.prop_id = prop_id; 1159 1160 prop.data = val; 1161 1162 if (opae_manager_ifpga_set_prop(mgr, &prop)) 1163 return -EINVAL; 1164 1165 return 0; 1166 } 1167 1168 static int 1169 fme_err_read_seu_emr(struct opae_manager *mgr) 1170 { 1171 u64 val; 1172 int ret; 1173 1174 ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val); 1175 if (ret) 1176 return -EINVAL; 1177 1178 IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%" PRIx64 "\n", val); 1179 1180 ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val); 1181 if (ret) 1182 return -EINVAL; 1183 1184 IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%" PRIx64 "\n", val); 1185 1186 return 0; 1187 } 1188 1189 static int fme_clear_warning_intr(struct opae_manager *mgr) 1190 { 1191 u64 val; 1192 1193 if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0)) 1194 return -EINVAL; 1195 1196 if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val)) 1197 return -EINVAL; 1198 if ((val & 0x40) != 0) 1199 IFPGA_RAWDEV_PMD_INFO("clean not done\n"); 1200 1201 return 0; 1202 } 1203 1204 static int fme_clean_fme_error(struct opae_manager *mgr) 1205 { 1206 u64 val; 1207 1208 if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val)) 1209 return -EINVAL; 1210 1211 IFPGA_RAWDEV_PMD_DEBUG("before clean 0x%" PRIx64 "\n", val); 1212 1213 ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_CLEAR, val); 1214 1215 if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val)) 1216 return -EINVAL; 1217 1218 IFPGA_RAWDEV_PMD_DEBUG("after clean 0x%" PRIx64 "\n", val); 1219 1220 return 0; 1221 } 1222 1223 static int 1224 fme_err_handle_error0(struct opae_manager *mgr) 1225 { 1226 struct feature_fme_error0 fme_error0; 1227 u64 val; 1228 1229 if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val)) 1230 return -EINVAL; 1231 1232 if (fme_clean_fme_error(mgr)) 1233 return -EINVAL; 1234 1235 fme_error0.csr = val; 1236 1237 if (fme_error0.fabric_err) 1238 IFPGA_RAWDEV_PMD_ERR("Fabric error\n"); 1239 else if (fme_error0.fabfifo_overflow) 1240 IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n"); 1241 else if (fme_error0.afu_acc_mode_err) 1242 IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n"); 1243 else if (fme_error0.pcie0cdc_parity_err) 1244 IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n"); 1245 else if (fme_error0.cvlcdc_parity_err) 1246 IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n"); 1247 else if (fme_error0.fpgaseuerr) 1248 fme_err_read_seu_emr(mgr); 1249 1250 /* clean the errors */ 1251 if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val)) 1252 return -EINVAL; 1253 1254 return 0; 1255 } 1256 1257 static int 1258 fme_err_handle_catfatal_error(struct opae_manager *mgr) 1259 { 1260 struct feature_fme_ras_catfaterror fme_catfatal; 1261 u64 val; 1262 1263 if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val)) 1264 return -EINVAL; 1265 1266 fme_catfatal.csr = val; 1267 1268 if (fme_catfatal.cci_fatal_err) 1269 IFPGA_RAWDEV_PMD_ERR("CCI error detected\n"); 1270 else if (fme_catfatal.fabric_fatal_err) 1271 IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n"); 1272 else if (fme_catfatal.pcie_poison_err) 1273 IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n"); 1274 else if (fme_catfatal.inject_fata_err) 1275 IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n"); 1276 else if (fme_catfatal.crc_catast_err) 1277 IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n"); 1278 else if (fme_catfatal.injected_catast_err) 1279 IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n"); 1280 else if (fme_catfatal.bmc_seu_catast_err) 1281 fme_err_read_seu_emr(mgr); 1282 1283 return 0; 1284 } 1285 1286 static int 1287 fme_err_handle_nonfaterror(struct opae_manager *mgr) 1288 { 1289 struct feature_fme_ras_nonfaterror nonfaterr; 1290 u64 val; 1291 1292 if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val)) 1293 return -EINVAL; 1294 1295 nonfaterr.csr = val; 1296 1297 if (nonfaterr.temp_thresh_ap1) 1298 IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n"); 1299 else if (nonfaterr.temp_thresh_ap2) 1300 IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n"); 1301 else if (nonfaterr.pcie_error) 1302 IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n"); 1303 else if (nonfaterr.portfatal_error) 1304 IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n"); 1305 else if (nonfaterr.proc_hot) 1306 IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n"); 1307 else if (nonfaterr.afu_acc_mode_err) 1308 IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n"); 1309 else if (nonfaterr.injected_nonfata_err) { 1310 IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n"); 1311 fme_clear_warning_intr(mgr); 1312 } else if (nonfaterr.temp_thresh_AP6) 1313 IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n"); 1314 else if (nonfaterr.power_thresh_AP1) 1315 IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n"); 1316 else if (nonfaterr.power_thresh_AP2) 1317 IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n"); 1318 else if (nonfaterr.mbp_err) 1319 IFPGA_RAWDEV_PMD_INFO("an MBP event\n"); 1320 1321 return 0; 1322 } 1323 1324 static void 1325 fme_interrupt_handler(void *param) 1326 { 1327 struct opae_manager *mgr = (struct opae_manager *)param; 1328 1329 IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__); 1330 1331 fme_err_handle_error0(mgr); 1332 fme_err_handle_nonfaterror(mgr); 1333 fme_err_handle_catfatal_error(mgr); 1334 } 1335 1336 int 1337 ifpga_unregister_msix_irq(enum ifpga_irq_type type, 1338 int vec_start, rte_intr_callback_fn handler, void *arg) 1339 { 1340 struct rte_intr_handle intr_handle; 1341 1342 if (type == IFPGA_FME_IRQ) 1343 intr_handle = ifpga_irq_handle[0]; 1344 else if (type == IFPGA_AFU_IRQ) 1345 intr_handle = ifpga_irq_handle[vec_start + 1]; 1346 1347 rte_intr_efd_disable(&intr_handle); 1348 1349 return rte_intr_callback_unregister(&intr_handle, 1350 handler, arg); 1351 } 1352 1353 int 1354 ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, 1355 enum ifpga_irq_type type, int vec_start, int count, 1356 rte_intr_callback_fn handler, const char *name, 1357 void *arg) 1358 { 1359 int ret; 1360 struct rte_intr_handle intr_handle; 1361 struct opae_adapter *adapter; 1362 struct opae_manager *mgr; 1363 struct opae_accelerator *acc; 1364 1365 adapter = ifpga_rawdev_get_priv(dev); 1366 if (!adapter) 1367 return -ENODEV; 1368 1369 mgr = opae_adapter_get_mgr(adapter); 1370 if (!mgr) 1371 return -ENODEV; 1372 1373 if (type == IFPGA_FME_IRQ) { 1374 intr_handle = ifpga_irq_handle[0]; 1375 count = 1; 1376 } else if (type == IFPGA_AFU_IRQ) 1377 intr_handle = ifpga_irq_handle[vec_start + 1]; 1378 1379 intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX; 1380 1381 ret = rte_intr_efd_enable(&intr_handle, count); 1382 if (ret) 1383 return -ENODEV; 1384 1385 intr_handle.fd = intr_handle.efds[0]; 1386 1387 IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d\n", 1388 name, intr_handle.vfio_dev_fd, 1389 intr_handle.fd); 1390 1391 if (type == IFPGA_FME_IRQ) { 1392 struct fpga_fme_err_irq_set err_irq_set; 1393 err_irq_set.evtfd = intr_handle.efds[0]; 1394 1395 ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); 1396 if (ret) 1397 return -EINVAL; 1398 } else if (type == IFPGA_AFU_IRQ) { 1399 acc = opae_adapter_get_acc(adapter, port_id); 1400 if (!acc) 1401 return -EINVAL; 1402 1403 ret = opae_acc_set_irq(acc, vec_start, count, intr_handle.efds); 1404 if (ret) 1405 return -EINVAL; 1406 } 1407 1408 /* register interrupt handler using DPDK API */ 1409 ret = rte_intr_callback_register(&intr_handle, 1410 handler, (void *)arg); 1411 if (ret) 1412 return -EINVAL; 1413 1414 IFPGA_RAWDEV_PMD_INFO("success register %s interrupt\n", name); 1415 1416 return 0; 1417 } 1418 1419 static int 1420 ifpga_rawdev_create(struct rte_pci_device *pci_dev, 1421 int socket_id) 1422 { 1423 int ret = 0; 1424 struct rte_rawdev *rawdev = NULL; 1425 struct ifpga_rawdev *dev = NULL; 1426 struct opae_adapter *adapter = NULL; 1427 struct opae_manager *mgr = NULL; 1428 struct opae_adapter_data_pci *data = NULL; 1429 char name[RTE_RAWDEV_NAME_MAX_LEN]; 1430 int i; 1431 1432 if (!pci_dev) { 1433 IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); 1434 ret = -EINVAL; 1435 goto cleanup; 1436 } 1437 1438 memset(name, 0, sizeof(name)); 1439 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x", 1440 pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); 1441 1442 IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id()); 1443 1444 /* Allocate device structure */ 1445 rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct opae_adapter), 1446 socket_id); 1447 if (rawdev == NULL) { 1448 IFPGA_RAWDEV_PMD_ERR("Unable to allocate rawdevice"); 1449 ret = -EINVAL; 1450 goto cleanup; 1451 } 1452 1453 ipn3ke_bridge_func.get_ifpga_rawdev = ifpga_rawdev_get; 1454 ipn3ke_bridge_func.set_i40e_sw_dev = rte_pmd_i40e_set_switch_dev; 1455 1456 dev = ifpga_rawdev_allocate(rawdev); 1457 if (dev == NULL) { 1458 IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice"); 1459 ret = -EINVAL; 1460 goto cleanup; 1461 } 1462 dev->aer_enable = 0; 1463 1464 /* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */ 1465 data = opae_adapter_data_alloc(OPAE_FPGA_PCI); 1466 if (!data) { 1467 ret = -ENOMEM; 1468 goto cleanup; 1469 } 1470 1471 /* init opae_adapter_data_pci for device specific information */ 1472 for (i = 0; i < PCI_MAX_RESOURCE; i++) { 1473 data->region[i].phys_addr = pci_dev->mem_resource[i].phys_addr; 1474 data->region[i].len = pci_dev->mem_resource[i].len; 1475 data->region[i].addr = pci_dev->mem_resource[i].addr; 1476 } 1477 data->device_id = pci_dev->id.device_id; 1478 data->vendor_id = pci_dev->id.vendor_id; 1479 data->bus = pci_dev->addr.bus; 1480 data->devid = pci_dev->addr.devid; 1481 data->function = pci_dev->addr.function; 1482 data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd; 1483 1484 adapter = rawdev->dev_private; 1485 /* create a opae_adapter based on above device data */ 1486 ret = opae_adapter_init(adapter, pci_dev->device.name, data); 1487 if (ret) { 1488 ret = -ENOMEM; 1489 goto free_adapter_data; 1490 } 1491 1492 rawdev->dev_ops = &ifpga_rawdev_ops; 1493 rawdev->device = &pci_dev->device; 1494 rawdev->driver_name = pci_dev->driver->driver.name; 1495 1496 /* must enumerate the adapter before use it */ 1497 ret = opae_adapter_enumerate(adapter); 1498 if (ret) 1499 goto free_adapter_data; 1500 1501 /* get opae_manager to rawdev */ 1502 mgr = opae_adapter_get_mgr(adapter); 1503 if (mgr) { 1504 /* PF function */ 1505 IFPGA_RAWDEV_PMD_INFO("this is a PF function"); 1506 } 1507 1508 ret = ifpga_register_msix_irq(rawdev, 0, IFPGA_FME_IRQ, 0, 0, 1509 fme_interrupt_handler, "fme_irq", mgr); 1510 if (ret) 1511 goto free_adapter_data; 1512 1513 return ret; 1514 1515 free_adapter_data: 1516 if (data) 1517 opae_adapter_data_free(data); 1518 cleanup: 1519 if (rawdev) 1520 rte_rawdev_pmd_release(rawdev); 1521 1522 return ret; 1523 } 1524 1525 static int 1526 ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) 1527 { 1528 int ret; 1529 struct rte_rawdev *rawdev; 1530 char name[RTE_RAWDEV_NAME_MAX_LEN]; 1531 struct opae_adapter *adapter; 1532 struct opae_manager *mgr; 1533 1534 if (!pci_dev) { 1535 IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); 1536 ret = -EINVAL; 1537 return ret; 1538 } 1539 1540 memset(name, 0, sizeof(name)); 1541 snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x", 1542 pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); 1543 1544 IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d", 1545 name, rte_socket_id()); 1546 1547 rawdev = rte_rawdev_pmd_get_named_dev(name); 1548 if (!rawdev) { 1549 IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); 1550 return -EINVAL; 1551 } 1552 1553 adapter = ifpga_rawdev_get_priv(rawdev); 1554 if (!adapter) 1555 return -ENODEV; 1556 1557 mgr = opae_adapter_get_mgr(adapter); 1558 if (!mgr) 1559 return -ENODEV; 1560 1561 if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, 1562 fme_interrupt_handler, mgr)) 1563 return -EINVAL; 1564 1565 opae_adapter_data_free(adapter->data); 1566 opae_adapter_free(adapter); 1567 1568 /* rte_rawdev_close is called by pmd_release */ 1569 ret = rte_rawdev_pmd_release(rawdev); 1570 if (ret) 1571 IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed"); 1572 1573 return ret; 1574 } 1575 1576 static int 1577 ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 1578 struct rte_pci_device *pci_dev) 1579 { 1580 IFPGA_RAWDEV_PMD_FUNC_TRACE(); 1581 return ifpga_rawdev_create(pci_dev, rte_socket_id()); 1582 } 1583 1584 static int 1585 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev) 1586 { 1587 ifpga_monitor_stop_func(); 1588 return ifpga_rawdev_destroy(pci_dev); 1589 } 1590 1591 static struct rte_pci_driver rte_ifpga_rawdev_pmd = { 1592 .id_table = pci_ifpga_map, 1593 .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 1594 .probe = ifpga_rawdev_pci_probe, 1595 .remove = ifpga_rawdev_pci_remove, 1596 }; 1597 1598 RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); 1599 RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); 1600 RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci"); 1601 RTE_LOG_REGISTER(ifpga_rawdev_logtype, driver.raw.init, NOTICE); 1602 1603 static const char * const valid_args[] = { 1604 #define IFPGA_ARG_NAME "ifpga" 1605 IFPGA_ARG_NAME, 1606 #define IFPGA_ARG_PORT "port" 1607 IFPGA_ARG_PORT, 1608 #define IFPGA_AFU_BTS "afu_bts" 1609 IFPGA_AFU_BTS, 1610 NULL 1611 }; 1612 1613 static int ifpga_rawdev_get_string_arg(const char *key __rte_unused, 1614 const char *value, void *extra_args) 1615 { 1616 int size; 1617 if (!value || !extra_args) 1618 return -EINVAL; 1619 1620 size = strlen(value) + 1; 1621 *(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE); 1622 if (!*(char **)extra_args) 1623 return -ENOMEM; 1624 1625 strlcpy(*(char **)extra_args, value, size); 1626 1627 return 0; 1628 } 1629 static int 1630 ifpga_cfg_probe(struct rte_vdev_device *dev) 1631 { 1632 struct rte_devargs *devargs; 1633 struct rte_kvargs *kvlist = NULL; 1634 struct rte_rawdev *rawdev = NULL; 1635 struct ifpga_rawdev *ifpga_dev; 1636 int port; 1637 char *name = NULL; 1638 const char *bdf; 1639 char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; 1640 int ret = -1; 1641 1642 devargs = dev->device.devargs; 1643 1644 kvlist = rte_kvargs_parse(devargs->args, valid_args); 1645 if (!kvlist) { 1646 IFPGA_RAWDEV_PMD_LOG(ERR, "error when parsing param"); 1647 goto end; 1648 } 1649 1650 if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) { 1651 if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME, 1652 &ifpga_rawdev_get_string_arg, 1653 &name) < 0) { 1654 IFPGA_RAWDEV_PMD_ERR("error to parse %s", 1655 IFPGA_ARG_NAME); 1656 goto end; 1657 } 1658 } else { 1659 IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", 1660 IFPGA_ARG_NAME); 1661 goto end; 1662 } 1663 1664 if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) { 1665 if (rte_kvargs_process(kvlist, 1666 IFPGA_ARG_PORT, 1667 &rte_ifpga_get_integer32_arg, 1668 &port) < 0) { 1669 IFPGA_RAWDEV_PMD_ERR("error to parse %s", 1670 IFPGA_ARG_PORT); 1671 goto end; 1672 } 1673 } else { 1674 IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", 1675 IFPGA_ARG_PORT); 1676 goto end; 1677 } 1678 1679 memset(dev_name, 0, sizeof(dev_name)); 1680 snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name); 1681 rawdev = rte_rawdev_pmd_get_named_dev(dev_name); 1682 if (!rawdev) 1683 goto end; 1684 ifpga_dev = ifpga_rawdev_get(rawdev); 1685 if (!ifpga_dev) 1686 goto end; 1687 bdf = name; 1688 ifpga_rawdev_fill_info(ifpga_dev, bdf); 1689 1690 ifpga_monitor_start_func(); 1691 1692 memset(dev_name, 0, sizeof(dev_name)); 1693 snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", 1694 port, name); 1695 1696 ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME), 1697 dev_name, devargs->args); 1698 end: 1699 if (kvlist) 1700 rte_kvargs_free(kvlist); 1701 if (name) 1702 free(name); 1703 1704 return ret; 1705 } 1706 1707 static int 1708 ifpga_cfg_remove(struct rte_vdev_device *vdev) 1709 { 1710 IFPGA_RAWDEV_PMD_INFO("Remove ifpga_cfg %p", 1711 vdev); 1712 1713 return 0; 1714 } 1715 1716 static struct rte_vdev_driver ifpga_cfg_driver = { 1717 .probe = ifpga_cfg_probe, 1718 .remove = ifpga_cfg_remove, 1719 }; 1720 1721 RTE_PMD_REGISTER_VDEV(ifpga_rawdev_cfg, ifpga_cfg_driver); 1722 RTE_PMD_REGISTER_ALIAS(ifpga_rawdev_cfg, ifpga_cfg); 1723 RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg, 1724 "ifpga=<string> " 1725 "port=<int> " 1726 "afu_bts=<path>"); 1727