From a112b7ecb1a0ebbc2555e4a97bfc1d779eb439c0 Mon Sep 17 00:00:00 2001 From: Andrew Gospodarek Date: Fri, 13 Jun 2008 15:51:14 -0400 Subject: [PATCH] e1000: restart receive unit workaroun on ESB2 hardware RHBZ 446374 There is a workaround for ESB2 hardware that was added to deal with link detection problems, but it gets skipped when we took the fix for some of the watchdog timeout issues. This adds back the functionality. --- drivers/net/e1000/e1000.h | 1 + drivers/net/e1000/e1000_main.c | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 9992a5c..cf5d240 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -347,6 +347,7 @@ struct e1000_adapter { boolean_t tso_force; boolean_t smart_power_down; /* phy smart power down */ boolean_t quad_port_a; + boolean_t rx_restart_now; unsigned long flags; uint32_t eeprom_wol; }; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6663908..b8022aa 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1979,6 +1979,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter) } E1000_WRITE_REG(&adapter->hw, RCTL, rctl); + adapter->rx_restart_now = 0; } /** @@ -2537,6 +2538,18 @@ e1000_82547_tx_fifo_stall(unsigned long data) } } +static void e1000_enable_receives(struct e1000_adapter *adapter) +{ + /* make sure the receive unit is started */ + if ((adapter->hw.mac_type == e1000_80003es2lan) && + (adapter->rx_restart_now == 1)) { + struct e1000_hw *hw = &adapter->hw; + u32 rctl = E1000_READ_REG(hw, RCTL); + E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN); + adapter->rx_restart_now = 0; + } +} + /** * e1000_watchdog - Timer Call-back * @data: pointer to adapter cast into an unsigned long @@ -2559,8 +2572,10 @@ e1000_watchdog_task(struct net_device *netdev) int32_t ret_val; if ((netif_carrier_ok(netdev)) && - (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) + (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { + e1000_enable_receives(adapter); goto link_up; + } ret_val = e1000_check_for_link(&adapter->hw); if ((ret_val == E1000_ERR_PHY) && @@ -2662,13 +2677,6 @@ e1000_watchdog_task(struct net_device *netdev) mod_timer(&adapter->phy_info_timer, (jiffies + 2 * HZ)); adapter->smartspeed = 0; - } else { - /* make sure the receive unit is started */ - if (adapter->hw.rx_needs_kicking) { - struct e1000_hw *hw = &adapter->hw; - uint32_t rctl = E1000_READ_REG(hw, RCTL); - E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN); - } } } else { if (netif_carrier_ok(netdev)) { @@ -3767,6 +3775,7 @@ irqreturn_t e1000_intr_msi(int irq, void *data, struct pt_regs *regs) /* disable receives */ uint32_t rctl = E1000_READ_REG(hw, RCTL); E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); + adapter->rx_restart_now = 1; } /* guard against interrupt when we're going down */ if (!test_bit(__E1000_DOWN, &adapter->flags)) @@ -3847,6 +3856,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) /* disable receives */ rctl = E1000_READ_REG(hw, RCTL); E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); + adapter->rx_restart_now = 1; } /* guard against interrupt when we're going down */ if (!test_bit(__E1000_DOWN, &adapter->flags)) -- 1.5.2.1