[][kernel][common][eth][Add NETSYSv3 new feature support]

[Description]
Add NETSYSv3 new feature support.

If without this patch, driver can't work on the NETSYSv3 hardware.

Patchset9: Add RSS supporting, and rename mtk_mac_link_state()
           to mtk_mac_pcs_get_state().
Patchset12: Add Signed-off.
Patchset15: Improve NETSYS stability.

[Release-log]
N/A

Change-Id: I095e0d39819448c9d2c18d2bb6e6d8065fc23d33
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6574066
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 0d5ca16..c6f76bf 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
@@ -24,6 +24,7 @@
 #include <linux/ctype.h>
 #include <linux/debugfs.h>
 #include <linux/of_mdio.h>
+#include <linux/of_address.h>
 
 #include "mtk_eth_soc.h"
 #include "mtk_eth_dbg.h"
@@ -43,20 +44,55 @@
 typedef int (*mtk_lro_dbg_func) (int par);
 
 struct mtk_eth_debug {
-        struct dentry *root;
+	struct dentry *root;
+	void __iomem *base;
+	int direct_access;
 };
 
 struct mtk_eth *g_eth;
 
 struct mtk_eth_debug eth_debug;
 
+int mt798x_iomap(void)
+{
+	struct device_node *np = NULL;
+
+	np = of_find_node_by_name(NULL, "switch0");
+	if (np) {
+		eth_debug.base = of_iomap(np, 0);
+		if (!eth_debug.base) {
+			pr_err("of_iomap failed\n");
+			of_node_put(np);
+			return -ENOMEM;
+		}
+
+		of_node_put(np);
+		eth_debug.direct_access = 1;
+	}
+
+	return 0;
+}
+
+int mt798x_iounmap(void)
+{
+	eth_debug.direct_access = 0;
+	if (eth_debug.base)
+		iounmap(eth_debug.base);
+
+	return 0;
+}
+
 void mt7530_mdio_w32(struct mtk_eth *eth, u16 reg, u32 val)
 {
 	mutex_lock(&eth->mii_bus->mdio_lock);
 
-	_mtk_mdio_write(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
-	_mtk_mdio_write(eth, 0x1f, (reg >> 2) & 0xf,  val & 0xffff);
-	_mtk_mdio_write(eth, 0x1f, 0x10, val >> 16);
+	if (eth_debug.direct_access)
+		__raw_writel(val, eth_debug.base + reg);
+	else {
+		_mtk_mdio_write(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
+		_mtk_mdio_write(eth, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
+		_mtk_mdio_write(eth, 0x1f, 0x10, val >> 16);
+	}
 
 	mutex_unlock(&eth->mii_bus->mdio_lock);
 }
@@ -64,9 +100,15 @@
 u32 mt7530_mdio_r32(struct mtk_eth *eth, u32 reg)
 {
 	u16 high, low;
+	u32 ret;
 
 	mutex_lock(&eth->mii_bus->mdio_lock);
 
+	if (eth_debug.direct_access) {
+		ret = __raw_readl(eth_debug.base + reg);
+		mutex_unlock(&eth->mii_bus->mdio_lock);
+		return ret;
+	}
 	_mtk_mdio_write(eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
 	low = _mtk_mdio_read(eth, 0x1f, (reg >> 2) & 0xf);
 	high = _mtk_mdio_read(eth, 0x1f, 0x10);
@@ -118,6 +160,7 @@
 }
 
 static const struct file_operations mtketh_debug_fops = {
+	.owner = THIS_MODULE,
 	.open = mtketh_debug_open,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -209,6 +252,7 @@
 }
 
 static const struct file_operations mtketh_debug_mt7530sw_fops = {
+	.owner = THIS_MODULE,
 	.open = mtketh_debug_mt7530sw_open,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -417,7 +461,7 @@
 		*read_data = mt7530_mdio_r32(eth, phy_register);
 
 	else
-		*read_data = _mtk_mdio_read(eth, phy_addr, phy_register);
+		*read_data = mdiobus_read(eth->mii_bus, phy_addr, phy_register);
 }
 
 void mii_mgr_write_combine(struct mtk_eth *eth, u16 phy_addr, u16 phy_register,
@@ -427,17 +471,17 @@
 		mt7530_mdio_w32(eth, phy_register, write_data);
 
 	else
-		_mtk_mdio_write(eth, phy_addr, phy_register, write_data);
+		mdiobus_write(eth->mii_bus, phy_addr, phy_register, write_data);
 }
 
 static void mii_mgr_read_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 *data)
 {
-	*data = _mtk_mdio_read(eth, port, mdiobus_c45_addr(devad, reg));
+	*data = mdiobus_read(eth->mii_bus, port, mdiobus_c45_addr(devad, reg));
 }
 
 static void mii_mgr_write_cl45(struct mtk_eth *eth, u16 port, u16 devad, u16 reg, u16 data)
 {
-	_mtk_mdio_write(eth, port, mdiobus_c45_addr(devad, reg), data);
+	mdiobus_write(eth->mii_bus, port, mdiobus_c45_addr(devad, reg), data);
 }
 
 int mtk_do_priv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -519,75 +563,112 @@
 	return -EFAULT;
 }
 
+static void gdm_reg_dump_v3(struct mtk_eth *eth, u32 gdm_id, u32 mib_base)
+{
+	pr_info("| GDMA%d_RX_GBCNT  : %010u (Rx Good Bytes)	|\n",
+		gdm_id, mtk_r32(eth, mib_base));
+	pr_info("| GDMA%d_RX_GPCNT  : %010u (Rx Good Pkts)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x08));
+	pr_info("| GDMA%d_RX_OERCNT : %010u (overflow error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x10));
+	pr_info("| GDMA%d_RX_FERCNT : %010u (FCS error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x14));
+	pr_info("| GDMA%d_RX_SERCNT : %010u (too short)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x18));
+	pr_info("| GDMA%d_RX_LERCNT : %010u (too long)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x1C));
+	pr_info("| GDMA%d_RX_CERCNT : %010u (checksum error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x20));
+	pr_info("| GDMA%d_RX_FCCNT  : %010u (flow control)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x24));
+	pr_info("| GDMA%d_RX_VDPCNT : %010u (VID drop)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x28));
+	pr_info("| GDMA%d_RX_PFCCNT : %010u (priority flow control)\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x2C));
+	pr_info("| GDMA%d_TX_GBCNT  : %010u (Tx Good Bytes)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x40));
+	pr_info("| GDMA%d_TX_GPCNT  : %010u (Tx Good Pkts)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x48));
+	pr_info("| GDMA%d_TX_SKIPCNT: %010u (abort count)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x50));
+	pr_info("| GDMA%d_TX_COLCNT : %010u (collision count)|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x54));
+	pr_info("| GDMA%d_TX_OERCNT : %010u (overflow error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x58));
+	pr_info("| GDMA%d_TX_FCCNT  : %010u (flow control)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x60));
+	pr_info("| GDMA%d_TX_PFCCNT : %010u (priority flow control)\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x64));
+	pr_info("|						|\n");
+}
+
+static void gdm_reg_dump_v2(struct mtk_eth *eth, u32 gdm_id, u32 mib_base)
+{
+	pr_info("| GDMA%d_RX_GBCNT  : %010u (Rx Good Bytes)	|\n",
+		gdm_id, mtk_r32(eth, mib_base));
+	pr_info("| GDMA%d_RX_GPCNT  : %010u (Rx Good Pkts)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x08));
+	pr_info("| GDMA%d_RX_OERCNT : %010u (overflow error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x10));
+	pr_info("| GDMA%d_RX_FERCNT : %010u (FCS error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x14));
+	pr_info("| GDMA%d_RX_SERCNT : %010u (too short)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x18));
+	pr_info("| GDMA%d_RX_LERCNT : %010u (too long)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x1C));
+	pr_info("| GDMA%d_RX_CERCNT : %010u (checksum error)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x20));
+	pr_info("| GDMA%d_RX_FCCNT  : %010u (flow control)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x24));
+	pr_info("| GDMA%d_TX_SKIPCNT: %010u (abort count)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x28));
+	pr_info("| GDMA%d_TX_COLCNT : %010u (collision count)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x2C));
+	pr_info("| GDMA%d_TX_GBCNT  : %010u (Tx Good Bytes)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x30));
+	pr_info("| GDMA%d_TX_GPCNT  : %010u (Tx Good Pkts)	|\n",
+		gdm_id, mtk_r32(eth, mib_base + 0x38));
+	pr_info("|						|\n");
+}
+
+static void gdm_cnt_read(struct mtk_eth *eth)
+{
+	u32 i, mib_base;
+
+	pr_info("\n			<<CPU>>\n");
+	pr_info("			   |\n");
+	pr_info("+-----------------------------------------------+\n");
+	pr_info("|		  <<PSE>>		        |\n");
+	pr_info("+-----------------------------------------------+\n");
+	pr_info("			   |\n");
+	pr_info("+-----------------------------------------------+\n");
+	pr_info("|		  <<GDMA>>		        |\n");
+
+	for (i = 0; i < MTK_MAC_COUNT; i++) {
+		mib_base = MTK_GDM1_TX_GBCNT + MTK_STAT_OFFSET * i;
+
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+			gdm_reg_dump_v3(eth, i + 1, mib_base);
+		else
+			gdm_reg_dump_v2(eth, i + 1, mib_base);
+	}
+
+	pr_info("+-----------------------------------------------+\n");
+}
+
 int esw_cnt_read(struct seq_file *seq, void *v)
 {
 	unsigned int pkt_cnt = 0;
 	int i = 0;
 	struct mtk_eth *eth = g_eth;
-	unsigned int mib_base = MTK_GDM1_TX_GBCNT;
 
-	seq_puts(seq, "\n		  <<CPU>>\n");
-	seq_puts(seq, "		    |\n");
-	seq_puts(seq, "+-----------------------------------------------+\n");
-	seq_puts(seq, "|		  <<PSE>>		        |\n");
-	seq_puts(seq, "+-----------------------------------------------+\n");
-	seq_puts(seq, "		   |\n");
-	seq_puts(seq, "+-----------------------------------------------+\n");
-	seq_puts(seq, "|		  <<GDMA>>		        |\n");
-	seq_printf(seq, "| GDMA1_RX_GBCNT  : %010u (Rx Good Bytes)	|\n",
-		   mtk_r32(eth, mib_base));
-	seq_printf(seq, "| GDMA1_RX_GPCNT  : %010u (Rx Good Pkts)	|\n",
-		   mtk_r32(eth, mib_base+0x08));
-	seq_printf(seq, "| GDMA1_RX_OERCNT : %010u (overflow error)	|\n",
-		   mtk_r32(eth, mib_base+0x10));
-	seq_printf(seq, "| GDMA1_RX_FERCNT : %010u (FCS error)	|\n",
-		   mtk_r32(eth, mib_base+0x14));
-	seq_printf(seq, "| GDMA1_RX_SERCNT : %010u (too short)	|\n",
-		   mtk_r32(eth, mib_base+0x18));
-	seq_printf(seq, "| GDMA1_RX_LERCNT : %010u (too long)	|\n",
-		   mtk_r32(eth, mib_base+0x1C));
-	seq_printf(seq, "| GDMA1_RX_CERCNT : %010u (checksum error)	|\n",
-		   mtk_r32(eth, mib_base+0x20));
-	seq_printf(seq, "| GDMA1_RX_FCCNT  : %010u (flow control)	|\n",
-		   mtk_r32(eth, mib_base+0x24));
-	seq_printf(seq, "| GDMA1_TX_SKIPCNT: %010u (about count)	|\n",
-		   mtk_r32(eth, mib_base+0x28));
-	seq_printf(seq, "| GDMA1_TX_COLCNT : %010u (collision count)	|\n",
-		   mtk_r32(eth, mib_base+0x2C));
-	seq_printf(seq, "| GDMA1_TX_GBCNT  : %010u (Tx Good Bytes)	|\n",
-		   mtk_r32(eth, mib_base+0x30));
-	seq_printf(seq, "| GDMA1_TX_GPCNT  : %010u (Tx Good Pkts)	|\n",
-		   mtk_r32(eth, mib_base+0x38));
-	seq_puts(seq, "|						|\n");
-	seq_printf(seq, "| GDMA2_RX_GBCNT  : %010u (Rx Good Bytes)	|\n",
-		   mtk_r32(eth, mib_base+0x40));
-	seq_printf(seq, "| GDMA2_RX_GPCNT  : %010u (Rx Good Pkts)	|\n",
-		   mtk_r32(eth, mib_base+0x48));
-	seq_printf(seq, "| GDMA2_RX_OERCNT : %010u (overflow error)	|\n",
-		   mtk_r32(eth, mib_base+0x50));
-	seq_printf(seq, "| GDMA2_RX_FERCNT : %010u (FCS error)	|\n",
-		   mtk_r32(eth, mib_base+0x54));
-	seq_printf(seq, "| GDMA2_RX_SERCNT : %010u (too short)	|\n",
-		   mtk_r32(eth, mib_base+0x58));
-	seq_printf(seq, "| GDMA2_RX_LERCNT : %010u (too long)	|\n",
-		   mtk_r32(eth, mib_base+0x5C));
-	seq_printf(seq, "| GDMA2_RX_CERCNT : %010u (checksum error)	|\n",
-		   mtk_r32(eth, mib_base+0x60));
-	seq_printf(seq, "| GDMA2_RX_FCCNT  : %010u (flow control)	|\n",
-		   mtk_r32(eth, mib_base+0x64));
-	seq_printf(seq, "| GDMA2_TX_SKIPCNT: %010u (skip)		|\n",
-		   mtk_r32(eth, mib_base+0x68));
-	seq_printf(seq, "| GDMA2_TX_COLCNT : %010u (collision)	|\n",
-		   mtk_r32(eth, mib_base+0x6C));
-	seq_printf(seq, "| GDMA2_TX_GBCNT  : %010u (Tx Good Bytes)	|\n",
-		   mtk_r32(eth, mib_base+0x70));
-	seq_printf(seq, "| GDMA2_TX_GPCNT  : %010u (Tx Good Pkts)	|\n",
-		   mtk_r32(eth, mib_base+0x78));
-	seq_puts(seq, "+-----------------------------------------------+\n");
+	gdm_cnt_read(eth);
 
 	if (!mt7530_exist(eth))
 		return 0;
 
+	mt798x_iomap();
+
 #define DUMP_EACH_PORT(base)					\
 	do { \
 		for (i = 0; i < 7; i++) {				\
@@ -643,6 +724,8 @@
 
 	seq_puts(seq, "\n");
 
+	mt798x_iounmap();
+
 	return 0;
 }
 
@@ -680,7 +763,8 @@
 			   tx_ring->txd1, tx_ring->txd2,
 			   tx_ring->txd3, tx_ring->txd4);
 
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+		    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 			seq_printf(seq, " %08x %08x %08x %08x",
 				   tx_ring->txd5, tx_ring->txd6,
 				   tx_ring->txd7, tx_ring->txd8);
@@ -720,7 +804,8 @@
 			   hwtx_ring->txd1, hwtx_ring->txd2,
 			   hwtx_ring->txd3, hwtx_ring->txd4);
 
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+		    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 			seq_printf(seq, " %08x %08x %08x %08x",
 				   hwtx_ring->txd5, hwtx_ring->txd6,
 				   hwtx_ring->txd7, hwtx_ring->txd8);
@@ -761,7 +846,8 @@
 			   rx_ring->rxd1, rx_ring->rxd2,
 			   rx_ring->rxd3, rx_ring->rxd4);
 
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+		    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 			seq_printf(seq, " %08x %08x %08x %08x",
 				   rx_ring->rxd5, rx_ring->rxd6,
 				   rx_ring->rxd7, rx_ring->rxd8);
@@ -806,7 +892,8 @@
 
 	seq_printf(seq, "| FE_INT_STA	: %08x |\n",
 		   mtk_r32(eth, MTK_FE_INT_STATUS));
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
 		seq_printf(seq, "| FE_INT_STA2	: %08x |\n",
 			   mtk_r32(eth, MTK_FE_INT_STATUS2));
 
@@ -817,13 +904,20 @@
 	seq_printf(seq, "| PSE_IQ_STA2	: %08x |\n",
 		   mtk_r32(eth, MTK_PSE_IQ_STA(1)));
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		seq_printf(seq, "| PSE_IQ_STA3	: %08x |\n",
 			   mtk_r32(eth, MTK_PSE_IQ_STA(2)));
 		seq_printf(seq, "| PSE_IQ_STA4	: %08x |\n",
 			   mtk_r32(eth, MTK_PSE_IQ_STA(3)));
 		seq_printf(seq, "| PSE_IQ_STA5	: %08x |\n",
 			   mtk_r32(eth, MTK_PSE_IQ_STA(4)));
+		seq_printf(seq, "| PSE_IQ_STA6	: %08x |\n",
+			   mtk_r32(eth, MTK_PSE_IQ_STA(5)));
+		seq_printf(seq, "| PSE_IQ_STA7	: %08x |\n",
+			   mtk_r32(eth, MTK_PSE_IQ_STA(6)));
+		seq_printf(seq, "| PSE_IQ_STA8	: %08x |\n",
+			   mtk_r32(eth, MTK_PSE_IQ_STA(7)));
 	}
 
 	seq_printf(seq, "| PSE_OQ_STA1	: %08x |\n",
@@ -831,13 +925,20 @@
 	seq_printf(seq, "| PSE_OQ_STA2	: %08x |\n",
 		   mtk_r32(eth, MTK_PSE_OQ_STA(1)));
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		seq_printf(seq, "| PSE_OQ_STA3	: %08x |\n",
 			   mtk_r32(eth, MTK_PSE_OQ_STA(2)));
 		seq_printf(seq, "| PSE_OQ_STA4	: %08x |\n",
 			   mtk_r32(eth, MTK_PSE_OQ_STA(3)));
 		seq_printf(seq, "| PSE_OQ_STA5	: %08x |\n",
 			   mtk_r32(eth, MTK_PSE_OQ_STA(4)));
+		seq_printf(seq, "| PSE_OQ_STA6	: %08x |\n",
+			   mtk_r32(eth, MTK_PSE_OQ_STA(5)));
+		seq_printf(seq, "| PSE_OQ_STA7	: %08x |\n",
+			   mtk_r32(eth, MTK_PSE_OQ_STA(6)));
+		seq_printf(seq, "| PSE_OQ_STA8	: %08x |\n",
+			   mtk_r32(eth, MTK_PSE_OQ_STA(7)));
 	}
 
 	seq_printf(seq, "| PDMA_CRX_IDX	: %08x |\n",
@@ -850,6 +951,10 @@
 		   mtk_r32(eth, MTK_QTX_DTX_PTR));
 	seq_printf(seq, "| QDMA_FQ_CNT	: %08x |\n",
 		   mtk_r32(eth, MTK_QDMA_FQ_CNT));
+	seq_printf(seq, "| QDMA_FWD_CNT	: %08x |\n",
+		   mtk_r32(eth, MTK_QDMA_FWD_CNT));
+	seq_printf(seq, "| QDMA_FSM	: %08x |\n",
+		   mtk_r32(eth, MTK_QDMA_FSM));
 	seq_printf(seq, "| FE_PSE_FREE	: %08x |\n",
 		   mtk_r32(eth, MTK_FE_PSE_FREE));
 	seq_printf(seq, "| FE_DROP_FQ	: %08x |\n",
@@ -862,16 +967,29 @@
 		   mtk_r32(eth, MTK_GDMA_FWD_CFG(0)));
 	seq_printf(seq, "| GDM2_IG_CTRL	: %08x |\n",
 		   mtk_r32(eth, MTK_GDMA_FWD_CFG(1)));
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+		seq_printf(seq, "| GDM3_IG_CTRL	: %08x |\n",
+			   mtk_r32(eth, MTK_GDMA_FWD_CFG(2)));
+	}
 	seq_printf(seq, "| MAC_P1_MCR	: %08x |\n",
 		   mtk_r32(eth, MTK_MAC_MCR(0)));
 	seq_printf(seq, "| MAC_P2_MCR	: %08x |\n",
 		   mtk_r32(eth, MTK_MAC_MCR(1)));
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+		seq_printf(seq, "| MAC_P3_MCR	: %08x |\n",
+			   mtk_r32(eth, MTK_MAC_MCR(2)));
+	}
 	seq_printf(seq, "| MAC_P1_FSM	: %08x |\n",
 		   mtk_r32(eth, MTK_MAC_FSM(0)));
 	seq_printf(seq, "| MAC_P2_FSM	: %08x |\n",
 		   mtk_r32(eth, MTK_MAC_FSM(1)));
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+		seq_printf(seq, "| MAC_P3_FSM	: %08x |\n",
+			   mtk_r32(eth, MTK_MAC_FSM(2)));
+	}
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		seq_printf(seq, "| FE_CDM1_FSM	: %08x |\n",
 			   mtk_r32(eth, MTK_FE_CDM1_FSM));
 		seq_printf(seq, "| FE_CDM2_FSM	: %08x |\n",
@@ -880,6 +998,10 @@
 			   mtk_r32(eth, MTK_FE_CDM3_FSM));
 		seq_printf(seq, "| FE_CDM4_FSM	: %08x |\n",
 			   mtk_r32(eth, MTK_FE_CDM4_FSM));
+		seq_printf(seq, "| FE_CDM5_FSM	: %08x |\n",
+			   mtk_r32(eth, MTK_FE_CDM5_FSM));
+		seq_printf(seq, "| FE_CDM6_FSM	: %08x |\n",
+			   mtk_r32(eth, MTK_FE_CDM6_FSM));
 		seq_printf(seq, "| FE_GDM1_FSM	: %08x |\n",
 			   mtk_r32(eth, MTK_FE_GDM1_FSM));
 		seq_printf(seq, "| FE_GDM2_FSM	: %08x |\n",
@@ -895,7 +1017,8 @@
 	}
 
 	mtk_w32(eth, 0xffffffff, MTK_FE_INT_STATUS);
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
 		mtk_w32(eth, 0xffffffff, MTK_FE_INT_STATUS2);
 
 	return 0;
@@ -919,7 +1042,8 @@
 	struct mtk_eth *eth = g_eth;
 	u32 idx, agg_cnt, agg_size;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		idx = ring_no - 4;
 		agg_cnt = RX_DMA_GET_AGG_CNT_V2(rxd->rxd6);
 	} else {
@@ -940,7 +1064,8 @@
 	struct mtk_eth *eth = g_eth;
 	u32 idx, flush_reason;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
 		idx = ring_no - 4;
 		flush_reason = RX_DMA_GET_FLUSH_RSN_V2(rxd->rxd6);
 	} else {
@@ -1187,7 +1312,8 @@
 {
 	struct mtk_eth *eth = g_eth;
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
 		hw_lro_stats_read_v2(seq, v);
 	else
 		hw_lro_stats_read_v1(seq, v);
@@ -1458,7 +1584,8 @@
 	seq_puts(seq, "[4] = hwlro_ring_enable_ctrl\n");
 	seq_puts(seq, "[5] = hwlro_stats_enable_ctrl\n\n");
 
-	if (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_V2)) {
+	if (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_V2) ||
+	    MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_V3)) {
 		for (i = 1; i <= 8; i++)
 			hw_lro_auto_tlb_dump_v2(seq, i);
 	} else {
@@ -1494,7 +1621,7 @@
 		    ((reg_op1 >> MTK_LRO_RING_AGE_TIME_L_OFFSET) & 0x3ff);
 		seq_printf(seq,
 			   "Ring[%d]: MAX_AGG_CNT=%d, AGG_TIME=%d, AGE_TIME=%d, Threshold=%d\n",
-			   (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_V2))? i+3 : i,
+			   (MTK_HAS_CAPS(g_eth->soc->caps, MTK_NETSYS_V1)) ? i : i+3,
 			   agg_cnt, agg_time, age_time, reg_op4);
 	}