diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 81 |
1 files changed, 32 insertions, 49 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 965e6ec0adb..67edd69e842 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. |
@@ -554,11 +554,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
554 | } | 554 | } |
555 | 555 | ||
556 | 556 | ||
557 | static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | 557 | static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, |
558 | struct tid_ampdu_rx *tid_agg_rx, | 558 | struct tid_ampdu_rx *tid_agg_rx, |
559 | int index) | 559 | int index) |
560 | { | 560 | { |
561 | struct ieee80211_local *local = hw_to_local(hw); | 561 | struct ieee80211_local *local = sdata->local; |
562 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 562 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
563 | struct ieee80211_rx_status *status; | 563 | struct ieee80211_rx_status *status; |
564 | 564 | ||
@@ -578,7 +578,7 @@ no_frame: | |||
578 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 578 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
579 | } | 579 | } |
580 | 580 | ||
581 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | 581 | static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, |
582 | struct tid_ampdu_rx *tid_agg_rx, | 582 | struct tid_ampdu_rx *tid_agg_rx, |
583 | u16 head_seq_num) | 583 | u16 head_seq_num) |
584 | { | 584 | { |
@@ -589,7 +589,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
589 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { | 589 | 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) % | 590 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
591 | tid_agg_rx->buf_size; | 591 | tid_agg_rx->buf_size; |
592 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 592 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); |
593 | } | 593 | } |
594 | } | 594 | } |
595 | 595 | ||
@@ -604,7 +604,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
604 | */ | 604 | */ |
605 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 605 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
606 | 606 | ||
607 | static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | 607 | static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, |
608 | struct tid_ampdu_rx *tid_agg_rx) | 608 | struct tid_ampdu_rx *tid_agg_rx) |
609 | { | 609 | { |
610 | int index, j; | 610 | int index, j; |
@@ -632,12 +632,9 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
632 | HT_RX_REORDER_BUF_TIMEOUT)) | 632 | HT_RX_REORDER_BUF_TIMEOUT)) |
633 | goto set_release_timer; | 633 | goto set_release_timer; |
634 | 634 | ||
635 | #ifdef CONFIG_MAC80211_HT_DEBUG | 635 | ht_dbg_ratelimited(sdata, |
636 | if (net_ratelimit()) | 636 | "release an RX reorder frame due to timeout on earlier frames\n"); |
637 | wiphy_debug(hw->wiphy, | 637 | 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 | 638 | ||
642 | /* | 639 | /* |
643 | * Increment the head seq# also for the skipped slots. | 640 | * Increment the head seq# also for the skipped slots. |
@@ -647,7 +644,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
647 | skipped = 0; | 644 | skipped = 0; |
648 | } | 645 | } |
649 | } else while (tid_agg_rx->reorder_buf[index]) { | 646 | } else while (tid_agg_rx->reorder_buf[index]) { |
650 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 647 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); |
651 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 648 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
652 | tid_agg_rx->buf_size; | 649 | tid_agg_rx->buf_size; |
653 | } | 650 | } |
@@ -677,7 +674,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
677 | * rcu_read_lock protection. It returns false if the frame | 674 | * rcu_read_lock protection. It returns false if the frame |
678 | * can be processed immediately, true if it was consumed. | 675 | * can be processed immediately, true if it was consumed. |
679 | */ | 676 | */ |
680 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 677 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, |
681 | struct tid_ampdu_rx *tid_agg_rx, | 678 | struct tid_ampdu_rx *tid_agg_rx, |
682 | struct sk_buff *skb) | 679 | struct sk_buff *skb) |
683 | { | 680 | { |
@@ -706,7 +703,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
706 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { | 703 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { |
707 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); | 704 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); |
708 | /* release stored frames up to new head to stack */ | 705 | /* release stored frames up to new head to stack */ |
709 | ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); | 706 | ieee80211_release_reorder_frames(sdata, tid_agg_rx, |
707 | head_seq_num); | ||
710 | } | 708 | } |
711 | 709 | ||
712 | /* Now the new frame is always in the range of the reordering buffer */ | 710 | /* Now the new frame is always in the range of the reordering buffer */ |
@@ -736,7 +734,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
736 | tid_agg_rx->reorder_buf[index] = skb; | 734 | tid_agg_rx->reorder_buf[index] = skb; |
737 | tid_agg_rx->reorder_time[index] = jiffies; | 735 | tid_agg_rx->reorder_time[index] = jiffies; |
738 | tid_agg_rx->stored_mpdu_num++; | 736 | tid_agg_rx->stored_mpdu_num++; |
739 | ieee80211_sta_reorder_release(hw, tid_agg_rx); | 737 | ieee80211_sta_reorder_release(sdata, tid_agg_rx); |
740 | 738 | ||
741 | out: | 739 | out: |
742 | spin_unlock(&tid_agg_rx->reorder_lock); | 740 | spin_unlock(&tid_agg_rx->reorder_lock); |
@@ -751,7 +749,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
751 | { | 749 | { |
752 | struct sk_buff *skb = rx->skb; | 750 | struct sk_buff *skb = rx->skb; |
753 | struct ieee80211_local *local = rx->local; | 751 | struct ieee80211_local *local = rx->local; |
754 | struct ieee80211_hw *hw = &local->hw; | ||
755 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 752 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
756 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 753 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
757 | struct sta_info *sta = rx->sta; | 754 | struct sta_info *sta = rx->sta; |
@@ -813,7 +810,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
813 | * sure that we cannot get to it any more before doing | 810 | * sure that we cannot get to it any more before doing |
814 | * anything with it. | 811 | * anything with it. |
815 | */ | 812 | */ |
816 | if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) | 813 | if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) |
817 | return; | 814 | return; |
818 | 815 | ||
819 | dont_reorder: | 816 | dont_reorder: |
@@ -1136,24 +1133,18 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1136 | set_sta_flag(sta, WLAN_STA_PS_STA); | 1133 | set_sta_flag(sta, WLAN_STA_PS_STA); |
1137 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1134 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1138 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1135 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
1139 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1136 | 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", | 1137 | sta->sta.addr, sta->sta.aid); |
1141 | sdata->name, sta->sta.addr, sta->sta.aid); | ||
1142 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1143 | } | 1138 | } |
1144 | 1139 | ||
1145 | static void ap_sta_ps_end(struct sta_info *sta) | 1140 | static void ap_sta_ps_end(struct sta_info *sta) |
1146 | { | 1141 | { |
1147 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1142 | 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", | 1143 | sta->sta.addr, sta->sta.aid); |
1149 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | ||
1150 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1151 | 1144 | ||
1152 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1145 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1153 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1146 | 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", | 1147 | 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; | 1148 | return; |
1158 | } | 1149 | } |
1159 | 1150 | ||
@@ -1383,19 +1374,8 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
1383 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) | 1374 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) |
1384 | sdata->fragment_next = 0; | 1375 | sdata->fragment_next = 0; |
1385 | 1376 | ||
1386 | if (!skb_queue_empty(&entry->skb_list)) { | 1377 | 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); | 1378 | __skb_queue_purge(&entry->skb_list); |
1398 | } | ||
1399 | 1379 | ||
1400 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ | 1380 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ |
1401 | *skb = NULL; | 1381 | *skb = NULL; |
@@ -1753,7 +1733,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1753 | */ | 1733 | */ |
1754 | xmit_skb = skb_copy(skb, GFP_ATOMIC); | 1734 | xmit_skb = skb_copy(skb, GFP_ATOMIC); |
1755 | if (!xmit_skb) | 1735 | if (!xmit_skb) |
1756 | net_dbg_ratelimited("%s: failed to clone multicast frame\n", | 1736 | net_info_ratelimited("%s: failed to clone multicast frame\n", |
1757 | dev->name); | 1737 | dev->name); |
1758 | } else { | 1738 | } else { |
1759 | dsta = sta_info_get(sdata, skb->data); | 1739 | dsta = sta_info_get(sdata, skb->data); |
@@ -1937,7 +1917,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1937 | ether_addr_equal(sdata->vif.addr, hdr->addr3)) | 1917 | ether_addr_equal(sdata->vif.addr, hdr->addr3)) |
1938 | return RX_CONTINUE; | 1918 | return RX_CONTINUE; |
1939 | 1919 | ||
1940 | q = ieee80211_select_queue_80211(local, skb, hdr); | 1920 | q = ieee80211_select_queue_80211(sdata, skb, hdr); |
1941 | if (ieee80211_queue_stopped(&local->hw, q)) { | 1921 | if (ieee80211_queue_stopped(&local->hw, q)) { |
1942 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); | 1922 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); |
1943 | return RX_DROP_MONITOR; | 1923 | return RX_DROP_MONITOR; |
@@ -1957,7 +1937,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1957 | 1937 | ||
1958 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1938 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1959 | if (!fwd_skb) { | 1939 | if (!fwd_skb) { |
1960 | net_dbg_ratelimited("%s: failed to clone mesh frame\n", | 1940 | net_info_ratelimited("%s: failed to clone mesh frame\n", |
1961 | sdata->name); | 1941 | sdata->name); |
1962 | goto out; | 1942 | goto out; |
1963 | } | 1943 | } |
@@ -2060,8 +2040,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2060 | static ieee80211_rx_result debug_noinline | 2040 | static ieee80211_rx_result debug_noinline |
2061 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 2041 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
2062 | { | 2042 | { |
2063 | struct ieee80211_local *local = rx->local; | ||
2064 | struct ieee80211_hw *hw = &local->hw; | ||
2065 | struct sk_buff *skb = rx->skb; | 2043 | struct sk_buff *skb = rx->skb; |
2066 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; | 2044 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; |
2067 | struct tid_ampdu_rx *tid_agg_rx; | 2045 | struct tid_ampdu_rx *tid_agg_rx; |
@@ -2098,7 +2076,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
2098 | 2076 | ||
2099 | spin_lock(&tid_agg_rx->reorder_lock); | 2077 | spin_lock(&tid_agg_rx->reorder_lock); |
2100 | /* release stored frames up to start of BAR */ | 2078 | /* release stored frames up to start of BAR */ |
2101 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); | 2079 | ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, |
2080 | start_seq_num); | ||
2102 | spin_unlock(&tid_agg_rx->reorder_lock); | 2081 | spin_unlock(&tid_agg_rx->reorder_lock); |
2103 | 2082 | ||
2104 | kfree_skb(skb); | 2083 | kfree_skb(skb); |
@@ -2752,7 +2731,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2752 | return; | 2731 | return; |
2753 | 2732 | ||
2754 | spin_lock(&tid_agg_rx->reorder_lock); | 2733 | spin_lock(&tid_agg_rx->reorder_lock); |
2755 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); | 2734 | ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); |
2756 | spin_unlock(&tid_agg_rx->reorder_lock); | 2735 | spin_unlock(&tid_agg_rx->reorder_lock); |
2757 | 2736 | ||
2758 | ieee80211_rx_handlers(&rx); | 2737 | ieee80211_rx_handlers(&rx); |
@@ -3032,6 +3011,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3032 | if (unlikely(local->quiescing || local->suspended)) | 3011 | if (unlikely(local->quiescing || local->suspended)) |
3033 | goto drop; | 3012 | goto drop; |
3034 | 3013 | ||
3014 | /* We might be during a HW reconfig, prevent Rx for the same reason */ | ||
3015 | if (unlikely(local->in_reconfig)) | ||
3016 | goto drop; | ||
3017 | |||
3035 | /* | 3018 | /* |
3036 | * The same happens when we're not even started, | 3019 | * The same happens when we're not even started, |
3037 | * but that's worth a warning. | 3020 | * but that's worth a warning. |