* [PATCH v3 06/12] eal: add probe and remove support for rte_driver
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
rte_driver now supports probe and remove. These would be used for generic
device type (PCI, etc) probe and remove.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 4004f9a..7d2ab16 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -145,6 +145,16 @@ void rte_eal_device_insert(struct rte_device *dev);
void rte_eal_device_remove(struct rte_device *dev);
/**
+ * Initialisation function for the driver called during probing.
+ */
+typedef int (driver_probe_t)(struct rte_driver *, struct rte_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (driver_remove_t)(struct rte_device *);
+
+/**
* A structure describing a device driver.
*/
struct rte_driver {
@@ -152,6 +162,8 @@ struct rte_driver {
struct rte_bus *bus; /**< Bus serviced by this driver */
const char *name; /**< Driver name. */
const char *alias; /**< Driver alias. */
+ driver_probe_t *probe; /**< Probe the device */
+ driver_remove_t *remove; /**< Remove/hotplugging the device */
};
/**
--
2.7.4
^ permalink raw reply related
* [PATCH v3 07/12] eal: enable probe from bus infrastructure
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
The model is:
rte_eal_init
`--> calls rte_eal_bus_probe()
This iterates over all the drivers and devices and matches them. For
matched bus specific device-driver and calls:
`-> rte_driver->probe()
for all matched device/drivers (rte_bus->match() successful)
This would be responsible for devargs related checks, eventually
calling:
`-> rte_xxx_driver->probe()
which does all the work from eth_dev allocation to init.
(Currently, eth_dev init is done by eth_driver->eth_dev_init,
which would be removed soon)
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/eal_common_bus.c | 51 +++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 5fbfdcc..0dfa800 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -196,11 +196,60 @@ rte_eal_bus_scan(void)
return 0;
}
+static int
+perform_probe(struct rte_bus *bus __rte_unused, struct rte_driver *driver,
+ struct rte_device *device)
+{
+ int ret;
+
+ if (!driver->probe) {
+ RTE_LOG(ERR, EAL, "Driver (%s) doesn't support probe.\n",
+ driver->name);
+ /* This is not an error - just a badly implemented PMD */
+ return 0;
+ }
+
+ ret = driver->probe(driver, device);
+ if (ret < 0)
+ /* One of the probes failed */
+ RTE_LOG(ERR, EAL, "Probe failed for (%s).\n", driver->name);
+
+ /* In either case, ret <0 (error), ret > 0 (not supported) and ret = 0
+ * success, return ret
+ */
+ return ret;
+}
+
/* Match driver<->device and call driver->probe() */
int
rte_eal_bus_probe(void)
{
- /* Until driver->probe is available, this is dummy implementation */
+ int ret;
+ struct rte_bus *bus;
+ struct rte_device *device;
+ struct rte_driver *driver;
+
+ /* For each bus registered with EAL */
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ TAILQ_FOREACH(device, &bus->device_list, next) {
+ TAILQ_FOREACH(driver, &bus->driver_list, next) {
+ ret = bus->match(driver, device);
+ if (!ret) {
+ ret = perform_probe(bus, driver,
+ device);
+ if (ret < 0)
+ return ret;
+
+ device->driver = driver;
+ /* ret == 0 is success; ret >0 implies
+ * driver doesn't support the device.
+ * in either case, continue
+ */
+ }
+ }
+ }
+ }
+
return 0;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v3 08/12] pci: split match and probe function
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
Matching of PCI device address and driver ID table is being done at two
discreet locations duplicating the code. (rte_eal_pci_probe_one_driver
and rte_eal_pci_detach_dev).
Splitting the matching function into rte_eal_pci_match.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/eal_common_pci.c | 198 ++++++++++++++++++--------------
lib/librte_eal/common/include/rte_pci.h | 15 +++
2 files changed, 125 insertions(+), 88 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 6bff675..706f91c 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -152,131 +152,153 @@ pci_unmap_resource(void *requested_addr, size_t size)
requested_addr);
}
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
+int
+rte_eal_pci_match(struct rte_pci_driver *pci_drv,
+ struct rte_pci_device *pci_dev)
{
- int ret;
+ int match = 1;
const struct rte_pci_id *id_table;
- for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
+ if (!pci_drv || !pci_dev || !pci_drv->id_table) {
+ RTE_LOG(DEBUG, EAL, "Invalid PCI Driver object\n");
+ return -1;
+ }
+ for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+ id_table++) {
/* check if device's identifiers match the driver's ones */
- if (id_table->vendor_id != dev->id.vendor_id &&
+ if (id_table->vendor_id != pci_dev->id.vendor_id &&
id_table->vendor_id != PCI_ANY_ID)
continue;
- if (id_table->device_id != dev->id.device_id &&
+ if (id_table->device_id != pci_dev->id.device_id &&
id_table->device_id != PCI_ANY_ID)
continue;
- if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
- id_table->subsystem_vendor_id != PCI_ANY_ID)
+ if (id_table->subsystem_vendor_id !=
+ pci_dev->id.subsystem_vendor_id &&
+ id_table->subsystem_vendor_id != PCI_ANY_ID)
continue;
- if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
- id_table->subsystem_device_id != PCI_ANY_ID)
+ if (id_table->subsystem_device_id !=
+ pci_dev->id.subsystem_device_id &&
+ id_table->subsystem_device_id != PCI_ANY_ID)
continue;
- if (id_table->class_id != dev->id.class_id &&
+ if (id_table->class_id != pci_dev->id.class_id &&
id_table->class_id != RTE_CLASS_ANY_ID)
continue;
- struct rte_pci_addr *loc = &dev->addr;
-
- RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
- loc->domain, loc->bus, loc->devid, loc->function,
- dev->device.numa_node);
-
- /* no initialization when blacklisted, return without error */
- if (dev->device.devargs != NULL &&
- dev->device.devargs->type ==
- RTE_DEVTYPE_BLACKLISTED_PCI) {
- RTE_LOG(INFO, EAL, " Device is blacklisted, not initializing\n");
- return 1;
- }
-
- RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
- dev->id.device_id, dr->driver.name);
-
- if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
- /* map resources for devices that use igb_uio */
- ret = rte_eal_pci_map_device(dev);
- if (ret != 0)
- return ret;
- } 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;
- }
-
- /* reference driver structure */
- dev->driver = dr;
-
- /* call the driver probe() function */
- ret = dr->probe(dr, dev);
- if (ret)
- dev->driver = NULL;
-
- return ret;
+ match = 0;
+ break;
}
- /* return positive value if driver doesn't support this device */
- return 1;
+
+ return match;
}
/*
- * If vendor/device ID match, call the remove() function of the
+ * If vendor/device ID match, call the probe() function of the
* driver.
*/
static int
-rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
- struct rte_pci_device *dev)
+rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
+ struct rte_pci_device *dev)
{
- const struct rte_pci_id *id_table;
+ int ret;
+ struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
+ loc = &dev->addr;
- /* check if device's identifiers match the driver's ones */
- if (id_table->vendor_id != dev->id.vendor_id &&
- id_table->vendor_id != PCI_ANY_ID)
- continue;
- if (id_table->device_id != dev->id.device_id &&
- id_table->device_id != PCI_ANY_ID)
- continue;
- if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
- id_table->subsystem_vendor_id != PCI_ANY_ID)
- continue;
- if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
- id_table->subsystem_device_id != PCI_ANY_ID)
- continue;
+ RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+ loc->domain, loc->bus, loc->devid, loc->function,
+ dev->device.numa_node);
- struct rte_pci_addr *loc = &dev->addr;
+ /* no initialization when blacklisted, return without error */
+ if (dev->device.devargs != NULL &&
+ dev->device.devargs->type ==
+ RTE_DEVTYPE_BLACKLISTED_PCI) {
+ RTE_LOG(INFO, EAL, " Device is blacklisted, not"
+ " initializing\n");
+ return 1;
+ }
- RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
- loc->domain, loc->bus, loc->devid,
- loc->function, dev->device.numa_node);
+ /* The device is not blacklisted; Check if driver supports it */
+ ret = rte_eal_pci_match(dr, dev);
+ if (ret) {
+ /* Match of device and driver failed */
+ RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
+ dr->driver.name);
+ return 1;
+ }
- RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n", dev->id.vendor_id,
- dev->id.device_id, dr->driver.name);
+ RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
+ dev->id.device_id, dr->driver.name);
+
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+ /* map resources for devices that use igb_uio */
+ ret = rte_eal_pci_map_device(dev);
+ if (ret != 0)
+ return ret;
+ } 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;
+ }
- if (dr->remove && (dr->remove(dev) < 0))
- return -1; /* negative value is an error */
+ /* reference driver structure */
+ dev->driver = dr;
- /* clear driver structure */
+ /* call the driver probe() function */
+ ret = dr->probe(dr, dev);
+ if (ret) {
+ RTE_LOG(DEBUG, EAL, "Driver (%s) probe failed.\n",
+ dr->driver.name);
dev->driver = NULL;
+ }
- if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
- /* unmap resources for devices that use igb_uio */
- rte_eal_pci_unmap_device(dev);
+ return ret;
+}
- return 0;
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
+ struct rte_pci_device *dev)
+{
+ int ret;
+ struct rte_pci_addr *loc;
+
+ if ((dr == NULL) || (dev == NULL))
+ return -EINVAL;
+
+ ret = rte_eal_pci_match(dr, dev);
+ if (ret) {
+ /* Device and driver don't match */
+ return 1;
}
- /* return positive value if driver doesn't support this device */
- return 1;
+ 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->device.numa_node);
+
+ RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n", dev->id.vendor_id,
+ dev->id.device_id, dr->driver.name);
+
+ if (dr->remove && (dr->remove(dev) < 0))
+ return -1; /* negative value is an error */
+
+ /* clear driver structure */
+ dev->driver = NULL;
+
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+ /* unmap resources for devices that use igb_uio */
+ rte_eal_pci_unmap_device(dev);
+
+ return 0;
}
/*
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..c9b113d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -369,6 +369,21 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
int rte_eal_pci_scan(void);
/**
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ * PCI driver from which ID table would be extracted
+ * @param pci_dev
+ * PCI device to match against the driver
+ * @return
+ * 0 for successful match
+ * !0 for unsuccessful match
+ */
+int
+rte_eal_pci_match(struct rte_pci_driver *pci_drv,
+ struct rte_pci_device *pci_dev);
+
+/**
* Probe the PCI bus for registered drivers.
*
* Scan the content of the PCI bus, and call the probe() function for
--
2.7.4
^ permalink raw reply related
* [PATCH v3 09/12] eal/pci: generalize args of PCI scan/match towards RTE device/driver
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
PCI scan and match now work on rte_device/rte_driver rather than PCI
specific objects. These functions can now be plugged to the generic
bus callbacks for scanning and matching devices/drivers.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
app/test/test_pci.c | 2 +-
lib/librte_eal/bsdapp/eal/eal_pci.c | 4 ++--
lib/librte_eal/common/eal_common_pci.c | 28 +++++++++++++++++++++-------
lib/librte_eal/common/include/rte_pci.h | 17 ++++++++++-------
lib/librte_eal/linuxapp/eal/eal_pci.c | 4 ++--
5 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index cda186d..f9b84db 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -180,7 +180,7 @@ test_pci_setup(void)
TAILQ_INSERT_TAIL(&real_pci_device_list, dev, next);
}
- ret = rte_eal_pci_scan();
+ ret = rte_eal_pci_scan(NULL);
TEST_ASSERT_SUCCESS(ret, "failed to scan PCI bus");
rte_eal_pci_dump(stdout);
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..10b234e 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -361,7 +361,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
* list. Call pci_scan_one() for each pci entry found.
*/
int
-rte_eal_pci_scan(void)
+rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
{
int fd;
unsigned dev_count = 0;
@@ -676,7 +676,7 @@ rte_eal_pci_init(void)
if (internal_config.no_pci)
return 0;
- if (rte_eal_pci_scan() < 0) {
+ if (rte_eal_pci_scan(NULL) < 0) {
RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
return -1;
}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 706f91c..562c0fd 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -153,17 +153,22 @@ pci_unmap_resource(void *requested_addr, size_t size)
}
int
-rte_eal_pci_match(struct rte_pci_driver *pci_drv,
- struct rte_pci_device *pci_dev)
+rte_eal_pci_match(struct rte_driver *drv,
+ struct rte_device *dev)
{
int match = 1;
const struct rte_pci_id *id_table;
+ struct rte_pci_driver *pci_drv;
+ struct rte_pci_device *pci_dev;
- if (!pci_drv || !pci_dev || !pci_drv->id_table) {
- RTE_LOG(DEBUG, EAL, "Invalid PCI Driver object\n");
+ if (!drv || !dev) {
+ RTE_LOG(DEBUG, EAL, "Invalid Device/Driver\n");
return -1;
}
+ pci_drv = container_of(drv, struct rte_pci_driver, driver);
+ pci_dev = container_of(dev, struct rte_pci_device, device);
+
for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
id_table++) {
/* check if device's identifiers match the driver's ones */
@@ -201,11 +206,15 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
int ret;
+ struct rte_driver *driver;
+ struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
+ driver = &dr->driver;
+ device = &dev->device;
loc = &dev->addr;
RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -222,11 +231,11 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
}
/* The device is not blacklisted; Check if driver supports it */
- ret = rte_eal_pci_match(dr, dev);
+ ret = rte_eal_pci_match(driver, device);
if (ret) {
/* Match of device and driver failed */
RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
- dr->driver.name);
+ driver->name);
return 1;
}
@@ -268,12 +277,17 @@ rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
int ret;
+ struct rte_driver *driver = NULL;
+ struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- ret = rte_eal_pci_match(dr, dev);
+ driver = &(dr->driver);
+ device = &(dev->device);
+
+ ret = rte_eal_pci_match(driver, device);
if (ret) {
/* Device and driver don't match */
return 1;
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index c9b113d..10108a4 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -363,25 +363,28 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
* Scan the content of the PCI bus, and the devices in the devices
* list
*
+ * @param bus
+ * Reference to the PCI bus
+ *
* @return
* 0 on success, negative on error
*/
-int rte_eal_pci_scan(void);
+int rte_eal_pci_scan(struct rte_bus *bus);
/**
* Match the PCI Driver and Device using the ID Table
*
- * @param pci_drv
- * PCI driver from which ID table would be extracted
- * @param pci_dev
- * PCI device to match against the driver
+ * @param drv
+ * driver from which ID table would be extracted
+ * @param dev
+ * device to match against the driver
* @return
* 0 for successful match
* !0 for unsuccessful match
*/
int
-rte_eal_pci_match(struct rte_pci_driver *pci_drv,
- struct rte_pci_device *pci_dev);
+rte_eal_pci_match(struct rte_driver *drv,
+ struct rte_device *dev);
/**
* Probe the PCI bus for registered drivers.
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..bafb7fb 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -485,7 +485,7 @@ parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
* list
*/
int
-rte_eal_pci_scan(void)
+rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
{
struct dirent *e;
DIR *dir;
@@ -763,7 +763,7 @@ rte_eal_pci_init(void)
if (internal_config.no_pci)
return 0;
- if (rte_eal_pci_scan() < 0) {
+ if (rte_eal_pci_scan(NULL) < 0) {
RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
return -1;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v3 10/12] pci: Pass rte_pci_addr to functions instead of separate args
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Ben Walker,
Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
From: Ben Walker <benjamin.walker@intel.com>
Instead of passing domain, bus, devid, func, just pass
an rte_pci_addr.
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
[Shreyansh: Checkpatch error fix]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/linuxapp/eal/eal_pci.c | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index bafb7fb..cbd25df 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -267,8 +267,7 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
/* Scan one pci sysfs entry, and fill the devices list from it. */
static int
-pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
- uint8_t devid, uint8_t function)
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
{
char filename[PATH_MAX];
unsigned long tmp;
@@ -281,10 +280,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
return -1;
memset(dev, 0, sizeof(*dev));
- dev->addr.domain = domain;
- dev->addr.bus = bus;
- dev->addr.devid = devid;
- dev->addr.function = function;
+ dev->addr = *addr;
/* get vendor id */
snprintf(filename, sizeof(filename), "%s/vendor", dirname);
@@ -429,16 +425,14 @@ pci_update_device(const struct rte_pci_addr *addr)
pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
addr->function);
- return pci_scan_one(filename, addr->domain, addr->bus, addr->devid,
- addr->function);
+ return pci_scan_one(filename, addr);
}
/*
* split up a pci address into its constituent parts.
*/
static int
-parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
- uint8_t *bus, uint8_t *devid, uint8_t *function)
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
{
/* first split on ':' */
union splitaddr {
@@ -466,10 +460,10 @@ parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
/* now convert to int values */
errno = 0;
- *domain = (uint16_t)strtoul(splitaddr.domain, NULL, 16);
- *bus = (uint8_t)strtoul(splitaddr.bus, NULL, 16);
- *devid = (uint8_t)strtoul(splitaddr.devid, NULL, 16);
- *function = (uint8_t)strtoul(splitaddr.function, NULL, 10);
+ 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);
if (errno != 0)
goto error;
@@ -490,8 +484,7 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
- uint16_t domain;
- uint8_t bus, devid, function;
+ struct rte_pci_addr addr;
dir = opendir(pci_get_sysfs_path());
if (dir == NULL) {
@@ -500,20 +493,22 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
return -1;
}
+
while ((e = readdir(dir)) != NULL) {
if (e->d_name[0] == '.')
continue;
- if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &domain,
- &bus, &devid, &function) != 0)
+ if (parse_pci_addr_format(e->d_name,
+ sizeof(e->d_name), &addr) != 0)
continue;
snprintf(dirname, sizeof(dirname), "%s/%s",
pci_get_sysfs_path(), e->d_name);
- if (pci_scan_one(dirname, domain, bus, devid, function) < 0)
+ if (pci_scan_one(dirname, &addr) < 0)
goto error;
}
closedir(dir);
+
return 0;
error:
--
2.7.4
^ permalink raw reply related
* [PATCH v3 12/12] drivers: update PMDs to use rte_driver probe and remove
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
These callbacks now act as first layer of PCI interfaces from the Bus.
Bus probe would enter the PMDs through the rte_driver->probe/remove
callbacks, falling to rte_xxx_driver->probe/remove (Currently, all the
drivers are rte_pci_driver).
This patch also changes QAT which is the only crypto PMD based on PCI.
All others would be changed in a separate patch focused on VDEV.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
drivers/crypto/qat/rte_qat_cryptodev.c | 4 ++++
drivers/net/bnx2x/bnx2x_ethdev.c | 8 ++++++++
drivers/net/bnxt/bnxt_ethdev.c | 4 ++++
drivers/net/cxgbe/cxgbe_ethdev.c | 4 ++++
drivers/net/e1000/em_ethdev.c | 4 ++++
drivers/net/e1000/igb_ethdev.c | 8 ++++++++
drivers/net/ena/ena_ethdev.c | 4 ++++
drivers/net/enic/enic_ethdev.c | 4 ++++
drivers/net/fm10k/fm10k_ethdev.c | 4 ++++
drivers/net/i40e/i40e_ethdev.c | 4 ++++
drivers/net/i40e/i40e_ethdev_vf.c | 4 ++++
drivers/net/ixgbe/ixgbe_ethdev.c | 8 ++++++++
drivers/net/mlx4/mlx4.c | 4 +++-
drivers/net/mlx5/mlx5.c | 1 +
drivers/net/nfp/nfp_net.c | 4 ++++
drivers/net/qede/qede_ethdev.c | 8 ++++++++
drivers/net/szedata2/rte_eth_szedata2.c | 4 ++++
drivers/net/thunderx/nicvf_ethdev.c | 4 ++++
drivers/net/virtio/virtio_ethdev.c | 2 ++
drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 ++++
20 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index 1e7ee61..bc1a9c6 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -120,6 +120,10 @@ crypto_qat_dev_init(__attribute__((unused)) struct rte_cryptodev_driver *crypto_
static struct rte_cryptodev_driver rte_qat_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_qat_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_cryptodev_pci_probe,
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 0eae433..9f3b3f2 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -618,6 +618,10 @@ eth_bnx2xvf_dev_init(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_bnx2x_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_bnx2x_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
@@ -632,6 +636,10 @@ static struct eth_driver rte_bnx2x_pmd = {
*/
static struct eth_driver rte_bnx2xvf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_bnx2xvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 035fe07..c8671c8 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1160,6 +1160,10 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
static struct eth_driver bnxt_rte_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = bnxt_pci_id_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING |
RTE_PCI_DRV_DETACHABLE | RTE_PCI_DRV_INTR_LSC,
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index b7f28eb..67714fa 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1039,6 +1039,10 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_cxgbe_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = cxgb4_pci_tbl,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index aee3d34..7be5da3 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -391,6 +391,10 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_em_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_em_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2fddf0c..70dd24c 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1078,6 +1078,10 @@ eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_igb_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_igb_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
@@ -1094,6 +1098,10 @@ static struct eth_driver rte_igb_pmd = {
*/
static struct eth_driver rte_igbvf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_igbvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index ab9a178..54fc8de 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1705,6 +1705,10 @@ static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
static struct eth_driver rte_ena_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_ena_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2b154ec..c2783db 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -634,6 +634,10 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_enic_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_enic_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 923690c..d1a2efa 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -3061,6 +3061,10 @@ static const struct rte_pci_id pci_id_fm10k_map[] = {
static struct eth_driver rte_pmd_fm10k = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_fm10k_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..9c5d50f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -670,6 +670,10 @@ static const struct rte_i40e_xstats_name_off rte_i40e_txq_prio_strings[] = {
static struct eth_driver rte_i40e_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_i40e_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..10bf6ab 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1527,6 +1527,10 @@ i40evf_dev_uninit(struct rte_eth_dev *eth_dev)
*/
static struct eth_driver rte_i40evf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_i40evf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index edc9b22..80ee232 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1564,6 +1564,10 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_ixgbe_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_ixgbe_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
@@ -1580,6 +1584,10 @@ static struct eth_driver rte_ixgbe_pmd = {
*/
static struct eth_driver rte_ixgbevf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_ixgbevf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index da61a85..e3dcd41 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5907,7 +5907,9 @@ static const struct rte_pci_id mlx4_pci_id_map[] = {
static struct eth_driver mlx4_driver = {
.pci_drv = {
.driver = {
- .name = MLX4_DRIVER_NAME
+ .name = MLX4_DRIVER_NAME,
+ .probe = rte_eal_pci_probe,
+ },
},
.id_table = mlx4_pci_id_map,
.probe = mlx4_pci_probe,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 90cc35e..76dda13 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -731,6 +731,7 @@ static struct eth_driver mlx5_driver = {
.pci_drv = {
.driver = {
.name = MLX5_DRIVER_NAME
+ .probe = rte_eal_pci_probe,
},
.id_table = mlx5_pci_id_map,
.probe = mlx5_pci_probe,
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index de80b46..125ba86 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -2469,6 +2469,10 @@ static struct rte_pci_id pci_id_nfp_net_map[] = {
static struct eth_driver rte_nfp_net_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_nfp_net_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index d106dd0..31f6733 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1642,6 +1642,10 @@ static struct rte_pci_id pci_id_qede_map[] = {
static struct eth_driver rte_qedevf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_qedevf_map,
.drv_flags =
RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
@@ -1655,6 +1659,10 @@ static struct eth_driver rte_qedevf_pmd = {
static struct eth_driver rte_qede_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_qede_map,
.drv_flags =
RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index f3cd52d..a649e60 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1572,6 +1572,10 @@ static const struct rte_pci_id rte_szedata2_pci_id_table[] = {
static struct eth_driver szedata2_eth_driver = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = rte_szedata2_pci_id_table,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 466e49c..72ac748 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -2110,6 +2110,10 @@ static const struct rte_pci_id pci_id_nicvf_map[] = {
static struct eth_driver rte_nicvf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_nicvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..4d5d1bb 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1377,6 +1377,8 @@ static struct eth_driver rte_virtio_pmd = {
.pci_drv = {
.driver = {
.name = "net_virtio",
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
},
.id_table = pci_id_virtio_map,
.drv_flags = RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 8bb13e5..57f66cb 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -335,6 +335,10 @@ eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_vmxnet3_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_vmxnet3_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
--
2.7.4
^ permalink raw reply related
* [PATCH v3 11/12] eal: enable PCI bus and PCI test framework
From: Shreyansh Jain @ 2016-12-16 13:10 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com>
Register a PCI bus with Scan/match and probe callbacks. Necessary changes
in EAL layer for enabling bus interfaces. PCI devices and drivers now
reside within the Bus object.
Now that PCI bus handles the scan/probe methods, independent calls to
PCI scan and probe can be removed from the code.
PCI device and driver list are also removed.
rte_device and rte_driver list continue to exist. As does the VDEV lists.
Changes to test_pci:
- use a dummy test_pci_bus for all PCI test driver registrations
- this reduces the need for cleaning global list
- add necessary callbacks for invoking scan and probing/matching
using EAL PCI scan code
Note: With this patch, all PCI PMDs would cease to work because of lack
rte_driver->probe/remove implementations. Next patch would do that.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
app/test/test_pci.c | 154 +++++++++++------
lib/librte_eal/bsdapp/eal/eal.c | 7 -
lib/librte_eal/bsdapp/eal/eal_pci.c | 52 +++---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 7 +-
lib/librte_eal/common/eal_common_pci.c | 212 ++++++++++++++----------
lib/librte_eal/common/eal_private.h | 14 +-
lib/librte_eal/common/include/rte_pci.h | 53 +++---
lib/librte_eal/linuxapp/eal/eal.c | 7 -
lib/librte_eal/linuxapp/eal/eal_pci.c | 57 ++++---
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 7 +-
10 files changed, 330 insertions(+), 240 deletions(-)
diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index f9b84db..e95b758 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -38,6 +38,7 @@
#include <sys/queue.h>
#include <rte_interrupts.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_ethdev.h>
#include <rte_devargs.h>
@@ -61,10 +62,18 @@
int test_pci_run = 0; /* value checked by the multiprocess test */
static unsigned pci_dev_count;
+static struct rte_bus *pci_bus; /* global reference to a Test PCI bus */
static int my_driver_init(struct rte_pci_driver *dr,
struct rte_pci_device *dev);
+/* Test PCI bus. */
+struct rte_bus test_pci_bus = {
+ .name = "test_pci_bus",
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match,
+};
+
/* IXGBE NICS */
struct rte_pci_id my_driver_id[] = {
{RTE_PCI_DEVICE(0x0001, 0x1234)},
@@ -79,7 +88,9 @@ struct rte_pci_id my_driver_id2[] = {
struct rte_pci_driver my_driver = {
.driver = {
- .name = "test_driver"
+ .name = "test_driver",
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
},
.probe = my_driver_init,
.id_table = my_driver_id,
@@ -88,7 +99,9 @@ struct rte_pci_driver my_driver = {
struct rte_pci_driver my_driver2 = {
.driver = {
- .name = "test_driver2"
+ .name = "test_driver2",
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
},
.probe = my_driver_init,
.id_table = my_driver_id2,
@@ -108,14 +121,67 @@ my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
return 0;
}
+/* dump devices on the bus */
+static void
+do_pci_device_dump(FILE *f)
+{
+ int i;
+ struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+
+ TAILQ_FOREACH(r_dev, &pci_bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
+
+ fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+ dev->addr.devid, dev->addr.function);
+ fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+ dev->id.device_id);
+
+ for (i = 0; i != sizeof(dev->mem_resource) /
+ sizeof(dev->mem_resource[0]); i++) {
+ fprintf(f, " %16.16"PRIx64" %16.16"PRIx64"\n",
+ dev->mem_resource[i].phys_addr,
+ dev->mem_resource[i].len);
+ }
+ }
+}
+
+/* Dummy implementation for rte_eal_pci_probe() over test_pci_bus */
+static int
+do_pci_bus_probe(void)
+{
+ int ret;
+ struct rte_device *device;
+ struct rte_driver *driver;
+
+ TAILQ_FOREACH(device, &pci_bus->device_list, next) {
+ TAILQ_FOREACH(driver, &pci_bus->driver_list, next) {
+ ret = pci_bus->match(driver, device);
+ if (!ret) {
+ if (!driver->probe)
+ continue;
+
+ device->driver = driver;
+ ret = driver->probe(driver, device);
+ if (ret != 0)
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void
blacklist_all_devices(void)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *device = NULL;
unsigned i = 0;
char pci_addr_str[16];
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ TAILQ_FOREACH(device, &(pci_bus->device_list), next) {
+ dev = container_of(device, struct rte_pci_device, device);
snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT,
dev->addr.domain, dev->addr.bus, dev->addr.devid,
dev->addr.function);
@@ -142,19 +208,11 @@ static void free_devargs_list(void)
}
}
-/* backup real devices & drivers (not used for testing) */
-struct pci_driver_list real_pci_driver_list =
- TAILQ_HEAD_INITIALIZER(real_pci_driver_list);
-struct pci_device_list real_pci_device_list =
- TAILQ_HEAD_INITIALIZER(real_pci_device_list);
-
REGISTER_LINKED_RESOURCE(test_pci_sysfs);
static int
test_pci_setup(void)
{
- struct rte_pci_device *dev;
- struct rte_pci_driver *dr;
const struct resource *r;
int ret;
@@ -167,22 +225,19 @@ test_pci_setup(void)
ret = setenv("SYSFS_PCI_DEVICES", "test_pci_sysfs/bus/pci/devices", 1);
TEST_ASSERT_SUCCESS(ret, "failed to setenv");
- /* Unregister original devices & drivers lists */
- while (!TAILQ_EMPTY(&pci_driver_list)) {
- dr = TAILQ_FIRST(&pci_driver_list);
- rte_eal_pci_unregister(dr);
- TAILQ_INSERT_TAIL(&real_pci_driver_list, dr, next);
- }
+ /* Create a new Bus called 'test_pci_bus' */
+ /* Bus doesn't exist; Create the test bus */
+ printf("Creating a Test PCI bus\n");
+ rte_eal_bus_register(&test_pci_bus);
+ pci_bus = &test_pci_bus;
- while (!TAILQ_EMPTY(&pci_device_list)) {
- dev = TAILQ_FIRST(&pci_device_list);
- TAILQ_REMOVE(&pci_device_list, dev, next);
- TAILQ_INSERT_TAIL(&real_pci_device_list, dev, next);
- }
+ printf("Scan for Test devices and add to bus\n");
+ ret = pci_bus->scan(pci_bus);
- ret = rte_eal_pci_scan(NULL);
TEST_ASSERT_SUCCESS(ret, "failed to scan PCI bus");
- rte_eal_pci_dump(stdout);
+
+ printf("Dump of all devices scanned:\n");
+ do_pci_device_dump(stdout);
return 0;
}
@@ -190,8 +245,8 @@ test_pci_setup(void)
static int
test_pci_cleanup(void)
{
- struct rte_pci_device *dev;
- struct rte_pci_driver *dr;
+ struct rte_device *dev = NULL;
+ struct rte_driver *dr = NULL;
const struct resource *r;
int ret;
@@ -203,28 +258,23 @@ test_pci_cleanup(void)
ret = resource_rm_by_tar(r);
TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name);
+ TEST_ASSERT_NOT_NULL(pci_bus, "Invalid bus specified");
+
/*
* FIXME: there is no API in DPDK to free a rte_pci_device so we
* cannot free the devices in the right way. Let's assume that we
* don't care for tests.
*/
- while (!TAILQ_EMPTY(&pci_device_list)) {
- dev = TAILQ_FIRST(&pci_device_list);
- TAILQ_REMOVE(&pci_device_list, dev, next);
+ TAILQ_FOREACH(dev, &(pci_bus->device_list), next) {
+ rte_eal_bus_remove_device(dev);
+ dev->driver = NULL;
}
- /* Restore original devices & drivers lists */
- while (!TAILQ_EMPTY(&real_pci_driver_list)) {
- dr = TAILQ_FIRST(&real_pci_driver_list);
- TAILQ_REMOVE(&real_pci_driver_list, dr, next);
- rte_eal_pci_register(dr);
+ TAILQ_FOREACH(dr, &(pci_bus->driver_list), next) {
+ rte_eal_bus_remove_driver(dr);
}
- while (!TAILQ_EMPTY(&real_pci_device_list)) {
- dev = TAILQ_FIRST(&real_pci_device_list);
- TAILQ_REMOVE(&real_pci_device_list, dev, next);
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
- }
+ rte_eal_bus_unregister(pci_bus);
return 0;
}
@@ -234,16 +284,19 @@ test_pci_blacklist(void)
{
struct rte_devargs_list save_devargs_list;
- printf("Dump all devices\n");
- TEST_ASSERT(TAILQ_EMPTY(&pci_driver_list),
- "pci_driver_list not empty");
+ TEST_ASSERT_NOT_NULL(pci_bus, "Invalid bus specified");
+
+ TEST_ASSERT(TAILQ_EMPTY(&pci_bus->driver_list),
+ "PCI Driver list not empty");
- rte_eal_pci_register(&my_driver);
- rte_eal_pci_register(&my_driver2);
+ /* Add test drivers to Bus */
+ rte_eal_bus_add_driver(pci_bus, &(my_driver.driver));
+ rte_eal_bus_add_driver(pci_bus, &(my_driver2.driver));
pci_dev_count = 0;
- printf("Scan bus\n");
- rte_eal_pci_probe();
+
+ printf("Probe the Test Bus\n");
+ do_pci_bus_probe();
if (pci_dev_count == 0) {
printf("no device detected\n");
@@ -257,8 +310,8 @@ test_pci_blacklist(void)
blacklist_all_devices();
pci_dev_count = 0;
- printf("Scan bus with all devices blacklisted\n");
- rte_eal_pci_probe();
+ printf("Probe bus with all devices blacklisted\n");
+ do_pci_bus_probe();
free_devargs_list();
devargs_list = save_devargs_list;
@@ -270,8 +323,9 @@ test_pci_blacklist(void)
test_pci_run = 1;
- rte_eal_pci_unregister(&my_driver);
- rte_eal_pci_unregister(&my_driver2);
+ /* Clear the test drivers added to Test Bus */
+ rte_eal_bus_remove_driver(&(my_driver.driver));
+ rte_eal_bus_remove_driver(&(my_driver2.driver));
return 0;
}
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 30afc6b..79d82d4 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -562,9 +562,6 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_timer_init() < 0)
rte_panic("Cannot init HPET or TSC timers\n");
- if (rte_eal_pci_init() < 0)
- rte_panic("Cannot init PCI\n");
-
eal_check_mem_on_local_socket();
if (eal_plugins_init() < 0)
@@ -616,10 +613,6 @@ rte_eal_init(int argc, char **argv)
rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
rte_eal_mp_wait_lcore();
- /* Probe & Initialize PCI devices */
- if (rte_eal_pci_probe())
- rte_panic("Cannot probe PCI\n");
-
if (rte_eal_bus_probe())
rte_panic("Cannot probe devices\n");
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 10b234e..ab9f9d2 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -58,6 +58,7 @@
#include <rte_interrupts.h>
#include <rte_log.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_common.h>
#include <rte_launch.h>
@@ -249,7 +250,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
}
static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+pci_scan_one(struct rte_bus *bus, int dev_pci_fd, struct pci_conf *conf)
{
struct rte_pci_device *dev;
struct pci_bar_io bar;
@@ -322,19 +323,23 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
}
/* device is valid, add in list (sorted) */
- if (TAILQ_EMPTY(&pci_device_list)) {
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ if (TAILQ_EMPTY(&bus->device_list)) {
+ rte_eal_bus_add_device(bus, &dev->device);
}
else {
struct rte_pci_device *dev2 = NULL;
+ struct rte_device *r_dev2;
int ret;
- TAILQ_FOREACH(dev2, &pci_device_list, next) {
+ TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+ dev2 = container_of(r_dev2, struct rte_pci_device,
+ device);
ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
if (ret > 0)
continue;
else if (ret < 0) {
- TAILQ_INSERT_BEFORE(dev2, dev, next);
+ rte_eal_bus_insert_device(bus, &dev2->device,
+ &dev->device);
return 0;
} else { /* already registered */
dev2->kdrv = dev->kdrv;
@@ -346,7 +351,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
return 0;
}
}
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ rte_eal_bus_add_device(bus, &dev->device);
}
return 0;
@@ -361,7 +366,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
* list. Call pci_scan_one() for each pci entry found.
*/
int
-rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
+rte_eal_pci_scan(struct rte_bus *bus)
{
int fd;
unsigned dev_count = 0;
@@ -374,6 +379,10 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
.matches = &matches[0],
};
+ /* for debug purposes, PCI can be disabled */
+ if (internal_config.no_pci)
+ return 0;
+
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
@@ -389,7 +398,7 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
}
for (i = 0; i < conf_io.num_matches; i++)
- if (pci_scan_one(fd, &matches[i]) < 0)
+ if (pci_scan_one(bus, fd, &matches[i]) < 0)
goto error;
dev_count += conf_io.num_matches;
@@ -407,9 +416,9 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
}
int
-pci_update_device(const struct rte_pci_addr *addr)
+pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr)
{
- int fd;
+ int fd = -1;
struct pci_conf matches[2];
struct pci_match_conf match = {
.pc_sel = {
@@ -427,6 +436,9 @@ pci_update_device(const struct rte_pci_addr *addr)
.matches = &matches[0],
};
+ if (!bus)
+ goto error;
+
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
@@ -442,7 +454,7 @@ pci_update_device(const struct rte_pci_addr *addr)
if (conf_io.num_matches != 1)
goto error;
- if (pci_scan_one(fd, &matches[0]) < 0)
+ if (pci_scan_one(bus, fd, &matches[0]) < 0)
goto error;
close(fd);
@@ -668,17 +680,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
return ret;
}
-/* Init the PCI EAL subsystem */
-int
-rte_eal_pci_init(void)
-{
- /* for debug purposes, PCI can be disabled */
- if (internal_config.no_pci)
- return 0;
+struct rte_bus pci_bus = {
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match,
+};
- if (rte_eal_pci_scan(NULL) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
- return -1;
- }
- return 0;
-}
+RTE_REGISTER_BUS(pci, pci_bus);
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 23fc1c1..3dcf439 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -6,8 +6,6 @@ DPDK_2.0 {
eal_parse_sysfs_value;
eal_timer_source;
lcore_config;
- pci_device_list;
- pci_driver_list;
per_lcore__lcore_id;
per_lcore__rte_errno;
rte_calloc;
@@ -41,7 +39,6 @@ DPDK_2.0 {
rte_eal_mp_wait_lcore;
rte_eal_parse_devargs_str;
rte_eal_pci_dump;
- rte_eal_pci_probe;
rte_eal_pci_probe_one;
rte_eal_pci_register;
rte_eal_pci_scan;
@@ -187,5 +184,9 @@ DPDK_17.02 {
rte_eal_bus_remove_device;
rte_eal_bus_remove_driver;
rte_eal_bus_unregister;
+ rte_eal_pci_match;
+ rte_eal_pci_probe;
+ rte_eal_pci_remove;
+ rte_eal_pci_scan;
} DPDK_16.11;
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 562c0fd..e6d8d87 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -71,6 +71,7 @@
#include <rte_interrupts.h>
#include <rte_log.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_per_lcore.h>
#include <rte_memory.h>
@@ -82,11 +83,6 @@
#include "eal_private.h"
-struct pci_driver_list pci_driver_list =
- TAILQ_HEAD_INITIALIZER(pci_driver_list);
-struct pci_device_list pci_device_list =
- TAILQ_HEAD_INITIALIZER(pci_device_list);
-
#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
const char *pci_get_sysfs_path(void)
@@ -206,39 +202,10 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
int ret;
- struct rte_driver *driver;
- struct rte_device *device;
- struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- driver = &dr->driver;
- device = &dev->device;
- loc = &dev->addr;
-
- RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
- loc->domain, loc->bus, loc->devid, loc->function,
- dev->device.numa_node);
-
- /* no initialization when blacklisted, return without error */
- if (dev->device.devargs != NULL &&
- dev->device.devargs->type ==
- RTE_DEVTYPE_BLACKLISTED_PCI) {
- RTE_LOG(INFO, EAL, " Device is blacklisted, not"
- " initializing\n");
- return 1;
- }
-
- /* The device is not blacklisted; Check if driver supports it */
- ret = rte_eal_pci_match(driver, device);
- if (ret) {
- /* Match of device and driver failed */
- RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
- driver->name);
- return 1;
- }
-
RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
dev->id.device_id, dr->driver.name);
@@ -276,23 +243,11 @@ static int
rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
- int ret;
- struct rte_driver *driver = NULL;
- struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- driver = &(dr->driver);
- device = &(dev->device);
-
- ret = rte_eal_pci_match(driver, device);
- if (ret) {
- /* Device and driver don't match */
- return 1;
- }
-
loc = &dev->addr;
RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -321,9 +276,9 @@ rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
* failed, return 1 if no driver is found for this device.
*/
static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
+pci_probe_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev)
{
- struct rte_pci_driver *dr = NULL;
+ struct rte_driver *r_dr = NULL;
int rc = 0;
if (dev == NULL)
@@ -333,8 +288,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
if (dev->driver != NULL)
return 0;
- TAILQ_FOREACH(dr, &pci_driver_list, next) {
- rc = rte_eal_pci_probe_one_driver(dr, dev);
+ TAILQ_FOREACH(r_dr, &bus->driver_list, next) {
+ rc = rte_eal_pci_probe(r_dr, &dev->device);
if (rc < 0)
/* negative value is an error */
return -1;
@@ -352,15 +307,17 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
* failed, return 1 if no driver is found for this device.
*/
static int
-pci_detach_all_drivers(struct rte_pci_device *dev)
+pci_detach_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev)
{
struct rte_pci_driver *dr = NULL;
+ struct rte_driver *r_dr = NULL;
int rc = 0;
if (dev == NULL)
return -1;
- TAILQ_FOREACH(dr, &pci_driver_list, next) {
+ TAILQ_FOREACH(r_dr, &bus->driver_list, next) {
+ dr = container_of(r_dr, struct rte_pci_driver, driver);
rc = rte_eal_pci_detach_dev(dr, dev);
if (rc < 0)
/* negative value is an error */
@@ -381,22 +338,31 @@ int
rte_eal_pci_probe_one(const struct rte_pci_addr *addr)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+ struct rte_bus *bus;
int ret = 0;
if (addr == NULL)
return -1;
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return -1;
+ }
+
/* update current pci device in global list, kernel bindings might have
* changed since last time we looked at it.
*/
- if (pci_update_device(addr) < 0)
+ if (pci_update_device(bus, addr) < 0)
goto err_return;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
if (rte_eal_compare_pci_addr(&dev->addr, addr))
continue;
- ret = pci_probe_all_drivers(dev);
+ ret = pci_probe_all_drivers(bus, dev);
if (ret)
goto err_return;
return 0;
@@ -417,20 +383,29 @@ int
rte_eal_pci_detach(const struct rte_pci_addr *addr)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+ struct rte_bus *bus;
int ret = 0;
if (addr == NULL)
return -1;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus is not registered\n");
+ return -1;
+ }
+
+ TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
if (rte_eal_compare_pci_addr(&dev->addr, addr))
continue;
- ret = pci_detach_all_drivers(dev);
+ ret = pci_detach_all_drivers(bus, dev);
if (ret < 0)
goto err_return;
- TAILQ_REMOVE(&pci_device_list, dev, next);
+ rte_eal_bus_remove_device(r_dev);
free(dev);
return 0;
}
@@ -443,41 +418,73 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr)
return -1;
}
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
int
-rte_eal_pci_probe(void)
+rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device)
{
- struct rte_pci_device *dev = NULL;
- struct rte_devargs *devargs;
- int probe_all = 0;
int ret = 0;
+ struct rte_devargs *devargs;
+ struct rte_pci_device *pci_dev;
+ struct rte_pci_driver *pci_drv;
+ struct rte_pci_addr *loc;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
- probe_all = 1;
+ if (!driver || !device)
+ return -1;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ pci_dev = container_of(device, struct rte_pci_device, device);
+ pci_drv = container_of(driver, struct rte_pci_driver, driver);
- /* set devargs in PCI structure */
- devargs = pci_devargs_lookup(dev);
- if (devargs != NULL)
- dev->device.devargs = devargs;
+ loc = &pci_dev->addr;
- /* probe all or only whitelisted devices */
- if (probe_all)
- ret = pci_probe_all_drivers(dev);
- else if (devargs != NULL &&
- devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
- ret = pci_probe_all_drivers(dev);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
- " cannot be used\n", dev->addr.domain, dev->addr.bus,
- dev->addr.devid, dev->addr.function);
+ RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+ loc->domain, loc->bus, loc->devid, loc->function,
+ pci_dev->device.numa_node);
+
+ /* Fetch the devargs associated with the device */
+ devargs = pci_devargs_lookup(pci_dev);
+ if (devargs != NULL)
+ pci_dev->device.devargs = devargs;
+
+ /* no initialization when blacklisted, return without error */
+ if (pci_dev->device.devargs != NULL &&
+ pci_dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
+ RTE_LOG(INFO, EAL, " Device is blacklisted, not"
+ " initializing\n");
+ return 1;
}
+ ret = rte_eal_pci_probe_one_driver(pci_drv, pci_dev);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+ " cannot be used\n", pci_dev->addr.domain,
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+ return ret;
+ }
+ return 0;
+}
+
+int
+rte_eal_pci_remove(struct rte_device *device)
+{
+ int ret = 0;
+ struct rte_pci_device *pci_dev;
+
+ if (!device)
+ return -1;
+
+ pci_dev = container_of(device, struct rte_pci_device, device);
+
+ if (!pci_dev->driver)
+ return -1;
+
+ ret = rte_eal_pci_detach_dev(pci_dev->driver, pci_dev);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+ " cannot be used\n", pci_dev->addr.domain,
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+ return ret;
+ }
return 0;
}
@@ -506,8 +513,17 @@ void
rte_eal_pci_dump(FILE *f)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+ struct rte_bus *bus;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return;
+ }
+
+ TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
pci_dump_one_device(f, dev);
}
}
@@ -516,14 +532,32 @@ rte_eal_pci_dump(FILE *f)
void
rte_eal_pci_register(struct rte_pci_driver *driver)
{
- TAILQ_INSERT_TAIL(&pci_driver_list, driver, next);
- rte_eal_driver_register(&driver->driver);
+ struct rte_bus *bus;
+
+ RTE_VERIFY(driver);
+
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return;
+ }
+
+ rte_eal_bus_add_driver(bus, &driver->driver);
}
/* unregister a driver */
void
rte_eal_pci_unregister(struct rte_pci_driver *driver)
{
- rte_eal_driver_unregister(&driver->driver);
- TAILQ_REMOVE(&pci_driver_list, driver, next);
+ struct rte_bus *bus;
+
+ RTE_VERIFY(driver);
+
+ bus = driver->driver.bus;
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return;
+ }
+
+ rte_eal_bus_remove_driver(&driver->driver);
}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..06ec172 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -108,16 +108,6 @@ int rte_eal_timer_init(void);
*/
int rte_eal_log_init(const char *id, int facility);
-/**
- * Init the PCI infrastructure
- *
- * This function is private to EAL.
- *
- * @return
- * 0 on success, negative on error
- */
-int rte_eal_pci_init(void);
-
struct rte_pci_driver;
struct rte_pci_device;
@@ -126,13 +116,15 @@ struct rte_pci_device;
*
* This function is private to EAL.
*
+ * @param bus
+ * The PCI bus on which device is connected
* @param addr
* The PCI Bus-Device-Function address to look for
* @return
* - 0 on success.
* - negative on error.
*/
-int pci_update_device(const struct rte_pci_addr *addr);
+int pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr);
/**
* Unbind kernel driver for this device
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 10108a4..ec8f672 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -86,12 +86,6 @@ extern "C" {
#include <rte_interrupts.h>
#include <rte_dev.h>
-TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
-TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
-
-extern struct pci_driver_list pci_driver_list; /**< Global list of PCI drivers. */
-extern struct pci_device_list pci_device_list; /**< Global list of PCI devices. */
-
/** Pathname of PCI devices directory. */
const char *pci_get_sysfs_path(void);
@@ -372,6 +366,40 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
int rte_eal_pci_scan(struct rte_bus *bus);
/**
+ * Probe callback for the PCI bus
+ *
+ * For each matched pair of PCI device and driver on PCI bus, perform devargs
+ * check, and call a series of callbacks to allocate ethdev/cryptodev instances
+ * and intializing them.
+ *
+ * @param driver
+ * Generic driver object matched with the device
+ * @param device
+ * Generic device object to initialize
+ * @return
+ * - 0 on success.
+ * - !0 on error.
+ */
+int
+rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device);
+
+/**
+ * Remove callback for the PCI bus
+ *
+ * Called when a device needs to be removed from a bus; wraps around the
+ * PCI specific implementation layered over rte_pci_driver->remove. Default
+ * handler used by PCI PMDs
+ *
+ * @param device
+ * rte_device object referring to device to be removed
+ * @return
+ * - 0 for successful removal
+ * - !0 for failure in removal of device
+ */
+int
+rte_eal_pci_remove(struct rte_device *device);
+
+/**
* Match the PCI Driver and Device using the ID Table
*
* @param drv
@@ -387,19 +415,6 @@ rte_eal_pci_match(struct rte_driver *drv,
struct rte_device *dev);
/**
- * Probe the PCI bus for registered drivers.
- *
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- *
- * @return
- * - 0 on success.
- * - Negative on error.
- */
-int rte_eal_pci_probe(void);
-
-/**
* Map the PCI device resources in user space virtual memory address
*
* Note that driver should not call this function when flag
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 01d0cee..ff92de2 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -803,9 +803,6 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0)
rte_panic("Cannot init logs\n");
- if (rte_eal_pci_init() < 0)
- rte_panic("Cannot init PCI\n");
-
#ifdef VFIO_PRESENT
if (rte_eal_vfio_setup() < 0)
rte_panic("Cannot init VFIO\n");
@@ -887,10 +884,6 @@ rte_eal_init(int argc, char **argv)
rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
rte_eal_mp_wait_lcore();
- /* Probe & Initialize PCI devices */
- if (rte_eal_pci_probe())
- rte_panic("Cannot probe PCI\n");
-
if (rte_eal_bus_probe())
rte_panic("Cannot probe devices\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index cbd25df..5c66aa7 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -35,6 +35,7 @@
#include <dirent.h>
#include <rte_log.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_eal_memconfig.h>
#include <rte_malloc.h>
@@ -267,7 +268,8 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
/* Scan one pci sysfs entry, and fill the devices list from it. */
static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+pci_scan_one(struct rte_bus *bus, const char *dirname,
+ const struct rte_pci_addr *addr)
{
char filename[PATH_MAX];
unsigned long tmp;
@@ -385,21 +387,23 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
dev->kdrv = RTE_KDRV_NONE;
/* device is valid, add in list (sorted) */
- if (TAILQ_EMPTY(&pci_device_list)) {
- rte_eal_device_insert(&dev->device);
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ if (TAILQ_EMPTY(&bus->device_list)) {
+ rte_eal_bus_add_device(bus, &dev->device);
} else {
struct rte_pci_device *dev2;
+ struct rte_device *r_dev2;
int ret;
- TAILQ_FOREACH(dev2, &pci_device_list, next) {
+ TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+ dev2 = container_of(r_dev2, struct rte_pci_device,
+ device);
ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
if (ret > 0)
continue;
if (ret < 0) {
- TAILQ_INSERT_BEFORE(dev2, dev, next);
- rte_eal_device_insert(&dev->device);
+ rte_eal_bus_insert_device(bus, &dev2->device,
+ &dev->device);
} else { /* already registered */
dev2->kdrv = dev->kdrv;
dev2->max_vfs = dev->max_vfs;
@@ -409,15 +413,14 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
}
return 0;
}
- rte_eal_device_insert(&dev->device);
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ rte_eal_bus_add_device(bus, &dev->device);
}
return 0;
}
int
-pci_update_device(const struct rte_pci_addr *addr)
+pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr)
{
char filename[PATH_MAX];
@@ -425,7 +428,7 @@ pci_update_device(const struct rte_pci_addr *addr)
pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
addr->function);
- return pci_scan_one(filename, addr);
+ return pci_scan_one(bus, filename, addr);
}
/*
@@ -479,13 +482,22 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
* list
*/
int
-rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
+rte_eal_pci_scan(struct rte_bus *bus_p)
{
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
struct rte_pci_addr addr;
+ if (!bus_p) {
+ RTE_LOG(ERR, EAL, "PCI Bus is not registered\n");
+ return -1;
+ }
+
+ /* for debug purposes, PCI can be disabled */
+ if (internal_config.no_pci)
+ return 0;
+
dir = opendir(pci_get_sysfs_path());
if (dir == NULL) {
RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
@@ -504,7 +516,7 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
snprintf(dirname, sizeof(dirname), "%s/%s",
pci_get_sysfs_path(), e->d_name);
- if (pci_scan_one(dirname, &addr) < 0)
+ if (pci_scan_one(bus_p, dirname, &addr) < 0)
goto error;
}
closedir(dir);
@@ -750,18 +762,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
return ret;
}
-/* Init the PCI EAL subsystem */
-int
-rte_eal_pci_init(void)
-{
- /* for debug purposes, PCI can be disabled */
- if (internal_config.no_pci)
- return 0;
-
- if (rte_eal_pci_scan(NULL) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
- return -1;
- }
+struct rte_bus pci_bus = {
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match,
+};
- return 0;
-}
+RTE_REGISTER_BUS(pci, pci_bus);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index c873a7f..6e0ec51 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -6,8 +6,6 @@ DPDK_2.0 {
eal_parse_sysfs_value;
eal_timer_source;
lcore_config;
- pci_device_list;
- pci_driver_list;
per_lcore__lcore_id;
per_lcore__rte_errno;
rte_calloc;
@@ -41,7 +39,6 @@ DPDK_2.0 {
rte_eal_mp_wait_lcore;
rte_eal_parse_devargs_str;
rte_eal_pci_dump;
- rte_eal_pci_probe;
rte_eal_pci_probe_one;
rte_eal_pci_register;
rte_eal_pci_scan;
@@ -191,5 +188,9 @@ DPDK_17.02 {
rte_eal_bus_remove_device;
rte_eal_bus_remove_driver;
rte_eal_bus_unregister;
+ rte_eal_pci_match;
+ rte_eal_pci_probe;
+ rte_eal_pci_remove;
+ rte_eal_pci_scan;
} DPDK_16.11;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v3 11/12] eal: enable PCI bus and PCI test framework
From: Shreyansh Jain @ 2016-12-16 13:20 UTC (permalink / raw)
To: dev; +Cc: david.marchand, thomas.monjalon, ferruh.yigit, jianbo.liu
In-Reply-To: <1481893853-31790-12-git-send-email-shreyansh.jain@nxp.com>
On Friday 16 December 2016 06:40 PM, Shreyansh Jain wrote:
> Register a PCI bus with Scan/match and probe callbacks. Necessary changes
> in EAL layer for enabling bus interfaces. PCI devices and drivers now
> reside within the Bus object.
>
> Now that PCI bus handles the scan/probe methods, independent calls to
> PCI scan and probe can be removed from the code.
> PCI device and driver list are also removed.
>
> rte_device and rte_driver list continue to exist. As does the VDEV lists.
>
> Changes to test_pci:
> - use a dummy test_pci_bus for all PCI test driver registrations
> - this reduces the need for cleaning global list
> - add necessary callbacks for invoking scan and probing/matching
> using EAL PCI scan code
>
> Note: With this patch, all PCI PMDs would cease to work because of lack
> rte_driver->probe/remove implementations. Next patch would do that.
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
> app/test/test_pci.c | 154 +++++++++++------
> lib/librte_eal/bsdapp/eal/eal.c | 7 -
> lib/librte_eal/bsdapp/eal/eal_pci.c | 52 +++---
> lib/librte_eal/bsdapp/eal/rte_eal_version.map | 7 +-
> lib/librte_eal/common/eal_common_pci.c | 212 ++++++++++++++----------
> lib/librte_eal/common/eal_private.h | 14 +-
> lib/librte_eal/common/include/rte_pci.h | 53 +++---
> lib/librte_eal/linuxapp/eal/eal.c | 7 -
> lib/librte_eal/linuxapp/eal/eal_pci.c | 57 ++++---
> lib/librte_eal/linuxapp/eal/rte_eal_version.map | 7 +-
> 10 files changed, 330 insertions(+), 240 deletions(-)
>
<snip>
This is a relatively large patch. I would love to split it but
currently I am unable to find a nice/clean way. Any suggestions would
be really appreciated:
This currently does 3 broad things:
- Move the PCI device/driver registration to PCI Bus
-- So, introduce PCI bus
-- change EAL to point to this new bus
- remove/refactor existing EAL/*/*pci* code to accommodate this shift
- Test PCI framework.
I could have split test_pci changes into a new patch, but that breaks
compilation after this patchset if test_pci compilation is enabled
(disabled by default). Is that acceptable? (if not, I am stuck with
keeping this set of changes into a single patch).
And, I would appreciate some help in confirming if the changes to
test_pci are OK or not from PCI testing perspective.
-
Shreyansh
^ permalink raw reply
* Re: [PATCH v3 04/12] eal/bus: add scan, match and insert support
From: Shreyansh Jain @ 2016-12-16 13:25 UTC (permalink / raw)
To: dev; +Cc: david.marchand, thomas.monjalon, ferruh.yigit, jianbo.liu
In-Reply-To: <1481893853-31790-5-git-send-email-shreyansh.jain@nxp.com>
On Friday 16 December 2016 06:40 PM, Shreyansh Jain wrote:
> When a PMD is registred, it will associate itself with a bus.
>
> A bus is responsible for 'scan' of all the devices attached to it.
> All the scanned devices are attached to bus specific device_list.
> During the probe operation, 'match' of the drivers and devices would
> be done.
>
> Also, rather than adding a device to tail, a new device might be added to
> the list (pivoted on bus) at a predefined position, for example, adding it
> in order of addressing. Support for this is added as '*bus_insert'.
>
> This patch also adds necessary test framework to test the scan and
> match callbacks.
>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> ---
> app/test/test_bus.c | 265 ++++++++++++++++++++++++++++++++
> lib/librte_eal/common/eal_common_bus.c | 15 ++
> lib/librte_eal/common/include/rte_bus.h | 64 ++++++++
> 3 files changed, 344 insertions(+)
>
> diff --git a/app/test/test_bus.c b/app/test/test_bus.c
> index 760d40a..ed95479 100644
> --- a/app/test/test_bus.c
> +++ b/app/test/test_bus.c
> @@ -80,12 +80,32 @@ struct dummy_bus {
> struct rte_bus_list orig_bus_list =
> TAILQ_HEAD_INITIALIZER(orig_bus_list);
>
> +/* Forward declarations for callbacks from bus */
> +
> +/* Bus A
> + * Scan would register devA1 and devA2 to bus
> + */
> +int scan_fn_for_busA(struct rte_bus *bus);
> +
> +/* Bus B
> + * Scan would register devB1 and devB2 to bus
> + */
> +int scan_fn_for_busB(struct rte_bus *bus);
> +
> +/* generic implementations wrapped around by above declarations */
> +static int generic_scan_fn(struct rte_bus *bus);
> +static int generic_match_fn(struct rte_driver *drv, struct rte_device *dev);
> +
> struct rte_bus busA = {
> .name = "busA", /* "busA" */
> + .scan = scan_fn_for_busA,
> + .match = generic_match_fn,
> };
>
> struct rte_bus busB = {
> .name = "busB", /* "busB */
> + .scan = scan_fn_for_busB,
> + .match = generic_match_fn,
> };
>
> struct rte_driver driverA = {
> @@ -184,6 +204,92 @@ dump_device_tree(void)
> printf("------>8-------\n");
> }
>
> +/* @internal
> + * Move over the dummy_buses and find the entry matching the bus object
> + * passed as argument.
> + * For each device in that dummy_buses list, register.
> + *
> + * @param bus
> + * bus to scan againt test entry
> + * @return
> + * 0 for successful scan, even if no devices are found
> + * !0 for any error in scanning (like, invalid bus)
> + */
> +static int
> +generic_scan_fn(struct rte_bus *bus)
> +{
> + int i = 0;
> + struct rte_device *dev = NULL;
> + struct dummy_bus *db = NULL;
> +
> + if (!bus)
> + return -1;
> +
> + /* Extract the device tree node using the bus passed */
> + for (i = 0; dummy_buses[i].name; i++) {
> + if (!strcmp(dummy_buses[i].name, bus->name)) {
> + db = &dummy_buses[i];
> + break;
> + }
> + }
> +
> + if (!db)
> + return -1;
> +
> + /* For all the devices in the device tree (dummy_buses), add device */
> + for (i = 0; db->devices[i]; i++) {
> + dev = &(db->devices[i]->dev);
> + rte_eal_bus_add_device(bus, dev);
> + }
> +
> + return 0;
> +}
> +
> +/* @internal
> + * Obtain bus from driver object. Match the address of rte_device object
> + * with all the devices associated with that bus.
> + *
> + * Being a test function, all this does is validate that device object
> + * provided is available on the same bus to which driver is registered.
> + *
> + * @param drv
> + * driver to which matching is to be performed
> + * @param dev
> + * device object to match with driver
> + * @return
> + * 0 for successful match
> + * !0 for failed match
> + */
> +static int
> +generic_match_fn(struct rte_driver *drv, struct rte_device *dev)
> +{
> + struct rte_bus *bus;
> + struct rte_device *dev_p = NULL;
> +
> + /* Match is based entirely on address of 'dev' and 'dev_p' extracted
> + * from bus->device_list.
> + */
> +
> + /* a driver is registered with the bus *before* the scan. */
> + bus = drv->bus;
> + TAILQ_FOREACH(dev_p, &bus->device_list, next) {
> + if (dev == dev_p)
> + return 0;
> + }
> +
> + return 1;
> +}
> +
> +int
> +scan_fn_for_busA(struct rte_bus *bus) {
> + return generic_scan_fn(bus);
> +}
> +
> +int
> +scan_fn_for_busB(struct rte_bus *bus) {
> + return generic_scan_fn(bus);
> +}
> +
> static int
> test_bus_setup(void)
> {
> @@ -391,6 +497,155 @@ test_driver_unregistration_on_bus(void)
>
> }
>
> +static int
> +test_device_unregistration_on_bus(void)
> +{
> + int i;
> + struct rte_bus *bus = NULL;
> + struct rte_device *dev;
> +
> + for (i = 0; dummy_buses[i].name; i++) {
> + bus = rte_eal_get_bus(dummy_buses[i].name);
> + if (!bus) {
> + printf("Unable to find bus (%s)\n",
> + dummy_buses[i].name);
> + return -1;
> + }
> +
> + /* For bus 'bus', unregister all devices */
> + TAILQ_FOREACH(dev, &bus->device_list, next) {
> + rte_eal_bus_remove_device(dev);
> + }
> + }
> +
> + for (i = 0; dummy_buses[i].name; i++) {
> + bus = rte_eal_get_bus(dummy_buses[i].name);
> +
> + if (!TAILQ_EMPTY(&bus->device_list)) {
> + printf("Unable to remove all devices on bus (%s)\n",
> + bus->name);
> + return -1;
> + }
> + }
> +
> + /* All devices from all buses have been removed */
> + printf("All devices on all buses unregistered.\n");
> + dump_device_tree();
> +
> + return 0;
> +}
> +
> +/* @internal
> + * For each bus registered, call the scan function to identify devices
> + * on the bus.
> + *
> + * @param void
> + * @return
> + * 0 for successful scan
> + * !0 for unsuccessful scan
> + *
> + */
> +static int
> +test_bus_scan(void)
> +{
> + int ret;
> + struct rte_bus *bus;
> +
> + TAILQ_FOREACH(bus, &rte_bus_list, next) {
> + /* Call the scan function for each bus */
> + ret = bus->scan(bus);
> + if (ret) {
> + printf("Scan of buses failed.\n");
> + return -1;
> + }
> + }
> +
> + printf("Scan of all buses completed.\n");
> + dump_device_tree();
> +
> + return 0;
> +}
> +
> +/* @internal
> + * Function to perform 'probe' and link devices and drivers on a bus.
> + * This would work over all the buses registered, and all devices and drivers
> + * registered with it - call match on each pair.
> + * Aim is to test the match_fn for each bus.
> + *
> + * @param void
> + * @return
> + * 0 for successful probe
> + * !0 for failure in probe
> + *
> + */
> +static int
> +test_probe_on_bus(void)
> +{
> + int ret = 0;
> + int i, j;
> + struct rte_bus *bus = NULL;
> + struct rte_device *dev = NULL;
> + struct rte_driver *drv = NULL;
> +
> + /* In case of this test:
> + * 1. for each bus in rte_bus_list
> + * 2. for each device in bus->device_list
> + * 3. for each driver in bus->driver_list
> + * 4. call match
> + * 5. link driver and device
> + * 6. Verify the linkage.
> + */
This comment style is indeed in a warning from checkpatch. My bad -
somehow I missed fixing this before sending out. v4, along with any
other major comments/reviews.
<snip>
-
Shreyansh
^ permalink raw reply
* Re: [PATCH v12 0/6] add Tx preparation
From: Jan Mędala @ 2016-12-16 13:53 UTC (permalink / raw)
To: Ananyev, Konstantin
Cc: Yigit, Ferruh, Thomas Monjalon, Harish Patil, dev@dpdk.org,
Rahul Lakkireddy, Stephen Hurd, Jakub Palider, John Daley,
Adrien Mazarguil, Alejandro Lucero, Rasesh Mody, Jacob, Jerin,
Yuanhan Liu, Kulasek, TomaszX, olivier.matz@6wind.com, Yong Wang,
evgenys@amazon.com, netanel@amazon.com
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0F039A@irsmsx105.ger.corp.intel.com>
Hello,
> Is there any update on that subject?
>
At this point we need to have only pseudo-header checksum for TSO. Maybe
there will be new requirements, but that's something I cannot predict at
this point.
> So it seems that standard pseudo-header checksum calculation should be
> enough.
> Is that correct?
>
Yes, this will be enough at this point.
We also need to deliver a fix for issue we found during investigation of
tx_prep() API.
Thanks,
Jan
^ permalink raw reply
* Re: [PATCH v3] drivers: advertise kmod dependencies in pmdinfo
From: Ferruh Yigit @ 2016-12-16 14:19 UTC (permalink / raw)
To: Neil Horman, Olivier Matz
Cc: Stephen Hemminger, dev, thomas.monjalon, vido, fiona.trahe,
adrien.mazarguil
In-Reply-To: <20161216123738.GA2255@hmsreliant.think-freely.org>
On 12/16/2016 12:37 PM, Neil Horman wrote:
> On Fri, Dec 16, 2016 at 10:22:08AM +0100, Olivier Matz wrote:
>> Hi,
>>
>> On Thu, 15 Dec 2016 09:22:07 -0800, Stephen Hemminger
>> <stephen@networkplumber.org> wrote:
>>> On Thu, 15 Dec 2016 11:09:12 -0500
>>> Neil Horman <nhorman@tuxdriver.com> wrote:
>>>
>>>> On Thu, Dec 15, 2016 at 02:46:39PM +0100, Olivier Matz wrote:
>>>>> Add a new macro RTE_PMD_REGISTER_KMOD_DEP() that allows a driver
>>>>> to declare the list of kernel modules required to run properly.
>>>>>
>>>>> Today, most PCI drivers require uio/vfio.
>>>>>
>>>>> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
>>>>> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
>>>>> ---
>>>>>
>>>>> v2 -> v3:
>>>>> - fix kmods deps advertised by mellanox drivers as pointed out
>>>>> by Adrien
>>>>>
>>>>> v1 ->
>>>>> v2:
>>>>> - do not advertise uio_pci_generic for vf drivers
>>>>> - rebase on top of head: use new driver names and prefix
>>>>> macro with
>>>>> RTE_
>>>>>
>>>>> rfc -> v1:
>>>>> - the kmod information can be per-device using a modalias-like
>>>>> pattern
>>>>> - change syntax to use '&' and '|' instead of ',' and ':'
>>>>> - remove useless prerequisites in kmod lis: no need to
>>>>> specify both uio and uio_pci_generic, only the latter is
>>>>> required
>>>>> - update kmod list in szedata2 driver
>>>>> - remove kmod list in qat driver: it requires more than just
>>>>> loading a kmod, which is described in documentation
>>>>>
>>>>> buildtools/pmdinfogen/pmdinfogen.c | 1 +
>>>>> buildtools/pmdinfogen/pmdinfogen.h | 1 +
>>>>> drivers/net/bnx2x/bnx2x_ethdev.c | 2 ++
>>>>> drivers/net/bnxt/bnxt_ethdev.c | 1 +
>>>>> drivers/net/cxgbe/cxgbe_ethdev.c | 1 +
>>>>> drivers/net/e1000/em_ethdev.c | 1 +
>>>>> drivers/net/e1000/igb_ethdev.c | 2 ++
>>>>> drivers/net/ena/ena_ethdev.c | 1 +
>>>>> drivers/net/enic/enic_ethdev.c | 1 +
>>>>> drivers/net/fm10k/fm10k_ethdev.c | 1 +
>>>>> drivers/net/i40e/i40e_ethdev.c | 1 +
>>>>> drivers/net/i40e/i40e_ethdev_vf.c | 1 +
>>>>> drivers/net/ixgbe/ixgbe_ethdev.c | 2 ++
>>>>> drivers/net/mlx4/mlx4.c | 2 ++
>>>>> drivers/net/mlx5/mlx5.c | 1 +
>>>>> drivers/net/nfp/nfp_net.c | 1 +
>>>>> drivers/net/qede/qede_ethdev.c | 2 ++
>>>>> drivers/net/szedata2/rte_eth_szedata2.c | 2 ++
>>>>> drivers/net/thunderx/nicvf_ethdev.c | 1 +
>>>>> drivers/net/virtio/virtio_ethdev.c | 1 +
>>>>> drivers/net/vmxnet3/vmxnet3_ethdev.c | 1 +
>>>>> lib/librte_eal/common/include/rte_dev.h | 25
>>>>> +++++++++++++++++++++++++ tools/dpdk-pmdinfo.py
>>>>> | 5 ++++- 23 files changed, 56 insertions(+), 1 deletion(-)
>>>>>
>>>> Its odd that all devices, regardless of vendor should depend on the
>>>> igb_uio module. It seems to me that depending on uio_pci_generic
>>>> or vfio is sufficient.
>>
>> igb_uio is the historical uio module of dpdk. Although it is called
>> igb_uio, it is not specific to Intel drivers.
>>
>> Most drivers declare "igb_uio | uio_pci_generic | vfio", which means
>> that any of the 3 kernel modules can be used.
>>
>> I think there are some cases where people will prefer using igb_uio,
>> for instance to use a vf pmd in a vm where there is no iommu,
>> and where the kernel vfio module does not support the no-iommu mode.
>>
>>
>>>
>>> Yes it seems just a special case extension for Mellanox drivers.
>>
>> Kmod deps are different whether it's a vf driver or not.
>> Mellanox drivers are not the only drivers that do not require uio,
>> there is also szedata2.
>>
>> Is it an argument for not including this patch?
>>
> Speaking only for myself, I'm not suggesting the patch not be included, only
> questioning the need to list igb_uio as an optional dependency. From what I
> understand uio_pci_generic is equaly capable of being used in a vf as igb_uio,
> and so it seems like its sufficient to list in the deps alone, or am I missing
> something?
>
> Additionally, in regards to the comment about rebasing on net-next here, I don't
> think thats needed. This patch is built such that you will be able to apply
> this tag to additional drivers later, as they get merged into thomas's tree, you
> don't need to get them all in one shot.
Right, more drivers can be added later. But also I don't see any problem
if this patch rebased on next-net and be a more complete patch. That is
why it was a question to the author.
> More to the point, there are crypto
> drivers that may make use of this module dependency tag, and those are also
> missing. I would suggest taking the patch based on it current state (once the
> above igb_uio issue is settled), and then adding the tag to new drivers in
> subsequent releases as they get merged.
>
> Neil
>
>>
>> Regards,
>> Olivier
>>
^ permalink raw reply
* Re: [PATCH v3 00/29] Support VFD and DPDK PF + kernel VF on i40e
From: Ferruh Yigit @ 2016-12-16 14:28 UTC (permalink / raw)
To: Qi Zhang, jingjing.wu, helin.zhang; +Cc: dev
In-Reply-To: <1481835919-36488-1-git-send-email-qi.z.zhang@intel.com>
On 12/15/2016 9:04 PM, Qi Zhang wrote:
> 1, VF Daemon (VFD)
> VFD is an idea to control all the VFs from PF.
> As we need to support the scenario kernel PF + DPDK VF,
> DPDK follows the interface between kernel PF + kernel VF.
> We don't want to introduce too many new messages between PF and VF.
> So this patch set adds some new APIs to control VFs directly from PF.
> The new APIs include,
> 1) set VF MAC anti-spoofing
> 2) set VF VLAN anti-spoofing
> 3) set TX loopback
> 4) set VF unicast promiscuous mode
> 5) set VF multicast promiscuous mode
> 6) set VF MTU
> 7) get/reset VF stats
> 8) set VF MAC address
> 9) set VF VLAN stripping
> 10) VF VLAN insertion
> 12) set VF broadcast mode
> 12) set VF VLAN tag
> 13) set VF VLAN filter
> VFD also includes VF to PF mailbox message management by APP.
> When PF receives mailbox messages from VF, PF should call the callback provided by APP to know if they're permitted to be processed.
>
> 2, Implement VF MAC address setting on VF.
>
> 3, Support the scenario DPDK PF + kernel VF.
>
> v3:
> - fix issue that VF does not work for i40e
> - remove patch for VDMq receive mode init
> - move get/reset VF stats API into rte_pmd_i40
>
> v2:
> - fix the compile issues.
> - fix the checkpatch warning and typo.
> - update the commit log of some patches.
> - fix the invalid port ID issue of testpmd.
>
> Bernard Iremonger (7):
> net/i40e: add set VF VLAN insert function
> net/i40e: set VF broadcast mode from PF
> net/i40e: set VF VLAN tag from PF
> net/i40e: set VF VLAN filter from PF
> app/testpmd: add command to test VF broadcast mode on i40e
> app/testpmd: add command to test VF VLAN tag on i40e
> app/testpmd: handle i40e in VF VLAN filter command
>
> Chen Jing D(Mark) (6):
> net/i40e: add VF VLAN strip func
> net/i40e: change version number to support Linux VF
> net/i40e: return correct vsi_id
> net/i40e: parse more VF parameter and configure
> net/i40e: support Linux VF to configure IRQ link list
> net/i40e: enhance in sanity check of MAC
>
> Ferruh Yigit (3):
> net/i40e: set VF MAC from PF support
> net/i40e: set VF MAC from VF support
> net/i40e: fix VF MAC address assignment
>
> Qi Zhang (3):
> net/i40e: enable VF MTU change
> net/i40e: fix VF reset flow
> net/i40e: set/clear VF stats from PF
>
> Wenzhuo Lu (10):
> net/i40e: support link status notification
> net/i40e: add callback to user on VF to PF mbox msg
> net/i40e: set VF MAC anti-spoofing from PF
> net/i40e: set VF VLAN anti-spoofing from PF
> net/i40e: set Tx loopback from PF
> net/i40e: set VF unicast promisc mode from PF
> net/i40e: set VF multicast promisc mode from PF
> app/testpmd: use VFD APIs on i40e
> app/testpmd: use unicast promiscuous mode on i40e
> app/testpmd: use multicast promiscuous mode on i40e
>
<...>
Hi Qi,
I can't cleanly apply the patchset to the next-net tree, mainly because
of the testpmd conflicts.
I will send a new version of the patchset shortly.
Thanks,
ferruh
^ permalink raw reply
* Re: [dpdk-stable] [PATCH 2/2] ethdev: clarify xstats Api documentation
From: Mcnamara, John @ 2016-12-16 14:28 UTC (permalink / raw)
To: Olivier Matz, dev@dpdk.org, thomas.monjalon@6wind.com
Cc: Horton, Remy, stable@dpdk.org
In-Reply-To: <1481881454-17382-2-git-send-email-olivier.matz@6wind.com>
> -----Original Message-----
> From: stable [mailto:stable-bounces@dpdk.org] On Behalf Of Olivier Matz
> Sent: Friday, December 16, 2016 9:44 AM
> To: dev@dpdk.org; thomas.monjalon@6wind.com
> Cc: Horton, Remy <remy.horton@intel.com>; stable@dpdk.org
> Subject: [dpdk-stable] [PATCH 2/2] ethdev: clarify xstats Api
> documentation
>
> Reword the Api documentation of xstats ethdev.
>
> CC: stable@dpdk.org
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
> lib/librte_ether/rte_ethdev.h | 45 ++++++++++++++++++++++++--------------
> -----
> ...
> int rte_eth_xstats_get_names(uint8_t port_id,
> struct rte_eth_xstat_name *xstats_names, @@ -2296,19 +2300,20
> @@ int rte_eth_xstats_get_names(uint8_t port_id,
> * The port identifier of the Ethernet device.
> * @param xstats
> * A pointer to a table of structure of type *rte_eth_xstat*
> - * to be filled with device statistics ids and values.
> + * to be filled with device statistics ids and values: id is the
> + * index of the name string in xstats_names (@see rte_eth_xstats_get_names),
The @see directive starts a new "See also" section and breaks/interrupts the
parameter description. Probably what you want is:
index of the name string in xstats_names (see rte_eth_xstats_get_names()),
Otherwise it is a good update.
John
^ permalink raw reply
* Re: [dpdk-stable] [PATCH 2/2] ethdev: clarify xstats Api documentation
From: Olivier Matz @ 2016-12-16 14:36 UTC (permalink / raw)
To: Mcnamara, John
Cc: dev@dpdk.org, thomas.monjalon@6wind.com, Horton, Remy,
stable@dpdk.org
In-Reply-To: <B27915DBBA3421428155699D51E4CFE202686E3E@IRSMSX103.ger.corp.intel.com>
Hi John,
On Fri, 16 Dec 2016 14:28:21 +0000, "Mcnamara, John"
<john.mcnamara@intel.com> wrote:
> > -----Original Message-----
> > From: stable [mailto:stable-bounces@dpdk.org] On Behalf Of Olivier
> > Matz Sent: Friday, December 16, 2016 9:44 AM
> > To: dev@dpdk.org; thomas.monjalon@6wind.com
> > Cc: Horton, Remy <remy.horton@intel.com>; stable@dpdk.org
> > Subject: [dpdk-stable] [PATCH 2/2] ethdev: clarify xstats Api
> > documentation
> >
> > Reword the Api documentation of xstats ethdev.
> >
> > CC: stable@dpdk.org
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > ---
> > lib/librte_ether/rte_ethdev.h | 45
> > ++++++++++++++++++++++++-------------- -----
> > ...
> > int rte_eth_xstats_get_names(uint8_t port_id,
> > struct rte_eth_xstat_name *xstats_names, @@
> > -2296,19 +2300,20 @@ int rte_eth_xstats_get_names(uint8_t port_id,
> > * The port identifier of the Ethernet device.
> > * @param xstats
> > * A pointer to a table of structure of type *rte_eth_xstat*
> > - * to be filled with device statistics ids and values.
> > + * to be filled with device statistics ids and values: id is the
> > + * index of the name string in xstats_names (@see
> > rte_eth_xstats_get_names),
>
> The @see directive starts a new "See also" section and
> breaks/interrupts the parameter description. Probably what you want
> is:
>
> index of the name string in xstats_names (see
> rte_eth_xstats_get_names()),
>
> Otherwise it is a good update.
>
> John
Thank you for the review. I'll send a new version of the patch
addressing this.
Regards,
Olivier
^ permalink raw reply
* [PATCH v4 09/29] net/i40e: fix VF reset flow
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Qi Zhang <qi.z.zhang@intel.com>
Add missing step during VF reset: PF should
set I40E_VFGEN_RSTAT to ACTIVE at end of the
VF reset operation or VF driver may not able
to detect that reset is already completed.
This patch also remove the unnecessary enum
for vfr state.
Fixes: 4861cde46116 ("i40e: new poll mode driver")
CC: stable@dpdk.org
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
drivers/net/i40e/i40e_pf.c | 6 ++++--
drivers/net/i40e/i40e_pf.h | 5 -----
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 8b8a14f..2bc3355 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -139,7 +139,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
abs_vf_id = vf_id + hw->func_caps.vf_base_id;
/* Notify VF that we are in VFR progress */
- I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_VFR_INPROGRESS);
+ I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_INPROGRESS);
/*
* If require a SW VF reset, a VFLR interrupt will be generated,
@@ -220,7 +220,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
}
/* Reset done, Set COMPLETE flag and clear reset bit */
- I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_VFR_COMPLETED);
+ I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_COMPLETED);
val = I40E_READ_REG(hw, I40E_VPGEN_VFRTRIG(vf_id));
val &= ~I40E_VPGEN_VFRTRIG_VFSWR_MASK;
I40E_WRITE_REG(hw, I40E_VPGEN_VFRTRIG(vf_id), val);
@@ -248,6 +248,8 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
return -EFAULT;
}
+ I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_VFACTIVE);
+
return ret;
}
diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h
index 59bf2ee..ada398b 100644
--- a/drivers/net/i40e/i40e_pf.h
+++ b/drivers/net/i40e/i40e_pf.h
@@ -48,11 +48,6 @@
#define I40E_DPDK_OFFSET 0x100
-enum i40e_pf_vfr_state {
- I40E_PF_VFR_INPROGRESS = 0,
- I40E_PF_VFR_COMPLETED = 1,
-};
-
/* DPDK pf driver specific command to VF */
enum i40e_virtchnl_ops_dpdk {
/*
--
2.9.3
^ permalink raw reply related
* [PATCH v4 12/29] net/i40e: fix VF MAC address assignment
From: Ferruh Yigit @ 2016-12-16 14:39 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
If PF sets vf->mac_addr, in VF initialization hw->mac.addr will be set
to that same value. It is possible to check if PF set a MAC address or
not through the hw->mac.addr variable.
hw->mac.addr set by i40e_vf_parse_hw_config(), call stack is:
In PF side
i40e_pf_host_process_cmd_get_vf_resources()
eth_addr_copy(vf->mac_addr, vf_res->vsi_res[0].default_mac_address)
In VF sise
i40evf_init_vf()
i40evf_get_vf_resources()
i40e_vf_parse_hw_config()
memcpy(hw->mac.addr, vsi_res->default_mac_addr)
Updated code is after i40evf_get_vf_resources() and can benefit from
hw->mac.addr variable.
Fixes: 89e6b86384bb ("i40evf: rework MAC address validation")
CC: stable@dpdk.org
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
drivers/net/i40e/i40e_ethdev_vf.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 5016249..0977095 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1193,7 +1193,6 @@ i40evf_init_vf(struct rte_eth_dev *dev)
int i, err, bufsz;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
- struct ether_addr *p_mac_addr;
uint16_t interval =
i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX);
@@ -1270,13 +1269,10 @@ i40evf_init_vf(struct rte_eth_dev *dev)
vf->vsi.adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
/* Store the MAC address configured by host, or generate random one */
- p_mac_addr = (struct ether_addr *)(vf->vsi_res->default_mac_addr);
- if (is_valid_assigned_ether_addr(p_mac_addr)) { /* Configured by host */
- ether_addr_copy(p_mac_addr, (struct ether_addr *)hw->mac.addr);
+ if (is_valid_assigned_ether_addr((struct ether_addr *)hw->mac.addr))
vf->flags |= I40E_FLAG_VF_MAC_BY_PF;
- } else {
+ else
eth_random_addr(hw->mac.addr); /* Generate a random one */
- }
/* If the PF host is not DPDK, set the interval of ITR0 to max*/
if (vf->version_major != I40E_DPDK_VERSION_MAJOR) {
--
2.9.3
^ permalink raw reply related
* [PATCH v4 00/29] Support VFD and DPDK PF + kernel VF on i40e
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <1481835919-36488-1-git-send-email-qi.z.zhang@intel.com>
1, VF Daemon (VFD)
VFD is an idea to control all the VFs from PF.
As we need to support the scenario kernel PF + DPDK VF,
DPDK follows the interface between kernel PF + kernel VF.
We don't want to introduce too many new messages between PF and VF.
So this patch set adds some new APIs to control VFs directly from PF.
The new APIs include,
1) set VF MAC anti-spoofing
2) set VF VLAN anti-spoofing
3) set TX loopback
4) set VF unicast promiscuous mode
5) set VF multicast promiscuous mode
6) set VF MTU
7) get/reset VF stats
8) set VF MAC address
9) set VF VLAN stripping
10) VF VLAN insertion
12) set VF broadcast mode
12) set VF VLAN tag
13) set VF VLAN filter
VFD also includes VF to PF mailbox message management by APP.
When PF receives mailbox messages from VF, PF should call the callback provided by APP to know if they're permitted to be processed.
2, Implement VF MAC address setting on VF.
3, Support the scenario DPDK PF + kernel VF.
v4:
- rebase on latest next-net
- move patch 10/29 testpmd part to patch 18/29
v3:
- fix issue that VF does not work for i40e
- remove patch for VDMq receive mode init
- move get/reset VF stats API into rte_pmd_i40
v2:
- fix the compile issues.
- fix the checkpatch warning and typo.
- update the commit log of some patches.
- fix the invalid port ID issue of testpmd.
Bernard Iremonger (7):
net/i40e: add set VF VLAN insert function
net/i40e: set VF broadcast mode from PF
net/i40e: set VF VLAN tag from PF
net/i40e: set VF VLAN filter from PF
app/testpmd: add command to test VF broadcast mode on i40e
app/testpmd: add command to test VF VLAN tag on i40e
app/testpmd: handle i40e in VF VLAN filter command
Chen Jing D(Mark) (6):
net/i40e: add VF VLAN strip func
net/i40e: change version number to support Linux VF
net/i40e: return correct VSI id
net/i40e: parse more VF parameter and configure
net/i40e: support Linux VF to configure IRQ link list
net/i40e: enhance in sanity check of MAC
Ferruh Yigit (3):
net/i40e: set VF MAC from PF support
net/i40e: set VF MAC from VF support
net/i40e: fix VF MAC address assignment
Qi Zhang (3):
net/i40e: enable VF MTU change
net/i40e: fix VF reset flow
net/i40e: set/clear VF stats from PF
Wenzhuo Lu (10):
net/i40e: support link status notification
net/i40e: add callback to user on VF to PF mbox msg
net/i40e: set VF MAC anti-spoofing from PF
net/i40e: set VF VLAN anti-spoofing from PF
net/i40e: set Tx loopback from PF
net/i40e: set VF unicast promisc mode from PF
net/i40e: set VF multicast promisc mode from PF
app/testpmd: use VFD APIs on i40e
app/testpmd: use unicast promiscuous mode on i40e
app/testpmd: use multicast promiscuous mode on i40e
app/test-pmd/Makefile | 2 +
app/test-pmd/cmdline.c | 473 +++++++++++++++-
app/test-pmd/config.c | 17 +-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 32 ++
drivers/net/i40e/Makefile | 4 +-
drivers/net/i40e/i40e_ethdev.c | 847 +++++++++++++++++++++++++++-
drivers/net/i40e/i40e_ethdev.h | 5 +-
drivers/net/i40e/i40e_ethdev_vf.c | 82 ++-
drivers/net/i40e/i40e_pf.c | 417 ++++++++++++--
drivers/net/i40e/i40e_pf.h | 9 +-
drivers/net/i40e/rte_pmd_i40e.h | 328 +++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 20 +
12 files changed, 2129 insertions(+), 107 deletions(-)
create mode 100644 drivers/net/i40e/rte_pmd_i40e.h
--
2.9.3
^ permalink raw reply
* [PATCH v4 01/29] net/i40e: support link status notification
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
Add an API to expose the ability, that PF can notify VF
when link status changes, to APP.
So if PF APP doesn't want to enable interruption but check
link status by itself, PF APP can let VF know link status
changed.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/Makefile | 4 ++-
drivers/net/i40e/i40e_ethdev.c | 28 +++++++++++++++
drivers/net/i40e/i40e_pf.c | 4 +--
drivers/net/i40e/i40e_pf.h | 4 ++-
drivers/net/i40e/rte_pmd_i40e.h | 58 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 6 ++++
6 files changed, 100 insertions(+), 4 deletions(-)
create mode 100644 drivers/net/i40e/rte_pmd_i40e.h
diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 66997b6..a2ef53c 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -1,6 +1,6 @@
# BSD LICENSE
#
-# Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -111,6 +111,8 @@ ifeq ($(findstring RTE_MACHINE_CPUFLAG_SSE4_1,$(CFLAGS)),)
CFLAGS_i40e_rxtx_vec_sse.o += -msse4.1
endif
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_I40E_PMD)-include := rte_pmd_i40e.h
# this lib depends upon:
DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f42f4ba..fc7e987 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -62,6 +62,7 @@
#include "i40e_rxtx.h"
#include "i40e_pf.h"
#include "i40e_regs.h"
+#include "rte_pmd_i40e.h"
#define ETH_I40E_FLOATING_VEB_ARG "enable_floating_veb"
#define ETH_I40E_FLOATING_VEB_LIST_ARG "floating_veb_list"
@@ -9695,3 +9696,30 @@ i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
return ret;
}
+
+int
+rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct i40e_pf *pf;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (vf >= dev_info.max_vfs)
+ return -EINVAL;
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf > pf->vf_num - 1 || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid argument.");
+ return -EINVAL;
+ }
+
+ i40e_notify_vf_link_status(dev, &pf->vfs[vf]);
+
+ return 0;
+}
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index ddfc140..f70712b 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -897,7 +897,7 @@ i40e_pf_host_process_cmd_cfg_pvid(struct i40e_pf_vf *vf,
return ret;
}
-static void
+void
i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf)
{
struct i40e_virtchnl_pf_event event;
diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h
index cddc45c..59bf2ee 100644
--- a/drivers/net/i40e/i40e_pf.h
+++ b/drivers/net/i40e/i40e_pf.h
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -123,5 +123,7 @@ void i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
uint8_t *msg, uint16_t msglen);
int i40e_pf_host_init(struct rte_eth_dev *dev);
int i40e_pf_host_uninit(struct rte_eth_dev *dev);
+void i40e_notify_vf_link_status(struct rte_eth_dev *dev,
+ struct i40e_pf_vf *vf);
#endif /* _I40E_PF_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
new file mode 100644
index 0000000..14852f2
--- /dev/null
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -0,0 +1,58 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 Intel Corporation. All rights reserved.
+ *
+ * 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
+ * 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
+ * distribution.
+ * * 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
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file rte_pmd_i40e.h
+ * i40e PMD specific functions.
+ *
+ **/
+
+#ifndef _PMD_I40E_H_
+#define _PMD_I40E_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Notify VF when PF link status changes.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF id.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if *vf* invalid.
+ */
+int rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf);
+
+#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index ef35398..4555446 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -2,3 +2,9 @@ DPDK_2.0 {
local: *;
};
+
+DPDK_17.02 {
+ global:
+
+ rte_pmd_i40e_ping_vfs;
+} DPDK_2.0;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 02/29] net/i40e: add callback to user on VF to PF mbox msg
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
The callback asks the user application if it is allowed to
perform the mailbox messages.
If the return value from user is RTE_PMD_I40E_MB_EVENT_PROCEED
then continue. If ACK or NACK, do nothing and send
not_supported to VF.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_pf.c | 230 ++++++++++++++++++++++++++++++++++------
drivers/net/i40e/rte_pmd_i40e.h | 21 ++++
2 files changed, 216 insertions(+), 35 deletions(-)
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index f70712b..8b8a14f 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -55,6 +55,7 @@
#include "i40e_ethdev.h"
#include "i40e_rxtx.h"
#include "i40e_pf.h"
+#include "rte_pmd_i40e.h"
#define I40E_CFG_CRCSTRIP_DEFAULT 1
@@ -272,14 +273,23 @@ i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf,
}
static void
-i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf)
+i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf, bool b_op)
{
struct i40e_virtchnl_version_info info;
info.major = I40E_DPDK_VERSION_MAJOR;
info.minor = I40E_DPDK_VERSION_MINOR;
- i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION,
- I40E_SUCCESS, (uint8_t *)&info, sizeof(info));
+
+ if (b_op)
+ i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION,
+ I40E_SUCCESS,
+ (uint8_t *)&info,
+ sizeof(info));
+ else
+ i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION,
+ I40E_NOT_SUPPORTED,
+ (uint8_t *)&info,
+ sizeof(info));
}
static int
@@ -292,13 +302,20 @@ i40e_pf_host_process_cmd_reset_vf(struct i40e_pf_vf *vf)
}
static int
-i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf)
+i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, bool b_op)
{
struct i40e_virtchnl_vf_resource *vf_res = NULL;
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
uint32_t len = 0;
int ret = I40E_SUCCESS;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(vf,
+ I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
/* only have 1 VSI by default */
len = sizeof(struct i40e_virtchnl_vf_resource) +
I40E_DEFAULT_VF_VSI_NUM *
@@ -423,7 +440,8 @@ i40e_pf_host_hmc_config_txq(struct i40e_hw *hw,
static int
i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
struct i40e_vsi *vsi = vf->vsi;
@@ -432,6 +450,13 @@ i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf,
struct i40e_virtchnl_queue_pair_info *vc_qpi;
int i, ret = I40E_SUCCESS;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(vf,
+ I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (!msg || vc_vqci->num_queue_pairs > vsi->nb_qps ||
vc_vqci->num_queue_pairs > I40E_MAX_VSI_QP ||
msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqci,
@@ -482,7 +507,8 @@ i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_config_vsi_queues_ext(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
struct i40e_vsi *vsi = vf->vsi;
@@ -491,6 +517,14 @@ i40e_pf_host_process_cmd_config_vsi_queues_ext(struct i40e_pf_vf *vf,
struct i40e_virtchnl_queue_pair_ext_info *vc_qpei;
int i, ret = I40E_SUCCESS;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (!msg || vc_vqcei->num_queue_pairs > vsi->nb_qps ||
vc_vqcei->num_queue_pairs > I40E_MAX_VSI_QP ||
msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqcei,
@@ -539,12 +573,21 @@ i40e_pf_host_process_cmd_config_vsi_queues_ext(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_config_irq_map(struct i40e_pf_vf *vf,
- uint8_t *msg, uint16_t msglen)
+ uint8_t *msg, uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_irq_map_info *irqmap =
(struct i40e_virtchnl_irq_map_info *)msg;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen < sizeof(struct i40e_virtchnl_irq_map_info)) {
PMD_DRV_LOG(ERR, "buffer too short");
ret = I40E_ERR_PARAM;
@@ -646,12 +689,21 @@ i40e_pf_host_process_cmd_enable_queues(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_disable_queues(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_queue_select *q_sel =
(struct i40e_virtchnl_queue_select *)msg;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_DISABLE_QUEUES,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen != sizeof(*q_sel)) {
ret = I40E_ERR_PARAM;
goto send_msg;
@@ -669,7 +721,8 @@ i40e_pf_host_process_cmd_disable_queues(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_ether_addr_list *addr_list =
@@ -678,6 +731,14 @@ i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
int i;
struct ether_addr *mac;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
memset(&filter, 0 , sizeof(struct i40e_mac_filter_info));
if (msg == NULL || msglen <= sizeof(*addr_list)) {
@@ -707,7 +768,8 @@ i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_ether_addr_list *addr_list =
@@ -715,6 +777,14 @@ i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf,
int i;
struct ether_addr *mac;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen <= sizeof(*addr_list)) {
PMD_DRV_LOG(ERR, "delete_ether_address argument too short");
ret = I40E_ERR_PARAM;
@@ -739,7 +809,8 @@ i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf,
- uint8_t *msg, uint16_t msglen)
+ uint8_t *msg, uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_vlan_filter_list *vlan_filter_list =
@@ -747,6 +818,14 @@ i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf,
int i;
uint16_t *vid;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_ADD_VLAN,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) {
PMD_DRV_LOG(ERR, "add_vlan argument too short");
ret = I40E_ERR_PARAM;
@@ -771,7 +850,8 @@ i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf,
static int
i40e_pf_host_process_cmd_del_vlan(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_vlan_filter_list *vlan_filter_list =
@@ -779,6 +859,14 @@ i40e_pf_host_process_cmd_del_vlan(struct i40e_pf_vf *vf,
int i;
uint16_t *vid;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_DEL_VLAN,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) {
PMD_DRV_LOG(ERR, "delete_vlan argument too short");
ret = I40E_ERR_PARAM;
@@ -803,7 +891,8 @@ static int
i40e_pf_host_process_cmd_config_promisc_mode(
struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_promisc_info *promisc =
@@ -811,6 +900,14 @@ i40e_pf_host_process_cmd_config_promisc_mode(
struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
bool unicast = FALSE, multicast = FALSE;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen != sizeof(*promisc)) {
ret = I40E_ERR_PARAM;
goto send_msg;
@@ -836,13 +933,20 @@ i40e_pf_host_process_cmd_config_promisc_mode(
}
static int
-i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf)
+i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf, bool b_op)
{
i40e_update_vsi_stats(vf->vsi);
- i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS,
- I40E_SUCCESS, (uint8_t *)&vf->vsi->eth_stats,
- sizeof(vf->vsi->eth_stats));
+ if (b_op)
+ i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS,
+ I40E_SUCCESS,
+ (uint8_t *)&vf->vsi->eth_stats,
+ sizeof(vf->vsi->eth_stats));
+ else
+ i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS,
+ I40E_NOT_SUPPORTED,
+ (uint8_t *)&vf->vsi->eth_stats,
+ sizeof(vf->vsi->eth_stats));
return I40E_SUCCESS;
}
@@ -851,12 +955,21 @@ static int
i40e_pf_host_process_cmd_cfg_vlan_offload(
struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_vlan_offload_info *offload =
(struct i40e_virtchnl_vlan_offload_info *)msg;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen != sizeof(*offload)) {
ret = I40E_ERR_PARAM;
goto send_msg;
@@ -877,12 +990,21 @@ i40e_pf_host_process_cmd_cfg_vlan_offload(
static int
i40e_pf_host_process_cmd_cfg_pvid(struct i40e_pf_vf *vf,
uint8_t *msg,
- uint16_t msglen)
+ uint16_t msglen,
+ bool b_op)
{
int ret = I40E_SUCCESS;
struct i40e_virtchnl_pvid_info *tpid_info =
(struct i40e_virtchnl_pvid_info *)msg;
+ if (!b_op) {
+ i40e_pf_host_send_msg_to_vf(
+ vf,
+ I40E_VIRTCHNL_OP_CFG_VLAN_PVID,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ return ret;
+ }
+
if (msg == NULL || msglen != sizeof(*tpid_info)) {
ret = I40E_ERR_PARAM;
goto send_msg;
@@ -923,6 +1045,8 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
struct i40e_pf_vf *vf;
/* AdminQ will pass absolute VF id, transfer to internal vf id */
uint16_t vf_id = abs_vf_id - hw->func_caps.vf_base_id;
+ struct rte_pmd_i40e_mb_event_param cb_param;
+ bool b_op = TRUE;
if (vf_id > pf->vf_num - 1 || !pf->vfs) {
PMD_DRV_LOG(ERR, "invalid argument");
@@ -937,10 +1061,35 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
return;
}
+ /**
+ * initialise structure to send to user application
+ * will return response from user in retval field
+ */
+ cb_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED;
+ cb_param.vfid = vf_id;
+ cb_param.msg_type = opcode;
+ cb_param.msg = (void *)msg;
+ cb_param.msglen = msglen;
+
+ /**
+ * Ask user application if we're allowed to perform those functions.
+ * If we get cb_param.retval == RTE_PMD_I40E_MB_EVENT_PROCEED,
+ * then business as usual.
+ * If RTE_PMD_I40E_MB_EVENT_NOOP_ACK or RTE_PMD_I40E_MB_EVENT_NOOP_NACK,
+ * do nothing and send not_supported to VF. As PF must send a response
+ * to VF and ACK/NACK is not defined.
+ */
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
+ if (cb_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) {
+ PMD_DRV_LOG(WARNING, "VF to PF message(%d) is not permitted!",
+ opcode);
+ b_op = FALSE;
+ }
+
switch (opcode) {
case I40E_VIRTCHNL_OP_VERSION :
PMD_DRV_LOG(INFO, "OP_VERSION received");
- i40e_pf_host_process_cmd_version(vf);
+ i40e_pf_host_process_cmd_version(vf, b_op);
break;
case I40E_VIRTCHNL_OP_RESET_VF :
PMD_DRV_LOG(INFO, "OP_RESET_VF received");
@@ -948,61 +1097,72 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
break;
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received");
- i40e_pf_host_process_cmd_get_vf_resource(vf);
+ i40e_pf_host_process_cmd_get_vf_resource(vf, b_op);
break;
case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES:
PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received");
- i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, msglen);
+ i40e_pf_host_process_cmd_config_vsi_queues(vf, msg,
+ msglen, b_op);
break;
case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT:
PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES_EXT received");
i40e_pf_host_process_cmd_config_vsi_queues_ext(vf, msg,
- msglen);
+ msglen, b_op);
break;
case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP:
PMD_DRV_LOG(INFO, "OP_CONFIG_IRQ_MAP received");
- i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen);
+ i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen, b_op);
break;
case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received");
- i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen);
- i40e_notify_vf_link_status(dev, vf);
+ if (b_op) {
+ i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen);
+ i40e_notify_vf_link_status(dev, vf);
+ } else {
+ i40e_pf_host_send_msg_to_vf(
+ vf, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
+ I40E_NOT_SUPPORTED, NULL, 0);
+ }
break;
case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received");
- i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen);
+ i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen, b_op);
break;
case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS:
PMD_DRV_LOG(INFO, "OP_ADD_ETHER_ADDRESS received");
- i40e_pf_host_process_cmd_add_ether_address(vf, msg, msglen);
+ i40e_pf_host_process_cmd_add_ether_address(vf, msg,
+ msglen, b_op);
break;
case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS:
PMD_DRV_LOG(INFO, "OP_DEL_ETHER_ADDRESS received");
- i40e_pf_host_process_cmd_del_ether_address(vf, msg, msglen);
+ i40e_pf_host_process_cmd_del_ether_address(vf, msg,
+ msglen, b_op);
break;
case I40E_VIRTCHNL_OP_ADD_VLAN:
PMD_DRV_LOG(INFO, "OP_ADD_VLAN received");
- i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen);
+ i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op);
break;
case I40E_VIRTCHNL_OP_DEL_VLAN:
PMD_DRV_LOG(INFO, "OP_DEL_VLAN received");
- i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen);
+ i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op);
break;
case I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
PMD_DRV_LOG(INFO, "OP_CONFIG_PROMISCUOUS_MODE received");
- i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, msglen);
+ i40e_pf_host_process_cmd_config_promisc_mode(vf, msg,
+ msglen, b_op);
break;
case I40E_VIRTCHNL_OP_GET_STATS:
PMD_DRV_LOG(INFO, "OP_GET_STATS received");
- i40e_pf_host_process_cmd_get_stats(vf);
+ i40e_pf_host_process_cmd_get_stats(vf, b_op);
break;
case I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD:
PMD_DRV_LOG(INFO, "OP_CFG_VLAN_OFFLOAD received");
- i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg, msglen);
+ i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg,
+ msglen, b_op);
break;
case I40E_VIRTCHNL_OP_CFG_VLAN_PVID:
PMD_DRV_LOG(INFO, "OP_CFG_VLAN_PVID received");
- i40e_pf_host_process_cmd_cfg_pvid(vf, msg, msglen);
+ i40e_pf_host_process_cmd_cfg_pvid(vf, msg, msglen, b_op);
break;
/* Don't add command supported below, which will
* return an error code.
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 14852f2..eb7a72b 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -42,6 +42,27 @@
#include <rte_ethdev.h>
/**
+ * Response sent back to i40e driver from user app after callback
+ */
+enum rte_pmd_i40e_mb_event_rsp {
+ RTE_PMD_I40E_MB_EVENT_NOOP_ACK, /**< skip mbox request and ACK */
+ RTE_PMD_I40E_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+ RTE_PMD_I40E_MB_EVENT_PROCEED, /**< proceed with mbox request */
+ RTE_PMD_I40E_MB_EVENT_MAX /**< max value of this enum */
+};
+
+/**
+ * Data sent to the user application when the callback is executed.
+ */
+struct rte_pmd_i40e_mb_event_param {
+ uint16_t vfid; /**< Virtual Function number */
+ uint16_t msg_type; /**< VF to PF message type, see i40e_virtchnl_ops */
+ uint16_t retval; /**< return value */
+ void *msg; /**< pointer to message */
+ uint16_t msglen; /**< length of the message */
+};
+
+/**
* Notify VF when PF link status changes.
*
* @param port
--
2.9.3
^ permalink raw reply related
* [PATCH v4 03/29] net/i40e: set VF MAC anti-spoofing from PF
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
Support enabling/disabling VF MAC anti-spoofing from
PF.
User can call the API on PF to enable/disable a specific
VF's MAC anti-spoofing.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 63 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 19 ++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 83 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fc7e987..c23e6b5 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -9723,3 +9723,66 @@ rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf)
return 0;
}
+
+int
+rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct i40e_pf *pf;
+ struct i40e_pf_vf *vf;
+ struct i40e_vsi *vsi;
+ struct i40e_hw *hw;
+ struct i40e_vsi_context ctxt;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid argument.");
+ return -EINVAL;
+ }
+
+ vf = &pf->vfs[vf_id];
+ vsi = vf->vsi;
+
+ /* Check if it has been already on or off */
+ if (vsi->info.valid_sections &
+ rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SECURITY_VALID)) {
+ if (on) {
+ if ((vsi->info.sec_flags &
+ I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK) ==
+ I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK)
+ return 0; /* already on */
+ } else {
+ if ((vsi->info.sec_flags &
+ I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK) == 0)
+ return 0; /* already off */
+ }
+ }
+
+ vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
+ if (on)
+ vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
+ else
+ vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
+
+ memset(&ctxt, 0, sizeof(ctxt));
+ (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+ ctxt.seid = vsi->seid;
+
+ hw = I40E_VSI_TO_HW(vsi);
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR, "Failed to update VSI params");
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index eb7a72b..52319cf 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -76,4 +76,23 @@ struct rte_pmd_i40e_mb_event_param {
*/
int rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf);
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF on which to set MAC anti spoofing.
+ * @param on
+ * 1 - Enable VFs MAC anti spoofing.
+ * 0 - Disable VFs MAC anti spoofing.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port,
+ uint16_t vf_id,
+ uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 4555446..30efb08 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -7,4 +7,5 @@ DPDK_17.02 {
global:
rte_pmd_i40e_ping_vfs;
+ rte_pmd_i40e_set_vf_mac_anti_spoof;
} DPDK_2.0;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 04/29] net/i40e: set VF VLAN anti-spoofing from PF
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
Support enabling/disabling VF VLAN anti-spoofing from
PF.
User can call the API on PF to enable/disable a specific
VF's VLAN anti-spoofing.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 116 +++++++++++++++++++++++++++++-
drivers/net/i40e/i40e_ethdev.h | 1 +
drivers/net/i40e/rte_pmd_i40e.h | 19 +++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
4 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c23e6b5..77be98b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -4418,6 +4418,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
vsi->user_param = user_param;
+ vsi->vlan_anti_spoof_on = 0;
/* Allocate queues */
switch (vsi->type) {
case I40E_VSI_MAIN :
@@ -5761,17 +5762,35 @@ i40e_set_vlan_filter(struct i40e_vsi *vsi,
uint16_t vlan_id, bool on)
{
uint32_t vid_idx, vid_bit;
+ struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+ struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
+ int ret;
if (vlan_id > ETH_VLAN_ID_MAX)
return;
vid_idx = I40E_VFTA_IDX(vlan_id);
vid_bit = I40E_VFTA_BIT(vlan_id);
+ vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
- if (on)
+ if (on) {
+ if (vsi->vlan_anti_spoof_on) {
+ ret = i40e_aq_add_vlan(hw, vsi->seid,
+ &vlan_data, 1, NULL);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR, "Failed to add vlan filter");
+ }
vsi->vfta[vid_idx] |= vid_bit;
- else
+ } else {
+ if (vsi->vlan_anti_spoof_on) {
+ ret = i40e_aq_remove_vlan(hw, vsi->seid,
+ &vlan_data, 1, NULL);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR,
+ "Failed to remove vlan filter");
+ }
vsi->vfta[vid_idx] &= ~vid_bit;
+ }
}
/**
@@ -9786,3 +9805,96 @@ rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf_id, uint8_t on)
return ret;
}
+
+static int
+i40e_add_rm_all_vlan_filter(struct i40e_vsi *vsi, uint8_t add)
+{
+ uint32_t j, k;
+ uint16_t vlan_id;
+ struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+ struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
+ int ret;
+
+ for (j = 0; j < I40E_VFTA_SIZE; j++) {
+ if (!vsi->vfta[j])
+ continue;
+
+ for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
+ if (!(vsi->vfta[j] & (1 << k)))
+ continue;
+
+ vlan_id = j * I40E_UINT32_BIT_SIZE + k;
+ vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
+ if (add)
+ ret = i40e_aq_add_vlan(hw, vsi->seid,
+ &vlan_data, 1, NULL);
+ else
+ ret = i40e_aq_remove_vlan(hw, vsi->seid,
+ &vlan_data, 1, NULL);
+ if (ret != I40E_SUCCESS) {
+ PMD_DRV_LOG(ERR,
+ "Failed to add/rm vlan filter");
+ return ret;
+ }
+ }
+ }
+
+ return I40E_SUCCESS;
+}
+
+int
+rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct i40e_pf *pf;
+ struct i40e_pf_vf *vf;
+ struct i40e_vsi *vsi;
+ struct i40e_hw *hw;
+ struct i40e_vsi_context ctxt;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid argument.");
+ return -EINVAL;
+ }
+
+ vf = &pf->vfs[vf_id];
+ vsi = vf->vsi;
+
+ /* Check if it has been already on or off */
+ if (vsi->vlan_anti_spoof_on == on)
+ return 0; /* already on or off */
+
+ vsi->vlan_anti_spoof_on = on;
+ ret = i40e_add_rm_all_vlan_filter(vsi, on);
+ if (ret)
+ return ret;
+
+ vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
+ if (on)
+ vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
+ else
+ vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
+
+ memset(&ctxt, 0, sizeof(ctxt));
+ (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+ ctxt.seid = vsi->seid;
+
+ hw = I40E_VSI_TO_HW(vsi);
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR, "Failed to update VSI params");
+
+ return ret;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 298cef4..0db140b 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -300,6 +300,7 @@ struct i40e_vsi {
uint16_t msix_intr; /* The MSIX interrupt binds to VSI */
uint16_t nb_msix; /* The max number of msix vector */
uint8_t enabled_tc; /* The traffic class enabled */
+ uint8_t vlan_anti_spoof_on; /* The VLAN anti-spoofing enabled */
struct i40e_bw_info bw_info; /* VSI bandwidth information */
};
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 52319cf..c8736c8 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -95,4 +95,23 @@ int rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port,
uint16_t vf_id,
uint8_t on);
+/**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF on which to set VLAN anti spoofing.
+ * @param on
+ * 1 - Enable VFs VLAN anti spoofing.
+ * 0 - Disable VFs VLAN anti spoofing.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port,
+ uint16_t vf_id,
+ uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 30efb08..fff6cf9 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -8,4 +8,5 @@ DPDK_17.02 {
rte_pmd_i40e_ping_vfs;
rte_pmd_i40e_set_vf_mac_anti_spoof;
+ rte_pmd_i40e_set_vf_vlan_anti_spoof;
} DPDK_2.0;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 05/29] net/i40e: set Tx loopback from PF
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
Support enabling/disabling TX loopback from PF.
User can call the API on PF to enable/disable TX loopback
for all the PF and VFs.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 219 ++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 16 +++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 236 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 77be98b..89f5784 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -9898,3 +9898,222 @@ rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf_id, uint8_t on)
return ret;
}
+
+static int
+i40e_vsi_rm_mac_filter(struct i40e_vsi *vsi)
+{
+ struct i40e_mac_filter *f;
+ struct i40e_macvlan_filter *mv_f;
+ int i, vlan_num;
+ enum rte_mac_filter_type filter_type;
+ int ret = I40E_SUCCESS;
+
+ /* remove all the MACs */
+ TAILQ_FOREACH(f, &vsi->mac_list, next) {
+ vlan_num = vsi->vlan_num;
+ filter_type = f->mac_info.filter_type;
+ if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+ filter_type == RTE_MACVLAN_HASH_MATCH) {
+ if (vlan_num == 0) {
+ PMD_DRV_LOG(ERR,
+ "VLAN number shouldn't be 0\n");
+ return I40E_ERR_PARAM;
+ }
+ } else if (filter_type == RTE_MAC_PERFECT_MATCH ||
+ filter_type == RTE_MAC_HASH_MATCH)
+ vlan_num = 1;
+
+ mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
+ if (!mv_f) {
+ PMD_DRV_LOG(ERR, "failed to allocate memory");
+ return I40E_ERR_NO_MEMORY;
+ }
+
+ for (i = 0; i < vlan_num; i++) {
+ mv_f[i].filter_type = filter_type;
+ (void)rte_memcpy(&mv_f[i].macaddr,
+ &f->mac_info.mac_addr,
+ ETH_ADDR_LEN);
+ }
+ if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+ filter_type == RTE_MACVLAN_HASH_MATCH) {
+ ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
+ &f->mac_info.mac_addr);
+ if (ret != I40E_SUCCESS) {
+ rte_free(mv_f);
+ return ret;
+ }
+ }
+
+ ret = i40e_remove_macvlan_filters(vsi, mv_f, vlan_num);
+ if (ret != I40E_SUCCESS) {
+ rte_free(mv_f);
+ return ret;
+ }
+
+ rte_free(mv_f);
+ ret = I40E_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+i40e_vsi_restore_mac_filter(struct i40e_vsi *vsi)
+{
+ struct i40e_mac_filter *f;
+ struct i40e_macvlan_filter *mv_f;
+ int i, vlan_num = 0;
+ int ret = I40E_SUCCESS;
+
+ /* restore all the MACs */
+ TAILQ_FOREACH(f, &vsi->mac_list, next) {
+ if ((f->mac_info.filter_type == RTE_MACVLAN_PERFECT_MATCH) ||
+ (f->mac_info.filter_type == RTE_MACVLAN_HASH_MATCH)) {
+ /**
+ * If vlan_num is 0, that's the first time to add mac,
+ * set mask for vlan_id 0.
+ */
+ if (vsi->vlan_num == 0) {
+ i40e_set_vlan_filter(vsi, 0, 1);
+ vsi->vlan_num = 1;
+ }
+ vlan_num = vsi->vlan_num;
+ } else if ((f->mac_info.filter_type == RTE_MAC_PERFECT_MATCH) ||
+ (f->mac_info.filter_type == RTE_MAC_HASH_MATCH))
+ vlan_num = 1;
+
+ mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
+ if (!mv_f) {
+ PMD_DRV_LOG(ERR, "failed to allocate memory");
+ return I40E_ERR_NO_MEMORY;
+ }
+
+ for (i = 0; i < vlan_num; i++) {
+ mv_f[i].filter_type = f->mac_info.filter_type;
+ (void)rte_memcpy(&mv_f[i].macaddr,
+ &f->mac_info.mac_addr,
+ ETH_ADDR_LEN);
+ }
+
+ if (f->mac_info.filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+ f->mac_info.filter_type == RTE_MACVLAN_HASH_MATCH) {
+ ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
+ &f->mac_info.mac_addr);
+ if (ret != I40E_SUCCESS) {
+ rte_free(mv_f);
+ return ret;
+ }
+ }
+
+ ret = i40e_add_macvlan_filters(vsi, mv_f, vlan_num);
+ if (ret != I40E_SUCCESS) {
+ rte_free(mv_f);
+ return ret;
+ }
+
+ rte_free(mv_f);
+ ret = I40E_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+i40e_vsi_set_tx_loopback(struct i40e_vsi *vsi, uint8_t on)
+{
+ struct i40e_vsi_context ctxt;
+ struct i40e_hw *hw;
+ int ret;
+
+ hw = I40E_VSI_TO_HW(vsi);
+
+ /* Use the FW API if FW >= v5.0 */
+ if (hw->aq.fw_maj_ver < 5) {
+ PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
+ return -ENOTSUP;
+ }
+
+ /* Check if it has been already on or off */
+ if (vsi->info.valid_sections &
+ rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID)) {
+ if (on) {
+ if ((vsi->info.switch_id &
+ I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) ==
+ I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB)
+ return 0; /* already on */
+ } else {
+ if ((vsi->info.switch_id &
+ I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) == 0)
+ return 0; /* already off */
+ }
+ }
+
+ /* remove all the MACs first */
+ ret = i40e_vsi_rm_mac_filter(vsi);
+ if (ret)
+ return ret;
+
+ vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+ if (on)
+ vsi->info.switch_id |= I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB;
+ else
+ vsi->info.switch_id &= ~I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB;
+
+ memset(&ctxt, 0, sizeof(ctxt));
+ (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+ ctxt.seid = vsi->seid;
+
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret != I40E_SUCCESS) {
+ PMD_DRV_LOG(ERR, "Failed to update VSI params");
+ return ret;
+ }
+
+ /* add all the MACs back */
+ ret = i40e_vsi_restore_mac_filter(vsi);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+int
+rte_pmd_i40e_set_tx_loopback(uint8_t port, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_pf_vf *vf;
+ struct i40e_vsi *vsi;
+ uint16_t vf_id;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ /* setup PF TX loopback */
+ vsi = pf->main_vsi;
+ ret = i40e_vsi_set_tx_loopback(vsi, on);
+ if (ret)
+ return ret;
+
+ /* setup TX loopback for all the VFs */
+ if (!pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid argument.");
+ return -EINVAL;
+ }
+
+ for (vf_id = 0; vf_id < pf->vf_num; vf_id++) {
+ vf = &pf->vfs[vf_id];
+ vsi = vf->vsi;
+
+ ret = i40e_vsi_set_tx_loopback(vsi, on);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index c8736c8..3c65be4 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -114,4 +114,20 @@ int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port,
uint16_t vf_id,
uint8_t on);
+/**
+ * Enable/Disable TX loopback on all the PF and VFs.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param on
+ * 1 - Enable TX loopback.
+ * 0 - Disable TX loopback.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_tx_loopback(uint8_t port,
+ uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index fff6cf9..3da04d3 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -9,4 +9,5 @@ DPDK_17.02 {
rte_pmd_i40e_ping_vfs;
rte_pmd_i40e_set_vf_mac_anti_spoof;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
+ rte_pmd_i40e_set_tx_loopback;
} DPDK_2.0;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 06/29] net/i40e: set VF unicast promisc mode from PF
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
Support enabling/disabling VF unicast promiscuous mode from
PF.
User can call the API on PF to enable/disable a specific
VF's unicast promiscuous mode.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 36 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 19 ++++++++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 56 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 89f5784..ffb69a1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10117,3 +10117,39 @@ rte_pmd_i40e_set_tx_loopback(uint8_t port, uint8_t on)
return ret;
}
+
+int
+rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct i40e_pf *pf;
+ struct i40e_pf_vf *vf;
+ struct i40e_hw *hw;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid argument.");
+ return -EINVAL;
+ }
+
+ vf = &pf->vfs[vf_id];
+ hw = I40E_VSI_TO_HW(vf->vsi);
+
+ ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vf->vsi->seid,
+ on, NULL, true);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR, "Failed to set unicast promiscuous mode");
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 3c65be4..4c98136 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -130,4 +130,23 @@ int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port,
int rte_pmd_i40e_set_tx_loopback(uint8_t port,
uint8_t on);
+/**
+ * Enable/Disable VF unicast promiscuous mode.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF on which to set.
+ * @param on
+ * 1 - Enable.
+ * 0 - Disable.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port,
+ uint16_t vf_id,
+ uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 3da04d3..24b78ce 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -10,4 +10,5 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_mac_anti_spoof;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
rte_pmd_i40e_set_tx_loopback;
+ rte_pmd_i40e_set_vf_unicast_promisc;
} DPDK_2.0;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 07/29] net/i40e: set VF multicast promisc mode from PF
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Wenzhuo Lu <wenzhuo.lu@intel.com>
Support enabling/disabling VF multicast promiscuous mode from
PF.
User can call the API on PF to enable/disable a specific
VF's multicast promiscuous mode.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 36 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 19 ++++++++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 56 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ffb69a1..e2214bd 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10153,3 +10153,39 @@ rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port, uint16_t vf_id, uint8_t on)
return ret;
}
+
+int
+rte_pmd_i40e_set_vf_multicast_promisc(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_dev_info dev_info;
+ struct i40e_pf *pf;
+ struct i40e_pf_vf *vf;
+ struct i40e_hw *hw;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ rte_eth_dev_info_get(port, &dev_info);
+
+ if (vf_id >= dev_info.max_vfs)
+ return -EINVAL;
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid argument.");
+ return -EINVAL;
+ }
+
+ vf = &pf->vfs[vf_id];
+ hw = I40E_VSI_TO_HW(vf->vsi);
+
+ ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid,
+ on, NULL);
+ if (ret != I40E_SUCCESS)
+ PMD_DRV_LOG(ERR, "Failed to set multicast promiscuous mode");
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 4c98136..9091520 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -149,4 +149,23 @@ int rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port,
uint16_t vf_id,
uint8_t on);
+/**
+ * Enable/Disable VF multicast promiscuous mode.
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * VF on which to set.
+ * @param on
+ * 1 - Enable.
+ * 0 - Disable.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_multicast_promisc(uint8_t port,
+ uint16_t vf_id,
+ uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 24b78ce..08d3028 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -11,4 +11,5 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_vlan_anti_spoof;
rte_pmd_i40e_set_tx_loopback;
rte_pmd_i40e_set_vf_unicast_promisc;
+ rte_pmd_i40e_set_vf_multicast_promisc;
} DPDK_2.0;
--
2.9.3
^ permalink raw reply related
* [PATCH v4 08/29] net/i40e: enable VF MTU change
From: Ferruh Yigit @ 2016-12-16 14:38 UTC (permalink / raw)
To: dev; +Cc: Jingjing Wu
In-Reply-To: <20161216143919.4909-1-ferruh.yigit@intel.com>
From: Qi Zhang <qi.z.zhang@intel.com>
This patch implement mtu_set ops for i40e VF.
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
drivers/net/i40e/i40e_ethdev_vf.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 12da0ec..bce01d0 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -151,6 +151,7 @@ static int i40evf_dev_rss_hash_update(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
struct rte_eth_rss_conf *rss_conf);
+static int i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
static int
i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
static int
@@ -225,6 +226,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
.reta_query = i40evf_dev_rss_reta_query,
.rss_hash_update = i40evf_dev_rss_hash_update,
.rss_hash_conf_get = i40evf_dev_rss_hash_conf_get,
+ .mtu_set = i40evf_dev_mtu_set,
};
/*
@@ -2641,3 +2643,34 @@ i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
return 0;
}
+
+static int
+i40evf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct rte_eth_dev_data *dev_data = vf->dev_data;
+ uint32_t frame_size = mtu + ETHER_HDR_LEN
+ + ETHER_CRC_LEN + I40E_VLAN_TAG_SIZE;
+ int ret = 0;
+
+ /* check if mtu is within the allowed range */
+ if ((mtu < ETHER_MIN_MTU) || (frame_size > I40E_FRAME_SIZE_MAX))
+ return -EINVAL;
+
+ /* mtu setting is forbidden if port is start */
+ if (dev_data->dev_started) {
+ PMD_DRV_LOG(ERR,
+ "port %d must be stopped before configuration\n",
+ dev_data->port_id);
+ return -EBUSY;
+ }
+
+ if (frame_size > ETHER_MAX_LEN)
+ dev_data->dev_conf.rxmode.jumbo_frame = 1;
+ else
+ dev_data->dev_conf.rxmode.jumbo_frame = 0;
+
+ dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+
+ return ret;
+}
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox