alx: add alx_get_stats64 operation
authorSabrina Dubroca <sd@queasysnail.net>
Thu, 9 Jan 2014 09:09:30 +0000 (10:09 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 12 Jan 2014 04:52:58 +0000 (20:52 -0800)
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/atheros/alx/alx.h
drivers/net/ethernet/atheros/alx/main.c

index d71103d..8fc93c5 100644 (file)
@@ -106,6 +106,9 @@ struct alx_priv {
        u16 msg_enable;
 
        bool msi;
+
+       /* protects hw.stats */
+       spinlock_t stats_lock;
 };
 
 extern const struct ethtool_ops alx_ethtool_ops;
index c3c4c26..e92ffd6 100644 (file)
@@ -1166,10 +1166,60 @@ static void alx_poll_controller(struct net_device *netdev)
 }
 #endif
 
+static struct rtnl_link_stats64 *alx_get_stats64(struct net_device *dev,
+                                       struct rtnl_link_stats64 *net_stats)
+{
+       struct alx_priv *alx = netdev_priv(dev);
+       struct alx_hw_stats *hw_stats = &alx->hw.stats;
+
+       spin_lock(&alx->stats_lock);
+
+       alx_update_hw_stats(&alx->hw);
+
+       net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
+       net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
+       net_stats->multicast  = hw_stats->rx_mcast;
+       net_stats->collisions = hw_stats->tx_single_col +
+                               hw_stats->tx_multi_col +
+                               hw_stats->tx_late_col +
+                               hw_stats->tx_abort_col;
+
+       net_stats->rx_errors  = hw_stats->rx_frag +
+                               hw_stats->rx_fcs_err +
+                               hw_stats->rx_len_err +
+                               hw_stats->rx_ov_sz +
+                               hw_stats->rx_ov_rrd +
+                               hw_stats->rx_align_err +
+                               hw_stats->rx_ov_rxf;
+
+       net_stats->rx_fifo_errors   = hw_stats->rx_ov_rxf;
+       net_stats->rx_length_errors = hw_stats->rx_len_err;
+       net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
+       net_stats->rx_frame_errors  = hw_stats->rx_align_err;
+       net_stats->rx_dropped       = hw_stats->rx_ov_rrd;
+
+       net_stats->tx_errors = hw_stats->tx_late_col +
+                              hw_stats->tx_abort_col +
+                              hw_stats->tx_underrun +
+                              hw_stats->tx_trunc;
+
+       net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+       net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
+       net_stats->tx_window_errors  = hw_stats->tx_late_col;
+
+       net_stats->tx_packets = hw_stats->tx_ok + net_stats->tx_errors;
+       net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors;
+
+       spin_unlock(&alx->stats_lock);
+
+       return net_stats;
+}
+
 static const struct net_device_ops alx_netdev_ops = {
        .ndo_open               = alx_open,
        .ndo_stop               = alx_stop,
        .ndo_start_xmit         = alx_start_xmit,
+       .ndo_get_stats64        = alx_get_stats64,
        .ndo_set_rx_mode        = alx_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = alx_set_mac_address,