ethdev: move info filling of PCI into drivers
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index d61af37..ec2edad 100644 (file)
@@ -72,6 +72,8 @@
 #include "base/ixgbe_phy.h"
 #include "ixgbe_regs.h"
 
+#include "rte_pmd_ixgbe.h"
+
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
  * least 8 bytes less than receive packet buffer size. This value is in units
@@ -231,7 +233,8 @@ static void ixgbe_dev_link_status_print(struct rte_eth_dev *dev);
 static int ixgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev);
 static int ixgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev);
 static int ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev);
-static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev);
+static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
+                                     struct rte_intr_handle *handle);
 static void ixgbe_dev_interrupt_handler(struct rte_intr_handle *handle,
                void *param);
 static void ixgbe_dev_interrupt_delayed_handler(void *param);
@@ -429,23 +432,80 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
  * The set of PCI devices this driver supports
  */
 static const struct rte_pci_id pci_id_ixgbe_map[] = {
-
-#define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
-#include "rte_pci_dev_ids.h"
-
-{ .vendor_id = 0, /* sentinel */ },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_BX) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_DUAL_PORT) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AF_SINGLE_PORT) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598AT2) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_SFP_LOM) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_CX4) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_CX4_DUAL_PORT) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_DA_DUAL_PORT) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82598EB_XF_LR) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KX4_MEZZ) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_KR) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_CX4) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_SUBDEV_ID_82599_SFP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_SUBDEV_ID_82599_RNDC) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_SUBDEV_ID_82599_560FLR) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_SUBDEV_ID_82599_ECNA_DP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BACKPLANE_FCOE) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_EM) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF2) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF_QP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_QSFP_SF_QP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_XAUI_LOM) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_T3_LOM) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_LS) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_SFP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_10G_T) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_1G_T) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550T) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550T1) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_KR) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_KR_L) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SFP_N) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SGMII) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SGMII_L) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_10G_T) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_QSFP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_QSFP_N) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_SFP) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_1G_T_L) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KX4) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KR) },
+#ifdef RTE_NIC_BYPASS
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BYPASS) },
+#endif
+       { .vendor_id = 0, /* sentinel */ },
 };
 
-
 /*
  * The set of PCI devices this driver supports (for 82599 VF)
  */
 static const struct rte_pci_id pci_id_ixgbevf_map[] = {
-
-#define RTE_PCI_DEV_ID_DECL_IXGBEVF(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
-#include "rte_pci_dev_ids.h"
-{ .vendor_id = 0, /* sentinel */ },
-
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF_HV) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF_HV) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF_HV) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF_HV) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF) },
+       { RTE_PCI_DEVICE(IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF_HV) },
+       { .vendor_id = 0, /* sentinel */ },
 };
 
 static const struct rte_eth_desc_lim rx_desc_lim = {
@@ -538,7 +598,6 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .timesync_disable     = ixgbe_timesync_disable,
        .timesync_read_rx_timestamp = ixgbe_timesync_read_rx_timestamp,
        .timesync_read_tx_timestamp = ixgbe_timesync_read_tx_timestamp,
-       .get_reg_length       = ixgbe_get_reg_length,
        .get_reg              = ixgbe_get_regs,
        .get_eeprom_length    = ixgbe_get_eeprom_length,
        .get_eeprom           = ixgbe_get_eeprom,
@@ -589,7 +648,6 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
        .rxq_info_get         = ixgbe_rxq_info_get,
        .txq_info_get         = ixgbe_txq_info_get,
        .mac_addr_set         = ixgbevf_set_default_mac_addr,
-       .get_reg_length       = ixgbevf_get_reg_length,
        .get_reg              = ixgbevf_get_regs,
        .reta_update          = ixgbe_dev_rss_reta_update,
        .reta_query           = ixgbe_dev_rss_reta_query,
@@ -1026,7 +1084,8 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)
 static int
 eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 {
-       struct rte_pci_device *pci_dev;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
        struct ixgbe_vfta *shadow_vfta =
@@ -1070,7 +1129,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 
                return 0;
        }
-       pci_dev = eth_dev->pci_dev;
 
        rte_eth_copy_pci_info(eth_dev, pci_dev);
 
@@ -1215,12 +1273,11 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
                     eth_dev->data->port_id, pci_dev->id.vendor_id,
                     pci_dev->id.device_id);
 
