Commit 8027aa24 authored by Junchang Wang's avatar Junchang Wang Committed by Francois Romieu

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: default avatarJunchang Wang <junchangwang@gmail.com>
Reviewed-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarFrancois Romieu <romieu@fr.zoreil.com>
parent 18f973af
...@@ -675,6 +675,12 @@ enum rtl_flag { ...@@ -675,6 +675,12 @@ enum rtl_flag {
RTL_FLAG_MAX RTL_FLAG_MAX
}; };
struct rtl8169_stats {
u64 packets;
u64 bytes;
struct u64_stats_sync syncp;
};
struct rtl8169_private { struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */ void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
...@@ -687,6 +693,8 @@ struct rtl8169_private { ...@@ -687,6 +693,8 @@ struct rtl8169_private {
u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
u32 dirty_rx; u32 dirty_rx;
u32 dirty_tx; u32 dirty_tx;
struct rtl8169_stats rx_stats;
struct rtl8169_stats tx_stats;
struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */
dma_addr_t TxPhyAddr; dma_addr_t TxPhyAddr;
...@@ -775,7 +783,9 @@ static void rtl_hw_start(struct net_device *dev); ...@@ -775,7 +783,9 @@ static void rtl_hw_start(struct net_device *dev);
static int rtl8169_close(struct net_device *dev); static int rtl8169_close(struct net_device *dev);
static void rtl_set_rx_mode(struct net_device *dev); static void rtl_set_rx_mode(struct net_device *dev);
static void rtl8169_tx_timeout(struct net_device *dev); static void rtl8169_tx_timeout(struct net_device *dev);
static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); static struct rtnl_link_stats64 *rtl8169_get_stats64(struct net_device *dev,
struct rtnl_link_stats64
*stats);
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8169_rx_clear(struct rtl8169_private *tp); static void rtl8169_rx_clear(struct rtl8169_private *tp);
static int rtl8169_poll(struct napi_struct *napi, int budget); 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,7 +3531,7 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
static const struct net_device_ops rtl8169_netdev_ops = { static const struct net_device_ops rtl8169_netdev_ops = {
.ndo_open = rtl8169_open, .ndo_open = rtl8169_open,
.ndo_stop = rtl8169_close, .ndo_stop = rtl8169_close,
.ndo_get_stats = rtl8169_get_stats, .ndo_get_stats64 = rtl8169_get_stats64,
.ndo_start_xmit = rtl8169_start_xmit, .ndo_start_xmit = rtl8169_start_xmit,
.ndo_tx_timeout = rtl8169_tx_timeout, .ndo_tx_timeout = rtl8169_tx_timeout,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
...@@ -5658,8 +5668,10 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) ...@@ -5658,8 +5668,10 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry); tp->TxDescArray + entry);
if (status & LastFrag) { if (status & LastFrag) {
dev->stats.tx_packets++; u64_stats_update_begin(&tp->tx_stats.syncp);
dev->stats.tx_bytes += tx_skb->skb->len; tp->tx_stats.packets++;
tp->tx_stats.bytes += tx_skb->skb->len;
u64_stats_update_end(&tp->tx_stats.syncp);
dev_kfree_skb(tx_skb->skb); dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL; tx_skb->skb = NULL;
} }
...@@ -5807,8 +5819,10 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget ...@@ -5807,8 +5819,10 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget
napi_gro_receive(&tp->napi, skb); napi_gro_receive(&tp->napi, skb);
dev->stats.rx_bytes += pkt_size; u64_stats_update_begin(&tp->rx_stats.syncp);
dev->stats.rx_packets++; tp->rx_stats.packets++;
tp->rx_stats.bytes += pkt_size;
u64_stats_update_end(&tp->rx_stats.syncp);
} }
/* Work around for AMD plateform. */ /* Work around for AMD plateform. */
...@@ -6069,21 +6083,38 @@ static void rtl_set_rx_mode(struct net_device *dev) ...@@ -6069,21 +6083,38 @@ static void rtl_set_rx_mode(struct net_device *dev)
RTL_W32(RxConfig, tmp); RTL_W32(RxConfig, tmp);
} }
/** static struct rtnl_link_stats64 *
* rtl8169_get_stats - Get rtl8169 read/write statistics rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
* @dev: The Ethernet Device to get statistics for
*
* Get TX/RX statistics for rtl8169
*/
static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
{ {
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
unsigned int start;
if (netif_running(dev)) if (netif_running(dev))
rtl8169_rx_missed(dev, ioaddr); rtl8169_rx_missed(dev, ioaddr);
return &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));
stats->rx_dropped = dev->stats.rx_dropped;
stats->tx_dropped = dev->stats.tx_dropped;
stats->rx_length_errors = dev->stats.rx_length_errors;
stats->rx_errors = dev->stats.rx_errors;
stats->rx_crc_errors = dev->stats.rx_crc_errors;
stats->rx_fifo_errors = dev->stats.rx_fifo_errors;
stats->rx_missed_errors = dev->stats.rx_missed_errors;
return stats;
} }
static void rtl8169_net_suspend(struct net_device *dev) static void rtl8169_net_suspend(struct net_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment