Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
[linux-drm-fsl-dcu.git] / net / ieee80211 / softmac / ieee80211softmac_auth.c
index 4cef39e171d007cf4570f28ae793070f5ccaf5ff..826c32d24461198614b5ba3eb5eb4a0f33951ea2 100644 (file)
 
 #include "ieee80211softmac_priv.h"
 
-static void ieee80211softmac_auth_queue(void *data);
+static void ieee80211softmac_auth_queue(struct work_struct *work);
 
 /* Queues an auth request to the desired AP */
 int
-ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, 
+ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
        struct ieee80211softmac_network *net)
 {
        struct ieee80211softmac_auth_queue_item *auth;
        unsigned long flags;
-       
+
        if (net->authenticating || net->authenticated)
                return 0;
        net->authenticating = 1;
@@ -54,37 +54,38 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
        auth->mac = mac;
        auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT;
        auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST;
-       INIT_WORK(&auth->work, &ieee80211softmac_auth_queue, (void *)auth);
-       
+       INIT_DELAYED_WORK(&auth->work, ieee80211softmac_auth_queue);
+
        /* Lock (for list) */
        spin_lock_irqsave(&mac->lock, flags);
 
        /* add to list */
        list_add_tail(&auth->list, &mac->auth_queue);
-       schedule_work(&auth->work);
+       schedule_delayed_work(&auth->work, 0);
        spin_unlock_irqrestore(&mac->lock, flags);
-       
+
        return 0;
 }
 
 
 /* Sends an auth request to the desired AP and handles timeouts */
 static void
-ieee80211softmac_auth_queue(void *data)
+ieee80211softmac_auth_queue(struct work_struct *work)
 {
        struct ieee80211softmac_device *mac;
        struct ieee80211softmac_auth_queue_item *auth;
        struct ieee80211softmac_network *net;
        unsigned long flags;
 
-       auth = (struct ieee80211softmac_auth_queue_item *)data;
+       auth = container_of(work, struct ieee80211softmac_auth_queue_item,
+                           work.work);
        net = auth->net;
        mac = auth->mac;
 
        if(auth->retry > 0) {
                /* Switch to correct channel for this network */
                mac->set_channel(mac->dev, net->channel);
-               
+
                /* Lock and set flags */
                spin_lock_irqsave(&mac->lock, flags);
                if (unlikely(!mac->running)) {
@@ -118,20 +119,22 @@ ieee80211softmac_auth_queue(void *data)
 
 /* Sends a response to an auth challenge (for shared key auth). */
 static void
-ieee80211softmac_auth_challenge_response(void *_aq)
+ieee80211softmac_auth_challenge_response(struct work_struct *work)
 {
-       struct ieee80211softmac_auth_queue_item *aq = _aq;
+       struct ieee80211softmac_auth_queue_item *aq =
+               container_of(work, struct ieee80211softmac_auth_queue_item,
+                            work.work);
 
        /* Send our response */
        ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
 }
 
 /* Handle the auth response from the AP
- * This should be registered with ieee80211 as handle_auth 
+ * This should be registered with ieee80211 as handle_auth
  */
-int 
+int
 ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
-{      
+{
 
        struct list_head *list_ptr;
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
@@ -139,7 +142,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
        struct ieee80211softmac_network *net = NULL;
        unsigned long flags;
        u8 * data;
-       
+
        if (unlikely(!mac->running))
                return -ENODEV;
 
@@ -154,19 +157,19 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                        aq = NULL;
        }
        spin_unlock_irqrestore(&mac->lock, flags);
-       
+
        /* Make sure that we've got an auth queue item for this request */
        if(aq == NULL)
        {
-               printkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2));
+               dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2));
                /* Error #? */
                return -1;
-       }                       
-       
+       }
+
        /* Check for out of order authentication */
        if(!net->authenticating)
        {
-               printkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2));
+               dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2));
                return -1;
        }
 
@@ -179,10 +182,10 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                case WLAN_STATUS_SUCCESS:
                        /* Update the status to Authenticated */
                        spin_lock_irqsave(&mac->lock, flags);
-                       net->authenticating = 0;
+                       net->authenticating = 0;
                        net->authenticated = 1;
                        spin_unlock_irqrestore(&mac->lock, flags);
-                       
+
                        /* Send event */
                        printkl(KERN_NOTICE PFX "Open Authentication completed with "MAC_FMT"\n", MAC_ARG(net->bssid));
                        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
@@ -193,8 +196,8 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                        net->authenticated = 0;
                        net->authenticating = 0;
                        spin_unlock_irqrestore(&mac->lock, flags);
