Skip to content

Commit e54c644

Browse files
LorenzoBianconigregkh
authored andcommitted
wifi: mt76: mt7996: Switch to the secondary link if the default one is removed
[ Upstream commit 5ef44c2 ] Switch to the secondary link if available in mt7996_mac_sta_remove_links routine if the primary one is removed. Moreover reset secondary link index for single link scenario. Fixes: 85cd553 ("wifi: mt76: mt7996: use correct link_id when filling TXD and TXP") Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20251205-mt76-txq-wicd-fix-v2-3-f19ba48af7c1@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name> Stable-dep-of: e648051 ("wifi: mt76: mt7996: Decrement sta counter removing the link in mt7996_mac_reset_sta_iter()") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d6f6b3a commit e54c644

2 files changed

Lines changed: 41 additions & 22 deletions

File tree

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,14 +2406,12 @@ mt7996_mac_reset_sta_iter(void *data, struct ieee80211_sta *sta)
24062406
continue;
24072407

24082408
mt7996_mac_sta_deinit_link(dev, msta_link);
2409-
2410-
if (msta->deflink_id == i) {
2411-
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
2412-
continue;
2413-
}
2414-
2415-
kfree_rcu(msta_link, rcu_head);
2409+
if (msta_link != &msta->deflink)
2410+
kfree_rcu(msta_link, rcu_head);
24162411
}
2412+
2413+
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
2414+
msta->seclink_id = msta->deflink_id;
24172415
}
24182416

24192417
static void

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

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,22 @@ mt7996_post_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
961961
return ret;
962962
}
963963

964+
static void
965+
mt7996_sta_init_txq_wcid(struct ieee80211_sta *sta, int idx)
966+
{
967+
int i;
968+
969+
for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
970+
struct mt76_txq *mtxq;
971+
972+
if (!sta->txq[i])
973+
continue;
974+
975+
mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
976+
mtxq->wcid = idx;
977+
}
978+
}
979+
964980
static int
965981
mt7996_mac_sta_init_link(struct mt7996_dev *dev,
966982
struct ieee80211_bss_conf *link_conf,
@@ -978,21 +994,10 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev,
978994
return -ENOSPC;
979995

980996
if (msta->deflink_id == IEEE80211_LINK_UNSPECIFIED) {
981-
int i;
982-
983997
msta_link = &msta->deflink;
984998
msta->deflink_id = link_id;
985999
msta->seclink_id = msta->deflink_id;
986-
987-
for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
988-
struct mt76_txq *mtxq;
989-
990-
if (!sta->txq[i])
991-
continue;
992-
993-
mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv;
994-
mtxq->wcid = idx;
995-
}
1000+
mt7996_sta_init_txq_wcid(sta, idx);
9961001
} else {
9971002
msta_link = kzalloc(sizeof(*msta_link), GFP_KERNEL);
9981003
if (!msta_link)
@@ -1070,12 +1075,28 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
10701075

10711076
if (msta->deflink_id == link_id) {
10721077
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
1073-
continue;
1078+
if (msta->seclink_id == link_id) {
1079+
/* no secondary link available */
1080+
msta->seclink_id = msta->deflink_id;
1081+
} else {
1082+
struct mt7996_sta_link *msta_seclink;
1083+
1084+
/* switch to the secondary link */
1085+
msta_seclink = mt76_dereference(
1086+
msta->link[msta->seclink_id],
1087+
mdev);
1088+
if (msta_seclink) {
1089+
msta->deflink_id = msta->seclink_id;
1090+
mt7996_sta_init_txq_wcid(sta,
1091+
msta_seclink->wcid.idx);
1092+
}
1093+
}
10741094
} else if (msta->seclink_id == link_id) {
1075-
msta->seclink_id = IEEE80211_LINK_UNSPECIFIED;
1095+
msta->seclink_id = msta->deflink_id;
10761096
}
10771097

1078-
kfree_rcu(msta_link, rcu_head);
1098+
if (msta_link != &msta->deflink)
1099+
kfree_rcu(msta_link, rcu_head);
10791100
}
10801101
}
10811102

0 commit comments

Comments
 (0)