/*
 * Copyright (c) 2012-2017 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.
===========================================================================*/

/*===========================================================================

                      EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.



  when        who       what, where, why
----------    ---       --------------------------------------------------------
2010-03-15  SOFTAP      Created module

===========================================================================*/


/*--------------------------------------------------------------------------
  Include Files
------------------------------------------------------------------------*/
#include "vos_trace.h"
#include "csrApi.h"
#include "sme_Api.h"
#include "sapChSelect.h"
#include "sapInternal.h"
#ifdef ANI_OS_TYPE_QNX
#include "stdio.h"
#endif
#include "wlan_hdd_main.h"

#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
#include "limUtils.h"
#include "parserApi.h"
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */

/*--------------------------------------------------------------------------
  Function definitions
--------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------
  Defines
--------------------------------------------------------------------------*/
#define SAP_DEBUG

#define IS_RSSI_VALID( extRssi, rssi ) \
( \
   ((extRssi < rssi)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_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 \
        acs_band = eCSR_DOT11_MODE_11a;\
}

#define ACS_WEIGHT_AMOUNT_LOCAL    240

#define ACS_WEIGHT_AMOUNT_CONFIG(weights) \
	(((weights) & 0xf) + \
	(((weights) & 0xf0) >> 4) + \
	(((weights) & 0xf00) >> 8) + \
	(((weights) & 0xf000) >> 12) + \
	(((weights) & 0xf0000) >> 16) + \
	(((weights) & 0xf00000) >> 20))

/*
 * LSH/RSH 4 to enhance the accurate since
 * need to do modulation to ACS_WEIGHT_AMOUNT_LOCAL.
 */
#define ACS_WEIGHT_COMPUTE(weights, weight, factor, base) \
	(((((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL * (factor)) + \
	(ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
	ACS_WEIGHT_AMOUNT_CONFIG((weights))) + \
	((base) >> 1)) / (base)) + 8) >> 4)

#define ACS_WEIGHT_CFG_TO_LOCAL(weights, weight) \
	(((((((weight) << 4) * ACS_WEIGHT_AMOUNT_LOCAL) + \
	(ACS_WEIGHT_AMOUNT_CONFIG((weights)) >> 1)) / \
	ACS_WEIGHT_AMOUNT_CONFIG((weights))) + 8) >> 4)

#define ACS_WEIGHT_SOFTAP_RSSI_CFG(weights) \
	((weights) & 0xf)

#define ACS_WEIGHT_SOFTAP_COUNT_CFG(weights) \
	(((weights) & 0xf0) >> 4)

#define ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG(weights) \
	(((weights) & 0xf00) >> 8)

#define ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG(weights) \
	(((weights) & 0xf000) >> 12)

#define ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG(weights) \
	(((weights) & 0xf0000) >> 16)

#define ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG(weights) \
	(((weights) & 0xf00000) >> 20)

#ifdef FEATURE_WLAN_CH_AVOID
sapSafeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] =
{
  /*CH  , SAFE, default safe */
    {1  , VOS_TRUE},      //RF_CHAN_1,
    {2  , VOS_TRUE},      //RF_CHAN_2,
    {3  , VOS_TRUE},      //RF_CHAN_3,
    {4  , VOS_TRUE},      //RF_CHAN_4,
    {5  , VOS_TRUE},      //RF_CHAN_5,
    {6  , VOS_TRUE},      //RF_CHAN_6,
    {7  , VOS_TRUE},      //RF_CHAN_7,
    {8  , VOS_TRUE},      //RF_CHAN_8,
    {9  , VOS_TRUE},      //RF_CHAN_9,
    {10 , VOS_TRUE},      //RF_CHAN_10,
    {11 , VOS_TRUE},      //RF_CHAN_11,
    {12 , VOS_TRUE},      //RF_CHAN_12,
    {13 , VOS_TRUE},      //RF_CHAN_13,
    {14 , VOS_TRUE},      //RF_CHAN_14,
    {36 , VOS_TRUE},      //RF_CHAN_36,
    {40 , VOS_TRUE},      //RF_CHAN_40,
    {44 , VOS_TRUE},      //RF_CHAN_44,
    {48 , VOS_TRUE},      //RF_CHAN_48,
    {52 , VOS_TRUE},      //RF_CHAN_52,
    {56 , VOS_TRUE},      //RF_CHAN_56,
    {60 , VOS_TRUE},      //RF_CHAN_60,
    {64 , VOS_TRUE},      //RF_CHAN_64,
    {100, VOS_TRUE},      //RF_CHAN_100,
    {104, VOS_TRUE},      //RF_CHAN_104,
    {108, VOS_TRUE},      //RF_CHAN_108,
    {112, VOS_TRUE},      //RF_CHAN_112,
    {116, VOS_TRUE},      //RF_CHAN_116,
    {120, VOS_TRUE},      //RF_CHAN_120,
    {124, VOS_TRUE},      //RF_CHAN_124,
    {128, VOS_TRUE},      //RF_CHAN_128,
    {132, VOS_TRUE},      //RF_CHAN_132,
    {136, VOS_TRUE},      //RF_CHAN_136,
    {140, VOS_TRUE},      //RF_CHAN_140,
#ifdef FEATURE_WLAN_CH144
    {144, VOS_TRUE},      //RF_CHAN_144,
#endif
    {149, VOS_TRUE},      //RF_CHAN_149,
    {153, VOS_TRUE},      //RF_CHAN_153,
    {157, VOS_TRUE},      //RF_CHAN_157,
    {161, VOS_TRUE},      //RF_CHAN_161,
    {165, VOS_TRUE},      //RF_CHAN_165,
};
#endif

typedef struct
{
    v_U16_t chStartNum;
    v_U32_t weight;
} sapAcsChannelInfo;

#define ACS_WEIGHT_MAX     26664

sapAcsChannelInfo acsHT40Channels5G[ ] = {
    {36,   ACS_WEIGHT_MAX},
    {44,   ACS_WEIGHT_MAX},
    {52,   ACS_WEIGHT_MAX},
    {60,   ACS_WEIGHT_MAX},
    {100,  ACS_WEIGHT_MAX},
    {108,  ACS_WEIGHT_MAX},
    {116,  ACS_WEIGHT_MAX},
    {124,  ACS_WEIGHT_MAX},
    {132,  ACS_WEIGHT_MAX},
    {140,  ACS_WEIGHT_MAX},
    {149,  ACS_WEIGHT_MAX},
    {157,  ACS_WEIGHT_MAX},
};

sapAcsChannelInfo acsHT80Channels[ ] = {
    {36,   ACS_WEIGHT_MAX},
    {52,   ACS_WEIGHT_MAX},
    {100,  ACS_WEIGHT_MAX},
    {116,  ACS_WEIGHT_MAX},
    {132,  ACS_WEIGHT_MAX},
    {149,  ACS_WEIGHT_MAX},
};

sapAcsChannelInfo acsHT40Channels24G[ ] = {
    {1,    ACS_WEIGHT_MAX},
    {2,    ACS_WEIGHT_MAX},
    {3,    ACS_WEIGHT_MAX},
    {4,    ACS_WEIGHT_MAX},
    {9,    ACS_WEIGHT_MAX},
};

#define CHANNEL_165  165

