summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2400pci.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-03-09 22:42:59 +0100
committerJohn W. Linville <linville@tuxdriver.com>2008-03-13 16:02:35 -0400
commit8af244ccb14a4367568db11c5e78b45a4c2cf77e (patch)
tree350727822602b851dcc2d31ad7a64fe7c4528a88 /drivers/net/wireless/rt2x00/rt2400pci.c
parent3976ae6c2b09608cd6a13663737a6b219245b651 (diff)
downloadop-kernel-dev-8af244ccb14a4367568db11c5e78b45a4c2cf77e.zip
op-kernel-dev-8af244ccb14a4367568db11c5e78b45a4c2cf77e.tar.gz
rt2x00: Only disable beaconing just before beacon update
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c20
1 files changed, 13 insertions, 7 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, &reg);
- rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(&reg, CSR14_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00_set_field32(&reg, 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, &reg);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
rt2x00_set_field32(&reg, 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, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, 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.
OpenPOWER on IntegriCloud