net/bonding: use local prefix namespace
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_pci.c
index 7897e15..cee4b94 100644 (file)
@@ -41,6 +41,7 @@
 #include <rte_malloc.h>
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
+#include <rte_vfio.h>
 
 #include "eal_filesystem.h"
 #include "eal_private.h"
@@ -88,7 +89,7 @@ pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
 
 /* Map pci device */
 int
-rte_eal_pci_map_device(struct rte_pci_device *dev)
+rte_pci_map_device(struct rte_pci_device *dev)
 {
        int ret = -1;
 
@@ -119,7 +120,7 @@ rte_eal_pci_map_device(struct rte_pci_device *dev)
 
 /* Unmap pci device */
 void
-rte_eal_pci_unmap_device(struct rte_pci_device *dev)
+rte_pci_unmap_device(struct rte_pci_device *dev)
 {
        /* try unmapping the NIC resources using VFIO if it exists */
        switch (dev->kdrv) {
@@ -310,20 +311,21 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
                        dev->max_vfs = (uint16_t)tmp;
        }
 
-       /* get numa node */
+       /* get numa node, default to 0 if not present */
        snprintf(filename, sizeof(filename), "%s/numa_node",
                 dirname);
-       if (access(filename, R_OK) != 0) {
-               /* if no NUMA support, set default to 0 */
-               dev->device.numa_node = 0;
+
+       if (access(filename, F_OK) != -1) {
+               if (eal_parse_sysfs_value(filename, &tmp) == 0)
+                       dev->device.numa_node = tmp;
+               else
+                       dev->device.numa_node = -1;
        } else {
-               if (eal_parse_sysfs_value(filename, &tmp) < 0) {
-                       free(dev);
-                       return -1;
-               }
-               dev->device.numa_node = tmp;
+               dev->device.numa_node = 0;
        }
 
+       pci_name_set(dev);
+
        /* parse resources */
        snprintf(filename, sizeof(filename), "%s/resource", dirname);
        if (pci_parse_sysfs_resource(filename, dev) < 0) {
@@ -355,21 +357,22 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
 
        /* device is valid, add in list (sorted) */
        if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
-               rte_eal_pci_add_device(dev);
+               rte_pci_add_device(dev);
        } else {
                struct rte_pci_device *dev2;
                int ret;
 
                TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) {
-                       ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
+                       ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr);
                        if (ret > 0)
                                continue;
 
                        if (ret < 0) {
-                               rte_eal_pci_insert_device(dev2, dev);
+                               rte_pci_insert_device(dev2, dev);
                        } else { /* already registered */
                                dev2->kdrv = dev->kdrv;
                                dev2->max_vfs = dev->max_vfs;
+                               pci_name_set(dev2);
                                memmove(dev2->mem_resource, dev->mem_resource,
                                        sizeof(dev->mem_resource));
                                free(dev);
@@ -377,7 +380,7 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
                        return 0;
                }
 
-               rte_eal_pci_add_device(dev);
+               rte_pci_add_device(dev);
        }
 
        return 0;
@@ -427,10 +430,10 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
 
        /* now convert to int values */
        errno = 0;
-       addr->domain = (uint16_t)strtoul(splitaddr.domain, NULL, 16);
-       addr->bus = (uint8_t)strtoul(splitaddr.bus, NULL, 16);
-       addr->devid = (uint8_t)strtoul(splitaddr.devid, NULL, 16);
-       addr->function = (uint8_t)strtoul(splitaddr.function, NULL, 10);
+       addr->domain = strtoul(splitaddr.domain, NULL, 16);
+       addr->bus = strtoul(splitaddr.bus, NULL, 16);
+       addr->devid = strtoul(splitaddr.devid, NULL, 16);
+       addr->function = strtoul(splitaddr.function, NULL, 10);
        if (errno != 0)
                goto error;
 
@@ -446,7 +449,7 @@ error:
  * list
  */
 int
-rte_eal_pci_scan(void)
+rte_pci_scan(void)
 {
        struct dirent *e;
        DIR *dir;
@@ -454,9 +457,14 @@ rte_eal_pci_scan(void)
        struct rte_pci_addr addr;
 
        /* for debug purposes, PCI can be disabled */
-       if (internal_config.no_pci)
+       if (!rte_eal_has_pci())
                return 0;
 
+#ifdef VFIO_PRESENT
+       if (!pci_vfio_is_enabled())
+               RTE_LOG(DEBUG, EAL, "VFIO PCI modules not loaded\n");
+#endif
+
        dir = opendir(pci_get_sysfs_path());
        if (dir == NULL) {
                RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
@@ -485,9 +493,104 @@ error:
        return -1;
 }
 
+/*
+ * Is pci device bound to any kdrv
+ */
+static inline int
+pci_one_device_is_bound(void)
+{
+       struct rte_pci_device *dev = NULL;
+       int ret = 0;
+
+       FOREACH_DEVICE_ON_PCIBUS(dev) {
+               if (dev->kdrv == RTE_KDRV_UNKNOWN ||
+                   dev->kdrv == RTE_KDRV_NONE) {
+                       continue;
+               } else {
+                       ret = 1;
+                       break;
+               }
+       }
+       return ret;
+}
+
+/*
+ * Any one of the device bound to uio
+ */
+static inline int
+pci_one_device_bound_uio(void)
+{
+       struct rte_pci_device *dev = NULL;
+
+       FOREACH_DEVICE_ON_PCIBUS(dev) {
+               if (dev->kdrv == RTE_KDRV_IGB_UIO ||
+                  dev->kdrv == RTE_KDRV_UIO_GENERIC) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Any one of the device has iova as va
+ */
+static inline int
+pci_one_device_has_iova_va(void)
+{
+       struct rte_pci_device *dev = NULL;
+       struct rte_pci_driver *drv = NULL;
+
+       FOREACH_DRIVER_ON_PCIBUS(drv) {
+               if (drv && drv->drv_flags & RTE_PCI_DRV_IOVA_AS_VA) {
+                       FOREACH_DEVICE_ON_PCIBUS(dev) {
+                               if (dev->kdrv == RTE_KDRV_VFIO &&
+                                   rte_pci_match(drv, dev))
+                                       return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+/*
+ * Get iommu class of PCI devices on the bus.
+ */
+enum rte_iova_mode
+rte_pci_get_iommu_class(void)
+{
+       bool is_bound;
+       bool is_vfio_noiommu_enabled = true;
+       bool has_iova_va;
+       bool is_bound_uio;
+
+       is_bound = pci_one_device_is_bound();
+       if (!is_bound)
+               return RTE_IOVA_DC;
+
+       has_iova_va = pci_one_device_has_iova_va();
+       is_bound_uio = pci_one_device_bound_uio();
+#ifdef VFIO_PRESENT
+       is_vfio_noiommu_enabled = vfio_noiommu_is_enabled() == true ?
+                                       true : false;
+#endif
+
+       if (has_iova_va && !is_bound_uio && !is_vfio_noiommu_enabled)
+               return RTE_IOVA_VA;
+
+       if (has_iova_va) {
+               RTE_LOG(WARNING, EAL, "Some devices want iova as va but pa will be used because.. ");
+               if (is_vfio_noiommu_enabled)
+                       RTE_LOG(WARNING, EAL, "vfio-noiommu mode configured\n");
+               if (is_bound_uio)
+                       RTE_LOG(WARNING, EAL, "few device bound to UIO\n");
+       }
+
+       return RTE_IOVA_PA;
+}
+
 /* Read PCI config space. */
-int rte_eal_pci_read_config(const struct rte_pci_device *device,
-                           void *buf, size_t len, off_t offset)
+int rte_pci_read_config(const struct rte_pci_device *device,
+               void *buf, size_t len, off_t offset)
 {
        const struct rte_intr_handle *intr_handle = &device->intr_handle;
 
@@ -511,8 +614,8 @@ int rte_eal_pci_read_config(const struct rte_pci_device *device,
 }
 
 /* Write PCI config space. */
-int rte_eal_pci_write_config(const struct rte_pci_device *device,
-                            const void *buf, size_t len, off_t offset)
+int rte_pci_write_config(const struct rte_pci_device *device,
+               const void *buf, size_t len, off_t offset)
 {
        const struct rte_intr_handle *intr_handle = &device->intr_handle;
 
@@ -538,7 +641,7 @@ int rte_eal_pci_write_config(const struct rte_pci_device *device,
 #if defined(RTE_ARCH_X86)
 static int
 pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
-              struct rte_pci_ioport *p)
+               struct rte_pci_ioport *p)
 {
        uint16_t start, end;
        FILE *fp;
@@ -596,8 +699,8 @@ pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
 #endif
 
 int
-rte_eal_pci_ioport_map(struct rte_pci_device *dev, int bar,
-                      struct rte_pci_ioport *p)
+rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
+               struct rte_pci_ioport *p)
 {
        int ret = -1;
 
@@ -634,8 +737,8 @@ rte_eal_pci_ioport_map(struct rte_pci_device *dev, int bar,
 }
 
 void
-rte_eal_pci_ioport_read(struct rte_pci_ioport *p,
-                       void *data, size_t len, off_t offset)
+rte_pci_ioport_read(struct rte_pci_ioport *p,
+               void *data, size_t len, off_t offset)
 {
        switch (p->dev->kdrv) {
 #ifdef VFIO_PRESENT
@@ -660,8 +763,8 @@ rte_eal_pci_ioport_read(struct rte_pci_ioport *p,
 }
 
 void
-rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
-                        const void *data, size_t len, off_t offset)
+rte_pci_ioport_write(struct rte_pci_ioport *p,
+               const void *data, size_t len, off_t offset)
 {
        switch (p->dev->kdrv) {
 #ifdef VFIO_PRESENT
@@ -686,7 +789,7 @@ rte_eal_pci_ioport_write(struct rte_pci_ioport *p,
 }
 
 int
-rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
+rte_pci_ioport_unmap(struct rte_pci_ioport *p)
 {
        int ret = -1;