wlan: Modify the split scan logic to scan more than one channel at a
time

Modify the split scan logic to split the full scan into operations which
scan more than one channel at a time. The number of channels that are
scanned in each of the individual scan operations is configurable
through the gNumChanCombinedConc parameter from the cfg.ini file. The
default value of gNumChanCombinedConc is currently set to 1.

Change-Id: Ie5b39dcde3a6cae293cfb9350ae9102a61a84a63
CR-Fixed: 429425
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 26efbc1..e0e2034 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -581,6 +581,11 @@
 #define CFG_REST_TIME_CONC_MAX                      ( 10000 )
 #define CFG_REST_TIME_CONC_DEFAULT                  ( 100 )
 
+#define CFG_NUM_CHAN_COMBINED_CONC_NAME             "gNumChanCombinedConc"
+#define CFG_NUM_CHAN_COMBINED_CONC_MIN              ( 1 )
+#define CFG_NUM_CHAN_COMBINED_CONC_MAX              ( 255 )
+#define CFG_NUM_CHAN_COMBINED_CONC_DEFAULT          ( 1 )
+
 #endif
 
 #define CFG_MAX_PS_POLL_NAME                   "gMaxPsPoll"
@@ -1619,6 +1624,8 @@
    v_U32_t        nActiveMinChnTimeConc;     //in units of milliseconds
    v_U32_t        nActiveMaxChnTimeConc;     //in units of milliseconds
    v_U32_t        nRestTimeConc;             //in units of milliseconds
+   v_U8_t         nNumChanCombinedConc;      //number of channels combined
+                                             //in each split scan operation
 #endif
 
    v_U8_t         nMaxPsPoll;
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index af8ca73..6fb0e31 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -699,6 +699,13 @@
                  CFG_REST_TIME_CONC_DEFAULT, 
                  CFG_REST_TIME_CONC_MIN, 
                  CFG_REST_TIME_CONC_MAX ),
+
+   REG_VARIABLE( CFG_NUM_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer,
+                 hdd_config_t, nNumChanCombinedConc,
+                 VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+                 CFG_NUM_CHAN_COMBINED_CONC_DEFAULT,
+                 CFG_NUM_CHAN_COMBINED_CONC_MIN,
+                 CFG_NUM_CHAN_COMBINED_CONC_MAX ),
 #endif
    
    REG_VARIABLE( CFG_MAX_PS_POLL_NAME, WLAN_PARAM_Integer,
@@ -3254,6 +3261,7 @@
    smeConfig.csrConfig.nPassiveMaxChnTimeConc   = pConfig->nPassiveMaxChnTimeConc;
    smeConfig.csrConfig.nPassiveMinChnTimeConc   = pConfig->nPassiveMinChnTimeConc;
    smeConfig.csrConfig.nRestTimeConc            = pConfig->nRestTimeConc;
+   smeConfig.csrConfig.nNumChanCombinedConc     = pConfig->nNumChanCombinedConc;
 #endif
    smeConfig.csrConfig.Is11eSupportEnabled      = pConfig->b80211eIsEnabled;
    smeConfig.csrConfig.WMMSupportMode           = pConfig->WmmMode;
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 762bc40..f7ce9f3 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -990,6 +990,8 @@
     tANI_U32  nActiveMinChnTimeConc;     //in units of milliseconds
     tANI_U32  nActiveMaxChnTimeConc;     //in units of milliseconds
     tANI_U32  nRestTimeConc;             //in units of milliseconds
+    tANI_U8   nNumChanCombinedConc;      //number of channels combined
+                                         //in each split scan operation
 #endif
 
     tANI_BOOLEAN IsIdleScanEnabled;
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index dca24d7..0c30bf9 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -567,6 +567,8 @@
     tANI_U32  nActiveMinChnTimeConc;     //in units of milliseconds
     tANI_U32  nActiveMaxChnTimeConc;     //in units of milliseconds
     tANI_U32  nRestTimeConc;             //in units of milliseconds
+    tANI_U8   nNumChanCombinedConc;      //number of channels combined
+                                         //in each split scan operation
 #endif
 
     tANI_BOOLEAN IsIdleScanEnabled;
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index ac644ef..f56bfdd 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -939,6 +939,7 @@
     pMac->roam.configParam.nPassiveMaxChnTimeConc = CSR_PASSIVE_MAX_CHANNEL_TIME_CONC;
     pMac->roam.configParam.nPassiveMinChnTimeConc = CSR_PASSIVE_MIN_CHANNEL_TIME_CONC;
     pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC;
+    pMac->roam.configParam.nNumChanCombinedConc = CSR_NUM_CHAN_COMBINED_CONC;
 #endif
     pMac->roam.configParam.IsIdleScanEnabled = TRUE; //enable the idle scan by default
     pMac->roam.configParam.nTxPowerCap = CSR_MAX_TX_POWER;
@@ -1206,6 +1207,10 @@
         {
             pMac->roam.configParam.nRestTimeConc = pParam->nRestTimeConc;
         }
+        if(pParam->nNumChanCombinedConc)
+        {
+            pMac->roam.configParam.nNumChanCombinedConc = pParam->nNumChanCombinedConc;
+        }
 #endif
         //if upper layer wants to disable idle scan altogether set it to 0
         if(pParam->impsSleepTime)
@@ -1384,6 +1389,7 @@
         pParam->nPassiveMaxChnTimeConc = pMac->roam.configParam.nPassiveMaxChnTimeConc;
         pParam->nPassiveMinChnTimeConc = pMac->roam.configParam.nPassiveMinChnTimeConc;
         pParam->nRestTimeConc = pMac->roam.configParam.nRestTimeConc;
+        pParam->nNumChanCombinedConc = pMac->roam.configParam.nNumChanCombinedConc;
 #endif
         //Change the unit from microsecond to second
         pParam->impsSleepTime = pMac->roam.configParam.impsSleepTime / PAL_TIMER_TO_SEC_UNIT;
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index 0ad006d..98084a5 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -430,179 +430,169 @@
      * - any P2P session is connected
      */
     if ( (csrIsStaSessionConnected(pMac) && (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
-         (csrIsP2pSessionConnected(pMac)) )
+            (csrIsP2pSessionConnected(pMac)) )
     {
         tCsrScanRequest scanReq;
         tANI_U8 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels;
         tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
         tANI_U8    channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
-        tANI_U8    i = 0;
         tANI_BOOLEAN bMemAlloc = eANI_BOOLEAN_FALSE;
 
         if (numChn == 0)
         {
 
             numChn = pMac->scan.baseChannels.numChannels;
-             
-             status = palAllocateMemory( pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn );
-             if( !HAL_STATUS_SUCCESS( status ) )
-             {
-                 smsLog( pMac, LOGE, FL(" Failed to get memory for channel list \n") );
-                 return eHAL_STATUS_FAILURE;
-             }
-             bMemAlloc = eANI_BOOLEAN_TRUE;
-             status = palCopyMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, 
-                         pMac->scan.baseChannels.channelList, numChn );
-             if( !HAL_STATUS_SUCCESS( status ) )
-             {
-                 palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
-                 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
-                 smsLog( pMac, LOGE, FL(" Failed to copy memory to channel list \n") );
-                 return eHAL_STATUS_FAILURE;
-             }
-             pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn;
-         }
 
-         //Whenever we get a scan request with multiple channels we break it up into 2 requests
-         //First request  for first channel to scan and second request to scan remaining channels
-         for  (i=0; i < 2; i++)
-         {   //go through max 2 iterations. 
-             //Once for using the existing command when number of channels is 1 
-             //Second to go over the remaining channels after creating a new command
-            
-            if (1 == numChn)
+            status = palAllocateMemory( pMac->hHdd, (void **)&pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn );
+            if( !HAL_STATUS_SUCCESS( status ) )
             {
-                pSendScanCmd = pScanCmd;
-                pSendScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 1;
-                //Use concurrency values for min/maxChnTime. 
-                //We know csrIsAnySessionConnected(pMac) returns TRUE here
-                csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest);
-                if (i != 0)
-                { //Callback should be NULL for all except last channel So hdd_callback will be called only after last command
-                  //i!=0 then we came here in second iteration 
-                   pSendScanCmd->u.scanCmd.callback = NULL;
-                }
-                break; //break out of this loop in case there is only 1 channel then no need for 2nd iteration
-            
-            } else { //if number of channels > 1 then
-            
-                palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
+                smsLog( pMac, LOGE, FL(" Failed to get memory for channel list \n") );
+                return eHAL_STATUS_FAILURE;
+            }
+            bMemAlloc = eANI_BOOLEAN_TRUE;
+            status = palCopyMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList,
+                    pMac->scan.baseChannels.channelList, numChn );
+            if( !HAL_STATUS_SUCCESS( status ) )
+            {
+                palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
+                pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
+                smsLog( pMac, LOGE, FL(" Failed to copy memory to channel list \n") );
+                return eHAL_STATUS_FAILURE;
+            }
+            pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn;
+        }
 
