|
@@ -1600,15 +1600,28 @@ s32 e1000e_blink_led_generic(struct e1000_hw *hw)
|
|
|
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
|
|
|
+ /* Set the blink bit for each LED that's "on" (0x0E)
|
|
|
+ * (or "off" if inverted) in ledctl_mode2. The blink
|
|
|
+ * logic in hardware only works when mode is set to "on"
|
|
|
+ * so it must be changed accordingly when the mode is
|
|
|
+ * "off" and inverted.
|
|
|
*/
|
|
|
ledctl_blink = hw->mac.ledctl_mode2;
|
|
|
- for (i = 0; i < 4; i++)
|
|
|
- if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
|
|
|
- E1000_LEDCTL_MODE_LED_ON)
|
|
|
- ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
|
|
|
- (i * 8));
|
|
|
+ for (i = 0; i < 32; i += 8) {
|
|
|
+ u32 mode = (hw->mac.ledctl_mode2 >> i) &
|
|
|
+ E1000_LEDCTL_LED0_MODE_MASK;
|
|
|
+ u32 led_default = hw->mac.ledctl_default >> i;
|
|
|
+
|
|
|
+ if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
|
|
|
+ (mode == E1000_LEDCTL_MODE_LED_ON)) ||
|
|
|
+ ((led_default & E1000_LEDCTL_LED0_IVRT) &&
|
|
|
+ (mode == E1000_LEDCTL_MODE_LED_OFF))) {
|
|
|
+ ledctl_blink &=
|
|
|
+ ~(E1000_LEDCTL_LED0_MODE_MASK << i);
|
|
|
+ ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
|
|
|
+ E1000_LEDCTL_MODE_LED_ON) << i;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
ew32(LEDCTL, ledctl_blink);
|