aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorThomas Pedersen <thomas@cozybit.com>2011-11-04 00:11:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:05:48 -0500
commit6cc00d545a21ed26696f3bda865ebf11eccbf2b5 (patch)
treee048b70728f9fcb8dac02b72b421c037d03c1e5d /net
parentf3011cf9deb689bd68279c728c501a4166983c19 (diff)
mac80211: QoS multicast frames have No Ack policy
Previously QoS multicast frames had the Normal Acknowledgment QoS control bits set. This would cause broadcast frames to be discarded by peers with which we have a BA session, since their sequence number would fall outside the allowed range. Set No Ack QoS control bits on multicast QoS frames and filter these in de-aggregation code. Signed-off-by: Thomas Pedersen <thomas@cozybit.com> v2: Use proper QoS Ack Policy ctl field mask (Christian) v3: Clean up conditional (Johannes) Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/rx.c9
-rw-r--r--net/mac80211/wme.c3
2 files changed, 10 insertions, 2 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3173dcfc213..72c1eb4eb45 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -747,7 +747,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
747 struct sta_info *sta = rx->sta; 747 struct sta_info *sta = rx->sta;
748 struct tid_ampdu_rx *tid_agg_rx; 748 struct tid_ampdu_rx *tid_agg_rx;
749 u16 sc; 749 u16 sc;
750 int tid; 750 u8 tid, ack_policy;
751 751
752 if (!ieee80211_is_data_qos(hdr->frame_control)) 752 if (!ieee80211_is_data_qos(hdr->frame_control))
753 goto dont_reorder; 753 goto dont_reorder;
@@ -760,6 +760,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
760 if (!sta) 760 if (!sta)
761 goto dont_reorder; 761 goto dont_reorder;
762 762
763 ack_policy = *ieee80211_get_qos_ctl(hdr) &
764 IEEE80211_QOS_CTL_ACK_POLICY_MASK;
763 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 765 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
764 766
765 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); 767 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
@@ -770,6 +772,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
770 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 772 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
771 goto dont_reorder; 773 goto dont_reorder;
772 774
775 /* not part of a BA session */
776 if (ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
777 ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)
778 goto dont_reorder;
779
773 /* new, potentially un-ordered, ampdu frame - process it */ 780 /* new, potentially un-ordered, ampdu frame - process it */
774 781
775 /* reset session timer */ 782 /* reset session timer */
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index d0240bba45f..d4f789a4e4f 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -150,7 +150,8 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
150 /* preserve EOSP bit */ 150 /* preserve EOSP bit */
151 ack_policy = *p & IEEE80211_QOS_CTL_EOSP; 151 ack_policy = *p & IEEE80211_QOS_CTL_EOSP;
152 152
153 if (unlikely(sdata->local->wifi_wme_noack_test)) 153 if (unlikely(sdata->local->wifi_wme_noack_test) ||
154 is_multicast_ether_addr(hdr->addr1))
154 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; 155 ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
155 /* qos header is 2 bytes */ 156 /* qos header is 2 bytes */
156 *p++ = ack_policy | tid; 157 *p++ = ack_policy | tid;