Commit 3b72f84f authored by Clemens Gruber's avatar Clemens Gruber Committed by Jakub Kicinski

net: phy: marvell: Fix pause frame negotiation

The negotiation of flow control / pause frame modes was broken since
commit fcf1f59a ("net: phy: marvell: rearrange to use
genphy_read_lpa()") moved the setting of phydev->duplex below the
phy_resolve_aneg_pause call. Due to a check of DUPLEX_FULL in that
function, phydev->pause was no longer set.

Fix it by moving the parsing of the status variable before the blocks
dealing with the pause frames.

As the Marvell 88E1510 datasheet does not specify the timing between the
link status and the "Speed and Duplex Resolved" bit, we have to force
the link down as long as the resolved bit is not set, to avoid reporting
link up before we even have valid Speed/Duplex.

Tested with a Marvell 88E1510 (RGMII to Copper/1000Base-T)

Fixes: fcf1f59a ("net: phy: marvell: rearrange to use genphy_read_lpa()")
Signed-off-by: default avatarClemens Gruber <clemens.gruber@pqgruber.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 9d859289
...@@ -1263,6 +1263,30 @@ static int marvell_read_status_page_an(struct phy_device *phydev, ...@@ -1263,6 +1263,30 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
int lpa; int lpa;
int err; int err;
if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) {
phydev->link = 0;
return 0;
}
if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
phydev->duplex = DUPLEX_FULL;
else
phydev->duplex = DUPLEX_HALF;
switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
case MII_M1011_PHY_STATUS_1000:
phydev->speed = SPEED_1000;
break;
case MII_M1011_PHY_STATUS_100:
phydev->speed = SPEED_100;
break;
default:
phydev->speed = SPEED_10;
break;
}
if (!fiber) { if (!fiber) {
err = genphy_read_lpa(phydev); err = genphy_read_lpa(phydev);
if (err < 0) if (err < 0)
...@@ -1291,28 +1315,6 @@ static int marvell_read_status_page_an(struct phy_device *phydev, ...@@ -1291,28 +1315,6 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
} }
} }
if (!(status & MII_M1011_PHY_STATUS_RESOLVED))
return 0;
if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
phydev->duplex = DUPLEX_FULL;
else
phydev->duplex = DUPLEX_HALF;
switch (status & MII_M1011_PHY_STATUS_SPD_MASK) {
case MII_M1011_PHY_STATUS_1000:
phydev->speed = SPEED_1000;
break;
case MII_M1011_PHY_STATUS_100:
phydev->speed = SPEED_100;
break;
default:
phydev->speed = SPEED_10;
break;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment