Merge "SCAN-OFFLOAD: Changes required to process the scan results."
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 3e75f60..64aa6b2 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4204,4 +4204,25 @@
       up to uIEFieldLen (can be 0)
       -----------------------------*/
 } tSirScanOffloadReq, *tpSirScanOffloadReq;
+
+typedef enum sSirScanEventType {
+    SCAN_EVENT_STARTED=0x1,          /* Scan command accepted by FW */
+    SCAN_EVENT_COMPLETED=0x2,        /* Scan has been completed by FW */
+    SCAN_EVENT_BSS_CHANNEL=0x4,      /* FW is going to move to HOME channel */
+    SCAN_EVENT_FOREIGN_CHANNEL = 0x8,/* FW is going to move to FORIEGN channel */
+    SCAN_EVENT_DEQUEUED=0x10,       /* scan request got dequeued */
+    SCAN_EVENT_PREEMPTED=0x20,      /* preempted by other high priority scan */
+    SCAN_EVENT_START_FAILED=0x40,   /* scan start failed */
+    SCAN_EVENT_RESTARTED=0x80,      /*scan restarted*/
+    SCAN_EVENT_MAX=0x8000
+} tSirScanEventType;
+
+typedef struct sSirScanOffloadEvent{
+    tSirScanEventType event;
+    tSirResultCodes reasonCode;
+    tANI_U32 chanFreq;
+    tANI_U32 requestor;
+    tANI_U32 scanId;
+} tSirScanOffloadEvent, *tpSirScanOffloadEvent;
+
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c b/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c
index bebfa11..45a2339 100644
--- a/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c
@@ -102,9 +102,11 @@
            WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
     limPrintMacAddr(pMac, pHdr->sa, LOG2);)
 
-    if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
-        return;
-
+    if (!pMac->fScanOffload)
+    {
+        if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+            return;
+    }
 
     /**
      * Expect Beacon only when
@@ -116,7 +118,9 @@
     if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
         (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ||
         (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) ||
-        (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE))
+        (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)
+        || pMac->fScanOffload
+        )
     {
         if(eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd, 
                                                     (void **)&pBeacon, sizeof(tSchBeaconStruct)))
@@ -153,6 +157,12 @@
         MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, pBeacon->timeStamp[0]);)
         MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, pBeacon->timeStamp[1]);)
 
+        if (pMac->fScanOffload)
+        {
+            limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo,
+                    eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE);
+
+        }
 
         if ((pMac->lim.gLimMlmState  == eLIM_MLM_WT_PROBE_RESP_STATE) ||
             (pMac->lim.gLimMlmState  == eLIM_MLM_PASSIVE_SCAN_STATE))
@@ -169,7 +179,7 @@
         else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)
         {
         }
-        else
+        else if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)
         {
             if( psessionEntry->beacon != NULL )
             {
@@ -249,9 +259,11 @@
            WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
     limPrintMacAddr(pMac, pHdr->sa, LOG2);
 
-    if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
-        return;
-
+    if (!pMac->fScanOffload)
+    {
+        if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+            return;
+    }
 
     /**
      * No session has been established. Expect Beacon only when
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 235bb3e..22a5661 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -670,11 +670,13 @@
         return;
     }
 
-
-    if (limIsSystemInScanState(pMac))
+    if (!pMac->fScanOffload)
     {
-        limHandleFramesInScanState(pMac, limMsg, pRxPacketInfo, pDeferMsg, psessionEntry);
-        return;
+        if (limIsSystemInScanState(pMac))
+        {
+            limHandleFramesInScanState(pMac, limMsg, pRxPacketInfo, pDeferMsg, psessionEntry);
+            return;
+        }
     }
 
 /* Chance of crashing : to be done BT-AMP ........happens when broadcast probe req is received */
@@ -1931,6 +1933,11 @@
             break;
         }
 #endif
