mt76 fixes for 7.2

- fix warnings on removing device
 - null pointer deref fixes
 - fix for data structure confusion on USB/SDIO devices
 -----BEGIN PGP SIGNATURE-----
 Comment: GPGTools - http://gpgtools.org
 
 iF0EABECAB0WIQR10Rp9kadxD0kAQu/XfRQdAqdu9QUCamBjSgAKCRDXfRQdAqdu
 9dl8AJ9W13LLmh6qEat4rSYy/u77S5LL7wCgvKofaWK8EI1NhziBi3nw++BZGhg=
 =34vm
 -----END PGP SIGNATURE-----

Merge tag 'mt76-fixes-2026-07-22' of https://github.com/nbd168/wireless

Felix Fietkau says:
===================
mt76 fixes for 7.2

- fix warnings on removing device
- null pointer deref fixes
- fix for data structure confusion on USB/SDIO devices
===================

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2026-07-22 10:44:17 +02:00
commit 2afc33c538
14 changed files with 72 additions and 26 deletions

View File

@ -38,8 +38,8 @@ config MT792x_USB
select MT76_USB
config MT76_NPU
bool
depends on MT76_CORE
tristate
depends on NET_AIROHA_NPU=y || MT76_CORE=NET_AIROHA_NPU
source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig"

View File

@ -12,7 +12,11 @@ mt76-y := \
mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \
tx.o agg-rx.o mcu.o wed.o scan.o channel.o
mt76-$(CONFIG_MT76_NPU) += npu.o
ifdef CONFIG_MT76_NPU
# CONFIG_MT76_NPU is tristate to simplify dependency tracking,
# but it behaves as a bool symbol here.
mt76-y += npu.o
endif
mt76-$(CONFIG_PCI) += pci.o
mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o

View File

