From 80cded8b4a4b737220dbcf925879b84f978da6f0 Mon Sep 17 00:00:00 2001 From: Karunakar Dasineni Date: Mon, 10 Jul 2017 10:49:55 -0700 Subject: [PATCH] qcacmn: WAR for incorrect MSDU count in MPDU desc Rx MSDU count received in mpdu descriptor may be incorrect sometimes due to HW issue. We should check msdu buffer address in each Rx msdu buffer entry in RX msdu link descriptor. Change-Id: I86af4797cfb79fad33977cf53d62a8d368dc3543 --- dp/wifi3.0/dp_rx_defrag.c | 2 +- dp/wifi3.0/dp_rx_err.c | 8 ++++---- dp/wifi3.0/dp_rx_mon_dest.c | 7 ++++--- dp/wifi3.0/hal_rx.h | 15 +++++++++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 75e9863ae255..83a6c1a9efa7 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -1335,7 +1335,7 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, /* Get msdu_list for the given MPDU */ hal_rx_msdu_list_get(link_desc_va, &msdu_list, - mpdu_desc_info->msdu_count); + &mpdu_desc_info->msdu_count); /* Process all MSDUs in the current MPDU */ for (idx = 0; (idx < mpdu_desc_info->msdu_count) && quota--; idx++) { diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 00805ebae4d9..79c0cafce464 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -81,9 +81,9 @@ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, /* No UNMAP required -- this is "malloc_consistent" memory */ hal_rx_msdu_list_get(link_desc_va, &msdu_list, - mpdu_desc_info->msdu_count); + &mpdu_desc_info->msdu_count); - for (i = 0; (i < HAL_RX_NUM_MSDU_DESC) && quota--; i++) { + for (i = 0; (i < mpdu_desc_info->msdu_count) && quota--; i++) { struct dp_rx_desc *rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, msdu_list.sw_cookie[i]); @@ -835,7 +835,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_t msdu; qdf_nbuf_t last; struct hal_rx_msdu_list msdu_list; - uint8_t num_msdus; + uint16_t num_msdus; struct hal_buf_info buf_info; void *p_buf_addr_info; void *p_last_buf_addr_info; @@ -860,7 +860,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, num_msdus = (msdu_cnt > HAL_RX_NUM_MSDU_DESC)? HAL_RX_NUM_MSDU_DESC:msdu_cnt; - hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, num_msdus); + hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus); msdu_cnt -= num_msdus; diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index b7a4bc40a616..7d337dfb0cab 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -112,7 +112,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_t msdu; qdf_nbuf_t last; struct hal_rx_msdu_list msdu_list; - uint8_t num_msdus; + uint16_t num_msdus; uint32_t rx_buf_size, rx_pkt_offset; struct hal_buf_info buf_info; void *p_buf_addr_info; @@ -136,9 +136,10 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, qdf_assert(rx_msdu_link_desc); - num_msdus = msdu_cnt; + num_msdus = (msdu_cnt > HAL_RX_NUM_MSDU_DESC) ? + HAL_RX_NUM_MSDU_DESC:msdu_cnt; - hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, num_msdus); + hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus); msdu_cnt -= num_msdus; diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index c36ca52a6c3a..af8d7d721cca 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -1647,15 +1647,15 @@ struct hal_buf_info { * Return: void */ static inline void hal_rx_msdu_list_get(void *msdu_link_desc, - struct hal_rx_msdu_list *msdu_list, uint8_t num_msdus) + struct hal_rx_msdu_list *msdu_list, uint16_t *num_msdus) { struct rx_msdu_details *msdu_details; struct rx_msdu_desc_info *msdu_desc_info; struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)msdu_link_desc; int i; - if (num_msdus > HAL_RX_NUM_MSDU_DESC) - num_msdus = HAL_RX_NUM_MSDU_DESC; + if (*num_msdus > HAL_RX_NUM_MSDU_DESC) + *num_msdus = HAL_RX_NUM_MSDU_DESC; msdu_details = HAL_RX_LINK_DESC_MSDU0_PTR(msdu_link); @@ -1663,7 +1663,14 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc, "[%s][%d] msdu_link=%p msdu_details=%p\n", __func__, __LINE__, msdu_link, msdu_details); - for (i = 0; i < num_msdus; i++) { + for (i = 0; i < *num_msdus; i++) { + /* num_msdus received in mpdu descriptor may be incorrect + * sometimes due to HW issue. Check msdu buffer address also */ + if (HAL_RX_BUFFER_ADDR_31_0_GET( + &msdu_details[i].buffer_addr_info_details) == 0) { + *num_msdus = i; + break; + } msdu_desc_info = HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i]); msdu_list->msdu_info[i].msdu_flags = HAL_RX_MSDU_FLAGS_GET(msdu_desc_info);