From d5a07afa5d4a362834f0799f601fc2795a28c5d0 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Sat, 29 Jan 2022 07:44:43 -0800 Subject: [PATCH] qcacmn: WAR for invalid length buffers in wbm rx error path WAR for wrong length in first msdu in wbm rx error path while handling scatter gather buffers. Get the msdu length from the last buffer instead. Change-Id: I869391ef5ca7005dce972013679c2143be836ecb --- dp/wifi3.0/dp_main.c | 1 + dp/wifi3.0/dp_rx.c | 4 +++- dp/wifi3.0/dp_rx_err.c | 23 +++++++++++++++++++++++ dp/wifi3.0/dp_types.h | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index bc44eec386..684cc248e6 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -14637,6 +14637,7 @@ static void dp_soc_cfg_init(struct dp_soc *soc) soc->per_tid_basize_max_tid = 8; soc->wbm_release_desc_rx_sg_support = 1; soc->rxdma2sw_rings_not_supported = 1; + soc->wbm_sg_last_msdu_war = 1; soc->ast_offload_support = AST_OFFLOAD_ENABLE_STATUS; soc->mec_fw_offload = FW_MEC_FW_OFFLOAD_ENABLED; soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_V2_MAPS; diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index f4a30a0a28..3e9955cdc9 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1529,8 +1529,10 @@ qdf_nbuf_t dp_rx_sg_create(struct dp_soc *soc, qdf_nbuf_t nbuf) next = nbuf->next; nbuf->next = NULL; break; + } else if (qdf_nbuf_is_rx_chfrag_end(nbuf)) { + dp_err("Invalid packet length\n"); + qdf_assert_always(0); } - nbuf = nbuf->next; } while (!last_nbuf); diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 89b45051b2..7d68184e5a 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -2472,6 +2472,28 @@ static inline bool dp_handle_rxdma_decrypt_err(void) } #endif +/* + * dp_rx_wbm_sg_list_last_msdu_war() - war for HW issue + * + * This is a war for HW issue where length is only valid in last msdu + *@soc: DP SOC handle + */ +static inline void dp_rx_wbm_sg_list_last_msdu_war(struct dp_soc *soc) +{ + if (soc->wbm_sg_last_msdu_war) { + uint32_t len; + qdf_nbuf_t temp = soc->wbm_sg_param.wbm_sg_nbuf_tail; + + len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, + qdf_nbuf_data(temp)); + temp = soc->wbm_sg_param.wbm_sg_nbuf_head; + while (temp) { + QDF_NBUF_CB_RX_PKT_LEN(temp) = len; + temp = temp->next; + } + } +} + static inline bool dp_rx_is_sg_formation_required(struct hal_wbm_err_desc_info *info) { @@ -2645,6 +2667,7 @@ dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, nbuf_head, nbuf_tail, soc->wbm_sg_param.wbm_sg_nbuf_head, soc->wbm_sg_param.wbm_sg_nbuf_tail); + dp_rx_wbm_sg_list_last_msdu_war(soc); dp_rx_wbm_sg_list_reset(soc); process_sg_buf = false; } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 8dc483a70f..dcc6fc9b9a 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2309,6 +2309,7 @@ struct dp_soc { struct dp_mon_soc *monitor_soc; #endif uint8_t rxdma2sw_rings_not_supported:1, + wbm_sg_last_msdu_war:1, mec_fw_offload:1; /* Number of Rx refill rings */