[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