ixgbe: account more Rx errors
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index 0638302..19bcffe 100644 (file)
@@ -68,6 +68,9 @@
 #include "ixgbe_ethdev.h"
 #include "ixgbe_bypass.h"
 #include "ixgbe_rxtx.h"
+#include "base/ixgbe_type.h"
+#include "base/ixgbe_phy.h"
+#include "ixgbe_regs.h"
 
 /*
  * High threshold controlling when to start sending XOFF frames. Must be at
@@ -91,6 +94,7 @@
 
 #define IXGBE_MMW_SIZE_DEFAULT        0x4
 #define IXGBE_MMW_SIZE_JUMBO_FRAME    0x14
+#define IXGBE_MAX_RING_DESC           4096 /* replicate define from rxtx */
 
 /*
  *  Default values for RX/TX configuration
 
 #define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / sizeof(hw_stats->qprc[0]))
 
+#define IXGBE_HKEY_MAX_INDEX 10
+
+/* Additional timesync values. */
+#define IXGBE_TIMINCA_16NS_SHIFT 24
+#define IXGBE_TIMINCA_INCVALUE   16000000
+#define IXGBE_TIMINCA_INIT       ((0x02 << IXGBE_TIMINCA_16NS_SHIFT) \
+                                 | IXGBE_TIMINCA_INCVALUE)
+
 static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
 static int  ixgbe_dev_configure(struct rte_eth_dev *dev);
 static int  ixgbe_dev_start(struct rte_eth_dev *dev);
@@ -131,7 +143,10 @@ static int ixgbe_dev_link_update(struct rte_eth_dev *dev,
                                int wait_to_complete);
 static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
                                struct rte_eth_stats *stats);
+static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
+                               struct rte_eth_xstats *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
+static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
                                             uint16_t queue_id,
                                             uint8_t stat_idx,
@@ -179,6 +194,8 @@ static void ixgbe_dev_interrupt_delayed_handler(void *param);
 static void 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,
+                                          struct ether_addr *mac_addr);
 static void ixgbe_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_config);
 
 /* For Virtual Function support */
@@ -223,6 +240,8 @@ static void 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,
+                                            struct ether_addr *mac_addr);
 static int ixgbe_syn_filter_set(struct rte_eth_dev *dev,
                        struct rte_eth_syn_filter *filter,
                        bool add);
@@ -261,6 +280,27 @@ static int ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
                                      struct ether_addr *mc_addr_set,
                                      uint32_t nb_mc_addr);
 
+static int ixgbe_get_reg_length(struct rte_eth_dev *dev);
+static int ixgbe_get_regs(struct rte_eth_dev *dev,
+                           struct rte_dev_reg_info *regs);
+static int ixgbe_get_eeprom_length(struct rte_eth_dev *dev);
+static int ixgbe_get_eeprom(struct rte_eth_dev *dev,
+                               struct rte_dev_eeprom_info *eeprom);
+static int ixgbe_set_eeprom(struct rte_eth_dev *dev,
+                               struct rte_dev_eeprom_info *eeprom);
+
+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);
+
+static int ixgbe_timesync_enable(struct rte_eth_dev *dev);
+static int ixgbe_timesync_disable(struct rte_eth_dev *dev);
+static int ixgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+                                           struct timespec *timestamp,
+                                           uint32_t flags);
+static int ixgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+                                           struct timespec *timestamp);
+
 /*
  * Define VF Stats MACRO for Non "cleared on read" register
  */
@@ -334,7 +374,9 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .allmulticast_disable = ixgbe_dev_allmulticast_disable,
        .link_update          = ixgbe_dev_link_update,
        .stats_get            = ixgbe_dev_stats_get,
+       .xstats_get           = ixgbe_dev_xstats_get,
        .stats_reset          = ixgbe_dev_stats_reset,
+       .xstats_reset         = ixgbe_dev_xstats_reset,
        .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
        .dev_infos_get        = ixgbe_dev_info_get,
        .mtu_set              = ixgbe_dev_mtu_set,
@@ -359,6 +401,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .priority_flow_ctrl_set = ixgbe_priority_flow_ctrl_set,
        .mac_addr_add         = ixgbe_add_rar,
        .mac_addr_remove      = ixgbe_remove_rar,
