]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
8139too: Add 64bit statistics
authorJunchang Wang <junchangwang@gmail.com>
Mon, 5 Mar 2012 17:13:05 +0000 (17:13 +0000)
committerJoe Jin <joe.jin@oracle.com>
Fri, 18 May 2012 03:41:23 +0000 (11:41 +0800)
Switch to use ndo_get_stats64 to get 64bit statistics.
Two sync entries are used (one for Rx and one for Tx).

(cherry picked from commit 9184a22701ed257974e7950be11da4cbd3116c63)
Signed-off-by: Junchang Wang <junchangwang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/8139too.c

index 33b577a577c02734806eeae70a1169d0e81347da..415ff15266166a8876fe30590175930f6edb6f6a 100644 (file)
@@ -564,6 +564,12 @@ struct rtl_extra_stats {
        unsigned long rx_lost_in_ring;
 };
 
+struct rtl8139_stats {
+       u64     packets;
+       u64     bytes;
+       struct u64_stats_sync   syncp;
+};
+
 struct rtl8139_private {
        void __iomem            *mmio_addr;
        int                     drv_flags;
@@ -574,11 +580,13 @@ struct rtl8139_private {
 
        unsigned char           *rx_ring;
        unsigned int            cur_rx; /* RX buf index of next pkt */
+       struct rtl8139_stats    rx_stats;
        dma_addr_t              rx_ring_dma;
 
        unsigned int            tx_flag;
        unsigned long           cur_tx;
        unsigned long           dirty_tx;
+       struct rtl8139_stats    tx_stats;
        unsigned char           *tx_buf[NUM_TX_DESC];   /* Tx bounce buffers */
        unsigned char           *tx_bufs;       /* Tx bounce buffer region. */
        dma_addr_t              tx_bufs_dma;
@@ -640,7 +648,9 @@ static int rtl8139_poll(struct napi_struct *napi, int budget);
 static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
 static int rtl8139_close (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
-static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
+static struct rtnl_link_stats64 *rtl8139_get_stats64(struct net_device *dev,
+                                                   struct rtnl_link_stats64
+                                                   *stats);
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
@@ -910,7 +920,7 @@ err_out:
 static const struct net_device_ops rtl8139_netdev_ops = {
        .ndo_open               = rtl8139_open,
        .ndo_stop               = rtl8139_close,
-       .ndo_get_stats          = rtl8139_get_stats,
+       .ndo_get_stats64        = rtl8139_get_stats64,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = rtl8139_set_mac_address,
@@ -1776,8 +1786,10 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
                                dev->stats.tx_fifo_errors++;
                        }
                        dev->stats.collisions += (txstatus >> 24) & 15;
-                       dev->stats.tx_bytes += txstatus & 0x7ff;
-                       dev->stats.tx_packets++;
+                       u64_stats_update_begin(&tp->tx_stats.syncp);
+                       tp->tx_stats.packets++;
+                       tp->tx_stats.bytes += txstatus & 0x7ff;
+                       u64_stats_update_end(&tp->tx_stats.syncp);
                }
 
                dirty_tx++;
@@ -1997,8 +2009,10 @@ no_early_rx:
 
                        skb->protocol = eth_type_trans (skb, dev);
 
-                       dev->stats.rx_bytes += pkt_size;
-                       dev->stats.rx_packets++;
+                       u64_stats_update_begin(&tp->rx_stats.syncp);
+                       tp->rx_stats.packets++;
+                       tp->rx_stats.bytes += pkt_size;
+                       u64_stats_update_end(&tp->rx_stats.syncp);
 
                        netif_receive_skb (skb);
                } else {
@@ -2462,11 +2476,13 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 }
 
 
-static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
+static struct rtnl_link_stats64 *
+rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
        struct rtl8139_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned long flags;
+       unsigned int start;
 
        if (netif_running(dev)) {
                spin_lock_irqsave (&tp->lock, flags);
@@ -2475,7 +2491,21 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
                spin_unlock_irqrestore (&tp->lock, flags);
        }
 
-       return &dev->stats;
+       netdev_stats_to_stats64(stats, &dev->stats);
+
+       do {
+               start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp);
+               stats->rx_packets = tp->rx_stats.packets;
+               stats->rx_bytes = tp->rx_stats.bytes;
+       } while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start));
+
+       do {
+               start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp);
+               stats->tx_packets = tp->tx_stats.packets;
+               stats->tx_bytes = tp->tx_stats.bytes;
+       } while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start));
+
+       return stats;
 }
 
 /* Set or clear the multicast filter for this adaptor.