]> err.no Git - linux-2.6/blobdiff - net/ieee80211/softmac/ieee80211softmac_assoc.c
[PATCH] softmac: fix build-break from 881ee6999d66c8fc903b429b73bbe6045b38c549
[linux-2.6] / net / ieee80211 / softmac / ieee80211softmac_assoc.c
index 5d90b9a6ee50f5863027a1e957b1d918bbdfa0b7..44215ce64d4e9db3c9abb54edbfd35c154590bfd 100644 (file)
@@ -47,9 +47,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
        
        dprintk(KERN_INFO PFX "sent association request!\n");
 
-       /* Change the state to associating */
        spin_lock_irqsave(&mac->lock, flags);
-       mac->associnfo.associating = 1;
        mac->associated = 0; /* just to make sure */
 
        /* Set a timer for timeout */
@@ -63,6 +61,7 @@ void
 ieee80211softmac_assoc_timeout(void *d)
 {
        struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
+       struct ieee80211softmac_network *n;
        unsigned long flags;
 
        spin_lock_irqsave(&mac->lock, flags);
@@ -75,11 +74,12 @@ ieee80211softmac_assoc_timeout(void *d)
        mac->associnfo.associating = 0;
        mac->associnfo.bssvalid = 0;
        mac->associated = 0;
+
+       n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
        spin_unlock_irqrestore(&mac->lock, flags);
 
        dprintk(KERN_INFO PFX "assoc request timed out!\n");
-       /* FIXME: we need to know the network here. that requires a bit of restructuring */
-       ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
+       ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
 }
 
 void
@@ -164,12 +164,28 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne
 }
 
 static void
-ieee80211softmac_assoc_notify(struct net_device *dev, void *context)
+ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
        ieee80211softmac_assoc_work((void*)mac);
 }
 
+static void
+ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void *context)
+{
+       struct ieee80211softmac_device *mac = ieee80211_priv(dev);
+
+       switch (event_type) {
+       case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
+               ieee80211softmac_assoc_work((void*)mac);
+               break;
+       case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
+       case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
+               ieee80211softmac_disassoc(mac);
+               break;
+       }
+}
+
 /* This function is called to handle userspace requests (asynchronously) */
 void
 ieee80211softmac_assoc_work(void *d)
@@ -187,6 +203,10 @@ ieee80211softmac_assoc_work(void *d)
        if (mac->associated)
                ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
 
+       spin_lock_irqsave(&mac->lock, flags);
+       mac->associnfo.associating = 1;
+       spin_unlock_irqrestore(&mac->lock, flags);
+
        /* try to find the requested network in our list, if we found one already */
        if (bssvalid || mac->associnfo.bssfixed)
                found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);       
@@ -249,7 +269,7 @@ ieee80211softmac_assoc_work(void *d)
                         * Maybe we can hope to have more memory after scanning finishes ;)
                         */
                        dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
-                       ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify, NULL);
+                       ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
                        if (ieee80211softmac_start_scan(mac))
                                dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
                        return;
@@ -279,19 +299,32 @@ ieee80211softmac_assoc_work(void *d)
        memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
        
        /* we found a network! authenticate (if necessary) and associate to it. */
-       if (!found->authenticated) {
+       if (found->authenticating) {
+               dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
+               if(!mac->associnfo.assoc_wait) {
+                       mac->associnfo.assoc_wait = 1;
+                       ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
+               }
+               return;
+       }
+       if (!found->authenticated && !found->authenticating) {
                /* This relies on the fact that _auth_req only queues the work,
                 * otherwise adding the notification would be racy. */
                if (!ieee80211softmac_auth_req(mac, found)) {
-                       dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n");
-                       ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL);
+                       if(!mac->associnfo.assoc_wait) {
+                               dprintk(KERN_INFO PFX "Cannot associate without being authenticated, requested authentication\n");
+                               mac->associnfo.assoc_wait = 1;
+                               ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
+                       }
                } else {
                        printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
+                       mac->associnfo.assoc_wait = 0;
                        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
                }
                return;
        }
        /* finally! now we can start associating */
+       mac->associnfo.assoc_wait = 0;
        ieee80211softmac_assoc(mac, found);
 }