From: Shayne Chen Date: Sun, 15 Mar 2026 10:26:26 +0000 (+0100) Subject: wifi: mt76: mt7996: Move mlink deallocation in mt7996_vif_link_remove() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c8d22f28ea583bda31b7db8243e4e1eb042ac38a;p=thirdparty%2Fkernel%2Flinux.git wifi: mt76: mt7996: Move mlink deallocation in mt7996_vif_link_remove() Destroy mt76_vif_link struct in mt7996_vif_link_remove routine and not in mt76_unassign_vif_chanctx(). This is necessary since, in order to properly support MLO link reconfiguration, we will destroy mt76_vif_link struct during AP tear-down process and not running unassign_vif_chanctx mac80211 callback. This patch does not introduce any regression since mt76_assign_vif_chanctx/mt76_unassign_vif_chanctx APIs are currently used just by MT7996 driver. Signed-off-by: Shayne Chen Co-developed-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi Link: https://patch.msgid.link/20260315-mt7996-mlo-link-reconf-v1-3-a8a634fbc927@kernel.org Signed-off-by: Felix Fietkau --- diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c index cf3fc09e5d5a8..05eee64706ea8 100644 --- a/drivers/net/wireless/mediatek/mt76/channel.c +++ b/drivers/net/wireless/mediatek/mt76/channel.c @@ -158,8 +158,6 @@ void mt76_unassign_vif_chanctx(struct ieee80211_hw *hw, { struct mt76_chanctx *ctx = (struct mt76_chanctx *)conf->drv_priv; struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; - struct mt76_vif_data *mvif = mlink->mvif; - int link_id = link_conf->link_id; struct mt76_phy *phy = ctx->phy; struct mt76_dev *dev = phy->dev; @@ -176,15 +174,8 @@ void mt76_unassign_vif_chanctx(struct ieee80211_hw *hw, if (!mlink) goto out; - 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 (mlink != (struct mt76_vif_link *)vif->drv_priv) - kfree_rcu(mlink, rcu_head); - out: mutex_unlock(&dev->mutex); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 07a266f7670c1..feee93340a6c6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -459,6 +459,12 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, spin_unlock_bh(&dev->mt76.sta_poll_lock); mt76_wcid_cleanup(&dev->mt76, &msta_link->wcid); + + if (mlink != (struct mt76_vif_link *)vif->drv_priv && + !mlink->wcid->offchannel) { + rcu_assign_pointer(mlink->mvif->link[link_id], NULL); + kfree_rcu(mlink, rcu_head); + } } static void mt7996_phy_set_rxfilter(struct mt7996_phy *phy)