Imported Upstream version 17.05
[deb_dpdk.git] / lib / librte_ether / rte_ethdev.c
index 5a31759..83898a8 100644 (file)
@@ -138,10 +138,18 @@ enum {
        STAT_QMAP_RX
 };
 
-enum {
-       DEV_DETACHED = 0,
-       DEV_ATTACHED
-};
+uint8_t
+rte_eth_find_next(uint8_t port_id)
+{
+       while (port_id < RTE_MAX_ETHPORTS &&
+              rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED)
+               port_id++;
+
+       if (port_id >= RTE_MAX_ETHPORTS)
+               return RTE_MAX_ETHPORTS;
+
+       return port_id;
+}
 
 static void
 rte_eth_dev_data_alloc(void)
@@ -170,7 +178,7 @@ rte_eth_dev_allocated(const char *name)
        unsigned i;
 
        for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-               if ((rte_eth_devices[i].attached == DEV_ATTACHED) &&
+               if ((rte_eth_devices[i].state == RTE_ETH_DEV_ATTACHED) &&
                    strcmp(rte_eth_devices[i].data->name, name) == 0)
                        return &rte_eth_devices[i];
        }
@@ -183,7 +191,7 @@ rte_eth_dev_find_free_port(void)
        unsigned i;
 
        for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-               if (rte_eth_devices[i].attached == DEV_DETACHED)
+               if (rte_eth_devices[i].state == RTE_ETH_DEV_UNUSED)
                        return i;
        }
        return RTE_MAX_ETHPORTS;
@@ -195,7 +203,8 @@ eth_dev_get(uint8_t port_id)
        struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
 
        eth_dev->data = &rte_eth_dev_data[port_id];
-       eth_dev->attached = DEV_ATTACHED;
+       eth_dev->state = RTE_ETH_DEV_ATTACHED;
+       TAILQ_INIT(&(eth_dev->link_intr_cbs));
 
        eth_dev_last_created_port = port_id;
        nb_ports++;
@@ -224,9 +233,11 @@ rte_eth_dev_allocate(const char *name)
                return NULL;
        }
 
+       memset(&rte_eth_dev_data[port_id], 0, sizeof(struct rte_eth_dev_data));
        eth_dev = eth_dev_get(port_id);
        snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
        eth_dev->data->port_id = port_id;
+       eth_dev->data->mtu = ETHER_MTU;
 
        return eth_dev;
 }
@@ -236,8 +247,8 @@ rte_eth_dev_allocate(const char *name)
  * makes sure that the same device would have the same port id both
  * in the primary and secondary process.
  */
-static struct rte_eth_dev *
-eth_dev_attach_secondary(const char *name)
+struct rte_eth_dev *
+rte_eth_dev_attach_secondary(const char *name)
 {
        uint8_t i;
        struct rte_eth_dev *eth_dev;
@@ -268,121 +279,16 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
        if (eth_dev == NULL)
                return -EINVAL;
 
-       eth_dev->attached = DEV_DETACHED;
+       eth_dev->state = RTE_ETH_DEV_UNUSED;
        nb_ports--;
        return 0;
 }
 
-int
-rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
-                     struct rte_pci_device *pci_dev)
-{
-       struct eth_driver    *eth_drv;
-       struct rte_eth_dev *eth_dev;
-       char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-
-       int diag;
-
-       eth_drv = (struct eth_driver *)pci_drv;
-
-       rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
-                       sizeof(ethdev_name));
-
-       if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-               eth_dev = rte_eth_dev_allocate(ethdev_name);
-               if (eth_dev == NULL)
-                       return -ENOMEM;
-
-               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");
-       } else {
-               eth_dev = eth_dev_attach_secondary(ethdev_name);
-               if (eth_dev == NULL) {
-                       /*
-                        * if we failed to attach a device, it means the
-                        * device is skipped in primary process, due to
-                        * some errors. If so, we return a positive value,
-                        * to let EAL skip it for the secondary process
-                        * as well.
-                        */
-                       return 1;
-               }
-       }
-       eth_dev->pci_dev = pci_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(vendor_id=0x%x device_id=0x%x) failed\n",
-                       pci_drv->driver.name,
-                       (unsigned) pci_dev->id.vendor_id,
-                       (unsigned) pci_dev->id.device_id);
-       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_pci_remove(struct rte_pci_device *pci_dev)
-{
-       const struct eth_driver *eth_drv;
-       struct rte_eth_dev *eth_dev;
-       char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-       int ret;
-
-       if (pci_dev == NULL)
-               return -EINVAL;
-
-       rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
-                       sizeof(ethdev_name));
-
-       eth_dev = rte_eth_dev_allocated(ethdev_name);
-       if (eth_dev == NULL)
-               return -ENODEV;
-
-       eth_drv = (const struct eth_driver *)pci_dev->driver;
-
-       /* 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->pci_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 ||
-           rte_eth_devices[port_id].attached != DEV_ATTACHED)
+           rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED)
                return 0;
        else
                return 1;
@@ -434,9 +340,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)
                return -ENODEV;
 
        *port_id = RTE_MAX_ETHPORTS;
-
-       for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-
+       RTE_ETH_FOREACH_DEV(i) {
                if (!strncmp(name,
                        rte_eth_dev_data[i].name, strlen(name))) {
 
@@ -460,8 +364,8 @@ rte_eth_dev_is_detachable(uint8_t port_id)
        case RTE_KDRV_UIO_GENERIC:
        case RTE_KDRV_NIC_UIO:
        case RTE_KDRV_NONE:
-               break;
        case RTE_KDRV_VFIO:
+               break;
        default:
                return -ENOTSUP;
        }
@@ -588,6 +492,9 @@ rte_eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 
                for (i = nb_queues; i < old_nb_queues; i++)
                        (*dev->dev_ops->rx_queue_release)(rxq[i]);
+
+               rte_free(dev->data->rx_queues);
+               dev->data->rx_queues = NULL;
        }
        dev->data->nb_rx_queues = nb_queues;
        return 0;
@@ -739,6 +646,9 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
 
                for (i = nb_queues; i < old_nb_queues; i++)
                        (*dev->dev_ops->tx_queue_release)(txq[i]);
+
+               rte_free(dev->data->tx_queues);
+               dev->data->tx_queues = NULL;
        }
        dev->data->nb_tx_queues = nb_queues;
        return 0;
@@ -839,16 +749,19 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
                return -EINVAL;
        }
 
-       /*
-        * If link state interrupt is enabled, check that the
-        * device supports it.
-        */
+       /* Check that the device supports requested interrupts */
        if ((dev_conf->intr_conf.lsc == 1) &&
                (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
                        RTE_PMD_DEBUG_TRACE("driver %s does not support lsc\n",
                                        dev->data->drv_name);
                        return -EINVAL;
        }
+       if ((dev_conf->intr_conf.rmv == 1) &&
+           (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
+               RTE_PMD_DEBUG_TRACE("driver %s does not support rmv\n",
+                                   dev->data->drv_name);
+               return -EINVAL;
+       }
 
        /*
         * If jumbo frames are enabled, check that the maximum RX packet
@@ -909,39 +822,61 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
        return 0;
 }
 
+void
+_rte_eth_dev_reset(struct rte_eth_dev *dev)
+{
+       if (dev->data->dev_started) {
+               RTE_PMD_DEBUG_TRACE(
+                       "port %d must be stopped to allow reset\n",
+                       dev->data->port_id);
+               return;
+       }
+
+       rte_eth_dev_rx_queue_config(dev, 0);
+       rte_eth_dev_tx_queue_config(dev, 0);
+
+       memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf));
+}
+
 static void
 rte_eth_dev_config_restore(uint8_t port_id)
 {
        struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info;
-       struct ether_addr addr;
+       struct ether_addr *addr;
        uint16_t i;
        uint32_t pool = 0;
+       uint64_t pool_mask;
 
        dev = &rte_eth_devices[port_id];
 
        rte_eth_dev_info_get(port_id, &dev_info);
 
-       if (RTE_ETH_DEV_SRIOV(dev).active)
-               pool = RTE_ETH_DEV_SRIOV(dev).def_vmdq_idx;
-
-       /* replay MAC address configuration */
-       for (i = 0; i < dev_info.max_mac_addrs; i++) {
-               addr = dev->data->mac_addrs[i];
-
-               /* skip zero address */
-               if (is_zero_ether_addr(&addr))
-                       continue;
-
-               /* add address to the hardware */
-               if  (*dev->dev_ops->mac_addr_add &&
-                       (dev->data->mac_pool_sel[i] & (1ULL << pool)))
-                       (*dev->dev_ops->mac_addr_add)(dev, &addr, i, pool);
-               else {
-                       RTE_PMD_DEBUG_TRACE("port %d: MAC address array not supported\n",
-                                       port_id);
-                       /* exit the loop but not return an error */
-                       break;
+       /* replay MAC address configuration including default MAC */
+       addr = &dev->data->mac_addrs[0];
+       if (*dev->dev_ops->mac_addr_set != NULL)
+               (*dev->dev_ops->mac_addr_set)(dev, addr);
+       else if (*dev->dev_ops->mac_addr_add != NULL)
+               (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool);
+
+       if (*dev->dev_ops->mac_addr_add != NULL) {
+               for (i = 1; i < dev_info.max_mac_addrs; i++) {
+                       addr = &dev->data->mac_addrs[i];
+
+                       /* skip zero address */
+                       if (is_zero_ether_addr(addr))
+                               continue;
+
+                       pool = 0;
+                       pool_mask = dev->data->mac_pool_sel[i];
+
+                       do {
+                               if (pool_mask & 1ULL)
+                                       (*dev->dev_ops->mac_addr_add)(dev,
+                                               addr, i, pool);
+                               pool_mask >>= 1;
+                               pool++;
+                       } while (pool_mask);
                }
        }
 
@@ -1051,8 +986,10 @@ rte_eth_dev_close(uint8_t port_id)
        dev->data->dev_started = 0;
        (*dev->dev_ops->dev_close)(dev);
 
+       dev->data->nb_rx_queues = 0;
        rte_free(dev->data->rx_queues);
        dev->data->rx_queues = NULL;
+       dev->data->nb_tx_queues = 0;
        rte_free(dev->data->tx_queues);
        dev->data->tx_queues = NULL;
 }
@@ -1067,6 +1004,7 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
        uint32_t mbp_buf_size;
        struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info;
+       void **rxq;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1125,6 +1063,14 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
                return -EINVAL;
        }
 
+       rxq = dev->data->rx_queues;
+       if (rxq[rx_queue_id]) {
+               RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release,
+                                       -ENOTSUP);
+               (*dev->dev_ops->rx_queue_release)(rxq[rx_queue_id]);
+               rxq[rx_queue_id] = NULL;
+       }
+
        if (rx_conf == NULL)
                rx_conf = &dev_info.default_rxconf;
 
@@ -1146,6 +1092,7 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id,
 {
        struct rte_eth_dev *dev;
        struct rte_eth_dev_info dev_info;
+       void **txq;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -1178,6 +1125,14 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id,
                return -EINVAL;
        }
 
+       txq = dev->data->tx_queues;
+       if (txq[tx_queue_id]) {
+               RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release,
+                                       -ENOTSUP);
+               (*dev->dev_ops->tx_queue_release)(txq[tx_queue_id]);
+               txq[tx_queue_id] = NULL;
+       }
+
        if (tx_conf == NULL)
                tx_conf = &dev_info.default_txconf;
 
@@ -1234,6 +1189,20 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
        return ret;
 }
 
+int
+rte_eth_tx_done_cleanup(uint8_t port_id, uint16_t queue_id, uint32_t free_cnt)
+{
+       struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+
+       /* Validate Input Data. Bail if not valid or not supported. */
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
+
+       /* Call driver to free pending mbufs. */
+       return (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
+                       free_cnt);
+}
+
 void
 rte_eth_promiscuous_enable(uint8_t port_id)
 {
@@ -1393,12 +1362,19 @@ get_xstats_count(uint8_t port_id)
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
        dev = &rte_eth_devices[port_id];
+       if (dev->dev_ops->xstats_get_names_by_id != NULL) {
+               count = (*dev->dev_ops->xstats_get_names_by_id)(dev, NULL,
+                               NULL, 0);
+               if (count < 0)
+                       return count;
+       }
        if (dev->dev_ops->xstats_get_names != NULL) {
                count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0);
                if (count < 0)
                        return count;
        } else
                count = 0;
+
        count += RTE_NB_STATS;
        count += RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS) *
                 RTE_NB_RXQ_STATS;
@@ -1407,10 +1383,171 @@ get_xstats_count(uint8_t port_id)
        return count;
 }
 
+int
+rte_eth_xstats_get_id_by_name(uint8_t port_id, const char *xstat_name,
+               uint64_t *id)
+{
+       int cnt_xstats, idx_xstat;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+       if (!id) {
+               RTE_PMD_DEBUG_TRACE("Error: id pointer is NULL\n");
+               return -ENOMEM;
+       }
+
+       if (!xstat_name) {
+               RTE_PMD_DEBUG_TRACE("Error: xstat_name pointer is NULL\n");
+               return -ENOMEM;
+       }
+
+       /* Get count */
+       cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
+       if (cnt_xstats  < 0) {
+               RTE_PMD_DEBUG_TRACE("Error: Cannot get count of xstats\n");
+               return -ENODEV;
+       }
+
+       /* Get id-name lookup table */
+       struct rte_eth_xstat_name xstats_names[cnt_xstats];
+
+       if (cnt_xstats != rte_eth_xstats_get_names_by_id(
+                       port_id, xstats_names, cnt_xstats, NULL)) {
+               RTE_PMD_DEBUG_TRACE("Error: Cannot get xstats lookup\n");
+               return -1;
+       }
+
+       for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
+               if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) {
+                       *id = idx_xstat;
+                       return 0;
+               };
+       }
+
+       return -EINVAL;
+}
+
+int
+rte_eth_xstats_get_names_by_id(uint8_t port_id,
+       struct rte_eth_xstat_name *xstats_names, unsigned int size,
+       uint64_t *ids)
+{
+       /* Get all xstats */
+       if (!ids) {
+               struct rte_eth_dev *dev;
+               int cnt_used_entries;
+               int cnt_expected_entries;
+               int cnt_driver_entries;
+               uint32_t idx, id_queue;
+               uint16_t num_q;
+
+               cnt_expected_entries = get_xstats_count(port_id);
+               if (xstats_names == NULL || cnt_expected_entries < 0 ||
+                               (int)size < cnt_expected_entries)
+                       return cnt_expected_entries;
+
+               /* port_id checked in get_xstats_count() */
+               dev = &rte_eth_devices[port_id];
+               cnt_used_entries = 0;
+
+               for (idx = 0; idx < RTE_NB_STATS; idx++) {
+                       snprintf(xstats_names[cnt_used_entries].name,
+                               sizeof(xstats_names[0].name),
+                               "%s", rte_stats_strings[idx].name);
+                       cnt_used_entries++;
+               }
+               num_q = RTE_MIN(dev->data->nb_rx_queues,
+                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
+               for (id_queue = 0; id_queue < num_q; id_queue++) {
+                       for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
+                               snprintf(xstats_names[cnt_used_entries].name,
+                                       sizeof(xstats_names[0].name),
+                                       "rx_q%u%s",
+                                       id_queue,
+                                       rte_rxq_stats_strings[idx].name);
+                               cnt_used_entries++;
+                       }
+
+               }
+               num_q = RTE_MIN(dev->data->nb_tx_queues,
+                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
+               for (id_queue = 0; id_queue < num_q; id_queue++) {
+                       for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
+                               snprintf(xstats_names[cnt_used_entries].name,
+                                       sizeof(xstats_names[0].name),
+                                       "tx_q%u%s",
+                                       id_queue,
+                                       rte_txq_stats_strings[idx].name);
+                               cnt_used_entries++;
+                       }
+               }
+
+               if (dev->dev_ops->xstats_get_names_by_id != NULL) {
+                       /* If there are any driver-specific xstats, append them
+                        * to end of list.
+                        */
+                       cnt_driver_entries =
+                               (*dev->dev_ops->xstats_get_names_by_id)(
+                               dev,
+                               xstats_names + cnt_used_entries,
+                               NULL,
+                               size - cnt_used_entries);
+                       if (cnt_driver_entries < 0)
+                               return cnt_driver_entries;
+                       cnt_used_entries += cnt_driver_entries;
+
+               } else if (dev->dev_ops->xstats_get_names != NULL) {
+                       /* If there are any driver-specific xstats, append them
+                        * to end of list.
+                        */
+                       cnt_driver_entries = (*dev->dev_ops->xstats_get_names)(
+                               dev,
+                               xstats_names + cnt_used_entries,
+                               size - cnt_used_entries);
+                       if (cnt_driver_entries < 0)
+                               return cnt_driver_entries;
+                       cnt_used_entries += cnt_driver_entries;
+               }
+
+               return cnt_used_entries;
+       }
+       /* Get only xstats given by IDS */
+       else {
+               uint16_t len, i;
+               struct rte_eth_xstat_name *xstats_names_copy;
+
+               len = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
+
+               xstats_names_copy =
+                               malloc(sizeof(struct rte_eth_xstat_name) * len);
+               if (!xstats_names_copy) {
+                       RTE_PMD_DEBUG_TRACE(
+                            "ERROR: can't allocate memory for values_copy\n");
+                       free(xstats_names_copy);
+                       return -1;
+               }
+
+               rte_eth_xstats_get_names_by_id(port_id, xstats_names_copy,
+                               len, NULL);
+
+               for (i = 0; i < size; i++) {
+                       if (ids[i] >= len) {
+                               RTE_PMD_DEBUG_TRACE(
+                                       "ERROR: id value isn't valid\n");
+                               return -1;
+                       }
+                       strcpy(xstats_names[i].name,
+                                       xstats_names_copy[ids[i]].name);
+               }
+               free(xstats_names_copy);
+               return size;
+       }
+}
+
 int
 rte_eth_xstats_get_names(uint8_t port_id,
        struct rte_eth_xstat_name *xstats_names,
-       unsigned size)
+       unsigned int size)
 {
        struct rte_eth_dev *dev;
        int cnt_used_entries;
@@ -1473,14 +1610,140 @@ rte_eth_xstats_get_names(uint8_t port_id,
 }
 
 /* retrieve ethdev extended statistics */
+int
+rte_eth_xstats_get_by_id(uint8_t port_id, const uint64_t *ids, uint64_t *values,
+       unsigned int n)
+{
+       /* If need all xstats */
+       if (!ids) {
+               struct rte_eth_stats eth_stats;
+               struct rte_eth_dev *dev;
+               unsigned int count = 0, i, q;
+               signed int xcount = 0;
+               uint64_t val, *stats_ptr;
+               uint16_t nb_rxqs, nb_txqs;
+
+               RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+               dev = &rte_eth_devices[port_id];
+
+               nb_rxqs = RTE_MIN(dev->data->nb_rx_queues,
+                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
+               nb_txqs = RTE_MIN(dev->data->nb_tx_queues,
+                               RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+               /* Return generic statistics */
+               count = RTE_NB_STATS + (nb_rxqs * RTE_NB_RXQ_STATS) +
+                       (nb_txqs * RTE_NB_TXQ_STATS);
+
+
+               /* implemented by the driver */
+               if (dev->dev_ops->xstats_get_by_id != NULL) {
+                       /* Retrieve the xstats from the driver at the end of the
+                        * xstats struct. Retrieve all xstats.
+                        */
+                       xcount = (*dev->dev_ops->xstats_get_by_id)(dev,
+                                       NULL,
+                                       values ? values + count : NULL,
+                                       (n > count) ? n - count : 0);
+
+                       if (xcount < 0)
+                               return xcount;
+               /* implemented by the driver */
+               } else if (dev->dev_ops->xstats_get != NULL) {
+                       /* Retrieve the xstats from the driver at the end of the
+                        * xstats struct. Retrieve all xstats.
+                        * Compatibility for PMD without xstats_get_by_ids
+                        */
+                       unsigned int size = (n > count) ? n - count : 1;
+                       struct rte_eth_xstat xstats[size];
+
+                       xcount = (*dev->dev_ops->xstats_get)(dev,
+                                       values ? xstats : NULL, size);
+
+                       if (xcount < 0)
+                               return xcount;
+
+                       if (values != NULL)
+                               for (i = 0 ; i < (unsigned int)xcount; i++)
+                                       values[i + count] = xstats[i].value;
+               }
+
+               if (n < count + xcount || values == NULL)
+                       return count + xcount;
+
+               /* now fill the xstats structure */
+               count = 0;
+               rte_eth_stats_get(port_id, &eth_stats);
+
+               /* global stats */
+               for (i = 0; i < RTE_NB_STATS; i++) {
+                       stats_ptr = RTE_PTR_ADD(&eth_stats,
+                                               rte_stats_strings[i].offset);
+                       val = *stats_ptr;
+                       values[count++] = val;
+               }
+
+               /* per-rxq stats */
+               for (q = 0; q < nb_rxqs; q++) {
+                       for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+                               stats_ptr = RTE_PTR_ADD(&eth_stats,
+                                           rte_rxq_stats_strings[i].offset +
+                                           q * sizeof(uint64_t));
+                               val = *stats_ptr;
+                               values[count++] = val;
+                       }
+               }
+
+               /* per-txq stats */
+               for (q = 0; q < nb_txqs; q++) {
+                       for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+                               stats_ptr = RTE_PTR_ADD(&eth_stats,
+                                           rte_txq_stats_strings[i].offset +
+                                           q * sizeof(uint64_t));
+                               val = *stats_ptr;
+                               values[count++] = val;
+                       }
+               }
+
+               return count + xcount;
+       }
+       /* Need only xstats given by IDS array */
+       else {
+               uint16_t i, size;
+               uint64_t *values_copy;
+
+               size = rte_eth_xstats_get_by_id(port_id, NULL, NULL, 0);
+
+               values_copy = malloc(sizeof(*values_copy) * size);
+               if (!values_copy) {
+                       RTE_PMD_DEBUG_TRACE(
+                           "ERROR: can't allocate memory for values_copy\n");
+                       return -1;
+               }
+
+               rte_eth_xstats_get_by_id(port_id, NULL, values_copy, size);
+
+               for (i = 0; i < n; i++) {
+                       if (ids[i] >= size) {
+                               RTE_PMD_DEBUG_TRACE(
+                                       "ERROR: id value isn't valid\n");
+                               return -1;
+                       }
+                       values[i] = values_copy[ids[i]];
+               }
+               free(values_copy);
+               return n;
+       }
+}
+
 int
 rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
-       unsigned n)
+       unsigned int n)
 {
        struct rte_eth_stats eth_stats;
        struct rte_eth_dev *dev;
-       unsigned count = 0, i, q;
-       signed xcount = 0;
+       unsigned int count = 0, i, q;
+       signed int xcount = 0;
        uint64_t val, *stats_ptr;
        uint16_t nb_rxqs, nb_txqs;
 
@@ -1606,6 +1869,18 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id,
                        STAT_QMAP_RX);
 }
 
