diff options
author | Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com> | 2012-02-02 05:59:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-02-03 14:18:02 -0500 |
commit | 07445f688218a48bde72316aed9de4fdcc173131 (patch) | |
tree | a123651853cb0b901b4e505d9cf4470883bd7f50 /drivers/net/wireless | |
parent | b7097eb75fa11c302dcdec83f1dbfa874e0af0d1 (diff) |
ath9k: Fix kernel panic during driver initilization
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>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index abf943557dee..53a005d288aa 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -822,6 +822,11 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
822 | ARRAY_SIZE(ath9k_tpt_blink)); | 822 | ARRAY_SIZE(ath9k_tpt_blink)); |
823 | #endif | 823 | #endif |
824 | 824 | ||
825 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | ||
826 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
827 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||
828 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
829 | |||
825 | /* Register with mac80211 */ | 830 | /* Register with mac80211 */ |
826 | error = ieee80211_register_hw(hw); | 831 | error = ieee80211_register_hw(hw); |
827 | if (error) | 832 | if (error) |
@@ -840,10 +845,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
840 | goto error_world; | 845 | goto error_world; |
841 | } | 846 | } |
842 | 847 | ||
843 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | ||
844 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
845 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||
846 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
847 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 848 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
848 | 849 | ||
849 | ath_init_leds(sc); | 850 | ath_init_leds(sc); |