From 4878ad35123a4a56872ce0fb8cf9ba90282aeeb9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:14 +0100 Subject: net/phy: marvell: rename 88E1545 to 88E1540 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Linux driver calls it 88E1540 so do it here, too. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 9a963f6d5e..4bf8bae59a 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -266,9 +266,9 @@ static struct phy_driver marvell_phys[] = { .read_status = marvell_read_status, }, { - .phy_id = MARVELL_PHY_ID_88E1545, + .phy_id = MARVELL_PHY_ID_88E1540, .phy_id_mask = MARVELL_PHY_ID_MASK, - .drv.name = "Marvell 88E1545", + .drv.name = "Marvell 88E1540", .features = PHY_GBIT_FEATURES, .config_init = m88e1540_config_init, .config_aneg = genphy_config_aneg, -- cgit v1.2.3 From db4b34e77128d30965a29873c4e3f81ceb55825e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:15 +0100 Subject: net/phy: marvell: 88E1540 LED registers already exist on 88E1121 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So rename accordingly to match the definition used by Linux Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 4bf8bae59a..c4d9c7fe49 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -19,6 +19,9 @@ #define MII_M1011_PHY_SCR 0x10 #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 +#define MII_88E1121_PHY_LED_CTRL 16 +#define MII_88E1121_PHY_LED_PAGE 3 + #define MII_M1011_PHY_STATUS 0x11 #define MII_M1011_PHY_STATUS_1000 BIT(15) #define MII_M1011_PHY_STATUS_100 BIT(14) @@ -38,9 +41,6 @@ #define MII_88E1318S_PHY_MSCR1_REG 16 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6) -#define MII_88E1540_LED_PAGE 0x3 -#define MII_88E1540_LED_CONTROL 0x10 - #define MII_88E1540_QSGMII_PAGE 0x4 #define MII_88E1540_QSGMII_CONTROL 0x0 #define MII_88E1540_QSGMII_AUTONEG_EN BIT(12) @@ -157,8 +157,8 @@ static int m88e1540_config_init(struct phy_device *phydev) * Link: On * No Link: Off */ - phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1540_LED_PAGE); - phy_write(phydev, MII_88E1540_LED_CONTROL, 0x1111); + phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); + phy_write(phydev, MII_88E1121_PHY_LED_CTRL, 0x1111); /* Power-up the PHY. When going from power down to normal operation, * software reset and auto-negotiation restart are also performed. -- cgit v1.2.3 From 21b30a200977bd397704eab778bc52e921b2f3e3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:16 +0100 Subject: net/phy: marvell: rename phy_driver array to match Linux driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index c4d9c7fe49..ee95c2db57 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -237,7 +237,7 @@ static int m88e1318s_config_init(struct phy_device *phydev) return m88e1121_config_init(phydev); } -static struct phy_driver marvell_phys[] = { +static struct phy_driver marvell_drivers[] = { { .phy_id = MARVELL_PHY_ID_88E1121R, .phy_id_mask = MARVELL_PHY_ID_MASK, @@ -278,6 +278,7 @@ static struct phy_driver marvell_phys[] = { static int __init marvell_phy_init(void) { - return phy_drivers_register(marvell_phys, ARRAY_SIZE(marvell_phys)); + return phy_drivers_register(marvell_drivers, + ARRAY_SIZE(marvell_drivers)); } fs_initcall(marvell_phy_init); -- cgit v1.2.3 From a1bfa62c2088671115b0c9e472676c56d346e086 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:17 +0100 Subject: net/phy: marvell: change spacing to be more similar to the Linux driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make the barebox driver more similar to the Linux driver, only use a single space before the = in member initialisation. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index ee95c2db57..e015380676 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -239,40 +239,40 @@ static int m88e1318s_config_init(struct phy_device *phydev) static struct phy_driver marvell_drivers[] = { { - .phy_id = MARVELL_PHY_ID_88E1121R, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .drv.name = "Marvell 88E1121R", - .features = PHY_GBIT_FEATURES, - .config_init = m88e1121_config_init, - .config_aneg = genphy_config_aneg, - .read_status = marvell_read_status, + .phy_id = MARVELL_PHY_ID_88E1121R, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .drv.name = "Marvell 88E1121R", + .features = PHY_GBIT_FEATURES, + .config_init = &m88e1121_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &marvell_read_status, }, { - .phy_id = MARVELL_PHY_ID_88E1318S, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .drv.name = "Marvell 88E1318S", - .features = PHY_GBIT_FEATURES, - .config_init = m88e1318s_config_init, - .config_aneg = genphy_config_aneg, - .read_status = marvell_read_status, + .phy_id = MARVELL_PHY_ID_88E1318S, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .drv.name = "Marvell 88E1318S", + .features = PHY_GBIT_FEATURES, + .config_init = &m88e1318s_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &marvell_read_status, }, { - .phy_id = MARVELL_PHY_ID_88E1543, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .drv.name = "Marvell 88E1543", - .features = PHY_GBIT_FEATURES, - .config_init = m88e1540_config_init, - .config_aneg = genphy_config_aneg, - .read_status = marvell_read_status, + .phy_id = MARVELL_PHY_ID_88E1543, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .drv.name = "Marvell 88E1543", + .features = PHY_GBIT_FEATURES, + .config_init = &m88e1540_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &marvell_read_status, }, { - .phy_id = MARVELL_PHY_ID_88E1540, - .phy_id_mask = MARVELL_PHY_ID_MASK, - .drv.name = "Marvell 88E1540", - .features = PHY_GBIT_FEATURES, - .config_init = m88e1540_config_init, - .config_aneg = genphy_config_aneg, - .read_status = marvell_read_status, + .phy_id = MARVELL_PHY_ID_88E1540, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .drv.name = "Marvell 88E1540", + .features = PHY_GBIT_FEATURES, + .config_init = &m88e1540_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &marvell_read_status, }, }; -- cgit v1.2.3 From 3fd488a7203ed1113ece794c87f63e8048f2d7c4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:18 +0100 Subject: net/phy: marvell: align definition of MII_88E1121_PHY_MSCR to Linux driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index e015380676..d504cf85a1 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -32,7 +32,7 @@ #define MII_M1011_PHY_STATUS_LINK BIT(10) #define MII_88E1121_PHY_MSCR_PAGE 2 -#define MII_88E1121_PHY_MSCR 0x15 +#define MII_88E1121_PHY_MSCR_REG 21 #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) #define MII_88E1121_PHY_MSCR_RX_DELAY BIT(5) #define MII_88E1121_PHY_MSCR_DELAY_MASK \ @@ -186,7 +186,7 @@ static int m88e1121_config_init(struct phy_device *phydev) return ret; /* Setup RGMII TX/RX delay */ - reg = phy_read(phydev, MII_88E1121_PHY_MSCR) & + reg = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & ~MII_88E1121_PHY_MSCR_DELAY_MASK; if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) @@ -194,7 +194,7 @@ static int m88e1121_config_init(struct phy_device *phydev) if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) reg |= MII_88E1121_PHY_MSCR_TX_DELAY; - ret = phy_write(phydev, MII_88E1121_PHY_MSCR, reg); + ret = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, reg); if (ret < 0) return ret; -- cgit v1.2.3 From ebfd737bf94038b1a6ca548d65ca30b0fbd1593f Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:19 +0100 Subject: net/phy: marvell: improve config_aneg for 88E1121R and 88E1318S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is taken from the Linux driver Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index d504cf85a1..6bb50a3a1f 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -133,6 +133,80 @@ static int marvell_read_status(struct phy_device *phydev) return 0; } +static inline bool phy_interface_is_rgmii(struct phy_device *phydev) +{ + return phydev->interface >= PHY_INTERFACE_MODE_RGMII && + phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID; +}; + +static int m88e1121_config_aneg(struct phy_device *phydev) +{ + int err, oldpage, mscr; + + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1121_PHY_MSCR_PAGE); + if (err < 0) + return err; + + if (phy_interface_is_rgmii(phydev)) { + + mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & + MII_88E1121_PHY_MSCR_DELAY_MASK; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | + MII_88E1121_PHY_MSCR_TX_DELAY); + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; + + err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); + if (err < 0) + return err; + } + + phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + if (err < 0) + return err; + + err = phy_write(phydev, MII_M1011_PHY_SCR, + MII_M1011_PHY_SCR_AUTO_CROSS); + if (err < 0) + return err; + + return genphy_config_aneg(phydev); +} + +static int m88e1318_config_aneg(struct phy_device *phydev) +{ + int err, oldpage, mscr; + + oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1121_PHY_MSCR_PAGE); + if (err < 0) + return err; + + mscr = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG); + mscr |= MII_88E1318S_PHY_MSCR1_PAD_ODD; + + err = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, mscr); + if (err < 0) + return err; + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); + if (err < 0) + return err; + + return m88e1121_config_aneg(phydev); +} + static int m88e1540_config_init(struct phy_device *phydev) { u16 reg; @@ -244,7 +318,7 @@ static struct phy_driver marvell_drivers[] = { .drv.name = "Marvell 88E1121R", .features = PHY_GBIT_FEATURES, .config_init = &m88e1121_config_init, - .config_aneg = &genphy_config_aneg, + .config_aneg = &m88e1121_config_aneg, .read_status = &marvell_read_status, }, { @@ -253,7 +327,7 @@ static struct phy_driver marvell_drivers[] = { .drv.name = "Marvell 88E1318S", .features = PHY_GBIT_FEATURES, .config_init = &m88e1318s_config_init, - .config_aneg = &genphy_config_aneg, + .config_aneg = &m88e1318_config_aneg, .read_status = &marvell_read_status, }, { -- cgit v1.2.3 From 2a2ee7aafa9a1fab4e610cfd2967991a35b44ef0 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 11 Jan 2017 16:59:20 +0100 Subject: net/phy: marvell: add support for 88e1510 to marvell phy driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is mostly copied verbatim from the Linux driver. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/net/phy/marvell.c | 204 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 6bb50a3a1f..38b2ad31f8 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -31,6 +31,9 @@ #define MII_M1011_PHY_STATUS_RESOLVED BIT(11) #define MII_M1011_PHY_STATUS_LINK BIT(10) +#define MII_M1111_COPPER 0 +#define MII_M1111_FIBER 1 + #define MII_88E1121_PHY_MSCR_PAGE 2 #define MII_88E1121_PHY_MSCR_REG 21 #define MII_88E1121_PHY_MSCR_TX_DELAY BIT(4) @@ -45,6 +48,20 @@ #define MII_88E1540_QSGMII_CONTROL 0x0 #define MII_88E1540_QSGMII_AUTONEG_EN BIT(12) +#define MII_88E1510_GEN_CTRL_REG_1 0x14 +#define MII_88E1510_GEN_CTRL_REG_1_MODE_MASK 0x7 +#define MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII 0x1 /* SGMII to copper */ +#define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ + +#define LPA_PAUSE_FIBER 0x180 +#define LPA_PAUSE_ASYM_FIBER 0x100 + +#define ADVERTISE_FIBER_1000HALF 0x40 +#define ADVERTISE_FIBER_1000FULL 0x20 + +#define ADVERTISE_PAUSE_FIBER 0x180 +#define ADVERTISE_PAUSE_ASYM_FIBER 0x100 + /* * marvell_read_status * @@ -133,12 +150,24 @@ static int marvell_read_status(struct phy_device *phydev) return 0; } +#define MII_88E1510_GEN_CTRL_REG_1 0x14 + static inline bool phy_interface_is_rgmii(struct phy_device *phydev) { return phydev->interface >= PHY_INTERFACE_MODE_RGMII && phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID; }; +/* + * This same function in the Linux kernel parses the marvell,reg-init dt + * property and does the necessary register writes. It's kept as an exercise for + * a future user to implement this. :-) + */ +static int marvell_of_reg_init(struct phy_device *phydev) +{ + return 0; +} + static int m88e1121_config_aneg(struct phy_device *phydev) { int err, oldpage, mscr; @@ -207,6 +236,130 @@ static int m88e1318_config_aneg(struct phy_device *phydev) return m88e1121_config_aneg(phydev); } +/** + * ethtool_adv_to_fiber_adv_t + * @ethadv: the ethtool advertisement settings + * + * A small helper function that translates ethtool advertisement + * settings to phy autonegotiation advertisements for the + * MII_ADV register for fiber link. + */ +static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv) +{ + u32 result = 0; + + if (ethadv & ADVERTISED_1000baseT_Half) + result |= ADVERTISE_FIBER_1000HALF; + if (ethadv & ADVERTISED_1000baseT_Full) + result |= ADVERTISE_FIBER_1000FULL; + + if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP)) + result |= LPA_PAUSE_ASYM_FIBER; + else if (ethadv & ADVERTISE_PAUSE_CAP) + result |= (ADVERTISE_PAUSE_FIBER + & (~ADVERTISE_PAUSE_ASYM_FIBER)); + + return result; +} + +/** + * marvell_config_aneg_fiber - restart auto-negotiation or write BMCR + * @phydev: target phy_device struct + * + * Description: If auto-negotiation is enabled, we configure the + * advertising, and then restart auto-negotiation. If it is not + * enabled, then we write the BMCR. Adapted for fiber link in + * some Marvell's devices. + */ +static int marvell_config_aneg_fiber(struct phy_device *phydev) +{ + int changed = 0; + int err; + int adv, oldadv; + u32 advertise; + + if (phydev->autoneg != AUTONEG_ENABLE) + return genphy_setup_forced(phydev); + + /* Only allow advertising what this PHY supports */ + phydev->advertising &= phydev->supported; + advertise = phydev->advertising; + + /* Setup fiber advertisement */ + adv = phy_read(phydev, MII_ADVERTISE); + if (adv < 0) + return adv; + + oldadv = adv; + adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL + | LPA_PAUSE_FIBER); + adv |= ethtool_adv_to_fiber_adv_t(advertise); + + if (adv != oldadv) { + err = phy_write(phydev, MII_ADVERTISE, adv); + if (err < 0) + return err; + + changed = 1; + } + + if (changed == 0) { + /* Advertisement hasn't changed, but maybe aneg was never on to + * begin with? Or maybe phy was isolated? + */ + int ctl = phy_read(phydev, MII_BMCR); + + if (ctl < 0) + return ctl; + + if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) + changed = 1; /* do restart aneg */ + } + + /* Only restart aneg if we are advertising something different + * than we were before. + */ + if (changed > 0) + changed = genphy_restart_aneg(phydev); + + return changed; +} + +static int m88e1510_config_aneg(struct phy_device *phydev) +{ + int err; + + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); + if (err < 0) + goto error; + + /* Configure the copper link first */ + err = m88e1318_config_aneg(phydev); + if (err < 0) + goto error; + + /* Then the fiber link */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_FIBER); + if (err < 0) + goto error; + + err = marvell_config_aneg_fiber(phydev); + if (err < 0) + goto error; + + return phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); + +error: + phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_M1111_COPPER); + return err; +} + +static int marvell_config_init(struct phy_device *phydev) +{ + /* Set registers from marvell,reg-init DT property */ + return marvell_of_reg_init(phydev); +} + static int m88e1540_config_init(struct phy_device *phydev) { u16 reg; @@ -246,7 +399,7 @@ static int m88e1540_config_init(struct phy_device *phydev) if (ret < 0) return ret; - return 0; + return marvell_config_init(phydev); } static int m88e1121_config_init(struct phy_device *phydev) @@ -289,9 +442,10 @@ static int m88e1121_config_init(struct phy_device *phydev) if (ret < 0) return ret; - return 0; + return marvell_config_init(phydev); } + static int m88e1318s_config_init(struct phy_device *phydev) { u16 reg; @@ -311,6 +465,41 @@ static int m88e1318s_config_init(struct phy_device *phydev) return m88e1121_config_init(phydev); } +static int m88e1510_config_init(struct phy_device *phydev) +{ + int err; + int temp; + + /* SGMII-to-Copper mode initialization */ + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + /* Select page 18 */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 18); + if (err < 0) + return err; + + /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ + temp = phy_read(phydev, MII_88E1510_GEN_CTRL_REG_1); + temp &= ~MII_88E1510_GEN_CTRL_REG_1_MODE_MASK; + temp |= MII_88E1510_GEN_CTRL_REG_1_MODE_SGMII; + err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); + if (err < 0) + return err; + + /* PHY reset is necessary after changing MODE[2:0] */ + temp |= MII_88E1510_GEN_CTRL_REG_1_RESET; + err = phy_write(phydev, MII_88E1510_GEN_CTRL_REG_1, temp); + if (err < 0) + return err; + + /* Reset page selection */ + err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0); + if (err < 0) + return err; + } + + return m88e1121_config_init(phydev); +} + static struct phy_driver marvell_drivers[] = { { .phy_id = MARVELL_PHY_ID_88E1121R, @@ -339,13 +528,22 @@ static struct phy_driver marvell_drivers[] = { .config_aneg = &genphy_config_aneg, .read_status = &marvell_read_status, }, + { + .phy_id = MARVELL_PHY_ID_88E1510, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .drv.name = "Marvell 88E1510", + .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE, + .config_init = &m88e1510_config_init, + .config_aneg = &m88e1510_config_aneg, + .read_status = &marvell_read_status, + }, { .phy_id = MARVELL_PHY_ID_88E1540, .phy_id_mask = MARVELL_PHY_ID_MASK, .drv.name = "Marvell 88E1540", .features = PHY_GBIT_FEATURES, .config_init = &m88e1540_config_init, - .config_aneg = &genphy_config_aneg, + .config_aneg = &m88e1510_config_aneg, .read_status = &marvell_read_status, }, }; -- cgit v1.2.3