Skip to content

Commit 9dfe110

Browse files
oleremkuba-moo
authored andcommitted
net: phy: smsc: Fix link failure in forced mode with Auto-MDIX
Force a fixed MDI-X mode when auto-negotiation is disabled to prevent link instability. When forcing the link speed and duplex on a LAN9500 PHY (e.g., with `ethtool -s eth0 autoneg off ...`) while leaving MDI-X control in auto mode, the PHY fails to establish a stable link. This occurs because the PHY's Auto-MDIX algorithm is not designed to operate when auto-negotiation is disabled. In this state, the PHY continuously toggles the TX/RX signal pairs, which prevents the link partner from synchronizing. This patch resolves the issue by detecting when auto-negotiation is disabled. If the MDI-X control mode is set to 'auto', the driver now forces a specific, stable mode (ETH_TP_MDI) to prevent the pair toggling. This choice of a fixed MDI mode mirrors the behavior the hardware would exhibit if the AUTOMDIX_EN strap were configured for a fixed MDI connection. Fixes: 05b35e7 ("smsc95xx: add phylib support") Signed-off-by: Oleksij Rempel <[email protected]> Cc: Andre Edich <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0713e55 commit 9dfe110

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

drivers/net/phy/smsc.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,29 @@ static int smsc_phy_reset(struct phy_device *phydev)
155155

156156
static int lan87xx_config_aneg(struct phy_device *phydev)
157157
{
158-
int rc;
158+
u8 mdix_ctrl;
159159
int val;
160+
int rc;
161+
162+
/* When auto-negotiation is disabled (forced mode), the PHY's
163+
* Auto-MDIX will continue toggling the TX/RX pairs.
164+
*
165+
* To establish a stable link, we must select a fixed MDI mode.
166+
* If the user has not specified a fixed MDI mode (i.e., mdix_ctrl is
167+
* 'auto'), we default to ETH_TP_MDI. This choice of a ETH_TP_MDI mode
168+
* mirrors the behavior the hardware would exhibit if the AUTOMDIX_EN
169+
* strap were configured for a fixed MDI connection.
170+
*/
171+
if (phydev->autoneg == AUTONEG_DISABLE) {
172+
if (phydev->mdix_ctrl == ETH_TP_MDI_AUTO)
173+
mdix_ctrl = ETH_TP_MDI;
174+
else
175+
mdix_ctrl = phydev->mdix_ctrl;
176+
} else {
177+
mdix_ctrl = phydev->mdix_ctrl;
178+
}
160179

161-
switch (phydev->mdix_ctrl) {
180+
switch (mdix_ctrl) {
162181
case ETH_TP_MDI:
163182
val = SPECIAL_CTRL_STS_OVRRD_AMDIX_;
164183
break;
@@ -184,7 +203,7 @@ static int lan87xx_config_aneg(struct phy_device *phydev)
184203
rc |= val;
185204
phy_write(phydev, SPECIAL_CTRL_STS, rc);
186205

187-
phydev->mdix = phydev->mdix_ctrl;
206+
phydev->mdix = mdix_ctrl;
188207
return genphy_config_aneg(phydev);
189208
}
190209

0 commit comments

Comments
 (0)