mediatek: fix NETDEV WATCHDOG: eth0 (mtk_SOC_eth): Transmit queue 0 timed out

daxiong lxliu at ikuai8.com
Sun Oct 3 04:34:51 PDT 2021


Use flow control or BQL maybe lead to bug.
Iperf3 was usedfor 24 hours, Transmit Queue 0 timed out may occur.
 example:
   Server: iperf3 -s
   Client: iperf3 -c 172.16.10.20

Signed-off-by: daxiong <lxliu at ikuai8.com>
---
 ...iatek-ethernet-transmit-queue-timeout-bug.patch | 109 +++++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 target/linux/ramips/patches-5.4/500-mediatek-ethernet-transmit-queue-timeout-bug.patch

diff --git a/target/linux/ramips/patches-5.4/500-mediatek-ethernet-transmit-queue-timeout-bug.patch b/target/linux/ramips/patches-5.4/500-mediatek-ethernet-transmit-queue-timeout-bug.patch
new file mode 100644
index 0000000..d5da9e4
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/500-mediatek-ethernet-transmit-queue-timeout-bug.patch
@@ -0,0 +1,109 @@
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c	2021-10-03 18:46:25.065801660 +0800
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c	2021-10-03 19:13:24.931017393 +0800
+@@ -26,6 +26,11 @@
+ 
+ #include "mtk_eth_soc.h"
+ 
++//Bug info: NETDEV WATCHDOG: eth0 (mtk_soc_eth): transmit queue 0 timed out
++//Bug fixed: BQL and FC maybe QUEUE to be stopped forever
++#define DISABLE_MTK_BQL //disable Byte Queue Limit
++#define DISABLE_MTK_FC  //disable Flow Control
++
+ static int mtk_msg_level = -1;
+ module_param_named(msg_level, mtk_msg_level, int, 0);
+ MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
+@@ -380,6 +385,10 @@ static void mtk_mac_config(struct phylin
+ 			mcr_new |= MAC_MCR_FORCE_RX_FC;
+ 	}
+ 
++	#ifdef DISABLE_MTK_FC
++	mcr_new &= ~(MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC);
++	#endif
++
+ 	/* Only update control register when needed! */
+ 	if (mcr_new != mcr_cur)
+ 		mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
+@@ -535,8 +544,10 @@ static void mtk_validate(struct phylink_
+ 		}
+ 	}
+ 
++	#ifndef DISABLE_MTK_FC
+ 	phylink_set(mask, Pause);
+ 	phylink_set(mask, Asym_Pause);
++	#endif
+ 
+ 	linkmode_and(supported, supported, mask);
+ 	linkmode_and(state->advertising, state->advertising, mask);
+@@ -1071,8 +1082,10 @@ static int mtk_tx_map(struct sk_buff *sk
+ 			txd_pdma->txd2 |= TX_DMA_LS1;
+ 	}
+ 
++	#ifndef DISABLE_MTK_BQL
+ 	netdev_sent_queue(dev, skb->len);
+ 	skb_tx_timestamp(skb);
++	#endif
+ 
+ 	ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
+ 	atomic_sub(n_desc, &ring->free_count);
+@@ -1496,7 +1509,9 @@ static int mtk_poll_tx(struct mtk_eth *e
+ 	for (i = 0; i < MTK_MAC_COUNT; i++) {
+ 		if (!eth->netdev[i] || !done[i])
+ 			continue;
++		#ifndef DISABLE_MTK_BQL
+ 		netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
++		#endif
+ 		total += done[i];
+ 		eth->tx_packets += done[i];
+ 		eth->tx_bytes += bytes[i];
+--- a/drivers/net/dsa/mt7530.c	2021-10-03 18:47:00.077800119 +0800
++++ b/drivers/net/dsa/mt7530.c	2021-10-03 19:13:37.807016826 +0800
+@@ -22,6 +22,8 @@
+ 
+ #include "mt7530.h"
+ 
++#define DISABLE_MTK_FC  //disable Flow Control
++
+ /* String, offset, and register size in bytes if different from 4 bytes */
+ static const struct mt7530_mib_desc mt7530_mib[] = {
+ 	MIB_DESC(1, 0x00, "TxDrop"),
+@@ -1281,6 +1283,18 @@ mt7530_setup(struct dsa_switch *ds)
+ 	val |= MHWTRAP_MANUAL;
+ 	mt7530_write(priv, MT7530_MHWTRAP, val);
+ 
++#ifdef DISABLE_MTK_FC
++	usleep_range(10, 20);
++
++	val = mt7530_read(priv, 0x1FE0);
++	val &= ~BIT(31);
++	mt7530_write(priv, 0x1FE0, val);
++
++	mt7530_write(priv, MT7530_PMCR_P(5), 0x5e30b);
++	mt7530_write(priv, MT7530_PMCR_P(6), 0x5e30b);
++	usleep_range(10, 20);
++#endif
++
+ 	priv->p6_interface = PHY_INTERFACE_MODE_NA;
+ 
+ 	/* Enable and reset MIB counters */
+@@ -1427,6 +1441,10 @@ static void mt7530_phylink_mac_config(st
+ 			mcr_new |= PMCR_RX_FC_EN;
+ 	}
+ 
++	#ifdef DISABLE_MTK_FC
++	mcr_new &= ~(PMCR_TX_FC_EN | PMCR_RX_FC_EN);
++	#endif
++
+ 	if (mcr_new != mcr_cur)
+ 		mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
+ }
+@@ -1505,8 +1523,10 @@ unsupported:
+ 		}
+ 	}
+ 
++	#ifndef DISABLE_MTK_FC
+ 	phylink_set(mask, Pause);
+ 	phylink_set(mask, Asym_Pause);
++	#endif
+ 
+ 	linkmode_and(supported, supported, mask);
+ 	linkmode_and(state->advertising, state->advertising, mask);
-- 
1.9.1







More information about the openwrt-devel mailing list