Currently, the monitor destination ring's descriptor includes a 2-bit field for the end reason. Out of all the end reason values, hardware uses HAL_MON_FLUSH_DETECTED and HAL_MON_PPDU_TRUNCATED to indicate buffers that should not be processed due to system level errors. Driver should not process entries with these end reasons, as they contain junk values. However, the current code lacks end reason-specific checks for the monitor destination ring, leading to the processing of invalid buffers. Fix this by adding checks for these two end reasons during the reaping phase. Free the skb if either HAL_MON_FLUSH_DETECTED or HAL_MON_PPDU_TRUNCATED is detected, preventing the driver from processing invalid entries. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: P Praneesh <quic_ppranees@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath12k/dp_mon.c | 17 ++++++++++++++++- drivers/net/wireless/ath/ath12k/hal_desc.h | 3 +-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_mon.c b/drivers/net/wireless/ath/ath12k/dp_mon.c index bf43ef2b6b39..dbf5afd88ad5 100644 --- a/drivers/net/wireless/ath/ath12k/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/dp_mon.c @@ -2329,7 +2329,7 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, struct sk_buff_head skb_list; u64 cookie; int num_buffs_reaped = 0, srng_id, buf_id; - u32 hal_status, end_offset, info0; + u32 hal_status, end_offset, info0, end_reason; u8 pdev_idx = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, ar->pdev_idx); __skb_queue_head_init(&skb_list); @@ -2373,6 +2373,21 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget, skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); + end_reason = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_REASON); + + /* HAL_MON_FLUSH_DETECTED implies that an rx flush received at the end of + * rx PPDU and HAL_MON_PPDU_TRUNCATED implies that the PPDU got + * truncated due to a system level error. In both the cases, buffer data + * can be discarded + */ + if ((end_reason == HAL_MON_FLUSH_DETECTED) || + (end_reason == HAL_MON_PPDU_TRUNCATED)) { + ath12k_dbg(ab, ATH12K_DBG_DATA, + "Monitor dest descriptor end reason %d", end_reason); + dev_kfree_skb_any(skb); + goto move_next; + } + end_offset = u32_get_bits(info0, HAL_MON_DEST_INFO0_END_OFFSET); if (likely(end_offset <= DP_RX_BUFFER_SIZE)) { skb_put(skb, end_offset); diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/hal_desc.h index a102d27e5785..3e8983b85de8 100644 --- a/drivers/net/wireless/ath/ath12k/hal_desc.h +++ b/drivers/net/wireless/ath/ath12k/hal_desc.h @@ -2969,8 +2969,7 @@ struct hal_mon_buf_ring { #define HAL_MON_DEST_COOKIE_BUF_ID GENMASK(17, 0) #define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(11, 0) -#define HAL_MON_DEST_INFO0_FLUSH_DETECTED BIT(16) -#define HAL_MON_DEST_INFO0_END_OF_PPDU BIT(17) +#define HAL_MON_DEST_INFO0_END_REASON GENMASK(17, 16) #define HAL_MON_DEST_INFO0_INITIATOR BIT(18) #define HAL_MON_DEST_INFO0_EMPTY_DESC BIT(19) #define HAL_MON_DEST_INFO0_RING_ID GENMASK(27, 20) -- 2.34.1