Skip to content

Commit b3bf3dc

Browse files
committed
Merge tag 'mt76-fixes-2025-08-27' of https://github.com/nbd168/wireless
Felix Fietkay says: =================== mt76 fixes for 6.17 - fix regressions from mt7996 MLO support rework - fix offchannel handling issues on mt7996 - mt792x fixes - fix multiple wcid linked list corruption issues =================== Change-Id: Ib3e9a3217a40b9da69e122514d47fa46699c864b Signed-off-by: Johannes Berg <[email protected]>
2 parents 0e20450 + 49fba87 commit b3bf3dc

File tree

12 files changed

+124
-51
lines changed

12 files changed

+124
-51
lines changed

drivers/net/wireless/mediatek/mt76/mac80211.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,43 @@ void mt76_free_device(struct mt76_dev *dev)
818818
}
819819
EXPORT_SYMBOL_GPL(mt76_free_device);
820820

821+
static void mt76_reset_phy(struct mt76_phy *phy)
822+
{
823+
if (!phy)
824+
return;
825+
826+
INIT_LIST_HEAD(&phy->tx_list);
827+
}
828+
829+
void mt76_reset_device(struct mt76_dev *dev)
830+
{
831+
int i;
832+
833+
rcu_read_lock();
834+
for (i = 0; i < ARRAY_SIZE(dev->wcid); i++) {
835+
struct mt76_wcid *wcid;
836+
837+
wcid = rcu_dereference(dev->wcid[i]);
838+
if (!wcid)
839+
continue;
840+
841+
wcid->sta = 0;
842+
mt76_wcid_cleanup(dev, wcid);
843+
rcu_assign_pointer(dev->wcid[i], NULL);
844+
}
845+
rcu_read_unlock();
846+
847+
INIT_LIST_HEAD(&dev->wcid_list);
848+
INIT_LIST_HEAD(&dev->sta_poll_list);
849+
dev->vif_mask = 0;
850+
memset(dev->wcid_mask, 0, sizeof(dev->wcid_mask));
851+
852+
mt76_reset_phy(&dev->phy);
853+
for (i = 0; i < ARRAY_SIZE(dev->phys); i++)
854+
mt76_reset_phy(dev->phys[i]);
855+
}
856+
EXPORT_SYMBOL_GPL(mt76_reset_device);
857+
821858
struct mt76_phy *mt76_vif_phy(struct ieee80211_hw *hw,
822859
struct ieee80211_vif *vif)
823860
{
@@ -1679,6 +1716,10 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid)
16791716
skb_queue_splice_tail_init(&wcid->tx_pending, &list);
16801717
spin_unlock(&wcid->tx_pending.lock);
16811718

1719+
spin_lock(&wcid->tx_offchannel.lock);
1720+
skb_queue_splice_tail_init(&wcid->tx_offchannel, &list);
1721+
spin_unlock(&wcid->tx_offchannel.lock);
1722+
16821723
spin_unlock_bh(&phy->tx_lock);
16831724

16841725
while ((skb = __skb_dequeue(&list)) != NULL) {
@@ -1690,7 +1731,7 @@ EXPORT_SYMBOL_GPL(mt76_wcid_cleanup);
16901731

16911732
void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid)
16921733
{
1693-
if (test_bit(MT76_MCU_RESET, &dev->phy.state))
1734+
if (test_bit(MT76_MCU_RESET, &dev->phy.state) || !wcid->sta)
16941735
return;
16951736

16961737
spin_lock_bh(&dev->sta_poll_lock);

drivers/net/wireless/mediatek/mt76/mt76.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
12431243
struct ieee80211_rate *rates, int n_rates);
12441244
void mt76_unregister_device(struct mt76_dev *dev);
12451245
void mt76_free_device(struct mt76_dev *dev);
1246+
void mt76_reset_device(struct mt76_dev *dev);
12461247
void mt76_unregister_phy(struct mt76_phy *phy);
12471248

