Skip to content

Commit 91fac45

Browse files
committed
Merge branch 'Fix-88x3310-leaving-power-save-mode'
Russell King says: ==================== Fix 88x3310 leaving power save mode This series fixes a problem with the 88x3310 PHY on Macchiatobin coming out of powersave mode noticed by Matteo Croce. It seems that certain PHY firmwares do not properly exit powersave mode, resulting in a fibre link not coming up. The solution appears to be to soft-reset the PHY after clearing the powersave bit. We add support for reporting the PHY firmware version to the kernel log, and use it to trigger this new behaviour if we have v0.3.x.x or more recent firmware on the PHY. This, however, is a guess as the firmware revision documentation does not mention this issue, and we know that v0.2.1.0 works without this fix but v0.3.3.0 and later does not. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c799fca + 8f48c2a commit 91fac45

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

drivers/net/phy/marvell10g.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
3434

3535
enum {
36+
MV_PMA_FW_VER0 = 0xc011,
37+
MV_PMA_FW_VER1 = 0xc012,
3638
MV_PMA_BOOT = 0xc050,
3739
MV_PMA_BOOT_FATAL = BIT(0),
3840

@@ -73,7 +75,8 @@ enum {
7375

7476
/* Vendor2 MMD registers */
7577
MV_V2_PORT_CTRL = 0xf001,
76-
MV_V2_PORT_CTRL_PWRDOWN = 0x0800,
78+
MV_V2_PORT_CTRL_SWRST = BIT(15),
79+
MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
7780
MV_V2_TEMP_CTRL = 0xf08a,
7881
MV_V2_TEMP_CTRL_MASK = 0xc000,
7982
MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
@@ -83,6 +86,8 @@ enum {
8386
};
8487

8588
struct mv3310_priv {
89+
u32 firmware_ver;
90+
8691
struct device *hwmon_dev;
8792
char *hwmon_name;
8893
};
@@ -235,8 +240,17 @@ static int mv3310_power_down(struct phy_device *phydev)
235240

236241
static int mv3310_power_up(struct phy_device *phydev)
237242
{
238-
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
239-
MV_V2_PORT_CTRL_PWRDOWN);
243+
struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
244+
int ret;
245+
246+
ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
247+
MV_V2_PORT_CTRL_PWRDOWN);
248+
249+
if (priv->firmware_ver < 0x00030000)
250+
return ret;
251+
252+
return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
253+
MV_V2_PORT_CTRL_SWRST);
240254
}
241255

242256
static int mv3310_reset(struct phy_device *phydev, u32 unit)
@@ -355,6 +369,22 @@ static int mv3310_probe(struct phy_device *phydev)
355369

356370
dev_set_drvdata(&phydev->mdio.dev, priv);
357371

372+
ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER0);
373+
if (ret < 0)
374+
return ret;
375+
376+
priv->firmware_ver = ret << 16;
377+
378+
ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER1);
379+
if (ret < 0)
380+
return ret;
381+
382+
priv->firmware_ver |= ret;
383+
384+
phydev_info(phydev, "Firmware version %u.%u.%u.%u\n",
385+
priv->firmware_ver >> 24, (priv->firmware_ver >> 16) & 255,
386+
(priv->firmware_ver >> 8) & 255, priv->firmware_ver & 255);
387+
358388
/* Powering down the port when not in use saves about 600mW */
359389
ret = mv3310_power_down(phydev);
360390
if (ret)

0 commit comments

Comments
 (0)