rt2x00: fix beacon reset on rt2800
authorHelmut Schaa <helmut.schaa@googlemail.com>
Tue, 29 Jun 2010 19:48:06 +0000 (21:48 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 30 Jun 2010 19:00:52 +0000 (15:00 -0400)
When an interface is removed the according beacon entry should be reset.
The current approach to only clear the first word is not enough to stop
the device from sending out the beacon, hence resulting in beacons being
sent out for already removed interfaces.

Fix this by invalidating the entire TXWI in front of the beacon instead
of only the first word.

Also clear all beacons during startup in the same way.

Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2800lib.c

index f7e9e7635303d5d01541275c44f5873f6cf1b86f..5125315abf50497170493d7103ed7ee11a9fe474 100644 (file)
@@ -432,6 +432,20 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 }
 EXPORT_SYMBOL(rt2800_write_beacon);
 
+static void inline rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
+                                      unsigned int beacon_base)
+{
+       int i;
+
+       /*
+        * For the Beacon base registers we only need to clear
+        * the whole TXWI which (when set to 0) will invalidate
+        * the entire beacon.
+        */
+       for (i = 0; i < TXWI_DESC_SIZE; i += sizeof(__le32))
+               rt2800_register_write(rt2x00dev, beacon_base + i, 0);
+}
+
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 const struct rt2x00debug rt2800_rt2x00debug = {
        .owner  = THIS_MODULE,
@@ -733,19 +747,14 @@ EXPORT_SYMBOL_GPL(rt2800_config_filter);
 void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
                        struct rt2x00intf_conf *conf, const unsigned int flags)
 {
-       unsigned int beacon_base;
        u32 reg;
 
        if (flags & CONFIG_UPDATE_TYPE) {
                /*
                 * Clear current synchronisation setup.
-                * For the Beacon base registers we only need to clear
-                * the first byte since that byte contains the VALID and OWNER
-                * bits which (when set to 0) will invalidate the entire beacon.
                 */
-               beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
-               rt2800_register_write(rt2x00dev, beacon_base, 0);
-
+               rt2800_clear_beacon(rt2x00dev,
+                                   HW_BEACON_OFFSET(intf->beacon->entry_idx));
                /*
                 * Enable synchronisation.
                 */
@@ -1565,18 +1574,15 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 
        /*
         * Clear all beacons
-        * For the Beacon base registers we only need to clear
-        * the first byte since that byte contains the VALID and OWNER
-        * bits which (when set to 0) will invalidate the entire beacon.
         */
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
-       rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE0);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE1);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE2);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE3);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE4);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE5);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE6);
+       rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE7);
 
        if (rt2x00_is_usb(rt2x00dev)) {
                rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg);