prima: release v3.2.1.6

git://codeaurora.org/external/wlan/prima.git

d29fa4c wlan: Release 3.2.1.6
b074dbb Fix for setting properly the AC mask for TxConn
a66ea5c Stop scan refresh timer while resetting report scan state
5eb765b Set RoamRssiDiff=0 to disable roam hysteresis.
632cb65 Update the Channel Change Reason
efaed58 Inform TL about pending packets whenever Queue is filling up
4f74d03 Enable gEnableBypass11d to reduce the connection time.
9f918a0 Remove gNeighborScanChannelList from cfg.ini
2da87e7 Preferentially scan occupied channels (learned from previous scans).
b340701 Update template cfg.ini for LFR
e10a7e3 Fix for passing proper reason code to supplicant

Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h
index a707ce1..8b1797e 100644
--- a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1002,7 +1002,7 @@
 #define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT   (120)
 
 #define CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME                      "gNeighborScanChannelList"
-#define CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT                   "1,6"
+#define CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT                   ""
 
 #define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME                  "gNeighborScanChannelMinTime"
 #define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN                   (10)   
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
index 11c8d86..1c3682a 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
@@ -680,13 +680,7 @@
             /* To avoid wpa_supplicant sending "HANGED" CMD to ICS UI */
             if( eCSR_ROAM_LOSTLINK == roamStatus )
             {
-                /* TODO: Need to pass proper reason code
-                   currently we are passing only one reason code.
-                   Currently we are passing WLAN_REASON_DISASSOC_STA_HAS_LEFT
-                   rather than WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
-                   to avoid the supplicant fast reconnect */
-
-                cfg80211_disconnected(dev, WLAN_REASON_DISASSOC_STA_HAS_LEFT, NULL, 0, GFP_KERNEL);
+                cfg80211_disconnected(dev, pRoamInfo->reasonCode, NULL, 0, GFP_KERNEL);
             }
             else
             {
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c
index f2d8f16..17490ce 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -543,7 +543,14 @@
 #endif // HDD_WMM_DEBUG
 
    spin_lock(&pAdapter->wmm_tx_queue[ac].lock);
-
+   /*For every increment of 10 pkts in the queue, we inform TL about pending pkts.
+    * We check for +1 in the logic,to take care of Zero count which 
+    * occurs very frequently in low traffic cases */
+   if((pAdapter->wmm_tx_queue[ac].count + 1) % 10 == 0)
+   {
+           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s:Queue is Filling up.Inform TL again about pending packets", __FUNCTION__);
+           WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pHddStaCtx->conn_info.staId[0], ac );
+   }
    //If we have already reached the max queue size, disable the TX queue
    if ( pAdapter->wmm_tx_queue[ac].count == pAdapter->wmm_tx_queue[ac].max_size)
    {
diff --git a/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h b/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h
index dac79c6f..d779d83 100644
--- a/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h
+++ b/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h
@@ -39,9 +39,9 @@
 #define QWLAN_VERSION_MAJOR            3
 #define QWLAN_VERSION_MINOR            2
 #define QWLAN_VERSION_PATCH            1
-#define QWLAN_VERSION_EXTRA            "b"
-#define QWLAN_VERSION_BUILD            5
+#define QWLAN_VERSION_EXTRA            ""
+#define QWLAN_VERSION_BUILD            6
 
-#define QWLAN_VERSIONSTR               "3.2.1.5b"
+#define QWLAN_VERSIONSTR               "3.2.1.6"
 
 #endif /* QWLAN_VERSION_H */
diff --git a/drivers/staging/prima/CORE/MAC/inc/sirApi.h b/drivers/staging/prima/CORE/MAC/inc/sirApi.h
index 997c99c..1187fc1 100644
--- a/drivers/staging/prima/CORE/MAC/inc/sirApi.h
+++ b/drivers/staging/prima/CORE/MAC/inc/sirApi.h
@@ -1934,6 +1934,7 @@
 #ifdef WLAN_SOFTAP_FEATURE
     tANI_U16            staId;
 #endif
+    tANI_U32            reasonCode;
 } tSirSmeDisassocInd, *tpSirSmeDisassocInd;
 
 /// Definition for Disassociation confirm
@@ -1996,6 +1997,7 @@
 #ifdef WLAN_SOFTAP_FEATURE
     tANI_U16            staId;
 #endif
