aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 0cb4edee6af5..61c621e9273f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -60,7 +60,9 @@ static inline int should_drop_frame(struct sk_buff *skb,
60 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 60 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
61 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 61 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
62 62
63 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) 63 if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
64 RX_FLAG_FAILED_PLCP_CRC |
65 RX_FLAG_AMPDU_IS_ZEROLEN))
64 return 1; 66 return 1;
65 if (unlikely(skb->len < 16 + present_fcs_len)) 67 if (unlikely(skb->len < 16 + present_fcs_len))
66 return 1; 68 return 1;
@@ -91,10 +93,17 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
91 if (status->flag & RX_FLAG_HT) /* HT info */ 93 if (status->flag & RX_FLAG_HT) /* HT info */
92 len += 3; 94 len += 3;
93 95
96 if (status->flag & RX_FLAG_AMPDU_DETAILS) {
97 /* padding */
98 while (len & 3)
99 len++;
100 len += 8;
101 }
102
94 return len; 103 return len;
95} 104}
96 105
97/** 106/*
98 * ieee80211_add_rx_radiotap_header - add radiotap header 107 * ieee80211_add_rx_radiotap_header - add radiotap header
99 * 108 *
100 * add a radiotap header containing all the fields which the hardware provided. 109 * add a radiotap header containing all the fields which the hardware provided.
@@ -215,6 +224,37 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
215 pos++; 224 pos++;
216 *pos++ = status->rate_idx; 225 *pos++ = status->rate_idx;
217 } 226 }
227
228 if (status->flag & RX_FLAG_AMPDU_DETAILS) {
229 u16 flags = 0;
230
231 /* ensure 4 byte alignment */
232 while ((pos - (u8 *)rthdr) & 3)
233 pos++;
234 rthdr->it_present |=
235 cpu_to_le32(1 << IEEE80211_RADIOTAP_AMPDU_STATUS);
236 put_unaligned_le32(status->ampdu_reference, pos);
237 pos += 4;
238 if (status->flag & RX_FLAG_AMPDU_REPORT_ZEROLEN)
239 flags |= IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN;
240 if (status->flag & RX_FLAG_AMPDU_IS_ZEROLEN)
241 flags |= IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN;
242 if (status->flag & RX_FLAG_AMPDU_LAST_KNOWN)
243 flags |= IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN;
244 if (status->flag & RX_FLAG_AMPDU_IS_LAST)
245 flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST;
246 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR)
247 flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR;
248 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
249 flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN;
250 put_unaligned_le16(flags, pos);
251 pos += 2;
252 if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN)
253 *pos++ = status->ampdu_delimiter_crc;
254 else
255 *pos++ = 0;
256 *pos++ = 0;
257 }
218} 258}
219 259
220/* 260/*
@@ -2268,7 +2308,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2268 2308
2269 goto queue; 2309 goto queue;
2270 case WLAN_CATEGORY_SPECTRUM_MGMT: 2310 case WLAN_CATEGORY_SPECTRUM_MGMT:
2271 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) 2311 if (status->band != IEEE80211_BAND_5GHZ)
2272 break; 2312 break;
2273 2313
2274 if (sdata->vif.type != NL80211_IFTYPE_STATION) 2314 if (sdata->vif.type != NL80211_IFTYPE_STATION)
@@ -2772,8 +2812,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2772 if (!bssid) { 2812 if (!bssid) {
2773 if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) 2813 if (!ether_addr_equal(sdata->vif.addr, hdr->addr1))
2774 return 0; 2814 return 0;
2775 } else if (!ieee80211_bssid_match(bssid, 2815 } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) {
2776 sdata->vif.addr)) {
2777 /* 2816 /*
2778 * Accept public action frames even when the 2817 * Accept public action frames even when the
2779 * BSSID doesn't match, this is used for P2P 2818 * BSSID doesn't match, this is used for P2P
@@ -2793,9 +2832,18 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2793 if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) 2832 if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2))
2794 return 0; 2833 return 0;
2795 break; 2834 break;
2835 case NL80211_IFTYPE_P2P_DEVICE:
2836 if (!ieee80211_is_public_action(hdr, skb->len) &&
2837 !ieee80211_is_probe_req(hdr->frame_control) &&
2838 !ieee80211_is_probe_resp(hdr->frame_control) &&
2839 !ieee80211_is_beacon(hdr->frame_control))
2840 return 0;
2841 if (!ether_addr_equal(sdata->vif.addr, hdr->addr1))
2842 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2843 break;
2796 default: 2844 default:
2797 /* should never get here */ 2845 /* should never get here */
2798 WARN_ON(1); 2846 WARN_ON_ONCE(1);
2799 break; 2847 break;
2800 } 2848 }
2801 2849