[][[kernel][mt7988][eth][add reset function from fe to fe&&wdma reset]]

[Description]
Add reset function from FE reset to FE&WDMA reset
-FE reset need wifi stop traffic
-WIFI stop traffic may fail because of FE's reason
-we should switch to FE&WDMA reset when WIFI stop traffic fail
-default setting :mask print too much debug information
-follow DE advice jaguar disable idle check for xgdm/xmac

[Release-log]
N/A


Change-Id: I6b80eaa1114db23dbe751c046f8930c2d3548ff0
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7409800
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index c23f868..9987630 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -40,6 +40,8 @@
 u32 hw_lro_timestamp_flush_cnt[MTK_HW_LRO_RING_NUM];
 u32 hw_lro_norule_flush_cnt[MTK_HW_LRO_RING_NUM];
 u32 mtk_hwlro_stats_ebl;
+u32 dbg_show_level;
+
 static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb;
 typedef int (*mtk_lro_dbg_func) (int par);
 
@@ -396,6 +398,12 @@
 			} else
 				pr_info(" device resetting !!!\n");
 			break;
+		case 4:
+			dbg_show_level = 1;
+			break;
+		case 5:
+			dbg_show_level = 0;
+			break;
 		default:
 			pr_info("Usage: echo [level] > /sys/kernel/debug/mtketh/reset\n");
 			pr_info("Commands:	 [level]\n");
@@ -403,6 +411,8 @@
 			pr_info("			   1	 FE and WDMA reset\n");
 			pr_info("			   2	 enable reset\n");
 			pr_info("			   3	 FE reset\n");
+			pr_info("			   4	enable dump reset info\n");
+			pr_info("			   5	disable dump reset info\n");
 			break;
 	}
 	return count;
@@ -1846,7 +1856,7 @@
 	    proc_create(PROCREG_RESET_EVENT, 0, proc_reg_dir, &reset_event_fops);
 	if (!proc_reset_event)
 		pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_RESET_EVENT);
-
+	dbg_show_level = 1;
 	return 0;
 }
 
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
index eebec74..5ab74ad 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
@@ -25,6 +25,8 @@
 static int mtk_wifi_num = 0;
 static int mtk_rest_cnt = 0;
 u32 mtk_reset_flag = MTK_FE_START_RESET;
+bool mtk_stop_fail;
+
 typedef u32 (*mtk_monitor_xdma_func) (struct mtk_eth *eth);
 
 void mtk_reset_event_update(struct mtk_eth *eth, u32 id)
@@ -51,10 +53,12 @@
 #endif
 	ethsys_reset(eth, reset_bits);
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
-	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
 		regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0x3ffffff);
 
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+		regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0x6F8FF);
+
 	return 0;
 }
 
@@ -144,7 +148,8 @@
 
 	if (ret) {
 		mtk_reset_event_update(eth, MTK_EVENT_TOTAL_CNT);
-		mtk_dump_netsys_info(eth);
+		if (dbg_show_level)
+			mtk_dump_netsys_info(eth);
 	}
 
 	return ret;
@@ -619,6 +624,7 @@
 	switch (event) {
 	case MTK_WIFI_RESET_DONE:
 	case MTK_FE_STOP_TRAFFIC_DONE:
+		pr_info("%s rcv done event:%x\n", __func__, event);
 		mtk_rest_cnt--;
 		if(!mtk_rest_cnt) {
 			complete(&wait_ser_done);
@@ -633,6 +639,13 @@
 		mtk_wifi_num--;
 		mtk_rest_cnt = mtk_wifi_num;
 		break;
+	case MTK_FE_STOP_TRAFFIC_DONE_FAIL:
+		mtk_stop_fail = true;
+		mtk_reset_flag = MTK_FE_START_RESET;
+		pr_info("%s rcv done event:%x\n", __func__, event);
+		complete(&wait_ser_done);
+		mtk_rest_cnt = mtk_wifi_num;
+		break;
 	default:
 		break;
 	}
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.h
index 096331b..4ac77c8 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.h
@@ -18,6 +18,8 @@
 #define MTK_FE_STOP_TRAFFIC	(0x2005)
 #define MTK_FE_STOP_TRAFFIC_DONE	(0x2006)
 #define MTK_FE_START_TRAFFIC	(0x2007)
+#define MTK_FE_STOP_TRAFFIC_DONE_FAIL	(0x2008)
+
 
 /* ADMA Rx Debug Monitor */
 #define MTK_ADMA_RX_DBG0	(PDMA_BASE + 0x238)
@@ -67,6 +69,7 @@
 extern atomic_t reset_lock;
 extern struct completion wait_nat_done;
 extern u32 mtk_reset_flag;
+extern bool mtk_stop_fail;
 
 irqreturn_t mtk_handle_fe_irq(int irq, void *_eth);
 u32 mtk_check_reset_event(struct mtk_eth *eth, u32 status);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index b4890fe..05a5595 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3959,8 +3959,20 @@
 				eth->netdev[i]);
 		}
 		rtnl_unlock();
-		if (!wait_for_completion_timeout(&wait_ser_done, 3000))
+		if (!wait_for_completion_timeout(&wait_ser_done, 3000)) {
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
+				(mtk_stop_fail)) {
+				pr_info("send MTK_FE_START_RESET stop\n");
+				rtnl_lock();
+				call_netdevice_notifiers(MTK_FE_START_RESET,
+					eth->netdev[i]);
+				rtnl_unlock();
+				if (!wait_for_completion_timeout(&wait_ser_done,
+					3000))
+					pr_warn("wait for MTK_FE_START_RESET\n");
+				}
 			pr_warn("wait for MTK_FE_START_RESET\n");
+		}
 		rtnl_lock();
 		break;
 	}
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index f279ad5..03c18f0 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1822,6 +1822,7 @@
 extern struct mtk_eth *g_eth;
 extern const struct of_device_id of_mtk_match[];
 extern u32 mtk_hwlro_stats_ebl;
+extern u32 dbg_show_level;
 
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);