net: phylink: ensure inband AN works correctly [Linux 5.2]

net: phylink: ensure inband AN works correctly [Linux 5.2]

This Linux kernel change "net: phylink: ensure inband AN works correctly" is included in the Linux 5.2 release. This change is authored by Russell King <rmk+kernel [at] armlinux.org.uk> on Mon May 20 16:07:20 2019 +0100. The commit for this change in Linux stable tree is 406cb0c (patch).

net: phylink: ensure inband AN works correctly

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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>

There are 37 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/phy/phylink.c | 37 +++++++++++++++----------------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 89750c7..7498359 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -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;
        }

Leave a Reply

Your email address will not be published. Required fields are marked *