aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-06 16:19:27 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-07-12 06:10:44 -0400
commitd48b296850f25cb559cb9b907d6d8c09eca3e89d (patch)
treeca2603b4ebfa210dda48c1a311996d826084835e /net/mac80211/rx.c
parent5260a5b2c3524f198ea062fe0a6a4faa724e6a9d (diff)
mac80211: redesign scan RX
Scan receive is rather inefficient when there are multiple virtual interfaces. We iterate all of the virtual interfaces and then notify cfg80211 about each beacon many times. Redesign scan RX to happen before everything else. Then we can also get rid of IEEE80211_RX_IN_SCAN since we don't have to accept frames into the RX handlers for scanning or scheduled scanning any more. Overall, this simplifies the code. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c47
1 files changed, 8 insertions, 39 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 17a56151be7f..1d7a58098e34 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -413,29 +413,6 @@ static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx)
413 413
414/* rx handlers */ 414/* rx handlers */
415 415
416static ieee80211_rx_result debug_noinline
417ieee80211_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 !rcu_access_pointer(local->sched_scan_sdata)))
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 rcu_access_pointer(local->sched_scan_sdata))
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
439static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) 416static 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;
@@ -2692,7 +2669,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2692 goto rxh_next; \ 2669 goto rxh_next; \
2693 } while (0); 2670 } while (0);
2694 2671
2695 CALL_RXH(ieee80211_rx_h_passive_scan)
2696 CALL_RXH(ieee80211_rx_h_check) 2672 CALL_RXH(ieee80211_rx_h_check)
2697 2673
2698 ieee80211_rx_reorder_ampdu(rx); 2674 ieee80211_rx_reorder_ampdu(rx);
@@ -2762,11 +2738,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2762 return 0; 2738 return 0;
2763 if (ieee80211_is_beacon(hdr->frame_control)) { 2739 if (ieee80211_is_beacon(hdr->frame_control)) {
2764 return 1; 2740 return 1;
2765 } 2741 } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {
2766 else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { 2742 return 0;
2767 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
2768 return 0;
2769 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2770 } else if (!multicast && 2743 } else if (!multicast &&
2771 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { 2744 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {
2772 if (!(sdata->dev->flags & IFF_PROMISC)) 2745 if (!(sdata->dev->flags & IFF_PROMISC))
@@ -2804,11 +2777,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2804 * and location updates. Note that mac80211 2777 * and location updates. Note that mac80211
2805 * itself never looks at these frames. 2778 * itself never looks at these frames.
2806 */ 2779 */
2807 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 2780 if (ieee80211_is_public_action(hdr, skb->len))
2808 ieee80211_is_public_action(hdr, skb->len))
2809 return 1; 2781 return 1;
2810 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 2782 if (!ieee80211_is_beacon(hdr->frame_control))
2811 !ieee80211_is_beacon(hdr->frame_control))
2812 return 0; 2783 return 0;
2813 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2784 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2814 } 2785 }
@@ -2874,7 +2845,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
2874static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, 2845static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2875 struct sk_buff *skb) 2846 struct sk_buff *skb)
2876{ 2847{
2877 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2878 struct ieee80211_local *local = hw_to_local(hw); 2848 struct ieee80211_local *local = hw_to_local(hw);
2879 struct ieee80211_sub_if_data *sdata; 2849 struct ieee80211_sub_if_data *sdata;
2880 struct ieee80211_hdr *hdr; 2850 struct ieee80211_hdr *hdr;
@@ -2892,11 +2862,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2892 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) 2862 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2893 local->dot11ReceivedFragmentCount++; 2863 local->dot11ReceivedFragmentCount++;
2894 2864
2895 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2896 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
2897 test_bit(SCAN_SW_SCANNING, &local->scanning)))
2898 status->rx_flags |= IEEE80211_RX_IN_SCAN;
2899
2900 if (ieee80211_is_mgmt(fc)) 2865 if (ieee80211_is_mgmt(fc))
2901 err = skb_linearize(skb); 2866 err = skb_linearize(skb);
2902 else 2867 else
@@ -2911,6 +2876,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2911 ieee80211_parse_qos(&rx); 2876 ieee80211_parse_qos(&rx);
2912 ieee80211_verify_alignment(&rx); 2877 ieee80211_verify_alignment(&rx);
2913 2878
2879 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) ||
2880 ieee80211_is_beacon(hdr->frame_control)))
2881 ieee80211_scan_rx(local, skb);
2882
2914 if (ieee80211_is_data(fc)) { 2883 if (ieee80211_is_data(fc)) {
2915 prev_sta = NULL; 2884 prev_sta = NULL;
2916 2885