@ -1189,7 +1189,10 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
mt76_for_each_q_rx(dev, i) {
struct mt76_queue *q = &dev->q_rx[i];
netif_napi_del(&dev->napi[i]);
if (!mt76_queue_is_wed_rro(q)) {
napi_disable(&dev->napi[i]);
netif_napi_del(&dev->napi[i]);
}
mt76_dma_rx_cleanup(dev, q);
page_pool_destroy(q->page_pool);

View File

@ -181,7 +181,7 @@ mt76_eeprom_override(struct mt76_phy *phy)
if (err == -EPROBE_DEFER)
return err;
if (err) {
if (!is_valid_ether_addr(phy->macaddr)) {
eth_random_addr(phy->macaddr);
dev_info(dev->dev,
"Invalid MAC address, using random address %pM\n",

View File

@ -1647,7 +1647,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len);
#ifdef CONFIG_MT76_NPU
#if IS_ENABLED(CONFIG_MT76_NPU)
void mt76_npu_check_ppe(struct mt76_dev *dev, struct sk_buff *skb,
u32 info);
int mt76_npu_dma_add_buf(struct mt76_phy *phy, struct mt76_queue *q,
@ -1736,12 +1736,12 @@ static inline int mt76_npu_send_txrx_addr(struct mt76_dev *dev, int ifindex,
static inline bool mt76_npu_device_active(struct mt76_dev *dev)
{
return !!rcu_access_pointer(dev->mmio.npu);
return mt76_is_mmio(dev) && !!rcu_access_pointer(dev->mmio.npu);
}
static inline bool mt76_ppe_device_active(struct mt76_dev *dev)
{
return !!rcu_access_pointer(dev->mmio.ppe_dev);
return mt76_is_mmio(dev) && !!rcu_access_pointer(dev->mmio.ppe_dev);
}
static inline int mt76_npu_send_msg(struct airoha_npu *npu, int ifindex,

View File

@ -1601,6 +1601,8 @@ bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len)
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
if (!mt76_is_mmio(mdev))
return false;
mt7615_mac_tx_free(dev, data, len);
return false;
case PKT_TYPE_TXS:
@ -1634,6 +1636,10 @@ void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
dev_kfree_skb(skb);
break;
case PKT_TYPE_TXRX_NOTIFY:
if (!mt76_is_mmio(mdev)) {
dev_kfree_skb(skb);
break;
}
mt7615_mac_tx_free(dev, skb->data, skb->len);
dev_kfree_skb(skb);
break;

View File

@ -1458,6 +1458,8 @@ mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
struct bss_info_uni_he *he;
cap = mt76_connac_get_he_phy_cap(phy, vif);
if (!cap)
return;
he = (struct bss_info_uni_he *)tlv;
he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;

View File

@ -595,6 +595,8 @@ mt7915_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct tlv *tlv;
cap = mt76_connac_get_he_phy_cap(phy->mt76, vif);
if (!cap)
return;
tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_HE_BASIC, sizeof(*he));
@ -1177,13 +1179,12 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
}
static void
mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
struct mt7915_phy *phy, struct sta_rec_bf *bf)
mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta,
const struct ieee80211_sta_he_cap *vc,
struct sta_rec_bf *bf)
{
struct ieee80211_sta_he_cap *pc = &sta->deflink.he_cap;
struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
const struct ieee80211_sta_he_cap *vc =
mt76_connac_get_he_phy_cap(phy->mt76, vif);
const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;
u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);
u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
@ -1242,6 +1243,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_phy *phy = mvif->phy;
const struct ieee80211_sta_he_cap *vc = NULL;
int tx_ant = hweight8(phy->mt76->chainmask) - 1;
struct sta_rec_bf *bf;
struct tlv *tlv;
@ -1260,6 +1262,12 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
if (!ebf && !dev->ibf)
return;
if (sta->deflink.he_cap.has_he && ebf) {
vc = mt76_connac_get_he_phy_cap(phy->mt76, vif);
if (!vc)
return;
}
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BF, sizeof(*bf));
bf = (struct sta_rec_bf *)tlv;
@ -1268,7 +1276,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
* ht: iBF only, since mac80211 lacks of eBF support
*/
if (sta->deflink.he_cap.has_he && ebf)
mt7915_mcu_sta_bfer_he(sta, vif, phy, bf);
mt7915_mcu_sta_bfer_he(sta, vc, bf);
else if (sta->deflink.vht_cap.vht_supported)
mt7915_mcu_sta_bfer_vht(sta, phy, bf, ebf);
else if (sta->deflink.ht_cap.ht_supported)

View File

@ -570,8 +570,9 @@ bool mt7921_rx_check(struct mt76_dev *mdev, void *data, int len)
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
/* PKT_TYPE_TXRX_NOTIFY can be received only by mmio devices */
mt7921_mac_tx_free(dev, data, len); /* mmio */
if (!mt76_is_mmio(mdev))
return false;
mt7921_mac_tx_free(dev, data, len);
return false;
case PKT_TYPE_TXS:
for (rxd += 2; rxd + 8 <= end; rxd += 8)
@ -600,7 +601,10 @@ void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
/* PKT_TYPE_TXRX_NOTIFY can be received only by mmio devices */
if (!mt76_is_mmio(mdev)) {
napi_consume_skb(skb, 1);
break;
}
mt7921_mac_tx_free(dev, skb->data, skb->len);
napi_consume_skb(skb, 1);
break;

View File

