phy: advertise half duplex only when half duplex was asked for

The 100M branch of phy_set_speed() is missing an else. A port set to 100M
half writes 0x1481, falls into the next if, finds duplex is not 1 and takes
its else, and immediately overwrites the register with 0x1581. The port
ends up advertising 100BASE-TX half and full, which is what "both" is
supposed to mean.

The 10M branch directly above has the chain the 100M one meant to have, and
the values line up with it: bit 7 is 100BASE-TX half, bit 8 is full, so
0x1481, 0x1501 and 0x1581 are half, full and both, exactly as 0x1421,
0x1441 and 0x1461 are for 10M.

Forcing half duplex is something people do to match a link partner that
cannot negotiate, so quietly advertising full as well is the wrong way for
this to fail.

Not tried on hardware: every port on the switch here has a link up, and
setting the speed restarts negotiation.
This commit is contained in:
d00f committed 2026-09-08 23:49:11 +02:00
1 parent 5ecce86ef1
commit 412098d0ed
1 file changed
+1 -1
+1 -1
View File
@@ -343,7 +343,7 @@ void phy_set_speed(void) __banked
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_MGBASE_CTRL, 0x6001);
if (!phy_settings.duplex)
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1481);
if (phy_settings.duplex == 1)
else if (phy_settings.duplex == 1)
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1501);
else
phy_write(phy_settings.port, PHY_MMD_AN, PHY_ANEG_ADV, 0x1581);