From 46082dc0a69c8dcc78a6dfc0756e0ed4e1048574 Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Tue, 19 Sep 2017 12:25:38 +0800 Subject: [PATCH] qcacld-3.0: inject fw crash in crash-shutdown When kernel panic happen, if WiFi FW is still active, it may cause NOC errors/memory corruption, to avoid this, inject a fw crash first. Propagated from qcacld-2.0 Change-Id: I97a696a02dfd73aaca212ef1bca9f3597df1e382 CRs-Fixed: 2052332 --- core/hdd/src/wlan_hdd_driver_ops.c | 24 ++++++++++++++++++++++++ core/wma/inc/wma.h | 2 -- core/wma/inc/wma_api.h | 3 +++ core/wma/src/wma_main.c | 7 ++++--- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index e3dfe02f2940..f1faa17f42cb 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -525,6 +525,30 @@ static void wlan_hdd_shutdown(void) */ static void wlan_hdd_crash_shutdown(void) { + QDF_STATUS ret; + WMA_HANDLE wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + + if (!wma_handle) { + hdd_err("wma_handle is null"); + return; + } + + /* + * When kernel panic happen, if WiFi FW is still active + * it may cause NOC errors/memory corruption, to avoid + * this, inject a fw crash first. + * send crash_inject to FW directly, because we are now + * in an atomic context, and preempt has been disabled, + * MCThread won't be scheduled at the moment, at the same + * time, TargetFailure event wont't be received after inject + * crash due to the same reason. + */ + ret = wma_crash_inject(wma_handle, RECOVERY_SIM_ASSERT, 0); + if (QDF_IS_STATUS_ERROR(ret)) { + hdd_err("Failed to send crash inject:%d", ret); + return; + } + hif_crash_shutdown(cds_get_context(QDF_MODULE_ID_HIF)); } diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 67a106446219..f780d88de244 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2157,8 +2157,6 @@ QDF_STATUS wma_send_pdev_set_dual_mac_config(tp_wma_handle wma_handle, struct sir_dual_mac_config *msg); QDF_STATUS wma_send_pdev_set_antenna_mode(tp_wma_handle wma_handle, struct sir_antenna_mode_param *msg); -QDF_STATUS wma_crash_inject(tp_wma_handle wma_handle, uint32_t type, - uint32_t delay_time_ms); struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, uint8_t vdev_id, diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index fcc1eea18998..962d8c149e25 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -318,4 +318,7 @@ void wma_store_pdev(void *wma_ctx, struct wlan_objmgr_pdev *pdev); * Return: tSirWifiPeerType */ tSirWifiPeerType wmi_to_sir_peer_type(enum wmi_peer_type type); + +QDF_STATUS wma_crash_inject(WMA_HANDLE wma_handle, uint32_t type, + uint32_t delay_time_ms); #endif diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index a837c4730c9c..05bbc46ba32c 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -7921,14 +7921,15 @@ resp: * * Return: QDF_STATUS_SUCCESS for success or error code */ -QDF_STATUS wma_crash_inject(tp_wma_handle wma_handle, uint32_t type, - uint32_t delay_time_ms) +QDF_STATUS wma_crash_inject(WMA_HANDLE wma_handle, uint32_t type, + uint32_t delay_time_ms) { struct crash_inject param; + tp_wma_handle wma = (tp_wma_handle)wma_handle; param.type = type; param.delay_time_ms = delay_time_ms; - return wmi_crash_inject(wma_handle->wmi_handle, ¶m); + return wmi_crash_inject(wma->wmi_handle, ¶m); } #if defined(FEATURE_LRO)