diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 32b7db3123..697a86859f 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -1381,6 +1381,46 @@ fail: return; } +#ifdef DP_RX_DESC_COOKIE_INVALIDATE +/** + * dp_rx_link_cookie_check() - Validate link desc cookie + * @ring_desc: ring descriptor + * + * Return: qdf status + */ +static inline QDF_STATUS +dp_rx_link_cookie_check(hal_ring_desc_t ring_desc) +{ + if (qdf_unlikely(HAL_RX_REO_BUF_LINK_COOKIE_INVALID_GET(ring_desc))) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_rx_link_cookie_invalidate() - Invalidate link desc cookie + * @ring_desc: ring descriptor + * + * Return: None + */ +static inline void +dp_rx_link_cookie_invalidate(hal_ring_desc_t ring_desc) +{ + HAL_RX_REO_BUF_LINK_COOKIE_INVALID_SET(ring_desc); +} +#else +static inline QDF_STATUS +dp_rx_link_cookie_check(hal_ring_desc_t ring_desc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void +dp_rx_link_cookie_invalidate(hal_ring_desc_t ring_desc) +{ +} +#endif + uint32_t dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl, uint32_t quota) @@ -1403,6 +1443,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, struct hal_rx_msdu_list msdu_list; /* MSDU's per MPDU */ uint16_t num_msdus; struct dp_rx_desc *rx_desc = NULL; + QDF_STATUS status; /* Debug -- Remove later */ qdf_assert(soc && hal_ring_hdl); @@ -1426,8 +1467,8 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, } while (qdf_likely(quota-- && (ring_desc = - hal_srng_dst_get_next(hal_soc, - hal_ring_hdl)))) { + hal_srng_dst_peek(hal_soc, + hal_ring_hdl)))) { DP_STATS_INC(soc, rx.err_ring_pkts, 1); @@ -1448,6 +1489,12 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, qdf_assert_always((cookie >> LINK_DESC_ID_SHIFT) & LINK_DESC_ID_START); + status = dp_rx_link_cookie_check(ring_desc); + if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) { + DP_STATS_INC(soc, rx.err.invalid_link_cookie, 1); + break; + } + /* * Check if the buffer is to be processed on this processor */ @@ -1475,7 +1522,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, /* Return link descriptor through WBM ring (SW2WBM)*/ dp_rx_link_desc_return(soc, ring_desc, HAL_BM_ACTION_RELEASE_MSDU_LIST); - continue; + goto next_entry; } rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, @@ -1498,7 +1545,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, &mpdu_desc_info, &mac_id, quota); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } count = dp_rx_frag_handle(soc, @@ -1507,7 +1554,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx_bufs_reaped[mac_id] += count; DP_STATS_INC(soc, rx.rx_frags, 1); - continue; + goto next_entry; } if (hal_rx_reo_is_pn_error(ring_desc)) { @@ -1526,7 +1573,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, quota); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } if (hal_rx_reo_is_2k_jump(ring_desc)) { @@ -1548,7 +1595,7 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, HAL_REO_ERR_REGULAR_FRAME_2K_JUMP); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } if (hal_rx_reo_is_oor_error(ring_desc)) { @@ -1569,8 +1616,11 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, HAL_REO_ERR_REGULAR_FRAME_OOR); rx_bufs_reaped[mac_id] += count; - continue; + goto next_entry; } +next_entry: + dp_rx_link_cookie_invalidate(ring_desc); + hal_srng_dst_get_next(hal_soc, hal_ring_hdl); } done: diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index 1c045d7397..e8a05f1939 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -6051,6 +6051,8 @@ void dp_txrx_path_stats(struct dp_soc *soc) soc->stats.rx.err.rejected); DP_PRINT_STATS("Rx raw frame dropped: %d", soc->stats.rx.err.raw_frm_drop); + DP_PRINT_STATS("Rx stale link desc cookie: %d", + pdev->soc->stats.rx.err.invalid_link_cookie); DP_PRINT_STATS("Reo Statistics"); DP_PRINT_STATS("near_full: %u ", soc->stats.rx.near_full); @@ -6598,6 +6600,9 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_PRINT_STATS("Rx err msdu rejected: %d", soc->stats.rx.err.rejected); + DP_PRINT_STATS("Rx stale link desc cookie: %d", + soc->stats.rx.err.invalid_link_cookie); + for (i = 0; i < HAL_RXDMA_ERR_MAX; i++) { index += qdf_snprint(&rxdma_error[index], DP_RXDMA_ERR_LENGTH - index, diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 3a7d435215..9c014d4a98 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -851,6 +851,8 @@ struct dp_soc_stats { uint32_t msdu_count_mismatch; /* RX raw frame dropped count */ uint32_t raw_frm_drop; + /* Stale link desc cookie count*/ + uint32_t invalid_link_cookie; } err; /* packet count per core - per ring */ diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h index f39a480dc4..476a23dde9 100644 --- a/hal/wifi3.0/hal_rx.h +++ b/hal/wifi3.0/hal_rx.h @@ -300,6 +300,28 @@ enum hal_rx_ret_buf_manager { BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_MASK, \ BUFFER_ADDR_INFO_1_RETURN_BUFFER_MANAGER_LSB)) +#define HAL_RX_LINK_COOKIE_INVALID_MASK 0x40000000 + +#define HAL_RX_BUF_LINK_COOKIE_INVALID_GET(buff_addr_info) \ + ((*(((unsigned int *)buff_addr_info) + \ + (BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) & \ + HAL_RX_LINK_COOKIE_INVALID_MASK) + +#define HAL_RX_BUF_LINK_COOKIE_INVALID_SET(buff_addr_info) \ + ((*(((unsigned int *)buff_addr_info) + \ + (BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) |= \ + HAL_RX_LINK_COOKIE_INVALID_MASK) + +#define HAL_RX_REO_BUF_LINK_COOKIE_INVALID_GET(reo_desc) \ + (HAL_RX_BUF_LINK_COOKIE_INVALID_GET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->buf_or_link_desc_addr_info))) + +#define HAL_RX_REO_BUF_LINK_COOKIE_INVALID_SET(reo_desc) \ + (HAL_RX_BUF_LINK_COOKIE_INVALID_SET(& \ + (((struct reo_destination_ring *) \ + reo_desc)->buf_or_link_desc_addr_info))) + /* TODO: Convert the following structure fields accesseses to offsets */ #define HAL_RX_REO_BUFFER_ADDR_39_32_GET(reo_desc) \