rt2800: change initialization sequence to fix system freeze
authorStanislaw Gruszka <sgruszka@redhat.com>
Mon, 9 Sep 2013 10:37:37 +0000 (12:37 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 9 Sep 2013 18:44:34 +0000 (14:44 -0400)
My commit

commit c630ccf1a127578421a928489d51e99c05037054
Author: Stanislaw Gruszka <stf_xl@wp.pl>
Date:   Sat Mar 16 19:19:46 2013 +0100

    rt2800: rearrange bbp/rfcsr initialization

make Maxim machine freeze when try to start wireless device.

Initialization order and sending MCU_BOOT_SIGNAL request, changed in
above commit, is important. Doing things incorrectly make PCIe bus
problems, which can froze the machine.

This patch change initialization sequence like vendor driver do:
function NICInitializeAsic() from
2011_1007_RT5390_RT5392_Linux_STA_V2.5.0.3_DPO (PCI devices) and
DPO_RT5572_LinuxSTA_2.6.1.3_20121022 (according Mediatek, latest driver
for RT8070/RT3070/RT3370/RT3572/RT5370/RT5372/RT5572 USB devices).
It fixes freezes on Maxim system.

Resolve:
https://bugzilla.redhat.com/show_bug.cgi?id=1000679

Reported-and-tested-by: Maxim Polyakov <polyakov@dexmalabs.com>
Bisected-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Cc: stable@vger.kernel.org # 3.10+
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2800lib.c

index 95e6e61c3de0db729ec27e1eb4ce4f601faf7b1d..88ce656f96cda3d7ea1f7ae5756827538edfc6d2 100644 (file)
@@ -6659,19 +6659,20 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
                     rt2800_init_registers(rt2x00dev)))
                return -EIO;
 
+       if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev)))
+               return -EIO;
+
        /*
         * Send signal to firmware during boot time.
         */
        rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
        rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-       if (rt2x00_is_usb(rt2x00dev)) {
+       if (rt2x00_is_usb(rt2x00dev))
                rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
-               rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-       }
+       rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
        msleep(1);
 
-       if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
-                    rt2800_wait_bbp_ready(rt2x00dev)))
+       if (unlikely(rt2800_wait_bbp_ready(rt2x00dev)))
                return -EIO;
 
        rt2800_init_bbp(rt2x00dev);