+    tANI_U32            reasonCode;
 } tSirSmeDeauthInd, *tpSirSmeDeauthInd;
 
 /// Definition for Deauthentication confirm
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index d7050dd..f2e1330 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -1150,6 +1150,7 @@
             /* Update SME session Id and Transaction Id */
             pSirSmeDisassocInd->sessionId = smesessionId;
             pSirSmeDisassocInd->transactionId = smetransactionId;
+            pSirSmeDisassocInd->reasonCode = reasonCode;
 #endif
             pBuf = (tANI_U8 *) &pSirSmeDisassocInd->statusCode;
 
@@ -1265,6 +1266,7 @@
     pSirSmeDisassocInd->sessionId     =  psessionEntry->smeSessionId;
     pSirSmeDisassocInd->transactionId =  psessionEntry->transactionId;
     pSirSmeDisassocInd->statusCode    =  pStaDs->mlmStaContext.disassocReason;
+    pSirSmeDisassocInd->reasonCode    =  pStaDs->mlmStaContext.disassocReason;
     
     palCopyMemory( pMac->hHdd, pSirSmeDisassocInd->bssId , psessionEntry->bssId , sizeof(tSirMacAddr));
  
@@ -1343,6 +1345,7 @@
     palCopyMemory( pMac->hHdd, pSirSmeDeauthInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
     //peerMacAddr
     palCopyMemory( pMac->hHdd, pSirSmeDeauthInd->peerMacAddr, pStaDs->staAddr, sizeof(tSirMacAddr));
+    pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
 #else
 
     //sessionId
@@ -1497,6 +1500,7 @@
 #else
             pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
             pSirSmeDeauthInd->length      = sizeof(tSirSmeDeauthInd);
+            pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
 #endif
 
             // sessionId
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c
index 42afbe1..a295b29 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c
@@ -5553,6 +5553,9 @@
                                  "nel Offset: %d, Channel Width: %d\n" ),
                 pHTInfo->primaryChannel, secondaryChnlOffset,
                 psessionEntry->htRecommendedTxWidthSet );
+        psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION;
+        pMac->lim.gpchangeChannelCallback = NULL;
+        pMac->lim.gpchangeChannelData = NULL;
 
 #if defined WLAN_FEATURE_VOWIFI  
         limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel,
diff --git a/drivers/staging/prima/CORE/SME/inc/csrInternal.h b/drivers/staging/prima/CORE/SME/inc/csrInternal.h
index 504f9dc..1e7cfd8 100644
--- a/drivers/staging/prima/CORE/SME/inc/csrInternal.h
+++ b/drivers/staging/prima/CORE/SME/inc/csrInternal.h
@@ -76,6 +76,11 @@
      NULL \
 )
 
+//Support for "Fast roaming" (i.e., CCX, LFR, or 802.11r.)
+#define CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15  
+#define CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE 3
+#define CSR_BG_SCAN_CHANNEL_LIST_LEN (CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN + CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE)
+
 
 
 typedef enum
@@ -682,6 +687,7 @@
 #ifdef WLAN_AP_STA_CONCURRENCY
     tDblLinkList scanCmdPendingList;
 #endif    
+    tCsrChannel occupiedChannels;   //This includes all channels on which candidate APs are found
 }tCsrScanStruct;
 
 
@@ -1218,5 +1224,8 @@
 #ifdef FEATURE_WLAN_LFR
 //Returns whether "Legacy Fast Roaming" is enabled...or not
 tANI_BOOLEAN csrRoamIsFastRoamEnabled(tpAniSirGlobal pMac);
+tANI_BOOLEAN csrIsChannelPresentInList( tANI_U8 *pChannelList, int  numChannels, tANI_U8   channel );
+VOS_STATUS csrAddToChannelListFront( tANI_U8 *pChannelList, int  numChannels, tANI_U8   channel );
+tANI_BOOLEAN csrNeighborRoamIsSsidCandidateMatch( tpAniSirGlobal pMac, tDot11fBeaconIEs *pIes);
 #endif
 
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c b/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c
index fded37b..b997d5be 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c
@@ -8973,17 +8973,20 @@
         result = eCSR_ROAM_RESULT_DISASSOC_IND;
         pDisassocIndMsg = (tSirSmeDisassocInd *)pSirMsg;
         pSession->roamingStatusCode = pDisassocIndMsg->statusCode;
+        pSession->joinFailStatusCode.reasonCode = pDisassocIndMsg->reasonCode;
     }
     else if ( eWNI_SME_DEAUTH_IND == type )
     {
         result = eCSR_ROAM_RESULT_DEAUTH_IND;
         pDeauthIndMsg = (tSirSmeDeauthInd *)pSirMsg;
         pSession->roamingStatusCode = pDeauthIndMsg->statusCode;
+        pSession->joinFailStatusCode.reasonCode = pDeauthIndMsg->reasonCode;
     }
     else
     {
         smsLog(pMac, LOGW, FL("gets an unknown type (%d)\n"), type);
         result = eCSR_ROAM_RESULT_NONE;
+        pSession->joinFailStatusCode.reasonCode = 1;
     }
     
     // call profile lost link routine here
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c b/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c
index d93d920..355dc51 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c
@@ -1707,6 +1707,35 @@
 }
 
 
+#ifdef FEATURE_WLAN_LFR 
+//Add the channel to the occupiedChannels array
+static void csrScanAddToOccupiedChannels(
+        tpAniSirGlobal pMac, 
+        tCsrScanResult *pResult, 
+        tCsrChannel *pOccupiedChannels, 
+        tDot11fBeaconIEs *pIes)
+{
+    eHalStatus status;
+    tANI_U8   channel;
+    tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels;
+    tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList;
+
+    channel = pResult->Result.BssDescriptor.channelId;
+
+    if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, channel)
+        && csrNeighborRoamIsSsidCandidateMatch(pMac, pIes)) 
+    {
+        status = csrAddToChannelListFront(pOccupiedChannelList, numOccupiedChannels, channel); 
+        if(HAL_STATUS_SUCCESS(status))
+        { 
+            pOccupiedChannels->numChannels++;
+            if (pOccupiedChannels->numChannels > CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN) 
+                pOccupiedChannels->numChannels = CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN; 
+        } 
+    }
+}
+#endif
+
 //Put the BSS into the scan result list
 //pIes can not be NULL
 static void csrScanAddResult(tpAniSirGlobal pMac, tCsrScanResult *pResult, tDot11fBeaconIEs *pIes)
@@ -1714,6 +1743,9 @@
     pResult->preferValue = csrGetBssPreferValue(pMac, (int)pResult->Result.BssDescriptor.rssi);
     pResult->capValue = csrGetBssCapValue(pMac, &pResult->Result.BssDescriptor, pIes);
     csrLLInsertTail( &pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_LOCK );
+#ifdef FEATURE_WLAN_LFR 
+    csrScanAddToOccupiedChannels(pMac, pResult, &pMac->scan.occupiedChannels, pIes);
+#endif
 }
 
 
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h b/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h
index fdd7f12..c38961e 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h
@@ -53,7 +53,7 @@
 
 #define CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS 14
 
-#define CSR_MAX_BSS_SUPPORT            100
+#define CSR_MAX_BSS_SUPPORT            150
 
 //This number minus 1 means the number of times a channel is scanned before a BSS is remvoed from
 //cache scan result
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c b/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c
index 033c074..6f86172 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c
@@ -423,6 +423,9 @@
     pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
     pNeighborRoamInfo->MinQBssLoadRequired = 0;
 #endif
+
+    /* Stop scan refresh timer */
+    palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
     
     NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
     /* Deregister reassoc callback. Ignore return status */
