@@ -4049,6 +4049,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
40494049#undef CALL_RXH
40504050}
40514051
4052+ static bool
4053+ ieee80211_rx_is_valid_sta_link_id (struct ieee80211_sta * sta , u8 link_id )
4054+ {
4055+ if (!sta -> mlo )
4056+ return false;
4057+
4058+ return !!(sta -> valid_links & BIT (link_id ));
4059+ }
4060+
4061+ static bool ieee80211_rx_data_set_link (struct ieee80211_rx_data * rx ,
4062+ u8 link_id )
4063+ {
4064+ rx -> link_id = link_id ;
4065+ rx -> link = rcu_dereference (rx -> sdata -> link [link_id ]);
4066+
4067+ if (!rx -> sta )
4068+ return rx -> link ;
4069+
4070+ if (!ieee80211_rx_is_valid_sta_link_id (& rx -> sta -> sta , link_id ))
4071+ return false;
4072+
4073+ rx -> link_sta = rcu_dereference (rx -> sta -> link [link_id ]);
4074+
4075+ return rx -> link && rx -> link_sta ;
4076+ }
4077+
4078+ static bool ieee80211_rx_data_set_sta (struct ieee80211_rx_data * rx ,
4079+ struct ieee80211_sta * pubsta ,
4080+ int link_id )
4081+ {
4082+ struct sta_info * sta ;
4083+
4084+ sta = container_of (pubsta , struct sta_info , sta );
4085+
4086+ rx -> link_id = link_id ;
4087+ rx -> sta = sta ;
4088+
4089+ if (sta ) {
4090+ rx -> local = sta -> sdata -> local ;
4091+ if (!rx -> sdata )
4092+ rx -> sdata = sta -> sdata ;
4093+ rx -> link_sta = & sta -> deflink ;
4094+ }
4095+
4096+ if (link_id < 0 )
4097+ rx -> link = & rx -> sdata -> deflink ;
4098+ else if (!ieee80211_rx_data_set_link (rx , link_id ))
4099+ return false;
4100+
4101+ return true;
4102+ }
4103+
40524104/*
40534105 * This function makes calls into the RX path, therefore
40544106 * it has to be invoked under RCU read lock.
@@ -4057,16 +4109,19 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
40574109{
40584110 struct sk_buff_head frames ;
40594111 struct ieee80211_rx_data rx = {
4060- .sta = sta ,
4061- .sdata = sta -> sdata ,
4062- .local = sta -> local ,
40634112 /* This is OK -- must be QoS data frame */
40644113 .security_idx = tid ,
40654114 .seqno_idx = tid ,
4066- .link_id = -1 ,
40674115 };
40684116 struct tid_ampdu_rx * tid_agg_rx ;
4069- u8 link_id ;
4117+ int link_id = -1 ;
4118+
4119+ /* FIXME: statistics won't be right with this */
4120+ if (sta -> sta .valid_links )
4121+ link_id = ffs (sta -> sta .valid_links ) - 1 ;
4122+
4123+ if (!ieee80211_rx_data_set_sta (& rx , & sta -> sta , link_id ))
4124+ return ;
40704125
40714126 tid_agg_rx = rcu_dereference (sta -> ampdu_mlme .tid_rx [tid ]);
40724127 if (!tid_agg_rx )
@@ -4086,10 +4141,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
40864141 };
40874142 drv_event_callback (rx .local , rx .sdata , & event );
40884143 }
4089- /* FIXME: statistics won't be right with this */
4090- link_id = sta -> sta .valid_links ? ffs (sta -> sta .valid_links ) - 1 : 0 ;
4091- rx .link = rcu_dereference (sta -> sdata -> link [link_id ]);
4092- rx .link_sta = rcu_dereference (sta -> link [link_id ]);
40934144
40944145 ieee80211_rx_handlers (& rx , & frames );
40954146}
@@ -4105,7 +4156,6 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
41054156 /* This is OK -- must be QoS data frame */
41064157 .security_idx = tid ,
41074158 .seqno_idx = tid ,
4108- .link_id = -1 ,
41094159 };
41104160 int i , diff ;
41114161
@@ -4116,10 +4166,8 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
41164166
41174167 sta = container_of (pubsta , struct sta_info , sta );
41184168
4119- rx .sta = sta ;
4120- rx .sdata = sta -> sdata ;
4121- rx .link = & rx .sdata -> deflink ;
4122- rx .local = sta -> local ;
4169+ if (!ieee80211_rx_data_set_sta (& rx , pubsta , -1 ))
4170+ return ;
41234171
41244172 rcu_read_lock ();
41254173 tid_agg_rx = rcu_dereference (sta -> ampdu_mlme .tid_rx [tid ]);
@@ -4506,15 +4554,6 @@ void ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata)
45064554 mutex_unlock (& local -> sta_mtx );
45074555}
45084556
4509- static bool
4510- ieee80211_rx_is_valid_sta_link_id (struct ieee80211_sta * sta , u8 link_id )
4511- {
4512- if (!sta -> mlo )
4513- return false;
4514-
4515- return !!(sta -> valid_links & BIT (link_id ));
4516- }
4517-
45184557static void ieee80211_rx_8023 (struct ieee80211_rx_data * rx ,
45194558 struct ieee80211_fast_rx * fast_rx ,
45204559 int orig_len )
@@ -4625,7 +4664,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
46254664 struct sk_buff * skb = rx -> skb ;
46264665 struct ieee80211_hdr * hdr = (void * )skb -> data ;
46274666 struct ieee80211_rx_status * status = IEEE80211_SKB_RXCB (skb );
4628- struct sta_info * sta = rx -> sta ;
46294667 int orig_len = skb -> len ;
46304668 int hdrlen = ieee80211_hdrlen (hdr -> frame_control );
46314669 int snap_offs = hdrlen ;
@@ -4637,7 +4675,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
46374675 u8 da [ETH_ALEN ];
46384676 u8 sa [ETH_ALEN ];
46394677 } addrs __aligned (2 );
4640- struct link_sta_info * link_sta ;
46414678 struct ieee80211_sta_rx_stats * stats ;
46424679
46434680 /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
@@ -4740,18 +4777,10 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
47404777 drop :
47414778 dev_kfree_skb (skb );
47424779
4743- if (rx -> link_id >= 0 ) {
4744- link_sta = rcu_dereference (sta -> link [rx -> link_id ]);
4745- if (!link_sta )
4746- return true;
4747- } else {
4748- link_sta = & sta -> deflink ;
4749- }
4750-
47514780 if (fast_rx -> uses_rss )
4752- stats = this_cpu_ptr (link_sta -> pcpu_rx_stats );
4781+ stats = this_cpu_ptr (rx -> link_sta -> pcpu_rx_stats );
47534782 else
4754- stats = & link_sta -> rx_stats ;
4783+ stats = & rx -> link_sta -> rx_stats ;
47554784
47564785 stats -> dropped ++ ;
47574786 return true;
@@ -4769,8 +4798,8 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
47694798 struct ieee80211_local * local = rx -> local ;
47704799 struct ieee80211_sub_if_data * sdata = rx -> sdata ;
47714800 struct ieee80211_hdr * hdr = (void * )skb -> data ;
4772- struct link_sta_info * link_sta = NULL ;
4773- struct ieee80211_link_data * link ;
4801+ struct link_sta_info * link_sta = rx -> link_sta ;
4802+ struct ieee80211_link_data * link = rx -> link ;
47744803
47754804 rx -> skb = skb ;
47764805
@@ -4792,35 +4821,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
47924821 if (!ieee80211_accept_frame (rx ))
47934822 return false;
47944823
4795- if (rx -> link_id >= 0 ) {
4796- link = rcu_dereference (rx -> sdata -> link [rx -> link_id ]);
4797-
4798- /* we might race link removal */
4799- if (!link )
4800- return true;
4801- rx -> link = link ;
4802-
4803- if (rx -> sta ) {
4804- rx -> link_sta =
4805- rcu_dereference (rx -> sta -> link [rx -> link_id ]);
4806- if (!rx -> link_sta )
4807- return true;
4808- }
4809- } else {
4810- if (rx -> sta )
4811- rx -> link_sta = & rx -> sta -> deflink ;
4812-
4813- rx -> link = & sdata -> deflink ;
4814- }
4815-
4816- if (unlikely (!is_multicast_ether_addr (hdr -> addr1 ) &&
4817- rx -> link_id >= 0 && rx -> sta && rx -> sta -> sta .mlo )) {
4818- link_sta = rcu_dereference (rx -> sta -> link [rx -> link_id ]);
4819-
4820- if (WARN_ON_ONCE (!link_sta ))
4821- return true;
4822- }
4823-
48244824 if (!consume ) {
48254825 struct skb_shared_hwtstamps * shwt ;
48264826
@@ -4840,7 +4840,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
48404840 shwt -> hwtstamp = skb_hwtstamps (skb )-> hwtstamp ;
48414841 }
48424842
4843- if (unlikely (link_sta )) {
4843+ if (unlikely (rx -> sta && rx -> sta -> sta . mlo )) {
48444844 /* translate to MLD addresses */
48454845 if (ether_addr_equal (link -> conf -> addr , hdr -> addr1 ))
48464846 ether_addr_copy (hdr -> addr1 , rx -> sdata -> vif .addr );
@@ -4870,6 +4870,7 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
48704870 struct ieee80211_rx_status * status = IEEE80211_SKB_RXCB (skb );
48714871 struct ieee80211_fast_rx * fast_rx ;
48724872 struct ieee80211_rx_data rx ;
4873+ int link_id = -1 ;
48734874
48744875 memset (& rx , 0 , sizeof (rx ));
48754876 rx .skb = skb ;
@@ -4886,12 +4887,8 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
48864887 if (!pubsta )
48874888 goto drop ;
48884889
4889- rx .sta = container_of (pubsta , struct sta_info , sta );
4890- rx .sdata = rx .sta -> sdata ;
4891-
4892- if (status -> link_valid &&
4893- !ieee80211_rx_is_valid_sta_link_id (pubsta , status -> link_id ))
4894- goto drop ;
4890+ if (status -> link_valid )
4891+ link_id = status -> link_id ;
48954892
48964893 /*
48974894 * TODO: Should the frame be dropped if the right link_id is not
@@ -4900,19 +4897,8 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
49004897 * link_id is used only for stats purpose and updating the stats on
49014898 * the deflink is fine?
49024899 */
4903- if (status -> link_valid )
4904- rx .link_id = status -> link_id ;
4905-
4906- if (rx .link_id >= 0 ) {
4907- struct ieee80211_link_data * link ;
4908-
4909- link = rcu_dereference (rx .sdata -> link [rx .link_id ]);
4910- if (!link )
4911- goto drop ;
4912- rx .link = link ;
4913- } else {
4914- rx .link = & rx .sdata -> deflink ;
4915- }
4900+ if (!ieee80211_rx_data_set_sta (& rx , pubsta , link_id ))
4901+ goto drop ;
49164902
49174903 fast_rx = rcu_dereference (rx .sta -> fast_rx );
49184904 if (!fast_rx )
@@ -4930,6 +4916,8 @@ static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx,
49304916{
49314917 struct link_sta_info * link_sta ;
49324918 struct ieee80211_hdr * hdr = (void * )skb -> data ;
4919+ struct sta_info * sta ;
4920+ int link_id = -1 ;
49334921
49344922 /*
49354923 * Look up link station first, in case there's a
@@ -4939,24 +4927,19 @@ static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx,
49394927 */
49404928 link_sta = link_sta_info_get_bss (rx -> sdata , hdr -> addr2 );
49414929 if (link_sta ) {
4942- rx -> sta = link_sta -> sta ;
4943- rx -> link_id = link_sta -> link_id ;
4930+ sta = link_sta -> sta ;
4931+ link_id = link_sta -> link_id ;
49444932 } else {
49454933 struct ieee80211_rx_status * status = IEEE80211_SKB_RXCB (skb );
49464934
4947- rx -> sta = sta_info_get_bss (rx -> sdata , hdr -> addr2 );
4948- if (rx -> sta ) {
4949- if (status -> link_valid &&
4950- !ieee80211_rx_is_valid_sta_link_id (& rx -> sta -> sta ,
4951- status -> link_id ))
4952- return false;
4953-
4954- rx -> link_id = status -> link_valid ? status -> link_id : -1 ;
4955- } else {
4956- rx -> link_id = -1 ;
4957- }
4935+ sta = sta_info_get_bss (rx -> sdata , hdr -> addr2 );
4936+ if (status -> link_valid )
4937+ link_id = status -> link_id ;
49584938 }
49594939
4940+ if (!ieee80211_rx_data_set_sta (rx , & sta -> sta , link_id ))
4941+ return false;
4942+
49604943 return ieee80211_prepare_and_rx_handle (rx , skb , consume );
49614944}
49624945
@@ -5015,19 +4998,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
50154998
50164999 if (ieee80211_is_data (fc )) {
50175000 struct sta_info * sta , * prev_sta ;
5018- u8 link_id = status -> link_id ;
5001+ int link_id = -1 ;
50195002
5020- if (pubsta ) {
5021- rx .sta = container_of (pubsta , struct sta_info , sta );
5022- rx .sdata = rx .sta -> sdata ;
5003+ if (status -> link_valid )
5004+ link_id = status -> link_id ;
50235005
5024- if (status -> link_valid &&
5025- ! ieee80211_rx_is_valid_sta_link_id ( pubsta , link_id ))
5006+ if (pubsta ) {
5007+ if (! ieee80211_rx_data_set_sta ( & rx , pubsta , link_id ))
50265008 goto out ;
50275009
5028- if (status -> link_valid )
5029- rx .link_id = status -> link_id ;
5030-
50315010 /*
50325011 * In MLO connection, fetch the link_id using addr2
50335012 * when the driver does not pass link_id in status.
@@ -5045,7 +5024,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
50455024 if (!link_sta )
50465025 goto out ;
50475026
5048- rx . link_id = link_sta -> link_id ;
5027+ ieee80211_rx_data_set_link ( & rx , link_sta -> link_id ) ;
50495028 }
50505029
50515030 if (ieee80211_prepare_and_rx_handle (& rx , skb , true))
@@ -5061,30 +5040,27 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
50615040 continue ;
50625041 }
50635042
5064- if ((status -> link_valid &&
5065- !ieee80211_rx_is_valid_sta_link_id (& prev_sta -> sta ,
5066- link_id )) ||
5067- (!status -> link_valid && prev_sta -> sta .mlo ))
5043+ rx .sdata = prev_sta -> sdata ;
5044+ if (!ieee80211_rx_data_set_sta (& rx , & prev_sta -> sta ,
5045+ link_id ))
5046+ goto out ;
5047+
5048+ if (!status -> link_valid && prev_sta -> sta .mlo )
50685049 continue ;
50695050
5070- rx .link_id = status -> link_valid ? link_id : -1 ;
5071- rx .sta = prev_sta ;
5072- rx .sdata = prev_sta -> sdata ;
50735051 ieee80211_prepare_and_rx_handle (& rx , skb , false);
50745052
50755053 prev_sta = sta ;
50765054 }
50775055
50785056 if (prev_sta ) {
5079- if ((status -> link_valid &&
5080- !ieee80211_rx_is_valid_sta_link_id (& prev_sta -> sta ,
5081- link_id )) ||
5082- (!status -> link_valid && prev_sta -> sta .mlo ))
5057+ rx .sdata = prev_sta -> sdata ;
5058+ if (!ieee80211_rx_data_set_sta (& rx , & prev_sta -> sta ,
5059+ link_id ))
50835060 goto out ;
50845061
5085- rx .link_id = status -> link_valid ? link_id : -1 ;
5086- rx .sta = prev_sta ;
5087- rx .sdata = prev_sta -> sdata ;
5062+ if (!status -> link_valid && prev_sta -> sta .mlo )
5063+ goto out ;
50885064
50895065 if (ieee80211_prepare_and_rx_handle (& rx , skb , true))
50905066 return ;
0 commit comments