cfg80211: report userspace SME connected event properly
[pandora-kernel.git] / net / wireless / mlme.c
index b44b6c0..79d2eec 100644 (file)
@@ -67,6 +67,16 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 
        status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
+       /*
+        * This is a bit of a hack, we don't notify userspace of
+        * a (re-)association reply if we tried to send a reassoc
+        * and got a reject -- we only try again with an assoc
+        * frame instead of reassoc.
+        */
+       if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
+           cfg80211_sme_failed_reassoc(wdev))
+               goto out;
+
        nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
 
        if (status_code == WLAN_STATUS_SUCCESS) {
@@ -86,6 +96,15 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
                WARN_ON(!bss);
        }
 
+       if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
+               /*
+                * This is for the userspace SME, the CONNECTING
+                * state will be changed to CONNECTED by
+                * __cfg80211_connect_result() below.
+                */
+               wdev->sme_state = CFG80211_SME_CONNECTING;
+       }
+
        /* this consumes one bss reference (unless bss is NULL) */
        __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
                                  status_code,
@@ -97,6 +116,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
                cfg80211_put_bss(&bss->pub);
        }
 
+ out:
        wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
@@ -149,7 +169,7 @@ static void __cfg80211_send_deauth(struct net_device *dev,
 
                reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 
-               from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
+               from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
                __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
        } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
                __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
@@ -215,7 +235,7 @@ static void __cfg80211_send_disassoc(struct net_device *dev,
 
        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 
-       from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
+       from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
        __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 }