@@ -1689,6 +1692,70 @@
 
 /* ---------------------------------------------------------------------------
 
+    \fn csrNeighborRoamMergeChannelLists 
+
+    \brief  This function is used to merge two channel list.
+            NB: If called with outputNumOfChannels == 0, this routines
+                simply copies the input channel list to the output channel list.
+
+    \param  pMac - The handle returned by macOpen.
+    \param  pInputChannelList - The addtional channels to merge in to the "merged" channels list.
+    \param  inputNumOfChannels - The number of additional channels.
+    \param  pOutputChannelList - The place to put the "merged" channel list.
+    \param  outputNumOfChannels - The original number of channels in the "merged" channels list.
+    \param  pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list.
+
+    \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+VOS_STATUS csrNeighborRoamMergeChannelLists( 
+        tpAniSirGlobal pMac, 
+        tANI_U8   *pInputChannelList, 
+        int inputNumOfChannels,
+        tANI_U8   *pOutputChannelList,
+        int outputNumOfChannels,
+        int *pMergedOutputNumOfChannels 
+        )
+{
+    int i = 0;
+    int j = 0;
+    int numChannels = outputNumOfChannels;
+
+    // Check for NULL pointer
+    if (!pInputChannelList) return eHAL_STATUS_E_NULL_VALUE;
+
+    // Check for NULL pointer
+    if (!pOutputChannelList) return eHAL_STATUS_E_NULL_VALUE;
+
+    // Add the "new" channels in the input list to the end of the output list.
+    for (i = 0; i < inputNumOfChannels; i++)
+    {
+        for (j = 0; j < outputNumOfChannels; j++)
+        {
+            if (pInputChannelList[i] == pOutputChannelList[j])
+                break;
+        }
+        if (j == outputNumOfChannels)
+        {
+            if (pInputChannelList[i])
+            {
+                VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
+                        "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__, 
+                        pInputChannelList[i]); 
+                pOutputChannelList[numChannels] = pInputChannelList[i]; 
+                numChannels++; 
+            }
+        }
+    }
+
+    // Return final number of channels
+    *pMergedOutputNumOfChannels = numChannels; 
+
+    return eHAL_STATUS_SUCCESS;
+}
+
+/* ---------------------------------------------------------------------------
+
     \fn csrNeighborRoamCreateChanListFromNeighborReport
 
     \brief  This function is invoked when neighbor report is received for the 
@@ -1705,8 +1772,11 @@
 {
     tpRrmNeighborReportDesc pNeighborBssDesc;
     tpCsrNeighborRoamControlInfo    pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
-    tANI_U8         numChannels = 0, i = 0, j=0;
+    tANI_U8         numChannels = 0, i = 0;
     tANI_U8         channelList[MAX_BSS_IN_NEIGHBOR_RPT];
+#if 0
+    eHalStatus  status = eHAL_STATUS_SUCCESS;
+#endif
 
     /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
     pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
@@ -1753,28 +1823,18 @@
 
     if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
     {
+#if 0
         // Before we free the existing channel list for a safety net make sure
-        // we have a union of the IAPP and the already existing list. 
-        for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
-        {
-            for (j = 0; j < numChannels; j++)
-            {
-                if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] == channelList[j])
-                    break;
-            }
-            if (j == numChannels)
-            {
-                if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i])
-                {
-                            VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, 
-                                    "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
-                            pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
-                            channelList[numChannels] = 
-                            pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
-                            numChannels++;
-                }
-            }
-        }
+        // we have a union of the IAPP and the already existing list.
+        status = csrNeighborRoamMergeChannelLists( 
+                pMac, 
+                pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList, 
+                pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels, 
+                channelList, 
+                numChannels, 
+                &numChannels );
+#endif
+
         vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
     }
 
@@ -1903,6 +1963,109 @@
 #endif /* WLAN_FEATURE_VOWIFI_11R */
 
 
