diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 32 |
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 | ||
325 | static inline ieee80211_txrx_result | 325 | static ieee80211_txrx_result |
326 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) | 326 | ieee80211_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 | ||
354 | static inline ieee80211_txrx_result | 368 | static ieee80211_txrx_result |
355 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) | 369 | ieee80211_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; |