diff options
-rw-r--r-- | include/net/ieee80211.h | 2 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_module.c | 1 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 41 |
3 files changed, 41 insertions, 3 deletions
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index ebe7e41e5eaf..5e11ccf8a763 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h | |||
@@ -690,6 +690,7 @@ enum ieee80211_state { | |||
690 | 690 | ||
691 | #define CFG_IEEE80211_RESERVE_FCS (1<<0) | 691 | #define CFG_IEEE80211_RESERVE_FCS (1<<0) |
692 | #define CFG_IEEE80211_COMPUTE_FCS (1<<1) | 692 | #define CFG_IEEE80211_COMPUTE_FCS (1<<1) |
693 | #define CFG_IEEE80211_RTS (1<<2) | ||
693 | 694 | ||
694 | struct ieee80211_device { | 695 | struct ieee80211_device { |
695 | struct net_device *dev; | 696 | struct net_device *dev; |
@@ -747,6 +748,7 @@ struct ieee80211_device { | |||
747 | struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN]; | 748 | struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN]; |
748 | unsigned int frag_next_idx; | 749 | unsigned int frag_next_idx; |
749 | u16 fts; /* Fragmentation Threshold */ | 750 | u16 fts; /* Fragmentation Threshold */ |
751 | u16 rts; /* RTS threshold */ | ||
750 | 752 | ||
751 | /* Association info */ | 753 | /* Association info */ |
752 | u8 bssid[ETH_ALEN]; | 754 | u8 bssid[ETH_ALEN]; |
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index 82a4fd713b28..67d6bdd2e3f2 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c | |||
@@ -126,6 +126,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
126 | 126 | ||
127 | /* Default fragmentation threshold is maximum payload size */ | 127 | /* Default fragmentation threshold is maximum payload size */ |
128 | ieee->fts = DEFAULT_FTS; | 128 | ieee->fts = DEFAULT_FTS; |
129 | ieee->rts = DEFAULT_FTS; | ||
129 | ieee->scan_age = DEFAULT_MAX_SCAN_AGE; | 130 | ieee->scan_age = DEFAULT_MAX_SCAN_AGE; |
130 | ieee->open_wep = 1; | 131 | ieee->open_wep = 1; |
131 | 132 | ||
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) |