#define IXGBE_ALL_RAR_ENTRIES 16
 
+enum {NETDEV_STATS, IXGBEVF_STATS};
+
 struct ixgbe_stats {
        char stat_string[ETH_GSTRING_LEN];
-       struct {
-               int sizeof_stat;
-               int stat_offset;
-               int base_stat_offset;
-               int saved_reset_offset;
-       };
+       int type;
+       int sizeof_stat;
+       int stat_offset;
 };
 
-#define IXGBEVF_STAT(m, b, r) { \
-       .sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, m), \
-       .stat_offset = offsetof(struct ixgbevf_adapter, m), \
-       .base_stat_offset = offsetof(struct ixgbevf_adapter, b), \
-       .saved_reset_offset = offsetof(struct ixgbevf_adapter, r) \
+#define IXGBEVF_STAT(_name, _stat) { \
+       .stat_string = _name, \
+       .type = IXGBEVF_STATS, \
+       .sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, _stat), \
+       .stat_offset = offsetof(struct ixgbevf_adapter, _stat) \
 }
 
-#define IXGBEVF_ZSTAT(m) { \
-       .sizeof_stat = FIELD_SIZEOF(struct ixgbevf_adapter, m), \
-       .stat_offset = offsetof(struct ixgbevf_adapter, m), \
-       .base_stat_offset = -1, \
-       .saved_reset_offset = -1 \
+#define IXGBEVF_NETDEV_STAT(_net_stat) { \
+       .stat_string = #_net_stat, \
+       .type = NETDEV_STATS, \
+       .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
+       .stat_offset = offsetof(struct net_device_stats, _net_stat) \
 }
 
-static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
-       {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc,
-                                   stats.saved_reset_vfgprc)},
-       {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc,
-                                   stats.saved_reset_vfgptc)},
-       {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc,
-                                 stats.saved_reset_vfgorc)},
-       {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc,
-                                 stats.saved_reset_vfgotc)},
-       {"tx_busy", IXGBEVF_ZSTAT(tx_busy)},
-       {"tx_restart_queue", IXGBEVF_ZSTAT(restart_queue)},
-       {"tx_timeout_count", IXGBEVF_ZSTAT(tx_timeout_count)},
-       {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc,
-                                  stats.saved_reset_vfmprc)},
-       {"rx_csum_offload_errors", IXGBEVF_ZSTAT(hw_csum_rx_error)},
+static struct ixgbe_stats ixgbevf_gstrings_stats[] = {
+       IXGBEVF_NETDEV_STAT(rx_packets),
+       IXGBEVF_NETDEV_STAT(tx_packets),
+       IXGBEVF_NETDEV_STAT(rx_bytes),
+       IXGBEVF_NETDEV_STAT(tx_bytes),
+       IXGBEVF_STAT("tx_busy", tx_busy),
+       IXGBEVF_STAT("tx_restart_queue", restart_queue),
+       IXGBEVF_STAT("tx_timeout_count", tx_timeout_count),
+       IXGBEVF_NETDEV_STAT(multicast),
+       IXGBEVF_STAT("rx_csum_offload_errors", hw_csum_rx_error),
 #ifdef BP_EXTENDED_STATS
-       {"rx_bp_poll_yield", IXGBEVF_ZSTAT(bp_rx_yields)},
-       {"rx_bp_cleaned", IXGBEVF_ZSTAT(bp_rx_cleaned)},
-       {"rx_bp_misses", IXGBEVF_ZSTAT(bp_rx_missed)},
-       {"tx_bp_napi_yield", IXGBEVF_ZSTAT(bp_tx_yields)},
-       {"tx_bp_cleaned", IXGBEVF_ZSTAT(bp_tx_cleaned)},
-       {"tx_bp_misses", IXGBEVF_ZSTAT(bp_tx_missed)},
+       IXGBEVF_STAT("rx_bp_poll_yield", bp_rx_yields),
+       IXGBEVF_STAT("rx_bp_cleaned", bp_rx_cleaned),
+       IXGBEVF_STAT("rx_bp_misses", bp_rx_missed),
+       IXGBEVF_STAT("tx_bp_napi_yield", bp_tx_yields),
+       IXGBEVF_STAT("tx_bp_cleaned", bp_tx_cleaned),
+       IXGBEVF_STAT("tx_bp_misses", bp_tx_missed),
 #endif
 };
 
-#define IXGBE_QUEUE_STATS_LEN 0
-#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
+#define IXGBEVF_QUEUE_STATS_LEN ( \
+       (((struct ixgbevf_adapter *)netdev_priv(netdev))->num_tx_queues + \
+        ((struct ixgbevf_adapter *)netdev_priv(netdev))->num_rx_queues) * \
+        (sizeof(struct ixgbe_stats) / sizeof(u64)))
+#define IXGBEVF_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbevf_gstrings_stats)
 
-#define IXGBEVF_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
+#define IXGBEVF_STATS_LEN (IXGBEVF_GLOBAL_STATS_LEN + IXGBEVF_QUEUE_STATS_LEN)
 static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
        "Register test  (offline)",
        "Link test   (on/offline)"
 };
 
-#define IXGBE_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
+#define IXGBEVF_TEST_LEN (sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN)
 
 static int ixgbevf_get_settings(struct net_device *netdev,
                                struct ethtool_cmd *ecmd)
 {
        switch (stringset) {
        case ETH_SS_TEST:
-               return IXGBE_TEST_LEN;
+               return IXGBEVF_TEST_LEN;
        case ETH_SS_STATS:
-               return IXGBE_GLOBAL_STATS_LEN;
+               return IXGBEVF_GLOBAL_STATS_LEN;
        default:
                return -EINVAL;
        }
                                      struct ethtool_stats *stats, u64 *data)
 {
        struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-       char *base = (char *)adapter;
+       struct rtnl_link_stats64 temp;
+       const struct rtnl_link_stats64 *net_stats;
        int i;
+       char *p;
+
 #ifdef BP_EXTENDED_STATS
        u64 rx_yields = 0, rx_cleaned = 0, rx_missed = 0,
            tx_yields = 0, tx_cleaned = 0, tx_missed = 0;
 #endif
 
        ixgbevf_update_stats(adapter);
-       for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
-               char *p = base + ixgbe_gstrings_stats[i].stat_offset;
-               char *b = base + ixgbe_gstrings_stats[i].base_stat_offset;
-               char *r = base + ixgbe_gstrings_stats[i].saved_reset_offset;
-
-               if (ixgbe_gstrings_stats[i].sizeof_stat == sizeof(u64)) {
-                       if (ixgbe_gstrings_stats[i].base_stat_offset >= 0)
-                               data[i] = *(u64 *)p - *(u64 *)b + *(u64 *)r;
-                       else
-                               data[i] = *(u64 *)p;
-               } else {
-                       if (ixgbe_gstrings_stats[i].base_stat_offset >= 0)
-                               data[i] = *(u32 *)p - *(u32 *)b + *(u32 *)r;
-                       else
-                               data[i] = *(u32 *)p;
+       net_stats = dev_get_stats(netdev, &temp);
+       for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) {
+               switch (ixgbevf_gstrings_stats[i].type) {
+               case NETDEV_STATS:
+                       p = (char *)net_stats +
+                                       ixgbevf_gstrings_stats[i].stat_offset;
+                       break;
+               case IXGBEVF_STATS:
+                       p = (char *)adapter +
+                                       ixgbevf_gstrings_stats[i].stat_offset;
+                       break;
+               default:
+                       data[i] = 0;
+                       continue;
                }
+
+               data[i] = (ixgbevf_gstrings_stats[i].sizeof_stat ==
+                          sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
        }
 }
 
        switch (stringset) {
        case ETH_SS_TEST:
                memcpy(data, *ixgbe_gstrings_test,
-                      IXGBE_TEST_LEN * ETH_GSTRING_LEN);
+                      IXGBEVF_TEST_LEN * ETH_GSTRING_LEN);
                break;
        case ETH_SS_STATS:
-               for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
-                       memcpy(p, ixgbe_gstrings_stats[i].stat_string,
+               for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) {
+                       memcpy(p, ixgbevf_gstrings_stats[i].stat_string,
                               ETH_GSTRING_LEN);
                        p += ETH_GSTRING_LEN;
                }