+#ifdef FEATURE_WLAN_LFR 
+tANI_BOOLEAN csrNeighborRoamIsSsidCandidateMatch( 
+        tpAniSirGlobal pMac, 
+        tDot11fBeaconIEs *pIes)
+{
+    tpCsrNeighborRoamControlInfo    pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
+    tANI_U8 sessionId   = (tANI_U8)pNeighborRoamInfo->csrSessionId;
+    tCsrRoamConnectedProfile *pCurProfile;
+    tANI_BOOLEAN fMatch = FALSE;
+
+    if( !(pMac->roam.roamSession
+            && CSR_IS_SESSION_VALID(pMac, sessionId)))
+        return TRUE;  // Treat missing information as a match for everything. 
+
+    pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
+
+    if( !pCurProfile)
+        return TRUE;  // Treat missing information as a match for everything. 
+
+    if( pIes )
+    {
+        if(pIes->SSID.present)
+        {
+            fMatch = csrIsSsidMatch( pMac, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length, 
+                    pIes->SSID.ssid, pIes->SSID.num_ssid, 
+                    eANI_BOOLEAN_TRUE ); // Treat a missing SSID as a non-match.
+            // Return the result of the match operation
+            return fMatch;  
+        } else
+            return FALSE;  // Treat a missing SSID as a non-match.
+    } else
+        return FALSE;  // Again, treat missing SSID information as a non-match. 
+}
+
+/* ---------------------------------------------------------------------------
+
+    \fn csrNeighborRoamReorderChannelList
+
+    \brief  This function is used to reorder the channel list used for the background
+            scan. It uses the information learned from previous scans to re-order the
+            scan channel list to "favor" the "occupied channels".  The actual algorithm
+            is to scan the current set of "occupied channels" first, for every BG scan,
+            followed by a "chunk" of the remaining list of "valid channels". 
+
+    \param  pMac - The handle returned by macOpen.
+    \param  pInputChannelList - The default channels list.
+    \param  numOfChannels - The number of channels in the default channels list.
+    \param  pOutputChannelList - The place to put the "re-ordered" channel list.
+    \param  pOutputNumOfChannels - The number of channels in the "re-ordered" channel list.
+
+    \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
+
+---------------------------------------------------------------------------*/
+VOS_STATUS csrNeighborRoamReorderChannelList( 
+        tpAniSirGlobal pMac, 
+        tANI_U8   *pInputChannelList, 
+        int numOfChannels,
+        tANI_U8   *pOutputChannelList,
+        int *pOutputNumOfChannels 
+        )
+{
+    int i = 0;
+    int j = 0;
+    static int index = 0;
+    int outputNumOfChannels  = 0; // Clear the output number of channels
+    tANI_U8 numOccupiedChannels = pMac->scan.occupiedChannels.numChannels;
+    tANI_U8 *pOccupiedChannelList = pMac->scan.occupiedChannels.channelList;
+
+
+    // Copy over the "occupied channels" at the FRONT of pOutputChannelList.
+    for (i = 0; i < numOccupiedChannels; i++)
+    {
+        if (pOccupiedChannelList[i] != 0) 
+        {
+            pOutputChannelList[i] = pOccupiedChannelList[i]; 
+            outputNumOfChannels++;
+        }
+    }
+
+    // Copy over one "chunk" of channels from the "rest of the channels"...append them to the END of pOutputChannelList.
+    for (j = 0; j < CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE; j++)
+    {
+        if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, pInputChannelList[j+index % numOfChannels])) 
+        {
+            pOutputChannelList[i] = pInputChannelList[j+index % numOfChannels]; 
+            i++;
+            outputNumOfChannels++;
+        }
+    }
+
+    //Let's update the index...at which we start retrieving the next chunk
+    index = (index + CSR_BG_SCAN_VALID_CHANNEL_LIST_CHUNK_SIZE) % numOfChannels; 
+
+    //VOS_ASSERT(numOfChannels == i);
+    smsLog(pMac, LOGE, FL("numOfChannels in the default channels list=%d. Number in the final list=%d."), numOfChannels, i);
+
+    // Return the number of channels
+    *pOutputNumOfChannels = outputNumOfChannels; 
+
+    return eHAL_STATUS_SUCCESS;
+}
+#endif /* FEATURE_WLAN_LFR */
+
 /* ---------------------------------------------------------------------------
 
     \fn csrNeighborRoamTransitToCFGChanScan
@@ -1923,7 +2086,7 @@
     eHalStatus  status  = eHAL_STATUS_SUCCESS;
     int i = 0;
     int numOfChannels = 0;
-    tANI_U8   channelList[MAX_BSS_IN_NEIGHBOR_RPT];
+    tANI_U8   channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
 
     if ( 
 #ifdef FEATURE_WLAN_CCX
@@ -1945,37 +2108,88 @@
             vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
             pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
         }
-        // Find the right subset of the cfg list based on the current band we are on.
-        for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
+        VOS_ASSERT( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList == NULL);
+
+        // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER
+        // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR.
+        if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels)
         {
-            if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i])
+            // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini".
+            NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini");
+            status = csrNeighborRoamMergeChannelLists( 
+                    pMac, 
+                    pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, 
+                    pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels, 
+                    channelList, 
+                    0, //NB: If 0, simply copy the input channel list to the output list.
+                    &numOfChannels );
+        } 
+        else
+        {
+            /* Get current list of valid channels. */
+            NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Switching to master list of valid channels");
+            numOfChannels = sizeof(pMac->roam.validChannelList);
+            if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, (tANI_U32 *) &numOfChannels)))
             {
-                        VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
-                                "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
-                                pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
-                        channelList[numOfChannels] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
-                        numOfChannels++;
+                // Copy the "default valid channel list" (channelList) from the actual "valid channel list" information formed by CSR
+                status = csrNeighborRoamMergeChannelLists( 
+                        pMac, 
+                        (tANI_U8 *)pMac->roam.validChannelList, 
+                        numOfChannels,   // The number of channels in the validChannelList 
+                        channelList, 
+                        0, //NB: If 0, simply copy the input channel list to the output list.
+                        &numOfChannels );  // The final number of channels in the output list. Will be numOfChannels
+            }
+            else
+            { 
+                smsLog(pMac, LOGE, FL("Could not get valid channel list, TL event ignored")); 
+                return VOS_STATUS_E_FAILURE;
             }
         }
 