#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_ScanResultGetFirst(hal, scan_result);

	while (node) {
		total_ie_len = GET_IE_LEN_IN_BSS(node->BssDescriptor.length);
		temp_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
				SIR_MAC_QCOM_VENDOR_OUI,
				SIR_MAC_QCOM_VENDOR_SIZE,
				((tANI_U8 *)&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) {
				node = sme_ScanResultGetNext(hal, scan_result);
				continue;
			}
			sap_ctx->sap_detected_avoid_ch_ie.present = 1;
			VOS_TRACE(VOS_MODULE_ID_SAP,
				  VOS_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 = ACS_WEIGHT_MAX + 1;
					spect_ch[i].weight_copy =
							ACS_WEIGHT_MAX + 1;
					break;
				}
			}
		} /* if (temp_ptr) */
		node = sme_ScanResultGetNext(hal, scan_result);
	}
}
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */

#ifdef FEATURE_WLAN_CH_AVOID
/*==========================================================================
  FUNCTION    sapUpdateUnsafeChannelList

  DESCRIPTION
    Function  Undate unsafe channel list table

  DEPENDENCIES
    NA.

  IN
    SapContext pointer

  RETURN VALUE
    NULL
============================================================================*/
void sapUpdateUnsafeChannelList(ptSapContext pSapCtx)
{
   v_U16_t   i, j;

   v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL);
   struct hdd_context_s *hdd_ctxt;

   if (NULL == pvosGCtx)
   {
       VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
                  "VOSS Global Context is NULL");
       return ;
   }

   hdd_ctxt = (struct hdd_context_s *) vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);

   if (NULL == hdd_ctxt)
   {
       VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
                  "HDD Context is NULL");
       return ;
   }

   /* Flush, default set all channel safe */
   for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
   {
      safeChannels[i].isSafe = VOS_TRUE;
   }

   /* Try to find unsafe channel */
#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
   for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) {
        if (pSapCtx->dfs_ch_disable == VOS_TRUE) {
            if (VOS_IS_DFS_CH(safeChannels[i].channelNumber)) {
                safeChannels[i].isSafe = VOS_FALSE;
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                    "%s: DFS Ch %d is not safe in Concurrent mode", __func__,
                    safeChannels[i].channelNumber);
           }
        }
    }
#endif

   for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++)
   {
      for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++)
      {
         if(safeChannels[j].channelNumber == hdd_ctxt->unsafe_channel_list[i])
         {
            /* Found unsafe channel, update it */
            safeChannels[j].isSafe = VOS_FALSE;
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                      "%s : CH %d is not safe",
                      __func__, hdd_ctxt->unsafe_channel_list[i]);
            break;
         }
      }
   }

   return;
}

#endif /* FEATURE_WLAN_CH_AVOID */

/*==========================================================================
  FUNCTION    sapCleanupChannelList

  DESCRIPTION
    Function sapCleanupChannelList frees up the memory allocated to the channel list.

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
    NULL

  RETURN VALUE
    NULL
============================================================================*/

void sapCleanupChannelList(v_PVOID_t pvosGCtx)
{
    ptSapContext pSapCtx;

    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
               "Cleaning up the channel list structure");

    if (NULL == pvosGCtx)
    {
        VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
                   "SAP Global Context is NULL");
        return ;
    }

	pSapCtx = VOS_GET_SAP_CB(pvosGCtx);
    if (NULL == pSapCtx)
    {
        VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL,
                   "SAP Context is NULL");
        return ;
    }

    pSapCtx->SapChnlList.numChannel = 0;
    if (pSapCtx->SapChnlList.channelList) {
        vos_mem_free(pSapCtx->SapChnlList.channelList);
        pSapCtx->SapChnlList.channelList = NULL;
    }

    pSapCtx->SapAllChnlList.numChannel = 0;
    if (pSapCtx->SapAllChnlList.channelList) {
        vos_mem_free(pSapCtx->SapAllChnlList.channelList);
        pSapCtx->SapAllChnlList.channelList = NULL;
    }
}

/**
 * sap_channel_in_acs_channel_list() - check if channel in acs channel list
 * @channel_num: channel to check
 * @sap_ctx: struct ptSapContext
 * @spect_info_params: strcut tSapChSelSpectInfo
 *
 * This function checks if specified channel is in the configured ACS channel
 * list.
 *
 * Return: channel number if in acs channel list or SAP_CHANNEL_NOT_SELECTED
 */
uint8_t sap_channel_in_acs_channel_list(uint8_t channel_num,
                                        ptSapContext sap_ctx,
                                        tSapChSelSpectInfo *spect_info_params)
{
	uint8_t i = 0;

	if ((NULL == sap_ctx->acs_cfg->ch_list) ||
	    (NULL == spect_info_params))
		return channel_num;

	if (channel_num > 0 && channel_num <= 252) {
		for (i = 0; i < sap_ctx->acs_cfg->ch_list_count; i++) {
			if ((sap_ctx->acs_cfg->ch_list[i]) == channel_num)
				return channel_num;
		}
		return SAP_CHANNEL_NOT_SELECTED;
	} else {
		return SAP_CHANNEL_NOT_SELECTED;
	}
}

/*==========================================================================
  FUNCTION    sapSelectPreferredChannelFromChannelList

  DESCRIPTION
    Function sapSelectPreferredChannelFromChannelList 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.

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
    *pSpectInfoParams  : Pointer to tSapChSelSpectInfo structure
    bestChNum: best channel already calculated among all the chanels
    pSapCtx: having info of channel list from which best channel is selected

  RETURN VALUE
    v_U8_t:  best channel
============================================================================*/
v_U8_t sapSelectPreferredChannelFromChannelList(v_U8_t bestChNum,
                                                ptSapContext pSapCtx,
                                                tSapChSelSpectInfo *pSpectInfoParams)
{
    v_U8_t j = 0;
    v_U8_t count = 0;

    //If Channel List is not Configured don't do anything
    //Else return the Best Channel from the Channel List
    if((NULL == pSapCtx->acs_cfg->ch_list) ||
       (NULL == pSpectInfoParams))
    {
        return bestChNum;
    }

    if (bestChNum > 0 && bestChNum <= 252)
    {
        for(count=0; count < pSpectInfoParams->numSpectChans ; count++)
        {
            bestChNum = (v_U8_t)pSpectInfoParams->pSpectCh[count].chNum;
            if (bestChNum == 0)
                continue;
            // Select the best channel from allowed list
            for(j=0;j < pSapCtx->acs_cfg->ch_list_count;j++)
            {
                if( (pSapCtx->acs_cfg->ch_list[j]) == bestChNum)
                {
                    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                               "Best channel computed from Channel List is: %d",
                               bestChNum);
                    return bestChNum;
                }
            }
        }

        return SAP_CHANNEL_NOT_SELECTED;
    }
    else
        return SAP_CHANNEL_NOT_SELECTED;
}


/*==========================================================================
  FUNCTION    sapChanSelInit

  DESCRIPTION
    Function sapChanSelInit 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
    v_BOOL_t:  Success or FAIL

  SIDE EFFECTS
============================================================================*/
v_BOOL_t sapChanSelInit(tHalHandle halHandle,
                        tSapChSelSpectInfo *pSpectInfoParams,
                        ptSapContext pSapCtx)
{
    tSapSpectChInfo *pSpectCh = NULL;
    v_U8_t *pChans = NULL;
    v_U16_t channelnum = 0;
    tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
    v_BOOL_t chSafe = VOS_TRUE;
#ifdef FEATURE_WLAN_CH_AVOID
    v_U16_t i;
#endif
    v_U32_t dfs_master_cap_enabled;
    v_BOOL_t include_dfs_ch = VOS_TRUE;

    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s", __func__);

    pSpectInfoParams->numSpectChans = pMac->scan.base20MHzChannels.numChannels;

    // Allocate memory for weight computation of 2.4GHz
    pSpectCh = (tSapSpectChInfo *)vos_mem_malloc((pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));

    if(pSpectCh == NULL) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                "In %s, VOS_MALLOC_ERR", __func__);
        return eSAP_FALSE;
    }

    vos_mem_zero(pSpectCh, (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh));

    // Initialize the pointers in the DfsParams to the allocated memory
    pSpectInfoParams->pSpectCh = pSpectCh;

    pChans = pMac->scan.base20MHzChannels.channelList;
