[U-Boot] [PATCH] net: phy: ensure Gigabit features are masked off if requested
Alexey Brodkin
Alexey.Brodkin at synopsys.com
Mon Jan 11 11:26:56 CET 2016
Hi Joe,
On Wed, 2015-12-23 at 19:27 +0300, Alexey Brodkin wrote:
> From: Florian Fainelli <f.fainelli at 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 at gmail.com>
> Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
> Cc: Joe Hershberger <joe.hershberger at ni.com>
> ---
> drivers/net/phy/phy.c | 43 ++++++++++++++++++++++++++-----------------
> 1 file changed, 26 insertions(+), 17 deletions(-)
>
> 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;
> }
Any chance for this one to be applied?
-Alexey
More information about the U-Boot
mailing list