@@ -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+
12491256static int
12501257mt7996_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
13001311error_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
14241435mt7996_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
0 commit comments