[PATCH net] net: ethernet: mediatek: preserve sibling PPE bindings
From: Alexander Goodkind
Date: Thu Oct 22 2026 - 21:25:42 EST
__mtk_ppe_check_skb() clears entry->hash for flows bound to other
hardware slots in the same software hash bucket. This makes
mtk_flow_offload_stats() skip their hardware counter updates.
In the regular flow branch, clear entry->hash only when it matches
the slot being checked.
Fixes: c4f033d9e03e ("net: ethernet: mtk_eth_soc: rework hardware flow table management")
Link: https://github.com/openwrt/openwrt/pull/26107
Assisted-by: LLM
Signed-off-by: Alexander Goodkind <alex@xxxxxxxxxxx>
---
The MediaTek Ethernet driver stores forwarding rules for active
connections in hardware slots. For a bound flow entry, entry->hash
stores the hardware slot index. Flow entries for different hardware
slots can share the same software hash bucket.
OpenWrt's driver maintains cumulative packet and byte totals. During
each statistics update, mtk_flow_offload_stats() subtracts the previous
reading from the current total to calculate newly transferred traffic.
Losing a hardware slot association lowers the current total used in
that calculation and causes unsigned underflow. Conversion to 32 bits
produces a false increase of about 4 GiB. Subsequent calls to
mtk_foe_entry_get_stats() return only the unchanged prev_packets and
prev_bytes values, and mtk_flow_offload_stats() subtracts identical
readings and reports zero increments while traffic continues.
Two UDP trials reproduced this failure on a GL-MT3000 with MT7981
running OpenWrt 25.12.5 and Linux 6.12.94.
ARM64 allmodconfig and allyesconfig builds passed on net ffdf678dd166
with GCC 14.2.0, W=1 and CONFIG_WERROR=n. Patched builds did not add
warnings. Existing -Woverride-init warnings fail the unmodified build
with CONFIG_WERROR=y.
Codex assisted with investigating the counters and preparing the patch.
drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -764,7 +764,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
}
if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) {
- if (entry->hash != 0xffff)
+ if (entry->hash == hash)
entry->hash = 0xffff;
continue;
}
base-commit: ffdf678dd16610e3f006dac904bd37c09684673c