diff options
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e2976da4e0d9..b2cc1fda6cfd 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -92,12 +92,18 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
92 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) | 92 | if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) |
93 | sta_info_flush(sdata->local, sdata); | 93 | sta_info_flush(sdata->local, sdata); |
94 | 94 | ||
95 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
96 | if (sdata->vif.bss_conf.ibss_joined) { | ||
97 | sdata->vif.bss_conf.ibss_joined = false; | ||
98 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | ||
99 | } | ||
100 | |||
95 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | 101 | memcpy(ifibss->bssid, bssid, ETH_ALEN); |
96 | 102 | ||
97 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 103 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
98 | 104 | ||
99 | local->oper_channel = chan; | 105 | local->oper_channel = chan; |
100 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 106 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); |
101 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 107 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
102 | 108 | ||
103 | sband = local->hw.wiphy->bands[chan->band]; | 109 | sband = local->hw.wiphy->bands[chan->band]; |
@@ -171,6 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
171 | bss_change |= BSS_CHANGED_BSSID; | 177 | bss_change |= BSS_CHANGED_BSSID; |
172 | bss_change |= BSS_CHANGED_BEACON; | 178 | bss_change |= BSS_CHANGED_BEACON; |
173 | bss_change |= BSS_CHANGED_BEACON_ENABLED; | 179 | bss_change |= BSS_CHANGED_BEACON_ENABLED; |
180 | bss_change |= BSS_CHANGED_IBSS; | ||
181 | sdata->vif.bss_conf.ibss_joined = true; | ||
174 | ieee80211_bss_info_change_notify(sdata, bss_change); | 182 | ieee80211_bss_info_change_notify(sdata, bss_change); |
175 | 183 | ||
176 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); | 184 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); |
@@ -265,17 +273,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
265 | sta->sta.supp_rates[band] = supp_rates | | 273 | sta->sta.supp_rates[band] = supp_rates | |
266 | ieee80211_mandatory_rates(local, band); | 274 | ieee80211_mandatory_rates(local, band); |
267 | 275 | ||
276 | if (sta->sta.supp_rates[band] != prev_rates) { | ||
268 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 277 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
269 | if (sta->sta.supp_rates[band] != prev_rates) | ||
270 | printk(KERN_DEBUG "%s: updated supp_rates set " | 278 | printk(KERN_DEBUG "%s: updated supp_rates set " |
271 | "for %pM based on beacon info (0x%llx | " | 279 | "for %pM based on beacon/probe_response " |
272 | "0x%llx -> 0x%llx)\n", | 280 | "(0x%x -> 0x%x)\n", |
273 | sdata->name, | 281 | sdata->name, sta->sta.addr, |
274 | sta->sta.addr, | 282 | prev_rates, sta->sta.supp_rates[band]); |
275 | (unsigned long long) prev_rates, | ||
276 | (unsigned long long) supp_rates, | ||
277 | (unsigned long long) sta->sta.supp_rates[band]); | ||
278 | #endif | 283 | #endif |
284 | rate_control_rate_init(sta); | ||
285 | } | ||
279 | rcu_read_unlock(); | 286 | rcu_read_unlock(); |
280 | } else { | 287 | } else { |
281 | rcu_read_unlock(); | 288 | rcu_read_unlock(); |
@@ -371,6 +378,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
371 | sdata->name, mgmt->bssid); | 378 | sdata->name, mgmt->bssid); |
372 | #endif | 379 | #endif |
373 | ieee80211_sta_join_ibss(sdata, bss); | 380 | ieee80211_sta_join_ibss(sdata, bss); |
381 | supp_rates = ieee80211_sta_get_rates(local, elems, band); | ||
374 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 382 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, |
375 | supp_rates, GFP_KERNEL); | 383 | supp_rates, GFP_KERNEL); |
376 | } | 384 | } |
@@ -481,7 +489,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
481 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " | 489 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " |
482 | "IBSS networks with same SSID (merge)\n", sdata->name); | 490 | "IBSS networks with same SSID (merge)\n", sdata->name); |
483 | 491 | ||
484 | ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len); | 492 | ieee80211_request_internal_scan(sdata, |
493 | ifibss->ssid, ifibss->ssid_len, | ||
494 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
485 | } | 495 | } |
486 | 496 | ||
487 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 497 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
@@ -588,8 +598,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
588 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " | 598 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " |
589 | "join\n", sdata->name); | 599 | "join\n", sdata->name); |
590 | 600 | ||
591 | ieee80211_request_internal_scan(sdata, ifibss->ssid, | 601 | ieee80211_request_internal_scan(sdata, |
592 | ifibss->ssid_len); | 602 | ifibss->ssid, ifibss->ssid_len, |
603 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
593 | } else { | 604 | } else { |
594 | int interval = IEEE80211_SCAN_INTERVAL; | 605 | int interval = IEEE80211_SCAN_INTERVAL; |
595 | 606 | ||
@@ -897,6 +908,13 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
897 | sdata->u.ibss.channel = params->channel; | 908 | sdata->u.ibss.channel = params->channel; |
898 | sdata->u.ibss.fixed_channel = params->channel_fixed; | 909 | sdata->u.ibss.fixed_channel = params->channel_fixed; |
899 | 910 | ||
911 | /* fix ourselves to that channel now already */ | ||
912 | if (params->channel_fixed) { | ||
913 | sdata->local->oper_channel = params->channel; | ||
914 | WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata, | ||
915 | NL80211_CHAN_NO_HT)); | ||
916 | } | ||
917 | |||
900 | if (params->ie) { | 918 | if (params->ie) { |
901 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, | 919 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, |
902 | GFP_KERNEL); | 920 | GFP_KERNEL); |
@@ -951,7 +969,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
951 | kfree(sdata->u.ibss.ie); | 969 | kfree(sdata->u.ibss.ie); |
952 | skb = sdata->u.ibss.presp; | 970 | skb = sdata->u.ibss.presp; |
953 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); | 971 | rcu_assign_pointer(sdata->u.ibss.presp, NULL); |
954 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 972 | sdata->vif.bss_conf.ibss_joined = false; |
973 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | ||
974 | BSS_CHANGED_IBSS); | ||
955 | synchronize_rcu(); | 975 | synchronize_rcu(); |
956 | kfree_skb(skb); | 976 | kfree_skb(skb); |
957 | 977 | ||