wlan: Manual Reassoc Functionality
To handle the reassoc request from supplicant as part of
Manual reassoc request
Change-Id: I5719596e466c57dbba9acf37f9a369f3442cba17
CRs-Fixed: 481935
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 37a5e27..0f88ce0 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -1702,7 +1702,9 @@
tANI_U8 channel = 0;
tSirMacAddr targetApBssid;
eHalStatus status = eHAL_STATUS_SUCCESS;
-
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ tCsrHandoffRequest handoffInfo;
+#endif
hdd_station_ctx_t *pHddStaCtx = NULL;
tANI_BOOLEAN wesMode = eANI_BOOLEAN_FALSE;
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
@@ -1754,6 +1756,11 @@
}
/* Proceed with reassoc */
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ handoffInfo.channel = channel;
+ vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
+ sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
+#endif
}
#endif
#ifdef FEATURE_WLAN_LFR
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 4be93a2..8d324c6 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4123,4 +4123,14 @@
}tSirWlanExcludeUnencryptParam,*tpSirWlanExcludeUnencryptParam;
#endif
+typedef struct sAniHandoffReq
+{
+ // Common for all types are requests
+ tANI_U16 msgType; // message type is same as the request type
+ tANI_U16 msgLen; // length of the entire request
+ tANI_U8 sessionId;
+ tANI_U8 bssid[WNI_CFG_BSSID_LEN];
+ tANI_U8 channel;
+} tAniHandoffReq, *tpAniHandoffReq;
+
#endif /* __SIR_API_H */
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 9e46c4c..8c1ca67 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -375,7 +375,9 @@
#ifdef WLAN_FEATURE_GTK_OFFLOAD
eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP,
#endif // WLAN_FEATURE_GTK_OFFLOAD
- eWNI_SME_CANDIDATE_FOUND_IND, //ROAM candidate indication from FW
+ eWNI_SME_CANDIDATE_FOUND_IND, /*ROAM candidate indication from FW*/
+ eWNI_SME_HANDOFF_REQ,/*upper layer requested handoff to driver in STA mode*/
+ eWNI_SME_ROAM_SCAN_OFFLOAD_RSP,/*Fwd the LFR scan offload rsp from FW to SME*/
eWNI_SME_MSG_TYPES_END
};
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 4f28bc7..7dc0cf9 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -558,6 +558,7 @@
#endif
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#define SIR_HAL_ROAM_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 191)
+#define SIR_HAL_ROAM_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 192)
#endif
#define SIR_HAL_GET_ROAM_RSSI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 193)
#define SIR_HAL_GET_ROAM_RSSI_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 194)
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 984fb5f..4b8b869 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1367,6 +1367,13 @@
#define CSR_INVALID_SCANRESULT_HANDLE (NULL)
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+typedef struct tagCsrHandoffRequest
+{
+ tCsrBssid bssid;
+ tANI_U8 channel;
+}tCsrHandoffRequest;
+#endif
////////////////////////////////////////////Common SCAN starts
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 29be303..55592ae 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -1345,6 +1345,8 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
eHalStatus csrScanRequestLfrResult(tpAniSirGlobal pMac, tANI_U32 sessionId,
csrScanCompleteCallback callback, void *pContext);
+eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, tANI_U8 reason);
+eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, tCsrHandoffRequest *pHandoffInfo);
#endif
tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId);
#endif
diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h
index 768fd1e..70f68fa 100644
--- a/CORE/SME/inc/csrNeighborRoam.h
+++ b/CORE/SME/inc/csrNeighborRoam.h
@@ -210,6 +210,11 @@
we re-initialize occupied channel list */
tANI_S8 lookupDOWNRssi;
tANI_U8 uScanMode;
+ tANI_U8 uOsRequestedHandoff; /* upper layer requested
+ a reassoc */
+ tCsrHandoffRequest handoffReqInfo; /* handoff related info came
+ with upper layer's req for
+ reassoc */
#endif
} tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo;
@@ -265,8 +270,13 @@
#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW 12
#define REASON_NPROBES_CHANGED 13
#define REASON_HOME_AWAY_TIME_CHANGED 14
+#define REASON_OS_REQUESTED_ROAMING_NOW 15
eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reason);
eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, void* pMsg);
+eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg);
+eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac);
+eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status);
+eHalStatus csrNeighborRoamRestartLfrScan(tpAniSirGlobal pMac);
#endif
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index cd92142..052983e 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -2163,7 +2163,7 @@
\param hHal - The handle returned by macOpen.
\param newTMLevel - new Thermal Mitigation Level
\param tmMode - Thermal Mitigation handle mode, default 0
- \return eHalStatus
+ \return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_SetTmLevel(tHalHandle hHal, v_U16_t newTMLevel, v_U16_t tmMode);
@@ -2823,4 +2823,19 @@
*/
VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, tANI_U8 channel);
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+/*--------------------------------------------------------------------------
+ \brief sme_HandoffRequest() - a wrapper function to Request a handoff
+ from CSR.
+ This is a synchronous call
+ \param hHal - The handle returned by macOpen
+ \param pHandoffInfo - info provided by HDD with the handoff request (namely:
+ BSSID, channel etc.)
+ \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully.
+ Other status means SME is failed to send the request.
+ \sa
+ --------------------------------------------------------------------------*/
+
+eHalStatus sme_HandoffRequest(tHalHandle hHal, tCsrHandoffRequest *pHandoffInfo);
+#endif
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 4f92a67..6a9d241 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -6279,7 +6279,7 @@
else
{
//scan for this SSID
- status = csrScanForSSID(pMac, sessionId, pProfile, roamId);
+ status = csrScanForSSID(pMac, sessionId, pProfile, roamId, TRUE);
if(!HAL_STATUS_SUCCESS(status))
{
smsLog(pMac, LOGE, FL(" CSR failed to issue SSID scan command with status = 0x%08X"), status);
@@ -6439,7 +6439,7 @@
{
//Do a scan on this profile
//scan for this SSID only in case the AP suppresses SSID
- status = csrScanForSSID(pMac, sessionId, pProfile, roamId);
+ status = csrScanForSSID(pMac, sessionId, pProfile, roamId, TRUE);
if(!HAL_STATUS_SUCCESS(status))
{
break;
@@ -9517,6 +9517,10 @@
smsLog( pMac, LOG2, FL("Candidate found indication from PE"));
csrNeighborRoamCandidateFoundIndHdlr( pMac, pSirMsg );
break;
+ case eWNI_SME_HANDOFF_REQ:
+ smsLog( pMac, LOG2, FL("Handoff Req from self"));
+ csrNeighborRoamHandoffReqHdlr( pMac, pSirMsg );
+ break;
#endif
default:
@@ -14605,6 +14609,7 @@
if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled)
{
+ smsLog( pMac, LOGE,"isRoamOffloadScanEnabled not set \n");
return eHAL_STATUS_FAILURE;
}
status = csrRoamGetSessionIdFromBSSID(pMac,
@@ -14822,6 +14827,22 @@
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Roam Scan Offload Command %d, Reason %d", command, reason);
return status;
}
+
+eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, tANI_U8 reason)
+{
+ switch(reason)
+ {
+ case 0:
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Rsp for Roam Scan Offload with failure status");
+ break;
+ case REASON_OS_REQUESTED_ROAMING_NOW:
+ csrNeighborRoamProceedWithHandoffReq(pMac);
+ break;
+ default:
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Rsp for Roam Scan Offload with unknown Reason %d", reason);
+ }
+ return eHAL_STATUS_SUCCESS;
+}
#endif
tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask,
@@ -15864,3 +15885,37 @@
return eANI_BOOLEAN_FALSE;
}
+
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+eHalStatus csrHandoffRequest(tpAniSirGlobal pMac,
+ tCsrHandoffRequest *pHandoffInfo)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ vos_msg_t msg;
+
+ tAniHandoffReq *pMsg;
+ status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, sizeof(tAniHandoffReq));
+ if ( !HAL_STATUS_SUCCESS(status) )
+ {
+ smsLog(pMac, LOGE, " csrHandoffRequest: failed to allocate mem for req ");
+ return status;
+ }
+ pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_HANDOFF_REQ);
+ pMsg->msgLen = (tANI_U16)sizeof(tAniHandoffReq);
+ pMsg->sessionId = pMac->roam.neighborRoamInfo.csrSessionId;
+ pMsg->channel = pHandoffInfo->channel;
+ palCopyMemory(pMac->hHdd, pMsg->bssid,
+ pHandoffInfo->bssid,
+ 6);
+ msg.type = eWNI_SME_HANDOFF_REQ;
+ msg.bodyptr = pMsg;
+ msg.reserved = 0;
+ if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg))
+ {
+ smsLog(pMac, LOGE, " csrHandoffRequest failed to post msg to self ");
+ palFreeMemory(pMac->hHdd, (void *)pMsg);
+ status = eHAL_STATUS_FAILURE;
+ }
+ return status;
+}
+#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index d51ae0a..351e417 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -1610,6 +1610,19 @@
#endif
do
{
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ //if this scan is for LFR
+ if(pMac->roam.neighborRoamInfo.uOsRequestedHandoff)
+ {
+ //notify LFR state m/c
+ if(eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, eHAL_STATUS_SUCCESS))
+ {
+ csrNeighborRoamRestartLfrScan(pMac);
+ }
+ status = eHAL_STATUS_SUCCESS;
+ break;
+ }
+#endif
//If there is roam command waiting, ignore this roam because the newer roam command is the one to execute
if(csrIsRoamCommandWaitingForSession(pMac, sessionId))
{
@@ -1682,7 +1695,18 @@
tANI_U32 sessionId = pCommand->sessionId;
tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile;
tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
-
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ //if this scan is for LFR
+ if(pMac->roam.neighborRoamInfo.uOsRequestedHandoff)
+ {
+ //notify LFR state m/c
+ if(eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, eHAL_STATUS_FAILURE))
+ {
+ csrNeighborRoamRestartLfrScan(pMac);
+ }
+ return eHAL_STATUS_SUCCESS;
+ }
+#endif
if(!pSession)
{
smsLog(pMac, LOGE, FL(" session %d not found "), sessionId);
@@ -6665,7 +6689,7 @@
//This function is usually used for BSSs that suppresses SSID so the profile
//shall have one and only one SSID
-eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId)
+eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify)
{
eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
tSmeCmd *pScanCmd = NULL;
@@ -6701,7 +6725,7 @@
pScanCmd->sessionId = (tANI_U8)sessionId;
pScanCmd->u.scanCmd.callback = NULL;
pScanCmd->u.scanCmd.pContext = NULL;
- pScanCmd->u.scanCmd.reason = eCsrScanForSsid;
+ pScanCmd->u.scanCmd.reason = eCsrScanForSsid;//Need to check: might need a new reason for SSID scan for LFR during multisession with p2p
pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
palZeroMemory(pMac->hHdd, &pScanCmd->u.scanCmd.u.scanRequest, sizeof(tCsrScanRequest));
pScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
@@ -6811,8 +6835,11 @@
csrReleaseCommandScan(pMac, pScanCmd);
//TODO:free the memory that is allocated in this function
}
+ if(notify)
+ {
csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE);
}
+ }
}//valid
else
{
@@ -7615,3 +7642,90 @@
}
#endif
+eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId,
+ tCsrBssid bssid, tANI_U8 channel)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tDot11fBeaconIEs *pNewIes = NULL;
+ tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
+ tSirBssDescription *pNewBssDescriptor;
+ tANI_U32 size = 0;
+
+ if(NULL == pSession)
+ {
+ status = eHAL_STATUS_FAILURE;
+ return status;
+ }
+ smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: Current bssid::"
+ "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x"),
+ pSession->pConnectBssDesc->bssId[0],
+ pSession->pConnectBssDesc->bssId[1],
+ pSession->pConnectBssDesc->bssId[2],
+ pSession->pConnectBssDesc->bssId[3],
+ pSession->pConnectBssDesc->bssId[4],
+ pSession->pConnectBssDesc->bssId[5]);
+ smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: My bssid::"
+ "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x channel %d"),
+ bssid[0],bssid[1],bssid[2],
+ bssid[3],bssid[4],bssid[5],channel);
+
+ do
+ {
+ if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
+ pSession->pConnectBssDesc, &pNewIes)))
+ {
+ smsLog(pMac, LOGE, FL("%s: Failed to parse IEs"),
+ __func__);
+ status = eHAL_STATUS_FAILURE;
+ break;
+ }
+
+ size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length);
+ if(size)
+ {
+ status = palAllocateMemory(pMac->hHdd, (void **)&pNewBssDescriptor, size);
+ if(HAL_STATUS_SUCCESS(status))
+ {
+ palCopyMemory(pMac->hHdd, pNewBssDescriptor, pSession->pConnectBssDesc, size);
+ }
+ else
+ {
+ smsLog(pMac, LOGE, FL("%s: memory allocation failed"),
+ __func__);
+ status = eHAL_STATUS_FAILURE;
+ break;
+ }
+
+ //change the BSSID & channel as passed
+ palCopyMemory( pMac->hHdd, pNewBssDescriptor->bssId, bssid,
+ sizeof(tSirMacAddr) );
+ pNewBssDescriptor->channelId = channel;
+ if(NULL == csrScanSaveBssDescription( pMac, pNewBssDescriptor, pNewIes ))
+ {
+ smsLog(pMac, LOGE, FL("%s: csrScanSaveBssDescription failed"),
+ __func__);
+ status = eHAL_STATUS_FAILURE;
+ break;
+ }
+ }
+ else
+ {
+ smsLog(pMac, LOGE, FL("%s: length of bss descriptor is 0"),
+ __func__);
+ status = eHAL_STATUS_FAILURE;
+ break;
+ }
+ smsLog(pMac, LOGE, FL("%s: entry successfully added in scan cache"),
+ __func__);
+ }while(0);
+
+ if(pNewIes)
+ {
+ palFreeMemory(pMac->hHdd, pNewIes);
+ }
+ if(pNewBssDescriptor)
+ {
+ palFreeMemory(pMac->hHdd, pNewBssDescriptor);
+ }
+ return status;
+}
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index 1a8d5cf..d3221a7 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -259,7 +259,7 @@
eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq);
eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult);
void csrInitBGScanChannelList(tpAniSirGlobal pMac);
-eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId);
+eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify);
eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps);
eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac);
eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac);
@@ -968,5 +968,8 @@
tDot11fBeaconIEs *pIes);
#endif
eHalStatus csrSetTxPower(tpAniSirGlobal pMac, v_U8_t sessionId, v_U8_t mW);
+
+eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId,
+ tCsrBssid bssid, tANI_U8 channel);
#endif
diff --git a/CORE/SME/src/csr/csrNeighborRoam.c b/CORE/SME/src/csr/csrNeighborRoam.c
index 5affa75..6eccaf2 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.c
@@ -631,6 +631,11 @@
pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
#endif
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+ vos_mem_zero(&pNeighborRoamInfo->handoffReqInfo, sizeof(tCsrHandoffRequest));
+#endif
+
}
static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac)
@@ -735,6 +740,10 @@
pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
#endif
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+ vos_mem_zero(&pNeighborRoamInfo->handoffReqInfo, sizeof(tCsrHandoffRequest));
+#endif
}
void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac)
@@ -1096,8 +1105,13 @@
if(pEntry)
{
pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
- /* Add the BSSID to pre-auth fail list */
+ /* Add the BSSID to pre-auth fail list if it is not requested by HDD */
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if(!pNeighborRoamInfo->uOsRequestedHandoff)
+#endif
+ {
status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
+ }
/* Now we can free this node */
csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
}
@@ -1110,6 +1124,7 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (csrRoamIsRoamOffloadScanEnabled(pMac))
{
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_RESTART, REASON_PREAUTH_FAILED_FOR_ALL);
CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
} else
@@ -1180,6 +1195,28 @@
/* We dont want to set BSSID based Filter */
pScanFilter->BSSIDs.numOfBSSIDs = 0;
+ //only for HDD requested handoff fill in the BSSID in the filter
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (pNeighborRoamInfo->uOsRequestedHandoff)
+ {
+ pScanFilter->BSSIDs.numOfBSSIDs = 1;
+ pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
+ if (NULL == pScanFilter->BSSIDs.bssid)
+ {
+ smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
+ return eHAL_STATUS_FAILED_ALLOC;
+ }
+
+ vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
+
+ /* Populate the BSSID from handoff info received from HDD */
+ for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
+ {
+ vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
+ pNeighborRoamInfo->handoffReqInfo.bssid, sizeof(tSirMacAddr));
+ }
+ }
+#endif
/* Populate all the information from the connected profile */
pScanFilter->SSIDs.numOfSSIDs = 1;
pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
@@ -1967,6 +2004,7 @@
{
if (!tempVal || !roamNow)
{
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
/* There is no candidate or We are not roaming Now.
* Inform the FW to restart Roam Offload Scan */
csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_RESTART, REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
@@ -3879,7 +3917,9 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/*Inform the Firmware to STOP Scanning as the host has a disconnect.*/
if (csrRoamIsStaMode(pMac, sessionId))
+ {
csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED);
+ }
#endif
return eHAL_STATUS_SUCCESS;
}
@@ -4018,7 +4058,10 @@
* down to firmware.Do not send the START command for other session
* connections.*/
if(csrRoamIsStaMode(pMac, sessionId))
+ {
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_CONNECT);
+ }
} else {
#endif
@@ -4592,9 +4635,10 @@
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
eHalStatus status = eHAL_STATUS_SUCCESS;
/* we must be in connected state, if not ignore it */
- if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState)
+ if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState)
+ || (pNeighborRoamInfo->uOsRequestedHandoff))
{
- smsLog(pMac, LOGW, FL("Received in not CONNECTED state. Ignore it"));
+ smsLog(pMac, LOGE, FL("Received in not CONNECTED state OR uOsRequestedHandoff is set. Ignore it"));
status = eHAL_STATUS_FAILURE;
}
else
@@ -4612,5 +4656,268 @@
return status;
}
+
+/* ---------------------------------------------------------------------------
+
+ \fn csrNeighborRoamProcessHandoffReq
+
+ \brief This function is called start with the handoff process. First do a
+ SSID scan for the BSSID provided
+
+ \param pMac - The handle returned by macOpen.
+
+ \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+eHalStatus csrNeighborRoamProcessHandoffReq(tpAniSirGlobal pMac)
+{
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tANI_U32 roamId;
+ tCsrRoamProfile *pProfile = NULL;
+ tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pNeighborRoamInfo->csrSessionId );
+ tANI_U8 i = 0;
+
+ do
+ {
+ roamId = GET_NEXT_ROAM_ID(&pMac->roam);
+ status = palAllocateMemory(pMac->hHdd, (void **)&pProfile, sizeof(tCsrRoamProfile));
+ if(!HAL_STATUS_SUCCESS(status))
+ {
+ smsLog(pMac, LOGE, FL("Memory alloc failed"));
+ break;
+ }
+ palZeroMemory(pMac->hHdd, pProfile, sizeof(tCsrRoamProfile));
+ status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile);
+ if(!HAL_STATUS_SUCCESS(status))
+ {
+ smsLog(pMac, LOGE, FL("Profile copy failed"));
+ break;
+ }
+
+ //Add the BSSID & Channel
+ pProfile->BSSIDs.numOfBSSIDs = 1;
+ pProfile->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pProfile->BSSIDs.numOfBSSIDs);
+ if (NULL == pProfile->BSSIDs.bssid)
+ {
+ smsLog(pMac, LOGE, FL("mem alloc failed for BSSID"));
+ status = eHAL_STATUS_FAILURE;
+ break;
+ }
+
+ vos_mem_zero(pProfile->BSSIDs.bssid, sizeof(tSirMacAddr) * pProfile->BSSIDs.numOfBSSIDs);
+
+ /* Populate the BSSID from handoff info received from HDD */
+ for (i = 0; i < pProfile->BSSIDs.numOfBSSIDs; i++)
+ {
+ vos_mem_copy(&pProfile->BSSIDs.bssid[i],
+ pNeighborRoamInfo->handoffReqInfo.bssid, sizeof(tSirMacAddr));
+ }
+
+ pProfile->ChannelInfo.numOfChannels = 1;
+ pProfile->ChannelInfo.ChannelList =
+ vos_mem_malloc(sizeof(*pProfile->ChannelInfo.ChannelList) *
+ pProfile->ChannelInfo.numOfChannels);
+ if (NULL == pProfile->ChannelInfo.ChannelList)
+ {
+ smsLog(pMac, LOGE, FL("mem alloc failed for ChannelList"));
+ status = eHAL_STATUS_FAILURE;
+ break;
+ }
+ pProfile->ChannelInfo.ChannelList[0] = pNeighborRoamInfo->handoffReqInfo.channel;
+
+ //clean up csr cache first
+ //csrScanFlushSelectiveResult(pMac, VOS_FALSE);
+ //do a SSID scan
+ status = csrScanForSSID(pMac, pNeighborRoamInfo->csrSessionId, pProfile, roamId, FALSE);
+ if(!HAL_STATUS_SUCCESS(status))
+ {
+ smsLog(pMac, LOGE, FL("SSID scan failed"));
+ }
+ }while(0);
+
+ if(NULL != pProfile)
+ {
+ csrReleaseProfile(pMac, pProfile);
+ palFreeMemory(pMac->hHdd, pProfile);
+ }
+
+ return status;
+}
+
+/* ---------------------------------------------------------------------------
+
+ \fn csrNeighborRoamSssidScanDone
+
+ \brief This function is called once SSID scan is done. If SSID scan failed
+ to find our candidate add an entry to csr scan cache ourself before starting
+ the handoff process
+
+ \param pMac - The handle returned by macOpen.
+
+ \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status)
+{
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
+ eHalStatus hstatus;
+
+ smsLog(pMac, LOGE, FL("called "));
+
+ /* we must be in connected state, if not ignore it */
+ if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState)
+ {
+ smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ //if SSID scan failed to find our candidate add an entry to csr scan cache ourself
+ if(!HAL_STATUS_SUCCESS(status))
+ {
+ smsLog(pMac, LOGE, FL("Add an entry to csr scan cache"));
+ hstatus = csrScanCreateEntryInScanCache(pMac, pNeighborRoamInfo->csrSessionId,
+ pNeighborRoamInfo->handoffReqInfo.bssid,
+ pNeighborRoamInfo->handoffReqInfo.channel);
+ if (eHAL_STATUS_SUCCESS != hstatus)
+ {
+ smsLog(pMac, LOGE, FL("csrScanCreateEntryInScanCache failed with status %d"), hstatus);
+ return eHAL_STATUS_FAILURE;
+ }
+ }
+
+ /* Now we have completed scanning for the candidate provided by HDD. Let move on to HO*/
+ hstatus = csrNeighborRoamProcessScanComplete(pMac);
+
+ if (eHAL_STATUS_SUCCESS != hstatus)
+ {
+ smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus);
+ return eHAL_STATUS_FAILURE;
+ }
+ return eHAL_STATUS_SUCCESS;
+}
+
+/* ---------------------------------------------------------------------------
+
+ \fn csrNeighborRoamHandoffReqHdlr
+
+ \brief This function is called by CSR as soon as it gets a handoff request
+ to SME via MC thread
+
+ \param pMac - The handle returned by macOpen.
+ pMsg - Msg sent by HDD
+
+ \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg)
+{
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
+ tAniHandoffReq *pHandoffReqInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ /* we must be in connected state, if not ignore it */
+ if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState)
+ {
+ smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it"));
+ status = eHAL_STATUS_FAILURE;
+ }
+ else
+ {
+ //save the handoff info came from HDD as part of the reassoc req
+ pHandoffReqInfo = (tAniHandoffReq *)pMsg;
+ if (NULL != pHandoffReqInfo)
+ {
+ //sanity check
+ if (VOS_FALSE == vos_mem_compare(pHandoffReqInfo->bssid,
+ pNeighborRoamInfo->currAPbssid,
+ sizeof(tSirMacAddr)))
+ {
+
+ pNeighborRoamInfo->handoffReqInfo.channel = pHandoffReqInfo->channel;
+ vos_mem_copy(pNeighborRoamInfo->handoffReqInfo.bssid,
+ pHandoffReqInfo->bssid,
+ 6);
+ pNeighborRoamInfo->uOsRequestedHandoff = 1;
+ status = csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_STOP,
+ REASON_OS_REQUESTED_ROAMING_NOW);
+ if (eHAL_STATUS_SUCCESS != status)
+ {
+ smsLog(pMac, LOGE, FL("csrRoamOffloadScan failed"));
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+ }
+ }
+ else
+ {
+ smsLog(pMac, LOGE, FL("Received req has same BSSID as current AP!!"));
+ status = eHAL_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ smsLog(pMac, LOGE, FL("Received msg is NULL"));
+ status = eHAL_STATUS_FAILURE;
+ }
+ }
+
+ return status;
+}
+
+/* ---------------------------------------------------------------------------
+
+ \fn csrNeighborRoamProceedWithHandoffReq
+
+ \brief This function is called by CSR as soon as it gets rsp back for
+ ROAM_SCAN_OFFLOAD_STOP with reason REASON_OS_REQUESTED_ROAMING_NOW
+
+ \param pMac - The handle returned by macOpen.
+
+ \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac)
+{
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ /* we must be in connected state, if not ignore it */
+ if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState)
+ || (!pNeighborRoamInfo->uOsRequestedHandoff))
+ {
+ smsLog(pMac, LOGE, FL("Received in not CONNECTED state or uOsRequestedHandoff is not set. Ignore it"));
+ status = eHAL_STATUS_FAILURE;
+ }
+ else
+ {
+ //Let's go ahead with handoff
+ status = csrNeighborRoamProcessHandoffReq(pMac);
+ }
+ if(!HAL_STATUS_SUCCESS(status))
+ {
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+ }
+ return status;
+}
+
+/* ---------------------------------------------------------------------------
+
+ \fn csrNeighborRoamRestartLfrScan
+
+ \brief This function is called if HDD requested handoff failed for some
+ reason. Restart the LFR logic at that point.
+
+ \param pMac - The handle returned by macOpen.
+
+ \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+eHalStatus csrNeighborRoamRestartLfrScan(tpAniSirGlobal pMac)
+{
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
+ pNeighborRoamInfo->uOsRequestedHandoff = 0;
+ /* There is no candidate or We are not roaming Now.
+ * Inform the FW to restart Roam Offload Scan */
+ csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_RESTART, REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW);
+
+ return eHAL_STATUS_SUCCESS;
+}
#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index baec7ce..2c92f88 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1757,6 +1757,11 @@
}
break;
#endif
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP:
+ status = csrRoamOffloadScanRspHdlr((void *)pMac, pMsg->bodyval);
+ break;
+#endif // WLAN_FEATURE_ROAM_SCAN_OFFLOAD
default:
@@ -8420,3 +8425,35 @@
return VOS_STATUS_SUCCESS;
}
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+/*--------------------------------------------------------------------------
+ \brief sme_HandoffRequest() - a wrapper function to Request a handoff
+ from CSR.
+ This is a synchronous call
+ \param hHal - The handle returned by macOpen
+ \param pHandoffInfo - info provided by HDD with the handoff request (namely:
+ BSSID, channel etc.)
+ \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully.
+ Other status means SME is failed to send the request.
+ \sa
+ --------------------------------------------------------------------------*/
+
+eHalStatus sme_HandoffRequest(tHalHandle hHal,
+ tCsrHandoffRequest *pHandoffInfo)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+
+ status = sme_AcquireGlobalLock( &pMac->sme );
+ if ( HAL_STATUS_SUCCESS( status ) )
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ "%s: invoked", __func__);
+ status = csrHandoffRequest(pMac, pHandoffInfo);
+ sme_ReleaseGlobalLock( &pMac->sme );
+ }
+
+ return status ;
+}
+#endif
+
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index d469841..8938dec 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1037,6 +1037,7 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#define WDA_ROAM_SCAN_OFFLOAD_REQ SIR_HAL_ROAM_SCAN_OFFLOAD_REQ
+#define WDA_ROAM_SCAN_OFFLOAD_RSP SIR_HAL_ROAM_SCAN_OFFLOAD_RSP
#endif
#ifdef WLAN_WAKEUP_EVENTS
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index bba74ba..72ca23e 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -12613,7 +12613,10 @@
void WDA_RoamOffloadScanReqCallback(WDI_Status status, void* pUserData)
{
tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
- VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ vos_msg_t vosMsg;
+ wpt_uint8 reason = 0;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL,
"<------ %s " ,__func__);
if (NULL == pWdaParams)
{
@@ -12626,6 +12629,7 @@
{
if ( pWdaParams->wdaWdiApiMsgParam != NULL )
{
+ reason = ((WDI_RoamScanOffloadReqParamsType *)pWdaParams->wdaWdiApiMsgParam)->wdiRoamOffloadScanInfo.StartScanReason;
vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
}
if ( pWdaParams->wdaMsgParam != NULL)
@@ -12635,6 +12639,20 @@
vos_mem_free(pWdaParams) ;
}
+ vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP;
+ vosMsg.bodyptr = NULL;
+ if (WDI_STATUS_SUCCESS != status)
+ {
+ reason = 0;
+ }
+ vosMsg.bodyval = reason;
+ if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg))
+ {
+ /* free the mem and return */
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "Failed to post the rsp to UMAC" ,__func__);
+ }
+
return ;
}
#endif