[PATCH net 11/11] net: phy: smsc: wait for LAN83C183 power-down recovery
From: Florian Fainelli
Date: Tue Oct 27 2026 - 18:40:26 EST
The LAN83C183 uses the generic PHY driver, which returns immediately
after clearing BMCR_PDOWN. Section 1.11 of the datasheet allows 500 ms
before normal operation is restored. Starting the Au1000 MAC before the
MII clocks recover can hang the MTX-1 when reopening its interface.
Add a LAN83C183 driver entry and resume callback. Wait for recovery only
when BMCR_PDOWN was actually cleared, and propagate MDIO errors without
waiting. Resuming an already awake PHY does not incur the delay.
Fixes: be9dad1f9f26 ("net: phy: suspend phydev when going to HALTED")
Link: https://pdf.dzsc.com/LAN/LAN83C183.pdf#page=44
Signed-off-by: Florian Fainelli <f.fainelli@xxxxxxxxx>
---
drivers/net/phy/Kconfig | 2 +-
drivers/net/phy/smsc.c | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 30e9d22c8d1a..10466b2574eb 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -421,7 +421,7 @@ config SMSC_PHY
tristate "SMSC PHYs"
select CRC16
help
- Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
+ Currently supports the LAN83C183, LAN83C185, LAN8187 and LAN8700 PHYs
config STE10XP
tristate "STMicroelectronics STe10Xp PHYs"
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 48487149c225..c3b51afd4b1e 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -13,6 +13,7 @@
*/
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mii.h>
@@ -684,8 +685,32 @@ int smsc_phy_probe(struct phy_device *phydev)
}
EXPORT_SYMBOL_GPL(smsc_phy_probe);
+static int lan83c183_resume(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_modify_changed(phydev, MII_BMCR, BMCR_PDOWN, 0);
+ if (ret < 0)
+ return ret;
+
+ /* The PHY needs up to 500 ms to restore operation after power-down. */
+ if (ret)
+ msleep(500);
+
+ return 0;
+}
+
static struct phy_driver smsc_phy_driver[] = {
{
+ .phy_id = 0x0016f840,
+ .phy_id_mask = 0xfffffff0,
+ .name = "SMSC LAN83C183",
+
+ .get_features = genphy_read_abilities,
+ .suspend = genphy_suspend,
+ .resume = lan83c183_resume,
+ .set_loopback = genphy_loopback,
+}, {
.phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
.phy_id_mask = 0xfffffff0,
.name = "SMSC LAN83C185",
@@ -887,6 +912,7 @@ MODULE_AUTHOR("Herbert Valerio Riedel");
MODULE_LICENSE("GPL");
static const struct mdio_device_id __maybe_unused smsc_tbl[] = {
+ { 0x0016f840, 0xfffffff0 },
{ 0x0007c0a0, 0xfffffff0 },
{ 0x0007c0b0, 0xfffffff0 },
{ 0x0007c0c0, 0xfffffff0 },
--
2.53.0