[net,PATCH v1] net: ks8851: Fix receiver error in 100BASE-TX mode following software power-down
From: Marek Vasut
Date: Tue Sep 01 2026 - 14:10:10 EST
KSZ8851 errata sheet DS80000716D-page 4 Module 3 [1] states that,
when issuing a software power-down (PMECR[1:0] = 10) followed by a
power-on (PMECR[1:0] = 00), the receiver circuit can fail to start
properly preventing communication. The Transmitter will still send
data, but no data will be received.
The errata sheet also includes a workaround, which states that,
it is recommended that the software power-down feature not be used.
Implement that workaround and drop the entry into software power-down
mode. The ks8851_write_mac_addr() calls entry into normal power-on
mode at the very beginning of the function, therefore dropping the
second call to enter software power-down mode is sufficient here.
The ks8851_net_stop() can only be called after ks8851_net_start()
was already called, and ks8851_net_start() also makes the MAC enter
normal power-on mode, therefore it is also fine to drop the call to
enter software power-down mode from ks8851_net_stop().
This will lead to slight increase in power consumption, but it also
fixes a sporadic problem which occurs at least on KSZ8851-16MLL, on
which this fix is tested.
[1] https://ww1.microchip.com/downloads/en/DeviceDoc/80000716D.pdf
Fixes: 3ba81f3ece3c ("net: Micrel KS8851 SPI network driver")
Signed-off-by: Marek Vasut <marex@xxxxxxxxxxxx>
---
Cc: "David S. Miller" <davem@xxxxxxxxxxxxx>
Cc: Andrew Lunn <andrew+netdev@xxxxxxx>
Cc: Eric Dumazet <edumazet@xxxxxxxxxx>
Cc: Jakub Kicinski <kuba@xxxxxxxxxx>
Cc: Paolo Abeni <pabeni@xxxxxxxxxx>
Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Cc: Yicong Hui <yiconghui@xxxxxxxxx>
Cc: kernel@xxxxxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: netdev@xxxxxxxxxxxxxxx
---
drivers/net/ethernet/micrel/ks8851_common.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/net/ethernet/micrel/ks8851_common.c b/drivers/net/ethernet/micrel/ks8851_common.c
index 4afbb40bc0e4a..cd8dfca22720b 100644
--- a/drivers/net/ethernet/micrel/ks8851_common.c
+++ b/drivers/net/ethernet/micrel/ks8851_common.c
@@ -139,17 +139,14 @@ static int ks8851_write_mac_addr(struct net_device *dev)
ks8851_set_powermode(ks, PMECR_PM_NORMAL);
for (i = 0; i < ETH_ALEN; i += 2) {
val = (dev->dev_addr[i] << 8) | dev->dev_addr[i + 1];
ks8851_wrreg16(ks, KS_MAR(i), val);
}
- if (!netif_running(dev))
- ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
-
ks8851_unlock(ks);
return 0;
}
/**
* ks8851_read_mac_addr - read mac address from device registers
@@ -502,16 +499,14 @@ static int ks8851_net_stop(struct net_device *dev)
ks8851_lock(ks);
/* shutdown RX process */
ks8851_wrreg16(ks, KS_RXCR1, 0x0000);
/* shutdown TX process */
ks8851_wrreg16(ks, KS_TXCR, 0x0000);
- /* set powermode to soft power down to save power */
- ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
ks8851_unlock(ks);
/* ensure any queued tx buffers are dumped */
while (!skb_queue_empty(&ks->txq)) {
struct sk_buff *txb = skb_dequeue(&ks->txq);
netif_dbg(ks, ifdown, ks->netdev,
--
2.53.0