X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fraw%2Fifpga%2Fifpga_rawdev.c;h=8d9db585a4ce67e2b65d2dfe2aaa83d5cc2a82f0;hb=3378e71244b2b2a1a14f94ece735352b5c34dd99;hp=49bfaac2ad6cc5f3e1a7b7b431b56a783850865d;hpb=4a19f89104f8a021b7346db6216d2f723a2ffb86;p=dpdk.git diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 49bfaac2ad..8d9db585a4 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -41,14 +41,6 @@ #include "ifpga_rawdev.h" #include "ipn3ke_rawdev_api.h" -#define RTE_PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */ -#define RTE_PCI_CFG_SPACE_SIZE 256 -#define RTE_PCI_CFG_SPACE_EXP_SIZE 4096 -#define RTE_PCI_EXT_CAP_ID(header) (int)(header & 0x0000ffff) -#define RTE_PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) - -int ifpga_rawdev_logtype; - #define PCI_VENDOR_ID_INTEL 0x8086 /* PCI Device ID */ #define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD @@ -79,13 +71,17 @@ static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM]; static int ifpga_monitor_start; static pthread_t ifpga_monitor_start_thread; +#define IFPGA_MAX_IRQ 12 +/* 0 for FME interrupt, others are reserved for AFU irq */ +static struct rte_intr_handle *ifpga_irq_handle[IFPGA_MAX_IRQ]; + static struct ifpga_rawdev * ifpga_rawdev_allocate(struct rte_rawdev *rawdev); static int set_surprise_link_check_aer( struct ifpga_rawdev *ifpga_rdev, int force_disable); static int ifpga_pci_find_next_ext_capability(unsigned int fd, - int start, int cap); -static int ifpga_pci_find_ext_capability(unsigned int fd, int cap); + int start, uint32_t cap); +static int ifpga_pci_find_ext_capability(unsigned int fd, uint32_t cap); struct ifpga_rawdev * ifpga_rawdev_get(const struct rte_rawdev *rawdev) @@ -142,8 +138,8 @@ ifpga_rawdev_allocate(struct rte_rawdev *rawdev) return dev; } -static int ifpga_pci_find_next_ext_capability(unsigned int fd, -int start, int cap) +static int +ifpga_pci_find_next_ext_capability(unsigned int fd, int start, uint32_t cap) { uint32_t header; int ttl; @@ -181,7 +177,8 @@ int start, int cap) return 0; } -static int ifpga_pci_find_ext_capability(unsigned int fd, int cap) +static int +ifpga_pci_find_ext_capability(unsigned int fd, uint32_t cap) { return ifpga_pci_find_next_ext_capability(fd, 0, cap); } @@ -233,8 +230,9 @@ static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev, memset(link, 0, sizeof(link)); memset(link1, 0, sizeof(link1)); ret = readlink(path, link, (sizeof(link)-1)); - if (ret == -1) + if ((ret < 0) || ((unsigned int)ret > (sizeof(link)-1))) return -1; + link[ret] = 0; /* terminate string with null character */ strlcpy(link1, link, sizeof(link1)); memset(ifpga_dev->parent_bdf, 0, 16); point = strlen(link); @@ -528,10 +526,10 @@ ifpga_monitor_start_func(void) int ret; if (ifpga_monitor_start == 0) { - ret = pthread_create(&ifpga_monitor_start_thread, - NULL, - ifpga_rawdev_gsd_handle, NULL); - if (ret) { + ret = rte_ctrl_thread_create(&ifpga_monitor_start_thread, + "ifpga-monitor", NULL, + ifpga_rawdev_gsd_handle, NULL); + if (ret != 0) { IFPGA_RAWDEV_PMD_ERR( "Fail to create ifpga nonitor thread"); return -1; @@ -601,9 +599,10 @@ ifpga_fill_afu_dev(struct opae_accelerator *acc, return 0; } -static void +static int ifpga_rawdev_info_get(struct rte_rawdev *dev, - rte_rawdev_obj_t dev_info) + rte_rawdev_obj_t dev_info, + size_t dev_info_size) { struct opae_adapter *adapter; struct opae_accelerator *acc; @@ -615,14 +614,14 @@ ifpga_rawdev_info_get(struct rte_rawdev *dev, IFPGA_RAWDEV_PMD_FUNC_TRACE(); - if (!dev_info) { + if (!dev_info || dev_info_size != sizeof(*afu_dev)) { IFPGA_RAWDEV_PMD_ERR("Invalid request"); - return; + return -EINVAL; } adapter = ifpga_rawdev_get_priv(dev); if (!adapter) - return; + return -ENOENT; afu_dev = dev_info; afu_dev->rawdev = dev; @@ -634,7 +633,7 @@ ifpga_rawdev_info_get(struct rte_rawdev *dev, if (ifpga_fill_afu_dev(acc, afu_dev)) { IFPGA_RAWDEV_PMD_ERR("cannot get info\n"); - return; + return -ENOENT; } } @@ -644,21 +643,21 @@ ifpga_rawdev_info_get(struct rte_rawdev *dev, /* get LineSide BAR Index */ if (opae_manager_get_eth_group_region_info(mgr, 0, &opae_lside_eth_info)) { - return; + return -ENOENT; } lside_bar_idx = opae_lside_eth_info.mem_idx; /* get NICSide BAR Index */ if (opae_manager_get_eth_group_region_info(mgr, 1, &opae_nside_eth_info)) { - return; + return -ENOENT; } nside_bar_idx = opae_nside_eth_info.mem_idx; if (lside_bar_idx >= PCI_MAX_RESOURCE || nside_bar_idx >= PCI_MAX_RESOURCE || lside_bar_idx == nside_bar_idx) - return; + return -ENOENT; /* fill LineSide BAR Index */ afu_dev->mem_resource[lside_bar_idx].phys_addr = @@ -676,11 +675,13 @@ ifpga_rawdev_info_get(struct rte_rawdev *dev, afu_dev->mem_resource[nside_bar_idx].addr = opae_nside_eth_info.addr; } + return 0; } static int ifpga_rawdev_configure(const struct rte_rawdev *dev, - rte_rawdev_obj_t config) + rte_rawdev_obj_t config, + size_t config_size __rte_unused) { IFPGA_RAWDEV_PMD_FUNC_TRACE(); @@ -715,6 +716,16 @@ ifpga_rawdev_stop(struct rte_rawdev *dev) static int ifpga_rawdev_close(struct rte_rawdev *dev) { + struct opae_adapter *adapter; + + if (dev) { + adapter = ifpga_rawdev_get_priv(dev); + if (adapter) { + opae_adapter_destroy(adapter); + opae_adapter_data_free(adapter->data); + } + } + return dev ? 0:1; } @@ -775,7 +786,7 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, int file_fd; int ret = 0; ssize_t buffer_size; - void *buffer; + void *buffer, *buf_to_free; u64 pr_error; if (!file_name) @@ -807,6 +818,7 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, ret = -ENOMEM; goto close_fd; } + buf_to_free = buffer; /*read the raw data*/ if (buffer_size != read(file_fd, (void *)buffer, buffer_size)) { @@ -824,8 +836,8 @@ rte_fpga_do_pr(struct rte_rawdev *rawdev, int port_id, } free_buffer: - if (buffer) - rte_free(buffer); + if (buf_to_free) + rte_free(buf_to_free); close_fd: close(file_fd); file_fd = 0; @@ -1328,50 +1340,122 @@ fme_interrupt_handler(void *param) fme_err_handle_catfatal_error(mgr); } -static struct rte_intr_handle fme_intr_handle; +int +ifpga_unregister_msix_irq(enum ifpga_irq_type type, + int vec_start, rte_intr_callback_fn handler, void *arg) +{ + struct rte_intr_handle *intr_handle; + int rc, i; + + if (type == IFPGA_FME_IRQ) + intr_handle = ifpga_irq_handle[0]; + else if (type == IFPGA_AFU_IRQ) + intr_handle = ifpga_irq_handle[vec_start + 1]; + else + return 0; + + rte_intr_efd_disable(intr_handle); + + rc = rte_intr_callback_unregister(intr_handle, handler, arg); + + for (i = 0; i < IFPGA_MAX_IRQ; i++) + rte_intr_instance_free(ifpga_irq_handle[i]); + return rc; +} -static int ifpga_register_fme_interrupt(struct opae_manager *mgr) +int +ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, + enum ifpga_irq_type type, int vec_start, int count, + rte_intr_callback_fn handler, const char *name, + void *arg) { int ret; - struct fpga_fme_err_irq_set err_irq_set; - - fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX; + struct rte_intr_handle *intr_handle; + struct opae_adapter *adapter; + struct opae_manager *mgr; + struct opae_accelerator *acc; + int *intr_efds = NULL, nb_intr, i; - ret = rte_intr_efd_enable(&fme_intr_handle, 1); - if (ret) - return -EINVAL; + for (i = 0; i < IFPGA_MAX_IRQ; i++) { + ifpga_irq_handle[i] = + rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE); + if (ifpga_irq_handle[i] == NULL) + return -ENOMEM; + } - fme_intr_handle.fd = fme_intr_handle.efds[0]; + adapter = ifpga_rawdev_get_priv(dev); + if (!adapter) + return -ENODEV; - IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n", - fme_intr_handle.vfio_dev_fd, - fme_intr_handle.efds[0], fme_intr_handle.fd); + mgr = opae_adapter_get_mgr(adapter); + if (!mgr) + return -ENODEV; - err_irq_set.evtfd = fme_intr_handle.efds[0]; - ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); - if (ret) + if (type == IFPGA_FME_IRQ) { + intr_handle = ifpga_irq_handle[0]; + count = 1; + } else if (type == IFPGA_AFU_IRQ) { + intr_handle = ifpga_irq_handle[vec_start + 1]; + } else { return -EINVAL; + } - /* register FME interrupt using DPDK API */ - ret = rte_intr_callback_register(&fme_intr_handle, - fme_interrupt_handler, - (void *)mgr); + if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_VFIO_MSIX)) + return -rte_errno; + + ret = rte_intr_efd_enable(intr_handle, count); if (ret) - return -EINVAL; + return -ENODEV; - IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n"); + if (rte_intr_fd_set(intr_handle, + rte_intr_efds_index_get(intr_handle, 0))) + return -rte_errno; - return 0; -} + IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d\n", + name, rte_intr_dev_fd_get(intr_handle), + rte_intr_fd_get(intr_handle)); -static int -ifpga_unregister_fme_interrupt(struct opae_manager *mgr) -{ - rte_intr_efd_disable(&fme_intr_handle); + if (type == IFPGA_FME_IRQ) { + struct fpga_fme_err_irq_set err_irq_set; + err_irq_set.evtfd = rte_intr_efds_index_get(intr_handle, + 0); + + ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); + if (ret) + return -EINVAL; + } else if (type == IFPGA_AFU_IRQ) { + acc = opae_adapter_get_acc(adapter, port_id); + if (!acc) + return -EINVAL; + + nb_intr = rte_intr_nb_intr_get(intr_handle); + + intr_efds = calloc(nb_intr, sizeof(int)); + if (!intr_efds) + return -ENOMEM; + + for (i = 0; i < nb_intr; i++) + intr_efds[i] = rte_intr_efds_index_get(intr_handle, i); + + ret = opae_acc_set_irq(acc, vec_start, count, intr_efds); + if (ret) { + free(intr_efds); + return -EINVAL; + } + } + + /* register interrupt handler using DPDK API */ + ret = rte_intr_callback_register(intr_handle, + handler, (void *)arg); + if (ret) { + free(intr_efds); + return -EINVAL; + } + + IFPGA_RAWDEV_PMD_INFO("success register %s interrupt\n", name); - return rte_intr_callback_unregister(&fme_intr_handle, - fme_interrupt_handler, - (void *)mgr); + free(intr_efds); + return 0; } static int @@ -1394,7 +1478,7 @@ ifpga_rawdev_create(struct rte_pci_device *pci_dev, } memset(name, 0, sizeof(name)); - snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x", + snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, IFPGA_RAWDEV_NAME_FMT, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id()); @@ -1437,7 +1521,7 @@ ifpga_rawdev_create(struct rte_pci_device *pci_dev, data->bus = pci_dev->addr.bus; data->devid = pci_dev->addr.devid; data->function = pci_dev->addr.function; - data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd; + data->vfio_dev_fd = rte_intr_dev_fd_get(pci_dev->intr_handle); adapter = rawdev->dev_private; /* create a opae_adapter based on above device data */ @@ -1463,7 +1547,8 @@ ifpga_rawdev_create(struct rte_pci_device *pci_dev, IFPGA_RAWDEV_PMD_INFO("this is a PF function"); } - ret = ifpga_register_fme_interrupt(mgr); + ret = ifpga_register_msix_irq(rawdev, 0, IFPGA_FME_IRQ, 0, 0, + fme_interrupt_handler, "fme_irq", mgr); if (ret) goto free_adapter_data; @@ -1487,6 +1572,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) char name[RTE_RAWDEV_NAME_MAX_LEN]; struct opae_adapter *adapter; struct opae_manager *mgr; + struct ifpga_rawdev *dev; if (!pci_dev) { IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); @@ -1495,7 +1581,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) } memset(name, 0, sizeof(name)); - snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x", + snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, IFPGA_RAWDEV_NAME_FMT, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); IFPGA_RAWDEV_PMD_INFO("Closing %s on NUMA node %d", @@ -1506,6 +1592,9 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); return -EINVAL; } + dev = ifpga_rawdev_get(rawdev); + if (dev) + dev->rawdev = NULL; adapter = ifpga_rawdev_get_priv(rawdev); if (!adapter) @@ -1515,12 +1604,10 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) if (!mgr) return -ENODEV; - if (ifpga_unregister_fme_interrupt(mgr)) + if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, + fme_interrupt_handler, mgr) < 0) return -EINVAL; - opae_adapter_data_free(adapter->data); - opae_adapter_free(adapter); - /* rte_rawdev_close is called by pmd_release */ ret = rte_rawdev_pmd_release(rawdev); if (ret) @@ -1554,13 +1641,7 @@ static struct rte_pci_driver rte_ifpga_rawdev_pmd = { RTE_PMD_REGISTER_PCI(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci"); - -RTE_INIT(ifpga_rawdev_init_log) -{ - ifpga_rawdev_logtype = rte_log_register("driver.raw.init"); - if (ifpga_rawdev_logtype >= 0) - rte_log_set_level(ifpga_rawdev_logtype, RTE_LOG_NOTICE); -} +RTE_LOG_REGISTER_DEFAULT(ifpga_rawdev_logtype, NOTICE); static const char * const valid_args[] = { #define IFPGA_ARG_NAME "ifpga" @@ -1686,3 +1767,33 @@ RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg, "ifpga= " "port= " "afu_bts="); + +struct rte_pci_bus *ifpga_get_pci_bus(void) +{ + return rte_ifpga_rawdev_pmd.bus; +} + +int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port, + const char *file) +{ + if (!dev) { + IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid"); + return -EINVAL; + } + + return rte_fpga_do_pr(dev, port, file); +} + +void ifpga_rawdev_cleanup(void) +{ + struct ifpga_rawdev *dev; + unsigned int i; + + for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { + dev = &ifpga_rawdevices[i]; + if (dev->rawdev) { + rte_rawdev_pmd_release(dev->rawdev); + dev->rawdev = NULL; + } + } +}