From a81497bee70eb15039594b3116913133aa9c9b29 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 25 Jul 2017 15:02:58 +0100 Subject: net: phy: provide a hook for link up/link down events Sometimes, we need to do additional work between the PHY coming up and marking the carrier present - for example, we may need to wait for the PHY to MAC link to finish negotiation. This changes phylib to provide a notification function pointer which avoids the built-in netif_carrier_on() and netif_carrier_off() functions. Standard ->adjust_link functionality is provided by hooking a helper into the new ->phy_link_change method. Reviewed-by: Florian Fainelli Signed-off-by: Russell King Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers/net/phy/phy.c') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 71c64a774856..d5f2af2c5ddb 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -865,9 +865,15 @@ void phy_start(struct phy_device *phydev) } EXPORT_SYMBOL(phy_start); -static void phy_adjust_link(struct phy_device *phydev) +static void phy_link_up(struct phy_device *phydev) { - phydev->adjust_link(phydev->attached_dev); + phydev->phy_link_change(phydev, true, true); + phy_led_trigger_change_speed(phydev); +} + +static void phy_link_down(struct phy_device *phydev, bool do_carrier) +{ + phydev->phy_link_change(phydev, false, do_carrier); phy_led_trigger_change_speed(phydev); } @@ -912,8 +918,7 @@ void phy_state_machine(struct work_struct *work) /* If the link is down, give up on negotiation for now */ if (!phydev->link) { phydev->state = PHY_NOLINK; - netif_carrier_off(phydev->attached_dev); - phy_adjust_link(phydev); + phy_link_down(phydev, true); break; } @@ -925,9 +930,7 @@ void phy_state_machine(struct work_struct *work) /* If AN is done, we're running */ if (err > 0) { phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - phy_adjust_link(phydev); - + phy_link_up(phydev); } else if (0 == phydev->link_timeout--) needs_aneg = true; break; @@ -952,8 +955,7 @@ void phy_state_machine(struct work_struct *work) } } phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); - phy_adjust_link(phydev); + phy_link_up(phydev); } break; case PHY_FORCING: @@ -963,13 +965,12 @@ void phy_state_machine(struct work_struct *work) if (phydev->link) { phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); + phy_link_up(phydev); } else { if (0 == phydev->link_timeout--) needs_aneg = true; + phy_link_down(phydev, false); } - - phy_adjust_link(phydev); break; case PHY_RUNNING: /* Only register a CHANGE if we are polling and link changed @@ -1001,14 +1002,12 @@ void phy_state_machine(struct work_struct *work) if (phydev->link) { phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); + phy_link_up(phydev); } else { phydev->state = PHY_NOLINK; - netif_carrier_off(phydev->attached_dev); + phy_link_down(phydev, true); } - phy_adjust_link(phydev); - if (phy_interrupt_is_valid(phydev)) err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); @@ -1016,8 +1015,7 @@ void phy_state_machine(struct work_struct *work) case PHY_HALTED: if (phydev->link) { phydev->link = 0; - netif_carrier_off(phydev->attached_dev); - phy_adjust_link(phydev); + phy_link_down(phydev, true); do_suspend = true; } break; @@ -1037,11 +1035,11 @@ void phy_state_machine(struct work_struct *work) if (phydev->link) { phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); + phy_link_up(phydev); } else { phydev->state = PHY_NOLINK; + phy_link_down(phydev, false); } - phy_adjust_link(phydev); } else { phydev->state = PHY_AN; phydev->link_timeout = PHY_AN_TIMEOUT; @@ -1053,11 +1051,11 @@ void phy_state_machine(struct work_struct *work) if (phydev->link) { phydev->state = PHY_RUNNING; - netif_carrier_on(phydev->attached_dev); + phy_link_up(phydev); } else { phydev->state = PHY_NOLINK; + phy_link_down(phydev, false); } - phy_adjust_link(phydev); } break; } -- cgit v1.2.3