Skip to content

Commit 72b6945

Browse files
moore-brosnbd168
authored andcommitted
wifi: mt76: mt7925: host-only unwind published links on add failure
Release host link resources when mt7925_mac_sta_add_links() fails after partial success. msta->link[] and dev->mt76.wcid[] may already be published, so unwind the host state to avoid leaving stale links behind. Signed-off-by: Sean Wang <sean.wang@mediatek.com> Link: https://patch.msgid.link/20260306232238.2039675-20-sean.wang@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent 462fe33 commit 72b6945

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

  • drivers/net/wireless/mediatek/mt76/mt7925

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,11 +989,51 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev,
989989
return ret;
990990
}
991991

992+
/*
993+
* Host-only unwind for sta_add_links() failures.
994+
*
995+
* If add_links fail due to MCU/firmware timeouts; calling the full remove
996+
* path would send more firmware commands and may hang again. So only rollback
997+
* host-published state here (msta->link/valid_links, dev->mt76.wcid[idx]) and
998+
* free mlink objects (RCU-safe). Firmware state is left for reset/recovery.
999+
*/
1000+
static void
1001+
mt7925_mac_sta_unwind_links_host(struct mt792x_dev *dev,
1002+
struct ieee80211_sta *sta,
1003+
unsigned long links)
1004+
{
1005+
struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
1006+
unsigned int link_id;
1007+
1008+
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
1009+
struct mt792x_link_sta *mlink;
1010+
u16 idx;
1011+
1012+
mlink = rcu_replace_pointer(msta->link[link_id], NULL,
1013+
lockdep_is_held(&dev->mt76.mutex));
1014+
if (!mlink)
1015+
continue;
1016+
1017+
msta->valid_links &= ~BIT(link_id);
1018+
if (msta->deflink_id == link_id)
1019+
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
1020+
1021+
idx = mlink->wcid.idx;
1022+
rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
1023+
mt76_wcid_cleanup(&dev->mt76, &mlink->wcid);
1024+
mt76_wcid_mask_clear(dev->mt76.wcid_mask, idx);
1025+
1026+
if (mlink != &msta->deflink)
1027+
kfree_rcu(mlink, rcu_head);
1028+
}
1029+
}
1030+
9921031
static int
9931032
mt7925_mac_sta_add_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,
9941033
struct ieee80211_sta *sta, unsigned long new_links)
9951034
{
9961035
struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
1036+
unsigned long added_links = 0;
9971037
unsigned int link_id;
9981038
int err = 0;
9991039

@@ -1030,8 +1070,13 @@ mt7925_mac_sta_add_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,
10301070

10311071
rcu_assign_pointer(msta->link[link_id], mlink);
10321072
msta->valid_links |= BIT(link_id);
1073+
1074+
added_links |= BIT(link_id);
10331075
}
10341076

1077+
if (err && added_links)
1078+
mt7925_mac_sta_unwind_links_host(dev, sta, added_links);
1079+
10351080
return err;
10361081
}
10371082

0 commit comments

Comments
 (0)