#if defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
        if (pSapCtx->dfs_ch_disable == VOS_TRUE)
            include_dfs_ch = VOS_FALSE;
#endif
        ccmCfgGetInt(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
                                                     &dfs_master_cap_enabled);
        if (dfs_master_cap_enabled == 0 ||
                ACS_DFS_MODE_DISABLE == pSapCtx->dfs_mode)
            include_dfs_ch = VOS_FALSE;

    // Fill the channel number in the spectrum in the operating freq band
    for (channelnum = 0;
            channelnum < pSpectInfoParams->numSpectChans;
                channelnum++, pChans++, pSpectCh++) {
        chSafe = VOS_TRUE;

        /* check if the channel is in NOL blacklist */
        if(sapDfsIsChannelInNolList(pSapCtx, *pChans,
                        PHY_SINGLE_CHANNEL_CENTERED))
        {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                "In %s, Ch %d is in NOL list", __func__, *pChans);
            chSafe = VOS_FALSE;
            continue;
        }

        if (include_dfs_ch == VOS_FALSE) {
            if (VOS_IS_DFS_CH(*pChans)) {
                chSafe = VOS_FALSE;
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_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((safeChannels[i].channelNumber == *pChans) &&
                (VOS_FALSE == safeChannels[i].isSafe))
            {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        "In %s, Ch %d is not safe",
                          __func__, *pChans);
                chSafe = VOS_FALSE;
                break;
            }
        }
#endif /* FEATURE_WLAN_CH_AVOID */

        /* OFDM rates are not supported on channel 14 */
        if(*pChans == 14 &&
               eCSR_DOT11_MODE_11b != pSapCtx->csrRoamProfile.phyMode)
        {
            continue;
        }
        /* Skip DSRC channels */
        if (vos_is_dsrc_channel(vos_chan_to_freq(*pChans)))
            continue;

        if (VOS_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
        }
    }
    return eSAP_TRUE;
}

/*==========================================================================
  FUNCTION    sapweightRssiCount

  DESCRIPTION
    Function weightRssiCount calculates the channel weight due to rssi
         and data count(here number of BSS observed)

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
    sap_ctx     : Softap context
    rssi        : Max signal strength receieved from a BSS for the channel
    count       : Number of BSS observed in the channel

  RETURN VALUE
    v_U32_t     : Calculated channel weight based on above two

  SIDE EFFECTS
============================================================================*/
v_U32_t sapweightRssiCount(ptSapContext sap_ctx, v_S7_t rssi, v_U16_t count)
{
    v_S31_t     rssiWeight=0;
    v_S31_t     countWeight=0;
    v_U32_t     rssicountWeight=0;
    uint8_t     softap_rssi_weight_cfg, softap_count_weight_cfg;
    uint8_t     softap_rssi_weight_local, softap_count_weight_local;

    softap_rssi_weight_cfg =
        ACS_WEIGHT_SOFTAP_RSSI_CFG(sap_ctx->auto_channel_select_weight);

    softap_count_weight_cfg =
        ACS_WEIGHT_SOFTAP_COUNT_CFG(sap_ctx->auto_channel_select_weight);

    softap_rssi_weight_local =
        ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
                                softap_rssi_weight_cfg);

    softap_count_weight_local =
        ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
                                softap_count_weight_cfg);

    // Weight from RSSI
    rssiWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
                                    softap_rssi_weight_cfg,
                                    rssi - SOFTAP_MIN_RSSI,
                                    SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI);

    if(rssiWeight > softap_rssi_weight_local)
        rssiWeight = softap_rssi_weight_local;
    else if (rssiWeight < 0)
        rssiWeight = 0;

    // Weight from data count
    countWeight = ACS_WEIGHT_COMPUTE(sap_ctx->auto_channel_select_weight,
                                     softap_count_weight_cfg,
                                     count - SOFTAP_MIN_COUNT,
                                     SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT);

    if(countWeight > softap_count_weight_local)
        countWeight = softap_count_weight_local;

    rssicountWeight =  rssiWeight + countWeight;

    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d",
              __func__, rssiWeight, countWeight, rssicountWeight);

    return(rssicountWeight);
}


/**
 * sap_get_channel_status() - get channel info via channel number
 * @p_mac: Pointer to Global MAC structure
 * @channel_id: channel id
 *
 * Return: chan status info
 */
struct lim_channel_status *sap_get_channel_status
	(tpAniSirGlobal p_mac, uint32_t channel_id)
{
	return csr_get_channel_status(p_mac, channel_id);
}

/**
 * sap_clear_channel_status() - clear chan info
 * @p_mac: Pointer to Global MAC structure
 *
 * Return: none
 */
void sap_clear_channel_status(tpAniSirGlobal p_mac)
{
	csr_clear_channel_status(p_mac);
}

/**
 * sap_weight_channel_noise_floor() - compute noise floor weight
 * @sap_ctx:  sap context
 * @chn_stat: Pointer to chan status info
 *
 * Return: channel noise floor weight
 */
uint32_t sap_weight_channel_noise_floor(ptSapContext sap_ctx,
	struct lim_channel_status *channel_stat)
{
	uint32_t    noise_floor_weight;
	uint8_t     softap_nf_weight_cfg;
	uint8_t     softap_nf_weight_local;

	softap_nf_weight_cfg =
	    ACS_WEIGHT_SOFTAP_NOISE_FLOOR_CFG
	    (sap_ctx->auto_channel_select_weight);

	softap_nf_weight_local =
	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
				    softap_nf_weight_cfg);

	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
		VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
			  "In %s, Directly return max weight due to"
			  "sanity check failed.", __func__);
		return softap_nf_weight_local;
	}

	noise_floor_weight = (channel_stat->noise_floor == 0) ? 0 :
			    (ACS_WEIGHT_COMPUTE(
			     sap_ctx->auto_channel_select_weight,
			     softap_nf_weight_cfg,
			     channel_stat->noise_floor -
			     SOFTAP_MIN_NF,
			     SOFTAP_MAX_NF - SOFTAP_MIN_NF));

	if (noise_floor_weight > softap_nf_weight_local)
		noise_floor_weight = softap_nf_weight_local;
	else if (noise_floor_weight < 0)
		noise_floor_weight = 0;

	VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
		  "In %s, nf=%d, nfwc=%d, nfwl=%d, nfw=%d",
		  __func__, channel_stat->noise_floor,
		  softap_nf_weight_cfg, softap_nf_weight_local,
		  noise_floor_weight);

	return noise_floor_weight;
}

/**
 * sap_weight_channel_free() - compute channel free weight
 * @sap_ctx:  sap context
 * @chn_stat: Pointer to chan status info
 *
 * Return: channel free weight
 */
uint32_t sap_weight_channel_free(ptSapContext sap_ctx,
	struct lim_channel_status *channel_stat)
{
	uint32_t     channel_free_weight;
	uint8_t      softap_channel_free_weight_cfg;
	uint8_t      softap_channel_free_weight_local;
	uint32_t     rx_clear_count = 0;
	uint32_t     cycle_count = 0;

