Parcourir la source

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 il y a 6 ans
Parent
commit
808e3d4b71
2 fichiers modifiés avec 7 ajouts et 5 suppressions
  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",