From fd7dcb16e589710c5df479229e9c574329d32efa Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Wed, 18 Nov 2020 17:11:26 -0800 Subject: [PATCH 1/2] cnss2: Set RDDM done only when dump is collected This can help retry dump collection in kernel panic handler if something goes wrong in normal path. Also return proper value for cnss_force_collect_rddm() when RDDM is done successfully. Change-Id: Icf1dabb0313162c459839c52119420f65f73d5c1 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 2 ++ drivers/net/wireless/cnss2/pci.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index ceb98ece043c..0ae4a5548a28 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -1350,6 +1350,8 @@ wait_rddm: msecs_to_jiffies(CNSS_RDDM_TIMEOUT_MS)); if (!ret) ret = -ETIMEDOUT; + else if (ret > 0) + ret = 0; return ret; } diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 97298f1b5688..1013acf3a5b9 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -4463,8 +4463,9 @@ void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) if (dump_data->nentries > 0) plat_priv->ramdump_info_v2.dump_data_valid = true; -skip_dump: cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RDDM_DONE); + +skip_dump: complete(&plat_priv->rddm_complete); } From ba7ceb499a4aa75adcdca5bee20d18f3710652ab Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Mon, 17 Aug 2020 12:02:32 -0700 Subject: [PATCH 2/2] cnss2: Add new API to get QMI related timeouts Refactor and add new API to get QMI related timeouts. Also remove printing timeout value from cnss_get_qmi_timeout(). Instead print it in the callers of the API separately. Change-Id: Ifb0891b955c4b7f1ab5b20d1e37c8059ad1d7b29 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 66 +++++++++++++++++++++++-------- drivers/net/wireless/cnss2/main.h | 10 +++++ drivers/net/wireless/cnss2/pci.c | 19 ++++----- drivers/net/wireless/cnss2/qmi.c | 2 - 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 0ae4a5548a28..c85af1dda200 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -616,6 +616,40 @@ out: return ret; } +/** + * cnss_get_timeout - Get timeout for corresponding type. + * @plat_priv: Pointer to platform driver context. + * @cnss_timeout_type: Timeout type. + * + * Return: Timeout in milliseconds. + */ +unsigned int cnss_get_timeout(struct cnss_plat_data *plat_priv, + enum cnss_timeout_type timeout_type) +{ + unsigned int qmi_timeout = cnss_get_qmi_timeout(plat_priv); + + switch (timeout_type) { + case CNSS_TIMEOUT_QMI: + return qmi_timeout; + case CNSS_TIMEOUT_POWER_UP: + return (qmi_timeout << 2); + case CNSS_TIMEOUT_IDLE_RESTART: + /* In idle restart power up sequence, we have fw_boot_timer to + * handle FW initialization failure. + * It uses WLAN_MISSION_MODE_TIMEOUT, so setup 3x that time to + * account for FW dump collection and FW re-initialization on + * retry. + */ + return (qmi_timeout + WLAN_MISSION_MODE_TIMEOUT * 3); + case CNSS_TIMEOUT_CALIBRATION: + return (qmi_timeout + WLAN_COLD_BOOT_CAL_TIMEOUT); + case CNSS_TIMEOUT_WLAN_WATCHDOG: + return ((qmi_timeout << 1) + WLAN_WD_TIMEOUT_MS); + default: + return qmi_timeout; + } +} + unsigned int cnss_get_boot_timeout(struct device *dev) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); @@ -625,7 +659,7 @@ unsigned int cnss_get_boot_timeout(struct device *dev) return 0; } - return cnss_get_qmi_timeout(plat_priv); + return cnss_get_timeout(plat_priv, CNSS_TIMEOUT_QMI); } EXPORT_SYMBOL(cnss_get_boot_timeout); @@ -651,13 +685,14 @@ int cnss_power_up(struct device *dev) if (plat_priv->device_id == QCA6174_DEVICE_ID) goto out; - timeout = cnss_get_boot_timeout(dev); + timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_POWER_UP); reinit_completion(&plat_priv->power_up_complete); ret = wait_for_completion_timeout(&plat_priv->power_up_complete, - msecs_to_jiffies(timeout) << 2); + msecs_to_jiffies(timeout)); if (!ret) { - cnss_pr_err("Timeout waiting for power up to complete\n"); + cnss_pr_err("Timeout (%ums) waiting for power up to complete\n", + timeout); ret = -EAGAIN; goto out; } @@ -723,20 +758,15 @@ int cnss_idle_restart(struct device *dev) goto out; } - timeout = cnss_get_boot_timeout(dev); - /* In Idle restart power up sequence, we have fw_boot_timer to handle - * FW initialization failure. It uses WLAN_DRIVER_LOAD_TIMEOUT. - * Thus setup 3x that completion wait time to account for FW reinit / - * dump collection on retry. - */ + timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_IDLE_RESTART); ret = wait_for_completion_timeout(&plat_priv->power_up_complete, - msecs_to_jiffies(timeout + - WLAN_MISSION_MODE_TIMEOUT * 3)); + msecs_to_jiffies(timeout)); if (!ret) { /* This exception occurs after attempting retry of FW recovery. * Thus we can safely power off the device. */ - cnss_fatal_err("Timeout for idle restart to complete\n"); + cnss_fatal_err("Timeout (%ums) waiting for idle restart to complete\n", + timeout); ret = -ETIMEDOUT; cnss_power_down(dev); CNSS_ASSERT(0); @@ -784,7 +814,8 @@ int cnss_idle_shutdown(struct device *dev) ret = wait_for_completion_timeout(&plat_priv->recovery_complete, msecs_to_jiffies(RECOVERY_TIMEOUT)); if (!ret) { - cnss_pr_err("Timeout waiting for recovery to complete\n"); + cnss_pr_err("Timeout (%ums) waiting for recovery to complete\n", + RECOVERY_TIMEOUT); CNSS_ASSERT(0); } @@ -1348,10 +1379,13 @@ wait_rddm: ret = wait_for_completion_timeout (&plat_priv->rddm_complete, msecs_to_jiffies(CNSS_RDDM_TIMEOUT_MS)); - if (!ret) + if (!ret) { + cnss_pr_err("Timeout (%ums) waiting for RDDM to complete\n", + CNSS_RDDM_TIMEOUT_MS); ret = -ETIMEDOUT; - else if (ret > 0) + } else if (ret > 0) { ret = 0; + } return ret; } diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h index 8f677f03b7d6..23d862c998f7 100644 --- a/drivers/net/wireless/cnss2/main.h +++ b/drivers/net/wireless/cnss2/main.h @@ -385,6 +385,14 @@ struct cnss_dms_data { u8 mac[QMI_WLFW_MAC_ADDR_SIZE_V01]; }; +enum cnss_timeout_type { + CNSS_TIMEOUT_QMI, + CNSS_TIMEOUT_POWER_UP, + CNSS_TIMEOUT_IDLE_RESTART, + CNSS_TIMEOUT_CALIBRATION, + CNSS_TIMEOUT_WLAN_WATCHDOG, +}; + struct cnss_plat_data { struct platform_device *plat_dev; void *bus_priv; @@ -530,5 +538,7 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv, void *va, phys_addr_t pa, size_t size); int cnss_enable_int_pow_amp_vreg(struct cnss_plat_data *plat_priv); int cnss_get_tcs_info(struct cnss_plat_data *plat_priv); +unsigned int cnss_get_timeout(struct cnss_plat_data *plat_priv, + enum cnss_timeout_type); #endif /* _CNSS_MAIN_H */ diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 1013acf3a5b9..5036d4838909 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -2131,7 +2131,7 @@ retry: } cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false); - timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev); + timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_QMI); ret = cnss_pci_start_mhi(pci_priv); if (ret) { @@ -2430,12 +2430,12 @@ int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops) return -EPERM; } - timeout = cnss_get_boot_timeout(&pci_priv->pci_dev->dev); + timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_CALIBRATION); ret = wait_for_completion_timeout(&plat_priv->cal_complete, - WLAN_COLD_BOOT_CAL_TIMEOUT + msecs_to_jiffies(timeout)); if (!ret) { - cnss_pr_err("Timeout waiting for calibration to complete\n"); + cnss_pr_err("Timeout (%ums) waiting for calibration to complete\n", + timeout); if (!test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) CNSS_ASSERT(0); @@ -2480,12 +2480,12 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops) if (plat_priv->device_id == QCA6174_DEVICE_ID) goto skip_wait_power_up; - timeout = cnss_get_qmi_timeout(plat_priv); + timeout = cnss_get_timeout(plat_priv, CNSS_TIMEOUT_WLAN_WATCHDOG); ret = wait_for_completion_timeout(&plat_priv->power_up_complete, - msecs_to_jiffies((timeout << 1) + - WLAN_WD_TIMEOUT_MS)); + msecs_to_jiffies(timeout)); if (!ret) { - cnss_pr_err("Timeout waiting for driver power up to complete\n"); + cnss_pr_err("Timeout (%ums) waiting for driver power up to complete\n", + timeout); CNSS_ASSERT(0); } @@ -2498,7 +2498,8 @@ skip_wait_power_up: ret = wait_for_completion_timeout(&plat_priv->recovery_complete, msecs_to_jiffies(RECOVERY_TIMEOUT)); if (!ret) { - cnss_pr_err("Timeout waiting for recovery to complete\n"); + cnss_pr_err("Timeout (%ums) waiting for recovery to complete\n", + RECOVERY_TIMEOUT); CNSS_ASSERT(0); } diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c index 82e7f897e973..96b9cb39f1a4 100644 --- a/drivers/net/wireless/cnss2/qmi.c +++ b/drivers/net/wireless/cnss2/qmi.c @@ -1725,8 +1725,6 @@ out: unsigned int cnss_get_qmi_timeout(struct cnss_plat_data *plat_priv) { - cnss_pr_dbg("QMI timeout is %u ms\n", QMI_WLFW_TIMEOUT_MS); - return QMI_WLFW_TIMEOUT_MS; }