+        /* At this point, channelList contains our best inputs on the "valid channel list" */
+
+        /* Allocate for the maximum number that might be used */
+        smsLog(pMac, LOGE, FL("%d channels in the default list. Add %d occupied channels. %d is the MAX scan channel list."), 
+                numOfChannels, 
+                CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN, 
+                numOfChannels+CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN );
         pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
-        pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; 
-        if (numOfChannels)
-            pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc(numOfChannels);
-    
+        VOS_ASSERT( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList == NULL);
+        if (numOfChannels) 
+        {
+            pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = 
+                vos_mem_malloc(numOfChannels+CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN );
+        }
+   
         if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
         {
             smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
             return VOS_STATUS_E_RESOURCES;
         }
     
+#ifdef FEATURE_WLAN_LFR
         /* Since this is a legacy case, copy the channel list from CFG here */
-        vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList, 
-                                channelList, numOfChannels * sizeof(tANI_U8));
+    
+        status = csrNeighborRoamReorderChannelList( pMac, 
+                channelList, 
+                numOfChannels, 
+                pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList, 
+                &numOfChannels );
+        if (eHAL_STATUS_SUCCESS != status)
+#endif
+        {
+            /* Re-ordering failed. */
+            smsLog(pMac, LOGE, FL("Cannot re-order scan channel list. (status = %d) Going to use default scan channel list."), status);
+            vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList, 
+                    channelList, numOfChannels * sizeof(tANI_U8));
+        } 
 
+        /* Adjust for the actual number that are used */
+        pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
         for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
         {
-            NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG = %d\n", 
+            NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG (or scan caching) = %d\n", 
                 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
         }
     }
@@ -2001,6 +2215,8 @@
     
     pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
     pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
+    /* We are about to start a fresh scan cycle, purge results from the past */
+    csrScanFlushResult(pMac);
     
     /* Transition to CFG_CHAN_LIST_SCAN_STATE */
     CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c b/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c
index 9148c1a..c066148 100644
--- a/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c
+++ b/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c
@@ -6263,3 +6263,49 @@
     }
 }
 
