aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/rx.c168
2 files changed, 96 insertions, 73 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ba5d3637b956..7d3178f1b443 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -164,6 +164,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
164#define IEEE80211_RX_RA_MATCH BIT(1) 164#define IEEE80211_RX_RA_MATCH BIT(1)
165#define IEEE80211_RX_AMSDU BIT(2) 165#define IEEE80211_RX_AMSDU BIT(2)
166#define IEEE80211_RX_FRAGMENTED BIT(3) 166#define IEEE80211_RX_FRAGMENTED BIT(3)
167/* only add flags here that do not change with subframes of an aMPDU */
167 168
168struct ieee80211_rx_data { 169struct ieee80211_rx_data {
169 struct sk_buff *skb; 170 struct sk_buff *skb;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d71a63e1fd6a..57b8a0a42776 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -27,10 +27,6 @@
27#include "tkip.h" 27#include "tkip.h"
28#include "wme.h" 28#include "wme.h"
29 29
30static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
31 struct sk_buff *skb,
32 struct ieee80211_rate *rate);
33
34/* 30/*
35 * monitor mode reception 31 * monitor mode reception
36 * 32 *
@@ -555,7 +551,8 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
555 551
556static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, 552static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
557 struct tid_ampdu_rx *tid_agg_rx, 553 struct tid_ampdu_rx *tid_agg_rx,
558 int index) 554 int index,
555 struct sk_buff_head *frames)
559{ 556{
560 struct ieee80211_supported_band *sband; 557 struct ieee80211_supported_band *sband;
561 struct ieee80211_rate *rate = NULL; 558 struct ieee80211_rate *rate = NULL;
@@ -571,9 +568,9 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
571 sband = hw->wiphy->bands[status->band]; 568 sband = hw->wiphy->bands[status->band];
572 if (!(status->flag & RX_FLAG_HT)) 569 if (!(status->flag & RX_FLAG_HT))
573 rate = &sband->bitrates[status->rate_idx]; 570 rate = &sband->bitrates[status->rate_idx];
574 __ieee80211_rx_handle_packet(hw, skb, rate);
575 tid_agg_rx->stored_mpdu_num--; 571 tid_agg_rx->stored_mpdu_num--;
576 tid_agg_rx->reorder_buf[index] = NULL; 572 tid_agg_rx->reorder_buf[index] = NULL;
573 skb_queue_tail(frames, skb);
577 574
578no_frame: 575no_frame:
579 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); 576 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
@@ -581,14 +578,15 @@ no_frame:
581 578
582static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, 579static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
583 struct tid_ampdu_rx *tid_agg_rx, 580 struct tid_ampdu_rx *tid_agg_rx,
584 u16 head_seq_num) 581 u16 head_seq_num,
582 struct sk_buff_head *frames)
585{ 583{
586 int index; 584 int index;
587 585
588 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { 586 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
589 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 587 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
590 tid_agg_rx->buf_size; 588 tid_agg_rx->buf_size;
591 ieee80211_release_reorder_frame(hw, tid_agg_rx, index); 589 ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
592 } 590 }
593} 591}
594 592
@@ -608,7 +606,8 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
608 */ 606 */
609static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, 607static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
610 struct tid_ampdu_rx *tid_agg_rx, 608 struct tid_ampdu_rx *tid_agg_rx,
611 struct sk_buff *skb) 609 struct sk_buff *skb,
610 struct sk_buff_head *frames)
612{ 611{
613 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 612 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
614 u16 sc = le16_to_cpu(hdr->seq_ctrl); 613 u16 sc = le16_to_cpu(hdr->seq_ctrl);
@@ -632,7 +631,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
632 if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { 631 if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) {
633 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); 632 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size));
634 /* release stored frames up to new head to stack */ 633 /* release stored frames up to new head to stack */
635 ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); 634 ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num,
635 frames);
636 } 636 }
637 637
638 /* Now the new frame is always in the range of the reordering buffer */ 638 /* Now the new frame is always in the range of the reordering buffer */
@@ -687,7 +687,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
687 "frames\n", 687 "frames\n",
688 wiphy_name(hw->wiphy)); 688 wiphy_name(hw->wiphy));
689#endif 689#endif
690 ieee80211_release_reorder_frame(hw, tid_agg_rx, j); 690 ieee80211_release_reorder_frame(hw, tid_agg_rx,
691 j, frames);
691 692
692 /* 693 /*
693 * Increment the head seq# also for the skipped slots. 694 * Increment the head seq# also for the skipped slots.
@@ -697,7 +698,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
697 skipped = 0; 698 skipped = 0;
698 } 699 }
699 } else while (tid_agg_rx->reorder_buf[index]) { 700 } else while (tid_agg_rx->reorder_buf[index]) {
700 ieee80211_release_reorder_frame(hw, tid_agg_rx, index); 701 ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames);
701 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % 702 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
702 tid_agg_rx->buf_size; 703 tid_agg_rx->buf_size;
703 } 704 }
@@ -709,38 +710,39 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
709 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns 710 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns
710 * true if the MPDU was buffered, false if it should be processed. 711 * true if the MPDU was buffered, false if it should be processed.
711 */ 712 */
712static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, 713static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
713 struct sk_buff *skb) 714 struct sk_buff_head *frames)
714{ 715{
716 struct sk_buff *skb = rx->skb;
717 struct ieee80211_local *local = rx->local;
715 struct ieee80211_hw *hw = &local->hw; 718 struct ieee80211_hw *hw = &local->hw;
716 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 719 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
717 struct sta_info *sta; 720 struct sta_info *sta = rx->sta;
718 struct tid_ampdu_rx *tid_agg_rx; 721 struct tid_ampdu_rx *tid_agg_rx;
719 u16 sc; 722 u16 sc;
720 int tid; 723 int tid;
721 724
722 if (!ieee80211_is_data_qos(hdr->frame_control)) 725 if (!ieee80211_is_data_qos(hdr->frame_control))
723 return false; 726 goto dont_reorder;
724 727
725 /* 728 /*
726 * filter the QoS data rx stream according to 729 * filter the QoS data rx stream according to
727 * STA/TID and check if this STA/TID is on aggregation 730 * STA/TID and check if this STA/TID is on aggregation
728 */ 731 */
729 732
730 sta = sta_info_get(local, hdr->addr2);
731 if (!sta) 733 if (!sta)
732 return false; 734 goto dont_reorder;
733 735
734 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 736 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
735 737
736 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 738 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
737 return false; 739 goto dont_reorder;
738 740
739 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; 741 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
740 742
741 /* qos null data frames are excluded */ 743 /* qos null data frames are excluded */
742 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 744 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
743 return false; 745 goto dont_reorder;
744 746
745 /* new, potentially un-ordered, ampdu frame - process it */ 747 /* new, potentially un-ordered, ampdu frame - process it */
746 748
@@ -755,10 +757,14 @@ static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
755 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 757 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
756 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 758 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
757 dev_kfree_skb(skb); 759 dev_kfree_skb(skb);
758 return true; 760 return;
759 } 761 }
760 762
761 return ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb); 763 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames))
764 return;
765
766 dont_reorder:
767 __skb_queue_tail(frames, skb);
762} 768}
763 769
764static ieee80211_rx_result debug_noinline 770static ieee80211_rx_result debug_noinline
@@ -863,6 +869,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
863 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 869 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
864 return RX_CONTINUE; 870 return RX_CONTINUE;
865 871
872 /* start without a key */
873 rx->key = NULL;
874
866 if (rx->sta) 875 if (rx->sta)
867 stakey = rcu_dereference(rx->sta->key); 876 stakey = rcu_dereference(rx->sta->key);
868 877
@@ -1815,7 +1824,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1815} 1824}
1816 1825
1817static ieee80211_rx_result debug_noinline 1826static ieee80211_rx_result debug_noinline
1818ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) 1827ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1819{ 1828{
1820 struct ieee80211_local *local = rx->local; 1829 struct ieee80211_local *local = rx->local;
1821 struct ieee80211_hw *hw = &local->hw; 1830 struct ieee80211_hw *hw = &local->hw;
@@ -1845,7 +1854,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1845 TU_TO_EXP_TIME(tid_agg_rx->timeout)); 1854 TU_TO_EXP_TIME(tid_agg_rx->timeout));
1846 1855
1847 /* release stored frames up to start of BAR */ 1856 /* release stored frames up to start of BAR */
1848 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); 1857 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
1858 frames);
1849 kfree_skb(skb); 1859 kfree_skb(skb);
1850 return RX_QUEUED; 1860 return RX_QUEUED;
1851 } 1861 }
@@ -2168,8 +2178,11 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
2168 struct sk_buff *skb, 2178 struct sk_buff *skb,
2169 struct ieee80211_rate *rate) 2179 struct ieee80211_rate *rate)
2170{ 2180{
2181 struct sk_buff_head reorder_release;
2171 ieee80211_rx_result res = RX_DROP_MONITOR; 2182 ieee80211_rx_result res = RX_DROP_MONITOR;
2172 2183
2184 __skb_queue_head_init(&reorder_release);
2185
2173 rx->skb = skb; 2186 rx->skb = skb;
2174 rx->sdata = sdata; 2187 rx->sdata = sdata;
2175 2188
@@ -2177,50 +2190,72 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
2177 do { \ 2190 do { \
2178 res = rxh(rx); \ 2191 res = rxh(rx); \
2179 if (res != RX_CONTINUE) \ 2192 if (res != RX_CONTINUE) \
2180 goto rxh_done; \ 2193 goto rxh_next; \
2181 } while (0); 2194 } while (0);
2182 2195
2196 /*
2197 * NB: the rxh_next label works even if we jump
2198 * to it from here because then the list will
2199 * be empty, which is a trivial check
2200 */
2183 CALL_RXH(ieee80211_rx_h_passive_scan) 2201 CALL_RXH(ieee80211_rx_h_passive_scan)
2184 CALL_RXH(ieee80211_rx_h_check) 2202 CALL_RXH(ieee80211_rx_h_check)
2185 CALL_RXH(ieee80211_rx_h_decrypt) 2203
2186 CALL_RXH(ieee80211_rx_h_check_more_data) 2204 ieee80211_rx_reorder_ampdu(rx, &reorder_release);
2187 CALL_RXH(ieee80211_rx_h_sta_process) 2205
2188 CALL_RXH(ieee80211_rx_h_defragment) 2206 while ((skb = __skb_dequeue(&reorder_release))) {
2189 CALL_RXH(ieee80211_rx_h_ps_poll) 2207 /*
2190 CALL_RXH(ieee80211_rx_h_michael_mic_verify) 2208 * all the other fields are valid across frames
2191 /* must be after MMIC verify so header is counted in MPDU mic */ 2209 * that belong to an aMPDU since they are on the
2192 CALL_RXH(ieee80211_rx_h_remove_qos_control) 2210 * same TID from the same station
2193 CALL_RXH(ieee80211_rx_h_amsdu) 2211 */
2212 rx->skb = skb;
2213
2214 CALL_RXH(ieee80211_rx_h_decrypt)
2215 CALL_RXH(ieee80211_rx_h_check_more_data)
2216 CALL_RXH(ieee80211_rx_h_sta_process)
2217 CALL_RXH(ieee80211_rx_h_defragment)
2218 CALL_RXH(ieee80211_rx_h_ps_poll)
2219 CALL_RXH(ieee80211_rx_h_michael_mic_verify)
2220 /* must be after MMIC verify so header is counted in MPDU mic */
2221 CALL_RXH(ieee80211_rx_h_remove_qos_control)
2222 CALL_RXH(ieee80211_rx_h_amsdu)
2194#ifdef CONFIG_MAC80211_MESH 2223#ifdef CONFIG_MAC80211_MESH
2195 if (ieee80211_vif_is_mesh(&sdata->vif)) 2224 if (ieee80211_vif_is_mesh(&sdata->vif))
2196 CALL_RXH(ieee80211_rx_h_mesh_fwding); 2225 CALL_RXH(ieee80211_rx_h_mesh_fwding);
2197#endif 2226#endif
2198 CALL_RXH(ieee80211_rx_h_data) 2227 CALL_RXH(ieee80211_rx_h_data)
2199 CALL_RXH(ieee80211_rx_h_ctrl) 2228
2200 CALL_RXH(ieee80211_rx_h_action) 2229 /* special treatment -- needs the queue */
2201 CALL_RXH(ieee80211_rx_h_mgmt) 2230 res = ieee80211_rx_h_ctrl(rx, &reorder_release);
2231 if (res != RX_CONTINUE)
2232 goto rxh_next;
2233
2234 CALL_RXH(ieee80211_rx_h_action)
2235 CALL_RXH(ieee80211_rx_h_mgmt)
2202 2236
2203#undef CALL_RXH 2237#undef CALL_RXH
2204 2238
2205 rxh_done: 2239 rxh_next:
2206 switch (res) { 2240 switch (res) {
2207 case RX_DROP_MONITOR: 2241 case RX_DROP_MONITOR:
2208 I802_DEBUG_INC(sdata->local->rx_handlers_drop); 2242 I802_DEBUG_INC(sdata->local->rx_handlers_drop);
2209 if (rx->sta) 2243 if (rx->sta)
2210 rx->sta->rx_dropped++; 2244 rx->sta->rx_dropped++;
2211 /* fall through */ 2245 /* fall through */
2212 case RX_CONTINUE: 2246 case RX_CONTINUE:
2213 ieee80211_rx_cooked_monitor(rx, rate); 2247 ieee80211_rx_cooked_monitor(rx, rate);
2214 break; 2248 break;
2215 case RX_DROP_UNUSABLE: 2249 case RX_DROP_UNUSABLE:
2216 I802_DEBUG_INC(sdata->local->rx_handlers_drop); 2250 I802_DEBUG_INC(sdata->local->rx_handlers_drop);
2217 if (rx->sta) 2251 if (rx->sta)
2218 rx->sta->rx_dropped++; 2252 rx->sta->rx_dropped++;
2219 dev_kfree_skb(rx->skb); 2253 dev_kfree_skb(rx->skb);
2220 break; 2254 break;
2221 case RX_QUEUED: 2255 case RX_QUEUED:
2222 I802_DEBUG_INC(sdata->local->rx_handlers_queued); 2256 I802_DEBUG_INC(sdata->local->rx_handlers_queued);
2223 break; 2257 break;
2258 }
2224 } 2259 }
2225} 2260}
2226 2261
@@ -2494,20 +2529,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2494 return; 2529 return;
2495 } 2530 }
2496 2531
2497 /* 2532 __ieee80211_rx_handle_packet(hw, skb, rate);
2498 * In theory, the block ack reordering should happen after duplicate
2499 * removal (ieee80211_rx_h_check(), which is an RX handler). As such,
2500 * the call to ieee80211_rx_reorder_ampdu() should really be moved to
2501 * happen as a new RX handler between ieee80211_rx_h_check and
2502 * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for
2503 * the time being, the call can be here since RX reorder buf processing
2504 * will implicitly skip duplicates. We could, in theory at least,
2505 * process frames that ieee80211_rx_h_passive_scan would drop (e.g.,
2506 * frames from other than operational channel), but that should not
2507 * happen in normal networks.
2508 */
2509 if (!ieee80211_rx_reorder_ampdu(local, skb))
2510 __ieee80211_rx_handle_packet(hw, skb, rate);
2511 2533
2512 rcu_read_unlock(); 2534 rcu_read_unlock();
2513 2535