netfilter: xt_recent: inform user when hitcount is too large
[safe/jmp/linux-2.6] / net / mac80211 / work.c
index 5ba7599..7e708d5 100644 (file)
@@ -202,7 +202,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
-       u8 *pos;
+       u8 *pos, qos_info;
        const u8 *ies;
        size_t offset = 0, noffset;
        int i, len, count, rates_len, supp_rates_len;
@@ -375,6 +375,14 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
        }
 
        if (wk->assoc.wmm_used && local->hw.queues >= 4) {
+               if (wk->assoc.uapsd_used) {
+                       qos_info = local->uapsd_queues;
+                       qos_info |= (local->uapsd_max_sp_len <<
+                                    IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
+               } else {
+                       qos_info = 0;
+               }
+
                pos = skb_put(skb, 9);
                *pos++ = WLAN_EID_VENDOR_SPECIFIC;
                *pos++ = 7; /* len */
@@ -384,7 +392,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
                *pos++ = 2; /* WME */
                *pos++ = 0; /* WME info */
                *pos++ = 1; /* WME ver */
-               *pos++ = 0;
+               *pos++ = qos_info;
        }
 
        /* add any remaining custom (i.e. vendor specific here) IEs */
@@ -527,8 +535,7 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
         * First time we run, do nothing -- the generic code will
         * have switched to the right channel etc.
         */
-       if (!wk->remain.started) {
-               wk->remain.started = true;
+       if (!wk->started) {
                wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
 
                cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk,
@@ -813,14 +820,17 @@ static void ieee80211_work_work(struct work_struct *work)
        mutex_lock(&local->work_mtx);
 
        list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
+               bool started = wk->started;
+
                /* mark work as started if it's on the current off-channel */
-               if (!wk->started && local->tmp_channel &&
+               if (!started && local->tmp_channel &&
                    wk->chan == local->tmp_channel &&
                    wk->chan_type == local->tmp_channel_type) {
-                       wk->started = true;
+                       started = true;
+                       wk->timeout = jiffies;
                }
 
-               if (!wk->started && !local->tmp_channel) {
+               if (!started && !local->tmp_channel) {
                        /*
                         * TODO: could optimize this by leaving the
                         *       station vifs in awake mode if they
@@ -833,12 +843,12 @@ static void ieee80211_work_work(struct work_struct *work)
                        local->tmp_channel = wk->chan;
                        local->tmp_channel_type = wk->chan_type;
                        ieee80211_hw_config(local, 0);
-                       wk->started = true;
+                       started = true;
                        wk->timeout = jiffies;
                }
 
                /* don't try to work with items that aren't started */
-               if (!wk->started)
+               if (!started)
                        continue;
 
                if (time_is_after_jiffies(wk->timeout)) {
@@ -873,6 +883,8 @@ static void ieee80211_work_work(struct work_struct *work)
                        break;
                }
 
+               wk->started = started;
+
                switch (rma) {
                case WORK_ACT_NONE:
                        /* might have changed the timeout */
@@ -935,6 +947,9 @@ void ieee80211_add_work(struct ieee80211_work *wk)
        if (WARN_ON(!wk->done))
                return;
 
+       if (WARN_ON(!ieee80211_sdata_running(wk->sdata)))
+               return;
+
        wk->started = false;
 
        local = wk->sdata->local;
@@ -1010,8 +1025,6 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
                case IEEE80211_STYPE_PROBE_RESP:
                case IEEE80211_STYPE_ASSOC_RESP:
                case IEEE80211_STYPE_REASSOC_RESP:
-               case IEEE80211_STYPE_DEAUTH:
-               case IEEE80211_STYPE_DISASSOC:
                        skb_queue_tail(&local->work_skb_queue, skb);
                        ieee80211_queue_work(&local->hw, &local->work_work);
                        return RX_QUEUED;