qcacmn: skip processing duplicate descriptor in dp_rx_err_mpdu_pop
If there's a HW duplicate rx descriptor from hardware, it'll cause a NULL pointer issue in __dma_inv_range in dp_rxdma_err_process. In this case, skip procssing it as a workaround. CRs-Fixed: 2398327 Change-Id: I5639e5fc9a3a06e6762448ec7cb2ea58d9ae8160
This commit is contained in:
@@ -7039,6 +7039,9 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
|
||||
DP_PRINT_STATS("RX REL DUP DESC: %d",
|
||||
soc->stats.rx.err.hal_wbm_rel_dup);
|
||||
|
||||
DP_PRINT_STATS("RXDMA ERR DUP DESC: %d",
|
||||
soc->stats.rx.err.hal_rxdma_err_dup);
|
||||
|
||||
for (i = 0; i < HAL_RXDMA_ERR_MAX; i++) {
|
||||
index += qdf_snprint(&rxdma_error[index],
|
||||
DP_RXDMA_ERR_LENGTH - index,
|
||||
|
@@ -1553,6 +1553,26 @@ done:
|
||||
return rx_bufs_used; /* Assume no scale factor for now */
|
||||
}
|
||||
|
||||
/**
|
||||
* dup_desc_dbg() - dump and assert if duplicate rx desc found
|
||||
*
|
||||
* @soc: core DP main context
|
||||
* @rxdma_dst_ring_desc: void pointer to monitor link descriptor buf addr info
|
||||
* @rx_desc: void pointer to rx descriptor
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void dup_desc_dbg(struct dp_soc *soc,
|
||||
void *rxdma_dst_ring_desc,
|
||||
void *rx_desc)
|
||||
{
|
||||
DP_STATS_INC(soc, rx.err.hal_rxdma_err_dup, 1);
|
||||
dp_rx_dump_info_and_assert(soc,
|
||||
soc->rx_rel_ring.hal_srng,
|
||||
rxdma_dst_ring_desc,
|
||||
rx_desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_err_mpdu_pop() - extract the MSDU's from link descs
|
||||
*
|
||||
@@ -1585,6 +1605,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
||||
uint8_t rxdma_error_code = 0;
|
||||
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
|
||||
struct dp_pdev *pdev = dp_get_pdev_for_mac_id(soc, mac_id);
|
||||
void *ring_desc;
|
||||
|
||||
msdu = 0;
|
||||
|
||||
@@ -1629,6 +1650,25 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
|
||||
msdu_list.sw_cookie[i]);
|
||||
qdf_assert_always(rx_desc);
|
||||
msdu = rx_desc->nbuf;
|
||||
/*
|
||||
* this is a unlikely scenario
|
||||
* where the host is reaping
|
||||
* a descriptor which
|
||||
* it already reaped just a while ago
|
||||
* but is yet to replenish
|
||||
* it back to HW.
|
||||
* In this case host will dump
|
||||
* the last 128 descriptors
|
||||
* including the software descriptor
|
||||
* rx_desc and assert.
|
||||
*/
|
||||
ring_desc = rxdma_dst_ring_desc;
|
||||
if (qdf_unlikely(!rx_desc->in_use)) {
|
||||
dup_desc_dbg(soc,
|
||||
ring_desc,
|
||||
rx_desc);
|
||||
continue;
|
||||
}
|
||||
|
||||
qdf_nbuf_unmap_single(soc->osdev, msdu,
|
||||
QDF_DMA_FROM_DEVICE);
|
||||
|
@@ -711,6 +711,8 @@ struct dp_soc_stats {
|
||||
uint32_t hal_reo_dest_dup;
|
||||
/* HAL WBM RELEASE Duplicate count */
|
||||
uint32_t hal_wbm_rel_dup;
|
||||
/* HAL RXDMA error Duplicate count */
|
||||
uint32_t hal_rxdma_err_dup;
|
||||
} err;
|
||||
|
||||
/* packet count per core - per ring */
|
||||
|
@@ -1438,7 +1438,7 @@ static inline void hal_srng_dump_ring(struct hal_soc *hal, void *hal_ring)
|
||||
|
||||
desc = &srng->ring_base_vaddr[tp - srng->entry_size];
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_FATAL,
|
||||
QDF_TRACE_LEVEL_DEBUG,
|
||||
desc, (srng->entry_size << 2));
|
||||
|
||||
tp -= srng->entry_size;
|
||||
|
Reference in New Issue
Block a user