aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorFlorian Fainelli <florian.fainelli@broadcom.com>2026-09-21 15:00:17 -0700
committerJakub Kicinski <kuba@kernel.org>2026-09-23 19:06:49 -0700
commit0e2bec77ea62895416600c90588f593516572bca (patch)
tree27e0a10bdffa6b01f482a7fb77a246dcfc7bf416
parentnet: ipv6: keep room for the mac header in dst_dev_overhead() (diff)
net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems
When bcmgenet was converted to 64-bit statistics, STAT_RTNL members were switched to point into struct rtnl_link_stats64, whose fields are 64-bit (__u64) regardless of architecture. However, bcmgenet_get_ethtool_stats() retained a legacy check: if (sizeof(unsigned long) != sizeof(u32) && s->stat_sizeof == sizeof(unsigned long)) On 32-bit systems, sizeof(unsigned long) == sizeof(u32), causing this condition to evaluate to false. As a result, 64-bit RTNL stats fields were read via *(u32 *)p. On 32-bit Big-Endian systems (such as MIPS BE), this reads the high 32 bits and returns 0 until the counter exceeds 4GB; on 32-bit Little-Endian systems (such as 32-bit ARM), the value is truncated to 32 bits. Fix this by checking if s->stat_sizeof == sizeof(u64) so 64-bit fields are always read as 64-bit values. Fixes: 59aa6e3072aa ("net: bcmgenet: switch to use 64bit statistics") Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> Link: https://patch.msgid.link/20260921220021.281418-2-florian.fainelli@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index ca62041efecd..47a6c073c8d9 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1346,9 +1346,8 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
p = (char *)&stats64;
p += s->stat_offset;
- if (sizeof(unsigned long) != sizeof(u32) &&
- s->stat_sizeof == sizeof(unsigned long))
- data[i] = *(unsigned long *)p;
+ if (s->stat_sizeof == sizeof(u64))
+ data[i] = *(u64 *)p;
else
data[i] = *(u32 *)p;
}