wlan: Add support for PER based roaming #2
In congested environments, it could be possible that in station
mode client gets good RSSI from AP however it's not able to
transfer data at good rates. DUT should roam to a better AP if
available, if it faces congestion in home channel.
Following changes are added for this functionality:
1. Add changes to monitor Rx and Tx rates to trigger roam scan
in case data rates are low below a preconfigured value.
2. Implement a new AP selection algorithm which will consider AP
capabilty, channel conditions and RSSI to select new bss.
Add required protocol changes for same.
Change-Id: I394c15b54ea95aa08f648f33383cb0a364278585
CRs-Fixed: 1031345
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index ec93e5e..ced64e7 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -1932,8 +1932,21 @@
pMac->roam.configParam.nRoamScanHomeAwayTime = pParam->nRoamScanHomeAwayTime;
#endif
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
- pMac->roam.configParam.isRoamOffloadScanEnabled = pParam->isRoamOffloadScanEnabled;
- pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = pParam->bFastRoamInConIniFeatureEnabled;
+ pMac->roam.configParam.isRoamOffloadScanEnabled =
+ pParam->isRoamOffloadScanEnabled;
+ pMac->roam.configParam.bFastRoamInConIniFeatureEnabled =
+ pParam->bFastRoamInConIniFeatureEnabled;
+ pMac->roam.configParam.isPERRoamEnabled =
+ pParam->isPERRoamEnabled;
+ pMac->roam.configParam.rateUpThreshold = pParam->rateUpThreshold;
+ pMac->roam.configParam.rateDownThreshold = pParam->rateDownThreshold;
+ pMac->roam.configParam.waitPeriodForNextPERScan =
+ pParam->waitPeriodForNextPERScan;
+ pMac->roam.configParam.PERtimerThreshold = pParam->PERtimerThreshold;
+ pMac->roam.configParam.isPERRoamCCAEnabled =
+ pParam->isPERRoamCCAEnabled;
+ pMac->roam.configParam.PERroamTriggerPercent =
+ pParam->PERroamTriggerPercent;
#endif
#ifdef FEATURE_WLAN_LFR
pMac->roam.configParam.isFastRoamIniFeatureEnabled = pParam->isFastRoamIniFeatureEnabled;
@@ -2141,6 +2154,17 @@
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
pParam->isRoamOffloadScanEnabled = pMac->roam.configParam.isRoamOffloadScanEnabled;
pParam->bFastRoamInConIniFeatureEnabled = pMac->roam.configParam.bFastRoamInConIniFeatureEnabled;
+ pParam->isPERRoamEnabled =
+ pMac->roam.configParam.isPERRoamEnabled;
+ pParam->rateUpThreshold = pMac->roam.configParam.rateUpThreshold;
+ pParam->rateDownThreshold = pMac->roam.configParam.rateDownThreshold;
+ pParam->waitPeriodForNextPERScan =
+ pMac->roam.configParam.waitPeriodForNextPERScan;
+ pParam->PERtimerThreshold = pMac->roam.configParam.PERtimerThreshold;
+ pParam->isPERRoamCCAEnabled =
+ pMac->roam.configParam.isPERRoamCCAEnabled;
+ pParam->PERroamTriggerPercent =
+ pMac->roam.configParam.PERroamTriggerPercent;
#endif
#ifdef FEATURE_WLAN_LFR
pParam->isFastRoamIniFeatureEnabled = pMac->roam.configParam.isFastRoamIniFeatureEnabled;
@@ -8287,8 +8311,11 @@
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
tCsrRoamInfo roamInfo;
tANI_U32 roamId = 0;
-
- if ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode )
+ tANI_U32 current_timestamp, max_time = -1;
+ tANI_U32 candidateApCnt, oldestIndex;
+ tANI_U8 nilMac[6] = {0};
+
+ if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode)
{
smsLog( pMac, LOGW, "CSR SmeReassocReq Successful" );
result = eCsrReassocSuccess;
@@ -8301,6 +8328,73 @@
/* Need to dig more on indicating events to SME QoS module */
sme_QosCsrEventInd(pMac, pSmeJoinRsp->sessionId, SME_QOS_CSR_HANDOFF_COMPLETE, NULL);
csrRoamComplete( pMac, result, pSmeJoinRsp);
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ /* Add previous BSSID to blacklist ; this will be in blacklised for
+ * some period and score of this AP will be reduced if black listed
+ * to avoid ping pong */
+ if (pMac->PERroamCandidatesCnt)
+ {
+ current_timestamp = jiffies_to_msecs(jiffies);
+ for (candidateApCnt = 0; candidateApCnt <
+ SIR_PER_ROAM_MAX_CANDIDATE_CNT; candidateApCnt++)
+ {
+ /* Find one blank entry */
+ if (sirCompareMacAddr(nilMac,
+ pMac->previousRoamApInfo[candidateApCnt].bssAddr))
+ {
+ vos_mem_copy(pMac->previousRoamApInfo[candidateApCnt].
+ bssAddr,
+ pNeighborRoamInfo->prevConnProfile.bssid,
+ sizeof(tSirMacAddr));
+ pMac->previousRoamApInfo[candidateApCnt].timeStamp =
+ current_timestamp;
+ smsLog(pMac, LOG1, FL("added bssid=" MAC_ADDRESS_STR " at index %d"),
+ MAC_ADDR_ARRAY(
+ pNeighborRoamInfo->prevConnProfile.bssid),
+ candidateApCnt);
+ break;
+ }
+ /* if already in the list */
+ if (sirCompareMacAddr(pMac->previousRoamApInfo
+ [candidateApCnt].bssAddr,
+ pNeighborRoamInfo->prevConnProfile.bssid) &&
+ ((current_timestamp -
+ pMac->previousRoamApInfo[candidateApCnt].timeStamp) >
+ pMac->PERroamTimeout))
+ {
+ vos_mem_copy(pMac->previousRoamApInfo[candidateApCnt].
+ bssAddr,
+ pNeighborRoamInfo->prevConnProfile.bssid,
+ sizeof(tSirMacAddr));
+ pMac->previousRoamApInfo[candidateApCnt].timeStamp =
+ current_timestamp;
+ break;
+ } else
+ {
+ /* find oldest BSSID entry in the blacklist */
+ if (max_time <
+ pMac->previousRoamApInfo[candidateApCnt].timeStamp)
+ {
+ max_time =
+ pMac->previousRoamApInfo[candidateApCnt].timeStamp;
+ oldestIndex = candidateApCnt;
+ }
+ }
+ }
+ if (candidateApCnt == SIR_PER_ROAM_MAX_CANDIDATE_CNT)
+ {
+ smsLog(pMac, LOGW,
+ "%s: Clearing out oldest roam results bssid="
+ MAC_ADDRESS_STR,
+ __func__,
+ MAC_ADDR_ARRAY(pMac->previousRoamApInfo[oldestIndex].bssAddr));
+ pMac->previousRoamApInfo[oldestIndex].timeStamp = current_timestamp;
+ vos_mem_copy(pMac->previousRoamApInfo[oldestIndex].bssAddr,
+ pNeighborRoamInfo->prevConnProfile.bssid,
+ sizeof(tSirMacAddr));
+ }
+ }
+#endif
}
else
#endif
@@ -16594,7 +16688,9 @@
eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reason)
{
vos_msg_t msg;
+ vos_msg_t PERroamScanConfigMsg = {0};
tSirRoamOffloadScanReq *pRequestBuf;
+ tSirPERRoamOffloadScanReq *PERRoamReqBuf;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
tCsrRoamSession *pSession = NULL;
tANI_U8 i,j,num_channels = 0, ucDot11Mode;
@@ -16880,6 +16976,7 @@
/* MAWC feature */
pRequestBuf->MAWCEnabled =
pMac->roam.configParam.MAWCEnabled;
+
#ifdef FEATURE_WLAN_ESE
pRequestBuf->IsESEEnabled = pMac->roam.configParam.isEseIniFeatureEnabled;
#endif
@@ -17078,6 +17175,52 @@
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Roam Scan Offload Command %d, Reason %d", command, reason);
+
+ if (sme_IsFeatureSupportedByFW(PER_BASED_ROAMING) &&
+ (command != ROAM_SCAN_OFFLOAD_STOP))
+ {
+
+ /* PER ROAM SCAN */
+ PERRoamReqBuf = vos_mem_malloc(sizeof(*PERRoamReqBuf));
+ if (!PERRoamReqBuf)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: Not able to allocate mem for PERRoamReqBuf", __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+ /* PER Roam Config */
+ PERRoamReqBuf->rateUpThreshold =
+ pMac->roam.configParam.rateUpThreshold;
+ PERRoamReqBuf->rateDownThreshold =
+ pMac->roam.configParam.rateDownThreshold;
+ PERRoamReqBuf->waitPeriodForNextPERScan =
+ pMac->roam.configParam.waitPeriodForNextPERScan;
+ PERRoamReqBuf->PERtimerThreshold =
+ pMac->roam.configParam.PERtimerThreshold;
+ PERRoamReqBuf->isPERRoamCCAEnabled =
+ pMac->roam.configParam.isPERRoamCCAEnabled;
+ PERRoamReqBuf->PERroamTriggerPercent =
+ pMac->roam.configParam.PERroamTriggerPercent;
+ PERRoamReqBuf->sessionId = sessionId;
+
+ PERroamScanConfigMsg.type = WDA_PER_ROAM_SCAN_OFFLOAD_REQ;
+ PERroamScanConfigMsg.reserved = 0;
+ PERroamScanConfigMsg.bodyptr = PERRoamReqBuf;
+ if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA,
+ &PERroamScanConfigMsg))) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ FL("Not able to post WDA_PER_ROAM_SCAN_OFFLOAD_REQ msg to WDA"));
+ vos_mem_free(PERRoamReqBuf);
+ return eHAL_STATUS_FAILURE;
+ }
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+ FL("rateUpThreshold =%x rateDownThreshold =%x waitPeriodForNextPERScan=%u PERtimerThreshold=%u"),
+ PERRoamReqBuf->rateUpThreshold,
+ PERRoamReqBuf->rateDownThreshold,
+ PERRoamReqBuf->waitPeriodForNextPERScan,
+ PERRoamReqBuf->PERtimerThreshold);
+ }
+
return status;
}