From f76d6062ce1f68f110956b1f3d1df02abd9f8a54 Mon Sep 17 00:00:00 2001 From: Kai Chen Date: Wed, 3 Jul 2019 16:13:01 -0700 Subject: [PATCH] qcacmn: work around on monitor buffer ring back pressure issue destination ring MPDU processing is stuck because ppdu id is not sync between monitor status ring and monitor destination ring. Add logic to detect destination ring process stuck and jump over destination ring stuck entry. Change-Id: I17d9b5fba06a28239ec64d864ae7944ae04a7dae --- dp/wifi3.0/dp_rx_mon_dest.c | 34 +++++++++++++++++++++++++++++----- dp/wifi3.0/dp_types.h | 3 +++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 8fbf8f1564..832b4f6082 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -38,6 +38,12 @@ * It is assume wrap around. */ #define NOT_PPDU_ID_WRAP_AROUND 20000 +/* + * The destination ring processing is stuck if the destrination is not + * moving while status ring moves 16 ppdu. the destination ring processing + * skips this destination ring ppdu as walkaround + */ +#define MON_DEST_RING_STUCK_MAX_CNT 16 /** * dp_rx_mon_link_desc_return() - Return a MPDU link descriptor to HW @@ -1068,6 +1074,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) union dp_rx_desc_list_elem_t *tail = NULL; uint32_t ppdu_id; uint32_t rx_bufs_used; + uint32_t mpdu_rx_bufs_used; int mac_for_pdev = dp_get_mac_id_for_mac(soc, mac_id); struct cdp_pdev_mon_stats *rx_mon_stats; @@ -1105,11 +1112,28 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) head_msdu = (qdf_nbuf_t) NULL; tail_msdu = (qdf_nbuf_t) NULL; - rx_bufs_used += dp_rx_mon_mpdu_pop(soc, mac_id, - rxdma_dst_ring_desc, - &head_msdu, &tail_msdu, - &npackets, &ppdu_id, - &head, &tail); + mpdu_rx_bufs_used = + dp_rx_mon_mpdu_pop(soc, mac_id, + rxdma_dst_ring_desc, + &head_msdu, &tail_msdu, + &npackets, &ppdu_id, + &head, &tail); + + rx_bufs_used += mpdu_rx_bufs_used; + + if (mpdu_rx_bufs_used) + pdev->mon_dest_ring_stuck_cnt = 0; + else + pdev->mon_dest_ring_stuck_cnt++; + + if (pdev->mon_dest_ring_stuck_cnt > + MON_DEST_RING_STUCK_MAX_CNT) { + dp_alert("destination ring stuck"); + dp_alert("ppdu_id status=%d dest=%d", + pdev->ppdu_info.com_info.ppdu_id, ppdu_id); + pdev->ppdu_info.com_info.ppdu_id = ppdu_id; + continue; + } if (ppdu_id != pdev->ppdu_info.com_info.ppdu_id) { rx_mon_stats->stat_ring_ppdu_id_hist[ diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index c9cac73b6c..35b66222b4 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1338,6 +1338,9 @@ struct dp_pdev { struct dp_srng rxdma_mon_desc_ring[NUM_RXDMA_RINGS_PER_PDEV]; + /* Stuck count on monitor destination ring MPDU process */ + uint32_t mon_dest_ring_stuck_cnt; + /* * re-use memory section ends * reuse memory/deinit indicator