aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/rx.c459
1 files changed, 229 insertions, 230 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 097bb0343b91..d71a63e1fd6a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -27,9 +27,9 @@
27#include "tkip.h" 27#include "tkip.h"
28#include "wme.h" 28#include "wme.h"
29 29
30static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, 30static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
31 struct tid_ampdu_rx *tid_agg_rx, 31 struct sk_buff *skb,
32 u16 head_seq_num); 32 struct ieee80211_rate *rate);
33 33
34/* 34/*
35 * monitor mode reception 35 * monitor mode reception
@@ -534,6 +534,232 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
534 return RX_CONTINUE; 534 return RX_CONTINUE;
535} 535}
536 536
537#define SEQ_MODULO 0x1000
538#define SEQ_MASK 0xfff
539
540static inline int seq_less(u16 sq1, u16 sq2)
541{
542 return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
543}
544
545static inline u16 seq_inc(u16 sq)
546{
547 return (sq + 1) & SEQ_MASK;
548}
549
550static inline u16 seq_sub(u16 sq1, u16 sq2)
551{
552 return (sq1 - sq2) & SEQ_MASK;
553}
554
555
556static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
557 struct tid_ampdu_rx *tid_agg_rx,
558 int index)
559{
560 struct ieee80211_supported_band *sband;
561 struct ieee80211_rate *rate = NULL;
562 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
563 struct ieee80211_rx_status *status;
564
565 if (!skb)
566 goto no_frame;
567
568 status = IEEE80211_SKB_RXCB(skb);
569
570 /* release the reordered frames to stack */
571 sband = hw->wiphy->bands[status->band];
572 if (!(status->flag & RX_FLAG_HT))
573 rate = &sband->bitrates[status->rate_idx];
574 __ieee80211_rx_handle_packet(hw, skb, rate);
575 tid_agg_rx->stored_mpdu_num--;
576 tid_agg_rx->reorder_buf[index] = NULL;
577
578no_frame:
579 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
580}
581
582static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
583 struct tid_ampdu_rx *tid_agg_rx,
584 u16 head_seq_num)
585{
586 int index;
587
588 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) %
590 tid_agg_rx->buf_size;
591 ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
592 }
593}
594
595/*
596 * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
597 * the skb was added to the buffer longer than this time ago, the earlier
598 * frames that have not yet been received are assumed to be lost and the skb
599 * can be released for processing. This may also release other skb's from the
600 * reorder buffer if there are no additional gaps between the frames.
601 */
602#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
603
604/*
605 * As this function belongs to the RX path it must be under
606 * rcu_read_lock protection. It returns false if the frame
607 * can be processed immediately, true if it was consumed.
608 */
609static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
610 struct tid_ampdu_rx *tid_agg_rx,
611 struct sk_buff *skb)
612{
613 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
614 u16 sc = le16_to_cpu(hdr->seq_ctrl);
615 u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
616 u16 head_seq_num, buf_size;
617 int index;
618
619 buf_size = tid_agg_rx->buf_size;
620 head_seq_num = tid_agg_rx->head_seq_num;
621
622 /* frame with out of date sequence number */
623 if (seq_less(mpdu_seq_num, head_seq_num)) {
624 dev_kfree_skb(skb);
625 return true;
626 }
627
628 /*
629 * If frame the sequence number exceeds our buffering window
630 * size release some previous frames to make room for this one.
631 */
632 if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) {
633 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size));
634 /* release stored frames up to new head to stack */
635 ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num);
636 }
637
638 /* Now the new frame is always in the range of the reordering buffer */
639
640 index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size;
641
642 /* check if we already stored this frame */
643 if (tid_agg_rx->reorder_buf[index]) {
644 dev_kfree_skb(skb);
645 return true;
646 }
647
648 /*
649 * If the current MPDU is in the right order and nothing else
650 * is stored we can process it directly, no need to buffer it.
651 */
652 if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
653 tid_agg_rx->stored_mpdu_num == 0) {
654 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
655 return false;
656 }
657
658 /* put the frame in the reordering buffer */
659 tid_agg_rx->reorder_buf[index] = skb;
660 tid_agg_rx->reorder_time[index] = jiffies;
661 tid_agg_rx->stored_mpdu_num++;
662 /* release the buffer until next missing frame */
663 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
664 tid_agg_rx->buf_size;
665 if (!tid_agg_rx->reorder_buf[index] &&
666 tid_agg_rx->stored_mpdu_num > 1) {
667 /*
668 * No buffers ready to be released, but check whether any
669 * frames in the reorder buffer have timed out.
670 */
671 int j;
672 int skipped = 1;
673 for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
674 j = (j + 1) % tid_agg_rx->buf_size) {
675 if (!tid_agg_rx->reorder_buf[j]) {
676 skipped++;
677 continue;
678 }
679 if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
680 HT_RX_REORDER_BUF_TIMEOUT))
681 break;
682
683#ifdef CONFIG_MAC80211_HT_DEBUG
684 if (net_ratelimit())
685 printk(KERN_DEBUG "%s: release an RX reorder "
686 "frame due to timeout on earlier "
687 "frames\n",
688 wiphy_name(hw->wiphy));
689#endif
690 ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
691
692 /*
693 * Increment the head seq# also for the skipped slots.
694 */
695 tid_agg_rx->head_seq_num =
696 (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
697 skipped = 0;
698 }
699 } else while (tid_agg_rx->reorder_buf[index]) {
700 ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
701 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
702 tid_agg_rx->buf_size;
703 }
704
705 return true;
706}
707
708/*
709 * 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 */
712static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
713 struct sk_buff *skb)
714{
715 struct ieee80211_hw *hw = &local->hw;
716 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
717 struct sta_info *sta;
718 struct tid_ampdu_rx *tid_agg_rx;
719 u16 sc;
720 int tid;
721
722 if (!ieee80211_is_data_qos(hdr->frame_control))
723 return false;
724
725 /*
726 * filter the QoS data rx stream according to
727 * STA/TID and check if this STA/TID is on aggregation
728 */
729
730 sta = sta_info_get(local, hdr->addr2);
731 if (!sta)
732 return false;
733
734 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
735
736 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
737 return false;
738
739 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
740
741 /* qos null data frames are excluded */
742 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
743 return false;
744
745 /* new, potentially un-ordered, ampdu frame - process it */
746
747 /* reset session timer */
748 if (tid_agg_rx->timeout)
749 mod_timer(&tid_agg_rx->session_timer,
750 TU_TO_EXP_TIME(tid_agg_rx->timeout));
751
752 /* if this mpdu is fragmented - terminate rx aggregation session */
753 sc = le16_to_cpu(hdr->seq_ctrl);
754 if (sc & IEEE80211_SCTL_FRAG) {
755 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
756 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
757 dev_kfree_skb(skb);
758 return true;
759 }
760
761 return ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb);
762}
537 763
538static ieee80211_rx_result debug_noinline 764static ieee80211_rx_result debug_noinline
539ieee80211_rx_h_check(struct ieee80211_rx_data *rx) 765ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
@@ -2187,233 +2413,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2187 dev_kfree_skb(skb); 2413 dev_kfree_skb(skb);
2188} 2414}
2189 2415
2190#define SEQ_MODULO 0x1000
2191#define SEQ_MASK 0xfff
2192
2193static inline int seq_less(u16 sq1, u16 sq2)
2194{
2195 return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
2196}
2197
2198static inline u16 seq_inc(u16 sq)
2199{
2200 return (sq + 1) & SEQ_MASK;
2201}
2202
2203static inline u16 seq_sub(u16 sq1, u16 sq2)
2204{
2205 return (sq1 - sq2) & SEQ_MASK;
2206}
2207
2208
2209static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
2210 struct tid_ampdu_rx *tid_agg_rx,
2211 int index)
2212{
2213 struct ieee80211_supported_band *sband;
2214 struct ieee80211_rate *rate = NULL;
2215 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
2216 struct ieee80211_rx_status *status;
2217
2218 if (!skb)
2219 goto no_frame;
2220
2221 status = IEEE80211_SKB_RXCB(skb);
2222
2223 /* release the reordered frames to stack */
2224 sband = hw->wiphy->bands[status->band];
2225 if (!(status->flag & RX_FLAG_HT))
2226 rate = &sband->bitrates[status->rate_idx];
2227 __ieee80211_rx_handle_packet(hw, skb, rate);
2228 tid_agg_rx->stored_mpdu_num--;
2229 tid_agg_rx->reorder_buf[index] = NULL;
2230
2231no_frame:
2232 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
2233}
2234
2235static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw,
2236 struct tid_ampdu_rx *tid_agg_rx,
2237 u16 head_seq_num)
2238{
2239 int index;
2240
2241 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
2242 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
2243 tid_agg_rx->buf_size;
2244 ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
2245 }
2246}
2247
2248/*
2249 * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
2250 * the skb was added to the buffer longer than this time ago, the earlier
2251 * frames that have not yet been received are assumed to be lost and the skb
2252 * can be released for processing. This may also release other skb's from the
2253 * reorder buffer if there are no additional gaps between the frames.
2254 */
2255#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
2256
2257/*
2258 * As this function belongs to the RX path it must be under
2259 * rcu_read_lock protection. It returns false if the frame
2260 * can be processed immediately, true if it was consumed.
2261 */
2262static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
2263 struct tid_ampdu_rx *tid_agg_rx,
2264 struct sk_buff *skb)
2265{
2266 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2267 u16 sc = le16_to_cpu(hdr->seq_ctrl);
2268 u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
2269 u16 head_seq_num, buf_size;
2270 int index;
2271
2272 buf_size = tid_agg_rx->buf_size;
2273 head_seq_num = tid_agg_rx->head_seq_num;
2274
2275 /* frame with out of date sequence number */
2276 if (seq_less(mpdu_seq_num, head_seq_num)) {
2277 dev_kfree_skb(skb);
2278 return true;
2279 }
2280
2281 /*
2282 * If frame the sequence number exceeds our buffering window
2283 * size release some previous frames to make room for this one.
2284 */
2285 if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) {
2286 head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size));
2287 /* release stored frames up to new head to stack */
2288 ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num);
2289 }
2290
2291 /* Now the new frame is always in the range of the reordering buffer */
2292
2293 index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size;
2294
2295 /* check if we already stored this frame */
2296 if (tid_agg_rx->reorder_buf[index]) {
2297 dev_kfree_skb(skb);
2298 return true;
2299 }
2300
2301 /*
2302 * If the current MPDU is in the right order and nothing else
2303 * is stored we can process it directly, no need to buffer it.
2304 */
2305 if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
2306 tid_agg_rx->stored_mpdu_num == 0) {
2307 tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
2308 return false;
2309 }
2310
2311 /* put the frame in the reordering buffer */
2312 tid_agg_rx->reorder_buf[index] = skb;
2313 tid_agg_rx->reorder_time[index] = jiffies;
2314 tid_agg_rx->stored_mpdu_num++;
2315 /* release the buffer until next missing frame */
2316 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
2317 tid_agg_rx->buf_size;
2318 if (!tid_agg_rx->reorder_buf[index] &&
2319 tid_agg_rx->stored_mpdu_num > 1) {
2320 /*
2321 * No buffers ready to be released, but check whether any
2322 * frames in the reorder buffer have timed out.
2323 */
2324 int j;
2325 int skipped = 1;
2326 for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
2327 j = (j + 1) % tid_agg_rx->buf_size) {
2328 if (!tid_agg_rx->reorder_buf[j]) {
2329 skipped++;
2330 continue;
2331 }
2332 if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
2333 HT_RX_REORDER_BUF_TIMEOUT))
2334 break;
2335
2336#ifdef CONFIG_MAC80211_HT_DEBUG
2337 if (net_ratelimit())
2338 printk(KERN_DEBUG "%s: release an RX reorder "
2339 "frame due to timeout on earlier "
2340 "frames\n",
2341 wiphy_name(hw->wiphy));
2342#endif
2343 ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
2344
2345 /*
2346 * Increment the head seq# also for the skipped slots.
2347 */
2348 tid_agg_rx->head_seq_num =
2349 (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK;
2350 skipped = 0;
2351 }
2352 } else while (tid_agg_rx->reorder_buf[index]) {
2353 ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
2354 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %
2355 tid_agg_rx->buf_size;
2356 }
2357
2358 return true;
2359}
2360
2361/*
2362 * Reorder MPDUs from A-MPDUs, keeping them on a buffer. Returns
2363 * true if the MPDU was buffered, false if it should be processed.
2364 */
2365static bool ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2366 struct sk_buff *skb)
2367{
2368 struct ieee80211_hw *hw = &local->hw;
2369 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2370 struct sta_info *sta;
2371 struct tid_ampdu_rx *tid_agg_rx;
2372 u16 sc;
2373 int tid;
2374
2375 if (!ieee80211_is_data_qos(hdr->frame_control))
2376 return false;
2377
2378 /*
2379 * filter the QoS data rx stream according to
2380 * STA/TID and check if this STA/TID is on aggregation
2381 */
2382
2383 sta = sta_info_get(local, hdr->addr2);
2384 if (!sta)
2385 return false;
2386
2387 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
2388
2389 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
2390 return false;
2391
2392 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
2393
2394 /* qos null data frames are excluded */
2395 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
2396 return false;
2397
2398 /* new, potentially un-ordered, ampdu frame - process it */
2399
2400 /* reset session timer */
2401 if (tid_agg_rx->timeout)
2402 mod_timer(&tid_agg_rx->session_timer,
2403 TU_TO_EXP_TIME(tid_agg_rx->timeout));
2404
2405 /* if this mpdu is fragmented - terminate rx aggregation session */
2406 sc = le16_to_cpu(hdr->seq_ctrl);
2407 if (sc & IEEE80211_SCTL_FRAG) {
2408 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
2409 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
2410 dev_kfree_skb(skb);
2411 return true;
2412 }
2413
2414 return ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb);
2415}
2416
2417/* 2416/*
2418 * This is the receive path handler. It is called by a low level driver when an 2417 * This is the receive path handler. It is called by a low level driver when an
2419 * 802.11 MPDU is received from the hardware. 2418 * 802.11 MPDU is received from the hardware.