[PATCH] ieee80211: adds support for the creation of RTS packets
authorJames Ketrenos <jketreno@linux.intel.com>
Wed, 21 Sep 2005 16:54:43 +0000 (11:54 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Thu, 22 Sep 2005 03:02:30 +0000 (23:02 -0400)
tree b45c9c1017fd23216bfbe71e441aed9aa297fc84
parent 04aacdd71e904656a304d923bdcf57ad3bd2b254
author Ivo van Doorn <IvDoorn@gmail.com> 1124445405 -0500
committer James Ketrenos <jketreno@linux.intel.com> 1127313029 -0500

This patch adds support for the creation of RTS packets when the
config flag CFG_IEEE80211_RTS has been set.

Signed-Off-By: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
include/net/ieee80211.h
net/ieee80211/ieee80211_module.c
net/ieee80211/ieee80211_tx.c

index ebe7e41e5eaf11eb71b9672109ecb4607bd16375..5e11ccf8a7631cffaa1848c1d3aecdd92c7cf411 100644 (file)
@@ -690,6 +690,7 @@ enum ieee80211_state {
 
 #define CFG_IEEE80211_RESERVE_FCS (1<<0)
 #define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
 
 struct ieee80211_device {
        struct net_device *dev;
@@ -747,6 +748,7 @@ struct ieee80211_device {
        struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
        unsigned int frag_next_idx;
        u16 fts;                /* Fragmentation Threshold */
+       u16 rts;                /* RTS threshold */
 
        /* Association info */
        u8 bssid[ETH_ALEN];
index 82a4fd713b28ecff29b8ae9d2ad84f1c4f0f7858..67d6bdd2e3f24ad8e32b55811e7722dfc55e15af 100644 (file)
@@ -126,6 +126,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
        /* Default fragmentation threshold is maximum payload size */
        ieee->fts = DEFAULT_FTS;
+       ieee->rts = DEFAULT_FTS;
        ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
        ieee->open_wep = 1;
 
index 29770cfefc3d7041c8d1ec157c949242a23a389e..cdee41cefb263dbfdf1299796abc4b1be6025213 100644 (file)
@@ -222,13 +222,15 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
        return txb;
 }
 
-/* SKBs are added to the ieee->tx_queue. */
+/* Incoming skb is converted to a txb which consist of
+ * a block of 802.11 fragment packets (stored as skbs) */
 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
        struct ieee80211_txb *txb = NULL;
        struct ieee80211_hdr_3addr *frag_hdr;
-       int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
+       int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
+           rts_required;
        unsigned long flags;
        struct net_device_stats *stats = &ieee->stats;
        int ether_type, encrypt, host_encrypt;
@@ -334,6 +336,13 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        else
                bytes_last_frag = bytes_per_frag;
 
+       rts_required = (frag_size > ieee->rts
+                       && ieee->config & CFG_IEEE80211_RTS);
+       if (rts_required)
+               nr_frags++;
+       else
+               bytes_last_frag = bytes_per_frag;
+
        /* When we allocate the TXB we allocate enough space for the reserve
         * and full fragment bytes (bytes_per_frag doesn't include prefix,
         * postfix, header, FCS, etc.) */
@@ -346,7 +355,33 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        txb->encrypted = encrypt;
        txb->payload_size = bytes;
 
-       for (i = 0; i < nr_frags; i++) {
+       if (rts_required) {
+               skb_frag = txb->fragments[0];
+               frag_hdr =
+                   (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+
+               /*
+                * Set header frame_ctl to the RTS.
+                */
+               header.frame_ctl =
+                   cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+               memcpy(frag_hdr, &header, hdr_len);
+
+               /*
+                * Restore header frame_ctl to the original data setting.
+                */
+               header.frame_ctl = cpu_to_le16(fc);
+
+               if (ieee->config &
+                   (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+                       skb_put(skb_frag, 4);
+
+               txb->rts_included = 1;
+               i = 1;
+       } else
+               i = 0;
+
+       for (; i < nr_frags; i++) {
                skb_frag = txb->fragments[i];
 
                if (host_encrypt)