linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michael Buesch <mb@bu3sch.de>
To: John Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH] d80211: Add API to generate RTS and CTS-to-self frames
Date: Mon, 5 Feb 2007 14:12:50 +0100	[thread overview]
Message-ID: <200702051412.50703.mb@bu3sch.de> (raw)

This adds API calls to generate RTS and CTS-to-self frames.
To be called if the device firmware requires the host to
generate RTS/CTS frames.

Signed-off-by: Michael Buesch <mb@bu3sch.de>

Index: bu3sch-wireless-dev/include/linux/ieee80211.h
===================================================================
--- bu3sch-wireless-dev.orig/include/linux/ieee80211.h	2007-02-05 13:59:34.000000000 +0100
+++ bu3sch-wireless-dev/include/linux/ieee80211.h	2007-02-05 14:01:30.000000000 +0100
@@ -189,6 +189,21 @@ struct ieee80211_mgmt {
 } __attribute__ ((packed));
 
 
+/* Control frames */
+struct ieee80211_rts {
+	__le16 frame_control;
+	__le16 duration;
+	__u8 ra[6];
+	__u8 ta[6];
+} __attribute__ ((packed));
+
+struct ieee80211_cts {
+	__le16 frame_control;
+	__le16 duration;
+	__u8 ra[6];
+} __attribute__ ((packed));
+
+
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
Index: bu3sch-wireless-dev/include/net/d80211.h
===================================================================
--- bu3sch-wireless-dev.orig/include/net/d80211.h	2007-02-05 13:59:34.000000000 +0100
+++ bu3sch-wireless-dev/include/net/d80211.h	2007-02-05 14:01:30.000000000 +0100
@@ -194,7 +194,6 @@ struct ieee80211_tx_control {
 #define IEEE80211_TXCTL_TKIP_NEW_PHASE1_KEY (1<<9)
 	u32 flags;			       /* tx control flags defined
 						* above */
-	u16 rts_cts_duration;	/* duration field for RTS/CTS frame */
 	u8 retry_limit;		/* 1 = only first attempt, 2 = one retry, .. */
 	u8 power_level;		/* per-packet transmit power level, in dBm */
 	u8 antenna_sel; 	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
@@ -208,7 +207,8 @@ struct ieee80211_tx_control {
 	u8 sw_retry_attempt;	/* number of times hw has tried to
 				 * transmit frame (not incl. hw retries) */
 
-	int rateidx; /* internal 80211.o rateidx */
+	int rateidx;		/* internal 80211.o rateidx */
+	int rts_rateidx;	/* internal 80211.o rateidx for RTS/CTS */
 	int alt_retry_rate; /* retry rate for the last retries, given as the
 			     * hw specific value for the rate (from
 			     * struct ieee80211_rate). To be used to limit
@@ -829,6 +829,42 @@ struct sk_buff *ieee80211_beacon_get(str
 				     struct ieee80211_tx_control *control);
 
 /**
+ * ieee80211_rts_get - RTS frame generation function
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @frame: pointer to the frame that is going to be protected by the RTS.
+ * @frame_len: the frame length (in octets).
+ * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ * @rts: The buffer where to store the RTS frame.
+ *
+ * If the RTS frames are generated by the host system (i.e., not in
+ * hardware/firmware), the low-level driver uses this function to receive
+ * the next RTS frame from the 802.11 code. The low-level is responsible
+ * for calling this function before and RTS frame is needed.
+ */
+void ieee80211_rts_get(struct ieee80211_hw *hw,
+		       const void *frame, size_t frame_len,
+		       const struct ieee80211_tx_control *frame_txctl,
+		       struct ieee80211_rts *rts);
+
+/**
+ * ieee80211_ctstoself_get - CTS-to-self frame generation function
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @frame: pointer to the frame that is going to be protected by the CTS-to-self.
+ * @frame_len: the frame length (in octets).
+ * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ * @cts: The buffer where to store the CTS-to-self frame.
+ *
+ * If the CTS-to-self frames are generated by the host system (i.e., not in
+ * hardware/firmware), the low-level driver uses this function to receive
+ * the next CTS-to-self frame from the 802.11 code. The low-level is responsible
+ * for calling this function before and CTS-to-self frame is needed.
+ */
+void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
+			     const void *frame, size_t frame_len,
+			     const struct ieee80211_tx_control *frame_txctl,
+			     struct ieee80211_cts *cts);
+
+/**
  * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames
  * @hw: pointer as obtained from ieee80211_alloc_hw().
  * @if_id: interface ID from &struct ieee80211_if_init_conf.
Index: bu3sch-wireless-dev/net/d80211/ieee80211.c
===================================================================
--- bu3sch-wireless-dev.orig/net/d80211/ieee80211.c	2007-02-05 13:59:34.000000000 +0100
+++ bu3sch-wireless-dev/net/d80211/ieee80211.c	2007-02-05 14:01:30.000000000 +0100
@@ -802,7 +802,6 @@ ieee80211_tx_h_misc(struct ieee80211_txr
 	if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
 	    (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
 		struct ieee80211_rate *rate;
-		int erp = tx->u.tx.rate->flags & IEEE80211_RATE_ERP;
 
 		/* Do not use multiple retry rates when using RTS/CTS */
 		control->alt_retry_rate = -1;
@@ -813,16 +812,8 @@ ieee80211_tx_h_misc(struct ieee80211_txr
 		       !(rate->flags & IEEE80211_RATE_BASIC))
 			rate--;
 
-		if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
-			dur += ieee80211_frame_duration(tx->local, 10,
-							rate->rate, erp,
-							tx->local->
-							short_preamble);
-		dur += ieee80211_frame_duration(tx->local, tx->skb->len,
-						tx->u.tx.rate->rate, erp,
-						tx->u.tx.short_preamble);
-		control->rts_cts_duration = dur;
 		control->rts_cts_rate = rate->val;
+		control->rts_rateidx = (int)(rate - tx->local->curr_rates);
 	}
 
 	if (tx->sta) {
@@ -1781,7 +1772,6 @@ struct sk_buff * ieee80211_beacon_get(st
 		control->power_level = local->hw.conf.power_level;
 		control->flags |= IEEE80211_TXCTL_NO_ACK;
 		control->retry_limit = 1;
-		control->rts_cts_duration = 0;
 		control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
 	}
 
@@ -1790,6 +1780,87 @@ struct sk_buff * ieee80211_beacon_get(st
 }
 EXPORT_SYMBOL(ieee80211_beacon_get);
 
+static u16 ieee80211_rts_duration(struct ieee80211_local *local,
+				  size_t frame_len, int rate,
+				  int erp, int short_preamble)
+{
+	u16 dur;
+
+	/* Data frame duration */
+	dur = ieee80211_frame_duration(local, frame_len, rate, erp, short_preamble);
+	/* ACK duration */
+	dur += ieee80211_frame_duration(local, 14, rate, erp, short_preamble);
+	/* CTS duration */
+	dur += ieee80211_frame_duration(local, 14, rate, erp, short_preamble);
+
+	return dur;
+}
+
+static u16 ieee80211_ctstoself_duration(struct ieee80211_local *local,
+					size_t frame_len, int rate,
+					int erp, int short_preamble,
+					int data_requires_ack)
+{
+	u16 dur;
+
+	/* Data frame duration */
+	dur = ieee80211_frame_duration(local, frame_len, rate, erp, short_preamble);
+	if (data_requires_ack) {
+		/* ACK duration */
+		dur += ieee80211_frame_duration(local, 14, rate, erp, short_preamble);
+	}
+
+	return dur;
+}
+
+void ieee80211_rts_get(struct ieee80211_hw *hw,
+		       const void *frame, size_t frame_len,
+		       const struct ieee80211_tx_control *frame_txctl,
+		       struct ieee80211_rts *rts)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+	const struct ieee80211_hdr *hdr = frame;
+	struct ieee80211_rate *rate;
+	u16 fctl;
+	u16 duration;
+
+	fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
+	rate = &(local->curr_rates[frame_txctl->rts_rateidx]);
+	duration = ieee80211_rts_duration(local, frame_len, rate->rate,
+					  !!(rate->flags & IEEE80211_RATE_ERP),
+					  local->short_preamble);
+
+	rts->frame_control = cpu_to_le16(fctl);
+	rts->duration = cpu_to_le16(duration);
+	memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
+	memcpy(rts->ta, hdr->addr2, sizeof(rts->ta));
+}
+EXPORT_SYMBOL(ieee80211_rts_get);
+
+void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
+			     const void *frame, size_t frame_len,
+			     const struct ieee80211_tx_control *frame_txctl,
+			     struct ieee80211_cts *cts)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+	const struct ieee80211_hdr *hdr = frame;
+	struct ieee80211_rate *rate;
+	u16 fctl;
+	u16 duration;
+
+	fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS;
+	rate = &(local->curr_rates[frame_txctl->rts_rateidx]);
+	duration = ieee80211_ctstoself_duration(local, frame_len, rate->rate,
+						!!(rate->flags & IEEE80211_RATE_ERP),
+						local->short_preamble,
+						!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK));
+
+	cts->frame_control = cpu_to_le16(fctl);
+	cts->duration = cpu_to_le16(duration);
+	memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
+}
+EXPORT_SYMBOL(ieee80211_ctstoself_get);
+
 struct sk_buff *
 ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
 			  struct ieee80211_tx_control *control)
