aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c81
1 files changed, 46 insertions, 35 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c98be0593756..b5f1bba7ffe1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -668,9 +668,9 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
668 668
669static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, 669static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
670 struct tid_ampdu_rx *tid_agg_rx, 670 struct tid_ampdu_rx *tid_agg_rx,
671 int index) 671 int index,
672 struct sk_buff_head *frames)
672{ 673{
673 struct ieee80211_local *local = sdata->local;
674 struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; 674 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
675 struct ieee80211_rx_status *status; 675 struct ieee80211_rx_status *status;
676 676
@@ -684,7 +684,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
684 tid_agg_rx->reorder_buf[index] = NULL; 684 tid_agg_rx->reorder_buf[index] = NULL;
685 status = IEEE80211_SKB_RXCB(skb); 685 status = IEEE80211_SKB_RXCB(skb);
686 status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE; 686 status->rx_flags |= IEEE80211_RX_DEFERRED_RELEASE;
687 skb_queue_tail(&local->rx_skb_queue, skb); 687 __skb_queue_tail(frames, skb);
688 688
689no_frame: 689no_frame:
690 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 690 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
@@ -692,7 +692,8 @@ no_frame:
692 692
693static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, 693static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata,
694 struct tid_ampdu_rx *tid_agg_rx, 694 struct tid_ampdu_rx *tid_agg_rx,
695 u16 head_seq_num) 695 u16 head_seq_num,
696 struct sk_buff_head *frames)
696{ 697{
697 int index; 698 int index;
698 699
@@ -701,7 +702,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
701 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { 702 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
702 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 703 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
703 tid_agg_rx->buf_size; 704 tid_agg_rx->buf_size;
704 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); 705 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
706 frames);
705 } 707 }
706} 708}
707 709
@@ -717,7 +719,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
717#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) 719#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
718 720
719static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, 721static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
720 struct tid_ampdu_rx *tid_agg_rx) 722 struct tid_ampdu_rx *tid_agg_rx,
723 struct sk_buff_head *frames)
721{ 724{
722 int index, j; 725 int index, j;
723 726
@@ -746,7 +749,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
746 749
747 ht_dbg_ratelimited(sdata, 750 ht_dbg_ratelimited(sdata,
748 "release an RX reorder frame due to timeout on earlier frames\n"); 751 "release an RX reorder frame due to timeout on earlier frames\n");
749 ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); 752 ieee80211_release_reorder_frame(sdata, tid_agg_rx, j,
753 frames);
750 754
751 /* 755 /*
752 * Increment the head seq# also for the skipped slots. 756 * Increment the head seq# also for the skipped slots.
@@ -756,7 +760,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
756 skipped = 0; 760 skipped = 0;
757 } 761 }
758 } else while (tid_agg_rx->reorder_buf[index]) { 762 } else while (tid_agg_rx->reorder_buf[index]) {
759 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); 763 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
764 frames);
760 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 765 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
761 tid_agg_rx->buf_size; 766 tid_agg_rx->buf_size;
762 } 767 }
@@ -788,7 +793,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
788 */ 793 */
789static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, 794static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata,
790 struct tid_ampdu_rx *tid_agg_rx, 795 struct tid_ampdu_rx *tid_agg_rx,
791 struct sk_buff *skb) 796 struct sk_buff *skb,
797 struct sk_buff_head *frames)
792{ 798{
793 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 799 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
794 u16 sc = le16_to_cpu(hdr->seq_ctrl); 800 u16 sc = le16_to_cpu(hdr->seq_ctrl);
@@ -816,7 +822,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
816 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); 822 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size));
817 /* release stored frames up to new head to stack */ 823 /* release stored frames up to new head to stack */
818 ieee80211_release_reorder_frames(sdata, tid_agg_rx, 824 ieee80211_release_reorder_frames(sdata, tid_agg_rx,
819 head_seq_num); 825 head_seq_num, frames);
820 } 826 }
821 827
822 /* Now the new frame is always in the range of the reordering buffer */ 828 /* Now the new frame is always in the range of the reordering buffer */
@@ -846,7 +852,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
846 tid_agg_rx->reorder_buf[index] = skb; 852 tid_agg_rx->reorder_buf[index] = skb;
847 tid_agg_rx->reorder_time[index] = jiffies; 853 tid_agg_rx->reorder_time[index] = jiffies;
848 tid_agg_rx->stored_mpdu_num++; 854 tid_agg_rx->stored_mpdu_num++;
849 ieee80211_sta_reorder_release(sdata, tid_agg_rx); 855 ieee80211_sta_reorder_release(sdata, tid_agg_rx, frames);
850 856
851 out: 857 out:
852 spin_unlock(&tid_agg_rx->reorder_lock); 858 spin_unlock(&tid_agg_rx->reorder_lock);
@@ -857,7 +863,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
857 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns 863 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns
858 * true if the MPDU was buffered, false if it should be processed. 864 * true if the MPDU was buffered, false if it should be processed.
859 */ 865 */
860static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) 866static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
867 struct sk_buff_head *frames)
861{ 868{
862 struct sk_buff *skb = rx->skb; 869 struct sk_buff *skb = rx->skb;
863 struct ieee80211_local *local = rx->local; 870 struct ieee80211_local *local = rx->local;
@@ -922,11 +929,12 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
922 * sure that we cannot get to it any more before doing 929 * sure that we cannot get to it any more before doing
923 * anything with it. 930 * anything with it.
924 */ 931 */
925 if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) 932 if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb,
933 frames))
926 return; 934 return;
927 935
928 dont_reorder: 936 dont_reorder:
929 skb_queue_tail(&local->rx_skb_queue, skb); 937 __skb_queue_tail(frames, skb);
930} 938}
931 939
932static ieee80211_rx_result debug_noinline 940static ieee80211_rx_result debug_noinline
@@ -2184,7 +2192,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
2184} 2192}
2185 2193
2186static ieee80211_rx_result debug_noinline 2194static ieee80211_rx_result debug_noinline
2187ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) 2195ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
2188{ 2196{
2189 struct sk_buff *skb = rx->skb; 2197 struct sk_buff *skb = rx->skb;
2190 struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; 2198 struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
@@ -2223,7 +2231,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
2223 spin_lock(&tid_agg_rx->reorder_lock); 2231 spin_lock(&tid_agg_rx->reorder_lock);
2224 /* release stored frames up to start of BAR */ 2232 /* release stored frames up to start of BAR */
2225 ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, 2233 ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx,
2226 start_seq_num); 2234 start_seq_num, frames);
2227 spin_unlock(&tid_agg_rx->reorder_lock); 2235 spin_unlock(&tid_agg_rx->reorder_lock);
2228 2236
2229 kfree_skb(skb); 2237 kfree_skb(skb);
@@ -2808,7 +2816,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
2808 } 2816 }
2809} 2817}
2810 2818
2811static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx) 2819static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
2820 struct sk_buff_head *frames)
2812{ 2821{
2813 ieee80211_rx_result res = RX_DROP_MONITOR; 2822 ieee80211_rx_result res = RX_DROP_MONITOR;
2814 struct sk_buff *skb; 2823 struct sk_buff *skb;
@@ -2820,15 +2829,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2820 goto rxh_next; \ 2829 goto rxh_next; \
2821 } while (0); 2830 } while (0);
2822 2831
2823 spin_lock(&rx->local->rx_skb_queue.lock); 2832 spin_lock_bh(&rx->local->rx_path_lock);
2824 if (rx->local->running_rx_handler)
2825 goto unlock;
2826
2827 rx->local->running_rx_handler = true;
2828
2829 while ((skb = __skb_dequeue(&rx->local->rx_skb_queue))) {
2830 spin_unlock(&rx->local->rx_skb_queue.lock);
2831 2833
2834 while ((skb = __skb_dequeue(frames))) {
2832 /* 2835 /*
2833 * all the other fields are valid across frames 2836 * all the other fields are valid across frames
2834 * that belong to an aMPDU since they are on the 2837 * that belong to an aMPDU since they are on the
@@ -2849,7 +2852,12 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2849#endif 2852#endif
2850 CALL_RXH(ieee80211_rx_h_amsdu) 2853 CALL_RXH(ieee80211_rx_h_amsdu)
2851 CALL_RXH(ieee80211_rx_h_data) 2854 CALL_RXH(ieee80211_rx_h_data)
2852 CALL_RXH(ieee80211_rx_h_ctrl); 2855
2856 /* special treatment -- needs the queue */
2857 res = ieee80211_rx_h_ctrl(rx, frames);
2858 if (res != RX_CONTINUE)
2859 goto rxh_next;
2860
2853 CALL_RXH(ieee80211_rx_h_mgmt_check) 2861 CALL_RXH(ieee80211_rx_h_mgmt_check)
2854 CALL_RXH(ieee80211_rx_h_action) 2862 CALL_RXH(ieee80211_rx_h_action)
2855 CALL_RXH(ieee80211_rx_h_userspace_mgmt) 2863 CALL_RXH(ieee80211_rx_h_userspace_mgmt)
@@ -2858,20 +2866,20 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
2858 2866
2859 rxh_next: 2867 rxh_next:
2860 ieee80211_rx_handlers_result(rx, res); 2868 ieee80211_rx_handlers_result(rx, res);
2861 spin_lock(&rx->local->rx_skb_queue.lock); 2869
2862#undef CALL_RXH 2870#undef CALL_RXH
2863 } 2871 }
2864 2872
2865 rx->local->running_rx_handler = false; 2873 spin_unlock_bh(&rx->local->rx_path_lock);
2866
2867 unlock:
2868 spin_unlock(&rx->local->rx_skb_queue.lock);
2869} 2874}
2870 2875
2871static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) 2876static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2872{ 2877{
2878 struct sk_buff_head reorder_release;
2873 ieee80211_rx_result res = RX_DROP_MONITOR; 2879 ieee80211_rx_result res = RX_DROP_MONITOR;
2874 2880
2881 __skb_queue_head_init(&reorder_release);
2882
2875#define CALL_RXH(rxh) \ 2883#define CALL_RXH(rxh) \
2876 do { \ 2884 do { \
2877 res = rxh(rx); \ 2885 res = rxh(rx); \
@@ -2881,9 +2889,9 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2881 2889
2882 CALL_RXH(ieee80211_rx_h_check) 2890 CALL_RXH(ieee80211_rx_h_check)
2883 2891
2884 ieee80211_rx_reorder_ampdu(rx); 2892 ieee80211_rx_reorder_ampdu(rx, &reorder_release);
2885 2893
2886 ieee80211_rx_handlers(rx); 2894 ieee80211_rx_handlers(rx, &reorder_release);
2887 return; 2895 return;
2888 2896
2889 rxh_next: 2897 rxh_next:
@@ -2898,6 +2906,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2898 */ 2906 */
2899void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) 2907void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
2900{ 2908{
2909 struct sk_buff_head frames;
2901 struct ieee80211_rx_data rx = { 2910 struct ieee80211_rx_data rx = {
2902 .sta = sta, 2911 .sta = sta,
2903 .sdata = sta->sdata, 2912 .sdata = sta->sdata,
@@ -2913,11 +2922,13 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
2913 if (!tid_agg_rx) 2922 if (!tid_agg_rx)
2914 return; 2923 return;
2915 2924
2925 __skb_queue_head_init(&frames);
2926
2916 spin_lock(&tid_agg_rx->reorder_lock); 2927 spin_lock(&tid_agg_rx->reorder_lock);
2917 ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); 2928 ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx, &frames);
2918 spin_unlock(&tid_agg_rx->reorder_lock); 2929 spin_unlock(&tid_agg_rx->reorder_lock);
2919 2930
2920 ieee80211_rx_handlers(&rx); 2931 ieee80211_rx_handlers(&rx, &frames);
2921} 2932}
2922 2933
2923/* main receive path */ 2934/* main receive path */