-       rte_intr_callback_register(&pci_dev->intr_handle,
-                                  ixgbe_dev_interrupt_handler,
-                                  (void *)eth_dev);
+       rte_intr_callback_register(intr_handle,
+                                  ixgbe_dev_interrupt_handler, eth_dev);
 
        /* enable uio/vfio intr/eventfd mapping */
-       rte_intr_enable(&pci_dev->intr_handle);
+       rte_intr_enable(intr_handle);
 
        /* enable support intr */
        ixgbe_enable_intr(eth_dev);
@@ -1236,7 +1293,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
 static int
 eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
 {
-       struct rte_pci_device *pci_dev;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_hw *hw;
 
        PMD_INIT_FUNC_TRACE();
@@ -1245,7 +1303,6 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
                return -EPERM;
 
        hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-       pci_dev = eth_dev->pci_dev;
 
        if (hw->adapter_stopped == 0)
                ixgbe_dev_close(eth_dev);
@@ -1258,9 +1315,9 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
        ixgbe_swfw_lock_reset(hw);
 
        /* disable uio intr before callback unregister */
-       rte_intr_disable(&(pci_dev->intr_handle));
-       rte_intr_callback_unregister(&(pci_dev->intr_handle),
-               ixgbe_dev_interrupt_handler, (void *)eth_dev);
+       rte_intr_disable(intr_handle);
+       rte_intr_callback_unregister(intr_handle,
+                                    ixgbe_dev_interrupt_handler, eth_dev);
 
        /* uninitialize PF if max_vfs not zero */
        ixgbe_pf_host_uninit(eth_dev);
@@ -1324,7 +1381,8 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
 {
        int diag;
        uint32_t tc, tcs;
-       struct rte_pci_device *pci_dev;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
        struct ixgbe_vfta *shadow_vfta =
@@ -1362,8 +1420,6 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
                return 0;
        }
 
-       pci_dev = eth_dev->pci_dev;
-
        rte_eth_copy_pci_info(eth_dev, pci_dev);
 
        hw->device_id = pci_dev->id.device_id;
@@ -1456,10 +1512,9 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
                return -EIO;
        }
 
-       rte_intr_callback_register(&pci_dev->intr_handle,
-                                  ixgbevf_dev_interrupt_handler,
-                                  (void *)eth_dev);
-       rte_intr_enable(&pci_dev->intr_handle);
+       rte_intr_callback_register(intr_handle,
+                                  ixgbevf_dev_interrupt_handler, eth_dev);
+       rte_intr_enable(intr_handle);
        ixgbevf_intr_enable(hw);
 
        PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s",
@@ -1474,8 +1529,9 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
 static int
 eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(eth_dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_hw *hw;
-       struct rte_pci_device *pci_dev = eth_dev->pci_dev;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -1497,20 +1553,20 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
        rte_free(eth_dev->data->mac_addrs);
        eth_dev->data->mac_addrs = NULL;
 
-       rte_intr_disable(&pci_dev->intr_handle);
-       rte_intr_callback_unregister(&pci_dev->intr_handle,
-                                    ixgbevf_dev_interrupt_handler,
-                                    (void *)eth_dev);
+       rte_intr_disable(intr_handle);
+       rte_intr_callback_unregister(intr_handle,
+                                    ixgbevf_dev_interrupt_handler, eth_dev);
 
        return 0;
 }
 
 static struct eth_driver rte_ixgbe_pmd = {
        .pci_drv = {
-               .name = "rte_ixgbe_pmd",
                .id_table = pci_id_ixgbe_map,
                .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
                        RTE_PCI_DRV_DETACHABLE,
+               .probe = rte_eth_dev_pci_probe,
+               .remove = rte_eth_dev_pci_remove,
        },
        .eth_dev_init = eth_ixgbe_dev_init,
        .eth_dev_uninit = eth_ixgbe_dev_uninit,
@@ -1522,43 +1578,16 @@ static struct eth_driver rte_ixgbe_pmd = {
  */
 static struct eth_driver rte_ixgbevf_pmd = {
        .pci_drv = {
-               .name = "rte_ixgbevf_pmd",
                .id_table = pci_id_ixgbevf_map,
                .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
+               .probe = rte_eth_dev_pci_probe,
+               .remove = rte_eth_dev_pci_remove,
        },
        .eth_dev_init = eth_ixgbevf_dev_init,
        .eth_dev_uninit = eth_ixgbevf_dev_uninit,
        .dev_private_size = sizeof(struct ixgbe_adapter),
 };
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of PCI IXGBE devices.
- */
-static int
-rte_ixgbe_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
-{
-       PMD_INIT_FUNC_TRACE();
-
-       rte_eth_driver_register(&rte_ixgbe_pmd);
-       return 0;
-}
-
-/*
- * VF Driver initialization routine.
- * Invoked one at EAL init time.
- * Register itself as the [Virtual Poll Mode] Driver of PCI niantic devices.
- */
-static int
-rte_ixgbevf_pmd_init(const char *name __rte_unused, const char *param __rte_unused)
-{
-       PMD_INIT_FUNC_TRACE();
-
-       rte_eth_driver_register(&rte_ixgbevf_pmd);
-       return 0;
-}
-
 static int
 ixgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -1770,6 +1799,7 @@ ixgbe_vlan_hw_strip_disable_all(struct rte_eth_dev *dev)
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t ctrl;
        uint16_t i;
+       struct ixgbe_rx_queue *rxq;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -1780,9 +1810,10 @@ ixgbe_vlan_hw_strip_disable_all(struct rte_eth_dev *dev)
        } else {
                /* Other 10G NIC, the VLAN strip can be setup per queue in RXDCTL */
                for (i = 0; i < dev->data->nb_rx_queues; i++) {
-                       ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+                       rxq = dev->data->rx_queues[i];
+                       ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxq->reg_idx));
                        ctrl &= ~IXGBE_RXDCTL_VME;
-                       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), ctrl);
+                       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxq->reg_idx), ctrl);
 
                        /* record those setting for HW strip per queue */
                        ixgbe_vlan_hw_strip_bitmap_set(dev, i, 0);
