summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSameer Thalappil <sameert@codeaurora.org>2017-08-18 13:02:32 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-08-23 12:57:39 -0700
commit1b2a982b4f1fe0eead866d1b8abcbd791e171bfa (patch)
tree16eab2c34799e7854aff1b7aa2d37ff2b6c09cce
parente243bb85026ba9a88de4e860b265594da4f73706 (diff)
icnss: Do not process FW messages after Modem shutdown
During Modem graceful shutdown, QMI messages from WLAN FW can still be delivered to host even after icnss receives Modem shutdown notification from SSR framework. So prevent processing any such messages from FW after Modem shutdown. CRs-Fixed: 2095386 Change-Id: Ice21d043393b0f7b97aaccd68e1b28702cc9e393 Signed-off-by: Sameer Thalappil <sameert@codeaurora.org>
-rw-r--r--drivers/soc/qcom/icnss.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 7f2e4cc42e51..0d534290991b 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -294,6 +294,7 @@ enum icnss_driver_state {
ICNSS_WLFW_EXISTS,
ICNSS_SHUTDOWN_DONE,
ICNSS_HOST_TRIGGERED_PDR,
+ ICNSS_FW_DOWN,
};
struct ce_irq_list {
@@ -1950,6 +1951,12 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle,
icnss_pr_dbg("Received Ind 0x%x, msg_len: %d\n", msg_id, msg_len);
+ if (test_bit(ICNSS_FW_DOWN, &penv->state)) {
+ icnss_pr_dbg("FW down, ignoring 0x%x, state: 0x%lx\n",
+ msg_id, penv->state);
+ return;
+ }
+
switch (msg_id) {
case QMI_WLFW_FW_READY_IND_V01:
icnss_driver_event_post(ICNSS_DRIVER_EVENT_FW_READY_IND,
@@ -1996,6 +2003,7 @@ static int icnss_driver_event_server_arrive(void *data)
return -ENODEV;
set_bit(ICNSS_WLFW_EXISTS, &penv->state);
+ clear_bit(ICNSS_FW_DOWN, &penv->state);
penv->wlfw_clnt = qmi_handle_create(icnss_qmi_wlfw_clnt_notify, penv);
if (!penv->wlfw_clnt) {
@@ -2496,6 +2504,8 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
icnss_pr_info("Modem went down, state: 0x%lx, crashed: %d\n",
priv->state, notif->crashed);
+ set_bit(ICNSS_FW_DOWN, &priv->state);
+
if (notif->crashed)
priv->stats.recovery.root_pd_crash++;
else
@@ -2623,6 +2633,7 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
icnss_pr_info("PD service down, pd_state: %d, state: 0x%lx: cause: %s\n",
*state, priv->state, icnss_pdr_cause[cause]);
event_post:
+ set_bit(ICNSS_FW_DOWN, &priv->state);
icnss_ignore_qmi_timeout(true);
clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
@@ -2631,6 +2642,8 @@ event_post:
icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
ICNSS_EVENT_SYNC, event_data);
done:
+ if (notification == SERVREG_NOTIF_SERVICE_STATE_UP_V01)
+ clear_bit(ICNSS_FW_DOWN, &priv->state);
return NOTIFY_OK;
}
@@ -3824,6 +3837,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
case ICNSS_HOST_TRIGGERED_PDR:
seq_puts(s, "HOST TRIGGERED PDR");
continue;
+ case ICNSS_FW_DOWN:
+ seq_puts(s, "FW DOWN");
+ continue;
}
seq_printf(s, "UNKNOWN-%d", i);