Skip to content

Commit 2c84959

Browse files
dramforeverkuba-moo
authored andcommitted
net: spacemit: Check for netif_carrier_ok() in emac_stats_update()
Some PHYs stop the refclk for power saving, usually while link down. This causes reading stats to time out. Therefore, in emac_stats_update(), also don't update and reschedule if !netif_carrier_ok(). But that means we could be missing later updates if the link comes back up, so also reschedule when link up is detected in emac_adjust_link(). While we're at it, improve the comments and error message prints around this to reflect the better understanding of how this could happen. Hopefully if this happens again on new hardware, these comments will direct towards a solution. Closes: https://lore.kernel.org/r/[email protected]/ Fixes: bfec6d7 ("net: spacemit: Add K1 Ethernet MAC") Co-developed-by: Chukun Pan <[email protected]> Signed-off-by: Chukun Pan <[email protected]> Signed-off-by: Vivian Wang <[email protected]> Link: https://patch.msgid.link/20260123-k1-ethernet-clarify-stat-timeout-v3-1-93b9df627e87@iscas.ac.cn Signed-off-by: Jakub Kicinski <[email protected]>
1 parent e2a9eeb commit 2c84959

1 file changed

Lines changed: 27 additions & 7 deletions

File tree

drivers/net/ethernet/spacemit/k1_emac.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,13 @@ static int emac_read_stat_cnt(struct emac_priv *priv, u8 cnt, u32 *res,
10991099
100, 10000);
11001100

11011101
if (ret) {
1102-
netdev_err(priv->ndev, "Read stat timeout\n");
1102+
/*
1103+
* This could be caused by the PHY stopping its refclk even when
1104+
* the link is up, for power saving. See also comments in
1105+
* emac_stats_update().
1106+
*/
1107+
dev_err_ratelimited(&priv->ndev->dev,
1108+
"Read stat timeout. PHY clock stopped?\n");
11031109
return ret;
11041110
}
11051111

@@ -1147,17 +1153,25 @@ static void emac_stats_update(struct emac_priv *priv)
11471153

11481154
assert_spin_locked(&priv->stats_lock);
11491155

1150-
if (!netif_running(priv->ndev) || !netif_device_present(priv->ndev)) {
1151-
/* Not up, don't try to update */
1156+
/*
1157+
* We can't read statistics if the interface is not up. Also, some PHYs
1158+
* stop their reference clocks for link down power saving, which also
1159+
* causes reading statistics to time out. Don't update and don't
1160+
* reschedule in these cases.
1161+
*/
1162+
if (!netif_running(priv->ndev) ||
1163+
!netif_carrier_ok(priv->ndev) ||
1164+
!netif_device_present(priv->ndev)) {
11521165
return;
11531166
}
11541167

11551168
for (i = 0; i < sizeof(priv->tx_stats) / sizeof(*tx_stats); i++) {
11561169
/*
1157-
* If reading stats times out, everything is broken and there's
1158-
* nothing we can do. Reading statistics also can't return an
1159-
* error, so just return without updating and without
1160-
* rescheduling.
1170+
* If reading stats times out anyway, the stat registers will be
1171+
* stuck, and we can't really recover from that.
1172+
*
1173+
* Reading statistics also can't return an error, so just return
1174+
* without updating and without rescheduling.
11611175
*/
11621176
if (emac_tx_read_stat_cnt(priv, i, &res))
11631177
return;
@@ -1636,6 +1650,12 @@ static void emac_adjust_link(struct net_device *dev)
16361650
emac_wr(priv, MAC_GLOBAL_CONTROL, ctrl);
16371651

16381652
emac_set_fc_autoneg(priv);
1653+
1654+
/*
1655+
* Reschedule stats updates now that link is up. See comments in
1656+
* emac_stats_update().
1657+
*/
1658+
mod_timer(&priv->stats_timer, jiffies);
16391659
}
16401660

16411661
phy_print_status(phydev);

0 commit comments

Comments
 (0)