summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSameer Thalappil <sameert@codeaurora.org>2017-06-23 15:43:43 -0700
committerSameer Thalappil <sameert@codeaurora.org>2017-06-26 13:24:51 -0700
commit6a7013d43df429c8d2d091c15da3c8ee1fb2a285 (patch)
treea4309acf6a4233ce0e48a3f864547cb25aaacfc7
parentbbf9eb8202a69f12dcc04adf5567f78bada10076 (diff)
icnss: Add specific statistics for PDR
Maintain separate statistics to track the number of PDR instances from FW crash, host error, root PD crash and root PD shutdown cases. Also add support to announce the PDR cause in the log. CRs-Fixed: 2066366 Change-Id: I33995d694e3aae47dfcc9f249528a7f1815ee12f Signed-off-by: Sameer Thalappil <sameert@codeaurora.org>
-rw-r--r--drivers/soc/qcom/icnss.c61
1 files changed, 55 insertions, 6 deletions
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 9690d3c64560..f5517f26e1f1 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -268,6 +268,7 @@ enum icnss_driver_state {
ICNSS_WLFW_EXISTS,
ICNSS_WDOG_BITE,
ICNSS_SHUTDOWN_DONE,
+ ICNSS_HOST_TRIGGERED_PDR,
};
struct ce_irq_list {
@@ -320,6 +321,13 @@ struct icnss_stats {
uint32_t disable;
} ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS];
+ struct {
+ uint32_t pdr_fw_crash;
+ uint32_t pdr_host_error;
+ uint32_t root_pd_crash;
+ uint32_t root_pd_shutdown;
+ } recovery;
+
uint32_t pm_suspend;
uint32_t pm_suspend_err;
uint32_t pm_resume;
@@ -360,7 +368,6 @@ struct icnss_stats {
uint32_t rejuvenate_ack_req;
uint32_t rejuvenate_ack_resp;
uint32_t rejuvenate_ack_err;
- uint32_t trigger_recovery;
};
#define MAX_NO_OF_MAC_ADDR 4
@@ -369,6 +376,20 @@ struct icnss_wlan_mac_addr {
uint32_t no_of_mac_addr_set;
};
+enum icnss_pdr_cause_index {
+ ICNSS_FW_CRASH,
+ ICNSS_ROOT_PD_CRASH,
+ ICNSS_ROOT_PD_SHUTDOWN,
+ ICNSS_HOST_ERROR,
+};
+
+static const char * const icnss_pdr_cause[] = {
+ [ICNSS_FW_CRASH] = "FW crash",
+ [ICNSS_ROOT_PD_CRASH] = "Root PD crashed",
+ [ICNSS_ROOT_PD_SHUTDOWN] = "Root PD shutdown",
+ [ICNSS_HOST_ERROR] = "Host error",
+};
+
struct service_notifier_context {
void *handle;
uint32_t instance_id;
@@ -2400,6 +2421,11 @@ 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);
+ if (notif->crashed)
+ priv->stats.recovery.root_pd_crash++;
+ else
+ priv->stats.recovery.root_pd_shutdown++;
+
icnss_ignore_qmi_timeout(true);
event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
@@ -2479,6 +2505,7 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
enum pd_subsys_state *state = data;
struct icnss_event_pd_service_down_data *event_data;
struct icnss_uevent_fw_down_data fw_down_data;
+ enum icnss_pdr_cause_index cause = ICNSS_ROOT_PD_CRASH;
icnss_pr_dbg("PD service notification: 0x%lx state: 0x%lx\n",
notification, priv->state);
@@ -2493,26 +2520,40 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
if (state == NULL) {
event_data->crashed = true;
+ priv->stats.recovery.root_pd_crash++;
goto event_post;
}
- icnss_pr_info("PD service down, pd_state: %d, state: 0x%lx\n",
- *state, priv->state);
-
switch (*state) {
case ROOT_PD_WDOG_BITE:
event_data->crashed = true;
event_data->wdog_bite = true;
+ priv->stats.recovery.root_pd_crash++;
break;
case ROOT_PD_SHUTDOWN:
+ cause = ICNSS_ROOT_PD_SHUTDOWN;
+ priv->stats.recovery.root_pd_shutdown++;
+ break;
+ case USER_PD_STATE_CHANGE:
+ if (test_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state)) {
+ cause = ICNSS_HOST_ERROR;
+ priv->stats.recovery.pdr_host_error++;
+ } else {
+ cause = ICNSS_FW_CRASH;
+ priv->stats.recovery.pdr_fw_crash++;
+ }
break;
default:
event_data->crashed = true;
+ priv->stats.recovery.root_pd_crash++;
break;
}
+ icnss_pr_info("PD service down, pd_state: %d, state: 0x%lx: cause: %s\n",
+ *state, priv->state, icnss_pdr_cause[cause]);
event_post:
icnss_ignore_qmi_timeout(true);
+ clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
fw_down_data.crashed = event_data->crashed;
icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, &fw_down_data);
@@ -3255,7 +3296,6 @@ int icnss_trigger_recovery(struct device *dev)
WARN_ON(1);
icnss_pr_warn("Initiate PD restart at WLAN FW, state: 0x%lx\n",
priv->state);
- priv->stats.trigger_recovery++;
/*
* Initiate PDR, required only for the first instance
@@ -3263,6 +3303,9 @@ int icnss_trigger_recovery(struct device *dev)
ret = service_notif_pd_restart(priv->service_notifier[0].name,
priv->service_notifier[0].instance_id);
+ if (!ret)
+ set_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
+
out:
return ret;
}
@@ -3713,6 +3756,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
case ICNSS_SHUTDOWN_DONE:
seq_puts(s, "SHUTDOWN DONE");
continue;
+ case ICNSS_HOST_TRIGGERED_PDR:
+ seq_puts(s, "HOST TRIGGERED PDR");
+ continue;
}
seq_printf(s, "UNKNOWN-%d", i);
@@ -3811,7 +3857,10 @@ static int icnss_stats_show(struct seq_file *s, void *data)
ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_req);
ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_resp);
ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_err);
- ICNSS_STATS_DUMP(s, priv, trigger_recovery);
+ ICNSS_STATS_DUMP(s, priv, recovery.pdr_fw_crash);
+ ICNSS_STATS_DUMP(s, priv, recovery.pdr_host_error);
+ ICNSS_STATS_DUMP(s, priv, recovery.root_pd_crash);
+ ICNSS_STATS_DUMP(s, priv, recovery.root_pd_shutdown);
seq_puts(s, "\n<------------------ PM stats ------------------->\n");
ICNSS_STATS_DUMP(s, priv, pm_suspend);