* [PATCH #2] bcm43xx-d80211: Use d80211 API to generate RTS/CTS frames
[not found] <200702051723.50008.mb@bu3sch.de>
@ 2007-02-05 16:24 ` Michael Buesch
2007-02-05 16:25 ` [PATCH #2] rt2x00-d80211: " Michael Buesch
1 sibling, 0 replies; 2+ messages in thread
From: Michael Buesch @ 2007-02-05 16:24 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Use the new d80211 API to generate RTS and CTS-to-self frames.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Index: bu3sch-wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2007-02-05 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2007-02-05 17:21:17.000000000 +0100
@@ -198,85 +198,6 @@ __le16 bcm43xx_calc_duration(const struc
return duration_id;
}
-static inline
-u16 ceiling_div(u16 dividend, u16 divisor)
-{
- return ((dividend + divisor - 1) / divisor);
-}
-
-//TODO
-#if 0
-static void bcm43xx_generate_rts(const struct bcm43xx_phy *phy,
- struct bcm43xx_txhdr_fw3 *txhdr,
- u16 *flags,
- u8 bitrate,
- const struct ieee80211_hdr *wlhdr)
-{
- u16 fctl;
- u16 dur;
- u8 fallback_bitrate;
- int ofdm_modulation;
- int fallback_ofdm_modulation;
- u8 *sa, *da;
- u16 flen;
-
- sa = ieee80211_get_SA((struct ieee80211_hdr *)wlhdr);
- da = ieee80211_get_DA((struct ieee80211_hdr *)wlhdr);
- fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);
- ofdm_modulation = !(bcm43xx_is_cck_rate(bitrate));
- fallback_ofdm_modulation = !(bcm43xx_is_cck_rate(fallback_bitrate));
-
- flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + FCS_LEN,
- bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp),
- flen, bitrate);
- bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp),
- flen, fallback_bitrate);
- fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
- dur = le16_to_cpu(wlhdr->duration_id);
-/*FIXME: should we test for dur==0 here and let it unmodified in this case?
- * The following assert checks for this case...
- */
-assert(dur);
-/*FIXME: The duration calculation is not really correct.
- * I am not 100% sure which bitrate to use. We use the RTS rate here,
- * but this is likely to be wrong.
- */
- if (phy->type == BCM43xx_PHYTYPE_A) {
- /* Three times SIFS */
- dur += 16 * 3;
- /* Add ACK duration. */
- dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10,
- bitrate * 4);
- /* Add CTS duration. */
- dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10,
- bitrate * 4);
- } else {
- /* Three times SIFS */
- dur += 10 * 3;
- /* Add ACK duration. */
- dur += ceiling_div(8 * (14 /*bytes*/) * 10,
- bitrate);
- /* Add CTS duration. */
- dur += ceiling_div(8 * (14 /*bytes*/) * 10,
- bitrate);
- }
-
- txhdr->rts_cts_frame_control = cpu_to_le16(fctl);
- txhdr->rts_cts_dur = cpu_to_le16(dur);
-//printk(MAC_FMT " " MAC_FMT " " MAC_FMT "\n", MAC_ARG(wlhdr->addr1), MAC_ARG(wlhdr->addr2), MAC_ARG(wlhdr->addr3));
-//printk(MAC_FMT " " MAC_FMT "\n", MAC_ARG(sa), MAC_ARG(da));
- memcpy(txhdr->rts_cts_mac1, wlhdr->addr1, ETH_ALEN);//FIXME!
- memcpy(txhdr->rts_cts_mac2, sa, ETH_ALEN);
-
- *flags |= BCM43xx_TXHDRFLAG_RTSCTS;
- *flags |= BCM43xx_TXHDRFLAG_RTS;
- if (ofdm_modulation)
- *flags |= BCM43xx_TXHDRFLAG_RTSCTS_OFDM;
- if (fallback_ofdm_modulation)
- *flags |= BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM;
-}
-#endif
-
static void generate_txhdr_fw4(struct bcm43xx_wldev *dev,
struct bcm43xx_txhdr_fw4 *txhdr,
const unsigned char *fragment_data,
@@ -307,7 +228,6 @@ static void generate_txhdr_fw4(struct bc
txhdr->phy_rate = bcm43xx_plcp_get_ratecode_ofdm(rate);
else
txhdr->phy_rate = bcm43xx_plcp_get_ratecode_cck(rate);
- //TODO RTS phyrate
txhdr->mac_frame_ctl = wlhdr->frame_control;
memcpy(txhdr->tx_receiver, wlhdr->addr1, 6);
txhdr->dur_fb = bcm43xx_calc_duration(wlhdr, rate_fb);
@@ -386,8 +306,47 @@ static void generate_txhdr_fw4(struct bc
if (phy->type == BCM43xx_PHYTYPE_A)
mac_ctl |= BCM43xx_TX4_MAC_5GHZ;
- if (txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- //TODO
+ /* Generate the RTS or CTS-to-self frame */
+ if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
+ (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+ unsigned int len;
+ struct ieee80211_hdr *hdr;
+ int rts_rate, rts_rate_fb;
+ int rts_rate_ofdm, rts_rate_fb_ofdm;
+
+ rts_rate = txctl->rts_cts_rate;
+ rts_rate_ofdm = bcm43xx_is_ofdm_rate(rts_rate);
+ rts_rate_fb = bcm43xx_calc_fallback_rate(rts_rate);
+ rts_rate_fb_ofdm = bcm43xx_is_ofdm_rate(rts_rate_fb);
+
+ if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+ ieee80211_ctstoself_get(dev->wl->hw,
+ fragment_data, fragment_len, txctl,
+ (struct ieee80211_cts *)(txhdr->rts_frame));
+ mac_ctl |= BCM43xx_TX4_MAC_SENDCTS;
+ len = sizeof(struct ieee80211_cts);
+ } else {
+ ieee80211_rts_get(dev->wl->hw,
+ fragment_data, fragment_len, txctl,
+ (struct ieee80211_rts *)(txhdr->rts_frame));
+ mac_ctl |= BCM43xx_TX4_MAC_SENDRTS;
+ len = sizeof(struct ieee80211_rts);
+ }
+ len += FCS_LEN;
+ bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_plcp),
+ len, rts_rate);
+ bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_plcp_fb),
+ len, rts_rate_fb);
+ hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame);
+ txhdr->rts_dur_fb = hdr->duration_id;
+ if (rts_rate_ofdm) {
+ extra_ft |= BCM43xx_TX4_EFT_RTSOFDM;
+ txhdr->phy_rate_rts = bcm43xx_plcp_get_ratecode_ofdm(rts_rate);
+ } else
+ txhdr->phy_rate_rts = bcm43xx_plcp_get_ratecode_cck(rts_rate);
+ if (rts_rate_fb_ofdm)
+ extra_ft |= BCM43xx_TX4_EFT_RTSFBOFDM;
+ mac_ctl |= BCM43xx_TX4_MAC_LONGFRAME;
}
/* Magic cookie */
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH #2] rt2x00-d80211: Use d80211 API to generate RTS/CTS frames
[not found] <200702051723.50008.mb@bu3sch.de>
2007-02-05 16:24 ` [PATCH #2] bcm43xx-d80211: Use d80211 API to generate RTS/CTS frames Michael Buesch
@ 2007-02-05 16:25 ` Michael Buesch
1 sibling, 0 replies; 2+ messages in thread
From: Michael Buesch @ 2007-02-05 16:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Use the new d80211 API to generate RTS and CTS-to-self frames.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Index: bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2007-02-05 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2007-02-05 17:21:21.000000000 +0100
@@ -1351,29 +1351,18 @@ static void rt2400pci_disable_radio(stru
/*
* RTS frame creation.
*/
-static struct sk_buff* rt2400pci_create_rts(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_hdr *hdr, unsigned short duration)
+static struct sk_buff* rt2400pci_create_rts(struct ieee80211_hw *hw,
+ struct sk_buff *frag_skb,
+ struct ieee80211_tx_control *control)
{
- struct ieee80211_hdr *ieee80211hdr;
struct sk_buff *skb;
- u16 frame_control;
- skb = dev_alloc_skb(IEEE80211_HEADER);
+ skb = dev_alloc_skb(sizeof(struct ieee80211_rts));
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;
-
- frame_control = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
- ieee80211hdr->frame_control = cpu_to_le16(frame_control);
-
- ieee80211hdr->duration_id = cpu_to_le16(duration);
-
- ieee80211hdr->seq_ctrl = 0;
+ skb_put(skb, sizeof(struct ieee80211_rts));
+ ieee80211_rts_get(hw, frag_skb->data, frag_skb->len, control,
+ (struct ieee80211_rts *)(skb->data));
return skb;
}
@@ -1785,8 +1774,7 @@ static int rt2400pci_tx(struct ieee80211
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
!is_rts_frame(frame_control)) {
- skb_rts = rt2400pci_create_rts(rt2x00dev,
- ieee80211hdr, control->rts_cts_duration);
+ skb_rts = rt2400pci_create_rts(hw, skb, control);
if (!skb_rts) {
WARNING("Failed to create RTS frame.\n");
return NETDEV_TX_BUSY;
Index: bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2007-02-05 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2007-02-05 17:21:21.000000000 +0100
@@ -1477,29 +1477,18 @@ static void rt2500pci_disable_radio(stru
/*
* RTS frame creation.
*/
-static struct sk_buff* rt2500pci_create_rts(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_hdr *hdr, unsigned short duration)
+static struct sk_buff* rt2500pci_create_rts(struct ieee80211_hw *hw,
+ struct sk_buff *frag_skb,
+ struct ieee80211_tx_control *control)
{
- struct ieee80211_hdr *ieee80211hdr;
struct sk_buff *skb;
- u16 frame_control;
- skb = dev_alloc_skb(IEEE80211_HEADER);
+ skb = dev_alloc_skb(sizeof(struct ieee80211_rts));
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;
-
- frame_control = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
- ieee80211hdr->frame_control = cpu_to_le16(frame_control);
-
- ieee80211hdr->duration_id = cpu_to_le16(duration);
-
- ieee80211hdr->seq_ctrl = 0;
+ skb_put(skb, sizeof(struct ieee80211_rts));
+ ieee80211_rts_get(hw, frag_skb->data, frag_skb->len, control,
+ (struct ieee80211_rts *)(skb->data));
return skb;
}
@@ -1949,8 +1938,7 @@ static int rt2500pci_tx(struct ieee80211
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
!is_rts_frame(frame_control)) {
- skb_rts = rt2500pci_create_rts(rt2x00dev,
- ieee80211hdr, control->rts_cts_duration);
+ skb_rts = rt2500pci_create_rts(hw, skb, control);
if (!skb_rts) {
WARNING("Failed to create RTS frame.\n");
return NETDEV_TX_BUSY;
Index: bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2007-02-05 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2007-02-05 17:21:21.000000000 +0100
@@ -1442,29 +1442,18 @@ static void rt2500usb_disable_radio(stru
/*
* RTS frame creation.
*/
-static struct sk_buff* rt2500usb_create_rts(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_hdr *hdr, unsigned short duration)
+static struct sk_buff* rt2500usb_create_rts(struct ieee80211_hw *hw,
+ struct sk_buff *frag_skb,
+ struct ieee80211_tx_control *control)
{
- struct ieee80211_hdr *ieee80211hdr;
struct sk_buff *skb;
- u16 frame_control;
- skb = dev_alloc_skb(IEEE80211_HEADER);
+ skb = dev_alloc_skb(sizeof(struct ieee80211_rts));
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;
-
- frame_control = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
- ieee80211hdr->frame_control = cpu_to_le16(frame_control);
-
- ieee80211hdr->duration_id = cpu_to_le16(duration);
-
- ieee80211hdr->seq_ctrl = 0;
+ skb_put(skb, sizeof(struct ieee80211_rts));
+ ieee80211_rts_get(hw, frag_skb->data, frag_skb->len, control,
+ (struct ieee80211_rts *)(skb->data));
return skb;
}
@@ -1882,8 +1871,7 @@ static int rt2500usb_tx(struct ieee80211
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
!is_rts_frame(frame_control)) {
- skb_rts = rt2500usb_create_rts(rt2x00dev,
- ieee80211hdr, control->rts_cts_duration);
+ skb_rts = rt2500usb_create_rts(hw, skb, control);
if (!skb_rts) {
WARNING("Failed to create RTS frame.\n");
return NETDEV_TX_BUSY;
Index: bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt61pci.c
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2007-02-05 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2007-02-05 17:21:21.000000000 +0100
@@ -1925,29 +1925,18 @@ static void rt61pci_disable_radio(struct
/*
* RTS frame creation.
*/
-static struct sk_buff* rt61pci_create_rts(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_hdr *hdr, unsigned short duration)
+static struct sk_buff* rt61pci_create_rts(struct ieee80211_hw *hw,
+ struct sk_buff *frag_skb,
+ struct ieee80211_tx_control *control)
{
- struct ieee80211_hdr *ieee80211hdr;
struct sk_buff *skb;
- u16 frame_control;
- skb = dev_alloc_skb(IEEE80211_HEADER);
+ skb = dev_alloc_skb(sizeof(struct ieee80211_rts));
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;
-
- frame_control = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
- ieee80211hdr->frame_control = cpu_to_le16(frame_control);
-
- ieee80211hdr->duration_id = cpu_to_le16(duration);
-
- ieee80211hdr->seq_ctrl = 0;
+ skb_put(skb, sizeof(struct ieee80211_rts));
+ ieee80211_rts_get(hw, frag_skb->data, frag_skb->len, control,
+ (struct ieee80211_rts *)(skb->data));
return skb;
}
@@ -2445,8 +2434,7 @@ static int rt61pci_tx(struct ieee80211_h
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
!is_rts_frame(frame_control)) {
- skb_rts = rt61pci_create_rts(rt2x00dev,
- ieee80211hdr, control->rts_cts_duration);
+ skb_rts = rt61pci_create_rts(hw, skb, control);
if (!skb_rts) {
WARNING("Failed to create RTS frame.\n");
return NETDEV_TX_BUSY;
Index: bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt73usb.c
===================================================================
--- bu3sch-wireless-dev.orig/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2007-02-05 17:21:09.000000000 +0100
+++ bu3sch-wireless-dev/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2007-02-05 17:21:21.000000000 +0100
@@ -1704,29 +1704,18 @@ static void rt73usb_disable_radio(struct
/*
* RTS frame creation.
*/
-static struct sk_buff* rt73usb_create_rts(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_hdr *hdr, unsigned short duration)
+static struct sk_buff* rt73usb_create_rts(struct ieee80211_hw *hw,
+ struct sk_buff *frag_skb,
+ struct ieee80211_tx_control *control)
{
- struct ieee80211_hdr *ieee80211hdr;
struct sk_buff *skb;
- u16 frame_control;
- skb = dev_alloc_skb(IEEE80211_HEADER);
+ skb = dev_alloc_skb(sizeof(struct ieee80211_rts));
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;
-
- frame_control = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
- ieee80211hdr->frame_control = cpu_to_le16(frame_control);
-
- ieee80211hdr->duration_id = cpu_to_le16(duration);
-
- ieee80211hdr->seq_ctrl = 0;
+ skb_put(skb, sizeof(struct ieee80211_rts));
+ ieee80211_rts_get(hw, frag_skb->data, frag_skb->len, control,
+ (struct ieee80211_rts *)(skb->data));
return skb;
}
@@ -2153,8 +2142,7 @@ static int rt73usb_tx(struct ieee80211_h
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) &&
!is_rts_frame(frame_control)) {
- skb_rts = rt73usb_create_rts(rt2x00dev,
- ieee80211hdr, control->rts_cts_duration);
+ skb_rts = rt73usb_create_rts(hw, skb, control);
if (!skb_rts) {
WARNING("Failed to create RTS frame.\n");
return NETDEV_TX_BUSY;
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-02-05 16:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <200702051723.50008.mb@bu3sch.de>
2007-02-05 16:24 ` [PATCH #2] bcm43xx-d80211: Use d80211 API to generate RTS/CTS frames Michael Buesch
2007-02-05 16:25 ` [PATCH #2] rt2x00-d80211: " Michael Buesch
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.