Skip to content

Commit 6e5484d

Browse files
rmandradfrank-w
authored andcommitted
net: phy: as21xxx: make PHY matching side-effect free and non-fatal
The AS21xxx match callbacks were mutating device state while the core was still deciding which driver to bind. Specifically, match paths were writing `phydev->phy_id` (and for gen1 also touching vendor registers). On C45-discovered devices, `phydev->phy_id` may start as 0, so this could leave sysfs showing `0x00000000` or stale values. Also, returning negative errors from `match_phy_device()` can abort driver matching and leave the PHY unbound, which breaks management LED setup. Fix this by: - making gen1/gen2 match callbacks return `0` on read failure - removing `phydev->phy_id` updates from match callbacks - removing side-effect register writes from match callbacks - updating `phydev->phy_id` in gen1/gen2 probe after successful init using a best-effort PID re-read This keeps matching pure, avoids premature bind aborts, and ensures sysfs `phy_id` is updated only after the PHY is actually initialized. Signed-off-by: Rudy Andram <rmandrad@gmail.com>
1 parent 23c2b22 commit 6e5484d

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

drivers/net/phy/as21xxx/as21xxx.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,9 +1041,13 @@ static int aeon_get_features(struct phy_device *phydev)
10411041
return 0;
10421042
}
10431043

1044+
static int aeon_gen1_read_pid(struct phy_device *phydev, u32 *phy_id);
1045+
static int aeon_gen2_read_pid(struct phy_device *phydev, u32 *phy_id);
1046+
10441047
static int aeon_gen1_probe(struct phy_device *phydev)
10451048
{
10461049
struct as21xxx_priv *priv;
1050+
u32 phy_id;
10471051
int ret;
10481052

10491053
aeon_dbg(phydev, "gen1 probe start (mdio addr=%d)\n",
@@ -1079,6 +1083,14 @@ static int aeon_gen1_probe(struct phy_device *phydev)
10791083
if (ret)
10801084
return ret;
10811085

1086+
/*
1087+
* Keep sysfs phy_id aligned with the post-firmware C45 ID.
1088+
* Matching is done against C45 IDs, so failure here is non-fatal.
1089+
*/
1090+
ret = aeon_gen1_read_pid(phydev, &phy_id);
1091+
if (!ret && phy_id)
1092+
phydev->phy_id = phy_id;
1093+
10821094
aeon_dbg(phydev, "gen1 probe complete\n");
10831095

10841096
return 0;
@@ -1087,6 +1099,7 @@ static int aeon_gen1_probe(struct phy_device *phydev)
10871099
static int aeon_gen2_probe(struct phy_device *phydev)
10881100
{
10891101
struct as21xxx_priv *priv;
1102+
u32 phy_id;
10901103
int ret = 0;
10911104

10921105
aeon_dbg(phydev, "gen2 probe start (mdio addr=%d)\n",
@@ -1113,6 +1126,14 @@ static int aeon_gen2_probe(struct phy_device *phydev)
11131126
if (ret)
11141127
return ret;
11151128

1129+
/*
1130+
* Keep sysfs phy_id aligned with the post-firmware C45 ID.
1131+
* Matching is done against C45 IDs, so failure here is non-fatal.
1132+
*/
1133+
ret = aeon_gen2_read_pid(phydev, &phy_id);
1134+
if (!ret && phy_id)
1135+
phydev->phy_id = phy_id;
1136+
11161137
aeon_dbg(phydev, "gen2 probe complete\n");
11171138

11181139
return 0;
@@ -1510,9 +1531,8 @@ static int aeon_gen1_match_phy_device(struct phy_device *phydev,
15101531

15111532
ret = aeon_gen1_read_pid(phydev, &phy_id);
15121533
if (ret < 0) {
1513-
phydev_err(phydev, "gen1 match: failed to read PHY ID (%d)\n",
1514-
ret);
1515-
return ret;
1534+
aeon_dbg(phydev, "gen1 match: failed to read PHY ID (%d)\n", ret);
1535+
return 0;
15161536
}
15171537

15181538
aeon_dbg(phydev, "gen1 match: read PHY ID=0x%08x, trying driver=%s (0x%08x)\n",
@@ -1527,8 +1547,6 @@ static int aeon_gen1_match_phy_device(struct phy_device *phydev,
15271547
return phy_id == phydrv->phy_id;
15281548
}
15291549

1530-
phydev->phy_id = phy_id;
1531-
aeon_cl45_write(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK, 0x48);
15321550
if (phydrv->phy_id == PHY_ID_AS21XXX)
15331551
aeon_dbg(phydev,
15341552
"gen1 match: pre-fw generic PHY ID 0x%08x matched %s\n",
@@ -1546,12 +1564,10 @@ static int aeon_gen2_match_phy_device(struct phy_device *phydev,
15461564

15471565
ret = aeon_gen2_read_pid(phydev, &phy_id);
15481566
if (ret < 0) {
1549-
phydev_err(phydev, "gen2 match: failed to read PHY ID (%d)\n",
1550-
ret);
1551-
return ret;
1567+
aeon_dbg(phydev, "gen2 match: failed to read PHY ID (%d)\n", ret);
1568+
return 0;
15521569
}
15531570

1554-
phydev->phy_id = phy_id;
15551571
aeon_dbg(phydev, "gen2 match: read PHY ID=0x%08x, trying driver=%s (0x%08x)\n",
15561572
phy_id, phydrv->name, phydrv->phy_id);
15571573
if (phy_id == phydrv->phy_id)

0 commit comments

Comments
 (0)