From b1b1a14977f77d9805dd2cb11c7e8ddfc404818a Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Tue, 23 Aug 2016 00:53:22 +0200 Subject: [PATCH] Fix PCI vendor_id/device_id detection for SR-IOV devices Change-Id: I06ae392c7c8c3b4be7fd46560add442f42927c22 Signed-off-by: Damjan Marion --- vlib/vlib/pci/linux_pci.c | 26 ++++++++++++++++++-------- vlib/vlib/pci/pci.c | 6 ++---- vlib/vlib/pci/pci.h | 5 +++++ vnet/vnet/devices/dpdk/init.c | 16 +++++++--------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/vlib/vlib/pci/linux_pci.c b/vlib/vlib/pci/linux_pci.c index acd913a91e7..f9ee47ac145 100644 --- a/vlib/vlib/pci/linux_pci.c +++ b/vlib/vlib/pci/linux_pci.c @@ -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; diff --git a/vlib/vlib/pci/pci.c b/vlib/vlib/pci/pci.c index 73ae541320a..07d89fda233 100644 --- a/vlib/vlib/pci/pci.c +++ b/vlib/vlib/pci/pci.c @@ -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); diff --git a/vlib/vlib/pci/pci.h b/vlib/vlib/pci/pci.h index 06e10b80e59..3b83b89208b 100644 --- a/vlib/vlib/pci/pci.h +++ b/vlib/vlib/pci/pci.h @@ -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; diff --git a/vnet/vnet/devices/dpdk/init.c b/vnet/vnet/devices/dpdk/init.c index afaaa85a221..2ecfa38481a 100644 --- a/vnet/vnet/devices/dpdk/init.c +++ b/vnet/vnet/devices/dpdk/init.c @@ -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; } -- 2.16.6