diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/e1000/e1000_ethtool.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 490b2b7cd3ab..c67e93117271 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -31,14 +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), \ |
45 | offsetof(struct e1000_adapter, m) | ||
46 | #define E1000_NETDEV_STAT(m) NETDEV_STATS, \ | ||
47 | sizeof(((struct net_device *)0)->m), \ | ||
48 | offsetof(struct net_device, m) | ||
49 | |||
42 | static const struct e1000_stats e1000_gstrings_stats[] = { | 50 | static const struct e1000_stats e1000_gstrings_stats[] = { |
43 | { "rx_packets", E1000_STAT(stats.gprc) }, | 51 | { "rx_packets", E1000_STAT(stats.gprc) }, |
44 | { "tx_packets", E1000_STAT(stats.gptc) }, | 52 | { "tx_packets", E1000_STAT(stats.gptc) }, |
@@ -50,19 +58,19 @@ static const struct e1000_stats e1000_gstrings_stats[] = { | |||
50 | { "tx_multicast", E1000_STAT(stats.mptc) }, | 58 | { "tx_multicast", E1000_STAT(stats.mptc) }, |
51 | { "rx_errors", E1000_STAT(stats.rxerrc) }, | 59 | { "rx_errors", E1000_STAT(stats.rxerrc) }, |
52 | { "tx_errors", E1000_STAT(stats.txerrc) }, | 60 | { "tx_errors", E1000_STAT(stats.txerrc) }, |
53 | { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, | 61 | { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) }, |
54 | { "multicast", E1000_STAT(stats.mprc) }, | 62 | { "multicast", E1000_STAT(stats.mprc) }, |
55 | { "collisions", E1000_STAT(stats.colc) }, | 63 | { "collisions", E1000_STAT(stats.colc) }, |
56 | { "rx_length_errors", E1000_STAT(stats.rlerrc) }, | 64 | { "rx_length_errors", E1000_STAT(stats.rlerrc) }, |
57 | { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, | 65 | { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) }, |
58 | { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, | 66 | { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, |
59 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, | 67 | { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) }, |
60 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, | 68 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, |
61 | { "rx_missed_errors", E1000_STAT(stats.mpc) }, | 69 | { "rx_missed_errors", E1000_STAT(stats.mpc) }, |
62 | { "tx_aborted_errors", E1000_STAT(stats.ecol) }, | 70 | { "tx_aborted_errors", E1000_STAT(stats.ecol) }, |
63 | { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, | 71 | { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, |
64 | { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, | 72 | { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) }, |
65 | { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, | 73 | { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) }, |
66 | { "tx_window_errors", E1000_STAT(stats.latecol) }, | 74 | { "tx_window_errors", E1000_STAT(stats.latecol) }, |
67 | { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, | 75 | { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, |
68 | { "tx_deferred_ok", E1000_STAT(stats.dc) }, | 76 | { "tx_deferred_ok", E1000_STAT(stats.dc) }, |
@@ -207,6 +215,23 @@ static int e1000_set_settings(struct net_device *netdev, | |||
207 | return 0; | 215 | return 0; |
208 | } | 216 | } |
209 | 217 | ||
218 | static u32 e1000_get_link(struct net_device *netdev) | ||
219 | { | ||
220 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
221 | |||
222 | /* | ||
223 | * If the link is not reported up to netdev, interrupts are disabled, | ||
224 | * and so the physical link state may have changed since we last | ||
225 | * looked. Set get_link_status to make sure that the true link | ||
226 | * state is interrogated, rather than pulling a cached and possibly | ||
227 | * stale link state from the driver. | ||
228 | */ | ||
229 | if (!netif_carrier_ok(netdev)) | ||
230 | adapter->hw.get_link_status = 1; | ||
231 | |||
232 | return e1000_has_link(adapter); | ||
233 | } | ||
234 | |||
210 | static void e1000_get_pauseparam(struct net_device *netdev, | 235 | static void e1000_get_pauseparam(struct net_device *netdev, |
211 | struct ethtool_pauseparam *pause) | 236 | struct ethtool_pauseparam *pause) |
212 | { | 237 | { |
@@ -861,10 +886,10 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) | |||
861 | 886 | ||
862 | /* NOTE: we don't test MSI interrupts here, yet */ | 887 | /* NOTE: we don't test MSI interrupts here, yet */ |
863 | /* Hook up test interrupt handler just for this test */ | 888 | /* Hook up test interrupt handler just for this test */ |
864 | if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, | 889 | if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, |
865 | netdev)) | 890 | netdev)) |
866 | shared_int = false; | 891 | shared_int = false; |
867 | else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, | 892 | else if (request_irq(irq, e1000_test_intr, IRQF_SHARED, |
868 | netdev->name, netdev)) { | 893 | netdev->name, netdev)) { |
869 | *data = 1; | 894 | *data = 1; |
870 | return -1; | 895 | return -1; |
@@ -1830,10 +1855,21 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, | |||
1830 | { | 1855 | { |
1831 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1856 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1832 | int i; | 1857 | int i; |
1858 | char *p = NULL; | ||
1833 | 1859 | ||
1834 | e1000_update_stats(adapter); | 1860 | e1000_update_stats(adapter); |
1835 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { | 1861 | for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { |
1836 | char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; | 1862 | switch (e1000_gstrings_stats[i].type) { |
1863 | case NETDEV_STATS: | ||
1864 | p = (char *) netdev + | ||
1865 | e1000_gstrings_stats[i].stat_offset; | ||
1866 | break; | ||
1867 | case E1000_STATS: | ||
1868 | p = (char *) adapter + | ||
1869 | e1000_gstrings_stats[i].stat_offset; | ||
1870 | break; | ||
1871 | } | ||
1872 | |||
1837 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == | 1873 | data[i] = (e1000_gstrings_stats[i].sizeof_stat == |
1838 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; | 1874 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p; |
1839 | } | 1875 | } |
@@ -1873,7 +1909,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { | |||
1873 | .get_msglevel = e1000_get_msglevel, | 1909 | .get_msglevel = e1000_get_msglevel, |
1874 | .set_msglevel = e1000_set_msglevel, | 1910 | .set_msglevel = e1000_set_msglevel, |
1875 | .nway_reset = e1000_nway_reset, | 1911 | .nway_reset = e1000_nway_reset, |
1876 | .get_link = ethtool_op_get_link, | 1912 | .get_link = e1000_get_link, |
1877 | .get_eeprom_len = e1000_get_eeprom_len, | 1913 | .get_eeprom_len = e1000_get_eeprom_len, |
1878 | .get_eeprom = e1000_get_eeprom, | 1914 | .get_eeprom = e1000_get_eeprom, |
1879 | .set_eeprom = e1000_set_eeprom, | 1915 | .set_eeprom = e1000_set_eeprom, |