Message ID | 1452693577-25786-2-git-send-email-abrodkin@synopsys.com |
---|---|
State | Accepted |
Commit | bbdcaff |
Delegated to: | Joe Hershberger |
Headers | show |
On Wed, Jan 13, 2016 at 7:59 AM, Alexey Brodkin <Alexey.Brodkin@synopsys.com> wrote: > From: Florian Fainelli <f.fainelli@gmail.com> > > When a Gigabit PHY device is connected to a 10/100Mbits capable Ethernet > MAC, the driver will restrict the phydev->supported modes to mask off > Gigabit. If the Gigabit PHY comes out of reset with the Gigabit features > set by default in MII_CTRL1000, it will keep advertising these feature, > so by the time we call genphy_config_advert(), the condition on > phydev->supported having the Gigabit features on is false, and we do not > update MII_CTRL1000 with updated values, and we keep advertising Gigabit > features, eventually configuring the PHY for Gigabit whilst the Ethernet > MAC does not support that. > > This patches fixes the problem by ensuring that the Gigabit feature bits > are always cleared in MII_CTRL1000, if the PHY happens to be a Gigabit > PHY, and then, if Gigabit features are supported, setting those and > updating MII_CTRL1000 accordingly. > > This is a copy of patch from Linux kernel, see > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5273e3a5ca94fbeb8e07d31203069220d5e682aa > > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> > Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> > Cc: Joe Hershberger <joe.hershberger@ni.com> > --- Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Hi Alexey, https://patchwork.ozlabs.org/patch/566944/ was applied to u-boot-net.git. Thanks! -Joe
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 51b5746..084276f 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -38,11 +38,10 @@ DECLARE_GLOBAL_DATA_PTR; static int genphy_config_advert(struct phy_device *phydev) { u32 advertise; - int oldadv, adv; + int oldadv, adv, bmsr; int err, changed = 0; - /* Only allow advertising what - * this PHY supports */ + /* Only allow advertising what this PHY supports */ phydev->advertising &= phydev->supported; advertise = phydev->advertising; @@ -79,29 +78,39 @@ static int genphy_config_advert(struct phy_device *phydev) changed = 1; } + bmsr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); + if (bmsr < 0) + return bmsr; + + /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all + * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a + * logical 1. + */ + if (!(bmsr & BMSR_ESTATEN)) + return changed; + /* Configure gigabit if it's supported */ - if (phydev->supported & (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full)) { - oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); + oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); + + if (adv < 0) + return adv; - if (adv < 0) - return adv; + adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); - adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); + if (phydev->supported & (SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full)) { if (advertise & SUPPORTED_1000baseT_Half) adv |= ADVERTISE_1000HALF; if (advertise & SUPPORTED_1000baseT_Full) adv |= ADVERTISE_1000FULL; + } - if (adv != oldadv) { - err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, - adv); + if (adv != oldadv) + changed = 1; - if (err < 0) - return err; - changed = 1; - } - } + err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, adv); + if (err < 0) + return err; return changed; }