@@ -556,7 +556,7 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
goto err;
/* reserve an ethdev entry */
- eth_dev = rte_eth_dev_allocate(name);
+ eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_PCI);
if (eth_dev == NULL)
goto err;
@@ -227,7 +227,7 @@ rte_eth_dev_find_free_port(void)
}
struct rte_eth_dev *
-rte_eth_dev_allocate(const char *name)
+rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)
{
uint8_t port_id;
struct rte_eth_dev *eth_dev;
@@ -251,6 +251,7 @@ rte_eth_dev_allocate(const char *name)
snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
eth_dev->data->port_id = port_id;
eth_dev->attached = DEV_ATTACHED;
+ eth_dev->dev_type = type;
nb_ports++;
return eth_dev;
}
@@ -262,6 +263,7 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
return -EINVAL;
eth_dev->attached = 0;
+ eth_dev->dev_type = RTE_ETH_DEV_UNKNOWN;
nb_ports--;
return 0;
}
@@ -300,7 +302,7 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
rte_eth_dev_create_unique_device_name(ethdev_name,
sizeof(ethdev_name), pci_dev);
- eth_dev = rte_eth_dev_allocate(ethdev_name);
+ eth_dev = rte_eth_dev_allocate(ethdev_name, RTE_ETH_DEV_PCI);
if (eth_dev == NULL)
return -ENOMEM;
@@ -426,6 +428,14 @@ rte_eth_dev_count(void)
return (nb_ports);
}
+enum rte_eth_dev_type
+rte_eth_dev_get_device_type(uint8_t port_id)
+{
+ if (!rte_eth_dev_is_valid_port(port_id))
+ return -1;
+ return rte_eth_devices[port_id].dev_type;
+}
+
int
rte_eth_dev_save(struct rte_eth_dev *devs, size_t size)
{
@@ -523,6 +533,17 @@ rte_eth_dev_is_detachable(uint8_t port_id)
return -EINVAL;
}
+ if (rte_eth_devices[port_id].dev_type == RTE_ETH_DEV_PCI) {
+ switch (rte_eth_devices[port_id].pci_dev->pt_driver) {
+ case RTE_PT_IGB_UIO:
+ case RTE_PT_UIO_GENERIC:
+ break;
+ case RTE_PT_VFIO:
+ default:
+ return -ENOTSUP;
+ }
+ }
+
drv_flags = rte_eth_devices[port_id].driver->pci_drv.drv_flags;
return !(drv_flags & RTE_PCI_DRV_DETACHABLE);
}
@@ -1523,6 +1523,17 @@ struct eth_dev_ops {
};
/**
+ * The eth device type
+ */
+enum rte_eth_dev_type {
+ RTE_ETH_DEV_UNKNOWN, /**< unknown device type */
+ RTE_ETH_DEV_PCI,
+ /**< Physical function and Virtual function of PCI devices */
+ RTE_ETH_DEV_VIRTUAL, /**< non hardware device */
+ RTE_ETH_DEV_MAX /**< max value of this enum */
+};
+
+/**
* @internal
* The generic data structure associated with each ethernet device.
*
@@ -1541,6 +1552,7 @@ struct rte_eth_dev {
struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
struct rte_eth_dev_cb_list callbacks; /**< User application callbacks */
uint8_t attached; /**< Flag indicating the port is attached */
+ enum rte_eth_dev_type dev_type; /**< Flag indicating the device type */
};
struct rte_eth_dev_sriov {
@@ -1618,6 +1630,15 @@ extern uint8_t rte_eth_dev_count(void);
/**
* Function for internal use by port hotplug functions.
+ * Get the device type to know whether the device is physical or virtual.
+ * @param port_id The port identifier of the Ethernet device
+ * @return
+ * - Device type.
+ */
+extern enum rte_eth_dev_type rte_eth_dev_get_device_type(uint8_t port_id);
+
+/**
+ * Function for internal use by port hotplug functions.
* Copies current ethdev structures to the specified pointer.
*
* @param devs The pointer to the ethdev structures
@@ -1706,10 +1727,12 @@ extern struct rte_eth_dev *rte_eth_dev_allocated(const char *name);
* to that slot for the driver to use.
*
* @param name Unique identifier name for each Ethernet device
+ * @param type Device type of this Ethernet device
* @return
* - Slot in the rte_dev_devices array for a new device;
*/
-struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name,
+ enum rte_eth_dev_type type);
/**
* Function for internal use by dummy drivers primarily, e.g. ring-based
@@ -42,6 +42,7 @@ DPDK_2.0 {
rte_eth_dev_get_5tuple_filter;
rte_eth_dev_get_addr_by_port;
rte_eth_dev_get_changed_port;
+ rte_eth_dev_get_device_type;
rte_eth_dev_get_ethertype_filter;
rte_eth_dev_get_flex_filter;
rte_eth_dev_get_mtu;
@@ -649,7 +649,7 @@ rte_pmd_init_internals(const char *name,
}
/* reserve an ethdev entry */
- *eth_dev = rte_eth_dev_allocate(name);
+ *eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
if (*eth_dev == NULL)
goto error;
@@ -235,7 +235,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
}
/* reserve an ethdev entry */
- eth_dev = rte_eth_dev_allocate(name);
+ eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
if (eth_dev == NULL) {
RTE_BOND_LOG(ERR, "Unable to allocate rte_eth_dev");
goto err;
@@ -709,7 +709,7 @@ rte_pmd_init_internals(const char *name, const unsigned nb_rx_queues,
goto error;
/* reserve an ethdev entry */
- *eth_dev = rte_eth_dev_allocate(name);
+ *eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
if (*eth_dev == NULL)
goto error;
@@ -297,7 +297,7 @@ rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[],
goto error;
/* reserve an ethdev entry */
- eth_dev = rte_eth_dev_allocate(name);
+ eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
if (eth_dev == NULL)
goto error;
@@ -648,7 +648,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
goto err;
/* reserve an ethdev entry */
- eth_dev = rte_eth_dev_allocate(name);
+ eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
if (eth_dev == NULL)
goto err;