@@ -1797,6 +1828,7 @@ ixgbe_vlan_hw_strip_enable_all(struct rte_eth_dev *dev)
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t ctrl;
        uint16_t i;
+       struct ixgbe_rx_queue *rxq;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -1807,9 +1839,10 @@ ixgbe_vlan_hw_strip_enable_all(struct rte_eth_dev *dev)
        } else {
                /* Other 10G NIC, the VLAN strip can be setup per queue in RXDCTL */
                for (i = 0; i < dev->data->nb_rx_queues; i++) {
-                       ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+                       rxq = dev->data->rx_queues[i];
+                       ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxq->reg_idx));
                        ctrl |= IXGBE_RXDCTL_VME;
-                       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), ctrl);
+                       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxq->reg_idx), ctrl);
 
                        /* record those setting for HW strip per queue */
                        ixgbe_vlan_hw_strip_bitmap_set(dev, i, 1);
@@ -1912,6 +1945,8 @@ ixgbe_vmdq_vlan_hw_filter_enable(struct rte_eth_dev *dev)
 static int
 ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+
        switch (nb_rx_q) {
        case 1:
        case 2:
@@ -1925,7 +1960,7 @@ ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
        }
 
        RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = nb_rx_q;
-       RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = dev->pci_dev->max_vfs * nb_rx_q;
+       RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = pci_dev->max_vfs * nb_rx_q;
 
        return 0;
 }