-                pQueueScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
-                if (!pQueueScanCmd)
+        //Whenever we get a scan request with multiple channels we break it up into 2 requests
+        //First request  for first channel to scan and second request to scan remaining channels
+        if (numChn > pMac->roam.configParam.nNumChanCombinedConc)
+        {
+            palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
+
+            pQueueScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only
+            if (!pQueueScanCmd)
+            {
+                if (bMemAlloc)
                 {
-                    if (bMemAlloc)
-                    {
-                        palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
-                        pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
-                 
-                    }
-                    smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer\n") );
-                    return eHAL_STATUS_FAILURE;
+                    palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
+                    pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
+
                 }
-                pQueueScanCmd->command = pScanCmd->command; 
-                pQueueScanCmd->sessionId = pScanCmd->sessionId;
-                pQueueScanCmd->u.scanCmd.callback = pScanCmd->u.scanCmd.callback;
-                pQueueScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
-                pQueueScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
-                pQueueScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
+                smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer\n") );
+                return eHAL_STATUS_FAILURE;
+            }
+            pQueueScanCmd->command = pScanCmd->command;
+            pQueueScanCmd->sessionId = pScanCmd->sessionId;
+            pQueueScanCmd->u.scanCmd.callback = pScanCmd->u.scanCmd.callback;
+            pQueueScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext;
+            pQueueScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason;
+            pQueueScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around
 
-                /* First copy all the parameters to local variable of scan request */
-                csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);
+            /* First copy all the parameters to local variable of scan request */
+            csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest);
 
