Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kevin Groeneveld and committed by
David S. Miller
eeda8585 2e177a5c

+56 -39
+54 -38
drivers/net/ethernet/broadcom/b44.c
··· 483 483 static void b44_stats_update(struct b44 *bp) 484 484 { 485 485 unsigned long reg; 486 - u32 *val; 486 + u64 *val; 487 487 488 488 val = &bp->hw_stats.tx_good_octets; 489 + u64_stats_update_begin(&bp->hw_stats.syncp); 490 + 489 491 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { 490 492 *val++ += br32(bp, reg); 491 493 } ··· 498 496 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { 499 497 *val++ += br32(bp, reg); 500 498 } 499 + 500 + u64_stats_update_end(&bp->hw_stats.syncp); 501 501 } 502 502 503 503 static void b44_link_report(struct b44 *bp) ··· 1639 1635 return 0; 1640 1636 } 1641 1637 1642 - static struct net_device_stats *b44_get_stats(struct net_device *dev) 1638 + static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev, 1639 + struct rtnl_link_stats64 *nstat) 1643 1640 { 1644 1641 struct b44 *bp = netdev_priv(dev); 1645 - struct net_device_stats *nstat = &dev->stats; 1646 1642 struct b44_hw_stats *hwstat = &bp->hw_stats; 1643 + unsigned int start; 1647 1644 1648 - /* Convert HW stats into netdevice stats. */ 1649 - nstat->rx_packets = hwstat->rx_pkts; 1650 - nstat->tx_packets = hwstat->tx_pkts; 1651 - nstat->rx_bytes = hwstat->rx_octets; 1652 - nstat->tx_bytes = hwstat->tx_octets; 1653 - nstat->tx_errors = (hwstat->tx_jabber_pkts + 1654 - hwstat->tx_oversize_pkts + 1655 - hwstat->tx_underruns + 1656 - hwstat->tx_excessive_cols + 1657 - hwstat->tx_late_cols); 1658 - nstat->multicast = hwstat->tx_multicast_pkts; 1659 - nstat->collisions = hwstat->tx_total_cols; 1645 + do { 1646 + start = u64_stats_fetch_begin_bh(&hwstat->syncp); 1660 1647 1661 - nstat->rx_length_errors = (hwstat->rx_oversize_pkts + 1662 - hwstat->rx_undersize); 1663 - nstat->rx_over_errors = hwstat->rx_missed_pkts; 1664 - nstat->rx_frame_errors = hwstat->rx_align_errs; 1665 - nstat->rx_crc_errors = hwstat->rx_crc_errs; 1666 - nstat->rx_errors = (hwstat->rx_jabber_pkts + 1667 - hwstat->rx_oversize_pkts + 1668 - hwstat->rx_missed_pkts + 1669 - hwstat->rx_crc_align_errs + 1670 - hwstat->rx_undersize + 1671 - hwstat->rx_crc_errs + 1672 - hwstat->rx_align_errs + 1673 - hwstat->rx_symbol_errs); 1648 + /* Convert HW stats into rtnl_link_stats64 stats. */ 1649 + nstat->rx_packets = hwstat->rx_pkts; 1650 + nstat->tx_packets = hwstat->tx_pkts; 1651 + nstat->rx_bytes = hwstat->rx_octets; 1652 + nstat->tx_bytes = hwstat->tx_octets; 1653 + nstat->tx_errors = (hwstat->tx_jabber_pkts + 1654 + hwstat->tx_oversize_pkts + 1655 + hwstat->tx_underruns + 1656 + hwstat->tx_excessive_cols + 1657 + hwstat->tx_late_cols); 1658 + nstat->multicast = hwstat->tx_multicast_pkts; 1659 + nstat->collisions = hwstat->tx_total_cols; 1674 1660 1675 - nstat->tx_aborted_errors = hwstat->tx_underruns; 1661 + nstat->rx_length_errors = (hwstat->rx_oversize_pkts + 1662 + hwstat->rx_undersize); 1663 + nstat->rx_over_errors = hwstat->rx_missed_pkts; 1664 + nstat->rx_frame_errors = hwstat->rx_align_errs; 1665 + nstat->rx_crc_errors = hwstat->rx_crc_errs; 1666 + nstat->rx_errors = (hwstat->rx_jabber_pkts + 1667 + hwstat->rx_oversize_pkts + 1668 + hwstat->rx_missed_pkts + 1669 + hwstat->rx_crc_align_errs + 1670 + hwstat->rx_undersize + 1671 + hwstat->rx_crc_errs + 1672 + hwstat->rx_align_errs + 1673 + hwstat->rx_symbol_errs); 1674 + 1675 + nstat->tx_aborted_errors = hwstat->tx_underruns; 1676 1676 #if 0 1677 - /* Carrier lost counter seems to be broken for some devices */ 1678 - nstat->tx_carrier_errors = hwstat->tx_carrier_lost; 1677 + /* Carrier lost counter seems to be broken for some devices */ 1678 + nstat->tx_carrier_errors = hwstat->tx_carrier_lost; 1679 1679 #endif 1680 + } while (u64_stats_fetch_retry_bh(&hwstat->syncp, start)); 1680 1681 1681 1682 return nstat; 1682 1683 } ··· 2002 1993 struct ethtool_stats *stats, u64 *data) 2003 1994 { 2004 1995 struct b44 *bp = netdev_priv(dev); 2005 - u32 *val = &bp->hw_stats.tx_good_octets; 1996 + struct b44_hw_stats *hwstat = &bp->hw_stats; 1997 + u64 *data_src, *data_dst; 1998 + unsigned int start; 2006 1999 u32 i; 2007 2000 2008 2001 spin_lock_irq(&bp->lock); 2009 - 2010 2002 b44_stats_update(bp); 2011 - 2012 - for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) 2013 - *data++ = *val++; 2014 - 2015 2003 spin_unlock_irq(&bp->lock); 2004 + 2005 + do { 2006 + data_src = &hwstat->tx_good_octets; 2007 + data_dst = data; 2008 + start = u64_stats_fetch_begin_bh(&hwstat->syncp); 2009 + 2010 + for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) 2011 + *data_dst++ = *data_src++; 2012 + 2013 + } while (u64_stats_fetch_retry_bh(&hwstat->syncp, start)); 2016 2014 } 2017 2015 2018 2016 static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ··· 2129 2113 .ndo_open = b44_open, 2130 2114 .ndo_stop = b44_close, 2131 2115 .ndo_start_xmit = b44_start_xmit, 2132 - .ndo_get_stats = b44_get_stats, 2116 + .ndo_get_stats64 = b44_get_stats64, 2133 2117 .ndo_set_rx_mode = b44_set_rx_mode, 2134 2118 .ndo_set_mac_address = b44_set_mac_addr, 2135 2119 .ndo_validate_addr = eth_validate_addr,
+2 -1
drivers/net/ethernet/broadcom/b44.h
··· 338 338 * the layout 339 339 */ 340 340 struct b44_hw_stats { 341 - #define _B44(x) u32 x; 341 + #define _B44(x) u64 x; 342 342 B44_STAT_REG_DECLARE 343 343 #undef _B44 344 + struct u64_stats_sync syncp; 344 345 }; 345 346 346 347 struct ssb_device;