diff options
Diffstat (limited to 'drivers/net/phy/marvell.c')
-rw-r--r-- | drivers/net/phy/marvell.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 225c033..1b1698f 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -54,6 +54,9 @@ #define MII_M1145_PHY_EXT_CR 0x14 #define MII_M1145_RGMII_RX_DELAY 0x0080 #define MII_M1145_RGMII_TX_DELAY 0x0002 +#define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 +#define MII_M1145_HWCFG_MODE_MASK 0xf +#define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 #define MII_M1145_HWCFG_MODE_MASK 0xf @@ -123,6 +126,9 @@ #define MII_M1116R_CONTROL_REG_MAC 21 +#define MII_88E3016_PHY_SPEC_CTRL 0x10 +#define MII_88E3016_DISABLE_SCRAMBLER 0x0200 +#define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030 MODULE_DESCRIPTION("Marvell PHY driver"); MODULE_AUTHOR("Andy Fleming"); @@ -439,6 +445,25 @@ static int m88e1116r_config_init(struct phy_device *phydev) return 0; } +static int m88e3016_config_init(struct phy_device *phydev) +{ + int reg; + + /* Enable Scrambler and Auto-Crossover */ + reg = phy_read(phydev, MII_88E3016_PHY_SPEC_CTRL); + if (reg < 0) + return reg; + + reg &= ~MII_88E3016_DISABLE_SCRAMBLER; + reg |= MII_88E3016_AUTO_MDIX_CROSSOVER; + + reg = phy_write(phydev, MII_88E3016_PHY_SPEC_CTRL, reg); + if (reg < 0) + return reg; + + return 0; +} + static int m88e1111_config_init(struct phy_device *phydev) { int err; @@ -625,6 +650,7 @@ static int m88e1149_config_init(struct phy_device *phydev) static int m88e1145_config_init(struct phy_device *phydev) { int err; + int temp; /* Take care of errata E0 & E1 */ err = phy_write(phydev, 0x1d, 0x001b); @@ -682,7 +708,7 @@ static int m88e1145_config_init(struct phy_device *phydev) } if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { - int temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); + temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); if (temp < 0) return temp; @@ -789,6 +815,12 @@ static int marvell_read_status(struct phy_device *phydev) return 0; } +static int marvell_aneg_done(struct phy_device *phydev) +{ + int retval = phy_read(phydev, MII_M1011_PHY_STATUS); + return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED); +} + static int m88e1121_did_interrupt(struct phy_device *phydev) { int imask; @@ -1069,22 +1101,26 @@ static struct phy_driver marvell_drivers[] = { .suspend = &genphy_suspend, .driver = { .owner = THIS_MODULE }, }, + { + .phy_id = MARVELL_PHY_ID_88E3016, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E3016", + .features = PHY_BASIC_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_aneg = &genphy_config_aneg, + .config_init = &m88e3016_config_init, + .aneg_done = &marvell_aneg_done, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .did_interrupt = &m88e1121_did_interrupt, + .resume = &genphy_resume, + .suspend = &genphy_suspend, + .driver = { .owner = THIS_MODULE }, + }, }; -static int __init marvell_init(void) -{ - return phy_drivers_register(marvell_drivers, - ARRAY_SIZE(marvell_drivers)); -} - -static void __exit marvell_exit(void) -{ - phy_drivers_unregister(marvell_drivers, - ARRAY_SIZE(marvell_drivers)); -} - -module_init(marvell_init); -module_exit(marvell_exit); +module_phy_driver(marvell_drivers); static struct mdio_device_id __maybe_unused marvell_tbl[] = { { MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK }, @@ -1098,6 +1134,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = { { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, { } }; |