Index: bu3sch-wireless-dev/net/d80211/ieee80211_sta.c
===================================================================
--- bu3sch-wireless-dev.orig/net/d80211/ieee80211_sta.c	2007-02-05 13:59:34.000000000 +0100
+++ bu3sch-wireless-dev/net/d80211/ieee80211_sta.c	2007-02-05 14:01:30.000000000 +0100
@@ -2068,7 +2068,6 @@ static int ieee80211_sta_join_ibss(struc
 		control.power_level = local->hw.conf.power_level;
 		control.flags |= IEEE80211_TXCTL_NO_ACK;
 		control.retry_limit = 1;
-		control.rts_cts_duration = 0;
 
 		ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
 		if (ifsta->probe_resp) {


-- 
Greetings Michael.

             reply	other threads:[~2007-02-05 13:18 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-05 13:12 Michael Buesch [this message]
2007-02-05 13:14 ` [PATCH] bcm43xx-d80211: Use d80211 API to generate RTS/CTS frames Michael Buesch
2007-02-05 13:15 ` [PATCH] rt2x00-d80211: " Michael Buesch
2007-02-05 13:31 ` [PATCH] d80211: Add API to generate RTS and CTS-to-self frames Michael Buesch
2007-02-05 13:43 ` Johannes Berg
2007-02-05 13:53   ` Michael Buesch
2007-02-05 14:58 ` Jouni Malinen
2007-02-05 15:28   ` Michael Buesch
2007-02-05 16:47     ` Jouni Malinen
2007-02-05 16:53       ` Michael Buesch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200702051412.50703.mb@bu3sch.de \
    --to=mb@bu3sch.de \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).