Skip to content

Commit 06e5ba7

Browse files
committed
Merge branch 'phylink-resolve-fixes'
Marek Behún says: ==================== phylink resolve fixes With information from me and my nagging, Russell has produced two fixes for phylink, which add code that triggers another phylink_resolve() from phylink_resolve(), if certain conditions are met: interface is being changed or link is down and previous link was up These are needed because sometimes the PCS callbacks may provide stale values if link / speed / ... ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents ddb826c + dbae338 commit 06e5ba7

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

drivers/net/phy/phylink.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ static void phylink_resolve(struct work_struct *w)
710710
struct phylink_link_state link_state;
711711
struct net_device *ndev = pl->netdev;
712712
bool mac_config = false;
713+
bool retrigger = false;
713714
bool cur_link_state;
714715

715716
mutex_lock(&pl->state_mutex);
@@ -723,6 +724,7 @@ static void phylink_resolve(struct work_struct *w)
723724
link_state.link = false;
724725
} else if (pl->mac_link_dropped) {
725726
link_state.link = false;
727+
retrigger = true;
726728
} else {
727729
switch (pl->cur_link_an_mode) {
728730
case MLO_AN_PHY:
@@ -739,6 +741,19 @@ static void phylink_resolve(struct work_struct *w)
739741
case MLO_AN_INBAND:
740742
phylink_mac_pcs_get_state(pl, &link_state);
741743

744+
/* The PCS may have a latching link-fail indicator.
745+
* If the link was up, bring the link down and
746+
* re-trigger the resolve. Otherwise, re-read the
747+
* PCS state to get the current status of the link.
748+
*/
749+
if (!link_state.link) {
750+
if (cur_link_state)
751+
retrigger = true;
752+
else
753+
phylink_mac_pcs_get_state(pl,
754+
&link_state);
755+
}
756+
742757
/* If we have a phy, the "up" state is the union of
743758
* both the PHY and the MAC
744759
*/
@@ -747,6 +762,15 @@ static void phylink_resolve(struct work_struct *w)
747762

748763
/* Only update if the PHY link is up */
749764
if (pl->phydev && pl->phy_state.link) {
765+
/* If the interface has changed, force a
766+
* link down event if the link isn't already
767+
* down, and re-resolve.
768+
*/
769+
if (link_state.interface !=
770+
pl->phy_state.interface) {
771+
retrigger = true;
772+
link_state.link = false;
773+
}
750774
link_state.interface = pl->phy_state.interface;
751775

752776
/* If we have a PHY, we need to update with
@@ -789,7 +813,7 @@ static void phylink_resolve(struct work_struct *w)
789813
else
790814
phylink_link_up(pl, link_state);
791815
}
792-
if (!link_state.link && pl->mac_link_dropped) {
816+
if (!link_state.link && retrigger) {
793817
pl->mac_link_dropped = false;
794818
queue_work(system_power_efficient_wq, &pl->resolve);
795819
}

0 commit comments

Comments
 (0)