+       .mac_addr_set         = ixgbe_set_default_mac_addr,
        .uc_hash_table_set    = ixgbe_uc_hash_table_set,
        .uc_all_hash_table_set  = ixgbe_uc_all_hash_table_set,
        .mirror_rule_set      = ixgbe_mirror_rule_set,
@@ -386,6 +429,15 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .rss_hash_conf_get    = ixgbe_dev_rss_hash_conf_get,
        .filter_ctrl          = ixgbe_dev_filter_ctrl,
        .set_mc_addr_list     = ixgbe_dev_set_mc_addr_list,
+       .timesync_enable      = ixgbe_timesync_enable,
+       .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,
+       .set_eeprom           = ixgbe_set_eeprom,
 };
 
 /*
@@ -412,8 +464,46 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
        .mac_addr_add         = ixgbevf_add_mac_addr,
        .mac_addr_remove      = ixgbevf_remove_mac_addr,
        .set_mc_addr_list     = ixgbe_dev_set_mc_addr_list,
+       .mac_addr_set         = ixgbevf_set_default_mac_addr,
+       .get_reg_length       = ixgbevf_get_reg_length,
+       .get_reg              = ixgbevf_get_regs,
+};
+
+/* store statistics names and its offset in stats structure */
+struct rte_ixgbe_xstats_name_off {
+       char name[RTE_ETH_XSTATS_NAME_SIZE];
+       unsigned offset;
+};
+
+static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
+       {"rx_illegal_byte_err", offsetof(struct ixgbe_hw_stats, errbc)},
+       {"rx_len_err", offsetof(struct ixgbe_hw_stats, rlec)},
+       {"rx_undersize_count", offsetof(struct ixgbe_hw_stats, ruc)},
+       {"rx_oversize_count", offsetof(struct ixgbe_hw_stats, roc)},
+       {"rx_fragment_count", offsetof(struct ixgbe_hw_stats, rfc)},
+       {"rx_jabber_count", offsetof(struct ixgbe_hw_stats, rjc)},
+       {"l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
+       {"mac_local_fault", offsetof(struct ixgbe_hw_stats, mlfc)},
+       {"mac_remote_fault", offsetof(struct ixgbe_hw_stats, mrfc)},
+       {"mac_short_pkt_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
+       {"fccrc_error", offsetof(struct ixgbe_hw_stats, fccrc)},
+       {"fcoe_drop", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
+       {"fc_last_error", offsetof(struct ixgbe_hw_stats, fclast)},
+       {"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
+       {"rx_phy_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
+       {"mgmt_pkts_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
+       {"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
+       {"fdir_match", offsetof(struct ixgbe_hw_stats, fdirmatch)},
+       {"fdir_miss", offsetof(struct ixgbe_hw_stats, fdirmiss)},
+       {"tx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxontxc)},
+       {"rx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxonrxc)},
+       {"tx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxofftxc)},
+       {"rx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
 };
 
+#define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /     \
+               sizeof(rte_ixgbe_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -846,6 +936,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
                return -EIO;
        }
 
+       /* Reset the hw statistics */
+       ixgbe_dev_stats_reset(eth_dev);
+
        /* disable interrupt */
        ixgbe_disable_intr(hw);
 
@@ -1018,6 +1111,9 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
        /* init_mailbox_params */
        hw->mbx.ops.init_params(hw);
 
+       /* Reset the hw statistics */
+       ixgbevf_dev_stats_reset(eth_dev);
+
        /* Disable the interrupts for VF */
        ixgbevf_intr_disable(hw);
 
@@ -1761,24 +1857,16 @@ ixgbe_dev_close(struct rte_eth_dev *dev)
        ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
 }
 
-/*
- * This function is based on ixgbe_update_stats_counters() in base/ixgbe.c
- */
 static void
-ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+ixgbe_read_stats_registers(struct ixgbe_hw *hw, struct ixgbe_hw_stats
+                                                  *hw_stats, uint64_t *total_missed_rx,
+                                                  uint64_t *total_qbrc, uint64_t *total_qprc,
+                                                  uint64_t *rxnfgpc, uint64_t *txdgpc,
+                                                  uint64_t *total_qprdc)
 {
-       struct ixgbe_hw *hw =
-                       IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       struct ixgbe_hw_stats *hw_stats =
-                       IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
        uint32_t bprc, lxon, lxoff, total;
-       uint64_t total_missed_rx, total_qbrc, total_qprc;
        unsigned i;
 
-       total_missed_rx = 0;
-       total_qbrc = 0;
-       total_qprc = 0;
-
        hw_stats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
        hw_stats->illerrc += IXGBE_READ_REG(hw, IXGBE_ILLERRC);
        hw_stats->errbc += IXGBE_READ_REG(hw, IXGBE_ERRBC);
@@ -1790,7 +1878,7 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                /* global total per queue */
                hw_stats->mpc[i] += mp;
                /* Running comprehensive total for stats display */
-               total_missed_rx += hw_stats->mpc[i];
+               *total_missed_rx += hw_stats->mpc[i];
                if (hw->mac.type == ixgbe_mac_82598EB)
                        hw_stats->rnbc[i] +=
                            IXGBE_READ_REG(hw, IXGBE_RNBC(i));
@@ -1814,10 +1902,11 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                hw_stats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
                hw_stats->qbtc[i] +=
                    ((uint64_t)IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)) << 32);
-               hw_stats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+               *total_qprdc += hw_stats->qprdc[i] +=
+                               IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
 
-               total_qprc += hw_stats->qprc[i];
-               total_qbrc += hw_stats->qbrc[i];
+               *total_qprc += hw_stats->qprc[i];
+               *total_qbrc += hw_stats->qbrc[i];
        }
        hw_stats->mlfc += IXGBE_READ_REG(hw, IXGBE_MLFC);
        hw_stats->mrfc += IXGBE_READ_REG(hw, IXGBE_MRFC);
@@ -1825,6 +1914,8 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
        /* Note that gprc counts missed packets */
        hw_stats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
+       *rxnfgpc += IXGBE_READ_REG(hw, IXGBE_RXNFGPC);
+       *txdgpc += IXGBE_READ_REG(hw, IXGBE_TXDGPC);
 
        if (hw->mac.type != ixgbe_mac_82598EB) {
                hw_stats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
@@ -1902,6 +1993,35 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                hw_stats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
        }
 
+       /* Flow Director Stats registers */
+       hw_stats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+       hw_stats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+}
+
+/*
+ * This function is based on ixgbe_update_stats_counters() in ixgbe/ixgbe.c
+ */
+static void
+ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+       struct ixgbe_hw *hw =
+                       IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ixgbe_hw_stats *hw_stats =
+                       IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+       uint64_t total_missed_rx, total_qbrc, total_qprc, total_qprdc;
+       uint64_t rxnfgpc, txdgpc;
+       unsigned i;
+
+       total_missed_rx = 0;
+       total_qbrc = 0;
+       total_qprc = 0;
+       total_qprdc = 0;
+       rxnfgpc = 0;
+       txdgpc = 0;
+
+       ixgbe_read_stats_registers(hw, hw_stats, &total_missed_rx, &total_qbrc,
+                       &total_qprc, &rxnfgpc, &txdgpc, &total_qprdc);
+
        if (stats == NULL)
                return;
 
@@ -1910,7 +2030,6 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
        stats->ibytes = total_qbrc;
        stats->opackets = hw_stats->gptc;
        stats->obytes = hw_stats->gotc;
-       stats->imcasts = hw_stats->mprc;
 
        for (i = 0; i < IXGBE_QUEUE_STAT_COUNTERS; i++) {
                stats->q_ipackets[i] = hw_stats->qprc[i];
@@ -1921,28 +2040,26 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
        }
 
        /* Rx Errors */
-       stats->ibadcrc  = hw_stats->crcerrs;
-       stats->ibadlen  = hw_stats->rlec + hw_stats->ruc + hw_stats->roc;
-       stats->imissed  = total_missed_rx;
-       stats->ierrors  = stats->ibadcrc +
-                         stats->ibadlen +
-                         stats->imissed +
-                         hw_stats->illerrc + hw_stats->errbc;
+       stats->ierrors  = hw_stats->crcerrs +
+                         hw_stats->rlec +
+                         hw_stats->ruc +
+                         hw_stats->roc +
+                         total_missed_rx +
+                         hw_stats->illerrc +
+                         hw_stats->errbc +
+                         hw_stats->xec +
+                         hw_stats->mlfc +
+                         hw_stats->mrfc +
+                         hw_stats->rfc +
+                         hw_stats->rjc +
+                         hw_stats->fccrc +
+                         hw_stats->fclast +
+                         (rxnfgpc - hw_stats->gprc); /* PHY Errors*/
 
        /* Tx Errors */
-       stats->oerrors  = 0;
-
-       /* XON/XOFF pause frames */
-       stats->tx_pause_xon  = hw_stats->lxontxc;
-       stats->rx_pause_xon  = hw_stats->lxonrxc;
-       stats->tx_pause_xoff = hw_stats->lxofftxc;
-       stats->rx_pause_xoff = hw_stats->lxoffrxc;
-
-       /* Flow Director Stats registers */
-       hw_stats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
-       hw_stats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
-       stats->fdirmatch = hw_stats->fdirmatch;
-       stats->fdirmiss = hw_stats->fdirmiss;
+       /*txdgpc: packets that are DMA'ed*/
+       /*gptc: packets that are sent*/
+       stats->oerrors  = txdgpc - hw_stats->gptc;
 }
 
 static void
@@ -1958,6 +2075,61 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev)
        memset(stats, 0, sizeof(*stats));
 }
 
+static int
+ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+                                        unsigned n)
+{
+       struct ixgbe_hw *hw =
+                       IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ixgbe_hw_stats *hw_stats =
+                       IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+       uint64_t total_missed_rx, total_qbrc, total_qprc, total_qprdc;
+       uint64_t rxnfgpc, txdgpc;
+       unsigned i, count = IXGBE_NB_XSTATS;
+
+       if (n < count)
+               return count;
+
+       total_missed_rx = 0;
+       total_qbrc = 0;
+       total_qprc = 0;
+       total_qprdc = 0;
+       rxnfgpc = 0;
+       txdgpc = 0;
+
+       ixgbe_read_stats_registers(hw, hw_stats, &total_missed_rx, &total_qbrc,
+                                                          &total_qprc, &rxnfgpc, &txdgpc, &total_qprdc);
+
+       /* If this is a reset xstats is NULL, and we have cleared the
+        * registers by reading them.
+        */
+       if (!xstats)
+               return 0;
+
+       /* Extended stats */
+       for (i = 0; i < IXGBE_NB_XSTATS; i++) {
+               snprintf(xstats[i].name, sizeof(xstats[i].name),
+                               "%s", rte_ixgbe_stats_strings[i].name);
+               xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+                                                       rte_ixgbe_stats_strings[i].offset);
+       }
+
+       return count;
+}
+
+static void
+ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw_stats *stats =
+                       IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+       /* HW registers are cleared on read */
+       ixgbe_dev_xstats_get(dev, NULL, IXGBE_NB_XSTATS);
+
+       /* Reset software totals */
+       memset(stats, 0, sizeof(*stats));
+}
+
 static void
 ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -1993,6 +2165,7 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
        stats->opackets = hw_stats->vfgptc;
        stats->obytes = hw_stats->vfgotc;
        stats->imcasts = hw_stats->vfmprc;
+       /* stats->imcasts should be removed as imcasts is deprecated */
 }
 
 static void
@@ -2074,6 +2247,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
                                ETH_TXQ_FLAGS_NOOFFLOADS,
        };
+       dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
        dev_info->reta_size = ETH_RSS_RETA_SIZE_128;
        dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
@@ -2549,8 +2723,6 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        PMD_INIT_FUNC_TRACE();
 
        hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       if (fc_conf->autoneg != !hw->fc.disable_fc_autoneg)
-               return -ENOTSUP;
        rx_buf_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0));
        PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x", rx_buf_size);
 
@@ -2571,6 +2743,7 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        hw->fc.high_water[0]  = fc_conf->high_water;
        hw->fc.low_water[0]   = fc_conf->low_water;
        hw->fc.send_xon       = fc_conf->send_xon;
+       hw->fc.disable_fc_autoneg = !fc_conf->autoneg;
 
        err = ixgbe_fc_enable(hw);
 
@@ -2902,6 +3075,14 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
        ixgbe_clear_rar(hw, index);
 }
 
+static void
+ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+       ixgbe_remove_rar(dev, 0);
+
+       ixgbe_add_rar(dev, addr, 0, 0);
+}
+
 static int
 ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
@@ -3759,6 +3940,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
        }
 }
 
