| From foo@baz Wed May 31 09:13:34 JST 2017 |
| From: Andrew Lunn <andrew@lunn.ch> |
| Date: Tue, 23 May 2017 17:49:13 +0200 |
| Subject: net: phy: marvell: Limit errata to 88m1101 |
| |
| From: Andrew Lunn <andrew@lunn.ch> |
| |
| |
| [ Upstream commit f2899788353c13891412b273fdff5f02d49aa40f ] |
| |
| The 88m1101 has an errata when configuring autoneg. However, it was |
| being applied to many other Marvell PHYs as well. Limit its scope to |
| just the 88m1101. |
| |
| Fixes: 76884679c644 ("phylib: Add support for Marvell 88e1111S and 88e1145") |
| Reported-by: Daniel Walker <danielwa@cisco.com> |
| Signed-off-by: Andrew Lunn <andrew@lunn.ch> |
| Acked-by: Harini Katakam <harinik@xilinx.com> |
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/phy/marvell.c | 66 +++++++++++++++++++++++++--------------------- |
| 1 file changed, 37 insertions(+), 29 deletions(-) |
| |
| --- a/drivers/net/phy/marvell.c |
| +++ b/drivers/net/phy/marvell.c |
| @@ -240,34 +240,6 @@ static int marvell_config_aneg(struct ph |
| { |
| int err; |
| |
| - /* The Marvell PHY has an errata which requires |
| - * that certain registers get written in order |
| - * to restart autonegotiation */ |
| - err = phy_write(phydev, MII_BMCR, BMCR_RESET); |
| - |
| - if (err < 0) |
| - return err; |
| - |
| - err = phy_write(phydev, 0x1d, 0x1f); |
| - if (err < 0) |
| - return err; |
| - |
| - err = phy_write(phydev, 0x1e, 0x200c); |
| - if (err < 0) |
| - return err; |
| - |
| - err = phy_write(phydev, 0x1d, 0x5); |
| - if (err < 0) |
| - return err; |
| - |
| - err = phy_write(phydev, 0x1e, 0); |
| - if (err < 0) |
| - return err; |
| - |
| - err = phy_write(phydev, 0x1e, 0x100); |
| - if (err < 0) |
| - return err; |
| - |
| err = marvell_set_polarity(phydev, phydev->mdix); |
| if (err < 0) |
| return err; |
| @@ -301,6 +273,42 @@ static int marvell_config_aneg(struct ph |
| return 0; |
| } |
| |
| +static int m88e1101_config_aneg(struct phy_device *phydev) |
| +{ |
| + int err; |
| + |
| + /* This Marvell PHY has an errata which requires |
| + * that certain registers get written in order |
| + * to restart autonegotiation |
| + */ |
| + err = phy_write(phydev, MII_BMCR, BMCR_RESET); |
| + |
| + if (err < 0) |
| + return err; |
| + |
| + err = phy_write(phydev, 0x1d, 0x1f); |
| + if (err < 0) |
| + return err; |
| + |
| + err = phy_write(phydev, 0x1e, 0x200c); |
| + if (err < 0) |
| + return err; |
| + |
| + err = phy_write(phydev, 0x1d, 0x5); |
| + if (err < 0) |
| + return err; |
| + |
| + err = phy_write(phydev, 0x1e, 0); |
| + if (err < 0) |
| + return err; |
| + |
| + err = phy_write(phydev, 0x1e, 0x100); |
| + if (err < 0) |
| + return err; |
| + |
| + return marvell_config_aneg(phydev); |
| +} |
| + |
| static int m88e1111_config_aneg(struct phy_device *phydev) |
| { |
| int err; |
| @@ -1491,7 +1499,7 @@ static struct phy_driver marvell_drivers |
| .probe = marvell_probe, |
| .flags = PHY_HAS_INTERRUPT, |
| .config_init = &marvell_config_init, |
| - .config_aneg = &marvell_config_aneg, |
| + .config_aneg = &m88e1101_config_aneg, |
| .read_status = &genphy_read_status, |
| .ack_interrupt = &marvell_ack_interrupt, |
| .config_intr = &marvell_config_intr, |