diff options
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 29770cfefc3d..cdee41cefb26 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c | |||
@@ -222,13 +222,15 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, | |||
222 | return txb; | 222 | return txb; |
223 | } | 223 | } |
224 | 224 | ||
225 | /* SKBs are added to the ieee->tx_queue. */ | 225 | /* Incoming skb is converted to a txb which consist of |
226 | * a block of 802.11 fragment packets (stored as skbs) */ | ||
226 | int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | 227 | int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) |
227 | { | 228 | { |
228 | struct ieee80211_device *ieee = netdev_priv(dev); | 229 | struct ieee80211_device *ieee = netdev_priv(dev); |
229 | struct ieee80211_txb *txb = NULL; | 230 | struct ieee80211_txb *txb = NULL; |
230 | struct ieee80211_hdr_3addr *frag_hdr; | 231 | struct ieee80211_hdr_3addr *frag_hdr; |
231 | int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; | 232 | int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size, |
233 | rts_required; | ||
232 | unsigned long flags; | 234 | unsigned long flags; |
233 | struct net_device_stats *stats = &ieee->stats; | 235 | struct net_device_stats *stats = &ieee->stats; |
234 | int ether_type, encrypt, host_encrypt; | 236 | int ether_type, encrypt, host_encrypt; |
@@ -334,6 +336,13 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
334 | else | 336 | else |
335 | bytes_last_frag = bytes_per_frag; | 337 | bytes_last_frag = bytes_per_frag; |
336 | 338 | ||
339 | rts_required = (frag_size > ieee->rts | ||
340 | && ieee->config & CFG_IEEE80211_RTS); | ||
341 | if (rts_required) | ||
342 | nr_frags++; | ||
343 | else | ||
344 | bytes_last_frag = bytes_per_frag; | ||
345 | |||
337 | /* When we allocate the TXB we allocate enough space for the reserve | 346 | /* When we allocate the TXB we allocate enough space for the reserve |
338 | * and full fragment bytes (bytes_per_frag doesn't include prefix, | 347 | * and full fragment bytes (bytes_per_frag doesn't include prefix, |
339 | * postfix, header, FCS, etc.) */ | 348 | * postfix, header, FCS, etc.) */ |
@@ -346,7 +355,33 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) | |||
346 | txb->encrypted = encrypt; | 355 | txb->encrypted = encrypt; |
347 | txb->payload_size = bytes; | 356 | txb->payload_size = bytes; |
348 | 357 | ||
349 | for (i = 0; i < nr_frags; i++) { | 358 | if (rts_required) { |
359 | skb_frag = txb->fragments[0]; | ||
360 | frag_hdr = | ||
361 | (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len); | ||
362 | |||
363 | /* | ||
364 | * Set header frame_ctl to the RTS. | ||
365 | */ | ||
366 | header.frame_ctl = | ||
367 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); | ||
368 | memcpy(frag_hdr, &header, hdr_len); | ||
369 | |||
370 | /* | ||
371 | * Restore header frame_ctl to the original data setting. | ||
372 | */ | ||
373 | header.frame_ctl = cpu_to_le16(fc); | ||
374 | |||
375 | if (ieee->config & | ||
376 | (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) | ||
377 | skb_put(skb_frag, 4); | ||
378 | |||
379 | txb->rts_included = 1; | ||
380 | i = 1; | ||
381 | } else | ||
382 | i = 0; | ||
383 | |||
384 | for (; i < nr_frags; i++) { | ||
350 | skb_frag = txb->fragments[i]; | 385 | skb_frag = txb->fragments[i]; |
351 | 386 | ||
352 | if (host_encrypt) | 387 | if (host_encrypt) |