+#ifdef FEATURE_WLAN_LFR
+tANI_BOOLEAN csrIsChannelPresentInList( 
+        tANI_U8 *pChannelList,
+        int  numChannels,
+        tANI_U8   channel 
+        )
+{
+    int i = 0;
+
+    // Check for NULL pointer
+    if (!pChannelList) return FALSE;
+
+    // Look for the channel in the list
+    for (i = 0; i < numChannels; i++)
+    {
+        if (pChannelList[i] == channel) 
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+VOS_STATUS csrAddToChannelListFront( 
+        tANI_U8 *pChannelList,
+        int  numChannels,
+        tANI_U8   channel 
+        )
+{
+    int i = 0;
+
+    // Check for NULL pointer
+    if (!pChannelList) return eHAL_STATUS_E_NULL_VALUE;
+
+    // Make room for the addition.  (Start moving from the back.)
+    for (i = numChannels; i > 0; i--)
+    {
+        pChannelList[i] = pChannelList[i-1]; 
+    }
+
+    // Now add the NEW channel...at the front
+    pChannelList[0] = channel; 
+
+    return eHAL_STATUS_SUCCESS;
+}
+#endif
+
diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c
index 84687c6..56f6aab 100644
--- a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c
+++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c
@@ -1608,6 +1608,13 @@
     --------------------------------------------------------------------*/
   pTLCb->ucRegisteredStaId = ucSTAId;
 
+  if( WLANTL_STA_AUTHENTICATED != pTLCb->atlSTAClients[ucSTAId].tlState )
+  {
+    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+      "WLAN TL:Packet pending indication for STA: %d AC: %d State: %d", 
+               ucSTAId, ucAc, pTLCb->atlSTAClients[ucSTAId].tlState);
+  }
+
   /*-----------------------------------------------------------------------
     Enable this AC in the AC mask in order for TL to start servicing it
     Set packet pending flag 
@@ -5496,6 +5503,7 @@
    v_U8_t               ucTid;
    v_U8_t               extraHeadSpace = 0;
    v_U8_t               ucWDSEnabled = 0;
+   v_U8_t               ucAC, ucACMask, i; 
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
 
   /*------------------------------------------------------------------------
@@ -5505,8 +5513,8 @@
   pTLCb = VOS_GET_TL_CB(pvosGCtx);
   if ( NULL == pTLCb )
   {
-   TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
-             "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STATxConn"));
+   VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+             "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STATxConn");
    *pvosDataBuff = NULL;
     return VOS_STATUS_E_FAULT;
   }
@@ -5525,19 +5533,74 @@
        is successfull it will be re-enabled
   -------------------------------------------------------------------*/
 
-  pTLCb->atlSTAClients[ucSTAId].
-     aucACMask[pTLCb->atlSTAClients[ucSTAId].ucCurrentAC] = 0; 
+
+  //LTI:pTLCb->atlSTAClients[ucSTAId].
+  //LTI:   aucACMask[pTLCb->atlSTAClients[ucSTAId].ucCurrentAC] = 0; 
+
+  /*------------------------------------------------------------------------
+    Fetch packet from HDD
+   ------------------------------------------------------------------------*/
+  if ((WLAN_STA_SOFTAP != pTLCb->atlSTAClients[ucSTAId].wSTADesc.wSTAType) &&
+      (!vos_concurrent_sessions_running()))
+  {
+      ucAC = pTLCb->atlSTAClients[ucSTAId].ucCurrentAC;
+
+  /*-------------------------------------------------------------------
+      Disable AC temporary - if successfull retrieve re-enable
+      The order is justified because of the possible scenario
+       - TL tryes to fetch packet for AC and it returns NULL
+       - TL analyzes the data it has received to see if there are
+       any more pkts available for AC -> if not TL will disable AC
+       - however it is possible that while analyzing results TL got
+       preempted by a pending indication where the mask was again set
+       TL will not check again and as a result when it resumes
+       execution it will disable AC
+       To prevent this the AC will be disabled here and if retrieve
+       is successfull it will be re-enabled
+  -------------------------------------------------------------------*/
+     pTLCb->atlSTAClients[ucSTAId].aucACMask[ucAC] = 0; 
+  }
+  else
+  {
+    //softap case
+    ucAC = pTLCb->uCurServedAC;
+    pTLCb->atlSTAClients[ucSTAId].aucACMask[ucAC] = 0; 
+
+  }
 
     /*You make an initial assumption that HDD has no more data and if the 
       assumption was wrong you reset the flags to their original state
      This will prevent from exposing a race condition between checking with HDD 
      for packets and setting the flags to false*/
+ //LTI: vos_atomic_set_U8( &pTLCb->atlSTAClients[ucSTAId].ucPktPending, 0);
+ //LTI: pTLCb->atlSTAClients[ucSTAId].ucNoMoreData = 1;
   vos_atomic_set_U8( &pTLCb->atlSTAClients[ucSTAId].ucPktPending, 0);
+    WLAN_TL_AC_ARRAY_2_MASK( &pTLCb->atlSTAClients[ucSTAId], ucACMask, i); 
+#ifdef WLAN_SOFTAP_FEATURE
+    /*You make an initial assumption that HDD has no more data and if the 
+      assumption was wrong you reset the flags to their original state
+     This will prevent from exposing a race condition between checking with HDD 
+     for packets and setting the flags to false*/
+  if ( 0 == ucACMask )
+  {
   pTLCb->atlSTAClients[ucSTAId].ucNoMoreData = 1;
+  }
+  else
+  {
+    vos_atomic_set_U8( &pTLCb->atlSTAClients[ucSTAId].ucPktPending, 1);
+  }
+
+#endif
+
+  VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+            "WLAN TL: WLANTL_STATxConn fetching packet from HDD for AC: %d AC Mask: %d Pkt Pending: %d", 
+             ucAC, ucACMask, pTLCb->atlSTAClients[ucSTAId].ucPktPending);
 
   /*------------------------------------------------------------------------
     Fetch tx packet from HDD
    ------------------------------------------------------------------------*/
