summaryrefslogtreecommitdiff
path: root/hif/src/ce
diff options
context:
space:
mode:
authorNirav Shah <nnshah@codeaurora.org>2016-05-25 14:31:51 +0530
committerNandini Suresh <snandini@codeaurora.org>2016-06-30 03:11:34 -0700
commitb70bd731ec4648f9eea303c7a954192e951173eb (patch)
tree6ba5e03f032a6a4d875747e4116b75ed2b7d1caf /hif/src/ce
parent8f7d421854a837bf0116e11e16f63999210d1168 (diff)
qcacmn: Add per CPU interrupt statistics
Add per CPU per copy engine interrupt statistics. Change-Id: I1619f0db3314ae3d915284459f2b191f31fc2190 CRs-Fixed: 1017437
Diffstat (limited to 'hif/src/ce')
-rw-r--r--hif/src/ce/ce_main.h6
-rw-r--r--hif/src/ce/ce_tasklet.c58
-rw-r--r--hif/src/ce/ce_tasklet.h2
3 files changed, 66 insertions, 0 deletions
diff --git a/hif/src/ce/ce_main.h b/hif/src/ce/ce_main.h
index 6c3a67f91937..3023be80fe4c 100644
--- a/hif/src/ce/ce_main.h
+++ b/hif/src/ce/ce_main.h
@@ -31,6 +31,7 @@
#include "qdf_atomic.h"
#include "qdf_lock.h"
#include "hif_main.h"
+#include "qdf_util.h"
#define CE_HTT_T2H_MSG 1
#define CE_HTT_H2T_MSG 4
@@ -111,6 +112,10 @@ struct ce_tasklet_entry {
void *hif_ce_state;
};
+struct ce_intr_stats {
+ uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU];
+};
+
struct HIF_CE_state {
struct hif_softc ol_sc;
bool started;
@@ -135,6 +140,7 @@ struct HIF_CE_state {
/* Copy Engine used for Diagnostic Accesses */
struct CE_handle *ce_diag;
+ struct ce_intr_stats stats;
};
/*
diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c
index 5c692cc6a03d..c03a6958479f 100644
--- a/hif/src/ce/ce_tasklet.c
+++ b/hif/src/ce/ce_tasklet.c
@@ -257,6 +257,63 @@ static irqreturn_t hif_snoc_interrupt_handler(int irq, void *context)
}
/**
+ * hif_ce_increment_interrupt_count() - update ce stats
+ * @hif_ce_state: ce state
+ * @ce_id: ce id
+ *
+ * Return: none
+ */
+static inline void
+hif_ce_increment_interrupt_count(struct HIF_CE_state *hif_ce_state, int ce_id)
+{
+ int cpu_id = qdf_get_cpu();
+
+ hif_ce_state->stats.ce_per_cpu[ce_id][cpu_id]++;
+}
+
+/**
+ * hif_display_ce_stats() - display ce stats
+ * @hif_ce_state: ce state
+ *
+ * Return: none
+ */
+void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state)
+{
+#define STR_SIZE 128
+ uint8_t i, j, pos;
+ char str_buffer[STR_SIZE];
+ int size, ret;
+
+ qdf_print("CE interrupt statistics:");
+ for (i = 0; i < CE_COUNT_MAX; i++) {
+ size = STR_SIZE;
+ pos = 0;
+ qdf_print("CE id: %d", i);
+ for (j = 0; j < QDF_MAX_AVAILABLE_CPU; j++) {
+ ret = snprintf(str_buffer + pos, size, "[%d]: %d",
+ j, hif_ce_state->stats.ce_per_cpu[i][j]);
+ if (ret <= 0 || ret >= size)
+ break;
+ size -= ret;
+ pos += ret;
+ }
+ qdf_print("%s", str_buffer);
+ }
+#undef STR_SIZE
+}
+
+/**
+ * hif_clear_ce_stats() - clear ce stats
+ * @hif_ce_state: ce state
+ *
+ * Return: none
+ */
+void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state)
+{
+ qdf_mem_zero(&hif_ce_state->stats, sizeof(struct ce_intr_stats));
+}
+
+/**
* ce_dispatch_interrupt() - dispatch an interrupt to a processing context
* @ce_id: ce_id
* @tasklet_entry: context
@@ -283,6 +340,7 @@ irqreturn_t ce_dispatch_interrupt(int ce_id,
hif_irq_disable(scn, ce_id);
qdf_atomic_inc(&scn->active_tasklet_cnt);
hif_record_ce_desc_event(scn, ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
+ hif_ce_increment_interrupt_count(hif_ce_state, ce_id);
if (hif_napi_enabled(hif_hdl, ce_id))
hif_napi_schedule(hif_hdl, ce_id);
else
diff --git a/hif/src/ce/ce_tasklet.h b/hif/src/ce/ce_tasklet.h
index d2fa22c64b33..1b158aedfde7 100644
--- a/hif/src/ce/ce_tasklet.h
+++ b/hif/src/ce/ce_tasklet.h
@@ -35,4 +35,6 @@ QDF_STATUS ce_register_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask);
QDF_STATUS ce_unregister_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask);
irqreturn_t ce_dispatch_interrupt(int irq,
struct ce_tasklet_entry *tasklet_entry);
+void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state);
+void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state);
#endif /* __CE_TASKLET_H__ */