struct sk_buff *skb);
 int ieee80211_add_pending_skbs(struct ieee80211_local *local,
                               struct sk_buff_head *skbs);
+int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+                                 struct sk_buff_head *skbs,
+                                 void (*fn)(void *data), void *data);
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         u16 transaction, u16 auth_alg,
 
 
        atomic_dec(&sdata->bss->num_sta_ps);
 
-       clear_sta_flags(sta, WLAN_STA_PS_STA);
-
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
               sdata->name, sta->sta.addr, sta->sta.aid);
 
 
        if (!test_sta_flags(sta, WLAN_STA_PS_STA))
                ieee80211_sta_ps_deliver_wakeup(sta);
-       else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL))
+       else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
+               clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
                ieee80211_sta_ps_deliver_poll_response(sta);
+       } else
+               clear_sta_flags(sta, WLAN_STA_PS_DRIVER);
 }
 
 static int sta_prepare_rate_control(struct ieee80211_local *local,
 }
 EXPORT_SYMBOL(ieee80211_find_sta);
 
+static void clear_sta_ps_flags(void *_sta)
+{
+       struct sta_info *sta = _sta;
+
+       clear_sta_flags(sta, WLAN_STA_PS_DRIVER | WLAN_STA_PS_STA);
+}
+
 /* powersave support code */
 void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 {
 
        /* Send all buffered frames to the station */
        sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
-       buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
+       buffered = ieee80211_add_pending_skbs_fn(local, &sta->ps_tx_buf,
+                                                clear_sta_ps_flags, sta);
        sent += buffered;
        local->total_ps_buffered -= buffered;
 
 
        if (block)
                set_sta_flags(sta, WLAN_STA_PS_DRIVER);
-       else
+       else if (test_sta_flags(sta, WLAN_STA_PS_DRIVER))
                ieee80211_queue_work(hw, &sta->drv_unblock_wk);
 }
 EXPORT_SYMBOL(ieee80211_sta_block_awake);
 
        spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 }
 
-int ieee80211_add_pending_skbs(struct ieee80211_local *local,
-                              struct sk_buff_head *skbs)
+int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+                                 struct sk_buff_head *skbs,
+                                 void (*fn)(void *data), void *data)
 {
        struct ieee80211_hw *hw = &local->hw;
        struct sk_buff *skb;
                __skb_queue_tail(&local->pending[queue], skb);
        }
 
+       if (fn)
+               fn(data);
+
        for (i = 0; i < hw->queues; i++)
                __ieee80211_wake_queue(hw, i,
                        IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
        return ret;
 }
 
+int ieee80211_add_pending_skbs(struct ieee80211_local *local,
+                              struct sk_buff_head *skbs)
+{
+       return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
+}
+
 void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
                                    enum queue_stop_reason reason)
 {