aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2019-05-20 11:07:20 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-21 16:11:54 -0400
commit406cb0c4d16ac5b80c2c802b09fe71f1b1ff8eec (patch)
tree75923b5f7517ac6eefc779401ecc920c4695df4d
parent94d250fae48e6f873d8362308f5c4d02cd1b1fd2 (diff)
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 <rmk+kernel@armlinux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/phylink.c37
1 files 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)
422 422
423 case MLO_AN_INBAND: 423 case MLO_AN_INBAND:
424 phylink_get_mac_state(pl, &link_state); 424 phylink_get_mac_state(pl, &link_state);
425 if (pl->phydev) { 425
426 bool changed = false; 426 /* If we have a phy, the "up" state is the union of
427 427 * both the PHY and the MAC */
428 link_state.link = link_state.link && 428 if (pl->phydev)
429 pl->phy_state.link; 429 link_state.link &= pl->phy_state.link;
430 430
431 if (pl->phy_state.interface != 431 /* Only update if the PHY link is up */
432 link_state.interface) { 432 if (pl->phydev && pl->phy_state.link) {
433 link_state.interface = pl->phy_state.interface; 433 link_state.interface = pl->phy_state.interface;
434 changed = true; 434
435 } 435 /* If we have a PHY, we need to update with
436 436 * the pause mode bits. */
437 /* Propagate the flow control from the PHY 437 link_state.pause |= pl->phy_state.pause;
438 * to the MAC. Also propagate the interface 438 phylink_resolve_flow(pl, &link_state);
439 * if changed. 439 phylink_mac_config(pl, &link_state);
440 */
441 if (pl->phy_state.link || changed) {
442 link_state.pause |= pl->phy_state.pause;
443 phylink_resolve_flow(pl, &link_state);
444
445 phylink_mac_config(pl, &link_state);
446 }
447 } 440 }
448 break; 441 break;
449 } 442 }