[][openwrt][mt7988][eth][Add Ethernet RSS full support for Jaguar]

[Description]
Add Ethernet RSS full support for Jaguar.
In the past, RSS events are assigned to FE interrupts (GIC_ID: 196~199);
currently, RSS events would be assigned to ADMA-dedicated
interrupts (GIC_ID: 189~192) instead. In this way, RSS won't be limited
by the number of FE interrupts anymore, and thus can be extended
to 4-RSS Rx rings.

If without this patch, Ethernet can only enable 2-RSS Rx rings
due to the limitation of FE interrupt number.

[Usage]
Assume IRQ numbers of Ethernet Rx interrupts are 124~127 (shown in
cat /proc/interrupts).
Then we can adjust smp affinity to decide which CPU is going to
process those Rx interrupts.
The below example shows how we utilize 3-CPU to process Rx interrupts.
   - echo 1 > /proc/irq/124/smp_affinity  (CPU0 processes IRQ 124)
   - echo 2 > /proc/irq/125/smp_affinity  (CPU1 processes IRQ 125)
   - echo 4 > /proc/irq/126/smp_affinity  (CPU2 processes IRQ 126)
   - echo 4 > /proc/irq/127/smp_affinity  (CPU2 processes IRQ 127)

[Release-log]
N/A


Change-Id: I3df05df5863e9cb5288bb6db5113d3bc75ce46ad
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7514813
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi
index e99ef83..6b47ee6 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981.dtsi
@@ -390,10 +390,14 @@
         eth: ethernet@15100000 {
                 compatible = "mediatek,mt7981-eth";
                 reg = <0 0x15100000 0 0x80000>;
-                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
                 clocks = <&ethsys CK_ETH_FE_EN>,
                          <&ethsys CK_ETH_GP2_EN>,
                          <&ethsys CK_ETH_GP1_EN>,
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index f1ccf54..820e8bb 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -475,10 +475,14 @@
         eth: ethernet@15100000 {
                 compatible = "mediatek,mt7986-eth";
                 reg = <0 0x15100000 0 0x80000>;
-                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
                 clocks = <&ethsys CK_ETH_FE_EN>,
                          <&ethsys CK_ETH_GP2_EN>,
                          <&ethsys CK_ETH_GP1_EN>,
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
index 666fddb..96c68a5 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
@@ -377,10 +377,14 @@
         eth: ethernet@15100000 {
                 compatible = "mediatek,mt7986-eth";
                 reg = <0 0x15100000 0 0x80000>;
-                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
                 clocks = <&ethsys CK_ETH_FE_EN>,
                          <&ethsys CK_ETH_GP2_EN>,
                          <&ethsys CK_ETH_GP1_EN>,
diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
index 28cb8eb..98dc4df 100644
--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
@@ -774,7 +774,11 @@
 		compatible = "mediatek,mt7988-eth";
 		reg = <0 0x15100000 0 0x80000>,
 		      <0 0x15400000 0 0x380000>;
-		interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+		interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
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 6f17fa5..02f1d34 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
@@ -3067,10 +3067,12 @@
 	mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
 
 	/* Set perRSS GRP INT */
-	mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING1), MTK_PDMA_INT_GRP3);
+	mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(1)), MTK_PDMA_INT_GRP1);
+	mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(2)), MTK_PDMA_INT_GRP2);
+	mtk_w32(eth, MTK_RX_DONE_INT(MTK_RSS_RING(3)), MTK_PDMA_INT_GRP3);
 
 	/* Set GRP INT */
-	mtk_w32(eth, 0x21021030, MTK_FE_INT_GRP);
+	mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP);
 
 	/* Enable RSS delay interrupt */
 	mtk_w32(eth, 0x8f0f8f0f, MTK_PDMA_RSS_DELAY_INT);
@@ -3363,7 +3365,7 @@
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 	mtk_rx_irq_disable(eth, MTK_RX_DONE_INT(0));
-	mtk_handle_irq_rx(eth->irq[2], &eth->rx_napi[0]);
+	mtk_handle_irq_rx(eth->irq_fe[2], &eth->rx_napi[0]);
 	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 	mtk_rx_irq_enable(eth, MTK_RX_DONE_INT(0));
 }
