e1000: fix adapter led blinking inconsistency
Auke Kok [Tue, 27 Jun 2006 16:07:56 +0000 (09:07 -0700)]
Several e1000 adapters were not blinking correctly or inconsistently. This
patch cleans this up and makes them all behave the same as far as possible.

Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>

drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_hw.h

index cf5c5f4..0609155 100644 (file)
@@ -1786,21 +1786,8 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
                mod_timer(&adapter->blink_timer, jiffies);
                msleep_interruptible(data * 1000);
                del_timer_sync(&adapter->blink_timer);
-       } else if (adapter->hw.mac_type < e1000_82573) {
-               E1000_WRITE_REG(&adapter->hw, LEDCTL,
-                       (E1000_LEDCTL_LED2_BLINK_RATE |
-                        E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
-                        (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
-                        (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
-                        (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
-               msleep_interruptible(data * 1000);
        } else {
-               E1000_WRITE_REG(&adapter->hw, LEDCTL,
-                       (E1000_LEDCTL_LED2_BLINK_RATE |
-                        E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK |
-                        (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
-                        (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
-                        (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
+               e1000_blink_led_start(&adapter->hw);
                msleep_interruptible(data * 1000);
        }
 
index 749d621..1c5b184 100644 (file)
@@ -5537,6 +5537,44 @@ e1000_setup_led(struct e1000_hw *hw)
 }
 
 /******************************************************************************
+ * Used on 82571 and later Si that has LED blink bits.
+ * Callers must use their own timer and should have already called
+ * e1000_id_led_init()
+ * Call e1000_cleanup led() to stop blinking
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+int32_t
+e1000_blink_led_start(struct e1000_hw *hw)
+{
+    int16_t  i;
+    uint32_t ledctl_blink = 0;
+
+    DEBUGFUNC("e1000_id_led_blink_on");
+
+    if (hw->mac_type < e1000_82571) {
+        /* Nothing to do */
+        return E1000_SUCCESS;
+    }
+    if (hw->media_type == e1000_media_type_fiber) {
+        /* always blink LED0 for PCI-E fiber */
+        ledctl_blink = E1000_LEDCTL_LED0_BLINK |
+                     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
+    } else {
+        /* set the blink bit for each LED that's "on" (0x0E) in ledctl_mode2 */
+        ledctl_blink = hw->ledctl_mode2;
+        for (i=0; i < 4; i++)
+            if (((hw->ledctl_mode2 >> (i * 8)) & 0xFF) ==
+                E1000_LEDCTL_MODE_LED_ON)
+                ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << (i * 8));
+    }
+
+    E1000_WRITE_REG(hw, LEDCTL, ledctl_blink);
+
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
  * Restores the saved state of the SW controlable LED.
  *
  * hw - Struct containing variables accessed by shared code
index 467c9ed..941b47d 100644 (file)
@@ -401,6 +401,7 @@ int32_t e1000_setup_led(struct e1000_hw *hw);
 int32_t e1000_cleanup_led(struct e1000_hw *hw);
 int32_t e1000_led_on(struct e1000_hw *hw);
 int32_t e1000_led_off(struct e1000_hw *hw);
+int32_t e1000_blink_led_start(struct e1000_hw *hw);
 
 /* Adaptive IFS Functions */