[U-Boot] [PATCH 7/8] net/ethoc: don't advertise gigabit on the connected PHY

Michal Simek monstr at monstr.eu
Wed Jul 13 08:28:44 CEST 2016


On 8.7.2016 17:42, Max Filippov wrote:
> Introduce MDIO communication routines. Scan MDIO bus at reset to find
> attached PHYs and see if they support gigabit speeds. If they do check
> their gigabit control register: if gigabit autonegotiation is enabled
> clear it and reset the PHY.
> 
> This allows using OpenCores 10/100 MAC with gigabit PHY connected to
> gigabit network.
> 
> Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
> ---
>  drivers/net/ethoc.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
> index ee7c01e..8f70c0c 100644
> --- a/drivers/net/ethoc.c
> +++ b/drivers/net/ethoc.c
> @@ -290,6 +290,80 @@ static int ethoc_init_ring(struct eth_device *dev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_SYS_ETHOC_SETUP_PHY
> +
> +static u16 ethoc_mii_read(struct eth_device *dev, u8 phy, u8 reg)
> +{
> +	ulong tmo = get_timer(0);
> +
> +	ethoc_write(dev, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
> +	ethoc_write(dev, MIICOMMAND, MIICOMMAND_READ);
> +
> +	while (get_timer(tmo) < CONFIG_SYS_HZ) {
> +		u32 status = ethoc_read(dev, MIISTATUS);
> +		if (!(status & MIISTATUS_BUSY)) {
> +			u32 data = ethoc_read(dev, MIIRX_DATA);
> +			/* reset MII command register */
> +			ethoc_write(dev, MIICOMMAND, 0);
> +			return data;
> +		}
> +	}
> +	return 0xffff;
> +}
> +
> +static void ethoc_mii_write(struct eth_device *dev, u8 phy, u8 reg, u16 v)
> +{
> +	ulong tmo = get_timer(0);
> +
> +	ethoc_write(dev, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
> +	ethoc_write(dev, MIITX_DATA, v);
> +	ethoc_write(dev, MIICOMMAND, MIICOMMAND_WRITE);
> +
> +	while (get_timer(tmo) < CONFIG_SYS_HZ) {
> +		u32 stat = ethoc_read(dev, MIISTATUS);
> +		if (!(stat & MIISTATUS_BUSY)) {
> +			/* reset MII command register */
> +			ethoc_write(dev, MIICOMMAND, 0);
> +			return;
> +		}
> +	}
> +}
> +
> +static void ethoc_setup_phy(struct eth_device *dev)
> +{
> +	u8 phy;
> +
> +	ethoc_write(dev, MIIMODER, 0xfe);
> +
> +	for (phy = 0; phy < 32; ++phy) {
> +		if (ethoc_mii_read(dev, phy, MII_PHYSID1) != 0xffff) {
> +			u16 v;
> +
> +			v = ethoc_mii_read(dev, phy, MII_BMSR);
> +			if (!(v & BMSR_ESTATEN))
> +				continue;
> +
> +			v = ethoc_mii_read(dev, phy, MII_CTRL1000);
> +			if (!(v & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)))
> +				continue;
> +
> +			ethoc_mii_write(dev, phy, MII_CTRL1000,
> +					v & ~(ADVERTISE_1000FULL |
> +					      ADVERTISE_1000HALF));
> +			v = ethoc_mii_read(dev, phy, MII_BMCR);
> +			ethoc_mii_write(dev, phy, MII_BMCR, v | BMCR_RESET);
> +		}
> +	}
> +}
> +
> +#else
> +
> +static inline void ethoc_setup_phy(struct eth_device *dev)
> +{
> +}
> +
> +#endif
> +
>  static int ethoc_reset(struct eth_device *dev)
>  {
>  	u32 mode;
> @@ -311,6 +385,8 @@ static int ethoc_reset(struct eth_device *dev)
>  	ethoc_write(dev, MODER, mode);
>  	ethoc_write(dev, IPGT, 0x15);
>  
> +	ethoc_setup_phy(dev);
> +
>  	ethoc_ack_irq(dev, INT_MASK_ALL);
>  	ethoc_enable_rx_and_tx(dev);
>  	return 0;
> 

This looks kind of weird. If you have standard phy and you do it
properly in the driver you shouldn't do it in this way.
We have the same stuff for emaclite where IP can work only at 10/100 and
it can be used with 1G phy. Just look at setting there.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP SoCs


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160713/bf7b56e0/attachment.sig>


More information about the U-Boot mailing list