diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 96 |
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 | 252 | static 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 | |||
259 | static ieee80211_txrx_result | ||
260 | ieee80211_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; | 287 | static 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 | ||
344 | static ieee80211_txrx_result | ||
345 | ieee80211_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 | |||
380 | ieee80211_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 | ||
391 | static ieee80211_txrx_result | 369 | static 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)) && |