rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions.
authorGertjan van Wingerde <gwingerde@gmail.com>
Thu, 13 May 2010 19:16:03 +0000 (21:16 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 24 May 2010 19:07:41 +0000 (15:07 -0400)
(Based on a patch created by Ondrej Zary)

In some circumstances the Ralink devices do not properly go to sleep
or wake up, with timeouts occurring.
Fix this by retrying telling the device that it has to wake up or
sleep.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c

index 4ba7b038928fa1a0108c84319f2aa85b2a6054c6..ad2c98af7e9d62090dd54837206d07bcd23675a6 100644 (file)
@@ -926,7 +926,7 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
                               enum dev_state state)
 {
-       u32 reg;
+       u32 reg, reg2;
        unsigned int i;
        char put_to_sleep;
        char bbp_state;
@@ -947,11 +947,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
         * device has entered the correct state.
         */
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2x00pci_register_read(rt2x00dev, PWRCSR1, &reg);
-               bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE);
-               rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE);
+               rt2x00pci_register_read(rt2x00dev, PWRCSR1, &reg2);
+               bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
+               rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
                if (bbp_state == state && rf_state == state)
                        return 0;
+               rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
                msleep(10);
        }
 
index 89d132d4af1276e11ccf451004c00a3aa6e71fb2..41da3d218c65e343b5ded898ad5cee89257e4201 100644 (file)
@@ -1084,7 +1084,7 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
                               enum dev_state state)
 {
-       u32 reg;
+       u32 reg, reg2;
        unsigned int i;
        char put_to_sleep;
        char bbp_state;
@@ -1105,11 +1105,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
         * device has entered the correct state.
         */
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2x00pci_register_read(rt2x00dev, PWRCSR1, &reg);
-               bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE);
-               rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE);
+               rt2x00pci_register_read(rt2x00dev, PWRCSR1, &reg2);
+               bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
+               rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
                if (bbp_state == state && rf_state == state)
                        return 0;
+               rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
                msleep(10);
        }
 
index 2e3076f67535502b93bfbf7cde4b4cc2267521c0..6a74baf4e934b97e4ac3978341736790f18fb6e3 100644 (file)
@@ -1689,7 +1689,7 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 
 static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 {
-       u32 reg;
+       u32 reg, reg2;
        unsigned int i;
        char put_to_sleep;
 
@@ -1706,10 +1706,11 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
         * device has entered the correct state.
         */
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2x00pci_register_read(rt2x00dev, MAC_CSR12, &reg);
-               state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+               rt2x00pci_register_read(rt2x00dev, MAC_CSR12, &reg2);
+               state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
                if (state == !put_to_sleep)
                        return 0;
+               rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg);
                msleep(10);
        }
 
index e35bd19c3c5aeb09ffec25549bf4ef0d07064385..6e0d82efe9241802d8fdea54eacfe9f686437f0d 100644 (file)
@@ -1366,7 +1366,7 @@ static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 
 static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 {
-       u32 reg;
+       u32 reg, reg2;
        unsigned int i;
        char put_to_sleep;
 
@@ -1383,10 +1383,11 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
         * device has entered the correct state.
         */
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2x00usb_register_read(rt2x00dev, MAC_CSR12, &reg);
-               state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR12, &reg2);
+               state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
                if (state == !put_to_sleep)
                        return 0;
+               rt2x00usb_register_write(rt2x00dev, MAC_CSR12, reg);
                msleep(10);
        }