linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
@ 2018-07-30 14:01 Alexander Onnasch
  2018-07-30 14:06 ` Andrew Lunn
  2018-07-30 16:45 ` David Miller
  0 siblings, 2 replies; 10+ messages in thread
From: Alexander Onnasch @ 2018-07-30 14:01 UTC (permalink / raw)
  Cc: alexander.onnasch, Andrew Lunn, Florian Fainelli, netdev, linux-kernel

With Micrel KSZ8061 PHY, the link may occasionally not come up after
Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
sheet 80000688A.pdf describes the problem and possible workarounds in
detail, see below.
The patch implements workaround 1, which permanently fixes the issue.

DESCRIPTION
Link-up may not occur properly when the Ethernet cable is initially
connected. This issue occurs more commonly when the cable is connected
slowly, but it may occur any time a cable is connected. This issue occurs
in the auto-negotiation circuit, and will not occur if auto-negotiation
is disabled (which requires that the two link partners be set to the
same speed and duplex).

END USER IMPLICATIONS
When this issue occurs, link is not established. Subsequent cable
plug/unplug cycles will not correct the issue.

WORK AROUND
There are four approaches to work around this issue:
1.  This issue can be prevented by setting bit 15 in MMD device address 1,
    register 2, prior to connecting the  cable or prior to setting the
    Restart Auto-Negotiation bit in register 0h.The MMD registers are
    accessed via the indirect access registers Dh and Eh, or via the Micrel
    EthUtil utility as shown here:
    •  If using the EthUtil utility (usually with a Micrel KSZ8061
       Evaluation Board), type the following commands:
       > address 1
       > mmd 1
       > iw 2 b61a
    •  Alternatively, write the following registers to write to the
       indirect MMD register:
       Write register Dh, data 0001h
       Write register Eh, data 0002h
       Write register Dh, data 4001h
       Write register Eh, data B61Ah
2.  The issue can be avoided by disabling auto-negotiation in the KSZ8061,
    either by the strapping option, or by clearing bit 12 in register 0h.
    Care must be taken to ensure that the KSZ8061 and the link partner
    will link with the same speed and duplex. Note that the KSZ8061
    defaults to full-duplex when auto-negotiation is off, but other
    devices may default to half-duplex in the event of failed
    auto-negotiation.
3.  The issue can be avoided by connecting the cable prior to powering-up
    or resetting the KSZ8061, and leaving it plugged in thereafter.
4.  If the above measures are not taken and the problem occurs, link can
    be recovered by setting the Restart Auto-Negotiation bit in
    register 0h, or by resetting or power cycling the device. Reset may
    be either hardware reset or software reset (register 0h, bit 15).

PLAN
This errata will not be corrected in a future revision.

Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
---
 drivers/net/phy/micrel.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 6c45ff6..eb85cf4 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -339,6 +339,17 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
 	return genphy_config_aneg(phydev);
 }
 
+static int ksz8061_config_init(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
+	if (ret)
+		return ret;
+
+	return kszphy_config_init(phydev);
+}
+
 static int ksz9021_load_values_from_of(struct phy_device *phydev,
 				       const struct device_node *of_node,
 				       u16 reg,
@@ -938,7 +949,7 @@ static struct phy_driver ksphy_driver[] = {
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
-	.config_init	= kszphy_config_init,
+	.config_init	= ksz8061_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= kszphy_ack_interrupt,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-07-30 14:01 [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect Alexander Onnasch
@ 2018-07-30 14:06 ` Andrew Lunn
  2018-07-30 16:45 ` David Miller
  1 sibling, 0 replies; 10+ messages in thread
From: Andrew Lunn @ 2018-07-30 14:06 UTC (permalink / raw)
  To: Alexander Onnasch; +Cc: Florian Fainelli, netdev, linux-kernel

On Mon, Jul 30, 2018 at 04:01:27PM +0200, Alexander Onnasch wrote:
> With Micrel KSZ8061 PHY, the link may occasionally not come up after
> Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
> sheet 80000688A.pdf describes the problem and possible workarounds in
> detail, see below.
> The patch implements workaround 1, which permanently fixes the issue.
 
> Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-07-30 14:01 [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect Alexander Onnasch
  2018-07-30 14:06 ` Andrew Lunn
@ 2018-07-30 16:45 ` David Miller
  2018-08-13 10:41   ` Onnasch, Alexander (EXT)
  1 sibling, 1 reply; 10+ messages in thread
From: David Miller @ 2018-07-30 16:45 UTC (permalink / raw)
  To: alexander.onnasch; +Cc: andrew, f.fainelli, netdev, linux-kernel

From: Alexander Onnasch <alexander.onnasch@landisgyr.com>
Date: Mon, 30 Jul 2018 16:01:27 +0200

> With Micrel KSZ8061 PHY, the link may occasionally not come up after
> Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
> sheet 80000688A.pdf describes the problem and possible workarounds in
> detail, see below.
> The patch implements workaround 1, which permanently fixes the issue.
 ...
> Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>

This patch does not apply cleanly to any of my neworking trees.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-07-30 16:45 ` David Miller
@ 2018-08-13 10:41   ` Onnasch, Alexander (EXT)
  0 siblings, 0 replies; 10+ messages in thread
From: Onnasch, Alexander (EXT) @ 2018-08-13 10:41 UTC (permalink / raw)
  To: David Miller; +Cc: andrew, f.fainelli, netdev, linux-kernel

-----Original Message-----
From: David Miller <davem@davemloft.net> 
Sent: Montag, 30. Juli 2018 18:46
To: Onnasch, Alexander (EXT) <Alexander.Onnasch@landisgyr.com>
Cc: andrew@lunn.ch; f.fainelli@gmail.com; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect

From: Alexander Onnasch <alexander.onnasch@landisgyr.com>
Date: Mon, 30 Jul 2018 16:01:27 +0200

> With Micrel KSZ8061 PHY, the link may occasionally not come up after 
> Ethernet cable connect. The vendor's (Microchip, former Micrel) errata 
> sheet 80000688A.pdf describes the problem and possible workarounds in 
> detail, see below.
> The patch implements workaround 1, which permanently fixes the issue.
 ...
> Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>

This patch does not apply cleanly to any of my neworking trees.


Hello David

thanks a lot for reviewing ! How to proceed now ? If there is action required from my side please tell me.

best regards, 
Alex


Alexander Onnasch |   Landis+Gyr AG   |  Firmware Engineer
Phone: +41 41 935 6357  |   Fax: +41 41 935 6211
Email: alexander.onnasch@landisgyr.com  |   Site: www.landisgyr.com  |   Address: Theilerstr. 1, CH-6301 Zug, Switzerland
manage energy better


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-07-30 14:00       ` Onnasch, Alexander (EXT)
@ 2018-07-30 14:03         ` Andrew Lunn
  0 siblings, 0 replies; 10+ messages in thread
From: Andrew Lunn @ 2018-07-30 14:03 UTC (permalink / raw)
  To: Onnasch, Alexander (EXT); +Cc: Florian Fainelli, netdev, linux-kernel

On Mon, Jul 30, 2018 at 02:00:44PM +0000, Onnasch, Alexander (EXT) wrote:
> Hi Andrew
> 
> thanks for your feedback. I was on holiday, thus just delayed, not forgotten...
> Sorry for top-posting - odd company default mail setup.

But you did it again....

Your email client should not be forcing you to top post. So please
don't.

	Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-06-19 15:28     ` Andrew Lunn
@ 2018-07-30 14:00       ` Onnasch, Alexander (EXT)
  2018-07-30 14:03         ` Andrew Lunn
  0 siblings, 1 reply; 10+ messages in thread
From: Onnasch, Alexander (EXT) @ 2018-07-30 14:00 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, netdev, linux-kernel

Hi Andrew

thanks for your feedback. I was on holiday, thus just delayed, not forgotten...
Sorry for top-posting - odd company default mail setup.
I checked again phy_write_mmd(), you are right ! 
Patch with changed implementation will follow.

Best regards, Alex


-----Original Message-----
From: Andrew Lunn <andrew@lunn.ch> 
Sent: Dienstag, 19. Juni 2018 17:29
To: Onnasch, Alexander (EXT) <Alexander.Onnasch@landisgyr.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect

On Tue, Jun 19, 2018 at 02:23:41PM +0000, Onnasch, Alexander (EXT) wrote:
> Hi Andrew
> thanks for the hint. But actually I cannot confirm - or I don't see it yet. 
> 
> Without having tested, just from the code, the struct phy_driver instance for PHY_ID_KSZ8061 in micrel.c does not have a .write_mmd function assigned, thus phy_write_mmd should evaluate to its else-clause (see below) and not to mdiobus_write (as in phy_write).
> 
> Also the ksz8061_extended_write() function which I have added uses the same principle as already existing HW-specific functions in micrel.c for simular reasons (kszphy_extended_write and ksz9031_extended_write).
> They use phy_write all over the place in that file and never phy_write_mmd - for whatever reason they had.
> Thus I thought it would be a good idea ...

Hi Alexander

Please don't top post. And wrap your lines at around 75 characters 

> 		struct mii_bus *bus = phydev->mdio.bus;
> 		int phy_addr = phydev->mdio.addr;
> 
> 		mutex_lock(&bus->mdio_lock);
> 		mmd_phy_indirect(bus, phy_addr, devad, regnum);
> 
> 		/* Write the data into MMD's selected register */
> 		bus->write(bus, phy_addr, MII_MMD_DATA, val);
> 		mutex_unlock(&bus->mdio_lock);


> > +static int ksz8061_extended_write(struct phy_device *phydev,
> > +				  u8 mode, u32 dev_addr, u32 regnum, u16 val) {
> > +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, dev_addr);
> > +	phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, regnum);
> > +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
> > +	return phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, val); }
> 
> Hi Alexander
> 
> This looks a lot like phy_write_mmd().

Look closely at the two implementations. Look at what
mmd_phy_indirect() does. I _think_ these are identical. So don't add your own helper, please use the core code.

     Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-06-19 14:23   ` Onnasch, Alexander (EXT)
@ 2018-06-19 15:28     ` Andrew Lunn
  2018-07-30 14:00       ` Onnasch, Alexander (EXT)
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2018-06-19 15:28 UTC (permalink / raw)
  To: Onnasch, Alexander (EXT); +Cc: Florian Fainelli, netdev, linux-kernel

On Tue, Jun 19, 2018 at 02:23:41PM +0000, Onnasch, Alexander (EXT) wrote:
> Hi Andrew
> thanks for the hint. But actually I cannot confirm - or I don't see it yet. 
> 
> Without having tested, just from the code, the struct phy_driver instance for PHY_ID_KSZ8061 in micrel.c does not have a .write_mmd function assigned, thus phy_write_mmd should evaluate to its else-clause (see below) and not to mdiobus_write (as in phy_write).
> 
> Also the ksz8061_extended_write() function which I have added uses the same principle as already existing HW-specific functions in micrel.c for simular reasons (kszphy_extended_write and ksz9031_extended_write).
> They use phy_write all over the place in that file and never phy_write_mmd - for whatever reason they had.
> Thus I thought it would be a good idea ...

Hi Alexander

Please don't top post. And wrap your lines at around 75 characters 

> 		struct mii_bus *bus = phydev->mdio.bus;
> 		int phy_addr = phydev->mdio.addr;
> 
> 		mutex_lock(&bus->mdio_lock);
> 		mmd_phy_indirect(bus, phy_addr, devad, regnum);
> 
> 		/* Write the data into MMD's selected register */
> 		bus->write(bus, phy_addr, MII_MMD_DATA, val);
> 		mutex_unlock(&bus->mdio_lock);


> > +static int ksz8061_extended_write(struct phy_device *phydev,
> > +				  u8 mode, u32 dev_addr, u32 regnum, u16 val) {
> > +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, dev_addr);
> > +	phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, regnum);
> > +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
> > +	return phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, val); }
> 
> Hi Alexander
> 
> This looks a lot like phy_write_mmd().

Look closely at the two implementations. Look at what
mmd_phy_indirect() does. I _think_ these are identical. So don't add
your own helper, please use the core code.

     Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-06-06 12:39 ` Andrew Lunn
@ 2018-06-19 14:23   ` Onnasch, Alexander (EXT)
  2018-06-19 15:28     ` Andrew Lunn
  0 siblings, 1 reply; 10+ messages in thread
From: Onnasch, Alexander (EXT) @ 2018-06-19 14:23 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, netdev, linux-kernel

Hi Andrew
thanks for the hint. But actually I cannot confirm - or I don't see it yet. 

Without having tested, just from the code, the struct phy_driver instance for PHY_ID_KSZ8061 in micrel.c does not have a .write_mmd function assigned, thus phy_write_mmd should evaluate to its else-clause (see below) and not to mdiobus_write (as in phy_write).

Also the ksz8061_extended_write() function which I have added uses the same principle as already existing HW-specific functions in micrel.c for simular reasons (kszphy_extended_write and ksz9031_extended_write).
They use phy_write all over the place in that file and never phy_write_mmd - for whatever reason they had.
Thus I thought it would be a good idea ...

best regards, Alex


static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
{
	return mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, regnum, val);
}



int phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
{
	int ret;

	if (regnum > (u16)~0 || devad > 32)
		return -EINVAL;

	if (phydev->drv->write_mmd) {
		ret = phydev->drv->write_mmd(phydev, devad, regnum, val);
	} else if (phydev->is_c45) {
		u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff);

		ret = mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
				    addr, val);
	} else {
		struct mii_bus *bus = phydev->mdio.bus;
		int phy_addr = phydev->mdio.addr;

		mutex_lock(&bus->mdio_lock);
		mmd_phy_indirect(bus, phy_addr, devad, regnum);

		/* Write the data into MMD's selected register */
		bus->write(bus, phy_addr, MII_MMD_DATA, val);
		mutex_unlock(&bus->mdio_lock);

		ret = 0;
	}
	return ret;
}

-----Original Message-----
From: Andrew Lunn <andrew@lunn.ch> 
Sent: Mittwoch, 6. Juni 2018 14:40
To: Onnasch, Alexander (EXT) <Alexander.Onnasch@landisgyr.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect

On Wed, Jun 06, 2018 at 10:03:18AM +0200, Alexander Onnasch wrote:
> With Micrel KSZ8061 PHY, the link may occasionally not come up after 
> Ethernet cable connect. The vendor's (Microchip, former Micrel) errata 
> sheet 80000688A.pdf describes the problem and possible workarounds in 
> detail, see below.
> The patch implements workaround 1, which permanently fixes the issue.
> 
> DESCRIPTION
> Link-up may not occur properly when the Ethernet cable is initially 
> connected. This issue occurs more commonly when the cable is connected 
> slowly, but it may occur any time a cable is connected. This issue 
> occurs in the auto-negotiation circuit, and will not occur if 
> auto-negotiation is disabled (which requires that the two link 
> partners be set to the same speed and duplex).
> 
> END USER IMPLICATIONS
> When this issue occurs, link is not established. Subsequent cable 
> plug/unplug cycles will not correct the issue.
> 
> WORK AROUND
> There are four approaches to work around this issue:
> 1.  This issue can be prevented by setting bit 15 in MMD device address 1,
>     register 2, prior to connecting the  cable or prior to setting the
>     Restart Auto-Negotiation bit in register 0h.The MMD registers are
>     accessed via the indirect access registers Dh and Eh, or via the Micrel
>     EthUtil utility as shown here:
>     •  If using the EthUtil utility (usually with a Micrel KSZ8061
>        Evaluation Board), type the following commands:
>        > address 1
>        > mmd 1
>        > iw 2 b61a
>     •  Alternatively, write the following registers to write to the
>        indirect MMD register:
>        Write register Dh, data 0001h
>        Write register Eh, data 0002h
>        Write register Dh, data 4001h
>        Write register Eh, data B61Ah
> 2.  The issue can be avoided by disabling auto-negotiation in the KSZ8061,
>     either by the strapping option, or by clearing bit 12 in register 0h.
>     Care must be taken to ensure that the KSZ8061 and the link partner
>     will link with the same speed and duplex. Note that the KSZ8061
>     defaults to full-duplex when auto-negotiation is off, but other
>     devices may default to half-duplex in the event of failed
>     auto-negotiation.
> 3.  The issue can be avoided by connecting the cable prior to powering-up
>     or resetting the KSZ8061, and leaving it plugged in thereafter.
> 4.  If the above measures are not taken and the problem occurs, link can
>     be recovered by setting the Restart Auto-Negotiation bit in
>     register 0h, or by resetting or power cycling the device. Reset may
>     be either hardware reset or software reset (register 0h, bit 15).
> 
> PLAN
> This errata will not be corrected in a future revision.
> 
> Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
> ---
>  drivers/net/phy/micrel.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 
> 6c45ff6..7d80a00 100644
> --- a/drivers/net/phy/micrel.c
> +++ b/drivers/net/phy/micrel.c
> @@ -339,6 +339,28 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
>  	return genphy_config_aneg(phydev);
>  }
>  
> +#define MII_KSZ8061RN_MMD_CTRL_REG	    0x0d
> +#define MII_KSZ8061RN_MMD_REGDATA_REG	0x0e
> +
> +static int ksz8061_extended_write(struct phy_device *phydev,
> +				  u8 mode, u32 dev_addr, u32 regnum, u16 val) {
> +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, dev_addr);
> +	phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, regnum);
> +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
> +	return phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, val); }

Hi Alexander

This looks a lot like phy_write_mmd().

     Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
  2018-06-06  8:03 Alexander Onnasch
@ 2018-06-06 12:39 ` Andrew Lunn
  2018-06-19 14:23   ` Onnasch, Alexander (EXT)
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Lunn @ 2018-06-06 12:39 UTC (permalink / raw)
  To: Alexander Onnasch; +Cc: Florian Fainelli, netdev, linux-kernel

On Wed, Jun 06, 2018 at 10:03:18AM +0200, Alexander Onnasch wrote:
> With Micrel KSZ8061 PHY, the link may occasionally not come up after
> Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
> sheet 80000688A.pdf describes the problem and possible workarounds in
> detail, see below.
> The patch implements workaround 1, which permanently fixes the issue.
> 
> DESCRIPTION
> Link-up may not occur properly when the Ethernet cable is initially
> connected. This issue occurs more commonly when the cable is connected
> slowly, but it may occur any time a cable is connected. This issue occurs
> in the auto-negotiation circuit, and will not occur if auto-negotiation
> is disabled (which requires that the two link partners be set to the
> same speed and duplex).
> 
> END USER IMPLICATIONS
> When this issue occurs, link is not established. Subsequent cable
> plug/unplug cycles will not correct the issue.
> 
> WORK AROUND
> There are four approaches to work around this issue:
> 1.  This issue can be prevented by setting bit 15 in MMD device address 1,
>     register 2, prior to connecting the  cable or prior to setting the
>     Restart Auto-Negotiation bit in register 0h.The MMD registers are
>     accessed via the indirect access registers Dh and Eh, or via the Micrel
>     EthUtil utility as shown here:
>     •  If using the EthUtil utility (usually with a Micrel KSZ8061
>        Evaluation Board), type the following commands:
>        > address 1
>        > mmd 1
>        > iw 2 b61a
>     •  Alternatively, write the following registers to write to the
>        indirect MMD register:
>        Write register Dh, data 0001h
>        Write register Eh, data 0002h
>        Write register Dh, data 4001h
>        Write register Eh, data B61Ah
> 2.  The issue can be avoided by disabling auto-negotiation in the KSZ8061,
>     either by the strapping option, or by clearing bit 12 in register 0h.
>     Care must be taken to ensure that the KSZ8061 and the link partner
>     will link with the same speed and duplex. Note that the KSZ8061
>     defaults to full-duplex when auto-negotiation is off, but other
>     devices may default to half-duplex in the event of failed
>     auto-negotiation.
> 3.  The issue can be avoided by connecting the cable prior to powering-up
>     or resetting the KSZ8061, and leaving it plugged in thereafter.
> 4.  If the above measures are not taken and the problem occurs, link can
>     be recovered by setting the Restart Auto-Negotiation bit in
>     register 0h, or by resetting or power cycling the device. Reset may
>     be either hardware reset or software reset (register 0h, bit 15).
> 
> PLAN
> This errata will not be corrected in a future revision.
> 
> Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
> ---
>  drivers/net/phy/micrel.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
> index 6c45ff6..7d80a00 100644
> --- a/drivers/net/phy/micrel.c
> +++ b/drivers/net/phy/micrel.c
> @@ -339,6 +339,28 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
>  	return genphy_config_aneg(phydev);
>  }
>  
> +#define MII_KSZ8061RN_MMD_CTRL_REG	    0x0d
> +#define MII_KSZ8061RN_MMD_REGDATA_REG	0x0e
> +
> +static int ksz8061_extended_write(struct phy_device *phydev,
> +				  u8 mode, u32 dev_addr, u32 regnum, u16 val)
> +{
> +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, dev_addr);
> +	phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, regnum);
> +	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
> +	return phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, val);
> +}

Hi Alexander

This looks a lot like phy_write_mmd().

     Andrew

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect
@ 2018-06-06  8:03 Alexander Onnasch
  2018-06-06 12:39 ` Andrew Lunn
  0 siblings, 1 reply; 10+ messages in thread
From: Alexander Onnasch @ 2018-06-06  8:03 UTC (permalink / raw)
  Cc: alexander.onnasch, Andrew Lunn, Florian Fainelli, netdev, linux-kernel

With Micrel KSZ8061 PHY, the link may occasionally not come up after
Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
sheet 80000688A.pdf describes the problem and possible workarounds in
detail, see below.
The patch implements workaround 1, which permanently fixes the issue.

DESCRIPTION
Link-up may not occur properly when the Ethernet cable is initially
connected. This issue occurs more commonly when the cable is connected
slowly, but it may occur any time a cable is connected. This issue occurs
in the auto-negotiation circuit, and will not occur if auto-negotiation
is disabled (which requires that the two link partners be set to the
same speed and duplex).

END USER IMPLICATIONS
When this issue occurs, link is not established. Subsequent cable
plug/unplug cycles will not correct the issue.

WORK AROUND
There are four approaches to work around this issue:
1.  This issue can be prevented by setting bit 15 in MMD device address 1,
    register 2, prior to connecting the  cable or prior to setting the
    Restart Auto-Negotiation bit in register 0h.The MMD registers are
    accessed via the indirect access registers Dh and Eh, or via the Micrel
    EthUtil utility as shown here:
    •  If using the EthUtil utility (usually with a Micrel KSZ8061
       Evaluation Board), type the following commands:
       > address 1
       > mmd 1
       > iw 2 b61a
    •  Alternatively, write the following registers to write to the
       indirect MMD register:
       Write register Dh, data 0001h
       Write register Eh, data 0002h
       Write register Dh, data 4001h
       Write register Eh, data B61Ah
2.  The issue can be avoided by disabling auto-negotiation in the KSZ8061,
    either by the strapping option, or by clearing bit 12 in register 0h.
    Care must be taken to ensure that the KSZ8061 and the link partner
    will link with the same speed and duplex. Note that the KSZ8061
    defaults to full-duplex when auto-negotiation is off, but other
    devices may default to half-duplex in the event of failed
    auto-negotiation.
3.  The issue can be avoided by connecting the cable prior to powering-up
    or resetting the KSZ8061, and leaving it plugged in thereafter.
4.  If the above measures are not taken and the problem occurs, link can
    be recovered by setting the Restart Auto-Negotiation bit in
    register 0h, or by resetting or power cycling the device. Reset may
    be either hardware reset or software reset (register 0h, bit 15).

PLAN
This errata will not be corrected in a future revision.

Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
---
 drivers/net/phy/micrel.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 6c45ff6..7d80a00 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -339,6 +339,28 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
 	return genphy_config_aneg(phydev);
 }
 
+#define MII_KSZ8061RN_MMD_CTRL_REG	    0x0d
+#define MII_KSZ8061RN_MMD_REGDATA_REG	0x0e
+
+static int ksz8061_extended_write(struct phy_device *phydev,
+				  u8 mode, u32 dev_addr, u32 regnum, u16 val)
+{
+	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, dev_addr);
+	phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, regnum);
+	phy_write(phydev, MII_KSZ8061RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
+	return phy_write(phydev, MII_KSZ8061RN_MMD_REGDATA_REG, val);
+}
+
+static int ksz8061_config_init(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = ksz8061_extended_write(phydev, 0x1, 0x1, 0x2, 0xB61A);
+	if (ret)
+		return ret;
+	return kszphy_config_init(phydev);
+}
+
 static int ksz9021_load_values_from_of(struct phy_device *phydev,
 				       const struct device_node *of_node,
 				       u16 reg,
@@ -938,7 +960,7 @@ static struct phy_driver ksphy_driver[] = {
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
-	.config_init	= kszphy_config_init,
+	.config_init	= ksz8061_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= kszphy_ack_interrupt,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-08-13 10:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-30 14:01 [PATCH] net/phy: Micrel KSZ8061 PHY link failure after cable connect Alexander Onnasch
2018-07-30 14:06 ` Andrew Lunn
2018-07-30 16:45 ` David Miller
2018-08-13 10:41   ` Onnasch, Alexander (EXT)
  -- strict thread matches above, loose matches on Subject: below --
2018-06-06  8:03 Alexander Onnasch
2018-06-06 12:39 ` Andrew Lunn
2018-06-19 14:23   ` Onnasch, Alexander (EXT)
2018-06-19 15:28     ` Andrew Lunn
2018-07-30 14:00       ` Onnasch, Alexander (EXT)
2018-07-30 14:03         ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).