@@ -3784,11 +3786,9 @@
 	mtk_rx_irq_disable(eth, ~0);
 
 	/* FE int grouping */
-	mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
-	mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->pdma.int_grp2);
 	mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
 	mtk_w32(eth, MTK_RX_DONE_INT(0), reg_map->qdma.int_grp2);
-	mtk_w32(eth, 0x21021003, MTK_FE_INT_GRP);
+	mtk_w32(eth, 0x210FFFF2, MTK_FE_INT_GRP);
 	mtk_w32(eth, MTK_FE_INT_TSO_FAIL |
 		MTK_FE_INT_TSO_ILLEGAL | MTK_FE_INT_TSO_ALIGN |
 		MTK_FE_INT_RFIFO_OV | MTK_FE_INT_RFIFO_UF, MTK_FE_INT_ENABLE);
@@ -4553,7 +4553,7 @@
 	eth->netdev[id]->features |= eth->soc->hw_features;
 	eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
 
-	eth->netdev[id]->irq = eth->irq[0];
+	eth->netdev[id]->irq = eth->irq_fe[0];
 	eth->netdev[id]->dev.of_node = np;
 
 	return 0;
@@ -4710,12 +4710,17 @@
 		}
 	}
 
-	for (i = 0; i < MTK_MAX_IRQ_NUM; i++) {
+	for (i = 0; i < MTK_PDMA_IRQ_NUM; i++)
+		eth->irq_pdma[i] = platform_get_irq(pdev, i);
+
+	for (i = 0; i < MTK_FE_IRQ_NUM; i++) {
 		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
-			eth->irq[i] = eth->irq[0];
+			eth->irq_fe[i] = eth->irq_fe[0];
 		else
-			eth->irq[i] = platform_get_irq(pdev, i);
-		if (eth->irq[i] < 0) {
+			eth->irq_fe[i] =
+				platform_get_irq(pdev, i + MTK_PDMA_IRQ_NUM);
+
+		if (eth->irq_fe[i] < 0) {
 			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
 			return -ENXIO;
 		}
@@ -4765,37 +4770,35 @@
 		goto err_free_dev;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
-		err = devm_request_irq(eth->dev, eth->irq[0],
+		err = devm_request_irq(eth->dev, eth->irq_fe[0],
 				       mtk_handle_irq, 0,
 				       dev_name(eth->dev), eth);
 	} else {
-		err = devm_request_irq(eth->dev, eth->irq[1],
+		err = devm_request_irq(eth->dev, eth->irq_fe[1],
 				       mtk_handle_irq_tx, 0,
 				       dev_name(eth->dev), eth);
 		if (err)
 			goto err_free_dev;
 
-		err = devm_request_irq(eth->dev, eth->irq[2],
+		err = devm_request_irq(eth->dev, eth->irq_fe[2],
+				       mtk_handle_fe_irq, 0,
+				       dev_name(eth->dev), eth);
+		if (err)
+			goto err_free_dev;
+
+		err = devm_request_irq(eth->dev, eth->irq_pdma[0],
 				       mtk_handle_irq_rx, 0,
 				       dev_name(eth->dev), &eth->rx_napi[0]);
 		if (err)
 			goto err_free_dev;
 
-		if (MTK_MAX_IRQ_NUM > 3) {
-			if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
-				for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
-					err = devm_request_irq(eth->dev,
-							       eth->irq[2 + i],
-							       mtk_handle_irq_rx, 0,
-							       dev_name(eth->dev),
-							       &eth->rx_napi[i]);
-					if (err)
-						goto err_free_dev;
-				}
-			} else {
-				err = devm_request_irq(eth->dev, eth->irq[3],
-						       mtk_handle_fe_irq, 0,
-						       dev_name(eth->dev), eth);
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
+			for (i = 1; i < MTK_RX_NAPI_NUM; i++) {
+				err = devm_request_irq(eth->dev,
+						       eth->irq_pdma[i],
+						       mtk_handle_irq_rx, 0,
+						       dev_name(eth->dev),
+						       &eth->rx_napi[i]);
 				if (err)
 					goto err_free_dev;
 			}
@@ -4823,7 +4826,7 @@
 		} else
 			netif_info(eth, probe, eth->netdev[i],
 				   "mediatek frame engine at 0x%08lx, irq %d\n",
-				   eth->netdev[i]->base_addr, eth->irq[0]);
+				   eth->netdev[i]->base_addr, eth->irq_fe[0]);
 	}
 
 	/* we run 2 devices on the same DMA ring so we need a dummy device
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 2082ec6..e95e3dc 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
@@ -86,6 +86,9 @@
 #define MTK_FE_INT_RFIFO_UF	BIT(19)
 #define MTK_GDM1_AF		BIT(28)
 #define MTK_GDM2_AF		BIT(29)
+#define MTK_FE_IRQ_NUM		(4)
+#define MTK_PDMA_IRQ_NUM	(4)
+#define MTK_MAX_IRQ_NUM		(MTK_FE_IRQ_NUM + MTK_PDMA_IRQ_NUM)
 
 /* PDMA HW LRO Alter Flow Timer Register */
 #define MTK_PDMA_LRO_ALT_REFRESH_TIMER	0x1c
@@ -254,14 +257,12 @@
 /* PDMA RSS Control Registers */
 #if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
 #define MTK_PDMA_RSS_GLO_CFG		(PDMA_BASE + 0x800)
-#define MTK_RX_NAPI_NUM			(2)
-#define MTK_MAX_IRQ_NUM			(4)
+#define MTK_RX_NAPI_NUM			(4)
 #else
 #define MTK_PDMA_RSS_GLO_CFG		0x2800
 #define MTK_RX_NAPI_NUM			(1)
-#define MTK_MAX_IRQ_NUM			(3)
 #endif
-#define MTK_RSS_RING1			(1)
+#define MTK_RSS_RING(x)			(x)
 #define MTK_RSS_EN			BIT(0)
 #define MTK_RSS_CFG_REQ			BIT(2)
 #define MTK_RSS_IPV6_STATIC_HASH	(0x7 << 8)
@@ -274,7 +275,7 @@
 #define MTK_RSS_INDR_TABLE_DW5		(MTK_PDMA_RSS_GLO_CFG + 0x64)
 #define MTK_RSS_INDR_TABLE_DW6		(MTK_PDMA_RSS_GLO_CFG + 0x68)
 #define MTK_RSS_INDR_TABLE_DW7		(MTK_PDMA_RSS_GLO_CFG + 0x6C)
-#define MTK_RSS_INDR_TABLE_SIZE4	0x44444444
+#define MTK_RSS_INDR_TABLE_SIZE4	0x39393939
 
 /* PDMA Global Configuration Register */
 #define MTK_PDMA_GLO_CFG	(PDMA_BASE + 0x204)
@@ -445,12 +446,13 @@
 /* QDMA Interrupt Status Register */
 #define MTK_QDMA_INT_STATUS	(QDMA_BASE + 0x218)
 #if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-#define MTK_RX_DONE_INT(ring_no)					\
+#define MTK_RX_DONE_INT(ring_no)						\
 	(MTK_HAS_CAPS(eth->soc->caps, MTK_RSS) ? (BIT(24 + (ring_no))) :	\
 	 ((ring_no) ? BIT(16 + (ring_no)) : BIT(14)))
 #else
-#define MTK_RX_DONE_INT(ring_no)		\
-	((ring_no)? BIT(24 + (ring_no)) : BIT(30))
+#define MTK_RX_DONE_INT(ring_no)						\
+	(MTK_HAS_CAPS(eth->soc->caps, MTK_RSS) ? (BIT(16 + (ring_no))) :	\
+	 ((ring_no) ? BIT(24 + (ring_no)) : BIT(30)))
 #endif
 #define MTK_RX_DONE_INT3	BIT(19)
 #define MTK_RX_DONE_INT2	BIT(18)
@@ -1767,7 +1769,8 @@
 	struct net_device		dummy_dev;
 	struct net_device		*netdev[MTK_MAX_DEVS];
 	struct mtk_mac			*mac[MTK_MAX_DEVS];
-	int				irq[MTK_MAX_IRQ_NUM];
+	int				irq_fe[MTK_FE_IRQ_NUM];
+	int				irq_pdma[MTK_PDMA_IRQ_NUM];
 	u8				hwver;
 	u32				msg_enable;
 	unsigned long			sysclk;