diff options
-rw-r--r-- | include/net/mac80211.h | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 32 |
2 files changed, 25 insertions, 9 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2606ca282c5e..5b9e7a262448 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -308,6 +308,8 @@ struct ieee80211_tx_control { | |||
308 | * set_retry_limit configured | 308 | * set_retry_limit configured |
309 | * long retry value */ | 309 | * long retry value */ |
310 | #define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */ | 310 | #define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */ |
311 | #define IEEE80211_TXCTL_SEND_AFTER_DTIM (1<<12) /* send this frame after DTIM | ||
312 | * beacon */ | ||
311 | u32 flags; /* tx control flags defined | 313 | u32 flags; /* tx control flags defined |
312 | * above */ | 314 | * above */ |
313 | u8 key_idx; /* keyidx from hw->set_key(), undefined if | 315 | u8 key_idx; /* keyidx from hw->set_key(), undefined if |
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; |