net: phy: consolidate PHY reset in phy_init_hw()

There are quite a lot of drivers touching a PHY device MII_BMCR
register to reset the PHY without taking care of:

1) ensuring that BMCR_RESET is cleared after a given timeout
2) the PHY state machine resuming to the proper state and re-applying
potentially changed settings such as auto-negotiation

Introduce phy_poll_reset() which will take care of polling the MII_BMCR
for the BMCR_RESET bit to be cleared after a given timeout or return a
timeout error code.

In order to make sure the PHY is in a correct state, phy_init_hw() first
issues a software reset through MII_BMCR and then applies any fixups.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Florian Fainelli
2013-12-06 13:01:34 -08:00
committed by David S. Miller
parent 06d87cec73
commit 87aa9f9c61
3 changed files with 60 additions and 4 deletions

View File

@@ -318,6 +318,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
{
struct mii_ioctl_data *mii_data = if_mii(ifr);
u16 val = mii_data->val_in;
int ret = 0;
switch (cmd) {
case SIOCGMIIPHY:
@@ -362,7 +363,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
if (mii_data->reg_num == MII_BMCR &&
val & BMCR_RESET)
phy_init_hw(phydev);
ret = phy_init_hw(phydev);
break;
case SIOCSHWTSTAMP:
@@ -374,7 +375,7 @@ int phy_mii_ioctl(struct phy_device *phydev,
return -EOPNOTSUPP;
}
return 0;
return ret;
}
EXPORT_SYMBOL(phy_mii_ioctl);