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 | ||
