Browse Source

qcacld-3.0: Reject host suspend in driver open state

After insmod wlan.ko, don't ifconfig wlan0 up, driver will be in
DRIVER_MODULES_OPENED instead of DRIVER_MODULES_ENABLED state.
If host suspend at this time, PCIE will suspend too, when resume,
PCIE bus driver may reset ROME soc during link reconnection, copy
engine is reset too.
When host send wmi cmd to F/W, copy engine will access 0 address,
SMMU fault will happen.

There is logic inside ROME hardware&firmware, if PDEV_SUSPEND or
WOW_ENABLE WMI command is sent to firmware, firmware will decuple
the reset path between ROME pcie interface and ROME soc,
then ROME soc will not be reset if pcie bus driver toggle the
PERST pin to ENDP, only pcie interface part is reset.

Change-Id: I3b6344f69ea70248953af155efd00adf7914e98b
CRs-Fixed: 2243667
Jianmin Zhu 6 years ago
parent
commit
16b94b1725
2 changed files with 17 additions and 0 deletions
  1. 10 0
      core/hdd/src/wlan_hdd_driver_ops.c
  2. 7 0
      core/hdd/src/wlan_hdd_power.c

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

@@ -759,6 +759,11 @@ static int __wlan_hdd_bus_suspend(struct wow_enable_params wow_params)
 		return err;
 	}
 
+	if (hdd_ctx->driver_status == DRIVER_MODULES_OPENED) {
+		hdd_err("Driver open state,  can't suspend");
+		return -EAGAIN;
+	}
+
 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
 		hdd_debug("Driver Module closed; skipping suspend");
 		return 0;
@@ -873,6 +878,11 @@ static int __wlan_hdd_bus_suspend_noirq(void)
 		return errno;
 	}
 
+	if (hdd_ctx->driver_status == DRIVER_MODULES_OPENED) {
+		hdd_err("Driver open state,  can't suspend");
+		return -EAGAIN;
+	}
+
 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
 		hdd_debug("Driver module closed; skip bus-noirq suspend");
 		return 0;

+ 7 - 0
core/hdd/src/wlan_hdd_power.c

@@ -1618,6 +1618,13 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
 		return rc;
 
 	mutex_lock(&hdd_ctx->iface_change_lock);
+
+	if (hdd_ctx->driver_status == DRIVER_MODULES_OPENED) {
+		mutex_unlock(&hdd_ctx->iface_change_lock);
+		hdd_err("Driver open state,  can't suspend");
+		return -EAGAIN;
+	}
+
 	if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
 		mutex_unlock(&hdd_ctx->iface_change_lock);
 		hdd_debug("Driver Modules not Enabled ");