[rdkb][common][bsp][Refactor and sync wifi from openwrt]

[Description]
535edd63 [MAC80211][mt76][update debug patch]
326a55a3 [MAC80211][Rebase Patches][mt76 build fail]
bb5dace6 [MAC80211][wed][fix ind cmd int fail after ser]
d5ecd7f9 [mac80211][mt76][Fix WFDMA setting]
cbc895ac [MAC80211][misc][Fix condiction of check default bin]
1bc12c1f [MAC80211][misc][Add omcproxy package for IGMP feature]
dff3e670 [mac80211][Rebase][rebase to the latest codebase]
ffdcb6aa [MAC80211][Rebase Patches][update internal patches based on mt76-2023-06-22-29cfabbb]
136f0006 [MAC80211][hostapd][Add EDCCA BW_160 support]
c74da51a [MAC80211][misc][Fix mac address issues]

[Release-log]

Change-Id: I4fc2286827638fc5fa4b7a714c624ebf05f5e3d0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0041-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0041-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
new file mode 100644
index 0000000..f6e14b7
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0041-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
@@ -0,0 +1,135 @@
+From 78bc83a6a4dc69f135c6a32756e8acb96c64b1bf Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Tue, 13 Jun 2023 09:04:43 +0800
+Subject: [PATCH] wifi: mt76: mt7996: adjust wfdma setting to enhance
+ throughput
+
+1. Set band 1 traffic to pcie1.
+2. Refactor dma prefetch and enlarge txd prefetch size.
+3. Update pdma setting.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7996/dma.c  | 57 ++++++++++++++++++++++++++++++++++++++-------------
+ mt7996/regs.h |  9 ++++++++
+ 2 files changed, 52 insertions(+), 14 deletions(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index f01cea5e..bb390517 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -56,22 +56,34 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+ 	MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7996_TXQ_FWDL);
+ }
+ 
++static u32 __mt7996_dma_prefetch_base(u16 *base, u8 depth)
++{
++	u32 ret = *base << 16 | depth;
++
++	*base = *base + (depth << 4);
++
++	return ret;
++}
++
+ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
+ {
+-#define PREFETCH(_base, _depth)	((_base) << 16 | (_depth))
++	u16 base = 0;
++
++#define PREFETCH(_depth)	(__mt7996_dma_prefetch_base(&base, (_depth)))
+ 	/* prefetch SRAM wrapping boundary for tx/rx ring. */
+-	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x0, 0x2));
+-	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x20, 0x2));
+-	mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x40, 0x4));
+-	mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x80, 0x4));
+-	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0xc0, 0x2));
+-	mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0xe0, 0x4));
+-	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x120, 0x2));
+-	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x140, 0x2));
+-	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x160, 0x2));
+-	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x180, 0x2));
+-	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10));
+-	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10));
++	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_FWDL) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WM) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_TXQ_EXT_CTRL(0) + ofs, PREFETCH(0x8));
++	mt76_wr(dev, MT_TXQ_EXT_CTRL(1) + ofs, PREFETCH(0x8));
++	mt76_wr(dev, MT_MCUQ_EXT_CTRL(MT_MCUQ_WA) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_TXQ_EXT_CTRL(2) + ofs, PREFETCH(0x8));
++	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MCU_WA) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN_WA) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x2));
++	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x10));
++	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x10));
++#undef PREFETCH
+ 
+ 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
+ }
+@@ -223,6 +235,12 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1,
+ 		 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
+ 
++	/* WFDMA rx threshold */
++	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_45_TH, 0xc000c);
++	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_67_TH, 0x10008);
++	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_89_TH, 0x10008);
++	mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_RRO_TH, 0x20);
++
+ 	if (dev->hif2) {
+ 		/* GLO_CFG_EXT0 */
+ 		mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
+@@ -234,7 +252,18 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 			 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
+ 
+ 		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
+-			 MT_WFDMA_HOST_CONFIG_PDMA_BAND);
++			 MT_WFDMA_HOST_CONFIG_PDMA_BAND |
++			 MT_WFDMA_HOST_CONFIG_BAND2_PCIE1);
++
++		/* AXI read outstanding number */
++		mt76_rmw(dev, MT_WFDMA_AXI_R2A_CTRL,
++			 MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK, 0x14);
++
++		/* WFDMA rx threshold */
++		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_45_TH + hif1_ofs, 0xc000c);
++		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_67_TH + hif1_ofs, 0x10008);
++		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_89_TH + hif1_ofs, 0x10008);
++		mt76_wr(dev, MT_WFDMA0_PAUSE_RX_Q_RRO_TH + hif1_ofs, 0x20);
+ 	}
+ 
+ 	if (dev->hif2) {
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 3a5914c4..5917ba1a 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -333,6 +333,11 @@ enum base_rev {
+ #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO		BIT(27)
+ #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
+ 
++#define MT_WFDMA0_PAUSE_RX_Q_45_TH		MT_WFDMA0(0x268)
++#define MT_WFDMA0_PAUSE_RX_Q_67_TH		MT_WFDMA0(0x26c)
++#define MT_WFDMA0_PAUSE_RX_Q_89_TH		MT_WFDMA0(0x270)
++#define MT_WFDMA0_PAUSE_RX_Q_RRO_TH		MT_WFDMA0(0x27c)
++
+ #define WF_WFDMA0_GLO_CFG_EXT0			MT_WFDMA0(0x2b0)
+ #define WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD	BIT(18)
+ #define WF_WFDMA0_GLO_CFG_EXT0_WED_MERGE_MODE	BIT(14)
+@@ -355,10 +360,14 @@ enum base_rev {
+ 
+ #define MT_WFDMA_HOST_CONFIG			MT_WFDMA_EXT_CSR(0x30)
+ #define MT_WFDMA_HOST_CONFIG_PDMA_BAND		BIT(0)
++#define MT_WFDMA_HOST_CONFIG_BAND2_PCIE1	BIT(22)
+ 
+ #define MT_WFDMA_EXT_CSR_HIF_MISC		MT_WFDMA_EXT_CSR(0x44)
+ #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY		BIT(0)
+ 
++#define MT_WFDMA_AXI_R2A_CTRL			MT_WFDMA_EXT_CSR(0x500)
++#define MT_WFDMA_AXI_R2A_CTRL_OUTSTAND_MASK	GENMASK(4, 0)
++
+ #define MT_PCIE_RECOG_ID			0xd7090
+ #define MT_PCIE_RECOG_ID_MASK			GENMASK(30, 0)
+ #define MT_PCIE_RECOG_ID_SEM			BIT(31)
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
index 7179a65..fcc450e 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
@@ -1,21 +1,21 @@
-From e7b3aa46df08dc89f0ed30c36d56ee4acf50d982 Mon Sep 17 00:00:00 2001
+From 16ea1c12d369ea1f315edcc7a8525efc6d78403a Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Fri, 24 Mar 2023 14:02:32 +0800
-Subject: [PATCH 1000/1015] wifi: mt76: mt7996: add debug tool
+Subject: [PATCH] wifi: mt76: mt7996: add debug tool
 
 Change-Id: Ie10390b01f17db893dbfbf3221bf63a4bd1fe38f
 ---
  mt7996/Makefile      |    3 +
  mt7996/coredump.c    |   10 +-
  mt7996/coredump.h    |    7 +
- mt7996/debugfs.c     |   29 +-
+ mt7996/debugfs.c     |   24 +-
  mt7996/mt7996.h      |   14 +
  mt7996/mtk_debug.h   | 2165 ++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_debugfs.c | 2353 ++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     |   18 +
  mt7996/mtk_mcu.h     |   16 +
  tools/fwlog.c        |   25 +-
- 10 files changed, 4622 insertions(+), 18 deletions(-)
+ 10 files changed, 4617 insertions(+), 18 deletions(-)
  create mode 100644 mt7996/mtk_debug.h
  create mode 100644 mt7996/mtk_debugfs.c
  create mode 100644 mt7996/mtk_mcu.c
@@ -113,7 +113,7 @@
  mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
  {
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index ca4d615d..8a513f46 100644
+index ca4d615d..93581fef 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
 @@ -301,6 +301,9 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
@@ -126,7 +126,7 @@
  
  	if (dev->fw_debug_bin)
  		val = MCU_FW_LOG_RELAY;
-@@ -407,16 +410,22 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
+@@ -407,11 +410,12 @@ mt7996_fw_debug_bin_set(void *data, u64 val)
  	};
  	struct mt7996_dev *dev = data;
  
@@ -142,17 +142,7 @@
  
  	dev->fw_debug_bin = val;
  
- 	relay_reset(dev->relay_fwlog);
- 
-+	if (dev->relay_fwlog && !val) {
-+		relay_close(dev->relay_fwlog);
-+		dev->relay_fwlog = NULL;
-+	}
-+
- 	return mt7996_fw_debug_wm_set(dev, dev->fw_debug_wm);
- }
- 
-@@ -825,6 +834,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
+@@ -825,6 +829,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
  	if (phy == &dev->phy)
  		dev->debugfs_dir = dir;
  
@@ -164,7 +154,7 @@
  	return 0;
  }
  
-@@ -837,6 +851,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
+@@ -837,6 +846,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
  	void *dest;
  
  	spin_lock_irqsave(&lock, flags);
@@ -177,7 +167,7 @@
  	dest = relay_reserve(dev->relay_fwlog, hdrlen + len + 4);
  	if (dest) {
  		*(u32 *)dest = hdrlen + len;
-@@ -869,9 +889,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
+@@ -869,9 +884,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
  		.msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR),
  	};
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
index 8452177..9a003d7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
@@ -1,7 +1,7 @@
-From 0eaa67d2a2558d1366c25e18e43475907903dea4 Mon Sep 17 00:00:00 2001
+From 017ed7925cbdfb41d3d85fed54a97cff9fcf2f78 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Feb 2023 13:50:56 +0800
-Subject: [PATCH 2004/2008] wifi: mt76: mt7996: wed: add wed3.0 rx support
+Subject: [PATCH] wifi: mt76: mt7996: wed: add wed3.0 rx support
 
 add hardware rro support, This is the preliminary patch for WED3.0 support.
 
@@ -9,24 +9,24 @@
 Change-Id: I7e113b1392bcf085ec02c8a44ffbb7cf7c3fa027
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
- dma.c           | 197 +++++++++++++++++++++++++++++++++++++-----------
+ dma.c           | 205 +++++++++++++++++++++++++++++++++++++-----------
  dma.h           |  12 +++
  mac80211.c      |   1 +
- mt76.h          |  63 ++++++++++++++--
- mt7996/dma.c    | 163 +++++++++++++++++++++++++++++++++------
- mt7996/init.c   | 124 +++++++++++++++++++++++++++++-
- mt7996/mac.c    |  42 +++++++++--
+ mt76.h          |  63 +++++++++++++--
+ mt7996/dma.c    | 163 ++++++++++++++++++++++++++++++++------
+ mt7996/init.c   | 124 ++++++++++++++++++++++++++++-
+ mt7996/mac.c    |  42 ++++++++--
  mt7996/mcu.c    |   8 +-
  mt7996/mmio.c   |  36 +++++++--
  mt7996/mt7996.h |  58 ++++++++++++++
- mt7996/regs.h   |  63 +++++++++++++++-
- 11 files changed, 675 insertions(+), 92 deletions(-)
+ mt7996/regs.h   |  63 ++++++++++++++-
+ 11 files changed, 683 insertions(+), 92 deletions(-)
 
 diff --git a/dma.c b/dma.c
 index 930ec768..e5b4d898 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -193,46 +193,65 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
+@@ -193,46 +193,68 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
  static void
  mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
  {
@@ -81,10 +81,13 @@
  	u32 buf1 = 0, ctrl;
  	int idx = q->head;
  	int rx_token;
- 
-+	if (mt76_queue_is_rro_ind(q))
-+		goto done;
++	void *e_buf = data;
 +
++	if (mt76_queue_is_rro_ind(q)) {
++		e_buf = &q->rro_desc[q->head];
++		goto done;
++	}
+ 
 +	desc = &q->desc[q->head];
  	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
  
@@ -100,7 +103,7 @@
  
  		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
  		if (rx_token < 0) {
-@@ -249,6 +268,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -249,10 +271,11 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
  	WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
  	WRITE_ONCE(desc->info, 0);
  
@@ -108,7 +111,12 @@
  	entry->dma_addr[0] = buf->addr;
  	entry->dma_len[0] = buf->len;
  	entry->rxwi = rxwi;
-@@ -396,14 +416,15 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+-	entry->buf = data;
++	entry->buf = e_buf;
+ 	entry->wcid = 0xffff;
+ 	entry->skip_buf1 = true;
+ 	q->head = (q->head + 1) % q->ndesc;
+@@ -396,14 +419,18 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
  
  static void *
  mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
@@ -117,16 +125,20 @@
  {
  	struct mt76_queue_entry *e = &q->entry[idx];
  	struct mt76_desc *desc = &q->desc[idx];
- 	void *buf;
+-	void *buf;
++	void *buf = e->buf;
 +	u32 ctrl;
  
++	if (mt76_queue_is_rro_ind(q))
++		goto done;
++
 +	ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
  	if (len) {
 -		u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
  		*len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctrl);
  		*more = !(ctrl & MT_DMA_CTL_LAST_SEC0);
  	}
-@@ -411,6 +432,12 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -411,6 +438,12 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  	if (info)
  		*info = le32_to_cpu(desc->info);
  
@@ -139,7 +151,7 @@
  	if (mt76_queue_is_wed_rx(q)) {
  		u32 buf1 = le32_to_cpu(desc->buf1);
  		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
-@@ -423,20 +450,46 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -423,28 +456,54 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  				 SKB_WITH_OVERHEAD(q->buf_size),
  				 DMA_FROM_DEVICE);
  
@@ -196,18 +208,29 @@
  			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
 -		}
  	} else {
- 		buf = e->buf;
- 		e->buf = NULL;
-@@ -458,15 +511,20 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+-		buf = e->buf;
+-		e->buf = NULL;
+ 		dma_unmap_single(dev->dma_dev, e->dma_addr[0],
+ 				 SKB_WITH_OVERHEAD(q->buf_size),
+ 				 DMA_FROM_DEVICE);
+ 	}
+ 
++done:
++	e->buf = NULL;
+ 	return buf;
+ }
+ 
+@@ -458,15 +517,22 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
  	if (!q->queued)
  		return NULL;
  
 -	if (flush)
 -		q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
 -	else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
--		return NULL;
-+	if (q->flags & MT_QFLAG_RRO) {
++	if (mt76_queue_is_rro_ind(q)) {
 +		goto done;
++	} else if (q->flags & MT_QFLAG_RRO) {
+ 		return NULL;
 +	} else {
 +		if (flush)
 +			q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
@@ -224,7 +247,7 @@
  }
  
  static int
-@@ -615,7 +673,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -615,7 +681,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  
  	while (q->queued < q->ndesc - 1) {
  		struct mt76_queue_buf qbuf;
@@ -236,7 +259,7 @@
  
  		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
  		if (!buf)
-@@ -627,10 +688,11 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -627,10 +696,11 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  			break;
  		}
  
@@ -249,7 +272,7 @@
  			dma_unmap_single(dev->dma_dev, addr, len,
  					 DMA_FROM_DEVICE);
  			skb_free_frag(buf);
-@@ -639,7 +701,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -639,7 +709,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
  		frames++;
  	}
  
@@ -258,7 +281,7 @@
  		mt76_dma_kick_queue(dev, q);
  
  	spin_unlock_bh(&q->lock);
-@@ -652,7 +714,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -652,7 +722,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
  	struct mtk_wed_device *wed = &dev->mmio.wed;
  	int ret, type, ring;
@@ -267,7 +290,7 @@
  
  	if (!q || !q->ndesc)
  		return -EINVAL;
-@@ -679,7 +741,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -679,7 +749,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  	case MT76_WED_Q_TXFREE:
  		/* WED txfree queue needs ring to be initialized before setup */
  		q->flags = 0;
@@ -276,7 +299,7 @@
  		mt76_dma_rx_fill(dev, q);
  		q->flags = flags;
  
-@@ -688,9 +750,31 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -688,9 +758,31 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  			q->wed_regs = wed->txfree_ring.reg_base;
  		break;
  	case MT76_WED_Q_RX:
@@ -311,7 +334,7 @@
  		break;
  	default:
  		ret = -EINVAL;
-@@ -719,10 +803,25 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -719,10 +811,25 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	q->hw_idx = idx;
  
  	size = q->ndesc * sizeof(struct mt76_desc);
@@ -337,7 +360,7 @@
  	size = q->ndesc * sizeof(*q->entry);
  	q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
  	if (!q->entry)
-@@ -732,8 +831,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -732,8 +839,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	if (ret)
  		return ret;
  
@@ -351,24 +374,7 @@
  
  	return 0;
  }
-@@ -751,13 +853,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 	spin_lock_bh(&q->lock);
- 
- 	do {
-+		if (q->flags & MT_QFLAG_RRO)
-+			break;
-+
- 		buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more, NULL);
- 		if (!buf)
- 			break;
- 
--		if (q->flags & MT_QFLAG_RRO)
--			continue;
--
- 		skb_free_frag(buf);
- 	} while (1);
- 
-@@ -768,8 +870,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -768,8 +878,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  
  	spin_unlock_bh(&q->lock);
  
@@ -378,7 +384,7 @@
  	    (q->flags & MT_QFLAG_RRO))
  		return;
  
-@@ -790,9 +891,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -790,9 +899,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
  	if (!q->ndesc)
  		return;
  
@@ -392,7 +398,7 @@
  	mt76_dma_rx_cleanup(dev, q);
  
  	/* reset WED rx queues */
-@@ -839,8 +944,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -839,8 +952,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  	bool check_ddone = false;
  	bool more;
  
@@ -403,7 +409,7 @@
  		dma_idx = Q_READ(dev, q, dma_idx);
  		check_ddone = true;
  	}
-@@ -1002,7 +1107,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -1002,7 +1115,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  	mt76_for_each_q_rx(dev, i) {
  		struct mt76_queue *q = &dev->q_rx[i];
  
@@ -413,7 +419,7 @@
  			continue;
  
  		netif_napi_del(&dev->napi[i]);
-@@ -1014,6 +1120,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -1014,6 +1128,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  
  	if (mtk_wed_device_active(&dev->mmio.wed_ext))
  		mtk_wed_device_detach(&dev->mmio.wed_ext);
@@ -601,7 +607,7 @@
  
  	return token;
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 673b08bb..c5c7f160 100644
+index 428f3d08..45ccc7b5 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
 @@ -64,6 +64,29 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
@@ -634,30 +640,30 @@
  	/* data tx queue */
  	TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
  	TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
-@@ -91,6 +114,22 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x180, 0x2));
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10));
- 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10));
+@@ -102,6 +125,22 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
+ 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x2));
+ 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x10));
+ 	mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x10));
 +	if (dev->rro_support) {
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
-+			PREFETCH(0x3a0, 0x10));
++			PREFETCH(0x10));
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
-+			PREFETCH(0x4a0, 0x10));
++			PREFETCH(0x10));
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
-+			PREFETCH(0x5a0, 0x4));
++			PREFETCH(0x4));
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
-+			PREFETCH(0x5e0, 0x4));
++			PREFETCH(0x4));
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
-+			PREFETCH(0x620, 0x4));
++			PREFETCH(0x4));
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
-+			PREFETCH(0x660, 0x2));
++			PREFETCH(0x4));
 +		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
-+			PREFETCH(0x680, 0x2));
++			PREFETCH(0x4));
 +	}
+ #undef PREFETCH
  
  	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
- }
-@@ -149,6 +188,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
+@@ -161,6 +200,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
  
  void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
  {
@@ -665,7 +671,7 @@
  	u32 hif1_ofs = 0;
  	u32 irq_mask;
  
-@@ -157,11 +197,16 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+@@ -169,11 +209,16 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
  
  	/* enable wpdma tx/rx */
  	if (!reset) {
@@ -687,7 +693,7 @@
  
  		if (dev->hif2)
  			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-@@ -173,8 +218,8 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+@@ -185,8 +230,8 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
  
  	/* enable interrupts for TX/RX rings */
  	irq_mask = MT_INT_MCU_CMD |
@@ -698,7 +704,7 @@
  
  	if (mt7996_band_valid(dev, MT_BAND0))
  		irq_mask |= MT_INT_BAND0_RX_DONE;
-@@ -185,14 +230,14 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+@@ -197,14 +242,14 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
  	if (mt7996_band_valid(dev, MT_BAND2))
  		irq_mask |= MT_INT_BAND2_RX_DONE;
  
@@ -715,7 +721,7 @@
  	}
  
  	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-@@ -269,7 +314,8 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+@@ -298,7 +343,8 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
  		/* fix hardware limitation, pcie1's rx ring3 is not available
  		 * so, redirect pcie0 rx ring3 interrupt to pcie1
  		 */
@@ -725,7 +731,7 @@
  			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
  				 MT_WFDMA0_RX_INT_SEL_RING6);
  		else
-@@ -282,6 +328,78 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+@@ -311,6 +357,78 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
  	return 0;
  }
  
@@ -804,7 +810,7 @@
  int mt7996_dma_init(struct mt7996_dev *dev)
  {
  	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-@@ -351,6 +469,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -380,6 +498,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  		return ret;
  
  	/* rx data queue for band0 and band1 */
@@ -814,7 +820,7 @@
  	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
  			       MT_RXQ_ID(MT_RXQ_MAIN),
  			       MT7996_RX_RING_SIZE,
-@@ -374,9 +495,6 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -403,9 +524,6 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	if (mt7996_band_valid(dev, MT_BAND2)) {
  		/* rx data queue for band2 */
  		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
@@ -824,7 +830,7 @@
  		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
  				       MT_RXQ_ID(MT_RXQ_BAND2),
  				       MT7996_RX_RING_SIZE,
-@@ -400,11 +518,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -429,11 +547,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  			return ret;
  	}
  
@@ -839,7 +845,7 @@
  		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
  				       MT_RXQ_ID(MT_RXQ_RRO_BAND0),
  				       MT7996_RX_RING_SIZE,
-@@ -414,8 +533,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -443,8 +562,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  			return ret;
  
  		/* tx free notify event from WA for band0 */
@@ -849,7 +855,7 @@
  		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
  				       MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
  				       MT7996_RX_MCU_RING_SIZE,
-@@ -428,6 +546,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -457,6 +575,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  			/* rx rro data queue for band2 */
  			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags = MT_RRO_Q_DATA(1);
  			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_QFLAG_MAGIC;
@@ -857,7 +863,7 @@
  			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
  					       MT_RXQ_ID(MT_RXQ_RRO_BAND2),
  					       MT7996_RX_RING_SIZE,
-@@ -505,18 +624,18 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+@@ -534,18 +653,18 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
  
  	/* reset hw queues */
  	for (i = 0; i < __MT_TXQ_MAX; i++) {
@@ -1356,7 +1362,7 @@
  			 struct sk_buff *skb, u32 *info);
  bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 04658639..6624685e 100644
+index 5ed7bcca..47fa965f 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
 @@ -39,6 +39,40 @@ enum base_rev {
@@ -1400,7 +1406,7 @@
  #define MT_MCU_INT_EVENT			0x2108
  #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
  #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
-@@ -391,6 +425,7 @@ enum base_rev {
+@@ -400,6 +434,7 @@ enum base_rev {
  #define MT_MCUQ_RING_BASE(q)			(MT_Q_BASE(q) + 0x300)
  #define MT_TXQ_RING_BASE(q)			(MT_Q_BASE(__TXQ(q)) + 0x300)
  #define MT_RXQ_RING_BASE(q)			(MT_Q_BASE(__RXQ(q)) + 0x500)
@@ -1408,7 +1414,7 @@
  
  #define MT_MCUQ_EXT_CTRL(q)			(MT_Q_BASE(q) +	0x600 +	\
  						 MT_MCUQ_ID(q) * 0x4)
-@@ -418,6 +453,15 @@ enum base_rev {
+@@ -427,6 +462,15 @@ enum base_rev {
  #define MT_INT_MCU_CMD				BIT(29)
  #define MT_INT_RX_TXFREE_EXT			BIT(26)
  
@@ -1424,7 +1430,7 @@
  #define MT_INT_RX(q)				(dev->q_int_mask[__RXQ(q)])
  #define MT_INT_TX_MCU(q)			(dev->q_int_mask[(q)])
  
-@@ -425,20 +469,31 @@ enum base_rev {
+@@ -434,20 +478,31 @@ enum base_rev {
  						 MT_INT_RX(MT_RXQ_MCU_WA))
  
  #define MT_INT_BAND0_RX_DONE			(MT_INT_RX(MT_RXQ_MAIN) |	\
@@ -1461,5 +1467,5 @@
  #define MT_INT_TX_DONE_FWDL			BIT(26)
  #define MT_INT_TX_DONE_MCU_WM			BIT(27)
 -- 
-2.39.2
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
index 0d2134b..3d25c27 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
@@ -15,7 +15,7 @@
 index e5b4d898..e31f6390 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -770,8 +770,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -778,8 +778,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  				q->head = q->ndesc - 1;
  				q->queued = q->ndesc - 1;
  			}
@@ -26,7 +26,7 @@
  			if (!ret)
  				q->wed_regs = wed->rx_ring[ring].reg_base;
  		}
-@@ -902,7 +903,9 @@ done:
+@@ -910,7 +911,9 @@ done:
  
  	/* reset WED rx queues */
  	mt76_dma_wed_setup(dev, q, true);
@@ -41,7 +41,7 @@
 index c5c7f160..471ae81c 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -495,6 +495,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -524,6 +524,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	if (mt7996_band_valid(dev, MT_BAND2)) {
  		/* rx data queue for band2 */
  		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
@@ -54,7 +54,7 @@
  		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
  				       MT_RXQ_ID(MT_RXQ_BAND2),
  				       MT7996_RX_RING_SIZE,
-@@ -582,11 +588,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -611,11 +617,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	return 0;
  }
  
@@ -90,7 +90,7 @@
  	int i;
  
  	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
-@@ -620,21 +650,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+@@ -649,21 +679,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
  	if (force)
  		mt7996_wfsys_reset(dev);
  
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
index 3114ebf..dda4d93 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
@@ -37,6 +37,7 @@
     file://0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch \
     file://0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch \
     file://0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch \
+    file://0041-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch \
     file://0999-wifi-mt76-mt7996-for-build-pass.patch \
     file://1000-wifi-mt76-mt7996-add-debug-tool.patch \
     file://1001-wifi-mt76-mt7996-add-txpower-support.patch \
diff --git a/recipes-wifi/linux-mt76/files/patches/0000-sync-to-master-codebase.patch b/recipes-wifi/linux-mt76/files/patches/0000-sync-to-master-codebase.patch
new file mode 100644
index 0000000..1ee1534
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/0000-sync-to-master-codebase.patch
@@ -0,0 +1,5882 @@
+From d10be7604c55c961bd06a2e4aaeff1baf4fda24a Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 24 May 2023 16:39:32 +0200
+Subject: [PATCH] sync to master codebase
+
+---
+ Makefile                                   |   2 +-
+ dma.c                                      |   6 +
+ mac80211.c                                 |   6 +
+ mt76.h                                     | 106 ++++++-
+ mt7603/init.c                              |   2 -
+ mt7603/mac.c                               |  22 +-
+ mt7603/main.c                              |  20 +-
+ mt7603/mt7603.h                            |   4 -
+ mt7615/init.c                              |   4 +-
+ mt7615/mac.c                               |  30 +-
+ mt7615/main.c                              |  49 +++-
+ mt7615/mt7615.h                            |   4 -
+ mt7615/regs.h                              |   9 +
+ mt76_connac.h                              |  10 +-
+ mt76_connac2_mac.h                         |   4 +-
+ mt76_connac3_mac.c                         | 182 ++++++++++++
+ mt76_connac3_mac.h                         | 325 +++++++++++++++++++++
+ mt76_connac_mac.c                          | 109 ++++++-
+ mt76_connac_mcu.c                          |   3 +
+ mt76_connac_mcu.h                          |   6 +-
+ mt76x02_util.c                             |  13 -
+ mt7915/debugfs.c                           | 128 ++++----
+ mt7915/dma.c                               | 148 +++++-----
+ mt7915/init.c                              |  12 +-
+ mt7915/mac.c                               | 192 +++++-------
+ mt7915/mac.h                               |   7 +-
+ mt7915/main.c                              | 184 +++++++++---
+ mt7915/mcu.c                               | 119 +++++++-
+ mt7915/mmio.c                              |  34 +--
+ mt7915/mt7915.h                            |  74 +----
+ mt7915/regs.h                              |   3 +
+ mt7915/soc.c                               |  53 ++--
+ mt7921/debugfs.c                           |   2 +-
+ mt7921/dma.c                               |  10 +-
+ mt7921/init.c                              |  72 ++++-
+ mt7921/mac.c                               | 118 +++-----
+ mt7921/main.c                              |  42 ++-
+ mt7921/mcu.c                               |  25 +-
+ mt7921/mt7921.h                            |  43 +--
+ mt7921/pci.c                               |  10 +-
+ mt7921/pci_mac.c                           |  16 +-
+ mt7921/regs.h                              |   1 -
+ mt7921/usb.c                               |   3 +
+ mt7996/debugfs.c                           |   4 +-
+ mt7996/dma.c                               |  83 +++---
+ mt7996/init.c                              |   5 +-
+ mt7996/mac.c                               | 317 +++++---------------
+ mt7996/mac.h                               | 315 +-------------------
+ mt7996/main.c                              | 114 +++++---
+ mt7996/mcu.c                               | 182 +++++++++---
+ mt7996/mcu.h                               |  17 ++
+ mt7996/mt7996.h                            |  80 +----
+ mt7996/pci.c                               |   1 +
+ mt7996/regs.h                              |  21 +-
+ tx.c                                       |  16 +-
+ 59 files changed, 1908 insertions(+), 1459 deletions(-)
+ create mode 100644 mt76_connac3_mac.c
+ create mode 100644 mt76_connac3_mac.h
+
+diff --git a/Makefile b/Makefile
+index 9c287cf4..f9b94280 100644
+--- a/Makefile
++++ b/Makefile
+@@ -28,7 +28,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
+ 
+ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
+ 
+-mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o
++mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o
+ 
+ obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
+ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
+diff --git a/dma.c b/dma.c
+index 465190eb..05d9ab3c 100644
+--- a/dma.c
++++ b/dma.c
+@@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+ 	struct mt76_queue_buf buf = {};
+ 	dma_addr_t addr;
+ 
++	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
++		goto error;
++
+ 	if (q->queued + 1 >= q->ndesc - 1)
+ 		goto error;
+ 
+@@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+ 	dma_addr_t addr;
+ 	u8 *txwi;
+ 
++	if (test_bit(MT76_RESET, &dev->phy.state))
++		goto free_skb;
++
+ 	t = mt76_get_txwi(dev);
+ 	if (!t)
+ 		goto free_skb;
+diff --git a/mac80211.c b/mac80211.c
+index 2c4a5290..85407387 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -76,6 +76,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
+ 	CHAN5G(165, 5825),
+ 	CHAN5G(169, 5845),
+ 	CHAN5G(173, 5865),
++	CHAN5G(177, 5885),
+ };
+ 
+ static const struct ieee80211_channel mt76_channels_6ghz[] = {
+@@ -660,6 +661,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+ 	idr_init(&dev->rx_token);
+ 
+ 	INIT_LIST_HEAD(&dev->wcid_list);
++	INIT_LIST_HEAD(&dev->sta_poll_list);
++	spin_lock_init(&dev->sta_poll_lock);
+ 
+ 	INIT_LIST_HEAD(&dev->txwi_cache);
+ 	INIT_LIST_HEAD(&dev->rxwi_cache);
+@@ -1738,6 +1741,9 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+ 	for (i = 0; i < (eht ? 14 : 12); i++)
+ 		data[ei++] += stats->tx_mcs[i];
+ 
++	for (i = 0; i < 4; i++)
++		data[ei++] += stats->tx_nss[i];
++
+ 	wi->worker_stat_count = ei - wi->initial_stat_idx;
+ }
+ EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
+diff --git a/mt76.h b/mt76.h
+index 8b4635e9..034ab90c 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -277,7 +277,7 @@ struct mt76_sta_stats {
+ 	u64 tx_mcs[16];		/* mcs idx */
+ 	u64 tx_bytes;
+ 	/* WED TX */
+-	u32 tx_packets;
++	u32 tx_packets;		/* unit: MSDU */
+ 	u32 tx_retries;
+ 	u32 tx_failed;
+ 	/* WED RX */
+@@ -316,6 +316,7 @@ struct mt76_wcid {
+ 	int inactive_count;
+ 
+ 	struct rate_info rate;
++	unsigned long ampdu_state;
+ 
+ 	u16 idx;
+ 	u8 hw_key_idx;
+@@ -336,6 +337,8 @@ struct mt76_wcid {
+ 	struct idr pktid;
+ 
+ 	struct mt76_sta_stats stats;
++
++	struct list_head poll_list;
+ };
+ 
+ struct mt76_txq {
+@@ -692,6 +695,9 @@ struct mt76_vif {
+ 	u8 wmm_idx;
+ 	u8 scan_seq_num;
+ 	u8 cipher;
++	u8 basic_rates_idx;
++	u8 mcast_rates_idx;
++	u8 beacon_rates_idx;
+ };
+ 
+ struct mt76_phy {
+@@ -813,6 +819,9 @@ struct mt76_dev {
+ 	struct mt76_wcid __rcu *wcid[MT76_N_WCIDS];
+ 	struct list_head wcid_list;
+ 
++	struct list_head sta_poll_list;
++	spinlock_t sta_poll_lock;
++
+ 	u32 rev;
+ 
+ 	struct tasklet_struct pre_tbtt_tasklet;
+@@ -847,6 +856,101 @@ struct mt76_dev {
+ 	};
+ };
+ 
++/* per-phy stats.  */
++struct mt76_mib_stats {
++	u32 ack_fail_cnt;
++	u32 fcs_err_cnt;
++	u32 rts_cnt;
++	u32 rts_retries_cnt;
++	u32 ba_miss_cnt;
++	u32 tx_bf_cnt;
++	u32 tx_mu_bf_cnt;
++	u32 tx_mu_mpdu_cnt;
++	u32 tx_mu_acked_mpdu_cnt;
++	u32 tx_su_acked_mpdu_cnt;
++	u32 tx_bf_ibf_ppdu_cnt;
++	u32 tx_bf_ebf_ppdu_cnt;
++
++	u32 tx_bf_rx_fb_all_cnt;
++	u32 tx_bf_rx_fb_eht_cnt;
++	u32 tx_bf_rx_fb_he_cnt;
++	u32 tx_bf_rx_fb_vht_cnt;
++	u32 tx_bf_rx_fb_ht_cnt;
++
++	u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
++	u32 tx_bf_rx_fb_nc_cnt;
++	u32 tx_bf_rx_fb_nr_cnt;
++	u32 tx_bf_fb_cpl_cnt;
++	u32 tx_bf_fb_trig_cnt;
++
++	u32 tx_ampdu_cnt;
++	u32 tx_stop_q_empty_cnt;
++	u32 tx_mpdu_attempts_cnt;
++	u32 tx_mpdu_success_cnt;
++	u32 tx_pkt_ebf_cnt;
++	u32 tx_pkt_ibf_cnt;
++
++	u32 tx_rwp_fail_cnt;
++	u32 tx_rwp_need_cnt;
++
++	/* rx stats */
++	u32 rx_fifo_full_cnt;
++	u32 channel_idle_cnt;
++	u32 primary_cca_busy_time;
++	u32 secondary_cca_busy_time;
++	u32 primary_energy_detect_time;
++	u32 cck_mdrdy_time;
++	u32 ofdm_mdrdy_time;
++	u32 green_mdrdy_time;
++	u32 rx_vector_mismatch_cnt;
++	u32 rx_delimiter_fail_cnt;
++	u32 rx_mrdy_cnt;
++	u32 rx_len_mismatch_cnt;
++	u32 rx_mpdu_cnt;
++	u32 rx_ampdu_cnt;
++	u32 rx_ampdu_bytes_cnt;
++	u32 rx_ampdu_valid_subframe_cnt;
++	u32 rx_ampdu_valid_subframe_bytes_cnt;
++	u32 rx_pfdrop_cnt;
++	u32 rx_vec_queue_overflow_drop_cnt;
++	u32 rx_ba_cnt;
++
++	u32 tx_amsdu[8];
++	u32 tx_amsdu_cnt;
++
++	/* mcu_muru_stats */
++	u32 dl_cck_cnt;
++	u32 dl_ofdm_cnt;
++	u32 dl_htmix_cnt;
++	u32 dl_htgf_cnt;
++	u32 dl_vht_su_cnt;
++	u32 dl_vht_2mu_cnt;
++	u32 dl_vht_3mu_cnt;
++	u32 dl_vht_4mu_cnt;
++	u32 dl_he_su_cnt;
++	u32 dl_he_ext_su_cnt;
++	u32 dl_he_2ru_cnt;
++	u32 dl_he_2mu_cnt;
++	u32 dl_he_3ru_cnt;
++	u32 dl_he_3mu_cnt;
++	u32 dl_he_4ru_cnt;
++	u32 dl_he_4mu_cnt;
++	u32 dl_he_5to8ru_cnt;
++	u32 dl_he_9to16ru_cnt;
++	u32 dl_he_gtr16ru_cnt;
++
++	u32 ul_hetrig_su_cnt;
++	u32 ul_hetrig_2ru_cnt;
++	u32 ul_hetrig_3ru_cnt;
++	u32 ul_hetrig_4ru_cnt;
++	u32 ul_hetrig_5to8ru_cnt;
++	u32 ul_hetrig_9to16ru_cnt;
++	u32 ul_hetrig_gtr16ru_cnt;
++	u32 ul_hetrig_2mu_cnt;
++	u32 ul_hetrig_3mu_cnt;
++	u32 ul_hetrig_4mu_cnt;
++};
++
+ struct mt76_power_limits {
+ 	s8 cck[4];
+ 	s8 ofdm[8];
+diff --git a/mt7603/init.c b/mt7603/init.c
+index 9a2e632d..0762de3c 100644
+--- a/mt7603/init.c
++++ b/mt7603/init.c
+@@ -500,8 +500,6 @@ int mt7603_register_device(struct mt7603_dev *dev)
+ 	bus_ops->rmw = mt7603_rmw;
+ 	dev->mt76.bus = bus_ops;
+ 
+-	INIT_LIST_HEAD(&dev->sta_poll_list);
+-	spin_lock_init(&dev->sta_poll_lock);
+ 	spin_lock_init(&dev->ps_lock);
+ 
+ 	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7603_mac_work);
+diff --git a/mt7603/mac.c b/mt7603/mac.c
+index 12e0af52..de11557e 100644
+--- a/mt7603/mac.c
++++ b/mt7603/mac.c
+@@ -412,16 +412,16 @@ void mt7603_mac_sta_poll(struct mt7603_dev *dev)
+ 	while (1) {
+ 		bool clear = false;
+ 
+-		spin_lock_bh(&dev->sta_poll_lock);
+-		if (list_empty(&dev->sta_poll_list)) {
+-			spin_unlock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		if (list_empty(&dev->mt76.sta_poll_list)) {
++			spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 			break;
+ 		}
+ 
+-		msta = list_first_entry(&dev->sta_poll_list, struct mt7603_sta,
+-					poll_list);
+-		list_del_init(&msta->poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		msta = list_first_entry(&dev->mt76.sta_poll_list,
++					struct mt7603_sta, wcid.poll_list);
++		list_del_init(&msta->wcid.poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		addr = mt7603_wtbl4_addr(msta->wcid.idx);
+ 		for (i = 0; i < 4; i++) {
+@@ -1267,10 +1267,10 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
+ 	msta = container_of(wcid, struct mt7603_sta, wcid);
+ 	sta = wcid_to_sta(wcid);
+ 
+-	if (list_empty(&msta->poll_list)) {
+-		spin_lock_bh(&dev->sta_poll_lock);
+-		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++	if (list_empty(&msta->wcid.poll_list)) {
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+ 	if (mt7603_mac_add_txs_skb(dev, msta, pid, txs_data))
+diff --git a/mt7603/main.c b/mt7603/main.c
+index 1b1358c6..1d489341 100644
+--- a/mt7603/main.c
++++ b/mt7603/main.c
+@@ -66,7 +66,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ 
+ 	idx = MT7603_WTBL_RESERVED - 1 - mvif->idx;
+ 	dev->mt76.vif_mask |= BIT_ULL(mvif->idx);
+-	INIT_LIST_HEAD(&mvif->sta.poll_list);
++	INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
+ 	mvif->sta.wcid.idx = idx;
+ 	mvif->sta.wcid.hw_key_idx = -1;
+ 	mt76_packet_id_init(&mvif->sta.wcid);
+@@ -100,10 +100,10 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ 
+ 	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 	dev->mt76.vif_mask &= ~BIT_ULL(mvif->idx);
+@@ -351,7 +351,7 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (idx < 0)
+ 		return -ENOSPC;
+ 
+-	INIT_LIST_HEAD(&msta->poll_list);
++	INIT_LIST_HEAD(&msta->wcid.poll_list);
+ 	__skb_queue_head_init(&msta->psq);
+ 	msta->ps = ~0;
+ 	msta->smps = ~0;
+@@ -388,10 +388,10 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	mt7603_filter_tx(dev, wcid->idx, true);
+ 	spin_unlock_bh(&dev->ps_lock);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&mdev->sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&mdev->sta_poll_lock);
+ 
+ 	mt7603_wtbl_clear(dev, wcid->idx);
+ }
+diff --git a/mt7603/mt7603.h b/mt7603/mt7603.h
+index 7c3be596..354b1898 100644
+--- a/mt7603/mt7603.h
++++ b/mt7603/mt7603.h
+@@ -64,7 +64,6 @@ struct mt7603_sta {
+ 
+ 	struct mt7603_vif *vif;
+ 
+-	struct list_head poll_list;
+ 	u32 tx_airtime_ac[4];
+ 
+ 	struct sk_buff_head psq;
+@@ -110,9 +109,6 @@ struct mt7603_dev {
+ 
+ 	u32 rxfilter;
+ 
+-	struct list_head sta_poll_list;
+-	spinlock_t sta_poll_lock;
+-
+ 	struct mt7603_sta global_sta;
+ 
+ 	u32 agc0, agc3;
+diff --git a/mt7615/init.c b/mt7615/init.c
+index 621e69f0..18a50ccf 100644
+--- a/mt7615/init.c
++++ b/mt7615/init.c
+@@ -397,6 +397,8 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
++	if (!is_mt7622(&phy->dev->mt76))
++		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
+ 
+ 	ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
+ 	ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
+@@ -626,8 +628,6 @@ void mt7615_init_device(struct mt7615_dev *dev)
+ 	INIT_DELAYED_WORK(&dev->coredump.work, mt7615_coredump_work);
+ 	skb_queue_head_init(&dev->phy.scan_event_list);
+ 	skb_queue_head_init(&dev->coredump.msg_list);
+-	INIT_LIST_HEAD(&dev->sta_poll_list);
+-	spin_lock_init(&dev->sta_poll_lock);
+ 	init_waitqueue_head(&dev->reset_wait);
+ 	init_waitqueue_head(&dev->phy.roc_wait);
+ 
+diff --git a/mt7615/mac.c b/mt7615/mac.c
+index da1d17b7..7ba78983 100644
+--- a/mt7615/mac.c
++++ b/mt7615/mac.c
+@@ -387,10 +387,11 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
+ 		struct mt7615_sta *msta;
+ 
+ 		msta = container_of(status->wcid, struct mt7615_sta, wcid);
+-		spin_lock_bh(&dev->sta_poll_lock);
+-		if (list_empty(&msta->poll_list))
+-			list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		if (list_empty(&msta->wcid.poll_list))
++			list_add_tail(&msta->wcid.poll_list,
++				      &dev->mt76.sta_poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+ 	if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask &&
+@@ -905,16 +906,19 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev)
+ 	int i;
+ 
+ 	INIT_LIST_HEAD(&sta_poll_list);
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	list_splice_init(&dev->sta_poll_list, &sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	while (!list_empty(&sta_poll_list)) {
+ 		bool clear = false;
+ 
+ 		msta = list_first_entry(&sta_poll_list, struct mt7615_sta,
+-					poll_list);
+-		list_del_init(&msta->poll_list);
++					wcid.poll_list);
++
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		list_del_init(&msta->wcid.poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		addr = mt7615_mac_wtbl_addr(dev, msta->wcid.idx) + 19 * 4;
+ 
+@@ -1511,10 +1515,10 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
+ 	msta = container_of(wcid, struct mt7615_sta, wcid);
+ 	sta = wcid_to_sta(wcid);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (list_empty(&msta->poll_list))
+-		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (list_empty(&msta->wcid.poll_list))
++		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	if (mt7615_mac_add_txs_skb(dev, msta, pid, txs_data))
+ 		goto out;
+diff --git a/mt7615/main.c b/mt7615/main.c
+index dadb13f2..200b1752 100644
+--- a/mt7615/main.c
++++ b/mt7615/main.c
+@@ -222,7 +222,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
+ 
+ 	idx = MT7615_WTBL_RESERVED - mvif->mt76.idx;
+ 
+-	INIT_LIST_HEAD(&mvif->sta.poll_list);
++	INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
+ 	mvif->sta.wcid.idx = idx;
+ 	mvif->sta.wcid.phy_idx = mvif->mt76.band_idx;
+ 	mvif->sta.wcid.hw_key_idx = -1;
+@@ -274,10 +274,10 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
+ 
+ 	mt7615_mutex_release(dev);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	mt76_packet_id_flush(&dev->mt76, &mvif->sta.wcid);
+ }
+@@ -552,6 +552,32 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
+ 	mt7615_mutex_release(dev);
+ }
+ 
++static void
++mt7615_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++		       struct ieee80211_bss_conf *info)
++{
++	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
++	struct mt7615_dev *dev = mt7615_hw_dev(hw);
++	u8 i, band = mvif->mt76.band_idx;
++	u32 *mu;
++
++	mu = (u32 *)info->mu_group.membership;
++	for (i = 0; i < WLAN_MEMBERSHIP_LEN / sizeof(*mu); i++) {
++		if (is_mt7663(&dev->mt76))
++			mt76_wr(dev, MT7663_WF_PHY_GID_TAB_VLD(band, i), mu[i]);
++		else
++			mt76_wr(dev, MT_WF_PHY_GID_TAB_VLD(band, i), mu[i]);
++	}
++
++	mu = (u32 *)info->mu_group.position;
++	for (i = 0; i < WLAN_USER_POSITION_LEN / sizeof(*mu); i++) {
++		if (is_mt7663(&dev->mt76))
++			mt76_wr(dev, MT7663_WF_PHY_GID_TAB_POS(band, i), mu[i]);
++		else
++			mt76_wr(dev, MT_WF_PHY_GID_TAB_POS(band, i), mu[i]);
++	}
++}
++
+ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
+ 				    struct ieee80211_vif *vif,
+ 				    struct ieee80211_bss_conf *info,
+@@ -600,6 +626,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
+ 	if (changed & BSS_CHANGED_ASSOC)
+ 		mt7615_mac_set_beacon_filter(phy, vif, vif->cfg.assoc);
+ 
++	if (changed & BSS_CHANGED_MU_GROUPS)
++		 mt7615_update_mu_group(hw, vif, info);
++
+ 	mt7615_mutex_release(dev);
+ }
+ 
+@@ -628,7 +657,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (idx < 0)
+ 		return -ENOSPC;
+ 
+-	INIT_LIST_HEAD(&msta->poll_list);
++	INIT_LIST_HEAD(&msta->wcid.poll_list);
+ 	msta->vif = mvif;
+ 	msta->wcid.sta = 1;
+ 	msta->wcid.idx = idx;
+@@ -676,10 +705,10 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
+ 		mt7615_mcu_add_bss_info(phy, vif, sta, false);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&mdev->sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&mdev->sta_poll_lock);
+ 
+ 	mt76_connac_power_save_sched(phy->mt76, &dev->pm);
+ }
+diff --git a/mt7615/mt7615.h b/mt7615/mt7615.h
+index 582d1b5b..a20322aa 100644
+--- a/mt7615/mt7615.h
++++ b/mt7615/mt7615.h
+@@ -125,7 +125,6 @@ struct mt7615_sta {
+ 
+ 	struct mt7615_vif *vif;
+ 
+-	struct list_head poll_list;
+ 	u32 airtime_ac[8];
+ 
+ 	struct ieee80211_tx_rate rates[4];
+@@ -262,9 +261,6 @@ struct mt7615_dev {
+ 	wait_queue_head_t reset_wait;
+ 	u32 reset_state;
+ 
+-	struct list_head sta_poll_list;
+-	spinlock_t sta_poll_lock;
+-
+ 	struct {
+ 		u8 n_pulses;
+ 		u32 period;
+diff --git a/mt7615/regs.h b/mt7615/regs.h
+index 7cecb22c..806b3887 100644
+--- a/mt7615/regs.h
++++ b/mt7615/regs.h
+@@ -212,6 +212,15 @@ enum mt7615_reg_base {
+ 
+ #define MT7663_WF_PHY_R0_PHYCTRL_STS5(_phy)	MT_WF_PHY(0x0224 + ((_phy) << 12))
+ 
++#define MT_WF_PHY_GID_TAB_VLD(_phy, i)		MT_WF_PHY(0x0254 + (i) * 4 + \
++							  ((_phy) << 9))
++#define MT7663_WF_PHY_GID_TAB_VLD(_phy, i)	MT_WF_PHY(0x0254 + (i) * 4 + \
++							  ((_phy) << 12))
++#define MT_WF_PHY_GID_TAB_POS(_phy, i)		MT_WF_PHY(0x025c + (i) * 4 + \
++							  ((_phy) << 9))
++#define MT7663_WF_PHY_GID_TAB_POS(_phy, i)	MT_WF_PHY(0x025c + (i) * 4 + \
++							  ((_phy) << 12))
++
+ #define MT_WF_PHY_MIN_PRI_PWR(_phy)	MT_WF_PHY((_phy) ? 0x084 : 0x229c)
+ #define MT_WF_PHY_PD_OFDM_MASK(_phy)	((_phy) ? GENMASK(24, 16) : \
+ 					 GENMASK(28, 20))
+diff --git a/mt76_connac.h b/mt76_connac.h
+index 77ca8f05..22878f08 100644
+--- a/mt76_connac.h
++++ b/mt76_connac.h
+@@ -419,5 +419,13 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
+ 				  struct mt76_rx_status *status,
+ 				  struct ieee80211_supported_band *sband,
+ 				  __le32 *rxv, u8 *mode);
+-
++void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi);
++void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t,
++			    struct ieee80211_sta *sta,
++			    struct list_head *free_list);
++void mt76_connac2_tx_token_put(struct mt76_dev *dev);
++
++/* connac3 */
++void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv,
++					 u8 mode);
+ #endif /* __MT76_CONNAC_H */
+diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
+index a5ec0f63..bd2a9246 100644
+--- a/mt76_connac2_mac.h
++++ b/mt76_connac2_mac.h
+@@ -34,7 +34,7 @@ enum {
+ 
+ #define MT_TX_FREE_MSDU_CNT		GENMASK(9, 0)
+ #define MT_TX_FREE_WLAN_ID		GENMASK(23, 14)
+-#define MT_TX_FREE_LATENCY		GENMASK(12, 0)
++#define MT_TX_FREE_COUNT		GENMASK(12, 0)
+ /* 0: success, others: dropped */
+ #define MT_TX_FREE_STATUS		GENMASK(14, 13)
+ #define MT_TX_FREE_MSDU_ID		GENMASK(30, 16)
+@@ -173,7 +173,7 @@ enum {
+ #define MT_TXS5_MPDU_TX_CNT		GENMASK(31, 23)
+ 
+ #define MT_TXS6_MPDU_FAIL_CNT		GENMASK(31, 23)
+-
++#define MT_TXS7_MPDU_RETRY_BYTE		GENMASK(22, 0)
+ #define MT_TXS7_MPDU_RETRY_CNT		GENMASK(31, 23)
+ 
+ /* RXD DW0 */
+diff --git a/mt76_connac3_mac.c b/mt76_connac3_mac.c
+new file mode 100644
+index 00000000..73e9f283
+--- /dev/null
++++ b/mt76_connac3_mac.c
+@@ -0,0 +1,182 @@
++// SPDX-License-Identifier: ISC
++/* Copyright (C) 2023 MediaTek Inc. */
++
++#include "mt76_connac.h"
++#include "mt76_connac3_mac.h"
++#include "dma.h"
++
++#define HE_BITS(f)		cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
++#define HE_PREP(f, m, v)	le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
++						 IEEE80211_RADIOTAP_HE_##f)
++
++static void
++mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
++				       struct ieee80211_radiotap_he *he,
++				       __le32 *rxv)
++{
++	u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC), offs = 0;
++
++	status->bw = RATE_INFO_BW_HE_RU;
++
++	switch (ru) {
++	case 0 ... 36:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
++		offs = ru;
++		break;
++	case 37 ... 52:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
++		offs = ru - 37;
++		break;
++	case 53 ... 60:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
++		offs = ru - 53;
++		break;
++	case 61 ... 64:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
++		offs = ru - 61;
++		break;
++	case 65 ... 66:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
++		offs = ru - 65;
++		break;
++	case 67:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
++		break;
++	case 68:
++		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
++		break;
++	}
++
++	he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
++	he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) |
++		     le16_encode_bits(offs,
++				      IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
++}
++
++#define MU_PREP(f, v)	le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f)
++static void
++mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
++{
++	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
++	static const struct ieee80211_radiotap_he_mu mu_known = {
++		.flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
++			  HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
++			  HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) |
++			  HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
++		.flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
++	};
++	struct ieee80211_radiotap_he_mu *he_mu;
++
++	status->flag |= RX_FLAG_RADIOTAP_HE_MU;
++
++	he_mu = skb_push(skb, sizeof(mu_known));
++	memcpy(he_mu, &mu_known, sizeof(mu_known));
++
++	he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx);
++	if (status->he_dcm)
++		he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm);
++
++	he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
++			 MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
++				 le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER));
++
++	he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff;
++
++	if (status->bw >= RATE_INFO_BW_40) {
++		he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
++		he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff;
++	}
++
++	if (status->bw >= RATE_INFO_BW_80) {
++		u32 ru_h, ru_l;
++
++		he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff;
++
++		ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L);
++		ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7;
++		he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4);
++	}
++}
++
++void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv,
++					 u8 mode)
++{
++	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
++	static const struct ieee80211_radiotap_he known = {
++		.data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
++			 HE_BITS(DATA1_DATA_DCM_KNOWN) |
++			 HE_BITS(DATA1_STBC_KNOWN) |
++			 HE_BITS(DATA1_CODING_KNOWN) |
++			 HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
++			 HE_BITS(DATA1_DOPPLER_KNOWN) |
++			 HE_BITS(DATA1_SPTL_REUSE_KNOWN) |
++			 HE_BITS(DATA1_BSS_COLOR_KNOWN),
++		.data2 = HE_BITS(DATA2_GI_KNOWN) |
++			 HE_BITS(DATA2_TXBF_KNOWN) |
++			 HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
++			 HE_BITS(DATA2_TXOP_KNOWN),
++	};
++	u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1;
++	struct ieee80211_radiotap_he *he;
++
++	status->flag |= RX_FLAG_RADIOTAP_HE;
++
++	he = skb_push(skb, sizeof(known));
++	memcpy(he, &known, sizeof(known));
++
++	he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) |
++		    HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]);
++	he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]);
++	he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) |
++		    le16_encode_bits(ltf_size,
++				     IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
++	if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
++		he->data5 |= HE_BITS(DATA5_TXBF);
++	he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) |
++		    HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]);
++
++	switch (mode) {
++	case MT_PHY_TYPE_HE_SU:
++		he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
++			     HE_BITS(DATA1_UL_DL_KNOWN) |
++			     HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
++			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
++
++		he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) |
++			     HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
++		break;
++	case MT_PHY_TYPE_HE_EXT_SU:
++		he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
++			     HE_BITS(DATA1_UL_DL_KNOWN) |
++			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
++
++		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
++		break;
++	case MT_PHY_TYPE_HE_MU:
++		he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
++			     HE_BITS(DATA1_UL_DL_KNOWN);
++
++		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
++		he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]);
++
++		mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv);
++		mt76_connac3_mac_decode_he_mu_radiotap(skb, rxv);
++		break;
++	case MT_PHY_TYPE_HE_TB:
++		he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
++			     HE_BITS(DATA1_SPTL_REUSE2_KNOWN) |
++			     HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
++			     HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
++
++		he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) |
++			     HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) |
++			     HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) |
++			     HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]);
++
++		mt76_connac3_mac_decode_he_radiotap_ru(status, he, rxv);
++		break;
++	default:
++		break;
++	}
++}
++EXPORT_SYMBOL_GPL(mt76_connac3_mac_decode_he_radiotap);
+diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
+new file mode 100644
+index 00000000..6663a0b4
+--- /dev/null
++++ b/mt76_connac3_mac.h
+@@ -0,0 +1,325 @@
++/* SPDX-License-Identifier: ISC */
++/* Copyright (C) 2023 MediaTek Inc. */
++
++#ifndef __MT76_CONNAC3_MAC_H
++#define __MT76_CONNAC3_MAC_H
++
++#define MT_CT_PARSE_LEN			72
++#define MT_CT_DMA_BUF_NUM		2
++
++#define MT_RXD0_LENGTH			GENMASK(15, 0)
++#define MT_RXD0_PKT_FLAG                GENMASK(19, 16)
++#define MT_RXD0_PKT_TYPE		GENMASK(31, 27)
++
++#define MT_RXD0_MESH			BIT(18)
++#define MT_RXD0_MHCP			BIT(19)
++#define MT_RXD0_NORMAL_ETH_TYPE_OFS	GENMASK(22, 16)
++#define MT_RXD0_NORMAL_IP_SUM		BIT(23)
++#define MT_RXD0_NORMAL_UDP_TCP_SUM	BIT(24)
++
++#define MT_RXD0_SW_PKT_TYPE_MASK	GENMASK(31, 16)
++#define MT_RXD0_SW_PKT_TYPE_MAP		0x380F
++#define MT_RXD0_SW_PKT_TYPE_FRAME	0x3801
++
++/* RXD DW1 */
++#define MT_RXD1_NORMAL_WLAN_IDX		GENMASK(11, 0)
++#define MT_RXD1_NORMAL_GROUP_1		BIT(16)
++#define MT_RXD1_NORMAL_GROUP_2		BIT(17)
++#define MT_RXD1_NORMAL_GROUP_3		BIT(18)
++#define MT_RXD1_NORMAL_GROUP_4		BIT(19)
++#define MT_RXD1_NORMAL_GROUP_5		BIT(20)
++#define MT_RXD1_NORMAL_KEY_ID		GENMASK(22, 21)
++#define MT_RXD1_NORMAL_CM		BIT(23)
++#define MT_RXD1_NORMAL_CLM		BIT(24)
++#define MT_RXD1_NORMAL_ICV_ERR		BIT(25)
++#define MT_RXD1_NORMAL_TKIP_MIC_ERR	BIT(26)
++#define MT_RXD1_NORMAL_BAND_IDX		GENMASK(28, 27)
++#define MT_RXD1_NORMAL_SPP_EN		BIT(29)
++#define MT_RXD1_NORMAL_ADD_OM		BIT(30)
++#define MT_RXD1_NORMAL_SEC_DONE		BIT(31)
++
++/* RXD DW2 */
++#define MT_RXD2_NORMAL_BSSID		GENMASK(5, 0)
++#define MT_RXD2_NORMAL_MAC_HDR_LEN	GENMASK(12, 8)
++#define MT_RXD2_NORMAL_HDR_TRANS	BIT(7)
++#define MT_RXD2_NORMAL_HDR_OFFSET	GENMASK(15, 13)
++#define MT_RXD2_NORMAL_SEC_MODE		GENMASK(20, 16)
++#define MT_RXD2_NORMAL_MU_BAR		BIT(21)
++#define MT_RXD2_NORMAL_SW_BIT		BIT(22)
++#define MT_RXD2_NORMAL_AMSDU_ERR	BIT(23)
++#define MT_RXD2_NORMAL_MAX_LEN_ERROR	BIT(24)
++#define MT_RXD2_NORMAL_HDR_TRANS_ERROR	BIT(25)
++#define MT_RXD2_NORMAL_INT_FRAME	BIT(26)
++#define MT_RXD2_NORMAL_FRAG		BIT(27)
++#define MT_RXD2_NORMAL_NULL_FRAME	BIT(28)
++#define MT_RXD2_NORMAL_NDATA		BIT(29)
++#define MT_RXD2_NORMAL_NON_AMPDU	BIT(30)
++#define MT_RXD2_NORMAL_BF_REPORT	BIT(31)
++
++/* RXD DW3 */
++#define MT_RXD3_NORMAL_RXV_SEQ		GENMASK(7, 0)
++#define MT_RXD3_NORMAL_CH_FREQ		GENMASK(15, 8)
++#define MT_RXD3_NORMAL_ADDR_TYPE	GENMASK(17, 16)
++#define MT_RXD3_NORMAL_U2M		BIT(0)
++#define MT_RXD3_NORMAL_HTC_VLD		BIT(18)
++#define MT_RXD3_NORMAL_BEACON_MC	BIT(20)
++#define MT_RXD3_NORMAL_BEACON_UC	BIT(21)
++#define MT_RXD3_NORMAL_CO_ANT		BIT(22)
++#define MT_RXD3_NORMAL_FCS_ERR		BIT(24)
++#define MT_RXD3_NORMAL_VLAN2ETH		BIT(31)
++
++/* RXD DW4 */
++#define MT_RXD4_NORMAL_PAYLOAD_FORMAT	GENMASK(1, 0)
++#define MT_RXD4_FIRST_AMSDU_FRAME	GENMASK(1, 0)
++#define MT_RXD4_MID_AMSDU_FRAME		BIT(1)
++#define MT_RXD4_LAST_AMSDU_FRAME	BIT(0)
++
++#define MT_RXV_HDR_BAND_IDX		BIT(24)
++
++/* RXD GROUP4 */
++#define MT_RXD8_FRAME_CONTROL		GENMASK(15, 0)
++
++#define MT_RXD10_SEQ_CTRL		GENMASK(15, 0)
++#define MT_RXD10_QOS_CTL		GENMASK(31, 16)
++
++#define MT_RXD11_HT_CONTROL		GENMASK(31, 0)
++
++/* P-RXV */
++#define MT_PRXV_TX_RATE			GENMASK(6, 0)
++#define MT_PRXV_TX_DCM			BIT(4)
++#define MT_PRXV_TX_ER_SU_106T		BIT(5)
++#define MT_PRXV_NSTS			GENMASK(10, 7)
++#define MT_PRXV_TXBF			BIT(11)
++#define MT_PRXV_HT_AD_CODE		BIT(12)
++#define MT_PRXV_HE_RU_ALLOC		GENMASK(30, 22)
++#define MT_PRXV_RCPI3			GENMASK(31, 24)
++#define MT_PRXV_RCPI2			GENMASK(23, 16)
++#define MT_PRXV_RCPI1			GENMASK(15, 8)
++#define MT_PRXV_RCPI0			GENMASK(7, 0)
++#define MT_PRXV_HT_SHORT_GI		GENMASK(4, 3)
++#define MT_PRXV_HT_STBC			GENMASK(10, 9)
++#define MT_PRXV_TX_MODE			GENMASK(14, 11)
++#define MT_PRXV_FRAME_MODE		GENMASK(2, 0)
++#define MT_PRXV_DCM			BIT(5)
++
++/* C-RXV */
++#define MT_CRXV_HE_NUM_USER		GENMASK(26, 20)
++#define MT_CRXV_HE_LTF_SIZE		GENMASK(28, 27)
++#define MT_CRXV_HE_LDPC_EXT_SYM		BIT(30)
++
++#define MT_CRXV_HE_PE_DISAMBIG		BIT(1)
++#define MT_CRXV_HE_UPLINK		BIT(2)
++
++#define MT_CRXV_HE_MU_AID		GENMASK(27, 17)
++#define MT_CRXV_HE_BEAM_CHNG		BIT(29)
++
++#define MT_CRXV_HE_DOPPLER		BIT(0)
++#define MT_CRXV_HE_BSS_COLOR		GENMASK(15, 10)
++#define MT_CRXV_HE_TXOP_DUR		GENMASK(19, 17)
++
++#define MT_CRXV_HE_SR_MASK		GENMASK(11, 8)
++#define MT_CRXV_HE_SR1_MASK		GENMASK(16, 12)
++#define MT_CRXV_HE_SR2_MASK             GENMASK(20, 17)
++#define MT_CRXV_HE_SR3_MASK             GENMASK(24, 21)
++
++#define MT_CRXV_HE_RU0			GENMASK(8, 0)
++#define MT_CRXV_HE_RU1			GENMASK(17, 9)
++#define MT_CRXV_HE_RU2			GENMASK(26, 18)
++#define MT_CRXV_HE_RU3_L		GENMASK(31, 27)
++#define MT_CRXV_HE_RU3_H		GENMASK(3, 0)
++
++enum tx_header_format {
++	MT_HDR_FORMAT_802_3,
++	MT_HDR_FORMAT_CMD,
++	MT_HDR_FORMAT_802_11,
++	MT_HDR_FORMAT_802_11_EXT,
++};
++
++enum tx_pkt_type {
++	MT_TX_TYPE_CT,
++	MT_TX_TYPE_SF,
++	MT_TX_TYPE_CMD,
++	MT_TX_TYPE_FW,
++};
++
++enum tx_port_idx {
++	MT_TX_PORT_IDX_LMAC,
++	MT_TX_PORT_IDX_MCU
++};
++
++enum tx_mcu_port_q_idx {
++	MT_TX_MCU_PORT_RX_Q0 = 0x20,
++	MT_TX_MCU_PORT_RX_Q1,
++	MT_TX_MCU_PORT_RX_Q2,
++	MT_TX_MCU_PORT_RX_Q3,
++	MT_TX_MCU_PORT_RX_FWDL = 0x3e
++};
++
++enum tx_mgnt_type {
++	MT_TX_NORMAL,
++	MT_TX_TIMING,
++	MT_TX_ADDBA,
++};
++
++#define MT_CT_INFO_APPLY_TXD		BIT(0)
++#define MT_CT_INFO_COPY_HOST_TXD_ALL	BIT(1)
++#define MT_CT_INFO_MGMT_FRAME		BIT(2)
++#define MT_CT_INFO_NONE_CIPHER_FRAME	BIT(3)
++#define MT_CT_INFO_HSR2_TX		BIT(4)
++#define MT_CT_INFO_FROM_HOST		BIT(7)
++
++#define MT_TXD_SIZE			(8 * 4)
++
++#define MT_TXD0_Q_IDX			GENMASK(31, 25)
++#define MT_TXD0_PKT_FMT			GENMASK(24, 23)
++#define MT_TXD0_ETH_TYPE_OFFSET		GENMASK(22, 16)
++#define MT_TXD0_TX_BYTES		GENMASK(15, 0)
++
++#define MT_TXD1_FIXED_RATE		BIT(31)
++#define MT_TXD1_OWN_MAC			GENMASK(30, 25)
++#define MT_TXD1_TID			GENMASK(24, 21)
++#define MT_TXD1_BIP			BIT(24)
++#define MT_TXD1_ETH_802_3		BIT(20)
++#define MT_TXD1_HDR_INFO		GENMASK(20, 16)
++#define MT_TXD1_HDR_FORMAT		GENMASK(15, 14)
++#define MT_TXD1_TGID			GENMASK(13, 12)
++#define MT_TXD1_WLAN_IDX		GENMASK(11, 0)
++
++#define MT_TXD2_POWER_OFFSET		GENMASK(31, 26)
++#define MT_TXD2_MAX_TX_TIME		GENMASK(25, 16)
++#define MT_TXD2_FRAG			GENMASK(15, 14)
++#define MT_TXD2_HTC_VLD			BIT(13)
++#define MT_TXD2_DURATION		BIT(12)
++#define MT_TXD2_HDR_PAD			GENMASK(11, 10)
++#define MT_TXD2_RTS			BIT(9)
++#define MT_TXD2_OWN_MAC_MAP		BIT(8)
++#define MT_TXD2_BF_TYPE			GENMASK(6, 7)
++#define MT_TXD2_FRAME_TYPE		GENMASK(5, 4)
++#define MT_TXD2_SUB_TYPE		GENMASK(3, 0)
++
++#define MT_TXD3_SN_VALID		BIT(31)
++#define MT_TXD3_PN_VALID		BIT(30)
++#define MT_TXD3_SW_POWER_MGMT		BIT(29)
++#define MT_TXD3_BA_DISABLE		BIT(28)
++#define MT_TXD3_SEQ			GENMASK(27, 16)
++#define MT_TXD3_REM_TX_COUNT		GENMASK(15, 11)
++#define MT_TXD3_TX_COUNT		GENMASK(10, 6)
++#define MT_TXD3_HW_AMSDU		BIT(5)
++#define MT_TXD3_BCM			BIT(4)
++#define MT_TXD3_EEOSP			BIT(3)
++#define MT_TXD3_EMRD			BIT(2)
++#define MT_TXD3_PROTECT_FRAME		BIT(1)
++#define MT_TXD3_NO_ACK			BIT(0)
++
++#define MT_TXD4_PN_LOW			GENMASK(31, 0)
++
++#define MT_TXD5_PN_HIGH			GENMASK(31, 16)
++#define MT_TXD5_FL			BIT(15)
++#define MT_TXD5_BYPASS_TBB		BIT(14)
++#define MT_TXD5_BYPASS_RBB		BIT(13)
++#define MT_TXD5_BSS_COLOR_ZERO		BIT(12)
++#define MT_TXD5_TX_STATUS_HOST		BIT(10)
++#define MT_TXD5_TX_STATUS_MCU		BIT(9)
++#define MT_TXD5_TX_STATUS_FMT		BIT(8)
++#define MT_TXD5_PID			GENMASK(7, 0)
++
++#define MT_TXD6_TX_SRC			GENMASK(31, 30)
++#define MT_TXD6_VTA			BIT(28)
++#define MT_TXD6_BW			GENMASK(25, 22)
++#define MT_TXD6_TX_RATE			GENMASK(21, 16)
++#define MT_TXD6_TIMESTAMP_OFS_EN	BIT(15)
++#define MT_TXD6_TIMESTAMP_OFS_IDX	GENMASK(14, 10)
++#define MT_TXD6_MSDU_CNT		GENMASK(9, 4)
++#define MT_TXD6_DIS_MAT			BIT(3)
++#define MT_TXD6_DAS			BIT(2)
++#define MT_TXD6_AMSDU_CAP		BIT(1)
++
++#define MT_TXD7_TXD_LEN			GENMASK(31, 30)
++#define MT_TXD7_IP_SUM			BIT(29)
++#define MT_TXD7_DROP_BY_SDO		BIT(28)
++#define MT_TXD7_MAC_TXD			BIT(27)
++#define MT_TXD7_CTXD			BIT(26)
++#define MT_TXD7_CTXD_CNT		GENMASK(25, 22)
++#define MT_TXD7_UDP_TCP_SUM		BIT(15)
++#define MT_TXD7_TX_TIME			GENMASK(9, 0)
++
++#define MT_TX_RATE_STBC			BIT(14)
++#define MT_TX_RATE_NSS			GENMASK(13, 10)
++#define MT_TX_RATE_MODE			GENMASK(9, 6)
++#define MT_TX_RATE_SU_EXT_TONE		BIT(5)
++#define MT_TX_RATE_DCM			BIT(4)
++/* VHT/HE only use bits 0-3 */
++#define MT_TX_RATE_IDX			GENMASK(5, 0)
++
++#define MT_TXFREE0_PKT_TYPE		GENMASK(31, 27)
++#define MT_TXFREE0_MSDU_CNT		GENMASK(25, 16)
++#define MT_TXFREE0_RX_BYTE		GENMASK(15, 0)
++
++#define MT_TXFREE1_VER			GENMASK(18, 16)
++
++#define MT_TXFREE_INFO_PAIR		BIT(31)
++#define MT_TXFREE_INFO_HEADER		BIT(30)
++#define MT_TXFREE_INFO_WLAN_ID		GENMASK(23, 12)
++#define MT_TXFREE_INFO_MSDU_ID		GENMASK(14, 0)
++#define MT_TXFREE_INFO_COUNT		GENMASK(27, 24)
++#define MT_TXFREE_INFO_STAT		GENMASK(29, 28)
++
++#define MT_TXS0_BW			GENMASK(31, 29)
++#define MT_TXS0_TID			GENMASK(28, 26)
++#define MT_TXS0_AMPDU			BIT(25)
++#define MT_TXS0_TXS_FORMAT		GENMASK(24, 23)
++#define MT_TXS0_BA_ERROR		BIT(22)
++#define MT_TXS0_PS_FLAG			BIT(21)
++#define MT_TXS0_TXOP_TIMEOUT		BIT(20)
++#define MT_TXS0_BIP_ERROR		BIT(19)
++
++#define MT_TXS0_QUEUE_TIMEOUT		BIT(18)
++#define MT_TXS0_RTS_TIMEOUT		BIT(17)
++#define MT_TXS0_ACK_TIMEOUT		BIT(16)
++#define MT_TXS0_ACK_ERROR_MASK		GENMASK(18, 16)
++
++#define MT_TXS0_TX_STATUS_HOST		BIT(15)
++#define MT_TXS0_TX_STATUS_MCU		BIT(14)
++#define MT_TXS0_TX_RATE			GENMASK(13, 0)
++
++#define MT_TXS1_SEQNO			GENMASK(31, 20)
++#define MT_TXS1_RESP_RATE		GENMASK(19, 16)
++#define MT_TXS1_RXV_SEQNO		GENMASK(15, 8)
++#define MT_TXS1_TX_POWER_DBM		GENMASK(7, 0)
++
++#define MT_TXS2_BF_STATUS		GENMASK(31, 30)
++#define MT_TXS2_BAND			GENMASK(29, 28)
++#define MT_TXS2_WCID			GENMASK(27, 16)
++#define MT_TXS2_TX_DELAY		GENMASK(15, 0)
++
++#define MT_TXS3_PID			GENMASK(31, 24)
++#define MT_TXS3_RATE_STBC		BIT(7)
++#define MT_TXS3_FIXED_RATE		BIT(6)
++#define MT_TXS3_SRC			GENMASK(5, 4)
++#define MT_TXS3_SHARED_ANTENNA		BIT(3)
++#define MT_TXS3_LAST_TX_RATE		GENMASK(2, 0)
++
++#define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
++
++#define MT_TXS5_F0_FINAL_MPDU		BIT(31)
++#define MT_TXS5_F0_QOS			BIT(30)
++#define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)
++#define MT_TXS5_F0_FRONT_TIME		GENMASK(24, 0)
++#define MT_TXS5_F1_MPDU_TX_COUNT	GENMASK(31, 24)
++#define MT_TXS5_F1_MPDU_TX_BYTES	GENMASK(23, 0)
++
++#define MT_TXS6_F0_NOISE_3		GENMASK(31, 24)
++#define MT_TXS6_F0_NOISE_2		GENMASK(23, 16)
++#define MT_TXS6_F0_NOISE_1		GENMASK(15, 8)
++#define MT_TXS6_F0_NOISE_0		GENMASK(7, 0)
++#define MT_TXS6_F1_MPDU_FAIL_COUNT	GENMASK(31, 24)
++#define MT_TXS6_F1_MPDU_FAIL_BYTES	GENMASK(23, 0)
++
++#define MT_TXS7_F0_RCPI_3		GENMASK(31, 24)
++#define MT_TXS7_F0_RCPI_2		GENMASK(23, 16)
++#define MT_TXS7_F0_RCPI_1		GENMASK(15, 8)
++#define MT_TXS7_F0_RCPI_0		GENMASK(7, 0)
++#define MT_TXS7_F1_MPDU_RETRY_COUNT	GENMASK(31, 24)
++#define MT_TXS7_F1_MPDU_RETRY_BYTES	GENMASK(23, 0)
++
++#endif /* __MT76_CONNAC3_MAC_H */
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index ee0fbfcd..ee5177fd 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -495,6 +495,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ 				    BSS_CHANGED_BEACON_ENABLED));
+ 	bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
+ 					 BSS_CHANGED_FILS_DISCOVERY));
++	bool amsdu_en = wcid->amsdu;
+ 
+ 	if (vif) {
+ 		struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
+@@ -521,9 +522,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ 		q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
+ 			mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
+ 
+-		/* counting non-offloading skbs */
+-		wcid->stats.tx_bytes += skb->len;
+-		wcid->stats.tx_packets++;
++		/* mt7915 WA only counts WED path */
++		if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed))
++			wcid->stats.tx_packets++;
+ 	}
+ 
+ 	val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
+@@ -554,12 +555,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ 	txwi[4] = 0;
+ 
+ 	val = FIELD_PREP(MT_TXD5_PID, pid);
+-	if (pid >= MT_PACKET_ID_FIRST)
++	if (pid >= MT_PACKET_ID_FIRST) {
+ 		val |= MT_TXD5_TX_STATUS_HOST;
++		amsdu_en = amsdu_en && !is_mt7921(dev);
++	}
+ 
+ 	txwi[5] = cpu_to_le32(val);
+ 	txwi[6] = 0;
+-	txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
++	txwi[7] = amsdu_en ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
+ 
+ 	if (is_8023)
+ 		mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid);
+@@ -606,11 +609,11 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ 	txs = le32_to_cpu(txs_data[0]);
+ 
+ 	/* PPDU based reporting */
+-	if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
++	if (mtk_wed_device_active(&dev->mmio.wed) &&
++	    FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
+ 		stats->tx_bytes +=
+-			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE);
+-		stats->tx_packets +=
+-			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
++			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
++			le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
+ 		stats->tx_failed +=
+ 			le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
+ 		stats->tx_retries +=
+@@ -728,17 +731,15 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ 	skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
+ 	if (skb) {
+ 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+-		bool noacked = !(info->flags & IEEE80211_TX_STAT_ACK);
+ 
+ 		if (!(le32_to_cpu(txs_data[0]) & MT_TXS0_ACK_ERROR_MASK))
+ 			info->flags |= IEEE80211_TX_STAT_ACK;
+ 
+ 		info->status.ampdu_len = 1;
+-		info->status.ampdu_ack_len = !noacked;
++		info->status.ampdu_ack_len =
++			!!(info->flags & IEEE80211_TX_STAT_ACK);
+ 		info->status.rates[0].idx = -1;
+ 
+-		wcid->stats.tx_failed += noacked;
+-
+ 		mt76_connac2_mac_fill_txs(dev, wcid, txs_data);
+ 		mt76_tx_status_skb_done(dev, skb, &list);
+ 	}
+@@ -1111,3 +1112,85 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(mt76_connac2_mac_fill_rx_rate);
++
++void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
++{
++	struct mt76_wcid *wcid;
++	u16 fc, tid;
++	u32 val;
++
++	if (!sta ||
++	    !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
++		return;
++
++	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
++	if (tid >= 6) /* skip VO queue */
++		return;
++
++	val = le32_to_cpu(txwi[2]);
++	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
++	     FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
++	if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
++		return;
++
++	wcid = (struct mt76_wcid *)sta->drv_priv;
++	if (!test_and_set_bit(tid, &wcid->ampdu_state))
++		ieee80211_start_tx_ba_session(sta, tid, 0);
++}
++EXPORT_SYMBOL_GPL(mt76_connac2_tx_check_aggr);
++
++void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t,
++			    struct ieee80211_sta *sta,
++			    struct list_head *free_list)
++{
++	struct mt76_wcid *wcid;
++	__le32 *txwi;
++	u16 wcid_idx;
++
++	mt76_connac_txp_skb_unmap(dev, t);
++	if (!t->skb)
++		goto out;
++
++	txwi = (__le32 *)mt76_get_txwi_ptr(dev, t);
++	if (sta) {
++		wcid = (struct mt76_wcid *)sta->drv_priv;
++		wcid_idx = wcid->idx;
++	} else {
++		wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
++		wcid = rcu_dereference(dev->wcid[wcid_idx]);
++
++		if (wcid && wcid->sta) {
++			sta = container_of((void *)wcid, struct ieee80211_sta,
++					   drv_priv);
++			spin_lock_bh(&dev->sta_poll_lock);
++			if (list_empty(&wcid->poll_list))
++				list_add_tail(&wcid->poll_list,
++					      &dev->sta_poll_list);
++			spin_unlock_bh(&dev->sta_poll_lock);
++		}
++	}
++
++	if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
++		mt76_connac2_tx_check_aggr(sta, txwi);
++
++	__mt76_tx_complete_skb(dev, wcid_idx, t->skb, free_list);
++out:
++	t->skb = NULL;
++	mt76_put_txwi(dev, t);
++}
++EXPORT_SYMBOL_GPL(mt76_connac2_txwi_free);
++
++void mt76_connac2_tx_token_put(struct mt76_dev *dev)
++{
++	struct mt76_txwi_cache *txwi;
++	int id;
++
++	spin_lock_bh(&dev->token_lock);
++	idr_for_each_entry(&dev->token, txwi, id) {
++		mt76_connac2_txwi_free(dev, txwi, NULL, NULL);
++		dev->token_count--;
++	}
++	spin_unlock_bh(&dev->token_lock);
++	idr_destroy(&dev->token);
++}
++EXPORT_SYMBOL_GPL(mt76_connac2_tx_token_put);
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 46f69aa8..0f0a519f 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -1221,6 +1221,9 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
+ 
+ int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb)
+ {
++	if (!mt76_is_mmio(dev))
++		return 0;
++
+ 	if (!mtk_wed_device_active(&dev->mmio.wed))
+ 		return 0;
+ 
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 91d98eff..fe729bbf 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -22,6 +22,7 @@
+ 
+ #define FW_START_OVERRIDE		BIT(0)
+ #define FW_START_WORKING_PDA_CR4	BIT(2)
++#define FW_START_WORKING_PDA_DSP	BIT(3)
+ 
+ #define PATCH_SEC_NOT_SUPPORT		GENMASK(31, 0)
+ #define PATCH_SEC_TYPE_MASK		GENMASK(15, 0)
+@@ -518,7 +519,8 @@ struct sta_rec_muru {
+ 		u8 uo_ra;
+ 		u8 he_2x996_tone;
+ 		u8 rx_t_frame_11ac;
+-		u8 rsv[3];
++		u8 rx_ctrl_frame_to_mbss;
++		u8 rsv[2];
+ 	} ofdma_ul;
+ 
+ 	struct {
+@@ -998,6 +1000,7 @@ enum {
+ 	MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
+ 	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
+ 	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
++	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
+ 	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
+ 	MCU_EXT_EVENT_MURU_CTRL = 0x9f,
+ };
+@@ -1287,6 +1290,7 @@ enum {
+ 	UNI_BSS_INFO_UAPSD = 19,
+ 	UNI_BSS_INFO_PS = 21,
+ 	UNI_BSS_INFO_BCNFT = 22,
++	UNI_BSS_INFO_IFS_TIME = 23,
+ 	UNI_BSS_INFO_OFFLOAD = 25,
+ 	UNI_BSS_INFO_MLD = 26,
+ };
+diff --git a/mt76x02_util.c b/mt76x02_util.c
+index dcbb5c60..a9b77083 100644
+--- a/mt76x02_util.c
++++ b/mt76x02_util.c
+@@ -413,12 +413,9 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 	struct mt76x02_sta *msta;
+ 	struct mt76_wcid *wcid;
+ 	int idx = key->keyidx;
+-	int ret;
+ 
+ 	/* fall back to sw encryption for unsupported ciphers */
+ 	switch (key->cipher) {
+-	case WLAN_CIPHER_SUITE_WEP40:
+-	case WLAN_CIPHER_SUITE_WEP104:
+ 	case WLAN_CIPHER_SUITE_TKIP:
+ 	case WLAN_CIPHER_SUITE_CCMP:
+ 		break;
+@@ -471,16 +468,6 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ 	}
+ 	mt76_wcid_key_setup(&dev->mt76, wcid, key);
+ 
+-	if (!msta) {
+-		if (key || wcid->hw_key_idx == idx) {
+-			ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key);
+-			if (ret)
+-				return ret;
+-		}
+-
+-		return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key);
+-	}
+-
+ 	return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key);
+ }
+ EXPORT_SYMBOL_GPL(mt76x02_set_key);
+diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
+index 879884ea..6c3696c8 100644
+--- a/mt7915/debugfs.c
++++ b/mt7915/debugfs.c
+@@ -251,7 +251,6 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ {
+ 	struct mt7915_phy *phy = file->private;
+ 	struct mt7915_dev *dev = phy->dev;
+-	struct mt7915_mcu_muru_stats mu_stats = {};
+ 	static const char * const dl_non_he_type[] = {
+ 		"CCK", "OFDM", "HT MIX", "HT GF",
+ 		"VHT SU", "VHT 2MU", "VHT 3MU", "VHT 4MU"
+@@ -275,7 +274,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 
+-	ret = mt7915_mcu_muru_debug_get(phy, &mu_stats);
++	ret = mt7915_mcu_muru_debug_get(phy);
+ 	if (ret)
+ 		goto exit;
+ 
+@@ -285,14 +284,13 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 	for (i = 0; i < 5; i++)
+ 		seq_printf(file, "%8s | ", dl_non_he_type[i]);
+ 
+-#define __dl_u32(s)     le32_to_cpu(mu_stats.dl.s)
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | %8u | %8u | %8u | ",
+-		   __dl_u32(cck_cnt),
+-		   __dl_u32(ofdm_cnt),
+-		   __dl_u32(htmix_cnt),
+-		   __dl_u32(htgf_cnt),
+-		   __dl_u32(vht_su_cnt));
++		   phy->mib.dl_cck_cnt,
++		   phy->mib.dl_ofdm_cnt,
++		   phy->mib.dl_htmix_cnt,
++		   phy->mib.dl_htgf_cnt,
++		   phy->mib.dl_vht_su_cnt);
+ 
+ 	seq_puts(file, "\nDownlink MU-MIMO\nData Type:  ");
+ 
+@@ -301,23 +299,23 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | %8u | ",
+-		   __dl_u32(vht_2mu_cnt),
+-		   __dl_u32(vht_3mu_cnt),
+-		   __dl_u32(vht_4mu_cnt));
++		   phy->mib.dl_vht_2mu_cnt,
++		   phy->mib.dl_vht_3mu_cnt,
++		   phy->mib.dl_vht_4mu_cnt);
+ 
+-	sub_total_cnt = __dl_u32(vht_2mu_cnt) +
+-		__dl_u32(vht_3mu_cnt) +
+-		__dl_u32(vht_4mu_cnt);
++	sub_total_cnt = phy->mib.dl_vht_2mu_cnt +
++			phy->mib.dl_vht_3mu_cnt +
++			phy->mib.dl_vht_4mu_cnt;
+ 
+ 	seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld",
+ 		   sub_total_cnt);
+ 
+ 	total_ppdu_cnt = sub_total_cnt +
+-		__dl_u32(cck_cnt) +
+-		__dl_u32(ofdm_cnt) +
+-		__dl_u32(htmix_cnt) +
+-		__dl_u32(htgf_cnt) +
+-		__dl_u32(vht_su_cnt);
++			 phy->mib.dl_cck_cnt +
++			 phy->mib.dl_ofdm_cnt +
++			 phy->mib.dl_htmix_cnt +
++			 phy->mib.dl_htgf_cnt +
++			 phy->mib.dl_vht_su_cnt;
+ 
+ 	seq_printf(file, "\nAll non-HE DL PPDU count: %lld", total_ppdu_cnt);
+ 
+@@ -329,8 +327,7 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | ",
+-		   __dl_u32(he_su_cnt),
+-		   __dl_u32(he_ext_su_cnt));
++		   phy->mib.dl_he_su_cnt, phy->mib.dl_he_ext_su_cnt);
+ 
+ 	seq_puts(file, "\nDownlink MU-MIMO\nData Type:  ");
+ 
+@@ -339,9 +336,8 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | %8u | ",
+-		   __dl_u32(he_2mu_cnt),
+-		   __dl_u32(he_3mu_cnt),
+-		   __dl_u32(he_4mu_cnt));
++		   phy->mib.dl_he_2mu_cnt, phy->mib.dl_he_3mu_cnt,
++		   phy->mib.dl_he_4mu_cnt);
+ 
+ 	seq_puts(file, "\nDownlink OFDMA\nData Type:  ");
+ 
+@@ -350,37 +346,35 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | %8u | %8u | %9u | %8u | ",
+-		   __dl_u32(he_2ru_cnt),
+-		   __dl_u32(he_3ru_cnt),
+-		   __dl_u32(he_4ru_cnt),
+-		   __dl_u32(he_5to8ru_cnt),
+-		   __dl_u32(he_9to16ru_cnt),
+-		   __dl_u32(he_gtr16ru_cnt));
+-
+-	sub_total_cnt = __dl_u32(he_2mu_cnt) +
+-		__dl_u32(he_3mu_cnt) +
+-		__dl_u32(he_4mu_cnt);
++		   phy->mib.dl_he_2ru_cnt,
++		   phy->mib.dl_he_3ru_cnt,
++		   phy->mib.dl_he_4ru_cnt,
++		   phy->mib.dl_he_5to8ru_cnt,
++		   phy->mib.dl_he_9to16ru_cnt,
++		   phy->mib.dl_he_gtr16ru_cnt);
++
++	sub_total_cnt = phy->mib.dl_he_2mu_cnt +
++			phy->mib.dl_he_3mu_cnt +
++			phy->mib.dl_he_4mu_cnt;
+ 	total_ppdu_cnt = sub_total_cnt;
+ 
+ 	seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld",
+ 		   sub_total_cnt);
+ 
+-	sub_total_cnt = __dl_u32(he_2ru_cnt) +
+-		__dl_u32(he_3ru_cnt) +
+-		__dl_u32(he_4ru_cnt) +
+-		__dl_u32(he_5to8ru_cnt) +
+-		__dl_u32(he_9to16ru_cnt) +
+-		__dl_u32(he_gtr16ru_cnt);
++	sub_total_cnt = phy->mib.dl_he_2ru_cnt +
++			phy->mib.dl_he_3ru_cnt +
++			phy->mib.dl_he_4ru_cnt +
++			phy->mib.dl_he_5to8ru_cnt +
++			phy->mib.dl_he_9to16ru_cnt +
++			phy->mib.dl_he_gtr16ru_cnt;
+ 	total_ppdu_cnt += sub_total_cnt;
+ 
+ 	seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld",
+ 		   sub_total_cnt);
+ 
+-	total_ppdu_cnt += __dl_u32(he_su_cnt) +
+-		__dl_u32(he_ext_su_cnt);
++	total_ppdu_cnt += phy->mib.dl_he_su_cnt + phy->mib.dl_he_ext_su_cnt;
+ 
+ 	seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt);
+-#undef __dl_u32
+ 
+ 	/* HE Uplink */
+ 	seq_puts(file, "\n\nUplink");
+@@ -389,12 +383,11 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 	for (i = 0; i < 3; i++)
+ 		seq_printf(file, "%8s | ", ul_he_type[i]);
+ 
+-#define __ul_u32(s)     le32_to_cpu(mu_stats.ul.s)
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | %8u | ",
+-		   __ul_u32(hetrig_2mu_cnt),
+-		   __ul_u32(hetrig_3mu_cnt),
+-		   __ul_u32(hetrig_4mu_cnt));
++		   phy->mib.ul_hetrig_2mu_cnt,
++		   phy->mib.ul_hetrig_3mu_cnt,
++		   phy->mib.ul_hetrig_4mu_cnt);
+ 
+ 	seq_puts(file, "\nTrigger-based Uplink OFDMA\nData Type:  ");
+ 
+@@ -403,37 +396,36 @@ static int mt7915_muru_stats_show(struct seq_file *file, void *data)
+ 
+ 	seq_puts(file, "\nTotal Count:");
+ 	seq_printf(file, "%8u | %8u | %8u | %8u | %8u | %9u |  %7u | ",
+-		   __ul_u32(hetrig_su_cnt),
+-		   __ul_u32(hetrig_2ru_cnt),
+-		   __ul_u32(hetrig_3ru_cnt),
+-		   __ul_u32(hetrig_4ru_cnt),
+-		   __ul_u32(hetrig_5to8ru_cnt),
+-		   __ul_u32(hetrig_9to16ru_cnt),
+-		   __ul_u32(hetrig_gtr16ru_cnt));
+-
+-	sub_total_cnt = __ul_u32(hetrig_2mu_cnt) +
+-		__ul_u32(hetrig_3mu_cnt) +
+-		__ul_u32(hetrig_4mu_cnt);
++		   phy->mib.ul_hetrig_su_cnt,
++		   phy->mib.ul_hetrig_2ru_cnt,
++		   phy->mib.ul_hetrig_3ru_cnt,
++		   phy->mib.ul_hetrig_4ru_cnt,
++		   phy->mib.ul_hetrig_5to8ru_cnt,
++		   phy->mib.ul_hetrig_9to16ru_cnt,
++		   phy->mib.ul_hetrig_gtr16ru_cnt);
++
++	sub_total_cnt = phy->mib.ul_hetrig_2mu_cnt +
++			phy->mib.ul_hetrig_3mu_cnt +
++			phy->mib.ul_hetrig_4mu_cnt;
+ 	total_ppdu_cnt = sub_total_cnt;
+ 
+ 	seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld",
+ 		   sub_total_cnt);
+ 
+-	sub_total_cnt = __ul_u32(hetrig_2ru_cnt) +
+-		__ul_u32(hetrig_3ru_cnt) +
+-		__ul_u32(hetrig_4ru_cnt) +
+-		__ul_u32(hetrig_5to8ru_cnt) +
+-		__ul_u32(hetrig_9to16ru_cnt) +
+-		__ul_u32(hetrig_gtr16ru_cnt);
++	sub_total_cnt = phy->mib.ul_hetrig_2ru_cnt +
++			phy->mib.ul_hetrig_3ru_cnt +
++			phy->mib.ul_hetrig_4ru_cnt +
++			phy->mib.ul_hetrig_5to8ru_cnt +
++			phy->mib.ul_hetrig_9to16ru_cnt +
++			phy->mib.ul_hetrig_gtr16ru_cnt;
+ 	total_ppdu_cnt += sub_total_cnt;
+ 
+ 	seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld",
+ 		   sub_total_cnt);
+ 
+-	total_ppdu_cnt += __ul_u32(hetrig_su_cnt);
++	total_ppdu_cnt += phy->mib.ul_hetrig_su_cnt;
+ 
+ 	seq_printf(file, "\nAll HE UL TB PPDU count: %lld\n", total_ppdu_cnt);
+-#undef __ul_u32
+ 
+ exit:
+ 	mutex_unlock(&dev->mt76.mutex);
+@@ -719,10 +711,10 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
+ static void
+ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
+ {
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	static const char * const bw[] = {
+ 		"BW20", "BW40", "BW80", "BW160"
+ 	};
+-	struct mib_stats *mib = &phy->mib;
+ 
+ 	/* Tx Beamformer monitor */
+ 	seq_puts(s, "\nTx Beamformer applied PPDU counts: ");
+@@ -768,7 +760,7 @@ mt7915_tx_stats_show(struct seq_file *file, void *data)
+ {
+ 	struct mt7915_phy *phy = file->private;
+ 	struct mt7915_dev *dev = phy->dev;
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	int i;
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+diff --git a/mt7915/dma.c b/mt7915/dma.c
+index 86a93ded..59a44d79 100644
+--- a/mt7915/dma.c
++++ b/mt7915/dma.c
+@@ -250,12 +250,90 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst)
+ 	}
+ }
+ 
+-static int mt7915_dma_enable(struct mt7915_dev *dev)
++int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset)
+ {
+ 	struct mt76_dev *mdev = &dev->mt76;
+ 	u32 hif1_ofs = 0;
+ 	u32 irq_mask;
+ 
++	if (dev->hif2)
++		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++	/* enable wpdma tx/rx */
++	if (!reset) {
++		mt76_set(dev, MT_WFDMA0_GLO_CFG,
++			MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++			MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++			MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++			MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++		if (is_mt7915(mdev))
++			mt76_set(dev, MT_WFDMA1_GLO_CFG,
++				MT_WFDMA1_GLO_CFG_TX_DMA_EN |
++				MT_WFDMA1_GLO_CFG_RX_DMA_EN |
++				MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
++				MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
++
++		if (dev->hif2) {
++			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
++				MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++				MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++				MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++				MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++			if (is_mt7915(mdev))
++				mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
++					MT_WFDMA1_GLO_CFG_TX_DMA_EN |
++					MT_WFDMA1_GLO_CFG_RX_DMA_EN |
++					MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
++					MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
++
++			mt76_set(dev, MT_WFDMA_HOST_CONFIG,
++				MT_WFDMA_HOST_CONFIG_PDMA_BAND);
++		}
++	}
++
++	/* enable interrupts for TX/RX rings */
++	irq_mask = MT_INT_RX_DONE_MCU |
++		   MT_INT_TX_DONE_MCU |
++		   MT_INT_MCU_CMD;
++
++	if (!dev->phy.mt76->band_idx)
++		irq_mask |= MT_INT_BAND0_RX_DONE;
++
++	if (dev->dbdc_support || dev->phy.mt76->band_idx)
++		irq_mask |= MT_INT_BAND1_RX_DONE;
++
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
++		u32 wed_irq_mask = irq_mask;
++		int ret;
++
++		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
++		if (!is_mt798x(&dev->mt76))
++			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
++		else
++			mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++
++		ret = mt7915_mcu_wed_enable_rx_stats(dev);
++		if (ret)
++			return ret;
++
++		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
++	}
++
++	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
++
++	mt7915_irq_enable(dev, irq_mask);
++	mt7915_irq_disable(dev, 0);
++
++	return 0;
++}
++
++static int mt7915_dma_enable(struct mt7915_dev *dev, bool reset)
++{
++	struct mt76_dev *mdev = &dev->mt76;
++	u32 hif1_ofs = 0;
++
+ 	if (dev->hif2)
+ 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+ 
+@@ -322,69 +400,7 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
+ 	mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
+ 		  MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
+ 
+-	/* set WFDMA Tx/Rx */
+-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
+-		 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+-		 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+-		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+-		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+-	if (is_mt7915(mdev))
+-		mt76_set(dev, MT_WFDMA1_GLO_CFG,
+-			 MT_WFDMA1_GLO_CFG_TX_DMA_EN |
+-			 MT_WFDMA1_GLO_CFG_RX_DMA_EN |
+-			 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
+-			 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
+-
+-	if (dev->hif2) {
+-		mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
+-			 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+-			 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+-			 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+-			 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+-		if (is_mt7915(mdev))
+-			mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
+-				 MT_WFDMA1_GLO_CFG_TX_DMA_EN |
+-				 MT_WFDMA1_GLO_CFG_RX_DMA_EN |
+-				 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
+-				 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
+-
+-		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
+-			 MT_WFDMA_HOST_CONFIG_PDMA_BAND);
+-	}
+-
+-	/* enable interrupts for TX/RX rings */
+-	irq_mask = MT_INT_RX_DONE_MCU |
+-		   MT_INT_TX_DONE_MCU |
+-		   MT_INT_MCU_CMD;
+-
+-	if (!dev->phy.mt76->band_idx)
+-		irq_mask |= MT_INT_BAND0_RX_DONE;
+-
+-	if (dev->dbdc_support || dev->phy.mt76->band_idx)
+-		irq_mask |= MT_INT_BAND1_RX_DONE;
+-
+-	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+-		u32 wed_irq_mask = irq_mask;
+-		int ret;
+-
+-		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
+-		if (!is_mt798x(&dev->mt76))
+-			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
+-		else
+-			mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+-
+-		ret = mt7915_mcu_wed_enable_rx_stats(dev);
+-		if (ret)
+-			return ret;
+-
+-		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
+-	}
+-
+-	mt7915_irq_enable(dev, irq_mask);
+-
+-	return 0;
++	return mt7915_dma_start(dev, reset, true);
+ }
+ 
+ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+@@ -560,7 +576,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ 			  mt7915_poll_tx);
+ 	napi_enable(&dev->mt76.tx_napi);
+ 
+-	mt7915_dma_enable(dev);
++	mt7915_dma_enable(dev, false);
+ 
+ 	return 0;
+ }
+@@ -642,7 +658,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
+ 		mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP,
+ 			 MT_WFDMA0_EXT0_RXWB_KEEP);
+ 
+-	mt7915_dma_enable(dev);
++	mt7915_dma_enable(dev, !force);
+ 
+ 	return 0;
+ }
+diff --git a/mt7915/init.c b/mt7915/init.c
+index f85f7d39..e156a3c2 100644
+--- a/mt7915/init.c
++++ b/mt7915/init.c
+@@ -505,6 +505,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
+ 	set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |
+ 	      FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);
+ 	mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
++
++	/* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
++	 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
++	 */
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++		mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
+ }
+ 
+ static void
+@@ -587,6 +593,8 @@ void mt7915_mac_init(struct mt7915_dev *dev)
+ 
+ 	if (!is_mt7915(&dev->mt76))
+ 		mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT);
++	else
++		mt76_clear(dev, MT_PLE_HOST_RPT0, MT_PLE_HOST_RPT0_TX_LATENCY);
+ 
+ 	/* enable hardware de-agg */
+ 	mt76_set(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);
+@@ -1164,7 +1172,7 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
+ static void mt7915_stop_hardware(struct mt7915_dev *dev)
+ {
+ 	mt7915_mcu_exit(dev);
+-	mt7915_tx_token_put(dev);
++	mt76_connac2_tx_token_put(&dev->mt76);
+ 	mt7915_dma_cleanup(dev);
+ 	tasklet_disable(&dev->mt76.irq_tasklet);
+ 
+@@ -1183,9 +1191,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
+ 	INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);
+ 	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
+ 	INIT_LIST_HEAD(&dev->sta_rc_list);
+-	INIT_LIST_HEAD(&dev->sta_poll_list);
+ 	INIT_LIST_HEAD(&dev->twt_list);
+-	spin_lock_init(&dev->sta_poll_lock);
+ 
+ 	init_waitqueue_head(&dev->reset_wait);
+ 	INIT_WORK(&dev->reset_work, mt7915_mac_reset_work);
+diff --git a/mt7915/mac.c b/mt7915/mac.c
+index fb6bab87..b8b0c0fd 100644
+--- a/mt7915/mac.c
++++ b/mt7915/mac.c
+@@ -105,9 +105,9 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
+ 	LIST_HEAD(sta_poll_list);
+ 	int i;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	list_splice_init(&dev->sta_poll_list, &sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	rcu_read_lock();
+ 
+@@ -118,15 +118,15 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
+ 		s8 rssi[4];
+ 		u8 bw;
+ 
+-		spin_lock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 		if (list_empty(&sta_poll_list)) {
+-			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 			break;
+ 		}
+ 		msta = list_first_entry(&sta_poll_list,
+-					struct mt7915_sta, poll_list);
+-		list_del_init(&msta->poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++					struct mt7915_sta, wcid.poll_list);
++		list_del_init(&msta->wcid.poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		idx = msta->wcid.idx;
+ 
+@@ -326,10 +326,11 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
+ 
+ 	if (status->wcid) {
+ 		msta = container_of(status->wcid, struct mt7915_sta, wcid);
+-		spin_lock_bh(&dev->sta_poll_lock);
+-		if (list_empty(&msta->poll_list))
+-			list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		if (list_empty(&msta->wcid.poll_list))
++			list_add_tail(&msta->wcid.poll_list,
++				      &dev->mt76.sta_poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+ 	status->freq = mphy->chandef.chan->center_freq;
+@@ -841,74 +842,6 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
+ 	return MT_TXD_SIZE + sizeof(*txp);
+ }
+ 
+-static void
+-mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+-{
+-	struct mt7915_sta *msta;
+-	u16 fc, tid;
+-	u32 val;
+-
+-	if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
+-		return;
+-
+-	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
+-	if (tid >= 6) /* skip VO queue */
+-		return;
+-
+-	val = le32_to_cpu(txwi[2]);
+-	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
+-	     FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
+-	if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
+-		return;
+-
+-	msta = (struct mt7915_sta *)sta->drv_priv;
+-	if (!test_and_set_bit(tid, &msta->ampdu_state))
+-		ieee80211_start_tx_ba_session(sta, tid, 0);
+-}
+-
+-static void
+-mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t,
+-		 struct ieee80211_sta *sta, struct list_head *free_list)
+-{
+-	struct mt76_dev *mdev = &dev->mt76;
+-	struct mt7915_sta *msta;
+-	struct mt76_wcid *wcid;
+-	__le32 *txwi;
+-	u16 wcid_idx;
+-
+-	mt76_connac_txp_skb_unmap(mdev, t);
+-	if (!t->skb)
+-		goto out;
+-
+-	txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
+-	if (sta) {
+-		wcid = (struct mt76_wcid *)sta->drv_priv;
+-		wcid_idx = wcid->idx;
+-	} else {
+-		wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
+-		wcid = rcu_dereference(dev->mt76.wcid[wcid_idx]);
+-
+-		if (wcid && wcid->sta) {
+-			msta = container_of(wcid, struct mt7915_sta, wcid);
+-			sta = container_of((void *)msta, struct ieee80211_sta,
+-					  drv_priv);
+-			spin_lock_bh(&dev->sta_poll_lock);
+-			if (list_empty(&msta->poll_list))
+-				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-			spin_unlock_bh(&dev->sta_poll_lock);
+-		}
+-	}
+-
+-	if (sta && likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
+-		mt7915_tx_check_aggr(sta, txwi);
+-
+-	__mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
+-
+-out:
+-	t->skb = NULL;
+-	mt76_put_txwi(mdev, t);
+-}
+-
+ static void
+ mt7915_mac_tx_free_prepare(struct mt7915_dev *dev)
+ {
+@@ -951,6 +884,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ 	struct mt76_dev *mdev = &dev->mt76;
+ 	struct mt76_txwi_cache *txwi;
+ 	struct ieee80211_sta *sta = NULL;
++	struct mt76_wcid *wcid = NULL;
+ 	LIST_HEAD(free_list);
+ 	void *end = data + len;
+ 	bool v3, wake = false;
+@@ -977,7 +911,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ 		info = le32_to_cpu(*cur_info);
+ 		if (info & MT_TX_FREE_PAIR) {
+ 			struct mt7915_sta *msta;
+-			struct mt76_wcid *wcid;
+ 			u16 idx;
+ 
+ 			idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
+@@ -987,14 +920,33 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ 				continue;
+ 
+ 			msta = container_of(wcid, struct mt7915_sta, wcid);
+-			spin_lock_bh(&dev->sta_poll_lock);
+-			if (list_empty(&msta->poll_list))
+-				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_lock_bh(&mdev->sta_poll_lock);
++			if (list_empty(&msta->wcid.poll_list))
++				list_add_tail(&msta->wcid.poll_list,
++					      &mdev->sta_poll_list);
++			spin_unlock_bh(&mdev->sta_poll_lock);
+ 			continue;
+ 		}
+ 
+-		if (v3 && (info & MT_TX_FREE_MPDU_HEADER))
++		if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) {
++			u32 tx_retries = 0, tx_failed = 0;
++
++			if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3)) {
++				tx_retries =
++					FIELD_GET(MT_TX_FREE_COUNT_V3, info) - 1;
++				tx_failed = tx_retries +
++					!!FIELD_GET(MT_TX_FREE_STAT_V3, info);
++			} else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER)) {
++				tx_retries =
++					FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
++				tx_failed = tx_retries +
++					!!FIELD_GET(MT_TX_FREE_STAT, info);
++			}
++			wcid->stats.tx_retries += tx_retries;
++			wcid->stats.tx_failed += tx_failed;
++		}
++
++		if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
+ 			continue;
+ 
+ 		for (i = 0; i < 1 + v3; i++) {
+@@ -1010,7 +962,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ 			if (!txwi)
+ 				continue;
+ 
+-			mt7915_txwi_free(dev, txwi, sta, &free_list);
++			mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
+ 		}
+ 	}
+ 
+@@ -1042,7 +994,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
+ 		if (!txwi)
+ 			continue;
+ 
+-		mt7915_txwi_free(dev, txwi, NULL, &free_list);
++		mt76_connac2_txwi_free(mdev, txwi, NULL, &free_list);
+ 	}
+ 
+ 	mt7915_mac_tx_free_done(dev, &free_list, wake);
+@@ -1081,10 +1033,10 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
+ 	if (!wcid->sta)
+ 		goto out;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (list_empty(&msta->poll_list))
+-		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (list_empty(&msta->wcid.poll_list))
++		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ out:
+ 	rcu_read_unlock();
+@@ -1357,20 +1309,6 @@ mt7915_update_beacons(struct mt7915_dev *dev)
+ 		mt7915_update_vif_beacon, mphy_ext->hw);
+ }
+ 
+-void mt7915_tx_token_put(struct mt7915_dev *dev)
+-{
+-	struct mt76_txwi_cache *txwi;
+-	int id;
+-
+-	spin_lock_bh(&dev->mt76.token_lock);
+-	idr_for_each_entry(&dev->mt76.token, txwi, id) {
+-		mt7915_txwi_free(dev, txwi, NULL, NULL);
+-		dev->mt76.token_count--;
+-	}
+-	spin_unlock_bh(&dev->mt76.token_lock);
+-	idr_destroy(&dev->mt76.token);
+-}
+-
+ static int
+ mt7915_mac_restart(struct mt7915_dev *dev)
+ {
+@@ -1389,8 +1327,12 @@ mt7915_mac_restart(struct mt7915_dev *dev)
+ 
+ 	if (dev_is_pci(mdev->dev)) {
+ 		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
+-		if (dev->hif2)
+-			mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
++		if (dev->hif2) {
++			if (is_mt7915(mdev))
++				mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0x0);
++			else
++				mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0x0);
++		}
+ 	}
+ 
+ 	set_bit(MT76_RESET, &dev->mphy.state);
+@@ -1415,7 +1357,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
+ 	napi_disable(&dev->mt76.tx_napi);
+ 
+ 	/* token reinit */
+-	mt7915_tx_token_put(dev);
++	mt76_connac2_tx_token_put(&dev->mt76);
+ 	idr_init(&dev->mt76.token);
+ 
+ 	mt7915_dma_reset(dev, true);
+@@ -1440,8 +1382,12 @@ mt7915_mac_restart(struct mt7915_dev *dev)
+ 	}
+ 	if (dev_is_pci(mdev->dev)) {
+ 		mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
+-		if (dev->hif2)
+-			mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
++		if (dev->hif2) {
++			if (is_mt7915(mdev))
++				mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
++			else
++				mt76_wr(dev, MT_PCIE1_MAC_INT_ENABLE_MT7916, 0xff);
++		}
+ 	}
+ 
+ 	/* load firmware */
+@@ -1604,13 +1550,19 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 	if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) {
+ 		mt7915_dma_reset(dev, false);
+ 
+-		mt7915_tx_token_put(dev);
++		mt76_connac2_tx_token_put(&dev->mt76);
+ 		idr_init(&dev->mt76.token);
+ 
+ 		mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_INIT);
+ 		mt7915_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
+ 	}
+ 
++	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
++	mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
++
++	/* enable DMA Tx/Rx and interrupt */
++	mt7915_dma_start(dev, false, false);
++
+ 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ 	clear_bit(MT76_RESET, &dev->mphy.state);
+ 	if (phy2)
+@@ -1625,9 +1577,6 @@ void mt7915_mac_reset_work(struct work_struct *work)
+ 
+ 	tasklet_schedule(&dev->mt76.irq_tasklet);
+ 
+-	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
+-	mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+-
+ 	mt76_worker_enable(&dev->mt76.tx_worker);
+ 
+ 	local_bh_disable();
+@@ -1747,8 +1696,8 @@ void mt7915_reset(struct mt7915_dev *dev)
+ 
+ void mt7915_mac_update_stats(struct mt7915_phy *phy)
+ {
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	struct mt7915_dev *dev = phy->dev;
+-	struct mib_stats *mib = &phy->mib;
+ 	int i, aggr0 = 0, aggr1, cnt;
+ 	u8 band = phy->mt76->band_idx;
+ 	u32 val;
+@@ -2010,7 +1959,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
+ 	u32 changed;
+ 	LIST_HEAD(list);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 	list_splice_init(&dev->sta_rc_list, &list);
+ 
+ 	while (!list_empty(&list)) {
+@@ -2018,7 +1967,7 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
+ 		list_del_init(&msta->rc_list);
+ 		changed = msta->changed;
+ 		msta->changed = 0;
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
+ 		vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
+@@ -2031,10 +1980,10 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
+ 		if (changed & IEEE80211_RC_SMPS_CHANGED)
+ 			mt7915_mcu_add_smps(dev, vif, sta);
+ 
+-		spin_lock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ }
+ 
+ void mt7915_mac_work(struct work_struct *work)
+@@ -2054,6 +2003,9 @@ void mt7915_mac_work(struct work_struct *work)
+ 
+ 		mt7915_mac_update_stats(phy);
+ 		mt7915_mac_severe_check(phy);
++
++		if (phy->dev->muru_debug)
++			mt7915_mcu_muru_debug_get(phy);
+ 	}
+ 
+ 	mutex_unlock(&mphy->dev->mutex);
+diff --git a/mt7915/mac.h b/mt7915/mac.h
+index ce94f87e..448b1b38 100644
+--- a/mt7915/mac.h
++++ b/mt7915/mac.h
+@@ -9,7 +9,12 @@
+ #define MT_TX_FREE_VER			GENMASK(18, 16)
+ #define MT_TX_FREE_MSDU_CNT_V0		GENMASK(6, 0)
+ /* 0: success, others: dropped */
+-#define MT_TX_FREE_MPDU_HEADER		BIT(30)
++#define MT_TX_FREE_COUNT		GENMASK(12, 0)
++#define MT_TX_FREE_COUNT_V3		GENMASK(27, 24)
++#define MT_TX_FREE_STAT			GENMASK(14, 13)
++#define MT_TX_FREE_STAT_V3		GENMASK(29, 28)
++#define MT_TX_FREE_MPDU_HEADER		BIT(15)
++#define MT_TX_FREE_MPDU_HEADER_V3	BIT(30)
+ #define MT_TX_FREE_MSDU_ID_V3		GENMASK(14, 0)
+ 
+ #define MT_TXS5_F0_FINAL_MPDU		BIT(31)
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 8ce7b1c5..ca5631f5 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -248,7 +248,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
+ 	idx = MT7915_WTBL_RESERVED - mvif->mt76.idx;
+ 
+ 	INIT_LIST_HEAD(&mvif->sta.rc_list);
+-	INIT_LIST_HEAD(&mvif->sta.poll_list);
++	INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
+ 	mvif->sta.wcid.idx = idx;
+ 	mvif->sta.wcid.phy_idx = ext_phy;
+ 	mvif->sta.wcid.hw_key_idx = -1;
+@@ -308,10 +308,10 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
+ 	phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
+ 	mutex_unlock(&dev->mt76.mutex);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	mt76_packet_id_flush(&dev->mt76, &msta->wcid);
+ }
+@@ -629,11 +629,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ 		}
+ 	}
+ 
+-	if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
+-		mt7915_mcu_add_bss_info(phy, vif, true);
+-		mt7915_mcu_add_sta(dev, vif, NULL, true);
+-	}
+-
+ 	/* ensure that enable txcmd_mode after bss_info */
+ 	if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
+ 		mt7915_mcu_set_tx(dev, vif);
+@@ -653,6 +648,37 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ 	mutex_unlock(&dev->mt76.mutex);
+ }
+ 
++static int
++mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++		struct ieee80211_bss_conf *link_conf)
++{
++	struct mt7915_phy *phy = mt7915_hw_phy(hw);
++	struct mt7915_dev *dev = mt7915_hw_dev(hw);
++	int err;
++
++	mutex_lock(&dev->mt76.mutex);
++
++	err = mt7915_mcu_add_bss_info(phy, vif, true);
++	if (err)
++		goto out;
++	err = mt7915_mcu_add_sta(dev, vif, NULL, true);
++out:
++	mutex_unlock(&dev->mt76.mutex);
++
++	return err;
++}
++
++static void
++mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++	       struct ieee80211_bss_conf *link_conf)
++{
++	struct mt7915_dev *dev = mt7915_hw_dev(hw);
++
++	mutex_lock(&dev->mt76.mutex);
++	mt7915_mcu_add_sta(dev, vif, NULL, false);
++	mutex_unlock(&dev->mt76.mutex);
++}
++
+ static void
+ mt7915_channel_switch_beacon(struct ieee80211_hw *hw,
+ 			     struct ieee80211_vif *vif,
+@@ -679,7 +705,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 		return -ENOSPC;
+ 
+ 	INIT_LIST_HEAD(&msta->rc_list);
+-	INIT_LIST_HEAD(&msta->poll_list);
++	INIT_LIST_HEAD(&msta->wcid.poll_list);
+ 	msta->vif = mvif;
+ 	msta->wcid.sta = 1;
+ 	msta->wcid.idx = idx;
+@@ -714,12 +740,12 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
+ 		mt7915_mac_twt_teardown_flow(dev, msta, i);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
++	spin_lock_bh(&mdev->sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
+ 	if (!list_empty(&msta->rc_list))
+ 		list_del_init(&msta->rc_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&mdev->sta_poll_lock);
+ }
+ 
+ static void mt7915_tx(struct ieee80211_hw *hw,
+@@ -801,16 +827,16 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ 	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ 		mtxq->aggr = false;
+-		clear_bit(tid, &msta->ampdu_state);
++		clear_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = mt7915_mcu_add_tx_ba(dev, params, false);
+ 		break;
+ 	case IEEE80211_AMPDU_TX_START:
+-		set_bit(tid, &msta->ampdu_state);
++		set_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
+ 		break;
+ 	case IEEE80211_AMPDU_TX_STOP_CONT:
+ 		mtxq->aggr = false;
+-		clear_bit(tid, &msta->ampdu_state);
++		clear_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = mt7915_mcu_add_tx_ba(dev, params, false);
+ 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ 		break;
+@@ -842,7 +868,7 @@ mt7915_get_stats(struct ieee80211_hw *hw,
+ {
+ 	struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ 	struct mt7915_dev *dev = mt7915_hw_dev(hw);
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 
+@@ -1019,21 +1045,20 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+ 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
+ 	}
+ 
+-	if (!txrate->legacy && !txrate->flags)
+-		return;
+-
+-	if (txrate->legacy) {
+-		sinfo->txrate.legacy = txrate->legacy;
+-	} else {
+-		sinfo->txrate.mcs = txrate->mcs;
+-		sinfo->txrate.nss = txrate->nss;
+-		sinfo->txrate.bw = txrate->bw;
+-		sinfo->txrate.he_gi = txrate->he_gi;
+-		sinfo->txrate.he_dcm = txrate->he_dcm;
+-		sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
++	if (txrate->legacy || txrate->flags) {
++		if (txrate->legacy) {
++			sinfo->txrate.legacy = txrate->legacy;
++		} else {
++			sinfo->txrate.mcs = txrate->mcs;
++			sinfo->txrate.nss = txrate->nss;
++			sinfo->txrate.bw = txrate->bw;
++			sinfo->txrate.he_gi = txrate->he_gi;
++			sinfo->txrate.he_dcm = txrate->he_dcm;
++			sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
++		}
++		sinfo->txrate.flags = txrate->flags;
++		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+ 	}
+-	sinfo->txrate.flags = txrate->flags;
+-	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+ 
+ 	/* offloading flows bypass networking stack, so driver counts and
+ 	 * reports sta statistics via NL80211_STA_INFO when WED is active.
+@@ -1042,14 +1067,10 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+ 		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
+ 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
+ 
+-		sinfo->tx_packets = msta->wcid.stats.tx_packets;
+-		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
+-
+-		sinfo->tx_failed = msta->wcid.stats.tx_failed;
+-		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
+-
+-		sinfo->tx_retries = msta->wcid.stats.tx_retries;
+-		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
++		if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) {
++			sinfo->tx_packets = msta->wcid.stats.tx_packets;
++			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
++		}
+ 
+ 		if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {
+ 			sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
+@@ -1060,6 +1081,12 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
+ 		}
+ 	}
+ 
++	sinfo->tx_failed = msta->wcid.stats.tx_failed;
++	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
++
++	sinfo->tx_retries = msta->wcid.stats.tx_retries;
++	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
++
+ 	sinfo->ack_signal = (s8)msta->ack_signal;
+ 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
+ 
+@@ -1073,11 +1100,11 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
+ 	struct mt7915_dev *dev = msta->vif->phy->dev;
+ 	u32 *changed = data;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 	msta->changed |= *changed;
+ 	if (list_empty(&msta->rc_list))
+ 		list_add_tail(&msta->rc_list, &dev->sta_rc_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ }
+ 
+ static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
+@@ -1253,6 +1280,38 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
+ 	"rx_vec_queue_overflow_drop_cnt",
+ 	"rx_ba_cnt",
+ 
++	/* muru mu-mimo and ofdma related stats */
++	"dl_cck_cnt",
++	"dl_ofdm_cnt",
++	"dl_htmix_cnt",
++	"dl_htgf_cnt",
++	"dl_vht_su_cnt",
++	"dl_vht_2mu_cnt",
++	"dl_vht_3mu_cnt",
++	"dl_vht_4mu_cnt",
++	"dl_he_su_cnt",
++	"dl_he_ext_su_cnt",
++	"dl_he_2ru_cnt",
++	"dl_he_2mu_cnt",
++	"dl_he_3ru_cnt",
++	"dl_he_3mu_cnt",
++	"dl_he_4ru_cnt",
++	"dl_he_4mu_cnt",
++	"dl_he_5to8ru_cnt",
++	"dl_he_9to16ru_cnt",
++	"dl_he_gtr16ru_cnt",
++
++	"ul_hetrig_su_cnt",
++	"ul_hetrig_2ru_cnt",
++	"ul_hetrig_3ru_cnt",
++	"ul_hetrig_4ru_cnt",
++	"ul_hetrig_5to8ru_cnt",
++	"ul_hetrig_9to16ru_cnt",
++	"ul_hetrig_gtr16ru_cnt",
++	"ul_hetrig_2mu_cnt",
++	"ul_hetrig_3mu_cnt",
++	"ul_hetrig_4mu_cnt",
++
+ 	/* per vif counters */
+ 	"v_tx_mode_cck",
+ 	"v_tx_mode_ofdm",
+@@ -1279,6 +1338,10 @@ static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {
+ 	"v_tx_mcs_9",
+ 	"v_tx_mcs_10",
+ 	"v_tx_mcs_11",
++	"v_tx_nss_1",
++	"v_tx_nss_2",
++	"v_tx_nss_3",
++	"v_tx_nss_4",
+ };
+ 
+ #define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)
+@@ -1326,11 +1389,11 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+ 	struct mt7915_dev *dev = mt7915_hw_dev(hw);
+ 	struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ 	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	struct mt76_ethtool_worker_info wi = {
+ 		.data = data,
+ 		.idx = mvif->mt76.idx,
+ 	};
+-	struct mib_stats *mib = &phy->mib;
+ 	/* See mt7915_ampdu_stat_read_phy, etc */
+ 	int i, ei = 0, stats_size;
+ 
+@@ -1403,6 +1466,37 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+ 	data[ei++] = mib->rx_vec_queue_overflow_drop_cnt;
+ 	data[ei++] = mib->rx_ba_cnt;
+ 
++	data[ei++] = mib->dl_cck_cnt;
++	data[ei++] = mib->dl_ofdm_cnt;
++	data[ei++] = mib->dl_htmix_cnt;
++	data[ei++] = mib->dl_htgf_cnt;
++	data[ei++] = mib->dl_vht_su_cnt;
++	data[ei++] = mib->dl_vht_2mu_cnt;
++	data[ei++] = mib->dl_vht_3mu_cnt;
++	data[ei++] = mib->dl_vht_4mu_cnt;
++	data[ei++] = mib->dl_he_su_cnt;
++	data[ei++] = mib->dl_he_ext_su_cnt;
++	data[ei++] = mib->dl_he_2ru_cnt;
++	data[ei++] = mib->dl_he_2mu_cnt;
++	data[ei++] = mib->dl_he_3ru_cnt;
++	data[ei++] = mib->dl_he_3mu_cnt;
++	data[ei++] = mib->dl_he_4ru_cnt;
++	data[ei++] = mib->dl_he_4mu_cnt;
++	data[ei++] = mib->dl_he_5to8ru_cnt;
++	data[ei++] = mib->dl_he_9to16ru_cnt;
++	data[ei++] = mib->dl_he_gtr16ru_cnt;
++
++	data[ei++] = mib->ul_hetrig_su_cnt;
++	data[ei++] = mib->ul_hetrig_2ru_cnt;
++	data[ei++] = mib->ul_hetrig_3ru_cnt;
++	data[ei++] = mib->ul_hetrig_4ru_cnt;
++	data[ei++] = mib->ul_hetrig_5to8ru_cnt;
++	data[ei++] = mib->ul_hetrig_9to16ru_cnt;
++	data[ei++] = mib->ul_hetrig_gtr16ru_cnt;
++	data[ei++] = mib->ul_hetrig_2mu_cnt;
++	data[ei++] = mib->ul_hetrig_3mu_cnt;
++	data[ei++] = mib->ul_hetrig_4mu_cnt;
++
+ 	/* Add values for all stations owned by this vif */
+ 	wi.initial_stat_idx = ei;
+ 	ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi);
+@@ -1540,6 +1634,8 @@ const struct ieee80211_ops mt7915_ops = {
+ 	.conf_tx = mt7915_conf_tx,
+ 	.configure_filter = mt7915_configure_filter,
+ 	.bss_info_changed = mt7915_bss_info_changed,
++	.start_ap = mt7915_start_ap,
++	.stop_ap = mt7915_stop_ap,
+ 	.sta_add = mt7915_sta_add,
+ 	.sta_remove = mt7915_sta_remove,
+ 	.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index aa706ff6..71eeb54a 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -167,7 +167,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+ 	}
+ 
+ 	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
+-	if (seq != rxd->seq)
++	if (seq != rxd->seq &&
++	    !(rxd->eid == MCU_CMD_EXT_CID &&
++	      rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+ 		return -EAGAIN;
+ 
+ 	if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
+@@ -277,7 +279,7 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
+ 
+ 	r = (struct mt7915_mcu_rdd_report *)skb->data;
+ 
+-	if (r->band_idx > MT_BAND1)
++	if (r->band_idx > MT_RX_SEL2)
+ 		return;
+ 
+ 	if ((r->band_idx && !dev->phy.mt76->band_idx) &&
+@@ -398,12 +400,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
+ 	struct mt76_connac2_mcu_rxd *rxd;
+ 
+ 	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
+-	if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
+-	    rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
+-	    rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
+-	    rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
+-	    rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
+-	    !rxd->seq)
++	if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
++	     rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
++	     rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
++	     rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
++	     rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
++	     !rxd->seq) &&
++	     !(rxd->eid == MCU_CMD_EXT_CID &&
++	       rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+ 		mt7915_mcu_rx_unsolicited_event(dev, skb);
+ 	else
+ 		mt76_mcu_rx_event(&dev->mt76, skb);
+@@ -2115,12 +2119,11 @@ int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enabled)
+ 				sizeof(data), false);
+ }
+ 
+-int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms)
++int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
+ 	struct sk_buff *skb;
+-	struct mt7915_mcu_muru_stats *mu_stats =
+-				(struct mt7915_mcu_muru_stats *)ms;
++	struct mt7915_mcu_muru_stats *mu_stats;
+ 	int ret;
+ 
+ 	struct {
+@@ -2136,7 +2139,43 @@ int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms)
+ 	if (ret)
+ 		return ret;
+ 
+-	memcpy(mu_stats, skb->data, sizeof(struct mt7915_mcu_muru_stats));
++	mu_stats = (struct mt7915_mcu_muru_stats *)(skb->data);
++
++	/* accumulate stats, these are clear-on-read */
++#define __dl_u32(s)	 phy->mib.dl_##s += le32_to_cpu(mu_stats->dl.s)
++#define __ul_u32(s)	 phy->mib.ul_##s += le32_to_cpu(mu_stats->ul.s)
++	__dl_u32(cck_cnt);
++	__dl_u32(ofdm_cnt);
++	__dl_u32(htmix_cnt);
++	__dl_u32(htgf_cnt);
++	__dl_u32(vht_su_cnt);
++	__dl_u32(vht_2mu_cnt);
++	__dl_u32(vht_3mu_cnt);
++	__dl_u32(vht_4mu_cnt);
++	__dl_u32(he_su_cnt);
++	__dl_u32(he_2ru_cnt);
++	__dl_u32(he_2mu_cnt);
++	__dl_u32(he_3ru_cnt);
++	__dl_u32(he_3mu_cnt);
++	__dl_u32(he_4ru_cnt);
++	__dl_u32(he_4mu_cnt);
++	__dl_u32(he_5to8ru_cnt);
++	__dl_u32(he_9to16ru_cnt);
++	__dl_u32(he_gtr16ru_cnt);
++
++	__ul_u32(hetrig_su_cnt);
++	__ul_u32(hetrig_2ru_cnt);
++	__ul_u32(hetrig_3ru_cnt);
++	__ul_u32(hetrig_4ru_cnt);
++	__ul_u32(hetrig_5to8ru_cnt);
++	__ul_u32(hetrig_9to16ru_cnt);
++	__ul_u32(hetrig_gtr16ru_cnt);
++	__ul_u32(hetrig_2mu_cnt);
++	__ul_u32(hetrig_3mu_cnt);
++	__ul_u32(hetrig_4mu_cnt);
++#undef __dl_u32
++#undef __ul_u32
++
+ 	dev_kfree_skb(skb);
+ 
+ 	return 0;
+@@ -3736,6 +3775,62 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
+ 				 &req, sizeof(req), true);
+ }
+ 
++int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
++{
++	struct {
++		__le32 cmd;
++		__le32 num;
++		__le32 __rsv;
++		__le16 wlan_idx;
++	} req = {
++		.cmd = cpu_to_le32(0x15),
++		.num = cpu_to_le32(1),
++		.wlan_idx = cpu_to_le16(wlan_idx),
++	};
++	struct mt7915_mcu_wa_tx_stat {
++		__le16 wlan_idx;
++		u8 __rsv[2];
++
++		/* tx_bytes is deprecated since WA byte counter uses u32,
++		 * which easily leads to overflow.
++		 */
++		__le32 tx_bytes;
++		__le32 tx_packets;
++	} *res;
++	struct mt76_wcid *wcid;
++	struct sk_buff *skb;
++	int ret;
++
++	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY),
++					&req, sizeof(req), true, &skb);
++	if (ret)
++		return ret;
++
++	if (!is_mt7915(&dev->mt76))
++		skb_pull(skb, 4);
++
++	res = (struct mt7915_mcu_wa_tx_stat *)skb->data;
++
++	if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	rcu_read_lock();
++
++	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
++	if (wcid)
++		wcid->stats.tx_packets += le32_to_cpu(res->tx_packets);
++	else
++		ret = -EINVAL;
++
++	rcu_read_unlock();
++out:
++	dev_kfree_skb(skb);
++
++	return ret;
++}
++
+ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
+ {
+ 	struct {
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 984b5f60..fc7ace63 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -545,8 +545,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ {
+ 	struct mt7915_dev *dev;
+-	struct mt7915_phy *phy;
+-	int ret;
+ 
+ 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+ 
+@@ -554,43 +552,19 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+ 	dev->mt76.token_size = wed->wlan.token_start;
+ 	spin_unlock_bh(&dev->mt76.token_lock);
+ 
+-	ret = wait_event_timeout(dev->mt76.tx_wait,
+-				 !dev->mt76.wed_token_count, HZ);
+-	if (!ret)
+-		return -EAGAIN;
+-
+-	phy = &dev->phy;
+-	mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
+-
+-	phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
+-	if (phy)
+-		mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx),
+-			 MT_AGG_ACR_PPDU_TXS2H);
+-
+-	return 0;
++	return !wait_event_timeout(dev->mt76.tx_wait,
++				   !dev->mt76.wed_token_count, HZ);
+ }
+ 
+ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+ {
+ 	struct mt7915_dev *dev;
+-	struct mt7915_phy *phy;
+ 
+ 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+ 
+ 	spin_lock_bh(&dev->mt76.token_lock);
+ 	dev->mt76.token_size = MT7915_TOKEN_SIZE;
+ 	spin_unlock_bh(&dev->mt76.token_lock);
+-
+-	/* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
+-	 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
+-	 */
+-	phy = &dev->phy;
+-	mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
+-
+-	phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
+-	if (phy)
+-		mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx),
+-			   MT_AGG_ACR_PPDU_TXS2H);
+ }
+ 
+ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -1064,7 +1038,7 @@ static int __init mt7915_init(void)
+ 		goto error_pci;
+ 
+ 	if (IS_ENABLED(CONFIG_MT798X_WMAC)) {
+-		ret = platform_driver_register(&mt7986_wmac_driver);
++		ret = platform_driver_register(&mt798x_wmac_driver);
+ 		if (ret)
+ 			goto error_wmac;
+ 	}
+@@ -1082,7 +1056,7 @@ error_pci:
+ static void __exit mt7915_exit(void)
+ {
+ 	if (IS_ENABLED(CONFIG_MT798X_WMAC))
+-		platform_driver_unregister(&mt7986_wmac_driver);
++		platform_driver_unregister(&mt798x_wmac_driver);
+ 
+ 	pci_unregister_driver(&mt7915_pci_driver);
+ 	pci_unregister_driver(&mt7915_hif_driver);
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 103cd0d7..0c7226b8 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -136,7 +136,6 @@ struct mt7915_sta {
+ 
+ 	struct mt7915_vif *vif;
+ 
+-	struct list_head poll_list;
+ 	struct list_head rc_list;
+ 	u32 airtime_ac[8];
+ 
+@@ -145,7 +144,6 @@ struct mt7915_sta {
+ 
+ 	unsigned long changed;
+ 	unsigned long jiffies;
+-	unsigned long ampdu_state;
+ 	struct mt76_connac_sta_key_conf bip;
+ 
+ 	struct {
+@@ -164,67 +162,6 @@ struct mt7915_vif {
+ 	struct cfg80211_bitrate_mask bitrate_mask;
+ };
+ 
+-/* per-phy stats.  */
+-struct mib_stats {
+-	u32 ack_fail_cnt;
+-	u32 fcs_err_cnt;
+-	u32 rts_cnt;
+-	u32 rts_retries_cnt;
+-	u32 ba_miss_cnt;
+-	u32 tx_bf_cnt;
+-	u32 tx_mu_mpdu_cnt;
+-	u32 tx_mu_acked_mpdu_cnt;
+-	u32 tx_su_acked_mpdu_cnt;
+-	u32 tx_bf_ibf_ppdu_cnt;
+-	u32 tx_bf_ebf_ppdu_cnt;
+-
+-	u32 tx_bf_rx_fb_all_cnt;
+-	u32 tx_bf_rx_fb_he_cnt;
+-	u32 tx_bf_rx_fb_vht_cnt;
+-	u32 tx_bf_rx_fb_ht_cnt;
+-
+-	u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
+-	u32 tx_bf_rx_fb_nc_cnt;
+-	u32 tx_bf_rx_fb_nr_cnt;
+-	u32 tx_bf_fb_cpl_cnt;
+-	u32 tx_bf_fb_trig_cnt;
+-
+-	u32 tx_ampdu_cnt;
+-	u32 tx_stop_q_empty_cnt;
+-	u32 tx_mpdu_attempts_cnt;
+-	u32 tx_mpdu_success_cnt;
+-	u32 tx_pkt_ebf_cnt;
+-	u32 tx_pkt_ibf_cnt;
+-
+-	u32 tx_rwp_fail_cnt;
+-	u32 tx_rwp_need_cnt;
+-
+-	/* rx stats */
+-	u32 rx_fifo_full_cnt;
+-	u32 channel_idle_cnt;
+-	u32 primary_cca_busy_time;
+-	u32 secondary_cca_busy_time;
+-	u32 primary_energy_detect_time;
+-	u32 cck_mdrdy_time;
+-	u32 ofdm_mdrdy_time;
+-	u32 green_mdrdy_time;
+-	u32 rx_vector_mismatch_cnt;
+-	u32 rx_delimiter_fail_cnt;
+-	u32 rx_mrdy_cnt;
+-	u32 rx_len_mismatch_cnt;
+-	u32 rx_mpdu_cnt;
+-	u32 rx_ampdu_cnt;
+-	u32 rx_ampdu_bytes_cnt;
+-	u32 rx_ampdu_valid_subframe_cnt;
+-	u32 rx_ampdu_valid_subframe_bytes_cnt;
+-	u32 rx_pfdrop_cnt;
+-	u32 rx_vec_queue_overflow_drop_cnt;
+-	u32 rx_ba_cnt;
+-
+-	u32 tx_amsdu[8];
+-	u32 tx_amsdu_cnt;
+-};
+-
+ /* crash-dump */
+ struct mt7915_crash_data {
+ 	guid_t guid;
+@@ -270,7 +207,7 @@ struct mt7915_phy {
+ 	u32 rx_ampdu_ts;
+ 	u32 ampdu_ref;
+ 
+-	struct mib_stats mib;
++	struct mt76_mib_stats mib;
+ 	struct mt76_channel_state state_ts;
+ 
+ #ifdef CONFIG_NL80211_TESTMODE
+@@ -335,9 +272,7 @@ struct mt7915_dev {
+ #endif
+ 
+ 	struct list_head sta_rc_list;
+-	struct list_head sta_poll_list;
+ 	struct list_head twt_list;
+-	spinlock_t sta_poll_lock;
+ 
+ 	u32 hw_pattern;
+ 
+@@ -437,7 +372,7 @@ extern const struct ieee80211_ops mt7915_ops;
+ extern const struct mt76_testmode_ops mt7915_testmode_ops;
+ extern struct pci_driver mt7915_pci_driver;
+ extern struct pci_driver mt7915_hif_driver;
+-extern struct platform_driver mt7986_wmac_driver;
++extern struct platform_driver mt798x_wmac_driver;
+ 
+ #ifdef CONFIG_MT798X_WMAC
+ int mt7986_wmac_enable(struct mt7915_dev *dev);
+@@ -472,6 +407,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2);
+ void mt7915_dma_prefetch(struct mt7915_dev *dev);
+ void mt7915_dma_cleanup(struct mt7915_dev *dev);
+ int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
++int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset);
+ int mt7915_txbf_init(struct mt7915_dev *dev);
+ void mt7915_init_txpower(struct mt7915_dev *dev,
+ 			 struct ieee80211_supported_band *sband);
+@@ -545,6 +481,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ 			   struct ieee80211_sta *sta, struct rate_info *rate);
+ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
+ 				     struct cfg80211_chan_def *chandef);
++int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
+ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+@@ -618,7 +555,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 			  enum mt76_txq_id qid, struct mt76_wcid *wcid,
+ 			  struct ieee80211_sta *sta,
+ 			  struct mt76_tx_info *tx_info);
+-void mt7915_tx_token_put(struct mt7915_dev *dev);
+ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 			 struct sk_buff *skb, u32 *info);
+ bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len);
+@@ -629,7 +565,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy);
+ void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy);
+ void mt7915_update_channel(struct mt76_phy *mphy);
+ int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enable);
+-int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms);
++int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy);
+ int mt7915_mcu_wed_enable_rx_stats(struct mt7915_dev *dev);
+ int mt7915_init_debugfs(struct mt7915_phy *phy);
+ void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len);
+diff --git a/mt7915/regs.h b/mt7915/regs.h
+index 374677f7..588cd87e 100644
+--- a/mt7915/regs.h
++++ b/mt7915/regs.h
+@@ -145,6 +145,9 @@ enum offs_rev {
+ #define MT_PLE_BASE			0x820c0000
+ #define MT_PLE(ofs)			(MT_PLE_BASE + (ofs))
+ 
++#define MT_PLE_HOST_RPT0		MT_PLE(0x030)
++#define MT_PLE_HOST_RPT0_TX_LATENCY	BIT(3)
++
+ #define MT_FL_Q_EMPTY			MT_PLE(__OFFS(PLE_FL_Q_EMPTY))
+ #define MT_FL_Q0_CTRL			MT_PLE(__OFFS(PLE_FL_Q_CTRL))
+ #define MT_FL_Q2_CTRL			MT_PLE(__OFFS(PLE_FL_Q_CTRL) + 0x8)
+diff --git a/mt7915/soc.c b/mt7915/soc.c
+index fffe3623..1f23e60f 100644
+--- a/mt7915/soc.c
++++ b/mt7915/soc.c
+@@ -174,10 +174,11 @@ static u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev)
+ {
+ 	u32 val;
+ 
++	/* Only DBDC A-die is used with MT7981 */
+ 	if (is_mt7981(&dev->mt76))
+ 		return ADIE_DBDC;
+-	else
+-		val = readl(dev->sku + MT_TOP_POS_SKU);
++
++	val = readl(dev->sku + MT_TOP_POS_SKU);
+ 
+ 	return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val);
+ }
+@@ -268,10 +269,14 @@ static int mt798x_wmac_coninfra_check(struct mt7915_dev *dev)
+ 	u32 cur;
+ 	u32 con_infra_version;
+ 
+-	if (is_mt7981(&dev->mt76))
++	if (is_mt7981(&dev->mt76)) {
+ 		con_infra_version = MT7981_CON_INFRA_VERSION;
+-	if (is_mt7986(&dev->mt76))
++	} else if (is_mt7986(&dev->mt76)) {
+ 		con_infra_version = MT7986_CON_INFRA_VERSION;
++	} else {
++		WARN_ON(1);
++		return -EINVAL;
++	}
+ 
+ 	return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version),
+ 				 USEC_PER_MSEC, 50 * USEC_PER_MSEC,
+@@ -308,12 +313,9 @@ static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev)
+ 		       MT_TOP_MCU_EMI_BASE_MASK, val);
+ 
+ 	if (is_mt7981(&dev->mt76)) {
+-		/* TODO: mt7981: unsure if we need this at all
+-		 * This base could be also valid for the mt7986 */
+ 		mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE,
+ 			       MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16);
+ 
+-		/* TODO: mt7986: replace by efuse reserved region? */
+ 		mt76_rmw_field(dev, MT_TOP_EFUSE_BASE,
+ 			       MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16);
+ 	}
+@@ -519,10 +521,14 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie)
+ 		rg_xo_01 = 0x1d59080f;
+ 		rg_xo_03 = 0x34c00fe0;
+ 	} else {
+-		if (is_mt7981(&dev->mt76))
++		if (is_mt7981(&dev->mt76)) {
+ 			rg_xo_01 = 0x1959c80f;
+-		else if (is_mt7986(&dev->mt76))
++		} else if (is_mt7986(&dev->mt76)) {
+ 			rg_xo_01 = 0x1959f80f;
++		} else {
++			WARN_ON(1);
++			return -EINVAL;
++		}
+ 		rg_xo_03 = 0x34d00fe0;
+ 	}
+ 
+@@ -644,10 +650,15 @@ static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie)
+ 		return ret;
+ 
+ 	/* turn on SX0 LTBUF */
+-	if (is_mt7981(&dev->mt76))
++	if (is_mt7981(&dev->mt76)) {
+ 		ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007);
+-	else if (is_mt7986(&dev->mt76))
++	} else if (is_mt7986(&dev->mt76)) {
+ 		ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002);
++	} else {
++		WARN_ON(1);
++		return -EINVAL;
++	}
++
+ 	if (ret)
+ 		return ret;
+ 
+@@ -784,7 +795,6 @@ mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type)
+ 		       MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1);
+ 	usleep_range(60, 100);
+ 
+-	/* TODO: mt7981: sets also bit WF4, but mt7986 doesn't need/allow this? */
+ 	txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT |
+ 		      MT_AFE_RG_WBG_EN_TXCAL_WF0 |
+ 		      MT_AFE_RG_WBG_EN_TXCAL_WF1 |
+@@ -930,7 +940,6 @@ static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable)
+ {
+ 	u32 cur;
+ 
+-	/* TODO: check if this is really needed or should be also used for mt7981 */
+ 	if (is_mt7986(&dev->mt76))
+ 		mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0);
+ 
+@@ -1217,7 +1226,7 @@ static int mt798x_wmac_init(struct mt7915_dev *dev)
+ 	return 0;
+ }
+ 
+-static int mt7986_wmac_probe(struct platform_device *pdev)
++static int mt798x_wmac_probe(struct platform_device *pdev)
+ {
+ 	void __iomem *mem_base;
+ 	struct mt7915_dev *dev;
+@@ -1277,7 +1286,7 @@ free_device:
+ 	return ret;
+ }
+ 
+-static int mt7986_wmac_remove(struct platform_device *pdev)
++static int mt798x_wmac_remove(struct platform_device *pdev)
+ {
+ 	struct mt7915_dev *dev = platform_get_drvdata(pdev);
+ 
+@@ -1286,21 +1295,21 @@ static int mt7986_wmac_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static const struct of_device_id mt7986_wmac_of_match[] = {
++static const struct of_device_id mt798x_wmac_of_match[] = {
+ 	{ .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 },
+ 	{ .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 },
+ 	{},
+ };
+ 
+-MODULE_DEVICE_TABLE(of, mt7986_wmac_of_match);
++MODULE_DEVICE_TABLE(of, mt798x_wmac_of_match);
+ 
+-struct platform_driver mt7986_wmac_driver = {
++struct platform_driver mt798x_wmac_driver = {
+ 	.driver = {
+-		.name = "mt7986-wmac",
+-		.of_match_table = mt7986_wmac_of_match,
++		.name = "mt798x-wmac",
++		.of_match_table = mt798x_wmac_of_match,
+ 	},
+-	.probe = mt7986_wmac_probe,
+-	.remove = mt7986_wmac_remove,
++	.probe = mt798x_wmac_probe,
++	.remove = mt798x_wmac_remove,
+ };
+ 
+ MODULE_FIRMWARE(MT7986_FIRMWARE_WA);
+diff --git a/mt7921/debugfs.c b/mt7921/debugfs.c
+index d6b6edba..d6c66e77 100644
+--- a/mt7921/debugfs.c
++++ b/mt7921/debugfs.c
+@@ -95,7 +95,7 @@ mt7921_tx_stats_show(struct seq_file *file, void *data)
+ {
+ 	struct mt7921_dev *dev = file->private;
+ 	struct mt7921_phy *phy = &dev->phy;
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	int i;
+ 
+ 	mt7921_mutex_acquire(dev);
+diff --git a/mt7921/dma.c b/mt7921/dma.c
+index 73d8dc14..4153cd6c 100644
+--- a/mt7921/dma.c
++++ b/mt7921/dma.c
+@@ -74,9 +74,9 @@ static int mt7921_dma_disable(struct mt7921_dev *dev, bool force)
+ 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
+ 		   MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+ 
+-	if (!mt76_poll(dev, MT_WFDMA0_GLO_CFG,
+-		       MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
+-		       MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
++	if (!mt76_poll_msec_tick(dev, MT_WFDMA0_GLO_CFG,
++				 MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
++				 MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 100, 1))
+ 		return -ETIMEDOUT;
+ 
+ 	/* disable dmashdl */
+@@ -231,10 +231,6 @@ int mt7921_dma_init(struct mt7921_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = mt7921_wfsys_reset(dev);
+-	if (ret)
+-		return ret;
+-
+ 	/* init tx queue */
+ 	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0,
+ 					 MT7921_TX_RING_SIZE,
+diff --git a/mt7921/init.c b/mt7921/init.c
+index e929f6eb..94b7cdfd 100644
+--- a/mt7921/init.c
++++ b/mt7921/init.c
+@@ -2,6 +2,9 @@
+ /* Copyright (C) 2020 MediaTek Inc. */
+ 
+ #include <linux/etherdevice.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/thermal.h>
+ #include <linux/firmware.h>
+ #include "mt7921.h"
+ #include "../mt76_connac2_mac.h"
+@@ -51,6 +54,57 @@ static const struct ieee80211_iface_combination if_comb_chanctx[] = {
+ 	}
+ };
+ 
++static ssize_t mt7921_thermal_temp_show(struct device *dev,
++					struct device_attribute *attr,
++					char *buf)
++{
++	switch (to_sensor_dev_attr(attr)->index) {
++	case 0: {
++		struct mt7921_phy *phy = dev_get_drvdata(dev);
++		struct mt7921_dev *mdev = phy->dev;
++		int temperature;
++
++		mt7921_mutex_acquire(mdev);
++		temperature = mt7921_mcu_get_temperature(phy);
++		mt7921_mutex_release(mdev);
++
++		if (temperature < 0)
++			return temperature;
++		/* display in millidegree Celsius */
++		return sprintf(buf, "%u\n", temperature * 1000);
++	}
++	default:
++		return -EINVAL;
++	}
++}
++static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7921_thermal_temp, 0);
++
++static struct attribute *mt7921_hwmon_attrs[] = {
++	&sensor_dev_attr_temp1_input.dev_attr.attr,
++	NULL,
++};
++ATTRIBUTE_GROUPS(mt7921_hwmon);
++
++static int mt7921_thermal_init(struct mt7921_phy *phy)
++{
++	struct wiphy *wiphy = phy->mt76->hw->wiphy;
++	struct device *hwmon;
++	const char *name;
++
++	if (!IS_REACHABLE(CONFIG_HWMON))
++		return 0;
++
++	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7921_%s",
++			      wiphy_name(wiphy));
++
++	hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
++						       mt7921_hwmon_groups);
++	if (IS_ERR(hwmon))
++		return PTR_ERR(hwmon);
++
++	return 0;
++}
++
+ static void
+ mt7921_regd_notifier(struct wiphy *wiphy,
+ 		     struct regulatory_request *request)
+@@ -113,7 +167,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ 	wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
+ 	wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
+ 	wiphy->max_sched_scan_reqs = 1;
+-	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
++	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH |
++			WIPHY_FLAG_SPLIT_SCAN_6GHZ;
+ 	wiphy->reg_notifier = mt7921_regd_notifier;
+ 
+ 	wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
+@@ -176,12 +231,12 @@ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
+ static u8
+ mt7921_get_offload_capability(struct device *dev, const char *fw_wm)
+ {
+-	struct mt7921_fw_features *features = NULL;
+ 	const struct mt76_connac2_fw_trailer *hdr;
+ 	struct mt7921_realease_info *rel_info;
+ 	const struct firmware *fw;
+ 	int ret, i, offset = 0;
+ 	const u8 *data, *end;
++	u8 offload_caps = 0;
+ 
+ 	ret = request_firmware(&fw, fw_wm, dev);
+ 	if (ret)
+@@ -213,7 +268,10 @@ mt7921_get_offload_capability(struct device *dev, const char *fw_wm)
+ 		data += sizeof(*rel_info);
+ 
+ 		if (rel_info->tag == MT7921_FW_TAG_FEATURE) {
++			struct mt7921_fw_features *features;
++
+ 			features = (struct mt7921_fw_features *)data;
++			offload_caps = features->data;
+ 			break;
+ 		}
+ 
+@@ -223,7 +281,7 @@ mt7921_get_offload_capability(struct device *dev, const char *fw_wm)
+ out:
+ 	release_firmware(fw);
+ 
+-	return features ? features->data : 0;
++	return offload_caps;
+ }
+ 
+ struct ieee80211_ops *
+@@ -359,6 +417,12 @@ static void mt7921_init_work(struct work_struct *work)
+ 		return;
+ 	}
+ 
++	ret = mt7921_thermal_init(&dev->phy);
++	if (ret) {
++		dev_err(dev->mt76.dev, "thermal init failed\n");
++		return;
++	}
++
+ 	/* we support chip reset now */
+ 	dev->hw_init_done = true;
+ 
+@@ -392,8 +456,6 @@ int mt7921_register_device(struct mt7921_dev *dev)
+ #endif
+ 	skb_queue_head_init(&dev->phy.scan_event_list);
+ 	skb_queue_head_init(&dev->coredump.msg_list);
+-	INIT_LIST_HEAD(&dev->sta_poll_list);
+-	spin_lock_init(&dev->sta_poll_lock);
+ 
+ 	INIT_WORK(&dev->reset_work, mt7921_mac_reset_work);
+ 	INIT_WORK(&dev->init_work, mt7921_init_work);
+diff --git a/mt7921/mac.c b/mt7921/mac.c
+index 1675bf52..368f9271 100644
+--- a/mt7921/mac.c
++++ b/mt7921/mac.c
+@@ -52,7 +52,7 @@ bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask)
+ 			 0, 5000);
+ }
+ 
+-void mt7921_mac_sta_poll(struct mt7921_dev *dev)
++static void mt7921_mac_sta_poll(struct mt7921_dev *dev)
+ {
+ 	static const u8 ac_to_tid[] = {
+ 		[IEEE80211_AC_BE] = 0,
+@@ -68,9 +68,9 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev)
+ 	s8 rssi[4];
+ 	int i;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	list_splice_init(&dev->sta_poll_list, &sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	while (true) {
+ 		bool clear = false;
+@@ -78,15 +78,15 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev)
+ 		u16 idx;
+ 		u8 bw;
+ 
+-		spin_lock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 		if (list_empty(&sta_poll_list)) {
+-			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 			break;
+ 		}
+ 		msta = list_first_entry(&sta_poll_list,
+-					struct mt7921_sta, poll_list);
+-		list_del_init(&msta->poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++					struct mt7921_sta, wcid.poll_list);
++		list_del_init(&msta->wcid.poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		idx = msta->wcid.idx;
+ 		addr = mt7921_mac_wtbl_lmac_addr(idx, MT_WTBL_AC0_CTT_OFFSET);
+@@ -183,7 +183,6 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev)
+ 		ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal);
+ 	}
+ }
+-EXPORT_SYMBOL_GPL(mt7921_mac_sta_poll);
+ 
+ static void
+ mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy,
+@@ -281,10 +280,11 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ 
+ 	if (status->wcid) {
+ 		msta = container_of(status->wcid, struct mt7921_sta, wcid);
+-		spin_lock_bh(&dev->sta_poll_lock);
+-		if (list_empty(&msta->poll_list))
+-			list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		if (list_empty(&msta->wcid.poll_list))
++			list_add_tail(&msta->wcid.poll_list,
++				      &dev->mt76.sta_poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+ 	mt7921_get_status_freq_info(dev, mphy, status, chfreq);
+@@ -511,30 +511,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ 	return 0;
+ }
+ 
+-static void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+-{
+-	struct mt7921_sta *msta;
+-	u16 fc, tid;
+-	u32 val;
+-
+-	if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
+-		return;
+-
+-	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
+-	if (tid >= 6) /* skip VO queue */
+-		return;
+-
+-	val = le32_to_cpu(txwi[2]);
+-	fc = FIELD_GET(MT_TXD2_FRAME_TYPE, val) << 2 |
+-	     FIELD_GET(MT_TXD2_SUB_TYPE, val) << 4;
+-	if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
+-		return;
+-
+-	msta = (struct mt7921_sta *)sta->drv_priv;
+-	if (!test_and_set_bit(tid, &msta->ampdu_state))
+-		ieee80211_start_tx_ba_session(sta, tid, 0);
+-}
+-
+ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
+ {
+ 	struct mt7921_sta *msta = NULL;
+@@ -567,46 +543,15 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
+ 	if (!wcid->sta)
+ 		goto out;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (list_empty(&msta->poll_list))
+-		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (list_empty(&msta->wcid.poll_list))
++		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ out:
+ 	rcu_read_unlock();
+ }
+ 
+-void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t,
+-		      struct ieee80211_sta *sta, bool clear_status,
+-		      struct list_head *free_list)
+-{
+-	struct mt76_dev *mdev = &dev->mt76;
+-	__le32 *txwi;
+-	u16 wcid_idx;
+-
+-	mt76_connac_txp_skb_unmap(mdev, t);
+-	if (!t->skb)
+-		goto out;
+-
+-	txwi = (__le32 *)mt76_get_txwi_ptr(mdev, t);
+-	if (sta) {
+-		struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+-
+-		if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
+-			mt7921_tx_check_aggr(sta, txwi);
+-
+-		wcid_idx = wcid->idx;
+-	} else {
+-		wcid_idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
+-	}
+-
+-	__mt76_tx_complete_skb(mdev, wcid_idx, t->skb, free_list);
+-out:
+-	t->skb = NULL;
+-	mt76_put_txwi(mdev, t);
+-}
+-EXPORT_SYMBOL_GPL(mt7921_txwi_free);
+-
+ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
+ {
+ 	struct mt76_connac_tx_free *free = data;
+@@ -614,6 +559,7 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
+ 	struct mt76_dev *mdev = &dev->mt76;
+ 	struct mt76_txwi_cache *txwi;
+ 	struct ieee80211_sta *sta = NULL;
++	struct mt76_wcid *wcid = NULL;
+ 	struct sk_buff *skb, *tmp;
+ 	void *end = data + len;
+ 	LIST_HEAD(free_list);
+@@ -637,7 +583,6 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
+ 		 */
+ 		if (info & MT_TX_FREE_PAIR) {
+ 			struct mt7921_sta *msta;
+-			struct mt76_wcid *wcid;
+ 			u16 idx;
+ 
+ 			count++;
+@@ -648,21 +593,28 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)
+ 				continue;
+ 
+ 			msta = container_of(wcid, struct mt7921_sta, wcid);
+-			spin_lock_bh(&dev->sta_poll_lock);
+-			if (list_empty(&msta->poll_list))
+-				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_lock_bh(&mdev->sta_poll_lock);
++			if (list_empty(&msta->wcid.poll_list))
++				list_add_tail(&msta->wcid.poll_list,
++					      &mdev->sta_poll_list);
++			spin_unlock_bh(&mdev->sta_poll_lock);
+ 			continue;
+ 		}
+ 
+ 		msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info);
+ 		stat = FIELD_GET(MT_TX_FREE_STATUS, info);
+ 
++		if (wcid) {
++			wcid->stats.tx_retries +=
++				FIELD_GET(MT_TX_FREE_COUNT, info) - 1;
++			wcid->stats.tx_failed += !!stat;
++		}
++
+ 		txwi = mt76_token_release(mdev, msdu, &wake);
+ 		if (!txwi)
+ 			continue;
+ 
+-		mt7921_txwi_free(dev, txwi, sta, stat, &free_list);
++		mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
+ 	}
+ 
+ 	if (wake)
+@@ -952,8 +904,8 @@ EXPORT_SYMBOL_GPL(mt7921_reset);
+ 
+ void mt7921_mac_update_mib_stats(struct mt7921_phy *phy)
+ {
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	struct mt7921_dev *dev = phy->dev;
+-	struct mib_stats *mib = &phy->mib;
+ 	int i, aggr0 = 0, aggr1;
+ 	u32 val;
+ 
+@@ -1180,6 +1132,10 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	if (unlikely(tx_info->skb->len <= ETH_HLEN))
+ 		return -EINVAL;
+ 
++	err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE);
++	if (err)
++		return err;
++
+ 	if (!wcid)
+ 		wcid = &dev->mt76.global_wcid;
+ 
+@@ -1224,7 +1180,7 @@ void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
+ 	sta = wcid_to_sta(wcid);
+ 
+ 	if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
+-		mt7921_tx_check_aggr(sta, txwi);
++		mt76_connac2_tx_check_aggr(sta, txwi);
+ 
+ 	skb_pull(e->skb, headroom);
+ 	mt76_tx_complete_skb(mdev, e->wcid, e->skb);
+diff --git a/mt7921/main.c b/mt7921/main.c
+index 3b6adb29..87067ac3 100644
+--- a/mt7921/main.c
++++ b/mt7921/main.c
+@@ -313,7 +313,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,
+ 
+ 	idx = MT7921_WTBL_RESERVED - mvif->mt76.idx;
+ 
+-	INIT_LIST_HEAD(&mvif->sta.poll_list);
++	INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
+ 	mvif->sta.wcid.idx = idx;
+ 	mvif->sta.wcid.phy_idx = mvif->mt76.band_idx;
+ 	mvif->sta.wcid.hw_key_idx = -1;
+@@ -357,10 +357,10 @@ static void mt7921_remove_interface(struct ieee80211_hw *hw,
+ 	phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
+ 	mt7921_mutex_release(dev);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	mt76_packet_id_flush(&dev->mt76, &msta->wcid);
+ }
+@@ -764,7 +764,7 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	if (idx < 0)
+ 		return -ENOSPC;
+ 
+-	INIT_LIST_HEAD(&msta->poll_list);
++	INIT_LIST_HEAD(&msta->wcid.poll_list);
+ 	msta->vif = mvif;
+ 	msta->wcid.sta = 1;
+ 	msta->wcid.idx = idx;
+@@ -842,10 +842,10 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 						    mvif->ctx);
+ 	}
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
+ }
+@@ -954,16 +954,16 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ 	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ 		mtxq->aggr = false;
+-		clear_bit(tid, &msta->ampdu_state);
++		clear_bit(tid, &msta->wcid.ampdu_state);
+ 		mt7921_mcu_uni_tx_ba(dev, params, false);
+ 		break;
+ 	case IEEE80211_AMPDU_TX_START:
+-		set_bit(tid, &msta->ampdu_state);
++		set_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
+ 		break;
+ 	case IEEE80211_AMPDU_TX_STOP_CONT:
+ 		mtxq->aggr = false;
+-		clear_bit(tid, &msta->ampdu_state);
++		clear_bit(tid, &msta->wcid.ampdu_state);
+ 		mt7921_mcu_uni_tx_ba(dev, params, false);
+ 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ 		break;
+@@ -995,7 +995,7 @@ mt7921_get_stats(struct ieee80211_hw *hw,
+ 		 struct ieee80211_low_level_stats *stats)
+ {
+ 	struct mt7921_phy *phy = mt7921_hw_phy(hw);
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 
+ 	mt7921_mutex_acquire(phy->dev);
+ 
+@@ -1077,6 +1077,10 @@ static const char mt7921_gstrings_stats[][ETH_GSTRING_LEN] = {
+ 	"v_tx_mcs_9",
+ 	"v_tx_mcs_10",
+ 	"v_tx_mcs_11",
++	"v_tx_nss_1",
++	"v_tx_nss_2",
++	"v_tx_nss_3",
++	"v_tx_nss_4",
+ };
+ 
+ static void
+@@ -1133,7 +1137,7 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	int stats_size = ARRAY_SIZE(mt7921_gstrings_stats);
+ 	struct mt7921_phy *phy = mt7921_hw_phy(hw);
+ 	struct mt7921_dev *dev = phy->dev;
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	struct mt76_ethtool_worker_info wi = {
+ 		.data = data,
+ 		.idx = mvif->mt76.idx,
+@@ -1363,7 +1367,7 @@ mt7921_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+ 		return -EINVAL;
+ 
+ 	if ((BIT(hweight8(tx_ant)) - 1) != tx_ant)
+-		tx_ant = BIT(ffs(tx_ant) - 1) - 1;
++		return -EINVAL;
+ 
+ 	mt7921_mutex_acquire(dev);
+ 
+@@ -1399,6 +1403,12 @@ static void mt7921_sta_statistics(struct ieee80211_hw *hw,
+ 		sinfo->txrate.he_dcm = txrate->he_dcm;
+ 		sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
+ 	}
++	sinfo->tx_failed = msta->wcid.stats.tx_failed;
++	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
++
++	sinfo->tx_retries = msta->wcid.stats.tx_retries;
++	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
++
+ 	sinfo->txrate.flags = txrate->flags;
+ 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+ 
+diff --git a/mt7921/mcu.c b/mt7921/mcu.c
+index c69ce6df..a0ad18c7 100644
+--- a/mt7921/mcu.c
++++ b/mt7921/mcu.c
+@@ -476,12 +476,6 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
+ {
+ 	int ret;
+ 
+-	ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
+-	if (ret && mt76_is_mmio(&dev->mt76)) {
+-		dev_dbg(dev->mt76.dev, "Firmware is already download\n");
+-		goto fw_loaded;
+-	}
+-
+ 	ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev));
+ 	if (ret)
+ 		return ret;
+@@ -504,8 +498,6 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
+ 		return -EIO;
+ 	}
+ 
+-fw_loaded:
+-
+ #ifdef CONFIG_PM
+ 	dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
+ #endif /* CONFIG_PM */
+@@ -1313,6 +1305,23 @@ int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
+ 	return 0;
+ }
+ 
++int mt7921_mcu_get_temperature(struct mt7921_phy *phy)
++{
++	struct mt7921_dev *dev = phy->dev;
++	struct {
++		u8 ctrl_id;
++		u8 action;
++		u8 band_idx;
++		u8 rsv[5];
++	} req = {
++		.ctrl_id = THERMAL_SENSOR_TEMP_QUERY,
++		.band_idx = phy->mt76->band_idx,
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req,
++				 sizeof(req), true);
++}
++
+ int mt7921_mcu_set_rxfilter(struct mt7921_dev *dev, u32 fif,
+ 			    u8 bit_op, u32 bit_map)
+ {
+diff --git a/mt7921/mt7921.h b/mt7921/mt7921.h
+index 149acb16..ec987965 100644
+--- a/mt7921/mt7921.h
++++ b/mt7921/mt7921.h
+@@ -19,7 +19,6 @@
+ #define MT7921_PM_TIMEOUT		(HZ / 12)
+ #define MT7921_HW_SCAN_TIMEOUT		(HZ / 10)
+ #define MT7921_WATCHDOG_TIME		(HZ / 4)
+-#define MT7921_RESET_TIMEOUT		(30 * HZ)
+ 
+ #define MT7921_TX_RING_SIZE		2048
+ #define MT7921_TX_MCU_RING_SIZE		256
+@@ -151,14 +150,12 @@ struct mt7921_sta {
+ 
+ 	struct mt7921_vif *vif;
+ 
+-	struct list_head poll_list;
+ 	u32 airtime_ac[8];
+ 
+ 	int ack_signal;
+ 	struct ewma_avg_signal avg_ack_signal;
+ 
+ 	unsigned long last_txs;
+-	unsigned long ampdu_state;
+ 
+ 	struct mt76_connac_sta_key_conf bip;
+ };
+@@ -179,35 +176,6 @@ struct mt7921_vif {
+ 	struct ieee80211_chanctx_conf *ctx;
+ };
+ 
+-struct mib_stats {
+-	u32 ack_fail_cnt;
+-	u32 fcs_err_cnt;
+-	u32 rts_cnt;
+-	u32 rts_retries_cnt;
+-	u32 ba_miss_cnt;
+-
+-	u32 tx_bf_ibf_ppdu_cnt;
+-	u32 tx_bf_ebf_ppdu_cnt;
+-	u32 tx_bf_rx_fb_all_cnt;
+-	u32 tx_bf_rx_fb_he_cnt;
+-	u32 tx_bf_rx_fb_vht_cnt;
+-	u32 tx_bf_rx_fb_ht_cnt;
+-
+-	u32 tx_ampdu_cnt;
+-	u32 tx_mpdu_attempts_cnt;
+-	u32 tx_mpdu_success_cnt;
+-	u32 tx_pkt_ebf_cnt;
+-	u32 tx_pkt_ibf_cnt;
+-
+-	u32 rx_mpdu_cnt;
+-	u32 rx_ampdu_cnt;
+-	u32 rx_ampdu_bytes_cnt;
+-	u32 rx_ba_cnt;
+-
+-	u32 tx_amsdu[8];
+-	u32 tx_amsdu_cnt;
+-};
+-
+ enum {
+ 	MT7921_CLC_POWER,
+ 	MT7921_CLC_CHAN,
+@@ -247,7 +215,7 @@ struct mt7921_phy {
+ 	u32 rx_ampdu_ts;
+ 	u32 ampdu_ref;
+ 
+-	struct mib_stats mib;
++	struct mt76_mib_stats mib;
+ 
+ 	u8 sta_work_count;
+ 
+@@ -304,9 +272,6 @@ struct mt7921_dev {
+ 	bool hw_init_done:1;
+ 	bool fw_assert:1;
+ 
+-	struct list_head sta_poll_list;
+-	spinlock_t sta_poll_lock;
+-
+ 	struct work_struct init_work;
+ 
+ 	u8 fw_debug;
+@@ -477,7 +442,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 			   struct mt76_tx_info *tx_info);
+ 
+ void mt7921_tx_worker(struct mt76_worker *w);
+-void mt7921_tx_token_put(struct mt7921_dev *dev);
+ bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len);
+ void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 			 struct sk_buff *skb, u32 *info);
+@@ -510,10 +474,6 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			void *data, int len);
+ int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ 			 struct netlink_callback *cb, void *data, int len);
+-void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t,
+-		      struct ieee80211_sta *sta, bool clear_status,
+-		      struct list_head *free_list);
+-void mt7921_mac_sta_poll(struct mt7921_dev *dev);
+ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
+ 			      struct sk_buff *skb, int seq);
+ 
+@@ -540,6 +500,7 @@ int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
+ 			   bool enable);
+ int mt7921_mcu_config_sniffer(struct mt7921_vif *vif,
+ 			      struct ieee80211_chanctx_conf *ctx);
++int mt7921_mcu_get_temperature(struct mt7921_phy *phy);
+ 
+ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 				   enum mt76_txq_id qid, struct mt76_wcid *wcid,
+diff --git a/mt7921/pci.c b/mt7921/pci.c
+index 1c727870..7c8bf719 100644
+--- a/mt7921/pci.c
++++ b/mt7921/pci.c
+@@ -115,7 +115,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev)
+ 	cancel_work_sync(&pm->wake_work);
+ 	cancel_work_sync(&dev->reset_work);
+ 
+-	mt7921_tx_token_put(dev);
++	mt76_connac2_tx_token_put(&dev->mt76);
+ 	__mt7921_mcu_drv_pmctrl(dev);
+ 	mt7921_dma_cleanup(dev);
+ 	mt7921_wfsys_reset(dev);
+@@ -325,6 +325,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
+ 	bus_ops->rmw = mt7921_rmw;
+ 	dev->mt76.bus = bus_ops;
+ 
++	ret = mt7921e_mcu_fw_pmctrl(dev);
++	if (ret)
++		goto err_free_dev;
++
+ 	ret = __mt7921e_mcu_drv_pmctrl(dev);
+ 	if (ret)
+ 		goto err_free_dev;
+@@ -333,6 +337,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
+ 		    (mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
+ 	dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
+ 
++	ret = mt7921_wfsys_reset(dev);
++	if (ret)
++		goto err_free_dev;
++
+ 	mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
+ 
+ 	mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
+diff --git a/mt7921/pci_mac.c b/mt7921/pci_mac.c
+index 6053a255..978c90a0 100644
+--- a/mt7921/pci_mac.c
++++ b/mt7921/pci_mac.c
+@@ -53,20 +53,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	return 0;
+ }
+ 
+-void mt7921_tx_token_put(struct mt7921_dev *dev)
+-{
+-	struct mt76_txwi_cache *txwi;
+-	int id;
+-
+-	spin_lock_bh(&dev->mt76.token_lock);
+-	idr_for_each_entry(&dev->mt76.token, txwi, id) {
+-		mt7921_txwi_free(dev, txwi, NULL, false, NULL);
+-		dev->mt76.token_count--;
+-	}
+-	spin_unlock_bh(&dev->mt76.token_lock);
+-	idr_destroy(&dev->mt76.token);
+-}
+-
+ int mt7921e_mac_reset(struct mt7921_dev *dev)
+ {
+ 	int i, err;
+@@ -91,7 +77,7 @@ int mt7921e_mac_reset(struct mt7921_dev *dev)
+ 	napi_disable(&dev->mt76.napi[MT_RXQ_MCU_WA]);
+ 	napi_disable(&dev->mt76.tx_napi);
+ 
+-	mt7921_tx_token_put(dev);
++	mt76_connac2_tx_token_put(&dev->mt76);
+ 	idr_init(&dev->mt76.token);
+ 
+ 	mt7921_wpdma_reset(dev, true);
+diff --git a/mt7921/regs.h b/mt7921/regs.h
+index e52977ff..b1801425 100644
+--- a/mt7921/regs.h
++++ b/mt7921/regs.h
+@@ -158,7 +158,6 @@
+ 
+ #define MT_MIB_MB_SDR0(_band, n)	MT_WF_MIB(_band, 0x100 + ((n) << 4))
+ #define MT_MIB_RTS_RETRIES_COUNT_MASK	GENMASK(31, 16)
+-#define MT_MIB_RTS_COUNT_MASK		GENMASK(15, 0)
+ 
+ #define MT_MIB_MB_BSDR0(_band)		MT_WF_MIB(_band, 0x688)
+ #define MT_MIB_RTS_COUNT_MASK		GENMASK(15, 0)
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index 513ab4ba..4d40ec7f 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -474,10 +474,10 @@ mt7996_ampdu_stat_read_phy(struct mt7996_phy *phy, struct seq_file *file)
+ static void
+ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
+ {
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	static const char * const bw[] = {
+ 		"BW20", "BW40", "BW80", "BW160"
+ 	};
+-	struct mib_stats *mib = &phy->mib;
+ 
+ 	/* Tx Beamformer monitor */
+ 	seq_puts(s, "\nTx Beamformer applied PPDU counts: ");
+@@ -523,7 +523,7 @@ mt7996_tx_stats_show(struct seq_file *file, void *data)
+ {
+ 	struct mt7996_phy *phy = file->private;
+ 	struct mt7996_dev *dev = phy->dev;
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	int i;
+ 	u32 attempts, success, per;
+ 
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 53414346..586e247a 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -128,11 +128,55 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
+ 	}
+ }
+ 
+-static int mt7996_dma_enable(struct mt7996_dev *dev)
++void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
+ {
+ 	u32 hif1_ofs = 0;
+ 	u32 irq_mask;
+ 
++	if (dev->hif2)
++		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++	/* enable WFDMA Tx/Rx */
++	if (!reset) {
++		mt76_set(dev, MT_WFDMA0_GLO_CFG,
++			 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++			 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++			 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++			 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++		if (dev->hif2)
++			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
++				 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++				 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++				 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++				 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++	}
++
++	/* enable interrupts for TX/RX rings */
++	irq_mask = MT_INT_MCU_CMD;
++	if (reset)
++		goto done;
++
++	irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
++
++	if (!dev->mphy.band_idx)
++		irq_mask |= MT_INT_BAND0_RX_DONE;
++
++	if (dev->dbdc_support)
++		irq_mask |= MT_INT_BAND1_RX_DONE;
++
++	if (dev->tbtc_support)
++		irq_mask |= MT_INT_BAND2_RX_DONE;
++
++done:
++	mt7996_irq_enable(dev, irq_mask);
++	mt7996_irq_disable(dev, 0);
++}
++
++static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
++{
++	u32 hif1_ofs = 0;
++
+ 	if (dev->hif2)
+ 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+ 
+@@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
+ 	mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
+ 		  MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
+ 
+-	/* set WFDMA Tx/Rx */
+-	mt76_set(dev, MT_WFDMA0_GLO_CFG,
+-		 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+-		 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+-		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+-		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+ 	/* GLO_CFG_EXT0 */
+ 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0,
+ 		 WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
+@@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
+ 		 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
+ 
+ 	if (dev->hif2) {
+-		mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
+-			 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+-			 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+-			 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+-			 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+ 		/* GLO_CFG_EXT0 */
+ 		mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
+ 			 WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
+@@ -216,23 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
+ 		/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
+ 	}
+ 
+-	/* enable interrupts for TX/RX rings */
+-	irq_mask = MT_INT_RX_DONE_MCU |
+-		   MT_INT_TX_DONE_MCU |
+-		   MT_INT_MCU_CMD;
+-
+-	if (!dev->mphy.band_idx)
+-		irq_mask |= MT_INT_BAND0_RX_DONE;
+-
+-	if (dev->dbdc_support)
+-		irq_mask |= MT_INT_BAND1_RX_DONE;
+-
+-	if (dev->tbtc_support)
+-		irq_mask |= MT_INT_BAND2_RX_DONE;
+-
+-	mt7996_irq_enable(dev, irq_mask);
+-
+-	return 0;
++	mt7996_dma_start(dev, reset);
+ }
+ 
+ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -293,7 +308,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	/* event from WA */
+ 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
+ 			       MT_RXQ_ID(MT_RXQ_MCU_WA),
+-			       MT7996_RX_MCU_RING_SIZE,
++			       MT7996_RX_MCU_RING_SIZE_WA,
+ 			       MT_RX_BUF_SIZE,
+ 			       MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
+ 	if (ret)
+@@ -347,7 +362,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 			  mt7996_poll_tx);
+ 	napi_enable(&dev->mt76.tx_napi);
+ 
+-	mt7996_dma_enable(dev);
++	mt7996_dma_enable(dev, false);
+ 
+ 	return 0;
+ }
+@@ -413,7 +428,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+ 	mt76_for_each_q_rx(&dev->mt76, i)
+ 		mt76_queue_rx_reset(dev, i);
+ 
+-	mt7996_dma_enable(dev);
++	mt7996_dma_enable(dev, !force);
+ }
+ 
+ void mt7996_dma_cleanup(struct mt7996_dev *dev)
+diff --git a/mt7996/init.c b/mt7996/init.c
+index f1b48cdd..e297e7cb 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -183,6 +183,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
+ 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
++	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
+ 
+ 	if (!mdev->dev->of_node ||
+ 	    !of_property_read_bool(mdev->dev->of_node,
+@@ -217,6 +218,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+ 		phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
+ 			IEEE80211_HT_MPDU_DENSITY_1;
++
++		ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
+ 	}
+ 
+ 	mt76_set_stream_caps(phy->mt76, true);
+@@ -853,9 +856,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ 	INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
+ 	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
+ 	INIT_LIST_HEAD(&dev->sta_rc_list);
+-	INIT_LIST_HEAD(&dev->sta_poll_list);
+ 	INIT_LIST_HEAD(&dev->twt_list);
+-	spin_lock_init(&dev->sta_poll_lock);
+ 
+ 	init_waitqueue_head(&dev->reset_wait);
+ 	INIT_WORK(&dev->reset_work, mt7996_mac_reset_work);
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 0d51090d..17dd531e 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -13,10 +13,6 @@
+ 
+ #define to_rssi(field, rcpi)	((FIELD_GET(field, rcpi) - 220) / 2)
+ 
+-#define HE_BITS(f)		cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+-#define HE_PREP(f, m, v)	le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
+-						 IEEE80211_RADIOTAP_HE_##f)
+-
+ static const struct mt7996_dfs_radar_spec etsi_radar_specs = {
+ 	.pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 },
+ 	.radar_pattern = {
+@@ -111,9 +107,9 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
+ 	LIST_HEAD(sta_poll_list);
+ 	int i;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	list_splice_init(&dev->sta_poll_list, &sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	rcu_read_lock();
+ 
+@@ -124,15 +120,15 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
+ 		s8 rssi[4];
+ 		u8 bw;
+ 
+-		spin_lock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 		if (list_empty(&sta_poll_list)) {
+-			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 			break;
+ 		}
+ 		msta = list_first_entry(&sta_poll_list,
+-					struct mt7996_sta, poll_list);
+-		list_del_init(&msta->poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++					struct mt7996_sta, wcid.poll_list);
++		list_del_init(&msta->wcid.poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		idx = msta->wcid.idx;
+ 
+@@ -263,180 +259,6 @@ void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
+ 	mt76_wr(dev, MT_WTBL_ITCR, ctrl);
+ }
+ 
+-static void
+-mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
+-				 struct ieee80211_radiotap_he *he,
+-				 __le32 *rxv)
+-{
+-	u32 ru, offs = 0;
+-
+-	ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC);
+-
+-	status->bw = RATE_INFO_BW_HE_RU;
+-
+-	switch (ru) {
+-	case 0 ... 36:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
+-		offs = ru;
+-		break;
+-	case 37 ... 52:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
+-		offs = ru - 37;
+-		break;
+-	case 53 ... 60:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
+-		offs = ru - 53;
+-		break;
+-	case 61 ... 64:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
+-		offs = ru - 61;
+-		break;
+-	case 65 ... 66:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
+-		offs = ru - 65;
+-		break;
+-	case 67:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
+-		break;
+-	case 68:
+-		status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
+-		break;
+-	}
+-
+-	he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
+-	he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) |
+-		     le16_encode_bits(offs,
+-				      IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
+-}
+-
+-static void
+-mt7996_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
+-{
+-	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+-	static const struct ieee80211_radiotap_he_mu mu_known = {
+-		.flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
+-			  HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
+-			  HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) |
+-			  HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
+-		.flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
+-	};
+-	struct ieee80211_radiotap_he_mu *he_mu = NULL;
+-
+-	status->flag |= RX_FLAG_RADIOTAP_HE_MU;
+-
+-	he_mu = skb_push(skb, sizeof(mu_known));
+-	memcpy(he_mu, &mu_known, sizeof(mu_known));
+-
+-#define MU_PREP(f, v)	le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f)
+-
+-	he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx);
+-	if (status->he_dcm)
+-		he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm);
+-
+-	he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
+-			 MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
+-				 le32_get_bits(rxv[4], MT_CRXV_HE_NUM_USER));
+-
+-	he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) & 0xff;
+-
+-	if (status->bw >= RATE_INFO_BW_40) {
+-		he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
+-		he_mu->ru_ch2[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU1) & 0xff;
+-	}
+-
+-	if (status->bw >= RATE_INFO_BW_80) {
+-		u32 ru_h, ru_l;
+-
+-		he_mu->ru_ch1[1] = le32_get_bits(rxv[16], MT_CRXV_HE_RU2) & 0xff;
+-
+-		ru_l = le32_get_bits(rxv[16], MT_CRXV_HE_RU3_L);
+-		ru_h = le32_get_bits(rxv[17], MT_CRXV_HE_RU3_H) & 0x7;
+-		he_mu->ru_ch2[1] = (u8)(ru_l | ru_h << 4);
+-	}
+-}
+-
+-static void
+-mt7996_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode)
+-{
+-	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+-	static const struct ieee80211_radiotap_he known = {
+-		.data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
+-			 HE_BITS(DATA1_DATA_DCM_KNOWN) |
+-			 HE_BITS(DATA1_STBC_KNOWN) |
+-			 HE_BITS(DATA1_CODING_KNOWN) |
+-			 HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
+-			 HE_BITS(DATA1_DOPPLER_KNOWN) |
+-			 HE_BITS(DATA1_SPTL_REUSE_KNOWN) |
+-			 HE_BITS(DATA1_BSS_COLOR_KNOWN),
+-		.data2 = HE_BITS(DATA2_GI_KNOWN) |
+-			 HE_BITS(DATA2_TXBF_KNOWN) |
+-			 HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
+-			 HE_BITS(DATA2_TXOP_KNOWN),
+-	};
+-	struct ieee80211_radiotap_he *he = NULL;
+-	u32 ltf_size = le32_get_bits(rxv[4], MT_CRXV_HE_LTF_SIZE) + 1;
+-
+-	status->flag |= RX_FLAG_RADIOTAP_HE;
+-
+-	he = skb_push(skb, sizeof(known));
+-	memcpy(he, &known, sizeof(known));
+-
+-	he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[9]) |
+-		    HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[4]);
+-	he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[13]);
+-	he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5]) |
+-		    le16_encode_bits(ltf_size,
+-				     IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
+-	if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
+-		he->data5 |= HE_BITS(DATA5_TXBF);
+-	he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[9]) |
+-		    HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[9]);
+-
+-	switch (mode) {
+-	case MT_PHY_TYPE_HE_SU:
+-		he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
+-			     HE_BITS(DATA1_UL_DL_KNOWN) |
+-			     HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
+-			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
+-
+-		he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[8]) |
+-			     HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
+-		break;
+-	case MT_PHY_TYPE_HE_EXT_SU:
+-		he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
+-			     HE_BITS(DATA1_UL_DL_KNOWN) |
+-			     HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
+-
+-		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
+-		break;
+-	case MT_PHY_TYPE_HE_MU:
+-		he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
+-			     HE_BITS(DATA1_UL_DL_KNOWN);
+-
+-		he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[5]);
+-		he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[8]);
+-
+-		mt7996_mac_decode_he_radiotap_ru(status, he, rxv);
+-		mt7996_mac_decode_he_mu_radiotap(skb, rxv);
+-		break;
+-	case MT_PHY_TYPE_HE_TB:
+-		he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
+-			     HE_BITS(DATA1_SPTL_REUSE2_KNOWN) |
+-			     HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
+-			     HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
+-
+-		he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[13]) |
+-			     HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[13]) |
+-			     HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[13]) |
+-			     HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[13]);
+-
+-		mt7996_mac_decode_he_radiotap_ru(status, he, rxv);
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+ /* The HW does not translate the mac header to 802.3 for mesh point */
+ static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
+ {
+@@ -680,10 +502,11 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ 		struct mt7996_sta *msta;
+ 
+ 		msta = container_of(status->wcid, struct mt7996_sta, wcid);
+-		spin_lock_bh(&dev->sta_poll_lock);
+-		if (list_empty(&msta->poll_list))
+-			list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
++		if (list_empty(&msta->wcid.poll_list))
++			list_add_tail(&msta->wcid.poll_list,
++				      &dev->mt76.sta_poll_list);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+ 	status->freq = mphy->chandef.chan->center_freq;
+@@ -835,14 +658,19 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ 		skb_pull(skb, hdr_gap);
+ 		if (!hdr_trans && status->amsdu && !(ieee80211_has_a4(fc) && is_mesh)) {
+ 			pad_start = ieee80211_get_hdrlen_from_skb(skb);
+-		} else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR) &&
+-			   get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q) {
++		} else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) {
+ 			/* When header translation failure is indicated,
+ 			 * the hardware will insert an extra 2-byte field
+ 			 * containing the data length after the protocol
+-			 * type field.
++			 * type field. This happens either when the LLC-SNAP
++			 * pattern did not match, or if a VLAN header was
++			 * detected.
+ 			 */
+-			pad_start = 16;
++			pad_start = 12;
++			if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
++				pad_start += 4;
++			else
++				pad_start = 0;
+ 		}
+ 
+ 		if (pad_start) {
+@@ -880,7 +708,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	}
+ 
+ 	if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
+-		mt7996_mac_decode_he_radiotap(skb, rxv, mode);
++		mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
+ 
+ 	if (!status->wcid || !ieee80211_is_data_qos(fc))
+ 		return 0;
+@@ -1003,7 +831,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ {
+ 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ 	struct ieee80211_vif *vif = info->control.vif;
+-	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt76_vif *mvif;
+ 	struct mt76_phy *mphy = &dev->mphy;
+ 	u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
+ 	u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
+@@ -1015,10 +843,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ 	bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
+ 					 BSS_CHANGED_FILS_DISCOVERY));
+ 
+-	if (vif) {
+-		omac_idx = mvif->mt76.omac_idx;
+-		wmm_idx = mvif->mt76.wmm_idx;
+-		band_idx = mvif->mt76.band_idx;
++	mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL;
++	if (mvif) {
++		omac_idx = mvif->omac_idx;
++		wmm_idx = mvif->wmm_idx;
++		band_idx = mvif->band_idx;
+ 	}
+ 
+ 	mphy = mt76_dev_phy(&dev->mt76, band_idx);
+@@ -1083,14 +912,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ 		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 		bool mcast = ieee80211_is_data(hdr->frame_control) &&
+ 			     is_multicast_ether_addr(hdr->addr1);
+-		u8 idx = mvif->basic_rates_idx;
++		u8 idx = MT7996_BASIC_RATES_TBL;
+ 
+-		if (mcast && mvif->mcast_rates_idx)
+-			idx = mvif->mcast_rates_idx;
+-		else if (beacon && mvif->beacon_rates_idx)
+-			idx = mvif->beacon_rates_idx;
++		if (mvif) {
++			if (mcast && mvif->mcast_rates_idx)
++				idx = mvif->mcast_rates_idx;
++			else if (beacon && mvif->beacon_rates_idx)
++				idx = mvif->beacon_rates_idx;
++			else
++				idx = mvif->basic_rates_idx;
++		}
+ 
+-		txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx);
++		txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE, idx));
+ 		txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
+ 	}
+ }
+@@ -1200,7 +1033,7 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+ 		return;
+ 
+ 	msta = (struct mt7996_sta *)sta->drv_priv;
+-	if (!test_and_set_bit(tid, &msta->ampdu_state))
++	if (!test_and_set_bit(tid, &msta->wcid.ampdu_state))
+ 		ieee80211_start_tx_ba_session(sta, tid, 0);
+ }
+ 
+@@ -1288,10 +1121,11 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ 				continue;
+ 
+ 			msta = container_of(wcid, struct mt7996_sta, wcid);
+-			spin_lock_bh(&dev->sta_poll_lock);
+-			if (list_empty(&msta->poll_list))
+-				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_lock_bh(&mdev->sta_poll_lock);
++			if (list_empty(&msta->wcid.poll_list))
++				list_add_tail(&msta->wcid.poll_list,
++					      &mdev->sta_poll_list);
++			spin_unlock_bh(&mdev->sta_poll_lock);
+ 			continue;
+ 		}
+ 
+@@ -1326,9 +1160,10 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ }
+ 
+ static bool
+-mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid, int pid,
+-		       __le32 *txs_data, struct mt76_sta_stats *stats)
++mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
++		       int pid, __le32 *txs_data)
+ {
++	struct mt76_sta_stats *stats = &wcid->stats;
+ 	struct ieee80211_supported_band *sband;
+ 	struct mt76_dev *mdev = &dev->mt76;
+ 	struct mt76_phy *mphy;
+@@ -1490,15 +1325,15 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
+ 
+ 	msta = container_of(wcid, struct mt7996_sta, wcid);
+ 
+-	mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data, &msta->stats);
++	mt7996_mac_add_txs_skb(dev, wcid, pid, txs_data);
+ 
+ 	if (!wcid->sta)
+ 		goto out;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (list_empty(&msta->poll_list))
+-		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (list_empty(&msta->wcid.poll_list))
++		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ out:
+ 	rcu_read_unlock();
+@@ -1611,20 +1446,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy)
+ 	mt7996_mcu_get_chan_mib_info(phy, true);
+ }
+ 
+-void mt7996_mac_set_timing(struct mt7996_phy *phy)
++void mt7996_mac_set_coverage_class(struct mt7996_phy *phy)
+ {
+ 	s16 coverage_class = phy->coverage_class;
+ 	struct mt7996_dev *dev = phy->dev;
+ 	struct mt7996_phy *phy2 = mt7996_phy2(dev);
+ 	struct mt7996_phy *phy3 = mt7996_phy3(dev);
+-	u32 val, reg_offset;
++	u32 reg_offset;
+ 	u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |
+ 		  FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
+ 	u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
+ 		   FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
+ 	u8 band_idx = phy->mt76->band_idx;
+ 	int offset;
+-	bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
+ 
+ 	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
+ 		return;
+@@ -1637,34 +1471,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy)
+ 		coverage_class = max_t(s16, coverage_class,
+ 				       phy3->coverage_class);
+ 
+-	mt76_set(dev, MT_ARB_SCR(band_idx),
+-		 MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
+-	udelay(1);
+-
+ 	offset = 3 * coverage_class;
+ 	reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
+ 		     FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
+ 
+ 	mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset);
+ 	mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset);
+-	mt76_wr(dev, MT_TMAC_ICR0(band_idx),
+-		FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
+-		FIELD_PREP(MT_IFS_RIFS, 2) |
+-		FIELD_PREP(MT_IFS_SIFS, 10) |
+-		FIELD_PREP(MT_IFS_SLOT, phy->slottime));
+-
+-	if (!a_band)
+-		mt76_wr(dev, MT_TMAC_ICR1(band_idx),
+-			FIELD_PREP(MT_IFS_EIFS_CCK, 314));
+-
+-	if (phy->slottime < 20 || a_band)
+-		val = MT7996_CFEND_RATE_DEFAULT;
+-	else
+-		val = MT7996_CFEND_RATE_11B;
+-
+-	mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val);
+-	mt76_clear(dev, MT_ARB_SCR(band_idx),
+-		   MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
+ }
+ 
+ void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band)
+@@ -2048,6 +1860,12 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 		mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
+ 	}
+ 
++	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
++	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
++
++	/* enable DMA Tx/Tx and interrupt */
++	mt7996_dma_start(dev, false);
++
+ 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ 	clear_bit(MT76_RESET, &dev->mphy.state);
+ 	if (phy2)
+@@ -2064,9 +1882,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 
+ 	tasklet_schedule(&dev->mt76.irq_tasklet);
+ 
+-	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
+-	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+-
+ 	mt76_worker_enable(&dev->mt76.tx_worker);
+ 
+ 	local_bh_disable();
+@@ -2193,8 +2008,8 @@ void mt7996_reset(struct mt7996_dev *dev)
+ 
+ void mt7996_mac_update_stats(struct mt7996_phy *phy)
+ {
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	struct mt7996_dev *dev = phy->dev;
+-	struct mib_stats *mib = &phy->mib;
+ 	u8 band_idx = phy->mt76->band_idx;
+ 	u32 cnt;
+ 	int i;
+@@ -2341,7 +2156,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
+ 	u32 changed;
+ 	LIST_HEAD(list);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 	list_splice_init(&dev->sta_rc_list, &list);
+ 
+ 	while (!list_empty(&list)) {
+@@ -2349,7 +2164,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
+ 		list_del_init(&msta->rc_list);
+ 		changed = msta->changed;
+ 		msta->changed = 0;
+-		spin_unlock_bh(&dev->sta_poll_lock);
++		spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 		sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
+ 		vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
+@@ -2361,10 +2176,10 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
+ 
+ 		/* TODO: smps change */
+ 
+-		spin_lock_bh(&dev->sta_poll_lock);
++		spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 	}
+ 
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ }
+ 
+ void mt7996_mac_work(struct work_struct *work)
+diff --git a/mt7996/mac.h b/mt7996/mac.h
+index bc4e6c55..e629324a 100644
+--- a/mt7996/mac.h
++++ b/mt7996/mac.h
+@@ -6,320 +6,7 @@
+ #ifndef __MT7996_MAC_H
+ #define __MT7996_MAC_H
+ 
+-#define MT_CT_PARSE_LEN			72
+-#define MT_CT_DMA_BUF_NUM		2
+-
+-#define MT_RXD0_LENGTH			GENMASK(15, 0)
+-#define MT_RXD0_PKT_TYPE		GENMASK(31, 27)
+-
+-#define MT_RXD0_MESH			BIT(18)
+-#define MT_RXD0_MHCP			BIT(19)
+-#define MT_RXD0_NORMAL_ETH_TYPE_OFS	GENMASK(22, 16)
+-#define MT_RXD0_NORMAL_IP_SUM		BIT(23)
+-#define MT_RXD0_NORMAL_UDP_TCP_SUM	BIT(24)
+-
+-#define MT_RXD0_SW_PKT_TYPE_MASK	GENMASK(31, 16)
+-#define MT_RXD0_SW_PKT_TYPE_MAP		0x380F
+-#define MT_RXD0_SW_PKT_TYPE_FRAME	0x3801
+-
+-/* RXD DW1 */
+-#define MT_RXD1_NORMAL_WLAN_IDX		GENMASK(11, 0)
+-#define MT_RXD1_NORMAL_GROUP_1		BIT(16)
+-#define MT_RXD1_NORMAL_GROUP_2		BIT(17)
+-#define MT_RXD1_NORMAL_GROUP_3		BIT(18)
+-#define MT_RXD1_NORMAL_GROUP_4		BIT(19)
+-#define MT_RXD1_NORMAL_GROUP_5		BIT(20)
+-#define MT_RXD1_NORMAL_KEY_ID		GENMASK(22, 21)
+-#define MT_RXD1_NORMAL_CM		BIT(23)
+-#define MT_RXD1_NORMAL_CLM		BIT(24)
+-#define MT_RXD1_NORMAL_ICV_ERR		BIT(25)
+-#define MT_RXD1_NORMAL_TKIP_MIC_ERR	BIT(26)
+-#define MT_RXD1_NORMAL_BAND_IDX		GENMASK(28, 27)
+-#define MT_RXD1_NORMAL_SPP_EN		BIT(29)
+-#define MT_RXD1_NORMAL_ADD_OM		BIT(30)
+-#define MT_RXD1_NORMAL_SEC_DONE		BIT(31)
+-
+-/* RXD DW2 */
+-#define MT_RXD2_NORMAL_BSSID		GENMASK(5, 0)
+-#define MT_RXD2_NORMAL_MAC_HDR_LEN	GENMASK(12, 8)
+-#define MT_RXD2_NORMAL_HDR_TRANS	BIT(7)
+-#define MT_RXD2_NORMAL_HDR_OFFSET	GENMASK(15, 13)
+-#define MT_RXD2_NORMAL_SEC_MODE		GENMASK(20, 16)
+-#define MT_RXD2_NORMAL_MU_BAR		BIT(21)
+-#define MT_RXD2_NORMAL_SW_BIT		BIT(22)
+-#define MT_RXD2_NORMAL_AMSDU_ERR	BIT(23)
+-#define MT_RXD2_NORMAL_MAX_LEN_ERROR	BIT(24)
+-#define MT_RXD2_NORMAL_HDR_TRANS_ERROR	BIT(25)
+-#define MT_RXD2_NORMAL_INT_FRAME	BIT(26)
+-#define MT_RXD2_NORMAL_FRAG		BIT(27)
+-#define MT_RXD2_NORMAL_NULL_FRAME	BIT(28)
+-#define MT_RXD2_NORMAL_NDATA		BIT(29)
+-#define MT_RXD2_NORMAL_NON_AMPDU	BIT(30)
+-#define MT_RXD2_NORMAL_BF_REPORT	BIT(31)
+-
+-/* RXD DW3 */
+-#define MT_RXD3_NORMAL_RXV_SEQ		GENMASK(7, 0)
+-#define MT_RXD3_NORMAL_CH_FREQ		GENMASK(15, 8)
+-#define MT_RXD3_NORMAL_ADDR_TYPE	GENMASK(17, 16)
+-#define MT_RXD3_NORMAL_U2M		BIT(0)
+-#define MT_RXD3_NORMAL_HTC_VLD		BIT(18)
+-#define MT_RXD3_NORMAL_BEACON_MC	BIT(20)
+-#define MT_RXD3_NORMAL_BEACON_UC	BIT(21)
+-#define MT_RXD3_NORMAL_CO_ANT		BIT(22)
+-#define MT_RXD3_NORMAL_FCS_ERR		BIT(24)
+-#define MT_RXD3_NORMAL_VLAN2ETH		BIT(31)
+-
+-/* RXD DW4 */
+-#define MT_RXD4_NORMAL_PAYLOAD_FORMAT	GENMASK(1, 0)
+-#define MT_RXD4_FIRST_AMSDU_FRAME	GENMASK(1, 0)
+-#define MT_RXD4_MID_AMSDU_FRAME		BIT(1)
+-#define MT_RXD4_LAST_AMSDU_FRAME	BIT(0)
+-
+-#define MT_RXV_HDR_BAND_IDX		BIT(24)
+-
+-/* RXD GROUP4 */
+-#define MT_RXD8_FRAME_CONTROL		GENMASK(15, 0)
+-
+-#define MT_RXD10_SEQ_CTRL		GENMASK(15, 0)
+-#define MT_RXD10_QOS_CTL		GENMASK(31, 16)
+-
+-#define MT_RXD11_HT_CONTROL		GENMASK(31, 0)
+-
+-/* P-RXV */
+-#define MT_PRXV_TX_RATE			GENMASK(6, 0)
+-#define MT_PRXV_TX_DCM			BIT(4)
+-#define MT_PRXV_TX_ER_SU_106T		BIT(5)
+-#define MT_PRXV_NSTS			GENMASK(10, 7)
+-#define MT_PRXV_TXBF			BIT(11)
+-#define MT_PRXV_HT_AD_CODE		BIT(12)
+-#define MT_PRXV_HE_RU_ALLOC		GENMASK(30, 22)
+-#define MT_PRXV_RCPI3			GENMASK(31, 24)
+-#define MT_PRXV_RCPI2			GENMASK(23, 16)
+-#define MT_PRXV_RCPI1			GENMASK(15, 8)
+-#define MT_PRXV_RCPI0			GENMASK(7, 0)
+-#define MT_PRXV_HT_SHORT_GI		GENMASK(4, 3)
+-#define MT_PRXV_HT_STBC			GENMASK(10, 9)
+-#define MT_PRXV_TX_MODE			GENMASK(14, 11)
+-#define MT_PRXV_FRAME_MODE		GENMASK(2, 0)
+-#define MT_PRXV_DCM			BIT(5)
+-
+-/* C-RXV */
+-#define MT_CRXV_HE_NUM_USER		GENMASK(26, 20)
+-#define MT_CRXV_HE_LTF_SIZE		GENMASK(28, 27)
+-#define MT_CRXV_HE_LDPC_EXT_SYM		BIT(30)
+-
+-#define MT_CRXV_HE_PE_DISAMBIG		BIT(1)
+-#define MT_CRXV_HE_UPLINK		BIT(2)
+-
+-#define MT_CRXV_HE_MU_AID		GENMASK(27, 17)
+-#define MT_CRXV_HE_BEAM_CHNG		BIT(29)
+-
+-#define MT_CRXV_HE_DOPPLER		BIT(0)
+-#define MT_CRXV_HE_BSS_COLOR		GENMASK(15, 10)
+-#define MT_CRXV_HE_TXOP_DUR		GENMASK(19, 17)
+-
+-#define MT_CRXV_HE_SR_MASK		GENMASK(11, 8)
+-#define MT_CRXV_HE_SR1_MASK		GENMASK(16, 12)
+-#define MT_CRXV_HE_SR2_MASK             GENMASK(20, 17)
+-#define MT_CRXV_HE_SR3_MASK             GENMASK(24, 21)
+-
+-#define MT_CRXV_HE_RU0			GENMASK(8, 0)
+-#define MT_CRXV_HE_RU1			GENMASK(17, 9)
+-#define MT_CRXV_HE_RU2			GENMASK(26, 18)
+-#define MT_CRXV_HE_RU3_L		GENMASK(31, 27)
+-#define MT_CRXV_HE_RU3_H		GENMASK(3, 0)
+-
+-enum tx_header_format {
+-	MT_HDR_FORMAT_802_3,
+-	MT_HDR_FORMAT_CMD,
+-	MT_HDR_FORMAT_802_11,
+-	MT_HDR_FORMAT_802_11_EXT,
+-};
+-
+-enum tx_pkt_type {
+-	MT_TX_TYPE_CT,
+-	MT_TX_TYPE_SF,
+-	MT_TX_TYPE_CMD,
+-	MT_TX_TYPE_FW,
+-};
+-
+-enum tx_port_idx {
+-	MT_TX_PORT_IDX_LMAC,
+-	MT_TX_PORT_IDX_MCU
+-};
+-
+-enum tx_mcu_port_q_idx {
+-	MT_TX_MCU_PORT_RX_Q0 = 0x20,
+-	MT_TX_MCU_PORT_RX_Q1,
+-	MT_TX_MCU_PORT_RX_Q2,
+-	MT_TX_MCU_PORT_RX_Q3,
+-	MT_TX_MCU_PORT_RX_FWDL = 0x3e
+-};
+-
+-enum tx_mgnt_type {
+-	MT_TX_NORMAL,
+-	MT_TX_TIMING,
+-	MT_TX_ADDBA,
+-};
+-
+-#define MT_CT_INFO_APPLY_TXD		BIT(0)
+-#define MT_CT_INFO_COPY_HOST_TXD_ALL	BIT(1)
+-#define MT_CT_INFO_MGMT_FRAME		BIT(2)
+-#define MT_CT_INFO_NONE_CIPHER_FRAME	BIT(3)
+-#define MT_CT_INFO_HSR2_TX		BIT(4)
+-#define MT_CT_INFO_FROM_HOST		BIT(7)
+-
+-#define MT_TXD_SIZE			(8 * 4)
+-
+-#define MT_TXD0_Q_IDX			GENMASK(31, 25)
+-#define MT_TXD0_PKT_FMT			GENMASK(24, 23)
+-#define MT_TXD0_ETH_TYPE_OFFSET		GENMASK(22, 16)
+-#define MT_TXD0_TX_BYTES		GENMASK(15, 0)
+-
+-#define MT_TXD1_FIXED_RATE		BIT(31)
+-#define MT_TXD1_OWN_MAC			GENMASK(30, 25)
+-#define MT_TXD1_TID			GENMASK(24, 21)
+-#define MT_TXD1_BIP			BIT(24)
+-#define MT_TXD1_ETH_802_3		BIT(20)
+-#define MT_TXD1_HDR_INFO		GENMASK(20, 16)
+-#define MT_TXD1_HDR_FORMAT		GENMASK(15, 14)
+-#define MT_TXD1_TGID			GENMASK(13, 12)
+-#define MT_TXD1_WLAN_IDX		GENMASK(11, 0)
+-
+-#define MT_TXD2_POWER_OFFSET		GENMASK(31, 26)
+-#define MT_TXD2_MAX_TX_TIME		GENMASK(25, 16)
+-#define MT_TXD2_FRAG			GENMASK(15, 14)
+-#define MT_TXD2_HTC_VLD			BIT(13)
+-#define MT_TXD2_DURATION		BIT(12)
+-#define MT_TXD2_HDR_PAD			GENMASK(11, 10)
+-#define MT_TXD2_RTS			BIT(9)
+-#define MT_TXD2_OWN_MAC_MAP		BIT(8)
+-#define MT_TXD2_BF_TYPE			GENMASK(6, 7)
+-#define MT_TXD2_FRAME_TYPE		GENMASK(5, 4)
+-#define MT_TXD2_SUB_TYPE		GENMASK(3, 0)
+-
+-#define MT_TXD3_SN_VALID		BIT(31)
+-#define MT_TXD3_PN_VALID		BIT(30)
+-#define MT_TXD3_SW_POWER_MGMT		BIT(29)
+-#define MT_TXD3_BA_DISABLE		BIT(28)
+-#define MT_TXD3_SEQ			GENMASK(27, 16)
+-#define MT_TXD3_REM_TX_COUNT		GENMASK(15, 11)
+-#define MT_TXD3_TX_COUNT		GENMASK(10, 6)
+-#define MT_TXD3_HW_AMSDU		BIT(5)
+-#define MT_TXD3_BCM			BIT(4)
+-#define MT_TXD3_EEOSP			BIT(3)
+-#define MT_TXD3_EMRD			BIT(2)
+-#define MT_TXD3_PROTECT_FRAME		BIT(1)
+-#define MT_TXD3_NO_ACK			BIT(0)
+-
+-#define MT_TXD4_PN_LOW			GENMASK(31, 0)
+-
+-#define MT_TXD5_PN_HIGH			GENMASK(31, 16)
+-#define MT_TXD5_FL			BIT(15)
+-#define MT_TXD5_BYPASS_TBB		BIT(14)
+-#define MT_TXD5_BYPASS_RBB		BIT(13)
+-#define MT_TXD5_BSS_COLOR_ZERO		BIT(12)
+-#define MT_TXD5_TX_STATUS_HOST		BIT(10)
+-#define MT_TXD5_TX_STATUS_MCU		BIT(9)
+-#define MT_TXD5_TX_STATUS_FMT		BIT(8)
+-#define MT_TXD5_PID			GENMASK(7, 0)
+-
+-#define MT_TXD6_TX_SRC			GENMASK(31, 30)
+-#define MT_TXD6_VTA			BIT(28)
+-#define MT_TXD6_BW			GENMASK(25, 22)
+-#define MT_TXD6_TX_RATE			GENMASK(21, 16)
+-#define MT_TXD6_TIMESTAMP_OFS_EN	BIT(15)
+-#define MT_TXD6_TIMESTAMP_OFS_IDX	GENMASK(14, 10)
+-#define MT_TXD6_MSDU_CNT		GENMASK(9, 4)
+-#define MT_TXD6_DIS_MAT			BIT(3)
+-#define MT_TXD6_DAS			BIT(2)
+-#define MT_TXD6_AMSDU_CAP		BIT(1)
+-
+-#define MT_TXD7_TXD_LEN			GENMASK(31, 30)
+-#define MT_TXD7_IP_SUM			BIT(29)
+-#define MT_TXD7_DROP_BY_SDO		BIT(28)
+-#define MT_TXD7_MAC_TXD			BIT(27)
+-#define MT_TXD7_CTXD			BIT(26)
+-#define MT_TXD7_CTXD_CNT		GENMASK(25, 22)
+-#define MT_TXD7_UDP_TCP_SUM		BIT(15)
+-#define MT_TXD7_TX_TIME			GENMASK(9, 0)
+-
+-#define MT_TX_RATE_STBC			BIT(14)
+-#define MT_TX_RATE_NSS			GENMASK(13, 10)
+-#define MT_TX_RATE_MODE			GENMASK(9, 6)
+-#define MT_TX_RATE_SU_EXT_TONE		BIT(5)
+-#define MT_TX_RATE_DCM			BIT(4)
+-/* VHT/HE only use bits 0-3 */
+-#define MT_TX_RATE_IDX			GENMASK(5, 0)
+-
+-#define MT_TXFREE0_PKT_TYPE		GENMASK(31, 27)
+-#define MT_TXFREE0_MSDU_CNT		GENMASK(25, 16)
+-#define MT_TXFREE0_RX_BYTE		GENMASK(15, 0)
+-
+-#define MT_TXFREE1_VER			GENMASK(18, 16)
+-
+-#define MT_TXFREE_INFO_PAIR		BIT(31)
+-#define MT_TXFREE_INFO_HEADER		BIT(30)
+-#define MT_TXFREE_INFO_WLAN_ID		GENMASK(23, 12)
+-#define MT_TXFREE_INFO_MSDU_ID		GENMASK(14, 0)
+-
+-#define MT_TXS0_BW			GENMASK(31, 29)
+-#define MT_TXS0_TID			GENMASK(28, 26)
+-#define MT_TXS0_AMPDU			BIT(25)
+-#define MT_TXS0_TXS_FORMAT		GENMASK(24, 23)
+-#define MT_TXS0_BA_ERROR		BIT(22)
+-#define MT_TXS0_PS_FLAG			BIT(21)
+-#define MT_TXS0_TXOP_TIMEOUT		BIT(20)
+-#define MT_TXS0_BIP_ERROR		BIT(19)
+-
+-#define MT_TXS0_QUEUE_TIMEOUT		BIT(18)
+-#define MT_TXS0_RTS_TIMEOUT		BIT(17)
+-#define MT_TXS0_ACK_TIMEOUT		BIT(16)
+-#define MT_TXS0_ACK_ERROR_MASK		GENMASK(18, 16)
+-
+-#define MT_TXS0_TX_STATUS_HOST		BIT(15)
+-#define MT_TXS0_TX_STATUS_MCU		BIT(14)
+-#define MT_TXS0_TX_RATE			GENMASK(13, 0)
+-
+-#define MT_TXS1_SEQNO			GENMASK(31, 20)
+-#define MT_TXS1_RESP_RATE		GENMASK(19, 16)
+-#define MT_TXS1_RXV_SEQNO		GENMASK(15, 8)
+-#define MT_TXS1_TX_POWER_DBM		GENMASK(7, 0)
+-
+-#define MT_TXS2_BF_STATUS		GENMASK(31, 30)
+-#define MT_TXS2_BAND			GENMASK(29, 28)
+-#define MT_TXS2_WCID			GENMASK(27, 16)
+-#define MT_TXS2_TX_DELAY		GENMASK(15, 0)
+-
+-#define MT_TXS3_PID			GENMASK(31, 24)
+-#define MT_TXS3_RATE_STBC		BIT(7)
+-#define MT_TXS3_FIXED_RATE		BIT(6)
+-#define MT_TXS3_SRC			GENMASK(5, 4)
+-#define MT_TXS3_SHARED_ANTENNA		BIT(3)
+-#define MT_TXS3_LAST_TX_RATE		GENMASK(2, 0)
+-
+-#define MT_TXS4_TIMESTAMP		GENMASK(31, 0)
+-
+-#define MT_TXS5_F0_FINAL_MPDU		BIT(31)
+-#define MT_TXS5_F0_QOS			BIT(30)
+-#define MT_TXS5_F0_TX_COUNT		GENMASK(29, 25)
+-#define MT_TXS5_F0_FRONT_TIME		GENMASK(24, 0)
+-#define MT_TXS5_F1_MPDU_TX_COUNT	GENMASK(31, 24)
+-#define MT_TXS5_F1_MPDU_TX_BYTES	GENMASK(23, 0)
+-
+-#define MT_TXS6_F0_NOISE_3		GENMASK(31, 24)
+-#define MT_TXS6_F0_NOISE_2		GENMASK(23, 16)
+-#define MT_TXS6_F0_NOISE_1		GENMASK(15, 8)
+-#define MT_TXS6_F0_NOISE_0		GENMASK(7, 0)
+-#define MT_TXS6_F1_MPDU_FAIL_COUNT	GENMASK(31, 24)
+-#define MT_TXS6_F1_MPDU_FAIL_BYTES	GENMASK(23, 0)
+-
+-#define MT_TXS7_F0_RCPI_3		GENMASK(31, 24)
+-#define MT_TXS7_F0_RCPI_2		GENMASK(23, 16)
+-#define MT_TXS7_F0_RCPI_1		GENMASK(15, 8)
+-#define MT_TXS7_F0_RCPI_0		GENMASK(7, 0)
+-#define MT_TXS7_F1_MPDU_RETRY_COUNT	GENMASK(31, 24)
+-#define MT_TXS7_F1_MPDU_RETRY_BYTES	GENMASK(23, 0)
++#include "../mt76_connac3_mac.h"
+ 
+ struct mt7996_dfs_pulse {
+ 	u32 max_width;		/* us */
+diff --git a/mt7996/main.c b/mt7996/main.c
+index f306e9c5..c3a479dc 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -43,6 +43,10 @@ int mt7996_run(struct ieee80211_hw *hw)
+ 	if (ret)
+ 		goto out;
+ 
++	ret = mt7996_mcu_set_radio_en(phy, true);
++	if (ret)
++		goto out;
++
+ 	ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_RX_PATH);
+ 	if (ret)
+ 		goto out;
+@@ -82,6 +86,8 @@ static void mt7996_stop(struct ieee80211_hw *hw)
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 
++	mt7996_mcu_set_radio_en(phy, false);
++
+ 	clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
+ 
+ 	mutex_unlock(&dev->mt76.mutex);
+@@ -190,17 +196,13 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
+ 	if (ret)
+ 		goto out;
+ 
+-	ret = mt7996_mcu_set_radio_en(phy, true);
+-	if (ret)
+-		goto out;
+-
+ 	dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);
+ 	phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
+ 
+ 	idx = MT7996_WTBL_RESERVED - mvif->mt76.idx;
+ 
+ 	INIT_LIST_HEAD(&mvif->sta.rc_list);
+-	INIT_LIST_HEAD(&mvif->sta.poll_list);
++	INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);
+ 	mvif->sta.wcid.idx = idx;
+ 	mvif->sta.wcid.phy_idx = band_idx;
+ 	mvif->sta.wcid.hw_key_idx = -1;
+@@ -221,9 +223,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
+ 	vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
+ 
+ 	if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)
+-		mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
++		mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
+ 	else
+-		mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL;
++		mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL;
+ 
+ 	mt7996_init_bitrate_mask(vif);
+ 
+@@ -253,7 +255,6 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
+ 		phy->monitor_vif = NULL;
+ 
+ 	mt7996_mcu_add_dev_info(phy, vif, false);
+-	mt7996_mcu_set_radio_en(phy, false);
+ 
+ 	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
+ 
+@@ -262,10 +263,10 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
+ 	phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
+ 	mutex_unlock(&dev->mt76.mutex);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ 
+ 	mt76_packet_id_flush(&dev->mt76, &msta->wcid);
+ }
+@@ -286,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy)
+ 	if (ret)
+ 		goto out;
+ 
+-	mt7996_mac_set_timing(phy);
+ 	ret = mt7996_dfs_init_radar_detector(phy);
+ 	mt7996_mac_cca_stats_reset(phy);
+ 
+@@ -505,7 +505,7 @@ static u8
+ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		       bool beacon, bool mcast)
+ {
+-	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
+ 	struct mt76_phy *mphy = hw->priv;
+ 	u16 rate;
+ 	u8 i, idx, ht;
+@@ -517,7 +517,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ 
+ 		/* must odd index */
+-		idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20);
++		idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->idx % 20);
+ 		mt7996_mac_set_fixed_rate_table(dev, idx, rate);
+ 		return idx;
+ 	}
+@@ -530,12 +530,32 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	return mvif->basic_rates_idx;
+ }
+ 
++static void
++mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++		       struct ieee80211_bss_conf *info)
++{
++	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt7996_dev *dev = mt7996_hw_dev(hw);
++	u8 band = mvif->mt76.band_idx;
++	u32 *mu;
++
++	mu = (u32 *)info->mu_group.membership;
++	mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD0(band), mu[0]);
++	mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_VLD1(band), mu[1]);
++
++	mu = (u32 *)info->mu_group.position;
++	mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS0(band), mu[0]);
++	mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS1(band), mu[1]);
++	mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS2(band), mu[2]);
++	mt76_wr(dev, MT_WF_PHYRX_BAND_GID_TAB_POS3(band), mu[3]);
++}
++
+ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
+ 				    struct ieee80211_vif *vif,
+ 				    struct ieee80211_bss_conf *info,
+ 				    u64 changed)
+ {
+-	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
+ 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ 	struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ 
+@@ -563,7 +583,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
+ 
+ 		if (slottime != phy->slottime) {
+ 			phy->slottime = slottime;
+-			mt7996_mac_set_timing(phy);
++			mt7996_mcu_set_timing(phy, vif);
+ 		}
+ 	}
+ 
+@@ -602,6 +622,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
+ 	    changed & BSS_CHANGED_FILS_DISCOVERY)
+ 		mt7996_mcu_beacon_inband_discov(dev, vif, changed);
+ 
++	if (changed & BSS_CHANGED_MU_GROUPS)
++		mt7996_update_mu_group(hw, vif, info);
++
+ 	mutex_unlock(&dev->mt76.mutex);
+ }
+ 
+@@ -631,7 +654,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 		return -ENOSPC;
+ 
+ 	INIT_LIST_HEAD(&msta->rc_list);
+-	INIT_LIST_HEAD(&msta->poll_list);
++	INIT_LIST_HEAD(&msta->wcid.poll_list);
+ 	msta->vif = mvif;
+ 	msta->wcid.sta = 1;
+ 	msta->wcid.idx = idx;
+@@ -666,12 +689,12 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 	for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
+ 		mt7996_mac_twt_teardown_flow(dev, msta, i);
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
+-	if (!list_empty(&msta->poll_list))
+-		list_del_init(&msta->poll_list);
++	spin_lock_bh(&mdev->sta_poll_lock);
++	if (!list_empty(&msta->wcid.poll_list))
++		list_del_init(&msta->wcid.poll_list);
+ 	if (!list_empty(&msta->rc_list))
+ 		list_del_init(&msta->rc_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&mdev->sta_poll_lock);
+ }
+ 
+ static void mt7996_tx(struct ieee80211_hw *hw,
+@@ -751,16 +774,16 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ 	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ 		mtxq->aggr = false;
+-		clear_bit(tid, &msta->ampdu_state);
++		clear_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = mt7996_mcu_add_tx_ba(dev, params, false);
+ 		break;
+ 	case IEEE80211_AMPDU_TX_START:
+-		set_bit(tid, &msta->ampdu_state);
++		set_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
+ 		break;
+ 	case IEEE80211_AMPDU_TX_STOP_CONT:
+ 		mtxq->aggr = false;
+-		clear_bit(tid, &msta->ampdu_state);
++		clear_bit(tid, &msta->wcid.ampdu_state);
+ 		ret = mt7996_mcu_add_tx_ba(dev, params, false);
+ 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ 		break;
+@@ -792,7 +815,7 @@ mt7996_get_stats(struct ieee80211_hw *hw,
+ {
+ 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ 	struct mt7996_dev *dev = mt7996_hw_dev(hw);
+-	struct mib_stats *mib = &phy->mib;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 
+@@ -903,7 +926,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
+ 
+ 	mutex_lock(&dev->mt76.mutex);
+ 	phy->coverage_class = max_t(s16, coverage_class, 0);
+-	mt7996_mac_set_timing(phy);
++	mt7996_mac_set_coverage_class(phy);
+ 	mutex_unlock(&dev->mt76.mutex);
+ }
+ 
+@@ -952,18 +975,19 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
+ 	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ 	struct rate_info *txrate = &msta->wcid.rate;
+ 
+-	if (!txrate->legacy && !txrate->flags)
+-		return;
+-
+-	if (txrate->legacy) {
+-		sinfo->txrate.legacy = txrate->legacy;
+-	} else {
+-		sinfo->txrate.mcs = txrate->mcs;
+-		sinfo->txrate.nss = txrate->nss;
+-		sinfo->txrate.bw = txrate->bw;
+-		sinfo->txrate.he_gi = txrate->he_gi;
+-		sinfo->txrate.he_dcm = txrate->he_dcm;
+-		sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
++	if (txrate->legacy || txrate->flags) {
++		if (txrate->legacy) {
++			sinfo->txrate.legacy = txrate->legacy;
++		} else {
++			sinfo->txrate.mcs = txrate->mcs;
++			sinfo->txrate.nss = txrate->nss;
++			sinfo->txrate.bw = txrate->bw;
++			sinfo->txrate.he_gi = txrate->he_gi;
++			sinfo->txrate.he_dcm = txrate->he_dcm;
++			sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
++		}
++		sinfo->txrate.flags = txrate->flags;
++		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+ 	}
+ 	sinfo->txrate.flags = txrate->flags;
+ 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+@@ -981,11 +1005,11 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
+ 	struct mt7996_dev *dev = msta->vif->phy->dev;
+ 	u32 *changed = data;
+ 
+-	spin_lock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 	msta->changed |= *changed;
+ 	if (list_empty(&msta->rc_list))
+ 		list_add_tail(&msta->rc_list, &dev->sta_rc_list);
+-	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
+ }
+ 
+ static void mt7996_sta_rc_update(struct ieee80211_hw *hw,
+@@ -1153,6 +1177,10 @@ static const char mt7996_gstrings_stats[][ETH_GSTRING_LEN] = {
+ 	"v_tx_mcs_11",
+ 	"v_tx_mcs_12",
+ 	"v_tx_mcs_13",
++	"v_tx_nss_1",
++	"v_tx_nss_2",
++	"v_tx_nss_3",
++	"v_tx_nss_4",
+ };
+ 
+ #define MT7996_SSTATS_LEN ARRAY_SIZE(mt7996_gstrings_stats)
+@@ -1186,7 +1214,7 @@ static void mt7996_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
+ 	if (msta->vif->mt76.idx != wi->idx)
+ 		return;
+ 
+-	mt76_ethtool_worker(wi, &msta->stats, true);
++	mt76_ethtool_worker(wi, &msta->wcid.stats, true);
+ }
+ 
+ static
+@@ -1197,11 +1225,11 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw,
+ 	struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ 	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt76_mib_stats *mib = &phy->mib;
+ 	struct mt76_ethtool_worker_info wi = {
+ 		.data = data,
+ 		.idx = mvif->mt76.idx,
+ 	};
+-	struct mib_stats *mib = &phy->mib;
+ 	/* See mt7996_ampdu_stat_read_phy, etc */
+ 	int i, ei = 0;
+ 
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 88e2f9d0..4a30db49 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
+ 		return;
+ 
+-	mphy = dev->mt76.phys[r->band_idx];
++	if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2)
++		mphy = dev->rdd2_phy->mt76;
++	else
++		mphy = dev->mt76.phys[r->band_idx];
++
+ 	if (!mphy)
+ 		return;
+ 
+@@ -600,7 +604,7 @@ static void
+ mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
+ 		       struct mt7996_phy *phy)
+ {
+-	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
+ 	struct bss_rate_tlv *bmc;
+ 	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
+ 	enum nl80211_band band = chandef->chan->band;
+@@ -701,6 +705,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,
+ 				 sizeof(req), true);
+ }
+ 
++static void
++mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
++{
++	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt7996_phy *phy = mvif->phy;
++	struct bss_ifs_time_tlv *ifs_time;
++	struct tlv *tlv;
++	bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;
++
++	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
++
++	ifs_time = (struct bss_ifs_time_tlv *)tlv;
++	ifs_time->slot_valid = true;
++	ifs_time->sifs_valid = true;
++	ifs_time->rifs_valid = true;
++	ifs_time->eifs_valid = true;
++
++	ifs_time->slot_time = cpu_to_le16(phy->slottime);
++	ifs_time->sifs_time = cpu_to_le16(10);
++	ifs_time->rifs_time = cpu_to_le16(2);
++	ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84);
++
++	if (is_2ghz) {
++		ifs_time->eifs_cck_valid = true;
++		ifs_time->eifs_cck_time = cpu_to_le16(314);
++	}
++}
++
+ static int
+ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ 			 struct ieee80211_vif *vif,
+@@ -712,6 +744,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ 	struct cfg80211_chan_def *chandef = &phy->chandef;
+ 	struct mt76_connac_bss_basic_tlv *bss;
+ 	u32 type = CONNECTION_INFRA_AP;
++	u16 sta_wlan_idx = wlan_idx;
+ 	struct tlv *tlv;
+ 	int idx;
+ 
+@@ -731,7 +764,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ 				struct mt76_wcid *wcid;
+ 
+ 				wcid = (struct mt76_wcid *)sta->drv_priv;
+-				wlan_idx = wcid->idx;
++				sta_wlan_idx = wcid->idx;
+ 			}
+ 			rcu_read_unlock();
+ 		}
+@@ -751,7 +784,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ 	bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
+ 	bss->dtim_period = vif->bss_conf.dtim_period;
+ 	bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
+-	bss->sta_idx = cpu_to_le16(wlan_idx);
++	bss->sta_idx = cpu_to_le16(sta_wlan_idx);
+ 	bss->conn_type = cpu_to_le32(type);
+ 	bss->omac_idx = mvif->omac_idx;
+ 	bss->band_idx = mvif->band_idx;
+@@ -825,6 +858,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
+ 		mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
+ 		mt7996_mcu_bss_ra_tlv(skb, vif, phy);
+ 		mt7996_mcu_bss_txcmd_tlv(skb, true);
++		mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
+ 
+ 		if (vif->bss_conf.he_support)
+ 			mt7996_mcu_bss_he_tlv(skb, vif, phy);
+@@ -837,6 +871,23 @@ out:
+ 				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
+ }
+ 
++int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
++{
++	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt7996_dev *dev = phy->dev;
++	struct sk_buff *skb;
++
++	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
++					 MT7996_BSS_UPDATE_MAX_SIZE);
++	if (IS_ERR(skb))
++		return PTR_ERR(skb);
++
++	mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
++
++	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
++				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
++}
++
+ static int
+ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+ 		  struct ieee80211_ampdu_params *params,
+@@ -1050,6 +1101,59 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ 	}
+ }
+ 
++static void
++mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
++			struct ieee80211_vif *vif, struct ieee80211_sta *sta)
++{
++	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
++	struct sta_rec_muru *muru;
++	struct tlv *tlv;
++
++	if (vif->type != NL80211_IFTYPE_STATION &&
++	    vif->type != NL80211_IFTYPE_AP)
++		return;
++
++	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
++
++	muru = (struct sta_rec_muru *)tlv;
++	muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer ||
++			       vif->bss_conf.he_mu_beamformer ||
++			       vif->bss_conf.vht_mu_beamformer ||
++			       vif->bss_conf.vht_mu_beamformee;
++	muru->cfg.ofdma_dl_en = true;
++
++	if (sta->deflink.vht_cap.vht_supported)
++		muru->mimo_dl.vht_mu_bfee =
++			!!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
++
++	if (!sta->deflink.he_cap.has_he)
++		return;
++
++	muru->mimo_dl.partial_bw_dl_mimo =
++		HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]);
++
++	muru->mimo_ul.full_ul_mimo =
++		HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]);
++	muru->mimo_ul.partial_ul_mimo =
++		HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);
++
++	muru->ofdma_dl.punc_pream_rx =
++		HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
++	muru->ofdma_dl.he_20m_in_40m_2g =
++		HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]);
++	muru->ofdma_dl.he_20m_in_160m =
++		HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
++	muru->ofdma_dl.he_80m_in_160m =
++		HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);
++
++	muru->ofdma_ul.t_frame_dur =
++		HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
++	muru->ofdma_ul.mu_cascading =
++		HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]);
++	muru->ofdma_ul.uo_ra =
++		HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]);
++}
++
+ static inline bool
+ mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
+ 			struct ieee80211_sta *sta, bool bfee)
+@@ -1727,7 +1831,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ 		mt7996_mcu_sta_he_6g_tlv(skb, sta);
+ 		/* starec eht */
+ 		mt7996_mcu_sta_eht_tlv(skb, sta);
+-		/* TODO: starec muru */
++		/* starec muru */
++		mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);
+ 		/* starec bfee */
+ 		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+ 		/* starec hdr trans */
+@@ -2155,7 +2260,7 @@ out:
+ static int
+ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
+ 			     const struct mt7996_fw_trailer *hdr,
+-			     const u8 *data, bool is_wa)
++			     const u8 *data, enum mt7996_ram_type type)
+ {
+ 	int i, offset = 0;
+ 	u32 override = 0, option = 0;
+@@ -2167,8 +2272,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
+ 
+ 		region = (const struct mt7996_fw_region *)((const u8 *)hdr -
+ 			 (hdr->n_region - i) * sizeof(*region));
++		/* DSP and WA use same mode */
+ 		mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
+-						   region->feature_set, is_wa);
++						   region->feature_set,
++						   type != MT7996_RAM_TYPE_WM);
+ 		len = le32_to_cpu(region->len);
+ 		addr = le32_to_cpu(region->addr);
+ 
+@@ -2195,19 +2302,22 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
+ 	if (override)
+ 		option |= FW_START_OVERRIDE;
+ 
+-	if (is_wa)
++	if (type == MT7996_RAM_TYPE_WA)
+ 		option |= FW_START_WORKING_PDA_CR4;
++	else if (type == MT7996_RAM_TYPE_DSP)
++		option |= FW_START_WORKING_PDA_DSP;
+ 
+ 	return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
+ }
+ 
+-static int mt7996_load_ram(struct mt7996_dev *dev)
++static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
++			     const char *fw_file, enum mt7996_ram_type ram_type)
+ {
+ 	const struct mt7996_fw_trailer *hdr;
+ 	const struct firmware *fw;
+ 	int ret;
+ 
+-	ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev);
++	ret = request_firmware(&fw, fw_file, dev->mt76.dev);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -2217,37 +2327,13 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+ 		goto out;
+ 	}
+ 
+-	hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
++	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
++	dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n",
++		 fw_type, hdr->fw_ver, hdr->build_date);
+ 
+-	dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
+-		 hdr->fw_ver, hdr->build_date);
+-
+-	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false);
++	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type);
+ 	if (ret) {
+-		dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
+-		goto out;
+-	}
+-
+-	release_firmware(fw);
+-
+-	ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev);
+-	if (ret)
+-		return ret;
+-
+-	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
+-		dev_err(dev->mt76.dev, "Invalid firmware\n");
+-		ret = -EINVAL;
+-		goto out;
+-	}
+-
+-	hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
+-
+-	dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
+-		 hdr->fw_ver, hdr->build_date);
+-
+-	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true);
+-	if (ret) {
+-		dev_err(dev->mt76.dev, "Failed to start WA firmware\n");
++		dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type);
+ 		goto out;
+ 	}
+ 
+@@ -2261,6 +2347,24 @@ out:
+ 	return ret;
+ }
+ 
++static int mt7996_load_ram(struct mt7996_dev *dev)
++{
++	int ret;
++
++	ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
++				MT7996_RAM_TYPE_WM);
++	if (ret)
++		return ret;
++
++	ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
++				MT7996_RAM_TYPE_DSP);
++	if (ret)
++		return ret;
++
++	return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
++				 MT7996_RAM_TYPE_WA);
++}
++
+ static int
+ mt7996_firmware_state(struct mt7996_dev *dev, bool wa)
+ {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index d7075a4d..078f8285 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -317,6 +317,22 @@ struct bss_sec_tlv {
+ 	u8 __rsv2[1];
+ } __packed;
+ 
++struct bss_ifs_time_tlv {
++	__le16 tag;
++	__le16 len;
++	u8 slot_valid;
++	u8 sifs_valid;
++	u8 rifs_valid;
++	u8 eifs_valid;
++	__le16 slot_time;
++	__le16 sifs_time;
++	__le16 rifs_time;
++	__le16 eifs_time;
++	u8 eifs_cck_valid;
++	u8 rsv;
++	__le16 eifs_cck_time;
++} __packed;
++
+ struct bss_power_save {
+ 	__le16 tag;
+ 	__le16 len;
+@@ -552,6 +568,7 @@ enum {
+ 					 sizeof(struct bss_txcmd_tlv) +		\
+ 					 sizeof(struct bss_power_save) +	\
+ 					 sizeof(struct bss_sec_tlv) +		\
++					 sizeof(struct bss_ifs_time_tlv) +	\
+ 					 sizeof(struct bss_mld_tlv))
+ 
+ #define MT7996_STA_UPDATE_MAX_SIZE	(sizeof(struct sta_req_hdr) +		\
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 4d7dcb95..726c222e 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -26,15 +26,17 @@
+ 
+ #define MT7996_RX_RING_SIZE		1536
+ #define MT7996_RX_MCU_RING_SIZE		512
++#define MT7996_RX_MCU_RING_SIZE_WA	1024
+ 
+ #define MT7996_FIRMWARE_WA		"mediatek/mt7996/mt7996_wa.bin"
+ #define MT7996_FIRMWARE_WM		"mediatek/mt7996/mt7996_wm.bin"
++#define MT7996_FIRMWARE_DSP		"mediatek/mt7996/mt7996_dsp.bin"
+ #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
+ 
+ #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_SIZE		7680
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+-#define MT7996_TOKEN_SIZE		8192
++#define MT7996_TOKEN_SIZE		16384
+ 
+ #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
+ #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
+@@ -52,6 +54,12 @@ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+ struct mt7996_dfs_pattern;
+ 
++enum mt7996_ram_type {
++	MT7996_RAM_TYPE_WM,
++	MT7996_RAM_TYPE_WA,
++	MT7996_RAM_TYPE_DSP,
++};
++
+ enum mt7996_txq_id {
+ 	MT7996_TXQ_FWDL = 16,
+ 	MT7996_TXQ_MCU_WM,
+@@ -95,7 +103,6 @@ struct mt7996_sta {
+ 
+ 	struct mt7996_vif *vif;
+ 
+-	struct list_head poll_list;
+ 	struct list_head rc_list;
+ 	u32 airtime_ac[8];
+ 
+@@ -104,9 +111,6 @@ struct mt7996_sta {
+ 
+ 	unsigned long changed;
+ 	unsigned long jiffies;
+-	unsigned long ampdu_state;
+-
+-	struct mt76_sta_stats stats;
+ 
+ 	struct mt76_connac_sta_key_conf bip;
+ 
+@@ -124,64 +128,6 @@ struct mt7996_vif {
+ 
+ 	struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
+ 	struct cfg80211_bitrate_mask bitrate_mask;
+-
+-	u8 basic_rates_idx;
+-	u8 mcast_rates_idx;
+-	u8 beacon_rates_idx;
+-};
+-
+-/* per-phy stats.  */
+-struct mib_stats {
+-	u32 ack_fail_cnt;
+-	u32 fcs_err_cnt;
+-	u32 rts_cnt;
+-	u32 rts_retries_cnt;
+-	u32 ba_miss_cnt;
+-	u32 tx_mu_bf_cnt;
+-	u32 tx_mu_mpdu_cnt;
+-	u32 tx_mu_acked_mpdu_cnt;
+-	u32 tx_su_acked_mpdu_cnt;
+-	u32 tx_bf_ibf_ppdu_cnt;
+-	u32 tx_bf_ebf_ppdu_cnt;
+-
+-	u32 tx_bf_rx_fb_all_cnt;
+-	u32 tx_bf_rx_fb_eht_cnt;
+-	u32 tx_bf_rx_fb_he_cnt;
+-	u32 tx_bf_rx_fb_vht_cnt;
+-	u32 tx_bf_rx_fb_ht_cnt;
+-
+-	u32 tx_bf_rx_fb_bw; /* value of last sample, not cumulative */
+-	u32 tx_bf_rx_fb_nc_cnt;
+-	u32 tx_bf_rx_fb_nr_cnt;
+-	u32 tx_bf_fb_cpl_cnt;
+-	u32 tx_bf_fb_trig_cnt;
+-
+-	u32 tx_ampdu_cnt;
+-	u32 tx_stop_q_empty_cnt;
+-	u32 tx_mpdu_attempts_cnt;
+-	u32 tx_mpdu_success_cnt;
+-	/* BF counter is PPDU-based, so remove MPDU-based BF counter */
+-
+-	u32 tx_rwp_fail_cnt;
+-	u32 tx_rwp_need_cnt;
+-
+-	/* rx stats */
+-	u32 rx_fifo_full_cnt;
+-	u32 channel_idle_cnt;
+-	u32 rx_vector_mismatch_cnt;
+-	u32 rx_delimiter_fail_cnt;
+-	u32 rx_len_mismatch_cnt;
+-	u32 rx_mpdu_cnt;
+-	u32 rx_ampdu_cnt;
+-	u32 rx_ampdu_bytes_cnt;
+-	u32 rx_ampdu_valid_subframe_cnt;
+-	u32 rx_ampdu_valid_subframe_bytes_cnt;
+-	u32 rx_pfdrop_cnt;
+-	u32 rx_vec_queue_overflow_drop_cnt;
+-	u32 rx_ba_cnt;
+-
+-	u32 tx_amsdu[8];
+-	u32 tx_amsdu_cnt;
+ };
+ 
+ /* crash-dump */
+@@ -222,7 +168,7 @@ struct mt7996_phy {
+ 	u32 rx_ampdu_ts;
+ 	u32 ampdu_ref;
+ 
+-	struct mib_stats mib;
++	struct mt76_mib_stats mib;
+ 	struct mt76_channel_state state_ts;
+ };
+ 
+@@ -272,9 +218,7 @@ struct mt7996_dev {
+ #endif
+ 
+ 	struct list_head sta_rc_list;
+-	struct list_head sta_poll_list;
+ 	struct list_head twt_list;
+-	spinlock_t sta_poll_lock;
+ 
+ 	u32 hw_pattern;
+ 
+@@ -405,6 +349,7 @@ int mt7996_dma_init(struct mt7996_dev *dev);
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
+ void mt7996_dma_prefetch(struct mt7996_dev *dev);
+ void mt7996_dma_cleanup(struct mt7996_dev *dev);
++void mt7996_dma_start(struct mt7996_dev *dev, bool reset);
+ void mt7996_init_txpower(struct mt7996_dev *dev,
+ 			 struct ieee80211_supported_band *sband);
+ int mt7996_txbf_init(struct mt7996_dev *dev);
+@@ -456,6 +401,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
+ 			    const struct mt7996_dfs_pattern *pattern);
+ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
+ int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
++int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
+ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
+ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ 		       u8 rx_sel, u8 val);
+@@ -519,7 +465,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ 			   struct sk_buff *skb, struct mt76_wcid *wcid,
+ 			   struct ieee80211_key_conf *key, int pid,
+ 			   enum mt76_txq_id qid, u32 changed);
+-void mt7996_mac_set_timing(struct mt7996_phy *phy);
++void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
+ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 		       struct ieee80211_sta *sta);
+ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 64aee3fb..c5301050 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);
+ MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);
+ MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
+ MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
++MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
+ MODULE_FIRMWARE(MT7996_ROM_PATCH);
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index d1d3d154..97beab92 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -557,22 +557,29 @@ enum base_rev {
+ 
+ #define MT_PCIE1_MAC_INT_ENABLE			MT_PCIE1_MAC(0x188)
+ 
++/* PHYRX CSD */
++#define MT_WF_PHYRX_CSD_BASE			0x83000000
++#define MT_WF_PHYRX_CSD(_band, _wf, ofs)	(MT_WF_PHYRX_CSD_BASE + \
++						 ((_band) << 20) + \
++						 ((_wf) << 16) + (ofs))
++#define MT_WF_PHYRX_CSD_IRPI(_band, _wf)	MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
++
+ /* PHYRX CTRL */
+ #define MT_WF_PHYRX_BAND_BASE			0x83080000
+ #define MT_WF_PHYRX_BAND(_band, ofs)		(MT_WF_PHYRX_BAND_BASE + \
+ 						 ((_band) << 20) + (ofs))
+ 
++#define MT_WF_PHYRX_BAND_GID_TAB_VLD0(_band)	MT_WF_PHYRX_BAND(_band, 0x1054)
++#define MT_WF_PHYRX_BAND_GID_TAB_VLD1(_band)	MT_WF_PHYRX_BAND(_band, 0x1058)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS0(_band)	MT_WF_PHYRX_BAND(_band, 0x105c)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS1(_band)	MT_WF_PHYRX_BAND(_band, 0x1060)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS2(_band)	MT_WF_PHYRX_BAND(_band, 0x1064)
++#define MT_WF_PHYRX_BAND_GID_TAB_POS3(_band)	MT_WF_PHYRX_BAND(_band, 0x1068)
++
+ #define MT_WF_PHYRX_BAND_RX_CTRL1(_band)	MT_WF_PHYRX_BAND(_band, 0x2004)
+ #define MT_WF_PHYRX_BAND_RX_CTRL1_IPI_EN	GENMASK(2, 0)
+ #define MT_WF_PHYRX_BAND_RX_CTRL1_STSCNT_EN	GENMASK(11, 9)
+ 
+-/* PHYRX CSD */
+-#define MT_WF_PHYRX_CSD_BASE			0x83000000
+-#define MT_WF_PHYRX_CSD(_band, _wf, ofs)	(MT_WF_PHYRX_CSD_BASE + \
+-						 ((_band) << 20) + \
+-						 ((_wf) << 16) + (ofs))
+-#define MT_WF_PHYRX_CSD_IRPI(_band, _wf)	MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
+-
+ /* PHYRX CSD BAND */
+ #define MT_WF_PHYRX_CSD_BAND_RXTD12(_band)		MT_WF_PHYRX_BAND(_band, 0x8230)
+ #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR_ONLY	BIT(18)
+diff --git a/tx.c b/tx.c
+index 72b3ec71..6cc26cc6 100644
+--- a/tx.c
++++ b/tx.c
+@@ -121,6 +121,7 @@ int
+ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ 		       struct sk_buff *skb)
+ {
++	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ 	struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
+ 	int pid;
+@@ -134,8 +135,14 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ 		return MT_PACKET_ID_NO_ACK;
+ 
+ 	if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
+-			     IEEE80211_TX_CTL_RATE_CTRL_PROBE)))
++			     IEEE80211_TX_CTL_RATE_CTRL_PROBE))) {
++		if (mtk_wed_device_active(&dev->mmio.wed) &&
++		    ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) ||
++		     ieee80211_is_data(hdr->frame_control)))
++			return MT_PACKET_ID_WED;
++
+ 		return MT_PACKET_ID_NO_SKB;
++	}
+ 
+ 	spin_lock_bh(&dev->status_lock);
+ 
+@@ -263,8 +270,15 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
+ #endif
+ 
+ 	if (cb->pktid < MT_PACKET_ID_FIRST) {
++		struct ieee80211_rate_status rs = {};
++
+ 		hw = mt76_tx_status_get_hw(dev, skb);
+ 		status.sta = wcid_to_sta(wcid);
++		if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
++			rs.rate_idx = wcid->rate;
++			status.rates = &rs;
++			status.n_rates = 1;
++		}
+ 		spin_lock_bh(&dev->rx_lock);
+ 		ieee80211_tx_status_ext(hw, &status);
+ 		spin_unlock_bh(&dev->rx_lock);
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch b/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch
rename to recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch
index abecf0a..1cce8bc 100644
--- a/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch
@@ -1,7 +1,7 @@
-From 02041c431dd8866954f76bd0d57af44971e1167a Mon Sep 17 00:00:00 2001
+From 478585697afd695e4c55bc1a805523d2f7fb572c Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 23 Mar 2023 08:49:48 +0800
-Subject: [PATCH 2/6] wifi: mt76: mt7915: Update beacon size limitation for 11v
+Subject: [PATCH 1/7] wifi: mt76: mt7915: Update beacon size limitation for 11v
 
 Separate the beacon offload command into two;
 one is for beacons and the other is for inband discovery frames.
@@ -21,10 +21,10 @@
  4 files changed, 45 insertions(+), 33 deletions(-)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 8ce7b1c..14930f5 100644
+index ca5631f..0d94090 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -645,11 +645,13 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+@@ -640,11 +640,13 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
  		mt7915_update_bss_color(hw, vif, &info->he_bss_color);
  
  	if (changed & (BSS_CHANGED_BEACON |
@@ -42,10 +42,10 @@
  }
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 7d9c46b..8ab4239 100644
+index 71eeb54..5661df4 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -1875,10 +1875,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1879,10 +1879,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
  }
  
@@ -59,7 +59,7 @@
  {
  #define OFFLOAD_TX_MODE_SU	BIT(0)
  #define OFFLOAD_TX_MODE_MU	BIT(1)
-@@ -1888,14 +1887,28 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
+@@ -1892,14 +1891,28 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
  	struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
  	enum nl80211_band band = chandef->chan->band;
  	struct mt76_wcid *wcid = &dev->mt76.global_wcid;
@@ -90,7 +90,7 @@
  	if (changed & BSS_CHANGED_FILS_DISCOVERY &&
  	    vif->bss_conf.fils_discovery.max_interval) {
  		interval = vif->bss_conf.fils_discovery.max_interval;
-@@ -1907,26 +1920,25 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
+@@ -1911,26 +1924,25 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
  	}
  
  	if (!skb)
@@ -123,7 +123,7 @@
  	discov->tx_mode = OFFLOAD_TX_MODE_SU;
  	/* 0: UNSOL PROBE RESP, 1: FILS DISCOV */
  	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
-@@ -1934,13 +1946,16 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
+@@ -1938,13 +1950,16 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
  	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
  	discov->enable = true;
  
@@ -141,7 +141,7 @@
  }
  
  int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-@@ -1976,7 +1991,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1980,7 +1995,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	if (!skb)
  		return -EINVAL;
  
@@ -150,7 +150,7 @@
  		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
  		dev_kfree_skb(skb);
  		return -EINVAL;
-@@ -1990,11 +2005,6 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1994,11 +2009,6 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
  	dev_kfree_skb(skb);
  
@@ -199,10 +199,10 @@
  mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
  {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 103cd0d..9c79eff 100644
+index 0c7226b..fe46a36 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -497,6 +497,8 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
+@@ -433,6 +433,8 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
  			 bool add);
  int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  				struct cfg80211_he_bss_color *he_bss_color);
diff --git a/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-fix-background-radar-event-being-bl.patch b/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-fix-background-radar-event-being-bl.patch
deleted file mode 100644
index b40ba17..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0001-wifi-mt76-mt7915-fix-background-radar-event-being-bl.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 2247f39a4638afa622c21bb2b12f2d1744673a57 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Wed, 15 Mar 2023 17:41:16 +0800
-Subject: [PATCH 1/6] wifi: mt76: mt7915: fix background radar event being
- blocked
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7915/mcu.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index aa706ff..7d9c46b 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -277,7 +277,7 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
- 
- 	r = (struct mt7915_mcu_rdd_report *)skb->data;
- 
--	if (r->band_idx > MT_BAND1)
-+	if (r->band_idx > MT_RX_SEL2)
- 		return;
- 
- 	if ((r->band_idx && !dev->phy.mt76->band_idx) &&
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-the-beamformer-issue.patch b/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-fix-the-beamformer-issue.patch
similarity index 80%
rename from recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-the-beamformer-issue.patch
rename to recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-fix-the-beamformer-issue.patch
index 59a5f54..b5df657 100644
--- a/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-the-beamformer-issue.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0002-wifi-mt76-mt7915-fix-the-beamformer-issue.patch
@@ -1,7 +1,7 @@
-From dc866136370fb7ce58bbc27ba7e5fdf40b6138d9 Mon Sep 17 00:00:00 2001
+From ba388175c8a0ecfc3264389cb4d2c49ed2c8b557 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Wed, 12 Apr 2023 15:53:42 +0800
-Subject: [PATCH 4/6] wifi: mt76: mt7915: fix the beamformer issue
+Subject: [PATCH 2/7] wifi: mt76: mt7915: fix the beamformer issue
 
 without this patch, when ap sets the tx stream number to 2,
 ap doesn't send any beamform packets.
@@ -12,10 +12,10 @@
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8ab4239..d374465 100644
+index 5661df4..e820de6 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -1008,13 +1008,13 @@ static inline bool
+@@ -1012,13 +1012,13 @@ static inline bool
  mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  			struct ieee80211_sta *sta, bool bfee)
  {
diff --git a/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch b/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
similarity index 85%
rename from recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
rename to recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
index 253ed63..12bb6ad 100644
--- a/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch
@@ -1,7 +1,7 @@
-From 2692ebd0cb63c666eb7e8db099e71f5b67fcd323 Mon Sep 17 00:00:00 2001
+From a02364eee1308512fd25d3647238dd8da9cf3ae2 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Thu, 18 May 2023 18:11:37 +0800
-Subject: [PATCH 5/6] wifi: mt76: fix incorrect HE TX GI report
+Subject: [PATCH 3/7] wifi: mt76: fix incorrect HE TX GI report
 
 Change GI reporting source from static capability to rate-tuning module.
 
@@ -9,15 +9,15 @@
 ---
  mt76.h          |   4 ++
  mt7915/init.c   |   4 ++
- mt7915/mac.c    |  60 ++++++++++++------
+ mt7915/mac.c    |  64 ++++++++++++-------
  mt7915/main.c   |   7 +++
  mt7915/mcu.c    | 161 ++++++++++++++++++++++++++++++++++++++++++++++++
  mt7915/mcu.h    |  58 +++++++++++++++++
  mt7915/mt7915.h |   6 ++
- 7 files changed, 280 insertions(+), 20 deletions(-)
+ 7 files changed, 282 insertions(+), 22 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 8b4635e..3f13cec 100644
+index 034ab90..1ca23c9 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -254,12 +254,16 @@ struct mt76_queue_ops {
@@ -38,10 +38,10 @@
  	MT_PHY_TYPE_HE_EXT_SU,
  	MT_PHY_TYPE_HE_TB,
 diff --git a/mt7915/init.c b/mt7915/init.c
-index f85f7d3..abca909 100644
+index e156a3c..a47a980 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -648,6 +648,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
+@@ -656,6 +656,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
  	struct mt76_phy *mphy = phy->mt76;
  	int ret;
  
@@ -50,7 +50,7 @@
  	INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);
  
  	mt7915_eeprom_parse_hw_cap(dev, phy);
-@@ -1180,6 +1182,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1188,6 +1190,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
  	dev->phy.dev = dev;
  	dev->phy.mt76 = &dev->mt76.phy;
  	dev->mt76.phy.priv = &dev->phy;
@@ -60,7 +60,7 @@
  	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
  	INIT_LIST_HEAD(&dev->sta_rc_list);
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 7be1e17..a3ed4dd 100644
+index b8b0c0f..789f86a 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -173,15 +173,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
@@ -98,23 +98,26 @@
  		/* get signal strength of resp frames (CTS/BA/ACK) */
  		addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 30);
  		val = mt76_rr(dev, addr);
-@@ -978,6 +958,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -911,6 +891,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+ 		info = le32_to_cpu(*cur_info);
  		if (info & MT_TX_FREE_PAIR) {
  			struct mt7915_sta *msta;
- 			struct mt76_wcid *wcid;
 +			struct mt7915_phy *phy;
  			u16 idx;
  
  			idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
-@@ -987,10 +968,17 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -920,11 +901,18 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  				continue;
  
  			msta = container_of(wcid, struct mt7915_sta, wcid);
+-			spin_lock_bh(&mdev->sta_poll_lock);
 +			phy = msta->vif->phy;
- 			spin_lock_bh(&dev->sta_poll_lock);
- 			if (list_empty(&msta->poll_list))
- 				list_add_tail(&msta->poll_list, &dev->sta_poll_list);
- 			spin_unlock_bh(&dev->sta_poll_lock);
++			spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 			if (list_empty(&msta->wcid.poll_list))
+ 				list_add_tail(&msta->wcid.poll_list,
+ 					      &mdev->sta_poll_list);
+-			spin_unlock_bh(&mdev->sta_poll_lock);
++			spin_unlock_bh(&dev->mt76.sta_poll_lock);
 +
 +			spin_lock_bh(&phy->stats_lock);
 +			if (list_empty(&msta->stats_list))
@@ -124,7 +127,7 @@
  			continue;
  		}
  
-@@ -1051,6 +1039,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
+@@ -1003,6 +991,7 @@ mt7915_mac_tx_free_v0(struct mt7915_dev *dev, void *data, int len)
  static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
  {
  	struct mt7915_sta *msta = NULL;
@@ -132,9 +135,9 @@
  	struct mt76_wcid *wcid;
  	__le32 *txs_data = data;
  	u16 wcidx;
-@@ -1086,6 +1075,11 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
- 		list_add_tail(&msta->poll_list, &dev->sta_poll_list);
- 	spin_unlock_bh(&dev->sta_poll_lock);
+@@ -1038,6 +1027,11 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
+ 		list_add_tail(&msta->wcid.poll_list, &dev->mt76.sta_poll_list);
+ 	spin_unlock_bh(&dev->mt76.sta_poll_lock);
  
 +	phy = msta->vif->phy;
 +	spin_lock_bh(&phy->stats_lock);
@@ -144,7 +147,7 @@
  out:
  	rcu_read_unlock();
  }
-@@ -2012,6 +2006,27 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
+@@ -1950,6 +1944,27 @@ static void mt7915_mac_severe_check(struct mt7915_phy *phy)
  	phy->trb_ts = trb;
  }
  
@@ -172,8 +175,8 @@
  void mt7915_mac_sta_rc_work(struct work_struct *work)
  {
  	struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
-@@ -2067,6 +2082,11 @@ void mt7915_mac_work(struct work_struct *work)
- 		mt7915_mac_severe_check(phy);
+@@ -2008,6 +2023,11 @@ void mt7915_mac_work(struct work_struct *work)
+ 			mt7915_mcu_muru_debug_get(phy);
  	}
  
 +	if (++phy->stats_work_count == 10) {
@@ -185,18 +188,18 @@
  
  	mt76_tx_status_check(mphy->dev, false);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 14930f5..1a741b8 100644
+index 0d94090..06e4291 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -682,6 +682,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -708,6 +708,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  
  	INIT_LIST_HEAD(&msta->rc_list);
- 	INIT_LIST_HEAD(&msta->poll_list);
+ 	INIT_LIST_HEAD(&msta->wcid.poll_list);
 +	INIT_LIST_HEAD(&msta->stats_list);
  	msta->vif = mvif;
  	msta->wcid.sta = 1;
  	msta->wcid.idx = idx;
-@@ -706,6 +707,7 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -732,6 +733,7 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  {
  	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
  	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
@@ -204,10 +207,10 @@
  	int i;
  
  	mt7915_mcu_add_sta(dev, vif, sta, false);
-@@ -722,6 +724,11 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -748,6 +750,11 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (!list_empty(&msta->rc_list))
  		list_del_init(&msta->rc_list);
- 	spin_unlock_bh(&dev->sta_poll_lock);
+ 	spin_unlock_bh(&mdev->sta_poll_lock);
 +
 +	spin_lock_bh(&phy->stats_lock);
 +	if (!list_empty(&msta->stats_list))
@@ -217,10 +220,10 @@
  
  static void mt7915_tx(struct ieee80211_hw *hw,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index d374465..8d8a203 100644
+index e820de6..87cc8d9 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3672,6 +3672,167 @@ out:
+@@ -3711,6 +3711,167 @@ out:
  	return ret;
  }
  
@@ -463,19 +466,19 @@
 +};
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index d1715ff..5451024 100644
+index fe46a36..6abe931 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -138,6 +138,7 @@ struct mt7915_sta {
+@@ -137,6 +137,7 @@ struct mt7915_sta {
+ 	struct mt7915_vif *vif;
  
- 	struct list_head poll_list;
  	struct list_head rc_list;
 +	struct list_head stats_list;
  	u32 airtime_ac[8];
  
  	int ack_signal;
-@@ -273,6 +274,10 @@ struct mt7915_phy {
- 	struct mib_stats mib;
+@@ -210,6 +211,10 @@ struct mt7915_phy {
+ 	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
  
 +	u8 stats_work_count;
@@ -485,7 +488,7 @@
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -544,6 +549,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
+@@ -479,6 +484,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
  int mt7915_mcu_get_temperature(struct mt7915_phy *phy);
  int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
  int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy);
diff --git a/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch b/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch
deleted file mode 100644
index d7deb35..0000000
--- a/recipes-wifi/linux-mt76/files/patches/0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From 98998425cb0089e60f7172552f8231814736e921 Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Thu, 18 May 2023 18:02:17 +0800
-Subject: [PATCH 3/6] wifi: mt76: mt7915: disable wfdma tx/rx during SER
- recovery.
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
----
- dma.c           |   6 ++
- mt7915/dma.c    | 148 +++++++++++++++++++++++++++---------------------
- mt7915/mac.c    |  17 +++++-
- mt7915/mt7915.h |   1 +
- 4 files changed, 103 insertions(+), 69 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 465190e..05d9ab3 100644
---- a/dma.c
-+++ b/dma.c
-@@ -466,6 +466,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
- 	struct mt76_queue_buf buf = {};
- 	dma_addr_t addr;
- 
-+	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
-+		goto error;
-+
- 	if (q->queued + 1 >= q->ndesc - 1)
- 		goto error;
- 
-@@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
- 	dma_addr_t addr;
- 	u8 *txwi;
- 
-+	if (test_bit(MT76_RESET, &dev->phy.state))
-+		goto free_skb;
-+
- 	t = mt76_get_txwi(dev);
- 	if (!t)
- 		goto free_skb;
-diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 86a93de..4c8cf0c 100644
---- a/mt7915/dma.c
-+++ b/mt7915/dma.c
-@@ -250,12 +250,90 @@ static void mt7915_dma_disable(struct mt7915_dev *dev, bool rst)
- 	}
- }
- 
--static int mt7915_dma_enable(struct mt7915_dev *dev)
-+int __mt7915_dma_enable(struct mt7915_dev *dev, bool reset, bool wed_reset)
- {
- 	struct mt76_dev *mdev = &dev->mt76;
- 	u32 hif1_ofs = 0;
- 	u32 irq_mask;
- 
-+	if (dev->hif2)
-+		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	/* enable wpdma tx/rx */
-+	if (!reset) {
-+		mt76_set(dev, MT_WFDMA0_GLO_CFG,
-+			MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+			MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+			MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+			MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+
-+		if (is_mt7915(mdev))
-+			mt76_set(dev, MT_WFDMA1_GLO_CFG,
-+				MT_WFDMA1_GLO_CFG_TX_DMA_EN |
-+				MT_WFDMA1_GLO_CFG_RX_DMA_EN |
-+				MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
-+				MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
-+
-+		if (dev->hif2) {
-+			mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
-+				MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+				MT_WFDMA0_GLO_CFG_RX_DMA_EN |
-+				MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
-+				MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
-+
-+			if (is_mt7915(mdev))
-+				mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
-+					MT_WFDMA1_GLO_CFG_TX_DMA_EN |
-+					MT_WFDMA1_GLO_CFG_RX_DMA_EN |
-+					MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
-+					MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
-+
-+			mt76_set(dev, MT_WFDMA_HOST_CONFIG,
-+				MT_WFDMA_HOST_CONFIG_PDMA_BAND);
-+		}
-+	}
-+
-+	/* enable interrupts for TX/RX rings */
-+	irq_mask = MT_INT_RX_DONE_MCU |
-+		   MT_INT_TX_DONE_MCU |
-+		   MT_INT_MCU_CMD;
-+
-+	if (!dev->phy.mt76->band_idx)
-+		irq_mask |= MT_INT_BAND0_RX_DONE;
-+
-+	if (dev->dbdc_support || dev->phy.mt76->band_idx)
-+		irq_mask |= MT_INT_BAND1_RX_DONE;
-+
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
-+		u32 wed_irq_mask = irq_mask;
-+		int ret;
-+
-+		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
-+		if (!is_mt798x(&dev->mt76))
-+			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
-+		else
-+			mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+
-+		ret = mt7915_mcu_wed_enable_rx_stats(dev);
-+		if (ret)
-+			return ret;
-+
-+		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
-+	}
-+
-+	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-+
-+	mt7915_irq_enable(dev, irq_mask);
-+	mt7915_irq_disable(dev, 0);
-+
-+	return 0;
-+}
-+
-+static int mt7915_dma_enable(struct mt7915_dev *dev, bool reset)
-+{
-+	struct mt76_dev *mdev = &dev->mt76;
-+	u32 hif1_ofs = 0;
-+
- 	if (dev->hif2)
- 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
- 
-@@ -322,69 +400,7 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
- 	mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
- 		  MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
- 
--	/* set WFDMA Tx/Rx */
--	mt76_set(dev, MT_WFDMA0_GLO_CFG,
--		 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
--		 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
--		 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
--		 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
--
--	if (is_mt7915(mdev))
--		mt76_set(dev, MT_WFDMA1_GLO_CFG,
--			 MT_WFDMA1_GLO_CFG_TX_DMA_EN |
--			 MT_WFDMA1_GLO_CFG_RX_DMA_EN |
--			 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
--			 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
--
--	if (dev->hif2) {
--		mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
--			 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
--			 MT_WFDMA0_GLO_CFG_RX_DMA_EN |
--			 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
--			 MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
--
--		if (is_mt7915(mdev))
--			mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
--				 MT_WFDMA1_GLO_CFG_TX_DMA_EN |
--				 MT_WFDMA1_GLO_CFG_RX_DMA_EN |
--				 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
--				 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
--
--		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
--			 MT_WFDMA_HOST_CONFIG_PDMA_BAND);
--	}
--
--	/* enable interrupts for TX/RX rings */
--	irq_mask = MT_INT_RX_DONE_MCU |
--		   MT_INT_TX_DONE_MCU |
--		   MT_INT_MCU_CMD;
--
--	if (!dev->phy.mt76->band_idx)
--		irq_mask |= MT_INT_BAND0_RX_DONE;
--
--	if (dev->dbdc_support || dev->phy.mt76->band_idx)
--		irq_mask |= MT_INT_BAND1_RX_DONE;
--
--	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
--		u32 wed_irq_mask = irq_mask;
--		int ret;
--
--		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
--		if (!is_mt798x(&dev->mt76))
--			mt76_wr(dev, MT_INT_WED_MASK_CSR, wed_irq_mask);
--		else
--			mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
--
--		ret = mt7915_mcu_wed_enable_rx_stats(dev);
--		if (ret)
--			return ret;
--
--		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
--	}
--
--	mt7915_irq_enable(dev, irq_mask);
--
--	return 0;
-+	return __mt7915_dma_enable(dev, reset, true);
- }
- 
- int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
-@@ -560,7 +576,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- 			  mt7915_poll_tx);
- 	napi_enable(&dev->mt76.tx_napi);
- 
--	mt7915_dma_enable(dev);
-+	mt7915_dma_enable(dev, false);
- 
- 	return 0;
- }
-@@ -642,7 +658,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
- 		mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP,
- 			 MT_WFDMA0_EXT0_RXWB_KEEP);
- 
--	mt7915_dma_enable(dev);
-+	mt7915_dma_enable(dev, !force);
- 
- 	return 0;
- }
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index fb6bab8..7be1e17 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -1574,6 +1574,8 @@ void mt7915_mac_reset_work(struct work_struct *work)
- 	if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA))
- 		return;
- 
-+	dev_info(dev->mt76.dev,"%s L1 SER recovery start.\n",
-+		 wiphy_name(dev->mt76.hw->wiphy));
- 	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
- 		mtk_wed_device_stop(&dev->mt76.mmio.wed);
- 		if (!is_mt798x(&dev->mt76))
-@@ -1611,6 +1613,12 @@ void mt7915_mac_reset_work(struct work_struct *work)
- 		mt7915_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
- 	}
- 
-+	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
-+	mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
-+
-+	/* enable dma tx/rx and interrupt */
-+	__mt7915_dma_enable(dev, false, false);
-+
- 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	clear_bit(MT76_RESET, &dev->mphy.state);
- 	if (phy2)
-@@ -1625,9 +1633,6 @@ void mt7915_mac_reset_work(struct work_struct *work)
- 
- 	tasklet_schedule(&dev->mt76.irq_tasklet);
- 
--	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
--	mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
--
- 	mt76_worker_enable(&dev->mt76.tx_worker);
- 
- 	local_bh_disable();
-@@ -1649,6 +1654,8 @@ void mt7915_mac_reset_work(struct work_struct *work)
- 		ieee80211_queue_delayed_work(ext_phy->hw,
- 					     &phy2->mt76->mac_work,
- 					     MT7915_WATCHDOG_TIME);
-+	dev_info(dev->mt76.dev,"%s L1 SER recovery completed.\n",
-+		 wiphy_name(dev->mt76.hw->wiphy));
- }
- 
- /* firmware coredump */
-@@ -1723,6 +1730,10 @@ skip_coredump:
- 
- void mt7915_reset(struct mt7915_dev *dev)
- {
-+	dev_info(dev->mt76.dev, "%s SER recovery state: 0x%08x\n",
-+		 wiphy_name(dev->mt76.hw->wiphy),
-+		 READ_ONCE(dev->recovery.state));
-+
- 	if (!dev->recovery.hw_init_done)
- 		return;
- 
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 9c79eff..d1715ff 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -472,6 +472,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2);
- void mt7915_dma_prefetch(struct mt7915_dev *dev);
- void mt7915_dma_cleanup(struct mt7915_dev *dev);
- int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
-+int __mt7915_dma_enable(struct mt7915_dev *dev, bool reset, bool wed_reset);
- int mt7915_txbf_init(struct mt7915_dev *dev);
- void mt7915_init_txpower(struct mt7915_dev *dev,
- 			 struct ieee80211_supported_band *sband);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch
rename to recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch
index 420aeb0..a0b17c3 100644
--- a/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0004-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch
@@ -1,7 +1,7 @@
-From c32e29ad8916241b5a0bdc5f662e766687524327 Mon Sep 17 00:00:00 2001
+From 7982b31fabc8cecdc45e7b123c76997c4a323ca8 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 17 May 2023 17:34:55 +0800
-Subject: [PATCH 6/6] wifi: mt76: mt7915: fix DFS CAC tx emission issue after
+Subject: [PATCH 4/7] wifi: mt76: mt7915: fix DFS CAC tx emission issue after
  interface down up
 
 FW's channel state is set during the first wifi interface setup. If the switch reason for
@@ -16,10 +16,10 @@
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8d8a203..9dd4e34 100644
+index 87cc8d9..4ac08d0 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2693,12 +2693,12 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
+@@ -2732,12 +2732,12 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
  	if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
  		req.tx_path_num = fls(phy->mt76->antenna_mask);
  
diff --git a/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
similarity index 95%
rename from recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
index b646d67..3ac4b4b 100644
--- a/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0005-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch
@@ -1,7 +1,7 @@
-From a15a9b160d9bb9b52cb697251777c5c39f842f24 Mon Sep 17 00:00:00 2001
+From 086a3d4b3fb679e1a138bae4c86566edfd944902 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 22 May 2023 13:49:37 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add pc stack dump for WM's coredump.
+Subject: [PATCH 5/7] wifi: mt76: mt7915: add pc stack dump for WM's coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -15,7 +15,7 @@
  7 files changed, 207 insertions(+), 71 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 3f13cec6..354acc09 100644
+index 1ca23c9..a4cf9b6 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -27,6 +27,8 @@
@@ -40,7 +40,7 @@
  enum mt76_wed_type {
  	MT76_WED_Q_TX,
  	MT76_WED_Q_TXFREE,
-@@ -776,6 +784,9 @@ struct mt76_dev {
+@@ -782,6 +790,9 @@ struct mt76_dev {
  	struct device *dma_dev;
  
  	struct mt76_mcu mcu;
@@ -51,10 +51,10 @@
  	struct net_device napi_dev;
  	struct net_device tx_napi_dev;
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 46f69aa8..913bad95 100644
+index 0f0a519..cd6ce3c 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -3017,6 +3017,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+@@ -3020,6 +3020,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
  		goto out;
  	}
  
@@ -64,7 +64,7 @@
  	snprintf(dev->hw->wiphy->fw_version,
  		 sizeof(dev->hw->wiphy->fw_version),
  		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
-@@ -3046,6 +3049,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+@@ -3049,6 +3052,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
  		goto out;
  	}
  
@@ -74,7 +74,7 @@
  	snprintf(dev->hw->wiphy->fw_version,
  		 sizeof(dev->hw->wiphy->fw_version),
  		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
-@@ -3116,6 +3122,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
+@@ -3119,6 +3125,9 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
  	dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
  		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
  
@@ -85,7 +85,7 @@
  		struct mt76_connac2_patch_sec *sec;
  		u32 len, addr, mode;
 diff --git a/mt7915/coredump.c b/mt7915/coredump.c
-index 5daf2258..298c1cad 100644
+index 5daf225..298c1ca 100644
 --- a/mt7915/coredump.c
 +++ b/mt7915/coredump.c
 @@ -7,7 +7,7 @@
@@ -413,7 +413,7 @@
  }
  
 diff --git a/mt7915/coredump.h b/mt7915/coredump.h
-index 709f8e9c..809ccbdf 100644
+index 709f8e9..809ccbd 100644
 --- a/mt7915/coredump.h
 +++ b/mt7915/coredump.h
 @@ -4,6 +4,7 @@
@@ -513,10 +513,10 @@
  	return NULL;
  }
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index a3ed4ddf..2a87b506 100644
+index 789f86a..67e7b26 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -1653,28 +1653,31 @@ void mt7915_mac_reset_work(struct work_struct *work)
+@@ -1595,28 +1595,31 @@ void mt7915_mac_reset_work(struct work_struct *work)
  }
  
  /* firmware coredump */
@@ -554,7 +554,7 @@
  	if (!mem_region || !crash_data->memdump_buf_len) {
  		mutex_unlock(&dev->dump_mutex);
  		goto skip_memdump;
-@@ -1684,6 +1687,9 @@ void mt7915_mac_dump_work(struct work_struct *work)
+@@ -1626,6 +1629,9 @@ void mt7915_mac_dump_work(struct work_struct *work)
  	buf_len = crash_data->memdump_buf_len;
  
  	/* dumping memory content... */
@@ -564,7 +564,7 @@
  	memset(buf, 0, buf_len);
  	for (i = 0; i < num; i++) {
  		if (mem_region->len > buf_len) {
-@@ -1701,6 +1707,7 @@ void mt7915_mac_dump_work(struct work_struct *work)
+@@ -1643,6 +1649,7 @@ void mt7915_mac_dump_work(struct work_struct *work)
  		mt7915_memcpy_fromio(dev, buf, mem_region->start,
  				     mem_region->len);
  
@@ -572,7 +572,7 @@
  		hdr->start = mem_region->start;
  		hdr->len = mem_region->len;
  
-@@ -1717,8 +1724,18 @@ void mt7915_mac_dump_work(struct work_struct *work)
+@@ -1659,8 +1666,18 @@ void mt7915_mac_dump_work(struct work_struct *work)
  	mutex_unlock(&dev->dump_mutex);
  
  skip_memdump:
@@ -594,10 +594,10 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 54510245..4fb0a375 100644
+index 6abe931..4de3e05 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -335,7 +335,7 @@ struct mt7915_dev {
+@@ -272,7 +272,7 @@ struct mt7915_dev {
  	struct mutex dump_mutex;
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
@@ -607,10 +607,10 @@
  #endif
  
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 374677f7..636b12da 100644
+index 588cd87..d01b9ea 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
-@@ -1215,4 +1215,24 @@ enum offs_rev {
+@@ -1218,4 +1218,24 @@ enum offs_rev {
  #define MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR	MT_MCU_WM_CIRQ(0x108)
  #define MT_MCU_WM_CIRQ_EINT_SOFT_ADDR		MT_MCU_WM_CIRQ(0x118)
  
diff --git a/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch
rename to recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch
index 5cca53c..fe833e5 100644
--- a/recipes-wifi/linux-mt76/files/patches/0008-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0006-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch
@@ -1,7 +1,8 @@
-From 4fe047234a68854764a3dbf4cfb18ffee441961f Mon Sep 17 00:00:00 2001
+From 50f77fea3f310a623f0fc3656f1a28a7e769c598 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Wed, 24 May 2023 10:17:38 +0800
-Subject: [PATCH] wifi: mt76: mt7915: update mpdu density in 2/5g capability
+Subject: [PATCH 6/7] wifi: mt76: mt7915: update mpdu density in 2/5g
+ capability
 
 Set mpdu density to 2 usec to meet hardware capability
 and also update enhance throughput.
@@ -12,7 +13,7 @@
  1 file changed, 12 insertions(+), 4 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index abca9095..bf2edcc2 100644
+index a47a980..75f8d96 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
 @@ -398,8 +398,12 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
diff --git a/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
similarity index 93%
rename from recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
rename to recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
index 89cb09b..7fa9a8d 100644
--- a/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0007-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch
@@ -1,8 +1,7 @@
-From 74a8d89cbec86aa3cddf05a8ecadc65458fb4f14 Mon Sep 17 00:00:00 2001
+From ef4b8b36345cb50b5186ced6d2c09742f44e6719 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Sat, 1 Apr 2023 08:18:17 +0800
-Subject: [PATCH 0999/1033] wifi: mt76: mt7915: build pass for Linux Kernel 5.4
- fixes
+Subject: [PATCH 7/7] wifi: mt76: mt7915: build pass for Linux Kernel 5.4 fixes
 
 ---
  debugfs.c         |  2 ++
@@ -265,7 +264,7 @@
  	if (!is_valid_ether_addr(phy->macaddr)) {
  		eth_random_addr(phy->macaddr);
 diff --git a/mac80211.c b/mac80211.c
-index 2c4a529..991d91b 100644
+index 8540738..76cb08b 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -4,7 +4,6 @@
@@ -276,7 +275,7 @@
  #include "mt76.h"
  
  #define CHAN2G(_idx, _freq) {			\
-@@ -562,47 +561,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
+@@ -563,47 +562,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
  }
  EXPORT_SYMBOL_GPL(mt76_unregister_phy);
  
@@ -324,7 +323,7 @@
  struct mt76_dev *
  mt76_alloc_device(struct device *pdev, unsigned int size,
  		  const struct ieee80211_ops *ops,
-@@ -1742,21 +1700,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1748,21 +1706,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  }
  EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
  
@@ -359,10 +358,10 @@
  struct sk_buff *
  __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
 diff --git a/mt76.h b/mt76.h
-index 3f13cec..a8f26a8 100644
+index a4cf9b6..35bf19f 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -202,7 +202,7 @@ struct mt76_queue {
+@@ -210,7 +210,7 @@ struct mt76_queue {
  
  	dma_addr_t desc_dma;
  	struct sk_buff *rx_head;
@@ -371,7 +370,7 @@
  };
  
  struct mt76_mcu_ops {
-@@ -1324,7 +1324,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1439,7 +1439,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
  	return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout);
  }
  
@@ -379,7 +378,7 @@
  void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  			 struct mt76_sta_stats *stats, bool eht);
  int mt76_skb_adjust_pad(struct sk_buff *skb, int pad);
-@@ -1436,25 +1435,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+@@ -1551,25 +1550,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
  struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
  int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
  			  struct mt76_txwi_cache *r, dma_addr_t phys);
@@ -418,7 +417,7 @@
  static bool prefer_offload_fw = true;
  module_param(prefer_offload_fw, bool, 0644);
 diff --git a/mt76_connac.h b/mt76_connac.h
-index 77ca8f0..ca26984 100644
+index 22878f0..4560ab7 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -56,7 +56,6 @@ enum {
@@ -438,7 +437,7 @@
  
  	if (chandef->width >= ARRAY_SIZE(width_to_bw))
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 46f69aa..732a4e6 100644
+index cd6ce3c..a558c68 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -4,6 +4,7 @@
@@ -449,7 +448,7 @@
  
  int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
  {
-@@ -1329,40 +1330,6 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1332,40 +1333,6 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  }
  EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
  
@@ -490,7 +489,7 @@
  const struct ieee80211_sta_he_cap *
  mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  {
-@@ -1375,18 +1342,6 @@ mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
+@@ -1378,18 +1345,6 @@ mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  }
  EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap);
  
@@ -510,10 +509,10 @@
  #define DEFAULT_HE_DURATION_RTS_THRES	1023
  static void
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 91d98ef..ebb7f58 100644
+index fe729bb..bd0bf4b 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1883,12 +1883,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
+@@ -1887,12 +1887,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
  
  const struct ieee80211_sta_he_cap *
  mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif);
@@ -527,10 +526,10 @@
  int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
  			    struct mt76_connac_sta_key_conf *sta_key_conf,
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 1a741b8..f78f2bf 100644
+index 06e4291..251df80 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1298,22 +1298,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
+@@ -1361,22 +1361,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
  			   struct ieee80211_vif *vif,
  			   u32 sset, u8 *data)
  {
@@ -559,16 +558,16 @@
  }
  
  static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
-@@ -1341,7 +1338,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1404,7 +1401,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+ 		.idx = mvif->mt76.idx,
  	};
- 	struct mib_stats *mib = &phy->mib;
  	/* See mt7915_ampdu_stat_read_phy, etc */
 -	int i, ei = 0, stats_size;
 +	int i, ei = 0;
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1422,12 +1419,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
+@@ -1516,12 +1513,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
  		return;
  
  	ei += wi.worker_stat_count;
@@ -585,7 +584,7 @@
  
  static void
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 9dd4e34..dbdc48a 100644
+index 4ac08d0..6cf2a3f 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -6,6 +6,7 @@
@@ -597,10 +596,10 @@
  #define fw_name(_dev, name, ...)	({			\
  	char *_fw;						\
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 984b5f6..1bb8a4c 100644
+index fc7ace6..8d92e76 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -596,9 +596,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+@@ -570,9 +570,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
  static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  {
  	struct mt7915_dev *dev;
@@ -614,7 +613,7 @@
  	for (i = 0; i < dev->mt76.rx_token_size; i++) {
  		struct mt76_txwi_cache *t;
  
-@@ -606,7 +610,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -580,7 +584,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  		if (!t || !t->ptr)
  			continue;
  
@@ -625,7 +624,7 @@
  		t->ptr = NULL;
  
  		mt76_put_rxwi(&dev->mt76, t);
-@@ -618,38 +624,47 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -592,38 +598,47 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  {
  	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
@@ -691,7 +690,7 @@
  			goto unmap;
  		}
  
-@@ -661,8 +676,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -635,8 +650,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  	return 0;
  
  unmap:
@@ -701,10 +700,10 @@
  	return -ENOMEM;
  }
 diff --git a/mt7921/main.c b/mt7921/main.c
-index 3b6adb2..47eb38e 100644
+index 87067ac..022cd34 100644
 --- a/mt7921/main.c
 +++ b/mt7921/main.c
-@@ -1083,34 +1083,17 @@ static void
+@@ -1087,34 +1087,17 @@ static void
  mt7921_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		      u32 sset, u8 *data)
  {
@@ -740,15 +739,15 @@
  }
  
  static void
-@@ -1130,7 +1113,6 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1134,7 +1117,6 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  			 struct ethtool_stats *stats, u64 *data)
  {
  	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
 -	int stats_size = ARRAY_SIZE(mt7921_gstrings_stats);
  	struct mt7921_phy *phy = mt7921_hw_phy(hw);
  	struct mt7921_dev *dev = phy->dev;
- 	struct mib_stats *mib = &phy->mib;
-@@ -1186,14 +1168,9 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	struct mt76_mib_stats *mib = &phy->mib;
+@@ -1190,14 +1172,9 @@ void mt7921_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		return;
  
  	ei += wi.worker_stat_count;
diff --git a/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch b/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
similarity index 99%
rename from recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
rename to recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
index 85a5fe8..aa3146d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
+++ b/recipes-wifi/linux-mt76/files/patches/0999-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch
@@ -1,7 +1,8 @@
-From d7349df90b0382edfa3bbed0e48cfcc5a989e79e Mon Sep 17 00:00:00 2001
+From 99a1f11d07da770d1da5278ac751ccc3f44eb72f Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Wed, 22 Jun 2022 10:39:47 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add mtk internal debug tools for mt76
+Subject: [PATCH 0999/1031] wifi: mt76: mt7915: add mtk internal debug tools
+ for mt76
 
 ---
  mt76_connac_mcu.h     |    6 +
@@ -22,10 +23,10 @@
  create mode 100644 mt7915/mtk_mcu.c
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index ebb7f587..8d6c422b 100644
+index bd0bf4b..ab3b58e 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1148,6 +1148,7 @@ enum {
+@@ -1151,6 +1151,7 @@ enum {
  	MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
  	MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
  	MCU_EXT_CMD_TXBF_ACTION = 0x1e,
@@ -33,7 +34,7 @@
  	MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
  	MCU_EXT_CMD_THERMAL_PROT = 0x23,
  	MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
-@@ -1171,6 +1172,11 @@ enum {
+@@ -1174,6 +1175,11 @@ enum {
  	MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
  	MCU_EXT_CMD_RXDCOC_CAL = 0x59,
  	MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
@@ -46,7 +47,7 @@
  	MCU_EXT_CMD_CAL_CACHE = 0x67,
  	MCU_EXT_CMD_RED_ENABLE = 0x68,
 diff --git a/mt7915/Makefile b/mt7915/Makefile
-index c4dca9c1..fd711416 100644
+index c4dca9c..fd71141 100644
 --- a/mt7915/Makefile
 +++ b/mt7915/Makefile
 @@ -4,7 +4,7 @@ EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
@@ -59,7 +60,7 @@
  mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
  mt7915e-$(CONFIG_MT798X_WMAC) += soc.o
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 879884ea..9fca0093 100644
+index 6c3696c..d66d104 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -8,6 +8,9 @@
@@ -72,7 +73,7 @@
  
  /** global debugfs **/
  
-@@ -504,6 +507,9 @@ mt7915_fw_debug_wm_set(void *data, u64 val)
+@@ -496,6 +499,9 @@ mt7915_fw_debug_wm_set(void *data, u64 val)
  	int ret;
  
  	dev->fw.debug_wm = val ? MCU_FW_LOG_TO_HOST : 0;
@@ -82,7 +83,7 @@
  
  	if (dev->fw.debug_bin)
  		val = 16;
-@@ -528,6 +534,9 @@ mt7915_fw_debug_wm_set(void *data, u64 val)
+@@ -520,6 +526,9 @@ mt7915_fw_debug_wm_set(void *data, u64 val)
  		if (ret)
  			goto out;
  	}
@@ -92,7 +93,7 @@
  
  	/* WM CPU info record control */
  	mt76_clear(dev, MT_CPU_UTIL_CTRL, BIT(0));
-@@ -535,6 +544,12 @@ mt7915_fw_debug_wm_set(void *data, u64 val)
+@@ -527,6 +536,12 @@ mt7915_fw_debug_wm_set(void *data, u64 val)
  	mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR, BIT(5));
  	mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR, BIT(5));
  
@@ -105,7 +106,7 @@
  out:
  	if (ret)
  		dev->fw.debug_wm = 0;
-@@ -547,7 +562,11 @@ mt7915_fw_debug_wm_get(void *data, u64 *val)
+@@ -539,7 +554,11 @@ mt7915_fw_debug_wm_get(void *data, u64 *val)
  {
  	struct mt7915_dev *dev = data;
  
@@ -118,7 +119,7 @@
  
  	return 0;
  }
-@@ -622,16 +641,30 @@ mt7915_fw_debug_bin_set(void *data, u64 val)
+@@ -614,16 +633,30 @@ mt7915_fw_debug_bin_set(void *data, u64 val)
  	};
  	struct mt7915_dev *dev = data;
  
@@ -152,7 +153,7 @@
  	return mt7915_fw_debug_wm_set(dev, dev->fw.debug_wm);
  }
  
-@@ -1257,6 +1290,11 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
+@@ -1249,6 +1282,11 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
  	if (!ext_phy)
  		dev->debugfs_dir = dir;
  
@@ -164,7 +165,7 @@
  	return 0;
  }
  
-@@ -1269,6 +1307,12 @@ mt7915_debugfs_write_fwlog(struct mt7915_dev *dev, const void *hdr, int hdrlen,
+@@ -1261,6 +1299,12 @@ mt7915_debugfs_write_fwlog(struct mt7915_dev *dev, const void *hdr, int hdrlen,
  	void *dest;
  
  	spin_lock_irqsave(&lock, flags);
@@ -177,7 +178,7 @@
  	dest = relay_reserve(dev->relay_fwlog, hdrlen + len + 4);
  	if (dest) {
  		*(u32 *)dest = hdrlen + len;
-@@ -1297,17 +1341,50 @@ void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int
+@@ -1289,17 +1333,50 @@ void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int
  		.msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR),
  	};
  
@@ -231,7 +232,7 @@
  
  	if (dev->relay_fwlog)
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 2a87b506..a62a9bca 100644
+index 67e7b26..99cbabd 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -275,6 +275,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
@@ -245,7 +246,7 @@
  	memset(status, 0, sizeof(*status));
  
  	if ((rxd1 & MT_RXD1_NORMAL_BAND_IDX) && !phy->mt76->band_idx) {
-@@ -458,6 +462,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -459,6 +463,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
  	}
  
  	hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
@@ -256,7 +257,7 @@
  	if (hdr_trans && ieee80211_has_morefrags(fc)) {
  		struct ieee80211_vif *vif;
  		int err;
-@@ -795,6 +803,12 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -796,6 +804,12 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  	tx_info->buf[1].skip_unmap = true;
  	tx_info->nbuf = MT_CT_DMA_BUF_NUM;
  
@@ -270,7 +271,7 @@
  }
  
 diff --git a/mt7915/main.c b/mt7915/main.c
-index f78f2bf0..699f767f 100644
+index 251df80..cc4ac94 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -73,7 +73,11 @@ int mt7915_run(struct ieee80211_hw *hw)
@@ -286,10 +287,10 @@
  		goto out;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index dbdc48a0..5acba67d 100644
+index 6cf2a3f..fbbd848 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -203,6 +203,11 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
+@@ -205,6 +205,11 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
  	else
  		qid = MT_MCUQ_WM;
  
@@ -301,7 +302,7 @@
  	return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
  }
  
-@@ -2246,7 +2251,10 @@ static int mt7915_red_set_watermark(struct mt7915_dev *dev)
+@@ -2285,7 +2290,10 @@ static int mt7915_red_set_watermark(struct mt7915_dev *dev)
  				 sizeof(req), false);
  }
  
@@ -313,7 +314,7 @@
  {
  #define RED_DISABLE		0
  #define RED_BY_WA_ENABLE	2
-@@ -3310,6 +3318,8 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
+@@ -3349,6 +3357,8 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
  		.sku_enable = enable,
  	};
  
@@ -322,8 +323,8 @@
  	return mt76_mcu_send_msg(&dev->mt76,
  				 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
  				 sizeof(req), true);
-@@ -3908,6 +3918,23 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
- 				 &req, sizeof(req), true);
+@@ -4003,6 +4013,23 @@ out:
+ 	return ret;
  }
  
 +#ifdef MTK_DEBUG
@@ -346,7 +347,7 @@
  int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
  {
  	struct {
-@@ -3936,3 +3963,22 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
+@@ -4031,3 +4058,22 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
  
  	return 0;
  }
@@ -370,7 +371,7 @@
 +}
 +#endif
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index aebacc7d..daea67f0 100644
+index aebacc7..daea67f 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -333,6 +333,10 @@ enum {
@@ -385,7 +386,7 @@
  };
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 4fb0a375..88e3bb3d 100644
+index 4de3e05..b5e7c86 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -9,6 +9,7 @@
@@ -396,7 +397,7 @@
  #define MT7915_MAX_INTERFACES		19
  #define MT7915_WTBL_SIZE		288
  #define MT7916_WTBL_SIZE		544
-@@ -370,6 +371,28 @@ struct mt7915_dev {
+@@ -305,6 +306,28 @@ struct mt7915_dev {
  	struct reset_control *rstc;
  	void __iomem *dcm;
  	void __iomem *sku;
@@ -425,7 +426,7 @@
  };
  
  enum {
-@@ -650,4 +673,24 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -585,4 +608,24 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
@@ -452,7 +453,7 @@
  #endif
 diff --git a/mt7915/mt7915_debug.h b/mt7915/mt7915_debug.h
 new file mode 100644
-index 00000000..fa8794fd
+index 0000000..fa8794f
 --- /dev/null
 +++ b/mt7915/mt7915_debug.h
 @@ -0,0 +1,1418 @@
@@ -1876,7 +1877,7 @@
 +#endif
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
 new file mode 100644
-index 00000000..b1f8631c
+index 0000000..70e4cb2
 --- /dev/null
 +++ b/mt7915/mtk_debugfs.c
 @@ -0,0 +1,3624 @@
@@ -4933,7 +4934,7 @@
 +	struct cos_msg_trace_t *msg_trace = NULL;
 +	u32 ptr_addr = 0;
 +	u32 length = 0;
-+	u32 idx = 0, i = 0;
++	u32 idx = 0;
 +	u32 cnt = 0;
 +	u32 msg_history_num = 0;
 +
@@ -5074,14 +5075,14 @@
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	struct cos_program_trace_t *cos_program_trace_ptr = NULL;
 +	u32 trace_ptr = 0;
-+	u32 idx = 0, i = 0;
++	u32 idx = 0;
 +	u32 old_idx = 0;
 +	u32 old_idx_addr = 0;
 +	u32 prev_idx = 0;
 +	u32 prev_time = 0;
 +	u32 curr_time = 0;
 +	u32 diff = 0;
-+	u32 length = 0;
++	//u32 length = 0, i = 0;
 +
 +	cos_program_trace_ptr = kmalloc(PROGRAM_TRACE_HISTORY_NUM * sizeof(struct cos_program_trace_t), GFP_KERNEL);
 +	if (!cos_program_trace_ptr) {
@@ -5149,7 +5150,7 @@
 +{
 +	struct mt7915_dev *dev = dev_get_drvdata(s->private);
 +	u32 macVal = 0, g_exp_type = 0, COS_Interrupt_Count = 0;
-+	u8 exp_assert_proc_entry_cnt = 0, exp_assert_state = 0, g_irq_history_num = 0;;
++	u8 exp_assert_proc_entry_cnt = 0, exp_assert_state = 0, g_irq_history_num = 0;
 +	u16 processing_irqx = 0;
 +	u32 processing_lisr = 0, Current_Task_Id = 0, Current_Task_Indx = 0;
 +	u8 km_irq_info_idx = 0, km_eint_info_idx = 0, km_sched_info_idx = 0, g_sched_history_num = 0;
@@ -5163,7 +5164,7 @@
 +	u32 g_sched_history_num_addr = 0, km_sched_trace_ptr_addr = 0;
 +	u32 km_irq_trace_ptr_addr = 0, km_total_time_addr  = 0, last_dequeued_msg_id = 0;
 +	u32 i = 0 ,t1 = 0, t2 = 0, t3 = 0;
-+	u8 idx = 0, str[32], exp_type[64];;
++	u8 idx = 0, str[32], exp_type[64];
 +	int ret;
 +
 +	g_exp_type_addr = 0x022050DC;
@@ -5506,7 +5507,7 @@
 +#endif
 diff --git a/mt7915/mtk_mcu.c b/mt7915/mtk_mcu.c
 new file mode 100644
-index 00000000..143dae26
+index 0000000..143dae2
 --- /dev/null
 +++ b/mt7915/mtk_mcu.c
 @@ -0,0 +1,51 @@
@@ -5562,7 +5563,7 @@
 +				 sizeof(req), true);
 +}
 diff --git a/tools/fwlog.c b/tools/fwlog.c
-index e5d4a105..3d51d9ec 100644
+index e5d4a10..3d51d9e 100644
 --- a/tools/fwlog.c
 +++ b/tools/fwlog.c
 @@ -26,7 +26,7 @@ static const char *debugfs_path(const char *phyname, const char *file)
diff --git a/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch b/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-csi-implement-csi-support.patch
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-csi-implement-csi-support.patch
index 67a82bb..4bb39a5 100644
--- a/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1000-wifi-mt76-mt7915-csi-implement-csi-support.patch
@@ -1,7 +1,7 @@
-From 97b4997c04cfdae312ae7a67249422f88be91c40 Mon Sep 17 00:00:00 2001
+From dc8113e03f94a498a28d5394e71e53f479ca5bc3 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Jun 2022 20:13:02 +0800
-Subject: [PATCH 1001/1033] wifi: mt76: mt7915: csi: implement csi support
+Subject: [PATCH 1000/1031] wifi: mt76: mt7915: csi: implement csi support
 
 ---
  mt76_connac_mcu.h |   2 +
@@ -17,18 +17,18 @@
  create mode 100644 mt7915/vendor.h
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8d6c422..4f7db5c 100644
+index ab3b58e..f6738bc 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1000,6 +1000,7 @@ enum {
- 	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
+@@ -1003,6 +1003,7 @@ enum {
+ 	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
  	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
  	MCU_EXT_EVENT_MURU_CTRL = 0x9f,
 +	MCU_EXT_EVENT_CSI_REPORT = 0xc2,
  };
  
  /* unified event table */
-@@ -1193,6 +1194,7 @@ enum {
+@@ -1196,6 +1197,7 @@ enum {
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
  	MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
@@ -54,10 +54,10 @@
  mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
  mt7915e-$(CONFIG_MT798X_WMAC) += soc.o
 diff --git a/mt7915/init.c b/mt7915/init.c
-index abca909..1fe123d 100644
+index 75f8d96..d42d17b 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -670,6 +670,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
+@@ -686,6 +686,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy)
  	/* init wiphy according to mphy and phy */
  	mt7915_init_wiphy(phy);
  
@@ -70,7 +70,7 @@
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1150,6 +1156,25 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
+@@ -1166,6 +1172,25 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
  	}
  }
  
@@ -96,7 +96,7 @@
  static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  {
  	struct mt7915_phy *phy = mt7915_ext_phy(dev);
-@@ -1158,6 +1183,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
+@@ -1174,6 +1199,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
  	if (!phy)
  		return;
  
@@ -107,7 +107,7 @@
  	mt7915_unregister_thermal(phy);
  	mt76_unregister_phy(mphy);
  	ieee80211_free_hw(mphy->hw);
-@@ -1170,6 +1199,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
+@@ -1186,6 +1215,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev)
  	mt7915_dma_cleanup(dev);
  	tasklet_disable(&dev->mt76.irq_tasklet);
  
@@ -118,7 +118,7 @@
  	if (is_mt798x(&dev->mt76))
  		mt7986_wmac_disable(dev);
  }
-@@ -1212,6 +1245,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
+@@ -1226,6 +1259,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
  	dev->mt76.test_ops = &mt7915_testmode_ops;
  #endif
  
@@ -132,7 +132,7 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 5acba67..b3fdcdf 100644
+index fbbd848..4ef5190 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -40,6 +40,10 @@ static bool sr_scene_detect = true;
@@ -146,7 +146,7 @@
  static u8
  mt7915_mcu_get_sta_nss(u16 mcs_map)
  {
-@@ -375,6 +379,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -377,6 +381,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_FW_LOG_2_HOST:
  		mt7915_mcu_rx_log_message(dev, skb);
  		break;
@@ -158,8 +158,8 @@
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
-@@ -3918,6 +3927,108 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
- 				 &req, sizeof(req), true);
+@@ -4013,6 +4022,108 @@ out:
+ 	return ret;
  }
  
 +#ifdef CONFIG_MTK_VENDOR
@@ -354,10 +354,10 @@
 +
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 29394b6..43705fb 100644
+index b5e7c86..c2ac60c 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -292,6 +292,20 @@ struct mt7915_phy {
+@@ -229,6 +229,20 @@ struct mt7915_phy {
  		u8 spe_idx;
  	} test;
  #endif
@@ -378,7 +378,7 @@
  };
  
  struct mt7915_dev {
-@@ -673,6 +687,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -608,6 +622,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch b/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-air-monitor-support.patch
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-air-monitor-support.patch
index fc76eb5..ee5db05 100644
--- a/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1001-wifi-mt76-mt7915-air-monitor-support.patch
@@ -1,7 +1,7 @@
-From 85e642f5fbd701ab10c29b24113ca354dd0e9345 Mon Sep 17 00:00:00 2001
+From 0f97cca7ee69e2c599504be05757e6897cd49982 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Tue, 11 Jan 2022 12:03:23 +0800
-Subject: [PATCH 1002/1033] wifi: mt76: mt7915: air monitor support
+Subject: [PATCH 1001/1031] wifi: mt76: mt7915: air monitor support
 
 ---
  mt76_connac_mcu.h |   2 +
@@ -13,10 +13,10 @@
  6 files changed, 442 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 4f7db5c..6174505 100644
+index f6738bc..c24fa8e 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1194,6 +1194,8 @@ enum {
+@@ -1197,6 +1197,8 @@ enum {
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
  	MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
@@ -26,10 +26,10 @@
  };
  
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index b5805bb..ff4e1dd 100644
+index 99cbabd..462fe6c 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -523,6 +523,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -524,6 +524,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,
  			seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
  			qos_ctl = *ieee80211_get_qos_ctl(hdr);
  		}
@@ -41,10 +41,10 @@
  		status->flag |= RX_FLAG_8023;
  		mt7915_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 699f767..4438e7b 100644
+index cc4ac94..fcddb36 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -703,6 +703,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -729,6 +729,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (ret)
  		return ret;
  
@@ -55,10 +55,10 @@
  }
  
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 43705fb..51d7f34 100644
+index c2ac60c..7a9752f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -244,6 +244,35 @@ struct mt7915_hif {
+@@ -181,6 +181,35 @@ struct mt7915_hif {
  	int irq;
  };
  
@@ -94,7 +94,7 @@
  struct mt7915_phy {
  	struct mt76_phy *mt76;
  	struct mt7915_dev *dev;
-@@ -305,6 +334,8 @@ struct mt7915_phy {
+@@ -242,6 +271,8 @@ struct mt7915_phy {
  		u32 interval;
  		u32 last_record;
  	} csi;
@@ -103,7 +103,7 @@
  #endif
  };
  
-@@ -691,6 +722,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -626,6 +657,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  void mt7915_vendor_register(struct mt7915_phy *phy);
  int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
  			u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
diff --git a/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch b/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
rename to recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
index eea919e..7787604 100644
--- a/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1002-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch
@@ -1,7 +1,7 @@
-From e308945d818a93dd553f5f311865b1eff33954f2 Mon Sep 17 00:00:00 2001
+From c79fc4ca594e0c4506d8601243523476b47a13eb Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Tue, 4 Apr 2023 02:23:57 +0800
-Subject: [PATCH 1003/1033] wifi: mt76: mt7915: add support for muru_onoff via
+Subject: [PATCH 1002/1031] wifi: mt76: mt7915: add support for muru_onoff via
 
 ---
  mt7915/init.c        |  2 ++
@@ -12,10 +12,10 @@
  5 files changed, 51 insertions(+), 2 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 1fe123d..7250998 100644
+index d42d17b..41f137c 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -449,6 +449,8 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+@@ -457,6 +457,8 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
  		mphy->leds.cdev.brightness_set = mt7915_led_set_brightness;
  		mphy->leds.cdev.blink_set = mt7915_led_set_blink;
  	}
@@ -25,10 +25,10 @@
  
  static void
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index b3fdcdf..68e3583 100644
+index 4ef5190..a4a8194 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -866,6 +866,7 @@ static void
+@@ -870,6 +870,7 @@ static void
  mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  			struct ieee80211_sta *sta, struct ieee80211_vif *vif)
  {
@@ -36,7 +36,7 @@
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
-@@ -878,13 +879,18 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -882,13 +883,18 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  
  	muru = (struct sta_rec_muru *)tlv;
  
@@ -73,20 +73,20 @@
 +
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 51d7f34..7613e60 100644
+index 7a9752f..2befa44 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -301,6 +301,8 @@ struct mt7915_phy {
+@@ -238,6 +238,8 @@ struct mt7915_phy {
  	u32 rx_ampdu_ts;
  	u32 ampdu_ref;
  
 +	u8 muru_onoff;
 +
- 	struct mib_stats mib;
+ 	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 4bbb410..1db1d87 100644
+index 70e4cb2..e5fb2ce 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -2558,6 +2558,38 @@ static int mt7915_token_txd_read(struct seq_file *s, void *data)
@@ -128,7 +128,7 @@
  static int mt7915_amsduinfo_read(struct seq_file *s, void *data)
  {
  	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-@@ -3538,6 +3570,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+@@ -3554,6 +3586,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  
  	mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch b/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-certification-patches.patch
similarity index 97%
rename from recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch
rename to recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-certification-patches.patch
index 1849dcc..ca89de1 100644
--- a/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-certification-patches.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1003-wifi-mt76-mt7915-certification-patches.patch
@@ -1,7 +1,7 @@
-From 87ac75bc1a347093b56c35111cf0bfd210314785 Mon Sep 17 00:00:00 2001
+From 63fe4d2540b6acd65461bcaea5cb5492b881b55f Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Mon, 6 Jun 2022 20:15:51 +0800
-Subject: [PATCH 1004/1033] wifi: mt76: mt7915: certification patches
+Subject: [PATCH 1003/1031] wifi: mt76: mt7915: certification patches
 
 ---
  mt76_connac_mcu.h    |   1 +
@@ -16,10 +16,10 @@
  9 files changed, 954 insertions(+), 5 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6174505..978a4d0 100644
+index c24fa8e..7b96feb 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1196,6 +1196,7 @@ enum {
+@@ -1199,6 +1199,7 @@ enum {
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
@@ -28,7 +28,7 @@
  };
  
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index ff4e1dd..5c7a47c 100644
+index 462fe6c..3773cdc 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
 @@ -8,6 +8,7 @@
@@ -39,7 +39,7 @@
  
  #define to_rssi(field, rcpi)	((FIELD_GET(field, rcpi) - 220) / 2)
  
-@@ -2045,6 +2046,21 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
+@@ -2000,6 +2001,21 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
  	spin_unlock_bh(&phy->stats_lock);
  }
  
@@ -50,25 +50,25 @@
 +	struct mt7915_dev *dev = msta->vif->phy->dev;
 +	u32 *changed = data;
 +
-+	spin_lock_bh(&dev->sta_poll_lock);
++	spin_lock_bh(&dev->mt76.sta_poll_lock);
 +	msta->changed |= *changed;
 +	if (list_empty(&msta->rc_list))
 +		list_add_tail(&msta->rc_list, &dev->sta_rc_list);
-+	spin_unlock_bh(&dev->sta_poll_lock);
++	spin_unlock_bh(&dev->mt76.sta_poll_lock);
 +}
 +#endif
 +
  void mt7915_mac_sta_rc_work(struct work_struct *work)
  {
  	struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
-@@ -2067,6 +2083,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
+@@ -2022,6 +2038,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
  		sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
  		vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
  
 +#ifdef CONFIG_MTK_VENDOR
 +		if (changed & CAPI_RFEATURE_CHANGED) {
 +			mt7915_mcu_set_rfeature_starec(&changed, dev, vif, sta);
-+			spin_lock_bh(&dev->sta_poll_lock);
++			spin_lock_bh(&dev->mt76.sta_poll_lock);
 +			continue;
 +		}
 +#endif
@@ -76,10 +76,10 @@
  			       IEEE80211_RC_NSS_CHANGED |
  			       IEEE80211_RC_BW_CHANGED))
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 4438e7b..e7523c1 100644
+index fcddb36..5e7dcae 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -678,6 +678,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -704,6 +704,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
  	bool ext_phy = mvif->phy != &dev->phy;
@@ -89,7 +89,7 @@
  	int ret, idx;
  
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
-@@ -706,7 +709,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -732,7 +735,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  #ifdef CONFIG_MTK_VENDOR
  	mt7915_vendor_amnt_sta_remove(mvif->phy, sta);
  #endif
@@ -107,10 +107,10 @@
  
  void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 68e3583..8ee1d48 100644
+index a4a8194..3c3ea73 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4033,6 +4033,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -4128,6 +4128,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb)
  
  	return 0;
  }
@@ -818,10 +818,10 @@
  
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 7613e60..60364f0 100644
+index 2befa44..3cff377 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -721,6 +721,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -656,6 +656,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
  #ifdef CONFIG_MTK_VENDOR
@@ -842,7 +842,7 @@
  int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode,
  			u8 cfg, u8 v1, u32 v2, u8 *mac_addr);
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 1db1d87..fc148d4 100644
+index e5fb2ce..0149706 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -2564,7 +2564,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val)
diff --git a/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch b/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
similarity index 78%
rename from recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
rename to recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
index 151e20d..b36974e 100644
--- a/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1004-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch
@@ -1,7 +1,7 @@
-From aad666a7107ef807bf965d02ea2699447d7a738c Mon Sep 17 00:00:00 2001
+From 014d2a853950d9ca5ea5b450abf082f36ca6ed7b Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 23 Mar 2023 09:55:50 +0800
-Subject: [PATCH 1005/1033] wifi: mt76: mt7915: add support for runtime set
+Subject: [PATCH 1004/1031] wifi: mt76: mt7915: add support for runtime set
  in-band discovery
 
 Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+), 3 deletions(-)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 8ee1d48..922ae18 100644
+index 3c3ea73..c21f30e 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -1930,8 +1930,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1934,8 +1934,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	bcn = (struct bss_info_bcn *)tlv;
  	bcn->enable = true;
  
@@ -23,7 +23,7 @@
  		interval = vif->bss_conf.fils_discovery.max_interval;
  		skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
  	} else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
-@@ -1965,7 +1964,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1969,7 +1968,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
  	discov->tx_interval = interval;
  	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
diff --git a/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch b/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
rename to recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
index a621d88..3644ebe 100644
--- a/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch
@@ -1,7 +1,7 @@
-From fb010c2d8e8e547bc52e8485840c4821f9e49d4c Mon Sep 17 00:00:00 2001
+From 9aa0bf50b22e4c6951cf3859c344a1e2caedb08d Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Tue, 4 Apr 2023 02:27:44 +0800
-Subject: [PATCH 1006/1033] wifi: mt76: mt7915: add mt76 vendor muru onoff
+Subject: [PATCH 1005/1031] wifi: mt76: mt7915: add mt76 vendor muru onoff
  command
 
 ---
@@ -12,10 +12,10 @@
  4 files changed, 63 insertions(+)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 922ae18..5a68bb7 100644
+index c21f30e..8c4ed60 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4052,6 +4052,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+@@ -4147,6 +4147,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
  		if (val == 0)
  			phy->muru_onoff = MUMIMO_DL_CERT | MUMIMO_DL;
  		break;
diff --git a/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch b/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch
similarity index 77%
rename from recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch
rename to recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch
index 1d7ea79..465c631 100644
--- a/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch
@@ -1,17 +1,17 @@
-From 24c4b9c1156af2f9edb0d880a506ce1e3e2d599d Mon Sep 17 00:00:00 2001
+From 3496d9a51ede8540e8378dc783535229aeebbc7e Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Thu, 14 Apr 2022 15:18:02 +0800
-Subject: [PATCH 1007/1033] wifi: mt76: mt7915: drop undefined action frame
+Subject: [PATCH 1006/1031] wifi: mt76: mt7915: drop undefined action frame
 
 ---
  mt7915/mac.c | 6 ++++++
  1 file changed, 6 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 5c7a47c..25acb97 100644
+index 3773cdc..f26f949 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -736,6 +736,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -737,6 +737,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  			  struct mt76_tx_info *tx_info)
  {
  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
@@ -20,7 +20,7 @@
  	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
  	struct ieee80211_key_conf *key = info->control.hw_key;
-@@ -766,6 +768,10 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -767,6 +769,10 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
  	t->skb = tx_info->skb;
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-rework-testmode-init-registers.patch b/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch
similarity index 95%
rename from recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-rework-testmode-init-registers.patch
rename to recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch
index e9a09e4..744fa72 100644
--- a/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-rework-testmode-init-registers.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch
@@ -1,7 +1,7 @@
-From 4a809f8898c4009e88370959802bfd38e2eb94f3 Mon Sep 17 00:00:00 2001
+From 6e755239f1f0ed9bd8357cf0a0160d253ca70abd Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 6 Jun 2022 19:46:26 +0800
-Subject: [PATCH 1009/1033] wifi: mt76: testmode: rework testmode init
+Subject: [PATCH 1007/1031] wifi: mt76: testmode: rework testmode init
  registers
 
 ---
@@ -18,10 +18,10 @@
  10 files changed, 164 insertions(+), 35 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 991d91b..115bb05 100644
+index 76cb08b..4e75e7f 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -784,7 +784,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
+@@ -787,7 +787,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
  	}
  
  #ifdef CONFIG_NL80211_TESTMODE
@@ -32,10 +32,10 @@
  		if (status->flag & RX_FLAG_FAILED_FCS_CRC)
  			phy->test.rx_stats.fcs_error[q]++;
 diff --git a/mt76.h b/mt76.h
-index 3425159..492fe42 100644
+index 35bf19f..c2ad06a 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -648,6 +648,8 @@ struct mt76_testmode_ops {
+@@ -659,6 +659,8 @@ struct mt76_testmode_ops {
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
  };
  
@@ -44,7 +44,7 @@
  struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
-@@ -679,6 +681,8 @@ struct mt76_testmode_data {
+@@ -690,6 +692,8 @@ struct mt76_testmode_data {
  
  	u8 addr[3][ETH_ALEN];
  
@@ -53,7 +53,7 @@
  	u32 tx_pending;
  	u32 tx_queued;
  	u16 tx_queued_limit;
-@@ -686,6 +690,7 @@ struct mt76_testmode_data {
+@@ -697,6 +701,7 @@ struct mt76_testmode_data {
  	struct {
  		u64 packets[__MT_RXQ_MAX];
  		u64 fcs_error[__MT_RXQ_MAX];
@@ -62,10 +62,10 @@
  };
  
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 978a4d0..d6165a3 100644
+index 7b96feb..92e0b91 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1190,6 +1190,7 @@ enum {
+@@ -1193,6 +1193,7 @@ enum {
  	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
  	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
  	MCU_EXT_CMD_MURU_CTRL = 0x9f,
@@ -86,7 +86,7 @@
  	MCU_ATE_CLEAN_TXQUEUE = 0x1c,
  };
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 1bb8a4c..b97aca7 100644
+index 8d92e76..b23679a 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -120,6 +120,7 @@ static const u32 mt7986_reg[] = {
@@ -106,7 +106,7 @@
  	[TMAC_ODTR]		= 0x0cc,
  	[TMAC_ATCR]		= 0x00c,
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 374677f..e7bc181 100644
+index d01b9ea..038596c 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
 @@ -48,6 +48,7 @@ enum reg_rev {
@@ -117,7 +117,7 @@
  	TMAC_CDTR,
  	TMAC_ODTR,
  	TMAC_ATCR,
-@@ -198,6 +199,12 @@ enum offs_rev {
+@@ -201,6 +202,12 @@ enum offs_rev {
  #define MT_TRB_RXPSR0_RX_WTBL_PTR	GENMASK(25, 16)
  #define MT_TRB_RXPSR0_RX_RMAC_PTR	GENMASK(9, 0)
  
@@ -130,7 +130,7 @@
  /* TMAC: band 0(0x820e4000), band 1(0x820f4000) */
  #define MT_WF_TMAC_BASE(_band)		((_band) ? 0x820f4000 : 0x820e4000)
  #define MT_WF_TMAC(_band, ofs)		(MT_WF_TMAC_BASE(_band) + (ofs))
-@@ -206,6 +213,9 @@ enum offs_rev {
+@@ -209,6 +216,9 @@ enum offs_rev {
  #define MT_TMAC_TCR0_TX_BLINK		GENMASK(7, 6)
  #define MT_TMAC_TCR0_TBTT_STOP_CTRL	BIT(25)
  
@@ -140,7 +140,7 @@
  #define MT_TMAC_CDTR(_band)		MT_WF_TMAC(_band, __OFFS(TMAC_CDTR))
   #define MT_TMAC_ODTR(_band)		MT_WF_TMAC(_band, __OFFS(TMAC_ODTR))
  #define MT_TIMEOUT_VAL_PLCP		GENMASK(15, 0)
-@@ -485,8 +495,10 @@ enum offs_rev {
+@@ -488,8 +498,10 @@ enum offs_rev {
  #define MT_AGG_PCR0_VHT_PROT		BIT(13)
  #define MT_AGG_PCR0_PTA_WIN_DIS		BIT(15)
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch b/recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-additional-supports.patch
similarity index 97%
rename from recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch
rename to recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-additional-supports.patch
index 7902ebc..11eb9ae 100644
--- a/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1008-wifi-mt76-testmode-additional-supports.patch
@@ -1,7 +1,7 @@
-From c311d022536c9c6be72f8e4a134f9dbaed13cd6d Mon Sep 17 00:00:00 2001
+From 0f770281dfd6cb89550134c85e5ac36e41e5517c Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 21 Apr 2022 15:43:19 +0800
-Subject: [PATCH 1010/1014] wifi: mt76: testmode: additional supports
+Subject: [PATCH 1008/1031] wifi: mt76: testmode: additional supports
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -43,7 +43,7 @@
  #endif
  
 diff --git a/mac80211.c b/mac80211.c
-index 115bb05..75e2ffe 100644
+index 4e75e7f..966d8d0 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -55,6 +55,13 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
@@ -60,10 +60,10 @@
  	CHAN5G(100, 5500),
  	CHAN5G(104, 5520),
  	CHAN5G(108, 5540),
-@@ -75,6 +82,11 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
- 	CHAN5G(165, 5825),
+@@ -76,6 +83,11 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
  	CHAN5G(169, 5845),
  	CHAN5G(173, 5865),
+ 	CHAN5G(177, 5885),
 +
 +	CHAN5G(184, 4920),
 +	CHAN5G(188, 4940),
@@ -73,10 +73,10 @@
  
  static const struct ieee80211_channel mt76_channels_6ghz[] = {
 diff --git a/mt76.h b/mt76.h
-index 492fe42..3191626 100644
+index c2ad06a..a5908de 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -646,6 +646,21 @@ struct mt76_testmode_ops {
+@@ -657,6 +657,21 @@ struct mt76_testmode_ops {
  	int (*set_params)(struct mt76_phy *phy, struct nlattr **tb,
  			  enum mt76_testmode_state new_state);
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
@@ -98,7 +98,7 @@
  };
  
  #define MT_TM_FW_RX_COUNT	BIT(0)
-@@ -654,16 +669,11 @@ struct mt76_testmode_data {
+@@ -665,16 +680,11 @@ struct mt76_testmode_data {
  	enum mt76_testmode_state state;
  
  	u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)];
@@ -115,7 +115,7 @@
  	u8 tx_rate_stbc;
  	u8 tx_ltf;
  
-@@ -679,10 +689,37 @@ struct mt76_testmode_data {
+@@ -690,10 +700,37 @@ struct mt76_testmode_data {
  	u8 tx_power[4];
  	u8 tx_power_control;
  
@@ -154,7 +154,7 @@
  	u32 tx_pending;
  	u32 tx_queued;
  	u16 tx_queued_limit;
-@@ -1147,6 +1184,59 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
+@@ -1258,6 +1295,59 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
  #endif
  }
  
@@ -214,7 +214,7 @@
  static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
  					struct sk_buff *skb,
  					struct ieee80211_hw **hw)
-@@ -1157,7 +1247,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
+@@ -1268,7 +1358,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
  	for (i = 0; i < ARRAY_SIZE(dev->phys); i++) {
  		struct mt76_phy *phy = dev->phys[i];
  
@@ -224,7 +224,7 @@
  			*hw = dev->phys[i]->hw;
  			return true;
  		}
-@@ -1259,7 +1350,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -1370,7 +1461,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
  		       struct netlink_callback *cb, void *data, int len);
  int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
@@ -235,7 +235,7 @@
  static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable)
  {
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 1cdef36..15ed126 100644
+index a558c68..74b63f0 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -395,6 +395,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
@@ -257,18 +257,18 @@
  		return;
  
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index d6165a3..79416e6 100644
+index 92e0b91..e3980c3 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -996,6 +996,7 @@ enum {
+@@ -998,6 +998,7 @@ enum {
  	MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
  	MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
  	MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
 +	MCU_EXT_EVENT_BF_STATUS_READ = 0x35,
  	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
  	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
- 	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
-@@ -1197,6 +1198,7 @@ enum {
+ 	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
+@@ -1200,6 +1201,7 @@ enum {
  	MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
@@ -290,10 +290,10 @@
  				return ret;
  		}
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 7250998..8eacf34 100644
+index 41f137c..09ee080 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -701,7 +701,7 @@ static void mt7915_init_work(struct work_struct *work)
+@@ -717,7 +717,7 @@ static void mt7915_init_work(struct work_struct *work)
  	struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
  				 init_work);
  
@@ -303,10 +303,10 @@
  	mt7915_init_txpower(dev, &dev->mphy.sband_2g.sband);
  	mt7915_init_txpower(dev, &dev->mphy.sband_5g.sband);
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 25acb97..ee33850 100644
+index f26f949..98c433f 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -603,16 +603,38 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -604,16 +604,38 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  {
  #ifdef CONFIG_NL80211_TESTMODE
  	struct mt76_testmode_data *td = &phy->mt76->test;
@@ -348,7 +348,7 @@
  
  	switch (td->tx_rate_mode) {
  	case MT76_TM_TX_MODE_HT:
-@@ -643,7 +665,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -644,7 +666,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  			rate_idx += 4;
  
  		r = &phy->mt76->hw->wiphy->bands[band]->bitrates[rate_idx];
@@ -357,7 +357,7 @@
  
  		mode = val >> 8;
  		rate_idx = val & 0xff;
-@@ -702,13 +724,14 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -703,13 +725,14 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  	if (mode >= MT_PHY_TYPE_HE_SU)
  		val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf);
  
@@ -375,7 +375,7 @@
  #endif
  }
  
-@@ -1469,7 +1492,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
+@@ -1415,7 +1438,7 @@ mt7915_mac_restart(struct mt7915_dev *dev)
  		goto out;
  
  	/* set the necessary init items */
@@ -385,7 +385,7 @@
  		goto out;
  
 diff --git a/mt7915/main.c b/mt7915/main.c
-index e7523c1..798eaa8 100644
+index 5e7dcae..2e3d2f6 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -238,7 +238,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
@@ -398,10 +398,10 @@
  		mvif->mt76.wmm_idx += 2;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 5a68bb7..5cea513 100644
+index 8c4ed60..2f716f3 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -387,6 +387,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -389,6 +389,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
@@ -413,15 +413,15 @@
  	default:
  		break;
  	}
-@@ -418,6 +423,7 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
- 	    rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
-+	    rxd->ext_eid == MCU_EXT_EVENT_BF_STATUS_READ ||
- 	    !rxd->seq)
- 		mt7915_mcu_rx_unsolicited_event(dev, skb);
- 	else
-@@ -2713,7 +2719,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
+@@ -420,6 +425,7 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
+ 	     rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
+ 	     rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
+ 	     rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
++	     rxd->ext_eid == MCU_EXT_EVENT_BF_STATUS_READ ||
+ 	     !rxd->seq) &&
+ 	     !(rxd->eid == MCU_CMD_EXT_CID &&
+ 	       rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
+@@ -2752,7 +2758,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
  	}
  #endif
  
@@ -431,7 +431,7 @@
  		req.tx_path_num = fls(phy->mt76->antenna_mask);
  
  	if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
-@@ -2781,21 +2788,21 @@ static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev)
+@@ -2820,21 +2827,21 @@ static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev)
  	return 0;
  }
  
@@ -456,7 +456,7 @@
  {
  	struct mt7915_mcu_eeprom_info req = {
  		.addr = cpu_to_le32(round_down(offset,
-@@ -2804,7 +2811,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
+@@ -2843,7 +2850,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
  	struct mt7915_mcu_eeprom_info *res;
  	struct sk_buff *skb;
  	int ret;
@@ -465,7 +465,7 @@
  
  	ret = mt76_mcu_send_and_get_msg(&dev->mt76,
  					MCU_EXT_QUERY(EFUSE_ACCESS),
-@@ -2813,8 +2820,11 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
+@@ -2852,8 +2859,11 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
  		return ret;
  
  	res = (struct mt7915_mcu_eeprom_info *)skb->data;
@@ -537,7 +537,7 @@
  
  enum {
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index b97aca7..fd5722b 100644
+index b23679a..6505d76 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -134,6 +134,7 @@ static const u32 mt7915_offs[] = {
@@ -557,10 +557,10 @@
  	[AGG_PCR0]		= 0x040,
  	[AGG_ACR0]		= 0x054,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 60364f0..83743cd 100644
+index 3cff377..84f75e7 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -321,6 +321,9 @@ struct mt7915_phy {
+@@ -258,6 +258,9 @@ struct mt7915_phy {
  		u8 last_snr;
  
  		u8 spe_idx;
@@ -570,7 +570,7 @@
  	} test;
  #endif
  
-@@ -419,6 +422,14 @@ struct mt7915_dev {
+@@ -354,6 +357,14 @@ struct mt7915_dev {
  	void __iomem *dcm;
  	void __iomem *sku;
  
@@ -585,7 +585,7 @@
  #ifdef MTK_DEBUG
  	u16 wlan_idx;
  	struct {
-@@ -591,8 +602,8 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
+@@ -526,8 +537,8 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
  				   struct ieee80211_vif *vif,
  				   struct ieee80211_sta *sta,
  				   void *data, u32 field);
@@ -596,7 +596,7 @@
  int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num);
  int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
  		       bool hdr_trans);
-@@ -630,6 +641,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+@@ -566,6 +577,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
  int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
  void mt7915_mcu_exit(struct mt7915_dev *dev);
@@ -605,7 +605,7 @@
  static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
  {
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index e7bc181..b6f36f5 100644
+index 038596c..428f482 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
 @@ -62,6 +62,7 @@ enum offs_rev {
@@ -616,7 +616,7 @@
  	AGG_AWSCR0,
  	AGG_PCR0,
  	AGG_ACR0,
-@@ -482,6 +483,8 @@ enum offs_rev {
+@@ -485,6 +486,8 @@ enum offs_rev {
  #define MT_WF_AGG_BASE(_band)		((_band) ? 0x820f2000 : 0x820e2000)
  #define MT_WF_AGG(_band, ofs)		(MT_WF_AGG_BASE(_band) + (ofs))
  
@@ -626,7 +626,7 @@
  							  (_n) * 4))
  #define MT_AGG_PCR0(_band, _n)		MT_WF_AGG(_band, (__OFFS(AGG_PCR0) +	\
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 4693919..62ef4db 100644
+index 4693919..1e72bf2 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -9,6 +9,9 @@
@@ -887,7 +887,7 @@
 +
 +	/* prevent from starting tx ba session */
 +	for (tid = 0; tid < 8; tid++)
-+		set_bit(tid, &msta->ampdu_state);
++		set_bit(tid, &msta->wcid.ampdu_state);
 +
 +	list_add_tail(&msta->wcid.list, &td->tm_entry_list);
 +	td->entry_num++;
@@ -3083,10 +3083,10 @@
  };
  
 diff --git a/tx.c b/tx.c
-index 72b3ec7..94f0d82 100644
+index 6cc26cc..5d7bf34 100644
 --- a/tx.c
 +++ b/tx.c
-@@ -252,8 +252,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
+@@ -259,8 +259,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
  	if (mt76_is_testmode_skb(dev, skb, &hw)) {
  		struct mt76_phy *phy = hw->priv;
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch b/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch
similarity index 97%
rename from recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch
index 82e8e7d..a0bbf2c 100644
--- a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch
@@ -1,7 +1,7 @@
-From b933c76718db1c21ecaaf0cddfa4d598617153ea Mon Sep 17 00:00:00 2001
+From 2471603cc433dfe9d5d9ba9f22e4692e4170a6a8 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 31 Aug 2022 20:06:52 +0800
-Subject: [PATCH 1011/1014] wifi: mt76: testmode: add pre-cal support
+Subject: [PATCH 1009/1031] wifi: mt76: testmode: add pre-cal support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -36,10 +36,10 @@
  
  out_put_node:
 diff --git a/mt76.h b/mt76.h
-index 3191626..c632852 100644
+index a5908de..7d83d40 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -647,6 +647,7 @@ struct mt76_testmode_ops {
+@@ -658,6 +658,7 @@ struct mt76_testmode_ops {
  			  enum mt76_testmode_state new_state);
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
  	int (*set_eeprom)(struct mt76_phy *phy, u32 offset, u8 *val, u8 action);
@@ -48,10 +48,10 @@
  
  struct mt76_testmode_entry_data {
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 79416e6..df7e50b 100644
+index e3980c3..acbc07d 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -992,6 +992,7 @@ enum {
+@@ -994,6 +994,7 @@ enum {
  
  /* ext event table */
  enum {
@@ -113,10 +113,10 @@
  
  #endif
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 5cea513..2a515e3 100644
+index 2f716f3..91a3710 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -391,6 +391,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -393,6 +393,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_BF_STATUS_READ:
  		mt7915_tm_txbf_status_read(dev, skb);
  		break;
@@ -126,7 +126,7 @@
  #endif
  	default:
  		break;
-@@ -2888,7 +2891,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
+@@ -2927,7 +2930,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
  	u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
  	u32 total = MT_EE_CAL_GROUP_SIZE;
  
@@ -135,7 +135,7 @@
  		return 0;
  
  	/*
-@@ -2968,11 +2971,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+@@ -3007,11 +3010,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
  {
  	struct mt7915_dev *dev = phy->dev;
  	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
@@ -168,10 +168,10 @@
  
  	idx = mt7915_dpd_freq_idx(center_freq, chandef->width);
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 83743cd..54e8944 100644
+index 84f75e7..fcfe53f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -406,6 +406,10 @@ struct mt7915_dev {
+@@ -341,6 +341,10 @@ struct mt7915_dev {
  	struct rchan *relay_fwlog;
  
  	void *cal;
@@ -182,7 +182,7 @@
  
  	struct {
  		u8 debug_wm;
-@@ -642,6 +646,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
+@@ -578,6 +582,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
  void mt7915_mcu_exit(struct mt7915_dev *dev);
  int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb);
@@ -191,7 +191,7 @@
  static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
  {
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 62ef4db..b2d26ff 100644
+index 1e72bf2..7d285eb 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -5,6 +5,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch b/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch
similarity index 98%
rename from recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch
index fb2113a..acba084 100644
--- a/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch
@@ -1,7 +1,7 @@
-From e44d59d15e90c11b1466b12ac9401922c11504f6 Mon Sep 17 00:00:00 2001
+From d2566732630e8562709f3dc24069335fd551f821 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Mon, 12 Sep 2022 18:16:54 +0800
-Subject: [PATCH 1012/1014] wifi: mt76: testmode: add iBF command mode support
+Subject: [PATCH 1010/1031] wifi: mt76: testmode: add iBF command mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 85 insertions(+), 7 deletions(-)
 
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index b2d26ff..40a3a06 100644
+index 7d285eb..f735cae 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -720,6 +720,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
diff --git a/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
similarity index 97%
rename from recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
index f920fd6..1875c93 100644
--- a/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
@@ -1,7 +1,7 @@
-From ee654a359005c8f5e48cc34a42dc76a6550d7e7f Mon Sep 17 00:00:00 2001
+From 9067741d5a3b3ec88618912e243c192c419d518f Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 27 Oct 2022 17:42:07 +0800
-Subject: [PATCH 1013/1014] wifi: mt76: testmode: add ZWDFS test mode support
+Subject: [PATCH 1011/1031] wifi: mt76: testmode: add ZWDFS test mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -18,10 +18,10 @@
  10 files changed, 508 insertions(+), 1 deletion(-)
 
 diff --git a/mt76.h b/mt76.h
-index c632852..f4412a2 100644
+index 7d83d40..75b2874 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -730,6 +730,15 @@ struct mt76_testmode_data {
+@@ -741,6 +741,15 @@ struct mt76_testmode_data {
  		u64 fcs_error[__MT_RXQ_MAX];
  		u64 len_mismatch;
  	} rx_stats;
@@ -38,10 +38,10 @@
  
  struct mt76_vif {
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index df7e50b..7663522 100644
+index acbc07d..e55e548 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1192,6 +1192,7 @@ enum {
+@@ -1195,6 +1195,7 @@ enum {
  	MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
  	MCU_EXT_CMD_SET_RDD_TH = 0x9d,
  	MCU_EXT_CMD_MURU_CTRL = 0x9f,
@@ -49,7 +49,7 @@
  	MCU_EXT_CMD_RX_STAT = 0xa4,
  	MCU_EXT_CMD_SET_SPR = 0xa8,
  	MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
-@@ -1202,6 +1203,7 @@ enum {
+@@ -1205,6 +1206,7 @@ enum {
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_CERT_CFG = 0xb7,
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
@@ -58,10 +58,10 @@
  
  enum {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 2a515e3..cb70af5 100644
+index 91a3710..8203006 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2619,6 +2619,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
+@@ -2658,6 +2658,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
  		req.monitor_chan = chandef->chan->hw_value;
  		req.monitor_central_chan =
  			ieee80211_frequency_to_channel(chandef->center_freq1);
@@ -69,7 +69,7 @@
  		req.band_idx = phy->mt76->band_idx;
  		req.scan_mode = 2;
  		break;
-@@ -4602,3 +4603,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable)
+@@ -4697,3 +4698,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable)
  	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MEC_CTRL), &req, sizeof(req), true);
  }
  #endif
@@ -196,18 +196,18 @@
  #define OFDMA_DL                       BIT(0)
  #define OFDMA_UL                       BIT(1)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 54e8944..e9fc92a 100644
+index fcfe53f..cdd1833 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -305,6 +305,7 @@ struct mt7915_phy {
+@@ -242,6 +242,7 @@ struct mt7915_phy {
  
- 	struct mib_stats mib;
+ 	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
 +	struct delayed_work ipi_work;
  
  	u8 stats_work_count;
  	struct list_head stats_list;
-@@ -759,6 +760,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+@@ -694,6 +695,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
  
@@ -218,10 +218,10 @@
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
  int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp);
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index b6f36f5..a7e8598 100644
+index 428f482..482b3fe 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
-@@ -1205,6 +1205,8 @@ enum offs_rev {
+@@ -1208,6 +1208,8 @@ enum offs_rev {
  #define MT_WF_IRPI_NSS(phy, nss)	MT_WF_IRPI(0x6000 + ((phy) << 20) + ((nss) << 16))
  #define MT_WF_IRPI_NSS_MT7916(phy, nss)	MT_WF_IRPI(0x1000 + ((phy) << 20) + ((nss) << 16))
  
@@ -231,7 +231,7 @@
  #define MT_WF_PHY_BASE			0x83080000
  #define MT_WF_PHY(ofs)			(MT_WF_PHY_BASE + (ofs))
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 40a3a06..b98aaaa 100644
+index f735cae..2e51dcd 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -13,6 +13,12 @@ enum {
diff --git a/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch b/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
similarity index 92%
rename from recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
rename to recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
index 1163a02..defa03f 100644
--- a/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
@@ -1,8 +1,8 @@
-From 44b3c5fed9a9c63e7da34004d265669f241a2886 Mon Sep 17 00:00:00 2001
+From 4e08b1f0bd72662d736b536b42ffe3221e1f0f3f Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 15 Dec 2022 19:45:18 +0800
-Subject: [PATCH] wifi: mt76: testmode: add iBF/eBF cal and cert commands with
- golden
+Subject: [PATCH 1012/1031] wifi: mt76: testmode: add iBF/eBF cal and cert
+ commands with golden
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -25,10 +25,10 @@
  16 files changed, 856 insertions(+), 324 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index 29164534..0e29248d 100644
+index 75b2874..af29bde 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -700,6 +700,7 @@ struct mt76_testmode_data {
+@@ -703,6 +703,7 @@ struct mt76_testmode_data {
  
  	struct list_head tm_entry_list;
  	struct mt76_wcid *cur_entry;
@@ -36,7 +36,7 @@
  	u8 entry_num;
  	union {
  		struct mt76_testmode_entry_data ed;
-@@ -728,6 +729,9 @@ struct mt76_testmode_data {
+@@ -731,6 +732,9 @@ struct mt76_testmode_data {
  
  	u8 txbf_act;
  	u16 txbf_param[8];
@@ -47,10 +47,10 @@
  	u32 tx_pending;
  	u32 tx_queued;
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 0f52b456..2aea5cf4 100644
+index 74b63f0..e6b468c 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
-@@ -2764,6 +2764,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
+@@ -2767,6 +2767,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
  	u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
  	struct bss_info_basic *bss;
  	struct tlv *tlv;
@@ -58,7 +58,7 @@
  
  	tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
  	bss = (struct bss_info_basic *)tlv;
-@@ -2823,6 +2824,8 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
+@@ -2826,6 +2827,8 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
  		bss->dtim_period = vif->bss_conf.dtim_period;
  		bss->phy_mode = mt76_connac_get_phy_mode(phy, vif,
  							 chandef->chan->band, NULL);
@@ -68,10 +68,10 @@
  		memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
  	}
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 5b907c95..02a369d2 100644
+index 98c433f..4dfbc0c 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -728,8 +728,10 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+@@ -729,8 +729,10 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
  		val |= MT_TXD6_LDPC;
  
  	txwi[3] &= ~cpu_to_le32(MT_TXD3_SN_VALID);
@@ -84,7 +84,7 @@
  	txwi[6] |= cpu_to_le32(val);
  #endif
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 798eaa85..a9cbaed8 100644
+index 2e3d2f6..bd49b21 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -205,46 +205,37 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)
@@ -175,10 +175,10 @@
  
  	return ret;
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 2432e578..bc284541 100644
+index 8203006..8d8255e 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -197,6 +197,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
+@@ -199,6 +199,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
  	int ret;
  
  	ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, wait_seq);
@@ -186,7 +186,7 @@
  	if (ret)
  		return ret;
  
-@@ -387,10 +388,12 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -389,10 +390,12 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
  	case MCU_EXT_EVENT_BCC_NOTIFY:
  		mt7915_mcu_rx_bcc_notify(dev, skb);
  		break;
@@ -201,7 +201,7 @@
  	case MCU_EXT_EVENT_RF_TEST:
  		mt7915_tm_rf_test_event(dev, skb);
  		break;
-@@ -677,11 +680,22 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
+@@ -681,11 +684,22 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
  	if (enable)
  		mt76_connac_mcu_bss_omac_tlv(skb, vif);
  
@@ -227,7 +227,7 @@
  
  	if (enable) {
  		mt7915_mcu_bss_rfch_tlv(skb, vif, phy);
-@@ -3389,6 +3403,7 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
+@@ -3429,6 +3443,7 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
  
  int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
  {
@@ -235,7 +235,7 @@
  	struct {
  		u8 action;
  		union {
-@@ -3415,7 +3430,6 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
+@@ -3455,7 +3470,6 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action)
  		.action = action,
  	};
  
@@ -243,7 +243,7 @@
  	switch (action) {
  	case MT_BF_SOUNDING_ON:
  		req.snd.snd_mode = MT_BF_PROCESSING;
-@@ -4494,6 +4508,9 @@ int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
+@@ -4590,6 +4604,9 @@ int mt7915_mcu_set_txbf_sound_info(struct mt7915_phy *phy, u8 action,
  		req.he_opt = v2;
  		req.glo_opt = v3;
  		break;
@@ -254,7 +254,7 @@
  		return -EINVAL;
  	}
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index d361f63e..7f13f3b0 100644
+index d361f63..7f13f3b 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -531,10 +531,12 @@ enum {
@@ -448,7 +448,7 @@
  	MURU_SET_ARB_OP_MODE = 14,
  	MURU_SET_PLATFORM_TYPE = 25,
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index fd5722b9..d5198eb5 100644
+index 6505d76..25c3fe2 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -133,6 +133,7 @@ static const u32 mt7915_offs[] = {
@@ -468,10 +468,10 @@
  	[AGG_AALCR0]		= 0x028,
  	[AGG_AWSCR0]		= 0x030,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 37949f23..67efe9d8 100644
+index cdd1833..7bb7153 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -323,7 +323,6 @@ struct mt7915_phy {
+@@ -260,7 +260,6 @@ struct mt7915_phy {
  
  		u8 spe_idx;
  
@@ -479,7 +479,7 @@
  		bool bf_ever_en;
  	} test;
  #endif
-@@ -427,7 +426,7 @@ struct mt7915_dev {
+@@ -362,7 +361,7 @@ struct mt7915_dev {
  	void __iomem *dcm;
  	void __iomem *sku;
  
@@ -488,15 +488,15 @@
  	struct {
  		void *txbf_phase_cal;
  		void *txbf_pfmu_data;
-@@ -565,6 +564,7 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev);
+@@ -500,6 +499,7 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev);
  int mt7915_dma_reset(struct mt7915_dev *dev, bool force);
- int __mt7915_dma_enable(struct mt7915_dev *dev, bool reset, bool wed_reset);
+ int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset);
  int mt7915_txbf_init(struct mt7915_dev *dev);
 +int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_en);
  void mt7915_init_txpower(struct mt7915_dev *dev,
  			 struct ieee80211_supported_band *sband);
  void mt7915_reset(struct mt7915_dev *dev);
-@@ -646,8 +646,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+@@ -582,8 +582,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
  int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
  void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
  void mt7915_mcu_exit(struct mt7915_dev *dev);
@@ -508,7 +508,7 @@
  
  static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
  {
-@@ -783,4 +785,10 @@ enum {
+@@ -718,4 +720,10 @@ enum {
  
  #endif
  
@@ -520,7 +520,7 @@
 +
  #endif
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index a1e9afcd..be279f7b 100644
+index 0149706..63b4ae0 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -2892,6 +2892,36 @@ mt7915_txpower_level_set(void *data, u64 val)
@@ -573,7 +573,7 @@
  
  	return 0;
 diff --git a/mt7915/mtk_mcu.c b/mt7915/mtk_mcu.c
-index 143dae26..906c8725 100644
+index 143dae2..906c872 100644
 --- a/mt7915/mtk_mcu.c
 +++ b/mt7915/mtk_mcu.c
 @@ -1,9 +1,10 @@
@@ -836,7 +836,7 @@
 +}
 +#endif
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index a7e8598..5d91b80 100644
+index 482b3fe..44da7b8 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
 @@ -61,6 +61,7 @@ enum offs_rev {
@@ -847,7 +847,7 @@
  	RMAC_MIB_AIRTIME14,
  	AGG_AALCR0,
  	AGG_AWSCR0,
-@@ -530,6 +531,9 @@ enum offs_rev {
+@@ -533,6 +534,9 @@ enum offs_rev {
  #define MT_ARB_DRNGR0(_band, _n)	MT_WF_ARB(_band, (__OFFS(ARB_DRNGR0) +	\
  							  (_n) * 4))
  
@@ -858,7 +858,7 @@
  #define MT_WF_RMAC_BASE(_band)		((_band) ? 0x820f5000 : 0x820e5000)
  #define MT_WF_RMAC(_band, ofs)		(MT_WF_RMAC_BASE(_band) + (ofs))
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index b98aaaa..5665da7 100644
+index 2e51dcd..fafe909 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
 @@ -53,6 +53,8 @@ struct reg_band {
@@ -870,8 +870,8 @@
  
  static u8 mt7915_tm_chan_bw(enum nl80211_chan_width width)
  {
-@@ -73,6 +75,25 @@ static u8 mt7915_tm_chan_bw(enum nl80211_chan_width width)
- 	return width_to_bw[width];
+@@ -92,6 +94,25 @@ mt7915_tm_check_antenna(struct mt7915_phy *phy)
+ 	return 0;
  }
  
 +static u8 mt7915_tm_rate_to_phy(u8 tx_rate_mode)
@@ -896,7 +896,7 @@
  static void
  mt7915_tm_update_channel(struct mt7915_phy *phy)
  {
-@@ -273,17 +294,33 @@ mt7915_tm_add_txbf(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -292,17 +313,33 @@ mt7915_tm_add_txbf(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
  	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
  	struct mt7915_dev *dev = phy->dev;
@@ -937,7 +937,7 @@
  
  	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
  					    &msta->wcid);
-@@ -299,8 +336,11 @@ mt7915_tm_add_txbf(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -318,8 +355,11 @@ mt7915_tm_add_txbf(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  	bf->ncol = nc;
  	bf->nrow = nr;
  	bf->ndp_rate = ndp_rate;
@@ -950,7 +950,7 @@
  
  	if (ebf) {
  		bf->mem[0].row = 0;
-@@ -353,11 +393,8 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
+@@ -372,11 +412,8 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
  	}
  
  	memcpy(sta->addr, ed->addr[0], ETH_ALEN);
@@ -964,7 +964,7 @@
  
  	if (td->tx_rate_mode >= MT76_TM_TX_MODE_HT)
  		memcpy(&sta->deflink.ht_cap, &sband->ht_cap, sizeof(sta->deflink.ht_cap));
-@@ -382,6 +419,14 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
+@@ -401,6 +438,14 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
  	list_add_tail(&msta->wcid.list, &td->tm_entry_list);
  	td->entry_num++;
  
@@ -979,7 +979,7 @@
  	return 0;
  }
  
-@@ -451,7 +496,7 @@ mt7915_tm_update_entry(struct mt7915_phy *phy)
+@@ -470,7 +515,7 @@ mt7915_tm_update_entry(struct mt7915_phy *phy)
  	struct mt76_testmode_entry_data *ed, tmp;
  	struct mt76_wcid *wcid, *last;
  
@@ -988,7 +988,7 @@
  		return;
  
  	memcpy(&tmp, &td->ed, sizeof(tmp));
-@@ -472,20 +517,30 @@ mt7915_tm_update_entry(struct mt7915_phy *phy)
+@@ -491,20 +536,30 @@ mt7915_tm_update_entry(struct mt7915_phy *phy)
  static int
  mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
  {
@@ -1022,7 +1022,7 @@
  					 MAX_PHASE_GROUP_NUM,
  					 GFP_KERNEL);
  		if (!phase_cal)
-@@ -495,7 +550,10 @@ mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
+@@ -514,7 +569,10 @@ mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
  	}
  
  	if (!dev->test.txbf_pfmu_data) {
@@ -1034,7 +1034,7 @@
  		if (!pfmu_data)
  			return -ENOMEM;
  
-@@ -504,21 +562,77 @@ mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
+@@ -523,21 +581,77 @@ mt7915_tm_txbf_init(struct mt7915_phy *phy, u16 *val)
  
  	if (!dev->test.txbf_pfmu_tag) {
  		pfmu_tag = devm_kzalloc(dev->mt76.dev,
@@ -1118,7 +1118,7 @@
  
  	return mt7915_tm_set_trx(phy, TM_MAC_TX, true);
  }
-@@ -545,8 +659,7 @@ mt7915_tm_txbf_phase_comp(struct mt7915_phy *phy, u16 *val)
+@@ -564,8 +678,7 @@ mt7915_tm_txbf_phase_comp(struct mt7915_phy *phy, u16 *val)
  		.read_from_e2p = val[3],
  		.disable = val[4],
  	};
@@ -1128,7 +1128,7 @@
  
  	wait_event_timeout(dev->mt76.tx_wait, phase[val[2]].status != 0, HZ);
  	memcpy(req.buf, &phase[val[2]].phase, sizeof(req.buf));
-@@ -559,32 +672,9 @@ mt7915_tm_txbf_phase_comp(struct mt7915_phy *phy, u16 *val)
+@@ -578,32 +691,9 @@ mt7915_tm_txbf_phase_comp(struct mt7915_phy *phy, u16 *val)
  				 sizeof(req), true);
  }
  
@@ -1162,7 +1162,7 @@
  {
  	struct mt7915_dev *dev = phy->dev;
  	struct {
-@@ -611,8 +701,6 @@ static int
+@@ -630,8 +720,6 @@ static int
  mt7915_tm_txbf_apply_tx(struct mt7915_phy *phy, u16 wlan_idx, bool ebf,
  			bool ibf, bool phase_cal)
  {
@@ -1171,7 +1171,7 @@
  	struct mt7915_dev *dev = phy->dev;
  	struct {
  		u8 category;
-@@ -641,14 +729,15 @@ static int mt7915_tm_txbf_set_rate(struct mt7915_phy *phy,
+@@ -660,14 +748,15 @@ static int mt7915_tm_txbf_set_rate(struct mt7915_phy *phy,
  {
  	struct mt7915_dev *dev = phy->dev;
  	struct mt76_testmode_entry_data *ed = mt76_testmode_entry_data(phy->mt76, wcid);
@@ -1189,7 +1189,7 @@
  	rate.nss = ed->tx_rate_nss;
  	rate.mcs = ed->tx_rate_idx;
  	rate.ldpc = (rate.bw || ed->tx_rate_ldpc) * GENMASK(2, 0);
-@@ -662,13 +751,14 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
+@@ -681,13 +770,14 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
  {
  	bool bf_on = val[0], update = val[3];
  	/* u16 wlan_idx = val[2]; */
@@ -1206,7 +1206,7 @@
  		tag->t1.invalid_prof = false;
  		mt7915_tm_txbf_profile_tag_write(phy, 2, tag);
  
-@@ -683,7 +773,7 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
+@@ -702,7 +792,7 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
  		} else {
  			phy->test.bf_ever_en = false;
  
@@ -1215,7 +1215,7 @@
  			tag->t1.invalid_prof = true;
  			mt7915_tm_txbf_profile_tag_write(phy, 2, tag);
  		}
-@@ -698,6 +788,7 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
+@@ -717,6 +807,7 @@ mt7915_tm_txbf_set_tx(struct mt7915_phy *phy, u16 *val)
  static int
  mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
  {
@@ -1223,7 +1223,7 @@
  	static const u8 mode_to_lm[] = {
  		[MT76_TM_TX_MODE_CCK] = 0,
  		[MT76_TM_TX_MODE_OFDM] = 0,
-@@ -711,7 +802,8 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -730,7 +821,8 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
  	struct mt76_testmode_data *td = &phy->mt76->test;
  	struct mt76_wcid *wcid;
  	struct ieee80211_vif *vif = phy->monitor_vif;
@@ -1233,7 +1233,7 @@
  	u8 pfmu_idx = val[0], nc = val[2], nr;
  	bool is_atenl = val[6];
  	int ret;
-@@ -729,18 +821,22 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -748,18 +840,22 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
  	tag->t1.nr = nr;
  	tag->t1.nc = nc;
  	tag->t1.invalid_prof = true;
@@ -1262,7 +1262,7 @@
  	} else {
  		tag->t1.row_id1 = 4;
  		tag->t1.row_id2 = 5;
-@@ -761,6 +857,19 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -780,6 +876,19 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
  	if (ret)
  		return ret;
  
@@ -1282,7 +1282,7 @@
  	if (!ebf && is_atenl)
  		return mt7915_tm_txbf_apply_tx(phy, 1, false, true, true);
  
-@@ -778,7 +887,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
+@@ -797,7 +906,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
  		u8 category;
  		u8 group_l_m_n;
  		u8 group;
@@ -1291,7 +1291,7 @@
  		u8 cal_type;
  		u8 lna_gain_level;
  		u8 _rsv[2];
-@@ -786,12 +895,12 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
+@@ -805,12 +914,12 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
  		.category = MT_BF_PHASE_CAL,
  		.group = val[0],
  		.group_l_m_n = val[1],
@@ -1307,7 +1307,7 @@
  
  	phase[req.group].status = 0;
  
-@@ -799,53 +908,10 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
+@@ -818,53 +927,10 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
  				 sizeof(req), true);
  }
  
@@ -1362,7 +1362,7 @@
  	struct mt76_testmode_data *td = &phy->mt76->test;
  	u16 pfmu_idx = val[0];
  	u16 subc_id = val[1];
-@@ -854,9 +920,9 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -873,9 +939,9 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
  	u16 angle31 = val[4];
  	u16 angle41 = val[5];
  	s16 phi11 = 0, phi21 = 0, phi31 = 0;
@@ -1374,7 +1374,7 @@
  		return -EINVAL;
  
  	if (td->tx_antenna_mask == 2) {
-@@ -870,7 +936,7 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -889,7 +955,7 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
  		phi31 = (s16)(angle41 - angle31);
  	}
  
@@ -1383,7 +1383,7 @@
  	pfmu_data = &pfmu_data[subc_id];
  
  	if (subc_id < 32)
-@@ -880,21 +946,21 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -899,21 +965,21 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
  	pfmu_data->phi11 = cpu_to_le16(phi11);
  	pfmu_data->phi21 = cpu_to_le16(phi21);
  	pfmu_data->phi31 = cpu_to_le16(phi31);
@@ -1408,7 +1408,7 @@
  
  		return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION),
  					 &req, sizeof(req), true);
-@@ -906,7 +972,7 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -925,7 +991,7 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
  static int
  mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
  {
@@ -1417,7 +1417,7 @@
  	struct mt7915_dev *dev = phy->dev;
  	u8 *eeprom = dev->mt76.eeprom.data;
  	u16 offset;
-@@ -916,7 +982,7 @@ mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
+@@ -935,7 +1001,7 @@ mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
  	is_7976 = mt7915_check_adie(dev, false) || is_mt7916(&dev->mt76);
  	offset = is_7976 ? 0x60a : 0x651;
  
@@ -1426,7 +1426,7 @@
  	for (i = 0; i < MAX_PHASE_GROUP_NUM; i++) {
  		p = &phase[i];
  
-@@ -931,17 +997,75 @@ mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
+@@ -950,17 +1016,75 @@ mt7915_tm_txbf_e2p_update(struct mt7915_phy *phy)
  	return 0;
  }
  
@@ -1504,7 +1504,7 @@
  		return mt7915_tm_txbf_init(phy, val);
  	case MT76_TM_TXBF_ACT_UPDATE_CH:
  		mt7915_tm_update_channel(phy);
-@@ -967,6 +1091,36 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -986,6 +1110,36 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
  
  		return mt7915_tm_txbf_apply_tx(phy, wlan_idx, ebf, ibf, phase_cal);
  	}
@@ -1541,7 +1541,7 @@
  	default:
  		break;
  	};
-@@ -1186,9 +1340,10 @@ mt7915_tm_set_ipi(struct mt7915_phy *phy)
+@@ -1261,9 +1415,10 @@ mt7915_tm_set_ipi(struct mt7915_phy *phy)
  
  static int
  mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
@@ -1554,7 +1554,7 @@
  	struct mt7915_mcu_tx req = {
  		.valid = true,
  		.mode = tx_cmd,
-@@ -1196,6 +1351,9 @@ mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
+@@ -1271,6 +1426,9 @@ mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
  	};
  	struct edca *e = &req.edca[0];
  
@@ -1564,7 +1564,7 @@
  	e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS;
  	e->set = WMM_PARAM_SET;
  
-@@ -1208,17 +1366,19 @@ mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
+@@ -1283,17 +1441,19 @@ mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
  }
  
  static int
@@ -1585,7 +1585,7 @@
  	u8 band = phy->mt76->band_idx;
  	u32 i2t_time, tr2t_time, txv_time;
  	u16 cw = 0;
-@@ -1232,6 +1392,7 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
+@@ -1307,6 +1467,7 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
  	ipg -= sig_ext;
  
  	if (ipg <= (TM_MAX_SIFS + slot_time)) {
@@ -1593,7 +1593,7 @@
  		sifs = ipg - slot_time;
  	} else {
  		u32 val = (ipg + slot_time) / slot_time;
-@@ -1267,10 +1428,12 @@ done:
+@@ -1342,10 +1503,12 @@ done:
  
  	mt7915_tm_set_slot_time(phy, slot_time, sifs);
  
@@ -1608,7 +1608,7 @@
  }
  
  static int
-@@ -1469,7 +1632,7 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -1544,7 +1707,7 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
  
  		phy->mt76->test.aid = 0;
  		phy->mt76->test.tx_mpdu_len = 0;
@@ -1617,7 +1617,7 @@
  		mt7915_tm_set_entry(phy);
  	} else {
  		INIT_DELAYED_WORK(&phy->ipi_work, mt7915_tm_ipi_work);
-@@ -1654,7 +1817,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1729,7 +1892,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  		u32 tx_time = td->tx_time, ipg = td->tx_ipg;
  		u8 duty_cycle = td->tx_duty_cycle;
  
@@ -1626,7 +1626,7 @@
  			mt7915_tm_update_channel(phy);
  
  		if (td->tx_spe_idx)
-@@ -1669,7 +1832,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1744,7 +1907,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  			if (duty_cycle < 100)
  				tx_time = duty_cycle * ipg / (100 - duty_cycle);
  		}
@@ -1635,7 +1635,7 @@
  		mt7915_tm_set_tx_len(phy, tx_time);
  
  		if (ipg)
-@@ -1688,6 +1851,9 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1763,6 +1926,9 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
  		mt7915_tm_tx_frames_mu(phy, en);
  
  	mt7915_tm_set_trx(phy, TM_MAC_TX, en);
@@ -1645,7 +1645,7 @@
  }
  
  static int
-@@ -1779,7 +1945,7 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+@@ -1854,7 +2020,7 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
  	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
  
  	if (en) {
@@ -1654,7 +1654,7 @@
  			mt7915_tm_update_channel(phy);
  		if (td->aid)
  			mt7915_tm_set_rx_user_idx(phy, td->aid);
-@@ -1796,6 +1962,9 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+@@ -1871,6 +2037,9 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
  		mt7915_tm_set_muru_aid(phy, en ? td->aid : 0xf800);
  
  	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
@@ -1664,7 +1664,7 @@
  }
  
  static int
-@@ -1855,34 +2024,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
+@@ -1930,34 +2099,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
  		rate_idx = sband->bitrates[idx].hw_value & 0xff;
  	}
  
@@ -1885,7 +1885,7 @@
  	/* keep last */
  	NUM_MT76_TM_TXBF_ACT,
 diff --git a/tools/fields.c b/tools/fields.c
-index fc01043e..7caacb94 100644
+index fc01043..7caacb9 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -33,7 +33,10 @@ static const char * const testmode_tx_mode[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch b/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
similarity index 72%
rename from recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
rename to recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
index 5a6e92f..72ea192 100644
--- a/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch
@@ -1,7 +1,7 @@
-From 0ec1b67bab3908a2990b9698093f5307535ee697 Mon Sep 17 00:00:00 2001
+From dfdfc04bade216097db573acdeab7a0bdb17ed0a Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Sun, 24 Apr 2022 10:07:00 +0800
-Subject: [PATCH 1015/1033] wifi: mt76: mt7915: init rssi in WTBL when add
+Subject: [PATCH 1013/1031] wifi: mt76: mt7915: init rssi in WTBL when add
  station
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 4 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index a9cbaed..972cd1a 100644
+index bd49b21..70ceb5d 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -692,6 +692,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -718,6 +718,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
  #endif
  	int ret, idx;
@@ -20,7 +20,7 @@
  
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
  	if (idx < 0)
-@@ -716,6 +717,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -742,6 +743,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (ret)
  		return ret;
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch b/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
similarity index 71%
rename from recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
rename to recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
index b5fa9d4..8b75f3d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch
@@ -1,7 +1,7 @@
-From fc4243228375ae6b3b27dc6bd73b16bc86cd5482 Mon Sep 17 00:00:00 2001
+From 58af0b3d79b19bb572121c089f40aa74c5262f20 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 6 May 2022 15:58:42 +0800
-Subject: [PATCH 1016/1033] wifi: mt76: connac: airtime fairness feature off in
+Subject: [PATCH 1014/1031] wifi: mt76: connac: airtime fairness feature off in
  mac80211
 
 ---
@@ -9,10 +9,10 @@
  1 file changed, 1 deletion(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 75e2ffe..fb0aea6 100644
+index 966d8d0..ddc13dd 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -436,7 +436,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
+@@ -437,7 +437,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
  			WIPHY_FLAG_AP_UAPSD;
  
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
diff --git a/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch b/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
similarity index 93%
rename from recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
rename to recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
index 0a2cb92..978fb5d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1015-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch
@@ -1,7 +1,7 @@
-From cd68747e751a5efef46b66675568ba16050d84d2 Mon Sep 17 00:00:00 2001
+From 6ed8355ed9d1e4e8bd15c9ed3b1799ed25358240 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Fri, 20 May 2022 19:19:25 +0800
-Subject: [PATCH 1017/1033] wifi: mt76: mt7915: add mt7986 and mt7916
+Subject: [PATCH 1015/1031] wifi: mt76: mt7915: add mt7986 and mt7916
  pre-calibration
 
 Add pre-calibration for mt7986 and mt7916. It has different data size
@@ -63,10 +63,10 @@
  	MT_EE_RATE_DELTA_5G =	0x29d,
  	MT_EE_TX0_POWER_2G =	0x2fc,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index bc28454..fcd07ed 100644
+index 8d8255e..1bbcf42 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2903,7 +2903,8 @@ static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx,
+@@ -2943,7 +2943,8 @@ static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx,
  int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
  {
  	u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
@@ -76,7 +76,7 @@
  
  	if (!(eep[offs] & MT_EE_WIFI_CAL_GROUP))
  		return 0;
-@@ -2941,9 +2942,9 @@ static int mt7915_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
+@@ -2981,9 +2982,9 @@ static int mt7915_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
  	return -1;
  }
  
@@ -88,7 +88,7 @@
  		5180, 5200, 5220, 5240,
  		5260, 5280, 5300, 5320,
  		5500, 5520, 5540, 5560,
-@@ -2951,34 +2952,69 @@ static int mt7915_dpd_freq_idx(u16 freq, u8 bw)
+@@ -2991,34 +2992,69 @@ static int mt7915_dpd_freq_idx(u16 freq, u8 bw)
  		5660, 5680, 5700, 5745,
  		5765, 5785, 5805, 5825
  	};
@@ -168,7 +168,7 @@
  }
  
  int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
-@@ -3010,24 +3046,24 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+@@ -3050,24 +3086,24 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
  	if (!(eep[offs] & dpd_mask))
  		return 0;
  
diff --git a/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch b/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
rename to recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
index f373601..e6bf515 100644
--- a/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1016-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch
@@ -1,7 +1,7 @@
-From 5b4357f01aa42091e84846490bbb453e97e2cf40 Mon Sep 17 00:00:00 2001
+From 2dce2d65b1a25c230c82d45f9e809cf9c8526a8a Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <Yi-Chia.Hsieh@mediatek.com>
 Date: Tue, 12 Jul 2022 10:04:35 -0700
-Subject: [PATCH 1018/1033] wifi: mt76: mt7915: add phy capability vendor
+Subject: [PATCH 1016/1031] wifi: mt76: mt7915: add phy capability vendor
  command
 
 ---
@@ -11,7 +11,7 @@
  3 files changed, 78 insertions(+)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 3bfd611..fdedacf 100644
+index 7bb7153..d4e85cd 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -11,6 +11,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch b/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
rename to recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
index ead4458..d272113 100644
--- a/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1017-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch
@@ -1,7 +1,7 @@
-From 6b3ebcfbfb1252a3c203c4f6c6309909020b4be2 Mon Sep 17 00:00:00 2001
+From 0ad1449e3a5826799a8446a3b3082943bde83247 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Fri, 24 Jun 2022 11:15:45 +0800
-Subject: [PATCH 1019/1033] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl
+Subject: [PATCH 1017/1031] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl
  enable/threshold/compensation
 
 Change-Id: I06a3f94d5e444be894200e2b6588d76ed38d09d0
@@ -16,10 +16,10 @@
  7 files changed, 265 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 7663522..35fb252 100644
+index e55e548..da2f5dd 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1202,6 +1202,7 @@ enum {
+@@ -1205,6 +1205,7 @@ enum {
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_CERT_CFG = 0xb7,
@@ -28,7 +28,7 @@
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
  };
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 972cd1a..260385e 100644
+index 70ceb5d..4b2c4d9 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -477,6 +477,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
@@ -42,10 +42,10 @@
  		ret = mt7915_set_channel(phy);
  		if (ret)
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index fcd07ed..9cde484 100644
+index 1bbcf42..a43543c 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4720,3 +4720,76 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w
+@@ -4816,3 +4816,76 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w
  
  	return 0;
  }
@@ -155,10 +155,10 @@
  
  #endif
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index fdedacf..2409bf5 100644
+index d4e85cd..59a2e4f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -762,7 +762,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
+@@ -697,7 +697,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
  int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
diff --git a/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-implement-bin-file-mode.patch b/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-implement-bin-file-mode.patch
similarity index 92%
rename from recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-implement-bin-file-mode.patch
rename to recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-implement-bin-file-mode.patch
index f747ddc..723a881 100644
--- a/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-implement-bin-file-mode.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1018-wifi-mt76-mt7915-implement-bin-file-mode.patch
@@ -1,7 +1,7 @@
-From 819b0590e6b8ef9e44e3f0a01c3db33eb236f463 Mon Sep 17 00:00:00 2001
+From 03d79a9399ab4dab4f2624d07d79902224563938 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 7 Jul 2022 11:09:59 +0800
-Subject: [PATCH] wifi: mt76: mt7915: implement bin file mode
+Subject: [PATCH 1018/1031] wifi: mt76: mt7915: implement bin file mode
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -15,7 +15,7 @@
  6 files changed, 111 insertions(+), 3 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index aa889258..412740f0 100644
+index aa88925..412740f 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -104,6 +104,26 @@ out_put_node:
@@ -46,10 +46,10 @@
  mt76_eeprom_override(struct mt76_phy *phy)
  {
 diff --git a/mt76.h b/mt76.h
-index 0e29248d..b49590d5 100644
+index af29bde..b4e3429 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -916,6 +916,9 @@ struct mt76_dev {
+@@ -925,6 +925,9 @@ struct mt76_dev {
  		struct mt76_usb usb;
  		struct mt76_sdio sdio;
  	};
@@ -58,8 +58,8 @@
 +	const char *bin_file_name;
  };
  
- struct mt76_power_limits {
-@@ -1052,6 +1055,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
+ /* per-phy stats.  */
+@@ -1156,6 +1159,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
  int mt76_eeprom_init(struct mt76_dev *dev, int len);
  void mt76_eeprom_override(struct mt76_phy *phy);
  int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
@@ -68,7 +68,7 @@
  struct mt76_queue *
  mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
 diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c
-index a5c99a5e..fd08d42a 100644
+index a5c99a5..fd08d42 100644
 --- a/mt7915/eeprom.c
 +++ b/mt7915/eeprom.c
 @@ -47,8 +47,11 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
@@ -149,7 +149,7 @@
  		if (ret)
  			return ret;
 diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h
-index fdae347e..9056d786 100644
+index fdae347..9056d78 100644
 --- a/mt7915/eeprom.h
 +++ b/mt7915/eeprom.h
 @@ -108,6 +108,13 @@ enum mt7915_sku_rate_group {
@@ -167,10 +167,10 @@
  mt7915_get_channel_group_5g(int channel, bool is_7976)
  {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b22990a5..f2ee80e9 100644
+index 59a2e4f..becd065 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -400,6 +400,8 @@ struct mt7915_dev {
+@@ -335,6 +335,8 @@ struct mt7915_dev {
  
  	bool dbdc_support;
  	bool flash_mode;
@@ -179,7 +179,7 @@
  	bool muru_debug;
  	bool ibf;
  
-@@ -775,6 +777,7 @@ void mt7915_dump_tmac_info(u8 *tmac_info);
+@@ -710,6 +712,7 @@ void mt7915_dump_tmac_info(u8 *tmac_info);
  int mt7915_mcu_set_txpower_level(struct mt7915_phy *phy, u8 drop_level);
  void mt7915_packet_log_to_host(struct mt7915_dev *dev, const void *data, int len, int type, int des_len);
  int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable);
@@ -188,7 +188,7 @@
  #define PKT_BIN_DEBUG_MAGIC	0xc8763123
  enum {
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index be279f7b..809dff3f 100644
+index 63b4ae0..f98667f 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3,6 +3,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-Add-mu-dump-support.patch b/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-Add-mu-dump-support.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-Add-mu-dump-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-Add-mu-dump-support.patch
index 747cbf2..1a7fb1f 100644
--- a/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-Add-mu-dump-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1019-wifi-mt76-mt7915-Add-mu-dump-support.patch
@@ -1,7 +1,7 @@
-From 95f591a8dcc2d3517b85147928677b60f5c9e015 Mon Sep 17 00:00:00 2001
+From 92a5b059b029f74daa27c746f170f98cc8576a30 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Thu, 11 Aug 2022 18:09:45 -0700
-Subject: [PATCH 1022/1033] wifi: mt76: mt7915: Add mu dump support
+Subject: [PATCH 1019/1031] wifi: mt76: mt7915: Add mu dump support
 
 Change-Id: I521214f3feb6f0d528a9f550255050ffd1ec96d2
 ---
diff --git a/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch b/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
similarity index 95%
rename from recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
rename to recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
index 2d62615..3a2702d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1020-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch
@@ -1,7 +1,7 @@
-From ceaf2875e70fba9ac5c4a65f6cfa13c447a2cf0d Mon Sep 17 00:00:00 2001
+From 8c471e9dbac0f144255da57bfe937eb8f17be9f0 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 28 Oct 2022 10:15:56 +0800
-Subject: [PATCH 1023/1033] wifi: mt76: mt7915: add vendor subcmd three wire
+Subject: [PATCH 1020/1031] wifi: mt76: mt7915: add vendor subcmd three wire
  (PTA) ctrl
 
 Change-Id: Ic1044698f294455594a0c6254f55326fdab90580
@@ -16,10 +16,10 @@
  6 files changed, 111 insertions(+), 29 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 35fb252..661d790 100644
+index da2f5dd..daeec01 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1201,7 +1201,7 @@ enum {
+@@ -1204,7 +1204,7 @@ enum {
  	/* for vendor csi and air monitor */
  	MCU_EXT_CMD_SMESH_CTRL = 0xae,
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
@@ -29,10 +29,10 @@
  	MCU_EXT_CMD_CSI_CTRL = 0xc2,
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 9cde484..7603bd8 100644
+index a43543c..ee951bc 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4419,37 +4419,33 @@ void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
+@@ -4515,37 +4515,33 @@ void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable)
  			&req, sizeof(req), false);
  }
  
@@ -134,10 +134,10 @@
  #define OFDMA_DL                       BIT(0)
  #define OFDMA_UL                       BIT(1)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 25f92e1..b3a0f2a 100644
+index becd065..f22d796 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -756,6 +756,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
+@@ -691,6 +691,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction);
  void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable);
  int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val);
  void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type);
diff --git a/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch b/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
rename to recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
index 29dbd3b..3ae5f48 100644
--- a/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch
@@ -1,7 +1,7 @@
-From d85a245c188aaad1fbc08a45c147e2328ac33922 Mon Sep 17 00:00:00 2001
+From 67cc264ada370e3eaf488b3dcee1beae96d00ec4 Mon Sep 17 00:00:00 2001
 From: mtk27835 <shurong.wen@mediatek.com>
 Date: Wed, 7 Sep 2022 14:01:29 -0700
-Subject: [PATCH 1024/1033] wifi: mt76: mt7915: add ibf control vendor cmd
+Subject: [PATCH 1021/1031] wifi: mt76: mt7915: add ibf control vendor cmd
 
 Signed-off-by: mtk27835 <shurong.wen@mediatek.com>
 ---
diff --git a/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-initialize-wcid.patch b/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-initialize-wcid.patch
deleted file mode 100644
index 16954d3..0000000
--- a/recipes-wifi/linux-mt76/files/patches/1021-wifi-mt76-mt7915-initialize-wcid.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 3351af0e260216cb75d03db85982bf4bc9308f7d Mon Sep 17 00:00:00 2001
-From: Sujuan Chen <sujuan.chen@mediatek.com>
-Date: Tue, 12 Jul 2022 13:56:07 +0800
-Subject: [PATCH 1021/1033] wifi: mt76: mt7915: initialize wcid
-
-Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
----
- mt7915/mac.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index af90e19..e5ecb5b 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -1007,7 +1007,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- 		info = le32_to_cpu(*cur_info);
- 		if (info & MT_TX_FREE_PAIR) {
- 			struct mt7915_sta *msta;
--			struct mt76_wcid *wcid;
-+			struct mt76_wcid *wcid = NULL;
- 			struct mt7915_phy *phy;
- 			u16 idx;
- 
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch b/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
rename to recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
index 04e6733..7b5979c 100644
--- a/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1022-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch
@@ -1,7 +1,7 @@
-From db8ca122f32340716f8f130485f7df58cc0d436a Mon Sep 17 00:00:00 2001
+From 8e91f74ba88b15f031d49d6af05334516f4fb767 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 30 Mar 2023 15:12:37 +0800
-Subject: [PATCH 1025/1033] wifi: mt76: mt7915: add E3 re-bonding for low yield
+Subject: [PATCH 1022/1031] wifi: mt76: mt7915: add E3 re-bonding for low yield
  rate issue
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -57,10 +57,10 @@
  	if (ret)
  		return ret;
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b3a0f2a..e2f196b 100644
+index f22d796..5e70b66 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -554,6 +554,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+@@ -489,6 +489,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
  
  int mt7915_register_device(struct mt7915_dev *dev);
  void mt7915_unregister_device(struct mt7915_dev *dev);
diff --git a/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch b/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
similarity index 85%
rename from recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
rename to recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
index 99dfad3..5e25d7b 100644
--- a/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1023-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch
@@ -1,7 +1,7 @@
-From 4127f1f3a388e72e8271f032dc081301a79bfba5 Mon Sep 17 00:00:00 2001
+From 5aea18aadf208d42c34ffae42839f7b9d564d446 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 14 Oct 2022 11:15:13 +0800
-Subject: [PATCH 1026/1033] wifi: mt76: mt7915: support on off SW ACI through
+Subject: [PATCH 1023/1031] wifi: mt76: mt7915: support on off SW ACI through
  debugfs
 
 Signed-off-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
@@ -12,10 +12,10 @@
  2 files changed, 22 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 661d790..1fdbc1c 100644
+index daeec01..8228bbb 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1203,6 +1203,7 @@ enum {
+@@ -1206,6 +1206,7 @@ enum {
  	MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
  	MCU_EXT_CMD_SET_CFG = 0xb7,
  	MCU_EXT_CMD_EDCCA = 0xba,
@@ -24,7 +24,7 @@
  	MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5,
  };
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 2cccebe..acff7ce 100644
+index f98667f..c8b677d 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3644,6 +3644,25 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
@@ -53,7 +53,7 @@
  int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  {
  	struct mt7915_dev *dev = phy->dev;
-@@ -3733,6 +3752,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+@@ -3732,6 +3751,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
  
  	debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir,
  				    mt7915_show_eeprom_mode);
diff --git a/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch b/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
similarity index 92%
rename from recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
index bce4a14..17a1e96 100644
--- a/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1024-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch
@@ -1,7 +1,7 @@
-From cd39ff8dad3bfea4c0ec7ac7e71b92158cfa11b5 Mon Sep 17 00:00:00 2001
+From 960329a1e103dd6ce72f5c866c8f925b905cca76 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 5 Dec 2022 18:21:51 +0800
-Subject: [PATCH 1027/1033] wifi: mt76: mt7915: add bf backoff limit table
+Subject: [PATCH 1024/1031] wifi: mt76: mt7915: add bf backoff limit table
  support
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -58,10 +58,10 @@
  }
  EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
 diff --git a/mt76.h b/mt76.h
-index 668ab2b..ea43716 100644
+index b4e3429..2f801de 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -918,6 +918,14 @@ struct mt76_power_limits {
+@@ -1030,6 +1030,14 @@ struct mt76_power_limits {
  	s8 ofdm[8];
  	s8 mcs[4][10];
  	s8 ru[7][12];
@@ -77,10 +77,10 @@
  
  struct mt76_ethtool_worker_info {
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index 9fca009..a122457 100644
+index d66d104..2b63e56 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
-@@ -1027,7 +1027,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
+@@ -1019,7 +1019,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf,
  	if (!buf)
  		return -ENOMEM;
  
@@ -89,7 +89,7 @@
  	if (ret)
  		goto out;
  
-@@ -1137,7 +1137,7 @@ mt7915_rate_txpower_set(struct file *file, const char __user *user_buf,
+@@ -1129,7 +1129,7 @@ mt7915_rate_txpower_set(struct file *file, const char __user *user_buf,
  
  	mutex_lock(&dev->mt76.mutex);
  	ret = mt7915_mcu_get_txpower_sku(phy, req.txpower_sku,
@@ -98,7 +98,7 @@
  	if (ret)
  		goto out;
  
-@@ -1179,7 +1179,7 @@ out:
+@@ -1171,7 +1171,7 @@ out:
  	return ret ? ret : count;
  }
  
@@ -107,7 +107,7 @@
  	.write = mt7915_rate_txpower_set,
  	.read = mt7915_rate_txpower_get,
  	.open = simple_open,
-@@ -1187,6 +1187,69 @@ static const struct file_operations mt7915_rate_txpower_fops = {
+@@ -1179,6 +1179,69 @@ static const struct file_operations mt7915_rate_txpower_fops = {
  	.llseek = default_llseek,
  };
  
@@ -177,7 +177,7 @@
  static int
  mt7915_twt_stats(struct seq_file *s, void *data)
  {
-@@ -1273,7 +1336,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
+@@ -1265,7 +1328,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
  	debugfs_create_file("implicit_txbf", 0600, dir, dev,
  			    &fops_implicit_txbf);
  	debugfs_create_file("txpower_sku", 0400, dir, phy,
@@ -189,10 +189,10 @@
  				    mt7915_twt_stats);
  	debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 7603bd8..0bec0bc 100644
+index ee951bc..9e64337 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3260,7 +3260,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3300,7 +3300,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  	int ret;
  	s8 txpower_sku[MT7915_SKU_RATE_NUM];
  
@@ -202,7 +202,7 @@
  	if (ret)
  		return ret;
  
-@@ -3302,51 +3303,98 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3342,51 +3343,98 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  
  int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
  {
@@ -326,7 +326,7 @@
  	struct mt7915_dev *dev = phy->dev;
  	struct {
  		u8 format_id;
-@@ -3355,10 +3403,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+@@ -3395,10 +3443,9 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
  		u8 _rsv;
  	} __packed req = {
  		.format_id = TX_POWER_LIMIT_INFO,
@@ -338,7 +338,7 @@
  	struct sk_buff *skb;
  	int ret, i;
  
-@@ -3368,9 +3415,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
+@@ -3408,9 +3455,15 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len)
  	if (ret)
  		return ret;
  
@@ -357,7 +357,7 @@
  
  	dev_kfree_skb(skb);
  
-@@ -3412,9 +3465,18 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
+@@ -3452,9 +3505,18 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
  		.band_idx = phy->mt76->band_idx,
  		.sku_enable = enable,
  	};
@@ -400,7 +400,7 @@
  	SPR_ENABLE = 0x1,
  	SPR_ENABLE_SD = 0x3,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index e2f196b..b4644f6 100644
+index 5e70b66..7584d1f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -72,6 +72,7 @@
@@ -411,7 +411,7 @@
  
  #define MT7915_MAX_TWT_AGRT		16
  #define MT7915_MAX_STA_TWT_AGRT		8
-@@ -621,7 +622,8 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
+@@ -556,7 +557,8 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
  int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
  int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
  int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
diff --git a/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-amsdu-set-and-get-control.patch b/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
similarity index 84%
rename from recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
rename to recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
index 0f0a54f..731ee05 100644
--- a/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1025-wifi-mt76-mt7915-amsdu-set-and-get-control.patch
@@ -1,27 +1,24 @@
-From 433251f722c4efb2b14e19619a19ee85fe58c026 Mon Sep 17 00:00:00 2001
+From 7815bd8d3b07c67262190fb085ad123e3b402d63 Mon Sep 17 00:00:00 2001
 From: TomLiu <tomml.liu@mediatek.com>
 Date: Wed, 14 Dec 2022 00:44:07 -0800
-Subject: [PATCH 1028/1033] wifi: mt76: mt7915: amsdu set and get control
+Subject: [PATCH 1025/1031] wifi: mt76: mt7915: amsdu set and get control
 
 ---
- mt7915/mac.c    | 10 ++++++++++
+ mt7915/mac.c    |  7 +++++++
  mt7915/mt7915.h |  1 +
- mt7915/vendor.c | 31 +++++++++++++++++++++++++++++++
+ mt7915/vendor.c | 30 ++++++++++++++++++++++++++++++
  mt7915/vendor.h | 12 ++++++++++++
- 4 files changed, 54 insertions(+)
+ 4 files changed, 50 insertions(+)
 
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index e5ecb5b..1301b61 100644
+index 4dfbc0c..436fc31 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -2077,6 +2077,16 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
+@@ -2032,6 +2032,13 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
  	spin_unlock_bh(&phy->stats_lock);
  }
  
 +void mt7915_set_wireless_amsdu(struct ieee80211_hw *hw, u8 en) {
-+	struct mt76_phy *mphy = hw->priv;
-+	struct mt76_dev *mdev = mphy->dev;
-+
 +	if (en)
 +		ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
 +	else
@@ -32,10 +29,10 @@
  void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta)
  {
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b4644f6..b0743c0 100644
+index 7584d1f..10c1cba 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -747,6 +747,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -682,6 +682,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  			 bool pci, int *irq);
  
  #ifdef CONFIG_MTK_VENDOR
@@ -44,7 +41,7 @@
  void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
  void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev,
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index b661ea4..3d1984b 100644
+index b661ea4..0105d2f 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -30,10 +30,16 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
@@ -64,7 +61,7 @@
  static const struct nla_policy
  mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
  	[MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
-@@ -985,11 +991,35 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
+@@ -985,11 +991,34 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy,
  		val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]);
  		mt7915_mcu_set_cfg(phy, CFGINFO_CERT_CFG, val8); /* Cert Enable for OMI */
  		mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */
@@ -82,9 +79,8 @@
 +			     unsigned long *storage)
 +{
 +	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-+	struct mt7915_phy *phy = mt7915_hw_phy(hw);
-+	struct mt7915_dev *dev = phy->dev;
 +	int len = 0;
++
 +	if (*storage == 1)
 +		return -ENOENT;
 +	*storage = 1;
@@ -100,7 +96,7 @@
  static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  				  struct wireless_dev *wdev,
  				  const void *data,
-@@ -1288,6 +1318,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1288,6 +1317,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
  			WIPHY_VENDOR_CMD_NEED_RUNNING,
  		.doit = mt7915_vendor_wireless_ctrl,
diff --git a/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch b/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
rename to recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
index d28ba31..3f4be8f 100644
--- a/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1026-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch
@@ -1,7 +1,7 @@
-From 680ee306a830525879b8d972f8cd894b01514225 Mon Sep 17 00:00:00 2001
+From f5f0d7a46738a626f93a76979e1cc99e7b6a21fb Mon Sep 17 00:00:00 2001
 From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
 Date: Tue, 24 Jan 2023 14:32:08 +0800
-Subject: [PATCH 1029/1033] wifi: mt76: mt7915: Add vendor command attribute
+Subject: [PATCH 1026/1031] wifi: mt76: mt7915: Add vendor command attribute
  for RTS BW signaling.
 
 Signed-off-by: himanshu.goyal <himanshu.goyal@mediatek.com>
@@ -13,10 +13,10 @@
  4 files changed, 20 insertions(+)
 
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 0bec0bc..3939768 100644
+index 9e64337..db4642c 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4497,6 +4497,12 @@ int mt7915_mcu_set_cfg(struct mt7915_phy *phy, u8 cfg_info, u8 type)
+@@ -4593,6 +4593,12 @@ int mt7915_mcu_set_cfg(struct mt7915_phy *phy, u8 cfg_info, u8 type)
  		req.cert.length = cpu_to_le16(tlv_len);
  		req.cert.cert_program = type;
  		break;
@@ -62,7 +62,7 @@
  };
  
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 3d1984b..6bbdc6f 100644
+index 0105d2f..fb2fe82 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -33,6 +33,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = {
diff --git a/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch b/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
rename to recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
index 1d9d84a..4e62abc 100644
--- a/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1027-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch
@@ -1,7 +1,7 @@
-From 6f671ea083717d2e0d9578239c761d4fe55e4d74 Mon Sep 17 00:00:00 2001
+From 25137db002576b18fff8eef3ef30f5049a4af036 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Thu, 26 Jan 2023 08:50:47 +0800
-Subject: [PATCH 1030/1033] wifi: mt76: mt7915: add vendor cmd to get available
+Subject: [PATCH 1027/1031] wifi: mt76: mt7915: add vendor cmd to get available
  color bitmap
 
 Add a vendor cmd to notify user space available color bitmap.
@@ -14,7 +14,7 @@
  2 files changed, 48 insertions(+)
 
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index 6bbdc6f..af60880 100644
+index fb2fe82..94c4aad 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -98,6 +98,11 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
@@ -29,7 +29,7 @@
  struct csi_null_tone {
  	u8 start;
  	u8 end;
-@@ -1277,6 +1282,27 @@ mt7915_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+@@ -1276,6 +1281,27 @@ mt7915_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
  	return 1;
  }
  
@@ -57,7 +57,7 @@
  
  static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  	{
-@@ -1383,6 +1409,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+@@ -1382,6 +1408,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
  		.dumpit = mt7915_vendor_ibf_ctrl_dump,
  		.policy = ibf_ctrl_policy,
  		.maxattr = MTK_VENDOR_ATTR_IBF_CTRL_MAX,
diff --git a/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch b/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
rename to recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
index 5e89b94..ea19201 100644
--- a/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1028-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch
@@ -1,7 +1,7 @@
-From 12591211de7e8688434cc1cc93143871e3403507 Mon Sep 17 00:00:00 2001
+From ca0e38bced7648a60d967c0826ae3175b4a21fcd Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Fri, 24 Feb 2023 16:29:42 +0800
-Subject: [PATCH 1031/1033] wifi: mt76: mt7915: disable SW-ACI by default
+Subject: [PATCH 1028/1031] wifi: mt76: mt7915: disable SW-ACI by default
 
 Support to enable/disable SW-ACI by module parameter "sw_aci_enable".
 SW-ACI feature is disable by default.
@@ -13,7 +13,7 @@
  4 files changed, 29 insertions(+), 9 deletions(-)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 260385e..8d1120c 100644
+index 4b2c4d9..95b15a2 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -8,6 +8,10 @@
@@ -39,10 +39,10 @@
  
  	if (phy != &dev->phy) {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 3939768..13e5a54 100644
+index db4642c..cf8d249 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -4857,3 +4857,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value)
+@@ -4953,3 +4953,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value)
  
  	return 0;
  }
@@ -62,10 +62,10 @@
 +				 sizeof(req), NULL);
 +}
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index b0743c0..82d632b 100644
+index 10c1cba..0d3c67b 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -771,6 +771,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+@@ -706,6 +706,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
  #endif
  int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value, s8 compensation);
  int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value);
@@ -74,7 +74,7 @@
  int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp);
  
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index acff7ce..4629f6b 100644
+index c8b677d..336f38e 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -3647,16 +3647,12 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data)
diff --git a/recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch b/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
rename to recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
index dac7194..308cf52 100644
--- a/recipes-wifi/linux-mt76/files/patches/1033-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1029-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch
@@ -1,7 +1,7 @@
-From e3d526b4c7a48f8b220899020e96c1e110f492ca Mon Sep 17 00:00:00 2001
+From 51808db9d3edb7e76fc1d2de5a3cbd7e01d4b3e4 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Thu, 27 Apr 2023 15:37:33 +0800
-Subject: [PATCH 1033/1033] wifi: mt76: mt7915: add muru user number debug
+Subject: [PATCH 1029/1031] wifi: mt76: mt7915: add muru user number debug
  command
 
 ---
@@ -11,10 +11,10 @@
  3 files changed, 17 insertions(+), 1 deletion(-)
 
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 82d632b..45a5254 100644
+index 0d3c67b..8fafbb1 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -635,6 +635,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
+@@ -570,6 +570,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
  int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
  			    const struct mt7915_dfs_pattern *pattern);
  int mt7915_mcu_set_muru_ctrl(struct mt7915_dev *dev, u32 cmd, u32 val);
@@ -23,7 +23,7 @@
  int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy);
  int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
 diff --git a/mt7915/vendor.c b/mt7915/vendor.c
-index af60880..a2f3f45 100644
+index 94c4aad..b450808 100644
 --- a/mt7915/vendor.c
 +++ b/mt7915/vendor.c
 @@ -45,6 +45,8 @@ static const struct nla_policy
@@ -35,7 +35,7 @@
  };
  
  static const struct nla_policy
-@@ -1035,9 +1037,10 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -1034,9 +1036,10 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  				  int data_len)
  {
  	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
@@ -47,7 +47,7 @@
  	u32 val32 = 0;
  
  	err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
-@@ -1051,6 +1054,16 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
+@@ -1050,6 +1053,16 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy,
  			 FIELD_PREP(RATE_CFG_VAL, val8);
  		ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
  			mt7915_set_wireless_vif, &val32);
diff --git a/recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch b/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
rename to recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
index d030805..bb8dbf1 100644
--- a/recipes-wifi/linux-mt76/files/patches/1034-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1030-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch
@@ -1,7 +1,7 @@
-From 4eb61cd26244aca09e163a7a013b3190cab35ced Mon Sep 17 00:00:00 2001
+From eb4ee3779dde8b15d03c32516d89c87bd19381c1 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 22 May 2023 15:30:21 +0800
-Subject: [PATCH] wifi: mt76: mt7915: add debugfs for fw coredump.
+Subject: [PATCH 1030/1031] wifi: mt76: mt7915: add debugfs for fw coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 58 insertions(+), 9 deletions(-)
 
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index a122457e..8dd79d8f 100644
+index 2b63e56..99ce0a9 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -82,8 +82,10 @@ mt7915_sys_recovery_set(struct file *file, const char __user *user_buf,
@@ -67,10 +67,10 @@
  	/* SER statistics */
  	desc += scnprintf(buff + desc, bufsz - desc,
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 4e3c869c..498c3984 100644
+index 436fc31..f930c50 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -1783,10 +1783,34 @@ void mt7915_mac_dump_work(struct work_struct *work)
+@@ -1725,10 +1725,34 @@ void mt7915_mac_dump_work(struct work_struct *work)
  
  	dev = container_of(work, struct mt7915_dev, dump_work);
  
@@ -107,7 +107,7 @@
  }
  
  void mt7915_reset(struct mt7915_dev *dev)
-@@ -1809,7 +1833,7 @@ void mt7915_reset(struct mt7915_dev *dev)
+@@ -1747,7 +1771,7 @@ void mt7915_reset(struct mt7915_dev *dev)
  			 wiphy_name(dev->mt76.hw->wiphy));
  
  		mt7915_irq_disable(dev, MT_INT_MCU_CMD);
@@ -117,7 +117,7 @@
  	}
  
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 8ac70e56..7febe658 100644
+index 8ac70e5..7febe65 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -745,8 +745,12 @@ enum {
@@ -135,7 +135,7 @@
  	SER_ENABLE = 2,
  	SER_RECOVER
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 677856b4..cb2afeeb 100644
+index 8fafbb1..b7fa1a4 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -91,6 +91,13 @@ struct mt7915_sta;
@@ -152,7 +152,7 @@
  enum mt7915_txq_id {
  	MT7915_TXQ_FWDL = 16,
  	MT7915_TXQ_MCU_WM,
-@@ -386,6 +393,7 @@ struct mt7915_dev {
+@@ -323,6 +330,7 @@ struct mt7915_dev {
  
  	/* protects coredump data */
  	struct mutex dump_mutex;
@@ -160,7 +160,7 @@
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
  		struct mt7915_crash_data *crash_data[__MT76_RAM_TYPE_MAX];
-@@ -573,6 +581,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
+@@ -508,6 +516,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
  void mt7915_init_txpower(struct mt7915_dev *dev,
  			 struct ieee80211_supported_band *sband);
  void mt7915_reset(struct mt7915_dev *dev);
diff --git a/recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-remove-BW160-support.patch b/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-remove-BW160-support.patch
similarity index 62%
rename from recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-remove-BW160-support.patch
rename to recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-remove-BW160-support.patch
index aa0efc4..77ad7f1 100644
--- a/recipes-wifi/linux-mt76/files/patches/1035-wifi-mt76-mt7915-remove-BW160-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1031-wifi-mt76-mt7915-remove-BW160-support.patch
@@ -1,46 +1,50 @@
-From 22ffda45e657edd08380a24b3615d8e924775af8 Mon Sep 17 00:00:00 2001
+From a16f98e2a2abcda88b80b5614d38b4083e30b59f Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Wed, 24 May 2023 22:35:54 +0800
-Subject: [PATCH] wifi: mt76: mt7915: remove BW160 support
+Subject: [PATCH 1031/1031] wifi: mt76: mt7915: remove BW160 support
 
 Remove BW160 capability in mt7915.
 ---
- mt7915/init.c | 24 +++++-------------------
- 1 file changed, 5 insertions(+), 19 deletions(-)
+ mt7915/init.c | 29 +++++++----------------------
+ 1 file changed, 7 insertions(+), 22 deletions(-)
 
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 8eacf34..527cbac 100644
+index 09ee080..bc16f17 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -416,12 +416,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+@@ -420,13 +420,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
+ 
  			vht_cap->cap |=
  				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
- 				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
+-				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
 -
 -			if (!dev->dbdc_support)
 -				vht_cap->cap |=
 -					IEEE80211_VHT_CAP_SHORT_GI_160 |
 -					IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
 -					FIELD_PREP(IEEE80211_VHT_CAP_EXT_NSS_BW_MASK, 1);
++				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;;
  		} else {
- 			vht_cap->cap |=
- 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
-@@ -870,12 +864,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
+ 			phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
+ 				IEEE80211_HT_MPDU_DENSITY_2;
+@@ -886,13 +880,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy,
  	int sts = hweight8(phy->mt76->chainmask);
  	u8 c, sts_160 = sts;
  
 -	/* Can do 1/2 of STS in 160Mhz mode for mt7915 */
-+	/* mt7915 doesn't support bw160 */
- 	if (is_mt7915(&dev->mt76)) {
+-	if (is_mt7915(&dev->mt76)) {
 -		if (!dev->dbdc_support)
 -			sts_160 /= 2;
 -		else
 -			sts_160 = 0;
+-	}
++	/* mt7915 doesn't support bw160 */
++	if (is_mt7915(&dev->mt76))
 +		sts_160 = 0;
- 	}
  
  #ifdef CONFIG_MAC80211_MESH
-@@ -956,15 +947,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
+ 	if (vif == NL80211_IFTYPE_MESH_POINT)
+@@ -972,15 +962,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
  	int i, idx = 0, nss = hweight8(phy->mt76->antenna_mask);
  	u16 mcs_map = 0;
  	u16 mcs_map_160 = 0;
@@ -60,5 +64,5 @@
  
  	for (i = 0; i < 8; i++) {
 -- 
-2.39.0
+2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-Add-5G-UNII4-support.patch b/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-Add-5G-UNII4-support.patch
deleted file mode 100644
index af92dad..0000000
--- a/recipes-wifi/linux-mt76/files/patches/1032-wifi-mt76-mt7915-Add-5G-UNII4-support.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From ebee8109eb2d0dba82518e3b1ceae58580b65b69 Mon Sep 17 00:00:00 2001
-From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
-Date: Tue, 2 May 2023 15:08:42 +0800
-Subject: [PATCH 1032/1033] wifi: mt76: mt7915: Add 5G UNII4 support.
-
----
- mac80211.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/mac80211.c b/mac80211.c
-index fb0aea6..553d901 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -82,6 +82,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
- 	CHAN5G(165, 5825),
- 	CHAN5G(169, 5845),
- 	CHAN5G(173, 5865),
-+	CHAN5G(177, 5885),
- 
- 	CHAN5G(184, 4920),
- 	CHAN5G(188, 4940),
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/3000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch b/recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
similarity index 77%
rename from recipes-wifi/linux-mt76/files/patches/3000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
rename to recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
index cc09bac..e843ab7 100644
--- a/recipes-wifi/linux-mt76/files/patches/3000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch
@@ -1,19 +1,19 @@
-From 30912b07f4f8a8e3c6639c4d61326fe872ba8ce5 Mon Sep 17 00:00:00 2001
+From 3659e82e8fa99a3a5be9e22c9941ca20d035e1fe Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Fri, 25 Nov 2022 10:38:53 +0800
-Subject: [PATCH 3000/3012] wifi: mt76: mt7915: wed: add wed tx support
+Subject: [PATCH 2000/2009] wifi: mt76: mt7915: wed: add wed tx support
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
  mt76_connac.h   |  1 +
- mt7915/mac.c    | 11 +++++++----
+ mt7915/mac.c    | 10 +++++++---
  mt7915/main.c   |  4 ++--
  mt7915/mmio.c   |  5 +++--
  mt7915/mt7915.h |  2 +-
- 5 files changed, 14 insertions(+), 9 deletions(-)
+ 5 files changed, 14 insertions(+), 8 deletions(-)
 
 diff --git a/mt76_connac.h b/mt76_connac.h
-index ca26984..fc453e5 100644
+index 4560ab7..431e4d7 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -130,6 +130,7 @@ struct mt76_connac_sta_key_conf {
@@ -25,10 +25,10 @@
  struct mt76_connac_fw_txp {
  	__le16 flags;
 diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 1301b61..26b5e15 100644
+index f930c50..a0d1f89 100644
 --- a/mt7915/mac.c
 +++ b/mt7915/mac.c
-@@ -866,9 +866,9 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
+@@ -867,9 +867,9 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
  
  	txp->token = cpu_to_le16(token_id);
  	txp->nbuf = 1;
@@ -40,7 +40,7 @@
  }
  
  static void
-@@ -984,6 +984,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -918,6 +918,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  	LIST_HEAD(free_list);
  	void *end = data + len;
  	bool v3, wake = false;
@@ -48,17 +48,17 @@
  	u16 total, count = 0;
  	u32 txd = le32_to_cpu(free->txd);
  	__le32 *cur_info;
-@@ -1047,12 +1048,14 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
+@@ -999,12 +1000,15 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
  			txwi = mt76_token_release(mdev, msdu, &wake);
  			if (!txwi)
  				continue;
 +			else
 +				with_txwi = false;
  
- 			mt7915_txwi_free(dev, txwi, sta, &free_list);
+ 			mt76_connac2_txwi_free(mdev, txwi, sta, &free_list);
  		}
  	}
--
+ 
 -	mt7915_mac_tx_free_done(dev, &free_list, wake);
 +	if (!with_txwi)
 +		mt7915_mac_tx_free_done(dev, &free_list, wake);
@@ -66,10 +66,10 @@
  
  static void
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 8d1120c..59e879b 100644
+index 95b15a2..e0b1643 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1546,14 +1546,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1640,14 +1640,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	if (!mtk_wed_device_active(wed))
  		return -ENODEV;
  
@@ -87,7 +87,7 @@
  
  	ctx->dev = NULL;
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index d5198eb..3f4749b 100644
+index 25c3fe2..e5e005e 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
 @@ -13,7 +13,7 @@
@@ -99,16 +99,16 @@
  module_param(wed_enable, bool, 0644);
  MODULE_PARM_DESC(wed_enable, "Enable Wireless Ethernet Dispatch support");
  
-@@ -584,7 +584,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+@@ -569,7 +569,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
  	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
  
  	spin_lock_bh(&dev->mt76.token_lock);
 -	dev->mt76.token_size = MT7915_TOKEN_SIZE;
 +	dev->mt76.token_size = wed->wlan.token_start;//MT7915_TOKEN_SIZE
  	spin_unlock_bh(&dev->mt76.token_lock);
+ }
  
- 	/* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
-@@ -838,6 +838,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -812,6 +812,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  
  	*irq = wed->irq;
  	dev->mt76.dma_dev = wed->dev;
@@ -117,7 +117,7 @@
  	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
  	if (ret)
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 45a5254..d0ae42f 100644
+index b7fa1a4..f4e60b2 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -62,7 +62,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/3001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch b/recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches/3001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
rename to recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
index be9a604..e785db3 100644
--- a/recipes-wifi/linux-mt76/files/patches/3001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch
@@ -1,7 +1,7 @@
-From 7d1859d341a5c77b206b6b72c8a3d06dcef60042 Mon Sep 17 00:00:00 2001
+From 7727bc30f1fea1174cf1c6ea853a7092d4dae2c9 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Tue, 13 Dec 2022 17:51:26 +0800
-Subject: [PATCH 3001/3012] wifi: mt76: mt7915: wed: add wds support when wed
+Subject: [PATCH 2001/2009] wifi: mt76: mt7915: wed: add wds support when wed
  is enabled
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -15,10 +15,10 @@
  6 files changed, 82 insertions(+), 10 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index ea43716..3d36913 100644
+index 2f801de..e315fc1 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -60,6 +60,12 @@ enum mt76_wed_type {
+@@ -68,6 +68,12 @@ enum mt76_wed_type {
  	MT76_WED_Q_RX,
  };
  
@@ -32,10 +32,10 @@
  	u32 (*rr)(struct mt76_dev *dev, u32 offset);
  	void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 59e879b..13e797f 100644
+index e0b1643..c70b9d6 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -704,8 +704,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -730,8 +730,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  #endif
  	int ret, idx;
  	u32 addr;
@@ -52,7 +52,7 @@
  	if (idx < 0)
  		return -ENOSPC;
  
-@@ -1182,6 +1189,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
+@@ -1209,6 +1216,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,
  	else
  		clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);
  
@@ -66,7 +66,7 @@
  	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);
  }
  
-@@ -1553,8 +1567,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1647,8 +1661,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	path->dev = ctx->dev;
  	path->mtk_wdma.wdma_idx = wed->wdma_idx;
  	path->mtk_wdma.bss = mvif->mt76.idx;
@@ -81,10 +81,10 @@
  	ctx->dev = NULL;
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 13e5a54..e9bc4b1 100644
+index cf8d249..ca472c2 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -2346,10 +2346,18 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
+@@ -2385,10 +2385,18 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev)
  	if (ret)
  		return ret;
  
@@ -108,7 +108,7 @@
  	ret = mt7915_mcu_set_mwds(dev, 1);
  	if (ret)
 diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index 8ac70e5..c533a7d 100644
+index 7febe65..82b0847 100644
 --- a/mt7915/mcu.h
 +++ b/mt7915/mcu.h
 @@ -339,6 +339,7 @@ enum {
diff --git a/recipes-wifi/linux-mt76/files/patches/3002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch b/recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
similarity index 79%
rename from recipes-wifi/linux-mt76/files/patches/3002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
rename to recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
index a39c895..b9d24ec 100644
--- a/recipes-wifi/linux-mt76/files/patches/3002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch
@@ -1,7 +1,7 @@
-From 73eb4f4af78b3158592dfeb97e15196f471bf4c1 Mon Sep 17 00:00:00 2001
+From a8a74f9dbc766d0a517d1311d901e46c62dbc1c6 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Fri, 19 May 2023 07:05:22 +0800
-Subject: [PATCH 3002/3012] wifi: mt76: mt7915: wed: add fill receive path to 
+Subject: [PATCH 2002/2009] wifi: mt76: mt7915: wed: add fill receive path to
  report wed idx
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -10,10 +10,10 @@
  1 file changed, 18 insertions(+)
 
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 13e797f..275c6a0 100644
+index c70b9d6..97c90ec 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
-@@ -1579,6 +1579,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+@@ -1673,6 +1673,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
  	return 0;
  }
  
@@ -37,7 +37,7 @@
  static int
  mt7915_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  		    struct net_device *netdev, enum tc_setup_type type,
-@@ -1644,6 +1661,7 @@ const struct ieee80211_ops mt7915_ops = {
+@@ -1740,6 +1757,7 @@ const struct ieee80211_ops mt7915_ops = {
  	.set_radar_background = mt7915_set_radar_background,
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
  	.net_fill_forward_path = mt7915_net_fill_forward_path,
diff --git a/recipes-wifi/linux-mt76/files/patches/3003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch b/recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches/3003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
rename to recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
index fcfae5a..2b35208 100644
--- a/recipes-wifi/linux-mt76/files/patches/3003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
@@ -1,7 +1,7 @@
-From 354522be19efd1be1c35b765ebcc5d9ea11bd465 Mon Sep 17 00:00:00 2001
+From 457cb9380e3c1f875991bf551db68e638d4be95d Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Fri, 25 Nov 2022 14:32:35 +0800
-Subject: [PATCH 3003/3012] wifi: mt76: mt7915: wed: find rx token by physical
+Subject: [PATCH 2003/2009] wifi: mt76: mt7915: wed: find rx token by physical
  address
 
 The token id in RxDMAD may be incorrect when it is not the last frame due to
diff --git a/recipes-wifi/linux-mt76/files/patches/3004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch b/recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
similarity index 96%
rename from recipes-wifi/linux-mt76/files/patches/3004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
rename to recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
index a8a355e..c1fd5b0 100644
--- a/recipes-wifi/linux-mt76/files/patches/3004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch
@@ -1,7 +1,7 @@
-From 5f06d232336902dee12f67fad58ac6b637ef89ec Mon Sep 17 00:00:00 2001
+From 52823aad02634b30aa18c4e27d5e5df08b7d52e7 Mon Sep 17 00:00:00 2001
 From: Lian Chen <lian.chen@mediatek.com>
 Date: Mon, 7 Nov 2022 14:47:44 +0800
-Subject: [PATCH 3004/3012] wifi: mt76: mt7915: wed: HW ATF support for mt7986
+Subject: [PATCH 2004/2009] wifi: mt76: mt7915: wed: HW ATF support for mt7986
 
 Signed-off-by: Lian Chen <lian.chen@mediatek.com>
 ---
@@ -15,10 +15,10 @@
  7 files changed, 826 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 1fdbc1c..fd5aecb 100644
+index 8228bbb..1257dfa 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1161,6 +1161,7 @@ enum {
+@@ -1164,6 +1164,7 @@ enum {
  	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
  	MCU_EXT_CMD_WTBL_UPDATE = 0x32,
  	MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
@@ -26,7 +26,7 @@
  	MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
  	MCU_EXT_CMD_ATE_CTRL = 0x3d,
  	MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
-@@ -1170,6 +1171,7 @@ enum {
+@@ -1173,6 +1174,7 @@ enum {
  	MCU_EXT_CMD_MUAR_UPDATE = 0x48,
  	MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
  	MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
@@ -35,7 +35,7 @@
  	MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f,
  	MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index a122457..e44ac9a 100644
+index 99ce0a9..73e132b 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
 @@ -12,6 +12,10 @@
@@ -49,7 +49,7 @@
  /** global debugfs **/
  
  struct hw_queue_map {
-@@ -211,6 +215,406 @@ static const struct file_operations mt7915_sys_recovery_ops = {
+@@ -223,6 +227,406 @@ static const struct file_operations mt7915_sys_recovery_ops = {
  	.llseek = default_llseek,
  };
  
@@ -456,7 +456,7 @@
  static int
  mt7915_radar_trigger(void *data, u64 val)
  {
-@@ -1342,6 +1746,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
+@@ -1346,6 +1750,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
  	debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
  				    mt7915_twt_stats);
  	debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
@@ -465,10 +465,10 @@
  	if (!dev->dbdc_support || phy->mt76->band_idx) {
  		debugfs_create_u32("dfs_hw_pattern", 0400, dir,
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 8eacf34..8684d7a 100644
+index bc16f17..cf576ed 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -575,10 +575,46 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
+@@ -583,10 +583,46 @@ mt7915_init_led_mux(struct mt7915_dev *dev)
  	}
  }
  
@@ -515,7 +515,7 @@
  
  	/* config pse qid6 wfdma port selection */
  	if (!is_mt7915(&dev->mt76) && dev->hif2)
-@@ -600,6 +636,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
+@@ -610,6 +646,9 @@ void mt7915_mac_init(struct mt7915_dev *dev)
  		mt7915_mac_init_band(dev, i);
  
  	mt7915_init_led_mux(dev);
@@ -526,7 +526,7 @@
  
  int mt7915_txbf_init(struct mt7915_dev *dev)
 diff --git a/mt7915/main.c b/mt7915/main.c
-index 275c6a0..2ba36da 100644
+index 97c90ec..7b34162 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -217,6 +217,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
@@ -547,7 +547,7 @@
  	return ret;
  }
  
-@@ -699,6 +703,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -725,6 +729,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
  	bool ext_phy = mvif->phy != &dev->phy;
@@ -555,7 +555,7 @@
  #ifdef CONFIG_MTK_VENDOR
  	struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy;
  #endif
-@@ -749,6 +754,16 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+@@ -775,6 +780,16 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
  	if (phy->muru_onoff & MUMIMO_DL_CERT)
  		mt7915_mcu_set_mimo(phy, 0);
  #endif
@@ -573,10 +573,10 @@
  }
  
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index e9bc4b1..3b0ba5c 100644
+index ca472c2..7472825 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
-@@ -3507,6 +3507,171 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
+@@ -3547,6 +3547,171 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
  				 &req, sizeof(req), false);
  }
  
@@ -749,10 +749,10 @@
  {
  #define MT_BF_PROCESSING	4
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index d0ae42f..fddca24 100644
+index f4e60b2..0621684 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -134,6 +134,58 @@ struct mt7915_twt_flow {
+@@ -141,6 +141,58 @@ struct mt7915_twt_flow {
  
  DECLARE_EWMA(avg_signal, 10, 8)
  
@@ -811,7 +811,7 @@
  struct mt7915_sta {
  	struct mt76_wcid wcid; /* must be first */
  
-@@ -156,6 +208,7 @@ struct mt7915_sta {
+@@ -161,6 +213,7 @@ struct mt7915_sta {
  		u8 flowid_mask;
  		struct mt7915_twt_flow flow[MT7915_MAX_STA_TWT_AGRT];
  	} twt;
@@ -819,7 +819,7 @@
  };
  
  struct mt7915_vif {
-@@ -459,6 +512,8 @@ struct mt7915_dev {
+@@ -402,6 +455,8 @@ struct mt7915_dev {
  	} dbg;
  	const struct mt7915_dbg_reg_desc *dbg_reg;
  #endif
@@ -828,7 +828,7 @@
  };
  
  enum {
-@@ -491,6 +546,15 @@ enum mt7915_rdd_cmd {
+@@ -434,6 +489,15 @@ enum mt7915_rdd_cmd {
  	RDD_IRQ_OFF,
  };
  
@@ -844,7 +844,7 @@
  static inline struct mt7915_phy *
  mt7915_hw_phy(struct ieee80211_hw *hw)
  {
-@@ -620,6 +684,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
+@@ -564,6 +628,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
  int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
  			      u8 en);
  int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band);
@@ -856,7 +856,7 @@
  int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy);
  int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len,
 diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 4629f6b..361b50c 100644
+index 336f38e..3eeb921 100644
 --- a/mt7915/mtk_debugfs.c
 +++ b/mt7915/mtk_debugfs.c
 @@ -1368,7 +1368,6 @@ static EMPTY_QUEUE_INFO_T ple_txcmd_queue_empty_info[] = {
diff --git a/recipes-wifi/linux-mt76/files/patches/3005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch b/recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
similarity index 92%
rename from recipes-wifi/linux-mt76/files/patches/3005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
rename to recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
index dc542aa..6f2380f 100644
--- a/recipes-wifi/linux-mt76/files/patches/3005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch
@@ -1,7 +1,7 @@
-From dbd501e7d4570588f1bae9cd53177e83d3f5f81e Mon Sep 17 00:00:00 2001
+From 59b6df9977582f53ba8434189091a8a3c3012e20 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Fri, 6 Jan 2023 18:18:50 +0800
-Subject: [PATCH 3005/3012] wifi: mt76: mt7915: wed: add rxwi for further in
+Subject: [PATCH 2005/2009] wifi: mt76: mt7915: wed: add rxwi for further in
  chip rro
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
@@ -244,7 +244,7 @@
  unmap:
  	for (n--; n > 0; n--)
 diff --git a/mac80211.c b/mac80211.c
-index 553d901..4a0f333 100644
+index ddc13dd..52c552b 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -603,7 +603,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
@@ -255,7 +255,7 @@
  	mutex_init(&dev->mutex);
  	init_waitqueue_head(&dev->tx_wait);
  
-@@ -634,6 +633,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+@@ -636,6 +635,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
  	INIT_LIST_HEAD(&dev->txwi_cache);
  	INIT_LIST_HEAD(&dev->rxwi_cache);
  	dev->token_size = dev->drv->token_size;
@@ -264,10 +264,10 @@
  	for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
  		skb_queue_head_init(&dev->rx_skb[i]);
 diff --git a/mt76.h b/mt76.h
-index 3d36913..b178b95 100644
+index e315fc1..6c488bd 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -165,6 +165,7 @@ struct mt76_queue_entry {
+@@ -173,6 +173,7 @@ struct mt76_queue_entry {
  	};
  	union {
  		struct mt76_txwi_cache *txwi;
@@ -275,7 +275,7 @@
  		struct urb *urb;
  		int buf_sz;
  	};
-@@ -360,10 +361,15 @@ struct mt76_txwi_cache {
+@@ -371,10 +372,15 @@ struct mt76_txwi_cache {
  	struct list_head list;
  	dma_addr_t dma_addr;
  
@@ -295,7 +295,7 @@
  };
  
  struct mt76_rx_tid {
-@@ -449,6 +455,7 @@ struct mt76_driver_ops {
+@@ -460,6 +466,7 @@ struct mt76_driver_ops {
  	u16 txwi_size;
  	u16 token_size;
  	u8 mcs_rates;
@@ -303,7 +303,7 @@
  
  	void (*update_survey)(struct mt76_phy *phy);
  
-@@ -819,7 +826,6 @@ struct mt76_dev {
+@@ -833,7 +840,6 @@ struct mt76_dev {
  
  	struct ieee80211_hw *hw;
  
@@ -311,7 +311,7 @@
  	spinlock_t lock;
  	spinlock_t cc_lock;
  
-@@ -1411,8 +1417,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
+@@ -1523,8 +1529,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
  }
  
  void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
@@ -322,7 +322,7 @@
  void mt76_free_pending_rxwi(struct mt76_dev *dev);
  void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
  		      struct napi_struct *napi);
-@@ -1564,9 +1570,9 @@ struct mt76_txwi_cache *
+@@ -1676,9 +1682,9 @@ struct mt76_txwi_cache *
  mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
  int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
  void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
@@ -335,7 +335,7 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 4c8cf0c..3784b7b 100644
+index 59a44d7..326c8c8 100644
 --- a/mt7915/dma.c
 +++ b/mt7915/dma.c
 @@ -509,7 +509,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
@@ -355,10 +355,10 @@
  
  		/* rx data queue for band1 */
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 3f4749b..1c416bc 100644
+index e5e005e..4151af0 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -610,18 +610,18 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -584,18 +584,18 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  				sizeof(struct skb_shared_info));
  
  	for (i = 0; i < dev->mt76.rx_token_size; i++) {
@@ -384,7 +384,7 @@
  	}
  
  	mt76_free_pending_rxwi(&dev->mt76);
-@@ -639,18 +639,18 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -613,18 +613,18 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  				sizeof(struct skb_shared_info));
  
  	for (i = 0; i < size; i++) {
@@ -406,7 +406,7 @@
  			goto unmap;
  		}
  
-@@ -660,17 +660,17 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -634,17 +634,17 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  					  DMA_TO_DEVICE);
  		if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
  			__free_pages(page, get_order(length));
@@ -427,7 +427,7 @@
  			goto unmap;
  		}
  
-@@ -831,7 +831,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+@@ -805,7 +805,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
  	wed->wlan.reset = mt7915_mmio_wed_reset;
  	wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
  
@@ -436,7 +436,7 @@
  
  	if (mtk_wed_device_attach(wed))
  		return 0;
-@@ -1038,6 +1038,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
+@@ -1012,6 +1012,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
  				SURVEY_INFO_TIME_RX |
  				SURVEY_INFO_TIME_BSS_RX,
  		.token_size = MT7915_TOKEN_SIZE,
@@ -445,7 +445,7 @@
  		.tx_complete_skb = mt76_connac_tx_complete_skb,
  		.rx_skb = mt7915_queue_rx_skb,
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index fddca24..646f3e8 100644
+index 0621684..0153e5f 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
 @@ -64,6 +64,7 @@
@@ -457,10 +457,10 @@
  #define MT7915_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
  #define MT7915_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
 diff --git a/tx.c b/tx.c
-index 94f0d82..a87e361 100644
+index 5d7bf34..2594a62 100644
 --- a/tx.c
 +++ b/tx.c
-@@ -760,16 +760,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+@@ -774,16 +774,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
  EXPORT_SYMBOL_GPL(mt76_token_consume);
  
  int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
@@ -481,7 +481,7 @@
  	}
  	spin_unlock_bh(&dev->rx_token_lock);
  
-@@ -806,15 +806,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+@@ -820,15 +820,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
  }
  EXPORT_SYMBOL_GPL(mt76_token_release);
  
diff --git a/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch b/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
new file mode 100644
index 0000000..8f61926
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch
@@ -0,0 +1,295 @@
+From 3a498fb75b2f609a41019f844873496117b1fff6 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 11 Jan 2023 10:56:27 +0800
+Subject: [PATCH] wifi: mt76: add debugfs knob to show packet error rate
+
+Get tx count and tx failed from mcu command
+---
+ mt76.h               |   2 +
+ mt76_connac_mcu.h    |   1 +
+ mt7915/mcu.c         | 108 +++++++++++++++++++++++++++++++++++++++++++
+ mt7915/mcu.h         |  21 ++++++++-
+ mt7915/mt7915.h      |   1 +
+ mt7915/mtk_debugfs.c |  62 +++++++++++++++++++++++++
+ 6 files changed, 194 insertions(+), 1 deletion(-)
+
+diff --git a/mt76.h b/mt76.h
+index 6c488bd1..cbd63695 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -297,8 +297,10 @@ struct mt76_sta_stats {
+ 	u64 tx_bytes;
+ 	/* WED TX */
+ 	u32 tx_packets;		/* unit: MSDU */
++	u32 tx_mpdu_cnt;
+ 	u32 tx_retries;
+ 	u32 tx_failed;
++	u32 tx_failed_wm;
+ 	/* WED RX */
+ 	u64 rx_bytes;
+ 	u32 rx_packets;
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 1257dfa1..cfdee7c1 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1162,6 +1162,7 @@ enum {
+ 	MCU_EXT_CMD_EDCA_UPDATE = 0x27,
+ 	MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
+ 	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
++	MCU_EXT_CMD_GET_TX_STAT = 0x30,
+ 	MCU_EXT_CMD_WTBL_UPDATE = 0x32,
+ 	MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
+ 	MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 74728252..07a4b085 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -4214,6 +4214,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
+ 		return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
+ }
+ 
++static int mt7915_mcu_get_tx_stat_v1(struct mt7915_phy *phy,
++				     u16 wlan_idx)
++{
++#define to_wcid(hi, lo) (hi << 8 | lo)
++	struct mt7915_dev *dev = phy->dev;
++	struct mt76_phy *mphy = phy->mt76;
++	struct mt7915_mcu_tx_stat_v1 *res;
++	struct mt76_wcid *wcid;
++	struct sk_buff *skb;
++	struct {
++		__le32 category;
++		u8 wlan_idx_lo;
++		u8 band;
++		u8 wlan_idx_hi;
++		u8 __rsv[5];
++	} __packed req = {
++		.category = cpu_to_le32(MCU_GET_TX_STAT_CNT),
++		.band = mphy->band_idx,
++		.wlan_idx_lo = to_wcid_lo(wlan_idx),
++		.wlan_idx_hi = to_wcid_hi(wlan_idx),
++	};
++	int ret;
++
++	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
++					&req, sizeof(req), true, &skb);
++	if (ret)
++		return ret;
++
++	res = (struct mt7915_mcu_tx_stat_v1 *)skb->data;
++
++	if (to_wcid(res->wlan_idx_hi, res->wlan_idx_lo) != wlan_idx) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	rcu_read_lock();
++
++	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
++	if (wcid) {
++		wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
++		wcid->stats.tx_failed_wm += le32_to_cpu(res->tx_failed);
++	} else {
++		ret = -EINVAL;
++	}
++
++	rcu_read_unlock();
++out:
++	dev_kfree_skb(skb);
++
++	return ret;
++}
++
++static int mt7915_mcu_get_tx_stat_v2(struct mt7915_phy *phy,
++				     u16 wlan_idx)
++{
++	struct mt7915_dev *dev = phy->dev;
++	struct mt76_phy *mphy = phy->mt76;
++	struct mt7915_mcu_tx_stat_v2 *res;
++	struct mt76_wcid *wcid;
++	struct sk_buff *skb;
++	struct {
++		u8 category;
++		u8 band;
++		__le16 wcid;
++	} __packed req = {
++		.category = MCU_GET_TX_STAT_CNT,
++		.band = mphy->band_idx,
++		.wcid = cpu_to_le16(wlan_idx),
++	};
++	int ret;
++
++	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
++					&req, sizeof(req), true, &skb);
++	if (ret)
++		return ret;
++
++	res = (struct mt7915_mcu_tx_stat_v2 *)skb->data;
++
++	if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	rcu_read_lock();
++
++	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
++	if (wcid) {
++		wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
++		wcid->stats.tx_failed_wm += le32_to_cpu(res->tx_failed);
++	} else {
++		ret = -EINVAL;
++	}
++
++	rcu_read_unlock();
++out:
++	dev_kfree_skb(skb);
++
++	return ret;
++}
++
++int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx)
++{
++	if (is_mt7915(&phy->dev->mt76))
++		return mt7915_mcu_get_tx_stat_v1(phy, wlan_idx);
++
++	return mt7915_mcu_get_tx_stat_v2(phy, wlan_idx);
++}
++
+ int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ 				struct cfg80211_he_bss_color *he_bss_color)
+ {
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index 82b0847d..d6849797 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -790,7 +790,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
+ }
+ 
+ enum {
+-	MCU_GET_TX_RATE = 4
++	MCU_GET_TX_RATE = 4,
++	MCU_GET_TX_STAT_CNT = 8
+ };
+ 
+ #ifdef CONFIG_MTK_VENDOR
+@@ -1069,6 +1070,24 @@ struct mt7915_muru {
+ /* DL&UL User config */
+ #define MURU_USER_CNT                   BIT(4)
+ 
++struct mt7915_mcu_tx_stat_v1 {
++	u8 wlan_idx_lo;
++	u8 band_idx;
++	u8 wlan_idx_hi;
++	u8 __rsv1[29];
++	__le32 tx_cnt;
++	__le32 tx_failed;
++	u8 __rsv2[26];
++};
++
++struct mt7915_mcu_tx_stat_v2 {
++	u8 __rsv1[4];
++	__le16 wlan_idx;
++	u8 __rsv2[2];
++	__le32 tx_cnt;
++	__le32 tx_failed;
++};
++
+ enum {
+    CAPI_SU,
+    CAPI_MU,
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 0153e5fe..85c5c95c 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -661,6 +661,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
+ 				     struct cfg80211_chan_def *chandef);
+ int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
++int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx);
+ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
+diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
+index 3eeb921f..da33578c 100644
+--- a/mt7915/mtk_debugfs.c
++++ b/mt7915/mtk_debugfs.c
+@@ -3790,6 +3790,66 @@ mt7915_sw_aci_set(void *data, u64 val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_sw_aci, NULL,
+ 			 mt7915_sw_aci_set, "%llx\n");
+ 
++static int mt7915_reset_counter(void *data, u64 val)
++{
++	struct mt7915_phy *phy = data;
++	struct mt7915_dev *dev = phy->dev;
++	struct mt76_wcid *wcid;
++
++	/* Clear the firmware counters */
++	mt7915_mcu_wed_wa_tx_stats(dev, dev->wlan_idx);
++	mt7915_get_tx_stat(phy, dev->wlan_idx);
++
++	rcu_read_lock();
++	wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
++	if (!wcid)
++		return -EINVAL;
++
++	memset(&wcid->stats, 0, sizeof(struct mt76_sta_stats));
++
++	rcu_read_unlock();
++
++	return 0;
++}
++
++DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_counter, NULL,
++			 mt7915_reset_counter, "%lld\n");
++
++static int
++mt7915_per_read(struct seq_file *s, void *data)
++{
++	struct mt7915_dev *dev = dev_get_drvdata(s->private);
++	struct mt76_sta_stats *stats;
++	struct mt76_wcid *wcid;
++	int ret;
++	u8 phy_idx;
++
++	if (!dev->mt76.wcid[dev->wlan_idx])
++		return -EINVAL;
++
++	phy_idx = dev->mt76.wcid[dev->wlan_idx]->phy_idx;
++
++	ret = mt7915_get_tx_stat(dev->mt76.phys[phy_idx]->priv, dev->wlan_idx);
++	if (ret)
++		return ret;
++
++	rcu_read_lock();
++	wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
++	if (!wcid)
++		return -EINVAL;
++
++	stats = &wcid->stats;
++
++	seq_printf(s, "sta %d, tx_mpdu_cnt = %u, tx_failed = %u,  PER = %u.%u%%\n", dev->wlan_idx,
++		   stats->tx_mpdu_cnt, stats->tx_failed_wm,
++		   stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt / 10 : 0,
++		   stats->tx_mpdu_cnt ? stats->tx_failed_wm * 1000 / stats->tx_mpdu_cnt % 10 : 0);
++
++	rcu_read_unlock();
++
++	return 0;
++}
++
+ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
+@@ -3880,6 +3940,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
+ 				    mt7915_show_eeprom_mode);
+ 	debugfs_create_file("sw_aci", 0600, dir, dev,
+ 			    &fops_sw_aci);
++	debugfs_create_file("reset_counter", 0200, dir, dev, &fops_reset_counter);
++	debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
+ 	return 0;
+ }
+ #endif
+-- 
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches/3011-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch b/recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
similarity index 88%
rename from recipes-wifi/linux-mt76/files/patches/3011-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
rename to recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
index d62d58a..bc755ff 100644
--- a/recipes-wifi/linux-mt76/files/patches/3011-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2008-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch
@@ -1,7 +1,7 @@
-From 3ad0a83922b0778c06201d453f42b25e60c32fef Mon Sep 17 00:00:00 2001
+From 48b21966878b9b47925ce65008614d52117e2dba Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Thu, 6 Apr 2023 17:50:52 +0800
-Subject: [PATCH 3011/3012] wifi: mt76: mt7915: add ctxd support for mt7916
+Subject: [PATCH 2008/2009] wifi: mt76: mt7915: add ctxd support for mt7916
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  2 files changed, 35 insertions(+)
 
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 3784b7b..daa01fd 100644
+index 326c8c8..f71ec55 100644
 --- a/mt7915/dma.c
 +++ b/mt7915/dma.c
 @@ -433,6 +433,26 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
@@ -18,7 +18,7 @@
  				mt76_rmw(dev, MT_WFDMA0_EXT0_CFG, MT_WFDMA0_EXT0_RXWB_KEEP,
  					 MT_WFDMA0_EXT0_RXWB_KEEP);
 +			else {
-+				if (mt76_rr(dev, MT_CBTOP_RESV) & 0xff == 2) {
++				if ((mt76_rr(dev, MT_CBTOP_RESV) & 0xff) == 2) {
 +					mt76_set(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_DUMMY_REG);
 +					mt76_set(dev, MT_WFDMA0_CTXD_CFG, FIELD_PREP(MT_WFDMA0_CTXD_TIMEOUT, 0xa));
 +				} else {
@@ -41,10 +41,10 @@
  	} else {
  		mt76_clear(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED);
 diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 7955d01..2f32a00 100644
+index 44da7b8..bc963ac 100644
 --- a/mt7915/regs.h
 +++ b/mt7915/regs.h
-@@ -603,6 +603,7 @@ enum offs_rev {
+@@ -606,6 +606,7 @@ enum offs_rev {
  #define MT_WFDMA0_GLO_CFG		MT_WFDMA0(0x208)
  #define MT_WFDMA0_GLO_CFG_TX_DMA_EN	BIT(0)
  #define MT_WFDMA0_GLO_CFG_RX_DMA_EN	BIT(2)
@@ -52,7 +52,7 @@
  #define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO	BIT(28)
  #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO	BIT(27)
  #define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2	BIT(21)
-@@ -612,6 +613,17 @@ enum offs_rev {
+@@ -615,6 +616,17 @@ enum offs_rev {
  #define MT_WFDMA0_EXT0_CFG		MT_WFDMA0(0x2b0)
  #define MT_WFDMA0_EXT0_RXWB_KEEP	BIT(10)
  
@@ -70,7 +70,7 @@
  #define MT_WFDMA0_PRI_DLY_INT_CFG0	MT_WFDMA0(0x2f0)
  #define MT_WFDMA0_PRI_DLY_INT_CFG1	MT_WFDMA0(0x2f4)
  #define MT_WFDMA0_PRI_DLY_INT_CFG2	MT_WFDMA0(0x2f8)
-@@ -655,6 +667,8 @@ enum offs_rev {
+@@ -658,6 +670,8 @@ enum offs_rev {
  #define MT_WFDMA_WED_RING_CONTROL_TX1	GENMASK(12, 8)
  #define MT_WFDMA_WED_RING_CONTROL_RX1	GENMASK(20, 16)
  
@@ -79,7 +79,7 @@
  #define MT_WFDMA_EXT_CSR_HIF_MISC	MT_WFDMA_EXT_CSR_PHYS(0x44)
  #define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY	BIT(0)
  
-@@ -1183,6 +1197,7 @@ enum offs_rev {
+@@ -1186,6 +1200,7 @@ enum offs_rev {
  
  #define MT_HW_BOUND			0x70010020
  #define MT_HW_REV			0x70010204
diff --git a/recipes-wifi/linux-mt76/files/patches/3012-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch b/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
similarity index 95%
rename from recipes-wifi/linux-mt76/files/patches/3012-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
rename to recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
index 93b297d..95d4013 100644
--- a/recipes-wifi/linux-mt76/files/patches/3012-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
+++ b/recipes-wifi/linux-mt76/files/patches/2009-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch
@@ -1,7 +1,7 @@
-From c06020d2384a5d5cd773bdd8a1975ebe12cb1135 Mon Sep 17 00:00:00 2001
+From 70b5d2b88e048a9e24f4f509df5385d3246c7105 Mon Sep 17 00:00:00 2001
 From: Sujuan Chen <sujuan.chen@mediatek.com>
 Date: Thu, 5 Jan 2023 16:43:57 +0800
-Subject: [PATCH 3012/3012] wifi: mt76: connac: wed: add wed rx copy skb
+Subject: [PATCH 2009/2009] wifi: mt76: connac: wed: add wed rx copy skb
 
 Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
 ---
@@ -158,10 +158,10 @@
  
  static void
 diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index bbaaa33..4113ab2 100644
+index 4151af0..25893bd 100644
 --- a/mt7915/mmio.c
 +++ b/mt7915/mmio.c
-@@ -581,6 +581,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
+@@ -576,6 +576,7 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
  static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  {
  	struct mt7915_dev *dev;
@@ -169,7 +169,7 @@
  	u32 length;
  	int i;
  
-@@ -597,13 +598,33 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+@@ -592,13 +593,33 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
  
  		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
  				 wed->wlan.rx_size, DMA_FROM_DEVICE);
@@ -204,7 +204,7 @@
  }
  
  static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-@@ -620,35 +641,33 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -615,35 +636,33 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
  	for (i = 0; i < size; i++) {
  		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
  		dma_addr_t phy_addr;
diff --git a/recipes-wifi/linux-mt76/files/patches/3006-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch b/recipes-wifi/linux-mt76/files/patches/3006-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch
deleted file mode 100644
index 1b26803..0000000
--- a/recipes-wifi/linux-mt76/files/patches/3006-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch
+++ /dev/null
@@ -1,239 +0,0 @@
-From 13f5dc38354525add94b7c60ee289fd011ae5dbc Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 18 Jan 2023 16:37:22 +0800
-Subject: [PATCH 3006/3012] wifi: mt76: mt7915: add wa command to get tx msdu
- count
-
----
- mt76.h             |  2 +-
- mt76_connac2_mac.h |  1 +
- mt76_connac_mac.c  |  9 +++----
- mt76_connac_mcu.h  |  1 +
- mt7915/main.c      |  8 ++++---
- mt7915/mcu.c       | 58 ++++++++++++++++++++++++++++++++++++++++++----
- mt7915/mcu.h       | 11 +++++++++
- mt7915/mt7915.h    |  1 +
- 8 files changed, 79 insertions(+), 12 deletions(-)
-
-diff --git a/mt76.h b/mt76.h
-index b178b95..4794b6a 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -288,7 +288,7 @@ struct mt76_sta_stats {
- 	u64 tx_mcs[16];		/* mcs idx */
- 	u64 tx_bytes;
- 	/* WED TX */
--	u32 tx_packets;
-+	u32 tx_packets;		/* unit: MSDU */
- 	u32 tx_retries;
- 	u32 tx_failed;
- 	/* WED RX */
-diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
-index a5ec0f6..e7a4019 100644
---- a/mt76_connac2_mac.h
-+++ b/mt76_connac2_mac.h
-@@ -174,6 +174,7 @@ enum {
- 
- #define MT_TXS6_MPDU_FAIL_CNT		GENMASK(31, 23)
- 
-+#define MT_TXS7_MPDU_RETRY_BYTE		GENMASK(22, 0)
- #define MT_TXS7_MPDU_RETRY_CNT		GENMASK(31, 23)
- 
- /* RXD DW0 */
-diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index ee0fbfc..ee37fe5 100644
---- a/mt76_connac_mac.c
-+++ b/mt76_connac_mac.c
-@@ -523,7 +523,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
- 
- 		/* counting non-offloading skbs */
- 		wcid->stats.tx_bytes += skb->len;
--		wcid->stats.tx_packets++;
-+
-+		if (is_mt7915(dev))
-+			wcid->stats.tx_packets++;
- 	}
- 
- 	val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
-@@ -608,9 +610,8 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
- 	/* PPDU based reporting */
- 	if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
- 		stats->tx_bytes +=
--			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE);
--		stats->tx_packets +=
--			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
-+			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
-+			le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
- 		stats->tx_failed +=
- 			le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
- 		stats->tx_retries +=
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index fd5aecb..97d732a 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1000,6 +1000,7 @@ enum {
- 	MCU_EXT_EVENT_BF_STATUS_READ = 0x35,
- 	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
- 	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
-+	MCU_EXT_EVENT_WA_TX_STAT = 0x74,
- 	MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
- 	MCU_EXT_EVENT_MURU_CTRL = 0x9f,
- 	MCU_EXT_EVENT_CSI_REPORT = 0xc2,
-diff --git a/mt7915/main.c b/mt7915/main.c
-index 2ba36da..ccdb148 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -1116,9 +1116,6 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- 		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
- 
--		sinfo->tx_packets = msta->wcid.stats.tx_packets;
--		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
--
- 		sinfo->tx_failed = msta->wcid.stats.tx_failed;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
- 
-@@ -1134,6 +1131,11 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- 		}
- 	}
- 
-+	if (!mt7915_mcu_get_tx_stat_wa(phy->dev, msta->wcid.idx)) {
-+		sinfo->tx_packets = msta->wcid.stats.tx_packets;
-+		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
-+	}
-+
- 	sinfo->ack_signal = (s8)msta->ack_signal;
- 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
- 
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 3b0ba5c..c27b8f9 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -172,7 +172,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
- 	}
- 
- 	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
--	if (seq != rxd->seq)
-+
-+	if (seq != rxd->seq &&
-+	    !(rxd->eid == MCU_CMD_EXT_CID && rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
- 		return -EAGAIN;
- 
- 	if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
-@@ -424,13 +426,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
- 	struct mt76_connac2_mcu_rxd *rxd;
- 
- 	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
--	if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
-+	if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
- 	    rxd->ext_eid == MCU_EXT_EVENT_BF_STATUS_READ ||
--	    !rxd->seq)
-+	    !rxd->seq) &&
-+	    !(rxd->eid == MCU_CMD_EXT_CID && rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
- 		mt7915_mcu_rx_unsolicited_event(dev, skb);
- 	else
- 		mt76_mcu_rx_event(&dev->mt76, skb);
-@@ -4139,7 +4142,7 @@ int mt7915_mcu_get_tx_rate_v2(struct mt7915_phy *phy, u16 wcidx)
- 	};
- 
- 	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
--					&req, sizeof(req), true, &skb);
-+                                        &req, sizeof(req), true, &skb);
- 	if (ret)
- 		return ret;
- 
-@@ -4174,6 +4177,53 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx)
- 		return mt7915_mcu_get_tx_rate_v2(phy, wcidx);
- }
- 
-+int mt7915_mcu_get_tx_stat_wa(struct mt7915_dev *dev, u16 wlan_idx)
-+{
-+	struct {
-+		__le32 cmd;
-+		__le32 num;
-+		__le32 __rsv;
-+		__le16 wlan_idx;
-+	} req = {
-+		.cmd = cpu_to_le32(MCU_WA_QUERY_GET_TX_STAT),
-+		.num = cpu_to_le32(1),
-+		.wlan_idx = cpu_to_le16(wlan_idx),
-+	};
-+	struct mt7915_mcu_wa_tx_stat *res;
-+	struct mt76_wcid *wcid;
-+	struct sk_buff *skb;
-+	int ret;
-+
-+	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY),
-+					&req, sizeof(req), true, &skb);
-+	if (ret)
-+		return ret;
-+
-+	if (!is_mt7915(&dev->mt76))
-+		skb_pull(skb, 4);
-+
-+	res = (struct mt7915_mcu_wa_tx_stat *)skb->data;
-+
-+	if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
-+		ret = -EINVAL;
-+		goto out;
-+	}
-+
-+	rcu_read_lock();
-+
-+	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+	if (wcid)
-+		wcid->stats.tx_packets += le32_to_cpu(res->tx_msdu_cnt);
-+	else
-+		ret = -EINVAL;
-+
-+	rcu_read_unlock();
-+out:
-+	dev_kfree_skb(skb);
-+
-+	return ret;
-+}
-+
- int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- 				struct cfg80211_he_bss_color *he_bss_color)
- {
-diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index c533a7d..eca028b 100644
---- a/mt7915/mcu.h
-+++ b/mt7915/mcu.h
-@@ -347,6 +347,17 @@ enum {
- 	MCU_WA_PARAM_RED_SETTING = 0x40,
- };
- 
-+enum {
-+	MCU_WA_QUERY_GET_TX_STAT = 0x15,
-+};
-+
-+struct mt7915_mcu_wa_tx_stat {
-+	__le16 wlan_idx;
-+	u8 __rsv2[2];
-+	__le32 tx_bytes;
-+	__le32 tx_msdu_cnt;
-+};
-+
- enum mcu_mmps_mode {
- 	MCU_MMPS_STATIC,
- 	MCU_MMPS_DYNAMIC,
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 646f3e8..ef9b0e1 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -714,6 +714,7 @@ int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy);
- int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx);
- int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
- 			   struct ieee80211_sta *sta, struct rate_info *rate);
-+int mt7915_mcu_get_tx_stat_wa(struct mt7915_dev *dev, u16 wcid);
- int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
- 				     struct cfg80211_chan_def *chandef);
- int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/3007-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch b/recipes-wifi/linux-mt76/files/patches/3007-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch
deleted file mode 100644
index 9e29a40..0000000
--- a/recipes-wifi/linux-mt76/files/patches/3007-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch
+++ /dev/null
@@ -1,252 +0,0 @@
-From 7624f0f425a72927b29178227f92d9bb88d5202c Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 11 Jan 2023 10:56:27 +0800
-Subject: [PATCH 3007/3012] wifi: mt76: get tx count and tx failed from mcu
- command
-
----
- mt76.h            |   1 +
- mt76_connac_mac.c |   2 -
- mt76_connac_mcu.h |   1 +
- mt7915/main.c     |   8 ++--
- mt7915/mcu.c      | 108 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7915/mcu.h      |  21 ++++++++-
- mt7915/mt7915.h   |   1 +
- 7 files changed, 136 insertions(+), 6 deletions(-)
-
-diff --git a/mt76.h b/mt76.h
-index 4794b6a..e0bb41e 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -289,6 +289,7 @@ struct mt76_sta_stats {
- 	u64 tx_bytes;
- 	/* WED TX */
- 	u32 tx_packets;		/* unit: MSDU */
-+	u32 tx_mpdu_cnt;
- 	u32 tx_retries;
- 	u32 tx_failed;
- 	/* WED RX */
-diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index ee37fe5..6cd8c27 100644
---- a/mt76_connac_mac.c
-+++ b/mt76_connac_mac.c
-@@ -612,8 +612,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
- 		stats->tx_bytes +=
- 			le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
- 			le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
--		stats->tx_failed +=
--			le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
- 		stats->tx_retries +=
- 			le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_CNT);
- 
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 97d732a..b299a54 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1160,6 +1160,7 @@ enum {
- 	MCU_EXT_CMD_EDCA_UPDATE = 0x27,
- 	MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
- 	MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
-+	MCU_EXT_CMD_GET_TX_STAT = 0x30,
- 	MCU_EXT_CMD_WTBL_UPDATE = 0x32,
- 	MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
- 	MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38,
-diff --git a/mt7915/main.c b/mt7915/main.c
-index ccdb148..c377ef2 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -1116,9 +1116,6 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- 		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
- 
--		sinfo->tx_failed = msta->wcid.stats.tx_failed;
--		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
--
- 		sinfo->tx_retries = msta->wcid.stats.tx_retries;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
- 
-@@ -1136,6 +1133,11 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
- 	}
- 
-+	if (!mt7915_get_tx_stat(phy, msta->wcid.idx)) {
-+		sinfo->tx_failed = msta->wcid.stats.tx_failed;
-+		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
-+	}
-+
- 	sinfo->ack_signal = (s8)msta->ack_signal;
- 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
- 
-diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index c27b8f9..2c6dddc 100644
---- a/mt7915/mcu.c
-+++ b/mt7915/mcu.c
-@@ -4224,6 +4224,114 @@ out:
- 	return ret;
- }
- 
-+static int mt7915_mcu_get_tx_stat_v1(struct mt7915_phy *phy,
-+				     u16 wlan_idx)
-+{
-+#define to_wcid(hi, lo) (hi << 8 | lo)
-+	struct mt7915_dev *dev = phy->dev;
-+	struct mt76_phy *mphy = phy->mt76;
-+	struct mt7915_mcu_tx_stat_v1 *res;
-+	struct mt76_wcid *wcid;
-+	struct sk_buff *skb;
-+	struct {
-+		__le32 category;
-+		u8 wlan_idx_lo;
-+		u8 band;
-+		u8 wlan_idx_hi;
-+		u8 __rsv[5];
-+	} __packed req = {
-+		.category = cpu_to_le32(MCU_GET_TX_STAT_CNT),
-+		.band = mphy->band_idx,
-+		.wlan_idx_lo = to_wcid_lo(wlan_idx),
-+		.wlan_idx_hi = to_wcid_hi(wlan_idx),
-+	};
-+	int ret;
-+
-+	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
-+					&req, sizeof(req), true, &skb);
-+	if (ret)
-+		return ret;
-+
-+	res = (struct mt7915_mcu_tx_stat_v1 *)skb->data;
-+
-+	if (to_wcid(res->wlan_idx_hi, res->wlan_idx_lo) != wlan_idx) {
-+		ret = -EINVAL;
-+		goto out;
-+	}
-+
-+	rcu_read_lock();
-+
-+	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+	if (wcid) {
-+		wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
-+		wcid->stats.tx_failed += le32_to_cpu(res->tx_failed);
-+	} else {
-+		ret = -EINVAL;
-+	}
-+
-+	rcu_read_unlock();
-+out:
-+	dev_kfree_skb(skb);
-+
-+	return ret;
-+}
-+
-+static int mt7915_mcu_get_tx_stat_v2(struct mt7915_phy *phy,
-+				     u16 wlan_idx)
-+{
-+	struct mt7915_dev *dev = phy->dev;
-+	struct mt76_phy *mphy = phy->mt76;
-+	struct mt7915_mcu_tx_stat_v2 *res;
-+	struct mt76_wcid *wcid;
-+	struct sk_buff *skb;
-+	struct {
-+		u8 category;
-+		u8 band;
-+		__le16 wcid;
-+	} __packed req = {
-+		.category = MCU_GET_TX_STAT_CNT,
-+		.band = mphy->band_idx,
-+		.wcid = cpu_to_le16(wlan_idx),
-+	};
-+	int ret;
-+
-+	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(GET_TX_STAT),
-+					&req, sizeof(req), true, &skb);
-+	if (ret)
-+		return ret;
-+
-+	res = (struct mt7915_mcu_tx_stat_v2 *)skb->data;
-+
-+	if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
-+		ret = -EINVAL;
-+		goto out;
-+	}
-+
-+	rcu_read_lock();
-+
-+	wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
-+	if (wcid) {
-+		wcid->stats.tx_mpdu_cnt += le32_to_cpu(res->tx_cnt);
-+		wcid->stats.tx_failed += le32_to_cpu(res->tx_failed);
-+	} else {
-+		ret = -EINVAL;
-+	}
-+
-+	rcu_read_unlock();
-+out:
-+	dev_kfree_skb(skb);
-+
-+	return ret;
-+}
-+
-+int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx)
-+{
-+	if (is_mt7915(&phy->dev->mt76))
-+		return mt7915_mcu_get_tx_stat_v1(phy, wlan_idx);
-+
-+	return mt7915_mcu_get_tx_stat_v2(phy, wlan_idx);
-+}
-+
- int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- 				struct cfg80211_he_bss_color *he_bss_color)
- {
-diff --git a/mt7915/mcu.h b/mt7915/mcu.h
-index eca028b..c712dbb 100644
---- a/mt7915/mcu.h
-+++ b/mt7915/mcu.h
-@@ -797,7 +797,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower)
- }
- 
- enum {
--	MCU_GET_TX_RATE = 4
-+	MCU_GET_TX_RATE = 4,
-+	MCU_GET_TX_STAT_CNT = 8
- };
- 
- #ifdef CONFIG_MTK_VENDOR
-@@ -1076,6 +1077,24 @@ struct mt7915_muru {
- /* DL&UL User config */
- #define MURU_USER_CNT                   BIT(4)
- 
-+struct mt7915_mcu_tx_stat_v1 {
-+	u8 wlan_idx_lo;
-+	u8 band_idx;
-+	u8 wlan_idx_hi;
-+	u8 __rsv1[29];
-+	__le32 tx_cnt;
-+	__le32 tx_failed;
-+	u8 __rsv2[26];
-+};
-+
-+struct mt7915_mcu_tx_stat_v2 {
-+	u8 __rsv1[4];
-+	__le16 wlan_idx;
-+	u8 __rsv2[2];
-+	__le32 tx_cnt;
-+	__le32 tx_failed;
-+};
-+
- enum {
-    CAPI_SU,
-    CAPI_MU,
-diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index ef9b0e1..52cf748 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -715,6 +715,7 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx);
- int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
- 			   struct ieee80211_sta *sta, struct rate_info *rate);
- int mt7915_mcu_get_tx_stat_wa(struct mt7915_dev *dev, u16 wcid);
-+int mt7915_get_tx_stat(struct mt7915_phy *phy, u16 wlan_idx);
- int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
- 				     struct cfg80211_chan_def *chandef);
- int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/3008-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch b/recipes-wifi/linux-mt76/files/patches/3008-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch
deleted file mode 100644
index 63744a8..0000000
--- a/recipes-wifi/linux-mt76/files/patches/3008-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 475282f29cf4364626cf6146d78da23640ea7dfd Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Wed, 18 Jan 2023 11:50:38 +0800
-Subject: [PATCH 3008/3012] wifi: mt76: mt7915: enable PPDU-TxS to host when
- wed enable
-
-Calculate tx bytes and tx retries from PPDU-TxS
----
- mt76_connac_mac.c |  2 --
- mt7915/init.c     |  6 ++++++
- mt7915/mmio.c     | 21 ---------------------
- tx.c              | 21 +++++++++++++++++++++
- 4 files changed, 27 insertions(+), 23 deletions(-)
-
-diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
-index 6cd8c27..8b77e93 100644
---- a/mt76_connac_mac.c
-+++ b/mt76_connac_mac.c
-@@ -522,8 +522,6 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
- 			mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
- 
- 		/* counting non-offloading skbs */
--		wcid->stats.tx_bytes += skb->len;
--
- 		if (is_mt7915(dev))
- 			wcid->stats.tx_packets++;
- 	}
-diff --git a/mt7915/init.c b/mt7915/init.c
-index 8684d7a..9036f44 100644
---- a/mt7915/init.c
-+++ b/mt7915/init.c
-@@ -507,6 +507,12 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
- 	set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |
- 	      FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);
- 	mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);
-+
-+	/* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
-+	 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
-+	 */
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H);
- }
- 
- static void
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 1c416bc..bbaaa33 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -551,7 +551,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
- static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
- {
- 	struct mt7915_dev *dev;
--	struct mt7915_phy *phy;
- 	int ret;
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-@@ -565,38 +564,18 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
- 	if (!ret)
- 		return -EAGAIN;
- 
--	phy = &dev->phy;
--	mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
--
--	phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
--	if (phy)
--		mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx),
--			 MT_AGG_ACR_PPDU_TXS2H);
--
- 	return 0;
- }
- 
- static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
- {
- 	struct mt7915_dev *dev;
--	struct mt7915_phy *phy;
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- 
- 	spin_lock_bh(&dev->mt76.token_lock);
- 	dev->mt76.token_size = wed->wlan.token_start;//MT7915_TOKEN_SIZE
- 	spin_unlock_bh(&dev->mt76.token_lock);
--
--	/* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than
--	 * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set.
--	 */
--	phy = &dev->phy;
--	mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H);
--
--	phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL;
--	if (phy)
--		mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx),
--			   MT_AGG_ACR_PPDU_TXS2H);
- }
- 
- static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-diff --git a/tx.c b/tx.c
-index a87e361..335ddb5 100644
---- a/tx.c
-+++ b/tx.c
-@@ -122,6 +122,7 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
- 		       struct sk_buff *skb)
- {
- 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- 	struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
- 	int pid;
- 
-@@ -133,6 +134,11 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
- 	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- 		return MT_PACKET_ID_NO_ACK;
- 
-+	if (mtk_wed_device_active(&dev->mmio.wed) &&
-+	    ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) ||
-+	    ieee80211_is_data(hdr->frame_control)))
-+		return MT_PACKET_ID_WED;
-+
- 	if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
- 			     IEEE80211_TX_CTL_RATE_CTRL_PROBE)))
- 		return MT_PACKET_ID_NO_SKB;
-@@ -262,8 +268,23 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
- #endif
- 
- 	if (cb->pktid < MT_PACKET_ID_FIRST) {
-+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+		struct ieee80211_rate_status rs = {};
-+
- 		hw = mt76_tx_status_get_hw(dev, skb);
- 		status.sta = wcid_to_sta(wcid);
-+		if (mtk_wed_device_active(&dev->mmio.wed) &&
-+		    (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
-+			info->status.rates[0].idx = -1;
-+
-+			if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
-+				rs.rate_idx = wcid->rate;
-+				status.rates = &rs;
-+				status.n_rates = 1;
-+			} else {
-+				status.n_rates = 0;
-+			}
-+		}
- 		spin_lock_bh(&dev->rx_lock);
- 		ieee80211_tx_status_ext(hw, &status);
- 		spin_unlock_bh(&dev->rx_lock);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/3009-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch b/recipes-wifi/linux-mt76/files/patches/3009-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch
deleted file mode 100644
index e4e0343..0000000
--- a/recipes-wifi/linux-mt76/files/patches/3009-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 7fad725b238b5b94403b9c4457aa0c3c0acdd576 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Tue, 17 Jan 2023 21:15:00 +0800
-Subject: [PATCH 3009/3012] wifi: mt76: mt7915: get tx retries from tx free
- done event for sw path
-
----
- mt76_connac2_mac.h |  2 ++
- mt7915/mac.c       | 14 +++++++++++---
- mt7915/mac.h       |  3 ++-
- mt7915/main.c      |  6 +++---
- 4 files changed, 18 insertions(+), 7 deletions(-)
-
-diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h
-index e7a4019..e6170ea 100644
---- a/mt76_connac2_mac.h
-+++ b/mt76_connac2_mac.h
-@@ -38,6 +38,8 @@ enum {
- /* 0: success, others: dropped */
- #define MT_TX_FREE_STATUS		GENMASK(14, 13)
- #define MT_TX_FREE_MSDU_ID		GENMASK(30, 16)
-+#define MT_TX_FREE_TX_COUNT		GENMASK(12, 0)
-+#define MT_TX_FREE_TX_COUNT_V3		GENMASK(27, 24)
- #define MT_TX_FREE_PAIR			BIT(31)
- /* will support this field in further revision */
- #define MT_TX_FREE_RATE			GENMASK(13, 0)
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 26b5e15..0994ce1 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -981,6 +981,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- 	struct mt76_dev *mdev = &dev->mt76;
- 	struct mt76_txwi_cache *txwi;
- 	struct ieee80211_sta *sta = NULL;
-+	struct mt76_wcid *wcid = NULL;
- 	LIST_HEAD(free_list);
- 	void *end = data + len;
- 	bool v3, wake = false;
-@@ -995,7 +996,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- 	v3 = (FIELD_GET(MT_TX_FREE_VER, txd) == 0x4);
- 
- 	for (cur_info = tx_info; count < total; cur_info++) {
--		u32 msdu, info;
-+		u32 msdu, info, retries = 0;
- 		u8 i;
- 
- 		if (WARN_ON_ONCE((void *)cur_info >= end))
-@@ -1008,7 +1009,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- 		info = le32_to_cpu(*cur_info);
- 		if (info & MT_TX_FREE_PAIR) {
- 			struct mt7915_sta *msta;
--			struct mt76_wcid *wcid = NULL;
- 			struct mt7915_phy *phy;
- 			u16 idx;
- 
-@@ -1033,7 +1033,15 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
- 			continue;
- 		}
- 
--		if (v3 && (info & MT_TX_FREE_MPDU_HEADER))
-+		if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
-+			retries = u32_get_bits(info, MT_TX_FREE_TX_COUNT_V3) - 1;
-+		else if (!v3 && (info & MT_TX_FREE_MPDU_HEADER))
-+			retries = u32_get_bits(info, MT_TX_FREE_TX_COUNT) - 1;
-+
-+		if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid)
-+			wcid->stats.tx_retries += retries;
-+
-+		if (v3 && (info & MT_TX_FREE_MPDU_HEADER_V3))
- 			continue;
- 
- 		for (i = 0; i < 1 + v3; i++) {
-diff --git a/mt7915/mac.h b/mt7915/mac.h
-index ce94f87..859298d 100644
---- a/mt7915/mac.h
-+++ b/mt7915/mac.h
-@@ -9,7 +9,8 @@
- #define MT_TX_FREE_VER			GENMASK(18, 16)
- #define MT_TX_FREE_MSDU_CNT_V0		GENMASK(6, 0)
- /* 0: success, others: dropped */
--#define MT_TX_FREE_MPDU_HEADER		BIT(30)
-+#define MT_TX_FREE_MPDU_HEADER		BIT(15)
-+#define MT_TX_FREE_MPDU_HEADER_V3	BIT(30)
- #define MT_TX_FREE_MSDU_ID_V3		GENMASK(14, 0)
- 
- #define MT_TXS5_F0_FINAL_MPDU		BIT(31)
-diff --git a/mt7915/main.c b/mt7915/main.c
-index c377ef2..f836aa8 100644
---- a/mt7915/main.c
-+++ b/mt7915/main.c
-@@ -1116,9 +1116,6 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- 		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
- 
--		sinfo->tx_retries = msta->wcid.stats.tx_retries;
--		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
--
- 		if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {
- 			sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
- 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
-@@ -1128,6 +1125,9 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
- 		}
- 	}
- 
-+	sinfo->tx_retries = msta->wcid.stats.tx_retries;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
-+
- 	if (!mt7915_mcu_get_tx_stat_wa(phy->dev, msta->wcid.idx)) {
- 		sinfo->tx_packets = msta->wcid.stats.tx_packets;
- 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/3010-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch b/recipes-wifi/linux-mt76/files/patches/3010-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch
deleted file mode 100644
index 3142884..0000000
--- a/recipes-wifi/linux-mt76/files/patches/3010-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 629de725ea7db82076de9c1d23e84b24c64dc64b Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Mon, 30 Jan 2023 11:36:32 +0800
-Subject: [PATCH 3010/3012] wifi: mt76: update debugfs knob for reset counter
- and get tx packet error rate
-
----
- mt7915/mtk_debugfs.c | 62 ++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 62 insertions(+)
-
-diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c
-index 361b50c..f896e53 100644
---- a/mt7915/mtk_debugfs.c
-+++ b/mt7915/mtk_debugfs.c
-@@ -3790,6 +3790,66 @@ mt7915_sw_aci_set(void *data, u64 val)
- DEFINE_DEBUGFS_ATTRIBUTE(fops_sw_aci, NULL,
- 			 mt7915_sw_aci_set, "%llx\n");
- 
-+static int mt7915_reset_counter(void *data, u64 val)
-+{
-+	struct mt7915_phy *phy = data;
-+	struct mt7915_dev *dev = phy->dev;
-+	struct mt76_wcid *wcid;
-+
-+	/* Clear the firmware counters */
-+	mt7915_mcu_get_tx_stat_wa(dev, dev->wlan_idx);
-+	mt7915_get_tx_stat(phy, dev->wlan_idx);
-+
-+	rcu_read_lock();
-+	wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
-+	if (!wcid)
-+		return -EINVAL;
-+
-+	memset(&wcid->stats, 0, sizeof(struct mt76_sta_stats));
-+
-+	rcu_read_unlock();
-+
-+	return 0;
-+}
-+
-+DEFINE_DEBUGFS_ATTRIBUTE(fops_reset_counter, NULL,
-+			 mt7915_reset_counter, "%lld\n");
-+
-+static int
-+mt7915_per_read(struct seq_file *s, void *data)
-+{
-+	struct mt7915_dev *dev = dev_get_drvdata(s->private);
-+	struct mt76_sta_stats *stats;
-+	struct mt76_wcid *wcid;
-+	int ret;
-+	u8 phy_idx;
-+
-+	if (!dev->mt76.wcid[dev->wlan_idx])
-+		return -EINVAL;
-+
-+	phy_idx = dev->mt76.wcid[dev->wlan_idx]->phy_idx;
-+
-+	ret = mt7915_get_tx_stat(dev->mt76.phys[phy_idx]->priv, dev->wlan_idx);
-+	if (ret)
-+		return ret;
-+
-+	rcu_read_lock();
-+	wcid = rcu_dereference(dev->mt76.wcid[dev->wlan_idx]);
-+	if (!wcid)
-+		return -EINVAL;
-+
-+	stats = &wcid->stats;
-+
-+	seq_printf(s, "sta %d, tx_mpdu_cnt = %u, tx_failed = %u,  PER = %u.%u%%\n", dev->wlan_idx,
-+		   stats->tx_mpdu_cnt, stats->tx_failed,
-+		   stats->tx_mpdu_cnt ? stats->tx_failed * 1000 / stats->tx_mpdu_cnt / 10 : 0,
-+		   stats->tx_mpdu_cnt ? stats->tx_failed * 1000 / stats->tx_mpdu_cnt % 10 : 0);
-+
-+	rcu_read_unlock();
-+
-+	return 0;
-+}
-+
- int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
- {
- 	struct mt7915_dev *dev = phy->dev;
-@@ -3881,6 +3941,8 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir)
- 				    mt7915_show_eeprom_mode);
- 	debugfs_create_file("sw_aci", 0600, dir, dev,
- 			    &fops_sw_aci);
-+	debugfs_create_file("reset_counter", 0200, dir, dev, &fops_reset_counter);
-+	debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read);
- 	return 0;
- }
- #endif
--- 
-2.18.0
-
diff --git a/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch b/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch
index a22d9b3..2cf9c0d 100644
--- a/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch
+++ b/recipes-wifi/linux-mt76/files/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch
@@ -1,4 +1,4 @@
-From db40f94c0f681cb7f36efcee47997a9755c63325 Mon Sep 17 00:00:00 2001
+From f433ab08414bf574d03a362ef997918cd98e696e Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 5 Apr 2023 08:29:19 +0800
 Subject: [PATCH] mt76: revert for backports-5.15 wireless stack
@@ -10,18 +10,19 @@
  mt7615/dma.c      |   4 +-
  mt7615/main.c     |   6 +-
  mt7615/mcu.c      |   8 +-
+ mt76_connac_mac.c |   2 +-
  mt76_connac_mcu.c | 108 +++++++++---------
  mt76x02_mac.c     |   6 +-
  mt7915/debugfs.c  |   4 +-
  mt7915/dma.c      |   4 +-
  mt7915/init.c     |   3 +-
- mt7915/mac.c      |   2 +-
- mt7915/main.c     |  11 +-
+ mt7915/main.c     |  17 ++-
  mt7915/mcu.c      | 273 ++++++++++++++++++++++++++++++----------------
+ mt7915/mmio.c     |   2 +-
  mt7915/mt7915.h   |  14 +++
  mt7915/testmode.c |   8 +-
- tx.c              |  26 ++---
- 16 files changed, 282 insertions(+), 201 deletions(-)
+ tx.c              |  22 ++--
+ 17 files changed, 286 insertions(+), 201 deletions(-)
 
 diff --git a/dma.c b/dma.c
 index 4daa64d..220e684 100644
@@ -37,10 +38,10 @@
  		napi_enable(&dev->napi[i]);
  	}
 diff --git a/mac80211.c b/mac80211.c
-index 4a0f333..b3058e0 100644
+index 52c552b..b5cee8c 100644
 --- a/mac80211.c
 +++ b/mac80211.c
-@@ -1519,7 +1519,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
+@@ -1521,7 +1521,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power);
  static void
  __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
@@ -49,7 +50,7 @@
  		ieee80211_csa_finish(vif);
  }
  
-@@ -1541,7 +1541,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
+@@ -1543,7 +1543,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif)
  {
  	struct mt76_dev *dev = priv;
  
@@ -74,7 +75,7 @@
  
  	mt76_poll(dev, MT_WPDMA_GLO_CFG,
 diff --git a/mt7615/main.c b/mt7615/main.c
-index dadb13f..2c61c36 100644
+index 200b175..53f30a0 100644
 --- a/mt7615/main.c
 +++ b/mt7615/main.c
 @@ -473,7 +473,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
@@ -86,7 +87,7 @@
  	       const struct ieee80211_tx_queue_params *params)
  {
  	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
-@@ -555,7 +555,7 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
+@@ -581,7 +581,7 @@ mt7615_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
  				    struct ieee80211_vif *vif,
  				    struct ieee80211_bss_conf *info,
@@ -95,15 +96,15 @@
  {
  	struct mt7615_dev *dev = mt7615_hw_dev(hw);
  	struct mt7615_phy *phy = mt7615_hw_phy(hw);
-@@ -598,7 +598,7 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
+@@ -624,7 +624,7 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
  	}
  
  	if (changed & BSS_CHANGED_ASSOC)
 -		mt7615_mac_set_beacon_filter(phy, vif, vif->cfg.assoc);
 +		mt7615_mac_set_beacon_filter(phy, vif, info->assoc);
  
- 	mt7615_mutex_release(dev);
- }
+ 	if (changed & BSS_CHANGED_MU_GROUPS)
+ 		 mt7615_update_mu_group(hw, vif, info);
 diff --git a/mt7615/mcu.c b/mt7615/mcu.c
 index 86061e9..a79308b 100644
 --- a/mt7615/mcu.c
@@ -144,8 +145,21 @@
  		.dtim_period = vif->bss_conf.dtim_period,
  		.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
  	};
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index 5edf912..44c5221 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -1118,7 +1118,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+ 	u32 val;
+ 
+ 	if (!sta ||
+-	    !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
++	    !(sta->ht_cap.ht_supported || sta->he_cap.has_he))
+ 		return;
+ 
+ 	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index d228312..665de18 100644
+index e6b468c..220c133 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -197,7 +197,7 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
@@ -435,7 +449,7 @@
  				flags |= MT_WTBL_W5_SHORT_GI_160;
  		}
  		raw = (struct wtbl_raw *)tlv;
-@@ -1294,9 +1294,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1297,9 +1297,9 @@ u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  		return 0x38;
  
  	if (sta) {
@@ -448,7 +462,7 @@
  	} else {
  		struct ieee80211_supported_band *sband;
  
-@@ -1616,7 +1616,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
+@@ -1619,7 +1619,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
  	for (i = 0; i < sreq->n_ssids; i++) {
  		if (!sreq->ssids[i].ssid_len)
  			continue;
@@ -456,7 +470,7 @@
  		req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
  		memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
  		       sreq->ssids[i].ssid_len);
-@@ -1756,7 +1755,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
+@@ -1759,7 +1758,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
  		memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
  		req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
  	}
@@ -464,7 +478,7 @@
  	req->match_num = sreq->n_match_sets;
  	for (i = 0; i < req->match_num; i++) {
  		match = &sreq->match_sets[i];
-@@ -2243,10 +2241,8 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
+@@ -2246,10 +2244,8 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
  				      struct mt76_vif *vif,
  				      struct ieee80211_bss_conf *info)
  {
@@ -476,7 +490,7 @@
  			   IEEE80211_BSS_ARP_ADDR_LIST_LEN);
  	struct {
  		struct {
-@@ -2274,7 +2270,7 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
+@@ -2277,7 +2273,7 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
  
  	skb_put_data(skb, &req_hdr, sizeof(req_hdr));
  	for (i = 0; i < len; i++)
@@ -511,10 +525,10 @@
  		if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
  			ba_size = 0;
 diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
-index e44ac9a..e841d1e 100644
+index 73e132b..5345ff7 100644
 --- a/mt7915/debugfs.c
 +++ b/mt7915/debugfs.c
-@@ -1911,8 +1911,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file,
+@@ -1915,8 +1915,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file,
  
  	phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0);
  	for (i = 0; i <= phy.bw; i++) {
@@ -526,7 +540,7 @@
  	field = RATE_PARAM_FIXED;
  
 diff --git a/mt7915/dma.c b/mt7915/dma.c
-index daa01fd..5b8426a 100644
+index f71ec55..b4e231b 100644
 --- a/mt7915/dma.c
 +++ b/mt7915/dma.c
 @@ -590,8 +590,8 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
@@ -541,10 +555,10 @@
  
  	mt7915_dma_enable(dev, false);
 diff --git a/mt7915/init.c b/mt7915/init.c
-index 9036f44..f5d5adb 100644
+index cf576ed..ad5f788 100644
 --- a/mt7915/init.c
 +++ b/mt7915/init.c
-@@ -1145,8 +1145,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
+@@ -1140,8 +1140,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
  			mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss);
  		} else {
  			he_cap_elem->phy_cap_info[9] |=
@@ -554,21 +568,8 @@
  		}
  
  		if (band == NL80211_BAND_6GHZ) {
-diff --git a/mt7915/mac.c b/mt7915/mac.c
-index 0994ce1..e9156af 100644
---- a/mt7915/mac.c
-+++ b/mt7915/mac.c
-@@ -878,7 +878,7 @@ mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
- 	u16 fc, tid;
- 	u32 val;
- 
--	if (!sta || !(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))
-+	if (!sta || !(sta->ht_cap.ht_supported || sta->he_cap.has_he))
- 		return;
- 
- 	tid = le32_get_bits(txwi[1], MT_TXD1_TID);
 diff --git a/mt7915/main.c b/mt7915/main.c
-index f836aa8..653dffe 100644
+index 5db7e6a..d90bdaf 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -273,6 +273,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e
@@ -606,10 +607,30 @@
  
  	if (changed & BSS_CHANGED_ERP_CTS_PROT)
  		mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
-@@ -1240,10 +1241,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,
+@@ -680,8 +681,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ }
+ 
+ static int
+-mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		struct ieee80211_bss_conf *link_conf)
++mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
  {
  	struct mt7915_phy *phy = mt7915_hw_phy(hw);
  	struct mt7915_dev *dev = mt7915_hw_dev(hw);
+@@ -700,8 +700,7 @@ out:
+ }
+ 
+ static void
+-mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-	       struct ieee80211_bss_conf *link_conf)
++mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+ {
+ 	struct mt7915_dev *dev = mt7915_hw_dev(hw);
+ 
+@@ -1265,10 +1264,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,
+ {
+ 	struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ 	struct mt7915_dev *dev = mt7915_hw_dev(hw);
 -	s16 txpower = sta->deflink.txpwr.power;
 +	s16 txpower = sta->txpwr.power;
  	int ret;
@@ -620,7 +641,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 2c6dddc..94c3215 100644
+index 26d2964..cf80d77 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -67,7 +67,7 @@ mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs,
@@ -692,7 +713,7 @@
  		return;
  
  	ieee80211_color_change_finish(vif);
-@@ -750,13 +750,14 @@ static void
+@@ -751,13 +751,14 @@ static void
  mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  		      struct ieee80211_vif *vif)
  {
@@ -709,7 +730,7 @@
  		return;
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
-@@ -783,7 +784,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -784,7 +785,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  	     IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
  		cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
  
@@ -718,7 +739,7 @@
  	    (elem->phy_cap_info[1] &
  	     IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD))
  		cap |= STA_REC_HE_CAP_LDPC;
-@@ -842,8 +843,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+@@ -843,8 +844,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  
  	he->he_cap = cpu_to_le32(cap);
  
@@ -729,7 +750,7 @@
  	case IEEE80211_STA_RX_BW_160:
  		if (elem->phy_cap_info[0] &
  		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
-@@ -892,8 +893,9 @@ static void
+@@ -893,8 +894,9 @@ static void
  mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  			struct ieee80211_sta *sta, struct ieee80211_vif *vif)
  {
@@ -740,7 +761,7 @@
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
  
-@@ -905,9 +907,9 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -906,9 +908,9 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  
  	muru = (struct sta_rec_muru *)tlv;
  
@@ -753,7 +774,7 @@
  			       !!(phy->muru_onoff & MUMIMO_DL);
  	if (!is_mt7915(&dev->mt76))
  		muru->cfg.mimo_ul_en = true;
-@@ -917,11 +919,11 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -918,11 +920,11 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	muru->cfg.ofdma_dl_en = !!(phy->muru_onoff & OFDMA_DL);
  	muru->cfg.ofdma_ul_en = !!(phy->muru_onoff & OFDMA_UL);
  
@@ -768,7 +789,7 @@
  		return;
  
  	muru->mimo_dl.partial_bw_dl_mimo =
-@@ -955,13 +957,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -956,13 +958,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  	struct sta_rec_ht *ht;
  	struct tlv *tlv;
  
@@ -784,7 +805,7 @@
  }
  
  static void
-@@ -970,15 +972,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -971,15 +973,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  	struct sta_rec_vht *vht;
  	struct tlv *tlv;
  
@@ -804,7 +825,7 @@
  }
  
  static void
-@@ -993,7 +995,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -994,7 +996,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	    vif->type != NL80211_IFTYPE_AP)
  		return;
  
@@ -813,7 +834,7 @@
  	    return;
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
-@@ -1002,7 +1004,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1003,7 +1005,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	amsdu->amsdu_en = true;
  	msta->wcid.amsdu = true;
  
@@ -822,7 +843,7 @@
  	case IEEE80211_MAX_MPDU_LEN_VHT_11454:
  		if (!is_mt7915(&dev->mt76)) {
  			amsdu->max_mpdu_size =
-@@ -1045,8 +1047,8 @@ mt7915_mcu_sta_wtbl_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1046,8 +1048,8 @@ mt7915_mcu_sta_wtbl_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, tlv, wtbl_hdr);
  	if (sta)
  		mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, skb, sta, tlv,
@@ -833,7 +854,7 @@
  
  	return 0;
  }
-@@ -1055,6 +1057,7 @@ static inline bool
+@@ -1056,6 +1058,7 @@ static inline bool
  mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  			struct ieee80211_sta *sta, bool bfee)
  {
@@ -841,7 +862,7 @@
  	int sts = hweight16(phy->mt76->chainmask);
  
  	if (vif->type != NL80211_IFTYPE_STATION &&
-@@ -1064,25 +1067,25 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+@@ -1065,25 +1068,25 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
  	if (!bfee && sts < 2)
  		return false;
  
@@ -875,7 +896,7 @@
  			       (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
  	}
  
-@@ -1102,7 +1105,7 @@ static void
+@@ -1103,7 +1106,7 @@ static void
  mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
  		       struct sta_rec_bf *bf)
  {
@@ -884,7 +905,7 @@
  	u8 n = 0;
  
  	bf->tx_mode = MT_PHY_TYPE_HT;
-@@ -1127,7 +1130,7 @@ static void
+@@ -1128,7 +1131,7 @@ static void
  mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
  			struct sta_rec_bf *bf, bool explicit)
  {
@@ -893,7 +914,7 @@
  	struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap;
  	u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);
  	u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
-@@ -1148,14 +1151,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
+@@ -1149,14 +1152,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
  		bf->ncol = min_t(u8, nss_mcs, bf->nrow);
  		bf->ibf_ncol = bf->ncol;
  
@@ -910,7 +931,7 @@
  			bf->ibf_nrow = 1;
  	}
  }
-@@ -1164,7 +1167,7 @@ static void
+@@ -1165,7 +1168,7 @@ static void
  mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
  		       struct mt7915_phy *phy, struct sta_rec_bf *bf)
  {
@@ -919,7 +940,7 @@
  	struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
  	const struct ieee80211_sta_he_cap *vc =
  		mt76_connac_get_he_phy_cap(phy->mt76, vif);
-@@ -1189,7 +1192,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
+@@ -1190,7 +1193,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
  	bf->ncol = min_t(u8, nss_mcs, bf->nrow);
  	bf->ibf_ncol = bf->ncol;
  
@@ -928,7 +949,7 @@
  		return;
  
  	/* go over for 160MHz and 80p80 */
-@@ -1237,7 +1240,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1238,7 +1241,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	};
  	bool ebf;
  
@@ -937,7 +958,7 @@
  		return;
  
  	ebf = mt7915_is_ebf_supported(phy, vif, sta, false);
-@@ -1251,21 +1254,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1252,21 +1255,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	 * vht: support eBF and iBF
  	 * ht: iBF only, since mac80211 lacks of eBF support
  	 */
@@ -965,7 +986,7 @@
  		bf->ibf_timeout = 0x48;
  	else
  		bf->ibf_timeout = 0x18;
-@@ -1275,7 +1278,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1276,7 +1279,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	else
  		bf->mem_20m = matrix[bf->nrow][bf->ncol];
  
@@ -974,7 +995,7 @@
  	case IEEE80211_STA_RX_BW_160:
  	case IEEE80211_STA_RX_BW_80:
  		bf->mem_total = bf->mem_20m * 2;
-@@ -1300,7 +1303,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1301,7 +1304,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	struct tlv *tlv;
  	u8 nrow = 0;
  
@@ -983,7 +1004,7 @@
  		return;
  
  	if (!mt7915_is_ebf_supported(phy, vif, sta, true))
-@@ -1309,13 +1312,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
+@@ -1310,13 +1313,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee));
  	bfee = (struct sta_rec_bfee *)tlv;
  
@@ -1001,7 +1022,7 @@
  
  		nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
  				 pc->cap);
-@@ -1371,7 +1374,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
+@@ -1372,7 +1375,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
  			ra->phy = *phy;
  		break;
  	case RATE_PARAM_MMPS_UPDATE:
@@ -1010,7 +1031,7 @@
  		break;
  	case RATE_PARAM_SPE_UPDATE:
  		ra->spe_idx = *(u8 *)data;
-@@ -1446,7 +1449,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+@@ -1447,7 +1450,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
  	do {									\
  		u8 i, gi = mask->control[band]._gi;				\
  		gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI;		\
@@ -1019,7 +1040,7 @@
  			phy.sgi |= gi << (i << (_he));				\
  			phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\
  		}								\
-@@ -1460,11 +1463,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+@@ -1461,11 +1464,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
  		}								\
  	} while (0)
  
@@ -1034,7 +1055,7 @@
  		__sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);
  	} else {
  		nrates = hweight32(mask->control[band].legacy);
-@@ -1498,7 +1501,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+@@ -1499,7 +1502,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
  		 * actual txrate hardware sends out.
  		 */
  		addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7);
@@ -1043,7 +1064,7 @@
  			mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);
  		else
  			mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);
-@@ -1531,7 +1534,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1532,7 +1535,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  	enum nl80211_band band = chandef->chan->band;
  	struct sta_rec_ra *ra;
  	struct tlv *tlv;
@@ -1052,7 +1073,7 @@
  	u32 cap = sta->wme ? STA_CAP_WMM : 0;
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra));
-@@ -1541,9 +1544,9 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1542,9 +1545,9 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  	ra->auto_rate = true;
  	ra->phy_mode = mt76_connac_get_phy_mode(mphy, vif, band, sta);
  	ra->channel = chandef->chan->hw_value;
@@ -1065,7 +1086,7 @@
  
  	if (supp_rate) {
  		supp_rate &= mask->control[band].legacy;
-@@ -1563,22 +1566,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1564,22 +1567,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  		}
  	}
  
@@ -1097,7 +1118,7 @@
  			cap |= STA_CAP_LDPC;
  
  		mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs,
-@@ -1586,37 +1589,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
+@@ -1587,37 +1590,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
  		ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs;
  	}
  
@@ -1146,7 +1167,7 @@
  					       IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
  	}
  
-@@ -1825,7 +1828,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
+@@ -1826,7 +1829,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
  	if (!offs->cntdwn_counter_offs[0])
  		return;
  
@@ -1155,7 +1176,7 @@
  	tlv = mt7915_mcu_add_nested_subtlv(rskb, sub_tag, sizeof(*info),
  					   &bcn->sub_ntlv, &bcn->len);
  	info = (struct bss_info_bcn_cntdwn *)tlv;
-@@ -1910,9 +1913,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1911,9 +1914,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	if (offs->cntdwn_counter_offs[0]) {
  		u16 offset = offs->cntdwn_counter_offs[0];
  
@@ -1167,7 +1188,7 @@
  			cont->bcc_ofs = cpu_to_le16(offset - 3);
  	}
  
-@@ -1922,6 +1925,85 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -1923,6 +1926,85 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
  }
  
@@ -1253,7 +1274,7 @@
  int
  mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
  			     u32 changed)
-@@ -2033,7 +2115,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -2034,7 +2116,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	if (!en)
  		goto out;
  
@@ -1262,7 +1283,7 @@
  	if (!skb)
  		return -EINVAL;
  
-@@ -2046,6 +2128,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -2047,6 +2129,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  	info = IEEE80211_SKB_CB(skb);
  	info->hw_queue = FIELD_PREP(MT_TX_HW_QUEUE_PHY, ext_phy);
  
@@ -1270,7 +1291,7 @@
  	mt7915_mcu_beacon_cntdwn(vif, rskb, skb, bcn, &offs);
  	mt7915_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);
  	mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
-@@ -3283,17 +3366,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
+@@ -3320,17 +3403,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy,
  	if (txpower) {
  		u32 offs, len, i;
  
@@ -1291,11 +1312,24 @@
  					offs += len + sku_len[SKU_HE_RU26] * 3;
  					len = sku_len[SKU_HE_RU242] * 4;
  				}
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 25893bd..2d849d5 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -651,7 +651,7 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 		phy_addr = dma_map_single(dev->mt76.dma_dev, ptr,
+ 					  wed->wlan.rx_size,
+ 					  DMA_TO_DEVICE);
+-		
++
+ 		if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
+ 			skb_free_frag(ptr);
+ 			mt76_put_rxwi(&dev->mt76, r);
 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
-index 52cf748..fcd10b3 100644
+index 85c5c95..04fc539 100644
 --- a/mt7915/mt7915.h
 +++ b/mt7915/mt7915.h
-@@ -212,9 +212,23 @@ struct mt7915_sta {
+@@ -217,9 +217,23 @@ struct mt7915_sta {
  	struct mt7915_vow_sta_cfg vow_sta_cfg;
  };
  
@@ -1320,10 +1354,10 @@
  	struct mt7915_phy *phy;
  
 diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index b99bed5..8b9813b 100644
+index fafe909..b10dec5 100644
 --- a/mt7915/testmode.c
 +++ b/mt7915/testmode.c
-@@ -397,12 +397,12 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
+@@ -416,12 +416,12 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid)
  		memcpy(sta->addr, td->addr[0], ETH_ALEN);
  
  	if (td->tx_rate_mode >= MT76_TM_TX_MODE_HT)
@@ -1341,7 +1375,7 @@
  	sta->wme = 1;
  
 diff --git a/tx.c b/tx.c
-index 335ddb5..445469e 100644
+index 2594a62..26fa665 100644
 --- a/tx.c
 +++ b/tx.c
 @@ -60,20 +60,15 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
@@ -1368,7 +1402,7 @@
  		}
  
  		hw = mt76_tx_status_get_hw(dev, skb);
-@@ -238,6 +233,7 @@ mt76_tx_check_non_aql(struct mt76_dev *dev, struct mt76_wcid *wcid,
+@@ -239,6 +234,7 @@ mt76_tx_check_non_aql(struct mt76_dev *dev, struct mt76_wcid *wcid,
  void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *skb,
  			    struct list_head *free_list)
  {
@@ -1376,31 +1410,26 @@
  	struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
  	struct ieee80211_tx_status status = {
  		.skb = skb,
-@@ -268,21 +264,13 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
+@@ -269,15 +265,13 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
  #endif
  
  	if (cb->pktid < MT_PACKET_ID_FIRST) {
--		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 -		struct ieee80211_rate_status rs = {};
 -
  		hw = mt76_tx_status_get_hw(dev, skb);
  		status.sta = wcid_to_sta(wcid);
- 		if (mtk_wed_device_active(&dev->mmio.wed) &&
- 		    (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
--			info->status.rates[0].idx = -1;
--
--			if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
--				rs.rate_idx = wcid->rate;
--				status.rates = &rs;
--				status.n_rates = 1;
--			} else {
--				status.n_rates = 0;
-+			if (status.sta) {
-+				info->status.rates[0].idx = -1;
-+				status.rate = &wcid->rate;
- 			}
+-		if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
+-			rs.rate_idx = wcid->rate;
+-			status.rates = &rs;
+-			status.n_rates = 1;
++		if (status.sta) {
++			info->status.rates[0].idx = -1;
++			status.rate = &wcid->rate;
  		}
++
  		spin_lock_bh(&dev->rx_lock);
+ 		ieee80211_tx_status_ext(hw, &status);
+ 		spin_unlock_bh(&dev->rx_lock);
 -- 
 2.18.0
 
diff --git a/recipes-wifi/linux-mt76/files/patches/patches.inc b/recipes-wifi/linux-mt76/files/patches/patches.inc
index 17dddd2..78fc3e8 100644
--- a/recipes-wifi/linux-mt76/files/patches/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches/patches.inc
@@ -1,61 +1,54 @@
 #patch patches (come from openwrt/lede/target/linux/mediatek)
 SRC_URI_append = " \
-    file://0001-wifi-mt76-mt7915-fix-background-radar-event-being-bl.patch \
-    file://0002-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch \
-    file://0003-wifi-mt76-mt7915-disable-wfdma-tx-rx-during-SER-reco.patch \
-    file://0004-wifi-mt76-mt7915-fix-the-beamformer-issue.patch \
-    file://0005-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch \
-    file://0006-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch \
-    file://0007-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch \
-    file://0008-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch \
-    file://0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch \
-    file://1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch \
-    file://1001-wifi-mt76-mt7915-csi-implement-csi-support.patch \
-    file://1002-wifi-mt76-mt7915-air-monitor-support.patch \
-    file://1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch \
-    file://1004-wifi-mt76-mt7915-certification-patches.patch \
-    file://1005-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch \
-    file://1006-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch \
-    file://1007-wifi-mt76-mt7915-drop-undefined-action-frame.patch \
-    file://1009-wifi-mt76-testmode-rework-testmode-init-registers.patch \
-    file://1010-wifi-mt76-testmode-additional-supports.patch \
-    file://1011-wifi-mt76-testmode-add-pre-cal-support.patch \
-    file://1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch \
-    file://1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch \
-    file://1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch \
-    file://1015-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch \
-    file://1016-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch \
-    file://1017-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch \
-    file://1018-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch \
-    file://1019-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch \
-    file://1020-wifi-mt76-mt7915-implement-bin-file-mode.patch \
-    file://1021-wifi-mt76-mt7915-initialize-wcid.patch \
-    file://1022-wifi-mt76-mt7915-Add-mu-dump-support.patch \
-    file://1023-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch \
-    file://1024-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch \
-    file://1025-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch \
-    file://1026-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch \
-    file://1027-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch \
-    file://1028-wifi-mt76-mt7915-amsdu-set-and-get-control.patch \
-    file://1029-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch \
-    file://1030-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch \
-    file://1031-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch \
-    file://1032-wifi-mt76-mt7915-Add-5G-UNII4-support.patch \
-    file://1033-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch \
-    file://1034-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch \
-    file://1035-wifi-mt76-mt7915-remove-BW160-support.patch \
-    file://3000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch \
-    file://3001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch \
-    file://3002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch \
-    file://3003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch \
-    file://3004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch \
-    file://3005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch \
-    file://3006-wifi-mt76-mt7915-add-wa-command-to-get-tx-msdu-count.patch \
-    file://3007-wifi-mt76-get-tx-count-and-tx-failed-from-mcu-comman.patch \
-    file://3008-wifi-mt76-mt7915-enable-PPDU-TxS-to-host-when-wed-en.patch \
-    file://3009-wifi-mt76-mt7915-get-tx-retries-from-tx-free-done-ev.patch \
-    file://3010-wifi-mt76-update-debugfs-knob-for-reset-counter-and-.patch \
-    file://3011-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch \
-    file://3012-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch \
+    file://0000-sync-to-master-codebase.patch \
+    file://0001-wifi-mt76-mt7915-Update-beacon-size-limitation-for-1.patch \
+    file://0002-wifi-mt76-mt7915-fix-the-beamformer-issue.patch \
+    file://0003-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch \
+    file://0004-wifi-mt76-mt7915-fix-DFS-CAC-tx-emission-issue-after.patch \
+    file://0005-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch \
+    file://0006-wifi-mt76-mt7915-update-mpdu-density-in-2-5g-capabil.patch \
+    file://0007-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch \
+    file://0999-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch \
+    file://1000-wifi-mt76-mt7915-csi-implement-csi-support.patch \
+    file://1001-wifi-mt76-mt7915-air-monitor-support.patch \
+    file://1002-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch \
+    file://1003-wifi-mt76-mt7915-certification-patches.patch \
+    file://1004-wifi-mt76-mt7915-add-support-for-runtime-set-in-band.patch \
+    file://1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch \
+    file://1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch \
+    file://1007-wifi-mt76-testmode-rework-testmode-init-registers.patch \
+    file://1008-wifi-mt76-testmode-additional-supports.patch \
+    file://1009-wifi-mt76-testmode-add-pre-cal-support.patch \
+    file://1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch \
+    file://1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch \
+    file://1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch \
+    file://1013-wifi-mt76-mt7915-init-rssi-in-WTBL-when-add-station.patch \
+    file://1014-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch \
+    file://1015-wifi-mt76-mt7915-add-mt7986-and-mt7916-pre-calibrati.patch \
+    file://1016-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch \
+    file://1017-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch \
+    file://1018-wifi-mt76-mt7915-implement-bin-file-mode.patch \
+    file://1019-wifi-mt76-mt7915-Add-mu-dump-support.patch \
+    file://1020-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch \
+    file://1021-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch \
+    file://1022-wifi-mt76-mt7915-add-E3-re-bonding-for-low-yield-rat.patch \
+    file://1023-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch \
+    file://1024-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch \
+    file://1025-wifi-mt76-mt7915-amsdu-set-and-get-control.patch \
+    file://1026-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch \
+    file://1027-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch \
+    file://1028-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch \
+    file://1029-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch \
+    file://1030-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch \
+    file://1031-wifi-mt76-mt7915-remove-BW160-support.patch \
+    file://2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch \
+    file://2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch \
+    file://2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch \
+    file://2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch \
+    file://2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch \
+    file://2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch \
+    file://2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch \
+    file://2008-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch \
+    file://2009-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch \
     file://9999-mt76-revert-for-backports-5.15-wireless-stack.patch \
     "