diff options
author | Harini Katakam <harini.katakam@xilinx.com> | 2016-06-27 03:39:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-29 04:07:36 -0400 |
commit | 3ec0a0f10ceb77c78f540ded1d13bf0cf7f89a07 (patch) | |
tree | 7eb8838a7e169ea92cea1dfde69b3b0892c2fe43 | |
parent | d10f0b312adc21b9b78e36cf695e6157989ce041 (diff) |
net: marvell: Add separate config ANEG function for Marvell 88E1111
Marvell 88E1111 currently uses the generic marvell config ANEG function.
This function has a sequence accessing Page 5 and Register 31,
both of which are not defined or reserved for this PHY.
Hence this patch adds a new config ANEG function for Marvell 88E1111
without these erroneous accesses.
Signed-off-by: Harini Katakam <harinik@xilinx.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/marvell.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 79ccc11facc3..ec2c1eee6405 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
@@ -285,6 +285,48 @@ static int marvell_config_aneg(struct phy_device *phydev) | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | static int m88e1111_config_aneg(struct phy_device *phydev) | ||
289 | { | ||
290 | int err; | ||
291 | |||
292 | /* The Marvell PHY has an errata which requires | ||
293 | * that certain registers get written in order | ||
294 | * to restart autonegotiation | ||
295 | */ | ||
296 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
297 | |||
298 | err = marvell_set_polarity(phydev, phydev->mdix); | ||
299 | if (err < 0) | ||
300 | return err; | ||
301 | |||
302 | err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, | ||
303 | MII_M1111_PHY_LED_DIRECT); | ||
304 | if (err < 0) | ||
305 | return err; | ||
306 | |||
307 | err = genphy_config_aneg(phydev); | ||
308 | if (err < 0) | ||
309 | return err; | ||
310 | |||
311 | if (phydev->autoneg != AUTONEG_ENABLE) { | ||
312 | int bmcr; | ||
313 | |||
314 | /* A write to speed/duplex bits (that is performed by | ||
315 | * genphy_config_aneg() call above) must be followed by | ||
316 | * a software reset. Otherwise, the write has no effect. | ||
317 | */ | ||
318 | bmcr = phy_read(phydev, MII_BMCR); | ||
319 | if (bmcr < 0) | ||
320 | return bmcr; | ||
321 | |||
322 | err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET); | ||
323 | if (err < 0) | ||
324 | return err; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
288 | #ifdef CONFIG_OF_MDIO | 330 | #ifdef CONFIG_OF_MDIO |
289 | /* | 331 | /* |
290 | * Set and/or override some configuration registers based on the | 332 | * Set and/or override some configuration registers based on the |
@@ -1175,7 +1217,7 @@ static struct phy_driver marvell_drivers[] = { | |||
1175 | .flags = PHY_HAS_INTERRUPT, | 1217 | .flags = PHY_HAS_INTERRUPT, |
1176 | .probe = marvell_probe, | 1218 | .probe = marvell_probe, |
1177 | .config_init = &m88e1111_config_init, | 1219 | .config_init = &m88e1111_config_init, |
1178 | .config_aneg = &marvell_config_aneg, | 1220 | .config_aneg = &m88e1111_config_aneg, |
1179 | .read_status = &marvell_read_status, | 1221 | .read_status = &marvell_read_status, |
1180 | .ack_interrupt = &marvell_ack_interrupt, | 1222 | .ack_interrupt = &marvell_ack_interrupt, |
1181 | .config_intr = &marvell_config_intr, | 1223 | .config_intr = &marvell_config_intr, |