@@ -325,6 +325,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
}
int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+ struct rte_soc_device *soc_dev)
+{
+ struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+ rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+ sizeof(ethdev_name));
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc(
+ "ethdev private structure",
+ eth_drv->dev_private_size,
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL)
+ rte_panic("Cannot allocate memzone for private port "
+ "data\n");
+ }
+ eth_dev->soc_dev = soc_dev;
+ eth_dev->driver = eth_drv;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* init user callbacks */
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+ /*
+ * Set the default MTU.
+ */
+ eth_dev->data->mtu = ETHER_MTU;
+
+ /* Invoke PMD device initialization function */
+ diag = (*eth_drv->eth_dev_init)(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+ soc_drv->driver.name,
+ soc_dev->addr.name);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+ const struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+ int ret;
+
+ if (soc_dev == NULL)
+ return -EINVAL;
+
+ rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+ sizeof(ethdev_name));
+
+ eth_dev = rte_eth_dev_allocated(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENODEV;
+
+ eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+ /* Invoke PMD device uninit function */
+ if (*eth_drv->eth_dev_uninit) {
+ ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+ if (ret)
+ return ret;
+ }
+
+ /* free ether device */
+ rte_eth_dev_release_port(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ eth_dev->soc_dev = NULL;
+ eth_dev->driver = NULL;
+ eth_dev->data = NULL;
+
+ return 0;
+}
+
+
+int
rte_eth_dev_is_valid_port(uint8_t port_id)
{
if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1557,6 +1652,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
dev_info->pci_dev = dev->pci_dev;
+ dev_info->soc_dev = dev->soc_dev;
dev_info->driver_name = dev->data->drv_name;
dev_info->nb_rx_queues = dev->data->nb_rx_queues;
dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2535,8 +2631,15 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
static inline
struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
{
- if (dev->pci_dev)
+ if (dev->pci_dev) {
+ RTE_ASSERT(dev->soc_dev == NULL);
return &dev->pci_dev->intr_handle;
+ }
+
+ if (dev->soc_dev) {
+ RTE_ASSERT(dev->pci_dev == NULL);
+ return &dev->soc_dev->intr_handle;
+ }
RTE_ASSERT(0);
return NULL;
@@ -2573,6 +2676,23 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
return 0;
}
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+ if (dev->pci_dev) {
+ RTE_ASSERT(dev->soc_dev == NULL);
+ return dev->driver->pci_drv.driver.name;
+ }
+
+ if (dev->soc_dev) {
+ RTE_ASSERT(dev->pci_dev == NULL);
+ return dev->driver->soc_drv.driver.name;
+ }
+
+ RTE_ASSERT(0);
+ return NULL;
+}
+
const struct rte_memzone *
rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
uint16_t queue_id, size_t size, unsigned align,
@@ -2580,9 +2700,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
{
char z_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
+ const char *drv_name;
+ drv_name = eth_dev_get_driver_name(dev);
snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- dev->driver->pci_drv.driver.name, ring_name,
+ drv_name, ring_name,
dev->data->port_id, queue_id);
mz = rte_memzone_lookup(z_name);
@@ -3229,6 +3351,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
eth_dev->data->drv_name = pci_dev->driver->driver.name;
}
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+ struct rte_soc_device *soc_dev)
+{
+ if ((eth_dev == NULL) || (soc_dev == NULL)) {
+ RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+ eth_dev, soc_dev);
+ return;
+ }
+
+ RTE_ASSERT(eth_dev->soc_dev != NULL);
+
+ eth_dev->data->dev_flags = 0;
+ if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+ if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+ eth_dev->data->numa_node = soc_dev->device.numa_node;
+ eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
int
rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
struct rte_eth_l2_tunnel_conf *l2_tunnel)
@@ -180,6 +180,7 @@ extern "C" {
#include <rte_log.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_soc.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include "rte_ether.h"
@@ -877,6 +878,7 @@ struct rte_eth_conf {
*/
struct rte_eth_dev_info {
struct rte_pci_device *pci_dev; /**< Device PCI information. */
+ struct rte_soc_device *soc_dev; /**< Device SoC information. */
const char *driver_name; /**< Device Driver name. */
unsigned int if_index; /**< Index to bound host interface, or 0 if none.
Use if_indextoname() to translate into an interface name. */
@@ -1626,6 +1628,7 @@ struct rte_eth_dev {
const struct eth_driver *driver;/**< Driver for this device */
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+ struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
/** User application callbacks for NIC interrupts */
struct rte_eth_dev_cb_list link_intr_cbs;
/**
@@ -1860,6 +1863,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
*/
struct eth_driver {
struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
+ struct rte_soc_driver soc_drv; /**< The PMD is also a SoC driver. */
eth_dev_init_t eth_dev_init; /**< Device init function. */
eth_dev_uninit_t eth_dev_uninit; /**< Device uninit function. */
unsigned int dev_private_size; /**< Size of device private data. */
@@ -4262,6 +4266,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
struct rte_pci_device *pci_dev);
/**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ * - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+ struct rte_soc_device *soc_dev);
+
+/**
* Create memzone for HW rings.
* malloc can't be used as the physical address is needed.
* If the memzone is already created, then this function returns a ptr
@@ -4376,6 +4394,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
*/
int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+ struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
#ifdef __cplusplus
}
#endif