diff options
Diffstat (limited to 'drivers/net/phy/marvell.c')
| -rw-r--r-- | drivers/net/phy/marvell.c | 84 | 
1 files changed, 70 insertions, 14 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index bd37e45c89c0..1b1698f98818 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -50,9 +50,17 @@  #define MII_M1011_PHY_SCR		0x10  #define MII_M1011_PHY_SCR_AUTO_CROSS	0x0060 +#define MII_M1145_PHY_EXT_SR		0x1b  #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 +#define MII_M1145_HWCFG_FIBER_COPPER_AUTO	0x8000  #define MII_M1111_PHY_LED_CONTROL	0x18  #define MII_M1111_PHY_LED_DIRECT	0x4100 @@ -118,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"); @@ -434,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; @@ -620,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); @@ -676,6 +707,20 @@ static int m88e1145_config_init(struct phy_device *phydev)  		}  	} +	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { +		temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); +		if (temp < 0) +			return temp; + +		temp &= ~MII_M1145_HWCFG_MODE_MASK; +		temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK; +		temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO; + +		err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp); +		if (err < 0) +			return err; +	} +  	err = marvell_of_reg_init(phydev);  	if (err < 0)  		return err; @@ -770,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; @@ -1050,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 }, @@ -1079,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 },  	{ }  };  | 
