Fix PCI vendor_id/device_id detection for SR-IOV devices 67/2467/2
authorDamjan Marion <damarion@cisco.com>
Mon, 22 Aug 2016 22:53:22 +0000 (00:53 +0200)
committerDave Barach <openvpp@barachs.net>
Tue, 23 Aug 2016 12:46:21 +0000 (12:46 +0000)
Change-Id: I06ae392c7c8c3b4be7fd46560add442f42927c22
Signed-off-by: Damjan Marion <damarion@cisco.com>
vlib/vlib/pci/linux_pci.c
vlib/vlib/pci/pci.c
vlib/vlib/pci/pci.h
vnet/vnet/devices/dpdk/init.c

index acd913a..f9ee47a 100644 (file)
@@ -99,12 +99,9 @@ vlib_pci_bind_to_uio (vlib_pci_device_t * d, char *uio_driver_name)
   DIR *dir = 0;
   struct dirent *e;
   int fd;
-  pci_config_header_t *c;
   u8 *dev_dir_name = format (0, "/sys/bus/pci/devices/%U",
                             format_vlib_pci_addr, &d->bus_address);
 
-  c = &d->config0.header;
-
   /* if uio sub-directory exists, we are fine, device is
      already bound to UIO driver */
   s = format (s, "%v/uio%c", dev_dir_name, 0);
@@ -186,7 +183,7 @@ vlib_pci_bind_to_uio (vlib_pci_device_t * d, char *uio_driver_name)
   vec_reset_length (s);
 
   s = format (s, "/sys/bus/pci/drivers/%s/new_id%c", uio_driver_name, 0);
-  vlib_sysfs_write ((char *) s, "0x%04x 0x%04x", c->vendor_id, c->device_id);
+  vlib_sysfs_write ((char *) s, "0x%04x 0x%04x", d->vendor_id, d->device_id);
   vec_reset_length (s);
 
   s = format (s, "/sys/bus/pci/drivers/%s/bind%c", uio_driver_name, 0);
@@ -427,17 +424,14 @@ init_device_from_registered (vlib_main_t * vm,
   vlib_pci_main_t *pm = &pci_main;
   pci_device_registration_t *r;
   pci_device_id_t *i;
-  pci_config_header_t *c;
   clib_error_t *error;
 
-  c = &dev->config0.header;
-
   r = pm->pci_device_registrations;
 
   while (r)
     {
       for (i = r->supported_devices; i->vendor_id != 0; i++)
-       if (i->vendor_id == c->vendor_id && i->device_id == c->device_id)
+       if (i->vendor_id == dev->vendor_id && i->device_id == dev->device_id)
          {
            error = vlib_pci_bind_to_uio (dev, "uio_pci_generic");
            if (error)
@@ -474,6 +468,7 @@ scan_device (void *arg, u8 * dev_dir_name, u8 * ignored)
   clib_error_t *error = 0;
   vlib_pci_device_t *dev;
   linux_pci_device_t pdev = { 0 };
+  u32 tmp;
 
   f = format (0, "%v/config%c", dev_dir_name, 0);
   fd = open ((char *) f, O_RDWR);
@@ -592,6 +587,21 @@ scan_device (void *arg, u8 * dev_dir_name, u8 * ignored)
   f = format (f, "%v/numa_node%c", dev_dir_name, 0);
   vlib_sysfs_read ((char *) f, "%u", &dev->numa_node);
 
+  vec_reset_length (f);
+  f = format (f, "%v/class%c", dev_dir_name, 0);
+  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
+  dev->device_class = tmp >> 8;
+
+  vec_reset_length (f);
+  f = format (f, "%v/vendor%c", dev_dir_name, 0);
+  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
+  dev->vendor_id = tmp;
+
+  vec_reset_length (f);
+  f = format (f, "%v/device%c", dev_dir_name, 0);
+  vlib_sysfs_read ((char *) f, "0x%x", &tmp);
+  dev->device_id = tmp;
+
 done:
   vec_free (f);
   return error;
index 73ae541..07d89fd 100644 (file)
@@ -58,7 +58,6 @@ show_pci_fn (vlib_main_t * vm,
 {
   vlib_pci_main_t *pm = &pci_main;
   vlib_pci_device_t *d;
-  pci_config_header_t *c;
   int show_all = 0;
   u8 *s = 0;
 
@@ -77,9 +76,8 @@ show_pci_fn (vlib_main_t * vm,
 
   /* *INDENT-OFF* */
   pool_foreach (d, pm->pci_devs, ({
-    c = &d->config0.header;
 
-    if (c->device_class != PCI_CLASS_NETWORK_ETHERNET && !show_all)
+    if (d->device_class != PCI_CLASS_NETWORK_ETHERNET && !show_all)
       continue;
 
     vec_reset_length (s);
@@ -89,7 +87,7 @@ show_pci_fn (vlib_main_t * vm,
 
     vlib_cli_output (vm, "%-13U%-7v%04x:%04x   %-15U%-20s%-40v",
                     format_vlib_pci_addr, &d->bus_address, s,
-                    c->vendor_id, c->device_id,
+                    d->vendor_id, d->device_id,
                     format_vlib_pci_link_speed, d,
                     d->driver_name ? (char *) d->driver_name : "",
                     d->product_name);
index 06e10b8..3b83b89 100644 (file)
@@ -74,6 +74,11 @@ typedef struct vlib_pci_device
   /* Numa Node */
   int numa_node;
 
+  /* Device data */
+  u16 device_class;
+  u16 vendor_id;
+  u16 device_id;
+
   /* Vital Product Data */
   u8 *product_name;
   u8 *vpd_r;
index afaaa85..2ecfa38 100644 (file)
@@ -833,18 +833,16 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
   vlib_pci_main_t *pm = &pci_main;
   clib_error_t *error;
   vlib_pci_device_t *d;
-  pci_config_header_t *c;
   u8 *pci_addr = 0;
   int num_whitelisted = vec_len (conf->dev_confs);
 
   /* *INDENT-OFF* */
   pool_foreach (d, pm->pci_devs, ({
     dpdk_device_config_t * devconf = 0;
-    c = &d->config0.header;
     vec_reset_length (pci_addr);
     pci_addr = format (pci_addr, "%U%c", format_vlib_pci_addr, &d->bus_address, 0);
 
-    if (c->device_class != PCI_CLASS_NETWORK_ETHERNET)
+    if (d->device_class != PCI_CLASS_NETWORK_ETHERNET)
       continue;
 
     if (num_whitelisted)
@@ -858,24 +856,24 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
       }
 
     /* virtio */
-    if (c->vendor_id == 0x1af4 && c->device_id == 0x1000)
+    if (d->vendor_id == 0x1af4 && d->device_id == 0x1000)
       ;
     /* vmxnet3 */
-    else if (c->vendor_id == 0x15ad && c->device_id == 0x07b0)
+    else if (d->vendor_id == 0x15ad && d->device_id == 0x07b0)
       ;
     /* all Intel devices */
-    else if (c->vendor_id == 0x8086)
+    else if (d->vendor_id == 0x8086)
       ;
     /* Cisco VIC */
-    else if (c->vendor_id == 0x1137 && c->device_id == 0x0043)
+    else if (d->vendor_id == 0x1137 && d->device_id == 0x0043)
       ;
     /* Chelsio T4/T5 */
-    else if (c->vendor_id == 0x1425 && (c->device_id & 0xe000) == 0x4000)
+    else if (d->vendor_id == 0x1425 && (d->device_id & 0xe000) == 0x4000)
       ;
     else
       {
         clib_warning ("Unsupported Ethernet PCI device 0x%04x:0x%04x found "
-                     "at PCI address %s\n", (u16) c->vendor_id, (u16) c->device_id,
+                     "at PCI address %s\n", (u16) d->vendor_id, (u16) d->device_id,
                      pci_addr);
         continue;
       }