diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index b38d469b4983..d2977676e27e 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -273,6 +273,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, bool is_frag, is_first_msdu; bool drop_mpdu = false; uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; + uint64_t nbuf_paddr = 0; msdu = 0; @@ -318,22 +319,30 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, uint32_t l2_hdr_offset; struct dp_rx_desc *rx_desc = NULL; - /* WAR for duplicate buffers received from HW */ - if (qdf_unlikely(dp_pdev->mon_last_buf_cookie == - msdu_list.sw_cookie[i])) { - /* Skip duplicate buffer and drop subsequent - * buffers in this MPDU - */ - drop_mpdu = true; - dp_pdev->rx_mon_stats.dup_mon_buf_cnt++; - continue; - } rx_desc = dp_rx_get_mon_desc(soc, msdu_list.sw_cookie[i]); qdf_assert_always(rx_desc); msdu = rx_desc->nbuf; + if (msdu) + nbuf_paddr = qdf_nbuf_get_frag_paddr(msdu, 0); + /* WAR for duplicate buffers received from HW */ + if (qdf_unlikely(dp_pdev->mon_last_buf_cookie == + msdu_list.sw_cookie[i] || + !msdu || + msdu_list.paddr[i] != nbuf_paddr || + !rx_desc->in_use)) { + /* Skip duplicate buffer and drop subsequent + * buffers in this MPDU + */ + drop_mpdu = true; + dp_pdev->rx_mon_stats.dup_mon_buf_cnt++; + dp_pdev->mon_last_linkdesc_paddr = + buf_info.paddr; + continue; + } + if (rx_desc->unmapped == 0) { qdf_nbuf_unmap_single(soc->osdev, msdu, QDF_DMA_FROM_DEVICE); @@ -341,6 +350,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, } if (drop_mpdu) { + dp_pdev->mon_last_linkdesc_paddr = + buf_info.paddr; qdf_nbuf_free(msdu); msdu = NULL; goto next_msdu; diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h index d3fa0bf33fc1..12c70a3e4f74 100644 --- a/hal/wifi3.0/hal_rx.h +++ b/hal/wifi3.0/hal_rx.h @@ -1941,6 +1941,8 @@ struct hal_rx_msdu_list { struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC]; uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC]; uint8_t rbm[HAL_RX_NUM_MSDU_DESC]; + /* physical address of the msdu */ + uint64_t paddr[HAL_RX_NUM_MSDU_DESC]; }; struct hal_buf_info { @@ -2038,8 +2040,12 @@ static inline void hal_rx_msdu_list_get(struct hal_soc *hal_soc, msdu_list->sw_cookie[i] = HAL_RX_BUF_COOKIE_GET( &msdu_details[i].buffer_addr_info_details); - msdu_list->rbm[i] = HAL_RX_BUF_RBM_GET( + msdu_list->rbm[i] = HAL_RX_BUF_RBM_GET( &msdu_details[i].buffer_addr_info_details); + msdu_list->paddr[i] = HAL_RX_BUFFER_ADDR_31_0_GET( + &msdu_details[i].buffer_addr_info_details) | + (uint64_t)HAL_RX_BUFFER_ADDR_39_32_GET( + &msdu_details[i].buffer_addr_info_details) << 32; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "[%s][%d] i=%d sw_cookie=%d", __func__, __LINE__, i, msdu_list->sw_cookie[i]);