aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000e/ethtool.c')
-rw-r--r--drivers/net/e1000e/ethtool.c93
1 files changed, 70 insertions, 23 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 1bf4d2a5d34f..0aa50c229c79 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1,7 +1,7 @@
1/******************************************************************************* 1/*******************************************************************************
2 2
3 Intel PRO/1000 Linux driver 3 Intel PRO/1000 Linux driver
4 Copyright(c) 1999 - 2008 Intel Corporation. 4 Copyright(c) 1999 - 2009 Intel Corporation.
5 5
6 This program is free software; you can redistribute it and/or modify it 6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License, 7 under the terms and conditions of the GNU General Public License,
@@ -35,14 +35,22 @@
35 35
36#include "e1000.h" 36#include "e1000.h"
37 37
38enum {NETDEV_STATS, E1000_STATS};
39
38struct e1000_stats { 40struct 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), \
49 offsetof(struct e1000_adapter, m)
50#define E1000_NETDEV_STAT(m) NETDEV_STATS, \
51 sizeof(((struct net_device *)0)->m), \
52 offsetof(struct net_device, m)
53
46static const struct e1000_stats e1000_gstrings_stats[] = { 54static const struct e1000_stats e1000_gstrings_stats[] = {
47 { "rx_packets", E1000_STAT(stats.gprc) }, 55 { "rx_packets", E1000_STAT(stats.gprc) },
48 { "tx_packets", E1000_STAT(stats.gptc) }, 56 { "tx_packets", E1000_STAT(stats.gptc) },
@@ -52,21 +60,21 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
52 { "tx_broadcast", E1000_STAT(stats.bptc) }, 60 { "tx_broadcast", E1000_STAT(stats.bptc) },
53 { "rx_multicast", E1000_STAT(stats.mprc) }, 61 { "rx_multicast", E1000_STAT(stats.mprc) },
54 { "tx_multicast", E1000_STAT(stats.mptc) }, 62 { "tx_multicast", E1000_STAT(stats.mptc) },
55 { "rx_errors", E1000_STAT(net_stats.rx_errors) }, 63 { "rx_errors", E1000_NETDEV_STAT(stats.rx_errors) },
56 { "tx_errors", E1000_STAT(net_stats.tx_errors) }, 64 { "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) },
57 { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, 65 { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) },
58 { "multicast", E1000_STAT(stats.mprc) }, 66 { "multicast", E1000_STAT(stats.mprc) },
59 { "collisions", E1000_STAT(stats.colc) }, 67 { "collisions", E1000_STAT(stats.colc) },
60 { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) }, 68 { "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) },
61 { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, 69 { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) },
62 { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, 70 { "rx_crc_errors", E1000_STAT(stats.crcerrs) },
63 { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, 71 { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) },
64 { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, 72 { "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
65 { "rx_missed_errors", E1000_STAT(stats.mpc) }, 73 { "rx_missed_errors", E1000_STAT(stats.mpc) },
66 { "tx_aborted_errors", E1000_STAT(stats.ecol) }, 74 { "tx_aborted_errors", E1000_STAT(stats.ecol) },
67 { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, 75 { "tx_carrier_errors", E1000_STAT(stats.tncrs) },
68 { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, 76 { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) },
69 { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, 77 { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) },
70 { "tx_window_errors", E1000_STAT(stats.latecol) }, 78 { "tx_window_errors", E1000_STAT(stats.latecol) },
71 { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, 79 { "tx_abort_late_coll", E1000_STAT(stats.latecol) },
72 { "tx_deferred_ok", E1000_STAT(stats.dc) }, 80 { "tx_deferred_ok", E1000_STAT(stats.dc) },
@@ -182,6 +190,17 @@ static int e1000_get_settings(struct net_device *netdev,
182static u32 e1000_get_link(struct net_device *netdev) 190static u32 e1000_get_link(struct net_device *netdev)
183{ 191{
184 struct e1000_adapter *adapter = netdev_priv(netdev); 192 struct e1000_adapter *adapter = netdev_priv(netdev);
193 struct e1000_mac_info *mac = &adapter->hw.mac;
194
195 /*
196 * If the link is not reported up to netdev, interrupts are disabled,
197 * and so the physical link state may have changed since we last
198 * looked. Set get_link_status to make sure that the true link
199 * state is interrogated, rather than pulling a cached and possibly
200 * stale link state from the driver.
201 */
202 if (!netif_carrier_ok(netdev))
203 mac->get_link_status = 1;
185 204
186 return e1000_has_link(adapter); 205 return e1000_has_link(adapter);
187} 206}
@@ -327,10 +346,18 @@ static int e1000_set_pauseparam(struct net_device *netdev,
327 346
328 hw->fc.current_mode = hw->fc.requested_mode; 347 hw->fc.current_mode = hw->fc.requested_mode;
329 348
330 retval = ((hw->phy.media_type == e1000_media_type_fiber) ? 349 if (hw->phy.media_type == e1000_media_type_fiber) {
331 hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw)); 350 retval = hw->mac.ops.setup_link(hw);
351 /* implicit goto out */
352 } else {
353 retval = e1000e_force_mac_fc(hw);
354 if (retval)
355 goto out;
356 e1000e_set_fc_watermarks(hw);
357 }
332 } 358 }
333 359
360out:
334 clear_bit(__E1000_RESETTING, &adapter->state); 361 clear_bit(__E1000_RESETTING, &adapter->state);
335 return retval; 362 return retval;
336} 363}
@@ -508,7 +535,8 @@ static int e1000_get_eeprom(struct net_device *netdev,
508 535
509 if (ret_val) { 536 if (ret_val) {
510 /* a read error occurred, throw away the result */ 537 /* a read error occurred, throw away the result */
511 memset(eeprom_buff, 0xff, sizeof(eeprom_buff)); 538 memset(eeprom_buff, 0xff, sizeof(u16) *
539 (last_word - first_word + 1));
512 } else { 540 } else {
513 /* Device's eeprom is always little-endian, word addressable */ 541 /* Device's eeprom is always little-endian, word addressable */
514 for (i = 0; i < last_word - first_word + 1; i++) 542 for (i = 0; i < last_word - first_word + 1; i++)
@@ -588,7 +616,9 @@ static int e1000_set_eeprom(struct net_device *netdev,
588 * and flush shadow RAM for applicable controllers 616 * and flush shadow RAM for applicable controllers
589 */ 617 */
590 if ((first_word <= NVM_CHECKSUM_REG) || 618 if ((first_word <= NVM_CHECKSUM_REG) ||
591 (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573)) 619 (hw->mac.type == e1000_82583) ||
620 (hw->mac.type == e1000_82574) ||
621 (hw->mac.type == e1000_82573))
592 ret_val = e1000e_update_nvm_checksum(hw); 622 ret_val = e1000e_update_nvm_checksum(hw);
593 623
594out: 624out:
@@ -921,10 +951,10 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
921 e1000e_set_interrupt_capability(adapter); 951 e1000e_set_interrupt_capability(adapter);
922 } 952 }
923 /* Hook up test interrupt handler just for this test */ 953 /* Hook up test interrupt handler just for this test */
924 if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, 954 if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
925 netdev)) { 955 netdev)) {
926 shared_int = 0; 956 shared_int = 0;
927 } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, 957 } else if (request_irq(irq, e1000_test_intr, IRQF_SHARED,
928 netdev->name, netdev)) { 958 netdev->name, netdev)) {
929 *data = 1; 959 *data = 1;
930 ret_val = -1; 960 ret_val = -1;
@@ -1231,6 +1261,10 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
1231 1261
1232 hw->mac.autoneg = 0; 1262 hw->mac.autoneg = 0;
1233 1263
1264 /* Workaround: K1 must be disabled for stable 1Gbps operation */
1265 if (hw->mac.type == e1000_pchlan)
1266 e1000_configure_k1_ich8lan(hw, false);
1267
1234 if (hw->phy.type == e1000_phy_m88) { 1268 if (hw->phy.type == e1000_phy_m88) {
1235 /* Auto-MDI/MDIX Off */ 1269 /* Auto-MDI/MDIX Off */
1236 e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); 1270 e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
@@ -1761,12 +1795,11 @@ static int e1000_set_wol(struct net_device *netdev,
1761{ 1795{
1762 struct e1000_adapter *adapter = netdev_priv(netdev); 1796 struct e1000_adapter *adapter = netdev_priv(netdev);
1763 1797
1764 if (wol->wolopts & WAKE_MAGICSECURE)
1765 return -EOPNOTSUPP;
1766
1767 if (!(adapter->flags & FLAG_HAS_WOL) || 1798 if (!(adapter->flags & FLAG_HAS_WOL) ||
1768 !device_can_wakeup(&adapter->pdev->dev)) 1799 !device_can_wakeup(&adapter->pdev->dev) ||
1769 return wol->wolopts ? -EOPNOTSUPP : 0; 1800 (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
1801 WAKE_MAGIC | WAKE_PHY | WAKE_ARP)))
1802 return -EOPNOTSUPP;
1770 1803
1771 /* these settings will always override what we currently have */ 1804 /* these settings will always override what we currently have */
1772 adapter->wol = 0; 1805 adapter->wol = 0;
@@ -1824,6 +1857,7 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
1824 1857
1825 if ((hw->phy.type == e1000_phy_ife) || 1858 if ((hw->phy.type == e1000_phy_ife) ||
1826 (hw->mac.type == e1000_pchlan) || 1859 (hw->mac.type == e1000_pchlan) ||
1860 (hw->mac.type == e1000_82583) ||
1827 (hw->mac.type == e1000_82574)) { 1861 (hw->mac.type == e1000_82574)) {
1828 INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); 1862 INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
1829 if (!adapter->blink_timer.function) { 1863 if (!adapter->blink_timer.function) {
@@ -1904,10 +1938,21 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
1904{ 1938{
1905 struct e1000_adapter *adapter = netdev_priv(netdev); 1939 struct e1000_adapter *adapter = netdev_priv(netdev);
1906 int i; 1940 int i;
1941 char *p = NULL;
1907 1942
1908 e1000e_update_stats(adapter); 1943 e1000e_update_stats(adapter);
1909 for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { 1944 for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
1910 char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; 1945 switch (e1000_gstrings_stats[i].type) {
1946 case NETDEV_STATS:
1947 p = (char *) netdev +
1948 e1000_gstrings_stats[i].stat_offset;
1949 break;
1950 case E1000_STATS:
1951 p = (char *) adapter +
1952 e1000_gstrings_stats[i].stat_offset;
1953 break;
1954 }
1955
1911 data[i] = (e1000_gstrings_stats[i].sizeof_stat == 1956 data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
1912 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1957 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1913 } 1958 }
@@ -1967,6 +2012,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
1967 .get_sset_count = e1000e_get_sset_count, 2012 .get_sset_count = e1000e_get_sset_count,
1968 .get_coalesce = e1000_get_coalesce, 2013 .get_coalesce = e1000_get_coalesce,
1969 .set_coalesce = e1000_set_coalesce, 2014 .set_coalesce = e1000_set_coalesce,
2015 .get_flags = ethtool_op_get_flags,
2016 .set_flags = ethtool_op_set_flags,
1970}; 2017};
1971 2018
1972void e1000e_set_ethtool_ops(struct net_device *netdev) 2019void e1000e_set_ethtool_ops(struct net_device *netdev)