-                       
-                       printkl(KERN_NOTICE PFX "Open Authentication with "MAC_FMT" failed, error code: %i\n", 
+
+                       printkl(KERN_NOTICE PFX "Open Authentication with "MAC_FMT" failed, error code: %i\n",
                                MAC_ARG(net->bssid), le16_to_cpup(&auth->status));
                        /* Count the error? */
                        break;
@@ -209,18 +212,24 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                        data = (u8 *)auth->info_element;
                        if (*data++ != MFIE_TYPE_CHALLENGE) {
                                printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n");
-                               break;  
+                               break;
                        }
                        /* Save the challenge */
                        spin_lock_irqsave(&mac->lock, flags);
-                       net->challenge_len = *data++;   
+                       net->challenge_len = *data++;
                        if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
                                net->challenge_len = WLAN_AUTH_CHALLENGE_LEN;
-                       if (net->challenge != NULL)
-                               kfree(net->challenge);
-                       net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC);
-                       memcpy(net->challenge, data, net->challenge_len);
-                       aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; 
+                       kfree(net->challenge);
+                       net->challenge = kmemdup(data, net->challenge_len,
+                                                GFP_ATOMIC);
+                       if (net->challenge == NULL) {
+                               printkl(KERN_NOTICE PFX "Shared Key "
+                                       "Authentication failed due to "
+                                       "memory shortage.\n");
+                               spin_unlock_irqrestore(&mac->lock, flags);
+                               break;
+                       }
+                       aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
 
                        /* We reuse the work struct from the auth request here.
                         * It is safe to do so as each one is per-request, and
@@ -228,8 +237,8 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                         * we have obviously already sent the initial auth
                         * request. */
                        cancel_delayed_work(&aq->work);
-                       INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq);
-                       schedule_work(&aq->work);
+                       INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response);
+                       schedule_delayed_work(&aq->work, 0);
                        spin_unlock_irqrestore(&mac->lock, flags);
                        return 0;
                case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
@@ -239,22 +248,22 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                        /* Check the status code of the response */
                        switch(auth->status) {
                        case WLAN_STATUS_SUCCESS:
-                               /* Update the status to Authenticated */        
+                               /* Update the status to Authenticated */
                                spin_lock_irqsave(&mac->lock, flags);
                                net->authenticating = 0;
                                net->authenticated = 1;
                                spin_unlock_irqrestore(&mac->lock, flags);
-                               printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n", 
+                               printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n",
                                        MAC_ARG(net->bssid));
                                ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
                                break;
                        default:
-                               printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n", 
+                               printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n",
                                        MAC_ARG(net->bssid), le16_to_cpup(&auth->status));
                                /* Lock and reset flags */
                                spin_lock_irqsave(&mac->lock, flags);
-                               net->authenticating = 0;
-                               net->authenticated = 0;
+                               net->authenticating = 0;
+                               net->authenticated = 0;
                                spin_unlock_irqrestore(&mac->lock, flags);
                                /* Count the error? */
                                break;
@@ -268,7 +277,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                goto free_aq;
                break;
        default:
-               /* ERROR */     
+               /* ERROR */
                goto free_aq;
                break;
        }
@@ -304,7 +313,7 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
        spin_lock_irqsave(&mac->lock, flags);
        net->authenticating = 0;
        net->authenticated = 0;
-       
+
        /* Find correct auth queue item, if it exists */
        list_for_each(list_ptr, &mac->auth_queue) {
                aq = list_entry(list_ptr, struct ieee80211softmac_auth_queue_item, list);
@@ -313,7 +322,7 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
                else
                        aq = NULL;
        }
-       
+
        /* Cancel pending work */
        if(aq != NULL)
                /* Not entirely safe?  What about running work? */
@@ -324,47 +333,49 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
        if(net->challenge != NULL)
                kfree(net->challenge);
        kfree(net);
-       
+
        /* can't transmit data right now... */
        netif_carrier_off(mac->dev);
        spin_unlock_irqrestore(&mac->lock, flags);
+
+       ieee80211softmac_try_reassoc(mac);
 }
 
-/* 
+/*
  * Sends a deauth request to the desired AP
  */
-int 
-ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac, 
+int
+ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac,
        struct ieee80211softmac_network *net, int reason)
 {
        int ret;
-       
+
        /* Make sure the network is authenticated */
        if (!net->authenticated)
        {
-               printkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n");
+               dprintkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n");
                /* Error okay? */
                return -EPERM;
        }
-       
+
        /* Send the de-auth packet */
        if((ret = ieee80211softmac_send_mgt_frame(mac, net, IEEE80211_STYPE_DEAUTH, reason)))
                return ret;
-       
+
        ieee80211softmac_deauth_from_net(mac, net);
        return 0;
 }
+
 /*
  * This should be registered with ieee80211 as handle_deauth
  */
-int 
+int
 ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth)
 {
-       
+
        struct ieee80211softmac_network *net = NULL;
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-       
+
        if (unlikely(!mac->running))
                return -ENODEV;
 
@@ -374,9 +385,9 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
        }
 
        net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2);
-       
+
        if (net == NULL) {
-               printkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n",
+               dprintkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n",
                        MAC_ARG(deauth->header.addr2));
                return 0;
        }
@@ -384,7 +395,7 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
        /* Make sure the network is authenticated */
        if(!net->authenticated)
        {
-               printkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n");
+               dprintkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n");
                /* Error okay? */
                return -EPERM;
        }
@@ -392,6 +403,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
        ieee80211softmac_deauth_from_net(mac, net);
 
        /* let's try to re-associate */
-       schedule_work(&mac->associnfo.work);
+       schedule_delayed_work(&mac->associnfo.work, 0);
        return 0;
 }