[][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/misc.c b/feed/kernel/tops/src/misc.c
new file mode 100644
index 0000000..c61f647
--- /dev/null
+++ b/feed/kernel/tops/src/misc.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Alvin Kuo <alvin.kuo@mediatek.com>
+ */
+
+#include "tops/internal.h"
+#include "tops/misc.h"
+#include "tops/mbox.h"
+#include "tops/netsys.h"
+
+static struct mailbox_dev offload_send_mbox_dev[CORE_OFFLOAD_NUM] = {
+		[CORE_OFFLOAD_0] = MBOX_SEND_OFFLOAD_DEV(0, MISC),
+		[CORE_OFFLOAD_1] = MBOX_SEND_OFFLOAD_DEV(1, MISC),
+		[CORE_OFFLOAD_2] = MBOX_SEND_OFFLOAD_DEV(2, MISC),
+		[CORE_OFFLOAD_3] = MBOX_SEND_OFFLOAD_DEV(3, MISC),
+};
+
+int mtk_tops_misc_set_ppe_num(void)
+{
+	struct mailbox_msg msg = {
+		.msg1 = MISC_CMD_TYPE_SET_PPE_NUM,
+		.msg2 = mtk_tops_netsys_ppe_get_num(),
+	};
+	enum core_id core;
+	int ret;
+
+	for (core = CORE_OFFLOAD_0; core < CORE_OFFLOAD_NUM; core++) {
+		ret = mbox_send_msg_no_wait(&offload_send_mbox_dev[core], &msg);
+		/* TODO: error handle? */
+		if (ret)
+			TOPS_ERR("core offload%u set PPE num failed: %d\n",
+				 core, ret);
+	}
+
+	return ret;
+}
+
+int mtk_tops_misc_init(struct platform_device *pdev)
+{
+	enum core_id core;
+	int ret;
+
+	for (core = CORE_OFFLOAD_0; core < CORE_OFFLOAD_NUM; core++) {
+		ret = register_mbox_dev(MBOX_SEND, &offload_send_mbox_dev[core]);
+		if (ret)
+			goto err_out;
+	}
+
+	return ret;
+
+err_out:
+	for (; core > 0; core--)
+		unregister_mbox_dev(MBOX_SEND, &offload_send_mbox_dev[core - 1]);
+
+	return ret;
+}
+
+void mtk_tops_misc_deinit(struct platform_device *pdev)
+{
+	enum core_id core;
+
+	for (core = CORE_OFFLOAD_0; core < CORE_OFFLOAD_NUM; core++)
+		unregister_mbox_dev(MBOX_SEND, &offload_send_mbox_dev[core]);
+}