diff options
author | Junchang Wang <junchangwang@gmail.com> | 2012-03-04 17:30:32 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2012-03-05 18:23:51 -0500 |
commit | 8027aa245bbd125350f6a78c5a78771d143aba55 (patch) | |
tree | a07f292d4f13b18a7c86a2c7aed0cf96f333cee5 /drivers/net/ethernet/realtek/r8169.c | |
parent | 18f973af3e7028620186d1c1ace044506bb6229e (diff) |
r8169: add 64bit statistics.
Switch to use ndo_get_stats64 to get 64bit statistics.
Two sync entries are used (one for Rx and one for Tx).
Signed-off-by: Junchang Wang <junchangwang@gmail.com>
Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net/ethernet/realtek/r8169.c')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index fbd855bcd9f0..a4d7674886a2 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -675,6 +675,12 @@ enum rtl_flag { | |||
675 | RTL_FLAG_MAX | 675 | RTL_FLAG_MAX |
676 | }; | 676 | }; |
677 | 677 | ||
678 | struct rtl8169_stats { | ||
679 | u64 packets; | ||
680 | u64 bytes; | ||
681 | struct u64_stats_sync syncp; | ||
682 | }; | ||
683 | |||
678 | struct rtl8169_private { | 684 | struct rtl8169_private { |
679 | void __iomem *mmio_addr; /* memory map physical address */ | 685 | void __iomem *mmio_addr; /* memory map physical address */ |
680 | struct pci_dev *pci_dev; | 686 | struct pci_dev *pci_dev; |
@@ -687,6 +693,8 @@ struct rtl8169_private { | |||
687 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ | 693 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ |
688 | u32 dirty_rx; | 694 | u32 dirty_rx; |
689 | u32 dirty_tx; | 695 | u32 dirty_tx; |
696 | struct rtl8169_stats rx_stats; | ||
697 | struct rtl8169_stats tx_stats; | ||
690 | struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ | 698 | struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ |
691 | struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ | 699 | struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ |
692 | dma_addr_t TxPhyAddr; | 700 | dma_addr_t TxPhyAddr; |
@@ -775,7 +783,9 @@ static void rtl_hw_start(struct net_device *dev); | |||
775 | static int rtl8169_close(struct net_device *dev); | 783 | static int rtl8169_close(struct net_device *dev); |
776 | static void rtl_set_rx_mode(struct net_device *dev); | 784 | static void rtl_set_rx_mode(struct net_device *dev); |
777 | static void rtl8169_tx_timeout(struct net_device *dev); | 785 | static void rtl8169_tx_timeout(struct net_device *dev); |
778 | static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); | 786 | static struct rtnl_link_stats64 *rtl8169_get_stats64(struct net_device *dev, |
787 | struct rtnl_link_stats64 | ||
788 | *stats); | ||
779 | static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); | 789 | static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); |
780 | static void rtl8169_rx_clear(struct rtl8169_private *tp); | 790 | static void rtl8169_rx_clear(struct rtl8169_private *tp); |
781 | static int rtl8169_poll(struct napi_struct *napi, int budget); | 791 | static int rtl8169_poll(struct napi_struct *napi, int budget); |
@@ -3521,7 +3531,7 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp) | |||
3521 | static const struct net_device_ops rtl8169_netdev_ops = { | 3531 | static const struct net_device_ops rtl8169_netdev_ops = { |
3522 | .ndo_open = rtl8169_open, | 3532 | .ndo_open = rtl8169_open, |
3523 | .ndo_stop = rtl8169_close, | 3533 | .ndo_stop = rtl8169_close, |
3524 | .ndo_get_stats = rtl8169_get_stats, | 3534 | .ndo_get_stats64 = rtl8169_get_stats64, |
3525 | .ndo_start_xmit = rtl8169_start_xmit, | 3535 | .ndo_start_xmit = rtl8169_start_xmit, |
3526 | .ndo_tx_timeout = rtl8169_tx_timeout, | 3536 | .ndo_tx_timeout = rtl8169_tx_timeout, |
3527 | .ndo_validate_addr = eth_validate_addr, | 3537 | .ndo_validate_addr = eth_validate_addr, |
@@ -5658,8 +5668,10 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) | |||
5658 | rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, | 5668 | rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, |
5659 | tp->TxDescArray + entry); | 5669 | tp->TxDescArray + entry); |
5660 | if (status & LastFrag) { | 5670 | if (status & LastFrag) { |
5661 | dev->stats.tx_packets++; | 5671 | u64_stats_update_begin(&tp->tx_stats.syncp); |
5662 | dev->stats.tx_bytes += tx_skb->skb->len; | 5672 | tp->tx_stats.packets++; |
5673 | tp->tx_stats.bytes += tx_skb->skb->len; | ||
5674 | u64_stats_update_end(&tp->tx_stats.syncp); | ||
5663 | dev_kfree_skb(tx_skb->skb); | 5675 | dev_kfree_skb(tx_skb->skb); |
5664 | tx_skb->skb = NULL; | 5676 | tx_skb->skb = NULL; |
5665 | } | 5677 | } |
@@ -5807,8 +5819,10 @@ process_pkt: | |||
5807 | 5819 | ||
5808 | napi_gro_receive(&tp->napi, skb); | 5820 | napi_gro_receive(&tp->napi, skb); |
5809 | 5821 | ||
5810 | dev->stats.rx_bytes += pkt_size; | 5822 | u64_stats_update_begin(&tp->rx_stats.syncp); |
5811 | dev->stats.rx_packets++; | 5823 | tp->rx_stats.packets++; |
5824 | tp->rx_stats.bytes += pkt_size; | ||
5825 | u64_stats_update_end(&tp->rx_stats.syncp); | ||
5812 | } | 5826 | } |
5813 | 5827 | ||
5814 | /* Work around for AMD plateform. */ | 5828 | /* Work around for AMD plateform. */ |
@@ -6069,21 +6083,38 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
6069 | RTL_W32(RxConfig, tmp); | 6083 | RTL_W32(RxConfig, tmp); |
6070 | } | 6084 | } |
6071 | 6085 | ||
6072 | /** | 6086 | static struct rtnl_link_stats64 * |
6073 | * rtl8169_get_stats - Get rtl8169 read/write statistics | 6087 | rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) |
6074 | * @dev: The Ethernet Device to get statistics for | ||
6075 | * | ||
6076 | * Get TX/RX statistics for rtl8169 | ||
6077 | */ | ||
6078 | static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) | ||
6079 | { | 6088 | { |
6080 | struct rtl8169_private *tp = netdev_priv(dev); | 6089 | struct rtl8169_private *tp = netdev_priv(dev); |
6081 | void __iomem *ioaddr = tp->mmio_addr; | 6090 | void __iomem *ioaddr = tp->mmio_addr; |
6091 | unsigned int start; | ||
6082 | 6092 | ||
6083 | if (netif_running(dev)) | 6093 | if (netif_running(dev)) |
6084 | rtl8169_rx_missed(dev, ioaddr); | 6094 | rtl8169_rx_missed(dev, ioaddr); |
6085 | 6095 | ||
6086 | return &dev->stats; | 6096 | do { |
6097 | start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp); | ||
6098 | stats->rx_packets = tp->rx_stats.packets; | ||
6099 | stats->rx_bytes = tp->rx_stats.bytes; | ||
6100 | } while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start)); | ||
6101 | |||
6102 | |||
6103 | do { | ||
6104 | start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp); | ||
6105 | stats->tx_packets = tp->tx_stats.packets; | ||
6106 | stats->tx_bytes = tp->tx_stats.bytes; | ||
6107 | } while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start)); | ||
6108 | |||
6109 | stats->rx_dropped = dev->stats.rx_dropped; | ||
6110 | stats->tx_dropped = dev->stats.tx_dropped; | ||
6111 | stats->rx_length_errors = dev->stats.rx_length_errors; | ||
6112 | stats->rx_errors = dev->stats.rx_errors; | ||
6113 | stats->rx_crc_errors = dev->stats.rx_crc_errors; | ||
6114 | stats->rx_fifo_errors = dev->stats.rx_fifo_errors; | ||
6115 | stats->rx_missed_errors = dev->stats.rx_missed_errors; | ||
6116 | |||
6117 | return stats; | ||
6087 | } | 6118 | } |
6088 | 6119 | ||
6089 | static void rtl8169_net_suspend(struct net_device *dev) | 6120 | static void rtl8169_net_suspend(struct net_device *dev) |