icnss2: Add ASSERT if fw ready got timed out
Recovery timer is used to detect FW_READY timeout(60 Sec) during SSR/PDR recovery and assert. Same timer starts before cold boot calibration also and expires in 40 sec if FW_READY is not received. Change-Id: Ie4e2a327aa4f4df49b8684f9c178b9b5f4d4fb15 CRs-Fixed: 3221566
Цей коміт міститься в:

зафіксовано
Madan Koyyalamudi

джерело
3a589a650e
коміт
54df2d964c
@@ -83,6 +83,9 @@ module_param(qmi_timeout, ulong, 0600);
|
|||||||
#define WLFW_TIMEOUT msecs_to_jiffies(3000)
|
#define WLFW_TIMEOUT msecs_to_jiffies(3000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ICNSS_RECOVERY_TIMEOUT 60000
|
||||||
|
#define ICNSS_CAL_TIMEOUT 40000
|
||||||
|
|
||||||
static struct icnss_priv *penv;
|
static struct icnss_priv *penv;
|
||||||
static struct work_struct wpss_loader;
|
static struct work_struct wpss_loader;
|
||||||
uint64_t dynamic_feature_mask = ICNSS_DEFAULT_FEATURE_MASK;
|
uint64_t dynamic_feature_mask = ICNSS_DEFAULT_FEATURE_MASK;
|
||||||
@@ -1136,6 +1139,7 @@ static int icnss_driver_event_fw_ready_ind(struct icnss_priv *priv, void *data)
|
|||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
del_timer(&priv->recovery_timer);
|
||||||
set_bit(ICNSS_FW_READY, &priv->state);
|
set_bit(ICNSS_FW_READY, &priv->state);
|
||||||
clear_bit(ICNSS_MODE_ON, &priv->state);
|
clear_bit(ICNSS_MODE_ON, &priv->state);
|
||||||
atomic_set(&priv->soc_wake_ref_count, 0);
|
atomic_set(&priv->soc_wake_ref_count, 0);
|
||||||
@@ -1184,11 +1188,14 @@ static int icnss_driver_event_fw_init_done(struct icnss_priv *priv, void *data)
|
|||||||
if (icnss_wlfw_qdss_dnld_send_sync(priv))
|
if (icnss_wlfw_qdss_dnld_send_sync(priv))
|
||||||
icnss_pr_info("Failed to download qdss configuration file");
|
icnss_pr_info("Failed to download qdss configuration file");
|
||||||
|
|
||||||
if (test_bit(ICNSS_COLD_BOOT_CAL, &priv->state))
|
if (test_bit(ICNSS_COLD_BOOT_CAL, &priv->state)) {
|
||||||
|
mod_timer(&priv->recovery_timer,
|
||||||
|
jiffies + msecs_to_jiffies(ICNSS_CAL_TIMEOUT));
|
||||||
ret = wlfw_wlan_mode_send_sync_msg(priv,
|
ret = wlfw_wlan_mode_send_sync_msg(priv,
|
||||||
(enum wlfw_driver_mode_enum_v01)ICNSS_CALIBRATION);
|
(enum wlfw_driver_mode_enum_v01)ICNSS_CALIBRATION);
|
||||||
else
|
} else {
|
||||||
icnss_driver_event_fw_ready_ind(priv, NULL);
|
icnss_driver_event_fw_ready_ind(priv, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -2108,6 +2115,10 @@ static int icnss_wpss_notifier_nb(struct notifier_block *nb,
|
|||||||
}
|
}
|
||||||
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
||||||
ICNSS_EVENT_SYNC, event_data);
|
ICNSS_EVENT_SYNC, event_data);
|
||||||
|
|
||||||
|
if (notif->crashed)
|
||||||
|
mod_timer(&priv->recovery_timer,
|
||||||
|
jiffies + msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT));
|
||||||
out:
|
out:
|
||||||
icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
|
icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
@@ -2185,6 +2196,10 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
|
|||||||
}
|
}
|
||||||
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
||||||
ICNSS_EVENT_SYNC, event_data);
|
ICNSS_EVENT_SYNC, event_data);
|
||||||
|
|
||||||
|
if (notif->crashed)
|
||||||
|
mod_timer(&priv->recovery_timer,
|
||||||
|
jiffies + msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT));
|
||||||
out:
|
out:
|
||||||
icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
|
icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
@@ -2409,6 +2424,11 @@ static void icnss_pdr_notifier_cb(int state, char *service_path, void *priv_cb)
|
|||||||
clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
|
clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
|
||||||
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
||||||
ICNSS_EVENT_SYNC, event_data);
|
ICNSS_EVENT_SYNC, event_data);
|
||||||
|
|
||||||
|
if (event_data->crashed)
|
||||||
|
mod_timer(&priv->recovery_timer,
|
||||||
|
jiffies +
|
||||||
|
msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT));
|
||||||
break;
|
break;
|
||||||
case SERVREG_SERVICE_STATE_UP:
|
case SERVREG_SERVICE_STATE_UP:
|
||||||
clear_bit(ICNSS_FW_DOWN, &priv->state);
|
clear_bit(ICNSS_FW_DOWN, &priv->state);
|
||||||
@@ -4483,6 +4503,9 @@ static int icnss_probe(struct platform_device *pdev)
|
|||||||
INIT_WORK(&wpss_loader, icnss_wpss_load);
|
INIT_WORK(&wpss_loader, icnss_wpss_load);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer_setup(&priv->recovery_timer,
|
||||||
|
icnss_recovery_timeout_hdlr, 0);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->icnss_tcdev_list);
|
INIT_LIST_HEAD(&priv->icnss_tcdev_list);
|
||||||
|
|
||||||
icnss_pr_info("Platform driver probed successfully\n");
|
icnss_pr_info("Platform driver probed successfully\n");
|
||||||
@@ -4533,6 +4556,8 @@ static int icnss_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
icnss_pr_info("Removing driver: state: 0x%lx\n", priv->state);
|
icnss_pr_info("Removing driver: state: 0x%lx\n", priv->state);
|
||||||
|
|
||||||
|
del_timer(&priv->recovery_timer);
|
||||||
|
|
||||||
device_init_wakeup(&priv->pdev->dev, false);
|
device_init_wakeup(&priv->pdev->dev, false);
|
||||||
|
|
||||||
icnss_debugfs_destroy(priv);
|
icnss_debugfs_destroy(priv);
|
||||||
@@ -4591,6 +4616,14 @@ static int icnss_remove(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void icnss_recovery_timeout_hdlr(struct timer_list *t)
|
||||||
|
{
|
||||||
|
struct icnss_priv *priv = from_timer(priv, t, recovery_timer);
|
||||||
|
|
||||||
|
icnss_pr_err("Timeout waiting for FW Ready 0x%lx\n", priv->state);
|
||||||
|
ICNSS_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int icnss_pm_suspend(struct device *dev)
|
static int icnss_pm_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "wlan_firmware_service_v01.h"
|
#include "wlan_firmware_service_v01.h"
|
||||||
#include <linux/mailbox_client.h>
|
#include <linux/mailbox_client.h>
|
||||||
|
#include <linux/timer.h>
|
||||||
|
|
||||||
#define WCN6750_DEVICE_ID 0x6750
|
#define WCN6750_DEVICE_ID 0x6750
|
||||||
#define ADRASTEA_DEVICE_ID 0xabcd
|
#define ADRASTEA_DEVICE_ID 0xabcd
|
||||||
@@ -501,6 +502,7 @@ struct icnss_priv {
|
|||||||
u32 rf_subtype;
|
u32 rf_subtype;
|
||||||
u8 is_slate_rfa;
|
u8 is_slate_rfa;
|
||||||
struct completion slate_boot_complete;
|
struct completion slate_boot_complete;
|
||||||
|
struct timer_list recovery_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct icnss_reg_info {
|
struct icnss_reg_info {
|
||||||
@@ -528,5 +530,6 @@ int icnss_update_cpr_info(struct icnss_priv *priv);
|
|||||||
void icnss_add_fw_prefix_name(struct icnss_priv *priv, char *prefix_name,
|
void icnss_add_fw_prefix_name(struct icnss_priv *priv, char *prefix_name,
|
||||||
char *name);
|
char *name);
|
||||||
int icnss_aop_mbox_init(struct icnss_priv *priv);
|
int icnss_aop_mbox_init(struct icnss_priv *priv);
|
||||||
|
void icnss_recovery_timeout_hdlr(struct timer_list *t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Посилання в новій задачі
Заблокувати користувача