Commit 007ee031 authored by Chandrasekaran, Manishekar's avatar Chandrasekaran, Manishekar Committed by Madan Mohan Koyyalamudi
Browse files

qcacld: Abort scan for SSID if deauth is received from supplicant.

During connection if AP is not found in scan list, driver tries
to scan for the ssid (eCsrScanForSsid) and if AP is found,
the connect cmd is started.

During this scan if Disconnect comes from supplicant, as there is
no ongoing connect command and sme is not in connected state, the
disconnect command is dropped in SME and hdd is indicated success.
This leads to HDD waiting on the event disconnect_comp_var and
connState to eConnectionState_Disconnecting.

After this if supplicant send connect and as HDD is in
disconnecting state it will again wait for disconnect_comp_var
and return failure after timeout and this will continue and user
will not able to connect.

If disconnect is received during eCsrScanForSsid abort/dequeue
the eCsrScanForSsid in SME and in HDD set the connState to
eConnectionState_NotConnected and set disconnect_comp_var
complete.

Change-Id: I1da89065e1e59bcf08806179f85e3d9d00d5828e
CRs-Fixed: 689890
parent c12d5029
......@@ -9946,6 +9946,7 @@ int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
int status;
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
long ret;
 
status = wlan_hdd_validate_context(pHddCtx);
 
......@@ -9970,8 +9971,13 @@ int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
 
status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, reason);
if ( 0 != status )
if(eHAL_STATUS_CMD_NOT_QUEUED == status)
{
hddLog(VOS_TRACE_LEVEL_INFO,
FL("status = %d, already disconnected"),
(int)status );
}
else if ( 0 != status )
{
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s csrRoamDisconnect failure, returned %d",
......@@ -9979,24 +9985,26 @@ int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
pHddStaCtx->staDebugState = status;
return -EINVAL;
}
status = wait_for_completion_interruptible_timeout(
ret = wait_for_completion_interruptible_timeout(
&pAdapter->disconnect_comp_var,
msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
 
hdd_connSetConnectionState(pAdapter,
eConnectionState_NotConnected);
if (!status)
if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
{
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: Failed to disconnect, timed out", __func__);
return -ETIMEDOUT;
} else if (status == -ERESTARTSYS)
}
else if (ret == -ERESTARTSYS)
{
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: Failed to disconnect, wait interrupted", __func__);
return status;
return ret;
}
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
FL("Set HDD connState to eConnectionState_NotConnected"));
hdd_connSetConnectionState(pAdapter,
eConnectionState_NotConnected);
 
return 0;
}
......
......@@ -7457,7 +7457,10 @@ eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eC
}
else
{
smsLog( pMac, LOGE, FL("Roam command is not present"));
csrScanAbortScanForSSID(pMac, sessionId);
status = eHAL_STATUS_CMD_NOT_QUEUED;
smsLog( pMac, LOG1, FL(" Disconnect cmd not queued, Roam command is not present"
" return with status %d"), status);
}
return (status);
}
......
......@@ -8210,6 +8210,112 @@ void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList,
}
eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tSirSmeScanAbortReq *pMsg;
tANI_U16 msgLen;
tListElem *pEntry;
tSmeCmd *pCommand;
if (!pMac->fScanOffload)
{
pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
#ifdef WLAN_AP_STA_CONCURRENCY
csrRemoveScanForSSIDFromPendingList( pMac, &pMac->scan.scanCmdPendingList, sessionId);
#endif
csrRemoveScanForSSIDFromPendingList( pMac, &pMac->roam.roamCmdPendingList, sessionId);
csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeCmdPendingList, sessionId);
pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;
pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
}
else
{
pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE;
csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeScanCmdPendingList, sessionId);
pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE;
pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK);
}
if(NULL != pEntry)
{
pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
if ( (eSmeCommandScan == pCommand->command ) &&
(sessionId == pCommand->sessionId))
{
if ( eCsrScanForSsid == pCommand->u.scanCmd.reason)
{
msgLen = (tANI_U16)(sizeof( tSirSmeScanAbortReq ));
pMsg = vos_mem_malloc(msgLen);
if ( NULL == pMsg )
{
status = eHAL_STATUS_FAILURE;
smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq"));
}
else
{
vos_mem_zero((void *)pMsg, msgLen);
pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND);
pMsg->msgLen = pal_cpu_to_be16(msgLen);
pMsg->sessionId = sessionId;
status = palSendMBMessage(pMac->hHdd, pMsg);
}
}
}
}
return( status );
}
void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId)
{
tDblLinkList localList;
tListElem *pEntry;
tSmeCmd *pCommand;
tListElem *pEntryToRemove;
vos_mem_zero(&localList, sizeof(tDblLinkList));
if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList)))
{
smsLog(pMac, LOGE, FL(" failed to open list"));
return;
}
csrLLLock(pList);
if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) )
{
pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK);
// Have to make sure we don't loop back to the head of the list, which will
// happen if the entry is NOT on the list...
while( pEntry )
{
pEntryToRemove = pEntry;
pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link );
if ( (eSmeCommandScan == pCommand->command ) &&
(sessionId == pCommand->sessionId) )
{
if ( eCsrScanForSsid == pCommand->u.scanCmd.reason)
{
// Remove that entry only
if ( csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK))
{
csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK);
}
}
}
}
}
csrLLUnlock(pList);
while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) )
{
pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link );
csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE);
}
csrLLClose(&localList);
}
eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac,
tANI_U8 sessionId)
......
......@@ -293,6 +293,9 @@ void csrRemoveCmdWithSessionIdFromPendingList(tpAniSirGlobal pMac,
eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac,
tANI_U8 sessionId);
eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 sessionId);
eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId);
void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId);
//To age out scan results base. tSmeGetScanChnRsp is a pointer returned by LIM that
//has the information regarding scanned channels.
//The logic is that whenever CSR add a BSS to scan result, it set the age count to
......
......@@ -214,7 +214,8 @@ typedef enum
eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS,
eHAL_STATUS_FT_PREAUTH_KEY_FAILED,
#endif
//CMD not Queued in SME
eHAL_STATUS_CMD_NOT_QUEUED,
// not a real status. Just a way to mark the maximum in the enum.
eHAL_STATUS_MAX
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment