浏览代码

qcacld-3.0: Eliminate possibility of sending power off when FW is down

In the scenario of concurrent execution of __con_mode_handler and
triggering of SSR, there exists a possibility of driver sending power
off command while the target is not ready. In hdd_wlan_stop_modules, as
a part of __con_mode_handler context, pld_power_off was called after
the trigger of SSR, which caused assert in the platform driver.

To eliminate this, convert the static verfification of the driver state
at the start of the hdd_wlan_start_modules to dynamic. And also set the
target ready state to false in case SSR/FW_DOWN uevent is received.
These will ensure that the driver doesnot try to send the power off
command while the target is not ready.

Change-Id: Idf1056dc85107c535809bedf8b5534085033a1f5
CRs-Fixed: 2271096
Sourav Mohapatra 6 年之前
父节点
当前提交
808e3d4b71
共有 2 个文件被更改,包括 7 次插入5 次删除
  1. 2 0
      core/hdd/src/wlan_hdd_driver_ops.c
  2. 5 5
      core/hdd/src/wlan_hdd_main.c

+ 2 - 0
core/hdd/src/wlan_hdd_driver_ops.c

@@ -1463,10 +1463,12 @@ static void wlan_hdd_set_the_pld_uevent(struct pld_uevent_data *uevent)
 {
 	switch (uevent->uevent) {
 	case PLD_RECOVERY:
+		cds_set_target_ready(false);
 		cds_set_recovery_in_progress(true);
 		break;
 	case PLD_FW_DOWN:
 		cds_set_fw_state(CDS_FW_STATE_DOWN);
+		cds_set_target_ready(false);
 		break;
 	}
 }

+ 5 - 5
core/hdd/src/wlan_hdd_main.c

@@ -235,6 +235,8 @@ static qdf_wake_lock_t wlan_wake_lock;
 
 /* max peer can be tdls peers + self peer + bss peer */
 #define HDD_MAX_VDEV_PEER_COUNT  (HDD_MAX_NUM_TDLS_STA + 2)
+#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
+		      !cds_is_driver_recovering() && !cds_is_driver_loading())
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
 static const struct wiphy_wowlan_support wowlan_support_reg_init = {
@@ -10772,10 +10774,8 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
 	void *hif_ctx;
 	qdf_device_t qdf_ctx;
 	QDF_STATUS qdf_status;
-	int ret = 0;
 	bool is_recovery_stop = cds_is_driver_recovering();
-	bool is_idle_stop = !cds_is_driver_unloading() && !is_recovery_stop &&
-		!cds_is_driver_loading();
+	int ret = 0;
 	int active_threads;
 	struct target_psoc_info *tgt_hdl;
 
@@ -10802,7 +10802,7 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
 
 		cds_print_external_threads();
 
-		if (is_idle_stop && !ftm_mode) {
+		if (IS_IDLE_STOP && !ftm_mode) {
 			mutex_unlock(&hdd_ctx->iface_change_lock);
 			qdf_sched_delayed_work(&hdd_ctx->iface_idle_work,
 				       hdd_ctx->config->iface_change_wait_time);
@@ -10912,7 +10912,7 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
 
 	ol_cds_free();
 
-	if (is_idle_stop) {
+	if (IS_IDLE_STOP && cds_is_target_ready()) {
 		ret = pld_power_off(qdf_ctx->dev);
 		if (ret)
 			hdd_err("CNSS power down failed put device into Low power mode:%d",