mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 19:03:39 +00:00
131 lines
5.3 KiB
Diff
131 lines
5.3 KiB
Diff
From d762e0422fc0636f1eec53ebbec23a2258058734 Mon Sep 17 00:00:00 2001
|
|
From: P Praneesh <quic_ppranees@quicinc.com>
|
|
Date: Tue, 30 Aug 2022 22:04:01 +0530
|
|
Subject: [PATCH 2/4] ath11k: add length validation before skb_put call
|
|
|
|
In the wbm_err path, while processing tkip mic error msdu_len is fetched
|
|
from the hal_rx_desc's msdu_end. This msdu_len is directly passing to the
|
|
skb_put without the validation.
|
|
|
|
In the stretch test scenario, some of the descriptors received under wbm_err
|
|
is invalid and carries junk values which leads to higher msdu_len compare to
|
|
actual msdu data size.
|
|
|
|
Add a check to drop the skb when the calculation msdu length is greater than
|
|
the skb size and add provision to capture the dropped packet count in
|
|
soc_dp_stats.
|
|
|
|
Change-Id: I83e3440492c23a98fc3b667a78a9cc0449101231
|
|
Signed-off-by: Tamizh Chelvam Raja <quic_tamizhr@quicinc.com>
|
|
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 2 ++
|
|
drivers/net/wireless/ath/ath11k/debugfs.c | 10 ++++++----
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 21 +++++++++++++++++----
|
|
3 files changed, 25 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
|
|
index 0fb2e80..4b17c42 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -1007,7 +1007,9 @@ struct ath11k_soc_dp_stats {
|
|
u32 err_ring_pkts;
|
|
u32 invalid_rbm;
|
|
u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
|
|
+ u32 rxdma_error_drop[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
|
|
u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
|
|
+ u32 reo_error_drop[HAL_REO_DEST_RING_ERROR_CODE_MAX];
|
|
u32 hal_reo_error[DP_REO_DST_RING_MAX];
|
|
struct ath11k_soc_dp_tx_err_stats tx_err;
|
|
struct ath11k_dp_ring_bp_stats bp_stats;
|
|
diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
index d62fca7..0ae0ef5 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
|
@@ -1576,13 +1576,15 @@ static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
|
|
soc_stats->invalid_rbm);
|
|
len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
|
|
for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
|
|
- len += scnprintf(buf + len, size - len, "%s: %u\n",
|
|
- rxdma_err[i], soc_stats->rxdma_error[i]);
|
|
+ len += scnprintf(buf + len, size - len, "%s: handled %u dropped %u\n",
|
|
+ rxdma_err[i], soc_stats->rxdma_error[i],
|
|
+ soc_stats->rxdma_error_drop[i]);
|
|
|
|
len += scnprintf(buf + len, size - len, "\nREO errors:\n");
|
|
for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
|
|
- len += scnprintf(buf + len, size - len, "%s: %u\n",
|
|
- reo_err[i], soc_stats->reo_error[i]);
|
|
+ len += scnprintf(buf + len, size - len, "%s: handled %u dropped %u\n",
|
|
+ reo_err[i], soc_stats->reo_error[i],
|
|
+ soc_stats->reo_error_drop[i]);
|
|
|
|
len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
|
|
len += scnprintf(buf + len, size - len,
|
|
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
index 5946c5d..aefea73 100644
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -5054,8 +5054,6 @@ static bool ath11k_dp_rx_h_reo_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
|
bool drop = false;
|
|
|
|
- ar->ab->soc_stats.reo_error[rxcb->err_code]++;
|
|
-
|
|
switch (rxcb->err_code) {
|
|
case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
|
|
if (ath11k_dp_rx_h_null_q_desc(ar, msdu, status, msdu_list))
|
|
@@ -5075,10 +5073,15 @@ static bool ath11k_dp_rx_h_reo_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
break;
|
|
}
|
|
|
|
+ if (drop)
|
|
+ ar->ab->soc_stats.reo_error_drop[rxcb->err_code]++;
|
|
+ else
|
|
+ ar->ab->soc_stats.reo_error[rxcb->err_code]++;
|
|
+
|
|
return drop;
|
|
}
|
|
|
|
-static void ath11k_dp_rx_h_tkip_mic_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
+static bool ath11k_dp_rx_h_tkip_mic_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
struct ieee80211_rx_status *status)
|
|
{
|
|
u16 msdu_len;
|
|
@@ -5092,6 +5095,14 @@ static void ath11k_dp_rx_h_tkip_mic_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
|
|
l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, desc);
|
|
msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc);
|
|
+
|
|
+ if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) {
|
|
+ ath11k_warn(ar->ab, "invalid msdu len in tkip mirc err %u\n", msdu_len);
|
|
+ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", desc,
|
|
+ sizeof(struct hal_rx_desc));
|
|
+ return true;
|
|
+ }
|
|
+
|
|
skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
|
|
skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
|
|
|
|
@@ -5102,6 +5113,8 @@ static void ath11k_dp_rx_h_tkip_mic_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
|
|
ath11k_dp_rx_h_undecap(ar, msdu, desc,
|
|
HAL_ENCRYPT_TYPE_TKIP_MIC, status, false);
|
|
+
|
|
+ return false;
|
|
}
|
|
|
|
static bool ath11k_dp_rx_h_rxdma_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
@@ -5114,7 +5127,7 @@ static bool ath11k_dp_rx_h_rxdma_err(struct ath11k *ar, struct sk_buff *msdu,
|
|
|
|
switch (rxcb->err_code) {
|
|
case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:
|
|
- ath11k_dp_rx_h_tkip_mic_err(ar, msdu, status);
|
|
+ drop = ath11k_dp_rx_h_tkip_mic_err(ar, msdu, status);
|
|
break;
|
|
default:
|
|
/* TODO: Review other rxdma error code to check if anything is
|
|
--
|
|
2.17.1
|
|
|