mt7996_mac_sta_add_links() removes all links that it was asked to add, with flush set, when one of them fails. A link that comes back after a removal kept its msta_link and may still have a firmware entry. The flush frees its msta_link and returns its WTBL index to wcid_mask, so a later station can be given an index whose entry still belongs to this station. Flush only the links that this call created, and remove a returning link again without flush. Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()") Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 8e70a4061ed6..58a487549ddf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -1355,6 +1355,7 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, unsigned long new_links) { struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + unsigned long created = 0, returned = 0; unsigned int link_id; int err = 0; @@ -1372,6 +1373,7 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif, mt7996_sta_deflink_set(sta, link_id, msta_link->wcid.idx); msta->seclink_id = mt7996_sta_seclink_get(dev, msta); + returned |= BIT(link_id); continue; } @@ -1405,12 +1407,14 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif, goto error_unlink; mphy->num_sta++; + created |= BIT(link_id); } return 0; error_unlink: - mt7996_mac_sta_remove_links(dev, vif, sta, new_links, true); + mt7996_mac_sta_remove_links(dev, vif, sta, created, true); + mt7996_mac_sta_remove_links(dev, vif, sta, returned, false); return err; } -- 2.47.3