net: phy: add phy_check_link_status
In few places in the state machine the state is set to PHY_RUNNING or PHY_NOLINK after doing a phy_read_status(). So factor this out to phy_check_link_status(). First use it in phy_start_aneg(): By setting the state to PHY_RUNNING or PHY_NOLINK directly we can remove the code to handle the case that we're using interrupts and aneg was finished already. Definition of phy_link_up and phy_link_down needs to be moved because they are called in the new function. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c96469f830
Коммит
74a992b359
|
@ -62,6 +62,17 @@ static const char *phy_state_to_str(enum phy_state st)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void phy_link_up(struct phy_device *phydev)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_print_status - Convenience function to print out the current phy status
|
||||
|
@ -493,6 +504,34 @@ static int phy_config_aneg(struct phy_device *phydev)
|
|||
return genphy_config_aneg(phydev);
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_check_link_status - check link status and set state accordingly
|
||||
* @phydev: the phy_device struct
|
||||
*
|
||||
* Description: Check for link and whether autoneg was triggered / is running
|
||||
* and set state accordingly
|
||||
*/
|
||||
static int phy_check_link_status(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&phydev->lock));
|
||||
|
||||
err = phy_read_status(phydev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (phydev->link && phydev->state != PHY_RUNNING) {
|
||||
phydev->state = PHY_RUNNING;
|
||||
phy_link_up(phydev);
|
||||
} else if (!phydev->link && phydev->state != PHY_NOLINK) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
phy_link_down(phydev, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_start_aneg - start auto-negotiation for this PHY device
|
||||
* @phydev: the phy_device struct
|
||||
|
@ -504,7 +543,6 @@ static int phy_config_aneg(struct phy_device *phydev)
|
|||
*/
|
||||
int phy_start_aneg(struct phy_device *phydev)
|
||||
{
|
||||
bool trigger = 0;
|
||||
int err;
|
||||
|
||||
if (!phydev->drv)
|
||||
|
@ -524,32 +562,16 @@ int phy_start_aneg(struct phy_device *phydev)
|
|||
|
||||
if (phydev->state != PHY_HALTED) {
|
||||
if (AUTONEG_ENABLE == phydev->autoneg) {
|
||||
phydev->state = PHY_AN;
|
||||
phydev->link_timeout = PHY_AN_TIMEOUT;
|
||||
err = phy_check_link_status(phydev);
|
||||
} else {
|
||||
phydev->state = PHY_FORCING;
|
||||
phydev->link_timeout = PHY_FORCE_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-schedule a PHY state machine to check PHY status because
|
||||
* negotiation may already be done and aneg interrupt may not be
|
||||
* generated.
|
||||
*/
|
||||
if (!phy_polling_mode(phydev) && phydev->state == PHY_AN) {
|
||||
err = phy_aneg_done(phydev);
|
||||
if (err > 0) {
|
||||
trigger = true;
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&phydev->lock);
|
||||
|
||||
if (trigger)
|
||||
phy_trigger_machine(phydev);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(phy_start_aneg);
|
||||
|
@ -893,18 +915,6 @@ void phy_start(struct phy_device *phydev)
|
|||
}
|
||||
EXPORT_SYMBOL(phy_start);
|
||||
|
||||
static void phy_link_up(struct phy_device *phydev)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_state_machine - Handle the state machine
|
||||
* @work: work_struct that describes the work to be done
|
||||
|
|
Загрузка…
Ссылка в новой задаче