1473c88f9SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2473c88f9SBruce Richardson * Copyright(c) 2010-2018 Intel Corporation 3473c88f9SBruce Richardson */ 4473c88f9SBruce Richardson 5473c88f9SBruce Richardson #include <string.h> 6473c88f9SBruce Richardson #include <dirent.h> 7473c88f9SBruce Richardson #include <sys/stat.h> 8473c88f9SBruce Richardson #include <unistd.h> 9473c88f9SBruce Richardson #include <sys/types.h> 10473c88f9SBruce Richardson #include <fcntl.h> 119c006c45SRosen Xu #include <sys/ioctl.h> 129c006c45SRosen Xu #include <sys/epoll.h> 139c1b4ae5SDavid Marchand 14473c88f9SBruce Richardson #include <rte_log.h> 15473c88f9SBruce Richardson #include <rte_malloc.h> 16473c88f9SBruce Richardson #include <rte_devargs.h> 17473c88f9SBruce Richardson #include <rte_memcpy.h> 18473c88f9SBruce Richardson #include <rte_pci.h> 191f37cb2bSDavid Marchand #include <bus_pci_driver.h> 20473c88f9SBruce Richardson #include <rte_kvargs.h> 21473c88f9SBruce Richardson #include <rte_alarm.h> 229c006c45SRosen Xu #include <rte_interrupts.h> 23473c88f9SBruce Richardson #include <rte_errno.h> 24473c88f9SBruce Richardson #include <rte_per_lcore.h> 25473c88f9SBruce Richardson #include <rte_memory.h> 26473c88f9SBruce Richardson #include <rte_memzone.h> 27473c88f9SBruce Richardson #include <rte_eal.h> 28473c88f9SBruce Richardson #include <rte_common.h> 294851ef2bSDavid Marchand #include <bus_vdev_driver.h> 309c006c45SRosen Xu #include <rte_string_fns.h> 318418c928SRosen Xu #include <rte_pmd_i40e.h> 32b412ffa8SWei Huang #include <bus_driver.h> 33473c88f9SBruce Richardson 34473c88f9SBruce Richardson #include "base/opae_hw_api.h" 3582ce05d8SRosen Xu #include "base/opae_ifpga_hw_api.h" 3682ce05d8SRosen Xu #include "base/ifpga_api.h" 37473c88f9SBruce Richardson #include "rte_rawdev.h" 38473c88f9SBruce Richardson #include "rte_rawdev_pmd.h" 39925c074eSDavid Marchand #include "bus_ifpga_driver.h" 40473c88f9SBruce Richardson #include "ifpga_common.h" 41473c88f9SBruce Richardson #include "ifpga_logs.h" 42473c88f9SBruce Richardson #include "ifpga_rawdev.h" 43473c88f9SBruce Richardson #include "ipn3ke_rawdev_api.h" 44473c88f9SBruce Richardson 45473c88f9SBruce Richardson #define PCI_VENDOR_ID_INTEL 0x8086 46473c88f9SBruce Richardson /* PCI Device ID */ 47473c88f9SBruce Richardson #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD 48473c88f9SBruce Richardson #define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0 49473c88f9SBruce Richardson #define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4 50473c88f9SBruce Richardson #define PCIE_DEVICE_ID_PAC_N3000 0x0B30 51673c897fSWei Huang #define PCIE_DEVICE_ID_PAC_N6000 0xBCCE 52473c88f9SBruce Richardson /* VF Device */ 53473c88f9SBruce Richardson #define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF 54473c88f9SBruce Richardson #define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1 55473c88f9SBruce Richardson #define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5 56473c88f9SBruce Richardson #define PCIE_DEVICE_ID_VF_PAC_N3000 0x0B31 57673c897fSWei Huang #define PCIE_DEVICE_ID_VF_PAC_N6000 0xBCCF 58473c88f9SBruce Richardson #define RTE_MAX_RAW_DEVICE 10 59473c88f9SBruce Richardson 60473c88f9SBruce Richardson static const struct rte_pci_id pci_ifpga_map[] = { 61473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X) }, 62473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_5_X) }, 63473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_6_X) }, 64473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X) }, 65473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X) }, 66473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X) }, 67473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PAC_N3000),}, 68473c88f9SBruce Richardson { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_PAC_N3000),}, 69673c897fSWei Huang { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PAC_N6000),}, 70673c897fSWei Huang { RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_PAC_N6000),}, 71473c88f9SBruce Richardson { .vendor_id = 0, /* sentinel */ }, 72473c88f9SBruce Richardson }; 73473c88f9SBruce Richardson 749c006c45SRosen Xu static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM]; 759c006c45SRosen Xu 76e12a0166STyler Retzlaff static RTE_ATOMIC(int) ifpga_monitor_refcnt; 77a7ba40b2SThomas Monjalon static rte_thread_t ifpga_monitor_start_thread; 789c006c45SRosen Xu 799c006c45SRosen Xu static struct ifpga_rawdev * 809c006c45SRosen Xu ifpga_rawdev_allocate(struct rte_rawdev *rawdev); 819c006c45SRosen Xu static int set_surprise_link_check_aer( 829c006c45SRosen Xu struct ifpga_rawdev *ifpga_rdev, int force_disable); 839c006c45SRosen Xu static int ifpga_pci_find_next_ext_capability(unsigned int fd, 84e00d2b4cSManish Chopra int start, uint32_t cap); 85e00d2b4cSManish Chopra static int ifpga_pci_find_ext_capability(unsigned int fd, uint32_t cap); 8625456835SWei Huang static void fme_interrupt_handler(void *param); 879c006c45SRosen Xu 889c006c45SRosen Xu struct ifpga_rawdev * 899c006c45SRosen Xu ifpga_rawdev_get(const struct rte_rawdev *rawdev) 909c006c45SRosen Xu { 919c006c45SRosen Xu struct ifpga_rawdev *dev; 929c006c45SRosen Xu unsigned int i; 939c006c45SRosen Xu 949c006c45SRosen Xu if (rawdev == NULL) 959c006c45SRosen Xu return NULL; 969c006c45SRosen Xu 979c006c45SRosen Xu for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { 989c006c45SRosen Xu dev = &ifpga_rawdevices[i]; 999c006c45SRosen Xu if (dev->rawdev == rawdev) 1009c006c45SRosen Xu return dev; 1019c006c45SRosen Xu } 1029c006c45SRosen Xu 1039c006c45SRosen Xu return NULL; 1049c006c45SRosen Xu } 1059c006c45SRosen Xu 1069c006c45SRosen Xu static inline uint8_t 1079c006c45SRosen Xu ifpga_rawdev_find_free_device_index(void) 1089c006c45SRosen Xu { 1099c006c45SRosen Xu uint16_t dev_id; 1109c006c45SRosen Xu 1119c006c45SRosen Xu for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) { 1129c006c45SRosen Xu if (ifpga_rawdevices[dev_id].rawdev == NULL) 1139c006c45SRosen Xu return dev_id; 1149c006c45SRosen Xu } 1159c006c45SRosen Xu 1169c006c45SRosen Xu return IFPGA_RAWDEV_NUM; 1179c006c45SRosen Xu } 118673c897fSWei Huang 1199c006c45SRosen Xu static struct ifpga_rawdev * 1209c006c45SRosen Xu ifpga_rawdev_allocate(struct rte_rawdev *rawdev) 1219c006c45SRosen Xu { 1229c006c45SRosen Xu struct ifpga_rawdev *dev; 1239c006c45SRosen Xu uint16_t dev_id; 12420659eb3SWei Huang int i = 0; 1259c006c45SRosen Xu 1269c006c45SRosen Xu dev = ifpga_rawdev_get(rawdev); 1279c006c45SRosen Xu if (dev != NULL) { 1289c006c45SRosen Xu IFPGA_RAWDEV_PMD_ERR("Event device already allocated!"); 1299c006c45SRosen Xu return NULL; 1309c006c45SRosen Xu } 1319c006c45SRosen Xu 1329c006c45SRosen Xu dev_id = ifpga_rawdev_find_free_device_index(); 1339c006c45SRosen Xu if (dev_id == IFPGA_RAWDEV_NUM) { 1349c006c45SRosen Xu IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices"); 1359c006c45SRosen Xu return NULL; 1369c006c45SRosen Xu } 1379c006c45SRosen Xu 1389c006c45SRosen Xu dev = &ifpga_rawdevices[dev_id]; 1399c006c45SRosen Xu dev->rawdev = rawdev; 1409c006c45SRosen Xu dev->dev_id = dev_id; 14120659eb3SWei Huang for (i = 0; i < IFPGA_MAX_IRQ; i++) 14220659eb3SWei Huang dev->intr_handle[i] = NULL; 1432479a1e9SWei Huang dev->poll_enabled = 0; 144ae835abaSWei Huang for (i = 0; i < IFPGA_MAX_VDEV; i++) 145ae835abaSWei Huang dev->vdev_name[i] = NULL; 1469c006c45SRosen Xu 1479c006c45SRosen Xu return dev; 1489c006c45SRosen Xu } 1499c006c45SRosen Xu 150e00d2b4cSManish Chopra static int 151e00d2b4cSManish Chopra ifpga_pci_find_next_ext_capability(unsigned int fd, int start, uint32_t cap) 1529c006c45SRosen Xu { 1539c006c45SRosen Xu uint32_t header; 1549c006c45SRosen Xu int ttl; 1559c006c45SRosen Xu int pos = RTE_PCI_CFG_SPACE_SIZE; 1569c006c45SRosen Xu int ret; 1579c006c45SRosen Xu 1589c006c45SRosen Xu /* minimum 8 bytes per capability */ 1599c006c45SRosen Xu ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8; 1609c006c45SRosen Xu 1619c006c45SRosen Xu if (start) 1629c006c45SRosen Xu pos = start; 1639c006c45SRosen Xu ret = pread(fd, &header, sizeof(header), pos); 1649c006c45SRosen Xu if (ret == -1) 1659c006c45SRosen Xu return -1; 1669c006c45SRosen Xu 1679c006c45SRosen Xu /* 1689c006c45SRosen Xu * If we have no capabilities, this is indicated by cap ID, 1699c006c45SRosen Xu * cap version and next pointer all being 0. 1709c006c45SRosen Xu */ 1719c006c45SRosen Xu if (header == 0) 1729c006c45SRosen Xu return 0; 1739c006c45SRosen Xu 1749c006c45SRosen Xu while (ttl-- > 0) { 1759c006c45SRosen Xu if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start) 1769c006c45SRosen Xu return pos; 1779c006c45SRosen Xu 1789c006c45SRosen Xu pos = RTE_PCI_EXT_CAP_NEXT(header); 1799c006c45SRosen Xu if (pos < RTE_PCI_CFG_SPACE_SIZE) 1809c006c45SRosen Xu break; 1819c006c45SRosen Xu ret = pread(fd, &header, sizeof(header), pos); 1829c006c45SRosen Xu if (ret == -1) 1839c006c45SRosen Xu return -1; 1849c006c45SRosen Xu } 1859c006c45SRosen Xu 1869c006c45SRosen Xu return 0; 1879c006c45SRosen Xu } 1889c006c45SRosen Xu 189e00d2b4cSManish Chopra static int 190e00d2b4cSManish Chopra ifpga_pci_find_ext_capability(unsigned int fd, uint32_t cap) 1919c006c45SRosen Xu { 1929c006c45SRosen Xu return ifpga_pci_find_next_ext_capability(fd, 0, cap); 1939c006c45SRosen Xu } 1949c006c45SRosen Xu 1959c006c45SRosen Xu static int ifpga_get_dev_vendor_id(const char *bdf, 1969c006c45SRosen Xu uint32_t *dev_id, uint32_t *vendor_id) 1979c006c45SRosen Xu { 1989c006c45SRosen Xu int fd; 1999c006c45SRosen Xu char path[1024]; 2009c006c45SRosen Xu int ret; 2019c006c45SRosen Xu uint32_t header; 2029c006c45SRosen Xu 2039c006c45SRosen Xu strlcpy(path, "/sys/bus/pci/devices/", sizeof(path)); 2049c006c45SRosen Xu strlcat(path, bdf, sizeof(path)); 2059c006c45SRosen Xu strlcat(path, "/config", sizeof(path)); 2069c006c45SRosen Xu fd = open(path, O_RDWR); 2079c006c45SRosen Xu if (fd < 0) 2089c006c45SRosen Xu return -1; 2099c006c45SRosen Xu ret = pread(fd, &header, sizeof(header), 0); 2109c006c45SRosen Xu if (ret == -1) { 2119c006c45SRosen Xu close(fd); 2129c006c45SRosen Xu return -1; 2139c006c45SRosen Xu } 2149c006c45SRosen Xu (*vendor_id) = header & 0xffff; 2159c006c45SRosen Xu (*dev_id) = (header >> 16) & 0xffff; 2169c006c45SRosen Xu close(fd); 2179c006c45SRosen Xu 2189c006c45SRosen Xu return 0; 2199c006c45SRosen Xu } 2202479a1e9SWei Huang 2212479a1e9SWei Huang static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev) 2229c006c45SRosen Xu { 2232479a1e9SWei Huang struct opae_adapter *adapter = NULL; 2242479a1e9SWei Huang char path[1024] = "/sys/bus/pci/devices/"; 2259c006c45SRosen Xu char link[1024], link1[1024]; 2269c006c45SRosen Xu char dir[1024] = "/sys/devices/"; 2279c006c45SRosen Xu char *c; 2289c006c45SRosen Xu int ret; 229aae56ac4SWei Huang char sub_brg_bdf[4][16] = {{0}}; 2309c006c45SRosen Xu int point; 2319c006c45SRosen Xu DIR *dp = NULL; 2329c006c45SRosen Xu struct dirent *entry; 2339c006c45SRosen Xu int i, j; 2349c006c45SRosen Xu 2359c006c45SRosen Xu unsigned int dom, bus, dev; 2369c006c45SRosen Xu int func; 237047c2540SWei Huang uint32_t dev_id = 0; 238047c2540SWei Huang uint32_t vendor_id = 0; 2399c006c45SRosen Xu 2402479a1e9SWei Huang adapter = ifpga_dev ? ifpga_rawdev_get_priv(ifpga_dev->rawdev) : NULL; 2412479a1e9SWei Huang if (!adapter) 2422479a1e9SWei Huang return -ENODEV; 2432479a1e9SWei Huang 2442479a1e9SWei Huang strlcat(path, adapter->name, sizeof(path)); 2459c006c45SRosen Xu memset(link, 0, sizeof(link)); 2469c006c45SRosen Xu memset(link1, 0, sizeof(link1)); 2479c006c45SRosen Xu ret = readlink(path, link, (sizeof(link)-1)); 2485a906909SWei Huang if ((ret < 0) || ((unsigned int)ret > (sizeof(link)-1))) 2499c006c45SRosen Xu return -1; 2505a906909SWei Huang link[ret] = 0; /* terminate string with null character */ 2519c006c45SRosen Xu strlcpy(link1, link, sizeof(link1)); 2529c006c45SRosen Xu memset(ifpga_dev->parent_bdf, 0, 16); 2539c006c45SRosen Xu point = strlen(link); 2549c006c45SRosen Xu if (point < 39) 2559c006c45SRosen Xu return -1; 2569c006c45SRosen Xu point -= 39; 2579c006c45SRosen Xu link[point] = 0; 2589c006c45SRosen Xu if (point < 12) 2599c006c45SRosen Xu return -1; 2609c006c45SRosen Xu point -= 12; 2619c006c45SRosen Xu rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12); 2629c006c45SRosen Xu 2639c006c45SRosen Xu point = strlen(link1); 2649c006c45SRosen Xu if (point < 26) 2659c006c45SRosen Xu return -1; 2669c006c45SRosen Xu point -= 26; 2679c006c45SRosen Xu link1[point] = 0; 2689c006c45SRosen Xu if (point < 12) 2699c006c45SRosen Xu return -1; 2709c006c45SRosen Xu point -= 12; 2719c006c45SRosen Xu c = strchr(link1, 'p'); 2729c006c45SRosen Xu if (!c) 2739c006c45SRosen Xu return -1; 2749c006c45SRosen Xu strlcat(dir, c, sizeof(dir)); 2759c006c45SRosen Xu 2769c006c45SRosen Xu /* scan folder */ 2779c006c45SRosen Xu dp = opendir(dir); 2789c006c45SRosen Xu if (dp == NULL) 2799c006c45SRosen Xu return -1; 2809c006c45SRosen Xu i = 0; 2819c006c45SRosen Xu while ((entry = readdir(dp)) != NULL) { 2829c006c45SRosen Xu if (i >= 4) 2839c006c45SRosen Xu break; 2849c006c45SRosen Xu if (entry->d_name[0] == '.') 2859c006c45SRosen Xu continue; 2869c006c45SRosen Xu if (strlen(entry->d_name) > 12) 2879c006c45SRosen Xu continue; 2889c006c45SRosen Xu if (sscanf(entry->d_name, "%x:%x:%x.%d", 2899c006c45SRosen Xu &dom, &bus, &dev, &func) < 4) 2909c006c45SRosen Xu continue; 2919c006c45SRosen Xu else { 2929c006c45SRosen Xu strlcpy(sub_brg_bdf[i], 2939c006c45SRosen Xu entry->d_name, 2949c006c45SRosen Xu sizeof(sub_brg_bdf[i])); 2959c006c45SRosen Xu i++; 2969c006c45SRosen Xu } 2979c006c45SRosen Xu } 2989c006c45SRosen Xu closedir(dp); 2999c006c45SRosen Xu 3009c006c45SRosen Xu /* get fpga and fvl */ 3019c006c45SRosen Xu j = 0; 3029c006c45SRosen Xu for (i = 0; i < 4; i++) { 3039c006c45SRosen Xu strlcpy(link, dir, sizeof(link)); 3049c006c45SRosen Xu strlcat(link, "/", sizeof(link)); 3059c006c45SRosen Xu strlcat(link, sub_brg_bdf[i], sizeof(link)); 3069c006c45SRosen Xu dp = opendir(link); 3079c006c45SRosen Xu if (dp == NULL) 3089c006c45SRosen Xu return -1; 3099c006c45SRosen Xu while ((entry = readdir(dp)) != NULL) { 3109c006c45SRosen Xu if (j >= 8) 3119c006c45SRosen Xu break; 3129c006c45SRosen Xu if (entry->d_name[0] == '.') 3139c006c45SRosen Xu continue; 3149c006c45SRosen Xu 3159c006c45SRosen Xu if (strlen(entry->d_name) > 12) 3169c006c45SRosen Xu continue; 3179c006c45SRosen Xu if (sscanf(entry->d_name, "%x:%x:%x.%d", 3189c006c45SRosen Xu &dom, &bus, &dev, &func) < 4) 3199c006c45SRosen Xu continue; 3209c006c45SRosen Xu else { 3219c006c45SRosen Xu if (ifpga_get_dev_vendor_id(entry->d_name, 3229c006c45SRosen Xu &dev_id, &vendor_id)) 3239c006c45SRosen Xu continue; 3249c006c45SRosen Xu if (vendor_id == 0x8086 && 3259c006c45SRosen Xu (dev_id == 0x0CF8 || 3269c006c45SRosen Xu dev_id == 0x0D58 || 3279c006c45SRosen Xu dev_id == 0x1580)) { 3289c006c45SRosen Xu strlcpy(ifpga_dev->fvl_bdf[j], 3299c006c45SRosen Xu entry->d_name, 3309c006c45SRosen Xu sizeof(ifpga_dev->fvl_bdf[j])); 3319c006c45SRosen Xu j++; 3329c006c45SRosen Xu } 3339c006c45SRosen Xu } 3349c006c45SRosen Xu } 3359c006c45SRosen Xu closedir(dp); 3369c006c45SRosen Xu } 3379c006c45SRosen Xu 3389c006c45SRosen Xu return 0; 3399c006c45SRosen Xu } 3409c006c45SRosen Xu 3419c006c45SRosen Xu #define HIGH_FATAL(_sens, value)\ 3429c006c45SRosen Xu (((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\ 3439c006c45SRosen Xu (value > (_sens)->high_fatal)) 3449c006c45SRosen Xu 3459c006c45SRosen Xu #define HIGH_WARN(_sens, value)\ 3469c006c45SRosen Xu (((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\ 3479c006c45SRosen Xu (value > (_sens)->high_warn)) 3489c006c45SRosen Xu 3499c006c45SRosen Xu #define LOW_FATAL(_sens, value)\ 3509c006c45SRosen Xu (((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\ 3519c006c45SRosen Xu (value > (_sens)->low_fatal)) 3529c006c45SRosen Xu 3539c006c45SRosen Xu #define LOW_WARN(_sens, value)\ 3549c006c45SRosen Xu (((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\ 3559c006c45SRosen Xu (value > (_sens)->low_warn)) 3569c006c45SRosen Xu 3579c006c45SRosen Xu #define AUX_VOLTAGE_WARN 11400 3589c006c45SRosen Xu 3599c006c45SRosen Xu static int 3609c006c45SRosen Xu ifpga_monitor_sensor(struct rte_rawdev *raw_dev, 3619c006c45SRosen Xu bool *gsd_start) 3629c006c45SRosen Xu { 3639c006c45SRosen Xu struct opae_adapter *adapter; 3649c006c45SRosen Xu struct opae_manager *mgr; 3659c006c45SRosen Xu struct opae_sensor_info *sensor; 3669c006c45SRosen Xu unsigned int value; 3679c006c45SRosen Xu int ret; 3689c006c45SRosen Xu 3699c006c45SRosen Xu adapter = ifpga_rawdev_get_priv(raw_dev); 3709c006c45SRosen Xu if (!adapter) 3719c006c45SRosen Xu return -ENODEV; 3729c006c45SRosen Xu 3739c006c45SRosen Xu mgr = opae_adapter_get_mgr(adapter); 374673c897fSWei Huang if (!mgr || !mgr->sensor_list) 3759c006c45SRosen Xu return -ENODEV; 3769c006c45SRosen Xu 3774a19f891STianfei Zhang opae_mgr_for_each_sensor(mgr, sensor) { 3789c006c45SRosen Xu if (!(sensor->flags & OPAE_SENSOR_VALID)) 3799c006c45SRosen Xu goto fail; 3809c006c45SRosen Xu 3819c006c45SRosen Xu ret = opae_mgr_get_sensor_value(mgr, sensor, &value); 3829c006c45SRosen Xu if (ret) 3839c006c45SRosen Xu goto fail; 3849c006c45SRosen Xu 3859c006c45SRosen Xu if (value == 0xdeadbeef) { 386f665790aSDavid Marchand IFPGA_RAWDEV_PMD_DEBUG("dev_id %d sensor %s value %x", 3874a19f891STianfei Zhang raw_dev->dev_id, sensor->name, value); 3889c006c45SRosen Xu continue; 3899c006c45SRosen Xu } 3909c006c45SRosen Xu 3919c006c45SRosen Xu /* monitor temperature sensors */ 3929c006c45SRosen Xu if (!strcmp(sensor->name, "Board Temperature") || 3939c006c45SRosen Xu !strcmp(sensor->name, "FPGA Die Temperature")) { 394f665790aSDavid Marchand IFPGA_RAWDEV_PMD_DEBUG("read sensor %s %d %d %d", 3959c006c45SRosen Xu sensor->name, value, sensor->high_warn, 3969c006c45SRosen Xu sensor->high_fatal); 3979c006c45SRosen Xu 3989c006c45SRosen Xu if (HIGH_WARN(sensor, value) || 3999c006c45SRosen Xu LOW_WARN(sensor, value)) { 400f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("%s reach threshold %d", 4019c006c45SRosen Xu sensor->name, value); 4029c006c45SRosen Xu *gsd_start = true; 4039c006c45SRosen Xu break; 4049c006c45SRosen Xu } 4059c006c45SRosen Xu } 4069c006c45SRosen Xu 4079c006c45SRosen Xu /* monitor 12V AUX sensor */ 4089c006c45SRosen Xu if (!strcmp(sensor->name, "12V AUX Voltage")) { 4099c006c45SRosen Xu if (value < AUX_VOLTAGE_WARN) { 4104a19f891STianfei Zhang IFPGA_RAWDEV_PMD_INFO( 411f665790aSDavid Marchand "%s reach threshold %d mV", 4129c006c45SRosen Xu sensor->name, value); 4139c006c45SRosen Xu *gsd_start = true; 4149c006c45SRosen Xu break; 4159c006c45SRosen Xu } 4169c006c45SRosen Xu } 4179c006c45SRosen Xu } 4189c006c45SRosen Xu 4199c006c45SRosen Xu return 0; 4209c006c45SRosen Xu fail: 4219c006c45SRosen Xu return -EFAULT; 4229c006c45SRosen Xu } 4239c006c45SRosen Xu 4249c006c45SRosen Xu static int set_surprise_link_check_aer( 4259c006c45SRosen Xu struct ifpga_rawdev *ifpga_rdev, int force_disable) 4269c006c45SRosen Xu { 4279c006c45SRosen Xu struct rte_rawdev *rdev; 4289c006c45SRosen Xu int fd = -1; 4299c006c45SRosen Xu char path[1024]; 4309c006c45SRosen Xu int pos; 4319c006c45SRosen Xu int ret; 4329c006c45SRosen Xu uint32_t data; 4339c006c45SRosen Xu bool enable = 0; 4349c006c45SRosen Xu uint32_t aer_new0, aer_new1; 4359c006c45SRosen Xu 4362479a1e9SWei Huang if (!ifpga_rdev || !ifpga_rdev->rawdev) { 4379c006c45SRosen Xu printf("\n device does not exist\n"); 4389c006c45SRosen Xu return -EFAULT; 4399c006c45SRosen Xu } 4409c006c45SRosen Xu 4419c006c45SRosen Xu rdev = ifpga_rdev->rawdev; 4429c006c45SRosen Xu if (ifpga_rdev->aer_enable) 4439c006c45SRosen Xu return -EFAULT; 4449c006c45SRosen Xu if (ifpga_monitor_sensor(rdev, &enable)) 4459c006c45SRosen Xu return -EFAULT; 4469c006c45SRosen Xu if (enable || force_disable) { 447f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown"); 4489c006c45SRosen Xu ifpga_rdev->aer_enable = 1; 4499c006c45SRosen Xu /* get bridge fd */ 4509c006c45SRosen Xu strlcpy(path, "/sys/bus/pci/devices/", sizeof(path)); 4519c006c45SRosen Xu strlcat(path, ifpga_rdev->parent_bdf, sizeof(path)); 4529c006c45SRosen Xu strlcat(path, "/config", sizeof(path)); 4539c006c45SRosen Xu fd = open(path, O_RDWR); 4549c006c45SRosen Xu if (fd < 0) 4559c006c45SRosen Xu goto end; 4569c006c45SRosen Xu pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR); 4579c006c45SRosen Xu if (!pos) 4589c006c45SRosen Xu goto end; 4597be78d02SJosh Soref /* save previous ECAP_AER+0x08 */ 4609c006c45SRosen Xu ret = pread(fd, &data, sizeof(data), pos+0x08); 4619c006c45SRosen Xu if (ret == -1) 4629c006c45SRosen Xu goto end; 4639c006c45SRosen Xu ifpga_rdev->aer_old[0] = data; 4647be78d02SJosh Soref /* save previous ECAP_AER+0x14 */ 4659c006c45SRosen Xu ret = pread(fd, &data, sizeof(data), pos+0x14); 4669c006c45SRosen Xu if (ret == -1) 4679c006c45SRosen Xu goto end; 4689c006c45SRosen Xu ifpga_rdev->aer_old[1] = data; 4699c006c45SRosen Xu 4709c006c45SRosen Xu /* set ECAP_AER+0x08 to 0xFFFFFFFF */ 4719c006c45SRosen Xu data = 0xffffffff; 4729c006c45SRosen Xu ret = pwrite(fd, &data, 4, pos+0x08); 4739c006c45SRosen Xu if (ret == -1) 4749c006c45SRosen Xu goto end; 4759c006c45SRosen Xu /* set ECAP_AER+0x14 to 0xFFFFFFFF */ 4769c006c45SRosen Xu ret = pwrite(fd, &data, 4, pos+0x14); 4779c006c45SRosen Xu if (ret == -1) 4789c006c45SRosen Xu goto end; 4799c006c45SRosen Xu 4809c006c45SRosen Xu /* read current ECAP_AER+0x08 */ 4819c006c45SRosen Xu ret = pread(fd, &data, sizeof(data), pos+0x08); 4829c006c45SRosen Xu if (ret == -1) 4839c006c45SRosen Xu goto end; 4849c006c45SRosen Xu aer_new0 = data; 4859c006c45SRosen Xu /* read current ECAP_AER+0x14 */ 4869c006c45SRosen Xu ret = pread(fd, &data, sizeof(data), pos+0x14); 4879c006c45SRosen Xu if (ret == -1) 4889c006c45SRosen Xu goto end; 4899c006c45SRosen Xu aer_new1 = data; 4909c006c45SRosen Xu 4919c006c45SRosen Xu if (fd != -1) 4929c006c45SRosen Xu close(fd); 4939c006c45SRosen Xu 4949c006c45SRosen Xu printf(">>>>>>Set AER %x,%x %x,%x\n", 4959c006c45SRosen Xu ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1], 4969c006c45SRosen Xu aer_new0, aer_new1); 4979c006c45SRosen Xu 4989c006c45SRosen Xu return 1; 4999c006c45SRosen Xu } 5009c006c45SRosen Xu 5019c006c45SRosen Xu end: 5029c006c45SRosen Xu if (fd != -1) 5039c006c45SRosen Xu close(fd); 5049c006c45SRosen Xu return -EFAULT; 5059c006c45SRosen Xu } 5069c006c45SRosen Xu 507a7ba40b2SThomas Monjalon static uint32_t 5089c006c45SRosen Xu ifpga_rawdev_gsd_handle(__rte_unused void *param) 5099c006c45SRosen Xu { 5109c006c45SRosen Xu struct ifpga_rawdev *ifpga_rdev; 5119c006c45SRosen Xu int i; 5129c006c45SRosen Xu int gsd_enable, ret; 5139c006c45SRosen Xu #define MS 1000 5149c006c45SRosen Xu 515e12a0166STyler Retzlaff while (rte_atomic_load_explicit(&ifpga_monitor_refcnt, rte_memory_order_relaxed)) { 5169c006c45SRosen Xu gsd_enable = 0; 5179c006c45SRosen Xu for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { 5189c006c45SRosen Xu ifpga_rdev = &ifpga_rawdevices[i]; 5192479a1e9SWei Huang if (ifpga_rdev->poll_enabled) { 5209c006c45SRosen Xu ret = set_surprise_link_check_aer(ifpga_rdev, 5219c006c45SRosen Xu gsd_enable); 5229c006c45SRosen Xu if (ret == 1 && !gsd_enable) { 5239c006c45SRosen Xu gsd_enable = 1; 5249c006c45SRosen Xu i = -1; 5259c006c45SRosen Xu } 5269c006c45SRosen Xu } 5279c006c45SRosen Xu } 5289c006c45SRosen Xu 5299c006c45SRosen Xu if (gsd_enable) 5309c006c45SRosen Xu printf(">>>>>>Pls Shutdown APP\n"); 5319c006c45SRosen Xu 5329c006c45SRosen Xu rte_delay_us(100 * MS); 5339c006c45SRosen Xu } 5349c006c45SRosen Xu 535a7ba40b2SThomas Monjalon return 0; 5369c006c45SRosen Xu } 5379c006c45SRosen Xu 5389c006c45SRosen Xu static int 5392479a1e9SWei Huang ifpga_monitor_start_func(struct ifpga_rawdev *dev) 5409c006c45SRosen Xu { 5419c006c45SRosen Xu int ret; 5429c006c45SRosen Xu 5432479a1e9SWei Huang if (!dev) 5442479a1e9SWei Huang return -ENODEV; 5452479a1e9SWei Huang 5462479a1e9SWei Huang ret = ifpga_rawdev_fill_info(dev); 5472479a1e9SWei Huang if (ret) 5482479a1e9SWei Huang return ret; 5492479a1e9SWei Huang 5502479a1e9SWei Huang dev->poll_enabled = 1; 5512479a1e9SWei Huang 552e12a0166STyler Retzlaff if (!rte_atomic_fetch_add_explicit(&ifpga_monitor_refcnt, 1, rte_memory_order_relaxed)) { 553a7ba40b2SThomas Monjalon ret = rte_thread_create_internal_control(&ifpga_monitor_start_thread, 554a7ba40b2SThomas Monjalon "ifpga-mon", ifpga_rawdev_gsd_handle, NULL); 5559734f50eSChengwen Feng if (ret != 0) { 556a7ba40b2SThomas Monjalon ifpga_monitor_start_thread.opaque_id = 0; 5579c006c45SRosen Xu IFPGA_RAWDEV_PMD_ERR( 5587be78d02SJosh Soref "Fail to create ifpga monitor thread"); 5599c006c45SRosen Xu return -1; 5609c006c45SRosen Xu } 5619c006c45SRosen Xu } 5629c006c45SRosen Xu 5639c006c45SRosen Xu return 0; 5649c006c45SRosen Xu } 5652479a1e9SWei Huang 5669c006c45SRosen Xu static int 5672479a1e9SWei Huang ifpga_monitor_stop_func(struct ifpga_rawdev *dev) 5689c006c45SRosen Xu { 5699c006c45SRosen Xu int ret; 5709c006c45SRosen Xu 5712479a1e9SWei Huang if (!dev || !dev->poll_enabled) 5722479a1e9SWei Huang return 0; 57360e68d17STianfei Zhang 5742479a1e9SWei Huang dev->poll_enabled = 0; 5752479a1e9SWei Huang 576e12a0166STyler Retzlaff if (!(rte_atomic_fetch_sub_explicit(&ifpga_monitor_refcnt, 1, 577e12a0166STyler Retzlaff rte_memory_order_relaxed) - 1) && 578a7ba40b2SThomas Monjalon ifpga_monitor_start_thread.opaque_id != 0) { 579a7ba40b2SThomas Monjalon ret = pthread_cancel((pthread_t)ifpga_monitor_start_thread.opaque_id); 5809c006c45SRosen Xu if (ret) 5819c006c45SRosen Xu IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread"); 5829c006c45SRosen Xu 583a7ba40b2SThomas Monjalon ret = rte_thread_join(ifpga_monitor_start_thread, NULL); 5849c006c45SRosen Xu if (ret) 5859c006c45SRosen Xu IFPGA_RAWDEV_PMD_ERR("Can't join the thread"); 5869c006c45SRosen Xu 5879c006c45SRosen Xu return ret; 5889c006c45SRosen Xu } 5899c006c45SRosen Xu 5909c006c45SRosen Xu return 0; 5919c006c45SRosen Xu } 5929c006c45SRosen Xu 593473c88f9SBruce Richardson static int 594473c88f9SBruce Richardson ifpga_fill_afu_dev(struct opae_accelerator *acc, 595473c88f9SBruce Richardson struct rte_afu_device *afu_dev) 596473c88f9SBruce Richardson { 597473c88f9SBruce Richardson struct rte_mem_resource *res = afu_dev->mem_resource; 598473c88f9SBruce Richardson struct opae_acc_region_info region_info; 599473c88f9SBruce Richardson struct opae_acc_info info; 600473c88f9SBruce Richardson unsigned long i; 601473c88f9SBruce Richardson int ret; 602473c88f9SBruce Richardson 603473c88f9SBruce Richardson ret = opae_acc_get_info(acc, &info); 604473c88f9SBruce Richardson if (ret) 605473c88f9SBruce Richardson return ret; 606473c88f9SBruce Richardson 607473c88f9SBruce Richardson if (info.num_regions > PCI_MAX_RESOURCE) 608473c88f9SBruce Richardson return -EFAULT; 609473c88f9SBruce Richardson 610473c88f9SBruce Richardson afu_dev->num_region = info.num_regions; 611473c88f9SBruce Richardson 612473c88f9SBruce Richardson for (i = 0; i < info.num_regions; i++) { 613473c88f9SBruce Richardson region_info.index = i; 614473c88f9SBruce Richardson ret = opae_acc_get_region_info(acc, ®ion_info); 615473c88f9SBruce Richardson if (ret) 616473c88f9SBruce Richardson return ret; 617473c88f9SBruce Richardson 618473c88f9SBruce Richardson if ((region_info.flags & ACC_REGION_MMIO) && 619473c88f9SBruce Richardson (region_info.flags & ACC_REGION_READ) && 620473c88f9SBruce Richardson (region_info.flags & ACC_REGION_WRITE)) { 621473c88f9SBruce Richardson res[i].phys_addr = region_info.phys_addr; 622473c88f9SBruce Richardson res[i].len = region_info.len; 623473c88f9SBruce Richardson res[i].addr = region_info.addr; 624473c88f9SBruce Richardson } else 625473c88f9SBruce Richardson return -EFAULT; 626473c88f9SBruce Richardson } 627473c88f9SBruce Richardson 628473c88f9SBruce Richardson return 0; 629473c88f9SBruce Richardson } 630473c88f9SBruce Richardson 631f150dd88SBruce Richardson static int 632473c88f9SBruce Richardson ifpga_rawdev_info_get(struct rte_rawdev *dev, 63310b71caeSBruce Richardson rte_rawdev_obj_t dev_info, 63410b71caeSBruce Richardson size_t dev_info_size) 635473c88f9SBruce Richardson { 636473c88f9SBruce Richardson struct opae_adapter *adapter; 637473c88f9SBruce Richardson struct opae_accelerator *acc; 638473c88f9SBruce Richardson struct rte_afu_device *afu_dev; 639473c88f9SBruce Richardson struct opae_manager *mgr = NULL; 640473c88f9SBruce Richardson struct opae_eth_group_region_info opae_lside_eth_info; 641473c88f9SBruce Richardson struct opae_eth_group_region_info opae_nside_eth_info; 642473c88f9SBruce Richardson int lside_bar_idx, nside_bar_idx; 643473c88f9SBruce Richardson 644473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_FUNC_TRACE(); 645473c88f9SBruce Richardson 64610b71caeSBruce Richardson if (!dev_info || dev_info_size != sizeof(*afu_dev)) { 647473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Invalid request"); 648f150dd88SBruce Richardson return -EINVAL; 649473c88f9SBruce Richardson } 650473c88f9SBruce Richardson 651473c88f9SBruce Richardson adapter = ifpga_rawdev_get_priv(dev); 652473c88f9SBruce Richardson if (!adapter) 653f150dd88SBruce Richardson return -ENOENT; 654473c88f9SBruce Richardson 655473c88f9SBruce Richardson afu_dev = dev_info; 656473c88f9SBruce Richardson afu_dev->rawdev = dev; 657473c88f9SBruce Richardson 658473c88f9SBruce Richardson /* find opae_accelerator and fill info into afu_device */ 659473c88f9SBruce Richardson opae_adapter_for_each_acc(adapter, acc) { 660473c88f9SBruce Richardson if (acc->index != afu_dev->id.port) 661473c88f9SBruce Richardson continue; 662473c88f9SBruce Richardson 663473c88f9SBruce Richardson if (ifpga_fill_afu_dev(acc, afu_dev)) { 664f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("cannot get info"); 665f150dd88SBruce Richardson return -ENOENT; 666473c88f9SBruce Richardson } 667473c88f9SBruce Richardson } 668473c88f9SBruce Richardson 669473c88f9SBruce Richardson /* get opae_manager to rawdev */ 670473c88f9SBruce Richardson mgr = opae_adapter_get_mgr(adapter); 671473c88f9SBruce Richardson if (mgr) { 672473c88f9SBruce Richardson /* get LineSide BAR Index */ 673473c88f9SBruce Richardson if (opae_manager_get_eth_group_region_info(mgr, 0, 674473c88f9SBruce Richardson &opae_lside_eth_info)) { 675f150dd88SBruce Richardson return -ENOENT; 676473c88f9SBruce Richardson } 677473c88f9SBruce Richardson lside_bar_idx = opae_lside_eth_info.mem_idx; 678473c88f9SBruce Richardson 679473c88f9SBruce Richardson /* get NICSide BAR Index */ 680473c88f9SBruce Richardson if (opae_manager_get_eth_group_region_info(mgr, 1, 681473c88f9SBruce Richardson &opae_nside_eth_info)) { 682f150dd88SBruce Richardson return -ENOENT; 683473c88f9SBruce Richardson } 684473c88f9SBruce Richardson nside_bar_idx = opae_nside_eth_info.mem_idx; 685473c88f9SBruce Richardson 686473c88f9SBruce Richardson if (lside_bar_idx >= PCI_MAX_RESOURCE || 687473c88f9SBruce Richardson nside_bar_idx >= PCI_MAX_RESOURCE || 688473c88f9SBruce Richardson lside_bar_idx == nside_bar_idx) 689f150dd88SBruce Richardson return -ENOENT; 690473c88f9SBruce Richardson 691473c88f9SBruce Richardson /* fill LineSide BAR Index */ 692473c88f9SBruce Richardson afu_dev->mem_resource[lside_bar_idx].phys_addr = 693473c88f9SBruce Richardson opae_lside_eth_info.phys_addr; 694473c88f9SBruce Richardson afu_dev->mem_resource[lside_bar_idx].len = 695473c88f9SBruce Richardson opae_lside_eth_info.len; 696473c88f9SBruce Richardson afu_dev->mem_resource[lside_bar_idx].addr = 697473c88f9SBruce Richardson opae_lside_eth_info.addr; 698473c88f9SBruce Richardson 699473c88f9SBruce Richardson /* fill NICSide BAR Index */ 700473c88f9SBruce Richardson afu_dev->mem_resource[nside_bar_idx].phys_addr = 701473c88f9SBruce Richardson opae_nside_eth_info.phys_addr; 702473c88f9SBruce Richardson afu_dev->mem_resource[nside_bar_idx].len = 703473c88f9SBruce Richardson opae_nside_eth_info.len; 704473c88f9SBruce Richardson afu_dev->mem_resource[nside_bar_idx].addr = 705473c88f9SBruce Richardson opae_nside_eth_info.addr; 706473c88f9SBruce Richardson } 707f150dd88SBruce Richardson return 0; 708473c88f9SBruce Richardson } 709473c88f9SBruce Richardson 710473c88f9SBruce Richardson static int 711473c88f9SBruce Richardson ifpga_rawdev_configure(const struct rte_rawdev *dev, 7128db9dce7SBruce Richardson rte_rawdev_obj_t config, 7138db9dce7SBruce Richardson size_t config_size __rte_unused) 714473c88f9SBruce Richardson { 715473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_FUNC_TRACE(); 716473c88f9SBruce Richardson 7178f1d23ecSDavid Marchand if (dev == NULL) 7188f1d23ecSDavid Marchand return -EINVAL; 719473c88f9SBruce Richardson 720473c88f9SBruce Richardson return config ? 0 : 1; 721473c88f9SBruce Richardson } 722473c88f9SBruce Richardson 723473c88f9SBruce Richardson static int 724473c88f9SBruce Richardson ifpga_rawdev_start(struct rte_rawdev *dev) 725473c88f9SBruce Richardson { 726473c88f9SBruce Richardson int ret = 0; 727473c88f9SBruce Richardson struct opae_adapter *adapter; 728473c88f9SBruce Richardson 729473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_FUNC_TRACE(); 730473c88f9SBruce Richardson 7318f1d23ecSDavid Marchand if (dev == NULL) 7328f1d23ecSDavid Marchand return -EINVAL; 733473c88f9SBruce Richardson 734473c88f9SBruce Richardson adapter = ifpga_rawdev_get_priv(dev); 735473c88f9SBruce Richardson if (!adapter) 736473c88f9SBruce Richardson return -ENODEV; 737473c88f9SBruce Richardson 738473c88f9SBruce Richardson return ret; 739473c88f9SBruce Richardson } 740473c88f9SBruce Richardson 741473c88f9SBruce Richardson static void 742473c88f9SBruce Richardson ifpga_rawdev_stop(struct rte_rawdev *dev) 743473c88f9SBruce Richardson { 744473c88f9SBruce Richardson dev->started = 0; 745473c88f9SBruce Richardson } 746473c88f9SBruce Richardson 747473c88f9SBruce Richardson static int 748473c88f9SBruce Richardson ifpga_rawdev_close(struct rte_rawdev *dev) 749473c88f9SBruce Richardson { 750ae835abaSWei Huang struct ifpga_rawdev *ifpga_rdev = NULL; 75182255e03SWei Huang struct opae_adapter *adapter; 75225456835SWei Huang struct opae_manager *mgr; 753ae835abaSWei Huang char *vdev_name = NULL; 75425456835SWei Huang int i, ret = 0; 75582255e03SWei Huang 75682255e03SWei Huang if (dev) { 757ae835abaSWei Huang ifpga_rdev = ifpga_rawdev_get(dev); 758ae835abaSWei Huang if (ifpga_rdev) { 759ae835abaSWei Huang for (i = 0; i < IFPGA_MAX_VDEV; i++) { 760ae835abaSWei Huang vdev_name = ifpga_rdev->vdev_name[i]; 761ae835abaSWei Huang if (vdev_name) 762ae835abaSWei Huang rte_vdev_uninit(vdev_name); 763ae835abaSWei Huang } 764ae835abaSWei Huang ifpga_monitor_stop_func(ifpga_rdev); 765ae835abaSWei Huang ifpga_rdev->rawdev = NULL; 766ae835abaSWei Huang } 76782255e03SWei Huang adapter = ifpga_rawdev_get_priv(dev); 76882255e03SWei Huang if (adapter) { 76925456835SWei Huang mgr = opae_adapter_get_mgr(adapter); 77025456835SWei Huang if (ifpga_rdev && mgr) { 77125456835SWei Huang if (ifpga_unregister_msix_irq(ifpga_rdev, 77225456835SWei Huang IFPGA_FME_IRQ, 0, 77325456835SWei Huang fme_interrupt_handler, mgr) < 0) 77425456835SWei Huang ret = -EINVAL; 77525456835SWei Huang } 77682255e03SWei Huang opae_adapter_destroy(adapter); 77782255e03SWei Huang opae_adapter_data_free(adapter->data); 77882255e03SWei Huang } 77982255e03SWei Huang } 78082255e03SWei Huang 78125456835SWei Huang return ret; 782473c88f9SBruce Richardson } 783473c88f9SBruce Richardson 784473c88f9SBruce Richardson static int 785473c88f9SBruce Richardson ifpga_rawdev_reset(struct rte_rawdev *dev) 786473c88f9SBruce Richardson { 787473c88f9SBruce Richardson return dev ? 0:1; 788473c88f9SBruce Richardson } 789473c88f9SBruce Richardson 790473c88f9SBruce Richardson static int 791473c88f9SBruce Richardson fpga_pr(struct rte_rawdev *raw_dev, u32 port_id, const char *buffer, u32 size, 792473c88f9SBruce Richardson u64 *status) 793473c88f9SBruce Richardson { 794473c88f9SBruce Richardson 795473c88f9SBruce Richardson struct opae_adapter *adapter; 796473c88f9SBruce Richardson struct opae_manager *mgr; 797473c88f9SBruce Richardson struct opae_accelerator *acc; 798473c88f9SBruce Richardson struct opae_bridge *br; 799473c88f9SBruce Richardson int ret; 800473c88f9SBruce Richardson 801473c88f9SBruce Richardson adapter = ifpga_rawdev_get_priv(raw_dev); 802473c88f9SBruce Richardson if (!adapter) 803473c88f9SBruce Richardson return -ENODEV; 804473c88f9SBruce Richardson 805473c88f9SBruce Richardson mgr = opae_adapter_get_mgr(adapter); 806473c88f9SBruce Richardson if (!mgr) 807473c88f9SBruce Richardson return -ENODEV; 808473c88f9SBruce Richardson 809473c88f9SBruce Richardson acc = opae_adapter_get_acc(adapter, port_id); 810473c88f9SBruce Richardson if (!acc) 811473c88f9SBruce Richardson return -ENODEV; 812473c88f9SBruce Richardson 813473c88f9SBruce Richardson br = opae_acc_get_br(acc); 814473c88f9SBruce Richardson if (!br) 815473c88f9SBruce Richardson return -ENODEV; 816473c88f9SBruce Richardson 817473c88f9SBruce Richardson ret = opae_manager_flash(mgr, port_id, buffer, size, status); 818473c88f9SBruce Richardson if (ret) { 819f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("%s pr error %d", __func__, ret); 820473c88f9SBruce Richardson return ret; 821473c88f9SBruce Richardson } 822473c88f9SBruce Richardson 823473c88f9SBruce Richardson ret = opae_bridge_reset(br); 824473c88f9SBruce Richardson if (ret) { 825f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("%s reset port:%d error %d", 826473c88f9SBruce Richardson __func__, port_id, ret); 827473c88f9SBruce Richardson return ret; 828473c88f9SBruce Richardson } 829473c88f9SBruce Richardson 830473c88f9SBruce Richardson return ret; 831473c88f9SBruce Richardson } 832473c88f9SBruce Richardson 833473c88f9SBruce Richardson static int 834473c88f9SBruce Richardson rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, 835473c88f9SBruce Richardson const char *file_name) 836473c88f9SBruce Richardson { 837473c88f9SBruce Richardson struct stat file_stat; 838473c88f9SBruce Richardson int file_fd; 839473c88f9SBruce Richardson int ret = 0; 840473c88f9SBruce Richardson ssize_t buffer_size; 841ceccbcd7SWei Huang void *buffer, *buf_to_free; 842473c88f9SBruce Richardson u64 pr_error; 843473c88f9SBruce Richardson 844473c88f9SBruce Richardson if (!file_name) 845473c88f9SBruce Richardson return -EINVAL; 846473c88f9SBruce Richardson 847473c88f9SBruce Richardson file_fd = open(file_name, O_RDONLY); 848473c88f9SBruce Richardson if (file_fd < 0) { 849f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("%s: open file error: %s", 850473c88f9SBruce Richardson __func__, file_name); 851f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Message : %s", strerror(errno)); 852473c88f9SBruce Richardson return -EINVAL; 853473c88f9SBruce Richardson } 854473c88f9SBruce Richardson ret = stat(file_name, &file_stat); 855473c88f9SBruce Richardson if (ret) { 856f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("stat on bitstream file failed: %s", 857473c88f9SBruce Richardson file_name); 858473c88f9SBruce Richardson ret = -EINVAL; 859473c88f9SBruce Richardson goto close_fd; 860473c88f9SBruce Richardson } 861473c88f9SBruce Richardson buffer_size = file_stat.st_size; 862473c88f9SBruce Richardson if (buffer_size <= 0) { 863473c88f9SBruce Richardson ret = -EINVAL; 864473c88f9SBruce Richardson goto close_fd; 865473c88f9SBruce Richardson } 866473c88f9SBruce Richardson 867f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("bitstream file size: %zu", buffer_size); 868473c88f9SBruce Richardson buffer = rte_malloc(NULL, buffer_size, 0); 869473c88f9SBruce Richardson if (!buffer) { 870473c88f9SBruce Richardson ret = -ENOMEM; 871473c88f9SBruce Richardson goto close_fd; 872473c88f9SBruce Richardson } 873ceccbcd7SWei Huang buf_to_free = buffer; 874473c88f9SBruce Richardson 875473c88f9SBruce Richardson /*read the raw data*/ 876473c88f9SBruce Richardson if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) { 877473c88f9SBruce Richardson ret = -EINVAL; 878473c88f9SBruce Richardson goto free_buffer; 879473c88f9SBruce Richardson } 880473c88f9SBruce Richardson 881473c88f9SBruce Richardson /*do PR now*/ 882473c88f9SBruce Richardson ret = fpga_pr(rawdev, port_id, buffer, buffer_size, &pr_error); 883f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("downloading to device port %d....%s.", port_id, 884473c88f9SBruce Richardson ret ? "failed" : "success"); 885473c88f9SBruce Richardson if (ret) { 886473c88f9SBruce Richardson ret = -EINVAL; 887473c88f9SBruce Richardson goto free_buffer; 888473c88f9SBruce Richardson } 889473c88f9SBruce Richardson 890473c88f9SBruce Richardson free_buffer: 891ceccbcd7SWei Huang rte_free(buf_to_free); 892473c88f9SBruce Richardson close_fd: 893473c88f9SBruce Richardson close(file_fd); 894473c88f9SBruce Richardson file_fd = 0; 895473c88f9SBruce Richardson return ret; 896473c88f9SBruce Richardson } 897473c88f9SBruce Richardson 898473c88f9SBruce Richardson static int 899473c88f9SBruce Richardson ifpga_rawdev_pr(struct rte_rawdev *dev, 900473c88f9SBruce Richardson rte_rawdev_obj_t pr_conf) 901473c88f9SBruce Richardson { 902473c88f9SBruce Richardson struct opae_adapter *adapter; 903e21346c4SAndy Pei struct opae_manager *mgr; 904673c897fSWei Huang struct opae_board_info *info = NULL; 905473c88f9SBruce Richardson struct rte_afu_pr_conf *afu_pr_conf; 906473c88f9SBruce Richardson int ret; 907473c88f9SBruce Richardson struct uuid uuid; 908473c88f9SBruce Richardson struct opae_accelerator *acc; 909473c88f9SBruce Richardson 910473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_FUNC_TRACE(); 911473c88f9SBruce Richardson 912473c88f9SBruce Richardson adapter = ifpga_rawdev_get_priv(dev); 913473c88f9SBruce Richardson if (!adapter) 914473c88f9SBruce Richardson return -ENODEV; 915473c88f9SBruce Richardson 916473c88f9SBruce Richardson if (!pr_conf) 917473c88f9SBruce Richardson return -EINVAL; 918473c88f9SBruce Richardson 919473c88f9SBruce Richardson afu_pr_conf = pr_conf; 920473c88f9SBruce Richardson 921473c88f9SBruce Richardson if (afu_pr_conf->pr_enable) { 922473c88f9SBruce Richardson ret = rte_fpga_do_pr(dev, 923473c88f9SBruce Richardson afu_pr_conf->afu_id.port, 924473c88f9SBruce Richardson afu_pr_conf->bs_path); 925473c88f9SBruce Richardson if (ret) { 926f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("do pr error %d", ret); 927473c88f9SBruce Richardson return ret; 928473c88f9SBruce Richardson } 929473c88f9SBruce Richardson } 930473c88f9SBruce Richardson 931e21346c4SAndy Pei mgr = opae_adapter_get_mgr(adapter); 932673c897fSWei Huang if (mgr) { 933e21346c4SAndy Pei if (ifpga_mgr_ops.get_board_info(mgr, &info)) { 934e21346c4SAndy Pei IFPGA_RAWDEV_PMD_ERR("ifpga manager get_board_info fail!"); 935e21346c4SAndy Pei return -1; 936e21346c4SAndy Pei } 937673c897fSWei Huang } 938e21346c4SAndy Pei 939673c897fSWei Huang if (info && info->lightweight) { 940e21346c4SAndy Pei /* set uuid to all 0, when fpga is lightweight image */ 941e21346c4SAndy Pei memset(&afu_pr_conf->afu_id.uuid.uuid_low, 0, sizeof(u64)); 942e21346c4SAndy Pei memset(&afu_pr_conf->afu_id.uuid.uuid_high, 0, sizeof(u64)); 943e21346c4SAndy Pei } else { 944473c88f9SBruce Richardson acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port); 945473c88f9SBruce Richardson if (!acc) 946473c88f9SBruce Richardson return -ENODEV; 947473c88f9SBruce Richardson 948473c88f9SBruce Richardson ret = opae_acc_get_uuid(acc, &uuid); 949473c88f9SBruce Richardson if (ret) 950473c88f9SBruce Richardson return ret; 951473c88f9SBruce Richardson 952e21346c4SAndy Pei rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, 953e21346c4SAndy Pei sizeof(u64)); 954e21346c4SAndy Pei rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, 955e21346c4SAndy Pei sizeof(u64)); 956473c88f9SBruce Richardson 957f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx", 958e21346c4SAndy Pei __func__, 959473c88f9SBruce Richardson (unsigned long)afu_pr_conf->afu_id.uuid.uuid_low, 960473c88f9SBruce Richardson (unsigned long)afu_pr_conf->afu_id.uuid.uuid_high); 961e21346c4SAndy Pei } 962473c88f9SBruce Richardson return 0; 963473c88f9SBruce Richardson } 964473c88f9SBruce Richardson 965473c88f9SBruce Richardson static int 966473c88f9SBruce Richardson ifpga_rawdev_get_attr(struct rte_rawdev *dev, 967473c88f9SBruce Richardson const char *attr_name, uint64_t *attr_value) 968473c88f9SBruce Richardson { 969473c88f9SBruce Richardson struct opae_adapter *adapter; 970473c88f9SBruce Richardson struct opae_manager *mgr; 971473c88f9SBruce Richardson struct opae_retimer_info opae_rtm_info; 972473c88f9SBruce Richardson struct opae_retimer_status opae_rtm_status; 973473c88f9SBruce Richardson struct opae_eth_group_info opae_eth_grp_info; 974473c88f9SBruce Richardson struct opae_eth_group_region_info opae_eth_grp_reg_info; 975473c88f9SBruce Richardson int eth_group_num = 0; 976473c88f9SBruce Richardson uint64_t port_link_bitmap = 0, port_link_bit; 977473c88f9SBruce Richardson uint32_t i, j, p, q; 978473c88f9SBruce Richardson 979473c88f9SBruce Richardson #define MAX_PORT_PER_RETIMER 4 980473c88f9SBruce Richardson 981473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_FUNC_TRACE(); 982473c88f9SBruce Richardson 983473c88f9SBruce Richardson if (!dev || !attr_name || !attr_value) { 984473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Invalid arguments for getting attributes"); 985473c88f9SBruce Richardson return -1; 986473c88f9SBruce Richardson } 987473c88f9SBruce Richardson 988473c88f9SBruce Richardson adapter = ifpga_rawdev_get_priv(dev); 989473c88f9SBruce Richardson if (!adapter) { 990473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Adapter of dev %s is NULL", dev->name); 991473c88f9SBruce Richardson return -1; 992473c88f9SBruce Richardson } 993473c88f9SBruce Richardson 994473c88f9SBruce Richardson mgr = opae_adapter_get_mgr(adapter); 995473c88f9SBruce Richardson if (!mgr) { 996473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL"); 997473c88f9SBruce Richardson return -1; 998473c88f9SBruce Richardson } 999473c88f9SBruce Richardson 1000473c88f9SBruce Richardson /* currently, eth_group_num is always 2 */ 1001473c88f9SBruce Richardson eth_group_num = opae_manager_get_eth_group_nums(mgr); 1002473c88f9SBruce Richardson if (eth_group_num < 0) 1003473c88f9SBruce Richardson return -1; 1004473c88f9SBruce Richardson 1005473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideBaseMAC")) { 1006473c88f9SBruce Richardson /* Currently FPGA not implement, so just set all zeros*/ 1007473c88f9SBruce Richardson *attr_value = (uint64_t)0; 1008473c88f9SBruce Richardson return 0; 1009473c88f9SBruce Richardson } 1010473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideMACType")) { 1011473c88f9SBruce Richardson /* eth_group 0 on FPGA connect to LineSide */ 1012473c88f9SBruce Richardson if (opae_manager_get_eth_group_info(mgr, 0, 1013473c88f9SBruce Richardson &opae_eth_grp_info)) 1014473c88f9SBruce Richardson return -1; 1015473c88f9SBruce Richardson switch (opae_eth_grp_info.speed) { 1016473c88f9SBruce Richardson case ETH_SPEED_10G: 1017473c88f9SBruce Richardson *attr_value = 1018473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI); 1019473c88f9SBruce Richardson break; 1020473c88f9SBruce Richardson case ETH_SPEED_25G: 1021473c88f9SBruce Richardson *attr_value = 1022473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI); 1023473c88f9SBruce Richardson break; 1024473c88f9SBruce Richardson default: 1025473c88f9SBruce Richardson *attr_value = 1026473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_RETIMER_MAC_TYPE_UNKNOWN); 1027473c88f9SBruce Richardson break; 1028473c88f9SBruce Richardson } 1029473c88f9SBruce Richardson return 0; 1030473c88f9SBruce Richardson } 1031473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideLinkSpeed")) { 1032473c88f9SBruce Richardson if (opae_manager_get_retimer_status(mgr, &opae_rtm_status)) 1033473c88f9SBruce Richardson return -1; 1034473c88f9SBruce Richardson switch (opae_rtm_status.speed) { 1035473c88f9SBruce Richardson case MXD_1GB: 1036473c88f9SBruce Richardson *attr_value = 1037473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1038473c88f9SBruce Richardson break; 1039473c88f9SBruce Richardson case MXD_2_5GB: 1040473c88f9SBruce Richardson *attr_value = 1041473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1042473c88f9SBruce Richardson break; 1043473c88f9SBruce Richardson case MXD_5GB: 1044473c88f9SBruce Richardson *attr_value = 1045473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1046473c88f9SBruce Richardson break; 1047473c88f9SBruce Richardson case MXD_10GB: 1048473c88f9SBruce Richardson *attr_value = 1049473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_10GB); 1050473c88f9SBruce Richardson break; 1051473c88f9SBruce Richardson case MXD_25GB: 1052473c88f9SBruce Richardson *attr_value = 1053473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_25GB); 1054473c88f9SBruce Richardson break; 1055473c88f9SBruce Richardson case MXD_40GB: 1056473c88f9SBruce Richardson *attr_value = 1057473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_40GB); 1058473c88f9SBruce Richardson break; 1059473c88f9SBruce Richardson case MXD_100GB: 1060473c88f9SBruce Richardson *attr_value = 1061473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1062473c88f9SBruce Richardson break; 1063473c88f9SBruce Richardson case MXD_SPEED_UNKNOWN: 1064473c88f9SBruce Richardson *attr_value = 1065473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1066473c88f9SBruce Richardson break; 1067473c88f9SBruce Richardson default: 1068473c88f9SBruce Richardson *attr_value = 1069473c88f9SBruce Richardson (uint64_t)(IFPGA_RAWDEV_LINK_SPEED_UNKNOWN); 1070473c88f9SBruce Richardson break; 1071473c88f9SBruce Richardson } 1072473c88f9SBruce Richardson return 0; 1073473c88f9SBruce Richardson } 1074473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideLinkRetimerNum")) { 1075473c88f9SBruce Richardson if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1076473c88f9SBruce Richardson return -1; 1077473c88f9SBruce Richardson *attr_value = (uint64_t)(opae_rtm_info.nums_retimer); 1078473c88f9SBruce Richardson return 0; 1079473c88f9SBruce Richardson } 1080473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideLinkPortNum")) { 1081473c88f9SBruce Richardson if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1082473c88f9SBruce Richardson return -1; 1083473c88f9SBruce Richardson uint64_t tmp = (uint64_t)opae_rtm_info.ports_per_retimer * 1084473c88f9SBruce Richardson (uint64_t)opae_rtm_info.nums_retimer; 1085473c88f9SBruce Richardson *attr_value = tmp; 1086473c88f9SBruce Richardson return 0; 1087473c88f9SBruce Richardson } 1088473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideLinkStatus")) { 1089473c88f9SBruce Richardson if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1090473c88f9SBruce Richardson return -1; 1091473c88f9SBruce Richardson if (opae_manager_get_retimer_status(mgr, &opae_rtm_status)) 1092473c88f9SBruce Richardson return -1; 1093473c88f9SBruce Richardson (*attr_value) = 0; 1094473c88f9SBruce Richardson q = 0; 1095473c88f9SBruce Richardson port_link_bitmap = (uint64_t)(opae_rtm_status.line_link_bitmap); 1096473c88f9SBruce Richardson for (i = 0; i < opae_rtm_info.nums_retimer; i++) { 1097473c88f9SBruce Richardson p = i * MAX_PORT_PER_RETIMER; 1098473c88f9SBruce Richardson for (j = 0; j < opae_rtm_info.ports_per_retimer; j++) { 1099473c88f9SBruce Richardson port_link_bit = 0; 1100473c88f9SBruce Richardson IFPGA_BIT_SET(port_link_bit, (p+j)); 1101473c88f9SBruce Richardson port_link_bit &= port_link_bitmap; 1102473c88f9SBruce Richardson if (port_link_bit) 1103473c88f9SBruce Richardson IFPGA_BIT_SET((*attr_value), q); 1104473c88f9SBruce Richardson q++; 1105473c88f9SBruce Richardson } 1106473c88f9SBruce Richardson } 1107473c88f9SBruce Richardson return 0; 1108473c88f9SBruce Richardson } 1109473c88f9SBruce Richardson if (!strcmp(attr_name, "LineSideBARIndex")) { 1110473c88f9SBruce Richardson /* eth_group 0 on FPGA connect to LineSide */ 1111473c88f9SBruce Richardson if (opae_manager_get_eth_group_region_info(mgr, 0, 1112473c88f9SBruce Richardson &opae_eth_grp_reg_info)) 1113473c88f9SBruce Richardson return -1; 1114473c88f9SBruce Richardson *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx; 1115473c88f9SBruce Richardson return 0; 1116473c88f9SBruce Richardson } 1117473c88f9SBruce Richardson if (!strcmp(attr_name, "NICSideMACType")) { 1118473c88f9SBruce Richardson /* eth_group 1 on FPGA connect to NicSide */ 1119473c88f9SBruce Richardson if (opae_manager_get_eth_group_info(mgr, 1, 1120473c88f9SBruce Richardson &opae_eth_grp_info)) 1121473c88f9SBruce Richardson return -1; 1122473c88f9SBruce Richardson *attr_value = (uint64_t)(opae_eth_grp_info.speed); 1123473c88f9SBruce Richardson return 0; 1124473c88f9SBruce Richardson } 1125473c88f9SBruce Richardson if (!strcmp(attr_name, "NICSideLinkSpeed")) { 1126473c88f9SBruce Richardson /* eth_group 1 on FPGA connect to NicSide */ 1127473c88f9SBruce Richardson if (opae_manager_get_eth_group_info(mgr, 1, 1128473c88f9SBruce Richardson &opae_eth_grp_info)) 1129473c88f9SBruce Richardson return -1; 1130473c88f9SBruce Richardson *attr_value = (uint64_t)(opae_eth_grp_info.speed); 1131473c88f9SBruce Richardson return 0; 1132473c88f9SBruce Richardson } 1133473c88f9SBruce Richardson if (!strcmp(attr_name, "NICSideLinkPortNum")) { 1134473c88f9SBruce Richardson if (opae_manager_get_retimer_info(mgr, &opae_rtm_info)) 1135473c88f9SBruce Richardson return -1; 1136473c88f9SBruce Richardson uint64_t tmp = (uint64_t)opae_rtm_info.nums_fvl * 1137473c88f9SBruce Richardson (uint64_t)opae_rtm_info.ports_per_fvl; 1138473c88f9SBruce Richardson *attr_value = tmp; 1139473c88f9SBruce Richardson return 0; 1140473c88f9SBruce Richardson } 1141473c88f9SBruce Richardson if (!strcmp(attr_name, "NICSideLinkStatus")) 1142473c88f9SBruce Richardson return 0; 1143473c88f9SBruce Richardson if (!strcmp(attr_name, "NICSideBARIndex")) { 1144473c88f9SBruce Richardson /* eth_group 1 on FPGA connect to NicSide */ 1145473c88f9SBruce Richardson if (opae_manager_get_eth_group_region_info(mgr, 1, 1146473c88f9SBruce Richardson &opae_eth_grp_reg_info)) 1147473c88f9SBruce Richardson return -1; 1148473c88f9SBruce Richardson *attr_value = (uint64_t)opae_eth_grp_reg_info.mem_idx; 1149473c88f9SBruce Richardson return 0; 1150473c88f9SBruce Richardson } 1151473c88f9SBruce Richardson 1152473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("%s not support", attr_name); 1153473c88f9SBruce Richardson return -1; 1154473c88f9SBruce Richardson } 1155473c88f9SBruce Richardson 1156473c88f9SBruce Richardson static const struct rte_rawdev_ops ifpga_rawdev_ops = { 1157473c88f9SBruce Richardson .dev_info_get = ifpga_rawdev_info_get, 1158473c88f9SBruce Richardson .dev_configure = ifpga_rawdev_configure, 1159473c88f9SBruce Richardson .dev_start = ifpga_rawdev_start, 1160473c88f9SBruce Richardson .dev_stop = ifpga_rawdev_stop, 1161473c88f9SBruce Richardson .dev_close = ifpga_rawdev_close, 1162473c88f9SBruce Richardson .dev_reset = ifpga_rawdev_reset, 1163473c88f9SBruce Richardson 1164473c88f9SBruce Richardson .queue_def_conf = NULL, 1165473c88f9SBruce Richardson .queue_setup = NULL, 1166473c88f9SBruce Richardson .queue_release = NULL, 1167473c88f9SBruce Richardson 1168473c88f9SBruce Richardson .attr_get = ifpga_rawdev_get_attr, 1169473c88f9SBruce Richardson .attr_set = NULL, 1170473c88f9SBruce Richardson 1171473c88f9SBruce Richardson .enqueue_bufs = NULL, 1172473c88f9SBruce Richardson .dequeue_bufs = NULL, 1173473c88f9SBruce Richardson 1174473c88f9SBruce Richardson .dump = NULL, 1175473c88f9SBruce Richardson 1176473c88f9SBruce Richardson .xstats_get = NULL, 1177473c88f9SBruce Richardson .xstats_get_names = NULL, 1178473c88f9SBruce Richardson .xstats_get_by_name = NULL, 1179473c88f9SBruce Richardson .xstats_reset = NULL, 1180473c88f9SBruce Richardson 1181473c88f9SBruce Richardson .firmware_status_get = NULL, 1182473c88f9SBruce Richardson .firmware_version_get = NULL, 1183473c88f9SBruce Richardson .firmware_load = ifpga_rawdev_pr, 1184473c88f9SBruce Richardson .firmware_unload = NULL, 1185473c88f9SBruce Richardson 1186473c88f9SBruce Richardson .dev_selftest = NULL, 1187473c88f9SBruce Richardson }; 1188473c88f9SBruce Richardson 1189473c88f9SBruce Richardson static int 119082ce05d8SRosen Xu ifpga_get_fme_error_prop(struct opae_manager *mgr, 119182ce05d8SRosen Xu u64 prop_id, u64 *val) 119282ce05d8SRosen Xu { 119382ce05d8SRosen Xu struct feature_prop prop; 119482ce05d8SRosen Xu 119582ce05d8SRosen Xu prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR; 119682ce05d8SRosen Xu prop.prop_id = prop_id; 119782ce05d8SRosen Xu 119882ce05d8SRosen Xu if (opae_manager_ifpga_get_prop(mgr, &prop)) 119982ce05d8SRosen Xu return -EINVAL; 120082ce05d8SRosen Xu 120182ce05d8SRosen Xu *val = prop.data; 120282ce05d8SRosen Xu 120382ce05d8SRosen Xu return 0; 120482ce05d8SRosen Xu } 120582ce05d8SRosen Xu 120682ce05d8SRosen Xu static int 120782ce05d8SRosen Xu ifpga_set_fme_error_prop(struct opae_manager *mgr, 120882ce05d8SRosen Xu u64 prop_id, u64 val) 120982ce05d8SRosen Xu { 121082ce05d8SRosen Xu struct feature_prop prop; 121182ce05d8SRosen Xu 121282ce05d8SRosen Xu prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR; 121382ce05d8SRosen Xu prop.prop_id = prop_id; 121482ce05d8SRosen Xu 121582ce05d8SRosen Xu prop.data = val; 121682ce05d8SRosen Xu 121782ce05d8SRosen Xu if (opae_manager_ifpga_set_prop(mgr, &prop)) 121882ce05d8SRosen Xu return -EINVAL; 121982ce05d8SRosen Xu 122082ce05d8SRosen Xu return 0; 122182ce05d8SRosen Xu } 122282ce05d8SRosen Xu 122382ce05d8SRosen Xu static int 122482ce05d8SRosen Xu fme_err_read_seu_emr(struct opae_manager *mgr) 122582ce05d8SRosen Xu { 122682ce05d8SRosen Xu u64 val; 122782ce05d8SRosen Xu int ret; 122882ce05d8SRosen Xu 122982ce05d8SRosen Xu ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val); 123082ce05d8SRosen Xu if (ret) 123182ce05d8SRosen Xu return -EINVAL; 123282ce05d8SRosen Xu 1233f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%" PRIx64, val); 123482ce05d8SRosen Xu 123582ce05d8SRosen Xu ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val); 123682ce05d8SRosen Xu if (ret) 123782ce05d8SRosen Xu return -EINVAL; 123882ce05d8SRosen Xu 1239f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%" PRIx64, val); 124082ce05d8SRosen Xu 124182ce05d8SRosen Xu return 0; 124282ce05d8SRosen Xu } 124382ce05d8SRosen Xu 124482ce05d8SRosen Xu static int fme_clear_warning_intr(struct opae_manager *mgr) 124582ce05d8SRosen Xu { 124682ce05d8SRosen Xu u64 val; 124782ce05d8SRosen Xu 124882ce05d8SRosen Xu if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0)) 124982ce05d8SRosen Xu return -EINVAL; 125082ce05d8SRosen Xu 125182ce05d8SRosen Xu if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val)) 125282ce05d8SRosen Xu return -EINVAL; 125382ce05d8SRosen Xu if ((val & 0x40) != 0) 1254f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("clean not done"); 125582ce05d8SRosen Xu 125682ce05d8SRosen Xu return 0; 125782ce05d8SRosen Xu } 125882ce05d8SRosen Xu 12594858f8a5STianfei Zhang static int fme_clean_fme_error(struct opae_manager *mgr) 12604858f8a5STianfei Zhang { 12614858f8a5STianfei Zhang u64 val; 12624858f8a5STianfei Zhang 12634858f8a5STianfei Zhang if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val)) 12644858f8a5STianfei Zhang return -EINVAL; 12654858f8a5STianfei Zhang 1266f665790aSDavid Marchand IFPGA_RAWDEV_PMD_DEBUG("before clean 0x%" PRIx64, val); 12674858f8a5STianfei Zhang 12684858f8a5STianfei Zhang ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_CLEAR, val); 12694858f8a5STianfei Zhang 12704858f8a5STianfei Zhang if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val)) 12714858f8a5STianfei Zhang return -EINVAL; 12724858f8a5STianfei Zhang 1273f665790aSDavid Marchand IFPGA_RAWDEV_PMD_DEBUG("after clean 0x%" PRIx64, val); 12744858f8a5STianfei Zhang 12754858f8a5STianfei Zhang return 0; 12764858f8a5STianfei Zhang } 12774858f8a5STianfei Zhang 127882ce05d8SRosen Xu static int 127982ce05d8SRosen Xu fme_err_handle_error0(struct opae_manager *mgr) 128082ce05d8SRosen Xu { 128182ce05d8SRosen Xu struct feature_fme_error0 fme_error0; 128282ce05d8SRosen Xu u64 val; 128382ce05d8SRosen Xu 128482ce05d8SRosen Xu if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val)) 128582ce05d8SRosen Xu return -EINVAL; 128682ce05d8SRosen Xu 12874858f8a5STianfei Zhang if (fme_clean_fme_error(mgr)) 12884858f8a5STianfei Zhang return -EINVAL; 12894858f8a5STianfei Zhang 129082ce05d8SRosen Xu fme_error0.csr = val; 129182ce05d8SRosen Xu 129282ce05d8SRosen Xu if (fme_error0.fabric_err) 1293f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Fabric error"); 129482ce05d8SRosen Xu else if (fme_error0.fabfifo_overflow) 1295f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error"); 129682ce05d8SRosen Xu else if (fme_error0.afu_acc_mode_err) 1297f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected"); 129882ce05d8SRosen Xu else if (fme_error0.pcie0cdc_parity_err) 1299f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error"); 130082ce05d8SRosen Xu else if (fme_error0.cvlcdc_parity_err) 1301f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error"); 130282ce05d8SRosen Xu else if (fme_error0.fpgaseuerr) 130382ce05d8SRosen Xu fme_err_read_seu_emr(mgr); 130482ce05d8SRosen Xu 130582ce05d8SRosen Xu /* clean the errors */ 130682ce05d8SRosen Xu if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val)) 130782ce05d8SRosen Xu return -EINVAL; 130882ce05d8SRosen Xu 130982ce05d8SRosen Xu return 0; 131082ce05d8SRosen Xu } 131182ce05d8SRosen Xu 131282ce05d8SRosen Xu static int 131382ce05d8SRosen Xu fme_err_handle_catfatal_error(struct opae_manager *mgr) 131482ce05d8SRosen Xu { 131582ce05d8SRosen Xu struct feature_fme_ras_catfaterror fme_catfatal; 131682ce05d8SRosen Xu u64 val; 131782ce05d8SRosen Xu 131882ce05d8SRosen Xu if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val)) 131982ce05d8SRosen Xu return -EINVAL; 132082ce05d8SRosen Xu 132182ce05d8SRosen Xu fme_catfatal.csr = val; 132282ce05d8SRosen Xu 132382ce05d8SRosen Xu if (fme_catfatal.cci_fatal_err) 1324f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("CCI error detected"); 132582ce05d8SRosen Xu else if (fme_catfatal.fabric_fatal_err) 1326f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected"); 132782ce05d8SRosen Xu else if (fme_catfatal.pcie_poison_err) 1328f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports"); 132982ce05d8SRosen Xu else if (fme_catfatal.inject_fata_err) 1330f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error"); 133182ce05d8SRosen Xu else if (fme_catfatal.crc_catast_err) 1332f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error"); 133382ce05d8SRosen Xu else if (fme_catfatal.injected_catast_err) 1334f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error"); 133582ce05d8SRosen Xu else if (fme_catfatal.bmc_seu_catast_err) 133682ce05d8SRosen Xu fme_err_read_seu_emr(mgr); 133782ce05d8SRosen Xu 133882ce05d8SRosen Xu return 0; 133982ce05d8SRosen Xu } 134082ce05d8SRosen Xu 134182ce05d8SRosen Xu static int 134282ce05d8SRosen Xu fme_err_handle_nonfaterror(struct opae_manager *mgr) 134382ce05d8SRosen Xu { 134482ce05d8SRosen Xu struct feature_fme_ras_nonfaterror nonfaterr; 134582ce05d8SRosen Xu u64 val; 134682ce05d8SRosen Xu 134782ce05d8SRosen Xu if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val)) 134882ce05d8SRosen Xu return -EINVAL; 134982ce05d8SRosen Xu 135082ce05d8SRosen Xu nonfaterr.csr = val; 135182ce05d8SRosen Xu 135282ce05d8SRosen Xu if (nonfaterr.temp_thresh_ap1) 1353f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1"); 135482ce05d8SRosen Xu else if (nonfaterr.temp_thresh_ap2) 1355f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2"); 135682ce05d8SRosen Xu else if (nonfaterr.pcie_error) 1357f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie"); 135882ce05d8SRosen Xu else if (nonfaterr.portfatal_error) 1359f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port."); 136082ce05d8SRosen Xu else if (nonfaterr.proc_hot) 1361f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("a ProcHot event"); 136282ce05d8SRosen Xu else if (nonfaterr.afu_acc_mode_err) 1363f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch"); 136482ce05d8SRosen Xu else if (nonfaterr.injected_nonfata_err) { 1365f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("Injected Warning Error"); 136682ce05d8SRosen Xu fme_clear_warning_intr(mgr); 136782ce05d8SRosen Xu } else if (nonfaterr.temp_thresh_AP6) 1368f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6"); 136982ce05d8SRosen Xu else if (nonfaterr.power_thresh_AP1) 1370f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1"); 137182ce05d8SRosen Xu else if (nonfaterr.power_thresh_AP2) 1372f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2"); 137382ce05d8SRosen Xu else if (nonfaterr.mbp_err) 1374f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("an MBP event"); 137582ce05d8SRosen Xu 137682ce05d8SRosen Xu return 0; 137782ce05d8SRosen Xu } 137882ce05d8SRosen Xu 137982ce05d8SRosen Xu static void 138082ce05d8SRosen Xu fme_interrupt_handler(void *param) 138182ce05d8SRosen Xu { 138282ce05d8SRosen Xu struct opae_manager *mgr = (struct opae_manager *)param; 138382ce05d8SRosen Xu 1384f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred", __func__); 138582ce05d8SRosen Xu 138682ce05d8SRosen Xu fme_err_handle_error0(mgr); 138782ce05d8SRosen Xu fme_err_handle_nonfaterror(mgr); 138882ce05d8SRosen Xu fme_err_handle_catfatal_error(mgr); 138982ce05d8SRosen Xu } 139082ce05d8SRosen Xu 1391e0a1aafeSTianfei Zhang int 139220659eb3SWei Huang ifpga_unregister_msix_irq(struct ifpga_rawdev *dev, enum ifpga_irq_type type, 1393e0a1aafeSTianfei Zhang int vec_start, rte_intr_callback_fn handler, void *arg) 1394e0a1aafeSTianfei Zhang { 139520659eb3SWei Huang struct rte_intr_handle **intr_handle; 139620659eb3SWei Huang int rc = 0; 139720659eb3SWei Huang int i = vec_start + 1; 139820659eb3SWei Huang 139920659eb3SWei Huang if (!dev) 140020659eb3SWei Huang return -ENODEV; 140182ce05d8SRosen Xu 1402e0a1aafeSTianfei Zhang if (type == IFPGA_FME_IRQ) 140320659eb3SWei Huang intr_handle = (struct rte_intr_handle **)&dev->intr_handle[0]; 1404e0a1aafeSTianfei Zhang else if (type == IFPGA_AFU_IRQ) 140520659eb3SWei Huang intr_handle = (struct rte_intr_handle **)&dev->intr_handle[i]; 140650957920SWei Huang else 140720659eb3SWei Huang return -EINVAL; 1408e0a1aafeSTianfei Zhang 140920659eb3SWei Huang if ((*intr_handle) == NULL) { 1410f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("%s interrupt %d not registered", 141120659eb3SWei Huang type == IFPGA_FME_IRQ ? "FME" : "AFU", 141220659eb3SWei Huang type == IFPGA_FME_IRQ ? 0 : vec_start); 141320659eb3SWei Huang return -ENOENT; 141420659eb3SWei Huang } 1415e0a1aafeSTianfei Zhang 141620659eb3SWei Huang rte_intr_efd_disable(*intr_handle); 1417d61138d4SHarman Kalra 141820659eb3SWei Huang rc = rte_intr_callback_unregister(*intr_handle, handler, arg); 141920659eb3SWei Huang if (rc < 0) { 1420f665790aSDavid Marchand IFPGA_RAWDEV_PMD_ERR("Failed to unregister %s interrupt %d", 142120659eb3SWei Huang type == IFPGA_FME_IRQ ? "FME" : "AFU", 142220659eb3SWei Huang type == IFPGA_FME_IRQ ? 0 : vec_start); 142320659eb3SWei Huang } else { 142420659eb3SWei Huang rte_intr_instance_free(*intr_handle); 142520659eb3SWei Huang *intr_handle = NULL; 142620659eb3SWei Huang } 142720659eb3SWei Huang 1428d61138d4SHarman Kalra return rc; 1429e0a1aafeSTianfei Zhang } 1430e0a1aafeSTianfei Zhang 1431e0a1aafeSTianfei Zhang int 143220659eb3SWei Huang ifpga_register_msix_irq(struct ifpga_rawdev *dev, int port_id, 1433e0a1aafeSTianfei Zhang enum ifpga_irq_type type, int vec_start, int count, 1434e0a1aafeSTianfei Zhang rte_intr_callback_fn handler, const char *name, 1435e0a1aafeSTianfei Zhang void *arg) 143682ce05d8SRosen Xu { 143782ce05d8SRosen Xu int ret; 143820659eb3SWei Huang struct rte_intr_handle **intr_handle; 1439e0a1aafeSTianfei Zhang struct opae_adapter *adapter; 1440e0a1aafeSTianfei Zhang struct opae_manager *mgr; 1441e0a1aafeSTianfei Zhang struct opae_accelerator *acc; 1442d61138d4SHarman Kalra int *intr_efds = NULL, nb_intr, i; 1443d61138d4SHarman Kalra 144420659eb3SWei Huang if (!dev || !dev->rawdev) 144520659eb3SWei Huang return -ENODEV; 144682ce05d8SRosen Xu 144720659eb3SWei Huang adapter = ifpga_rawdev_get_priv(dev->rawdev); 1448e0a1aafeSTianfei Zhang if (!adapter) 1449e0a1aafeSTianfei Zhang return -ENODEV; 145082ce05d8SRosen Xu 1451e0a1aafeSTianfei Zhang mgr = opae_adapter_get_mgr(adapter); 1452e0a1aafeSTianfei Zhang if (!mgr) 1453e0a1aafeSTianfei Zhang return -ENODEV; 1454e0a1aafeSTianfei Zhang 1455e0a1aafeSTianfei Zhang if (type == IFPGA_FME_IRQ) { 145620659eb3SWei Huang intr_handle = (struct rte_intr_handle **)&dev->intr_handle[0]; 1457e0a1aafeSTianfei Zhang count = 1; 145850957920SWei Huang } else if (type == IFPGA_AFU_IRQ) { 145920659eb3SWei Huang i = vec_start + 1; 146020659eb3SWei Huang intr_handle = (struct rte_intr_handle **)&dev->intr_handle[i]; 146150957920SWei Huang } else { 146250957920SWei Huang return -EINVAL; 146350957920SWei Huang } 1464e0a1aafeSTianfei Zhang 146520659eb3SWei Huang if (*intr_handle) 146620659eb3SWei Huang return -EBUSY; 146720659eb3SWei Huang 146820659eb3SWei Huang *intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); 146920659eb3SWei Huang if (!(*intr_handle)) 147020659eb3SWei Huang return -ENOMEM; 147120659eb3SWei Huang 147220659eb3SWei Huang if (rte_intr_type_set(*intr_handle, RTE_INTR_HANDLE_VFIO_MSIX)) 1473d61138d4SHarman Kalra return -rte_errno; 1474e0a1aafeSTianfei Zhang 147520659eb3SWei Huang ret = rte_intr_efd_enable(*intr_handle, count); 147682ce05d8SRosen Xu if (ret) 1477e0a1aafeSTianfei Zhang return -ENODEV; 147882ce05d8SRosen Xu 147920659eb3SWei Huang if (rte_intr_fd_set(*intr_handle, 148020659eb3SWei Huang rte_intr_efds_index_get(*intr_handle, 0))) 1481d61138d4SHarman Kalra return -rte_errno; 148282ce05d8SRosen Xu 1483f665790aSDavid Marchand IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d", 148420659eb3SWei Huang name, rte_intr_dev_fd_get(*intr_handle), 148520659eb3SWei Huang rte_intr_fd_get(*intr_handle)); 148682ce05d8SRosen Xu 1487e0a1aafeSTianfei Zhang if (type == IFPGA_FME_IRQ) { 1488e0a1aafeSTianfei Zhang struct fpga_fme_err_irq_set err_irq_set; 148920659eb3SWei Huang err_irq_set.evtfd = rte_intr_efds_index_get(*intr_handle, 1490d61138d4SHarman Kalra 0); 1491e0a1aafeSTianfei Zhang 149282ce05d8SRosen Xu ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); 149382ce05d8SRosen Xu if (ret) 149482ce05d8SRosen Xu return -EINVAL; 1495e0a1aafeSTianfei Zhang } else if (type == IFPGA_AFU_IRQ) { 1496e0a1aafeSTianfei Zhang acc = opae_adapter_get_acc(adapter, port_id); 1497e0a1aafeSTianfei Zhang if (!acc) 1498e0a1aafeSTianfei Zhang return -EINVAL; 149982ce05d8SRosen Xu 150020659eb3SWei Huang nb_intr = rte_intr_nb_intr_get(*intr_handle); 1501d61138d4SHarman Kalra 1502*d891a597SStephen Hemminger intr_efds = rte_calloc("ifpga_efds", nb_intr, sizeof(int), 0); 1503d61138d4SHarman Kalra if (!intr_efds) 1504d61138d4SHarman Kalra return -ENOMEM; 1505d61138d4SHarman Kalra 1506d61138d4SHarman Kalra for (i = 0; i < nb_intr; i++) 150720659eb3SWei Huang intr_efds[i] = rte_intr_efds_index_get(*intr_handle, i); 1508d61138d4SHarman Kalra 1509d61138d4SHarman Kalra ret = opae_acc_set_irq(acc, vec_start, count, intr_efds); 1510d61138d4SHarman Kalra if (ret) { 1511*d891a597SStephen Hemminger rte_free(intr_efds); 1512e0a1aafeSTianfei Zhang return -EINVAL; 1513e0a1aafeSTianfei Zhang } 1514d61138d4SHarman Kalra } 1515e0a1aafeSTianfei Zhang 1516e0a1aafeSTianfei Zhang /* register interrupt handler using DPDK API */ 151720659eb3SWei Huang ret = rte_intr_callback_register(*intr_handle, 1518e0a1aafeSTianfei Zhang handler, (void *)arg); 1519d61138d4SHarman Kalra if (ret) { 1520*d891a597SStephen Hemminger rte_free(intr_efds); 152182ce05d8SRosen Xu return -EINVAL; 1522d61138d4SHarman Kalra } 152382ce05d8SRosen Xu 1524f665790aSDavid Marchand IFPGA_RAWDEV_PMD_INFO("success register %s interrupt", name); 152582ce05d8SRosen Xu 1526*d891a597SStephen Hemminger rte_free(intr_efds); 152782ce05d8SRosen Xu return 0; 152882ce05d8SRosen Xu } 152982ce05d8SRosen Xu 153082ce05d8SRosen Xu static int 1531473c88f9SBruce Richardson ifpga_rawdev_create(struct rte_pci_device *pci_dev, 1532473c88f9SBruce Richardson int socket_id) 1533473c88f9SBruce Richardson { 1534473c88f9SBruce Richardson int ret = 0; 1535473c88f9SBruce Richardson struct rte_rawdev *rawdev = NULL; 15369c006c45SRosen Xu struct ifpga_rawdev *dev = NULL; 1537473c88f9SBruce Richardson struct opae_adapter *adapter = NULL; 1538473c88f9SBruce Richardson struct opae_manager *mgr = NULL; 1539473c88f9SBruce Richardson struct opae_adapter_data_pci *data = NULL; 1540473c88f9SBruce Richardson char name[RTE_RAWDEV_NAME_MAX_LEN]; 1541473c88f9SBruce Richardson int i; 1542473c88f9SBruce Richardson 1543473c88f9SBruce Richardson if (!pci_dev) { 1544473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); 1545473c88f9SBruce Richardson ret = -EINVAL; 1546473c88f9SBruce Richardson goto cleanup; 1547473c88f9SBruce Richardson } 1548473c88f9SBruce Richardson 1549473c88f9SBruce Richardson memset(name, 0, sizeof(name)); 1550978bb0b3SWei Huang snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, IFPGA_RAWDEV_NAME_FMT, 1551473c88f9SBruce Richardson pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); 1552473c88f9SBruce Richardson 1553473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id()); 1554473c88f9SBruce Richardson 1555473c88f9SBruce Richardson /* Allocate device structure */ 1556473c88f9SBruce Richardson rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct opae_adapter), 1557473c88f9SBruce Richardson socket_id); 1558473c88f9SBruce Richardson if (rawdev == NULL) { 1559473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Unable to allocate rawdevice"); 1560473c88f9SBruce Richardson ret = -EINVAL; 1561473c88f9SBruce Richardson goto cleanup; 1562473c88f9SBruce Richardson } 1563473c88f9SBruce Richardson 15648418c928SRosen Xu ipn3ke_bridge_func.get_ifpga_rawdev = ifpga_rawdev_get; 15658418c928SRosen Xu ipn3ke_bridge_func.set_i40e_sw_dev = rte_pmd_i40e_set_switch_dev; 15668418c928SRosen Xu 15679c006c45SRosen Xu dev = ifpga_rawdev_allocate(rawdev); 15689c006c45SRosen Xu if (dev == NULL) { 15699c006c45SRosen Xu IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice"); 15709c006c45SRosen Xu ret = -EINVAL; 15719c006c45SRosen Xu goto cleanup; 15729c006c45SRosen Xu } 15739c006c45SRosen Xu dev->aer_enable = 0; 15749c006c45SRosen Xu 1575473c88f9SBruce Richardson /* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */ 1576473c88f9SBruce Richardson data = opae_adapter_data_alloc(OPAE_FPGA_PCI); 1577473c88f9SBruce Richardson if (!data) { 1578473c88f9SBruce Richardson ret = -ENOMEM; 1579473c88f9SBruce Richardson goto cleanup; 1580473c88f9SBruce Richardson } 1581473c88f9SBruce Richardson 1582473c88f9SBruce Richardson /* init opae_adapter_data_pci for device specific information */ 1583473c88f9SBruce Richardson for (i = 0; i < PCI_MAX_RESOURCE; i++) { 1584473c88f9SBruce Richardson data->region[i].phys_addr = pci_dev->mem_resource[i].phys_addr; 1585473c88f9SBruce Richardson data->region[i].len = pci_dev->mem_resource[i].len; 1586473c88f9SBruce Richardson data->region[i].addr = pci_dev->mem_resource[i].addr; 1587473c88f9SBruce Richardson } 1588473c88f9SBruce Richardson data->device_id = pci_dev->id.device_id; 1589473c88f9SBruce Richardson data->vendor_id = pci_dev->id.vendor_id; 15904a19f891STianfei Zhang data->bus = pci_dev->addr.bus; 15914a19f891STianfei Zhang data->devid = pci_dev->addr.devid; 15924a19f891STianfei Zhang data->function = pci_dev->addr.function; 1593d61138d4SHarman Kalra data->vfio_dev_fd = rte_intr_dev_fd_get(pci_dev->intr_handle); 1594473c88f9SBruce Richardson 1595473c88f9SBruce Richardson adapter = rawdev->dev_private; 1596473c88f9SBruce Richardson /* create a opae_adapter based on above device data */ 1597473c88f9SBruce Richardson ret = opae_adapter_init(adapter, pci_dev->device.name, data); 1598473c88f9SBruce Richardson if (ret) { 1599473c88f9SBruce Richardson ret = -ENOMEM; 1600673c897fSWei Huang goto cleanup; 1601473c88f9SBruce Richardson } 1602473c88f9SBruce Richardson 1603473c88f9SBruce Richardson rawdev->dev_ops = &ifpga_rawdev_ops; 1604473c88f9SBruce Richardson rawdev->device = &pci_dev->device; 1605473c88f9SBruce Richardson rawdev->driver_name = pci_dev->driver->driver.name; 1606473c88f9SBruce Richardson 1607473c88f9SBruce Richardson /* must enumerate the adapter before use it */ 1608473c88f9SBruce Richardson ret = opae_adapter_enumerate(adapter); 1609473c88f9SBruce Richardson if (ret) 1610673c897fSWei Huang goto cleanup; 1611473c88f9SBruce Richardson 1612473c88f9SBruce Richardson /* get opae_manager to rawdev */ 1613473c88f9SBruce Richardson mgr = opae_adapter_get_mgr(adapter); 1614473c88f9SBruce Richardson if (mgr) { 161520659eb3SWei Huang ret = ifpga_register_msix_irq(dev, 0, IFPGA_FME_IRQ, 0, 0, 1616e0a1aafeSTianfei Zhang fme_interrupt_handler, "fme_irq", mgr); 161782ce05d8SRosen Xu if (ret) 1618673c897fSWei Huang goto cleanup; 1619673c897fSWei Huang } 162082ce05d8SRosen Xu 16212479a1e9SWei Huang ret = ifpga_monitor_start_func(dev); 16222479a1e9SWei Huang if (ret) 1623673c897fSWei Huang goto cleanup; 16242479a1e9SWei Huang 1625473c88f9SBruce Richardson return ret; 1626473c88f9SBruce Richardson 1627473c88f9SBruce Richardson cleanup: 1628473c88f9SBruce Richardson if (rawdev) 1629473c88f9SBruce Richardson rte_rawdev_pmd_release(rawdev); 1630473c88f9SBruce Richardson 1631473c88f9SBruce Richardson return ret; 1632473c88f9SBruce Richardson } 1633473c88f9SBruce Richardson 1634473c88f9SBruce Richardson static int 1635473c88f9SBruce Richardson ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) 1636473c88f9SBruce Richardson { 1637473c88f9SBruce Richardson int ret; 1638473c88f9SBruce Richardson struct rte_rawdev *rawdev; 1639473c88f9SBruce Richardson char name[RTE_RAWDEV_NAME_MAX_LEN]; 1640473c88f9SBruce Richardson 1641473c88f9SBruce Richardson if (!pci_dev) { 1642473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); 1643473c88f9SBruce Richardson ret = -EINVAL; 1644473c88f9SBruce Richardson return ret; 1645473c88f9SBruce Richardson } 1646473c88f9SBruce Richardson 1647473c88f9SBruce Richardson memset(name, 0, sizeof(name)); 1648978bb0b3SWei Huang snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, IFPGA_RAWDEV_NAME_FMT, 1649473c88f9SBruce Richardson pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); 1650473c88f9SBruce Richardson 1651473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d", 1652473c88f9SBruce Richardson name, rte_socket_id()); 1653473c88f9SBruce Richardson 1654473c88f9SBruce Richardson rawdev = rte_rawdev_pmd_get_named_dev(name); 1655473c88f9SBruce Richardson if (!rawdev) { 1656473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); 1657473c88f9SBruce Richardson return -EINVAL; 1658473c88f9SBruce Richardson } 165982ce05d8SRosen Xu 1660473c88f9SBruce Richardson /* rte_rawdev_close is called by pmd_release */ 1661473c88f9SBruce Richardson ret = rte_rawdev_pmd_release(rawdev); 1662473c88f9SBruce Richardson if (ret) 1663473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_DEBUG("Device cleanup failed"); 1664473c88f9SBruce Richardson 1665473c88f9SBruce Richardson return ret; 1666473c88f9SBruce Richardson } 1667473c88f9SBruce Richardson 1668473c88f9SBruce Richardson static int 1669473c88f9SBruce Richardson ifpga_rawdev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 1670473c88f9SBruce Richardson struct rte_pci_device *pci_dev) 1671473c88f9SBruce Richardson { 1672473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_FUNC_TRACE(); 1673473c88f9SBruce Richardson return ifpga_rawdev_create(pci_dev, rte_socket_id()); 1674473c88f9SBruce Richardson } 1675473c88f9SBruce Richardson 1676473c88f9SBruce Richardson static int 1677473c88f9SBruce Richardson ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev) 1678473c88f9SBruce Richardson { 16792479a1e9SWei Huang IFPGA_RAWDEV_PMD_INFO("remove pci_dev %s", pci_dev->device.name); 1680473c88f9SBruce Richardson return ifpga_rawdev_destroy(pci_dev); 1681473c88f9SBruce Richardson } 1682473c88f9SBruce Richardson 1683473c88f9SBruce Richardson static struct rte_pci_driver rte_ifpga_rawdev_pmd = { 1684473c88f9SBruce Richardson .id_table = pci_ifpga_map, 1685473c88f9SBruce Richardson .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 1686473c88f9SBruce Richardson .probe = ifpga_rawdev_pci_probe, 1687473c88f9SBruce Richardson .remove = ifpga_rawdev_pci_remove, 1688473c88f9SBruce Richardson }; 1689473c88f9SBruce Richardson 1690473c88f9SBruce Richardson RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); 1691473c88f9SBruce Richardson RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); 1692473c88f9SBruce Richardson RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci"); 1693eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(ifpga_rawdev_logtype, NOTICE); 1694473c88f9SBruce Richardson 1695473c88f9SBruce Richardson static const char * const valid_args[] = { 1696473c88f9SBruce Richardson #define IFPGA_ARG_NAME "ifpga" 1697473c88f9SBruce Richardson IFPGA_ARG_NAME, 1698473c88f9SBruce Richardson #define IFPGA_ARG_PORT "port" 1699473c88f9SBruce Richardson IFPGA_ARG_PORT, 1700473c88f9SBruce Richardson #define IFPGA_AFU_BTS "afu_bts" 1701473c88f9SBruce Richardson IFPGA_AFU_BTS, 1702473c88f9SBruce Richardson NULL 1703473c88f9SBruce Richardson }; 1704473c88f9SBruce Richardson 17059c006c45SRosen Xu static int ifpga_rawdev_get_string_arg(const char *key __rte_unused, 17069c006c45SRosen Xu const char *value, void *extra_args) 17079c006c45SRosen Xu { 17089c006c45SRosen Xu int size; 17099c006c45SRosen Xu if (!value || !extra_args) 17109c006c45SRosen Xu return -EINVAL; 17119c006c45SRosen Xu 17129c006c45SRosen Xu size = strlen(value) + 1; 17139c006c45SRosen Xu *(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE); 17149c006c45SRosen Xu if (!*(char **)extra_args) 17159c006c45SRosen Xu return -ENOMEM; 17169c006c45SRosen Xu 17179c006c45SRosen Xu strlcpy(*(char **)extra_args, value, size); 17189c006c45SRosen Xu 17199c006c45SRosen Xu return 0; 17209c006c45SRosen Xu } 1721473c88f9SBruce Richardson 1722ae835abaSWei Huang static int 1723ae835abaSWei Huang ifpga_vdev_parse_devargs(struct rte_devargs *devargs, 1724ae835abaSWei Huang struct ifpga_vdev_args *args) 1725ae835abaSWei Huang { 1726ae835abaSWei Huang struct rte_kvargs *kvlist; 1727ae835abaSWei Huang char *name = NULL; 1728ae835abaSWei Huang int port = 0; 1729ae835abaSWei Huang int ret = -EINVAL; 1730ae835abaSWei Huang 1731ae835abaSWei Huang if (!devargs || !args) 1732ae835abaSWei Huang return ret; 1733473c88f9SBruce Richardson 1734473c88f9SBruce Richardson kvlist = rte_kvargs_parse(devargs->args, valid_args); 1735473c88f9SBruce Richardson if (!kvlist) { 1736ae835abaSWei Huang IFPGA_RAWDEV_PMD_ERR("error when parsing devargs"); 1737ae835abaSWei Huang return ret; 1738473c88f9SBruce Richardson } 1739473c88f9SBruce Richardson 1740473c88f9SBruce Richardson if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) { 1741473c88f9SBruce Richardson if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME, 1742ae835abaSWei Huang &ifpga_rawdev_get_string_arg, &name) < 0) { 1743473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("error to parse %s", 1744473c88f9SBruce Richardson IFPGA_ARG_NAME); 1745473c88f9SBruce Richardson goto end; 1746ae835abaSWei Huang } else { 1747ae835abaSWei Huang strlcpy(args->bdf, name, sizeof(args->bdf)); 1748ae835abaSWei Huang rte_free(name); 1749473c88f9SBruce Richardson } 1750473c88f9SBruce Richardson } else { 1751473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", 1752473c88f9SBruce Richardson IFPGA_ARG_NAME); 1753473c88f9SBruce Richardson goto end; 1754473c88f9SBruce Richardson } 1755473c88f9SBruce Richardson 1756473c88f9SBruce Richardson if (rte_kvargs_count(kvlist, IFPGA_ARG_PORT) == 1) { 1757ae835abaSWei Huang if (rte_kvargs_process(kvlist, IFPGA_ARG_PORT, 17589c89c333SDavid Marchand ifpga_get_integer32_arg, &port) < 0) { 1759473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("error to parse %s", 1760473c88f9SBruce Richardson IFPGA_ARG_PORT); 1761473c88f9SBruce Richardson goto end; 1762ae835abaSWei Huang } else { 1763ae835abaSWei Huang args->port = port; 1764473c88f9SBruce Richardson } 1765473c88f9SBruce Richardson } else { 1766473c88f9SBruce Richardson IFPGA_RAWDEV_PMD_ERR("arg %s is mandatory for ifpga bus", 1767473c88f9SBruce Richardson IFPGA_ARG_PORT); 1768473c88f9SBruce Richardson goto end; 1769473c88f9SBruce Richardson } 1770473c88f9SBruce Richardson 1771ae835abaSWei Huang ret = 0; 1772ae835abaSWei Huang 1773ae835abaSWei Huang end: 1774ae835abaSWei Huang rte_kvargs_free(kvlist); 1775ae835abaSWei Huang 1776ae835abaSWei Huang return ret; 1777ae835abaSWei Huang } 1778ae835abaSWei Huang 1779ae835abaSWei Huang static int 1780ae835abaSWei Huang ifpga_cfg_probe(struct rte_vdev_device *vdev) 1781ae835abaSWei Huang { 1782ae835abaSWei Huang struct rte_rawdev *rawdev = NULL; 1783ae835abaSWei Huang struct ifpga_rawdev *ifpga_dev; 1784ae835abaSWei Huang struct ifpga_vdev_args args; 1785ae835abaSWei Huang char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; 1786ae835abaSWei Huang const char *vdev_name = NULL; 1787ae835abaSWei Huang int i, n, ret = 0; 1788ae835abaSWei Huang 1789ae835abaSWei Huang vdev_name = rte_vdev_device_name(vdev); 1790ae835abaSWei Huang if (!vdev_name) 1791ae835abaSWei Huang return -EINVAL; 1792ae835abaSWei Huang 1793ae835abaSWei Huang IFPGA_RAWDEV_PMD_INFO("probe ifpga virtual device %s", vdev_name); 1794ae835abaSWei Huang 1795ae835abaSWei Huang ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args); 1796ae835abaSWei Huang if (ret) 1797ae835abaSWei Huang return ret; 1798ae835abaSWei Huang 1799473c88f9SBruce Richardson memset(dev_name, 0, sizeof(dev_name)); 1800ae835abaSWei Huang snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", args.bdf); 18019c006c45SRosen Xu rawdev = rte_rawdev_pmd_get_named_dev(dev_name); 18029c006c45SRosen Xu if (!rawdev) 1803ae835abaSWei Huang return -ENODEV; 18049c006c45SRosen Xu ifpga_dev = ifpga_rawdev_get(rawdev); 18059c006c45SRosen Xu if (!ifpga_dev) 1806ae835abaSWei Huang return -ENODEV; 18079c006c45SRosen Xu 1808ae835abaSWei Huang for (i = 0; i < IFPGA_MAX_VDEV; i++) { 1809ae835abaSWei Huang if (ifpga_dev->vdev_name[i] == NULL) { 1810ae835abaSWei Huang n = strlen(vdev_name) + 1; 1811ae835abaSWei Huang ifpga_dev->vdev_name[i] = rte_malloc(NULL, n, 0); 1812ae835abaSWei Huang if (ifpga_dev->vdev_name[i] == NULL) 1813ae835abaSWei Huang return -ENOMEM; 1814ae835abaSWei Huang strlcpy(ifpga_dev->vdev_name[i], vdev_name, n); 1815ae835abaSWei Huang break; 1816ae835abaSWei Huang } 1817ae835abaSWei Huang } 1818ae835abaSWei Huang 1819ae835abaSWei Huang if (i >= IFPGA_MAX_VDEV) { 1820ae835abaSWei Huang IFPGA_RAWDEV_PMD_ERR("Can't create more virtual device!"); 1821ae835abaSWei Huang return -ENOENT; 1822ae835abaSWei Huang } 1823ae835abaSWei Huang 1824473c88f9SBruce Richardson snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", 1825ae835abaSWei Huang args.port, args.bdf); 1826473c88f9SBruce Richardson ret = rte_eal_hotplug_add(RTE_STR(IFPGA_BUS_NAME), 1827ae835abaSWei Huang dev_name, vdev->device.devargs->args); 1828ae835abaSWei Huang if (ret) { 1829ae835abaSWei Huang rte_free(ifpga_dev->vdev_name[i]); 1830ae835abaSWei Huang ifpga_dev->vdev_name[i] = NULL; 1831ae835abaSWei Huang } 1832473c88f9SBruce Richardson 1833473c88f9SBruce Richardson return ret; 1834473c88f9SBruce Richardson } 1835473c88f9SBruce Richardson 1836b412ffa8SWei Huang static int cmp_dev_name(const struct rte_device *dev, const void *_name) 1837b412ffa8SWei Huang { 1838b412ffa8SWei Huang const char *name = _name; 1839b412ffa8SWei Huang return strcmp(dev->name, name); 1840b412ffa8SWei Huang } 1841b412ffa8SWei Huang 1842473c88f9SBruce Richardson static int 1843473c88f9SBruce Richardson ifpga_cfg_remove(struct rte_vdev_device *vdev) 1844473c88f9SBruce Richardson { 1845ae835abaSWei Huang struct rte_rawdev *rawdev = NULL; 1846ae835abaSWei Huang struct ifpga_rawdev *ifpga_dev; 1847ae835abaSWei Huang struct ifpga_vdev_args args; 1848b412ffa8SWei Huang struct rte_bus *bus; 1849ae835abaSWei Huang char dev_name[RTE_RAWDEV_NAME_MAX_LEN]; 1850ae835abaSWei Huang const char *vdev_name = NULL; 1851ae835abaSWei Huang char *tmp_vdev = NULL; 1852ae835abaSWei Huang int i, ret = 0; 1853473c88f9SBruce Richardson 1854ae835abaSWei Huang vdev_name = rte_vdev_device_name(vdev); 1855ae835abaSWei Huang if (!vdev_name) 1856ae835abaSWei Huang return -EINVAL; 1857ae835abaSWei Huang 1858ae835abaSWei Huang IFPGA_RAWDEV_PMD_INFO("remove ifpga virtual device %s", vdev_name); 1859ae835abaSWei Huang 1860ae835abaSWei Huang ret = ifpga_vdev_parse_devargs(vdev->device.devargs, &args); 1861ae835abaSWei Huang if (ret) 1862ae835abaSWei Huang return ret; 1863ae835abaSWei Huang 1864ae835abaSWei Huang memset(dev_name, 0, sizeof(dev_name)); 1865ae835abaSWei Huang snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", args.bdf); 1866ae835abaSWei Huang rawdev = rte_rawdev_pmd_get_named_dev(dev_name); 1867ae835abaSWei Huang if (!rawdev) 1868ae835abaSWei Huang return -ENODEV; 1869ae835abaSWei Huang ifpga_dev = ifpga_rawdev_get(rawdev); 1870ae835abaSWei Huang if (!ifpga_dev) 1871ae835abaSWei Huang return -ENODEV; 1872ae835abaSWei Huang 1873ae835abaSWei Huang snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s", 1874ae835abaSWei Huang args.port, args.bdf); 1875b412ffa8SWei Huang bus = rte_bus_find_by_name(RTE_STR(IFPGA_BUS_NAME)); 1876b412ffa8SWei Huang if (bus) { 1877b412ffa8SWei Huang if (bus->find_device(NULL, cmp_dev_name, dev_name)) { 1878b412ffa8SWei Huang ret = rte_eal_hotplug_remove(RTE_STR(IFPGA_BUS_NAME), 1879b412ffa8SWei Huang dev_name); 1880b412ffa8SWei Huang } 1881b412ffa8SWei Huang } 1882ae835abaSWei Huang 1883ae835abaSWei Huang for (i = 0; i < IFPGA_MAX_VDEV; i++) { 1884ae835abaSWei Huang tmp_vdev = ifpga_dev->vdev_name[i]; 1885ae835abaSWei Huang if (tmp_vdev && !strcmp(tmp_vdev, vdev_name)) { 1886ae835abaSWei Huang free(tmp_vdev); 1887ae835abaSWei Huang ifpga_dev->vdev_name[i] = NULL; 1888ae835abaSWei Huang break; 1889ae835abaSWei Huang } 1890ae835abaSWei Huang } 1891ae835abaSWei Huang 1892ae835abaSWei Huang return ret; 1893473c88f9SBruce Richardson } 1894473c88f9SBruce Richardson 1895473c88f9SBruce Richardson static struct rte_vdev_driver ifpga_cfg_driver = { 1896473c88f9SBruce Richardson .probe = ifpga_cfg_probe, 1897473c88f9SBruce Richardson .remove = ifpga_cfg_remove, 1898473c88f9SBruce Richardson }; 1899473c88f9SBruce Richardson 1900473c88f9SBruce Richardson RTE_PMD_REGISTER_VDEV(ifpga_rawdev_cfg, ifpga_cfg_driver); 1901473c88f9SBruce Richardson RTE_PMD_REGISTER_ALIAS(ifpga_rawdev_cfg, ifpga_cfg); 1902473c88f9SBruce Richardson RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg, 1903473c88f9SBruce Richardson "ifpga=<string> " 1904473c88f9SBruce Richardson "port=<int> " 1905473c88f9SBruce Richardson "afu_bts=<path>"); 1906f724a802SWei Huang 1907f724a802SWei Huang int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port, 1908f724a802SWei Huang const char *file) 1909f724a802SWei Huang { 1910f724a802SWei Huang if (!dev) { 1911f724a802SWei Huang IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid"); 1912f724a802SWei Huang return -EINVAL; 1913f724a802SWei Huang } 1914f724a802SWei Huang 1915f724a802SWei Huang return rte_fpga_do_pr(dev, port, file); 1916f724a802SWei Huang } 1917f724a802SWei Huang 1918f724a802SWei Huang void ifpga_rawdev_cleanup(void) 1919f724a802SWei Huang { 1920f724a802SWei Huang struct ifpga_rawdev *dev; 1921f724a802SWei Huang unsigned int i; 1922f724a802SWei Huang 1923f724a802SWei Huang for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { 1924f724a802SWei Huang dev = &ifpga_rawdevices[i]; 1925f724a802SWei Huang if (dev->rawdev) { 1926f724a802SWei Huang rte_rawdev_pmd_release(dev->rawdev); 1927f724a802SWei Huang dev->rawdev = NULL; 1928f724a802SWei Huang } 1929f724a802SWei Huang } 1930f724a802SWei Huang } 1931