diff options
Diffstat (limited to 'drivers/net/phy/marvell.c')
-rw-r--r-- | drivers/net/phy/marvell.c | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 280e8795b463..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 |
@@ -407,15 +449,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev) | |||
407 | if (err < 0) | 449 | if (err < 0) |
408 | return err; | 450 | return err; |
409 | 451 | ||
410 | oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); | 452 | return genphy_config_aneg(phydev); |
411 | |||
412 | phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); | ||
413 | phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); | ||
414 | phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); | ||
415 | |||
416 | err = genphy_config_aneg(phydev); | ||
417 | |||
418 | return err; | ||
419 | } | 453 | } |
420 | 454 | ||
421 | static int m88e1318_config_aneg(struct phy_device *phydev) | 455 | static int m88e1318_config_aneg(struct phy_device *phydev) |
@@ -636,6 +670,28 @@ static int m88e1111_config_init(struct phy_device *phydev) | |||
636 | return phy_write(phydev, MII_BMCR, BMCR_RESET); | 670 | return phy_write(phydev, MII_BMCR, BMCR_RESET); |
637 | } | 671 | } |
638 | 672 | ||
673 | static int m88e1121_config_init(struct phy_device *phydev) | ||
674 | { | ||
675 | int err, oldpage; | ||
676 | |||
677 | oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); | ||
678 | |||
679 | err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); | ||
680 | if (err < 0) | ||
681 | return err; | ||
682 | |||
683 | /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */ | ||
684 | err = phy_write(phydev, MII_88E1121_PHY_LED_CTRL, | ||
685 | MII_88E1121_PHY_LED_DEF); | ||
686 | if (err < 0) | ||
687 | return err; | ||
688 | |||
689 | phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); | ||
690 | |||
691 | /* Set marvell,reg-init configuration from device tree */ | ||
692 | return marvell_config_init(phydev); | ||
693 | } | ||
694 | |||
639 | static int m88e1510_config_init(struct phy_device *phydev) | 695 | static int m88e1510_config_init(struct phy_device *phydev) |
640 | { | 696 | { |
641 | int err; | 697 | int err; |
@@ -668,7 +724,7 @@ static int m88e1510_config_init(struct phy_device *phydev) | |||
668 | return err; | 724 | return err; |
669 | } | 725 | } |
670 | 726 | ||
671 | return marvell_config_init(phydev); | 727 | return m88e1121_config_init(phydev); |
672 | } | 728 | } |
673 | 729 | ||
674 | static int m88e1118_config_aneg(struct phy_device *phydev) | 730 | static int m88e1118_config_aneg(struct phy_device *phydev) |
@@ -1161,7 +1217,7 @@ static struct phy_driver marvell_drivers[] = { | |||
1161 | .flags = PHY_HAS_INTERRUPT, | 1217 | .flags = PHY_HAS_INTERRUPT, |
1162 | .probe = marvell_probe, | 1218 | .probe = marvell_probe, |
1163 | .config_init = &m88e1111_config_init, | 1219 | .config_init = &m88e1111_config_init, |
1164 | .config_aneg = &marvell_config_aneg, | 1220 | .config_aneg = &m88e1111_config_aneg, |
1165 | .read_status = &marvell_read_status, | 1221 | .read_status = &marvell_read_status, |
1166 | .ack_interrupt = &marvell_ack_interrupt, | 1222 | .ack_interrupt = &marvell_ack_interrupt, |
1167 | .config_intr = &marvell_config_intr, | 1223 | .config_intr = &marvell_config_intr, |
@@ -1196,7 +1252,7 @@ static struct phy_driver marvell_drivers[] = { | |||
1196 | .features = PHY_GBIT_FEATURES, | 1252 | .features = PHY_GBIT_FEATURES, |
1197 | .flags = PHY_HAS_INTERRUPT, | 1253 | .flags = PHY_HAS_INTERRUPT, |
1198 | .probe = marvell_probe, | 1254 | .probe = marvell_probe, |
1199 | .config_init = &marvell_config_init, | 1255 | .config_init = &m88e1121_config_init, |
1200 | .config_aneg = &m88e1121_config_aneg, | 1256 | .config_aneg = &m88e1121_config_aneg, |
1201 | .read_status = &marvell_read_status, | 1257 | .read_status = &marvell_read_status, |
1202 | .ack_interrupt = &marvell_ack_interrupt, | 1258 | .ack_interrupt = &marvell_ack_interrupt, |
@@ -1215,7 +1271,7 @@ static struct phy_driver marvell_drivers[] = { | |||
1215 | .features = PHY_GBIT_FEATURES, | 1271 | .features = PHY_GBIT_FEATURES, |
1216 | .flags = PHY_HAS_INTERRUPT, | 1272 | .flags = PHY_HAS_INTERRUPT, |
1217 | .probe = marvell_probe, | 1273 | .probe = marvell_probe, |
1218 | .config_init = &marvell_config_init, | 1274 | .config_init = &m88e1121_config_init, |
1219 | .config_aneg = &m88e1318_config_aneg, | 1275 | .config_aneg = &m88e1318_config_aneg, |
1220 | .read_status = &marvell_read_status, | 1276 | .read_status = &marvell_read_status, |
1221 | .ack_interrupt = &marvell_ack_interrupt, | 1277 | .ack_interrupt = &marvell_ack_interrupt, |