diff options
-rw-r--r-- | net/mac80211/mlme.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2f46db7d3afc..cc8e6ea1b27e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -4392,15 +4392,19 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
4392 | return -ENOMEM; | 4392 | return -ENOMEM; |
4393 | } | 4393 | } |
4394 | 4394 | ||
4395 | if (new_sta || override) { | 4395 | /* |
4396 | err = ieee80211_prep_channel(sdata, cbss); | 4396 | * Set up the information for the new channel before setting the |
4397 | if (err) { | 4397 | * new channel. We can't - completely race-free - change the basic |
4398 | if (new_sta) | 4398 | * rates bitmap and the channel (sband) that it refers to, but if |
4399 | sta_info_free(local, new_sta); | 4399 | * we set it up before we at least avoid calling into the driver's |
4400 | return -EINVAL; | 4400 | * bss_info_changed() method with invalid information (since we do |
4401 | } | 4401 | * call that from changing the channel - only for IDLE and perhaps |
4402 | } | 4402 | * some others, but ...). |
4403 | 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 | */ | ||
4404 | if (new_sta) { | 4408 | if (new_sta) { |
4405 | u32 rates = 0, basic_rates = 0; | 4409 | u32 rates = 0, basic_rates = 0; |
4406 | bool have_higher_than_11mbit; | 4410 | bool have_higher_than_11mbit; |
@@ -4471,8 +4475,22 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
4471 | sdata->vif.bss_conf.sync_dtim_count = 0; | 4475 | sdata->vif.bss_conf.sync_dtim_count = 0; |
4472 | } | 4476 | } |
4473 | rcu_read_unlock(); | 4477 | rcu_read_unlock(); |
4478 | } | ||
4474 | 4479 | ||
4475 | /* 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 | */ | ||
4476 | ieee80211_bss_info_change_notify(sdata, | 4494 | ieee80211_bss_info_change_notify(sdata, |
4477 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES | | 4495 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES | |
4478 | BSS_CHANGED_BEACON_INT); | 4496 | BSS_CHANGED_BEACON_INT); |