@@ -816,59 +816,164 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw,
816816}
817817
818818static int
819- mt7996_mac_sta_add (struct mt76_phy * mphy , struct ieee80211_vif * vif ,
820- struct ieee80211_sta * sta )
819+ mt7996_mac_sta_init_link (struct mt7996_dev * dev , struct ieee80211_vif * vif ,
820+ struct mt7996_vif_link * link ,
821+ struct ieee80211_sta * sta , unsigned int link_id )
821822{
822- struct mt76_dev * mdev = mphy -> dev ;
823- struct mt7996_dev * dev = container_of (mdev , struct mt7996_dev , mt76 );
824823 struct mt7996_sta * msta = (struct mt7996_sta * )sta -> drv_priv ;
825- struct mt7996_vif * mvif = (struct mt7996_vif * )vif -> drv_priv ;
826- struct mt7996_sta_link * msta_link = & msta -> deflink ;
827- struct mt7996_vif_link * link = & mvif -> deflink ;
828- u8 band_idx = mphy -> band_idx ;
829- int i , idx , ret = 0 ;
824+ struct mt7996_phy * phy = link -> phy ;
825+ struct mt7996_sta_link * msta_link ;
826+ int idx ;
830827
831- mutex_lock (& mdev -> mutex );
828+ idx = mt76_wcid_alloc (dev -> mt76 .wcid_mask , MT7996_WTBL_STA );
829+ if (idx < 0 )
830+ return - ENOSPC ;
831+
832+ if (msta -> deflink_id == IEEE80211_LINK_UNSPECIFIED ) {
833+ int i ;
834+
835+ msta_link = & msta -> deflink ;
836+ msta -> deflink_id = link_id ;
837+
838+ for (i = 0 ; i < ARRAY_SIZE (sta -> txq ); i ++ ) {
839+ struct mt76_txq * mtxq ;
840+
841+ if (!sta -> txq [i ])
842+ continue ;
832843
833- idx = mt76_wcid_alloc (mdev -> wcid_mask , MT7996_WTBL_STA );
834- if (idx < 0 ) {
835- ret = - ENOSPC ;
836- goto unlock ;
844+ mtxq = (struct mt76_txq * )sta -> txq [i ]-> drv_priv ;
845+ mtxq -> wcid = idx ;
846+ }
847+ } else {
848+ msta_link = kzalloc (sizeof (* msta_link ), GFP_KERNEL );
849+ if (!msta_link )
850+ return - ENOMEM ;
837851 }
838852
839- msta -> vif = mvif ;
840853 INIT_LIST_HEAD (& msta_link -> rc_list );
841854 INIT_LIST_HEAD (& msta_link -> wcid .poll_list );
842855 msta_link -> sta = msta ;
843856 msta_link -> wcid .sta = 1 ;
844857 msta_link -> wcid .idx = idx ;
845- msta_link -> wcid .phy_idx = band_idx ;
858+ msta_link -> wcid .link_id = link_id ;
859+
860+ ewma_avg_signal_init (& msta_link -> avg_ack_signal );
861+ ewma_signal_init (& msta_link -> wcid .rssi );
846862
847- for (i = 0 ; i < ARRAY_SIZE (sta -> txq ); i ++ ) {
848- struct mt76_txq * mtxq ;
863+ rcu_assign_pointer (msta -> link [link_id ], msta_link );
849864
850- if (!sta -> txq [i ])
865+ mt7996_mac_wtbl_update (dev , idx , MT_WTBL_UPDATE_ADM_COUNT_CLEAR );
866+ mt7996_mcu_add_sta (dev , vif , & link -> mt76 , sta , CONN_STATE_DISCONNECT ,
867+ true);
868+
869+ rcu_assign_pointer (dev -> mt76 .wcid [idx ], & msta_link -> wcid );
870+ mt76_wcid_init (& msta_link -> wcid , phy -> mt76 -> band_idx );
871+
872+ return 0 ;
873+ }
874+
875+ static void
876+ mt7996_mac_sta_deinit_link (struct mt7996_dev * dev ,
877+ struct mt7996_sta_link * msta_link )
878+ {
879+ int i ;
880+
881+ for (i = 0 ; i < ARRAY_SIZE (msta_link -> wcid .aggr ); i ++ )
882+ mt76_rx_aggr_stop (& dev -> mt76 , & msta_link -> wcid , i );
883+
884+ mt7996_mac_wtbl_update (dev , msta_link -> wcid .idx ,
885+ MT_WTBL_UPDATE_ADM_COUNT_CLEAR );
886+
887+ spin_lock_bh (& dev -> mt76 .sta_poll_lock );
888+ if (!list_empty (& msta_link -> wcid .poll_list ))
889+ list_del_init (& msta_link -> wcid .poll_list );
890+ if (!list_empty (& msta_link -> rc_list ))
891+ list_del_init (& msta_link -> rc_list );
892+ spin_unlock_bh (& dev -> mt76 .sta_poll_lock );
893+
894+ mt76_wcid_cleanup (& dev -> mt76 , & msta_link -> wcid );
895+ mt76_wcid_mask_clear (dev -> mt76 .wcid_mask , msta_link -> wcid .idx );
896+ }
897+
898+ static void
899+ mt7996_mac_sta_remove_links (struct mt7996_dev * dev , struct ieee80211_sta * sta ,
900+ unsigned long links )
901+ {
902+ struct mt7996_sta * msta = (struct mt7996_sta * )sta -> drv_priv ;
903+ struct mt76_dev * mdev = & dev -> mt76 ;
904+ unsigned int link_id ;
905+
906+ for_each_set_bit (link_id , & links , IEEE80211_MLD_MAX_NUM_LINKS ) {
907+ struct mt7996_sta_link * msta_link = NULL ;
908+
909+ msta_link = rcu_replace_pointer (msta -> link [link_id ], msta_link ,
910+ lockdep_is_held (& mdev -> mutex ));
911+ if (!msta_link )
851912 continue ;
852913
853- mtxq = (struct mt76_txq * )sta -> txq [i ]-> drv_priv ;
854- mtxq -> wcid = idx ;
914+ mt7996_mac_sta_deinit_link (dev , msta_link );
915+ if (msta -> deflink_id == link_id ) {
916+ msta -> deflink_id = IEEE80211_LINK_UNSPECIFIED ;
917+ continue ;
918+ }
919+
920+ kfree_rcu (msta_link , rcu_head );
855921 }
922+ }
856923
857- ewma_avg_signal_init (& msta_link -> avg_ack_signal );
858- ewma_signal_init (& msta_link -> wcid .rssi );
924+ static int
925+ mt7996_mac_sta_add_links (struct mt7996_dev * dev , struct ieee80211_vif * vif ,
926+ struct ieee80211_sta * sta , unsigned long new_links )
927+ {
928+ struct mt7996_sta * msta = (struct mt7996_sta * )sta -> drv_priv ;
929+ unsigned int link_id ;
930+ int err ;
859931
860- mt7996_mac_wtbl_update (dev , idx ,
861- MT_WTBL_UPDATE_ADM_COUNT_CLEAR );
862- mt7996_mcu_add_sta (dev , vif , & link -> mt76 , sta , CONN_STATE_DISCONNECT ,
863- true);
932+ for_each_set_bit (link_id , & new_links , IEEE80211_MLD_MAX_NUM_LINKS ) {
933+ struct mt7996_vif_link * link ;
934+
935+ if (rcu_access_pointer (msta -> link [link_id ]))
936+ continue ;
937+
938+ link = mt7996_vif_link (dev , vif , link_id );
939+ if (!link )
940+ goto error_unlink ;
941+
942+ err = mt7996_mac_sta_init_link (dev , vif , link , sta , link_id );
943+ if (err )
944+ goto error_unlink ;
945+ }
946+
947+ return 0 ;
948+
949+ error_unlink :
950+ mt7996_mac_sta_remove_links (dev , sta , new_links );
951+
952+ return err ;
953+ }
954+
955+ static int
956+ mt7996_mac_sta_add (struct mt76_phy * mphy , struct ieee80211_vif * vif ,
957+ struct ieee80211_sta * sta )
958+ {
959+ struct mt76_dev * mdev = mphy -> dev ;
960+ struct mt7996_dev * dev = container_of (mdev , struct mt7996_dev , mt76 );
961+ struct mt7996_sta * msta = (struct mt7996_sta * )sta -> drv_priv ;
962+ struct mt7996_vif * mvif = (struct mt7996_vif * )vif -> drv_priv ;
963+ unsigned long links = sta -> mlo ? sta -> valid_links : BIT (0 );
964+ int err ;
965+
966+ mutex_lock (& mdev -> mutex );
967+
968+ msta -> deflink_id = IEEE80211_LINK_UNSPECIFIED ;
969+ msta -> vif = mvif ;
970+ err = mt7996_mac_sta_add_links (dev , vif , sta , links );
971+ if (!err )
972+ mphy -> num_sta ++ ;
864973
865- rcu_assign_pointer (mdev -> wcid [idx ], & msta_link -> wcid );
866- mt76_wcid_init (& msta_link -> wcid , band_idx );
867- mphy -> num_sta ++ ;
868- unlock :
869974 mutex_unlock (& mdev -> mutex );
870975
871- return ret ;
976+ return err ;
872977}
873978
874979static int
@@ -922,27 +1027,11 @@ mt7996_mac_sta_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif,
9221027{
9231028 struct mt76_dev * mdev = mphy -> dev ;
9241029 struct mt7996_dev * dev = container_of (mdev , struct mt7996_dev , mt76 );
925- struct mt7996_sta * msta = (struct mt7996_sta * )sta -> drv_priv ;
926- struct mt7996_sta_link * msta_link = & msta -> deflink ;
927- int i , idx = msta_link -> wcid .idx ;
1030+ unsigned long links = sta -> mlo ? sta -> valid_links : BIT (0 );
9281031
9291032 mutex_lock (& mdev -> mutex );
9301033
931- for (i = 0 ; i < ARRAY_SIZE (msta_link -> wcid .aggr ); i ++ )
932- mt76_rx_aggr_stop (mdev , & msta_link -> wcid , i );
933-
934- mt7996_mac_wtbl_update (dev , msta_link -> wcid .idx ,
935- MT_WTBL_UPDATE_ADM_COUNT_CLEAR );
936-
937- spin_lock_bh (& mdev -> sta_poll_lock );
938- if (!list_empty (& msta_link -> wcid .poll_list ))
939- list_del_init (& msta_link -> wcid .poll_list );
940- if (!list_empty (& msta_link -> rc_list ))
941- list_del_init (& msta_link -> rc_list );
942- spin_unlock_bh (& mdev -> sta_poll_lock );
943-
944- mt76_wcid_cleanup (mdev , & msta_link -> wcid );
945- mt76_wcid_mask_clear (mdev -> wcid_mask , idx );
1034+ mt7996_mac_sta_remove_links (dev , sta , links );
9461035 mphy -> num_sta -- ;
9471036
9481037 mutex_unlock (& mdev -> mutex );
0 commit comments