From e7cf674bc9ae02407d3a2236e24224827c4b04c4 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Fri, 16 Dec 2016 16:36:08 -0800 Subject: [PATCH] icnss: Show rejuvenation info in ICNSS stats report This is a debug enhance feature. It shows rejuvenation info in ICNSS stats report, which makes it easier to track the reason for every rejuvenation. CRs-Fixed: 2072253 Change-Id: I6d133b4b182943ed745d7587bd1ec23858c29750 Signed-off-by: Yuanyuan Liu --- drivers/soc/qcom/icnss.c | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 21be894414bc..07fe5720c4d8 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -365,6 +365,7 @@ struct icnss_stats { uint32_t vbatt_req; uint32_t vbatt_resp; uint32_t vbatt_req_err; + u32 rejuvenate_ind; uint32_t rejuvenate_ack_req; uint32_t rejuvenate_ack_resp; uint32_t rejuvenate_ack_err; @@ -456,6 +457,10 @@ static struct icnss_priv { struct icnss_wlan_mac_addr wlan_mac_addr; bool bypass_s1_smmu; struct mutex dev_lock; + u8 cause_for_rejuvenation; + u8 requesting_sub_system; + u16 line_number; + char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; } *penv; #ifdef CONFIG_ICNSS_DEBUG @@ -1691,6 +1696,60 @@ out: return ret; } +static int icnss_decode_rejuvenate_ind(void *msg, unsigned int msg_len) +{ + struct msg_desc ind_desc; + struct wlfw_rejuvenate_ind_msg_v01 ind_msg; + int ret = 0; + + if (!penv || !penv->wlfw_clnt) { + ret = -ENODEV; + goto out; + } + + memset(&ind_msg, 0, sizeof(ind_msg)); + + ind_desc.msg_id = QMI_WLFW_REJUVENATE_IND_V01; + ind_desc.max_msg_len = WLFW_REJUVENATE_IND_MSG_V01_MAX_MSG_LEN; + ind_desc.ei_array = wlfw_rejuvenate_ind_msg_v01_ei; + + ret = qmi_kernel_decode(&ind_desc, &ind_msg, msg, msg_len); + if (ret < 0) { + icnss_pr_err("Failed to decode rejuvenate ind message: ret %d, msg_len %u\n", + ret, msg_len); + goto out; + } + + if (ind_msg.cause_for_rejuvenation_valid) + penv->cause_for_rejuvenation = ind_msg.cause_for_rejuvenation; + else + penv->cause_for_rejuvenation = 0; + if (ind_msg.requesting_sub_system_valid) + penv->requesting_sub_system = ind_msg.requesting_sub_system; + else + penv->requesting_sub_system = 0; + if (ind_msg.line_number_valid) + penv->line_number = ind_msg.line_number; + else + penv->line_number = 0; + if (ind_msg.function_name_valid) + memcpy(penv->function_name, ind_msg.function_name, + QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1); + else + memset(penv->function_name, 0, + QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1); + + icnss_pr_info("Cause for rejuvenation: 0x%x, requesting sub-system: 0x%x, line number: %u, function name: %s\n", + penv->cause_for_rejuvenation, + penv->requesting_sub_system, + penv->line_number, + penv->function_name); + + penv->stats.rejuvenate_ind++; +out: + return ret; +} + static int wlfw_rejuvenate_ack_send_sync_msg(struct icnss_priv *priv) { int ret; @@ -1884,6 +1943,7 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle, msg_id, penv->state); icnss_ignore_qmi_timeout(true); + icnss_decode_rejuvenate_ind(msg, msg_len); event_data = kzalloc(sizeof(*event_data), GFP_KERNEL); if (event_data == NULL) return; @@ -3786,6 +3846,26 @@ static int icnss_stats_show_capability(struct seq_file *s, return 0; } +static int icnss_stats_show_rejuvenate_info(struct seq_file *s, + struct icnss_priv *priv) +{ + if (priv->stats.rejuvenate_ind) { + seq_puts(s, "\n<---------------- Rejuvenate Info ----------------->\n"); + seq_printf(s, "Number of Rejuvenations: %u\n", + priv->stats.rejuvenate_ind); + seq_printf(s, "Cause for Rejuvenation: 0x%x\n", + priv->cause_for_rejuvenation); + seq_printf(s, "Requesting Sub-System: 0x%x\n", + priv->requesting_sub_system); + seq_printf(s, "Line Number: %u\n", + priv->line_number); + seq_printf(s, "Function Name: %s\n", + priv->function_name); + } + + return 0; +} + static int icnss_stats_show_events(struct seq_file *s, struct icnss_priv *priv) { int i; @@ -3851,6 +3931,7 @@ static int icnss_stats_show(struct seq_file *s, void *data) ICNSS_STATS_DUMP(s, priv, vbatt_req); ICNSS_STATS_DUMP(s, priv, vbatt_resp); ICNSS_STATS_DUMP(s, priv, vbatt_req_err); + ICNSS_STATS_DUMP(s, priv, rejuvenate_ind); ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_req); ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_resp); ICNSS_STATS_DUMP(s, priv, rejuvenate_ack_err); @@ -3875,6 +3956,8 @@ static int icnss_stats_show(struct seq_file *s, void *data) icnss_stats_show_capability(s, priv); + icnss_stats_show_rejuvenate_info(s, priv); + icnss_stats_show_events(s, priv); icnss_stats_show_state(s, priv);