From 634d53f81b431bdbb0f0544f890e5cc6020905a3 Mon Sep 17 00:00:00 2001 From: Kai Chen Date: Sat, 15 Jul 2017 18:49:02 -0700 Subject: [PATCH] qcacmn: Fix the ppdu id and buffer reading issue Read the ppdu id from MPDU start TLV instead of ATTENTION TLV. The MPDU could extend to multiple SKB buffer. The ATTENTION TLV will be in the TLV of last SKB buffer. MPDU start will be in the first SKB buffer in MPDU. Read ppdu id from MPDU start TLV guarentee the correct reading The msdu count in MPDU from REO entrance ring is for msdu count for decap frame or MPDU count for not decap frame. msdu length in msdu desc info is for msdu length for decap frame or MPDU length for not decap frame. The MPDU could extend to multiple SKB. The continous bit in msdu desc info indicate if the MPDU/MSDU extend to next SKB. code is modified accordingly. Change-Id: If9aeb278f84a57d64651e1f877b5185f6db63cd2 --- dp/wifi3.0/dp_rx_err.c | 3 +- dp/wifi3.0/dp_rx_mon_dest.c | 71 +++++++++++++++++++++++++++++++------ dp/wifi3.0/hal_rx.h | 7 ++-- hal/wifi3.0/hal_api_mon.h | 25 +++---------- 4 files changed, 69 insertions(+), 37 deletions(-) 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);