From f6479c5709903b5959c6d19aefa3f640a81e9010 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Tue, 19 Jan 2016 14:12:00 +0530 Subject: [PATCH] qcacld-3.0: Move sta state to not connected after try disconnect qcacld-2.0 to qcacld-3.0 propagation If a connect is received with previous connect already in progress, sta connect state is moved from connecting to disconnecting and disconnect is initiated to stop the previous connect. If previous is present in sme/roam pending queue the disconnect will abort the previous connect by removing the cmd from pending queue. In this case the connect state is not moved back to not connected from disconecting. Thus the current connect command fails and all new connect command will fail as the connect state will always be in disconnecting state. To avoid this, move the connect state to not connected, once try disconnect is issued internally. Change-Id: Ia563f85df84cb9dbb3d3a82bc97127d39e7b1421 CRs-Fixed: 961559 --- core/hdd/src/wlan_hdd_cfg80211.c | 64 +++++++++++++++++++------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index efed484d0e90..4f1c1be971c1 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -8739,6 +8739,7 @@ static int wlan_hdd_try_disconnect(hdd_adapter_t *pAdapter) unsigned long rc; hdd_station_ctx_t *pHddStaCtx; eMib_dot11DesiredBssType connectedBssType; + int status, result = 0; pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); @@ -8752,36 +8753,48 @@ static int wlan_hdd_try_disconnect(hdd_adapter_t *pAdapter) eConnectionState_Disconnecting); /* Issue disconnect to CSR */ INIT_COMPLETION(pAdapter->disconnect_comp_var); - if (CDF_STATUS_SUCCESS == - sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), - pAdapter->sessionId, - eCSR_DISCONNECT_REASON_UNSPECIFIED)) { - rc = wait_for_completion_timeout(&pAdapter-> - disconnect_comp_var, - msecs_to_jiffies - (WLAN_WAIT_TIME_DISCONNECT)); - if (!rc) { - hddLog(LOGE, - FL("Sme disconnect event timed out session Id %d staDebugState %d"), - pAdapter->sessionId, - pHddStaCtx->staDebugState); - return -EALREADY; - } + + status = sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + /* + * Wait here instead of returning directly, this will block the + * next connect command and allow processing of the scan for + * ssid and the previous connect command in CSR. Else we might + * hit some race conditions leading to SME and HDD out of sync. + */ + if (CDF_STATUS_CMD_NOT_QUEUED == status) { + hdd_info("Already disconnected or connect was in sme/roam pending list and removed by disconnect"); + } else if (0 != status) { + hdd_err("csrRoamDisconnect failure, returned %d", + (int)status); + pHddStaCtx->staDebugState = status; + result = -EINVAL; + goto disconnected; + } + + rc = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!rc && (CDF_STATUS_CMD_NOT_QUEUED != status)) { + hdd_err("Sme disconnect event timed out session Id %d staDebugState %d", + pAdapter->sessionId, pHddStaCtx->staDebugState); + result = -ETIMEDOUT; } } else if (eConnectionState_Disconnecting == - pHddStaCtx->conn_info.connState) { + pHddStaCtx->conn_info.connState) { rc = wait_for_completion_timeout(&pAdapter->disconnect_comp_var, - msecs_to_jiffies - (WLAN_WAIT_TIME_DISCONNECT)); + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); if (!rc) { - hddLog(LOGE, - FL("Disconnect event timed out session Id %d staDebugState %d"), + hdd_err("Disconnect event timed out session Id %d staDebugState %d", pAdapter->sessionId, pHddStaCtx->staDebugState); - return -EALREADY; + result = -ETIMEDOUT; } } - - return 0; +disconnected: + hdd_info("Set HDD connState to eConnectionState_NotConnected"); + hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected); + return result; } /** @@ -8952,8 +8965,7 @@ int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason) * race conditions leading to SME and HDD out of sync. */ if (CDF_STATUS_CMD_NOT_QUEUED == status) { - hddLog(LOG1, FL("status = %d, already disconnected"), - (int)status); + hdd_info("Already disconnected or connect was in sme/roam pending list and removed by disconnect"); } else if (0 != status) { hddLog(LOGE, FL("csr_roam_disconnect failure, returned %d"), @@ -8966,7 +8978,7 @@ int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason) msecs_to_jiffies (WLAN_WAIT_TIME_DISCONNECT)); - if (!rc) { + if (!rc && (CDF_STATUS_CMD_NOT_QUEUED != status)) { hddLog(LOGE, FL("Failed to disconnect, timed out")); result = -ETIMEDOUT;