Hi Igor,
Am Donnerstag, 13. August 2015, 22:18:34 schrieben Sie:
> * Due to HW bug, LAN8700 sometimes does not detect presence of energy in the
> Ethernet cable in Energy Detect Power-Down mode (e.g while EDPWRDOWN bit is
> set, the ENERGYON bit does not asserted sometimes). This is a common bug of
> LAN87xx family of PHY chips.
Is there any offical errata sheet for this PHY family? How do you know, that this is a
common HW bug?
Me too, I think that this family has some problems with this mode, however, without
hard evidence, I would put it softer.
> * The lan87xx_read_status() was improved to acquire ENERGYON bit. Its previous
> algorythm still not reliable on 100 % and sometimes skip cable plugging.
>
> Signed-off-by: Igor Plyatov <plyatov@xxxxxxxxx>
> ---
> drivers/net/phy/smsc.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
> index c0f6479..8559ff1 100644
> --- a/drivers/net/phy/smsc.c
> +++ b/drivers/net/phy/smsc.c
> @@ -104,6 +104,7 @@ static int lan911x_config_init(struct phy_device *phydev)
> static int lan87xx_read_status(struct phy_device *phydev)
> {
> int err = genphy_read_status(phydev);
> + int i;
>
> if (!phydev->link) {
> /* Disable EDPD to wake up PHY */
> @@ -116,8 +117,16 @@ static int lan87xx_read_status(struct phy_device *phydev)
> if (rc < 0)
> return rc;
>
> - /* Sleep 64 ms to allow ~5 link test pulses to be sent */
> - msleep(64);
> + /* Wait max 640 ms to detect energy */
Why 640ms and not e.g. 650ms?
I'm no PHY expert, but this looks like an ugly workaround.
Maybe it would be better to avoid this power saving mode at all, when it is not
reliable, but this are just my 2cts. :-)
Anyway, I guess you should also update the explanation on top of the function to reflect
your new approach.
> + for (i = 0; i < 64; i++) {
> + /* Sleep to allow link test pulses to be sent */
> + msleep(10);
> + rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
> + if (rc < 0)
> + return rc;
> + if (rc & MII_LAN83C185_ENERGYON)
> + break;
> + };
>
> /* Re-enable EDPD */
> rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
> @@ -191,7 +200,7 @@ static struct phy_driver smsc_phy_driver[] = {
>
> /* basic functions */
> .config_aneg = genphy_config_aneg,
> - .read_status = genphy_read_status,
> + .read_status = lan87xx_read_status,
This one makes sense, since I really guess, that the whole PHY family behave very similar.
But this change alone does not solve your problem, right?
> .config_init = smsc_phy_config_init,
> .soft_reset = smsc_phy_reset,
>
>
Regards,
Michael