@ -1203,8 +1203,9 @@ bool mt7925_rx_check(struct mt76_dev *mdev, void *data, int len)
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
/* PKT_TYPE_TXRX_NOTIFY can be received only by mmio devices */
mt7925_mac_tx_free(dev, data, len); /* mmio */
if (!mt76_is_mmio(mdev))
return false;
mt7925_mac_tx_free(dev, data, len);
return false;
case PKT_TYPE_TXS:
for (rxd += 4; rxd + 12 <= end; rxd += 12)
@ -1240,7 +1241,10 @@ void mt7925_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
/* PKT_TYPE_TXRX_NOTIFY can be received only by mmio devices */
if (!mt76_is_mmio(mdev)) {
napi_consume_skb(skb, 1);
break;
}
mt7925_mac_tx_free(dev, skb->data, skb->len);
napi_consume_skb(skb, 1);
break;
@ -1284,6 +1288,9 @@ mt7925_vif_connect_iter(void *priv, u8 *mac,
for_each_set_bit(i, &valid, IEEE80211_MLD_MAX_NUM_LINKS) {
bss_conf = mt792x_vif_to_bss_conf(vif, i);
if (!bss_conf)
continue;
mconf = mt792x_vif_to_link(mvif, i);
mt76_connac_mcu_uni_add_dev(&dev->mphy, bss_conf, &mconf->mt76,

View File

@ -1713,6 +1713,9 @@ static void mt7925_sta_set_decap_offload(struct ieee80211_hw *hw,
mconf = mt792x_vif_to_link(mvif, i);
mlink = mt792x_sta_to_link(msta, i);
if (!mlink)
continue;
if (enabled)
set_bit(MT_WCID_FLAG_HDR_TRANS, &mlink->wcid.flags);
else

View File

@ -2773,6 +2773,8 @@ mt7925_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf,
struct tlv *tlv;
cap = mt76_connac_get_he_phy_cap(phy->mt76, link_conf->vif);
if (!cap)
return;
tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he));

View File

@ -16,6 +16,6 @@ config MT7996E
config MT7996_NPU
bool "MT7996 (PCIe) NPU support"
depends on MT7996E
depends on NET_AIROHA_NPU=y || MT7996E=NET_AIROHA_NPU
depends on NET_AIROHA_NPU=y || MT76_CORE=NET_AIROHA_NPU
select MT76_NPU
default n

View File

@ -935,6 +935,8 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct tlv *tlv;
cap = mt76_connac_get_he_phy_cap(phy->mt76, vif);
if (!cap)
return;
tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he));
@ -1855,17 +1857,18 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_link_sta *link_sta,
{
struct ieee80211_sta_he_cap *pc = &link_sta->he_cap;
struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
const struct ieee80211_sta_he_cap *vc =
mt76_connac_get_he_phy_cap(phy->mt76, vif);
const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;
u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);
u8 nss_mcs = mt7996_mcu_get_sta_nss(mcs_map);
const struct ieee80211_he_cap_elem *ve;
const struct ieee80211_sta_he_cap *vc;
u8 snd_dim, sts;
vc = mt76_connac_get_he_phy_cap(phy->mt76, vif);
if (!vc)
return;
bf->tx_mode = MT_PHY_TYPE_HE_SU;
ve = &vc->he_cap_elem;
mt7996_mcu_sta_sounding_rate(bf, phy);
@ -1921,14 +1924,18 @@ mt7996_mcu_sta_bfer_eht(struct ieee80211_link_sta *link_sta,
struct ieee80211_sta_eht_cap *pc = &link_sta->eht_cap;
struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem;
struct ieee80211_eht_mcs_nss_supp *eht_nss = &pc->eht_mcs_nss_supp;
const struct ieee80211_sta_eht_cap *vc =
mt76_connac_get_eht_phy_cap(phy->mt76, vif);
const struct ieee80211_eht_cap_elem_fixed *ve = &vc->eht_cap_elem;
u8 nss_mcs = u8_get_bits(eht_nss->bw._80.rx_tx_mcs9_max_nss,
IEEE80211_EHT_MCS_NSS_RX) - 1;
const struct ieee80211_eht_cap_elem_fixed *ve;
const struct ieee80211_sta_eht_cap *vc;
u8 snd_dim, sts;
vc = mt76_connac_get_eht_phy_cap(phy->mt76, vif);
if (!vc)
return;
bf->tx_mode = MT_PHY_TYPE_EHT_MU;
ve = &vc->eht_cap_elem;
mt7996_mcu_sta_sounding_rate(bf, phy);