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
此提交包含在:
@@ -4499,6 +4499,25 @@ void dp_set_max_page_size(struct qdf_mem_multi_page_t *pages,
|
||||
}
|
||||
#endif /* MAX_ALLOC_PAGE_SIZE */
|
||||
|
||||
/**
|
||||
* dp_get_next_index() - get the next entry to record an entry
|
||||
* in the history.
|
||||
* @curr_idx: Current index where the last entry is written.
|
||||
* @max_entries: Max number of entries in the history
|
||||
*
|
||||
* This function assumes that the max number os entries is a power of 2.
|
||||
*
|
||||
* Return: The index where the next entry is to be written.
|
||||
*/
|
||||
|
||||
static inline uint32_t dp_get_next_index(qdf_atomic_t *curr_idx,
|
||||
uint32_t max_entries)
|
||||
{
|
||||
uint32_t idx = qdf_atomic_inc_return(curr_idx);
|
||||
|
||||
return idx & (max_entries - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_history_get_next_index() - get the next entry to record an entry
|
||||
* in the history.
|
||||
@@ -4512,9 +4531,7 @@ void dp_set_max_page_size(struct qdf_mem_multi_page_t *pages,
|
||||
static inline uint32_t dp_history_get_next_index(qdf_atomic_t *curr_idx,
|
||||
uint32_t max_entries)
|
||||
{
|
||||
uint32_t idx = qdf_atomic_inc_return(curr_idx);
|
||||
|
||||
return idx & (max_entries - 1);
|
||||
return dp_get_next_index(curr_idx, max_entries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
新增問題並參考
封鎖使用者