wifi: ath12k: Fix WARN_ON during firmware crash in split-phy
Whenever firmware is crashed in split-phy below WARN_ON() triggered:
WARNING: CPU: 3 PID: 82 at net/mac80211/driver-ops.c:41 drv_stop+0xac/0xbc
Modules linked in: ath12k qmi_helpers
CPU: 3 PID: 82 Comm: kworker/3:2 Tainted: G D W
6.9.0-next-20240520-00113-gd981a3784e15 #39
Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C9 (DT)
Workqueue: events_freezable ieee80211_restart_work
pstate:
60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : drv_stop+0xac/0xbc
lr : ieee80211_stop_device+0x54/0x64
sp :
ffff8000848dbb20
x29:
ffff8000848dbb20 x28:
0000000000000790 x27:
ffff000014d78900
x26:
ffff000014d791f8 x25:
ffff000007f0d9b0 x24:
0000000000000018
x23:
0000000000000001 x22:
0000000000000000 x21:
ffff000014d78e10
x20:
ffff800081dc0000 x19:
ffff000014d78900 x18:
ffffffffffffffff
x17:
ffff7fffbca84000 x16:
ffff800083fe0000 x15:
ffff800081dc0b48
x14:
0000000000000076 x13:
0000000000000076 x12:
0000000000000001
x11:
0000000000000000 x10:
0000000000000a60 x9 :
ffff8000848db980
x8 :
ffff000000dddfc0 x7 :
0000000000000400 x6 :
ffff800083b012d8
x5 :
ffff800083b012d8 x4 :
0000000000000000 x3 :
ffff000014d78398
x2 :
0000000000000000 x1 :
0000000000000000 x0 :
ffff000014d78900
Call trace:
drv_stop+0xac/0xbc
ieee80211_stop_device+0x54/0x64
ieee80211_do_stop+0x5a0/0x790
ieee80211_stop+0x4c/0x178
__dev_close_many+0xb0/0x150
dev_close_many+0x88/0x130
dev_close.part.171+0x44/0x74
dev_close+0x1c/0x28
cfg80211_shutdown_all_interfaces+0x44/0xfc
ieee80211_restart_work+0xfc/0x14c
process_scheduled_works+0x18c/0x2dc
worker_thread+0x13c/0x314
kthread+0x118/0x124
ret_from_fork+0x10/0x20
---[ end trace
0000000000000000 ]---
The warning in question is from drv_stop():
if (WARN_ON(!local->started))
return;
The sequence of WARN_ON() is:
Thread 1:
-Firmware crash calls ath12k_core_reset().
-Call ieee80211_restart_hw() inside
ath12k_core_post_reconfigure_recovery() which schedules worker
for both hardware.
-Wait for completion of ab->recovery_start.
Thread 2 (worker thread):
-One hardware acquires rtnl_lock() inside ieee80211_restart_hw() and
calls ath12k_mac_wait_reconfigure() into ath12k_mac_op_start().
-Hardware is waiting for ab->reconfigure_complete but at this time
recovery_start_count value is 1 because another worker thread
(local->restart_work) is still waiting for rtnl_lock().
recovery_start_count is not equal to number of radios
(2 in split-phy). So ab->recovery_start complete does not set
due to this, thread 1 is still waiting and not able to perform
hif power down up and firmware reload.
-Wait timeout happens for ab->reconfigure_complete and comeback
to caller (ath12k_mac_op_start()) and sends WMI command to
crashed firmware and gets error.
-This returns error to drv_start() and local->started is set to false.
-Hardware calls cfg80211_shutdown_all_interfaces() after receiving error
inside ieee80211_restart_work() and goes to drv_stop(), here we trigger
WARN_ON as local->started is false.
To fix this issue call ieee80211_restart_hw() after firmware has been
reloaded. Now, each hardware can send WMI command to firmware
successfully. With this fix we don't need to wait for
ab->recovery_start completion so remove
ath12k_mac_wait_reconfigure().
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00209-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 HW2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240529034405.2863150-1-quic_aarasahu@quicinc.com