@@ -601,7 +601,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
601
601
struct ieee80211_supported_band * sband ;
602
602
struct ieee80211_chanctx_conf * chanctx_conf ;
603
603
struct ieee80211_channel * chan ;
604
- u32 rate_flags , rates = 0 ;
604
+ u32 rates = 0 ;
605
605
606
606
sdata_assert_lock (sdata );
607
607
@@ -612,7 +612,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
612
612
return ;
613
613
}
614
614
chan = chanctx_conf -> def .chan ;
615
- rate_flags = ieee80211_chandef_rate_flags (& chanctx_conf -> def );
616
615
rcu_read_unlock ();
617
616
sband = local -> hw .wiphy -> bands [chan -> band ];
618
617
shift = ieee80211_vif_get_shift (& sdata -> vif );
@@ -636,9 +635,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
636
635
*/
637
636
rates_len = 0 ;
638
637
for (i = 0 ; i < sband -> n_bitrates ; i ++ ) {
639
- if ((rate_flags & sband -> bitrates [i ].flags )
640
- != rate_flags )
641
- continue ;
642
638
rates |= BIT (i );
643
639
rates_len ++ ;
644
640
}
@@ -2818,7 +2814,7 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
2818
2814
u32 * rates , u32 * basic_rates ,
2819
2815
bool * have_higher_than_11mbit ,
2820
2816
int * min_rate , int * min_rate_index ,
2821
- int shift , u32 rate_flags )
2817
+ int shift )
2822
2818
{
2823
2819
int i , j ;
2824
2820
@@ -2846,8 +2842,6 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
2846
2842
int brate ;
2847
2843
2848
2844
br = & sband -> bitrates [j ];
2849
- if ((rate_flags & br -> flags ) != rate_flags )
2850
- continue ;
2851
2845
2852
2846
brate = DIV_ROUND_UP (br -> bitrate , (1 << shift ) * 5 );
2853
2847
if (brate == rate ) {
@@ -4398,40 +4392,32 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
4398
4392
return - ENOMEM ;
4399
4393
}
4400
4394
4401
- if (new_sta || override ) {
4402
- err = ieee80211_prep_channel (sdata , cbss );
4403
- if (err ) {
4404
- if (new_sta )
4405
- sta_info_free (local , new_sta );
4406
- return - EINVAL ;
4407
- }
4408
- }
4409
-
4395
+ /*
4396
+ * Set up the information for the new channel before setting the
4397
+ * new channel. We can't - completely race-free - change the basic
4398
+ * rates bitmap and the channel (sband) that it refers to, but if
4399
+ * we set it up before we at least avoid calling into the driver's
4400
+ * bss_info_changed() method with invalid information (since we do
4401
+ * call that from changing the channel - only for IDLE and perhaps
4402
+ * some others, but ...).
4403
+ *
4404
+ * So to avoid that, just set up all the new information before the
4405
+ * channel, but tell the driver to apply it only afterwards, since
4406
+ * it might need the new channel for that.
4407
+ */
4410
4408
if (new_sta ) {
4411
4409
u32 rates = 0 , basic_rates = 0 ;
4412
4410
bool have_higher_than_11mbit ;
4413
4411
int min_rate = INT_MAX , min_rate_index = -1 ;
4414
- struct ieee80211_chanctx_conf * chanctx_conf ;
4415
4412
const struct cfg80211_bss_ies * ies ;
4416
4413
int shift = ieee80211_vif_get_shift (& sdata -> vif );
4417
- u32 rate_flags ;
4418
-
4419
- rcu_read_lock ();
4420
- chanctx_conf = rcu_dereference (sdata -> vif .chanctx_conf );
4421
- if (WARN_ON (!chanctx_conf )) {
4422
- rcu_read_unlock ();
4423
- sta_info_free (local , new_sta );
4424
- return - EINVAL ;
4425
- }
4426
- rate_flags = ieee80211_chandef_rate_flags (& chanctx_conf -> def );
4427
- rcu_read_unlock ();
4428
4414
4429
4415
ieee80211_get_rates (sband , bss -> supp_rates ,
4430
4416
bss -> supp_rates_len ,
4431
4417
& rates , & basic_rates ,
4432
4418
& have_higher_than_11mbit ,
4433
4419
& min_rate , & min_rate_index ,
4434
- shift , rate_flags );
4420
+ shift );
4435
4421
4436
4422
/*
4437
4423
* This used to be a workaround for basic rates missing
@@ -4489,8 +4475,22 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
4489
4475
sdata -> vif .bss_conf .sync_dtim_count = 0 ;
4490
4476
}
4491
4477
rcu_read_unlock ();
4478
+ }
4492
4479
4493
- /* tell driver about BSSID, basic rates and timing */
4480
+ if (new_sta || override ) {
4481
+ err = ieee80211_prep_channel (sdata , cbss );
4482
+ if (err ) {
4483
+ if (new_sta )
4484
+ sta_info_free (local , new_sta );
4485
+ return - EINVAL ;
4486
+ }
4487
+ }
4488
+
4489
+ if (new_sta ) {
4490
+ /*
4491
+ * tell driver about BSSID, basic rates and timing
4492
+ * this was set up above, before setting the channel
4493
+ */
4494
4494
ieee80211_bss_info_change_notify (sdata ,
4495
4495
BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES |
4496
4496
BSS_CHANGED_BEACON_INT );
0 commit comments