aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ieee80211.h2
-rw-r--r--net/ieee80211/ieee80211_module.c1
-rw-r--r--net/ieee80211/ieee80211_tx.c41
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
694struct ieee80211_device { 695struct 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) */
226int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) 227int 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)