12481249
struct mt76_phy *mt76_alloc_radio_phy(struct mt76_dev *dev, unsigned int size,

drivers/net/wireless/mediatek/mt76/mt7915/mac.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,17 +1460,15 @@ mt7915_mac_full_reset(struct mt7915_dev *dev)
14601460
if (i == 10)
14611461
dev_err(dev->mt76.dev, "chip full reset failed\n");
14621462

1463-
spin_lock_bh(&dev->mt76.sta_poll_lock);
1464-
while (!list_empty(&dev->mt76.sta_poll_list))
1465-
list_del_init(dev->mt76.sta_poll_list.next);
1466-
spin_unlock_bh(&dev->mt76.sta_poll_lock);
1467-
1468-
memset(dev->mt76.wcid_mask, 0, sizeof(dev->mt76.wcid_mask));
1469-
dev->mt76.vif_mask = 0;
14701463
dev->phy.omac_mask = 0;
14711464
if (phy2)
14721465
phy2->omac_mask = 0;
14731466

1467+
mt76_reset_device(&dev->mt76);
1468+
1469+
INIT_LIST_HEAD(&dev->sta_rc_list);
1470+
INIT_LIST_HEAD(&dev->twt_list);
1471+
14741472
i = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
14751473
dev->mt76.global_wcid.idx = i;
14761474
dev->recovery.hw_full_reset = false;

drivers/net/wireless/mediatek/mt76/mt7921/main.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,11 +1459,8 @@ static int mt7921_pre_channel_switch(struct ieee80211_hw *hw,
14591459
if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc)
14601460
return -EOPNOTSUPP;
14611461

1462-
/* Avoid beacon loss due to the CAC(Channel Availability Check) time
1463-
* of the AP.
1464-
*/
14651462
if (!cfg80211_chandef_usable(hw->wiphy, &chsw->chandef,
1466-
IEEE80211_CHAN_RADAR))
1463+
IEEE80211_CHAN_DISABLED))
14671464
return -EOPNOTSUPP;
14681465

14691466
return 0;

drivers/net/wireless/mediatek/mt76/mt7925/mac.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1449,7 +1449,7 @@ void mt7925_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
14491449
sta = wcid_to_sta(wcid);
14501450

14511451
if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
1452-
mt76_connac2_tx_check_aggr(sta, txwi);
1452+
mt7925_tx_check_aggr(sta, e->skb, wcid);
14531453

14541454
skb_pull(e->skb, headroom);
14551455
mt76_tx_complete_skb(mdev, e->wcid, e->skb);

drivers/net/wireless/mediatek/mt76/mt7925/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,9 @@ mt7925_mac_sta_remove_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,
11911191
struct mt792x_bss_conf *mconf;
11921192
struct mt792x_link_sta *mlink;
11931193

1194+
if (vif->type == NL80211_IFTYPE_AP)
1195+
break;
1196+
11941197
link_sta = mt792x_sta_to_link_sta(vif, sta, link_id);
11951198
if (!link_sta)
11961199
continue;
@@ -2069,8 +2072,10 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
20692072
GFP_KERNEL);
20702073
mlink = devm_kzalloc(dev->mt76.dev, sizeof(*mlink),
20712074
GFP_KERNEL);
2072-
if (!mconf || !mlink)
2075+
if (!mconf || !mlink) {
2076+
mt792x_mutex_release(dev);
20732077
return -ENOMEM;
2078+
}
20742079
}
20752080

20762081
mconfs[link_id] = mconf;

drivers/net/wireless/mediatek/mt76/mt7925/mcu.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,13 +1834,13 @@ mt7925_mcu_sta_eht_mld_tlv(struct sk_buff *skb,
18341834
struct tlv *tlv;
18351835
u16 eml_cap;
18361836

1837+
if (!ieee80211_vif_is_mld(vif))
1838+
return;
1839+
18371840
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_EHT_MLD, sizeof(*eht_mld));
18381841
eht_mld = (struct sta_rec_eht_mld *)tlv;
18391842
eht_mld->mld_type = 0xff;
18401843

