Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / intel / e1000e / mac.c
index b25cc4300de77ed602de5d37322970d5e9fb0dc9..2480c1091873864991d9342b6ce15df61b07c000 100644 (file)
@@ -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);