net/ixgbe: fix DCB configuration
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index 8295ca6..5ecf129 100644 (file)
@@ -59,9 +59,6 @@
  */
 #define IXGBE_FC_LO    0x40
 
-/* Default minimum inter-interrupt interval for EITR configuration */
-#define IXGBE_MIN_INTER_INTERRUPT_INTERVAL_DEFAULT    0x79E
-
 /* Timer value included in XOFF frames. */
 #define IXGBE_FC_PAUSE 0x680
 
 
 #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / sizeof(hw_stats->qprc[0]))
 
-#define IXGBE_HKEY_MAX_INDEX 10
-
 /* Additional timesync values. */
 #define NSEC_PER_SEC             1000000000L
 #define IXGBE_INCVAL_10GB        0x66666666
 
 #define IXGBE_VT_CTL_POOLING_MODE_MASK         0x00030000
 #define IXGBE_VT_CTL_POOLING_MODE_ETAG         0x00010000
-#define DEFAULT_ETAG_ETYPE                     0x893f
 #define IXGBE_ETAG_ETYPE                       0x00005084
 #define IXGBE_ETAG_ETYPE_MASK                  0x0000ffff
 #define IXGBE_ETAG_ETYPE_VALID                 0x80000000
 #define IXGBE_EXVET_VET_EXT_SHIFT              16
 #define IXGBE_DMATXCTL_VT_MASK                 0xFFFF0000
 
-static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
+static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
 static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
 static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
 static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
@@ -227,7 +221,7 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static int ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
                         uint32_t index, uint32_t pool);
 static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbe_set_default_mac_addr(struct rte_eth_dev *dev,
                                           struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config);
 static bool is_device_supported(struct rte_eth_dev *dev,
@@ -243,8 +237,8 @@ static int ixgbevf_dev_link_update(struct rte_eth_dev *dev,
 static void ixgbevf_dev_stop(struct rte_eth_dev *dev);
 static void ixgbevf_dev_close(struct rte_eth_dev *dev);
 static int  ixgbevf_dev_reset(struct rte_eth_dev *dev);
-static void ixgbevf_intr_disable(struct ixgbe_hw *hw);
-static void ixgbevf_intr_enable(struct ixgbe_hw *hw);
+static void ixgbevf_intr_disable(struct rte_eth_dev *dev);
+static void ixgbevf_intr_enable(struct rte_eth_dev *dev);
 static int ixgbevf_dev_stats_get(struct rte_eth_dev *dev,
                struct rte_eth_stats *stats);
 static void ixgbevf_dev_stats_reset(struct rte_eth_dev *dev);
@@ -285,7 +279,7 @@ static int ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
                                struct ether_addr *mac_addr,
                                uint32_t index, uint32_t pool);
 static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
-static void ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+static int ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
                                             struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_get(struct rte_eth_dev *dev,
                        struct rte_eth_syn_filter *filter);
@@ -327,6 +321,11 @@ static int ixgbe_get_eeprom(struct rte_eth_dev *dev,
 static int ixgbe_set_eeprom(struct rte_eth_dev *dev,
                                struct rte_dev_eeprom_info *eeprom);
 
+static int ixgbe_get_module_info(struct rte_eth_dev *dev,
+                                struct rte_eth_dev_module_info *modinfo);
+static int ixgbe_get_module_eeprom(struct rte_eth_dev *dev,
+                                  struct rte_dev_eeprom_info *info);
+
 static int ixgbevf_get_reg_length(struct rte_eth_dev *dev);
 static int ixgbevf_get_regs(struct rte_eth_dev *dev,
                                struct rte_dev_reg_info *regs);
@@ -564,6 +563,8 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .get_eeprom_length    = ixgbe_get_eeprom_length,
        .get_eeprom           = ixgbe_get_eeprom,
        .set_eeprom           = ixgbe_set_eeprom,
+       .get_module_info      = ixgbe_get_module_info,
+       .get_module_eeprom    = ixgbe_get_module_eeprom,
        .get_dcb_info         = ixgbe_dev_get_dcb_info,
        .timesync_adjust_time = ixgbe_timesync_adjust_time,
        .timesync_read_time   = ixgbe_timesync_read_time,
@@ -1043,7 +1044,7 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)
  * It returns 0 on success.
  */
 static int
-eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
+eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
 {
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
@@ -1483,7 +1484,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
        }
        l2_tn_info->e_tag_en = FALSE;
        l2_tn_info->e_tag_fwd_en = FALSE;
-       l2_tn_info->e_tag_ether_type = DEFAULT_ETAG_ETYPE;
+       l2_tn_info->e_tag_ether_type = ETHER_TYPE_ETAG;
 
        return 0;
 }
@@ -1602,7 +1603,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
        ixgbevf_dev_stats_reset(eth_dev);
 
        /* Disable the interrupts for VF */
-       ixgbevf_intr_disable(hw);
+       ixgbevf_intr_disable(eth_dev);
 
        hw->mac.num_rar_entries = 128; /* The MAX of the underlying PF */
        diag = hw->mac.ops.reset_hw(hw);
@@ -1671,7 +1672,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
        rte_intr_callback_register(intr_handle,
                                   ixgbevf_dev_interrupt_handler, eth_dev);
        rte_intr_enable(intr_handle);
-       ixgbevf_intr_enable(hw);
+       ixgbevf_intr_enable(eth_dev);
 
        PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s",
                     eth_dev->data->port_id, pci_dev->id.vendor_id,
@@ -1704,7 +1705,7 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
        eth_dev->tx_pkt_burst = NULL;
 
        /* Disable the interrupts for VF */
-       ixgbevf_intr_disable(hw);
+       ixgbevf_intr_disable(eth_dev);
 
        rte_free(eth_dev->data->mac_addrs);
        eth_dev->data->mac_addrs = NULL;
@@ -1716,16 +1717,81 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
        return 0;
 }
 
-static int eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
-       struct rte_pci_device *pci_dev)
-{
-       return rte_eth_dev_pci_generic_probe(pci_dev,
-               sizeof(struct ixgbe_adapter), eth_ixgbe_dev_init);
+static int
+eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+               struct rte_pci_device *pci_dev)
+{
+       char name[RTE_ETH_NAME_MAX_LEN];
+       struct rte_eth_dev *pf_ethdev;
+       struct rte_eth_devargs eth_da;
+       int i, retval;
+
+       if (pci_dev->device.devargs) {
+               retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
+                               &eth_da);
+               if (retval)
+                       return retval;
+       } else
+               memset(&eth_da, 0, sizeof(eth_da));
+
+       retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
+               sizeof(struct ixgbe_adapter),
+               eth_dev_pci_specific_init, pci_dev,
+               eth_ixgbe_dev_init, NULL);
+
+       if (retval || eth_da.nb_representor_ports < 1)
+               return retval;
+
+       pf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);
+       if (pf_ethdev == NULL)
+               return -ENODEV;
+
+       /* probe VF representor ports */
+       for (i = 0; i < eth_da.nb_representor_ports; i++) {
+               struct ixgbe_vf_info *vfinfo;
+               struct ixgbe_vf_representor representor;
+
+               vfinfo = *IXGBE_DEV_PRIVATE_TO_P_VFDATA(
+                       pf_ethdev->data->dev_private);
+               if (vfinfo == NULL) {
+                       PMD_DRV_LOG(ERR,
+                               "no virtual functions supported by PF");
+                       break;
+               }
+
+               representor.vf_id = eth_da.representor_ports[i];
+               representor.switch_domain_id = vfinfo->switch_domain_id;
+               representor.pf_ethdev = pf_ethdev;
+
+               /* representor port net_bdf_port */
+               snprintf(name, sizeof(name), "net_%s_representor_%d",
+                       pci_dev->device.name,
+                       eth_da.representor_ports[i]);
+
+               retval = rte_eth_dev_create(&pci_dev->device, name,
+                       sizeof(struct ixgbe_vf_representor), NULL, NULL,
+                       ixgbe_vf_representor_init, &representor);
+
+               if (retval)
+                       PMD_DRV_LOG(ERR, "failed to create ixgbe vf "
+                               "representor %s.", name);
+       }
+
+       return 0;
 }
 
 static int eth_ixgbe_pci_remove(struct rte_pci_device *pci_dev)
 {
-       return rte_eth_dev_pci_generic_remove(pci_dev, eth_ixgbe_dev_uninit);
+       struct rte_eth_dev *ethdev;
+
+       ethdev = rte_eth_dev_allocated(pci_dev->device.name);
+       if (!ethdev)
+               return -ENODEV;
+
+       if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
+               return rte_eth_dev_destroy(ethdev, ixgbe_vf_representor_uninit);
+       else
+               return rte_eth_dev_destroy(ethdev, eth_ixgbe_dev_uninit);
 }
 
 static struct rte_pci_driver rte_ixgbe_pmd = {
@@ -2238,11 +2304,6 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                if (dev_conf->rxmode.mq_mode == ETH_MQ_RX_DCB) {
                        const struct rte_eth_dcb_rx_conf *conf;
 
-                       if (nb_rx_q != IXGBE_DCB_NB_QUEUES) {
-                               PMD_INIT_LOG(ERR, "DCB selected, nb_rx_q != %d.",
-                                                IXGBE_DCB_NB_QUEUES);
-                               return -EINVAL;
-                       }
                        conf = &dev_conf->rx_adv_conf.dcb_rx_conf;
                        if (!(conf->nb_tcs == ETH_4_TCS ||
                               conf->nb_tcs == ETH_8_TCS)) {
@@ -2256,11 +2317,6 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                if (dev_conf->txmode.mq_mode == ETH_MQ_TX_DCB) {
                        const struct rte_eth_dcb_tx_conf *conf;
 
-                       if (nb_tx_q != IXGBE_DCB_NB_QUEUES) {
-                               PMD_INIT_LOG(ERR, "DCB, nb_tx_q != %d.",
-                                                IXGBE_DCB_NB_QUEUES);
-                               return -EINVAL;
-                       }
                        conf = &dev_conf->tx_adv_conf.dcb_tx_conf;
                        if (!(conf->nb_tcs == ETH_4_TCS ||
                               conf->nb_tcs == ETH_8_TCS)) {
@@ -2296,9 +2352,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        struct ixgbe_adapter *adapter =
                (struct ixgbe_adapter *)dev->data->dev_private;
-       struct rte_eth_dev_info dev_info;
-       uint64_t rx_offloads;
-       uint64_t tx_offloads;
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -2310,22 +2363,6 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
                return ret;
        }
 
-       ixgbe_dev_info_get(dev, &dev_info);
-       rx_offloads = dev->data->dev_conf.rxmode.offloads;
-       if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-               PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-                           rx_offloads, dev_info.rx_offload_capa);
-               return -ENOTSUP;
-       }
-       tx_offloads = dev->data->dev_conf.txmode.offloads;
-       if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-               PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-                           tx_offloads, dev_info.tx_offload_capa);
-               return -ENOTSUP;
-       }
-
        /* set flag to update link status after init */
        intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -2448,6 +2485,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        uint32_t intr_vector = 0;
        int err, link_up = 0, negotiate = 0;
        uint32_t speed = 0;
+       uint32_t allowed_speeds = 0;
        int mask = 0;
        int status;
        uint16_t vf, idx;
@@ -2596,9 +2634,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        if (err)
                goto error;
 
+       switch (hw->mac.type) {
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
+               allowed_speeds = ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_2_5G |  ETH_LINK_SPEED_5G |
+                       ETH_LINK_SPEED_10G;
+               break;
+       default:
+               allowed_speeds = ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_10G;
+       }
+
        link_speeds = &dev->data->dev_conf.link_speeds;
-       if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
-                       ETH_LINK_SPEED_10G)) {
+       if (*link_speeds & ~allowed_speeds) {
                PMD_INIT_LOG(ERR, "Invalid link setting");
                goto error;
        }
@@ -2624,6 +2674,10 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        } else {
                if (*link_speeds & ETH_LINK_SPEED_10G)
                        speed |= IXGBE_LINK_SPEED_10GB_FULL;
+               if (*link_speeds & ETH_LINK_SPEED_5G)
+                       speed |= IXGBE_LINK_SPEED_5GB_FULL;
+               if (*link_speeds & ETH_LINK_SPEED_2_5G)
+                       speed |= IXGBE_LINK_SPEED_2_5GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_1G)
                        speed |= IXGBE_LINK_SPEED_1GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_100M)
@@ -2634,6 +2688,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        if (err)
                goto error;
 
+       ixgbe_dev_link_update(dev, 0);
+
 skip_link_setup:
 
        if (rte_intr_allow_others(intr_handle)) {
@@ -2849,7 +2905,7 @@ ixgbe_dev_reset(struct rte_eth_dev *dev)
        if (ret)
                return ret;
 
-       ret = eth_ixgbe_dev_init(dev);
+       ret = eth_ixgbe_dev_init(dev, NULL);
 
        return ret;
 }
@@ -3593,7 +3649,6 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        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) {
@@ -3640,9 +3695,6 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                },
                .tx_free_thresh = IXGBE_DEFAULT_TX_FREE_THRESH,
                .tx_rs_thresh = IXGBE_DEFAULT_TX_RSBIT_THRESH,
-               .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
-                            ETH_TXQ_FLAGS_NOOFFLOADS |
-                            ETH_TXQ_FLAGS_IGNORE,
                .offloads = 0,
        };
 
@@ -3712,7 +3764,6 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
        struct rte_pci_device *pci_dev = RTE_ETH_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 */
@@ -3749,9 +3800,6 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                },
                .tx_free_thresh = IXGBE_DEFAULT_TX_FREE_THRESH,
                .tx_rs_thresh = IXGBE_DEFAULT_TX_RSBIT_THRESH,
-               .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
-                            ETH_TXQ_FLAGS_NOOFFLOADS |
-                            ETH_TXQ_FLAGS_IGNORE,
                .offloads = 0,
        };
 
@@ -3866,7 +3914,7 @@ out:
 }
 
 /* return 0 means link status changed, -1 means not changed */
-static int
+int
 ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
                            int wait_to_complete, int vf)
 {
@@ -3883,7 +3931,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 
        memset(&link, 0, sizeof(link));
        link.link_status = ETH_LINK_DOWN;
-       link.link_speed = 0;
+       link.link_speed = ETH_SPEED_NUM_NONE;
        link.link_duplex = ETH_LINK_HALF_DUPLEX;
        link.link_autoneg = ETH_LINK_AUTONEG;
 
@@ -4768,14 +4816,15 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
        ixgbe_clear_rar(hw, index);
 }
 
-static void
+static int
 ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 
        ixgbe_remove_rar(dev, 0);
-
        ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
+
+       return 0;
 }
 
 static bool
@@ -4849,19 +4898,32 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
  * Virtual Function operations
  */
 static void
-ixgbevf_intr_disable(struct ixgbe_hw *hw)
+ixgbevf_intr_disable(struct rte_eth_dev *dev)
 {
+       struct ixgbe_interrupt *intr =
+               IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+       struct ixgbe_hw *hw =
+               IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
        PMD_INIT_FUNC_TRACE();
 
        /* Clear interrupt mask to stop from interrupts being generated */
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK);
 
        IXGBE_WRITE_FLUSH(hw);
+
+       /* Clear mask value. */
+       intr->mask = 0;
 }
 
 static void
-ixgbevf_intr_enable(struct ixgbe_hw *hw)
+ixgbevf_intr_enable(struct rte_eth_dev *dev)
 {
+       struct ixgbe_interrupt *intr =
+               IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+       struct ixgbe_hw *hw =
+               IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
        PMD_INIT_FUNC_TRACE();
 
        /* VF enable interrupt autoclean */
@@ -4870,6 +4932,9 @@ ixgbevf_intr_enable(struct ixgbe_hw *hw)
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_VF_IRQ_ENABLE_MASK);
 
        IXGBE_WRITE_FLUSH(hw);
