diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 39 |
1 files changed, 9 insertions, 30 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c8166adcd600..10bbbd33b314 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -228,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
228 | { | 228 | { |
229 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); | 229 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); |
230 | struct ieee80211_sub_if_data *sdata; | 230 | struct ieee80211_sub_if_data *sdata; |
231 | int needed_headroom = 0; | 231 | int needed_headroom; |
232 | struct sk_buff *skb, *skb2; | 232 | struct sk_buff *skb, *skb2; |
233 | struct net_device *prev_dev = NULL; | 233 | struct net_device *prev_dev = NULL; |
234 | int present_fcs_len = 0; | 234 | int present_fcs_len = 0; |
@@ -2544,16 +2544,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2544 | { | 2544 | { |
2545 | struct ieee80211_sub_if_data *sdata; | 2545 | struct ieee80211_sub_if_data *sdata; |
2546 | struct ieee80211_local *local = rx->local; | 2546 | struct ieee80211_local *local = rx->local; |
2547 | struct ieee80211_rtap_hdr { | ||
2548 | struct ieee80211_radiotap_header hdr; | ||
2549 | u8 flags; | ||
2550 | u8 rate_or_pad; | ||
2551 | __le16 chan_freq; | ||
2552 | __le16 chan_flags; | ||
2553 | } __packed *rthdr; | ||
2554 | struct sk_buff *skb = rx->skb, *skb2; | 2547 | struct sk_buff *skb = rx->skb, *skb2; |
2555 | struct net_device *prev_dev = NULL; | 2548 | struct net_device *prev_dev = NULL; |
2556 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2549 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2550 | int needed_headroom; | ||
2557 | 2551 | ||
2558 | /* | 2552 | /* |
2559 | * If cooked monitor has been processed already, then | 2553 | * If cooked monitor has been processed already, then |
@@ -2567,30 +2561,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2567 | if (!local->cooked_mntrs) | 2561 | if (!local->cooked_mntrs) |
2568 | goto out_free_skb; | 2562 | goto out_free_skb; |
2569 | 2563 | ||
2570 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2564 | /* room for the radiotap header based on driver features */ |
2571 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2565 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
2572 | goto out_free_skb; | ||
2573 | |||
2574 | rthdr = (void *)skb_push(skb, sizeof(*rthdr)); | ||
2575 | memset(rthdr, 0, sizeof(*rthdr)); | ||
2576 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
2577 | rthdr->hdr.it_present = | ||
2578 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
2579 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | ||
2580 | 2566 | ||
2581 | if (rate) { | 2567 | if (skb_headroom(skb) < needed_headroom && |
2582 | rthdr->rate_or_pad = rate->bitrate / 5; | 2568 | pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) |
2583 | rthdr->hdr.it_present |= | 2569 | goto out_free_skb; |
2584 | cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); | ||
2585 | } | ||
2586 | rthdr->chan_freq = cpu_to_le16(status->freq); | ||
2587 | 2570 | ||
2588 | if (status->band == IEEE80211_BAND_5GHZ) | 2571 | /* prepend radiotap information */ |
2589 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | | 2572 | ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); |
2590 | IEEE80211_CHAN_5GHZ); | ||
2591 | else | ||
2592 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
2593 | IEEE80211_CHAN_2GHZ); | ||
2594 | 2573 | ||
2595 | skb_set_mac_header(skb, 0); | 2574 | skb_set_mac_header(skb, 0); |
2596 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2575 | skb->ip_summed = CHECKSUM_UNNECESSARY; |