diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index b691bc95ec..ebfc4f440c 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -963,7 +963,6 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, uint32_t rx_bufs_used = 0; uint32_t msdu_cnt; uint32_t i; - bool mpdu_err; uint8_t push_reason; uint8_t rxdma_error_code = 0; @@ -972,7 +971,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, last = NULL; hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, - &p_last_buf_addr_info, &msdu_cnt, &mpdu_err); + &p_last_buf_addr_info, &msdu_cnt); push_reason = hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc); diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 7d337dfb0c..da478a2b03 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -84,6 +84,27 @@ done: return status; } +/** + * dp_mon_adjust_frag_len() - MPDU and MSDU may spread across + * multiple nbufs. This function + * is to return data length in + * fragmented buffer + * + * @total_len: pointer to remaining data length. + * @frag_len: poiter to data length in this fragment. +*/ +static inline void dp_mon_adjust_frag_len(uint32_t *total_len, +uint32_t *frag_len) +{ + if (*total_len >= (RX_BUFFER_SIZE - RX_PKT_TLVS_LEN)) { + *frag_len = RX_BUFFER_SIZE - RX_PKT_TLVS_LEN; + *total_len -= *frag_len; + } else { + *frag_len = *total_len; + *total_len = 0; + } +} + /** * dp_rx_mon_mpdu_pop() - Return a MPDU link descriptor to HW * (WBM), following error handling @@ -121,14 +142,23 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, uint32_t msdu_ppdu_id, msdu_cnt; uint8_t *data; uint32_t i; - bool mpdu_fcs_err; + bool mpdu_err = false; + uint32_t total_frag_len, frag_len; + bool is_frag, is_first_msdu; msdu = 0; last = NULL; hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info, - &p_last_buf_addr_info, &msdu_cnt, &mpdu_fcs_err); + &p_last_buf_addr_info, &msdu_cnt); + + if(HAL_RX_WBM_RXDMA_PSH_RSN_ERROR == + hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc)) + mpdu_err = true; + + is_frag = false; + is_first_msdu = true; do { rx_msdu_link_desc = @@ -136,13 +166,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, qdf_assert(rx_msdu_link_desc); - num_msdus = (msdu_cnt > HAL_RX_NUM_MSDU_DESC) ? - HAL_RX_NUM_MSDU_DESC:msdu_cnt; - hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus); - msdu_cnt -= num_msdus; - for (i = 0; i < num_msdus; i++) { uint32_t l2_hdr_offset; struct dp_rx_desc *rx_desc = @@ -163,8 +188,12 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, __func__, __LINE__, msdu, data); rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); - msdu_ppdu_id = + + if(is_first_msdu) { + msdu_ppdu_id = HAL_RX_MON_HW_DESC_GET_PPDUID_GET(rx_desc_tlv); + is_first_msdu = false; + } QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, @@ -179,7 +208,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, __func__, __LINE__, *ppdu_id, msdu_ppdu_id); - if (*ppdu_id != msdu_ppdu_id) { + if ((*ppdu_id != msdu_ppdu_id) && !mpdu_err) { *ppdu_id = msdu_ppdu_id; return rx_bufs_used; } @@ -188,6 +217,28 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, hal_rx_mon_hw_desc_get_mpdu_status(rx_desc_tlv, &(dp_pdev->ppdu_info.rx_status)); + + if(msdu_list.msdu_info[i].msdu_flags & + HAL_MSDU_F_MSDU_CONTINUATION) { + if(!is_frag) { + total_frag_len = + msdu_list.msdu_info[i].msdu_len; + is_frag = true; + } + dp_mon_adjust_frag_len( + &total_frag_len, &frag_len); + } else { + if(is_frag) { + dp_mon_adjust_frag_len( + &total_frag_len, &frag_len); + } else { + frag_len = + msdu_list.msdu_info[i].msdu_len; + } + is_frag = false; + msdu_cnt--; + } + rx_pkt_offset = HAL_RX_MON_HW_RX_DESC_SIZE(); /* * HW structures call this L3 header padding @@ -199,7 +250,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, hal_rx_msdu_end_l3_hdr_padding_get(data); rx_buf_size = rx_pkt_offset + l2_hdr_offset - + msdu_list.msdu_info[i].msdu_len; + + frag_len; qdf_nbuf_set_pktlen(msdu, rx_buf_size); diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index 5e6d31a969..51bc4bc29c 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -1683,21 +1683,17 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc, struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)msdu_link_desc; int i; - if (*num_msdus > HAL_RX_NUM_MSDU_DESC) - *num_msdus = HAL_RX_NUM_MSDU_DESC; - msdu_details = HAL_RX_LINK_DESC_MSDU0_PTR(msdu_link); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "[%s][%d] msdu_link=%p msdu_details=%p\n", __func__, __LINE__, msdu_link, msdu_details); - for (i = 0; i < *num_msdus; i++) { + for (i = 0; i < HAL_RX_NUM_MSDU_DESC; i++) { /* num_msdus received in mpdu descriptor may be incorrect * 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) { - *num_msdus = i; break; } msdu_desc_info = HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i]); @@ -1713,6 +1709,7 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc, "[%s][%d] i=%d sw_cookie=%d\n", __func__, __LINE__, i, msdu_list->sw_cookie[i]); } + *num_msdus = i; } /** diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 8c47ab5a46..50ec3dcf67 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -158,12 +158,13 @@ HAL_RX_DESC_GET_80211_HDR(void *hw_desc_addr) { static inline uint32_t HAL_RX_MON_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) { - struct rx_attention *rx_attn; + struct rx_mpdu_info *rx_mpdu_info; struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; - rx_attn = &rx_desc->attn_tlv.rx_attn; + rx_mpdu_info = + &rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details; - return HAL_RX_GET(rx_attn, RX_ATTENTION_0, PHY_PPDU_ID); + return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID); } /* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */ @@ -205,15 +206,13 @@ uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr) * the current descriptor * @ buf_info: structure to return the buffer information * @ msdu_cnt: pointer to msdu count in MPDU - * @ mpdu_fcs_err: pointer to valuable of mpdu fcs error * Return: void */ static inline void hal_rx_reo_ent_buf_paddr_get(void *rx_desc, struct hal_buf_info *buf_info, void **pp_buf_addr_info, - uint32_t *msdu_cnt, - bool *mpdu_fcs_err + uint32_t *msdu_cnt ) { struct reo_entrance_ring *reo_ent_ring = @@ -221,24 +220,10 @@ void hal_rx_reo_ent_buf_paddr_get(void *rx_desc, struct buffer_addr_info *buf_addr_info; struct rx_mpdu_desc_info *rx_mpdu_desc_info_details; uint32_t loop_cnt; - uint32_t rxdma_push_reason; - uint32_t rxdma_error_code; rx_mpdu_desc_info_details = &reo_ent_ring->reo_level_mpdu_frame_info.rx_mpdu_desc_info_details; - rxdma_push_reason = HAL_RX_GET(reo_ent_ring, REO_ENTRANCE_RING_6, - RXDMA_PUSH_REASON); - - *mpdu_fcs_err = false; - - if (rxdma_push_reason == HAL_RX_WBM_RXDMA_PSH_RSN_ERROR) { - rxdma_error_code = HAL_RX_GET(reo_ent_ring, - REO_ENTRANCE_RING_6, RXDMA_ERROR_CODE); - if (rxdma_error_code == HAL_RXDMA_ERR_FCS) - *mpdu_fcs_err = true; - } - *msdu_cnt = HAL_RX_GET(rx_mpdu_desc_info_details, RX_MPDU_DESC_INFO_0, MSDU_COUNT);