diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index d0e760fb3443..30906318d4e1 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -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, diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 610cdd4a9c54..10a9c132a979 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -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); diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index 4efebd835a6e..8c1ebe83c5f2 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -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); }