qcacmn: return msdu link descriptors to wbm release ring

add support to return msdu link descriptors received on rxDMA error ring
to wbm release ring without freeing the nbufs (msdus).

Change-Id: Ic12c3f0531a639b61d3d77cee6266ce595e4d1c9
This commit is contained in:
Tallapragada Kalyan 2017-09-26 21:04:24 +05:30 • committed by snandini
commit 0017291c13
3 changed files with 80 additions and 28 deletions

View file

@ -643,11 +643,12 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
* @soc: core DP main context
* @buf_addr_info: opaque pointer to the REO error ring descriptor
* @buf_addr_info: void pointer to the buffer_addr_info
* @bm_action: put to idle_list or release to msdu_list
* Return: QDF_STATUS
*/
QDF_STATUS
dp_rx_link_desc_buf_return(struct dp_soc *soc, struct dp_srng *dp_rxdma_srng,
void *buf_addr_info);
void *buf_addr_info, uint8_t bm_action);
uint32_t
dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id,

View file

@ -677,7 +677,7 @@ fail:
* Return: QDF_STATUS
*/
static QDF_STATUS
dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc)
dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc, uint8_t bm_action)
{
void *buf_addr_info = HAL_RX_REO_BUF_ADDR_INFO_GET(ring_desc);
struct dp_srng *wbm_desc_rel_ring = &soc->wbm_desc_rel_ring;
@ -709,7 +709,7 @@ dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc)
if (qdf_likely(src_srng_desc)) {
/* Return link descriptor through WBM ring (SW2WBM)*/
hal_rx_msdu_link_desc_set(hal_soc,
src_srng_desc, buf_addr_info);
src_srng_desc, buf_addr_info, bm_action);
status = QDF_STATUS_SUCCESS;
} else {
struct hal_srng *srng = (struct hal_srng *)wbm_rel_srng;
@ -841,7 +841,8 @@ dp_rx_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
continue;
}
/* Return link descriptor through WBM ring (SW2WBM)*/
dp_rx_link_desc_return(soc, ring_desc);
dp_rx_link_desc_return(soc, ring_desc,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
}
done:
@ -1109,6 +1110,8 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
uint32_t i;
uint8_t push_reason;
uint8_t rxdma_error_code = 0;
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
struct dp_pdev *pdev = soc->pdev_list[mac_id];
msdu = 0;
@ -1134,29 +1137,42 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
HAL_RX_NUM_MSDU_DESC:msdu_cnt;
hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus);
msdu_cnt -= num_msdus;
if (msdu_list.sw_cookie[0] != HAL_RX_COOKIE_SPECIAL) {
for (i = 0; i < num_msdus; i++) {
struct dp_rx_desc *rx_desc =
dp_rx_cookie_2_va_rxdma_buf(soc,
msdu_list.sw_cookie[i]);
qdf_assert(rx_desc);
msdu = rx_desc->nbuf;
/* if the msdus belongs to NSS offloaded radio &&
* the rbm is not SW3_BM then return the msdu_link
* descriptor without freeing the msdus (nbufs). let
* these buffers be given to NSS completion ring for
* NSS to free them.
* else iterate through the msdu link desc list and
* free each msdu in the list.
*/
if (msdu_list.rbm[0] != HAL_RX_BUF_RBM_SW3_BM &&
wlan_cfg_get_dp_pdev_nss_enabled(
pdev->wlan_cfg_ctx))
bm_action = HAL_BM_ACTION_RELEASE_MSDU_LIST;
else {
for (i = 0; i < num_msdus; i++) {
struct dp_rx_desc *rx_desc =
dp_rx_cookie_2_va_rxdma_buf(soc,
msdu_list.sw_cookie[i]);
qdf_assert(rx_desc);
msdu = rx_desc->nbuf;
qdf_nbuf_unmap_single(soc->osdev, msdu,
QDF_DMA_FROM_DEVICE);
qdf_nbuf_unmap_single(soc->osdev, msdu,
QDF_DMA_FROM_DEVICE);
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
"[%s][%d] msdu_nbuf=%pK \n",
__func__, __LINE__, msdu);
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
"[%s][%d] msdu_nbuf=%pK \n",
__func__, __LINE__, msdu);
qdf_nbuf_free(msdu);
rx_bufs_used++;
dp_rx_add_to_free_desc_list(head,
tail, rx_desc);
qdf_nbuf_free(msdu);
rx_bufs_used++;
dp_rx_add_to_free_desc_list(head,
tail, rx_desc);
}
}
} else {
rxdma_error_code = HAL_RXDMA_ERR_WAR;
@ -1165,7 +1181,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info,
&p_buf_addr_info);
dp_rx_link_desc_return(soc, p_last_buf_addr_info);
dp_rx_link_desc_return(soc, p_last_buf_addr_info, bm_action);
p_last_buf_addr_info = p_buf_addr_info;
} while (buf_info.paddr && msdu_cnt);

View file

@ -302,6 +302,25 @@ enum hal_rx_ret_buf_manager {
* shift by the corresponding _LSB. This is because, they are
* finally taken and "OR'ed" into a single word again.
*/
#define HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_SET(msdu_info_ptr, val) \
((*(((uint32_t *)msdu_info_ptr) + \
(RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_OFFSET >> 2))) |= \
(val << RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_LSB) & \
RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_MASK)
#define HAL_RX_LAST_MSDU_IN_MPDU_FLAG_SET(msdu_info_ptr, val) \
((*(((uint32_t *)msdu_info_ptr) + \
(RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_OFFSET >> 2))) |= \
(val << RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_LSB) & \
RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_MASK)
#define HAL_RX_MSDU_CONTINUATION_FLAG_SET(msdu_info_ptr, val) \
((*(((uint32_t *)msdu_info_ptr) + \
(RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_OFFSET >> 2))) |= \
(val << RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_LSB) & \
RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_MASK)
#define HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_GET(msdu_info_ptr) \
((*_OFFSET_TO_WORD_PTR(msdu_info_ptr, \
RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_OFFSET)) & \
@ -1746,6 +1765,7 @@ hal_rx_mpdu_end_mic_err_get(uint8_t *buf)
struct hal_rx_msdu_list {
struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC];
uint8_t rbm[HAL_RX_NUM_MSDU_DESC];
};
struct hal_buf_info {
@ -1789,9 +1809,20 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
* sometimes due to HW issue. Check msdu buffer address also */
if (HAL_RX_BUFFER_ADDR_31_0_GET(
&msdu_details[i].buffer_addr_info_details) == 0) {
/* set the last msdu bit in the prev msdu_desc_info */
msdu_desc_info =
HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i - 1]);
HAL_RX_LAST_MSDU_IN_MPDU_FLAG_SET(msdu_desc_info, 1);
break;
}
msdu_desc_info = HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i]);
/* set first MSDU bit or the last MSDU bit */
if (!i)
HAL_RX_FIRST_MSDU_IN_MPDU_FLAG_SET(msdu_desc_info, 1);
else if (i == (HAL_RX_NUM_MSDU_DESC - 1))
HAL_RX_LAST_MSDU_IN_MPDU_FLAG_SET(msdu_desc_info, 1);
msdu_list->msdu_info[i].msdu_flags =
HAL_RX_MSDU_FLAGS_GET(msdu_desc_info);
msdu_list->msdu_info[i].msdu_len =
@ -1799,7 +1830,8 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
msdu_list->sw_cookie[i] =
HAL_RX_BUF_COOKIE_GET(
&msdu_details[i].buffer_addr_info_details);
msdu_list->rbm[i] = HAL_RX_BUF_RBM_GET(
&msdu_details[i].buffer_addr_info_details);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"[%s][%d] i=%d sw_cookie=%d\n",
__func__, __LINE__, i, msdu_list->sw_cookie[i]);
@ -1942,6 +1974,7 @@ enum hal_rxdma_error_code {
* HW BM action settings in WBM release ring
*/
#define HAL_BM_ACTION_PUT_IN_IDLE_LIST 0
#define HAL_BM_ACTION_RELEASE_MSDU_LIST 1
/**
* enum hal_rx_wbm_error_source: Indicates which module initiated the
@ -2030,12 +2063,14 @@ static inline bool hal_rx_reo_is_2k_jump(void *rx_desc)
* @ soc : HAL version of the SOC pointer
* @ src_srng_desc : void pointer to the WBM Release Ring descriptor
* @ buf_addr_info : void pointer to the buffer_addr_info
* @ bm_action : put in IDLE list or release to MSDU_LIST
*
* Return: void
*/
/* look at implementation at dp_hw_link_desc_pool_setup()*/
static inline void hal_rx_msdu_link_desc_set(struct hal_soc *soc,
void *src_srng_desc, void *buf_addr_info)
void *src_srng_desc, void *buf_addr_info,
uint8_t bm_action)
{
struct wbm_release_ring *wbm_rel_srng =
(struct wbm_release_ring *)src_srng_desc;
@ -2046,7 +2081,7 @@ static inline void hal_rx_msdu_link_desc_set(struct hal_soc *soc,
HAL_DESC_SET_FIELD(src_srng_desc, WBM_RELEASE_RING_2,
RELEASE_SOURCE_MODULE, HAL_RX_WBM_ERR_SRC_SW);
HAL_DESC_SET_FIELD(src_srng_desc, WBM_RELEASE_RING_2, BM_ACTION,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
bm_action);
HAL_DESC_SET_FIELD(src_srng_desc, WBM_RELEASE_RING_2,
BUFFER_OR_DESC_TYPE, HAL_RX_WBM_BUF_TYPE_MSDU_LINK_DESC);
}