mac80211: fix scan abort sanity checks
[safe/jmp/linux-2.6] / net / mac80211 / mlme.c
index c374d2d..dcc14e9 100644 (file)
@@ -458,9 +458,15 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
        mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
        if (stype == IEEE80211_STYPE_DEAUTH)
-               cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie);
+               if (cookie)
+                       __cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
+               else
+                       cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
        else
-               cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie);
+               if (cookie)
+                       __cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
+               else
+                       cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
        ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
 }
 
@@ -923,7 +929,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        ieee80211_recalc_ps(local, -1);
        mutex_unlock(&local->iflist_mtx);
 
-       netif_tx_start_all_queues(sdata->dev);
+       netif_start_queue(sdata->dev);
        netif_carrier_on(sdata->dev);
 }
 
@@ -1055,7 +1061,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
         * time -- we don't want the scan code to enable queues.
         */
 
-       netif_tx_stop_all_queues(sdata->dev);
+       netif_stop_queue(sdata->dev);
        netif_carrier_off(sdata->dev);
 
        rcu_read_lock();
@@ -1388,8 +1394,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
 
        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 
-       printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
-                       sdata->dev->name, reason_code);
+       printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
+                       sdata->dev->name, mgmt->sa, reason_code);
 
        ieee80211_set_disassoc(sdata, false);
        return RX_MGMT_CFG80211_DISASSOC;
@@ -1457,8 +1463,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        if (status_code != WLAN_STATUS_SUCCESS) {
                printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
                       sdata->dev->name, status_code);
-               list_del(&wk->list);
-               kfree(wk);
+               wk->state = IEEE80211_MGD_STATE_IDLE;
                return RX_MGMT_CFG80211_ASSOC;
        }
 
@@ -1675,7 +1680,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 
        /* direct probe may be part of the association flow */
        if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) {
-               printk(KERN_DEBUG "%s direct probe responded\n",
+               printk(KERN_DEBUG "%s: direct probe responded\n",
                       sdata->dev->name);
                wk->tries = 0;
                wk->state = IEEE80211_MGD_STATE_AUTH;
@@ -1959,12 +1964,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                        /* no action */
                        break;
                case RX_MGMT_CFG80211_DEAUTH:
-                       cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len,
-                                            NULL);
+                       cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
                        break;
                case RX_MGMT_CFG80211_DISASSOC:
-                       cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len,
-                                              NULL);
+                       cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
                        break;
                default:
                        WARN(1, "unexpected: %d", rma);
@@ -2019,7 +2022,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
                break;
        case RX_MGMT_CFG80211_DEAUTH:
-               cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, NULL);
+               cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
                break;
        default:
                WARN(1, "unexpected: %d", rma);
@@ -2123,25 +2126,9 @@ static void ieee80211_sta_work(struct work_struct *work)
                }
        }
 
-       list_for_each_entry(wk, &ifmgd->work_list, list) {
-               if (wk->state != IEEE80211_MGD_STATE_IDLE) {
-                       anybusy = true;
-                       break;
-               }
-       }
 
        ieee80211_recalc_idle(local);
 
-       if (!anybusy) {
-               mutex_unlock(&ifmgd->mtx);
-
-               if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
-                       ieee80211_queue_delayed_work(&local->hw,
-                                                    &local->scan_work,
-                                                    round_jiffies_relative(0));
-               return;
-       }
-
        list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
                if (time_is_after_jiffies(wk->timeout)) {
                        /*
@@ -2187,6 +2174,18 @@ static void ieee80211_sta_work(struct work_struct *work)
                }
        }
 
+       list_for_each_entry(wk, &ifmgd->work_list, list) {
+               if (wk->state != IEEE80211_MGD_STATE_IDLE) {
+                       anybusy = true;
+                       break;
+               }
+       }
+       if (!anybusy &&
+           test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
+               ieee80211_queue_delayed_work(&local->hw,
+                                            &local->scan_work,
+                                            round_jiffies_relative(0));
+
        mutex_unlock(&ifmgd->mtx);
 
        list_for_each_entry_safe(wk, tmp, &free_work, list) {
@@ -2506,9 +2505,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_mgd_work *wk;
        const u8 *bssid = NULL;
 
-       printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
-              sdata->dev->name, req->reason_code);
-
        mutex_lock(&ifmgd->mtx);
 
        if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
@@ -2536,6 +2532,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 
        mutex_unlock(&ifmgd->mtx);
 
+       printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
+              sdata->dev->name, bssid, req->reason_code);
+
        ieee80211_send_deauth_disassoc(sdata, bssid,
                        IEEE80211_STYPE_DEAUTH, req->reason_code,
                        cookie);
@@ -2549,9 +2548,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-       printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
-              sdata->dev->name, req->reason_code);
-
        mutex_lock(&ifmgd->mtx);
 
        /*
@@ -2565,6 +2561,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
                return -ENOLINK;
        }
 
+       printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
+              sdata->dev->name, req->bss->bssid, req->reason_code);
+
        ieee80211_set_disassoc(sdata, false);
 
        mutex_unlock(&ifmgd->mtx);