[][openwrt][mt7988][tops][support v1.1.0]

[Description]
Add support to TOPS v1.1.0 with latest driver and firmware
1. Support TOPS mini network stack
   Refactor codes to improve the reusability of tunnel parameter fetching
   process.
2. Change flow table's tunnel arrangement to align with TOPS mini network
   stack
3. TOPS firmware support reorder Tx/Rx process
   Add some flexibilities to support more applications.
4. Update debug commands
   4.1 Add command to show registered tunnel parameters
   4.2 Update command to register debug tunnel parameters
5. Fix minor bugs
   5.1 coding defects
   5.2 tunnel binding mechanism bugs
6. Support tunnel protocol
   6.1 L2oGRE

[Release-log]
N/A

Change-Id: Idd6b6e0fb0495d21062ededd8b010dc14af317ff
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8319846
diff --git a/package-21.02/kernel/tops/src/debugfs.c b/package-21.02/kernel/tops/src/debugfs.c
new file mode 100644
index 0000000..d2c40cf
--- /dev/null
+++ b/package-21.02/kernel/tops/src/debugfs.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Mediatek Inc. All Rights Reserved.
+ *
+ * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/inet.h>
+#include <linux/uaccess.h>
+
+#include "tops/debugfs.h"
+#include "tops/firmware.h"
+#include "tops/internal.h"
+#include "tops/mcu.h"
+#include "tops/trm.h"
+#include "tops/tunnel.h"
+#include "tops/wdt.h"
+
+static const char *tops_role_name[__TOPS_ROLE_TYPE_MAX] = {
+	[TOPS_ROLE_TYPE_MGMT] = "tops-mgmt",
+	[TOPS_ROLE_TYPE_CLUSTER] = "tops-offload",
+};
+
+static struct dentry *tops_fw_debugfs_root;
+
+static int tops_fw_info_show(struct seq_file *s, void *private)
+{
+	enum tops_role_type rtype;
+	struct tm tm = {0};
+	const char *value;
+	const char *prop;
+	u32 nattr;
+	u32 i;
+
+	for (rtype = TOPS_ROLE_TYPE_MGMT; rtype < __TOPS_ROLE_TYPE_MAX; rtype++) {
+		mtk_tops_fw_get_built_date(rtype, &tm);
+
+		seq_printf(s, "%s FW information:\n", tops_role_name[rtype]);
+		seq_printf(s, "Git revision:\t%llx\n",
+			   mtk_tops_fw_get_git_commit_id(rtype));
+		seq_printf(s, "Build date:\t%04ld/%02d/%02d %02d:%02d:%02d\n",
+			   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+			   tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+		nattr = mtk_tops_fw_attr_get_num(rtype);
+
+		for (i = 0; i < nattr; i++) {
+			prop = mtk_tops_fw_attr_get_property(rtype, i);
+			if (!prop)
+				continue;
+
+			value = mtk_tops_fw_attr_get_value(rtype, prop);
+
+			seq_printf(s, "%s:\t%s\n", prop, value);
+		}
+		seq_puts(s, "\n");
+	}
+
+	return 0;
+}
+
+static int tops_tnl_show(struct seq_file *s, void *private)
+{
+	struct tops_tnl_info *tnl_info;
+	struct tops_tnl_params *tnl_params;
+	u32 i;
+
+	for (i = 0; i < CONFIG_TOPS_TNL_NUM; i++) {
+		tnl_info = mtk_tops_tnl_info_get_by_idx(i);
+		if (IS_ERR(tnl_info))
+			/* tunnel not enabled */
+			continue;
+
+		tnl_params = &tnl_info->tnl_params;
+		if (!tnl_info->tnl_type || !tnl_info->tnl_type->tnl_param_dump)
+			continue;
+
+		seq_printf(s, "Tunnel Index: %02u\n", i);
+
+		mtk_tops_mac_param_dump(s, &tnl_params->params);
+
+		mtk_tops_network_param_dump(s, &tnl_params->params);
+
+		mtk_tops_transport_param_dump(s, &tnl_params->params);
+
+		tnl_info->tnl_type->tnl_param_dump(s, &tnl_params->params);
+
+		seq_printf(s, "\tTOPS Entry: %02u CLS Entry: %02u CDRT: %02u Flag: 0x%x\n",
+			   tnl_params->tops_entry_proto,
+			   tnl_params->cls_entry,
+			   tnl_params->cdrt,
+			   tnl_params->flag);
+	}
+
+	return 0;
+}
+
+static int tops_tnl_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, tops_tnl_show, file->private_data);
+}
+
+static int tops_tnl_add_new_tnl(const char *buf)
+{
+	struct tops_tnl_params tnl_params;
+	struct tops_params *params;
+	struct tops_tnl_info *tnl_info;
+	struct tops_tnl_type *tnl_type;
+	char proto[DEBUG_PROTO_LEN];
+	int ofs = 0;
+	int ret = 0;
+
+	memset(&tnl_params, 0, sizeof(struct tops_tnl_params));
+	memset(proto, 0, sizeof(proto));
+
+	params = &tnl_params.params;
+
+	ret = mtk_tops_debug_param_setup(buf, &ofs, params);
+	if (ret)
+		return ret;
+
+	ret = mtk_tops_debug_param_proto_peek(buf, ofs, proto);
+	if (ret < 0)
+		return ret;
+
+	ofs += ret;
+
+	tnl_type = mtk_tops_tnl_type_get_by_name(proto);
+	if (!tnl_type || !tnl_type->tnl_debug_param_setup)
+		return -ENODEV;
+
+	ret = tnl_type->tnl_debug_param_setup(buf, &ofs, params);
+	if (ret < 0)
+		return ret;
+
+	tnl_params.flag |= TNL_DECAP_ENABLE;
+	tnl_params.flag |= TNL_ENCAP_ENABLE;
+	tnl_params.tops_entry_proto = tnl_type->tnl_proto_type;
+
+	tnl_info = mtk_tops_tnl_info_alloc(tnl_type);
+	if (IS_ERR(tnl_info))
+		return -ENOMEM;
+
+	tnl_info->flag |= TNL_INFO_DEBUG;
+	memcpy(&tnl_info->cache, &tnl_params, sizeof(struct tops_tnl_params));
+
+	mtk_tops_tnl_info_hash(tnl_info);
+
+	mtk_tops_tnl_info_submit(tnl_info);
+
+	return 0;
+}
+
+static ssize_t tops_tnl_write(struct file *file, const char __user *buffer,
+			      size_t count, loff_t *data)
+{
+	char cmd[21] = {0};
+	char buf[512];
+	int nchar = 0;
+	int ret = 0;
+
+	if (count > sizeof(buf))
+		return -ENOMEM;
+
+	if (copy_from_user(buf, buffer, count))
+		return -EFAULT;
+
+	buf[count] = '\0';
+
+	ret = sscanf(buf, "%20s %n", cmd, &nchar);
+
+	if (ret != 1)
+		return -EPERM;
+
+	if (!strcmp(cmd, "NEW_TNL")) {
+		ret = tops_tnl_add_new_tnl(buf + nchar);
+		if (ret)
+			return ret;
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+DEFINE_SHOW_ATTRIBUTE(tops_fw_info);
+
+static const struct file_operations tops_tnl_fops = {
+	.open = tops_tnl_open,
+	.read = seq_read,
+	.write = tops_tnl_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+int mtk_tops_debugfs_init(struct platform_device *pdev)
+{
+	tops_fw_debugfs_root = debugfs_create_dir("fw", tops_debugfs_root);
+
+	debugfs_create_file("firmware_info", 0400, tops_fw_debugfs_root, NULL,
+			    &tops_fw_info_fops);
+
+	debugfs_create_file("tunnel", 0444, tops_fw_debugfs_root, NULL,
+			    &tops_tnl_fops);
+
+	return 0;
+}
+
+void mtk_tops_debugfs_deinit(struct platform_device *pdev)
+{
+	debugfs_remove_recursive(tops_fw_debugfs_root);
+}