+//LTI
+#if 0 
 #ifdef WLAN_SOFTAP_FEATURE
   if (WLAN_STA_SOFTAP != pTLCb->atlSTAClients[ucSTAId].wSTADesc.wSTAType && 
      (!vos_concurrent_sessions_running()))
@@ -5561,6 +5624,12 @@
                                                 &vosDataBuff, &tlMetaInfo );
   }
 #endif
+#endif
+
+  vosStatus = pTLCb->atlSTAClients[ucSTAId].pfnSTAFetchPkt( pvosGCtx, 
+                               &ucSTAId,
+                               ucAC,
+                               &vosDataBuff, &tlMetaInfo );
 
   if (( VOS_STATUS_SUCCESS != vosStatus ) || ( NULL == vosDataBuff ))
   {
@@ -5577,6 +5646,10 @@
     pTLCb->atlSTAClients[ucSTAId].ucCurrentAC     = WLANTL_AC_VO;
     pTLCb->atlSTAClients[ucSTAId].ucCurrentWeight = 0;
 
+    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+              "WLAN TL: WLANTL_STATxConn no more packets in HDD for AC: %d AC Mask: %d", 
+               ucAC, ucACMask);
+
     return vosStatus;
   }
 
@@ -5584,9 +5657,8 @@
    the no more data assumption*/
   vos_atomic_set_U8( &pTLCb->atlSTAClients[ucSTAId].ucPktPending, 1);
   pTLCb->atlSTAClients[ucSTAId].ucNoMoreData = 0;
+  pTLCb->atlSTAClients[ucSTAId].aucACMask[ucAC] = 1; 
 
-   pTLCb->atlSTAClients[ucSTAId].
-     aucACMask[pTLCb->atlSTAClients[ucSTAId].ucCurrentAC] = 1; 
 #ifdef WLAN_PERF 
   vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAL, 
                              (v_PVOID_t)0);
@@ -6349,22 +6421,26 @@
     /* that we get an EAPOL packet in WAPI mode or vice versa? */
     if ( WLANTL_LLC_8021X_TYPE  != usEtherType && WLANTL_LLC_WAI_TYPE  != usEtherType )
     {
-      TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
-                 "WLAN TL:Frame not EAPOL or WAI - dropping"));
+      VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                 "WLAN TL:RX Frame not EAPOL or WAI EtherType %d - dropping", usEtherType );
       /* Drop packet */
       vos_pkt_return_packet(vosDataBuff);
     }
 #else
     if ( WLANTL_LLC_8021X_TYPE  != usEtherType )
     {
-      TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
-                 "WLAN TL:Frame not EAPOL - dropping"));
+      VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                 "WLAN TL:RX Frame not EAPOL EtherType %d - dropping", usEtherType);
       /* Drop packet */
       vos_pkt_return_packet(vosDataBuff);
     }
 #endif /* FEATURE_WLAN_WAPI */
     else /* Frame is an EAPOL frame or a WAI frame*/  
     {
+
+      VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+                 "WLAN TL:RX Frame  EAPOL EtherType %d - processing", usEtherType);
+
       if (( 0 == WDA_GET_RX_FT_DONE(aucBDHeader) ) &&
          ( 0 != pTLCb->atlSTAClients[ucSTAId].wSTADesc.ucSwFrameRXXlation))
       {
diff --git a/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini b/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini
index cb32d0e..6432276 100644
--- a/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini
@@ -160,10 +160,9 @@
 ImplicitQosIsEnabled=1
 gNeighborScanTimerPeriod=200
 
-gNeighborLookupThreshold=50
-gNeighborReassocThreshold=55
+gNeighborLookupThreshold=70
+gNeighborReassocThreshold=75
 
-gNeighborScanChannelList=1,11,36,64
 gNeighborScanChannelMinTime=20
 gNeighborScanChannelMaxTime=30
 gMaxNeighborReqTries=3
@@ -176,7 +175,7 @@
 #Check if the AP to which we are roaming is better than current AP in terms of RSSI.
 #Checking is disabled if set to Zero.Otherwise it will use this value as to how better 
 #the RSSI of the new/roamable AP should be for roaming
-RoamRssiDiff=5
+RoamRssiDiff=0
 
 # SAP Country code
 
@@ -302,7 +301,7 @@
 
 #passive scan to find out the domain
 
-#gEnableBypass11d=1
+gEnableBypass11d=1
 
 
 #If set to 0, will not scan DFS channels