+int
+rte_eth_dev_fw_version_get(uint8_t port_id, char *fw_version, size_t fw_size)
+{
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+       dev = &rte_eth_devices[port_id];
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, -ENOTSUP);
+       return (*dev->dev_ops->fw_version_get)(dev, fw_version, fw_size);
+}
+
 void
 rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 {
@@ -1625,7 +1900,6 @@ 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->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;
@@ -1883,13 +2157,7 @@ rte_eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
        if (!reta_conf)
                return -EINVAL;
 
-       if (reta_size != RTE_ALIGN(reta_size, RTE_RETA_GROUP_SIZE)) {
-               RTE_PMD_DEBUG_TRACE("Invalid reta size, should be %u aligned\n",
-                                                       RTE_RETA_GROUP_SIZE);
-               return -EINVAL;
-       }
-
-       num = reta_size / RTE_RETA_GROUP_SIZE;
+       num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
        for (i = 0; i < num; i++) {
                if (reta_conf[i].mask)
                        return 0;
@@ -2101,6 +2369,7 @@ rte_eth_dev_mac_addr_add(uint8_t port_id, struct ether_addr *addr,
        struct rte_eth_dev *dev;
        int index;
        uint64_t pool_mask;
+       int ret;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
@@ -2133,15 +2402,17 @@ rte_eth_dev_mac_addr_add(uint8_t port_id, struct ether_addr *addr,
        }
 
        /* Update NIC */
-       (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
+       ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
 
-       /* Update address in NIC data structure */
-       ether_addr_copy(addr, &dev->data->mac_addrs[index]);
+       if (ret == 0) {
+               /* Update address in NIC data structure */
+               ether_addr_copy(addr, &dev->data->mac_addrs[index]);
 
-       /* Update pool bitmap in NIC data structure */
-       dev->data->mac_pool_sel[index] |= (1ULL << pool);
+               /* Update pool bitmap in NIC data structure */
+               dev->data->mac_pool_sel[index] |= (1ULL << pool);
+       }
 
-       return 0;
+       return ret;
 }
 
 int
@@ -2194,32 +2465,6 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
        return 0;
 }
 
-int
-rte_eth_dev_set_vf_rxmode(uint8_t port_id,  uint16_t vf,
-                               uint16_t rx_mode, uint8_t on)
-{
-       uint16_t num_vfs;
-       struct rte_eth_dev *dev;
-       struct rte_eth_dev_info dev_info;
-
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-       dev = &rte_eth_devices[port_id];
-       rte_eth_dev_info_get(port_id, &dev_info);
-
-       num_vfs = dev_info.max_vfs;
-       if (vf > num_vfs) {
-               RTE_PMD_DEBUG_TRACE("set VF RX mode:invalid VF id %d\n", vf);
-               return -EINVAL;
-       }
-
-       if (rx_mode == 0) {
-               RTE_PMD_DEBUG_TRACE("set VF RX mode:mode mask ca not be zero\n");
-               return -EINVAL;
-       }
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rx_mode, -ENOTSUP);
-       return (*dev->dev_ops->set_vf_rx_mode)(dev, vf, rx_mode, on);
-}
 
 /*
  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
@@ -2309,76 +2554,6 @@ rte_eth_dev_uc_all_hash_table_set(uint8_t port_id, uint8_t on)
        return (*dev->dev_ops->uc_all_hash_table_set)(dev, on);
 }
 
-int
-rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
-{
-       uint16_t num_vfs;
-       struct rte_eth_dev *dev;
-       struct rte_eth_dev_info dev_info;
-
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-       dev = &rte_eth_devices[port_id];
-       rte_eth_dev_info_get(port_id, &dev_info);
-
-       num_vfs = dev_info.max_vfs;
-       if (vf > num_vfs) {
-               RTE_PMD_DEBUG_TRACE("port %d: invalid vf id\n", port_id);
-               return -EINVAL;
-       }
-
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rx, -ENOTSUP);
-       return (*dev->dev_ops->set_vf_rx)(dev, vf, on);
-}
-
-int
-rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
-{
-       uint16_t num_vfs;
-       struct rte_eth_dev *dev;
-       struct rte_eth_dev_info dev_info;
-
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-       dev = &rte_eth_devices[port_id];
-       rte_eth_dev_info_get(port_id, &dev_info);
-
-       num_vfs = dev_info.max_vfs;
-       if (vf > num_vfs) {
-               RTE_PMD_DEBUG_TRACE("set pool tx:invalid pool id=%d\n", vf);
-               return -EINVAL;
-       }
-
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_tx, -ENOTSUP);
-       return (*dev->dev_ops->set_vf_tx)(dev, vf, on);
-}
-
-int
-rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
-                              uint64_t vf_mask, uint8_t vlan_on)
-{
-       struct rte_eth_dev *dev;
-
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-       dev = &rte_eth_devices[port_id];
-
-       if (vlan_id > ETHER_MAX_VLAN_ID) {
-               RTE_PMD_DEBUG_TRACE("VF VLAN filter:invalid VLAN id=%d\n",
-                       vlan_id);
-               return -EINVAL;
-       }
-
-       if (vf_mask == 0) {
-               RTE_PMD_DEBUG_TRACE("VF VLAN filter:pool_mask can not be 0\n");
-               return -EINVAL;
-       }
-
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_filter, -ENOTSUP);
-       return (*dev->dev_ops->set_vf_vlan_filter)(dev, vlan_id,
-                                                  vf_mask, vlan_on);
-}
-
 int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
                                        uint16_t tx_rate)
 {
@@ -2409,45 +2584,12 @@ int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
        return (*dev->dev_ops->set_queue_rate_limit)(dev, queue_idx, tx_rate);
 }
 
-int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate,
-                               uint64_t q_msk)
-{
-       struct rte_eth_dev *dev;
-       struct rte_eth_dev_info dev_info;
-       struct rte_eth_link link;
-
-       if (q_msk == 0)
-               return 0;
-
-       RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
-       dev = &rte_eth_devices[port_id];
-       rte_eth_dev_info_get(port_id, &dev_info);
-       link = dev->data->dev_link;
-
-       if (vf > dev_info.max_vfs) {
-               RTE_PMD_DEBUG_TRACE("set VF rate limit:port %d: "
-                               "invalid vf id=%d\n", port_id, vf);
-               return -EINVAL;
-       }
-
-       if (tx_rate > link.link_speed) {
-               RTE_PMD_DEBUG_TRACE("set VF rate limit:invalid tx_rate=%d, "
-                               "bigger than link speed= %d\n",
-                               tx_rate, link.link_speed);
-               return -EINVAL;
-       }
-
-       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rate_limit, -ENOTSUP);
-       return (*dev->dev_ops->set_vf_rate_limit)(dev, vf, tx_rate, q_msk);
-}
-
 int
 rte_eth_mirror_rule_set(uint8_t port_id,
                        struct rte_eth_mirror_conf *mirror_conf,
                        uint8_t rule_id, uint8_t on)
 {
-       struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+       struct rte_eth_dev *dev;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        if (mirror_conf->rule_type == 0) {
@@ -2483,7 +2625,7 @@ rte_eth_mirror_rule_set(uint8_t port_id,
 int
 rte_eth_mirror_rule_reset(uint8_t port_id, uint8_t rule_id)
 {
-       struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+       struct rte_eth_dev *dev;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
@@ -2590,7 +2732,7 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
                dev_cb = *cb_lst;
                cb_lst->active = 1;
                if (cb_arg != NULL)
-                       dev_cb.cb_arg = (void *) cb_arg;
+                       dev_cb.cb_arg = cb_arg;
 
                rte_spinlock_unlock(&rte_eth_dev_cb_lock);
                dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
@@ -2613,7 +2755,13 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 
        dev = &rte_eth_devices[port_id];
-       intr_handle = &dev->pci_dev->intr_handle;
+
+       if (!dev->intr_handle) {
+               RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+               return -ENOTSUP;
+       }
+
+       intr_handle = dev->intr_handle;
        if (!intr_handle->intr_vec) {
                RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
                return -EPERM;
@@ -2641,7 +2789,7 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
        const struct rte_memzone *mz;
 
        snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-                dev->driver->pci_drv.driver.name, ring_name,
+                dev->data->drv_name, ring_name,
                 dev->data->port_id, queue_id);
 
        mz = rte_memzone_lookup(z_name);
@@ -2673,7 +2821,12 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
                return -EINVAL;
        }
 
-       intr_handle = &dev->pci_dev->intr_handle;
+       if (!dev->intr_handle) {
+               RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+               return -ENOTSUP;
+       }
+
+       intr_handle = dev->intr_handle;
        if (!intr_handle->intr_vec) {
                RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
                return -EPERM;
@@ -3266,26 +3419,6 @@ rte_eth_dev_get_dcb_info(uint8_t port_id,
        return (*dev->dev_ops->get_dcb_info)(dev, dcb_info);
 }
 
-void
-rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_dev)
-{
-       if ((eth_dev == NULL) || (pci_dev == NULL)) {
-               RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p pci_dev=%p\n",
-                               eth_dev, pci_dev);
-               return;
-       }
-
-       eth_dev->data->dev_flags = 0;
-       if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
-               eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
-       if (pci_dev->driver->drv_flags & RTE_PCI_DRV_DETACHABLE)
-               eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
-
-       eth_dev->data->kdrv = pci_dev->kdrv;
-       eth_dev->data->numa_node = pci_dev->device.numa_node;
-       eth_dev->data->drv_name = pci_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)