diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:22:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:22:43 -0400 |
commit | 55faed1e607a24ca7f3453a3eb463ca8987f8139 (patch) | |
tree | 70c1f910576713e799b5b409d9f4c3c56840526e /net/ieee80211/ieee80211_tx.c | |
parent | 946e91f36e90eea46758dd725b1c3b239f270f68 (diff) | |
parent | 0edd5b44913cd0aba6f23b626b407f70bb3fb018 (diff) |
Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 66 |
1 files changed, 28 insertions, 38 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index b7ea3e25e25d..c9aaff3fea1e 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c | |||
@@ -45,10 +45,8 @@ | |||
45 | 45 | ||
46 | #include <net/ieee80211.h> | 46 | #include <net/ieee80211.h> |
47 | 47 | ||
48 | |||
49 | /* | 48 | /* |
50 | 49 | ||
51 | |||
52 | 802.11 Data Frame | 50 | 802.11 Data Frame |
53 | 51 | ||
54 | ,-------------------------------------------------------------------. | 52 | ,-------------------------------------------------------------------. |
@@ -82,7 +80,6 @@ Desc. | IV | Encrypted | ICV | | |||
82 | `-----------------------' | 80 | `-----------------------' |
83 | Total: 8 non-data bytes | 81 | Total: 8 non-data bytes |
84 | 82 | ||
85 | |||
86 | 802.3 Ethernet Data Frame | 83 | 802.3 Ethernet Data Frame |
87 | 84 | ||
88 | ,-----------------------------------------. | 85 | ,-----------------------------------------. |
@@ -131,7 +128,7 @@ payload of each frame is reduced to 492 bytes. | |||
131 | static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; | 128 | static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; |
132 | static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; | 129 | static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; |
133 | 130 | ||
134 | static inline int ieee80211_put_snap(u8 *data, u16 h_proto) | 131 | static inline int ieee80211_put_snap(u8 * data, u16 h_proto) |
135 | { | 132 | { |
136 | struct ieee80211_snap_hdr *snap; | 133 | struct ieee80211_snap_hdr *snap; |
137 | u8 *oui; | 134 | u8 *oui; |
@@ -149,17 +146,15 @@ static inline int ieee80211_put_snap(u8 *data, u16 h_proto) | |||
149 | snap->oui[1] = oui[1]; | 146 | snap->oui[1] = oui[1]; |
150 | snap->oui[2] = oui[2]; | 147 | snap->oui[2] = oui[2]; |
151 | 148 | ||
152 | *(u16 *)(data + SNAP_SIZE) = htons(h_proto); | 149 | *(u16 *) (data + SNAP_SIZE) = htons(h_proto); |
153 | 150 | ||
154 | return SNAP_SIZE + sizeof(u16); | 151 | return SNAP_SIZE + sizeof(u16); |
155 | } | 152 | } |
156 | 153 | ||
157 | static inline int ieee80211_encrypt_fragment( | 154 | static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, |
158 | struct ieee80211_device *ieee, | 155 | struct sk_buff *frag, int hdr_len) |
159 | struct sk_buff *frag, | ||
160 | int hdr_len) | ||
161 | { | 156 | { |
162 | struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx]; | 157 | struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx]; |
163 | int res; | 158 | int res; |
164 | 159 | ||
165 | #ifdef CONFIG_IEEE80211_CRYPT_TKIP | 160 | #ifdef CONFIG_IEEE80211_CRYPT_TKIP |
@@ -167,7 +162,7 @@ static inline int ieee80211_encrypt_fragment( | |||
167 | 162 | ||
168 | if (ieee->tkip_countermeasures && | 163 | if (ieee->tkip_countermeasures && |
169 | crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { | 164 | crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { |
170 | header = (struct ieee80211_hdr *) frag->data; | 165 | header = (struct ieee80211_hdr *)frag->data; |
171 | if (net_ratelimit()) { | 166 | if (net_ratelimit()) { |
172 | printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " | 167 | printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " |
173 | "TX packet to " MAC_FMT "\n", | 168 | "TX packet to " MAC_FMT "\n", |
@@ -200,8 +195,8 @@ static inline int ieee80211_encrypt_fragment( | |||
200 | return 0; | 195 | return 0; |
201 | } | 196 | } |
202 | 197 | ||
203 | 198 | void ieee80211_txb_free(struct ieee80211_txb *txb) | |
204 | void ieee80211_txb_free(struct ieee80211_txb *txb) { | 199 | { |
205 | int i; | 200 | int i; |
206 | if (unlikely(!txb)) | 201 | if (unlikely(!txb)) |
207 | return; | 202 | return; |
@@ -216,9 +211,8 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, | |||
216 | { | 211 | { |
217 | struct ieee80211_txb *txb; | 212 | struct ieee80211_txb *txb; |
218 | int i; | 213 | int i; |
219 | txb = kmalloc( | 214 | txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags), |
220 | sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags), | 215 | gfp_mask); |
221 | gfp_mask); | ||
222 | if (!txb) | 216 | if (!txb) |
223 | return NULL; | 217 | return NULL; |
224 | 218 | ||
@@ -243,8 +237,7 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, | |||
243 | } | 237 | } |
244 | 238 | ||
245 | /* SKBs are added to the ieee->tx_queue. */ | 239 | /* SKBs are added to the ieee->tx_queue. */ |
246 | int ieee80211_xmit(struct sk_buff *skb, | 240 | int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) |
247 | struct net_device *dev) | ||
248 | { | 241 | { |
249 | struct ieee80211_device *ieee = netdev_priv(dev); | 242 | struct ieee80211_device *ieee = netdev_priv(dev); |
250 | struct ieee80211_txb *txb = NULL; | 243 | struct ieee80211_txb *txb = NULL; |
@@ -255,21 +248,20 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
255 | int ether_type, encrypt; | 248 | int ether_type, encrypt; |
256 | int bytes, fc, hdr_len; | 249 | int bytes, fc, hdr_len; |
257 | struct sk_buff *skb_frag; | 250 | struct sk_buff *skb_frag; |
258 | struct ieee80211_hdr header = { /* Ensure zero initialized */ | 251 | struct ieee80211_hdr header = { /* Ensure zero initialized */ |
259 | .duration_id = 0, | 252 | .duration_id = 0, |
260 | .seq_ctl = 0 | 253 | .seq_ctl = 0 |
261 | }; | 254 | }; |
262 | u8 dest[ETH_ALEN], src[ETH_ALEN]; | 255 | u8 dest[ETH_ALEN], src[ETH_ALEN]; |
263 | 256 | ||
264 | struct ieee80211_crypt_data* crypt; | 257 | struct ieee80211_crypt_data *crypt; |
265 | 258 | ||
266 | spin_lock_irqsave(&ieee->lock, flags); | 259 | spin_lock_irqsave(&ieee->lock, flags); |
267 | 260 | ||
268 | /* If there is no driver handler to take the TXB, dont' bother | 261 | /* If there is no driver handler to take the TXB, dont' bother |
269 | * creating it... */ | 262 | * creating it... */ |
270 | if (!ieee->hard_start_xmit) { | 263 | if (!ieee->hard_start_xmit) { |
271 | printk(KERN_WARNING "%s: No xmit handler.\n", | 264 | printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name); |
272 | ieee->dev->name); | ||
273 | goto success; | 265 | goto success; |
274 | } | 266 | } |
275 | 267 | ||
@@ -284,7 +276,7 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
284 | crypt = ieee->crypt[ieee->tx_keyidx]; | 276 | crypt = ieee->crypt[ieee->tx_keyidx]; |
285 | 277 | ||
286 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && | 278 | encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && |
287 | ieee->host_encrypt && crypt && crypt->ops; | 279 | ieee->host_encrypt && crypt && crypt->ops; |
288 | 280 | ||
289 | if (!encrypt && ieee->ieee802_1x && | 281 | if (!encrypt && ieee->ieee802_1x && |
290 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { | 282 | ieee->drop_unencrypted && ether_type != ETH_P_PAE) { |
@@ -294,7 +286,7 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
294 | 286 | ||
295 | /* Save source and destination addresses */ | 287 | /* Save source and destination addresses */ |
296 | memcpy(&dest, skb->data, ETH_ALEN); | 288 | memcpy(&dest, skb->data, ETH_ALEN); |
297 | memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); | 289 | memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN); |
298 | 290 | ||
299 | /* Advance the SKB to the start of the payload */ | 291 | /* Advance the SKB to the start of the payload */ |
300 | skb_pull(skb, sizeof(struct ethhdr)); | 292 | skb_pull(skb, sizeof(struct ethhdr)); |
@@ -304,7 +296,7 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
304 | 296 | ||
305 | if (encrypt) | 297 | if (encrypt) |
306 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | | 298 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | |
307 | IEEE80211_FCTL_PROTECTED; | 299 | IEEE80211_FCTL_PROTECTED; |
308 | else | 300 | else |
309 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; | 301 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; |
310 | 302 | ||
@@ -327,8 +319,7 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
327 | 319 | ||
328 | /* Determine fragmentation size based on destination (multicast | 320 | /* Determine fragmentation size based on destination (multicast |
329 | * and broadcast are not fragmented) */ | 321 | * and broadcast are not fragmented) */ |
330 | if (is_multicast_ether_addr(dest) || | 322 | if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest)) |
331 | is_broadcast_ether_addr(dest)) | ||
332 | frag_size = MAX_FRAG_THRESHOLD; | 323 | frag_size = MAX_FRAG_THRESHOLD; |
333 | else | 324 | else |
334 | frag_size = ieee->fts; | 325 | frag_size = ieee->fts; |
@@ -345,7 +336,7 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
345 | /* Each fragment may need to have room for encryptiong pre/postfix */ | 336 | /* Each fragment may need to have room for encryptiong pre/postfix */ |
346 | if (encrypt) | 337 | if (encrypt) |
347 | bytes_per_frag -= crypt->ops->extra_prefix_len + | 338 | bytes_per_frag -= crypt->ops->extra_prefix_len + |
348 | crypt->ops->extra_postfix_len; | 339 | crypt->ops->extra_postfix_len; |
349 | 340 | ||
350 | /* Number of fragments is the total bytes_per_frag / | 341 | /* Number of fragments is the total bytes_per_frag / |
351 | * payload_per_fragment */ | 342 | * payload_per_fragment */ |
@@ -380,19 +371,19 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
380 | /* If this is not the last fragment, then add the MOREFRAGS | 371 | /* If this is not the last fragment, then add the MOREFRAGS |
381 | * bit to the frame control */ | 372 | * bit to the frame control */ |
382 | if (i != nr_frags - 1) { | 373 | if (i != nr_frags - 1) { |
383 | frag_hdr->frame_ctl = cpu_to_le16( | 374 | frag_hdr->frame_ctl = |
384 | fc | IEEE80211_FCTL_MOREFRAGS); | 375 | cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS); |
385 | bytes = bytes_per_frag; | 376 | bytes = bytes_per_frag; |
386 | } else { | 377 | } else { |
387 | /* The last fragment takes the remaining length */ | 378 | /* The last fragment takes the remaining length */ |
388 | bytes = bytes_last_frag; | 379 | bytes = bytes_last_frag; |
389 | } | 380 | } |
390 | 381 | ||
391 | /* Put a SNAP header on the first fragment */ | 382 | /* Put a SNAP header on the first fragment */ |
392 | if (i == 0) { | 383 | if (i == 0) { |
393 | ieee80211_put_snap( | 384 | ieee80211_put_snap(skb_put |
394 | skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), | 385 | (skb_frag, SNAP_SIZE + sizeof(u16)), |
395 | ether_type); | 386 | ether_type); |
396 | bytes -= SNAP_SIZE + sizeof(u16); | 387 | bytes -= SNAP_SIZE + sizeof(u16); |
397 | } | 388 | } |
398 | 389 | ||
@@ -410,14 +401,13 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
410 | skb_put(skb_frag, 4); | 401 | skb_put(skb_frag, 4); |
411 | } | 402 | } |
412 | 403 | ||
413 | 404 | success: | |
414 | success: | ||
415 | spin_unlock_irqrestore(&ieee->lock, flags); | 405 | spin_unlock_irqrestore(&ieee->lock, flags); |
416 | 406 | ||
417 | dev_kfree_skb_any(skb); | 407 | dev_kfree_skb_any(skb); |
418 | 408 | ||
419 | if (txb) { | 409 | if (txb) { |
420 | if ((*ieee->hard_start_xmit)(txb, dev) == 0) { | 410 | if ((*ieee->hard_start_xmit) (txb, dev) == 0) { |
421 | stats->tx_packets++; | 411 | stats->tx_packets++; |
422 | stats->tx_bytes += txb->payload_size; | 412 | stats->tx_bytes += txb->payload_size; |
423 | return 0; | 413 | return 0; |
@@ -427,7 +417,7 @@ int ieee80211_xmit(struct sk_buff *skb, | |||
427 | 417 | ||
428 | return 0; | 418 | return 0; |
429 | 419 | ||
430 | failed: | 420 | failed: |
431 | spin_unlock_irqrestore(&ieee->lock, flags); | 421 | spin_unlock_irqrestore(&ieee->lock, flags); |
432 | netif_stop_queue(dev); | 422 | netif_stop_queue(dev); |
433 | stats->tx_errors++; | 423 | stats->tx_errors++; |