blob: bf557ee770887e3038c12f924aa25bc10f1377df [file] [log] [blame]
developer8cb3ac72022-07-04 10:55:14 +08001From a59cb5c770a694cb34ab179ec59e91ba5c39908b Mon Sep 17 00:00:00 2001
2From: Bo Jiao <Bo.Jiao@mediatek.com>
3Date: Mon, 27 Jun 2022 14:48:35 +0800
4Subject: [PATCH 6/8] 9995-flow-offload-add-mkhnat-dual-ppe-new-v2
5
6---
7 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 1 +
8 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 67 ++++++++++++++-----
9 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++-
10 drivers/net/ethernet/mediatek/mtk_ppe.c | 5 +-
11 drivers/net/ethernet/mediatek/mtk_ppe.h | 7 +-
12 .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 27 ++++++--
13 .../net/ethernet/mediatek/mtk_ppe_offload.c | 45 ++++++++++---
14 include/linux/netdevice.h | 4 ++
15 8 files changed, 125 insertions(+), 41 deletions(-)
16 mode change 100644 => 100755 drivers/net/ethernet/mediatek/mtk_ppe_offload.c
17
18diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
19index 7f78de6b9..381136c21 100644
20--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
21+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
22@@ -479,6 +479,7 @@
23 mediatek,ethsys = <&ethsys>;
24 mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
25 mediatek,wed = <&wed0>, <&wed1>;
26+ mtketh-ppe-num = <2>;
27 #reset-cells = <1>;
28 #address-cells = <1>;
29 #size-cells = <0>;
30diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
31index 01fc1e5c0..3f67bebfe 100644
32--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
33+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
developerdca0fde2022-12-14 11:40:35 +080034@@ -1732,6 +1732,7 @@ static int mtk_poll_rx(struct napi_struc
developer8cb3ac72022-07-04 10:55:14 +080035 u8 *data, *new_data;
developerdca0fde2022-12-14 11:40:35 +080036 struct mtk_rx_dma_v2 *rxd, trxd;
developer8cb3ac72022-07-04 10:55:14 +080037 int done = 0;
38+ int i;
39
40 if (unlikely(!ring))
41 goto rx_done;
developerdca0fde2022-12-14 11:40:35 +080042@@ -1843,14 +1844,20 @@ static int mtk_poll_rx(struct napi_struc
developer8cb3ac72022-07-04 10:55:14 +080043
developer231d3ac2023-03-15 10:25:01 +080044 #if defined(CONFIG_MEDIATEK_NETSYS_RX_V2)
developer8cb3ac72022-07-04 10:55:14 +080045 reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON_V2, trxd.rxd5);
46- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
47- mtk_ppe_check_skb(eth->ppe, skb,
48- trxd.rxd5 & MTK_RXD5_FOE_ENTRY_V2);
49+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
50+ for (i = 0; i < eth->ppe_num; i++) {
51+ mtk_ppe_check_skb(eth->ppe[i], skb,
52+ trxd.rxd5 & MTK_RXD5_FOE_ENTRY_V2);
53+ }
54+ }
55 #else
56 reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
57- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
58- mtk_ppe_check_skb(eth->ppe, skb,
59- trxd.rxd4 & MTK_RXD4_FOE_ENTRY);
60+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
61+ for (i = 0; i < eth->ppe_num; i++) {
62+ mtk_ppe_check_skb(eth->ppe[i], skb,
63+ trxd.rxd4 & MTK_RXD4_FOE_ENTRY);
64+ }
65+ }
66 #endif
67
68 if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
developerdca0fde2022-12-14 11:40:35 +080069@@ -3184,8 +3191,12 @@ static int mtk_open(struct net_device *d
70 if (!phy_node && eth->xgmii->regmap_sgmii[mac->id])
71 regmap_write(eth->xgmii->regmap_sgmii[mac->id], SGMSYS_QPHY_PWR_STATE_CTRL, 0);
developer8cb3ac72022-07-04 10:55:14 +080072
developerdca0fde2022-12-14 11:40:35 +080073- if (eth->soc->offload_version && mtk_ppe_start(&eth->ppe) == 0)
developer8cb3ac72022-07-04 10:55:14 +080074- gdm_config = MTK_GDMA_TO_PPE;
developerdca0fde2022-12-14 11:40:35 +080075+ if (eth->soc->offload_version) {
developer8cb3ac72022-07-04 10:55:14 +080076+ gdm_config = MTK_GDMA_TO_PPE0;
77+
78+ for (i = 0; i < eth->ppe_num; i++)
79+ mtk_ppe_start(eth->ppe[i]);
80+ }
81
developerdca0fde2022-12-14 11:40:35 +080082 mtk_gdm_config(eth, mac->id, gdm_config);
developer8cb3ac72022-07-04 10:55:14 +080083
developerdca0fde2022-12-14 11:40:35 +080084@@ -3268,8 +3279,10 @@ static int mtk_stop(struct net_device *d
developer8cb3ac72022-07-04 10:55:14 +080085
86 mtk_dma_free(eth);
87
88- if (eth->soc->offload_version)
89- mtk_ppe_stop(eth->ppe);
90+ if (eth->soc->offload_version) {
91+ for (i = 0; i < eth->ppe_num; i++)
92+ mtk_ppe_stop(eth->ppe[i]);
93+ }
94
95 return 0;
96 }
developerdca0fde2022-12-14 11:40:35 +080097@@ -4408,15 +4421,35 @@ static int mtk_probe(struct platform_dev
developer8cb3ac72022-07-04 10:55:14 +080098 }
99
100 if (eth->soc->offload_version) {
101- eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
102- if (!eth->ppe) {
103- err = -ENOMEM;
104- goto err_free_dev;
105+ unsigned int val;
106+
107+ err = of_property_read_u32_index(pdev->dev.of_node, "mtketh-ppe-num", 0, &val);
108+ if (err < 0)
109+ eth->ppe_num = 1;
110+ else
111+ eth->ppe_num = val;
112+
113+ if (eth->ppe_num > MTK_MAX_PPE_NUM) {
114+ dev_warn(&pdev->dev, "%d is not a valid ppe num, please check mtketh-ppe-num in dts !", eth->ppe_num);
115+ eth->ppe_num = MTK_MAX_PPE_NUM;
116 }
117
118- err = mtk_eth_offload_init(eth);
119- if (err)
120- goto err_free_dev;
121+ dev_info(&pdev->dev, "ppe num = %d\n", eth->ppe_num);
122+
123+ for (i = 0; i < eth->ppe_num; i++) {
124+ eth->ppe[i] = mtk_ppe_init(eth,
125+ eth->base + MTK_ETH_PPE_BASE + i * 0x400, 2, i);
126+ if (!eth->ppe[i]) {
127+ err = -ENOMEM;
128+ goto err_free_dev;
129+ }
130+
131+ err = mtk_eth_offload_init(eth, i);
132+ if (err)
133+ goto err_free_dev;
134+ }
135+
136+ mtk_ppe_debugfs_init(eth);
137 }
138
139 for (i = 0; i < MTK_MAX_DEVS; i++) {
140diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
141index fce1a7172..b4de7c0c6 100644
142--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
143+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
developerdca0fde2022-12-14 11:40:35 +0800144@@ -118,7 +118,12 @@
developer8cb3ac72022-07-04 10:55:14 +0800145 #define MTK_GDMA_UCS_EN BIT(20)
developerdca0fde2022-12-14 11:40:35 +0800146 #define MTK_GDMA_STRP_CRC BIT(16)
developer8cb3ac72022-07-04 10:55:14 +0800147 #define MTK_GDMA_TO_PDMA 0x0
148-#define MTK_GDMA_TO_PPE 0x3333
developer57382532022-07-06 11:59:11 +0800149+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
developer8cb3ac72022-07-04 10:55:14 +0800150+#define MTK_GDMA_TO_PPE0 0x3333
151+#define MTK_GDMA_TO_PPE1 0x4444
developer57382532022-07-06 11:59:11 +0800152+#else
153+#define MTK_GDMA_TO_PPE0 0x4444
154+#endif
developer8cb3ac72022-07-04 10:55:14 +0800155 #define MTK_GDMA_DROP_ALL 0x7777
156
developerdca0fde2022-12-14 11:40:35 +0800157 /* GDM Egress Control Register */
158@@ -1612,7 +1617,8 @@ struct mtk_eth {
developer8cb3ac72022-07-04 10:55:14 +0800159 spinlock_t syscfg0_lock;
160 struct timer_list mtk_dma_monitor_timer;
161
162- struct mtk_ppe *ppe;
163+ u8 ppe_num;
164+ struct mtk_ppe *ppe[MTK_MAX_PPE_NUM];
165 struct rhashtable flow_table;
166 };
167
developer16b22152023-06-01 13:48:39 +0800168@@ -1668,9 +1674,11 @@ int mtk_gmac_usxgmii_path_setup(struct m
developer1fb19c92023-03-07 23:45:23 +0800169 void mtk_usxgmii_reset(struct mtk_xgmii *ss, int mac_id);
170 int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
developer8cb3ac72022-07-04 10:55:14 +0800171
172-int mtk_eth_offload_init(struct mtk_eth *eth);
173+int mtk_eth_offload_init(struct mtk_eth *eth, int id);
174 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
175 void *type_data);
176 void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
developer16b22152023-06-01 13:48:39 +0800177 int mtk_rss_set_indr_tbl(struct mtk_eth *eth, int num);
developer8cb3ac72022-07-04 10:55:14 +0800178+
developer1fb19c92023-03-07 23:45:23 +0800179+int mtk_ppe_debugfs_init(struct mtk_eth *eth);
180 #endif /* MTK_ETH_H */
developer8cb3ac72022-07-04 10:55:14 +0800181diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
182index d46e91178..3d6ff30ba 100755
183--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
184+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
185@@ -677,7 +677,7 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
186 }
187
188 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
189- int version)
190+ int version, int id)
191 {
192 struct device *dev = eth->dev;
193 struct mtk_foe_entry *foe;
194@@ -696,6 +696,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
195 ppe->eth = eth;
196 ppe->dev = dev;
197 ppe->version = version;
198+ ppe->id = id;
199
200 foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
201 &ppe->foe_phys, GFP_KERNEL);
202@@ -704,8 +705,6 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
203
204 ppe->foe_table = foe;
205
206- mtk_ppe_debugfs_init(ppe);
207-
208 return ppe;
209 }
210
211diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
212index a76f4b0ac..21cc55145 100644
213--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
214+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
developer7c939fe2022-08-22 13:16:56 +0800215@@ -8,10 +8,12 @@
developer8cb3ac72022-07-04 10:55:14 +0800216 #include <linux/bitfield.h>
217 #include <linux/rhashtable.h>
218
developer7c939fe2022-08-22 13:16:56 +0800219 #if defined(CONFIG_MEDIATEK_NETSYS_V2)
developer8cb3ac72022-07-04 10:55:14 +0800220+#define MTK_MAX_PPE_NUM 2
developer8cb3ac72022-07-04 10:55:14 +0800221 #define MTK_ETH_PPE_BASE 0x2000
developer7c939fe2022-08-22 13:16:56 +0800222 #else
223+#define MTK_MAX_PPE_NUM 1
224 #define MTK_ETH_PPE_BASE 0xc00
225 #endif
developer8cb3ac72022-07-04 10:55:14 +0800226
227 #define MTK_PPE_ENTRIES_SHIFT 3
228@@ -253,6 +255,7 @@ struct mtk_flow_entry {
229 };
230 };
231 u8 type;
232+ s8 ppe_index;
233 s8 wed_index;
234 u16 hash;
235 union {
236@@ -272,6 +275,7 @@ struct mtk_ppe {
237 struct device *dev;
238 void __iomem *base;
239 int version;
240+ int id;
241
242 struct mtk_foe_entry *foe_table;
243 dma_addr_t foe_phys;
244@@ -284,7 +288,7 @@ struct mtk_ppe {
245 void *acct_table;
246 };
247
248-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
249+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version, int id);
250 int mtk_ppe_start(struct mtk_ppe *ppe);
251 int mtk_ppe_stop(struct mtk_ppe *ppe);
252
253@@ -335,6 +339,5 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
254 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
255 void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
256 int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
257-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
258
259 #endif
260diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
261index a591ab1fd..f4ebe5944 100644
262--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
263+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
264@@ -73,9 +73,8 @@ mtk_print_addr_info(struct seq_file *m, struct mtk_flow_addr_info *ai)
265 }
266
267 static int
268-mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
269+mtk_ppe_debugfs_foe_show(struct seq_file *m, struct mtk_ppe *ppe, bool bind)
270 {
271- struct mtk_ppe *ppe = m->private;
272 int i;
273
274 for (i = 0; i < MTK_PPE_ENTRIES; i++) {
275@@ -122,6 +121,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
276 break;
277 }
278
279+ seq_printf(m, " ppe=%d", ppe->id);
280+
281 seq_printf(m, " orig=");
282 mtk_print_addr_info(m, &ai);
283
284@@ -164,13 +165,25 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
285 static int
286 mtk_ppe_debugfs_foe_show_all(struct seq_file *m, void *private)
287 {
288- return mtk_ppe_debugfs_foe_show(m, private, false);
289+ struct mtk_eth *eth = m->private;
290+ int i;
291+
292+ for (i = 0; i < eth->ppe_num; i++)
293+ mtk_ppe_debugfs_foe_show(m, eth->ppe[i], false);
294+
295+ return 0;
296 }
297
298 static int
299 mtk_ppe_debugfs_foe_show_bind(struct seq_file *m, void *private)
300 {
301- return mtk_ppe_debugfs_foe_show(m, private, true);
302+ struct mtk_eth *eth = m->private;
303+ int i;
304+
305+ for (i = 0; i < eth->ppe_num; i++)
306+ mtk_ppe_debugfs_foe_show(m, eth->ppe[i], true);
307+
308+ return 0;
309 }
310
311 static int
312@@ -187,7 +200,7 @@ mtk_ppe_debugfs_foe_open_bind(struct inode *inode, struct file *file)
313 inode->i_private);
314 }
315
316-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
317+int mtk_ppe_debugfs_init(struct mtk_eth *eth)
318 {
319 static const struct file_operations fops_all = {
320 .open = mtk_ppe_debugfs_foe_open_all,
321@@ -209,8 +222,8 @@ int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
322 if (!root)
323 return -ENOMEM;
324
325- debugfs_create_file("entries", S_IRUGO, root, ppe, &fops_all);
326- debugfs_create_file("bind", S_IRUGO, root, ppe, &fops_bind);
327+ debugfs_create_file("entries", S_IRUGO, root, eth, &fops_all);
328+ debugfs_create_file("bind", S_IRUGO, root, eth, &fops_bind);
329
330 return 0;
331 }
332diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
333old mode 100644
334new mode 100755
335index 5a4201447..2f7d76d3b
336--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
337+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
338@@ -226,8 +226,10 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
339 struct flow_action_entry *act;
340 struct mtk_flow_data data = {};
341 struct mtk_foe_entry foe;
342- struct net_device *odev = NULL;
343+ struct net_device *idev = NULL, *odev = NULL;
344 struct mtk_flow_entry *entry;
345+ struct net_device_path_ctx ctx = {};
346+ struct net_device_path path = {};
347 int offload_type = 0;
348 int wed_index = -1;
349 u16 addr_type = 0;
350@@ -242,6 +244,10 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
351 struct flow_match_meta match;
352
353 flow_rule_match_meta(rule, &match);
354+ idev = __dev_get_by_index(&init_net, match.key->ingress_ifindex);
355+
356+ if (!idev)
357+ pr_info("[%s] idev doesn't exist !\n", __func__);
358 } else {
359 return -EOPNOTSUPP;
360 }
developer7c939fe2022-08-22 13:16:56 +0800361@@ -435,11 +441,27 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
developer8cb3ac72022-07-04 10:55:14 +0800362 if (!entry)
363 return -ENOMEM;
364
365+ i = 0;
developer7c939fe2022-08-22 13:16:56 +0800366+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
developer8cb3ac72022-07-04 10:55:14 +0800367+ if (idev && idev->netdev_ops->ndo_fill_receive_path) {
368+ ctx.dev = idev;
369+ idev->netdev_ops->ndo_fill_receive_path(&ctx, &path);
370+ i = path.mtk_wdma.wdma_idx;
371+ if (i >= eth->ppe_num) {
372+ if (printk_ratelimit())
373+ pr_info("[%s] PPE%d doesn't exist, please check mtketh-ppe-num in dts !\n", __func__, i);
374+
375+ return -EINVAL;
376+ }
377+ }
developer7c939fe2022-08-22 13:16:56 +0800378+#endif
developer8cb3ac72022-07-04 10:55:14 +0800379+
380 entry->cookie = f->cookie;
381 memcpy(&entry->data, &foe, sizeof(entry->data));
382+ entry->ppe_index = i;
383 entry->wed_index = wed_index;
384
385- if (mtk_foe_entry_commit(eth->ppe, entry) < 0)
386+ if (mtk_foe_entry_commit(eth->ppe[i], entry) < 0)
387 goto free;
388
389 err = rhashtable_insert_fast(&eth->flow_table, &entry->node,
390@@ -450,7 +470,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
391 return 0;
392
393 clear:
394- mtk_foe_entry_clear(eth->ppe, entry);
395+ mtk_foe_entry_clear(eth->ppe[i], entry);
396 free:
397 kfree(entry);
398 if (wed_index >= 0)
399@@ -462,13 +482,15 @@ static int
400 mtk_flow_offload_destroy(struct mtk_eth *eth, struct flow_cls_offload *f)
401 {
402 struct mtk_flow_entry *entry;
403+ int i;
404
405 entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
406 mtk_flow_ht_params);
407 if (!entry)
408 return -ENOENT;
409
410- mtk_foe_entry_clear(eth->ppe, entry);
411+ i = entry->ppe_index;
412+ mtk_foe_entry_clear(eth->ppe[i], entry);
413 rhashtable_remove_fast(&eth->flow_table, &entry->node,
414 mtk_flow_ht_params);
415 if (entry->wed_index >= 0)
416@@ -483,13 +505,15 @@ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
417 {
418 struct mtk_flow_entry *entry;
419 u32 idle;
420+ int i;
421
422 entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
423 mtk_flow_ht_params);
424 if (!entry)
425 return -ENOENT;
426
427- idle = mtk_foe_entry_idle_time(eth->ppe, entry);
428+ i = entry->ppe_index;
429+ idle = mtk_foe_entry_idle_time(eth->ppe[i], entry);
430 f->stats.lastused = jiffies - idle * HZ;
431
432 return 0;
developer207b39d2022-10-07 15:57:16 +0800433@@ -540,12 +564,14 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
developer8cb3ac72022-07-04 10:55:14 +0800434 static LIST_HEAD(block_cb_list);
435 struct flow_block_cb *block_cb;
436 flow_setup_cb_t *cb;
developer207b39d2022-10-07 15:57:16 +0800437- int err = 0;
438+ int i, err = 0;
439
440 flowtable = container_of(f->block, struct nf_flowtable, flow_block);
developer8cb3ac72022-07-04 10:55:14 +0800441
442- if (!eth->ppe || !eth->ppe->foe_table)
443- return -EOPNOTSUPP;
444+ for (i = 0; i < eth->ppe_num; i++) {
445+ if (!eth->ppe[i] || !eth->ppe[i]->foe_table)
446+ return -EOPNOTSUPP;
447+ }
448
449 if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
450 return -EOPNOTSUPP;
451@@ -591,9 +618,9 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
452 }
453 }
454
455-int mtk_eth_offload_init(struct mtk_eth *eth)
456+int mtk_eth_offload_init(struct mtk_eth *eth, int id)
457 {
458- if (!eth->ppe || !eth->ppe->foe_table)
459+ if (!eth->ppe[id] || !eth->ppe[id]->foe_table)
460 return 0;
461
462 return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
463diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
464index 35998b1a7..0ada2461b 100644
465--- a/include/linux/netdevice.h
466+++ b/include/linux/netdevice.h
467@@ -1302,6 +1302,8 @@ struct tlsdev_ops;
468 * rtnl_lock is not held.
469 * int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path);
470 * Get the forwarding path to reach the real device from the HW destination address
471+ * int (*ndo_fill_receive_path)(struct net_device_path_ctx *ctx, struct net_device_path *path);
472+ * Get the receiving path to reach the real device from the HW source address
473 */
474 struct net_device_ops {
475 int (*ndo_init)(struct net_device *dev);
476@@ -1501,6 +1503,8 @@ struct net_device_ops {
477 struct devlink_port * (*ndo_get_devlink_port)(struct net_device *dev);
478 int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx,
479 struct net_device_path *path);
480+ int (*ndo_fill_receive_path)(struct net_device_path_ctx *ctx,
481+ struct net_device_path *path);
482 };
483
484 /**
485--
4862.18.0
487