	softap_channel_free_weight_cfg =
	    ACS_WEIGHT_SOFTAP_CHANNEL_FREE_CFG
	    (sap_ctx->auto_channel_select_weight);

	softap_channel_free_weight_local =
	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
				    softap_channel_free_weight_cfg);

	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
		VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
			  "In %s, Directly return max weight due to"
			  "sanity check failed.", __func__);
		return softap_channel_free_weight_local;
	}

	rx_clear_count = channel_stat->rx_clear_count -
			 channel_stat->tx_frame_count -
			 channel_stat->rx_frame_count;
	cycle_count = channel_stat->cycle_count;

	/* LSH 4, otherwise it is always 0. */
	channel_free_weight = (cycle_count == 0) ? 0 :
			 (ACS_WEIGHT_COMPUTE(
			  sap_ctx->auto_channel_select_weight,
			  softap_channel_free_weight_cfg,
			  ((rx_clear_count << 8) +
			   (cycle_count >> 1))/cycle_count -
			  (SOFTAP_MIN_CHNFREE << 8),
			  (SOFTAP_MAX_CHNFREE -
			   SOFTAP_MIN_CHNFREE) << 8));

	if (channel_free_weight > softap_channel_free_weight_local)
		channel_free_weight = softap_channel_free_weight_local;

	VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
		  "In %s, rcc=%d, cc=%d, tc=%d, rc=%d, cfwc=%d, cfwl=%d, cfw=%d",
		  __func__, rx_clear_count, cycle_count,
		  channel_stat->tx_frame_count,
		  channel_stat->rx_frame_count,
		  softap_channel_free_weight_cfg,
		  softap_channel_free_weight_local,
		  channel_free_weight);

	return channel_free_weight;
}

/**
 * sap_weight_channel_txpwr_range() - compute channel tx power range weight
 * @sap_ctx:  sap context
 * @chn_stat: Pointer to chan status info
 *
 * Return: tx power range weight
 */
uint32_t sap_weight_channel_txpwr_range(ptSapContext sap_ctx,
	struct lim_channel_status *channel_stat)
{
	uint32_t     txpwr_weight_low_speed;
	uint8_t      softap_txpwr_range_weight_cfg;
	uint8_t      softap_txpwr_range_weight_local;

	softap_txpwr_range_weight_cfg =
	    ACS_WEIGHT_SOFTAP_TX_POWER_RANGE_CFG
	    (sap_ctx->auto_channel_select_weight);

	softap_txpwr_range_weight_local =
	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
				    softap_txpwr_range_weight_cfg);

	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
		VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
			  "In %s, Directly return max weight due to"
			  "sanity check failed.", __func__);
		return softap_txpwr_range_weight_local;
	}

	txpwr_weight_low_speed = (channel_stat->chan_tx_pwr_range == 0) ? 0 :
				(ACS_WEIGHT_COMPUTE(
				 sap_ctx->auto_channel_select_weight,
				 softap_txpwr_range_weight_cfg,
				 SOFTAP_MAX_TXPWR -
				 channel_stat->chan_tx_pwr_range,
				 SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));

	if (txpwr_weight_low_speed > softap_txpwr_range_weight_local)
		txpwr_weight_low_speed = softap_txpwr_range_weight_local;

	VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
		  "In %s, tpr=%d, tprwc=%d, tprwl=%d, tprw=%d",
		  __func__, channel_stat->chan_tx_pwr_range,
		  softap_txpwr_range_weight_cfg,
		  softap_txpwr_range_weight_local,
		  txpwr_weight_low_speed);

	return txpwr_weight_low_speed;
}

/**
 * sap_weight_channel_txpwr_tput() - compute channel tx power throughput weight
 * @sap_ctx:  sap context
 * @chn_stat: Pointer to chan status info
 *
 * Return: tx power throughput weight
 */
uint32_t sap_weight_channel_txpwr_tput(ptSapContext sap_ctx,
	struct lim_channel_status *channel_stat)
{
	uint32_t     txpwr_weight_high_speed;
	uint8_t      softap_txpwr_tput_weight_cfg;
	uint8_t      softap_txpwr_tput_weight_local;

	softap_txpwr_tput_weight_cfg =
	    ACS_WEIGHT_SOFTAP_TX_POWER_THROUGHPUT_CFG
	    (sap_ctx->auto_channel_select_weight);

	softap_txpwr_tput_weight_local =
	    ACS_WEIGHT_CFG_TO_LOCAL(sap_ctx->auto_channel_select_weight,
				    softap_txpwr_tput_weight_cfg);

	if (channel_stat == NULL || channel_stat->channelfreq == 0) {
		VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
			  "In %s, Directly return max weight due to"
			  "sanity check failed.", __func__);
		return softap_txpwr_tput_weight_local;
	}

	txpwr_weight_high_speed = (channel_stat->chan_tx_pwr_throughput == 0) ? 0 :
				 (ACS_WEIGHT_COMPUTE(
				  sap_ctx->auto_channel_select_weight,
				  softap_txpwr_tput_weight_cfg,
				  SOFTAP_MAX_TXPWR -
				  channel_stat->chan_tx_pwr_throughput,
				  SOFTAP_MAX_TXPWR - SOFTAP_MIN_TXPWR));

	if (txpwr_weight_high_speed > softap_txpwr_tput_weight_local)
		txpwr_weight_high_speed = softap_txpwr_tput_weight_local;

	VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
		  "In %s, tpt=%d, tptwc=%d, tptwl=%d, tptw=%d",
		  __func__, channel_stat->chan_tx_pwr_throughput,
		  softap_txpwr_tput_weight_cfg,
		  softap_txpwr_tput_weight_local,
		  txpwr_weight_high_speed);

	return txpwr_weight_high_speed;
}

/**
 * sap_weight_channel_status() - compute chan status weight
 * @sap_ctx:  sap context
 * @chn_stat: Pointer to chan status info
 *
 * Return: chan status weight
 */
uint32_t sap_weight_channel_status(ptSapContext sap_ctx,
				   struct lim_channel_status *channel_stat)
{
	return sap_weight_channel_noise_floor(sap_ctx, channel_stat) +
	       sap_weight_channel_free(sap_ctx, channel_stat) +
	       sap_weight_channel_txpwr_range(sap_ctx, channel_stat) +
	       sap_weight_channel_txpwr_tput(sap_ctx, channel_stat);
}

/*==========================================================================
  FUNCTION    sapInterferenceRssiCount

  DESCRIPTION
    Function sapInterferenceRssiCount Considers the Adjacent channel rssi
    and data count(here number of BSS observed)

  DEPENDENCIES
    NA.

  PARAMETERS

    pSpectCh    : Channel Information

  RETURN VALUE
    NA.

  SIDE EFFECTS
============================================================================*/
void sapInterferenceRssiCount(tSapSpectChInfo *pSpectCh,
                              tSapSpectChInfo *spect_ch_strt_addr,
                              tSapSpectChInfo *spect_ch_end_addr)
{
    tSapSpectChInfo *pExtSpectCh = NULL;
    v_S31_t rssi;

    if (NULL == pSpectCh)
    {
        VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                   "%s: pSpectCh is NULL", __func__);
        return;
    }

    switch(pSpectCh->chNum)
    {
        case CHANNEL_1:
            pExtSpectCh = (pSpectCh + 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
        break;

        case CHANNEL_2:
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;
        case CHANNEL_3:
            pExtSpectCh = (pSpectCh - 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;
        case CHANNEL_4:
            pExtSpectCh = (pSpectCh - 3);
            if(pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;

        case CHANNEL_5:
        case CHANNEL_6:
        case CHANNEL_7:
        case CHANNEL_8:
        case CHANNEL_9:
        case CHANNEL_10:
            pExtSpectCh = (pSpectCh - 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 3);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 4);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;

        case CHANNEL_11:
            pExtSpectCh = (pSpectCh - 4);
            if(pExtSpectCh != NULL &&
               (pExtSpectCh >= spect_ch_strt_addr &&
                pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }

            pExtSpectCh = (pSpectCh - 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 3);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;

        case CHANNEL_12:
            pExtSpectCh = (pSpectCh - 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }

            pExtSpectCh = (pSpectCh - 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 2);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;

        case CHANNEL_13:
            pExtSpectCh = (pSpectCh - 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }

            pExtSpectCh = (pSpectCh - 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 2);
            if(pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh + 1);
            if ((pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr)))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;

        case CHANNEL_14:
            pExtSpectCh = (pSpectCh - 1);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 2);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 3);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            pExtSpectCh = (pSpectCh - 4);
            if (pExtSpectCh != NULL &&
                (pExtSpectCh >= spect_ch_strt_addr &&
                 pExtSpectCh < spect_ch_end_addr))
            {
                ++pExtSpectCh->bssCount;
                rssi = pSpectCh->rssiAgr +
                       SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY;
                if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                {
                    pExtSpectCh->rssiAgr = rssi;
                }
                if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                    pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
            }
            break;

        default:
            break;
    }
}

/*==========================================================================
  FUNCTION    sapComputeSpectWeight

  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
    sap_ctx                : Pointer to Sap context
  RETURN VALUE
    void     : NULL

  SIDE EFFECTS
============================================================================*/
void sapComputeSpectWeight( tSapChSelSpectInfo* pSpectInfoParams,
                            tHalHandle halHandle, tScanResultHandle pResult,
                            ptSapContext sap_ctx)
{
    v_S7_t rssi = 0;
    v_U8_t chn_num = 0;
    v_U8_t channel_id = 0;

    tCsrScanResultInfo *pScanResult;
    tSapSpectChInfo *pSpectCh   = pSpectInfoParams->pSpectCh;
    v_U32_t operatingBand = eCSR_DOT11_MODE_11g;
    v_U16_t channelWidth;
    v_U16_t secondaryChannelOffset;
    v_U16_t centerFreq;
    v_U16_t vhtSupport;
    v_U32_t ieLen = 0;
    tSirProbeRespBeacon *pBeaconStruct;
    tpAniSirGlobal  pMac = (tpAniSirGlobal) halHandle;
    tSapSpectChInfo *pSpectChStartAddr = pSpectInfoParams->pSpectCh;
    tSapSpectChInfo *pSpectChEndAddr =
                    pSpectInfoParams->pSpectCh + pSpectInfoParams->numSpectChans;
    tSapSpectChInfo *pExtSpectCh = NULL;

    pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon));
    if ( NULL == pBeaconStruct )
    {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                   "Unable to allocate memory in sapComputeSpectWeight");
        return;
    }
    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
    */
    SET_ACS_BAND(operatingBand, sap_ctx);

    pScanResult = sme_ScanResultGetFirst(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;

        ieLen = GET_IE_LEN_IN_BSS(pScanResult->BssDescriptor.length);
        vos_mem_set((tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0);

        if ((sirParseBeaconIE(pMac, pBeaconStruct,(tANI_U8 *)( pScanResult->BssDescriptor.ieFields), ieLen)) == eSIR_SUCCESS)
        {
            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;
                    }
                }
            }
        }
        // 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

                if(operatingBand) // Connsidering the Extension Channel only in a channels
                {
                    /* Updating the received ChannelWidth */
                    if (pSpectCh->channelWidth != channelWidth)
                        pSpectCh->channelWidth = 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( secondaryChannelOffset)
                            {
                                case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: // Above the Primary Channel
                                    pExtSpectCh = (pSpectCh + 1);
                                    if( pExtSpectCh != NULL &&
                                       (pExtSpectCh >= pSpectChStartAddr &&
                                        pExtSpectCh < pSpectChEndAddr))
                                    {
                                        ++pExtSpectCh->bssCount;
                                        rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                        // REducing the rssi by -20 and assigning it to Extension channel
                                        if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                        {
                                            pExtSpectCh->rssiAgr = 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 >= pSpectChStartAddr &&
                                        pExtSpectCh < pSpectChEndAddr))
                                    {
                                        rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                        if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                        {
                                            pExtSpectCh->rssiAgr = rssi;
                                        }
                                        if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                            pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                        ++pExtSpectCh->bssCount;
                                    }
                                break;
                            }
                        break;
                        case eHT_CHANNEL_WIDTH_80MHZ: // VHT80
                            if((centerFreq - channel_id) == 6)
                            {
                                tSapSpectChInfo *pExtSpectCh = NULL;
                                pExtSpectCh = (pSpectCh + 1);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = 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 >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = 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 >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = 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((centerFreq - channel_id) == 2)
                            {
                                tSapSpectChInfo *pExtSpectCh = NULL;
                                pExtSpectCh = (pSpectCh - 1 );
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                                pExtSpectCh = (pSpectCh + 1);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                                pExtSpectCh = (pSpectCh + 2);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                            }
                            else if((centerFreq - channel_id) == -2)
                            {
                                tSapSpectChInfo *pExtSpectCh = NULL;
                                pExtSpectCh = (pSpectCh - 1 );
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                                pExtSpectCh = (pSpectCh - 2);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                                pExtSpectCh = (pSpectCh + 1);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                            }
                            else if((centerFreq - channel_id) == -6)
                            {
                                tSapSpectChInfo *pExtSpectCh = NULL;
                                pExtSpectCh = (pSpectCh - 1 );
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                                pExtSpectCh = (pSpectCh - 2);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                                pExtSpectCh = (pSpectCh - 3);
                                if( pExtSpectCh != NULL &&
                                   (pExtSpectCh >= pSpectChStartAddr &&
                                    pExtSpectCh < pSpectChEndAddr))
                                {
                                    ++pExtSpectCh->bssCount;
                                    rssi = pSpectCh->rssiAgr + SAP_SUBBAND3_RSSI_EFFECT_PRIMARY;
                                    if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi))
                                    {
                                        pExtSpectCh->rssiAgr = rssi;
                                    }
                                    if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI)
                                        pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI;
                                }
                            }
                        break;
                    }
                }

                if(operatingBand == eCSR_DOT11_MODE_11g)
                {
                     sapInterferenceRssiCount(pSpectCh, pSpectChStartAddr,
                                              pSpectChEndAddr);
                }

                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=%pK, ChannelWidth %d, secondaryChanOffset %d, center frequency %d",
                  __func__, pScanResult->BssDescriptor.channelIdSelf,
                 pScanResult->BssDescriptor.channelId,
                 pScanResult->BssDescriptor.rssi, pSpectCh->bssCount,
                 pScanResult, pSpectCh->channelWidth,
                 secondaryChannelOffset, centerFreq);

                 pSpectCh++;
                 break;
           } else {
             pSpectCh++;
           }
        }

        pScanResult = sme_ScanResultGetNext(halHandle, pResult);
    }

    // Calculate the weights for all channels in the spectrum pSpectCh
    pSpectCh = pSpectInfoParams->pSpectCh;

    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_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 = (v_S7_t)pSpectCh->rssiAgr;

        pSpectCh->weight = SAPDFS_NORMALISE_1000 *
                (sapweightRssiCount(sap_ctx, rssi, pSpectCh->bssCount)
                 + sap_weight_channel_status(sap_ctx,
                 sap_get_channel_status(pMac, pSpectCh->chNum)));
        if (pSpectCh->weight > ACS_WEIGHT_MAX)
            pSpectCh->weight = ACS_WEIGHT_MAX;
        pSpectCh->weight_copy = pSpectCh->weight;

        //------ Debug Info ------
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_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++;
    }
    sap_clear_channel_status(pMac);
    vos_mem_free(pBeaconStruct);
}

/*==========================================================================
  FUNCTION    sapChanSelExit

  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 sapChanSelExit( tSapChSelSpectInfo *pSpectInfoParams )
{
    // Free all the allocated memory
    vos_mem_free(pSpectInfoParams->pSpectCh);
}

/*==========================================================================
  FUNCTION    sapSortChlWeight

  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 sapSortChlWeight(tSapChSelSpectInfo *pSpectInfoParams)
{
    tSapSpectChInfo temp;

    tSapSpectChInfo *pSpectCh = NULL;
    v_U32_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) {
            vos_mem_copy(&temp, &pSpectCh[minWeightIndex], sizeof(*pSpectCh));
            vos_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i], sizeof(*pSpectCh));
            vos_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
        }
    }
}

/*==========================================================================
  FUNCTION    sapSortChlWeightHT80

  DESCRIPTION
    Funtion to sort the channels with the least weight first for HT80 channels

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
    pSpectInfoParams       : Pointer to the tSapChSelSpectInfo structure

  RETURN VALUE
    void     : NULL

  SIDE EFFECTS
============================================================================*/
void sapSortChlWeightHT80(tSapChSelSpectInfo *pSpectInfoParams)
{
    v_U8_t i, j, n;
    tSapSpectChInfo *pSpectInfo;
    v_U8_t minIdx;
    int start_channel = 0;
    chan_bonding_bitmap channelBitmap;

    pSpectInfo = pSpectInfoParams->pSpectCh;
    /* for each HT80 channel, calculate the combined weight of the
       four 20MHz weight */
    for (i = 0; i < ARRAY_SIZE(acsHT80Channels); i++)
    {
        for (j = 0; j < pSpectInfoParams->numSpectChans; j++)
        {
            if ( pSpectInfo[j].chNum == acsHT80Channels[i].chStartNum )
                break;
        }
        if (j == pSpectInfoParams->numSpectChans)
            continue;
        /* found the channel, add the 4 adjacent channels' weight.
         * Check the array index to avoid access overflow.
         */
        if (((j + 3) < pSpectInfoParams->numSpectChans) &&
             ((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) &&
             ((pSpectInfo[j].chNum +8) == pSpectInfo[j+2].chNum) &&
             ((pSpectInfo[j].chNum +12) == pSpectInfo[j+3].chNum))
        {
            acsHT80Channels[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
            {
                /* upper 2 channels are better choice */
                if (pSpectInfo[j+2].weight <= pSpectInfo[j+3].weight)
                    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 = ACS_WEIGHT_MAX * 4;

            pSpectInfo[j+minIdx].weight = acsHT80Channels[i].weight;
        }
        else
        {
            /* some channels does not exist in pSectInfo array,
               skip this channel and those in the same HT80 width*/
            pSpectInfo[j].weight = ACS_WEIGHT_MAX * 4;
            if (((j + 1) < pSpectInfoParams->numSpectChans) &&
                ((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum))
                pSpectInfo[j+1].weight = ACS_WEIGHT_MAX * 4;
            if (((j + 2) < pSpectInfoParams->numSpectChans) &&
                ((pSpectInfo[j].chNum +8) == pSpectInfo[j+2].chNum))
                pSpectInfo[j+2].weight = ACS_WEIGHT_MAX * 4;
            if (((j + 3) < pSpectInfoParams->numSpectChans) &&
                ((pSpectInfo[j].chNum +12) == pSpectInfo[j+3].chNum))
                pSpectInfo[j+3].weight = ACS_WEIGHT_MAX * 4;
        }
    }

    /* mark the weight of the channel that can't satisfy 80MHZ
       as max value, so that it will be sorted to the bottom*/

    vos_mem_zero(&channelBitmap, sizeof(channelBitmap));
    channelBitmap.chanBondingSet[0].startChannel = 36;
    channelBitmap.chanBondingSet[1].startChannel = 52;
    channelBitmap.chanBondingSet[2].startChannel = 100;
    channelBitmap.chanBondingSet[3].startChannel = 116;
    channelBitmap.chanBondingSet[4].startChannel = 132;
    channelBitmap.chanBondingSet[5].startChannel = 149;

    pSpectInfo = pSpectInfoParams->pSpectCh;
    for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
        for (i = 0; i < MAX_80MHZ_BANDS; i++) {
            start_channel = channelBitmap.chanBondingSet[i].startChannel;
            if (pSpectInfo[j].chNum >= start_channel &&
                    (pSpectInfo[j].chNum <= start_channel + 12)) {
                channelBitmap.chanBondingSet[i].channelMap |=
                    1 << ((pSpectInfo[j].chNum - start_channel)/4);
                break;
            }
        }
    }
    for (j =0; j < pSpectInfoParams->numSpectChans; j++) {
        for (i = 0; i < MAX_80MHZ_BANDS; i++) {
            start_channel = channelBitmap.chanBondingSet[i].startChannel;
            if (pSpectInfo[j].chNum >= start_channel &&
                    (pSpectInfo[j].chNum <= start_channel + 12) &&
                    channelBitmap.chanBondingSet[i].channelMap != SAP_80MHZ_MASK)
                pSpectInfo[j].weight = ACS_WEIGHT_MAX * 4;
        }
    }

    pSpectInfo = pSpectInfoParams->pSpectCh;
    for (j = 0; j < pSpectInfoParams->numSpectChans; j++)
    {
        if ( CHANNEL_165 == pSpectInfo[j].chNum )
        {
            pSpectInfo[j].weight = ACS_WEIGHT_MAX * 4;
            break;
        }
    }

    pSpectInfo = pSpectInfoParams->pSpectCh;
    for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                    "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
                    __func__, pSpectInfo->chNum, pSpectInfo->weight,
                    pSpectInfo->rssiAgr, pSpectInfo->bssCount);
        pSpectInfo++;
    }

    sapSortChlWeight(pSpectInfoParams);
}

/*==========================================================================
  FUNCTION    sapSortChlWeightHT40_24G

  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 sapSortChlWeightHT40_24G(tSapChSelSpectInfo *pSpectInfoParams)
{
    v_U8_t i, j;
    tSapSpectChInfo *pSpectInfo;
    v_U32_t tmpWeight1, tmpWeight2;
    v_U32_t ht40plus2gendch = 0;

    pSpectInfo = pSpectInfoParams->pSpectCh;
    /*for each HT40 channel, calculate the combined weight of the
      two 20MHz weight */
    for (i = 0; i < ARRAY_SIZE(acsHT40Channels24G); i++)
    {
        for (j = 0; j < pSpectInfoParams->numSpectChans; j++)
        {
            if (pSpectInfo[j].chNum == acsHT40Channels24G[i].chStartNum)
                break;
        }
        if (j == pSpectInfoParams->numSpectChans)
            continue;

        if (((j + 4) < pSpectInfoParams->numSpectChans) &&
            ((pSpectInfo[j].chNum +4) == pSpectInfo[j+4].chNum))
        {
            /* check if there is another channel combination possiblity
               e.g., {1, 5} & {5, 9} */
            if (((j + 8) < pSpectInfoParams->numSpectChans) &&
                ((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 = ACS_WEIGHT_MAX * 2;
                        pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2;
                    }
                    else
                    {
                        pSpectInfo[j+4].weight = tmpWeight1;
                        /* for secondary channel selection */
                        pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2 - 1;
                        pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2;
                    }
                }
                else
                {
                    if (pSpectInfo[j+4].weight <= pSpectInfo[j+8].weight)
                    {
                        pSpectInfo[j+4].weight = tmpWeight2;
                        pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
                        /* for secondary channel selection */
                        pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2 - 1;
                    }
                    else
                    {
                        pSpectInfo[j+8].weight = tmpWeight2;
                        pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
                        pSpectInfo[j+4].weight = 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 = ACS_WEIGHT_MAX * 2;
                }
                else
                {
                    pSpectInfo[j+4].weight = tmpWeight1;
                    pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
                }
            }
        }
        else
            pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
    }

    /* Every channel should be checked. Add the check for the omissive channel.
       Mark the channel whose combination can't satisfy 40MHZ as max value,
       so that it will be sorted to the bottom*/
    if (vos_is_fcc_regdomain())
        ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
    else
        ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
    for (i = 5; i <= ht40plus2gendch; i++) {
        for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
            if (pSpectInfo[j].chNum == i &&
                    ((pSpectInfo[j].chNum + 4) != pSpectInfo[j+4].chNum) &&
                    ((pSpectInfo[j].chNum - 4) != pSpectInfo[j-4].chNum))
                pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
        }
    }
    for (i = ht40plus2gendch + 1; i <= 13; i++) {
        for (j = 0; j < pSpectInfoParams->numSpectChans; j++) {
            if (pSpectInfo[j].chNum == i &&
                    (pSpectInfo[j].chNum - 4) != pSpectInfo[j-4].chNum)
                pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
        }
    }

    sapSortChlWeight(pSpectInfoParams);
}


