From 406cb0c4d16ac5b80c2c802b09fe71f1b1ff8eec Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 20 May 2019 16:07:20 +0100 Subject: [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 Signed-off-by: David S. Miller --- 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 89750c7dfd6f..74983593834b 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; } -- 2.30.2