RollBall SFPs contain Marvell 88X3310 PHY, but they have configuration pins strapped so that MACTYPE is configured in XFI with Rate Matching mode.
When these SFPs are inserted into a device which only supports lower speeds on host interface, we need to configure the MACTYPE to a mode in which the H unit changes SerDes speed according to speed on the copper interface. I chose to use the 10GBASE-R/5GBASE-R/2500BASE-X/SGMII with AN mode. Signed-off-by: Marek Behún <marek.be...@nic.cz> --- drivers/net/phy/marvell10g.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index 29575442b25b2..13a588fa69e77 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -81,6 +81,7 @@ enum { MV_V2_PORT_CTRL_SWRST = BIT(15), MV_V2_PORT_CTRL_PWRDOWN = BIT(11), MV_V2_PORT_MAC_TYPE_MASK = 0x7, + MV_V2_PORT_MAC_TYPE_10GBR_SGMII_AN = 0x4, MV_V2_PORT_MAC_TYPE_RATE_MATCH = 0x6, /* Temperature control/read registers (88X3310 only) */ MV_V2_TEMP_CTRL = 0xf08a, @@ -258,17 +259,40 @@ static int mv3310_power_down(struct phy_device *phydev) static int mv3310_power_up(struct phy_device *phydev) { struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + u16 val, mask; int ret; ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, MV_V2_PORT_CTRL_PWRDOWN); - if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 || - priv->firmware_ver < 0x00030000) + if (ret < 0) return ret; - return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, - MV_V2_PORT_CTRL_SWRST); + /* TODO: add support for changing MACTYPE on 88E2110 via register 1.C0A4.2:0 */ + if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310) + return 0; + + val = mask = MV_V2_PORT_CTRL_SWRST; + + switch (phydev->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_2500BASEX: + val |= MV_V2_PORT_MAC_TYPE_10GBR_SGMII_AN; + mask |= MV_V2_PORT_MAC_TYPE_MASK; + break; + + default: + /* Otherwise we assume that the MACTYPE is set correctly by strapping pins. + * Feel free to add support for changing MACTYPE for other modes + * (XAUI/RXAUI/USXGMII). + */ + + /* reset is not needed for firmware version < 0.3.0.0 when not changing MACTYPE */ + if (priv->firmware_ver < 0x00030000) + return 0; + } + + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, mask, val); } static int mv3310_reset(struct phy_device *phydev, u32 unit) -- 2.26.2