@@ -1942,6 +1977,8 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                /* check multi-queue mode */
                switch (dev_conf->rxmode.mq_mode) {
                case ETH_MQ_RX_VMDQ_DCB:
+                       PMD_INIT_LOG(INFO, "ETH_MQ_RX_VMDQ_DCB mode supported in SRIOV");
+                       break;
                case ETH_MQ_RX_VMDQ_DCB_RSS:
                        /* DCB/RSS VMDQ in SRIOV mode, not implement yet */
                        PMD_INIT_LOG(ERR, "SRIOV active,"
@@ -1977,11 +2014,9 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
 
                switch (dev_conf->txmode.mq_mode) {
                case ETH_MQ_TX_VMDQ_DCB:
-                       /* DCB VMDQ in SRIOV mode, not implement yet */
-                       PMD_INIT_LOG(ERR, "SRIOV is active,"
-                                       " unsupported VMDQ mq_mode tx %d.",
-                                       dev_conf->txmode.mq_mode);
-                       return -EINVAL;
+                       PMD_INIT_LOG(INFO, "ETH_MQ_TX_VMDQ_DCB mode supported in SRIOV");
+                       dev->data->dev_conf.txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
+                       break;
                default: /* ETH_MQ_TX_VMDQ_ONLY or ETH_MQ_TX_NONE */
                        dev->data->dev_conf.txmode.mq_mode = ETH_MQ_TX_VMDQ_ONLY;
                        break;
@@ -2156,7 +2191,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_vf_info *vfinfo =
                *IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        uint32_t intr_vector = 0;
        int err, link_up = 0, negotiate = 0;
        uint32_t speed = 0;
@@ -2236,6 +2272,36 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
                goto error;
        }
 
+    mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK |
+               ETH_VLAN_EXTEND_MASK;
+       ixgbe_vlan_offload_set(dev, mask);
+
+       if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_VMDQ_ONLY) {
+               /* Enable vlan filtering for VMDq */
+               ixgbe_vmdq_vlan_hw_filter_enable(dev);
+       }
+
+       /* Configure DCB hw */
+       ixgbe_configure_dcb(dev);
+
+       if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE) {
+               err = ixgbe_fdir_configure(dev);
+               if (err)
+                       goto error;
+       }
+
+       /* Restore vf rate limit */
+       if (vfinfo != NULL) {
+               for (vf = 0; vf < pci_dev->max_vfs; vf++)
+                       for (idx = 0; idx < IXGBE_MAX_QUEUE_NUM_PER_VF; idx++)
+                               if (vfinfo[vf].tx_rate[idx] != 0)
+                                       ixgbe_set_vf_rate_limit(dev, vf,
+                                               vfinfo[vf].tx_rate[idx],
+                                               1 << idx);
+       }
+
+       ixgbe_restore_statistics_mapping(dev);
+
        err = ixgbe_dev_rxtx_start(dev);
        if (err < 0) {
                PMD_INIT_LOG(ERR, "Unable to start rxtx queues");
@@ -2303,8 +2369,7 @@ skip_link_setup:
                        ixgbe_dev_lsc_interrupt_setup(dev);
        } else {
                rte_intr_callback_unregister(intr_handle,
-                                            ixgbe_dev_interrupt_handler,
-                                            (void *)dev);
+                                            ixgbe_dev_interrupt_handler, dev);
                if (dev->data->dev_conf.intr_conf.lsc != 0)
                        PMD_INIT_LOG(INFO, "lsc won't enable because of"
                                     " no intr multiplex\n");
@@ -2321,36 +2386,6 @@ skip_link_setup:
        /* resume enabled intr since hw reset */
        ixgbe_enable_intr(dev);
 
-       mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK |
-               ETH_VLAN_EXTEND_MASK;
-       ixgbe_vlan_offload_set(dev, mask);
-
-       if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_VMDQ_ONLY) {
-               /* Enable vlan filtering for VMDq */
-               ixgbe_vmdq_vlan_hw_filter_enable(dev);
-       }
-
-       /* Configure DCB hw */
-       ixgbe_configure_dcb(dev);
-
-       if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE) {
-               err = ixgbe_fdir_configure(dev);
-               if (err)
-                       goto error;
-       }
-
-       /* Restore vf rate limit */
-       if (vfinfo != NULL) {
-               for (vf = 0; vf < dev->pci_dev->max_vfs; vf++)
-                       for (idx = 0; idx < IXGBE_MAX_QUEUE_NUM_PER_VF; idx++)
-                               if (vfinfo[vf].tx_rate[idx] != 0)
-                                       ixgbe_set_vf_rate_limit(dev, vf,
-                                               vfinfo[vf].tx_rate[idx],
-                                               1 << idx);
-       }
-
-       ixgbe_restore_statistics_mapping(dev);
-
        return 0;
 
 error:
@@ -2373,7 +2408,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        struct ixgbe_filter_info *filter_info =
                IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
        struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        int vf;
 
        PMD_INIT_FUNC_TRACE();
@@ -2388,8 +2424,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        /* stop adapter */
        ixgbe_stop_adapter(hw);
 
-       for (vf = 0; vfinfo != NULL &&
-                    vf < dev->pci_dev->max_vfs; vf++)
+       for (vf = 0; vfinfo != NULL && vf < pci_dev->max_vfs; vf++)
                vfinfo[vf].clear_to_send = false;
 
        if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
@@ -2784,7 +2819,6 @@ static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
 
                /* Extended stats from ixgbe_hw_stats */
                for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
-                       xstats_names[count].id = count;
                        snprintf(xstats_names[count].name,
                                sizeof(xstats_names[count].name),
                                "%s",
@@ -2795,7 +2829,6 @@ static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
                /* RX Priority Stats */
                for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
                        for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
-                               xstats_names[count].id = count;
                                snprintf(xstats_names[count].name,
                                        sizeof(xstats_names[count].name),
                                        "rx_priority%u_%s", i,
@@ -2807,7 +2840,6 @@ static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
                /* TX Priority Stats */
                for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) {
                        for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) {
-                               xstats_names[count].id = count;
                                snprintf(xstats_names[count].name,
                                        sizeof(xstats_names[count].name),
                                        "tx_priority%u_%s", i,
@@ -2868,7 +2900,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        /* Extended stats from ixgbe_hw_stats */
        count = 0;
        for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
-               xstats[count].id = count;
                xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
                                rte_ixgbe_stats_strings[i].offset);
                count++;
@@ -2877,7 +2908,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        /* RX Priority Stats */
        for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
                for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
-                       xstats[count].id = count;
                        xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
                                        rte_ixgbe_rxq_strings[stat].offset +
                                        (sizeof(uint64_t) * i));
@@ -2888,7 +2918,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        /* TX Priority Stats */
        for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) {
                for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) {
-                       xstats[count].id = count;
                        xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
                                        rte_ixgbe_txq_strings[stat].offset +
                                        (sizeof(uint64_t) * i));
@@ -2959,7 +2988,6 @@ ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 
        /* Extended stats */
        for (i = 0; i < IXGBEVF_NB_XSTATS; i++) {
-               xstats[i].id = i;
                xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
                        rte_ixgbevf_stats_strings[i].offset);
        }
@@ -3003,9 +3031,11 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev)
 static void
 ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
 
+       dev_info->pci_dev = pci_dev;
        dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
        dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
        if (RTE_ETH_DEV_SRIOV(dev).active == 0) {
@@ -3021,7 +3051,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS register */
        dev_info->max_mac_addrs = hw->mac.num_rar_entries;
        dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
-       dev_info->max_vfs = dev->pci_dev->max_vfs;
+       dev_info->max_vfs = pci_dev->max_vfs;
        if (hw->mac.type == ixgbe_mac_82598EB)
                dev_info->max_vmdq_pools = ETH_16_POOLS;
        else
@@ -3135,15 +3165,17 @@ static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                     struct rte_eth_dev_info *dev_info)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+       dev_info->pci_dev = pci_dev;
        dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
        dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
        dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL reg */
        dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS reg */
        dev_info->max_mac_addrs = hw->mac.num_rar_entries;
        dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
-       dev_info->max_vfs = dev->pci_dev->max_vfs;
+       dev_info->max_vfs = pci_dev->max_vfs;
        if (hw->mac.type == ixgbe_mac_82598EB)
                dev_info->max_vmdq_pools = ETH_16_POOLS;
        else
@@ -3405,6 +3437,7 @@ ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
 static void
 ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
        struct rte_eth_link link;
 
        memset(&link, 0, sizeof(link));
@@ -3419,11 +3452,11 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
                PMD_INIT_LOG(INFO, " Port %d: Link Down",
                                (int)(dev->data->port_id));
        }
-       PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
-                               dev->pci_dev->addr.domain,
-                               dev->pci_dev->addr.bus,
-                               dev->pci_dev->addr.devid,
-                               dev->pci_dev->addr.function);
+       PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
+                               pci_dev->addr.domain,
+                               pci_dev->addr.bus,
+                               pci_dev->addr.devid,
+                               pci_dev->addr.function);
 }
 
 /*
@@ -3437,7 +3470,8 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
  *  - On failure, a negative value.
  */
 static int
-ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
+ixgbe_dev_interrupt_action(struct rte_eth_dev *dev,
+                          struct rte_intr_handle *intr_handle)
 {
        struct ixgbe_interrupt *intr =
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
@@ -3487,7 +3521,7 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
        } else {
                PMD_DRV_LOG(DEBUG, "enable intr immediately");
                ixgbe_enable_intr(dev);
-               rte_intr_enable(&(dev->pci_dev->intr_handle));
+               rte_intr_enable(intr_handle);
        }
 
 
@@ -3512,6 +3546,8 @@ static void
 ixgbe_dev_interrupt_delayed_handler(void *param)
 {
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_interrupt *intr =
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        struct ixgbe_hw *hw =
@@ -3531,12 +3567,12 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
                ixgbe_dev_link_update(dev, 0);
                intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
                ixgbe_dev_link_status_print(dev);
-               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
        }
 
        PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
        ixgbe_enable_intr(dev);
-       rte_intr_enable(&(dev->pci_dev->intr_handle));
+       rte_intr_enable(intr_handle);
 }
 
 /**
@@ -3552,13 +3588,13 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
  *  void
  */
 static void
-ixgbe_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
+ixgbe_dev_interrupt_handler(struct rte_intr_handle *handle,
                            void *param)
 {
        struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
 
        ixgbe_dev_interrupt_get_status(dev);
-       ixgbe_dev_interrupt_action(dev);
+       ixgbe_dev_interrupt_action(dev, handle);
 }
 
 static int
@@ -4020,6 +4056,38 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
        ixgbe_add_rar(dev, addr, 0, 0);
 }
 
+int
+rte_pmd_ixgbe_set_vf_mac_addr(uint8_t port, uint16_t vf,
+               struct ether_addr *mac_addr)
+{
+       struct ixgbe_hw *hw;
+       struct ixgbe_vf_info *vfinfo;
+       int rar_entry;
+       uint8_t *new_mac = (uint8_t *)(mac_addr);
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+
+       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;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       vfinfo = *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+       rar_entry = hw->mac.num_rar_entries - (vf + 1);
+
+       if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) {
+               rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac,
+                               ETHER_ADDR_LEN);
+               return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf,
+                               IXGBE_RAH_AV);
+       }
+       return -EINVAL;
+}
+
 static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
@@ -4136,7 +4204,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t intr_vector = 0;
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
        int err, mask = 0;
 
@@ -4199,7 +4268,8 @@ static void
 ixgbevf_dev_stop(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -4613,6 +4683,216 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
        return ret;
 }
 
+int
+rte_pmd_ixgbe_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+       struct ixgbe_hw *hw;
+       struct ixgbe_mac_info *mac;
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+
+       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;
+
+       if (on > 1)
+               return -EINVAL;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       mac = &hw->mac;
+
+       mac->ops.set_vlan_anti_spoofing(hw, on, vf);
+
+       return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+       struct ixgbe_hw *hw;
+       struct ixgbe_mac_info *mac;
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+
+       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;
+
+       if (on > 1)
+               return -EINVAL;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       mac = &hw->mac;
+       mac->ops.set_mac_anti_spoofing(hw, on, vf);
+
+       return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_insert(uint8_t port, uint16_t vf, uint16_t vlan_id)
+{
+       struct ixgbe_hw *hw;
+       uint32_t ctrl;
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+
+       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;
+
+       if (vlan_id > 4095)
+               return -EINVAL;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       ctrl = IXGBE_READ_REG(hw, IXGBE_VMVIR(vf));
+       if (vlan_id) {
+               ctrl = vlan_id;
+               ctrl |= IXGBE_VMVIR_VLANA_DEFAULT;
+       } else {
+               ctrl = 0;
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), ctrl);
+
+       return 0;
+}
+
+int
+rte_pmd_ixgbe_set_tx_loopback(uint8_t port, uint8_t on)
+{
+       struct ixgbe_hw *hw;
+       uint32_t ctrl;
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+       dev = &rte_eth_devices[port];
+
+       if (on > 1)
+               return -EINVAL;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       ctrl = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+       /* enable or disable VMDQ loopback */
+       if (on)
+               ctrl |= IXGBE_PFDTXGSWC_VT_LBEN;
+       else
+               ctrl &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+
+       IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, ctrl);
+
+       return 0;
+}
+
+int
+rte_pmd_ixgbe_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+       struct ixgbe_hw *hw;
+       uint32_t reg_value;
+       int i;
+       int num_queues = (int)(IXGBE_QDE_IDX_MASK >> IXGBE_QDE_IDX_SHIFT);
+       struct rte_eth_dev *dev;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+       dev = &rte_eth_devices[port];
+
+       if (on > 1)
+               return -EINVAL;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       for (i = 0; i <= num_queues; i++) {
+               reg_value = IXGBE_QDE_WRITE |
+                               (i << IXGBE_QDE_IDX_SHIFT) |
+                               (on & IXGBE_QDE_ENABLE);
+               IXGBE_WRITE_REG(hw, IXGBE_QDE, reg_value);
+       }
+
+       return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_split_drop_en(uint8_t port, uint16_t vf, uint8_t on)
+{
+       struct ixgbe_hw *hw;
+       uint32_t reg_value;
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+
+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+       dev = &rte_eth_devices[port];
+       rte_eth_dev_info_get(port, &dev_info);
+
+       /* only support VF's 0 to 63 */
+       if ((vf >= dev_info.max_vfs) || (vf > 63))
+               return -EINVAL;
+
+       if (on > 1)
+               return -EINVAL;
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       reg_value = IXGBE_READ_REG(hw, IXGBE_SRRCTL(vf));
+       if (on)
+               reg_value |= IXGBE_SRRCTL_DROP_EN;
+       else
+               reg_value &= ~IXGBE_SRRCTL_DROP_EN;
+
+       IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(vf), reg_value);
+
+       return 0;
+}
+
+int
+rte_pmd_ixgbe_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
+{
+       struct rte_eth_dev *dev;
+       struct rte_eth_dev_info dev_info;
+       uint16_t queues_per_pool;
+       uint32_t q;
+
+       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;
+
+       if (on > 1)
+               return -EINVAL;
+
+       RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->vlan_strip_queue_set, -ENOTSUP);
+
+       /* The PF has 128 queue pairs and in SRIOV configuration
+        * those queues will be assigned to VF's, so RXDCTL
+        * registers will be dealing with queues which will be
+        * assigned to VF's.
+        * Let's say we have SRIOV configured with 31 VF's then the
+        * first 124 queues 0-123 will be allocated to VF's and only
+        * the last 4 queues 123-127 will be assigned to the PF.
+        */
+
+       queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools;
+
+       for (q = 0; q < queues_per_pool; q++)
+               (*dev->dev_ops->vlan_strip_queue_set)(dev,
+                               q + vf * queues_per_pool, on);
+       return 0;
+}
+
 #define IXGBE_MRCTL_VPME  0x01 /* Virtual Pool Mirroring. */
 #define IXGBE_MRCTL_UPME  0x02 /* Uplink Port Mirroring. */
 #define IXGBE_MRCTL_DPME  0x04 /* Downlink Port Mirroring. */
@@ -4791,6 +5071,8 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
 static int
 ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        uint32_t mask;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -4800,7 +5082,7 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
        RTE_SET_USED(queue_id);
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
 
-       rte_intr_enable(&dev->pci_dev->intr_handle);
+       rte_intr_enable(intr_handle);
 
        return 0;
 }
@@ -4823,6 +5105,8 @@ ixgbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 static int
 ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        uint32_t mask;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -4842,7 +5126,7 @@ ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
                mask &= (1 << (queue_id - 32));
                IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
        }
-       rte_intr_enable(&dev->pci_dev->intr_handle);
+       rte_intr_enable(intr_handle);
 
        return 0;
 }
@@ -4946,7 +5230,8 @@ ixgbe_set_ivar_map(struct ixgbe_hw *hw, int8_t direction,
 static void
 ixgbevf_configure_msix(struct rte_eth_dev *dev)
 {
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t q_idx;
@@ -4979,7 +5264,8 @@ ixgbevf_configure_msix(struct rte_eth_dev *dev)
 static void
 ixgbe_configure_msix(struct rte_eth_dev *dev)
 {
-       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
+       struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t queue_id, base = IXGBE_MISC_VEC_ID;
@@ -5097,6 +5383,7 @@ static int ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev,
 static int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
        uint16_t tx_rate, uint64_t q_msk)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_vf_info *vfinfo =
                *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
@@ -5111,7 +5398,7 @@ static int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
                return -EINVAL;
 
        if (vfinfo != NULL) {
-               for (vf_idx = 0; vf_idx < dev->pci_dev->max_vfs; vf_idx++) {
+               for (vf_idx = 0; vf_idx < pci_dev->max_vfs; vf_idx++) {
                        if (vf_idx == vf)
                                continue;
                        for (idx = 0; idx < RTE_DIM(vfinfo[vf_idx].tx_rate);
@@ -6323,6 +6610,12 @@ ixgbe_get_regs(struct rte_eth_dev *dev,
        const struct reg_info **reg_set = (hw->mac.type == ixgbe_mac_82598EB) ?
                                    ixgbe_regs_mac_82598EB : ixgbe_regs_others;
 
+       if (data == NULL) {
+               regs->length = ixgbe_get_reg_length(dev);
+               regs->width = sizeof(uint32_t);
+               return 0;
+       }
+
        /* Support only full register dump */
        if ((regs->length == 0) ||
            (regs->length == (uint32_t)ixgbe_get_reg_length(dev))) {
@@ -6347,6 +6640,12 @@ ixgbevf_get_regs(struct rte_eth_dev *dev,
        int count = 0;
        const struct reg_info *reg_group;
 
+       if (data == NULL) {
+               regs->length = ixgbevf_get_reg_length(dev);
+               regs->width = sizeof(uint32_t);
+               return 0;
+       }
+
        /* Support only full register dump */
        if ((regs->length == 0) ||
            (regs->length == (uint32_t)ixgbevf_get_reg_length(dev))) {
@@ -6912,15 +7211,16 @@ ixgbe_e_tag_insertion_en_dis(struct rte_eth_dev *dev,
                             struct rte_eth_l2_tunnel_conf *l2_tunnel,
                             bool en)
 {
+       struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
        int ret = 0;
        uint32_t vmtir, vmvir;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       if (l2_tunnel->vf_id >= dev->pci_dev->max_vfs) {
+       if (l2_tunnel->vf_id >= pci_dev->max_vfs) {
                PMD_DRV_LOG(ERR,
                            "VF id %u should be less than %u",
                            l2_tunnel->vf_id,
-                           dev->pci_dev->max_vfs);
+                           pci_dev->max_vfs);
                return -EINVAL;
        }
 
@@ -7233,51 +7533,12 @@ ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
        return ret;
 }
 
-/* ixgbevf_update_xcast_mode - Update Multicast mode
- * @hw: pointer to the HW structure
- * @netdev: pointer to net device structure
- * @xcast_mode: new multicast mode
- *
- * Updates the Multicast Mode of VF.
- */
-static int ixgbevf_update_xcast_mode(struct ixgbe_hw *hw,
-                                    int xcast_mode)
-{
-       struct ixgbe_mbx_info *mbx = &hw->mbx;
-       u32 msgbuf[2];
-       s32 err;
-
-       switch (hw->api_version) {
-       case ixgbe_mbox_api_12:
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE;
-       msgbuf[1] = xcast_mode;
-
-       err = mbx->ops.write_posted(hw, msgbuf, 2, 0);
-       if (err)
-               return err;
-
-       err = mbx->ops.read_posted(hw, msgbuf, 2, 0);
-       if (err)
-               return err;
-
-       msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
-       if (msgbuf[0] == (IXGBE_VF_UPDATE_XCAST_MODE | IXGBE_VT_MSGTYPE_NACK))
-               return -EPERM;
-
-       return 0;
-}
-
 static void
 ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       ixgbevf_update_xcast_mode(hw, IXGBEVF_XCAST_MODE_ALLMULTI);
+       hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_ALLMULTI);
 }
 
 static void
@@ -7285,7 +7546,7 @@ ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       ixgbevf_update_xcast_mode(hw, IXGBEVF_XCAST_MODE_NONE);
+       hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_NONE);
 }
 
 static void ixgbevf_mbx_process(struct rte_eth_dev *dev)
@@ -7298,7 +7559,7 @@ static void ixgbevf_mbx_process(struct rte_eth_dev *dev)
 
        /* PF reset VF event */
        if (in_msg == IXGBE_PF_CONTROL_MSG)
-               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET);
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
 }
 
 static int
@@ -7349,15 +7610,9 @@ ixgbevf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
        ixgbevf_dev_interrupt_action(dev);
 }
 
-static struct rte_driver rte_ixgbe_driver = {
-       .type = PMD_PDEV,
-       .init = rte_ixgbe_pmd_init,
-};
-
-static struct rte_driver rte_ixgbevf_driver = {
-       .type = PMD_PDEV,
-       .init = rte_ixgbevf_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_ixgbe_driver);
-PMD_REGISTER_DRIVER(rte_ixgbevf_driver);
+RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd.pci_drv);
+RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio");
+RTE_PMD_REGISTER_PCI(net_ixgbe_vf, rte_ixgbevf_pmd.pci_drv);
+RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe_vf, pci_id_ixgbevf_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe_vf, "* igb_uio | vfio");