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>
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)
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);