diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-06-28 20:09:00 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-06-28 20:08:59 -0700 |
| commit | e80ffe4ec7bc3af9b77c630a470ffe77650f9308 (patch) | |
| tree | 0c4b55f872e078cca2efb14b7e7a5c3fa249d0ce | |
| parent | 823d04d683bfa9b6da415db882028b05fc13f1b8 (diff) | |
| parent | 6a7013d43df429c8d2d091c15da3c8ee1fb2a285 (diff) | |
Merge "icnss: Add specific statistics for PDR"
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 61 |
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); |
