[][Add toggle for uplink qos]

[Description]
Add toggle for uplink qos.
Because customer wants uplink traffic not go through qdma for higher t-put.

[Release-log]
N/A


Change-Id: Iecafc414b883dc245d8232b8cb2f83f4f289654c
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6783534
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index 9005ab2..d02a55b 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -1103,6 +1103,8 @@
 #define IS_GMAC1_MODE ((hnat_priv->gmac_num == 1) ? 1 : 0)
 #define IS_HQOS_MODE (qos_toggle == 1)
 #define IS_PPPQ_MODE (qos_toggle == 2)		/* Per Port Per Queue */
+#define IS_HQOS_DL_MODE (IS_HQOS_MODE && qos_dl_toggle)
+#define IS_HQOS_UL_MODE (IS_HQOS_MODE && qos_ul_toggle)
 #define MAX_PPPQ_PORT_NUM	6
 
 #define es(entry) (entry_state[entry->bfib1.state])
@@ -1182,6 +1184,8 @@
 		      struct packet_type *pt, struct net_device *unused);
 extern int dbg_cpu_reason;
 extern int debug_level;
+extern int qos_dl_toggle;
+extern int qos_ul_toggle;
 extern int hook_toggle;
 extern int mape_toggle;
 extern int qos_toggle;
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
index 3822b1a..1857e9b 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
@@ -28,6 +28,8 @@
 int hook_toggle;
 int mape_toggle;
 int qos_toggle;
+int qos_dl_toggle = 1;
+int qos_ul_toggle = 1;
 unsigned int dbg_cpu_reason_cnt[MAX_CRSN_NUM];
 
 static const char * const entry_state[] = { "INVALID", "UNBIND", "BIND", "FIN" };
@@ -2366,9 +2368,38 @@
 	.release = single_release,
 };
 
+static void hnat_qos_toggle_usage(void)
+{
+	pr_info("\nHQoS toggle Command Usage:\n");
+	pr_info("Show HQoS mode:\n");
+	pr_info("    cat /sys/kernel/debug/hnat/qos_toggle\n");
+	pr_info("Disable HQoS mode:\n");
+	pr_info("    echo 0 > /sys/kernel/debug/hnat/qos_toggle\n");
+	pr_info("Enable HQoS on bidirection:\n");
+	pr_info("    echo 1 > /sys/kernel/debug/hnat/qos_toggle\n");
+	pr_info("Enable HQoS on uplink only:\n");
+	pr_info("    echo 1 uplink > /sys/kernel/debug/hnat/qos_toggle\n");
+	pr_info("Enable HQoS on downlink only:\n");
+	pr_info("    echo 1 downlink > /sys/kernel/debug/hnat/qos_toggle\n");
+	pr_info("Enable Per-port-per-queue mode:\n");
+	pr_info("    echo 2 > /sys/kernel/debug/hnat/qos_toggle\n");
+	pr_info("Show HQoS toggle usage:\n");
+	pr_info("    echo 3 > /sys/kernel/debug/hnat/qos_toggle\n\n");
+}
+
 static int hnat_qos_toggle_read(struct seq_file *m, void *private)
 {
-	pr_info("value=%d, HQoS is %s now!\n", qos_toggle, (qos_toggle) ? "enabled" : "disabled");
+	if (qos_toggle == 0) {
+		pr_info("HQoS is disabled now!\n");
+	} else if (qos_toggle == 1) {
+		pr_info("HQoS is enabled now!\n");
+		pr_info("HQoS uplink is %s now!\n",
+				qos_ul_toggle ? "enabled" : "disabled");
+		pr_info("HQoS downlink is %s now!\n",
+				qos_dl_toggle ? "enabled" : "disabled");
+	} else if (qos_toggle == 2) {
+		pr_info("Per-port-per-queue mode is enabled!\n");
+	}
 
 	return 0;
 }
