diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 898434cce2..908f8eb944 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -633,6 +633,15 @@ static inline void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx, } #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */ +void hif_display_ctrl_traffic_pipes_state(struct hif_opaque_softc *hif_ctx); + +#if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) +void hif_display_latest_desc_hist(struct hif_opaque_softc *hif_ctx); +#else +static +inline void hif_display_latest_desc_hist(struct hif_opaque_softc *hif_ctx) {} +#endif + /** * enum HIF_DEVICE_POWER_CHANGE_TYPE: Device Power change type * diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 59e03b26f3..ed274692b9 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -168,6 +168,68 @@ void hif_ce_desc_record_rx_paddr(struct hif_softc *scn, } #endif /* HIF_RECORD_RX_PADDR */ +void hif_display_latest_desc_hist(struct hif_opaque_softc *hif_ctx) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + struct ce_desc_hist *ce_hist; + struct latest_evt_history *evt; + int i; + + if (!scn) + return; + + ce_hist = &scn->hif_ce_desc_hist; + + for (i = 0; i < HIF_CE_MAX_LATEST_HIST; i++) { + if (!ce_hist->enable[i + HIF_CE_MAX_LATEST_HIST]) + continue; + + evt = &ce_hist->latest_evt[i]; + hif_info_high("CE_id:%d cpu_id:%d irq_entry:0x%llx tasklet_entry:0x%llx tasklet_resched:0x%llx tasklet_exit:0x%llx ce_work:0x%llx hp:%x tp:%x", + (i + HIF_CE_MAX_LATEST_HIST), evt->cpu_id, + evt->irq_entry_ts, evt->bh_entry_ts, + evt->bh_resched_ts, evt->bh_exit_ts, + evt->bh_work_ts, evt->ring_hp, evt->ring_tp); + } +} + +void hif_record_latest_evt(struct ce_desc_hist *ce_hist, + uint8_t type, + int ce_id, uint64_t time, + uint32_t hp, uint32_t tp) +{ + struct latest_evt_history *latest_evt; + + if (ce_id != 2 && ce_id != 3) + return; + + latest_evt = &ce_hist->latest_evt[ce_id - HIF_CE_MAX_LATEST_HIST]; + + switch (type) { + case HIF_IRQ_EVENT: + latest_evt->irq_entry_ts = time; + latest_evt->cpu_id = qdf_get_cpu(); + break; + case HIF_CE_TASKLET_ENTRY: + latest_evt->bh_entry_ts = time; + break; + case HIF_CE_TASKLET_RESCHEDULE: + latest_evt->bh_resched_ts = time; + break; + case HIF_CE_TASKLET_EXIT: + latest_evt->bh_exit_ts = time; + break; + case HIF_TX_DESC_COMPLETION: + case HIF_CE_DEST_STATUS_RING_REAP: + latest_evt->bh_work_ts = time; + latest_evt->ring_hp = hp; + latest_evt->ring_tp = tp; + break; + default: + break; + } +} + /** * hif_record_ce_desc_event() - record ce descriptor events * @scn: hif_softc @@ -227,6 +289,8 @@ void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id, if (ce_hist->data_enable[ce_id]) hif_ce_desc_data_record(event, len); + + hif_record_latest_evt(ce_hist, type, ce_id, event->time, 0, 0); } qdf_export_symbol(hif_record_ce_desc_event); diff --git a/hif/src/ce/ce_service_legacy.c b/hif/src/ce/ce_service_legacy.c index 53f60045a4..85ced1c8ac 100644 --- a/hif/src/ce/ce_service_legacy.c +++ b/hif/src/ce/ce_service_legacy.c @@ -1264,6 +1264,8 @@ static bool ce_check_int_watermark(struct CE_state *CE_state, return false; } +void hif_display_ctrl_traffic_pipes_state(struct hif_opaque_softc *hif_ctx) { } + #ifdef HIF_CE_LOG_INFO /** * ce_get_index_info_legacy(): Get CE index info diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c index 6bc3abe959..b26fa1a45d 100644 --- a/hif/src/ce/ce_service_srng.c +++ b/hif/src/ce/ce_service_srng.c @@ -78,6 +78,26 @@ (uint32_t)(((dma_addr) >> 32) & 0xFF);\ } while (0) +void hif_display_ctrl_traffic_pipes_state(struct hif_opaque_softc *hif_ctx) +{ + struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx); + struct CE_state *CE_state; + uint32_t hp = 0, tp = 0; + + CE_state = scn->ce_id_to_state[2]; + hal_get_sw_hptp(scn->hal_soc, + CE_state->status_ring->srng_ctx, + &tp, &hp); + hif_info_high("CE-2 Dest status ring current snapshot HP:%u TP:%u", + hp, tp); + + hp = 0; + tp = 0; + CE_state = scn->ce_id_to_state[3]; + hal_get_sw_hptp(scn->hal_soc, CE_state->src_ring->srng_ctx, &tp, &hp); + hif_info_high("CE-3 Source ring current snapshot HP:%u TP:%u", hp, tp); +} + #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, enum hif_ce_event_type type, @@ -131,6 +151,9 @@ void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, if (ce_hist->data_enable[ce_id]) hif_ce_desc_data_record(event, len); + + hif_record_latest_evt(ce_hist, type, ce_id, event->time, + event->current_hp, event->current_tp); } #endif /* HIF_CONFIG_SLUB_DEBUG_ON || HIF_CE_DEBUG_DATA_BUF */ diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index dbc7b68cbf..0c07eefd4a 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -182,6 +182,20 @@ struct hif_latency_detect { * for defined here */ #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF) + +#define HIF_CE_MAX_LATEST_HIST 2 + +struct latest_evt_history { + uint64_t irq_entry_ts; + uint64_t bh_entry_ts; + uint64_t bh_resched_ts; + uint64_t bh_exit_ts; + uint64_t bh_work_ts; + int cpu_id; + uint32_t ring_hp; + uint32_t ring_tp; +}; + struct ce_desc_hist { qdf_atomic_t history_index[CE_COUNT_MAX]; uint8_t ce_id_hist_map[CE_COUNT_MAX]; @@ -191,7 +205,13 @@ struct ce_desc_hist { uint32_t hist_index; uint32_t hist_id; void *hist_ev[CE_COUNT_MAX]; + struct latest_evt_history latest_evt[HIF_CE_MAX_LATEST_HIST]; }; + +void hif_record_latest_evt(struct ce_desc_hist *ce_hist, + uint8_t type, + int ce_id, uint64_t time, + uint32_t hp, uint32_t tp); #endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)*/ /**