aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bna/bnad_ethtool.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-09-02 15:45:02 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-02 15:45:02 -0400
commit250e061e1d3e26600236a3dd9172e7f5f5916c00 (patch)
tree4f52da41f1b254538b75e4ba84a8e4f1c2a23b2b /drivers/net/bna/bnad_ethtool.c
parentdeffd77759e3ceb936f0760cc54a213881577a83 (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.c17
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;