Skip to content

Commit fc06493

Browse files
oleremkuba-moo
authored andcommitted
net: phy: dp83td510: fix kernel stall during netboot in DP83TD510E PHY driver
Fix an issue where the kernel would stall during netboot, showing the "sched: RT throttling activated" message. This stall was triggered by the behavior of the mii_interrupt bit (Bit 7 - DP83TD510E_STS_MII_INT) in the DP83TD510E's PHY_STS Register (Address = 0x10). The DP83TD510E datasheet (2020) states that the bit clears on write, however, in practice, the bit clears on read. This discrepancy had significant implications on the driver's interrupt handling. The PHY_STS Register was used by handle_interrupt() to check for pending interrupts and by read_status() to get the current link status. The call to read_status() was unintentionally clearing the mii_interrupt status bit without deasserting the IRQ pin, causing handle_interrupt() to miss other pending interrupts. This issue was most apparent during netboot. The fix refrains from using the PHY_STS Register for interrupt handling. Instead, we now solely rely on the INTERRUPT_REG_1 Register (Address = 0x12) and INTERRUPT_REG_2 Register (Address = 0x13) for this purpose. These registers directly influence the IRQ pin state and are latched high until read. Note: The INTERRUPT_REG_2 Register (Address = 0x13) exists and can also be used for interrupt handling, specifically for "Aneg page received interrupt" and "Polarity change interrupt". However, these features are currently not supported by this driver. Fixes: 165cd04 ("net: phy: dp83td510: Add support for the DP83TD510 Ethernet PHY") Cc: <stable@vger.kernel.org> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Link: https://lore.kernel.org/r/20230621043848.3806124-1-o.rempel@pengutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent aa54069 commit fc06493

1 file changed

Lines changed: 5 additions & 18 deletions

File tree

drivers/net/phy/dp83td510.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
/* MDIO_MMD_VEND2 registers */
1414
#define DP83TD510E_PHY_STS 0x10
15+
/* Bit 7 - mii_interrupt, active high. Clears on read.
16+
* Note: Clearing does not necessarily deactivate IRQ pin if interrupts pending.
17+
* This differs from the DP83TD510E datasheet (2020) which states this bit
18+
* clears on write 0.
19+
*/
1520
#define DP83TD510E_STS_MII_INT BIT(7)
1621
#define DP83TD510E_LINK_STATUS BIT(0)
1722

@@ -53,12 +58,6 @@ static int dp83td510_config_intr(struct phy_device *phydev)
5358
int ret;
5459

5560
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
56-
/* Clear any pending interrupts */
57-
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PHY_STS,
58-
0x0);
59-
if (ret)
60-
return ret;
61-
6261
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
6362
DP83TD510E_INTERRUPT_REG_1,
6463
DP83TD510E_INT1_LINK_EN);
@@ -81,10 +80,6 @@ static int dp83td510_config_intr(struct phy_device *phydev)
8180
DP83TD510E_GENCFG_INT_EN);
8281
if (ret)
8382
return ret;
84-
85-
/* Clear any pending interrupts */
86-
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PHY_STS,
87-
0x0);
8883
}
8984

9085
return ret;
@@ -94,14 +89,6 @@ static irqreturn_t dp83td510_handle_interrupt(struct phy_device *phydev)
9489
{
9590
int ret;
9691

97-
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_PHY_STS);
98-
if (ret < 0) {
99-
phy_error(phydev);
100-
return IRQ_NONE;
101-
} else if (!(ret & DP83TD510E_STS_MII_INT)) {
102-
return IRQ_NONE;
103-
}
104-
10592
/* Read the current enabled interrupts */
10693
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_INTERRUPT_REG_1);
10794
if (ret < 0) {

0 commit comments

Comments
 (0)