diff --git a/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c b/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c index dbc47c409f..244b1964f2 100644 --- a/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_rx_mon_status_1.0.c @@ -1033,6 +1033,7 @@ QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, union dp_rx_desc_list_elem_t *next; void *rxdma_srng; struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(dp_soc, mac_id); + QDF_STATUS status = QDF_STATUS_SUCCESS; if (!dp_pdev) { dp_rx_mon_status_debug("%pK: pdev is null for mac_id = %d", @@ -1094,6 +1095,17 @@ QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, if (qdf_unlikely(!rx_netbuf)) { dp_rx_mon_status_err("%pK: qdf_nbuf allocate or map fail, count %d", dp_soc, count); + /* + * If buffer allocation fails on current HP, then + * decrement HP so it will be set to previous index + * where proper buffer is attached. + */ + if (!count) + status = QDF_STATUS_E_NOMEM; + else + hal_srng_src_dec_hp(dp_soc->hal_soc, + rxdma_srng); + break; } @@ -1148,7 +1160,7 @@ QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, mac_id, rx_desc_pool); } - return QDF_STATUS_SUCCESS; + return status; } #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index f444d993a4..5b5f157e6a 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -2178,6 +2178,34 @@ void *hal_srng_src_peek_n_get_next(hal_soc_handle_t hal_soc_hdl, return NULL; } +/** + * hal_srng_src_dec_hp - Decrement source srng HP to previous index + * @hal_soc_hdl: Opaque HAL SOC handle + * @hal_ring_hdl: Source ring pointer + * + * Return: None + */ +static inline +void hal_srng_src_dec_hp(hal_soc_handle_t hal_soc_hdl, + hal_ring_handle_t hal_ring_hdl) +{ + struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl; + uint32_t hp = srng->u.src_ring.hp; + + /* This HP adjustment is mostly done in error cases. + * Only local HP is being decremented not the value + * communicated to consumer or H.W. + */ + if (hp == srng->u.src_ring.cached_tp) + return; + else if (hp == 0) + hp = srng->ring_size - srng->entry_size; + else + hp = (hp - srng->entry_size) % srng->ring_size; + + srng->u.src_ring.hp = hp; +} + /** * hal_srng_src_peek_n_get_next_next() - Get next to next, i.e HP + 2 entry from * a ring without moving head pointer.