+
+    case WDA_RX_SCAN_EVENT:
+        limProcessRxScanEvent(pMac, limMsg->bodyptr);
+        break;
+
     default:
         vos_mem_free((v_VOID_t*)limMsg->bodyptr);
         limMsg->bodyptr = NULL;
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index 0bdcdec..5469339 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -39,8 +39,8 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+
 /*
- * Airgo Networks, Inc proprietary. All rights reserved.
  * This file limProcessMlmRspMessages.cc contains the code
  * for processing response messages from MLM state machine.
  * Author:        Chandra Modumudi
@@ -4820,3 +4820,55 @@
     schProcessPreBeaconInd(pMac, &limMsg);
     return;
 }
+
+void limSendScanOffloadComplete(tpAniSirGlobal pMac,
+                                tSirResultCodes reasonCode)
+{
+    tANI_U16 scanRspLen = 0;
+
+    pMac->lim.gLimSmeScanResultLength +=
+        pMac->lim.gLimMlmScanResultLength;
+    if ((pMac->lim.gLimRspReqd) ||
+            pMac->lim.gLimReportBackgroundScanResults)
+    {
+        pMac->lim.gLimRspReqd = false;
+        if ((reasonCode == eSIR_SME_SUCCESS) ||
+                pMac->lim.gLimSmeScanResultLength) {
+            scanRspLen = sizeof(tSirSmeScanRsp) +
+                pMac->lim.gLimSmeScanResultLength -
+                sizeof(tSirBssDescription);
+        }
+        else
+            scanRspLen = sizeof(tSirSmeScanRsp);
+
+        limSendSmeScanRsp(pMac, scanRspLen, reasonCode,
+                pMac->lim.gSmeSessionId,
+                pMac->lim.gTransactionId);
+    }
+}
+
+
+void limProcessRxScanEvent(tpAniSirGlobal pMac, void *buf)
+{
+    tSirScanOffloadEvent *pScanEvent = (tSirScanOffloadEvent *) buf;
+
+    VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+            "scan_id = %lu", pScanEvent->scanId);
+
+    switch (pScanEvent->event)
+    {
+        case SCAN_EVENT_STARTED:
+            break;
+        case SCAN_EVENT_START_FAILED:
+        case SCAN_EVENT_COMPLETED:
+            limSendScanOffloadComplete(pMac, pScanEvent->reasonCode);
+            break;
+        case SCAN_EVENT_BSS_CHANNEL:
+        case SCAN_EVENT_FOREIGN_CHANNEL:
+        case SCAN_EVENT_DEQUEUED:
+        case SCAN_EVENT_PREEMPTED:
+        default:
+            VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG,
+                    "Received unhandled scan event %lu", pScanEvent->event);
+    }
+}
diff --git a/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c b/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
index ab82179..f4756a9 100644
--- a/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c
@@ -135,11 +135,15 @@
              WDA_GET_RX_MPDU_LEN(pRxPacketInfo));
     limPrintMacAddr(pMac, pHdr->sa, LOG2);)
 
-   if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+   if (!pMac->fScanOffload)
    {
-       palFreeMemory(pMac->hHdd, pProbeRsp);    
-       return;
+       if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+       {
+           palFreeMemory(pMac->hHdd, pProbeRsp);
+           return;
+       }
    }
+
    // Validate IE information before processing Probe Response Frame
    if (limValidateIEInformationInProbeRspFrame(pRxPacketInfo) != eSIR_SUCCESS)
    {
@@ -165,14 +169,16 @@
      *
      * Ignore Probe Response frame in all other states
      */
-        // TO SUPPORT BT-AMP
+        /*  */
+   // TO SUPPORT BT-AMP
     if (((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||   //mlm state check should be global - 18th oct
         (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ||     //mlm state check should be global - 18th oct
         (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) ||            //mlm state check should be global - 18th oct 
         (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) ||
         (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )||
         ((GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) &&
-         (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)))
+        (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)) ||
+        pMac->fScanOffload)
     {
         frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
 
@@ -196,7 +202,14 @@
             palFreeMemory(pMac->hHdd, pProbeRsp);
             return;
         }
-                                                                            //To Support BT-AMP                    
+
+        if (pMac->fScanOffload)
+        {
+            limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo,
+                    eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE);
+        }
+
+        //To Support BT-AMP
         if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||    //mlm state check should be global - 18th oct
             (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE))
             limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, 
@@ -370,11 +383,14 @@
           WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)))
     {
 #endif
-       if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
-       {
-          palFreeMemory(pMac->hHdd, pProbeRsp);
-          return;
-       }
+        if (!pMac->fScanOffload)
+        {
+            if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS)
+            {
+                palFreeMemory(pMac->hHdd, pProbeRsp);
+                return;
+            }
+        }
 #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
     }
 #endif
@@ -424,7 +440,25 @@
     }
     else
 #endif
-    if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+    if (pMac->fScanOffload)
+    {
+        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;
+        }
+        limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo,
+                eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE);
+    }
+    else 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/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index 8f86cf9..57b170c 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -1109,5 +1109,7 @@
     void * cbackDataPtr;
 } tSetLinkCbackParams;
 #endif
+
+void limProcessRxScanEvent(tpAniSirGlobal mac, void *buf);
 #endif /* __LIM_TYPES_H */