]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/ibss.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[karo-tx-linux.git] / net / mac80211 / ibss.c
index 01974c2510a801581b99dc35310c1bf0d0ab6f07..b2cc1fda6cfdb6ba1054aa2bb224f9fce7bba5e8 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <linux/if_ether.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
@@ -91,12 +92,18 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
                sta_info_flush(sdata->local, sdata);
 
+       /* if merging, indicate to driver that we leave the old IBSS */
+       if (sdata->vif.bss_conf.ibss_joined) {
+               sdata->vif.bss_conf.ibss_joined = false;
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS);
+       }
+
        memcpy(ifibss->bssid, bssid, ETH_ALEN);
 
        sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
 
        local->oper_channel = chan;
-       local->oper_channel_type = NL80211_CHAN_NO_HT;
+       WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
        sband = local->hw.wiphy->bands[chan->band];
@@ -170,6 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        bss_change |= BSS_CHANGED_BSSID;
        bss_change |= BSS_CHANGED_BEACON;
        bss_change |= BSS_CHANGED_BEACON_ENABLED;
+       bss_change |= BSS_CHANGED_IBSS;
+       sdata->vif.bss_conf.ibss_joined = true;
        ieee80211_bss_info_change_notify(sdata, bss_change);
 
        ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
@@ -480,7 +489,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
        printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
               "IBSS networks with same SSID (merge)\n", sdata->name);
 
-       ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
+       ieee80211_request_internal_scan(sdata,
+                       ifibss->ssid, ifibss->ssid_len,
+                       ifibss->fixed_channel ? ifibss->channel : NULL);
 }
 
 static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -587,8 +598,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
                       "join\n", sdata->name);
 
-               ieee80211_request_internal_scan(sdata, ifibss->ssid,
-                                               ifibss->ssid_len);
+               ieee80211_request_internal_scan(sdata,
+                               ifibss->ssid, ifibss->ssid_len,
+                               ifibss->fixed_channel ? ifibss->channel : NULL);
        } else {
                int interval = IEEE80211_SCAN_INTERVAL;
 
@@ -896,6 +908,13 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
        sdata->u.ibss.channel = params->channel;
        sdata->u.ibss.fixed_channel = params->channel_fixed;
 
+       /* fix ourselves to that channel now already */
+       if (params->channel_fixed) {
+               sdata->local->oper_channel = params->channel;
+               WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
+                                                   NL80211_CHAN_NO_HT));
+       }
+
        if (params->ie) {
                sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
                                           GFP_KERNEL);
@@ -950,7 +969,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
        kfree(sdata->u.ibss.ie);
        skb = sdata->u.ibss.presp;
        rcu_assign_pointer(sdata->u.ibss.presp, NULL);
-       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+       sdata->vif.bss_conf.ibss_joined = false;
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
+                                               BSS_CHANGED_IBSS);
        synchronize_rcu();
        kfree_skb(skb);