All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Buesch <mb@bu3sch.de>
To: John Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org,
	Jouni Malinen <jkmaline@cc.hut.fi>,
	Johannes Berg <johannes@sipsolutions.net>
Subject: [PATCH #2] d80211: Add API to generate RTS and CTS-to-self frames
Date: Mon, 5 Feb 2007 17:26:09 +0100	[thread overview]
Message-ID: <200702051726.09556.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 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/include/linux/ieee80211.h	2007-02-05 17:21:13.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 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/include/net/d80211.h	2007-02-05 17:21:13.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,70 @@ 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_rts_duration - Get the duration field for an RTS frame
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @frame_len: the length of the frame that is going to be protected by the RTS.
+ * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ *
+ * If the RTS is generated in firmware, but the host system must provide
+ * the duration field, the low-level driver uses this function to receive
+ * the duration field value in little-endian byteorder.
+ */
+__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
+			      size_t frame_len,
+			      const struct ieee80211_tx_control *frame_txctl);
+
+/**
+ * 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_ctstoself_duration - Get the duration field for a CTS-to-self frame
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
+ * @frame_txctl: &struct ieee80211_tx_control of the frame.
+ *
+ * If the CTS-to-self is generated in firmware, but the host system must provide
+ * the duration field, the low-level driver uses this function to receive
+ * the duration field value in little-endian byteorder.
+ */
+__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
+				    size_t frame_len,
+				    const struct ieee80211_tx_control *frame_txctl);
+
+/**
  * 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 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/net/d80211/ieee80211.c	2007-02-05 17:21:13.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,91 @@ struct sk_buff * ieee80211_beacon_get(st
 }
 EXPORT_SYMBOL(ieee80211_beacon_get);
 
+__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
+			      size_t frame_len,
+			      const struct ieee80211_tx_control *frame_txctl)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+	struct ieee80211_rate *rate;
+	int short_preamble = local->short_preamble;
+	int erp;
+	u16 dur;
+
+	rate = &(local->curr_rates[frame_txctl->rts_rateidx]);
+	erp = !!(rate->flags & IEEE80211_RATE_ERP);
+
+	/* CTS duration */
+	dur = ieee80211_frame_duration(local, 10, rate->rate,
+				       erp, short_preamble);
+	/* Data frame duration */
+	dur += ieee80211_frame_duration(local, frame_len, rate->rate,
+					erp, short_preamble);
+	/* ACK duration */
+	dur += ieee80211_frame_duration(local, 10, rate->rate,
+					erp, short_preamble);
+
+	return cpu_to_le16(dur);
+}
+EXPORT_SYMBOL(ieee80211_rts_duration);
+
+
+__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
+				    size_t frame_len,
+				    const struct ieee80211_tx_control *frame_txctl)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+	struct ieee80211_rate *rate;
+	int short_preamble = local->short_preamble;
+	int erp;
+	u16 dur;
+
+	rate = &(local->curr_rates[frame_txctl->rts_rateidx]);
+	erp = !!(rate->flags & IEEE80211_RATE_ERP);
+
+	/* Data frame duration */
+	dur = ieee80211_frame_duration(local, frame_len, rate->rate,
+				       erp, short_preamble);
+	if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) {
+		/* ACK duration */
+		dur += ieee80211_frame_duration(local, 10, rate->rate,
+						erp, short_preamble);
+	}
+
+	return cpu_to_le16(dur);
+}
+EXPORT_SYMBOL(ieee80211_ctstoself_duration);
+
+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)
+{
+	const struct ieee80211_hdr *hdr = frame;
+	u16 fctl;
+
+	fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
+	rts->frame_control = cpu_to_le16(fctl);
+	rts->duration = ieee80211_rts_duration(hw, frame_len, frame_txctl);
+	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)
+{
+	const struct ieee80211_hdr *hdr = frame;
+	u16 fctl;
+
+	fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS;
+	cts->frame_control = cpu_to_le16(fctl);
+	cts->duration = ieee80211_ctstoself_duration(hw, frame_len, frame_txctl);
+	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 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/net/d80211/ieee80211_sta.c	2007-02-05 17:21:13.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 16:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-05 16:26 Michael Buesch [this message]
2007-02-08 19:44 ` [PATCH #2] d80211: Add API to generate RTS and CTS-to-self frames Jiri Benc
2007-02-09  5:57   ` 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=200702051726.09556.mb@bu3sch.de \
    --to=mb@bu3sch.de \
    --cc=jkmaline@cc.hut.fi \
    --cc=johannes@sipsolutions.net \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.