qcacmn: Do not unmap buffer if MSDU done is not set

Currently if the msdu_done bit is not set in the
rx_pkt_tlvs, the buffer is unmapped and freed.
There was an issue seen where hardware accessed a
buffer address, which probably was delivered to driver
without DMA of data to the buffer (thereby unmapped
and freed before hw attempted second access). This
results in unwanted recovery.

Based on the above hypothesis, add a workaround
to skip the unmap-and-free of any buffer for which
the msdu_done bit was not set in the rx_pkt_tlv.
Also mark the corresponding rx_desc as in_err_state.

The rx_desc corresponding to such aforementioned
msdu_done failure msdus are stored in a rolling
list, where the old entry is force unmapped & freed
when a new entry needs to be added. This force
unmap-and-free of the oldest buffer gives an uncertain
amount of delay between it being reaped from rx ring and
actual unmap-and-free.

Change-Id: Ibf8f3c886118d532af818466cb46218d88146271
CRs-Fixed: 3667674
This commit is contained in:
Rakesh Pillai
2023-11-10 03:01:48 -08:00
committed by Ravindra Konda
parent 3ed7625c2a
commit d149d2a2e8
5 changed files with 161 additions and 6 deletions

View File

@@ -3493,6 +3493,19 @@ static inline void dp_soc_msdu_done_fail_history_detach(struct dp_soc *soc)
}
#endif
#ifdef DP_RX_PEEK_MSDU_DONE_WAR
static void dp_soc_msdu_done_fail_desc_list_attach(struct dp_soc *soc)
{
qdf_atomic_init(&soc->msdu_done_fail_desc_list.index);
qdf_atomic_set(&soc->msdu_done_fail_desc_list.index,
DP_MSDU_DONE_FAIL_DESCS_MAX - 1);
}
#else
static void dp_soc_msdu_done_fail_desc_list_attach(struct dp_soc *soc)
{
}
#endif
#ifdef WLAN_SUPPORT_RX_FLOW_TAG
QDF_STATUS
dp_rx_fst_attach_wrapper(struct dp_soc *soc, struct dp_pdev *pdev)
@@ -13675,6 +13688,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
dp_soc_rx_history_attach(soc);
dp_soc_mon_status_ring_history_attach(soc);
dp_soc_tx_history_attach(soc);
dp_soc_msdu_done_fail_desc_list_attach(soc);
dp_soc_msdu_done_fail_history_attach(soc);
wlan_set_srng_cfg(&soc->wlan_srng_cfg);
soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc);