summaryrefslogtreecommitdiff
path: root/net/ieee80211/ieee80211_tx.c
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-09-21 20:54:43 +0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-22 07:02:30 +0400
commit3cdd00c5827621cd0b1bb0665aa62ef9a724297d (patch)
tree03d3a7cfa9fb645b052bac748c5398430ab2c9ca /net/ieee80211/ieee80211_tx.c
parentee34af37c095482b9dba254b9cd7cb5e65e9a25e (diff)
downloadlinux-3cdd00c5827621cd0b1bb0665aa62ef9a724297d.tar.xz
[PATCH] ieee80211: adds support for the creation of RTS packets
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>
Diffstat (limited to 'net/ieee80211/ieee80211_tx.c')
-rw-r--r--net/ieee80211/ieee80211_tx.c41
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,
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)