summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Nunley <nicholasx.d.nunley@intel.com>2010-02-03 14:49:28 +0000
committerDavid S. Miller <davem@davemloft.net>2010-02-03 19:39:56 -0800
commitde50174e9db59c0634dc217925d70544170b046c (patch)
tree85670591e07925b7178f13577331cb8dfc9ba519
parent3285ef3b1257028d17f0811d3e89243fe5727049 (diff)
e1000: Report link status in ethtool when interface is down
With this change ethtool will correctly report link status when the interface is down. Currently ethtool reports the link as not detected when the interface is down. Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--e1000.h1
-rw-r--r--e1000_ethtool.c19
-rw-r--r--e1000_main.c2
3 files changed, 20 insertions, 2 deletions
diff --git a/e1000.h b/e1000.h
index e8932db..9902b33 100644
--- a/e1000.h
+++ b/e1000.h
@@ -349,6 +349,7 @@ extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
extern void e1000_update_stats(struct e1000_adapter *adapter);
+extern bool e1000_has_link(struct e1000_adapter *adapter);
extern void e1000_power_up_phy(struct e1000_adapter *);
extern void e1000_set_ethtool_ops(struct net_device *netdev);
extern void e1000_check_options(struct e1000_adapter *adapter);
diff --git a/e1000_ethtool.c b/e1000_ethtool.c
index 13e9ece..c67e931 100644
--- a/e1000_ethtool.c
+++ b/e1000_ethtool.c
@@ -215,6 +215,23 @@ static int e1000_set_settings(struct net_device *netdev,
return 0;
}
+static u32 e1000_get_link(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+
+ /*
+ * If the link is not reported up to netdev, interrupts are disabled,
+ * and so the physical link state may have changed since we last
+ * looked. Set get_link_status to make sure that the true link
+ * state is interrogated, rather than pulling a cached and possibly
+ * stale link state from the driver.
+ */
+ if (!netif_carrier_ok(netdev))
+ adapter->hw.get_link_status = 1;
+
+ return e1000_has_link(adapter);
+}
+
static void e1000_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
@@ -1892,7 +1909,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_msglevel = e1000_get_msglevel,
.set_msglevel = e1000_set_msglevel,
.nway_reset = e1000_nway_reset,
- .get_link = ethtool_op_get_link,
+ .get_link = e1000_get_link,
.get_eeprom_len = e1000_get_eeprom_len,
.get_eeprom = e1000_get_eeprom,
.set_eeprom = e1000_set_eeprom,
diff --git a/e1000_main.c b/e1000_main.c
index b608528..4ff50d6 100644
--- a/e1000_main.c
+++ b/e1000_main.c
@@ -2246,7 +2246,7 @@ static void e1000_82547_tx_fifo_stall(unsigned long data)
}
}
-static bool e1000_has_link(struct e1000_adapter *adapter)
+bool e1000_has_link(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
bool link_active = false;