diff options
author | Ajit Khaparde <ajitk@serverengines.com> | 2009-10-12 21:45:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-13 14:48:27 -0400 |
commit | e0f36a95c7adb6551188cdcc5a7031ce106fccbf (patch) | |
tree | 9314f67e01886500400c6753e66f79053aa6f403 /drivers/net/e1000e/ethtool.c | |
parent | 29c3a050f83c524218b1baa4e43aedd21501b338 (diff) |
e1000e: Fix erroneous display of stats by ethtool -S
Commit fd8235bb 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/net/e1000e/ethtool.c')
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 8a78a143e591..a70999b8c6cf 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -35,16 +35,22 @@ | |||
35 | 35 | ||
36 | #include "e1000.h" | 36 | #include "e1000.h" |
37 | 37 | ||
38 | enum {NETDEV_STATS, E1000_STATS}; | ||
39 | |||
38 | struct e1000_stats { | 40 | struct e1000_stats { |
39 | char stat_string[ETH_GSTRING_LEN]; | 41 | char stat_string[ETH_GSTRING_LEN]; |
42 | int type; | ||
40 | int sizeof_stat; | 43 | int sizeof_stat; |
41 | int stat_offset; | 44 | int stat_offset; |
42 | }; | 45 | }; |
43 | 46 | ||
44 | #define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ | 47 | #define E1000_STAT(m) E1000_STATS, \ |
45 | offsetof(struct e1000_adapter, m) | 48 | sizeof(((struct e1000_adapter *)0)->m), \ |
46 | #define E1000_NETDEV_STAT(m) sizeof(((struct net_device *)0)->m), \ | 49 | offsetof(struct e1000_adapter, m) |
47 | offsetof(struct net_device, m) | 50 | #define E1000_NETDEV_STAT(m) NETDEV_STATS, \ |
51 | sizeof(((struct net_device *)0)->m), \ | ||
52 | offsetof(struct net_device, m) | ||
53 | |||
48 | static const struct e1000_stats e1000_gstrings_stats[] = { | 54 | static const struct e1000_stats e1000_gstrings_stats[] = { |
49 | { "rx_packets", E1000_STAT(stats.gprc) }, | 55 | { "rx_packets", E1000_STAT(stats.gprc) }, |
50 | { "tx_packets", E1000_STAT(stats.gptc) }, | 56 | { "tx_packets", E1000_STAT(stats.gptc) }, |
@@ -1906,10 +1912,21 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, | |||
1906 | { | 1912 | { |
1907 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1913 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1908 | int i; | 1914 | int i; |
1915 | char *p = NULL; | ||
1909 | 1916 | ||
1910 | e1000e_update_stats(adapter); | 1917 | e1000e_update_stats(adapter); |
1911 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { | 1918 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { |
1912 | char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; | 1919 | switch (e1000_gstrings_stats[i].type) { |
1920 | case NETDEV_STATS: | ||
1921 | p = (char *) netdev + | ||
1922 | e1000_gstrings_stats[i].stat_offset; | ||
1923 | break; | ||
1924 | case E1000_STATS: | ||
1925 | p = (char *) adapter + | ||
1926 | e1000_gstrings_stats[i].stat_offset; | ||
1927 | break; | ||
1928 | } | ||
1929 | |||
1913 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == | 1930 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == |
1914 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | 1931 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; |
1915 | } | 1932 | } |