diff --git a/core/hif/src/ce/ce_internal.h b/core/hif/src/ce/ce_internal.h index 0592d2018ba5..d95f27cd3e4f 100644 --- a/core/hif/src/ce/ce_internal.h +++ b/core/hif/src/ce/ce_internal.h @@ -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); diff --git a/core/hif/src/ce/ce_service.c b/core/hif/src/ce/ce_service.c index 6f48a2b96d9b..5f474ccaeebf 100644 --- a/core/hif/src/ce/ce_service.c +++ b/core/hif/src/ce/ce_service.c @@ -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; } diff --git a/core/hif/src/ce/ce_tasklet.c b/core/hif/src/ce/ce_tasklet.c index 2ca61ca34a2e..a2edeba26563 100644 --- a/core/hif/src/ce/ce_tasklet.c +++ b/core/hif/src/ce/ce_tasklet.c @@ -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