[][openwrt][mt7988][tops][fix 3 PPE feature issue]

[Description]
Fix tunnel decapsulation can not be bound by PPE and encapsulation
unexpectedly dropped to APMCU issues.

Since HNAT has enabled 3 PPE capability, it will forward ingress packets
to different PPE according to their sport. However, this feature will
cause some problem for tunnel offload because TOPS explicitly overwrites
Fport by CLS HW rather than following ETH/HNAT GDM's configuration.
Furthermore, this overwritten Fport will cause HNAT driver to lookup a
wrong PPE table.

Eventually, the packets that are decap'ed and forwarded by TOPS are sent
to a different PPE which is not HNAT driver expected. Thus, HNAT will find
an invalid entry and not able to bind that flow even though that flow is
actually rate reach in another PPE.

To fix this issue, TOPS CLS rule is updated according to the system's 3
PPE feature is enabled or not. If the feature is not enabled, CLS Fport
rule will set to original PPE0. Otherwise, Fport will be set to PPE1 since
we expect all tunnel packets are coming from GDM2.

The encapsulation also has problem because TOPS MCU will try to find PPE's
flow entry before packet encapsulation taken place. If the flow entry can
not be correctly found, TOPS MCU will forward that packet to APMCU.

[Release-log]
N/A

Change-Id: Ic5b8f33b904318829f6f13e90828b9e7cdc2f9d3
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8684603
diff --git a/feed/kernel/tops/src/netsys.c b/feed/kernel/tops/src/netsys.c
index 50513d8..e1770c9 100644
--- a/feed/kernel/tops/src/netsys.c
+++ b/feed/kernel/tops/src/netsys.c
@@ -32,6 +32,7 @@
 
 struct netsys_hw {
 	void __iomem *base;
+	u32 ppe_num;
 };
 
 static struct netsys_hw netsys;
@@ -111,6 +112,11 @@
 	return 0;
 }
 
+u32 mtk_tops_netsys_ppe_get_num(void)
+{
+	return netsys.ppe_num;
+}
+
 u32 mtk_tops_netsys_ppe_get_max_entry_num(u32 ppe_id)
 {
 	u32 tbl_entry_num;
@@ -132,7 +138,7 @@
 	return PPE_DEFAULT_ENTRY_SIZE << tbl_entry_num;
 }
 
-int mtk_tops_netsys_init(struct platform_device *pdev)
+static int mtk_tops_netsys_base_init(struct platform_device *pdev)
 {
 	struct device_node *fe_mem = NULL;
 	struct resource res;
@@ -144,12 +150,57 @@
 		return -ENODEV;
 	}
 
-	if (of_address_to_resource(fe_mem, 0, &res))
-		return -ENXIO;
+	if (of_address_to_resource(fe_mem, 0, &res)) {
+		ret = -ENXIO;
+		goto out;
+	}
 
 	netsys.base = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
-	if (!netsys.base)
-		return -ENOMEM;
+	if (!netsys.base) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+out:
+	of_node_put(fe_mem);
+
+	return ret;
+}
+
+static int mtk_tops_netsys_ppe_num_init(struct platform_device *pdev)
+{
+	struct device_node *hnat = NULL;
+	u32 val = 0;
+	int ret = 0;
+
+	hnat = of_parse_phandle(pdev->dev.of_node, "hnat", 0);
+	if (!hnat) {
+		TOPS_ERR("can not find hnat node\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(hnat, "mtketh-ppe-num", &val);
+	if (ret)
+		netsys.ppe_num = 1;
+	else
+		netsys.ppe_num = val;
+
+	of_node_put(hnat);
+
+	return 0;
+}
+
+int mtk_tops_netsys_init(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = mtk_tops_netsys_base_init(pdev);
+	if (ret)
+		return ret;
+
+	ret = mtk_tops_netsys_ppe_num_init(pdev);
+	if (ret)
+		return ret;
 
 	ret = mtk_trm_hw_config_register(TRM_NETSYS, &netsys_trm_hw_cfg);
 	if (ret)