[][MAC80211][WED][Refactor and sync wed patches from upstream]
[Description]
Refactor and sync wed patches from upstream
[Release-log]
Change-Id: I4e3dc38a67c3ec099ba59257442900ba92cc4198
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8706171
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3019-mtk-wed-add-wed3-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3019-mtk-wed-add-wed3-support.patch
deleted file mode 100644
index b90693d..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3019-mtk-wed-add-wed3-support.patch
+++ /dev/null
@@ -1,3755 +0,0 @@
-From 542064ad977706558be071e0f7d706f5aa37f390 Mon Sep 17 00:00:00 2001
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Mon, 18 Sep 2023 13:21:15 +0800
-Subject: [PATCH 1/5] mtk:wed:add wed3 support
-
----
- arch/arm64/boot/dts/mediatek/mt7988.dtsi | 152 ++-
- .../dts/mediatek/mt7988a-dsa-10g-spim-nor.dts | 16 +-
- .../dts/mediatek/mt7988d-dsa-10g-spim-nor.dts | 16 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +-
- drivers/net/ethernet/mediatek/mtk_ppe.c | 17 +-
- drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +-
- .../net/ethernet/mediatek/mtk_ppe_offload.c | 16 +-
- drivers/net/ethernet/mediatek/mtk_wed.c | 1178 +++++++++++++----
- drivers/net/ethernet/mediatek/mtk_wed.h | 25 +-
- .../net/ethernet/mediatek/mtk_wed_debugfs.c | 584 +++++++-
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 14 +-
- drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 5 +-
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 338 ++++-
- include/linux/netdevice.h | 7 +
- include/linux/soc/mediatek/mtk_wed.h | 83 +-
- 16 files changed, 2070 insertions(+), 391 deletions(-)
- mode change 100755 => 100644 drivers/net/ethernet/mediatek/mtk_ppe.c
-
-diff --git a/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
-index 7e96640..3368240 100644
---- a/arch/arm64/boot/dts/mediatek/mt7988.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
-@@ -193,44 +193,49 @@
- status = "disabled";
- };
-
-- wed: wed@15010000 {
-- compatible = "mediatek,wed";
-- wed_num = <3>;
-- /* add this property for wed get the pci slot number. */
-- pci_slot_map = <0>, <1>, <2>;
-- reg = <0 0x15010000 0 0x2000>,
-- <0 0x15012000 0 0x2000>,
-- <0 0x15014000 0 0x2000>;
-+ wed0: wed@15010000 {
-+ compatible = "mediatek,mt7988-wed",
-+ "syscon";
-+ reg = <0 0x15010000 0 0x2000>;
- interrupt-parent = <&gic>;
-- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
-- };
--
-- wed2: wed2@15012000 {
-- compatible = "mediatek,wed2";
-- wed_num = <3>;
-- /* add this property for wed get the pci slot number. */
-- reg = <0 0x15010000 0 0x2000>,
-- <0 0x15012000 0 0x2000>,
-- <0 0x15014000 0 0x2000>;
-+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
-+ mediatek,wed_pcie = <&wed_pcie>;
-+ mediatek,ap2woccif = <&ap2woccif0>;
-+ mediatek,wocpu_ilm = <&wocpu0_ilm>;
-+ mediatek,wocpu_dlm = <&wocpu0_dlm>;
-+ mediatek,wocpu_boot = <&cpu0_boot>;
-+ mediatek,wocpu_emi = <&wocpu0_emi>;
-+ mediatek,wocpu_data = <&wocpu_data>;
-+ };
-+
-+ wed1: wed@15012000 {
-+ compatible = "mediatek,mt7988-wed",
-+ "syscon";
-+ reg = <0 0x15012000 0 0x2000>;
- interrupt-parent = <&gic>;
-- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
-- };
--
-- wed3: wed3@15014000 {
-- compatible = "mediatek,wed3";
-- wed_num = <3>;
-- /* add this property for wed get the pci slot number. */
-- reg = <0 0x15010000 0 0x2000>,
-- <0 0x15012000 0 0x2000>,
-- <0 0x15014000 0 0x2000>;
-+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
-+ mediatek,wed_pcie = <&wed_pcie>;
-+ mediatek,ap2woccif = <&ap2woccif1>;
-+ mediatek,wocpu_ilm = <&wocpu1_ilm>;
-+ mediatek,wocpu_dlm = <&wocpu1_dlm>;
-+ mediatek,wocpu_boot = <&cpu1_boot>;
-+ mediatek,wocpu_emi = <&wocpu1_emi>;
-+ mediatek,wocpu_data = <&wocpu_data>;
-+ };
-+
-+ wed2: wed@15014000 {
-+ compatible = "mediatek,mt7988-wed",
-+ "syscon";
-+ reg = <0 0x15014000 0 0x2000>;
- interrupt-parent = <&gic>;
-- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
-+ mediatek,wed_pcie = <&wed_pcie>;
-+ mediatek,ap2woccif = <&ap2woccif2>;
-+ mediatek,wocpu_ilm = <&wocpu2_ilm>;
-+ mediatek,wocpu_dlm = <&wocpu2_dlm>;
-+ mediatek,wocpu_boot = <&cpu2_boot>;
-+ mediatek,wocpu_emi = <&wocpu2_emi>;
-+ mediatek,wocpu_data = <&wocpu_data>;
- };
-
- wdma: wdma@15104800 {
-@@ -240,15 +245,25 @@
- <0 0x15105000 0 0x400>;
- };
-
-- ap2woccif: ap2woccif@151A5000 {
-- compatible = "mediatek,ap2woccif";
-- reg = <0 0x151A5000 0 0x1000>,
-- <0 0x152A5000 0 0x1000>,
-- <0 0x153A5000 0 0x1000>;
-+ ap2woccif0: ap2woccif@151A5000 {
-+ compatible = "mediatek,ap2woccif", "syscon";
-+ reg = <0 0x151A5000 0 0x1000>;
-+ interrupt-parent = <&gic>;
-+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ ap2woccif1: ap2woccif@152A5000 {
-+ compatible = "mediatek,ap2woccif", "syscon";
-+ reg = <0 0x152A5000 0 0x1000>;
- interrupt-parent = <&gic>;
-- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ ap2woccif2: ap2woccif@153A5000 {
-+ compatible = "mediatek,ap2woccif", "syscon";
-+ reg = <0 0x153A5000 0 0x1000>;
-+ interrupt-parent = <&gic>;
-+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- wocpu0_ilm: wocpu0_ilm@151E0000 {
-@@ -256,31 +271,53 @@
- reg = <0 0x151E0000 0 0x8000>;
- };
-
-- wocpu1_ilm: wocpu1_ilm@152E0000 {
-- compatible = "mediatek,wocpu1_ilm";
-+ wocpu1_ilm: wocpu_ilm@152E0000 {
-+ compatible = "mediatek,wocpu_ilm";
- reg = <0 0x152E0000 0 0x8000>;
- };
-
-- wocpu2_ilm: wocpu2_ilm@153E0000 {
-- compatible = "mediatek,wocpu2_ilm";
-- reg = <0 0x153E0000 0 0x8000>;
-+ wocpu2_ilm: wocpu_ilm@153E0000 {
-+ compatible = "mediatek,wocpu_ilm";
-+ reg = <0 0x153E0000 0 0x8000>;
-+ };
-+
-+ wocpu0_dlm: wocpu_dlm@151E8000 {
-+ compatible = "mediatek,wocpu_dlm";
-+ reg = <0 0x151E8000 0 0x2000>;
-+
-+ resets = <ðsysrst 0>;
-+ reset-names = "wocpu_rst";
-+ };
-+
-+ wocpu1_dlm: wocpu_dlm@0x152E8000 {
-+ compatible = "mediatek,wocpu_dlm";
-+ reg = <0 0x152E8000 0 0x2000>;
-+
-+ resets = <ðsysrst 0>;
-+ reset-names = "wocpu_rst";
- };
-
-- wocpu_dlm: wocpu_dlm@151E8000 {
-+ wocpu2_dlm: wocpu_dlm@0x153E8000 {
- compatible = "mediatek,wocpu_dlm";
-- reg = <0 0x151E8000 0 0x2000>,
-- <0 0x152E8000 0 0x2000>,
-- <0 0x153E8000 0 0x2000>;
-+ reg = <0 0x153E8000 0 0x2000>;
-
- resets = <ðsysrst 0>;
- reset-names = "wocpu_rst";
- };
-
-- cpu_boot: wocpu_boot@15194000 {
-- compatible = "mediatek,wocpu_boot";
-- reg = <0 0x15194000 0 0x1000>,
-- <0 0x15294000 0 0x1000>,
-- <0 0x15394000 0 0x1000>;
-+ cpu0_boot: wocpu_boot@15194000 {
-+ compatible = "mediatek,wocpu0_boot";
-+ reg = <0 0x15194000 0 0x1000>;
-+ };
-+
-+ cpu1_boot: wocpu_boot@15294000 {
-+ compatible = "mediatek,wocpu1_boot";
-+ reg = <0 0x15294000 0 0x1000>;
-+ };
-+
-+ cpu2_boot: wocpu_boot@15394000 {
-+ compatible = "mediatek,wocpu2_boot";
-+ reg = <0 0x15394000 0 0x1000>;
- };
-
- reserved-memory {
-@@ -901,6 +938,7 @@
- <&topckgen CK_TOP_CB_NET2_D2>;
- mediatek,ethsys = <ðsys>;
- mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
-+ mediatek,wed = <&wed0>, <&wed1>, <&wed2>;
- mediatek,usxgmiisys = <&usxgmiisys0>, <&usxgmiisys1>;
- mediatek,xfi_pextp = <&xfi_pextp0>, <&xfi_pextp1>;
- mediatek,xfi_pll = <&xfi_pll>;
-diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
-index 578a489..596f0ca 100644
---- a/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
-@@ -369,9 +369,23 @@
- status = "okay";
- };
-
--&wed {
-+&wed0 {
- dy_txbm_enable = "true";
- dy_txbm_budge = <8>;
- txbm_init_sz = <10>;
- status = "okay";
- };
-+
-+&wed1 {
-+ dy_txbm_enable = "true";
-+ dy_txbm_budge = <8>;
-+ txbm_init_sz = <10>;
-+ status = "okay";
-+};
-+
-+&wed2 {
-+ dy_txbm_enable = "true";
-+ dy_txbm_budge = <8>;
-+ txbm_init_sz = <10>;
-+ status = "okay";
-+};
-\ No newline at end of file
-diff --git a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
-index e743718..f430118 100644
---- a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
-@@ -381,9 +381,23 @@
- status = "okay";
- };
-
--&wed {
-+&wed0 {
- dy_txbm_enable = "true";
- dy_txbm_budge = <8>;
- txbm_init_sz = <10>;
- status = "okay";
- };
-+
-+&wed1 {
-+ dy_txbm_enable = "true";
-+ dy_txbm_budge = <8>;
-+ txbm_init_sz = <10>;
-+ status = "okay";
-+};
-+
-+&wed2 {
-+ dy_txbm_enable = "true";
-+ dy_txbm_budge = <8>;
-+ txbm_init_sz = <10>;
-+ status = "okay";
-+};
-\ No newline at end of file
-diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index c75ce25..ec78adf 100644
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5216,7 +5216,8 @@ static int mtk_probe(struct platform_device *pdev)
- "mediatek,wed", i);
- static const u32 wdma_regs[] = {
- MTK_WDMA0_BASE,
-- MTK_WDMA1_BASE
-+ MTK_WDMA1_BASE,
-+ MTK_WDMA2_BASE
- };
- void __iomem *wdma;
- u32 wdma_phy;
-diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 1074f46..a788d43 100644
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -623,9 +623,12 @@
- #define RX_DMA_SPORT_MASK 0x7
- #define RX_DMA_SPORT_MASK_V2 0xf
-
--#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
- #define MTK_WDMA0_BASE 0x4800
- #define MTK_WDMA1_BASE 0x4c00
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+#define MTK_WDMA2_BASE 0x5000
-+#endif
- #else
- #define MTK_WDMA0_BASE 0x2800
- #define MTK_WDMA1_BASE 0x2c00
-diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-old mode 100755
-new mode 100644
-index 0e9c0bd..ae0acd5
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -9,6 +9,7 @@
- #include <linux/if_ether.h>
- #include <linux/if_vlan.h>
- #include <net/dsa.h>
-+#include <net/route.h>
- #include "mtk_eth_soc.h"
- #include "mtk_ppe.h"
- #include "mtk_ppe_regs.h"
-@@ -407,7 +408,7 @@ 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 bss, int wcid, bool amsdu_en)
- {
- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
- u32 *ib2 = mtk_foe_entry_ib2(entry);
-@@ -419,6 +420,9 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
-
- l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
- FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+ l2->winfo_pao = FIELD_PREP(MTK_FOE_WINFO_PAO_AMSDU_EN, amsdu_en);
-+#endif
- #else
- if (wdma_idx)
- *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX;
-@@ -454,6 +458,17 @@ int mtk_foe_entry_set_dscp(struct mtk_foe_entry *entry, int dscp)
- *ib2 &= ~MTK_FOE_IB2_DSCP;
- *ib2 |= FIELD_PREP(MTK_FOE_IB2_DSCP, dscp);
-
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
-+
-+ if (*ib2 & MTK_FOE_IB2_WDMA_WINFO &&
-+ l2->winfo_pao & MTK_FOE_WINFO_PAO_AMSDU_EN) {
-+ u8 tid = (dscp >> 5) & 0xf;
-+
-+ l2->winfo_pao |= FIELD_PREP(MTK_FOE_WINFO_PAO_TID, tid);
-+ }
-+#endif
-+
- return 0;
- }
-
-diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
-index 2a8b6ef..66c7f10 100644
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -428,7 +428,7 @@ 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 bss, int wcid, bool amsdu_en);
- int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid);
- int mtk_foe_entry_set_dscp(struct mtk_foe_entry *entry, int dscp);
- bool mtk_foe_entry_match(struct mtk_foe_entry *entry, struct mtk_foe_entry *data);
-diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-index 95174b7..339359e 100644
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -112,6 +112,7 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
- info->queue = path.mtk_wdma.queue;
- info->bss = path.mtk_wdma.bss;
- info->wcid = path.mtk_wdma.wcid;
-+ info->amsdu_en = path.mtk_wdma.amsdu_en;
-
- return 0;
- }
-@@ -193,13 +194,15 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
-
- 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);
-+ info.wcid, info.amsdu_en);
- pse_port = PSE_PPE0_PORT;
- #if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
- if (info.wdma_idx == 0)
- pse_port = PSE_WDMA0_PORT;
- else if (info.wdma_idx == 1)
- pse_port = PSE_WDMA1_PORT;
-+ else if (info.wdma_idx == 2)
-+ pse_port = PSE_WDMA2_PORT;
- else
- return -EOPNOTSUPP;
- #endif
-@@ -481,8 +484,6 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
- if (data.pppoe.num == 1)
- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
-
-- mtk_foe_entry_set_dscp(&foe, dscp);
--
- mtk_foe_entry_set_sp(eth->ppe[ppe_index], &foe);
-
- err = mtk_flow_set_output_device(eth, &foe, odev, f->flow->ct, data.eth.h_dest,
-@@ -490,8 +491,9 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
- if (err)
- return err;
-
-- if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
-- return err;
-+ mtk_foe_entry_set_dscp(&foe, dscp);
-+ /*if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
-+ return err;*/
-
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
-@@ -516,8 +518,8 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
- mtk_foe_entry_clear(eth->ppe[ppe_index], entry);
- free:
- kfree(entry);
-- if (wed_index >= 0)
-- mtk_wed_flow_remove(wed_index);
-+ /*if (wed_index >= 0)
-+ mtk_wed_flow_remove(wed_index);*/
- return err;
- }
-
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 48c35ae..561fc6c 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -28,7 +28,7 @@ struct wo_cmd_ring {
- u32 cnt;
- u32 unit;
- };
--static struct mtk_wed_hw *hw_list[2];
-+static struct mtk_wed_hw *hw_list[3];
- static DEFINE_MUTEX(hw_lock);
-
- static void
-@@ -73,6 +73,26 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)
- return wdma_r32(dev, MTK_WDMA_GLO_CFG);
- }
-
-+static u32
-+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ if (wed_r32(dev, reg) & mask)
-+ return true;
-+
-+ return false;
-+}
-+
-+static int
-+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
-+{
-+ int sleep = 1000;
-+ int timeout = 100 * sleep;
-+ u32 val;
-+
-+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-+ timeout, false, dev, reg, mask);
-+}
-+
- static int
- mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- {
-@@ -235,6 +255,8 @@ mtk_wed_assign(struct mtk_wed_device *dev)
- continue;
-
- hw->wed_dev = dev;
-+ hw->pci_base = MTK_WED_PCIE_BASE;
-+
- return hw;
- }
-
-@@ -242,23 +264,84 @@ mtk_wed_assign(struct mtk_wed_device *dev)
- }
-
- static int
--mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
-+mtk_wed_pao_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_pao *pao;
-+ int i, j;
-+
-+ pao = kzalloc(sizeof(struct mtk_wed_pao), GFP_KERNEL);
-+ if (!pao)
-+ return -ENOMEM;
-+
-+ dev->hw->wed_pao = pao;
-+
-+ for (i = 0; i < 32; i++) {
-+ /* each segment is 64K*/
-+ pao->hif_txd[i] = (char *)__get_free_pages(GFP_ATOMIC |
-+ GFP_DMA32 |
-+ __GFP_ZERO, 4);
-+ if (!pao->hif_txd[i])
-+ goto err;
-+
-+ pao->hif_txd_phys[i] = dma_map_single(dev->hw->dev,
-+ pao->hif_txd[i],
-+ 16 * PAGE_SIZE,
-+ DMA_TO_DEVICE);
-+ if (unlikely(dma_mapping_error(dev->hw->dev,
-+ pao->hif_txd_phys[i])))
-+ goto err;
-+ }
-+
-+ return 0;
-+
-+err:
-+ for (j = 0; j < i; j++)
-+ dma_unmap_single(dev->hw->dev, pao->hif_txd_phys[j],
-+ 16 * PAGE_SIZE, DMA_TO_DEVICE);
-+
-+ return -ENOMEM;
-+}
-+
-+static int
-+mtk_wed_pao_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_pao *pao = dev->hw->wed_pao;
-+ int i;
-+
-+ for (i = 0; i < 32; i++) {
-+ dma_unmap_single(dev->hw->dev, pao->hif_txd_phys[i],
-+ 16 * PAGE_SIZE, DMA_TO_DEVICE);
-+ free_pages((unsigned long)pao->hif_txd[i], 4);
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
- {
- struct mtk_wdma_desc *desc;
-+ void *desc_ptr;
- dma_addr_t desc_phys;
-- void **page_list;
-+ struct dma_page_info *page_list;
- u32 last_seg = MTK_WDMA_DESC_CTRL_LAST_SEG1;
- int token = dev->wlan.token_start;
-- int ring_size, n_pages, page_idx;
-- int i;
--
-+ int ring_size, pkt_nums, n_pages, page_idx;
-+ int i, ret = 0;
-
- if (dev->ver == MTK_WED_V1) {
- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-- } else {
-+ pkt_nums = ring_size;
-+ dev->tx_buf_ring.desc_size = sizeof(struct mtk_wdma_desc);
-+ } else if (dev->hw->version == 2) {
- ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
- MTK_WED_WDMA_RING_SIZE * 2;
- last_seg = MTK_WDMA_DESC_CTRL_LAST_SEG0;
-+ dev->tx_buf_ring.desc_size = sizeof(struct mtk_wdma_desc);
-+ } else if (dev->hw->version == 3) {
-+ ring_size = MTK_WED_TX_BM_DMA_SIZE;
-+ pkt_nums = MTK_WED_TX_BM_PKT_CNT;
-+ dev->tx_buf_ring.desc_size = sizeof(struct mtk_rxbm_desc);
- }
-
- n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
-@@ -267,18 +350,20 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- if (!page_list)
- return -ENOMEM;
-
-- dev->buf_ring.size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-- dev->buf_ring.pages = page_list;
-+ dev->tx_buf_ring.size = ring_size;
-+ dev->tx_buf_ring.pages = page_list;
-+ dev->tx_buf_ring.pkt_nums = pkt_nums;
-
-- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-- &desc_phys, GFP_KERNEL);
-- if (!desc)
-+ desc_ptr = dma_alloc_coherent(dev->hw->dev,
-+ ring_size * dev->tx_buf_ring.desc_size,
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc_ptr)
- return -ENOMEM;
-
-- dev->buf_ring.desc = desc;
-- dev->buf_ring.desc_phys = desc_phys;
-+ dev->tx_buf_ring.desc = desc_ptr;
-+ dev->tx_buf_ring.desc_phys = desc_phys;
-
-- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
-+ for (i = 0, page_idx = 0; i < pkt_nums; i += MTK_WED_BUF_PER_PAGE) {
- dma_addr_t page_phys, buf_phys;
- struct page *page;
- void *buf;
-@@ -295,7 +380,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- return -ENOMEM;
- }
-
-- page_list[page_idx++] = page;
-+ page_list[page_idx].addr = page;
-+ page_list[page_idx].addr_phys = page_phys;
-+ page_idx++;
-+
- dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
-
-@@ -303,19 +391,23 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- buf_phys = page_phys;
-
- for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
-- u32 txd_size;
--
-- txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
--
-+ desc = desc_ptr;
- desc->buf0 = buf_phys;
-- desc->buf1 = buf_phys + txd_size;
-- desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0,
-- txd_size) |
-- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-- MTK_WED_BUF_SIZE - txd_size) |
-- last_seg;
-- desc->info = 0;
-- desc++;
-+ if (dev->hw->version < 3) {
-+ u32 txd_size;
-+
-+ txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
-+ desc->buf1 = buf_phys + txd_size;
-+ desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0,
-+ txd_size) |
-+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
-+ MTK_WED_BUF_SIZE - txd_size) |
-+ last_seg;
-+ desc->info = 0;
-+ } else {
-+ desc->ctrl = token << 16;
-+ }
-+ desc_ptr += dev->tx_buf_ring.desc_size;
-
- buf += MTK_WED_BUF_SIZE;
- buf_phys += MTK_WED_BUF_SIZE;
-@@ -325,15 +417,18 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- DMA_BIDIRECTIONAL);
- }
-
-- return 0;
-+ if (dev->hw->version == 3)
-+ ret = mtk_wed_pao_buffer_alloc(dev);
-+
-+ return ret;
- }
-
- static void
--mtk_wed_free_buffer(struct mtk_wed_device *dev)
-+mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
- {
-- struct mtk_wdma_desc *desc = dev->buf_ring.desc;
-- void **page_list = dev->buf_ring.pages;
-- int ring_size, page_idx;
-+ struct mtk_rxbm_desc *desc = dev->tx_buf_ring.desc;
-+ struct dma_page_info *page_list = dev->tx_buf_ring.pages;
-+ int ring_size, page_idx, pkt_nums;
- int i;
-
- if (!page_list)
-@@ -342,33 +437,33 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
- if (!desc)
- goto free_pagelist;
-
-- if (dev->ver == MTK_WED_V1) {
-- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-- } else {
-- ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
-- MTK_WED_WDMA_RING_SIZE * 2;
-+ pkt_nums = ring_size = dev->tx_buf_ring.size;
-+ if (dev->hw->version == 3) {
-+ mtk_wed_pao_free_buffer(dev);
-+ pkt_nums = dev->tx_buf_ring.pkt_nums;
- }
-
-- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
-- void *page = page_list[page_idx++];
-+ for (i = 0, page_idx = 0; i < pkt_nums; i += MTK_WED_BUF_PER_PAGE) {
-+ void *page = page_list[page_idx].addr;
-
- if (!page)
- break;
-
-- dma_unmap_page(dev->hw->dev, desc[i].buf0,
-+ dma_unmap_page(dev->hw->dev, page_list[page_idx].addr_phys,
- PAGE_SIZE, DMA_BIDIRECTIONAL);
- __free_page(page);
-+ page_idx++;
- }
-
-- dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-- desc, dev->buf_ring.desc_phys);
-+ dma_free_coherent(dev->hw->dev, ring_size * dev->tx_buf_ring.desc_size,
-+ dev->tx_buf_ring.desc, dev->tx_buf_ring.desc_phys);
-
- free_pagelist:
- kfree(page_list);
- }
-
- static int
--mtk_wed_rx_bm_alloc(struct mtk_wed_device *dev)
-+mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
- {
- struct mtk_rxbm_desc *desc;
- dma_addr_t desc_phys;
-@@ -389,7 +484,7 @@ mtk_wed_rx_bm_alloc(struct mtk_wed_device *dev)
- }
-
- static void
--mtk_wed_free_rx_bm(struct mtk_wed_device *dev)
-+mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
- {
- struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
- int ring_size = dev->rx_buf_ring.size;
-@@ -403,6 +498,113 @@ mtk_wed_free_rx_bm(struct mtk_wed_device *dev)
- desc, dev->rx_buf_ring.desc_phys);
- }
-
-+/* TODO */
-+static int
-+mtk_wed_rx_page_buffer_alloc(struct mtk_wed_device *dev)
-+{
-+ int ring_size = dev->wlan.rx_nbuf, buf_num = MTK_WED_RX_PG_BM_CNT;
-+ struct mtk_rxbm_desc *desc;
-+ dma_addr_t desc_phys;
-+ struct dma_page_info *page_list;
-+ int n_pages, page_idx;
-+ int i;
-+
-+ n_pages = buf_num / MTK_WED_RX_PAGE_BUF_PER_PAGE;
-+
-+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
-+ if (!page_list)
-+ return -ENOMEM;
-+
-+ dev->rx_page_buf_ring.size = ring_size & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ dev->rx_page_buf_ring.pages = page_list;
-+ dev->rx_page_buf_ring.pkt_nums = buf_num;
-+
-+ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-+ &desc_phys, GFP_KERNEL);
-+ if (!desc)
-+ return -ENOMEM;
-+
-+ dev->rx_page_buf_ring.desc = desc;
-+ dev->rx_page_buf_ring.desc_phys = desc_phys;
-+
-+ for (i = 0, page_idx = 0; i < buf_num; i += MTK_WED_RX_PAGE_BUF_PER_PAGE) {
-+ dma_addr_t page_phys, buf_phys;
-+ struct page *page;
-+ void *buf;
-+ int s;
-+
-+ page = __dev_alloc_pages(GFP_KERNEL, 0);
-+ if (!page)
-+ return -ENOMEM;
-+
-+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ if (dma_mapping_error(dev->hw->dev, page_phys)) {
-+ __free_page(page);
-+ return -ENOMEM;
-+ }
-+
-+ page_list[page_idx].addr= page;
-+ page_list[page_idx].addr_phys= page_phys;
-+ page_idx++;
-+
-+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+
-+ buf = page_to_virt(page);
-+ buf_phys = page_phys;
-+
-+ for (s = 0; s < MTK_WED_RX_PAGE_BUF_PER_PAGE; s++) {
-+
-+ desc->buf0 = cpu_to_le32(buf_phys);
-+ desc++;
-+
-+ buf += MTK_WED_PAGE_BUF_SIZE;
-+ buf_phys += MTK_WED_PAGE_BUF_SIZE;
-+ }
-+
-+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE,
-+ DMA_BIDIRECTIONAL);
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+mtk_wed_rx_page_free_buffer(struct mtk_wed_device *dev)
-+{
-+ struct mtk_rxbm_desc *desc = dev->rx_page_buf_ring.desc;
-+ struct dma_page_info *page_list = dev->rx_page_buf_ring.pages;
-+ int ring_size, page_idx;
-+ int i;
-+
-+ if (!page_list)
-+ return;
-+
-+ if (!desc)
-+ goto free_pagelist;
-+
-+ ring_size = dev->rx_page_buf_ring.pkt_nums;
-+
-+ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_RX_PAGE_BUF_PER_PAGE) {
-+ void *page = page_list[page_idx].addr;
-+
-+ if (!page)
-+ break;
-+
-+ dma_unmap_page(dev->hw->dev, page_list[page_idx].addr_phys,
-+ PAGE_SIZE, DMA_BIDIRECTIONAL);
-+ __free_page(page);
-+ page_idx++;
-+ }
-+
-+ dma_free_coherent(dev->hw->dev, dev->rx_page_buf_ring.size * sizeof(*desc),
-+ desc, dev->rx_page_buf_ring.desc_phys);
-+
-+free_pagelist:
-+ kfree(page_list);
-+}
-+
- static void
- mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int scale)
- {
-@@ -416,19 +618,35 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int sca
- static void
- mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
- {
-- int i;
-+ int i, scale = dev->hw->version > 1 ? 2 : 1;
-
- for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
-- mtk_wed_free_ring(dev, &dev->tx_ring[i], 1);
-+ if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED))
-+ mtk_wed_free_ring(dev, &dev->tx_ring[i], 1);
-+
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- mtk_wed_free_ring(dev, &dev->tx_wdma[i], dev->ver);
-+ if ((dev->tx_wdma[i].flags & MTK_WED_RING_CONFIGURED))
-+ mtk_wed_free_ring(dev, &dev->tx_wdma[i], scale);
- }
-
- static void
- mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
- {
-- mtk_wed_free_rx_bm(dev);
-+ int i, scale = dev->hw->version > 1 ? 2 : 1;
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++)
-+ if ((dev->rx_ring[i].flags & MTK_WED_RING_CONFIGURED))
-+ mtk_wed_free_ring(dev, &dev->rx_ring[i], 1);
-+
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-+ if ((dev->rx_wdma[i].flags & MTK_WED_RING_CONFIGURED))
-+ mtk_wed_free_ring(dev, &dev->rx_wdma[i], scale);
-+
-+ mtk_wed_free_rx_buffer(dev);
- mtk_wed_free_ring(dev, &dev->rro.rro_ring, 1);
-+
-+ if (dev->wlan.hwrro)
-+ mtk_wed_rx_page_free_buffer(dev);
- }
-
- static void
-@@ -437,7 +655,7 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
- u32 wdma_mask;
-
- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
-- if (dev->ver > MTK_WED_V1)
-+ if (mtk_wed_get_rx_capa(dev))
- wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
- GENMASK(1, 0));
- /* wed control cr set */
-@@ -447,7 +665,7 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- if (dev->ver == MTK_WED_V1) {
-+ if (dev->hw->version == 1) {
- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
- MTK_WED_PCIE_INT_TRIGGER_STATUS);
-
-@@ -458,6 +676,8 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
- wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
- } else {
-+ if (dev->hw->version == 3)
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN);
-
- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
- MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
-@@ -475,18 +695,20 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
- dev->wlan.txfree_tbit));
-
-- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-- MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-- MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-- MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-- MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-- dev->wlan.rx_tbit[0]) |
-- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-- dev->wlan.rx_tbit[1]));
-+ if (mtk_wed_get_rx_capa(dev))
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-+ dev->wlan.rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-+ dev->wlan.rx_tbit[1]));
- }
-+
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
-- if (dev->ver == MTK_WED_V1) {
-+ if (dev->hw->version == 1) {
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
- wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
-@@ -506,6 +728,21 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
- {
- u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-
-+ switch (dev->hw->version) {
-+ case 1:
-+ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
-+ break;
-+ case 2 :
-+ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH2 |
-+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH2 |
-+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
-+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
-+ break;
-+ case 3:
-+ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT;
-+ break;
-+ }
-+
- if (!dev->hw->num_flows)
- mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-
-@@ -514,31 +751,86 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
- }
-
- static void
--mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
-+mtk_wed_pao_init(struct mtk_wed_device *dev)
- {
-- if (en) {
-- 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);
-+ struct mtk_wed_pao *pao = dev->hw->wed_pao;
-+ int i;
-+
-+ for (i = 0; i < 32; i++)
-+ wed_w32(dev, MTK_WED_PAO_HIFTXD_BASE_L(i),
-+ pao->hif_txd_phys[i]);
-+
-+ /* init all sta parameter */
-+ wed_w32(dev, MTK_WED_PAO_STA_INFO_INIT, MTK_WED_PAO_STA_RMVL |
-+ MTK_WED_PAO_STA_WTBL_HDRT_MODE |
-+ FIELD_PREP(MTK_WED_PAO_STA_MAX_AMSDU_LEN,
-+ dev->wlan.max_amsdu_len >> 8) |
-+ FIELD_PREP(MTK_WED_PAO_STA_MAX_AMSDU_NUM,
-+ dev->wlan.max_amsdu_nums));
-+
-+ wed_w32(dev, MTK_WED_PAO_STA_INFO, MTK_WED_PAO_STA_INFO_DO_INIT);
-+
-+ if (mtk_wed_poll_busy(dev, MTK_WED_PAO_STA_INFO,
-+ MTK_WED_PAO_STA_INFO_DO_INIT)) {
-+ dev_err(dev->hw->dev, "mtk_wed%d: pao init failed!\n",
-+ dev->hw->index);
-+ return;
- }
-+
-+ /* init pao txd src */
-+ wed_set(dev, MTK_WED_PAO_HIFTXD_CFG,
-+ FIELD_PREP(MTK_WED_PAO_HIFTXD_SRC, dev->hw->index));
-+
-+ /* init qmem */
-+ wed_set(dev, MTK_WED_PAO_PSE, MTK_WED_PAO_PSE_RESET);
-+ if (mtk_wed_poll_busy(dev, MTK_WED_PAO_MON_QMEM_STS1, BIT(29))) {
-+ pr_info("%s: init pao qmem fail\n", __func__);
-+ return;
-+ }
-+
-+ /* eagle E1 PCIE1 tx ring 22 flow control issue */
-+ if (dev->wlan.chip_id == 0x7991) {
-+ wed_clr(dev, MTK_WED_PAO_AMSDU_FIFO,
-+ MTK_WED_PAO_AMSDU_IS_PRIOR0_RING);
-+ }
-+
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN);
-+
-+ return;
- }
-
--static void
--mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
-+static int
-+mtk_wed_hwrro_init(struct mtk_wed_device *dev)
- {
--#define MTK_WFMDA_RX_DMA_EN BIT(2)
-+ if (!mtk_wed_get_rx_capa(dev))
-+ return 0;
-
-+ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM,
-+ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128));
-+
-+ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE,
-+ dev->rx_page_buf_ring.desc_phys);
-+
-+ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR,
-+ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX |
-+ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX,
-+ MTK_WED_RX_PG_BM_CNT));
-+
-+ /* enable rx_page_bm to fetch dmad */
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev,
-+ struct mtk_wed_ring *ring)
-+{
- int timeout = 3;
-- u32 cur_idx, regs;
-+ u32 cur_idx;
-
- do {
-- regs = MTK_WED_WPDMA_RING_RX_DATA(idx) +
-- MTK_WED_RING_OFS_CPU_IDX;
-- cur_idx = wed_r32(dev, regs);
-+ cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX);
- if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
- break;
-
-@@ -546,70 +838,133 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
- timeout--;
- } while (timeout > 0);
-
-- if (timeout) {
-- unsigned int val;
-+ return timeout;
-+}
-
-- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
-- dev->wlan.phy_base);
-- val |= MTK_WFMDA_RX_DMA_EN;
-
-- wifi_w32(dev, dev->wlan.wpdma_rx_glo -
-- dev->wlan.phy_base, val);
-+static void
-+mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
-+{
-+ if (en) {
-+ 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 {
-- dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable failed!\n",
-- dev->hw->index, idx);
-+ 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_enable(struct mtk_wed_device *dev)
- {
-- wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-+#define MTK_WFMDA_RX_DMA_EN BIT(2)
-+
-+ if (dev->hw->version == 1)
-+ 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 |
- MTK_WED_GLO_CFG_RX_DMA_EN);
-+
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) |
-+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8));
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
-+
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
-+
- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR);
- 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_TX_DMA_EN /*|
- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
-- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
-+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES*/);
-
-- if (dev->ver == MTK_WED_V1) {
-+ if (dev->hw->version == 1) {
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
- int idx = 0;
-
-- wed_set(dev, MTK_WED_WPDMA_CTRL,
-- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
--
-- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+ if (mtk_wed_get_rx_capa(dev))
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
- 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);
-
-+ if (dev->hw->version == 3) {
-+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
-+
-+ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ //wdma_w32(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8));
-+
-+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
-+
-+ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+
-+ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ }
-+ }
-+
- 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);
-
-+ if (!mtk_wed_get_rx_capa(dev))
-+ return;
-+
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN);
- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
- MTK_WED_WPDMA_RX_D_RX_DRV_EN |
- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
- 0x2));
-
-- for (idx = 0; idx < dev->hw->ring_num; idx++)
-- mtk_wed_check_wfdma_rx_fill(dev, idx);
-+ for (idx = 0; idx < dev->hw->ring_num; idx++) {
-+ struct mtk_wed_ring *ring = &dev->rx_ring[idx];
-+
-+ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ if(mtk_wed_check_wfdma_rx_fill(dev, ring)) {
-+ unsigned int val;
-+
-+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
-+ dev->wlan.phy_base);
-+ val |= MTK_WFMDA_RX_DMA_EN;
-+
-+ wifi_w32(dev, dev->wlan.wpdma_rx_glo -
-+ dev->wlan.phy_base, val);
-+
-+ dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable successful!\n",
-+ dev->hw->index, idx);
-+ } else {
-+ dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable failed!\n",
-+ dev->hw->index, idx);
-+ }
-+ }
- }
- }
-
-@@ -644,15 +999,20 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
- MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-- }
-
-- mtk_wed_set_512_support(dev, false);
-+ if (dev->hw->version == 3 && mtk_wed_get_rx_capa(dev)) {
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG,
-+ MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG,
-+ MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ }
-+ }
- }
-
- static void
- mtk_wed_stop(struct mtk_wed_device *dev)
- {
-- if (dev->ver > MTK_WED_V1) {
-+ if (mtk_wed_get_rx_capa(dev)) {
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
- wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
- }
-@@ -677,13 +1037,21 @@ mtk_wed_deinit(struct mtk_wed_device *dev)
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-- if (dev->hw->ver == 1)
-+ if (dev->hw->version == 1)
- return;
-
- wed_clr(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_RX_ROUTE_QM_EN |
- MTK_WED_CTRL_WED_RX_BM_EN |
- MTK_WED_CTRL_RX_RRO_QM_EN);
-+
-+ if (dev->hw->version == 3) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN);
-+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_PAO);
-+ wed_clr(dev, MTK_WED_PCIE_INT_CTRL,
-+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER);
-+ }
- }
-
- static void
-@@ -702,9 +1070,9 @@ mtk_wed_detach(struct mtk_wed_device *dev)
-
- mtk_wdma_tx_reset(dev);
-
-- mtk_wed_free_buffer(dev);
-+ mtk_wed_free_tx_buffer(dev);
- mtk_wed_free_tx_rings(dev);
-- if (dev->ver > MTK_WED_V1) {
-+ if (mtk_wed_get_rx_capa(dev)) {
- mtk_wed_wo_reset(dev);
- mtk_wed_free_rx_rings(dev);
- mtk_wed_wo_exit(hw);
-@@ -731,24 +1099,29 @@ mtk_wed_detach(struct mtk_wed_device *dev)
- static void
- mtk_wed_bus_init(struct mtk_wed_device *dev)
- {
--#define PCIE_BASE_ADDR0 0x11280000
-+ switch (dev->wlan.bus_type) {
-+ case MTK_WED_BUS_PCIE: {
-+ struct device_node *np = dev->hw->eth->dev->of_node;
-+ struct regmap *regs;
-
-- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
-- struct device_node *node;
-- void __iomem * base_addr;
-- u32 value = 0;
-+ if (dev->hw->version == 2) {
-+ regs = syscon_regmap_lookup_by_phandle(np,
-+ "mediatek,wed-pcie");
-+ if (IS_ERR(regs))
-+ break;
-
-- node = of_parse_phandle(dev->hw->node, "mediatek,wed_pcie", 0);
-- if (!node) {
-- pr_err("%s: no wed_pcie node\n", __func__);
-- return;
-+ regmap_update_bits(regs, 0, BIT(0), BIT(0));
- }
-
-- base_addr = of_iomap(node, 0);
--
-- value = readl(base_addr);
-- value |= BIT(0);
-- writel(value, base_addr);
-+ if (dev->wlan.msi) {
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, dev->hw->pci_base| 0xc08);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, dev->hw->pci_base | 0xc04);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8));
-+ } else {
-+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, dev->hw->pci_base | 0x180);
-+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, dev->hw->pci_base | 0x184);
-+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-+ }
-
- wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
-@@ -756,45 +1129,53 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
- /* 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);
--
-- value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-- value = 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);
-+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER |
-+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, dev->hw->index));
-
-- value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-- value = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
--
-- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
--
-- /* pola setting */
-- value = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
-- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-- } else if (dev->wlan.bus_type == MTK_WED_BUS_AXI) {
-+ 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;
- }
-+
- return;
- }
-
- static void
- mtk_wed_set_wpdma(struct mtk_wed_device *dev)
- {
-- if (dev->ver > MTK_WED_V1) {
-+ 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, dev->wlan.wpdma_tx);
- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
-
-- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
-- } else {
-- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ int i;
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_RING0, dev->wlan.wpdma_rx[0]);
-+ if (dev->wlan.wpdma_rx[1])
-+ wed_w32(dev, MTK_WED_WPDMA_RX_RING1, dev->wlan.wpdma_rx[1]);
-+
-+ if (dev->wlan.hwrro) {
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]);
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]);
-+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) {
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i),
-+ dev->wlan.wpdma_rx_pg + i * 0x10);
-+ }
-+ }
-+ }
- }
- }
-
-@@ -806,21 +1187,25 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
- mtk_wed_deinit(dev);
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-
-- if (dev->ver > MTK_WED_V1)
-- mtk_wed_bus_init(dev);
--
- mtk_wed_set_wpdma(dev);
-
-- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
-- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
-- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ if (dev->hw->version == 3) {
-+ mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE;
-+ set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2);
-+ } else {
-+ mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
-+ MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
-+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-+ set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
-+ MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
-+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
-+ }
-+
- wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
-
-- if (dev->ver == MTK_WED_V1) {
-+ if (dev->hw->version == 1) {
- u32 offset;
-+
- offset = dev->hw->index ? 0x04000400 : 0;
- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
- wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset);
-@@ -907,11 +1292,16 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
- } while (1);
-
- /* configure RX_ROUTE_QM */
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
-- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ if (dev->hw->version == 2) {
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
-+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
-+ } else {
-+ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0,
-+ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT, 0x3 + dev->hw->index));
-+ }
-
- /* enable RX_ROUTE_QM */
- wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
-@@ -920,23 +1310,45 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
- static void
- mtk_wed_tx_hw_init(struct mtk_wed_device *dev)
- {
-- int size = dev->buf_ring.size;
-+ int size = dev->wlan.nbuf;
- int rev_size = MTK_WED_TX_RING_SIZE / 2;
-- int thr = 1;
-+ int thr_lo = 1, thr_hi = 1;
-
-- if (dev->ver > MTK_WED_V1) {
-+ if (dev->hw->version == 1) {
-+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
-+ MTK_WED_TX_BM_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, rev_size / 128));
-+ } else {
- size = MTK_WED_WDMA_RING_SIZE * ARRAY_SIZE(dev->tx_wdma) +
-- dev->buf_ring.size;
-+ dev->tx_buf_ring.size;
- rev_size = size;
-- thr = 0;
-+ thr_lo = 0;
-+ thr_hi = MTK_WED_TX_BM_DYN_THR_HI;
-+
-+ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_PAUSE |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM,
-+ size / 128) |
-+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
-+ size / 128));
-+
-+ /* return SKBID + SDP back to bm */
-+ if (dev->ver == 3) {
-+ wed_set(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
-+ size = dev->wlan.nbuf;
-+ rev_size = size;
-+ } else {
-+ 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);
-+ }
- }
-
-- wed_w32(dev, MTK_WED_TX_BM_CTRL,
-- MTK_WED_TX_BM_CTRL_PAUSE |
-- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, size / 128) |
-- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, rev_size / 128));
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
-
-- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
-+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
-
- wed_w32(dev, MTK_WED_TX_BM_TKID,
- FIELD_PREP(MTK_WED_TX_BM_TKID_START,
-@@ -946,25 +1358,44 @@ mtk_wed_tx_hw_init(struct mtk_wed_device *dev)
-
- 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, thr) |
-- MTK_WED_TX_BM_DYN_THR_HI);
-+ if (dev->hw->version < 3)
-+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
-+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, thr_lo) |
-+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, thr_hi));
-+ else {
-+ /* change to new bm */
-+ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR, dev->tx_buf_ring.pkt_nums |
-+ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
-+ wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_LEGACY_EN);
-+ }
-
-- if (dev->ver > MTK_WED_V1) {
-+ if (dev->hw->version != 1) {
- 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) |
-+ 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);
-+ size / 128));
-+
-+ /* return SKBID + SDP back to bm */
-+ if (dev->ver == 3)
-+ wed_set(dev, MTK_WED_TX_TKID_CTRL,
-+ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
-+ else
-+ 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_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_INIT_PTR, dev->tx_buf_ring.pkt_nums |
-+ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-- if (dev->ver > MTK_WED_V1)
-+ if (dev->hw->version != 1)
- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
- }
-
-@@ -977,7 +1408,26 @@ mtk_wed_rx_hw_init(struct mtk_wed_device *dev)
-
- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-
-+ /* reset prefetch index of ring */
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
-+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
-+
-+ /* reset prefetch FIFO of ring */
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR |
-+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0);
-+
- mtk_wed_rx_bm_hw_init(dev);
-+ if (dev->wlan.hwrro)
-+ mtk_wed_hwrro_init(dev);
- mtk_wed_rro_hw_init(dev);
- mtk_wed_route_qm_hw_init(dev);
- }
-@@ -991,7 +1441,7 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
- dev->init_done = true;
- mtk_wed_set_ext_int(dev, false);
- mtk_wed_tx_hw_init(dev);
-- if (dev->ver > MTK_WED_V1)
-+ if (mtk_wed_get_rx_capa(dev))
- mtk_wed_rx_hw_init(dev);
- }
-
-@@ -1015,26 +1465,6 @@ mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale, bool tx)
- }
- }
-
--static u32
--mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
--{
-- if (wed_r32(dev, reg) & mask)
-- return true;
--
-- return false;
--}
--
--static int
--mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
--{
-- int sleep = 1000;
-- int timeout = 100 * sleep;
-- u32 val;
--
-- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
-- timeout, false, dev, reg, mask);
--}
--
- static void
- mtk_wed_rx_reset(struct mtk_wed_device *dev)
- {
-@@ -1133,7 +1563,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
- mtk_wed_ring_reset(desc, MTK_WED_RX_RING_SIZE, 1, false);
- }
-
-- mtk_wed_free_rx_bm(dev);
-+ mtk_wed_free_rx_buffer(dev);
- }
-
-
-@@ -1271,12 +1701,15 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev,
- int idx, int size, bool reset)
- {
- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
-+ int scale = dev->hw->version > 1 ? 2 : 1;
-
- if(!reset)
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- dev->ver, true))
-+ scale, true))
- return -ENOMEM;
-
-+ wdma->flags |= MTK_WED_RING_CONFIGURED;
-+
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
- wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT,
-@@ -1296,12 +1729,33 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev,
- int idx, int size, bool reset)
- {
- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
-+ int scale = dev->hw->version > 1 ? 2 : 1;
-
- if (!reset)
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- dev->ver, true))
-+ scale, true))
- return -ENOMEM;
-
-+ if (dev->hw->version == 3) {
-+ struct mtk_wdma_desc *desc = wdma->desc;
-+ int i;
-+
-+ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) {
-+ desc->buf0 = 0;
-+ desc->ctrl = MTK_WDMA_DESC_CTRL_DMA_DONE;
-+ desc->buf1 = 0;
-+ desc->info = MTK_WDMA_TXD0_DESC_INFO_DMA_DONE;
-+ desc++;
-+ desc->buf0 = 0;
-+ desc->ctrl = MTK_WDMA_DESC_CTRL_DMA_DONE;
-+ desc->buf1 = 0;
-+ desc->info = MTK_WDMA_TXD1_DESC_INFO_DMA_DONE;
-+ desc++;
-+ }
-+ }
-+
-+ wdma->flags |= MTK_WED_RING_CONFIGURED;
-+
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
- wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
-@@ -1312,7 +1766,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev,
- MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
- if (reset)
- mtk_wed_ring_reset(wdma->desc, MTK_WED_WDMA_RING_SIZE,
-- dev->ver, true);
-+ scale, true);
- if (idx == 0) {
- wed_w32(dev, MTK_WED_WDMA_RING_TX
- + MTK_WED_RING_OFS_BASE, wdma->desc_phys);
-@@ -1395,7 +1849,7 @@ mtk_wed_send_msg(struct mtk_wed_device *dev, int cmd_id, void *data, int len)
- {
- struct mtk_wed_wo *wo = dev->hw->wed_wo;
-
-- if (dev->ver == MTK_WED_V1)
-+ if (!mtk_wed_get_rx_capa(dev))
- return 0;
-
- return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, cmd_id, data, len, true);
-@@ -1420,24 +1874,106 @@ mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
- }
- }
-
-+static void
-+mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask)
-+{
-+ int idx, ret;
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
-+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
-+
-+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hwrro)
-+ return;
-+
-+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG,
-+ dev->wlan.rro_rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG,
-+ dev->wlan.rro_rx_tbit[1]));
-+
-+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG,
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[1])|
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG,
-+ dev->wlan.rx_pg_tbit[2]));
-+
-+ /*
-+ * RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after
-+ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken
-+ */
-+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
-+
-+ for (idx = 0; idx < MTK_WED_RX_QUEUES; idx++) {
-+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
-+
-+ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ ret = mtk_wed_check_wfdma_rx_fill(dev, ring);
-+ if (!ret)
-+ dev_err(dev->hw->dev, "mtk_wed%d: rx_rro_ring(%d) init failed!\n",
-+ dev->hw->index, idx);
-+ }
-+
-+ for (idx = 0; idx < MTK_WED_RX_PAGE_QUEUES; idx++){
-+ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
-+ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
-+ continue;
-+
-+ ret = mtk_wed_check_wfdma_rx_fill(dev, ring);
-+ if (!ret)
-+ dev_err(dev->hw->dev, "mtk_wed%d: rx_page_ring(%d) init failed!\n",
-+ dev->hw->index, idx);
-+ }
-+}
-+
- static void
- mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- {
- int i, ret;
-
-- if (dev->ver > MTK_WED_V1)
-- ret = mtk_wed_rx_bm_alloc(dev);
-+ if (mtk_wed_get_rx_capa(dev)) {
-+ ret = mtk_wed_rx_buffer_alloc(dev);
-+ if (ret)
-+ return;
-+
-+ if (dev->wlan.hwrro)
-+ mtk_wed_rx_page_buffer_alloc(dev);
-+ }
-
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
- if (!dev->tx_wdma[i].desc)
- mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
-
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_page_ring); i++) {
-+ u32 count = MTK_WED_RRO_MSDU_PG_CTRL0(i) +
-+ MTK_WED_RING_OFS_COUNT;
-+
-+ if (!wed_r32(dev, count))
-+ wed_w32(dev, count, 1);
-+ }
-+
- mtk_wed_hw_init(dev);
-
- mtk_wed_set_int(dev, irq_mask);
- mtk_wed_set_ext_int(dev, true);
-
-- if (dev->ver == MTK_WED_V1) {
-+ if (dev->hw->version == 1) {
- u32 val;
-
- val = dev->wlan.wpdma_phys |
-@@ -1448,33 +1984,52 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- val |= BIT(1);
- val |= BIT(0);
- regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
-- } else {
-+ } else if (mtk_wed_get_rx_capa(dev)) {
- /* driver set mid ready and only once */
- wed_w32(dev, MTK_WED_EXT_INT_MASK1,
- MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
- wed_w32(dev, MTK_WED_EXT_INT_MASK2,
- MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-+ if (dev->hw->version == 3)
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK3,
-+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
-
- wed_r32(dev, MTK_WED_EXT_INT_MASK1);
- wed_r32(dev, MTK_WED_EXT_INT_MASK2);
-+ if (dev->hw->version == 3)
-+ wed_r32(dev, MTK_WED_EXT_INT_MASK3);
-
- ret = mtk_wed_rro_cfg(dev);
- if (ret)
- return;
- }
-- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-+
-+ if (dev->hw->version == 2)
-+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
-+ else if (dev->hw->version == 3)
-+ mtk_wed_pao_init(dev);
-
- mtk_wed_dma_enable(dev);
- dev->running = true;
- }
-
-+static int
-+mtk_wed_get_pci_base(struct mtk_wed_device *dev)
-+{
-+ if (dev->hw->index == 0)
-+ return MTK_WED_PCIE_BASE0;
-+ else if (dev->hw->index == 1)
-+ return MTK_WED_PCIE_BASE1;
-+ else
-+ return MTK_WED_PCIE_BASE2;
-+}
-+
- static int
- mtk_wed_attach(struct mtk_wed_device *dev)
- __releases(RCU)
- {
- struct mtk_wed_hw *hw;
- struct device *device;
-- u16 ver;
- int ret = 0;
-
- RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
-@@ -1494,34 +2049,30 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- goto out;
- }
-
-- device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
-- ? &dev->wlan.pci_dev->dev
-- : &dev->wlan.platform_dev->dev;
-+ 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->ver);
-+ hw->index, hw->version);
-
- dev->hw = hw;
- dev->dev = hw->dev;
- dev->irq = hw->irq;
- dev->wdma_idx = hw->index;
-+ dev->ver = hw->version;
-+
-+ if (dev->hw->version == 3)
-+ dev->hw->pci_base = mtk_wed_get_pci_base(dev);
-
- if (hw->eth->dma_dev == hw->eth->dev &&
- of_dma_is_coherent(hw->eth->dev->of_node))
- mtk_eth_set_dma_device(hw->eth, hw->dev);
-
-- dev->ver = FIELD_GET(MTK_WED_REV_ID_MAJOR,
-- wed_r32(dev, MTK_WED_REV_ID));
-- if (dev->ver > MTK_WED_V1)
-- ver = FIELD_GET(MTK_WED_REV_ID_MINOR,
-- wed_r32(dev, MTK_WED_REV_ID));
--
-- dev->rev_id = ((dev->ver << 28) | ver << 16);
--
-- ret = mtk_wed_buffer_alloc(dev);
-+ ret = mtk_wed_tx_buffer_alloc(dev);
- if (ret)
- goto error;
-
-- if (dev->ver > MTK_WED_V1) {
-+ if (mtk_wed_get_rx_capa(dev)) {
- ret = mtk_wed_rro_alloc(dev);
- if (ret)
- goto error;
-@@ -1533,15 +2084,20 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- init_completion(&dev->wlan_reset_done);
- atomic_set(&dev->fe_reset, 0);
-
-- if (dev->ver == MTK_WED_V1)
-+ if (dev->hw->version != 1)
-+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
-+ else
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
- BIT(hw->index), 0);
-- else
-+
-+ if (mtk_wed_get_rx_capa(dev))
- ret = mtk_wed_wo_init(hw);
-
- error:
-- if (ret)
-+ if (ret) {
-+ pr_info("%s: detach wed\n", __func__);
- mtk_wed_detach(dev);
-+ }
- out:
- mutex_unlock(&hw_lock);
-
-@@ -1576,8 +2132,26 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx,
- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, reset))
- return -ENOMEM;
-
-+ if (dev->hw->version == 3 && idx == 1) {
-+ /* reset prefetch index */
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ /* reset prefetch FIFO */
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
-+ }
-+
- ring->reg_base = MTK_WED_RING_TX(idx);
- ring->wpdma = regs;
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-
- /* WED -> WPDMA */
- wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
-@@ -1599,7 +2173,7 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
- struct mtk_wed_ring *ring = &dev->txfree_ring;
- int i, idx = 1;
-
-- if(dev->ver > MTK_WED_V1)
-+ if(dev->hw->version > 1)
- idx = 0;
-
- /*
-@@ -1638,6 +2212,7 @@ mtk_wed_rx_ring_setup(struct mtk_wed_device *dev,
-
- ring->reg_base = MTK_WED_RING_RX_DATA(idx);
- ring->wpdma = regs;
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
- dev->hw->ring_num = idx + 1;
-
- /* WPDMA -> WED */
-@@ -1652,6 +2227,129 @@ mtk_wed_rx_ring_setup(struct mtk_wed_device *dev,
- return 0;
- }
-
-+static int
-+mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
-+
-+ ring->wpdma = regs;
-+
-+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE,
-+ readl(regs));
-+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
-+
-+ ring->wpdma = regs;
-+
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE,
-+ readl(regs));
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+
-+ ring->flags |= MTK_WED_RING_CONFIGURED;
-+
-+ return 0;
-+}
-+
-+static int
-+mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
-+{
-+ struct mtk_wed_ring *ring = &dev->ind_cmd_ring;
-+ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT);
-+ int i = 0, cnt = 0;
-+
-+ ring->wpdma = regs;
-+
-+ if (readl(regs) & 0xf)
-+ pr_info("%s(): address is not 16-byte alignment\n", __func__);
-+
-+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE,
-+ readl(regs) & 0xfffffff0);
-+
-+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT,
-+ readl(regs + MTK_WED_RING_OFS_COUNT));
-+
-+ /* ack sn cr */
-+ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base +
-+ dev->wlan.ind_cmd.ack_sn_addr);
-+ wed_w32(dev, MTK_WED_RRO_CFG1,
-+ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ,
-+ dev->wlan.ind_cmd.win_size) |
-+ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID,
-+ dev->wlan.ind_cmd.particular_sid));
-+
-+ /* particular session addr element */
-+ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0, dev->wlan.ind_cmd.particular_se_phys);
-+
-+ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) {
-+ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA,
-+ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4);
-+ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
-+ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f));
-+
-+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
-+ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) &&
-+ cnt < 100) {
-+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
-+ cnt++;
-+ }
-+ if (cnt >= 100) {
-+ dev_err(dev->hw->dev, "mtk_wed%d: write ba session base failed!\n",
-+ dev->hw->index);
-+ }
-+ /*if (mtk_wed_poll_busy(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
-+ MTK_WED_ADDR_ELEM_TBL_WR_RDY)) {
-+ dev_err(dev->hw->dev, "mtk_wed%d: write ba session base failed!\n",
-+ dev->hw->index);
-+ return -1;
-+ }*/
-+ }
-+
-+ /* pn check init */
-+ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) {
-+ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M,
-+ MTK_WED_PN_CHECK_IS_FIRST);
-+
-+ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR |
-+ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i));
-+
-+ cnt = 0;
-+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
-+ while (!(val & MTK_WED_PN_CHECK_WR_RDY) &&
-+ cnt < 100) {
-+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
-+ cnt++;
-+ }
-+ if (cnt >= 100) {
-+ dev_err(dev->hw->dev, "mtk_wed%d: session(%d) init failed!\n",
-+ dev->hw->index, i);
-+ }
-+ /*if (mtk_wed_poll_busy(dev, MTK_WED_PN_CHECK_CFG,
-+ MTK_WED_PN_CHECK_WR_RDY)) {
-+ dev_err(dev->hw->dev, "mtk_wed%d: session(%d) init failed!\n",
-+ dev->hw->index, i);
-+ //return -1;
-+ }*/
-+ }
-+
-+ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN);
-+
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
-+
-+ return 0;
-+}
-+
-+
- static u32
- mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
- {
-@@ -1659,9 +2357,13 @@ mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
-
- 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;
-- if (!dev->hw->num_flows)
-- val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-+ if (dev->hw->version == 3) {
-+ val &= MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT;
-+ } else {
-+ val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK;
-+ if (!dev->hw->num_flows)
-+ val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
-+ }
- if (val && net_ratelimit())
- pr_err("mtk_wed%d: error status=%08x\n", dev->hw->index, val);
-
-@@ -1754,6 +2456,9 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- .tx_ring_setup = mtk_wed_tx_ring_setup,
- .txfree_ring_setup = mtk_wed_txfree_ring_setup,
- .rx_ring_setup = mtk_wed_rx_ring_setup,
-+ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup,
-+ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup,
-+ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup,
- .msg_update = mtk_wed_send_msg,
- .start = mtk_wed_start,
- .stop = mtk_wed_stop,
-@@ -1765,6 +2470,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- .detach = mtk_wed_detach,
- .setup_tc = mtk_wed_eth_setup_tc,
- .ppe_check = mtk_wed_ppe_check,
-+ .start_hwrro = mtk_wed_start_hwrro,
- };
- struct device_node *eth_np = eth->dev->of_node;
- struct platform_device *pdev;
-@@ -1804,9 +2510,10 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- hw->wdma_phy = wdma_phy;
- hw->index = index;
- hw->irq = irq;
-- hw->ver = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-+ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) ?
-+ 3 : MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-
-- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+ 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,
-@@ -1821,7 +2528,6 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- regmap_write(hw->mirror, 0, 0);
- regmap_write(hw->mirror, 4, 0);
- }
-- hw->ver = MTK_WED_V1;
- }
-
- mtk_wed_hw_add_debugfs(hw);
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
-index 490873c..fcf7bd0 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -10,10 +10,13 @@
- #include <linux/netdevice.h>
- #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
-
--#define MTK_WED_PKT_SIZE 1900
-+#define MTK_WED_PKT_SIZE 1920//1900
- #define MTK_WED_BUF_SIZE 2048
-+#define MTK_WED_PAGE_BUF_SIZE 128
- #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
-+#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
- #define MTK_WED_RX_RING_SIZE 1536
-+#define MTK_WED_RX_PG_BM_CNT 8192
-
- #define MTK_WED_TX_RING_SIZE 2048
- #define MTK_WED_WDMA_RING_SIZE 512
-@@ -27,6 +30,9 @@
- #define MTK_WED_RRO_QUE_CNT 8192
- #define MTK_WED_MIOD_ENTRY_CNT 128
-
-+#define MTK_WED_TX_BM_DMA_SIZE 65536
-+#define MTK_WED_TX_BM_PKT_CNT 32768
-+
- #define MODULE_ID_WO 1
-
- struct mtk_eth;
-@@ -43,6 +49,8 @@ struct mtk_wed_hw {
- struct dentry *debugfs_dir;
- struct mtk_wed_device *wed_dev;
- struct mtk_wed_wo *wed_wo;
-+ struct mtk_wed_pao *wed_pao;
-+ u32 pci_base;
- u32 debugfs_reg;
- u32 num_flows;
- u32 wdma_phy;
-@@ -50,7 +58,8 @@ struct mtk_wed_hw {
- int ring_num;
- int irq;
- int index;
-- u32 ver;
-+ int token_id;
-+ u32 version;
- };
-
- struct mtk_wdma_info {
-@@ -58,6 +67,18 @@ struct mtk_wdma_info {
- u8 queue;
- u16 wcid;
- u8 bss;
-+ u32 usr_info;
-+ u8 tid;
-+ u8 is_fixedrate;
-+ u8 is_prior;
-+ u8 is_sp;
-+ u8 hf;
-+ u8 amsdu_en;
-+};
-+
-+struct mtk_wed_pao {
-+ char *hif_txd[32];
-+ dma_addr_t hif_txd_phys[32];
- };
-
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-index 4a9e684..51e3d7c 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-@@ -11,9 +11,11 @@ struct reg_dump {
- u16 offset;
- u8 type;
- u8 base;
-+ u32 mask;
- };
-
- enum {
-+ DUMP_TYPE_END,
- DUMP_TYPE_STRING,
- DUMP_TYPE_WED,
- DUMP_TYPE_WDMA,
-@@ -23,8 +25,11 @@ enum {
- DUMP_TYPE_WED_RRO,
- };
-
-+#define DUMP_END() { .type = DUMP_TYPE_END }
- #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
- #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
-+#define DUMP_REG_MASK(_reg, _mask) { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
-+
- #define DUMP_RING(_prefix, _base, ...) \
- { _prefix " BASE", _base, __VA_ARGS__ }, \
- { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \
-@@ -32,6 +37,7 @@ enum {
- { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
-
- #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
-+#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
- #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
-
- #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
-@@ -52,36 +58,49 @@ print_reg_val(struct seq_file *s, const char *name, u32 val)
-
- static void
- dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
-- const struct reg_dump *regs, int n_regs)
-+ const struct reg_dump **regs)
- {
-- const struct reg_dump *cur;
-+ const struct reg_dump **cur_o = regs, *cur;
-+ bool newline = false;
- u32 val;
-
-- for (cur = regs; cur < ®s[n_regs]; cur++) {
-- switch (cur->type) {
-- case DUMP_TYPE_STRING:
-- seq_printf(s, "%s======== %s:\n",
-- cur > regs ? "\n" : "",
-- cur->name);
-- continue;
-- case DUMP_TYPE_WED:
-- case DUMP_TYPE_WED_RRO:
-- val = wed_r32(dev, cur->offset);
-- break;
-- case DUMP_TYPE_WDMA:
-- val = wdma_r32(dev, cur->offset);
-- break;
-- case DUMP_TYPE_WPDMA_TX:
-- val = wpdma_tx_r32(dev, cur->base, cur->offset);
-- break;
-- case DUMP_TYPE_WPDMA_TXFREE:
-- val = wpdma_txfree_r32(dev, cur->offset);
-- break;
-- case DUMP_TYPE_WPDMA_RX:
-- val = wpdma_rx_r32(dev, cur->base, cur->offset);
-- break;
-+ while (*cur_o) {
-+ cur = *cur_o;
-+
-+ while (cur->type != DUMP_TYPE_END) {
-+ switch (cur->type) {
-+ case DUMP_TYPE_STRING:
-+ seq_printf(s, "%s======== %s:\n",
-+ newline ? "\n" : "",
-+ cur->name);
-+ newline = true;
-+ cur++;
-+ continue;
-+ case DUMP_TYPE_WED:
-+ case DUMP_TYPE_WED_RRO:
-+ val = wed_r32(dev, cur->offset);
-+ break;
-+ case DUMP_TYPE_WDMA:
-+ val = wdma_r32(dev, cur->offset);
-+ break;
-+ case DUMP_TYPE_WPDMA_TX:
-+ val = wpdma_tx_r32(dev, cur->base, cur->offset);
-+ break;
-+ case DUMP_TYPE_WPDMA_TXFREE:
-+ val = wpdma_txfree_r32(dev, cur->offset);
-+ break;
-+ case DUMP_TYPE_WPDMA_RX:
-+ val = wpdma_rx_r32(dev, cur->base, cur->offset);
-+ break;
-+ }
-+
-+ if (cur->mask)
-+ val = (cur->mask & val) >> (ffs(cur->mask) - 1);
-+
-+ print_reg_val(s, cur->name, val);
-+ cur++;
- }
-- print_reg_val(s, cur->name, val);
-+ cur_o++;
- }
- }
-
-@@ -89,7 +108,7 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
- static int
- wed_txinfo_show(struct seq_file *s, void *data)
- {
-- static const struct reg_dump regs[] = {
-+ static const struct reg_dump regs_common[] = {
- DUMP_STR("WED TX"),
- DUMP_WED(WED_TX_MIB(0)),
- DUMP_WED_RING(WED_RING_TX(0)),
-@@ -128,16 +147,32 @@ wed_txinfo_show(struct seq_file *s, void *data)
- DUMP_WDMA_RING(WDMA_RING_RX(0)),
- DUMP_WDMA_RING(WDMA_RING_RX(1)),
-
-- DUMP_STR("TX FREE"),
-+ DUMP_STR("WED TX FREE"),
- DUMP_WED(WED_RX_MIB(0)),
-+ DUMP_WED_RING(WED_RING_RX(0)),
-+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
-+
-+ DUMP_WED(WED_RX_MIB(1)),
-+ DUMP_WED_RING(WED_RING_RX(1)),
-+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
-+ DUMP_STR("WED_WPDMA TX FREE"),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
-+ DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
-+ DUMP_END(),
-+ };
-+
-+ static const struct reg_dump *regs[] = {
-+ ®s_common[0],
-+ NULL,
- };
-+
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-
- if (!dev)
- return 0;
-
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ dump_wed_regs(s, dev, regs);
-
- return 0;
- }
-@@ -146,7 +181,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
- static int
- wed_rxinfo_show(struct seq_file *s, void *data)
- {
-- static const struct reg_dump regs[] = {
-+ static const struct reg_dump regs_common[] = {
- DUMP_STR("WPDMA RX"),
- DUMP_WPDMA_RX_RING(0),
- DUMP_WPDMA_RX_RING(1),
-@@ -164,7 +199,7 @@ wed_rxinfo_show(struct seq_file *s, void *data)
- DUMP_WED_RING(WED_RING_RX_DATA(0)),
- DUMP_WED_RING(WED_RING_RX_DATA(1)),
-
-- DUMP_STR("WED RRO"),
-+ DUMP_STR("WED WO RRO"),
- DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
- DUMP_WED(WED_RROQM_MID_MIB),
- DUMP_WED(WED_RROQM_MOD_MIB),
-@@ -175,16 +210,6 @@ wed_rxinfo_show(struct seq_file *s, void *data)
- DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
- DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
-
-- DUMP_STR("WED Route QM"),
-- DUMP_WED(WED_RTQM_R2H_MIB(0)),
-- DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-- DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-- DUMP_WED(WED_RTQM_R2H_MIB(1)),
-- DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-- DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-- DUMP_WED(WED_RTQM_Q2N_MIB),
-- DUMP_WED(WED_RTQM_Q2B_MIB),
-- DUMP_WED(WED_RTQM_PFDBK_MIB),
-
- DUMP_STR("WED WDMA TX"),
- DUMP_WED(WED_WDMA_TX_MIB),
-@@ -205,15 +230,99 @@ wed_rxinfo_show(struct seq_file *s, void *data)
- DUMP_WED(WED_RX_BM_INTF2),
- DUMP_WED(WED_RX_BM_INTF),
- DUMP_WED(WED_RX_BM_ERR_STS),
-+ DUMP_END()
-+ };
-+
-+ static const struct reg_dump regs_v2[] = {
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_R2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
-+ DUMP_WED(WED_RTQM_R2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
-+ DUMP_WED(WED_RTQM_Q2N_MIB),
-+ DUMP_WED(WED_RTQM_Q2B_MIB),
-+ DUMP_WED(WED_RTQM_PFDBK_MIB),
-+
-+ DUMP_END()
-+ };
-+
-+ static const struct reg_dump regs_v3[] = {
-+ DUMP_STR("WED RX RRO DATA"),
-+ DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
-+ DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
-+
-+ DUMP_STR("WED RX MSDU PAGE"),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
-+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
-+
-+ DUMP_STR("WED RX IND CMD"),
-+ DUMP_WED(WED_IND_CMD_RX_CTRL1),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
-+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
-+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
-+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
-+ WED_IND_CMD_PREFETCH_FREE_CNT),
-+ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
-+
-+ DUMP_STR("WED ADDR ELEM"),
-+ DUMP_WED(WED_ADDR_ELEM_CFG0),
-+ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
-+ WED_ADDR_ELEM_PREFETCH_FREE_CNT),
-+
-+ DUMP_STR("WED Route QM"),
-+ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT),
-+ DUMP_WED(WED_RTQM_ENQ_ERR_CNT),
-+
-+ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_PKT_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT),
-+ DUMP_WED(WED_RTQM_DEQ_ERR_CNT),
-+
-+ DUMP_END()
-+ };
-+
-+ static const struct reg_dump *regs_new_v2[] = {
-+ ®s_common[0],
-+ ®s_v2[0],
-+ NULL,
-+ };
-+
-+ static const struct reg_dump *regs_new_v3[] = {
-+ ®s_common[0],
-+ ®s_v3[0],
-+ NULL,
- };
-
- struct mtk_wed_hw *hw = s->private;
- struct mtk_wed_device *dev = hw->wed_dev;
-+ const struct reg_dump **regs;
-
- if (!dev)
- return 0;
-
-- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
-+ switch(dev->hw->version) {
-+ case 2:
-+ regs = regs_new_v2;
-+ break;
-+ case 3:
-+ regs = regs_new_v3;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ dump_wed_regs(s, dev, regs);
-
- return 0;
- }
-@@ -248,6 +357,383 @@ mtk_wed_reg_get(void *data, u64 *val)
- DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
- "0x%08llx\n");
-
-+static int
-+wed_token_txd_show(struct seq_file *s, void *data)
-+{
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+ struct dma_page_info *page_list = dev->tx_buf_ring.pages;
-+ int token = dev->wlan.token_start;
-+ u32 val = hw->token_id, size = 1;
-+ int page_idx = (val - token) / 2;
-+ int i;
-+
-+ if (val < token) {
-+ size = val;
-+ page_idx = 0;
-+ }
-+
-+ for (i = 0; i < size; i += MTK_WED_BUF_PER_PAGE) {
-+ void *page = page_list[page_idx++].addr;
-+ void *buf;
-+ int j;
-+
-+ if (!page)
-+ break;
-+
-+ buf = page_to_virt(page);
-+
-+ for (j = 0; j < MTK_WED_BUF_PER_PAGE; j++) {
-+ printk("[TXD]:token id = %d\n", token + 2 * (page_idx - 1) + j);
-+ print_hex_dump(KERN_ERR , "", DUMP_PREFIX_OFFSET, 16, 1, (u8 *)buf, 128, false);
-+ seq_printf(s, "\n");
-+
-+ buf += MTK_WED_BUF_SIZE;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+DEFINE_SHOW_ATTRIBUTE(wed_token_txd);
-+
-+static int
-+wed_pao_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs_common[] = {
-+ DUMP_STR("PAO AMDSU INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_FIFO_DMAD),
-+
-+ DUMP_STR("PAO AMDSU ENG0 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(0)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(0)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(0)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(0)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(0)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(0),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(0),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(0),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(0),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(0),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG1 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(1)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(1)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(1)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(1)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(1)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(1),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(1),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(1),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG2 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(2)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(2)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(2)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(2)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(2)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(2),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(2),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG3 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(3)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(3)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(3)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(3)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(3)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(3),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(3),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(3),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(3),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(3),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG4 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(4)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(4)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(4)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(4)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(4)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(4),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(4),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG5 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(5)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(5)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(5)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(5)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(5)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(5),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(5),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(5),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(5),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(5),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG6 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(6)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(6)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(6)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(6)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(6)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(6),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(6),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(6),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(6),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(6),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG7 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(7)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(7)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(7)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(7)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(7)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(7),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(7),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(7),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(7),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO AMDSU ENG8 INFO"),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(8)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(8)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(8)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(8)),
-+ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(8)),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(8),
-+ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(8),
-+ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(8),
-+ WED_PAO_AMSDU_ENG_CUR_ENTRY),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(8),
-+ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
-+ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(8),
-+ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
-+
-+ DUMP_STR("PAO QMEM INFO"),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(0), WED_PAO_QMEM_FQ_CNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(0), WED_PAO_QMEM_SP_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(1), WED_PAO_QMEM_TID0_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(1), WED_PAO_QMEM_TID1_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(2), WED_PAO_QMEM_TID2_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(2), WED_PAO_QMEM_TID3_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(3), WED_PAO_QMEM_TID4_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(3), WED_PAO_QMEM_TID5_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(4), WED_PAO_QMEM_TID6_QCNT),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(4), WED_PAO_QMEM_TID7_QCNT),
-+
-+
-+ DUMP_STR("PAO QMEM HEAD INFO"),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(0), WED_PAO_QMEM_FQ_HEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(0), WED_PAO_QMEM_SP_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(1), WED_PAO_QMEM_TID0_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(1), WED_PAO_QMEM_TID1_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(2), WED_PAO_QMEM_TID2_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(2), WED_PAO_QMEM_TID3_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(3), WED_PAO_QMEM_TID4_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(3), WED_PAO_QMEM_TID5_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(4), WED_PAO_QMEM_TID6_QHEAD),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(4), WED_PAO_QMEM_TID7_QHEAD),
-+
-+ DUMP_STR("PAO QMEM TAIL INFO"),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(5), WED_PAO_QMEM_FQ_TAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(5), WED_PAO_QMEM_SP_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(6), WED_PAO_QMEM_TID0_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(6), WED_PAO_QMEM_TID1_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(7), WED_PAO_QMEM_TID2_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(7), WED_PAO_QMEM_TID3_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(8), WED_PAO_QMEM_TID4_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(8), WED_PAO_QMEM_TID5_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(9), WED_PAO_QMEM_TID6_QTAIL),
-+ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(9), WED_PAO_QMEM_TID7_QTAIL),
-+
-+ DUMP_STR("PAO HIFTXD MSDU INFO"),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(1)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(2)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(3)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(4)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(5)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(6)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(7)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(8)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(9)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(10)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(11)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(12)),
-+ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(13)),
-+ DUMP_END()
-+ };
-+
-+ static const struct reg_dump *regs[] = {
-+ ®s_common[0],
-+ NULL,
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev)
-+ return 0;
-+
-+ dump_wed_regs(s, dev, regs);
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_pao);
-+
-+static int
-+wed_rtqm_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs_common[] = {
-+ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"),
-+ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT),
-+
-+
-+ DUMP_STR("WED Route QM IGRS1(Legacy)"),
-+ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS2(RRO3.0)"),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT),
-+
-+ DUMP_STR("WED Route QM IGRS3(DEBUG)"),
-+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)),
-+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)),
-+ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT),
-+
-+ DUMP_END()
-+ };
-+
-+ static const struct reg_dump *regs[] = {
-+ ®s_common[0],
-+ NULL,
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev)
-+ return 0;
-+
-+ dump_wed_regs(s, dev, regs);
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
-+
-+
-+static int
-+wed_rro_show(struct seq_file *s, void *data)
-+{
-+ static const struct reg_dump regs_common[] = {
-+ DUMP_STR("RRO/IND CMD CNT"),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(1)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(2)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(3)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(4)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(5)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(6)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(7)),
-+ DUMP_WED(WED_RX_IND_CMD_CNT(8)),
-+ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9),
-+ WED_IND_CMD_MAGIC_CNT_FAIL_CNT),
-+
-+ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)),
-+ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1),
-+ WED_ADDR_ELEM_SIG_FAIL_CNT),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(1)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(2)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(3)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(4)),
-+ DUMP_WED(WED_RX_MSDU_PG_CNT(5)),
-+ DUMP_WED_MASK(WED_RX_PN_CHK_CNT,
-+ WED_PN_CHK_FAIL_CNT),
-+
-+ DUMP_END()
-+ };
-+
-+ static const struct reg_dump *regs[] = {
-+ ®s_common[0],
-+ NULL,
-+ };
-+ struct mtk_wed_hw *hw = s->private;
-+ struct mtk_wed_device *dev = hw->wed_dev;
-+
-+ if (!dev)
-+ return 0;
-+
-+ dump_wed_regs(s, dev, regs);
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(wed_rro);
-+
- void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
- {
- struct dentry *dir;
-@@ -261,8 +747,18 @@ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
- debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
- debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
- debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
-- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
-- if (hw->ver != MTK_WED_V1) {
-+ debugfs_create_u32("token_id", 0600, dir, &hw->token_id);
-+ debugfs_create_file_unsafe("token_txd", 0600, dir, hw, &wed_token_txd_fops);
-+
-+ if (hw->version == 3)
-+ debugfs_create_file_unsafe("pao", 0400, dir, hw, &wed_pao_fops);
-+
-+ if (hw->version != 1) {
-+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
-+ if (hw->version == 3) {
-+ debugfs_create_file_unsafe("rtqm", 0400, dir, hw, &wed_rtqm_fops);
-+ debugfs_create_file_unsafe("rro", 0400, dir, hw, &wed_rro_fops);
-+ }
- wed_wo_mcu_debugfs(hw, dir);
- }
- }
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-index b5a86f6..c2d060b 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -245,8 +245,7 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
- if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
- mcu = MT7981_FIRMWARE_WO;
- else
-- mcu = wo->hw->index ? MT7986_FIRMWARE_WO_2 :
-- MT7986_FIRMWARE_WO_1;
-+ mcu = wo->hw->index ? MTK_FIRMWARE_WO_1 : MTK_FIRMWARE_WO_0;
-
- ret = request_firmware(&fw, mcu, wo->hw->dev);
- if (ret)
-@@ -293,8 +292,12 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
- }
-
- /* write the start address */
-- boot_cr = wo->hw->index ?
-- WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR : WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+ if (wo->hw->version == 3)
-+ boot_cr = WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+ else
-+ boot_cr = wo->hw->index ?
-+ WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR : WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
-+
- wo_w32(wo, boot_cr, (wo->region[WO_REGION_EMI].addr_pa >> 16));
-
- /* wo firmware reset */
-@@ -302,8 +305,7 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
-
- val = wo_r32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
-
-- val |= wo->hw->index ? WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WA_CPU_RSTB_MASK :
-- WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
-+ val |= WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
-
- wo_w32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
-
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
-index dbb17ae..a533b6e 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
-@@ -17,8 +17,9 @@
- #define WARP_ALREADY_DONE_STATUS (1)
-
- #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
--#define MT7986_FIRMWARE_WO_1 "mediatek/mt7986_wo_0.bin"
--#define MT7986_FIRMWARE_WO_2 "mediatek/mt7986_wo_1.bin"
-+#define MTK_FIRMWARE_WO_0 "mediatek/mtk_wo_0.bin"
-+#define MTK_FIRMWARE_WO_1 "mediatek/mtk_wo_1.bin"
-+#define MTK_FIRMWARE_WO_2 "mediatek/mtk_wo_2.bin"
-
- #define WOCPU_EMI_DEV_NODE "mediatek,wocpu_emi"
- #define WOCPU_ILM_DEV_NODE "mediatek,wocpu_ilm"
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index 403a36b..25be547 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -20,6 +20,9 @@
- #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
- #define MTK_WED_RX_BM_TOKEN GENMASK(31, 16)
-
-+#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29)
-+#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31)
-+
- struct mtk_wdma_desc {
- __le32 buf0;
- __le32 ctrl;
-@@ -51,6 +54,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
- #define MTK_WED_RESET_RX_RRO_QM BIT(20)
- #define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
-+#define MTK_WED_RESET_TX_PAO BIT(22)
- #define MTK_WED_RESET_WED BIT(31)
-
- #define MTK_WED_CTRL 0x00c
-@@ -58,6 +62,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1)
- #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2)
- #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
-+#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7)
- #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
- #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
-@@ -68,9 +75,14 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
- #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
- #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
-+#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20)
-+#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21)
-+#define MTK_WED_CTRL_TX_PAO_EN BIT(22)
-+#define MTK_WED_CTRL_TX_PAO_BUSY BIT(23)
- #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_CTRL_FLD_MIB_RD_CLR BIT(28)
-
- #define MTK_WED_EXT_INT_STATUS 0x020
- #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0)
-@@ -78,12 +90,10 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4)
- #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8)
- #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9)
--#if defined(CONFIG_MEDIATEK_NETSYS_V2)
--#define MTK_WED_EXT_INT_STATUS_TX_TKID_LO_TH BIT(10)
--#define MTK_WED_EXT_INT_STATUS_TX_TKID_HI_TH BIT(11)
--#endif
--#define MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY BIT(12)
--#define MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER BIT(13)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH2 BIT(10)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH2 BIT(11)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
-+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
- #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
-@@ -100,17 +110,15 @@ struct mtk_wdma_desc {
- #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
- MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
- MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
-- MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY | \
-- MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER | \
- 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_DMA_R_RESP_ERR | \
-- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR)
-+ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR)
-
- #define MTK_WED_EXT_INT_MASK 0x028
- #define MTK_WED_EXT_INT_MASK1 0x02c
- #define MTK_WED_EXT_INT_MASK2 0x030
-+#define MTK_WED_EXT_INT_MASK3 0x034
-
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-@@ -118,9 +126,14 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_BM_CTRL 0x080
- #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-+#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26)
-+#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27)
- #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28)
-
- #define MTK_WED_TX_BM_BASE 0x084
-+#define MTK_WED_TX_BM_INIT_PTR 0x088
-+#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0)
-+#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16)
-
- #define MTK_WED_TX_BM_BUF_LEN 0x08c
-
-@@ -134,22 +147,24 @@ struct mtk_wdma_desc {
- #if defined(CONFIG_MEDIATEK_NETSYS_V2)
- #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(8, 0)
- #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(24, 16)
--
--#define MTK_WED_TX_BM_TKID 0x0c8
--#define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
--#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
- #else
- #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0)
- #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16)
-+#endif
-
--#define MTK_WED_TX_BM_TKID 0x088
-+#define MTK_WED_TX_BM_TKID 0x0c8
- #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
- #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
--#endif
-
- #define MTK_WED_TX_TKID_CTRL 0x0c0
-+#if defined(CONFIG_MEDIATEK_NETSYS_V3)
-+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(7, 0)
-+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(23, 16)
-+#else
- #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-+#endif
-+
- #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-
- #define MTK_WED_TX_TKID_DYN_THR 0x0e0
-@@ -220,12 +235,15 @@ struct mtk_wdma_desc {
- #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_EVENT_PKT_FMT_VER GENMASK(15, 12)
-+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18)
- #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_DRV_EVENT_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_DDONE_CHK_LAST BIT(25)
- #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28)
-+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30)
-
- /* CONFIG_MEDIATEK_NETSYS_V1 */
- #define MTK_WED_WPDMA_GLO_CFG_RX_BT_SIZE GENMASK(5, 4)
-@@ -288,9 +306,11 @@ struct mtk_wdma_desc {
- #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_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
-+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
-+#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21)
-+
- #define MTK_WED_WPDMA_CFG_BASE 0x580
- #define MTK_WED_WPDMA_CFG_INT_MASK 0x584
- #define MTK_WED_WPDMA_CFG_TX 0x588
-@@ -319,20 +339,50 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-
- #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
--#define MTK_WED_WPDMA_RX_RING 0x770
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#define MTK_WED_WPDMA_RX_RING0 0x770
-+#else
-+#define MTK_WED_WPDMA_RX_RING0 0x7d0
-+#endif
-+#define MTK_WED_WPDMA_RX_RING1 0x7d8
-
- #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
- #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
- #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
-
-+#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
-+#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
-+#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8
-+#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15)
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc
-+
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16)
-+
- #define MTK_WED_WDMA_RING_TX 0x800
-
- #define MTK_WED_WDMA_TX_MIB 0x810
-
--
- #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
- #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
-
-+#define MTK_WED_WDMA_RX_PREF_CFG 0x950
-+#define MTK_WED_WDMA_RX_PREF_EN BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
-+#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
-+#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
-+#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
-+#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
-+
-+#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
-+#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16)
-+
- #define MTK_WED_WDMA_GLO_CFG 0xa04
- #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
- #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
-@@ -365,6 +415,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
-
- #define MTK_WED_WDMA_INT_CTRL 0xa2c
-+#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0)
- #define MTK_WED_WDMA_INT_POLL_SRC_SEL GENMASK(17, 16)
-
- #define MTK_WED_WDMA_CFG_BASE 0xaa0
-@@ -426,6 +477,18 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_INT_GRP1 0x250
- #define MTK_WDMA_INT_GRP2 0x254
-
-+#define MTK_WDMA_PREF_TX_CFG 0x2d0
-+#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
-+
-+#define MTK_WDMA_PREF_RX_CFG 0x2dc
-+#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
-+
-+#define MTK_WDMA_WRBK_TX_CFG 0x300
-+#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
-+
-+#define MTK_WDMA_WRBK_RX_CFG 0x344
-+#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
-+
- #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
- #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
- #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-@@ -439,6 +502,31 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
- #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-
-+#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
-+#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
-+#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34
-+
-+
-+#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44
-+#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50
-+#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54+ (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c
-+
-+#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c
-+#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78
-+#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c+ (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84
-+
-+#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94
-+#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0
-+#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4+ (_n) * 0x4)
-+#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac
-+
- #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
- #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
- #define MTK_WED_RTQM_Q2N_MIB 0xb80
-@@ -447,6 +535,24 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q2B_MIB 0xb8c
- #define MTK_WED_RTQM_PFDBK_MIB 0xb90
-
-+#define MTK_WED_RTQM_ENQ_CFG0 0xbb8
-+#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12)
-+
-+#define MTK_WED_RTQM_FDROP_MIB 0xb84
-+#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc
-+#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0
-+#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4
-+#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8
-+#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc
-+#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0
-+
-+#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8
-+#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc
-+#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0
-+#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4
-+#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8
-+#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec
-+
- #define MTK_WED_RROQM_GLO_CFG 0xc04
- #define MTK_WED_RROQM_RST_IDX 0xc08
- #define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
-@@ -487,8 +593,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RX_BM_BASE 0xd84
- #define MTK_WED_RX_BM_INIT_PTR 0xd88
- #define MTK_WED_RX_BM_PTR 0xd8c
--#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
- #define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0)
-+#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
-
- #define MTK_WED_RX_BM_BLEN 0xd90
- #define MTK_WED_RX_BM_STS 0xd94
-@@ -496,7 +602,193 @@ struct mtk_wdma_desc {
- #define MTK_WED_RX_BM_INTF 0xd9c
- #define MTK_WED_RX_BM_ERR_STS 0xda8
-
-+#define MTK_RRO_IND_CMD_SIGNATURE 0xe00
-+#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0)
-+#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28)
-+
-+#define MTK_WED_IND_CMD_RX_CTRL0 0xe04
-+#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0)
-+#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16)
-+#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28)
-+
-+#define MTK_WED_IND_CMD_RX_CTRL1 0xe08
-+#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c
-+#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0)
-+#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16)
-+
-+#define MTK_WED_RRO_CFG0 0xe10
-+#define MTK_WED_RRO_CFG1 0xe14
-+#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29)
-+#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16)
-+#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0)
-+
-+#define MTK_WED_ADDR_ELEM_CFG0 0xe18
-+#define MTK_WED_ADDR_ELEM_CFG1 0xe1c
-+#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16)
-+
-+#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20
-+#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0)
-+#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28)
-+#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29)
-+#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30)
-+#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31)
-+
-+#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24
-+#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28
-+
-+#define MTK_WED_PN_CHECK_CFG 0xe30
-+#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0)
-+#define MTK_WED_PN_CHECK_RD_RDY BIT(28)
-+#define MTK_WED_PN_CHECK_WR_RDY BIT(29)
-+#define MTK_WED_PN_CHECK_RD BIT(30)
-+#define MTK_WED_PN_CHECK_WR BIT(31)
-+
-+#define MTK_WED_PN_CHECK_WDATA_M 0xe38
-+#define MTK_WED_PN_CHECK_IS_FIRST BIT(17)
-+
-+#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8)
-+
-+#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58
-+#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26)
-+#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31)
-+
-+#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc)
-+#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc)
-+#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc)
-+
-+#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10)
-+
-+#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13)
-+
-+#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4)
-+#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26)
-+#define MTK_WED_RRO_RX_D_DRV_EN BIT(31)
-+
-+#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0
-+#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0)
-+
-+#define MTK_WED_RRO_PG_BM_BASE 0xeb4
-+#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8
-+#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0)
-+#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10)
-+
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
-+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
-+
-+#define MTK_WED_RX_IND_CMD_CNT0 0xf20
-+#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
-+
-+#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4)
-+#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0)
-+
-+#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4)
-+#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0)
-+#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16)
-+#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0)
-+
-+#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4)
-+
-+#define MTK_WED_RX_PN_CHK_CNT 0xf70
-+#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0)
-+
- #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
- #define MTK_WED_PCIE_INT_MASK 0x0
-
-+#define MTK_WED_PAO_AMSDU_FIFO 0x1800
-+#define MTK_WED_PAO_AMSDU_IS_PRIOR0_RING BIT(10)
-+
-+#define MTK_WED_PAO_STA_INFO 0x01810
-+#define MTK_WED_PAO_STA_INFO_DO_INIT BIT(0)
-+#define MTK_WED_PAO_STA_INFO_SET_INIT BIT(1)
-+
-+#define MTK_WED_PAO_STA_INFO_INIT 0x01814
-+#define MTK_WED_PAO_STA_WTBL_HDRT_MODE BIT(0)
-+#define MTK_WED_PAO_STA_RMVL BIT(1)
-+#define MTK_WED_PAO_STA_MAX_AMSDU_LEN GENMASK(7, 2)
-+#define MTK_WED_PAO_STA_MAX_AMSDU_NUM GENMASK(11, 8)
-+
-+#define MTK_WED_PAO_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4)
-+
-+#define MTK_WED_PAO_PSE 0x1910
-+#define MTK_WED_PAO_PSE_RESET BIT(16)
-+
-+#define MTK_WED_PAO_HIFTXD_CFG 0x1968
-+#define MTK_WED_PAO_HIFTXD_SRC GENMASK(16, 15)
-+
-+#define MTK_WED_PAO_MON_AMSDU_FIFO_DMAD 0x1a34
-+
-+#define MTK_WED_PAO_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50)
-+#define MTK_WED_PAO_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50)
-+#define MTK_WED_PAO_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50)
-+#define MTK_WED_PAO_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50)
-+#define MTK_WED_PAO_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50)
-+
-+#define MTK_WED_PAO_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50)
-+#define MTK_WED_PAO_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0)
-+#define MTK_WED_PAO_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16)
-+
-+#define MTK_WED_PAO_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50)
-+#define MTK_WED_PAO_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0)
-+#define MTK_WED_PAO_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16)
-+#define MTK_WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24)
-+
-+#define MTK_WED_PAO_MON_QMEM_STS1 0x1e04
-+
-+#define MTK_WED_PAO_MON_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4)
-+#define MTK_WED_PAO_QMEM_FQ_CNT GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_SP_QCNT GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID0_QCNT GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID1_QCNT GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID2_QCNT GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID3_QCNT GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID4_QCNT GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID5_QCNT GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID6_QCNT GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID7_QCNT GENMASK(11, 0)
-+
-+#define MTK_WED_PAO_MON_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4)
-+#define MTK_WED_PAO_QMEM_FQ_HEAD GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_SP_QHEAD GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID0_QHEAD GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID1_QHEAD GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID2_QHEAD GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID3_QHEAD GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID4_QHEAD GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID5_QHEAD GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID6_QHEAD GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID7_QHEAD GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_FQ_TAIL GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_SP_QTAIL GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID0_QTAIL GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID1_QTAIL GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID2_QTAIL GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID3_QTAIL GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID4_QTAIL GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID5_QTAIL GENMASK(11, 0)
-+#define MTK_WED_PAO_QMEM_TID6_QTAIL GENMASK(27, 16)
-+#define MTK_WED_PAO_QMEM_TID7_QTAIL GENMASK(11, 0)
-+
-+#define MTK_WED_PAO_MON_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4)
-+
-+#define MTK_WED_PCIE_BASE 0x11280000
-+
-+#define MTK_WED_PCIE_BASE0 0x11300000
-+#define MTK_WED_PCIE_BASE1 0x11310000
-+#define MTK_WED_PCIE_BASE2 0x11290000
- #endif
-diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index b2abebe..204051d 100644
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -880,6 +880,13 @@ struct net_device_path {
- u8 queue;
- u16 wcid;
- u8 bss;
-+ u32 usr_info;
-+ u8 tid;
-+ u8 is_fixedrate;
-+ u8 is_prior;
-+ u8 is_sp;
-+ u8 hf;
-+ u8 amsdu_en;
- } mtk_wdma;
- };
- };
-diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index 27cf284..92df4ba 100644
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -5,11 +5,14 @@
- #include <linux/rcupdate.h>
- #include <linux/regmap.h>
- #include <linux/pci.h>
-+#include <linux/skbuff.h>
-+#include <linux/iopoll.h>
-
- #define WED_WO_STA_REC 0x6
-
- #define MTK_WED_TX_QUEUES 2
- #define MTK_WED_RX_QUEUES 2
-+#define MTK_WED_RX_PAGE_QUEUES 3
-
- enum mtk_wed_wo_cmd {
- MTK_WED_WO_CMD_WED_CFG,
-@@ -55,10 +58,13 @@ enum mtk_wed_bus_tye {
- struct mtk_wed_hw;
- struct mtk_wdma_desc;
-
-+#define MTK_WED_RING_CONFIGURED BIT(0)
-+
- struct mtk_wed_ring {
- struct mtk_wdma_desc *desc;
- dma_addr_t desc_phys;
- int size;
-+ u32 flags;
-
- u32 reg_base;
- void __iomem *wpdma;
-@@ -69,11 +75,18 @@ struct mtk_rxbm_desc {
- __le32 token;
- } __packed __aligned(4);
-
-+struct dma_page_info {
-+ void *addr;
-+ dma_addr_t addr_phys;
-+};
-+
- struct dma_buf {
- int size;
-- void **pages;
-- struct mtk_wdma_desc *desc;
-+ int pkt_nums;
-+ void *desc;
-+ int desc_size;
- dma_addr_t desc_phys;
-+ struct dma_page_info *pages;
- };
-
- struct dma_entry {
-@@ -97,6 +110,7 @@ struct mtk_wed_device {
- struct device *dev;
- struct mtk_wed_hw *hw;
- bool init_done, running;
-+ bool wdma_init_done;
- int wdma_idx;
- int irq;
- u8 ver;
-@@ -108,7 +122,11 @@ struct mtk_wed_device {
- struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
- struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-
-- struct dma_buf buf_ring;
-+ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES];
-+ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES];
-+ struct mtk_wed_ring ind_cmd_ring;
-+
-+ struct dma_buf tx_buf_ring;
-
- struct {
- int size;
-@@ -117,6 +135,8 @@ struct mtk_wed_device {
- dma_addr_t desc_phys;
- } rx_buf_ring;
-
-+ struct dma_buf rx_page_buf_ring;
-+
- struct {
- struct mtk_wed_ring rro_ring;
- void __iomem *rro_desc;
-@@ -131,8 +151,9 @@ struct mtk_wed_device {
- struct platform_device *platform_dev;
- struct pci_dev *pci_dev;
- };
-+ enum mtk_wed_bus_tye bus_type;
- void __iomem *base;
-- u32 bus_type;
-+ void __iomem *regs;
- u32 phy_base;
-
- u32 wpdma_phys;
-@@ -141,10 +162,14 @@ struct mtk_wed_device {
- u32 wpdma_tx;
- u32 wpdma_txfree;
- u32 wpdma_rx_glo;
-- u32 wpdma_rx;
-+ u32 wpdma_rx[MTK_WED_RX_QUEUES];
-+ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
-+ u32 wpdma_rx_pg;
-
- u8 tx_tbit[MTK_WED_TX_QUEUES];
- u8 rx_tbit[MTK_WED_RX_QUEUES];
-+ u8 rro_rx_tbit[MTK_WED_RX_QUEUES];
-+ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES];
- u8 txfree_tbit;
-
- u16 token_start;
-@@ -154,12 +179,26 @@ struct mtk_wed_device {
- unsigned int rx_size;
-
- bool wcid_512;
--
-+ bool hwrro;
-+ bool msi;
-+
-+ u8 max_amsdu_nums;
-+ u32 max_amsdu_len;
-+
-+ struct {
-+ u8 se_group_nums;
-+ u16 win_size;
-+ u16 particular_sid;
-+ u32 ack_sn_addr;
-+ dma_addr_t particular_se_phys;
-+ dma_addr_t addr_elem_phys[1024];
-+ } ind_cmd;
-+
-+ u32 chip_id;
- 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);
-- u32 (*init_rx_buf)(struct mtk_wed_device *wed,
-- int pkt_num);
-+ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size);
- void (*release_rx_buf)(struct mtk_wed_device *wed);
- void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
- struct mtk_wed_wo_rx_stats *stats);
-@@ -180,6 +219,11 @@ struct mtk_wed_ops {
- void __iomem *regs);
- int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs, bool reset);
-+ int (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ int (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
-+ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev, void __iomem *regs);
- int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
- void *data, int len);
- void (*detach)(struct mtk_wed_device *dev);
-@@ -196,6 +240,7 @@ struct mtk_wed_ops {
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
- void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
- u32 reason, u32 hash);
-+ void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask);
- };
-
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -224,12 +269,21 @@ static inline bool
- mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
- {
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ if (dev->ver == 3 && !dev->wlan.hwrro)
-+ return false;
-+
- return dev->ver != 1;
- #else
- return false;
- #endif
- }
-
-+static inline bool
-+mtk_wed_device_support_pao(struct mtk_wed_device *dev)
-+{
-+ return dev->ver == 3;
-+}
-+
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- #define mtk_wed_device_active(_dev) !!(_dev)->ops
- #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
-@@ -243,6 +297,12 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
- (_dev)->ops->txfree_ring_setup(_dev, _regs)
- #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
-+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \
-+ (_dev)->ops->ind_rx_ring_setup(_dev, _regs)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
- (_dev)->ops->msg_update(_dev, _id, _msg, _len)
- #define mtk_wed_device_reg_read(_dev, _reg) \
-@@ -257,6 +317,9 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
- (_dev)->ops->reset_dma(_dev)
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
- (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
-+#define mtk_wed_device_start_hwrro(_dev, _mask) \
-+ (_dev)->ops->start_hwrro(_dev, _mask)
-+
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- {
-@@ -268,6 +331,9 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
- #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
- #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
-+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
- #define mtk_wed_device_reg_read(_dev, _reg) 0
- #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
- #define mtk_wed_device_irq_get(_dev, _mask) 0
-@@ -275,6 +341,7 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- #define mtk_wed_device_dma_reset(_dev) do {} while (0)
- #define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) do {} while (0)
- #define mtk_wed_device_ppe_check(_dev, _hash) do {} while (0)
-+#define mtk_wed_device_start_hwrro(_dev, _mask) do {} while (0)
- #endif
-
- #endif
---
-2.18.0
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3020-mtk-wed-add-wed3-ser-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3020-mtk-wed-add-wed3-ser-support.patch
deleted file mode 100644
index 328a4bc..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3020-mtk-wed-add-wed3-ser-support.patch
+++ /dev/null
@@ -1,642 +0,0 @@
-From f0b9f017b170690be346d3e08371fdadca0d59d3 Mon Sep 17 00:00:00 2001
-From: mtk27745 <rex.lu@mediatek.com>
-Date: Mon, 18 Sep 2023 13:22:44 +0800
-Subject: [PATCH] mtk wed add wed3 ser support
-
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 260 +++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 73 +++++-
- include/linux/soc/mediatek/mtk_wed.h | 6 +-
- 3 files changed, 310 insertions(+), 29 deletions(-)
-
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 561fc6c..f20a4ae 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -99,16 +99,70 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- u32 status;
- u32 mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
- int busy, i;
-+ u32 value;
-
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
- busy = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-- !(status & mask), 0, 10000);
-+ !(status & mask), 0, 10000);
-
-+ if (dev->hw->version == 3) {
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_PREF_TX_CFG);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_PREF_RX_CFG);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_WRBK_TX_CFG);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_WRBK_RX_CFG);
-+
-+ /* Prefetch FIFO */
-+ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
-+
-+ /* Core FIFO */
-+ value = (MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
-+
-+ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, value);
-+ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, value);
-+
-+ /* Writeback FIFO */
-+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
-+
-+ /* Prefetch ring status */
-+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
-+ /* Writeback ring status */
-+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
-+ }
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
-- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-- if (!dev->rx_wdma[i].desc) {
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-+ if (!dev->tx_wdma[i].desc) {
- wdma_w32(dev, MTK_WDMA_RING_RX(i) +
- MTK_WED_RING_OFS_CPU_IDX, 0);
- }
-@@ -121,16 +175,65 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev)
- {
- u32 status;
- u32 mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
-- int i;
-+ int busy, i;
-+ u32 value;
-
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
- !(status & mask), 0, 10000))
- WARN_ON_ONCE(1);
-
-+ if (dev->hw->version == 3) {
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
-+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_PREF_TX_CFG);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_PREF_RX_CFG);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
-+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_WRBK_TX_CFG);
-+ busy = read_poll_timeout(wdma_r32, status,
-+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), 0, 10000,
-+ false, dev, MTK_WDMA_WRBK_RX_CFG);
-+
-+ /* Prefetch FIFO */
-+ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
-+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
-+ /* Core FIFO */
-+ value = (MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
-+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
-+
-+ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, value);
-+ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, value);
-+ /* Writeback FIFO */
-+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
-+
-+ /* Prefetch ring status */
-+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
-+ /* Writeback ring status */
-+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
-+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
-+ }
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
- wdma_w32(dev, MTK_WDMA_RING_TX(i) +
- MTK_WED_RING_OFS_CPU_IDX, 0);
- }
-@@ -913,7 +1016,7 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
-
- wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
-- //wdma_w32(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
-+ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
- if (mtk_wed_get_rx_capa(dev)) {
- wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
- MTK_WED_WPDMA_RX_D_PREF_EN |
-@@ -1476,13 +1579,30 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
- mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
- &state, sizeof(state), true);
-
-+ if (dev->wlan.hwrro) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS,
-+ MTK_WED_RX_IND_CMD_BUSY);
-+ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG);
-+ }
- wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
- busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
- MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
-+ if (dev->hw->version == 3)
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_BUSY);
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
- } else {
-+ if (dev->hw->version == 3) {
-+ /*1.a. Disable Prefetch HW*/
-+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, MTK_WED_WPDMA_RX_D_PREF_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
-+ MTK_WED_WPDMA_RX_D_PREF_BUSY);
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL);
-+ }
- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
- MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
- MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-@@ -1510,6 +1630,24 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
- wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
- }
-
-+ if (dev->wlan.hwrro) {
-+ /* Disable RRO MSDU Page Drv */
-+ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
-+
-+ /* Disable RRO Data Drv */
-+ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
-+
-+ /* RRO MSDU Page Drv Reset */
-+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
-+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
-+
-+ /* RRO Data Drv Reset */
-+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_CLR);
-+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2),
-+ MTK_WED_RRO_RX_D_DRV_CLR);
-+ }
-+
- /* reset route qm */
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
- busy = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-@@ -1517,8 +1655,13 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
- } else {
-- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-- MTK_WED_RTQM_Q_RST);
-+ if (dev->hw->version == 3) {
-+ wed_set(dev, MTK_WED_RTQM_RST, BIT(0));
-+ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0));
-+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
-+ } else
-+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
-+ MTK_WED_RTQM_Q_RST);
- }
-
- /* reset tx wdma */
-@@ -1526,8 +1669,13 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
-
- /* reset tx wdma drv */
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
-- mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
-+ if (dev->hw->version == 3)
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS,
-+ MTK_WED_WPDMA_STATUS_TX_DRV);
-+ else
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
-+
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
-
- /* reset wed rx dma */
-@@ -1545,9 +1693,17 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
- /* reset rx bm */
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
- mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WED_RX_BM_BUSY);
-+ MTK_WED_CTRL_WED_RX_BM_BUSY);
- mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
-
-+ if (dev->wlan.hwrro) {
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_PG_BM_BUSY);
-+ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
-+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
-+ }
-+
- /* wo change to enable state */
- state = WO_STATE_ENABLE;
- mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
-@@ -1564,6 +1720,9 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
- }
-
- mtk_wed_free_rx_buffer(dev);
-+
-+ if (dev->wlan.hwrro)
-+ mtk_wed_rx_page_free_buffer(dev);
- }
-
-
-@@ -1597,18 +1756,54 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
-
- /* 2. Reset WDMA Rx DMA/Driver_Engine */
- busy = !!mtk_wdma_rx_reset(dev);
-+ if (dev->hw->version == 3) {
-+ val = wed_r32(dev, MTK_WED_WDMA_GLO_CFG);
-+ val |= MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-+ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN;
-+ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val);
-+ } else
-+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-
-- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
- busy = !!(busy ||
- mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY));
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY));
-+ if (dev->hw->version == 3)
-+ busy = !!(busy ||
-+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_BUSY));
-
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
- } else {
-+ if (dev->hw->version == 3) {
-+ /*1.a. Disable Prefetch HW*/
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
-+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_BUSY);
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_DDONE2_EN);
-+
-+ /* reset prefetch index */
-+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
-+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
-+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
-+
-+ /* reset prefetch FIFO */
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
-+ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
-+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
-+ /*2. Reset dma index*/
-+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
-+ MTK_WED_WDMA_RESET_IDX_RX_ALL);
-+ }
- wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
-- MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV);
-+ MTK_WED_WDMA_RESET_IDX_RX |
-+ MTK_WED_WDMA_RESET_IDX_DRV);
- wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0);
-
- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-@@ -1623,9 +1818,15 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
- for (i = 0; i < 100; i++) {
-- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
-- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-- break;
-+ if (dev->ver > MTK_WED_V1) {
-+ val = wed_r32(dev, MTK_WED_TX_TKID_INTF);
-+ if (FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP, val) == 0x40)
-+ break;
-+ } else {
-+ val = wed_r32(dev, MTK_WED_TX_BM_INTF);
-+ if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
-+ break;
-+ }
- }
- mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
-
-@@ -1634,18 +1835,20 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
-
- /* 4. Reset WED WPDMA Tx Driver Engine */
- busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-
- busy = !!(busy ||
- mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY));
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY));
- if (busy) {
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
- mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV);
-+ if (dev->hw->version == 3)
-+ wed_w32(dev, MTK_WED_RX1_CTRL2, 0);
- } else {
- wed_w32(dev, MTK_WED_WPDMA_RESET_IDX,
- MTK_WED_WPDMA_RESET_IDX_TX |
-@@ -1658,11 +1861,17 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
- }
- }
-
-- if (dev->ver > MTK_WED_V1) {
-- dev->init_done = false;
-- mtk_wed_rx_reset(dev);
-+ dev->init_done = false;
-+
-+ if (dev->hw->version == 3) {
-+ /*reset wed pao*/
-+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN);
-+ mtk_wed_reset(dev, MTK_WED_RESET_TX_PAO);
- }
-
-+ if (mtk_wed_get_rx_capa(dev))
-+ mtk_wed_rx_reset(dev);
-+
- }
-
- static int
-@@ -1875,7 +2084,7 @@ mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
- }
-
- static void
--mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask)
-+mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask, bool reset)
- {
- int idx, ret;
-
-@@ -1885,6 +2094,11 @@ mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask)
- if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hwrro)
- return;
-
-+ if (reset) {
-+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
-+ return;
-+ }
-+
- wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
- wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
-
-diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index 25be547..4379dc4 100644
---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -42,6 +42,8 @@ struct mtk_wdma_desc {
- #define MTK_WED_RESET 0x008
- #define MTK_WED_RESET_TX_BM BIT(0)
- #define MTK_WED_RESET_RX_BM BIT(1)
-+#define MTK_WED_RESET_RX_PG_BM BIT(2)
-+#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3)
- #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
- #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
- #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
-@@ -64,7 +66,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
- #define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
- #define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
--#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7)
-+#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7)
- #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
- #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
- #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
-@@ -123,6 +125,10 @@ struct mtk_wdma_desc {
- #define MTK_WED_STATUS 0x060
- #define MTK_WED_STATUS_TX GENMASK(15, 8)
-
-+#define MTK_WED_WPDMA_STATUS 0x068
-+#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8)
-+
-+
- #define MTK_WED_TX_BM_CTRL 0x080
- #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
- #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
-@@ -167,6 +173,9 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
-
-+#define MTK_WED_TX_TKID_INTF 0x0dc
-+#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16)
-+
- #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)
-@@ -203,10 +212,11 @@ struct mtk_wdma_desc {
- #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31)
-
- #define MTK_WED_RESET_IDX 0x20c
--#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
--#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-+#define MTK_WED_RESET_IDX_TX GENMASK(1, 0)
- #define MTK_WED_RESET_IDX_RX GENMASK(7, 6)
- #else
-+#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
- #define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
- #endif
- #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
-@@ -221,6 +231,7 @@ struct mtk_wdma_desc {
- #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
-
- #define MTK_WED_SCR0 0x3c0
-+#define MTK_WED_RX1_CTRL2 0x418
- #define MTK_WED_WPDMA_INT_TRIGGER 0x504
- #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
- #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
-@@ -336,6 +347,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
- #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
-+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20)
- #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
-
- #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
-@@ -352,6 +364,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
- #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
-+#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1)
- #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
- #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
-
-@@ -373,11 +386,13 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WDMA_RX_PREF_CFG 0x950
- #define MTK_WED_WDMA_RX_PREF_EN BIT(0)
-+#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1)
- #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
- #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
- #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
- #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
- #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
-+#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27)
-
- #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
- #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
-@@ -406,6 +421,7 @@ struct mtk_wdma_desc {
-
- #define MTK_WED_WDMA_RESET_IDX 0xa08
- #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
-+#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20)
- #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
-
- #define MTK_WED_WDMA_INT_CLR 0xa24
-@@ -474,21 +490,66 @@ struct mtk_wdma_desc {
- #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30)
- #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31)
-
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8)
-+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12)
-+
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18)
-+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21)
-+
-+
-+
- #define MTK_WDMA_INT_GRP1 0x250
- #define MTK_WDMA_INT_GRP2 0x254
-
- #define MTK_WDMA_PREF_TX_CFG 0x2d0
- #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
-+#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1)
-
- #define MTK_WDMA_PREF_RX_CFG 0x2dc
- #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
-+#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1)
-+
-+#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0
-+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0)
-+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16)
-+
-+#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4
-+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0)
-+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16)
-+
-+#define MTK_WDMA_PREF_SIDX_CFG 0x2e4
-+#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
-+#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
-
- #define MTK_WDMA_WRBK_TX_CFG 0x300
-+#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0)
- #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
-
-+#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4)
-+#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0)
-+
-+
- #define MTK_WDMA_WRBK_RX_CFG 0x344
-+#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0)
- #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
-
-+#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4)
-+#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0)
-+
-+
-+#define MTK_WDMA_WRBK_SIDX_CFG 0x388
-+#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
-+#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
-+
- #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
- #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
- #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
-@@ -502,6 +563,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
- #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
-
-+#define MTK_WED_RTQM_RST 0xb04
-+
-+
- #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
- #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
- #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
-@@ -691,6 +755,9 @@ struct mtk_wdma_desc {
- #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
- #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
-
-+#define MTK_WED_RRO_RX_HW_STS 0xf00
-+#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0)
-+
- #define MTK_WED_RX_IND_CMD_CNT0 0xf20
- #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
-
-diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index 92df4ba..1438692 100644
---- a/include/linux/soc/mediatek/mtk_wed.h
-+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -240,7 +240,7 @@ struct mtk_wed_ops {
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
- void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
- u32 reason, u32 hash);
-- void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask);
-+ void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask, bool reset);
- };
-
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -317,8 +317,8 @@ mtk_wed_device_support_pao(struct mtk_wed_device *dev)
- (_dev)->ops->reset_dma(_dev)
- #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
- (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
--#define mtk_wed_device_start_hwrro(_dev, _mask) \
-- (_dev)->ops->start_hwrro(_dev, _mask)
-+#define mtk_wed_device_start_hwrro(_dev, _mask, _reset) \
-+ (_dev)->ops->start_hwrro(_dev, _mask, _reset)
-
- #else
- static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
---
-2.18.0
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-2952-net-ethernet-mtk_eth_soc-modify-fq-size-4K.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-2952-net-ethernet-mtk_eth_soc-modify-fq-size-4K.patch
similarity index 100%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-2952-net-ethernet-mtk_eth_soc-modify-fq-size-4K.patch
rename to autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-2952-net-ethernet-mtk_eth_soc-modify-fq-size-4K.patch
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch
index 1ba25be..4a9bfae 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3001-mt7622-backport-nf-hw-offload-framework-and-upstream.patch
@@ -1,14 +1,14 @@
-From b80c745d2b90b30558e4f5b12060af956ae8e76d Mon Sep 17 00:00:00 2001
+From 35623475d9eb8522756b0b4833c95a31a0ceb10b Mon Sep 17 00:00:00 2001
From: Bo Jiao <Bo.Jiao@mediatek.com>
Date: Mon, 18 Sep 2023 10:52:27 +0800
-Subject: [PATCH 02/22] mt7622 backport nf hw offload framework and upstream
+Subject: [PATCH 01/24] mt7622 backport nf hw offload framework and upstream
hnat plus xt-FLOWOFFLOAD update v2
---
drivers/net/ethernet/mediatek/Makefile | 3 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 25 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 19 +-
- drivers/net/ethernet/mediatek/mtk_ppe.c | 510 +++++++
+ drivers/net/ethernet/mediatek/mtk_ppe.c | 514 +++++++
drivers/net/ethernet/mediatek/mtk_ppe.h | 288 ++++
.../net/ethernet/mediatek/mtk_ppe_debugfs.c | 214 +++
.../net/ethernet/mediatek/mtk_ppe_offload.c | 535 ++++++++
@@ -46,7 +46,7 @@
net/netfilter/nf_flow_table_ip.c | 447 +++---
net/netfilter/nf_flow_table_offload.c | 1199 +++++++++++++++++
net/netfilter/xt_FLOWOFFLOAD.c | 800 +++++++++++
- 41 files changed, 4995 insertions(+), 435 deletions(-)
+ 41 files changed, 4999 insertions(+), 435 deletions(-)
mode change 100644 => 100755 drivers/net/ethernet/mediatek/Makefile
mode change 100644 => 100755 drivers/net/ethernet/mediatek/mtk_eth_soc.c
mode change 100644 => 100755 drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -76,10 +76,10 @@
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
old mode 100644
new mode 100755
-index c4bea4d..9c85e16
+index 37fd338..20b2943
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3573,6 +3573,7 @@ static int mtk_open(struct net_device *dev)
+@@ -4001,6 +4001,7 @@ static int mtk_open(struct net_device *dev)
u32 id = mtk_mac2xgmii_id(eth, mac->id);
int err, i;
struct device_node *phy_node;
@@ -87,7 +87,7 @@
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
-@@ -3650,7 +3651,10 @@ static int mtk_open(struct net_device *dev)
+@@ -4085,7 +4086,10 @@ static int mtk_open(struct net_device *dev)
regmap_write(eth->sgmii->pcs[id].regmap,
SGMSYS_QPHY_PWR_STATE_CTRL, 0);
@@ -99,7 +99,7 @@
return 0;
}
-@@ -3730,6 +3734,9 @@ static int mtk_stop(struct net_device *dev)
+@@ -4172,6 +4176,9 @@ static int mtk_stop(struct net_device *dev)
mtk_dma_free(eth);
@@ -109,7 +109,7 @@
return 0;
}
-@@ -4576,6 +4583,7 @@ static const struct net_device_ops mtk_netdev_ops = {
+@@ -5081,6 +5088,7 @@ static const struct net_device_ops mtk_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = mtk_poll_controller,
#endif
@@ -117,7 +117,7 @@
};
static void mux_poll(struct work_struct *work)
-@@ -5161,6 +5169,17 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5711,6 +5719,17 @@ static int mtk_probe(struct platform_device *pdev)
goto err_free_dev;
}
@@ -135,7 +135,7 @@
for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i])
continue;
-@@ -5254,6 +5273,7 @@ static const struct mtk_soc_data mt2701_data = {
+@@ -5811,6 +5830,7 @@ static const struct mtk_soc_data mt2701_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
@@ -143,7 +143,7 @@
.rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
-@@ -5271,6 +5291,7 @@ static const struct mtk_soc_data mt7621_data = {
+@@ -5828,6 +5848,7 @@ static const struct mtk_soc_data mt7621_data = {
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -151,7 +151,7 @@
.rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
-@@ -5289,6 +5310,7 @@ static const struct mtk_soc_data mt7622_data = {
+@@ -5846,6 +5867,7 @@ static const struct mtk_soc_data mt7622_data = {
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -159,7 +159,7 @@
.rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
-@@ -5306,6 +5328,7 @@ static const struct mtk_soc_data mt7623_data = {
+@@ -5863,6 +5885,7 @@ static const struct mtk_soc_data mt7623_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
@@ -170,7 +170,7 @@
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
old mode 100644
new mode 100755
-index 8a9b615..a87e46d
+index 26a99d1..4d3a63c
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -15,6 +15,8 @@
@@ -182,7 +182,7 @@
#define MTK_QDMA_PAGE_SIZE 2048
#define MTK_MAX_RX_LENGTH 1536
-@@ -44,7 +46,8 @@
+@@ -47,7 +49,8 @@
NETIF_F_HW_VLAN_CTAG_TX | \
NETIF_F_SG | NETIF_F_TSO | \
NETIF_F_TSO6 | \
@@ -192,7 +192,7 @@
#define MTK_SET_FEATURES (NETIF_F_LRO | \
NETIF_F_HW_VLAN_CTAG_RX)
#define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
-@@ -127,6 +130,7 @@
+@@ -134,6 +137,7 @@
#define MTK_GDMA_UCS_EN BIT(20)
#define MTK_GDMA_STRP_CRC BIT(16)
#define MTK_GDMA_TO_PDMA 0x0
@@ -200,7 +200,7 @@
#define MTK_GDMA_DROP_ALL 0x7777
/* GDM Egress Control Register */
-@@ -617,6 +621,12 @@
+@@ -661,6 +665,12 @@
#define RX_DMA_TCI(_x) ((_x) & (VLAN_PRIO_MASK | VLAN_VID_MASK))
#define RX_DMA_VPID(_x) (((_x) >> 16) & 0xffff)
@@ -213,7 +213,7 @@
/* QDMA descriptor rxd4 */
#define RX_DMA_L4_VALID BIT(24)
#define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */
-@@ -1651,6 +1661,7 @@ struct mtk_soc_data {
+@@ -1712,6 +1722,7 @@ struct mtk_soc_data {
u64 caps;
u64 required_clks;
bool required_pctl;
@@ -221,7 +221,7 @@
netdev_features_t hw_features;
bool has_sram;
struct {
-@@ -1847,6 +1858,9 @@ struct mtk_eth {
+@@ -1912,6 +1923,9 @@ struct mtk_eth {
int ip_align;
spinlock_t syscfg0_lock;
struct timer_list mtk_dma_monitor_timer;
@@ -231,7 +231,7 @@
};
/* struct mtk_mac - the structure that holds the info about the MACs of the
-@@ -1927,6 +1941,9 @@ int mtk_toprgu_init(struct mtk_eth *eth, struct device_node *r);
+@@ -1993,6 +2007,9 @@ int mtk_toprgu_init(struct mtk_eth *eth, struct device_node *r);
int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
void mtk_usxgmii_link_poll(struct work_struct *work);
@@ -243,7 +243,7 @@
#endif /* MTK_ETH_H */
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
new file mode 100644
-index 0000000..27b5be5
+index 0000000..6965d98
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -0,0 +1,514 @@
@@ -1967,10 +1967,10 @@
+
+#endif
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
-index 078c0f4..f8a98d8 100644
+index 555ba50..25dcff2 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
-@@ -1378,12 +1378,34 @@ static void ppp_dev_priv_destructor(struct net_device *dev)
+@@ -1380,12 +1380,34 @@ static void ppp_dev_priv_destructor(struct net_device *dev)
ppp_destroy_interface(ppp);
}
@@ -2043,10 +2043,10 @@
static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index 631d158..ef44d9a 100644
+index 1c1ab37..44842a2 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
-@@ -838,6 +838,59 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
+@@ -843,6 +843,59 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
struct sk_buff *skb,
struct net_device *sb_dev);
@@ -2106,7 +2106,7 @@
enum tc_setup_type {
TC_SETUP_QDISC_MQPRIO,
TC_SETUP_CLSU32,
-@@ -853,6 +906,7 @@ enum tc_setup_type {
+@@ -858,6 +911,7 @@ enum tc_setup_type {
TC_SETUP_ROOT_QDISC,
TC_SETUP_QDISC_GRED,
TC_SETUP_QDISC_TAPRIO,
@@ -2114,7 +2114,7 @@
};
/* These structures hold the attributes of bpf state that are being passed
-@@ -1248,6 +1302,8 @@ struct tlsdev_ops;
+@@ -1253,6 +1307,8 @@ struct tlsdev_ops;
* Get devlink port instance associated with a given netdev.
* Called with a reference on the netdevice and devlink locks only,
* rtnl_lock is not held.
@@ -2123,7 +2123,7 @@
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
-@@ -1445,6 +1501,8 @@ struct net_device_ops {
+@@ -1450,6 +1506,8 @@ struct net_device_ops {
int (*ndo_xsk_wakeup)(struct net_device *dev,
u32 queue_id, u32 flags);
struct devlink_port * (*ndo_get_devlink_port)(struct net_device *dev);
@@ -2132,7 +2132,7 @@
};
/**
-@@ -2670,6 +2728,8 @@ void dev_remove_offload(struct packet_offload *po);
+@@ -2689,6 +2747,8 @@ void dev_remove_offload(struct packet_offload *po);
int dev_get_iflink(const struct net_device *dev);
int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
@@ -2210,7 +2210,7 @@
-
#endif /* _NF_CONNTRACK_IPV6_H*/
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
-index 90690e3..ce0bc3e 100644
+index 90690e3..38a8d3f 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -105,6 +105,8 @@ struct nf_conn {
@@ -2222,7 +2222,7 @@
};
static inline struct nf_conn *
-@@ -279,6 +279,18 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
+@@ -279,6 +281,18 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
!nf_ct_is_dying(ct);
}
@@ -2264,7 +2264,7 @@
int nf_conntrack_acct_init(void);
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
-index 68d7fc9..feac793 100644
+index 68d7fc9..7374cb2 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -8,31 +8,101 @@
@@ -2370,7 +2370,7 @@
struct flow_offload_tuple {
union {
-@@ -52,13 +120,30 @@ struct flow_offload_tuple {
+@@ -52,13 +122,30 @@ struct flow_offload_tuple {
u8 l3proto;
u8 l4proto;
@@ -2406,7 +2406,7 @@
};
};
-@@ -67,52 +152,140 @@ struct flow_offload_tuple_rhash {
+@@ -67,52 +154,140 @@ struct flow_offload_tuple_rhash {
struct flow_offload_tuple tuple;
};
@@ -2569,7 +2569,7 @@
struct flow_ports {
__be16 source, dest;
-@@ -126,4 +299,41 @@ unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
+@@ -126,4 +301,41 @@ unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
#define MODULE_ALIAS_NF_FLOWTABLE(family) \
MODULE_ALIAS("nf-flowtable-" __stringify(family))
@@ -2685,10 +2685,10 @@
+
+#endif /* _XT_FLOWOFFLOAD_H */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
-index 0a3a167..6112266 100644
+index dd7e09e..c373f1d 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
-@@ -747,6 +747,26 @@ static int vlan_dev_get_iflink(const struct net_device *dev)
+@@ -771,6 +771,26 @@ static int vlan_dev_get_iflink(const struct net_device *dev)
return real_dev->ifindex;
}
@@ -2715,7 +2715,7 @@
static const struct ethtool_ops vlan_ethtool_ops = {
.get_link_ksettings = vlan_ethtool_get_link_ksettings,
.get_drvinfo = vlan_ethtool_get_drvinfo,
-@@ -785,6 +805,7 @@ static const struct net_device_ops vlan_netdev_ops = {
+@@ -809,6 +829,7 @@ static const struct net_device_ops vlan_netdev_ops = {
#endif
.ndo_fix_features = vlan_dev_fix_features,
.ndo_get_iflink = vlan_dev_get_iflink,
@@ -2724,10 +2724,10 @@
static void vlan_dev_free(struct net_device *dev)
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
-index 501f77f..0940b44 100644
+index ab201d5..deec45b 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
-@@ -377,6 +377,54 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
+@@ -385,6 +385,54 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
return br_del_if(br, slave_dev);
}
@@ -2782,7 +2782,7 @@
static const struct ethtool_ops br_ethtool_ops = {
.get_drvinfo = br_getinfo,
.get_link = ethtool_op_get_link,
-@@ -410,6 +458,7 @@ static const struct net_device_ops br_netdev_ops = {
+@@ -418,6 +466,7 @@ static const struct net_device_ops br_netdev_ops = {
.ndo_bridge_setlink = br_setlink,
.ndo_bridge_dellink = br_dellink,
.ndo_features_check = passthru_features_check,
@@ -2895,10 +2895,10 @@
struct bridge_vlan_info *p_vinfo)
{
diff --git a/net/core/dev.c b/net/core/dev.c
-index 54cc544..a117bd0 100644
+index ef7362b..5bade26 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -639,6 +639,52 @@ int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
+@@ -722,6 +722,52 @@ int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
@@ -2952,7 +2952,7 @@
* __dev_get_by_name - find a device by its name
* @net: the applicable net namespace
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
-index e2b91b3..2dfaa1e 100644
+index cd5b354..2ea9ec1 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1031,14 +1031,32 @@ static int dsa_slave_setup_tc_block(struct net_device *dev,
@@ -3042,7 +3042,7 @@
tristate "Netfilter IPv4 packet duplication to alternate destination"
depends on !NF_CONNTRACK || NF_CONNTRACK
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
-index 8231a7a..7176d7f 100644
+index 816275b..671f767 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -607,7 +607,7 @@ int ip6_forward(struct sk_buff *skb)
@@ -3181,7 +3181,7 @@
obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
-index f6ab6f4..f689e19 100644
+index 706d180..65d16ef 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -864,9 +864,8 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
@@ -6086,7 +6086,7 @@
+}
diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
new file mode 100644
-index 0000000..2cab008
+index 0000000..e4c7db9
--- /dev/null
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
@@ -0,0 +1,800 @@
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3002-dts-netsys2-wed-changes.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3002-dts-netsys2-wed-changes.patch
index eacae85..213c69e 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3002-dts-netsys2-wed-changes.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3002-dts-netsys2-wed-changes.patch
@@ -1,19 +1,37 @@
-From be48305fd2e3ecd9a9853f2ae11fb9432e40b299 Mon Sep 17 00:00:00 2001
+From f99c7b63e766c2ff8851a8ba6ff77f3d8bfef0d5 Mon Sep 17 00:00:00 2001
From: Bo Jiao <Bo.Jiao@mediatek.com>
Date: Mon, 18 Sep 2023 10:55:08 +0800
-Subject: [PATCH 03/22] dts mt7986 wed changes
+Subject: [PATCH 02/24] dts netsys2 wed changes
---
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 33 ++++++++---------------
- arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 33 ++++++++---------------
- 2 files changed, 22 insertions(+), 44 deletions(-)
+ .../boot/dts/mediatek/mt7981-spim-nor-rfb.dts | 8 -----
+ arch/arm64/boot/dts/mediatek/mt7981.dtsi | 21 ++++--------
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 33 +++++++------------
+ arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 33 +++++++------------
+ 4 files changed, 28 insertions(+), 67 deletions(-)
-diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-index e43c306..e5d4e12 100644
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -58,32 +58,20 @@
- };
+diff --git a/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
+index 3fa55a0..f5c70a4 100755
+--- a/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
+@@ -211,11 +211,3 @@
+ &xhci {
+ status = "okay";
+ };
+-
+-&wed {
+- dy_txbm_enable = "true";
+- dy_txbm_budget = <8>;
+- txbm_init_sz = <8>;
+- txbm_max_sz = <32>;
+- status = "okay";
+-};
+diff --git a/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+index 91415e4..283421a 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7981.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+@@ -90,22 +90,12 @@
+ #io-channel-cells = <1>;
};
- wed: wed@15010000 {
@@ -24,49 +42,34 @@
- reg = <0 0x15010000 0 0x1000>,
- <0 0x15011000 0 0x1000>;
+ wed0: wed@15010000 {
-+ compatible = "mediatek,mt7986-wed",
++ compatible = "mediatek,mt7981-wed",
+ "syscon";
+ reg = <0 0x15010000 0 0x1000>;
interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
- };
-
-- wed2: wed2@15011000 {
-- compatible = "mediatek,wed2";
-- wed_num = <2>;
-- reg = <0 0x15010000 0 0x1000>,
-- <0 0x15011000 0 0x1000>;
-+ wed1: wed@15011000 {
-+ compatible = "mediatek,mt7986-wed",
-+ "syscon";
-+ reg = <0 0x15011000 0 0x1000>;
- interrupt-parent = <&gic>;
-- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- wdma: wdma@15104800 {
- compatible = "mediatek,wed-wdma";
- reg = <0 0x15104800 0 0x400>,
- <0 0x15104c00 0 0x400>;
-+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
};
ap2woccif: ap2woccif@151A5000 {
-@@ -507,6 +495,7 @@
- <&topckgen CK_TOP_CB_SGM_325M>;
+@@ -423,6 +413,7 @@
mediatek,ethsys = <ðsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
-+ mediatek,wed = <&wed0>, <&wed1>;
+ mediatek,infracfg = <&topmisc>;
++ mediatek,wed = <&wed0>;
#reset-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
-diff --git a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
-index 21d8357..2d2207f 100644
---- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+index 2c7e171..3a4f279 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -58,32 +58,20 @@
};
};
@@ -110,7 +113,7 @@
};
ap2woccif: ap2woccif@151A5000 {
-@@ -409,6 +397,7 @@
+@@ -494,6 +482,7 @@
<&topckgen CK_TOP_CB_SGM_325M>;
mediatek,ethsys = <ðsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
@@ -118,12 +121,12 @@
#reset-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
-diff --git a/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-index ccaf0ad0..b2f53b13 100644
---- a/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-@@ -90,22 +90,12 @@
- #io-channel-cells = <1>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+index 26f093b..ce884f0 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+@@ -58,32 +58,20 @@
+ };
};
- wed: wed@15010000 {
@@ -134,46 +137,45 @@
- reg = <0 0x15010000 0 0x1000>,
- <0 0x15011000 0 0x1000>;
+ wed0: wed@15010000 {
-+ compatible = "mediatek,mt7981-wed",
++ compatible = "mediatek,mt7986-wed",
+ "syscon";
+ reg = <0 0x15010000 0 0x1000>;
interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+- wed2: wed2@15011000 {
+- compatible = "mediatek,wed2";
+- wed_num = <2>;
+- reg = <0 0x15010000 0 0x1000>,
+- <0 0x15011000 0 0x1000>;
++ wed1: wed@15011000 {
++ compatible = "mediatek,mt7986-wed",
++ "syscon";
++ reg = <0 0x15011000 0 0x1000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- wdma: wdma@15104800 {
- compatible = "mediatek,wed-wdma";
- reg = <0 0x15104800 0 0x400>,
- <0 0x15104c00 0 0x400>;
-+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
};
ap2woccif: ap2woccif@151A5000 {
-@@ -423,6 +413,7 @@
+@@ -408,6 +396,7 @@
+ <&topckgen CK_TOP_CB_SGM_325M>;
mediatek,ethsys = <ðsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
- mediatek,infracfg = <&topmisc>;
-+ mediatek,wed = <&wed0>;
++ mediatek,wed = <&wed0>, <&wed1>;
#reset-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
-diff --git a/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
-index 3fa55a07..f5c70a4e 100755
---- a/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7981-spim-nor-rfb.dts
-@@ -211,11 +211,3 @@
- &xhci {
- status = "okay";
- };
--
--&wed {
-- dy_txbm_enable = "true";
-- dy_txbm_budget = <8>;
-- txbm_init_sz = <8>;
-- txbm_max_sz = <32>;
-- status = "okay";
--};
--
2.18.0
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3003-add-wed.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3003-add-wed.patch
index 16c04b5..a60b6ce 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3003-add-wed.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3003-add-wed.patch
@@ -1,7 +1,7 @@
-From cdb36beeb6725bcef3faad499c017c26bc17fd4a Mon Sep 17 00:00:00 2001
+From b895d23fa63dd712191b6d223fe6c41682c7d375 Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 10:56:21 +0800
-Subject: [PATCH 04/22] add wed
+Subject: [PATCH 03/24] add wed
---
arch/arm64/boot/dts/mediatek/mt7622.dtsi | 32 +-
@@ -13,7 +13,7 @@
drivers/net/ethernet/mediatek/mtk_ppe.h | 89 +-
.../net/ethernet/mediatek/mtk_ppe_debugfs.c | 4 +-
.../net/ethernet/mediatek/mtk_ppe_offload.c | 167 +++-
- drivers/net/ethernet/mediatek/mtk_wed.c | 876 ++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_wed.c | 881 ++++++++++++++++++
drivers/net/ethernet/mediatek/mtk_wed.h | 135 +++
.../net/ethernet/mediatek/mtk_wed_debugfs.c | 175 ++++
drivers/net/ethernet/mediatek/mtk_wed_ops.c | 8 +
@@ -21,7 +21,7 @@
include/linux/netdevice.h | 7 +
include/linux/soc/mediatek/mtk_wed.h | 131 +++
net/core/dev.c | 4 +
- 17 files changed, 2207 insertions(+), 103 deletions(-)
+ 17 files changed, 2212 insertions(+), 103 deletions(-)
mode change 100755 => 100644 drivers/net/ethernet/mediatek/Kconfig
mode change 100755 => 100644 drivers/net/ethernet/mediatek/Makefile
mode change 100755 => 100644 drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -134,7 +134,7 @@
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
old mode 100755
new mode 100644
-index 9c85e16..88b38e2
+index 20b2943..8d15399
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -21,11 +21,13 @@
@@ -151,7 +151,7 @@
#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE)
#include "mtk_hnat/nf_hnat_mtk.h"
-@@ -2191,6 +2193,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2356,6 +2358,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
struct net_device *netdev = NULL;
dma_addr_t dma_addr = DMA_MAPPING_ERROR;
u64 addr64 = 0;
@@ -159,7 +159,7 @@
int mac = 0;
idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-@@ -2282,6 +2285,17 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2444,6 +2447,17 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, netdev);
@@ -177,7 +177,7 @@
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
if (trxd.rxd3 & RX_DMA_VTAG_V2)
-@@ -3735,7 +3749,7 @@ static int mtk_stop(struct net_device *dev)
+@@ -4177,7 +4191,7 @@ static int mtk_stop(struct net_device *dev)
mtk_dma_free(eth);
if (eth->soc->offload_version)
@@ -186,7 +186,7 @@
return 0;
}
-@@ -5044,6 +5058,22 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5560,6 +5574,22 @@ static int mtk_probe(struct platform_device *pdev)
}
}
@@ -208,8 +208,8 @@
+
if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) {
for (i = 0; i < MTK_PDMA_IRQ_NUM; i++)
-
-@@ -5170,10 +5200,11 @@ static int mtk_probe(struct platform_device *pdev)
+ eth->irq_pdma[i] = platform_get_irq(pdev, i);
+@@ -5720,10 +5750,11 @@ static int mtk_probe(struct platform_device *pdev)
}
if (eth->soc->offload_version) {
@@ -227,10 +227,10 @@
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
old mode 100755
new mode 100644
-index a87e46d..15337d3
+index 4d3a63c..00cfe3b
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -578,6 +578,9 @@
+@@ -615,6 +615,9 @@
#define RX_DMA_SPORT_MASK 0x7
#define RX_DMA_SPORT_MASK_V2 0xf
@@ -240,7 +240,7 @@
/* QDMA descriptor txd4 */
#define TX_DMA_CHKSUM (0x7 << 29)
#define TX_DMA_TSO BIT(28)
-@@ -1859,7 +1862,7 @@ struct mtk_eth {
+@@ -1924,7 +1927,7 @@ struct mtk_eth {
spinlock_t syscfg0_lock;
struct timer_list mtk_dma_monitor_timer;
@@ -252,7 +252,7 @@
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
old mode 100644
new mode 100755
-index 27b5be5..86741bf
+index 6965d98..eeaec1b
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -6,9 +6,22 @@
@@ -1262,10 +1262,10 @@
return rhashtable_init(ð->flow_table, &mtk_flow_ht_params);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
new file mode 100644
-index 0000000..ea1cbdf
+index 0000000..affa704
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -0,0 +1,876 @@
+@@ -0,0 +1,881 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
+
@@ -1413,16 +1413,17 @@
+
+ for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
+ u32 txd_size;
++ u32 ctrl;
+
+ txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
+
-+ desc->buf0 = buf_phys;
-+ desc->buf1 = buf_phys + txd_size;
-+ desc->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;
++ 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;
++ desc->ctrl = cpu_to_le32(ctrl);
+ desc->info = 0;
+ desc++;
+
@@ -1453,12 +1454,14 @@
+
+ for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
+ void *page = page_list[page_idx++];
++ dma_addr_t buf_addr;
+
+ if (!page)
+ break;
+
-+ dma_unmap_page(dev->hw->dev, desc[i].buf0,
-+ PAGE_SIZE, DMA_BIDIRECTIONAL);
++ buf_addr = le32_to_cpu(desc[i].buf0);
++ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
+ __free_page(page);
+ }
+
@@ -1917,7 +1920,7 @@
+ * WDMA RX.
+ */
+
-+ BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
++ BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
+
+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE))
+ return -ENOMEM;
@@ -2082,7 +2085,7 @@
+ return;
+
+ regs = syscon_regmap_lookup_by_phandle(np, NULL);
-+ if (!regs)
++ if (IS_ERR(regs))
+ return;
+
+ rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
@@ -2093,6 +2096,8 @@
+ goto unlock;
+
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
++ if (!hw)
++ goto unlock;
+ hw->node = np;
+ hw->regs = regs;
+ hw->eth = eth;
@@ -2736,10 +2741,10 @@
+
+#endif
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index ef44d9a..59a3e96 100644
+index 44842a2..5305384 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
-@@ -844,6 +844,7 @@ enum net_device_path_type {
+@@ -849,6 +849,7 @@ enum net_device_path_type {
DEV_PATH_BRIDGE,
DEV_PATH_PPPOE,
DEV_PATH_DSA,
@@ -2747,7 +2752,7 @@
};
struct net_device_path {
-@@ -869,6 +870,12 @@ struct net_device_path {
+@@ -874,6 +875,12 @@ struct net_device_path {
int port;
u16 proto;
} dsa;
@@ -2898,10 +2903,10 @@
+
+#endif
diff --git a/net/core/dev.c b/net/core/dev.c
-index a117bd0..1b6d42b 100644
+index 5bade26..0775e8d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
-@@ -675,6 +675,10 @@ int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
+@@ -758,6 +758,10 @@ int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
if (WARN_ON_ONCE(last_dev == ctx.dev))
return -1;
}
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch
index d613ce8..37666e6 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3004-ethernet-update-ppe-from-netsys1-to-netsys2.patch
@@ -1,7 +1,7 @@
-From 3562f05aedc6c2d793b34b3ee3eb78e8352804c8 Mon Sep 17 00:00:00 2001
+From 3a07dcf1a402223c3d96eed88f9dcb8eac0a9362 Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 10:58:32 +0800
-Subject: [PATCH 05/22] ethernet update ppe from mt7622 to mt7986
+Subject: [PATCH 04/24] ethernet update ppe from netsys1 to netsys2
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 ++++-
@@ -13,10 +13,10 @@
6 files changed, 113 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 88b38e2..bfda873 100644
+index 8d15399..45dc85f 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2285,16 +2285,27 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2447,16 +2447,27 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, netdev);
@@ -45,7 +45,7 @@
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_RX_V2)) {
-@@ -5396,6 +5407,7 @@ static const struct mtk_soc_data mt7986_data = {
+@@ -5953,6 +5964,7 @@ static const struct mtk_soc_data mt7986_data = {
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -54,10 +54,10 @@
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 15337d3..a385df5 100644
+index 00cfe3b..69eb112 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -130,7 +130,7 @@
+@@ -137,7 +137,7 @@
#define MTK_GDMA_UCS_EN BIT(20)
#define MTK_GDMA_STRP_CRC BIT(16)
#define MTK_GDMA_TO_PDMA 0x0
@@ -66,7 +66,7 @@
#define MTK_GDMA_DROP_ALL 0x7777
/* GDM Egress Control Register */
-@@ -630,6 +630,11 @@
+@@ -674,6 +674,11 @@
#define MTK_RXD4_SRC_PORT GENMASK(21, 19)
#define MTK_RXD4_ALG GENMASK(31, 22)
@@ -79,7 +79,7 @@
#define RX_DMA_L4_VALID BIT(24)
#define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 86741bf..ef8acbc 100755
+index eeaec1b..e195fb3 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
index 8d605e0..458379d 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3005-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
@@ -1,7 +1,7 @@
-From 806bb7d1a0a44a92101c506564a41dc6c4b68fd0 Mon Sep 17 00:00:00 2001
+From d35e908b342bce34e01c29a07328a4a245d5d79d Mon Sep 17 00:00:00 2001
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
Date: Tue, 26 Dec 2023 16:31:34 +0800
-Subject: [PATCH 06/22] flow-offload-add-mkhnat-dual-ppe-new-v2
+Subject: [PATCH 05/24] flow-offload-add-mkhnat-dual-ppe-new-v2
---
arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 1 +
@@ -16,10 +16,10 @@
mode change 100644 => 100755 drivers/net/ethernet/mediatek/mtk_ppe_offload.c
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-index e5d4e12..0c54e12 100644
+index 3a4f279..d70151b 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -496,6 +496,7 @@
+@@ -483,6 +483,7 @@
mediatek,ethsys = <ðsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
mediatek,wed = <&wed0>, <&wed1>;
@@ -28,10 +28,10 @@
#address-cells = <1>;
#size-cells = <0>;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index bfda873..ee5e0c6 100644
+index 45dc85f..07209f0 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2276,14 +2276,16 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2459,14 +2459,16 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2)
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON_V2, trxd.rxd5);
@@ -52,7 +52,7 @@
#endif
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
-@@ -3676,8 +3683,12 @@ static int mtk_open(struct net_device *dev)
+@@ -4111,8 +4113,12 @@ static int mtk_open(struct net_device *dev)
regmap_write(eth->sgmii->pcs[id].regmap,
SGMSYS_QPHY_PWR_STATE_CTRL, 0);
@@ -67,7 +67,7 @@
mtk_gdm_config(eth, mac->id, gdm_config);
-@@ -3759,8 +3770,10 @@ static int mtk_stop(struct net_device *dev)
+@@ -4201,8 +4207,10 @@ static int mtk_stop(struct net_device *dev)
mtk_dma_free(eth);
@@ -80,7 +80,7 @@
return 0;
}
-@@ -5211,15 +5224,35 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5761,15 +5769,35 @@ static int mtk_probe(struct platform_device *pdev)
}
if (eth->soc->offload_version) {
@@ -124,10 +124,10 @@
for (i = 0; i < MTK_MAX_DEVS; i++) {
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index a385df5..783166d 100644
+index 69eb112..a00583f 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -130,7 +130,12 @@
+@@ -137,7 +137,12 @@
#define MTK_GDMA_UCS_EN BIT(20)
#define MTK_GDMA_STRP_CRC BIT(16)
#define MTK_GDMA_TO_PDMA 0x0
@@ -141,7 +141,7 @@
#define MTK_GDMA_DROP_ALL 0x7777
/* GDM Egress Control Register */
-@@ -1867,7 +1872,8 @@ struct mtk_eth {
+@@ -1932,7 +1937,8 @@ struct mtk_eth {
spinlock_t syscfg0_lock;
struct timer_list mtk_dma_monitor_timer;
@@ -151,7 +151,7 @@
struct rhashtable flow_table;
};
-@@ -1949,9 +1955,11 @@ int mtk_toprgu_init(struct mtk_eth *eth, struct device_node *r);
+@@ -2015,9 +2021,11 @@ int mtk_toprgu_init(struct mtk_eth *eth, struct device_node *r);
int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
void mtk_usxgmii_link_poll(struct work_struct *work);
@@ -165,7 +165,7 @@
+int mtk_ppe_debugfs_init(struct mtk_eth *eth);
#endif /* MTK_ETH_H */
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index ef8acbc..96c15b3 100755
+index e195fb3..c9ee505 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -696,7 +696,7 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
@@ -449,10 +449,10 @@
return rhashtable_init(ð->flow_table, &mtk_flow_ht_params);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index 59a3e96..0967dc2 100644
+index 5305384..b2abebe 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
-@@ -1311,6 +1311,8 @@ struct tlsdev_ops;
+@@ -1316,6 +1316,8 @@ struct tlsdev_ops;
* rtnl_lock is not held.
* int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path);
* Get the forwarding path to reach the real device from the HW destination address
@@ -461,7 +461,7 @@
*/
struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
-@@ -1510,6 +1512,8 @@ struct net_device_ops {
+@@ -1515,6 +1517,8 @@ struct net_device_ops {
struct devlink_port * (*ndo_get_devlink_port)(struct net_device *dev);
int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx,
struct net_device_path *path);
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3006-add-wed-tx-support-for-netsys2.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3006-add-wed-tx-support-for-netsys2.patch
index 5cfedfc..5197d21 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3006-add-wed-tx-support-for-netsys2.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3006-add-wed-tx-support-for-netsys2.patch
@@ -1,23 +1,23 @@
-From d76914437a405265b298b7b01235a7304634c567 Mon Sep 17 00:00:00 2001
+From 56e9bf306919ffb33d45951541d908cd7d21c081 Mon Sep 17 00:00:00 2001
From: Bo Jiao <Bo.Jiao@mediatek.com>
Date: Mon, 18 Sep 2023 11:01:55 +0800
-Subject: [PATCH] add-wed-tx-support-for-mt7986
+Subject: [PATCH 06/24] add-wed-tx-support-for-netsys2
---
arch/arm64/boot/dts/mediatek/mt7981.dtsi | 1 +
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 2 +
- arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 2 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 17 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +
- drivers/net/ethernet/mediatek/mtk_wed.c | 498 +++++++++++++-----
- drivers/net/ethernet/mediatek/mtk_wed.h | 18 +-
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 6 +-
+ arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 6 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 41 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 -
+ drivers/net/ethernet/mediatek/mtk_wed.c | 525 +++++++++++++-----
+ drivers/net/ethernet/mediatek/mtk_wed.h | 21 +-
.../net/ethernet/mediatek/mtk_wed_debugfs.c | 3 +
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 130 ++++-
- include/linux/soc/mediatek/mtk_wed.h | 23 +
- 10 files changed, 549 insertions(+), 150 deletions(-)
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 111 +++-
+ include/linux/soc/mediatek/mtk_wed.h | 21 +-
+ 10 files changed, 575 insertions(+), 163 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-index e1b9b2c..3e0d2c0 100644
+index 283421a..cb8f4e1 100644
--- a/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
@@ -96,6 +96,7 @@
@@ -29,7 +29,7 @@
ap2woccif: ap2woccif@151A5000 {
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-index 7e3101c..e9756bd 100644
+index d70151b..9c288fc 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -64,6 +64,7 @@
@@ -48,8 +48,26 @@
};
ap2woccif: ap2woccif@151A5000 {
+@@ -482,6 +484,7 @@
+ <&topckgen CK_TOP_CB_SGM_325M>;
+ mediatek,ethsys = <ðsys>;
+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
++ mediatek,wed-pcie = <&wed_pcie>;
+ mediatek,wed = <&wed0>, <&wed1>;
+ mtketh-ppe-num = <2>;
+ #reset-cells = <1>;
+@@ -549,7 +552,8 @@
+ };
+
+ wed_pcie: wed_pcie@10003000 {
+- compatible = "mediatek,wed_pcie";
++ compatible = "mediatek,wed_pcie",
++ "syscon";
+ reg = <0 0x10003000 0 0x10>;
+ };
+
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
-index a780cfb..eafe314 100644
+index ce884f0..02feaa9 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
@@ -64,6 +64,7 @@
@@ -68,11 +86,29 @@
};
ap2woccif: ap2woccif@151A5000 {
+@@ -396,6 +398,7 @@
+ <&topckgen CK_TOP_CB_SGM_325M>;
+ mediatek,ethsys = <ðsys>;
+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
++ mediatek,wed-pcie = <&wed_pcie>;
+ mediatek,wed = <&wed0>, <&wed1>;
+ #reset-cells = <1>;
+ #address-cells = <1>;
+@@ -462,7 +465,8 @@
+ };
+
+ wed_pcie: wed_pcie@10003000 {
+- compatible = "mediatek,wed_pcie";
++ compatible = "mediatek,wed_pcie",
++ "syscon";
+ reg = <0 0x10003000 0 0x10>;
+ };
+
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 3685926..51fe4b3 100644
+index 07209f0..268c9e7 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5091,6 +5091,7 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5476,6 +5476,7 @@ static int mtk_probe(struct platform_device *pdev)
{
struct device_node *mac_np, *mux_np;
struct mtk_eth *eth;
@@ -80,8 +116,8 @@
int err, i;
eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL);
-@@ -5111,13 +5112,12 @@ static int mtk_probe(struct platform_device *pdev)
- return PTR_ERR(eth->sram_base);
+@@ -5498,13 +5499,12 @@ static int mtk_probe(struct platform_device *pdev)
+ eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET;
}
- if(eth->soc->has_sram) {
@@ -93,49 +129,66 @@
+ if (unlikely(!res))
+ return -EINVAL;
+
-+ if(eth->soc->has_sram)
++ if (eth->soc->has_sram)
eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
- }
mtk_get_hwver(eth);
+@@ -5593,20 +5593,25 @@ static int mtk_probe(struct platform_device *pdev)
+ }
+ }
+
-@@ -5213,12 +5213,15 @@ static int mtk_probe(struct platform_device *pdev)
- MTK_WDMA1_BASE
- };
- void __iomem *wdma;
-+ u32 wdma_phy;
+- for (i = 0;; i++) {
+- struct device_node *np = of_parse_phandle(pdev->dev.of_node,
+- "mediatek,wed", i);
+- static const u32 wdma_regs[] = {
+- MTK_WDMA0_BASE,
+- MTK_WDMA1_BASE
+- };
+- void __iomem *wdma;
++ if (eth->soc->offload_version) {
++ for (i = 0;; i++) {
++ struct device_node *np;
++ phys_addr_t wdma_phy;
++ u32 wdma_base;
- if (!np || i >= ARRAY_SIZE(wdma_regs))
- break;
+- if (!np || i >= ARRAY_SIZE(wdma_regs))
+- break;
++ if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
++ break;
- wdma = eth->base + wdma_regs[i];
+- wdma = eth->base + wdma_regs[i];
- mtk_wed_add_hw(np, eth, wdma, i);
-+ wdma_phy = res->start + wdma_regs[i];
++ np = of_parse_phandle(pdev->dev.of_node,
++ "mediatek,wed", i);
++ if (!np)
++ break;
+
-+ mtk_wed_add_hw(np, eth, wdma, wdma_phy, i);
++ 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);
++ }
}
if (MTK_HAS_CAPS(eth->soc->caps, MTK_PDMA_INT)) {
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index b714c27..e9d88f1 100644
+index a00583f..9099dea 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -593,8 +593,13 @@
+@@ -620,9 +620,6 @@
#define RX_DMA_SPORT_MASK 0x7
#define RX_DMA_SPORT_MASK_V2 0xf
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#define MTK_WDMA0_BASE 0x4800
-+#define MTK_WDMA1_BASE 0x4c00
-+#else
- #define MTK_WDMA0_BASE 0x2800
- #define MTK_WDMA1_BASE 0x2c00
-+#endif
-
+-#define MTK_WDMA0_BASE 0x2800
+-#define MTK_WDMA1_BASE 0x2c00
+-
/* QDMA descriptor txd4 */
#define TX_DMA_CHKSUM (0x7 << 29)
+ #define TX_DMA_TSO BIT(28)
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index ea1cbdf..948f013 100644
+index affa704..02e06a8 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -18,15 +18,6 @@
@@ -154,37 +207,44 @@
static struct mtk_wed_hw *hw_list[2];
static DEFINE_MUTEX(hw_lock);
-@@ -80,14 +71,19 @@ mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
- static struct mtk_wed_hw *
+@@ -81,11 +72,31 @@ static struct mtk_wed_hw *
mtk_wed_assign(struct mtk_wed_device *dev)
{
-- struct mtk_wed_hw *hw;
+ struct mtk_wed_hw *hw;
+ int i;
+
-+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
-+ struct mtk_wed_hw *hw = hw_list[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 || hw->wed_dev)
-+ continue;
++ 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;
-+ hw->wed_dev = dev;
-+ return hw;
-+ }
-
-- hw->wed_dev = dev;
-- return hw;
+ return NULL;
- }
- static int
-@@ -96,19 +92,27 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- struct mtk_wdma_desc *desc;
++out:
+ hw->wed_dev = dev;
+ return hw;
+ }
+@@ -97,11 +108,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
dma_addr_t desc_phys;
void **page_list;
-+ u32 last_seg = MTK_WDMA_DESC_CTRL_LAST_SEG1;
int token = dev->wlan.token_start;
- int ring_size;
- int n_pages;
@@ -193,130 +253,65 @@
+ int i;
+
+
-+ if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1)
+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
-+ } else {
++ else
+ ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
+ MTK_WED_WDMA_RING_SIZE * 2;
-+ last_seg = MTK_WDMA_DESC_CTRL_LAST_SEG0;
-+ }
- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
- if (!page_list)
- return -ENOMEM;
-
-- dev->buf_ring.size = ring_size;
-+ dev->buf_ring.size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
- dev->buf_ring.pages = page_list;
+@@ -151,10 +167,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
-@@ -154,7 +158,7 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
- txd_size) |
- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
- MTK_WED_BUF_SIZE - txd_size) |
-- MTK_WDMA_DESC_CTRL_LAST_SEG1;
-+ last_seg;
+ 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++;
-
-@@ -202,12 +206,12 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
- }
-
- static void
--mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
-+mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int scale)
- {
+@@ -210,7 +233,7 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
if (!ring->desc)
return;
- dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc),
-+ dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc) * scale,
++ dma_free_coherent(dev->hw->dev, ring->size * ring->desc_size,
ring->desc, ring->desc_phys);
}
-@@ -217,9 +221,69 @@ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
- int i;
+@@ -230,6 +253,9 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
+ {
+ u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
- for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
-- mtk_wed_free_ring(dev, &dev->tx_ring[i]);
-+ mtk_wed_free_ring(dev, &dev->tx_ring[i], 1);
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
-+ mtk_wed_free_ring(dev, &dev->tx_wdma[i], dev->ver);
-+}
-+
-+static void
-+mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
-+{
-+ u32 wdma_mask;
-+
-+ 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);
-+
-+ if (dev->ver == MTK_WED_V1) {
-+ 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);
-+ } 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]));
++ if (dev->hw->version == 1)
++ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
+
-+ /* 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));
-+ }
-+ /* initail wdma interrupt agent */
-+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
-+ if (dev->ver == MTK_WED_V1) {
-+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
-+ } else {
-+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
-+ wed_set(dev, MTK_WED_WDMA_INT_CTRL,
-+ FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,dev->wdma_idx));
-+
-+ }
-+
-+ 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);
- }
+ if (!dev->hw->num_flows)
+ mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
- static void
-@@ -234,10 +298,95 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
+@@ -237,10 +263,57 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
wed_r32(dev, MTK_WED_EXT_INT_MASK);
}
+static void
-+mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
++mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
+{
-+ if (en) {
++ 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));
@@ -328,43 +323,6 @@
+}
+
+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 |
-+ MTK_WED_GLO_CFG_RX_DMA_EN);
-+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-+ 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);
-+
-+ if (dev->ver == MTK_WED_V1) {
-+ 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_dma_disable(struct mtk_wed_device *dev)
+{
+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
@@ -383,7 +341,7 @@
+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0);
+
-+ if (dev->ver == MTK_WED_V1) {
++ 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);
@@ -391,6 +349,8 @@
+ 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)
+ }
+}
+
@@ -400,13 +360,10 @@
- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
+ mtk_wed_dma_disable(dev);
+
-+ if (dev->ver > MTK_WED_V1)
-+ mtk_wed_set_512_support(dev, false);
-+
mtk_wed_set_ext_int(dev, false);
wed_clr(dev, MTK_WED_CTRL,
-@@ -245,26 +394,18 @@ mtk_wed_stop(struct mtk_wed_device *dev)
+@@ -248,26 +321,18 @@ mtk_wed_stop(struct mtk_wed_device *dev)
MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
MTK_WED_CTRL_WED_TX_BM_EN |
MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
@@ -435,7 +392,7 @@
struct mtk_wed_hw *hw = dev->hw;
mutex_lock(&hw_lock);
-@@ -279,11 +420,14 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+@@ -282,11 +347,14 @@ mtk_wed_detach(struct mtk_wed_device *dev)
mtk_wed_free_buffer(dev);
mtk_wed_free_tx_rings(dev);
@@ -444,7 +401,7 @@
- BIT(hw->index), BIT(hw->index));
+ if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
+ wlan_node = dev->wlan.pci_dev->dev.of_node;
-+ 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));
+ }
@@ -454,31 +411,25 @@
hw->eth->dma_dev != hw->eth->dev)
mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
-@@ -294,15 +438,87 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+@@ -297,14 +365,76 @@ mtk_wed_detach(struct mtk_wed_device *dev)
mutex_unlock(&hw_lock);
}
++#define PCIE_BASE_ADDR0 0x11280000
+static void
+mtk_wed_bus_init(struct mtk_wed_device *dev)
+{
-+#define PCIE_BASE_ADDR0 0x11280000
-+
-+ if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
-+ struct device_node *node;
-+ void __iomem * base_addr;
-+ u32 value = 0;
++ switch (dev->wlan.bus_type) {
++ case MTK_BUS_TYPE_PCIE: {
++ struct device_node *np = dev->hw->eth->dev->of_node;
++ struct regmap *regs;
+
-+ node = of_parse_phandle(dev->hw->node, "mediatek,wed_pcie", 0);
-+ if (!node) {
-+ pr_err("%s: no wed_pcie node\n", __func__);
-+ return;
-+ }
-+
-+ base_addr = of_iomap(node, 0);
++ regs = syscon_regmap_lookup_by_phandle(np,
++ "mediatek,wed-pcie");
++ if (IS_ERR(regs))
++ break;
+
-+ value = readl(base_addr);
-+ value |= BIT(0);
-+ writel(value, base_addr);
++ 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));
@@ -489,40 +440,40 @@
+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
+
-+ value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-+ value = 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);
+
-+ value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-+ value = 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 */
-+ value = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
+ wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-+ } else if (dev->wlan.bus_type == MTK_BUS_TYPE_AXI) {
++ break;
++ }
++ case MTK_BUS_TYPE_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;
+ }
-+ return;
+}
+
+static void
+mtk_wed_set_wpdma(struct mtk_wed_device *dev)
+{
-+ if (dev->ver > MTK_WED_V1) {
++ 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);
-+ } else {
-+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
+ }
+}
+
@@ -534,21 +485,16 @@
mtk_wed_stop(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
-
-+ if (dev->ver > MTK_WED_V1)
-+ mtk_wed_bus_init(dev);
-+
+ mtk_wed_set_wpdma(dev);
-+
+
mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
-@@ -311,30 +527,54 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
+@@ -314,14 +444,30 @@ mtk_wed_hw_init_early(struct mtk_wed_device *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);
-+ if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ u32 offset;
+ offset = dev->hw->index ? 0x04000400 : 0;
+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
@@ -557,7 +503,8 @@
- offset = dev->hw->index ? 0x04000400 : 0;
- 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));
++ 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);
@@ -579,44 +526,62 @@
}
static void
- mtk_wed_hw_init(struct mtk_wed_device *dev)
- {
-+ int size = dev->buf_ring.size;
-+ int rev_size = MTK_WED_TX_RING_SIZE / 2;
-+ int thr = 1;
-+
- if (dev->init_done)
- return;
+@@ -332,46 +478,79 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
dev->init_done = true;
mtk_wed_set_ext_int(dev, false);
-+
-+ if (dev->ver > MTK_WED_V1) {
-+ size = MTK_WED_WDMA_RING_SIZE * 2 + dev->buf_ring.size;
-+ rev_size = size;
-+ thr = 0;
-+ }
-+
- wed_w32(dev, MTK_WED_TX_BM_CTRL,
- MTK_WED_TX_BM_CTRL_PAUSE |
+- wed_w32(dev, MTK_WED_TX_BM_CTRL,
+- MTK_WED_TX_BM_CTRL_PAUSE |
- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
- dev->buf_ring.size / 128) |
- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
- MTK_WED_TX_RING_SIZE / 256));
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, size / 128) |
-+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, rev_size / 128));
wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
-@@ -347,28 +587,38 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+- 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,
+- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) |
-+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, thr) |
- MTK_WED_TX_BM_DYN_THR_HI);
-
-+ if (dev->ver > MTK_WED_V1) {
+- MTK_WED_TX_BM_DYN_THR_HI);
++ if (dev->hw->version == 1) {
++ wed_w32(dev, MTK_WED_TX_BM_CTRL,
++ MTK_WED_TX_BM_CTRL_PAUSE |
++ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
++ dev->buf_ring.size / 128) |
++ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
++ MTK_WED_TX_RING_SIZE / 256));
++ 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_CTRL,
++ MTK_WED_TX_BM_CTRL_PAUSE |
++ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
++ dev->buf_ring.size / 128) |
++ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
++ dev->buf_ring.size / 128));
++ 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,
@@ -627,21 +592,27 @@
+ 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);
--
- wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
-+ if (dev->ver > MTK_WED_V1)
++ 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_wdma_desc *desc, int size, int scale)
++mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size)
{
++ void *head = (void *)ring->desc;
int i;
for (i = 0; i < size; i++) {
@@ -649,136 +620,228 @@
- 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;
-+ desc += scale;
}
}
-@@ -424,7 +674,7 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
- if (!desc)
+@@ -422,12 +601,10 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ 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(desc, MTK_WED_TX_RING_SIZE, dev->ver);
++ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE);
}
if (mtk_wed_poll_busy(dev))
-@@ -481,16 +731,16 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+@@ -484,16 +661,16 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
static int
mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
- int size)
-+ int size, int scale)
++ int size, u32 desc_size)
{
- ring->desc = dma_alloc_coherent(dev->hw->dev,
+- ring->desc = dma_alloc_coherent(dev->hw->dev,
- size * sizeof(*ring->desc),
-+ size * sizeof(*ring->desc) * scale,
++ 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->desc, size, scale);
++ mtk_wed_ring_reset(ring, size);
return 0;
}
-@@ -500,7 +750,7 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+@@ -501,9 +678,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
+ 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, dev->ver))
++ 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,
-@@ -521,60 +771,36 @@ static void
- mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+@@ -521,43 +699,63 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+ }
+
+ 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 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);
-
+- 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));
- mtk_wed_hw_init(dev);
++ /* 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_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);
--
++ 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);
-+ mtk_wed_set_int(dev, irq_mask);
-
+-
- wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
--
-- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
++ 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_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);
-- wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
-- wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
-+ mtk_wed_set_ext_int(dev, true);
+ 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 |
-- MTK_WED_GLO_CFG_RX_DMA_EN);
-- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
-- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ if (dev->ver == MTK_WED_V1) {
-+ u32 val;
+ wed_set(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_TX_DMA_EN |
+@@ -568,16 +766,57 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-- mtk_wed_set_ext_int(dev, true);
++ 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);
++
++ 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 wdma_mask;
++ 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 |
- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index);
-+ 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->index)
-+ val |= BIT(1);
-+ val |= BIT(0);
++ if (dev->hw->version == 1) {
++ u32 val;
++
++ 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;
}
+@@ -586,20 +825,19 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ __releases(RCU)
+ {
+ struct mtk_wed_hw *hw;
++ struct device *device;
+ int ret = 0;
+
-@@ -588,15 +814,11 @@ mtk_wed_attach(struct mtk_wed_device *dev)
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 ||
-- !try_module_get(THIS_MODULE))
++ 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;
-+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
rcu_read_unlock();
@@ -789,55 +852,48 @@
mutex_lock(&hw_lock);
hw = mtk_wed_assign(dev);
-@@ -606,8 +828,6 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+@@ -609,8 +847,11 @@ mtk_wed_attach(struct mtk_wed_device *dev)
goto out;
}
- dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index);
-
++ 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;
dev->dev = hw->dev;
dev->irq = hw->irq;
-@@ -617,6 +837,9 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- of_dma_is_coherent(hw->eth->dev->of_node))
- mtk_eth_set_dma_device(hw->eth, hw->dev);
-
-+ dev->ver = FIELD_GET(MTK_WED_REV_ID_MAJOR,
-+ wed_r32(dev, MTK_WED_REV_ID));
-+
- ret = mtk_wed_buffer_alloc(dev);
- if (ret) {
- mtk_wed_detach(dev);
-@@ -624,7 +847,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+@@ -627,7 +868,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
}
mtk_wed_hw_init_early(dev);
- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0);
+
-+ if (dev->ver == MTK_WED_V1)
++ if (hw->hifsys)
+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
+ BIT(hw->index), 0);
out:
mutex_unlock(&hw_lock);
-@@ -651,7 +877,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+@@ -654,7 +898,8 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
+ 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, 1))
++ 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))
-@@ -678,21 +904,24 @@ static int
+@@ -681,21 +926,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, idx = 1;
-+
-+ if(dev->ver > MTK_WED_V1)
-+ idx = 0;
++ int i, index = dev->hw->version == 1;
/*
* For txfree event handling, the same DMA ring is shared between WED
@@ -845,7 +901,7 @@
* WED
*/
- ring->reg_base = MTK_WED_RING_RX(1);
-+ ring->reg_base = MTK_WED_RING_RX(idx);
++ ring->reg_base = MTK_WED_RING_RX(index);
ring->wpdma = regs;
for (i = 0; i < 12; i += 4) {
@@ -853,22 +909,43 @@
- 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(idx) + i, val);
-+ wed_w32(dev, MTK_WED_WPDMA_RING_RX(idx) + 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;
-@@ -780,7 +1009,8 @@ void mtk_wed_flow_remove(int index)
+@@ -783,7 +1028,9 @@ void mtk_wed_flow_remove(int index)
}
void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, int index)
-+ void __iomem *wdma, u32 wdma_phy, int index)
++ void __iomem *wdma, phys_addr_t wdma_phy,
++ int index)
+
{
static const struct mtk_wed_ops wed_ops = {
.attach = mtk_wed_attach,
-@@ -830,21 +1060,27 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -809,16 +1056,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+
+ pdev = of_find_device_by_node(np);
+ if (!pdev)
+- return;
++ goto err_of_node_put;
+
+ get_device(&pdev->dev);
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+- return;
++ goto err_put_device;
+
+ regs = syscon_regmap_lookup_by_phandle(np, NULL);
+ if (IS_ERR(regs))
+- return;
++ goto err_put_device;
+
+ rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
+
+@@ -835,27 +1082,42 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
hw->eth = eth;
hw->dev = &pdev->dev;
hw->wdma = wdma;
@@ -883,16 +960,17 @@
- kfree(hw);
- goto unlock;
- }
-
-- if (!index) {
-- regmap_write(hw->mirror, 0, 0);
-- regmap_write(hw->mirror, 4, 0);
-+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
++
++ 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 (!index) {
+- regmap_write(hw->mirror, 0, 0);
+- regmap_write(hw->mirror, 4, 0);
+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) {
+ kfree(hw);
+ goto unlock;
@@ -907,8 +985,30 @@
mtk_wed_hw_add_debugfs(hw);
hw_list[index] = hw;
+
++ mutex_unlock(&hw_lock);
++
++ return;
++
+ unlock:
+ mutex_unlock(&hw_lock);
++err_put_device:
++ put_device(&pdev->dev);
++err_of_node_put:
++ of_node_put(np);
+ }
+
+ void mtk_wed_exit(void)
+@@ -876,6 +1138,7 @@ void mtk_wed_exit(void)
+ hw_list[i] = NULL;
+ debugfs_remove(hw->debugfs_dir);
+ put_device(hw->dev);
++ of_node_put(hw->node);
+ kfree(hw);
+ }
+ }
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
-index 981ec61..9b17b74 100644
+index 981ec61..c9a20e4 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
@@ -8,6 +8,19 @@
@@ -931,20 +1031,27 @@
struct mtk_eth;
-@@ -23,6 +36,7 @@ struct mtk_wed_hw {
+@@ -18,11 +31,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;
-+ u32 wdma_phy;
++ u8 version;
char dirname[5];
int irq;
int index;
-@@ -101,14 +115,14 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
+@@ -101,14 +116,16 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
}
void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, int index);
-+ void __iomem *wdma, u32 wdma_phy, 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);
@@ -952,7 +1059,8 @@
static inline void
mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, int index)
-+ void __iomem *wdma, u32 wdma_phy, int index)
++ void __iomem *wdma, phys_addr_t wdma_phy,
++ int index)
{
}
static inline void
@@ -971,26 +1079,18 @@
struct mtk_wed_hw *hw = s->private;
struct mtk_wed_device *dev = hw->wed_dev;
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index 0a0465e..a9b9e2a 100644
+index 0a0465e..e66acda 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -4,9 +4,15 @@
- #ifndef __MTK_WED_REGS_H
+@@ -5,6 +5,7 @@
#define __MTK_WED_REGS_H
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(13, 0)
-+#define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(14)
-+#define MTK_WDMA_DESC_CTRL_BURST BIT(15)
-+#else
#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)
-+#endif
#define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16)
- #define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30)
- #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
-@@ -18,6 +24,14 @@ struct mtk_wdma_desc {
+@@ -18,6 +19,14 @@ struct mtk_wdma_desc {
__le32 info;
} __packed __aligned(4);
@@ -1005,7 +1105,7 @@
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
#define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
-@@ -41,6 +55,7 @@ struct mtk_wdma_desc {
+@@ -41,6 +50,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)
@@ -1013,7 +1113,7 @@
#define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
#define MTK_WED_EXT_INT_STATUS 0x020
-@@ -49,6 +64,10 @@ struct mtk_wdma_desc {
+@@ -49,6 +59,10 @@ struct mtk_wdma_desc {
#define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4)
#define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8)
#define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9)
@@ -1024,7 +1124,7 @@
#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
#define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
-@@ -57,16 +76,23 @@ struct mtk_wdma_desc {
+@@ -57,16 +71,23 @@ 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)
@@ -1051,36 +1151,21 @@
#define MTK_WED_EXT_INT_MASK 0x028
-@@ -80,10 +106,6 @@ struct mtk_wdma_desc {
-
+@@ -81,6 +102,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_START GENMASK(15, 0)
--#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
--
- #define MTK_WED_TX_BM_BUF_LEN 0x08c
+ #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)
- #define MTK_WED_TX_BM_INTF 0x09c
-@@ -93,9 +115,38 @@ struct mtk_wdma_desc {
- #define MTK_WED_TX_BM_INTF_TKID_READ BIT(29)
+@@ -94,7 +116,25 @@ struct mtk_wdma_desc {
#define MTK_WED_TX_BM_DYN_THR 0x0a0
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#define MTK_WED_TX_BM_DYN_THR_LO GENMASK(8, 0)
-+#define MTK_WED_TX_BM_DYN_THR_HI GENMASK(24, 16)
-+
-+#define MTK_WED_TX_BM_TKID 0x0c8
-+#define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
-+#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-+#else
#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_TKID 0x088
-+#define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
-+#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
-+#endif
++#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)
@@ -1097,11 +1182,10 @@
+#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 +176,7 @@ struct mtk_wdma_desc {
+@@ -125,6 +165,7 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
#define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
@@ -1109,7 +1193,7 @@
#define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10)
-@@ -139,6 +191,19 @@ struct mtk_wdma_desc {
+@@ -139,6 +180,19 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY BIT(1)
#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN BIT(2)
#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
@@ -1129,7 +1213,7 @@
#define MTK_WED_WPDMA_GLO_CFG_RX_BT_SIZE GENMASK(5, 4)
#define MTK_WED_WPDMA_GLO_CFG_TX_WB_DDONE BIT(6)
#define MTK_WED_WPDMA_GLO_CFG_BIG_ENDIAN BIT(7)
-@@ -152,24 +217,54 @@ struct mtk_wdma_desc {
+@@ -152,24 +206,54 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_GLO_CFG_FIRST_TOKEN_ONLY BIT(26)
#define MTK_WED_WPDMA_GLO_CFG_OMIT_RX_INFO BIT(27)
#define MTK_WED_WPDMA_GLO_CFG_OMIT_TX_INFO BIT(28)
@@ -1185,7 +1269,7 @@
#define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
#define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
-@@ -203,14 +298,22 @@ struct mtk_wdma_desc {
+@@ -203,14 +287,22 @@ struct mtk_wdma_desc {
#define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
#define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
@@ -1209,7 +1293,7 @@
#define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4)
#define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
-@@ -221,14 +324,21 @@ struct mtk_wdma_desc {
+@@ -221,14 +313,21 @@ struct mtk_wdma_desc {
#define MTK_WED_RING_OFS_CPU_IDX 0x08
#define MTK_WED_RING_OFS_DMA_IDX 0x0c
@@ -1233,21 +1317,14 @@
#define MTK_WDMA_INT_MASK 0x228
#define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0)
diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index 7e00cca..ffd547a 100644
+index 7e00cca..4db70b0 100644
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -8,6 +8,19 @@
+@@ -8,12 +8,19 @@
#define MTK_WED_TX_QUEUES 2
+enum {
-+ MTK_NO_WED,
-+ MTK_WED_V1,
-+ MTK_WED_V2,
-+ MTK_WED_VMAX
-+};
-+
-+enum {
+ MTK_BUS_TYPE_PCIE,
+ MTK_BUS_TYPE_AXI,
+ MTK_BUS_TYPE_MAX
@@ -1256,20 +1333,24 @@
struct mtk_wed_hw;
struct mtk_wdma_desc;
-@@ -28,6 +41,7 @@ struct mtk_wed_device {
- bool init_done, running;
- int wdma_idx;
- int irq;
-+ u8 ver;
+ struct mtk_wed_ring {
+ struct mtk_wdma_desc *desc;
+ dma_addr_t desc_phys;
++ u32 desc_size;
+ int size;
+
+ u32 reg_base;
+@@ -42,9 +49,21 @@ struct mtk_wed_device {
- struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
- struct mtk_wed_ring txfree_ring;
-@@ -43,8 +57,17 @@ struct mtk_wed_device {
/* filled by driver: */
struct {
- struct pci_dev *pci_dev;
+- struct pci_dev *pci_dev;
++ union {
++ struct platform_device *platform_dev;
++ struct pci_dev *pci_dev;
++ };
++ enum mtk_wed_bus_tye bus_type;
+ void __iomem *base;
-+ u32 bus_type;
u32 wpdma_phys;
+ u32 wpdma_int;
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3007-add-wed-tx-wds-support-for-netsys2.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3007-add-wed-tx-wds-support-for-netsys2.patch
index aaa6c48..d8c1c8c 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3007-add-wed-tx-wds-support-for-netsys2.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3007-add-wed-tx-wds-support-for-netsys2.patch
@@ -1,20 +1,20 @@
-From 396ce749479219467ea3f1123d5e9a303e5051ec Mon Sep 17 00:00:00 2001
+From 7c68ae1b991064bc0904313c56b83d2f3e03ccd7 Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:03:33 +0800
-Subject: [PATCH 08/22] add-wed-tx-wds-support-for-mt7986
+Subject: [PATCH 07/24] add-wed-tx-wds-support-for-netsys2
---
- drivers/net/ethernet/mediatek/mtk_wed.c | 8 +++++++-
+ drivers/net/ethernet/mediatek/mtk_wed.c | 6 ++++--
drivers/net/ethernet/mediatek/mtk_wed_regs.h | 1 +
include/linux/soc/mediatek/mtk_wed.h | 3 +++
- 3 files changed, 11 insertions(+), 1 deletion(-)
+ 3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 0588e32..23e3dc5 100644
+index 02e06a8..ea8b2db 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -797,7 +797,7 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- val |= BIT(0);
+@@ -813,7 +813,7 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ 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);
@@ -22,31 +22,24 @@
}
mtk_wed_dma_enable(dev);
-@@ -809,6 +809,7 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- __releases(RCU)
- {
- struct mtk_wed_hw *hw;
-+ u16 ver;
- int ret = 0;
+@@ -869,9 +869,11 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
-@@ -839,6 +840,11 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ mtk_wed_hw_init_early(dev);
- dev->ver = FIELD_GET(MTK_WED_REV_ID_MAJOR,
- wed_r32(dev, MTK_WED_REV_ID));
-+ if (dev->ver > MTK_WED_V1)
-+ ver = FIELD_GET(MTK_WED_REV_ID_MINOR,
-+ wed_r32(dev, MTK_WED_REV_ID));
-+
-+ dev->rev_id = ((dev->ver << 28) | ver << 16);
+- if (hw->hifsys)
++ if (hw->version == 1)
+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
+ BIT(hw->index), 0);
++ else
++ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
- ret = mtk_wed_buffer_alloc(dev);
- if (ret) {
+ out:
+ mutex_unlock(&hw_lock);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index a9b9e2a..14e0e21 100644
+index e66acda..e797e9d 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -31,6 +31,7 @@ struct mtk_wdma_desc {
+@@ -26,6 +26,7 @@ struct mtk_wdma_desc {
#define MTK_WED_REV_ID 0x000
#define MTK_WED_REV_ID_MAJOR GENMASK(7, 0)
#endif
@@ -55,18 +48,18 @@
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index ffd547a..e914cb4 100644
+index 4db70b0..00036f9 100644
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -42,6 +42,7 @@ struct mtk_wed_device {
+@@ -35,6 +35,7 @@ struct mtk_wed_device {
+ bool init_done, running;
int wdma_idx;
int irq;
- u8 ver;
+ u32 rev_id;
struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
struct mtk_wed_ring txfree_ring;
-@@ -72,6 +73,8 @@ struct mtk_wed_device {
+@@ -68,6 +69,8 @@ struct mtk_wed_device {
u16 token_start;
unsigned int nbuf;
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3008-add-wed-rx-support-for-netsys2.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3008-add-wed-rx-support-for-netsys2.patch
index 7efa9df..fd64dcf 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3008-add-wed-rx-support-for-netsys2.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3008-add-wed-rx-support-for-netsys2.patch
@@ -1,24 +1,25 @@
-From d35f304a7d0ec9612064a41b98338d9f712fbb48 Mon Sep 17 00:00:00 2001
+From fad15885ddf2f138ed3ec652b4fcd0cbdf54bf4e Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:04:53 +0800
-Subject: [PATCH 09/22] add-wed-rx-support-for-mt7896
+Subject: [PATCH 08/24] add-wed-rx-support-for-netsys2
---
+ arch/arm64/boot/dts/mediatek/mt7981.dtsi | 23 +-
arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 42 +-
arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 42 +-
drivers/net/ethernet/mediatek/Makefile | 2 +-
- drivers/net/ethernet/mediatek/mtk_wed.c | 639 ++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_wed.c | 645 ++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_wed.h | 51 ++
drivers/net/ethernet/mediatek/mtk_wed_ccif.c | 133 ++++
drivers/net/ethernet/mediatek/mtk_wed_ccif.h | 45 ++
.../net/ethernet/mediatek/mtk_wed_debugfs.c | 90 +++
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 586 ++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 96 +++
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 144 +++-
- drivers/net/ethernet/mediatek/mtk_wed_wo.c | 564 ++++++++++++++++
- drivers/net/ethernet/mediatek/mtk_wed_wo.h | 324 +++++++++
- include/linux/soc/mediatek/mtk_wed.h | 126 +++-
- 14 files changed, 2801 insertions(+), 83 deletions(-)
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 604 ++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 97 +++
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 143 +++-
+ drivers/net/ethernet/mediatek/mtk_wed_wo.c | 564 +++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_wed_wo.h | 325 +++++++++
+ include/linux/soc/mediatek/mtk_wed.h | 114 +++-
+ 15 files changed, 2822 insertions(+), 98 deletions(-)
create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.c
create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ccif.h
create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c
@@ -26,8 +27,52 @@
create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c
create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h
+diff --git a/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+index cb8f4e1..39b99d8 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7981.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+@@ -97,26 +97,29 @@
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif0>;
++ mediatek,wocpu_ilm = <&wocpu0_ilm>;
++ mediatek,wocpu_dlm = <&wocpu0_dlm>;
++ mediatek,wocpu_boot = <&cpu_boot>;
++ mediatek,wocpu_emi = <&wocpu0_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
+ };
+
+- ap2woccif: ap2woccif@151A5000 {
+- compatible = "mediatek,ap2woccif";
+- reg = <0 0x151A5000 0 0x1000>,
+- <0 0x151AD000 0 0x1000>;
++ ap2woccif0: ap2woccif@151A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x151A5000 0 0x1000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+- };
++ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
++ };
+
+ wocpu0_ilm: wocpu0_ilm@151E0000 {
+ compatible = "mediatek,wocpu0_ilm";
+ reg = <0 0x151E0000 0 0x8000>;
+ };
+
+- wocpu_dlm: wocpu_dlm@151E8000 {
++ wocpu0_dlm: wocpu_dlm@151E8000 {
+ compatible = "mediatek,wocpu_dlm";
+- reg = <0 0x151E8000 0 0x2000>,
+- <0 0x151F8000 0 0x2000>;
++ reg = <0 0x151E8000 0 0x2000>;
+
+ resets = <ðsysrst 0>;
+ reset-names = "wocpu_rst";
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-index 3ff8994..c5dc5e8 100644
+index 9c288fc..e6f50d5 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -65,6 +65,12 @@
@@ -98,7 +143,7 @@
resets = <ðsysrst 0>;
reset-names = "wocpu_rst";
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
-index 043e509..bfd2a02 100644
+index 02feaa9..3bacadc 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
@@ -65,6 +65,12 @@
@@ -168,50 +213,6 @@
resets = <ðsysrst 0>;
reset-names = "wocpu_rst";
-diff --git a/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-index d34943e7..512fb5d6 100644
---- a/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7981.dtsi
-@@ -97,26 +97,29 @@
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
- mediatek,wed_pcie = <&wed_pcie>;
-+ mediatek,ap2woccif = <&ap2woccif0>;
-+ mediatek,wocpu_ilm = <&wocpu0_ilm>;
-+ mediatek,wocpu_dlm = <&wocpu0_dlm>;
-+ mediatek,wocpu_boot = <&cpu_boot>;
-+ mediatek,wocpu_emi = <&wocpu0_emi>;
-+ mediatek,wocpu_data = <&wocpu_data>;
- };
-
-- ap2woccif: ap2woccif@151A5000 {
-- compatible = "mediatek,ap2woccif";
-- reg = <0 0x151A5000 0 0x1000>,
-- <0 0x151AD000 0 0x1000>;
-+ ap2woccif0: ap2woccif@151A5000 {
-+ compatible = "mediatek,ap2woccif", "syscon";
-+ reg = <0 0x151A5000 0 0x1000>;
- interrupt-parent = <&gic>;
-- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
-- };
-+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-
- wocpu0_ilm: wocpu0_ilm@151E0000 {
- compatible = "mediatek,wocpu0_ilm";
- reg = <0 0x151E0000 0 0x8000>;
- };
-
-- wocpu_dlm: wocpu_dlm@151E8000 {
-+ wocpu0_dlm: wocpu_dlm@151E8000 {
- compatible = "mediatek,wocpu_dlm";
-- reg = <0 0x151E8000 0 0x2000>,
-- <0 0x151F8000 0 0x2000>;
-+ reg = <0 0x151E8000 0 0x2000>;
-
- resets = <ðsysrst 0>;
- reset-names = "wocpu_rst";
diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
index 4090132..fdbb90f 100644
--- a/drivers/net/ethernet/mediatek/Makefile
@@ -224,10 +225,10 @@
+obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o mtk_wed_wo.o mtk_wed_mcu.o mtk_wed_ccif.o
obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtk_hnat/
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 23e3dc5..4b2f1a2 100644
+index ea8b2db..ad9f3d5 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -13,11 +13,19 @@
+@@ -13,10 +13,13 @@
#include <linux/debugfs.h>
#include <linux/iopoll.h>
#include <linux/soc/mediatek/mtk_wed.h>
@@ -236,19 +237,12 @@
#include "mtk_wed_regs.h"
#include "mtk_wed.h"
#include "mtk_ppe.h"
--
+#include "mtk_wed_mcu.h"
+#include "mtk_wed_wo.h"
-+
-+struct wo_cmd_ring {
-+ u32 q_base;
-+ u32 cnt;
-+ u32 unit;
-+};
+
static struct mtk_wed_hw *hw_list[2];
static DEFINE_MUTEX(hw_lock);
-
-@@ -51,6 +59,56 @@ wdma_set(struct mtk_wed_device *dev, u32 reg, u32 mask)
+@@ -51,12 +54,65 @@ wdma_set(struct mtk_wed_device *dev, u32 reg, u32 mask)
wdma_m32(dev, reg, 0, mask);
}
@@ -258,92 +252,107 @@
+ wdma_m32(dev, reg, mask, 0);
+}
+
+ static u32
+ mtk_wed_read_reset(struct mtk_wed_device *dev)
+ {
+ return wed_r32(dev, MTK_WED_RESET);
+ }
+
+static u32
+mtk_wdma_read_reset(struct mtk_wed_device *dev)
+{
+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
+}
+
-+static void
++static int
+mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+{
-+ u32 status;
-+ u32 mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
-+ int i;
++ u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
++ int i, ret;
+
+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
-+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 1000))
-+ WARN_ON_ONCE(1);
++ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
++ !(status & mask), 0, 1000)
++ if (ret)
++ dev_err(dev->hw->dev, "rx reset failed \n");
+
-+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
-+ if (!dev->rx_wdma[i].desc) {
-+ wdma_w32(dev, MTK_WDMA_RING_RX(i) +
-+ MTK_WED_RING_OFS_CPU_IDX, 0);
++ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
++ if (!dev->rx_wdma[i].desc)
++ continue;
++
++ wdma_w32(dev,
++ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
+ }
+}
+
+static void
+mtk_wdma_tx_reset(struct mtk_wed_device *dev)
+{
-+ u32 status;
-+ u32 mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
++ u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
+ int i;
+
+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
+ !(status & mask), 0, 1000))
-+ WARN_ON_ONCE(1);
++ dev_err(dev->hw->dev, "tx reset failed \n");
+
-+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-+ if (!dev->tx_wdma[i].desc) {
-+ wdma_w32(dev, MTK_WDMA_RING_TX(i) +
-+ MTK_WED_RING_OFS_CPU_IDX, 0);
++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
++ if (!dev->tx_wdma[i].desc)
++ continue;
++
++ wdma_w32(dev,
++ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
+ }
+}
+
- static u32
- mtk_wed_read_reset(struct mtk_wed_device *dev)
+ static void
+ mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
{
-@@ -68,6 +126,52 @@ mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
+@@ -68,6 +124,58 @@ mtk_wed_reset(struct mtk_wed_device *dev, u32 mask)
WARN_ON_ONCE(1);
}
++static u32
++mtk_wed_wo_read_status(struct mtk_wed_device *dev)
++{
++ return wed_r32(dev, MTK_WED_SCR0 + 4 * WED_DUMMY_CR_WO_STATUS);
++}
++
+static void
+mtk_wed_wo_reset(struct mtk_wed_device *dev)
+{
+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
+ u8 state = WO_STATE_DISABLE;
-+ u8 state_done = WOIF_DISABLE_DONE;
+ void __iomem *reg;
-+ u32 value;
-+ unsigned long timeout = jiffies + WOCPU_TIMEOUT;
++ u32 val;
+
+ mtk_wdma_tx_reset(dev);
+
+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
+
-+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
-+ &state, sizeof(state), false);
++ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
++ MTK_WED_WO_CMD_CHANGE_STATE, &state,
++ sizeof(state), false);
+
-+ do {
-+ value = wed_r32(dev, MTK_WED_SCR0 + 4 * WED_DUMMY_CR_WO_STATUS);
-+ } while (value != state_done && !time_after(jiffies, timeout));
++ if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val,
++ val == WOIF_DISABLE_DONE,
++ 100, WOCPU_TIMEOUT))
++ dev_err(dev->hw->dev, "failed to disable wed-wo\n");
+
+ reg = ioremap(WOCPU_MCUSYS_RESET_ADDR, 4);
-+ value = readl((void *)reg);
++ val = readl((void *)reg);
+ switch(dev->hw->index) {
+ case 0:
-+ value |= WOCPU_WO0_MCUSYS_RESET_MASK;
-+ writel(value, (void *)reg);
-+ value &= ~WOCPU_WO0_MCUSYS_RESET_MASK;
-+ writel(value, (void *)reg);
++ val |= WOCPU_WO0_MCUSYS_RESET_MASK;
++ writel(val, (void *)reg);
++ val &= ~WOCPU_WO0_MCUSYS_RESET_MASK;
++ writel(val, (void *)reg);
+ break;
+ case 1:
-+ value |= WOCPU_WO1_MCUSYS_RESET_MASK;
-+ writel(value, (void *)reg);
-+ value &= ~WOCPU_WO1_MCUSYS_RESET_MASK;
-+ writel(value, (void *)reg);
++ val |= WOCPU_WO1_MCUSYS_RESET_MASK;
++ writel(val, (void *)reg);
++ val &= ~WOCPU_WO1_MCUSYS_RESET_MASK;
++ writel(val, (void *)reg);
+ break;
+ default:
+ dev_err(dev->hw->dev, "wrong mtk_wed%d\n",
@@ -358,21 +367,58 @@
static struct mtk_wed_hw *
mtk_wed_assign(struct mtk_wed_device *dev)
{
-@@ -178,7 +282,7 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+@@ -102,7 +210,7 @@ mtk_wed_assign(struct mtk_wed_device *dev)
+ }
+
+ static int
+-mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
++mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+ {
+ struct mtk_wdma_desc *desc;
+ dma_addr_t desc_phys;
+@@ -124,16 +232,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
+ if (!page_list)
+ return -ENOMEM;
+
+- dev->buf_ring.size = ring_size;
+- dev->buf_ring.pages = page_list;
++ dev->tx_buf_ring.size = ring_size;
++ dev->tx_buf_ring.pages = page_list;
+
+ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
+ &desc_phys, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+- dev->buf_ring.desc = desc;
+- dev->buf_ring.desc_phys = desc_phys;
++ dev->tx_buf_ring.desc = desc;
++ dev->tx_buf_ring.desc_phys = desc_phys;
+
+ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
+ dma_addr_t page_phys, buf_phys;
+@@ -194,11 +302,11 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
+ }
+
+ static void
+-mtk_wed_free_buffer(struct mtk_wed_device *dev)
++mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
{
- struct mtk_wdma_desc *desc = dev->buf_ring.desc;
- void **page_list = dev->buf_ring.pages;
+- struct mtk_wdma_desc *desc = dev->buf_ring.desc;
+- void **page_list = dev->buf_ring.pages;
- int page_idx;
++ struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
++ void **page_list = dev->tx_buf_ring.pages;
+ int ring_size, page_idx;
int i;
if (!page_list)
-@@ -187,7 +291,14 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+@@ -207,7 +315,14 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
if (!desc)
goto free_pagelist;
- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
-+ if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+ } else {
+ ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
@@ -381,201 +427,141 @@
+
+ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
void *page = page_list[page_idx++];
+ dma_addr_t buf_addr;
- if (!page)
-@@ -198,13 +309,49 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+@@ -220,13 +335,64 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
__free_page(page);
}
- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc),
+- desc, dev->buf_ring.desc_phys);
+ dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
- desc, dev->buf_ring.desc_phys);
++ desc, dev->tx_buf_ring.desc_phys);
free_pagelist:
kfree(page_list);
}
+static int
-+mtk_wed_rx_bm_alloc(struct mtk_wed_device *dev)
++mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
+{
+ struct mtk_rxbm_desc *desc;
+ dma_addr_t desc_phys;
-+ int ring_size;
+
-+ ring_size = dev->wlan.rx_nbuf;
-+ dev->rx_buf_ring.size = ring_size;
-+ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
++ dev->rx_buf_ring.size = dev->wlan.rx_nbuf;
++ desc = dma_alloc_coherent(dev->hw->dev,
++ dev->wlan.rx_nbuf * sizeof(*desc),
+ &desc_phys, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ dev->rx_buf_ring.desc = desc;
+ dev->rx_buf_ring.desc_phys = desc_phys;
-+
+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
++
+ return 0;
+}
+
+static void
-+mtk_wed_free_rx_bm(struct mtk_wed_device *dev)
++mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
+{
+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
-+ int ring_size = dev->rx_buf_ring.size;
+
+ if (!desc)
+ return;
+
+ dev->wlan.release_rx_buf(dev);
+
-+ dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
++ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc),
+ desc, dev->rx_buf_ring.desc_phys);
+}
+
++static void
++mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev)
++{
++ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD,
++ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size));
++
++ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys);
++
++ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL |
++ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt));
++
++ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
++ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
++
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
++}
++
static void
- mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int scale)
+ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
{
-@@ -226,13 +373,22 @@ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
- mtk_wed_free_ring(dev, &dev->tx_wdma[i], dev->ver);
+@@ -237,6 +403,13 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
+ ring->desc, ring->desc_phys);
}
+static void
+mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
+{
-+ mtk_wed_free_rx_bm(dev);
-+ mtk_wed_free_ring(dev, &dev->rro.rro_ring, 1);
++ mtk_wed_free_rx_buffer(dev);
++ mtk_wed_free_ring(dev, &dev->rro.ring);
+}
+
static void
- mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
+ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
{
- u32 wdma_mask;
-
- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
--
-+ if (dev->ver > MTK_WED_V1)
-+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
-+ GENMASK(1, 0));
- /* wed control cr set */
- wed_set(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WDMA_INT_AGENT_EN |
-@@ -251,7 +407,7 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
- wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
- } 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 |
-@@ -262,22 +418,30 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG,
- dev->wlan.tx_tbit[1]));
+@@ -244,8 +417,8 @@ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
-- /* 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_WPDMA_INT_CTRL_RX,
-+ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
-+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
-+ dev->wlan.rx_tbit[0]) |
-+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
-+ dev->wlan.rx_tbit[1]));
- }
-- /* initail wdma interrupt agent */
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
- if (dev->ver == MTK_WED_V1) {
- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
- } else {
- wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
- wed_set(dev, MTK_WED_WDMA_INT_CTRL,
-- FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,dev->wdma_idx));
--
-+ FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,
-+ dev->wdma_idx));
- }
+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
+ mtk_wed_free_ring(dev, &dev->tx_ring[i]);
+- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+- mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
++ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
++ mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
+ }
- wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask);
-@@ -312,6 +476,40 @@ mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
+ static void
+@@ -277,6 +450,39 @@ mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
}
}
++#define MTK_WFMDA_RX_DMA_EN BIT(2)
+static void
+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
+{
-+#define MTK_WFMDA_RX_DMA_EN BIT(2)
++ u32 val;
++ int i;
+
-+ int timeout = 3;
-+ u32 cur_idx, regs;
++ if(!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED))
++ return;
+
-+ do {
-+ regs = MTK_WED_WPDMA_RING_RX_DATA(idx) +
-+ MTK_WED_RING_OFS_CPU_IDX;
-+ cur_idx = wed_r32(dev, regs);
++ for (i = 0; i < 3; i++) {
++ u32 cur_idx;
++
++ cur_idx = wed_r32(dev,
++ MTK_WED_WPDMA_RING_RX_DATA(idx) +
++ MTK_WED_RING_OFS_CPU_IDX);
+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
+ break;
+
+ usleep_range(100000, 200000);
-+ timeout--;
-+ } while (timeout > 0);
-+
-+ if (timeout) {
-+ unsigned int val;
-+
-+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
-+ dev->wlan.phy_base);
-+ val |= MTK_WFMDA_RX_DMA_EN;
++ }
+
-+ wifi_w32(dev, dev->wlan.wpdma_rx_glo -
-+ dev->wlan.phy_base, val);
-+ } else {
++ if (i == 3) {
+ dev_err(dev->hw->dev, "mtk_wed%d: rx dma enable failed!\n",
+ dev->hw->index);
++ return;
+ }
++
++ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) |
++ MTK_WFMDA_RX_DMA_EN;
++ wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val);
+}
+
static void
- mtk_wed_dma_enable(struct mtk_wed_device *dev)
+ mtk_wed_dma_disable(struct mtk_wed_device *dev)
{
-@@ -336,9 +534,15 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
- wdma_set(dev, MTK_WDMA_GLO_CFG,
- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
- } else {
-+ int idx = 0;
-+
- wed_set(dev, MTK_WED_WPDMA_CTRL,
- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
-
-+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
-+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-+
- 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);
-@@ -346,6 +550,15 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
- 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);
-+
-+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
-+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
-+ 0x2));
-+
-+ for (idx = 0; idx < MTK_WED_RX_QUEUES; idx++)
-+ mtk_wed_check_wfdma_rx_fill(dev, idx);
- }
- }
-
-@@ -363,19 +576,23 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
+@@ -291,22 +497,26 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
MTK_WED_GLO_CFG_TX_DMA_EN |
MTK_WED_GLO_CFG_RX_DMA_EN);
@@ -586,7 +572,7 @@
- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0);
+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
- if (dev->ver == MTK_WED_V1) {
+ 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);
@@ -596,125 +582,169 @@
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)
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
}
++
++ mtk_wed_set_512_support (dev, false);
}
-@@ -383,10 +600,12 @@ static void
- mtk_wed_stop(struct mtk_wed_device *dev)
- {
- mtk_wed_dma_disable(dev);
-+ mtk_wed_set_512_support(dev, false);
-
-- if (dev->ver > MTK_WED_V1)
-- mtk_wed_set_512_support(dev, false);
--
-+ if (dev->ver > MTK_WED_V1) {
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
-+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
-+ }
- mtk_wed_set_ext_int(dev, false);
-
- wed_clr(dev, MTK_WED_CTRL,
-@@ -395,6 +614,11 @@ mtk_wed_stop(struct mtk_wed_device *dev)
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
-
-+ if (dev->ver > MTK_WED_V1) {
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_BM_EN);
-+ }
-+
- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
+ static void
+@@ -327,6 +537,14 @@ mtk_wed_stop(struct mtk_wed_device *dev)
wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
-@@ -417,10 +641,21 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+ wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
++
++ if (dev->hw->version == 1)
++ return;
++
++ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
++ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
++
+ }
+
+ static void
+@@ -344,10 +562,23 @@ mtk_wed_detach(struct mtk_wed_device *dev)
mtk_wed_reset(dev, MTK_WED_RESET_WED);
-+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+- mtk_wed_free_buffer(dev);
++ if (mtk_wed_get_rx_capa(dev)) {
++ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
++ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
++ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
++ }
+
- mtk_wed_free_buffer(dev);
++ mtk_wed_free_tx_buffer(dev);
mtk_wed_free_tx_rings(dev);
-+ if (dev->ver > MTK_WED_V1) {
+
+- if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
++ if (mtk_wed_get_rx_capa(dev)) {
+ mtk_wed_wo_reset(dev);
+ mtk_wed_free_rx_rings(dev);
+ mtk_wed_wo_exit(hw);
++ mtk_wdma_rx_reset(dev);
+ }
+
-+ mtk_wdma_rx_reset(dev);
-
-- if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
wlan_node = dev->wlan.pci_dev->dev.of_node;
- 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,
-@@ -443,7 +678,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
+@@ -370,7 +601,7 @@ static void
+ mtk_wed_bus_init(struct mtk_wed_device *dev)
{
- #define PCIE_BASE_ADDR0 0x11280000
-
-- if (dev->wlan.bus_type == MTK_BUS_TYPE_PCIE) {
-+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
- struct device_node *node;
- void __iomem * base_addr;
- u32 value = 0;
-@@ -477,7 +712,6 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
- value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
- value = 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);
+ switch (dev->wlan.bus_type) {
+- case MTK_BUS_TYPE_PCIE: {
++ case MTK_WED_BUS_PCIE: {
+ struct device_node *np = dev->hw->eth->dev->of_node;
+ struct regmap *regs;
-@@ -485,7 +719,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
- value = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+@@ -402,7 +633,7 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
-- } else if (dev->wlan.bus_type == MTK_BUS_TYPE_AXI) {
-+ } else if (dev->wlan.bus_type == MTK_WED_BUS_AXI) {
+ break;
+ }
+- case MTK_BUS_TYPE_AXI:
++ 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));
-@@ -501,6 +735,9 @@ mtk_wed_set_wpdma(struct mtk_wed_device *dev)
+@@ -424,6 +655,8 @@ mtk_wed_set_wpdma(struct mtk_wed_device *dev)
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);
-+
+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
- } else {
- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
}
-@@ -549,24 +786,92 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
- FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL,
- MTK_WDMA_RING_RX(0)));
- }
-+}
+ }
-+static void
-+mtk_wed_rx_bm_hw_init(struct mtk_wed_device *dev)
+@@ -470,6 +703,141 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
+
+ }
+
++static int
++mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
++ int size)
+{
-+ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD,
-+ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size));
++ ring->desc = dma_alloc_coherent(dev->hw->dev,
++ size * sizeof(*ring->desc),
++ &ring->desc_phys, GFP_KERNEL);
++ if (!ring->desc)
++ return -ENOMEM;
+
-+ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys);
++ ring->desc_size = sizeof(*ring->desc);
++ ring->size = size;
++ memset(ring->desc, 0, size);
+
-+ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL |
-+ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt));
++ return 0;
++}
+
-+ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH,
-+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
++#define MTK_WED_MIOD_COUNT (MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT)
++static int
++mtk_wed_rro_alloc(struct mtk_wed_device *dev)
++{
++ struct device_node *np, *node = dev->hw->node;
++ struct mtk_wed_ring *ring;
++ struct resource res;
++ int ret;
+
-+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
- }
-
- static void
--mtk_wed_hw_init(struct mtk_wed_device *dev)
++ np = of_parse_phandle(node, "mediatek,wocpu_dlm", 0);
++ if (!np)
++ return -ENODEV;
++
++ ret = of_address_to_resource(np, 0, &res);
++ if (ret)
++ return ret;
++
++ dev->rro.rro_desc = ioremap(res.start, resource_size(&res));
++
++ ring = &dev->rro.ring;
++
++ dev->rro.miod_phys = res.start;
++ dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys;
++
++ if (mtk_wed_rro_ring_alloc(dev, ring, MTK_WED_RRO_QUE_CNT))
++ return -ENOMEM;
++
++ return 0;
++}
++
++static int
++mtk_wed_rro_cfg(struct mtk_wed_device *dev)
++{
++ struct mtk_wed_wo *wo = dev->hw->wed_wo;
++ struct {
++ struct {
++ __le32 base;
++ __le32 cnt;
++ __le32 unit;
++ } ring[2];
++
++ __le32 wed;
++ u8 version;
++ } req = {
++ .ring[0] = {
++ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE),
++ .cnt = cpu_to_le32(MTK_WED_MIOD_CNT),
++ .unit = cpu_to_le32(MTK_WED_MIOD_ENTRY_CNT),
++ },
++ .ring[1] = {
++ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE +
++ MTK_WED_MIOD_COUNT),
++ .cnt = cpu_to_le32(MTK_WED_FB_CMD_CNT),
++ .unit = cpu_to_le32(4),
++ },
++ };
++
++ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, MTK_WED_WO_CMD_WED_CFG,
++ &req, sizeof(req), true);
++}
++
++static void
+mtk_wed_rro_hw_init(struct mtk_wed_device *dev)
+{
+ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG,
@@ -723,19 +753,19 @@
+ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW,
+ MTK_WED_MIOD_ENTRY_CNT >> 2));
+
-+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_desc_phys);
++ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_phys);
+
+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1,
+ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT));
+
-+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_desc_phys);
++ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_phys);
+
+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1,
+ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT));
+
+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0);
+
-+ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.rro_ring.desc_phys);
++ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.ring.desc_phys);
+
+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
+ MTK_WED_RROQM_RST_IDX_MIOD |
@@ -753,12 +783,12 @@
+{
+ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM);
+
-+ do {
-+ udelay(100);
++ for (;;) {
++ usleep_range(100, 200);
+
+ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM))
+ break;
-+ } while (1);
++ }
+
+ /* configure RX_ROUTE_QM */
+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
@@ -771,85 +801,109 @@
+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+}
+
-+static void
-+mtk_wed_tx_hw_init(struct mtk_wed_device *dev)
+ static void
+ mtk_wed_hw_init(struct mtk_wed_device *dev)
{
- int size = dev->buf_ring.size;
- int rev_size = MTK_WED_TX_RING_SIZE / 2;
- int thr = 1;
+@@ -479,7 +847,7 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+ dev->init_done = true;
+ mtk_wed_set_ext_int(dev, false);
-- if (dev->init_done)
-- return;
--
-- dev->init_done = true;
-- mtk_wed_set_ext_int(dev, false);
--
- if (dev->ver > MTK_WED_V1) {
-- size = MTK_WED_WDMA_RING_SIZE * 2 + dev->buf_ring.size;
-+ size = MTK_WED_WDMA_RING_SIZE * ARRAY_SIZE(dev->tx_wdma) +
-+ dev->buf_ring.size;
- rev_size = size;
- thr = 0;
- }
-@@ -609,13 +914,46 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
++ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
+
+ wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
+
+@@ -487,7 +855,7 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
+ MTK_WED_TX_BM_CTRL_PAUSE |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
+- dev->buf_ring.size / 128) |
++ dev->tx_buf_ring.size / 128) |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
+ MTK_WED_TX_RING_SIZE / 256));
+ wed_w32(dev, MTK_WED_TX_BM_TKID,
+@@ -503,9 +871,9 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
+ MTK_WED_TX_BM_CTRL_PAUSE |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
+- dev->buf_ring.size / 128) |
++ dev->tx_buf_ring.size / 128) |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
+- dev->buf_ring.size / 128));
++ dev->tx_buf_ring.size / 128));
+ wed_w32(dev, MTK_WED_TX_BM_TKID_V2,
+ FIELD_PREP(MTK_WED_TX_BM_TKID_START,
+ dev->wlan.token_start) |
+@@ -518,9 +886,9 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+ 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) |
++ dev->tx_buf_ring.size / 128) |
+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
+- dev->buf_ring.size / 128));
++ dev->tx_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);
+@@ -528,27 +896,42 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+
+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
+
+- if (dev->hw->version == 1)
++ 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
++ } else {
+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
++ /* rx hw init*/
++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
++ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
++ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
++
++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
++
++ mtk_wed_rx_buffer_hw_init(dev);
++ mtk_wed_rro_hw_init(dev);
++ mtk_wed_route_qm_hw_init(dev);
++ }
+
+ 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, int scale)
-+mtk_wed_rx_hw_init(struct mtk_wed_device *dev)
+-mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size)
++mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx)
{
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
-+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
-+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
-+
-+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
-+
-+ mtk_wed_rx_bm_hw_init(dev);
-+ mtk_wed_rro_hw_init(dev);
-+ mtk_wed_route_qm_hw_init(dev);
-+}
-+
-+static void
-+mtk_wed_hw_init(struct mtk_wed_device *dev)
-+{
-+ if (dev->init_done)
-+ return;
-+
-+ dev->init_done = true;
-+ mtk_wed_set_ext_int(dev, false);
-+ mtk_wed_tx_hw_init(dev);
-+ if (dev->ver > MTK_WED_V1)
-+ mtk_wed_rx_hw_init(dev);
-+}
-+
-+static void
-+mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale, bool tx)
-+{
-+ __le32 ctrl;
+ void *head = (void *)ring->desc;
int i;
-+ if (tx)
-+ ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
-+ else
-+ ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST);
-+
for (i = 0; i < size; i++) {
+ 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->ctrl = ctrl;
++ if (tx)
++ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE);
++ else
++ desc->ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST);
desc->buf1 = 0;
desc->info = 0;
- desc += scale;
-@@ -674,7 +1012,7 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
- if (!desc)
+ }
+@@ -604,7 +987,8 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ if (!dev->tx_ring[i].desc)
continue;
-- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE, dev->ver);
-+ mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE, dev->ver, true);
+- mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE);
++ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE,
++ true);
}
if (mtk_wed_poll_busy(dev))
-@@ -692,6 +1030,8 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+@@ -622,6 +1006,8 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
@@ -858,38 +912,21 @@
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
-@@ -729,9 +1069,24 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
-
- }
+@@ -661,7 +1047,7 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
-+static int
-+mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-+ int size)
-+{
-+ ring->desc = dma_alloc_coherent(dev->hw->dev,
-+ size * sizeof(*ring->desc),
-+ &ring->desc_phys, GFP_KERNEL);
-+ if (!ring->desc)
-+ return -ENOMEM;
-+
-+ ring->size = size;
-+ memset(ring->desc, 0, size);
-+ return 0;
-+}
-+
static int
mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
-- int size, int scale)
-+ int size, int scale, bool tx)
+- int size, u32 desc_size)
++ int size, u32 desc_size, bool tx)
{
- ring->desc = dma_alloc_coherent(dev->hw->dev,
- size * sizeof(*ring->desc) * scale,
-@@ -740,17 +1095,18 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
- return -ENOMEM;
+ ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size,
+ &ring->desc_phys, GFP_KERNEL);
+@@ -670,18 +1056,23 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
+ ring->desc_size = desc_size;
ring->size = size;
-- mtk_wed_ring_reset(ring->desc, size, scale);
-+ mtk_wed_ring_reset(ring->desc, size, scale, tx);
+- mtk_wed_ring_reset(ring, size);
++ mtk_wed_ring_reset(ring, size, tx);
return 0;
}
@@ -898,25 +935,36 @@
-mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
{
- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
+- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
++ struct mtk_wed_ring *wdma;
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, dev->ver))
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ dev->ver, true))
+- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size))
++ if (idx >= ARRAY_SIZE(dev->rx_wdma))
++ return -EINVAL;
++
++ wdma = &dev->rx_wdma[idx];
++ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
++ true))
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -767,22 +1123,143 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+@@ -698,6 +1089,62 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
return 0;
}
+static int
+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+{
-+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
++ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
++ struct mtk_wed_ring *wdma;
+
++ if (idx >= ARRAY_SIZE(dev->tx_wdma))
++ return -EINVAL;
++
++ wdma = &dev->tx_wdma[idx];
+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ dev->ver, true))
++ desc_size, true))
+ return -ENOMEM;
+
+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
@@ -928,136 +976,117 @@
+ wdma_w32(dev,
+ MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
+
-+ if (idx == 0) {
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX
-+ + MTK_WED_RING_OFS_BASE, wdma->desc_phys);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX
-+ + MTK_WED_RING_OFS_COUNT, size);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX
-+ + MTK_WED_RING_OFS_CPU_IDX, 0);
-+ wed_w32(dev, MTK_WED_WDMA_RING_TX
-+ + MTK_WED_RING_OFS_DMA_IDX, 0);
++ if (!idx) {
++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
++ wdma->desc_phys);
++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_COUNT,
++ size);
++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_CPU_IDX,
++ 0);
++ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_DMA_IDX,
++ 0);
+ }
+
+ return 0;
+}
+
-+static int
-+mtk_wed_rro_alloc(struct mtk_wed_device *dev)
++static void
++mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
++ u32 reason, u32 hash)
+{
-+ struct device_node *np, *node = dev->hw->node;
-+ struct mtk_wed_ring *ring;
-+ struct resource res;
-+ int ret;
-+
-+ np = of_parse_phandle(node, "mediatek,wocpu_dlm", 0);
-+ if (!np)
-+ return -ENODEV;
-+
-+ ret = of_address_to_resource(np, 0, &res);
-+ if (ret)
-+ return ret;
-+
-+ dev->rro.rro_desc = ioremap(res.start, resource_size(&res));
-+
-+ ring = &dev->rro.rro_ring;
-+
-+ dev->rro.miod_desc_phys = res.start;
-+
-+ dev->rro.mcu_view_miod = MTK_WED_WOCPU_VIEW_MIOD_BASE;
-+ dev->rro.fdbk_desc_phys = MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT
-+ + dev->rro.miod_desc_phys;
-+
-+ if (mtk_wed_rro_ring_alloc(dev, ring, MTK_WED_RRO_QUE_CNT))
-+ return -ENOMEM;
-+
-+ return 0;
-+}
++ struct mtk_eth *eth = dev->hw->eth;
++ struct ethhdr *eh;
+
-+static int
-+mtk_wed_rro_cfg(struct mtk_wed_device *dev)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ struct {
-+ struct wo_cmd_ring ring[2];
++ if (!skb)
++ return;
+
-+ u32 wed;
-+ u8 ver;
-+ } req = {
-+ .ring = {
-+ [0] = {
-+ .q_base = dev->rro.mcu_view_miod,
-+ .cnt = MTK_WED_MIOD_CNT,
-+ .unit = MTK_WED_MIOD_ENTRY_CNT,
-+ },
-+ [1] = {
-+ .q_base = dev->rro.mcu_view_miod +
-+ MTK_WED_MIOD_ENTRY_CNT *
-+ MTK_WED_MIOD_CNT,
-+ .cnt = MTK_WED_FB_CMD_CNT,
-+ .unit = 4,
-+ },
-+ },
-+ .wed = 0,
-+ };
++ if (reason != MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
++ return;
+
-+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_WED_CFG,
-+ &req, sizeof(req), true);
++ skb_set_mac_header(skb, 0);
++ eh = eth_hdr(skb);
++ skb->protocol = eh->h_proto;
++ mtk_ppe_check_skb(eth->ppe[dev->hw->index], skb, hash);
+}
+
-+static int
-+mtk_wed_send_msg(struct mtk_wed_device *dev, int cmd_id, void *data, int len)
-+{
-+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+
-+ if (dev->ver == MTK_WED_V1)
-+ return 0;
+ static void
+ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+ {
+@@ -720,6 +1167,8 @@ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+
+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
+ } else {
++ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
++ GENMASK(1, 0));
+ /* initail tx interrupt trigger */
+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
+@@ -738,6 +1187,16 @@ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
+ dev->wlan.txfree_tbit));
+
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
++ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
++ dev->wlan.rx_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
++ dev->wlan.rx_tbit[1]));
+
-+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, cmd_id, data, len, true);
-+}
+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
+ wed_set(dev, MTK_WED_WDMA_INT_CTRL,
+ FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,dev->wdma_idx));
+@@ -775,9 +1234,15 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
+ wdma_set(dev, MTK_WDMA_GLO_CFG,
+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
+ } else {
++ int i;
+
-+static void
-+mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
-+ u32 reason, u32 hash)
-+{
-+ int idx = dev->hw->index;
-+ struct mtk_eth *eth = dev->hw->eth;
-+ struct ethhdr *eh;
+ wed_set(dev, MTK_WED_WPDMA_CTRL,
+ MTK_WED_WPDMA_CTRL_SDL1_FIXED);
+
++ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
++ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
++ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
+
-+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
-+ if (!skb)
-+ return;
+ 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);
+@@ -785,18 +1250,26 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
+ 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);
+
-+ skb_set_mac_header(skb, 0);
-+ eh = eth_hdr(skb);
-+ skb->protocol = eh->h_proto;
-+ mtk_ppe_check_skb(eth->ppe[idx], skb, hash);
-+ }
-+}
++ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
++ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
++ 0x2));
+
++ for (i = 0; i < MTK_WED_RX_QUEUES; i++)
++ mtk_wed_check_wfdma_rx_fill(dev, i);
+ }
+ }
+
static void
mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
{
- u32 wdma_mask;
-- int i;
-+ int i, ret;
+ int i;
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
- if (!dev->tx_wdma[i].desc)
+- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+- if (!dev->tx_wdma[i].desc)
- mtk_wed_wdma_ring_setup(dev, i, 16);
--
++ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
++ if (!dev->rx_wdma[i].desc)
+ mtk_wed_wdma_rx_ring_setup(dev, i, 16);
- mtk_wed_hw_init(dev);
-
- mtk_wed_set_int(dev, irq_mask);
--
--
- mtk_wed_set_ext_int(dev, true);
- if (dev->ver == MTK_WED_V1) {
-@@ -797,8 +1274,20 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
- val |= BIT(0);
+ mtk_wed_hw_init(dev);
+@@ -813,9 +1286,22 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ 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, dev->wlan.wcid_512);
@@ -1070,75 +1099,83 @@
+ wed_r32(dev, MTK_WED_EXT_INT_MASK1);
+ wed_r32(dev, MTK_WED_EXT_INT_MASK2);
+
-+ ret = mtk_wed_rro_cfg(dev);
-+ if (ret)
++ if (mtk_wed_rro_cfg(dev))
+ return;
++
}
-+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
++ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
++
mtk_wed_dma_enable(dev);
dev->running = true;
-@@ -809,6 +1298,7 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- __releases(RCU)
- {
- struct mtk_wed_hw *hw;
-+ struct device *device;
- u16 ver;
- int ret = 0;
-
-@@ -829,6 +1319,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- goto out;
+ }
+@@ -844,7 +1330,7 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ if (!hw) {
+ module_put(THIS_MODULE);
+ ret = -ENODEV;
+- goto out;
++ goto unlock;
}
-+ 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->ver);
-+
- dev->hw = hw;
+ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE ?
+@@ -856,26 +1342,40 @@ mtk_wed_attach(struct mtk_wed_device *dev)
dev->dev = hw->dev;
dev->irq = hw->irq;
-@@ -847,9 +1343,17 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- dev->rev_id = ((dev->ver << 28) | ver << 16);
+ dev->wdma_idx = hw->index;
++ dev->version = hw->version;
+
+ if (hw->eth->dma_dev == hw->eth->dev &&
+ of_dma_is_coherent(hw->eth->dev->of_node))
+ mtk_eth_set_dma_device(hw->eth, hw->dev);
- ret = mtk_wed_buffer_alloc(dev);
+- ret = mtk_wed_buffer_alloc(dev);
- if (ret) {
- mtk_wed_detach(dev);
-- goto out;
++ ret = mtk_wed_tx_buffer_alloc(dev);
+ if (ret)
-+ goto error;
+ goto out;
+- }
+
-+ if (dev->ver > MTK_WED_V1) {
-+ ret = mtk_wed_rx_bm_alloc(dev);
++ if (mtk_wed_get_rx_capa(dev)) {
++ ret = mtk_wed_rx_buffer_alloc(dev);
+ if (ret)
-+ goto error;
++ goto out;
+
+ ret = mtk_wed_rro_alloc(dev);
+ if (ret)
-+ goto error;
- }
++ goto out;
++ }
mtk_wed_hw_init_early(dev);
-@@ -857,7 +1361,12 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- if (dev->ver == MTK_WED_V1)
+
+- if (hw->version == 1)
++ if (hw->version == 1) {
regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
BIT(hw->index), 0);
-+ else
+- else
++ } else {
+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
+ ret = mtk_wed_wo_init(hw);
++ }
-+error:
+ out:
+ if (ret)
+ mtk_wed_detach(dev);
- out:
++unlock:
mutex_unlock(&hw_lock);
-@@ -883,10 +1392,10 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+ return ret;
+@@ -898,13 +1398,14 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+ * WDMA RX.
+ */
- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
+- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring));
++ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
++ return -EINVAL;
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, 1))
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, 1, true))
+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
+- sizeof(*ring->desc)))
++ sizeof(*ring->desc), true))
return -ENOMEM;
- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
@@ -1146,7 +1183,7 @@
return -ENOMEM;
ring->reg_base = MTK_WED_RING_TX(idx);
-@@ -933,6 +1442,35 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
+@@ -948,6 +1449,37 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
return 0;
}
@@ -1155,10 +1192,11 @@
+{
+ struct mtk_wed_ring *ring = &dev->rx_ring[idx];
+
-+ BUG_ON(idx > ARRAY_SIZE(dev->rx_ring));
-+
++ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
++ return -EINVAL;
+
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, 1, false))
++ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
++ sizeof(*ring->desc), false))
+ return -ENOMEM;
+
+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
@@ -1166,6 +1204,7 @@
+
+ ring->reg_base = MTK_WED_RING_RX_DATA(idx);
+ ring->wpdma = regs;
++ ring->flags |= MTK_WED_RING_CONFIGURED;
+
+ /* WPDMA -> WED */
+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
@@ -1182,16 +1221,17 @@
static u32
mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
{
-@@ -1022,6 +1560,8 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -1037,7 +1569,9 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ static const struct mtk_wed_ops wed_ops = {
.attach = mtk_wed_attach,
.tx_ring_setup = mtk_wed_tx_ring_setup,
- .txfree_ring_setup = mtk_wed_txfree_ring_setup,
+ .rx_ring_setup = mtk_wed_rx_ring_setup,
-+ .msg_update = mtk_wed_send_msg,
+ .txfree_ring_setup = mtk_wed_txfree_ring_setup,
++ .msg_update = mtk_wed_mcu_msg_update,
.start = mtk_wed_start,
.stop = mtk_wed_stop,
.reset_dma = mtk_wed_reset_dma,
-@@ -1030,6 +1570,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -1046,6 +1580,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
.irq_get = mtk_wed_irq_get,
.irq_set_mask = mtk_wed_irq_set_mask,
.detach = mtk_wed_detach,
@@ -1199,24 +1239,8 @@
};
struct device_node *eth_np = eth->dev->of_node;
struct platform_device *pdev;
-@@ -1069,6 +1610,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- hw->wdma_phy = wdma_phy;
- hw->index = index;
- hw->irq = irq;
-+ hw->ver = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
-
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
-@@ -1085,6 +1627,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- regmap_write(hw->mirror, 0, 0);
- regmap_write(hw->mirror, 4, 0);
- }
-+ hw->ver = MTK_WED_V1;
- }
-
- mtk_wed_hw_add_debugfs(hw);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
-index 9b17b74..8ef5253 100644
+index c9a20e4..1bfd96f 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
@@ -13,6 +13,7 @@
@@ -1236,29 +1260,22 @@
+#define MTK_WED_RRO_QUE_CNT 8192
+#define MTK_WED_MIOD_ENTRY_CNT 128
+
-+#define MODULE_ID_WO 1
++#define MTK_WED_MODULE_ID_WO 1
struct mtk_eth;
+struct mtk_wed_wo;
struct mtk_wed_hw {
struct device_node *node;
-@@ -34,12 +42,14 @@ struct mtk_wed_hw {
+@@ -35,6 +43,7 @@ struct mtk_wed_hw {
struct regmap *mirror;
struct dentry *debugfs_dir;
struct mtk_wed_device *wed_dev;
+ struct mtk_wed_wo *wed_wo;
u32 debugfs_reg;
u32 num_flows;
- u32 wdma_phy;
- char dirname[5];
- int irq;
- int index;
-+ u32 ver;
- };
-
- struct mtk_wdma_info {
-@@ -66,6 +76,18 @@ wed_r32(struct mtk_wed_device *dev, u32 reg)
+ u8 version;
+@@ -67,6 +76,18 @@ wed_r32(struct mtk_wed_device *dev, u32 reg)
return val;
}
@@ -1277,8 +1294,8 @@
static inline void
wdma_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
{
-@@ -114,6 +136,23 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
- writel(val, dev->txfree_ring.wpdma + reg);
+@@ -97,6 +118,24 @@ wpdma_tx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val)
+ writel(val, dev->tx_ring[ring].wpdma + reg);
}
+static inline u32
@@ -1298,10 +1315,11 @@
+
+ writel(val, dev->rx_ring[ring].wpdma + reg);
+}
- void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, u32 wdma_phy, int index);
- void mtk_wed_exit(void);
-@@ -146,4 +185,16 @@ static inline void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
++
+ static inline u32
+ wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg)
+ {
+@@ -149,4 +188,16 @@ static inline void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
}
#endif
@@ -1509,7 +1527,7 @@
+
+#endif
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
-index f420f18..4a9e684 100644
+index f420f18..7d8be99 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
@@ -2,6 +2,7 @@
@@ -1645,16 +1663,16 @@
debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
-+ if (hw->ver != MTK_WED_V1) {
++ if (hw->version != 1) {
+ wed_wo_mcu_debugfs(hw, dir);
+ }
}
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
new file mode 100644
-index 0000000..96e30a3
+index 0000000..be63406
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -0,0 +1,590 @@
+@@ -0,0 +1,604 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/skbuff.h>
@@ -1743,6 +1761,20 @@
+ return ret;
+}
+
++int
++mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, int len)
++{
++ struct mtk_wed_wo *wo = dev->hw->wed_wo;
++
++ if (dev->hw->version == 1)
++ return 0;
++
++ if (WARN_ON(!wo))
++ return -ENODEV;
++
++ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, true);
++}
++
+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo,
+ struct sk_buff *skb)
+{
@@ -1804,7 +1836,7 @@
+ req.arg0 = (u32)exp->phys;
+ req.arg1 = (u32)exp->log_size;
+
-+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_EXCEPTION_INIT,
++ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, MTK_WED_WO_CMD_EXCEPTION_INIT,
+ &req, sizeof(req), false);
+
+free:
@@ -2030,7 +2062,7 @@
+ hdr->length = cpu_to_le16(skb->len);
+ hdr->uni_id = seq;
+
-+ if (to_id == MODULE_ID_WO)
++ if (to_id == MTK_WED_MODULE_ID_WO)
+ hdr->flag |= WARP_CMD_FLAG_FROM_TO_WO;
+
+ if (wait_resp && wait_seq)
@@ -2225,7 +2257,7 @@
+ return count;
+ }
+
-+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, cmd_id, (void *)msgbuf, sizeof(struct wo_cmd_query), wait);
++ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, cmd_id, (void *)msgbuf, sizeof(struct wo_cmd_query), wait);
+
+ return count;
+
@@ -2247,7 +2279,7 @@
+
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
new file mode 100644
-index 0000000..19e1199
+index 0000000..dbb17ae
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
@@ -0,0 +1,97 @@
@@ -2349,19 +2381,18 @@
+
+#endif
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index 14e0e21..31871f7 100644
+index e797e9d..a79305f 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -4,6 +4,8 @@
+@@ -4,6 +4,7 @@
#ifndef __MTK_WED_REGS_H
#define __MTK_WED_REGS_H
+#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8)
-+
- #if defined(CONFIG_MEDIATEK_NETSYS_V2)
- #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(13, 0)
- #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(14)
-@@ -16,6 +18,7 @@
+ #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)
+@@ -11,6 +12,7 @@
#define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16)
#define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30)
#define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
@@ -2369,7 +2400,7 @@
struct mtk_wdma_desc {
__le32 buf0;
-@@ -42,6 +45,8 @@ struct mtk_wdma_desc {
+@@ -37,6 +39,8 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET_WED_TX_DMA BIT(12)
#define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
@@ -2378,7 +2409,7 @@
#define MTK_WED_RESET_WED BIT(31)
#define MTK_WED_CTRL 0x00c
-@@ -53,8 +58,12 @@ struct mtk_wdma_desc {
+@@ -48,8 +52,12 @@ struct mtk_wdma_desc {
#define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
#define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
#define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11)
@@ -2393,7 +2424,7 @@
#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)
-@@ -69,8 +78,8 @@ struct mtk_wdma_desc {
+@@ -64,8 +72,8 @@ struct mtk_wdma_desc {
#define MTK_WED_EXT_INT_STATUS_TX_TKID_LO_TH BIT(10)
#define MTK_WED_EXT_INT_STATUS_TX_TKID_HI_TH BIT(11)
#endif
@@ -2404,7 +2435,7 @@
#define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
#define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
#define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
-@@ -87,8 +96,8 @@ struct mtk_wdma_desc {
+@@ -82,8 +90,8 @@ struct mtk_wdma_desc {
#define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
@@ -2415,7 +2446,7 @@
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 | \
-@@ -96,6 +105,8 @@ struct mtk_wdma_desc {
+@@ -91,6 +99,8 @@ struct mtk_wdma_desc {
MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR)
#define MTK_WED_EXT_INT_MASK 0x028
@@ -2424,7 +2455,7 @@
#define MTK_WED_STATUS 0x060
#define MTK_WED_STATUS_TX GENMASK(15, 8)
-@@ -183,6 +194,9 @@ struct mtk_wdma_desc {
+@@ -172,6 +182,9 @@ struct mtk_wdma_desc {
#define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10)
@@ -2434,7 +2465,7 @@
#define MTK_WED_WPDMA_INT_TRIGGER 0x504
#define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
#define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
-@@ -239,13 +253,19 @@ struct mtk_wdma_desc {
+@@ -228,13 +241,19 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_INT_CTRL_TX 0x530
#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0)
@@ -2455,7 +2486,7 @@
#define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538
#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0)
-@@ -270,13 +290,40 @@ struct mtk_wdma_desc {
+@@ -259,13 +278,40 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4)
#define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4)
@@ -2496,7 +2527,7 @@
#define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2)
#define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3)
#define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4)
-@@ -320,6 +367,20 @@ struct mtk_wdma_desc {
+@@ -309,6 +355,20 @@ struct mtk_wdma_desc {
#define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4)
#define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4)
@@ -2517,7 +2548,7 @@
#define MTK_WED_RING_OFS_BASE 0x00
#define MTK_WED_RING_OFS_COUNT 0x04
#define MTK_WED_RING_OFS_CPU_IDX 0x08
-@@ -330,12 +391,13 @@ struct mtk_wdma_desc {
+@@ -319,12 +379,13 @@ struct mtk_wdma_desc {
#define MTK_WDMA_GLO_CFG 0x204
#define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0)
@@ -2532,7 +2563,7 @@
#define MTK_WDMA_RESET_IDX 0x208
#define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0)
#define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16)
-@@ -359,4 +421,70 @@ struct mtk_wdma_desc {
+@@ -348,4 +409,70 @@ struct mtk_wdma_desc {
/* DMA channel mapping */
#define HIFSYS_DMA_AG_MAP 0x008
@@ -3175,10 +3206,10 @@
+}
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
new file mode 100644
-index 0000000..548b38e
+index 0000000..b24fef3
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -0,0 +1,324 @@
+@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2021 Felix Fietkau <nbd@nbd.name> */
+
@@ -3499,23 +3530,31 @@
+ return val;
+}
+
++int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, int len);
+int mtk_wed_wo_init(struct mtk_wed_hw *hw);
+void mtk_wed_wo_exit(struct mtk_wed_hw *hw);
+#endif
+
diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index e914cb4..e8fca31 100644
+index 00036f9..658f392 100644
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -6,7 +6,39 @@
- #include <linux/regmap.h>
+@@ -7,26 +7,73 @@
#include <linux/pci.h>
-+#define WED_WO_STA_REC 0x6
-+
#define MTK_WED_TX_QUEUES 2
+#define MTK_WED_RX_QUEUES 2
-+
+
+-enum {
+- MTK_BUS_TYPE_PCIE,
+- MTK_BUS_TYPE_AXI,
+- MTK_BUS_TYPE_MAX
+-};
++#define WED_WO_STA_REC 0x6
+
+ struct mtk_wed_hw;
+ struct mtk_wdma_desc;
+
+enum mtk_wed_wo_cmd {
+ MTK_WED_WO_CMD_WED_CFG,
+ MTK_WED_WO_CMD_WED_RX_STAT,
@@ -3544,45 +3583,29 @@
+ MTK_WED_WO_CMD_CCIF_RING_DUMP,
+ MTK_WED_WO_CMD_WED_END
+};
-
- enum {
- MTK_NO_WED,
-@@ -15,10 +47,9 @@ enum {
- MTK_WED_VMAX
- };
-
--enum {
-- MTK_BUS_TYPE_PCIE,
-- MTK_BUS_TYPE_AXI,
-- MTK_BUS_TYPE_MAX
-+enum mtk_wed_bus_tye {
-+ MTK_WED_BUS_PCIE,
-+ MTK_WED_BUS_AXI,
- };
-
- struct mtk_wed_hw;
-@@ -33,6 +64,33 @@ struct mtk_wed_ring {
- void __iomem *wpdma;
- };
-
++
+struct mtk_rxbm_desc {
+ __le32 buf0;
+ __le32 token;
+} __packed __aligned(4);
+
-+struct dma_buf {
-+ int size;
-+ void **pages;
-+ struct mtk_wdma_desc *desc;
-+ dma_addr_t desc_phys;
-+};
-+
-+struct dma_entry {
-+ int size;
-+ struct mtk_rxbm_desc *desc;
-+ dma_addr_t desc_phys;
++enum mtk_wed_bus_tye{
++ MTK_WED_BUS_PCIE,
++ MTK_WED_BUS_AXI,
+};
+
++#define MTK_WED_RING_CONFIGURED BIT(0)
+ struct mtk_wed_ring {
+ struct mtk_wdma_desc *desc;
+ dma_addr_t desc_phys;
+ u32 desc_size;
+ int size;
++ u32 flags;
+
+ u32 reg_base;
+ void __iomem *wpdma;
+ };
+
+struct mtk_wed_wo_rx_stats {
+ __le16 wlan_idx;
+ __le16 tid;
@@ -3595,42 +3618,49 @@
struct mtk_wed_device {
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
const struct mtk_wed_ops *ops;
-@@ -47,37 +105,64 @@ struct mtk_wed_device {
+@@ -35,18 +82,37 @@ struct mtk_wed_device {
+ bool init_done, running;
+ int wdma_idx;
+ int irq;
++ u8 version;
++
++ /* used by wlan driver */
+ u32 rev_id;
+
struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
++ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
struct mtk_wed_ring txfree_ring;
struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
-+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
-+
-+ struct dma_buf buf_ring;
struct {
int size;
-- void **pages;
-- struct mtk_wdma_desc *desc;
-+ struct page_frag_cache rx_page;
-+ struct mtk_rxbm_desc *desc;
+ void **pages;
+ struct mtk_wdma_desc *desc;
dma_addr_t desc_phys;
- } buf_ring;
-+ } rx_buf_ring;
++ } tx_buf_ring;
++
++ struct {
++ int size;
++ struct page_frag_cache rx_page;
++ struct mtk_rxbm_desc *desc;
++ dma_addr_t desc_phys;
++ } rx_buf_ring;
+
+ struct {
-+ struct mtk_wed_ring rro_ring;
++ struct mtk_wed_ring ring;
+ void __iomem *rro_desc;
-+ dma_addr_t miod_desc_phys;
-+ dma_addr_t fdbk_desc_phys;
-+ u32 mcu_view_miod;
++ dma_addr_t miod_phys;
++ dma_addr_t fdbk_phys;
+ } rro;
/* filled by driver: */
struct {
-- struct pci_dev *pci_dev;
-+ union {
-+ struct platform_device *platform_dev;
-+ struct pci_dev *pci_dev;
-+ };
+@@ -56,24 +122,35 @@ struct mtk_wed_device {
+ };
+ enum mtk_wed_bus_tye bus_type;
void __iomem *base;
- u32 bus_type;
+ u32 phy_base;
u32 wpdma_phys;
@@ -3656,35 +3686,30 @@
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);
-+ u32 (*init_rx_buf)(struct mtk_wed_device *wed,
-+ int pkt_num);
++ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size);
+ void (*release_rx_buf)(struct mtk_wed_device *wed);
+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
+ struct mtk_wed_wo_rx_stats *stats);
} wlan;
#endif
};
-@@ -88,6 +173,10 @@ struct mtk_wed_ops {
+@@ -82,9 +159,15 @@ struct mtk_wed_ops {
+ int (*attach)(struct mtk_wed_device *dev);
+ int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs);
++ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
++ void __iomem *regs);
int (*txfree_ring_setup)(struct mtk_wed_device *dev,
void __iomem *regs);
-+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-+ void __iomem *regs);
+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
+ void *data, int len);
void (*detach)(struct mtk_wed_device *dev);
-
- void (*stop)(struct mtk_wed_device *dev);
-@@ -99,6 +188,8 @@ struct mtk_wed_ops {
-
- u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
- void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
+ u32 reason, u32 hash);
- };
- extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
-@@ -123,6 +214,16 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+ void (*stop)(struct mtk_wed_device *dev);
+ void (*start)(struct mtk_wed_device *dev, u32 irq_mask);
+@@ -119,6 +202,16 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
return ret;
}
@@ -3692,7 +3717,7 @@
+mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+{
+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+ return dev->ver != 1;
++ return dev->version != 1;
+#else
+ return false;
+#endif
@@ -3701,37 +3726,26 @@
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
#define mtk_wed_device_active(_dev) !!(_dev)->ops
#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
-@@ -131,6 +232,10 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
- #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
- (_dev)->ops->txfree_ring_setup(_dev, _regs)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
-+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
-+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
- #define mtk_wed_device_reg_read(_dev, _reg) \
- (_dev)->ops->reg_read(_dev, _reg)
- #define mtk_wed_device_reg_write(_dev, _reg, _val) \
-@@ -139,6 +244,8 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
+@@ -135,6 +228,12 @@ mtk_wed_device_attach(struct mtk_wed_device *dev)
(_dev)->ops->irq_get(_dev, _mask)
#define mtk_wed_device_irq_set_mask(_dev, _mask) \
(_dev)->ops->irq_set_mask(_dev, _mask)
++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
++ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
++#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
++ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
#else
static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
{
-@@ -148,10 +255,13 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- #define mtk_wed_device_start(_dev, _mask) do {} while (0)
- #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
- #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
- #define mtk_wed_device_reg_read(_dev, _reg) 0
+@@ -148,6 +247,9 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
#define mtk_wed_device_irq_get(_dev, _mask) 0
#define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
+#define mtk_wed_device_ppe_check(_dev, _hash) do {} while (0)
++#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
#endif
#endif
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3009-add-wed-ser-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3009-add-wed-ser-support.patch
index c53746f..28417c1 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3009-add-wed-ser-support.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3009-add-wed-ser-support.patch
@@ -1,21 +1,21 @@
-From de9cc10d4e2d5aad4801dc92fb37c42478a4ab68 Mon Sep 17 00:00:00 2001
+From d62ace95491fa4569c9ca9bca0b49b4995194a45 Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:05:45 +0800
-Subject: [PATCH 10/22] add-wed-ser-support
+Subject: [PATCH 09/24] add-wed-ser-support
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 +
- drivers/net/ethernet/mediatek/mtk_wed.c | 361 ++++++++++++++-----
- drivers/net/ethernet/mediatek/mtk_wed.h | 11 +
- drivers/net/ethernet/mediatek/mtk_wed_regs.h | 12 +
- include/linux/soc/mediatek/mtk_wed.h | 27 +-
- 5 files changed, 320 insertions(+), 99 deletions(-)
+ drivers/net/ethernet/mediatek/mtk_wed.c | 391 ++++++++++++++-----
+ drivers/net/ethernet/mediatek/mtk_wed.h | 10 +
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 9 +
+ include/linux/soc/mediatek/mtk_wed.h | 25 +-
+ 5 files changed, 342 insertions(+), 101 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 2cab49a..c1399c5 100644
+index 268c9e7..a24b223 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4158,6 +4158,9 @@ static void mtk_pending_work(struct work_struct *work)
+@@ -4619,6 +4619,9 @@ static void mtk_pending_work(struct work_struct *work)
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!eth->netdev[i])
continue;
@@ -25,7 +25,7 @@
if (mtk_reset_flag == MTK_FE_STOP_TRAFFIC) {
pr_info("send MTK_FE_STOP_TRAFFIC event\n");
call_netdevice_notifiers(MTK_FE_STOP_TRAFFIC,
-@@ -4183,6 +4186,7 @@ static void mtk_pending_work(struct work_struct *work)
+@@ -4644,6 +4647,7 @@ static void mtk_pending_work(struct work_struct *work)
pr_warn("wait for MTK_FE_START_RESET\n");
}
rtnl_lock();
@@ -33,7 +33,7 @@
break;
}
-@@ -4221,6 +4225,9 @@ static void mtk_pending_work(struct work_struct *work)
+@@ -4682,6 +4686,9 @@ static void mtk_pending_work(struct work_struct *work)
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!eth->netdev[i])
continue;
@@ -43,7 +43,7 @@
if (mtk_reset_flag == MTK_FE_STOP_TRAFFIC) {
pr_info("send MTK_FE_START_TRAFFIC event\n");
call_netdevice_notifiers(MTK_FE_START_TRAFFIC,
-@@ -4230,6 +4237,7 @@ static void mtk_pending_work(struct work_struct *work)
+@@ -4691,6 +4698,7 @@ static void mtk_pending_work(struct work_struct *work)
call_netdevice_notifiers(MTK_FE_RESET_DONE,
eth->netdev[i]);
}
@@ -52,7 +52,7 @@
eth->netdev[i]);
break;
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 4b2f1a2..ae31412 100644
+index ad9f3d5..5dd1182 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -13,8 +13,10 @@
@@ -66,60 +66,52 @@
#include "mtk_wed_regs.h"
#include "mtk_wed.h"
#include "mtk_ppe.h"
-@@ -71,23 +73,27 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)
- return wdma_r32(dev, MTK_WDMA_GLO_CFG);
- }
-
--static void
-+static int
- mtk_wdma_rx_reset(struct mtk_wed_device *dev)
- {
- u32 status;
- u32 mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
-- int i;
-+ int busy, i;
+@@ -80,10 +82,13 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
-- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-- !(status & mask), 0, 1000))
-- WARN_ON_ONCE(1);
-+ busy = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
-+ !(status & mask), 0, 10000);
-+
+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
+- !(status & mask), 0, 1000)
++ !(status & mask), 0, 10000);
+ if (ret)
+ dev_err(dev->hw->dev, "rx reset failed \n");
+
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
- for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
- if (!dev->rx_wdma[i].desc) {
- wdma_w32(dev, MTK_WDMA_RING_RX(i) +
- MTK_WED_RING_OFS_CPU_IDX, 0);
++
+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
+ if (!dev->rx_wdma[i].desc)
+ continue;
+@@ -91,6 +96,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+ wdma_w32(dev,
+ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
}
+
-+ return busy;
++ return ret;
}
static void
-@@ -99,14 +105,14 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev)
+@@ -101,16 +108,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev)
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
- !(status & mask), 0, 1000))
+ !(status & mask), 0, 10000))
- WARN_ON_ONCE(1);
+ dev_err(dev->hw->dev, "tx reset failed \n");
+- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
+- if (!dev->tx_wdma[i].desc)
+- continue;
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-- if (!dev->tx_wdma[i].desc) {
-- wdma_w32(dev, MTK_WDMA_RING_TX(i) +
-- MTK_WED_RING_OFS_CPU_IDX, 0);
+
++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+ wdma_w32(dev,
+ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
- }
-+ wdma_w32(dev, MTK_WDMA_RING_TX(i) +
-+ MTK_WED_RING_OFS_CPU_IDX, 0);
}
- static u32
-@@ -172,6 +178,51 @@ mtk_wed_wo_reset(struct mtk_wed_device *dev)
+ static void
+@@ -176,6 +182,59 @@ mtk_wed_wo_reset(struct mtk_wed_device *dev)
iounmap((void *)reg);
}
@@ -131,9 +123,13 @@
+
+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+ struct mtk_wed_hw *hw = hw_list[i];
-+ struct mtk_wed_device *dev = hw->wed_dev;
++ struct mtk_wed_device *dev;
+ int err;
+
++ if (!hw)
++ break;
++
++ dev = hw->wed_dev;
+ if (!dev || !dev->wlan.reset)
+ continue;
+
@@ -156,8 +152,12 @@
+
+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+ struct mtk_wed_hw *hw = hw_list[i];
-+ struct mtk_wed_device *dev = hw->wed_dev;
++ struct mtk_wed_device *dev;
++
++ if (!hw)
++ break;
+
++ dev = hw->wed_dev;
+ if (!dev || !dev->wlan.reset_complete)
+ continue;
+
@@ -171,123 +171,134 @@
static struct mtk_wed_hw *
mtk_wed_assign(struct mtk_wed_device *dev)
{
-@@ -505,8 +556,8 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
- wifi_w32(dev, dev->wlan.wpdma_rx_glo -
- dev->wlan.phy_base, val);
- } else {
+@@ -473,8 +532,8 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
+ }
+
+ if (i == 3) {
- dev_err(dev->hw->dev, "mtk_wed%d: rx dma enable failed!\n",
- dev->hw->index);
+ dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable failed!\n",
+ dev->hw->index, idx);
+ return;
}
- }
-
-@@ -557,7 +608,7 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
- 0x2));
-- for (idx = 0; idx < MTK_WED_RX_QUEUES; idx++)
-+ for (idx = 0; idx < dev->hw->ring_num; idx++)
- mtk_wed_check_wfdma_rx_fill(dev, idx);
- }
- }
-@@ -594,36 +645,45 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
- wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
- }
-+
-+ mtk_wed_set_512_support(dev, false);
- }
-
+@@ -522,16 +581,8 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
static void
mtk_wed_stop(struct mtk_wed_device *dev)
{
- mtk_wed_dma_disable(dev);
-- mtk_wed_set_512_support(dev, false);
-
- if (dev->ver > MTK_WED_V1) {
- wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
- wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
- }
mtk_wed_set_ext_int(dev, false);
-+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
-+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
-+ 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);
-+}
-+
-+static void
+- wed_clr(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_WPDMA_INT_TRIGGER, 0);
+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
+ wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
+@@ -543,39 +594,49 @@ mtk_wed_stop(struct mtk_wed_device *dev)
+
+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
+- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+-
+ }
+
+ static void
+-mtk_wed_detach(struct mtk_wed_device *dev)
+mtk_wed_deinit(struct mtk_wed_device *dev)
-+{
+ {
+- struct device_node *wlan_node;
+- struct mtk_wed_hw *hw = dev->hw;
+ mtk_wed_stop(dev);
+ mtk_wed_dma_disable(dev);
-+
- wed_clr(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);
-- if (dev->ver > MTK_WED_V1) {
-- wed_clr(dev, MTK_WED_CTRL,
-- MTK_WED_CTRL_WED_RX_BM_EN);
-- }
-+ if (dev->hw->ver == 1)
+- mutex_lock(&hw_lock);
++ wed_clr(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);
+
+- mtk_wed_stop(dev);
++ if (dev->hw->version == 1)
+ return;
-- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
-- wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
-- 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);
+- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
+- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
+ MTK_WED_CTRL_WED_RX_BM_EN |
+ MTK_WED_CTRL_RX_RRO_QM_EN);
- }
-
- static void
-@@ -634,16 +694,13 @@ mtk_wed_detach(struct mtk_wed_device *dev)
++}
- mutex_lock(&hw_lock);
+- mtk_wed_reset(dev, MTK_WED_RESET_WED);
++static void
++__mtk_wed_detach(struct mtk_wed_device *dev)
++{
++ struct device_node *wlan_node;
++ struct mtk_wed_hw *hw = dev->hw;
-- mtk_wed_stop(dev);
+- if (mtk_wed_get_rx_capa(dev)) {
+- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
+- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
+- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+- }
+ mtk_wed_deinit(dev);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+ mtk_wdma_rx_reset(dev);
-
- mtk_wed_reset(dev, MTK_WED_RESET_WED);
-
-- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
-- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-+ mtk_wdma_tx_reset(dev);
-
- mtk_wed_free_buffer(dev);
++ mtk_wed_reset(dev, MTK_WED_RESET_WED);
+ mtk_wed_free_tx_buffer(dev);
mtk_wed_free_tx_rings(dev);
-@@ -653,8 +710,6 @@ mtk_wed_detach(struct mtk_wed_device *dev)
- mtk_wed_wo_exit(hw);
+
+ if (mtk_wed_get_rx_capa(dev)) {
+- mtk_wed_wo_reset(dev);
++ if(hw->wed_wo)
++ mtk_wed_wo_reset(dev);
+ mtk_wed_free_rx_rings(dev);
+- mtk_wed_wo_exit(hw);
+- mtk_wdma_rx_reset(dev);
++ if(hw->wed_wo)
++ mtk_wed_wo_exit(hw);
++ mtk_wdma_tx_reset(dev);
}
-- mtk_wdma_rx_reset(dev);
--
if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
- wlan_node = dev->wlan.pci_dev->dev.of_node;
- if (of_dma_is_coherent(wlan_node))
-@@ -748,7 +803,7 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
+@@ -593,6 +654,13 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+ module_put(THIS_MODULE);
+
+ hw->wed_dev = NULL;
++}
++
++static void
++mtk_wed_detach(struct mtk_wed_device *dev)
++{
++ mutex_lock(&hw_lock);
++ __mtk_wed_detach(dev);
+ mutex_unlock(&hw_lock);
+ }
+
+@@ -665,7 +733,7 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
{
u32 mask, set;
- mtk_wed_stop(dev);
+ mtk_wed_deinit(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
+ mtk_wed_set_wpdma(dev);
+
+@@ -715,7 +783,6 @@ mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
+
+ ring->desc_size = sizeof(*ring->desc);
+ ring->size = size;
+- memset(ring->desc, 0, size);
- if (dev->ver > MTK_WED_V1)
-@@ -961,44 +1016,127 @@ mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale, bool tx)
+ return 0;
+ }
+@@ -938,44 +1005,140 @@ mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx)
}
static u32
@@ -314,7 +325,7 @@
-
- if (wed_r32(dev, MTK_WED_CTRL) &
- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY))
-+ if (wed_r32(dev, reg) & mask)
++ if (wed_r32(dev, reg) & mask)
return true;
return false;
@@ -332,23 +343,26 @@
return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
- timeout, false, dev);
+ timeout, false, dev, reg, mask);
- }
-
-+static void
++}
++
++static int
+mtk_wed_rx_reset(struct mtk_wed_device *dev)
+{
+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
-+ u8 state = WO_STATE_SER_RESET;
-+ bool busy = false;
-+ int i;
++ u8 val = WO_STATE_SER_RESET;
++ int i, ret;
+
-+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
-+ &state, sizeof(state), true);
++ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
++ MTK_WED_WO_CMD_CHANGE_STATE, &val,
++ sizeof(val), true);
++
++ if (ret)
++ return ret;
+
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
-+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
-+ if (busy) {
++ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
++ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
++ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
+ } else {
@@ -368,9 +382,9 @@
+
+ /* reset rro qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_RRO_QM_BUSY);
-+ if (busy) {
++ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
++ MTK_WED_CTRL_RX_RRO_QM_BUSY);
++ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM);
+ } else {
+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
@@ -381,9 +395,9 @@
+
+ /* reset route qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
-+ if (busy) {
++ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
++ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
++ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
+ } else {
+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
@@ -400,66 +414,73 @@
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
+
+ /* reset wed rx dma */
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
-+ MTK_WED_GLO_CFG_RX_DMA_BUSY);
++ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
++ MTK_WED_GLO_CFG_RX_DMA_BUSY);
+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN);
-+ if (busy) {
++ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
+ } else {
-+ wed_set(dev, MTK_WED_RESET_IDX,
-+ MTK_WED_RESET_IDX_RX);
++ struct mtk_eth *eth = dev->hw->eth;
++
++ if(MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++ wed_set(dev, MTK_WED_RESET_IDX,
++ MTK_WED_RESET_IDX_RX_V2);
++ else
++ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+ /* reset rx bm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_RX_BM_BUSY);
++ MTK_WED_CTRL_WED_RX_BM_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
+
+ /* wo change to enable state */
-+ state = WO_STATE_ENABLE;
-+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
-+ &state, sizeof(state), true);
++ val = WO_STATE_ENABLE;
++ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
++ MTK_WED_WO_CMD_CHANGE_STATE, &val,
++ sizeof(val), true);
++
++ if (ret)
++ return ret;
+
+ /* wed_rx_ring_reset */
+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) {
-+ struct mtk_wdma_desc *desc = dev->rx_ring[i].desc;
-+
-+ if (!desc)
++ if (!dev->rx_ring[i].desc)
+ continue;
+
-+ mtk_wed_ring_reset(desc, MTK_WED_RX_RING_SIZE, 1, false);
++ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE,
++ false);
+ }
+
-+ mtk_wed_free_rx_bm(dev);
-+}
++ mtk_wed_free_rx_buffer(dev);
+
++ return 0;
+ }
+
+
static void
mtk_wed_reset_dma(struct mtk_wed_device *dev)
{
-@@ -1012,25 +1150,28 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
- if (!desc)
- continue;
-
-- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE, dev->ver, true);
-+ mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE, 1, true);
+@@ -991,22 +1154,25 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ true);
}
- if (mtk_wed_poll_busy(dev))
- busy = mtk_wed_check_busy(dev);
+ /* 1.Reset WED Tx DMA */
+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN);
-+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_BUSY);
++ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
++ MTK_WED_GLO_CFG_TX_DMA_BUSY);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
} else {
- wed_w32(dev, MTK_WED_RESET_IDX,
+- wed_w32(dev, MTK_WED_RESET_IDX,
- MTK_WED_RESET_IDX_TX |
- MTK_WED_RESET_IDX_RX);
-+ MTK_WED_RESET_IDX_TX);
++ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
wed_w32(dev, MTK_WED_RESET_IDX, 0);
}
@@ -470,138 +491,153 @@
- mtk_wdma_rx_reset(dev);
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
-+ busy = !!(busy ||
-+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
-+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY));
++ if (!busy)
++ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
++ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
-@@ -1047,15 +1188,30 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+@@ -1023,6 +1189,9 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
}
+ /* 3. Reset WED WPDMA Tx Driver Engine */
-+ wed_clr(dev, MTK_WED_CTRL,
-+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
for (i = 0; i < 100; i++) {
val = wed_r32(dev, MTK_WED_TX_BM_INTF);
if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
- break;
+@@ -1030,8 +1199,21 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
}
--
+
mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
-+
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN);
mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
+ /* 4. Reset WED WPDMA Tx Driver Engine */
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
++
+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
+
-+ busy = !!(busy ||
-+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
-+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY));
++ if(!busy)
++ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY);
++
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
-@@ -1065,6 +1221,16 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
- MTK_WED_WPDMA_RESET_IDX_TX |
- MTK_WED_WPDMA_RESET_IDX_RX);
+@@ -1043,6 +1225,16 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
-+ if (dev->ver > MTK_WED_V1) {
-+ wed_w32(dev, MTK_WED_RESET_IDX,
-+ MTK_WED_RESET_WPDMA_IDX_RX);
-+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
-+ }
-+ }
-+
-+ if (dev->ver > MTK_WED_V1) {
-+ dev->init_done = false;
-+ mtk_wed_rx_reset(dev);
}
++ dev->init_done = false;
++ if (dev->hw->version == 1)
++ return;
++
++ if (!busy) {
++ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX);
++ wed_w32(dev, MTK_WED_RESET_IDX, 0);
++ }
++
++ mtk_wed_rx_reset(dev);
}
-@@ -1101,13 +1267,15 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
+
+ static int
+@@ -1062,7 +1254,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring,
}
static int
-mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev,
-+ int idx, int size, bool reset)
++mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
++ bool reset)
{
- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
+ struct mtk_wed_ring *wdma;
+@@ -1071,8 +1264,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+ return -EINVAL;
-- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- dev->ver, true))
-- return -ENOMEM;
-+ if(!reset)
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ dev->ver, true))
-+ return -ENOMEM;
+ wdma = &dev->rx_wdma[idx];
+- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
+- true))
++ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
++ desc_size, true))
+ return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
-@@ -1124,13 +1292,15 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+@@ -1090,7 +1283,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
}
static int
-mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
-+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev,
-+ int idx, int size, bool reset)
++mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
++ bool reset)
{
- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
+ struct mtk_wed_ring *wdma;
+@@ -1099,8 +1293,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+ return -EINVAL;
+ wdma = &dev->tx_wdma[idx];
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-- dev->ver, true))
-- return -ENOMEM;
-+ if (!reset)
-+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
-+ dev->ver, true))
-+ return -ENOMEM;
+- desc_size, true))
++ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
++ desc_size, true))
+ return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
- wdma->desc_phys);
-@@ -1140,7 +1310,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
- MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
+@@ -1112,6 +1306,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
wdma_w32(dev,
MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
--
+
+ if (reset)
-+ mtk_wed_ring_reset(wdma->desc, MTK_WED_WDMA_RING_SIZE,
-+ dev->ver, true);
- if (idx == 0) {
- wed_w32(dev, MTK_WED_WDMA_RING_TX
- + MTK_WED_RING_OFS_BASE, wdma->desc_phys);
-@@ -1253,9 +1425,12 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
++ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true);
++
+ if (!idx) {
+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
+ wdma->desc_phys);
+@@ -1267,9 +1464,12 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
{
- int i, ret;
+ int i;
-+ if (dev->ver > MTK_WED_V1)
-+ ret = mtk_wed_rx_bm_alloc(dev);
++ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev))
++ return;
+
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
- if (!dev->tx_wdma[i].desc)
+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
+ if (!dev->rx_wdma[i].desc)
- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
+
mtk_wed_hw_init(dev);
+@@ -1278,10 +1478,9 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ mtk_wed_set_ext_int(dev, true);
+
+ if (dev->hw->version == 1) {
+- u32 val;
+-
+- val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN |
+- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index);
++ u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN |
++ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID,
++ dev->hw->index);
-@@ -1347,10 +1522,6 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- goto error;
+ val |= BIT(0) | (BIT(1) * !!dev->hw->index);
+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
+@@ -1353,10 +1552,6 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ goto out;
- if (dev->ver > MTK_WED_V1) {
-- ret = mtk_wed_rx_bm_alloc(dev);
+ if (mtk_wed_get_rx_capa(dev)) {
+- ret = mtk_wed_rx_buffer_alloc(dev);
- if (ret)
-- goto error;
+- goto out;
-
ret = mtk_wed_rro_alloc(dev);
if (ret)
- goto error;
-@@ -1358,6 +1529,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ goto out;
+@@ -1364,6 +1559,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
mtk_wed_hw_init_early(dev);
@@ -609,10 +645,23 @@
+ init_completion(&dev->wlan_reset_done);
+ atomic_set(&dev->fe_reset, 0);
+
- if (dev->ver == MTK_WED_V1)
+ if (hw->version == 1) {
regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
BIT(hw->index), 0);
-@@ -1374,7 +1549,8 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+@@ -1373,8 +1572,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ }
+
+ out:
+- if (ret)
+- mtk_wed_detach(dev);
++ if (ret) {
++ dev_err(dev->hw->dev, "failed to attach wed device\n");
++ __mtk_wed_detach(dev);
++ }
+ unlock:
+ mutex_unlock(&hw_lock);
+
+@@ -1382,7 +1583,8 @@ mtk_wed_attach(struct mtk_wed_device *dev)
}
static int
@@ -622,65 +671,52 @@
{
struct mtk_wed_ring *ring = &dev->tx_ring[idx];
-@@ -1392,10 +1568,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+@@ -1401,11 +1603,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
+ return -EINVAL;
- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring));
-
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, 1, true))
-- return -ENOMEM;
-+ if (!reset)
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
-+ 1, true))
-+ return -ENOMEM;
+- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
+- sizeof(*ring->desc), true))
++ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
++ sizeof(*ring->desc), true))
+ return -ENOMEM;
- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, reset))
++ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
++ reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_TX(idx);
-@@ -1443,21 +1621,24 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
+@@ -1450,18 +1653,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
}
static int
-mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
-+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev,
-+ int idx, void __iomem *regs, bool reset)
++mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
++ bool reset)
{
struct mtk_wed_ring *ring = &dev->rx_ring[idx];
- BUG_ON(idx > ARRAY_SIZE(dev->rx_ring));
+ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
+ return -EINVAL;
-+ if (!reset)
-+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
-+ 1, false))
-+ return -ENOMEM;
+- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
+- sizeof(*ring->desc), false))
++ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
++ sizeof(*ring->desc), false))
+ return -ENOMEM;
-- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, 1, false))
-- return -ENOMEM;
--
- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
-+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, reset))
++ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
++ reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_RX_DATA(idx);
- ring->wpdma = regs;
-+ dev->hw->ring_num = idx + 1;
-
- /* WPDMA -> WED */
- wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
-index 8ef5253..490873c 100644
+index 1bfd96f..2ce1a5b 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
-@@ -47,6 +47,7 @@ struct mtk_wed_hw {
- u32 num_flows;
- u32 wdma_phy;
- char dirname[5];
-+ int ring_num;
- int irq;
- int index;
- u32 ver;
-@@ -158,6 +159,9 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+@@ -160,6 +160,9 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
void mtk_wed_exit(void);
int mtk_wed_flow_add(int index);
void mtk_wed_flow_remove(int index);
@@ -690,7 +726,7 @@
#else
static inline void
mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-@@ -175,6 +179,13 @@ static inline int mtk_wed_flow_add(int index)
+@@ -178,6 +181,13 @@ static inline int mtk_wed_flow_add(int index)
static inline void mtk_wed_flow_remove(int index)
{
}
@@ -705,10 +741,10 @@
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-index 31871f7..403a36b 100644
+index a79305f..645b8b1 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
-@@ -38,11 +38,15 @@ struct mtk_wdma_desc {
+@@ -32,11 +32,15 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
@@ -724,20 +760,16 @@
#define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
#define MTK_WED_RESET_RX_RRO_QM BIT(20)
-@@ -185,7 +189,12 @@ struct mtk_wdma_desc {
-
+@@ -174,6 +178,8 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET_IDX 0x20c
#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
-+#if defined(CONFIG_MEDIATEK_NETSYS_V2)
-+#define MTK_WED_RESET_IDX_RX GENMASK(7, 6)
-+#else
#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
-+#endif
++#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
#define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4)
-@@ -299,6 +308,9 @@ struct mtk_wdma_desc {
+@@ -287,6 +293,9 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
@@ -748,10 +780,10 @@
#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)
diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index e8fca31..98ed390 100644
+index 658f392..6772ea8 100644
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -163,18 +163,23 @@ struct mtk_wed_device {
+@@ -151,16 +151,21 @@ struct mtk_wed_device {
void (*release_rx_buf)(struct mtk_wed_device *wed);
void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
struct mtk_wed_wo_rx_stats *stats);
@@ -769,60 +801,60 @@
int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
+ void __iomem *regs, bool reset);
- int (*txfree_ring_setup)(struct mtk_wed_device *dev,
- void __iomem *regs);
int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
-- void __iomem *regs);
+- void __iomem *regs);
+ void __iomem *regs, bool reset);
+ int (*txfree_ring_setup)(struct mtk_wed_device *dev,
+ void __iomem *regs);
int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
- void *data, int len);
- void (*detach)(struct mtk_wed_device *dev);
-@@ -228,12 +233,13 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+@@ -216,8 +221,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
#define mtk_wed_device_active(_dev) !!(_dev)->ops
#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
#define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \
- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \
-+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
++ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
#define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
(_dev)->ops->txfree_ring_setup(_dev, _regs)
--#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
-- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
-+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
- #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
- (_dev)->ops->msg_update(_dev, _id, _msg, _len)
#define mtk_wed_device_reg_read(_dev, _reg) \
-@@ -244,6 +250,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+@@ -228,12 +233,14 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
(_dev)->ops->irq_get(_dev, _mask)
#define mtk_wed_device_irq_set_mask(_dev, _mask) \
(_dev)->ops->irq_set_mask(_dev, _mask)
-+#define mtk_wed_device_dma_reset(_dev) \
-+ (_dev)->ops->reset_dma(_dev)
+-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
+- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
++ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, reset)
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
(_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
+ #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
++#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
++#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
#else
-@@ -253,14 +261,15 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ {
+@@ -241,15 +248,17 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
}
#define mtk_wed_device_detach(_dev) do {} while (0)
#define mtk_wed_device_start(_dev, _mask) do {} while (0)
-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
-+#define mtk_wed_device_stop(_dev) do {} while (0)
+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
--#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
--#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
-+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_reg_read(_dev, _reg) 0
#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
#define mtk_wed_device_irq_get(_dev, _mask) 0
#define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
-+#define mtk_wed_device_dma_reset(_dev) do {} while (0)
+-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
++#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_ppe_check(_dev, _hash) do {} while (0)
+ #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
++#define mtk_wed_device_stop(_dev) do {} while (0)
++#define mtk_wed_device_dma_reset(_dev) do {} while (0)
#endif
+ #endif
--
2.18.0
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch
index b547328..18c6d2a 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3010-ethernet-update-ppe-backward-compatible-two-way-hash.patch
@@ -1,7 +1,7 @@
-From 84fd451dd7379943e6957e9ceb749be4d6c41540 Mon Sep 17 00:00:00 2001
+From 7feee53fdfd481fc2beb02739ccd0e87f1c96b7a Mon Sep 17 00:00:00 2001
From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:07:14 +0800
-Subject: [PATCH 11/22] ethernet-update-ppe-backward-compatible-two-way-hash
+Subject: [PATCH 10/24] ethernet-update-ppe-backward-compatible-two-way-hash
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 ++++++++-
@@ -11,10 +11,10 @@
4 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index c1399c5..bd622d3 100644
+index a24b223..e8837b6 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5252,7 +5252,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5799,7 +5799,8 @@ static int mtk_probe(struct platform_device *pdev)
for (i = 0; i < eth->ppe_num; i++) {
eth->ppe[i] = mtk_ppe_init(eth,
@@ -24,7 +24,7 @@
if (!eth->ppe[i]) {
err = -ENOMEM;
goto err_free_dev;
-@@ -5359,6 +5360,7 @@ static const struct mtk_soc_data mt2701_data = {
+@@ -5913,6 +5914,7 @@ static const struct mtk_soc_data mt2701_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
@@ -32,7 +32,7 @@
.offload_version = 2,
.rss_num = 0,
.txrx = {
-@@ -5377,6 +5379,7 @@ static const struct mtk_soc_data mt7621_data = {
+@@ -5931,6 +5933,7 @@ static const struct mtk_soc_data mt7621_data = {
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -40,7 +40,7 @@
.offload_version = 2,
.rss_num = 0,
.txrx = {
-@@ -5396,6 +5399,7 @@ static const struct mtk_soc_data mt7622_data = {
+@@ -5950,6 +5953,7 @@ static const struct mtk_soc_data mt7622_data = {
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -48,7 +48,7 @@
.offload_version = 2,
.rss_num = 0,
.txrx = {
-@@ -5414,6 +5418,7 @@ static const struct mtk_soc_data mt7623_data = {
+@@ -5968,6 +5972,7 @@ static const struct mtk_soc_data mt7623_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
@@ -56,7 +56,7 @@
.offload_version = 2,
.rss_num = 0,
.txrx = {
-@@ -5451,6 +5456,7 @@ static const struct mtk_soc_data mt7986_data = {
+@@ -6005,6 +6010,7 @@ static const struct mtk_soc_data mt7986_data = {
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -64,7 +64,7 @@
.offload_version = 2,
.rss_num = 4,
.txrx = {
-@@ -5470,6 +5476,8 @@ static const struct mtk_soc_data mt7981_data = {
+@@ -6024,6 +6030,8 @@ static const struct mtk_soc_data mt7981_data = {
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -74,10 +74,10 @@
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 960b979..68b8ab1 100644
+index 9099dea..b4f04e2 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1679,6 +1679,7 @@ struct mtk_soc_data {
+@@ -1732,6 +1732,7 @@ struct mtk_soc_data {
u64 caps;
u64 required_clks;
bool required_pctl;
@@ -86,7 +86,7 @@
netdev_features_t hw_features;
bool has_sram;
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 96c15b3..4da7e7a 100755
+index c9ee505..569bf34 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -88,7 +88,7 @@ static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable)
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch
index c516fd6..6a2a6f6 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3011-flow-offload-add-mtkhnat-flow-accounting.patch
@@ -1,7 +1,7 @@
-From 77bdae190ded4dfafa80dfaf04a77018e33e233c Mon Sep 17 00:00:00 2001
+From 4eaba588e0c730d6188f5f1b667a55d1b9ca0fe6 Mon Sep 17 00:00:00 2001
From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:09:23 +0800
-Subject: [PATCH 12/22] flow-offload-add-mtkhnat-flow-accounting
+Subject: [PATCH 11/24] flow-offload-add-mtkhnat-flow-accounting
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +-
@@ -15,10 +15,10 @@
8 files changed, 191 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index bd622d3..9d8ce07 100644
+index e8837b6..9cd306d 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5253,7 +5253,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5800,7 +5800,8 @@ static int mtk_probe(struct platform_device *pdev)
for (i = 0; i < eth->ppe_num; i++) {
eth->ppe[i] = mtk_ppe_init(eth,
eth->base + MTK_ETH_PPE_BASE + i * 0x400,
@@ -28,7 +28,7 @@
if (!eth->ppe[i]) {
err = -ENOMEM;
goto err_free_dev;
-@@ -5360,6 +5361,7 @@ static const struct mtk_soc_data mt2701_data = {
+@@ -5914,6 +5915,7 @@ static const struct mtk_soc_data mt2701_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
@@ -36,7 +36,7 @@
.hash_way = 2,
.offload_version = 2,
.rss_num = 0,
-@@ -5379,6 +5381,7 @@ static const struct mtk_soc_data mt7621_data = {
+@@ -5933,6 +5935,7 @@ static const struct mtk_soc_data mt7621_data = {
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -44,7 +44,7 @@
.hash_way = 2,
.offload_version = 2,
.rss_num = 0,
-@@ -5399,6 +5402,7 @@ static const struct mtk_soc_data mt7622_data = {
+@@ -5953,6 +5956,7 @@ static const struct mtk_soc_data mt7622_data = {
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -52,7 +52,7 @@
.hash_way = 2,
.offload_version = 2,
.rss_num = 0,
-@@ -5418,6 +5422,7 @@ static const struct mtk_soc_data mt7623_data = {
+@@ -5972,6 +5976,7 @@ static const struct mtk_soc_data mt7623_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
@@ -60,7 +60,7 @@
.hash_way = 2,
.offload_version = 2,
.rss_num = 0,
-@@ -5438,6 +5443,7 @@ static const struct mtk_soc_data mt7629_data = {
+@@ -5992,6 +5997,7 @@ static const struct mtk_soc_data mt7629_data = {
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -68,7 +68,7 @@
.rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
-@@ -5456,6 +5462,7 @@ static const struct mtk_soc_data mt7986_data = {
+@@ -6010,6 +6016,7 @@ static const struct mtk_soc_data mt7986_data = {
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -76,7 +76,7 @@
.hash_way = 4,
.offload_version = 2,
.rss_num = 4,
-@@ -5476,6 +5483,7 @@ static const struct mtk_soc_data mt7981_data = {
+@@ -6030,6 +6037,7 @@ static const struct mtk_soc_data mt7981_data = {
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -84,7 +84,7 @@
.hash_way = 4,
.offload_version = 2,
.rss_num = 4,
-@@ -5513,6 +5521,7 @@ static const struct mtk_soc_data rt5350_data = {
+@@ -6067,6 +6075,7 @@ static const struct mtk_soc_data rt5350_data = {
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
@@ -93,10 +93,10 @@
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 68b8ab1..101c233 100644
+index b4f04e2..5f90765 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1683,6 +1683,7 @@ struct mtk_soc_data {
+@@ -1736,6 +1736,7 @@ struct mtk_soc_data {
u8 offload_version;
netdev_features_t hw_features;
bool has_sram;
@@ -105,7 +105,7 @@
u32 txd_size;
u32 rxd_size;
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 4da7e7a..f55a95c 100755
+index 569bf34..94e03b2 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -74,6 +74,46 @@ static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
@@ -446,10 +446,10 @@
#define MTK_PPE_MIB_CACHE_CTL_EN BIT(0)
#define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2)
diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
-index 2cab008..1defb15 100644
+index e4c7db9..aae37f5 100644
--- a/net/netfilter/xt_FLOWOFFLOAD.c
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -766,7 +766,7 @@ static int __init xt_flowoffload_tg_init(void)
+@@ -772,7 +772,7 @@ static int __init xt_flowoffload_tg_init(void)
if (ret)
goto cleanup;
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch
index d51f24f..4110b83 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3012-flow-offload-add-mtkhnat-qdma-qos.patch
@@ -1,19 +1,19 @@
-From 9e21d6fa97e93cb2ba9b923810666ddaf7a981ee Mon Sep 17 00:00:00 2001
+From 0247c9d63f56bbe34f4205f986957b5036a9a4d8 Mon Sep 17 00:00:00 2001
From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:11:03 +0800
-Subject: [PATCH 13/22] flow-offload-add-mtkhnat-qdma-qos
+Subject: [PATCH 12/24] flow-offload-add-mtkhnat-qdma-qos
---
drivers/net/ethernet/mediatek/Makefile | 2 +-
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 ++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 50 ++
drivers/net/ethernet/mediatek/mtk_ppe.c | 48 +-
drivers/net/ethernet/mediatek/mtk_ppe.h | 4 +
.../net/ethernet/mediatek/mtk_ppe_offload.c | 28 +-
.../net/ethernet/mediatek/mtk_qdma_debugfs.c | 439 ++++++++++++++++++
include/net/flow_offload.h | 1 +
net/netfilter/nf_flow_table_offload.c | 4 +-
- 9 files changed, 593 insertions(+), 6 deletions(-)
+ 9 files changed, 581 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c
diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
@@ -30,10 +30,10 @@
ifdef CONFIG_DEBUG_FS
mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 9d8ce07..0f6613b 100644
+index 9cd306d..1660fd9 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -5266,6 +5266,8 @@ static int mtk_probe(struct platform_device *pdev)
+@@ -5813,6 +5813,8 @@ static int mtk_probe(struct platform_device *pdev)
}
mtk_ppe_debugfs_init(eth);
@@ -42,7 +42,7 @@
}
for (i = 0; i < MTK_MAX_DEVS; i++) {
-@@ -5371,6 +5373,7 @@ static const struct mtk_soc_data mt2701_data = {
+@@ -5925,6 +5927,7 @@ static const struct mtk_soc_data mt2701_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -50,7 +50,7 @@
},
};
-@@ -5391,6 +5394,7 @@ static const struct mtk_soc_data mt7621_data = {
+@@ -5945,6 +5948,7 @@ static const struct mtk_soc_data mt7621_data = {
.rxd_size = sizeof(struct mtk_rx_dma),
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -58,7 +58,7 @@
},
};
-@@ -5412,6 +5416,7 @@ static const struct mtk_soc_data mt7622_data = {
+@@ -5966,6 +5970,7 @@ static const struct mtk_soc_data mt7622_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -66,7 +66,7 @@
},
};
-@@ -5432,6 +5437,7 @@ static const struct mtk_soc_data mt7623_data = {
+@@ -5986,6 +5991,7 @@ static const struct mtk_soc_data mt7623_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -74,7 +74,7 @@
},
};
-@@ -5472,6 +5478,7 @@ static const struct mtk_soc_data mt7986_data = {
+@@ -6026,6 +6032,7 @@ static const struct mtk_soc_data mt7986_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
@@ -82,7 +82,7 @@
},
};
-@@ -5493,6 +5500,7 @@ static const struct mtk_soc_data mt7981_data = {
+@@ -6047,6 +6054,7 @@ static const struct mtk_soc_data mt7981_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
@@ -90,7 +90,7 @@
},
};
-@@ -5511,6 +5519,7 @@ static const struct mtk_soc_data mt7988_data = {
+@@ -6065,6 +6073,7 @@ static const struct mtk_soc_data mt7988_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT_V2,
@@ -98,7 +98,7 @@
},
};
-@@ -5529,6 +5538,7 @@ static const struct mtk_soc_data rt5350_data = {
+@@ -6083,6 +6092,7 @@ static const struct mtk_soc_data rt5350_data = {
.rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = MTK_TX_DMA_BUF_SHIFT,
@@ -107,10 +107,10 @@
};
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 101c233..7ea380e 100644
+index 5f90765..02ca0b2 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -458,6 +471,9 @@
+@@ -487,6 +487,9 @@
#define FC_THRES_DROP_EN (7 << 16)
#define FC_THRES_MIN 0x4444
@@ -120,7 +120,7 @@
/* QDMA Interrupt Status Register */
#define MTK_QDMA_INT_STATUS (QDMA_BASE + 0x218)
#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
-@@ -494,6 +510,11 @@
+@@ -530,6 +533,11 @@
/* QDMA Interrupt Mask Register */
#define MTK_QDMA_HRED2 (QDMA_BASE + 0x244)
@@ -132,7 +132,7 @@
/* QDMA TX Forward CPU Pointer Register */
#define MTK_QTX_CTX_PTR (QDMA_BASE +0x300)
-@@ -521,6 +542,14 @@
+@@ -557,6 +565,14 @@
/* QDMA FQ Free Page Buffer Length Register */
#define MTK_QDMA_FQ_BLEN (QDMA_BASE +0x32c)
@@ -147,7 +147,7 @@
/* WDMA Registers */
#define MTK_WDMA_CTX_PTR(x) (WDMA_BASE(x) + 0x8)
#define MTK_WDMA_DTX_PTR(x) (WDMA_BASE(x) + 0xC)
-@@ -1690,6 +1719,7 @@ struct mtk_soc_data {
+@@ -1743,6 +1759,7 @@ struct mtk_soc_data {
u32 rx_dma_l4_valid;
u32 dma_max_len;
u32 dma_len_offset;
@@ -155,7 +155,7 @@
} txrx;
};
-@@ -1879,6 +1909,7 @@ struct mtk_eth {
+@@ -1936,6 +1953,7 @@ struct mtk_eth {
spinlock_t syscfg0_lock;
struct timer_list mtk_dma_monitor_timer;
@@ -163,7 +163,7 @@
u8 ppe_num;
struct mtk_ppe *ppe[MTK_MAX_PPE_NUM];
struct rhashtable flow_table;
-@@ -1936,6 +1967,36 @@ extern const struct of_device_id of_mtk_match[];
+@@ -1994,6 +2012,36 @@ extern const struct of_device_id of_mtk_match[];
extern u32 mtk_hwlro_stats_ebl;
extern u32 dbg_show_level;
@@ -200,7 +200,7 @@
/* read the hardware status register */
void mtk_stats_update_mac(struct mtk_mac *mac);
-@@ -1969,4 +2028,6 @@ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+@@ -2027,4 +2075,6 @@ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
u32 mtk_rss_indr_table(struct mtk_rss_params *rss_params, int index);
int mtk_ppe_debugfs_init(struct mtk_eth *eth);
@@ -208,7 +208,7 @@
+int mtk_qdma_debugfs_init(struct mtk_eth *eth);
#endif /* MTK_ETH_H */
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index f55a95c..6d6c1e4 100755
+index 94e03b2..8388f65 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -128,7 +128,7 @@ static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable)
@@ -366,7 +366,7 @@
return err;
diff --git a/drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c b/drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c
new file mode 100644
-index 0000000..3a7c585
+index 0000000..d76b3c5
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_qdma_debugfs.c
@@ -0,0 +1,439 @@
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3013-flow-offload-ovs-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3013-flow-offload-ovs-support.patch
index a164d1a..5220a63 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3013-flow-offload-ovs-support.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3013-flow-offload-ovs-support.patch
@@ -1,7 +1,7 @@
-From 842a435bd21807447504a387e5ebb8071b0db93f Mon Sep 17 00:00:00 2001
+From f3112e335a7f95aeb3d834962de813baadc1f620 Mon Sep 17 00:00:00 2001
From: Evelyn Tsai <evelyn.tsai@mediatek.com>
Date: Mon, 18 Sep 2023 11:11:41 +0800
-Subject: [PATCH 14/22] flow-offload-ovs-support
+Subject: [PATCH 13/24] flow-offload-ovs-support
---
net/openvswitch/vport-internal_dev.c | 46 ++++++++++++++++++++++++++++
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-update-net-bridge-for-bridger.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-update-net-bridge-for-bridger.patch
index 89e664f..a23233f 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-update-net-bridge-for-bridger.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3014-update-net-bridge-for-bridger.patch
@@ -1,7 +1,7 @@
-From 120baca4e8b019d03c8d1a29012cea911629247a Mon Sep 17 00:00:00 2001
+From 552ae5e27e936eb74dd563485ab77f40b96a61a5 Mon Sep 17 00:00:00 2001
From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:13:51 +0800
-Subject: [PATCH 15/22] update-net-bridge-for-bridger
+Subject: [PATCH 14/24] update-net-bridge-for-bridger
---
include/net/switchdev.h | 2 +
@@ -1805,10 +1805,10 @@
+ return false;
+}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
-index da1ef00..b896f71 100644
+index 4eed989..de75eb2 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
-@@ -1998,6 +1998,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+@@ -2004,6 +2004,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
goto cont;
if (idx < s_idx)
goto cont;
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch
index bedf09e..c44e494 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3015-ethernet-update-ppe-from-netsys2-to-netsys3.patch
@@ -1,7 +1,7 @@
-From 5481f7ecbd3cfffd8234bc8e952a6e07f42de76c Mon Sep 17 00:00:00 2001
+From a326344938c515068241eb66580f57255258d9c6 Mon Sep 17 00:00:00 2001
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
Date: Tue, 21 Nov 2023 16:42:01 +0800
-Subject: [PATCH 16/22] ethernet-update-ppe-from-netsys2-to-netsys3
+Subject: [PATCH 15/24] ethernet-update-ppe-from-netsys2-to-netsys3
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 ++++---
@@ -13,10 +13,10 @@
6 files changed, 85 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 850bc4f..8910d40 100644
+index 1660fd9..a3ed175 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2248,17 +2248,17 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2447,17 +2447,17 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, netdev);
@@ -37,8 +37,8 @@
+#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON_V2, trxd.rxd5);
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
- for (i = 0; i < eth->ppe_num; i++) {
-@@ -5290,7 +5290,8 @@ static int mtk_probe(struct platform_device *pdev)
+ mtk_ppe_check_skb(eth->ppe[0], skb,
+@@ -5799,7 +5799,8 @@ static int mtk_probe(struct platform_device *pdev)
for (i = 0; i < eth->ppe_num; i++) {
eth->ppe[i] = mtk_ppe_init(eth,
@@ -48,7 +48,7 @@
2, eth->soc->hash_way, i,
eth->soc->has_accounting);
if (!eth->ppe[i]) {
-@@ -5557,6 +5558,9 @@ static const struct mtk_soc_data mt7988_data = {
+@@ -6066,6 +6067,9 @@ static const struct mtk_soc_data mt7988_data = {
.required_clks = MT7988_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
@@ -59,10 +59,10 @@
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 9c77f14..c7d36c5 100644
+index 02ca0b2..f9dda59 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -134,9 +134,10 @@
+@@ -137,9 +137,10 @@
#define MTK_GDMA_UCS_EN BIT(20)
#define MTK_GDMA_STRP_CRC BIT(16)
#define MTK_GDMA_TO_PDMA 0x0
@@ -74,7 +74,7 @@
#else
#define MTK_GDMA_TO_PPE0 0x4444
#endif
-@@ -1978,14 +1979,14 @@ extern u32 dbg_show_level;
+@@ -2014,14 +2015,14 @@ extern u32 dbg_show_level;
static inline void mtk_set_ib1_sp(struct mtk_eth *eth, struct mtk_foe_entry *foe, u32 val)
{
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3016-mediatek-ethernet-add-wifi2wifi-offload-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3016-mediatek-ethernet-add-wifi2wifi-offload-support.patch
index 121db94..14639c4 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3016-mediatek-ethernet-add-wifi2wifi-offload-support.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3016-mediatek-ethernet-add-wifi2wifi-offload-support.patch
@@ -1,21 +1,21 @@
-From d3183ad9ed0a8a35047a37f30d85f920a729897c Mon Sep 17 00:00:00 2001
+From 743b10e8e2a17c904f27cf78d46aea64193fc41c Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:16:18 +0800
-Subject: [PATCH 17/22] mediatek-ethernet-add-wifi2wifi-offload-support
+Subject: [PATCH 16/24] mediatek-ethernet-add-wifi2wifi-offload-support
---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
.../net/ethernet/mediatek/mtk_ppe_offload.c | 35 +++++++++++++------
drivers/net/ethernet/mediatek/mtk_wed.c | 13 +++++++
- include/linux/soc/mediatek/mtk_wed.h | 6 +++-
- 4 files changed, 45 insertions(+), 11 deletions(-)
+ include/linux/soc/mediatek/mtk_wed.h | 5 +++
+ 4 files changed, 45 insertions(+), 10 deletions(-)
mode change 100755 => 100644 drivers/net/ethernet/mediatek/mtk_ppe_offload.c
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 23c5f49..ee89b4c 100644
+index f9dda59..88d2f46 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -2027,6 +2027,8 @@ void mtk_usxgmii_link_poll(struct work_struct *work);
+@@ -2072,6 +2072,8 @@ void mtk_usxgmii_link_poll(struct work_struct *work);
int mtk_eth_offload_init(struct mtk_eth *eth, int id);
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data);
@@ -100,15 +100,15 @@
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index ae31412..3e760f7 100644
+index 5dd1182..68eedd3 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1733,6 +1733,18 @@ void mtk_wed_flow_remove(int index)
+@@ -1766,6 +1766,18 @@ void mtk_wed_flow_remove(int index)
mutex_unlock(&hw_lock);
}
+static int mtk_wed_eth_setup_tc(struct mtk_wed_device *wed, struct net_device *dev,
-+ int type, void *type_data)
++ int type, void *type_data)
+{
+ switch (type) {
+ case TC_SETUP_BLOCK:
@@ -120,9 +120,9 @@
+}
+
void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
- void __iomem *wdma, u32 wdma_phy, int index)
-
-@@ -1751,6 +1763,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ void __iomem *wdma, phys_addr_t wdma_phy,
+ int index)
+@@ -1785,6 +1797,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
.irq_get = mtk_wed_irq_get,
.irq_set_mask = mtk_wed_irq_set_mask,
.detach = mtk_wed_detach,
@@ -131,36 +131,35 @@
};
struct device_node *eth_np = eth->dev->of_node;
diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
-index 98ed390..27cf284 100644
+index 6772ea8..470beb2 100644
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
-@@ -183,7 +183,8 @@ struct mtk_wed_ops {
- int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
- void *data, int len);
+@@ -173,6 +173,8 @@ struct mtk_wed_ops {
void (*detach)(struct mtk_wed_device *dev);
--
+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
+ u32 reason, u32 hash);
+ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
-+ int type, void *type_data);
++ int type, void *type_data);
+
void (*stop)(struct mtk_wed_device *dev);
void (*start)(struct mtk_wed_device *dev, u32 irq_mask);
- void (*reset_dma)(struct mtk_wed_device *dev);
-@@ -232,6 +233,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- #define mtk_wed_device_active(_dev) !!(_dev)->ops
- #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
+@@ -241,6 +243,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
+ #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
+ #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
+#define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) \
+ (_dev)->ops->setup_tc(_dev, _ndev, _type, _data)
- #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
- #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
- #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \
-@@ -270,6 +273,7 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
- #define mtk_wed_device_irq_get(_dev, _mask) 0
- #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
+ #else
+ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ {
+@@ -259,6 +263,7 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
+ #define mtk_wed_device_stop(_dev) do {} while (0)
#define mtk_wed_device_dma_reset(_dev) do {} while (0)
+#define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) do {} while (0)
- #define mtk_wed_device_ppe_check(_dev, _hash) do {} while (0)
#endif
+ #endif
--
2.18.0
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3017-flow-offload-add-mtkhnat-dscp.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3017-flow-offload-add-mtkhnat-dscp.patch
index 478a7a9..070bb7c 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3017-flow-offload-add-mtkhnat-dscp.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3017-flow-offload-add-mtkhnat-dscp.patch
@@ -1,7 +1,7 @@
-From 3e4d44d8da90b9ba20abc5cec255d92b67e3fb00 Mon Sep 17 00:00:00 2001
+From 8c918e858df4b7cb12ea185acf23e83bae883cd2 Mon Sep 17 00:00:00 2001
From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
Date: Mon, 18 Sep 2023 11:17:24 +0800
-Subject: [PATCH 18/22] flow-offload-add-mtkhnat-dscp
+Subject: [PATCH 17/24] flow-offload-add-mtkhnat-dscp
---
drivers/net/ethernet/mediatek/mtk_ppe.c | 11 +++++++
@@ -13,10 +13,10 @@
6 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 446acca..384e811 100755
+index 184e29d..0e9c0bd 100755
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -435,6 +435,17 @@ int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid)
+@@ -446,6 +446,17 @@ int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid)
return 0;
}
@@ -84,10 +84,10 @@
err = mtk_flow_set_output_device(eth, &foe, odev, f->flow->ct, data.eth.h_dest,
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
-index feac793..97a277d 100644
+index 7374cb2..d5dd3fe 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
-@@ -36,6 +36,7 @@ struct nf_flow_key {
+@@ -38,6 +38,7 @@ struct nf_flow_key {
};
struct flow_dissector_key_tcp tcp;
struct flow_dissector_key_ports tp;
@@ -95,7 +95,7 @@
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
struct nf_flow_match {
-@@ -145,6 +146,7 @@ struct flow_offload_tuple {
+@@ -147,6 +148,7 @@ struct flow_offload_tuple {
u8 h_dest[ETH_ALEN];
} out;
};
@@ -132,7 +132,7 @@
}
diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
-index 1defb15..d4aecab 100644
+index aae37f5..5364a32 100644
--- a/net/netfilter/xt_FLOWOFFLOAD.c
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
@@ -49,6 +49,35 @@ static DEFINE_SPINLOCK(hooks_lock);
@@ -171,7 +171,7 @@
static unsigned int
xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state)
-@@ -617,6 +646,9 @@ flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
+@@ -623,6 +652,9 @@ flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
if (flow_offload_route_init(flow, &route) < 0)
goto err_flow_add;
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3018-flow-offload-add-mtkhnat-netlink.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3018-flow-offload-add-mtkhnat-netlink.patch
index 3bb7e7a..ff6f58f 100644
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3018-flow-offload-add-mtkhnat-netlink.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3018-flow-offload-add-mtkhnat-netlink.patch
@@ -1,7 +1,7 @@
-From 6bda18f107acbf04f01c18ad5964be6f7404d3cf Mon Sep 17 00:00:00 2001
+From 122cb2a2ae7ececd20412083b5bb9bfd6f9c8d26 Mon Sep 17 00:00:00 2001
From: Bc-bocun Chen <bc-bocun.chen@mediatek.com>
Date: Mon, 18 Sep 2023 13:14:08 +0800
-Subject: [PATCH 19/22] flow-offload-add-mtkhnat-netlink
+Subject: [PATCH 18/24] flow-offload-add-mtkhnat-netlink
---
include/net/netfilter/nf_flow_table.h | 1 +
@@ -14,10 +14,10 @@
create mode 100644 net/netfilter/nf_flow_table_netlink.c
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
-index 97a277d..3490d90 100644
+index d5dd3fe..f2bce73 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
-@@ -277,6 +277,7 @@ int nf_flow_table_init(struct nf_flowtable *flow_table);
+@@ -279,6 +279,7 @@ int nf_flow_table_init(struct nf_flowtable *flow_table);
void nf_flow_table_free(struct nf_flowtable *flow_table);
void flow_offload_teardown(struct flow_offload *flow);
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3019-mtk-wed-add-wed3-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3019-mtk-wed-add-wed3-support.patch
new file mode 100644
index 0000000..c3aac60
--- /dev/null
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3019-mtk-wed-add-wed3-support.patch
@@ -0,0 +1,3817 @@
+From 3519673178423e9b7271782fd1a66f42cce88d19 Mon Sep 17 00:00:00 2001
+From: Sujuan Chen <sujuan.chen@mediatek.com>
+Date: Mon, 18 Sep 2023 13:21:15 +0800
+Subject: [PATCH 19/24] mtk:wed:add wed3 support
+
+---
+ arch/arm64/boot/dts/mediatek/mt7988.dtsi | 152 ++-
+ .../dts/mediatek/mt7988a-dsa-10g-spim-nor.dts | 16 +-
+ .../dts/mediatek/mt7988d-dsa-10g-spim-nor.dts | 16 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.c | 17 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +-
+ .../net/ethernet/mediatek/mtk_ppe_offload.c | 9 +-
+ drivers/net/ethernet/mediatek/mtk_wed.c | 1192 +++++++++++++----
+ drivers/net/ethernet/mediatek/mtk_wed.h | 73 +-
+ .../net/ethernet/mediatek/mtk_wed_debugfs.c | 584 +++++++-
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 40 +-
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 7 +-
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 353 ++++-
+ include/linux/netdevice.h | 7 +
+ include/linux/soc/mediatek/mtk_wed.h | 77 +-
+ 14 files changed, 2146 insertions(+), 399 deletions(-)
+ mode change 100755 => 100644 drivers/net/ethernet/mediatek/mtk_ppe.c
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+index 7e96640..3368240 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7988.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+@@ -193,44 +193,49 @@
+ status = "disabled";
+ };
+
+- wed: wed@15010000 {
+- compatible = "mediatek,wed";
+- wed_num = <3>;
+- /* add this property for wed get the pci slot number. */
+- pci_slot_map = <0>, <1>, <2>;
+- reg = <0 0x15010000 0 0x2000>,
+- <0 0x15012000 0 0x2000>,
+- <0 0x15014000 0 0x2000>;
++ wed0: wed@15010000 {
++ compatible = "mediatek,mt7988-wed",
++ "syscon";
++ reg = <0 0x15010000 0 0x2000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+- };
+-
+- wed2: wed2@15012000 {
+- compatible = "mediatek,wed2";
+- wed_num = <3>;
+- /* add this property for wed get the pci slot number. */
+- reg = <0 0x15010000 0 0x2000>,
+- <0 0x15012000 0 0x2000>,
+- <0 0x15014000 0 0x2000>;
++ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
++ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif0>;
++ mediatek,wocpu_ilm = <&wocpu0_ilm>;
++ mediatek,wocpu_dlm = <&wocpu0_dlm>;
++ mediatek,wocpu_boot = <&cpu0_boot>;
++ mediatek,wocpu_emi = <&wocpu0_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
++ };
++
++ wed1: wed@15012000 {
++ compatible = "mediatek,mt7988-wed",
++ "syscon";
++ reg = <0 0x15012000 0 0x2000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+- };
+-
+- wed3: wed3@15014000 {
+- compatible = "mediatek,wed3";
+- wed_num = <3>;
+- /* add this property for wed get the pci slot number. */
+- reg = <0 0x15010000 0 0x2000>,
+- <0 0x15012000 0 0x2000>,
+- <0 0x15014000 0 0x2000>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
++ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif1>;
++ mediatek,wocpu_ilm = <&wocpu1_ilm>;
++ mediatek,wocpu_dlm = <&wocpu1_dlm>;
++ mediatek,wocpu_boot = <&cpu1_boot>;
++ mediatek,wocpu_emi = <&wocpu1_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
++ };
++
++ wed2: wed@15014000 {
++ compatible = "mediatek,mt7988-wed",
++ "syscon";
++ reg = <0 0x15014000 0 0x2000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
++ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif2>;
++ mediatek,wocpu_ilm = <&wocpu2_ilm>;
++ mediatek,wocpu_dlm = <&wocpu2_dlm>;
++ mediatek,wocpu_boot = <&cpu2_boot>;
++ mediatek,wocpu_emi = <&wocpu2_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
+ };
+
+ wdma: wdma@15104800 {
+@@ -240,15 +245,25 @@
+ <0 0x15105000 0 0x400>;
+ };
+
+- ap2woccif: ap2woccif@151A5000 {
+- compatible = "mediatek,ap2woccif";
+- reg = <0 0x151A5000 0 0x1000>,
+- <0 0x152A5000 0 0x1000>,
+- <0 0x153A5000 0 0x1000>;
++ ap2woccif0: ap2woccif@151A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x151A5000 0 0x1000>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
++ };
++
++ ap2woccif1: ap2woccif@152A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x152A5000 0 0x1000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
++ };
++
++ ap2woccif2: ap2woccif@153A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x153A5000 0 0x1000>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ wocpu0_ilm: wocpu0_ilm@151E0000 {
+@@ -256,31 +271,53 @@
+ reg = <0 0x151E0000 0 0x8000>;
+ };
+
+- wocpu1_ilm: wocpu1_ilm@152E0000 {
+- compatible = "mediatek,wocpu1_ilm";
++ wocpu1_ilm: wocpu_ilm@152E0000 {
++ compatible = "mediatek,wocpu_ilm";
+ reg = <0 0x152E0000 0 0x8000>;
+ };
+
+- wocpu2_ilm: wocpu2_ilm@153E0000 {
+- compatible = "mediatek,wocpu2_ilm";
+- reg = <0 0x153E0000 0 0x8000>;
++ wocpu2_ilm: wocpu_ilm@153E0000 {
++ compatible = "mediatek,wocpu_ilm";
++ reg = <0 0x153E0000 0 0x8000>;
++ };
++
++ wocpu0_dlm: wocpu_dlm@151E8000 {
++ compatible = "mediatek,wocpu_dlm";
++ reg = <0 0x151E8000 0 0x2000>;
++
++ resets = <ðsysrst 0>;
++ reset-names = "wocpu_rst";
++ };
++
++ wocpu1_dlm: wocpu_dlm@0x152E8000 {
++ compatible = "mediatek,wocpu_dlm";
++ reg = <0 0x152E8000 0 0x2000>;
++
++ resets = <ðsysrst 0>;
++ reset-names = "wocpu_rst";
+ };
+
+- wocpu_dlm: wocpu_dlm@151E8000 {
++ wocpu2_dlm: wocpu_dlm@0x153E8000 {
+ compatible = "mediatek,wocpu_dlm";
+- reg = <0 0x151E8000 0 0x2000>,
+- <0 0x152E8000 0 0x2000>,
+- <0 0x153E8000 0 0x2000>;
++ reg = <0 0x153E8000 0 0x2000>;
+
+ resets = <ðsysrst 0>;
+ reset-names = "wocpu_rst";
+ };
+
+- cpu_boot: wocpu_boot@15194000 {
+- compatible = "mediatek,wocpu_boot";
+- reg = <0 0x15194000 0 0x1000>,
+- <0 0x15294000 0 0x1000>,
+- <0 0x15394000 0 0x1000>;
++ cpu0_boot: wocpu_boot@15194000 {
++ compatible = "mediatek,wocpu0_boot";
++ reg = <0 0x15194000 0 0x1000>;
++ };
++
++ cpu1_boot: wocpu_boot@15294000 {
++ compatible = "mediatek,wocpu1_boot";
++ reg = <0 0x15294000 0 0x1000>;
++ };
++
++ cpu2_boot: wocpu_boot@15394000 {
++ compatible = "mediatek,wocpu2_boot";
++ reg = <0 0x15394000 0 0x1000>;
+ };
+
+ reserved-memory {
+@@ -901,6 +938,7 @@
+ <&topckgen CK_TOP_CB_NET2_D2>;
+ mediatek,ethsys = <ðsys>;
+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
++ mediatek,wed = <&wed0>, <&wed1>, <&wed2>;
+ mediatek,usxgmiisys = <&usxgmiisys0>, <&usxgmiisys1>;
+ mediatek,xfi_pextp = <&xfi_pextp0>, <&xfi_pextp1>;
+ mediatek,xfi_pll = <&xfi_pll>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
+index a22af29..9169188 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
+@@ -372,9 +372,23 @@
+ status = "okay";
+ };
+
+-&wed {
++&wed0 {
+ dy_txbm_enable = "true";
+ dy_txbm_budge = <8>;
+ txbm_init_sz = <10>;
+ status = "okay";
+ };
++
++&wed1 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
++
++&wed2 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
+\ No newline at end of file
+diff --git a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
+index effcfd8..30e4846 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
+@@ -382,9 +382,23 @@
+ status = "okay";
+ };
+
+-&wed {
++&wed0 {
+ dy_txbm_enable = "true";
+ dy_txbm_budge = <8>;
+ txbm_init_sz = <10>;
+ status = "okay";
+ };
++
++&wed1 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
++
++&wed2 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
+\ No newline at end of file
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+old mode 100755
+new mode 100644
+index 0e9c0bd..ae0acd5
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -9,6 +9,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/if_vlan.h>
+ #include <net/dsa.h>
++#include <net/route.h>
+ #include "mtk_eth_soc.h"
+ #include "mtk_ppe.h"
+ #include "mtk_ppe_regs.h"
+@@ -407,7 +408,7 @@ 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 bss, int wcid, bool amsdu_en)
+ {
+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
+ u32 *ib2 = mtk_foe_entry_ib2(entry);
+@@ -419,6 +420,9 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+
+ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
+ FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ l2->winfo_pao = FIELD_PREP(MTK_FOE_WINFO_PAO_AMSDU_EN, amsdu_en);
++#endif
+ #else
+ if (wdma_idx)
+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX;
+@@ -454,6 +458,17 @@ int mtk_foe_entry_set_dscp(struct mtk_foe_entry *entry, int dscp)
+ *ib2 &= ~MTK_FOE_IB2_DSCP;
+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_DSCP, dscp);
+
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
++
++ if (*ib2 & MTK_FOE_IB2_WDMA_WINFO &&
++ l2->winfo_pao & MTK_FOE_WINFO_PAO_AMSDU_EN) {
++ u8 tid = (dscp >> 5) & 0xf;
++
++ l2->winfo_pao |= FIELD_PREP(MTK_FOE_WINFO_PAO_TID, tid);
++ }
++#endif
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
+index 2a8b6ef..66c7f10 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -428,7 +428,7 @@ 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 bss, int wcid, bool amsdu_en);
+ int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid);
+ int mtk_foe_entry_set_dscp(struct mtk_foe_entry *entry, int dscp);
+ bool mtk_foe_entry_match(struct mtk_foe_entry *entry, struct mtk_foe_entry *data);
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+index 95174b7..2d432f2 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -112,6 +112,7 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
+ info->queue = path.mtk_wdma.queue;
+ info->bss = path.mtk_wdma.bss;
+ info->wcid = path.mtk_wdma.wcid;
++ info->amsdu = path.mtk_wdma.amsdu;
+
+ return 0;
+ }
+@@ -193,13 +194,15 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
+
+ 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);
++ info.wcid, info.amsdu);
+ pse_port = PSE_PPE0_PORT;
+ #if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+ if (info.wdma_idx == 0)
+ pse_port = PSE_WDMA0_PORT;
+ else if (info.wdma_idx == 1)
+ pse_port = PSE_WDMA1_PORT;
++ else if (info.wdma_idx == 2)
++ pse_port = PSE_WDMA2_PORT;
+ else
+ return -EOPNOTSUPP;
+ #endif
+@@ -481,8 +484,6 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
+ if (data.pppoe.num == 1)
+ mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
+
+- mtk_foe_entry_set_dscp(&foe, dscp);
+-
+ mtk_foe_entry_set_sp(eth->ppe[ppe_index], &foe);
+
+ err = mtk_flow_set_output_device(eth, &foe, odev, f->flow->ct, data.eth.h_dest,
+@@ -490,6 +491,8 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
+ if (err)
+ return err;
+
++ mtk_foe_entry_set_dscp(&foe, dscp);
++
+ if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
+ return err;
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 68eedd3..2fed493 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -23,9 +23,45 @@
+ #include "mtk_wed_mcu.h"
+ #include "mtk_wed_wo.h"
+
+-static struct mtk_wed_hw *hw_list[2];
++#define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4)
++#define MTK_WED_AMSDU_NPAGES 32
++
++static struct mtk_wed_hw *hw_list[3];
+ static DEFINE_MUTEX(hw_lock);
+
++static const struct mtk_wed_soc_data mt7622_data = {
++ .regmap = {
++ .tx_bm_tkid = 0x088,
++ .wpdma_rx_ring0 = 0x770,
++ .reset_idx_tx_mask = GENMASK(3, 0),
++ .reset_idx_rx_mask = GENMASK(17, 16),
++ },
++ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc),
++ .wdma_desc_size = sizeof(struct mtk_wdma_desc),
++};
++
++static const struct mtk_wed_soc_data mt7986_data = {
++ .regmap = {
++ .tx_bm_tkid = 0x0c8,
++ .wpdma_rx_ring0 = 0x770,
++ .reset_idx_tx_mask = GENMASK(1, 0),
++ .reset_idx_rx_mask = GENMASK(7, 6),
++ },
++ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc),
++ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
++};
++
++static const struct mtk_wed_soc_data mt7988_data = {
++ .regmap = {
++ .tx_bm_tkid = 0x0c8,
++ .wpdma_rx_ring0 = 0x7d0,
++ .reset_idx_tx_mask = GENMASK(1, 0),
++ .reset_idx_rx_mask = GENMASK(7, 6),
++ },
++ .tx_ring_desc_size = sizeof(struct mtk_wed_bm_desc),
++ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc),
++};
++
+ static void
+ wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
+ {
+@@ -74,6 +110,26 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)
+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
+ }
+
++static u32
++mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++{
++ if (wed_r32(dev, reg) & mask)
++ return true;
++
++ return false;
++}
++
++static int
++mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++{
++ int sleep = 1000;
++ int timeout = 100 * sleep;
++ u32 val;
++
++ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
++ timeout, false, dev, reg, mask);
++}
++
+ static int
+ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+ {
+@@ -249,7 +305,7 @@ mtk_wed_assign(struct mtk_wed_device *dev)
+ if (!hw->wed_dev)
+ goto out;
+
+- if (hw->version == 1)
++ if (mtk_wed_is_v1(hw))
+ return NULL;
+
+ /* MT7986 WED devices do not have any pcie slot restrictions */
+@@ -269,40 +325,153 @@ mtk_wed_assign(struct mtk_wed_device *dev)
+ }
+
+ static int
+-mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
++mtk_wed_amsdu_buffer_alloc(struct mtk_wed_device *dev)
+ {
+- struct mtk_wdma_desc *desc;
+- dma_addr_t desc_phys;
+- void **page_list;
+- int token = dev->wlan.token_start;
+- int ring_size, n_pages, page_idx;
++ struct mtk_wed_hw *hw = dev->hw;
++ struct mtk_wed_amsdu *wed_amsdu;
+ int i;
+
++ if (!mtk_wed_is_v3_or_greater(hw))
++ return 0;
+
+- if (dev->hw->version == 1)
+- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+- else
+- ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
+- MTK_WED_WDMA_RING_SIZE * 2;
++ wed_amsdu = devm_kcalloc(hw->dev, MTK_WED_AMSDU_NPAGES,
++ sizeof(*wed_amsdu), GFP_KERNEL);
++ if (!wed_amsdu)
++ return -ENOMEM;
++
++ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
++ void *ptr;
++
++ /* each segment is 64K */
++ ptr = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN |
++ __GFP_ZERO | __GFP_COMP |
++ GFP_DMA32,
++ get_order(MTK_WED_AMSDU_BUF_SIZE));
++ if (!ptr)
++ goto error;
++
++ wed_amsdu[i].txd = ptr;
++ wed_amsdu[i].txd_phy = dma_map_single(hw->dev, ptr,
++ MTK_WED_AMSDU_BUF_SIZE,
++ DMA_TO_DEVICE);
++ if (dma_mapping_error(hw->dev, wed_amsdu[i].txd_phy))
++ goto error;
++ }
++ dev->hw->wed_amsdu = wed_amsdu;
++
++ return 0;
++
++error:
++ for (i--; i >= 0; i--)
++ dma_unmap_single(hw->dev, wed_amsdu[i].txd_phy,
++ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
++ return -ENOMEM;
++}
++
++
++static void
++mtk_wed_amsdu_free_buffer(struct mtk_wed_device *dev)
++{
++ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
++ int i;
++
++ if (!wed_amsdu)
++ return;
++
++ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) {
++ dma_unmap_single(dev->hw->dev, wed_amsdu[i].txd_phy,
++ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE);
++ free_pages((unsigned long)wed_amsdu[i].txd,
++ get_order(MTK_WED_AMSDU_BUF_SIZE));
++ }
++}
++
++static int
++mtk_wed_amsdu_init(struct mtk_wed_device *dev)
++{
++ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu;
++ int i, ret;
++
++ if (!wed_amsdu)
++ return 0;
+
+- n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
++ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++)
++ wed_w32(dev, MTK_WED_AMSDU_HIFTXD_BASE_L(i),
++ wed_amsdu[i].txd_phy);
++
++ /* init all sta parameter */
++ wed_w32(dev, MTK_WED_AMSDU_STA_INFO_INIT, MTK_WED_AMSDU_STA_RMVL |
++ MTK_WED_AMSDU_STA_WTBL_HDRT_MODE |
++ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_LEN,
++ dev->wlan.amsdu_max_len >> 8) |
++ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_NUM,
++ dev->wlan.amsdu_max_subframes));
++
++ wed_w32(dev, MTK_WED_AMSDU_STA_INFO, MTK_WED_AMSDU_STA_INFO_DO_INIT);
++
++ ret = mtk_wed_poll_busy(dev, MTK_WED_AMSDU_STA_INFO,
++ MTK_WED_AMSDU_STA_INFO_DO_INIT);
++ if (ret) {
++ dev_err(dev->hw->dev, "amsdu initialization failed\n");
++ return ret;
++ }
++
++ /* init partial amsdu offload txd src */
++ wed_set(dev, MTK_WED_AMSDU_HIFTXD_CFG,
++ FIELD_PREP(MTK_WED_AMSDU_HIFTXD_SRC, dev->hw->index));
++
++ /* init qmem */
++ wed_set(dev, MTK_WED_AMSDU_PSE, MTK_WED_AMSDU_PSE_RESET);
++ ret = mtk_wed_poll_busy(dev, MTK_WED_MON_AMSDU_QMEM_STS1, BIT(29));
++ if (ret) {
++ pr_info("%s: amsdu qmem initialization failed\n", __func__);
++ return ret;
++ }
++
++ /* eagle E1 PCIE1 tx ring 22 flow control issue */
++ if (dev->wlan.id == 0x7991)
++ wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING);
++
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
++
++ return 0;
++}
++
++static int
++mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
++{
++ u32 desc_size = dev->hw->soc->tx_ring_desc_size;
++ int i, page_idx = 0, n_pages, ring_size;
++ int token = dev->wlan.token_start;
++ struct mtk_wed_buf *page_list;
++ dma_addr_t desc_phys;
++ void *desc_ptr;
++
++ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
++ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
++ dev->tx_buf_ring.size = ring_size;
++ } else {
++ dev->tx_buf_ring.size = MTK_WED_TX_BM_DMA_SIZE;
++ ring_size = MTK_WED_TX_BM_PKT_CNT;
++ }
++ n_pages = dev->tx_buf_ring.size / MTK_WED_BUF_PER_PAGE;
+
+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
+ if (!page_list)
+ return -ENOMEM;
+
+- dev->tx_buf_ring.size = ring_size;
+ dev->tx_buf_ring.pages = page_list;
+
+- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
+- &desc_phys, GFP_KERNEL);
+- if (!desc)
++ desc_ptr = dma_alloc_coherent(dev->hw->dev,
++ dev->tx_buf_ring.size * desc_size,
++ &desc_phys, GFP_KERNEL);
++ if (!desc_ptr)
+ return -ENOMEM;
+
+- dev->tx_buf_ring.desc = desc;
++ dev->tx_buf_ring.desc = desc_ptr;
+ dev->tx_buf_ring.desc_phys = desc_phys;
+
+- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
++ for (i = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
+ dma_addr_t page_phys, buf_phys;
+ struct page *page;
+ void *buf;
+@@ -319,7 +488,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+ return -ENOMEM;
+ }
+
+- page_list[page_idx++] = page;
++ page_list[page_idx].p = page;
++ page_list[page_idx++].phy_addr = page_phys;
+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+
+@@ -327,28 +497,31 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+ buf_phys = page_phys;
+
+ for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
+- u32 txd_size;
+- u32 ctrl;
+-
+- txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
++ struct mtk_wdma_desc *desc = desc_ptr;
+
+ desc->buf0 = cpu_to_le32(buf_phys);
+- desc->buf1 = cpu_to_le32(buf_phys + txd_size);
+-
+- 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++;
+-
++ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
++ u32 txd_size, ctrl;
++
++ txd_size = dev->wlan.init_buf(buf, buf_phys,
++ token++);
++ desc->buf1 = cpu_to_le32(buf_phys + txd_size);
++ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size);
++ if (mtk_wed_is_v1(dev->hw))
++ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG1 |
++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
++ MTK_WED_BUF_SIZE - txd_size);
++ else
++ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 |
++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2,
++ MTK_WED_BUF_SIZE - txd_size);
++ desc->ctrl = cpu_to_le32(ctrl);
++ desc->info = 0;
++ } else {
++ desc->ctrl = cpu_to_le32(token << 16);
++ }
++
++ desc_ptr += desc_size;
+ buf += MTK_WED_BUF_SIZE;
+ buf_phys += MTK_WED_BUF_SIZE;
+ }
+@@ -363,48 +536,107 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+ static void
+ mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
+ {
+- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc;
+- void **page_list = dev->tx_buf_ring.pages;
+- int ring_size, page_idx;
+- int i;
++ struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages;
++ struct mtk_wed_hw *hw = dev->hw;
++ int i, page_idx = 0;
+
+ if (!page_list)
+ return;
+
+- if (!desc)
++ if (!dev->tx_buf_ring.desc)
+ goto free_pagelist;
+
+- if (dev->hw->version == 1) {
+- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+- } else {
+- ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
+- MTK_WED_WDMA_RING_SIZE * 2;
+- }
+-
+- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
+- void *page = page_list[page_idx++];
+- dma_addr_t buf_addr;
++ for (i = 0; i < dev->tx_buf_ring.size; i += MTK_WED_BUF_PER_PAGE) {
++ dma_addr_t page_phy = page_list[page_idx].phy_addr;
++ void *page = page_list[page_idx++].p;
+
+ if (!page)
+ break;
+
+- buf_addr = le32_to_cpu(desc[i].buf0);
+- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
++ dma_unmap_page(dev->hw->dev, page_phy, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+ __free_page(page);
+ }
+
+- dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
+- desc, dev->tx_buf_ring.desc_phys);
++ dma_free_coherent(dev->hw->dev,
++ dev->tx_buf_ring.size * hw->soc->tx_ring_desc_size,
++ dev->tx_buf_ring.desc,
++ dev->tx_buf_ring.desc_phys);
+
+ free_pagelist:
+ kfree(page_list);
+ }
+
++static int
++mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev)
++{
++ int n_pages = MTK_WED_RX_PG_BM_CNT / MTK_WED_RX_PAGE_BUF_PER_PAGE;
++ struct mtk_wed_buf *page_list;
++ struct mtk_wed_bm_desc *desc;
++ dma_addr_t desc_phys;
++ int i, page_idx = 0;
++
++ if (!dev->wlan.hw_rro)
++ return 0;
++
++ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
++ if (!page_list)
++ return -ENOMEM;
++
++ dev->hw_rro.size = dev->wlan.rx_nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
++ dev->hw_rro.pages = page_list;
++
++ desc = dma_alloc_coherent(dev->hw->dev,
++ dev->wlan.rx_nbuf * sizeof(*desc),
++ &desc_phys, GFP_KERNEL);
++ if (!desc)
++ return -ENOMEM;
++
++ dev->hw_rro.desc = desc;
++ dev->hw_rro.desc_phys = desc_phys;
++
++ for (i = 0, page_idx = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_PAGE_BUF_PER_PAGE) {
++ dma_addr_t page_phys, buf_phys;
++ struct page *page;
++ void *buf;
++ int s;
++
++ page = __dev_alloc_pages(GFP_KERNEL, 0);
++ if (!page)
++ return -ENOMEM;
++
++ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dev->hw->dev, page_phys)) {
++ __free_page(page);
++ return -ENOMEM;
++ }
++
++ page_list[page_idx].p= page;
++ page_list[page_idx++].phy_addr= page_phys;
++ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++
++ buf = page_to_virt(page);
++ buf_phys = page_phys;
++ for (s = 0; s < MTK_WED_RX_PAGE_BUF_PER_PAGE; s++) {
++ desc->buf0 = cpu_to_le32(buf_phys);
++ desc++;
++ buf += MTK_WED_PAGE_BUF_SIZE;
++ buf_phys += MTK_WED_PAGE_BUF_SIZE;
++ }
++
++ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++ }
++
++ return 0;
++}
++
+ static int
+ mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
+ {
+- struct mtk_rxbm_desc *desc;
++ struct mtk_wed_bm_desc *desc;
+ dma_addr_t desc_phys;
+
+ dev->rx_buf_ring.size = dev->wlan.rx_nbuf;
+@@ -418,13 +650,48 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
+ dev->rx_buf_ring.desc_phys = desc_phys;
+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt);
+
+- return 0;
++ return mtk_wed_hwrro_buffer_alloc(dev);
++}
++
++static void
++mtk_wed_hwrro_free_buffer(struct mtk_wed_device *dev)
++{
++ struct mtk_wed_buf *page_list = dev->hw_rro.pages;
++ struct mtk_wed_bm_desc *desc = dev->hw_rro.desc;
++ int i, page_idx = 0;
++
++ if (!dev->wlan.hw_rro)
++ return;
++
++ if (!page_list)
++ return;
++
++ if (!desc)
++ goto free_pagelist;
++
++ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_PAGE_BUF_PER_PAGE) {
++ dma_addr_t buf_addr = page_list[page_idx].phy_addr;
++ void *page = page_list[page_idx++].p;
++
++ if (!page)
++ break;
++
++ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++ __free_page(page);
++ }
++
++ dma_free_coherent(dev->hw->dev, dev->hw_rro.size * sizeof(*desc),
++ desc, dev->hw_rro.desc_phys);
++
++free_pagelist:
++ kfree(page_list);
+ }
+
+ static void
+ mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
+ {
+- struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
++ struct mtk_wed_bm_desc *desc = dev->rx_buf_ring.desc;
+
+ if (!desc)
+ return;
+@@ -433,6 +700,28 @@ mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
+
+ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc),
+ desc, dev->rx_buf_ring.desc_phys);
++
++ mtk_wed_hwrro_free_buffer(dev);
++}
++
++static void
++mtk_wed_hwrro_init(struct mtk_wed_device *dev)
++{
++ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
++ return;
++
++ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM,
++ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128));
++
++ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE, dev->hw_rro.desc_phys);
++
++ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR,
++ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX |
++ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX,
++ MTK_WED_RX_PG_BM_CNT));
++
++ /* enable rx_page_bm to fetch dmad */
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
+ }
+
+ static void
+@@ -450,6 +739,8 @@ mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev)
+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff));
+
+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
++
++ mtk_wed_hwrro_init(dev);
+ }
+
+ static void
+@@ -465,6 +756,16 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring)
+ static void
+ mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
+ {
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++)
++ if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED))
++ mtk_wed_free_ring(dev, &dev->rx_ring[i]);
++
++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
++ if ((dev->tx_wdma[i].flags & MTK_WED_RING_CONFIGURED))
++ mtk_wed_free_ring(dev, &dev->tx_wdma[i]);
++
+ mtk_wed_free_rx_buffer(dev);
+ mtk_wed_free_ring(dev, &dev->rro.ring);
+ }
+@@ -475,9 +776,12 @@ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
+- mtk_wed_free_ring(dev, &dev->tx_ring[i]);
++ if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED))
++ mtk_wed_free_ring(dev, &dev->tx_ring[i]);
++
+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
+- mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
++ if ((dev->rx_wdma[i].flags & MTK_WED_RING_CONFIGURED))
++ mtk_wed_free_ring(dev, &dev->rx_wdma[i]);
+ }
+
+ static void
+@@ -485,8 +789,20 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
+ {
+ u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
+
+- if (dev->hw->version == 1)
++ switch (dev->hw->version) {
++ case 1:
+ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
++ break;
++ case 2:
++ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH2 |
++ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH2 |
++ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
++ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
++ break;
++ case 3:
++ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT;
++ break;
++ }
+
+ if (!dev->hw->num_flows)
+ mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
+@@ -498,6 +814,9 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
+ static void
+ mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
+ {
++ if (!mtk_wed_is_v2(dev->hw))
++ return;
++
+ if (enable) {
+ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
+ wed_w32(dev, MTK_WED_TXP_DW1,
+@@ -509,22 +828,15 @@ mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable)
+ }
+ }
+
+-#define MTK_WFMDA_RX_DMA_EN BIT(2)
+-static void
+-mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
++static int
++mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev,
++ struct mtk_wed_ring *ring)
+ {
+- u32 val;
+ int i;
+
+- if(!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED))
+- return;
+-
+ for (i = 0; i < 3; i++) {
+- u32 cur_idx;
++ u32 cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX);
+
+- cur_idx = wed_r32(dev,
+- MTK_WED_WPDMA_RING_RX_DATA(idx) +
+- MTK_WED_RING_OFS_CPU_IDX);
+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
+ break;
+
+@@ -532,14 +844,12 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
+ }
+
+ if (i == 3) {
+- dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable failed!\n",
+- dev->hw->index, idx);
+- return;
++ dev_err(dev->hw->dev, "mtk_wed%d: dma enable failed!\n",
++ dev->hw->index);
++ return -ETIMEDOUT;
+ }
+
+- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) |
+- MTK_WFMDA_RX_DMA_EN;
+- wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val);
++ return 0;
+ }
+
+ static void
+@@ -561,7 +871,7 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
+
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v1(dev->hw)) {
+ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
+ wdma_clr(dev, MTK_WDMA_GLO_CFG,
+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
+@@ -573,9 +883,17 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
+ MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
++
++ if (mtk_wed_is_v3_or_greater(dev->hw) &&
++ mtk_wed_get_rx_capa(dev)) {
++ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG,
++ MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG,
++ MTK_WDMA_PREF_RX_CFG_PREF_EN);
++ }
+ }
+
+- mtk_wed_set_512_support (dev, false);
++ mtk_wed_set_512_support(dev, false);
+ }
+
+ static void
+@@ -589,7 +907,7 @@ mtk_wed_stop(struct mtk_wed_device *dev)
+ wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
+
+- if (dev->hw->version == 1)
++ if (!mtk_wed_get_rx_capa(dev))
+ return;
+
+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
+@@ -608,13 +926,21 @@ mtk_wed_deinit(struct mtk_wed_device *dev)
+ MTK_WED_CTRL_WED_TX_BM_EN |
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+- if (dev->hw->version == 1)
++ if (mtk_wed_is_v1(dev->hw))
+ return;
+
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
+ MTK_WED_CTRL_WED_RX_BM_EN |
+ MTK_WED_CTRL_RX_RRO_QM_EN);
++
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
++ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_AMSDU);
++ wed_clr(dev, MTK_WED_PCIE_INT_CTRL,
++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
++ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER);
++ }
+ }
+
+ static void
+@@ -627,6 +953,8 @@ __mtk_wed_detach(struct mtk_wed_device *dev)
+
+ mtk_wdma_rx_reset(dev);
+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
++ mtk_wed_amsdu_free_buffer(dev);
++ mtk_wdma_tx_reset(dev);
+ mtk_wed_free_tx_buffer(dev);
+ mtk_wed_free_tx_rings(dev);
+
+@@ -636,7 +964,6 @@ __mtk_wed_detach(struct mtk_wed_device *dev)
+ mtk_wed_free_rx_rings(dev);
+ if(hw->wed_wo)
+ mtk_wed_wo_exit(hw);
+- mtk_wdma_tx_reset(dev);
+ }
+
+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
+@@ -664,21 +991,36 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+ mutex_unlock(&hw_lock);
+ }
+
+-#define PCIE_BASE_ADDR0 0x11280000
+ static void
+ mtk_wed_bus_init(struct mtk_wed_device *dev)
+ {
+ switch (dev->wlan.bus_type) {
+ case MTK_WED_BUS_PCIE: {
+ struct device_node *np = dev->hw->eth->dev->of_node;
+- struct regmap *regs;
+
+- regs = syscon_regmap_lookup_by_phandle(np,
+- "mediatek,wed-pcie");
+- if (IS_ERR(regs))
+- break;
++ if (mtk_wed_is_v2(dev->hw)) {
++ struct regmap *regs;
++ 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));
++ }
++
++ if (dev->wlan.msi) {
++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM,
++ dev->hw->pci_base | 0xc08);
++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
++ dev->hw->pci_base | 0xc04);
++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8));
++ } else {
++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM,
++ dev->hw->pci_base | 0x180);
++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE,
++ dev->hw->pci_base | 0x184);
++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
++ }
+
+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
+@@ -686,19 +1028,9 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
+ /* 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);
+-
+- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
+- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
+-
+- /* 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 */
+- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
++ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER |
++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL,
++ dev->hw->index));
+ break;
+ }
+ case MTK_WED_BUS_AXI:
+@@ -714,45 +1046,71 @@ mtk_wed_bus_init(struct mtk_wed_device *dev)
+ 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);
++ int i;
+
+- 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);
+- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
+- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
++ if (mtk_wed_is_v1(dev->hw)) {
++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
++ return;
+ }
++
++ 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);
++
++ if (!mtk_wed_get_rx_capa(dev))
++ return;
++
++ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
++ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx[0]);
++
++ if (dev->wlan.wpdma_rx[1])
++ wed_w32(dev, MTK_WED_WPDMA_RX_RING1, dev->wlan.wpdma_rx[1]);
++
++ if (!dev->wlan.hw_rro)
++ return;
++
++ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]);
++ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]);
++ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++)
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i),
++ dev->wlan.wpdma_rx_pg + i * 0x10);
+ }
+
+ static void
+ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
+ {
+- u32 mask, set;
++ u32 set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2);
++ u32 mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE;
+
+ mtk_wed_deinit(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 |
+- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
+- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
+- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
+- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
++ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
++ mask |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
++ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
++ set |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
++ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
++ }
+ wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
+
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v1(dev->hw)) {
+ u32 offset;
++
+ offset = dev->hw->index ? 0x04000400 : 0;
++
++ 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));
++ 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);
+@@ -844,7 +1202,8 @@ mtk_wed_rro_cfg(struct mtk_wed_device *dev)
+ },
+ };
+
+- return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, MTK_WED_WO_CMD_WED_CFG,
++ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
++ MTK_WED_WO_CMD_WED_CFG,
+ &req, sizeof(req), true);
+ }
+
+@@ -895,11 +1254,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
+ }
+
+ /* configure RX_ROUTE_QM */
+- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
+- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
+- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
+- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
+- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
++ if (mtk_wed_is_v2(dev->hw)) {
++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
++ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
++ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT,
++ 0x3 + dev->hw->index));
++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
++ } else {
++ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0,
++ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT,
++ 0x3 + dev->hw->index));
++ }
+
+ /* enable RX_ROUTE_QM */
+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+@@ -918,35 +1284,26 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+
+ wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
+
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v1(dev->hw)) {
+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
+ MTK_WED_TX_BM_CTRL_PAUSE |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
+ dev->tx_buf_ring.size / 128) |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
+ MTK_WED_TX_RING_SIZE / 256));
+- 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 {
++ } else if (mtk_wed_is_v2(dev->hw)) {
+ wed_w32(dev, MTK_WED_TX_BM_CTRL,
+ MTK_WED_TX_BM_CTRL_PAUSE |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM,
+ dev->tx_buf_ring.size / 128) |
+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM,
+ dev->tx_buf_ring.size / 128));
+- 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_TKID_DYN_THR,
++ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
++ MTK_WED_TX_TKID_DYN_THR_HI);
+ 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);
+@@ -956,32 +1313,73 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+ dev->tx_buf_ring.size / 128) |
+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
+ dev->tx_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);
+ }
+
++ wed_w32(dev, dev->hw->soc->regmap.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));
++
+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
+
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ /* switch to new bm architecture */
++ wed_clr(dev, MTK_WED_TX_BM_CTRL,
++ MTK_WED_TX_BM_CTRL_LEGACY_EN);
++
++ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
++ MTK_WED_TX_TKID_CTRL_PAUSE |
++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3,
++ dev->wlan.nbuf / 128) |
++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3,
++ dev->wlan.nbuf / 128));
++ /* return SKBID + SDP back to bm */
++ wed_set(dev, MTK_WED_TX_TKID_CTRL,
++ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
++
++ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR,
++ MTK_WED_TX_BM_PKT_CNT |
++ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
++ }
++
++ if (mtk_wed_is_v1(dev->hw)) {
+ 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);
+- /* rx hw init*/
++ } else if (mtk_wed_get_rx_capa(dev)) {
++ /* rx hw init */
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
+
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
+
++ /* reset prefetch index of ring */
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++
++ /* reset prefetch FIFO of ring */
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR |
++ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR);
++ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0);
++
+ mtk_wed_rx_buffer_hw_init(dev);
+ mtk_wed_rro_hw_init(dev);
+ mtk_wed_route_qm_hw_init(dev);
+ }
+
+ wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
++ if (!mtk_wed_is_v1(dev->hw))
++ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
+ }
+
+ static void
+@@ -1099,13 +1497,8 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
+ } else {
+- struct mtk_eth *eth = dev->hw->eth;
+-
+- if(MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+- wed_set(dev, MTK_WED_RESET_IDX,
+- MTK_WED_RESET_IDX_RX_V2);
+- else
+- wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
++ wed_set(dev, MTK_WED_RESET_IDX,
++ dev->hw->soc->regmap.reset_idx_rx_mask);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+@@ -1162,7 +1555,8 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ if (busy) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
+ } else {
+- wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
++ wed_w32(dev, MTK_WED_RESET_IDX,
++ dev->hw->soc->regmap.reset_idx_tx_mask);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+@@ -1226,7 +1620,7 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ }
+
+ dev->init_done = false;
+- if (dev->hw->version == 1)
++ if (mtk_wed_is_v1(dev->hw))
+ return;
+
+ if (!busy) {
+@@ -1257,7 +1651,6 @@ static int
+ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+ bool reset)
+ {
+- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
+ struct mtk_wed_ring *wdma;
+
+ if (idx >= ARRAY_SIZE(dev->rx_wdma))
+@@ -1265,9 +1658,11 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+
+ wdma = &dev->rx_wdma[idx];
+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+- desc_size, true))
++ dev->hw->soc->wdma_desc_size, true))
+ return -ENOMEM;
+
++ wdma->flags |= MTK_WED_RING_CONFIGURED;
++
+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
+ wdma->desc_phys);
+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT,
+@@ -1286,7 +1681,6 @@ static int
+ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+ bool reset)
+ {
+- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
+ struct mtk_wed_ring *wdma;
+
+ if (idx >= ARRAY_SIZE(dev->tx_wdma))
+@@ -1294,9 +1688,29 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+
+ wdma = &dev->tx_wdma[idx];
+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+- desc_size, true))
++ dev->hw->soc->wdma_desc_size, true))
+ return -ENOMEM;
+
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ struct mtk_wdma_desc *desc = wdma->desc;
++ int i;
++
++ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) {
++ desc->buf0 = 0;
++ desc->ctrl = MTK_WDMA_DESC_CTRL_DMA_DONE;
++ desc->buf1 = 0;
++ desc->info = MTK_WDMA_TXD0_DESC_INFO_DMA_DONE;
++ desc++;
++ desc->buf0 = 0;
++ desc->ctrl = MTK_WDMA_DESC_CTRL_DMA_DONE;
++ desc->buf1 = 0;
++ desc->info = MTK_WDMA_TXD1_DESC_INFO_DMA_DONE;
++ desc++;
++ }
++ }
++
++ wdma->flags |= MTK_WED_RING_CONFIGURED;
++
+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
+ wdma->desc_phys);
+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
+@@ -1354,7 +1768,7 @@ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+ MTK_WED_CTRL_WED_TX_BM_EN |
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v1(dev->hw)) {
+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
+ MTK_WED_PCIE_INT_TRIGGER_STATUS);
+
+@@ -1364,8 +1778,9 @@ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+
+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
+ } else {
+- wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
+- GENMASK(1, 0));
++ if (mtk_wed_is_v3_or_greater(dev->hw))
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN);
++
+ /* initail tx interrupt trigger */
+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
+@@ -1384,19 +1799,25 @@ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
+ dev->wlan.txfree_tbit));
+
+- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
+- MTK_WED_WPDMA_INT_CTRL_RX0_EN |
+- MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
+- MTK_WED_WPDMA_INT_CTRL_RX1_EN |
+- MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
+- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
+- dev->wlan.rx_tbit[0]) |
+- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
+- dev->wlan.rx_tbit[1]));
++ if (mtk_wed_get_rx_capa(dev)) {
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
++ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
++ dev->wlan.rx_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
++ dev->wlan.rx_tbit[1]));
++
++ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
++ GENMASK(1, 0));
++ }
+
+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
+ wed_set(dev, MTK_WED_WDMA_INT_CTRL,
+- FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,dev->wdma_idx));
++ FIELD_PREP(MTK_WED_WDMA_INT_POLL_SRC_SEL,
++ dev->wdma_idx));
+ }
+ /* initail wdma interrupt agent */
+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
+@@ -1407,56 +1828,293 @@ mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
+ }
+
++#define MTK_WFMDA_RX_DMA_EN BIT(2)
+ 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);
++ int i;
++
++ if (!mtk_wed_is_v3_or_greater(dev->hw)) {
++ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
++ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
++ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
++ MTK_WED_WPDMA_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);
++ wed_set(dev, MTK_WED_WPDMA_CTRL, MTK_WED_WPDMA_CTRL_SDL1_FIXED);
++ } else {
++ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN |
++ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR);
++ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
++ }
+
+ wed_set(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_TX_DMA_EN |
+ MTK_WED_GLO_CFG_RX_DMA_EN);
+- wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
+- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
++
+ 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);
+-
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v1(dev->hw)) {
+ wdma_set(dev, MTK_WDMA_GLO_CFG,
+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
+- } else {
+- int i;
++ return;
++ }
+
+- 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_set(dev, MTK_WED_WDMA_GLO_CFG,
+- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
+- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) |
++ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8));
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
+
++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
++ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST);
+ 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);
++ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK |
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK |
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
+
+- 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);
++ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
++ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++ }
+
+- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+- MTK_WED_WPDMA_RX_D_RX_DRV_EN |
+- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
+- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
+- 0x2));
++ 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);
++
++ if (!mtk_wed_get_rx_capa(dev))
++ return;
++
++ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
++ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
++ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
++
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN);
++ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
++ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, 0x2));
++
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_EN |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8));
++
++ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
++ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
++ }
++
++ for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
++ struct mtk_wed_ring *ring = &dev->rx_ring[i];
++ u32 val;
++
++ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
++ continue;
++
++ if(mtk_wed_check_wfdma_rx_fill(dev, ring)) {
++ dev_err(dev->hw->dev,
++ "mtk_wed%d: rx(%d) dma enable failed!\n",
++ dev->hw->index, i);
++ continue;
++ }
++
++ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
++ dev->wlan.phy_base) | MTK_WFMDA_RX_DMA_EN;
++
++ wifi_w32(dev,
++ dev->wlan.wpdma_rx_glo - dev->wlan.phy_base,
++ val);
++
++ dev_err(dev->hw->dev,
++ "mtk_wed%d: rx(%d) dma enable successful!\n",
++ dev->hw->index, i);
++ }
++}
++
++static void
++mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask)
++{
++ int i;
++
++ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
++ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
++
++ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
++ return;
++
++ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
++ MTK_WED_RRO_MSDU_PG_DRV_CLR);
++
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX,
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG,
++ dev->wlan.rro_rx_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG,
++ dev->wlan.rro_rx_tbit[1]));
++
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG,
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG,
++ dev->wlan.rx_pg_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG,
++ dev->wlan.rx_pg_tbit[1])|
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG,
++ dev->wlan.rx_pg_tbit[2]));
++
++ /*
++ * RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after
++ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken
++ */
++ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
++ MTK_WED_RRO_MSDU_PG_DRV_EN);
++
++ for (i = 0; i < MTK_WED_RX_QUEUES; i++) {
++ struct mtk_wed_ring *ring = &dev->rx_rro_ring[i];
++
++ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
++ continue;
++
++ if (mtk_wed_check_wfdma_rx_fill(dev, ring))
++ dev_err(dev->hw->dev,
++ "mtk_wed%d: rx_rro_ring(%d) init failed!\n",
++ dev->hw->index, i);
++ }
++
++ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++){
++ struct mtk_wed_ring *ring = &dev->rx_page_ring[i];
++
++ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
++ continue;
++
++ if (mtk_wed_check_wfdma_rx_fill(dev, ring))
++ dev_err(dev->hw->dev,
++ "mtk_wed%d: rx_page_ring(%d) init failed!\n",
++ dev->hw->index, i);
++ }
++}
++
++static void
++mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
++{
++ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
++
++ ring->wpdma = regs;
++
++ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE,
++ readl(regs));
++ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT,
++ readl(regs + MTK_WED_RING_OFS_COUNT));
++
++ ring->flags |= MTK_WED_RING_CONFIGURED;
++}
++
++static void
++mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
++{
++ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
++
++ ring->wpdma = regs;
++
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE,
++ readl(regs));
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT,
++ readl(regs + MTK_WED_RING_OFS_COUNT));
++
++ ring->flags |= MTK_WED_RING_CONFIGURED;
++}
++
++static int
++mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
++{
++ struct mtk_wed_ring *ring = &dev->ind_cmd_ring;
++ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT);
++ int i = 0, count = 0;
+
+- for (i = 0; i < MTK_WED_RX_QUEUES; i++)
+- mtk_wed_check_wfdma_rx_fill(dev, i);
++ ring->wpdma = regs;
++
++ if (readl(regs) & 0xf)
++ pr_info("%s(): address is not 16-byte alignment\n", __func__);
++
++ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE,
++ readl(regs) & 0xfffffff0);
++
++ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT,
++ readl(regs + MTK_WED_RING_OFS_COUNT));
++
++ /* ack sn cr */
++ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base +
++ dev->wlan.ind_cmd.ack_sn_addr);
++ wed_w32(dev, MTK_WED_RRO_CFG1,
++ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ,
++ dev->wlan.ind_cmd.win_size) |
++ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID,
++ dev->wlan.ind_cmd.particular_sid));
++
++ /* particular session addr element */
++ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0,
++ dev->wlan.ind_cmd.particular_se_phys);
++
++ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) {
++ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA,
++ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4);
++ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
++ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f));
++
++ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
++ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) && count++ < 100)
++ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
++
++ if (count >= 100)
++ dev_err(dev->hw->dev,
++ "mtk_wed%d: write ba session base failed!\n",
++ dev->hw->index);
+ }
++
++ /* pn check init */
++ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) {
++ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M,
++ MTK_WED_PN_CHECK_IS_FIRST);
++
++ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR |
++ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i));
++
++ count = 0;
++ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
++ while (!(val & MTK_WED_PN_CHECK_WR_RDY) && count++ < 100)
++ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
++
++ if (count >= 100)
++ dev_err(dev->hw->dev,
++ "mtk_wed%d: session(%d) init failed!\n",
++ dev->hw->index, i);
++ }
++
++ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN);
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
++
++ return 0;
+ }
+
+ static void
+@@ -1477,14 +2135,14 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+
+ mtk_wed_set_ext_int(dev, true);
+
+- if (dev->hw->version == 1) {
++ if (mtk_wed_is_v1(dev->hw)) {
+ 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 {
++ } else if (mtk_wed_get_rx_capa(dev)) {
+ /* driver set mid ready and only once */
+ wed_w32(dev, MTK_WED_EXT_INT_MASK1,
+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
+@@ -1494,12 +2152,19 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ wed_r32(dev, MTK_WED_EXT_INT_MASK1);
+ wed_r32(dev, MTK_WED_EXT_INT_MASK2);
+
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ wed_w32(dev, MTK_WED_EXT_INT_MASK3,
++ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
++ wed_r32(dev, MTK_WED_EXT_INT_MASK3);
++ }
++
+ if (mtk_wed_rro_cfg(dev))
+ return;
+
+ }
+
+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
++ mtk_wed_amsdu_init(dev);
+
+ mtk_wed_dma_enable(dev);
+ dev->running = true;
+@@ -1537,11 +2202,13 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ : &dev->wlan.platform_dev->dev;
+ dev_info(device, "attaching wed device %d version %d\n",
+ hw->index, hw->version);
++
+ dev->hw = hw;
+ dev->dev = hw->dev;
+ dev->irq = hw->irq;
+ dev->wdma_idx = hw->index;
+ dev->version = hw->version;
++ dev->hw->pci_base = mtk_wed_get_pci_base(dev);
+
+ if (hw->eth->dma_dev == hw->eth->dev &&
+ of_dma_is_coherent(hw->eth->dev->of_node))
+@@ -1551,6 +2218,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ if (ret)
+ goto out;
+
++ ret = mtk_wed_amsdu_buffer_alloc(dev);
++ if (ret)
++ goto out;
++
+ if (mtk_wed_get_rx_capa(dev)) {
+ ret = mtk_wed_rro_alloc(dev);
+ if (ret)
+@@ -1563,13 +2234,14 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ init_completion(&dev->wlan_reset_done);
+ atomic_set(&dev->fe_reset, 0);
+
+- if (hw->version == 1) {
++ if (mtk_wed_is_v1(hw))
+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
+ BIT(hw->index), 0);
+- } else {
++ else
+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
++
++ if (mtk_wed_get_rx_capa(dev))
+ ret = mtk_wed_wo_init(hw);
+- }
+
+ out:
+ if (ret) {
+@@ -1613,6 +2285,24 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx,
+
+ ring->reg_base = MTK_WED_RING_TX(idx);
+ ring->wpdma = regs;
++ ring->flags |= MTK_WED_RING_CONFIGURED;
++
++ if (mtk_wed_is_v3_or_greater(dev->hw) && idx == 1) {
++ /* reset prefetch index */
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
++
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
++
++ /* reset prefetch FIFO */
++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
++ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
++ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
++ }
+
+ /* WED -> WPDMA */
+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
+@@ -1632,7 +2322,7 @@ 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, index = dev->hw->version == 1;
++ int i, index = mtk_wed_is_v1(dev->hw);
+
+ /*
+ * For txfree event handling, the same DMA ring is shared between WED
+@@ -1692,9 +2382,13 @@ mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
+
+ 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;
+- if (!dev->hw->num_flows)
+- val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ val &= MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT;
++ } else {
++ val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK;
++ if (!dev->hw->num_flows)
++ val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
++ }
+ if (val && net_ratelimit())
+ pr_err("mtk_wed%d: error status=%08x\n", dev->hw->index, val);
+
+@@ -1718,19 +2412,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask)
+ int mtk_wed_flow_add(int index)
+ {
+ struct mtk_wed_hw *hw = hw_list[index];
+- int ret;
++ int ret = 0;
+
+- if (!hw || !hw->wed_dev)
+- return -ENODEV;
++ mutex_lock(&hw_lock);
+
+- if (hw->num_flows) {
+- hw->num_flows++;
+- return 0;
++ if (!hw || !hw->wed_dev) {
++ ret = -ENODEV;
++ goto out;
+ }
+
+- mutex_lock(&hw_lock);
+- if (!hw->wed_dev) {
+- ret = -ENODEV;
++ if (!hw->wed_dev->wlan.offload_enable)
++ goto out;
++
++ if (hw->num_flows) {
++ hw->num_flows++;
+ goto out;
+ }
+
+@@ -1749,14 +2444,15 @@ void mtk_wed_flow_remove(int index)
+ {
+ struct mtk_wed_hw *hw = hw_list[index];
+
+- if (!hw)
+- return;
++ mutex_lock(&hw_lock);
+
+- if (--hw->num_flows)
+- return;
++ if (!hw || !hw->wed_dev)
++ goto out;
+
+- mutex_lock(&hw_lock);
+- if (!hw->wed_dev)
++ if (!hw->wed_dev->wlan.offload_disable)
++ goto out;
++
++ if (--hw->num_flows)
+ goto out;
+
+ hw->wed_dev->wlan.offload_disable(hw->wed_dev);
+@@ -1799,6 +2495,10 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ .detach = mtk_wed_detach,
+ .setup_tc = mtk_wed_eth_setup_tc,
+ .ppe_check = mtk_wed_ppe_check,
++ .start_hw_rro = mtk_wed_start_hw_rro,
++ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup,
++ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup,
++ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup,
+ };
+ struct device_node *eth_np = eth->dev->of_node;
+ struct platform_device *pdev;
+@@ -1840,14 +2540,22 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ hw->wdma_phy = wdma_phy;
+ hw->index = index;
+ hw->irq = irq;
+- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
++ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) ?
++ 3 : MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+
+- if (hw->version == 1) {
++ switch (hw->version) {
++ case 2:
++ hw->soc = &mt7986_data;
++ break;
++ case 3:
++ hw->soc = &mt7988_data;
++ break;
++ default:
++ case 1:
+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
+- "mediatek,pcie-mirror");
++ "mediatek,pcie-mirror");
+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
+- "mediatek,hifsys");
+-
++ "mediatek,hifsys");
+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) {
+ kfree(hw);
+ goto unlock;
+@@ -1857,8 +2565,10 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ regmap_write(hw->mirror, 0, 0);
+ regmap_write(hw->mirror, 4, 0);
+ }
++ hw->soc = &mt7622_data;
++ break;
+ }
+-
++
+ mtk_wed_hw_add_debugfs(hw);
+
+ hw_list[index] = hw;
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
+index 2ce1a5b..f5e30ce 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed.h
+@@ -8,12 +8,18 @@
+ #include <linux/debugfs.h>
+ #include <linux/regmap.h>
+ #include <linux/netdevice.h>
++
++#include "mtk_wed_regs.h"
++
+ #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
+
+-#define MTK_WED_PKT_SIZE 1900
++#define MTK_WED_PKT_SIZE 1920//1900
+ #define MTK_WED_BUF_SIZE 2048
++#define MTK_WED_PAGE_BUF_SIZE 128
+ #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
++#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
+ #define MTK_WED_RX_RING_SIZE 1536
++#define MTK_WED_RX_PG_BM_CNT 8192
+
+ #define MTK_WED_TX_RING_SIZE 2048
+ #define MTK_WED_WDMA_RING_SIZE 512
+@@ -27,12 +33,27 @@
+ #define MTK_WED_RRO_QUE_CNT 8192
+ #define MTK_WED_MIOD_ENTRY_CNT 128
+
++#define MTK_WED_TX_BM_DMA_SIZE 65536
++#define MTK_WED_TX_BM_PKT_CNT 32768
++
+ #define MTK_WED_MODULE_ID_WO 1
+
+ struct mtk_eth;
+ struct mtk_wed_wo;
+
++struct mtk_wed_soc_data {
++ struct {
++ u32 tx_bm_tkid;
++ u32 wpdma_rx_ring0;
++ u32 reset_idx_tx_mask;
++ u32 reset_idx_rx_mask;
++ } regmap;
++ u32 tx_ring_desc_size;
++ u32 wdma_desc_size;
++};
++
+ struct mtk_wed_hw {
++ const struct mtk_wed_soc_data *soc;
+ struct device_node *node;
+ struct mtk_eth *eth;
+ struct regmap *regs;
+@@ -44,12 +65,15 @@ struct mtk_wed_hw {
+ struct dentry *debugfs_dir;
+ struct mtk_wed_device *wed_dev;
+ struct mtk_wed_wo *wed_wo;
++ struct mtk_wed_amsdu *wed_amsdu;
++ u32 pci_base;
+ u32 debugfs_reg;
+ u32 num_flows;
+ u8 version;
+ char dirname[5];
+ int irq;
+ int index;
++ int token_id;
+ };
+
+ struct mtk_wdma_info {
+@@ -57,9 +81,41 @@ struct mtk_wdma_info {
+ u8 queue;
+ u16 wcid;
+ u8 bss;
++ u32 usr_info;
++ u8 tid;
++ u8 is_fixedrate;
++ u8 is_prior;
++ u8 is_sp;
++ u8 hf;
++ u8 amsdu;
++};
++
++struct mtk_wed_amsdu {
++ void *txd;
++ dma_addr_t txd_phy;
+ };
+
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
++static inline bool mtk_wed_is_v1(struct mtk_wed_hw *hw)
++{
++ return hw->version == 1;
++}
++
++static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw)
++{
++ return hw->version == 2;
++}
++
++static inline bool mtk_wed_is_v3(struct mtk_wed_hw *hw)
++{
++ return hw->version == 3;
++}
++
++static inline bool mtk_wed_is_v3_or_greater(struct mtk_wed_hw *hw)
++{
++ return hw->version > 2;
++}
++
+ static inline void
+ wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
+ {
+@@ -154,6 +210,21 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
+ writel(val, dev->txfree_ring.wpdma + reg);
+ }
+
++static inline u32 mtk_wed_get_pci_base(struct mtk_wed_device *dev)
++{
++ if (!mtk_wed_is_v3_or_greater(dev->hw))
++ return MTK_WED_PCIE_BASE;
++
++ switch (dev->hw->index) {
++ case 1:
++ return MTK_WED_PCIE_BASE1;
++ case 2:
++ return MTK_WED_PCIE_BASE2;
++ default:
++ return MTK_WED_PCIE_BASE0;
++ }
++}
++
+ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ void __iomem *wdma, phys_addr_t wdma_phy,
+ int index);
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+index 7d8be99..69fe29b 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+@@ -11,9 +11,11 @@ struct reg_dump {
+ u16 offset;
+ u8 type;
+ u8 base;
++ u32 mask;
+ };
+
+ enum {
++ DUMP_TYPE_END,
+ DUMP_TYPE_STRING,
+ DUMP_TYPE_WED,
+ DUMP_TYPE_WDMA,
+@@ -23,8 +25,11 @@ enum {
+ DUMP_TYPE_WED_RRO,
+ };
+
++#define DUMP_END() { .type = DUMP_TYPE_END }
+ #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
+ #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
++#define DUMP_REG_MASK(_reg, _mask) { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
++
+ #define DUMP_RING(_prefix, _base, ...) \
+ { _prefix " BASE", _base, __VA_ARGS__ }, \
+ { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \
+@@ -32,6 +37,7 @@ enum {
+ { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
+
+ #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
++#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
+ #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
+
+ #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
+@@ -52,36 +58,49 @@ print_reg_val(struct seq_file *s, const char *name, u32 val)
+
+ static void
+ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
+- const struct reg_dump *regs, int n_regs)
++ const struct reg_dump **regs)
+ {
+- const struct reg_dump *cur;
++ const struct reg_dump **cur_o = regs, *cur;
++ bool newline = false;
+ u32 val;
+
+- for (cur = regs; cur < ®s[n_regs]; cur++) {
+- switch (cur->type) {
+- case DUMP_TYPE_STRING:
+- seq_printf(s, "%s======== %s:\n",
+- cur > regs ? "\n" : "",
+- cur->name);
+- continue;
+- case DUMP_TYPE_WED:
+- case DUMP_TYPE_WED_RRO:
+- val = wed_r32(dev, cur->offset);
+- break;
+- case DUMP_TYPE_WDMA:
+- val = wdma_r32(dev, cur->offset);
+- break;
+- case DUMP_TYPE_WPDMA_TX:
+- val = wpdma_tx_r32(dev, cur->base, cur->offset);
+- break;
+- case DUMP_TYPE_WPDMA_TXFREE:
+- val = wpdma_txfree_r32(dev, cur->offset);
+- break;
+- case DUMP_TYPE_WPDMA_RX:
+- val = wpdma_rx_r32(dev, cur->base, cur->offset);
+- break;
++ while (*cur_o) {
++ cur = *cur_o;
++
++ while (cur->type != DUMP_TYPE_END) {
++ switch (cur->type) {
++ case DUMP_TYPE_STRING:
++ seq_printf(s, "%s======== %s:\n",
++ newline ? "\n" : "",
++ cur->name);
++ newline = true;
++ cur++;
++ continue;
++ case DUMP_TYPE_WED:
++ case DUMP_TYPE_WED_RRO:
++ val = wed_r32(dev, cur->offset);
++ break;
++ case DUMP_TYPE_WDMA:
++ val = wdma_r32(dev, cur->offset);
++ break;
++ case DUMP_TYPE_WPDMA_TX:
++ val = wpdma_tx_r32(dev, cur->base, cur->offset);
++ break;
++ case DUMP_TYPE_WPDMA_TXFREE:
++ val = wpdma_txfree_r32(dev, cur->offset);
++ break;
++ case DUMP_TYPE_WPDMA_RX:
++ val = wpdma_rx_r32(dev, cur->base, cur->offset);
++ break;
++ }
++
++ if (cur->mask)
++ val = (cur->mask & val) >> (ffs(cur->mask) - 1);
++
++ print_reg_val(s, cur->name, val);
++ cur++;
+ }
+- print_reg_val(s, cur->name, val);
++ cur_o++;
+ }
+ }
+
+@@ -89,7 +108,7 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
+ static int
+ wed_txinfo_show(struct seq_file *s, void *data)
+ {
+- static const struct reg_dump regs[] = {
++ static const struct reg_dump regs_common[] = {
+ DUMP_STR("WED TX"),
+ DUMP_WED(WED_TX_MIB(0)),
+ DUMP_WED_RING(WED_RING_TX(0)),
+@@ -128,16 +147,32 @@ wed_txinfo_show(struct seq_file *s, void *data)
+ DUMP_WDMA_RING(WDMA_RING_RX(0)),
+ DUMP_WDMA_RING(WDMA_RING_RX(1)),
+
+- DUMP_STR("TX FREE"),
++ DUMP_STR("WED TX FREE"),
+ DUMP_WED(WED_RX_MIB(0)),
++ DUMP_WED_RING(WED_RING_RX(0)),
++ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
++
++ DUMP_WED(WED_RX_MIB(1)),
++ DUMP_WED_RING(WED_RING_RX(1)),
++ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
++ DUMP_STR("WED_WPDMA TX FREE"),
++ DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
++ DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
++ DUMP_END(),
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
+ };
++
+ struct mtk_wed_hw *hw = s->private;
+ struct mtk_wed_device *dev = hw->wed_dev;
+
+ if (!dev)
+ return 0;
+
+- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
++ dump_wed_regs(s, dev, regs);
+
+ return 0;
+ }
+@@ -146,7 +181,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
+ static int
+ wed_rxinfo_show(struct seq_file *s, void *data)
+ {
+- static const struct reg_dump regs[] = {
++ static const struct reg_dump regs_common[] = {
+ DUMP_STR("WPDMA RX"),
+ DUMP_WPDMA_RX_RING(0),
+ DUMP_WPDMA_RX_RING(1),
+@@ -164,7 +199,7 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ DUMP_WED_RING(WED_RING_RX_DATA(0)),
+ DUMP_WED_RING(WED_RING_RX_DATA(1)),
+
+- DUMP_STR("WED RRO"),
++ DUMP_STR("WED WO RRO"),
+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
+ DUMP_WED(WED_RROQM_MID_MIB),
+ DUMP_WED(WED_RROQM_MOD_MIB),
+@@ -175,16 +210,6 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
+
+- DUMP_STR("WED Route QM"),
+- DUMP_WED(WED_RTQM_R2H_MIB(0)),
+- DUMP_WED(WED_RTQM_R2Q_MIB(0)),
+- DUMP_WED(WED_RTQM_Q2H_MIB(0)),
+- DUMP_WED(WED_RTQM_R2H_MIB(1)),
+- DUMP_WED(WED_RTQM_R2Q_MIB(1)),
+- DUMP_WED(WED_RTQM_Q2H_MIB(1)),
+- DUMP_WED(WED_RTQM_Q2N_MIB),
+- DUMP_WED(WED_RTQM_Q2B_MIB),
+- DUMP_WED(WED_RTQM_PFDBK_MIB),
+
+ DUMP_STR("WED WDMA TX"),
+ DUMP_WED(WED_WDMA_TX_MIB),
+@@ -205,15 +230,99 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ DUMP_WED(WED_RX_BM_INTF2),
+ DUMP_WED(WED_RX_BM_INTF),
+ DUMP_WED(WED_RX_BM_ERR_STS),
++ DUMP_END()
++ };
++
++ static const struct reg_dump regs_v2[] = {
++ DUMP_STR("WED Route QM"),
++ DUMP_WED(WED_RTQM_R2H_MIB(0)),
++ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
++ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
++ DUMP_WED(WED_RTQM_R2H_MIB(1)),
++ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
++ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
++ DUMP_WED(WED_RTQM_Q2N_MIB),
++ DUMP_WED(WED_RTQM_Q2B_MIB),
++ DUMP_WED(WED_RTQM_PFDBK_MIB),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump regs_v3[] = {
++ DUMP_STR("WED RX RRO DATA"),
++ DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
++ DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
++
++ DUMP_STR("WED RX MSDU PAGE"),
++ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
++ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
++ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
++
++ DUMP_STR("WED RX IND CMD"),
++ DUMP_WED(WED_IND_CMD_RX_CTRL1),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
++ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
++ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
++ WED_IND_CMD_PREFETCH_FREE_CNT),
++ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
++
++ DUMP_STR("WED ADDR ELEM"),
++ DUMP_WED(WED_ADDR_ELEM_CFG0),
++ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
++ WED_ADDR_ELEM_PREFETCH_FREE_CNT),
++
++ DUMP_STR("WED Route QM"),
++ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
++ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT),
++ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT),
++ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT),
++ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT),
++ DUMP_WED(WED_RTQM_ENQ_ERR_CNT),
++
++ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT),
++ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT),
++ DUMP_WED(WED_RTQM_DEQ_PKT_CNT),
++ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT),
++ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT),
++ DUMP_WED(WED_RTQM_DEQ_ERR_CNT),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs_new_v2[] = {
++ ®s_common[0],
++ ®s_v2[0],
++ NULL,
++ };
++
++ static const struct reg_dump *regs_new_v3[] = {
++ ®s_common[0],
++ ®s_v3[0],
++ NULL,
+ };
+
+ struct mtk_wed_hw *hw = s->private;
+ struct mtk_wed_device *dev = hw->wed_dev;
++ const struct reg_dump **regs;
+
+ if (!dev)
+ return 0;
+
+- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
++ switch(dev->hw->version) {
++ case 2:
++ regs = regs_new_v2;
++ break;
++ case 3:
++ regs = regs_new_v3;
++ break;
++ default:
++ return 0;
++ }
++
++ dump_wed_regs(s, dev, regs);
+
+ return 0;
+ }
+@@ -248,6 +357,381 @@ mtk_wed_reg_get(void *data, u64 *val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
+ "0x%08llx\n");
+
++static int
++wed_token_txd_show(struct seq_file *s, void *data)
++{
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++ struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages;
++ int token = dev->wlan.token_start;
++ u32 val = hw->token_id, size = 1;
++ int page_idx = (val - token) / 2;
++ int i;
++
++ if (val < token) {
++ size = val;
++ page_idx = 0;
++ }
++
++ for (i = 0; i < size; i += MTK_WED_BUF_PER_PAGE) {
++ void *page = page_list[page_idx++].p;
++ void *buf;
++ int j;
++
++ if (!page)
++ break;
++
++ buf = page_to_virt(page);
++
++ for (j = 0; j < MTK_WED_BUF_PER_PAGE; j++) {
++ printk("[TXD]:token id = %d\n", token + 2 * (page_idx - 1) + j);
++ print_hex_dump(KERN_ERR , "", DUMP_PREFIX_OFFSET, 16, 1, (u8 *)buf, 128, false);
++ seq_printf(s, "\n");
++
++ buf += MTK_WED_BUF_SIZE;
++ }
++ }
++
++ return 0;
++}
++
++DEFINE_SHOW_ATTRIBUTE(wed_token_txd);
++
++static int
++wed_amsdu_show(struct seq_file *s, void *data)
++{
++ static const struct reg_dump regs_common[] = {
++ DUMP_STR("WED AMDSU INFO"),
++ DUMP_WED(WED_MON_AMSDU_FIFO_DMAD),
++
++ DUMP_STR("WED AMDSU ENG0 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(0)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(0)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(0)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(0)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(0)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG1 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(1)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(1)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(1)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(1)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(1)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG2 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(2)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(2)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(2)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(2)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(2)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG3 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(3)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(3)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(3)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(3)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(3)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG4 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(4)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(4)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(4)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(4)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(4)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG5 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(5)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(5)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(5)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(5)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(5)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG6 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(6)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(6)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(6)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(6)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(6)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG7 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(7)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(7)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(7)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(7)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(7)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED AMDSU ENG8 INFO"),
++ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(8)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(8)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENI(8)),
++ DUMP_WED(WED_MON_AMSDU_ENG_QENO(8)),
++ DUMP_WED(WED_MON_AMSDU_ENG_MERG(8)),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
++ WED_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8),
++ WED_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
++ WED_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
++ WED_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8),
++ WED_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("WED QMEM INFO"),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_FQ_CNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_SP_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID0_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID1_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID2_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID3_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID4_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID5_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID6_QCNT),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID7_QCNT),
++
++ DUMP_STR("WED QMEM HEAD INFO"),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_FQ_HEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_SP_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID0_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID1_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID2_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID3_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID4_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID5_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID6_QHEAD),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID7_QHEAD),
++
++ DUMP_STR("WED QMEM TAIL INFO"),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_FQ_TAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_SP_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID0_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID1_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID2_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID3_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID4_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID5_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL),
++ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL),
++
++ DUMP_STR("WED HIFTXD MSDU INFO"),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(3)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(4)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(5)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(6)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(7)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(8)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(9)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(10)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)),
++ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)),
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
++ };
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++
++ if (!dev)
++ return 0;
++
++ dump_wed_regs(s, dev, regs);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_amsdu);
++
++static int
++wed_rtqm_show(struct seq_file *s, void *data)
++{
++ static const struct reg_dump regs_common[] = {
++ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"),
++ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT),
++
++
++ DUMP_STR("WED Route QM IGRS1(Legacy)"),
++ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT),
++
++ DUMP_STR("WED Route QM IGRS2(RRO3.0)"),
++ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT),
++
++ DUMP_STR("WED Route QM IGRS3(DEBUG)"),
++ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
++ };
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++
++ if (!dev)
++ return 0;
++
++ dump_wed_regs(s, dev, regs);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
++
++
++static int
++wed_rro_show(struct seq_file *s, void *data)
++{
++ static const struct reg_dump regs_common[] = {
++ DUMP_STR("RRO/IND CMD CNT"),
++ DUMP_WED(WED_RX_IND_CMD_CNT(1)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(2)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(3)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(4)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(5)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(6)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(7)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(8)),
++ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9),
++ WED_IND_CMD_MAGIC_CNT_FAIL_CNT),
++
++ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)),
++ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1),
++ WED_ADDR_ELEM_SIG_FAIL_CNT),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(1)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(2)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(3)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(4)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(5)),
++ DUMP_WED_MASK(WED_RX_PN_CHK_CNT,
++ WED_PN_CHK_FAIL_CNT),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
++ };
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++
++ if (!dev)
++ return 0;
++
++ dump_wed_regs(s, dev, regs);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_rro);
++
+ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
+ {
+ struct dentry *dir;
+@@ -261,8 +745,20 @@ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
+ debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
+ debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
+ debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
+- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
+- if (hw->version != 1) {
++ debugfs_create_u32("token_id", 0600, dir, &hw->token_id);
++ debugfs_create_file_unsafe("token_txd", 0600, dir, hw, &wed_token_txd_fops);
++
++ if (!mtk_wed_is_v1(hw)) {
++ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw,
++ &wed_rxinfo_fops);
+ wed_wo_mcu_debugfs(hw, dir);
++ if (mtk_wed_is_v3_or_greater(hw)) {
++ debugfs_create_file_unsafe("amsdu", 0400, dir, hw,
++ &wed_amsdu_fops);
++ debugfs_create_file_unsafe("rtqm", 0400, dir, hw,
++ &wed_rtqm_fops);
++ debugfs_create_file_unsafe("rro", 0400, dir, hw,
++ &wed_rro_fops);
++ }
+ }
+ }
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+index be63406..18d1fb1 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -91,7 +91,7 @@ mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, int len)
+ {
+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
+
+- if (dev->hw->version == 1)
++ if (!mtk_wed_get_rx_capa(dev))
+ return 0;
+
+ if (WARN_ON(!wo))
+@@ -248,7 +248,7 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+ u8 reserved1[15];
+ } __packed *region;
+
+- char *mcu;
++ char *fw_name;
+ const struct mtk_wed_fw_trailer *hdr;
+ static u8 shared[MAX_REGION_SIZE] = {0};
+ const struct firmware *fw;
+@@ -256,13 +256,24 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+ u32 ofs = 0;
+ u32 boot_cr, val;
+
+- if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
+- mcu = MT7981_FIRMWARE_WO;
+- else
+- mcu = wo->hw->index ? MT7986_FIRMWARE_WO_2 :
+- MT7986_FIRMWARE_WO_1;
++ switch (wo->hw->version) {
++ case 2:
++ if (of_device_is_compatible(wo->hw->node,
++ "mediatek,mt7981-wed"))
++ fw_name = MT7981_FIRMWARE_WO;
++ else
++ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1
++ : MT7986_FIRMWARE_WO0;
++ break;
++ case 3:
++ fw_name = wo->hw->index ? MT7988_FIRMWARE_WO1
++ : MT7988_FIRMWARE_WO0;
++ break;
++ default:
++ return -EINVAL;
++ }
+
+- ret = request_firmware(&fw, mcu, wo->hw->dev);
++ ret = request_firmware(&fw, fw_name, wo->hw->dev);
+ if (ret)
+ return ret;
+
+@@ -307,8 +318,11 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+ }
+
+ /* write the start address */
+- boot_cr = wo->hw->index ?
+- WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR : WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
++ if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
++ boot_cr = WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR;
++ else
++ boot_cr = WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
++
+ wo_w32(wo, boot_cr, (wo->region[WO_REGION_EMI].addr_pa >> 16));
+
+ /* wo firmware reset */
+@@ -316,8 +330,10 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+
+ val = wo_r32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
+
+- val |= wo->hw->index ? WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WA_CPU_RSTB_MASK :
+- WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
++ if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
++ val |= WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WA_CPU_RSTB_MASK;
++ else
++ val |= WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
+
+ wo_w32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
+index dbb17ae..6d4c9a7 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
+@@ -17,8 +17,11 @@
+ #define WARP_ALREADY_DONE_STATUS (1)
+
+ #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
+-#define MT7986_FIRMWARE_WO_1 "mediatek/mt7986_wo_0.bin"
+-#define MT7986_FIRMWARE_WO_2 "mediatek/mt7986_wo_1.bin"
++#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
++#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
++#define MT7988_FIRMWARE_WO0 "mediatek/mtk_wo_0.bin"
++#define MT7988_FIRMWARE_WO1 "mediatek/mtk_wo_1.bin"
++#define MT7988_FIRMWARE_WO2 "mediatek/mtk_wo_2.bin"
+
+ #define WOCPU_EMI_DEV_NODE "mediatek,wocpu_emi"
+ #define WOCPU_ILM_DEV_NODE "mediatek,wocpu_ilm"
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+index 645b8b1..0af264d 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+@@ -14,6 +14,9 @@
+ #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
+ #define MTK_WED_RX_BM_TOKEN GENMASK(31, 16)
+
++#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29)
++#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31)
++
+ struct mtk_wdma_desc {
+ __le32 buf0;
+ __le32 ctrl;
+@@ -45,6 +48,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
+ #define MTK_WED_RESET_RX_RRO_QM BIT(20)
+ #define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
++#define MTK_WED_RESET_TX_AMSDU BIT(22)
+ #define MTK_WED_RESET_WED BIT(31)
+
+ #define MTK_WED_CTRL 0x00c
+@@ -52,6 +56,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1)
+ #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2)
+ #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
++#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
++#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
++#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7)
+ #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
+ #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
+ #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
+@@ -62,9 +69,14 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
+ #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
+ #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
++#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20)
++#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21)
++#define MTK_WED_CTRL_TX_AMSDU_EN BIT(22)
++#define MTK_WED_CTRL_TX_AMSDU_BUSY BIT(23)
+ #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_CTRL_FLD_MIB_RD_CLR BIT(28)
+
+ #define MTK_WED_EXT_INT_STATUS 0x020
+ #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0)
+@@ -72,12 +84,10 @@ struct mtk_wdma_desc {
+ #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4)
+ #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8)
+ #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9)
+-#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+-#define MTK_WED_EXT_INT_STATUS_TX_TKID_LO_TH BIT(10)
+-#define MTK_WED_EXT_INT_STATUS_TX_TKID_HI_TH BIT(11)
+-#endif
+-#define MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY BIT(12)
+-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER BIT(13)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH2 BIT(10)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH2 BIT(11)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
+ #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
+ #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
+ #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
+@@ -94,17 +104,15 @@ struct mtk_wdma_desc {
+ #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
+ MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
+- MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY | \
+- MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER | \
+ 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_DMA_R_RESP_ERR | \
+- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR)
++ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR)
+
+ #define MTK_WED_EXT_INT_MASK 0x028
+ #define MTK_WED_EXT_INT_MASK1 0x02c
+ #define MTK_WED_EXT_INT_MASK2 0x030
++#define MTK_WED_EXT_INT_MASK3 0x034
+
+ #define MTK_WED_STATUS 0x060
+ #define MTK_WED_STATUS_TX GENMASK(15, 8)
+@@ -112,12 +120,15 @@ struct mtk_wdma_desc {
+ #define MTK_WED_TX_BM_CTRL 0x080
+ #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
+ #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
++#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26)
++#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27)
+ #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28)
+
+ #define MTK_WED_TX_BM_BASE 0x084
++#define MTK_WED_TX_BM_INIT_PTR 0x088
++#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0)
++#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16)
+
+-#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)
+
+@@ -140,6 +151,9 @@ struct mtk_wdma_desc {
+ #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_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0)
++#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16)
++
+ #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)
+@@ -205,12 +219,15 @@ struct mtk_wdma_desc {
+ #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_EVENT_PKT_FMT_VER GENMASK(15, 12)
++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18)
+ #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_DRV_EVENT_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_DDONE_CHK_LAST BIT(25)
+ #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28)
++#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30)
+
+ /* CONFIG_MEDIATEK_NETSYS_V1 */
+ #define MTK_WED_WPDMA_GLO_CFG_RX_BT_SIZE GENMASK(5, 4)
+@@ -273,9 +290,11 @@ struct mtk_wdma_desc {
+ #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_POLL_EN GENMASK(13, 12)
+ #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_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
++#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21)
++
+ #define MTK_WED_WPDMA_CFG_BASE 0x580
+ #define MTK_WED_WPDMA_CFG_INT_MASK 0x584
+ #define MTK_WED_WPDMA_CFG_TX 0x588
+@@ -304,20 +323,50 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
+
+ #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
+-#define MTK_WED_WPDMA_RX_RING 0x770
++#if defined(CONFIG_MEDIATEK_NETSYS_V2)
++#define MTK_WED_WPDMA_RX_RING0 0x770
++#else
++#define MTK_WED_WPDMA_RX_RING0 0x7d0
++#endif
++#define MTK_WED_WPDMA_RX_RING1 0x7d8
+
+ #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
+ #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
+ #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
+
++#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
++#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
++#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
++#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
++
++#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8
++#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15)
++
++#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc
++
++#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0
++#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0)
++#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16)
++
+ #define MTK_WED_WDMA_RING_TX 0x800
+
+ #define MTK_WED_WDMA_TX_MIB 0x810
+
+-
+ #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
+ #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
+
++#define MTK_WED_WDMA_RX_PREF_CFG 0x950
++#define MTK_WED_WDMA_RX_PREF_EN BIT(0)
++#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
++#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
++#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
++#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
++#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
++
++#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
++#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
++#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16)
++
+ #define MTK_WED_WDMA_GLO_CFG 0xa04
+ #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
+ #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
+@@ -350,6 +399,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
+
+ #define MTK_WED_WDMA_INT_CTRL 0xa2c
++#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0)
+ #define MTK_WED_WDMA_INT_POLL_SRC_SEL GENMASK(17, 16)
+
+ #define MTK_WED_WDMA_CFG_BASE 0xaa0
+@@ -369,7 +419,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_RX_BM_BASE 0xd84
+ #define MTK_WED_RX_BM_INIT_PTR 0xd88
+-#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0)
++#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0)
+ #define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16)
+
+ #define MTK_WED_RX_PTR 0xd8c
+@@ -411,6 +461,18 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_INT_GRP1 0x250
+ #define MTK_WDMA_INT_GRP2 0x254
+
++#define MTK_WDMA_PREF_TX_CFG 0x2d0
++#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
++
++#define MTK_WDMA_PREF_RX_CFG 0x2dc
++#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
++
++#define MTK_WDMA_WRBK_TX_CFG 0x300
++#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
++
++#define MTK_WDMA_WRBK_RX_CFG 0x344
++#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
++
+ #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
+ #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
+ #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
+@@ -419,11 +481,36 @@ struct mtk_wdma_desc {
+ #define HIFSYS_DMA_AG_MAP 0x008
+
+ #define MTK_WED_RTQM_GLO_CFG 0xb00
+-#define MTK_WED_RTQM_BUSY BIT(1)
+-#define MTK_WED_RTQM_Q_RST BIT(2)
++#define MTK_WED_RTQM_BUSY BIT(1)
++#define MTK_WED_RTQM_Q_RST BIT(2)
+ #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
+ #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
+
++#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
++#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
++#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34
++
++
++#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44
++#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50
++#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c
++
++#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c
++#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78
++#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84
++
++#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94
++#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0
++#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac
++
+ #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
+ #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
+ #define MTK_WED_RTQM_Q2N_MIB 0xb80
+@@ -432,21 +519,39 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RTQM_Q2B_MIB 0xb8c
+ #define MTK_WED_RTQM_PFDBK_MIB 0xb90
+
++#define MTK_WED_RTQM_ENQ_CFG0 0xbb8
++#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12)
++
++#define MTK_WED_RTQM_FDROP_MIB 0xb84
++#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc
++#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0
++#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4
++#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8
++#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc
++#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0
++
++#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8
++#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc
++#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0
++#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4
++#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8
++#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec
++
+ #define MTK_WED_RROQM_GLO_CFG 0xc04
+ #define MTK_WED_RROQM_RST_IDX 0xc08
+-#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
+-#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4)
++#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
++#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4)
+
+ #define MTK_WED_RROQM_MIOD_CTRL0 0xc40
+ #define MTK_WED_RROQM_MIOD_CTRL1 0xc44
+-#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0)
++#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0)
+
+ #define MTK_WED_RROQM_MIOD_CTRL2 0xc48
+ #define MTK_WED_RROQM_MIOD_CTRL3 0xc4c
+
+ #define MTK_WED_RROQM_FDBK_CTRL0 0xc50
+ #define MTK_WED_RROQM_FDBK_CTRL1 0xc54
+-#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0)
++#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0)
+
+ #define MTK_WED_RROQM_FDBK_CTRL2 0xc58
+
+@@ -454,7 +559,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RROQ_BASE_H 0xc84
+
+ #define MTK_WED_RROQM_MIOD_CFG 0xc8c
+-#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0)
++#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0)
+ #define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8)
+ #define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16)
+
+@@ -468,20 +573,206 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8
+ #define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec
+
+-#define MTK_WED_RX_BM_RX_DMAD 0xd80
++#define MTK_WED_RX_BM_RX_DMAD 0xd80
+ #define MTK_WED_RX_BM_BASE 0xd84
+ #define MTK_WED_RX_BM_INIT_PTR 0xd88
+-#define MTK_WED_RX_BM_PTR 0xd8c
+-#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
++#define MTK_WED_RX_BM_PTR 0xd8c
+ #define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0)
++#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
+
+-#define MTK_WED_RX_BM_BLEN 0xd90
++#define MTK_WED_RX_BM_BLEN 0xd90
+ #define MTK_WED_RX_BM_STS 0xd94
+ #define MTK_WED_RX_BM_INTF2 0xd98
+ #define MTK_WED_RX_BM_INTF 0xd9c
+ #define MTK_WED_RX_BM_ERR_STS 0xda8
+
+-#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
++#define MTK_RRO_IND_CMD_SIGNATURE 0xe00
++#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0)
++#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28)
++
++#define MTK_WED_IND_CMD_RX_CTRL0 0xe04
++#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0)
++#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16)
++#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28)
++
++#define MTK_WED_IND_CMD_RX_CTRL1 0xe08
++#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c
++#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0)
++#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16)
++
++#define MTK_WED_RRO_CFG0 0xe10
++#define MTK_WED_RRO_CFG1 0xe14
++#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29)
++#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16)
++#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0)
++
++#define MTK_WED_ADDR_ELEM_CFG0 0xe18
++#define MTK_WED_ADDR_ELEM_CFG1 0xe1c
++#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16)
++
++#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20
++#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0)
++#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28)
++#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29)
++#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30)
++#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31)
++
++#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24
++#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28
++
++#define MTK_WED_PN_CHECK_CFG 0xe30
++#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0)
++#define MTK_WED_PN_CHECK_RD_RDY BIT(28)
++#define MTK_WED_PN_CHECK_WR_RDY BIT(29)
++#define MTK_WED_PN_CHECK_RD BIT(30)
++#define MTK_WED_PN_CHECK_WR BIT(31)
++
++#define MTK_WED_PN_CHECK_WDATA_M 0xe38
++#define MTK_WED_PN_CHECK_IS_FIRST BIT(17)
++
++#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8)
++
++#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58
++#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26)
++#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31)
++
++#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc)
++#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc)
++#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc)
++
++#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10)
++
++#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13)
++
++#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4)
++#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26)
++#define MTK_WED_RRO_RX_D_DRV_EN BIT(31)
++
++#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0
++#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0)
++
++#define MTK_WED_RRO_PG_BM_BASE 0xeb4
++#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8
++#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0)
++#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16)
++
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10)
++
++#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
++
++#define MTK_WED_RX_IND_CMD_CNT0 0xf20
++#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
++
++#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4)
++#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0)
++
++#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4)
++#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0)
++#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16)
++#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0)
++
++#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4)
++
++#define MTK_WED_RX_PN_CHK_CNT 0xf70
++#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0)
++
++#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
+ #define MTK_WED_PCIE_INT_MASK 0x0
+
++#define MTK_WED_AMSDU_FIFO 0x1800
++#define MTK_WED_AMSDU_IS_PRIOR0_RING BIT(10)
++
++#define MTK_WED_AMSDU_STA_INFO 0x01810
++#define MTK_WED_AMSDU_STA_INFO_DO_INIT BIT(0)
++#define MTK_WED_AMSDU_STA_INFO_SET_INIT BIT(1)
++
++#define MTK_WED_AMSDU_STA_INFO_INIT 0x01814
++#define MTK_WED_AMSDU_STA_WTBL_HDRT_MODE BIT(0)
++#define MTK_WED_AMSDU_STA_RMVL BIT(1)
++#define MTK_WED_AMSDU_STA_MAX_AMSDU_LEN GENMASK(7, 2)
++#define MTK_WED_AMSDU_STA_MAX_AMSDU_NUM GENMASK(11, 8)
++
++#define MTK_WED_AMSDU_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4)
++
++#define MTK_WED_AMSDU_PSE 0x1910
++#define MTK_WED_AMSDU_PSE_RESET BIT(16)
++
++#define MTK_WED_AMSDU_HIFTXD_CFG 0x1968
++#define MTK_WED_AMSDU_HIFTXD_SRC GENMASK(16, 15)
++
++#define MTK_WED_MON_AMSDU_FIFO_DMAD 0x1a34
++
++#define MTK_WED_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50)
++#define MTK_WED_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50)
++#define MTK_WED_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50)
++#define MTK_WED_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50)
++#define MTK_WED_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50)
++
++#define MTK_WED_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50)
++#define MTK_WED_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0)
++#define MTK_WED_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16)
++
++#define MTK_WED_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50)
++#define MTK_WED_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0)
++#define MTK_WED_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16)
++#define MTK_WED_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24)
++
++#define MTK_WED_MON_AMSDU_QMEM_STS1 0x1e04
++
++#define MTK_WED_MON_AMSDU_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4)
++#define MTK_WED_AMSDU_QMEM_FQ_CNT GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_SP_QCNT GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID0_QCNT GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID1_QCNT GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID2_QCNT GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID3_QCNT GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID4_QCNT GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID5_QCNT GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID6_QCNT GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID7_QCNT GENMASK(11, 0)
++
++#define MTK_WED_MON_AMSDU_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4)
++#define MTK_WED_AMSDU_QMEM_FQ_HEAD GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_SP_QHEAD GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID0_QHEAD GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID1_QHEAD GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID2_QHEAD GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID3_QHEAD GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID4_QHEAD GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID5_QHEAD GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID6_QHEAD GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID7_QHEAD GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_FQ_TAIL GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_SP_QTAIL GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID0_QTAIL GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID1_QTAIL GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID2_QTAIL GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID3_QTAIL GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID4_QTAIL GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID5_QTAIL GENMASK(11, 0)
++#define MTK_WED_AMSDU_QMEM_TID6_QTAIL GENMASK(27, 16)
++#define MTK_WED_AMSDU_QMEM_TID7_QTAIL GENMASK(11, 0)
++
++#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4)
++
++#define MTK_WED_PCIE_BASE 0x11280000
++
++#define MTK_WED_PCIE_BASE0 0x11300000
++#define MTK_WED_PCIE_BASE1 0x11310000
++#define MTK_WED_PCIE_BASE2 0x11290000
+ #endif
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index b2abebe..a9e455d 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -880,6 +880,13 @@ struct net_device_path {
+ u8 queue;
+ u16 wcid;
+ u8 bss;
++ u32 usr_info;
++ u8 tid;
++ u8 is_fixedrate;
++ u8 is_prior;
++ u8 is_sp;
++ u8 hf;
++ u8 amsdu;
+ } mtk_wdma;
+ };
+ };
+diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
+index 470beb2..e81e41f 100644
+--- a/include/linux/soc/mediatek/mtk_wed.h
++++ b/include/linux/soc/mediatek/mtk_wed.h
+@@ -5,9 +5,12 @@
+ #include <linux/rcupdate.h>
+ #include <linux/regmap.h>
+ #include <linux/pci.h>
++#include <linux/skbuff.h>
++#include <linux/iopoll.h>
+
+ #define MTK_WED_TX_QUEUES 2
+ #define MTK_WED_RX_QUEUES 2
++#define MTK_WED_RX_PAGE_QUEUES 3
+
+ #define WED_WO_STA_REC 0x6
+
+@@ -43,7 +46,7 @@ enum mtk_wed_wo_cmd {
+ MTK_WED_WO_CMD_WED_END
+ };
+
+-struct mtk_rxbm_desc {
++struct mtk_wed_bm_desc {
+ __le32 buf0;
+ __le32 token;
+ } __packed __aligned(4);
+@@ -74,6 +77,11 @@ struct mtk_wed_wo_rx_stats {
+ __le32 rx_drop_cnt;
+ };
+
++struct mtk_wed_buf {
++ void *p;
++ dma_addr_t phy_addr;
++};
++
+ struct mtk_wed_device {
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ const struct mtk_wed_ops *ops;
+@@ -92,10 +100,13 @@ struct mtk_wed_device {
+ struct mtk_wed_ring txfree_ring;
+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES];
+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
++ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES];
++ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES];
++ struct mtk_wed_ring ind_cmd_ring;
+
+ struct {
+ int size;
+- void **pages;
++ struct mtk_wed_buf *pages;
+ struct mtk_wdma_desc *desc;
+ dma_addr_t desc_phys;
+ } tx_buf_ring;
+@@ -103,7 +114,7 @@ struct mtk_wed_device {
+ struct {
+ int size;
+ struct page_frag_cache rx_page;
+- struct mtk_rxbm_desc *desc;
++ struct mtk_wed_bm_desc *desc;
+ dma_addr_t desc_phys;
+ } rx_buf_ring;
+
+@@ -114,6 +125,13 @@ struct mtk_wed_device {
+ dma_addr_t fdbk_phys;
+ } rro;
+
++ struct {
++ int size;
++ struct mtk_wed_buf *pages;
++ struct mtk_wed_bm_desc *desc;
++ dma_addr_t desc_phys;
++ } hw_rro;
++
+ /* filled by driver: */
+ struct {
+ union {
+@@ -123,6 +141,7 @@ struct mtk_wed_device {
+ enum mtk_wed_bus_tye bus_type;
+ void __iomem *base;
+ u32 phy_base;
++ u32 id;
+
+ u32 wpdma_phys;
+ u32 wpdma_int;
+@@ -130,10 +149,14 @@ struct mtk_wed_device {
+ u32 wpdma_tx;
+ u32 wpdma_txfree;
+ u32 wpdma_rx_glo;
+- u32 wpdma_rx;
++ u32 wpdma_rx[MTK_WED_RX_QUEUES];
++ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
++ u32 wpdma_rx_pg;
+
+ u8 tx_tbit[MTK_WED_TX_QUEUES];
+ u8 rx_tbit[MTK_WED_RX_QUEUES];
++ u8 rro_rx_tbit[MTK_WED_RX_QUEUES];
++ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES];
+ u8 txfree_tbit;
+
+ u16 token_start;
+@@ -141,8 +164,22 @@ struct mtk_wed_device {
+ unsigned int rx_nbuf;
+ unsigned int rx_npkt;
+ unsigned int rx_size;
++ unsigned int amsdu_max_len;
+
+ bool wcid_512;
++ bool hw_rro;
++ bool msi;
++
++ u8 amsdu_max_subframes;
++
++ struct {
++ u8 se_group_nums;
++ u16 win_size;
++ u16 particular_sid;
++ u32 ack_sn_addr;
++ dma_addr_t particular_se_phys;
++ dma_addr_t addr_elem_phys[1024];
++ } ind_cmd;
+
+ u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
+ int (*offload_enable)(struct mtk_wed_device *wed);
+@@ -185,6 +222,13 @@ struct mtk_wed_ops {
+
+ u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
+ void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
++ void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask);
++ void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
++ void __iomem *regs);
++ void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
++ void __iomem *regs);
++ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev,
++ void __iomem *regs);
+ };
+
+ extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
+@@ -213,12 +257,25 @@ static inline bool
+ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+ {
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
++ if (dev->version == 3)
++ return dev->wlan.hw_rro;
++
+ return dev->version != 1;
+ #else
+ return false;
+ #endif
+ }
+
++static inline bool
++mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev)
++{
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++ return dev->version == 3;
++#else
++ return false;
++#endif
++}
++
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ #define mtk_wed_device_active(_dev) !!(_dev)->ops
+ #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
+@@ -245,6 +302,14 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+ #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
+ #define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) \
+ (_dev)->ops->setup_tc(_dev, _ndev, _type, _data)
++#define mtk_wed_device_start_hw_rro(_dev, _mask) \
++ (_dev)->ops->start_hw_rro(_dev, _mask)
++#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
++ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
++#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
++ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs)
++#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \
++ (_dev)->ops->ind_rx_ring_setup(_dev, _regs)
+ #else
+ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ {
+@@ -264,6 +329,10 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ #define mtk_wed_device_stop(_dev) do {} while (0)
+ #define mtk_wed_device_dma_reset(_dev) do {} while (0)
+ #define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) do {} while (0)
++#define mtk_wed_device_start_hw_rro(_dev, _mask) do {} while (0)
++#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
++#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
++#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
+ #endif
+
+ #endif
+--
+2.18.0
+
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3020-mtk-wed-add-wed3-ser-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3020-mtk-wed-add-wed3-ser-support.patch
new file mode 100644
index 0000000..9778202
--- /dev/null
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3020-mtk-wed-add-wed3-ser-support.patch
@@ -0,0 +1,705 @@
+From 11f1e7684e9cadd83038694396ebd99792cff590 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Mon, 18 Sep 2023 13:22:44 +0800
+Subject: [PATCH 20/24] mtk wed add wed3 ser support
+
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 340 ++++++++++++++++---
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 68 +++-
+ include/linux/soc/mediatek/mtk_wed.h | 8 +-
+ 3 files changed, 368 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 2fed493..7f14d43 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -110,24 +110,88 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)
+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
+ }
+
+-static u32
+-mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++static void
++mtk_wdma_v3_rx_reset(struct mtk_wed_device *dev)
+ {
+- if (wed_r32(dev, reg) & mask)
+- return true;
+-
+- return false;
+-}
++ u32 status;
+
+-static int
+-mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
+-{
+- int sleep = 1000;
+- int timeout = 100 * sleep;
+- u32 val;
++ if (!mtk_wed_is_v3_or_greater(dev->hw))
++ return;
+
+- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
+- timeout, false, dev, reg, mask);
++ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG))
++ dev_err(dev->hw->dev, "rx reset failed\n");
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG))
++ dev_err(dev->hw->dev, "rx reset failed\n");
++
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG))
++ dev_err(dev->hw->dev, "rx reset failed\n");
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG))
++ dev_err(dev->hw->dev, "rx reset failed\n");
++
++ /* prefetch FIFO */
++ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
++
++ /* core FIFO */
++ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG,
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
++ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG,
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
++
++ /* writeback FIFO */
++ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0),
++ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1),
++ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0),
++ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1),
++ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++
++ /* prefetch ring status */
++ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG,
++ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG,
++ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
++
++ /* writeback ring status */
++ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG,
++ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG,
++ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
+ }
+
+ static int
+@@ -142,6 +206,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+ if (ret)
+ dev_err(dev->hw->dev, "rx reset failed \n");
+
++ mtk_wdma_v3_rx_reset(dev);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+
+@@ -156,6 +221,101 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+ return ret;
+ }
+
++static u32
++mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++{
++ return !!(wed_r32(dev, reg) & mask);
++}
++
++static int
++mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++{
++ int sleep = 15000;
++ int timeout = 100 * sleep;
++ u32 val;
++
++ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
++ timeout, false, dev, reg, mask);
++}
++
++static void
++mtk_wdma_v3_tx_reset(struct mtk_wed_device *dev)
++{
++ u32 status;
++
++ if (!mtk_wed_is_v3_or_greater(dev->hw))
++ return;
++
++ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG))
++ dev_err(dev->hw->dev, "tx reset failed\n");
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG))
++ dev_err(dev->hw->dev, "tx reset failed\n");
++
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG))
++ dev_err(dev->hw->dev, "tx reset failed\n");
++
++ if (read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY),
++ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG))
++ dev_err(dev->hw->dev, "tx reset failed\n");
++
++ /* prefetch FIFO */
++ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
++
++ /* core FIFO */
++ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG,
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
++ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG,
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
++
++ /* writeback FIFO */
++ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0),
++ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1),
++ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0),
++ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1),
++ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++
++ /* prefetch ring status */
++ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG,
++ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG,
++ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
++
++ /* writeback ring status */
++ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG,
++ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG,
++ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
++}
++
+ static void
+ mtk_wdma_tx_reset(struct mtk_wed_device *dev)
+ {
+@@ -167,6 +327,7 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev)
+ !(status & mask), 0, 10000))
+ dev_err(dev->hw->dev, "tx reset failed \n");
+
++ mtk_wdma_v3_tx_reset(dev);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+
+@@ -1402,25 +1563,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx)
+ }
+ }
+
+-static u32
+-mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
+-{
+- if (wed_r32(dev, reg) & mask)
+- return true;
+-
+- return false;
+-}
+-
+-static int
+-mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
+-{
+- int sleep = 1000;
+- int timeout = 100 * sleep;
+- u32 val;
+-
+- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
+- timeout, false, dev, reg, mask);
+-}
+
+ static int
+ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+@@ -1436,13 +1578,32 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ if (ret)
+ return ret;
+
++ if (dev->wlan.hw_rro) {
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS,
++ MTK_WED_RX_IND_CMD_BUSY);
++ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG);
++ }
++
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
++ if (!ret && mtk_wed_is_v3_or_greater(dev->hw))
++ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_BUSY);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
+ } else {
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ /*1.a. Disable Prefetch HW*/
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, MTK_WED_WPDMA_RX_D_PREF_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_BUSY);
++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
++ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL);
++ }
++
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
+@@ -1470,15 +1631,36 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
+ }
+
++ if (dev->wlan.hw_rro) {
++ /* Disable RRO MSDU Page Drv */
++ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
++
++ /* Disable RRO Data Drv */
++ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
++
++ /* RRO MSDU Page Drv Reset */
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
++ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
++ MTK_WED_RRO_MSDU_PG_DRV_CLR);
++
++ /* RRO Data Drv Reset */
++ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_CLR);
++ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2),
++ MTK_WED_RRO_RX_D_DRV_CLR);
++ }
++
+ /* reset route qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
++ } else if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ wed_set(dev, MTK_WED_RTQM_RST, BIT(0));
++ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0));
++ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
+ } else {
+- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
+- MTK_WED_RTQM_Q_RST);
++ wed_set(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
+ }
+
+ /* reset tx wdma */
+@@ -1486,8 +1668,12 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+
+ /* reset tx wdma drv */
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
+- mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
++ if (mtk_wed_is_v3_or_greater(dev->hw))
++ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS,
++ MTK_WED_WPDMA_STATUS_TX_DRV);
++ else
++ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
++ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
+
+ /* reset wed rx dma */
+@@ -1508,6 +1694,14 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ MTK_WED_CTRL_WED_RX_BM_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
+
++ if (dev->wlan.hw_rro) {
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
++ MTK_WED_CTRL_WED_RX_PG_BM_BUSY);
++ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
++ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
++ }
++
+ /* wo change to enable state */
+ val = WO_STATE_ENABLE;
+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
+@@ -1527,6 +1721,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ }
+
+ mtk_wed_free_rx_buffer(dev);
++ mtk_wed_hwrro_free_buffer(dev);
+
+ return 0;
+ }
+@@ -1562,16 +1757,55 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+
+ /* 2. Reset WDMA Rx DMA/Driver_Engine */
+ busy = !!mtk_wdma_rx_reset(dev);
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ val = MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE |
++ wed_r32(dev, MTK_WED_WDMA_GLO_CFG);
++ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN;
++ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val);
++ } else {
++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
++ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
++ }
+
+- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+ if (!busy)
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
++ if (!busy && mtk_wed_is_v3_or_greater(dev->hw))
++ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_BUSY);
+
+ if (busy) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
+ } else {
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ /*1.a. Disable Prefetch HW*/
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_BUSY);
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
++
++ /* reset prefetch index */
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
++
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
++
++ /* reset prefetch FIFO */
++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
++ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
++ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
++
++ /*2. Reset dma index*/
++ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
++ MTK_WED_WDMA_RESET_IDX_RX_ALL);
++ }
+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
+ MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV);
+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0);
+@@ -1587,8 +1821,13 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+ for (i = 0; i < 100; i++) {
+- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
+- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
++ if (mtk_wed_is_v1(dev->hw))
++ val = FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP,
++ wed_r32(dev, MTK_WED_TX_BM_INTF));
++ else
++ val = FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP,
++ wed_r32(dev, MTK_WED_TX_TKID_INTF));
++ if (val == 0x40)
+ break;
+ }
+
+@@ -1612,6 +1851,8 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV);
++ if (mtk_wed_is_v3_or_greater(dev->hw))
++ wed_w32(dev, MTK_WED_RX1_CTRL2, 0);
+ } else {
+ wed_w32(dev, MTK_WED_WPDMA_RESET_IDX,
+ MTK_WED_WPDMA_RESET_IDX_TX |
+@@ -1628,7 +1869,14 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+- mtk_wed_rx_reset(dev);
++ if (mtk_wed_is_v3_or_greater(dev->hw)) {
++ /* reset amsdu engine */
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN);
++ mtk_wed_reset(dev, MTK_WED_RESET_TX_AMSDU);
++ }
++
++ if (mtk_wed_get_rx_capa(dev))
++ mtk_wed_rx_reset(dev);
+ }
+
+ static int
+@@ -1945,7 +2193,7 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
+ }
+
+ static void
+-mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask)
++mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask, bool reset)
+ {
+ int i;
+
+@@ -1955,6 +2203,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask)
+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro)
+ return;
+
++ if (reset) {
++ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
++ MTK_WED_RRO_MSDU_PG_DRV_EN);
++ return;
++ }
++
+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
+ MTK_WED_RRO_MSDU_PG_DRV_CLR);
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+index 0af264d..1ee0fe1 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+@@ -36,6 +36,8 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RESET 0x008
+ #define MTK_WED_RESET_TX_BM BIT(0)
+ #define MTK_WED_RESET_RX_BM BIT(1)
++#define MTK_WED_RESET_RX_PG_BM BIT(2)
++#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3)
+ #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
+ #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
+ #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
+@@ -58,7 +60,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
+ #define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
+ #define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
+-#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7)
++#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7)
+ #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
+ #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
+ #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
+@@ -117,6 +119,10 @@ struct mtk_wdma_desc {
+ #define MTK_WED_STATUS 0x060
+ #define MTK_WED_STATUS_TX GENMASK(15, 8)
+
++#define MTK_WED_WPDMA_STATUS 0x068
++#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8)
++
++
+ #define MTK_WED_TX_BM_CTRL 0x080
+ #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
+ #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
+@@ -154,6 +160,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0)
+ #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16)
+
++#define MTK_WED_TX_TKID_INTF 0x0dc
++#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16)
++
+ #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)
+@@ -205,6 +214,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
+
+ #define MTK_WED_SCR0 0x3c0
++#define MTK_WED_RX1_CTRL2 0x418
+ #define MTK_WED_WPDMA_INT_TRIGGER 0x504
+ #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
+ #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
+@@ -320,6 +330,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
+ #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
++#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20)
+ #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
+
+ #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
+@@ -336,6 +347,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
+ #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
++#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1)
+ #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
+ #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
+
+@@ -357,11 +369,13 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WDMA_RX_PREF_CFG 0x950
+ #define MTK_WED_WDMA_RX_PREF_EN BIT(0)
++#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1)
+ #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
+ #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
+ #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
+ #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
+ #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
++#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27)
+
+ #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
+ #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
+@@ -390,6 +404,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WDMA_RESET_IDX 0xa08
+ #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
++#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20)
+ #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
+
+ #define MTK_WED_WDMA_INT_CLR 0xa24
+@@ -458,21 +473,66 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30)
+ #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31)
+
++#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0)
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4)
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8)
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12)
++
++#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21)
++
++
++
+ #define MTK_WDMA_INT_GRP1 0x250
+ #define MTK_WDMA_INT_GRP2 0x254
+
+ #define MTK_WDMA_PREF_TX_CFG 0x2d0
+ #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
++#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1)
+
+ #define MTK_WDMA_PREF_RX_CFG 0x2dc
+ #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
++#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1)
++
++#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0
++#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0)
++#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16)
++
++#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4
++#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0)
++#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16)
++
++#define MTK_WDMA_PREF_SIDX_CFG 0x2e4
++#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
++#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
+
+ #define MTK_WDMA_WRBK_TX_CFG 0x300
++#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0)
+ #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
+
++#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4)
++#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0)
++
++
+ #define MTK_WDMA_WRBK_RX_CFG 0x344
++#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0)
+ #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
+
++#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4)
++#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0)
++
++
++#define MTK_WDMA_WRBK_SIDX_CFG 0x388
++#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
++#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
++
+ #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
+ #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
+ #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
+@@ -486,6 +546,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
+ #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
+
++#define MTK_WED_RTQM_RST 0xb04
++
++
+ #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
+ #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
+ #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
+@@ -675,6 +738,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
+ #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
+
++#define MTK_WED_RRO_RX_HW_STS 0xf00
++#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0)
++
+ #define MTK_WED_RX_IND_CMD_CNT0 0xf20
+ #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
+
+diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
+index e81e41f..83a4b8b 100644
+--- a/include/linux/soc/mediatek/mtk_wed.h
++++ b/include/linux/soc/mediatek/mtk_wed.h
+@@ -222,7 +222,7 @@ struct mtk_wed_ops {
+
+ u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
+ void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
+- void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask);
++ void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask, bool reset);
+ void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
+ void __iomem *regs);
+ void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
+@@ -302,8 +302,8 @@ mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev)
+ #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
+ #define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) \
+ (_dev)->ops->setup_tc(_dev, _ndev, _type, _data)
+-#define mtk_wed_device_start_hw_rro(_dev, _mask) \
+- (_dev)->ops->start_hw_rro(_dev, _mask)
++#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) \
++ (_dev)->ops->start_hw_rro(_dev, _mask, _reset)
+ #define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
+ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
+ #define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
+@@ -329,7 +329,7 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ #define mtk_wed_device_stop(_dev) do {} while (0)
+ #define mtk_wed_device_dma_reset(_dev) do {} while (0)
+ #define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) do {} while (0)
+-#define mtk_wed_device_start_hw_rro(_dev, _mask) do {} while (0)
++#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) do {} while (0)
+ #define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
+ #define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
+ #define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
+--
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
similarity index 78%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
rename to autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
index af32459..0d0ac4e 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3021-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch
@@ -1,7 +1,7 @@
-From 659d8d088ee856cbc7598a26a307fd3e20a70e8e Mon Sep 17 00:00:00 2001
+From a0aa9757876b525b24a16bd3cb48b5dac02a8945 Mon Sep 17 00:00:00 2001
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Mon, 18 Sep 2023 13:23:56 +0800
-Subject: [PATCH 22/22] mtk: wed: add dma mask limitation and GFP_DMA32 for
+Subject: [PATCH 21/24] mtk: wed: add dma mask limitation and GFP_DMA32 for
board >= 4GB dram
---
@@ -12,10 +12,10 @@
4 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
-index 0d101d5..2ec7148 100644
+index 7f14d43..b928ff6 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -472,7 +472,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+@@ -638,7 +638,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
void *buf;
int s;
@@ -24,7 +24,7 @@
if (!page)
return -ENOMEM;
-@@ -636,7 +636,7 @@ mtk_wed_rx_page_buffer_alloc(struct mtk_wed_device *dev)
+@@ -762,7 +762,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev)
void *buf;
int s;
@@ -33,22 +33,22 @@
if (!page)
return -ENOMEM;
-@@ -2249,6 +2249,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
- dev->wdma_idx = hw->index;
- dev->ver = hw->version;
+@@ -2464,6 +2464,10 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ dev->version = hw->version;
+ dev->hw->pci_base = mtk_wed_get_pci_base(dev);
+ ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
- if (dev->hw->version == 3)
- dev->hw->pci_base = mtk_wed_get_pci_base(dev);
-
+ if (hw->eth->dma_dev == hw->eth->dev &&
+ of_dma_is_coherent(hw->eth->dev->of_node))
+ mtk_eth_set_dma_device(hw->eth, hw->dev);
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-index 055594d..4ed1548 100644
+index 18d1fb1..a88061c 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -131,7 +131,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo)
+@@ -145,7 +145,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo)
}req;
exp->log_size = EXCEPTION_LOG_SIZE;
@@ -57,7 +57,7 @@
if (!exp->log)
return -ENOMEM;
-@@ -151,7 +151,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo)
+@@ -165,7 +165,7 @@ int mtk_wed_exception_init(struct mtk_wed_wo *wo)
&req, sizeof(req), false);
free:
@@ -89,7 +89,7 @@
wo->hw = NULL;
diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.h b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-index 548b38e..3fd1f3f 100644
+index b24fef3..5afa6de 100644
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
@@ -193,6 +193,7 @@ struct mtk_wed_wo {
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3022-mediatek-ethernet-add-multiple-ppe-allocation.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3022-mediatek-ethernet-add-multiple-ppe-allocati.patch
similarity index 83%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3022-mediatek-ethernet-add-multiple-ppe-allocation.patch
rename to autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3022-mediatek-ethernet-add-multiple-ppe-allocati.patch
index cd6c8ca..15d51b9 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3022-mediatek-ethernet-add-multiple-ppe-allocation.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3022-mediatek-ethernet-add-multiple-ppe-allocati.patch
@@ -1,7 +1,8 @@
-From f80b9b330efd9d675c7c548c5af459792037ca99 Mon Sep 17 00:00:00 2001
+From d73ee12c93d4146b3585fc5d93271b1fbafcd3c4 Mon Sep 17 00:00:00 2001
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
Date: Tue, 26 Dec 2023 16:46:16 +0800
-Subject: [PATCH] 999-3022-mediatek-ethernet-add-multiple-ppe-allocatiion.patch
+Subject: [PATCH 22/24]
+ 999-3022-mediatek-ethernet-add-multiple-ppe-allocatiion.patch
---
arch/arm64/boot/dts/mediatek/mt7988.dtsi | 1 +
@@ -11,10 +12,10 @@
4 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
-index 44a2f1b..cf50542 100644
+index 3368240..ff1619d 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
-@@ -949,6 +949,7 @@
+@@ -945,6 +945,7 @@
mediatek,infracfg = <&topmisc>;
mediatek,toprgu = <&watchdog>;
mediatek,hwver = <&hwver>;
@@ -23,10 +24,10 @@
#address-cells = <1>;
#size-cells = <0>;
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-index 4cdfead..9009960 100644
+index a3ed175..a761d95 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2170,6 +2170,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2349,6 +2349,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
u8 *data, *new_data;
struct mtk_rx_dma_v2 *rxd, trxd;
int done = 0;
@@ -34,7 +35,7 @@
if (unlikely(!ring))
goto rx_done;
-@@ -2277,7 +2278,8 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
+@@ -2460,7 +2461,8 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
#if defined(CONFIG_MEDIATEK_NETSYS_RX_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON_V2, trxd.rxd5);
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) {
@@ -44,7 +45,7 @@
trxd.rxd5 & MTK_RXD5_FOE_ENTRY_V2);
}
#else
-@@ -3781,7 +3783,19 @@ static int mtk_open(struct net_device *dev)
+@@ -4114,7 +4116,19 @@ static int mtk_open(struct net_device *dev)
SGMSYS_QPHY_PWR_STATE_CTRL, 0);
if (eth->soc->offload_version) {
@@ -65,7 +66,7 @@
for (i = 0; i < eth->ppe_num; i++)
mtk_ppe_start(eth->ppe[i]);
-@@ -4748,6 +4762,7 @@ static const struct net_device_ops mtk_netdev_ops = {
+@@ -5130,6 +5144,7 @@ static const struct net_device_ops mtk_netdev_ops = {
.ndo_poll_controller = mtk_poll_controller,
#endif
.ndo_setup_tc = mtk_eth_setup_tc,
@@ -74,10 +75,10 @@
static void mux_poll(struct work_struct *work)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-index 12ffb3c..1bf335c 100644
+index 88d2f46..711a8e9 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1945,6 +1945,7 @@ struct mtk_mac {
+@@ -1973,6 +1973,7 @@ struct mtk_mac {
phy_interface_t interface;
unsigned int mode;
unsigned int type;
@@ -85,7 +86,7 @@
int speed;
struct device_node *of_node;
struct phylink *phylink;
-@@ -2045,6 +2046,8 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
+@@ -2074,6 +2075,8 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data);
int mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f,
struct mtk_eth *eth);
@@ -95,10 +96,10 @@
u32 mtk_rss_indr_table(struct mtk_rss_params *rss_params, int index);
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-index 339359e..8f721ba 100644
+index 2d432f2..7f432be 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -693,6 +693,16 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
+@@ -694,6 +694,16 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
}
}
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3024-mtk-ppe-dispatch-short-packets-to-high-priority-TXQ-in-PPPQ.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3023-mtk-ppe-dispatch-short-packets-to-high-prio.patch
similarity index 88%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3024-mtk-ppe-dispatch-short-packets-to-high-priority-TXQ-in-PPPQ.patch
rename to autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3023-mtk-ppe-dispatch-short-packets-to-high-prio.patch
index 31d8b89..92591a5 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3024-mtk-ppe-dispatch-short-packets-to-high-priority-TXQ-in-PPPQ.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3023-mtk-ppe-dispatch-short-packets-to-high-prio.patch
@@ -1,14 +1,15 @@
-From 8306aa4c52abf96af2c229762207369f279c89e2 Mon Sep 17 00:00:00 2001
+From e8a6054c824c5c65abd501bfd7437a3d7c5f2751 Mon Sep 17 00:00:00 2001
From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
Date: Tue, 28 Nov 2023 13:25:03 +0800
-Subject: [PATCH] 999-3024-mtk-ppe-dispatch-short-packets-to-high-priority-TXQ-in-PPPQ
+Subject: [PATCH 23/24]
+ mtk-ppe-dispatch-short-packets-to-high-priority-TXQ-in-PPPQ
---
drivers/net/ethernet/mediatek/mtk_ppe.c | 27 +++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
-index 16aec2e..1e2b96e 100644
+index ae0acd5..84d9763 100644
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -451,6 +451,28 @@ int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid)
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3025-dts-88d-option-type-2-support.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3024-dts-88d-option-type-2-support.patch
similarity index 83%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3025-dts-88d-option-type-2-support.patch
rename to autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3024-dts-88d-option-type-2-support.patch
index 9084982..9125b94 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/target/linux/mediatek/patches-5.4/999-3025-dts-88d-option-type-2-support.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/999-3024-dts-88d-option-type-2-support.patch
@@ -1,7 +1,7 @@
-From a344727c9d91c162839e7283aeac281f88f30e8a Mon Sep 17 00:00:00 2001
+From b294202119468041b6f4b6651f968c9d2a0adcc2 Mon Sep 17 00:00:00 2001
From: Rex Lu <rex.lu@mediatek.com>
Date: Mon, 22 Jan 2024 13:50:29 +0800
-Subject: [PATCH] dts 88d option type 2 support
+Subject: [PATCH 24/24] dts 88d option type 2 support
Signed-off-by: Rex Lu <rex.lu@mediatek.com>
---
@@ -10,10 +10,10 @@
2 files changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts b/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
-index 5513d04..7619009 100644
+index 8ebcbaf..df15051 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
-@@ -569,6 +569,7 @@
+@@ -572,6 +572,7 @@
mt7996@0,0 {
reg = <0x0000 0 0 0 0>;
device_type = "pci";
@@ -22,10 +22,10 @@
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
-index 4cab1ae..b98efb9 100644
+index d4f96c8..c27ffa6 100644
--- a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
-@@ -546,6 +546,7 @@
+@@ -547,6 +547,7 @@
mt7996@0,0 {
reg = <0x0000 0 0 0 0>;
device_type = "pci";