git: 54c8cac0ad8e - stable/15 - mt76: update Mediatek's mt76 driver

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Mon, 27 Oct 2025 00:19:08 UTC
The branch stable/15 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=54c8cac0ad8e90f4da9e95cf36419dfe83d6b2f0

commit 54c8cac0ad8e90f4da9e95cf36419dfe83d6b2f0
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-10-17 21:22:52 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-10-27 00:18:22 +0000

    mt76: update Mediatek's mt76 driver
    
    This version is based on
    git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
    e5f0a698b34ed76002dc5cff3804a61c80233a7a ( tag: v6.17 ).
    
    (cherry picked from commit 14b53301e8d482654f94c23e6884fe96b3d26825)
---
 sys/contrib/dev/mediatek/mt76/channel.c          |    9 +-
 sys/contrib/dev/mediatek/mt76/dma.c              |   14 +-
 sys/contrib/dev/mediatek/mt76/eeprom.c           |    4 +
 sys/contrib/dev/mediatek/mt76/mac80211.c         |   70 +-
 sys/contrib/dev/mediatek/mt76/mcu.c              |    4 +
 sys/contrib/dev/mediatek/mt76/mt76.h             |   53 +-
 sys/contrib/dev/mediatek/mt76/mt7603/dma.c       |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7603/mac.c       |   10 +-
 sys/contrib/dev/mediatek/mt76/mt7603/main.c      |    5 +-
 sys/contrib/dev/mediatek/mt76/mt7615/init.c      |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mac.c       |    7 +-
 sys/contrib/dev/mediatek/mt76/mt7615/main.c      |   17 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mcu.c       |    6 +-
 sys/contrib/dev/mediatek/mt76/mt7615/pci_mac.c   |    4 +-
 sys/contrib/dev/mediatek/mt76/mt7615/sdio_mcu.c  |  180 ----
 sys/contrib/dev/mediatek/mt76/mt7615/usb.c       |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7615/usb_mcu.c   |  100 ---
 sys/contrib/dev/mediatek/mt76/mt76_connac.h      |    7 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac3_mac.h |    4 +
 sys/contrib/dev/mediatek/mt76/mt76_connac_mac.c  |    2 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.c  |   51 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.h  |   14 +
 sys/contrib/dev/mediatek/mt76/mt76x0/pci.c       |    3 +-
 sys/contrib/dev/mediatek/mt76/mt76x02.h          |    9 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_mac.c      |    4 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_mmio.c     |    1 -
 sys/contrib/dev/mediatek/mt76/mt76x02_usb_core.c |    4 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_util.c     |    4 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/pci.c       |    3 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/pci_main.c  |    6 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/usb.c       |    6 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/usb_init.c  |   13 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/usb_main.c  |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7915/debugfs.c   |   81 +-
 sys/contrib/dev/mediatek/mt76/mt7915/eeprom.c    |   33 +-
 sys/contrib/dev/mediatek/mt76/mt7915/eeprom.h    |    1 +
 sys/contrib/dev/mediatek/mt76/mt7915/init.c      |   16 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mac.c       |   84 +-
 sys/contrib/dev/mediatek/mt76/mt7915/main.c      |   13 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mcu.c       |   86 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mcu.h       |   14 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mmio.c      |   11 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mt7915.h    |   25 +-
 sys/contrib/dev/mediatek/mt76/mt7921/mac.c       |    8 +-
 sys/contrib/dev/mediatek/mt76/mt7921/main.c      |   28 +-
 sys/contrib/dev/mediatek/mt76/mt7921/sdio.c      |    2 +
 sys/contrib/dev/mediatek/mt76/mt7921/sdio_mac.c  |   58 ++
 sys/contrib/dev/mediatek/mt76/mt7925/Makefile    |    1 +
 sys/contrib/dev/mediatek/mt76/mt7925/init.c      |  104 +++
 sys/contrib/dev/mediatek/mt76/mt7925/mac.c       |    8 +-
 sys/contrib/dev/mediatek/mt76/mt7925/main.c      |  219 +++--
 sys/contrib/dev/mediatek/mt76/mt7925/mcu.c       |  522 +++++++----
 sys/contrib/dev/mediatek/mt76/mt7925/mcu.h       |   93 +-
 sys/contrib/dev/mediatek/mt76/mt7925/mt7925.h    |   42 +-
 sys/contrib/dev/mediatek/mt76/mt7925/pci.c       |    7 +-
 sys/contrib/dev/mediatek/mt76/mt7925/regs.h      |    4 +-
 sys/contrib/dev/mediatek/mt76/mt7925/testmode.c  |  201 +++++
 sys/contrib/dev/mediatek/mt76/mt792x.h           |   22 +-
 sys/contrib/dev/mediatek/mt76/mt792x_acpi_sar.c  |  123 ++-
 sys/contrib/dev/mediatek/mt76/mt792x_acpi_sar.h  |   18 +-
 sys/contrib/dev/mediatek/mt76/mt792x_core.c      |   45 +-
 sys/contrib/dev/mediatek/mt76/mt792x_mac.c       |    5 +-
 sys/contrib/dev/mediatek/mt76/mt7996/coredump.c  |    4 +-
 sys/contrib/dev/mediatek/mt76/mt7996/debugfs.c   |   73 +-
 sys/contrib/dev/mediatek/mt76/mt7996/dma.c       |  196 +++--
 sys/contrib/dev/mediatek/mt76/mt7996/eeprom.c    |   42 +-
 sys/contrib/dev/mediatek/mt76/mt7996/init.c      |   45 +-
 sys/contrib/dev/mediatek/mt76/mt7996/mac.c       |  492 +++++++----
 sys/contrib/dev/mediatek/mt76/mt7996/main.c      | 1028 ++++++++++++++++------
 sys/contrib/dev/mediatek/mt76/mt7996/mcu.c       |  907 ++++++++++++-------
 sys/contrib/dev/mediatek/mt76/mt7996/mcu.h       |   59 +-
 sys/contrib/dev/mediatek/mt76/mt7996/mmio.c      |  200 ++++-
 sys/contrib/dev/mediatek/mt76/mt7996/mt7996.h    |  156 ++--
 sys/contrib/dev/mediatek/mt76/mt7996/pci.c       |   26 +-
 sys/contrib/dev/mediatek/mt76/mt7996/regs.h      |   51 +-
 sys/contrib/dev/mediatek/mt76/scan.c             |   21 +-
 sys/contrib/dev/mediatek/mt76/sdio_txrx.c        |    6 +-
 sys/contrib/dev/mediatek/mt76/tx.c               |   26 +-
 sys/contrib/dev/mediatek/mt76/util.c             |    2 +-
 sys/contrib/dev/mediatek/mt76/wed.c              |    6 +-
 sys/modules/mt76/Makefile.inc                    |    1 +
 81 files changed, 3978 insertions(+), 1859 deletions(-)

diff --git a/sys/contrib/dev/mediatek/mt76/channel.c b/sys/contrib/dev/mediatek/mt76/channel.c
index 6a35c6ebd823..77b75792eb48 100644
--- a/sys/contrib/dev/mediatek/mt76/channel.c
+++ b/sys/contrib/dev/mediatek/mt76/channel.c
@@ -173,13 +173,13 @@ void mt76_unassign_vif_chanctx(struct ieee80211_hw *hw,
 	if (!mlink)
 		goto out;
 
-	if (link_conf != &vif->bss_conf)
+	if (mlink != (struct mt76_vif_link *)vif->drv_priv)
 		rcu_assign_pointer(mvif->link[link_id], NULL);
 
 	dev->drv->vif_link_remove(phy, vif, link_conf, mlink);
 	mlink->ctx = NULL;
 
-	if (link_conf != &vif->bss_conf)
+	if (mlink != (struct mt76_vif_link *)vif->drv_priv)
 		kfree_rcu(mlink, rcu_head);
 
 out:
@@ -293,6 +293,7 @@ struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy,
 		kfree(mlink);
 		return ERR_PTR(ret);
 	}
+	rcu_assign_pointer(mvif->offchannel_link, mlink);
 
 	return mlink;
 }
@@ -301,10 +302,14 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
 			   struct mt76_vif_link *mlink)
 {
 	struct mt76_dev *dev = phy->dev;
+	struct mt76_vif_data *mvif;
 
 	if (IS_ERR_OR_NULL(mlink) || !mlink->offchannel)
 		return;
 
+	mvif = mlink->mvif;
+
+	rcu_assign_pointer(mvif->offchannel_link, NULL);
 	dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink);
 	kfree(mlink);
 }
diff --git a/sys/contrib/dev/mediatek/mt76/dma.c b/sys/contrib/dev/mediatek/mt76/dma.c
index 6765e1281ac3..af902a761e42 100644
--- a/sys/contrib/dev/mediatek/mt76/dma.c
+++ b/sys/contrib/dev/mediatek/mt76/dma.c
@@ -6,7 +6,7 @@
 #include <linux/dma-mapping.h>
 #if defined(__FreeBSD__)
 #include <linux/cache.h>
-#include <net/page_pool.h>
+#include <net/page_pool/helpers.h>
 #endif
 #include "mt76.h"
 #include "dma.h"
