mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-01 16:27:08 +08:00
119 lines
4.3 KiB
Diff
119 lines
4.3 KiB
Diff
From 1e15aacd12386d8f1372929a3fd52db9ef3344fc Mon Sep 17 00:00:00 2001
|
|
From: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
|
|
Date: Thu, 10 Feb 2022 12:17:06 +0530
|
|
Subject: [PATCH] ath11k: fix destination monitor ring out of sync
|
|
|
|
More than 20000 PPDU id jumping causing status ring and destination
|
|
ring processing not sync. The status ring is processed and the
|
|
destination ring is not processed. Since destination is not reaped for
|
|
so long, backpressure occurs at the destination ring.
|
|
|
|
To address this issue update the PPDU id with the latest PPDU, this
|
|
will allow the destination ring to be reaped and will prevent the
|
|
rings from getting out of sync.
|
|
|
|
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1.r1-00026-QCAHKSWPL_SILICONZ-2
|
|
Signed-off-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
|
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
|
Link: https://lore.kernel.org/r/20220210064706.6171-1-quic_kathirve@quicinc.com
|
|
---
|
|
drivers/net/wireless/ath/ath11k/dp.h | 3 ++
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 42 +++++++++++++++++++++----
|
|
2 files changed, 39 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
|
|
index 409d6cc5a1d5..b6ec2d6a2bb6 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
|
@@ -115,6 +115,8 @@ struct ath11k_pdev_mon_stats {
|
|
u32 dest_mpdu_drop;
|
|
u32 dup_mon_linkdesc_cnt;
|
|
u32 dup_mon_buf_cnt;
|
|
+ u32 dest_mon_stuck;
|
|
+ u32 dest_mon_not_reaped;
|
|
};
|
|
|
|
struct dp_full_mon_mpdu {
|
|
@@ -167,6 +169,7 @@ struct ath11k_mon_data {
|
|
|
|
struct ath11k_pdev_dp {
|
|
u32 mac_id;
|
|
+ u32 mon_dest_ring_stuck_cnt;
|
|
atomic_t num_tx_pending;
|
|
wait_queue_head_t tx_empty_waitq;
|
|
struct dp_rxdma_ring rx_refill_buf_ring;
|
|
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
index 99dc9b5bbf4b..20c9e7904261 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -4959,6 +4959,12 @@ static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id,
|
|
return -EINVAL;
|
|
}
|
|
|
|
+/* The destination ring processing is stuck if the destination is not
|
|
+ * moving while status ring moves 16 PPDU. The destination ring processing
|
|
+ * skips this destination ring PPDU as a workaround.
|
|
+ */
|
|
+#define MON_DEST_RING_STUCK_MAX_CNT 16
|
|
+
|
|
static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
|
|
u32 quota, struct napi_struct *napi)
|
|
{
|
|
@@ -4972,6 +4978,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
|
|
u32 ring_id;
|
|
struct ath11k_pdev_mon_stats *rx_mon_stats;
|
|
u32 npackets = 0;
|
|
+ u32 mpdu_rx_bufs_used;
|
|
|
|
if (ar->ab->hw_params.rxdma1_enable)
|
|
ring_id = dp->rxdma_mon_dst_ring.ring_id;
|
|
@@ -5001,16 +5008,39 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
|
|
head_msdu = NULL;
|
|
tail_msdu = NULL;
|
|
|
|
- rx_bufs_used += ath11k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry,
|
|
- &head_msdu,
|
|
- &tail_msdu,
|
|
- &npackets, &ppdu_id);
|
|
+ mpdu_rx_bufs_used = ath11k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry,
|
|
+ &head_msdu,
|
|
+ &tail_msdu,
|
|
+ &npackets, &ppdu_id);
|
|
+
|
|
+ rx_bufs_used += mpdu_rx_bufs_used;
|
|
+
|
|
+ if (mpdu_rx_bufs_used) {
|
|
+ dp->mon_dest_ring_stuck_cnt = 0;
|
|
+ } else {
|
|
+ dp->mon_dest_ring_stuck_cnt++;
|
|
+ rx_mon_stats->dest_mon_not_reaped++;
|
|
+ }
|
|
+
|
|
+ if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) {
|
|
+ rx_mon_stats->dest_mon_stuck++;
|
|
+ ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
|
+ "status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n",
|
|
+ pmon->mon_ppdu_info.ppdu_id, ppdu_id,
|
|
+ dp->mon_dest_ring_stuck_cnt,
|
|
+ rx_mon_stats->dest_mon_not_reaped,
|
|
+ rx_mon_stats->dest_mon_stuck);
|
|
+ pmon->mon_ppdu_info.ppdu_id = ppdu_id;
|
|
+ continue;
|
|
+ }
|
|
|
|
if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) {
|
|
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
|
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
|
- "dest_rx: new ppdu_id %x != status ppdu_id %x",
|
|
- ppdu_id, pmon->mon_ppdu_info.ppdu_id);
|
|
+ "dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n",
|
|
+ ppdu_id, pmon->mon_ppdu_info.ppdu_id,
|
|
+ rx_mon_stats->dest_mon_not_reaped,
|
|
+ rx_mon_stats->dest_mon_stuck);
|
|
break;
|
|
}
|
|
if (head_msdu && tail_msdu) {
|
|
--
|
|
2.35.1
|
|
|