diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-09-02 15:45:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-02 15:45:02 -0400 |
commit | 250e061e1d3e26600236a3dd9172e7f5f5916c00 (patch) | |
tree | 4f52da41f1b254538b75e4ba84a8e4f1c2a23b2b /drivers/net/bna/bnad_ethtool.c | |
parent | deffd77759e3ceb936f0760cc54a213881577a83 (diff) |
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 @@ | |||
34 | #define BNAD_NUM_TXQ_COUNTERS 5 | 34 | #define BNAD_NUM_TXQ_COUNTERS 5 |
35 | 35 | ||
36 | #define BNAD_ETHTOOL_STATS_NUM \ | 36 | #define BNAD_ETHTOOL_STATS_NUM \ |
37 | (sizeof(struct net_device_stats) / sizeof(unsigned long) + \ | 37 | (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \ |
38 | sizeof(struct bnad_drv_stats) / sizeof(u64) + \ | 38 | sizeof(struct bnad_drv_stats) / sizeof(u64) + \ |
39 | offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64)) | 39 | offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64)) |
40 | 40 | ||
@@ -1159,7 +1159,8 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, | |||
1159 | { | 1159 | { |
1160 | struct bnad *bnad = netdev_priv(netdev); | 1160 | struct bnad *bnad = netdev_priv(netdev); |
1161 | int i, j, bi; | 1161 | int i, j, bi; |
1162 | unsigned long *net_stats, flags; | 1162 | unsigned long flags; |
1163 | struct rtnl_link_stats64 *net_stats64; | ||
1163 | u64 *stats64; | 1164 | u64 *stats64; |
1164 | u64 bmap; | 1165 | u64 bmap; |
1165 | 1166 | ||
@@ -1176,16 +1177,12 @@ bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, | |||
1176 | spin_lock_irqsave(&bnad->bna_lock, flags); | 1177 | spin_lock_irqsave(&bnad->bna_lock, flags); |
1177 | bi = 0; | 1178 | bi = 0; |
1178 | memset(buf, 0, stats->n_stats * sizeof(u64)); | 1179 | memset(buf, 0, stats->n_stats * sizeof(u64)); |
1179 | memset(&bnad->net_stats, 0, sizeof(struct net_device_stats)); | ||
1180 | 1180 | ||
1181 | bnad_netdev_qstats_fill(bnad); | 1181 | net_stats64 = (struct rtnl_link_stats64 *)buf; |
1182 | bnad_netdev_hwstats_fill(bnad); | 1182 | bnad_netdev_qstats_fill(bnad, net_stats64); |
1183 | bnad_netdev_hwstats_fill(bnad, net_stats64); | ||
1183 | 1184 | ||
1184 | /* Fill net_stats into ethtool buffers */ | 1185 | bi = sizeof(*net_stats64) / sizeof(u64); |
1185 | net_stats = (unsigned long *)&bnad->net_stats; | ||
1186 | for (i = 0; i < sizeof(struct net_device_stats) / sizeof(unsigned long); | ||
1187 | i++) | ||
1188 | buf[bi++] = net_stats[i]; | ||
1189 | 1186 | ||
1190 | /* Fill driver stats into ethtool buffers */ | 1187 | /* Fill driver stats into ethtool buffers */ |
1191 | stats64 = (u64 *)&bnad->stats.drv_stats; | 1188 | stats64 = (u64 *)&bnad->stats.drv_stats; |