summaryrefslogtreecommitdiff
path: root/hif/src
diff options
context:
space:
mode:
authorMohit Khanna <mkhannaqca@codeaurora.org>2016-10-06 19:58:02 -0700
committerMohit Khanna <mkhannaqca@codeaurora.org>2016-11-16 22:30:41 -0800
commit4e5c84e3fb0ece3bb6f3e0f86c2a20ae61225366 (patch)
treec9f28a4736d289988dc30367f18551eba56c2b21 /hif/src
parent2df19cb29e089911ec0e0a42d5646522faa6df39 (diff)
qcacmn: Add NAPI statistics to dumpstats
Currently NAPI stats are retrieved as a part of iwpriv getStats command. The buffer available for this command is limited and NAPI stats get trucncated. Add a new dumpStats parameter (9) to dump NAPI stats. Change-Id: Iaf52a3dcecac2f7b24fde2f8220fbfddc767965b CRs-Fixed: 1076563
Diffstat (limited to 'hif/src')
-rw-r--r--hif/src/ce/ce_main.h4
-rw-r--r--hif/src/ce/ce_service.c18
-rw-r--r--hif/src/ce/ce_tasklet.c5
-rw-r--r--hif/src/hif_napi.c85
4 files changed, 94 insertions, 18 deletions
diff --git a/hif/src/ce/ce_main.h b/hif/src/ce/ce_main.h
index 3023be80fe4c..4a68618bd1bc 100644
--- a/hif/src/ce/ce_main.h
+++ b/hif/src/ce/ce_main.h
@@ -112,7 +112,7 @@ struct ce_tasklet_entry {
void *hif_ce_state;
};
-struct ce_intr_stats {
+struct ce_stats {
uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU];
};
@@ -140,7 +140,7 @@ struct HIF_CE_state {
/* Copy Engine used for Diagnostic Accesses */
struct CE_handle *ce_diag;
- struct ce_intr_stats stats;
+ struct ce_stats stats;
};
/*
diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c
index 770f72c5126a..0cb54d6af9e8 100644
--- a/hif/src/ce/ce_service.c
+++ b/hif/src/ce/ce_service.c
@@ -35,6 +35,7 @@
#include "regtable.h"
#include "hif_main.h"
#include "hif_debug.h"
+#include "hif_napi.h"
#ifdef IPA_OFFLOAD
#ifdef QCA_WIFI_3_0
@@ -199,9 +200,20 @@ inline void ce_init_ce_desc_event_log(int ce_id, int size)
bool hif_ce_service_should_yield(struct hif_softc *scn,
struct CE_state *ce_state)
{
- bool yield = qdf_system_time_after_eq(qdf_system_ticks(),
- ce_state->ce_service_yield_time) ||
- hif_max_num_receives_reached(scn, ce_state->receive_count);
+ bool yield, time_limit_reached, rxpkt_thresh_reached = 0;
+
+ time_limit_reached = qdf_system_time_after_eq(qdf_system_ticks(),
+ ce_state->ce_service_yield_time);
+ if (!time_limit_reached)
+ rxpkt_thresh_reached = hif_max_num_receives_reached
+ (scn, ce_state->receive_count);
+
+ yield = time_limit_reached || rxpkt_thresh_reached;
+
+ if (yield)
+ hif_napi_update_yield_stats(ce_state,
+ time_limit_reached,
+ rxpkt_thresh_reached);
return yield;
}
diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c
index c820d874f788..b604c30dc4d1 100644
--- a/hif/src/ce/ce_tasklet.c
+++ b/hif/src/ce/ce_tasklet.c
@@ -437,7 +437,6 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state)
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]);
@@ -446,7 +445,7 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state)
size -= ret;
pos += ret;
}
- qdf_print("%s", str_buffer);
+ qdf_print("CE id[%d] - %s", i, str_buffer);
}
#undef STR_SIZE
}
@@ -459,7 +458,7 @@ void hif_display_ce_stats(struct HIF_CE_state *hif_ce_state)
*/
void hif_clear_ce_stats(struct HIF_CE_state *hif_ce_state)
{
- qdf_mem_zero(&hif_ce_state->stats, sizeof(struct ce_intr_stats));
+ qdf_mem_zero(&hif_ce_state->stats, sizeof(struct ce_stats));
}
/**
diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c
index 90c04dec7365..9c08e21f8697 100644
--- a/hif/src/hif_napi.c
+++ b/hif/src/hif_napi.c
@@ -799,22 +799,78 @@ out:
}
#ifdef HELIUMPLUS
-/*
- * Local functions
- * - no argument checks, all internal/trusted callers
+/**
+ *
+ * hif_napi_update_yield_stats() - update NAPI yield related stats
+ * @cpu_id: CPU ID for which stats needs to be updates
+ * @ce_id: Copy Engine ID for which yield stats needs to be updates
+ * @time_limit_reached: indicates whether the time limit was reached
+ * @rxpkt_thresh_reached: indicates whether rx packet threshold was reached
+ *
+ * Return: None
*/
+void hif_napi_update_yield_stats(struct CE_state *ce_state,
+ bool time_limit_reached,
+ bool rxpkt_thresh_reached)
+{
+ struct hif_softc *hif;
+ struct qca_napi_data *napi_data = NULL;
+ int ce_id = 0;
+ int cpu_id = 0;
+
+ if (unlikely(NULL == ce_state)) {
+ QDF_ASSERT(NULL != ce_state);
+ return;
+ }
-#ifdef FEATURE_NAPI_DEBUG
-static void hnc_dump_cpus(struct qca_napi_data *napid)
+ hif = ce_state->scn;
+
+ if (unlikely(NULL == hif)) {
+ QDF_ASSERT(NULL != hif);
+ return;
+ } else {
+ napi_data = &(hif->napi_data);
+ if (unlikely(NULL == napi_data))
+ QDF_ASSERT(NULL != napi_data);
+ return;
+ }
+
+ ce_id = ce_state->id;
+ cpu_id = qdf_get_cpu();
+
+ if (time_limit_reached)
+ napi_data->napis[ce_id].stats[cpu_id].time_limit_reached++;
+ else
+ napi_data->napis[ce_id].stats[cpu_id].rxpkt_thresh_reached++;
+}
+
+/**
+ *
+ * hif_napi_stats() - display NAPI CPU statistics
+ * @napid: pointer to qca_napi_data
+ *
+ * Description:
+ * Prints the various CPU cores on which the NAPI instances /CEs interrupts
+ * are being executed. Can be called from outside NAPI layer.
+ *
+ * Return: None
+ */
+void hif_napi_stats(struct qca_napi_data *napid)
{
int i;
- struct qca_napi_cpu *cpu = napid->napi_cpu;
+ struct qca_napi_cpu *cpu;
+
+ if (napid == NULL) {
+ qdf_print("%s: napiid struct is null", __func__);
+ return;
+ }
- NAPI_DEBUG("%s: NAPI CPU TABLE", __func__);
- NAPI_DEBUG("lilclhead=%d, bigclhead=%d",
+ cpu = napid->napi_cpu;
+ qdf_print("NAPI CPU TABLE");
+ qdf_print("lilclhead=%d, bigclhead=%d",
napid->lilcl_head, napid->bigcl_head);
for (i = 0; i < NR_CPUS; i++) {
- NAPI_DEBUG("CPU[%02d]: state:%d crid=%02d clid=%02d "
+ qdf_print("CPU[%02d]: state:%d crid=%02d clid=%02d "
"crmk:0x%0lx thmk:0x%0lx frq:%d "
"napi = 0x%08x lnk:%d",
i,
@@ -824,7 +880,16 @@ static void hnc_dump_cpus(struct qca_napi_data *napid)
cpu[i].max_freq, cpu[i].napis,
cpu[i].cluster_nxt);
}
- /* return; -- Linus does not like it, I do. */
+}
+
+#ifdef FEATURE_NAPI_DEBUG
+/*
+ * Local functions
+ * - no argument checks, all internal/trusted callers
+ */
+static void hnc_dump_cpus(struct qca_napi_data *napid)
+{
+ hif_napi_stats(napid);
}
#else
static void hnc_dump_cpus(struct qca_napi_data *napid) { /* no-op */ };