diff options
author | Ajit Khaparde <ajitk@serverengines.com> | 2009-10-12 21:45:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-13 14:48:28 -0400 |
commit | 8328c38fcda2743249fd142174acf025d4cdd21f (patch) | |
tree | 40c920ed68896e0c71290d2e0b00cac5108ac8b5 /drivers | |
parent | e0f36a95c7adb6551188cdcc5a7031ce106fccbf (diff) |
e1000: Fix erroneous display of stats by ethtool -S
Commit 23d26497 overlooked the way offsets for netdev stats were considered.
Because of this some of the stats shown by ethtool -S were wrong.
This patch fixes it.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index e25b339eb5bd..ffbae0a0b4f1 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -31,16 +31,22 @@ | |||
31 | #include "e1000.h" | 31 | #include "e1000.h" |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | 33 | ||
34 | enum {NETDEV_STATS, E1000_STATS}; | ||
35 | |||
34 | struct e1000_stats { | 36 | struct e1000_stats { |
35 | char stat_string[ETH_GSTRING_LEN]; | 37 | char stat_string[ETH_GSTRING_LEN]; |
38 | int type; | ||
36 | int sizeof_stat; | 39 | int sizeof_stat; |
37 | int stat_offset; | 40 | int stat_offset; |
38 | }; | 41 | }; |
39 | 42 | ||
40 | #define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \ | 43 | #define E1000_STAT(m) E1000_STATS, \ |
41 | offsetof(struct e1000_adapter, m) | 44 | sizeof(((struct e1000_adapter *)0)->m), \ |
42 | #define E1000_NETDEV_STAT(m) FIELD_SIZEOF(struct net_device, m), \ | 45 | offsetof(struct e1000_adapter, m) |
43 | offsetof(struct net_device, m) | 46 | #define E1000_NETDEV_STAT(m) NETDEV_STATS, \ |
47 | sizeof(((struct net_device *)0)->m), \ | ||
48 | offsetof(struct net_device, m) | ||
49 | |||
44 | static const struct e1000_stats e1000_gstrings_stats[] = { | 50 | static const struct e1000_stats e1000_gstrings_stats[] = { |
45 | { "rx_packets", E1000_STAT(stats.gprc) }, | 51 | { "rx_packets", E1000_STAT(stats.gprc) }, |
46 | { "tx_packets", E1000_STAT(stats.gptc) }, | 52 | { "tx_packets", E1000_STAT(stats.gptc) }, |
@@ -1832,10 +1838,21 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, | |||
1832 | { | 1838 | { |
1833 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1839 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1834 | int i; | 1840 | int i; |
1841 | char *p = NULL; | ||
1835 | 1842 | ||
1836 | e1000_update_stats(adapter); | 1843 | e1000_update_stats(adapter); |
1837 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { | 1844 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { |
1838 | char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; | 1845 | switch (e1000_gstrings_stats[i].type) { |
1846 | case NETDEV_STATS: | ||
1847 | p = (char *) netdev + | ||
1848 | e1000_gstrings_stats[i].stat_offset; | ||
1849 | break; | ||
1850 | case E1000_STATS: | ||
1851 | p = (char *) adapter + | ||
1852 | e1000_gstrings_stats[i].stat_offset; | ||
1853 | break; | ||
1854 | } | ||
1855 | |||
1839 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == | 1856 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == |
1840 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | 1857 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; |
1841 | } | 1858 | } |