diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index c01ba70164..6d25b29bb6 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -776,9 +776,9 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, } static -void dp_rx_wbm_err_handle_bar(struct dp_soc *soc, - struct dp_peer *peer, - qdf_nbuf_t nbuf) +void dp_rx_err_handle_bar(struct dp_soc *soc, + struct dp_peer *peer, + qdf_nbuf_t nbuf) { uint8_t *rx_tlv_hdr; unsigned char type, subtype; @@ -817,6 +817,76 @@ void dp_rx_wbm_err_handle_bar(struct dp_soc *soc, start_seq_num); } +static void +dp_rx_bar_frame_handle(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc, + struct hal_rx_mpdu_desc_info *mpdu_desc_info, + uint8_t error) +{ + qdf_nbuf_t nbuf; + struct dp_pdev *pdev; + struct dp_peer *peer; + struct rx_desc_pool *rx_desc_pool; + uint16_t peer_id; + uint8_t *rx_tlv_hdr; + uint32_t tid; + + nbuf = rx_desc->nbuf; + rx_desc_pool = &soc->rx_desc_buf[rx_desc->pool_id]; + dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, + rx_desc_pool->buf_size, + false); + qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf, + QDF_DMA_FROM_DEVICE, + rx_desc_pool->buf_size); + rx_desc->unmapped = 1; + rx_tlv_hdr = qdf_nbuf_data(nbuf); + peer_id = + hal_rx_mpdu_start_sw_peer_id_get(soc->hal_soc, + rx_tlv_hdr); + peer = dp_peer_get_ref_by_id(soc, peer_id, + DP_MOD_ID_RX_ERR); + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, + rx_tlv_hdr); + pdev = dp_get_pdev_for_lmac_id(soc, rx_desc->pool_id); + + if (!peer) + goto next; + + dp_info("BAR frame: peer = "QDF_MAC_ADDR_FMT + " peer_id = %d" + " tid = %u" + " SSN = %d" + " error status = %d", + QDF_MAC_ADDR_REF(peer->mac_addr.raw), + peer->peer_id, + tid, + mpdu_desc_info->mpdu_seq, + error); + + switch (error) { + case HAL_REO_ERR_BAR_FRAME_2K_JUMP: + /* fallthrough */ + case HAL_REO_ERR_BAR_FRAME_OOR: + dp_rx_err_handle_bar(soc, peer, nbuf); + DP_STATS_INC(soc, + rx.err.reo_error[error], 1); + break; + default: + DP_STATS_INC(soc, rx.bar_frame, 1); + } + + dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR); +next: + dp_rx_link_desc_return(soc, ring_desc, + HAL_BM_ACTION_PUT_IN_IDLE_LIST); + dp_rx_add_to_free_desc_list(&pdev->free_list_head, + &pdev->free_list_tail, + rx_desc); + qdf_nbuf_free(nbuf); +} + /** * dp_2k_jump_handle() - Function to handle 2k jump exception * on WBM ring @@ -1614,9 +1684,14 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, error = HAL_RX_ERROR_STATUS_GET(ring_desc); - qdf_assert(error == HAL_REO_ERROR_DETECTED); - buf_type = HAL_RX_REO_BUF_TYPE_GET(ring_desc); + + /* Get the MPDU DESC info */ + hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info); + + if (mpdu_desc_info.msdu_count == 0) + goto next_entry; + /* * For REO error ring, expect only MSDU LINK DESC */ @@ -1673,8 +1748,20 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, mac_id = rx_desc->pool_id; - /* Get the MPDU DESC info */ - hal_rx_mpdu_desc_info_get(ring_desc, &mpdu_desc_info); + if (mpdu_desc_info.bar_frame) { + qdf_assert_always(mpdu_desc_info.msdu_count == 1); + + dp_rx_bar_frame_handle(soc, + ring_desc, + rx_desc, + &mpdu_desc_info, + error); + + rx_bufs_reaped[mac_id] += 1; + goto next_entry; + } + + dp_info("Got pkt with REO ERROR: %d", error); if (mpdu_desc_info.mpdu_flags & HAL_MPDU_F_FRAGMENT) { /* @@ -1725,6 +1812,11 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, goto next_entry; } + /* + * Expect REO errors to be handled after this point + */ + qdf_assert_always(error == HAL_REO_ERROR_DETECTED); + if (hal_rx_reo_is_pn_error(ring_desc)) { /* TOD0 */ DP_STATS_INC(soc, @@ -1786,6 +1878,8 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, rx_bufs_reaped[mac_id] += count; goto next_entry; } + /* Assert if unexpected error type */ + qdf_assert_always(0); next_entry: dp_rx_link_cookie_invalidate(ring_desc); hal_srng_dst_get_next(hal_soc, hal_ring_hdl); @@ -2151,9 +2245,9 @@ done: case HAL_REO_ERR_BAR_FRAME_2K_JUMP: case HAL_REO_ERR_BAR_FRAME_OOR: if (peer) - dp_rx_wbm_err_handle_bar(soc, - peer, - nbuf); + dp_rx_err_handle_bar(soc, + peer, + nbuf); qdf_nbuf_free(nbuf); break; diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index dde4b06241..a140655a1a 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -6055,6 +6055,8 @@ void dp_txrx_path_stats(struct dp_soc *soc) DP_PRINT_STATS("hal ring access full fail: %u msdus", pdev->soc->stats.rx.err.hal_ring_access_full_fail); + DP_PRINT_STATS("Rx BAR frames:%d", soc->stats.rx.bar_frame); + for (error_code = 0; error_code < HAL_REO_ERR_MAX; error_code++) { if (!pdev->soc->stats.rx.err.reo_error[error_code]) @@ -6636,6 +6638,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc) DP_PRINT_STATS("REO Error(0-14):%s", reo_error); DP_PRINT_STATS("REO CMD SEND FAIL: %d", soc->stats.rx.err.reo_cmd_send_fail); + + DP_PRINT_STATS("Rx BAR frames:%d", soc->stats.rx.bar_frame); } #ifdef FEATURE_TSO_STATS diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index a6e2edd6d2..bbb5ab91f9 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -889,6 +889,8 @@ struct dp_soc_stats { uint32_t near_full; /* Break ring reaping as not all scattered msdu received */ uint32_t msdu_scatter_wait_break; + /* Number of bar frames received */ + uint32_t bar_frame; struct { /* Invalid RBM error count */ diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 9b9e815940..dc220cd77a 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -1101,6 +1101,15 @@ extern void *hal_srng_setup(void *hal_soc, int ring_type, int ring_num, (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ERROR_ ## \ DESTINATION_RING_ ## _OFFSET ## _SHFT)) +/* + * Macro to access HWIO_REO_R0_ERROR_DESTINATION_RING_CTRL_IX_1 + * to map destination to rings + */ +#define HAL_REO_ERR_REMAP_IX1(_VALUE, _OFFSET) \ + ((_VALUE) << \ + (HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ERROR_ ## \ + DESTINATION_RING_ ## _OFFSET ## _SHFT)) + /* * Macro to access HWIO_REO_R0_DESTINATION_RING_CTRL_IX_0 * to map destination to rings diff --git a/hal/wifi3.0/hal_rx.h b/hal/wifi3.0/hal_rx.h index 70448db8bd..3392c2a7f0 100644 --- a/hal/wifi3.0/hal_rx.h +++ b/hal/wifi3.0/hal_rx.h @@ -186,12 +186,14 @@ enum hal_rx_msdu_desc_flags { * [2] AMPDU flag * [3] raw_ampdu * @peer_meta_data: Upper bits containing peer id, vdev id + * @bar_frame: indicates if received frame is a bar frame */ struct hal_rx_mpdu_desc_info { uint16_t msdu_count; uint16_t mpdu_seq; /* 12 bits for length */ uint32_t mpdu_flags; uint32_t peer_meta_data; /* sw progamed meta-data:MAC Id & peer Id */ + uint16_t bar_frame; }; /** @@ -427,6 +429,11 @@ enum hal_rx_ret_buf_manager { HAL_RX_MPDU_AMPDU_FLAG_GET(mpdu_info_ptr) | \ HAL_RX_MPDU_RAW_MPDU_GET(mpdu_info_ptr)) +#define HAL_RX_MPDU_BAR_FRAME_GET(mpdu_info_ptr) \ + ((mpdu_info_ptr[RX_MPDU_DESC_INFO_0_BAR_FRAME_OFFSET >> 2] & \ + RX_MPDU_DESC_INFO_0_BAR_FRAME_MASK) >> \ + RX_MPDU_DESC_INFO_0_BAR_FRAME_LSB) + #define HAL_RX_MSDU_PKT_LENGTH_GET(msdu_info_ptr) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(msdu_info_ptr, \ @@ -558,6 +565,7 @@ static inline void hal_rx_mpdu_desc_info_get(void *desc_addr, mpdu_desc_info->mpdu_flags = HAL_RX_MPDU_FLAGS_GET(mpdu_info); mpdu_desc_info->peer_meta_data = HAL_RX_MPDU_DESC_PEER_META_DATA_GET(mpdu_info); + mpdu_desc_info->bar_frame = HAL_RX_MPDU_BAR_FRAME_GET(mpdu_info); } /* diff --git a/hal/wifi3.0/qca6390/hal_6390.c b/hal/wifi3.0/qca6390/hal_6390.c index 212a88285d..c1696e8ca9 100644 --- a/hal/wifi3.0/qca6390/hal_6390.c +++ b/hal/wifi3.0/qca6390/hal_6390.c @@ -1027,9 +1027,9 @@ hal_reo_set_err_dst_remap_6390(void *hal_soc) HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 3) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 4) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 5) | - HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 6) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 6) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 7) | - HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 8) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 8) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 9); HAL_REG_WRITE(hal_soc, diff --git a/hal/wifi3.0/qca6390/hal_6390_rx.h b/hal/wifi3.0/qca6390/hal_6390_rx.h index 745f9a7eb9..095b9f8de0 100644 --- a/hal/wifi3.0/qca6390/hal_6390_rx.h +++ b/hal/wifi3.0/qca6390/hal_6390_rx.h @@ -294,6 +294,17 @@ HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ SEQ_WCSS_UMAC_REO_REG_OFFSET), \ (reg_val)); \ + reg_val = \ + HAL_REG_READ((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET)); \ + reg_val &= \ + (~HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_BMSK |\ + (REO_REMAP_TCL << HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_SHFT)); \ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ } while (0) #define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \ diff --git a/hal/wifi3.0/qca6490/hal_6490.c b/hal/wifi3.0/qca6490/hal_6490.c index cc9cebfc7a..b8f9766dde 100644 --- a/hal/wifi3.0/qca6490/hal_6490.c +++ b/hal/wifi3.0/qca6490/hal_6490.c @@ -1471,9 +1471,18 @@ hal_reo_set_err_dst_remap_6490(void *hal_soc) HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 3) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 4) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 5) | - HAL_REO_ERR_REMAP_IX0(REO_REMAP_RELEASE, 6) | + HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 6) | HAL_REO_ERR_REMAP_IX0(REO_REMAP_TCL, 7); + uint32_t dst_remap_ix1 = + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 14) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 13) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 12) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 11) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 10) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_RELEASE, 9) | + HAL_REO_ERR_REMAP_IX1(REO_REMAP_TCL, 8); + HAL_REG_WRITE(hal_soc, HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET), @@ -1484,6 +1493,17 @@ hal_reo_set_err_dst_remap_6490(void *hal_soc) hal_soc, HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_0_ADDR( SEQ_WCSS_UMAC_REO_REG_OFFSET))); + + HAL_REG_WRITE(hal_soc, + HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + dst_remap_ix1); + + hal_info("HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1 0x%x", + HAL_REG_READ( + hal_soc, + HWIO_REO_R0_ERROR_DESTINATION_MAPPING_IX_1_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET))); } /** diff --git a/hal/wifi3.0/qca6490/hal_6490_rx.h b/hal/wifi3.0/qca6490/hal_6490_rx.h index 1d26d1be17..8859e95eb0 100644 --- a/hal/wifi3.0/qca6490/hal_6490_rx.h +++ b/hal/wifi3.0/qca6490/hal_6490_rx.h @@ -307,6 +307,17 @@ HWIO_REO_R0_MISC_CTL_ADDR( \ SEQ_WCSS_UMAC_REO_REG_OFFSET), \ (reg_val)); \ + reg_val = \ + HAL_REG_READ((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET)); \ + reg_val &= \ + (~HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_BMSK |\ + (REO_REMAP_TCL << HWIO_REO_R0_GENERAL_ENABLE_BAR_DEST_RING_SHFT)); \ + HAL_REG_WRITE((soc), \ + HWIO_REO_R0_GENERAL_ENABLE_ADDR( \ + SEQ_WCSS_UMAC_REO_REG_OFFSET), \ + (reg_val)); \ } while (0) #define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \