Ver Fonte

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
Shiva Krishna Pittala há 2 anos atrás
pai
commit
8641a158f3

+ 19 - 0
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

+ 1 - 0
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 {

+ 2 - 0
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,
 };
 

+ 13 - 0
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 = {

+ 2 - 0
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 {

+ 71 - 13
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;

+ 19 - 2
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,

+ 2 - 0
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,
 	};
 

+ 6 - 0
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);

+ 1 - 0
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,

+ 2 - 0
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] =