aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r--drivers/net/e1000/e1000_ethtool.c58
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
34enum {NETDEV_STATS, E1000_STATS};
35
34struct e1000_stats { 36struct 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
42static const struct e1000_stats e1000_gstrings_stats[] = { 50static 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
218static 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
210static void e1000_get_pauseparam(struct net_device *netdev, 235static 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,