qcacmn: Use next link_desc instead of msdu_count

MSDU count is not reliable in all cases.Hence it is better
to check whether next_link_desc is valid or not and then
free the MSDUs in the next descriptor and subsequently
release both the current and next link descriptor back to HW.

Change-Id: Ie5ea3be547f9aed6673293221f6b47661cd92cce
This commit is contained in:
Debasis Das
2020-08-07 20:11:29 +05:30
committed by snandini
parent dcb1efdcce
commit 59d63401a5
2 changed files with 82 additions and 24 deletions

View File

@@ -297,18 +297,23 @@ dp_rx_msdus_drop(struct dp_soc *soc, hal_ring_desc_t ring_desc,
uint8_t *rx_tlv_hdr;
uint32_t tid;
struct rx_desc_pool *rx_desc_pool;
struct dp_rx_desc *rx_desc;
/* First field in REO Dst ring Desc is buffer_addr_info */
void *buf_addr_info = ring_desc;
struct buffer_addr_info cur_link_desc_addr_info = { 0 };
struct buffer_addr_info next_link_desc_addr_info = { 0 };
hal_rx_reo_buf_paddr_get(ring_desc, &buf_info);
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info);
more_msdu_link_desc:
/* No UNMAP required -- this is "malloc_consistent" memory */
hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list,
&mpdu_desc_info->msdu_count);
for (i = 0; (i < mpdu_desc_info->msdu_count) && quota--; i++) {
struct dp_rx_desc *rx_desc =
dp_rx_cookie_2_va_rxdma_buf(soc,
for (i = 0; (i < mpdu_desc_info->msdu_count); i++) {
rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc,
msdu_list.sw_cookie[i]);
qdf_assert_always(rx_desc);
@@ -358,9 +363,38 @@ dp_rx_msdus_drop(struct dp_soc *soc, hal_ring_desc_t ring_desc,
&pdev->free_list_tail, rx_desc);
}
/* Return link descriptor through WBM ring (SW2WBM)*/
dp_rx_link_desc_return(soc, ring_desc, HAL_BM_ACTION_PUT_IN_IDLE_LIST);
/*
* If the msdu's are spread across multiple link-descriptors,
* we cannot depend solely on the msdu_count(e.g., if msdu is
* spread across multiple buffers).Hence, it is
* necessary to check the next link_descriptor and release
* all the msdu's that are part of it.
*/
hal_rx_get_next_msdu_link_desc_buf_addr_info(
link_desc_va,
&next_link_desc_addr_info);
if (hal_rx_is_buf_addr_info_valid(
&next_link_desc_addr_info)) {
/* Clear the next link desc info for the current link_desc */
hal_rx_clear_next_msdu_link_desc_buf_addr_info(link_desc_va);
dp_rx_link_desc_return_by_addr(soc, buf_addr_info,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
hal_rx_buffer_addr_info_get_paddr(
&next_link_desc_addr_info,
&buf_info);
cur_link_desc_addr_info = next_link_desc_addr_info;
buf_addr_info = &cur_link_desc_addr_info;
link_desc_va =
dp_rx_cookie_2_link_desc_va(soc, &buf_info);
goto more_msdu_link_desc;
}
quota--;
dp_rx_link_desc_return_by_addr(soc, buf_addr_info,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
return rx_bufs_used;
}
@@ -588,13 +622,21 @@ process_next_msdu:
tail_nbuf = NULL;
}
if (msdu_processed < mpdu_desc_info->msdu_count) {
/*
* If the msdu's are spread across multiple link-descriptors,
* we cannot depend solely on the msdu_count(e.g., if msdu is
* spread across multiple buffers).Hence, it is
* necessary to check the next link_descriptor and release
* all the msdu's that are part of it.
*/
hal_rx_get_next_msdu_link_desc_buf_addr_info(
link_desc_va,
&next_link_desc_addr_info);
if (hal_rx_is_buf_addr_info_valid(
&next_link_desc_addr_info)) {
/* Clear the next link desc info for the current link_desc */
hal_rx_clear_next_msdu_link_desc_buf_addr_info(link_desc_va);
dp_rx_link_desc_return_by_addr(
soc,
buf_addr_info,
@@ -610,7 +652,6 @@ process_next_msdu:
goto more_msdu_link_desc;
}
}
dp_rx_link_desc_return_by_addr(soc, buf_addr_info,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);

View File

@@ -3846,6 +3846,23 @@ void hal_rx_get_next_msdu_link_desc_buf_addr_info(
*next_addr_info = msdu_link->next_msdu_link_desc_addr_info;
}
/**
* hal_rx_clear_next_msdu_link_desc_buf_addr_info(): clear next msdu link desc
* buffer addr info
* @link_desc_va: pointer to current msdu link Desc
*
* return: None
*/
static inline
void hal_rx_clear_next_msdu_link_desc_buf_addr_info(void *link_desc_va)
{
struct rx_msdu_link *msdu_link = link_desc_va;
if (msdu_link)
qdf_mem_zero(&msdu_link->next_msdu_link_desc_addr_info,
sizeof(msdu_link->next_msdu_link_desc_addr_info));
}
/**
* hal_rx_is_buf_addr_info_valid(): check is the buf_addr_info valid
*