Explorar el Código

qcacld-3.0: Send De-init sequence to firmware when the modules are not enabled

With the new statemachine  cds start/stop will not be invoked without an
interface up from upperlayer. As part of cds stop host sends de-initialization
sequence to firmware, If there is no interface up from the upper layer and
driver gets removed, host driver dosent send the de-init
inidication to firmware and starts closing its modules because of this
fw & host are out of sync.

To migitate the issue send the de-init sequence during if the modules are
opened but not enabled.

Change-Id: Ice85f995a870e69e52b4fcf2fac13761bf1a63a1
CRs-Fixed: 1060893
Arun Khandavalli hace 8 años
padre
commit
55f890bb97
Se han modificado 2 ficheros con 39 adiciones y 0 borrados
  1. 2 0
      core/cds/inc/cds_sched.h
  2. 37 0
      core/cds/src/cds_api.c

+ 2 - 0
core/cds/inc/cds_sched.h

@@ -321,6 +321,8 @@ typedef struct _cds_context_type {
 	bool do_hw_mode_change;
 	bool enable_fatal_event;
 	struct cds_config_info *cds_cfg;
+	/* WAR: Is cds disabled */
+	bool is_cds_disabled;
 } cds_context_type, *p_cds_contextType;
 
 /*---------------------------------------------------------------------------

+ 37 - 0
core/cds/src/cds_api.c

@@ -693,6 +693,8 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
 		cds_err("Failed to stop MAC");
 		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
 	}
+
+	gp_cds_context->is_cds_disabled = 1;
 	return qdf_status;
 }
 
@@ -705,6 +707,40 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
 QDF_STATUS cds_close(v_CONTEXT_t cds_context)
 {
 	QDF_STATUS qdf_status;
+	tp_wma_handle wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		cds_err("Failed to get wma_handle!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/*
+	 * With new state machine changes cds_close can be invoked without
+	 * cds_disable. So, send the following clean up prerequisites to fw,
+	 * So Fw and host are in sync for cleanup indication:
+	 * - Send PDEV_SUSPEND indication to firmware
+	 * - Disable HIF Interrupts.
+	 * - Clean up CE tasklets.
+	 */
+
+	if (!gp_cds_context->is_cds_disabled) {
+		cds_info("send denint sequence to firmware");
+		if (!cds_is_driver_recovering()) {
+#ifdef HIF_USB
+			/* Suspend the target and enable interrupt */
+			if (wma_suspend_target(wma_handle, 0))
+				cds_err("Failed to suspend target");
+#else
+			/* Suspend the target and disable interrupt */
+			if (wma_suspend_target(wma_handle, 1))
+				cds_err("Failed to suspend target");
+#endif /* HIF_USB */
+		}
+		hif_disable_isr(
+			((cds_context_type *) cds_context)->pHIFContext);
+		hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
+	}
 
 	qdf_status = wma_wmi_work_close(cds_context);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -778,6 +814,7 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context)
 	cds_deinit_ini_config();
 	qdf_timer_module_deinit();
 
+	gp_cds_context->is_cds_disabled = 0;
 	return QDF_STATUS_SUCCESS;
 }