Merge branch 'gpio/merge' of git://git.secretlab.ca/git/linux-2.6
[pandora-kernel.git] / net / mac80211 / ibss.c
index 3e81af1..56c24ca 100644 (file)
@@ -40,7 +40,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
                                        struct ieee80211_mgmt *mgmt,
                                        size_t len)
 {
-       u16 auth_alg, auth_transaction, status_code;
+       u16 auth_alg, auth_transaction;
 
        lockdep_assert_held(&sdata->u.ibss.mtx);
 
@@ -49,7 +49,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
 
        auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
        auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
-       status_code = le16_to_cpu(mgmt->u.auth.status_code);
 
        /*
         * IEEE 802.11 standard does not require authentication in IBSS
@@ -527,8 +526,6 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
 static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_supported_band *sband;
        u8 bssid[ETH_ALEN];
        u16 capability;
        int i;
@@ -551,8 +548,6 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
        printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
               sdata->name, bssid);
 
-       sband = local->hw.wiphy->bands[ifibss->channel->band];
-
        capability = WLAN_CAPABILITY_IBSS;
 
        if (ifibss->privacy)
@@ -661,19 +656,22 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
 static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
                                        struct sk_buff *req)
 {
-       struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req);
        struct ieee80211_mgmt *mgmt = (void *)req->data;
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
        int tx_last_beacon, len = req->len;
        struct sk_buff *skb;
        struct ieee80211_mgmt *resp;
+       struct sk_buff *presp;
        u8 *pos, *end;
 
        lockdep_assert_held(&ifibss->mtx);
 
+       presp = rcu_dereference_protected(ifibss->presp,
+                                         lockdep_is_held(&ifibss->mtx));
+
        if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
-           len < 24 + 2 || !ifibss->presp)
+           len < 24 + 2 || !presp)
                return;
 
        tx_last_beacon = drv_tx_last_beacon(local);
@@ -685,7 +683,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
               mgmt->bssid, tx_last_beacon);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
-       if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH))
+       if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
                return;
 
        if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
@@ -711,7 +709,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        }
 
        /* Reply with ProbeResp */
-       skb = skb_copy(ifibss->presp, GFP_KERNEL);
+       skb = skb_copy(presp, GFP_KERNEL);
        if (!skb)
                return;
 
@@ -967,6 +965,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 
        mutex_lock(&sdata->u.ibss.mtx);
 
+       sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
+       memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
+       sdata->u.ibss.ssid_len = 0;
+
        active_ibss = ieee80211_sta_active_ibss(sdata);
 
        if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
@@ -991,7 +993,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
 
        /* remove beacon */
        kfree(sdata->u.ibss.ie);
-       skb = sdata->u.ibss.presp;
+       skb = rcu_dereference_protected(sdata->u.ibss.presp,
+                                       lockdep_is_held(&sdata->u.ibss.mtx));
        rcu_assign_pointer(sdata->u.ibss.presp, NULL);
        sdata->vif.bss_conf.ibss_joined = false;
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
@@ -1000,8 +1003,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
        kfree_skb(skb);
 
        skb_queue_purge(&sdata->skb_queue);
-       memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
-       sdata->u.ibss.ssid_len = 0;
 
        del_timer_sync(&sdata->u.ibss.timer);