aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/tx.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e177a8dc23b9..f7aff2e97eea 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -322,16 +322,27 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
322 wiphy_name(local->hw.wiphy), purged); 322 wiphy_name(local->hw.wiphy), purged);
323} 323}
324 324
325static inline ieee80211_txrx_result 325static ieee80211_txrx_result
326ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) 326ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx)
327{ 327{
328 /* broadcast/multicast frame */ 328 /*
329 /* If any of the associated stations is in power save mode, 329 * broadcast/multicast frame
330 * the frame is buffered to be sent after DTIM beacon frame */ 330 *
331 if ((tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) && 331 * If any of the associated stations is in power save mode,
332 tx->sdata->type != IEEE80211_IF_TYPE_WDS && 332 * the frame is buffered to be sent after DTIM beacon frame.
333 tx->sdata->bss && atomic_read(&tx->sdata->bss->num_sta_ps) && 333 * This is done either by the hardware or us.
334 !(tx->fc & IEEE80211_FCTL_ORDER)) { 334 */
335
336 /* not AP/IBSS or ordered frame */
337 if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER))
338 return TXRX_CONTINUE;
339
340 /* no stations in PS mode */
341 if (!atomic_read(&tx->sdata->bss->num_sta_ps))
342 return TXRX_CONTINUE;
343
344 /* buffered in mac80211 */
345 if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) {
335 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) 346 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
336 purge_old_ps_buffers(tx->local); 347 purge_old_ps_buffers(tx->local);
337 if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= 348 if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >=
@@ -348,10 +359,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx)
348 return TXRX_QUEUED; 359 return TXRX_QUEUED;
349 } 360 }
350 361
362 /* buffered in hardware */
363 tx->u.tx.control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM;
364
351 return TXRX_CONTINUE; 365 return TXRX_CONTINUE;
352} 366}
353 367
354static inline ieee80211_txrx_result 368static ieee80211_txrx_result
355ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) 369ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
356{ 370{
357 struct sta_info *sta = tx->sta; 371 struct sta_info *sta = tx->sta;