* set_retry_limit configured
                                                  * long retry value */
 #define IEEE80211_TXCTL_EAPOL_FRAME    (1<<11) /* internal to mac80211 */
+#define IEEE80211_TXCTL_SEND_AFTER_DTIM        (1<<12) /* send this frame after DTIM
+                                                * beacon */
        u32 flags;                             /* tx control flags defined
                                                * above */
        u8 key_idx;             /* keyidx from hw->set_key(), undefined if
 
               wiphy_name(local->hw.wiphy), purged);
 }
 
-static inline ieee80211_txrx_result
+static ieee80211_txrx_result
 ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx)
 {
-       /* broadcast/multicast frame */
-       /* If any of the associated stations is in power save mode,
-        * the frame is buffered to be sent after DTIM beacon frame */
-       if ((tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) &&
-           tx->sdata->type != IEEE80211_IF_TYPE_WDS &&
-           tx->sdata->bss && atomic_read(&tx->sdata->bss->num_sta_ps) &&
-           !(tx->fc & IEEE80211_FCTL_ORDER)) {
+       /*
+        * broadcast/multicast frame
+        *
+        * If any of the associated stations is in power save mode,
+        * the frame is buffered to be sent after DTIM beacon frame.
+        * This is done either by the hardware or us.
+        */
+
+       /* not AP/IBSS or ordered frame */
+       if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER))
+               return TXRX_CONTINUE;
+
+       /* no stations in PS mode */
+       if (!atomic_read(&tx->sdata->bss->num_sta_ps))
+               return TXRX_CONTINUE;
+
+       /* buffered in mac80211 */
+       if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) {
                if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
                        purge_old_ps_buffers(tx->local);
                if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >=
                return TXRX_QUEUED;
        }
 
+       /* buffered in hardware */
+       tx->u.tx.control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM;
+
        return TXRX_CONTINUE;
 }
 
-static inline ieee80211_txrx_result
+static ieee80211_txrx_result
 ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
 {
        struct sta_info *sta = tx->sta;