qcacld-3.0: Initial snapshot of ihelium wlan driver

qcacld-3.0: Initial snapshot of ihelium wlan driver
to match code-scanned SU Release 5.0.0.139. This is
open-source version of wlan for next Android release.

Change-Id: Icf598ca97da74f84bea607e4e902d1889806f507
diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c
new file mode 100644
index 0000000..cb8e89f
--- /dev/null
+++ b/core/sap/src/sap_ch_select.c
@@ -0,0 +1,2030 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+
+                      s a p C h S e l e c t . C
+   OVERVIEW:
+
+   This software unit holds the implementation of the WLAN SAP modules
+   functions for channel selection.
+
+   DEPENDENCIES:
+
+   Are listed for each API below.
+   ===========================================================================*/
+
+/*--------------------------------------------------------------------------
+   Include Files
+   ------------------------------------------------------------------------*/
+#include "cdf_trace.h"
+#include "csr_api.h"
+#include "sme_api.h"
+#include "sap_ch_select.h"
+#include "sap_internal.h"
+#ifdef ANI_OS_TYPE_QNX
+#include "stdio.h"
+#endif
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#include "lim_utils.h"
+#include "parser_api.h"
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+#ifdef CONFIG_CNSS
+#include <net/cnss.h>
+#endif
+
+/*--------------------------------------------------------------------------
+   Function definitions
+   --------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------
+   Defines
+   --------------------------------------------------------------------------*/
+#define SAP_DEBUG
+
+#define IS_RSSI_VALID(extRssi, rssi) \
+	( \
+		((extRssi < rssi) ? true : false) \
+	)
+
+#define SET_ACS_BAND(acs_band, pSapCtx) \
+{ \
+	if (pSapCtx->acs_cfg->start_ch <= 14 && \
+		pSapCtx->acs_cfg->end_ch <= 14) \
+		acs_band = eCSR_DOT11_MODE_11g; \
+	else if (pSapCtx->acs_cfg->start_ch >= 14)\
+		acs_band = eCSR_DOT11_MODE_11a; \
+	else \
+		acs_band = eCSR_DOT11_MODE_abg; \
+}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+sapSafeChannelType safe_channels[NUM_20MHZ_RF_CHANNELS] = {
+	/*CH  , SAFE, default safe */
+	{1, true}
+	,                       /* RF_CHAN_1, */
+	{2, true}
+	,                       /* RF_CHAN_2, */
+	{3, true}
+	,                       /* RF_CHAN_3, */
+	{4, true}
+	,                       /* RF_CHAN_4, */
+	{5, true}
+	,                       /* RF_CHAN_5, */
+	{6, true}
+	,                       /* RF_CHAN_6, */
+	{7, true}
+	,                       /* RF_CHAN_7, */
+	{8, true}
+	,                       /* RF_CHAN_8, */
+	{9, true}
+	,                       /* RF_CHAN_9, */
+	{10, true}
+	,                       /* RF_CHAN_10, */
+	{11, true}
+	,                       /* RF_CHAN_11, */
+	{12, true}
+	,                       /* RF_CHAN_12, */
+	{13, true}
+	,                       /* RF_CHAN_13, */
+	{14, true}
+	,                       /* RF_CHAN_14, */
+	{240, true}
+	,                       /* RF_CHAN_240, */
+	{244, true}
+	,                       /* RF_CHAN_244, */
+	{248, true}
+	,                       /* RF_CHAN_248, */
+	{252, true}
+	,                       /* RF_CHAN_252, */
+	{208, true}
+	,                       /* RF_CHAN_208, */
+	{212, true}
+	,                       /* RF_CHAN_212, */
+	{216, true}
+	,                       /* RF_CHAN_216, */
+	{36, true}
+	,                       /* RF_CHAN_36, */
+	{40, true}
+	,                       /* RF_CHAN_40, */
+	{44, true}
+	,                       /* RF_CHAN_44, */
+	{48, true}
+	,                       /* RF_CHAN_48, */
+	{52, true}
+	,                       /* RF_CHAN_52, */
+	{56, true}
+	,                       /* RF_CHAN_56, */
+	{60, true}
+	,                       /* RF_CHAN_60, */
+	{64, true}
+	,                       /* RF_CHAN_64, */
+	{100, true}
+	,                       /* RF_CHAN_100, */
+	{104, true}
+	,                       /* RF_CHAN_104, */
+	{108, true}
+	,                       /* RF_CHAN_108, */
+	{112, true}
+	,                       /* RF_CHAN_112, */
+	{116, true}
+	,                       /* RF_CHAN_116, */
+	{120, true}
+	,                       /* RF_CHAN_120, */
+	{124, true}
+	,                       /* RF_CHAN_124, */
+	{128, true}
+	,                       /* RF_CHAN_128, */
+	{132, true}
+	,                       /* RF_CHAN_132, */
+	{136, true}
+	,                       /* RF_CHAN_136, */
+	{140, true}
+	,                       /* RF_CHAN_140, */
+	{144, true}
+	,                       /* RF_CHAN_144, */
+	{149, true}
+	,                       /* RF_CHAN_149, */
+	{153, true}
+	,                       /* RF_CHAN_153, */
+	{157, true}
+	,                       /* RF_CHAN_157, */
+	{161, true}
+	,                       /* RF_CHAN_161, */
+	{165, true}
+	,                       /* RF_CHAN_165, */
+};
+#endif
+
+typedef struct {
+	uint16_t chStartNum;
+	uint32_t weight;
+} sapAcsChannelInfo;
+
+sapAcsChannelInfo acs_ht40_channels5_g[] = {
+	{36, SAP_ACS_WEIGHT_MAX},
+	{44, SAP_ACS_WEIGHT_MAX},
+	{52, SAP_ACS_WEIGHT_MAX},
+	{60, SAP_ACS_WEIGHT_MAX},
+	{100, SAP_ACS_WEIGHT_MAX},
+	{108, SAP_ACS_WEIGHT_MAX},
+	{116, SAP_ACS_WEIGHT_MAX},
+	{124, SAP_ACS_WEIGHT_MAX},
+	{132, SAP_ACS_WEIGHT_MAX},
+	{140, SAP_ACS_WEIGHT_MAX},
+	{149, SAP_ACS_WEIGHT_MAX},
+	{157, SAP_ACS_WEIGHT_MAX},
+};
+
+sapAcsChannelInfo acs_ht80_channels[] = {
+	{36, SAP_ACS_WEIGHT_MAX},
+	{52, SAP_ACS_WEIGHT_MAX},
+	{100, SAP_ACS_WEIGHT_MAX},
+	{116, SAP_ACS_WEIGHT_MAX},
+	{132, SAP_ACS_WEIGHT_MAX},
+	{149, SAP_ACS_WEIGHT_MAX},
+};
+
+sapAcsChannelInfo acs_ht40_channels24_g[] = {
+	{1, SAP_ACS_WEIGHT_MAX},
+	{2, SAP_ACS_WEIGHT_MAX},
+	{3, SAP_ACS_WEIGHT_MAX},
+	{4, SAP_ACS_WEIGHT_MAX},
+	{9, SAP_ACS_WEIGHT_MAX},
+};
+
+#define CHANNEL_165  165
+
+/* rssi discount for channels in PCL */
+#define PCL_RSSI_DISCOUNT 10
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * sap_check_n_add_channel() - checks and add given channel in sap context's
+ * avoid_channels_info struct
+ * @sap_ctx:           sap context.
+ * @new_channel:       channel to be added to sap_ctx's avoid ch info
+ *
+ * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
+ * which MDM device's AP with MCC was detected. This function will add channels
+ * to that list after checking for duplicates.
+ *
+ * Return: true: if channel was added or already present
+ *   else false: if channel list was already full.
+ */
+bool
+sap_check_n_add_channel(ptSapContext sap_ctx,
+			uint8_t new_channel)
+{
+	uint8_t i = 0;
+	struct sap_avoid_channels_info *ie_info =
+		&sap_ctx->sap_detected_avoid_ch_ie;
+
+	for (i = 0; i < sizeof(ie_info->channels); i++) {
+		if (ie_info->channels[i] == new_channel)
+			break;
+
+		if (ie_info->channels[i] == 0) {
+			ie_info->channels[i] = new_channel;
+			break;
+		}
+	}
+	if (i == sizeof(ie_info->channels))
+		return false;
+	else
+		return true;
+}
+/**
+ * sap_check_n_add_overlapped_chnls() - checks & add overlapped channels
+ *                                      to primary channel in 2.4Ghz band.
+ * @sap_ctx:           sap context.
+ * @primary_chnl:      primary channel to be avoided.
+ *
+ * sap_ctx contains sap_avoid_ch_info struct containing the list of channels on
+ * which MDM device's AP with MCC was detected. This function will add channels
+ * to that list after checking for duplicates.
+ *
+ * Return: true: if channel was added or already present
+ *   else false: if channel list was already full.
+ */
+static bool
+sap_check_n_add_overlapped_chnls(ptSapContext sap_ctx, uint8_t primary_channel)
+{
+	uint8_t i = 0, j = 0, upper_chnl = 0, lower_chnl = 0;
+	struct sap_avoid_channels_info *ie_info =
+		&sap_ctx->sap_detected_avoid_ch_ie;
+	/*
+	 * if primary channel less than channel 1 or out of 2g band then
+	 * no further process is required. return true in this case.
+	 */
+	if (primary_channel < CHANNEL_1 || primary_channel > CHANNEL_14)
+		return true;
+
+	/* lower channel is one channel right before primary channel */
+	lower_chnl = primary_channel - 1;
+	/* upper channel is one channel right after primary channel */
+	upper_chnl = primary_channel + 1;
+
+	/* lower channel needs to be non-zero, zero is not valid channel */
+	if (lower_chnl > (CHANNEL_1 - 1)) {
+		for (i = 0; i < sizeof(ie_info->channels); i++) {
+			if (ie_info->channels[i] == lower_chnl)
+				break;
+			if (ie_info->channels[i] == 0) {
+				ie_info->channels[i] = lower_chnl;
+				break;
+			}
+		}
+	}
+	/* upper channel needs to be atleast last channel in 2.4Ghz band */
+	if (upper_chnl < (CHANNEL_14 + 1)) {
+		for (j = 0; j < sizeof(ie_info->channels); j++) {
+			if (ie_info->channels[j] == upper_chnl)
+				break;
+			if (ie_info->channels[j] == 0) {
+				ie_info->channels[j] = upper_chnl;
+				break;
+			}
+		}
+	}
+	if (i == sizeof(ie_info->channels) || j == sizeof(ie_info->channels))
+		return false;
+	else
+		return true;
+}
+
+/**
+ * sap_process_avoid_ie() - processes the detected Q2Q IE
+ * context's avoid_channels_info struct
+ * @hal:                hal handle
+ * @sap_ctx:            sap context.
+ * @scan_result:        scan results for ACS scan.
+ * @spect_info:         spectrum weights array to update
+ *
+ * Detection of Q2Q IE indicates presence of another MDM device with its AP
+ * operating in MCC mode. This function parses the scan results and processes
+ * the Q2Q IE if found. It then extracts the channels and populates them in
+ * sap_ctx struct. It also increases the weights of those channels so that
+ * ACS logic will avoid those channels in its selection algorithm.
+ *
+ * Return: void
+ */
+void sap_process_avoid_ie(tHalHandle hal,
+			  ptSapContext sap_ctx,
+			  tScanResultHandle scan_result,
+			  tSapChSelSpectInfo *spect_info)
+{
+	uint32_t total_ie_len = 0;
+	uint8_t *temp_ptr = NULL;
+	uint8_t i = 0;
+	struct sAvoidChannelIE *avoid_ch_ie;
+	tCsrScanResultInfo *node = NULL;
+	tpAniSirGlobal mac_ctx = NULL;
+	tSapSpectChInfo *spect_ch = NULL;
+
+	mac_ctx = PMAC_STRUCT(hal);
+	spect_ch = spect_info->pSpectCh;
+	node = sme_scan_result_get_first(hal, scan_result);
+
+	while (node) {
+		total_ie_len = (node->BssDescriptor.length +
+			sizeof(uint16_t) + sizeof(uint32_t) -
+			sizeof(tSirBssDescription));
+		temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
+				SIR_MAC_QCOM_VENDOR_OUI,
+				SIR_MAC_QCOM_VENDOR_SIZE,
+				((uint8_t *)&node->BssDescriptor.ieFields),
+				total_ie_len);
+
+		if (temp_ptr) {
+			avoid_ch_ie = (struct sAvoidChannelIE *)temp_ptr;
+			if (avoid_ch_ie->type != QCOM_VENDOR_IE_MCC_AVOID_CH)
+				continue;
+
+			sap_ctx->sap_detected_avoid_ch_ie.present = 1;
+			CDF_TRACE(CDF_MODULE_ID_SAP,
+				  CDF_TRACE_LEVEL_DEBUG,
+				  "Q2Q IE - avoid ch %d",
+				  avoid_ch_ie->channel);
+			/* add this channel to to_avoid channel list */
+			sap_check_n_add_channel(sap_ctx,
+					avoid_ch_ie->channel);
+			sap_check_n_add_overlapped_chnls(sap_ctx,
+					avoid_ch_ie->channel);
+			/*
+			 * Mark weight of these channel present in IE to MAX
+			 * so that ACS logic will to avoid thse channels
+			 */
+			for (i = 0; i < spect_info->numSpectChans; i++)
+				if (spect_ch[i].chNum == avoid_ch_ie->channel) {
+					/*
+					 * weight is set more than max so that,
+					 * in the case of other channels being
+					 * assigned max weight due to noise,
+					 * they may be preferred over channels
+					 * with Q2Q IE.
+					 */
+					spect_ch[i].weight = SAP_ACS_WEIGHT_MAX + 1;
+					spect_ch[i].weight_copy =
+						SAP_ACS_WEIGHT_MAX + 1;
+					break;
+				}
+		} /* if (temp_ptr) */
+		node = sme_scan_result_get_next(hal, scan_result);
+	}
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+/*==========================================================================
+   FUNCTION    sap_update_unsafe_channel_list
+
+   DESCRIPTION
+    Function  Undate unsafe channel list table
+
+   DEPENDENCIES
+    NA.
+
+   IN
+    SapContext pointer
+
+   RETURN VALUE
+    NULL
+   ============================================================================*/
+#ifdef CONFIG_CNSS
+void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
+{
+	uint16_t i, j;
+	uint16_t unsafe_channel_list[NUM_20MHZ_RF_CHANNELS];
+	uint16_t unsafe_channel_count = 0;
+
+	/* Flush, default set all channel safe */
+	for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
+		safe_channels[i].isSafe = true;
+	}
+
+	/* Try to find unsafe channel */
+#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) || \
+	defined(WLAN_FEATURE_MBSSID)
+	for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
+		if (pSapCtx->dfs_ch_disable == true) {
+			if (CDS_IS_DFS_CH(safe_channels[i].channelNumber)) {
+				safe_channels[i].isSafe = false;
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					CDF_TRACE_LEVEL_INFO_HIGH,
+					"%s: DFS Ch %d is not safe in"
+					" Concurrent mode",
+					__func__,
+					safe_channels[i].channelNumber);
+			}
+		}
+	}
+#endif
+
+	cnss_get_wlan_unsafe_channel(unsafe_channel_list,
+				     &unsafe_channel_count,
+				     sizeof(unsafe_channel_list));
+
+	for (i = 0; i < unsafe_channel_count; i++) {
+		for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++) {
+			if (safe_channels[j].channelNumber ==
+			    unsafe_channel_list[i]) {
+				/* Found unsafe channel, update it */
+				safe_channels[j].isSafe = false;
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					  CDF_TRACE_LEVEL_ERROR,
+					  FL("CH %d is not safe"),
+					  unsafe_channel_list[i]);
+				break;
+			}
+		}
+	}
+
+	return;
+}
+#else
+void sap_update_unsafe_channel_list(ptSapContext pSapCtx)
+{
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			  "%s: Not implemented", __func__);
+	return;
+}
+#endif
+
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+/*==========================================================================
+   FUNCTION    sap_cleanup_channel_list
+
+   DESCRIPTION
+    Function sap_cleanup_channel_list frees up the memory allocated to the channel list.
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    NULL
+
+   RETURN VALUE
+    NULL
+   ============================================================================*/
+
+void sap_cleanup_channel_list(
+#ifdef WLAN_FEATURE_MBSSID
+	void *p_cds_gctx
+#else
+	void
+#endif
+	) {
+#ifndef WLAN_FEATURE_MBSSID
+	void *p_cds_gctx = cds_get_global_context();
+#endif
+	ptSapContext pSapCtx;
+
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
+		  "Cleaning up the channel list structure");
+
+	if (NULL == p_cds_gctx) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_FATAL,
+			  "SAP Global Context is NULL");
+		return;
+	}
+
+	pSapCtx = CDS_GET_SAP_CB(p_cds_gctx);
+	if (NULL == pSapCtx) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_FATAL,
+			  "SAP Context is NULL");
+		return;
+	}
+
+	pSapCtx->SapChnlList.numChannel = 0;
+	if (pSapCtx->SapChnlList.channelList) {
+		cdf_mem_free(pSapCtx->SapChnlList.channelList);
+		pSapCtx->SapChnlList.channelList = NULL;
+	}
+
+	pSapCtx->SapAllChnlList.numChannel = 0;
+	if (pSapCtx->SapAllChnlList.channelList) {
+		cdf_mem_free(pSapCtx->SapAllChnlList.channelList);
+		pSapCtx->SapAllChnlList.channelList = NULL;
+	}
+}
+
+/**
+ * sap_select_preferred_channel_from_channel_list() - to calc best cahnnel
+ * @best_chnl: best channel already calculated among all the chanels
+ * @sap_ctx: sap context
+ * @spectinfo_param: Pointer to tSapChSelSpectInfo structure
+ *
+ * This function calculates the best channel among the configured channel list.
+ * If channel list not configured then returns the best channel calculated
+ * among all the channel list.
+ *
+ * Return: uint8_t best channel
+ */
+uint8_t sap_select_preferred_channel_from_channel_list(uint8_t best_chnl,
+				ptSapContext sap_ctx,
+				tSapChSelSpectInfo *spectinfo_param)
+{
+	uint8_t i = 0;
+
+	/*
+	 * If Channel List is not Configured don't do anything
+	 * Else return the Best Channel from the Channel List
+	 */
+	if ((NULL == sap_ctx->acs_cfg->ch_list) ||
+		(NULL == spectinfo_param) ||
+		(0 == sap_ctx->acs_cfg->ch_list_count))
+		return best_chnl;
+
+	if (best_chnl <= 0 || best_chnl > 252)
+		return SAP_CHANNEL_NOT_SELECTED;
+
+	/* Select the best channel from allowed list */
+	for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
+		if (sap_ctx->acs_cfg->ch_list[i] == best_chnl) {
+			CDF_TRACE(CDF_MODULE_ID_SAP,
+				CDF_TRACE_LEVEL_INFO_HIGH,
+				"Best channel is: %d",
+				best_chnl);
+			return best_chnl;
+		}
+	}
+
+	return SAP_CHANNEL_NOT_SELECTED;
+}
+
+/*==========================================================================
+   FUNCTION    sap_chan_sel_init
+
+   DESCRIPTION
+    Function sap_chan_sel_init allocates the memory, intializes the
+         structures used by the channel selection algorithm
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    halHandle          : Pointer to tHalHandle
+   *pSpectInfoParams  : Pointer to tSapChSelSpectInfo structure
+     pSapCtx           : Pointer to SAP Context
+
+   RETURN VALUE
+    bool:  Success or FAIL
+
+   SIDE EFFECTS
+   ============================================================================*/
+bool sap_chan_sel_init(tHalHandle halHandle,
+		       tSapChSelSpectInfo *pSpectInfoParams, ptSapContext pSapCtx)
+{
+	tSapSpectChInfo *pSpectCh = NULL;
+	uint8_t *pChans = NULL;
+	uint16_t channelnum = 0;
+	tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
+	bool chSafe = true;
+#ifdef FEATURE_WLAN_CH_AVOID
+	uint16_t i;
+#endif
+	uint32_t dfs_master_cap_enabled;
+	bool include_dfs_ch = true;
+
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH, "In %s",
+		  __func__);
+
+	pSpectInfoParams->numSpectChans =
+		pMac->scan.base_channels.numChannels;
+
+	/* Allocate memory for weight computation of 2.4GHz */
+	pSpectCh =
+		(tSapSpectChInfo *) cdf_mem_malloc((pSpectInfoParams->numSpectChans)
+						   * sizeof(*pSpectCh));
+
+	if (pSpectCh == NULL) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			  "In %s, CDF_MALLOC_ERR", __func__);
+		return eSAP_FALSE;
+	}
+
+	cdf_mem_zero(pSpectCh,
+		     (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));
+
+	/* Initialize the pointers in the DfsParams to the allocated memory */
+	pSpectInfoParams->pSpectCh = pSpectCh;
+
+	pChans = pMac->scan.base_channels.channelList;
+
+#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE) || defined(WLAN_FEATURE_MBSSID)
+	if (pSapCtx->dfs_ch_disable == true)
+		include_dfs_ch = false;
+#endif
+	sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
+			&dfs_master_cap_enabled);
+	if (dfs_master_cap_enabled == 0)
+		include_dfs_ch = false;
+
+	/* Fill the channel number in the spectrum in the operating freq band */
+	for (channelnum = 0;
+	     channelnum < pSpectInfoParams->numSpectChans;
+	     channelnum++, pChans++) {
+		chSafe = true;
+
+		/* check if the channel is in NOL blacklist */
+		if (sap_dfs_is_channel_in_nol_list(pSapCtx, *pChans,
+						   PHY_SINGLE_CHANNEL_CENTERED)) {
+			CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+				  "In %s, Ch %d is in NOL list", __func__,
+				  *pChans);
+			chSafe = false;
+			continue;
+		}
+
+		if (include_dfs_ch == false) {
+			if (CDS_IS_DFS_CH(*pChans)) {
+				chSafe = false;
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					  CDF_TRACE_LEVEL_INFO_HIGH,
+					  "In %s, DFS Ch %d not considered for ACS",
+					  __func__, *pChans);
+				continue;
+			}
+		}
+
+#ifdef FEATURE_WLAN_CH_AVOID
+		for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
+			if ((safe_channels[i].channelNumber == *pChans) &&
+			    (false == safe_channels[i].isSafe)) {
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					  CDF_TRACE_LEVEL_INFO_HIGH,
+					  "In %s, Ch %d is not safe", __func__,
+					  *pChans);
+				chSafe = false;
+				break;
+			}
+		}
+#endif /* FEATURE_WLAN_CH_AVOID */
+
+		/* OFDM rates are not supported on channel 14 */
+		if (*pChans == 14 &&
+		    eCSR_DOT11_MODE_11b != pSapCtx->csr_roamProfile.phyMode) {
+			pSpectCh++;
+			continue;
+		}
+
+		if (true == chSafe) {
+			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++;
+	}
+	return eSAP_TRUE;
+}
+
+/*==========================================================================
+   FUNCTION    sapweight_rssi_count
+
+   DESCRIPTION
+    Function weightRssiCount calculates the channel weight due to rssi
+         and data count(here number of BSS observed)
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    rssi        : Max signal strength receieved from a BSS for the channel
+    count       : Number of BSS observed in the channel
+
+   RETURN VALUE
+    uint32_t     : Calculated channel weight based on above two
+
+   SIDE EFFECTS
+   ============================================================================*/
+uint32_t sapweight_rssi_count(int8_t rssi, uint16_t count)
+{
+	int32_t rssiWeight = 0;
+	int32_t countWeight = 0;
+	uint32_t rssicountWeight = 0;
+
+	/* Weight from RSSI */
+	rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI)
+		     / (SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);
+
+	if (rssiWeight > SOFTAP_RSSI_WEIGHT)
+		rssiWeight = SOFTAP_RSSI_WEIGHT;
+	else if (rssiWeight < 0)
+		rssiWeight = 0;
+
+	/* Weight from data count */
+	countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT)
+		      / (SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);
+
+	if (countWeight > SOFTAP_COUNT_WEIGHT)
+		countWeight = SOFTAP_COUNT_WEIGHT;
+
+	rssicountWeight = rssiWeight + countWeight;
+
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
+		  __func__, rssiWeight, countWeight, rssicountWeight);
+
+	return rssicountWeight;
+}
+
+/**
+ * sap_update_rssi_bsscount() - updates bss count and rssi effect.
+ *
+ * @pSpectCh:     Channel Information
+ * @offset:       Channel Offset
+ * @sap_24g:      Channel is in 2.4G or 5G
+ *
+ * sap_update_rssi_bsscount updates bss count and rssi effect based
+ * on the channel offset.
+ *
+ * Return: None.
+ */
+
+void sap_update_rssi_bsscount(tSapSpectChInfo *pSpectCh, int32_t offset,
+			      bool sap_24g)
+{
+	tSapSpectChInfo *pExtSpectCh = NULL;
+	int32_t rssi, rsssi_effect;
+
+	pExtSpectCh = (pSpectCh + offset);
+	if (pExtSpectCh != NULL) {
+		++pExtSpectCh->bssCount;
+		switch (offset) {
+		case -1:
+		case 1:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
+			break;
+		case -2:
+		case 2:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
+			break;
+		case -3:
+		case 3:
+			rsssi_effect = sap_24g ?
+			    SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY :
+			    SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
+			break;
+		case -4:
+		case 4:
+			rsssi_effect =
+			    SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
+			break;
+		default:
+			rsssi_effect = 0;
+			break;
+		}
+
+		rssi = pSpectCh->rssiAgr + rsssi_effect;
+		if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
+			pExtSpectCh->rssiAgr = rssi;
+		if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
+			pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
+	}
+}
+
+/**
+ * sap_upd_chan_spec_params() - sap_upd_chan_spec_params
+ *                              updates channel parameters obtained from Beacon
+ * @pBeaconStruct Beacon strucutre populated by parse_beacon function
+ * @channelWidth Channel width
+ * @secondaryChannelOffset Secondary Channel Offset
+ * @vhtSupport If channel supports VHT
+ * @centerFreq Central frequency for the given channel.
+ *
+ * sap_upd_chan_spec_params updates the spectrum channels based on the
+ * pBeaconStruct obtained from Beacon IE
+ *
+ * Return: NA.
+ */
+
+void sap_upd_chan_spec_params(tSirProbeRespBeacon *pBeaconStruct,
+			      uint16_t *channelWidth,
+			      uint16_t *secondaryChannelOffset,
+			      uint16_t *vhtSupport,
+			      uint16_t *centerFreq)
+{
+	if (NULL == pBeaconStruct) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			  FL("pBeaconStruct is NULL"));
+		return;
+	}
+
+	if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) {
+		*channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet;
+		*secondaryChannelOffset = pBeaconStruct->HTInfo.
+						secondaryChannelOffset;
+
+		if (pBeaconStruct->VHTOperation.present) {
+			*vhtSupport = pBeaconStruct->VHTOperation.present;
+			if (pBeaconStruct->VHTOperation.chanWidth >
+			    WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
+				*channelWidth = eHT_CHANNEL_WIDTH_80MHZ;
+				*centerFreq = pBeaconStruct->VHTOperation.
+							chanCenterFreqSeg1;
+			}
+		}
+	}
+}
+
+/**
+ * sap_interference_rssi_count_5G() - sap_interference_rssi_count
+ *                                    considers the Adjacent channel rssi and
+ *                                    data count(here number of BSS observed)
+ * @spect_ch:        Channel Information
+ * @chan_width:      Channel width parsed from beacon IE
+ * @sec_chan_offset: Secondary Channel Offset
+ * @center_freq:     Central frequency for the given channel.
+ * @channel_id:      channel_id
+ *
+ * sap_interference_rssi_count_5G considers the Adjacent channel rssi
+ * and data count(here number of BSS observed)
+ *
+ * Return: NA.
+ */
+
+void sap_interference_rssi_count_5G(tSapSpectChInfo *spect_ch,
+				 uint16_t chan_width,
+				 uint16_t sec_chan_offset,
+				 uint16_t center_freq, uint8_t channel_id)
+{
+	if (NULL == spect_ch) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			  FL("spect_ch is NULL"));
+		return;
+	}
+
+	/* Updating the received ChannelWidth */
+	if (spect_ch->channelWidth != chan_width)
+		spect_ch->channelWidth = chan_width;
+	/* If received ChannelWidth is other than HT20,
+	 * we need to update the extension channel Params as well
+	 * chan_width == 0, HT20
+	 * chan_width == 1, HT40
+	 * chan_width == 2, VHT80
+	 */
+
+	switch (spect_ch->channelWidth) {
+	case eHT_CHANNEL_WIDTH_40MHZ:   /* HT40 */
+		switch (sec_chan_offset) {
+		/* Above the Primary Channel */
+		case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+			sap_update_rssi_bsscount(spect_ch, 1, false);
+			break;
+
+		/* Below the Primary channel */
+		case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+			sap_update_rssi_bsscount(spect_ch, -1, false);
+			break;
+		}
+		break;
+	case eHT_CHANNEL_WIDTH_80MHZ:   /* VHT80 */
+		if ((center_freq - channel_id) == 6) {
+			sap_update_rssi_bsscount(spect_ch, 1, false);
+			sap_update_rssi_bsscount(spect_ch, 2, false);
+			sap_update_rssi_bsscount(spect_ch, 3, false);
+		} else if ((center_freq - channel_id) == 2) {
+			sap_update_rssi_bsscount(spect_ch, -1, false);
+			sap_update_rssi_bsscount(spect_ch, 1, false);
+			sap_update_rssi_bsscount(spect_ch, 2, false);
+		} else if ((center_freq - channel_id) == -2) {
+			sap_update_rssi_bsscount(spect_ch, -2, false);
+			sap_update_rssi_bsscount(spect_ch, -1, false);
+			sap_update_rssi_bsscount(spect_ch, 1, false);
+		} else if ((center_freq - channel_id) == -6) {
+			sap_update_rssi_bsscount(spect_ch, -1, false);
+			sap_update_rssi_bsscount(spect_ch, -2, false);
+			sap_update_rssi_bsscount(spect_ch, -3, false);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * sap_interference_rssi_count() - sap_interference_rssi_count
+ *                                 considers the Adjacent channel rssi
+ *                                 and data count(here number of BSS observed)
+ * @spect_ch    Channel Information
+ *
+ * sap_interference_rssi_count considers the Adjacent channel rssi
+ * and data count(here number of BSS observed)
+ *
+ * Return: None.
+ */
+
+void sap_interference_rssi_count(tSapSpectChInfo *spect_ch)
+{
+	if (NULL == spect_ch) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			  "%s: spect_ch is NULL", __func__);
+		return;
+	}
+
+	switch (spect_ch->chNum) {
+	case CHANNEL_1:
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		sap_update_rssi_bsscount(spect_ch, 3, true);
+		sap_update_rssi_bsscount(spect_ch, 4, true);
+		break;
+
+	case CHANNEL_2:
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		sap_update_rssi_bsscount(spect_ch, 3, true);
+		sap_update_rssi_bsscount(spect_ch, 4, true);
+		break;
+	case CHANNEL_3:
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		sap_update_rssi_bsscount(spect_ch, 3, true);
+		sap_update_rssi_bsscount(spect_ch, 4, true);
+		break;
+	case CHANNEL_4:
+		sap_update_rssi_bsscount(spect_ch, -3, true);
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		sap_update_rssi_bsscount(spect_ch, 3, true);
+		sap_update_rssi_bsscount(spect_ch, 4, true);
+		break;
+
+	case CHANNEL_5:
+	case CHANNEL_6:
+	case CHANNEL_7:
+	case CHANNEL_8:
+	case CHANNEL_9:
+	case CHANNEL_10:
+		sap_update_rssi_bsscount(spect_ch, -4, true);
+		sap_update_rssi_bsscount(spect_ch, -3, true);
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		sap_update_rssi_bsscount(spect_ch, 3, true);
+		sap_update_rssi_bsscount(spect_ch, 4, true);
+		break;
+
+	case CHANNEL_11:
+		sap_update_rssi_bsscount(spect_ch, -4, true);
+		sap_update_rssi_bsscount(spect_ch, -3, true);
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		sap_update_rssi_bsscount(spect_ch, 3, true);
+		break;
+
+	case CHANNEL_12:
+		sap_update_rssi_bsscount(spect_ch, -4, true);
+		sap_update_rssi_bsscount(spect_ch, -3, true);
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		sap_update_rssi_bsscount(spect_ch, 2, true);
+		break;
+
+	case CHANNEL_13:
+		sap_update_rssi_bsscount(spect_ch, -4, true);
+		sap_update_rssi_bsscount(spect_ch, -3, true);
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		sap_update_rssi_bsscount(spect_ch, 1, true);
+		break;
+
+	case CHANNEL_14:
+		sap_update_rssi_bsscount(spect_ch, -4, true);
+		sap_update_rssi_bsscount(spect_ch, -3, true);
+		sap_update_rssi_bsscount(spect_ch, -2, true);
+		sap_update_rssi_bsscount(spect_ch, -1, true);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*==========================================================================
+  Function    ch_in_pcl
+
+  Description
+   Check if a channel is in the preferred channel list
+
+  Parameters
+   sap_ctx   SAP context pointer
+   channel   input channel number
+
+  Return Value
+   true:    channel is in PCL
+   false:   channel is not in PCL
+ ==========================================================================*/
+bool ch_in_pcl(ptSapContext sap_ctx, uint8_t channel)
+{
+	uint32_t i;
+
+	for (i = 0; i < sap_ctx->acs_cfg->pcl_ch_count; i++) {
+		if (channel == sap_ctx->acs_cfg->pcl_channels[i])
+			return true;
+	}
+
+	return false;
+}
+
+/*==========================================================================
+   FUNCTION    sap_compute_spect_weight
+
+   DESCRIPTION
+    Main function for computing the weight of each channel in the
+    spectrum based on the RSSI value of the BSSes on the channel
+    and number of BSS
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSpectInfoParams structure
+    halHandle              : Pointer to HAL handle
+    pResult                : Pointer to tScanResultHandle
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams,
+			      tHalHandle halHandle, tScanResultHandle pResult,
+				ptSapContext sap_ctx)
+{
+	int8_t rssi = 0;
+	uint8_t chn_num = 0;
+	uint8_t channel_id = 0;
+
+	tCsrScanResultInfo *pScanResult;
+	tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh;
+	uint32_t operatingBand;
+	uint16_t channelWidth;
+	uint16_t secondaryChannelOffset;
+	uint16_t centerFreq;
+	uint16_t vhtSupport;
+	uint32_t ieLen = 0;
+	tSirProbeRespBeacon *pBeaconStruct;
+	tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
+
+	pBeaconStruct = cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+	if (NULL == pBeaconStruct) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			  "Unable to allocate memory in sap_compute_spect_weight\n");
+		return;
+	}
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Computing spectral weight", __func__);
+
+	/**
+	 * Soft AP specific channel weight calculation using DFS formula
+	 */
+	SET_ACS_BAND(operatingBand, sap_ctx);
+
+	pScanResult = sme_scan_result_get_first(halHandle, pResult);
+
+	while (pScanResult) {
+		pSpectCh = pSpectInfoParams->pSpectCh;
+		/* Defining the default values, so that any value will hold the default values */
+		channelWidth = eHT_CHANNEL_WIDTH_20MHZ;
+		secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
+		vhtSupport = 0;
+		centerFreq = 0;
+
+		if (pScanResult->BssDescriptor.ieFields != NULL) {
+			ieLen =
+				(pScanResult->BssDescriptor.length +
+				 sizeof(uint16_t) + sizeof(uint32_t) -
+				 sizeof(tSirBssDescription));
+			cdf_mem_set((uint8_t *) pBeaconStruct,
+				    sizeof(tSirProbeRespBeacon), 0);
+
+			if ((sir_parse_beacon_ie
+				     (pMac, pBeaconStruct,
+				     (uint8_t *) (pScanResult->BssDescriptor.ieFields),
+				     ieLen)) == eSIR_SUCCESS) {
+				sap_upd_chan_spec_params(pBeaconStruct,
+					&channelWidth, &secondaryChannelOffset,
+					&vhtSupport, &centerFreq);
+			}
+		}
+		/* Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list */
+		for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans;
+		     chn_num++) {
+
+			/*
+			 *  if the Beacon has channel ID, use it other wise we will
+			 *  rely on the channelIdSelf
+			 */
+			if (pScanResult->BssDescriptor.channelId == 0)
+				channel_id =
+					pScanResult->BssDescriptor.channelIdSelf;
+			else
+				channel_id =
+					pScanResult->BssDescriptor.channelId;
+
+			if (pSpectCh && (channel_id == pSpectCh->chNum)) {
+				if (pSpectCh->rssiAgr <
+				    pScanResult->BssDescriptor.rssi)
+					pSpectCh->rssiAgr =
+						pScanResult->BssDescriptor.rssi;
+
+				++pSpectCh->bssCount;   /* Increment the count of BSS */
+
+				/*
+				 * Connsidering the Extension Channel
+				 * only in a channels
+				 */
+				switch (operatingBand) {
+				case eCSR_DOT11_MODE_11a:
+					sap_interference_rssi_count_5G(
+					    pSpectCh, channelWidth,
+					    secondaryChannelOffset, centerFreq,
+					    channel_id);
+					break;
+
+				case eCSR_DOT11_MODE_11g:
+					sap_interference_rssi_count(pSpectCh);
+					break;
+
+				case eCSR_DOT11_MODE_abg:
+					sap_interference_rssi_count_5G(
+					    pSpectCh, channelWidth,
+					    secondaryChannelOffset, centerFreq,
+					    channel_id);
+					sap_interference_rssi_count(pSpectCh);
+					break;
+				}
+
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					  CDF_TRACE_LEVEL_INFO_HIGH,
+					  "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%p, ChannelWidth %d, secondaryChanOffset %d, center frequency %d \n",
+					  __func__,
+					  pScanResult->BssDescriptor.
+					  channelIdSelf,
+					  pScanResult->BssDescriptor.channelId,
+					  pScanResult->BssDescriptor.rssi,
+					  pSpectCh->bssCount, pScanResult,
+					  pSpectCh->channelWidth,
+					  secondaryChannelOffset, centerFreq);
+				pSpectCh++;
+				break;
+			} else {
+				pSpectCh++;
+			}
+		}
+
+		pScanResult = sme_scan_result_get_next(halHandle, pResult);
+	}
+
+	/* Calculate the weights for all channels in the spectrum pSpectCh */
+	pSpectCh = pSpectInfoParams->pSpectCh;
+
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Spectrum Channels Weight", __func__);
+
+	for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans);
+	     chn_num++) {
+
+		/*
+		   rssi : Maximum received signal strength among all BSS on that channel
+		   bssCount : Number of BSS on that channel
+		 */
+
+		rssi = (int8_t) pSpectCh->rssiAgr;
+		if (ch_in_pcl(sap_ctx, chn_num))
+			rssi -= PCL_RSSI_DISCOUNT;
+
+		pSpectCh->weight =
+			SAPDFS_NORMALISE_1000 * sapweight_rssi_count(rssi,
+								     pSpectCh->
+								     bssCount);
+		pSpectCh->weight_copy = pSpectCh->weight;
+
+		/* ------ Debug Info ------ */
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d",
+			  __func__, pSpectCh->chNum, pSpectCh->weight,
+			  pSpectCh->rssiAgr, pSpectCh->bssCount);
+		/* ------ Debug Info ------ */
+		pSpectCh++;
+	}
+	cdf_mem_free(pBeaconStruct);
+}
+
+/*==========================================================================
+   FUNCTION    sap_chan_sel_exit
+
+   DESCRIPTION
+    Exit function for free out the allocated memory, to be called
+    at the end of the dfsSelectChannel function
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+void sap_chan_sel_exit(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	/* Free all the allocated memory */
+	cdf_mem_free(pSpectInfoParams->pSpectCh);
+}
+
+/*==========================================================================
+   FUNCTION    sap_sort_chl_weight
+
+   DESCRIPTION
+    Funtion to sort the channels with the least weight first for 20MHz channels
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+void sap_sort_chl_weight(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	tSapSpectChInfo temp;
+
+	tSapSpectChInfo *pSpectCh = NULL;
+	uint32_t i = 0, j = 0, minWeightIndex = 0;
+
+	pSpectCh = pSpectInfoParams->pSpectCh;
+	for (i = 0; i < pSpectInfoParams->numSpectChans; i++) {
+		minWeightIndex = i;
+		for (j = i + 1; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectCh[j].weight <
+			    pSpectCh[minWeightIndex].weight) {
+				minWeightIndex = j;
+			}
+		}
+		if (minWeightIndex != i) {
+			cdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
+				     sizeof(*pSpectCh));
+			cdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
+				     sizeof(*pSpectCh));
+			cdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
+		}
+	}
+}
+
+/**
+ * sap_sort_chl_weight_ht80() - to sort the channels with the least weight
+ * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Funtion to sort the channels with the least weight first for HT80 channels
+ *
+ * Return: none
+ */
+void sap_sort_chl_weight_ht80(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	uint8_t i, j, n;
+	tSapSpectChInfo *pSpectInfo;
+	uint8_t minIdx;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/* for each HT80 channel, calculate the combined weight of the
+	   four 20MHz weight */
+	for (i = 0; i < ARRAY_SIZE(acs_ht80_channels); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+					acs_ht80_channels[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		if (!(((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) &&
+			((pSpectInfo[j].chNum + 8) ==
+				 pSpectInfo[j + 2].chNum) &&
+			((pSpectInfo[j].chNum + 12) ==
+				 pSpectInfo[j + 3].chNum))) {
+			/*
+			 * some channels does not exist in pSectInfo array,
+			 * skip this channel and those in the same HT80 width
+			 */
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
+			if ((pSpectInfo[j].chNum + 4) ==
+					pSpectInfo[j + 1].chNum)
+				pSpectInfo[j + 1].weight =
+					SAP_ACS_WEIGHT_MAX * 4;
+			if ((pSpectInfo[j].chNum + 8) ==
+					pSpectInfo[j + 2].chNum)
+				pSpectInfo[j + 2].weight =
+					SAP_ACS_WEIGHT_MAX * 4;
+			if ((pSpectInfo[j].chNum + 12) ==
+					pSpectInfo[j + 3].chNum)
+				pSpectInfo[j + 3].weight =
+					SAP_ACS_WEIGHT_MAX * 4;
+			continue;
+		}
+		/*found the channel, add the 4 adjacent channels' weight */
+		acs_ht80_channels[i].weight = pSpectInfo[j].weight +
+			pSpectInfo[j + 1].weight + pSpectInfo[j + 2].weight +
+			pSpectInfo[j + 3].weight;
+		/* find best channel among 4 channels as the primary channel */
+		if ((pSpectInfo[j].weight + pSpectInfo[j + 1].weight) <
+			(pSpectInfo[j + 2].weight + pSpectInfo[j + 3].weight)) {
+			/* lower 2 channels are better choice */
+			if (pSpectInfo[j].weight < pSpectInfo[j + 1].weight)
+				minIdx = 0;
+			else
+				minIdx = 1;
+		} else if (pSpectInfo[j + 2].weight <=
+				pSpectInfo[j + 3].weight) {
+			/* upper 2 channels are better choice */
+			minIdx = 2;
+		} else {
+			minIdx = 3;
+		}
+
+		/*
+		 * set all 4 channels to max value first, then reset the
+		 * best channel as the selected primary channel, update its
+		 * weightage with the combined weight value
+		 */
+		for (n = 0; n < 4; n++)
+			pSpectInfo[j + n].weight = SAP_ACS_WEIGHT_MAX * 4;
+
+		pSpectInfo[j + minIdx].weight = acs_ht80_channels[i].weight;
+	}
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+		if (CHANNEL_165 == pSpectInfo[j].chNum) {
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 4;
+			break;
+		}
+	}
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			FL("Channel=%d Weight= %d rssi=%d bssCount=%d"),
+			pSpectInfo->chNum, pSpectInfo->weight,
+			pSpectInfo->rssiAgr, pSpectInfo->bssCount);
+		pSpectInfo++;
+	}
+}
+
+/**
+ * sap_sort_chl_weight_ht40_24_g() - to sort channel with the least weight
+ * @pSpectInfoParams: Pointer to the tSapChSelSpectInfo structure
+ *
+ * Funtion to sort the channels with the least weight first for HT40 channels
+ *
+ * Return: none
+ */
+void sap_sort_chl_weight_ht40_24_g(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	uint8_t i, j;
+	tSapSpectChInfo *pSpectInfo;
+	uint32_t tmpWeight1, tmpWeight2;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/*
+	 * for each HT40 channel, calculate the combined weight of the
+	 * two 20MHz weight
+	 */
+	for (i = 0; i < ARRAY_SIZE(acs_ht40_channels24_g); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+				acs_ht40_channels24_g[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		if (!((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 4].chNum)) {
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+			continue;
+		}
+		/*
+		 * check if there is another channel combination possiblity
+		 * e.g., {1, 5} & {5, 9}
+		 */
+		if ((pSpectInfo[j + 4].chNum + 4) == pSpectInfo[j + 8].chNum) {
+			/* need to compare two channel pairs */
+			tmpWeight1 = pSpectInfo[j].weight +
+						pSpectInfo[j + 4].weight;
+			tmpWeight2 = pSpectInfo[j + 4].weight +
+						pSpectInfo[j + 8].weight;
+			if (tmpWeight1 <= tmpWeight2) {
+				if (pSpectInfo[j].weight <=
+						pSpectInfo[j + 4].weight) {
+					pSpectInfo[j].weight =
+						tmpWeight1;
+					pSpectInfo[j + 4].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+					pSpectInfo[j + 8].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+				} else {
+					pSpectInfo[j + 4].weight =
+						tmpWeight1;
+					/* for secondary channel selection */
+					pSpectInfo[j].weight =
+						SAP_ACS_WEIGHT_MAX * 2
+						- 1;
+					pSpectInfo[j + 8].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+				}
+			} else {
+				if (pSpectInfo[j + 4].weight <=
+						pSpectInfo[j + 8].weight) {
+					pSpectInfo[j + 4].weight =
+						tmpWeight2;
+					pSpectInfo[j].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+					/* for secondary channel selection */
+					pSpectInfo[j + 8].weight =
+						SAP_ACS_WEIGHT_MAX * 2
+						- 1;
+				} else {
+					pSpectInfo[j + 8].weight =
+						tmpWeight2;
+					pSpectInfo[j].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+					pSpectInfo[j + 4].weight =
+						SAP_ACS_WEIGHT_MAX * 2;
+				}
+			}
+		} else {
+			tmpWeight1 = pSpectInfo[j].weight +
+						pSpectInfo[j + 4].weight;
+			if (pSpectInfo[j].weight <=
+					pSpectInfo[j + 4].weight) {
+				pSpectInfo[j].weight = tmpWeight1;
+				pSpectInfo[j + 4].weight =
+					SAP_ACS_WEIGHT_MAX * 2;
+			} else {
+				pSpectInfo[j + 4].weight = tmpWeight1;
+				pSpectInfo[j].weight =
+					SAP_ACS_WEIGHT_MAX * 2;
+			}
+		}
+	}
+}
+
+/*==========================================================================
+   FUNCTION    sap_sort_chl_weight_ht40_5_g
+
+   DESCRIPTION
+    Funtion to sort the channels with the least weight first for HT40 channels
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+void sap_sort_chl_weight_ht40_5_g(tSapChSelSpectInfo *pSpectInfoParams)
+{
+	uint8_t i, j;
+	tSapSpectChInfo *pSpectInfo;
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	/*for each HT40 channel, calculate the combined weight of the
+	   two 20MHz weight */
+	for (i = 0; i < ARRAY_SIZE(acs_ht40_channels5_g); i++) {
+		for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+			if (pSpectInfo[j].chNum ==
+			    acs_ht40_channels5_g[i].chStartNum)
+				break;
+		}
+		if (j == pSpectInfoParams->numSpectChans)
+			continue;
+
+		/* found the channel, add the two adjacent channels' weight */
+		if ((pSpectInfo[j].chNum + 4) == pSpectInfo[j + 1].chNum) {
+			acs_ht40_channels5_g[i].weight = pSpectInfo[j].weight +
+						      pSpectInfo[j + 1].weight;
+			/* select better of the adjact channel as the primary channel */
+			if (pSpectInfo[j].weight <= pSpectInfo[j + 1].weight) {
+				pSpectInfo[j].weight =
+					acs_ht40_channels5_g[i].weight;
+				/* mark the adjacent channel's weight as max value so
+				   that it will be sorted to the bottom */
+				pSpectInfo[j + 1].weight =
+					SAP_ACS_WEIGHT_MAX * 2;
+			} else {
+				pSpectInfo[j + 1].weight =
+					acs_ht40_channels5_g[i].weight;
+				/* mark the adjacent channel's weight as max value so
+				   that it will be sorted to the bottom */
+				pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+			}
+
+		} else
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+	}
+
+	/* avoid channel 165 by setting its weight to max */
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
+		if (CHANNEL_165 == pSpectInfo[j].chNum) {
+			pSpectInfo[j].weight = SAP_ACS_WEIGHT_MAX * 2;
+			break;
+		}
+	}
+
+	pSpectInfo = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
+			  __func__, pSpectInfo->chNum, pSpectInfo->weight,
+			  pSpectInfo->rssiAgr, pSpectInfo->bssCount);
+		pSpectInfo++;
+	}
+
+	sap_sort_chl_weight(pSpectInfoParams);
+}
+
+/*==========================================================================
+   FUNCTION    sap_sort_chl_weight_all
+
+   DESCRIPTION
+    Funtion to sort the channels with the least weight first
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    ptSapContext           : Pointer to the ptSapContext structure
+    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure
+
+   RETURN VALUE
+    void     : NULL
+
+   SIDE EFFECTS
+   ============================================================================*/
+void sap_sort_chl_weight_all(ptSapContext pSapCtx,
+			     tSapChSelSpectInfo *pSpectInfoParams,
+			     uint32_t operatingBand)
+{
+	tSapSpectChInfo *pSpectCh = NULL;
+	uint32_t j = 0;
+#ifndef SOFTAP_CHANNEL_RANGE
+	uint32_t i = 0;
+#endif
+
+	pSpectCh = pSpectInfoParams->pSpectCh;
+#ifdef SOFTAP_CHANNEL_RANGE
+
+	switch (pSapCtx->acs_cfg->ch_width) {
+	case CH_WIDTH_40MHZ:
+		if (eCSR_DOT11_MODE_11g == operatingBand)
+			sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
+		else if (eCSR_DOT11_MODE_11a == operatingBand)
+			sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
+		else {
+			sap_sort_chl_weight_ht40_24_g(pSpectInfoParams);
+			sap_sort_chl_weight_ht40_5_g(pSpectInfoParams);
+		}
+		sap_sort_chl_weight(pSpectInfoParams);
+		break;
+
+	case CH_WIDTH_80MHZ:
+		sap_sort_chl_weight_ht80(pSpectInfoParams);
+		break;
+
+	case CH_WIDTH_20MHZ:
+	default:
+		/* Sorting the channels as per weights as 20MHz channels */
+		sap_sort_chl_weight(pSpectInfoParams);
+	}
+
+#else
+	/* Sorting the channels as per weights */
+	for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) {
+		minWeightIndex = i;
+		for (j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) {
+			if (pSpectCh[j].weight <
+			    pSpectCh[minWeightIndex].weight) {
+				minWeightIndex = j;
+			}
+		}
+		if (minWeightIndex != i) {
+			cdf_mem_copy(&temp, &pSpectCh[minWeightIndex],
+				     sizeof(*pSpectCh));
+			cdf_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
+				     sizeof(*pSpectCh));
+			cdf_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
+		}
+	}
+#endif
+
+	/* For testing */
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Sorted Spectrum Channels Weight", __func__);
+	pSpectCh = pSpectInfoParams->pSpectCh;
+	for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			  "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
+			  __func__, pSpectCh->chNum, pSpectCh->weight,
+			  pSpectCh->rssiAgr, pSpectCh->bssCount);
+		pSpectCh++;
+	}
+
+}
+
+/*==========================================================================
+   FUNCTION    sap_filter_over_lap_ch
+
+   DESCRIPTION
+    return true if ch is acceptable.
+    This function will decide if we will filter over lap channel or not.
+
+   DEPENDENCIES
+    shall called after ap start.
+
+   PARAMETERS
+
+   IN
+    pSapCtx          : Pointer to ptSapContext.
+    chNum             : Filter channel number.
+
+   RETURN VALUE
+    bool          : true if channel is accepted.
+
+   SIDE EFFECTS
+   ============================================================================*/
+bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
+{
+	if (pSapCtx->enableOverLapCh)
+		return eSAP_TRUE;
+	else if ((chNum == CHANNEL_1) ||
+		 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
+		return eSAP_TRUE;
+
+	return eSAP_FALSE;
+}
+
+/*==========================================================================
+   FUNCTION    sap_select_channel
+
+   DESCRIPTION
+    Runs a algorithm to select the best channel to operate in based on BSS
+    rssi and bss count on each channel
+
+   DEPENDENCIES
+    NA.
+
+   PARAMETERS
+
+    IN
+    halHandle       : Pointer to HAL handle
+    pResult         : Pointer to tScanResultHandle
+
+   RETURN VALUE
+    uint8_t          : Success - channel number, Fail - zero
+
+   SIDE EFFECTS
+   ============================================================================*/
+uint8_t sap_select_channel(tHalHandle halHandle, ptSapContext pSapCtx,
+			   tScanResultHandle pScanResult)
+{
+	/* DFS param object holding all the data req by the algo */
+	tSapChSelSpectInfo oSpectInfoParams = { NULL, 0 };
+	tSapChSelSpectInfo *pSpectInfoParams = &oSpectInfoParams;       /* Memory? NB */
+	uint8_t bestChNum = SAP_CHANNEL_NOT_SELECTED;
+#ifdef FEATURE_WLAN_CH_AVOID
+	uint8_t i;
+	uint8_t firstSafeChannelInRange = SAP_CHANNEL_NOT_SELECTED;
+#endif
+#ifdef SOFTAP_CHANNEL_RANGE
+	uint32_t startChannelNum;
+	uint32_t endChannelNum;
+	uint32_t operatingBand = 0;
+	uint32_t tmpChNum;
+	uint8_t count;
+#endif
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "In %s, Running SAP Ch Select", __func__);
+
+#ifdef FEATURE_WLAN_CH_AVOID
+	sap_update_unsafe_channel_list(pSapCtx);
+#endif
+
+	if (NULL == pScanResult) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: No external AP present\n", __func__);
+
+#ifndef SOFTAP_CHANNEL_RANGE
+		return bestChNum;
+#else
+		startChannelNum = pSapCtx->acs_cfg->start_ch;
+		endChannelNum = pSapCtx->acs_cfg->end_ch;
+
+
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: start - end: %d - %d\n", __func__,
+			  startChannelNum, endChannelNum);
+
+#ifndef FEATURE_WLAN_CH_AVOID   /* FEATURE_WLAN_CH_AVOID NOT defined case */
+		pSapCtx->acs_cfg->pri_ch = startChannelNum;
+		pSapCtx->acs_cfg->ht_sec_ch = 0;
+		/* pick the first channel in configured range */
+		return startChannelNum;
+#else                           /* FEATURE_WLAN_CH_AVOID defined */
+
+		/* get a channel in PCL and within the range */
+		for (i = 0; i < pSapCtx->acs_cfg->pcl_ch_count; i++) {
+			if ((pSapCtx->acs_cfg->pcl_channels[i] >=
+							startChannelNum)
+				&& (pSapCtx->acs_cfg->pcl_channels[i] <=
+							endChannelNum)) {
+				firstSafeChannelInRange =
+					pSapCtx->acs_cfg->pcl_channels[i];
+				break;
+			}
+		}
+		if (SAP_CHANNEL_NOT_SELECTED != firstSafeChannelInRange)
+			return firstSafeChannelInRange;
+
+		for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
+			if ((safe_channels[i].channelNumber >= startChannelNum)
+			    && (safe_channels[i].channelNumber <=
+				endChannelNum)) {
+				CHANNEL_STATE channel_type =
+					cds_get_channel_state(safe_channels[i].
+						channelNumber);
+
+				if ((channel_type == CHANNEL_STATE_DISABLE) ||
+					(channel_type == CHANNEL_STATE_INVALID))
+					continue;
+
+				if (safe_channels[i].isSafe == true) {
+					CDF_TRACE(CDF_MODULE_ID_SAP,
+						  CDF_TRACE_LEVEL_INFO_HIGH,
+						  "%s: channel %d in the configuration is safe\n",
+						  __func__,
+						  safe_channels[i].
+						  channelNumber);
+					firstSafeChannelInRange =
+						safe_channels[i].channelNumber;
+					break;
+				}
+
+				CDF_TRACE(CDF_MODULE_ID_SAP,
+					  CDF_TRACE_LEVEL_INFO_HIGH,
+					  "%s: channel %d in the configuration is unsafe\n",
+					  __func__,
+					  safe_channels[i].channelNumber);
+			}
+		}
+
+		/* if no channel selected return SAP_CHANNEL_NOT_SELECTED */
+		return firstSafeChannelInRange;
+#endif /* !FEATURE_WLAN_CH_AVOID */
+#endif /* SOFTAP_CHANNEL_RANGE */
+	}
+
+	/* Initialize the structure pointed by pSpectInfoParams */
+	if (sap_chan_sel_init(halHandle, pSpectInfoParams, pSapCtx) != eSAP_TRUE) {
+		CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR,
+			  "In %s, Ch Select initialization failed", __func__);
+		return SAP_CHANNEL_NOT_SELECTED;
+	}
+	/* Compute the weight of the entire spectrum in the operating band */
+	sap_compute_spect_weight(pSpectInfoParams, halHandle, pScanResult,
+								pSapCtx);
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+	/* process avoid channel IE to collect all channels to avoid */
+	sap_process_avoid_ie(halHandle, pSapCtx, pScanResult, pSpectInfoParams);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+#ifdef SOFTAP_CHANNEL_RANGE
+	startChannelNum = pSapCtx->acs_cfg->start_ch;
+	endChannelNum = pSapCtx->acs_cfg->end_ch;
+	SET_ACS_BAND(operatingBand, pSapCtx);
+
+	pSapCtx->acsBestChannelInfo.channelNum = 0;
+	pSapCtx->acsBestChannelInfo.weight = SAP_ACS_WEIGHT_MAX;
+
+	/* Sort the channel list as per the computed weights, lesser weight first. */
+	sap_sort_chl_weight_all(pSapCtx, pSpectInfoParams, operatingBand);
+
+	/*Loop till get the best channel in the given range */
+	for (count = 0; count < pSpectInfoParams->numSpectChans; count++) {
+		if ((startChannelNum <= pSpectInfoParams->pSpectCh[count].chNum)
+		    && (endChannelNum >=
+			pSpectInfoParams->pSpectCh[count].chNum)) {
+			if (bestChNum == SAP_CHANNEL_NOT_SELECTED) {
+				bestChNum =
+					pSpectInfoParams->pSpectCh[count].chNum;
+				/* check if bestChNum is in preferred channel list */
+				bestChNum =
+					sap_select_preferred_channel_from_channel_list
+						(bestChNum, pSapCtx, pSpectInfoParams);
+				if (bestChNum == SAP_CHANNEL_NOT_SELECTED) {
+					/* not in preferred channel list, go to next best channel */
+					continue;
+				}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+				/* Weight of the channels(device's AP is
+				 * operating) increased to MAX+1 so that they
+				 * will be choosen only when there is no other
+				 * best channel to choose
+				 */
+				if (sap_check_in_avoid_ch_list(pSapCtx,
+								bestChNum)) {
+					bestChNum = SAP_CHANNEL_NOT_SELECTED;
+					continue;
+				}
+#endif
+
+				pSapCtx->acsBestChannelInfo.channelNum =
+								bestChNum;
+				pSapCtx->acsBestChannelInfo.weight =
+							pSpectInfoParams->
+							pSpectCh[count].
+							weight_copy;
+			}
+
+			if (bestChNum != SAP_CHANNEL_NOT_SELECTED) {
+				if (operatingBand == eCSR_DOT11_MODE_11g) {
+					/* Give preference to Non-overlap channels */
+					if (sap_filter_over_lap_ch(pSapCtx,
+								   pSpectInfoParams->
+								   pSpectCh[count].
+								   chNum)) {
+						tmpChNum =
+							pSpectInfoParams->
+							pSpectCh[count].chNum;
+						tmpChNum =
+							sap_select_preferred_channel_from_channel_list
+								(tmpChNum, pSapCtx,
+								pSpectInfoParams);
+						if (tmpChNum !=
+						    SAP_CHANNEL_NOT_SELECTED) {
+							bestChNum = tmpChNum;
+							break;
+						}
+					}
+				}
+			}
+		}
+	}
+#else
+	/* Sort the channel list as per the computed weights, lesser weight first. */
+	sap_sort_chl_weight_all(pSapCtx, halHandle, pSpectInfoParams);
+	/* Get the first channel in sorted array as best 20M Channel */
+	bestChNum = (uint8_t) pSpectInfoParams->pSpectCh[0].chNum;
+	/* Select Best Channel from Channel List if Configured */
+	bestChNum = sap_select_preferred_channel_from_channel_list(bestChNum,
+								   pSapCtx,
+								   pSpectInfoParams);
+#endif
+
+	/** in case the best channel seleted is not in PCL and there is another
+	 * channel which has same weightage and is in PCL, choose the one in
+	 * PCL
+	 */
+	for (count = 0; count < pSpectInfoParams->numSpectChans; count++) {
+		/** check if a pcl channel has the same weightage
+		 * as the best channel
+		 */
+		if (ch_in_pcl(pSapCtx, pSpectInfoParams->pSpectCh[count].chNum)
+			&& (pSpectInfoParams->pSpectCh[count].weight ==
+			pSapCtx->acsBestChannelInfo.weight)) {
+			if (sap_select_preferred_channel_from_channel_list(
+				pSpectInfoParams->pSpectCh[count].chNum,
+				pSapCtx, pSpectInfoParams) ==
+						SAP_CHANNEL_NOT_SELECTED)
+				continue;
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+			if (sap_check_in_avoid_ch_list(pSapCtx, bestChNum))
+				continue;
+#endif
+			bestChNum = pSpectInfoParams->pSpectCh[count].chNum;
+			CDF_TRACE(CDF_MODULE_ID_SAP,
+					CDF_TRACE_LEVEL_INFO_HIGH,
+					"change best channel to %d in PCL",
+					bestChNum);
+			break;
+		}
+	}
+
+	pSapCtx->acs_cfg->pri_ch = bestChNum;
+	/* determine secondary channel for 2.4G channel 5, 6, 7 in HT40 */
+	if ((operatingBand == eCSR_DOT11_MODE_11g) &&
+			(pSapCtx->acs_cfg->ch_width == CH_WIDTH_40MHZ)) {
+		if ((bestChNum >= 5) && (bestChNum <= 7)) {
+			int weight_below, weight_above, i;
+			tSapSpectChInfo *pspect_info;
+
+			weight_below = weight_above = SAP_ACS_WEIGHT_MAX;
+			pspect_info = pSpectInfoParams->pSpectCh;
+			for (i = 0; i < pSpectInfoParams->numSpectChans;
+									i++) {
+				if (pspect_info[i].chNum == (bestChNum - 4))
+					weight_below = pspect_info[i].weight;
+
+				if (pspect_info[i].chNum == (bestChNum + 4))
+					weight_above = pspect_info[i].weight;
+			}
+
+			if (weight_below < weight_above)
+				pSapCtx->acs_cfg->ht_sec_ch =
+						pSapCtx->acs_cfg->pri_ch - 4;
+			else
+				pSapCtx->acs_cfg->ht_sec_ch =
+						pSapCtx->acs_cfg->pri_ch + 4;
+		} else if (bestChNum >= 1 && bestChNum <= 4) {
+			pSapCtx->acs_cfg->ht_sec_ch =
+						pSapCtx->acs_cfg->pri_ch + 4;
+		} else if (bestChNum >= 8 && bestChNum <= 13) {
+			pSapCtx->acs_cfg->ht_sec_ch =
+						pSapCtx->acs_cfg->pri_ch - 4;
+		} else if (bestChNum == 14) {
+			pSapCtx->acs_cfg->ht_sec_ch = 0;
+		}
+		pSapCtx->secondary_ch = pSapCtx->acs_cfg->ht_sec_ch;
+	}
+	/* Free all the allocated memory */
+	sap_chan_sel_exit(pSpectInfoParams);
+
+	CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO_HIGH,
+		"In %s, Running SAP Ch select Completed, Ch=%d", __func__,
+		bestChNum);
+	if (bestChNum > 0 && bestChNum <= 252)
+		return bestChNum;
+	else
+		return SAP_CHANNEL_NOT_SELECTED;
+}