diff --git a/dp/wifi3.0/be/dp_be_rx.c b/dp/wifi3.0/be/dp_be_rx.c index b6370150b5..5243f1936e 100644 --- a/dp/wifi3.0/be/dp_be_rx.c +++ b/dp/wifi3.0/be/dp_be_rx.c @@ -69,6 +69,30 @@ dp_rx_update_flow_info(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr) } #endif +#ifdef DP_RX_MSDU_DONE_FAIL_HISTORY +static inline void +dp_rx_msdu_done_fail_event_record(struct dp_soc *soc, + qdf_nbuf_t nbuf) +{ + struct dp_msdu_done_fail_entry *entry; + uint32_t idx; + + if (qdf_unlikely(!soc->msdu_done_fail_hist)) + return; + + idx = dp_history_get_next_index(&soc->msdu_done_fail_hist->index, + DP_MSDU_DONE_FAIL_HIST_MAX); + entry = &soc->msdu_done_fail_hist->entry[idx]; + entry->paddr = qdf_nbuf_get_frag_paddr(nbuf, 0); +} +#else +static inline void +dp_rx_msdu_done_fail_event_record(struct dp_soc *soc, + qdf_nbuf_t nbuf) +{ +} +#endif + #ifndef AST_OFFLOAD_ENABLE static void dp_rx_wds_learn(struct dp_soc *soc, @@ -612,10 +636,12 @@ done: */ if (qdf_unlikely(!qdf_nbuf_is_rx_chfrag_cont(nbuf) && !hal_rx_tlv_msdu_done_get_be(rx_tlv_hdr))) { - dp_err("MSDU DONE failure"); DP_STATS_INC(soc, rx.err.msdu_done_fail, 1); + dp_err("MSDU DONE failure %d", + soc->stats.rx.err.msdu_done_fail); hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, QDF_TRACE_LEVEL_INFO); + dp_rx_msdu_done_fail_event_record(soc, nbuf); tid_stats->fail_cnt[MSDU_DONE_FAILURE]++; dp_rx_nbuf_free(nbuf); qdf_assert(0); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 1667c289e2..703904ffdf 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3469,6 +3469,30 @@ static inline void dp_soc_tx_history_detach(struct dp_soc *soc) } #endif /* WLAN_FEATURE_DP_TX_DESC_HISTORY */ +#ifdef DP_RX_MSDU_DONE_FAIL_HISTORY +static void dp_soc_msdu_done_fail_history_attach(struct dp_soc *soc) +{ + soc->msdu_done_fail_hist = + qdf_mem_malloc(sizeof(struct dp_msdu_done_fail_history)); + if (soc->msdu_done_fail_hist) + qdf_atomic_init(&soc->msdu_done_fail_hist->index); +} + +static void dp_soc_msdu_done_fail_history_detach(struct dp_soc *soc) +{ + if (soc->msdu_done_fail_hist) + qdf_mem_free(soc->msdu_done_fail_hist); +} +#else +static inline void dp_soc_msdu_done_fail_history_attach(struct dp_soc *soc) +{ +} + +static inline void dp_soc_msdu_done_fail_history_detach(struct dp_soc *soc) +{ +} +#endif + #ifdef WLAN_SUPPORT_RX_FLOW_TAG QDF_STATUS dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev) @@ -4030,6 +4054,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc) dp_soc_mon_status_ring_history_detach(soc); dp_soc_rx_history_detach(soc); dp_soc_cfg_history_detach(soc); + dp_soc_msdu_done_fail_history_detach(soc); if (!dp_monitor_modularized_enable()) { dp_mon_soc_detach_wrapper(soc); @@ -13650,6 +13675,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, dp_soc_rx_history_attach(soc); dp_soc_mon_status_ring_history_attach(soc); dp_soc_tx_history_attach(soc); + dp_soc_msdu_done_fail_history_attach(soc); wlan_set_srng_cfg(&soc->wlan_srng_cfg); soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc); if (!soc->wlan_cfg_ctx) { @@ -13743,6 +13769,7 @@ fail4: fail3: wlan_cfg_soc_detach(soc->wlan_cfg_ctx); fail2: + dp_soc_msdu_done_fail_history_detach(soc); qdf_mem_free(soc->cdp_soc.ops); fail1: qdf_mem_common_free(soc); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index a255db1c3a..5d5233dc4c 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2643,6 +2643,20 @@ struct test_qaddr_del { uint8_t chip_id; }; +#ifdef DP_RX_MSDU_DONE_FAIL_HISTORY + +#define DP_MSDU_DONE_FAIL_HIST_MAX 32 + +struct dp_msdu_done_fail_entry { + qdf_dma_addr_t paddr; +}; + +struct dp_msdu_done_fail_history { + qdf_atomic_t index; + struct dp_msdu_done_fail_entry entry[DP_MSDU_DONE_FAIL_HIST_MAX]; +}; +#endif + /* SOC level structure for data path */ struct dp_soc { /** @@ -3212,6 +3226,9 @@ struct dp_soc { uint64_t start_time; } stale_entry[MAX_TCL_DATA_RINGS]; #endif +#ifdef DP_RX_MSDU_DONE_FAIL_HISTORY + struct dp_msdu_done_fail_history *msdu_done_fail_hist; +#endif }; #ifdef IPA_OFFLOAD