diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-09-02 23:45:02 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-02 23:45:02 +0400 |
commit | 250e061e1d3e26600236a3dd9172e7f5f5916c00 (patch) | |
tree | 4f52da41f1b254538b75e4ba84a8e4f1c2a23b2b /drivers/net/bna/bnad_ethtool.c | |
parent | deffd77759e3ceb936f0760cc54a213881577a83 (diff) | |
download | linux-250e061e1d3e26600236a3dd9172e7f5f5916c00.tar.xz |
bna: fix stats handling
get_stats() method incorrectly clears a global array before folding
various stats. This can break SNMP applications.
Switch to 64 bit flavor to work on a user supplied buffer, and provide
64bit counters even on 32bit arches.
Fix a bug in bnad_netdev_hwstats_fill(), for rx_fifo_errors, missing a
folding (only the last counter was taken into account)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Rasesh Mody <rmody@brocade.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bna/bnad_ethtool.c')
-rw-r--r-- | drivers/net/bna/bnad_ethtool.c | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c index b337bd9bed29..11fa2ea842c1 100644 --- a/drivers/net/bna/bnad_ethtool.c +++ b/drivers/net/bna/bnad_ethtool.c @@ -34,7 +34,7 @@ #define BNAD_NUM_TXQ_COUNTERS 5 #define BNAD_ETHTOOL_STATS_NUM \ - (sizeof(struct net_device_stats) / sizeof(unsigned long) + \ + (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \ sizeof(struct bnad_drv_stats) / sizeof(u64) + \ offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64)) @@ -1159,7 +1159,8 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, { struct bnad *bnad = netdev_priv(netdev); int i, j, bi; - unsigned long *net_stats, flags; + unsigned long flags; + struct rtnl_link_stats64 *net_stats64; u64 *stats64; u64 bmap; @@ -1176,16 +1177,12 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, spin_lock_irqsave(&bnad->bna_lock, flags); bi = 0; memset(buf, 0, stats->n_stats * sizeof(u64)); - memset(&bnad->net_stats, 0, sizeof(struct net_device_stats)); - bnad_netdev_qstats_fill(bnad); - bnad_netdev_hwstats_fill(bnad); + net_stats64 = (struct rtnl_link_stats64 *)buf; + bnad_netdev_qstats_fill(bnad, net_stats64); + bnad_netdev_hwstats_fill(bnad, net_stats64); - /* Fill net_stats into ethtool buffers */ - net_stats = (unsigned long *)&bnad->net_stats; - for (i = 0; i < sizeof(struct net_device_stats) / sizeof(unsigned long); - i++) - buf[bi++] = net_stats[i]; + bi = sizeof(*net_stats64) / sizeof(u64); /* Fill driver stats into ethtool buffers */ stats64 = (u64 *)&bnad->stats.drv_stats; |