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.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c542fc1c983d..9cd59ecbcd67 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -79,8 +79,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
79 struct ieee80211_sub_if_data *sdata; 79 struct ieee80211_sub_if_data *sdata;
80 struct ieee80211_rate *rate; 80 struct ieee80211_rate *rate;
81 int needed_headroom = 0; 81 int needed_headroom = 0;
82 struct ieee80211_rtap_hdr { 82 struct ieee80211_radiotap_header *rthdr;
83 struct ieee80211_radiotap_header hdr; 83 __le64 *rttsft = NULL;
84 struct ieee80211_rtap_fixed_data {
84 u8 flags; 85 u8 flags;
85 u8 rate; 86 u8 rate;
86 __le16 chan_freq; 87 __le16 chan_freq;
@@ -88,7 +89,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
88 u8 antsignal; 89 u8 antsignal;
89 u8 padding_for_rxflags; 90 u8 padding_for_rxflags;
90 __le16 rx_flags; 91 __le16 rx_flags;
91 } __attribute__ ((packed)) *rthdr; 92 } __attribute__ ((packed)) *rtfixed;
92 struct sk_buff *skb, *skb2; 93 struct sk_buff *skb, *skb2;
93 struct net_device *prev_dev = NULL; 94 struct net_device *prev_dev = NULL;
94 int present_fcs_len = 0; 95 int present_fcs_len = 0;
@@ -105,7 +106,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
105 if (status->flag & RX_FLAG_RADIOTAP) 106 if (status->flag & RX_FLAG_RADIOTAP)
106 rtap_len = ieee80211_get_radiotap_len(origskb->data); 107 rtap_len = ieee80211_get_radiotap_len(origskb->data);
107 else 108 else
108 needed_headroom = sizeof(*rthdr); 109 /* room for radiotap header, always present fields and TSFT */
110 needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8;
109 111
110 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 112 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
111 present_fcs_len = FCS_LEN; 113 present_fcs_len = FCS_LEN;
@@ -133,7 +135,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
133 * them allocate enough headroom to start with. 135 * them allocate enough headroom to start with.
134 */ 136 */
135 if (skb_headroom(skb) < needed_headroom && 137 if (skb_headroom(skb) < needed_headroom &&
136 pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) { 138 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) {
137 dev_kfree_skb(skb); 139 dev_kfree_skb(skb);
138 return NULL; 140 return NULL;
139 } 141 }
@@ -152,42 +154,56 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
152 154
153 /* if necessary, prepend radiotap information */ 155 /* if necessary, prepend radiotap information */
154 if (!(status->flag & RX_FLAG_RADIOTAP)) { 156 if (!(status->flag & RX_FLAG_RADIOTAP)) {
157 rtfixed = (void *) skb_push(skb, sizeof(*rtfixed));
158 rtap_len = sizeof(*rthdr) + sizeof(*rtfixed);
159 if (status->flag & RX_FLAG_TSFT) {
160 rttsft = (void *) skb_push(skb, sizeof(*rttsft));
161 rtap_len += 8;
162 }
155 rthdr = (void *) skb_push(skb, sizeof(*rthdr)); 163 rthdr = (void *) skb_push(skb, sizeof(*rthdr));
156 memset(rthdr, 0, sizeof(*rthdr)); 164 memset(rthdr, 0, sizeof(*rthdr));
157 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); 165 memset(rtfixed, 0, sizeof(*rtfixed));
158 rthdr->hdr.it_present = 166 rthdr->it_present =
159 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | 167 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
160 (1 << IEEE80211_RADIOTAP_RATE) | 168 (1 << IEEE80211_RADIOTAP_RATE) |
161 (1 << IEEE80211_RADIOTAP_CHANNEL) | 169 (1 << IEEE80211_RADIOTAP_CHANNEL) |
162 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | 170 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |
163 (1 << IEEE80211_RADIOTAP_RX_FLAGS)); 171 (1 << IEEE80211_RADIOTAP_RX_FLAGS));
164 rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ? 172 rtfixed->flags = 0;
165 IEEE80211_RADIOTAP_F_FCS : 0; 173 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
174 rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS;
175
176 if (rttsft) {
177 *rttsft = cpu_to_le64(status->mactime);
178 rthdr->it_present |=
179 cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
180 }
166 181
167 /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ 182 /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */
168 rthdr->rx_flags = 0; 183 rtfixed->rx_flags = 0;
169 if (status->flag & 184 if (status->flag &
170 (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) 185 (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
171 rthdr->rx_flags |= 186 rtfixed->rx_flags |=
172 cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); 187 cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
173 188
174 rate = ieee80211_get_rate(local, status->phymode, 189 rate = ieee80211_get_rate(local, status->phymode,
175 status->rate); 190 status->rate);
176 if (rate) 191 if (rate)
177 rthdr->rate = rate->rate / 5; 192 rtfixed->rate = rate->rate / 5;
178 193
179 rthdr->chan_freq = cpu_to_le16(status->freq); 194 rtfixed->chan_freq = cpu_to_le16(status->freq);
180 195
181 if (status->phymode == MODE_IEEE80211A) 196 if (status->phymode == MODE_IEEE80211A)
182 rthdr->chan_flags = 197 rtfixed->chan_flags =
183 cpu_to_le16(IEEE80211_CHAN_OFDM | 198 cpu_to_le16(IEEE80211_CHAN_OFDM |
184 IEEE80211_CHAN_5GHZ); 199 IEEE80211_CHAN_5GHZ);
185 else 200 else
186 rthdr->chan_flags = 201 rtfixed->chan_flags =
187 cpu_to_le16(IEEE80211_CHAN_DYN | 202 cpu_to_le16(IEEE80211_CHAN_DYN |
188 IEEE80211_CHAN_2GHZ); 203 IEEE80211_CHAN_2GHZ);
189 204
190 rthdr->antsignal = status->ssi; 205 rtfixed->antsignal = status->ssi;
206 rthdr->it_len = cpu_to_le16(rtap_len);
191 } 207 }
192 208
193 skb_set_mac_header(skb, 0); 209 skb_set_mac_header(skb, 0);