wlan: Auto Channel Selection Support in HT40/VHT80

Auto Channel Selection Support in HT40/VHT80

Change-Id: I0b6424031f11446395a0b6f6a724b879758df9ca
CR-Fixed: 427491
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index ad9ac0c..4902862 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -1239,20 +1239,19 @@
  * called by wlan_hdd_cfg80211_start_bss() and
  * This function  selects the cbmode based on primary channel
  */ 
-static VOS_STATUS wlan_hdd_select_cbmode(hdd_adapter_t *pAdapter,tsap_Config_t *pSapConfig )
+VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
 {
     tSmeConfigParams smeConfig;
-    hdd_context_t  *pHddCtx  = ( hdd_context_t *) pAdapter->pHddCtx;
-    hdd_config_t  *pConfigIni = ((hdd_context_t *)(pAdapter->pHddCtx))->cfg_ini;
-    v_U8_t         channel;
-
+    hdd_context_t  *pHddCtx  = ( hdd_context_t *) pAdapter;
+    hdd_config_t  *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
+    
     if(
 #ifdef WLAN_FEATURE_11AC
-      pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11ac &&
-      pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
+      SapHw_mode != eSAP_DOT11_MODE_11ac &&
+      SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
 #endif
-      pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11n &&
-      pSapConfig->SapHw_mode != eSAP_DOT11_MODE_11n_ONLY 
+      SapHw_mode != eSAP_DOT11_MODE_11n &&
+      SapHw_mode != eSAP_DOT11_MODE_11n_ONLY 
       )
     {
         return VOS_STATUS_SUCCESS;
@@ -1262,15 +1261,15 @@
         return VOS_STATUS_SUCCESS;
     }
 
-    channel = pSapConfig->channel;
+    //channel = pSapConfig->channel;
     vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
 
     sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
 
 #ifdef WLAN_FEATURE_11AC
 
-    if ( pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11ac || 
-         pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
+    if ( SapHw_mode == eSAP_DOT11_MODE_11ac || 
+         SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
     {
         if ( channel== 36 || channel == 52 || channel == 100 ||
              channel == 116 || channel == 149 )
@@ -1302,8 +1301,8 @@
         }
     }
 #endif
-    if ( pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11n ||
-          pSapConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
+    if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
+          SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
     {
         if ( channel== 40 || channel == 48 || channel == 56 ||
              channel == 64 || channel == 104 || channel == 112 ||
@@ -1631,7 +1630,8 @@
     }
 #endif
      
-    wlan_hdd_select_cbmode(pHostapdAdapter,pConfig);
+    if( AUTO_CHANNEL_SELECT != pConfig->channel)
+        wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
     // ht_capab is not what the name conveys,this is used for protection bitmap
     pConfig->ht_capab =
                  (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 6d4edd7..33c3363 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -702,6 +702,13 @@
     tANI_U8              WscIeProbeRsp[WSCIE_PROBE_RSP_LEN];
     tANI_U8              reservedPadding4;
 
+    /* ChannelWidth, secondaryChanneloffset, VHT capability and center freqency in case of VHT Information what peer sent in beacon/probersp */
+
+    tANI_U16             channelWidth;
+    tANI_U16             secondaryChannelOffset;
+    tANI_U16             vhtSupport;
+    tANI_U16             centerFreq; 
+
     tANI_U32             ieFields[1];
 } tSirBssDescription, *tpSirBssDescription;
 
diff --git a/CORE/SAP/src/sapApiLinkCntl.c b/CORE/SAP/src/sapApiLinkCntl.c
index 13ec941..f6ae08c 100644
--- a/CORE/SAP/src/sapApiLinkCntl.c
+++ b/CORE/SAP/src/sapApiLinkCntl.c
@@ -198,6 +198,7 @@
       psapContext->channel = operChannel;
     }
     
+    wlan_sap_select_cbmode(vos_get_context( VOS_MODULE_ID_HDD, psapContext->pvosGCtx),psapContext->csrRoamProfile.phyMode, psapContext->channel);
 #ifdef SOFTAP_CHANNEL_RANGE
     if(psapContext->channelList != NULL)
     {
diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c
index 756370a..a2200ca 100644
--- a/CORE/SAP/src/sapChSelect.c
+++ b/CORE/SAP/src/sapChSelect.c
@@ -348,6 +348,7 @@
         pSpectCh->chNum = *pChans;
         pSpectCh->valid = eSAP_TRUE;
         pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;// Initialise for all channels
+        pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; // Initialise 20MHz for all the Channels 
         pSpectCh++;
         pChans++;
     }
@@ -439,18 +440,21 @@
 
     tCsrScanResultInfo *pScanResult;
     tSapSpectChInfo *pSpectCh   = pSpectInfoParams->pSpectCh;
+    v_U32_t operatingBand;
 
     VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Computing spectral weight", __func__);
 
     /**
     * Soft AP specific channel weight calculation using DFS formula
     */
+    ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
 
     pScanResult = sme_ScanResultGetFirst(halHandle, pResult);    
 
     while (pScanResult) {
         pSpectCh = pSpectInfoParams->pSpectCh;
-        // Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list
+        
+	// Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list
         for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans; chn_num++) {
 
             /*
@@ -468,11 +472,166 @@
 
                 ++pSpectCh->bssCount; // Increment the count of BSS
 
+                if(operatingBand) // Connsidering the Extension Channel only in a channels
+                {
+                    /* Updating the received ChannelWidth */
+                    if (pSpectCh->channelWidth != pScanResult->BssDescriptor.channelWidth) 
+                        pSpectCh->channelWidth = pScanResult->BssDescriptor.channelWidth;
+		    
+                    /* If received ChannelWidth is other than HT20, we need to update the extension channel Params as well
+                     * channelWidth == 0, HT20
+                     * channelWidth == 1, HT40
+                     * channelWidth == 2, VHT80
+                     */
+                    switch(pSpectCh->channelWidth)
+                    {
+                        case eHT_CHANNEL_WIDTH_40MHZ: //HT40
+                            switch( pScanResult->BssDescriptor.secondaryChannelOffset)
+                            {
+                                tSapSpectChInfo *pExtSpectCh = NULL;
+                                case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: // Above the Primary Channel
+                                    pExtSpectCh = (pSpectCh + 1);
+                                    if(pExtSpectCh != NULL)
+                                    {
+                                        ++pExtSpectCh->bssCount;
+                                        // REducing the rssi by -20 and assigning it to Extension channel
+                                        pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                        if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                            pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                    }
+                                break;
+                                case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: // Below the Primary channel
+                                    pExtSpectCh = (pSpectCh - 1);
+                                    if(pExtSpectCh != NULL) 
+                                    {
+                                        pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                        if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                            pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                        ++pExtSpectCh->bssCount;
+                                    }
+                                break;
+                            }
+                        break;
+                        case eHT_CHANNEL_WIDTH_80MHZ: // VHT80
+                            if((pScanResult->BssDescriptor.centerFreq - channel_id) == 6)
+                            {
+                                tSapSpectChInfo *pExtSpectCh = NULL;
+                                pExtSpectCh = (pSpectCh + 1);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI); // Reducing the rssi by -20 and assigning it to Subband 1 
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh + 2);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_SUBBAND2_RSSI); // Reducing the rssi by -30 and assigning it to Subband 2
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh + 3);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_SUBBAND3_RSSI); // Reducing the rssi by -40 and assigning it to Subband 3
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }  
+                            }
+                            else if((pScanResult->BssDescriptor.centerFreq - channel_id) == 2)
+                            {
+                                tSapSpectChInfo *pExtSpectCh = NULL;
+                                pExtSpectCh = (pSpectCh - 1 );
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh + 1);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh + 2);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_SUBBAND2_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                            }
+                            else if((pScanResult->BssDescriptor.centerFreq - channel_id) == -2)
+                            {
+                                tSapSpectChInfo *pExtSpectCh = NULL;
+                                pExtSpectCh = (pSpectCh - 1 );
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh - 2);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_SUBBAND2_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh + 1);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                            }
+                            else if((pScanResult->BssDescriptor.centerFreq - channel_id) == -6)
+                            {
+                                tSapSpectChInfo *pExtSpectCh = NULL;
+                                pExtSpectCh = (pSpectCh - 1 );
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_CHAN_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh - 2);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_SUBBAND2_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                                pExtSpectCh = (pSpectCh - 3);
+                                if(pExtSpectCh != NULL)
+                                {
+                                    ++pExtSpectCh->bssCount;
+                                    pExtSpectCh->rssiAgr = (pSpectCh->rssiAgr + SAP_EXT_SUBBAND3_RSSI);
+                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+                                }
+                            }
+                        break;
+                    }
+                } 
+
                 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
