git: 54c8cac0ad8e - stable/15 - mt76: update Mediatek's mt76 driver
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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 ***