/*==========================================================================
  FUNCTION    sapSortChlWeightHT40_5G

  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 sapSortChlWeightHT40_5G(tSapChSelSpectInfo *pSpectInfoParams)
{
    v_U8_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(acsHT40Channels5G); i++)
    {
        for (j = 0; j < pSpectInfoParams->numSpectChans; j++)
        {
            if (pSpectInfo[j].chNum == acsHT40Channels5G[i].chStartNum)
                break;
        }
        if (j == pSpectInfoParams->numSpectChans)
            continue;

        /* found the channel, add the two adjacent channels' weight */
        if (((j + 1) < pSpectInfoParams->numSpectChans) &&
            ((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum))
        {
            acsHT40Channels5G[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 = acsHT40Channels5G[i].weight;
                /* mark the adjacent channel's weight as max value so
                   that it will be sorted to the bottom */
                pSpectInfo[j+1].weight = ACS_WEIGHT_MAX * 2;
            }
            else
            {
                pSpectInfo[j+1].weight = acsHT40Channels5G[i].weight;
                /* mark the adjacent channel's weight as max value so
                   that it will be sorted to the bottom */
                pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
            }

        }
        else
           pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
    }

    /* Every channel should be checked. Add the check for the omissive channel.
       Mark the channel whose combination can't satisfy 40MHZ as max value,
       so that it will be sorted to the bottom*/
    for (j = 1; j < pSpectInfoParams->numSpectChans; j++) {
        for (i = 0; i < ARRAY_SIZE(acsHT40Channels5G); i++) {
            if (pSpectInfo[j].chNum == (acsHT40Channels5G[i].chStartNum + 4) &&
                    pSpectInfo[j-1].chNum != acsHT40Channels5G[i].chStartNum) {
                pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2;
                break;
            }
        }
    }
    /* 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 = ACS_WEIGHT_MAX * 2;
            break;
        }
    }

    pSpectInfo = pSpectInfoParams->pSpectCh;
    for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                    "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d",
                    __func__, pSpectInfo->chNum, pSpectInfo->weight,
                    pSpectInfo->rssiAgr, pSpectInfo->bssCount);
        pSpectInfo++;
    }

    sapSortChlWeight(pSpectInfoParams);
}

/*==========================================================================
  FUNCTION    sapSortChlWeightAll

  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 sapSortChlWeightAll(ptSapContext pSapCtx,
                           tSapChSelSpectInfo *pSpectInfoParams,
                           v_U32_t operatingBand)
{
    tSapSpectChInfo *pSpectCh = NULL;
    v_U32_t j = 0;
#ifndef  SOFTAP_CHANNEL_RANGE
    v_U32_t i = 0;
#endif

    pSpectCh = pSpectInfoParams->pSpectCh;
#ifdef SOFTAP_CHANNEL_RANGE

    switch (pSapCtx->acs_cfg->ch_width)
    {
    case eHT_CHANNEL_WIDTH_40MHZ:
        if (eCSR_DOT11_MODE_11a == operatingBand)
            sapSortChlWeightHT40_5G(pSpectInfoParams);
        else
            sapSortChlWeightHT40_24G(pSpectInfoParams);
        break;

    case eHT_CHANNEL_WIDTH_80MHZ:
        sapSortChlWeightHT80(pSpectInfoParams);
        break;

    case eHT_CHANNEL_WIDTH_20MHZ:
    default:
        /* Sorting the channels as per weights as 20MHz channels */
        sapSortChlWeight(pSpectInfoParams);
    }

#else
    /* Sorting the channels as per weights */
    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) {
            vos_mem_copy(&temp, &pSpectCh[minWeightIndex], sizeof(*pSpectCh));
            vos_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i],
                                                    sizeof(*pSpectCh));
            vos_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh));
        }
    }
#endif

    /* For testing */
    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                    "In %s, Sorted Spectrum Channels Weight", __func__);
    pSpectCh = pSpectInfoParams->pSpectCh;
    for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_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    sapFilterOverLapCh

  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
    v_BOOL_t          : true if channel is accepted.

  SIDE EFFECTS