-                   "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=0x%x",
-                  __func__, pScanResult->BssDescriptor.channelIdSelf, pScanResult->BssDescriptor.channelId, 
-                  pScanResult->BssDescriptor.rssi, pSpectCh->bssCount, pScanResult);
-                         
+                   "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=0x%x, ChannelWidth %d, secondaryChanOffset %d, center frequency %d \n",
+                  __func__, pScanResult->BssDescriptor.channelIdSelf, pScanResult->BssDescriptor.channelId, pScanResult->BssDescriptor.rssi, pSpectCh->bssCount, pScanResult,pSpectCh->channelWidth,pScanResult->BssDescriptor.secondaryChannelOffset,pScanResult->BssDescriptor.centerFreq);
                  pSpectCh++;
                  break;
            } else {
diff --git a/CORE/SAP/src/sapChSelect.h b/CORE/SAP/src/sapChSelect.h
index 25ea2f9..d9dd6fe 100644
--- a/CORE/SAP/src/sapChSelect.h
+++ b/CORE/SAP/src/sapChSelect.h
@@ -82,6 +82,11 @@
 #define SAP_DEFAULT_CHANNEL     (6)
 #define SAP_DEFAULT_5GHZ_CHANNEL      (40)
 #define SAP_CHANNEL_NOT_SELECTED (0)
+
+#define SOFTAP_HT20_CHANNELWIDTH 0
+#define SAP_EXT_CHAN_RSSI      (-20)
+#define SAP_EXT_SUBBAND2_RSSI      (-30)
+#define SAP_EXT_SUBBAND3_RSSI      (-40)
 /**
 * Structure holding information of each channel in the spectrum, 
 * it contains the channel number, the computed weight
@@ -96,6 +101,7 @@
 
 typedef struct {
     v_U16_t chNum;      // Channel Number
+    v_U16_t channelWidth;      // Channel Width
     v_U16_t bssCount;   // bss found in scanresult for this channel
     v_S31_t rssiAgr;    // Max value of rssi among all BSS(es) from scanresult for this channel
     v_U32_t weight;     // Weightage of this channel
diff --git a/CORE/SAP/src/sapInternal.h b/CORE/SAP/src/sapInternal.h
index 39a6c04..7df7130 100644
--- a/CORE/SAP/src/sapInternal.h
+++ b/CORE/SAP/src/sapInternal.h
@@ -734,6 +734,9 @@
 VOS_STATUS
 sap_ReleaseGlobalLock( ptSapContext  pSapCtx );
 
+VOS_STATUS
+wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel);
+
 #ifdef __cplusplus
 }
 #endif 
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index cf28bb1..ca3de42 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -2716,7 +2716,29 @@
             csrSaveToChannelPower2G_5G( pMac, pIesLocal->Country.num_triplets * sizeof(tSirMacChanInfo), 
                                         (tSirMacChanInfo *)(&pIesLocal->Country.triplets[0]) );
         }
-
+	
+        if(pIesLocal->HTCaps.present && pIesLocal->HTInfo.present) 
+        {
+            pBssDescription->Result.BssDescriptor.channelWidth = pIesLocal->HTCaps.supportedChannelWidthSet;
+            pBssDescription->Result.BssDescriptor.secondaryChannelOffset = pIesLocal->HTInfo.secondaryChannelOffset;
+            if(pIesLocal->VHTOperation.present)
+            {
+                pBssDescription->Result.BssDescriptor.vhtSupport = pIesLocal->VHTOperation.present;
+                if(pIesLocal->VHTOperation.chanWidth > eHT_CHANNEL_WIDTH_20MHZ) 
+                {
+                    pBssDescription->Result.BssDescriptor.channelWidth = eHT_CHANNEL_WIDTH_80MHZ;
+                    pBssDescription->Result.BssDescriptor.centerFreq = pIesLocal->VHTOperation.chanCenterFreqSeg1; 
+                }
+            }
+        }  
+        else
+        {
+            pBssDescription->Result.BssDescriptor.channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
+            pBssDescription->Result.BssDescriptor.secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
+            pBssDescription->Result.BssDescriptor.vhtSupport = 0;
+            pBssDescription->Result.BssDescriptor.centerFreq = 0;
+        }
+        
         // append to main list
         csrScanAddResult(pMac, pBssDescription, pIesLocal);
         if( (pBssDescription->Result.pvIes == NULL) && pIesLocal )