summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThanh Quan <[email protected]>2025-10-27 15:03:58 +0100
committerJerome Forissier <[email protected]>2025-12-01 09:52:33 +0100
commit85a7e45c3350afd9f7c17bb0bb2a47aa94be982d (patch)
treea2ef4ec9df592c52b8efc59357500286003d42d4
parent31bf4a1c308773895a8e7ea047b3cea037e4c922 (diff)
net: phy: dp83869: fix STRAP_OPMODE bitmask
According to the TI DP83869HM datasheet Revision D (June 2025), section 7.6.1.41 STRAP_STS Register, the STRAP_OPMODE bitmask is bit [11:9]. Fix this. In case the PHY is auto-detected via PHY ID registers, or not described in DT, or, in case the PHY is described in DT but the optional DT property "ti,op-mode" is not present, then the driver reads out the PHY functional mode (RGMII, SGMII, ...) from hardware straps. Currently, all upstream users of this PHY specify both DT compatible string "ethernet-phy-id2000.a0f1" and ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET> property, therefore it seems no upstream users are affected by this bug. The driver currently interprets bits [2:0] of STRAP_STS register as PHY functional mode. Those bits are controlled by ANEG_DIS, ANEGSEL_0 straps and an always-zero reserved bit. Systems that use RGMII-to-Copper functional mode are unlikely to disable auto-negotiation via ANEG_DIS strap, or change auto-negotiation behavior via ANEGSEL_0 strap. Therefore, even with this bug in place, the STRAP_STS register content is likely going to be interpreted by the driver as RGMII-to-Copper mode. However, for a system with PHY functional mode strapping set to other mode than RGMII-to-Copper, the driver is likely to misinterpret the strapping as RGMII-to-Copper and misconfigure the PHY. For example, on a system with SGMII-to-Copper strapping, the STRAP_STS register reads as 0x0c20, but the PHY ends up being configured for incompatible RGMII-to-Copper mode. Fixes: f3e22eea815d ("net: phy: add TI DP83869HM ethernet driver") Signed-off-by: Thanh Quan <[email protected]> Signed-off-by: Hai Pham <[email protected]> Signed-off-by: Marek Vasut <[email protected]> # Use FIELD_GET()
-rw-r--r--drivers/net/phy/dp83869.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index b6fb5adae1f..c60fbf26a03 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -5,6 +5,7 @@
*/
#include <phy.h>
+#include <linux/bitfield.h>
#include <linux/compat.h>
#include <malloc.h>
@@ -64,7 +65,7 @@
#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
/* STRAP_STS1 bits */
-#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
+#define DP83869_STRAP_OP_MODE_MASK GENMASK(11, 9)
#define DP83869_STRAP_STS1_RESERVED BIT(11)
#define DP83869_STRAP_MIRROR_ENABLED BIT(12)
@@ -168,7 +169,7 @@ static int dp83869_set_strapped_mode(struct phy_device *phydev)
if (val < 0)
return val;
- dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK;
+ dp83869->mode = FIELD_GET(DP83869_STRAP_OP_MODE_MASK, val);
return 0;
}