[PATCH 7/24] RT2x00: Add RTS frame creation

2006-07-26 Thread Ivo van Doorn
From Ivo van Doorn [EMAIL PROTECTED]

Support RTS.
When rts is required, create the frame and send it out
before the rest of the frames.

Signed-off-by: Ivo van Doorn [EMAIL PROTECTED]

---

diff -rU3 wireless-dev-txpower/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 
wireless-dev-rts/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-txpower/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 
2006-07-23 17:24:56.0 +0200
+++ wireless-dev-rts/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 
2006-07-23 
18:16:35.0 +0200
@@ -863,6 +863,36 @@
 }
 
 /*
+ * RTS frame creation.
+ */
+static struct sk_buff* rt2400pci_create_rts(struct rt2x00_dev *rt2x00dev,
+   struct ieee80211_hdr *hdr, unsigned short duration)
+{
+   struct ieee80211_hdr *ieee80211hdr;
+   struct sk_buff *skb;
+   u16 temp;
+
+   skb = dev_alloc_skb(IEEE80211_HEADER);
+   if (!skb)
+   return NULL;
+
+   /*
+* Copy the entire header over to RTS frame.
+*/
+   memcpy(skb_put(skb, IEEE80211_HEADER), hdr, IEEE80211_HEADER);
+   ieee80211hdr = (struct ieee80211_hdr*)skb-data;
+
+   temp = (WLAN_FC_TYPE_CTRL   2) | (WLAN_FC_STYPE_RTS  4);
+   ieee80211hdr-frame_control = cpu_to_le16(temp);
+
+   ieee80211hdr-duration_id += cpu_to_le16(duration);
+
+   ieee80211hdr-seq_ctrl = 0;
+
+   return skb;
+}
+
+/*
  * TX descriptor initialization
  */
 static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
@@ -876,15 +906,32 @@
u16 length_low;
u16 signal;
u16 service;
+   u16 frame_control;
+   u8 bitrate;
+   int tx_rate;
+
+   /*
+* Check which rate should be used for this frame.
+*/
+   frame_control = le16_to_cpu(ieee80211hdr-frame_control);
+   if (WLAN_FC_GET_STYPE(frame_control) == WLAN_FC_STYPE_RTS 
+   control-rts_cts_rate)
+   tx_rate = control-rts_cts_rate;
+   else
+   tx_rate = control-tx_rate;
 
rt2x00_set_field32(txd-word0, TXD_W0_VALID, 1);
rt2x00_set_field32(txd-word0, TXD_W0_ACK, !control-no_ack);
 
/*
-* TODO: IFS can be various values, where can we find
-* which one we want to use?
+* Set IFS to IFS_SIFS when the this is not the first fragment,
+* or this fragment came after RTS/CTS.
 */
-   rt2x00_set_field32(txd-word0, TXD_W0_IFS, 0);
+   if ((WLAN_GET_SEQ_FRAG(le16_to_cpu(ieee80211hdr-seq_ctrl))  0) ||
+   control-use_rts_cts)
+   rt2x00_set_field32(txd-word0, TXD_W0_IFS, IFS_SIFS);
+   else
+   rt2x00_set_field32(txd-word0, TXD_W0_IFS, IFS_BACKOFF);
 
if (control-queue == IEEE80211_TX_QUEUE_BEACON)
rt2x00_set_field32(txd-word0, TXD_W0_TIMESTAMP, 1);
@@ -896,16 +943,15 @@
 */
rt2x00_set_field32(txd-word0, TXD_W0_RETRY_MODE, 0);
 
-   if (ieee80211hdr-frame_control  WLAN_FC_MOREFRAG)
+   if (frame_control  WLAN_FC_MOREFRAG)
rt2x00_set_field32(txd-word0, TXD_W0_MORE_FRAG, 1);
else
rt2x00_set_field32(txd-word0, TXD_W0_MORE_FRAG, 0);
 
-   /*
-* TODO: Does this field mean device will send RTS, or that this
-* frame is an RTS frame?
-*/
-   rt2x00_set_field32(txd-word0, TXD_W0_RTS, control-use_rts_cts);
+   if (WLAN_FC_GET_STYPE(frame_control) == WLAN_FC_STYPE_RTS)
+   rt2x00_set_field32(txd-word10, TXD_W10_RTS, 1);
+   else
+   rt2x00_set_field32(txd-word10, TXD_W10_RTS, 0);
 
rt2x00_set_field32(txd-word2, TXD_W2_DATABYTE_COUNT, skb-len);
 
@@ -918,9 +964,9 @@
 * Convert length to microseconds.
 */
residual = get_duration_res(length,
-   DEVICE_GET_RATE_FIELD(control-tx_rate, RATE));
+   DEVICE_GET_RATE_FIELD(tx_rate, RATE));
length = get_duration(length,
-   DEVICE_GET_RATE_FIELD(control-tx_rate, RATE));
+   DEVICE_GET_RATE_FIELD(tx_rate, RATE));
 
if (residual)
length++;
@@ -938,8 +984,8 @@
length_high = 0x8000 | 0x0700 | (length  8);
length_low = 0x8000 | 0x0800 | (length  0xff);
 
-   signal = 0x8500 | DEVICE_GET_RATE_FIELD(control-tx_rate, PLCP);
-   if (DEVICE_GET_RATE_FIELD(control-tx_rate, PREAMBLE))
+   signal = 0x8500 | DEVICE_GET_RATE_FIELD(tx_rate, PLCP);
+   if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE))
signal |= 0x0008;
 
service = 0x0600 | 0x0004;
@@ -1089,8 +1135,9 @@
entry-tx_status.retry_count = rt2x00_get_field32(
txd-word0, TXD_W0_RETRY_COUNT);
 
-   ieee80211_tx_status(ring-net_dev,
-   entry-skb, entry-tx_status);
+   if (!GET_FLAG(entry, ENTRY_RTS_FRAME))
+   ieee80211_tx_status(ring-net_dev,
+   entry-skb, entry-tx_status);
 

Re: [PATCH 7/24] RT2x00: Add RTS frame creation

2006-07-26 Thread Ivo van Doorn
From Ivo van Doorn [EMAIL PROTECTED]

Support RTS.
When rts is required, create the frame and send it out
before the rest of the frames.

Signed-off-by: Ivo van Doorn [EMAIL PROTECTED]

diff -rU3 wireless-dev-txpower/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 
wireless-dev-rts/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-txpower/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 
2006-07-23 17:24:56.0 +0200
+++ wireless-dev-rts/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 
2006-07-23 18:16:35.0 +0200
@@ -863,6 +863,36 @@
 }
 
 /*
+ * RTS frame creation.
+ */
+static struct sk_buff* rt2400pci_create_rts(struct rt2x00_dev *rt2x00dev,
+   struct ieee80211_hdr *hdr, unsigned short duration)
+{
+   struct ieee80211_hdr *ieee80211hdr;
+   struct sk_buff *skb;
+   u16 temp;
+
+   skb = dev_alloc_skb(IEEE80211_HEADER);
+   if (!skb)
+   return NULL;
+
+   /*
+* Copy the entire header over to RTS frame.
+*/
+   memcpy(skb_put(skb, IEEE80211_HEADER), hdr, IEEE80211_HEADER);
+   ieee80211hdr = (struct ieee80211_hdr*)skb-data;
+
+   temp = (WLAN_FC_TYPE_CTRL   2) | (WLAN_FC_STYPE_RTS  4);
+   ieee80211hdr-frame_control = cpu_to_le16(temp);
+
+   ieee80211hdr-duration_id += cpu_to_le16(duration);
+
+   ieee80211hdr-seq_ctrl = 0;
+
+   return skb;
+}
+
+/*
  * TX descriptor initialization
  */
 static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