@@ -2446,24 +2477,63 @@
 static ssize_t hnat_qos_toggle_write(struct file *file, const char __user *buffer,
 				     size_t count, loff_t *data)
 {
-	char buf[8];
+	char buf[32], tmp[32];
 	int len = count;
+	char *p_buf = NULL, *p_token = NULL;
 
-	if ((len > 8) || copy_from_user(buf, buffer, len))
+	if (len  >= sizeof(buf))
+		return -EFAULT;
+
+	if (copy_from_user(buf, buffer, len))
 		return -EFAULT;
 
+	buf[len] = '\0';
+
 	if (buf[0] == '0') {
-		pr_info("HQoS is going to be disabled !\n");
+		pr_info("HQoS is going to be disabled!\n");
 		qos_toggle = 0;
+		qos_dl_toggle = 0;
+		qos_ul_toggle = 0;
 		hnat_qos_disable();
 	} else if (buf[0] == '1') {
-		pr_info("HQoS mode is going to be enabled !\n");
+		p_buf = buf;
+		p_token = strsep(&p_buf, " \t");
+		if (p_buf) {
+			memcpy(tmp, p_buf, strlen(p_buf));
+			tmp[len] = '\0';
+			if (!strncmp(tmp, "uplink", 6)) {
+				qos_dl_toggle = 0;
+				qos_ul_toggle = 1;
+			} else if (!strncmp(tmp, "downlink", 8)) {
+				qos_ul_toggle = 0;
+				qos_dl_toggle = 1;
+			} else {
+				pr_info("Direction should be uplink or downlink.\n");
+				hnat_qos_toggle_usage();
+				return len;
+			}
+		} else {
+			qos_ul_toggle = 1;
+			qos_dl_toggle = 1;
+		}
+		pr_info("HQoS mode is going to be enabled!\n");
+		pr_info("HQoS uplink is going to be %s!\n",
+				qos_ul_toggle ? "enabled" : "disabled");
+		pr_info("HQoS downlink is going to be %s!\n",
+				qos_dl_toggle ? "enabled" : "disabled");
 		qos_toggle = 1;
 	} else if (buf[0] == '2') {
-		pr_info("Per-port-per-queue mode is going to be enabled !\n");
+		pr_info("Per-port-per-queue mode is going to be enabled!\n");
 		pr_info("PPPQ use qid 0~5 (scheduler 0).\n");
 		qos_toggle = 2;
+		qos_dl_toggle = 0;
+		qos_ul_toggle = 0;
 		hnat_qos_pppq_enable();
+	} else if (buf[0] == '3') {
+		hnat_qos_toggle_usage();
+	} else {
+		pr_info("Input error!\n");
+		hnat_qos_toggle_usage();
 	}
 
 	return len;
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 0de1740..0939f07 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -1445,7 +1445,11 @@
 						 hnat_priv->data->version == MTK_HNAT_V5) ?
 						 skb->mark & 0x7f : skb->mark & 0xf;
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-					entry.ipv4_hnapt.tport_id = 1;
+					if ((IS_WAN(dev) && IS_HQOS_UL_MODE) ||
+					    (IS_LAN(dev) && IS_HQOS_DL_MODE))
+						entry.ipv4_hnapt.tport_id = 1;
+					else
+						entry.ipv4_hnapt.tport_id = 0;
 #else
 					entry.ipv4_hnapt.iblk2.fqos = 1;
 #endif
@@ -1605,7 +1609,11 @@
 				entry.ipv4_hnapt.iblk2.fqos = 0;
 			else
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-				entry.ipv4_hnapt.tport_id = 1;
+				if ((IS_WAN(dev) && IS_HQOS_UL_MODE) ||
+					(IS_LAN(dev) && IS_HQOS_DL_MODE))
+					entry.ipv4_hnapt.tport_id = 1;
+				else
+					entry.ipv4_hnapt.tport_id = 0;
 #else
 				entry.ipv4_hnapt.iblk2.fqos =
 					(!IS_PPPQ_MODE || (IS_PPPQ_MODE &&
@@ -1645,7 +1653,11 @@
 				entry.ipv6_5t_route.iblk2.fqos = 0;
 			else
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-				entry.ipv6_5t_route.tport_id = 1;
+				if ((IS_WAN(dev) && IS_HQOS_UL_MODE) ||
+					(IS_LAN(dev) && IS_HQOS_DL_MODE))
+					entry.ipv6_5t_route.tport_id = 1;
+				else
+					entry.ipv6_5t_route.tport_id = 0;
 #else
 				entry.ipv6_5t_route.iblk2.fqos =
 					(!IS_PPPQ_MODE || (IS_PPPQ_MODE &&
@@ -1773,7 +1785,7 @@
 			entry->ipv4_hnapt.winfo.bssid = skb_hnat_bss_id(skb);
 			entry->ipv4_hnapt.winfo.wcid = skb_hnat_wc_id(skb);
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-			entry->ipv4_hnapt.tport_id = (IS_HQOS_MODE) ? 1 : 0;
+			entry->ipv4_hnapt.tport_id = IS_HQOS_DL_MODE ? 1 : 0;
 			entry->ipv4_hnapt.iblk2.rxid = skb_hnat_rx_id(skb);
 			entry->ipv4_hnapt.iblk2.winfoi = 1;
 			entry->ipv4_hnapt.winfo_pao.usr_info =
@@ -1831,7 +1843,7 @@
 		entry->ipv6_hnapt.winfo_pao.is_sp = skb_hnat_is_sp(skb);
 		entry->ipv6_hnapt.winfo_pao.hf = skb_hnat_hf(skb);
 		entry->ipv6_hnapt.winfo_pao.amsdu = skb_hnat_amsdu(skb);
-		entry->ipv6_hnapt.tport_id = (IS_HQOS_MODE) ? 1 : 0;
+		entry->ipv6_hnapt.tport_id = IS_HQOS_DL_MODE ? 1 : 0;
 #endif
 	} else {
 		entry->ipv6_5t_route.iblk2.fqos = 0;
@@ -1843,7 +1855,7 @@
 			entry->ipv6_5t_route.winfo.bssid = skb_hnat_bss_id(skb);
 			entry->ipv6_5t_route.winfo.wcid = skb_hnat_wc_id(skb);
 #if defined(CONFIG_MEDIATEK_NETSYS_V3)
-			entry->ipv6_5t_route.tport_id = (IS_HQOS_MODE) ? 1 : 0;
+			entry->ipv6_5t_route.tport_id = IS_HQOS_DL_MODE ? 1 : 0;
 			entry->ipv6_5t_route.iblk2.rxid = skb_hnat_rx_id(skb);
 			entry->ipv6_5t_route.iblk2.winfoi = 1;
 			entry->ipv6_5t_route.winfo_pao.usr_info =