aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Groeneveld <kgroeneveld@gmail.com>2012-07-17 13:46:01 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-18 12:29:43 -0400
commiteeda8585522bcc173f91d6254dfa63e871087c54 (patch)
treeeb8c990517cd5df69e2915828d42f25933fb36a2
parent2e177a5c6cc52d8a422c69ba87b8a7e00ecb6eac (diff)
b44: add 64 bit stats
Add support for 64 bit stats to Broadcom b44 ethernet driver. Signed-off-by: Kevin Groeneveld <kgroeneveld@gmail.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/b44.c96
-rw-r--r--drivers/net/ethernet/broadcom/b44.h3
2 files changed, 58 insertions, 41 deletions
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index d09c6b583d17..9786c0e9890e 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -483,9 +483,11 @@ out:
483static void b44_stats_update(struct b44 *bp) 483static void b44_stats_update(struct b44 *bp)
484{ 484{
485 unsigned long reg; 485 unsigned long reg;
486 u32 *val; 486 u64 *val;
487 487
488 val = &bp->hw_stats.tx_good_octets; 488 val = &bp->hw_stats.tx_good_octets;
489 u64_stats_update_begin(&bp->hw_stats.syncp);
490
489 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { 491 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
490 *val++ += br32(bp, reg); 492 *val++ += br32(bp, reg);
491 } 493 }
@@ -496,6 +498,8 @@ static void b44_stats_update(struct b44 *bp)
496 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { 498 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
497 *val++ += br32(bp, reg); 499 *val++ += br32(bp, reg);
498 } 500 }
501
502 u64_stats_update_end(&bp->hw_stats.syncp);
499} 503}
500 504
501static void b44_link_report(struct b44 *bp) 505static void b44_link_report(struct b44 *bp)
@@ -1635,44 +1639,49 @@ static int b44_close(struct net_device *dev)
1635 return 0; 1639 return 0;
1636} 1640}
1637 1641
1638static struct net_device_stats *b44_get_stats(struct net_device *dev) 1642static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev,
1643 struct rtnl_link_stats64 *nstat)
1639{ 1644{
1640 struct b44 *bp = netdev_priv(dev); 1645 struct b44 *bp = netdev_priv(dev);
1641 struct net_device_stats *nstat = &dev->stats;
1642 struct b44_hw_stats *hwstat = &bp->hw_stats; 1646 struct b44_hw_stats *hwstat = &bp->hw_stats;
1643 1647 unsigned int start;
1644 /* Convert HW stats into netdevice stats. */ 1648
1645 nstat->rx_packets = hwstat->rx_pkts; 1649 do {
1646 nstat->tx_packets = hwstat->tx_pkts; 1650 start = u64_stats_fetch_begin_bh(&hwstat->syncp);
1647 nstat->rx_bytes = hwstat->rx_octets; 1651
1648 nstat->tx_bytes = hwstat->tx_octets; 1652 /* Convert HW stats into rtnl_link_stats64 stats. */
1649 nstat->tx_errors = (hwstat->tx_jabber_pkts + 1653 nstat->rx_packets = hwstat->rx_pkts;
1650 hwstat->tx_oversize_pkts + 1654 nstat->tx_packets = hwstat->tx_pkts;
1651 hwstat->tx_underruns + 1655 nstat->rx_bytes = hwstat->rx_octets;
1652 hwstat->tx_excessive_cols + 1656 nstat->tx_bytes = hwstat->tx_octets;
1653 hwstat->tx_late_cols); 1657 nstat->tx_errors = (hwstat->tx_jabber_pkts +
1654 nstat->multicast = hwstat->tx_multicast_pkts; 1658 hwstat->tx_oversize_pkts +
1655 nstat->collisions = hwstat->tx_total_cols; 1659 hwstat->tx_underruns +
1656 1660 hwstat->tx_excessive_cols +
1657 nstat->rx_length_errors = (hwstat->rx_oversize_pkts + 1661 hwstat->tx_late_cols);
1658 hwstat->rx_undersize); 1662 nstat->multicast = hwstat->tx_multicast_pkts;
1659 nstat->rx_over_errors = hwstat->rx_missed_pkts; 1663 nstat->collisions = hwstat->tx_total_cols;
1660 nstat->rx_frame_errors = hwstat->rx_align_errs; 1664
1661 nstat->rx_crc_errors = hwstat->rx_crc_errs; 1665 nstat->rx_length_errors = (hwstat->rx_oversize_pkts +
1662 nstat->rx_errors = (hwstat->rx_jabber_pkts + 1666 hwstat->rx_undersize);
1663 hwstat->rx_oversize_pkts + 1667 nstat->rx_over_errors = hwstat->rx_missed_pkts;
1664 hwstat->rx_missed_pkts + 1668 nstat->rx_frame_errors = hwstat->rx_align_errs;
1665 hwstat->rx_crc_align_errs + 1669 nstat->rx_crc_errors = hwstat->rx_crc_errs;
1666 hwstat->rx_undersize + 1670 nstat->rx_errors = (hwstat->rx_jabber_pkts +
1667 hwstat->rx_crc_errs + 1671 hwstat->rx_oversize_pkts +
1668 hwstat->rx_align_errs + 1672 hwstat->rx_missed_pkts +
1669 hwstat->rx_symbol_errs); 1673 hwstat->rx_crc_align_errs +
1670 1674 hwstat->rx_undersize +
1671 nstat->tx_aborted_errors = hwstat->tx_underruns; 1675 hwstat->rx_crc_errs +
1676 hwstat->rx_align_errs +
1677 hwstat->rx_symbol_errs);
1678
1679 nstat->tx_aborted_errors = hwstat->tx_underruns;
1672#if 0 1680#if 0
1673 /* Carrier lost counter seems to be broken for some devices */ 1681 /* Carrier lost counter seems to be broken for some devices */
1674 nstat->tx_carrier_errors = hwstat->tx_carrier_lost; 1682 nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
1675#endif 1683#endif
1684 } while (u64_stats_fetch_retry_bh(&hwstat->syncp, start));
1676 1685
1677 return nstat; 1686 return nstat;
1678} 1687}
@@ -1993,17 +2002,24 @@ static void b44_get_ethtool_stats(struct net_device *dev,
1993 struct ethtool_stats *stats, u64 *data) 2002 struct ethtool_stats *stats, u64 *data)
1994{ 2003{
1995 struct b44 *bp = netdev_priv(dev); 2004 struct b44 *bp = netdev_priv(dev);
1996 u32 *val = &bp->hw_stats.tx_good_octets; 2005 struct b44_hw_stats *hwstat = &bp->hw_stats;
2006 u64 *data_src, *data_dst;
2007 unsigned int start;
1997 u32 i; 2008 u32 i;
1998 2009
1999 spin_lock_irq(&bp->lock); 2010 spin_lock_irq(&bp->lock);
2000
2001 b44_stats_update(bp); 2011 b44_stats_update(bp);
2012 spin_unlock_irq(&bp->lock);
2002 2013
2003 for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) 2014 do {
2004 *data++ = *val++; 2015 data_src = &hwstat->tx_good_octets;
2016 data_dst = data;
2017 start = u64_stats_fetch_begin_bh(&hwstat->syncp);
2005 2018
2006 spin_unlock_irq(&bp->lock); 2019 for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
2020 *data_dst++ = *data_src++;
2021
2022 } while (u64_stats_fetch_retry_bh(&hwstat->syncp, start));
2007} 2023}
2008 2024
2009static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 2025static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -2113,7 +2129,7 @@ static const struct net_device_ops b44_netdev_ops = {
2113 .ndo_open = b44_open, 2129 .ndo_open = b44_open,
2114 .ndo_stop = b44_close, 2130 .ndo_stop = b44_close,
2115 .ndo_start_xmit = b44_start_xmit, 2131 .ndo_start_xmit = b44_start_xmit,
2116 .ndo_get_stats = b44_get_stats, 2132 .ndo_get_stats64 = b44_get_stats64,
2117 .ndo_set_rx_mode = b44_set_rx_mode, 2133 .ndo_set_rx_mode = b44_set_rx_mode,
2118 .ndo_set_mac_address = b44_set_mac_addr, 2134 .ndo_set_mac_address = b44_set_mac_addr,
2119 .ndo_validate_addr = eth_validate_addr, 2135 .ndo_validate_addr = eth_validate_addr,
diff --git a/drivers/net/ethernet/broadcom/b44.h b/drivers/net/ethernet/broadcom/b44.h
index e1905a49279f..8993d72f0420 100644
--- a/drivers/net/ethernet/broadcom/b44.h
+++ b/drivers/net/ethernet/broadcom/b44.h
@@ -338,9 +338,10 @@ struct ring_info {
338 * the layout 338 * the layout
339 */ 339 */
340struct b44_hw_stats { 340struct b44_hw_stats {
341#define _B44(x) u32 x; 341#define _B44(x) u64 x;
342B44_STAT_REG_DECLARE 342B44_STAT_REG_DECLARE
343#undef _B44 343#undef _B44
344 struct u64_stats_sync syncp;
344}; 345};
345 346
346struct ssb_device; 347struct ssb_device;