diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-09-29 10:04:28 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-30 15:57:11 -0400 |
commit | 60750397122fe0fb81a6e52fd790b3f749b6e010 (patch) | |
tree | 3efa9772e7428d800fd2d236c558ca37c0ef7bb4 /net/mac80211/sta_info.c | |
parent | c868cb35d013896ab6a80a554fb88baef06cedcd (diff) |
mac80211: also expire filtered frames
mac80211 will expire normal PS-buffered frames, but
if the device rejected some frames for a sleeping
station, these won't be on the ps_tx_buf queue but
on the tx_filtered queue instead; this is done to
avoid reordering.
However, mac80211 will not expire frames from the
filtered queue, let's fix that.
Also add a more comments to what all this expiry is
doing and how it works.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 863d59fe6886..8dabe66fc37f 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -709,6 +709,39 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
709 | if (!sta->sdata->bss) | 709 | if (!sta->sdata->bss) |
710 | return false; | 710 | return false; |
711 | 711 | ||
712 | /* | ||
713 | * First check for frames that should expire on the filtered | ||
714 | * queue. Frames here were rejected by the driver and are on | ||
715 | * a separate queue to avoid reordering with normal PS-buffered | ||
716 | * frames. They also aren't accounted for right now in the | ||
717 | * total_ps_buffered counter. | ||
718 | */ | ||
719 | for (;;) { | ||
720 | spin_lock_irqsave(&sta->tx_filtered.lock, flags); | ||
721 | skb = skb_peek(&sta->tx_filtered); | ||
722 | if (sta_info_buffer_expired(sta, skb)) | ||
723 | skb = __skb_dequeue(&sta->tx_filtered); | ||
724 | else | ||
725 | skb = NULL; | ||
726 | spin_unlock_irqrestore(&sta->tx_filtered.lock, flags); | ||
727 | |||
728 | /* | ||
729 | * Frames are queued in order, so if this one | ||
730 | * hasn't expired yet we can stop testing. If | ||
731 | * we actually reached the end of the queue we | ||
732 | * also need to stop, of course. | ||
733 | */ | ||
734 | if (!skb) | ||
735 | break; | ||
736 | dev_kfree_skb(skb); | ||
737 | } | ||
738 | |||
739 | /* | ||
740 | * Now also check the normal PS-buffered queue, this will | ||
741 | * only find something if the filtered queue was emptied | ||
742 | * since the filtered frames are all before the normal PS | ||
743 | * buffered frames. | ||
744 | */ | ||
712 | for (;;) { | 745 | for (;;) { |
713 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); | 746 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); |
714 | skb = skb_peek(&sta->ps_tx_buf); | 747 | skb = skb_peek(&sta->ps_tx_buf); |
@@ -718,6 +751,11 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
718 | skb = NULL; | 751 | skb = NULL; |
719 | spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); | 752 | spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); |
720 | 753 | ||
754 | /* | ||
755 | * frames are queued in order, so if this one | ||
756 | * hasn't expired yet (or we reached the end of | ||
757 | * the queue) we can stop testing | ||
758 | */ | ||
721 | if (!skb) | 759 | if (!skb) |
722 | break; | 760 | break; |
723 | 761 | ||
@@ -727,13 +765,22 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
727 | sta->sta.addr); | 765 | sta->sta.addr); |
728 | #endif | 766 | #endif |
729 | dev_kfree_skb(skb); | 767 | dev_kfree_skb(skb); |
730 | |||
731 | /* if the queue is now empty recalc TIM bit */ | ||
732 | if (skb_queue_empty(&sta->ps_tx_buf)) | ||
733 | sta_info_recalc_tim(sta); | ||
734 | } | 768 | } |
735 | 769 | ||
736 | return !skb_queue_empty(&sta->ps_tx_buf); | 770 | /* |
771 | * Finally, recalculate the TIM bit for this station -- it might | ||
772 | * now be clear because the station was too slow to retrieve its | ||
773 | * frames. | ||
774 | */ | ||
775 | sta_info_recalc_tim(sta); | ||
776 | |||
777 | /* | ||
778 | * Return whether there are any frames still buffered, this is | ||
779 | * used to check whether the cleanup timer still needs to run, | ||
780 | * if there are no frames we don't need to rearm the timer. | ||
781 | */ | ||
782 | return !(skb_queue_empty(&sta->ps_tx_buf) && | ||
783 | skb_queue_empty(&sta->tx_filtered)); | ||
737 | } | 784 | } |
738 | 785 | ||
739 | static int __must_check __sta_info_destroy(struct sta_info *sta) | 786 | static int __must_check __sta_info_destroy(struct sta_info *sta) |