Browse Source

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
Yu Wang 7 years ago
parent
commit
46082dc0a6
4 changed files with 31 additions and 5 deletions
  1. 24 0
      core/hdd/src/wlan_hdd_driver_ops.c
  2. 0 2
      core/wma/inc/wma.h
  3. 3 0
      core/wma/inc/wma_api.h
  4. 4 3
      core/wma/src/wma_main.c

+ 24 - 0
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));
 }
 

+ 0 - 2
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,

+ 3 - 0
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

+ 4 - 3
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, &param);
+	return wmi_crash_inject(wma->wmi_handle, &param);
 }
 
 #if defined(FEATURE_LRO)