@@ -647,10 +647,8 @@ mt76_dma_rx_fill_buf(struct mt76_dev *dev, struct mt76_queue *q,
 
 	while (q->queued < q->ndesc - 1) {
 		struct mt76_queue_buf qbuf = {};
-		enum dma_data_direction dir;
-		dma_addr_t addr;
-		int offset;
 		void *buf = NULL;
+		int offset;
 
 		if (mt76_queue_is_wed_rro_ind(q))
 			goto done;
@@ -659,11 +657,8 @@ mt76_dma_rx_fill_buf(struct mt76_dev *dev, struct mt76_queue *q,
 		if (!buf)
 			break;
 
-		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);
-
-		qbuf.addr = addr + q->buf_offset;
+		qbuf.addr = page_pool_get_dma_addr(virt_to_head_page(buf)) +
+			    offset + q->buf_offset;
 done:
 		qbuf.len = len - q->buf_offset;
 		qbuf.skip_unmap = false;
@@ -1023,6 +1018,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
 	int i;
 
 	mt76_worker_disable(&dev->tx_worker);
+	napi_disable(&dev->tx_napi);
 	netif_napi_del(&dev->tx_napi);
 
 	for (i = 0; i < ARRAY_SIZE(dev->phys); i++) {
diff --git a/sys/contrib/dev/mediatek/mt76/eeprom.c b/sys/contrib/dev/mediatek/mt76/eeprom.c
index eb25879e2021..f2eb2cd6e509 100644
--- a/sys/contrib/dev/mediatek/mt76/eeprom.c
+++ b/sys/contrib/dev/mediatek/mt76/eeprom.c
@@ -101,6 +101,10 @@ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int l
 
 #ifdef CONFIG_NL80211_TESTMODE
 	dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
+	if (!dev->test_mtd.name) {
+		ret = -ENOMEM;
+		goto out_put_node;
+	}
 	dev->test_mtd.offset = offset;
 #endif
 
diff --git a/sys/contrib/dev/mediatek/mt76/mac80211.c b/sys/contrib/dev/mediatek/mt76/mac80211.c
index f4a714c57f82..927d8519104f 100644
--- a/sys/contrib/dev/mediatek/mt76/mac80211.c
+++ b/sys/contrib/dev/mediatek/mt76/mac80211.c
@@ -459,8 +459,10 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
 
-	wiphy->available_antennas_tx = phy->antenna_mask;
-	wiphy->available_antennas_rx = phy->antenna_mask;
+	if (!wiphy->available_antennas_tx)
+		wiphy->available_antennas_tx = phy->antenna_mask;
+	if (!wiphy->available_antennas_rx)
+		wiphy->available_antennas_rx = phy->antenna_mask;
 
 	wiphy->sar_capa = &mt76_sar_capa;
 	phy->frp = devm_kcalloc(dev->dev, wiphy->sar_capa->num_freq_ranges,
@@ -848,8 +850,45 @@ void mt76_free_device(struct mt76_dev *dev)
 }
 EXPORT_SYMBOL_GPL(mt76_free_device);
 
-static struct mt76_phy *
-mt76_vif_phy(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static void mt76_reset_phy(struct mt76_phy *phy)
+{
+	if (!phy)
+		return;
+
+	INIT_LIST_HEAD(&phy->tx_list);
+}
+
+void mt76_reset_device(struct mt76_dev *dev)
+{
+	int i;
+
+	rcu_read_lock();
+	for (i = 0; i < ARRAY_SIZE(dev->wcid); i++) {
+		struct mt76_wcid *wcid;
+
+		wcid = rcu_dereference(dev->wcid[i]);
+		if (!wcid)
+			continue;
+
+		wcid->sta = 0;
+		mt76_wcid_cleanup(dev, wcid);
+		rcu_assign_pointer(dev->wcid[i], NULL);
+	}
+	rcu_read_unlock();
+
+	INIT_LIST_HEAD(&dev->wcid_list);
+	INIT_LIST_HEAD(&dev->sta_poll_list);
+	dev->vif_mask = 0;
+	memset(dev->wcid_mask, 0, sizeof(dev->wcid_mask));
+
+	mt76_reset_phy(&dev->phy);
+	for (i = 0; i < ARRAY_SIZE(dev->phys); i++)
+		mt76_reset_phy(dev->phys[i]);
+}
+EXPORT_SYMBOL_GPL(mt76_reset_device);
+
+struct mt76_phy *mt76_vif_phy(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif)
 {
 	struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
 	struct mt76_chanctx *ctx;
@@ -863,6 +902,7 @@ mt76_vif_phy(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	ctx = (struct mt76_chanctx *)mlink->ctx->drv_priv;
 	return ctx->phy;
 }
+EXPORT_SYMBOL_GPL(mt76_vif_phy);
 
 static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
 {
@@ -1712,6 +1752,10 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
 	skb_queue_splice_tail_init(&wcid->tx_pending, &list);
 	spin_unlock(&wcid->tx_pending.lock);
 
+	spin_lock(&wcid->tx_offchannel.lock);
+	skb_queue_splice_tail_init(&wcid->tx_offchannel, &list);
+	spin_unlock(&wcid->tx_offchannel.lock);
+
 	spin_unlock_bh(&phy->tx_lock);
 
 	while ((skb = __skb_dequeue(&list)) != NULL) {
@@ -1723,7 +1767,7 @@ EXPORT_SYMBOL_GPL(mt76_wcid_cleanup);
 
 void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid)
 {
-	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
+	if (test_bit(MT76_MCU_RESET, &dev->phy.state) || !wcid->sta)
 		return;
 
 	spin_lock_bh(&dev->sta_poll_lock);
@@ -1733,6 +1777,17 @@ void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid)
 }
 EXPORT_SYMBOL_GPL(mt76_wcid_add_poll);
 
+s8 mt76_get_power_bound(struct mt76_phy *phy, s8 txpower)
+{
+	int n_chains = hweight16(phy->chainmask);
+
+	txpower = mt76_get_sar_power(phy, phy->chandef.chan, txpower * 2);
+	txpower -= mt76_tx_power_path_delta(n_chains);
+
+	return txpower;
+}
+EXPORT_SYMBOL_GPL(mt76_get_power_bound);
+
 int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		     unsigned int link_id, int *dbm)
 {
@@ -1743,7 +1798,7 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		return -EINVAL;
 
 	n_chains = hweight16(phy->chainmask);
-	delta = mt76_tx_power_nss_delta(n_chains);
+	delta = mt76_tx_power_path_delta(n_chains);
 	*dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2);
 
 	return 0;
@@ -1914,7 +1969,8 @@ void mt76_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 }
 EXPORT_SYMBOL_GPL(mt76_sw_scan_complete);
 
-int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+int mt76_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant,
+		     u32 *rx_ant)
 {
 	struct mt76_phy *phy = hw->priv;
 	struct mt76_dev *dev = phy->dev;
diff --git a/sys/contrib/dev/mediatek/mt76/mcu.c b/sys/contrib/dev/mediatek/mt76/mcu.c
index f8f47a40d3be..d554eed10986 100644
--- a/sys/contrib/dev/mediatek/mt76/mcu.c
+++ b/sys/contrib/dev/mediatek/mt76/mcu.c
@@ -78,6 +78,10 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
 	unsigned long expires;
 	int ret, seq;
 
+	if (mt76_is_sdio(dev))
+		if (test_bit(MT76_RESET, &dev->phy.state) && atomic_read(&dev->bus_hung))
+			return -EIO;
+
 	if (ret_skb)
 		*ret_skb = NULL;
 
diff --git a/sys/contrib/dev/mediatek/mt76/mt76.h b/sys/contrib/dev/mediatek/mt76/mt76.h
index c54d02346262..0b7686e6c36e 100644
--- a/sys/contrib/dev/mediatek/mt76/mt76.h
+++ b/sys/contrib/dev/mediatek/mt76/mt76.h
@@ -20,7 +20,6 @@
 #include <linux/debugfs.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <net/page_pool.h>
 #endif
 #include <net/mac80211.h>
 #include <net/page_pool/helpers.h>
@@ -170,6 +169,16 @@ enum mt76_dfs_state {
 	MT_DFS_STATE_ACTIVE,
 };
 
+#define MT76_RNR_SCAN_MAX_BSSIDS       16
+struct mt76_scan_rnr_param {
+	u8 bssid[MT76_RNR_SCAN_MAX_BSSIDS][ETH_ALEN];
+	u8 channel[MT76_RNR_SCAN_MAX_BSSIDS];
+	u8 random_mac[ETH_ALEN];
+	u8 seq_num;
+	u8 bssid_num;
+	u32 sreq_flag;
+};
+
 struct mt76_queue_buf {
 	dma_addr_t addr;
 	u16 len:15,
@@ -359,6 +368,7 @@ struct mt76_wcid {
 	u8 hw_key_idx;
 	u8 hw_key_idx2;
 
+	u8 offchannel:1;
 	u8 sta:1;
 	u8 sta_disabled:1;
 	u8 amsdu:1;
@@ -499,6 +509,7 @@ struct mt76_hw_cap {
 #define MT_DRV_RX_DMA_HDR		BIT(3)
 #define MT_DRV_HW_MGMT_TXQ		BIT(4)
 #define MT_DRV_AMSDU_OFFLOAD		BIT(5)
+#define MT_DRV_IGNORE_TXS_FAILED	BIT(6)
 
 struct mt76_driver_ops {
 	u32 drv_flags;
@@ -777,6 +788,7 @@ struct mt76_testmode_data {
 
 struct mt76_vif_link {
 	u8 idx;
+	u8 link_idx;
 	u8 omac_idx;
 	u8 band_idx;
 	u8 wmm_idx;
@@ -794,6 +806,7 @@ struct mt76_vif_link {
 
 struct mt76_vif_data {
 	struct mt76_vif_link __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
+	struct mt76_vif_link __rcu *offchannel_link;
 
 	struct mt76_phy *roc_phy;
 	u16 valid_links;
@@ -945,6 +958,8 @@ struct mt76_dev {
 	char alpha2[3];
 	enum nl80211_dfs_regions region;
 
+	struct mt76_scan_rnr_param rnr;
+
 	u32 debugfs_reg;
 
 	u8 csa_complete;
@@ -975,6 +990,8 @@ struct mt76_dev {
 		struct mt76_usb usb;
 		struct mt76_sdio sdio;
 	};
+
+	atomic_t bus_hung;
 };
 
 /* per-phy stats.  */
@@ -1216,6 +1233,16 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q,
 #define mt76_dereference(p, dev) \
 	rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex))
 
+static inline struct mt76_wcid *
+__mt76_wcid_ptr(struct mt76_dev *dev, u16 idx)
+{
+	if (idx >= ARRAY_SIZE(dev->wcid))
+		return NULL;
+	return rcu_dereference(dev->wcid[idx]);
+}
+
+#define mt76_wcid_ptr(dev, idx) __mt76_wcid_ptr(&(dev)->mt76, idx)
+
 struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size,
 				   const struct ieee80211_ops *ops,
 				   const struct mt76_driver_ops *drv_ops);
@@ -1223,6 +1250,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
 			 struct ieee80211_rate *rates, int n_rates);
 void mt76_unregister_device(struct mt76_dev *dev);
 void mt76_free_device(struct mt76_dev *dev);
+void mt76_reset_device(struct mt76_dev *dev);
 void mt76_unregister_phy(struct mt76_phy *phy);
 
 struct mt76_phy *mt76_alloc_radio_phy(struct mt76_dev *dev, unsigned int size,
@@ -1232,6 +1260,8 @@ struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size,
 				u8 band_idx);
 int mt76_register_phy(struct mt76_phy *phy, bool vht,
 		      struct ieee80211_rate *rates, int n_rates);
+struct mt76_phy *mt76_vif_phy(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif);
 
 struct dentry *mt76_register_debugfs_fops(struct mt76_phy *phy,
 					  const struct file_operations *ops);
@@ -1388,12 +1418,12 @@ static inline bool mt76_is_skb_pktid(u8 pktid)
 	return pktid >= MT_PACKET_ID_FIRST;
 }
 
-static inline u8 mt76_tx_power_nss_delta(u8 nss)
+static inline u8 mt76_tx_power_path_delta(u8 path)
 {
-	static const u8 nss_delta[4] = { 0, 6, 9, 12 };
-	u8 idx = nss - 1;
+	static const u8 path_delta[5] = { 0, 6, 9, 12, 14 };
+	u8 idx = path - 1;
 
-	return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0;
+	return (idx < ARRAY_SIZE(path_delta)) ? path_delta[idx] : 0;
 }
 
 static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
@@ -1490,6 +1520,8 @@ void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 int mt76_get_min_avg_rssi(struct mt76_dev *dev, u8 phy_idx);
 
+s8 mt76_get_power_bound(struct mt76_phy *phy, s8 txpower);
+
 int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		     unsigned int link_id, int *dbm);
 int mt76_init_sar_power(struct ieee80211_hw *hw,
@@ -1501,7 +1533,8 @@ int mt76_get_sar_power(struct mt76_phy *phy,
 void mt76_csa_check(struct mt76_dev *dev);
 void mt76_csa_finish(struct mt76_dev *dev);
 
-int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
+int mt76_get_antenna(struct ieee80211_hw *hw, int radio_idx, u32 *tx_ant,
+		     u32 *rx_ant);
 int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set);
 void mt76_insert_ccmp_hdr(struct sk_buff *skb, u8 key_id);
 int mt76_get_rate(struct mt76_dev *dev,
@@ -1793,7 +1826,8 @@ static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
 {
 	struct page *page = virt_to_head_page(buf);
 
-	page_pool_put_full_page(page->pp, page, allow_direct);
+	page_pool_put_full_page(pp_page_to_nmdesc(page)->pp, page,
+				allow_direct);
 }
 
 static inline void *
@@ -1864,6 +1898,9 @@ mt76_vif_link(struct mt76_dev *dev, struct ieee80211_vif *vif, int link_id)
 	struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
 	struct mt76_vif_data *mvif = mlink->mvif;
 
+	if (!link_id)
+		return mlink;
+
 	return mt76_dereference(mvif->link[link_id], dev);
 }
 
@@ -1874,7 +1911,7 @@ mt76_vif_conf_link(struct mt76_dev *dev, struct ieee80211_vif *vif,
 	struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv;
 	struct mt76_vif_data *mvif = mlink->mvif;
 
-	if (link_conf == &vif->bss_conf)
+	if (link_conf == &vif->bss_conf || !link_conf->link_id)
 		return mlink;
 
 	return mt76_dereference(mvif->link[link_conf->link_id], dev);
diff --git a/sys/contrib/dev/mediatek/mt76/mt7603/dma.c b/sys/contrib/dev/mediatek/mt76/mt7603/dma.c
index 863e5770df51..e26cc78fff94 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7603/dma.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7603/dma.c
@@ -44,7 +44,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
 	if (idx >= MT7603_WTBL_STA - 1)
 		goto free;
 
-	wcid = rcu_dereference(dev->mt76.wcid[idx]);
+	wcid = mt76_wcid_ptr(dev, idx);
 	if (!wcid)
 		goto free;
 
diff --git a/sys/contrib/dev/mediatek/mt76/mt7603/mac.c b/sys/contrib/dev/mediatek/mt76/mt7603/mac.c
index 413973d05b43..6387f9e61060 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7603/mac.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7603/mac.c
@@ -487,10 +487,7 @@ mt7603_rx_get_wcid(struct mt7603_dev *dev, u8 idx, bool unicast)
 	struct mt7603_sta *sta;
 	struct mt76_wcid *wcid;
 
-	if (idx >= MT7603_WTBL_SIZE)
-		return NULL;
-
-	wcid = rcu_dereference(dev->mt76.wcid[idx]);
+	wcid = mt76_wcid_ptr(dev, idx);
 	if (unicast || !wcid)
 		return wcid;
 
@@ -1266,12 +1263,9 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
 	if (pid == MT_PACKET_ID_NO_ACK)
 		return;
 
-	if (wcidx >= MT7603_WTBL_SIZE)
-		return;
-
 	rcu_read_lock();
 
-	wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
+	wcid = mt76_wcid_ptr(dev, wcidx);
 	if (!wcid)
 		goto out;
 
diff --git a/sys/contrib/dev/mediatek/mt76/mt7603/main.c b/sys/contrib/dev/mediatek/mt76/mt7603/main.c
index 3e8b1ec76169..0d7c84941cd0 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7603/main.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7603/main.c
@@ -216,7 +216,7 @@ static int mt7603_set_sar_specs(struct ieee80211_hw *hw,
 }
 
 static int
-mt7603_config(struct ieee80211_hw *hw, u32 changed)
+mt7603_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
 {
 	struct mt7603_dev *dev = hw->priv;
 	int ret = 0;
@@ -657,7 +657,8 @@ mt7603_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 }
 
 static void
-mt7603_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
+mt7603_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
+			  s16 coverage_class)
 {
 	struct mt7603_dev *dev = hw->priv;
 
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/init.c b/sys/contrib/dev/mediatek/mt76/mt7615/init.c
index 1e55e600981b..06d5a3f2fa67 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7615/init.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7615/init.c
@@ -275,7 +275,7 @@ void mt7615_init_txpower(struct mt7615_dev *dev,
 			 struct ieee80211_supported_band *sband)
 {
 	int i, n_chains = hweight8(dev->mphy.antenna_mask), target_chains;
-	int delta_idx, delta = mt76_tx_power_nss_delta(n_chains);
+	int delta_idx, delta = mt76_tx_power_path_delta(n_chains);
 	u8 *eep = (u8 *)dev->mt76.eeprom.data;
 	enum nl80211_band band = sband->band;
 	struct mt76_power_limits limits;
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/mac.c b/sys/contrib/dev/mediatek/mt76/mt7615/mac.c
index 994f6f8ccd87..10bf7e5b3acb 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7615/mac.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7615/mac.c
@@ -93,10 +93,7 @@ static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev,
 	struct mt7615_sta *sta;
 	struct mt76_wcid *wcid;
 
-	if (idx >= MT7615_WTBL_SIZE)
-		return NULL;
-
-	wcid = rcu_dereference(dev->mt76.wcid[idx]);
+	wcid = mt76_wcid_ptr(dev, idx);
 	if (unicast || !wcid)
 		return wcid;
 
@@ -1507,7 +1504,7 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data)
 
 	rcu_read_lock();
 
-	wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
+	wcid = mt76_wcid_ptr(dev, wcidx);
 	if (!wcid)
 		goto out;
 
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/main.c b/sys/contrib/dev/mediatek/mt76/mt7615/main.c
index 2e7b05eeef7a..15fe155ac3f3 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7615/main.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7615/main.c
@@ -97,7 +97,7 @@ static void mt7615_stop(struct ieee80211_hw *hw, bool suspend)
 	struct mt7615_phy *phy = mt7615_hw_phy(hw);
 
 	cancel_delayed_work_sync(&phy->mt76->mac_work);
-	del_timer_sync(&phy->roc_timer);
+	timer_delete_sync(&phy->roc_timer);
 	cancel_work_sync(&phy->roc_work);
 
 	cancel_delayed_work_sync(&dev->pm.ps_work);
@@ -420,7 +420,7 @@ static int mt7615_set_sar_specs(struct ieee80211_hw *hw,
 	return mt76_update_channel(phy->mt76);
 }
 
-static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
+static int mt7615_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
 {
 	struct mt7615_dev *dev = mt7615_hw_dev(hw);
 	struct mt7615_phy *phy = mt7615_hw_phy(hw);
@@ -784,7 +784,8 @@ static void mt7615_tx(struct ieee80211_hw *hw,
 	mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb);
 }
 
-static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
+static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx,
+				    u32 val)
 {
 	struct mt7615_dev *dev = mt7615_hw_dev(hw);
 	struct mt7615_phy *phy = mt7615_hw_phy(hw);
@@ -972,7 +973,8 @@ mt7615_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 }
 
 static void
-mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
+mt7615_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
+			  s16 coverage_class)
 {
 	struct mt7615_phy *phy = mt7615_hw_phy(hw);
 	struct mt7615_dev *dev = phy->dev;
@@ -984,7 +986,8 @@ mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
 }
 
 static int
-mt7615_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+mt7615_set_antenna(struct ieee80211_hw *hw, int radio_idx,
+		   u32 tx_ant, u32 rx_ant)
 {
 	struct mt7615_dev *dev = mt7615_hw_dev(hw);
 	struct mt7615_phy *phy = mt7615_hw_phy(hw);
@@ -1043,7 +1046,7 @@ void mt7615_roc_work(struct work_struct *work)
 
 void mt7615_roc_timer(struct timer_list *timer)
 {
-	struct mt7615_phy *phy = from_timer(phy, timer, roc_timer);
+	struct mt7615_phy *phy = timer_container_of(phy, timer, roc_timer);
 
 	ieee80211_queue_work(phy->mt76->hw, &phy->roc_work);
 }
@@ -1194,7 +1197,7 @@ static int mt7615_cancel_remain_on_channel(struct ieee80211_hw *hw,
 	if (!test_and_clear_bit(MT76_STATE_ROC, &phy->mt76->state))
 		return 0;
 
-	del_timer_sync(&phy->roc_timer);
+	timer_delete_sync(&phy->roc_timer);
 	cancel_work_sync(&phy->roc_work);
 
 	mt7615_mutex_acquire(phy->dev);
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/mcu.c b/sys/contrib/dev/mediatek/mt76/mt7615/mcu.c
index ccc36ee0900c..ec2f759d407f 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7615/mcu.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7615/mcu.c
@@ -2071,7 +2071,7 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
 	};
 
 	tx_power = mt76_get_sar_power(mphy, mphy->chandef.chan, tx_power);
-	tx_power -= mt76_tx_power_nss_delta(n_chains);
+	tx_power -= mt76_tx_power_path_delta(n_chains);
 	tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
 					      &limits, tx_power);
 	mphy->txpower_cur = tx_power;
@@ -2088,8 +2088,8 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
 		int delta = 0;
 
 		if (i < n_chains - 1)
-			delta = mt76_tx_power_nss_delta(n_chains) -
-				mt76_tx_power_nss_delta(i + 1);
+			delta = mt76_tx_power_path_delta(n_chains) -
+				mt76_tx_power_path_delta(i + 1);
 		sku[MT_SKU_1SS_DELTA + i] = delta;
 	}
 }
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/pci_mac.c b/sys/contrib/dev/mediatek/mt76/mt7615/pci_mac.c
index 5da2bf332af0..fe8a3d852dbf 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7615/pci_mac.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7615/pci_mac.c
@@ -223,12 +223,12 @@ void mt7615_mac_reset_work(struct work_struct *work)
 	set_bit(MT76_MCU_RESET, &dev->mphy.state);
 	wake_up(&dev->mt76.mcu.wait);
 	cancel_delayed_work_sync(&dev->mphy.mac_work);
-	del_timer_sync(&dev->phy.roc_timer);
+	timer_delete_sync(&dev->phy.roc_timer);
 	cancel_work_sync(&dev->phy.roc_work);
 	if (phy2) {
 		set_bit(MT76_RESET, &phy2->mt76->state);
 		cancel_delayed_work_sync(&phy2->mt76->mac_work);
-		del_timer_sync(&phy2->roc_timer);
+		timer_delete_sync(&phy2->roc_timer);
 		cancel_work_sync(&phy2->roc_work);
 	}
 
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/sdio_mcu.c b/sys/contrib/dev/mediatek/mt76/mt7615/sdio_mcu.c
deleted file mode 100644
index a7b8acb2da83..000000000000
--- a/sys/contrib/dev/mediatek/mt76/mt7615/sdio_mcu.c
+++ /dev/null
@@ -1,180 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (C) 2020 MediaTek Inc.
- *
- * Author: Felix Fietkau <nbd@nbd.name>
- *	   Lorenzo Bianconi <lorenzo@kernel.org>
- *	   Sean Wang <sean.wang@mediatek.com>
- */
-#include <linux/kernel.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/module.h>
-#include <linux/iopoll.h>
-
-#include "../sdio.h"
-#include "mt7615.h"
-#include "mac.h"
-#include "mcu.h"
-#include "regs.h"
-
-static int mt7663s_mcu_init_sched(struct mt7615_dev *dev)
-{
-	struct mt76_sdio *sdio = &dev->mt76.sdio;
-	u32 txdwcnt;
-
-	sdio->sched.pse_data_quota = mt76_get_field(dev, MT_PSE_PG_HIF0_GROUP,
-						    MT_HIF0_MIN_QUOTA);
-	sdio->sched.pse_mcu_quota = mt76_get_field(dev, MT_PSE_PG_HIF1_GROUP,
-						   MT_HIF1_MIN_QUOTA);
-	sdio->sched.ple_data_quota = mt76_get_field(dev, MT_PLE_PG_HIF0_GROUP,
-						    MT_HIF0_MIN_QUOTA);
-	sdio->sched.pse_page_size = MT_PSE_PAGE_SZ;
-	txdwcnt = mt76_get_field(dev, MT_PP_TXDWCNT,
-				 MT_PP_TXDWCNT_TX1_ADD_DW_CNT);
-	sdio->sched.deficit = txdwcnt << 2;
-
-	return 0;
-}
-
-static int
-mt7663s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
-			 int cmd, int *seq)
-{
-	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
-	int ret;
-
-	mt7615_mcu_fill_msg(dev, skb, cmd, seq);
-	ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0);
-	if (ret)
-		return ret;
-
-	mt76_queue_kick(dev, mdev->q_mcu[MT_MCUQ_WM]);
-
-	return ret;
-}
-
-static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
-{
-	struct sdio_func *func = dev->mt76.sdio.func;
-	struct mt76_phy *mphy = &dev->mt76.phy;
-	struct mt76_connac_pm *pm = &dev->pm;
-	u32 status;
-	int ret;
-
-	sdio_claim_host(func);
-
-	sdio_writel(func, WHLPCR_FW_OWN_REQ_CLR, MCR_WHLPCR, NULL);
-
-	ret = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
-				 status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);
-	if (ret < 0) {
-		dev_err(dev->mt76.dev, "Cannot get ownership from device");
-	} else {
-		clear_bit(MT76_STATE_PM, &mphy->state);
-
-		pm->stats.last_wake_event = jiffies;
-		pm->stats.doze_time += pm->stats.last_wake_event -
-				       pm->stats.last_doze_event;
-	}
-	sdio_release_host(func);
-
-	return ret;
-}
-
-static int mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev)
-{
-	struct mt76_phy *mphy = &dev->mt76.phy;
-	int ret = 0;
-
-	mutex_lock(&dev->pm.mutex);
-
-	if (test_bit(MT76_STATE_PM, &mphy->state))
-		ret = __mt7663s_mcu_drv_pmctrl(dev);
-
-	mutex_unlock(&dev->pm.mutex);
-
-	return ret;
-}
-
-static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev)
-{
-	struct sdio_func *func = dev->mt76.sdio.func;
-	struct mt76_phy *mphy = &dev->mt76.phy;
-	struct mt76_connac_pm *pm = &dev->pm;
-	int ret = 0;
-	u32 status;
-
-	mutex_lock(&pm->mutex);
-
-	if (mt76_connac_skip_fw_pmctrl(mphy, pm))
-		goto out;
-
-	sdio_claim_host(func);
-
-	sdio_writel(func, WHLPCR_FW_OWN_REQ_SET, MCR_WHLPCR, NULL);
-
-	ret = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
-				 !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000);
-	if (ret < 0) {
-		dev_err(dev->mt76.dev, "Cannot set ownership to device");
-		clear_bit(MT76_STATE_PM, &mphy->state);
-	} else {
-		pm->stats.last_doze_event = jiffies;
-		pm->stats.awake_time += pm->stats.last_doze_event -
-					pm->stats.last_wake_event;
-	}
-
-	sdio_release_host(func);
-out:
-	mutex_unlock(&pm->mutex);
-
-	return ret;
-}
-
-int mt7663s_mcu_init(struct mt7615_dev *dev)
-{
-	static const struct mt76_mcu_ops mt7663s_mcu_ops = {
-		.headroom = sizeof(struct mt7615_mcu_txd),
-		.tailroom = MT_USB_TAIL_SIZE,
-		.mcu_skb_send_msg = mt7663s_mcu_send_message,
-		.mcu_parse_response = mt7615_mcu_parse_response,
-		.mcu_rr = mt76_connac_mcu_reg_rr,
-		.mcu_wr = mt76_connac_mcu_reg_wr,
-	};
-	struct mt7615_mcu_ops *mcu_ops;
-	int ret;
-
-	ret = __mt7663s_mcu_drv_pmctrl(dev);
-	if (ret)
-		return ret;
-
-	dev->mt76.mcu_ops = &mt7663s_mcu_ops;
-
-	ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
-	if (ret) {
-		mt7615_mcu_restart(&dev->mt76);
-		if (!mt76_poll_msec(dev, MT_CONN_ON_MISC,
-				    MT_TOP_MISC2_FW_N9_RDY, 0, 500))
-			return -EIO;
-	}
-
-	ret = __mt7663_load_firmware(dev);
-	if (ret)
-		return ret;
-
-	mcu_ops = devm_kmemdup(dev->mt76.dev, dev->mcu_ops, sizeof(*mcu_ops),
-			       GFP_KERNEL);
-	if (!mcu_ops)
-		return -ENOMEM;
-
-	mcu_ops->set_drv_ctrl = mt7663s_mcu_drv_pmctrl;
-	mcu_ops->set_fw_ctrl = mt7663s_mcu_fw_pmctrl;
-	dev->mcu_ops = mcu_ops;
-
-	ret = mt7663s_mcu_init_sched(dev);
-	if (ret)
-		return ret;
-
-	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
-
-	return 0;
-}
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/usb.c b/sys/contrib/dev/mediatek/mt76/mt7615/usb.c
index 4aa9fa1c4a23..d96e06b4fee1 100644
--- a/sys/contrib/dev/mediatek/mt76/mt7615/usb.c
+++ b/sys/contrib/dev/mediatek/mt76/mt7615/usb.c
@@ -85,7 +85,7 @@ static void mt7663u_stop(struct ieee80211_hw *hw, bool suspend)
 	struct mt7615_dev *dev = hw->priv;
 
 	clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
-	del_timer_sync(&phy->roc_timer);
+	timer_delete_sync(&phy->roc_timer);
 	cancel_work_sync(&phy->roc_work);
 	cancel_delayed_work_sync(&phy->scan_work);
 	cancel_delayed_work_sync(&phy->mt76->mac_work);
diff --git a/sys/contrib/dev/mediatek/mt76/mt7615/usb_mcu.c b/sys/contrib/dev/mediatek/mt76/mt7615/usb_mcu.c
deleted file mode 100644
index 33c01f8ce8e2..000000000000
--- a/sys/contrib/dev/mediatek/mt76/mt7615/usb_mcu.c
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (C) 2019 MediaTek Inc.
- *
- * Author: Felix Fietkau <nbd@nbd.name>
- *	   Lorenzo Bianconi <lorenzo@kernel.org>
- *	   Sean Wang <sean.wang@mediatek.com>
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "mt7615.h"
-#include "mac.h"
-#include "mcu.h"
-#include "regs.h"
-
-static int
-mt7663u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
-			 int cmd, int *seq)
-{
-	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
-	int ret, ep, len, pad;
-
-	mt7615_mcu_fill_msg(dev, skb, cmd, seq);
-	if (cmd != MCU_CMD(FW_SCATTER))
-		ep = MT_EP_OUT_INBAND_CMD;
-	else
-		ep = MT_EP_OUT_AC_BE;
-
-	len = skb->len;
-	put_unaligned_le32(len, skb_push(skb, sizeof(len)));
-	pad = round_up(skb->len, 4) + 4 - skb->len;
-	ret = mt76_skb_adjust_pad(skb, pad);
-	if (ret < 0)
-		goto out;
-
*** 10286 LINES SKIPPED ***