From: Daniel Golle Date: Tue, 27 Sep 2022 20:08:04 +0000 (+0100) Subject: kernel: mtk_ppe: use MTK_FOE_STATE_INVALID instead of *_UNBIND X-Git-Tag: v23.05.0-rc1~2294 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=9e08724634005b28ae94355ca43b87fbc265e039;p=openwrt%2Fstaging%2Fhauke.git kernel: mtk_ppe: use MTK_FOE_STATE_INVALID instead of *_UNBIND Instead of dropping *fix-typo-in-__mtk_foe_entry.patch which effectively means keeping the (also wrong) assignment of MTK_FOE_STATE_BIND, rather use MTK_FOE_STATE_INVALID as that works well on both older (NETSYS_V1) and newer (NETSYS_V2) MediaTek SoCs. Suggested-by: Felix Fietkau Signed-off-by: Daniel Golle --- diff --git a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch b/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch deleted file mode 100644 index 7ab6d486b2..0000000000 --- a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4253e6e2b795a18ab534adcd5c313d3fc4150975 Mon Sep 17 00:00:00 2001 -Message-Id: <4253e6e2b795a18ab534adcd5c313d3fc4150975.1662332102.git.lorenzo@kernel.org> -In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> -References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Mon, 5 Sep 2022 00:48:52 +0200 -Subject: [PATCH net-next 3/6] net: ethernet: mtk_eth_soc: check max allowed - value in mtk_ppe_check_skb - -Check theoretical OOB accesses in mtk_ppe_check_skb routine - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -294,6 +294,9 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s - if (!ppe) - return; - -+ if (hash > MTK_PPE_HASH_MASK) -+ return; -+ - now = (u16)jiffies; - diff = now - ppe->foe_check_time[hash]; - if (diff < HZ / 10) diff --git a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch b/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch new file mode 100644 index 0000000000..77daf6c8bf --- /dev/null +++ b/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch @@ -0,0 +1,27 @@ +From 12ff69304c83c679ca01ef3db963ab0db9de19fb Mon Sep 17 00:00:00 2001 +Message-Id: <12ff69304c83c679ca01ef3db963ab0db9de19fb.1662332102.git.lorenzo@kernel.org> +In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 00:43:43 +0200 +Subject: [PATCH net-next 2/6] net: ethernet: mtk_eth_soc: fix typo in + __mtk_foe_entry_clear + +Set ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear routine. + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -413,7 +413,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); + + hwe->ib1 &= ~MTK_FOE_IB1_STATE; +- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND); ++ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND); + dma_wmb(); + } + entry->hash = 0xffff; diff --git a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch b/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch new file mode 100644 index 0000000000..7ab6d486b2 --- /dev/null +++ b/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch @@ -0,0 +1,28 @@ +From 4253e6e2b795a18ab534adcd5c313d3fc4150975 Mon Sep 17 00:00:00 2001 +Message-Id: <4253e6e2b795a18ab534adcd5c313d3fc4150975.1662332102.git.lorenzo@kernel.org> +In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 00:48:52 +0200 +Subject: [PATCH net-next 3/6] net: ethernet: mtk_eth_soc: check max allowed + value in mtk_ppe_check_skb + +Check theoretical OOB accesses in mtk_ppe_check_skb routine + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -294,6 +294,9 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s + if (!ppe) + return; + ++ if (hash > MTK_PPE_HASH_MASK) ++ return; ++ + now = (u16)jiffies; + diff = now - ppe->foe_check_time[hash]; + if (diff < HZ / 10) diff --git a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch b/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch deleted file mode 100644 index a8c88daf1f..0000000000 --- a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch +++ /dev/null @@ -1,189 +0,0 @@ -From e5ecb4f619197b93fa682d722452dc8412864cdb Mon Sep 17 00:00:00 2001 -Message-Id: -From: Lorenzo Bianconi -Date: Fri, 26 Aug 2022 01:12:57 +0200 -Subject: [PATCH net-next 1/5] net: ethernet: mtk_eth_wed: add - mtk_wed_configure_irq and mtk_wed_dma_{enable/disable} - -Introduce mtk_wed_configure_irq, mtk_wed_dma_enable and mtk_wed_dma_disable -utility routines. -This is a preliminary patch to introduce mt7986 wed support. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 87 +++++++++++++------- - drivers/net/ethernet/mediatek/mtk_wed_regs.h | 6 +- - 2 files changed, 64 insertions(+), 29 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -237,9 +237,30 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - } - - static void --mtk_wed_stop(struct mtk_wed_device *dev) -+mtk_wed_dma_disable(struct mtk_wed_device *dev) - { -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ -+ wed_clr(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_TX_DMA_EN | -+ MTK_WED_GLO_CFG_RX_DMA_EN); -+ - regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -+ wdma_m32(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_TX_DMA_EN | -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+} -+ -+static void -+mtk_wed_stop(struct mtk_wed_device *dev) -+{ -+ mtk_wed_dma_disable(dev); - mtk_wed_set_ext_int(dev, false); - - wed_clr(dev, MTK_WED_CTRL, -@@ -252,15 +273,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_MASK, 0); - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); -- -- wed_clr(dev, MTK_WED_GLO_CFG, -- MTK_WED_GLO_CFG_TX_DMA_EN | -- MTK_WED_GLO_CFG_RX_DMA_EN); -- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); - } - - static void -@@ -313,7 +325,10 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - -- wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - - offset = dev->hw->index ? 0x04000400 : 0; - wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -@@ -520,43 +535,38 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_d - } - - static void --mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) -+mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) - { -- u32 wdma_mask; -- u32 val; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -- if (!dev->tx_wdma[i].desc) -- mtk_wed_wdma_ring_setup(dev, i, 16); -- -- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); -- -- mtk_wed_hw_init(dev); -+ u32 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); - -+ /* wed control cr set */ - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WDMA_INT_AGENT_EN | - MTK_WED_CTRL_WPDMA_INT_AGENT_EN | - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, -+ MTK_WED_PCIE_INT_TRIGGER_STATUS); - - wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, - MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | - MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); - -- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -- -+ /* initail wdma interrupt agent */ - wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - - wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); - wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); -- - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); - wed_w32(dev, MTK_WED_INT_MASK, irq_mask); -+} -+ -+static void -+mtk_wed_dma_enable(struct mtk_wed_device *dev) -+{ -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); - - wed_set(dev, MTK_WED_GLO_CFG, - MTK_WED_GLO_CFG_TX_DMA_EN | -@@ -567,6 +577,26 @@ mtk_wed_start(struct mtk_wed_device *dev - wed_set(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); - -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_TX_DMA_EN | -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+} -+ -+static void -+mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) -+{ -+ u32 val; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -+ if (!dev->tx_wdma[i].desc) -+ mtk_wed_wdma_ring_setup(dev, i, 16); -+ -+ mtk_wed_hw_init(dev); -+ mtk_wed_configure_irq(dev, irq_mask); -+ - mtk_wed_set_ext_int(dev, true); - val = dev->wlan.wpdma_phys | - MTK_PCIE_MIRROR_MAP_EN | -@@ -577,6 +607,7 @@ mtk_wed_start(struct mtk_wed_device *dev - val |= BIT(0); - regmap_write(dev->hw->mirror, dev->hw->index * 4, val); - -+ mtk_wed_dma_enable(dev); - dev->running = true; - } - ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -224,7 +224,11 @@ struct mtk_wdma_desc { - #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) - - #define MTK_WDMA_GLO_CFG 0x204 --#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26) -+#define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) -+#define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) -+#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) -+#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) -+#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) - - #define MTK_WDMA_RESET_IDX 0x208 - #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) diff --git a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch b/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch new file mode 100644 index 0000000000..a8c88daf1f --- /dev/null +++ b/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch @@ -0,0 +1,189 @@ +From e5ecb4f619197b93fa682d722452dc8412864cdb Mon Sep 17 00:00:00 2001 +Message-Id: +From: Lorenzo Bianconi +Date: Fri, 26 Aug 2022 01:12:57 +0200 +Subject: [PATCH net-next 1/5] net: ethernet: mtk_eth_wed: add + mtk_wed_configure_irq and mtk_wed_dma_{enable/disable} + +Introduce mtk_wed_configure_irq, mtk_wed_dma_enable and mtk_wed_dma_disable +utility routines. +This is a preliminary patch to introduce mt7986 wed support. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 87 +++++++++++++------- + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 6 +- + 2 files changed, 64 insertions(+), 29 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -237,9 +237,30 @@ mtk_wed_set_ext_int(struct mtk_wed_devic + } + + static void +-mtk_wed_stop(struct mtk_wed_device *dev) ++mtk_wed_dma_disable(struct mtk_wed_device *dev) + { ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); ++ ++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); ++ ++ wed_clr(dev, MTK_WED_GLO_CFG, ++ MTK_WED_GLO_CFG_TX_DMA_EN | ++ MTK_WED_GLO_CFG_RX_DMA_EN); ++ + regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); ++ wdma_m32(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_TX_DMA_EN | ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++} ++ ++static void ++mtk_wed_stop(struct mtk_wed_device *dev) ++{ ++ mtk_wed_dma_disable(dev); + mtk_wed_set_ext_int(dev, false); + + wed_clr(dev, MTK_WED_CTRL, +@@ -252,15 +273,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) + wdma_w32(dev, MTK_WDMA_INT_MASK, 0); + wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); + wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); +- +- wed_clr(dev, MTK_WED_GLO_CFG, +- MTK_WED_GLO_CFG_TX_DMA_EN | +- MTK_WED_GLO_CFG_RX_DMA_EN); +- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, +- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | +- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); +- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, +- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); + } + + static void +@@ -313,7 +325,10 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; + wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); + +- wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES); ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); + + offset = dev->hw->index ? 0x04000400 : 0; + wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); +@@ -520,43 +535,38 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_d + } + + static void +-mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) ++mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) + { +- u32 wdma_mask; +- u32 val; +- int i; +- +- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) +- if (!dev->tx_wdma[i].desc) +- mtk_wed_wdma_ring_setup(dev, i, 16); +- +- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); +- +- mtk_wed_hw_init(dev); ++ u32 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); + ++ /* wed control cr set */ + wed_set(dev, MTK_WED_CTRL, + MTK_WED_CTRL_WDMA_INT_AGENT_EN | + MTK_WED_CTRL_WPDMA_INT_AGENT_EN | + MTK_WED_CTRL_WED_TX_BM_EN | + MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); + +- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS); ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, ++ MTK_WED_PCIE_INT_TRIGGER_STATUS); + + wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, + MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | + MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); + +- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, +- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); +- ++ /* initail wdma interrupt agent */ + wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); + wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); + + wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); + wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); +- + wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); + wed_w32(dev, MTK_WED_INT_MASK, irq_mask); ++} ++ ++static void ++mtk_wed_dma_enable(struct mtk_wed_device *dev) ++{ ++ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); + + wed_set(dev, MTK_WED_GLO_CFG, + MTK_WED_GLO_CFG_TX_DMA_EN | +@@ -567,6 +577,26 @@ mtk_wed_start(struct mtk_wed_device *dev + wed_set(dev, MTK_WED_WDMA_GLO_CFG, + MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); + ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_TX_DMA_EN | ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++} ++ ++static void ++mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) ++{ ++ u32 val; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) ++ if (!dev->tx_wdma[i].desc) ++ mtk_wed_wdma_ring_setup(dev, i, 16); ++ ++ mtk_wed_hw_init(dev); ++ mtk_wed_configure_irq(dev, irq_mask); ++ + mtk_wed_set_ext_int(dev, true); + val = dev->wlan.wpdma_phys | + MTK_PCIE_MIRROR_MAP_EN | +@@ -577,6 +607,7 @@ mtk_wed_start(struct mtk_wed_device *dev + val |= BIT(0); + regmap_write(dev->hw->mirror, dev->hw->index * 4, val); + ++ mtk_wed_dma_enable(dev); + dev->running = true; + } + +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -224,7 +224,11 @@ struct mtk_wdma_desc { + #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) + + #define MTK_WDMA_GLO_CFG 0x204 +-#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26) ++#define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) ++#define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) ++#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) ++#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) ++#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) + + #define MTK_WDMA_RESET_IDX 0x208 + #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) diff --git a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch b/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch deleted file mode 100644 index 71bfcdbac8..0000000000 --- a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch +++ /dev/null @@ -1,942 +0,0 @@ -From 463a71af080fbc77339bee2037fb1e081e3824f7 Mon Sep 17 00:00:00 2001 -Message-Id: <463a71af080fbc77339bee2037fb1e081e3824f7.1662886034.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 27 Aug 2022 16:15:14 +0200 -Subject: [PATCH net-next 2/5] net: ethernet: mtk_eth_wed: add wed support for - mt7986 chipset - -Introduce Wireless Etherne Dispatcher support on transmission side -for mt7986 chipset - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +- - drivers/net/ethernet/mediatek/mtk_wed.c | 371 ++++++++++++++---- - drivers/net/ethernet/mediatek/mtk_wed.h | 8 +- - .../net/ethernet/mediatek/mtk_wed_debugfs.c | 3 + - drivers/net/ethernet/mediatek/mtk_wed_regs.h | 81 +++- - include/linux/soc/mediatek/mtk_wed.h | 8 + - 6 files changed, 408 insertions(+), 97 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3892,6 +3892,7 @@ void mtk_eth_set_dma_device(struct mtk_e - - static int mtk_probe(struct platform_device *pdev) - { -+ struct resource *res = NULL; - struct device_node *mac_np; - struct mtk_eth *eth; - int err, i; -@@ -3972,16 +3973,31 @@ static int mtk_probe(struct platform_dev - } - } - -- for (i = 0;; i++) { -- struct device_node *np = of_parse_phandle(pdev->dev.of_node, -- "mediatek,wed", i); -- void __iomem *wdma; -- -- if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) -- break; -- -- wdma = eth->base + eth->soc->reg_map->wdma_base[i]; -- mtk_wed_add_hw(np, eth, wdma, i); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ } -+ -+ if (eth->soc->offload_version) { -+ for (i = 0;; i++) { -+ struct device_node *np; -+ phys_addr_t wdma_phy; -+ u32 wdma_base; -+ -+ if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) -+ break; -+ -+ np = of_parse_phandle(pdev->dev.of_node, -+ "mediatek,wed", i); -+ if (!np) -+ break; -+ -+ wdma_base = eth->soc->reg_map->wdma_base[i]; -+ wdma_phy = res ? res->start + wdma_base : 0; -+ mtk_wed_add_hw(np, eth, eth->base + wdma_base, -+ wdma_phy, i); -+ } - } - - for (i = 0; i < 3; i++) { ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -25,6 +25,11 @@ - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -+#define MTK_WED_MAX_GROUP_SIZE 0x100 -+#define MTK_WED_VLD_GROUP_SIZE 0x40 -+#define MTK_WED_PER_GROUP_PKT 128 -+ -+#define MTK_WED_FBUF_SIZE 128 - - static struct mtk_wed_hw *hw_list[2]; - static DEFINE_MUTEX(hw_lock); -@@ -150,10 +155,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - - desc->buf0 = cpu_to_le32(buf_phys); - desc->buf1 = cpu_to_le32(buf_phys + txd_size); -- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ -+ if (dev->hw->version == 1) -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -+ MTK_WED_BUF_SIZE - txd_size) | -+ MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ else -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, -+ MTK_WED_BUF_SIZE - txd_size) | -+ MTK_WDMA_DESC_CTRL_LAST_SEG0; - desc->ctrl = cpu_to_le32(ctrl); - desc->info = 0; - desc++; -@@ -209,7 +221,7 @@ mtk_wed_free_ring(struct mtk_wed_device - if (!ring->desc) - return; - -- dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc), -+ dma_free_coherent(dev->hw->dev, ring->size * ring->desc_size, - ring->desc, ring->desc_phys); - } - -@@ -229,6 +241,14 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - { - u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -+ if (dev->hw->version == 1) -+ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -+ else -+ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | -+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; -+ - if (!dev->hw->num_flows) - mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; - -@@ -237,6 +257,20 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - } - - static void -+mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable) -+{ -+ if (enable) { -+ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); -+ wed_w32(dev, MTK_WED_TXP_DW1, -+ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103)); -+ } else { -+ wed_w32(dev, MTK_WED_TXP_DW1, -+ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100)); -+ wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); -+ } -+} -+ -+static void - mtk_wed_dma_disable(struct mtk_wed_device *dev) - { - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -@@ -249,12 +283,22 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_GLO_CFG_TX_DMA_EN | - MTK_WED_GLO_CFG_RX_DMA_EN); - -- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); - wdma_m32(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_TX_DMA_EN | - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); -+ -+ if (dev->hw->version == 1) { -+ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -+ wdma_m32(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+ } else { -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ -+ mtk_wed_set_512_support(dev, false); -+ } - } - - static void -@@ -293,7 +337,7 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_free_buffer(dev); - mtk_wed_free_tx_rings(dev); - -- if (of_dma_is_coherent(wlan_node)) -+ if (of_dma_is_coherent(wlan_node) && hw->hifsys) - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), BIT(hw->index)); - -@@ -308,14 +352,69 @@ mtk_wed_detach(struct mtk_wed_device *de - mutex_unlock(&hw_lock); - } - -+#define PCIE_BASE_ADDR0 0x11280000 -+static void -+mtk_wed_bus_init(struct mtk_wed_device *dev) -+{ -+ struct device_node *np = dev->hw->eth->dev->of_node; -+ struct regmap *regs; -+ u32 val; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); -+ if (IS_ERR(regs)) -+ return; -+ -+ regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ -+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -+ -+ /* pcie interrupt control: pola/source selection */ -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -+ -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -+ -+ /* pcie interrupt status trigger register */ -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -+ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -+ -+ /* pola setting */ -+ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+} -+ -+static void -+mtk_wed_set_wpdma(struct mtk_wed_device *dev) -+{ -+ if (dev->hw->version == 1) { -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -+ } else { -+ mtk_wed_bus_init(dev); -+ -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ } -+} -+ - static void - mtk_wed_hw_init_early(struct mtk_wed_device *dev) - { - u32 mask, set; -- u32 offset; - - mtk_wed_stop(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ mtk_wed_set_wpdma(dev); - - mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | - MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -@@ -325,17 +424,33 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - -- wdma_set(dev, MTK_WDMA_GLO_CFG, -- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -- -- offset = dev->hw->index ? 0x04000400 : 0; -- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -- wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); -+ if (dev->hw->version == 1) { -+ u32 offset = dev->hw->index ? 0x04000400 : 0; - -- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index)); -- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+ -+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, -+ MTK_PCIE_BASE(dev->hw->index)); -+ } else { -+ wed_w32(dev, MTK_WED_WDMA_CFG_BASE, dev->hw->wdma_phy); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_ETH_DMAD_FMT); -+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, -+ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_INTS, -+ MTK_WDMA_INT_STATUS) | -+ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_CFG, -+ MTK_WDMA_GLO_CFG)); -+ -+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, -+ FIELD_PREP(MTK_WED_WDMA_OFST1_TX_CTRL, -+ MTK_WDMA_RING_TX(0)) | -+ FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL, -+ MTK_WDMA_RING_RX(0))); -+ } - } - - static void -@@ -355,37 +470,65 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); - -- wed_w32(dev, MTK_WED_TX_BM_TKID, -- FIELD_PREP(MTK_WED_TX_BM_TKID_START, -- dev->wlan.token_start) | -- FIELD_PREP(MTK_WED_TX_BM_TKID_END, -- dev->wlan.token_start + dev->wlan.nbuf - 1)); -- - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - -- wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | -- MTK_WED_TX_BM_DYN_THR_HI); -+ if (dev->hw->version == 1) { -+ wed_w32(dev, MTK_WED_TX_BM_TKID, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, -+ dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + -+ dev->wlan.nbuf - 1)); -+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | -+ MTK_WED_TX_BM_DYN_THR_HI); -+ } else { -+ wed_w32(dev, MTK_WED_TX_BM_TKID_V2, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, -+ dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + -+ dev->wlan.nbuf - 1)); -+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | -+ MTK_WED_TX_BM_DYN_THR_HI_V2); -+ wed_w32(dev, MTK_WED_TX_TKID_CTRL, -+ MTK_WED_TX_TKID_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, -+ dev->buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, -+ dev->buf_ring.size / 128)); -+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | -+ MTK_WED_TX_TKID_DYN_THR_HI); -+ } - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -- wed_set(dev, MTK_WED_CTRL, -- MTK_WED_CTRL_WED_TX_BM_EN | -- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ if (dev->hw->version == 1) -+ wed_set(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ else -+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); - } - - static void --mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size) -+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) - { -+ void *head = (void *)ring->desc; - int i; - - for (i = 0; i < size; i++) { -- desc[i].buf0 = 0; -- desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -- desc[i].buf1 = 0; -- desc[i].info = 0; -+ struct mtk_wdma_desc *desc; -+ -+ desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); -+ desc->buf0 = 0; -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc->buf1 = 0; -+ desc->info = 0; - } - } - -@@ -436,12 +579,10 @@ mtk_wed_reset_dma(struct mtk_wed_device - int i; - - for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) { -- struct mtk_wdma_desc *desc = dev->tx_ring[i].desc; -- -- if (!desc) -+ if (!dev->tx_ring[i].desc) - continue; - -- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE); -+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); - } - - if (mtk_wed_poll_busy(dev)) -@@ -498,16 +639,16 @@ mtk_wed_reset_dma(struct mtk_wed_device - - static int - mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -- int size) -+ int size, u32 desc_size) - { -- ring->desc = dma_alloc_coherent(dev->hw->dev, -- size * sizeof(*ring->desc), -+ ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, - &ring->desc_phys, GFP_KERNEL); - if (!ring->desc) - return -ENOMEM; - -+ ring->desc_size = desc_size; - ring->size = size; -- mtk_wed_ring_reset(ring->desc, size); -+ mtk_wed_ring_reset(ring, size); - - return 0; - } -@@ -515,9 +656,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device - static int - mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) - { -+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; - -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -546,16 +688,41 @@ mtk_wed_configure_irq(struct mtk_wed_dev - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, -- MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ if (dev->hw->version == 1) { -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, -+ MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, -+ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | -+ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); - -- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, -- MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | -- MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); -+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); -+ } else { -+ /* initail tx interrupt trigger */ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, -+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR | -+ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN | -+ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG, -+ dev->wlan.tx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG, -+ dev->wlan.tx_tbit[1])); -+ -+ /* initail txfree interrupt trigger */ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX_FREE, -+ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN | -+ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, -+ dev->wlan.txfree_tbit)); -+ -+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); -+ wed_set(dev, MTK_WED_WDMA_INT_CTRL, -+ FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, -+ dev->wdma_idx)); -+ } - -- /* initail wdma interrupt agent */ - wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); -- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - - wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); - wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); -@@ -580,14 +747,28 @@ mtk_wed_dma_enable(struct mtk_wed_device - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_TX_DMA_EN | - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); -+ -+ if (dev->hw->version == 1) { -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+ } else { -+ wed_set(dev, MTK_WED_WPDMA_CTRL, -+ MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | -+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -+ } - } - - static void - mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) - { -- u32 val; - int i; - - for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -@@ -598,14 +779,17 @@ mtk_wed_start(struct mtk_wed_device *dev - mtk_wed_configure_irq(dev, irq_mask); - - mtk_wed_set_ext_int(dev, true); -- val = dev->wlan.wpdma_phys | -- MTK_PCIE_MIRROR_MAP_EN | -- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index); -- -- if (dev->hw->index) -- val |= BIT(1); -- val |= BIT(0); -- regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -+ -+ if (dev->hw->version == 1) { -+ u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | -+ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, -+ dev->hw->index); -+ -+ val |= BIT(0) | (BIT(1) * !!dev->hw->index); -+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -+ } else { -+ mtk_wed_set_512_support(dev, true); -+ } - - mtk_wed_dma_enable(dev); - dev->running = true; -@@ -639,7 +823,9 @@ mtk_wed_attach(struct mtk_wed_device *de - goto out; - } - -- dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index); -+ dev_info(&dev->wlan.pci_dev->dev, -+ "attaching wed device %d version %d\n", -+ hw->index, hw->version); - - dev->hw = hw; - dev->dev = hw->dev; -@@ -657,7 +843,9 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0); -+ if (hw->hifsys) -+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -+ BIT(hw->index), 0); - - out: - mutex_unlock(&hw_lock); -@@ -684,7 +872,8 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - - BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); - -- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) -+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -+ sizeof(*ring->desc))) - return -ENOMEM; - - if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -@@ -711,21 +900,21 @@ static int - mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) - { - struct mtk_wed_ring *ring = &dev->txfree_ring; -- int i; -+ int i, index = dev->hw->version == 1; - - /* - * For txfree event handling, the same DMA ring is shared between WED - * and WLAN. The WLAN driver accesses the ring index registers through - * WED - */ -- ring->reg_base = MTK_WED_RING_RX(1); -+ ring->reg_base = MTK_WED_RING_RX(index); - ring->wpdma = regs; - - for (i = 0; i < 12; i += 4) { - u32 val = readl(regs + i); - -- wed_w32(dev, MTK_WED_RING_RX(1) + i, val); -- wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val); -+ wed_w32(dev, MTK_WED_RING_RX(index) + i, val); -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX(index) + i, val); - } - - return 0; -@@ -734,11 +923,19 @@ mtk_wed_txfree_ring_setup(struct mtk_wed - static u32 - mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) - { -- u32 val; -+ u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ -+ if (dev->hw->version == 1) -+ ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -+ else -+ ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | -+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; - - val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); - wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); -- val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ val &= ext_mask; - if (!dev->hw->num_flows) - val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; - if (val && net_ratelimit()) -@@ -813,7 +1010,8 @@ out: - } - - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -- void __iomem *wdma, int index) -+ void __iomem *wdma, phys_addr_t wdma_phy, -+ int index) - { - static const struct mtk_wed_ops wed_ops = { - .attach = mtk_wed_attach, -@@ -860,26 +1058,33 @@ void mtk_wed_add_hw(struct device_node * - hw = kzalloc(sizeof(*hw), GFP_KERNEL); - if (!hw) - goto unlock; -+ - hw->node = np; - hw->regs = regs; - hw->eth = eth; - hw->dev = &pdev->dev; -+ hw->wdma_phy = wdma_phy; - hw->wdma = wdma; - hw->index = index; - hw->irq = irq; -- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, -- "mediatek,pcie-mirror"); -- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -- "mediatek,hifsys"); -- if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { -- kfree(hw); -- goto unlock; -- } -+ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; - -- if (!index) { -- regmap_write(hw->mirror, 0, 0); -- regmap_write(hw->mirror, 4, 0); -+ if (hw->version == 1) { -+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, -+ "mediatek,pcie-mirror"); -+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -+ "mediatek,hifsys"); -+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { -+ kfree(hw); -+ goto unlock; -+ } -+ -+ if (!index) { -+ regmap_write(hw->mirror, 0, 0); -+ regmap_write(hw->mirror, 4, 0); -+ } - } -+ - mtk_wed_hw_add_debugfs(hw); - - hw_list[index] = hw; ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -18,11 +18,13 @@ struct mtk_wed_hw { - struct regmap *hifsys; - struct device *dev; - void __iomem *wdma; -+ phys_addr_t wdma_phy; - struct regmap *mirror; - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; - u32 debugfs_reg; - u32 num_flows; -+ u8 version; - char dirname[5]; - int irq; - int index; -@@ -101,14 +103,16 @@ wpdma_txfree_w32(struct mtk_wed_device * - } - - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -- void __iomem *wdma, int index); -+ void __iomem *wdma, phys_addr_t wdma_phy, -+ int index); - void mtk_wed_exit(void); - int mtk_wed_flow_add(int index); - void mtk_wed_flow_remove(int index); - #else - static inline void - mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -- void __iomem *wdma, int index) -+ void __iomem *wdma, phys_addr_t wdma_phy, -+ int index) - { - } - static inline void ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -116,6 +116,9 @@ wed_txinfo_show(struct seq_file *s, void - DUMP_WDMA(WDMA_GLO_CFG), - DUMP_WDMA_RING(WDMA_RING_RX(0)), - DUMP_WDMA_RING(WDMA_RING_RX(1)), -+ -+ DUMP_STR("TX FREE"), -+ DUMP_WED(WED_RX_MIB(0)), - }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -5,6 +5,7 @@ - #define __MTK_WED_REGS_H - - #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) -+#define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) - #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) - #define MTK_WDMA_DESC_CTRL_BURST BIT(16) - #define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16) -@@ -41,6 +42,7 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_RESERVE_EN BIT(12) - #define MTK_WED_CTRL_RESERVE_BUSY BIT(13) - #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) -+#define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) - #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) - - #define MTK_WED_EXT_INT_STATUS 0x020 -@@ -57,7 +59,8 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20) - #define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21) --#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22) -+#define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) -+#define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) - #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ - MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ -@@ -65,8 +68,7 @@ struct mtk_wdma_desc { - MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \ - MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \ - MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \ -- MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \ -- MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR) -+ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) - - #define MTK_WED_EXT_INT_MASK 0x028 - -@@ -81,6 +83,7 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_BM_BASE 0x084 - - #define MTK_WED_TX_BM_TKID 0x088 -+#define MTK_WED_TX_BM_TKID_V2 0x0c8 - #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) - #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) - -@@ -94,7 +97,25 @@ struct mtk_wdma_desc { - - #define MTK_WED_TX_BM_DYN_THR 0x0a0 - #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0) -+#define MTK_WED_TX_BM_DYN_THR_LO_V2 GENMASK(8, 0) - #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16) -+#define MTK_WED_TX_BM_DYN_THR_HI_V2 GENMASK(24, 16) -+ -+#define MTK_WED_TX_TKID_CTRL 0x0c0 -+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0) -+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) -+#define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) -+ -+#define MTK_WED_TX_TKID_DYN_THR 0x0e0 -+#define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) -+#define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) -+ -+#define MTK_WED_TXP_DW0 0x120 -+#define MTK_WED_TXP_DW1 0x124 -+#define MTK_WED_WPDMA_WRITE_TXP GENMASK(31, 16) -+#define MTK_WED_TXDP_CTRL 0x130 -+#define MTK_WED_TXDP_DW9_OVERWR BIT(9) -+#define MTK_WED_RX_BM_TKID_MIB 0x1cc - - #define MTK_WED_INT_STATUS 0x200 - #define MTK_WED_INT_MASK 0x204 -@@ -125,6 +146,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) - - #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) -+#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) - - #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) - -@@ -155,21 +177,62 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29) - #define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) - -+/* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC BIT(4) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21) -+#define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28) -+ - #define MTK_WED_WPDMA_RESET_IDX 0x50c - #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) - #define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16) - -+#define MTK_WED_WPDMA_CTRL 0x518 -+#define MTK_WED_WPDMA_CTRL_SDL1_FIXED BIT(31) -+ - #define MTK_WED_WPDMA_INT_CTRL 0x520 - #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) - - #define MTK_WED_WPDMA_INT_MASK 0x524 - -+#define MTK_WED_WPDMA_INT_CTRL_TX 0x530 -+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) -+ -+#define MTK_WED_WPDMA_INT_CTRL_RX 0x534 -+ -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG GENMASK(6, 2) -+ - #define MTK_WED_PCIE_CFG_BASE 0x560 - -+#define MTK_WED_PCIE_CFG_BASE 0x560 -+#define MTK_WED_PCIE_CFG_INTM 0x564 -+#define MTK_WED_PCIE_CFG_MSIS 0x568 - #define MTK_WED_PCIE_INT_TRIGGER 0x570 - #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) - -+#define MTK_WED_PCIE_INT_CTRL 0x57c -+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) -+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) -+#define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12) -+ - #define MTK_WED_WPDMA_CFG_BASE 0x580 -+#define MTK_WED_WPDMA_CFG_INT_MASK 0x584 -+#define MTK_WED_WPDMA_CFG_TX 0x588 -+#define MTK_WED_WPDMA_CFG_TX_FREE 0x58c - - #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) - #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) -@@ -203,15 +266,24 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) - #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) - -+#define MTK_WED_WDMA_INT_CLR 0xa24 -+#define MTK_WED_WDMA_INT_CLR_RX_DONE GENMASK(17, 16) -+ - #define MTK_WED_WDMA_INT_TRIGGER 0xa28 - #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) - - #define MTK_WED_WDMA_INT_CTRL 0xa2c - #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) - -+#define MTK_WED_WDMA_CFG_BASE 0xaa0 - #define MTK_WED_WDMA_OFFSET0 0xaa4 - #define MTK_WED_WDMA_OFFSET1 0xaa8 - -+#define MTK_WED_WDMA_OFST0_GLO_INTS GENMASK(15, 0) -+#define MTK_WED_WDMA_OFST0_GLO_CFG GENMASK(31, 16) -+#define MTK_WED_WDMA_OFST1_TX_CTRL GENMASK(15, 0) -+#define MTK_WED_WDMA_OFST1_RX_CTRL GENMASK(31, 16) -+ - #define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4) - #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) - #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) -@@ -221,6 +293,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RING_OFS_CPU_IDX 0x08 - #define MTK_WED_RING_OFS_DMA_IDX 0x0c - -+#define MTK_WDMA_RING_TX(_n) (0x000 + (_n) * 0x10) - #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) - - #define MTK_WDMA_GLO_CFG 0x204 -@@ -234,6 +307,8 @@ struct mtk_wdma_desc { - #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) - #define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16) - -+#define MTK_WDMA_INT_STATUS 0x220 -+ - #define MTK_WDMA_INT_MASK 0x228 - #define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0) - #define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16) ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -14,6 +14,7 @@ struct mtk_wdma_desc; - struct mtk_wed_ring { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -+ u32 desc_size; - int size; - - u32 reg_base; -@@ -45,10 +46,17 @@ struct mtk_wed_device { - struct pci_dev *pci_dev; - - u32 wpdma_phys; -+ u32 wpdma_int; -+ u32 wpdma_mask; -+ u32 wpdma_tx; -+ u32 wpdma_txfree; - - u16 token_start; - unsigned int nbuf; - -+ u8 tx_tbit[MTK_WED_TX_QUEUES]; -+ u8 txfree_tbit; -+ - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); - void (*offload_disable)(struct mtk_wed_device *wed); diff --git a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch b/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch deleted file mode 100644 index 70b7bad31f..0000000000 --- a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch +++ /dev/null @@ -1,237 +0,0 @@ -From 6e1df49f330dce7c58a39d6772f1385b6887bb03 Mon Sep 17 00:00:00 2001 -Message-Id: <6e1df49f330dce7c58a39d6772f1385b6887bb03.1662990860.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Thu, 8 Sep 2022 11:26:10 +0200 -Subject: [PATCH net-next] net: ethernet: mtk_eth_wed: add axi bus support - -Other than pcie bus, introduce support for axi bus to mtk wed driver. -Axi bus is used to connect mt7986-wmac soc chip available on mt7986 -device. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 116 +++++++++++++------ - drivers/net/ethernet/mediatek/mtk_wed_regs.h | 2 + - include/linux/soc/mediatek/mtk_wed.h | 11 +- - 3 files changed, 91 insertions(+), 38 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -85,11 +85,31 @@ static struct mtk_wed_hw * - mtk_wed_assign(struct mtk_wed_device *dev) - { - struct mtk_wed_hw *hw; -+ int i; -+ -+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { -+ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; -+ if (!hw) -+ return NULL; -+ -+ if (!hw->wed_dev) -+ goto out; -+ -+ if (hw->version == 1) -+ return NULL; -+ -+ /* MT7986 WED devices do not have any pcie slot restrictions */ -+ } -+ /* MT7986 PCIE or AXI */ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ hw = hw_list[i]; -+ if (hw && !hw->wed_dev) -+ goto out; -+ } - -- hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; -- if (!hw || hw->wed_dev) -- return NULL; -+ return NULL; - -+out: - hw->wed_dev = dev; - return hw; - } -@@ -322,7 +342,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) - static void - mtk_wed_detach(struct mtk_wed_device *dev) - { -- struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node; - struct mtk_wed_hw *hw = dev->hw; - - mutex_lock(&hw_lock); -@@ -337,9 +356,14 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_free_buffer(dev); - mtk_wed_free_tx_rings(dev); - -- if (of_dma_is_coherent(wlan_node) && hw->hifsys) -- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -- BIT(hw->index), BIT(hw->index)); -+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { -+ struct device_node *wlan_node; -+ -+ wlan_node = dev->wlan.pci_dev->dev.of_node; -+ if (of_dma_is_coherent(wlan_node) && hw->hifsys) -+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -+ BIT(hw->index), BIT(hw->index)); -+ } - - if (!hw_list[!hw->index]->wed_dev && - hw->eth->dma_dev != hw->eth->dev) -@@ -356,40 +380,54 @@ mtk_wed_detach(struct mtk_wed_device *de - static void - mtk_wed_bus_init(struct mtk_wed_device *dev) - { -- struct device_node *np = dev->hw->eth->dev->of_node; -- struct regmap *regs; -- u32 val; -- -- regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); -- if (IS_ERR(regs)) -- return; -+ switch (dev->wlan.bus_type) { -+ case MTK_WED_BUS_PCIE: { -+ struct device_node *np = dev->hw->eth->dev->of_node; -+ struct regmap *regs; -+ u32 val; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, -+ "mediatek,wed-pcie"); -+ if (IS_ERR(regs)) -+ break; - -- regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ regmap_update_bits(regs, 0, BIT(0), BIT(0)); - -- wed_w32(dev, MTK_WED_PCIE_INT_CTRL, -- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); - -- /* pcie interrupt control: pola/source selection */ -- wed_set(dev, MTK_WED_PCIE_INT_CTRL, -- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -- wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -- -- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -- -- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -- -- /* pcie interrupt status trigger register */ -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -- -- /* pola setting */ -- val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -- wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+ /* pcie interrupt control: pola/source selection */ -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -+ -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -+ -+ /* pcie interrupt status trigger register */ -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -+ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -+ -+ /* pola setting */ -+ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+ break; -+ } -+ case MTK_WED_BUS_AXI: -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -+ MTK_WED_WPDMA_INT_CTRL_SIG_SRC | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0)); -+ break; -+ default: -+ break; -+ } - } - - static void -@@ -800,12 +838,14 @@ mtk_wed_attach(struct mtk_wed_device *de - __releases(RCU) - { - struct mtk_wed_hw *hw; -+ struct device *device; - int ret = 0; - - RCU_LOCKDEP_WARN(!rcu_read_lock_held(), - "mtk_wed_attach without holding the RCU read lock"); - -- if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 || -+ if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE && -+ pci_domain_nr(dev->wlan.pci_dev->bus) > 1) || - !try_module_get(THIS_MODULE)) - ret = -ENODEV; - -@@ -823,8 +863,10 @@ mtk_wed_attach(struct mtk_wed_device *de - goto out; - } - -- dev_info(&dev->wlan.pci_dev->dev, -- "attaching wed device %d version %d\n", -+ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE -+ ? &dev->wlan.pci_dev->dev -+ : &dev->wlan.platform_dev->dev; -+ dev_info(device, "attaching wed device %d version %d\n", - hw->index, hw->version); - - dev->hw = hw; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -198,6 +198,8 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_INT_CTRL 0x520 - #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) -+#define MTK_WED_WPDMA_INT_CTRL_SIG_SRC BIT(22) -+#define MTK_WED_WPDMA_INT_CTRL_SRC_SEL GENMASK(17, 16) - - #define MTK_WED_WPDMA_INT_MASK 0x524 - ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -11,6 +11,11 @@ - struct mtk_wed_hw; - struct mtk_wdma_desc; - -+enum mtk_wed_bus_tye { -+ MTK_WED_BUS_PCIE, -+ MTK_WED_BUS_AXI, -+}; -+ - struct mtk_wed_ring { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -@@ -43,7 +48,11 @@ struct mtk_wed_device { - - /* filled by driver: */ - struct { -- struct pci_dev *pci_dev; -+ union { -+ struct platform_device *platform_dev; -+ struct pci_dev *pci_dev; -+ }; -+ enum mtk_wed_bus_tye bus_type; - - u32 wpdma_phys; - u32 wpdma_int; diff --git a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch b/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch new file mode 100644 index 0000000000..71bfcdbac8 --- /dev/null +++ b/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch @@ -0,0 +1,942 @@ +From 463a71af080fbc77339bee2037fb1e081e3824f7 Mon Sep 17 00:00:00 2001 +Message-Id: <463a71af080fbc77339bee2037fb1e081e3824f7.1662886034.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Sat, 27 Aug 2022 16:15:14 +0200 +Subject: [PATCH net-next 2/5] net: ethernet: mtk_eth_wed: add wed support for + mt7986 chipset + +Introduce Wireless Etherne Dispatcher support on transmission side +for mt7986 chipset + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +- + drivers/net/ethernet/mediatek/mtk_wed.c | 371 ++++++++++++++---- + drivers/net/ethernet/mediatek/mtk_wed.h | 8 +- + .../net/ethernet/mediatek/mtk_wed_debugfs.c | 3 + + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 81 +++- + include/linux/soc/mediatek/mtk_wed.h | 8 + + 6 files changed, 408 insertions(+), 97 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3892,6 +3892,7 @@ void mtk_eth_set_dma_device(struct mtk_e + + static int mtk_probe(struct platform_device *pdev) + { ++ struct resource *res = NULL; + struct device_node *mac_np; + struct mtk_eth *eth; + int err, i; +@@ -3972,16 +3973,31 @@ static int mtk_probe(struct platform_dev + } + } + +- for (i = 0;; i++) { +- struct device_node *np = of_parse_phandle(pdev->dev.of_node, +- "mediatek,wed", i); +- void __iomem *wdma; +- +- if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) +- break; +- +- wdma = eth->base + eth->soc->reg_map->wdma_base[i]; +- mtk_wed_add_hw(np, eth, wdma, i); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -EINVAL; ++ } ++ ++ if (eth->soc->offload_version) { ++ for (i = 0;; i++) { ++ struct device_node *np; ++ phys_addr_t wdma_phy; ++ u32 wdma_base; ++ ++ if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) ++ break; ++ ++ np = of_parse_phandle(pdev->dev.of_node, ++ "mediatek,wed", i); ++ if (!np) ++ break; ++ ++ wdma_base = eth->soc->reg_map->wdma_base[i]; ++ wdma_phy = res ? res->start + wdma_base : 0; ++ mtk_wed_add_hw(np, eth, eth->base + wdma_base, ++ wdma_phy, i); ++ } + } + + for (i = 0; i < 3; i++) { +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -25,6 +25,11 @@ + + #define MTK_WED_TX_RING_SIZE 2048 + #define MTK_WED_WDMA_RING_SIZE 1024 ++#define MTK_WED_MAX_GROUP_SIZE 0x100 ++#define MTK_WED_VLD_GROUP_SIZE 0x40 ++#define MTK_WED_PER_GROUP_PKT 128 ++ ++#define MTK_WED_FBUF_SIZE 128 + + static struct mtk_wed_hw *hw_list[2]; + static DEFINE_MUTEX(hw_lock); +@@ -150,10 +155,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi + + desc->buf0 = cpu_to_le32(buf_phys); + desc->buf1 = cpu_to_le32(buf_phys + txd_size); +- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | +- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, +- MTK_WED_BUF_SIZE - txd_size) | +- MTK_WDMA_DESC_CTRL_LAST_SEG1; ++ ++ if (dev->hw->version == 1) ++ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | ++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, ++ MTK_WED_BUF_SIZE - txd_size) | ++ MTK_WDMA_DESC_CTRL_LAST_SEG1; ++ else ++ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | ++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, ++ MTK_WED_BUF_SIZE - txd_size) | ++ MTK_WDMA_DESC_CTRL_LAST_SEG0; + desc->ctrl = cpu_to_le32(ctrl); + desc->info = 0; + desc++; +@@ -209,7 +221,7 @@ mtk_wed_free_ring(struct mtk_wed_device + if (!ring->desc) + return; + +- dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc), ++ dma_free_coherent(dev->hw->dev, ring->size * ring->desc_size, + ring->desc, ring->desc_phys); + } + +@@ -229,6 +241,14 @@ mtk_wed_set_ext_int(struct mtk_wed_devic + { + u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; + ++ if (dev->hw->version == 1) ++ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; ++ else ++ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | ++ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | ++ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | ++ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; ++ + if (!dev->hw->num_flows) + mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; + +@@ -237,6 +257,20 @@ mtk_wed_set_ext_int(struct mtk_wed_devic + } + + static void ++mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable) ++{ ++ if (enable) { ++ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); ++ wed_w32(dev, MTK_WED_TXP_DW1, ++ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103)); ++ } else { ++ wed_w32(dev, MTK_WED_TXP_DW1, ++ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100)); ++ wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); ++ } ++} ++ ++static void + mtk_wed_dma_disable(struct mtk_wed_device *dev) + { + wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, +@@ -249,12 +283,22 @@ mtk_wed_dma_disable(struct mtk_wed_devic + MTK_WED_GLO_CFG_TX_DMA_EN | + MTK_WED_GLO_CFG_RX_DMA_EN); + +- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); + wdma_m32(dev, MTK_WDMA_GLO_CFG, + MTK_WDMA_GLO_CFG_TX_DMA_EN | + MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); ++ ++ if (dev->hw->version == 1) { ++ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); ++ wdma_m32(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); ++ } else { ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); ++ ++ mtk_wed_set_512_support(dev, false); ++ } + } + + static void +@@ -293,7 +337,7 @@ mtk_wed_detach(struct mtk_wed_device *de + mtk_wed_free_buffer(dev); + mtk_wed_free_tx_rings(dev); + +- if (of_dma_is_coherent(wlan_node)) ++ if (of_dma_is_coherent(wlan_node) && hw->hifsys) + regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, + BIT(hw->index), BIT(hw->index)); + +@@ -308,14 +352,69 @@ mtk_wed_detach(struct mtk_wed_device *de + mutex_unlock(&hw_lock); + } + ++#define PCIE_BASE_ADDR0 0x11280000 ++static void ++mtk_wed_bus_init(struct mtk_wed_device *dev) ++{ ++ struct device_node *np = dev->hw->eth->dev->of_node; ++ struct regmap *regs; ++ u32 val; ++ ++ regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); ++ if (IS_ERR(regs)) ++ return; ++ ++ regmap_update_bits(regs, 0, BIT(0), BIT(0)); ++ ++ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); ++ ++ /* pcie interrupt control: pola/source selection */ ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, ++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); ++ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); ++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ ++ /* pcie interrupt status trigger register */ ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); ++ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); ++ ++ /* pola setting */ ++ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); ++} ++ ++static void ++mtk_wed_set_wpdma(struct mtk_wed_device *dev) ++{ ++ if (dev->hw->version == 1) { ++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); ++ } else { ++ mtk_wed_bus_init(dev); ++ ++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); ++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); ++ } ++} ++ + static void + mtk_wed_hw_init_early(struct mtk_wed_device *dev) + { + u32 mask, set; +- u32 offset; + + mtk_wed_stop(dev); + mtk_wed_reset(dev, MTK_WED_RESET_WED); ++ mtk_wed_set_wpdma(dev); + + mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | + MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | +@@ -325,17 +424,33 @@ mtk_wed_hw_init_early(struct mtk_wed_dev + MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; + wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); + +- wdma_set(dev, MTK_WDMA_GLO_CFG, +- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); +- +- offset = dev->hw->index ? 0x04000400 : 0; +- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); +- wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); ++ if (dev->hw->version == 1) { ++ u32 offset = dev->hw->index ? 0x04000400 : 0; + +- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index)); +- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++ ++ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); ++ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); ++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, ++ MTK_PCIE_BASE(dev->hw->index)); ++ } else { ++ wed_w32(dev, MTK_WED_WDMA_CFG_BASE, dev->hw->wdma_phy); ++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_ETH_DMAD_FMT); ++ wed_w32(dev, MTK_WED_WDMA_OFFSET0, ++ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_INTS, ++ MTK_WDMA_INT_STATUS) | ++ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_CFG, ++ MTK_WDMA_GLO_CFG)); ++ ++ wed_w32(dev, MTK_WED_WDMA_OFFSET1, ++ FIELD_PREP(MTK_WED_WDMA_OFST1_TX_CTRL, ++ MTK_WDMA_RING_TX(0)) | ++ FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL, ++ MTK_WDMA_RING_RX(0))); ++ } + } + + static void +@@ -355,37 +470,65 @@ mtk_wed_hw_init(struct mtk_wed_device *d + + wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); + +- wed_w32(dev, MTK_WED_TX_BM_TKID, +- FIELD_PREP(MTK_WED_TX_BM_TKID_START, +- dev->wlan.token_start) | +- FIELD_PREP(MTK_WED_TX_BM_TKID_END, +- dev->wlan.token_start + dev->wlan.nbuf - 1)); +- + wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); + +- wed_w32(dev, MTK_WED_TX_BM_DYN_THR, +- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | +- MTK_WED_TX_BM_DYN_THR_HI); ++ if (dev->hw->version == 1) { ++ wed_w32(dev, MTK_WED_TX_BM_TKID, ++ FIELD_PREP(MTK_WED_TX_BM_TKID_START, ++ dev->wlan.token_start) | ++ FIELD_PREP(MTK_WED_TX_BM_TKID_END, ++ dev->wlan.token_start + ++ dev->wlan.nbuf - 1)); ++ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, ++ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | ++ MTK_WED_TX_BM_DYN_THR_HI); ++ } else { ++ wed_w32(dev, MTK_WED_TX_BM_TKID_V2, ++ FIELD_PREP(MTK_WED_TX_BM_TKID_START, ++ dev->wlan.token_start) | ++ FIELD_PREP(MTK_WED_TX_BM_TKID_END, ++ dev->wlan.token_start + ++ dev->wlan.nbuf - 1)); ++ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, ++ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | ++ MTK_WED_TX_BM_DYN_THR_HI_V2); ++ wed_w32(dev, MTK_WED_TX_TKID_CTRL, ++ MTK_WED_TX_TKID_CTRL_PAUSE | ++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, ++ dev->buf_ring.size / 128) | ++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, ++ dev->buf_ring.size / 128)); ++ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, ++ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | ++ MTK_WED_TX_TKID_DYN_THR_HI); ++ } + + mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); + +- wed_set(dev, MTK_WED_CTRL, +- MTK_WED_CTRL_WED_TX_BM_EN | +- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ if (dev->hw->version == 1) ++ wed_set(dev, MTK_WED_CTRL, ++ MTK_WED_CTRL_WED_TX_BM_EN | ++ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); ++ else ++ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); + + wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); + } + + static void +-mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size) ++mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) + { ++ void *head = (void *)ring->desc; + int i; + + for (i = 0; i < size; i++) { +- desc[i].buf0 = 0; +- desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); +- desc[i].buf1 = 0; +- desc[i].info = 0; ++ struct mtk_wdma_desc *desc; ++ ++ desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); ++ desc->buf0 = 0; ++ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); ++ desc->buf1 = 0; ++ desc->info = 0; + } + } + +@@ -436,12 +579,10 @@ mtk_wed_reset_dma(struct mtk_wed_device + int i; + + for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) { +- struct mtk_wdma_desc *desc = dev->tx_ring[i].desc; +- +- if (!desc) ++ if (!dev->tx_ring[i].desc) + continue; + +- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE); ++ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); + } + + if (mtk_wed_poll_busy(dev)) +@@ -498,16 +639,16 @@ mtk_wed_reset_dma(struct mtk_wed_device + + static int + mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, +- int size) ++ int size, u32 desc_size) + { +- ring->desc = dma_alloc_coherent(dev->hw->dev, +- size * sizeof(*ring->desc), ++ ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, + &ring->desc_phys, GFP_KERNEL); + if (!ring->desc) + return -ENOMEM; + ++ ring->desc_size = desc_size; + ring->size = size; +- mtk_wed_ring_reset(ring->desc, size); ++ mtk_wed_ring_reset(ring, size); + + return 0; + } +@@ -515,9 +656,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device + static int + mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) + { ++ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; + struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; + +- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE)) ++ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) + return -ENOMEM; + + wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, +@@ -546,16 +688,41 @@ mtk_wed_configure_irq(struct mtk_wed_dev + MTK_WED_CTRL_WED_TX_BM_EN | + MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); + +- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, +- MTK_WED_PCIE_INT_TRIGGER_STATUS); ++ if (dev->hw->version == 1) { ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, ++ MTK_WED_PCIE_INT_TRIGGER_STATUS); ++ ++ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, ++ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | ++ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); + +- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, +- MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | +- MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); ++ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); ++ } else { ++ /* initail tx interrupt trigger */ ++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, ++ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | ++ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR | ++ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN | ++ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG, ++ dev->wlan.tx_tbit[0]) | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG, ++ dev->wlan.tx_tbit[1])); ++ ++ /* initail txfree interrupt trigger */ ++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX_FREE, ++ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN | ++ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, ++ dev->wlan.txfree_tbit)); ++ ++ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); ++ wed_set(dev, MTK_WED_WDMA_INT_CTRL, ++ FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, ++ dev->wdma_idx)); ++ } + +- /* initail wdma interrupt agent */ + wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); +- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); + + wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); + wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); +@@ -580,14 +747,28 @@ mtk_wed_dma_enable(struct mtk_wed_device + wdma_set(dev, MTK_WDMA_GLO_CFG, + MTK_WDMA_GLO_CFG_TX_DMA_EN | + MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | +- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); ++ ++ if (dev->hw->version == 1) { ++ wdma_set(dev, MTK_WDMA_GLO_CFG, ++ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); ++ } else { ++ wed_set(dev, MTK_WED_WPDMA_CTRL, ++ MTK_WED_WPDMA_CTRL_SDL1_FIXED); ++ ++ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | ++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); ++ ++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | ++ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); ++ } + } + + static void + mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) + { +- u32 val; + int i; + + for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) +@@ -598,14 +779,17 @@ mtk_wed_start(struct mtk_wed_device *dev + mtk_wed_configure_irq(dev, irq_mask); + + mtk_wed_set_ext_int(dev, true); +- val = dev->wlan.wpdma_phys | +- MTK_PCIE_MIRROR_MAP_EN | +- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index); +- +- if (dev->hw->index) +- val |= BIT(1); +- val |= BIT(0); +- regmap_write(dev->hw->mirror, dev->hw->index * 4, val); ++ ++ if (dev->hw->version == 1) { ++ u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | ++ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, ++ dev->hw->index); ++ ++ val |= BIT(0) | (BIT(1) * !!dev->hw->index); ++ regmap_write(dev->hw->mirror, dev->hw->index * 4, val); ++ } else { ++ mtk_wed_set_512_support(dev, true); ++ } + + mtk_wed_dma_enable(dev); + dev->running = true; +@@ -639,7 +823,9 @@ mtk_wed_attach(struct mtk_wed_device *de + goto out; + } + +- dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index); ++ dev_info(&dev->wlan.pci_dev->dev, ++ "attaching wed device %d version %d\n", ++ hw->index, hw->version); + + dev->hw = hw; + dev->dev = hw->dev; +@@ -657,7 +843,9 @@ mtk_wed_attach(struct mtk_wed_device *de + } + + mtk_wed_hw_init_early(dev); +- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0); ++ if (hw->hifsys) ++ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, ++ BIT(hw->index), 0); + + out: + mutex_unlock(&hw_lock); +@@ -684,7 +872,8 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + + BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); + +- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) ++ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, ++ sizeof(*ring->desc))) + return -ENOMEM; + + if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) +@@ -711,21 +900,21 @@ static int + mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) + { + struct mtk_wed_ring *ring = &dev->txfree_ring; +- int i; ++ int i, index = dev->hw->version == 1; + + /* + * For txfree event handling, the same DMA ring is shared between WED + * and WLAN. The WLAN driver accesses the ring index registers through + * WED + */ +- ring->reg_base = MTK_WED_RING_RX(1); ++ ring->reg_base = MTK_WED_RING_RX(index); + ring->wpdma = regs; + + for (i = 0; i < 12; i += 4) { + u32 val = readl(regs + i); + +- wed_w32(dev, MTK_WED_RING_RX(1) + i, val); +- wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val); ++ wed_w32(dev, MTK_WED_RING_RX(index) + i, val); ++ wed_w32(dev, MTK_WED_WPDMA_RING_RX(index) + i, val); + } + + return 0; +@@ -734,11 +923,19 @@ mtk_wed_txfree_ring_setup(struct mtk_wed + static u32 + mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) + { +- u32 val; ++ u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; ++ ++ if (dev->hw->version == 1) ++ ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; ++ else ++ ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | ++ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | ++ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | ++ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; + + val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); + wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); +- val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK; ++ val &= ext_mask; + if (!dev->hw->num_flows) + val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; + if (val && net_ratelimit()) +@@ -813,7 +1010,8 @@ out: + } + + void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +- void __iomem *wdma, int index) ++ void __iomem *wdma, phys_addr_t wdma_phy, ++ int index) + { + static const struct mtk_wed_ops wed_ops = { + .attach = mtk_wed_attach, +@@ -860,26 +1058,33 @@ void mtk_wed_add_hw(struct device_node * + hw = kzalloc(sizeof(*hw), GFP_KERNEL); + if (!hw) + goto unlock; ++ + hw->node = np; + hw->regs = regs; + hw->eth = eth; + hw->dev = &pdev->dev; ++ hw->wdma_phy = wdma_phy; + hw->wdma = wdma; + hw->index = index; + hw->irq = irq; +- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, +- "mediatek,pcie-mirror"); +- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, +- "mediatek,hifsys"); +- if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { +- kfree(hw); +- goto unlock; +- } ++ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; + +- if (!index) { +- regmap_write(hw->mirror, 0, 0); +- regmap_write(hw->mirror, 4, 0); ++ if (hw->version == 1) { ++ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, ++ "mediatek,pcie-mirror"); ++ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, ++ "mediatek,hifsys"); ++ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { ++ kfree(hw); ++ goto unlock; ++ } ++ ++ if (!index) { ++ regmap_write(hw->mirror, 0, 0); ++ regmap_write(hw->mirror, 4, 0); ++ } + } ++ + mtk_wed_hw_add_debugfs(hw); + + hw_list[index] = hw; +--- a/drivers/net/ethernet/mediatek/mtk_wed.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed.h +@@ -18,11 +18,13 @@ struct mtk_wed_hw { + struct regmap *hifsys; + struct device *dev; + void __iomem *wdma; ++ phys_addr_t wdma_phy; + struct regmap *mirror; + struct dentry *debugfs_dir; + struct mtk_wed_device *wed_dev; + u32 debugfs_reg; + u32 num_flows; ++ u8 version; + char dirname[5]; + int irq; + int index; +@@ -101,14 +103,16 @@ wpdma_txfree_w32(struct mtk_wed_device * + } + + void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +- void __iomem *wdma, int index); ++ void __iomem *wdma, phys_addr_t wdma_phy, ++ int index); + void mtk_wed_exit(void); + int mtk_wed_flow_add(int index); + void mtk_wed_flow_remove(int index); + #else + static inline void + mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, +- void __iomem *wdma, int index) ++ void __iomem *wdma, phys_addr_t wdma_phy, ++ int index) + { + } + static inline void +--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c +@@ -116,6 +116,9 @@ wed_txinfo_show(struct seq_file *s, void + DUMP_WDMA(WDMA_GLO_CFG), + DUMP_WDMA_RING(WDMA_RING_RX(0)), + DUMP_WDMA_RING(WDMA_RING_RX(1)), ++ ++ DUMP_STR("TX FREE"), ++ DUMP_WED(WED_RX_MIB(0)), + }; + struct mtk_wed_hw *hw = s->private; + struct mtk_wed_device *dev = hw->wed_dev; +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -5,6 +5,7 @@ + #define __MTK_WED_REGS_H + + #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) ++#define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) + #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) + #define MTK_WDMA_DESC_CTRL_BURST BIT(16) + #define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16) +@@ -41,6 +42,7 @@ struct mtk_wdma_desc { + #define MTK_WED_CTRL_RESERVE_EN BIT(12) + #define MTK_WED_CTRL_RESERVE_BUSY BIT(13) + #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) ++#define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) + #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) + + #define MTK_WED_EXT_INT_STATUS 0x020 +@@ -57,7 +59,8 @@ struct mtk_wdma_desc { + #define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20) + #define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21) +-#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22) ++#define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) ++#define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) + #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) + #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ + MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ +@@ -65,8 +68,7 @@ struct mtk_wdma_desc { + MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \ + MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \ + MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \ +- MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \ +- MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR) ++ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) + + #define MTK_WED_EXT_INT_MASK 0x028 + +@@ -81,6 +83,7 @@ struct mtk_wdma_desc { + #define MTK_WED_TX_BM_BASE 0x084 + + #define MTK_WED_TX_BM_TKID 0x088 ++#define MTK_WED_TX_BM_TKID_V2 0x0c8 + #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) + #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) + +@@ -94,7 +97,25 @@ struct mtk_wdma_desc { + + #define MTK_WED_TX_BM_DYN_THR 0x0a0 + #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0) ++#define MTK_WED_TX_BM_DYN_THR_LO_V2 GENMASK(8, 0) + #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16) ++#define MTK_WED_TX_BM_DYN_THR_HI_V2 GENMASK(24, 16) ++ ++#define MTK_WED_TX_TKID_CTRL 0x0c0 ++#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0) ++#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) ++#define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) ++ ++#define MTK_WED_TX_TKID_DYN_THR 0x0e0 ++#define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) ++#define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) ++ ++#define MTK_WED_TXP_DW0 0x120 ++#define MTK_WED_TXP_DW1 0x124 ++#define MTK_WED_WPDMA_WRITE_TXP GENMASK(31, 16) ++#define MTK_WED_TXDP_CTRL 0x130 ++#define MTK_WED_TXDP_DW9_OVERWR BIT(9) ++#define MTK_WED_RX_BM_TKID_MIB 0x1cc + + #define MTK_WED_INT_STATUS 0x200 + #define MTK_WED_INT_MASK 0x204 +@@ -125,6 +146,7 @@ struct mtk_wdma_desc { + #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) + + #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) ++#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) + + #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) + +@@ -155,21 +177,62 @@ struct mtk_wdma_desc { + #define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29) + #define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) + ++/* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC BIT(4) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20) ++#define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21) ++#define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24) ++#define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28) ++ + #define MTK_WED_WPDMA_RESET_IDX 0x50c + #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) + #define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16) + ++#define MTK_WED_WPDMA_CTRL 0x518 ++#define MTK_WED_WPDMA_CTRL_SDL1_FIXED BIT(31) ++ + #define MTK_WED_WPDMA_INT_CTRL 0x520 + #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) + + #define MTK_WED_WPDMA_INT_MASK 0x524 + ++#define MTK_WED_WPDMA_INT_CTRL_TX 0x530 ++#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0) ++#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1) ++#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG GENMASK(6, 2) ++#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN BIT(8) ++#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR BIT(9) ++#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) ++ ++#define MTK_WED_WPDMA_INT_CTRL_RX 0x534 ++ ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR BIT(1) ++#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG GENMASK(6, 2) ++ + #define MTK_WED_PCIE_CFG_BASE 0x560 + ++#define MTK_WED_PCIE_CFG_BASE 0x560 ++#define MTK_WED_PCIE_CFG_INTM 0x564 ++#define MTK_WED_PCIE_CFG_MSIS 0x568 + #define MTK_WED_PCIE_INT_TRIGGER 0x570 + #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) + ++#define MTK_WED_PCIE_INT_CTRL 0x57c ++#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) ++#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) ++#define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12) ++ + #define MTK_WED_WPDMA_CFG_BASE 0x580 ++#define MTK_WED_WPDMA_CFG_INT_MASK 0x584 ++#define MTK_WED_WPDMA_CFG_TX 0x588 ++#define MTK_WED_WPDMA_CFG_TX_FREE 0x58c + + #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) + #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) +@@ -203,15 +266,24 @@ struct mtk_wdma_desc { + #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) + #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) + ++#define MTK_WED_WDMA_INT_CLR 0xa24 ++#define MTK_WED_WDMA_INT_CLR_RX_DONE GENMASK(17, 16) ++ + #define MTK_WED_WDMA_INT_TRIGGER 0xa28 + #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) + + #define MTK_WED_WDMA_INT_CTRL 0xa2c + #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) + ++#define MTK_WED_WDMA_CFG_BASE 0xaa0 + #define MTK_WED_WDMA_OFFSET0 0xaa4 + #define MTK_WED_WDMA_OFFSET1 0xaa8 + ++#define MTK_WED_WDMA_OFST0_GLO_INTS GENMASK(15, 0) ++#define MTK_WED_WDMA_OFST0_GLO_CFG GENMASK(31, 16) ++#define MTK_WED_WDMA_OFST1_TX_CTRL GENMASK(15, 0) ++#define MTK_WED_WDMA_OFST1_RX_CTRL GENMASK(31, 16) ++ + #define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4) + #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) + #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) +@@ -221,6 +293,7 @@ struct mtk_wdma_desc { + #define MTK_WED_RING_OFS_CPU_IDX 0x08 + #define MTK_WED_RING_OFS_DMA_IDX 0x0c + ++#define MTK_WDMA_RING_TX(_n) (0x000 + (_n) * 0x10) + #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) + + #define MTK_WDMA_GLO_CFG 0x204 +@@ -234,6 +307,8 @@ struct mtk_wdma_desc { + #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) + #define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16) + ++#define MTK_WDMA_INT_STATUS 0x220 ++ + #define MTK_WDMA_INT_MASK 0x228 + #define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0) + #define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16) +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -14,6 +14,7 @@ struct mtk_wdma_desc; + struct mtk_wed_ring { + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; ++ u32 desc_size; + int size; + + u32 reg_base; +@@ -45,10 +46,17 @@ struct mtk_wed_device { + struct pci_dev *pci_dev; + + u32 wpdma_phys; ++ u32 wpdma_int; ++ u32 wpdma_mask; ++ u32 wpdma_tx; ++ u32 wpdma_txfree; + + u16 token_start; + unsigned int nbuf; + ++ u8 tx_tbit[MTK_WED_TX_QUEUES]; ++ u8 txfree_tbit; ++ + u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); + int (*offload_enable)(struct mtk_wed_device *wed); + void (*offload_disable)(struct mtk_wed_device *wed); diff --git a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch b/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch deleted file mode 100644 index 1ecbf485f1..0000000000 --- a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch +++ /dev/null @@ -1,882 +0,0 @@ -From 93408c858e5dc01d97c55efa721268f63fde2ae5 Mon Sep 17 00:00:00 2001 -Message-Id: <93408c858e5dc01d97c55efa721268f63fde2ae5.1662886034.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 3 Sep 2022 18:34:09 +0200 -Subject: [PATCH net-next 4/5] net: ethernet: mtk_eth_soc: introduce flow - offloading support for mt7986 - -Introduce hw flow offload support for mt7986 chipset. PPE is not enabled -yet in mt7986 since mt76 support is not available yet. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 72 ++++++ - drivers/net/ethernet/mediatek/mtk_ppe.c | 213 +++++++++++------- - drivers/net/ethernet/mediatek/mtk_ppe.h | 52 ++++- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 49 ++-- - drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 8 + - 6 files changed, 289 insertions(+), 116 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1858,12 +1858,14 @@ static int mtk_poll_rx(struct napi_struc - bytes += skb->len; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); - hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; - if (hash != MTK_RXD5_FOE_ENTRY) - skb_set_hash(skb, jhash_1word(hash, 0), - PKT_HASH_TYPE_L4); - rxdcsum = &trxd.rxd3; - } else { -+ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); - hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; - if (hash != MTK_RXD4_FOE_ENTRY) - skb_set_hash(skb, jhash_1word(hash, 0), -@@ -1877,7 +1879,6 @@ static int mtk_poll_rx(struct napi_struc - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, netdev); - -- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); - if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) - mtk_ppe_check_skb(eth->ppe[0], skb, hash); - -@@ -4181,7 +4182,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4201,7 +4202,7 @@ static const struct mtk_soc_data mt7622_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4220,7 +4221,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 2, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4252,9 +4253,11 @@ static const struct mtk_soc_data mt7986_ - .reg_map = &mt7986_reg_map, - .ana_rgc3 = 0x128, - .caps = MT7986_CAPS, -+ .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, - .hash_offset = 4, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1150,6 +1150,78 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u - return ppe->foe_table + hash * soc->foe_entry_size; - } - -+static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_TIMESTAMP_V2; -+ -+ return MTK_FOE_IB1_BIND_TIMESTAMP; -+} -+ -+static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_PPPOE_V2; -+ -+ return MTK_FOE_IB1_BIND_PPPOE; -+} -+ -+static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_VLAN_TAG_V2; -+ -+ return MTK_FOE_IB1_BIND_VLAN_TAG; -+} -+ -+static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; -+ -+ return MTK_FOE_IB1_BIND_VLAN_LAYER; -+} -+ -+static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); -+ -+ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -+} -+ -+static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); -+ -+ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -+} -+ -+static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_PACKET_TYPE_V2; -+ -+ return MTK_FOE_IB1_PACKET_TYPE; -+} -+ -+static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); -+ -+ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); -+} -+ -+static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB2_MULTICAST_V2; -+ -+ return MTK_FOE_IB2_MULTICAST; -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -56,7 +56,7 @@ static u32 ppe_clear(struct mtk_ppe *ppe - - static u32 mtk_eth_timestamp(struct mtk_eth *eth) - { -- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; -+ return mtk_r32(eth, 0x0010) & mtk_get_ib1_ts_mask(eth); - } - - static int mtk_ppe_wait_busy(struct mtk_ppe *ppe) -@@ -93,7 +93,7 @@ static u32 mtk_ppe_hash_entry(struct mtk - u32 hv1, hv2, hv3; - u32 hash; - -- switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) { -+ switch (mtk_get_ib1_pkt_type(eth, e->ib1)) { - case MTK_PPE_PKT_TYPE_IPV4_ROUTE: - case MTK_PPE_PKT_TYPE_IPV4_HNAPT: - hv1 = e->ipv4.orig.ports; -@@ -129,9 +129,9 @@ static u32 mtk_ppe_hash_entry(struct mtk - } - - static inline struct mtk_foe_mac_info * --mtk_foe_entry_l2(struct mtk_foe_entry *entry) -+mtk_foe_entry_l2(struct mtk_eth *eth, struct mtk_foe_entry *entry) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) - return &entry->bridge.l2; -@@ -143,9 +143,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e - } - - static inline u32 * --mtk_foe_entry_ib2(struct mtk_foe_entry *entry) -+mtk_foe_entry_ib2(struct mtk_eth *eth, struct mtk_foe_entry *entry) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) - return &entry->bridge.ib2; -@@ -156,27 +156,38 @@ mtk_foe_entry_ib2(struct mtk_foe_entry * - return &entry->ipv4.ib2; - } - --int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, -- u8 pse_port, u8 *src_mac, u8 *dest_mac) -+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int type, int l4proto, u8 pse_port, u8 *src_mac, -+ u8 *dest_mac) - { - struct mtk_foe_mac_info *l2; - u32 ports_pad, val; - - memset(entry, 0, sizeof(*entry)); - -- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | -- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | -- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -- MTK_FOE_IB1_BIND_TTL | -- MTK_FOE_IB1_BIND_CACHE; -- entry->ib1 = val; -- -- val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | -- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) | -- FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | -+ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | -+ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -+ MTK_FOE_IB1_BIND_CACHE_V2 | MTK_FOE_IB1_BIND_TTL_V2; -+ entry->ib1 = val; -+ -+ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); -+ } else { -+ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | -+ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | -+ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -+ MTK_FOE_IB1_BIND_CACHE | MTK_FOE_IB1_BIND_TTL; -+ entry->ib1 = val; -+ -+ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); -+ } - - if (is_multicast_ether_addr(dest_mac)) -- val |= MTK_FOE_IB2_MULTICAST; -+ val |= mtk_get_ib2_multicast_mask(eth); - - ports_pad = 0xa5a5a500 | (l4proto & 0xff); - if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE) -@@ -210,24 +221,30 @@ int mtk_foe_entry_prepare(struct mtk_foe - return 0; - } - --int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port) -+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, u8 port) - { -- u32 *ib2 = mtk_foe_entry_ib2(entry); -- u32 val; -+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); -+ u32 val = *ib2; - -- val = *ib2; -- val &= ~MTK_FOE_IB2_DEST_PORT; -- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ val &= ~MTK_FOE_IB2_DEST_PORT_V2; -+ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); -+ } else { -+ val &= ~MTK_FOE_IB2_DEST_PORT; -+ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); -+ } - *ib2 = val; - - return 0; - } - --int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress, -+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, bool egress, - __be32 src_addr, __be16 src_port, - __be32 dest_addr, __be16 dest_port) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - struct mtk_ipv4_tuple *t; - - switch (type) { -@@ -262,11 +279,12 @@ int mtk_foe_entry_set_ipv4_tuple(struct - return 0; - } - --int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, -+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, - __be32 *src_addr, __be16 src_port, - __be32 *dest_addr, __be16 dest_port) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - u32 *src, *dest; - int i; - -@@ -297,39 +315,41 @@ int mtk_foe_entry_set_ipv6_tuple(struct - return 0; - } - --int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port) -+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int port) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - - l2->etype = BIT(port); - -- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER)) -- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); -+ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth))) -+ entry->ib1 |= mtk_prep_ib1_vlan_layer(eth, 1); - else - l2->etype |= BIT(8); - -- entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG; -+ entry->ib1 &= ~mtk_get_ib1_vlan_tag_mask(eth); - - return 0; - } - --int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid) -+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int vid) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - -- switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) { -+ switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) { - case 0: -- entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG | -- FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); -+ entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) | -+ mtk_prep_ib1_vlan_layer(eth, 1); - l2->vlan1 = vid; - return 0; - case 1: -- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) { -+ if (!(entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) { - l2->vlan1 = vid; - l2->etype |= BIT(8); - } else { - l2->vlan2 = vid; -- entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); -+ entry->ib1 += mtk_prep_ib1_vlan_layer(eth, 1); - } - return 0; - default: -@@ -337,34 +357,42 @@ int mtk_foe_entry_set_vlan(struct mtk_fo - } - } - --int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid) -+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int sid) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - -- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) || -- (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) -+ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth)) || -+ (entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) - l2->etype = ETH_P_PPP_SES; - -- entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE; -+ entry->ib1 |= mtk_get_ib1_ppoe_mask(eth); - l2->pppoe_id = sid; - - return 0; - } - --int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, -- int bss, int wcid) -+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int wdma_idx, int txq, int bss, int wcid) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -- u32 *ib2 = mtk_foe_entry_ib2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); -+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- *ib2 &= ~MTK_FOE_IB2_PORT_MG; -- *ib2 |= MTK_FOE_IB2_WDMA_WINFO; -- if (wdma_idx) -- *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; -- -- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | -- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | -- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | -+ MTK_FOE_IB2_WDMA_WINFO_V2; -+ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | -+ FIELD_PREP(MTK_FOE_WINFO_BSS, bss); -+ } else { -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG; -+ *ib2 |= MTK_FOE_IB2_WDMA_WINFO; -+ if (wdma_idx) -+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; -+ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | -+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | -+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ } - - return 0; - } -@@ -376,14 +404,15 @@ static inline bool mtk_foe_entry_usable( - } - - static bool --mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data) -+mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, -+ struct mtk_foe_entry *data) - { - int type, len; - - if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) - return false; - -- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); -+ type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); - if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) - len = offsetof(struct mtk_foe_entry, ipv6._rsv); - else -@@ -427,14 +456,12 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - - static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) - { -- u16 timestamp; -- u16 now; -- -- now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; -- timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); -+ u16 now = mtk_eth_timestamp(ppe->eth); -+ u16 timestamp = ib1 & ib1_ts_mask; - - if (timestamp > now) -- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; -+ return ib1_ts_mask + 1 - timestamp + now; - else - return now - timestamp; - } -@@ -442,6 +469,7 @@ static int __mtk_foe_entry_idle_time(str - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -+ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); - struct mtk_flow_entry *cur; - struct mtk_foe_entry *hwe; - struct hlist_node *tmp; -@@ -466,8 +494,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe - continue; - - idle = cur_idle; -- entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -- entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ entry->data.ib1 &= ~ib1_ts_mask; -+ entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; - } - } - -@@ -489,7 +517,7 @@ mtk_flow_entry_update(struct mtk_ppe *pp - - hwe = mtk_foe_get_entry(ppe, entry->hash); - memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); -- if (!mtk_flow_entry_match(entry, &foe)) { -+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { - entry->hash = 0xffff; - goto out; - } -@@ -504,16 +532,22 @@ static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) - { -+ struct mtk_eth *eth = ppe->eth; -+ u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -- u16 timestamp; - -- timestamp = mtk_eth_timestamp(ppe->eth); -- timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP; -- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; -+ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, -+ timestamp); -+ } else { -+ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -+ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, -+ timestamp); -+ } - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size); -+ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size); - wmb(); - hwe->ib1 = entry->ib1; - -@@ -540,8 +574,8 @@ mtk_foe_entry_commit_l2(struct mtk_ppe * - - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); - const struct mtk_soc_data *soc = ppe->eth->soc; -+ int type = mtk_get_ib1_pkt_type(ppe->eth, entry->data.ib1); - u32 hash; - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) -@@ -564,7 +598,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ - struct mtk_flow_entry *flow_info; - struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; -- u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; -+ u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - - flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end), -@@ -584,16 +618,16 @@ mtk_foe_entry_commit_subflow(struct mtk_ - foe.ib1 &= ib1_mask; - foe.ib1 |= entry->data.ib1 & ~ib1_mask; - -- l2 = mtk_foe_entry_l2(&foe); -+ l2 = mtk_foe_entry_l2(ppe->eth, &foe); - memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); - -- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); - if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) - memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); - else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) - l2->etype = ETH_P_IPV6; - -- *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2; -+ *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; - - __mtk_foe_entry_commit(ppe, &foe, hash); - } -@@ -626,7 +660,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe - continue; - } - -- if (found || !mtk_flow_entry_match(entry, hwe)) { -+ if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { - if (entry->hash != 0xffff) - entry->hash = 0xffff; - continue; -@@ -771,6 +805,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) | - FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, - MTK_PPE_ENTRIES_SHIFT); -+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_PPE_TB_CFG_INFO_SEL; - ppe_w32(ppe, MTK_PPE_TB_CFG, val); - - ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, -@@ -778,15 +814,21 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - - mtk_ppe_cache_enable(ppe, true); - -- val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | -- MTK_PPE_FLOW_CFG_IP4_UDP_FRAG | -- MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | -+ val = MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | - MTK_PPE_FLOW_CFG_IP6_5T_ROUTE | - MTK_PPE_FLOW_CFG_IP6_6RD | - MTK_PPE_FLOW_CFG_IP4_NAT | - MTK_PPE_FLOW_CFG_IP4_NAPT | - MTK_PPE_FLOW_CFG_IP4_DSLITE | - MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; -+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | -+ MTK_PPE_MD_TOAP_BYP_CRSN1 | -+ MTK_PPE_MD_TOAP_BYP_CRSN2 | -+ MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY; -+ else -+ val |= MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | -+ MTK_PPE_FLOW_CFG_IP4_UDP_FRAG; - ppe_w32(ppe, MTK_PPE_FLOW_CFG, val); - - val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) | -@@ -820,6 +862,11 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - ppe_w32(ppe, MTK_PPE_GLO_CFG, val); - - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); -+ -+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { -+ ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); -+ ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); -+ } - } - - int mtk_ppe_stop(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -32,6 +32,15 @@ - #define MTK_FOE_IB1_UDP BIT(30) - #define MTK_FOE_IB1_STATIC BIT(31) - -+/* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_FOE_IB1_BIND_TIMESTAMP_V2 GENMASK(7, 0) -+#define MTK_FOE_IB1_BIND_VLAN_LAYER_V2 GENMASK(16, 14) -+#define MTK_FOE_IB1_BIND_PPPOE_V2 BIT(17) -+#define MTK_FOE_IB1_BIND_VLAN_TAG_V2 BIT(18) -+#define MTK_FOE_IB1_BIND_CACHE_V2 BIT(20) -+#define MTK_FOE_IB1_BIND_TTL_V2 BIT(22) -+#define MTK_FOE_IB1_PACKET_TYPE_V2 GENMASK(27, 23) -+ - enum { - MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0, - MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1, -@@ -53,14 +62,25 @@ enum { - - #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12) - -+#define MTK_FOE_IB2_RX_IDX GENMASK(18, 17) - #define MTK_FOE_IB2_PORT_AG GENMASK(23, 18) - - #define MTK_FOE_IB2_DSCP GENMASK(31, 24) - -+/* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_FOE_IB2_PORT_MG_V2 BIT(7) -+#define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) -+#define MTK_FOE_IB2_MULTICAST_V2 BIT(13) -+#define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) -+#define MTK_FOE_IB2_PORT_AG_V2 GENMASK(23, 20) -+ - #define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0) - #define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6) - #define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14) - -+#define MTK_FOE_WINFO_BSS GENMASK(5, 0) -+#define MTK_FOE_WINFO_WCID GENMASK(15, 6) -+ - enum { - MTK_FOE_STATE_INVALID, - MTK_FOE_STATE_UNBIND, -@@ -81,6 +101,9 @@ struct mtk_foe_mac_info { - - u16 pppoe_id; - u16 src_mac_lo; -+ -+ u16 minfo; -+ u16 winfo; - }; - - /* software-only entry type */ -@@ -198,7 +221,7 @@ struct mtk_foe_entry { - struct mtk_foe_ipv4_dslite dslite; - struct mtk_foe_ipv6 ipv6; - struct mtk_foe_ipv6_6rd ipv6_6rd; -- u32 data[19]; -+ u32 data[23]; - }; - }; - -@@ -306,20 +329,27 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s - __mtk_ppe_check_skb(ppe, skb, hash); - } - --int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, -- u8 pse_port, u8 *src_mac, u8 *dest_mac); --int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); --int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig, -+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int type, int l4proto, u8 pse_port, u8 *src_mac, -+ u8 *dest_mac); -+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, u8 port); -+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, bool orig, - __be32 src_addr, __be16 src_port, - __be32 dest_addr, __be16 dest_port); --int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, -+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, - __be32 *src_addr, __be16 src_port, - __be32 *dest_addr, __be16 dest_port); --int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port); --int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid); --int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); --int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, -- int bss, int wcid); -+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int port); -+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int vid); -+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int sid); -+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int wdma_idx, int txq, int bss, int wcid); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -52,18 +52,19 @@ static const struct rhashtable_params mt - }; - - static int --mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data, -- bool egress) -+mtk_flow_set_ipv4_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, -+ struct mtk_flow_data *data, bool egress) - { -- return mtk_foe_entry_set_ipv4_tuple(foe, egress, -+ return mtk_foe_entry_set_ipv4_tuple(eth, foe, egress, - data->v4.src_addr, data->src_port, - data->v4.dst_addr, data->dst_port); - } - - static int --mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data) -+mtk_flow_set_ipv6_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, -+ struct mtk_flow_data *data) - { -- return mtk_foe_entry_set_ipv6_tuple(foe, -+ return mtk_foe_entry_set_ipv6_tuple(eth, foe, - data->v6.src_addr.s6_addr32, data->src_port, - data->v6.dst_addr.s6_addr32, data->dst_port); - } -@@ -190,16 +191,29 @@ mtk_flow_set_output_device(struct mtk_et - int pse_port, dsa_port; - - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { -- mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss, -- info.wcid); -- pse_port = 3; -+ mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, -+ info.bss, info.wcid); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ switch (info.wdma_idx) { -+ case 0: -+ pse_port = 8; -+ break; -+ case 1: -+ pse_port = 9; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ pse_port = 3; -+ } - *wed_index = info.wdma_idx; - goto out; - } - - dsa_port = mtk_flow_get_dsa_port(&dev); - if (dsa_port >= 0) -- mtk_foe_entry_set_dsa(foe, dsa_port); -+ mtk_foe_entry_set_dsa(eth, foe, dsa_port); - - if (dev == eth->netdev[0]) - pse_port = 1; -@@ -209,7 +223,7 @@ mtk_flow_set_output_device(struct mtk_et - return -EOPNOTSUPP; - - out: -- mtk_foe_entry_set_pse_port(foe, pse_port); -+ mtk_foe_entry_set_pse_port(eth, foe, pse_port); - - return 0; - } -@@ -333,9 +347,8 @@ mtk_flow_offload_replace(struct mtk_eth - !is_valid_ether_addr(data.eth.h_dest)) - return -EINVAL; - -- err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0, -- data.eth.h_source, -- data.eth.h_dest); -+ err = mtk_foe_entry_prepare(eth, &foe, offload_type, l4proto, 0, -+ data.eth.h_source, data.eth.h_dest); - if (err) - return err; - -@@ -360,7 +373,7 @@ mtk_flow_offload_replace(struct mtk_eth - data.v4.src_addr = addrs.key->src; - data.v4.dst_addr = addrs.key->dst; - -- mtk_flow_set_ipv4_addr(&foe, &data, false); -+ mtk_flow_set_ipv4_addr(eth, &foe, &data, false); - } - - if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { -@@ -371,7 +384,7 @@ mtk_flow_offload_replace(struct mtk_eth - data.v6.src_addr = addrs.key->src; - data.v6.dst_addr = addrs.key->dst; - -- mtk_flow_set_ipv6_addr(&foe, &data); -+ mtk_flow_set_ipv6_addr(eth, &foe, &data); - } - - flow_action_for_each(i, act, &rule->action) { -@@ -401,7 +414,7 @@ mtk_flow_offload_replace(struct mtk_eth - } - - if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { -- err = mtk_flow_set_ipv4_addr(&foe, &data, true); -+ err = mtk_flow_set_ipv4_addr(eth, &foe, &data, true); - if (err) - return err; - } -@@ -413,10 +426,10 @@ mtk_flow_offload_replace(struct mtk_eth - if (data.vlan.proto != htons(ETH_P_8021Q)) - return -EOPNOTSUPP; - -- mtk_foe_entry_set_vlan(&foe, data.vlan.id); -+ mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id); - } - if (data.pppoe.num == 1) -- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid); -+ mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid); - - err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest, - &wed_index); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -21,6 +21,9 @@ - #define MTK_PPE_GLO_CFG_BUSY BIT(31) - - #define MTK_PPE_FLOW_CFG 0x204 -+#define MTK_PPE_MD_TOAP_BYP_CRSN0 BIT(1) -+#define MTK_PPE_MD_TOAP_BYP_CRSN1 BIT(2) -+#define MTK_PPE_MD_TOAP_BYP_CRSN2 BIT(3) - #define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG BIT(6) - #define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG BIT(7) - #define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE BIT(8) -@@ -54,6 +57,7 @@ - #define MTK_PPE_TB_CFG_HASH_MODE GENMASK(15, 14) - #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) - #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) -+#define MTK_PPE_TB_CFG_INFO_SEL BIT(20) - - enum { - MTK_PPE_SCAN_MODE_DISABLED, -@@ -112,6 +116,8 @@ enum { - #define MTK_PPE_DEFAULT_CPU_PORT 0x248 - #define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n) (GENMASK(2, 0) << ((_n) * 4)) - -+#define MTK_PPE_DEFAULT_CPU_PORT1 0x24c -+ - #define MTK_PPE_MTU_DROP 0x308 - - #define MTK_PPE_VLAN_MTU0 0x30c -@@ -141,4 +147,6 @@ enum { - #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) - #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) - -+#define MTK_PPE_SBW_CTRL 0x374 -+ - #endif diff --git a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch b/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch new file mode 100644 index 0000000000..70b7bad31f --- /dev/null +++ b/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch @@ -0,0 +1,237 @@ +From 6e1df49f330dce7c58a39d6772f1385b6887bb03 Mon Sep 17 00:00:00 2001 +Message-Id: <6e1df49f330dce7c58a39d6772f1385b6887bb03.1662990860.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +Date: Thu, 8 Sep 2022 11:26:10 +0200 +Subject: [PATCH net-next] net: ethernet: mtk_eth_wed: add axi bus support + +Other than pcie bus, introduce support for axi bus to mtk wed driver. +Axi bus is used to connect mt7986-wmac soc chip available on mt7986 +device. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 116 +++++++++++++------ + drivers/net/ethernet/mediatek/mtk_wed_regs.h | 2 + + include/linux/soc/mediatek/mtk_wed.h | 11 +- + 3 files changed, 91 insertions(+), 38 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -85,11 +85,31 @@ static struct mtk_wed_hw * + mtk_wed_assign(struct mtk_wed_device *dev) + { + struct mtk_wed_hw *hw; ++ int i; ++ ++ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { ++ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; ++ if (!hw) ++ return NULL; ++ ++ if (!hw->wed_dev) ++ goto out; ++ ++ if (hw->version == 1) ++ return NULL; ++ ++ /* MT7986 WED devices do not have any pcie slot restrictions */ ++ } ++ /* MT7986 PCIE or AXI */ ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ hw = hw_list[i]; ++ if (hw && !hw->wed_dev) ++ goto out; ++ } + +- hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; +- if (!hw || hw->wed_dev) +- return NULL; ++ return NULL; + ++out: + hw->wed_dev = dev; + return hw; + } +@@ -322,7 +342,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) + static void + mtk_wed_detach(struct mtk_wed_device *dev) + { +- struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node; + struct mtk_wed_hw *hw = dev->hw; + + mutex_lock(&hw_lock); +@@ -337,9 +356,14 @@ mtk_wed_detach(struct mtk_wed_device *de + mtk_wed_free_buffer(dev); + mtk_wed_free_tx_rings(dev); + +- if (of_dma_is_coherent(wlan_node) && hw->hifsys) +- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, +- BIT(hw->index), BIT(hw->index)); ++ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { ++ struct device_node *wlan_node; ++ ++ wlan_node = dev->wlan.pci_dev->dev.of_node; ++ if (of_dma_is_coherent(wlan_node) && hw->hifsys) ++ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, ++ BIT(hw->index), BIT(hw->index)); ++ } + + if (!hw_list[!hw->index]->wed_dev && + hw->eth->dma_dev != hw->eth->dev) +@@ -356,40 +380,54 @@ mtk_wed_detach(struct mtk_wed_device *de + static void + mtk_wed_bus_init(struct mtk_wed_device *dev) + { +- struct device_node *np = dev->hw->eth->dev->of_node; +- struct regmap *regs; +- u32 val; +- +- regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); +- if (IS_ERR(regs)) +- return; ++ switch (dev->wlan.bus_type) { ++ case MTK_WED_BUS_PCIE: { ++ struct device_node *np = dev->hw->eth->dev->of_node; ++ struct regmap *regs; ++ u32 val; ++ ++ regs = syscon_regmap_lookup_by_phandle(np, ++ "mediatek,wed-pcie"); ++ if (IS_ERR(regs)) ++ break; + +- regmap_update_bits(regs, 0, BIT(0), BIT(0)); ++ regmap_update_bits(regs, 0, BIT(0), BIT(0)); + +- wed_w32(dev, MTK_WED_PCIE_INT_CTRL, +- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); ++ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); + +- /* pcie interrupt control: pola/source selection */ +- wed_set(dev, MTK_WED_PCIE_INT_CTRL, +- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | +- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); +- wed_r32(dev, MTK_WED_PCIE_INT_CTRL); +- +- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); +- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); +- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); +- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); +- +- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); +- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); +- +- /* pcie interrupt status trigger register */ +- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); +- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); +- +- /* pola setting */ +- val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); +- wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); ++ /* pcie interrupt control: pola/source selection */ ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, ++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | ++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); ++ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); ++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); ++ ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); ++ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); ++ ++ /* pcie interrupt status trigger register */ ++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); ++ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); ++ ++ /* pola setting */ ++ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); ++ wed_set(dev, MTK_WED_PCIE_INT_CTRL, ++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); ++ break; ++ } ++ case MTK_WED_BUS_AXI: ++ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, ++ MTK_WED_WPDMA_INT_CTRL_SIG_SRC | ++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0)); ++ break; ++ default: ++ break; ++ } + } + + static void +@@ -800,12 +838,14 @@ mtk_wed_attach(struct mtk_wed_device *de + __releases(RCU) + { + struct mtk_wed_hw *hw; ++ struct device *device; + int ret = 0; + + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "mtk_wed_attach without holding the RCU read lock"); + +- if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 || ++ if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE && ++ pci_domain_nr(dev->wlan.pci_dev->bus) > 1) || + !try_module_get(THIS_MODULE)) + ret = -ENODEV; + +@@ -823,8 +863,10 @@ mtk_wed_attach(struct mtk_wed_device *de + goto out; + } + +- dev_info(&dev->wlan.pci_dev->dev, +- "attaching wed device %d version %d\n", ++ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE ++ ? &dev->wlan.pci_dev->dev ++ : &dev->wlan.platform_dev->dev; ++ dev_info(device, "attaching wed device %d version %d\n", + hw->index, hw->version); + + dev->hw = hw; +--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h +@@ -198,6 +198,8 @@ struct mtk_wdma_desc { + + #define MTK_WED_WPDMA_INT_CTRL 0x520 + #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) ++#define MTK_WED_WPDMA_INT_CTRL_SIG_SRC BIT(22) ++#define MTK_WED_WPDMA_INT_CTRL_SRC_SEL GENMASK(17, 16) + + #define MTK_WED_WPDMA_INT_MASK 0x524 + +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -11,6 +11,11 @@ + struct mtk_wed_hw; + struct mtk_wdma_desc; + ++enum mtk_wed_bus_tye { ++ MTK_WED_BUS_PCIE, ++ MTK_WED_BUS_AXI, ++}; ++ + struct mtk_wed_ring { + struct mtk_wdma_desc *desc; + dma_addr_t desc_phys; +@@ -43,7 +48,11 @@ struct mtk_wed_device { + + /* filled by driver: */ + struct { +- struct pci_dev *pci_dev; ++ union { ++ struct platform_device *platform_dev; ++ struct pci_dev *pci_dev; ++ }; ++ enum mtk_wed_bus_tye bus_type; + + u32 wpdma_phys; + u32 wpdma_int; diff --git a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch deleted file mode 100644 index 037e9d4443..0000000000 --- a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b94b02a270471337bef73c44fa3493a521e31a61 Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Mon, 5 Sep 2022 13:56:13 +0200 -Subject: [PATCH net-next 5/5] net: ethernet: mtk_eth_soc: enable flow - offloading support for mt7986 - -Enable hw packet engine and wireless packet dispatcher for mt7986 - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4256,6 +4256,7 @@ static const struct mtk_soc_data mt7986_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, -+ .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { diff --git a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch b/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch new file mode 100644 index 0000000000..1ecbf485f1 --- /dev/null +++ b/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch @@ -0,0 +1,882 @@ +From 93408c858e5dc01d97c55efa721268f63fde2ae5 Mon Sep 17 00:00:00 2001 +Message-Id: <93408c858e5dc01d97c55efa721268f63fde2ae5.1662886034.git.lorenzo@kernel.org> +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Sat, 3 Sep 2022 18:34:09 +0200 +Subject: [PATCH net-next 4/5] net: ethernet: mtk_eth_soc: introduce flow + offloading support for mt7986 + +Introduce hw flow offload support for mt7986 chipset. PPE is not enabled +yet in mt7986 since mt76 support is not available yet. + +Co-developed-by: Bo Jiao +Signed-off-by: Bo Jiao +Co-developed-by: Sujuan Chen +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 72 ++++++ + drivers/net/ethernet/mediatek/mtk_ppe.c | 213 +++++++++++------- + drivers/net/ethernet/mediatek/mtk_ppe.h | 52 ++++- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 49 ++-- + drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 8 + + 6 files changed, 289 insertions(+), 116 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -1858,12 +1858,14 @@ static int mtk_poll_rx(struct napi_struc + bytes += skb->len; + + if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); + hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; + if (hash != MTK_RXD5_FOE_ENTRY) + skb_set_hash(skb, jhash_1word(hash, 0), + PKT_HASH_TYPE_L4); + rxdcsum = &trxd.rxd3; + } else { ++ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); + hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; + if (hash != MTK_RXD4_FOE_ENTRY) + skb_set_hash(skb, jhash_1word(hash, 0), +@@ -1877,7 +1879,6 @@ static int mtk_poll_rx(struct napi_struc + skb_checksum_none_assert(skb); + skb->protocol = eth_type_trans(skb, netdev); + +- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); + if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) + mtk_ppe_check_skb(eth->ppe[0], skb, hash); + +@@ -4181,7 +4182,7 @@ static const struct mtk_soc_data mt7621_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4201,7 +4202,7 @@ static const struct mtk_soc_data mt7622_ + .required_pctl = false, + .offload_version = 2, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4220,7 +4221,7 @@ static const struct mtk_soc_data mt7623_ + .required_pctl = true, + .offload_version = 2, + .hash_offset = 2, +- .foe_entry_size = sizeof(struct mtk_foe_entry), ++ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +@@ -4252,9 +4253,11 @@ static const struct mtk_soc_data mt7986_ + .reg_map = &mt7986_reg_map, + .ana_rgc3 = 0x128, + .caps = MT7986_CAPS, ++ .hw_features = MTK_HW_FEATURES, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, + .hash_offset = 4, ++ .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -1150,6 +1150,78 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u + return ppe->foe_table + hash * soc->foe_entry_size; + } + ++static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_TIMESTAMP_V2; ++ ++ return MTK_FOE_IB1_BIND_TIMESTAMP; ++} ++ ++static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_PPPOE_V2; ++ ++ return MTK_FOE_IB1_BIND_PPPOE; ++} ++ ++static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_VLAN_TAG_V2; ++ ++ return MTK_FOE_IB1_BIND_VLAN_TAG; ++} ++ ++static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; ++ ++ return MTK_FOE_IB1_BIND_VLAN_LAYER; ++} ++ ++static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); ++ ++ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); ++} ++ ++static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); ++ ++ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); ++} ++ ++static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB1_PACKET_TYPE_V2; ++ ++ return MTK_FOE_IB1_PACKET_TYPE; ++} ++ ++static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); ++ ++ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); ++} ++ ++static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) ++{ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) ++ return MTK_FOE_IB2_MULTICAST_V2; ++ ++ return MTK_FOE_IB2_MULTICAST; ++} ++ + /* read the hardware status register */ + void mtk_stats_update_mac(struct mtk_mac *mac); + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -56,7 +56,7 @@ static u32 ppe_clear(struct mtk_ppe *ppe + + static u32 mtk_eth_timestamp(struct mtk_eth *eth) + { +- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; ++ return mtk_r32(eth, 0x0010) & mtk_get_ib1_ts_mask(eth); + } + + static int mtk_ppe_wait_busy(struct mtk_ppe *ppe) +@@ -93,7 +93,7 @@ static u32 mtk_ppe_hash_entry(struct mtk + u32 hv1, hv2, hv3; + u32 hash; + +- switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) { ++ switch (mtk_get_ib1_pkt_type(eth, e->ib1)) { + case MTK_PPE_PKT_TYPE_IPV4_ROUTE: + case MTK_PPE_PKT_TYPE_IPV4_HNAPT: + hv1 = e->ipv4.orig.ports; +@@ -129,9 +129,9 @@ static u32 mtk_ppe_hash_entry(struct mtk + } + + static inline struct mtk_foe_mac_info * +-mtk_foe_entry_l2(struct mtk_foe_entry *entry) ++mtk_foe_entry_l2(struct mtk_eth *eth, struct mtk_foe_entry *entry) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) + return &entry->bridge.l2; +@@ -143,9 +143,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e + } + + static inline u32 * +-mtk_foe_entry_ib2(struct mtk_foe_entry *entry) ++mtk_foe_entry_ib2(struct mtk_eth *eth, struct mtk_foe_entry *entry) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) + return &entry->bridge.ib2; +@@ -156,27 +156,38 @@ mtk_foe_entry_ib2(struct mtk_foe_entry * + return &entry->ipv4.ib2; + } + +-int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, +- u8 pse_port, u8 *src_mac, u8 *dest_mac) ++int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int type, int l4proto, u8 pse_port, u8 *src_mac, ++ u8 *dest_mac) + { + struct mtk_foe_mac_info *l2; + u32 ports_pad, val; + + memset(entry, 0, sizeof(*entry)); + +- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | +- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | +- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | +- MTK_FOE_IB1_BIND_TTL | +- MTK_FOE_IB1_BIND_CACHE; +- entry->ib1 = val; +- +- val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | +- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) | +- FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | ++ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | ++ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | ++ MTK_FOE_IB1_BIND_CACHE_V2 | MTK_FOE_IB1_BIND_TTL_V2; ++ entry->ib1 = val; ++ ++ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); ++ } else { ++ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | ++ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | ++ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | ++ MTK_FOE_IB1_BIND_CACHE | MTK_FOE_IB1_BIND_TTL; ++ entry->ib1 = val; ++ ++ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | ++ FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); ++ } + + if (is_multicast_ether_addr(dest_mac)) +- val |= MTK_FOE_IB2_MULTICAST; ++ val |= mtk_get_ib2_multicast_mask(eth); + + ports_pad = 0xa5a5a500 | (l4proto & 0xff); + if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE) +@@ -210,24 +221,30 @@ int mtk_foe_entry_prepare(struct mtk_foe + return 0; + } + +-int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port) ++int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, u8 port) + { +- u32 *ib2 = mtk_foe_entry_ib2(entry); +- u32 val; ++ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); ++ u32 val = *ib2; + +- val = *ib2; +- val &= ~MTK_FOE_IB2_DEST_PORT; +- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ val &= ~MTK_FOE_IB2_DEST_PORT_V2; ++ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); ++ } else { ++ val &= ~MTK_FOE_IB2_DEST_PORT; ++ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); ++ } + *ib2 = val; + + return 0; + } + +-int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress, ++int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, bool egress, + __be32 src_addr, __be16 src_port, + __be32 dest_addr, __be16 dest_port) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + struct mtk_ipv4_tuple *t; + + switch (type) { +@@ -262,11 +279,12 @@ int mtk_foe_entry_set_ipv4_tuple(struct + return 0; + } + +-int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, ++int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, + __be32 *src_addr, __be16 src_port, + __be32 *dest_addr, __be16 dest_port) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); ++ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); + u32 *src, *dest; + int i; + +@@ -297,39 +315,41 @@ int mtk_foe_entry_set_ipv6_tuple(struct + return 0; + } + +-int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port) ++int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int port) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + + l2->etype = BIT(port); + +- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER)) +- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); ++ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth))) ++ entry->ib1 |= mtk_prep_ib1_vlan_layer(eth, 1); + else + l2->etype |= BIT(8); + +- entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG; ++ entry->ib1 &= ~mtk_get_ib1_vlan_tag_mask(eth); + + return 0; + } + +-int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid) ++int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int vid) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + +- switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) { ++ switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) { + case 0: +- entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG | +- FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); ++ entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) | ++ mtk_prep_ib1_vlan_layer(eth, 1); + l2->vlan1 = vid; + return 0; + case 1: +- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) { ++ if (!(entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) { + l2->vlan1 = vid; + l2->etype |= BIT(8); + } else { + l2->vlan2 = vid; +- entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); ++ entry->ib1 += mtk_prep_ib1_vlan_layer(eth, 1); + } + return 0; + default: +@@ -337,34 +357,42 @@ int mtk_foe_entry_set_vlan(struct mtk_fo + } + } + +-int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid) ++int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int sid) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); + +- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) || +- (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) ++ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth)) || ++ (entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) + l2->etype = ETH_P_PPP_SES; + +- entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE; ++ entry->ib1 |= mtk_get_ib1_ppoe_mask(eth); + l2->pppoe_id = sid; + + return 0; + } + +-int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, +- int bss, int wcid) ++int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int wdma_idx, int txq, int bss, int wcid) + { +- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); +- u32 *ib2 = mtk_foe_entry_ib2(entry); ++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); ++ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); + +- *ib2 &= ~MTK_FOE_IB2_PORT_MG; +- *ib2 |= MTK_FOE_IB2_WDMA_WINFO; +- if (wdma_idx) +- *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; +- +- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | +- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | +- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; ++ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | ++ MTK_FOE_IB2_WDMA_WINFO_V2; ++ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | ++ FIELD_PREP(MTK_FOE_WINFO_BSS, bss); ++ } else { ++ *ib2 &= ~MTK_FOE_IB2_PORT_MG; ++ *ib2 |= MTK_FOE_IB2_WDMA_WINFO; ++ if (wdma_idx) ++ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; ++ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | ++ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | ++ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); ++ } + + return 0; + } +@@ -376,14 +404,15 @@ static inline bool mtk_foe_entry_usable( + } + + static bool +-mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data) ++mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, ++ struct mtk_foe_entry *data) + { + int type, len; + + if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) + return false; + +- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); ++ type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); + if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) + len = offsetof(struct mtk_foe_entry, ipv6._rsv); + else +@@ -427,14 +456,12 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + + static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) + { +- u16 timestamp; +- u16 now; +- +- now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; +- timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; ++ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); ++ u16 now = mtk_eth_timestamp(ppe->eth); ++ u16 timestamp = ib1 & ib1_ts_mask; + + if (timestamp > now) +- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; ++ return ib1_ts_mask + 1 - timestamp + now; + else + return now - timestamp; + } +@@ -442,6 +469,7 @@ static int __mtk_foe_entry_idle_time(str + static void + mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { ++ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); + struct mtk_flow_entry *cur; + struct mtk_foe_entry *hwe; + struct hlist_node *tmp; +@@ -466,8 +494,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe + continue; + + idle = cur_idle; +- entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; +- entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; ++ entry->data.ib1 &= ~ib1_ts_mask; ++ entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; + } + } + +@@ -489,7 +517,7 @@ mtk_flow_entry_update(struct mtk_ppe *pp + + hwe = mtk_foe_get_entry(ppe, entry->hash); + memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); +- if (!mtk_flow_entry_match(entry, &foe)) { ++ if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { + entry->hash = 0xffff; + goto out; + } +@@ -504,16 +532,22 @@ static void + __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, + u16 hash) + { ++ struct mtk_eth *eth = ppe->eth; ++ u16 timestamp = mtk_eth_timestamp(eth); + struct mtk_foe_entry *hwe; +- u16 timestamp; + +- timestamp = mtk_eth_timestamp(ppe->eth); +- timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP; +- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; +- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; ++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, ++ timestamp); ++ } else { ++ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; ++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, ++ timestamp); ++ } + + hwe = mtk_foe_get_entry(ppe, hash); +- memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size); ++ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size); + wmb(); + hwe->ib1 = entry->ib1; + +@@ -540,8 +574,8 @@ mtk_foe_entry_commit_l2(struct mtk_ppe * + + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) + { +- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); + const struct mtk_soc_data *soc = ppe->eth->soc; ++ int type = mtk_get_ib1_pkt_type(ppe->eth, entry->data.ib1); + u32 hash; + + if (type == MTK_PPE_PKT_TYPE_BRIDGE) +@@ -564,7 +598,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ + struct mtk_flow_entry *flow_info; + struct mtk_foe_entry foe = {}, *hwe; + struct mtk_foe_mac_info *l2; +- u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; ++ u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; + int type; + + flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end), +@@ -584,16 +618,16 @@ mtk_foe_entry_commit_subflow(struct mtk_ + foe.ib1 &= ib1_mask; + foe.ib1 |= entry->data.ib1 & ~ib1_mask; + +- l2 = mtk_foe_entry_l2(&foe); ++ l2 = mtk_foe_entry_l2(ppe->eth, &foe); + memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); + +- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1); ++ type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); + if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) + memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); + else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) + l2->etype = ETH_P_IPV6; + +- *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2; ++ *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; + + __mtk_foe_entry_commit(ppe, &foe, hash); + } +@@ -626,7 +660,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe + continue; + } + +- if (found || !mtk_flow_entry_match(entry, hwe)) { ++ if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { + if (entry->hash != 0xffff) + entry->hash = 0xffff; + continue; +@@ -771,6 +805,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) | + FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, + MTK_PPE_ENTRIES_SHIFT); ++ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ val |= MTK_PPE_TB_CFG_INFO_SEL; + ppe_w32(ppe, MTK_PPE_TB_CFG, val); + + ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, +@@ -778,15 +814,21 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + + mtk_ppe_cache_enable(ppe, true); + +- val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | +- MTK_PPE_FLOW_CFG_IP4_UDP_FRAG | +- MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | ++ val = MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | + MTK_PPE_FLOW_CFG_IP6_5T_ROUTE | + MTK_PPE_FLOW_CFG_IP6_6RD | + MTK_PPE_FLOW_CFG_IP4_NAT | + MTK_PPE_FLOW_CFG_IP4_NAPT | + MTK_PPE_FLOW_CFG_IP4_DSLITE | + MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; ++ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) ++ val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | ++ MTK_PPE_MD_TOAP_BYP_CRSN1 | ++ MTK_PPE_MD_TOAP_BYP_CRSN2 | ++ MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY; ++ else ++ val |= MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | ++ MTK_PPE_FLOW_CFG_IP4_UDP_FRAG; + ppe_w32(ppe, MTK_PPE_FLOW_CFG, val); + + val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) | +@@ -820,6 +862,11 @@ void mtk_ppe_start(struct mtk_ppe *ppe) + ppe_w32(ppe, MTK_PPE_GLO_CFG, val); + + ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); ++ ++ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { ++ ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); ++ ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); ++ } + } + + int mtk_ppe_stop(struct mtk_ppe *ppe) +--- a/drivers/net/ethernet/mediatek/mtk_ppe.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h +@@ -32,6 +32,15 @@ + #define MTK_FOE_IB1_UDP BIT(30) + #define MTK_FOE_IB1_STATIC BIT(31) + ++/* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_FOE_IB1_BIND_TIMESTAMP_V2 GENMASK(7, 0) ++#define MTK_FOE_IB1_BIND_VLAN_LAYER_V2 GENMASK(16, 14) ++#define MTK_FOE_IB1_BIND_PPPOE_V2 BIT(17) ++#define MTK_FOE_IB1_BIND_VLAN_TAG_V2 BIT(18) ++#define MTK_FOE_IB1_BIND_CACHE_V2 BIT(20) ++#define MTK_FOE_IB1_BIND_TTL_V2 BIT(22) ++#define MTK_FOE_IB1_PACKET_TYPE_V2 GENMASK(27, 23) ++ + enum { + MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0, + MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1, +@@ -53,14 +62,25 @@ enum { + + #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12) + ++#define MTK_FOE_IB2_RX_IDX GENMASK(18, 17) + #define MTK_FOE_IB2_PORT_AG GENMASK(23, 18) + + #define MTK_FOE_IB2_DSCP GENMASK(31, 24) + ++/* CONFIG_MEDIATEK_NETSYS_V2 */ ++#define MTK_FOE_IB2_PORT_MG_V2 BIT(7) ++#define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) ++#define MTK_FOE_IB2_MULTICAST_V2 BIT(13) ++#define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) ++#define MTK_FOE_IB2_PORT_AG_V2 GENMASK(23, 20) ++ + #define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0) + #define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6) + #define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14) + ++#define MTK_FOE_WINFO_BSS GENMASK(5, 0) ++#define MTK_FOE_WINFO_WCID GENMASK(15, 6) ++ + enum { + MTK_FOE_STATE_INVALID, + MTK_FOE_STATE_UNBIND, +@@ -81,6 +101,9 @@ struct mtk_foe_mac_info { + + u16 pppoe_id; + u16 src_mac_lo; ++ ++ u16 minfo; ++ u16 winfo; + }; + + /* software-only entry type */ +@@ -198,7 +221,7 @@ struct mtk_foe_entry { + struct mtk_foe_ipv4_dslite dslite; + struct mtk_foe_ipv6 ipv6; + struct mtk_foe_ipv6_6rd ipv6_6rd; +- u32 data[19]; ++ u32 data[23]; + }; + }; + +@@ -306,20 +329,27 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s + __mtk_ppe_check_skb(ppe, skb, hash); + } + +-int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, +- u8 pse_port, u8 *src_mac, u8 *dest_mac); +-int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); +-int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig, ++int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int type, int l4proto, u8 pse_port, u8 *src_mac, ++ u8 *dest_mac); ++int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, u8 port); ++int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, bool orig, + __be32 src_addr, __be16 src_port, + __be32 dest_addr, __be16 dest_port); +-int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, ++int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, ++ struct mtk_foe_entry *entry, + __be32 *src_addr, __be16 src_port, + __be32 *dest_addr, __be16 dest_port); +-int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port); +-int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid); +-int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); +-int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, +- int bss, int wcid); ++int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int port); ++int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int vid); ++int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int sid); ++int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, ++ int wdma_idx, int txq, int bss, int wcid); + int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); + int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -52,18 +52,19 @@ static const struct rhashtable_params mt + }; + + static int +-mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data, +- bool egress) ++mtk_flow_set_ipv4_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, ++ struct mtk_flow_data *data, bool egress) + { +- return mtk_foe_entry_set_ipv4_tuple(foe, egress, ++ return mtk_foe_entry_set_ipv4_tuple(eth, foe, egress, + data->v4.src_addr, data->src_port, + data->v4.dst_addr, data->dst_port); + } + + static int +-mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data) ++mtk_flow_set_ipv6_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, ++ struct mtk_flow_data *data) + { +- return mtk_foe_entry_set_ipv6_tuple(foe, ++ return mtk_foe_entry_set_ipv6_tuple(eth, foe, + data->v6.src_addr.s6_addr32, data->src_port, + data->v6.dst_addr.s6_addr32, data->dst_port); + } +@@ -190,16 +191,29 @@ mtk_flow_set_output_device(struct mtk_et + int pse_port, dsa_port; + + if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { +- mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss, +- info.wcid); +- pse_port = 3; ++ mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, ++ info.bss, info.wcid); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ++ switch (info.wdma_idx) { ++ case 0: ++ pse_port = 8; ++ break; ++ case 1: ++ pse_port = 9; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } else { ++ pse_port = 3; ++ } + *wed_index = info.wdma_idx; + goto out; + } + + dsa_port = mtk_flow_get_dsa_port(&dev); + if (dsa_port >= 0) +- mtk_foe_entry_set_dsa(foe, dsa_port); ++ mtk_foe_entry_set_dsa(eth, foe, dsa_port); + + if (dev == eth->netdev[0]) + pse_port = 1; +@@ -209,7 +223,7 @@ mtk_flow_set_output_device(struct mtk_et + return -EOPNOTSUPP; + + out: +- mtk_foe_entry_set_pse_port(foe, pse_port); ++ mtk_foe_entry_set_pse_port(eth, foe, pse_port); + + return 0; + } +@@ -333,9 +347,8 @@ mtk_flow_offload_replace(struct mtk_eth + !is_valid_ether_addr(data.eth.h_dest)) + return -EINVAL; + +- err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0, +- data.eth.h_source, +- data.eth.h_dest); ++ err = mtk_foe_entry_prepare(eth, &foe, offload_type, l4proto, 0, ++ data.eth.h_source, data.eth.h_dest); + if (err) + return err; + +@@ -360,7 +373,7 @@ mtk_flow_offload_replace(struct mtk_eth + data.v4.src_addr = addrs.key->src; + data.v4.dst_addr = addrs.key->dst; + +- mtk_flow_set_ipv4_addr(&foe, &data, false); ++ mtk_flow_set_ipv4_addr(eth, &foe, &data, false); + } + + if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { +@@ -371,7 +384,7 @@ mtk_flow_offload_replace(struct mtk_eth + data.v6.src_addr = addrs.key->src; + data.v6.dst_addr = addrs.key->dst; + +- mtk_flow_set_ipv6_addr(&foe, &data); ++ mtk_flow_set_ipv6_addr(eth, &foe, &data); + } + + flow_action_for_each(i, act, &rule->action) { +@@ -401,7 +414,7 @@ mtk_flow_offload_replace(struct mtk_eth + } + + if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { +- err = mtk_flow_set_ipv4_addr(&foe, &data, true); ++ err = mtk_flow_set_ipv4_addr(eth, &foe, &data, true); + if (err) + return err; + } +@@ -413,10 +426,10 @@ mtk_flow_offload_replace(struct mtk_eth + if (data.vlan.proto != htons(ETH_P_8021Q)) + return -EOPNOTSUPP; + +- mtk_foe_entry_set_vlan(&foe, data.vlan.id); ++ mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id); + } + if (data.pppoe.num == 1) +- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid); ++ mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid); + + err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest, + &wed_index); +--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h +@@ -21,6 +21,9 @@ + #define MTK_PPE_GLO_CFG_BUSY BIT(31) + + #define MTK_PPE_FLOW_CFG 0x204 ++#define MTK_PPE_MD_TOAP_BYP_CRSN0 BIT(1) ++#define MTK_PPE_MD_TOAP_BYP_CRSN1 BIT(2) ++#define MTK_PPE_MD_TOAP_BYP_CRSN2 BIT(3) + #define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG BIT(6) + #define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG BIT(7) + #define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE BIT(8) +@@ -54,6 +57,7 @@ + #define MTK_PPE_TB_CFG_HASH_MODE GENMASK(15, 14) + #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) + #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) ++#define MTK_PPE_TB_CFG_INFO_SEL BIT(20) + + enum { + MTK_PPE_SCAN_MODE_DISABLED, +@@ -112,6 +116,8 @@ enum { + #define MTK_PPE_DEFAULT_CPU_PORT 0x248 + #define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n) (GENMASK(2, 0) << ((_n) * 4)) + ++#define MTK_PPE_DEFAULT_CPU_PORT1 0x24c ++ + #define MTK_PPE_MTU_DROP 0x308 + + #define MTK_PPE_VLAN_MTU0 0x30c +@@ -141,4 +147,6 @@ enum { + #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) + #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) + ++#define MTK_PPE_SBW_CTRL 0x374 ++ + #endif diff --git a/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch new file mode 100644 index 0000000000..037e9d4443 --- /dev/null +++ b/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch @@ -0,0 +1,26 @@ +From b94b02a270471337bef73c44fa3493a521e31a61 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Lorenzo Bianconi +Date: Mon, 5 Sep 2022 13:56:13 +0200 +Subject: [PATCH net-next 5/5] net: ethernet: mtk_eth_soc: enable flow + offloading support for mt7986 + +Enable hw packet engine and wireless packet dispatcher for mt7986 + +Signed-off-by: Lorenzo Bianconi +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -4256,6 +4256,7 @@ static const struct mtk_soc_data mt7986_ + .hw_features = MTK_HW_FEATURES, + .required_clks = MT7986_CLKS_BITMAP, + .required_pctl = false, ++ .offload_version = 2, + .hash_offset = 4, + .foe_entry_size = sizeof(struct mtk_foe_entry), + .txrx = { diff --git a/target/linux/generic/pending-5.15/782-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch b/target/linux/generic/pending-5.15/782-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch new file mode 100644 index 0000000000..cc71ec60f3 --- /dev/null +++ b/target/linux/generic/pending-5.15/782-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch @@ -0,0 +1,51 @@ +From cd8e1f340c3e571b78952d4ca2c128d183a47cc2 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 28 Sep 2022 02:17:02 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix state in + __mtk_foe_entry_clear +To: linux-mediatek@lists.infradead.org, + netdev@vger.kernel.org, + Lorenzo Bianconi +Cc: Sujuan Chen , + Bo Jiao , + Felix Fietkau , + John Crispin , + Sean Wang , + Mark Lee , + David S. Miller , + Eric Dumazet , + Jakub Kicinski , + Paolo Abeni , + Matthias Brugger , + Chen Minqiang , + Thomas Hühn + +Setting ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear +routine as done by commit 0e80707d94e4c8 ("net: ethernet: mtk_eth_soc: +fix typo in __mtk_foe_entry_clear") breaks flow offloading, at least +on older MTK_NETSYS_V1 SoCs, OpenWrt users have confirmed the bug on +MT7622 and MT7621 systems. +Felix Fietkau suggested to use MTK_FOE_STATE_INVALID instead which +works well on both, MTK_NETSYS_V1 and MTK_NETSYS_V2. + +Tested on MT7622 (Linksys E8450) and MT7986 (BananaPi BPI-R3). + +Suggested-by: Felix Fietkau +Fixes: 0e80707d94e4c8 ("net: ethernet: mtk_eth_soc: fix typo in __mtk_foe_entry_clear") +Fixes: 33fc42de33278 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries") +Signed-off-by: Daniel Golle +--- + drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_ppe.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c +@@ -442,7 +442,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp + struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); + + hwe->ib1 &= ~MTK_FOE_IB1_STATE; +- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND); ++ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); + dma_wmb(); + } + entry->hash = 0xffff;