Commit 9184a227 authored by Junchang Wang's avatar Junchang Wang Committed by David S. Miller
Browse files

8139too: 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>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f6a1ad42
Loading
Loading
Loading
Loading
+38 −8
Original line number Diff line number Diff line
@@ -565,6 +565,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;
@@ -575,11 +581,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;
@@ -641,7 +649,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);
@@ -937,7 +947,7 @@ static int rtl8139_set_features(struct net_device *dev, netdev_features_t featur
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,
@@ -1807,8 +1817,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++;
@@ -2050,8 +2062,10 @@ keep_pkt:

			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 {
@@ -2515,11 +2529,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);
@@ -2528,7 +2544,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.