diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2010-04-06 05:18:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-07 14:38:06 -0400 |
commit | 54297e4d60b74e602138594c131097347d128b5a (patch) | |
tree | 5985dc4483e001b1029e3ca9355a80f2180f7832 /net/mac80211/rx.c | |
parent | 098a607091426e79178b9a6c318d993fea131791 (diff) |
mac80211: fix some RX aggregation locking
A few places in mac80211 do not currently acquire
the sta lock for RX aggregation, but they should.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 62053fa711f3..f42d5060a7bb 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -720,14 +720,16 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
720 | 720 | ||
721 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | 721 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
722 | 722 | ||
723 | spin_lock(&sta->lock); | ||
724 | |||
723 | if (!sta->ampdu_mlme.tid_active_rx[tid]) | 725 | if (!sta->ampdu_mlme.tid_active_rx[tid]) |
724 | goto dont_reorder; | 726 | goto dont_reorder_unlock; |
725 | 727 | ||
726 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; | 728 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; |
727 | 729 | ||
728 | /* qos null data frames are excluded */ | 730 | /* qos null data frames are excluded */ |
729 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) | 731 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) |
730 | goto dont_reorder; | 732 | goto dont_reorder_unlock; |
731 | 733 | ||
732 | /* new, potentially un-ordered, ampdu frame - process it */ | 734 | /* new, potentially un-ordered, ampdu frame - process it */ |
733 | 735 | ||
@@ -739,15 +741,20 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
739 | /* if this mpdu is fragmented - terminate rx aggregation session */ | 741 | /* if this mpdu is fragmented - terminate rx aggregation session */ |
740 | sc = le16_to_cpu(hdr->seq_ctrl); | 742 | sc = le16_to_cpu(hdr->seq_ctrl); |
741 | if (sc & IEEE80211_SCTL_FRAG) { | 743 | if (sc & IEEE80211_SCTL_FRAG) { |
744 | spin_unlock(&sta->lock); | ||
742 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, | 745 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, |
743 | WLAN_REASON_QSTA_REQUIRE_SETUP); | 746 | WLAN_REASON_QSTA_REQUIRE_SETUP); |
744 | dev_kfree_skb(skb); | 747 | dev_kfree_skb(skb); |
745 | return; | 748 | return; |
746 | } | 749 | } |
747 | 750 | ||
748 | if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) | 751 | if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) { |
752 | spin_unlock(&sta->lock); | ||
749 | return; | 753 | return; |
754 | } | ||
750 | 755 | ||
756 | dont_reorder_unlock: | ||
757 | spin_unlock(&sta->lock); | ||
751 | dont_reorder: | 758 | dont_reorder: |
752 | __skb_queue_tail(frames, skb); | 759 | __skb_queue_tail(frames, skb); |
753 | } | 760 | } |
@@ -1804,9 +1811,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) | |||
1804 | if (ieee80211_is_back_req(bar->frame_control)) { | 1811 | if (ieee80211_is_back_req(bar->frame_control)) { |
1805 | if (!rx->sta) | 1812 | if (!rx->sta) |
1806 | return RX_DROP_MONITOR; | 1813 | return RX_DROP_MONITOR; |
1814 | spin_lock(&rx->sta->lock); | ||
1807 | tid = le16_to_cpu(bar->control) >> 12; | 1815 | tid = le16_to_cpu(bar->control) >> 12; |
1808 | if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) | 1816 | if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) { |
1817 | spin_unlock(&rx->sta->lock); | ||
1809 | return RX_DROP_MONITOR; | 1818 | return RX_DROP_MONITOR; |
1819 | } | ||
1810 | tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; | 1820 | tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; |
1811 | 1821 | ||
1812 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; | 1822 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; |
@@ -1820,6 +1830,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) | |||
1820 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, | 1830 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, |
1821 | frames); | 1831 | frames); |
1822 | kfree_skb(skb); | 1832 | kfree_skb(skb); |
1833 | spin_unlock(&rx->sta->lock); | ||
1823 | return RX_QUEUED; | 1834 | return RX_QUEUED; |
1824 | } | 1835 | } |
1825 | 1836 | ||