1841-
if (!ieee80211_vif_is_mld(vif))
1842-
return;
1843-
18441844
ext_capa = cfg80211_get_iftype_ext_capa(wiphy,
18451845
ieee80211_vif_type_p2p(vif));
18461846
if (!ext_capa)
@@ -1912,6 +1912,7 @@ mt7925_mcu_sta_cmd(struct mt76_phy *phy,
19121912
struct mt76_dev *dev = phy->dev;
19131913
struct mt792x_bss_conf *mconf;
19141914
struct sk_buff *skb;
1915+
int conn_state;
19151916

19161917
mconf = mt792x_vif_to_link(mvif, info->wcid->link_id);
19171918

@@ -1920,10 +1921,13 @@ mt7925_mcu_sta_cmd(struct mt76_phy *phy,
19201921
if (IS_ERR(skb))
19211922
return PTR_ERR(skb);
19221923

1924+
conn_state = info->enable ? CONN_STATE_PORT_SECURE :
1925+
CONN_STATE_DISCONNECT;
1926+
19231927
if (info->enable && info->link_sta) {
19241928
mt76_connac_mcu_sta_basic_tlv(dev, skb, info->link_conf,
19251929
info->link_sta,
1926-
info->enable, info->newly);
1930+
conn_state, info->newly);
19271931
mt7925_mcu_sta_phy_tlv(skb, info->vif, info->link_sta);
19281932
mt7925_mcu_sta_ht_tlv(skb, info->link_sta);
19291933
mt7925_mcu_sta_vht_tlv(skb, info->link_sta);

drivers/net/wireless/mediatek/mt76/mt7996/mac.c

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static struct mt76_wcid *mt7996_rx_get_wcid(struct mt7996_dev *dev,
6262
int i;
6363

6464
wcid = mt76_wcid_ptr(dev, idx);
65-
if (!wcid)
65+
if (!wcid || !wcid->sta)
6666
return NULL;
6767

6868
if (!mt7996_band_valid(dev, band_idx))
@@ -903,8 +903,12 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
903903
IEEE80211_TX_CTRL_MLO_LINK);
904904

905905
mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL;
906-
if (mvif)
907-
mlink = rcu_dereference(mvif->mt76.link[link_id]);
906+
if (mvif) {
907+
if (wcid->offchannel)
908+
mlink = rcu_dereference(mvif->mt76.offchannel_link);
909+
if (!mlink)
910+
mlink = rcu_dereference(mvif->mt76.link[link_id]);
911+
}
908912

909913
if (mlink) {
910914
omac_idx = mlink->omac_idx;
@@ -1243,8 +1247,10 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
12431247
idx = FIELD_GET(MT_TXFREE_INFO_WLAN_ID, info);
12441248
wcid = mt76_wcid_ptr(dev, idx);
12451249
sta = wcid_to_sta(wcid);
1246-
if (!sta)
1250+
if (!sta) {
1251+
link_sta = NULL;
12471252
goto next;
1253+
}
12481254

12491255
link_sta = rcu_dereference(sta->link[wcid->link_id]);
12501256
if (!link_sta)
@@ -1694,43 +1700,53 @@ mt7996_wait_reset_state(struct mt7996_dev *dev, u32 state)
16941700
static void
16951701
mt7996_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif)
16961702
{
1697-
struct ieee80211_hw *hw = priv;
1703+
struct ieee80211_bss_conf *link_conf;
1704+
struct mt7996_phy *phy = priv;
1705+
struct mt7996_dev *dev = phy->dev;
1706+
unsigned int link_id;
1707+
16981708

16991709
switch (vif->type) {
17001710
case NL80211_IFTYPE_MESH_POINT:
17011711
case NL80211_IFTYPE_ADHOC:
17021712
case NL80211_IFTYPE_AP:
1703-
mt7996_mcu_add_beacon(hw, vif, &vif->bss_conf);
17041713
break;
17051714
default:
1706-
break;
1715+
return;
1716+
}
1717+
1718+
for_each_vif_active_link(vif, link_conf, link_id) {
1719+
struct mt7996_vif_link *link;
1720+
1721+
link = mt7996_vif_link(dev, vif, link_id);
1722+
if (!link || link->phy != phy)
1723+
continue;
1724+
1725+
mt7996_mcu_add_beacon(dev->mt76.hw, vif, link_conf);
17071726
}
17081727
}
17091728

1729+
void mt7996_mac_update_beacons(struct mt7996_phy *phy)
1730+
{
1731+
ieee80211_iterate_active_interfaces(phy->mt76->hw,
1732+
IEEE80211_IFACE_ITER_RESUME_ALL,
1733+
mt7996_update_vif_beacon, phy);
1734+
}
1735+
17101736
static void
17111737
mt7996_update_beacons(struct mt7996_dev *dev)
17121738
{
17131739
struct mt76_phy *phy2, *phy3;
17141740

1715-
ieee80211_iterate_active_interfaces(dev->mt76.hw,
1716-
IEEE80211_IFACE_ITER_RESUME_ALL,
1717-
mt7996_update_vif_beacon, dev->mt76.hw);
1741+
mt7996_mac_update_beacons(&dev->phy);
17181742

17191743
phy2 = dev->mt76.phys[MT_BAND1];
1720-
if (!phy2)
1721-
return;
1722-
1723-
ieee80211_iterate_active_interfaces(phy2->hw,
1724-
IEEE80211_IFACE_ITER_RESUME_ALL,
1725-
mt7996_update_vif_beacon, phy2->hw);
1744+
if (phy2)
1745+
mt7996_mac_update_beacons(phy2->priv);
17261746

17271747
phy3 = dev->mt76.phys[MT_BAND2];
1728-
if (!phy3)
1729-
return;
1730-
1731-
ieee80211_iterate_active_interfaces(phy3->hw,
1732-
IEEE80211_IFACE_ITER_RESUME_ALL,
1733-
mt7996_update_vif_beacon, phy3->hw);
1748+
if (phy3)
1749+
mt7996_mac_update_beacons(phy3->priv);
17341750
}
17351751

17361752
void mt7996_tx_token_put(struct mt7996_dev *dev)

drivers/net/wireless/mediatek/mt76/mt7996/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@ int mt7996_set_channel(struct mt76_phy *mphy)
516516
struct mt7996_phy *phy = mphy->priv;
517517
int ret;
518518

519+
if (mphy->offchannel)
520+
mt7996_mac_update_beacons(phy);
521+
519522
ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
520523
if (ret)
521524
goto out;
@@ -533,6 +536,8 @@ int mt7996_set_channel(struct mt76_phy *mphy)
533536

534537
mt7996_mac_reset_counters(phy);
535538
phy->noise = 0;
539+
if (!mphy->offchannel)
540+
mt7996_mac_update_beacons(phy);
536541

537542
out:
538543
ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,

drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,8 +1879,8 @@ mt7996_mcu_get_mmps_mode(enum ieee80211_smps_mode smps)
18791879
int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
18801880
void *data, u16 version)
18811881
{
1882+
struct uni_header hdr = {};
18821883
struct ra_fixed_rate *req;
1883-
struct uni_header hdr;
18841884
struct sk_buff *skb;
18851885
struct tlv *tlv;
18861886
int len;
@@ -2755,27 +2755,32 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
27552755
struct ieee80211_bss_conf *link_conf)
27562756
{
27572757
struct mt7996_dev *dev = mt7996_hw_dev(hw);
2758-
struct mt76_vif_link *mlink = mt76_vif_conf_link(&dev->mt76, vif, link_conf);
2758+
struct mt7996_vif_link *link = mt7996_vif_conf_link(dev, vif, link_conf);
2759+
struct mt76_vif_link *mlink = link ? &link->mt76 : NULL;
27592760
struct ieee80211_mutable_offsets offs;
27602761
struct ieee80211_tx_info *info;
27612762
struct sk_buff *skb, *rskb;
27622763
struct tlv *tlv;
27632764
struct bss_bcn_content_tlv *bcn;
27642765
int len, extra_len = 0;
2766+
bool enabled = link_conf->enable_beacon;
27652767

27662768
if (link_conf->nontransmitted)
27672769
return 0;
27682770

27692771
if (!mlink)
27702772
return -EINVAL;
27712773

2774+
if (link->phy && link->phy->mt76->offchannel)
2775+
enabled = false;
2776+
27722777
rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, mlink,
27732778
MT7996_MAX_BSS_OFFLOAD_SIZE);
27742779
if (IS_ERR(rskb))
27752780
return PTR_ERR(rskb);
27762781

27772782
skb = ieee80211_beacon_get_template(hw, vif, &offs, link_conf->link_id);
2778-
if (link_conf->enable_beacon && !skb) {
2783+
if (enabled && !skb) {
27792784
dev_kfree_skb(rskb);
27802785
return -EINVAL;
27812786
}
@@ -2794,7 +2799,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
27942799
len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + extra_len, 4);
27952800
tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len);
27962801
bcn = (struct bss_bcn_content_tlv *)tlv;
2797-
bcn->enable = link_conf->enable_beacon;
2802+
bcn->enable = enabled;
27982803
if (!bcn->enable)
27992804
goto out;
28002805

@@ -3372,7 +3377,7 @@ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans)
33723377
{
33733378
struct {
33743379
u8 __rsv[4];
3375-
} __packed hdr;
3380+
} __packed hdr = {};
33763381
struct hdr_trans_blacklist *req_blacklist;
33773382
struct hdr_trans_en *req_en;
33783383
struct sk_buff *skb;

0 commit comments

Comments
 (0)