@@ -876,15 +906,32 @@
u16 length_low;
u16 signal;
u16 service;
+   u16 frame_control;
+   u8 bitrate;
+   int tx_rate;
+
+   /*
+* Check which rate should be used for this frame.
+*/
+   frame_control = le16_to_cpu(ieee80211hdr-frame_control);
+   if (WLAN_FC_GET_STYPE(frame_control) == WLAN_FC_STYPE_RTS 
+   control-rts_cts_rate)
+   tx_rate = control-rts_cts_rate;
+   else
+   tx_rate = control-tx_rate;
 
rt2x00_set_field32(txd-word0, TXD_W0_VALID, 1);
rt2x00_set_field32(txd-word0, TXD_W0_ACK, !control-no_ack);
 
/*
-* TODO: IFS can be various values, where can we find
-* which one we want to use?
+* Set IFS to IFS_SIFS when the this is not the first fragment,
+* or this fragment came after RTS/CTS.
 */
-   rt2x00_set_field32(txd-word0, TXD_W0_IFS, 0);
+   if ((WLAN_GET_SEQ_FRAG(le16_to_cpu(ieee80211hdr-seq_ctrl))  0) ||
+   control-use_rts_cts)
+   rt2x00_set_field32(txd-word0, TXD_W0_IFS, IFS_SIFS);
+   else
+   rt2x00_set_field32(txd-word0, TXD_W0_IFS, IFS_BACKOFF);
 
if (control-queue == IEEE80211_TX_QUEUE_BEACON)
rt2x00_set_field32(txd-word0, TXD_W0_TIMESTAMP, 1);
@@ -896,16 +943,15 @@
 */
rt2x00_set_field32(txd-word0, TXD_W0_RETRY_MODE, 0);
 
-   if (ieee80211hdr-frame_control  WLAN_FC_MOREFRAG)
+   if (frame_control  WLAN_FC_MOREFRAG)
rt2x00_set_field32(txd-word0, TXD_W0_MORE_FRAG, 1);
else
rt2x00_set_field32(txd-word0, TXD_W0_MORE_FRAG, 0);
 
-   /*
-* TODO: Does this field mean device will send RTS, or that this
-* frame is an RTS frame?
-*/
-   rt2x00_set_field32(txd-word0, TXD_W0_RTS, control-use_rts_cts);
+   if (WLAN_FC_GET_STYPE(frame_control) == WLAN_FC_STYPE_RTS)
+   rt2x00_set_field32(txd-word10, TXD_W10_RTS, 1);
+   else
+   rt2x00_set_field32(txd-word10, TXD_W10_RTS, 0);
 
rt2x00_set_field32(txd-word2, TXD_W2_DATABYTE_COUNT, skb-len);
 
@@ -918,9 +964,9 @@
 * Convert length to microseconds.
 */
residual = get_duration_res(length,
-   DEVICE_GET_RATE_FIELD(control-tx_rate, RATE));
+   DEVICE_GET_RATE_FIELD(tx_rate, RATE));
length = get_duration(length,
-   DEVICE_GET_RATE_FIELD(control-tx_rate, RATE));
+   DEVICE_GET_RATE_FIELD(tx_rate, RATE));
 
if (residual)
length++;
@@ -938,8 +984,8 @@
length_high = 0x8000 | 0x0700 | (length  8);
length_low = 0x8000 | 0x0800 | (length  0xff);
 
-   signal = 0x8500 | DEVICE_GET_RATE_FIELD(control-tx_rate, PLCP);
-   if (DEVICE_GET_RATE_FIELD(control-tx_rate, PREAMBLE))
+   signal = 0x8500 | DEVICE_GET_RATE_FIELD(tx_rate, PLCP);
+   if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE))
signal |= 0x0008;
 
service = 0x0600 | 0x0004;
@@ -1089,8 +1135,9 @@
entry-tx_status.retry_count = rt2x00_get_field32(
txd-word0, TXD_W0_RETRY_COUNT);
 
-   ieee80211_tx_status(ring-net_dev,
-   entry-skb, entry-tx_status);
+   if (!GET_FLAG(entry, ENTRY_RTS_FRAME))
+   ieee80211_tx_status(ring-net_dev,
+   entry-skb, entry-tx_status);