wlan: LFR2.0 Host Driver Changes
Master Gerrit for WLAN_FEATURE_ROAM_SCAN_OFFLOAD.
Includes all the Host Driver Changes.
Change-Id: I1c7adb30b24b49c6f2b5c3de3394831812b1c6d0
CRs-Fixed: 460568
diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c
index fde0fef..f186f20 100644
--- a/CORE/MAC/src/pe/lim/limApi.c
+++ b/CORE/MAC/src/pe/lim/limApi.c
@@ -119,6 +119,14 @@
palZeroMemory(pMac->hHdd, pMac->lim.gLimCachedScanHashTable,
sizeof(pMac->lim.gLimCachedScanHashTable));
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+
+ pMac->lim.gLimMlmLfrScanResultLength = 0;
+ pMac->lim.gLimSmeLfrScanResultLength = 0;
+
+ palZeroMemory(pMac->hHdd, pMac->lim.gLimCachedLfrScanHashTable,
+ sizeof(pMac->lim.gLimCachedLfrScanHashTable));
+#endif
pMac->lim.gLimBackgroundScanChannelId = 0;
pMac->lim.gLimBackgroundScanStarted = 0;
pMac->lim.gLimRestoreCBNumScanInterval = LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT;
@@ -642,6 +650,9 @@
// By default return unique scan results
pMac->lim.gLimReturnUniqueResults = true;
pMac->lim.gLimSmeScanResultLength = 0;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pMac->lim.gLimSmeLfrScanResultLength = 0;
+#endif
}
else
{
@@ -2154,6 +2165,12 @@
{
return eMGMT_DROP_NO_DROP;
}
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ else if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))
+ {
+ return eMGMT_DROP_NO_DROP;
+ }
+#endif
else if (WDA_IS_RX_IN_SCAN(pRxPacketInfo))
{
return eMGMT_DROP_SCAN_MODE_FRAME;
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 7b25aeb..f21a75e 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -549,7 +549,34 @@
limLog( pMac, LOG4, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"),
fc.protVer, fc.type, fc.subType, WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
-
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if ( WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))
+ {
+ limLog( pMac, LOG2, FL("Notify SME with candidate ind"));
+ //send a session 0 for now - TBD
+ limSendSmeCandidateFoundInd(pMac, 0);
+ goto end;
+ }
+ if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))
+ {
+ if (fc.subType == SIR_MAC_MGMT_BEACON)
+ {
+ limLog( pMac, LOG2, FL("Save this beacon in LFR cache"));
+ __limHandleBeacon(pMac, limMsg, NULL);
+ }
+ else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP)
+ {
+ limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache"));
+ limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo);
+ }
+ else
+ {
+ limLog( pMac, LOGE, FL("Wrong frame Type %d, Subtype %d for LFR"),
+ fc.type, fc.subType);
+ }
+ goto end;
+ }
+#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
#ifdef FEATURE_WLAN_CCX
if (fc.type == SIR_MAC_DATA_FRAME && isFrmFt)
{
@@ -808,6 +835,9 @@
} // switch (fc.type)
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+end:
+#endif
limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr) ;
return;
} /*** end limHandle80211Frames() ***/
diff --git a/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c b/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
index af77b3d..44f180a 100644
--- a/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
@@ -357,11 +357,19 @@
WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
limPrintMacAddr(pMac, pHdr->sa, LOG2);
- if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) ||
+ WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)))
{
- palFreeMemory(pMac->hHdd, pProbeRsp);
- return;
+#endif
+ if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+ {
+ palFreeMemory(pMac->hHdd, pProbeRsp);
+ return;
+ }
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
}
+#endif
// Validate IE information before processing Probe Response Frame
if (limValidateIEInformationInProbeRspFrame(pRxPacketInfo) != eSIR_SUCCESS)
{
@@ -376,9 +384,30 @@
* - eLIM_MLM_BSS_STARTED_STATE
* Hence, expect Probe Response only when
* 1. STA is in scan mode waiting for Beacon/Probe response
+ * 2. LFR logic in FW sends up candidate frames
*
* Ignore Probe Response frame in all other states
*/
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))
+ {
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ // Get pointer to Probe Response frame body
+ pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE)
+ {
+ limLog(pMac, LOG1, FL("Parse error ProbeResponse, length=%d\n"), frameLen);
+ palFreeMemory(pMac->hHdd, pProbeRsp);
+ return;
+ }
+ limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache"));
+ limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo,
+ eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE);
+ }
+ else
+#endif
if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
(pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct
(pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) )
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index b2885d0..8e06ea0 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -384,6 +384,9 @@
/// By default return unique scan results
pMac->lim.gLimReturnUniqueResults = true;
pMac->lim.gLimSmeScanResultLength = 0;
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ pMac->lim.gLimSmeLfrScanResultLength = 0;
+#endif
if (((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd)
{
@@ -1326,24 +1329,58 @@
tANI_U16 scanRspLen = sizeof(tSirSmeScanRsp);
pMac->lim.gLimRspReqd = false;
-
- if (pMac->lim.gLimSmeScanResultLength == 0)
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (pScanReq->returnFreshResults & SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS)
{
- limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pScanReq->sessionId, pScanReq->transactionId);
+ pMac->lim.gLimSmeLfrScanResultLength = pMac->lim.gLimMlmLfrScanResultLength;
+ if (pMac->lim.gLimSmeLfrScanResultLength == 0)
+ {
+ limSendSmeLfrScanRsp(pMac, scanRspLen,
+ eSIR_SME_SUCCESS,
+ pScanReq->sessionId,
+ pScanReq->transactionId);
+ }
+ else
+ {
+ scanRspLen = sizeof(tSirSmeScanRsp) +
+ pMac->lim.gLimSmeLfrScanResultLength -
+ sizeof(tSirBssDescription);
+ limSendSmeLfrScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS,
+ pScanReq->sessionId, pScanReq->transactionId);
+ }
}
else
{
- scanRspLen = sizeof(tSirSmeScanRsp) +
- pMac->lim.gLimSmeScanResultLength -
- sizeof(tSirBssDescription);
- limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pScanReq->sessionId, pScanReq->transactionId);
+#endif
+ if (pMac->lim.gLimSmeScanResultLength == 0)
+ {
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS,
+ pScanReq->sessionId, pScanReq->transactionId);
+ }
+ else
+ {
+ scanRspLen = sizeof(tSirSmeScanRsp) +
+ pMac->lim.gLimSmeScanResultLength -
+ sizeof(tSirBssDescription);
+ limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS,
+ pScanReq->sessionId, pScanReq->transactionId);
+ }
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
}
+#endif
if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS)
{
// Discard previously cached scan results
limReInitScanResults(pMac);
}
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_LFR_RESULTS)
+ {
+ // Discard previously cached scan results
+ limReInitLfrScanResults(pMac);
+ }
+#endif
} // if (pMac->lim.gLimRspReqd)
} // else ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ...
diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.c b/CORE/MAC/src/pe/lim/limScanResultUtils.c
index bd3edf8..4bc027e 100644
--- a/CORE/MAC/src/pe/lim/limScanResultUtils.c
+++ b/CORE/MAC/src/pe/lim/limScanResultUtils.c
@@ -396,12 +396,19 @@
* a SSID (if it is also set). Ignore the other BSS in that case.
*/
- if ((pMac->lim.gpLimMlmScanReq) && (((fScanning) && ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 )
- && (pMac->lim.gpLimMlmScanReq->numSsid) &&
- !limIsScanRequestedSSID(pMac, &pBPR->ssId))
- || (!fFound && (pMac->lim.gpLimMlmScanReq && pMac->lim.gpLimMlmScanReq->bssId) &&
- !palEqualMemory(pMac->hHdd, bssid, &pMac->lim.gpLimMlmScanReq->bssId, 6)))
- )
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)))
+ {
+#endif
+ if ((pMac->lim.gpLimMlmScanReq) &&
+ (((fScanning) &&
+ ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) &&
+ (pMac->lim.gpLimMlmScanReq->numSsid) &&
+ !limIsScanRequestedSSID(pMac, &pBPR->ssId)) ||
+ (!fFound && (pMac->lim.gpLimMlmScanReq &&
+ pMac->lim.gpLimMlmScanReq->bssId) &&
+ !palEqualMemory(pMac->hHdd, bssid,
+ &pMac->lim.gpLimMlmScanReq->bssId, 6))))
{
/**
* Received SSID does not match with
@@ -411,6 +418,9 @@
return;
}
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ }
+#endif
/* There is no point in caching & reporting the scan results for APs
* which are in the process of switching the channel. So, we are not
@@ -501,8 +511,38 @@
/**
* Depending on whether to store unique or all
* scan results, pass hash update/add parameter
+ * For LFR candidates just add them on it's own cache
*/
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))
+ {
+ limLog(pMac, LOG2, FL(" pHdr->addr1:%02x:%02x:%02x:%02x:%02x:%02x\n"),
+ pHdr->addr1[0],
+ pHdr->addr1[1],
+ pHdr->addr1[2],
+ pHdr->addr1[3],
+ pHdr->addr1[4],
+ pHdr->addr1[5]);
+ limLog(pMac, LOG2, FL(" pHdr->addr2:%02x:%02x:%02x:%02x:%02x:%02x\n"),
+ pHdr->addr2[0],
+ pHdr->addr2[1],
+ pHdr->addr2[2],
+ pHdr->addr2[3],
+ pHdr->addr2[4],
+ pHdr->addr2[5]);
+ limLog(pMac, LOG2, FL(" pHdr->addr3:%02x:%02x:%02x:%02x:%02x:%02x\n"),
+ pHdr->addr3[0],
+ pHdr->addr3[1],
+ pHdr->addr3[2],
+ pHdr->addr3[3],
+ pHdr->addr3[4],
+ pHdr->addr3[5]);
+ limLog( pMac, LOG2, FL("Save this entry in LFR cache"));
+ status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll);
+ }
+ else
+#endif
//If it is not scanning, only save unique results
if (pMac->lim.gLimReturnUniqueResults || (!fScanning))
{
@@ -814,6 +854,225 @@
} /****** end limDeleteHashEntry() ******/
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+/**
+ * limInitLfrHashTable()
+ *
+ *FUNCTION:
+ * This function is called upon receiving SME_START_REQ
+ * to initialize global cached Lfr scan hash table
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limInitLfrHashTable(tpAniSirGlobal pMac)
+{
+ tANI_U16 i;
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ pMac->lim.gLimCachedLfrScanHashTable[i] = NULL;
+} /****** end limInitLfrHashTable() ******/
+
+
+
+/**
+ * limLookupNaddLfrHashEntry()
+ *
+ *FUNCTION:
+ * This function is called upon receiving a Beacon or
+ * Probe Response frame during Lfr scan phase from FW to store
+ * received BSS description into Lfr scan result hash table.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBssDescr - Pointer to BSS description to be
+ * added to the Lfr scan result hash table.
+ * @param action - Indicates action to be performed
+ * when same BSS description is found. This is
+ * dependent on whether unique scan result to
+ * be stored or not.
+ *
+ * @return None
+ */
+
+eHalStatus
+limLookupNaddLfrHashEntry(tpAniSirGlobal pMac,
+ tLimScanResultNode *pBssDescr, tANI_U8 action,
+ tANI_U8 dontUpdateAll)
+{
+ tANI_U8 index, ssidLen = 0;
+ tLimScanResultNode *ptemp, *pprev;
+ tSirMacCapabilityInfo *pSirCap, *pSirCapTemp;
+ int idx, len;
+ tANI_U8 *pbIe;
+ tANI_S8 rssi = 0;
+
+ index = limScanHashFunction(pBssDescr->bssDescription.bssId);
+ ptemp = pMac->lim.gLimCachedLfrScanHashTable[index];
+
+ //ieFields start with TLV of SSID IE
+ ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
+ pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
+
+ for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
+ {
+ //For infrastructure, check BSSID and SSID. For IBSS, check more
+ pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo;
+ if((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first
+ (palEqualMemory( pMac->hHdd,(tANI_U8 *) pBssDescr->bssDescription.bssId,
+ (tANI_U8 *) ptemp->bssDescription.bssId,
+ sizeof(tSirMacAddr))) && //matching BSSID
+ (pBssDescr->bssDescription.channelId ==
+ ptemp->bssDescription.channelId) &&
+ palEqualMemory( pMac->hHdd,((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
+ ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
+ (tANI_U8) (ssidLen + 1)) &&
+ ((pSirCapTemp->ess) || //we are done for infrastructure
+ //For IBSS, nwType and channelId
+ (((pBssDescr->bssDescription.nwType ==
+ ptemp->bssDescription.nwType) &&
+ (pBssDescr->bssDescription.channelId ==
+ ptemp->bssDescription.channelId))))
+ )
+ {
+ // Found the same BSS description
+ if (action == LIM_HASH_UPDATE)
+ {
+ if(dontUpdateAll)
+ {
+ rssi = ptemp->bssDescription.rssi;
+ }
+
+ if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp)
+ {
+ //We get a different, save the old frame WSC IE if it is there
+ idx = 0;
+ len = ptemp->bssDescription.length - sizeof(tSirBssDescription) +
+ sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
+ pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields;
+ //Save WPS IE if it exists
+ pBssDescr->bssDescription.WscIeLen = 0;
+ while(idx < len)
+ {
+ if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
+ (0x00 == pbIe[2]) && (0x50 == pbIe[3]) &&
+ (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
+ {
+ //Found it
+ if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
+ {
+ palCopyMemory(pMac->hHdd, pBssDescr->bssDescription.WscIeProbeRsp,
+ pbIe, pbIe[1] + 2);
+ pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2;
+ }
+ break;
+ }
+ idx += pbIe[1] + 2;
+ pbIe += pbIe[1] + 2;
+ }
+ }
+
+
+ if(NULL != pMac->lim.gpLimMlmScanReq)
+ {
+ if((pMac->lim.gpLimMlmScanReq->numSsid)&&
+ ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *)
+ &pBssDescr->bssDescription.ieFields + 1))))
+ return eHAL_STATUS_FAILURE;
+ }
+
+ // Delete this entry
+ if (ptemp == pMac->lim.gLimCachedLfrScanHashTable[index])
+ pprev = pMac->lim.gLimCachedLfrScanHashTable[index] = ptemp->next;
+ else
+ pprev->next = ptemp->next;
+
+ pMac->lim.gLimMlmLfrScanResultLength -=
+ ptemp->bssDescription.length + sizeof(tANI_U16);
+
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) ptemp);
+ }
+ break;
+ }
+ }
+
+ //for now, only rssi, we can add more if needed
+ if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi)
+ {
+ pBssDescr->bssDescription.rssi = rssi;
+ }
+
+ // Add this BSS description at same index
+ if (pprev == pMac->lim.gLimCachedLfrScanHashTable[index])
+ {
+ pBssDescr->next = pMac->lim.gLimCachedLfrScanHashTable[index];
+ pMac->lim.gLimCachedLfrScanHashTable[index] = pBssDescr;
+ }
+ else
+ {
+ pBssDescr->next = pprev->next;
+ pprev->next = pBssDescr;
+ }
+ pMac->lim.gLimMlmLfrScanResultLength +=
+ pBssDescr->bssDescription.length + sizeof(tANI_U16);
+
+ PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"),
+ pBssDescr->bssDescription.length,
+ pMac->lim.gLimMlmLfrScanResultLength);
+ limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);)
+
+ //
+ // TODO: IF applicable, do we need to send:
+ // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF
+ // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP
+ //
+ return eHAL_STATUS_SUCCESS;
+}
+
+
+
+/**
+ * limDeleteLfrHashEntry()
+ *
+ *FUNCTION:
+ * This function is called upon to delete
+ * a BSS description from LFR scan result hash table.
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * Yet to find the utility of the function
+ *
+ * @param pBssDescr - Pointer to BSS description to be
+ * deleted from the LFR scan result hash table.
+ *
+ * @return None
+ */
+
+void limDeleteLfrHashEntry(tLimScanResultNode *pBssDescr)
+{
+} /****** end limDeleteLfrHashEntry() ******/
+
+#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/**
* limCopyScanResult()
@@ -938,3 +1197,82 @@
pMac->lim.gLimMlmScanResultLength = 0;
} /****** end limReInitScanResults() ******/
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+/**
+ * limDeleteCachedLfrScanResults()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeMessages() upon receiving
+ * SME_SCAN_REQ with flush scan result flag set for LFR.
+ *
+ *LOGIC:
+ * This function traverses the scan list stored in lfr scan hash
+ * table and deletes the entries if any
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limDeleteCachedLfrScanResults(tpAniSirGlobal pMac)
+{
+ tLimScanResultNode *pNode, *pNextNode;
+ tANI_U16 i;
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ {
+ if ((pNode = pMac->lim.gLimCachedLfrScanHashTable[i]) != NULL)
+ {
+ while (pNode)
+ {
+ pNextNode = pNode->next;
+
+ // Delete the current node
+ palFreeMemory( pMac->hHdd, (tANI_U8 *) pNode);
+
+ pNode = pNextNode;
+ }
+ }
+ }
+
+ pMac->lim.gLimSmeLfrScanResultLength = 0;
+} /****** end limDeleteCachedLfrScanResults() ******/
+
+
+
+/**
+ * limReInitLfrScanResults()
+ *
+ *FUNCTION:
+ * This function is called delete exisiting scan results
+ * and initialize the lfr scan hash table
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+limReInitLfrScanResults(tpAniSirGlobal pMac)
+{
+ limDeleteCachedLfrScanResults(pMac);
+ limInitLfrHashTable(pMac);
+
+ // !!LAC - need to clear out the global scan result length
+ // since the list was just purged from the hash table.
+ pMac->lim.gLimMlmLfrScanResultLength = 0;
+
+} /****** end limReInitLfrScanResults() ******/
+#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.h b/CORE/MAC/src/pe/lim/limScanResultUtils.h
index 9ad88bf..fc17886 100644
--- a/CORE/MAC/src/pe/lim/limScanResultUtils.h
+++ b/CORE/MAC/src/pe/lim/limScanResultUtils.h
@@ -39,6 +39,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
+
/*
* Airgo Networks, Inc proprietary. All rights reserved.
* This file limScanResultUtils.h contains the utility definitions
@@ -65,6 +66,14 @@
void limRestorePreScanState(tpAniSirGlobal);
void limCopyScanResult(tpAniSirGlobal, tANI_U8 *);
void limReInitScanResults(tpAniSirGlobal);
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+void limInitLfrHashTable(tpAniSirGlobal);
+eHalStatus
+ limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8);
+void limDeleteLfrHashEntry(tLimScanResultNode *);
+void limDeleteCachedLfrScanResults(tpAniSirGlobal);
+void limReInitLfrScanResults(tpAniSirGlobal);
+#endif
tANI_U32 limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal);
void limCheckAndAddBssDescription(tpAniSirGlobal, tpSirProbeRespBeacon, tANI_U8 *, tANI_BOOLEAN, tANI_U8);
#if defined WLAN_FEATURE_VOWIFI
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index c907ef7..d91c595 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -772,6 +772,169 @@
} /*** end limSendSmeScanRsp() ***/
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+/**
+ * limSendSmeLfrScanRsp()
+ *
+ *FUNCTION:
+ * This function is called by limProcessSmeReqMessages() to send
+ * eWNI_SME_SCAN_RSP message to applications above MAC Software
+ * only for sending up the roam candidates.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param length Indicates length of message
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_SCAN_REQ message
+ *
+ * @return None
+ */
+
+void
+limSendSmeLfrScanRsp(tpAniSirGlobal pMac, tANI_U16 length,
+ tSirResultCodes resultCode,tANI_U8 smesessionId,tANI_U16 smetranscationId)
+{
+ tSirMsgQ mmhMsg;
+ tpSirSmeScanRsp pSirSmeScanRsp=NULL;
+ tLimScanResultNode *ptemp = NULL;
+ tANI_U16 msgLen, allocLength, curMsgLen = 0;
+ tANI_U16 i, bssCount;
+ tANI_U8 *pbBuf;
+ tSirBssDescription *pDesc;
+
+ PELOG1(limLog(pMac, LOG1,
+ FL("Sending message SME_SCAN_RSP with length=%d reasonCode %s\n"),
+ length, limResultCodeStr(resultCode));)
+
+ if (resultCode != eSIR_SME_SUCCESS)
+ {
+ limPostSmeScanRspMessage(pMac, length, resultCode,smesessionId,smetranscationId);
+ return;
+ }
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ i = 0;
+ bssCount = 0;
+ msgLen = 0;
+ allocLength = LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED * LIM_SIZE_OF_EACH_BSS;
+ if ( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **)&pSirSmeScanRsp, allocLength))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_SCAN_RSP\n"));
+
+ return;
+ }
+ for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+ {
+ //when ptemp is not NULL it is a left over
+ ptemp = pMac->lim.gLimCachedLfrScanHashTable[i];
+ while(ptemp)
+ {
+ pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen;
+ if(0 == bssCount)
+ {
+ msgLen = sizeof(tSirSmeScanRsp) -
+ sizeof(tSirBssDescription) +
+ ptemp->bssDescription.length +
+ sizeof(ptemp->bssDescription.length);
+ pDesc = pSirSmeScanRsp->bssDescription;
+ }
+ else
+ {
+ msgLen += ptemp->bssDescription.length +
+ sizeof(ptemp->bssDescription.length);
+ pDesc = (tSirBssDescription *)pbBuf;
+ }
+ if ( (allocLength < msgLen) ||
+ (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) )
+ {
+ pSirSmeScanRsp->statusCode =
+ eSIR_SME_MORE_SCAN_RESULTS_FOLLOW;
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->length = curMsgLen;
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
+ (void **)&pSirSmeScanRsp,
+ allocLength))
+ {
+ // Log error
+ limLog(pMac, LOGP,
+ FL("call to palAllocateMemory failed for eWNI_SME_SCAN_RSP\n"));
+ return;
+ }
+ msgLen = sizeof(tSirSmeScanRsp) -
+ sizeof(tSirBssDescription) +
+ ptemp->bssDescription.length +
+ sizeof(ptemp->bssDescription.length);
+ pDesc = pSirSmeScanRsp->bssDescription;
+ bssCount = 1;
+ }
+ curMsgLen = msgLen;
+
+ PELOG2(limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d\n"),
+ msgLen, ptemp->bssDescription.length);)
+ pDesc->length
+ = ptemp->bssDescription.length;
+ palCopyMemory( pMac->hHdd, (tANI_U8 *) &pDesc->bssId,
+ (tANI_U8 *) &ptemp->bssDescription.bssId,
+ ptemp->bssDescription.length);
+
+ PELOG2(limLog(pMac, LOG2, FL("BssId "));
+ limPrintMacAddr(pMac, ptemp->bssDescription.bssId, LOG2);)
+
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetranscationId;
+
+ ptemp = ptemp->next;
+ } //while(ptemp)
+ } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
+
+ if (0 == bssCount)
+ {
+ limPostSmeScanRspMessage(pMac, length, resultCode, smesessionId, smetranscationId);
+ if (NULL != pSirSmeScanRsp)
+ {
+ palFreeMemory( pMac->hHdd, pSirSmeScanRsp);
+ pSirSmeScanRsp = NULL;
+ }
+ }
+ else
+ {
+ // send last message
+ pSirSmeScanRsp->statusCode = eSIR_SME_SUCCESS;
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->length = curMsgLen;
+
+ /* Update SME session Id and SME transcation Id */
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetranscationId;
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type));
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+ PELOG2(limLog(pMac, LOG2, FL("statusCode : eSIR_SME_SUCCESS\n"));)
+ }
+
+ return;
+
+} /*** end limSendSmeLfrScanRsp() ***/
+#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
/**
* limPostSmeScanRspMessage()
@@ -2525,3 +2688,46 @@
return;
}
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+/** -----------------------------------------------------------------
+ \brief limSendSmeCandidateFoundInd() - sends
+ eWNI_SME_CANDIDATE_FOUND_IND
+
+ After receiving candidate found indication frame from FW, this
+ function sends a eWNI_SME_CANDIDATE_FOUND_IND to SME to notify
+ roam candidate(s) are available.
+
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+limSendSmeCandidateFoundInd(tpAniSirGlobal pMac, tANI_U8 sessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd;
+
+ if ( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd,
+ (void **)&pSirSmeCandidateFoundInd,
+ sizeof(tSirSmeCandidateFoundInd)))
+ {
+ limLog(pMac, LOGP, FL("palAllocateMemory failed for eWNI_SME_CANDIDATE_FOUND_IND\n"));
+ return;
+ }
+
+ pSirSmeCandidateFoundInd->messageType = eWNI_SME_CANDIDATE_FOUND_IND;
+ pSirSmeCandidateFoundInd->length = sizeof(tSirSmeDisassocInd);
+
+ pSirSmeCandidateFoundInd->sessionId = sessionId;
+
+
+ limLog( pMac, LOGE, FL("posting candidate ind to SME"));
+ mmhMsg.type = eWNI_SME_CANDIDATE_FOUND_IND;
+ mmhMsg.bodyptr = pSirSmeCandidateFoundInd;
+ mmhMsg.bodyval = 0;
+
+ limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
+
+} /*** end limSendSmeCandidateFoundInd() ***/
+#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
index a2e5c47..3ef5351 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h
@@ -63,6 +63,9 @@
void limSendSmeRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U8 , tANI_U16);
void limSendSmeStartBssRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16);
void limSendSmeScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16);
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+void limSendSmeLfrScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16);
+#endif
void limPostSmeScanRspMessage(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8,tANI_U16);
void limSendSmeAuthRsp(tpAniSirGlobal, tSirResultCodes,
tSirMacAddr, tAniAuthType, tANI_U16,tpPESession,tANI_U8,tANI_U16);
@@ -72,8 +75,9 @@
void limSendSmeDeauthNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16, tANI_U8, tANI_U16);
void limSendSmeDisassocInd(tpAniSirGlobal, tpDphHashNode,tpPESession);
void limSendSmeDeauthInd(tpAniSirGlobal, tpDphHashNode, tpPESession psessionEntry);
-
-
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+void limSendSmeCandidateFoundInd(tpAniSirGlobal, tANI_U8);
+#endif
void limSendSmeWmStatusChangeNtf(tpAniSirGlobal, tSirSmeStatusChangeCode, tANI_U32 *, tANI_U16, tANI_U8);
void limSendSmeSetContextRsp(tpAniSirGlobal,
diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c
index 3c0b34b..b72bbf2 100644
--- a/CORE/MAC/src/pe/lim/limUtils.c
+++ b/CORE/MAC/src/pe/lim/limUtils.c
@@ -80,6 +80,11 @@
static const tANI_U8 abChannel[]= {36,40,44,48,52,56,60,64,100,104,108,112,116,
120,124,128,132,136,140,149,153,157,161,165};
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+static const tANI_U8 aUnsortedChannelList[]= {52,56,60,64,100,104,108,112,116,
+ 120,124,128,132,136,140,36,40,44,48,149,153,157,161,165};
+#endif
+
//#define LIM_MAX_ACTIVE_SESSIONS 3 //defined temporarily for BT-AMP SUPPORT
#define SUCCESS 1 //defined temporarily for BT-AMP
@@ -898,6 +903,13 @@
/// Initialize scan result hash table
limReInitScanResults(pMac); //sep26th review
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ /// Initialize lfr scan result hash table
+ // Could there be a problem in multisession with SAP/P2P GO, when in the
+ // middle of FW bg scan, SAP started; Again that could be a problem even on
+ // infra + SAP/P2P GO too - TBD
+ limReInitLfrScanResults(pMac);
+#endif
/// Initialize number of pre-auth contexts
pMac->lim.gLimNumPreAuthContexts = 0;
@@ -1088,6 +1100,10 @@
/// Cleanup cached scan list
limReInitScanResults(pMac);
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ /// Cleanup cached scan list
+ limReInitLfrScanResults(pMac);
+#endif
} /*** end limCleanupMlm() ***/
@@ -7309,6 +7325,11 @@
tANI_U8 limUnmapChannel(tANI_U8 mapChannel)
{
if( mapChannel > 0 && mapChannel < 25 )
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+ if (IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE)
+ return aUnsortedChannelList[mapChannel -1];
+ else
+#endif
return abChannel[mapChannel -1];
else
return 0;