[][MAC80211][wifi7][Misc][Sync Internal patches to External Release Folder]

[Description]
Add 20231011 MT7996 firmware and sync patches to External Release Folder

[Release-log]
N/A

Change-Id: I8971c21f494c3947f2ac7f19b8c398488356ca59
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/8101977
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
index fdaa90b..bef1050 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0001-Revert-wifi-mt76-mt7996-fill-txd-by-host-driver.patch
@@ -1,7 +1,7 @@
-From fd4524824058ee584f62e5762935f012679d85b8 Mon Sep 17 00:00:00 2001
+From 455955959ceaabf80454570c2dfaa3128d524791 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 19 Sep 2023 11:21:23 +0800
-Subject: [PATCH 01/22] Revert "wifi: mt76: mt7996: fill txd by host driver"
+Subject: [PATCH 01/98] Revert "wifi: mt76: mt7996: fill txd by host driver"
 
 This reverts commit 325a0c4931990d553487024c4f76c776492bdcc2.
 ---
@@ -9,7 +9,7 @@
  1 file changed, 9 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index c43839a20..1a1e21872 100644
+index c43839a..1a1e218 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
 @@ -967,8 +967,11 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
@@ -40,5 +40,5 @@
  	if (!key)
  		txp->fw.flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0002-wifi-mt76-wed-sync-to-wed-upstream.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0002-wifi-mt76-wed-sync-to-wed-upstream.patch
new file mode 100644
index 0000000..25dfc5d
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0002-wifi-mt76-wed-sync-to-wed-upstream.patch
@@ -0,0 +1,2740 @@
+From 4709ca02ba0332508ac6885acbc779bdfac3f0be Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Fri, 6 Oct 2023 21:20:25 +0800
+Subject: [PATCH] wifi: mt76: wed: sync to wed upstream
+
+---
+ dma.c             | 219 +++++++++++++++++++++++++++------------
+ dma.h             |  12 +++
+ mac80211.c        |  19 +++-
+ mmio.c            |  97 +++++++++++++++++
+ mt76.h            | 102 ++++++++++++++++--
+ mt7603/dma.c      |   9 +-
+ mt7615/dma.c      |   6 +-
+ mt76_connac.h     |   3 +-
+ mt76_connac_mac.c |   5 +-
+ mt76x02_mmio.c    |   5 +-
+ mt7915/dma.c      |  18 ++--
+ mt7915/main.c     |  16 +--
+ mt7915/mmio.c     | 107 +------------------
+ mt7921/pci.c      |   2 +-
+ mt7925/pci.c      |   2 +-
+ mt7996/dma.c      | 258 ++++++++++++++++++++++++++++++++++++++++++----
+ mt7996/init.c     | 156 ++++++++++++++++++++++++++--
+ mt7996/mac.c      |  72 +++++++++++--
+ mt7996/main.c     |  42 ++++++++
+ mt7996/mcu.c      |  13 ++-
+ mt7996/mmio.c     | 208 +++++++++++++++++++++++++++++++++----
+ mt7996/mt7996.h   |  67 +++++++++++-
+ mt7996/pci.c      |  72 ++++++++++---
+ mt7996/regs.h     |  65 +++++++++++-
+ 24 files changed, 1276 insertions(+), 299 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 643e18e..dd20271 100644
+--- a/dma.c
++++ b/dma.c
+@@ -9,11 +9,11 @@
+ 
+ #if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
+ 
+-#define Q_READ(_dev, _q, _field) ({					\
++#define Q_READ(_q, _field) ({						\
+ 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
+ 	u32 _val;							\
+ 	if ((_q)->flags & MT_QFLAG_WED)					\
+-		_val = mtk_wed_device_reg_read(&(_dev)->mmio.wed,	\
++		_val = mtk_wed_device_reg_read((_q)->wed,		\
+ 					       ((_q)->wed_regs +	\
+ 					        _offset));		\
+ 	else								\
+@@ -21,10 +21,10 @@
+ 	_val;								\
+ })
+ 
+-#define Q_WRITE(_dev, _q, _field, _val)	do {				\
++#define Q_WRITE(_q, _field, _val)	do {				\
+ 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
+ 	if ((_q)->flags & MT_QFLAG_WED)					\
+-		mtk_wed_device_reg_write(&(_dev)->mmio.wed,		\
++		mtk_wed_device_reg_write((_q)->wed,			\
+ 					 ((_q)->wed_regs + _offset),	\
+ 					 _val);				\
+ 	else								\
+@@ -33,8 +33,8 @@
+ 
+ #else
+ 
+-#define Q_READ(_dev, _q, _field)	readl(&(_q)->regs->_field)
+-#define Q_WRITE(_dev, _q, _field, _val)	writel(_val, &(_q)->regs->_field)
++#define Q_READ(_q, _field)		readl(&(_q)->regs->_field)
++#define Q_WRITE(_q, _field, _val)	writel(_val, &(_q)->regs->_field)
+ 
+ #endif
+ 
+@@ -188,40 +188,63 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
+ static void
+ mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
+ {
+-	Q_WRITE(dev, q, desc_base, q->desc_dma);
+-	Q_WRITE(dev, q, ring_size, q->ndesc);
+-	q->head = Q_READ(dev, q, dma_idx);
++	Q_WRITE(q, desc_base, q->desc_dma);
++	if (q->flags & MT_QFLAG_WED_RRO_EN)
++		Q_WRITE(q, ring_size, MT_DMA_RRO_EN | q->ndesc);
++	else
++		Q_WRITE(q, ring_size, q->ndesc);
++	q->head = Q_READ(q, dma_idx);
+ 	q->tail = q->head;
+ }
+ 
+ static void
+-mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
++__mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
++		       bool reset_idx)
+ {
+-	int i;
+-
+ 	if (!q || !q->ndesc)
+ 		return;
+ 
+-	/* clear descriptors */
+-	for (i = 0; i < q->ndesc; i++)
+-		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
++	if (!mt76_queue_is_wed_rro_ind(q)) {
++		int i;
+ 
+-	Q_WRITE(dev, q, cpu_idx, 0);
+-	Q_WRITE(dev, q, dma_idx, 0);
++		/* clear descriptors */
++		for (i = 0; i < q->ndesc; i++)
++			q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
++	}
++
++	if (reset_idx) {
++		Q_WRITE(q, cpu_idx, 0);
++		Q_WRITE(q, dma_idx, 0);
++	}
+ 	mt76_dma_sync_idx(dev, q);
+ }
+ 
++static void
++mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
++{
++	__mt76_dma_queue_reset(dev, q, true);
++}
++
+ static int
+ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ 		    struct mt76_queue_buf *buf, void *data)
+ {
+-	struct mt76_desc *desc = &q->desc[q->head];
+ 	struct mt76_queue_entry *entry = &q->entry[q->head];
+ 	struct mt76_txwi_cache *txwi = NULL;
++	struct mt76_desc *desc;
+ 	u32 buf1 = 0, ctrl;
+ 	int idx = q->head;
+ 	int rx_token;
+ 
++	if (mt76_queue_is_wed_rro_ind(q)) {
++		struct mt76_wed_rro_desc *rro_desc;
++
++		rro_desc = (struct mt76_wed_rro_desc *)q->desc;
++		data = &rro_desc[q->head];
++		goto done;
++	}
++
++	desc = &q->desc[q->head];
+ 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+ 
+ 	if (mt76_queue_is_wed_rx(q)) {
+@@ -244,6 +267,7 @@ 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);
+ 
++done:
+ 	entry->dma_addr[0] = buf->addr;
+ 	entry->dma_len[0] = buf->len;
+ 	entry->txwi = txwi;
+@@ -343,7 +367,7 @@ static void
+ mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
+ {
+ 	wmb();
+-	Q_WRITE(dev, q, cpu_idx, q->head);
++	Q_WRITE(q, cpu_idx, q->head);
+ }
+ 
+ static void
+@@ -359,7 +383,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+ 	if (flush)
+ 		last = -1;
+ 	else
+-		last = Q_READ(dev, q, dma_idx);
++		last = Q_READ(q, dma_idx);
+ 
+ 	while (q->queued > 0 && q->tail != last) {
+ 		mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
+@@ -371,7 +395,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+ 		}
+ 
+ 		if (!flush && q->tail == last)
+-			last = Q_READ(dev, q, dma_idx);
++			last = Q_READ(q, dma_idx);
+ 	}
+ 	spin_unlock_bh(&q->cleanup_lock);
+ 
+@@ -392,10 +416,14 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ {
+ 	struct mt76_queue_entry *e = &q->entry[idx];
+ 	struct mt76_desc *desc = &q->desc[idx];
+-	void *buf;
++	void *buf = e->buf;
++	u32 ctrl;
+ 
++	if (mt76_queue_is_wed_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);
+ 	}
+@@ -403,6 +431,12 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 	if (info)
+ 		*info = le32_to_cpu(desc->info);
+ 
++	if (drop) {
++		*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
++		if (ctrl & MT_DMA_CTL_VER_MASK)
++			*drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
++	}
++
+ 	if (mt76_queue_is_wed_rx(q)) {
+ 		u32 buf1 = le32_to_cpu(desc->buf1);
+ 		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
+@@ -420,23 +454,16 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		t->ptr = NULL;
+ 
+ 		mt76_put_rxwi(dev, t);
+-
+-		if (drop) {
+-			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+-
+-			*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
+-					   MT_DMA_CTL_DROP));
+-
++		if (drop)
+ 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
+-		}
+ 	} else {
+-		buf = e->buf;
+-		e->buf = NULL;
+ 		dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
+ 				SKB_WITH_OVERHEAD(q->buf_size),
+ 				page_pool_get_dma_dir(q->page_pool));
+ 	}
+ 
++done:
++	e->buf = NULL;
+ 	return buf;
+ }
+ 
+@@ -450,11 +477,16 @@ 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)))
++	if (mt76_queue_is_wed_rro_data(q))
+ 		return NULL;
+ 
++	if (!mt76_queue_is_wed_rro_ind(q)) {
++		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;
++	}
++
+ 	q->tail = (q->tail + 1) % q->ndesc;
+ 	q->queued--;
+ 
+@@ -606,11 +638,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+ 	spin_lock_bh(&q->lock);
+ 
+ 	while (q->queued < q->ndesc - 1) {
++		struct mt76_queue_buf qbuf = {};
+ 		enum dma_data_direction dir;
+-		struct mt76_queue_buf qbuf;
+ 		dma_addr_t addr;
+ 		int offset;
+-		void *buf;
++		void *buf = NULL;
++
++		if (mt76_queue_is_wed_rro_ind(q))
++			goto done;
+ 
+ 		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
+ 		if (!buf)
+@@ -621,6 +656,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+ 		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
+ 
+ 		qbuf.addr = addr + q->buf_offset;
++done:
+ 		qbuf.len = len - q->buf_offset;
+ 		qbuf.skip_unmap = false;
+ 		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
+@@ -630,7 +666,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+ 		frames++;
+ 	}
+ 
+-	if (frames)
++	if (frames || mt76_queue_is_wed_rx(q))
+ 		mt76_dma_kick_queue(dev, q);
+ 
+ 	spin_unlock_bh(&q->lock);
+@@ -641,15 +677,14 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+ 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;
+-	u8 flags;
++	int ret = 0, type, ring;
++	u16 flags;
+ 
+ 	if (!q || !q->ndesc)
+ 		return -EINVAL;
+ 
+ 	flags = q->flags;
+-	if (!mtk_wed_device_active(wed))
++	if (!q->wed || !mtk_wed_device_active(q->wed))
+ 		q->flags &= ~MT_QFLAG_WED;
+ 
+ 	if (!(q->flags & MT_QFLAG_WED))
+@@ -660,29 +695,52 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 
+ 	switch (type) {
+ 	case MT76_WED_Q_TX:
+-		ret = mtk_wed_device_tx_ring_setup(wed, ring, q->regs, reset);
++		ret = mtk_wed_device_tx_ring_setup(q->wed, ring, q->regs,
++						   reset);
+ 		if (!ret)
+-			q->wed_regs = wed->tx_ring[ring].reg_base;
++			q->wed_regs = q->wed->tx_ring[ring].reg_base;
+ 		break;
+ 	case MT76_WED_Q_TXFREE:
+ 		/* WED txfree queue needs ring to be initialized before setup */
+ 		q->flags = 0;
+ 		mt76_dma_queue_reset(dev, q);
+ 		mt76_dma_rx_fill(dev, q, false);
+-		q->flags = flags;
+ 
+-		ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
++		ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
+ 		if (!ret)
+-			q->wed_regs = wed->txfree_ring.reg_base;
++			q->wed_regs = q->wed->txfree_ring.reg_base;
+ 		break;
+ 	case MT76_WED_Q_RX:
+-		ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
++		ret = mtk_wed_device_rx_ring_setup(q->wed, ring, q->regs,
++						   reset);
+ 		if (!ret)
+-			q->wed_regs = wed->rx_ring[ring].reg_base;
++			q->wed_regs = q->wed->rx_ring[ring].reg_base;
++		break;
++	case MT76_WED_RRO_Q_DATA:
++		q->flags &= ~MT_QFLAG_WED;
++		__mt76_dma_queue_reset(dev, q, false);
++		mtk_wed_device_rro_rx_ring_setup(q->wed, ring, q->regs);
++		q->head = q->ndesc - 1;
++		q->queued = q->head;
++		break;
++	case MT76_WED_RRO_Q_MSDU_PG:
++		q->flags &= ~MT_QFLAG_WED;
++		__mt76_dma_queue_reset(dev, q, false);
++		mtk_wed_device_msdu_pg_rx_ring_setup(q->wed, ring, q->regs);
++		q->head = q->ndesc - 1;
++		q->queued = q->head;
++		break;
++	case MT76_WED_RRO_Q_IND:
++		q->flags &= ~MT_QFLAG_WED;
++		mt76_dma_queue_reset(dev, q);
++		mt76_dma_rx_fill(dev, q, false);
++		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
+ 		break;
+ 	default:
+ 		ret = -EINVAL;
++		break;
+ 	}
++	q->flags = flags;
+ 
+ 	return ret;
+ #else
+@@ -706,11 +764,26 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ 	q->buf_size = bufsize;
+ 	q->hw_idx = idx;
+ 
+-	size = q->ndesc * sizeof(struct mt76_desc);
+-	q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
++	size = mt76_queue_is_wed_rro_ind(q) ? sizeof(struct mt76_wed_rro_desc)
++					    : sizeof(struct mt76_desc);
++	q->desc = dmam_alloc_coherent(dev->dma_dev, q->ndesc * size,
++				      &q->desc_dma, GFP_KERNEL);
+ 	if (!q->desc)
+ 		return -ENOMEM;
+ 
++	if (mt76_queue_is_wed_rro_ind(q)) {
++		struct mt76_wed_rro_desc *rro_desc;
++		int i;
++
++		rro_desc = (struct mt76_wed_rro_desc *)q->desc;
++		for (i = 0; i < q->ndesc; i++) {
++			struct mt76_wed_rro_ind *cmd;
++
++			cmd = (struct mt76_wed_rro_ind *)&rro_desc[i];
++			cmd->magic_cnt = MT_DMA_WED_IND_CMD_CNT - 1;
++		}
++	}
++
+ 	size = q->ndesc * sizeof(*q->entry);
+ 	q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
+ 	if (!q->entry)
+@@ -724,8 +797,13 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ 	if (ret)
+ 		return ret;
+ 
+-	if (q->flags != MT_WED_Q_TXFREE)
+-		mt76_dma_queue_reset(dev, q);
++	if (mtk_wed_device_active(&dev->mmio.wed)) {
++		if ((mtk_wed_get_rx_capa(&dev->mmio.wed) && mt76_queue_is_wed_rro(q)) ||
++		    mt76_queue_is_wed_tx_free(q))
++			return 0;
++	}
++
++	mt76_dma_queue_reset(dev, q);
+ 
+ 	return 0;
+ }
+@@ -746,7 +824,8 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+ 		if (!buf)
+ 			break;
+ 
+-		mt76_put_page_pool_buf(buf, false);
++		if (!mt76_queue_is_wed_rro(q))
++			mt76_put_page_pool_buf(buf, false);
+ 	} while (1);
+ 
+ 	if (q->rx_head) {
+@@ -761,19 +840,22 @@ static void
+ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+ {
+ 	struct mt76_queue *q = &dev->q_rx[qid];
+-	int i;
+ 
+ 	if (!q->ndesc)
+ 		return;
+ 
+-	for (i = 0; i < q->ndesc; i++)
+-		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
++	if (!mt76_queue_is_wed_rro_ind(q)) {
++		int i;
++
++		for (i = 0; i < q->ndesc; i++)
++			q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
++	}
+ 
+ 	mt76_dma_rx_cleanup(dev, q);
+ 
+ 	/* reset WED rx queues */
+ 	mt76_dma_wed_setup(dev, q, true);
+-	if (q->flags != MT_WED_Q_TXFREE) {
++	if (!mt76_queue_is_wed_tx_free(q)) {
+ 		mt76_dma_sync_idx(dev, q);
+ 		mt76_dma_rx_fill(dev, q, false);
+ 	}
+@@ -816,8 +898,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+ 	bool more;
+ 
+ 	if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
+-	    q->flags == MT_WED_Q_TXFREE) {
+-		dma_idx = Q_READ(dev, q, dma_idx);
++	    mt76_queue_is_wed_tx_free(q)) {
++		dma_idx = Q_READ(q, dma_idx);
+ 		check_ddone = true;
+ 	}
+ 
+@@ -827,7 +909,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+ 
+ 		if (check_ddone) {
+ 			if (q->tail == dma_idx)
+-				dma_idx = Q_READ(dev, q, dma_idx);
++				dma_idx = Q_READ(q, dma_idx);
+ 
+ 			if (q->tail == dma_idx)
+ 				break;
+@@ -979,16 +1061,23 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+ 	mt76_for_each_q_rx(dev, i) {
+ 		struct mt76_queue *q = &dev->q_rx[i];
+ 
++		if (mtk_wed_device_active(&dev->mmio.wed) &&
++		    mt76_queue_is_wed_rro(q))
++			continue;
++
+ 		netif_napi_del(&dev->napi[i]);
+ 		mt76_dma_rx_cleanup(dev, q);
+ 
+ 		page_pool_destroy(q->page_pool);
+ 	}
+ 
+-	mt76_free_pending_txwi(dev);
+-	mt76_free_pending_rxwi(dev);
+-
+ 	if (mtk_wed_device_active(&dev->mmio.wed))
+ 		mtk_wed_device_detach(&dev->mmio.wed);
++
++	if (mtk_wed_device_active(&dev->mmio.wed_hif2))
++		mtk_wed_device_detach(&dev->mmio.wed_hif2);
++
++	mt76_free_pending_txwi(dev);
++	mt76_free_pending_rxwi(dev);
+ }
+ EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
+diff --git a/dma.h b/dma.h
+index 1b090d7..22b79d5 100644
+--- a/dma.h
++++ b/dma.h
+@@ -25,6 +25,13 @@
+ #define MT_DMA_PPE_ENTRY		GENMASK(30, 16)
+ #define MT_DMA_INFO_PPE_VLD		BIT(31)
+ 
++#define MT_DMA_CTL_PN_CHK_FAIL		BIT(13)
++#define MT_DMA_CTL_VER_MASK		BIT(7)
++
++#define MT_DMA_RRO_EN		BIT(13)
++
++#define MT_DMA_WED_IND_CMD_CNT		8
++
+ #define MT_DMA_HDR_LEN			4
+ #define MT_RX_INFO_LEN			4
+ #define MT_FCE_INFO_LEN			4
+@@ -37,6 +44,11 @@ struct mt76_desc {
+ 	__le32 info;
+ } __packed __aligned(4);
+ 
++struct mt76_wed_rro_desc {
++	__le32 buf0;
++	__le32 buf1;
++} __packed __aligned(4);
++
+ enum mt76_qsel {
+ 	MT_QSEL_MGMT,
+ 	MT_QSEL_HCCA,
+diff --git a/mac80211.c b/mac80211.c
+index 12fcb2b..cd102dd 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -1726,7 +1726,7 @@ EXPORT_SYMBOL_GPL(mt76_get_antenna);
+ 
+ struct mt76_queue *
+ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
+-		int ring_base, u32 flags)
++		int ring_base, void *wed, u32 flags)
+ {
+ 	struct mt76_queue *hwq;
+ 	int err;
+@@ -1736,6 +1736,7 @@ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
+ 		return ERR_PTR(-ENOMEM);
+ 
+ 	hwq->flags = flags;
++	hwq->wed = wed;
+ 
+ 	err = dev->queue_ops->alloc(dev, hwq, idx, n_desc, 0, ring_base);
+ 	if (err < 0)
+@@ -1843,3 +1844,19 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
+ 	return MT_DFS_STATE_ACTIVE;
+ }
+ EXPORT_SYMBOL_GPL(mt76_phy_dfs_state);
++
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++		      struct net_device *netdev, enum tc_setup_type type,
++		      void *type_data)
++{
++	struct mt76_phy *phy = hw->priv;
++	struct mtk_wed_device *wed = &phy->dev->mmio.wed;
++
++	if (!mtk_wed_device_active(wed))
++		return -EOPNOTSUPP;
++
++	return mtk_wed_device_setup_tc(wed, netdev, type, type_data);
++}
++EXPORT_SYMBOL_GPL(mt76_net_setup_tc);
++#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
+diff --git a/mmio.c b/mmio.c
+index 86e3d2a..c346249 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -4,6 +4,7 @@
+  */
+ 
+ #include "mt76.h"
++#include "dma.h"
+ #include "trace.h"
+ 
+ static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset)
+@@ -84,6 +85,102 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr,
+ }
+ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+ 
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
++{
++	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++	int i;
++
++	for (i = 0; i < dev->rx_token_size; i++) {
++		struct mt76_txwi_cache *t;
++
++		t = mt76_rx_token_release(dev, i);
++		if (!t || !t->ptr)
++			continue;
++
++		mt76_put_page_pool_buf(t->ptr, false);
++		t->ptr = NULL;
++
++		mt76_put_rxwi(dev, t);
++	}
++
++	mt76_free_pending_rxwi(dev);
++}
++EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
++
++u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
++{
++	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
++	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
++	int i, len = SKB_WITH_OVERHEAD(q->buf_size);
++	struct mt76_txwi_cache *t = NULL;
++
++	for (i = 0; i < size; i++) {
++		enum dma_data_direction dir;
++		dma_addr_t addr;
++		u32 offset;
++		int token;
++		void *buf;
++
++		t = mt76_get_rxwi(dev);
++		if (!t)
++			goto unmap;
++
++		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
++		if (!buf)
++			goto unmap;
++
++		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
++		dir = page_pool_get_dma_dir(q->page_pool);
++		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
++
++		desc->buf0 = cpu_to_le32(addr);
++		token = mt76_rx_token_consume(dev, buf, t, addr);
++		if (token < 0) {
++			mt76_put_page_pool_buf(buf, false);
++			goto unmap;
++		}
++
++		desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
++						      token));
++		desc++;
++	}
++
++	return 0;
++
++unmap:
++	if (t)
++		mt76_put_rxwi(dev, t);
++	mt76_mmio_wed_release_rx_buf(wed);
++
++	return -ENOMEM;
++}
++EXPORT_SYMBOL_GPL(mt76_mmio_wed_init_rx_buf);
++
++int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed)
++{
++	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++
++	spin_lock_bh(&dev->token_lock);
++	dev->token_size = wed->wlan.token_start;
++	spin_unlock_bh(&dev->token_lock);
++
++	return !wait_event_timeout(dev->tx_wait, !dev->wed_token_count, HZ);
++}
++EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_enable);
++
++void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed)
++{
++	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++
++	spin_lock_bh(&dev->token_lock);
++	dev->token_size = dev->drv->token_size;
++	spin_unlock_bh(&dev->token_lock);
++}
++EXPORT_SYMBOL_GPL(mt76_mmio_wed_offload_disable);
++#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
++
+ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
+ {
+ 	static const struct mt76_bus_ops mt76_mmio_ops = {
+diff --git a/mt76.h b/mt76.h
+index a238216..7f93210 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -28,15 +28,22 @@
+ #define MT76_TOKEN_FREE_THR	64
+ 
+ #define MT_QFLAG_WED_RING	GENMASK(1, 0)
+-#define MT_QFLAG_WED_TYPE	GENMASK(3, 2)
+-#define MT_QFLAG_WED		BIT(4)
++#define MT_QFLAG_WED_TYPE	GENMASK(4, 2)
++#define MT_QFLAG_WED		BIT(5)
++#define MT_QFLAG_WED_RRO	BIT(6)
++#define MT_QFLAG_WED_RRO_EN	BIT(7)
+ 
+ #define __MT_WED_Q(_type, _n)	(MT_QFLAG_WED | \
+ 				 FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
+ 				 FIELD_PREP(MT_QFLAG_WED_RING, _n))
++#define __MT_WED_RRO_Q(_type, _n)	(MT_QFLAG_WED_RRO | __MT_WED_Q(_type, _n))
++
+ #define MT_WED_Q_TX(_n)		__MT_WED_Q(MT76_WED_Q_TX, _n)
+ #define MT_WED_Q_RX(_n)		__MT_WED_Q(MT76_WED_Q_RX, _n)
+ #define MT_WED_Q_TXFREE		__MT_WED_Q(MT76_WED_Q_TXFREE, 0)
++#define MT_WED_RRO_Q_DATA(_n)	__MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n)
++#define MT_WED_RRO_Q_MSDU_PG(_n)	__MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n)
++#define MT_WED_RRO_Q_IND	__MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0)
+ 
+ struct mt76_dev;
+ struct mt76_phy;
+@@ -58,6 +65,9 @@ enum mt76_wed_type {
+ 	MT76_WED_Q_TX,
+ 	MT76_WED_Q_TXFREE,
+ 	MT76_WED_Q_RX,
++	MT76_WED_RRO_Q_DATA,
++	MT76_WED_RRO_Q_MSDU_PG,
++	MT76_WED_RRO_Q_IND,
+ };
+ 
+ struct mt76_bus_ops {
+@@ -106,6 +116,16 @@ enum mt76_rxq_id {
+ 	MT_RXQ_MAIN_WA,
+ 	MT_RXQ_BAND2,
+ 	MT_RXQ_BAND2_WA,
++	MT_RXQ_RRO_BAND0,
++	MT_RXQ_RRO_BAND1,
++	MT_RXQ_RRO_BAND2,
++	MT_RXQ_MSDU_PAGE_BAND0,
++	MT_RXQ_MSDU_PAGE_BAND1,
++	MT_RXQ_MSDU_PAGE_BAND2,
++	MT_RXQ_TXFREE_BAND0,
++	MT_RXQ_TXFREE_BAND1,
++	MT_RXQ_TXFREE_BAND2,
++	MT_RXQ_RRO_IND,
+ 	__MT_RXQ_MAX
+ };
+ 
+@@ -183,6 +203,7 @@ struct mt76_queue {
+ 	spinlock_t lock;
+ 	spinlock_t cleanup_lock;
+ 	struct mt76_queue_entry *entry;
++	struct mt76_rro_desc *rro_desc;
+ 	struct mt76_desc *desc;
+ 
+ 	u16 first;
+@@ -196,8 +217,9 @@ struct mt76_queue {
+ 
+ 	u8 buf_offset;
+ 	u8 hw_idx;
+-	u8 flags;
++	u16 flags;
+ 
++	struct mtk_wed_device *wed;
+ 	u32 wed_regs;
+ 
+ 	dma_addr_t desc_dma;
+@@ -352,6 +374,17 @@ struct mt76_txq {
+ 	bool aggr;
+ };
+ 
++struct mt76_wed_rro_ind {
++	u32 se_id	: 12;
++	u32 rsv		: 4;
++	u32 start_sn	: 12;
++	u32 ind_reason	: 4;
++	u32 ind_cnt	: 13;
++	u32 win_sz	: 3;
++	u32 rsv2	: 13;
++	u32 magic_cnt	: 3;
++};
++
+ struct mt76_txwi_cache {
+ 	struct list_head list;
+ 	dma_addr_t dma_addr;
+@@ -602,6 +635,7 @@ struct mt76_mmio {
+ 	u32 irqmask;
+ 
+ 	struct mtk_wed_device wed;
++	struct mtk_wed_device wed_hif2;
+ 	struct completion wed_reset;
+ 	struct completion wed_reset_complete;
+ };
+@@ -1046,6 +1080,12 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,
+ void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs);
+ void mt76_pci_disable_aspm(struct pci_dev *pdev);
+ 
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++int mt76_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++		      struct net_device *netdev, enum tc_setup_type type,
++		      void *type_data);
++#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
++
+ static inline u16 mt76_chip(struct mt76_dev *dev)
+ {
+ 	return dev->rev >> 16;
+@@ -1056,6 +1096,13 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
+ 	return dev->rev & 0xffff;
+ }
+ 
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size);
++void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed);
++int mt76_mmio_wed_offload_enable(struct mtk_wed_device *wed);
++void mt76_mmio_wed_offload_disable(struct mtk_wed_device *wed);
++#endif /*CONFIG_NET_MEDIATEK_SOC_WED */
++
+ #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76))
+ #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76))
+ 
+@@ -1105,15 +1152,16 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
+ 
+ struct mt76_queue *
+ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
+-		int ring_base, u32 flags);
++		int ring_base, void *wed, u32 flags);
+ u16 mt76_calculate_default_rate(struct mt76_phy *phy,
+ 				struct ieee80211_vif *vif, int rateidx);
+ static inline int mt76_init_tx_queue(struct mt76_phy *phy, int qid, int idx,
+-				     int n_desc, int ring_base, u32 flags)
++				     int n_desc, int ring_base, void *wed,
++				     u32 flags)
+ {
+ 	struct mt76_queue *q;
+ 
+-	q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, flags);
++	q = mt76_init_queue(phy->dev, qid, idx, n_desc, ring_base, wed, flags);
+ 	if (IS_ERR(q))
+ 		return PTR_ERR(q);
+ 
+@@ -1127,7 +1175,7 @@ static inline int mt76_init_mcu_queue(struct mt76_dev *dev, int qid, int idx,
+ {
+ 	struct mt76_queue *q;
+ 
+-	q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, 0);
++	q = mt76_init_queue(dev, qid, idx, n_desc, ring_base, NULL, 0);
+ 	if (IS_ERR(q))
+ 		return PTR_ERR(q);
+ 
+@@ -1541,10 +1589,38 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ 			      struct mt76_power_limits *dest,
+ 			      s8 target_power);
+ 
+-static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
++static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
+ {
+ 	return (q->flags & MT_QFLAG_WED) &&
+-	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
++	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
++}
++
++static inline bool mt76_queue_is_wed_rro(struct mt76_queue *q)
++{
++	return q->flags & MT_QFLAG_WED_RRO;
++}
++
++static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
++{
++	return mt76_queue_is_wed_rro(q) &&
++	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND;
++}
++
++static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
++{
++	return mt76_queue_is_wed_rro(q) &&
++	       (FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA ||
++		FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
++}
++
++static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
++{
++	if (!(q->flags & MT_QFLAG_WED))
++		return false;
++
++	return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX ||
++	       mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q);
++
+ }
+ 
+ struct mt76_txwi_cache *
+@@ -1584,10 +1660,14 @@ static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
+ static inline int
+ mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+ {
+-	int token;
++	int token, start = 0;
++
++	if (mtk_wed_device_active(&dev->mmio.wed))
++		start = dev->mmio.wed.wlan.nbuf;
+ 
+ 	spin_lock_bh(&dev->token_lock);
+-	token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
++	token = idr_alloc(&dev->token, *ptxwi, start, start + dev->token_size,
++			  GFP_ATOMIC);
+ 	spin_unlock_bh(&dev->token_lock);
+ 
+ 	return token;
+diff --git a/mt7603/dma.c b/mt7603/dma.c
+index 03ba11a..7a2f5d3 100644
+--- a/mt7603/dma.c
++++ b/mt7603/dma.c
+@@ -173,13 +173,14 @@ int mt7603_dma_init(struct mt7603_dev *dev)
+ 
+ 	for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
+ 		ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
+-					 MT7603_TX_RING_SIZE, MT_TX_RING_BASE, 0);
++					 MT7603_TX_RING_SIZE, MT_TX_RING_BASE,
++					 NULL, 0);
+ 		if (ret)
+ 			return ret;
+ 	}
+ 
+ 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
+-				 MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
++				 MT7603_PSD_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -189,12 +190,12 @@ int mt7603_dma_init(struct mt7603_dev *dev)
+ 		return ret;
+ 
+ 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_BEACON, MT_TX_HW_QUEUE_BCN,
+-				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
++				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+ 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_CAB, MT_TX_HW_QUEUE_BMC,
+-				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, 0);
++				 MT_MCU_RING_SIZE, MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/mt7615/dma.c b/mt7615/dma.c
+index 0ce01cc..e7135b2 100644
+--- a/mt7615/dma.c
++++ b/mt7615/dma.c
+@@ -26,14 +26,14 @@ mt7622_init_tx_queues_multi(struct mt7615_dev *dev)
+ 	for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
+ 		ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
+ 					 MT7615_TX_RING_SIZE / 2,
+-					 MT_TX_RING_BASE, 0);
++					 MT_TX_RING_BASE, NULL, 0);
+ 		if (ret)
+ 			return ret;
+ 	}
+ 
+ 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT7622_TXQ_MGMT,
+ 				 MT7615_TX_MGMT_RING_SIZE,
+-				 MT_TX_RING_BASE, 0);
++				 MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -55,7 +55,7 @@ mt7615_init_tx_queues(struct mt7615_dev *dev)
+ 		return mt7622_init_tx_queues_multi(dev);
+ 
+ 	ret = mt76_connac_init_tx_queues(&dev->mphy, 0, MT7615_TX_RING_SIZE,
+-					 MT_TX_RING_BASE, 0);
++					 MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/mt76_connac.h b/mt76_connac.h
+index 1f29d8c..e5ebde1 100644
+--- a/mt76_connac.h
++++ b/mt76_connac.h
+@@ -391,7 +391,8 @@ mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm)
+ 
+ void mt76_connac_gen_ppe_thresh(u8 *he_ppet, int nss);
+ int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
+-			       int ring_base, u32 flags);
++			       int ring_base, void *wed, u32 flags);
++
+ void mt76_connac_write_hw_txp(struct mt76_dev *dev,
+ 			      struct mt76_tx_info *tx_info,
+ 			      void *txp_ptr, u32 id);
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
+index 93402d2..c791464 100644
+--- a/mt76_connac_mac.c
++++ b/mt76_connac_mac.c
+@@ -256,11 +256,12 @@ void mt76_connac_txp_skb_unmap(struct mt76_dev *dev,
+ EXPORT_SYMBOL_GPL(mt76_connac_txp_skb_unmap);
+ 
+ int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
+-			       int ring_base, u32 flags)
++			       int ring_base, void *wed, u32 flags)
+ {
+ 	int i, err;
+ 
+-	err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base, flags);
++	err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base,
++				 wed, flags);
+ 	if (err < 0)
+ 		return err;
+ 
+diff --git a/mt76x02_mmio.c b/mt76x02_mmio.c
+index 9b5e3fb..e5ad635 100644
+--- a/mt76x02_mmio.c
++++ b/mt76x02_mmio.c
+@@ -199,13 +199,14 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
+ 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ 		ret = mt76_init_tx_queue(&dev->mphy, i, mt76_ac_to_hwq(i),
+ 					 MT76x02_TX_RING_SIZE,
+-					 MT_TX_RING_BASE, 0);
++					 MT_TX_RING_BASE, NULL, 0);
+ 		if (ret)
+ 			return ret;
+ 	}
+ 
+ 	ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
+-				 MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE, 0);
++				 MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE,
++				 NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/mt7915/dma.c b/mt7915/dma.c
+index 59a44d7..1bceeb5 100644
+--- a/mt7915/dma.c
++++ b/mt7915/dma.c
+@@ -9,18 +9,20 @@ static int
+ mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc, int ring_base)
+ {
+ 	struct mt7915_dev *dev = phy->dev;
++	struct mtk_wed_device *wed = NULL;
+ 
+-	if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
+ 		if (is_mt798x(&dev->mt76))
+ 			ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
+ 		else
+ 			ring_base = MT_WED_TX_RING_BASE;
+ 
+ 		idx -= MT_TXQ_ID(0);
++		wed = &dev->mt76.mmio.wed;
+ 	}
+ 
+ 	return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc, ring_base,
+-					  MT_WED_Q_TX(idx));
++					  wed, MT_WED_Q_TX(idx));
+ }
+ 
+ static int mt7915_poll_tx(struct napi_struct *napi, int budget)
+@@ -492,7 +494,8 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ 	if (mtk_wed_device_active(&mdev->mmio.wed) && is_mt7915(mdev)) {
+ 		wa_rx_base = MT_WED_RX_RING_BASE;
+ 		wa_rx_idx = MT7915_RXQ_MCU_WA;
+-		dev->mt76.q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
++		mdev->q_rx[MT_RXQ_MCU_WA].flags = MT_WED_Q_TXFREE;
++		mdev->q_rx[MT_RXQ_MCU_WA].wed = &mdev->mmio.wed;
+ 	} else {
+ 		wa_rx_base = MT_RXQ_RING_BASE(MT_RXQ_MCU_WA);
+ 		wa_rx_idx = MT_RXQ_ID(MT_RXQ_MCU_WA);
+@@ -507,9 +510,10 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ 	if (!dev->phy.mt76->band_idx) {
+ 		if (mtk_wed_device_active(&mdev->mmio.wed) &&
+ 		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
+-			dev->mt76.q_rx[MT_RXQ_MAIN].flags =
++			mdev->q_rx[MT_RXQ_MAIN].flags =
+ 				MT_WED_Q_RX(MT7915_RXQ_BAND0);
+ 			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
++			mdev->q_rx[MT_RXQ_MAIN].wed = &mdev->mmio.wed;
+ 		}
+ 
+ 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
+@@ -528,6 +532,7 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ 
+ 		if (mtk_wed_device_active(&mdev->mmio.wed)) {
+ 			mdev->q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
++			mdev->q_rx[MT_RXQ_MAIN_WA].wed = &mdev->mmio.wed;
+ 			if (is_mt7916(mdev)) {
+ 				wa_rx_base =  MT_WED_RX_RING_BASE;
+ 				wa_rx_idx = MT7915_RXQ_MCU_WA;
+@@ -544,9 +549,10 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ 	if (dev->dbdc_support || dev->phy.mt76->band_idx) {
+ 		if (mtk_wed_device_active(&mdev->mmio.wed) &&
+ 		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
+-			dev->mt76.q_rx[MT_RXQ_BAND1].flags =
++			mdev->q_rx[MT_RXQ_BAND1].flags =
+ 				MT_WED_Q_RX(MT7915_RXQ_BAND1);
+ 			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
++			mdev->q_rx[MT_RXQ_BAND1].wed = &mdev->mmio.wed;
+ 		}
+ 
+ 		/* rx data queue for band1 */
+@@ -643,7 +649,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force)
+ 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
+ 
+ 	mt76_for_each_q_rx(&dev->mt76, i) {
+-		if (dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE)
++		if (mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i]))
+ 			continue;
+ 
+ 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
+diff --git a/mt7915/main.c b/mt7915/main.c
+index a3fd54c..ba34c8e 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -1653,20 +1653,6 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw,
+ 
+ 	return 0;
+ }
+-
+-static int
+-mt7915_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		    struct net_device *netdev, enum tc_setup_type type,
+-		    void *type_data)
+-{
+-	struct mt7915_dev *dev = mt7915_hw_dev(hw);
+-	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+-
+-	if (!mtk_wed_device_active(wed))
+-		return -EOPNOTSUPP;
+-
+-	return mtk_wed_device_setup_tc(wed, netdev, type, type_data);
+-}
+ #endif
+ 
+ const struct ieee80211_ops mt7915_ops = {
+@@ -1721,6 +1707,6 @@ 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,
+-	.net_setup_tc = mt7915_net_setup_tc,
++	.net_setup_tc = mt76_net_setup_tc,
+ #endif
+ };
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index fc7ace6..85cb3fe 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -542,105 +542,6 @@ static u32 mt7915_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ }
+ 
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+-static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed)
+-{
+-	struct mt7915_dev *dev;
+-
+-	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;
+-	spin_unlock_bh(&dev->mt76.token_lock);
+-
+-	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;
+-
+-	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);
+-}
+-
+-static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+-{
+-	struct mt7915_dev *dev;
+-	int i;
+-
+-	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+-	for (i = 0; i < dev->mt76.rx_token_size; i++) {
+-		struct mt76_txwi_cache *t;
+-
+-		t = mt76_rx_token_release(&dev->mt76, i);
+-		if (!t || !t->ptr)
+-			continue;
+-
+-		mt76_put_page_pool_buf(t->ptr, false);
+-		t->ptr = NULL;
+-
+-		mt76_put_rxwi(&dev->mt76, t);
+-	}
+-
+-	mt76_free_pending_rxwi(&dev->mt76);
+-}
+-
+-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;
+-	struct mt76_txwi_cache *t = NULL;
+-	struct mt7915_dev *dev;
+-	struct mt76_queue *q;
+-	int i, len;
+-
+-	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+-	q = &dev->mt76.q_rx[MT_RXQ_MAIN];
+-	len = SKB_WITH_OVERHEAD(q->buf_size);
+-
+-	for (i = 0; i < size; i++) {
+-		enum dma_data_direction dir;
+-		dma_addr_t addr;
+-		u32 offset;
+-		int token;
+-		void *buf;
+-
+-		t = mt76_get_rxwi(&dev->mt76);
+-		if (!t)
+-			goto unmap;
+-
+-		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
+-		if (!buf)
+-			goto unmap;
+-
+-		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
+-		dir = page_pool_get_dma_dir(q->page_pool);
+-		dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir);
+-
+-		desc->buf0 = cpu_to_le32(addr);
+-		token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
+-		if (token < 0) {
+-			mt76_put_page_pool_buf(buf, false);
+-			goto unmap;
+-		}
+-
+-		desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
+-						      token));
+-		desc++;
+-	}
+-
+-	return 0;
+-
+-unmap:
+-	if (t)
+-		mt76_put_rxwi(&dev->mt76, t);
+-	mt7915_mmio_wed_release_rx_buf(wed);
+-	return -ENOMEM;
+-}
+-
+ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed,
+ 					    struct mtk_wed_wo_rx_stats *stats)
+ {
+@@ -778,10 +679,10 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+ 	}
+ 
+ 	wed->wlan.init_buf = mt7915_wed_init_buf;
+-	wed->wlan.offload_enable = mt7915_mmio_wed_offload_enable;
+-	wed->wlan.offload_disable = mt7915_mmio_wed_offload_disable;
+-	wed->wlan.init_rx_buf = mt7915_mmio_wed_init_rx_buf;
+-	wed->wlan.release_rx_buf = mt7915_mmio_wed_release_rx_buf;
++	wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
++	wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
++	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
++	wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
+ 	wed->wlan.update_wo_rx_stats = mt7915_mmio_wed_update_rx_stats;
+ 	wed->wlan.reset = mt7915_mmio_wed_reset;
+ 	wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
+diff --git a/mt7921/pci.c b/mt7921/pci.c
+index 9647e4b..9ea7e0c 100644
+--- a/mt7921/pci.c
++++ b/mt7921/pci.c
+@@ -171,7 +171,7 @@ static int mt7921_dma_init(struct mt792x_dev *dev)
+ 	/* init tx queue */
+ 	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0,
+ 					 MT7921_TX_RING_SIZE,
+-					 MT_TX_RING_BASE, 0);
++					 MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/mt7925/pci.c b/mt7925/pci.c
+index 08ef75e..734f31e 100644
+--- a/mt7925/pci.c
++++ b/mt7925/pci.c
+@@ -218,7 +218,7 @@ static int mt7925_dma_init(struct mt792x_dev *dev)
+ 	/* init tx queue */
+ 	ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7925_TXQ_BAND0,
+ 					 MT7925_TX_RING_SIZE,
+-					 MT_TX_RING_BASE, 0);
++					 MT_TX_RING_BASE, NULL, 0);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 586e247..2221d22 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -7,6 +7,26 @@
+ #include "../dma.h"
+ #include "mac.h"
+ 
++int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, int n_desc,
++			  int ring_base, struct mtk_wed_device *wed)
++{
++	struct mt7996_dev *dev = phy->dev;
++	u32 flags = 0;
++
++	if (mtk_wed_device_active(wed)) {
++		ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
++		idx -= MT_TXQ_ID(0);
++
++		if (phy->mt76->band_idx == MT_BAND2)
++			flags = MT_WED_Q_TX(0);
++		else
++			flags = MT_WED_Q_TX(idx);
++	}
++
++	return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc,
++					  ring_base, wed, flags);
++}
++
+ static int mt7996_poll_tx(struct napi_struct *napi, int budget)
+ {
+ 	struct mt7996_dev *dev;
+@@ -45,6 +65,29 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+ 	RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
+ 	RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
+ 
++	if (dev->has_rro) {
++		/* band0 */
++		RXQ_CONFIG(MT_RXQ_RRO_BAND0, WFDMA0, MT_INT_RX_DONE_RRO_BAND0,
++			   MT7996_RXQ_RRO_BAND0);
++		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
++			   MT7996_RXQ_MSDU_PG_BAND0);
++		RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
++			   MT7996_RXQ_TXFREE0);
++		/* band1 */
++		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
++			   MT7996_RXQ_MSDU_PG_BAND1);
++		/* band2 */
++		RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
++			   MT7996_RXQ_RRO_BAND2);
++		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
++			   MT7996_RXQ_MSDU_PG_BAND2);
++		RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
++			   MT7996_RXQ_TXFREE2);
++
++		RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
++			   MT7996_RXQ_RRO_IND);
++	}
++
+ 	/* 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);
+@@ -73,6 +116,24 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
+ 	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));
+ 
++	if (dev->has_rro) {
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
++			PREFETCH(0x3a0, 0x10));
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
++			PREFETCH(0x4a0, 0x10));
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
++			PREFETCH(0x5a0, 0x4));
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
++			PREFETCH(0x5e0, 0x4));
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
++			PREFETCH(0x620, 0x4));
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
++			PREFETCH(0x660, 0x4));
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
++			PREFETCH(0x6a0, 0x4));
++	}
++#undef PREFETCH
++
+ 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
+ }
+ 
+@@ -128,8 +189,9 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
+ 	}
+ }
+ 
+-void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
++void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
+ {
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ 	u32 hif1_ofs = 0;
+ 	u32 irq_mask;
+ 
+@@ -138,11 +200,16 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
+ 
+ 	/* 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 (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
++			mt76_set(dev, MT_WFDMA0_GLO_CFG,
++				 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++				 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO);
++		else
++			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,
+@@ -153,11 +220,7 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
+ 	}
+ 
+ 	/* 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;
++	irq_mask = MT_INT_MCU_CMD | MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
+ 
+ 	if (!dev->mphy.band_idx)
+ 		irq_mask |= MT_INT_BAND0_RX_DONE;
+@@ -168,7 +231,16 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
+ 	if (dev->tbtc_support)
+ 		irq_mask |= MT_INT_BAND2_RX_DONE;
+ 
+-done:
++	if (mtk_wed_device_active(wed) && wed_reset) {
++		u32 wed_irq_mask = irq_mask;
++
++		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
++		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++		mtk_wed_device_start(wed, wed_irq_mask);
++	}
++
++	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
++
+ 	mt7996_irq_enable(dev, irq_mask);
+ 	mt7996_irq_disable(dev, 0);
+ }
+@@ -241,17 +313,90 @@ static void 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
+ 		 */
+-		mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
+-			 MT_WFDMA0_RX_INT_SEL_RING3);
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++		    dev->has_rro)
++			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
++				 MT_WFDMA0_RX_INT_SEL_RING6);
++		else
++			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
++				 MT_WFDMA0_RX_INT_SEL_RING3);
++	}
++
++	mt7996_dma_start(dev, reset, true);
++}
++
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++int mt7996_dma_rro_init(struct mt7996_dev *dev)
++{
++	struct mt76_dev *mdev = &dev->mt76;
++	u32 irq_mask;
++	int ret;
++
++	/* ind cmd */
++	mdev->q_rx[MT_RXQ_RRO_IND].flags = MT_WED_RRO_Q_IND;
++	mdev->q_rx[MT_RXQ_RRO_IND].wed = &mdev->mmio.wed;
++	ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_RRO_IND],
++			       MT_RXQ_ID(MT_RXQ_RRO_IND),
++			       MT7996_RX_RING_SIZE,
++			       0, MT_RXQ_RRO_IND_RING_BASE);
++	if (ret)
++		return ret;
+ 
+-		/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
++	/* rx msdu page queue for band0 */
++	mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags =
++		MT_WED_RRO_Q_MSDU_PG(0) | MT_QFLAG_WED_RRO_EN;
++	mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0].wed = &mdev->mmio.wed;
++	ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND0],
++			       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),
++			       MT7996_RX_RING_SIZE,
++			       MT7996_RX_MSDU_PAGE_SIZE,
++			       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));
++	if (ret)
++		return ret;
++
++	if (dev->dbdc_support) {
++		/* rx msdu page queue for band1 */
++		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
++			MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
++		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].wed = &mdev->mmio.wed;
++		ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1],
++				       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),
++				       MT7996_RX_RING_SIZE,
++				       MT7996_RX_MSDU_PAGE_SIZE,
++				       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));
++		if (ret)
++			return ret;
++	}
++
++	if (dev->tbtc_support) {
++		/* rx msdu page queue for band2 */
++		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags =
++			MT_WED_RRO_Q_MSDU_PG(2) | MT_QFLAG_WED_RRO_EN;
++		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].wed = &mdev->mmio.wed;
++		ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2],
++				       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),
++				       MT7996_RX_RING_SIZE,
++				       MT7996_RX_MSDU_PAGE_SIZE,
++				       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));
++		if (ret)
++			return ret;
+ 	}
+ 
+-	mt7996_dma_start(dev, reset);
++	irq_mask = mdev->mmio.irqmask | MT_INT_RRO_RX_DONE |
++		   MT_INT_TX_DONE_BAND2;
++	mt76_wr(dev, MT_INT_MASK_CSR, irq_mask);
++	mtk_wed_device_start_hw_rro(&mdev->mmio.wed, irq_mask, false);
++	mt7996_irq_enable(dev, irq_mask);
++
++	return 0;
+ }
++#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
+ 
+ int mt7996_dma_init(struct mt7996_dev *dev)
+ {
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
++	u32 rx_base;
+ 	u32 hif1_ofs = 0;
+ 	int ret;
+ 
+@@ -265,10 +410,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	mt7996_dma_disable(dev, true);
+ 
+ 	/* init tx queue */
+-	ret = mt76_connac_init_tx_queues(dev->phy.mt76,
+-					 MT_TXQ_ID(dev->mphy.band_idx),
+-					 MT7996_TX_RING_SIZE,
+-					 MT_TXQ_RING_BASE(0), 0);
++	ret = mt7996_init_tx_queues(&dev->phy,
++				    MT_TXQ_ID(dev->mphy.band_idx),
++				    MT7996_TX_RING_SIZE,
++				    MT_TXQ_RING_BASE(0),
++				    wed);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -315,6 +461,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		return ret;
+ 
+ 	/* rx data queue for band0 and band1 */
++	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
++		dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
++		dev->mt76.q_rx[MT_RXQ_MAIN].wed = wed;
++	}
++
+ 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
+ 			       MT_RXQ_ID(MT_RXQ_MAIN),
+ 			       MT7996_RX_RING_SIZE,
+@@ -324,6 +475,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		return ret;
+ 
+ 	/* tx free notify event from WA for band0 */
++	if (mtk_wed_device_active(wed) && !dev->has_rro) {
++		dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
++		dev->mt76.q_rx[MT_RXQ_MAIN_WA].wed = wed;
++	}
++
+ 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA],
+ 			       MT_RXQ_ID(MT_RXQ_MAIN_WA),
+ 			       MT7996_RX_MCU_RING_SIZE,
+@@ -334,17 +490,23 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 
+ 	if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
+ 		/* rx data queue for band2 */
++		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
+ 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ 				       MT_RXQ_ID(MT_RXQ_BAND2),
+ 				       MT7996_RX_RING_SIZE,
+ 				       MT_RX_BUF_SIZE,
+-				       MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs);
++				       rx_base);
+ 		if (ret)
+ 			return ret;
+ 
+ 		/* tx free notify event from WA for band2
+ 		 * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
+ 		 */
++		if (mtk_wed_device_active(wed_hif2) && !dev->has_rro) {
++			dev->mt76.q_rx[MT_RXQ_BAND2_WA].flags = MT_WED_Q_TXFREE;
++			dev->mt76.q_rx[MT_RXQ_BAND2_WA].wed = wed_hif2;
++		}
++
+ 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2_WA],
+ 				       MT_RXQ_ID(MT_RXQ_BAND2_WA),
+ 				       MT7996_RX_MCU_RING_SIZE,
+@@ -354,6 +516,60 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 			return ret;
+ 	}
+ 
++	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
++	    dev->has_rro) {
++		/* rx rro data queue for band0 */
++		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags =
++			MT_WED_RRO_Q_DATA(0) | MT_QFLAG_WED_RRO_EN;
++		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].wed = wed;
++		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
++				       MT_RXQ_ID(MT_RXQ_RRO_BAND0),
++				       MT7996_RX_RING_SIZE,
++				       MT7996_RX_BUF_SIZE,
++				       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0));
++		if (ret)
++			return ret;
++
++		/* tx free notify event from WA for band0 */
++		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
++		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].wed = wed;
++
++		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,
++				       MT7996_RX_BUF_SIZE,
++				       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
++		if (ret)
++			return ret;
++
++		if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
++			/* rx rro data queue for band2 */
++			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags =
++				MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
++			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].wed = wed;
++			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
++					       MT_RXQ_ID(MT_RXQ_RRO_BAND2),
++					       MT7996_RX_RING_SIZE,
++					       MT7996_RX_BUF_SIZE,
++					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND2) + hif1_ofs);
++			if (ret)
++				return ret;
++
++			/* tx free notify event from MAC for band2 */
++			if (mtk_wed_device_active(wed_hif2)) {
++				dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].flags = MT_WED_Q_TXFREE;
++				dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].wed = wed_hif2;
++			}
++			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2],
++					       MT_RXQ_ID(MT_RXQ_TXFREE_BAND2),
++					       MT7996_RX_MCU_RING_SIZE,
++					       MT7996_RX_BUF_SIZE,
++					       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND2) + hif1_ofs);
++			if (ret)
++				return ret;
++		}
++	}
++
+ 	ret = mt76_init_queues(dev, mt76_dma_rx_poll);
+ 	if (ret < 0)
+ 		return ret;
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 12c2513..d335b58 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -155,7 +155,7 @@ mt7996_regd_notifier(struct wiphy *wiphy,
+ }
+ 
+ static void
+-mt7996_init_wiphy(struct ieee80211_hw *hw)
++mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
+ {
+ 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ 	struct mt76_dev *mdev = &phy->dev->mt76;
+@@ -167,6 +167,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ 	hw->max_rx_aggregation_subframes = max_subframes;
+ 	hw->max_tx_aggregation_subframes = max_subframes;
+ 	hw->netdev_features = NETIF_F_RXCSUM;
++	if (mtk_wed_device_active(wed))
++		hw->netdev_features |= NETIF_F_HW_TC;
+ 
+ 	hw->radiotap_timestamp.units_pos =
+ 		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
+@@ -312,8 +314,13 @@ void mt7996_mac_init(struct mt7996_dev *dev)
+ 
+ 	/* rro module init */
+ 	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
+-	mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
+-	mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
++	if (dev->has_rro) {
++		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);
++		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
++	} else {
++		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
++		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
++	}
+ 
+ 	mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
+ 			  MCU_WA_PARAM_HW_PATH_HIF_VER,
+@@ -350,6 +357,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 	struct mt76_phy *mphy;
+ 	u32 mac_ofs, hif1_ofs = 0;
+ 	int ret;
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ 
+ 	if (band != MT_BAND1 && band != MT_BAND2)
+ 		return 0;
+@@ -361,8 +369,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 	if (phy)
+ 		return 0;
+ 
+-	if (band == MT_BAND2 && dev->hif2)
++	if (band == MT_BAND2 && dev->hif2) {
+ 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++		wed = &dev->mt76.mmio.wed_hif2;
++	}
+ 
+ 	mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);
+ 	if (!mphy)
+@@ -395,11 +405,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 	mt76_eeprom_override(mphy);
+ 
+ 	/* init wiphy according to mphy and phy */
+-	mt7996_init_wiphy(mphy->hw);
+-	ret = mt76_connac_init_tx_queues(phy->mt76,
+-					 MT_TXQ_ID(band),
+-					 MT7996_TX_RING_SIZE,
+-					 MT_TXQ_RING_BASE(band) + hif1_ofs, 0);
++	mt7996_init_wiphy(mphy->hw, wed);
++	ret = mt7996_init_tx_queues(mphy->priv,
++				    MT_TXQ_ID(band),
++				    MT7996_TX_RING_SIZE,
++				    MT_TXQ_RING_BASE(band) + hif1_ofs,
++				    wed);
+ 	if (ret)
+ 		goto error;
+ 
+@@ -412,6 +423,13 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 	if (ret)
+ 		goto error;
+ 
++	if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {
++		u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;
++
++		mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
++		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
++	}
++
+ 	return 0;
+ 
+ error:
+@@ -456,6 +474,120 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
+ 	msleep(20);
+ }
+ 
++static int mt7996_wed_rro_init(struct mt7996_dev *dev)
++{
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++	u32 reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
++	struct mt7996_wed_rro_addr *addr;
++	void *ptr;
++	int i;
++
++	if (!dev->has_rro)
++		return 0;
++
++	if (!mtk_wed_device_active(wed))
++		return 0;
++
++	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {
++		ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
++					  MT7996_RRO_BA_BITMAP_CR_SIZE,
++					  &dev->wed_rro.ba_bitmap[i].phy_addr,
++					  GFP_KERNEL);
++		if (!ptr)
++			return -ENOMEM;
++
++		dev->wed_rro.ba_bitmap[i].ptr = ptr;
++	}
++
++	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
++		int j;
++
++		ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
++				MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr),
++				&dev->wed_rro.addr_elem[i].phy_addr,
++				GFP_KERNEL);
++		if (!ptr)
++			return -ENOMEM;
++
++		dev->wed_rro.addr_elem[i].ptr = ptr;
++		memset(dev->wed_rro.addr_elem[i].ptr, 0,
++		       MT7996_RRO_WINDOW_MAX_SIZE * sizeof(*addr));
++
++		addr = dev->wed_rro.addr_elem[i].ptr;
++		for (j = 0; j < MT7996_RRO_WINDOW_MAX_SIZE; j++) {
++			addr->signature = 0xff;
++			addr++;
++		}
++
++		wed->wlan.ind_cmd.addr_elem_phys[i] =
++			dev->wed_rro.addr_elem[i].phy_addr;
++	}
++
++	ptr = dmam_alloc_coherent(dev->mt76.dma_dev,
++				  MT7996_RRO_WINDOW_MAX_LEN * sizeof(*addr),
++				  &dev->wed_rro.session.phy_addr,
++				  GFP_KERNEL);
++	if (!ptr)
++		return -ENOMEM;
++
++	dev->wed_rro.session.ptr = ptr;
++	addr = dev->wed_rro.session.ptr;
++	for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
++		addr->signature = 0xff;
++		addr++;
++	}
++
++	/* rro hw init */
++	/* TODO: remove line after WM has set */
++	mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
++
++	/* setup BA bitmap cache address */
++	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
++		dev->wed_rro.ba_bitmap[0].phy_addr);
++	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
++	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
++		dev->wed_rro.ba_bitmap[1].phy_addr);
++	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
++
++	/* setup Address element address */
++	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
++		mt76_wr(dev, reg, dev->wed_rro.addr_elem[i].phy_addr >> 4);
++		reg += 4;
++	}
++
++	/* setup Address element address - separate address segment mode */
++	mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
++		MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
++
++	wed->wlan.ind_cmd.win_size = ffs(MT7996_RRO_WINDOW_MAX_LEN) - 6;
++	wed->wlan.ind_cmd.particular_sid = MT7996_RRO_MAX_SESSION;
++	wed->wlan.ind_cmd.particular_se_phys = dev->wed_rro.session.phy_addr;
++	wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_LEN;
++	wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
++
++	mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
++	mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
++		 MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
++
++	/* particular session configure */
++	/* use max session idx + 1 as particular session id */
++	mt76_wr(dev, MT_RRO_PARTICULAR_CFG0, dev->wed_rro.session.phy_addr);
++	mt76_wr(dev, MT_RRO_PARTICULAR_CFG1,
++		MT_RRO_PARTICULAR_CONFG_EN |
++		FIELD_PREP(MT_RRO_PARTICULAR_SID, MT7996_RRO_MAX_SESSION));
++
++	/* interrupt enable */
++	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
++		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
++
++	/* rro ind cmd queue init */
++	return mt7996_dma_rro_init(dev);
++#else
++	return 0;
++#endif
++}
++
+ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ {
+ 	int ret, idx;
+@@ -477,6 +609,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	ret = mt7996_wed_rro_init(dev);
++	if (ret)
++		return ret;
++
+ 	ret = mt7996_eeprom_init(dev);
+ 	if (ret < 0)
+ 		return ret;
+@@ -884,7 +1020,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
+-	mt7996_init_wiphy(hw);
++	mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);
+ 
+ 	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
+ 				   ARRAY_SIZE(mt76_rates));
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 1a1e218..4be5410 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -449,8 +449,36 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
+ 	return 0;
+ }
+ 
++static void
++mt7996_wed_check_ppe(struct mt7996_dev *dev, struct mt76_queue *q,
++		     struct mt7996_sta *msta, struct sk_buff *skb,
++		     u32 info)
++{
++	struct ieee80211_vif *vif;
++	struct wireless_dev *wdev;
++
++	if (!msta || !msta->vif)
++		return;
++
++	if (!mt76_queue_is_wed_rx(q))
++		return;
++
++	if (!(info & MT_DMA_INFO_PPE_VLD))
++		return;
++
++	vif = container_of((void *)msta->vif, struct ieee80211_vif,
++			   drv_priv);
++	wdev = ieee80211_vif_to_wdev(vif);
++	skb->dev = wdev->netdev;
++
++	mtk_wed_device_ppe_check(&dev->mt76.mmio.wed, skb,
++				 FIELD_GET(MT_DMA_PPE_CPU_REASON, info),
++				 FIELD_GET(MT_DMA_PPE_ENTRY, info));
++}
++
+ static int
+-mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
++mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
++		   struct sk_buff *skb, u32 *info)
+ {
+ 	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+ 	struct mt76_phy *mphy = &dev->mt76.phy;
+@@ -475,7 +503,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	u16 seq_ctrl = 0;
+ 	__le16 fc = 0;
+ 	int idx;
++	u8 hw_aggr = false;
++	struct mt7996_sta *msta = NULL;
+ 
++	hw_aggr = status->aggr;
+ 	memset(status, 0, sizeof(*status));
+ 
+ 	band_idx = FIELD_GET(MT_RXD1_NORMAL_BAND_IDX, rxd1);
+@@ -502,8 +533,6 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ 	status->wcid = mt7996_rx_get_wcid(dev, idx, unicast);
+ 
+ 	if (status->wcid) {
+-		struct mt7996_sta *msta;
+-
+ 		msta = container_of(status->wcid, struct mt7996_sta, wcid);
+ 		spin_lock_bh(&dev->mt76.sta_poll_lock);
+ 		if (list_empty(&msta->wcid.poll_list))
+@@ -708,12 +737,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ 		}
+ 	} else {
+ 		status->flag |= RX_FLAG_8023;
++		mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
++				     *info);
+ 	}
+ 
+ 	if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
+ 		mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
+ 
+-	if (!status->wcid || !ieee80211_is_data_qos(fc))
++	if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
+ 		return 0;
+ 
+ 	status->aggr = unicast &&
+@@ -1010,6 +1041,29 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 	return 0;
+ }
+ 
++u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
++{
++	struct mt76_connac_fw_txp *txp = ptr + MT_TXD_SIZE;
++	__le32 *txwi = ptr;
++	u32 val;
++
++	memset(ptr, 0, MT_TXD_SIZE + sizeof(*txp));
++
++	val = FIELD_PREP(MT_TXD0_TX_BYTES, MT_TXD_SIZE) |
++	      FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CT);
++	txwi[0] = cpu_to_le32(val);
++
++	val = BIT(31) |
++	      FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3);
++	txwi[1] = cpu_to_le32(val);
++
++	txp->token = cpu_to_le16(token_id);
++	txp->nbuf = 1;
++	txp->buf[0] = cpu_to_le32(phys + MT_TXD_SIZE + sizeof(*txp));
++
++	return MT_TXD_SIZE + sizeof(*txp);
++}
++
+ static void
+ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+ {
+@@ -1388,6 +1442,12 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 
+ 	switch (type) {
+ 	case PKT_TYPE_TXRX_NOTIFY:
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2) &&
++		    q == MT_RXQ_TXFREE_BAND2) {
++			dev_kfree_skb(skb);
++			break;
++		}
++
+ 		mt7996_mac_tx_free(dev, skb->data, skb->len);
+ 		napi_consume_skb(skb, 1);
+ 		break;
+@@ -1404,7 +1464,7 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 		dev_kfree_skb(skb);
+ 		break;
+ 	case PKT_TYPE_NORMAL:
+-		if (!mt7996_mac_fill_rx(dev, skb)) {
++		if (!mt7996_mac_fill_rx(dev, q, skb, info)) {
+ 			mt76_rx(&dev->mt76, q, skb);
+ 			return;
+ 		}
+@@ -1862,7 +1922,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+ 
+ 	/* enable DMA Tx/Tx and interrupt */
+-	mt7996_dma_start(dev, false);
++	mt7996_dma_start(dev, false, false);
+ 
+ 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ 	clear_bit(MT76_RESET, &dev->mphy.state);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index a2ab668..ae4f0ce 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1368,6 +1368,44 @@ out:
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++static int
++mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
++			     struct ieee80211_vif *vif,
++			     struct ieee80211_sta *sta,
++			     struct net_device_path_ctx *ctx,
++			     struct net_device_path *path)
++{
++	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
++	struct mt7996_dev *dev = mt7996_hw_dev(hw);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++
++	if (phy != &dev->phy && phy->mt76->band_idx == MT_BAND2)
++		wed = &dev->mt76.mmio.wed_hif2;
++
++	if (!mtk_wed_device_active(wed))
++		return -ENODEV;
++
++	if (msta->wcid.idx > MT7996_WTBL_STA)
++		return -EIO;
++
++	path->type = DEV_PATH_MTK_WDMA;
++	path->dev = ctx->dev;
++	path->mtk_wdma.wdma_idx = wed->wdma_idx;
++	path->mtk_wdma.bss = mvif->mt76.idx;
++	path->mtk_wdma.queue = 0;
++	path->mtk_wdma.wcid = msta->wcid.idx;
++
++	path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);
++	ctx->dev = NULL;
++
++	return 0;
++}
++
++#endif
++
+ const struct ieee80211_ops mt7996_ops = {
+ 	.tx = mt7996_tx,
+ 	.start = mt7996_start,
+@@ -1412,4 +1450,8 @@ const struct ieee80211_ops mt7996_ops = {
+ 	.sta_add_debugfs = mt7996_sta_add_debugfs,
+ #endif
+ 	.set_radar_background = mt7996_set_radar_background,
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++	.net_fill_forward_path = mt7996_net_fill_forward_path,
++	.net_setup_tc = mt76_net_setup_tc,
++#endif
+ };
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 12bf4e5..3ff70c6 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -912,7 +912,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
+ }
+ 
+ static int
+-mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
++mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif,
+ 		  struct ieee80211_ampdu_params *params,
+ 		  bool enable, bool tx)
+ {
+@@ -921,7 +921,7 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+ 	struct sk_buff *skb;
+ 	struct tlv *tlv;
+ 
+-	skb = __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid,
++	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mvif, wcid,
+ 					      MT7996_STA_UPDATE_MAX_SIZE);
+ 	if (IS_ERR(skb))
+ 		return PTR_ERR(skb);
+@@ -935,8 +935,9 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+ 	ba->ba_en = enable << params->tid;
+ 	ba->amsdu = params->amsdu;
+ 	ba->tid = params->tid;
++	ba->ba_rdd_rro = !tx && enable && dev->has_rro;
+ 
+-	return mt76_mcu_skb_send_msg(dev, skb,
++	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ 				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
+ }
+ 
+@@ -951,8 +952,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
+ 	if (enable && !params->amsdu)
+ 		msta->wcid.amsdu = false;
+ 
+-	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
+-				 enable, true);
++	return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, true);
+ }
+ 
+ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+@@ -962,8 +962,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+ 	struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;
+ 	struct mt7996_vif *mvif = msta->vif;
+ 
+-	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
+-				 enable, false);
++	return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, false);
+ }
+ 
+ static void
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 3a591a7..c7b6d4b 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -10,6 +10,10 @@
+ #include "mt7996.h"
+ #include "mac.h"
+ #include "../trace.h"
++#include "../dma.h"
++
++static bool wed_enable;
++module_param(wed_enable, bool, 0644);
+ 
+ static const struct __base mt7996_reg_base[] = {
+ 	[WF_AGG_BASE]		= { { 0x820e2000, 0x820f2000, 0x830e2000 } },
+@@ -191,6 +195,143 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ 	return dev->bus_ops->rmw(mdev, __mt7996_reg_addr(dev, offset), mask, val);
+ }
+ 
++int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
++			 bool hif2, int *irq)
++{
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++	struct pci_dev *pci_dev = pdev_ptr;
++	u32 hif1_ofs = 0;
++	int ret;
++
++	if (!wed_enable)
++		return 0;
++
++	dev->has_rro = true;
++
++	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++	if (hif2)
++		wed = &dev->mt76.mmio.wed_hif2;
++
++	wed->wlan.pci_dev = pci_dev;
++	wed->wlan.bus_type = MTK_WED_BUS_PCIE;
++
++	wed->wlan.base = devm_ioremap(dev->mt76.dev,
++				      pci_resource_start(pci_dev, 0),
++				      pci_resource_len(pci_dev, 0));
++	wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
++
++	if (hif2) {
++		wed->wlan.wpdma_int = wed->wlan.phy_base +
++				      MT_INT_PCIE1_SOURCE_CSR_EXT;
++		wed->wlan.wpdma_mask = wed->wlan.phy_base +
++				       MT_INT_PCIE1_MASK_CSR;
++		wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
++					     MT_TXQ_RING_BASE(0) +
++					     MT7996_TXQ_BAND2 * MT_RING_SIZE;
++		if (dev->has_rro) {
++			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
++						 MT_RXQ_RING_BASE(0) +
++						 MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
++			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
++		} else {
++			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
++						 MT_RXQ_RING_BASE(0) +
++						 MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
++			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
++		}
++
++		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
++		wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
++				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
++				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
++
++		wed->wlan.id = 0x7991;
++		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
++	} else {
++		wed->wlan.hw_rro = dev->has_rro; /* default on */
++		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
++		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
++		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
++				     MT7996_TXQ_BAND0 * MT_RING_SIZE;
++
++		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
++
++		wed->wlan.wpdma_rx = wed->wlan.phy_base +
++				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
++				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
++
++		wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
++					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
++					    MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
++		wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
++					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
++					    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
++		wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
++					MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
++					MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
++
++		wed->wlan.rx_nbuf = 65536;
++		wed->wlan.rx_npkt = dev->hif2 ? 32768 : 24576;
++		wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
++
++		wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
++		wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
++
++		wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
++		wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
++
++		wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
++		wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
++		wed->wlan.rx_pg_tbit[2] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND2) - 1;
++
++		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
++		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
++		if (dev->has_rro) {
++			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
++						 MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
++			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
++		} else {
++			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
++			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
++						  MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
++		}
++		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
++	}
++
++	wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
++	wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
++
++	wed->wlan.amsdu_max_subframes = 8;
++	wed->wlan.amsdu_max_len = 1536;
++
++	wed->wlan.init_buf = mt7996_wed_init_buf;
++	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
++	wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
++	wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
++	wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
++
++	if (mtk_wed_device_attach(wed))
++		return 0;
++
++	*irq = wed->irq;
++	dev->mt76.dma_dev = wed->dev;
++
++	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
++	if (ret)
++		return ret;
++
++	ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
++	if (ret)
++		return ret;
++
++	return 1;
++#else
++	return 0;
++#endif
++}
++
+ static int mt7996_mmio_init(struct mt76_dev *mdev,
+ 			    void __iomem *mem_base,
+ 			    u32 device_id)
+@@ -241,8 +382,17 @@ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
+ 	mdev->mmio.irqmask |= set;
+ 
+ 	if (write_reg) {
+-		mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
+-		mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
++		if (mtk_wed_device_active(&mdev->mmio.wed)) {
++			mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
++						    mdev->mmio.irqmask);
++			if (mtk_wed_device_active(&mdev->mmio.wed_hif2)) {
++				mtk_wed_device_irq_set_mask(&mdev->mmio.wed_hif2,
++							    mdev->mmio.irqmask);
++			}
++		} else {
++			mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
++			mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
++		}
+ 	}
+ 
+ 	spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
+@@ -260,22 +410,36 @@ static void mt7996_rx_poll_complete(struct mt76_dev *mdev,
+ static void mt7996_irq_tasklet(struct tasklet_struct *t)
+ {
+ 	struct mt7996_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);
++	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
+ 	u32 i, intr, mask, intr1;
+ 
+-	mt76_wr(dev, MT_INT_MASK_CSR, 0);
+-	if (dev->hif2)
+-		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+-
+-	intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
+-	intr &= dev->mt76.mmio.irqmask;
+-	mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+-
+-	if (dev->hif2) {
+-		intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
+-		intr1 &= dev->mt76.mmio.irqmask;
+-		mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
++	if (dev->hif2 && mtk_wed_device_active(wed_hif2)) {
++		mtk_wed_device_irq_set_mask(wed_hif2, 0);
++		intr1 = mtk_wed_device_irq_get(wed_hif2,
++					       dev->mt76.mmio.irqmask);
++		if (intr1 & MT_INT_RX_TXFREE_EXT)
++			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
++	}
+ 
+-		intr |= intr1;
++	if (mtk_wed_device_active(wed)) {
++		mtk_wed_device_irq_set_mask(wed, 0);
++		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
++		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
++	} else {
++		mt76_wr(dev, MT_INT_MASK_CSR, 0);
++		if (dev->hif2)
++			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
++
++		intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
++		intr &= dev->mt76.mmio.irqmask;
++		mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
++		if (dev->hif2) {
++			intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
++			intr1 &= dev->mt76.mmio.irqmask;
++			mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
++			intr |= intr1;
++		}
+ 	}
+ 
+ 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
+@@ -308,9 +472,17 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
+ {
+ 	struct mt7996_dev *dev = dev_instance;
+ 
+-	mt76_wr(dev, MT_INT_MASK_CSR, 0);
+-	if (dev->hif2)
+-		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++		mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed, 0);
++	else
++		mt76_wr(dev, MT_INT_MASK_CSR, 0);
++
++	if (dev->hif2) {
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
++			mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_hif2, 0);
++		else
++			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
++	}
+ 
+ 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
+ 		return IRQ_NONE;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 7354e5c..c541eaa 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -37,6 +37,7 @@
+ #define MT7996_EEPROM_SIZE		7680
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+ #define MT7996_TOKEN_SIZE		16384
++#define MT7996_HW_TOKEN_SIZE		8192
+ 
+ #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
+ #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
+@@ -49,6 +50,22 @@
+ #define MT7996_BASIC_RATES_TBL		11
+ #define MT7996_BEACON_RATES_TBL		25
+ 
++#define MT7996_RRO_MAX_SESSION		1024
++#define MT7996_RRO_WINDOW_MAX_LEN	1024
++#define MT7996_RRO_ADDR_ELEM_LEN	128
++#define MT7996_RRO_BA_BITMAP_LEN	2
++#define MT7996_RRO_BA_BITMAP_CR_SIZE	((MT7996_RRO_MAX_SESSION * 128) /	\
++					 MT7996_RRO_BA_BITMAP_LEN)
++#define MT7996_RRO_BA_BITMAP_SESSION_SIZE	(MT7996_RRO_MAX_SESSION /	\
++						 MT7996_RRO_ADDR_ELEM_LEN)
++#define MT7996_RRO_WINDOW_MAX_SIZE	(MT7996_RRO_WINDOW_MAX_LEN *		\
++					 MT7996_RRO_BA_BITMAP_SESSION_SIZE)
++
++#define MT7996_RX_BUF_SIZE		(1800 + \
++					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
++#define MT7996_RX_MSDU_PAGE_SIZE	(128 + \
++					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -78,6 +95,16 @@ enum mt7996_rxq_id {
+ 	MT7996_RXQ_BAND0 = 4,
+ 	MT7996_RXQ_BAND1 = 4,/* unused */
+ 	MT7996_RXQ_BAND2 = 5,
++	MT7996_RXQ_RRO_BAND0 = 8,
++	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
++	MT7996_RXQ_RRO_BAND2 = 6,
++	MT7996_RXQ_MSDU_PG_BAND0 = 10,
++	MT7996_RXQ_MSDU_PG_BAND1 = 11,
++	MT7996_RXQ_MSDU_PG_BAND2 = 12,
++	MT7996_RXQ_TXFREE0 = 9,
++	MT7996_RXQ_TXFREE1 = 9,
++	MT7996_RXQ_TXFREE2 = 7,
++	MT7996_RXQ_RRO_IND = 0,
+ };
+ 
+ struct mt7996_twt_flow {
+@@ -147,6 +174,15 @@ struct mt7996_hif {
+ 	int irq;
+ };
+ 
++struct mt7996_wed_rro_addr {
++	u32 head_low;
++	u32 head_high : 4;
++	u32 count: 11;
++	u32 oor: 1;
++	u32 rsv : 8;
++	u32 signature : 8;
++};
++
+ struct mt7996_phy {
+ 	struct mt76_phy *mt76;
+ 	struct mt7996_dev *dev;
+@@ -226,6 +262,22 @@ struct mt7996_dev {
+ 	bool tbtc_support:1;
+ 	bool flash_mode:1;
+ 	bool has_eht:1;
++	bool has_rro:1;
++
++	struct {
++		struct {
++			void *ptr;
++			dma_addr_t phy_addr;
++		} ba_bitmap[MT7996_RRO_BA_BITMAP_LEN];
++		struct {
++			void *ptr;
++			dma_addr_t phy_addr;
++		} addr_elem[MT7996_RRO_ADDR_ELEM_LEN];
++		struct {
++			void *ptr;
++			dma_addr_t phy_addr;
++		} session;
++	} wed_rro;
+ 
+ 	bool ibf;
+ 	u8 fw_debug_wm;
+@@ -335,7 +387,9 @@ 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_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset);
++int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
++			  int n_desc, int ring_base, struct mtk_wed_device *wed);
+ void mt7996_init_txpower(struct mt7996_dev *dev,
+ 			 struct ieee80211_supported_band *sband);
+ int mt7996_txbf_init(struct mt7996_dev *dev);
+@@ -495,5 +549,16 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			    struct ieee80211_sta *sta, struct dentry *dir);
+ #endif
++int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
++			 bool hif2, int *irq);
++u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
++
++#ifdef CONFIG_MTK_DEBUG
++int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
++#endif
++
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++int mt7996_dma_rro_init(struct mt7996_dev *dev);
++#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
+ 
+ #endif
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index c530105..92869ca 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -125,15 +125,26 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 	mt7996_wfsys_reset(dev);
+ 	hif2 = mt7996_pci_init_hif2(pdev);
+ 
+-	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
++	ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
+ 	if (ret < 0)
+-		goto free_device;
++		goto free_wed_or_irq_vector;
+ 
+-	irq = pdev->irq;
+-	ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
++	if (!ret) {
++		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
++		if (ret < 0)
++			goto free_device;
++	}
++	ret = devm_request_irq(mdev->dev, pdev->irq, mt7996_irq_handler,
+ 			       IRQF_SHARED, KBUILD_MODNAME, dev);
+ 	if (ret)
+-		goto free_irq_vector;
++		goto free_wed_or_irq_vector;
++
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
++		ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
++				       IRQF_SHARED, KBUILD_MODNAME "-wed", dev);
++		if (ret)
++			goto free_irq;
++	}
+ 
+ 	mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ 	/* master switch of PCIe tnterrupt enable */
+@@ -143,16 +154,30 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 		hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
+ 		dev->hif2 = hif2;
+ 
+-		ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
++		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &irq);
+ 		if (ret < 0)
+-			goto free_hif2;
++			goto free_irq;
++
++		if (!ret) {
++			ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
++			if (ret < 0)
++				goto free_hif2;
+ 
+-		dev->hif2->irq = hif2_dev->irq;
+-		ret = devm_request_irq(mdev->dev, dev->hif2->irq,
+-				       mt7996_irq_handler, IRQF_SHARED,
+-				       KBUILD_MODNAME "-hif", dev);
++			dev->hif2->irq = hif2_dev->irq;
++		}
++
++		ret = devm_request_irq(mdev->dev, hif2_dev->irq, mt7996_irq_handler,
++				       IRQF_SHARED, KBUILD_MODNAME "-hif", dev);
+ 		if (ret)
+-			goto free_hif2_irq_vector;
++			goto free_hif2;
++
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
++			ret = devm_request_irq(mdev->dev, irq,
++					       mt7996_irq_handler, IRQF_SHARED,
++					       KBUILD_MODNAME "-wed-hif", dev);
++			if (ret)
++				goto free_hif2_irq_vector;
++		}
+ 
+ 		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ 		/* master switch of PCIe tnterrupt enable */
+@@ -168,15 +193,28 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ free_hif2_irq:
+ 	if (dev->hif2)
+ 		devm_free_irq(mdev->dev, dev->hif2->irq, dev);
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
++		devm_free_irq(mdev->dev, dev->mt76.mmio.wed_hif2.irq, dev);
+ free_hif2_irq_vector:
+-	if (dev->hif2)
+-		pci_free_irq_vectors(hif2_dev);
++	if (dev->hif2) {
++		if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
++			mtk_wed_device_detach(&dev->mt76.mmio.wed_hif2);
++		else
++			pci_free_irq_vectors(hif2_dev);
++	}
+ free_hif2:
+ 	if (dev->hif2)
+ 		put_device(dev->hif2->dev);
+-	devm_free_irq(mdev->dev, irq, dev);
+-free_irq_vector:
+-	pci_free_irq_vectors(pdev);
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++		devm_free_irq(mdev->dev, dev->mt76.mmio.wed.irq, dev);
++free_irq:
++	devm_free_irq(mdev->dev, pdev->irq, dev);
++free_wed_or_irq_vector:
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++		mtk_wed_device_detach(&dev->mt76.mmio.wed);
++	else
++		pci_free_irq_vectors(pdev);
++
+ free_device:
+ 	mt76_free_device(&dev->mt76);
+ 
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 5702290..854390d 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -39,6 +39,38 @@ enum base_rev {
+ 
+ #define __BASE(_id, _band)			(dev->reg.base[(_id)].band_base[(_band)])
+ 
++/* RRO TOP */
++#define MT_RRO_TOP_BASE				0xA000
++#define MT_RRO_TOP(ofs)				(MT_RRO_TOP_BASE + (ofs))
++
++#define MT_RRO_BA_BITMAP_BASE0			MT_RRO_TOP(0x8)
++#define MT_RRO_BA_BITMAP_BASE1			MT_RRO_TOP(0xC)
++#define WF_RRO_AXI_MST_CFG			MT_RRO_TOP(0xB8)
++#define WF_RRO_AXI_MST_CFG_DIDX_OK		BIT(12)
++#define MT_RRO_ADDR_ARRAY_BASE1			MT_RRO_TOP(0x34)
++#define MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE	BIT(31)
++
++#define MT_RRO_IND_CMD_SIGNATURE_BASE0		MT_RRO_TOP(0x38)
++#define MT_RRO_IND_CMD_SIGNATURE_BASE1		MT_RRO_TOP(0x3C)
++#define MT_RRO_IND_CMD_0_CTRL0			MT_RRO_TOP(0x40)
++#define MT_RRO_IND_CMD_SIGNATURE_BASE1_EN	BIT(31)
++
++#define MT_RRO_PARTICULAR_CFG0			MT_RRO_TOP(0x5C)
++#define MT_RRO_PARTICULAR_CFG1			MT_RRO_TOP(0x60)
++#define MT_RRO_PARTICULAR_CONFG_EN		BIT(31)
++#define MT_RRO_PARTICULAR_SID			GENMASK(30, 16)
++
++#define MT_RRO_BA_BITMAP_BASE_EXT0		MT_RRO_TOP(0x70)
++#define MT_RRO_BA_BITMAP_BASE_EXT1		MT_RRO_TOP(0x74)
++#define MT_RRO_HOST_INT_ENA			MT_RRO_TOP(0x204)
++#define MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA   BIT(0)
++
++#define MT_RRO_ADDR_ELEM_SEG_ADDR0		MT_RRO_TOP(0x400)
++
++#define MT_RRO_ACK_SN_CTRL			MT_RRO_TOP(0x50)
++#define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
++#define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
++
+ #define MT_MCU_INT_EVENT			0x2108
+ #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
+ #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
+@@ -323,6 +355,7 @@ enum base_rev {
+ 
+ #define MT_WFDMA0_RX_INT_PCIE_SEL		MT_WFDMA0(0x154)
+ #define MT_WFDMA0_RX_INT_SEL_RING3		BIT(3)
++#define MT_WFDMA0_RX_INT_SEL_RING6		BIT(6)
+ 
+ #define MT_WFDMA0_MCU_HOST_INT_ENA		MT_WFDMA0(0x1f4)
+ 
+@@ -367,6 +400,9 @@ enum base_rev {
+ #define MT_WFDMA0_PCIE1_BASE			0xd8000
+ #define MT_WFDMA0_PCIE1(ofs)			(MT_WFDMA0_PCIE1_BASE + (ofs))
+ 
++#define MT_INT_PCIE1_SOURCE_CSR_EXT		MT_WFDMA0_PCIE1(0x118)
++#define MT_INT_PCIE1_MASK_CSR			MT_WFDMA0_PCIE1(0x11c)
++
+ #define MT_WFDMA0_PCIE1_BUSY_ENA		MT_WFDMA0_PCIE1(0x13c)
+ #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0	BIT(0)
+ #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1	BIT(1)
+@@ -387,6 +423,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)
++#define MT_RXQ_RRO_IND_RING_BASE		MT_RRO_TOP(0x40)
+ 
+ #define MT_MCUQ_EXT_CTRL(q)			(MT_Q_BASE(q) +	0x600 +	\
+ 						 MT_MCUQ_ID(q) * 0x4)
+@@ -412,6 +449,15 @@ enum base_rev {
+ #define MT_INT_RX_TXFREE_MAIN			BIT(17)
+ #define MT_INT_RX_TXFREE_TRI			BIT(15)
+ #define MT_INT_MCU_CMD				BIT(29)
++#define MT_INT_RX_TXFREE_EXT			BIT(26)
++
++#define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
++#define MT_INT_RX_DONE_RRO_BAND1		BIT(16)
++#define MT_INT_RX_DONE_RRO_BAND2		BIT(14)
++#define MT_INT_RX_DONE_RRO_IND			BIT(11)
++#define MT_INT_RX_DONE_MSDU_PG_BAND0		BIT(18)
++#define MT_INT_RX_DONE_MSDU_PG_BAND1		BIT(19)
++#define MT_INT_RX_DONE_MSDU_PG_BAND2		BIT(23)
+ 
+ #define MT_INT_RX(q)				(dev->q_int_mask[__RXQ(q)])
+ #define MT_INT_TX_MCU(q)			(dev->q_int_mask[(q)])
+@@ -420,20 +466,31 @@ enum base_rev {
+ 						 MT_INT_RX(MT_RXQ_MCU_WA))
+ 
+ #define MT_INT_BAND0_RX_DONE			(MT_INT_RX(MT_RXQ_MAIN) |	\
+-						 MT_INT_RX(MT_RXQ_MAIN_WA))
++						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
++						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
+ 
+ #define MT_INT_BAND1_RX_DONE			(MT_INT_RX(MT_RXQ_BAND1) |	\
+ 						 MT_INT_RX(MT_RXQ_BAND1_WA) |	\
+-						 MT_INT_RX(MT_RXQ_MAIN_WA))
++						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
++						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
+ 
+ #define MT_INT_BAND2_RX_DONE			(MT_INT_RX(MT_RXQ_BAND2) |	\
+ 						 MT_INT_RX(MT_RXQ_BAND2_WA) |	\
+-						 MT_INT_RX(MT_RXQ_MAIN_WA))
++						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
++						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
++
++#define MT_INT_RRO_RX_DONE			(MT_INT_RX(MT_RXQ_RRO_BAND0) |		\
++						 MT_INT_RX(MT_RXQ_RRO_BAND1) |		\
++						 MT_INT_RX(MT_RXQ_RRO_BAND2) |		\
++						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND0) |	\
++						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND1) |	\
++						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND2))
+ 
+ #define MT_INT_RX_DONE_ALL			(MT_INT_RX_DONE_MCU |		\
+ 						 MT_INT_BAND0_RX_DONE |		\
+ 						 MT_INT_BAND1_RX_DONE |		\
+-						 MT_INT_BAND2_RX_DONE)
++						 MT_INT_BAND2_RX_DONE |		\
++						 MT_INT_RRO_RX_DONE)
+ 
+ #define MT_INT_TX_DONE_FWDL			BIT(26)
+ #define MT_INT_TX_DONE_MCU_WM			BIT(27)
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0002-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
similarity index 90%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0002-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
index 0478681..c657c5b 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0002-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0003-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
@@ -1,7 +1,7 @@
-From 2327076bc0ae52d057204b337d7b1503f097dfbf Mon Sep 17 00:00:00 2001
+From 0d8aff6fa4ee351350dda83f8cc7ca2b557322ac Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Fri, 14 Apr 2023 16:51:59 +0800
-Subject: [PATCH 02/22] wifi: mt76: mt7996: add support for auxiliary path
+Subject: [PATCH 03/98] wifi: mt76: mt7996: add support for auxiliary path
 
 Add support to correctly configure the setting of variants that have
 additional TX or RX path.
@@ -17,7 +17,7 @@
  4 files changed, 35 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 544b6c6f1..9db7e5310 100644
+index 544b6c6..9db7e53 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -148,36 +148,49 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
@@ -75,7 +75,7 @@
  	mphy->antenna_mask = BIT(nss) - 1;
  	mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 0c749774f..412d6e2f8 100644
+index 0c74977..412d6e2 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -33,6 +33,9 @@ enum mt7996_eeprom_field {
@@ -89,10 +89,10 @@
  #define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1	GENMASK(2, 0)
  #define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2	GENMASK(5, 3)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 12bf4e503..d422214e2 100644
+index 3ff70c6..328bea9 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3179,7 +3179,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
+@@ -3178,7 +3178,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
  		.center_ch = ieee80211_frequency_to_channel(freq1),
  		.bw = mt76_connac_chan_bw(chandef),
  		.tx_path_num = hweight16(phy->mt76->chainmask),
@@ -102,10 +102,10 @@
  		.channel_band = ch_band[chandef->chan->band],
  	};
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 7354e5cf8..25a563f74 100644
+index c541eaa..ef84173 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -170,6 +170,8 @@ struct mt7996_phy {
+@@ -206,6 +206,8 @@ struct mt7996_phy {
  
  	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
@@ -114,7 +114,7 @@
  };
  
  struct mt7996_dev {
-@@ -437,6 +439,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
+@@ -491,6 +493,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
  void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
  			  size_t len);
  
@@ -134,5 +134,5 @@
  u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
  bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0003-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
similarity index 87%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0003-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
index e6be9b8..bb8761d 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0003-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0004-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
@@ -1,7 +1,7 @@
-From 55edd1cc06062fc6a71426e062a253eafc48d575 Mon Sep 17 00:00:00 2001
+From f6b0399c4e70fb8fa521d53e59bc933e491271c3 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 20 Apr 2023 16:34:47 +0800
-Subject: [PATCH 03/22] wifi: mt76: mt7996: add eht mode tx stats
+Subject: [PATCH 04/98] wifi: mt76: mt7996: add eht mode tx stats
 
 Add eht mode bf fbk stats and bw320 through debugfs tx_stats command
 
@@ -11,7 +11,7 @@
  1 file changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 4d40ec7ff..9bd953586 100644
+index 4d40ec7..9bd9535 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
 @@ -476,7 +476,7 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
@@ -35,5 +35,5 @@
  		   mib->tx_bf_rx_fb_vht_cnt,
  		   mib->tx_bf_rx_fb_ht_cnt);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0004-wifi-mt76-mt7996-add-thermal-protection-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch
similarity index 90%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0004-wifi-mt76-mt7996-add-thermal-protection-support.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch
index 2f79dac..9d85c7c 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0004-wifi-mt76-mt7996-add-thermal-protection-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0005-wifi-mt76-mt7996-add-thermal-protection-support.patch
@@ -1,7 +1,7 @@
-From c348e633baeb810556505bfd98c09c8527e43ae8 Mon Sep 17 00:00:00 2001
+From c4d8ad5eb5f4d9929e923fa2c0683a2e24d8ca0c Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 2 Feb 2023 21:20:31 +0800
-Subject: [PATCH 04/22] wifi: mt76: mt7996: add thermal protection support
+Subject: [PATCH 05/98] wifi: mt76: mt7996: add thermal protection support
 
 This commit includes the following changes:
 1. implement MTK thermal protection driver API
@@ -10,15 +10,15 @@
 Change-Id: I8fecc28f5b17ee50ae4644d1dd17d188dd694731
 ---
  mt76_connac_mcu.h |   1 +
- mt7996/init.c     | 103 ++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/init.c     | 103 +++++++++++++++++++++++++++++++++++++++++++++
  mt7996/main.c     |   8 ++++
- mt7996/mcu.c      | 106 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.c      | 105 ++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.h      |  44 +++++++++++++++++++
  mt7996/mt7996.h   |  15 +++++++
- 6 files changed, 277 insertions(+)
+ 6 files changed, 276 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6064973f9..99077f1fc 100644
+index 6064973..99077f1 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
 @@ -1021,6 +1021,7 @@ enum {
@@ -30,7 +30,7 @@
  };
  
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 12c251382..ccfa511ea 100644
+index d335b58..610d80e 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
 @@ -42,6 +42,98 @@ static const struct ieee80211_iface_combination if_comb[] = {
@@ -132,7 +132,7 @@
  static void mt7996_led_set_config(struct led_classdev *led_cdev,
  				  u8 delay_on, u8 delay_off)
  {
-@@ -408,6 +500,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -419,6 +511,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	if (ret)
  		goto error;
  
@@ -143,7 +143,7 @@
  	ret = mt7996_init_debugfs(phy);
  	if (ret)
  		goto error;
-@@ -428,6 +524,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
+@@ -446,6 +542,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
  	if (!phy)
  		return;
  
@@ -152,7 +152,7 @@
  	mphy = phy->dev->mt76.phys[band];
  	mt76_unregister_phy(mphy);
  	ieee80211_free_hw(mphy->hw);
-@@ -891,6 +989,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1027,6 +1125,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -163,7 +163,7 @@
  	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
  
  	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
-@@ -914,6 +1016,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
+@@ -1050,6 +1152,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
  {
  	mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
  	mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
@@ -172,7 +172,7 @@
  	mt76_unregister_device(&dev->mt76);
  	mt7996_mcu_exit(dev);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index a2ab668a3..ec25351cc 100644
+index ae4f0ce..280120b 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -51,6 +51,14 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -191,7 +191,7 @@
  
  	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index d422214e2..ff6b82a9f 100644
+index 328bea9..5310f9b 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -449,6 +449,34 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -239,7 +239,7 @@
  	default:
  		break;
  	}
-@@ -3451,6 +3482,81 @@ out:
+@@ -3450,6 +3481,80 @@ out:
  	return 0;
  }
  
@@ -307,8 +307,7 @@
 +
 +	/* set high-temperature trigger threshold */
 +	req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_ENABLE);
-+	/* add a safety margin ~10 */
-+	req.enable.restore_temp = cpu_to_le32(phy->throttle_temp[0] - 10);
++	req.enable.restore_temp = cpu_to_le32(phy->throttle_temp[0]);
 +	req.enable.trigger_temp = cpu_to_le32(phy->throttle_temp[1]);
 +	req.enable.sustain_time = cpu_to_le16(SUSTAIN_PERIOD);
 +
@@ -322,7 +321,7 @@
  {
  	struct {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index e4b31228b..f1528df82 100644
+index e4b3122..f1528df 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -30,6 +30,28 @@ struct mt7996_mcu_uni_event {
@@ -391,10 +390,10 @@
  	UNI_CMD_ACCESS_REG_BASIC = 0x0,
  	UNI_CMD_ACCESS_RF_REG_BASIC,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 25a563f74..810a472ea 100644
+index ef84173..e1972e9 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -49,6 +49,13 @@
+@@ -50,6 +50,13 @@
  #define MT7996_BASIC_RATES_TBL		11
  #define MT7996_BEACON_RATES_TBL		25
  
@@ -405,10 +404,10 @@
 +#define MT7996_CRIT_TEMP		110
 +#define MT7996_MAX_TEMP			120
 +
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -155,6 +162,11 @@ struct mt7996_phy {
+ #define MT7996_RRO_MAX_SESSION		1024
+ #define MT7996_RRO_WINDOW_MAX_LEN	1024
+ #define MT7996_RRO_ADDR_ELEM_LEN	128
+@@ -191,6 +198,11 @@ struct mt7996_phy {
  
  	struct ieee80211_vif *monitor_vif;
  
@@ -420,7 +419,7 @@
  	u32 rxfilter;
  	u64 omac_mask;
  
-@@ -391,6 +403,9 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
+@@ -445,6 +457,9 @@ 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);
@@ -431,5 +430,5 @@
  		       u8 rx_sel, u8 val);
  int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0005-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
similarity index 84%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0005-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
index e054827..a4338f3 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0005-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0006-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
@@ -1,15 +1,15 @@
-From 4df411cd61129d17fcaf39c8a588f8b64aaf147c Mon Sep 17 00:00:00 2001
+From 3bf4da3eba0f082ec3be1c0ee603cbae3e9d9fbb Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Thu, 2 Feb 2023 20:53:42 +0800
-Subject: [PATCH 05/22] wifi: mt76: mt7996: add thermal sensor device support
+Subject: [PATCH 06/98] wifi: mt76: mt7996: add thermal sensor device support
 
 ---
- mt7996/init.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/init.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.c  | 41 ++++++++++++++++++++++++
- 2 files changed, 128 insertions(+)
+ 2 files changed, 129 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index ccfa511ea..5f10d87bb 100644
+index 610d80e..de4a5f7 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
 @@ -4,6 +4,8 @@
@@ -21,7 +21,7 @@
  #include <linux/thermal.h>
  #include "mt7996.h"
  #include "mac.h"
-@@ -42,6 +44,81 @@ static const struct ieee80211_iface_combination if_comb[] = {
+@@ -42,6 +44,82 @@ static const struct ieee80211_iface_combination if_comb[] = {
  	}
  };
  
@@ -66,12 +66,13 @@
 +	mutex_lock(&phy->dev->mt76.mutex);
 +	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130);
 +
++	/* add a safety margin ~10 */
 +	if ((i - 1 == MT7996_CRIT_TEMP_IDX &&
-+	     val > phy->throttle_temp[MT7996_MAX_TEMP_IDX]) ||
++	     val > phy->throttle_temp[MT7996_MAX_TEMP_IDX] - 10) ||
 +	    (i - 1 == MT7996_MAX_TEMP_IDX &&
-+	     val < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
++	     val - 10 < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
 +		dev_err(phy->dev->mt76.dev,
-+			"temp1_max shall be greater than temp1_crit.");
++			"temp1_max shall be 10 degrees higher than temp1_crit.");
 +		mutex_unlock(&phy->dev->mt76.mutex);
 +		return -EINVAL;
 +	}
@@ -103,7 +104,7 @@
  static int
  mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
  				      unsigned long *state)
-@@ -113,6 +190,7 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+@@ -113,6 +191,7 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
  {
  	struct wiphy *wiphy = phy->mt76->hw->wiphy;
  	struct thermal_cooling_device *cdev;
@@ -111,7 +112,7 @@
  	const char *name;
  
  	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",
-@@ -131,6 +209,15 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+@@ -131,6 +210,15 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
  	phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;
  	phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;
  
@@ -128,10 +129,10 @@
  }
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index ff6b82a9f..c3666c925 100644
+index 5310f9b..8320c8c 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3482,6 +3482,47 @@ out:
+@@ -3481,6 +3481,47 @@ out:
  	return 0;
  }
  
@@ -180,5 +181,5 @@
  int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)
  {
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0006-wifi-mt76-mt7996-make-band-capability-init-flexible.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
similarity index 65%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0006-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
index d6e7363..873029f 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0006-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0007-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
@@ -1,7 +1,7 @@
-From 3121e46d58e1fe871e2940c9b2e38e448a07585e Mon Sep 17 00:00:00 2001
+From 3fdeeee1f24b09fc0d08b6a386e06c6146e83d9c Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 23 May 2023 15:49:03 +0800
-Subject: [PATCH 06/22] wifi: mt76: mt7996: make band capability init flexible
+Subject: [PATCH 07/98] wifi: mt76: mt7996: make band capability init flexible
 
 There're some variations of mt7996 chipset which only support two-band,
 so parse the adie combination to correctly set band capability.
@@ -9,20 +9,20 @@
 Change-Id: Ifcb49504f02f5cc6a23c626e30b4f0e1360fe157
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 ---
- mt7996/dma.c    |  8 ++++----
+ mt7996/dma.c    | 14 +++++++-------
  mt7996/init.c   | 29 ++++++++++++++++++-----------
  mt7996/mcu.c    | 13 +++++--------
  mt7996/mt7996.h | 11 +++++++++++
  mt7996/regs.h   |  3 +++
- 5 files changed, 41 insertions(+), 23 deletions(-)
+ 5 files changed, 44 insertions(+), 26 deletions(-)
 
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 586e247a1..f5118d054 100644
+index 2221d22..3d04470 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -159,13 +159,13 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- 
- 	irq_mask = MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
+@@ -222,13 +222,13 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
+ 	/* enable interrupts for TX/RX rings */
+ 	irq_mask = MT_INT_MCU_CMD | MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
  
 -	if (!dev->mphy.band_idx)
 +	if (mt7996_band_valid(dev, MT_BAND0))
@@ -36,23 +36,50 @@
 +	if (mt7996_band_valid(dev, MT_BAND2))
  		irq_mask |= MT_INT_BAND2_RX_DONE;
  
- done:
-@@ -332,7 +332,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	if (mtk_wed_device_active(wed) && wed_reset) {
+@@ -354,7 +354,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
+-	if (dev->dbdc_support) {
++	if (mt7996_band_valid(dev, MT_BAND1)) {
+ 		/* rx msdu page queue for band1 */
+ 		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags =
+ 			MT_WED_RRO_Q_MSDU_PG(1) | MT_QFLAG_WED_RRO_EN;
+@@ -368,7 +368,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
+ 			return ret;
+ 	}
+ 
+-	if (dev->tbtc_support) {
++	if (mt7996_band_valid(dev, MT_BAND2)) {
+ 		/* rx msdu page queue for band2 */
+ 		mdev->q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags =
+ 			MT_WED_RRO_Q_MSDU_PG(2) | MT_QFLAG_WED_RRO_EN;
+@@ -488,7 +488,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
 -	if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
 +	if (mt7996_band_valid(dev, MT_BAND2)) {
  		/* rx data queue for band2 */
+ 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
  		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
+@@ -542,7 +542,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		if (ret)
+ 			return ret;
+ 
+-		if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
++		if (mt7996_band_valid(dev, MT_BAND2)) {
+ 			/* rx rro data queue for band2 */
+ 			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags =
+ 				MT_WED_RRO_Q_DATA(1) | MT_QFLAG_WED_RRO_EN;
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 5f10d87bb..c86c70c22 100644
+index de4a5f7..2e6efc5 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -530,11 +530,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	u32 mac_ofs, hif1_ofs = 0;
+@@ -539,11 +539,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	int ret;
+ 	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
  
 -	if (band != MT_BAND1 && band != MT_BAND2)
 -		return 0;
@@ -63,7 +90,7 @@
  		return 0;
  
  	if (phy)
-@@ -649,8 +645,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -782,8 +778,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  
  	INIT_WORK(&dev->init_work, mt7996_init_work);
  
@@ -76,7 +103,7 @@
  
  	ret = mt7996_dma_init(dev);
  	if (ret)
-@@ -1080,8 +1078,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1217,8 +1215,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -85,7 +112,7 @@
  	ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
  	if (ret)
  		return ret;
-@@ -1090,13 +1086,24 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1227,13 +1223,24 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -113,10 +140,10 @@
  
  void mt7996_unregister_device(struct mt7996_dev *dev)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index c3666c925..49bd398a2 100644
+index 8320c8c..84f362b 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2768,7 +2768,7 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
+@@ -2767,7 +2767,7 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
  {
  	struct uni_header hdr = {};
  	struct sk_buff *skb;
@@ -125,7 +152,7 @@
  
  	num = 2 + 2 * (dev->dbdc_support + dev->tbtc_support);
  	len = sizeof(hdr) + num * sizeof(struct vow_rx_airtime);
-@@ -2778,13 +2778,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
+@@ -2777,13 +2777,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
  
  	skb_put_data(skb, &hdr, sizeof(hdr));
  
@@ -144,10 +171,10 @@
  	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
  				     MCU_WM_UNI_CMD(VOW), true);
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 810a472ea..230d9ee79 100644
+index e1972e9..137d5a2 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -329,6 +329,17 @@ mt7996_phy3(struct mt7996_dev *dev)
+@@ -381,6 +381,17 @@ mt7996_phy3(struct mt7996_dev *dev)
  	return __mt7996_phy(dev, MT_BAND2);
  }
  
@@ -166,10 +193,10 @@
  extern struct pci_driver mt7996_pci_driver;
  extern struct pci_driver mt7996_hif_driver;
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 570229062..3d32f1e9a 100644
+index 854390d..a4d5ad8 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -545,6 +545,9 @@ enum base_rev {
+@@ -602,6 +602,9 @@ enum base_rev {
  #define MT_TOP_MISC				MT_TOP(0xf0)
  #define MT_TOP_MISC_FW_STATE			GENMASK(2, 0)
  
@@ -180,5 +207,5 @@
  #define MT_WF_SUBSYS_RST			0x70028600
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0007-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
similarity index 90%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0007-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
index 36a2f62..a5b808a 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0007-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0008-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
@@ -1,7 +1,7 @@
-From 907b2a98a0bae4db421767e9f52668f4534c337a Mon Sep 17 00:00:00 2001
+From 8f93c158b307ee75e622a5897499f5837c0d3446 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 12 May 2023 16:24:53 +0800
-Subject: [PATCH 07/22] wifi: mt76: mt7996: add beacon duplicate tx mode
+Subject: [PATCH 08/98] wifi: mt76: mt7996: add beacon duplicate tx mode
  support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,7 +16,7 @@
  7 files changed, 69 insertions(+), 25 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 99077f1fc..90c08d276 100644
+index 99077f1..90c08d2 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
 @@ -1239,6 +1239,7 @@ enum {
@@ -28,10 +28,10 @@
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
  	MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index c86c70c22..a8a60a8c9 100644
+index 2e6efc5..17a4abd 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -351,6 +351,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+@@ -354,6 +354,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
  		IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
  
  	phy->slottime = 9;
@@ -39,7 +39,7 @@
  
  	hw->sta_data_size = sizeof(struct mt7996_sta);
  	hw->vif_data_size = sizeof(struct mt7996_vif);
-@@ -460,11 +461,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
+@@ -463,11 +464,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
  
  	for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
  		u16 rate = mt76_rates[i].hw_value;
@@ -55,7 +55,7 @@
  }
  
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 1a1e21872..c20a6affc 100644
+index 4be5410..6688186 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
 @@ -248,17 +248,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
@@ -77,7 +77,7 @@
  static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
  {
 diff --git a/mt7996/main.c b/mt7996/main.c
-index ec25351cc..d8fd8191c 100644
+index 280120b..41f0fa1 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -522,24 +522,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -123,10 +123,10 @@
  
  	return 0;
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 49bd398a2..653c1d2b7 100644
+index 84f362b..dbb3ceb 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4057,6 +4057,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+@@ -4055,6 +4055,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
  				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
  }
  
@@ -164,7 +164,7 @@
  {
  	struct {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index f1528df82..c20a94788 100644
+index f1528df..c20a947 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -738,4 +738,24 @@ enum {
@@ -193,10 +193,10 @@
 +
  #endif
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 230d9ee79..56e2cef1a 100644
+index 137d5a2..21ad51d 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -46,7 +46,7 @@
+@@ -47,7 +47,7 @@
  #define MT7996_MAX_QUEUE		(__MT_RXQ_MAX +	__MT_MCUQ_MAX + 3)
  
  /* NOTE: used to map mt76_rates. idx may change if firmware expands table */
@@ -205,7 +205,7 @@
  #define MT7996_BEACON_RATES_TBL		25
  
  #define MT7996_THERMAL_THROTTLE_MAX	100
-@@ -177,6 +177,8 @@ struct mt7996_phy {
+@@ -213,6 +213,8 @@ struct mt7996_phy {
  
  	u8 rdd_state;
  
@@ -214,7 +214,7 @@
  	u32 rx_ampdu_ts;
  	u32 ampdu_ref;
  
-@@ -421,6 +423,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+@@ -475,6 +477,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
  		       u8 rx_sel, u8 val);
  int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
  				     struct cfg80211_chan_def *chandef);
@@ -223,7 +223,7 @@
  int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
  int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
  int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
-@@ -485,8 +489,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
+@@ -539,8 +543,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
  void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
  void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
  			      struct ieee80211_vif *vif, bool enable);
@@ -233,5 +233,5 @@
  			   struct sk_buff *skb, struct mt76_wcid *wcid,
  			   struct ieee80211_key_conf *key, int pid,
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0008-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
similarity index 74%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0008-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
index bf8d858..b151c94 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0008-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0009-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
@@ -1,7 +1,7 @@
-From f1efd2608cbdf962d18652e37522ab50e235c539 Mon Sep 17 00:00:00 2001
+From 3e4d68091c7b74769481acdf1b305fd1edb15d4d Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Tue, 30 May 2023 11:27:01 +0800
-Subject: [PATCH 08/22] wifi: mt76: mt7996: fix bss rate tlv to sync firmware
+Subject: [PATCH 09/98] wifi: mt76: mt7996: fix bss rate tlv to sync firmware
  change
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
@@ -10,7 +10,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index c20a94788..78ecd757e 100644
+index c20a947..78ecd75 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -259,7 +259,7 @@ struct bss_rate_tlv {
@@ -23,5 +23,5 @@
  
  struct bss_ra_tlv {
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0009-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
similarity index 77%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0009-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
index 607fabd..ca966b6 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0009-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0010-wifi-mt76-mt7996-adjust-wfdma-setting-to-enhance-thr.patch
@@ -1,7 +1,7 @@
-From 65b539b6e2d62f038c1a93f443a59f7457f91aab Mon Sep 17 00:00:00 2001
+From e1ddb78f4185559bc6f9be1d1b302f9f52899f94 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 09/22] wifi: mt76: mt7996: adjust wfdma setting to enhance
+Subject: [PATCH 10/98] wifi: mt76: mt7996: adjust wfdma setting to enhance
  throughput
 
 1. Set band 1 traffic to pcie1.
@@ -10,15 +10,15 @@
 
 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(-)
+ mt7996/dma.c  | 70 +++++++++++++++++++++++++++++++++++----------------
+ mt7996/regs.h |  9 +++++++
+ 2 files changed, 58 insertions(+), 21 deletions(-)
 
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index f5118d054..d4bbe9fb4 100644
+index 3d04470..1ed91da 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -56,22 +56,34 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+@@ -99,38 +99,49 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
  	MCUQ_CONFIG(MT_MCUQ_FWDL, WFDMA0, MT_INT_TX_DONE_FWDL, MT7996_TXQ_FWDL);
  }
  
@@ -62,11 +62,33 @@
 +	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 void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ 	if (dev->has_rro) {
+ 		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, 0x4));
++			PREFETCH(0x4));
+ 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
+-			PREFETCH(0x6a0, 0x4));
++			PREFETCH(0x4));
+ 	}
+ #undef PREFETCH
+ 
+@@ -295,6 +306,12 @@ static void 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);
  
@@ -79,7 +101,7 @@
  	if (dev->hif2) {
  		/* GLO_CFG_EXT0 */
  		mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
-@@ -234,7 +252,18 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+@@ -306,7 +323,18 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
  			 WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
  
  		mt76_set(dev, MT_WFDMA_HOST_CONFIG,
@@ -100,10 +122,10 @@
  
  	if (dev->hif2) {
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 3d32f1e9a..a5b370d1d 100644
+index a4d5ad8..f7c99cd 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -333,6 +333,11 @@ enum base_rev {
+@@ -366,6 +366,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)
  
@@ -115,7 +137,7 @@
  #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 {
+@@ -388,10 +393,14 @@ enum base_rev {
  
  #define MT_WFDMA_HOST_CONFIG			MT_WFDMA_EXT_CSR(0x30)
  #define MT_WFDMA_HOST_CONFIG_PDMA_BAND		BIT(0)
@@ -131,5 +153,5 @@
  #define MT_PCIE_RECOG_ID_MASK			GENMASK(30, 0)
  #define MT_PCIE_RECOG_ID_SEM			BIT(31)
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0010-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
similarity index 82%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0010-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
index 9f0aa6b..d32dea5 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0010-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-fill-txd-bandwidth-filed-value-for-.patch
@@ -1,7 +1,7 @@
-From db3aa2948cee6fce2c2cc17d4c5a4a0c31b6365d Mon Sep 17 00:00:00 2001
+From bae9e0c386cd710bdf414b0e0e097ea95812673e Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Wed, 6 Sep 2023 14:51:00 +0800
-Subject: [PATCH 10/22] wifi: mt76: mt7996: fill txd bandwidth filed value for
+Subject: [PATCH 11/98] wifi: mt76: mt7996: fill txd bandwidth filed value for
  fixed rate frame
 
 Fill bw field value for fixed rate enabled frame to keep it be sent by bw20.
@@ -16,7 +16,7 @@
  2 files changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index 87bfa441a..df6b02af9 100644
+index 87bfa44..df6b02a 100644
 --- a/mt76_connac3_mac.h
 +++ b/mt76_connac3_mac.h
 @@ -239,6 +239,7 @@ enum tx_mgnt_type {
@@ -28,10 +28,10 @@
  #define MT_TXD6_TX_RATE			GENMASK(21, 16)
  #define MT_TXD6_TIMESTAMP_OFS_EN	BIT(15)
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index c20a6affc..38822402b 100644
+index 6688186..2c6bee4 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -912,7 +912,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+@@ -943,7 +943,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
  				idx = mvif->basic_rates_idx;
  		}
  
@@ -42,5 +42,5 @@
  	}
  }
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
similarity index 81%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
index 310479f..3a49f34 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0012-wifi-mt76-mt7996-add-IEEE80211_RC_SMPS_CHANGED-handl.patch
@@ -1,7 +1,7 @@
-From c308bd889a207eff9382126f697da59243b593e4 Mon Sep 17 00:00:00 2001
+From 2d7f3506aa6759fa1a7667d53bf88eb543035c33 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Mon, 24 Jul 2023 16:32:03 +0800
-Subject: [PATCH 11/22] wifi: mt76: mt7996: add IEEE80211_RC_SMPS_CHANGED
+Subject: [PATCH 12/98] wifi: mt76: mt7996: add IEEE80211_RC_SMPS_CHANGED
  handler
 
 Send mcu command to firmware to handle smps mode.
@@ -14,10 +14,10 @@
  3 files changed, 10 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 38822402b..fd1edf140 100644
+index 2c6bee4..ccb7b22 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -2162,7 +2162,9 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
+@@ -2222,7 +2222,9 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
  			       IEEE80211_RC_BW_CHANGED))
  			mt7996_mcu_add_rate_ctrl(dev, vif, sta, true);
  
@@ -29,10 +29,10 @@
  		spin_lock_bh(&dev->mt76.sta_poll_lock);
  	}
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 653c1d2b7..a5cfd40f9 100644
+index dbb3ceb..18c3f34 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1680,9 +1680,8 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
+@@ -1679,9 +1679,8 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
  				     MCU_WM_UNI_CMD(RA), true);
  }
  
@@ -44,7 +44,7 @@
  {
  	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
  	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-@@ -1710,6 +1709,9 @@ mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -1709,6 +1708,9 @@ mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  		if (phy)
  			ra->phy = *phy;
  		break;
@@ -55,10 +55,10 @@
  		break;
  	}
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 56e2cef1a..890f522d9 100644
+index 21ad51d..c8e7a33 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -397,6 +397,8 @@ int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif,
+@@ -451,6 +451,8 @@ int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif,
  int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  			     struct ieee80211_sta *sta, bool changed);
  int mt7996_set_channel(struct mt7996_phy *phy);
@@ -68,5 +68,5 @@
  int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif);
  int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0012-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
similarity index 88%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0012-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
index 26f923e..5f85886 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0012-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0013-wifi-mt76-mt7996-fix-mcu-command-format-to-align-fir.patch
@@ -1,7 +1,7 @@
-From d1cc4c8da42cf8e3feef5a75611eefd8bf693823 Mon Sep 17 00:00:00 2001
+From 8c79e229decdc24af9e95e6396699b3723f7efc4 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Fri, 7 Jul 2023 10:35:05 +0800
-Subject: [PATCH 12/22] wifi: mt76: mt7996: fix mcu command format to align
+Subject: [PATCH 13/98] wifi: mt76: mt7996: fix mcu command format to align
  firmware
 
 Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
@@ -11,10 +11,10 @@
  2 files changed, 75 insertions(+), 8 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a5cfd40f9..9dfee8292 100644
+index 18c3f34..ee1915c 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1685,8 +1685,8 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif
+@@ -1684,8 +1684,8 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif
  {
  	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
  	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
@@ -25,7 +25,7 @@
  	struct sk_buff *skb;
  	struct tlv *tlv;
  
-@@ -1697,7 +1697,7 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif
+@@ -1696,7 +1696,7 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif
  		return PTR_ERR(skb);
  
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
@@ -34,7 +34,7 @@
  
  	switch (field) {
  	case RATE_PARAM_AUTO:
-@@ -1729,7 +1729,7 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif
+@@ -1728,7 +1728,7 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif
  	struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
  	struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
  	enum nl80211_band band = chandef->chan->band;
@@ -43,7 +43,7 @@
  	int ret, nrates = 0;
  
  #define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he)			\
-@@ -1817,13 +1817,13 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
+@@ -1816,13 +1816,13 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
  	struct cfg80211_chan_def *chandef = &mphy->chandef;
  	struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
  	enum nl80211_band band = chandef->chan->band;
@@ -60,7 +60,7 @@
  	ra->valid = true;
  	ra->auto_rate = true;
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 78ecd757e..05785cb9f 100644
+index 78ecd75..05785cb 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -433,6 +433,73 @@ struct sta_rec_sec_uni {
@@ -150,5 +150,5 @@
  					 sizeof(struct sta_rec_eht) +		\
  					 sizeof(struct sta_rec_hdrt) +		\
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0013-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
similarity index 84%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0013-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
index f05595a..1a93d0b 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0013-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0014-wifi-mt76-mt7996-add-lock-for-indirect-register-acce.patch
@@ -1,7 +1,7 @@
-From 843b9adeef21e5e3e574baea8391a929bf48412a Mon Sep 17 00:00:00 2001
+From 6a8359a808df29b708b2fd2aa84c0a369be7a7d5 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Mon, 3 Jul 2023 22:38:43 +0800
-Subject: [PATCH 13/22] wifi: mt76: mt7996: add lock for indirect register
+Subject: [PATCH 14/98] wifi: mt76: mt7996: add lock for indirect register
  access
 
 Some races were observed during indirect register access, fix this
@@ -10,15 +10,15 @@
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 Change-Id: I0de2cd27df9ccb7f9a7d9ce265e869175b1ca7f1
 ---
- mt7996/mmio.c   | 68 +++++++++++++++++++++++++++++++++----------------
+ mt7996/mmio.c   | 69 +++++++++++++++++++++++++++++++++----------------
  mt7996/mt7996.h |  3 +--
- 2 files changed, 47 insertions(+), 24 deletions(-)
+ 2 files changed, 48 insertions(+), 24 deletions(-)
 
 diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 3a591a7b4..d5eaa1bcf 100644
+index c7b6d4b..ab088a2 100644
 --- a/mt7996/mmio.c
 +++ b/mt7996/mmio.c
-@@ -82,7 +82,6 @@ static u32 mt7996_reg_map_l1(struct mt7996_dev *dev, u32 addr)
+@@ -86,7 +86,6 @@ static u32 mt7996_reg_map_l1(struct mt7996_dev *dev, u32 addr)
  	u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);
  	u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);
  
@@ -26,7 +26,7 @@
  	dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L1,
  			  MT_HIF_REMAP_L1_MASK,
  			  FIELD_PREP(MT_HIF_REMAP_L1_MASK, base));
-@@ -97,7 +96,6 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
+@@ -101,7 +100,6 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
  	u32 offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET, addr);
  	u32 base = FIELD_GET(MT_HIF_REMAP_L2_BASE, addr);
  
@@ -34,7 +34,7 @@
  	dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2,
  			  MT_HIF_REMAP_L2_MASK,
  			  FIELD_PREP(MT_HIF_REMAP_L2_MASK, base));
-@@ -107,26 +105,10 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
+@@ -111,26 +109,10 @@ static u32 mt7996_reg_map_l2(struct mt7996_dev *dev, u32 addr)
  	return MT_HIF_REMAP_BASE_L2 + offset;
  }
  
@@ -61,7 +61,7 @@
  	if (addr < 0x100000)
  		return addr;
  
-@@ -143,6 +125,11 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
+@@ -147,6 +129,11 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr)
  		return dev->reg.map[i].mapped + ofs;
  	}
  
@@ -73,13 +73,13 @@
  	if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) ||
  	    (addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) ||
  	    (addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END))
-@@ -166,29 +153,65 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
- 			  size_t len)
+@@ -171,28 +158,65 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
  {
  	u32 addr = __mt7996_reg_addr(dev, offset);
-+	unsigned long flags;
  
 -	memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
++	unsigned long flags;
++
 +	if (addr) {
 +		memcpy_fromio(buf, dev->mt76.mmio.regs + addr, len);
 +		return;
@@ -142,8 +142,8 @@
 +	return val;
  }
  
- static int mt7996_mmio_init(struct mt76_dev *mdev,
-@@ -200,6 +223,7 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
+ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+@@ -341,6 +365,7 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
  
  	dev = container_of(mdev, struct mt7996_dev, mt76);
  	mt76_mmio_init(&dev->mt76, mem_base);
@@ -152,10 +152,10 @@
  	switch (device_id) {
  	case 0x7990:
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 890f522d9..ea1104845 100644
+index c8e7a33..c0ceef0 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -257,8 +257,7 @@ struct mt7996_dev {
+@@ -309,8 +309,7 @@ struct mt7996_dev {
  		u8 n_agrt;
  	} twt;
  
@@ -166,5 +166,5 @@
  	u8 wtbl_size_group;
  };
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0014-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
similarity index 85%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0014-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
index 6079c79..381c929 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0014-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0015-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
@@ -1,7 +1,7 @@
-From 8fecc721eb37961a4eb2238be62d83d70a368c59 Mon Sep 17 00:00:00 2001
+From 09a1b2d9ad49d3bea1bdd8d4f7326af6a65a3dbb Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 16 Feb 2023 13:53:14 +0800
-Subject: [PATCH 14/22] wifi: mt76: connac: set correct muar_idx for connac3
+Subject: [PATCH 15/98] wifi: mt76: connac: set correct muar_idx for connac3
  chipset
 
 Set the muar_idx to 0xe for the hw bcast/mcast station entry of connac3
@@ -15,7 +15,7 @@
  2 files changed, 8 insertions(+)
 
 diff --git a/mt76_connac.h b/mt76_connac.h
-index 1f29d8cd9..fa742b9ae 100644
+index e5ebde1..c6726ab 100644
 --- a/mt76_connac.h
 +++ b/mt76_connac.h
 @@ -245,6 +245,11 @@ static inline bool is_connac_v1(struct mt76_dev *dev)
@@ -31,7 +31,7 @@
  {
  	switch (mt76_chip(dev)) {
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index bcd6c20f3..68de52535 100644
+index bcd6c20..68de525 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -282,6 +282,9 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
@@ -45,5 +45,5 @@
  				     &hdr.wlan_idx_hi);
  	skb = mt76_mcu_msg_alloc(dev, NULL, len);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0015-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
similarity index 94%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0015-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
index ada5073..a850a6c 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0015-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0016-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
@@ -1,7 +1,7 @@
-From 92894504b24036f011244a5e270b045c1617156c Mon Sep 17 00:00:00 2001
+From 4d055393b680ce616cb96f75cca154016cfb9a68 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Fri, 19 May 2023 14:16:50 +0800
-Subject: [PATCH 15/22] wifi: mt76: mt7996: add firmware WA's coredump.
+Subject: [PATCH 16/98] wifi: mt76: mt7996: add firmware WA's coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 Change-Id: I51f115b4ae15bc0f871f93652570d72511dbf880
@@ -15,7 +15,7 @@
  6 files changed, 182 insertions(+), 83 deletions(-)
 
 diff --git a/mt7996/coredump.c b/mt7996/coredump.c
-index ccab0d7b9..60b88085c 100644
+index ccab0d7..60b8808 100644
 --- a/mt7996/coredump.c
 +++ b/mt7996/coredump.c
 @@ -7,11 +7,11 @@
@@ -336,7 +336,7 @@
  }
  
 diff --git a/mt7996/coredump.h b/mt7996/coredump.h
-index af2ba219b..01ed3731c 100644
+index af2ba21..01ed373 100644
 --- a/mt7996/coredump.h
 +++ b/mt7996/coredump.h
 @@ -6,10 +6,13 @@
@@ -429,10 +429,10 @@
  	return NULL;
  }
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index fd1edf140..0aabded63 100644
+index ccb7b22..066955e 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1902,28 +1902,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -1962,28 +1962,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
  }
  
  /* firmware coredump */
@@ -465,7 +465,7 @@
  	if (!mem_region || !crash_data->memdump_buf_len) {
  		mutex_unlock(&dev->dump_mutex);
  		goto skip_memdump;
-@@ -1933,6 +1930,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -1993,6 +1990,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	buf_len = crash_data->memdump_buf_len;
  
  	/* dumping memory content... */
@@ -475,7 +475,7 @@
  	memset(buf, 0, buf_len);
  	for (i = 0; i < num; i++) {
  		if (mem_region->len > buf_len) {
-@@ -1949,6 +1949,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2009,6 +2009,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
  		mt7996_memcpy_fromio(dev, buf, mem_region->start,
  				     mem_region->len);
  
@@ -483,7 +483,7 @@
  		hdr->start = mem_region->start;
  		hdr->len = mem_region->len;
  
-@@ -1965,8 +1966,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2025,8 +2026,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	mutex_unlock(&dev->dump_mutex);
  
  skip_memdump:
@@ -507,10 +507,10 @@
  }
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 9dfee8292..56b2bbc69 100644
+index ee1915c..2c611e7 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2459,6 +2459,8 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
+@@ -2458,6 +2458,8 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
  
  	dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
  		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
@@ -519,7 +519,7 @@
  
  	for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
  		struct mt7996_patch_sec *sec;
-@@ -2585,6 +2587,9 @@ static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
+@@ -2584,6 +2586,9 @@ static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
  	}
  
  	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
@@ -530,19 +530,19 @@
  		 fw_type, hdr->fw_ver, hdr->build_date);
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index ea1104845..3ac354b18 100644
+index c0ceef0..0bb20a9 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -56,6 +56,8 @@
+@@ -57,6 +57,8 @@
  #define MT7996_CRIT_TEMP		110
  #define MT7996_MAX_TEMP			120
  
 +#define MT7996_BUILD_TIME_LEN		24
 +
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -65,6 +67,7 @@ enum mt7996_ram_type {
+ #define MT7996_RRO_MAX_SESSION		1024
+ #define MT7996_RRO_WINDOW_MAX_LEN	1024
+ #define MT7996_RRO_ADDR_ELEM_LEN	128
+@@ -82,6 +84,7 @@ enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
  	MT7996_RAM_TYPE_WA,
  	MT7996_RAM_TYPE_DSP,
@@ -550,7 +550,7 @@
  };
  
  enum mt7996_txq_id {
-@@ -229,9 +232,11 @@ struct mt7996_dev {
+@@ -265,9 +268,11 @@ struct mt7996_dev {
  	struct mutex dump_mutex;
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
@@ -564,10 +564,10 @@
  	struct list_head sta_rc_list;
  	struct list_head twt_list;
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index a5b370d1d..b5c363a6f 100644
+index f7c99cd..bd0eb51 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -491,7 +491,8 @@ enum base_rev {
+@@ -548,7 +548,8 @@ enum base_rev {
  
  /* FW MODE SYNC */
  #define MT_FW_ASSERT_CNT			0x02208274
@@ -577,7 +577,7 @@
  
  #define MT_SWDEF_BASE				0x00401400
  
-@@ -599,11 +600,15 @@ enum base_rev {
+@@ -656,11 +657,15 @@ enum base_rev {
  #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR		BIT(29)
  
  /* CONN MCU EXCP CON */
@@ -594,5 +594,5 @@
  
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0016-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
similarity index 86%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0016-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
index c6e5cb6..54d32c3 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0016-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0017-wifi-mt76-mt7996-get-tx_retries-and-tx_failed-from-t.patch
@@ -1,7 +1,7 @@
-From fd9cc614274b3bfbc1604c2a93cac2a1169e3518 Mon Sep 17 00:00:00 2001
+From ff0611f9ade6ea4e9d84b7bd852ff745c609500b Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 28 Jun 2023 07:51:38 +0800
-Subject: [PATCH 16/22] wifi: mt76: mt7996: get tx_retries and tx_failed from
+Subject: [PATCH 17/98] wifi: mt76: mt7996: get tx_retries and tx_failed from
  txfree for both wed on and wed off
 
 ---
@@ -11,7 +11,7 @@
  3 files changed, 24 insertions(+), 7 deletions(-)
 
 diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index df6b02af9..20a2fe931 100644
+index df6b02a..20a2fe9 100644
 --- a/mt76_connac3_mac.h
 +++ b/mt76_connac3_mac.h
 @@ -272,11 +272,11 @@ enum tx_mgnt_type {
@@ -29,10 +29,10 @@
  #define MT_TXFREE_INFO_COUNT		GENMASK(27, 24)
  #define MT_TXFREE_INFO_STAT		GENMASK(29, 28)
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 0aabded63..8f3742c4e 100644
+index 066955e..bdc90a0 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1065,6 +1065,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+@@ -1119,6 +1119,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
  	struct mt76_phy *phy3 = mdev->phys[MT_BAND2];
  	struct mt76_txwi_cache *txwi;
  	struct ieee80211_sta *sta = NULL;
@@ -40,7 +40,7 @@
  	LIST_HEAD(free_list);
  	struct sk_buff *skb, *tmp;
  	void *end = data + len;
-@@ -1083,7 +1084,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+@@ -1137,7 +1138,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
  		mt76_queue_tx_cleanup(dev, phy3->q_tx[MT_TXQ_BE], false);
  	}
  
@@ -49,7 +49,7 @@
  		return;
  
  	total = le32_get_bits(tx_free[0], MT_TXFREE0_MSDU_CNT);
-@@ -1099,10 +1100,9 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+@@ -1153,10 +1154,9 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
  		info = le32_to_cpu(*cur_info);
  		if (info & MT_TXFREE_INFO_PAIR) {
  			struct mt7996_sta *msta;
@@ -61,7 +61,7 @@
  			wcid = rcu_dereference(dev->mt76.wcid[idx]);
  			sta = wcid_to_sta(wcid);
  			if (!sta)
-@@ -1115,10 +1115,21 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+@@ -1169,10 +1169,21 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
  					      &mdev->sta_poll_list);
  			spin_unlock_bh(&mdev->sta_poll_lock);
  			continue;
@@ -86,7 +86,7 @@
  		for (i = 0; i < 2; i++) {
  			msdu = (info >> (15 * i)) & MT_TXFREE_INFO_MSDU_ID;
 diff --git a/mt7996/main.c b/mt7996/main.c
-index d8fd8191c..32d975c63 100644
+index 41f0fa1..f152e76 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -997,6 +997,12 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
@@ -103,5 +103,5 @@
  	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0017-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
similarity index 62%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0017-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
index d130143..5110644 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0017-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0018-wifi-mt76-mt7996-Add-mcu-commands-for-getting-sta-tx.patch
@@ -1,28 +1,23 @@
-From 19082cf5d84a2c1a8e92d525a96de49b08d086fd Mon Sep 17 00:00:00 2001
+From 63501a3e941097581dcee61a0149ee5bc944c579 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 28 Jun 2023 08:10:25 +0800
-Subject: [PATCH 17/22] wifi: mt76: mt7996: Add mcu commands for getting sta tx
+Subject: [PATCH 18/98] wifi: mt76: mt7996: Add mcu commands for getting sta tx
  statistic
 
-Add ALL_STA command to query station tx statistic from WM mcu.
-The commands are called periodically to query information from the WM mcu.
-The response events are sent as unsolicited event.
-
-We get tx bytes and rx bytes counts with tag UNI_ALL_STA_TXRX_ADM_STAT
-and get MSDU packet counts with tag UNI_ALL_STA_TRX_MSDU_COUNT.
-The MSDU packet counts are based on UWTBL DW10 and DW11.
-It's accumulative and not read-clear.
+Per peer Tx/Rx statistic can only be obtained by querying WM when WED is
+on. This patch switches to periodic event reporting in the case of WED
+being enabled.
 ---
  mt76_connac_mcu.h | 15 +++++++++++
- mt7996/mac.c      |  3 +++
- mt7996/main.c     | 12 +++++++++
+ mt7996/mac.c      |  5 ++++
+ mt7996/main.c     | 15 +++++++++++
  mt7996/mcu.c      | 68 +++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/mcu.h      | 29 ++++++++++++++++++++
+ mt7996/mcu.h      | 26 ++++++++++++++++++
  mt7996/mt7996.h   |  1 +
- 6 files changed, 128 insertions(+)
+ 6 files changed, 130 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 90c08d276..e9dd9aa64 100644
+index 90c08d2..e9dd9aa 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
 @@ -1023,6 +1023,8 @@ enum {
@@ -62,44 +57,56 @@
  	MT_NIC_CAP_TX_RESOURCE,
  	MT_NIC_CAP_TX_EFUSE_ADDR,
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 8f3742c4e..8f75da695 100644
+index bdc90a0..4828f10 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -2212,6 +2212,9 @@ void mt7996_mac_work(struct work_struct *work)
+@@ -2272,6 +2272,11 @@ void mt7996_mac_work(struct work_struct *work)
  		mphy->mac_work_count = 0;
  
  		mt7996_mac_update_stats(phy);
 +
-+		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
-+		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
++		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
++			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
++			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
++		};
  	}
  
  	mutex_unlock(&mphy->dev->mutex);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 32d975c63..284fb373b 100644
+index f152e76..e9e1fd9 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -1008,6 +1008,18 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
+@@ -977,6 +977,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
+ 				  struct ieee80211_sta *sta,
+ 				  struct station_info *sinfo)
+ {
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
+ 	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
+ 	struct rate_info *txrate = &msta->wcid.rate;
+ 
+@@ -1008,6 +1009,20 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
  
  	sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);
  	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
 +
-+	sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
++	if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
++		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
++		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
 +
-+	sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
++		sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
++		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
 +
-+	sinfo->tx_packets = msta->wcid.stats.tx_packets;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
++		sinfo->tx_packets = msta->wcid.stats.tx_packets;
++		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
 +
-+	sinfo->rx_packets = msta->wcid.stats.rx_packets;
-+	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
++		sinfo->rx_packets = msta->wcid.stats.rx_packets;
++		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
++	}
  }
  
  static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 56b2bbc69..146e284fc 100644
+index 2c611e7..652a600 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -477,6 +477,54 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -114,7 +121,7 @@
 +
 +	skb_pull(skb, sizeof(struct mt7996_mcu_rxd));
 +
-+	res = (struct mt7996_mcu_all_sta_info_event *) skb->data;
++	res = (struct mt7996_mcu_all_sta_info_event *)skb->data;
 +
 +	for (i = 0; i < le16_to_cpu(res->sta_num); i++) {
 +		u8 ac;
@@ -167,7 +174,7 @@
  	default:
  		break;
  	}
-@@ -4194,3 +4245,20 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
+@@ -4192,3 +4243,20 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
  	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req,
  				 sizeof(req), true);
  }
@@ -189,39 +196,36 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 05785cb9f..66af7a90f 100644
+index 05785cb..97151d1 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -191,6 +191,35 @@ struct mt7996_mcu_thermal_notify {
+@@ -191,6 +191,32 @@ struct mt7996_mcu_thermal_notify {
  	u8 __rsv2[4];
  } __packed;
  
-+struct all_sta_trx_adm_stat {
-+	__le16 wlan_idx;
-+	u8 __rsv[2];
-+	__le32 tx_bytes[IEEE80211_NUM_ACS];
-+	__le32 rx_bytes[IEEE80211_NUM_ACS];
-+} __packed;
-+
-+struct all_sta_trx_msdu_cnt {
-+	__le16 wlan_idx;
-+	u8 __rsv[2];
-+	__le32 tx_msdu_cnt;
-+	__le32 rx_msdu_cnt;
-+} __packed;
-+
 +struct mt7996_mcu_all_sta_info_event {
-+	u8 __rsv[4];
++	u8 rsv[4];
 +	__le16 tag;
 +	__le16 len;
 +        u8 more;
-+        u8 __rsv2;
++        u8 rsv2;
 +        __le16 sta_num;
-+        u8 __rsv3[2];
++        u8 rsv3[2];
 +
 +	union {
-+		struct all_sta_trx_adm_stat adm_stat[0];
-+		struct all_sta_trx_msdu_cnt msdu_cnt[0];
++		struct {
++			__le16 wlan_idx;
++			u8 rsv[2];
++			__le32 tx_bytes[IEEE80211_NUM_ACS];
++			__le32 rx_bytes[IEEE80211_NUM_ACS];
++		} adm_stat[0];
++
++		struct {
++			__le16 wlan_idx;
++			u8 rsv[2];
++			__le32 tx_msdu_cnt;
++			__le32 rx_msdu_cnt;
++		} msdu_cnt[0];
 +	};
 +} __packed;
 +
@@ -229,17 +233,17 @@
  	UNI_MIB_OBSS_AIRTIME = 26,
  	UNI_MIB_NON_WIFI_TIME = 27,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 3ac354b18..bf9960e30 100644
+index 0bb20a9..420d113 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -423,6 +423,7 @@ 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_get_temperature(struct mt7996_phy *phy);
+@@ -494,6 +494,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
+ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ void mt7996_mcu_exit(struct mt7996_dev *dev);
 +int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
- int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
- int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
- int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ 
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
+ {
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0018-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
similarity index 90%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0018-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
index 301cefd..6505422 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0018-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0019-wifi-mt76-mt7996-enable-PPDU-TxS-to-host.patch
@@ -1,7 +1,7 @@
-From 1edcdd6bd28fb6ea388e73fd665b5c58f47c15a7 Mon Sep 17 00:00:00 2001
+From 85c7ec658b8ea1ee4ca7525f21c28d2f456e0b95 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 28 Jun 2023 08:34:21 +0800
-Subject: [PATCH 18/22] wifi: mt76: mt7996: enable PPDU-TxS to host
+Subject: [PATCH 19/98] wifi: mt76: mt7996: enable PPDU-TxS to host
 
 Enable PPDU-TxS by default no matter WED on or WED off
 PPDU-TxS is also capable of getting tx_bytes and tx_retries,
@@ -14,7 +14,7 @@
  4 files changed, 60 insertions(+), 19 deletions(-)
 
 diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
-index 20a2fe931..7402de245 100644
+index 20a2fe9..7402de2 100644
 --- a/mt76_connac3_mac.h
 +++ b/mt76_connac3_mac.h
 @@ -281,6 +281,12 @@ enum tx_mgnt_type {
@@ -66,10 +66,10 @@
 +
  #endif /* __MT76_CONNAC3_MAC_H */
 diff --git a/mt7996/init.c b/mt7996/init.c
-index a8a60a8c9..2fe3da475 100644
+index 17a4abd..3656b89 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -453,6 +453,11 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
+@@ -456,6 +456,11 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
  	set = FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_MODE, 0) |
  	      FIELD_PREP(MT_WTBLOFF_RSCR_RCPI_PARAM, 0x3);
  	mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
@@ -82,10 +82,10 @@
  
  static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 8f75da695..d4d3cf5b7 100644
+index 4828f10..7512147 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1173,22 +1173,35 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
+@@ -1227,22 +1227,35 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
  	bool cck = false;
  	u32 txrate, txs, mode, stbc;
  
@@ -131,7 +131,7 @@
  
  	txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
  
-@@ -1288,9 +1301,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
+@@ -1342,9 +1355,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
  	wcid->rate = rate;
  
  out:
@@ -143,7 +143,7 @@
  	mt76_tx_status_unlock(mdev, &list);
  
  	return !!skb;
-@@ -1304,13 +1316,10 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
+@@ -1358,13 +1370,10 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
  	u16 wcidx;
  	u8 pid;
  
@@ -160,10 +160,10 @@
  
  	if (wcidx >= mt7996_wtbl_size(dev))
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index b5c363a6f..5b7b8babb 100644
+index bd0eb51..865e005 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -243,6 +243,13 @@ enum base_rev {
+@@ -275,6 +275,13 @@ enum base_rev {
  						 FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \
  						 FIELD_PREP(MT_WTBL_LMAC_DW, _dw))
  
@@ -178,5 +178,5 @@
  #define MT_WF_ARB_BASE(_band)			__BASE(WF_ARB_BASE, (_band))
  #define MT_WF_ARB(_band, ofs)			(MT_WF_ARB_BASE(_band) + (ofs))
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0019-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
similarity index 87%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0019-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
index 4a75641..5cee6a0 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0019-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0020-wifi-mt76-mt7996-fix-incorrect-report-of-TX-GI.patch
@@ -1,7 +1,7 @@
-From 8d63150a261b6c9f3f19004e8f09dd0bdddffe24 Mon Sep 17 00:00:00 2001
+From e66867f6acc33faa75e9e301ad64e0903cffd7be Mon Sep 17 00:00:00 2001
 From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
 Date: Fri, 14 Jul 2023 09:43:53 +0800
-Subject: [PATCH 19/22] wifi: mt76: mt7996: fix incorrect report of TX GI
+Subject: [PATCH 20/98] wifi: mt76: mt7996: fix incorrect report of TX GI
 
 ---
  mt76_connac_mcu.h |  2 +-
@@ -12,7 +12,7 @@
  5 files changed, 74 insertions(+), 46 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index e9dd9aa64..8562ca42a 100644
+index e9dd9aa..8562ca4 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
 @@ -1327,7 +1327,7 @@ enum {
@@ -25,7 +25,7 @@
  	UNI_ALL_STA_TXRX_ADM_STAT,
  	UNI_ALL_STA_TXRX_AIR_TIME,
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index d4d3cf5b7..e999cce39 100644
+index 7512147..06c9a14 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
 @@ -102,7 +102,6 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
@@ -94,7 +94,7 @@
  		/* get signal strength of resp frames (CTS/BA/ACK) */
  		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
  		val = mt76_rr(dev, addr);
-@@ -1249,6 +1204,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
+@@ -1303,6 +1258,8 @@ mt7996_mac_add_txs_skb(struct mt7996_dev *dev, struct mt76_wcid *wcid,
  			goto out;
  
  		rate.flags = RATE_INFO_FLAGS_VHT_MCS;
@@ -103,19 +103,19 @@
  		break;
  	case MT_PHY_TYPE_HE_SU:
  	case MT_PHY_TYPE_HE_EXT_SU:
-@@ -2222,6 +2179,7 @@ void mt7996_mac_work(struct work_struct *work)
+@@ -2282,6 +2239,7 @@ void mt7996_mac_work(struct work_struct *work)
  
  		mt7996_mac_update_stats(phy);
  
 +		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
- 		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
- 		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
- 	}
+ 		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
+ 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
+ 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 284fb373b..fa4a37f20 100644
+index e9e1fd9..0b3f8c8 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -990,6 +990,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
+@@ -991,6 +991,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
  			sinfo->txrate.he_gi = txrate->he_gi;
  			sinfo->txrate.he_dcm = txrate->he_dcm;
  			sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
@@ -124,7 +124,7 @@
  		sinfo->txrate.flags = txrate->flags;
  		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 146e284fc..dd28ae2de 100644
+index 652a600..c190067 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -477,6 +477,43 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -189,7 +189,7 @@
  			wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);
  			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 66af7a90f..ccc260c83 100644
+index 97151d1..376931e 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -191,6 +191,27 @@ struct mt7996_mcu_thermal_notify {
@@ -217,17 +217,17 @@
 +	u8 __rsv2;
 +} __packed;
 +
- struct all_sta_trx_adm_stat {
- 	__le16 wlan_idx;
- 	u8 __rsv[2];
-@@ -215,6 +236,7 @@ struct mt7996_mcu_all_sta_info_event {
-         u8 __rsv3[2];
+ struct mt7996_mcu_all_sta_info_event {
+ 	u8 rsv[4];
+ 	__le16 tag;
+@@ -201,6 +222,7 @@ struct mt7996_mcu_all_sta_info_event {
+         u8 rsv3[2];
  
  	union {
 +		struct all_sta_trx_rate rate[0];
- 		struct all_sta_trx_adm_stat adm_stat[0];
- 		struct all_sta_trx_msdu_cnt msdu_cnt[0];
- 	};
+ 		struct {
+ 			__le16 wlan_idx;
+ 			u8 rsv[2];
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0020-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
similarity index 84%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0020-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
index be0645d..a5a8417 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0020-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0021-wifi-mt76-mt7996-remove-periodic-MPDU-TXS-request.patch
@@ -1,7 +1,7 @@
-From c1b3730e6c089fa9c22b94147373fdc7518a225c Mon Sep 17 00:00:00 2001
+From e6830d67bbbc38036cd077badd5a605b8f257752 Mon Sep 17 00:00:00 2001
 From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
 Date: Thu, 27 Jul 2023 14:00:30 +0800
-Subject: [PATCH 20/22] wifi: mt76: mt7996: remove periodic MPDU TXS request
+Subject: [PATCH 21/98] wifi: mt76: mt7996: remove periodic MPDU TXS request
 
 ---
  mt7996/mac.c    | 39 ++++++++++++++++++++++-----------------
@@ -10,10 +10,10 @@
  3 files changed, 22 insertions(+), 19 deletions(-)
 
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index e999cce39..d7751cf55 100644
+index 06c9a14..32c52fc 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -895,15 +895,6 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -926,15 +926,6 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
  	if (!wcid)
  		wcid = &dev->mt76.global_wcid;
  
@@ -29,7 +29,7 @@
  	t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
  	t->skb = tx_info->skb;
  
-@@ -956,22 +947,36 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -1010,22 +1001,36 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
  }
  
  static void
@@ -72,7 +72,7 @@
  	if (unlikely(fc != (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA)))
  		return;
  
-@@ -999,7 +1004,7 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
+@@ -1053,7 +1058,7 @@ mt7996_txwi_free(struct mt7996_dev *dev, struct mt76_txwi_cache *t,
  		wcid_idx = wcid->idx;
  
  		if (likely(t->skb->protocol != cpu_to_be16(ETH_P_PAE)))
@@ -81,7 +81,7 @@
  	} else {
  		wcid_idx = le32_get_bits(txwi[9], MT_TXD9_WLAN_IDX);
  	}
-@@ -1276,7 +1281,7 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
+@@ -1330,7 +1335,7 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
  	wcidx = le32_get_bits(txs_data[2], MT_TXS2_MLD_ID);
  	pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
  
@@ -91,7 +91,7 @@
  
  	if (wcidx >= mt7996_wtbl_size(dev))
 diff --git a/mt7996/main.c b/mt7996/main.c
-index fa4a37f20..501ea2764 100644
+index 0b3f8c8..832b861 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -666,7 +666,6 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -103,10 +103,10 @@
  	ewma_avg_signal_init(&msta->avg_ack_signal);
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index bf9960e30..4477b95d6 100644
+index 420d113..f268773 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -120,7 +120,6 @@ struct mt7996_sta {
+@@ -147,7 +147,6 @@ struct mt7996_sta {
  	struct ewma_avg_signal avg_ack_signal;
  
  	unsigned long changed;
@@ -115,5 +115,5 @@
  	struct mt76_connac_sta_key_conf bip;
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0021-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
similarity index 89%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0021-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
index b613f37..575b7db 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0021-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0022-wifi-mt76-connac-use-peer-address-for-station-BMC-en.patch
@@ -1,7 +1,7 @@
-From 3b25bfe66c903b49e2143fd7c4fea68a48be9371 Mon Sep 17 00:00:00 2001
+From 1b0bafc1cfb554b6150eb2ea3e1a5100ef1b0a24 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 24 Aug 2023 18:38:11 +0800
-Subject: [PATCH 21/22] wifi: mt76: connac: use peer address for station BMC
+Subject: [PATCH 22/98] wifi: mt76: connac: use peer address for station BMC
  entry
 
 Set peer address and aid for the BMC wtbl of station interface. For some
@@ -17,7 +17,7 @@
  2 files changed, 11 insertions(+), 1 deletion(-)
 
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 68de52535..bb570f252 100644
+index 68de525..bb570f2 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -391,7 +391,14 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
@@ -37,7 +37,7 @@
  	}
  
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 501ea2764..04a2d07a8 100644
+index 832b861..0e51fe0 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -582,6 +582,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
@@ -51,5 +51,5 @@
  		mt7996_mcu_add_sta(dev, vif, NULL, true);
  	}
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0022-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
similarity index 77%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0022-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
index ccaf2f1..1494376 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0022-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0023-wifi-mt76-mt7996-disable-rx-header-translation-for-B.patch
@@ -1,7 +1,7 @@
-From d2e010af6649b263cad49b71fa8fe2b975e51aa1 Mon Sep 17 00:00:00 2001
+From cb01c8f9cef451d5e478d8498902d52a92ca4b55 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Tue, 5 Sep 2023 17:31:49 +0800
-Subject: [PATCH 22/22] wifi: mt76: mt7996: disable rx header translation for
+Subject: [PATCH 23/98] wifi: mt76: mt7996: disable rx header translation for
  BMC entry
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
@@ -11,10 +11,10 @@
  1 file changed, 5 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index dd28ae2de..181be911b 100644
+index c190067..39f76a0 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1720,10 +1720,10 @@ mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+@@ -1719,10 +1719,10 @@ mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
  	else
  		hdr_trans->from_ds = true;
  
@@ -27,7 +27,7 @@
  	hdr_trans->dis_rx_hdr_tran = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
  	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
  		hdr_trans->to_ds = true;
-@@ -2096,6 +2096,9 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2095,6 +2095,9 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  	if (!enable)
  		goto out;
  
@@ -37,7 +37,7 @@
  	/* tag order is in accordance with firmware dependency. */
  	if (sta) {
  		/* starec phy */
-@@ -2122,8 +2125,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2121,8 +2124,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  		mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);
  		/* starec bfee */
  		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
@@ -47,5 +47,5 @@
  
  	ret = mt7996_mcu_add_group(dev, vif, sta);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0024-wifi-mt76-mt7996-add-kite-pci-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0024-wifi-mt76-mt7996-add-kite-pci-support.patch
new file mode 100644
index 0000000..d3c12af
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0024-wifi-mt76-mt7996-add-kite-pci-support.patch
@@ -0,0 +1,81 @@
+From 140d3c7139e37efcdc097b1b23be635da683e773 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Mon, 22 May 2023 09:30:28 +0800
+Subject: [PATCH 24/98] wifi: mt76: mt7996: add kite pci support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76_connac.h | 5 +++++
+ mt7996/mmio.c | 1 +
+ mt7996/pci.c  | 8 ++++++--
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/mt76_connac.h b/mt76_connac.h
+index c6726ab..b1ec8d4 100644
+--- a/mt76_connac.h
++++ b/mt76_connac.h
+@@ -222,6 +222,11 @@ static inline bool is_mt7996(struct mt76_dev *dev)
+ 	return mt76_chip(dev) == 0x7990;
+ }
+ 
++static inline bool is_mt7992(struct mt76_dev *dev)
++{
++	return mt76_chip(dev) == 0x7992;
++}
++
+ static inline bool is_mt7622(struct mt76_dev *dev)
+ {
+ 	if (!IS_ENABLED(CONFIG_MT7622_WMAC))
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index ab088a2..567f930 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -369,6 +369,7 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
+ 
+ 	switch (device_id) {
+ 	case 0x7990:
++	case 0x7992:
+ 		dev->reg.base = mt7996_reg_base;
+ 		dev->reg.map = mt7996_reg_map;
+ 		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 92869ca..e8edf77 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -17,11 +17,13 @@ static u32 hif_idx;
+ 
+ static const struct pci_device_id mt7996_pci_device_table[] = {
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7990) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7992) },
+ 	{ },
+ };
+ 
+ static const struct pci_device_id mt7996_hif_device_table[] = {
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7991) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x799a) },
+ 	{ },
+ };
+ 
+@@ -60,7 +62,9 @@ static void mt7996_put_hif2(struct mt7996_hif *hif)
+ static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev)
+ {
+ 	hif_idx++;
+-	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL))
++
++	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL) &&
++	    !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x799a, NULL))
+ 		return NULL;
+ 
+ 	writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
+@@ -113,7 +117,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 
+ 	mt76_pci_disable_aspm(pdev);
+ 
+-	if (id->device == 0x7991)
++	if (id->device == 0x7991 || id->device == 0x799a)
+ 		return mt7996_pci_hif2_probe(pdev);
+ 
+ 	dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch
new file mode 100644
index 0000000..7ce6401
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0025-wifi-mt76-mt7996-add-kite-wtbl-size-support.patch
@@ -0,0 +1,56 @@
+From 12f123f46ccce46990ce98d05a3a9db3b20b5459 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 14 Jun 2023 17:47:11 +0800
+Subject: [PATCH 25/98] wifi: mt76: mt7996: add kite wtbl size support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c | 3 ++-
+ mt7996/mt7996.h | 6 ++++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 9db7e53..ca0e9d0 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -103,7 +103,8 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
+ 		dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
+ 	}
+ 
+-	if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4)
++	if (dev->wtbl_size_group < 2 || dev->wtbl_size_group > 4 ||
++	    is_mt7992(&dev->mt76))
+ 		dev->wtbl_size_group = 2; /* set default */
+ 
+ 	return 0;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index f268773..6a31819 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -13,6 +13,7 @@
+ 
+ #define MT7996_MAX_INTERFACES		19	/* per-band */
+ #define MT7996_MAX_WMM_SETS		4
++#define MT7996_WTBL_EXTEND_SIZE		(is_mt7992(&dev->mt76) ? 32 : 64)
+ #define MT7996_WTBL_RESERVED		(mt7996_wtbl_size(dev) - 1)
+ #define MT7996_WTBL_STA			(MT7996_WTBL_RESERVED - \
+ 					 mt7996_max_interface_num(dev))
+@@ -497,12 +498,13 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
+ 
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
+ {
+-	return MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support);
++	return min(MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support),
++		   MT7996_WTBL_EXTEND_SIZE);
+ }
+ 
+ static inline u16 mt7996_wtbl_size(struct mt7996_dev *dev)
+ {
+-	return (dev->wtbl_size_group << 8) + 64;
++	return (dev->wtbl_size_group << 8) + MT7996_WTBL_EXTEND_SIZE;
+ }
+ 
+ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch
new file mode 100644
index 0000000..d494783
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0026-wifi-mt76-mt7996-accommodate-MT7992-with-different-c.patch
@@ -0,0 +1,28 @@
+From f364ba42a956ba321876c2ac3798811cd8ea88f3 Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Wed, 7 Jun 2023 10:21:09 +0800
+Subject: [PATCH 26/98] wifi: mt76: mt7996: accommodate MT7992 with different
+ capability
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ mt7996/mt7996.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 6a31819..31fa2b5 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -390,6 +390,9 @@ mt7996_phy3(struct mt7996_dev *dev)
+ static inline bool
+ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+ {
++	if (is_mt7992(&dev->mt76))
++		return band <= MT_BAND1;
++
+ 	/* tri-band support */
+ 	if (band <= MT_BAND2 &&
+ 	    mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch
new file mode 100644
index 0000000..3f5cfe7
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0027-wifi-mt76-mt7996-add-AFE-pll-enable-before-driver-ow.patch
@@ -0,0 +1,47 @@
+From 41ae938fe5d3df6b40e2b1cd5baaf8ea59bd2c46 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 12 Jul 2023 23:00:29 +0800
+Subject: [PATCH 27/98] wifi: mt76: mt7996: add AFE pll enable before driver
+ own
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+---
+ mt7996/init.c | 4 ++++
+ mt7996/regs.h | 7 +++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 3656b89..273d1e7 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -782,6 +782,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ 	int ret, idx;
+ 
+ 	mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
++	if (is_mt7992(&dev->mt76)) {
++		mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND0), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);
++		mt76_rmw(dev, MT_AFE_CTL_BAND_PLL_03(MT_BAND1), MT_AFE_CTL_BAND_PLL_03_MSB_EN, 0);
++	}
+ 
+ 	INIT_WORK(&dev->init_work, mt7996_init_work);
+ 
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 865e005..e76dae6 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -675,4 +675,11 @@ enum base_rev {
+ #define MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS	GENMASK(20, 16)
+ #define MT_MCU_WM_EXCP_LR_LOG			MT_MCU_WM_EXCP(0x204)
+ 
++/* CONN AFE CTL CON */
++#define MT_AFE_CTL_BASE				0x18043000
++#define MT_AFE_CTL_BAND(_band, ofs)		(MT_AFE_CTL_BASE + \
++						 ((_band) * 0x1000) + (ofs))
++#define MT_AFE_CTL_BAND_PLL_03(_band)		MT_AFE_CTL_BAND(_band, 0x2c)
++#define MT_AFE_CTL_BAND_PLL_03_MSB_EN		BIT(1)
++
+ #endif
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch
new file mode 100644
index 0000000..9d0f02b
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0028-wifi-mt76-mt7996-add-kite-eagle-CR-offset-revision.patch
@@ -0,0 +1,232 @@
+From df9f668cf78a4c8dbc505f5fc0fb27a14e94f4c1 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 14 Jul 2023 17:29:35 +0800
+Subject: [PATCH 28/98] wifi: mt76: mt7996: add kite & eagle CR offset revision
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/mmio.c | 58 +++++++++++++++++++++++++++++++++++++++
+ mt7996/regs.h | 76 +++++++++++++++++++++++++++++++++++----------------
+ 2 files changed, 111 insertions(+), 23 deletions(-)
+
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 567f930..2132b2e 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -28,6 +28,58 @@ static const struct __base mt7996_reg_base[] = {
+ 	[WF_RATE_BASE]		= { { 0x820ee000, 0x820fe000, 0x830ee000 } },
+ };
+ 
++static const u32 mt7996_offs[] = {
++	[MIB_RVSR0]		= 0x720,
++	[MIB_RVSR1]		= 0x724,
++	[MIB_BTSCR5]		= 0x788,
++	[MIB_BTSCR6]		= 0x798,
++	[MIB_RSCR1]		= 0x7ac,
++	[MIB_RSCR27]		= 0x954,
++	[MIB_RSCR28]		= 0x958,
++	[MIB_RSCR29]		= 0x95c,
++	[MIB_RSCR30]		= 0x960,
++	[MIB_RSCR31]		= 0x964,
++	[MIB_RSCR33]		= 0x96c,
++	[MIB_RSCR35]		= 0x974,
++	[MIB_RSCR36]		= 0x978,
++	[MIB_BSCR0]		= 0x9cc,
++	[MIB_BSCR1]		= 0x9d0,
++	[MIB_BSCR2]		= 0x9d4,
++	[MIB_BSCR3]		= 0x9d8,
++	[MIB_BSCR4]		= 0x9dc,
++	[MIB_BSCR5]		= 0x9e0,
++	[MIB_BSCR6]		= 0x9e4,
++	[MIB_BSCR7]		= 0x9e8,
++	[MIB_BSCR17]		= 0xa10,
++	[MIB_TRDR1]		= 0xa28,
++};
++
++static const u32 mt7992_offs[] = {
++	[MIB_RVSR0]		= 0x760,
++	[MIB_RVSR1]		= 0x764,
++	[MIB_BTSCR5]		= 0x7c8,
++	[MIB_BTSCR6]		= 0x7d8,
++	[MIB_RSCR1]		= 0x7f0,
++	[MIB_RSCR27]		= 0x998,
++	[MIB_RSCR28]		= 0x99c,
++	[MIB_RSCR29]		= 0x9a0,
++	[MIB_RSCR30]		= 0x9a4,
++	[MIB_RSCR31]		= 0x9a8,
++	[MIB_RSCR33]		= 0x9b0,
++	[MIB_RSCR35]		= 0x9b8,
++	[MIB_RSCR36]		= 0x9bc,
++	[MIB_BSCR0]		= 0xac8,
++	[MIB_BSCR1]		= 0xacc,
++	[MIB_BSCR2]		= 0xad0,
++	[MIB_BSCR3]		= 0xad4,
++	[MIB_BSCR4]		= 0xad8,
++	[MIB_BSCR5]		= 0xadc,
++	[MIB_BSCR6]		= 0xae0,
++	[MIB_BSCR7]		= 0xae4,
++	[MIB_BSCR17]		= 0xb0c,
++	[MIB_TRDR1]		= 0xb24,
++};
++
+ static const struct __map mt7996_reg_map[] = {
+ 	{ 0x54000000, 0x02000, 0x1000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */
+ 	{ 0x55000000, 0x03000, 0x1000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */
+@@ -369,8 +421,14 @@ static int mt7996_mmio_init(struct mt76_dev *mdev,
+ 
+ 	switch (device_id) {
+ 	case 0x7990:
++		dev->reg.base = mt7996_reg_base;
++		dev->reg.offs_rev = mt7996_offs;
++		dev->reg.map = mt7996_reg_map;
++		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
++		break;
+ 	case 0x7992:
+ 		dev->reg.base = mt7996_reg_base;
++		dev->reg.offs_rev = mt7992_offs;
+ 		dev->reg.map = mt7996_reg_map;
+ 		dev->reg.map_size = ARRAY_SIZE(mt7996_reg_map);
+ 		break;
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index e76dae6..de5df91 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -19,6 +19,7 @@ struct __base {
+ /* used to differentiate between generations */
+ struct mt7996_reg_desc {
+ 	const struct __base *base;
++	const u32 *offs_rev;
+ 	const struct __map *map;
+ 	u32 map_size;
+ };
+@@ -39,6 +40,35 @@ enum base_rev {
+ 
+ #define __BASE(_id, _band)			(dev->reg.base[(_id)].band_base[(_band)])
+ 
++enum offs_rev {
++	MIB_RVSR0,
++	MIB_RVSR1,
++	MIB_BTSCR5,
++	MIB_BTSCR6,
++	MIB_RSCR1,
++	MIB_RSCR27,
++	MIB_RSCR28,
++	MIB_RSCR29,
++	MIB_RSCR30,
++	MIB_RSCR31,
++	MIB_RSCR33,
++	MIB_RSCR35,
++	MIB_RSCR36,
++	MIB_BSCR0,
++	MIB_BSCR1,
++	MIB_BSCR2,
++	MIB_BSCR3,
++	MIB_BSCR4,
++	MIB_BSCR5,
++	MIB_BSCR6,
++	MIB_BSCR7,
++	MIB_BSCR17,
++	MIB_TRDR1,
++	__MT_OFFS_MAX,
++};
++
++#define __OFFS(id)			(dev->reg.offs_rev[(id)])
++
+ /* RRO TOP */
+ #define MT_RRO_TOP_BASE				0xA000
+ #define MT_RRO_TOP(ofs)				(MT_RRO_TOP_BASE + (ofs))
+@@ -172,32 +202,32 @@ enum base_rev {
+ #define MT_WF_MIB_BASE(_band)			__BASE(WF_MIB_BASE, (_band))
+ #define MT_WF_MIB(_band, ofs)			(MT_WF_MIB_BASE(_band) + (ofs))
+ 
+-#define MT_MIB_BSCR0(_band)			MT_WF_MIB(_band, 0x9cc)
+-#define MT_MIB_BSCR1(_band)			MT_WF_MIB(_band, 0x9d0)
+-#define MT_MIB_BSCR2(_band)			MT_WF_MIB(_band, 0x9d4)
+-#define MT_MIB_BSCR3(_band)			MT_WF_MIB(_band, 0x9d8)
+-#define MT_MIB_BSCR4(_band)			MT_WF_MIB(_band, 0x9dc)
+-#define MT_MIB_BSCR5(_band)			MT_WF_MIB(_band, 0x9e0)
+-#define MT_MIB_BSCR6(_band)			MT_WF_MIB(_band, 0x9e4)
+-#define MT_MIB_BSCR7(_band)			MT_WF_MIB(_band, 0x9e8)
+-#define MT_MIB_BSCR17(_band)			MT_WF_MIB(_band, 0xa10)
++#define MT_MIB_BSCR0(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR0))
++#define MT_MIB_BSCR1(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR1))
++#define MT_MIB_BSCR2(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR2))
++#define MT_MIB_BSCR3(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR3))
++#define MT_MIB_BSCR4(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR4))
++#define MT_MIB_BSCR5(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR5))
++#define MT_MIB_BSCR6(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR6))
++#define MT_MIB_BSCR7(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR7))
++#define MT_MIB_BSCR17(_band)			MT_WF_MIB(_band, __OFFS(MIB_BSCR17))
+ 
+ #define MT_MIB_TSCR5(_band)			MT_WF_MIB(_band, 0x6c4)
+ #define MT_MIB_TSCR6(_band)			MT_WF_MIB(_band, 0x6c8)
+ #define MT_MIB_TSCR7(_band)			MT_WF_MIB(_band, 0x6d0)
+ 
+-#define MT_MIB_RSCR1(_band)			MT_WF_MIB(_band, 0x7ac)
++#define MT_MIB_RSCR1(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR1))
+ /* rx mpdu counter, full 32 bits */
+-#define MT_MIB_RSCR31(_band)			MT_WF_MIB(_band, 0x964)
+-#define MT_MIB_RSCR33(_band)			MT_WF_MIB(_band, 0x96c)
++#define MT_MIB_RSCR31(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR31))
++#define MT_MIB_RSCR33(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR33))
+ 
+ #define MT_MIB_SDR6(_band)			MT_WF_MIB(_band, 0x020)
+ #define MT_MIB_SDR6_CHANNEL_IDL_CNT_MASK	GENMASK(15, 0)
+ 
+-#define MT_MIB_RVSR0(_band)			MT_WF_MIB(_band, 0x720)
++#define MT_MIB_RVSR0(_band)			MT_WF_MIB(_band, __OFFS(MIB_RVSR0))
+ 
+-#define MT_MIB_RSCR35(_band)			MT_WF_MIB(_band, 0x974)
+-#define MT_MIB_RSCR36(_band)			MT_WF_MIB(_band, 0x978)
++#define MT_MIB_RSCR35(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR35))
++#define MT_MIB_RSCR36(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR36))
+ 
+ /* tx ampdu cnt, full 32 bits */
+ #define MT_MIB_TSCR0(_band)			MT_WF_MIB(_band, 0x6b0)
+@@ -210,16 +240,16 @@ enum base_rev {
+ #define MT_MIB_TSCR4(_band)			MT_WF_MIB(_band, 0x6c0)
+ 
+ /* rx ampdu count, 32-bit */
+-#define MT_MIB_RSCR27(_band)			MT_WF_MIB(_band, 0x954)
++#define MT_MIB_RSCR27(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR27))
+ 
+ /* rx ampdu bytes count, 32-bit */
+-#define MT_MIB_RSCR28(_band)			MT_WF_MIB(_band, 0x958)
++#define MT_MIB_RSCR28(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR28))
+ 
+ /* rx ampdu valid subframe count */
+-#define MT_MIB_RSCR29(_band)			MT_WF_MIB(_band, 0x95c)
++#define MT_MIB_RSCR29(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR29))
+ 
+ /* rx ampdu valid subframe bytes count, 32bits */
+-#define MT_MIB_RSCR30(_band)			MT_WF_MIB(_band, 0x960)
++#define MT_MIB_RSCR30(_band)			MT_WF_MIB(_band, __OFFS(MIB_RSCR30))
+ 
+ /* remaining windows protected stats */
+ #define MT_MIB_SDR27(_band)			MT_WF_MIB(_band, 0x080)
+@@ -228,18 +258,18 @@ enum base_rev {
+ #define MT_MIB_SDR28(_band)			MT_WF_MIB(_band, 0x084)
+ #define MT_MIB_SDR28_TX_RWP_NEED_CNT		GENMASK(15, 0)
+ 
+-#define MT_MIB_RVSR1(_band)			MT_WF_MIB(_band, 0x724)
++#define MT_MIB_RVSR1(_band)			MT_WF_MIB(_band, __OFFS(MIB_RVSR1))
+ 
+ /* rx blockack count, 32 bits */
+ #define MT_MIB_TSCR1(_band)			MT_WF_MIB(_band, 0x6b4)
+ 
+ #define MT_MIB_BTSCR0(_band)			MT_WF_MIB(_band, 0x5e0)
+-#define MT_MIB_BTSCR5(_band)			MT_WF_MIB(_band, 0x788)
+-#define MT_MIB_BTSCR6(_band)			MT_WF_MIB(_band, 0x798)
++#define MT_MIB_BTSCR5(_band)			MT_WF_MIB(_band, __OFFS(MIB_BTSCR5))
++#define MT_MIB_BTSCR6(_band)			MT_WF_MIB(_band, __OFFS(MIB_BTSCR6))
+ 
+ #define MT_MIB_BFTFCR(_band)			MT_WF_MIB(_band, 0x5d0)
+ 
+-#define MT_TX_AGG_CNT(_band, n)			MT_WF_MIB(_band, 0xa28 + ((n) << 2))
++#define MT_TX_AGG_CNT(_band, n)			MT_WF_MIB(_band, __OFFS(MIB_TRDR1) + ((n) << 2))
+ #define MT_MIB_ARNG(_band, n)			MT_WF_MIB(_band, 0x0b0 + ((n) << 2))
+ #define MT_MIB_ARNCR_RANGE(val, n)		(((val) >> ((n) << 4)) & GENMASK(9, 0))
+ 
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch
new file mode 100644
index 0000000..7b88df9
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0029-wifi-mt76-mt7996-add-preamble-puncture-support-for-m.patch
@@ -0,0 +1,97 @@
+From ee2e6d4d137cadf56c1c102d73761f76fd97a6ea Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Fri, 22 Sep 2023 10:32:37 +0800
+Subject: [PATCH 29/98] wifi: mt76: mt7996: add preamble puncture support for
+ mt7996
+
+Add support configure preamble puncture feature through mcu commands.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt76_connac_mcu.h |  1 +
+ mt7996/mcu.c      | 30 ++++++++++++++++++++++++++++++
+ mt7996/mcu.h      |  4 ++++
+ mt7996/mt7996.h   |  2 ++
+ 4 files changed, 37 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 8562ca4..6fac67b 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1241,6 +1241,7 @@ enum {
+ 	MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
+ 	MCU_UNI_CMD_THERMAL = 0x35,
+ 	MCU_UNI_CMD_VOW = 0x37,
++	MCU_UNI_CMD_PP = 0x38,
+ 	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
+ 	MCU_UNI_CMD_RRO = 0x57,
+ 	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 39f76a0..60af1d4 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4308,3 +4308,33 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),
+ 				 &req, sizeof(req), false);
+ }
++
++int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode,
++			 u8 force_bitmap_ctrl, u16 bitmap)
++{
++	struct mt7996_dev *dev = phy->dev;
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++		bool mgmt_mode;
++		u8 band_idx;
++		u8 force_bitmap_ctrl;
++		bool auto_mode;
++		__le16 bitmap;
++		u8 _rsv2[2];
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_CMD_PP_EN_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++
++		.mgmt_mode = !auto_mode,
++		.band_idx = phy->mt76->band_idx,
++		.force_bitmap_ctrl = force_bitmap_ctrl,
++		.auto_mode = auto_mode,
++		.bitmap = cpu_to_le16(bitmap),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PP),
++				 &req, sizeof(req), false);
++}
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 376931e..296acbd 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -845,6 +845,10 @@ enum {
+ 	MT7996_SEC_MODE_MAX,
+ };
+ 
++enum {
++	UNI_CMD_PP_EN_CTRL,
++};
++
+ #define MT7996_PATCH_SEC		GENMASK(31, 24)
+ #define MT7996_PATCH_SCRAMBLE_KEY	GENMASK(15, 8)
+ #define MT7996_PATCH_AES_KEY		GENMASK(7, 0)
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 31fa2b5..c4d74a0 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -598,6 +598,8 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
+ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ 				     struct ieee80211_vif *vif,
+ 				     struct ieee80211_sta *sta);
++int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode, u8 force_bitmap,
++			 u16 bitmap);
+ #ifdef CONFIG_MAC80211_DEBUGFS
+ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			    struct ieee80211_sta *sta, struct dentry *dir);
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch
new file mode 100644
index 0000000..0789ad2
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0030-wifi-mt76-mt7996-fix-all-sta-info-struct-alignment.patch
@@ -0,0 +1,26 @@
+From b1d7c2518edfcf9fe96a0231132449c2f924d1d6 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 6 Oct 2023 16:39:39 +0800
+Subject: [PATCH 30/98] wifi: mt76: mt7996: fix all sta info struct alignment
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/mcu.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 296acbd..af7cd18 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -219,7 +219,7 @@ struct mt7996_mcu_all_sta_info_event {
+         u8 more;
+         u8 rsv2;
+         __le16 sta_num;
+-        u8 rsv3[2];
++        u8 rsv3[4];
+ 
+ 	union {
+ 		struct all_sta_trx_rate rate[0];
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch
new file mode 100644
index 0000000..8e716a0
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0031-wifi-mt76-mt7996-refine-ampdu-factor.patch
@@ -0,0 +1,111 @@
+From 274d96dc00990390f4e830452d9032471deacf33 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Fri, 6 Oct 2023 11:44:03 +0800
+Subject: [PATCH 31/98] wifi: mt76: mt7996: refine ampdu factor
+
+Firmware would parse ht/vht/he/eht cap to get correct ampdu parameters.
+---
+ mt76_connac_mcu.h |  4 +++-
+ mt7996/mcu.c      | 44 ++++----------------------------------------
+ mt7996/mcu.h      |  1 -
+ 3 files changed, 7 insertions(+), 42 deletions(-)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 6fac67b..ca2e573 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -298,7 +298,9 @@ struct sta_rec_ht {
+ 	__le16 tag;
+ 	__le16 len;
+ 	__le16 ht_cap;
+-	u16 rsv;
++	__le16 ht_cap_ext;
++	u8 ampdu_param;
++	u8 _rsv[3];
+ } __packed;
+ 
+ struct sta_rec_vht {
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 60af1d4..8b81644 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1195,6 +1195,10 @@ mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+ 
+ 	ht = (struct sta_rec_ht *)tlv;
+ 	ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);
++	ht->ampdu_param = u8_encode_bits(sta->deflink.ht_cap.ampdu_factor,
++					 IEEE80211_HT_AMPDU_PARM_FACTOR) |
++			  u8_encode_bits(sta->deflink.ht_cap.ampdu_density,
++					 IEEE80211_HT_AMPDU_PARM_DENSITY);
+ }
+ 
+ static void
+@@ -1651,44 +1655,6 @@ mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ 	bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
+ }
+ 
+-static void
+-mt7996_mcu_sta_phy_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+-		       struct ieee80211_vif *vif, struct ieee80211_sta *sta)
+-{
+-	struct sta_rec_phy *phy;
+-	struct tlv *tlv;
+-	u8 af = 0, mm = 0;
+-
+-	if (!sta->deflink.ht_cap.ht_supported && !sta->deflink.he_6ghz_capa.capa)
+-		return;
+-
+-	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
+-
+-	phy = (struct sta_rec_phy *)tlv;
+-	if (sta->deflink.ht_cap.ht_supported) {
+-		af = sta->deflink.ht_cap.ampdu_factor;
+-		mm = sta->deflink.ht_cap.ampdu_density;
+-	}
+-
+-	if (sta->deflink.vht_cap.vht_supported) {
+-		u8 vht_af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
+-				      sta->deflink.vht_cap.cap);
+-
+-		af = max_t(u8, af, vht_af);
+-	}
+-
+-	if (sta->deflink.he_6ghz_capa.capa) {
+-		af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
+-				   IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
+-		mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
+-				   IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
+-	}
+-
+-	phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR, af) |
+-		     FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY, mm);
+-	phy->max_ampdu_len = af;
+-}
+-
+ static void
+ mt7996_mcu_sta_hdrt_tlv(struct mt7996_dev *dev, struct sk_buff *skb)
+ {
+@@ -2100,8 +2066,6 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ 
+ 	/* tag order is in accordance with firmware dependency. */
+ 	if (sta) {
+-		/* starec phy */
+-		mt7996_mcu_sta_phy_tlv(dev, skb, vif, sta);
+ 		/* starec hdrt mode */
+ 		mt7996_mcu_sta_hdrt_tlv(dev, skb);
+ 		/* starec bfer */
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index af7cd18..ca16336 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -730,7 +730,6 @@ enum {
+ 					 sizeof(struct sta_rec_uapsd) + 	\
+ 					 sizeof(struct sta_rec_amsdu) +		\
+ 					 sizeof(struct sta_rec_bfee) +		\
+-					 sizeof(struct sta_rec_phy) +		\
+ 					 sizeof(struct sta_rec_ra_uni) +	\
+ 					 sizeof(struct sta_rec_sec) +		\
+ 					 sizeof(struct sta_rec_ra_fixed_uni) +	\
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0999-wifi-mt76-mt7996-for-build-pass.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0999-wifi-mt76-mt7996-for-build-pass.patch
index 011ba0f..48ca34e 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0999-wifi-mt76-mt7996-for-build-pass.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0999-wifi-mt76-mt7996-for-build-pass.patch
@@ -1,7 +1,7 @@
-From bb7ab509be8e0cf9c9f10efa2fdd4c9c9b4d25b0 Mon Sep 17 00:00:00 2001
+From fd11038a011cf006ee347a48d880c38a2ad20c75 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 3 Nov 2022 00:27:17 +0800
-Subject: [PATCH 0999/1024] wifi: mt76: mt7996: for build pass
+Subject: [PATCH 32/98] wifi: mt76: mt7996: for build pass
 
 Change-Id: Ieb44c33ee6e6a2e6058c1ef528404c1a1cbcfdaf
 ---
@@ -18,7 +18,7 @@
  10 files changed, 19 insertions(+), 4 deletions(-)
 
 diff --git a/debugfs.c b/debugfs.c
-index c4649ba04..ac5207e5e 100644
+index c4649ba..ac5207e 100644
 --- a/debugfs.c
 +++ b/debugfs.c
 @@ -33,8 +33,11 @@ mt76_napi_threaded_set(void *data, u64 val)
@@ -34,10 +34,10 @@
  	return 0;
  }
 diff --git a/dma.c b/dma.c
-index 643e18ebb..f5091a35b 100644
+index dd20271..bb995e2 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -861,7 +861,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -943,7 +943,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		    !(dev->drv->rx_check(dev, data, len)))
  			goto free_frag;
  
@@ -47,7 +47,7 @@
  			goto free_frag;
  
 diff --git a/eeprom.c b/eeprom.c
-index 2558788f7..a07ca8440 100644
+index 2558788..a07ca84 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -161,9 +161,15 @@ void
@@ -68,7 +68,7 @@
  	if (!is_valid_ether_addr(phy->macaddr)) {
  		eth_random_addr(phy->macaddr);
 diff --git a/mcu.c b/mcu.c
-index a8cafa39a..fa4b05441 100644
+index a8cafa3..fa4b054 100644
 --- a/mcu.c
 +++ b/mcu.c
 @@ -4,6 +4,7 @@
@@ -80,7 +80,7 @@
  struct sk_buff *
  __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data,
 diff --git a/mt7615/mcu.c b/mt7615/mcu.c
-index 955974a82..db337aada 100644
+index 955974a..db337aa 100644
 --- a/mt7615/mcu.c
 +++ b/mt7615/mcu.c
 @@ -10,6 +10,7 @@
@@ -92,7 +92,7 @@
  static bool prefer_offload_fw = true;
  module_param(prefer_offload_fw, bool, 0644);
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index bb570f252..236cfea6a 100644
+index bb570f2..236cfea 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -4,6 +4,7 @@
@@ -104,7 +104,7 @@
  int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
  {
 diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index b6fba1ae1..dee01e03f 100644
+index b6fba1a..dee01e0 100644
 --- a/mt7915/mcu.c
 +++ b/mt7915/mcu.c
 @@ -6,6 +6,7 @@
@@ -116,10 +116,10 @@
  #define fw_name(_dev, name, ...)	({			\
  	char *_fw;						\
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index d4bbe9fb4..2e75d2794 100644
+index 1ed91da..23f6f16 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -387,8 +387,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -602,8 +602,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	if (ret < 0)
  		return ret;
  
@@ -131,7 +131,7 @@
  
  	mt7996_dma_enable(dev, false);
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 9db7e5310..1d98d99eb 100644
+index ca0e9d0..7ae92e1 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -98,6 +98,7 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
@@ -143,7 +143,7 @@
  		dev->has_eht = !(cap & MODE_HE_ONLY);
  		dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 181be911b..3d6792259 100644
+index 8b81644..fdc4fb4 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -5,6 +5,7 @@
@@ -155,5 +155,5 @@
  #include "mcu.h"
  #include "mac.h"
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1000-wifi-mt76-mt7996-add-debug-tool.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1000-wifi-mt76-mt7996-add-debug-tool.patch
index 11599c0..d29a90b 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1000-wifi-mt76-mt7996-add-debug-tool.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1000-wifi-mt76-mt7996-add-debug-tool.patch
@@ -1,7 +1,7 @@
-From 36a71ed07925573d2eff73f7be91c86763151470 Mon Sep 17 00:00:00 2001
+From 393f2e0f06e9a6ead8ffd64c904b6e24ff6c92f1 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/1024] wifi: mt76: mt7996: add debug tool
+Subject: [PATCH 33/98] wifi: mt76: mt7996: add debug tool
 
 Change-Id: Ie10390b01f17db893dbfbf3221bf63a4bd1fe38f
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -10,20 +10,20 @@
  mt7996/coredump.c    |   10 +-
  mt7996/coredump.h    |    7 +
  mt7996/debugfs.c     |   34 +-
- mt7996/mt7996.h      |   14 +
+ mt7996/mt7996.h      |   10 +
  mt7996/mtk_debug.h   | 2147 ++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_debugfs.c | 2379 ++++++++++++++++++++++++++++++++++++++++++
  mt7996/mtk_mcu.c     |   18 +
  mt7996/mtk_mcu.h     |   16 +
  tools/fwlog.c        |   25 +-
- 10 files changed, 4634 insertions(+), 20 deletions(-)
+ 10 files changed, 4630 insertions(+), 20 deletions(-)
  create mode 100644 mt7996/mtk_debug.h
  create mode 100644 mt7996/mtk_debugfs.c
  create mode 100644 mt7996/mtk_mcu.c
  create mode 100644 mt7996/mtk_mcu.h
 
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index 07c8b555c..a056b40e0 100644
+index 07c8b55..a056b40 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -1,4 +1,6 @@
@@ -40,7 +40,7 @@
 +
 +mt7996e-y += mtk_debugfs.o mtk_mcu.o
 diff --git a/mt7996/coredump.c b/mt7996/coredump.c
-index 60b88085c..a7f91b56d 100644
+index 60b8808..a7f91b5 100644
 --- a/mt7996/coredump.c
 +++ b/mt7996/coredump.c
 @@ -195,7 +195,7 @@ mt7996_coredump_fw_stack(struct mt7996_dev *dev, u8 type, struct mt7996_coredump
@@ -89,7 +89,7 @@
  		dev_warn(dev->mt76.dev, "no crash dump data found\n");
  		return -ENODATA;
 diff --git a/mt7996/coredump.h b/mt7996/coredump.h
-index 01ed3731c..93cd84a03 100644
+index 01ed373..93cd84a 100644
 --- a/mt7996/coredump.h
 +++ b/mt7996/coredump.h
 @@ -75,6 +75,7 @@ struct mt7996_mem_region {
@@ -114,7 +114,7 @@
  mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
  {
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 9bd953586..92aa1644f 100644
+index 9bd9535..92aa164 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
 @@ -290,11 +290,20 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
@@ -201,10 +201,10 @@
  	hdr.timestamp = cpu_to_le32(mt76_rr(dev, MT_LPON_FRCR(0)));
  	hdr.len = *(__le16 *)data;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 4477b95d6..8aa124a0c 100644
+index c4d74a0..8801956 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -264,6 +264,16 @@ struct mt7996_dev {
+@@ -317,6 +317,16 @@ struct mt7996_dev {
  	spinlock_t reg_lock;
  
  	u8 wtbl_size_group;
@@ -221,18 +221,9 @@
  };
  
  enum {
-@@ -544,4 +554,8 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			    struct ieee80211_sta *sta, struct dentry *dir);
- #endif
- 
-+#ifdef CONFIG_MTK_DEBUG
-+int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
-+#endif
-+
- #endif
 diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
 new file mode 100644
-index 000000000..368f0bcf0
+index 0000000..368f0bc
 --- /dev/null
 +++ b/mt7996/mtk_debug.h
 @@ -0,0 +1,2147 @@
@@ -2385,7 +2376,7 @@
 +#endif
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
 new file mode 100644
-index 000000000..5aa5c94f3
+index 0000000..5aa5c94
 --- /dev/null
 +++ b/mt7996/mtk_debugfs.c
 @@ -0,0 +1,2379 @@
@@ -2726,7 +2717,7 @@
 +static int mt7996_dump_version(struct seq_file *s, void *data)
 +{
 +	struct mt7996_dev *dev = dev_get_drvdata(s->private);
-+	seq_printf(s, "Version: 3.3.14.0\n");
++	seq_printf(s, "Version: 3.3.10.0\n");
 +
 +	if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
 +		return 0;
@@ -4770,7 +4761,7 @@
 +#endif
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
 new file mode 100644
-index 000000000..e88701667
+index 0000000..e887016
 --- /dev/null
 +++ b/mt7996/mtk_mcu.c
 @@ -0,0 +1,18 @@
@@ -4794,7 +4785,7 @@
 +#endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
 new file mode 100644
-index 000000000..e741aa278
+index 0000000..e741aa2
 --- /dev/null
 +++ b/mt7996/mtk_mcu.h
 @@ -0,0 +1,16 @@
@@ -4815,7 +4806,7 @@
 +
 +#endif
 diff --git a/tools/fwlog.c b/tools/fwlog.c
-index e5d4a1051..3c6a61d71 100644
+index e5d4a10..3c6a61d 100644
 --- a/tools/fwlog.c
 +++ b/tools/fwlog.c
 @@ -26,7 +26,7 @@ static const char *debugfs_path(const char *phyname, const char *file)
@@ -4899,5 +4890,5 @@
  	return ret;
  }
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
index a7a8038..ff8d7a8 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1001-wifi-mt76-mt7996-add-check-for-hostapd-config-he_ldp.patch
@@ -1,7 +1,7 @@
-From 9db4d791dab1d0500c13475ee704965aa0d779ab Mon Sep 17 00:00:00 2001
+From cb64d3c0b0dd79b8255caef614b13fe17f1b5b07 Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Thu, 8 Jun 2023 17:32:33 +0800
-Subject: [PATCH 1001/1024] wifi: mt76: mt7996: add check for hostapd config
+Subject: [PATCH 34/98] wifi: mt76: mt7996: add check for hostapd config
  he_ldpc
 
 Add check for hostapd config he_ldpc.
@@ -14,10 +14,10 @@
  1 file changed, 8 insertions(+), 3 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 3d6792259..867818825 100644
+index fdc4fb4..7d0c511 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1097,7 +1097,8 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+@@ -1096,7 +1096,8 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
  }
  
  static void
@@ -27,7 +27,7 @@
  {
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
  	struct ieee80211_he_mcs_nss_supp mcs_map;
-@@ -1117,6 +1118,10 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
+@@ -1116,6 +1117,10 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  		he->he_phy_cap[i] = elem->phy_cap_info[i];
  	}
  
@@ -38,7 +38,7 @@
  	mcs_map = sta->deflink.he_cap.he_mcs_nss_supp;
  	switch (sta->deflink.bandwidth) {
  	case IEEE80211_STA_RX_BW_160:
-@@ -2029,7 +2034,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -1994,7 +1999,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  	 * update sta_rec_he here.
  	 */
  	if (changed)
@@ -47,7 +47,7 @@
  
  	/* sta_rec_ra accommodates BW, NSS and only MCS range format
  	 * i.e 0-{7,8,9} for VHT.
-@@ -2117,7 +2122,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2080,7 +2085,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
  		/* starec amsdu */
  		mt7996_mcu_sta_amsdu_tlv(dev, skb, vif, sta);
  		/* starec he */
@@ -57,5 +57,5 @@
  		mt7996_mcu_sta_he_6g_tlv(skb, sta);
  		/* starec eht */
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
index 0969a87..56f85a8 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1002-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
@@ -1,7 +1,7 @@
-From c8247563a1cdb0b28a1b834a14d258982255d50a Mon Sep 17 00:00:00 2001
+From e622295e18a1af30c999928701787d8c562621c3 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 28 Dec 2022 22:24:25 +0800
-Subject: [PATCH 1002/1024] wifi: mt76: testmode: add atenl support in mt7996
+Subject: [PATCH 35/98] wifi: mt76: testmode: add atenl support in mt7996
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  2 files changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/testmode.c b/testmode.c
-index 4644dace9..5c93aa6a8 100644
+index 4644dac..5c93aa6 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -613,7 +613,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
@@ -24,7 +24,7 @@
  
  	if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
 diff --git a/testmode.h b/testmode.h
-index 5e2792d81..a40cd74b4 100644
+index 5e2792d..a40cd74 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -17,6 +17,7 @@
@@ -44,5 +44,5 @@
  	MT76_TM_ATTR_TX_COUNT,
  	MT76_TM_ATTR_TX_LENGTH,
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1003-wifi-mt76-testmode-add-basic-testmode-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
index 9da4da4..5b78a59 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1003-wifi-mt76-testmode-add-basic-testmode-support.patch
@@ -1,7 +1,7 @@
-From 7faad00dd85cec867c133a7d48ccb3b500719f94 Mon Sep 17 00:00:00 2001
+From ce58ffb18be834e2f62a30a71c9d6f5805517a9e Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 1 Mar 2023 11:59:16 +0800
-Subject: [PATCH 1003/1024] wifi: mt76: testmode: add basic testmode support
+Subject: [PATCH 36/98] wifi: mt76: testmode: add basic testmode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  mt7996/Makefile   |   1 +
  mt7996/eeprom.c   |  35 ++-
  mt7996/eeprom.h   |   1 +
- mt7996/init.c     |   7 +
+ mt7996/init.c     |   8 +
  mt7996/mac.c      |   3 +-
  mt7996/main.c     |  16 ++
  mt7996/mcu.c      |  42 ++-
@@ -23,12 +23,12 @@
  testmode.c        |  78 ++++--
  testmode.h        |  64 +++++
  tools/fields.c    | 102 ++++++-
- 18 files changed, 1382 insertions(+), 34 deletions(-)
+ 18 files changed, 1383 insertions(+), 34 deletions(-)
  create mode 100644 mt7996/testmode.c
  create mode 100644 mt7996/testmode.h
 
 diff --git a/eeprom.c b/eeprom.c
-index a07ca8440..437d8ca24 100644
+index a07ca84..437d8ca 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -94,8 +94,10 @@ static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offs
@@ -45,7 +45,7 @@
  
  out_put_node:
 diff --git a/mac80211.c b/mac80211.c
-index 12fcb2b01..5740ba061 100644
+index cd102dd..f10ca90 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -835,7 +835,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
@@ -59,10 +59,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 a2382160d..ad1123c4a 100644
+index 7f93210..feb861c 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -658,14 +658,20 @@ struct mt76_testmode_ops {
+@@ -692,14 +692,20 @@ 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);
@@ -83,7 +83,7 @@
  	u32 tx_count;
  	u16 tx_mpdu_len;
  
-@@ -675,6 +681,7 @@ struct mt76_testmode_data {
+@@ -709,6 +715,7 @@ struct mt76_testmode_data {
  	u8 tx_rate_sgi;
  	u8 tx_rate_ldpc;
  	u8 tx_rate_stbc;
@@ -91,7 +91,7 @@
  	u8 tx_ltf;
  
  	u8 tx_antenna_mask;
-@@ -684,6 +691,9 @@ struct mt76_testmode_data {
+@@ -718,6 +725,9 @@ struct mt76_testmode_data {
  	u32 tx_time;
  	u32 tx_ipg;
  
@@ -101,7 +101,7 @@
  	u32 freq_offset;
  
  	u8 tx_power[4];
-@@ -698,7 +708,16 @@ struct mt76_testmode_data {
+@@ -732,7 +742,16 @@ struct mt76_testmode_data {
  	struct {
  		u64 packets[__MT_RXQ_MAX];
  		u64 fcs_error[__MT_RXQ_MAX];
@@ -118,7 +118,7 @@
  };
  
  struct mt76_vif {
-@@ -1370,6 +1389,22 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
+@@ -1418,6 +1437,22 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
  int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
  int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len);
  
@@ -142,10 +142,10 @@
  {
  #ifdef CONFIG_NL80211_TESTMODE
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8562ca42a..7e859da65 100644
+index ca2e573..4d054bd 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1237,11 +1237,13 @@ enum {
+@@ -1239,12 +1239,14 @@ enum {
  	MCU_UNI_CMD_EFUSE_CTRL = 0x2d,
  	MCU_UNI_CMD_RA = 0x2f,
  	MCU_UNI_CMD_MURU = 0x31,
@@ -154,13 +154,14 @@
  	MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
  	MCU_UNI_CMD_THERMAL = 0x35,
  	MCU_UNI_CMD_VOW = 0x37,
+ 	MCU_UNI_CMD_PP = 0x38,
  	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
 +	MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
  	MCU_UNI_CMD_RRO = 0x57,
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
  	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index a056b40e0..7bb17f440 100644
+index a056b40..7bb17f4 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -8,5 +8,6 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
@@ -171,7 +172,7 @@
  
  mt7996e-y += mtk_debugfs.o mtk_mcu.o
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 1d98d99eb..b81ed64ce 100644
+index 7ae92e1..7fd318c 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -6,6 +6,11 @@
@@ -241,7 +242,7 @@
  		if (ret < 0)
  			return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 412d6e2f8..9ea3667f1 100644
+index 412d6e2..9ea3667 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -253,10 +254,10 @@
  	MT_EE_RATE_DELTA_2G =	0x1400,
  	MT_EE_RATE_DELTA_5G =	0x147d,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 2fe3da475..f41e4e5eb 100644
+index 273d1e7..6d39c3c 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -663,6 +663,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -800,6 +800,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  
  	set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
  
@@ -267,22 +268,23 @@
  	ret = mt7996_mcu_init(dev);
  	if (ret)
  		return ret;
-@@ -1076,6 +1080,9 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1217,6 +1221,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  
- 	mt7996_init_wiphy(hw);
+ 	mt7996_init_wiphy(hw, &dev->mt76.mmio.wed);
  
 +#ifdef CONFIG_NL80211_TESTMODE
 +	dev->mt76.test_ops = &mt7996_testmode_ops;
 +#endif
++
  	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index d7751cf55..f00133489 100644
+index 32c52fc..637f0f6 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -654,7 +654,8 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- 		status->flag |= RX_FLAG_8023;
+@@ -685,7 +685,8 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
+ 				     *info);
  	}
  
 -	if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
@@ -290,9 +292,9 @@
 +	    !(status->flag & RX_FLAG_8023))
  		mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
  
- 	if (!status->wcid || !ieee80211_is_data_qos(fc))
+ 	if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 04a2d07a8..3336602f1 100644
+index 0e51fe0..226235c 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -23,6 +23,18 @@ static bool mt7996_dev_running(struct mt7996_dev *dev)
@@ -323,7 +325,7 @@
  	mt7996_mac_enable_nf(dev, phy->mt76->band_idx);
  
  	ret = mt7996_mcu_set_rts_thresh(phy, 0x92b);
-@@ -1437,6 +1451,8 @@ const struct ieee80211_ops mt7996_ops = {
+@@ -1478,6 +1492,8 @@ const struct ieee80211_ops mt7996_ops = {
  	.sta_set_decap_offload = mt7996_sta_set_decap_offload,
  	.add_twt_setup = mt7996_mac_add_twt_setup,
  	.twt_teardown_request = mt7996_twt_teardown_request,
@@ -333,10 +335,10 @@
  	.sta_add_debugfs = mt7996_sta_add_debugfs,
  #endif
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 867818825..837cf1b30 100644
+index 7d0c511..141b838 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2718,8 +2718,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+@@ -2681,8 +2681,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
  {
  	int ret;
  
@@ -351,8 +353,8 @@
  	if (ret)
  		return ret;
  
-@@ -4316,3 +4320,37 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
- 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),
+@@ -4308,3 +4312,37 @@ int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, bool auto_mode,
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(PP),
  				 &req, sizeof(req), false);
  }
 +
@@ -390,10 +392,10 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index ccc260c83..86701c3f6 100644
+index ca16336..16ffc3d 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -818,6 +818,33 @@ enum {
+@@ -814,6 +814,33 @@ enum {
  	UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG,
  };
  
@@ -428,10 +430,10 @@
  	UNI_CMD_ACCESS_REG_BASIC = 0x0,
  	UNI_CMD_ACCESS_RF_REG_BASIC,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 8aa124a0c..18208388b 100644
+index 8801956..3964035 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -31,9 +31,11 @@
+@@ -32,9 +32,11 @@
  #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"
@@ -443,7 +445,7 @@
  #define MT7996_EEPROM_SIZE		7680
  #define MT7996_EEPROM_BLOCK_SIZE	16
  #define MT7996_TOKEN_SIZE		16384
-@@ -65,6 +67,7 @@ struct mt7996_dfs_pattern;
+@@ -83,6 +85,7 @@ struct mt7996_dfs_pattern;
  
  enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
@@ -451,7 +453,7 @@
  	MT7996_RAM_TYPE_WA,
  	MT7996_RAM_TYPE_DSP,
  	__MT7996_RAM_TYPE_MAX,
-@@ -188,6 +191,21 @@ struct mt7996_phy {
+@@ -225,6 +228,21 @@ struct mt7996_phy {
  	struct mt76_channel_state state_ts;
  
  	bool has_aux_rx;
@@ -473,16 +475,16 @@
  };
  
  struct mt7996_dev {
-@@ -247,6 +265,8 @@ struct mt7996_dev {
- 	bool flash_mode:1;
- 	bool has_eht:1;
+@@ -300,6 +318,8 @@ struct mt7996_dev {
+ 		} session;
+ 	} wed_rro;
  
 +	bool testmode_enable;
 +
  	bool ibf;
  	u8 fw_debug_wm;
  	u8 fw_debug_wa;
-@@ -358,6 +378,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+@@ -414,6 +434,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
  extern const struct ieee80211_ops mt7996_ops;
  extern struct pci_driver mt7996_pci_driver;
  extern struct pci_driver mt7996_hif_driver;
@@ -490,7 +492,7 @@
  
  struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
  				     void __iomem *mem_base, u32 device_id);
-@@ -367,6 +388,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+@@ -423,6 +444,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
  int mt7996_register_device(struct mt7996_dev *dev);
  void mt7996_unregister_device(struct mt7996_dev *dev);
  int mt7996_eeprom_init(struct mt7996_dev *dev);
@@ -498,17 +500,17 @@
  int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
  int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
  				   struct ieee80211_channel *chan);
-@@ -450,6 +472,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
- int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+@@ -508,6 +530,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
  void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
  void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
 +int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
  
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
 new file mode 100644
-index 000000000..fb041c336
+index 0000000..fb041c3
 --- /dev/null
 +++ b/mt7996/testmode.c
 @@ -0,0 +1,674 @@
@@ -1188,7 +1190,7 @@
 +};
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
 new file mode 100644
-index 000000000..e4d55a61a
+index 0000000..e4d55a6
 --- /dev/null
 +++ b/mt7996/testmode.h
 @@ -0,0 +1,297 @@
@@ -1490,7 +1492,7 @@
 +
 +#endif
 diff --git a/testmode.c b/testmode.c
-index 5c93aa6a8..bbe8230fd 100644
+index 5c93aa6..bbe8230 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -2,11 +2,13 @@
@@ -1681,7 +1683,7 @@
  	     nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
 diff --git a/testmode.h b/testmode.h
-index a40cd74b4..141bb8625 100644
+index a40cd74..141bb86 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -19,6 +19,7 @@
@@ -1833,7 +1835,7 @@
  	/* keep last */
  	NUM_MT76_TM_TX_MODES,
 diff --git a/tools/fields.c b/tools/fields.c
-index e3f690896..055f90f3c 100644
+index e3f6908..055f90f 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -10,6 +10,7 @@ static const char * const testmode_state[] = {
@@ -2048,5 +2050,5 @@
  
  const struct tm_field msg_field = {
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
index d6b30ae..dbef00c 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1004-wifi-mt76-mt7996-add-eagle-default-bin-of-different-.patch
@@ -1,8 +1,8 @@
-From 2de4c7cb583e687e644be8050ab2cd2ba7802ed3 Mon Sep 17 00:00:00 2001
+From 10df4848e7a7116529e1f596e06d0d03891f502e Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Thu, 20 Jul 2023 17:27:22 +0800
-Subject: [PATCH 1004/1024] wifi: mt76: mt7996: add eagle default bin of
- different sku variants
+Subject: [PATCH 37/98] wifi: mt76: mt7996: add eagle default bin of different
+ sku variants
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  3 files changed, 32 insertions(+), 2 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index b81ed64ce..c4d51a439 100644
+index 7fd318c..3276740 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -30,6 +30,8 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
@@ -25,10 +25,10 @@
  		return MT7996_EEPROM_DEFAULT;
  }
 diff --git a/mt7996/init.c b/mt7996/init.c
-index f41e4e5eb..aebdc0df8 100644
+index 6d39c3c..fed74d0 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -652,6 +652,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -789,6 +789,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  
  	INIT_WORK(&dev->init_work, mt7996_init_work);
  
@@ -40,10 +40,10 @@
  			    mt7996_band_valid(dev, MT_BAND2);
  	dev->tbtc_support = mt7996_band_valid(dev, MT_BAND1) &&
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 18208388b..d65adac41 100644
+index 3964035..efdcff7 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -35,6 +35,7 @@
+@@ -36,6 +36,7 @@
  #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
  
  #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
@@ -51,7 +51,7 @@
  #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
  #define MT7996_EEPROM_SIZE		7680
  #define MT7996_EEPROM_BLOCK_SIZE	16
-@@ -65,6 +66,11 @@ struct mt7996_sta;
+@@ -83,6 +84,11 @@ struct mt7996_sta;
  struct mt7996_dfs_pulse;
  struct mt7996_dfs_pattern;
  
@@ -63,7 +63,7 @@
  enum mt7996_ram_type {
  	MT7996_RAM_TYPE_WM,
  	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
-@@ -227,6 +233,8 @@ struct mt7996_dev {
+@@ -264,6 +270,8 @@ struct mt7996_dev {
  	struct cfg80211_chan_def rdd2_chandef;
  	struct mt7996_phy *rdd2_phy;
  
@@ -72,7 +72,7 @@
  	u16 chainmask;
  	u8 chainshift[__MT_MAX_BAND];
  	u32 hif_idx;
-@@ -364,12 +372,28 @@ mt7996_phy3(struct mt7996_dev *dev)
+@@ -417,6 +425,23 @@ mt7996_phy3(struct mt7996_dev *dev)
  	return __mt7996_phy(dev, MT_BAND2);
  }
  
@@ -96,6 +96,9 @@
  static inline bool
  mt7996_band_valid(struct mt7996_dev *dev, u8 band)
  {
+@@ -424,8 +449,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band)
+ 		return band <= MT_BAND1;
+ 
  	/* tri-band support */
 -	if (band <= MT_BAND2 &&
 -	    mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
@@ -104,5 +107,5 @@
  
  	return band == MT_BAND0 || band == MT_BAND2;
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
index 71a05fb..78ae8ad 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1005-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
@@ -1,7 +1,7 @@
-From d7700431ea080cc79002cad62384ea66054f9905 Mon Sep 17 00:00:00 2001
+From b02a81b168e9c42350c1f6a9b7e38c60c76cc692 Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 8 May 2023 09:03:50 +0800
-Subject: [PATCH 1005/1024] wifi: mt76: mt7996: enable SCS feature for mt7996
+Subject: [PATCH 38/98] wifi: mt76: mt7996: enable SCS feature for mt7996
  driver
 
 Enable Smart Carrier Sense algorithn by default to improve performance
@@ -14,14 +14,14 @@
  mt7996/main.c     |   7 +++
  mt7996/mcu.c      | 123 ++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/mcu.h      |   6 +++
- mt7996/mt7996.h   |  16 ++++++
- 6 files changed, 154 insertions(+)
+ mt7996/mt7996.h   |  15 ++++++
+ 6 files changed, 153 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 7e859da65..25b467e5d 100644
+index 4d054bd..fae76c9 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1230,6 +1230,7 @@ enum {
+@@ -1232,6 +1232,7 @@ enum {
  	MCU_UNI_CMD_GET_STAT_INFO = 0x23,
  	MCU_UNI_CMD_SNIFFER = 0x24,
  	MCU_UNI_CMD_SR = 0x25,
@@ -30,10 +30,10 @@
  	MCU_UNI_CMD_SET_DBDC_PARMS = 0x28,
  	MCU_UNI_CMD_TXPOWER = 0x2b,
 diff --git a/mt7996/init.c b/mt7996/init.c
-index aebdc0df8..f76fe6ea7 100644
+index fed74d0..f393e04 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -1070,6 +1070,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1211,6 +1211,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	dev->mt76.phy.priv = &dev->phy;
  	INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
  	INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
@@ -42,7 +42,7 @@
  	INIT_LIST_HEAD(&dev->twt_list);
  
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 3336602f1..ab5693e4f 100644
+index 226235c..6fa4a65 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -73,11 +73,17 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -72,10 +72,10 @@
  	mutex_lock(&dev->mt76.mutex);
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 837cf1b30..db3cab39c 100644
+index 141b838..6cedc39 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4354,3 +4354,126 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+@@ -4346,3 +4346,126 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
  	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TXPOWER),
  				 &req, sizeof(req), false);
  }
@@ -203,11 +203,11 @@
 +				 &req, sizeof(req), false);
 +}
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 86701c3f6..3b2536601 100644
+index 16ffc3d..ff9cc9c 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
 @@ -875,6 +875,12 @@ enum {
- 	MT7996_SEC_MODE_MAX,
+ 	UNI_CMD_PP_EN_CTRL,
  };
  
 +enum {
@@ -220,14 +220,13 @@
  #define MT7996_PATCH_SCRAMBLE_KEY	GENMASK(15, 8)
  #define MT7996_PATCH_AES_KEY		GENMASK(7, 0)
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index d65adac41..7b7dc9b33 100644
+index efdcff7..eb48dbd 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -165,6 +165,17 @@ struct mt7996_hif {
+@@ -193,6 +193,16 @@ struct mt7996_hif {
  	int irq;
  };
  
-+
 +struct mt7996_scs_ctrl {
 +	u8 scs_enable;
 +	s8 sta_min_rssi;
@@ -238,10 +237,10 @@
 +	SCS_ENABLE,
 +};
 +
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -198,6 +209,8 @@ struct mt7996_phy {
+ struct mt7996_wed_rro_addr {
+ 	u32 head_low;
+ 	u32 head_high : 4;
+@@ -235,6 +245,8 @@ struct mt7996_phy {
  
  	bool has_aux_rx;
  
@@ -250,7 +249,7 @@
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -243,6 +256,7 @@ struct mt7996_dev {
+@@ -280,6 +292,7 @@ struct mt7996_dev {
  	struct work_struct rc_work;
  	struct work_struct dump_work;
  	struct work_struct reset_work;
@@ -258,9 +257,9 @@
  	wait_queue_head_t reset_wait;
  	struct {
  		u32 state;
-@@ -497,6 +511,8 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
- void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+@@ -555,6 +568,8 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
  void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
  int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
 +int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
 +void mt7996_mcu_scs_sta_poll(struct work_struct *work);
@@ -268,5 +267,5 @@
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1006-wifi-mt76-mt7996-add-txpower-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1006-wifi-mt76-mt7996-add-txpower-support.patch
index 17045c2..0a0d376 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1006-wifi-mt76-mt7996-add-txpower-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1006-wifi-mt76-mt7996-add-txpower-support.patch
@@ -1,7 +1,7 @@
-From bcc8b3bec7555dfd5d1960ee9139f152af8aa9c7 Mon Sep 17 00:00:00 2001
+From 1c1dd57bde8919fdf04ef914b781eb6183582562 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 24 Mar 2023 23:35:30 +0800
-Subject: [PATCH 1006/1024] wifi: mt76: mt7996: add txpower support
+Subject: [PATCH 39/98] wifi: mt76: mt7996: add txpower support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Change-Id: Ic3e7b17f3664fa7f774137572f885359fa2ec93b
@@ -17,10 +17,10 @@
  8 files changed, 429 insertions(+), 11 deletions(-)
 
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index c4d51a439..bdb81018b 100644
+index 3276740..e4c4b86 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -295,3 +295,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
+@@ -296,3 +296,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
  
  	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
  }
@@ -59,7 +59,7 @@
 +	[SKU_EHT3x996_484] = 16,
 +};
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 9ea3667f1..343e65e18 100644
+index 9ea3667..343e65e 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -75,4 +75,46 @@ mt7996_get_channel_group_6g(int channel)
@@ -110,10 +110,10 @@
 +
  #endif
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 3b2536601..3a1b957c4 100644
+index ff9cc9c..71dc165 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -830,6 +830,7 @@ struct tx_power_ctrl {
+@@ -826,6 +826,7 @@ struct tx_power_ctrl {
  		bool ate_mode_enable;
  		bool percentage_ctrl_enable;
  		bool bf_backoff_enable;
@@ -121,7 +121,7 @@
  		u8 power_drop_level;
  	};
  	u8 band_idx;
-@@ -843,6 +844,7 @@ enum {
+@@ -839,6 +840,7 @@ enum {
  	UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL = 3,
  	UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
  	UNI_TXPOWER_ATE_MODE_CTRL = 6,
@@ -130,28 +130,28 @@
  
  enum {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 7b7dc9b33..7bd8abe79 100644
+index eb48dbd..23d1614 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -61,6 +61,8 @@
+@@ -63,6 +63,8 @@
  
  #define MT7996_BUILD_TIME_LEN		24
  
 +#define MT7996_SKU_RATE_NUM		417
 +
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -511,6 +513,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
- void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #define MT7996_RRO_MAX_SESSION		1024
+ #define MT7996_RRO_WINDOW_MAX_LEN	1024
+ #define MT7996_RRO_ADDR_ELEM_LEN	128
+@@ -568,6 +570,7 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
  void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
  int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
 +int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
  int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 5aa5c94f3..57fcbab35 100644
+index 5aa5c94..57fcbab 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
 @@ -2325,6 +2325,232 @@ static int mt7996_sta_info(struct seq_file *s, void *data)
@@ -398,7 +398,7 @@
  	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
  				    mt7996_wtbl_read);
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index e88701667..f772243b8 100644
+index e887016..f772243 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
 @@ -12,7 +12,30 @@
@@ -433,7 +433,7 @@
  
  #endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index e741aa278..beb1aba24 100644
+index e741aa2..beb1aba 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
 @@ -10,6 +10,84 @@
@@ -522,10 +522,10 @@
  #endif
  
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 5b7b8babb..e0b51b5df 100644
+index de5df91..565022a 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -585,24 +585,31 @@ enum base_rev {
+@@ -672,24 +672,31 @@ enum offs_rev {
  						 ((_wf) << 16) + (ofs))
  #define MT_WF_PHYRX_CSD_IRPI(_band, _wf)	MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
  
@@ -569,5 +569,5 @@
  #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR		BIT(29)
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
index 2e967b5..38754fa 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1007-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
@@ -1,23 +1,23 @@
-From 10d7c82abb8af232334700ded00d7ee4bb580077 Mon Sep 17 00:00:00 2001
+From 6c7addb48070af33da842ede744264149f2a9110 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 13 Dec 2022 15:17:43 +0800
-Subject: [PATCH 1007/1024] wifi: mt76: mt7996: add mu vendor command support
+Subject: [PATCH 40/98] wifi: mt76: mt7996: add mu vendor command support
 
 Change-Id: I4599bd97917651aaea51d7ff186ffff73a07e4ce
 ---
  mt7996/Makefile |  3 +-
- mt7996/init.c   |  9 ++++++
+ mt7996/init.c   |  8 +++++
  mt7996/mcu.c    | 37 ++++++++++++++++++---
  mt7996/mcu.h    | 12 +++++++
  mt7996/mt7996.h |  6 ++++
  mt7996/vendor.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
  mt7996/vendor.h | 22 +++++++++++++
- 7 files changed, 168 insertions(+), 6 deletions(-)
+ 7 files changed, 167 insertions(+), 6 deletions(-)
  create mode 100644 mt7996/vendor.c
  create mode 100644 mt7996/vendor.h
 
 diff --git a/mt7996/Makefile b/mt7996/Makefile
-index 7bb17f440..6643c7a38 100644
+index 7bb17f4..6643c7a 100644
 --- a/mt7996/Makefile
 +++ b/mt7996/Makefile
 @@ -1,11 +1,12 @@
@@ -35,10 +35,10 @@
  mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
  mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
 diff --git a/mt7996/init.c b/mt7996/init.c
-index f76fe6ea7..5644bba4a 100644
+index f393e04..1f4e84d 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -585,6 +585,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -597,6 +597,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
  	if (ret)
  		goto error;
  
@@ -49,11 +49,10 @@
  	ret = mt76_register_phy(mphy, true, mt76_rates,
  				ARRAY_SIZE(mt76_rates));
  	if (ret)
-@@ -1088,6 +1092,11 @@ int mt7996_register_device(struct mt7996_dev *dev)
- #ifdef CONFIG_NL80211_TESTMODE
+@@ -1230,6 +1234,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
  	dev->mt76.test_ops = &mt7996_testmode_ops;
  #endif
-+
+ 
 +#ifdef CONFIG_MTK_VENDOR
 +	mt7996_vendor_register(&dev->phy);
 +#endif
@@ -62,10 +61,10 @@
  				   ARRAY_SIZE(mt76_rates));
  	if (ret)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index db3cab39c..554f40ca2 100644
+index 6cedc39..a008c08 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -1263,6 +1263,8 @@ static void
+@@ -1266,6 +1266,8 @@ static void
  mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
  			struct ieee80211_vif *vif, struct ieee80211_sta *sta)
  {
@@ -74,7 +73,7 @@
  	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
  	struct sta_rec_muru *muru;
  	struct tlv *tlv;
-@@ -1274,11 +1276,14 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+@@ -1277,11 +1279,14 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
  
  	muru = (struct sta_rec_muru *)tlv;
@@ -94,7 +93,7 @@
  
  	if (sta->deflink.vht_cap.vht_supported)
  		muru->mimo_dl.vht_mu_bfee =
-@@ -4477,3 +4482,25 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+@@ -4469,3 +4474,25 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
  	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
  				 &req, sizeof(req), false);
  }
@@ -121,10 +120,10 @@
 +}
 +#endif
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 3a1b957c4..1d7748771 100644
+index 71dc165..c5c0a44 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -686,8 +686,20 @@ enum {
+@@ -683,8 +683,20 @@ enum {
  	RATE_PARAM_FIXED_MCS,
  	RATE_PARAM_FIXED_GI = 11,
  	RATE_PARAM_AUTO = 20,
@@ -146,10 +145,10 @@
  	BF_SOUNDING_ON = 1,
  	BF_HW_EN_UPDATE = 17,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 7bd8abe79..88ccb3060 100644
+index 23d1614..013122f 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -213,6 +213,7 @@ struct mt7996_phy {
+@@ -249,6 +249,7 @@ struct mt7996_phy {
  
  	struct mt7996_scs_ctrl scs_ctrl;
  
@@ -157,9 +156,9 @@
  #ifdef CONFIG_NL80211_TESTMODE
  	struct {
  		u32 *reg_backup;
-@@ -620,6 +621,11 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			    struct ieee80211_sta *sta, struct dentry *dir);
- #endif
+@@ -683,6 +684,11 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 			 bool hif2, int *irq);
+ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
  
 +#ifdef CONFIG_MTK_VENDOR
 +void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
@@ -171,7 +170,7 @@
  #endif
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
 new file mode 100644
-index 000000000..b5ecbdf1d
+index 0000000..b5ecbdf
 --- /dev/null
 +++ b/mt7996/vendor.c
 @@ -0,0 +1,85 @@
@@ -262,7 +261,7 @@
 +}
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
 new file mode 100644
-index 000000000..8ac3ba8ed
+index 0000000..8ac3ba8
 --- /dev/null
 +++ b/mt7996/vendor.h
 @@ -0,0 +1,22 @@
@@ -289,5 +288,5 @@
 +
 +#endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
index e416ffa..45f1585 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1008-wifi-mt76-mt7996-Add-air-monitor-support.patch
@@ -1,7 +1,7 @@
-From 83c8cdffd598cdc0be7efab551e9d7942247cb25 Mon Sep 17 00:00:00 2001
+From 98127145e2f401f65029185adab6dfcb0e90dbd9 Mon Sep 17 00:00:00 2001
 From: Evelyn Tsai <evelyn.tsai@mediatek.com>
 Date: Wed, 26 Apr 2023 04:40:05 +0800
-Subject: [PATCH 1008/1024] wifi: mt76: mt7996: Add air monitor support
+Subject: [PATCH 41/98] wifi: mt76: mt7996: Add air monitor support
 
 ---
  mt76_connac_mcu.h |   1 +
@@ -13,10 +13,10 @@
  6 files changed, 445 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 25b467e5d..6d9b0df2d 100644
+index fae76c9..bbf600b 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1220,6 +1220,7 @@ enum {
+@@ -1222,6 +1222,7 @@ enum {
  	MCU_UNI_CMD_REG_ACCESS = 0x0d,
  	MCU_UNI_CMD_CHIP_CONFIG = 0x0e,
  	MCU_UNI_CMD_POWER_CTRL = 0x0f,
@@ -25,10 +25,10 @@
  	MCU_UNI_CMD_SER = 0x13,
  	MCU_UNI_CMD_TWT = 0x14,
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index f00133489..6b8000303 100644
+index 637f0f6..ee17d59 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -650,6 +650,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -679,6 +679,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
  			if (ieee80211_has_a4(fc) && is_mesh && status->amsdu)
  				*qos &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
  		}
@@ -38,9 +38,9 @@
 +#endif
  	} else {
  		status->flag |= RX_FLAG_8023;
- 	}
+ 		mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
 diff --git a/mt7996/main.c b/mt7996/main.c
-index ab5693e4f..c1d4b3805 100644
+index 6fa4a65..804c0c1 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -696,6 +696,10 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -55,10 +55,10 @@
  	if (ret)
  		return ret;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 88ccb3060..2f4bbee70 100644
+index 013122f..3c535be 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -178,6 +178,34 @@ enum {
+@@ -205,6 +205,34 @@ enum {
  	SCS_ENABLE,
  };
  
@@ -90,10 +90,10 @@
 +};
 +#endif
 +
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -228,6 +256,10 @@ struct mt7996_phy {
+ struct mt7996_wed_rro_addr {
+ 	u32 head_low;
+ 	u32 head_high : 4;
+@@ -264,6 +292,10 @@ struct mt7996_phy {
  		u8 spe_idx;
  	} test;
  #endif
@@ -104,7 +104,7 @@
  };
  
  struct mt7996_dev {
-@@ -624,6 +656,9 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -687,6 +719,9 @@ u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
  #ifdef CONFIG_MTK_VENDOR
  void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
  void mt7996_vendor_register(struct mt7996_phy *phy);
@@ -115,7 +115,7 @@
  
  #ifdef CONFIG_MTK_DEBUG
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index b5ecbdf1d..f3b089d72 100644
+index b5ecbdf..f3b089d 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -16,6 +16,32 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
@@ -506,7 +506,7 @@
 +	spin_lock_init(&phy->amnt_lock);
  }
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 8ac3ba8ed..2078cafaf 100644
+index 8ac3ba8..2078caf 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -4,6 +4,7 @@
@@ -561,5 +561,5 @@
 +
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
index 84d1834..672885d 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1009-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
@@ -1,8 +1,8 @@
-From 953b2c0c19abfbb13e2445857b71ab4a999fe6cb Mon Sep 17 00:00:00 2001
+From 786bd792b2a62dee5e4aca8aa09ed01be1731ec4 Mon Sep 17 00:00:00 2001
 From: mtk23510 <rudra.shahi@mediatek.com>
 Date: Fri, 24 Mar 2023 19:18:53 +0800
-Subject: [PATCH 1009/1024] wifi: mt76: mt7996: add driver support for wpa3 ocv
- and bp mt76
+Subject: [PATCH 42/98] wifi: mt76: mt7996: add driver support for wpa3 ocv and
+ bp mt76
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
 ---
@@ -10,10 +10,10 @@
  1 file changed, 2 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 5644bba4a..70af2f964 100644
+index 1f4e84d..5940e41 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -374,6 +374,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+@@ -377,6 +377,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
  
@@ -23,5 +23,5 @@
  	    !of_property_read_bool(mdev->dev->of_node,
  				   "mediatek,disable-radar-background"))
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
index e7f7a34..1185d02 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1010-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
@@ -1,7 +1,7 @@
-From 8cbf5b49e3ecfa038198362d6141c195d12753bd Mon Sep 17 00:00:00 2001
+From db3b9fa4bc9c70231b7237dee2f7bcf35c6135f2 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 31 Mar 2023 11:27:24 +0800
-Subject: [PATCH 1010/1024] wifi: mt76: testmode: add testmode pre-calibration
+Subject: [PATCH 43/98] wifi: mt76: testmode: add testmode pre-calibration
  support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -22,7 +22,7 @@
  12 files changed, 632 insertions(+), 23 deletions(-)
 
 diff --git a/mac80211.c b/mac80211.c
-index 5740ba061..ef4b83244 100644
+index f10ca90..9c582cb 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -7,27 +7,6 @@
@@ -54,7 +54,7 @@
  	CHAN2G(1, 2412),
  	CHAN2G(2, 2417),
 diff --git a/mt76.h b/mt76.h
-index ad1123c4a..f58a955d6 100644
+index feb861c..fc69d3e 100644
 --- a/mt76.h
 +++ b/mt76.h
 @@ -18,6 +18,27 @@
@@ -85,7 +85,7 @@
  #define MT_MCU_RING_SIZE	32
  #define MT_RX_BUF_SIZE		2048
  #define MT_SKB_HEAD_LEN		256
-@@ -660,6 +681,7 @@ struct mt76_testmode_ops {
+@@ -694,6 +715,7 @@ struct mt76_testmode_ops {
  	int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
  	void (*reset_rx_stats)(struct mt76_phy *phy);
  	void (*tx_stop)(struct mt76_phy *phy);
@@ -94,10 +94,10 @@
  
  #define MT_TM_FW_RX_COUNT	BIT(0)
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 6d9b0df2d..b2c22568d 100644
+index bbf600b..d65ecf0 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1021,8 +1021,10 @@ enum {
+@@ -1023,8 +1023,10 @@ enum {
  	MCU_UNI_EVENT_RDD_REPORT = 0x11,
  	MCU_UNI_EVENT_ROC = 0x27,
  	MCU_UNI_EVENT_TX_DONE = 0x2d,
@@ -109,7 +109,7 @@
  	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
  };
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index bdb81018b..374f0e558 100644
+index e4c4b86..b88fd64 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -12,6 +12,42 @@ static bool testmode_enable;
@@ -193,7 +193,7 @@
  mt7996_eeprom_load_default(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 343e65e18..7ff290f40 100644
+index 343e65e..7ff290f 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -258,7 +258,7 @@
  #define MT_EE_WIFI_CONF2_TX_PATH_BAND1		GENMASK(2, 0)
  #define MT_EE_WIFI_CONF2_TX_PATH_BAND2		GENMASK(5, 3)
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 554f40ca2..dd3374a99 100644
+index a008c08..d6f4e22 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -623,6 +623,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -274,10 +274,10 @@
  		break;
  	}
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 2f4bbee70..91d759ec4 100644
+index 3c535be..684c254 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -333,6 +333,9 @@ struct mt7996_dev {
+@@ -385,6 +385,9 @@ struct mt7996_dev {
  	struct dentry *debugfs_dir;
  	struct rchan *relay_fwlog;
  
@@ -287,7 +287,7 @@
  	struct {
  		u8 table_mask;
  		u8 n_agrt;
-@@ -466,6 +469,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+@@ -521,6 +524,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
  int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
  				   struct ieee80211_channel *chan);
  s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band);
@@ -295,7 +295,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);
-@@ -549,6 +553,9 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+@@ -606,6 +610,9 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
  int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
  int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
@@ -306,7 +306,7 @@
  static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
  {
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index fb041c336..8ceea00b1 100644
+index fb041c3..8ceea00 100644
 --- a/mt7996/testmode.c
 +++ b/mt7996/testmode.c
 @@ -7,6 +7,8 @@
@@ -773,7 +773,7 @@
 +	.dump_precal = mt7996_tm_dump_precal,
  };
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
-index e4d55a61a..17c1456d3 100644
+index e4d55a6..17c1456 100644
 --- a/mt7996/testmode.h
 +++ b/mt7996/testmode.h
 @@ -34,6 +34,12 @@ enum bw_mapping_method {
@@ -835,7 +835,7 @@
  	RF_OPER_NORMAL,
  	RF_OPER_RF_TEST,
 diff --git a/testmode.c b/testmode.c
-index bbe8230fd..e66b54ae5 100644
+index bbe8230..e66b54a 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -631,6 +631,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
@@ -858,7 +858,7 @@
  		err = -EINVAL;
  
 diff --git a/testmode.h b/testmode.h
-index 141bb8625..db8ff53db 100644
+index 141bb86..db8ff53 100644
 --- a/testmode.h
 +++ b/testmode.h
 @@ -219,6 +219,14 @@ enum mt76_testmode_state {
@@ -877,7 +877,7 @@
  
  	/* keep last */
 diff --git a/tools/fields.c b/tools/fields.c
-index 055f90f3c..b01227638 100644
+index 055f90f..b012276 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
@@ -896,5 +896,5 @@
  
  static const char * const testmode_tx_mode[] = {
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch
index 26b8f02..6d1a987 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1011-wifi-mt76-mt7996-add-binfile-mode-support.patch
@@ -1,7 +1,7 @@
-From bc410b015f16893931f9be037140642cfe38ac88 Mon Sep 17 00:00:00 2001
+From 2cd9ab05b3a16a92fb2552102b2a9c36834d1e7d Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Fri, 31 Mar 2023 11:36:34 +0800
-Subject: [PATCH 1011/1024] wifi: mt76: mt7996: add binfile mode support
+Subject: [PATCH 44/98] wifi: mt76: mt7996: add binfile mode support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -14,7 +14,7 @@
  6 files changed, 112 insertions(+), 3 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 437d8ca24..89bb91335 100644
+index 437d8ca..89bb913 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -159,6 +159,26 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
@@ -45,10 +45,10 @@
  mt76_eeprom_override(struct mt76_phy *phy)
  {
 diff --git a/mt76.h b/mt76.h
-index f58a955d6..e6604de45 100644
+index fc69d3e..0bf0177 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -911,6 +911,8 @@ struct mt76_dev {
+@@ -945,6 +945,8 @@ struct mt76_dev {
  		struct mt76_usb usb;
  		struct mt76_sdio sdio;
  	};
@@ -57,7 +57,7 @@
  };
  
  /* per-phy stats.  */
-@@ -1143,6 +1145,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
+@@ -1190,6 +1192,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);
@@ -66,7 +66,7 @@
  struct mt76_queue *
  mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 374f0e558..4e50460be 100644
+index b88fd64..ca91c69 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
 @@ -61,8 +61,11 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
@@ -149,7 +149,7 @@
  	}
  
  	return mt7996_check_eeprom(dev);
-@@ -308,6 +342,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+@@ -309,6 +343,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
  			return ret;
  
  		dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
@@ -159,7 +159,7 @@
  		if (ret)
  			return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 7ff290f40..20dd87714 100644
+index 7ff290f..20dd877 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -99,6 +99,13 @@ enum mt7996_eeprom_band {
@@ -177,11 +177,11 @@
  mt7996_get_channel_group_5g(int channel)
  {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 91d759ec4..64e1bebf7 100644
+index 684c254..cda557e 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -323,6 +323,8 @@ struct mt7996_dev {
- 	bool has_eht:1;
+@@ -375,6 +375,8 @@ struct mt7996_dev {
+ 	} wed_rro;
  
  	bool testmode_enable;
 +	bool bin_file_mode;
@@ -189,7 +189,7 @@
  
  	bool ibf;
  	u8 fw_debug_wm;
-@@ -463,6 +465,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
+@@ -518,6 +520,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
  u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
  int mt7996_register_device(struct mt7996_dev *dev);
  void mt7996_unregister_device(struct mt7996_dev *dev);
@@ -198,7 +198,7 @@
  int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev);
  int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 57fcbab35..82b2785bd 100644
+index 57fcbab..82b2785 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
 @@ -2551,6 +2551,44 @@ static const struct file_operations mt7996_txpower_sku_fops = {
@@ -256,5 +256,5 @@
  	debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
  				    mt7996_wtbl_read);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
index 07f0518..3aac8a9 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1012-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
@@ -1,7 +1,7 @@
-From 43266cd8b1ba9bedd0541e994435017bb1bcbec6 Mon Sep 17 00:00:00 2001
+From 114d3abef99827bcc848e6aef393be79a7c34e71 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 1 Mar 2023 12:12:51 +0800
-Subject: [PATCH 1012/1024] wifi: mt76: mt7996: add normal mode pre-calibration
+Subject: [PATCH 45/98] wifi: mt76: mt7996: add normal mode pre-calibration
  support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
@@ -16,11 +16,11 @@
  7 files changed, 206 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index b2c22568d..196b4921d 100644
+index d65ecf0..762ac29 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1248,6 +1248,7 @@ enum {
- 	MCU_UNI_CMD_VOW = 0x37,
+@@ -1251,6 +1251,7 @@ enum {
+ 	MCU_UNI_CMD_PP = 0x38,
  	MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
  	MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
 +	MCU_UNI_CMD_PRECAL_RESULT = 0x47,
@@ -28,10 +28,10 @@
  	MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
  	MCU_UNI_CMD_PER_STA_INFO = 0x6d,
 diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 4e50460be..ac8e229a8 100644
+index ca91c69..56605de 100644
 --- a/mt7996/eeprom.c
 +++ b/mt7996/eeprom.c
-@@ -332,6 +332,25 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
+@@ -333,6 +333,25 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
  	return mt7996_eeprom_parse_band_config(phy);
  }
  
@@ -57,7 +57,7 @@
  int mt7996_eeprom_init(struct mt7996_dev *dev)
  {
  	int ret;
-@@ -349,6 +368,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+@@ -350,6 +369,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
  			return ret;
  	}
  
@@ -69,7 +69,7 @@
  	if (ret < 0)
  		return ret;
 diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 20dd87714..0f3f31d8f 100644
+index 20dd877..0f3f31d 100644
 --- a/mt7996/eeprom.h
 +++ b/mt7996/eeprom.h
 @@ -25,6 +25,8 @@ enum mt7996_eeprom_field {
@@ -82,10 +82,10 @@
  
  #define MT_EE_WIFI_CONF0_TX_PATH		GENMASK(2, 0)
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 70af2f964..06e6f30f3 100644
+index 5940e41..bf3479e 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -685,6 +685,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -826,6 +826,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
  	if (ret < 0)
  		return ret;
  
@@ -99,7 +99,7 @@
  	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);
  	if (idx)
 diff --git a/mt7996/main.c b/mt7996/main.c
-index c1d4b3805..f2e2de850 100644
+index 804c0c1..7d1bd42 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -312,6 +312,12 @@ int mt7996_set_channel(struct mt7996_phy *phy)
@@ -116,10 +116,10 @@
  	if (ret)
  		goto out;
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index dd3374a99..802b21685 100644
+index d6f4e22..695d5f0 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3493,6 +3493,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
+@@ -3456,6 +3456,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
  	return 0;
  }
  
@@ -293,11 +293,11 @@
  {
  #define NIC_CAP	3
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 64e1bebf7..99d4659f1 100644
+index cda557e..80a10bf 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -554,6 +554,8 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
- void mt7996_mcu_exit(struct mt7996_dev *dev);
+@@ -611,6 +611,8 @@ void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
  int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
  int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
 +int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
@@ -306,5 +306,5 @@
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  #ifdef CONFIG_NL80211_TESTMODE
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
index 9c6e4cb..9a38681 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1013-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
@@ -1,7 +1,7 @@
-From fe8bcf023b97cb281774611d95745bd2b1c14d9c Mon Sep 17 00:00:00 2001
+From a20311a499edde8f5b8e6b4bced55bd5e0f25884 Mon Sep 17 00:00:00 2001
 From: mtk23510 <rudra.shahi@mediatek.com>
 Date: Wed, 26 Apr 2023 20:08:10 +0800
-Subject: [PATCH 1013/1024] wifi: mt76: mt7996: Beacon protection feature added
+Subject: [PATCH 46/98] wifi: mt76: mt7996: Beacon protection feature added
 
 Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
 Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
@@ -14,10 +14,10 @@
  5 files changed, 153 insertions(+), 43 deletions(-)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 196b4921d..21cae4bf4 100644
+index 762ac29..42eb64c 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -416,6 +416,14 @@ struct sta_rec_he_6g_capa {
+@@ -418,6 +418,14 @@ struct sta_rec_he_6g_capa {
  	u8 rsv[2];
  } __packed;
  
@@ -32,7 +32,7 @@
  struct sec_key {
  	u8 cipher_id;
  	u8 cipher_len;
-@@ -768,6 +776,7 @@ struct wtbl_raw {
+@@ -770,6 +778,7 @@ struct wtbl_raw {
  					 sizeof(struct sta_rec_sec) +	\
  					 sizeof(struct sta_rec_ra_fixed) + \
  					 sizeof(struct sta_rec_he_6g_capa) + \
@@ -40,7 +40,7 @@
  					 sizeof(struct tlv) +		\
  					 MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
  
-@@ -798,6 +807,7 @@ enum {
+@@ -800,6 +809,7 @@ enum {
  	STA_REC_HE_V2 = 0x19,
  	STA_REC_MLD = 0x20,
  	STA_REC_EHT = 0x22,
@@ -48,7 +48,7 @@
  	STA_REC_HDRT = 0x28,
  	STA_REC_HDR_TRANS = 0x2B,
  	STA_REC_MAX_NUM
-@@ -1091,6 +1101,13 @@ enum mcu_cipher_type {
+@@ -1093,6 +1103,13 @@ enum mcu_cipher_type {
  	MCU_CIPHER_GCMP_256,
  	MCU_CIPHER_WAPI,
  	MCU_CIPHER_BIP_CMAC_128,
@@ -62,7 +62,7 @@
  };
  
  enum {
-@@ -1316,6 +1333,7 @@ enum {
+@@ -1319,6 +1336,7 @@ enum {
  	UNI_BSS_INFO_RATE = 11,
  	UNI_BSS_INFO_QBSS = 15,
  	UNI_BSS_INFO_SEC = 16,
@@ -70,7 +70,7 @@
  	UNI_BSS_INFO_TXCMD = 18,
  	UNI_BSS_INFO_UAPSD = 19,
  	UNI_BSS_INFO_PS = 21,
-@@ -1776,6 +1794,12 @@ mt76_connac_mcu_get_cipher(int cipher)
+@@ -1779,6 +1797,12 @@ mt76_connac_mcu_get_cipher(int cipher)
  		return MCU_CIPHER_GCMP;
  	case WLAN_CIPHER_SUITE_GCMP_256:
  		return MCU_CIPHER_GCMP_256;
@@ -84,7 +84,7 @@
  		return MCU_CIPHER_WAPI;
  	default:
 diff --git a/mt7996/main.c b/mt7996/main.c
-index f2e2de850..d8c8a5fac 100644
+index 7d1bd42..0ea006c 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -368,8 +368,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -117,10 +117,10 @@
  	mutex_unlock(&dev->mt76.mutex);
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 802b21685..22417e410 100644
+index 695d5f0..1a1c732 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2155,7 +2155,6 @@ out:
+@@ -2118,7 +2118,6 @@ out:
  
  static int
  mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
@@ -128,7 +128,7 @@
  		       struct sk_buff *skb,
  		       struct ieee80211_key_conf *key,
  		       enum set_key_cmd cmd)
-@@ -2176,43 +2175,22 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
+@@ -2139,43 +2138,22 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
  			return -EOPNOTSUPP;
  
  		sec_key = &sec->key[0];
@@ -186,7 +186,7 @@
  	} else {
  		sec->n_cipher = 0;
  	}
-@@ -2221,7 +2199,6 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
+@@ -2184,7 +2162,6 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,
  }
  
  int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
@@ -194,7 +194,7 @@
  		       struct ieee80211_key_conf *key, int mcu_cmd,
  		       struct mt76_wcid *wcid, enum set_key_cmd cmd)
  {
-@@ -2234,13 +2211,98 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
+@@ -2197,13 +2174,98 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
  	if (IS_ERR(skb))
  		return PTR_ERR(skb);
  
@@ -295,10 +295,10 @@
  			    struct ieee80211_vif *vif, bool enable)
  {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 1d7748771..512d8543b 100644
+index c5c0a44..7808c35 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -313,6 +313,23 @@ struct bss_rate_tlv {
+@@ -310,6 +310,23 @@ struct bss_rate_tlv {
  	u8 __rsv2[9];
  } __packed;
  
@@ -323,10 +323,10 @@
  	__le16 tag;
  	__le16 len;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 99d4659f1..b75523ff4 100644
+index 80a10bf..9f99d13 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -654,9 +654,10 @@ int mt7996_init_debugfs(struct mt7996_phy *phy);
+@@ -712,9 +712,10 @@ int mt7996_init_debugfs(struct mt7996_phy *phy);
  void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len);
  bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len);
  int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
@@ -339,5 +339,5 @@
  				     struct ieee80211_vif *vif,
  				     struct ieee80211_sta *sta);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
index d9f4bf5..16439d4 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1014-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
@@ -1,8 +1,8 @@
-From f6c3798a8abc8c28a509ed11b024ada9153820eb Mon Sep 17 00:00:00 2001
+From 9bbc79e25d5fe7c14ec520413f4fb0625af9c630 Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 22 Mar 2023 11:19:52 +0800
-Subject: [PATCH 1014/1024] wifi: mt76: testmode: add testmode ZWDFS
- verification support
+Subject: [PATCH 47/98] wifi: mt76: testmode: add testmode ZWDFS verification
+ support
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
@@ -15,10 +15,10 @@
  6 files changed, 326 insertions(+), 12 deletions(-)
 
 diff --git a/mt76.h b/mt76.h
-index e6604de45..0946a3bfb 100644
+index 0bf0177..0096c7f 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -740,6 +740,14 @@ struct mt76_testmode_data {
+@@ -774,6 +774,14 @@ struct mt76_testmode_data {
  	} cfg;
  
  	u8 aid;
@@ -34,10 +34,10 @@
  
  struct mt76_vif {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index b75523ff4..e3b014889 100644
+index 9f99d13..7269076 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -236,6 +236,7 @@ struct mt7996_phy {
+@@ -272,6 +272,7 @@ struct mt7996_phy {
  
  	struct mt76_mib_stats mib;
  	struct mt76_channel_state state_ts;
@@ -46,7 +46,7 @@
  	bool has_aux_rx;
  
 diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index 8ceea00b1..c52bf41bd 100644
+index 8ceea00..c52bf41 100644
 --- a/mt7996/testmode.c
 +++ b/mt7996/testmode.c
 @@ -17,6 +17,12 @@ enum {
@@ -336,7 +336,7 @@
  
  static int
 diff --git a/mt7996/testmode.h b/mt7996/testmode.h
-index 17c1456d3..57fde8c0a 100644
+index 17c1456..57fde8c 100644
 --- a/mt7996/testmode.h
 +++ b/mt7996/testmode.h
 @@ -27,9 +27,15 @@ enum {
@@ -399,7 +399,7 @@
 +
  #endif
 diff --git a/testmode.c b/testmode.c
-index e66b54ae5..bce3a9c1a 100644
+index e66b54a..bce3a9c 100644
 --- a/testmode.c
 +++ b/testmode.c
 @@ -27,6 +27,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
@@ -453,7 +453,7 @@
  	     nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
  	    (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
 diff --git a/tools/fields.c b/tools/fields.c
-index b01227638..77696ce7b 100644
+index b012276..77696ce 100644
 --- a/tools/fields.c
 +++ b/tools/fields.c
 @@ -35,6 +35,15 @@ static const char * const testmode_tx_mode[] = {
@@ -486,5 +486,5 @@
  	FIELD_NESTED_RO(STATS, stats, "",
  			.print_extra = print_extra_stats),
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1015-wifi-mt76-mt7996-add-single-sku.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1015-wifi-mt76-mt7996-add-single-sku.patch
index 8970f81..14514e2 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1015-wifi-mt76-mt7996-add-single-sku.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1015-wifi-mt76-mt7996-add-single-sku.patch
@@ -1,7 +1,7 @@
-From 31ab01539098f7f093da92fd1e2052b4eb4951ce Mon Sep 17 00:00:00 2001
+From d07d8b3b246b974d7ae4ad9bdfc676438cb45fec Mon Sep 17 00:00:00 2001
 From: "Allen.Ye" <allen.ye@mediatek.com>
 Date: Mon, 10 Jul 2023 19:56:16 +0800
-Subject: [PATCH 1015/1024] wifi: mt76: mt7996: add single sku
+Subject: [PATCH 48/98] wifi: mt76: mt7996: add single sku
 
 Add single sku and default enable sku.
 
@@ -18,7 +18,7 @@
  8 files changed, 179 insertions(+), 6 deletions(-)
 
 diff --git a/eeprom.c b/eeprom.c
-index 89bb91335..bd662dd4d 100644
+index 89bb913..bd662dd 100644
 --- a/eeprom.c
 +++ b/eeprom.c
 @@ -356,6 +356,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
@@ -104,10 +104,10 @@
  EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
  
 diff --git a/mt76.h b/mt76.h
-index 0946a3bfb..9f84389b7 100644
+index 0096c7f..d59a1f5 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -1026,6 +1026,14 @@ struct mt76_power_limits {
+@@ -1060,6 +1060,14 @@ struct mt76_power_limits {
  	s8 eht[16][16];
  };
  
@@ -122,16 +122,16 @@
  struct mt76_ethtool_worker_info {
  	u64 *data;
  	int idx;
-@@ -1607,6 +1615,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
+@@ -1655,6 +1663,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
  s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
  			      struct ieee80211_channel *chan,
  			      struct mt76_power_limits *dest,
 +			      struct mt76_power_path_limits *dest_path,
  			      s8 target_power);
  
- static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+ static inline bool mt76_queue_is_wed_tx_free(struct mt76_queue *q)
 diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 236cfea6a..214a526f0 100644
+index 236cfea..214a526 100644
 --- a/mt76_connac_mcu.c
 +++ b/mt76_connac_mcu.c
 @@ -2269,7 +2269,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
@@ -144,10 +144,10 @@
  			tx_power_tlv.last_msg = ch_list[idx] == last_ch;
  			sku_tlbv.channel = ch_list[idx];
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 06e6f30f3..5d8ecf038 100644
+index bf3479e..ad93927 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -294,6 +294,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+@@ -295,6 +295,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
  	int nss_delta = mt76_tx_power_nss_delta(nss);
  	int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
  	struct mt76_power_limits limits;
@@ -155,7 +155,7 @@
  
  	for (i = 0; i < sband->n_channels; i++) {
  		struct ieee80211_channel *chan = &sband->channels[i];
-@@ -302,6 +303,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+@@ -303,6 +304,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
  		target_power += pwr_delta;
  		target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
  							  &limits,
@@ -164,7 +164,7 @@
  		target_power += nss_delta;
  		target_power = DIV_ROUND_UP(target_power, 2);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index d8c8a5fac..b97483b6f 100644
+index 0ea006c..9e3e4ed 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -205,10 +205,10 @@
  	mutex_unlock(&dev->mt76.mutex);
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 22417e410..8260604ac 100644
+index 1a1c732..c87cb1a 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -4716,6 +4716,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+@@ -4708,6 +4708,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
  				 &req, sizeof(req), false);
  }
  
@@ -308,10 +308,10 @@
  void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
  {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 512d8543b..f6a8ee348 100644
+index 7808c35..6fc5ab3 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -781,6 +781,18 @@ enum {
+@@ -777,6 +777,18 @@ enum {
  #define MT7996_MAX_BSS_OFFLOAD_SIZE	(MT7996_MAX_BEACON_SIZE +		\
  					 MT7996_BEACON_UPDATE_SIZE)
  
@@ -331,18 +331,18 @@
  	UNI_BAND_CONFIG_RADIO_ENABLE,
  	UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index e3b014889..a5f97b55b 100644
+index 7269076..34c8fe6 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -62,6 +62,7 @@
+@@ -64,6 +64,7 @@
  #define MT7996_BUILD_TIME_LEN		24
  
  #define MT7996_SKU_RATE_NUM		417
 +#define MT7996_SKU_PATH_NUM		494
  
- struct mt7996_vif;
- struct mt7996_sta;
-@@ -557,6 +558,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ #define MT7996_RRO_MAX_SESSION		1024
+ #define MT7996_RRO_WINDOW_MAX_LEN	1024
+@@ -614,6 +615,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
  int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
  int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
  int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
@@ -351,5 +351,5 @@
  void mt7996_mcu_scs_sta_poll(struct work_struct *work);
  #ifdef CONFIG_NL80211_TESTMODE
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
index 5f40900..37717c3 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1016-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
@@ -1,7 +1,7 @@
-From 0295315c5ff56a9bb731d2186cbf85bd7100ac4c Mon Sep 17 00:00:00 2001
+From 8d1ba9d8e0f80eedcdf14d29dbca9c3cbd8589dc Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 3 May 2023 05:08:07 +0800
-Subject: [PATCH 1016/1024] wifi: mt76: mt7996: add vendor cmd to get available
+Subject: [PATCH 49/98] wifi: mt76: mt7996: 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, 47 insertions(+)
 
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index f3b089d72..391015777 100644
+index f3b089d..3910157 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -35,6 +35,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
@@ -75,7 +75,7 @@
  
  void mt7996_vendor_register(struct mt7996_phy *phy)
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index 2078cafaf..eec9e74a2 100644
+index 2078caf..eec9e74 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -6,6 +6,7 @@
@@ -103,5 +103,5 @@
  
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
index 6786b59..da8c4bd 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1017-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
@@ -1,7 +1,7 @@
-From 5b806ed8a6d74c27ff9752af8a2a92ce2d141427 Mon Sep 17 00:00:00 2001
+From 7556e60ec860e301a053dad4b16b7e88ccd9baa7 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Fri, 19 May 2023 14:56:07 +0800
-Subject: [PATCH 1017/1024] wifi: mt76: mt7996: add debugfs for fw coredump.
+Subject: [PATCH 50/98] wifi: mt76: mt7996: add debugfs for fw coredump.
 
 Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
 ---
@@ -12,7 +12,7 @@
  4 files changed, 56 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 92aa1644f..2c1183723 100644
+index 92aa164..2c11837 100644
 --- a/mt7996/debugfs.c
 +++ b/mt7996/debugfs.c
 @@ -84,6 +84,8 @@ mt7996_sys_recovery_set(struct file *file, const char __user *user_buf,
@@ -64,10 +64,10 @@
  	desc += scnprintf(buff + desc, bufsz - desc,
  			  "\nlet's dump firmware SER statistics...\n");
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 6b8000303..6e79be8de 100644
+index ee17d59..37cc94e 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1961,15 +1961,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
+@@ -2021,15 +2021,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
  	struct mt7996_dev *dev;
  
  	dev = container_of(work, struct mt7996_dev, dump_work);
@@ -107,7 +107,7 @@
  void mt7996_reset(struct mt7996_dev *dev)
  {
  	if (!dev->recovery.hw_init_done)
-@@ -1987,6 +2008,7 @@ void mt7996_reset(struct mt7996_dev *dev)
+@@ -2047,6 +2068,7 @@ void mt7996_reset(struct mt7996_dev *dev)
  
  		mt7996_irq_disable(dev, MT_INT_MCU_CMD);
  		queue_work(dev->mt76.wq, &dev->dump_work);
@@ -116,10 +116,10 @@
  	}
  
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index f6a8ee348..1b1f605d1 100644
+index 6fc5ab3..989a2ff 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -904,7 +904,11 @@ enum {
+@@ -900,7 +900,11 @@ enum {
  	UNI_CMD_SER_SET_RECOVER_L3_BF,
  	UNI_CMD_SER_SET_RECOVER_L4_MDP,
  	UNI_CMD_SER_SET_RECOVER_FULL,
@@ -132,10 +132,10 @@
  	UNI_CMD_SER_ENABLE = 1,
  	UNI_CMD_SER_SET,
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index a5f97b55b..43154e542 100644
+index 34c8fe6..9b110cf 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -82,6 +82,14 @@ enum mt7996_ram_type {
+@@ -100,6 +100,14 @@ enum mt7996_ram_type {
  	__MT7996_RAM_TYPE_MAX,
  };
  
@@ -150,7 +150,7 @@
  enum mt7996_txq_id {
  	MT7996_TXQ_FWDL = 16,
  	MT7996_TXQ_MCU_WM,
-@@ -306,6 +314,7 @@ struct mt7996_dev {
+@@ -342,6 +350,7 @@ struct mt7996_dev {
  
  	/* protects coredump data */
  	struct mutex dump_mutex;
@@ -158,7 +158,7 @@
  #ifdef CONFIG_DEV_COREDUMP
  	struct {
  		struct mt7996_crash_data *crash_data[__MT7996_RAM_TYPE_MAX];
-@@ -484,6 +493,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+@@ -541,6 +550,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
  			 struct ieee80211_supported_band *sband);
  int mt7996_txbf_init(struct mt7996_dev *dev);
  void mt7996_reset(struct mt7996_dev *dev);
@@ -167,5 +167,5 @@
  int mt7996_mcu_init(struct mt7996_dev *dev);
  int mt7996_mcu_init_firmware(struct mt7996_dev *dev);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
index e0ed32b..dc0b0c3 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1018-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
@@ -1,8 +1,8 @@
-From 84cb12629e944fdc2731efc4944c0fcd8c233087 Mon Sep 17 00:00:00 2001
+From a928c6df5edd9920b4293de6d1216461952aec27 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 6 Jun 2023 16:57:10 +0800
-Subject: [PATCH 1018/1024] wifi: mt76: mt7996: add support for runtime set
- in-band discovery
+Subject: [PATCH 51/98] wifi: mt76: mt7996: add support for runtime set in-band
+ discovery
 
 with this patch, AP can runtime set inband discovery via hostapd_cli
 
@@ -17,10 +17,10 @@
  1 file changed, 2 insertions(+), 3 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 8260604ac..7c40b8bb6 100644
+index c87cb1a..722c435 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -2521,8 +2521,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+@@ -2484,8 +2484,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
  	if (IS_ERR(rskb))
  		return PTR_ERR(rskb);
  
@@ -30,7 +30,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 &&
-@@ -2558,7 +2557,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+@@ -2521,7 +2520,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
  	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
  	discov->tx_interval = interval;
  	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
@@ -40,5 +40,5 @@
  
  	buf = (u8 *)tlv + sizeof(*discov);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
index b013595..06fc5e8 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1019-wifi-mt76-mt7996-add-vendor-subcmd-EDCCA-ctrl-enable.patch
@@ -1,8 +1,7 @@
-From d94e9301ccfd6ffd35ead052ebaa89afaefb9a88 Mon Sep 17 00:00:00 2001
+From 140f810c788ffccc605fa979635c9be2db4b9748 Mon Sep 17 00:00:00 2001
 From: mtk27745 <rex.lu@mediatek.com>
 Date: Thu, 8 Jun 2023 20:21:04 +0800
-Subject: [PATCH 1019/1024] wifi: mt76: mt7996: add vendor subcmd EDCCA ctrl
- enable
+Subject: [PATCH 52/98] wifi: mt76: mt7996: add vendor subcmd EDCCA ctrl enable
 
 ---
  mt7996/main.c    |   3 ++
@@ -15,7 +14,7 @@
  7 files changed, 282 insertions(+)
 
 diff --git a/mt7996/main.c b/mt7996/main.c
-index b97483b6f..3ce31786a 100644
+index 9e3e4ed..d928564 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -431,6 +431,9 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
@@ -29,10 +28,10 @@
  		ret = mt7996_set_channel(phy);
  		if (ret)
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 1b1f605d1..47fd1874d 100644
+index 989a2ff..bb876f3 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -795,6 +795,8 @@ mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
+@@ -791,6 +791,8 @@ mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
  
  enum {
  	UNI_BAND_CONFIG_RADIO_ENABLE,
@@ -42,10 +41,10 @@
  };
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 43154e542..eda74f7a9 100644
+index 9b110cf..8fd29d7 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -687,6 +687,17 @@ int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
+@@ -750,6 +750,17 @@ int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
  				  struct ieee80211_sta *sta);
  #endif
  
@@ -64,7 +63,7 @@
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
  #endif
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index f772243b8..048c53475 100644
+index f772243..048c534 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
 @@ -38,4 +38,90 @@ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *even
@@ -159,7 +158,7 @@
 +
  #endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index beb1aba24..9c0db87bb 100644
+index beb1aba..9c0db87 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
 @@ -89,6 +89,21 @@ enum txpower_event {
@@ -185,7 +184,7 @@
  
  #endif
 diff --git a/mt7996/vendor.c b/mt7996/vendor.c
-index 391015777..9f333d0ee 100644
+index 3910157..9f333d0 100644
 --- a/mt7996/vendor.c
 +++ b/mt7996/vendor.c
 @@ -40,6 +40,26 @@ bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = {
@@ -342,7 +341,7 @@
  
  void mt7996_vendor_register(struct mt7996_phy *phy)
 diff --git a/mt7996/vendor.h b/mt7996/vendor.h
-index eec9e74a2..4465bc9df 100644
+index eec9e74..4465bc9 100644
 --- a/mt7996/vendor.h
 +++ b/mt7996/vendor.h
 @@ -6,9 +6,42 @@
@@ -389,5 +388,5 @@
  	MTK_VENDOR_ATTR_MU_CTRL_UNSPEC,
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch
index 61106fc..f7596bb 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1020-wifi-mt76-mt7996-Fix-incorrect-UWTBL_LEN_IN_DW-param.patch
@@ -1,7 +1,7 @@
-From 1443f908c6eb33e33413fd20016be92f24557ce4 Mon Sep 17 00:00:00 2001
+From e24d476d4baca1aa3a32ac82ec0f1ea56cedf06c Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Wed, 28 Jun 2023 05:07:43 +0800
-Subject: [PATCH 1020/1024] wifi: mt76: mt7996: Fix incorrect UWTBL_LEN_IN_DW
+Subject: [PATCH 53/98] wifi: mt76: mt7996: Fix incorrect UWTBL_LEN_IN_DW
  parameter
 
 The UWTBL length is 16 DW. Correct the len to 16 so that we can
@@ -13,7 +13,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
-index 368f0bcf0..9718c2cbe 100644
+index 368f0bc..9718c2c 100644
 --- a/mt7996/mtk_debug.h
 +++ b/mt7996/mtk_debug.h
 @@ -834,7 +834,7 @@ enum cipher_suit {
@@ -26,5 +26,5 @@
  #define MT_DBG_WTBL_BASE		0x820D8000
  
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
index b201ac8..142193f 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1021-wifi-mt76-mt7996-add-support-spatial-reuse-debug-com.patch
@@ -1,7 +1,7 @@
-From 980b02284098c3cb3555ae7ec586918c94b6d51d Mon Sep 17 00:00:00 2001
+From 86906513b2597a79c26b72a6a9dc0ecf8b0ce1ed Mon Sep 17 00:00:00 2001
 From: Howard Hsu <howard-yh.hsu@mediatek.com>
 Date: Mon, 10 Jul 2023 11:47:29 +0800
-Subject: [PATCH 1021/1024] wifi: mt76: mt7996: add support spatial reuse debug
+Subject: [PATCH 54/98] wifi: mt76: mt7996: add support spatial reuse debug
  commands
 
 This commit adds the following debug commands in debugfs:
@@ -26,10 +26,10 @@
  7 files changed, 267 insertions(+)
 
 diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 21cae4bf4..1d01b2b89 100644
+index 42eb64c..e904ebc 100644
 --- a/mt76_connac_mcu.h
 +++ b/mt76_connac_mcu.h
-@@ -1029,6 +1029,7 @@ enum {
+@@ -1031,6 +1031,7 @@ enum {
  	MCU_UNI_EVENT_BSS_BEACON_LOSS = 0x0c,
  	MCU_UNI_EVENT_SCAN_DONE = 0x0e,
  	MCU_UNI_EVENT_RDD_REPORT = 0x11,
@@ -38,7 +38,7 @@
  	MCU_UNI_EVENT_TX_DONE = 0x2d,
  	MCU_UNI_EVENT_BF = 0x33,
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 3ce31786a..bae25ceda 100644
+index d928564..35f8fee 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
 @@ -6,6 +6,9 @@
@@ -62,7 +62,7 @@
  					   !dev->dbg.sku_disable);
  #else
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 7c40b8bb6..76788907a 100644
+index 722c435..2dbec1e 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -617,6 +617,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -78,10 +78,10 @@
  		mt7996_mcu_rx_thermal_notify(dev, skb);
  		break;
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index eda74f7a9..feb82e440 100644
+index 8fd29d7..1fac783 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -270,6 +270,10 @@ struct mt7996_phy {
+@@ -306,6 +306,10 @@ struct mt7996_phy {
  	spinlock_t amnt_lock;
  	struct mt7996_air_monitor_ctrl amnt_ctrl;
  #endif
@@ -92,7 +92,7 @@
  };
  
  struct mt7996_dev {
-@@ -700,6 +704,8 @@ enum edcca_bw_id {
+@@ -763,6 +767,8 @@ enum edcca_bw_id {
  
  #ifdef CONFIG_MTK_DEBUG
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
@@ -100,9 +100,9 @@
 +void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
  #endif
  
- #endif
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 82b2785bd..f56ad88df 100644
+index 82b2785..f56ad88 100644
 --- a/mt7996/mtk_debugfs.c
 +++ b/mt7996/mtk_debugfs.c
 @@ -2589,6 +2589,83 @@ static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
@@ -202,7 +202,7 @@
  }
  
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index 048c53475..3256de7f5 100644
+index 048c534..3256de7 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
 @@ -124,4 +124,115 @@ int mt7996_mcu_edcca_threshold_ctrl(struct mt7996_phy *phy, u8 *value, bool set)
@@ -322,7 +322,7 @@
 +}
  #endif
 diff --git a/mt7996/mtk_mcu.h b/mt7996/mtk_mcu.h
-index 9c0db87bb..a5bdb8831 100644
+index 9c0db87..a5bdb88 100644
 --- a/mt7996/mtk_mcu.h
 +++ b/mt7996/mtk_mcu.h
 @@ -104,6 +104,62 @@ enum {
@@ -389,5 +389,5 @@
  
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
index c9f5a19..ac60aa8 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1022-wifi-mt76-mt7996-Establish-BA-in-VO-queue.patch
@@ -1,17 +1,17 @@
-From 279016e3f3eece9baf69c60dfcb907679788d948 Mon Sep 17 00:00:00 2001
+From d7337c25e774ed96fc8f6d1390321bfc2dcac545 Mon Sep 17 00:00:00 2001
 From: MeiChia Chiu <meichia.chiu@mediatek.com>
 Date: Tue, 1 Aug 2023 16:02:28 +0800
-Subject: [PATCH 1022/1024] wifi: mt76: mt7996: Establish BA in VO queue
+Subject: [PATCH 55/98] wifi: mt76: mt7996: Establish BA in VO queue
 
 ---
  mt7996/mac.c | 2 --
  1 file changed, 2 deletions(-)
 
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 6e79be8de..04e14fa30 100644
+index 37cc94e..b24f237 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -963,8 +963,6 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
+@@ -1017,8 +1017,6 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb)
  		return;
  
  	tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
@@ -21,5 +21,5 @@
  	if (is_8023)
  		fc = IEEE80211_FTYPE_DATA |
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
index fe1520e..9fbc586 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1023-wifi-mt76-mt7996-add-eagle-iFEM-HWITS-ZWDFS-SW-worka.patch
@@ -1,21 +1,21 @@
-From a94962822a9df3869525ec040e2698be0c39c1e6 Mon Sep 17 00:00:00 2001
+From b69722554a27e8c13612f62c9b9cf8651a30bd8f Mon Sep 17 00:00:00 2001
 From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 Date: Wed, 5 Jul 2023 10:00:17 +0800
-Subject: [PATCH 1023/1024] wifi: mt76: mt7996: add eagle iFEM HWITS ZWDFS SW
+Subject: [PATCH 56/98] wifi: mt76: mt7996: add eagle iFEM HWITS ZWDFS SW
  workaround
 
 Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
 ---
- mt7996/main.c   | 55 ++++++++++++++++++++++++++++++++++++++++++++++---
- mt7996/mcu.c    |  6 ++++--
+ mt7996/main.c   | 58 ++++++++++++++++++++++++++++++++++++++++++++++---
+ mt7996/mcu.c    |  6 +++--
  mt7996/mt7996.h |  1 +
- 3 files changed, 57 insertions(+), 5 deletions(-)
+ 3 files changed, 60 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/main.c b/mt7996/main.c
-index bae25ceda..a00ebf9e6 100644
+index 35f8fee..d27275a 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -1410,6 +1410,51 @@ mt7996_twt_teardown_request(struct ieee80211_hw *hw,
+@@ -1413,6 +1413,54 @@ mt7996_twt_teardown_request(struct ieee80211_hw *hw,
  	mutex_unlock(&dev->mt76.mutex);
  }
  
@@ -30,8 +30,11 @@
 +	bool is_ifem_adie, expand = false;
 +	u32 origin_control;
 +
-+	is_ifem_adie = is_mt7996(&dev->mt76) &&
-+		       !!(mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) % 2);
++	if (is_mt7996(&dev->mt76))
++		is_ifem_adie = !!(mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) % 2);
++	else
++		is_ifem_adie = (mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB_7992) == 1);
++
 +	if (!user_chandef || !is_ifem_adie)
 +		goto out;
 +
@@ -67,7 +70,7 @@
  static int
  mt7996_set_radar_background(struct ieee80211_hw *hw,
  			    struct cfg80211_chan_def *chandef)
-@@ -1418,6 +1463,7 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+@@ -1421,6 +1469,7 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
  	struct mt7996_dev *dev = phy->dev;
  	int ret = -EINVAL;
  	bool running;
@@ -75,7 +78,7 @@
  
  	mutex_lock(&dev->mt76.mutex);
  
-@@ -1430,13 +1476,14 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+@@ -1433,13 +1482,14 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
  		goto out;
  	}
  
@@ -92,7 +95,7 @@
  		ret = mt7996_mcu_rdd_background_enable(phy, NULL);
  		if (ret)
  			goto out;
-@@ -1445,7 +1492,9 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
+@@ -1448,7 +1498,9 @@ mt7996_set_radar_background(struct ieee80211_hw *hw,
  			goto update_phy;
  	}
  
@@ -104,7 +107,7 @@
  		goto out;
  
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 76788907a..f9387ea56 100644
+index 2dbec1e..a4f3ed9 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -350,12 +350,14 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -125,10 +128,10 @@
  }
  
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index feb82e440..6447b2c90 100644
+index 1fac783..413fbf7 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -340,6 +340,7 @@ struct mt7996_dev {
+@@ -392,6 +392,7 @@ struct mt7996_dev {
  	bool testmode_enable;
  	bool bin_file_mode;
  	u8 eeprom_mode;
@@ -137,5 +140,5 @@
  	bool ibf;
  	u8 fw_debug_wm;
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
index f029716..63afb2c 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1024-wifi-mt76-mt7996-report-tx-and-rx-byte-to-tpt_led.patch
@@ -1,15 +1,14 @@
-From 9debb7a31a3db9f8dd48a48d5705a2e8819d9d6a Mon Sep 17 00:00:00 2001
+From fd96728a963faf55b7daba46a78aa25ab0c5f147 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Sat, 12 Aug 2023 04:17:22 +0800
-Subject: [PATCH 1024/1024] wifi: mt76: mt7996: report tx and rx byte to
- tpt_led
+Subject: [PATCH 57/98] wifi: mt76: mt7996: report tx and rx byte to tpt_led
 
 ---
  mt7996/mcu.c | 15 +++++++++++----
  1 file changed, 11 insertions(+), 4 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index f9387ea56..5f18de031 100644
+index a4f3ed9..3a960d1 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -531,6 +531,8 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -43,5 +42,5 @@
  			break;
  		case UNI_ALL_STA_TXRX_MSDU_COUNT:
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1025-wifi-mt76-mt7996-support-dup-wtbl.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
index 8a9b045..12cdca3 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1025-wifi-mt76-mt7996-support-dup-wtbl.patch
@@ -1,7 +1,7 @@
-From 0b429d84b4fe85431a273899e89bcbb65ae3df38 Mon Sep 17 00:00:00 2001
+From a0baa183c16552ec874141c62ce3c6346d24c684 Mon Sep 17 00:00:00 2001
 From: Shayne Chen <shayne.chen@mediatek.com>
 Date: Thu, 21 Sep 2023 00:52:46 +0800
-Subject: [PATCH] wifi: mt76: mt7996: support dup wtbl
+Subject: [PATCH 58/98] wifi: mt76: mt7996: support dup wtbl
 
 Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
 Change-Id: I14ba41ace8341c23c1cfb6e9c4fbb2d5e93a5714
@@ -12,10 +12,10 @@
  3 files changed, 25 insertions(+)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 5d8ecf038..3001db325 100644
+index ad93927..4503482 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -641,6 +641,7 @@ static void mt7996_init_work(struct work_struct *work)
+@@ -660,6 +660,7 @@ static void mt7996_init_work(struct work_struct *work)
  	mt7996_init_txpower(dev, &dev->mphy.sband_5g.sband);
  	mt7996_init_txpower(dev, &dev->mphy.sband_6g.sband);
  	mt7996_txbf_init(dev);
@@ -24,19 +24,19 @@
  
  void mt7996_wfsys_reset(struct mt7996_dev *dev)
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 6447b2c90..d1633494c 100644
+index 413fbf7..766de3f 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -707,6 +707,7 @@ enum edcca_bw_id {
+@@ -770,6 +770,7 @@ enum edcca_bw_id {
  int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
  int mt7996_mcu_set_sr_enable(struct mt7996_phy *phy, u8 action, u64 val, bool set);
  void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb);
 +int mt7996_mcu_set_dup_wtbl(struct mt7996_dev *dev);
  #endif
  
- #endif
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 diff --git a/mt7996/mtk_mcu.c b/mt7996/mtk_mcu.c
-index 3256de7f5..149694c19 100644
+index 3256de7..149694c 100644
 --- a/mt7996/mtk_mcu.c
 +++ b/mt7996/mtk_mcu.c
 @@ -235,4 +235,27 @@ void mt7996_mcu_rx_sr_event(struct mt7996_dev *dev, struct sk_buff *skb)
@@ -68,5 +68,5 @@
 +}
  #endif
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
new file mode 100644
index 0000000..354e553
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1026-wifi-mt76-mt7996-add-ibf-control-vendor-cmd.patch
@@ -0,0 +1,143 @@
+From b5d139f32d6f4f6476b82d59af7a96a1f57858a9 Mon Sep 17 00:00:00 2001
+From: "Allen.Ye" <allen.ye@mediatek.com>
+Date: Fri, 22 Sep 2023 09:54:49 +0800
+Subject: [PATCH 59/98] wifi: mt76: mt7996: add ibf control vendor cmd
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+---
+ mt7996/vendor.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 23 +++++++++++++++++
+ 2 files changed, 88 insertions(+)
+
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 9f333d0..dae3260 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -60,6 +60,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = {
+ 	[MTK_VENDOR_ATTR_EDCCA_DUMP_SEC160_VAL] = { .type = NLA_U8 },
+ };
+ 
++static const struct nla_policy
++ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = {
++	[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 },
++};
++
+ struct mt7996_amnt_data {
+ 	u8 idx;
+ 	u8 addr[ETH_ALEN];
+@@ -556,6 +561,54 @@ mt7996_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ 	return EDCCA_MAX_BW_NUM;
+ }
+ 
++static int mt7996_vendor_ibf_ctrl(struct wiphy *wiphy,
++				  struct wireless_dev *wdev,
++				  const void *data,
++				  int data_len)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_dev *dev = phy->dev;
++	struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_IBF_CTRL];
++	int err;
++	u8 val;
++
++	err = nla_parse(tb, MTK_VENDOR_ATTR_IBF_CTRL_MAX, data, data_len,
++			ibf_ctrl_policy, NULL);
++	if (err)
++		return err;
++
++	if (tb[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE]) {
++		val = nla_get_u8(tb[MTK_VENDOR_ATTR_IBF_CTRL_ENABLE]);
++
++		dev->ibf = !!val;
++
++		err = mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
++		if (err)
++			return err;
++	}
++	return 0;
++}
++
++static int
++mt7996_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
++			    struct sk_buff *skb, const void *data, int data_len,
++			    unsigned long *storage)
++{
++	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++	struct mt7996_phy *phy = mt7996_hw_phy(hw);
++	struct mt7996_dev *dev = phy->dev;
++
++	if (*storage == 1)
++		return -ENOENT;
++	*storage = 1;
++
++	if (nla_put_u8(skb, MTK_VENDOR_ATTR_IBF_DUMP_ENABLE, dev->ibf))
++		return -ENOMEM;
++
++	return 1;
++}
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 	{
+ 		.info = {
+@@ -604,6 +657,18 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ 		.policy = edcca_ctrl_policy,
+ 		.maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX,
+ 	},
++	{
++		.info = {
++			.vendor_id = MTK_NL80211_VENDOR_ID,
++			.subcmd = MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL,
++		},
++		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++			WIPHY_VENDOR_CMD_NEED_RUNNING,
++		.doit = mt7996_vendor_ibf_ctrl,
++		.dumpit = mt7996_vendor_ibf_ctrl_dump,
++		.policy = ibf_ctrl_policy,
++		.maxattr = MTK_VENDOR_ATTR_IBF_CTRL_MAX,
++	},
+ };
+ 
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 4465bc9..49f46f2 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -7,6 +7,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
+ 	MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
+ 	MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
++	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ };
+ 
+@@ -102,4 +103,26 @@ enum mtk_vendor_attr_bss_color_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL - 1
+ };
+ 
++enum mtk_vendor_attr_ibf_ctrl {
++	MTK_VENDOR_ATTR_IBF_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_IBF_CTRL_ENABLE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_IBF_CTRL,
++	MTK_VENDOR_ATTR_IBF_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_IBF_CTRL - 1
++};
++
++enum mtk_vendor_attr_ibf_dump {
++	MTK_VENDOR_ATTR_IBF_DUMP_UNSPEC,
++
++	MTK_VENDOR_ATTR_IBF_DUMP_ENABLE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_IBF_DUMP,
++	MTK_VENDOR_ATTR_IBF_DUMP_MAX =
++		NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1
++};
++
+ #endif
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch
new file mode 100644
index 0000000..a555c23
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1027-wifi-mt76-mt7996-add-kite-fwdl-support.patch
@@ -0,0 +1,120 @@
+From 4f5af38dbe7866b635428ebe80df29ab96bd660e Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 26 May 2023 14:41:27 +0800
+Subject: [PATCH 60/98] wifi: mt76: mt7996: add kite fwdl support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76_connac_mcu.c |  3 ++-
+ mt7996/mcu.c      | 26 +++++++++++++++++++++-----
+ mt7996/mt7996.h   |  6 ++++++
+ mt7996/pci.c      |  4 ++++
+ 4 files changed, 33 insertions(+), 6 deletions(-)
+
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index 214a526..43e8ce0 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -68,7 +68,8 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
+ 	if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
+ 	    (is_mt7921(dev) && addr == 0x900000) ||
+ 	    (is_mt7925(dev) && addr == 0x900000) ||
+-	    (is_mt7996(dev) && addr == 0x900000))
++	    (is_mt7996(dev) && addr == 0x900000) ||
++	    (is_mt7992(dev) && addr == 0x900000))
+ 		cmd = MCU_CMD(PATCH_START_REQ);
+ 	else
+ 		cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 3a960d1..255d0ba 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -11,6 +11,22 @@
+ #include "mac.h"
+ #include "eeprom.h"
+ 
++#define fw_name(_dev, name, ...)	({			\
++	char *_fw;						\
++	switch (mt76_chip(&(_dev)->mt76)) {			\
++	case 0x7996:						\
++		_fw = MT7996_##name;				\
++		break;						\
++	case 0x7992:						\
++		_fw = MT7992_##name;				\
++		break;						\
++	default:						\
++		_fw = MT7996_##name;				\
++		break;						\
++	}							\
++	_fw;							\
++})
++
+ struct mt7996_patch_hdr {
+ 	char build_date[16];
+ 	char platform[4];
+@@ -2598,7 +2614,7 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
+ 		return -EAGAIN;
+ 	}
+ 
+-	ret = request_firmware(&fw, MT7996_ROM_PATCH, dev->mt76.dev);
++	ret = request_firmware(&fw, fw_name(dev, ROM_PATCH), dev->mt76.dev);
+ 	if (ret)
+ 		goto out;
+ 
+@@ -2767,20 +2783,20 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+ 	int ret;
+ 
+ 	if (dev->testmode_enable)
+-		ret = __mt7996_load_ram(dev, "WM_TM", MT7996_FIRMWARE_WM_TM,
++		ret = __mt7996_load_ram(dev, "WM_TM", fw_name(dev, FIRMWARE_WM_TM),
+ 					MT7996_RAM_TYPE_WM_TM);
+ 	else
+-		ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
++		ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM),
+ 					MT7996_RAM_TYPE_WM);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
++	ret = __mt7996_load_ram(dev, "DSP", fw_name(dev, FIRMWARE_DSP),
+ 				MT7996_RAM_TYPE_DSP);
+ 	if (ret)
+ 		return ret;
+ 
+-	return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
++	return __mt7996_load_ram(dev, "WA", fw_name(dev, FIRMWARE_WA),
+ 				 MT7996_RAM_TYPE_WA);
+ }
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 766de3f..eb192eb 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -35,6 +35,12 @@
+ #define MT7996_FIRMWARE_WM_TM		"mediatek/mt7996/mt7996_wm_tm.bin"
+ #define MT7996_ROM_PATCH		"mediatek/mt7996/mt7996_rom_patch.bin"
+ 
++#define MT7992_FIRMWARE_WA		"mediatek/mt7996/mt7992_wa.bin"
++#define MT7992_FIRMWARE_WM		"mediatek/mt7996/mt7992_wm.bin"
++#define MT7992_FIRMWARE_DSP		"mediatek/mt7996/mt7992_dsp.bin"
++#define MT7992_FIRMWARE_WM_TM		"mediatek/mt7996/mt7992_wm_tm.bin"
++#define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
++
+ #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
+ #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index e8edf77..2bb707d 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -263,3 +263,7 @@ MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
+ MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
+ MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
+ MODULE_FIRMWARE(MT7996_ROM_PATCH);
++MODULE_FIRMWARE(MT7992_FIRMWARE_WA);
++MODULE_FIRMWARE(MT7992_FIRMWARE_WM);
++MODULE_FIRMWARE(MT7992_FIRMWARE_DSP);
++MODULE_FIRMWARE(MT7992_ROM_PATCH);
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch
new file mode 100644
index 0000000..3556945
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1028-wifi-mt76-mt7996-add-kite-eeprom-load-support.patch
@@ -0,0 +1,146 @@
+From dcace898314b1d369b61a0c4f7f9e325f04784dc Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 26 May 2023 14:44:04 +0800
+Subject: [PATCH 61/98] wifi: mt76: mt7996: add kite eeprom load support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c | 33 ++++++++++++++++++++++-----------
+ mt7996/mcu.c    |  2 +-
+ mt7996/mt7996.h | 10 ++++++++++
+ 3 files changed, 33 insertions(+), 12 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 56605de..6605853 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -53,9 +53,12 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ 	u8 *eeprom = dev->mt76.eeprom.data;
+ 	u16 val = get_unaligned_le16(eeprom);
+ 
++#define CHECK_EEPROM_ERR(match)	(match ? 0 : -EINVAL)
+ 	switch (val) {
+ 	case 0x7990:
+-		return 0;
++		return CHECK_EEPROM_ERR(is_mt7996(&dev->mt76));
++	case 0x7992:
++		return CHECK_EEPROM_ERR(is_mt7992(&dev->mt76));
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -66,13 +69,20 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ 	if (dev->bin_file_mode)
+ 		return dev->mt76.bin_file_name;
+ 
+-	/* reserve for future variants */
+-	if (dev->testmode_enable)
+-		return MT7996_EEPROM_DEFAULT_TM;
+-	else if (dev->chip_sku == MT7996_SKU_404)
+-		return MT7996_EEPROM_DEFAULT_404;
+-	else
++	switch (mt76_chip(&dev->mt76)) {
++	case 0x7990:
++		if (dev->testmode_enable)
++			return MT7996_EEPROM_DEFAULT_TM;
++		else if (dev->chip_sku == MT7996_SKU_404)
++			return MT7996_EEPROM_DEFAULT_404;
++		else
++			return MT7996_EEPROM_DEFAULT;
++	case 0x7992:
++		return dev->testmode_enable ?
++		       MT7992_EEPROM_DEFAULT_TM : MT7992_EEPROM_DEFAULT;
++	default:
+ 		return MT7996_EEPROM_DEFAULT;
++	}
+ }
+ 
+ int
+@@ -125,7 +135,7 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+ 		goto out;
+ 	}
+ 
+-	memcpy(eeprom, fw->data, MT7996_EEPROM_SIZE);
++	memcpy(eeprom, fw->data, mt7996_eeprom_size(dev));
+ 	dev->flash_mode = true;
+ 
+ out:
+@@ -141,7 +151,7 @@ static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
+ 	/* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
+ 	dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
+ 	if (dev->bin_file_mode) {
+-		dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
++		dev->mt76.eeprom.size = mt7996_eeprom_size(dev);
+ 		dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev, dev->mt76.eeprom.size,
+ 						     GFP_KERNEL);
+ 		if (!dev->mt76.eeprom.data)
+@@ -153,7 +163,7 @@ static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
+ 		if (mt7996_check_eeprom(dev))
+ 			return 0;
+ 	} else {
+-		ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
++		ret = mt76_eeprom_init(&dev->mt76, mt7996_eeprom_size(dev));
+ 	}
+ 
+ 	return ret;
+@@ -186,6 +196,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
+ {
+ 	int ret;
+ 	u8 free_block_num;
++	u16 eeprom_size = mt7996_eeprom_size(dev);
+ 	u32 block_num, i;
+ 	u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE;
+ 
+@@ -200,7 +211,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
+ 			return -EINVAL;
+ 
+ 		/* read eeprom data from efuse */
+-		block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size);
++		block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
+ 		for (i = 0; i < block_num; i++) {
+ 			ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size);
+ 			if (ret < 0)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 255d0ba..e9088ba 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3425,7 +3425,7 @@ static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)
+ 		.tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),
+ 		.buffer_mode = EE_MODE_BUFFER
+ 	};
+-	u16 eeprom_size = MT7996_EEPROM_SIZE;
++	u16 eeprom_size = mt7996_eeprom_size(dev);
+ 	u8 total = DIV_ROUND_UP(eeprom_size, PER_PAGE_SIZE);
+ 	u8 *eep = (u8 *)dev->mt76.eeprom.data;
+ 	int eep_len, i;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index eb192eb..433d886 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -44,7 +44,12 @@
+ #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
+ #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
++#define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom.bin"
++#define MT7992_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7992_eeprom_tm.bin"
++
+ #define MT7996_EEPROM_SIZE		7680
++#define MT7992_EEPROM_SIZE		7680
++
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+ #define MT7996_TOKEN_SIZE		16384
+ #define MT7996_HW_TOKEN_SIZE		8192
+@@ -643,6 +648,11 @@ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
+ 
++static inline u16 mt7996_eeprom_size(struct mt7996_dev *dev)
++{
++	return is_mt7996(&dev->mt76) ? MT7996_EEPROM_SIZE : MT7992_EEPROM_SIZE;
++}
++
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
+ {
+ 	return min(MT7996_MAX_INTERFACES * (1 + dev->dbdc_support + dev->tbtc_support),
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch
new file mode 100644
index 0000000..8b8119a
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1029-wifi-mt76-mt7996-add-kite-fw-default-bin-for-differe.patch
@@ -0,0 +1,128 @@
+From af793eb0cf8e035760bdb595ae96e7d7534df60f Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 21 Jul 2023 10:41:28 +0800
+Subject: [PATCH 62/98] wifi: mt76: mt7996: add kite fw & default bin for
+ different sku variants
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/eeprom.c | 10 ++++++++--
+ mt7996/mcu.c    |  7 ++++++-
+ mt7996/mt7996.h | 25 ++++++++++++++++++++++++-
+ mt7996/regs.h   |  2 ++
+ 4 files changed, 40 insertions(+), 4 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 6605853..6eebbb3 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -78,8 +78,14 @@ const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ 		else
+ 			return MT7996_EEPROM_DEFAULT;
+ 	case 0x7992:
+-		return dev->testmode_enable ?
+-		       MT7992_EEPROM_DEFAULT_TM : MT7992_EEPROM_DEFAULT;
++		if (dev->testmode_enable)
++			return MT7992_EEPROM_DEFAULT_TM;
++		else if (dev->chip_sku == MT7992_SKU_23)
++			return MT7992_EEPROM_DEFAULT_23;
++		else if (dev->chip_sku == MT7992_SKU_24)
++			return MT7992_EEPROM_DEFAULT_24;
++		else
++			return MT7992_EEPROM_DEFAULT;
+ 	default:
+ 		return MT7996_EEPROM_DEFAULT;
+ 	}
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index e9088ba..b8d26ec 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -18,7 +18,12 @@
+ 		_fw = MT7996_##name;				\
+ 		break;						\
+ 	case 0x7992:						\
+-		_fw = MT7992_##name;				\
++		if ((_dev)->chip_sku == MT7992_SKU_23)		\
++			_fw = MT7992_##name##_23;		\
++		else if ((_dev)->chip_sku == MT7992_SKU_24)	\
++			_fw = MT7992_##name##_24;		\
++		else						\
++			_fw = MT7992_##name;			\
+ 		break;						\
+ 	default:						\
+ 		_fw = MT7996_##name;				\
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 433d886..6775360 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -41,11 +41,25 @@
+ #define MT7992_FIRMWARE_WM_TM		"mediatek/mt7996/mt7992_wm_tm.bin"
+ #define MT7992_ROM_PATCH		"mediatek/mt7996/mt7992_rom_patch.bin"
+ 
++#define MT7992_FIRMWARE_WA_24		"mediatek/mt7996/mt7992_wa_24.bin"
++#define MT7992_FIRMWARE_WM_24		"mediatek/mt7996/mt7992_wm_24.bin"
++#define MT7992_FIRMWARE_DSP_24		"mediatek/mt7996/mt7992_dsp_24.bin"
++#define MT7992_FIRMWARE_WM_TM_24	"mediatek/mt7996/mt7992_wm_tm_24.bin"
++#define MT7992_ROM_PATCH_24		"mediatek/mt7996/mt7992_rom_patch_24.bin"
++
++#define MT7992_FIRMWARE_WA_23		"mediatek/mt7996/mt7992_wa_23.bin"
++#define MT7992_FIRMWARE_WM_23		"mediatek/mt7996/mt7992_wm_23.bin"
++#define MT7992_FIRMWARE_DSP_23		"mediatek/mt7996/mt7992_dsp_23.bin"
++#define MT7992_FIRMWARE_WM_TM_23	"mediatek/mt7996/mt7992_wm_tm_23.bin"
++#define MT7992_ROM_PATCH_23		"mediatek/mt7996/mt7992_rom_patch_23.bin"
++
+ #define MT7996_EEPROM_DEFAULT		"mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_DEFAULT_404	"mediatek/mt7996/mt7996_eeprom_dual_404.bin"
+ #define MT7996_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7996_eeprom_tm.bin"
+ #define MT7992_EEPROM_DEFAULT		"mediatek/mt7996/mt7992_eeprom.bin"
+ #define MT7992_EEPROM_DEFAULT_TM	"mediatek/mt7996/mt7992_eeprom_tm.bin"
++#define MT7992_EEPROM_DEFAULT_24	"mediatek/mt7996/mt7992_eeprom_24.bin"
++#define MT7992_EEPROM_DEFAULT_23	"mediatek/mt7996/mt7992_eeprom_23.bin"
+ 
+ #define MT7996_EEPROM_SIZE		7680
+ #define MT7992_EEPROM_SIZE		7680
+@@ -103,6 +117,12 @@ enum mt7996_sku_type {
+ 	MT7996_SKU_444,
+ };
+ 
++enum mt7992_sku_type {
++	MT7992_SKU_23,
++	MT7992_SKU_24,
++	MT7992_SKU_44,
++};
++
+ enum mt7996_ram_type {
+ 	MT7996_RAM_TYPE_WM,
+ 	MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
+@@ -510,11 +530,14 @@ mt7996_get_chip_sku(struct mt7996_dev *dev)
+ {
+ 	u32 val = mt76_rr(dev, MT_PAD_GPIO);
+ 
+-	/* reserve for future variants */
+ 	switch (mt76_chip(&dev->mt76)) {
+ 	case 0x7990:
+ 		dev->chip_sku = FIELD_GET(MT_PAD_GPIO_ADIE_COMB, val) <= 1;
+ 		break;
++	case 0x7992:
++		dev->chip_sku = !!FIELD_GET(MT_PAD_GPIO_ADIE_COMB_7992, val) +
++				!FIELD_GET(MT_PAD_GPIO_ADIE_NUM_7992, val);
++		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 565022a..d305c25 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -651,6 +651,8 @@ enum offs_rev {
+ 
+ #define MT_PAD_GPIO				0x700056f0
+ #define MT_PAD_GPIO_ADIE_COMB			GENMASK(16, 15)
++#define MT_PAD_GPIO_ADIE_COMB_7992		GENMASK(17, 16)
++#define MT_PAD_GPIO_ADIE_NUM_7992		BIT(15)
+ 
+ #define MT_HW_REV				0x70010204
+ #define MT_WF_SUBSYS_RST			0x70028600
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch
new file mode 100644
index 0000000..3af30bf
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/1030-wifi-mt76-mt7996-add-wtbl_info-support-for-kite.patch
@@ -0,0 +1,198 @@
+From ab77df3cc660c0aa0f46060499d8704dc389a2a6 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Mon, 24 Jul 2023 16:39:22 +0800
+Subject: [PATCH 63/98] wifi: mt76: mt7996: add wtbl_info support for kite
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/mtk_debug.h   | 22 +++++++++++++
+ mt7996/mtk_debugfs.c | 74 ++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 93 insertions(+), 3 deletions(-)
+
+diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
+index 9718c2c..1611345 100644
+--- a/mt7996/mtk_debug.h
++++ b/mt7996/mtk_debug.h
+@@ -1088,6 +1088,17 @@ enum cipher_suit {
+ #define WF_LWTBL_AAD_OM_MASK \
+ 	0x00008000 // 15-15
+ #define WF_LWTBL_AAD_OM_SHIFT                                       15
++/* kite DW2 field bit 13-14 */
++#define WF_LWTBL_DUAL_PTEC_EN_DW                                    2
++#define WF_LWTBL_DUAL_PTEC_EN_ADDR                                  8
++#define WF_LWTBL_DUAL_PTEC_EN_MASK \
++	0x00002000 // 13-13
++#define WF_LWTBL_DUAL_PTEC_EN_SHIFT                                 13
++#define WF_LWTBL_DUAL_CTS_CAP_DW                                    2
++#define WF_LWTBL_DUAL_CTS_CAP_ADDR                                  8
++#define WF_LWTBL_DUAL_CTS_CAP_MASK \
++	0x00004000 // 14-14
++#define WF_LWTBL_DUAL_CTS_CAP_SHIFT                                 14
+ #define WF_LWTBL_CIPHER_SUIT_PGTK_DW                                2
+ #define WF_LWTBL_CIPHER_SUIT_PGTK_ADDR                              8
+ #define WF_LWTBL_CIPHER_SUIT_PGTK_MASK \
+@@ -1305,6 +1316,8 @@ enum cipher_suit {
+ #define WF_LWTBL_AF_ADDR                                            20
+ #define WF_LWTBL_AF_MASK \
+ 	0x00000007 // 2- 0
++#define WF_LWTBL_AF_MASK_7992 \
++	0x0000000f // 3- 0
+ #define WF_LWTBL_AF_SHIFT                                           0
+ #define WF_LWTBL_AF_HE_DW                                           5
+ #define WF_LWTBL_AF_HE_ADDR                                         20
+@@ -1565,16 +1578,25 @@ enum cipher_suit {
+ #define WF_LWTBL_PRITX_SW_MODE_MASK \
+ 	0x00008000 // 15-15
+ #define WF_LWTBL_PRITX_SW_MODE_SHIFT                                15
++#define WF_LWTBL_PRITX_SW_MODE_MASK_7992 \
++	0x00004000 // 14-14
++#define WF_LWTBL_PRITX_SW_MODE_SHIFT_7992                           14
+ #define WF_LWTBL_PRITX_ERSU_DW                                      9
+ #define WF_LWTBL_PRITX_ERSU_ADDR                                    36
+ #define WF_LWTBL_PRITX_ERSU_MASK \
+ 	0x00010000 // 16-16
+ #define WF_LWTBL_PRITX_ERSU_SHIFT                                   16
++#define WF_LWTBL_PRITX_ERSU_MASK_7992 \
++	0x00008000 // 15-15
++#define WF_LWTBL_PRITX_ERSU_SHIFT_7992                              15
+ #define WF_LWTBL_PRITX_PLR_DW                                       9
+ #define WF_LWTBL_PRITX_PLR_ADDR                                     36
+ #define WF_LWTBL_PRITX_PLR_MASK \
+ 	0x00020000 // 17-17
+ #define WF_LWTBL_PRITX_PLR_SHIFT                                    17
++#define WF_LWTBL_PRITX_PLR_MASK_7992 \
++	0x00030000 // 17-16
++#define WF_LWTBL_PRITX_PLR_SHIFT_7992                               16
+ #define WF_LWTBL_PRITX_DCM_DW                                       9
+ #define WF_LWTBL_PRITX_DCM_ADDR                                     36
+ #define WF_LWTBL_PRITX_DCM_MASK \
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index f56ad88..ce48664 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -1011,7 +1011,8 @@ static void parse_fmac_lwtbl_dw0_1(struct seq_file *s, u8 *lwtbl)
+ 	}
+ }
+ 
+-static const struct berse_wtbl_parse WTBL_LMAC_DW2[] = {
++static const struct berse_wtbl_parse *WTBL_LMAC_DW2;
++static const struct berse_wtbl_parse WTBL_LMAC_DW2_7996[] = {
+ 	{"AID",                 WF_LWTBL_AID_MASK,              WF_LWTBL_AID_SHIFT,	false},
+ 	{"GID_SU",              WF_LWTBL_GID_SU_MASK,           NO_SHIFT_DEFINE,	false},
+ 	{"SPP_EN",              WF_LWTBL_SPP_EN_MASK,           NO_SHIFT_DEFINE,	false},
+@@ -1032,6 +1033,26 @@ static const struct berse_wtbl_parse WTBL_LMAC_DW2[] = {
+ 	{NULL,}
+ };
+ 
++static const struct berse_wtbl_parse WTBL_LMAC_DW2_7992[] = {
++	{"AID",                 WF_LWTBL_AID_MASK,              WF_LWTBL_AID_SHIFT,	false},
++	{"GID_SU",              WF_LWTBL_GID_SU_MASK,           NO_SHIFT_DEFINE,	false},
++	{"DUAL_PTEC_EN",        WF_LWTBL_DUAL_PTEC_EN_MASK,     NO_SHIFT_DEFINE,	false},
++	{"DUAL_CTS_CAP",        WF_LWTBL_DUAL_CTS_CAP_MASK,     NO_SHIFT_DEFINE,	false},
++	{"CIPHER_PGTK",WF_LWTBL_CIPHER_SUIT_PGTK_MASK, WF_LWTBL_CIPHER_SUIT_PGTK_SHIFT,	true},
++	{"FROM_DS",             WF_LWTBL_FD_MASK,               NO_SHIFT_DEFINE,	false},
++	{"TO_DS",               WF_LWTBL_TD_MASK,               NO_SHIFT_DEFINE,	false},
++	{"SW",                  WF_LWTBL_SW_MASK,               NO_SHIFT_DEFINE,	false},
++	{"UL",                  WF_LWTBL_UL_MASK,               NO_SHIFT_DEFINE,	false},
++	{"TX_POWER_SAVE",       WF_LWTBL_TX_PS_MASK,            NO_SHIFT_DEFINE,	true},
++	{"QOS",                 WF_LWTBL_QOS_MASK,              NO_SHIFT_DEFINE,	false},
++	{"HT",                  WF_LWTBL_HT_MASK,               NO_SHIFT_DEFINE,	false},
++	{"VHT",                 WF_LWTBL_VHT_MASK,              NO_SHIFT_DEFINE,	false},
++	{"HE",                  WF_LWTBL_HE_MASK,               NO_SHIFT_DEFINE,	false},
++	{"EHT",                 WF_LWTBL_EHT_MASK,              NO_SHIFT_DEFINE,	false},
++	{"MESH",                WF_LWTBL_MESH_MASK,             NO_SHIFT_DEFINE,	true},
++	{NULL,}
++};
++
+ static void parse_fmac_lwtbl_dw2(struct seq_file *s, u8 *lwtbl)
+ {
+ 	u32 *addr = 0;
+@@ -1141,7 +1162,8 @@ static void parse_fmac_lwtbl_dw4(struct seq_file *s, u8 *lwtbl)
+ 	}
+ }
+ 
+-static const struct berse_wtbl_parse WTBL_LMAC_DW5[] = {
++static const struct berse_wtbl_parse *WTBL_LMAC_DW5;
++static const struct berse_wtbl_parse WTBL_LMAC_DW5_7996[] = {
+ 	{"AF",                  WF_LWTBL_AF_MASK,           WF_LWTBL_AF_SHIFT,	false},
+ 	{"AF_HE",               WF_LWTBL_AF_HE_MASK,        WF_LWTBL_AF_HE_SHIFT,false},
+ 	{"RTS",                 WF_LWTBL_RTS_MASK,          NO_SHIFT_DEFINE,	false},
+@@ -1163,6 +1185,27 @@ static const struct berse_wtbl_parse WTBL_LMAC_DW5[] = {
+ 	{NULL,}
+ };
+ 
++static const struct berse_wtbl_parse WTBL_LMAC_DW5_7992[] = {
++	{"AF",                  WF_LWTBL_AF_MASK_7992,      WF_LWTBL_AF_SHIFT,	false},
++	{"RTS",                 WF_LWTBL_RTS_MASK,          NO_SHIFT_DEFINE,	false},
++	{"SMPS",                WF_LWTBL_SMPS_MASK,         NO_SHIFT_DEFINE,	false},
++	{"DYN_BW",              WF_LWTBL_DYN_BW_MASK,       NO_SHIFT_DEFINE,	true},
++	{"MMSS",                WF_LWTBL_MMSS_MASK,         WF_LWTBL_MMSS_SHIFT,false},
++	{"USR",                 WF_LWTBL_USR_MASK,          NO_SHIFT_DEFINE,	false},
++	{"SR_RATE",             WF_LWTBL_SR_R_MASK,         WF_LWTBL_SR_R_SHIFT,false},
++	{"SR_ABORT",            WF_LWTBL_SR_ABORT_MASK,     NO_SHIFT_DEFINE,	true},
++	{"TX_POWER_OFFSET",     WF_LWTBL_TX_POWER_OFFSET_MASK,  WF_LWTBL_TX_POWER_OFFSET_SHIFT,	false},
++	{"LTF_EHT",		WF_LWTBL_LTF_EHT_MASK,      WF_LWTBL_LTF_EHT_SHIFT, false},
++	{"GI_EHT",		WF_LWTBL_GI_EHT_MASK,       WF_LWTBL_GI_EHT_SHIFT, false},
++	{"DOPPL",               WF_LWTBL_DOPPL_MASK,        NO_SHIFT_DEFINE,	false},
++	{"TXOP_PS_CAP",         WF_LWTBL_TXOP_PS_CAP_MASK,  NO_SHIFT_DEFINE,	false},
++	{"DONOT_UPDATE_I_PSM",  WF_LWTBL_DU_I_PSM_MASK,     NO_SHIFT_DEFINE,	true},
++	{"I_PSM",               WF_LWTBL_I_PSM_MASK,        NO_SHIFT_DEFINE,	false},
++	{"PSM",                 WF_LWTBL_PSM_MASK,          NO_SHIFT_DEFINE,	false},
++	{"SKIP_TX",             WF_LWTBL_SKIP_TX_MASK,      NO_SHIFT_DEFINE,	true},
++	{NULL,}
++};
++
+ static void parse_fmac_lwtbl_dw5(struct seq_file *s, u8 *lwtbl)
+ {
+ 	u32 *addr = 0;
+@@ -1281,7 +1324,8 @@ static void parse_fmac_lwtbl_dw8(struct seq_file *s, u8 *lwtbl)
+ 	}
+ }
+ 
+-static const struct berse_wtbl_parse WTBL_LMAC_DW9[] = {
++static const struct berse_wtbl_parse *WTBL_LMAC_DW9;
++static const struct berse_wtbl_parse WTBL_LMAC_DW9_7996[] = {
+ 	{"RX_AVG_MPDU_SIZE",    WF_LWTBL_RX_AVG_MPDU_SIZE_MASK,    WF_LWTBL_RX_AVG_MPDU_SIZE_SHIFT,	false},
+ 	{"PRITX_SW_MODE",       WF_LWTBL_PRITX_SW_MODE_MASK,       NO_SHIFT_DEFINE,	false},
+ 	{"PRITX_ERSU",	    WF_LWTBL_PRITX_ERSU_MASK,	       NO_SHIFT_DEFINE,	false},
+@@ -1295,6 +1339,20 @@ static const struct berse_wtbl_parse WTBL_LMAC_DW9[] = {
+ 	{NULL,}
+ };
+ 
++static const struct berse_wtbl_parse WTBL_LMAC_DW9_7992[] = {
++	{"RX_AVG_MPDU_SIZE",    WF_LWTBL_RX_AVG_MPDU_SIZE_MASK,    WF_LWTBL_RX_AVG_MPDU_SIZE_SHIFT,	false},
++	{"PRITX_SW_MODE",       WF_LWTBL_PRITX_SW_MODE_MASK_7992,       NO_SHIFT_DEFINE,	false},
++	{"PRITX_ERSU",	    WF_LWTBL_PRITX_ERSU_MASK_7992,	       NO_SHIFT_DEFINE,	false},
++	{"PRITX_PLR",           WF_LWTBL_PRITX_PLR_MASK_7992,           NO_SHIFT_DEFINE,	true},
++	{"PRITX_DCM",           WF_LWTBL_PRITX_DCM_MASK,           NO_SHIFT_DEFINE,	false},
++	{"PRITX_ER106T",        WF_LWTBL_PRITX_ER106T_MASK,        NO_SHIFT_DEFINE,	true},
++	/* {"FCAP(0:20 1:~40)",    WTBL_FCAP_20_TO_160_MHZ,	WTBL_FCAP_20_TO_160_MHZ_OFFSET}, */
++	{"MPDU_FAIL_CNT",       WF_LWTBL_MPDU_FAIL_CNT_MASK,       WF_LWTBL_MPDU_FAIL_CNT_SHIFT,	false},
++	{"MPDU_OK_CNT",         WF_LWTBL_MPDU_OK_CNT_MASK,         WF_LWTBL_MPDU_OK_CNT_SHIFT,	false},
++	{"RATE_IDX",            WF_LWTBL_RATE_IDX_MASK,            WF_LWTBL_RATE_IDX_SHIFT,	true},
++	{NULL,}
++};
++
+ char *fcap_name[] = {"20MHz", "20/40MHz", "20/40/80MHz", "20/40/80/160/80+80MHz", "20/40/80/160/80+80/320MHz"};
+ 
+ static void parse_fmac_lwtbl_dw9(struct seq_file *s, u8 *lwtbl)
+@@ -2670,6 +2728,16 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+ 
++	if (is_mt7996(&dev->mt76)) {
++		WTBL_LMAC_DW2 = WTBL_LMAC_DW2_7996;
++		WTBL_LMAC_DW5 = WTBL_LMAC_DW5_7996;
++		WTBL_LMAC_DW9 = WTBL_LMAC_DW9_7996;
++	} else {
++		WTBL_LMAC_DW2 = WTBL_LMAC_DW2_7992;
++		WTBL_LMAC_DW5 = WTBL_LMAC_DW5_7992;
++		WTBL_LMAC_DW9 = WTBL_LMAC_DW9_7992;
++	}
++
+ 	mt7996_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
+ 
+ 	/* agg */
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
similarity index 74%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
index bcd1fe8..d2800ea 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2000-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
@@ -1,50 +1,50 @@
-From 43dacb36843a57b2c42ab7846ff853c3c04260b7 Mon Sep 17 00:00:00 2001
+From cc82fae54b1efd7de07034bea7a883b9fb362799 Mon Sep 17 00:00:00 2001
 From: Bo Jiao <Bo.Jiao@mediatek.com>
 Date: Mon, 6 Feb 2023 19:49:22 +0800
-Subject: [PATCH 2001/2012] wifi: mt76: revert page_poll for kernel 5.4
+Subject: [PATCH 64/98] wifi: mt76: revert page_poll for kernel 5.4
 
 This reverts commit e8c10835cf062c577ddf426913788c39d30b4bd7.
 
 Change-Id: I4e5764fc545087f691fb4c2f43e7a9cefd1e1657
 ---
- dma.c         | 78 +++++++++++++++++++++++++++++----------------------
- mac80211.c    | 57 -------------------------------------
+ dma.c         | 75 +++++++++++++++++++++++++++------------------------
+ mac80211.c    | 57 ---------------------------------------
+ mmio.c        | 56 ++++++++++++++++++++++++--------------
  mt76.h        | 22 +--------------
- mt7915/main.c | 26 +++++++----------
- mt7915/mmio.c | 55 ++++++++++++++++++++++--------------
- usb.c         | 43 ++++++++++++++--------------
- 6 files changed, 111 insertions(+), 170 deletions(-)
+ mt7915/main.c | 26 +++++++-----------
+ usb.c         | 43 ++++++++++++++---------------
+ 6 files changed, 109 insertions(+), 170 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 8182f6dc4..3785425b4 100644
+index bb995e2..06b76ea 100644
 --- a/dma.c
 +++ b/dma.c
 @@ -178,7 +178,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
  	local_bh_disable();
- 	while ((r = __mt76_get_rxwi(dev)) != NULL) {
- 		if (r->ptr)
--			mt76_put_page_pool_buf(r->ptr, false);
-+			skb_free_frag(r->ptr);
- 		kfree(r);
+ 	while ((t = __mt76_get_rxwi(dev)) != NULL) {
+ 		if (t->ptr)
+-			mt76_put_page_pool_buf(t->ptr, false);
++			skb_free_frag(t->ptr);
+ 		kfree(t);
  	}
  	local_bh_enable();
-@@ -411,9 +411,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 		if (!r)
+@@ -445,9 +445,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		if (!t)
  			return NULL;
  
--		dma_sync_single_for_cpu(dev->dma_dev, r->dma_addr,
+-		dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
 -				SKB_WITH_OVERHEAD(q->buf_size),
 -				page_pool_get_dma_dir(q->page_pool));
-+		dma_unmap_single(dev->dma_dev, r->dma_addr,
++		dma_unmap_single(dev->dma_dev, t->dma_addr,
 +				 SKB_WITH_OVERHEAD(q->buf_size),
 +				 DMA_FROM_DEVICE);
  
- 		buf = r->ptr;
- 		r->dma_addr = 0;
-@@ -432,9 +432,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		buf = t->ptr;
+ 		t->dma_addr = 0;
+@@ -457,9 +457,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		if (drop)
+ 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
  	} else {
- 		buf = e->buf;
- 		e->buf = NULL;
 -		dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
 -				SKB_WITH_OVERHEAD(q->buf_size),
 -				page_pool_get_dma_dir(q->page_pool));
@@ -53,8 +53,8 @@
 +				 DMA_FROM_DEVICE);
  	}
  
- 	return buf;
-@@ -594,11 +594,11 @@ free_skb:
+ done:
+@@ -626,11 +626,11 @@ free_skb:
  }
  
  static int
@@ -69,15 +69,17 @@
  
  	if (!q->ndesc)
  		return 0;
-@@ -606,25 +606,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
- 	spin_lock_bh(&q->lock);
+@@ -639,28 +639,29 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
  
  	while (q->queued < q->ndesc - 1) {
+ 		struct mt76_queue_buf qbuf = {};
 -		enum dma_data_direction dir;
- 		struct mt76_queue_buf qbuf;
 -		dma_addr_t addr;
 -		int offset;
- 		void *buf;
+ 		void *buf = NULL;
+ 
+ 		if (mt76_queue_is_wed_rro_ind(q))
+ 			goto done;
  
 -		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
 +		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
@@ -94,8 +96,9 @@
 +		}
  
 -		qbuf.addr = addr + q->buf_offset;
--		qbuf.len = len - q->buf_offset;
 +		qbuf.addr = addr + offset;
+ done:
+-		qbuf.len = len - q->buf_offset;
 +		qbuf.len = len - offset;
  		qbuf.skip_unmap = false;
  		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
@@ -106,16 +109,25 @@
  			break;
  		}
  		frames++;
-@@ -668,7 +669,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -704,7 +705,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
  		/* WED txfree queue needs ring to be initialized before setup */
  		q->flags = 0;
  		mt76_dma_queue_reset(dev, q);
 -		mt76_dma_rx_fill(dev, q, false);
 +		mt76_dma_rx_fill(dev, q);
- 		q->flags = flags;
  
- 		ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
-@@ -716,10 +717,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ 		ret = mtk_wed_device_txfree_ring_setup(q->wed, q->regs);
+ 		if (!ret)
+@@ -733,7 +734,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 	case MT76_WED_RRO_Q_IND:
+ 		q->flags &= ~MT_QFLAG_WED;
+ 		mt76_dma_queue_reset(dev, q);
+-		mt76_dma_rx_fill(dev, q, false);
++		mt76_dma_rx_fill(dev, q);
+ 		mtk_wed_device_ind_rx_ring_setup(q->wed, q->regs);
+ 		break;
+ 	default:
+@@ -789,10 +790,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  	if (!q->entry)
  		return -ENOMEM;
  
@@ -126,7 +138,7 @@
  	ret = mt76_dma_wed_setup(dev, q, false);
  	if (ret)
  		return ret;
-@@ -733,6 +730,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -811,6 +808,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
  static void
  mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  {
@@ -134,26 +146,21 @@
  	void *buf;
  	bool more;
  
-@@ -746,7 +744,10 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 		if (!buf)
+@@ -825,7 +823,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  			break;
  
--		mt76_put_page_pool_buf(buf, false);
-+		if (q->flags & MT_QFLAG_RRO)
-+			continue;
-+
-+		skb_free_frag(buf);
+ 		if (!mt76_queue_is_wed_rro(q))
+-			mt76_put_page_pool_buf(buf, false);
++			skb_free_frag(buf);
  	} while (1);
  
  	if (q->rx_head) {
-@@ -755,6 +756,18 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -834,6 +832,16 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
  	}
  
  	spin_unlock_bh(&q->lock);
 +
-+	if (((q->flags & MT_QFLAG_WED) &&
-+	     FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) ||
-+	    (q->flags & MT_QFLAG_RRO))
++	if (mt76_queue_is_wed_rx(q))
 +		return;
 +
 +	if (!q->rx_page.va)
@@ -165,16 +172,16 @@
  }
  
  static void
-@@ -775,7 +788,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -857,7 +865,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
  	mt76_dma_wed_setup(dev, q, true);
- 	if (q->flags != MT_WED_Q_TXFREE) {
+ 	if (!mt76_queue_is_wed_tx_free(q)) {
  		mt76_dma_sync_idx(dev, q);
 -		mt76_dma_rx_fill(dev, q, false);
 +		mt76_dma_rx_fill(dev, q);
  	}
  }
  
-@@ -793,7 +806,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+@@ -875,7 +883,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
  
  		skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
  	} else {
@@ -183,7 +190,7 @@
  	}
  
  	if (more)
-@@ -866,7 +879,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -948,7 +956,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  			goto free_frag;
  
  		skb_reserve(skb, q->buf_offset);
@@ -191,7 +198,7 @@
  
  		*(u32 *)skb->cb = info;
  
-@@ -882,10 +894,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -964,10 +971,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		continue;
  
  free_frag:
@@ -204,7 +211,7 @@
  	return done;
  }
  
-@@ -930,7 +942,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -1012,7 +1019,7 @@ mt76_dma_init(struct mt76_dev *dev,
  
  	mt76_for_each_q_rx(dev, i) {
  		netif_napi_add(&dev->napi_dev, &dev->napi[i], poll);
@@ -213,7 +220,7 @@
  		napi_enable(&dev->napi[i]);
  	}
  
-@@ -984,8 +996,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -1067,8 +1074,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
  
  		netif_napi_del(&dev->napi[i]);
  		mt76_dma_rx_cleanup(dev, q);
@@ -223,7 +230,7 @@
  
  	if (mtk_wed_device_active(&dev->mmio.wed))
 diff --git a/mac80211.c b/mac80211.c
-index abad16f31..7cd9b6fc7 100644
+index 9c582cb..3715c73 100644
 --- a/mac80211.c
 +++ b/mac80211.c
 @@ -4,7 +4,6 @@
@@ -282,7 +289,7 @@
  struct mt76_dev *
  mt76_alloc_device(struct device *pdev, unsigned int size,
  		  const struct ieee80211_ops *ops,
-@@ -1785,21 +1743,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1786,21 +1744,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
  }
  EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
  
@@ -304,11 +311,111 @@
  enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
  {
  	struct ieee80211_hw *hw = phy->hw;
+diff --git a/mmio.c b/mmio.c
+index c346249..5fb8392 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -89,8 +89,12 @@ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++	u32 length;
+ 	int i;
+ 
++	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
++				sizeof(struct skb_shared_info));
++
+ 	for (i = 0; i < dev->rx_token_size; i++) {
+ 		struct mt76_txwi_cache *t;
+ 
+@@ -98,7 +102,9 @@ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ 		if (!t || !t->ptr)
+ 			continue;
+ 
+-		mt76_put_page_pool_buf(t->ptr, false);
++		dma_unmap_single(dev->dma_dev, t->dma_addr,
++				 wed->wlan.rx_size, DMA_FROM_DEVICE);
++		__free_pages(virt_to_page(t->ptr), get_order(length));
+ 		t->ptr = NULL;
+ 
+ 		mt76_put_rxwi(dev, t);
+@@ -112,33 +118,45 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+ 	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
+-	struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
+-	int i, len = SKB_WITH_OVERHEAD(q->buf_size);
+-	struct mt76_txwi_cache *t = NULL;
++	u32 length;
++	int i;
++
++	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
++				sizeof(struct skb_shared_info));
+ 
+ 	for (i = 0; i < size; i++) {
+-		enum dma_data_direction dir;
+-		dma_addr_t addr;
+-		u32 offset;
++		struct mt76_txwi_cache *t = mt76_get_rxwi(dev);
++		dma_addr_t phy_addr;
++		struct page *page;
+ 		int token;
+-		void *buf;
++		void *ptr;
+ 
+-		t = mt76_get_rxwi(dev);
+ 		if (!t)
+ 			goto unmap;
+ 
+-		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
+-		if (!buf)
+-			goto unmap;
++		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
++		if (!page) {
++			mt76_put_rxwi(dev, t);
++ 			goto unmap;
++		}
+ 
+-		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
+-		dir = page_pool_get_dma_dir(q->page_pool);
+-		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
++		phy_addr = dma_map_single(dev->dma_dev, ptr,
++					  wed->wlan.rx_size,
++					  DMA_TO_DEVICE);
+ 
+-		desc->buf0 = cpu_to_le32(addr);
+-		token = mt76_rx_token_consume(dev, buf, t, addr);
++		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
++			skb_free_frag(ptr);
++			mt76_put_rxwi(dev, t);
++			goto unmap;
++		}
++
++		desc->buf0 = cpu_to_le32(phy_addr);
++		token = mt76_rx_token_consume(dev, ptr, t, phy_addr);
+ 		if (token < 0) {
+-			mt76_put_page_pool_buf(buf, false);
++			dma_unmap_single(dev->dma_dev, phy_addr,
++					 wed->wlan.rx_size, DMA_TO_DEVICE);
++			__free_pages(page, get_order(length));
++			mt76_put_rxwi(dev, t);
+ 			goto unmap;
+ 		}
+ 
+@@ -150,8 +168,6 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 	return 0;
+ 
+ unmap:
+-	if (t)
+-		mt76_put_rxwi(dev, t);
+ 	mt76_mmio_wed_release_rx_buf(wed);
+ 
+ 	return -ENOMEM;
 diff --git a/mt76.h b/mt76.h
-index 99756dce2..5243741b5 100644
+index d59a1f5..3af97e5 100644
 --- a/mt76.h
 +++ b/mt76.h
-@@ -224,7 +224,7 @@ struct mt76_queue {
+@@ -245,7 +245,7 @@ struct mt76_queue {
  
  	dma_addr_t desc_dma;
  	struct sk_buff *rx_head;
@@ -317,7 +424,7 @@
  };
  
  struct mt76_mcu_ops {
-@@ -1523,7 +1523,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1566,7 +1566,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);
  }
  
@@ -325,10 +432,10 @@
  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);
-@@ -1636,25 +1635,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
- struct mt76_rxwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
+@@ -1707,25 +1706,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_rxwi_cache *r, dma_addr_t phys);
+ 			  struct mt76_txwi_cache *r, dma_addr_t phys);
 -int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q);
 -static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
 -{
@@ -352,7 +459,7 @@
  static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
  {
 diff --git a/mt7915/main.c b/mt7915/main.c
-index a3fd54cc1..796cd5f04 100644
+index ba34c8e..4c80473 100644
 --- a/mt7915/main.c
 +++ b/mt7915/main.c
 @@ -1397,22 +1397,19 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw,
@@ -409,112 +516,8 @@
  }
  
  static void
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index a38109497..a28ab0290 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -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;
-+	u32 length;
- 	int i;
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
-+	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
-+				sizeof(struct skb_shared_info));
-+
- 	for (i = 0; i < dev->mt76.rx_token_size; i++) {
- 		struct mt76_rxwi_cache *r;
- 
-@@ -580,7 +584,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- 		if (!r || !r->ptr)
- 			continue;
- 
--		mt76_put_page_pool_buf(r->ptr, false);
-+		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
-+				 wed->wlan.rx_size, DMA_FROM_DEVICE);
-+		__free_pages(virt_to_page(r->ptr), get_order(length));
- 		r->ptr = NULL;
- 
- 		mt76_put_rxwi(&dev->mt76, r);
-@@ -604,38 +610,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;
--	struct mt76_txwi_cache *t = NULL;
- 	struct mt7915_dev *dev;
--	struct mt76_queue *q;
--	int i, len;
-+	u32 length;
-+	int i;
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
--	q = &dev->mt76.q_rx[MT_RXQ_MAIN];
--	len = SKB_WITH_OVERHEAD(q->buf_size);
-+	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
-+				sizeof(struct skb_shared_info));
- 
- 	for (i = 0; i < size; i++) {
--		enum dma_data_direction dir;
--		dma_addr_t addr;
--		u32 offset;
-+		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
-+		dma_addr_t phy_addr;
-+		struct page *page;
- 		int token;
--		void *buf;
-+		void *ptr;
- 
--		t = mt76_get_rxwi(&dev->mt76);
- 		if (!t)
- 			goto unmap;
- 
--		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
--		if (!buf)
-+		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
-+		if (!page) {
-+			mt76_put_rxwi(&dev->mt76, r);
- 			goto unmap;
-+		}
- 
--		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
--		dir = page_pool_get_dma_dir(q->page_pool);
--		dma_sync_single_for_device(dev->mt76.dma_dev, addr, len, dir);
-+		ptr = page_address(page);
-+		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))) {
-+			__free_pages(page, get_order(length));
-+			mt76_put_rxwi(&dev->mt76, r);
-+			goto unmap;
-+		}
- 
--		desc->buf0 = cpu_to_le32(addr);
--		token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
-+		desc->buf0 = cpu_to_le32(phy_addr);
-+		token = mt76_rx_token_consume(&dev->mt76, ptr, r, phy_addr);
- 		if (token < 0) {
--			mt76_put_page_pool_buf(buf, false);
-+			dma_unmap_single(dev->mt76.dma_dev, phy_addr,
-+					 wed->wlan.rx_size, DMA_TO_DEVICE);
-+			__free_pages(page, get_order(length));
-+			mt76_put_rxwi(&dev->mt76, r);
- 			goto unmap;
- 		}
- 
-@@ -647,8 +662,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 	return 0;
- 
- unmap:
--	if (t)
--		mt76_put_rxwi(&dev->mt76, t);
- 	mt7915_mmio_wed_release_rx_buf(wed);
- 	return -ENOMEM;
- }
 diff --git a/usb.c b/usb.c
-index 5e5c7bf51..3e281715f 100644
+index 5e5c7bf..3e28171 100644
 --- a/usb.c
 +++ b/usb.c
 @@ -319,27 +319,29 @@ mt76u_set_endpoints(struct usb_interface *intf,
@@ -648,5 +651,5 @@
  
  static void mt76u_free_rx(struct mt76_dev *dev)
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2000-wifi-mt76-rework-wed-rx-flow.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2000-wifi-mt76-rework-wed-rx-flow.patch
deleted file mode 100644
index 2b0701a..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2000-wifi-mt76-rework-wed-rx-flow.patch
+++ /dev/null
@@ -1,443 +0,0 @@
-From 0d65df1371fce544fe40c7458ed572a9cb813a48 Mon Sep 17 00:00:00 2001
-From: Bo Jiao <Bo.Jiao@mediatek.com>
-Date: Mon, 6 Feb 2023 13:37:23 +0800
-Subject: [PATCH 2000/2012] wifi: mt76: rework wed rx flow
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Change-Id: Icd787345c811cb5ad30d9c7c1c5f9e5298bd3be6
----
- dma.c           | 89 +++++++++++++++++++++++++------------------------
- mac80211.c      |  2 +-
- mt76.h          | 23 ++++++++-----
- mt7915/dma.c    |  2 --
- mt7915/mmio.c   | 27 +++++++++++----
- mt7915/mt7915.h |  1 +
- tx.c            | 16 ++++-----
- 7 files changed, 90 insertions(+), 70 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index f5091a35b..8182f6dc4 100644
---- a/dma.c
-+++ b/dma.c
-@@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
- 	return t;
- }
- 
--static struct mt76_txwi_cache *
-+static struct mt76_rxwi_cache *
- mt76_alloc_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t;
-+	struct mt76_rxwi_cache *r;
- 
--	t = kzalloc(L1_CACHE_ALIGN(sizeof(*t)), GFP_ATOMIC);
--	if (!t)
-+	r = kzalloc(L1_CACHE_ALIGN(sizeof(*r)), GFP_ATOMIC);
-+	if (!r)
- 		return NULL;
- 
--	t->ptr = NULL;
--	return t;
-+	r->ptr = NULL;
-+	return r;
- }
- 
- static struct mt76_txwi_cache *
-@@ -93,20 +93,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
- 	return t;
- }
- 
--static struct mt76_txwi_cache *
-+static struct mt76_rxwi_cache *
- __mt76_get_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t = NULL;
-+	struct mt76_rxwi_cache *r = NULL;
- 
--	spin_lock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
- 	if (!list_empty(&dev->rxwi_cache)) {
--		t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache,
-+		r = list_first_entry(&dev->rxwi_cache, struct mt76_rxwi_cache,
- 				     list);
--		list_del(&t->list);
-+		list_del(&r->list);
- 	}
--	spin_unlock(&dev->wed_lock);
-+	spin_unlock(&dev->lock);
- 
--	return t;
-+	return r;
- }
- 
- static struct mt76_txwi_cache *
-@@ -120,13 +120,13 @@ mt76_get_txwi(struct mt76_dev *dev)
- 	return mt76_alloc_txwi(dev);
- }
- 
--struct mt76_txwi_cache *
-+struct mt76_rxwi_cache *
- mt76_get_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t = __mt76_get_rxwi(dev);
-+	struct mt76_rxwi_cache *r = __mt76_get_rxwi(dev);
- 
--	if (t)
--		return t;
-+	if (r)
-+		return r;
- 
- 	return mt76_alloc_rxwi(dev);
- }
-@@ -145,14 +145,14 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
- EXPORT_SYMBOL_GPL(mt76_put_txwi);
- 
- void
--mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
-+mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r)
- {
--	if (!t)
-+	if (!r)
- 		return;
- 
--	spin_lock(&dev->wed_lock);
--	list_add(&t->list, &dev->rxwi_cache);
--	spin_unlock(&dev->wed_lock);
-+	spin_lock(&dev->lock);
-+	list_add(&r->list, &dev->rxwi_cache);
-+	spin_unlock(&dev->lock);
- }
- EXPORT_SYMBOL_GPL(mt76_put_rxwi);
- 
-@@ -173,13 +173,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
- void
- mt76_free_pending_rxwi(struct mt76_dev *dev)
- {
--	struct mt76_txwi_cache *t;
-+	struct mt76_rxwi_cache *r;
- 
- 	local_bh_disable();
--	while ((t = __mt76_get_rxwi(dev)) != NULL) {
--		if (t->ptr)
--			mt76_put_page_pool_buf(t->ptr, false);
--		kfree(t);
-+	while ((r = __mt76_get_rxwi(dev)) != NULL) {
-+		if (r->ptr)
-+			mt76_put_page_pool_buf(r->ptr, false);
-+		kfree(r);
- 	}
- 	local_bh_enable();
- }
-@@ -217,7 +217,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- {
- 	struct mt76_desc *desc = &q->desc[q->head];
- 	struct mt76_queue_entry *entry = &q->entry[q->head];
--	struct mt76_txwi_cache *txwi = NULL;
-+	struct mt76_rxwi_cache *rxwi = NULL;
- 	u32 buf1 = 0, ctrl;
- 	int idx = q->head;
- 	int rx_token;
-@@ -225,13 +225,13 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
- 
- 	if (mt76_queue_is_wed_rx(q)) {
--		txwi = mt76_get_rxwi(dev);
--		if (!txwi)
-+		rxwi = mt76_get_rxwi(dev);
-+		if (!rxwi)
- 			return -ENOMEM;
- 
--		rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
-+		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
- 		if (rx_token < 0) {
--			mt76_put_rxwi(dev, txwi);
-+			mt76_put_rxwi(dev, rxwi);
- 			return -ENOMEM;
- 		}
- 
-@@ -246,7 +246,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
- 
- 	entry->dma_addr[0] = buf->addr;
- 	entry->dma_len[0] = buf->len;
--	entry->txwi = txwi;
-+	entry->rxwi = rxwi;
- 	entry->buf = data;
- 	entry->wcid = 0xffff;
- 	entry->skip_buf1 = true;
-@@ -406,20 +406,20 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 	if (mt76_queue_is_wed_rx(q)) {
- 		u32 buf1 = le32_to_cpu(desc->buf1);
- 		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
--		struct mt76_txwi_cache *t = mt76_rx_token_release(dev, token);
-+		struct mt76_rxwi_cache *r = mt76_rx_token_release(dev, token);
- 
--		if (!t)
-+		if (!r)
- 			return NULL;
- 
--		dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
-+		dma_sync_single_for_cpu(dev->dma_dev, r->dma_addr,
- 				SKB_WITH_OVERHEAD(q->buf_size),
- 				page_pool_get_dma_dir(q->page_pool));
- 
--		buf = t->ptr;
--		t->dma_addr = 0;
--		t->ptr = NULL;
-+		buf = r->ptr;
-+		r->dma_addr = 0;
-+		r->ptr = NULL;
- 
--		mt76_put_rxwi(dev, t);
-+		mt76_put_rxwi(dev, r);
- 
- 		if (drop) {
- 			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
-@@ -979,16 +979,19 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	mt76_for_each_q_rx(dev, i) {
- 		struct mt76_queue *q = &dev->q_rx[i];
- 
-+		if (mt76_queue_is_wed_rx(q))
-+			continue;
-+
- 		netif_napi_del(&dev->napi[i]);
- 		mt76_dma_rx_cleanup(dev, q);
- 
- 		page_pool_destroy(q->page_pool);
- 	}
- 
--	mt76_free_pending_txwi(dev);
--	mt76_free_pending_rxwi(dev);
--
- 	if (mtk_wed_device_active(&dev->mmio.wed))
- 		mtk_wed_device_detach(&dev->mmio.wed);
-+
-+	mt76_free_pending_txwi(dev);
-+	mt76_free_pending_rxwi(dev);
- }
- EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
-diff --git a/mac80211.c b/mac80211.c
-index ef4b83244..abad16f31 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -617,7 +617,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
- 	spin_lock_init(&dev->lock);
- 	spin_lock_init(&dev->cc_lock);
- 	spin_lock_init(&dev->status_lock);
--	spin_lock_init(&dev->wed_lock);
- 	mutex_init(&dev->mutex);
- 	init_waitqueue_head(&dev->tx_wait);
- 
-@@ -650,6 +649,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;
-+	dev->rx_token_size = dev->drv->rx_token_size;
- 
- 	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 9f84389b7..99756dce2 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -180,6 +180,7 @@ struct mt76_queue_entry {
- 	};
- 	union {
- 		struct mt76_txwi_cache *txwi;
-+		struct mt76_rxwi_cache *rxwi;
- 		struct urb *urb;
- 		int buf_sz;
- 	};
-@@ -377,10 +378,14 @@ struct mt76_txwi_cache {
- 	struct list_head list;
- 	dma_addr_t dma_addr;
- 
--	union {
--		struct sk_buff *skb;
--		void *ptr;
--	};
-+	struct sk_buff *skb;
-+};
-+
-+struct mt76_rxwi_cache {
-+	struct list_head list;
-+	dma_addr_t dma_addr;
-+
-+	void *ptr;
- };
- 
- struct mt76_rx_tid {
-@@ -466,6 +471,7 @@ struct mt76_driver_ops {
- 	u16 txwi_size;
- 	u16 token_size;
- 	u8 mcs_rates;
-+	u16 rx_token_size;
- 
- 	void (*update_survey)(struct mt76_phy *phy);
- 
-@@ -824,7 +830,6 @@ struct mt76_dev {
- 
- 	struct ieee80211_hw *hw;
- 
--	spinlock_t wed_lock;
- 	spinlock_t lock;
- 	spinlock_t cc_lock;
- 
-@@ -1473,8 +1478,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);
--void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
--struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
-+void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r);
-+struct mt76_rxwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
- 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);
-@@ -1628,9 +1633,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);
--struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
-+struct mt76_rxwi_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);
-+			  struct mt76_rxwi_cache *r, dma_addr_t phys);
- int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q);
- static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
- {
-diff --git a/mt7915/dma.c b/mt7915/dma.c
-index 59a44d79a..326c8c8c1 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)
- 		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
- 			dev->mt76.q_rx[MT_RXQ_MAIN].flags =
- 				MT_WED_Q_RX(MT7915_RXQ_BAND0);
--			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
- 		}
- 
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
-@@ -546,7 +545,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
- 		    mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
- 			dev->mt76.q_rx[MT_RXQ_BAND1].flags =
- 				MT_WED_Q_RX(MT7915_RXQ_BAND1);
--			dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
- 		}
- 
- 		/* rx data queue for band1 */
-diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index fc7ace638..a38109497 100644
---- a/mt7915/mmio.c
-+++ b/mt7915/mmio.c
-@@ -574,16 +574,28 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- 
- 	dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
- 	for (i = 0; i < dev->mt76.rx_token_size; i++) {
--		struct mt76_txwi_cache *t;
-+		struct mt76_rxwi_cache *r;
- 
--		t = mt76_rx_token_release(&dev->mt76, i);
--		if (!t || !t->ptr)
-+		r = mt76_rx_token_release(&dev->mt76, i);
-+		if (!r || !r->ptr)
- 			continue;
- 
--		mt76_put_page_pool_buf(t->ptr, false);
--		t->ptr = NULL;
-+		mt76_put_page_pool_buf(r->ptr, false);
-+		r->ptr = NULL;
- 
--		mt76_put_rxwi(&dev->mt76, t);
-+		mt76_put_rxwi(&dev->mt76, r);
-+	}
-+
-+	mt76_for_each_q_rx(dev, i) {
-+		struct mt76_queue *q = &dev->q_rx[i];
-+
-+		if (!mt76_queue_is_wed_rx(q))
-+			continue;
-+
-+		netif_napi_del(&dev->napi[i]);
-+		mt76_dma_rx_cleanup(dev, q);
-+
-+		page_pool_destroy(q->page_pool);
- 	}
- 
- 	mt76_free_pending_rxwi(&dev->mt76);
-@@ -786,7 +798,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;
- 
--	dev->mt76.rx_token_size = wed->wlan.rx_npkt;
-+	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
- 
- 	if (mtk_wed_device_attach(wed))
- 		return 0;
-@@ -992,6 +1004,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
- 				SURVEY_INFO_TIME_RX |
- 				SURVEY_INFO_TIME_BSS_RX,
- 		.token_size = MT7915_TOKEN_SIZE,
-+		.rx_token_size = MT7915_RX_TOKEN_SIZE;
- 		.tx_prepare_skb = mt7915_tx_prepare_skb,
- 		.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 d317c523b..91eb5ad0f 100644
---- a/mt7915/mt7915.h
-+++ b/mt7915/mt7915.h
-@@ -62,6 +62,7 @@
- #define MT7915_EEPROM_BLOCK_SIZE	16
- #define MT7915_HW_TOKEN_SIZE		4096
- #define MT7915_TOKEN_SIZE		8192
-+#define MT7915_RX_TOKEN_SIZE		4096
- 
- #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 1809b0329..74bf0de12 100644
---- a/tx.c
-+++ b/tx.c
-@@ -843,16 +843,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,
--			  struct mt76_txwi_cache *t, dma_addr_t phys)
-+			  struct mt76_rxwi_cache *r, dma_addr_t phys)
- {
- 	int token;
- 
- 	spin_lock_bh(&dev->rx_token_lock);
--	token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
-+	token = idr_alloc(&dev->rx_token, r, 0, dev->rx_token_size,
- 			  GFP_ATOMIC);
- 	if (token >= 0) {
--		t->ptr = ptr;
--		t->dma_addr = phys;
-+		r->ptr = ptr;
-+		r->dma_addr = phys;
- 	}
- 	spin_unlock_bh(&dev->rx_token_lock);
- 
-@@ -889,15 +889,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
- }
- EXPORT_SYMBOL_GPL(mt76_token_release);
- 
--struct mt76_txwi_cache *
-+struct mt76_rxwi_cache *
- mt76_rx_token_release(struct mt76_dev *dev, int token)
- {
--	struct mt76_txwi_cache *t;
-+	struct mt76_rxwi_cache *r;
- 
- 	spin_lock_bh(&dev->rx_token_lock);
--	t = idr_remove(&dev->rx_token, token);
-+	r = idr_remove(&dev->rx_token, token);
- 	spin_unlock_bh(&dev->rx_token_lock);
- 
--	return t;
-+	return r;
- }
- EXPORT_SYMBOL_GPL(mt76_rx_token_release);
--- 
-2.39.2
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2001-wifi-mt76-rework-wed-rx-flow.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2001-wifi-mt76-rework-wed-rx-flow.patch
new file mode 100644
index 0000000..a0854af
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2001-wifi-mt76-rework-wed-rx-flow.patch
@@ -0,0 +1,539 @@
+From 78b8b86fce85c8ff6fad935bd9bd8b2df0e151ab Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Mon, 6 Feb 2023 13:37:23 +0800
+Subject: [PATCH 65/98] wifi: mt76: rework wed rx flow
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Change-Id: Icd787345c811cb5ad30d9c7c1c5f9e5298bd3be6
+---
+ dma.c           | 125 +++++++++++++++++++++++++++++++-----------------
+ mac80211.c      |   2 +-
+ mmio.c          |  58 ++++++++++++++--------
+ mt76.h          |  23 +++++----
+ mt7915/mmio.c   |   3 +-
+ mt7915/mt7915.h |   1 +
+ tx.c            |  16 +++----
+ 7 files changed, 143 insertions(+), 85 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 06b76ea..f48ec57 100644
+--- a/dma.c
++++ b/dma.c
+@@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
+ 	return t;
+ }
+ 
+-static struct mt76_txwi_cache *
++static struct mt76_rxwi_cache *
+ mt76_alloc_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t;
++	struct mt76_rxwi_cache *r;
+ 
+-	t = kzalloc(L1_CACHE_ALIGN(sizeof(*t)), GFP_ATOMIC);
+-	if (!t)
++	r = kzalloc(L1_CACHE_ALIGN(sizeof(*r)), GFP_ATOMIC);
++	if (!r)
+ 		return NULL;
+ 
+-	t->ptr = NULL;
+-	return t;
++	r->ptr = NULL;
++	return r;
+ }
+ 
+ static struct mt76_txwi_cache *
+@@ -93,20 +93,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
+ 	return t;
+ }
+ 
+-static struct mt76_txwi_cache *
++static struct mt76_rxwi_cache *
+ __mt76_get_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t = NULL;
++	struct mt76_rxwi_cache *r = NULL;
+ 
+-	spin_lock(&dev->wed_lock);
++	spin_lock(&dev->lock);
+ 	if (!list_empty(&dev->rxwi_cache)) {
+-		t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache,
++		r = list_first_entry(&dev->rxwi_cache, struct mt76_rxwi_cache,
+ 				     list);
+-		list_del(&t->list);
++		list_del(&r->list);
+ 	}
+-	spin_unlock(&dev->wed_lock);
++	spin_unlock(&dev->lock);
+ 
+-	return t;
++	return r;
+ }
+ 
+ static struct mt76_txwi_cache *
+@@ -120,13 +120,13 @@ mt76_get_txwi(struct mt76_dev *dev)
+ 	return mt76_alloc_txwi(dev);
+ }
+ 
+-struct mt76_txwi_cache *
++struct mt76_rxwi_cache *
+ mt76_get_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t = __mt76_get_rxwi(dev);
++	struct mt76_rxwi_cache *r = __mt76_get_rxwi(dev);
+ 
+-	if (t)
+-		return t;
++	if (r)
++		return r;
+ 
+ 	return mt76_alloc_rxwi(dev);
+ }
+@@ -145,14 +145,14 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ EXPORT_SYMBOL_GPL(mt76_put_txwi);
+ 
+ void
+-mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
++mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r)
+ {
+-	if (!t)
++	if (!r)
+ 		return;
+ 
+-	spin_lock(&dev->wed_lock);
+-	list_add(&t->list, &dev->rxwi_cache);
+-	spin_unlock(&dev->wed_lock);
++	spin_lock(&dev->lock);
++	list_add(&r->list, &dev->rxwi_cache);
++	spin_unlock(&dev->lock);
+ }
+ EXPORT_SYMBOL_GPL(mt76_put_rxwi);
+ 
+@@ -173,13 +173,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+ void
+ mt76_free_pending_rxwi(struct mt76_dev *dev)
+ {
+-	struct mt76_txwi_cache *t;
++	struct mt76_rxwi_cache *r;
+ 
+ 	local_bh_disable();
+-	while ((t = __mt76_get_rxwi(dev)) != NULL) {
+-		if (t->ptr)
+-			skb_free_frag(t->ptr);
+-		kfree(t);
++	while ((r = __mt76_get_rxwi(dev)) != NULL) {
++		if (r->ptr)
++			skb_free_frag(r->ptr);
++		kfree(r);
+ 	}
+ 	local_bh_enable();
+ }
+@@ -227,10 +227,10 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
+ 
+ static int
+ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+-		    struct mt76_queue_buf *buf, void *data)
++		    struct mt76_queue_buf *buf, void *data,
++		    struct mt76_rxwi_cache *rxwi)
+ {
+ 	struct mt76_queue_entry *entry = &q->entry[q->head];
+-	struct mt76_txwi_cache *txwi = NULL;
+ 	struct mt76_desc *desc;
+ 	u32 buf1 = 0, ctrl;
+ 	int idx = q->head;
+@@ -248,13 +248,15 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+ 
+ 	if (mt76_queue_is_wed_rx(q)) {
+-		txwi = mt76_get_rxwi(dev);
+-		if (!txwi)
+-			return -ENOMEM;
++		if (!rxwi) {
++			rxwi = mt76_get_rxwi(dev);
++			if (!rxwi)
++				return -ENOMEM;
++		}
+ 
+-		rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
++		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
+ 		if (rx_token < 0) {
+-			mt76_put_rxwi(dev, txwi);
++			mt76_put_rxwi(dev, rxwi);
+ 			return -ENOMEM;
+ 		}
+ 
+@@ -270,7 +272,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ done:
+ 	entry->dma_addr[0] = buf->addr;
+ 	entry->dma_len[0] = buf->len;
+-	entry->txwi = txwi;
++	entry->rxwi = rxwi;
+ 	entry->buf = data;
+ 	entry->wcid = 0xffff;
+ 	entry->skip_buf1 = true;
+@@ -412,7 +414,7 @@ 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,
+-		 int *len, u32 *info, bool *more, bool *drop)
++		 int *len, u32 *info, bool *more, bool *drop, bool flush)
+ {
+ 	struct mt76_queue_entry *e = &q->entry[idx];
+ 	struct mt76_desc *desc = &q->desc[idx];
+@@ -440,20 +442,53 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 	if (mt76_queue_is_wed_rx(q)) {
+ 		u32 buf1 = le32_to_cpu(desc->buf1);
+ 		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
+-		struct mt76_txwi_cache *t = mt76_rx_token_release(dev, token);
++		struct mt76_rxwi_cache *r = mt76_rx_token_release(dev, token);
+ 
+-		if (!t)
++		if (!r)
+ 			return NULL;
+ 
+-		dma_unmap_single(dev->dma_dev, t->dma_addr,
++		dma_unmap_single(dev->dma_dev, r->dma_addr,
+ 				 SKB_WITH_OVERHEAD(q->buf_size),
+ 				 DMA_FROM_DEVICE);
+ 
+-		buf = t->ptr;
+-		t->dma_addr = 0;
+-		t->ptr = NULL;
++		if (flush) {
++			buf = r->ptr;
++			r->dma_addr = 0;
++			r->ptr = NULL;
++
++			mt76_put_rxwi(dev, r);
++		} else {
++			struct mt76_queue_buf qbuf;
++
++			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++			if (!buf)
++				return NULL;
++
++			memcpy(buf, r->ptr, SKB_WITH_OVERHEAD(q->buf_size));
++
++			r->dma_addr = dma_map_single(dev->dma_dev, r->ptr,
++						     SKB_WITH_OVERHEAD(q->buf_size),
++						     DMA_FROM_DEVICE);
++			if (unlikely(dma_mapping_error(dev->dma_dev, r->dma_addr))) {
++				skb_free_frag(r->ptr);
++				mt76_put_rxwi(dev, r);
++				return NULL;
++			}
++
++			qbuf.addr = r->dma_addr;
++			qbuf.len = SKB_WITH_OVERHEAD(q->buf_size);
++			qbuf.skip_unmap = false;
++
++			if (mt76_dma_add_rx_buf(dev, q, &qbuf, r->ptr, r) < 0) {
++				dma_unmap_single(dev->dma_dev, r->dma_addr,
++						 SKB_WITH_OVERHEAD(q->buf_size),
++						 DMA_FROM_DEVICE);
++				skb_free_frag(r->ptr);
++				mt76_put_rxwi(dev, r);
++				return NULL;
++			}
++		}
+ 
+-		mt76_put_rxwi(dev, t);
+ 		if (drop)
+ 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
+ 	} else {
+@@ -490,7 +525,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+ 	q->tail = (q->tail + 1) % q->ndesc;
+ 	q->queued--;
+ 
+-	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
++	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
+ }
+ 
+ static int
+@@ -658,7 +693,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ done:
+ 		qbuf.len = len - offset;
+ 		qbuf.skip_unmap = false;
+-		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
++		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf, NULL) < 0) {
+ 			dma_unmap_single(dev->dma_dev, addr, len,
+ 					 DMA_FROM_DEVICE);
+ 			skb_free_frag(buf);
+diff --git a/mac80211.c b/mac80211.c
+index 3715c73..4552bc2 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -575,7 +575,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+ 	spin_lock_init(&dev->lock);
+ 	spin_lock_init(&dev->cc_lock);
+ 	spin_lock_init(&dev->status_lock);
+-	spin_lock_init(&dev->wed_lock);
+ 	mutex_init(&dev->mutex);
+ 	init_waitqueue_head(&dev->tx_wait);
+ 
+@@ -608,6 +607,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;
++	dev->rx_token_size = dev->drv->rx_token_size;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
+ 		skb_queue_head_init(&dev->rx_skb[i]);
+diff --git a/mmio.c b/mmio.c
+index 5fb8392..f7495f6 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -89,28 +89,45 @@ EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
+ void mt76_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+-	u32 length;
++	struct page *page;
+ 	int i;
+ 
+-	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
+-				sizeof(struct skb_shared_info));
+-
+ 	for (i = 0; i < dev->rx_token_size; i++) {
+-		struct mt76_txwi_cache *t;
++		struct mt76_rxwi_cache *r;
+ 
+-		t = mt76_rx_token_release(dev, i);
+-		if (!t || !t->ptr)
++		r = mt76_rx_token_release(dev, i);
++		if (!r || !r->ptr)
+ 			continue;
+ 
+-		dma_unmap_single(dev->dma_dev, t->dma_addr,
++		dma_unmap_single(dev->dma_dev, r->dma_addr,
+ 				 wed->wlan.rx_size, DMA_FROM_DEVICE);
+-		__free_pages(virt_to_page(t->ptr), get_order(length));
+-		t->ptr = NULL;
++		skb_free_frag(r->ptr);
++		r->ptr = NULL;
+ 
+-		mt76_put_rxwi(dev, t);
++		mt76_put_rxwi(dev, r);
+ 	}
+ 
+ 	mt76_free_pending_rxwi(dev);
++
++	mt76_for_each_q_rx(dev, i) {
++		struct mt76_queue *q = &dev->q_rx[i];
++
++		if (mt76_queue_is_wed_rx(q)) {
++			if (!q->rx_page.va)
++				continue;
++
++			page = virt_to_page(q->rx_page.va);
++			__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
++			memset(&q->rx_page, 0, sizeof(q->rx_page));
++		}
++	}
++
++	if (!wed->rx_buf_ring.rx_page.va)
++		return;
++
++	page = virt_to_page(wed->rx_buf_ring.rx_page.va);
++	__page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias);
++	memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page));
+ }
+ EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
+ 
+@@ -125,18 +142,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 				sizeof(struct skb_shared_info));
+ 
+ 	for (i = 0; i < size; i++) {
+-		struct mt76_txwi_cache *t = mt76_get_rxwi(dev);
++		struct mt76_rxwi_cache *r = mt76_get_rxwi(dev);
+ 		dma_addr_t phy_addr;
+-		struct page *page;
+ 		int token;
+ 		void *ptr;
+ 
+-		if (!t)
++		if (!r)
+ 			goto unmap;
+ 
+-		page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
+-		if (!page) {
+-			mt76_put_rxwi(dev, t);
++		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, GFP_ATOMIC);
++		if (!ptr) {
++			mt76_put_rxwi(dev, r);
+  			goto unmap;
+ 		}
+ 
+@@ -146,17 +162,17 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 
+ 		if (unlikely(dma_mapping_error(dev->dev, phy_addr))) {
+ 			skb_free_frag(ptr);
+-			mt76_put_rxwi(dev, t);
++			mt76_put_rxwi(dev, r);
+ 			goto unmap;
+ 		}
+ 
+ 		desc->buf0 = cpu_to_le32(phy_addr);
+-		token = mt76_rx_token_consume(dev, ptr, t, phy_addr);
++		token = mt76_rx_token_consume(dev, ptr, r, phy_addr);
+ 		if (token < 0) {
+ 			dma_unmap_single(dev->dma_dev, phy_addr,
+ 					 wed->wlan.rx_size, DMA_TO_DEVICE);
+-			__free_pages(page, get_order(length));
+-			mt76_put_rxwi(dev, t);
++			skb_free_frag(ptr);
++			mt76_put_rxwi(dev, r);
+ 			goto unmap;
+ 		}
+ 
+diff --git a/mt76.h b/mt76.h
+index 3af97e5..b960f3d 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -200,6 +200,7 @@ struct mt76_queue_entry {
+ 	};
+ 	union {
+ 		struct mt76_txwi_cache *txwi;
++		struct mt76_rxwi_cache *rxwi;
+ 		struct urb *urb;
+ 		int buf_sz;
+ 	};
+@@ -410,10 +411,14 @@ struct mt76_txwi_cache {
+ 	struct list_head list;
+ 	dma_addr_t dma_addr;
+ 
+-	union {
+-		struct sk_buff *skb;
+-		void *ptr;
+-	};
++	struct sk_buff *skb;
++};
++
++struct mt76_rxwi_cache {
++	struct list_head list;
++	dma_addr_t dma_addr;
++
++	void *ptr;
+ };
+ 
+ struct mt76_rx_tid {
+@@ -499,6 +504,7 @@ struct mt76_driver_ops {
+ 	u16 txwi_size;
+ 	u16 token_size;
+ 	u8 mcs_rates;
++	u16 rx_token_size;
+ 
+ 	void (*update_survey)(struct mt76_phy *phy);
+ 
+@@ -858,7 +864,6 @@ struct mt76_dev {
+ 
+ 	struct ieee80211_hw *hw;
+ 
+-	spinlock_t wed_lock;
+ 	spinlock_t lock;
+ 	spinlock_t cc_lock;
+ 
+@@ -1521,8 +1526,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);
+-void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
+-struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
++void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r);
++struct mt76_rxwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
+ 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);
+@@ -1703,9 +1708,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);
+-struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
++struct mt76_rxwi_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);
++			  struct mt76_rxwi_cache *r, dma_addr_t phys);
+ 
+ static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
+ {
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 85cb3fe..690cac5 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -687,7 +687,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;
+ 
+-	dev->mt76.rx_token_size = wed->wlan.rx_npkt;
++	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
+ 
+ 	if (mtk_wed_device_attach(wed))
+ 		return 0;
+@@ -893,6 +893,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
+ 				SURVEY_INFO_TIME_RX |
+ 				SURVEY_INFO_TIME_BSS_RX,
+ 		.token_size = MT7915_TOKEN_SIZE,
++		.rx_token_size = MT7915_RX_TOKEN_SIZE;
+ 		.tx_prepare_skb = mt7915_tx_prepare_skb,
+ 		.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 d317c52..91eb5ad 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -62,6 +62,7 @@
+ #define MT7915_EEPROM_BLOCK_SIZE	16
+ #define MT7915_HW_TOKEN_SIZE		4096
+ #define MT7915_TOKEN_SIZE		8192
++#define MT7915_RX_TOKEN_SIZE		4096
+ 
+ #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 1809b03..74bf0de 100644
+--- a/tx.c
++++ b/tx.c
+@@ -843,16 +843,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,
+-			  struct mt76_txwi_cache *t, dma_addr_t phys)
++			  struct mt76_rxwi_cache *r, dma_addr_t phys)
+ {
+ 	int token;
+ 
+ 	spin_lock_bh(&dev->rx_token_lock);
+-	token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
++	token = idr_alloc(&dev->rx_token, r, 0, dev->rx_token_size,
+ 			  GFP_ATOMIC);
+ 	if (token >= 0) {
+-		t->ptr = ptr;
+-		t->dma_addr = phys;
++		r->ptr = ptr;
++		r->dma_addr = phys;
+ 	}
+ 	spin_unlock_bh(&dev->rx_token_lock);
+ 
+@@ -889,15 +889,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+ }
+ EXPORT_SYMBOL_GPL(mt76_token_release);
+ 
+-struct mt76_txwi_cache *
++struct mt76_rxwi_cache *
+ mt76_rx_token_release(struct mt76_dev *dev, int token)
+ {
+-	struct mt76_txwi_cache *t;
++	struct mt76_rxwi_cache *r;
+ 
+ 	spin_lock_bh(&dev->rx_token_lock);
+-	t = idr_remove(&dev->rx_token, token);
++	r = idr_remove(&dev->rx_token, token);
+ 	spin_unlock_bh(&dev->rx_token_lock);
+ 
+-	return t;
++	return r;
+ }
+ EXPORT_SYMBOL_GPL(mt76_rx_token_release);
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
index 0cd7322..3dc3543 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
@@ -1,8 +1,8 @@
-From 522991328e51d164645d002c0b51d010a31a05df Mon Sep 17 00:00:00 2001
+From 1c0cb4fc09293006efdf8d1a9e92715a5705c29e Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Wed, 19 Apr 2023 17:13:41 +0800
-Subject: [PATCH 2002/2012] wifi: mt76: wed: change wed token init size to
- adapt wed3.0
+Subject: [PATCH 66/98] wifi: mt76: wed: change wed token init size to adapt
+ wed3.0
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
@@ -10,7 +10,7 @@
  1 file changed, 7 insertions(+), 3 deletions(-)
 
 diff --git a/tx.c b/tx.c
-index 74bf0de12..3857c2af6 100644
+index 74bf0de..3857c2a 100644
 --- a/tx.c
 +++ b/tx.c
 @@ -819,12 +819,16 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
@@ -34,5 +34,5 @@
  
  #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2006-wifi-mt76-add-random-early-drop-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2003-wifi-mt76-add-random-early-drop-support.patch
similarity index 87%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2006-wifi-mt76-add-random-early-drop-support.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2003-wifi-mt76-add-random-early-drop-support.patch
index 6b7206c..e21fa8b 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2006-wifi-mt76-add-random-early-drop-support.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2003-wifi-mt76-add-random-early-drop-support.patch
@@ -1,7 +1,7 @@
-From f314682c17e80faa3a2e59f3c16108ad746b450e Mon Sep 17 00:00:00 2001
+From 50d93c608b1cfe0750fa98c1fbafe6ad6ed3212d Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Wed, 19 Apr 2023 18:32:41 +0800
-Subject: [PATCH 2006/2012] wifi: mt76: add random early drop support
+Subject: [PATCH 67/98] wifi: mt76: add random early drop support
 
 ---
  mt7996/mcu.c    | 81 +++++++++++++++++++++++++++++++++++++++++++++++--
@@ -10,10 +10,10 @@
  3 files changed, 83 insertions(+), 3 deletions(-)
 
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 2fc22d576..b4d8e9c7f 100644
+index b8d26ec..6589610 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -3030,8 +3030,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
+@@ -3012,8 +3012,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
  	if (ret)
  		return ret;
  
@@ -24,7 +24,7 @@
  }
  
  int mt7996_mcu_init(struct mt7996_dev *dev)
-@@ -3063,6 +3063,83 @@ out:
+@@ -3045,6 +3045,83 @@ out:
  	skb_queue_purge(&dev->mt76.mcu.res_q);
  }
  
@@ -66,7 +66,7 @@
 +
 +	if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
 +		req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
-+			cpu_to_le16(MT7996_SW_TOKEN_SIZE);
++			cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
 +
 +	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
 +				 &req, sizeof(req), false);
@@ -109,10 +109,10 @@
  {
  	struct {
 diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 47fd1874d..7ab84029e 100644
+index bb876f3..666216a 100644
 --- a/mt7996/mcu.h
 +++ b/mt7996/mcu.h
-@@ -290,8 +290,9 @@ enum {
+@@ -287,8 +287,9 @@ enum {
  enum {
  	MCU_WA_PARAM_PDMA_RX = 0x04,
  	MCU_WA_PARAM_CPU_UTIL = 0x0b,
@@ -123,7 +123,7 @@
  };
  
  enum mcu_mmps_mode {
-@@ -821,6 +822,7 @@ enum {
+@@ -817,6 +818,7 @@ enum {
  	UNI_VOW_DRR_CTRL,
  	UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
  	UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
@@ -132,10 +132,10 @@
  
  enum {
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index cf2a66df2..c15e926a7 100644
+index 6775360..bba1364 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -624,6 +624,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
+@@ -654,6 +654,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
  int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
  int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
  int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
@@ -144,5 +144,5 @@
  int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
  int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch
deleted file mode 100644
index 335c634..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch
+++ /dev/null
@@ -1,973 +0,0 @@
-From fce79d49d2edfd81d8db74e0093b993cb2aff1ca Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Mon, 7 Aug 2023 20:05:49 +0800
-Subject: [PATCH 2003/2012] wifi: mt76: mt7996: wed: add wed3.0 tx support
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c           |  17 ++-
- mt76.h          |   7 ++
- mt7996/dma.c    | 126 ++++++++++++++++++---
- mt7996/init.c   |  21 +++-
- mt7996/mac.c    |  29 ++++-
- mt7996/main.c   |  46 ++++++++
- mt7996/mmio.c   | 295 +++++++++++++++++++++++++++++++++++++++++++++---
- mt7996/mt7996.h |   9 +-
- mt7996/pci.c    |  46 ++++++--
- mt7996/regs.h   |   5 +
- 10 files changed, 546 insertions(+), 55 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 3785425b4..c2dbe6f6b 100644
---- a/dma.c
-+++ b/dma.c
-@@ -13,6 +13,11 @@
- 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
- 	u32 _val;							\
- 	if ((_q)->flags & MT_QFLAG_WED)					\
-+		if((_q)->flags & MT_QFLAG_WED_EXT)			\
-+		_val = mtk_wed_device_reg_read(&(_dev)->mmio.wed_ext,	\
-+					       ((_q)->wed_regs +	\
-+					        _offset));		\
-+		else							\
- 		_val = mtk_wed_device_reg_read(&(_dev)->mmio.wed,	\
- 					       ((_q)->wed_regs +	\
- 					        _offset));		\
-@@ -24,6 +29,11 @@
- #define Q_WRITE(_dev, _q, _field, _val)	do {				\
- 	u32 _offset = offsetof(struct mt76_queue_regs, _field);		\
- 	if ((_q)->flags & MT_QFLAG_WED)					\
-+		if((_q)->flags & MT_QFLAG_WED_EXT)			\
-+		mtk_wed_device_reg_write(&(_dev)->mmio.wed_ext,		\
-+					 ((_q)->wed_regs + _offset),	\
-+					 _val);				\
-+		else							\
- 		mtk_wed_device_reg_write(&(_dev)->mmio.wed,		\
- 					 ((_q)->wed_regs + _offset),	\
- 					 _val);				\
-@@ -656,6 +666,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
- 	if (!(q->flags & MT_QFLAG_WED))
- 		return 0;
- 
-+	if ((q->flags & MT_QFLAG_WED_EXT))
-+		wed = &dev->mmio.wed_ext;
-+
- 	type = FIELD_GET(MT_QFLAG_WED_TYPE, q->flags);
- 	ring = FIELD_GET(MT_QFLAG_WED_RING, q->flags);
- 
-@@ -721,7 +734,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	if (ret)
- 		return ret;
- 
--	if (q->flags != MT_WED_Q_TXFREE)
-+	if (!mt76_queue_is_txfree(q))
- 		mt76_dma_queue_reset(dev, q);
- 
- 	return 0;
-@@ -1001,6 +1014,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	if (mtk_wed_device_active(&dev->mmio.wed))
- 		mtk_wed_device_detach(&dev->mmio.wed);
- 
-+	if (mtk_wed_device_active(&dev->mmio.wed_ext))
-+		mtk_wed_device_detach(&dev->mmio.wed_ext);
- 	mt76_free_pending_txwi(dev);
- 	mt76_free_pending_rxwi(dev);
- }
-diff --git a/mt76.h b/mt76.h
-index 5243741b5..3b2a658db 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -51,6 +51,7 @@
- #define MT_QFLAG_WED_RING	GENMASK(1, 0)
- #define MT_QFLAG_WED_TYPE	GENMASK(3, 2)
- #define MT_QFLAG_WED		BIT(4)
-+#define MT_QFLAG_WED_EXT	BIT(11)
- 
- #define __MT_WED_Q(_type, _n)	(MT_QFLAG_WED | \
- 				 FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
-@@ -629,6 +630,7 @@ struct mt76_mmio {
- 	u32 irqmask;
- 
- 	struct mtk_wed_device wed;
-+	struct mtk_wed_device wed_ext;
- 	struct completion wed_reset;
- 	struct completion wed_reset_complete;
- };
-@@ -1627,6 +1629,11 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
- 	return (q->flags & MT_QFLAG_WED) &&
- 	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
- }
-+static inline bool mt76_queue_is_txfree(struct mt76_queue *q)
-+{
-+	return (q->flags & MT_QFLAG_WED) &&
-+	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
-+}
- 
- struct mt76_txwi_cache *
- mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 2e75d2794..3c8f617e0 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -7,6 +7,25 @@
- #include "../dma.h"
- #include "mac.h"
- 
-+int
-+mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, int n_desc,
-+		     int ring_base, struct mtk_wed_device *wed)
-+{
-+	struct mt7996_dev *dev = phy->dev;
-+	u32 flags = 0;
-+
-+	if (mtk_wed_device_active(wed)) {
-+		ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
-+		idx -= MT_TXQ_ID(0);
-+		flags = MT_WED_Q_TX(idx);
-+		if (phy->mt76->band_idx == MT_BAND2)
-+			flags = MT_QFLAG_WED_EXT | MT_WED_Q_TX(0) ;
-+	}
-+
-+	return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc,
-+					  ring_base, flags);
-+}
-+
- static int mt7996_poll_tx(struct napi_struct *napi, int budget)
- {
- 	struct mt7996_dev *dev;
-@@ -140,7 +159,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- 	}
- }
- 
--void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
-+void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
- {
- 	u32 hif1_ofs = 0;
- 	u32 irq_mask;
-@@ -165,11 +184,7 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- 	}
- 
- 	/* 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;
-+	irq_mask = MT_INT_MCU_CMD | MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU;
- 
- 	if (mt7996_band_valid(dev, MT_BAND0))
- 		irq_mask |= MT_INT_BAND0_RX_DONE;
-@@ -180,7 +195,18 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset)
- 	if (mt7996_band_valid(dev, MT_BAND2))
- 		irq_mask |= MT_INT_BAND2_RX_DONE;
- 
--done:
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
-+		u32 wed_irq_mask = irq_mask;
-+
-+		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
-+
-+		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+
-+		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
-+	}
-+
-+	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-+
- 	mt7996_irq_enable(dev, irq_mask);
- 	mt7996_irq_disable(dev, 0);
- }
-@@ -270,17 +296,22 @@ static void 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
- 		 */
--		mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
--			 MT_WFDMA0_RX_INT_SEL_RING3);
--
--		/* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->rro_support)
-+			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
-+				 MT_WFDMA0_RX_INT_SEL_RING6);
-+		else
-+			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
-+				 MT_WFDMA0_RX_INT_SEL_RING3);
- 	}
- 
--	mt7996_dma_start(dev, reset);
-+	mt7996_dma_start(dev, reset, true);
- }
- 
- int mt7996_dma_init(struct mt7996_dev *dev)
- {
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
-+	u32 rx_base;
- 	u32 hif1_ofs = 0;
- 	int ret;
- 
-@@ -294,10 +325,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 	mt7996_dma_disable(dev, true);
- 
- 	/* init tx queue */
--	ret = mt76_connac_init_tx_queues(dev->phy.mt76,
--					 MT_TXQ_ID(dev->mphy.band_idx),
--					 MT7996_TX_RING_SIZE,
--					 MT_TXQ_RING_BASE(0), 0);
-+	ret = mt7996_init_tx_queues(&dev->phy,
-+				    MT_TXQ_ID(dev->mphy.band_idx),
-+				    MT7996_TX_RING_SIZE,
-+				    MT_TXQ_RING_BASE(0),
-+				    wed);
- 	if (ret)
- 		return ret;
- 
-@@ -353,6 +385,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		return ret;
- 
- 	/* tx free notify event from WA for band0 */
-+	if (mtk_wed_device_active(wed) && !dev->rro_support)
-+		dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
-+
- 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA],
- 			       MT_RXQ_ID(MT_RXQ_MAIN_WA),
- 			       MT7996_RX_MCU_RING_SIZE,
-@@ -363,17 +398,24 @@ 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;
-+		if (mtk_wed_device_active(wed))
-+			rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
-+
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
- 				       MT7996_RX_RING_SIZE,
- 				       MT_RX_BUF_SIZE,
--				       MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs);
-+				       rx_base);
- 		if (ret)
- 			return ret;
- 
- 		/* tx free notify event from WA for band2
- 		 * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
- 		 */
-+		if (mtk_wed_device_active(wed_ext) && !dev->rro_support)
-+			dev->mt76.q_rx[MT_RXQ_BAND2_WA].flags = MT_WED_Q_TXFREE |
-+								MT_QFLAG_WED_EXT;
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2_WA],
- 				       MT_RXQ_ID(MT_RXQ_BAND2_WA),
- 				       MT7996_RX_MCU_RING_SIZE,
-@@ -383,6 +425,56 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			return ret;
- 	}
- 
-+
-+	if (dev->rro_support) {
-+		/* rx rro data queue for band0 */
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags = MT_RRO_Q_DATA(0);
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_QFLAG_MAGIC;
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
-+				       MT_RXQ_ID(MT_RXQ_RRO_BAND0),
-+				       MT7996_RX_RING_SIZE,
-+				       MT7996_RX_BUF_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0));
-+		if (ret)
-+			return ret;
-+
-+		/* tx free notify event from WA for band0 */
-+		if (mtk_wed_device_active(wed))
-+			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
-+		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,
-+				       MT7996_RX_BUF_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
-+		if (ret)
-+			return ret;
-+
-+		if (mt7996_band_valid(dev, MT_BAND2)) {
-+			/* 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;
-+			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
-+					       MT_RXQ_ID(MT_RXQ_RRO_BAND2),
-+					       MT7996_RX_RING_SIZE,
-+					       MT7996_RX_BUF_SIZE,
-+					       MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND2) + hif1_ofs);
-+			if (ret)
-+				return ret;
-+
-+			/* tx free notify event from MAC for band2 */
-+			if (mtk_wed_device_active(wed_ext))
-+				dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].flags = MT_WED_Q_TXFREE |
-+									    MT_QFLAG_WED_EXT;
-+			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2],
-+					       MT_RXQ_ID(MT_RXQ_TXFREE_BAND2),
-+					       MT7996_RX_MCU_RING_SIZE,
-+					       MT7996_RX_BUF_SIZE,
-+					       MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND2) + hif1_ofs);
-+			if (ret)
-+				return ret;
-+		}
-+	}
-+
- 	ret = mt76_init_queues(dev, mt76_dma_rx_poll);
- 	if (ret < 0)
- 		return ret;
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 5d8ecf038..f2d43d3dc 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -540,6 +540,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	struct mt76_phy *mphy;
- 	u32 mac_ofs, hif1_ofs = 0;
- 	int ret;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
- 	if (!mt7996_band_valid(dev, band) || band == MT_BAND0)
- 		return 0;
-@@ -547,8 +548,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 	if (phy)
- 		return 0;
- 
--	if (band == MT_BAND2 && dev->hif2)
-+	if (band == MT_BAND2 && dev->hif2) {
- 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+		wed = &dev->mt76.mmio.wed_ext;
-+	}
- 
- 	mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);
- 	if (!mphy)
-@@ -582,10 +585,11 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
- 
- 	/* init wiphy according to mphy and phy */
- 	mt7996_init_wiphy(mphy->hw);
--	ret = mt76_connac_init_tx_queues(phy->mt76,
--					 MT_TXQ_ID(band),
--					 MT7996_TX_RING_SIZE,
--					 MT_TXQ_RING_BASE(band) + hif1_ofs, 0);
-+	ret = mt7996_init_tx_queues(mphy->priv,
-+				    MT_TXQ_ID(band),
-+				    MT7996_TX_RING_SIZE,
-+				    MT_TXQ_RING_BASE(band) + hif1_ofs,
-+				    wed);
- 	if (ret)
- 		goto error;
- 
-@@ -1126,6 +1130,13 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 
- 	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
- 
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
-+		mt76_wr(dev, MT_INT1_MASK_CSR,
-+			dev->mt76.mmio.irqmask|MT_INT_TX_DONE_BAND2);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
-+				     dev->mt76.mmio.irqmask |MT_INT_TX_DONE_BAND2);
-+	}
-+
- 	dev->recovery.hw_init_done = true;
- 
- 	ret = mt7996_init_debugfs(&dev->phy);
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 04e14fa30..e57bdee21 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1019,6 +1019,29 @@ out:
- 	mt76_put_txwi(mdev, t);
- }
- 
-+u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
-+{
-+	struct mt76_connac_fw_txp *txp = ptr + MT_TXD_SIZE;
-+	__le32 *txwi = ptr;
-+	u32 val;
-+
-+	memset(ptr, 0, MT_TXD_SIZE + sizeof(*txp));
-+
-+	val = FIELD_PREP(MT_TXD0_TX_BYTES, MT_TXD_SIZE) |
-+	      FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CT);
-+	txwi[0] = cpu_to_le32(val);
-+
-+	val = BIT(31) |
-+	      FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3);
-+	txwi[1] = cpu_to_le32(val);
-+
-+	txp->token = cpu_to_le16(token_id);
-+	txp->nbuf = 1;
-+	txp->buf[0] = cpu_to_le32(phys + MT_TXD_SIZE + sizeof(*txp));
-+
-+	return MT_TXD_SIZE + sizeof(*txp);
-+}
-+
- static void
- mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
- {
-@@ -1363,6 +1386,10 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 
- 	switch (type) {
- 	case PKT_TYPE_TXRX_NOTIFY:
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext) &&
-+		    q == MT_RXQ_TXFREE_BAND2)
-+		    return;
-+
- 		mt7996_mac_tx_free(dev, skb->data, skb->len);
- 		napi_consume_skb(skb, 1);
- 		break;
-@@ -1837,7 +1864,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
- 
- 	/* enable DMA Tx/Tx and interrupt */
--	mt7996_dma_start(dev, false);
-+	mt7996_dma_start(dev, false, false);
- 
- 	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	clear_bit(MT76_RESET, &dev->mphy.state);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index a00ebf9e6..e6be05656 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1508,6 +1508,49 @@ out:
- 	return ret;
- }
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static int
-+mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
-+			     struct ieee80211_vif *vif,
-+			     struct ieee80211_sta *sta,
-+			     struct net_device_path_ctx *ctx,
-+			     struct net_device_path *path)
-+{
-+	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
-+	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-+	struct mt7996_dev *dev = mt7996_hw_dev(hw);
-+	struct mt7996_phy *phy = mt7996_hw_phy(hw);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+
-+	if(phy != &dev->phy && phy->mt76->band_idx == MT_BAND2)
-+		wed = &dev->mt76.mmio.wed_ext;
-+
-+	if (!mtk_wed_device_active(wed))
-+		return -ENODEV;
-+
-+	if (msta->wcid.idx > MT7996_WTBL_STA)
-+		return -EIO;
-+
-+	path->type = DEV_PATH_MTK_WDMA;
-+	path->dev = ctx->dev;
-+	path->mtk_wdma.wdma_idx = wed->wdma_idx;
-+	path->mtk_wdma.bss = mvif->mt76.idx;
-+	path->mtk_wdma.queue = 0;
-+	path->mtk_wdma.wcid = msta->wcid.idx;
-+
-+	/* pao info */
-+	if (mtk_wed_device_support_pao(wed)) {
-+		path->mtk_wdma.amsdu_en = 1;
-+		path->mtk_wdma.is_sp = 0;
-+		path->mtk_wdma.is_fixedrate = 0;
-+	}
-+	ctx->dev = NULL;
-+
-+	return 0;
-+}
-+
-+#endif
-+
- const struct ieee80211_ops mt7996_ops = {
- 	.tx = mt7996_tx,
- 	.start = mt7996_start,
-@@ -1554,4 +1597,7 @@ const struct ieee80211_ops mt7996_ops = {
- 	.sta_add_debugfs = mt7996_sta_add_debugfs,
- #endif
- 	.set_radar_background = mt7996_set_radar_background,
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+	.net_fill_forward_path = mt7996_net_fill_forward_path,
-+#endif
- };
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index d5eaa1bcf..ad2482ef2 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -10,6 +10,11 @@
- #include "mt7996.h"
- #include "mac.h"
- #include "../trace.h"
-+#include "../dma.h"
-+
-+
-+static bool wed_enable = true;
-+module_param(wed_enable, bool, 0644);
- 
- static const struct __base mt7996_reg_base[] = {
- 	[WF_AGG_BASE]		= { { 0x820e2000, 0x820f2000, 0x830e2000 } },
-@@ -214,6 +219,228 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
- 	return val;
- }
- 
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+static void mt7996_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
-+{
-+	struct mt7996_dev *dev;
-+	struct page *page;
-+	int i;
-+
-+	dev = container_of(wed, struct mt7996_dev, mt76.mmio.wed);
-+	for (i = 0; i < dev->mt76.rx_token_size; i++) {
-+		struct mt76_rxwi_cache *r;
-+
-+		r = mt76_rx_token_release(&dev->mt76, i);
-+		if (!r || !r->ptr)
-+			continue;
-+
-+		dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
-+				 wed->wlan.rx_size, DMA_FROM_DEVICE);
-+		skb_free_frag(r->ptr);
-+		r->ptr = NULL;
-+
-+		mt76_put_rxwi(&dev->mt76, r);
-+	}
-+
-+	mt76_free_pending_rxwi(&dev->mt76);
-+
-+	mt76_for_each_q_rx(&dev->mt76, i) {
-+		struct mt76_queue *q = &dev->mt76.q_rx[i];
-+
-+		if (mt76_queue_is_wed_rx(q)) {
-+			if (!q->rx_page.va)
-+				continue;
-+
-+			page = virt_to_page(q->rx_page.va);
-+			__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
-+			memset(&q->rx_page, 0, sizeof(q->rx_page));
-+		}
-+	}
-+
-+	if (!wed->rx_buf_ring.rx_page.va)
-+		return;
-+
-+	page = virt_to_page(wed->rx_buf_ring.rx_page.va);
-+	__page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias);
-+	memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page));
-+
-+}
-+
-+static u32 mt7996_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
-+{
-+	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
-+	struct mt7996_dev *dev;
-+	u32 length;
-+	int i;
-+
-+	dev = container_of(wed, struct mt7996_dev, mt76.mmio.wed);
-+	length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
-+				sizeof(struct skb_shared_info));
-+
-+	for (i = 0; i < size; i++) {
-+		struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
-+		dma_addr_t phy_addr;
-+		int token;
-+		void *ptr;
-+
-+		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
-+				      GFP_KERNEL);
-+		if (!ptr) {
-+			mt76_put_rxwi(&dev->mt76, r);
-+			goto unmap;
-+		}
-+
-+		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);
-+			goto unmap;
-+		}
-+
-+		desc->buf0 = cpu_to_le32(phy_addr);
-+		token = mt76_rx_token_consume(&dev->mt76, ptr, r, phy_addr);
-+		if (token < 0) {
-+			dma_unmap_single(dev->mt76.dma_dev, phy_addr,
-+					 wed->wlan.rx_size, DMA_TO_DEVICE);
-+			skb_free_frag(ptr);
-+			mt76_put_rxwi(&dev->mt76, r);
-+			goto unmap;
-+		}
-+
-+		desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
-+						      token));
-+		desc++;
-+	}
-+
-+	return 0;
-+
-+unmap:
-+	mt7996_mmio_wed_release_rx_buf(wed);
-+	return -ENOMEM;
-+}
-+#endif
-+
-+int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-+			 bool hif2, int *irq)
-+{
-+#ifdef CONFIG_NET_MEDIATEK_SOC_WED
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct pci_dev *pci_dev = pdev_ptr;
-+	u32 hif1_ofs = 0;
-+	int ret;
-+
-+	if (!wed_enable)
-+		return 0;
-+
-+	dev->rro_support = true;
-+
-+	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	if (hif2)
-+		wed = &dev->mt76.mmio.wed_ext;
-+
-+	wed->wlan.pci_dev = pci_dev;
-+	wed->wlan.bus_type = MTK_WED_BUS_PCIE;
-+
-+	wed->wlan.base = devm_ioremap(dev->mt76.dev,
-+				      pci_resource_start(pci_dev, 0),
-+				      pci_resource_len(pci_dev, 0));
-+	wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
-+
-+	if (hif2) {
-+		wed->wlan.wpdma_int = wed->wlan.phy_base +
-+				      MT_INT_PCIE1_SOURCE_CSR_EXT;
-+		wed->wlan.wpdma_mask = wed->wlan.phy_base +
-+				       MT_INT_PCIE1_MASK_CSR;
-+		wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
-+					     MT_TXQ_RING_BASE(0) +
-+					     MT7996_TXQ_BAND2 * MT_RING_SIZE;
-+		if (dev->rro_support) {
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
-+						 MT_RXQ_RING_BASE(0) +
-+						 MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
-+		} else {
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
-+						 MT_RXQ_RING_BASE(0) +
-+						 MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
-+		}
-+
-+		wed->wlan.chip_id = 0x7991;
-+		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
-+	} else {
-+		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
-+		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
-+		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
-+				     MT7996_TXQ_BAND0 * MT_RING_SIZE;
-+
-+		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
-+
-+		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base +
-+					MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
-+					MT7996_RXQ_BAND0 * MT_RING_SIZE;
-+
-+		wed->wlan.rx_nbuf = 65536;
-+		wed->wlan.rx_npkt = 24576;
-+		wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
-+
-+		wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
-+		wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
-+
-+		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
-+		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
-+		if (dev->rro_support) {
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
-+						 MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
-+		} else {
-+			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
-+			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
-+						  MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
-+		}
-+	}
-+
-+	wed->wlan.nbuf = MT7996_TOKEN_SIZE;
-+
-+	wed->wlan.token_start = 0;
-+
-+	wed->wlan.max_amsdu_nums = 8;
-+	wed->wlan.max_amsdu_len = 1536;
-+
-+	wed->wlan.init_buf = mt7996_wed_init_buf;
-+	wed->wlan.offload_enable = NULL;
-+	wed->wlan.offload_disable = NULL;
-+	wed->wlan.init_rx_buf = mt7996_mmio_wed_init_rx_buf;
-+	wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
-+	wed->wlan.update_wo_rx_stats = NULL;
-+
-+	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
-+
-+	if (mtk_wed_device_attach(wed))
-+		return 0;
-+
-+	*irq = wed->irq;
-+	dev->mt76.dma_dev = wed->dev;
-+
-+	dev->mt76.token_size = MT7996_SW_TOKEN_SIZE;
-+
-+	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
-+	if (ret)
-+		return ret;
-+
-+	ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
-+	if (ret)
-+		return ret;
-+
-+	return 1;
-+#else
-+	return 0;
-+#endif
-+}
-+
- static int mt7996_mmio_init(struct mt76_dev *mdev,
- 			    void __iomem *mem_base,
- 			    u32 device_id)
-@@ -265,8 +492,17 @@ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
- 	mdev->mmio.irqmask |= set;
- 
- 	if (write_reg) {
--		mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
--		mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
-+		if (mtk_wed_device_active(&mdev->mmio.wed)) {
-+			mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
-+						    mdev->mmio.irqmask);
-+			if (mtk_wed_device_active(&mdev->mmio.wed_ext)) {
-+				mtk_wed_device_irq_set_mask(&mdev->mmio.wed_ext,
-+							    mdev->mmio.irqmask);
-+			}
-+		} else {
-+			mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
-+			mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
-+		}
- 	}
- 
- 	spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
-@@ -284,22 +520,36 @@ static void mt7996_rx_poll_complete(struct mt76_dev *mdev,
- static void mt7996_irq_tasklet(struct tasklet_struct *t)
- {
- 	struct mt7996_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
- 	u32 i, intr, mask, intr1;
- 
--	mt76_wr(dev, MT_INT_MASK_CSR, 0);
--	if (dev->hif2)
--		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
--
--	intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
--	intr &= dev->mt76.mmio.irqmask;
--	mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
--
--	if (dev->hif2) {
--		intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
--		intr1 &= dev->mt76.mmio.irqmask;
--		mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
-+	if (dev->hif2 && mtk_wed_device_active(wed_ext)) {
-+		mtk_wed_device_irq_set_mask(wed_ext, 0);
-+		intr1 = mtk_wed_device_irq_get(wed_ext,
-+					       dev->mt76.mmio.irqmask);
-+		if (intr1 & MT_INT_RX_TXFREE_EXT)
-+			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
-+	}
- 
--		intr |= intr1;
-+	if (mtk_wed_device_active(wed)) {
-+		mtk_wed_device_irq_set_mask(wed, 0);
-+		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
-+		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
-+	} else {
-+		mt76_wr(dev, MT_INT_MASK_CSR, 0);
-+		if (dev->hif2)
-+			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+
-+		intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
-+		intr &= dev->mt76.mmio.irqmask;
-+		mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
-+		if (dev->hif2) {
-+			intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
-+			intr1 &= dev->mt76.mmio.irqmask;
-+			mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
-+			intr |= intr1;
-+		}
- 	}
- 
- 	trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
-@@ -331,10 +581,19 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
- irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
- {
- 	struct mt7996_dev *dev = dev_instance;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
--	mt76_wr(dev, MT_INT_MASK_CSR, 0);
--	if (dev->hif2)
--		mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+	if (mtk_wed_device_active(wed))
-+		mtk_wed_device_irq_set_mask(wed, 0);
-+	else
-+		mt76_wr(dev, MT_INT_MASK_CSR, 0);
-+
-+	if (dev->hif2) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
-+			mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_ext, 0);
-+		else
-+			mt76_wr(dev, MT_INT1_MASK_CSR, 0);
-+	}
- 
- 	if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
- 		return IRQ_NONE;
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 6447b2c90..d09358305 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -40,6 +40,7 @@
- #define MT7996_EEPROM_SIZE		7680
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
-+#define MT7996_SW_TOKEN_SIZE		1024
- 
- #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
- #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
-@@ -493,7 +494,9 @@ 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);
-+int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
-+			  int n_desc, int ring_base, struct mtk_wed_device *wed);
-+void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset);
- void mt7996_init_txpower(struct mt7996_dev *dev,
- 			 struct ieee80211_supported_band *sband);
- int mt7996_txbf_init(struct mt7996_dev *dev);
-@@ -683,7 +686,9 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
- void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 			    struct ieee80211_sta *sta, struct dentry *dir);
- #endif
--
-+int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-+			 bool hif2, int *irq);
-+u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
- #ifdef CONFIG_MTK_VENDOR
- void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
- void mt7996_vendor_register(struct mt7996_phy *phy);
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index c5301050f..085408571 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -125,15 +125,22 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 	mt7996_wfsys_reset(dev);
- 	hif2 = mt7996_pci_init_hif2(pdev);
- 
--	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
-+	ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
- 	if (ret < 0)
--		goto free_device;
-+		goto free_wed_or_irq_vector;
-+
-+	if (!ret) {
-+		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
-+		if (ret < 0)
-+			goto free_device;
-+
-+		irq = pdev->irq;
-+	}
- 
--	irq = pdev->irq;
- 	ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
- 			       IRQF_SHARED, KBUILD_MODNAME, dev);
- 	if (ret)
--		goto free_irq_vector;
-+		goto free_wed_or_irq_vector;
- 
- 	mt76_wr(dev, MT_INT_MASK_CSR, 0);
- 	/* master switch of PCIe tnterrupt enable */
-@@ -143,11 +150,20 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 		hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
- 		dev->hif2 = hif2;
- 
--		ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
-+		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &irq);
- 		if (ret < 0)
--			goto free_hif2;
-+			goto free_wed_or_irq_vector;
-+
-+		if (!ret) {
-+			ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
-+			if (ret < 0)
-+				goto free_hif2;
-+
-+			dev->hif2->irq = hif2_dev->irq;
-+		} else {
-+			dev->hif2->irq = irq;
-+		}
- 
--		dev->hif2->irq = hif2_dev->irq;
- 		ret = devm_request_irq(mdev->dev, dev->hif2->irq,
- 				       mt7996_irq_handler, IRQF_SHARED,
- 				       KBUILD_MODNAME "-hif", dev);
-@@ -169,14 +185,22 @@ free_hif2_irq:
- 	if (dev->hif2)
- 		devm_free_irq(mdev->dev, dev->hif2->irq, dev);
- free_hif2_irq_vector:
--	if (dev->hif2)
--		pci_free_irq_vectors(hif2_dev);
-+	if (dev->hif2) {
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
-+			mtk_wed_device_detach(&dev->mt76.mmio.wed_ext);
-+		else
-+			pci_free_irq_vectors(hif2_dev);
-+	}
- free_hif2:
- 	if (dev->hif2)
- 		put_device(dev->hif2->dev);
- 	devm_free_irq(mdev->dev, irq, dev);
--free_irq_vector:
--	pci_free_irq_vectors(pdev);
-+free_wed_or_irq_vector:
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mtk_wed_device_detach(&dev->mt76.mmio.wed);
-+	else
-+		pci_free_irq_vectors(pdev);
-+
- free_device:
- 	mt76_free_device(&dev->mt76);
- 
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index e0b51b5df..ca7c2a811 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -330,6 +330,7 @@ enum base_rev {
- 
- #define MT_WFDMA0_RX_INT_PCIE_SEL		MT_WFDMA0(0x154)
- #define MT_WFDMA0_RX_INT_SEL_RING3		BIT(3)
-+#define MT_WFDMA0_RX_INT_SEL_RING6		BIT(6)
- 
- #define MT_WFDMA0_MCU_HOST_INT_ENA		MT_WFDMA0(0x1f4)
- 
-@@ -383,6 +384,9 @@ enum base_rev {
- #define MT_WFDMA0_PCIE1_BASE			0xd8000
- #define MT_WFDMA0_PCIE1(ofs)			(MT_WFDMA0_PCIE1_BASE + (ofs))
- 
-+#define MT_INT_PCIE1_SOURCE_CSR_EXT 		MT_WFDMA0_PCIE1(0x118)
-+#define MT_INT_PCIE1_MASK_CSR			MT_WFDMA0_PCIE1(0x11c)
-+
- #define MT_WFDMA0_PCIE1_BUSY_ENA		MT_WFDMA0_PCIE1(0x13c)
- #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0	BIT(0)
- #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1	BIT(1)
-@@ -428,6 +432,7 @@ enum base_rev {
- #define MT_INT_RX_TXFREE_MAIN			BIT(17)
- #define MT_INT_RX_TXFREE_TRI			BIT(15)
- #define MT_INT_MCU_CMD				BIT(29)
-+#define MT_INT_RX_TXFREE_EXT			BIT(26)
- 
- #define MT_INT_RX(q)				(dev->q_int_mask[__RXQ(q)])
- #define MT_INT_TX_MCU(q)			(dev->q_int_mask[(q)])
--- 
-2.39.2
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
new file mode 100644
index 0000000..d9fe625
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2004-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
@@ -0,0 +1,425 @@
+From d663fd304a7bd5701b2b3ac42b4743dabb252750 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 18 May 2023 15:01:47 +0800
+Subject: [PATCH 68/98] wifi: mt76: mt7996: reset addr_elem when delete ba
+
+The old addr element info may be used when the signature is not equel to
+0xff, and sta will find error SDP cause the SDP/SDL=0 issue.
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ mt76.h            |  1 +
+ mt76_connac_mcu.h |  1 +
+ mt7996/init.c     |  3 ++
+ mt7996/mac.c      | 97 +++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.c      | 77 +++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.h      | 46 ++++++++++++++++++++++
+ mt7996/mt7996.h   | 27 +++++++++++++
+ mt7996/regs.h     |  6 +++
+ 8 files changed, 258 insertions(+)
+
+diff --git a/mt76.h b/mt76.h
+index b960f3d..bea58ff 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -434,6 +434,7 @@ struct mt76_rx_tid {
+ 	u16 nframes;
+ 
+ 	u8 num;
++	u16 session_id;
+ 
+ 	u8 started:1, stopped:1, timer_pending:1;
+ 
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index e904ebc..f659d2e 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1038,6 +1038,7 @@ enum {
+ 	MCU_UNI_EVENT_THERMAL = 0x35,
+ 	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
+ 	MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
++	MCU_UNI_EVENT_RRO = 0x57,
+ 	MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
+ 	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
+ };
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 4503482..1f01f24 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -779,6 +779,9 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
+ 	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
+ 		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
+ 
++	INIT_WORK(&dev->wed_rro.rro_del_work, mt7996_rro_delete_sessions);
++	INIT_LIST_HEAD(&dev->wed_rro.rro_poll_list);
++
+ 	/* rro ind cmd queue init */
+ 	return mt7996_dma_rro_init(dev);
+ #else
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index b24f237..60ca23b 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1450,6 +1450,96 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 	}
+ }
+ 
++static struct mt7996_wed_rro_addr *
++mt7996_rro_get_addr_elem(struct mt7996_dev *dev, u16 seid, u16 sn)
++{
++	u32 idx;
++	void *addr;
++
++	if (seid == MT7996_RRO_MAX_SESSION) {
++		addr = dev->wed_rro.session.ptr;
++		idx = sn % MT7996_RRO_WINDOW_MAX_LEN;
++	} else {
++		addr = dev->wed_rro.addr_elem[seid / MT7996_RRO_BA_BITMAP_SESSION_SIZE].ptr;
++		idx = (seid % MT7996_RRO_BA_BITMAP_SESSION_SIZE) * MT7996_RRO_WINDOW_MAX_LEN
++			+ (sn % MT7996_RRO_WINDOW_MAX_LEN);
++	}
++	return addr + idx * sizeof(struct mt7996_wed_rro_addr);
++}
++
++static bool mt7996_rro_reset_sessions(struct mt7996_dev *dev, u16 session_id)
++{
++	struct  mt7996_wed_rro_addr *elem;
++	int i;
++
++	for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) {
++		elem = mt7996_rro_get_addr_elem(dev, session_id, i);
++		elem->signature = 0xff;
++	}
++	return true;
++
++}
++
++void  mt7996_rro_delete_sessions(struct work_struct *work)
++{
++	struct mt7996_dev *dev;
++	struct mt7996_rro_ba_session_elem *e;
++	int elem_nums;
++	LIST_HEAD(rro_poll_list);
++
++	dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,
++					       wed_rro.rro_del_work);
++	elem_nums = dev->wed_rro.elem_nums;
++
++	spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
++	list_splice_init(&dev->wed_rro.rro_poll_list, &rro_poll_list);
++	spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
++
++	do {
++		spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
++		if (list_empty(&rro_poll_list)) {
++			spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
++			break;
++		}
++
++		e = list_first_entry(&rro_poll_list,
++				     struct mt7996_rro_ba_session_elem,
++				     poll_list);
++		if (!e) {
++			spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
++			break;
++		}
++		list_del_init(&e->poll_list);
++		spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
++
++		if (mt7996_rro_reset_sessions(dev, e->session_id)) {
++			mt7996_mcu_reset_rro_sessions(dev, e->session_id);
++			kfree(e);
++			dev->wed_rro.elem_nums--;
++		}
++		elem_nums--;
++	} while (elem_nums);
++}
++
++int mt7996_rro_add_delete_elem(struct mt7996_dev *dev, u16 seid)
++{
++	struct mt7996_rro_ba_session_elem *e;
++
++	e = kzalloc(sizeof(*e), GFP_ATOMIC);
++	if (!e)
++		return -ENOMEM;
++
++	e->session_id = seid;
++
++	spin_lock_bh(&dev->wed_rro.rro_stbl_lock);
++	list_add_tail(&e->poll_list, &dev->wed_rro.rro_poll_list);
++	spin_unlock_bh(&dev->wed_rro.rro_stbl_lock);
++	dev->wed_rro.elem_nums++;
++
++	ieee80211_queue_work(mt76_hw(dev), &dev->wed_rro.rro_del_work);
++	return 0;
++}
++
+ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+@@ -1774,6 +1864,9 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
+ 	if (phy3)
+ 		ieee80211_stop_queues(phy3->mt76->hw);
+ 
++	if (dev->has_rro)
++		cancel_work_sync(&dev->wed_rro.rro_del_work);
++
+ 	cancel_delayed_work_sync(&dev->mphy.mac_work);
+ 	if (phy2)
+ 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
+@@ -1865,6 +1958,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ 	set_bit(MT76_RESET, &dev->mphy.state);
+ 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
+ 	wake_up(&dev->mt76.mcu.wait);
++
++	if (dev->has_rro)
++		cancel_work_sync(&dev->wed_rro.rro_del_work);
++
+ 	cancel_delayed_work_sync(&dev->mphy.mac_work);
+ 	if (phy2) {
+ 		set_bit(MT76_RESET, &phy2->mt76->state);
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 6589610..ce38a5e 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -538,6 +538,60 @@ mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rat
+ 	return 0;
+ }
+ 
++static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++	struct mt7996_mcu_rro_event *event;
++	struct mt7996_mcu_rro_ba *rro;
++	struct mt7996_mcu_rro_ba_del_chk_done *delba;
++	u16 len;
++
++	if (!dev->has_rro)
++		return;
++
++	event = (struct mt7996_mcu_rro_event *)skb->data;
++	skb_pull(skb, sizeof(struct mt7996_mcu_rxd) + 4);
++
++	switch (event->tag) {
++	case UNI_RRO_BA_SESSION_STATUS: {
++		len = sizeof(struct mt7996_mcu_rro_ba);
++		while (unlikely(len > skb->len) ? NULL : true) {
++			rro = (struct mt7996_mcu_rro_ba *)skb->data;
++			u16 idx = cpu_to_le16(rro->wlan_id);
++			struct mt76_rx_tid *tid;
++			struct mt76_wcid *wcid;
++
++			wcid = rcu_dereference(dev->mt76.wcid[idx]);
++			if (!wcid || !wcid->sta)
++				return;
++
++			tid = rcu_dereference(wcid->aggr[rro->tid]);
++			if (!tid)
++				return;
++			tid->session_id = cpu_to_le16(rro->session_id);
++			skb_pull(skb, len);
++		}
++		break;
++	}
++	case UNI_RRO_BA_SESSION_DEL_CHK_DONE: {
++		len = sizeof(struct mt7996_mcu_rro_ba_del_chk_done);
++		while (unlikely(len > skb->len) ? NULL : true) {
++			delba = (struct mt7996_mcu_rro_ba_del_chk_done *)skb->data;
++			u16 session_id = cpu_to_le16(delba->session_id);
++
++			mt7996_rro_add_delete_elem(dev, session_id);
++			skb_pull(skb, len);
++		}
++		break;
++	}
++
++	default:
++		dev_info(dev->mt76.dev, "%s: unknown rro event tag %d\n",
++			 __func__, event->tag);
++		break;
++	}
++
++}
++
+ static void
+ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ {
+@@ -663,6 +717,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ 		mt7996_tm_rf_test_event(dev, skb);
+ 		break;
+ #endif
++	case MCU_UNI_EVENT_RRO:
++		mt7996_mcu_rx_rro(dev, skb);
++		break;
+ 	default:
+ 		break;
+ 	}
+@@ -4615,6 +4672,26 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
+ 				 sizeof(req), true);
+ }
+ 
++int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid)
++{
++	struct {
++		/* fixed field */
++		u8 __rsv[4];
++
++		__le16 tag;
++		__le16 len;
++		__le16 session_id;
++		u8 pad[4];
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.session_id = cpu_to_le16(seid),
++	};
++
++	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO),
++				 &req, sizeof(req), true);
++}
++
+ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
+ {
+ 	struct mt7996_dev *dev = phy->dev;
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 666216a..0aa68f7 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -239,6 +239,50 @@ struct mt7996_mcu_all_sta_info_event {
+ 	};
+ } __packed;
+ 
++struct mt7996_mcu_rro_event {
++	struct mt7996_mcu_rxd rxd;
++
++	u8 __rsv1[4];
++
++	__le16 tag;
++	__le16 len;
++} __packed;
++
++struct mt7996_mcu_rro_ba {
++	__le16 tag;
++	__le16 len;
++
++	__le16 wlan_id;
++	u8 tid;
++	u8 __rsv1;
++	__le32 status;
++	__le16 session_id;
++	u8 __rsv2[2];
++} __packed;
++
++struct mt7996_mcu_rro_ba_del_chk_done {
++	__le16 tag;
++	__le16 len;
++
++	__le16 session_id;
++	u8 __rsv2[2];
++} __packed;
++
++enum  {
++	UNI_RRO_BA_SESSION_STATUS = 0,
++	UNI_RRO_BA_SESSION_TBL	= 1,
++	UNI_RRO_BA_SESSION_DEL_CHK_DONE = 2,
++	UNI_RRO_BA_SESSION_MAX_NUM
++};
++
++struct mt7996_mcu_rro_del_ba {
++	struct mt7996_mcu_rro_event event;
++
++	u8  wlan_idx;
++	u8  tid;
++	u8 __rsv2[2];
++};
++
+ enum mt7996_chan_mib_offs {
+ 	UNI_MIB_OBSS_AIRTIME = 26,
+ 	UNI_MIB_NON_WIFI_TIME = 27,
+@@ -840,6 +884,8 @@ enum {
+ 	UNI_RRO_GET_BA_SESSION_TABLE,
+ 	UNI_RRO_SET_BYPASS_MODE,
+ 	UNI_RRO_SET_TXFREE_PATH,
++	UNI_RRO_DEL_BA_SESSION,
++	UNI_RRO_SET_FLUSH_TIMEOUT
+ };
+ 
+ enum{
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index bba1364..af67c59 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -282,6 +282,26 @@ struct mt7996_wed_rro_addr {
+ 	u32 signature : 8;
+ };
+ 
++struct mt7996_rro_ba_session {
++	u32 ack_sn         :12;
++	u32 win_sz         :3;
++	u32 bn             :1;
++	u32 last_in_sn     :12;
++	u32 bc             :1;
++	u32 bd             :1;
++	u32 sat            :1;
++	u32 cn             :1;
++	u32 within_cnt     :12;
++	u32 to_sel         :3;
++	u32 rsv            :1;
++	u32 last_in_rxtime :12;
++};
++
++struct mt7996_rro_ba_session_elem {
++	struct list_head poll_list;
++	u16 session_id;
++};
++
+ struct mt7996_phy {
+ 	struct mt76_phy *mt76;
+ 	struct mt7996_dev *dev;
+@@ -418,6 +438,10 @@ struct mt7996_dev {
+ 			void *ptr;
+ 			dma_addr_t phy_addr;
+ 		} session;
++		struct work_struct rro_del_work;
++		spinlock_t rro_stbl_lock;
++		struct list_head rro_poll_list;
++		u16 elem_nums;
+ 	} wed_rro;
+ 
+ 	bool testmode_enable;
+@@ -653,6 +677,7 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
+ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
+ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
++int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid);
+ int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
+ int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
+@@ -757,6 +782,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ 			  struct ieee80211_sta *sta,
+ 			  struct mt76_tx_info *tx_info);
+ void mt7996_tx_token_put(struct mt7996_dev *dev);
++void  mt7996_rro_delete_sessions(struct work_struct *work);
++int mt7996_rro_add_delete_elem(struct mt7996_dev *dev, u16 seid);
+ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ 			 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 d305c25..38467d9 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -101,6 +101,12 @@ enum offs_rev {
+ #define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
+ #define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
+ 
++#define MT_RRO_DBG_RD_CTRL			MT_RRO_TOP(0xe0)
++#define MT_RRO_DBG_RD_ADDR			GENMASK(15, 0)
++#define MT_RRO_DBG_RD_EXEC			BIT(31)
++
++#define MT_RRO_DBG_RDAT_DW(_n)			MT_RRO_TOP(0xf0 + _n * 0x4)
++
+ #define MT_MCU_INT_EVENT			0x2108
+ #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
+ #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
deleted file mode 100644
index 2dc5574..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
+++ /dev/null
@@ -1,1535 +0,0 @@
-From c9cbe5b9cc6e0d17352814aafe6514a6623bbd12 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/2012] wifi: mt76: mt7996: wed: add wed3.0 rx support
-
-add hardware rro support, This is the preliminary patch for WED3.0 support.
-
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Change-Id: I7e113b1392bcf085ec02c8a44ffbb7cf7c3fa027
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c           | 197 +++++++++++++++++++++++++++++++++++++-----------
- dma.h           |  12 +++
- mac80211.c      |   1 +
- mt76.h          |  63 ++++++++++++++--
- mt7996/dma.c    | 161 ++++++++++++++++++++++++++++++++++-----
- mt7996/init.c   | 130 ++++++++++++++++++++++++++++++--
- mt7996/mac.c    |  42 +++++++++--
- mt7996/mcu.c    |   8 +-
- mt7996/mmio.c   |  44 +++++++++--
- mt7996/mt7996.h |  58 ++++++++++++++
- mt7996/pci.c    |   3 +-
- mt7996/regs.h   |  69 ++++++++++++++++-
- 12 files changed, 693 insertions(+), 95 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index c2dbe6f6b..8097a3121 100644
---- a/dma.c
-+++ b/dma.c
-@@ -198,46 +198,65 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
- static void
- mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
- {
-+	int ndesc = q->ndesc;
-+
-+	if (q->flags & MT_QFLAG_MAGIC)
-+		ndesc |= MT_DMA_MAGIC_EN;
-+
- 	Q_WRITE(dev, q, desc_base, q->desc_dma);
--	Q_WRITE(dev, q, ring_size, q->ndesc);
-+	Q_WRITE(dev, q, ring_size, ndesc);
- 	q->head = Q_READ(dev, q, dma_idx);
- 	q->tail = q->head;
- }
- 
- static void
--mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
-+mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, bool skip)
- {
- 	int i;
- 
- 	if (!q || !q->ndesc)
- 		return;
- 
-+	if (!q->desc)
-+		goto done;
-+
- 	/* clear descriptors */
- 	for (i = 0; i < q->ndesc; i++)
- 		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
- 
-+	if (skip)
-+		goto sync;
-+
-+done:
- 	Q_WRITE(dev, q, cpu_idx, 0);
- 	Q_WRITE(dev, q, dma_idx, 0);
-+sync:
- 	mt76_dma_sync_idx(dev, q);
- }
- 
- static int
- mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
--		    struct mt76_queue_buf *buf, void *data)
-+		    struct mt76_queue_buf *buf, void *data,
-+		    struct mt76_rxwi_cache *rxwi)
- {
--	struct mt76_desc *desc = &q->desc[q->head];
-+	struct mt76_desc *desc;
- 	struct mt76_queue_entry *entry = &q->entry[q->head];
--	struct mt76_rxwi_cache *rxwi = NULL;
- 	u32 buf1 = 0, ctrl;
- 	int idx = q->head;
- 	int rx_token;
- 
-+	if (mt76_queue_is_rro_ind(q))
-+		goto done;
-+
-+	desc = &q->desc[q->head];
- 	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
- 
- 	if (mt76_queue_is_wed_rx(q)) {
--		rxwi = mt76_get_rxwi(dev);
--		if (!rxwi)
--			return -ENOMEM;
-+		if (!rxwi) {
-+			rxwi = mt76_get_rxwi(dev);
-+			if (!rxwi)
-+				return -ENOMEM;
-+		}
- 
- 		rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
- 		if (rx_token < 0) {
-@@ -254,6 +273,7 @@ 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);
- 
-+done:
- 	entry->dma_addr[0] = buf->addr;
- 	entry->dma_len[0] = buf->len;
- 	entry->rxwi = rxwi;
-@@ -398,14 +418,15 @@ 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,
--		 int *len, u32 *info, bool *more, bool *drop)
-+		 int *len, u32 *info, bool *more, bool *drop, bool flush)
- {
- 	struct mt76_queue_entry *e = &q->entry[idx];
- 	struct mt76_desc *desc = &q->desc[idx];
- 	void *buf;
-+	u32 ctrl;
- 
-+	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);
- 	}
-@@ -413,6 +434,12 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 	if (info)
- 		*info = le32_to_cpu(desc->info);
- 
-+	if (drop) {
-+		*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
-+		if (ctrl & MT_DMA_CTL_VER_MASK)
-+			*drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
-+	}
-+
- 	if (mt76_queue_is_wed_rx(q)) {
- 		u32 buf1 = le32_to_cpu(desc->buf1);
- 		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
-@@ -425,20 +452,46 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 				 SKB_WITH_OVERHEAD(q->buf_size),
- 				 DMA_FROM_DEVICE);
- 
--		buf = r->ptr;
--		r->dma_addr = 0;
--		r->ptr = NULL;
--
--		mt76_put_rxwi(dev, r);
--
--		if (drop) {
--			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
--
--			*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
--					   MT_DMA_CTL_DROP));
-+		if (flush) {
-+			buf = r->ptr;
-+			r->dma_addr = 0;
-+			r->ptr = NULL;
-+
-+			mt76_put_rxwi(dev, r);
-+		} else {
-+			struct mt76_queue_buf qbuf;
-+
-+			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
-+			if (!buf)
-+				return NULL;
-+
-+			memcpy(buf, r->ptr, SKB_WITH_OVERHEAD(q->buf_size));
-+
-+			r->dma_addr = dma_map_single(dev->dma_dev, r->ptr,
-+						     SKB_WITH_OVERHEAD(q->buf_size),
-+						     DMA_FROM_DEVICE);
-+			if (unlikely(dma_mapping_error(dev->dma_dev, r->dma_addr))) {
-+				skb_free_frag(r->ptr);
-+				mt76_put_rxwi(dev, r);
-+				return NULL;
-+			}
-+
-+			qbuf.addr = r->dma_addr;
-+			qbuf.len = SKB_WITH_OVERHEAD(q->buf_size);
-+			qbuf.skip_unmap = false;
-+
-+			if (mt76_dma_add_rx_buf(dev, q, &qbuf, r->ptr, r) < 0) {
-+				dma_unmap_single(dev->dma_dev, r->dma_addr,
-+						 SKB_WITH_OVERHEAD(q->buf_size),
-+						 DMA_FROM_DEVICE);
-+				skb_free_frag(r->ptr);
-+				mt76_put_rxwi(dev, r);
-+				return NULL;
-+			}
-+		}
- 
-+		if (drop)
- 			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
--		}
- 	} else {
- 		buf = e->buf;
- 		e->buf = NULL;
-@@ -460,15 +513,20 @@ 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) {
-+		goto done;
-+	} else {
-+		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;
-+	}
- 
-+done:
- 	q->tail = (q->tail + 1) % q->ndesc;
- 	q->queued--;
- 
--	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
-+	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
- }
- 
- static int
-@@ -617,7 +675,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 
- 	while (q->queued < q->ndesc - 1) {
- 		struct mt76_queue_buf qbuf;
--		void *buf;
-+		void *buf = NULL;
-+
-+		if (mt76_queue_is_rro_ind(q))
-+			goto done;
- 
- 		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
- 		if (!buf)
-@@ -629,10 +690,11 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 			break;
- 		}
- 
-+done:
- 		qbuf.addr = addr + offset;
- 		qbuf.len = len - offset;
- 		qbuf.skip_unmap = false;
--		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
-+		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf, NULL) < 0) {
- 			dma_unmap_single(dev->dma_dev, addr, len,
- 					 DMA_FROM_DEVICE);
- 			skb_free_frag(buf);
-@@ -641,7 +703,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 		frames++;
- 	}
- 
--	if (frames)
-+	if (frames || mt76_queue_is_wed_rx(q))
- 		mt76_dma_kick_queue(dev, q);
- 
- 	spin_unlock_bh(&q->lock);
-@@ -654,7 +716,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;
--	u8 flags;
-+	u16 flags;
- 
- 	if (!q || !q->ndesc)
- 		return -EINVAL;
-@@ -681,7 +743,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;
--		mt76_dma_queue_reset(dev, q);
-+		mt76_dma_queue_reset(dev, q, false);
- 		mt76_dma_rx_fill(dev, q);
- 		q->flags = flags;
- 
-@@ -690,9 +752,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:
--		ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
--		if (!ret)
--			q->wed_regs = wed->rx_ring[ring].reg_base;
-+		if (q->flags & MT_QFLAG_RRO) {
-+			q->flags &= ~0x1f;
-+
-+			ring = FIELD_GET(MT_QFLAG_RRO_RING, q->flags);
-+			type = FIELD_GET(MT_QFLAG_RRO_TYPE, q->flags);
-+			if (type == MT76_RRO_Q_DATA) {
-+				mt76_dma_queue_reset(dev, q, true);
-+				ret = mtk_wed_device_rro_rx_ring_setup(wed, ring, q->regs);
-+			} else if (type == MT76_RRO_Q_MSDU_PG) {
-+				mt76_dma_queue_reset(dev, q, true);
-+				ret = mtk_wed_device_msdu_pg_rx_ring_setup(wed, ring, q->regs);
-+			} else if (type == MT76_RRO_Q_IND) {
-+				mt76_dma_queue_reset(dev, q, false);
-+				mt76_dma_rx_fill(dev, q);
-+				ret = mtk_wed_device_ind_rx_ring_setup(wed, q->regs);
-+			}
-+			if (type != MT76_RRO_Q_IND) {
-+				q->head = q->ndesc - 1;
-+				q->queued = q->ndesc - 1;
-+			}
-+		} else {
-+			ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, 0);
-+			if (!ret)
-+				q->wed_regs = wed->rx_ring[ring].reg_base;
-+		}
- 		break;
- 	default:
- 		ret = -EINVAL;
-@@ -721,10 +805,25 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	q->hw_idx = idx;
- 
- 	size = q->ndesc * sizeof(struct mt76_desc);
-+	if (mt76_queue_is_rro_ind(q))
-+		size = q->ndesc * sizeof(struct mt76_rro_desc);
-+
- 	q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
- 	if (!q->desc)
- 		return -ENOMEM;
- 
-+	if (mt76_queue_is_rro_ind(q)) {
-+		struct mt76_rro_ind *cmd;
-+		int i;
-+
-+		q->rro_desc = (struct mt76_rro_desc *)(q->desc);
-+		q->desc = NULL;
-+		for (i = 0; i < q->ndesc; i++) {
-+			cmd = (struct mt76_rro_ind *) &q->rro_desc[i];
-+			cmd->magic_cnt = MT_DMA_IND_CMD_MAGIC_CNT - 1;
-+		}
-+	}
-+
- 	size = q->ndesc * sizeof(*q->entry);
- 	q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
- 	if (!q->entry)
-@@ -734,8 +833,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
- 	if (ret)
- 		return ret;
- 
--	if (!mt76_queue_is_txfree(q))
--		mt76_dma_queue_reset(dev, q);
-+	if (!mtk_wed_device_active(&dev->mmio.wed) ||
-+	    (!mt76_queue_is_wed_txfree(q) &&
-+	     !(mtk_wed_get_rx_capa(&dev->mmio.wed) &&
-+	       q->flags & MT_QFLAG_RRO)))
-+		mt76_dma_queue_reset(dev, q, false);
- 
- 	return 0;
- }
-@@ -753,13 +855,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);
- 
-@@ -770,8 +872,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
- 
- 	spin_unlock_bh(&q->lock);
- 
--	if (((q->flags & MT_QFLAG_WED) &&
--	     FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) ||
-+	if (mt76_queue_is_wed_rx(q) ||
- 	    (q->flags & MT_QFLAG_RRO))
- 		return;
- 
-@@ -792,9 +893,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
- 	if (!q->ndesc)
- 		return;
- 
-+	if (!q->desc)
-+		goto done;
-+
- 	for (i = 0; i < q->ndesc; i++)
- 		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
- 
-+done:
- 	mt76_dma_rx_cleanup(dev, q);
- 
- 	/* reset WED rx queues */
-@@ -841,8 +946,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
- 	bool check_ddone = false;
- 	bool more;
- 
--	if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
--	    q->flags == MT_WED_Q_TXFREE) {
-+	if ((IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
-+	     q->flags == MT_WED_Q_TXFREE)) {
- 		dma_idx = Q_READ(dev, q, dma_idx);
- 		check_ddone = true;
- 	}
-@@ -1004,7 +1109,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
- 	mt76_for_each_q_rx(dev, i) {
- 		struct mt76_queue *q = &dev->q_rx[i];
- 
--		if (mt76_queue_is_wed_rx(q))
-+		if (mtk_wed_device_active(&dev->mmio.wed) &&
-+		    (q->flags & MT_QFLAG_RRO))
- 			continue;
- 
- 		netif_napi_del(&dev->napi[i]);
-@@ -1016,6 +1122,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);
-+
- 	mt76_free_pending_txwi(dev);
- 	mt76_free_pending_rxwi(dev);
- }
-diff --git a/dma.h b/dma.h
-index 1b090d78c..480370928 100644
---- a/dma.h
-+++ b/dma.h
-@@ -25,6 +25,13 @@
- #define MT_DMA_PPE_ENTRY		GENMASK(30, 16)
- #define MT_DMA_INFO_PPE_VLD		BIT(31)
- 
-+#define MT_DMA_CTL_PN_CHK_FAIL		BIT(13)
-+#define MT_DMA_CTL_VER_MASK		BIT(7)
-+
-+#define MT_DMA_MAGIC_EN		BIT(13)
-+
-+#define MT_DMA_IND_CMD_MAGIC_CNT	8
-+
- #define MT_DMA_HDR_LEN			4
- #define MT_RX_INFO_LEN			4
- #define MT_FCE_INFO_LEN			4
-@@ -37,6 +44,11 @@ struct mt76_desc {
- 	__le32 info;
- } __packed __aligned(4);
- 
-+struct mt76_rro_desc {
-+	__le32 buf0;
-+	__le32 buf1;
-+} __packed __aligned(4);
-+
- enum mt76_qsel {
- 	MT_QSEL_MGMT,
- 	MT_QSEL_HCCA,
-diff --git a/mac80211.c b/mac80211.c
-index 7cd9b6fc7..3070321d5 100644
---- a/mac80211.c
-+++ b/mac80211.c
-@@ -735,6 +735,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
- 			return;
- 		}
- 	}
-+
- 	__skb_queue_tail(&dev->rx_skb[q], skb);
- }
- 
-diff --git a/mt76.h b/mt76.h
-index 3b2a658db..3954d01c5 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -48,6 +48,18 @@
- 
- #define MT76_TOKEN_FREE_THR	64
- 
-+#define MT_QFLAG_RRO_RING	GENMASK(6, 5)
-+#define MT_QFLAG_RRO_TYPE	GENMASK(8, 7)
-+#define MT_QFLAG_RRO		BIT(9)
-+#define MT_QFLAG_MAGIC		BIT(10)
-+
-+#define __MT_RRO_Q(_type, _n)	(MT_QFLAG_RRO | \
-+				 FIELD_PREP(MT_QFLAG_RRO_TYPE, _type) | \
-+				 FIELD_PREP(MT_QFLAG_RRO_RING, _n))
-+#define MT_RRO_Q_DATA(_n)	__MT_RRO_Q(MT76_RRO_Q_DATA, _n)
-+#define MT_RRO_Q_MSDU_PG(_n)	__MT_RRO_Q(MT76_RRO_Q_MSDU_PG, _n)
-+#define MT_RRO_Q_IND		__MT_RRO_Q(MT76_RRO_Q_IND, 0)
-+
- #define MT_QFLAG_WED_RING	GENMASK(1, 0)
- #define MT_QFLAG_WED_TYPE	GENMASK(3, 2)
- #define MT_QFLAG_WED		BIT(4)
-@@ -82,6 +94,12 @@ enum mt76_wed_type {
- 	MT76_WED_Q_RX,
- };
- 
-+enum mt76_RRO_type {
-+	MT76_RRO_Q_DATA,
-+	MT76_RRO_Q_MSDU_PG,
-+	MT76_RRO_Q_IND,
-+};
-+
- struct mt76_bus_ops {
- 	u32 (*rr)(struct mt76_dev *dev, u32 offset);
- 	void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
-@@ -128,6 +146,16 @@ enum mt76_rxq_id {
- 	MT_RXQ_MAIN_WA,
- 	MT_RXQ_BAND2,
- 	MT_RXQ_BAND2_WA,
-+	MT_RXQ_RRO_BAND0,
-+	MT_RXQ_RRO_BAND1,
-+	MT_RXQ_RRO_BAND2,
-+	MT_RXQ_MSDU_PAGE_BAND0,
-+	MT_RXQ_MSDU_PAGE_BAND1,
-+	MT_RXQ_MSDU_PAGE_BAND2,
-+	MT_RXQ_TXFREE_BAND0,
-+	MT_RXQ_TXFREE_BAND1,
-+	MT_RXQ_TXFREE_BAND2,
-+	MT_RXQ_RRO_IND,
- 	__MT_RXQ_MAX
- };
- 
-@@ -206,6 +234,7 @@ struct mt76_queue {
- 	spinlock_t lock;
- 	spinlock_t cleanup_lock;
- 	struct mt76_queue_entry *entry;
-+	struct mt76_rro_desc *rro_desc;
- 	struct mt76_desc *desc;
- 
- 	u16 first;
-@@ -219,8 +248,8 @@ struct mt76_queue {
- 
- 	u8 buf_offset;
- 	u8 hw_idx;
--	u8 flags;
--
-+	u8 magic_cnt;
-+	u32 flags;
- 	u32 wed_regs;
- 
- 	dma_addr_t desc_dma;
-@@ -274,7 +303,7 @@ struct mt76_queue_ops {
- 
- 	void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
- 
--	void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
-+	void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q, bool skip);
- };
- 
- enum mt76_phy_type {
-@@ -375,6 +404,17 @@ struct mt76_txq {
- 	bool aggr;
- };
- 
-+struct mt76_rro_ind {
-+	u32 se_id	: 12;
-+	u32 rsv		: 4;
-+	u32 start_sn	: 12;
-+	u32 ind_reason	: 4;
-+	u32 ind_cnt	: 13;
-+	u32 win_sz	: 3;
-+	u32 rsv2	: 13;
-+	u32 magic_cnt	: 3;
-+};
-+
- struct mt76_txwi_cache {
- 	struct list_head list;
- 	dma_addr_t dma_addr;
-@@ -1629,12 +1669,19 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
- 	return (q->flags & MT_QFLAG_WED) &&
- 	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
- }
--static inline bool mt76_queue_is_txfree(struct mt76_queue *q)
-+
-+static inline bool mt76_queue_is_wed_txfree(struct mt76_queue *q)
- {
- 	return (q->flags & MT_QFLAG_WED) &&
- 	       FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
- }
- 
-+static inline bool mt76_queue_is_rro_ind(struct mt76_queue *q)
-+{
-+	return (q->flags & MT_QFLAG_RRO) &&
-+	       FIELD_GET(MT_QFLAG_RRO_TYPE, q->flags) == MT76_RRO_Q_IND;
-+}
-+
- 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);
-@@ -1653,10 +1700,14 @@ static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
- static inline int
- mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
- {
--	int token;
-+	int token, start = 0;
-+
-+	if (mtk_wed_device_active(&dev->mmio.wed))
-+		start = dev->mmio.wed.wlan.nbuf;
- 
- 	spin_lock_bh(&dev->token_lock);
--	token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
-+	token = idr_alloc(&dev->token, *ptxwi, start, start + dev->token_size,
-+			  GFP_ATOMIC);
- 	spin_unlock_bh(&dev->token_lock);
- 
- 	return token;
-diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 3c8f617e0..309cc242e 100644
---- a/mt7996/dma.c
-+++ b/mt7996/dma.c
-@@ -64,6 +64,29 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
- 	RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
- 	RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
- 
-+	if (dev->rro_support) {
-+		/* band0 */
-+		RXQ_CONFIG(MT_RXQ_RRO_BAND0, WFDMA0, MT_INT_RX_DONE_RRO_BAND0,
-+			   MT7996_RXQ_RRO_BAND0);
-+		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
-+			   MT7996_RXQ_MSDU_PG_BAND0);
-+		RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
-+			   MT7996_RXQ_TXFREE0);
-+		/* band1 */
-+		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
-+			   MT7996_RXQ_MSDU_PG_BAND1);
-+		/* band2 */
-+		RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
-+			   MT7996_RXQ_RRO_BAND2);
-+		RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
-+			   MT7996_RXQ_MSDU_PG_BAND2);
-+		RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
-+			   MT7996_RXQ_TXFREE2);
-+
-+		RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
-+			   MT7996_RXQ_RRO_IND);
-+	}
-+
- 	/* 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);
-@@ -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(0x10));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
-+			PREFETCH(0x10));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
-+			PREFETCH(0x4));
-+		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
-+			PREFETCH(0x4));
-+	}
- #undef PREFETCH
- 
- 	mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
-@@ -161,6 +200,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
- 
- void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
- {
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 	u32 hif1_ofs = 0;
- 	u32 irq_mask;
- 
-@@ -169,11 +209,16 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
- 
- 	/* 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 (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
-+			mt76_set(dev, MT_WFDMA0_GLO_CFG,
-+				 MT_WFDMA0_GLO_CFG_TX_DMA_EN |
-+				 MT_WFDMA0_GLO_CFG_OMIT_TX_INFO);
-+		else
-+			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,
-@@ -195,14 +240,14 @@ void mt7996_dma_start(struct mt7996_dev *dev, bool reset, bool wed_reset)
- 	if (mt7996_band_valid(dev, MT_BAND2))
- 		irq_mask |= MT_INT_BAND2_RX_DONE;
- 
--	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
-+	if (mtk_wed_device_active(wed) && wed_reset) {
- 		u32 wed_irq_mask = irq_mask;
- 
- 		wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
- 
- 		mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
- 
--		mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
-+		mtk_wed_device_start(wed, wed_irq_mask);
- 	}
- 
- 	irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
-@@ -296,7 +341,8 @@ static void 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
- 		 */
--		if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->rro_support)
-+		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    dev->rro_support)
- 			mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
- 				 MT_WFDMA0_RX_INT_SEL_RING6);
- 		else
-@@ -307,6 +353,78 @@ static void mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
- 	mt7996_dma_start(dev, reset, true);
- }
- 
-+int mt7996_dma_rro_init(struct mt7996_dev *dev)
-+{
-+	int ret;
-+	u32 hif1_ofs = 0;
-+	u32 wed_irq_mask;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+
-+	if (dev->hif2)
-+		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+
-+	/* ind cmd */
-+	dev->mt76.q_rx[MT_RXQ_RRO_IND].flags = MT_RRO_Q_IND | MT_WED_Q_RX(0);
-+	dev->mt76.q_rx[MT_RXQ_RRO_IND].flags |= MT_WED_Q_RX(0);
-+	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_IND],
-+			       MT_RXQ_ID(MT_RXQ_RRO_IND),
-+			       MT7996_RX_RING_SIZE,
-+			       0, MT_RXQ_RRO_IND_RING_BASE);
-+	if (ret)
-+		return ret;
-+
-+	/* rx msdu page queue for band0 */
-+	dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags = MT_RRO_Q_MSDU_PG(0);
-+	dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags |= MT_QFLAG_MAGIC;
-+	dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags |= MT_WED_Q_RX(0);
-+	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0],
-+			       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),
-+			       MT7996_RX_RING_SIZE,
-+			       MT7996_RX_MSDU_PAGE_SIZE,
-+			       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));
-+	if (ret)
-+		return ret;
-+
-+	if (mt7996_band_valid(dev, MT_BAND1)) {
-+		/* rx msdu page queue for band1 */
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags = MT_RRO_Q_MSDU_PG(1);
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags |= MT_QFLAG_MAGIC;
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags |= MT_WED_Q_RX(1);
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1],
-+				       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),
-+				       MT7996_RX_RING_SIZE,
-+				       MT7996_RX_MSDU_PAGE_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));
-+		if (ret)
-+			return ret;
-+	}
-+
-+	if (mt7996_band_valid(dev, MT_BAND2)) {
-+		/* rx msdu page queue for band2 */
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags = MT_RRO_Q_MSDU_PG(2);
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags |= MT_QFLAG_MAGIC;
-+		dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags |= MT_WED_Q_RX(0);
-+		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2],
-+				       MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),
-+				       MT7996_RX_RING_SIZE,
-+				       MT7996_RX_MSDU_PAGE_SIZE,
-+				       MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));
-+		if (ret)
-+			return ret;
-+	}
-+
-+	wed_irq_mask = dev->mt76.mmio.irqmask |
-+		       MT_INT_RRO_RX_DONE |
-+		       MT_INT_TX_DONE_BAND2;
-+
-+	mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
-+
-+	mtk_wed_device_start_hwrro(wed, wed_irq_mask, false);
-+	mt7996_irq_enable(dev, wed_irq_mask);
-+
-+	return 0;
-+}
-+
- int mt7996_dma_init(struct mt7996_dev *dev)
- {
- 	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-@@ -376,6 +494,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 		return ret;
- 
- 	/* rx data queue for band0 and band1 */
-+	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
-+		dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
-+
- 	ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
- 			       MT_RXQ_ID(MT_RXQ_MAIN),
- 			       MT7996_RX_RING_SIZE,
-@@ -399,8 +520,9 @@ 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;
--		if (mtk_wed_device_active(wed))
--			rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
-+		if (mtk_wed_device_active(wed_ext) && mtk_wed_get_rx_capa(wed_ext))
-+			dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(0) |
-+							     MT_QFLAG_WED_EXT;
- 
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
- 				       MT_RXQ_ID(MT_RXQ_BAND2),
-@@ -425,11 +547,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			return ret;
- 	}
- 
--
--	if (dev->rro_support) {
-+	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
-+	    dev->rro_support) {
- 		/* rx rro data queue for band0 */
- 		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags = MT_RRO_Q_DATA(0);
- 		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_QFLAG_MAGIC;
-+		dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_WED_Q_RX(0);
- 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
- 				       MT_RXQ_ID(MT_RXQ_RRO_BAND0),
- 				       MT7996_RX_RING_SIZE,
-@@ -439,8 +562,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
- 			return ret;
- 
- 		/* tx free notify event from WA for band0 */
--		if (mtk_wed_device_active(wed))
--			dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
-+		dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
- 		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,
-@@ -453,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;
-+			dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_WED_Q_RX(1);
- 			ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
- 					       MT_RXQ_ID(MT_RXQ_RRO_BAND2),
- 					       MT7996_RX_RING_SIZE,
-@@ -530,18 +653,18 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
- 
- 	/* reset hw queues */
- 	for (i = 0; i < __MT_TXQ_MAX; i++) {
--		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
-+		mt76_queue_reset(dev, dev->mphy.q_tx[i], false);
- 		if (phy2)
--			mt76_queue_reset(dev, phy2->q_tx[i]);
-+			mt76_queue_reset(dev, phy2->q_tx[i], false);
- 		if (phy3)
--			mt76_queue_reset(dev, phy3->q_tx[i]);
-+			mt76_queue_reset(dev, phy3->q_tx[i], false);
- 	}
- 
- 	for (i = 0; i < __MT_MCUQ_MAX; i++)
--		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
-+		mt76_queue_reset(dev, dev->mt76.q_mcu[i], false);
- 
- 	mt76_for_each_q_rx(&dev->mt76, i) {
--		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
-+		mt76_queue_reset(dev, &dev->mt76.q_rx[i], false);
- 	}
- 
- 	mt76_tx_status_check(&dev->mt76, true);
-diff --git a/mt7996/init.c b/mt7996/init.c
-index f2d43d3dc..3a749475e 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -502,8 +502,13 @@ void mt7996_mac_init(struct mt7996_dev *dev)
- 
- 	/* rro module init */
- 	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
--	mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
--	mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
-+	if (dev->rro_support) {
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
-+	} else {
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
-+		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
-+	}
- 
- 	mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
- 			  MCU_WA_PARAM_HW_PATH_HIF_VER,
-@@ -656,6 +661,114 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
- 	msleep(20);
- }
- 
-+static int mt7996_rro_init(struct mt7996_dev *dev)
-+{
-+	struct mt7996_rro_addr *ptr;
-+	struct mt7996_rro_cfg *rro = &dev->rro;
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	u32 size, val = 0, reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
-+	int i, j;
-+	void *buf;
-+
-+	for (i = 0; i < MT7996_RRO_BA_BITMAP_CR_CNT; i++) {
-+		buf = dmam_alloc_coherent(dev->mt76.dma_dev,
-+					  MT7996_BA_BITMAP_SZ_PER_CR,
-+					  &rro->ba_bitmap_cache_pa[i],
-+					  GFP_KERNEL);
-+		if (!buf)
-+			return -ENOMEM;
-+
-+		rro->ba_bitmap_cache_va[i] = buf;
-+	}
-+
-+	rro->win_sz = MT7996_RRO_WIN_SIZE_MAX;
-+	for (i = 0; i < MT7996_RRO_ADDR_ELEM_CR_CNT; i++) {
-+		size = MT7996_RRO_SESSION_PER_CR *
-+		       rro->win_sz * sizeof(struct mt7996_rro_addr);
-+
-+		buf = dmam_alloc_coherent(dev->mt76.dma_dev, size,
-+					  &rro->addr_elem_alloc_pa[i],
-+					  GFP_KERNEL);
-+		if (!buf)
-+			return -ENOMEM;
-+		rro->addr_elem_alloc_va[i] = buf;
-+
-+		memset(rro->addr_elem_alloc_va[i], 0, size);
-+
-+		ptr = rro->addr_elem_alloc_va[i];
-+		for (j = 0; j < MT7996_RRO_SESSION_PER_CR * rro->win_sz; j++, ptr++)
-+			ptr->signature = 0xff;
-+
-+		wed->wlan.ind_cmd.addr_elem_phys[i] = rro->addr_elem_alloc_pa[i];
-+	}
-+
-+	rro->particular_se_id = MT7996_RRO_SESSION_MAX;
-+	size = rro->win_sz * sizeof(struct mt7996_rro_addr);
-+	buf = dmam_alloc_coherent(dev->mt76.dma_dev, size,
-+				  &rro->particular_session_pa,
-+				  GFP_KERNEL);
-+	if (!buf)
-+		return -ENOMEM;
-+
-+	rro->particular_session_va = buf;
-+	ptr = rro->particular_session_va;
-+	for (j = 0; j < rro->win_sz; j++, ptr++)
-+		ptr->signature = 0xff;
-+
-+	INIT_LIST_HEAD(&rro->pg_addr_cache);
-+	for (i = 0; i < MT7996_RRO_MSDU_PG_HASH_SIZE; i++)
-+		INIT_LIST_HEAD(&rro->pg_hash_head[i]);
-+
-+	/* rro hw init */
-+	/* TODO: remove line after WM has set */
-+	mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
-+
-+	/* setup BA bitmap cache address */
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
-+		rro->ba_bitmap_cache_pa[0]);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
-+		rro->ba_bitmap_cache_pa[1]);
-+	mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
-+
-+	/* setup Address element address */
-+	for (i = 0; i < MT7996_RRO_ADDR_ELEM_CR_CNT; i++) {
-+		mt76_wr(dev, reg, rro->addr_elem_alloc_pa[i] >> 4);
-+		reg += 4;
-+	}
-+
-+	/* setup Address element address - separate address segment mode */
-+	mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
-+		MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
-+
-+	wed->wlan.ind_cmd.win_size = ffs(rro->win_sz) - 6;
-+	wed->wlan.ind_cmd.particular_sid = rro->particular_se_id;
-+	wed->wlan.ind_cmd.particular_se_phys = rro->particular_session_pa;
-+	wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_CR_CNT;
-+	wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
-+
-+	mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
-+	mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
-+		 MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
-+
-+	/* particular session configure */
-+	/* use max session idx + 1 as particular session id */
-+	mt76_wr(dev, MT_RRO_PARTICULAR_CFG0,
-+		rro->particular_session_pa);
-+
-+	val = FIELD_PREP(MT_RRO_PARTICULAR_SID,
-+			 MT7996_RRO_SESSION_MAX);
-+	val |= MT_RRO_PARTICULAR_CONFG_EN;
-+	mt76_wr(dev, MT_RRO_PARTICULAR_CFG1, val);
-+
-+	/* interrupt enable */
-+	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
-+		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
-+
-+	/* rro ind cmd queue init */
-+	return mt7996_dma_rro_init(dev);
-+}
-+
- static int mt7996_init_hardware(struct mt7996_dev *dev)
- {
- 	int ret, idx;
-@@ -687,6 +800,13 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
- 	if (ret)
- 		return ret;
- 
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+	    dev->rro_support) {
-+		ret = mt7996_rro_init(dev);
-+		if (ret)
-+			return ret;
-+	}
-+
- 	ret = mt7996_eeprom_init(dev);
- 	if (ret < 0)
- 		return ret;
-@@ -1131,10 +1251,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
- 	ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
- 
- 	if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
--		mt76_wr(dev, MT_INT1_MASK_CSR,
--			dev->mt76.mmio.irqmask|MT_INT_TX_DONE_BAND2);
-+		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR,
-+			MT_INT_TRX_DONE_EXT);
- 		mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
--				     dev->mt76.mmio.irqmask |MT_INT_TX_DONE_BAND2);
-+				     MT_INT_TRX_DONE_EXT);
- 	}
- 
- 	dev->recovery.hw_init_done = true;
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index e57bdee21..08a32195b 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -393,8 +393,37 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
- 	return 0;
- }
- 
-+static void
-+mt7996_wed_check_ppe(struct mt7996_dev *dev, struct mt76_queue *q,
-+		     struct mt7996_sta *msta, struct sk_buff *skb,
-+		     u32 info)
-+{
-+	struct ieee80211_vif *vif;
-+	struct wireless_dev *wdev;
-+
-+	if (!msta || !msta->vif)
-+		return;
-+
-+	if (!mt76_queue_is_wed_rx(q))
-+		return;
-+
-+	if (!(info & MT_DMA_INFO_PPE_VLD))
-+		return;
-+
-+	vif = container_of((void *)msta->vif, struct ieee80211_vif,
-+			   drv_priv);
-+	wdev = ieee80211_vif_to_wdev(vif);
-+	skb->dev = wdev->netdev;
-+
-+	mtk_wed_device_ppe_check(&dev->mt76.mmio.wed, skb,
-+				 FIELD_GET(MT_DMA_PPE_CPU_REASON, info),
-+				 FIELD_GET(MT_DMA_PPE_ENTRY, info));
-+}
-+
-+
- static int
--mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
-+mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
-+		   struct sk_buff *skb, u32 *info)
- {
- 	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
- 	struct mt76_phy *mphy = &dev->mt76.phy;
-@@ -419,7 +448,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- 	u16 seq_ctrl = 0;
- 	__le16 fc = 0;
- 	int idx;
-+	u8 hw_aggr = false;
-+	struct mt7996_sta *msta = NULL;
- 
-+	hw_aggr = status->aggr;
- 	memset(status, 0, sizeof(*status));
- 
- 	band_idx = FIELD_GET(MT_RXD1_NORMAL_BAND_IDX, rxd1);
-@@ -446,8 +478,6 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- 	status->wcid = mt7996_rx_get_wcid(dev, idx, unicast);
- 
- 	if (status->wcid) {
--		struct mt7996_sta *msta;
--
- 		msta = container_of(status->wcid, struct mt7996_sta, wcid);
- 		spin_lock_bh(&dev->mt76.sta_poll_lock);
- 		if (list_empty(&msta->wcid.poll_list))
-@@ -656,13 +686,15 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
- #endif
- 	} else {
- 		status->flag |= RX_FLAG_8023;
-+		mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
-+				     *info);
- 	}
- 
- 	if (rxv && mode >= MT_PHY_TYPE_HE_SU && mode < MT_PHY_TYPE_EHT_SU &&
- 	    !(status->flag & RX_FLAG_8023))
- 		mt76_connac3_mac_decode_he_radiotap(skb, rxv, mode);
- 
--	if (!status->wcid || !ieee80211_is_data_qos(fc))
-+	if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
- 		return 0;
- 
- 	status->aggr = unicast &&
-@@ -1406,7 +1438,7 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 		dev_kfree_skb(skb);
- 		break;
- 	case PKT_TYPE_NORMAL:
--		if (!mt7996_mac_fill_rx(dev, skb)) {
-+		if (!mt7996_mac_fill_rx(dev, q, skb, info)) {
- 			mt76_rx(&dev->mt76, q, skb);
- 			return;
- 		}
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 5f18de031..2fc22d576 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -1063,7 +1063,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
- static int
- mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
- 		  struct ieee80211_ampdu_params *params,
--		  bool enable, bool tx)
-+		  bool enable, bool tx, bool rro_enable)
- {
- 	struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
- 	struct sta_rec_ba_uni *ba;
-@@ -1084,6 +1084,8 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
- 	ba->ba_en = enable << params->tid;
- 	ba->amsdu = params->amsdu;
- 	ba->tid = params->tid;
-+	if (rro_enable && !tx && enable)
-+		ba->ba_rdd_rro = true;
- 
- 	return mt76_mcu_skb_send_msg(dev, skb,
- 				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
-@@ -1101,7 +1103,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
- 		msta->wcid.amsdu = false;
- 
- 	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
--				 enable, true);
-+				 enable, true, dev->rro_support);
- }
- 
- int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
-@@ -1112,7 +1114,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
- 	struct mt7996_vif *mvif = msta->vif;
- 
- 	return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
--				 enable, false);
-+				 enable, false, dev->rro_support);
- }
- 
- static void
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index ad2482ef2..1805d892f 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -336,7 +336,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 
- 	dev->rro_support = true;
- 
--	hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
-+	if (dev->hif2)
-+		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
- 
- 	if (hif2)
- 		wed = &dev->mt76.mmio.wed_ext;
-@@ -369,9 +370,15 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 			wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
- 		}
- 
-+		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
-+		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base + hif1_ofs +
-+					MT_RXQ_RING_BASE(MT7996_RXQ_BAND2) +
-+					MT7996_RXQ_BAND2 * MT_RING_SIZE;
-+
- 		wed->wlan.chip_id = 0x7991;
- 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
- 	} else {
-+		wed->wlan.hwrro = dev->rro_support; /* default on */
- 		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
- 		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
- 		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
-@@ -383,13 +390,33 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 					MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
- 					MT7996_RXQ_BAND0 * MT_RING_SIZE;
- 
-+		wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
-+					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
-+					    MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
-+		wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
-+					    MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
-+					    MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
-+		wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
-+					MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
-+					MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
-+
- 		wed->wlan.rx_nbuf = 65536;
- 		wed->wlan.rx_npkt = 24576;
-+		if (dev->hif2)
-+			wed->wlan.rx_npkt += 8192;
-+
- 		wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
- 
- 		wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
- 		wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
- 
-+		wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
-+		wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
-+
-+		wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
-+		wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
-+		wed->wlan.rx_pg_tbit[2] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND2) - 1;
-+
- 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
- 		wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
- 		if (dev->rro_support) {
-@@ -401,6 +428,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 			wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
- 						  MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
- 		}
-+
-+		dev->mt76.rx_token_size += wed->wlan.rx_npkt;
- 	}
- 
- 	wed->wlan.nbuf = MT7996_TOKEN_SIZE;
-@@ -417,8 +446,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
- 	wed->wlan.update_wo_rx_stats = NULL;
- 
--	dev->mt76.rx_token_size += wed->wlan.rx_npkt;
--
- 	if (mtk_wed_device_attach(wed))
- 		return 0;
- 
-@@ -530,12 +557,15 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
- 					       dev->mt76.mmio.irqmask);
- 		if (intr1 & MT_INT_RX_TXFREE_EXT)
- 			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
-+
-+		if (intr1 & MT_INT_RX_DONE_BAND2_EXT)
-+			napi_schedule(&dev->mt76.napi[MT_RXQ_BAND2]);
- 	}
- 
- 	if (mtk_wed_device_active(wed)) {
- 		mtk_wed_device_irq_set_mask(wed, 0);
- 		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
--		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
-+		intr |= (intr1 & ~MT_INT_TRX_DONE_EXT);
- 	} else {
- 		mt76_wr(dev, MT_INT_MASK_CSR, 0);
- 		if (dev->hif2)
-@@ -581,10 +611,9 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
- irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
- {
- 	struct mt7996_dev *dev = dev_instance;
--	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
- 
--	if (mtk_wed_device_active(wed))
--		mtk_wed_device_irq_set_mask(wed, 0);
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
-+		mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed, 0);
- 	else
- 		mt76_wr(dev, MT_INT_MASK_CSR, 0);
- 
-@@ -616,6 +645,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
- 				SURVEY_INFO_TIME_RX |
- 				SURVEY_INFO_TIME_BSS_RX,
- 		.token_size = MT7996_TOKEN_SIZE,
-+		.rx_token_size = MT7996_RX_TOKEN_SIZE,
- 		.tx_prepare_skb = mt7996_tx_prepare_skb,
- 		.tx_complete_skb = mt76_connac_tx_complete_skb,
- 		.rx_skb = mt7996_queue_rx_skb,
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index d09358305..cf2a66df2 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -40,6 +40,7 @@
- #define MT7996_EEPROM_SIZE		7680
- #define MT7996_EEPROM_BLOCK_SIZE	16
- #define MT7996_TOKEN_SIZE		16384
-+#define MT7996_RX_TOKEN_SIZE		16384
- #define MT7996_SW_TOKEN_SIZE		1024
- 
- #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
-@@ -65,6 +66,24 @@
- #define MT7996_SKU_RATE_NUM		417
- #define MT7996_SKU_PATH_NUM		494
- 
-+#define MT7996_RRO_MSDU_PG_HASH_SIZE	127
-+#define MT7996_RRO_SESSION_MAX		1024
-+#define MT7996_RRO_WIN_SIZE_MAX		1024
-+#define MT7996_RRO_ADDR_ELEM_CR_CNT	128
-+#define MT7996_RRO_BA_BITMAP_CR_CNT	2
-+#define MT7996_RRO_SESSION_PER_CR	(MT7996_RRO_SESSION_MAX /	\
-+					 MT7996_RRO_ADDR_ELEM_CR_CNT)
-+#define MT7996_BA_BITMAP_SZ_PER_SESSION	128
-+#define MT7996_BA_BITMAP_SZ_PER_CR	((MT7996_RRO_SESSION_MAX *		\
-+					 MT7996_BA_BITMAP_SZ_PER_SESSION) /	\
-+					 MT7996_RRO_BA_BITMAP_CR_CNT)
-+#define MT7996_SKB_TRUESIZE(x)		((x) +	\
-+					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+#define MT7996_RX_BUF_SIZE		MT7996_SKB_TRUESIZE(1800)
-+#define MT7996_RX_MSDU_PAGE_SIZE	MT7996_SKB_TRUESIZE(128)
-+
-+#define MT7996_WED_RX_TOKEN_SIZE	32768
-+
- struct mt7996_vif;
- struct mt7996_sta;
- struct mt7996_dfs_pulse;
-@@ -109,6 +128,16 @@ enum mt7996_rxq_id {
- 	MT7996_RXQ_BAND0 = 4,
- 	MT7996_RXQ_BAND1 = 4,/* unused */
- 	MT7996_RXQ_BAND2 = 5,
-+	MT7996_RXQ_RRO_BAND0 = 8,
-+	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
-+	MT7996_RXQ_RRO_BAND2 = 6,
-+	MT7996_RXQ_MSDU_PG_BAND0 = 10,
-+	MT7996_RXQ_MSDU_PG_BAND1 = 11,
-+	MT7996_RXQ_MSDU_PG_BAND2 = 12,
-+	MT7996_RXQ_TXFREE0 = 9,
-+	MT7996_RXQ_TXFREE1 = 9,
-+	MT7996_RXQ_TXFREE2 = 7,
-+	MT7996_RXQ_RRO_IND = 0,
- };
- 
- struct mt7996_twt_flow {
-@@ -216,6 +245,31 @@ struct mt7996_air_monitor_ctrl {
- };
- #endif
- 
-+struct mt7996_rro_addr {
-+	u32 head_pkt_l;
-+	u32 head_pkt_h	: 4;
-+	u32 seg_cnt	: 11;
-+	u32 out_of_range: 1;
-+	u32 rsv		: 8;
-+	u32 signature	: 8;
-+};
-+
-+struct mt7996_rro_cfg {
-+	u32 ind_signature;
-+	void *ba_bitmap_cache_va[MT7996_RRO_BA_BITMAP_CR_CNT];
-+	void *addr_elem_alloc_va[MT7996_RRO_ADDR_ELEM_CR_CNT];
-+	void *particular_session_va;
-+	u32 particular_se_id;
-+	dma_addr_t ba_bitmap_cache_pa[MT7996_RRO_BA_BITMAP_CR_CNT];
-+	dma_addr_t addr_elem_alloc_pa[MT7996_RRO_ADDR_ELEM_CR_CNT];
-+	dma_addr_t particular_session_pa;
-+	u16 win_sz;
-+
-+	spinlock_t lock;
-+	struct list_head pg_addr_cache;
-+	struct list_head pg_hash_head[MT7996_RRO_MSDU_PG_HASH_SIZE];
-+};
-+
- struct mt7996_phy {
- 	struct mt76_phy *mt76;
- 	struct mt7996_dev *dev;
-@@ -338,6 +392,9 @@ struct mt7996_dev {
- 	bool flash_mode:1;
- 	bool has_eht:1;
- 
-+	bool rro_support:1;
-+	struct mt7996_rro_cfg rro;
-+
- 	bool testmode_enable;
- 	bool bin_file_mode;
- 	u8 eeprom_mode;
-@@ -662,6 +719,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 			  struct ieee80211_sta *sta,
- 			  struct mt76_tx_info *tx_info);
- void mt7996_tx_token_put(struct mt7996_dev *dev);
-+int mt7996_dma_rro_init(struct mt7996_dev *dev);
- void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 			 struct sk_buff *skb, u32 *info);
- bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 085408571..9a134fcab 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -124,6 +124,8 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 	mdev = &dev->mt76;
- 	mt7996_wfsys_reset(dev);
- 	hif2 = mt7996_pci_init_hif2(pdev);
-+	if (hif2)
-+		dev->hif2 = hif2;
- 
- 	ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
- 	if (ret < 0)
-@@ -148,7 +150,6 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 
- 	if (hif2) {
- 		hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
--		dev->hif2 = hif2;
- 
- 		ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &irq);
- 		if (ret < 0)
-diff --git a/mt7996/regs.h b/mt7996/regs.h
-index ca7c2a811..c34357c3e 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -39,6 +39,40 @@ enum base_rev {
- 
- #define __BASE(_id, _band)			(dev->reg.base[(_id)].band_base[(_band)])
- 
-+
-+/* RRO TOP */
-+#define MT_RRO_TOP_BASE				0xA000
-+#define MT_RRO_TOP(ofs)				(MT_RRO_TOP_BASE + (ofs))
-+
-+#define MT_RRO_BA_BITMAP_BASE0			MT_RRO_TOP(0x8)
-+#define MT_RRO_BA_BITMAP_BASE1			MT_RRO_TOP(0xC)
-+#define WF_RRO_AXI_MST_CFG			MT_RRO_TOP(0xB8)
-+#define WF_RRO_AXI_MST_CFG_DIDX_OK		BIT(12)
-+#define MT_RRO_ADDR_ARRAY_BASE1			MT_RRO_TOP(0x34)
-+#define MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE	BIT(31)
-+
-+#define MT_RRO_IND_CMD_SIGNATURE_BASE0		MT_RRO_TOP(0x38)
-+#define MT_RRO_IND_CMD_SIGNATURE_BASE1		MT_RRO_TOP(0x3C)
-+#define MT_RRO_IND_CMD_0_CTRL0			MT_RRO_TOP(0x40)
-+#define MT_RRO_IND_CMD_SIGNATURE_BASE1_EN	BIT(31)
-+
-+#define MT_RRO_PARTICULAR_CFG0			MT_RRO_TOP(0x5C)
-+#define MT_RRO_PARTICULAR_CFG1			MT_RRO_TOP(0x60)
-+#define MT_RRO_PARTICULAR_CONFG_EN		BIT(31)
-+#define MT_RRO_PARTICULAR_SID			GENMASK(30, 16)
-+
-+#define MT_RRO_BA_BITMAP_BASE_EXT0		MT_RRO_TOP(0x70)
-+#define MT_RRO_BA_BITMAP_BASE_EXT1		MT_RRO_TOP(0x74)
-+#define MT_RRO_HOST_INT_ENA			MT_RRO_TOP(0x204)
-+#define MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA   BIT(0)
-+
-+#define MT_RRO_ADDR_ELEM_SEG_ADDR0		MT_RRO_TOP(0x400)
-+
-+#define MT_RRO_ACK_SN_CTRL			MT_RRO_TOP(0x50)
-+#define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
-+#define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
-+
-+
- #define MT_MCU_INT_EVENT			0x2108
- #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
- #define MT_MCU_INT_EVENT_DMA_INIT		BIT(1)
-@@ -407,6 +441,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)
-+#define MT_RXQ_RRO_IND_RING_BASE		MT_RRO_TOP(0x40)
- 
- #define MT_MCUQ_EXT_CTRL(q)			(MT_Q_BASE(q) +	0x600 +	\
- 						 MT_MCUQ_ID(q) * 0x4)
-@@ -432,8 +467,19 @@ enum base_rev {
- #define MT_INT_RX_TXFREE_MAIN			BIT(17)
- #define MT_INT_RX_TXFREE_TRI			BIT(15)
- #define MT_INT_MCU_CMD				BIT(29)
-+
-+#define MT_INT_RX_DONE_BAND2_EXT		BIT(23)
- #define MT_INT_RX_TXFREE_EXT			BIT(26)
- 
-+#define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
-+#define MT_INT_RX_DONE_RRO_BAND1		BIT(16)
-+#define MT_INT_RX_DONE_RRO_BAND2		BIT(14)
-+#define MT_INT_RX_DONE_RRO_IND			BIT(11)
-+#define MT_INT_RX_DONE_MSDU_PG_BAND0		BIT(18)
-+#define MT_INT_RX_DONE_MSDU_PG_BAND1		BIT(19)
-+#define MT_INT_RX_DONE_MSDU_PG_BAND2		BIT(23)
-+
-+
- #define MT_INT_RX(q)				(dev->q_int_mask[__RXQ(q)])
- #define MT_INT_TX_MCU(q)			(dev->q_int_mask[(q)])
- 
-@@ -441,20 +487,31 @@ enum base_rev {
- 						 MT_INT_RX(MT_RXQ_MCU_WA))
- 
- #define MT_INT_BAND0_RX_DONE			(MT_INT_RX(MT_RXQ_MAIN) |	\
--						 MT_INT_RX(MT_RXQ_MAIN_WA))
-+						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
-+						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
- 
- #define MT_INT_BAND1_RX_DONE			(MT_INT_RX(MT_RXQ_BAND1) |	\
- 						 MT_INT_RX(MT_RXQ_BAND1_WA) |	\
--						 MT_INT_RX(MT_RXQ_MAIN_WA))
-+						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
-+						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
- 
- #define MT_INT_BAND2_RX_DONE			(MT_INT_RX(MT_RXQ_BAND2) |	\
- 						 MT_INT_RX(MT_RXQ_BAND2_WA) |	\
--						 MT_INT_RX(MT_RXQ_MAIN_WA))
-+						 MT_INT_RX(MT_RXQ_MAIN_WA) |	\
-+						 MT_INT_RX(MT_RXQ_TXFREE_BAND0))
-+
-+#define MT_INT_RRO_RX_DONE			(MT_INT_RX(MT_RXQ_RRO_BAND0) |		\
-+						 MT_INT_RX(MT_RXQ_RRO_BAND1) |		\
-+						 MT_INT_RX(MT_RXQ_RRO_BAND2) |		\
-+						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND0) |	\
-+						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND1) |	\
-+						 MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND2))
- 
- #define MT_INT_RX_DONE_ALL			(MT_INT_RX_DONE_MCU |		\
- 						 MT_INT_BAND0_RX_DONE |		\
- 						 MT_INT_BAND1_RX_DONE |		\
--						 MT_INT_BAND2_RX_DONE)
-+						 MT_INT_BAND2_RX_DONE |		\
-+						 MT_INT_RRO_RX_DONE)
- 
- #define MT_INT_TX_DONE_FWDL			BIT(26)
- #define MT_INT_TX_DONE_MCU_WM			BIT(27)
-@@ -463,6 +520,10 @@ enum base_rev {
- #define MT_INT_TX_DONE_BAND1			BIT(31)
- #define MT_INT_TX_DONE_BAND2			BIT(15)
- 
-+#define MT_INT_TRX_DONE_EXT			(MT_INT_TX_DONE_BAND2 |	\
-+						 MT_INT_RX_DONE_BAND2_EXT |	\
-+						 MT_INT_RX_TXFREE_EXT)
-+
- #define MT_INT_TX_DONE_MCU			(MT_INT_TX_MCU(MT_MCUQ_WA) |	\
- 						 MT_INT_TX_MCU(MT_MCUQ_WM) |	\
- 						 MT_INT_TX_MCU(MT_MCUQ_FWDL))
--- 
-2.39.2
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch
deleted file mode 100644
index e62d01c..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 15e621e5bc992bf2a40f1897ca76fb63e93ba394 Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Thu, 13 Apr 2023 14:12:16 +0800
-Subject: [PATCH 2005/2012] wifi: mt76: mt7996: wed: add mt7996_net_setup_tc to
- support wifi2wifi offload
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- mt7996/main.c | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
-diff --git a/mt7996/main.c b/mt7996/main.c
-index e6be05656..1ccd07802 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -1549,6 +1549,24 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
- 	return 0;
- }
- 
-+static int mt7996_net_setup_tc(struct ieee80211_hw *hw,
-+			       struct ieee80211_vif *vif,
-+			       struct net_device *ndev,
-+			       enum tc_setup_type type,
-+			       void *type_data)
-+
-+{
-+	struct mt7996_dev *dev = mt7996_hw_dev(hw);
-+	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+
-+	if (!mtk_wed_device_active(wed))
-+		return -ENODEV;
-+
-+	mtk_wed_device_setup_tc(wed, ndev, type, type_data);
-+
-+	return 0;
-+}
-+
- #endif
- 
- const struct ieee80211_ops mt7996_ops = {
-@@ -1599,5 +1617,6 @@ const struct ieee80211_ops mt7996_ops = {
- 	.set_radar_background = mt7996_set_radar_background,
- #ifdef CONFIG_NET_MEDIATEK_SOC_WED
- 	.net_fill_forward_path = mt7996_net_fill_forward_path,
-+	.net_setup_tc = mt7996_net_setup_tc,
- #endif
- };
--- 
-2.39.2
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch
new file mode 100644
index 0000000..306c6e6
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2005-wifi-mt76-wed-change-pcie0-R5-to-pcie1-to-get-6G-ICS.patch
@@ -0,0 +1,93 @@
+From 161fde22deceee4e676f62b9d3b0366ffe52dc07 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Fri, 6 Oct 2023 14:01:41 +0800
+Subject: [PATCH 69/98] wifi: mt76 : wed : change pcie0 R5 to pcie1 to get 6G
+ ICS
+
+---
+ mt7996/dma.c  | 4 ++++
+ mt7996/init.c | 6 ++----
+ mt7996/mmio.c | 5 ++++-
+ mt7996/regs.h | 6 ++++++
+ 4 files changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 23f6f16..2397fe5 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -519,6 +519,10 @@ 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;
++		if (mtk_wed_device_active(wed_hif2) && mtk_wed_get_rx_capa(wed_hif2)) {
++			dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(0);
++			dev->mt76.q_rx[MT_RXQ_BAND2].wed = wed_hif2;
++		}
+ 		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ 				       MT_RXQ_ID(MT_RXQ_BAND2),
+ 				       MT7996_RX_RING_SIZE,
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 1f01f24..5627605 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -619,10 +619,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 		goto error;
+ 
+ 	if (wed == &dev->mt76.mmio.wed_hif2 && mtk_wed_device_active(wed)) {
+-		u32 irq_mask = dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2;
+-
+-		mt76_wr(dev, MT_INT1_MASK_CSR, irq_mask);
+-		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask);
++		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, MT_INT_TRX_DONE_EXT);
++		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, MT_INT_TRX_DONE_EXT);
+ 	}
+ 
+ 	return 0;
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 2132b2e..2e395d1 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -504,12 +504,15 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
+ 					       dev->mt76.mmio.irqmask);
+ 		if (intr1 & MT_INT_RX_TXFREE_EXT)
+ 			napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
++
++		if (intr1 & MT_INT_RX_DONE_BAND2_EXT)
++			napi_schedule(&dev->mt76.napi[MT_RXQ_BAND2]);
+ 	}
+ 
+ 	if (mtk_wed_device_active(wed)) {
+ 		mtk_wed_device_irq_set_mask(wed, 0);
+ 		intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
+-		intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
++		intr |= (intr1 & ~MT_INT_TRX_DONE_EXT);
+ 	} else {
+ 		mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ 		if (dev->hif2)
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 38467d9..a0b5270 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -501,6 +501,8 @@ enum offs_rev {
+ #define MT_INT_RX_TXFREE_MAIN			BIT(17)
+ #define MT_INT_RX_TXFREE_TRI			BIT(15)
+ #define MT_INT_MCU_CMD				BIT(29)
++
++#define MT_INT_RX_DONE_BAND2_EXT		BIT(23)
+ #define MT_INT_RX_TXFREE_EXT			BIT(26)
+ 
+ #define MT_INT_RX_DONE_RRO_BAND0		BIT(16)
+@@ -551,6 +553,10 @@ enum offs_rev {
+ #define MT_INT_TX_DONE_BAND1			BIT(31)
+ #define MT_INT_TX_DONE_BAND2			BIT(15)
+ 
++#define MT_INT_TRX_DONE_EXT			(MT_INT_TX_DONE_BAND2 |	\
++						 MT_INT_RX_DONE_BAND2_EXT |	\
++						 MT_INT_RX_TXFREE_EXT)
++
+ #define MT_INT_TX_DONE_MCU			(MT_INT_TX_MCU(MT_MCUQ_WA) |	\
+ 						 MT_INT_TX_MCU(MT_MCUQ_WM) |	\
+ 						 MT_INT_TX_MCU(MT_MCUQ_FWDL))
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch
new file mode 100644
index 0000000..7511279
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2006-wifi-mt76-mt7996-add-rro-elem-free-when-rmmod-wifi-m.patch
@@ -0,0 +1,65 @@
+From a2bd3309c6c1ea4d63d8ac3fc066914186740ab5 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Fri, 6 Oct 2023 15:48:37 +0800
+Subject: [PATCH 70/98] wifi: mt76: mt7996: add rro elem free when rmmod wifi
+ module
+
+---
+ mt7996/init.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 5627605..1ece390 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -670,6 +670,38 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
+ 	msleep(20);
+ }
+ 
++static int mt7996_rro_free(struct mt7996_dev *dev)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.ba_bitmap); i++) {
++		if (dev->wed_rro.ba_bitmap[i].ptr)
++			dmam_free_coherent(dev->mt76.dma_dev,
++					   MT7996_RRO_BA_BITMAP_CR_SIZE,
++					   dev->wed_rro.ba_bitmap[i].ptr,
++					   dev->wed_rro.ba_bitmap[i].phy_addr);
++	}
++
++	for (i = 0; i < ARRAY_SIZE(dev->wed_rro.addr_elem); i++) {
++		if (dev->wed_rro.addr_elem[i].ptr) {
++			dmam_free_coherent(dev->mt76.dma_dev,
++					   MT7996_RRO_WINDOW_MAX_SIZE *
++					   sizeof(struct mt7996_wed_rro_addr),
++					   dev->wed_rro.addr_elem[i].ptr,
++					   dev->wed_rro.addr_elem[i].phy_addr);
++		}
++	}
++
++	if (dev->wed_rro.session.ptr)
++		dmam_free_coherent(dev->mt76.dma_dev,
++				   MT7996_RRO_WINDOW_MAX_LEN *
++				   sizeof(struct mt7996_wed_rro_addr),
++				   dev->wed_rro.session.ptr,
++				   dev->wed_rro.session.phy_addr);
++
++	return 0;
++}
++
+ static int mt7996_wed_rro_init(struct mt7996_dev *dev)
+ {
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+@@ -1295,6 +1327,8 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
+ 	mt7996_coredump_unregister(dev);
+ 	mt76_unregister_device(&dev->mt76);
+ 	mt7996_mcu_exit(dev);
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->has_rro)
++		mt7996_rro_free(dev);
+ 	mt7996_tx_token_put(dev);
+ 	mt7996_dma_cleanup(dev);
+ 	tasklet_disable(&dev->mt76.irq_tasklet);
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2008-wifi-mt76-add-SER-support-for-wed3.0.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2007-wifi-mt76-add-SER-support-for-wed3.0.patch
similarity index 66%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2007-wifi-mt76-add-SER-support-for-wed3.0.patch
index c7f8dac..2ba1f4e 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2007-wifi-mt76-add-SER-support-for-wed3.0.patch
@@ -1,47 +1,36 @@
-From e13a81689d5df310915182b8b7f2858ac65a0472 Mon Sep 17 00:00:00 2001
+From 487a6e92fb6ce81d043b5a7632133379b8bcfbcb Mon Sep 17 00:00:00 2001
 From: mtk27745 <rex.lu@mediatek.com>
 Date: Tue, 23 May 2023 12:06:29 +0800
-Subject: [PATCH 2008/2012] wifi: mt76: add SER support for wed3.0
+Subject: [PATCH 71/98] wifi: mt76: add SER support for wed3.0
 
 Change-Id: I2711b9dc336fca9a1ae32a8fbf27810a7e27b1e3
 ---
- dma.c         |  7 +++++--
+ dma.c         |  4 +++-
  mt7996/dma.c  | 42 +++++++++++++++++++++++++++++++++++++++---
- mt7996/mac.c  | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
- mt7996/mmio.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 139 insertions(+), 6 deletions(-)
+ mt7996/mac.c  | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
+ mt7996/mmio.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 136 insertions(+), 5 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 8097a3121..bfe188134 100644
+index f48ec57..141a97b 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -772,8 +772,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;
- 			}
-+			q->flags = flags;
- 		} else {
--			ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, 0);
-+			ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
- 			if (!ret)
- 				q->wed_regs = wed->rx_ring[ring].reg_base;
- 		}
-@@ -904,7 +905,9 @@ done:
+@@ -898,7 +898,9 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
  
  	/* reset WED rx queues */
  	mt76_dma_wed_setup(dev, q, true);
--	if (q->flags != MT_WED_Q_TXFREE) {
-+	if (q->flags != MT_WED_Q_TXFREE &&
-+	    !((q->flags & MT_QFLAG_RRO) &&
+-	if (!mt76_queue_is_wed_tx_free(q)) {
++	if (!mt76_queue_is_wed_tx_free(q) &&
++	    !(mt76_queue_is_wed_rro(q) &&
 +	    mtk_wed_device_active(&dev->mmio.wed))) {
  		mt76_dma_sync_idx(dev, q);
  		mt76_dma_rx_fill(dev, q);
  	}
 diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 309cc242e..9416d7947 100644
+index 2397fe5..b2c7ae6 100644
 --- a/mt7996/dma.c
 +++ b/mt7996/dma.c
-@@ -611,11 +611,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -615,11 +615,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
  	return 0;
  }
  
@@ -62,7 +51,7 @@
 +static void
 +mt7996_dma_reset_tx_queue(struct mt7996_dev *dev, struct mt76_queue *q)
 +{
-+	mt76_queue_reset(dev, q, false);
++	mt76_queue_reset(dev, q);
 +	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
 +		mt76_dma_wed_setup(&dev->mt76, q, true);
 +}
@@ -73,16 +62,16 @@
  	struct mt76_phy *phy3 = dev->mt76.phys[MT_BAND2];
  	u32 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
 +	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
-+	struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
++	struct mtk_wed_device *wed_hif2 = &dev->mt76.mmio.wed_hif2;
  	int i;
  
  	mt76_clear(dev, MT_WFDMA0_GLO_CFG,
-@@ -649,21 +673,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+@@ -653,21 +677,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
  	if (force)
  		mt7996_wfsys_reset(dev);
  
-+	if (dev->hif2 && mtk_wed_device_active(wed_ext))
-+		mtk_wed_device_dma_reset(wed_ext);
++	if (dev->hif2 && mtk_wed_device_active(wed_hif2))
++		mtk_wed_device_dma_reset(wed_hif2);
 +
 +	if (mtk_wed_device_active(wed))
 +		mtk_wed_device_dma_reset(wed);
@@ -92,61 +81,61 @@
  
  	/* reset hw queues */
  	for (i = 0; i < __MT_TXQ_MAX; i++) {
--		mt76_queue_reset(dev, dev->mphy.q_tx[i], false);
+-		mt76_queue_reset(dev, dev->mphy.q_tx[i]);
 +		mt7996_dma_reset_tx_queue(dev, dev->mphy.q_tx[i]);
  		if (phy2)
--			mt76_queue_reset(dev, phy2->q_tx[i], false);
+-			mt76_queue_reset(dev, phy2->q_tx[i]);
 +			mt7996_dma_reset_tx_queue(dev, phy2->q_tx[i]);
  		if (phy3)
--			mt76_queue_reset(dev, phy3->q_tx[i], false);
+-			mt76_queue_reset(dev, phy3->q_tx[i]);
 +			mt7996_dma_reset_tx_queue(dev, phy3->q_tx[i]);
  	}
  
  	for (i = 0; i < __MT_MCUQ_MAX; i++)
- 		mt76_queue_reset(dev, dev->mt76.q_mcu[i], false);
+ 		mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
  
  	mt76_for_each_q_rx(&dev->mt76, i) {
 +		if (mtk_wed_device_active(wed) &&
-+		    ((dev->mt76.q_rx[i].flags & MT_QFLAG_RRO) ||
-+		    dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE))
++		    (mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]) ||
++		    mt76_queue_is_wed_tx_free(&dev->mt76.q_rx[i])))
 +			continue;
 +
- 		mt76_queue_reset(dev, &dev->mt76.q_rx[i], false);
+ 		mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
  	}
  
 diff --git a/mt7996/mac.c b/mt7996/mac.c
-index e331594d3..f994203aa 100644
+index 60ca23b..22cff71 100644
 --- a/mt7996/mac.c
 +++ b/mt7996/mac.c
-@@ -1804,6 +1804,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+@@ -1762,6 +1762,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
  	/* disable all tx/rx napi */
  	mt76_worker_disable(&dev->mt76.tx_worker);
  	mt76_for_each_q_rx(mdev, i) {
 +		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    (mdev->q_rx[i].flags & MT_QFLAG_RRO))
++		    mt76_queue_is_wed_rro(&mdev->q_rx[i]))
 +			continue;
 +
  		if (mdev->q_rx[i].ndesc)
  			napi_disable(&dev->mt76.napi[i]);
  	}
-@@ -1817,6 +1821,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+@@ -1775,6 +1779,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
  
  	local_bh_disable();
  	mt76_for_each_q_rx(mdev, i) {
 +		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    (mdev->q_rx[i].flags & MT_QFLAG_RRO))
++		    mt76_queue_is_wed_rro(&mdev->q_rx[i]))
 +			continue;
 +
  		if (mdev->q_rx[i].ndesc) {
  			napi_enable(&dev->mt76.napi[i]);
  			napi_schedule(&dev->mt76.napi[i]);
-@@ -1991,6 +1999,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -1949,6 +1957,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
  
  	dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.",
  		 wiphy_name(dev->mt76.hw->wiphy));
 +
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
-+		mtk_wed_device_stop(&dev->mt76.mmio.wed_ext);
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2))
++		mtk_wed_device_stop(&dev->mt76.mmio.wed_hif2);
 +
 +	if (mtk_wed_device_active(&dev->mt76.mmio.wed))
 +		mtk_wed_device_stop(&dev->mt76.mmio.wed);
@@ -154,14 +143,14 @@
  	ieee80211_stop_queues(mt76_hw(dev));
  	if (phy2)
  		ieee80211_stop_queues(phy2->mt76->hw);
-@@ -2014,8 +2029,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -1972,8 +1987,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
  		cancel_delayed_work_sync(&phy3->mt76->mac_work);
  	}
  	mt76_worker_disable(&dev->mt76.tx_worker);
 -	mt76_for_each_q_rx(&dev->mt76, i)
 +	mt76_for_each_q_rx(&dev->mt76, i) {
 +		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    (dev->mt76.q_rx[i].flags & MT_QFLAG_RRO))
++		    mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
 +			continue;
 +
  		napi_disable(&dev->mt76.napi[i]);
@@ -169,7 +158,7 @@
  	napi_disable(&dev->mt76.tx_napi);
  
  	mutex_lock(&dev->mt76.mutex);
-@@ -2038,6 +2058,29 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -1996,6 +2016,27 @@ void mt7996_mac_reset_work(struct work_struct *work)
  	/* enable DMA Tx/Tx and interrupt */
  	mt7996_dma_start(dev, false, false);
  
@@ -189,29 +178,27 @@
 +		mt7996_irq_disable(dev, 0);
 +	}
 +
-+	if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
-+		mt76_wr(dev, MT_INT1_MASK_CSR,
-+			dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2);
-+		mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
-+			dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2);
++	if (mtk_wed_device_active(&dev->mt76.mmio.wed_hif2)) {
++		mt76_wr(dev, MT_INT_PCIE1_MASK_CSR, MT_INT_TRX_DONE_EXT);
++		mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, MT_INT_TRX_DONE_EXT);
 +	}
 +
  	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
  	clear_bit(MT76_RESET, &dev->mphy.state);
  	if (phy2)
-@@ -2047,6 +2090,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+@@ -2005,6 +2046,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
  
  	local_bh_disable();
  	mt76_for_each_q_rx(&dev->mt76, i) {
 +		if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
-+		    ((dev->mt76.q_rx[i].flags & MT_QFLAG_RRO)))
++		    mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
 +			continue;
 +
  		napi_enable(&dev->mt76.napi[i]);
  		napi_schedule(&dev->mt76.napi[i]);
  	}
 diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 1805d892f..940f94998 100644
+index 2e395d1..631d905 100644
 --- a/mt7996/mmio.c
 +++ b/mt7996/mmio.c
 @@ -6,9 +6,11 @@
@@ -226,11 +213,11 @@
  #include "../trace.h"
  #include "../dma.h"
  
-@@ -320,6 +322,43 @@ unmap:
- 	mt7996_mmio_wed_release_rx_buf(wed);
- 	return -ENOMEM;
+@@ -271,6 +273,45 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ 	return val;
  }
-+
+ 
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
 +static int mt7996_mmio_wed_reset(struct mtk_wed_device *wed)
 +{
 +	struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed);
@@ -267,13 +254,15 @@
 +	complete(&dev->mmio.wed_reset_complete);
 +}
 +
- #endif
- 
++#endif
++
  int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
-@@ -445,6 +484,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 	wed->wlan.init_rx_buf = mt7996_mmio_wed_init_rx_buf;
- 	wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
- 	wed->wlan.update_wo_rx_stats = NULL;
+ 			 bool hif2, int *irq)
+ {
+@@ -387,6 +428,13 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 	wed->wlan.release_rx_buf = mt76_mmio_wed_release_rx_buf;
+ 	wed->wlan.offload_enable = mt76_mmio_wed_offload_enable;
+ 	wed->wlan.offload_disable = mt76_mmio_wed_offload_disable;
 +	if (hif2) {
 +		wed->wlan.reset = NULL;
 +		wed->wlan.reset_complete = NULL;
@@ -281,10 +270,9 @@
 +		wed->wlan.reset = mt7996_mmio_wed_reset;
 +		wed->wlan.reset_complete = mt7996_mmio_wed_reset_complete;
 +	}
-+
  
  	if (mtk_wed_device_attach(wed))
  		return 0;
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
deleted file mode 100644
index 7ed734a..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
+++ /dev/null
@@ -1,472 +0,0 @@
-From 3751850a855b377433c54118e283322aded240ee Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Thu, 18 May 2023 15:01:47 +0800
-Subject: [PATCH 2007/2012] wifi: mt76: mt7996: reset addr_elem when delete ba
-
-The old addr element info may be used when the signature is not equel to
-0xff, and sta will find error SDP cause the SDP/SDL=0 issue.
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- mt76.h            |   1 +
- mt76_connac_mcu.h |   1 +
- mt7996/init.c     |   3 +
- mt7996/mac.c      | 140 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/main.c     |   7 +++
- mt7996/mcu.c      |  63 +++++++++++++++++++++
- mt7996/mcu.h      |  34 +++++++++++
- mt7996/mt7996.h   |  32 +++++++++++
- mt7996/regs.h     |   5 ++
- 9 files changed, 286 insertions(+)
-
-diff --git a/mt76.h b/mt76.h
-index 3954d01c5..14d59ab94 100644
---- a/mt76.h
-+++ b/mt76.h
-@@ -442,6 +442,7 @@ struct mt76_rx_tid {
- 	u16 nframes;
- 
- 	u8 num;
-+	u8 partial_id;
- 
- 	u8 started:1, stopped:1, timer_pending:1;
- 
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 1d01b2b89..9fa978d5a 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -1036,6 +1036,7 @@ enum {
- 	MCU_UNI_EVENT_THERMAL = 0x35,
- 	MCU_UNI_EVENT_NIC_CAPAB = 0x43,
- 	MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
-+	MCU_UNI_EVENT_RRO = 0x57,
- 	MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
- 	MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
- };
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 3a749475e..43a49d42a 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -765,6 +765,9 @@ static int mt7996_rro_init(struct mt7996_dev *dev)
- 	mt76_wr(dev, MT_RRO_HOST_INT_ENA,
- 		MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
- 
-+	INIT_DELAYED_WORK(&dev->rro.rro_del_work, mt7996_rro_delete_sessions);
-+	INIT_LIST_HEAD(&dev->rro.rro_poll_list);
-+
- 	/* rro ind cmd queue init */
- 	return mt7996_dma_rro_init(dev);
- }
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 08a32195b..e331594d3 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1449,6 +1449,139 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 	}
- }
- 
-+static struct mt7996_rro_addr *
-+mt7996_rro_get_addr_elem(struct mt7996_dev *dev, u16 seid, u16 sn)
-+{
-+	struct mt7996_rro_cfg *rro = &dev->rro;
-+	u32 idx;
-+	void *addr;
-+
-+	if (seid == rro->particular_se_id) {
-+		addr = rro->particular_session_va;
-+		idx = sn % rro->win_sz;
-+	} else {
-+		addr = rro->addr_elem_alloc_va[seid / MT7996_RRO_SESSION_PER_CR];
-+		idx = (seid % MT7996_RRO_SESSION_PER_CR) * rro->win_sz
-+			+ (sn % rro->win_sz);
-+	}
-+	return addr + idx * sizeof(struct mt7996_rro_addr);
-+}
-+
-+static bool mt7996_rro_reset_sessions(struct mt7996_dev *dev,
-+				  u16 wcid, u8 partial_id)
-+{
-+	u32 sid = ((wcid & 0x7F) << 3) + partial_id;
-+	u32 value[2];
-+	struct mt7996_rro_ba_session *s;
-+	struct  mt7996_rro_addr *elem;
-+	int i;
-+
-+	mt76_wr(dev, MT_RRO_DBG_RD_CTRL, MT_RRO_DBG_RD_EXEC |
-+		sid >> 1 | 0x200);
-+
-+	if (sid & 0x1) {
-+		value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2));
-+		value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(3));
-+	} else {
-+		value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(0));
-+		value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(1));
-+	}
-+
-+	s = (struct mt7996_rro_ba_session *)&value[0];
-+	if (!s->cn && s->ack_sn == s->last_in_sn) {
-+		for (i = 0; i < MT7996_RRO_WIN_SIZE_MAX; i++) {
-+			elem = mt7996_rro_get_addr_elem(dev, sid, i);
-+			elem->signature = 0xff;
-+		}
-+		return true;
-+	}
-+
-+	return false;
-+}
-+
-+void  mt7996_rro_delete_sessions(struct work_struct *work)
-+{
-+	struct mt7996_dev *dev;
-+	struct mt7996_rro_ba_session_elem *e;
-+	int elem_nums;
-+	LIST_HEAD(rro_poll_list);
-+
-+	dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,
-+					       rro.rro_del_work.work);
-+	elem_nums = dev->rro.elem_nums;
-+
-+	spin_lock_bh(&dev->rro.rro_stbl_lock);
-+	list_splice_init(&dev->rro.rro_poll_list, &rro_poll_list);
-+	spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+
-+	do {
-+		spin_lock_bh(&dev->rro.rro_stbl_lock);
-+		if (list_empty(&rro_poll_list)) {
-+			spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+			break;
-+		}
-+
-+		e = list_first_entry(&rro_poll_list,
-+				     struct mt7996_rro_ba_session_elem,
-+				     poll_list);
-+		if (!e) {
-+			spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+			break;
-+		}
-+		list_del_init(&e->poll_list);
-+		spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+
-+		if (mt7996_rro_reset_sessions(dev, e->wlan_idx,
-+					      e->partial_id)) {
-+			mt7996_mcu_reset_rro_sessions(dev, e->wlan_idx,
-+						      e->tid, e->partial_id);
-+			kfree(e);
-+			dev->rro.elem_nums--;
-+		} else {
-+			spin_lock_bh(&dev->rro.rro_stbl_lock);
-+			list_add_tail(&e->poll_list, &dev->rro.rro_poll_list);
-+			spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+		}
-+		elem_nums--;
-+	} while (elem_nums);
-+
-+	if (list_empty(&rro_poll_list))
-+		ieee80211_queue_delayed_work(mt76_hw(dev),
-+					     &dev->rro.rro_del_work,
-+					     MT7996_WATCHDOG_TIME);
-+}
-+
-+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev,
-+			       struct mt7996_sta *msta, u8 tidno)
-+{
-+	struct mt76_rx_tid *tid = NULL;
-+	struct mt76_wcid *wcid = &msta->wcid;
-+	struct mt7996_rro_ba_session_elem *e;
-+	u16 idx = msta->wcid.idx;
-+
-+	tid = rcu_dereference(wcid->aggr[tidno]);
-+	if (!tid)
-+		return 0;
-+
-+	e = kzalloc(sizeof(*e), GFP_ATOMIC);
-+	if (!e)
-+		return -ENOMEM;
-+
-+	e->wlan_idx = idx;
-+	e->tid = tidno;
-+	e->partial_id = tid->partial_id;
-+
-+	spin_lock_bh(&dev->rro.rro_stbl_lock);
-+	list_add_tail(&e->poll_list, &dev->rro.rro_poll_list);
-+	spin_unlock_bh(&dev->rro.rro_stbl_lock);
-+	dev->rro.elem_nums++;
-+
-+	ieee80211_queue_delayed_work(mt76_hw(dev),
-+				     &dev->rro.rro_del_work,
-+				     MT7996_WATCHDOG_TIME);
-+	return 0;
-+}
-+
- void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy)
- {
- 	struct mt7996_dev *dev = phy->dev;
-@@ -1773,6 +1906,9 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
- 	if (phy3)
- 		ieee80211_stop_queues(phy3->mt76->hw);
- 
-+	if (dev->rro_support)
-+		cancel_delayed_work_sync(&dev->rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&dev->mphy.mac_work);
- 	if (phy2)
- 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
-@@ -1864,6 +2000,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
- 	set_bit(MT76_RESET, &dev->mphy.state);
- 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
- 	wake_up(&dev->mt76.mcu.wait);
-+
-+	if (dev->rro_support)
-+		cancel_delayed_work_sync(&dev->rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&dev->mphy.mac_work);
- 	if (phy2) {
- 		set_bit(MT76_RESET, &phy2->mt76->state);
-diff --git a/mt7996/main.c b/mt7996/main.c
-index 1ccd07802..52e9666ef 100644
---- a/mt7996/main.c
-+++ b/mt7996/main.c
-@@ -125,6 +125,9 @@ static void mt7996_stop(struct ieee80211_hw *hw)
- 	struct mt7996_dev *dev = mt7996_hw_dev(hw);
- 	struct mt7996_phy *phy = mt7996_hw_phy(hw);
- 
-+	if (dev->rro_support)
-+		cancel_delayed_work_sync(&dev->rro.rro_del_work);
-+
- 	cancel_delayed_work_sync(&phy->mt76->mac_work);
- 	cancel_delayed_work_sync(&dev->scs_work);
- 
-@@ -832,6 +835,10 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 		ret = mt7996_mcu_add_rx_ba(dev, params, true);
- 		break;
- 	case IEEE80211_AMPDU_RX_STOP:
-+		if (dev->rro_support)  {
-+			ret = mt7996_rro_add_delete_elem(dev, msta,
-+							 params->tid);
-+		}
- 		mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
- 		ret = mt7996_mcu_add_rx_ba(dev, params, false);
- 		break;
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index b4d8e9c7f..6c106d8cf 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -517,6 +517,41 @@ mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rat
- 	return 0;
- }
- 
-+static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
-+{
-+	struct mt7996_mcu_rro_event *event;
-+
-+	if (!dev->rro_support)
-+		return;
-+
-+	event = (struct mt7996_mcu_rro_event*)skb->data;
-+
-+	switch (event->tag) {
-+	case UNI_RRO_BA_SESSION_STATUS: {
-+		struct mt7996_mcu_rro_ba *rro = (struct mt7996_mcu_rro_ba *)skb->data;
-+		u16 idx = rro->wlan_id;
-+		struct mt76_rx_tid *tid;
-+		struct mt76_wcid *wcid;
-+
-+		wcid = rcu_dereference(dev->mt76.wcid[idx]);
-+		if (!wcid || !wcid->sta)
-+			return;
-+
-+		tid = rcu_dereference(wcid->aggr[rro->tid]);
-+		if (!tid)
-+			return;
-+		tid->partial_id = rro->partial_id;
-+
-+		break;
-+	}
-+	default:
-+		dev_info(dev->mt76.dev, "%s: unknown rro event tag %d\n",
-+			 __func__, event->tag);
-+		break;
-+	}
-+
-+}
-+
- static void
- mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
- {
-@@ -642,6 +677,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
- 		mt7996_tm_rf_test_event(dev, skb);
- 		break;
- #endif
-+	case MCU_UNI_EVENT_RRO:
-+		mt7996_mcu_rx_rro(dev, skb);
-+		break;
- 	default:
- 		break;
- 	}
-@@ -4651,6 +4689,31 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
- 				 &req, sizeof(req), false);
- }
- 
-+int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev,
-+					 u16 wcid, u8 tid, u8 pid)
-+{
-+	struct {
-+		/* fixed field */
-+		u8 __rsv[4];
-+
-+		__le16 tag;
-+		__le16 len;
-+		u16 wcid;
-+		u8 tid;
-+		u8 partial_id;
-+		u8 pad[4];
-+	} __packed req = {
-+		.tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
-+		.len = cpu_to_le16(sizeof(req) - 4),
-+		.wcid = wcid,
-+		.tid = tid,
-+		.partial_id = pid,
-+	};
-+
-+	return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(RRO),
-+				 &req, sizeof(req), true);
-+}
-+
- int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data)
- {
- 	struct mt7996_dev *dev = phy->dev;
-diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 7ab84029e..660823402 100644
---- a/mt7996/mcu.h
-+++ b/mt7996/mcu.h
-@@ -242,6 +242,38 @@ struct mt7996_mcu_all_sta_info_event {
- 	};
- } __packed;
- 
-+struct mt7996_mcu_rro_event {
-+	struct mt7996_mcu_rxd rxd;
-+
-+	u8 __rsv1[4];
-+
-+	__le16 tag;
-+	__le16 len;
-+} __packed;
-+
-+struct mt7996_mcu_rro_ba {
-+	struct mt7996_mcu_rro_event event;
-+
-+	u16 wlan_id;
-+	u8 tid;
-+	u8 partial_id;
-+	__le32 status;
-+}__packed;
-+
-+enum  {
-+	UNI_RRO_BA_SESSION_STATUS = 0,
-+	UNI_RRO_BA_SESSION_TBL	= 1,
-+	UNI_RRO_BA_SESSION_MAX_NUM
-+};
-+
-+struct mt7996_mcu_rro_del_ba {
-+	struct mt7996_mcu_rro_event event;
-+
-+	u8  wlan_idx;
-+	u8  tid;
-+	u8 __rsv2[2];
-+};
-+
- enum mt7996_chan_mib_offs {
- 	UNI_MIB_OBSS_AIRTIME = 26,
- 	UNI_MIB_NON_WIFI_TIME = 27,
-@@ -844,6 +876,8 @@ enum {
- 	UNI_RRO_GET_BA_SESSION_TABLE,
- 	UNI_RRO_SET_BYPASS_MODE,
- 	UNI_RRO_SET_TXFREE_PATH,
-+	UNI_RRO_DEL_BA_SESSION,
-+	UNI_RRO_SET_FLUSH_TIMEOUT
- };
- 
- enum{
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index c15e926a7..eb4b315a0 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -254,6 +254,28 @@ struct mt7996_rro_addr {
- 	u32 signature	: 8;
- };
- 
-+struct mt7996_rro_ba_session {
-+	u32 ack_sn         :12;
-+	u32 win_sz         :3;
-+	u32 bn             :1;
-+	u32 last_in_sn     :12;
-+	u32 bc             :1;
-+	u32 bd             :1;
-+	u32 sat            :1;
-+	u32 cn             :1;
-+	u32 within_cnt     :12;
-+	u32 to_sel         :3;
-+	u32 rsv            :1;
-+	u32 last_in_rxtime :12;
-+};
-+
-+struct mt7996_rro_ba_session_elem {
-+	struct list_head poll_list;
-+	u16 wlan_idx;
-+	u8 tid;
-+	u8 partial_id;
-+};
-+
- struct mt7996_rro_cfg {
- 	u32 ind_signature;
- 	void *ba_bitmap_cache_va[MT7996_RRO_BA_BITMAP_CR_CNT];
-@@ -268,6 +290,11 @@ struct mt7996_rro_cfg {
- 	spinlock_t lock;
- 	struct list_head pg_addr_cache;
- 	struct list_head pg_hash_head[MT7996_RRO_MSDU_PG_HASH_SIZE];
-+
-+	struct delayed_work rro_del_work;
-+	spinlock_t rro_stbl_lock;
-+	struct list_head rro_poll_list;
-+	u16 elem_nums;
- };
- 
- struct mt7996_phy {
-@@ -623,6 +650,8 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
- int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
- int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
- int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
-+int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev,
-+				     u16 wcid, u8 tid, u8 pid);
- int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
- int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
- int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
-@@ -721,6 +750,9 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- 			  struct mt76_tx_info *tx_info);
- void mt7996_tx_token_put(struct mt7996_dev *dev);
- int mt7996_dma_rro_init(struct mt7996_dev *dev);
-+void  mt7996_rro_delete_sessions(struct work_struct *work);
-+int mt7996_rro_add_delete_elem(struct mt7996_dev *dev,
-+			       struct mt7996_sta *msta, u8 tid);
- void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
- 			 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 c34357c3e..5577c9348 100644
---- a/mt7996/regs.h
-+++ b/mt7996/regs.h
-@@ -72,6 +72,11 @@ enum base_rev {
- #define MT_RRO_ACK_SN_CTRL_SN_MASK		GENMASK(27, 16)
- #define MT_RRO_ACK_SN_CTRL_SESSION_MASK		GENMASK(11, 0)
- 
-+#define MT_RRO_DBG_RD_CTRL			MT_RRO_TOP(0xe0)
-+#define MT_RRO_DBG_RD_ADDR			GENMASK(15, 0)
-+#define MT_RRO_DBG_RD_EXEC			BIT(31)
-+
-+#define MT_RRO_DBG_RDAT_DW(_n)			MT_RRO_TOP(0xf0 + _n * 0x4)
- 
- #define MT_MCU_INT_EVENT			0x2108
- #define MT_MCU_INT_EVENT_DMA_STOPPED		BIT(0)
--- 
-2.39.2
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2009-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
similarity index 82%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2009-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
index 45262ae..2688d54 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2009-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2008-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch
@@ -1,7 +1,7 @@
-From aa5ba9b452355d0bd7d76868753c66a88464318c Mon Sep 17 00:00:00 2001
+From 50c902b8856af271bc5514d623ad09f7c3f2d880 Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Wed, 19 Jul 2023 10:55:09 +0800
-Subject: [PATCH 2009/2012] wifi: mt76: mt7915: wed: find rx token by physical
+Subject: [PATCH 72/98] 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
@@ -14,10 +14,10 @@
  1 file changed, 25 insertions(+), 2 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index bfe188134..415121f74 100644
+index 141a97b..3983ebb 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -441,10 +441,33 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -440,10 +440,33 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  	}
  
  	if (mt76_queue_is_wed_rx(q)) {
@@ -52,7 +52,7 @@
  		if (!r)
  			return NULL;
  
-@@ -972,7 +995,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -965,7 +988,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
  		if (!data)
  			break;
  
@@ -62,5 +62,5 @@
  
  		if (q->rx_head)
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2010-wifi-mt76-drop-packet-based-on-ind_reason.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch
similarity index 83%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2010-wifi-mt76-drop-packet-based-on-ind_reason.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch
index 2e80514..675e4eb 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2010-wifi-mt76-drop-packet-based-on-ind_reason.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2009-wifi-mt76-drop-packet-based-on-ind_reason.patch
@@ -1,7 +1,7 @@
-From 508070a74e55bbdc06b8865736301f568feb8e9f Mon Sep 17 00:00:00 2001
+From f322c87d1e0634ec86acb5b254220918842132c6 Mon Sep 17 00:00:00 2001
 From: Peter Chiu <chui-hao.chiu@mediatek.com>
 Date: Wed, 26 Jul 2023 16:33:43 +0800
-Subject: [PATCH 2010/2012] wifi: mt76: drop packet based on ind_reason
+Subject: [PATCH 73/98] wifi: mt76: drop packet based on ind_reason
 
 Driver should drop packet which ind_reason is REPEAT and OLDPKT.
 
@@ -13,10 +13,10 @@
  2 files changed, 22 insertions(+), 2 deletions(-)
 
 diff --git a/dma.c b/dma.c
-index 415121f74..7e3d0393b 100644
+index 3983ebb..69e314a 100644
 --- a/dma.c
 +++ b/dma.c
-@@ -436,8 +436,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+@@ -435,8 +435,19 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
  
  	if (drop) {
  		*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
@@ -39,7 +39,7 @@
  
  	if (mt76_queue_is_wed_rx(q)) {
 diff --git a/dma.h b/dma.h
-index 480370928..f83604537 100644
+index 22b79d5..afcbcdd 100644
 --- a/dma.h
 +++ b/dma.h
 @@ -23,6 +23,7 @@
@@ -51,9 +51,9 @@
  
  #define MT_DMA_CTL_PN_CHK_FAIL		BIT(13)
 @@ -31,6 +32,7 @@
- #define MT_DMA_MAGIC_EN		BIT(13)
+ #define MT_DMA_RRO_EN		BIT(13)
  
- #define MT_DMA_IND_CMD_MAGIC_CNT	8
+ #define MT_DMA_WED_IND_CMD_CNT		8
 +#define MT_DMA_IND_REASON		GENMASK(15, 12)
  
  #define MT_DMA_HDR_LEN			4
@@ -73,5 +73,5 @@
  void mt76_dma_attach(struct mt76_dev *dev);
  void mt76_dma_cleanup(struct mt76_dev *dev);
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2011-wifi-mt76-mt7996-add-rro-timeout-setting.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch
similarity index 79%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2011-wifi-mt76-mt7996-add-rro-timeout-setting.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch
index 5a34171..6fe2cea 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2011-wifi-mt76-mt7996-add-rro-timeout-setting.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2010-wifi-mt76-mt7996-add-rro-timeout-setting.patch
@@ -1,7 +1,7 @@
-From 5bf92814ff8cf9e78b5b72db73dc3271097a236d Mon Sep 17 00:00:00 2001
+From 531d586b936634fad23651d18d2bbc832692c520 Mon Sep 17 00:00:00 2001
 From: "sujuan.chen" <sujuan.chen@mediatek.com>
 Date: Fri, 11 Aug 2023 18:26:39 +0800
-Subject: [PATCH 2011/2012] wifi: mt76: mt7996: add rro timeout setting
+Subject: [PATCH 74/98] wifi: mt76: mt7996: add rro timeout setting
 
 Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
 ---
@@ -12,13 +12,13 @@
  4 files changed, 18 insertions(+), 2 deletions(-)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 43a49d42a..8a415fb34 100644
+index 1ece390..51649dd 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -503,6 +503,11 @@ void mt7996_mac_init(struct mt7996_dev *dev)
+@@ -506,6 +506,11 @@ void mt7996_mac_init(struct mt7996_dev *dev)
  	/* rro module init */
  	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
- 	if (dev->rro_support) {
+ 	if (dev->has_rro) {
 +		u16 timeout;
 +
 +		timeout = mt76_rr(dev, MT_HW_REV) == MT_HW_VER1 ? 512 : 128;
@@ -28,7 +28,7 @@
  		mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
  	} else {
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6c106d8cf..a4c6cd5cf 100644
+index ce38a5e..bebd020 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
 @@ -4626,7 +4626,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev)
@@ -64,24 +64,24 @@
  		return -EINVAL;
  	}
 diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index eb4b315a0..6278d3045 100644
+index af67c59..06e00f4 100644
 --- a/mt7996/mt7996.h
 +++ b/mt7996/mt7996.h
-@@ -649,7 +649,7 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
+@@ -676,7 +676,7 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
  				    u16 rate_idx, bool beacon);
  int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
  int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
 -int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
 +int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val);
- int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev,
- 				     u16 wcid, u8 tid, u8 pid);
+ int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev, u16 seid);
  int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
 diff --git a/mt7996/regs.h b/mt7996/regs.h
-index 5577c9348..37d24b9b6 100644
+index a0b5270..77a2f9d 100644
 --- a/mt7996/regs.h
 +++ b/mt7996/regs.h
-@@ -637,6 +637,8 @@ enum base_rev {
- #define MT_PAD_GPIO_ADIE_COMB			GENMASK(16, 15)
+@@ -667,6 +667,8 @@ enum offs_rev {
+ #define MT_PAD_GPIO_ADIE_NUM_7992		BIT(15)
  
  #define MT_HW_REV				0x70010204
 +#define MT_HW_VER1				0x8a00
@@ -90,5 +90,5 @@
  
  /* PCIE MAC */
 -- 
-2.39.2
+2.18.0
 
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch
new file mode 100644
index 0000000..fec02ea
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2011-wifi-mt76-mt7996-add-dma-mask-limitation.patch
@@ -0,0 +1,84 @@
+From 39a1bb49d83141f79bf329fdd68e82bb77f5d0a2 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 20 Jul 2023 10:25:50 +0800
+Subject: [PATCH 75/98] wifi: mt76: mt7996: add dma mask limitation
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ dma.c         | 4 ++--
+ mmio.c        | 3 ++-
+ mt7996/mmio.c | 8 --------
+ mt7996/pci.c  | 2 +-
+ 4 files changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 69e314a..7616921 100644
+--- a/dma.c
++++ b/dma.c
+@@ -494,7 +494,7 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 		} else {
+ 			struct mt76_queue_buf qbuf;
+ 
+-			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
+ 			if (!buf)
+ 				return NULL;
+ 
+@@ -713,7 +713,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ 		if (mt76_queue_is_wed_rro_ind(q))
+ 			goto done;
+ 
+-		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
+ 		if (!buf)
+ 			break;
+ 
+diff --git a/mmio.c b/mmio.c
+index f7495f6..22629af 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -150,7 +150,8 @@ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ 		if (!r)
+ 			goto unmap;
+ 
+-		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, GFP_ATOMIC);
++		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
++				      GFP_ATOMIC | GFP_DMA32);
+ 		if (!ptr) {
+ 			mt76_put_rxwi(dev, r);
+  			goto unmap;
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 631d905..38b8843 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -442,14 +442,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 	*irq = wed->irq;
+ 	dev->mt76.dma_dev = wed->dev;
+ 
+-	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
+-	if (ret)
+-		return ret;
+-
+-	ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
+-	if (ret)
+-		return ret;
+-
+ 	return 1;
+ #else
+ 	return 0;
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 2bb707d..0024929 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -111,7 +111,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ 
+ 	pci_set_master(pdev);
+ 
+-	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
++	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ 	if (ret)
+ 		return ret;
+ 
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2012-wifi-mt76-mt7996-add-dma-mask-limitation.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2012-wifi-mt76-mt7996-add-dma-mask-limitation.patch
deleted file mode 100644
index 5ff3139..0000000
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2012-wifi-mt76-mt7996-add-dma-mask-limitation.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 655b23a24e07980cecd4f09e8779dfc9f69bff51 Mon Sep 17 00:00:00 2001
-From: "sujuan.chen" <sujuan.chen@mediatek.com>
-Date: Thu, 20 Jul 2023 10:25:50 +0800
-Subject: [PATCH 2012/2012] wifi: mt76: mt7996: add dma mask limitation
-
-Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
----
- dma.c         |  4 ++--
- mt7996/mmio.c | 10 +---------
- mt7996/pci.c  |  2 +-
- 3 files changed, 4 insertions(+), 12 deletions(-)
-
-diff --git a/dma.c b/dma.c
-index 7e3d0393b..81412deb1 100644
---- a/dma.c
-+++ b/dma.c
-@@ -495,7 +495,7 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- 		} else {
- 			struct mt76_queue_buf qbuf;
- 
--			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
-+			buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
- 			if (!buf)
- 				return NULL;
- 
-@@ -714,7 +714,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
- 		if (mt76_queue_is_rro_ind(q))
- 			goto done;
- 
--		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
-+		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC | GFP_DMA32);
- 		if (!buf)
- 			break;
- 
-diff --git a/mt7996/mmio.c b/mt7996/mmio.c
-index 940f94998..7a1d81447 100644
---- a/mt7996/mmio.c
-+++ b/mt7996/mmio.c
-@@ -286,7 +286,7 @@ static u32 mt7996_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
- 		void *ptr;
- 
- 		ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
--				      GFP_KERNEL);
-+				      GFP_ATOMIC | GFP_DMA32);
- 		if (!ptr) {
- 			mt76_put_rxwi(&dev->mt76, r);
- 			goto unmap;
-@@ -501,14 +501,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
- 
- 	dev->mt76.token_size = MT7996_SW_TOKEN_SIZE;
- 
--	ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
--	if (ret)
--		return ret;
--
--	ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
--	if (ret)
--		return ret;
--
- 	return 1;
- #else
- 	return 0;
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 9a134fcab..993e53817 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -107,7 +107,7 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
- 
- 	pci_set_master(pdev);
- 
--	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- 	if (ret)
- 		return ret;
- 
--- 
-2.39.2
-
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2013-wifi-mt76-mt7996-add-per-bss-statistic-info.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
similarity index 86%
rename from autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2013-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
rename to autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
index fe8d166..3295f14 100644
--- a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2013-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2012-wifi-mt76-mt7996-add-per-bss-statistic-info.patch
@@ -1,7 +1,7 @@
-From 3cee39db21222ca86581819f72fcc4839dfea429 Mon Sep 17 00:00:00 2001
+From d97655d3fe3ddf2bbd508de52e207bc91d0115e2 Mon Sep 17 00:00:00 2001
 From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
 Date: Fri, 18 Aug 2023 10:17:08 +0800
-Subject: [PATCH] wifi: mt76: mt7996: add per bss statistic info
+Subject: [PATCH 76/98] wifi: mt76: mt7996: add per bss statistic info
 
 Whenever WED is enabled, unicast traffic might run through HW path.
 As a result, we need to count them using WM event.
@@ -22,10 +22,10 @@
  3 files changed, 37 insertions(+), 5 deletions(-)
 
 diff --git a/mt7996/init.c b/mt7996/init.c
-index 1cdf81a..6b30820 100644
+index 51649dd..20e14e7 100644
 --- a/mt7996/init.c
 +++ b/mt7996/init.c
-@@ -375,6 +375,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+@@ -378,6 +378,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
  	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);
@@ -34,10 +34,10 @@
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION);
  	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
 diff --git a/mt7996/main.c b/mt7996/main.c
-index 52e9666..a8ed204 100644
+index d27275a..2e0b1f1 100644
 --- a/mt7996/main.c
 +++ b/mt7996/main.c
-@@ -254,6 +254,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
+@@ -251,6 +251,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
  	mvif->sta.wcid.phy_idx = band_idx;
  	mvif->sta.wcid.hw_key_idx = -1;
  	mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;
@@ -46,10 +46,10 @@
  
  	mt7996_mac_wtbl_update(dev, idx,
 diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index a4c6cd5..0653882 100644
+index bebd020..b2cb627 100644
 --- a/mt7996/mcu.c
 +++ b/mt7996/mcu.c
-@@ -552,6 +552,27 @@ static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -592,6 +592,27 @@ static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
  
  }
  
@@ -77,7 +77,7 @@
  static void
  mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  {
-@@ -567,7 +588,7 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -607,7 +628,7 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  		u16 wlan_idx;
  		struct mt76_wcid *wcid;
  		struct mt76_phy *mphy;
@@ -86,7 +86,7 @@
  
  		switch (le16_to_cpu(res->tag)) {
  		case UNI_ALL_STA_TXRX_RATE:
-@@ -595,6 +616,9 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -635,6 +656,9 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  				wcid->stats.tx_bytes += tx_bytes;
  				wcid->stats.rx_bytes += rx_bytes;
  
@@ -96,7 +96,7 @@
  				ieee80211_tpt_led_trig_tx(mphy->hw, tx_bytes);
  				ieee80211_tpt_led_trig_rx(mphy->hw, rx_bytes);
  			}
-@@ -606,10 +630,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -646,10 +670,16 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
  			if (!wcid)
  				break;
  
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch
new file mode 100644
index 0000000..8dd2d61
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2013-wifi-mt76-mt7996-support-TX-RX-for-Kite-without-WED-.patch
@@ -0,0 +1,234 @@
+From bd93ad7026e316307453438f4b7bce59e30bf03e Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Wed, 7 Jun 2023 14:11:28 +0800
+Subject: [PATCH 77/98] wifi: mt76: mt7996: support TX/RX for Kite without WED
+ and RRO
+
+Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76_connac3_mac.h |  3 ++-
+ mt7996/dma.c       | 61 +++++++++++++++++++++++++++++++++++++---------
+ mt7996/init.c      | 10 ++++++--
+ mt7996/mac.c       |  7 ++++--
+ mt7996/mt7996.h    |  4 +--
+ mt7996/regs.h      |  4 +--
+ 6 files changed, 68 insertions(+), 21 deletions(-)
+
+diff --git a/mt76_connac3_mac.h b/mt76_connac3_mac.h
+index 7402de2..3fd46ae 100644
+--- a/mt76_connac3_mac.h
++++ b/mt76_connac3_mac.h
+@@ -244,7 +244,8 @@ enum tx_mgnt_type {
+ #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_MSDU_CNT_MT7996		GENMASK(9, 4)
++#define MT_TXD6_MSDU_CNT_MT7992		GENMASK(15, 10)
+ #define MT_TXD6_DIS_MAT			BIT(3)
+ #define MT_TXD6_DAS			BIT(2)
+ #define MT_TXD6_AMSDU_CAP		BIT(1)
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index b2c7ae6..1163550 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -57,13 +57,21 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+ 	RXQ_CONFIG(MT_RXQ_MCU, WFDMA0, MT_INT_RX_DONE_WM, MT7996_RXQ_MCU_WM);
+ 	RXQ_CONFIG(MT_RXQ_MCU_WA, WFDMA0, MT_INT_RX_DONE_WA, MT7996_RXQ_MCU_WA);
+ 
+-	/* band0/band1 */
++	/* MT7996 band0/band1
++	 * MT7992 band0
++	 */
+ 	RXQ_CONFIG(MT_RXQ_MAIN, WFDMA0, MT_INT_RX_DONE_BAND0, MT7996_RXQ_BAND0);
+ 	RXQ_CONFIG(MT_RXQ_MAIN_WA, WFDMA0, MT_INT_RX_DONE_WA_MAIN, MT7996_RXQ_MCU_WA_MAIN);
+ 
+-	/* band2 */
+-	RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
+-	RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
++	if (is_mt7996(&dev->mt76)) {
++		/* MT7996 band2 */
++		RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
++		RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
++	} else {
++		/* MT7992 band1 */
++		RXQ_CONFIG(MT_RXQ_BAND1, WFDMA0, MT_INT_RX_DONE_BAND1, MT7996_RXQ_BAND1);
++		RXQ_CONFIG(MT_RXQ_BAND1_WA, WFDMA0, MT_INT_RX_DONE_WA_EXT, MT7996_RXQ_MCU_WA_EXT);
++	}
+ 
+ 	if (dev->has_rro) {
+ 		/* band0 */
+@@ -90,8 +98,12 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+ 
+ 	/* 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);
+-	TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
++	if (is_mt7996(&dev->mt76)) {
++		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
++		TXQ_CONFIG(2, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
++	} else {
++		TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND2, MT7996_TXQ_BAND2);
++	}
+ 
+ 	/* mcu tx queue */
+ 	MCUQ_CONFIG(MT_MCUQ_WM, WFDMA0, MT_INT_TX_DONE_MCU_WM, MT7996_TXQ_MCU_WM);
+@@ -123,10 +135,15 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
+ 	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));
++	if (is_mt7996(&dev->mt76))
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x2));
++	else
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1_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 (is_mt7996(&dev->mt76))
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x10));
++	else
++		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND1) + ofs, PREFETCH(0x10));
+ 	if (dev->has_rro) {
+ 		mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
+ 			PREFETCH(0x10));
+@@ -488,7 +505,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 	if (ret)
+ 		return ret;
+ 
+-	/* rx data queue for band0 and band1 */
++	/* rx data queue for band0 and MT7996 band1 */
+ 	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed)) {
+ 		dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
+ 		dev->mt76.q_rx[MT_RXQ_MAIN].wed = wed;
+@@ -517,7 +534,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		return ret;
+ 
+ 	if (mt7996_band_valid(dev, MT_BAND2)) {
+-		/* rx data queue for band2 */
++		/* rx data queue for MT7996 band2 */
+ 		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
+ 		if (mtk_wed_device_active(wed_hif2) && mtk_wed_get_rx_capa(wed_hif2)) {
+ 			dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(0);
+@@ -531,7 +548,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 		if (ret)
+ 			return ret;
+ 
+-		/* tx free notify event from WA for band2
++		/* tx free notify event from WA for MT7996 band2
+ 		 * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
+ 		 */
+ 		if (mtk_wed_device_active(wed_hif2) && !dev->has_rro) {
+@@ -546,6 +563,26 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ 				       MT_RXQ_RING_BASE(MT_RXQ_BAND2_WA));
+ 		if (ret)
+ 			return ret;
++	} else if (mt7996_band_valid(dev, MT_BAND1)) {
++		/* rx data queue for MT7992 band1 */
++		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1) + hif1_ofs;
++		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1],
++				       MT_RXQ_ID(MT_RXQ_BAND1),
++				       MT7996_RX_RING_SIZE,
++				       MT_RX_BUF_SIZE,
++				       rx_base);
++		if (ret)
++			return ret;
++
++		/* tx free notify event from WA for MT7992 band1 */
++		rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND1_WA) + hif1_ofs;
++		ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND1_WA],
++				       MT_RXQ_ID(MT_RXQ_BAND1_WA),
++				       MT7996_RX_MCU_RING_SIZE,
++				       MT_RX_BUF_SIZE,
++				       rx_base);
++		if (ret)
++			return ret;
+ 	}
+ 
+ 	if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 20e14e7..d539af0 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -505,7 +505,12 @@ void mt7996_mac_init(struct mt7996_dev *dev)
+ 	mt76_rmw_field(dev, MT_DMA_TCRF1(2), MT_DMA_TCRF1_QIDX, 0);
+ 
+ 	/* rro module init */
+-	mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
++	if (is_mt7996(&dev->mt76))
++		mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
++	else
++		mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE,
++				   dev->hif2 ? 7 : 0);
++
+ 	if (dev->has_rro) {
+ 		u16 timeout;
+ 
+@@ -562,7 +567,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 	if (phy)
+ 		return 0;
+ 
+-	if (band == MT_BAND2 && dev->hif2) {
++	if ((is_mt7996(&dev->mt76) && band == MT_BAND2 && dev->hif2) ||
++	    (is_mt7992(&dev->mt76) && band == MT_BAND1 && dev->hif2)) {
+ 		hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+ 		wed = &dev->mt76.mmio.wed_hif2;
+ 	}
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 22cff71..a92298d 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -878,8 +878,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ 		val |= MT_TXD5_TX_STATUS_HOST;
+ 	txwi[5] = cpu_to_le32(val);
+ 
+-	val = MT_TXD6_DIS_MAT | MT_TXD6_DAS |
+-	      FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
++	val = MT_TXD6_DIS_MAT | MT_TXD6_DAS;
++	if (is_mt7996(&dev->mt76))
++		val |= FIELD_PREP(MT_TXD6_MSDU_CNT_MT7996, 1);
++	else
++		val |= FIELD_PREP(MT_TXD6_MSDU_CNT_MT7992, 1);
+ 	txwi[6] = cpu_to_le32(val);
+ 	txwi[7] = 0;
+ 
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 06e00f4..4333d51 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -152,10 +152,10 @@ enum mt7996_rxq_id {
+ 	MT7996_RXQ_MCU_WM = 0,
+ 	MT7996_RXQ_MCU_WA,
+ 	MT7996_RXQ_MCU_WA_MAIN = 2,
+-	MT7996_RXQ_MCU_WA_EXT = 2,/* unused */
++	MT7996_RXQ_MCU_WA_EXT = 3, /* Only used by MT7992. */
+ 	MT7996_RXQ_MCU_WA_TRI = 3,
+ 	MT7996_RXQ_BAND0 = 4,
+-	MT7996_RXQ_BAND1 = 4,/* unused */
++	MT7996_RXQ_BAND1 = 5, /* Only used by MT7992. */
+ 	MT7996_RXQ_BAND2 = 5,
+ 	MT7996_RXQ_RRO_BAND0 = 8,
+ 	MT7996_RXQ_RRO_BAND1 = 8,/* unused */
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 77a2f9d..c9e90e3 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -491,12 +491,12 @@ enum offs_rev {
+ #define MT_INT1_MASK_CSR			MT_WFDMA0_PCIE1(0x204)
+ 
+ #define MT_INT_RX_DONE_BAND0			BIT(12)
+-#define MT_INT_RX_DONE_BAND1			BIT(12)
++#define MT_INT_RX_DONE_BAND1			BIT(13) /* Only used by MT7992. */
+ #define MT_INT_RX_DONE_BAND2			BIT(13)
+ #define MT_INT_RX_DONE_WM			BIT(0)
+ #define MT_INT_RX_DONE_WA			BIT(1)
+ #define MT_INT_RX_DONE_WA_MAIN			BIT(2)
+-#define MT_INT_RX_DONE_WA_EXT			BIT(2)
++#define MT_INT_RX_DONE_WA_EXT			BIT(3) /* Only used by MT7992. */
+ #define MT_INT_RX_DONE_WA_TRI			BIT(3)
+ #define MT_INT_RX_TXFREE_MAIN			BIT(17)
+ #define MT_INT_RX_TXFREE_TRI			BIT(15)
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
new file mode 100644
index 0000000..a581775
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2014-wifi-mt76-mt7996-add-support-for-HW-ATF-initializati.patch
@@ -0,0 +1,528 @@
+From dda3205c68ab3b38945f0066be5fc95ba067f3af Mon Sep 17 00:00:00 2001
+From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
+Date: Mon, 11 Sep 2023 16:35:15 +0800
+Subject: [PATCH 78/98] wifi: mt76: mt7996: add support for HW-ATF
+ initialization
+
+---
+ mt7996/init.c   |  43 ++++++++
+ mt7996/mcu.c    | 263 +++++++++++++++++++++++++++++++++++++++++++-----
+ mt7996/mcu.h    |   1 +
+ mt7996/mt7996.h |  94 +++++++++++++++++
+ 4 files changed, 376 insertions(+), 25 deletions(-)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index d539af0..d1db1d7 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -553,6 +553,37 @@ int mt7996_txbf_init(struct mt7996_dev *dev)
+ 	return mt7996_mcu_set_txbf(dev, BF_HW_EN_UPDATE);
+ }
+ 
++static int mt7996_vow_init(struct mt7996_phy *phy)
++{
++	struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++	int ret;
++
++	vow->atf_enable = true;
++	vow->watf_enable = false;
++	vow->max_deficit = 64;
++	vow->sch_type = VOW_SCH_TYPE_FOLLOW_POLICY;
++	vow->sch_policy = VOW_SCH_POLICY_SRR;
++
++	vow->drr_quantum[0] = VOW_DRR_QUANTUM_L0;
++	vow->drr_quantum[1] = VOW_DRR_QUANTUM_L1;
++	vow->drr_quantum[2] = VOW_DRR_QUANTUM_L2;
++	vow->drr_quantum[3] = VOW_DRR_QUANTUM_L3;
++	vow->drr_quantum[4] = VOW_DRR_QUANTUM_L4;
++	vow->drr_quantum[5] = VOW_DRR_QUANTUM_L5;
++	vow->drr_quantum[6] = VOW_DRR_QUANTUM_L6;
++	vow->drr_quantum[7] = VOW_DRR_QUANTUM_L7;
++
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND);
++	if (ret)
++		return ret;
++
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, NULL, VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL);
++	if (ret)
++		return ret;
++
++	return mt7996_mcu_set_vow_feature_ctrl(phy);
++}
++
+ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 			       enum mt76_band_id band)
+ {
+@@ -626,6 +657,12 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ 	if (ret)
+ 		goto error;
+ 
++	if (mt7996_vow_should_enable(dev)) {
++		ret = mt7996_vow_init(phy);
++		if (ret)
++			goto error;
++	}
++
+ 	ret = mt7996_init_debugfs(phy);
+ 	if (ret)
+ 		goto error;
+@@ -1315,6 +1352,12 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ 
+ 	dev->recovery.hw_init_done = true;
+ 
++	if (mt7996_vow_should_enable(dev)) {
++		ret = mt7996_vow_init(&dev->phy);
++		if (ret)
++			goto error;
++	}
++
+ 	ret = mt7996_init_debugfs(&dev->phy);
+ 	if (ret)
+ 		goto error;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index b2cb627..1915a22 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2147,34 +2147,35 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ }
+ 
+ static int
+-mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+-		     struct ieee80211_sta *sta)
++mt7996_mcu_sta_init_vow(struct mt7996_phy *phy, struct mt7996_sta *msta)
+ {
+-#define MT_STA_BSS_GROUP		1
+-	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+-	struct mt7996_sta *msta;
+-	struct {
+-		u8 __rsv1[4];
++	struct mt7996_vow_sta_ctrl *vow = &msta->vow;
++	u8 omac_idx = msta->vif->mt76.omac_idx;
++	int ret;
+ 
+-		__le16 tag;
+-		__le16 len;
+-		__le16 wlan_idx;
+-		u8 __rsv2[2];
+-		__le32 action;
+-		__le32 val;
+-		u8 __rsv3[8];
+-	} __packed req = {
+-		.tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
+-		.len = cpu_to_le16(sizeof(req) - 4),
+-		.action = cpu_to_le32(MT_STA_BSS_GROUP),
+-		.val = cpu_to_le32(mvif->mt76.idx % 16),
+-	};
++	/* Assignment of STA BSS group index aligns FW.
++	 * Each band has its own BSS group bitmap space.
++	 * 0: BSS 0
++	 * 4..18: BSS 0x11..0x1f
++	 */
++	vow->bss_grp_idx = (omac_idx <= HW_BSSID_MAX)
++	                   ? omac_idx
++	                   : HW_BSSID_MAX + omac_idx - EXT_BSSID_START;
++	vow->paused = false;
++	vow->drr_quantum[IEEE80211_AC_VO] = VOW_DRR_QUANTUM_IDX0;
++	vow->drr_quantum[IEEE80211_AC_VI] = VOW_DRR_QUANTUM_IDX1;
++	vow->drr_quantum[IEEE80211_AC_BE] = VOW_DRR_QUANTUM_IDX2;
++	vow->drr_quantum[IEEE80211_AC_BK] = VOW_DRR_QUANTUM_IDX2;
++
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_BSS_GROUP);
++	if (ret)
++		return ret;
+ 
+-	msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;
+-	req.wlan_idx = cpu_to_le16(msta->wcid.idx);
++	ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_PAUSE);
++	if (ret)
++		return ret;
+ 
+-	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
+-				 sizeof(req), true);
++	return mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_ALL);
+ }
+ 
+ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -2228,7 +2229,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ 		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);
+ 	}
+ 
+-	ret = mt7996_mcu_add_group(dev, vif, sta);
++	ret = mt7996_mcu_sta_init_vow(mvif->phy, msta);
+ 	if (ret) {
+ 		dev_kfree_skb(skb);
+ 		return ret;
+@@ -5027,6 +5028,218 @@ int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
+ 				     MCU_WM_UNI_CMD(TXPOWER), true);
+ }
+ 
++int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
++	                        enum vow_drr_ctrl_id id)
++{
++	struct mt7996_vow_sta_ctrl *vow = msta ? &msta->vow : NULL;
++	u32 val = 0;
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++		__le16 wlan_idx;
++		u8 band_idx;
++		u8 wmm_idx;
++		__le32 ctrl_id;
++
++		union {
++			__le32 val;
++			u8 drr_quantum[VOW_DRR_QUANTUM_NUM];
++		};
++
++		u8 __rsv2[3];
++		u8 omac_idx;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_VOW_DRR_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.wlan_idx = cpu_to_le16(msta ? msta->wcid.idx : 0),
++		.band_idx = phy->mt76->band_idx,
++		.wmm_idx = msta ? msta->vif->mt76.wmm_idx : 0,
++		.ctrl_id = cpu_to_le32(id),
++		.omac_idx = msta ? msta->vif->mt76.omac_idx : 0
++	};
++
++	switch (id) {
++	case VOW_DRR_CTRL_STA_ALL:
++		val |= FIELD_PREP(MT7996_DRR_STA_BSS_GRP_MASK, vow->bss_grp_idx);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC0_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_BK]);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC1_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_BE]);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC2_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_VI]);
++		val |= FIELD_PREP(MT7996_DRR_STA_AC3_QNTM_MASK, vow->drr_quantum[IEEE80211_AC_VO]);
++		req.val = cpu_to_le32(val);
++		break;
++	case VOW_DRR_CTRL_STA_BSS_GROUP:
++		req.val = cpu_to_le32(vow->bss_grp_idx);
++		break;
++	case VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND:
++		req.val = cpu_to_le32(phy->dev->vow.max_deficit);
++		break;
++	case VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL:
++		memcpy(req.drr_quantum, phy->dev->vow.drr_quantum, VOW_DRR_QUANTUM_NUM);
++		break;
++	case VOW_DRR_CTRL_STA_PAUSE:
++		req.val = cpu_to_le32(vow->paused);
++		break;
++	default:
++		dev_err(phy->dev->mt76.dev, "Unknown VoW DRR Control ID: %u\n", id);
++		return -EINVAL;
++	}
++
++	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(VOW),
++	                         &req, sizeof(req), true);
++}
++
++int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy)
++{
++	struct mt7996_vow_ctrl *vow = &phy->dev->vow;
++	struct {
++		u8 __rsv1[4];
++
++		__le16 tag;
++		__le16 len;
++
++		/* DW0 */
++		__le16 apply_bwc_enable_per_grp;
++		__le16 apply_bwc_refill_period		: 1;
++		__le16 __rsv2				: 3;
++		__le16 apply_band1_search_rule		: 1;
++		__le16 apply_band0_search_rule		: 1;
++		__le16 __rsv3				: 3;
++		__le16 apply_watf_enable		: 1;
++		__le16 __rsv4				: 2;
++		__le16 apply_grp_no_change_in_txop	: 1;
++		__le16 apply_atf_enable			: 1;
++		__le16 apply_bwc_token_refill_enable	: 1;
++		__le16 apply_bwc_enable			: 1;
++
++		/* DW1 */
++		__le16 apply_bwc_check_time_token_per_grp;
++		__le16 __rsv5;
++
++		/* DW2 */
++		__le16 apply_bwc_check_len_token_per_grp;
++		__le16 __rsv6;
++
++		/* DW3 */
++		u8 band_idx;
++		u8 __rsv7[3];
++
++		/* DW4 */
++		__le32 __rsv8;
++
++		/* DW5 */
++		__le16 bwc_enable_per_grp;
++		__le16 bwc_refill_period	: 3;
++		__le16 __rsv9			: 1;
++		__le16 band1_search_rule	: 1;
++		__le16 band0_search_rule	: 1;
++		__le16 __rsv10			: 3;
++		__le16 watf_enable		: 1;
++		__le16 __rsv11			: 2;
++		__le16 grp_no_change_in_txop	: 1;
++		__le16 atf_enable		: 1;
++		__le16 bwc_token_refill_enable	: 1;
++		__le16 bwc_enable		: 1;
++
++		/* DW6 */
++		__le16 bwc_check_time_token_per_grp;
++		__le16 __rsv12;
++
++		/* DW7 */
++		__le16 bwc_check_len_token_per_grp;
++		__le16 __rsv13;
++
++		/* DW8 */
++		__le32 apply_atf_rts_sta_lock		: 1;
++		__le32 atf_rts_sta_lock			: 1;
++		__le32 apply_atf_keep_quantum		: 1;
++		__le32 atf_keep_quantum			: 1;
++		__le32 apply_tx_cnt_mode_ctrl		: 1;
++		__le32 tx_cnt_mode_ctrl			: 4;
++		__le32 apply_tx_measure_mode_enable	: 1;
++		__le32 tx_measure_mode_enable		: 1;
++		__le32 apply_backoff_ctrl		: 1;
++		__le32 backoff_bound_enable		: 1;
++		__le32 backoff_bound			: 5;
++		__le32 apply_atf_rts_fail_charge	: 1;
++		__le32 atf_rts_fail_charge		: 1;
++		__le32 apply_zero_eifs			: 1;
++		__le32 zero_eifs			: 1;
++		__le32 apply_rx_rifs_enable		: 1;
++		__le32 rx_rifs_enable			: 1;
++		__le32 apply_vow_ctrl			: 1;
++		__le32 vow_ctrl_val			: 1;
++		__le32 vow_ctrl_bit			: 5;
++		__le32 __rsv14				: 1;
++
++		/* DW9 */
++		__le32 apply_spl_sta_num	: 1;
++		__le32 spl_sta_num		: 3;
++		__le32 dbg_lvl			: 2;
++		__le32 apply_atf_sch_ctrl	: 1;
++		__le32 atf_sch_type		: 2;
++		__le32 atf_sch_policy		: 2;
++		__le32 __rsv15			: 21;
++	} __packed req = {
++		.tag = cpu_to_le16(UNI_VOW_FEATURE_CTRL),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		/* DW0 */
++		.apply_bwc_enable_per_grp = cpu_to_le16(0xffff),
++		.apply_bwc_refill_period = true,
++		.apply_band1_search_rule = true,
++		.apply_band0_search_rule = true,
++		.apply_watf_enable = true,
++		.apply_grp_no_change_in_txop = true,
++		.apply_atf_enable = true,
++		.apply_bwc_token_refill_enable = true,
++		.apply_bwc_enable = true,
++		/* DW1 */
++		.apply_bwc_check_time_token_per_grp = cpu_to_le16(0xffff),
++		/* DW2 */
++		.apply_bwc_check_len_token_per_grp = cpu_to_le16(0xffff),
++		/* DW3 */
++		.band_idx = phy->mt76->band_idx,
++		/* DW5 */
++		.bwc_enable_per_grp = cpu_to_le16(0xffff),
++		.bwc_refill_period = VOW_REFILL_PERIOD_32US,
++		.band1_search_rule = VOW_SEARCH_WMM_FIRST,
++		.band0_search_rule = VOW_SEARCH_WMM_FIRST,
++		.watf_enable = vow->watf_enable,
++		.grp_no_change_in_txop = true,
++		.atf_enable = vow->atf_enable,
++		.bwc_token_refill_enable = true,
++		.bwc_enable = false,
++		/* DW6 */
++		.bwc_check_time_token_per_grp = cpu_to_le16(0x0),
++		/* DW7 */
++		.bwc_check_len_token_per_grp = cpu_to_le16(0x0),
++		/* DW8 */
++		.apply_atf_rts_sta_lock = false,
++		.apply_atf_keep_quantum = true,
++		.atf_keep_quantum = true,
++		.apply_tx_cnt_mode_ctrl = false,
++		.apply_tx_measure_mode_enable = false,
++		.apply_backoff_ctrl = false,
++		.apply_atf_rts_fail_charge = false,
++		.apply_zero_eifs = false,
++		.apply_rx_rifs_enable = false,
++		.apply_vow_ctrl = true,
++		.vow_ctrl_val = true,
++		/* Reset DRR table when SER occurs. */
++		.vow_ctrl_bit = 26,
++		/* DW9 */
++		.apply_spl_sta_num = false,
++		.dbg_lvl = 0,
++		.apply_atf_sch_ctrl = true,
++		.atf_sch_type = vow->sch_type,
++		.atf_sch_policy = vow->sch_policy
++	};
++
++	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(VOW),
++	                         &req, sizeof(req), true);
++}
++
+ #ifdef CONFIG_MTK_VENDOR
+ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+ {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 0aa68f7..fb81645 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -860,6 +860,7 @@ enum {
+ 
+ enum {
+ 	UNI_VOW_DRR_CTRL,
++	UNI_VOW_FEATURE_CTRL,
+ 	UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
+ 	UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
+ 	UNI_VOW_RED_ENABLE = 0x18,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 4333d51..ba73520 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -107,6 +107,12 @@
+ #define MT7996_RX_MSDU_PAGE_SIZE	(128 + \
+ 					 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+ 
++#define MT7996_DRR_STA_BSS_GRP_MASK	GENMASK(5, 0)
++#define MT7996_DRR_STA_AC0_QNTM_MASK	GENMASK(10, 8)
++#define MT7996_DRR_STA_AC1_QNTM_MASK	GENMASK(14, 12)
++#define MT7996_DRR_STA_AC2_QNTM_MASK	GENMASK(18, 16)
++#define MT7996_DRR_STA_AC3_QNTM_MASK	GENMASK(22, 20)
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -187,6 +193,79 @@ struct mt7996_twt_flow {
+ 
+ DECLARE_EWMA(avg_signal, 10, 8)
+ 
++enum {
++	VOW_SEARCH_AC_FIRST,
++	VOW_SEARCH_WMM_FIRST
++};
++
++enum {
++	VOW_REFILL_PERIOD_1US,
++	VOW_REFILL_PERIOD_2US,
++	VOW_REFILL_PERIOD_4US,
++	VOW_REFILL_PERIOD_8US,
++	VOW_REFILL_PERIOD_16US,
++	VOW_REFILL_PERIOD_32US,
++	VOW_REFILL_PERIOD_64US,
++	VOW_REFILL_PERIOD_128US
++};
++
++/* Default DRR airtime quantum of each level */
++enum {
++	VOW_DRR_QUANTUM_L0 = 6,
++	VOW_DRR_QUANTUM_L1 = 12,
++	VOW_DRR_QUANTUM_L2 = 16,
++	VOW_DRR_QUANTUM_L3 = 20,
++	VOW_DRR_QUANTUM_L4 = 24,
++	VOW_DRR_QUANTUM_L5 = 28,
++	VOW_DRR_QUANTUM_L6 = 32,
++	VOW_DRR_QUANTUM_L7 = 36
++};
++
++enum {
++	VOW_DRR_QUANTUM_IDX0,
++	VOW_DRR_QUANTUM_IDX1,
++	VOW_DRR_QUANTUM_IDX2,
++	VOW_DRR_QUANTUM_IDX3,
++	VOW_DRR_QUANTUM_IDX4,
++	VOW_DRR_QUANTUM_IDX5,
++	VOW_DRR_QUANTUM_IDX6,
++	VOW_DRR_QUANTUM_IDX7,
++	VOW_DRR_QUANTUM_NUM
++};
++
++enum {
++	VOW_SCH_TYPE_FOLLOW_POLICY,
++	VOW_SCH_TYPE_FOLLOW_HW
++};
++
++enum {
++	VOW_SCH_POLICY_SRR, /* Shared Round-Robin */
++	VOW_SCH_POLICY_WRR /* Weighted Round-Robin */
++};
++
++enum vow_drr_ctrl_id {
++	VOW_DRR_CTRL_STA_ALL,
++	VOW_DRR_CTRL_STA_BSS_GROUP,
++	VOW_DRR_CTRL_AIRTIME_DEFICIT_BOUND = 0x10,
++	VOW_DRR_CTRL_AIRTIME_QUANTUM_ALL = 0x28,
++	VOW_DRR_CTRL_STA_PAUSE = 0x30
++};
++
++struct mt7996_vow_ctrl {
++	bool atf_enable;
++	bool watf_enable;
++	u8 drr_quantum[VOW_DRR_QUANTUM_NUM];
++	u8 max_deficit;
++	u8 sch_type;
++	u8 sch_policy;
++};
++
++struct mt7996_vow_sta_ctrl {
++	bool paused;
++	u8 bss_grp_idx;
++	u8 drr_quantum[IEEE80211_NUM_ACS];
++};
++
+ struct mt7996_sta {
+ 	struct mt76_wcid wcid; /* must be first */
+ 
+@@ -206,6 +285,8 @@ struct mt7996_sta {
+ 		u8 flowid_mask;
+ 		struct mt7996_twt_flow flow[MT7996_MAX_STA_TWT_AGRT];
+ 	} twt;
++
++	struct mt7996_vow_sta_ctrl vow;
+ };
+ 
+ struct mt7996_vif {
+@@ -470,6 +551,7 @@ struct mt7996_dev {
+ 
+ 	u8 wtbl_size_group;
+ 
++	struct mt7996_vow_ctrl vow;
+ #ifdef CONFIG_MTK_DEBUG
+ 	u16 wlan_idx;
+ 	struct {
+@@ -697,6 +779,10 @@ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ #endif
+ 
++int mt7996_mcu_set_vow_drr_ctrl(struct mt7996_phy *phy, struct mt7996_sta *msta,
++	                        enum vow_drr_ctrl_id id);
++int mt7996_mcu_set_vow_feature_ctrl(struct mt7996_phy *phy);
++
+ static inline u16 mt7996_eeprom_size(struct mt7996_dev *dev)
+ {
+ 	return is_mt7996(&dev->mt76) ? MT7996_EEPROM_SIZE : MT7992_EEPROM_SIZE;
+@@ -749,6 +835,14 @@ static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
+ 	return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
+ }
+ 
++static inline bool
++mt7996_vow_should_enable(struct mt7996_dev *dev)
++{
++	return !wiphy_ext_feature_isset(mt76_hw(dev)->wiphy,
++	                                NL80211_EXT_FEATURE_AIRTIME_FAIRNESS) ||
++	       mtk_wed_device_active(&dev->mt76.mmio.wed);
++}
++
+ void mt7996_mac_init(struct mt7996_dev *dev);
+ u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
+ bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch
new file mode 100644
index 0000000..a6ffa60
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/2999-wifi-mt76-mt7996-support-backaward-compatiable.patch
@@ -0,0 +1,146 @@
+From 52c4cb0df8974126a52d907070fcd3205eb21c28 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Fri, 6 Oct 2023 20:59:42 +0800
+Subject: [PATCH 79/98] wifi: mt76: mt7996: support backaward compatiable
+
+---
+ mmio.c          |  2 +-
+ mt7996/dma.c    |  2 +-
+ mt7996/main.c   |  2 +-
+ mt7996/mcu.c    |  2 +-
+ mt7996/mmio.c   | 20 +++++++++++---------
+ mt7996/mt7996.h |  1 +
+ 6 files changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/mmio.c b/mmio.c
+index 22629af..aa6fe45 100644
+--- a/mmio.c
++++ b/mmio.c
+@@ -134,7 +134,7 @@ EXPORT_SYMBOL_GPL(mt76_mmio_wed_release_rx_buf);
+ u32 mt76_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+ {
+ 	struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
+-	struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc;
++	struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
+ 	u32 length;
+ 	int i;
+ 
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 1163550..326fd4b 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -430,7 +430,7 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev)
+ 	irq_mask = mdev->mmio.irqmask | MT_INT_RRO_RX_DONE |
+ 		   MT_INT_TX_DONE_BAND2;
+ 	mt76_wr(dev, MT_INT_MASK_CSR, irq_mask);
+-	mtk_wed_device_start_hw_rro(&mdev->mmio.wed, irq_mask, false);
++	mtk_wed_device_start_hwrro(&mdev->mmio.wed, irq_mask, false);
+ 	mt7996_irq_enable(dev, irq_mask);
+ 
+ 	return 0;
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 2e0b1f1..44612e9 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1545,7 +1545,7 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
+ 	path->mtk_wdma.queue = 0;
+ 	path->mtk_wdma.wcid = msta->wcid.idx;
+ 
+-	path->mtk_wdma.amsdu = mtk_wed_is_amsdu_supported(wed);
++	path->mtk_wdma.amsdu_en = mtk_wed_device_support_pao(wed);
+ 	ctx->dev = NULL;
+ 
+ 	return 0;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 1915a22..ea52e09 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3171,7 +3171,7 @@ static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
+ 
+ 	if (!mtk_wed_device_active(&dev->mt76.mmio.wed))
+ 		req.token_per_src[RED_TOKEN_SRC_CNT - 1] =
+-			cpu_to_le16(MT7996_TOKEN_SIZE - MT7996_HW_TOKEN_SIZE);
++			cpu_to_le16(MT7996_SW_TOKEN_SIZE);
+ 
+ 	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
+ 				 &req, sizeof(req), false);
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 38b8843..ab7e58e 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -14,7 +14,7 @@
+ #include "../trace.h"
+ #include "../dma.h"
+ 
+-static bool wed_enable;
++static bool wed_enable = true;
+ module_param(wed_enable, bool, 0644);
+ 
+ static const struct __base mt7996_reg_base[] = {
+@@ -360,14 +360,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 		}
+ 
+ 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
+-		wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
++		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base + hif1_ofs +
+ 				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ 				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
+ 
+-		wed->wlan.id = 0x7991;
++		wed->wlan.chip_id = 0x7991;
+ 		wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
+ 	} else {
+-		wed->wlan.hw_rro = dev->has_rro; /* default on */
++		wed->wlan.hwrro = dev->has_rro; /* default on */
+ 		wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
+ 		wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
+ 		wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
+@@ -375,7 +375,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 
+ 		wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
+ 
+-		wed->wlan.wpdma_rx = wed->wlan.phy_base +
++		wed->wlan.wpdma_rx[0] = wed->wlan.phy_base +
+ 				     MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ 				     MT7996_RXQ_BAND0 * MT_RING_SIZE;
+ 
+@@ -417,11 +417,11 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 		dev->mt76.rx_token_size = MT7996_TOKEN_SIZE + wed->wlan.rx_npkt;
+ 	}
+ 
+-	wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE;
+-	wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf;
++	wed->wlan.nbuf = MT7996_TOKEN_SIZE;
++	wed->wlan.token_start = 0;
+ 
+-	wed->wlan.amsdu_max_subframes = 8;
+-	wed->wlan.amsdu_max_len = 1536;
++	wed->wlan.max_amsdu_nums = 8;
++	wed->wlan.max_amsdu_len = 1536;
+ 
+ 	wed->wlan.init_buf = mt7996_wed_init_buf;
+ 	wed->wlan.init_rx_buf = mt76_mmio_wed_init_rx_buf;
+@@ -442,6 +442,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ 	*irq = wed->irq;
+ 	dev->mt76.dma_dev = wed->dev;
+ 
++	dev->mt76.token_size = MT7996_SW_TOKEN_SIZE;
++
+ 	return 1;
+ #else
+ 	return 0;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index ba73520..55a4087 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -67,6 +67,7 @@
+ #define MT7996_EEPROM_BLOCK_SIZE	16
+ #define MT7996_TOKEN_SIZE		16384
+ #define MT7996_HW_TOKEN_SIZE		8192
++#define MT7996_SW_TOKEN_SIZE		1024
+ 
+ #define MT7996_CFEND_RATE_DEFAULT	0x49	/* OFDM 24M */
+ #define MT7996_CFEND_RATE_11B		0x03	/* 11B LP, 11M */
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
new file mode 100644
index 0000000..4178b68
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/mtk-1006-hostapd-mtk-add-support-enable-disable-preamble-punc.patch
@@ -0,0 +1,374 @@
+From df3d6a354fc1243f8c862f2b61ee9ac09eabe482 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Thu, 21 Sep 2023 10:29:46 +0800
+Subject: [PATCH] hostapd: mtk: add support enable/disable preamble puncture
+ from mtk vendor command
+
+This commit supports two ways to enable/disable preamble puncture
+feature.
+
+1. Add new hostapd configuration "pp_mode". The possible value could be
+1 to 3. When the value is 0, it means that the firmware will turn off
+the pp algorithm. When the value is 1, it means that the firmware will
+enable the pp algorithm, allowing the algorithm to determine whether pp
+could be applied on each txcmd. When the value is 2, it means that pp
+feature is manually configured by the user. Please noted that for
+current implementation, the default configuration is 0.
+
+2. $ hostapd_cli -i <intf_name> raw set_pp mode val
+The argument "val" could be 0 for PP feature disabled or 1 to configure
+PP feature as auto mode.
+
+This commit also let user check whether pp feature is enabled by
+hostapd_cli command. The usage shows as below:
+$ hostapd_cli -i <intf_name> raw get_pp mode
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ hostapd/config_file.c             | 11 ++++++
+ hostapd/ctrl_iface.c              | 59 +++++++++++++++++++++++++++++++
+ src/ap/ap_config.c                |  1 +
+ src/ap/ap_config.h                |  7 ++++
+ src/ap/ap_drv_ops.c               |  9 +++++
+ src/ap/ap_drv_ops.h               |  1 +
+ src/ap/hostapd.c                  |  2 ++
+ src/common/mtk_vendor.h           | 12 +++++++
+ src/drivers/driver.h              |  6 ++++
+ src/drivers/driver_nl80211.c      | 49 +++++++++++++++++++++++++
+ src/drivers/driver_nl80211.h      |  1 +
+ src/drivers/driver_nl80211_capa.c |  3 ++
+ 12 files changed, 161 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index a751993..278f6b3 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -4801,6 +4801,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 		conf->eht_phy_capab.mu_beamformer = atoi(pos);
+ 	} else if (os_strcmp(buf, "punct_bitmap") == 0) {
+ 		conf->punct_bitmap = atoi(pos);
++		conf->pp_mode = PP_MANUAL_MODE;
+ 	} else if (os_strcmp(buf, "punct_acs_threshold") == 0) {
+ 		int val = atoi(pos);
+ 
+@@ -4876,6 +4877,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 			return 1;
+ 		}
+ 		conf->amsdu = val;
++	} else if (os_strcmp(buf, "pp_mode") == 0) {
++		int val = atoi(pos);
++
++		if ((val != PP_MANUAL_MODE && conf->punct_bitmap) ||
++		    val < PP_DISABLE || val > PP_MANUAL_MODE) {
++			wpa_printf(MSG_ERROR, "Line %d: invalid pp_mode value",
++				   line);
++			return 1;
++		}
++		conf->pp_mode = (u8) val;
+ 	} else {
+ 		wpa_printf(MSG_ERROR,
+ 			   "Line %d: unknown configuration item '%s'",
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index 517ebd6..7315d12 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -4183,6 +4183,59 @@ hostapd_ctrl_iface_set_background_radar_mode(struct hostapd_data *hapd, char *cm
+ 	return os_snprintf(buf, buflen, "OK\n");
+ }
+ 
++static int
++hostapd_ctrl_iface_set_pp(struct hostapd_data *hapd, char *cmd, char *buf,
++			  size_t buflen)
++{
++	char *pos, *config, *value;
++
++	config = cmd;
++	pos = os_strchr(config, ' ');
++	if (pos == NULL)
++		return -1;
++	*pos++ = '\0';
++
++	if (pos == NULL)
++		return -1;
++	value = pos;
++
++	if (os_strcmp(config, "mode") == 0) {
++		int val = atoi(value);
++
++		if (val < PP_DISABLE || val > PP_AUTO_MODE) {
++			wpa_printf(MSG_ERROR, "Invalid value for set_pp");
++			return -1;
++		}
++		hapd->iconf->pp_mode = (u8) val;
++		if (hostapd_drv_pp_mode_set(hapd) != 0)
++			return -1;
++	} else {
++		wpa_printf(MSG_ERROR,
++			   "Unsupported parameter %s for set_pp", config);
++		return -1;
++	}
++	return os_snprintf(buf, buflen, "OK\n");
++}
++
++static int
++hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf,
++			  size_t buflen)
++{
++	char *pos, *end;
++
++	pos = buf;
++	end = buf + buflen;
++
++	if (os_strcmp(cmd, "mode") == 0) {
++		return os_snprintf(pos, end - pos, "pp_mode: %d\n",
++				   hapd->iconf->pp_mode);
++	} else {
++		wpa_printf(MSG_ERROR,
++			   "Unsupported parameter %s for get_pp", cmd);
++		return -1;
++	}
++}
++
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+ 					      int reply_size,
+@@ -4769,6 +4822,12 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 	} else if (os_strncmp(buf, "DUMP_AMNT", 9) == 0) {
+ 		reply_len = hostapd_ctrl_iface_dump_amnt(hapd, buf+10,
+ 							reply, reply_size);
++	} else if (os_strncmp(buf, "set_pp", 6) == 0) {
++		reply_len = hostapd_ctrl_iface_set_pp(hapd, buf + 7, reply,
++						      reply_size);
++	} else if (os_strncmp(buf, "get_pp", 6) == 0) {
++		reply_len = hostapd_ctrl_iface_get_pp(hapd, buf + 7, reply,
++						      reply_size);
+ 	} else if (os_strncmp(buf, "set_muru_manual_config=", 23) == 0) {
+ 		// Replace first ':' with a single space ' '
+ 		char *pos = buf + 23;
+diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
+index 223db56..d8dd549 100644
+--- a/src/ap/ap_config.c
++++ b/src/ap/ap_config.c
+@@ -302,6 +302,7 @@ struct hostapd_config * hostapd_config_defaults(void)
+ 	conf->three_wire_enable = THREE_WIRE_MODE_DISABLE;
+ 	conf->ibf_enable = IBF_DEFAULT_ENABLE;
+ 	conf->amsdu = 1;
++	conf->pp_mode = PP_DISABLE;
+ 
+ 	return conf;
+ }
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index b6f05e7..9e39e82 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -1205,6 +1205,7 @@ struct hostapd_config {
+ 	u8 dfs_detect_mode;
+ 	u8 amsdu;
+ 	void *muru_config;
++	u8 pp_mode;
+ };
+ 
+ enum three_wire_mode {
+@@ -1257,6 +1258,12 @@ enum mtk_vendor_attr_edcca_ctrl_mode {
+ 	EDCCA_CTRL_NUM,
+ };
+ 
++enum pp_mode {
++	PP_DISABLE = 0,
++	PP_AUTO_MODE,
++	PP_MANUAL_MODE,
++};
++
+ #define EDCCA_DEFAULT_COMPENSATION -6
+ #define EDCCA_MIN_COMPENSATION -126
+ #define EDCCA_MAX_COMPENSATION 126
+diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
+index 5b93ea6..d0d8279 100644
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -1271,3 +1271,12 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd)
+ 	return hapd->driver->background_radar_mode(hapd->drv_priv,
+ 						   hapd->iconf->background_radar_mode);
+ }
++
++int hostapd_drv_pp_mode_set(struct hostapd_data *hapd)
++{
++	if (!hapd->driver || !hapd->driver->pp_mode_set ||
++	    hapd->iconf->pp_mode > PP_AUTO_MODE)
++		return 0;
++	return hapd->driver->pp_mode_set(hapd->drv_priv,
++					 hapd->iconf->pp_mode);
++}
+diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
+index 1e7ae7a..e4c2827 100644
+--- a/src/ap/ap_drv_ops.h
++++ b/src/ap/ap_drv_ops.h
+@@ -163,6 +163,7 @@ int hostapd_drv_ap_trig_type(struct hostapd_data *hapd, u8 enable, u8 type);
+ 
+ int hostapd_drv_amnt_set(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_sta_mac);
+ int hostapd_drv_amnt_dump(struct hostapd_data *hapd, u8 amnt_idx, u8 *amnt_dump_buf);
++int hostapd_drv_pp_mode_set(struct hostapd_data *hapd);
+ 
+ #include "drivers/driver.h"
+ 
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index 2b563a5..90c6c26 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -2526,6 +2526,8 @@ dfs_offload:
+ 		goto fail;
+ 	if (hostapd_drv_amsdu_ctrl(hapd) < 0)
+ 		goto fail;
++	if (hostapd_drv_pp_mode_set(hapd) < 0)
++		goto fail;
+ 
+ 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
+ 		   iface->bss[0]->conf->iface);
+diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h
+index 5bc1e04..6275c14 100644
+--- a/src/common/mtk_vendor.h
++++ b/src/common/mtk_vendor.h
+@@ -17,6 +17,7 @@ enum mtk_nl80211_vendor_subcmds {
+ 	MTK_NL80211_VENDOR_SUBCMD_IBF_CTRL = 0xc9,
+ 	MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ 	MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL = 0xcb,
++	MTK_NL80211_VENDOR_SUBCMD_PP_CTRL = 0xcc,
+ };
+ 
+ enum mtk_vendor_attr_edcca_ctrl {
+@@ -256,6 +257,17 @@ enum mtk_vendor_attr_background_radar_ctrl {
+ 		NUM_MTK_VENDOR_ATTRS_BACKGROUND_RADAR_CTRL - 1
+ };
+ 
++enum mtk_vendor_attr_pp_ctrl {
++	MTK_VENDOR_ATTR_PP_CTRL_UNSPEC,
++
++	MTK_VENDOR_ATTR_PP_MODE,
++
++	/* keep last */
++	NUM_MTK_VENDOR_ATTRS_PP_CTRL,
++	MTK_VENDOR_ATTR_PP_CTRL_MAX =
++		NUM_MTK_VENDOR_ATTRS_PP_CTRL - 1
++};
++
+ #define CSI_MAX_COUNT 256
+ #define ETH_ALEN 6
+ 
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index bc82d28..261ed80 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -5208,6 +5208,12 @@ struct wpa_driver_ops {
+ 	 * @background_radar_mode: background radar mode
+ 	 */
+ 	int (*background_radar_mode)(void *priv, u8 background_radar_mode);
++	/**
++	 * pp_mode_set - Set preamble puncture operation mode
++	 * @priv: Private driver interface data
++	 * @pp_mode: Value is defined in enum pp_mode
++	 */
++	int (*pp_mode_set)(void *priv, const u8 pp_mode);
+ };
+ 
+ /**
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index 2089ad6..3cc55dc 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -141,6 +141,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
+ 	[MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
+ };
+ 
++static struct nla_policy
++pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = {
++	[MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 },
++};
++
+ static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
+ {
+ 	struct nl_sock *handle;
+@@ -14756,6 +14761,49 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m
+ 	return ret;
+ }
+ 
++static int nl80211_pp_mode_set(void *priv, const u8 pp_mode)
++{
++	struct i802_bss *bss = priv;
++	struct wpa_driver_nl80211_data *drv = bss->drv;
++	struct nl_msg *msg;
++	struct nlattr *data;
++	int ret;
++
++	if (!drv->mtk_pp_vendor_cmd_avail) {
++		wpa_printf(MSG_DEBUG,
++			   "nl80211: Driver does not support setting preamble puncture");
++		return 0;
++	}
++
++	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
++	if (!msg)
++		goto fail;
++
++	if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) ||
++	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
++			MTK_NL80211_VENDOR_SUBCMD_PP_CTRL))
++		goto fail;
++
++	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
++	if (!data)
++		goto fail;
++
++	nla_put_u8(msg, MTK_VENDOR_ATTR_PP_MODE, pp_mode);
++
++	nla_nest_end(msg, data);
++	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
++
++	if (ret)
++		wpa_printf(MSG_ERROR, "Failed to set pp_enable. ret=%d (%s)",
++			   ret, strerror(-ret));
++
++	return ret;
++
++fail:
++	nlmsg_free(msg);
++	return -ENOBUFS;
++}
++
+ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.name = "nl80211",
+ 	.desc = "Linux nl80211/cfg80211",
+@@ -14929,4 +14977,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
+ 	.amnt_set = nl80211_amnt_set,
+ 	.amnt_dump = nl80211_amnt_dump,
+ 	.background_radar_mode = nl80211_background_radar_mode,
++	.pp_mode_set = nl80211_pp_mode_set,
+ };
+diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
+index 74ee9b1..1bba5b1 100644
+--- a/src/drivers/driver_nl80211.h
++++ b/src/drivers/driver_nl80211.h
+@@ -211,6 +211,7 @@ struct wpa_driver_nl80211_data {
+ 	unsigned int mtk_rfeatures_vendor_cmd_avail:1;
+ 	unsigned int mtk_amnt_vendor_cmd_avail:1;
+ 	unsigned int mtk_background_radar_vendor_cmd_avail:1;
++	unsigned int mtk_pp_vendor_cmd_avail:1;
+ 
+ 	u64 vendor_scan_cookie;
+ 	u64 remain_on_chan_cookie;
+diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
+index 90711b4..f2c42b9 100644
+--- a/src/drivers/driver_nl80211_capa.c
++++ b/src/drivers/driver_nl80211_capa.c
+@@ -1136,6 +1136,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
+ 				case MTK_NL80211_VENDOR_SUBCMD_BACKGROUND_RADAR_CTRL:
+ 					drv->mtk_background_radar_vendor_cmd_avail = 1;
+ 					break;
++				case MTK_NL80211_VENDOR_SUBCMD_PP_CTRL:
++					drv->mtk_pp_vendor_cmd_avail = 1;
++					break;
+ 				}
+ 			}
+ 
+-- 
+2.18.0
+
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
new file mode 100644
index 0000000..d2b117c
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/network/services/hostapd/patches/mtk-1007-hostapd-mtk-ACS-Add-EHT320-and-HT40-support-fix-issu.patch
@@ -0,0 +1,431 @@
+From 88f5a4c1c67f8fc40c8294c498faa72e1ceea470 Mon Sep 17 00:00:00 2001
+From: "fancy.liu" <fancy.liu@mediatek.com>
+Date: Thu, 28 Sep 2023 18:03:08 +0800
+Subject: [PATCH] hostapd: mtk: [ACS] Add EHT320 and HT40- support, fix issue
+
+1. Add 6G EHT320 support;
+2. Add 2.4G HT40- support;
+3. Fix issue: selected best channel is out of channels;
+
+Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
+---
+ src/ap/acs.c | 222 +++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 136 insertions(+), 86 deletions(-)
+
+diff --git a/src/ap/acs.c b/src/ap/acs.c
+index af31405..ed6a47b 100644
+--- a/src/ap/acs.c
++++ b/src/ap/acs.c
+@@ -245,6 +245,7 @@ enum bw_type {
+ 	ACS_BW40,
+ 	ACS_BW80,
+ 	ACS_BW160,
++	ACS_BW320,
+ };
+ 
+ struct bw_item {
+@@ -286,10 +287,16 @@ static const struct bw_item bw_160[] = {
+ 	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
+ 	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
+ };
++static const struct bw_item bw_320[] = {
++	{ 5955, 6255, 31 }, { 6115, 6415, 63 }, { 6275, 6575, 95 },
++	{ 6435, 6735, 127 }, { 6595, 6895, 159 }, { 6755, 7055, 191 },
++	{ -1, -1, -1 }
++};
+ static const struct bw_item *bw_desc[] = {
+ 	[ACS_BW40] = bw_40,
+ 	[ACS_BW80] = bw_80,
+ 	[ACS_BW160] = bw_160,
++	[ACS_BW320] = bw_320,
+ };
+ 
+ 
+@@ -583,12 +590,6 @@ static void acs_survey_mode_interference_factor(
+ 		    iface->conf->acs_exclude_dfs)
+ 			continue;
+ 
+-		if (!is_in_chanlist(iface, chan))
+-			continue;
+-
+-		if (!is_in_freqlist(iface, chan))
+-			continue;
+-
+ 		if (chan->max_tx_power < iface->conf->min_tx_power)
+ 			continue;
+ 
+@@ -775,17 +776,29 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			 struct hostapd_channel_data **ideal_chan,
+ 			 long double *ideal_factor)
+ {
+-	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
++	struct hostapd_channel_data *chan, *adj_chan = NULL, *tmp_chan = NULL, *best;
+ 	long double factor;
+ 	int i, j;
+ 	unsigned int k;
++	int ht40_plus = 1, sec_ch_factor = 1;
++
++	if (is_24ghz_mode(mode->mode)) {
++		ht40_plus = (iface->conf->secondary_channel == -1) ? 0 : 1;
++		sec_ch_factor = (iface->conf->secondary_channel == -1) ? -1 : 1;
++	}
++
++	wpa_printf(MSG_INFO, "%s:%d, bw(%u), n_chans(%d), num_channels(%d), sec_ch(%d)",
++		__func__, __LINE__, bw, n_chans, mode->num_channels, iface->conf->secondary_channel);
+ 
+ 	for (i = 0; i < mode->num_channels; i++) {
+ 		double total_weight;
+ 		struct acs_bias *bias, tmp_bias;
+-		bool update_best = true;
++		bool update_best = true, has_candidate = true;
+ 
+ 		best = chan = &mode->channels[i];
++		wpa_printf(MSG_INFO,
++			   "ACS: Channel[%d] %d: interference_factor %Lg",
++			   i, chan->chan, chan->interference_factor);
+ 
+ 		/* Since in the current ACS implementation the first channel is
+ 		 * always a primary channel, skip channels not available as
+@@ -804,11 +817,12 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    iface->conf->acs_exclude_dfs)
+ 			continue;
+ 
+-		if (!is_in_chanlist(iface, chan))
+-			continue;
+-
+-		if (!is_in_freqlist(iface, chan))
+-			continue;
++		if (!is_in_chanlist(iface, chan) || !is_in_freqlist(iface, chan)) {
++			if (is_24ghz_mode(mode->mode))
++				continue;
++			else
++				has_candidate = false;
++		}
+ 
+ 		if (chan->max_tx_power < iface->conf->min_tx_power)
+ 			continue;
+@@ -817,7 +831,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		    iface->conf->country[2] == 0x4f)
+ 			continue;
+ 
+-		if (!chan_bw_allowed(chan, bw, 1, 1)) {
++		if (!chan_bw_allowed(chan, bw, ht40_plus, 1)) {
+ 			wpa_printf(MSG_DEBUG,
+ 				   "ACS: Channel %d: BW %u is not supported",
+ 				   chan->chan, bw);
+@@ -838,7 +852,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 		}
+ 
+ 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
+-		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
++		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
++		     iface->conf->ieee80211be)) {
+ 			if (hostapd_get_oper_chwidth(iface->conf) ==
+ 			    CONF_OPER_CHWIDTH_80MHZ &&
+ 			    !acs_usable_bw_chan(chan, ACS_BW80)) {
+@@ -856,63 +871,89 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 					   chan->chan);
+ 				continue;
+ 			}
+-		}
+ 
+-		factor = 0;
+-		if (acs_usable_chan(chan))
+-			factor = chan->interference_factor;
+-		total_weight = 1;
+-
+-		for (j = 1; j < n_chans; j++) {
+-			adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
+-			if (!adj_chan)
+-				break;
+-
+-			if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++			if (iface->conf->ieee80211be &&
++			    hostapd_get_oper_chwidth(iface->conf) ==
++			    CONF_OPER_CHWIDTH_320MHZ &&
++			    !acs_usable_bw_chan(chan, ACS_BW320)) {
+ 				wpa_printf(MSG_DEBUG,
+-					   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
+-					   chan->chan, adj_chan->chan, bw);
+-				break;
++					   "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth",
++					   chan->chan);
++				continue;
+ 			}
++		}
++
++		factor = 0;
++		total_weight = 0;
+ 
+-			if (acs_usable_chan(adj_chan)) {
+-				factor += adj_chan->interference_factor;
++		if (!is_24ghz_mode(mode->mode)) {
++			/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
++			 * crowded primary channel if one was found in the segment */
++			if (acs_usable_chan(chan)) {
++				factor += chan->interference_factor;
+ 				total_weight += 1;
+-			} else {
+-				update_best = false;
+ 			}
+ 
+-			/* find the best channel in this segment */
+-			if (update_best &&
+-			    adj_chan->interference_factor <
+-			    best->interference_factor)
+-				best = adj_chan;
+-		}
++			for (j = 1; j < n_chans; j++) {
++				adj_chan = acs_find_chan(iface, chan->freq + j * 20);
++				if (!adj_chan)
++					break;
+ 
+-		if (j != n_chans) {
+-			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
+-				   chan->chan);
+-			continue;
+-		}
++				if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
++					wpa_printf(MSG_DEBUG,
++						   "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
++						   chan->chan, adj_chan->chan, bw);
++					break;
++				}
+ 
+-		/* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
+-		 * crowded primary channel if one was found in the segment */
+-		if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+-		    chan != best) {
+-			wpa_printf(MSG_DEBUG,
+-				   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
+-				   best->chan, chan->chan,
+-				   chan->interference_factor,
+-				   best->interference_factor);
+-			chan = best;
+-		}
++				update_best = true;
++				if (acs_usable_chan(adj_chan)) {
++					factor += adj_chan->interference_factor;
++					total_weight += 1;
++
++					if (!is_in_chanlist(iface, adj_chan) ||
++						!is_in_freqlist(iface, adj_chan))
++						update_best = false;
++				} else {
++					update_best = false;
++				}
++
++				/* find the best channel in this segment */
++				if (update_best && (!has_candidate ||
++					adj_chan->interference_factor < best->interference_factor)) {
++					best = adj_chan;
++					has_candidate = true;
++				}
++			}
+ 
+-		/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
+-		 * channel interference factor. */
+-		if (is_24ghz_mode(mode->mode)) {
++			if (j != n_chans || !has_candidate) {
++				wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
++					   chan->chan);
++				continue;
++			}
++
++			if (chan != best) {
++				wpa_printf(MSG_INFO,
++					   "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
++					   best->chan, chan->chan,
++					   chan->interference_factor,
++					   best->interference_factor);
++				chan = best;
++			}
++		} else {
+ 			for (j = 0; j < n_chans; j++) {
++				/* Will set primary_channel / secondary_channel(40M case) weight to 1 */
++				tmp_chan = acs_find_chan(iface, chan->freq +
++							 (j * 20) * sec_ch_factor);
++				if (tmp_chan && acs_usable_chan(tmp_chan)) {
++					factor += tmp_chan->interference_factor;
++					total_weight += 1;
++				}
++
++				/* 2.4 GHz has overlapping 20 MHz channels. Include adjacent channel
++				interference factor, separately for primary/secondary channel. */
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 5);
++							 ((j * 20) - 5) * sec_ch_factor);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -920,7 +961,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) - 10);
++							 ((j * 20) - 10) * sec_ch_factor);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -928,7 +969,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 5);
++							 ((j * 20) + 5) * sec_ch_factor);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -936,7 +977,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 				}
+ 
+ 				adj_chan = acs_find_chan(iface, chan->freq +
+-							 (j * 20) + 10);
++							 ((j * 20) + 10) * sec_ch_factor);
+ 				if (adj_chan && acs_usable_chan(adj_chan)) {
+ 					factor += ACS_NEXT_ADJ_WEIGHT *
+ 						adj_chan->interference_factor;
+@@ -945,7 +986,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 			}
+ 		}
+ 
+-		factor /= total_weight;
++		if (total_weight)
++			factor /= total_weight;
+ 
+ 		bias = NULL;
+ 		if (iface->conf->acs_chan_bias) {
+@@ -964,11 +1006,11 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
+ 
+ 		if (bias) {
+ 			factor *= bias->bias;
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg (%f bias)",
+ 				   chan->chan, factor, bias->bias);
+ 		} else {
+-			wpa_printf(MSG_DEBUG,
++			wpa_printf(MSG_INFO,
+ 				   "ACS:  * channel %d: total interference = %Lg",
+ 				   chan->chan, factor);
+ 		}
+@@ -1021,19 +1063,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+ 		goto bw_selected;
+ 	}
+ 
+-	/* TODO: HT40- support */
+-
+-	if (iface->conf->ieee80211n &&
+-	    iface->conf->secondary_channel == -1) {
+-		wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
+-		return NULL;
+-	}
+-
+ 	if (iface->conf->ieee80211n &&
+ 	    iface->conf->secondary_channel)
+ 		n_chans = 2;
+ 
+-	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
++	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
++	    iface->conf->ieee80211be) {
+ 		switch (hostapd_get_oper_chwidth(iface->conf)) {
+ 		case CONF_OPER_CHWIDTH_80MHZ:
+ 			n_chans = 4;
+@@ -1043,6 +1078,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
+ 			break;
+ 		default:
+ 			break;
++		/* 320 is supported only in 6GHz 11be mode */
+ 		}
+ 	}
+ 
+@@ -1063,7 +1099,7 @@ bw_selected:
+ 	}
+ 
+ 	if (ideal_chan) {
+-		wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
++		wpa_printf(MSG_INFO, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
+ 			   ideal_chan->chan, ideal_chan->freq, ideal_factor);
+ 
+ #ifdef CONFIG_IEEE80211BE
+@@ -1078,6 +1114,21 @@ bw_selected:
+ 	return rand_chan;
+ }
+ 
++static int acs_get_center_freq_320mhz(int channel)
++{
++	if (channel >= 1 && channel <= 45)
++		return 31;
++	else if (channel >= 49 && channel <= 77)
++		return 63;
++	else if (channel >= 81 && channel <= 109)
++		return 95;
++	else if (channel >= 113 && channel <= 141)
++		return 127;
++	else if (channel >= 145 && channel <= 173)
++		return 159;
++	else
++		return 191;
++}
+ 
+ static void acs_adjust_secondary(struct hostapd_iface *iface)
+ {
+@@ -1104,10 +1155,11 @@ static void acs_adjust_secondary(struct hostapd_iface *iface)
+ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ {
+ 	int center;
++ 	u8 bw = hostapd_get_oper_chwidth(iface->conf);
+ 
+-	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
++	wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
+ 
+-	switch (hostapd_get_oper_chwidth(iface->conf)) {
++	switch (bw) {
+ 	case CONF_OPER_CHWIDTH_USE_HT:
+ 		if (iface->conf->secondary_channel &&
+ 		    iface->freq >= 2400 && iface->freq < 2500)
+@@ -1121,6 +1173,9 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ 	case CONF_OPER_CHWIDTH_80MHZ:
+ 		center = acs_get_bw_center_chan(iface->freq, ACS_BW80);
+ 		break;
++	case CONF_OPER_CHWIDTH_320MHZ:
++		center = acs_get_center_freq_320mhz(iface->conf->channel);
++		break;
+ 	case CONF_OPER_CHWIDTH_160MHZ:
+ 		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
+ 		break;
+@@ -1128,7 +1183,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
+ 		/* TODO: How can this be calculated? Adjust
+ 		 * acs_find_ideal_chan() */
+ 		wpa_printf(MSG_INFO,
+-			   "ACS: Only VHT20/40/80/160 is supported now");
++			   "ACS: Only VHT20/40/80/160 EHT320 is supported now");
+ 		return;
+ 	}
+ 
+@@ -1191,7 +1246,8 @@ static void acs_study(struct hostapd_iface *iface)
+ 	iface->conf->punct_bitmap = ideal_chan->punct_bitmap;
+ #endif /* CONFIG_IEEE80211BE */
+ 
+-	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
++	if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
++		iface->conf->ieee80211be) {
+ 		acs_adjust_secondary(iface);
+ 		acs_adjust_center_freq(iface);
+ 	}
+@@ -1270,12 +1326,6 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
+ 		     iface->conf->acs_exclude_dfs))
+ 			continue;
+ 
+-		if (!is_in_chanlist(iface, chan))
+-			continue;
+-
+-		if (!is_in_freqlist(iface, chan))
+-			continue;
+-
+ 		if (chan->max_tx_power < iface->conf->min_tx_power)
+ 			continue;
+ 
+-- 
+2.25.1
+
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_dsp.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_dsp.bin
index 1c7710b..ada308b 100755
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_dsp.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_dsp.bin
Binary files differ
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin
index 7b151c9..c391788 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_rom_patch.bin
Binary files differ
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin
index b0433e8..20d91ee 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wa.bin
Binary files differ
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin
index 7188830..b6ca1a9 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm.bin
Binary files differ
diff --git a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm_tm.bin b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm_tm.bin
index 9ddee02..98d6517 100644
--- a/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm_tm.bin
+++ b/autobuild_mac80211_release/package/kernel/mt76/src/firmware/mt7996/mt7996_wm_tm.bin
Binary files differ