ath9k: Fix kernel panic during driver initilization
authorMohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
Thu, 2 Feb 2012 10:59:05 +0000 (16:29 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 3 Feb 2012 19:18:02 +0000 (14:18 -0500)
all works need to be initialized before ieee80211_register_hw
to prevent mac80211 call backs such as drv_start, drv_config
getting started. otherwise we would queue/cancel works before
initializing them and it leads to kernel panic.
this issue can be recreated with the following script
in Chrome laptops with AR928X cards, with background scan
running (or) Network manager is running

while true
do
sudo modprobe -v ath9k
sleep 3
sudo modprobe -r ath9k
sleep 3
done

 EIP: [<81040a47>] __cancel_work_timer+0xb8/0xe1 SS:ESP 0068:f6be9d70
 ---[ end trace 4f86d6139a9900ef ]---
 Registered led device: ath9k-phy0
 ieee80211 phy0: Atheros AR9280 Rev:2 mem=0xf88a0000,
 irq=16
 Kernel panic - not syncing: Fatal exception
 Pid: 456, comm: wpa_supplicant Tainted: G      D
 3.0.13 #1
Call Trace:
 [<81379e21>] panic+0x53/0x14a
 [<81004a30>] oops_end+0x73/0x81
 [<81004b53>] die+0x4c/0x55
 [<81002710>] do_trap+0x7c/0x83
 [<81002855>] ? do_bounds+0x58/0x58
 [<810028cc>] do_invalid_op+0x77/0x81
 [<81040a47>] ? __cancel_work_timer+0xb8/0xe1
 [<810489ec>] ? sched_clock_cpu+0x81/0x11f
 [<8103f809>] ? wait_on_work+0xe2/0xf7
 [<8137f807>] error_code+0x67/0x6c
 [<810300d8>] ? wait_consider_task+0x4ba/0x84c
 [<81040a47>] ? __cancel_work_timer+0xb8/0xe1
 [<810380c9>] ? try_to_del_timer_sync+0x5f/0x67
 [<81040a91>] cancel_work_sync+0xf/0x11
 [<f88d7b7c>] ath_set_channel+0x62/0x25c [ath9k]
 [<f88d67d1>] ? ath9k_tx_last_beacon+0x26a/0x85c [ath9k]
 [<f88d8899>] ath_radio_disable+0x3f1/0x68e [ath9k]
 [<f90d0edb>] ieee80211_hw_config+0x111/0x116 [mac80211]
 [<f90dd95c>] __ieee80211_recalc_idle+0x919/0xa37 [mac80211]
 [<f90dda76>] __ieee80211_recalc_idle+0xa33/0xa37 [mac80211]
 [<812dbed8>] __dev_open+0x82/0xab

Cc: <stable@vger.kernel.org>
Cc: Gary Morain <gmorain@google.com>
Cc: Paul Stewart <pstew@google.com>
Cc: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Tested-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/init.c

index abf943557deeca279a82ca434cb4eb5032d6805b..53a005d288aa53949da6e1317c57e294a092a907 100644 (file)
@@ -822,6 +822,11 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
                ARRAY_SIZE(ath9k_tpt_blink));
 #endif
 
+       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+       INIT_WORK(&sc->hw_check_work, ath_hw_check);
+       INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
@@ -840,10 +845,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
                        goto error_world;
        }
 
-       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
-       INIT_WORK(&sc->hw_check_work, ath_hw_check);
-       INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
-       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
        sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
        ath_init_leds(sc);