The branch stable/15 has been updated by bz:

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

commit 54c8cac0ad8e90f4da9e95cf36419dfe83d6b2f0
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2025-10-17 21:22:52 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
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 <[email protected]>
- *        Lorenzo Bianconi <[email protected]>
- *        Sean Wang <[email protected]>
- */
-#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 <[email protected]>
- *        Lorenzo Bianconi <[email protected]>
- *        Sean Wang <[email protected]>
- */
-#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 ***

Reply via email to