summaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/marvell.c
diff options
context:
space:
mode:
authorClemens Gruber <clemens.gruber@pqgruber.com>2020-04-11 18:51:25 +0200
committerJakub Kicinski <kuba@kernel.org>2020-04-11 16:51:09 -0700
commit3b72f84f8fb65e83e85e9be58eabcf95a40b8f46 (patch)
treea5fb37d5291b31d2d92d75581ec949c2e09df74a /drivers/net/phy/marvell.c
parent9d8592896fd946b27c385d42f5c80b0b5254fce9 (diff)
downloadlinux-3b72f84f8fb65e83e85e9be58eabcf95a40b8f46.tar.bz2
net: phy: marvell: Fix pause frame negotiation
The negotiation of flow control / pause frame modes was broken since commit fcf1f59afc67 ("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: fcf1f59afc67 ("net: phy: marvell: rearrange to use genphy_read_lpa()") Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/phy/marvell.c')
-rw-r--r--drivers/net/phy/marvell.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4714ca0e0d4b..7fc8e10c5f33 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1263,6 +1263,30 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
int lpa;
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) {
err = genphy_read_lpa(phydev);
if (err < 0)
@@ -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;
}