+
+       /* Save IXGBE_VTEIMS value to mask. */
+       intr->mask = IXGBE_VF_IRQ_ENABLE_MASK;
 }
 
 static int
@@ -4878,29 +4943,10 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
        struct rte_eth_conf *conf = &dev->data->dev_conf;
        struct ixgbe_adapter *adapter =
                        (struct ixgbe_adapter *)dev->data->dev_private;
-       struct rte_eth_dev_info dev_info;
-       uint64_t rx_offloads;
-       uint64_t tx_offloads;
 
        PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
                     dev->data->port_id);
 
-       ixgbevf_dev_info_get(dev, &dev_info);
-       rx_offloads = dev->data->dev_conf.rxmode.offloads;
-       if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
-               PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
-                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-                           rx_offloads, dev_info.rx_offload_capa);
-               return -ENOTSUP;
-       }
-       tx_offloads = dev->data->dev_conf.txmode.offloads;
-       if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
-               PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
-                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
-                           tx_offloads, dev_info.tx_offload_capa);
-               return -ENOTSUP;
-       }
-
        /*
         * VF has no ability to enable/disable HW CRC
         * Keep the persistent behavior the same as Host PF
@@ -4975,6 +5021,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
 
        ixgbevf_dev_rxtx_start(dev);
 
+       ixgbevf_dev_link_update(dev, 0);
+
        /* check and configure queue intr-vector mapping */
        if (rte_intr_cap_multiple(intr_handle) &&
            dev->data->dev_conf.intr_conf.rxq) {
@@ -5010,7 +5058,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
        rte_intr_enable(intr_handle);
 
        /* Re-enable interrupt for VF */
-       ixgbevf_intr_enable(hw);
+       ixgbevf_intr_enable(dev);
 
        return 0;
 }
@@ -5024,7 +5072,7 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
-       ixgbevf_intr_disable(hw);
+       ixgbevf_intr_disable(dev);
 
        hw->adapter_stopped = 1;
        ixgbe_stop_adapter(hw);
@@ -5164,15 +5212,13 @@ ixgbevf_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 static int
 ixgbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
-       struct ixgbe_hw *hw =
-               IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_rx_queue *rxq;
        uint16_t i;
        int on = 0;
 
        /* VF function only support hw strip feature, others are not support */
        if (mask & ETH_VLAN_STRIP_MASK) {
-               for (i = 0; i < hw->mac.max_rx_queues; i++) {
+               for (i = 0; i < dev->data->nb_rx_queues; i++) {
                        rxq = dev->data->rx_queues[i];
                        on = !!(rxq->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
                        ixgbevf_vlan_strip_queue_set(dev, i, on);
@@ -5518,17 +5564,17 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
-       uint32_t mask;
+       struct ixgbe_interrupt *intr =
+               IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t vec = IXGBE_MISC_VEC_ID;
 
-       mask = IXGBE_READ_REG(hw, IXGBE_VTEIMS);
        if (rte_intr_allow_others(intr_handle))
                vec = IXGBE_RX_VEC_START;
-       mask |= (1 << vec);
+       intr->mask |= (1 << vec);
        RTE_SET_USED(queue_id);
-       IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
+       IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, intr->mask);
 
        rte_intr_enable(intr_handle);
 
@@ -5538,19 +5584,19 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 static int
 ixgbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
-       uint32_t mask;
+       struct ixgbe_interrupt *intr =
+               IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        uint32_t vec = IXGBE_MISC_VEC_ID;
 
-       mask = IXGBE_READ_REG(hw, IXGBE_VTEIMS);
        if (rte_intr_allow_others(intr_handle))
                vec = IXGBE_RX_VEC_START;
-       mask &= ~(1 << vec);
+       intr->mask &= ~(1 << vec);
        RTE_SET_USED(queue_id);
-       IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
+       IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, intr->mask);
 
        return 0;
 }
@@ -5716,6 +5762,13 @@ ixgbevf_configure_msix(struct rte_eth_dev *dev)
                if (vector_idx < base + intr_handle->nb_efd - 1)
                        vector_idx++;
        }
+
+       /* As RX queue setting above show, all queues use the vector 0.
+        * Set only the ITR value of IXGBE_MISC_VEC_ID.
+        */
+       IXGBE_WRITE_REG(hw, IXGBE_VTEITR(IXGBE_MISC_VEC_ID),
+                       IXGBE_EITR_INTERVAL_US(IXGBE_QUEUE_ITR_INTERVAL_DEFAULT)
+                       | IXGBE_EITR_CNT_WDIS);
 }
 
 /**
@@ -5737,8 +5790,12 @@ ixgbe_configure_msix(struct rte_eth_dev *dev)
 
        /* won't configure msix register if no mapping is done
         * between intr vector and event fd
+        * but if misx has been enabled already, need to configure
+        * auto clean, auto mask and throttling.
         */
-       if (!rte_intr_dp_is_en(intr_handle))
+       gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+       if (!rte_intr_dp_is_en(intr_handle) &&
+           !(gpie & (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT)))
                return;
 
        if (rte_intr_allow_others(intr_handle))
@@ -5762,30 +5819,34 @@ ixgbe_configure_msix(struct rte_eth_dev *dev)
        /* Populate the IVAR table and set the ITR values to the
         * corresponding register.
         */
-       for (queue_id = 0; queue_id < dev->data->nb_rx_queues;
-            queue_id++) {
-               /* by default, 1:1 mapping */
-               ixgbe_set_ivar_map(hw, 0, queue_id, vec);
-               intr_handle->intr_vec[queue_id] = vec;
-               if (vec < base + intr_handle->nb_efd - 1)
-                       vec++;
-       }
+       if (rte_intr_dp_is_en(intr_handle)) {
+               for (queue_id = 0; queue_id < dev->data->nb_rx_queues;
+                       queue_id++) {
+                       /* by default, 1:1 mapping */
+                       ixgbe_set_ivar_map(hw, 0, queue_id, vec);
+                       intr_handle->intr_vec[queue_id] = vec;
+                       if (vec < base + intr_handle->nb_efd - 1)
+                               vec++;
+               }
 
-       switch (hw->mac.type) {
-       case ixgbe_mac_82598EB:
-               ixgbe_set_ivar_map(hw, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
-                                  IXGBE_MISC_VEC_ID);
-               break;
-       case ixgbe_mac_82599EB:
-       case ixgbe_mac_X540:
-       case ixgbe_mac_X550:
-               ixgbe_set_ivar_map(hw, -1, 1, IXGBE_MISC_VEC_ID);
-               break;
-       default:
-               break;
+               switch (hw->mac.type) {
+               case ixgbe_mac_82598EB:
+                       ixgbe_set_ivar_map(hw, -1,
+                                          IXGBE_IVAR_OTHER_CAUSES_INDEX,
+                                          IXGBE_MISC_VEC_ID);
+                       break;
+               case ixgbe_mac_82599EB:
+               case ixgbe_mac_X540:
+               case ixgbe_mac_X550:
+                       ixgbe_set_ivar_map(hw, -1, 1, IXGBE_MISC_VEC_ID);
+                       break;
+               default:
+                       break;
+               }
        }
        IXGBE_WRITE_REG(hw, IXGBE_EITR(IXGBE_MISC_VEC_ID),
-                       IXGBE_MIN_INTER_INTERRUPT_INTERVAL_DEFAULT & 0xFFF);
+                       IXGBE_EITR_INTERVAL_US(IXGBE_QUEUE_ITR_INTERVAL_DEFAULT)
+                       | IXGBE_EITR_CNT_WDIS);
 
        /* set up to autoclear timer, and the vectors */
        mask = IXGBE_EIMS_ENABLE_MASK;
@@ -5922,12 +5983,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
        }
 }
 
-static void
+static int
 ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
+
+       return 0;
 }
 
 int
@@ -7104,6 +7167,78 @@ ixgbe_set_eeprom(struct rte_eth_dev *dev,
        return eeprom->ops.write_buffer(hw,  first, length, data);
 }
 
+static int
+ixgbe_get_module_info(struct rte_eth_dev *dev,
+                     struct rte_eth_dev_module_info *modinfo)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t status;
+       uint8_t sff8472_rev, addr_mode;
+       bool page_swap = false;
+
+       /* Check whether we support SFF-8472 or not */
+       status = hw->phy.ops.read_i2c_eeprom(hw,
+                                            IXGBE_SFF_SFF_8472_COMP,
+                                            &sff8472_rev);
+       if (status != 0)
+               return -EIO;
+
+       /* addressing mode is not supported */
+       status = hw->phy.ops.read_i2c_eeprom(hw,
+                                            IXGBE_SFF_SFF_8472_SWAP,
+                                            &addr_mode);
+       if (status != 0)
+               return -EIO;
+
+       if (addr_mode & IXGBE_SFF_ADDRESSING_MODE) {
+               PMD_DRV_LOG(ERR,
+                           "Address change required to access page 0xA2, "
+                           "but not supported. Please report the module "
+                           "type to the driver maintainers.");
+               page_swap = true;
+       }
+
+       if (sff8472_rev == IXGBE_SFF_SFF_8472_UNSUP || page_swap) {
+               /* We have a SFP, but it does not support SFF-8472 */
+               modinfo->type = RTE_ETH_MODULE_SFF_8079;
+               modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
+       } else {
+               /* We have a SFP which supports a revision of SFF-8472. */
+               modinfo->type = RTE_ETH_MODULE_SFF_8472;
+               modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+       }
+
+       return 0;
+}
+
+static int
+ixgbe_get_module_eeprom(struct rte_eth_dev *dev,
+                       struct rte_dev_eeprom_info *info)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t status = IXGBE_ERR_PHY_ADDR_INVALID;
+       uint8_t databyte = 0xFF;
+       uint8_t *data = info->data;
+       uint32_t i = 0;
+
+       if (info->length == 0)
+               return -EINVAL;
+
+       for (i = info->offset; i < info->offset + info->length; i++) {
+               if (i < RTE_ETH_MODULE_SFF_8079_LEN)
+                       status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
+               else
+                       status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte);
+
+               if (status != 0)
+                       return -EIO;
+
+               data[i - info->offset] = databyte;
+       }
+
+       return 0;
+}
+
 uint16_t
 ixgbe_reta_size_get(enum ixgbe_mac_type mac_type) {
        switch (mac_type) {
@@ -8107,7 +8242,7 @@ ixgbevf_dev_interrupt_get_status(struct rte_eth_dev *dev)
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_interrupt *intr =
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-       ixgbevf_intr_disable(hw);
+       ixgbevf_intr_disable(dev);
 
        /* read-on-clear nic registers here */
        eicr = IXGBE_READ_REG(hw, IXGBE_VTEICR);
@@ -8124,7 +8259,6 @@ ixgbevf_dev_interrupt_get_status(struct rte_eth_dev *dev)
 static int
 ixgbevf_dev_interrupt_action(struct rte_eth_dev *dev)
 {
-       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct ixgbe_interrupt *intr =
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 
@@ -8133,7 +8267,7 @@ ixgbevf_dev_interrupt_action(struct rte_eth_dev *dev)
                intr->flags &= ~IXGBE_FLAG_MAILBOX;
        }
 
-       ixgbevf_intr_enable(hw);
+       ixgbevf_intr_enable(dev);
 
        return 0;
 }
@@ -8272,7 +8406,7 @@ ixgbe_rss_filter_restore(struct rte_eth_dev *dev)
        struct ixgbe_filter_info *filter_info =
                IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 
-       if (filter_info->rss_info.num)
+       if (filter_info->rss_info.conf.queue_num)
                ixgbe_config_rss_filter(dev,
                        &filter_info->rss_info, TRUE);
 }