============================================================================*/
v_BOOL_t sapFilterOverLapCh(ptSapContext pSapCtx, v_U16_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    sapSelectChannel

  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
    v_U8_t          : Success - channel number, Fail - zero

  SIDE EFFECTS
============================================================================*/
v_U8_t sapSelectChannel(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
    v_U8_t bestChNum = SAP_CHANNEL_NOT_SELECTED;
    v_U32_t ht40plus2gendch = 0;
#ifdef FEATURE_WLAN_CH_AVOID
    v_U8_t i;
    v_U8_t firstSafeChannelInRange = SAP_CHANNEL_NOT_SELECTED;
    v_U32_t dfs_master_cap_enabled;
#endif
#ifdef SOFTAP_CHANNEL_RANGE
    v_U32_t startChannelNum;
    v_U32_t endChannelNum;
    v_U32_t operatingBand = 0;
    v_U32_t tmpChNum;
    v_U8_t  count;
#endif

    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Running SAP Ch Select", __func__);

#ifdef FEATURE_WLAN_CH_AVOID
    sapUpdateUnsafeChannelList(pSapCtx);
#endif

    /*
     * If ACS weight is not enabled on noise_floor/channel_free/tx_power,
     * then skip acs process if no bss found.
     */
    if (NULL == pScanResult &&
        !(pSapCtx->auto_channel_select_weight & 0xffff00))
    {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                  "%s: No external AP present", __func__);

#ifndef SOFTAP_CHANNEL_RANGE
        return bestChNum;
#else
        //scan is successfull, but no AP is present
        startChannelNum = pSapCtx->acs_cfg->start_ch;
        endChannelNum = pSapCtx->acs_cfg->end_ch;

        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                  "%s: start - end: %d - %d", __func__,
                  startChannelNum, endChannelNum);

#ifndef FEATURE_WLAN_CH_AVOID /* FEATURE_WLAN_CH_AVOID NOT defined case*/
        // pick the first channel in configured range
	pSapCtx->acs_cfg->pri_ch = startChannelNum;
	pSapCtx->acs_cfg->ht_sec_ch = 0;
        return startChannelNum;
#else /* FEATURE_WLAN_CH_AVOID defined */

        ccmCfgGetInt(halHandle, WNI_CFG_DFS_MASTER_ENABLED,
                &dfs_master_cap_enabled);

        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                  "%s: dfs_master %x", __func__, dfs_master_cap_enabled);
        // any safe channels in the configured range?
        for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++)
        {
            if((safeChannels[i].channelNumber >= startChannelNum) &&
               (safeChannels[i].channelNumber <= endChannelNum))
            {
                eNVChannelEnabledType enable_type =
                   vos_nv_getChannelEnabledState(safeChannels[i].channelNumber);
                if ((NV_CHANNEL_DISABLE == enable_type) ||
                    (NV_CHANNEL_INVALID == enable_type))
                    continue;
                if ((pSapCtx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
                      (NV_CHANNEL_DFS == enable_type))
                    continue;

                if ((!dfs_master_cap_enabled) &&
                        (NV_CHANNEL_DFS == enable_type))
                {
                    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                            "%s: DFS master mode disabled. Skip DFS channel %d",
                            __func__, safeChannels[i].channelNumber);
                    continue;
                }

                if (safeChannels[i].isSafe == VOS_TRUE)
                {
                    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        "%s: channel %d in the configuration is safe",
                        __func__, safeChannels[i].channelNumber);
                    firstSafeChannelInRange = safeChannels[i].channelNumber;
                    break;
                }

                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                    "%s: channel %d in the configuration is unsafe", __func__,
                    safeChannels[i].channelNumber);
            }
        }

        /* if there is 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 (sapChanSelInit( halHandle, pSpectInfoParams, pSapCtx ) != eSAP_TRUE ) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_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
    sapComputeSpectWeight( 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
    if (eCSR_BAND_ALL == pSapCtx->scanBandPreference)
    {
        startChannelNum = pSapCtx->acs_cfg->start_ch;
        endChannelNum = pSapCtx->acs_cfg->end_ch;
        SET_ACS_BAND(operatingBand, pSapCtx);
    }
    else
    {
        if (eCSR_BAND_24 == pSapCtx->currentPreferredBand)
        {
            startChannelNum = rfChannels[RF_CHAN_1].channelNum;
            endChannelNum = rfChannels[RF_CHAN_14].channelNum;
            operatingBand = eCSR_DOT11_MODE_11g;
        }
        else
        {
            startChannelNum = rfChannels[RF_CHAN_36].channelNum;
            endChannelNum = rfChannels[RF_CHAN_165].channelNum;
            operatingBand = eCSR_DOT11_MODE_11a;
        }
    }

    pSapCtx->acsBestChannelInfo.channelNum = 0;
    pSapCtx->acsBestChannelInfo.weight = CFG_ACS_BAND_SWITCH_THRESHOLD_MAX;

    /* Sort the channel list as per the computed weights, lesser weight first.*/
    sapSortChlWeightAll(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 = sapSelectPreferredChannelFromChannelList(
                                       bestChNum, pSapCtx, pSpectInfoParams);
                if (bestChNum == SAP_CHANNEL_NOT_SELECTED)
                {
                    /* not in preferred channel list, go to next best channel*/
                    continue;
                }

                if (pSpectInfoParams->pSpectCh[count].weight_copy >
                                  pSapCtx->acsBandSwitchThreshold)
                {
                    /* the best channel exceeds the threshold
                       check if need to scan next band */
                    if ((eCSR_BAND_ALL !=  pSapCtx->scanBandPreference) &&
                                   !pSapCtx->allBandScanned)
                    {
                        /* store best channel for later comparison */
                        pSapCtx->acsBestChannelInfo.channelNum = bestChNum;
                        pSapCtx->acsBestChannelInfo.weight =
                                   pSpectInfoParams->pSpectCh[count].weight;
                        bestChNum = SAP_CHANNEL_NOT_SELECTED;
                        break;
                    }
                    else
                    {
                        /* all bands are scanned, compare current best channel
                           with channel scanned previously */
                        if (( pSpectInfoParams->pSpectCh[count].weight_copy >
                              pSapCtx->acsBestChannelInfo.weight)
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
                             /* Weight of the channels(MDM 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*/
                              && !sap_check_in_avoid_ch_list(pSapCtx, bestChNum)
#endif
                        )
                        {
                            /* previous stored channel is better */
                            bestChNum = pSapCtx->acsBestChannelInfo.channelNum;
                            break;
                        }
                        else
                        {
                            pSapCtx->acsBestChannelInfo.channelNum = bestChNum;
                            pSapCtx->acsBestChannelInfo.weight =
                                  pSpectInfoParams->pSpectCh[count].weight_copy;
                        }
                    }
                }
                else
                {
                    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 (sapFilterOverLapCh(pSapCtx,
                            pSpectInfoParams->pSpectCh[count].chNum) &&
                        (pSpectInfoParams->pSpectCh[count].weight_copy <=
                                 pSapCtx->acsBestChannelInfo.weight))
                    {
                        tmpChNum = pSpectInfoParams->pSpectCh[count].chNum;
                        tmpChNum = sap_channel_in_acs_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.
    sapSortChlWeightAll(pSapCtx, halHandle, pSpectInfoParams);
    // Get the first channel in sorted array as best 20M Channel
    bestChNum = (v_U8_t)pSpectInfoParams->pSpectCh[0].chNum;
    //Select Best Channel from Channel List if Configured
    bestChNum = sapSelectPreferredChannelFromChannelList(bestChNum,
                                                  pSapCtx, pSpectInfoParams);
#endif

    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 ==
                                             eHT_CHANNEL_WIDTH_40MHZ)) {
        if (vos_is_fcc_regdomain())
            ht40plus2gendch = HT40PLUS_2G_FCC_CH_END;
        else
            ht40plus2gendch = HT40PLUS_2G_EURJAP_CH_END;
        if ((bestChNum >= 5) && (bestChNum <= ht40plus2gendch)) {
            int weight_below, weight_above, i;
            tSapSpectChInfo *pSpectInfo;

            weight_below = weight_above  = ACS_WEIGHT_MAX;
            pSpectInfo = pSpectInfoParams->pSpectCh;

            for (i = 0; i < pSpectInfoParams->numSpectChans ; i++) {
               if (pSpectInfo[i].chNum == (bestChNum - 4))
                    weight_below = pSpectInfo[i].weight;

               if (pSpectInfo[i].chNum == (bestChNum + 4))
                    weight_above = pSpectInfo[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 > ht40plus2gendch && 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
    sapChanSelExit(pSpectInfoParams);

    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_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;
}