+static void
+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);
+}
+
 #define MAC_TYPE_FILTER_SUP(type)    do {\
        if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\
                (type) != ixgbe_mac_X550)\
@@ -4499,8 +4688,8 @@ ixgbe_dev_addr_list_itr(__attribute__((unused)) struct ixgbe_hw *hw,
 
 static int
 ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
-                          struct ether_addr *mc_addr_set,
-                          uint32_t nb_mc_addr)
+                         struct ether_addr *mc_addr_set,
+                         uint32_t nb_mc_addr)
 {
        struct ixgbe_hw *hw;
        u8 *mc_addr_list;
@@ -4511,6 +4700,238 @@ ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
                                         ixgbe_dev_addr_list_itr, TRUE);
 }
 
+static int
+ixgbe_timesync_enable(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t tsync_ctl;
+       uint32_t tsauxc;
+
+       /* Enable system time for platforms where it isn't on by default. */
+       tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
+       tsauxc &= ~IXGBE_TSAUXC_DISABLE_SYSTIME;
+       IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
+
+       /* Start incrementing the register used to timestamp PTP packets. */
+       IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, IXGBE_TIMINCA_INIT);
+
+       /* Enable L2 filtering of IEEE1588/802.1AS Ethernet frame types. */
+       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588),
+                       (ETHER_TYPE_1588 |
+                        IXGBE_ETQF_FILTER_EN |
+                        IXGBE_ETQF_1588));
+
+       /* Enable timestamping of received PTP packets. */
+       tsync_ctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+       tsync_ctl |= IXGBE_TSYNCRXCTL_ENABLED;
+       IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, tsync_ctl);
+
+       /* Enable timestamping of transmitted PTP packets. */
+       tsync_ctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
+       tsync_ctl |= IXGBE_TSYNCTXCTL_ENABLED;
+       IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, tsync_ctl);
+
+       return 0;
+}
+
+static int
+ixgbe_timesync_disable(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t tsync_ctl;
+
+       /* Disable timestamping of transmitted PTP packets. */
+       tsync_ctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
+       tsync_ctl &= ~IXGBE_TSYNCTXCTL_ENABLED;
+       IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, tsync_ctl);
+
+       /* Disable timestamping of received PTP packets. */
+       tsync_ctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+       tsync_ctl &= ~IXGBE_TSYNCRXCTL_ENABLED;
+       IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, tsync_ctl);
+
+       /* Disable L2 filtering of IEEE1588/802.1AS Ethernet frame types. */
+       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), 0);
+
+       /* Stop incrementating the System Time registers. */
+       IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, 0);
+
+       return 0;
+}
+
+static int
+ixgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+                                struct timespec *timestamp,
+                                uint32_t flags __rte_unused)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t tsync_rxctl;
+       uint32_t rx_stmpl;
+       uint32_t rx_stmph;
+
+       tsync_rxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+       if ((tsync_rxctl & IXGBE_TSYNCRXCTL_VALID) == 0)
+               return -EINVAL;
+
+       rx_stmpl = IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
+       rx_stmph = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
+
+       timestamp->tv_sec = (uint64_t)(((uint64_t)rx_stmph << 32) | rx_stmpl);
+       timestamp->tv_nsec = 0;
+
+       return  0;
+}
+
+static int
+ixgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+                                struct timespec *timestamp)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t tsync_txctl;
+       uint32_t tx_stmpl;
+       uint32_t tx_stmph;
+
+       tsync_txctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
+       if ((tsync_txctl & IXGBE_TSYNCTXCTL_VALID) == 0)
+               return -EINVAL;
+
+       tx_stmpl = IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
+       tx_stmph = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
+
+       timestamp->tv_sec = (uint64_t)(((uint64_t)tx_stmph << 32) | tx_stmpl);
+       timestamp->tv_nsec = 0;
+
+       return  0;
+}
+
+static int
+ixgbe_get_reg_length(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       int count = 0;
+       int g_ind = 0;
+       const struct reg_info *reg_group;
+       const struct reg_info **reg_set = (hw->mac.type == ixgbe_mac_82598EB) ?
+                                   ixgbe_regs_mac_82598EB : ixgbe_regs_others;
+
+       while ((reg_group = reg_set[g_ind++]))
+               count += ixgbe_regs_group_count(reg_group);
+
+       return count;
+}
+
+static int
+ixgbevf_get_reg_length(struct rte_eth_dev *dev __rte_unused)
+{
+       int count = 0;
+       int g_ind = 0;
+       const struct reg_info *reg_group;
+
+       while ((reg_group = ixgbevf_regs[g_ind++]))
+               count += ixgbe_regs_group_count(reg_group);
+
+       return count;
+}
+
+static int
+ixgbe_get_regs(struct rte_eth_dev *dev,
+             struct rte_dev_reg_info *regs)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t *data = regs->data;
+       int g_ind = 0;
+       int count = 0;
+       const struct reg_info *reg_group;
+       const struct reg_info **reg_set = (hw->mac.type == ixgbe_mac_82598EB) ?
+                                   ixgbe_regs_mac_82598EB : ixgbe_regs_others;
+
+       /* Support only full register dump */
+       if ((regs->length == 0) ||
+           (regs->length == (uint32_t)ixgbe_get_reg_length(dev))) {
+               regs->version = hw->mac.type << 24 | hw->revision_id << 16 |
+                       hw->device_id;
+               while ((reg_group = reg_set[g_ind++]))
+                       count += ixgbe_read_regs_group(dev, &data[count],
+                               reg_group);
+               return 0;
+       }
+
+       return -ENOTSUP;
+}
+
+static int
+ixgbevf_get_regs(struct rte_eth_dev *dev,
+               struct rte_dev_reg_info *regs)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t *data = regs->data;
+       int g_ind = 0;
+       int count = 0;
+       const struct reg_info *reg_group;
+
+       /* Support only full register dump */
+       if ((regs->length == 0) ||
+           (regs->length == (uint32_t)ixgbevf_get_reg_length(dev))) {
+               regs->version = hw->mac.type << 24 | hw->revision_id << 16 |
+                       hw->device_id;
+               while ((reg_group = ixgbevf_regs[g_ind++]))
+                       count += ixgbe_read_regs_group(dev, &data[count],
+                                                     reg_group);
+               return 0;
+       }
+
+       return -ENOTSUP;
+}
+
+static int
+ixgbe_get_eeprom_length(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       /* Return unit is byte count */
+       return hw->eeprom.word_size * 2;
+}
+
+static int
+ixgbe_get_eeprom(struct rte_eth_dev *dev,
+               struct rte_dev_eeprom_info *in_eeprom)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+       uint16_t *data = in_eeprom->data;
+       int first, length;
+
+       first = in_eeprom->offset >> 1;
+       length = in_eeprom->length >> 1;
+       if ((first >= hw->eeprom.word_size) ||
+           ((first + length) >= hw->eeprom.word_size))
+               return -EINVAL;
+
+       in_eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+       return eeprom->ops.read_buffer(hw, first, length, data);
+}
+
+static int
+ixgbe_set_eeprom(struct rte_eth_dev *dev,
+               struct rte_dev_eeprom_info *in_eeprom)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+       uint16_t *data = in_eeprom->data;
+       int first, length;
+
+       first = in_eeprom->offset >> 1;
+       length = in_eeprom->length >> 1;
+       if ((first >= hw->eeprom.word_size) ||
+           ((first + length) >= hw->eeprom.word_size))
+               return -EINVAL;
+
+       in_eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+       return eeprom->ops.write_buffer(hw,  first, length, data);
+}
+
 static struct rte_driver rte_ixgbe_driver = {
        .type = PMD_PDEV,
        .init = rte_ixgbe_pmd_init,