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.
next 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).