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.c96
1 files changed, 37 insertions, 59 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 535407d07fa4..3aae8e9e4e0a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -249,15 +249,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
249} 249}
250 250
251 251
252/* pre-rx handlers 252static void ieee80211_parse_qos(struct ieee80211_txrx_data *rx)
253 *
254 * these don't have dev/sdata fields in the rx data
255 * The sta value should also not be used because it may
256 * be NULL even though a STA (in IBSS mode) will be added.
257 */
258
259static ieee80211_txrx_result
260ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx)
261{ 253{
262 u8 *data = rx->skb->data; 254 u8 *data = rx->skb->data;
263 int tid; 255 int tid;
@@ -290,8 +282,40 @@ ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx)
290 /* Set skb->priority to 1d tag if highest order bit of TID is not set. 282 /* Set skb->priority to 1d tag if highest order bit of TID is not set.
291 * For now, set skb->priority to 0 for other cases. */ 283 * For now, set skb->priority to 0 for other cases. */
292 rx->skb->priority = (tid > 7) ? 0 : tid; 284 rx->skb->priority = (tid > 7) ? 0 : tid;
285}
293 286
294 return TXRX_CONTINUE; 287static void ieee80211_verify_ip_alignment(struct ieee80211_txrx_data *rx)
288{
289#ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT
290 int hdrlen;
291
292 if (!WLAN_FC_DATA_PRESENT(rx->fc))
293 return;
294
295 /*
296 * Drivers are required to align the payload data in a way that
297 * guarantees that the contained IP header is aligned to a four-
298 * byte boundary. In the case of regular frames, this simply means
299 * aligning the payload to a four-byte boundary (because either
300 * the IP header is directly contained, or IV/RFC1042 headers that
301 * have a length divisible by four are in front of it.
302 *
303 * With A-MSDU frames, however, the payload data address must
304 * yield two modulo four because there are 14-byte 802.3 headers
305 * within the A-MSDU frames that push the IP header further back
306 * to a multiple of four again. Thankfully, the specs were sane
307 * enough this time around to require padding each A-MSDU subframe
308 * to a length that is a multiple of four.
309 *
310 * Padding like atheros hardware adds which is inbetween the 802.11
311 * header and the payload is not supported, the driver is required
312 * to move the 802.11 header further back in that case.
313 */
314 hdrlen = ieee80211_get_hdrlen(rx->fc);
315 if (rx->flags & IEEE80211_TXRXD_RX_AMSDU)
316 hdrlen += ETH_HLEN;
317 WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3);
318#endif
295} 319}
296 320
297 321
@@ -340,52 +364,6 @@ static u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
340 return load; 364 return load;
341} 365}
342 366
343#ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT
344static ieee80211_txrx_result
345ieee80211_rx_h_verify_ip_alignment(struct ieee80211_txrx_data *rx)
346{
347 int hdrlen;
348
349 if (!WLAN_FC_DATA_PRESENT(rx->fc))
350 return TXRX_CONTINUE;
351
352 /*
353 * Drivers are required to align the payload data in a way that
354 * guarantees that the contained IP header is aligned to a four-
355 * byte boundary. In the case of regular frames, this simply means
356 * aligning the payload to a four-byte boundary (because either
357 * the IP header is directly contained, or IV/RFC1042 headers that
358 * have a length divisible by four are in front of it.
359 *
360 * With A-MSDU frames, however, the payload data address must
361 * yield two modulo four because there are 14-byte 802.3 headers
362 * within the A-MSDU frames that push the IP header further back
363 * to a multiple of four again. Thankfully, the specs were sane
364 * enough this time around to require padding each A-MSDU subframe
365 * to a length that is a multiple of four.
366 *
367 * Padding like atheros hardware adds which is inbetween the 802.11
368 * header and the payload is not supported, the driver is required
369 * to move the 802.11 header further back in that case.
370 */
371 hdrlen = ieee80211_get_hdrlen(rx->fc);
372 if (rx->flags & IEEE80211_TXRXD_RX_AMSDU)
373 hdrlen += ETH_HLEN;
374 WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3);
375
376 return TXRX_CONTINUE;
377}
378#endif
379
380ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
381{
382 ieee80211_rx_h_parse_qos,
383#ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT
384 ieee80211_rx_h_verify_ip_alignment,
385#endif
386 NULL
387};
388
389/* rx handlers */ 367/* rx handlers */
390 368
391static ieee80211_txrx_result 369static ieee80211_txrx_result
@@ -1747,9 +1725,9 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1747 if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning)) 1725 if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning))
1748 rx.flags |= IEEE80211_TXRXD_RXIN_SCAN; 1726 rx.flags |= IEEE80211_TXRXD_RXIN_SCAN;
1749 1727
1750 if (__ieee80211_invoke_rx_handlers(local, local->rx_pre_handlers, &rx, 1728 ieee80211_parse_qos(&rx);
1751 sta) != TXRX_CONTINUE) 1729 ieee80211_verify_ip_alignment(&rx);
1752 goto end; 1730
1753 skb = rx.skb; 1731 skb = rx.skb;
1754 1732
1755 if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) && 1733 if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) &&