qcacmn: fix rx path dma-inv-range, unmap-single issues
In case of duplicated rx descriptors from hardware, it will hit issues in __dma_inv_range(), __qdf_nbuf_unmap_single. Detect the duplicates, skip processing them, drop the mpdu. CRs-Fixed: 2413816 Change-Id: I7efd4b0c1bda5578578927bb22fe9d487758897d
This commit is contained in:
@@ -273,6 +273,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
bool is_frag, is_first_msdu;
|
bool is_frag, is_first_msdu;
|
||||||
bool drop_mpdu = false;
|
bool drop_mpdu = false;
|
||||||
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
|
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
|
||||||
|
uint64_t nbuf_paddr = 0;
|
||||||
|
|
||||||
msdu = 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;
|
uint32_t l2_hdr_offset;
|
||||||
struct dp_rx_desc *rx_desc = NULL;
|
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,
|
rx_desc = dp_rx_get_mon_desc(soc,
|
||||||
msdu_list.sw_cookie[i]);
|
msdu_list.sw_cookie[i]);
|
||||||
|
|
||||||
qdf_assert_always(rx_desc);
|
qdf_assert_always(rx_desc);
|
||||||
msdu = rx_desc->nbuf;
|
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) {
|
if (rx_desc->unmapped == 0) {
|
||||||
qdf_nbuf_unmap_single(soc->osdev, msdu,
|
qdf_nbuf_unmap_single(soc->osdev, msdu,
|
||||||
QDF_DMA_FROM_DEVICE);
|
QDF_DMA_FROM_DEVICE);
|
||||||
@@ -341,6 +350,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (drop_mpdu) {
|
if (drop_mpdu) {
|
||||||
|
dp_pdev->mon_last_linkdesc_paddr =
|
||||||
|
buf_info.paddr;
|
||||||
qdf_nbuf_free(msdu);
|
qdf_nbuf_free(msdu);
|
||||||
msdu = NULL;
|
msdu = NULL;
|
||||||
goto next_msdu;
|
goto next_msdu;
|
||||||
|
@@ -1941,6 +1941,8 @@ struct hal_rx_msdu_list {
|
|||||||
struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
|
struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
|
||||||
uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC];
|
uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC];
|
||||||
uint8_t rbm[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 {
|
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] =
|
msdu_list->sw_cookie[i] =
|
||||||
HAL_RX_BUF_COOKIE_GET(
|
HAL_RX_BUF_COOKIE_GET(
|
||||||
&msdu_details[i].buffer_addr_info_details);
|
&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_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,
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||||
"[%s][%d] i=%d sw_cookie=%d",
|
"[%s][%d] i=%d sw_cookie=%d",
|
||||||
__func__, __LINE__, i, msdu_list->sw_cookie[i]);
|
__func__, __LINE__, i, msdu_list->sw_cookie[i]);
|
||||||
|
Reference in New Issue
Block a user