qcacld-3.0: Record CE interrupt and tasklet entry/exit

Record CE interrupt in CE event history since the interrupts
may come separately for the different interrupts.

Change-Id: I269a103054d3ab2015d67370c43f4af598871b8d
CRs-Fixed: 951569
This commit is contained in:
Houston Hoffman 2015-12-06 21:02:11 -08:00 • committed by Satish Singh
commit dee0d5374c
3 changed files with 22 additions and 1 deletions

View file

@ -294,6 +294,10 @@ union ce_desc {
* @HIF_TX_GATHER_DESC_POST: post gather desc. (no write index update)
* @HIF_TX_DESC_POST: event recorded before updating write index of TX ring.
* @HIF_TX_DESC_COMPLETION: event recorded before updating sw index of TX ring.
* @HIF_IRQ_EVENT: event recorded in the irq before scheduling the bh
* @HIF_CE_TASKLET_ENTRY: records the start of the ce_tasklet
* @HIF_CE_TASKLET_RESCHEDULE: records the rescheduling of the wlan_tasklet
* @HIF_CE_TASKLET_EXIT: records the exit of the wlan tasklet without reschedule
*/
enum hif_ce_event_type {
HIF_RX_DESC_POST,
@ -301,6 +305,10 @@ enum hif_ce_event_type {
HIF_TX_GATHER_DESC_POST,
HIF_TX_DESC_POST,
HIF_TX_DESC_COMPLETION,
HIF_IRQ_EVENT,
HIF_CE_TASKLET_ENTRY,
HIF_CE_TASKLET_RESCHEDULE,
HIF_CE_TASKLET_EXIT,
};
void ce_init_ce_desc_event_log(int ce_id, int size);

View file

@ -101,6 +101,7 @@ struct hif_ce_desc_event {
cdf_atomic_t hif_ce_desc_history_index[CE_COUNT_MAX];
struct hif_ce_desc_event hif_ce_desc_history[CE_COUNT_MAX][HIF_CE_HISTORY_MAX];
/**
* get_next_record_index() - get the next record index
* @table_index: atomic index variable to increment
@ -142,7 +143,10 @@ void hif_record_ce_desc_event(int ce_id, enum hif_ce_event_type type,
&hif_ce_desc_history[ce_id][record_index];
event->type = type;
event->time = cds_get_monotonic_boottime();
event->descriptor = *descriptor;
if (descriptor != NULL)
event->descriptor = *descriptor;
else
memset(&event->descriptor, 0, sizeof(union ce_desc));
event->memory = memory;
event->index = index;
}

View file

@ -203,6 +203,9 @@ static void ce_tasklet(unsigned long data)
struct ol_softc *scn = hif_ce_state->scn;
struct CE_state *CE_state = scn->ce_id_to_state[tasklet_entry->ce_id];
hif_record_ce_desc_event(tasklet_entry->ce_id, HIF_CE_TASKLET_ENTRY,
NULL, NULL, 0);
if (cdf_atomic_read(&scn->link_suspended)) {
HIF_ERROR("%s: ce %d tasklet fired after link suspend.",
__func__, tasklet_entry->ce_id);
@ -221,6 +224,8 @@ static void ce_tasklet(unsigned long data)
* Enable the interrupt only when there is no pending frames in
* any of the Copy Engine pipes.
*/
hif_record_ce_desc_event(tasklet_entry->ce_id,
HIF_CE_TASKLET_RESCHEDULE, NULL, NULL, 0);
ce_schedule_tasklet(tasklet_entry);
return;
}
@ -228,6 +233,9 @@ static void ce_tasklet(unsigned long data)
if (scn->target_status != OL_TRGET_STATUS_RESET)
ce_irq_enable(scn, tasklet_entry->ce_id);
hif_record_ce_desc_event(tasklet_entry->ce_id, HIF_CE_TASKLET_EXIT,
NULL, NULL, 0);
cdf_atomic_dec(&scn->active_tasklet_cnt);
}
/**
@ -301,6 +309,7 @@ static irqreturn_t ce_irq_handler(int irq, void *context)
ce_irq_disable(scn, ce_id);
ce_irq_status(scn, ce_id, &host_status);
cdf_atomic_inc(&scn->active_tasklet_cnt);
hif_record_ce_desc_event(ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
if (hif_napi_enabled(scn, ce_id))
hif_napi_schedule(scn, ce_id);
else