From 5ec748e3b952de6dd9de8a5c46c2af2d461d9156 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 1 Jul 2021 17:57:48 +0530 Subject: [PATCH] qcacmn: Check for msdu len err only when msdu cont bit is 0 If an MSDU is scattered across multiple nbufs, rx attention tlvs are only valid for the last nbuf for this MSDU. MSDU len err field is fetched from rx attention tlvs for all the nbufs which could result in an incorrect drop of packets. Fix is to check for msdu len err for nbufs with msdu continuation bit set to 0. Change-Id: I0ed5cbb37a2ba34a39328618e3f5e66d419d7cca CRs-Fixed: 2982308 --- dp/wifi3.0/dp_rx.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index b3cb408f1ef0..a277ddf1016a 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -2710,13 +2710,6 @@ done: vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf); peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf); - if (qdf_unlikely(hal_rx_attn_msdu_len_err_get(rx_tlv_hdr))) { - DP_STATS_INC(soc, rx.err.msdu_len_err, 1); - qdf_nbuf_free(nbuf); - nbuf = next; - continue; - } - if (dp_rx_is_list_ready(deliver_list_head, vdev, peer, peer_id, vdev_id)) { dp_rx_deliver_to_stack(soc, vdev, peer, @@ -2790,17 +2783,25 @@ done: * Check if DMA completed -- msdu_done is the last bit * to be written */ - if (qdf_unlikely(!qdf_nbuf_is_rx_chfrag_cont(nbuf) && - !hal_rx_attn_msdu_done_get(rx_tlv_hdr))) { - dp_err("MSDU DONE failure"); - DP_STATS_INC(soc, rx.err.msdu_done_fail, 1); - hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, - QDF_TRACE_LEVEL_INFO); - tid_stats->fail_cnt[MSDU_DONE_FAILURE]++; - qdf_nbuf_free(nbuf); - qdf_assert(0); - nbuf = next; - continue; + if (qdf_likely(!qdf_nbuf_is_rx_chfrag_cont(nbuf))) { + if (qdf_unlikely(!hal_rx_attn_msdu_done_get( + rx_tlv_hdr))) { + dp_err_rl("MSDU DONE failure"); + DP_STATS_INC(soc, rx.err.msdu_done_fail, 1); + hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, + QDF_TRACE_LEVEL_INFO); + tid_stats->fail_cnt[MSDU_DONE_FAILURE]++; + qdf_assert(0); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } else if (qdf_unlikely(hal_rx_attn_msdu_len_err_get( + rx_tlv_hdr))) { + DP_STATS_INC(soc, rx.err.msdu_len_err, 1); + qdf_nbuf_free(nbuf); + nbuf = next; + continue; + } } DP_HIST_PACKET_COUNT_INC(vdev->pdev->pdev_id);