net: phylink: ensure inband AN works correctly
authorRussell King <rmk+kernel@armlinux.org.uk>
Mon, 20 May 2019 15:07:20 +0000 (16:07 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 21 May 2019 20:11:54 +0000 (13:11 -0700)
Do not update the link interface mode while the link is down to avoid
spurious link interface changes.

Always call mac_config if we have a PHY to propagate the pause mode
settings to the MAC.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/phylink.c

index 89750c7dfd6f8b350f4a327f6c73065219ce2bb5..74983593834b04a39e8272a899873a9a8626a633 100644 (file)
@@ -422,28 +422,21 @@ static void phylink_resolve(struct work_struct *w)
 
                case MLO_AN_INBAND:
                        phylink_get_mac_state(pl, &link_state);
-                       if (pl->phydev) {
-                               bool changed = false;
-
-                               link_state.link = link_state.link &&
-                                                 pl->phy_state.link;
-
-                               if (pl->phy_state.interface !=
-                                   link_state.interface) {
-                                       link_state.interface = pl->phy_state.interface;
-                                       changed = true;
-                               }
-
-                               /* Propagate the flow control from the PHY
-                                * to the MAC. Also propagate the interface
-                                * if changed.
-                                */
-                               if (pl->phy_state.link || changed) {
-                                       link_state.pause |= pl->phy_state.pause;
-                                       phylink_resolve_flow(pl, &link_state);
-
-                                       phylink_mac_config(pl, &link_state);
-                               }
+
+                       /* If we have a phy, the "up" state is the union of
+                        * both the PHY and the MAC */
+                       if (pl->phydev)
+                               link_state.link &= pl->phy_state.link;
+
+                       /* Only update if the PHY link is up */
+                       if (pl->phydev && pl->phy_state.link) {
+                               link_state.interface = pl->phy_state.interface;
+
+                               /* If we have a PHY, we need to update with
+                                * the pause mode bits. */
+                               link_state.pause |= pl->phy_state.pause;
+                               phylink_resolve_flow(pl, &link_state);
+                               phylink_mac_config(pl, &link_state);
                        }
                        break;
                }