diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2019-05-20 11:07:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-21 16:11:54 -0400 |
commit | 406cb0c4d16ac5b80c2c802b09fe71f1b1ff8eec (patch) | |
tree | 75923b5f7517ac6eefc779401ecc920c4695df4d | |
parent | 94d250fae48e6f873d8362308f5c4d02cd1b1fd2 (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.c | 37 |
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 | } |