/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
* All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
* are met:
*
- * * Redistributions of source code must retain the above copyright
+ * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
* distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
#include <ctype.h>
#include <rte_string_fns.h>
#include <rte_debug.h>
+#include "rte_pci_dev_ids.h"
#include "eal_filesystem.h"
#include "eal_private.h"
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
+ char filename[PATH_MAX];
char dirname2[PATH_MAX];
char devname[PATH_MAX]; /* contains the /dev/uioX */
void *mapaddr;
unsigned uio_num;
+ unsigned long start,size;
uint64_t phaddr;
uint64_t offset;
uint64_t pagesz;
dev->intr_handle.fd = -1;
/* secondary processes - use already recorded details */
- if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ if ((rte_eal_process_type() != RTE_PROC_PRIMARY) &&
+ (dev->id.vendor_id != PCI_VENDOR_ID_QUMRANET))
return (pci_uio_map_secondary(dev));
/* depending on kernel version, uio can be located in uio/uioX
* or uio:uioX */
rte_snprintf(dirname, sizeof(dirname),
- "/sys/bus/pci/devices/" PCI_PRI_FMT "/uio",
+ SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/uio",
loc->domain, loc->bus, loc->devid, loc->function);
dir = opendir(dirname);
if (dir == NULL) {
/* retry with the parent directory */
rte_snprintf(dirname, sizeof(dirname),
- "/sys/bus/pci/devices/" PCI_PRI_FMT,
+ SYSFS_PCI_DEVICES "/" PCI_PRI_FMT,
loc->domain, loc->bus, loc->devid, loc->function);
dir = opendir(dirname);
/* first try uio%d */
errno = 0;
uio_num = strtoull(e->d_name + shortprefix_len, &endptr, 10);
- if (errno == 0 && endptr != e->d_name) {
+ if (errno == 0 && endptr != (e->d_name + shortprefix_len)) {
rte_snprintf(dirname2, sizeof(dirname2),
"%s/uio%u", dirname, uio_num);
break;
/* then try uio:uio%d */
errno = 0;
uio_num = strtoull(e->d_name + longprefix_len, &endptr, 10);
- if (errno == 0 && endptr != e->d_name) {
+ if (errno == 0 && endptr != (e->d_name + longprefix_len)) {
rte_snprintf(dirname2, sizeof(dirname2),
"%s/uio:uio%u", dirname, uio_num);
break;
return -1;
}
+ if(dev->id.vendor_id == PCI_VENDOR_ID_QUMRANET) {
+ /* get portio size */
+ rte_snprintf(filename, sizeof(filename),
+ "%s/portio/port0/size", dirname2);
+ if (eal_parse_sysfs_value(filename, &size) < 0) {
+ RTE_LOG(ERR, EAL, "%s(): cannot parse size\n",
+ __func__);
+ return -1;
+ }
+
+ /* get portio start */
+ rte_snprintf(filename, sizeof(filename),
+ "%s/portio/port0/start", dirname2);
+ if (eal_parse_sysfs_value(filename, &start) < 0) {
+ RTE_LOG(ERR, EAL, "%s(): cannot parse portio start\n",
+ __func__);
+ return -1;
+ }
+ dev->mem_resource[0].addr = (void *)(uintptr_t)start;
+ dev->mem_resource[0].len = (uint64_t)size;
+ RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%lx with size=0x%lx\n", start, size);
+ /* rte_virtio_pmd does not need any other bar even if available */
+ return (0);
+ }
+
/* allocate the mapping details for secondary processes*/
if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
RTE_LOG(ERR, EAL,
"%s(): cannot store uio mmap details\n", __func__);
return (-1);
}
-
+
rte_snprintf(devname, sizeof(devname), "/dev/uio%u", uio_num);
rte_snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr));
-
+
/* collect info about device mappings */
if ((nb_maps = pci_uio_get_mappings(dirname2, uio_res->maps,
sizeof (uio_res->maps) / sizeof (uio_res->maps[0])))
}
dev->id.subsystem_device_id = (uint16_t)tmp;
+ /* get max_vfs */
+ dev->max_vfs = 0;
+ rte_snprintf(filename, sizeof(filename), "%s/max_vfs", dirname);
+ if (!access(filename, F_OK) &&
+ eal_parse_sysfs_value(filename, &tmp) == 0) {
+ dev->max_vfs = (uint16_t)tmp;
+ }
+
+ /* get numa node */
+ rte_snprintf(filename, sizeof(filename), "%s/numa_node",
+ dirname);
+ if (access(filename, R_OK) != 0) {
+ /* if no NUMA support just set node to 0 */
+ dev->numa_node = -1;
+ } else {
+ if (eal_parse_sysfs_value(filename, &tmp) < 0) {
+ free(dev);
+ return -1;
+ }
+ dev->numa_node = tmp;
+ }
+
/* parse resources */
rte_snprintf(filename, sizeof(filename), "%s/resource", dirname);
if (pci_parse_sysfs_resource(filename, dev) < 0) {
rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
{
struct rte_pci_id *id_table;
-#ifdef RTE_EAL_UNBIND_PORTS
- const char *module_name = NULL;
- int uio_status = -1;
-
- if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO)
- module_name = IGB_UIO_NAME;
-#endif
for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
id_table->subsystem_device_id != PCI_ANY_ID)
continue;
+ struct rte_pci_addr *loc = &dev->addr;
+
+ RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+ loc->domain, loc->bus, loc->devid, loc->function,
+ dev->numa_node);
+
RTE_LOG(DEBUG, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
dev->id.device_id, dr->name);
}
#ifdef RTE_EAL_UNBIND_PORTS
- /* Unbind PCI devices if needed */
- if (module_name != NULL)
- if (pci_switch_module(dr, dev, uio_status, module_name) < 0)
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO) {
+ /* unbind driver and load uio resources for Intel NICs */
+ if (pci_switch_module(dr, dev, 1, IGB_UIO_NAME) < 0)
return -1;
+ } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
+ rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* unbind current driver */
+ if (pci_unbind_kernel_driver(dev) < 0)
+ return -1;
+ }
#else
- /* just map the NIC resources */
- if (pci_uio_map_resource(dev) < 0)
- return -1;
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO)
+ /* just map resources for Intel NICs */
+ if (pci_uio_map_resource(dev) < 0)
+ return -1;
#endif
- /* We always should have BAR0 mapped */
- if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
- dev->mem_resource[0].addr == NULL) {
- RTE_LOG(ERR, EAL,
- "%s(): BAR0 is not mapped\n",
- __func__);
- return (-1);
- }
-
/* reference driver structure */
dev->driver = dr;
/* call the driver devinit() function */
return dr->devinit(dr, dev);
}
- return -1;
+ /* return positive value if driver is not found */
+ return 1;
}
/* Init the PCI EAL subsystem */