Skip to content

Commit dbd8eab

Browse files
committed
generic: 6.18: mtk_eth_soc: improve non-MTK tag_8021q DSA
Add patches to improve support for using 3rd-party DSA switches like MaxLinear MxL862xx with MediaTek's mtk_eth_soc being the conduit. This involves reorganizing hardware queues to avoid overlap (currently dp->index is used -- if there is more than one DSA switch this is problematic), and correctly programming flows of the non-MTK DSA users ports in the PPE offloading engine. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
1 parent c9a8791 commit dbd8eab

12 files changed

Lines changed: 914 additions & 17 deletions

target/linux/generic/hack-6.18/730-net-ethernet-mtk_eth_soc-add-hw-dump-for-forced-rese.patch

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
3737
.glo_cfg = 0x4604,
3838
.rst_idx = 0x4608,
3939
.delay_irq = 0x460c,
40-
@@ -4125,6 +4128,56 @@ static void mtk_set_mcr_max_rx(struct mt
40+
@@ -4178,6 +4181,56 @@ static void mtk_set_mcr_max_rx(struct mt
4141
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
4242
}
4343

@@ -63,7 +63,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
6363
+ mtk_hw_dump_reg(eth, "FE", 0x1400, 0x300);
6464
+ mtk_hw_dump_reg(eth, "ADMA", reg_map->pdma.rx_ptr, 0x300);
6565
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
66-
+ for (id = 0; id < MTK_QDMA_NUM_QUEUES / 16; id++) {
66+
+ for (id = 0; id < eth->soc->num_tx_queues / MTK_QTX_PER_PAGE; id++) {
6767
+ mtk_w32(eth, id, reg_map->qdma.page);
6868
+ pr_info("\nQDMA PAGE:%x ", mtk_r32(eth, reg_map->qdma.page));
6969
+ mtk_hw_dump_reg(eth, "QDMA", reg_map->qdma.qtx_cfg, 0x100);
@@ -94,7 +94,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
9494
static void mtk_hw_reset(struct mtk_eth *eth)
9595
{
9696
u32 val;
97-
@@ -4604,6 +4657,8 @@ static void mtk_pending_work(struct work
97+
@@ -4657,6 +4710,8 @@ static void mtk_pending_work(struct work
9898
rtnl_lock();
9999
set_bit(MTK_RESETTING, &eth->state);
100100

@@ -105,7 +105,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
105105
/* Run again reset preliminary configuration in order to avoid any
106106
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
107107
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
108-
@@ -1192,6 +1192,7 @@ struct mtk_reg_map {
108+
@@ -1200,6 +1200,7 @@ struct mtk_reg_map {
109109
u32 rx_ptr; /* rx base pointer */
110110
u32 rx_cnt_cfg; /* rx max count configuration */
111111
u32 qcrx_ptr; /* rx cpu pointer */
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
From 75baf4f561029dc48a5b244320c50773356f9f3e Mon Sep 17 00:00:00 2001
2+
From: Daniel Golle <daniel@makrotopia.org>
3+
Date: Thu, 23 Apr 2026 15:08:11 +0100
4+
Subject: [PATCH 1/9] net: ethernet: mtk_ppe_offload: use
5+
rhashtable_lookup_fast in flow ops
6+
7+
mtk_flow_offload_replace(), mtk_flow_offload_destroy() and
8+
mtk_flow_offload_stats() look up the flow hash table with
9+
rhashtable_lookup(), which is annotated __must_hold_shared(RCU)
10+
and, per kerneldoc, "must only be called under the RCU read lock."
11+
12+
All three call sites run under mtk_flow_offload_mutex but without
13+
an explicit rcu_read_lock(), so CONFIG_PROVE_RCU trips:
14+
15+
suspicious rcu_dereference_check() usage!
16+
include/linux/rhashtable.h:632 ...
17+
Call trace:
18+
mtk_flow_offload_replace+0x...
19+
mtk_flow_offload_cmd+0x...
20+
...
21+
22+
Switch to rhashtable_lookup_fast(), which takes the RCU read lock
23+
around the lookup internally. The driver's mutex keeps the entry
24+
pointer alive past the rhashtable_lookup_fast() call -- exactly the
25+
"other mechanism guaranteeing that the object won't go away" that
26+
rhashtable_lookup_fast()'s kerneldoc requires.
27+
28+
No functional change; just silences a lockdep false positive.
29+
30+
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
31+
---
32+
drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 11 ++++++-----
33+
1 file changed, 6 insertions(+), 5 deletions(-)
34+
35+
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
36+
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
37+
@@ -261,7 +261,8 @@ mtk_flow_offload_replace(struct mtk_eth
38+
int err = 0;
39+
int i;
40+
41+
- if (rhashtable_lookup(&eth->flow_table, &f->cookie, mtk_flow_ht_params))
42+
+ if (rhashtable_lookup_fast(&eth->flow_table, &f->cookie,
43+
+ mtk_flow_ht_params))
44+
return -EEXIST;
45+
46+
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) {
47+
@@ -503,8 +504,8 @@ mtk_flow_offload_destroy(struct mtk_eth
48+
{
49+
struct mtk_flow_entry *entry;
50+
51+
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
52+
- mtk_flow_ht_params);
53+
+ entry = rhashtable_lookup_fast(&eth->flow_table, &f->cookie,
54+
+ mtk_flow_ht_params);
55+
if (!entry)
56+
return -ENOENT;
57+
58+
@@ -525,8 +526,8 @@ mtk_flow_offload_stats(struct mtk_eth *e
59+
u64 packets, bytes;
60+
int idle;
61+
62+
- entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
63+
- mtk_flow_ht_params);
64+
+ entry = rhashtable_lookup_fast(&eth->flow_table, &f->cookie,
65+
+ mtk_flow_ht_params);
66+
if (!entry)
67+
return -ENOENT;
68+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
From daa37761de13976153502332f2fa675bd3761cc4 Mon Sep 17 00:00:00 2001
2+
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
3+
Date: Thu, 23 Apr 2026 13:56:30 +0100
4+
Subject: [PATCH 2/9] net: ethernet: mtk_ppe: set tport_idx on netsys_v3 for
5+
QoS
6+
7+
On MT7988 (netsys_v3) the PPE MAC info block carries a transport
8+
port index field. When not set, ETH-to-ETH and WiFi-to-ETH hardware-
9+
offloaded flows do not enter QDMA for scheduling, even with
10+
IB2_PSE_QOS programmed on the entry -- the packet bypasses the
11+
QDMA scheduler entirely, so any per-queue shaping installed
12+
downstream has no effect.
13+
14+
Populate the netsys_v3 tport/tinfo fields in struct mtk_foe_mac_info
15+
and set TPORT_IDX=1 from mtk_foe_entry_set_queue() on v3+.
16+
No functional change on netsys_v1 or v2.
17+
18+
The hard-coded value 1 matches MediaTek's reference driver; the
19+
datasheet may define additional transport modes, but none are in use
20+
by in-tree consumers.
21+
22+
Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
23+
[Daniel Golle: hoist l2 declaration to function top per kernel C89 style]
24+
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
25+
---
26+
drivers/net/ethernet/mediatek/mtk_ppe.c | 7 +++++++
27+
drivers/net/ethernet/mediatek/mtk_ppe.h | 4 ++++
28+
2 files changed, 11 insertions(+)
29+
30+
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
31+
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
32+
@@ -479,6 +479,7 @@ int mtk_foe_entry_set_queue(struct mtk_e
33+
unsigned int queue)
34+
{
35+
u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
36+
+ struct mtk_foe_mac_info *l2;
37+
38+
if (mtk_is_netsys_v2_or_greater(eth)) {
39+
*ib2 &= ~MTK_FOE_IB2_QID_V2;
40+
@@ -490,6 +491,12 @@ int mtk_foe_entry_set_queue(struct mtk_e
41+
*ib2 |= MTK_FOE_IB2_PSE_QOS;
42+
}
43+
44+
+ if (mtk_is_netsys_v3_or_greater(eth)) {
45+
+ l2 = mtk_foe_entry_l2(eth, entry);
46+
+ l2->tport &= ~MTK_FOE_TPORT_IDX;
47+
+ l2->tport |= FIELD_PREP(MTK_FOE_TPORT_IDX, 1);
48+
+ }
49+
+
50+
return 0;
51+
}
52+
53+
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
54+
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
55+
@@ -96,6 +96,8 @@ enum {
56+
#define MTK_FOE_WINFO_AMSDU_HF BIT(23)
57+
#define MTK_FOE_WINFO_AMSDU_EN BIT(24)
58+
59+
+#define MTK_FOE_TPORT_IDX GENMASK(3, 0)
60+
+
61+
enum {
62+
MTK_FOE_STATE_INVALID,
63+
MTK_FOE_STATE_UNBIND,
64+
@@ -124,6 +126,8 @@ struct mtk_foe_mac_info {
65+
/* netsys_v3 */
66+
u32 w3info;
67+
u32 amsdu;
68+
+ u16 tinfo;
69+
+ u16 tport;
70+
};
71+
72+
/* software-only entry type */
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
From eef4108f42f1b6e41274be5220253b2cd37ae8d1 Mon Sep 17 00:00:00 2001
2+
From: Daniel Golle <daniel@makrotopia.org>
3+
Date: Thu, 23 Apr 2026 13:57:37 +0100
4+
Subject: [PATCH 3/9] net: ethernet: mtk_ppe_offload: set output device before
5+
VLAN/PPPoE push
6+
7+
In mtk_flow_offload_replace(), run mtk_flow_set_output_device() and
8+
mtk_wed_flow_add() before the VLAN push loop and PPPoE push, rather
9+
than after them.
10+
11+
Today this is a no-op: set_output_device() on the DSA_TAG_PROTO_MTK
12+
path writes the special-tag etype into the L2 block, not a VLAN, so
13+
the relative order of VLAN push and output-device setup does not
14+
matter. The WED path likewise does not stack any VLANs.
15+
16+
This prepares the ground for taggers whose output-device setup
17+
pushes an outer 802.1Q tag (e.g. DSA_TAG_PROTO_MXL862_8021Q) which
18+
must land in vlan1 so that subsequent user VLANs stack into vlan2.
19+
Getting that order wrong would put the DSA outer tag in vlan2 and
20+
the user VLAN in vlan1, which the switch catchall strip rule would
21+
then remove from the wrong layer.
22+
23+
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
24+
---
25+
drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 16 ++++++++--------
26+
1 file changed, 8 insertions(+), 8 deletions(-)
27+
28+
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
29+
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
30+
@@ -453,6 +453,14 @@ mtk_flow_offload_replace(struct mtk_eth
31+
return err;
32+
}
33+
34+
+ err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest,
35+
+ &wed_index);
36+
+ if (err)
37+
+ return err;
38+
+
39+
+ if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
40+
+ return err;
41+
+
42+
if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE)
43+
foe.bridge.vlan = data.vlan_in;
44+
45+
@@ -462,14 +470,6 @@ mtk_flow_offload_replace(struct mtk_eth
46+
if (data.pppoe.num == 1)
47+
mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid);
48+
49+
- err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest,
50+
- &wed_index);
51+
- if (err)
52+
- return err;
53+
-
54+
- if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
55+
- return err;
56+
-
57+
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
58+
if (!entry)
59+
return -ENOMEM;

0 commit comments

Comments
 (0)