Skip to content

Commit

Permalink
phy: micrel: Disable auto negotiation on startup
Browse files Browse the repository at this point in the history
Disable auto negotiation on init to properly detect an already plugged
cable at boot.

At boot, when the phy is started, it is in the PHY_UP state.
However, if a cable is plugged at boot, because auto negociation is already
enabled at the time we get the first interrupt, the phy is already running.
But the state machine then switches from PHY_UP to PHY_AN and calls
phy_start_aneg(). phy_start_aneg() will not do anything because aneg is
already enabled on the phy. It will then wait for a interrupt before going
further. This interrupt will never happen unless the cable is unplugged and
then replugged.

It was working properly before 321beec (net: phy: Use interrupts when
available in NOLINK state) because switching to NOLINK meant starting
polling the phy, even if IRQ were enabled.

Fixes: 321beec (net: phy: Use interrupts when available in NOLINK state)
Signed-off-by: Alexandre Belloni <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
alexandrebelloni authored and davem330 committed Mar 1, 2016
1 parent f5aba91 commit 99f81af
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/net/phy/micrel.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,17 @@ static int kszphy_config_init(struct phy_device *phydev)
if (priv->led_mode >= 0)
kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);

if (phy_interrupt_is_valid(phydev)) {
int ctl = phy_read(phydev, MII_BMCR);

if (ctl < 0)
return ctl;

ret = phy_write(phydev, MII_BMCR, ctl & ~BMCR_ANENABLE);
if (ret < 0)
return ret;
}

return 0;
}

Expand Down

0 comments on commit 99f81af

Please sign in to comment.