From 8641a158f3ea0ccb4931b5fcc12e02115c5a824f Mon Sep 17 00:00:00 2001 From: Shiva Krishna Pittala Date: Wed, 27 Jul 2022 00:37:43 +0530 Subject: [PATCH] qcacmn: Hook the UMAC reset in the target attach path Call UMAC reset initialization API from soc_attach_target(). FW exposes a service bit for this feature, use that to conditionally enable this feature. Also, add default log levels for this feature. CRs-Fixed: 3253464 Change-Id: Ia7c9cf07a7ab7b000ebe452ab074a82173b70129 --- dp/inc/cdp_txrx_cmn.h | 19 +++++ dp/inc/cdp_txrx_ops.h | 1 + dp/inc/cdp_txrx_stats_struct.h | 2 + dp/wifi3.0/dp_main.c | 13 +++ dp/wifi3.0/dp_types.h | 2 + dp/wifi3.0/dp_umac_reset.c | 84 ++++++++++++++++--- dp/wifi3.0/dp_umac_reset.h | 21 ++++- qdf/linux/src/qdf_trace.c | 2 + .../init_deinit/src/init_event_handler.c | 6 ++ wmi/inc/wmi_unified_param.h | 1 + wmi/src/wmi_unified_tlv.c | 2 + 11 files changed, 138 insertions(+), 15 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 59f1b38832..a8f617f418 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -1704,6 +1704,25 @@ static inline void cdp_txrx_intr_detach(ol_txrx_soc_handle soc) soc->ops->cmn_drv_ops->txrx_intr_detach(soc); } +/** + * cdp_txrx_umac_reset_deinit(): De-initialize UMAC HW reset module + * @soc: soc handle + */ +static inline void cdp_txrx_umac_reset_deinit(ol_txrx_soc_handle soc) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return; + } + + if (!soc->ops->cmn_drv_ops || + !soc->ops->cmn_drv_ops->txrx_umac_reset_deinit) + return; + + soc->ops->cmn_drv_ops->txrx_umac_reset_deinit(soc); +} + /** * cdp_display_stats(): function to map to dump stats * @soc: soc handle diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index cbb77eee90..d0ed2a4ef7 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -676,6 +676,7 @@ struct cdp_cmn_ops { uint8_t vdev_id, bool mlo_peers_only); #endif + QDF_STATUS (*txrx_umac_reset_deinit)(ol_txrx_soc_handle soc); }; struct cdp_ctrl_ops { diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index a8e8792a8a..64a12d31fe 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -2824,6 +2824,7 @@ struct cdp_peer_hmwds_ast_add_status { * @DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT: For sending EAPOL's over control port * @DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT: For sending bulk AST delete * @DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT: To set the rssi dbm support bit + * @DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT: Whether target supports UMAC HW reset */ enum cdp_soc_param_t { DP_SOC_PARAM_MSDU_EXCEPTION_DESC, @@ -2832,6 +2833,7 @@ enum cdp_soc_param_t { DP_SOC_PARAM_EAPOL_OVER_CONTROL_PORT, DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT, DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT, + DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT, DP_SOC_PARAM_MAX, }; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 8e77a1bbc1..323703fa7a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -6539,6 +6539,13 @@ dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) return status; } + status = dp_soc_umac_reset_init(soc); + if (status != QDF_STATUS_SUCCESS && + status != QDF_STATUS_E_NOSUPPORT) { + dp_err("Failed to initialize UMAC reset"); + return status; + } + status = dp_rx_target_fst_config(soc); if (status != QDF_STATUS_SUCCESS && status != QDF_STATUS_E_NOSUPPORT) { @@ -12325,6 +12332,11 @@ static QDF_STATUS dp_soc_set_param(struct cdp_soc_t *soc_hdl, dp_info("Rssi dbm converstion support:%u", soc->features.rssi_dbm_conv_support); break; + case DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT: + soc->features.umac_hw_reset_support = value; + dp_info("UMAC HW reset support :%u", + soc->features.umac_hw_reset_support); + break; default: dp_info("not handled param %d ", param); break; @@ -12873,6 +12885,7 @@ static struct cdp_cmn_ops dp_ops_cmn = { #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) .txrx_recovery_vdev_flush_peers = dp_recovery_vdev_flush_peers, #endif + .txrx_umac_reset_deinit = dp_soc_umac_reset_deinit, }; static struct cdp_ctrl_ops dp_ops_ctrl = { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 8a520d0caa..24b4f608f3 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1909,11 +1909,13 @@ struct dp_arch_ops { * @dmac_cmn_src_rxbuf_ring_enabled: Flag to indicate DMAC mode common Rx * buffer source rings * @rssi_dbm_conv_support: Rssi dbm converstion support param. + * @umac_hw_reset_support: UMAC HW reset support */ struct dp_soc_features { uint8_t pn_in_reo_dest:1, dmac_cmn_src_rxbuf_ring_enabled:1; bool rssi_dbm_conv_support; + bool umac_hw_reset_support; }; enum sysfs_printing_mode { diff --git a/dp/wifi3.0/dp_umac_reset.c b/dp/wifi3.0/dp_umac_reset.c index 587078632f..b7cdb7072c 100644 --- a/dp/wifi3.0/dp_umac_reset.c +++ b/dp/wifi3.0/dp_umac_reset.c @@ -91,11 +91,16 @@ QDF_STATUS dp_soc_umac_reset_init(struct dp_soc *soc) return QDF_STATUS_E_NULL_VALUE; } + if (!soc->features.umac_hw_reset_support) { + dp_umac_reset_info("Target doesn't support the UMAC HW reset feature"); + return QDF_STATUS_E_NOSUPPORT; + } + umac_reset_ctx = &soc->umac_reset_ctx; qdf_mem_zero(umac_reset_ctx, sizeof(*umac_reset_ctx)); - umac_reset_ctx->supported = true; umac_reset_ctx->current_state = UMAC_RESET_STATE_WAIT_FOR_DO_PRE_RESET; + umac_reset_ctx->shmem_exp_magic_num = DP_UMAC_RESET_SHMEM_MAGIC_NUM; status = dp_get_umac_reset_intr_ctx(soc, &umac_reset_ctx->intr_offset); if (QDF_IS_STATUS_ERROR(status)) { @@ -120,11 +125,55 @@ QDF_STATUS dp_soc_umac_reset_init(struct dp_soc *soc) umac_reset_ctx->shmem_paddr_aligned = qdf_roundup( (uint64_t)umac_reset_ctx->shmem_paddr_unaligned, DP_UMAC_RESET_SHMEM_ALIGN); + umac_reset_ctx->shmem_size = alloc_size; + + /* Write the magic number to the shared memory */ + umac_reset_ctx->shmem_vaddr_aligned->magic_num = + DP_UMAC_RESET_SHMEM_MAGIC_NUM; + + /* Attach the interrupts */ + status = dp_umac_reset_interrupt_attach(soc); + if (QDF_IS_STATUS_ERROR(status)) { + dp_umac_reset_err("Interrupt attach failed"); + qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, + umac_reset_ctx->shmem_size, + umac_reset_ctx->shmem_vaddr_unaligned, + umac_reset_ctx->shmem_paddr_unaligned, + 0); + return status; + } /* Send the setup cmd to the target */ return dp_umac_reset_send_setup_cmd(soc); } +QDF_STATUS dp_soc_umac_reset_deinit(struct cdp_soc_t *txrx_soc) +{ + struct dp_soc *soc = (struct dp_soc *)txrx_soc; + struct dp_soc_umac_reset_ctx *umac_reset_ctx; + + if (!soc) { + dp_umac_reset_err("DP SOC is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!soc->features.umac_hw_reset_support) { + dp_umac_reset_info("Target doesn't support the UMAC HW reset feature"); + return QDF_STATUS_E_NOSUPPORT; + } + + dp_umac_reset_interrupt_detach(soc); + + umac_reset_ctx = &soc->umac_reset_ctx; + qdf_mem_free_consistent(soc->osdev, soc->osdev->dev, + umac_reset_ctx->shmem_size, + umac_reset_ctx->shmem_vaddr_unaligned, + umac_reset_ctx->shmem_paddr_unaligned, + 0); + + return QDF_STATUS_SUCCESS; +} + /** * dp_umac_reset_get_rx_event() - Extract the Rx event from the shared memory * @umac_reset_ctx: UMAC reset context @@ -325,14 +374,13 @@ QDF_STATUS dp_umac_reset_interrupt_attach(struct dp_soc *soc) return QDF_STATUS_E_NULL_VALUE; } - umac_reset_ctx = &soc->umac_reset_ctx; - - /* return if feature is not supported */ - if (!umac_reset_ctx->supported) { - dp_umac_reset_info("UMAC reset is not supported on this SOC"); + if (!soc->features.umac_hw_reset_support) { + dp_umac_reset_info("Target doesn't support the UMAC HW reset feature"); return QDF_STATUS_SUCCESS; } + umac_reset_ctx = &soc->umac_reset_ctx; + if (pld_get_enable_intx(soc->osdev->dev)) { dp_umac_reset_err("UMAC reset is not supported in legacy interrupt mode"); return QDF_STATUS_E_FAILURE; @@ -368,18 +416,13 @@ QDF_STATUS dp_umac_reset_interrupt_attach(struct dp_soc *soc) QDF_STATUS dp_umac_reset_interrupt_detach(struct dp_soc *soc) { - struct dp_soc_umac_reset_ctx *umac_reset_ctx; - if (!soc) { dp_umac_reset_err("DP SOC is null"); return QDF_STATUS_E_NULL_VALUE; } - umac_reset_ctx = &soc->umac_reset_ctx; - - /* return if feature is not supported */ - if (!umac_reset_ctx->supported) { - dp_umac_reset_info("UMAC reset is not supported on this SOC"); + if (!soc->features.umac_hw_reset_support) { + dp_umac_reset_info("Target doesn't support the UMAC HW reset feature"); return QDF_STATUS_SUCCESS; } @@ -398,6 +441,11 @@ QDF_STATUS dp_umac_reset_register_rx_action_callback( return QDF_STATUS_E_NULL_VALUE; } + if (!soc->features.umac_hw_reset_support) { + dp_umac_reset_info("Target doesn't support the UMAC HW reset feature"); + return QDF_STATUS_E_NOSUPPORT; + } + if (action >= UMAC_RESET_ACTION_MAX) { dp_umac_reset_err("invalid action: %d", action); return QDF_STATUS_E_INVAL; @@ -541,6 +589,16 @@ QDF_STATUS dp_umac_reset_notify_action_completion( { enum umac_reset_state next_state; + if (!soc) { + dp_umac_reset_err("DP SOC is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!soc->features.umac_hw_reset_support) { + dp_umac_reset_info("Target doesn't support the UMAC HW reset feature"); + return QDF_STATUS_E_NOSUPPORT; + } + switch (action) { case UMAC_RESET_ACTION_DO_PRE_RESET: next_state = UMAC_RESET_STATE_HOST_PRE_RESET_DONE; diff --git a/dp/wifi3.0/dp_umac_reset.h b/dp/wifi3.0/dp_umac_reset.h index 78edc6d087..bf27456b30 100644 --- a/dp/wifi3.0/dp_umac_reset.h +++ b/dp/wifi3.0/dp_umac_reset.h @@ -35,6 +35,7 @@ enum umac_reset_action { }; #ifdef DP_UMAC_HW_RESET_SUPPORT + #define dp_umac_reset_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_DP_UMAC_RESET, params) #define dp_umac_reset_err(params...) \ @@ -49,6 +50,8 @@ enum umac_reset_action { QDF_TRACE_DEBUG(QDF_MODULE_ID_DP_UMAC_RESET, params) #define DP_UMAC_RESET_SHMEM_ALIGN 8 +#define DP_UMAC_RESET_SHMEM_MAGIC_NUM (0xDEADBEEF) + /** * enum umac_reset_state - States required by the UMAC reset state machine * @UMAC_RESET_STATE_WAIT_FOR_DO_PRE_RESET: Waiting for the DO_PRE_RESET event @@ -126,9 +129,9 @@ struct umac_reset_rx_actions { * @shmem_vaddr_unaligned: Virtual address of the shared memory (unaligned) * @shmem_paddr_aligned: Physical address of the shared memory (aligned) * @shmem_vaddr_aligned: Virtual address of the shared memory (aligned) + * @shmem_size: Size of the shared memory * @intr_offset: Offset of the UMAC reset interrupt w.r.t DP base interrupt * @current_state: current state of the UMAC reset state machine - * @supported: Whether UMAC reset is supported on this soc * @shmem_exp_magic_num: Expected magic number in the shared memory * @rx_actions: callbacks for handling UMAC reset actions */ @@ -137,9 +140,9 @@ struct dp_soc_umac_reset_ctx { void *shmem_vaddr_unaligned; qdf_dma_addr_t shmem_paddr_aligned; htt_umac_hang_recovery_msg_shmem_t *shmem_vaddr_aligned; + size_t shmem_size; int intr_offset; enum umac_reset_state current_state; - bool supported; uint32_t shmem_exp_magic_num; struct umac_reset_rx_actions rx_actions; }; @@ -152,6 +155,14 @@ struct dp_soc_umac_reset_ctx { */ QDF_STATUS dp_soc_umac_reset_init(struct dp_soc *soc); +/** + * dp_soc_umac_reset_deinit() - De-initialize UMAC reset context + * @txrx_soc: DP soc object + * + * Return: QDF status of operation + */ +QDF_STATUS dp_soc_umac_reset_deinit(struct cdp_soc_t *txrx_soc); + /** * dp_umac_reset_interrupt_attach() - Register handlers for UMAC reset interrupt * @soc: DP soc object @@ -200,6 +211,12 @@ QDF_STATUS dp_soc_umac_reset_init(struct dp_soc *soc) return QDF_STATUS_SUCCESS; } +static inline +QDF_STATUS dp_soc_umac_reset_deinit(struct cdp_soc_t *txrx_soc) +{ + return QDF_STATUS_SUCCESS; +} + static inline QDF_STATUS dp_umac_reset_register_rx_action_callback( struct dp_soc *soc, diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c index c8bf7f2388..37e0393537 100644 --- a/qdf/linux/src/qdf_trace.c +++ b/qdf/linux/src/qdf_trace.c @@ -3597,6 +3597,7 @@ struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = { [QDF_MODULE_ID_T2LM] = {"T2LM"}, [QDF_MODULE_ID_DP_SAWF] = {"DP_SAWF"}, [QDF_MODULE_ID_SCS] = {"SCS"}, + [QDF_MODULE_ID_DP_UMAC_RESET] = {"UMAC_HW_RESET"}, [QDF_MODULE_ID_ANY] = {"ANY"}, }; qdf_export_symbol(g_qdf_category_name); @@ -4175,6 +4176,7 @@ static void set_default_trace_levels(struct category_info *cinfo) [QDF_MODULE_ID_T2LM] = QDF_TRACE_LEVEL_ERROR, [QDF_MODULE_ID_DP_SAWF] = QDF_TRACE_LEVEL_ERROR, [QDF_MODULE_ID_SCS] = QDF_TRACE_LEVEL_ERROR, + [QDF_MODULE_ID_DP_UMAC_RESET] = QDF_TRACE_LEVEL_ERROR, [QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO, }; diff --git a/target_if/init_deinit/src/init_event_handler.c b/target_if/init_deinit/src/init_event_handler.c index ddaef47253..1ec58229ce 100644 --- a/target_if/init_deinit/src/init_event_handler.c +++ b/target_if/init_deinit/src/init_event_handler.c @@ -390,6 +390,12 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle, cdp_soc_set_param(wlan_psoc_get_dp_handle(psoc), DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT, 1); + /* Send UMAC HW reset support to DP layer */ + if (wmi_service_enabled(wmi_handle, + wmi_service_umac_hang_recovery_support)) + cdp_soc_set_param(wlan_psoc_get_dp_handle(psoc), + DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT, 1); + if (wmi_service_enabled(wmi_handle, wmi_service_vdev_delete_all_peer)) wlan_psoc_nif_fw_ext2_cap_set(psoc, WLAN_VDEV_DELETE_ALL_PEER_SUPPORT); diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index a74a0860ee..fb179c89f4 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5732,6 +5732,7 @@ typedef enum { wmi_service_mgmt_rx_reo_supported, wmi_service_phy_dma_byte_swap_support, wmi_service_spectral_session_info_support, + wmi_service_umac_hang_recovery_support, wmi_service_mu_snif, #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE wmi_service_dynamic_update_vdev_macaddr_support, diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index e01cba94f4..2987103778 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -19926,6 +19926,8 @@ static void populate_tlv_service(uint32_t *wmi_service) WMI_SERVICE_UNAVAILABLE; wmi_service[wmi_service_spectral_session_info_support] = WMI_SERVICE_SPECTRAL_SESSION_INFO_SUPPORT; + wmi_service[wmi_service_umac_hang_recovery_support] = + WMI_SERVICE_UMAC_HANG_RECOVERY_SUPPORT; wmi_service[wmi_service_mu_snif] = WMI_SERVICE_MU_SNIF; #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE wmi_service[wmi_service_dynamic_update_vdev_macaddr_support] =