qcacld-3.0: Refactor 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 doesn't send the de-init
inidication to firmware and starts closing its modules because of this
fw & host are out of sync.

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

Change-Id: I52fddc1b8765105c44192085ba93bf00d14eb0bd
CRs-Fixed: 1073599
This commit is contained in:
Govind Singh
2016-09-27 22:07:43 +05:30
committed by qcabuildsw
父節點 9c58eba273
當前提交 b048e87f2c
共有 5 個文件被更改,包括 60 次插入41 次删除

查看文件

@@ -213,6 +213,8 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context);
*/
void cds_flush_cache_rx_queue(void);
QDF_STATUS cds_post_disable(v_CONTEXT_t cds_context);
QDF_STATUS cds_close(v_CONTEXT_t cds_context);
void cds_core_return_msg(void *pVContext, p_cds_msg_wrapper pMsgWrapper);

查看文件

@@ -321,8 +321,6 @@ 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;
/*---------------------------------------------------------------------------

查看文件

@@ -688,9 +688,6 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
wma_setneedshutdown(cds_context);
}
hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext);
hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
handle = cds_get_context(QDF_MODULE_ID_PE);
if (!handle) {
cds_err("Invalid PE context return!");
@@ -708,27 +705,51 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
}
gp_cds_context->is_cds_disabled = 1;
return qdf_status;
}
#ifdef HIF_USB
static inline void cds_suspend_target(tp_wma_handle wma_handle)
{
QDF_STATUS status;
/* Suspend the target and disable interrupt */
status = wma_suspend_target(wma_handle, 0);
if (status)
cds_err("Failed to suspend target, status = %d", status);
}
#else
static inline void cds_suspend_target(tp_wma_handle wma_handle)
{
QDF_STATUS status;
/* Suspend the target and disable interrupt */
status = wma_suspend_target(wma_handle, 1);
if (status)
cds_err("Failed to suspend target, status = %d", status);
}
#endif /* HIF_USB */
/**
* cds_close() - close cds module
* cds_post_disable() - post disable cds module
* @cds_context: CDS context
*
* Return: QDF status
*/
QDF_STATUS cds_close(v_CONTEXT_t cds_context)
QDF_STATUS cds_post_disable(v_CONTEXT_t cds_context)
{
QDF_STATUS qdf_status;
tp_wma_handle wma_handle;
struct hif_opaque_softc *hif_ctx;
wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
if (!wma_handle) {
cds_err("Failed to get wma_handle!");
return QDF_STATUS_E_INVAL;
}
hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
if (!hif_ctx) {
cds_err("Failed to get hif_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,
@@ -738,23 +759,27 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context)
* - 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);
}
cds_info("send denint sequence to firmware");
if (!cds_is_driver_recovering())
cds_suspend_target(wma_handle);
hif_disable_isr(hif_ctx);
hif_reset_soc(hif_ctx);
return QDF_STATUS_SUCCESS;
}
/**
* cds_close() - close cds module
* @cds_context: CDS context
*
* This API allows user to close modules registered
* with connectivity device services.
*
* Return: QDF status
*/
QDF_STATUS cds_close(v_CONTEXT_t cds_context)
{
QDF_STATUS qdf_status;
qdf_status = wma_wmi_work_close(cds_context);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -830,7 +855,6 @@ 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;
}

查看文件

@@ -7852,9 +7852,17 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx)
goto done;
}
qdf_status = cds_post_disable(hdd_ctx->pcds_context);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_err("Failed to process post CDS disable Modules! :%d",
qdf_status);
ret = -EINVAL;
QDF_ASSERT(0);
}
qdf_status = cds_close(hdd_ctx->pcds_context);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_warn("Failed to stop CDS:%d", qdf_status);
ret = -EINVAL;
QDF_ASSERT(0);
}
/* Clean up message queues of TX, RX and MC thread */

查看文件

@@ -3191,19 +3191,6 @@ QDF_STATUS wma_stop(void *cds_ctx, uint8_t reason)
WMA_LOGE("Failed to destroy the log completion timer");
}
/* There's no need suspend target which is already down during SSR. */
if (!cds_is_driver_recovering()) {
#ifdef HIF_USB
/* Suspend the target and enable interrupt */
if (wma_suspend_target(wma_handle, 0))
WMA_LOGE("Failed to suspend target");
#else
/* Suspend the target and disable interrupt */
if (wma_suspend_target(wma_handle, 1))
WMA_LOGE("Failed to suspend target");
#endif /* HIF_USB */
}
/* clean up ll-queue for all vdev */
for (i = 0; i < wma_handle->max_bssid; i++) {
if (wma_handle->interfaces[i].handle &&