e1000: workaround for the ESB2 NIC RX unit issue
authorJeff Garzik <jeff@garzik.org>
Fri, 15 Dec 2006 16:06:17 +0000 (11:06 -0500)
committerJeff Garzik <jeff@garzik.org>
Tue, 26 Dec 2006 20:51:30 +0000 (15:51 -0500)
In rare occasions, ESB2 systems would end up started without the RX
unit being turned on. Add a check that runs post-init to work around
this issue.

Originally from Jesse Brandeburg <jesse.brandeburg@intel.com>,
rewritten to use feature flags by me.

Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c

index 1ea556ef093bd3275ee13737dda7e3568d1bf716..ea7b371e911911e6291d4618d4b76f9f92eb2bc3 100644 (file)
@@ -452,6 +452,12 @@ e1000_set_mac_type(struct e1000_hw *hw)
        if (hw->mac_type >= e1000_82571)
                hw->has_manc2h = TRUE;
 
+       /* In rare occasions, ESB2 systems would end up started without
+        * the RX unit being turned on.
+        */
+       if (hw->mac_type == e1000_80003es2lan)
+               hw->rx_needs_kicking = TRUE;
+
        return E1000_SUCCESS;
 }
 
index 18a4ae4549adfa4c37ff086672d9a9151db6e50e..f4d01e169c48faffebbd2615b5054d1bded390cc 100644 (file)
@@ -1463,6 +1463,7 @@ struct e1000_hw {
        boolean_t               kmrn_lock_loss_workaround_disabled;
        boolean_t               bad_tx_carr_stats_fd;
        boolean_t               has_manc2h;
+       boolean_t               rx_needs_kicking;
 };
 
 
index 9c2494955bfca6310fa22efa994084836496cabe..343eb68fff7398d9633447631f1592c3bd9a248d 100644 (file)
@@ -2579,6 +2579,13 @@ e1000_watchdog(unsigned long data)
                        netif_wake_queue(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)) {