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.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index e82638ecae88..983493f2330c 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,
@@ -31,18 +31,27 @@
31#include <linux/netdevice.h> 31#include <linux/netdevice.h>
32#include <linux/ethtool.h> 32#include <linux/ethtool.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/slab.h>
34#include <linux/delay.h> 35#include <linux/delay.h>
35 36
36#include "e1000.h" 37#include "e1000.h"
37 38
39enum {NETDEV_STATS, E1000_STATS};
40
38struct e1000_stats { 41struct e1000_stats {
39 char stat_string[ETH_GSTRING_LEN]; 42 char stat_string[ETH_GSTRING_LEN];
43 int type;
40 int sizeof_stat; 44 int sizeof_stat;
41 int stat_offset; 45 int stat_offset;
42}; 46};
43 47
44#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ 48#define E1000_STAT(m) E1000_STATS, \
45 offsetof(struct e1000_adapter, m) 49 sizeof(((struct e1000_adapter *)0)->m), \
50 offsetof(struct e1000_adapter, m)
51#define E1000_NETDEV_STAT(m) NETDEV_STATS, \
52 sizeof(((struct net_device *)0)->m), \
53 offsetof(struct net_device, m)
54
46static const struct e1000_stats e1000_gstrings_stats[] = { 55static const struct e1000_stats e1000_gstrings_stats[] = {
47 { "rx_packets", E1000_STAT(stats.gprc) }, 56 { "rx_packets", E1000_STAT(stats.gprc) },
48 { "tx_packets", E1000_STAT(stats.gptc) }, 57 { "tx_packets", E1000_STAT(stats.gptc) },
@@ -52,21 +61,21 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
52 { "tx_broadcast", E1000_STAT(stats.bptc) }, 61 { "tx_broadcast", E1000_STAT(stats.bptc) },
53 { "rx_multicast", E1000_STAT(stats.mprc) }, 62 { "rx_multicast", E1000_STAT(stats.mprc) },
54 { "tx_multicast", E1000_STAT(stats.mptc) }, 63 { "tx_multicast", E1000_STAT(stats.mptc) },
55 { "rx_errors", E1000_STAT(net_stats.rx_errors) }, 64 { "rx_errors", E1000_NETDEV_STAT(stats.rx_errors) },
56 { "tx_errors", E1000_STAT(net_stats.tx_errors) }, 65 { "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) },
57 { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, 66 { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) },
58 { "multicast", E1000_STAT(stats.mprc) }, 67 { "multicast", E1000_STAT(stats.mprc) },
59 { "collisions", E1000_STAT(stats.colc) }, 68 { "collisions", E1000_STAT(stats.colc) },
60 { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) }, 69 { "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) },
61 { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, 70 { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) },
62 { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, 71 { "rx_crc_errors", E1000_STAT(stats.crcerrs) },
63 { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, 72 { "rx_frame_errors", E1000_NETDEV_STAT(stats.rx_frame_errors) },
64 { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, 73 { "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
65 { "rx_missed_errors", E1000_STAT(stats.mpc) }, 74 { "rx_missed_errors", E1000_STAT(stats.mpc) },
66 { "tx_aborted_errors", E1000_STAT(stats.ecol) }, 75 { "tx_aborted_errors", E1000_STAT(stats.ecol) },
67 { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, 76 { "tx_carrier_errors", E1000_STAT(stats.tncrs) },
68 { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, 77 { "tx_fifo_errors", E1000_NETDEV_STAT(stats.tx_fifo_errors) },
69 { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, 78 { "tx_heartbeat_errors", E1000_NETDEV_STAT(stats.tx_heartbeat_errors) },
70 { "tx_window_errors", E1000_STAT(stats.latecol) }, 79 { "tx_window_errors", E1000_STAT(stats.latecol) },
71 { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, 80 { "tx_abort_late_coll", E1000_STAT(stats.latecol) },
72 { "tx_deferred_ok", E1000_STAT(stats.dc) }, 81 { "tx_deferred_ok", E1000_STAT(stats.dc) },
@@ -182,8 +191,19 @@ static int e1000_get_settings(struct net_device *netdev,
182static u32 e1000_get_link(struct net_device *netdev) 191static u32 e1000_get_link(struct net_device *netdev)
183{ 192{
184 struct e1000_adapter *adapter = netdev_priv(netdev); 193 struct e1000_adapter *adapter = netdev_priv(netdev);
194 struct e1000_mac_info *mac = &adapter->hw.mac;
195
196 /*
197 * If the link is not reported up to netdev, interrupts are disabled,
198 * and so the physical link state may have changed since we last
199 * looked. Set get_link_status to make sure that the true link
200 * state is interrogated, rather than pulling a cached and possibly
201 * stale link state from the driver.
202 */
203 if (!netif_carrier_ok(netdev))
204 mac->get_link_status = 1;
185 205
186 return e1000_has_link(adapter); 206 return e1000e_has_link(adapter);
187} 207}
188 208
189static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) 209static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
@@ -516,7 +536,8 @@ static int e1000_get_eeprom(struct net_device *netdev,
516 536
517 if (ret_val) { 537 if (ret_val) {
518 /* a read error occurred, throw away the result */ 538 /* a read error occurred, throw away the result */
519 memset(eeprom_buff, 0xff, sizeof(eeprom_buff)); 539 memset(eeprom_buff, 0xff, sizeof(u16) *
540 (last_word - first_word + 1));
520 } else { 541 } else {
521 /* Device's eeprom is always little-endian, word addressable */ 542 /* Device's eeprom is always little-endian, word addressable */
522 for (i = 0; i < last_word - first_word + 1; i++) 543 for (i = 0; i < last_word - first_word + 1; i++)
@@ -596,7 +617,9 @@ static int e1000_set_eeprom(struct net_device *netdev,
596 * and flush shadow RAM for applicable controllers 617 * and flush shadow RAM for applicable controllers
597 */ 618 */
598 if ((first_word <= NVM_CHECKSUM_REG) || 619 if ((first_word <= NVM_CHECKSUM_REG) ||
599 (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573)) 620 (hw->mac.type == e1000_82583) ||
621 (hw->mac.type == e1000_82574) ||
622 (hw->mac.type == e1000_82573))
600 ret_val = e1000e_update_nvm_checksum(hw); 623 ret_val = e1000e_update_nvm_checksum(hw);
601 624
602out: 625out:
@@ -929,10 +952,10 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
929 e1000e_set_interrupt_capability(adapter); 952 e1000e_set_interrupt_capability(adapter);
930 } 953 }
931 /* Hook up test interrupt handler just for this test */ 954 /* Hook up test interrupt handler just for this test */
932 if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, 955 if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
933 netdev)) { 956 netdev)) {
934 shared_int = 0; 957 shared_int = 0;
935 } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, 958 } else if (request_irq(irq, e1000_test_intr, IRQF_SHARED,
936 netdev->name, netdev)) { 959 netdev->name, netdev)) {
937 *data = 1; 960 *data = 1;
938 ret_val = -1; 961 ret_val = -1;
@@ -1239,6 +1262,10 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
1239 1262
1240 hw->mac.autoneg = 0; 1263 hw->mac.autoneg = 0;
1241 1264
1265 /* Workaround: K1 must be disabled for stable 1Gbps operation */
1266 if (hw->mac.type == e1000_pchlan)
1267 e1000_configure_k1_ich8lan(hw, false);
1268
1242 if (hw->phy.type == e1000_phy_m88) { 1269 if (hw->phy.type == e1000_phy_m88) {
1243 /* Auto-MDI/MDIX Off */ 1270 /* Auto-MDI/MDIX Off */
1244 e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); 1271 e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
@@ -1769,12 +1796,11 @@ static int e1000_set_wol(struct net_device *netdev,
1769{ 1796{
1770 struct e1000_adapter *adapter = netdev_priv(netdev); 1797 struct e1000_adapter *adapter = netdev_priv(netdev);
1771 1798
1772 if (wol->wolopts & WAKE_MAGICSECURE)
1773 return -EOPNOTSUPP;
1774
1775 if (!(adapter->flags & FLAG_HAS_WOL) || 1799 if (!(adapter->flags & FLAG_HAS_WOL) ||
1776 !device_can_wakeup(&adapter->pdev->dev)) 1800 !device_can_wakeup(&adapter->pdev->dev) ||
1777 return wol->wolopts ? -EOPNOTSUPP : 0; 1801 (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
1802 WAKE_MAGIC | WAKE_PHY | WAKE_ARP)))
1803 return -EOPNOTSUPP;
1778 1804
1779 /* these settings will always override what we currently have */ 1805 /* these settings will always override what we currently have */
1780 adapter->wol = 0; 1806 adapter->wol = 0;
@@ -1832,6 +1858,7 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
1832 1858
1833 if ((hw->phy.type == e1000_phy_ife) || 1859 if ((hw->phy.type == e1000_phy_ife) ||
1834 (hw->mac.type == e1000_pchlan) || 1860 (hw->mac.type == e1000_pchlan) ||
1861 (hw->mac.type == e1000_82583) ||
1835 (hw->mac.type == e1000_82574)) { 1862 (hw->mac.type == e1000_82574)) {
1836 INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); 1863 INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
1837 if (!adapter->blink_timer.function) { 1864 if (!adapter->blink_timer.function) {
@@ -1912,10 +1939,21 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
1912{ 1939{
1913 struct e1000_adapter *adapter = netdev_priv(netdev); 1940 struct e1000_adapter *adapter = netdev_priv(netdev);
1914 int i; 1941 int i;
1942 char *p = NULL;
1915 1943
1916 e1000e_update_stats(adapter); 1944 e1000e_update_stats(adapter);
1917 for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { 1945 for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
1918 char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; 1946 switch (e1000_gstrings_stats[i].type) {
1947 case NETDEV_STATS:
1948 p = (char *) netdev +
1949 e1000_gstrings_stats[i].stat_offset;
1950 break;
1951 case E1000_STATS:
1952 p = (char *) adapter +
1953 e1000_gstrings_stats[i].stat_offset;
1954 break;
1955 }
1956
1919 data[i] = (e1000_gstrings_stats[i].sizeof_stat == 1957 data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
1920 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1958 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1921 } 1959 }
@@ -1975,6 +2013,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
1975 .get_sset_count = e1000e_get_sset_count, 2013 .get_sset_count = e1000e_get_sset_count,
1976 .get_coalesce = e1000_get_coalesce, 2014 .get_coalesce = e1000_get_coalesce,
1977 .set_coalesce = e1000_set_coalesce, 2015 .set_coalesce = e1000_set_coalesce,
2016 .get_flags = ethtool_op_get_flags,
2017 .set_flags = ethtool_op_set_flags,
1978}; 2018};
1979 2019
1980void e1000e_set_ethtool_ops(struct net_device *netdev) 2020void e1000e_set_ethtool_ops(struct net_device *netdev)