From: Ivo van Doorn <ivdoorn@gmail.com>
To: "John W. Linville" <linville@redhat.com>
Cc: "linux-wireless" <linux-wireless@vger.kernel.org>,
rt2400-devel@lists.sourceforge.net
Subject: [PATCH 09/24] rt2x00: Only disable beaconing just before beacon update
Date: Sun, 9 Mar 2008 22:42:59 +0100 [thread overview]
Message-ID: <200803092242.59261.IvDoorn@gmail.com> (raw)
In-Reply-To: <200803092237.43451.IvDoorn@gmail.com>
We should not write 0 to the beacon sync register during
config_intf() since that will clear out the beacon interval
and forces the beacon to be send out at the lowest interval.
(reported by Mattias Nissler).
The side effect of the same bug was that while working with
multiple virtual AP interfaces a change for any of those
interfaces would disable beaconing untill an beacon update
was provided.
This is resolved by only updating the TSF_SYNC value during
config_intf(). In update_beacon() we disable beaconing
temporarily to prevent fake beacons to be transmitted.
Finally kick_tx_queue() will enable beaconing again.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 20 +++++++++++++-------
drivers/net/wireless/rt2x00/rt2500pci.c | 19 +++++++++++++------
drivers/net/wireless/rt2x00/rt2500usb.c | 19 +++++++++++++------
drivers/net/wireless/rt2x00/rt61pci.c | 18 +++++++++++++-----
drivers/net/wireless/rt2x00/rt73usb.c | 18 +++++++++++++-----
5 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 460ef2f..a1c38a1 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -279,8 +279,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
u32 reg;
if (flags & CONFIG_UPDATE_TYPE) {
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
* Enable beacon config
*/
@@ -293,10 +291,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
- rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(®, CSR14_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1040,6 +1034,8 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
if (queue == RT2X00_BCN_QUEUE_BEACON) {
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
+ rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(®, CSR14_TBCN, 1);
rt2x00_set_field32(®, CSR14_BEACON_GEN, 1);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1517,10 +1513,10 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_intf *intf = vif_to_intf(control->vif);
struct queue_entry_priv_pci_tx *priv_tx;
struct skb_frame_desc *skbdesc;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
-
priv_tx = intf->beacon->priv_data;
/*
@@ -1536,6 +1532,16 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, CSR14, ®);
+ rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(®, CSR14_TBCN, 0);
+ rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index ffcd996..0962327 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -281,8 +281,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
u32 reg;
if (flags & CONFIG_UPDATE_TYPE) {
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
* Enable beacon config
*/
@@ -296,10 +294,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
- rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(®, CSR14_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1193,6 +1187,8 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
if (queue == RT2X00_BCN_QUEUE_BEACON) {
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
+ rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(®, CSR14_TBCN, 1);
rt2x00_set_field32(®, CSR14_BEACON_GEN, 1);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1828,6 +1824,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_intf *intf = vif_to_intf(control->vif);
struct queue_entry_priv_pci_tx *priv_tx;
struct skb_frame_desc *skbdesc;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -1847,6 +1844,16 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, CSR14, ®);
+ rt2x00_set_field32(®, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(®, CSR14_TBCN, 0);
+ rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 559131f..b6c6f7d 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -324,8 +324,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
u16 reg;
if (flags & CONFIG_UPDATE_TYPE) {
- rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);
-
/*
* Enable beacon config
*/
@@ -344,10 +342,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
- rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1);
- rt2x00_set_field16(®, TXRX_CSR19_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0);
rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
}
@@ -1092,6 +1086,8 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
+ rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1);
+ rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1);
rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1);
/*
* Beacon generation will fail initially.
@@ -1740,6 +1736,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
struct skb_frame_desc *skbdesc;
int pipe = usb_sndbulkpipe(usb_dev, 1);
int length;
+ u16 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -1765,6 +1762,16 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
+ rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0);
+ rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0);
+ rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 9ff7e60..9d8d096 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -336,17 +336,12 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
* bits which (when set to 0) will invalidate the entire beacon.
*/
beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
rt2x00pci_register_write(rt2x00dev, beacon_base, 0);
/*
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
- rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1562,6 +1557,8 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -2373,6 +2370,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_intf *intf = vif_to_intf(control->vif);
struct skb_frame_desc *skbdesc;
unsigned int beacon_base;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -2408,6 +2406,16 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4506423..d0c0fde 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -347,17 +347,12 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
* bits which (when set to 0) will invalidate the entire beacon.
*/
beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
- rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0);
rt73usb_register_write(rt2x00dev, beacon_base, 0);
/*
* Enable synchronisation.
*/
rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
- rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync);
rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1312,6 +1307,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);
rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1987,6 +1984,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct skb_frame_desc *skbdesc;
unsigned int beacon_base;
unsigned int timeout;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -2010,6 +2008,16 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
+ rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
--
1.5.4.3
next prev parent reply other threads:[~2008-03-09 21:50 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-09 21:37 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2008-03-09 21:38 ` [PATCH 01/24] rt2x00: Align RX descriptor to 4 bytes Ivo van Doorn
2008-03-09 21:38 ` [PATCH 02/24] rt2x00: Initialize TX control field in data entries Ivo van Doorn
2008-03-09 21:39 ` [PATCH 03/24] rt2x00: Use the correct size when copying the control info in txdone Ivo van Doorn
2008-03-09 21:40 ` [PATCH 04/24] rt2x00: Don't use uninitialized desc_len Ivo van Doorn
2008-03-09 21:40 ` [PATCH 05/24] rt2x00: never disable multicast because it disables broadcast too Ivo van Doorn
2008-03-09 21:41 ` [PATCH 06/24] rt2x00: Don't use unitialized rxdesc->size Ivo van Doorn
2008-03-09 21:41 ` [PATCH 07/24] rt2x00: Use skbdesc fields for descriptor initialization Ivo van Doorn
2008-03-09 21:42 ` [PATCH 08/24] rt2x00: Add new D-Link USB ID Ivo van Doorn
2008-03-09 21:42 ` Ivo van Doorn [this message]
2008-03-09 21:43 ` [PATCH 10/24] rt2x00:correct rx packet length for USB devices Ivo van Doorn
2008-03-09 21:43 ` [PATCH 11/24] rt2x00: Fix trivial log message Ivo van Doorn
2008-03-09 21:44 ` [PATCH 12/24] rt2x00: Upgrade queue->lock to use irqsave Ivo van Doorn
2008-03-09 21:44 ` [PATCH 13/24] rt2x00: Move firmware checksumming to driver Ivo van Doorn
2008-03-09 21:45 ` [PATCH 14/24] rt2x00: Start bugging when rt2x00lib doesn't filter SW diversity Ivo van Doorn
2008-03-09 21:45 ` [PATCH 15/24] rt2x00: Check IEEE80211_TXCTL_SEND_AFTER_DTIM flag Ivo van Doorn
2008-03-09 21:46 ` [PATCH 16/24] rt2x00: Rename config_preamble() to config_erp() Ivo van Doorn
2008-03-09 21:46 ` [PATCH 17/24] rt2x00: Add suspend/resume handlers to rt2x00rfkill Ivo van Doorn
2008-03-09 21:47 ` [PATCH 18/24] rt2x00: Make rt2x00leds_register return void Ivo van Doorn
2008-03-09 21:47 ` [PATCH 19/24] rt2x00: Always enable TSF ticking Ivo van Doorn
2008-03-09 21:48 ` [PATCH 20/24] rt2x00: Fix basic rate initialization Ivo van Doorn
2008-03-09 21:48 ` [PATCH 21/24] rt2x00: Fix compile error when rfkill is disabled Ivo van Doorn
2008-03-09 21:48 ` [PATCH 22/24] rt2x00: Fix RX DMA ring initialization Ivo van Doorn
2008-03-09 21:49 ` [PATCH 23/24] rt2x00: Fix rt2400pci signal Ivo van Doorn
2008-03-09 21:49 ` [PATCH 24/24] rt2x00: Release rt2x00 2.1.4 Ivo van Doorn
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=200803092242.59261.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@redhat.com \
--cc=rt2400-devel@lists.sourceforge.net \
/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).