[PATCH net] net: dsa: motorcomm: Do not publish partial MIB sample

From: David Yang

Date: Mon Nov 02 2026 - 05:13:49 EST


When a register read failed midway, the buffer was published anyway,
mixing fresh packet counters with stale byte counters; get_stats64 then
subtracts ETH_FCS_LEN per packet from the stale byte counter and
underflows on unsigned arithmetic.

Keep the last complete sample instead.

Fixes: 186623f4aa72 ("net: dsa: yt921x: Add support for Motorcomm YT921x")
Signed-off-by: David Yang <mmyangfl@xxxxxxxxx>
---
drivers/net/dsa/motorcomm/mib.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/motorcomm/mib.c b/drivers/net/dsa/motorcomm/mib.c
index 6b170fc6e187..bbcc418fcc87 100644
--- a/drivers/net/dsa/motorcomm/mib.c
+++ b/drivers/net/dsa/motorcomm/mib.c
@@ -127,6 +127,12 @@ static int yt921x_mib_read(struct yt921x_priv *priv, int port)
buf[i] = val;
}

+ if (res) {
+ dev_err(dev, "Failed to %s port %d: %i\n", "read stats for",
+ port, res);
+ return res;
+ }
+
flags = u64_stats_update_begin_irqsave(&pm->syncp);
for (size_t i = 0; i < ARRAY_SIZE(yt921x_mib_descs); i++)
u64_stats_set(&((u64_stats_t *)mib)[i], buf[i]);
@@ -148,10 +154,7 @@ static int yt921x_mib_read(struct yt921x_priv *priv, int port)
u64_stats_set(&pm->tx_frames, tx_frames);
u64_stats_update_end_irqrestore(&pm->syncp, flags);

- if (res)
- dev_err(dev, "Failed to %s port %d: %i\n", "read stats for",
- port, res);
- return res;
+ return 0;
}

void yt921x_mib_poll(struct work_struct *work)
--
2.53.0