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/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index fedb845..706940d 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -177,7 +177,11 @@
#endif // FEATURE_WLAN_SCAN_PNO
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
VOS_STATUS WDA_ProcessRoamScanOffloadReq(tWDA_CbContext *pWDA,tSirRoamOffloadScanReq *pRoamOffloadScanReqParams);
+VOS_STATUS WDA_ProcessPERRoamScanOffloadReq(tWDA_CbContext *pWDA,
+ tSirPERRoamOffloadScanReq *pPERRoamOffloadScanReqParams);
void WDA_RoamOffloadScanReqCallback(WDI_Status status, void* pUserData);
+void WDA_PERRoamOffloadScanReqCallback(WDI_Status status, void* pUserData);
+void WDA_PERRoamTriggerScanReqCallback(WDI_Status status, void* pUserData);
void WDA_ConvertSirAuthToWDIAuth(WDI_AuthType *AuthType, v_U8_t csrAuthType);
void WDA_ConvertSirEncToWDIEnc(WDI_EdType *EncrType, v_U8_t csrEncrType);
#endif
@@ -14758,6 +14762,63 @@
}
#endif /* WLAN_FEATURE_RMC */
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+VOS_STATUS WDA_ProcessPERRoamScanTriggerReq(tWDA_CbContext *pWDA,
+ tPERRoamScanStart *pPERRoamTriggerScanReqParams)
+{
+ WDI_Status status;
+ tWDA_ReqParams *pWdaParams ;
+ WDI_PERRoamTriggerScanInfo *pwdiPERRoamTriggerScanInfo =
+ (WDI_PERRoamTriggerScanInfo *)vos_mem_malloc(
+ sizeof(WDI_PERRoamTriggerScanInfo));
+
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "------> %s " ,__func__);
+
+ if (NULL == pwdiPERRoamTriggerScanInfo)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if (NULL == pWdaParams)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(pwdiPERRoamTriggerScanInfo);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pwdiPERRoamTriggerScanInfo->roamScanReq =
+ pPERRoamTriggerScanReqParams->start;
+
+ /* Store Params pass it to WDI */
+ pWdaParams->wdaWdiApiMsgParam = (void *)pwdiPERRoamTriggerScanInfo;
+ pWdaParams->pWdaContext = pWDA;
+
+ /* Store param pointer as passed in by caller */
+ pWdaParams->wdaMsgParam = pPERRoamTriggerScanReqParams;
+ status = WDI_PERRoamScanTriggerReq(pwdiPERRoamTriggerScanInfo,
+ (WDI_PERRoamTriggerScanCb)WDA_PERRoamTriggerScanReqCallback,
+ pWdaParams);
+
+ if(IS_WDI_STATUS_FAILURE(status))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failure in Start Roam Candidate trigger Req WDI API" );
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+ vos_mem_free(pWdaParams->wdaMsgParam);
+ pWdaParams->wdaWdiApiMsgParam = NULL;
+ pWdaParams->wdaMsgParam = NULL;
+ }
+ return CONVERT_WDI2VOS_STATUS(status) ;
+}
+#endif
+
/*
* FUNCTION: WDA_ProcessSetSpoofMacAddrReq
*
@@ -15693,6 +15754,11 @@
WDA_ProcessRoamScanOffloadReq(pWDA, (tSirRoamOffloadScanReq *)pMsg->bodyptr);
break;
}
+ case WDA_PER_ROAM_SCAN_OFFLOAD_REQ:
+ {
+ WDA_ProcessPERRoamScanOffloadReq(pWDA, (tSirPERRoamOffloadScanReq *)pMsg->bodyptr);
+ break;
+ }
#endif
case WDA_SET_TX_PER_TRACKING_REQ:
{
@@ -15851,7 +15917,14 @@
break;
}
#endif /* WLAN_FEATURE_RMC */
-
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ case WDA_PER_ROAM_SCAN_TRIGGER_REQ:
+ {
+ WDA_ProcessPERRoamScanTriggerReq(pWDA,
+ (tPERRoamScanStart *)pMsg->bodyptr);
+ break;
+ }
+#endif
#ifdef FEATURE_WLAN_BATCH_SCAN
case WDA_SET_BATCH_SCAN_REQ:
{
@@ -18000,6 +18073,69 @@
}
}
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+VOS_STATUS WDA_ProcessPERRoamScanOffloadReq(tWDA_CbContext *pWDA,
+ tSirPERRoamOffloadScanReq *pPERRoamOffloadScanReqParams)
+{
+ WDI_Status status;
+ tWDA_ReqParams *pWdaParams ;
+ WDI_PERRoamOffloadScanInfo *pwdiPERRoamOffloadScanInfo;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "------> %s " ,__func__);
+
+ pwdiPERRoamOffloadScanInfo = (WDI_PERRoamOffloadScanInfo *)
+ vos_mem_malloc(sizeof(WDI_PERRoamOffloadScanInfo));
+ if (NULL == pwdiPERRoamOffloadScanInfo) {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if (NULL == pWdaParams) {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ vos_mem_free(pwdiPERRoamOffloadScanInfo);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pwdiPERRoamOffloadScanInfo->rateUpThreshold =
+ pPERRoamOffloadScanReqParams->rateUpThreshold;
+ pwdiPERRoamOffloadScanInfo->rateDownThreshold =
+ pPERRoamOffloadScanReqParams->rateDownThreshold;
+ pwdiPERRoamOffloadScanInfo->waitPeriodForNextPERScan =
+ pPERRoamOffloadScanReqParams->waitPeriodForNextPERScan;
+ pwdiPERRoamOffloadScanInfo->PERtimerThreshold =
+ pPERRoamOffloadScanReqParams->PERtimerThreshold;
+ pwdiPERRoamOffloadScanInfo->isPERRoamCCAEnabled =
+ pPERRoamOffloadScanReqParams->isPERRoamCCAEnabled;
+ pwdiPERRoamOffloadScanInfo->PERroamTriggerPercent =
+ pPERRoamOffloadScanReqParams->PERroamTriggerPercent;
+
+ /* Store Params pass it to WDI */
+ pWdaParams->wdaWdiApiMsgParam = (void *)pwdiPERRoamOffloadScanInfo;
+ pWdaParams->pWdaContext = pWDA;
+
+ /* Store param pointer as passed in by caller */
+ pWdaParams->wdaMsgParam = pPERRoamOffloadScanReqParams;
+ status = WDI_PERRoamScanOffloadReq(pwdiPERRoamOffloadScanInfo,
+ (WDI_PERRoamOffloadScanCb)WDA_PERRoamOffloadScanReqCallback,
+ pWdaParams);
+
+ if(IS_WDI_STATUS_FAILURE(status)) {
+ VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failure in Send config PER roam params");
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+ vos_mem_free(pWdaParams->wdaMsgParam);
+ vos_mem_free(pWdaParams);
+ }
+ return CONVERT_WDI2VOS_STATUS(status) ;
+}
+#endif
+
/*
* FUNCTION: WDA_ProcessRoamScanOffloadReq
* Request to WDI to set Roam Offload Scan
@@ -18395,6 +18531,75 @@
return ;
}
+
+void WDA_PERRoamTriggerScanReqCallback(WDI_Status status, void* pUserData)
+{
+ tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+ vos_msg_t vosMsg;
+ wpt_uint8 reason = 0;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+ if (NULL == pWdaParams) {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0) ;
+ return ;
+ }
+ if ( pWdaParams->wdaMsgParam != NULL)
+ vos_mem_free(pWdaParams->wdaMsgParam);
+
+ vos_mem_free(pWdaParams) ;
+ vosMsg.type = eWNI_SME_ROAM_SCAN_TRIGGER_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,
+ "%s: Failed to post the rsp to UMAC", __func__);
+ }
+
+ return ;
+}
+
+
+void WDA_PERRoamOffloadScanReqCallback(WDI_Status status, void* pUserData)
+{
+ tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+ vos_msg_t vosMsg;
+ wpt_uint8 reason = 0;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+ if (NULL == pWdaParams) {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ VOS_ASSERT(0) ;
+ return ;
+ }
+ if ( pWdaParams->wdaMsgParam != NULL)
+ vos_mem_free(pWdaParams->wdaMsgParam);
+
+ 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,
+ "%s: Failed to post the rsp to UMAC", __func__);
+ }
+
+ return ;
+}
#endif
/*