Add driver support for 88E3016 PHY which is found on Marvell Yukon

FE+ controller. Due to the severe silicon bugs for Yukon FE+,
88E3016 seems to require more workarounds. However I'm not sure
whether the workaround is PHY specific or only applicable to Yukon
FE+. The datasheet for the PHY is publicly available but it lacks
several details for the workaround used in this change. The
workaround information was obtained from Linux. Many thanks to
Yukon FE+ users who helped me add 88E3016 support.

Tested by:	bz, Tanguy Bouzeloc ( the.zauron <> gmail dot com )
		Bruce Cran ( bruce <> cran dot org dot uk )
		Michael Reifenberger ( mike <> reifenberger dot com )
		Stephen Montgomery-Smith ( stephen <> missouri dot edu )
This commit is contained in:
Pyun YongHyeon 2009-05-25 02:36:29 +00:00
parent 2c56cee9e4
commit 745ef56af2
3 changed files with 34 additions and 4 deletions

View File

@ -107,6 +107,7 @@ static const struct mii_phydesc e1000phys[] = {
MII_PHY_DESC(MARVELL, E1116),
MII_PHY_DESC(MARVELL, E1116R),
MII_PHY_DESC(MARVELL, E1118),
MII_PHY_DESC(MARVELL, E3016),
MII_PHY_DESC(xxMARVELL, E1000),
MII_PHY_DESC(xxMARVELL, E1011),
MII_PHY_DESC(xxMARVELL, E1000_3),
@ -212,18 +213,29 @@ e1000phy_reset(struct mii_softc *sc)
reg |= E1000_SCR_AUTO_X_MODE;
if (esc->mii_model == MII_MODEL_MARVELL_E1116)
reg &= ~E1000_SCR_POWER_DOWN;
reg |= E1000_SCR_ASSERT_CRS_ON_TX;
break;
case MII_MODEL_MARVELL_E3082:
reg |= (E1000_SCR_AUTO_X_MODE >> 1);
reg |= E1000_SCR_ASSERT_CRS_ON_TX;
break;
case MII_MODEL_MARVELL_E3016:
reg |= E1000_SCR_AUTO_MDIX;
reg &= ~(E1000_SCR_EN_DETECT |
E1000_SCR_SCRAMBLER_DISABLE);
reg |= E1000_SCR_LPNP;
/* XXX Enable class A driver for Yukon FE+ A0. */
PHY_WRITE(sc, 0x1C, PHY_READ(sc, 0x1C) | 0x0001);
break;
default:
reg &= ~E1000_SCR_AUTO_X_MODE;
reg |= E1000_SCR_ASSERT_CRS_ON_TX;
break;
}
/* Enable CRS on TX. */
reg |= E1000_SCR_ASSERT_CRS_ON_TX;
/* Auto correction for reversed cable polarity. */
reg &= ~E1000_SCR_POLARITY_REVERSAL;
if (esc->mii_model != MII_MODEL_MARVELL_E3016) {
/* Auto correction for reversed cable polarity. */
reg &= ~E1000_SCR_POLARITY_REVERSAL;
}
PHY_WRITE(sc, E1000_SCR, reg);
if (esc->mii_model == MII_MODEL_MARVELL_E1116) {
@ -242,6 +254,13 @@ e1000phy_reset(struct mii_softc *sc)
case MII_MODEL_MARVELL_E1118:
case MII_MODEL_MARVELL_E1149:
break;
case MII_MODEL_MARVELL_E3016:
/* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */
PHY_WRITE(sc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04);
/* Integrated register calibration workaround. */
PHY_WRITE(sc, 0x1D, 17);
PHY_WRITE(sc, 0x1E, 0x3F60);
break;
default:
/* Force TX_CLK to 25MHz clock. */
reg = PHY_READ(sc, E1000_ESCR);

View File

@ -236,6 +236,16 @@
#define E1000_SCR_TX_FIFO_DEPTH_10 0x8000
#define E1000_SCR_TX_FIFO_DEPTH_12 0xC000
/* 88E3016 only */
#define E1000_SCR_AUTO_MDIX 0x0030
#define E1000_SCR_SIGDET_POLARITY 0x0040
#define E1000_SCR_EXT_DISTANCE 0x0080
#define E1000_SCR_FEFI_DISABLE 0x0100
#define E1000_SCR_NLP_GEN_DISABLE 0x0800
#define E1000_SCR_LPNP 0x1000
#define E1000_SCR_NLP_CHK_DISABLE 0x2000
#define E1000_SCR_EN_DETECT 0x4000
#define E1000_SCR_EN_DETECT_MASK 0x0300
/* 88E1112 page 2 */

View File

@ -247,6 +247,7 @@ model MARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY
model MARVELL E1116 0x0021 Marvell 88E1116 Gigabit PHY
model MARVELL E1116R 0x0024 Marvell 88E1116R Gigabit PHY
model MARVELL E1118 0x0022 Marvell 88E1118 Gigabit PHY
model MARVELL E3016 0x0026 Marvell 88E3016 10/100 Fast Ethernet PHY
model xxMARVELL E1000 0x0005 Marvell 88E1000 Gigabit PHY
model xxMARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY
model xxMARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY