Skip to content

Commit 61fe246

Browse files
LorenzoBianconinbd168
authored andcommitted
wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()
Similar to vif link management, postpone sta link destuction in mt7996_mac_sta_remove() introducing mt7996_mac_sta_remove_link utility routine and just disable sta link running mt7996_mac_sta_remove_links routine. This is a preliminary patch in order to support MLO link reconfiguration in MT7996 driver. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20260315-mt7996-mlo-link-reconf-v1-6-a8a634fbc927@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent 757a951 commit 61fe246

3 files changed

Lines changed: 45 additions & 49 deletions

File tree

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

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,26 +2372,8 @@ mt7996_mac_reset_sta_iter(void *data, struct ieee80211_sta *sta)
23722372
struct mt7996_dev *dev = data;
23732373
int i;
23742374

2375-
for (i = 0; i < ARRAY_SIZE(msta->link); i++) {
2376-
struct mt7996_sta_link *msta_link = NULL;
2377-
struct mt7996_phy *phy;
2378-
2379-
msta_link = rcu_replace_pointer(msta->link[i], msta_link,
2380-
lockdep_is_held(&dev->mt76.mutex));
2381-
if (!msta_link)
2382-
continue;
2383-
2384-
mt7996_mac_sta_deinit_link(dev, msta_link);
2385-
phy = __mt7996_phy(dev, msta_link->wcid.phy_idx);
2386-
if (phy)
2387-
phy->mt76->num_sta--;
2388-
2389-
if (msta_link != &msta->deflink)
2390-
kfree_rcu(msta_link, rcu_head);
2391-
}
2392-
2393-
msta->deflink_id = IEEE80211_LINK_UNSPECIFIED;
2394-
msta->seclink_id = msta->deflink_id;
2375+
for (i = 0; i < ARRAY_SIZE(msta->link); i++)
2376+
mt7996_mac_sta_remove_link(dev, sta, i, true);
23952377
}
23962378

23972379
static void

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

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,41 +1179,31 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev,
11791179
return 0;
11801180
}
11811181

1182-
void mt7996_mac_sta_deinit_link(struct mt7996_dev *dev,
1183-
struct mt7996_sta_link *msta_link)
1182+
void mt7996_mac_sta_remove_link(struct mt7996_dev *dev,
1183+
struct ieee80211_sta *sta,
1184+
unsigned int link_id, bool flush)
11841185
{
1186+
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
1187+
struct mt7996_sta_link *msta_link;
1188+
1189+
msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
1190+
if (!msta_link)
1191+
return;
1192+
11851193
spin_lock_bh(&dev->mt76.sta_poll_lock);
11861194
if (!list_empty(&msta_link->wcid.poll_list))
11871195
list_del_init(&msta_link->wcid.poll_list);
11881196
if (!list_empty(&msta_link->rc_list))
11891197
list_del_init(&msta_link->rc_list);
11901198
spin_unlock_bh(&dev->mt76.sta_poll_lock);
11911199

1192-
rcu_assign_pointer(dev->mt76.wcid[msta_link->wcid.idx], NULL);
11931200
mt76_wcid_cleanup(&dev->mt76, &msta_link->wcid);
1194-
mt76_wcid_mask_clear(dev->mt76.wcid_mask, msta_link->wcid.idx);
1195-
}
1196-
1197-
static void
1198-
mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
1199-
struct ieee80211_sta *sta, unsigned long links)
1200-
{
1201-
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
1202-
struct mt76_dev *mdev = &dev->mt76;
1203-
unsigned int link_id;
12041201

1205-
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) {
1206-
struct mt7996_sta_link *msta_link = NULL;
1202+
if (msta_link->wcid.link_valid) {
12071203
struct mt7996_phy *phy;
12081204

1209-
msta_link = rcu_replace_pointer(msta->link[link_id], msta_link,
1210-
lockdep_is_held(&mdev->mutex));
1211-
if (!msta_link)
1212-
continue;
1213-
12141205
mt7996_mac_wtbl_update(dev, msta_link->wcid.idx,
12151206
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
1216-
mt7996_mac_sta_deinit_link(dev, msta_link);
12171207

12181208
phy = __mt7996_phy(dev, msta_link->wcid.phy_idx);
12191209
if (phy)
@@ -1230,7 +1220,7 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
12301220
/* switch to the secondary link */
12311221
msta_seclink = mt76_dereference(
12321222
msta->link[msta->seclink_id],
1233-
mdev);
1223+
&dev->mt76);
12341224
if (msta_seclink) {
12351225
msta->deflink_id = msta->seclink_id;
12361226
mt7996_sta_init_txq_wcid(sta,
@@ -1240,12 +1230,29 @@ mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
12401230
} else if (msta->seclink_id == link_id) {
12411231
msta->seclink_id = msta->deflink_id;
12421232
}
1233+
msta_link->wcid.link_valid = false;
1234+
}
12431235

1236+
if (flush) {
1237+
rcu_assign_pointer(msta->link[link_id], NULL);
1238+
rcu_assign_pointer(dev->mt76.wcid[msta_link->wcid.idx], NULL);
1239+
mt76_wcid_mask_clear(dev->mt76.wcid_mask, msta_link->wcid.idx);
12441240
if (msta_link != &msta->deflink)
12451241
kfree_rcu(msta_link, rcu_head);
12461242
}
12471243
}
12481244

1245+
static void
1246+
mt7996_mac_sta_remove_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
1247+
struct ieee80211_sta *sta, unsigned long links,
1248+
bool flush)
1249+
{
1250+
unsigned int link_id;
1251+
1252+
for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS)
1253+
mt7996_mac_sta_remove_link(dev, sta, link_id, flush);
1254+
}
1255+
12491256
static int
12501257
mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
12511258
struct ieee80211_sta *sta, unsigned long new_links)
@@ -1257,11 +1264,15 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
12571264
for_each_set_bit(link_id, &new_links, IEEE80211_MLD_MAX_NUM_LINKS) {
12581265
struct ieee80211_bss_conf *link_conf;
12591266
struct ieee80211_link_sta *link_sta;
1267+
struct mt7996_sta_link *msta_link;
12601268
struct mt7996_vif_link *link;
12611269
struct mt76_phy *mphy;
12621270

1263-
if (rcu_access_pointer(msta->link[link_id]))
1271+
msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
1272+
if (msta_link) {
1273+
msta_link->wcid.link_valid = true;
12641274
continue;
1275+
}
12651276

12661277
link_conf = link_conf_dereference_protected(vif, link_id);
12671278
if (!link_conf) {
@@ -1298,7 +1309,7 @@ mt7996_mac_sta_add_links(struct mt7996_dev *dev, struct ieee80211_vif *vif,
12981309
return 0;
12991310

13001311
error_unlink:
1301-
mt7996_mac_sta_remove_links(dev, vif, sta, new_links);
1312+
mt7996_mac_sta_remove_links(dev, vif, sta, new_links, true);
13021313

13031314
return err;
13041315
}
@@ -1315,7 +1326,7 @@ mt7996_mac_sta_change_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
13151326

13161327
mutex_lock(&dev->mt76.mutex);
13171328

1318-
mt7996_mac_sta_remove_links(dev, vif, sta, rem);
1329+
mt7996_mac_sta_remove_links(dev, vif, sta, rem, false);
13191330
ret = mt7996_mac_sta_add_links(dev, vif, sta, add);
13201331

13211332
mutex_unlock(&dev->mt76.mutex);
@@ -1424,10 +1435,12 @@ static void
14241435
mt7996_mac_sta_remove(struct mt7996_dev *dev, struct ieee80211_vif *vif,
14251436
struct ieee80211_sta *sta)
14261437
{
1427-
unsigned long links = sta->valid_links ? sta->valid_links : BIT(0);
1438+
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
1439+
int i;
14281440

14291441
mutex_lock(&dev->mt76.mutex);
1430-
mt7996_mac_sta_remove_links(dev, vif, sta, links);
1442+
for (i = 0; i < ARRAY_SIZE(msta->link); i++)
1443+
mt7996_mac_sta_remove_link(dev, sta, i, true);
14311444
mutex_unlock(&dev->mt76.mutex);
14321445
}
14331446

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,8 +867,9 @@ void mt7996_mac_twt_teardown_flow(struct mt7996_dev *dev,
867867
struct mt7996_vif_link *link,
868868
struct mt7996_sta_link *msta_link,
869869
u8 flowid);
870-
void mt7996_mac_sta_deinit_link(struct mt7996_dev *dev,
871-
struct mt7996_sta_link *msta_link);
870+
void mt7996_mac_sta_remove_link(struct mt7996_dev *dev,
871+
struct ieee80211_sta *sta,
872+
unsigned int link_id, bool flush);
872873
void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw,
873874
struct ieee80211_sta *sta,
874875
struct ieee80211_twt_setup *twt);

0 commit comments

Comments
 (0)