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:
@@ -297,19 +297,24 @@ dp_rx_msdus_drop(struct dp_soc *soc, hal_ring_desc_t ring_desc,
|
|||||||
uint8_t *rx_tlv_hdr;
|
uint8_t *rx_tlv_hdr;
|
||||||
uint32_t tid;
|
uint32_t tid;
|
||||||
struct rx_desc_pool *rx_desc_pool;
|
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);
|
hal_rx_reo_buf_paddr_get(ring_desc, &buf_info);
|
||||||
|
|
||||||
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &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 */
|
/* No UNMAP required -- this is "malloc_consistent" memory */
|
||||||
hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list,
|
hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list,
|
||||||
&mpdu_desc_info->msdu_count);
|
&mpdu_desc_info->msdu_count);
|
||||||
|
|
||||||
for (i = 0; (i < mpdu_desc_info->msdu_count) && quota--; i++) {
|
for (i = 0; (i < mpdu_desc_info->msdu_count); i++) {
|
||||||
struct dp_rx_desc *rx_desc =
|
rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc,
|
||||||
dp_rx_cookie_2_va_rxdma_buf(soc,
|
msdu_list.sw_cookie[i]);
|
||||||
msdu_list.sw_cookie[i]);
|
|
||||||
|
|
||||||
qdf_assert_always(rx_desc);
|
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);
|
&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;
|
return rx_bufs_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,28 +622,35 @@ process_next_msdu:
|
|||||||
tail_nbuf = NULL;
|
tail_nbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msdu_processed < mpdu_desc_info->msdu_count) {
|
/*
|
||||||
hal_rx_get_next_msdu_link_desc_buf_addr_info(
|
* If the msdu's are spread across multiple link-descriptors,
|
||||||
link_desc_va,
|
* we cannot depend solely on the msdu_count(e.g., if msdu is
|
||||||
&next_link_desc_addr_info);
|
* 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(
|
if (hal_rx_is_buf_addr_info_valid(
|
||||||
&next_link_desc_addr_info)) {
|
&next_link_desc_addr_info)) {
|
||||||
dp_rx_link_desc_return_by_addr(
|
/* Clear the next link desc info for the current link_desc */
|
||||||
soc,
|
hal_rx_clear_next_msdu_link_desc_buf_addr_info(link_desc_va);
|
||||||
buf_addr_info,
|
dp_rx_link_desc_return_by_addr(
|
||||||
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
|
soc,
|
||||||
|
buf_addr_info,
|
||||||
|
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
|
||||||
|
|
||||||
hal_rx_buffer_addr_info_get_paddr(
|
hal_rx_buffer_addr_info_get_paddr(
|
||||||
&next_link_desc_addr_info,
|
&next_link_desc_addr_info,
|
||||||
&buf_info);
|
&buf_info);
|
||||||
link_desc_va =
|
link_desc_va =
|
||||||
dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
dp_rx_cookie_2_link_desc_va(soc, &buf_info);
|
||||||
cur_link_desc_addr_info = next_link_desc_addr_info;
|
cur_link_desc_addr_info = next_link_desc_addr_info;
|
||||||
buf_addr_info = &cur_link_desc_addr_info;
|
buf_addr_info = &cur_link_desc_addr_info;
|
||||||
|
|
||||||
goto more_msdu_link_desc;
|
goto more_msdu_link_desc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dp_rx_link_desc_return_by_addr(soc, buf_addr_info,
|
dp_rx_link_desc_return_by_addr(soc, buf_addr_info,
|
||||||
|
@@ -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;
|
*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
|
* hal_rx_is_buf_addr_info_valid(): check is the buf_addr_info valid
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user