diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 130 |
1 files changed, 41 insertions, 89 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 965e6ec0adb6..0cb4edee6af5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -94,7 +94,7 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, | |||
94 | return len; | 94 | return len; |
95 | } | 95 | } |
96 | 96 | ||
97 | /* | 97 | /** |
98 | * ieee80211_add_rx_radiotap_header - add radiotap header | 98 | * ieee80211_add_rx_radiotap_header - add radiotap header |
99 | * | 99 | * |
100 | * add a radiotap header containing all the fields which the hardware provided. | 100 | * add a radiotap header containing all the fields which the hardware provided. |
@@ -413,29 +413,6 @@ static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) | |||
413 | 413 | ||
414 | /* rx handlers */ | 414 | /* rx handlers */ |
415 | 415 | ||
416 | static ieee80211_rx_result debug_noinline | ||
417 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | ||
418 | { | ||
419 | struct ieee80211_local *local = rx->local; | ||
420 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
421 | struct sk_buff *skb = rx->skb; | ||
422 | |||
423 | if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | ||
424 | !local->sched_scanning)) | ||
425 | return RX_CONTINUE; | ||
426 | |||
427 | if (test_bit(SCAN_HW_SCANNING, &local->scanning) || | ||
428 | test_bit(SCAN_SW_SCANNING, &local->scanning) || | ||
429 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
430 | local->sched_scanning) | ||
431 | return ieee80211_scan_rx(rx->sdata, skb); | ||
432 | |||
433 | /* scanning finished during invoking of handlers */ | ||
434 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | ||
435 | return RX_DROP_UNUSABLE; | ||
436 | } | ||
437 | |||
438 | |||
439 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) | 416 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) |
440 | { | 417 | { |
441 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 418 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -554,11 +531,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
554 | } | 531 | } |
555 | 532 | ||
556 | 533 | ||
557 | static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | 534 | static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, |
558 | struct tid_ampdu_rx *tid_agg_rx, | 535 | struct tid_ampdu_rx *tid_agg_rx, |
559 | int index) | 536 | int index) |
560 | { | 537 | { |
561 | struct ieee80211_local *local = hw_to_local(hw); | 538 | struct ieee80211_local *local = sdata->local; |
562 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 539 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
563 | struct ieee80211_rx_status *status; | 540 | struct ieee80211_rx_status *status; |
564 | 541 | ||
@@ -578,7 +555,7 @@ no_frame: | |||
578 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 555 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
579 | } | 556 | } |
580 | 557 | ||
581 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | 558 | static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, |
582 | struct tid_ampdu_rx *tid_agg_rx, | 559 | struct tid_ampdu_rx *tid_agg_rx, |
583 | u16 head_seq_num) | 560 | u16 head_seq_num) |
584 | { | 561 | { |
@@ -589,7 +566,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
589 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { | 566 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { |
590 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 567 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
591 | tid_agg_rx->buf_size; | 568 | tid_agg_rx->buf_size; |
592 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 569 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); |
593 | } | 570 | } |
594 | } | 571 | } |
595 | 572 | ||
@@ -604,7 +581,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
604 | */ | 581 | */ |
605 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 582 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
606 | 583 | ||
607 | static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | 584 | static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, |
608 | struct tid_ampdu_rx *tid_agg_rx) | 585 | struct tid_ampdu_rx *tid_agg_rx) |
609 | { | 586 | { |
610 | int index, j; | 587 | int index, j; |
@@ -632,12 +609,9 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
632 | HT_RX_REORDER_BUF_TIMEOUT)) | 609 | HT_RX_REORDER_BUF_TIMEOUT)) |
633 | goto set_release_timer; | 610 | goto set_release_timer; |
634 | 611 | ||
635 | #ifdef CONFIG_MAC80211_HT_DEBUG | 612 | ht_dbg_ratelimited(sdata, |
636 | if (net_ratelimit()) | 613 | "release an RX reorder frame due to timeout on earlier frames\n"); |
637 | wiphy_debug(hw->wiphy, | 614 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); |
638 | "release an RX reorder frame due to timeout on earlier frames\n"); | ||
639 | #endif | ||
640 | ieee80211_release_reorder_frame(hw, tid_agg_rx, j); | ||
641 | 615 | ||
642 | /* | 616 | /* |
643 | * Increment the head seq# also for the skipped slots. | 617 | * Increment the head seq# also for the skipped slots. |
@@ -647,7 +621,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
647 | skipped = 0; | 621 | skipped = 0; |
648 | } | 622 | } |
649 | } else while (tid_agg_rx->reorder_buf[index]) { | 623 | } else while (tid_agg_rx->reorder_buf[index]) { |
650 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 624 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); |
651 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 625 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
652 | tid_agg_rx->buf_size; | 626 | tid_agg_rx->buf_size; |
653 | } | 627 | } |
@@ -677,7 +651,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
677 | * rcu_read_lock protection. It returns false if the frame | 651 | * rcu_read_lock protection. It returns false if the frame |
678 | * can be processed immediately, true if it was consumed. | 652 | * can be processed immediately, true if it was consumed. |
679 | */ | 653 | */ |
680 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 654 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, |
681 | struct tid_ampdu_rx *tid_agg_rx, | 655 | struct tid_ampdu_rx *tid_agg_rx, |
682 | struct sk_buff *skb) | 656 | struct sk_buff *skb) |
683 | { | 657 | { |
@@ -706,7 +680,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
706 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { | 680 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { |
707 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); | 681 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); |
708 | /* release stored frames up to new head to stack */ | 682 | /* release stored frames up to new head to stack */ |
709 | ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); | 683 | ieee80211_release_reorder_frames(sdata, tid_agg_rx, |
684 | head_seq_num); | ||
710 | } | 685 | } |
711 | 686 | ||
712 | /* Now the new frame is always in the range of the reordering buffer */ | 687 | /* Now the new frame is always in the range of the reordering buffer */ |
@@ -736,7 +711,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
736 | tid_agg_rx->reorder_buf[index] = skb; | 711 | tid_agg_rx->reorder_buf[index] = skb; |
737 | tid_agg_rx->reorder_time[index] = jiffies; | 712 | tid_agg_rx->reorder_time[index] = jiffies; |
738 | tid_agg_rx->stored_mpdu_num++; | 713 | tid_agg_rx->stored_mpdu_num++; |
739 | ieee80211_sta_reorder_release(hw, tid_agg_rx); | 714 | ieee80211_sta_reorder_release(sdata, tid_agg_rx); |
740 | 715 | ||
741 | out: | 716 | out: |
742 | spin_unlock(&tid_agg_rx->reorder_lock); | 717 | spin_unlock(&tid_agg_rx->reorder_lock); |
@@ -751,7 +726,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
751 | { | 726 | { |
752 | struct sk_buff *skb = rx->skb; | 727 | struct sk_buff *skb = rx->skb; |
753 | struct ieee80211_local *local = rx->local; | 728 | struct ieee80211_local *local = rx->local; |
754 | struct ieee80211_hw *hw = &local->hw; | ||
755 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 729 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
756 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 730 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
757 | struct sta_info *sta = rx->sta; | 731 | struct sta_info *sta = rx->sta; |
@@ -813,7 +787,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
813 | * sure that we cannot get to it any more before doing | 787 | * sure that we cannot get to it any more before doing |
814 | * anything with it. | 788 | * anything with it. |
815 | */ | 789 | */ |
816 | if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) | 790 | if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) |
817 | return; | 791 | return; |
818 | 792 | ||
819 | dont_reorder: | 793 | dont_reorder: |
@@ -1136,24 +1110,18 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1136 | set_sta_flag(sta, WLAN_STA_PS_STA); | 1110 | set_sta_flag(sta, WLAN_STA_PS_STA); |
1137 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1111 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1138 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1112 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
1139 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1113 | ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", |
1140 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 1114 | sta->sta.addr, sta->sta.aid); |
1141 | sdata->name, sta->sta.addr, sta->sta.aid); | ||
1142 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1143 | } | 1115 | } |
1144 | 1116 | ||
1145 | static void ap_sta_ps_end(struct sta_info *sta) | 1117 | static void ap_sta_ps_end(struct sta_info *sta) |
1146 | { | 1118 | { |
1147 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1119 | ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", |
1148 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", | 1120 | sta->sta.addr, sta->sta.aid); |
1149 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | ||
1150 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1151 | 1121 | ||
1152 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1122 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1153 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1123 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", |
1154 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", | 1124 | sta->sta.addr, sta->sta.aid); |
1155 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | ||
1156 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1157 | return; | 1125 | return; |
1158 | } | 1126 | } |
1159 | 1127 | ||
@@ -1383,19 +1351,8 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
1383 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) | 1351 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) |
1384 | sdata->fragment_next = 0; | 1352 | sdata->fragment_next = 0; |
1385 | 1353 | ||
1386 | if (!skb_queue_empty(&entry->skb_list)) { | 1354 | if (!skb_queue_empty(&entry->skb_list)) |
1387 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1388 | struct ieee80211_hdr *hdr = | ||
1389 | (struct ieee80211_hdr *) entry->skb_list.next->data; | ||
1390 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " | ||
1391 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | ||
1392 | "addr1=%pM addr2=%pM\n", | ||
1393 | sdata->name, idx, | ||
1394 | jiffies - entry->first_frag_time, entry->seq, | ||
1395 | entry->last_frag, hdr->addr1, hdr->addr2); | ||
1396 | #endif | ||
1397 | __skb_queue_purge(&entry->skb_list); | 1355 | __skb_queue_purge(&entry->skb_list); |
1398 | } | ||
1399 | 1356 | ||
1400 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ | 1357 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ |
1401 | *skb = NULL; | 1358 | *skb = NULL; |
@@ -1753,7 +1710,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1753 | */ | 1710 | */ |
1754 | xmit_skb = skb_copy(skb, GFP_ATOMIC); | 1711 | xmit_skb = skb_copy(skb, GFP_ATOMIC); |
1755 | if (!xmit_skb) | 1712 | if (!xmit_skb) |
1756 | net_dbg_ratelimited("%s: failed to clone multicast frame\n", | 1713 | net_info_ratelimited("%s: failed to clone multicast frame\n", |
1757 | dev->name); | 1714 | dev->name); |
1758 | } else { | 1715 | } else { |
1759 | dsta = sta_info_get(sdata, skb->data); | 1716 | dsta = sta_info_get(sdata, skb->data); |
@@ -1937,7 +1894,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1937 | ether_addr_equal(sdata->vif.addr, hdr->addr3)) | 1894 | ether_addr_equal(sdata->vif.addr, hdr->addr3)) |
1938 | return RX_CONTINUE; | 1895 | return RX_CONTINUE; |
1939 | 1896 | ||
1940 | q = ieee80211_select_queue_80211(local, skb, hdr); | 1897 | q = ieee80211_select_queue_80211(sdata, skb, hdr); |
1941 | if (ieee80211_queue_stopped(&local->hw, q)) { | 1898 | if (ieee80211_queue_stopped(&local->hw, q)) { |
1942 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); | 1899 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); |
1943 | return RX_DROP_MONITOR; | 1900 | return RX_DROP_MONITOR; |
@@ -1957,7 +1914,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1957 | 1914 | ||
1958 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1915 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1959 | if (!fwd_skb) { | 1916 | if (!fwd_skb) { |
1960 | net_dbg_ratelimited("%s: failed to clone mesh frame\n", | 1917 | net_info_ratelimited("%s: failed to clone mesh frame\n", |
1961 | sdata->name); | 1918 | sdata->name); |
1962 | goto out; | 1919 | goto out; |
1963 | } | 1920 | } |
@@ -2060,8 +2017,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2060 | static ieee80211_rx_result debug_noinline | 2017 | static ieee80211_rx_result debug_noinline |
2061 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 2018 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
2062 | { | 2019 | { |
2063 | struct ieee80211_local *local = rx->local; | ||
2064 | struct ieee80211_hw *hw = &local->hw; | ||
2065 | struct sk_buff *skb = rx->skb; | 2020 | struct sk_buff *skb = rx->skb; |
2066 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; | 2021 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; |
2067 | struct tid_ampdu_rx *tid_agg_rx; | 2022 | struct tid_ampdu_rx *tid_agg_rx; |
@@ -2098,7 +2053,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
2098 | 2053 | ||
2099 | spin_lock(&tid_agg_rx->reorder_lock); | 2054 | spin_lock(&tid_agg_rx->reorder_lock); |
2100 | /* release stored frames up to start of BAR */ | 2055 | /* release stored frames up to start of BAR */ |
2101 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); | 2056 | ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, |
2057 | start_seq_num); | ||
2102 | spin_unlock(&tid_agg_rx->reorder_lock); | 2058 | spin_unlock(&tid_agg_rx->reorder_lock); |
2103 | 2059 | ||
2104 | kfree_skb(skb); | 2060 | kfree_skb(skb); |
@@ -2425,7 +2381,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2425 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 2381 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
2426 | sig = status->signal; | 2382 | sig = status->signal; |
2427 | 2383 | ||
2428 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, | 2384 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, |
2429 | rx->skb->data, rx->skb->len, | 2385 | rx->skb->data, rx->skb->len, |
2430 | GFP_ATOMIC)) { | 2386 | GFP_ATOMIC)) { |
2431 | if (rx->sta) | 2387 | if (rx->sta) |
@@ -2716,7 +2672,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) | |||
2716 | goto rxh_next; \ | 2672 | goto rxh_next; \ |
2717 | } while (0); | 2673 | } while (0); |
2718 | 2674 | ||
2719 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2720 | CALL_RXH(ieee80211_rx_h_check) | 2675 | CALL_RXH(ieee80211_rx_h_check) |
2721 | 2676 | ||
2722 | ieee80211_rx_reorder_ampdu(rx); | 2677 | ieee80211_rx_reorder_ampdu(rx); |
@@ -2752,7 +2707,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2752 | return; | 2707 | return; |
2753 | 2708 | ||
2754 | spin_lock(&tid_agg_rx->reorder_lock); | 2709 | spin_lock(&tid_agg_rx->reorder_lock); |
2755 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); | 2710 | ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); |
2756 | spin_unlock(&tid_agg_rx->reorder_lock); | 2711 | spin_unlock(&tid_agg_rx->reorder_lock); |
2757 | 2712 | ||
2758 | ieee80211_rx_handlers(&rx); | 2713 | ieee80211_rx_handlers(&rx); |
@@ -2786,11 +2741,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2786 | return 0; | 2741 | return 0; |
2787 | if (ieee80211_is_beacon(hdr->frame_control)) { | 2742 | if (ieee80211_is_beacon(hdr->frame_control)) { |
2788 | return 1; | 2743 | return 1; |
2789 | } | 2744 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2790 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2745 | return 0; |
2791 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) | ||
2792 | return 0; | ||
2793 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
2794 | } else if (!multicast && | 2746 | } else if (!multicast && |
2795 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 2747 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { |
2796 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2748 | if (!(sdata->dev->flags & IFF_PROMISC)) |
@@ -2828,11 +2780,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2828 | * and location updates. Note that mac80211 | 2780 | * and location updates. Note that mac80211 |
2829 | * itself never looks at these frames. | 2781 | * itself never looks at these frames. |
2830 | */ | 2782 | */ |
2831 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2783 | if (ieee80211_is_public_action(hdr, skb->len)) |
2832 | ieee80211_is_public_action(hdr, skb->len)) | ||
2833 | return 1; | 2784 | return 1; |
2834 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2785 | if (!ieee80211_is_beacon(hdr->frame_control)) |
2835 | !ieee80211_is_beacon(hdr->frame_control)) | ||
2836 | return 0; | 2786 | return 0; |
2837 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 2787 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2838 | } | 2788 | } |
@@ -2898,7 +2848,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
2898 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2848 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2899 | struct sk_buff *skb) | 2849 | struct sk_buff *skb) |
2900 | { | 2850 | { |
2901 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2902 | struct ieee80211_local *local = hw_to_local(hw); | 2851 | struct ieee80211_local *local = hw_to_local(hw); |
2903 | struct ieee80211_sub_if_data *sdata; | 2852 | struct ieee80211_sub_if_data *sdata; |
2904 | struct ieee80211_hdr *hdr; | 2853 | struct ieee80211_hdr *hdr; |
@@ -2916,11 +2865,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2916 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) | 2865 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) |
2917 | local->dot11ReceivedFragmentCount++; | 2866 | local->dot11ReceivedFragmentCount++; |
2918 | 2867 | ||
2919 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | ||
2920 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
2921 | test_bit(SCAN_SW_SCANNING, &local->scanning))) | ||
2922 | status->rx_flags |= IEEE80211_RX_IN_SCAN; | ||
2923 | |||
2924 | if (ieee80211_is_mgmt(fc)) | 2868 | if (ieee80211_is_mgmt(fc)) |
2925 | err = skb_linearize(skb); | 2869 | err = skb_linearize(skb); |
2926 | else | 2870 | else |
@@ -2935,6 +2879,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2935 | ieee80211_parse_qos(&rx); | 2879 | ieee80211_parse_qos(&rx); |
2936 | ieee80211_verify_alignment(&rx); | 2880 | ieee80211_verify_alignment(&rx); |
2937 | 2881 | ||
2882 | if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) || | ||
2883 | ieee80211_is_beacon(hdr->frame_control))) | ||
2884 | ieee80211_scan_rx(local, skb); | ||
2885 | |||
2938 | if (ieee80211_is_data(fc)) { | 2886 | if (ieee80211_is_data(fc)) { |
2939 | prev_sta = NULL; | 2887 | prev_sta = NULL; |
2940 | 2888 | ||
@@ -3032,6 +2980,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3032 | if (unlikely(local->quiescing || local->suspended)) | 2980 | if (unlikely(local->quiescing || local->suspended)) |
3033 | goto drop; | 2981 | goto drop; |
3034 | 2982 | ||
2983 | /* We might be during a HW reconfig, prevent Rx for the same reason */ | ||
2984 | if (unlikely(local->in_reconfig)) | ||
2985 | goto drop; | ||
2986 | |||
3035 | /* | 2987 | /* |
3036 | * The same happens when we're not even started, | 2988 | * The same happens when we're not even started, |
3037 | * but that's worth a warning. | 2989 | * but that's worth a warning. |