-                /* Now modify the elements of local var scan request required to be modified for split scan */
-                if(scanReq.ChannelInfo.ChannelList != NULL)
-                {
-                    palFreeMemory(pMac->hHdd, scanReq.ChannelInfo.ChannelList);
-                    scanReq.ChannelInfo.ChannelList = NULL;
-                }
-                
-                pChnInfo->numOfChannels = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels - 1;
-
-                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, 
-                   FL(" &channelToScan %0x pScanCmd(0x%X) pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList(0x%X)numChn(%d)"),
-                   &channelToScan[0], (unsigned int)pScanCmd, 
-                   (unsigned int)pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn);
-              
-                palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[1], 
-                              pChnInfo->numOfChannels * sizeof(tANI_U8));
-
-                pChnInfo->ChannelList = &channelToScan[0];
-              
-                scanReq.BSSType = eCSR_BSS_TYPE_ANY;
-                //Modify callers parameters in case of concurrency
-                scanReq.scanType = eSIR_ACTIVE_SCAN;
-                //Use concurrency values for min/maxChnTime. 
-                //We know csrIsAnySessionConnected(pMac) returns TRUE here
-                csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);
-
-                status = csrScanCopyRequest(pMac, &pQueueScanCmd->u.scanCmd.u.scanRequest, &scanReq);
-
-                if(!HAL_STATUS_SUCCESS(status))
-                {
-                    if (bMemAlloc)
-                    {
-                        palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
-                        pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
-                 
-                    }
-                    if( scanReq.pIEField != NULL)
-                    {
-                        palFreeMemory(pMac->hHdd, scanReq.pIEField);
-                        scanReq.pIEField = NULL;
-                    }
-                    smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d\n"), status );
-                    return eHAL_STATUS_FAILURE;
-                }
-                /* Clean the local scan variable */
+            /* Now modify the elements of local var scan request required to be modified for split scan */
+            if(scanReq.ChannelInfo.ChannelList != NULL)
+            {
+                palFreeMemory(pMac->hHdd, scanReq.ChannelInfo.ChannelList);
                 scanReq.ChannelInfo.ChannelList = NULL;
-                scanReq.ChannelInfo.numOfChannels = 0;
-                csrScanFreeRequest(pMac, &scanReq);
-                numChn = 1; //make numChn to be 1 for second iteration to create a send command
-            }  
+            }
 
-         }
+            pChnInfo->numOfChannels = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels - pMac->roam.configParam.nNumChanCombinedConc;
 
-         fNoCmdPending = csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK );
+            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
+                    FL(" &channelToScan %0x pScanCmd(0x%X) pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList(0x%X)numChn(%d)"),
+                    &channelToScan[0], (unsigned int)pScanCmd,
+                    (unsigned int)pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn);
 
-         //Logic Below is as follows
-         // If the scanCmdPendingList is empty then we directly send that command
-         // to smeCommandQueue else we buffer it in our scanCmdPendingList Queue
-         if( fNoCmdPending )
-         {
-            
+            palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[pMac->roam.configParam.nNumChanCombinedConc],
+                    pChnInfo->numOfChannels * sizeof(tANI_U8));
+
+            pChnInfo->ChannelList = &channelToScan[0];
+
+            scanReq.BSSType = eCSR_BSS_TYPE_ANY;
+            //Modify callers parameters in case of concurrency
+            scanReq.scanType = eSIR_ACTIVE_SCAN;
+            //Use concurrency values for min/maxChnTime.
+            //We know csrIsAnySessionConnected(pMac) returns TRUE here
+            csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq);
+
+            status = csrScanCopyRequest(pMac, &pQueueScanCmd->u.scanCmd.u.scanRequest, &scanReq);
+
+            if(!HAL_STATUS_SUCCESS(status))
+            {
+                if (bMemAlloc)
+                {
+                    palFreeMemory( pMac->hHdd, pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList );
+                    pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL;
+
+                }
+                if( scanReq.pIEField != NULL)
+                {
+                    palFreeMemory(pMac->hHdd, scanReq.pIEField);
+                    scanReq.pIEField = NULL;
+                }
+                smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d\n"), status );
+                return eHAL_STATUS_FAILURE;
+            }
+            /* Clean the local scan variable */
+            scanReq.ChannelInfo.ChannelList = NULL;
+            scanReq.ChannelInfo.numOfChannels = 0;
+            csrScanFreeRequest(pMac, &scanReq);
+
+            /* setup the command to scan 2 channels */
+            pSendScanCmd = pScanCmd;
+            pSendScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = pMac->roam.configParam.nNumChanCombinedConc;
+            pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
+            pSendScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
+            //Use concurrency values for min/maxChnTime.
+            //We know csrIsAnySessionConnected(pMac) returns TRUE here
+            csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest);
+            pSendScanCmd->u.scanCmd.callback = NULL;
+        } else {
+            pSendScanCmd = pScanCmd;
+            pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
+            pSendScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN;
+            //Use concurrency values for min/maxChnTime.
+            //We know csrIsAnySessionConnected(pMac) returns TRUE here
+            csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest);
+        }
+
+        fNoCmdPending = csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK );
+
+        //Logic Below is as follows
+        // If the scanCmdPendingList is empty then we directly send that command
+        // to smeCommandQueue else we buffer it in our scanCmdPendingList Queue
+        if( fNoCmdPending )
+        {
             if (pQueueScanCmd != NULL)
             {            
-              csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
+                csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
             }
 
             if (pSendScanCmd != NULL)
             {            
                 return csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE);
             }
-         }
-         else
-         {           
+        }
+        else
+        {
             if (pSendScanCmd != NULL)
             {
                 csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pSendScanCmd->Link, LL_ACCESS_LOCK );
             }
+
             if (pQueueScanCmd != NULL)
             {
                 csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK );
             }
-         }
-
+        }
     }
     else
     {  //No concurrency case
         return csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE);
     }
-    
-
 
     return ( status );
-
 }
 #endif
 
@@ -5545,7 +5535,7 @@
         tCsrScanRequest scanReq;
         tSmeCmd *pSendScanCmd = NULL;
         tANI_U8 numChn = 0;
-        tANI_U8 i;
+        tANI_U8 i, j;
         tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo;
         tANI_U8    channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
         eHalStatus status;
@@ -5563,7 +5553,7 @@
          * - STA session is connected and the scan is not a P2P search
          * - any P2P session is connected
          */
-        if ( (numChn > 1) &&
+        if ( (numChn > pMac->roam.configParam.nNumChanCombinedConc) &&
              ((csrIsStaSessionConnected(pMac) && (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) ||
               (csrIsP2pSessionConnected(pMac))))
         {
@@ -5593,18 +5583,18 @@
                  scanReq.ChannelInfo.ChannelList = NULL;
              }
              
-             pChnInfo->numOfChannels = 1;
-             palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0], 
-                          1 * sizeof(tANI_U8)); //just send one channel
+             pChnInfo->numOfChannels = pMac->roam.configParam.nNumChanCombinedConc;
+             palCopyMemory(pMac->hHdd, &channelToScan[0], &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0],
+                     pChnInfo->numOfChannels * sizeof(tANI_U8)); //just send one channel
              pChnInfo->ChannelList = &channelToScan[0];
 
-             for (i = 0; i <= (numChn-2); i++)
+             for (i = 0, j = pMac->roam.configParam.nNumChanCombinedConc; i < (numChn-pMac->roam.configParam.nNumChanCombinedConc); i++, j++)
              {
                  pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] = 
-                 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i+1]; //Move all the channels one step
+                 pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[j]; //Move all the channels one step
              }
           
-             pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn -1; //reduce outstanding # of channels to be scanned
+             pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn - pMac->roam.configParam.nNumChanCombinedConc; //reduce outstanding # of channels to be scanned
 
              scanReq.BSSType = eCSR_BSS_TYPE_ANY;
              //Modify callers parameters in case of concurrency
diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h
index c46cb62..f01d833 100644
--- a/CORE/SME/src/csr/csrInsideApi.h
+++ b/CORE/SME/src/csr/csrInsideApi.h
@@ -72,6 +72,8 @@
 #define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC    20
 
 #define CSR_REST_TIME_CONC                  100
+
+#define CSR_NUM_CHAN_COMBINED_CONC          1
 #endif
 
 #define CSR_MAX_NUM_SUPPORTED_CHANNELS 55
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index e701df5..59c3925 100644
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -355,6 +355,7 @@
 gActiveMaxChannelTimeConc=27
 gActiveMinChannelTimeConc=20
 gRestTimeConc=100
+gNumChanCombinedConc=1
 
 #If set to 0, MCC is not allowed.
 gEnableMCCMode=1