qcacmn: gracefully handle error packets on partner soc
Ideally in MLO, Rx buffers should be routed to error rings of the SOC which owns the RX buffer or link desc incase of any error or fragment But in case of HW issue if the packets are routed to partner soc. Handle gracefully instead of assert Change-Id: Ia56188808dfd034e960e1c1345de8f760e4b05f1 CRs-Fixed: 3327959
This commit is contained in:

committed by
Madan Koyyalamudi

parent
f0811fb133
commit
86f7649e19
@@ -2205,20 +2205,52 @@ static int dp_rx_err_exception(struct dp_soc *soc, hal_ring_desc_t ring_desc)
|
||||
#endif /* HANDLE_RX_REROUTE_ERR */
|
||||
|
||||
#ifdef WLAN_MLO_MULTI_CHIP
|
||||
static void dp_idle_link_bm_id_check(struct dp_soc *soc, uint8_t rbm)
|
||||
/*
|
||||
* dp_idle_link_bm_id_check() - war for HW issue
|
||||
*
|
||||
* This is a war for HW issue where link descriptor
|
||||
* of partner soc received due to packets wrongly
|
||||
* interpreted as fragments
|
||||
*
|
||||
* @soc: DP SOC handle
|
||||
* @rbm: idle link RBM value
|
||||
* @ring_desc: reo error link descriptor
|
||||
*
|
||||
* returns: true in case link desc is consumed
|
||||
* false in other cases
|
||||
*/
|
||||
static bool dp_idle_link_bm_id_check(struct dp_soc *soc, uint8_t rbm,
|
||||
void *ring_desc)
|
||||
{
|
||||
struct dp_soc *replenish_soc = NULL;
|
||||
|
||||
/* return ok incase of link desc of same soc */
|
||||
if (rbm == soc->idle_link_bm_id)
|
||||
return false;
|
||||
|
||||
if (soc->arch_ops.dp_soc_get_by_idle_bm_id)
|
||||
replenish_soc =
|
||||
soc->arch_ops.dp_soc_get_by_idle_bm_id(soc, rbm);
|
||||
|
||||
qdf_assert_always(replenish_soc);
|
||||
|
||||
/*
|
||||
* For WIN usecase we should only get fragment packets in
|
||||
* this ring as for MLO case fragmentation is not supported
|
||||
* we should not see links from other soc.
|
||||
*
|
||||
* Adding a assert for link descriptors from local soc
|
||||
* Drop all packets from partner soc and replenish the descriptors
|
||||
*/
|
||||
qdf_assert_always(rbm == soc->idle_link_bm_id);
|
||||
dp_handle_wbm_internal_error(replenish_soc, ring_desc,
|
||||
HAL_WBM_RELEASE_RING_2_DESC_TYPE);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static void dp_idle_link_bm_id_check(struct dp_soc *soc, uint8_t rbm)
|
||||
static bool dp_idle_link_bm_id_check(struct dp_soc *soc, uint8_t rbm,
|
||||
void *ring_desc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2323,7 +2355,10 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
qdf_assert_always((hbi.sw_cookie >> LINK_DESC_ID_SHIFT) &
|
||||
soc->link_desc_id_start);
|
||||
|
||||
dp_idle_link_bm_id_check(soc, hbi.rbm);
|
||||
if (dp_idle_link_bm_id_check(soc, hbi.rbm, ring_desc)) {
|
||||
DP_STATS_INC(soc, rx.err.invalid_link_cookie, 1);
|
||||
goto next_entry;
|
||||
}
|
||||
|
||||
status = dp_rx_link_cookie_check(ring_desc);
|
||||
if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) {
|
||||
@@ -2642,10 +2677,12 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
hal_ring_desc_t ring_desc;
|
||||
hal_soc_handle_t hal_soc;
|
||||
struct dp_rx_desc *rx_desc;
|
||||
union dp_rx_desc_list_elem_t *head[MAX_PDEV_CNT] = { NULL };
|
||||
union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL };
|
||||
union dp_rx_desc_list_elem_t
|
||||
*head[WLAN_MAX_MLO_CHIPS][MAX_PDEV_CNT] = { { NULL } };
|
||||
union dp_rx_desc_list_elem_t
|
||||
*tail[WLAN_MAX_MLO_CHIPS][MAX_PDEV_CNT] = { { NULL } };
|
||||
uint32_t rx_bufs_used = 0;
|
||||
uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 };
|
||||
uint32_t rx_bufs_reaped[WLAN_MAX_MLO_CHIPS][MAX_PDEV_CNT] = { { 0 } };
|
||||
uint8_t buf_type;
|
||||
uint8_t mac_id;
|
||||
struct dp_pdev *dp_pdev;
|
||||
@@ -2663,6 +2700,8 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
bool process_sg_buf = false;
|
||||
uint32_t wbm_err_src;
|
||||
QDF_STATUS status;
|
||||
struct dp_soc *replenish_soc;
|
||||
uint8_t chip_id;
|
||||
struct hal_rx_mpdu_desc_info mpdu_desc_info = { 0 };
|
||||
|
||||
/* Debug -- Remove later */
|
||||
@@ -2742,11 +2781,12 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
nbuf);
|
||||
rx_desc->in_err_state = 1;
|
||||
rx_desc->unmapped = 1;
|
||||
rx_bufs_reaped[rx_desc->pool_id]++;
|
||||
dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id],
|
||||
&tail[rx_desc->pool_id],
|
||||
rx_desc);
|
||||
rx_bufs_reaped[rx_desc->chip_id][rx_desc->pool_id]++;
|
||||
|
||||
dp_rx_add_to_free_desc_list(
|
||||
&head[rx_desc->chip_id][rx_desc->pool_id],
|
||||
&tail[rx_desc->chip_id][rx_desc->pool_id],
|
||||
rx_desc);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2804,7 +2844,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
(uint8_t *)&wbm_err_info,
|
||||
sizeof(wbm_err_info));
|
||||
|
||||
rx_bufs_reaped[rx_desc->pool_id]++;
|
||||
rx_bufs_reaped[rx_desc->chip_id][rx_desc->pool_id]++;
|
||||
|
||||
if (qdf_nbuf_is_rx_chfrag_cont(nbuf) || process_sg_buf) {
|
||||
DP_RX_LIST_APPEND(soc->wbm_sg_param.wbm_sg_nbuf_head,
|
||||
@@ -2828,9 +2868,9 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
DP_RX_LIST_APPEND(nbuf_head, nbuf_tail, nbuf);
|
||||
}
|
||||
|
||||
dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id],
|
||||
&tail[rx_desc->pool_id],
|
||||
rx_desc);
|
||||
dp_rx_add_to_free_desc_list
|
||||
(&head[rx_desc->chip_id][rx_desc->pool_id],
|
||||
&tail[rx_desc->chip_id][rx_desc->pool_id], rx_desc);
|
||||
|
||||
/*
|
||||
* if continuation bit is set then we have MSDU spread
|
||||
@@ -2843,15 +2883,30 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
done:
|
||||
dp_srng_access_end(int_ctx, soc, hal_ring_hdl);
|
||||
|
||||
for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) {
|
||||
if (rx_bufs_reaped[mac_id]) {
|
||||
dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_id];
|
||||
rx_desc_pool = &soc->rx_desc_buf[mac_id];
|
||||
for (chip_id = 0; chip_id < WLAN_MAX_MLO_CHIPS; chip_id++) {
|
||||
for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) {
|
||||
/*
|
||||
* continue with next mac_id if no pkts were reaped
|
||||
* from that pool
|
||||
*/
|
||||
if (!rx_bufs_reaped[chip_id][mac_id])
|
||||
continue;
|
||||
|
||||
dp_rx_buffers_replenish(soc, mac_id, dp_rxdma_srng,
|
||||
rx_desc_pool, rx_bufs_reaped[mac_id],
|
||||
&head[mac_id], &tail[mac_id], false);
|
||||
rx_bufs_used += rx_bufs_reaped[mac_id];
|
||||
replenish_soc =
|
||||
soc->arch_ops.dp_rx_replenish_soc_get(soc, chip_id);
|
||||
|
||||
dp_rxdma_srng =
|
||||
&replenish_soc->rx_refill_buf_ring[mac_id];
|
||||
|
||||
rx_desc_pool = &replenish_soc->rx_desc_buf[mac_id];
|
||||
|
||||
dp_rx_buffers_replenish(replenish_soc, mac_id,
|
||||
dp_rxdma_srng,
|
||||
rx_desc_pool,
|
||||
rx_bufs_reaped[chip_id][mac_id],
|
||||
&head[chip_id][mac_id],
|
||||
&tail[chip_id][mac_id], false);
|
||||
rx_bufs_used += rx_bufs_reaped[chip_id][mac_id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3531,7 +3586,6 @@ dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc,
|
||||
/* buffer_addr_info is the first element of ring_desc */
|
||||
hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)hal_desc,
|
||||
&buf_info);
|
||||
pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(buf_info.sw_cookie);
|
||||
|
||||
if (buf_type == HAL_WBM_RELEASE_RING_2_BUFFER_TYPE) {
|
||||
DP_STATS_INC(soc, tx.wbm_internal_error[WBM_INT_ERROR_REO_NULL_MSDU_BUFF], 1);
|
||||
@@ -3556,6 +3610,8 @@ dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc,
|
||||
rx_bufs_reaped[rx_desc->pool_id]++;
|
||||
}
|
||||
} else if (buf_type == HAL_WBM_RELEASE_RING_2_DESC_TYPE) {
|
||||
pool_id = DP_RX_DESC_COOKIE_POOL_ID_GET(buf_info.sw_cookie);
|
||||
|
||||
dp_wbm_int_err_mpdu_pop(soc, pool_id, hal_desc,
|
||||
&head, &tail, rx_bufs_reaped);
|
||||
}
|
||||
|
Reference in New Issue
Block a user