/*
 * 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 A p i L i n k C n t l . C

  OVERVIEW:

  This software unit holds the implementation of the WLAN SAP modules
  Link Control functions.

  The functions externalized by this module are to be called ONLY by other
  WLAN modules (HDD)

  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.


   $Header: /cygdrive/c/Dropbox/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_SAP_PAL/CORE/SAP/src/sapApiLinkCntl.c,v 1.7 2008/12/18 19:44:11 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $


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

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

/*----------------------------------------------------------------------------
 * Include Files
 * -------------------------------------------------------------------------*/
#include "vos_trace.h"
// Pick up the CSR callback definition
#include "csrApi.h"
#include "sme_Api.h"
// SAP Internal API header file
#include "sapInternal.h"

/*----------------------------------------------------------------------------
 * Preprocessor Definitions and Constants
 * -------------------------------------------------------------------------*/
#define SAP_DEBUG

/*----------------------------------------------------------------------------
 * Type Declarations
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Global Data Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Static Variable Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Static Function Declarations and Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Externalized Function Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Function Declarations and Documentation
 * -------------------------------------------------------------------------*/

/*==========================================================================
  FUNCTION    WLANSAP_ScanCallback()

  DESCRIPTION
    Callback for Scan (scan results) Events

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
    tHalHandle  : tHalHandle passed in with the scan request
    *pContext   : The second context pass in for the caller (sapContext)
    scanID      : scanID got after the scan
    status      : Status of scan -success, failure or abort

  RETURN VALUE
    The eHalStatus code associated with performing the operation

    eHAL_STATUS_SUCCESS: Success

  SIDE EFFECTS
============================================================================*/
eHalStatus
WLANSAP_ScanCallback
(
  tHalHandle halHandle,
  void *pContext,           /* Opaque SAP handle */
  v_U8_t sessionId,
  v_U32_t scanID,
  eCsrScanStatus scanStatus
)
{
    tScanResultHandle pResult = NULL;
    eHalStatus scanGetResultStatus = eHAL_STATUS_FAILURE;
    ptSapContext psapContext = (ptSapContext)pContext;
    tWLAN_SAPEvent sapEvent; /* State machine event */
    v_U8_t operChannel = 0;
    VOS_STATUS sapstatus;
    tCsrRoamInfo *roam_info = NULL;
    tpAniSirGlobal pMac = NULL;
    v_U32_t event;

    if (NULL == halHandle)
    {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                  "In %s invalid hHal", __func__);
        return eHAL_STATUS_FAILURE;
    }
    else
    {
        pMac = PMAC_STRUCT( halHandle );
    }

    if (psapContext->sapsMachine == eSAP_DISCONNECTED) {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
                  "In %s BSS already stopped", __func__);
        return eHAL_STATUS_FAILURE;
    }

    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on scanStatus = %d", __func__, scanStatus);

    switch (scanStatus)
    {
        case eCSR_SCAN_SUCCESS:
            // sapScanCompleteCallback with eCSR_SCAN_SUCCESS
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR scanStatus = %s (%d)", __func__, "eCSR_SCAN_SUCCESS", scanStatus);

            // Get scan results, Run channel selection algorithm, select channel and keep in pSapContext->Channel
            scanGetResultStatus = sme_ScanGetResult(halHandle, psapContext->sessionId, NULL, &pResult);

            event = eSAP_MAC_SCAN_COMPLETE;

            if ((scanGetResultStatus != eHAL_STATUS_SUCCESS)&& (scanGetResultStatus != eHAL_STATUS_E_NULL_VALUE))
            {
                // No scan results
                VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, Get scan result failed! ret = %d",
                                __func__, scanGetResultStatus);
                break;
            }
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
            if (scanID != 0) {
                VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                    "%s: Sending ACS Scan skip event", __func__);
                sapSignalHDDevent(psapContext, NULL,
                                  eSAP_ACS_SCAN_SUCCESS_EVENT,
                                  (v_PVOID_t) eSAP_STATUS_SUCCESS);
            } else
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          "%s: ACS scan id: %d (skipped ACS SCAN)", __func__, scanID);
#endif
            operChannel = sapSelectChannel(halHandle, psapContext, pResult);
            if (!operChannel) {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("No channel was selected from preferred channel for Operating channel"));

                operChannel = psapContext->acs_cfg->start_ch;

                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("Selecting operating channel as starting channel from preferred channel list: %d"),
                          operChannel);
            }

            sme_ScanResultPurge(halHandle, pResult);
            break;

        default:
            event = eSAP_CHANNEL_SELECTION_FAILED;
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR scanStatus = %s (%d)", __func__, "eCSR_SCAN_ABORT/FAILURE", scanStatus);
    }

    if (psapContext->sapsMachine != eSAP_STARTED) {
        if (operChannel == SAP_CHANNEL_NOT_SELECTED)
#ifdef SOFTAP_CHANNEL_RANGE
        {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                      "%s: No suitable channel selected due to DFS, LTE-Coex and Concurrent mode restrictions", __func__);

            if (eCSR_BAND_ALL == psapContext->scanBandPreference ||
                psapContext->allBandScanned == eSAP_TRUE) {
                psapContext->sapsMachine = eSAP_CH_SELECT;
                event = eSAP_CHANNEL_SELECTION_FAILED;
            } else {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
                          "%s: Has scan band preference",
                          __func__);
                if (eCSR_BAND_24 == psapContext->currentPreferredBand)
                    psapContext->currentPreferredBand = eCSR_BAND_5G;
                else
                    psapContext->currentPreferredBand = eCSR_BAND_24;

                psapContext->allBandScanned = eSAP_TRUE;
                /* go back to DISCONNECT state, scan next band */
                psapContext->sapsMachine = eSAP_DISCONNECTED;
                event = eSAP_CHANNEL_SELECTION_RETRY;
            }
        }
#else
            psapContext->channel = SAP_DEFAULT_24GHZ_CHANNEL;
#endif
        else
            psapContext->channel = operChannel;

        sme_SelectCBMode(halHandle,
                         psapContext->csrRoamProfile.phyMode,
                         psapContext->channel, psapContext->secondary_ch,
                         &psapContext->vht_channel_width,
                         psapContext->ch_width_orig);

        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                  "In %s, Channel selected = %d", __func__,
                  psapContext->channel);
    } else {
        psapContext->channel = psapContext->backup_channel;

        roam_info = vos_mem_malloc(sizeof(*roam_info));
        if (!roam_info) {
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                      FL("Memory allocation failure!"));
        } else {
            roam_info->target_channel = operChannel;
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                      "In %s, Channel selected = %d", __func__,
                      roam_info->target_channel);
        }
    }

#ifdef SOFTAP_CHANNEL_RANGE
    if(psapContext->channelList != NULL)
    {
        /* Always free up the memory for channel selection whatever
         * the result */
        vos_mem_free(psapContext->channelList);
        psapContext->channelList = NULL;
        psapContext->num_of_channel = 0;
    }
#endif

    /* Fill in the event structure */
    sapEvent.event = event;
    sapEvent.params = roam_info;
    sapEvent.u1 = scanStatus;   // roamstatus
    sapEvent.u2 = 0;            // roamResult

    /* Handle event */
    sapstatus = sapFsm(psapContext, &sapEvent);

    if (roam_info)
        vos_mem_free(roam_info);
    return sapstatus;
}// WLANSAP_ScanCallback

/**
 * sap_config_acs_result : Generate ACS result params based on ch constraints
 * @sap_ctx: pointer to SAP context data struct
 * @hal: HAL Handle pointer
 *
 * This function calculates the ACS result params: ht sec channel, vht channel
 * information and channel bonding based on selected ACS channel.
 *
 * Return: None
 */

void sap_config_acs_result(tHalHandle hal, ptSapContext sap_ctx, uint32_t sec_ch)
{
	uint32_t channel = sap_ctx->acs_cfg->pri_ch;
	uint8_t cb_mode = eCSR_INI_SINGLE_CHANNEL_CENTERED;

	sap_ctx->acs_cfg->vht_seg0_center_ch = 0;
	sap_ctx->acs_cfg->vht_seg1_center_ch = 0;
	sap_ctx->acs_cfg->ht_sec_ch = 0;

	cb_mode = sme_SelectCBMode(hal, sap_ctx->csrRoamProfile.phyMode,
					channel, sec_ch,
                                        &sap_ctx->acs_cfg->ch_width,
					sap_ctx->acs_cfg->ch_width);

	if (cb_mode == eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY) {
		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
	} else if (cb_mode == eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY) {
		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
	} else if (cb_mode == eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW) {
		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
		sap_ctx->acs_cfg->vht_seg0_center_ch = sap_ctx->acs_cfg->pri_ch
									 + 6;
	} else if (cb_mode == eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW) {
		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
		sap_ctx->acs_cfg->vht_seg0_center_ch = sap_ctx->acs_cfg->pri_ch
									 + 2;
	} else if (cb_mode == eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH) {
		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch + 4;
		sap_ctx->acs_cfg->vht_seg0_center_ch = sap_ctx->acs_cfg->pri_ch
									 - 2;
	} else if (cb_mode == eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH) {
		sap_ctx->acs_cfg->ht_sec_ch = sap_ctx->acs_cfg->pri_ch - 4;
		sap_ctx->acs_cfg->vht_seg0_center_ch = sap_ctx->acs_cfg->pri_ch
									 - 6;
	}

}



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

  FUNCTION    WLANSAP_PreStartBssAcsScanCallback()

  DESCRIPTION
    Callback for Scan (scan results) Events

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
    tHalHandle:  the tHalHandle passed in with the scan request
    *p2: the second context pass in for the caller, opaque sap Handle here
    scanID:
    sessionId: Session identifier
    status: Status of scan -success, failure or abort

  RETURN VALUE
    The eHalStatus code associated with performing the operation

    eHAL_STATUS_SUCCESS:  Success

  SIDE EFFECTS

============================================================================*/
eHalStatus
WLANSAP_PreStartBssAcsScanCallback
(
  tHalHandle halHandle,
  void *pContext,
  v_U8_t sessionId,
  v_U32_t scanID,
  eCsrScanStatus scanStatus
)
{
    tScanResultHandle pResult = NULL;
    eHalStatus scanGetResultStatus = eHAL_STATUS_FAILURE;
    ptSapContext psapContext = (ptSapContext)pContext;
    v_U8_t operChannel = 0;
    VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
    eHalStatus halStatus = eHAL_STATUS_FAILURE;

    if ( eCSR_SCAN_SUCCESS == scanStatus)
    {
        VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("CSR scanStatus = %s (%d)"),
                   "eCSR_SCAN_SUCCESS", scanStatus);
        /*
         * Now do
         * 1. Get scan results
         * 2. Run channel selection algorithm
         * select channel and store in pSapContext->Channel
         */
        scanGetResultStatus = sme_ScanGetResult(halHandle,
                                                psapContext->sessionId,
                                                NULL, &pResult);

        if ((scanGetResultStatus != eHAL_STATUS_SUCCESS) &&
            (scanGetResultStatus != eHAL_STATUS_E_NULL_VALUE))
        {
            /*
             * No scan results
             * So, set the operation channel not selected
             * to allow the default channel to be set when
             * reporting to HDD
             */
            operChannel = SAP_CHANNEL_NOT_SELECTED;
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                       FL("Get scan result failed! ret = %d"),
                       scanGetResultStatus);
        }
        else
        {
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
            if (scanID != 0)
            {
                VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                           "%s: Sending ACS Scan skip event", __func__);
                sapSignalHDDevent(psapContext, NULL,
                                  eSAP_ACS_SCAN_SUCCESS_EVENT,
                                  (v_PVOID_t) eSAP_STATUS_SUCCESS);
            }
            else
            {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          "%s: ACS scan id: %d (skipped ACS SCAN)",
                          __func__, scanID);
            }
#endif
            operChannel = sapSelectChannel(halHandle, psapContext, pResult);
            if (!operChannel) {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("No channel was selected from preferred channel for Operating channel"));

                operChannel = psapContext->acs_cfg->start_ch;

                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("Selecting operating channel as starting channel from preferred channel list: %d"),
                          operChannel);
            }

            sme_ScanResultPurge(halHandle, pResult);
        }

        if (operChannel == SAP_CHANNEL_NOT_SELECTED)
#ifdef SOFTAP_CHANNEL_RANGE
        {
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
                       FL("No suitable channel selected"));

            if ( eCSR_BAND_ALL ==  psapContext->scanBandPreference ||
                     psapContext->allBandScanned == eSAP_TRUE)
            {
                halStatus = sapSignalHDDevent(psapContext, NULL,
                                      eSAP_ACS_CHANNEL_SELECTED,
                                      (v_PVOID_t) eSAP_STATUS_FAILURE);
            }
            else
            {
                VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
                           FL("Has scan band preference"));
                if (eCSR_BAND_24 == psapContext->currentPreferredBand)
                    psapContext->currentPreferredBand = eCSR_BAND_5G;
                else
                    psapContext->currentPreferredBand = eCSR_BAND_24;

                psapContext->allBandScanned = eSAP_TRUE;
                /*
                 * Go back to scanning, scan next band
                 *
                 * 1. No need to pass the second parameter
                 * as the SAP state machine is not started yet
                 * and there is no need for any event posting.
                 *
                 * 2. Set third parameter to TRUE to indicate the
                 * channel selection function to register a
                 * different scan callback fucntion to process
                 * the results pre start BSS.
                 */
                vosStatus = sapGotoChannelSel(psapContext, NULL, VOS_TRUE);
                if (VOS_STATUS_SUCCESS == vosStatus)
                {
                    halStatus = eHAL_STATUS_SUCCESS;
                }
                return halStatus;
            }
        }
#else
        psapContext->channel = sap_select_default_oper_chan_ini(halHandle, 0);
#endif
        else
        {
            /*
             * Valid Channel Found from scan results.
             */
            psapContext->acs_cfg->pri_ch = operChannel;
            psapContext->channel = operChannel;
            sap_config_acs_result(halHandle, psapContext,
                                             psapContext->acs_cfg->ht_sec_ch);
        }

#ifdef SOFTAP_CHANNEL_RANGE
        if(psapContext->channelList != NULL)
        {
            /*
             * Always free up the memory for
             * channel selection whatever
             * the result
             */
            vos_mem_free(psapContext->channelList);
            psapContext->channelList = NULL;
            psapContext->num_of_channel = 0;
        }
#endif

        VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("Channel selected = %d"), psapContext->channel);

        /*
         * By now, Channel should be selected
         * post a message to HDD to indicate
         * the ACS channel selection complete.
         */
        halStatus = sapSignalHDDevent(psapContext, NULL,
                                      eSAP_ACS_CHANNEL_SELECTED,
                                      (v_PVOID_t) eSAP_STATUS_SUCCESS);
    }
    else
    {
#ifdef SOFTAP_CHANNEL_RANGE
        if(psapContext->channelList != NULL)
        {
            /*
             * Always free up the memory for
             * channel selection whatever
             * the result
             */
            vos_mem_free(psapContext->channelList);
            psapContext->channelList = NULL;
            psapContext->num_of_channel = 0;
        }
#endif

        VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                   FL("CSR scanStatus = %s (%d), choose default channel"),
                   "eCSR_SCAN_ABORT/FAILURE", scanStatus );
#ifdef SOFTAP_CHANNEL_RANGE
        psapContext->channel = sap_select_default_oper_chan_ini(halHandle,
                                         psapContext->acs_cfg->hw_mode);
#else
        psapContext->channel = sap_select_default_oper_chan_ini(halHandle, 0);
#endif
        halStatus = sapSignalHDDevent(psapContext, NULL,
                                      eSAP_ACS_CHANNEL_SELECTED,
                                      (v_PVOID_t) eSAP_STATUS_SUCCESS);
    }
    return halStatus;
}

/*==========================================================================
  FUNCTION    WLANSAP_RoamCallback()

  DESCRIPTION
    Callback for Roam (connection status) Events

  DEPENDENCIES
    NA.

  PARAMETERS

    IN
      pContext      : pContext passed in with the roam request
      pCsrRoamInfo  : Pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and
      eRoamCmdResult: For detail valid members. It may be NULL
      roamId        : To identify the callback related roam request. 0 means unsolicited
      roamStatus    : Flag indicating the status of the callback
      roamResult    : Result

  RETURN VALUE
    The eHalStatus code associated with performing the operation

    eHAL_STATUS_SUCCESS: Success

  SIDE EFFECTS
============================================================================*/
eHalStatus
WLANSAP_RoamCallback
(
    void *pContext,           /* Opaque SAP handle */
    tCsrRoamInfo *pCsrRoamInfo,
    v_U32_t roamId,
    eRoamCmdStatus roamStatus,
    eCsrRoamResult roamResult
)
{
    /* sapContext value */
    ptSapContext sapContext = (ptSapContext) pContext;
    tWLAN_SAPEvent sapEvent; /* State machine event */
    VOS_STATUS  vosStatus = VOS_STATUS_SUCCESS;
    eHalStatus halStatus = eHAL_STATUS_SUCCESS;
    tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx);
    tpAniSirGlobal pMac = NULL;
    tANI_U8 dfs_beacon_start_req = 0;

    if (NULL == hHal)
    {
        VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                  "In %s invalid hHal", __func__);
        halStatus = eHAL_STATUS_FAILED_ALLOC;
        return halStatus;
    }
    else
    {
        pMac = PMAC_STRUCT( hHal );
    }

    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                 FL("before switch on roamStatus = %d"),
                 roamStatus);
    switch(roamStatus)
    {
        case eCSR_ROAM_SESSION_OPENED:
        {
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                      FL("Session %d opened successfully"),
                                 sapContext->sessionId);
            sapContext->isSapSessionOpen = eSAP_TRUE;
            vos_event_set(&sapContext->sap_session_opened_evt);
            break;
        }

        case eCSR_ROAM_INFRA_IND:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                           "eCSR_ROAM_INFRA_IND", roamStatus);
            if(roamResult == eCSR_ROAM_RESULT_INFRA_START_FAILED)
            {
                /* Fill in the event structure */
                sapEvent.event = eSAP_MAC_START_FAILS;
                sapEvent.params = pCsrRoamInfo;
                sapEvent.u1 = roamStatus;
                sapEvent.u2 = roamResult;

                /* Handle event */
                vosStatus = sapFsm(sapContext, &sapEvent);
                if(!VOS_IS_STATUS_SUCCESS(vosStatus))
                {
                    halStatus = eHAL_STATUS_FAILURE;
                }
            }
            break;

        case eCSR_ROAM_LOSTLINK:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_LOSTLINK", roamStatus);
            break;

        case eCSR_ROAM_MIC_ERROR_IND:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_MIC_ERROR_IND", roamStatus);
            break;

        case eCSR_ROAM_SET_KEY_COMPLETE:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_SET_KEY_COMPLETE", roamStatus);
            if (roamResult == eCSR_ROAM_RESULT_FAILURE )
            {
                /* Format the SET KEY complete information pass to HDD... */
                sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_SET_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE);
            }
            break;

        case eCSR_ROAM_REMOVE_KEY_COMPLETE:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_REMOVE_KEY_COMPLETE", roamStatus);
            if (roamResult == eCSR_ROAM_RESULT_FAILURE )
            {
                /* Format the SET KEY complete information pass to HDD... */
                sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_DEL_KEY_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE);
            }
            break;

        case eCSR_ROAM_ASSOCIATION_COMPLETION:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_ASSOCIATION_COMPLETION", roamStatus);
            if (roamResult == eCSR_ROAM_RESULT_FAILURE )
            {
                /* Format the SET KEY complete information pass to HDD... */
                sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_REASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE);
            }
            break;

        case eCSR_ROAM_DISASSOCIATED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_DISASSOCIATED", roamStatus);
            if (roamResult == eCSR_ROAM_RESULT_MIC_FAILURE)
            {
                /* Format the MIC failure event to return... */
                sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE);
            }
            break;

        case eCSR_ROAM_WPS_PBC_PROBE_REQ_IND:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_WPS_PBC_PROBE_REQ_IND", roamStatus);
            break;
        case eCSR_ROAM_REMAIN_CHAN_READY:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_REMAIN_CHAN_READY", roamStatus);
            sapSignalHDDevent(sapContext, pCsrRoamInfo,
                              eSAP_REMAIN_CHAN_READY,
                              (v_PVOID_t) eSAP_STATUS_SUCCESS);
            break;
       case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                        FL("CSR roamStatus = %s (%d)"),
                        "eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS", roamStatus);
            sapSignalHDDevent(sapContext, pCsrRoamInfo,
                            eSAP_DISCONNECT_ALL_P2P_CLIENT,
                            (v_PVOID_t) eSAP_STATUS_SUCCESS );
            break;

       case eCSR_ROAM_SEND_P2P_STOP_BSS:
           VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                             FL("Received stopbss"));
           sapSignalHDDevent(sapContext, pCsrRoamInfo,
                            eSAP_MAC_TRIG_STOP_BSS_EVENT,
                            (v_PVOID_t) eSAP_STATUS_SUCCESS );
           break;

       case eCSR_ROAM_DFS_RADAR_IND:
           VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("Received Radar Indication"));

           VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
               "sapdfs:  Indicate eSAP_DFS_RADAR_DETECT to HDD");
           sapSignalHDDevent(sapContext, NULL, eSAP_DFS_RADAR_DETECT,
               (v_PVOID_t) eSAP_STATUS_SUCCESS);

           /* sync to latest DFS-NOL */
           sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_GET,
                   (v_PVOID_t) eSAP_STATUS_SUCCESS);

           pMac->sap.SapDfsInfo.target_channel =
                     sapIndicateRadar(sapContext, &pCsrRoamInfo->dfs_event);

           /* if there is an assigned next channel hopping */
           if (0 < pMac->sap.SapDfsInfo.user_provided_target_channel)
           {
               pMac->sap.SapDfsInfo.target_channel =
                   pMac->sap.SapDfsInfo.user_provided_target_channel;
               pMac->sap.SapDfsInfo.user_provided_target_channel = 0;
           }

           if (pMac->sap.SapDfsInfo.target_channel == 0) {
               /* No available channel found */
               v_U8_t  intf;
               /* Issue stopbss for each sapctx */
               for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
               {
                    ptSapContext pSapContext;

                    if (((VOS_STA_SAP_MODE ==
                         pMac->sap.sapCtxList[intf].sapPersona) ||
                         (VOS_P2P_GO_MODE ==
                         pMac->sap.sapCtxList[intf].sapPersona)) &&
                         pMac->sap.sapCtxList[intf].pSapContext != NULL )
                    {
                        pSapContext = pMac->sap.sapCtxList[intf].pSapContext;
                        VOS_TRACE(VOS_MODULE_ID_SAP,
                                  VOS_TRACE_LEVEL_ERROR,
                        "sapdfs: no available channel for sapctx[%pK], StopBss",
                                  pSapContext);

                        WLANSAP_StopBss(pSapContext);
                     }
               }
               break;
           }

           pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
           sap_CacResetNotify(hHal);

           /* set DFS-NOL back to keep it update-to-date in CNSS */
           sapSignalHDDevent(sapContext, NULL, eSAP_DFS_NOL_SET,
                   (v_PVOID_t) eSAP_STATUS_SUCCESS);

           break;

       case eCSR_ROAM_DFS_CHAN_SW_NOTIFY:
           VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                     "In %s, Received Chan Sw Update Notification", __func__);
           break;

       case eCSR_ROAM_SET_CHANNEL_RSP:
           VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                     "In %s, Received set channel response", __func__);
           break;
       case eCSR_ROAM_EXT_CHG_CHNL_IND:
           VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                   "In %s, Received set channel Indication", __func__);
           break;
       default:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                         FL("CSR roamStatus not handled roamStatus = %s (%d)"),
                         get_eRoamCmdStatus_str(roamStatus), roamStatus);
            break;

    }
    VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                   FL("Before switch on roamResult = %d"), roamResult);
    switch (roamResult)
    {
        case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                         FL( "CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND",
                              roamResult);
            sapContext->nStaWPARSnReqIeLength = pCsrRoamInfo->rsnIELen;

            if(sapContext->nStaWPARSnReqIeLength)
                vos_mem_copy( sapContext->pStaWpaRsnReqIE,
                              pCsrRoamInfo->prsnIE, sapContext->nStaWPARSnReqIeLength);

#ifdef FEATURE_WLAN_WAPI
            sapContext->nStaWAPIReqIeLength = pCsrRoamInfo->wapiIELen;

            if(sapContext->nStaWAPIReqIeLength)
                vos_mem_copy( sapContext->pStaWapiReqIE,
                              pCsrRoamInfo->pwapiIE, sapContext->nStaWAPIReqIeLength);
#endif
            sapContext->nStaAddIeLength = pCsrRoamInfo->addIELen;

            if(sapContext->nStaAddIeLength)
                vos_mem_copy( sapContext->pStaAddIE,
                        pCsrRoamInfo->paddIE, sapContext->nStaAddIeLength);

            sapContext->SapQosCfg.WmmIsEnabled = pCsrRoamInfo->wmmEnabledSta;
            // MAC filtering
            vosStatus = sapIsPeerMacAllowed(sapContext, (v_U8_t *)pCsrRoamInfo->peerMac);

            if ( VOS_STATUS_SUCCESS == vosStatus )
            {
                vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_ASSOC_IND, (v_PVOID_t)eSAP_STATUS_SUCCESS);
                if(!VOS_IS_STATUS_SUCCESS(vosStatus))
                {
                   VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                             FL("CSR roamResult = (%d) MAC ("
                             MAC_ADDRESS_STR") fail"),
                             roamResult,
                             MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac));
                    halStatus = eHAL_STATUS_FAILURE;
                }
            }
            else
            {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
                          FL("CSR roamResult = (%d) MAC ("
                          MAC_ADDRESS_STR") not allowed"),
                          roamResult,
                          MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac));
                halStatus = eHAL_STATUS_FAILURE;
            }

            break;

        case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF",
                              roamResult);

            sapContext->nStaWPARSnReqIeLength = pCsrRoamInfo->rsnIELen;
            if (sapContext->nStaWPARSnReqIeLength)
                vos_mem_copy( sapContext->pStaWpaRsnReqIE,
                              pCsrRoamInfo->prsnIE, sapContext->nStaWPARSnReqIeLength);

            sapContext->nStaAddIeLength = pCsrRoamInfo->addIELen;
            if(sapContext->nStaAddIeLength)
                vos_mem_copy( sapContext->pStaAddIE,
                    pCsrRoamInfo->paddIE, sapContext->nStaAddIeLength);

            sapContext->SapQosCfg.WmmIsEnabled = pCsrRoamInfo->wmmEnabledSta;
            /* Fill in the event structure */
            vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_ASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_DEAUTH_IND:
        case eCSR_ROAM_RESULT_DISASSOC_IND:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_DISASSOC_IND",
                              roamResult);
            /* Fill in the event structure */
            vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_MIC_ERROR_GROUP:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_MIC_ERROR_GROUP",
                              roamResult);
            /* Fill in the event structure */
            //TODO: support for group key MIC failure event to be handled
            vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) NULL);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST",
                              roamResult);
            /* Fill in the event structure */
            //TODO: support for unicast key MIC failure event to be handled
            vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) NULL);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_AUTHENTICATED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_AUTHENTICATED",
                              roamResult);
            /* Fill in the event structure */
            vosStatus = sapSignalHDDevent(sapContext,
                                  pCsrRoamInfo,eSAP_STA_SET_KEY_EVENT,
                                  (v_PVOID_t)eSAP_STATUS_SUCCESS);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_ASSOCIATED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_ASSOCIATED",
                              roamResult);
            /* Fill in the event structure */
            sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_REASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS);
            break;

        case eCSR_ROAM_RESULT_INFRA_STARTED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_INFRA_STARTED",
                              roamResult);

            /* In the current implementation, hostapd is not aware that
             * drive will support DFS. Hence, driver should inform
             * eSAP_MAC_START_BSS_SUCCESS to upper layers and then perform
             * CAC underneath
             */
            sapEvent.event = eSAP_MAC_START_BSS_SUCCESS;
            sapEvent.params = pCsrRoamInfo;
            sapEvent.u1 = roamStatus;
            sapEvent.u2 = roamResult;

            vosStatus = sapFsm(sapContext, &sapEvent);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_INFRA_STOPPED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_INFRA_STOPPED",
                              roamResult);
            /* Fill in the event structure */
            sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;
            sapEvent.params = pCsrRoamInfo;
            sapEvent.u1 = roamStatus;
            sapEvent.u2 = roamResult;

            /* Handle event */
            vosStatus = sapFsm(sapContext, &sapEvent);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND",
                              roamResult);
            /* Fill in the event structure */
            //TODO: support for group key MIC failure event to be handled
            vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_WPS_PBC_PROBE_REQ_EVENT,(v_PVOID_t) NULL);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;

        case eCSR_ROAM_RESULT_FORCED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_FORCED",
                              roamResult);
            //This event can be used to inform hdd about user triggered disassoc event
            /* Fill in the event structure */
            sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS);
            break;

        case eCSR_ROAM_RESULT_NONE:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_NONE",
                              roamResult);
            //This event can be used to inform hdd about user triggered disassoc event
            /* Fill in the event structure */
            if ( roamStatus == eCSR_ROAM_SET_KEY_COMPLETE)
            {
                sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_SET_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_SUCCESS);
            }
            else if (roamStatus == eCSR_ROAM_REMOVE_KEY_COMPLETE )
            {
                sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_DEL_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_SUCCESS);
            }
            break;

        case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,
                          FL("CSR roamResult = %s (%d)"),
                             "eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED",
                              roamResult);
            /* Fill in the event structure */
            vosStatus = sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_MAX_ASSOC_EXCEEDED, (v_PVOID_t)NULL);
            if(!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }

            break;

        case eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND:
            if (eSAP_DFS_CAC_WAIT == sapContext->sapsMachine)
            {
                if (sapContext->csrRoamProfile.disableDFSChSwitch) {
                    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          "sapdfs: DFS channel switch disabled");
                    break;
                }
                if (VOS_TRUE == pMac->sap.SapDfsInfo.sap_radar_found_status)
                {
                    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                    "sapdfs:Posting event eSAP_DFS_CHANNEL_CAC_RADAR_FOUND");
                    /*
                     * If Radar is found, while in DFS CAC WAIT State then
                     * post stop and destroy the CAC timer and post a
                     * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND  to sapFsm.
                     */
                    vos_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
                    vos_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
                    pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;

                    /*
                     * User space is already indicated the CAC start and if
                     * CAC end on this channel is not indicated, the user
                     * space will be in some undefined state (e.g., UI frozen)
                     */
                    vosStatus = sapSignalHDDevent(sapContext, NULL,
                                          eSAP_DFS_CAC_INTERRUPTED,
                                          (v_PVOID_t) eSAP_STATUS_SUCCESS);
                    if (VOS_STATUS_SUCCESS != vosStatus) {
                            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                                FL("Failed to send CAC end"));
                            /* Want to still proceed and try to switch channel.
                             * Lets try not to be on the DFS channel
                             */
                    }

                    sapEvent.event = eSAP_DFS_CHANNEL_CAC_RADAR_FOUND;
                    sapEvent.params = 0;
                    sapEvent.u1 = 0;
                    sapEvent.u2 = 0;
                    vosStatus = sapFsm(sapContext, &sapEvent);
                    if(!VOS_IS_STATUS_SUCCESS(vosStatus))
                    {
                        halStatus = eHAL_STATUS_FAILURE;
                    }
                }
            }
            else if(eSAP_STARTED == sapContext->sapsMachine)
            {
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                "sapdfs:Posting event eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START");

                /* Radar found on the operating channel in STARTED state,
                 * new operating channel has already been selected. Send
                 * request to SME-->PE for sending CSA IE
                 */
                sapEvent.event = eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START;
                sapEvent.params = 0;
                sapEvent.u1 = 0;
                sapEvent.u2 = 0;
                vosStatus = sapFsm(sapContext, &sapEvent);
                if(!VOS_IS_STATUS_SUCCESS(vosStatus))
                {
                  halStatus = eHAL_STATUS_FAILURE;
                }
            }
            else
            {
                /* Further actions to be taken here */
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                         "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in (%d) state"
                         , __func__, sapContext->sapsMachine);
            }
            break;

        case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_SUCCESS:
        case eCSR_ROAM_RESULT_DFS_CHANSW_UPDATE_FAILURE:
        {
            eCsrPhyMode phyMode = sapContext->csrRoamProfile.phyMode;

            if (sapContext->csrRoamProfile.disableDFSChSwitch) {
                VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
                          "sapdfs: DFS channel switch disabled");
                /*
                 * Send a beacon start request to PE. CSA IE required
                 * flag from beacon template will be cleared by now.
                 * A new beacon template with no CSA IE will be sent
                 * to firmware.
                 */
                dfs_beacon_start_req = VOS_TRUE;
                halStatus = sme_RoamStartBeaconReq( hHal,
                                                    sapContext->bssid,
                                                    dfs_beacon_start_req);
                break;
            }

            /* Both success and failure cases are handled intentionally handled
             * together. Irrespective of whether the channel switch IE was
             * sent out successfully or not, SAP should still vacate the
             * channel immediately
             */
            if (eSAP_STARTED == sapContext->sapsMachine)
            {
               VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                          "sapdfs: from state %s => %s",
                          "eSAP_STARTED", "eSAP_DISCONNECTING");

               /* SAP to be moved to DISCONNECTING state */
               sapContext->sapsMachine = eSAP_DISCONNECTING;

               /* The associated stations have been informed to move
                * to a different channel. However, the AP may not always
                * select the advertised channel for operation if the radar
                * is seen. In that case, the stations will experience link-loss
                * and return back through scanning if they wish to
                */

               /* Send channel change request
                * From spec it is required that the AP should continue to
                * operate in the same mode as it is operating currently.
                * For e.g. 20/40/80 MHz operation
                */
                if (pMac->sap.SapDfsInfo.target_channel)
                {
                     sme_SelectCBMode(hHal, phyMode,
                                      pMac->sap.SapDfsInfo.target_channel,
                                      0, &sapContext->vht_channel_width,
                                      sapContext->ch_width_orig);
                }

                /*
                 * Fetch the number of SAP interfaces.
                 * If the number of sap Interface more than
                 * one then we will make is_sap_ready_for_chnl_chng to true
                 * for that sapctx
                 *
                 * If there is only one SAP interface then process immediately
                 */

                if (sap_get_total_number_sap_intf(hHal) > 1)
                {
                    v_U8_t  intf;
                    sapContext->is_sap_ready_for_chnl_chng = VOS_TRUE;
                    /*
                     * now check if the con-current sap interface is ready
                     * for channel change.
                     * If yes then we issue channel change for both the
                     * SAPs.
                     * If no then simply return success & we will issue channel
                     * change when second AP's 5 CSA beacon Tx is completed.
                     */
                     if (VOS_TRUE ==
                         is_concurrent_sap_ready_for_channel_change(hHal,
                                                                    sapContext))
                     {
                         /* Issue channel change req for each sapctx */
                         for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++)
                         {
                              ptSapContext pSapContext;
                              if (((VOS_STA_SAP_MODE ==
                                  pMac->sap.sapCtxList[intf].sapPersona) ||
                                  (VOS_P2P_GO_MODE ==
                                  pMac->sap.sapCtxList[intf].sapPersona)) &&
                                  (pMac->sap.sapCtxList[intf].pSapContext !=
                                   NULL))
                              {
                                   pSapContext =
                                      pMac->sap.sapCtxList[intf].pSapContext;
                                      VOS_TRACE(VOS_MODULE_ID_SAP,
                                                VOS_TRACE_LEVEL_INFO_MED,
                                    "sapdfs:issue chnl change for sapctx[%pK]",
                                                pSapContext);
                                   /* Send channel switch request */
                                   sapEvent.event = eWNI_SME_CHANNEL_CHANGE_REQ;
                                   sapEvent.params = 0;
                                   sapEvent.u1 = 0;
                                   sapEvent.u2 = 0;


                                   /* Handle event */
                                   vosStatus = sapFsm(pSapContext, &sapEvent);
                                   if(!VOS_IS_STATUS_SUCCESS(vosStatus))
                                   {
                                       halStatus = eHAL_STATUS_FAILURE;
                                       VOS_TRACE(VOS_MODULE_ID_SAP,
                                                 VOS_TRACE_LEVEL_ERROR,
                                       FL("post chnl chng req failed, sap[%pK]"),
                                       sapContext);
                                   }
                                   else
                                   {
                                       pSapContext->is_sap_ready_for_chnl_chng =
                                        VOS_FALSE;
                                   }

                               }
                         }
                     }
                     else
                     {
                         VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                         FL("sapdfs: sapctx[%pK] ready but not concurrent sap"),
                         sapContext);

                         halStatus = eHAL_STATUS_SUCCESS;
                     }
                }
                else
                {
                    /* Send channel switch request */
                    sapEvent.event = eWNI_SME_CHANNEL_CHANGE_REQ;
                    sapEvent.params = 0;
                    sapEvent.u1 = 0;
                    sapEvent.u2 = 0;

                    VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                    "sapdfs: Posting event eWNI_SME_CHANNEL_CHANGE_REQ to sapFSM");

                    /* Handle event */
                    vosStatus = sapFsm(sapContext, &sapEvent);
                    if(!VOS_IS_STATUS_SUCCESS(vosStatus))
                    {
                       halStatus = eHAL_STATUS_FAILURE;
                    }
                }
            }
            else
            {
                /* Further actions to be taken here */
                VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN,
                         "In %s, eCSR_ROAM_RESULT_DFS_RADAR_FOUND_IND received in (%d) state",
                         __func__, sapContext->sapsMachine);
            }
            break;
        }
        case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS:
        {
            /* Channel change is successful. If the new channel is a DFS
             * channel, then we will to perform channel availability check
             * for 60 seconds
             */
            VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                      "sapdfs: changing target channel to [%d]",
                      pMac->sap.SapDfsInfo.target_channel);

            sapContext->channel =
                  pMac->sap.SapDfsInfo.target_channel;

            /* Identify if this is channel change in radar detected state */
            if (eSAP_DISCONNECTING == sapContext->sapsMachine)
            {
               /* check if currently selected channel is a DFS channel */
               if (NV_CHANNEL_DFS ==
                     vos_nv_getChannelEnabledState(sapContext->channel))
               {
                   if ((VOS_FALSE == pMac->sap.SapDfsInfo.ignore_cac) &&
                        (eSAP_DFS_DO_NOT_SKIP_CAC ==
                         pMac->sap.SapDfsInfo.cac_state))
                   {
                      sapContext->sapsMachine = eSAP_DISCONNECTED;

                      VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                      "sapdfs: from state %s => %s with ignore cac FALSE on sapctx[%pK]",
                      "eSAP_DISCONNECTING", "DISCONNECTED", sapContext);

                      /* DFS Channel */
                      sapEvent.event = eSAP_DFS_CHANNEL_CAC_START;
                      sapEvent.params = pCsrRoamInfo;
                      sapEvent.u1 = 0;
                      sapEvent.u2 = 0;
                   }
                   else
                   {
                      VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                      "sapdfs: from state %s => %s with ignore cac TRUE on sapctx[%pK]",
                      "eSAP_DISCONNECTING", "eSAP_STARTING", sapContext);

                      /* Start beaconing on the new channel */
                      WLANSAP_StartBeaconReq((v_PVOID_t)sapContext);
                      sapContext->sapsMachine = eSAP_STARTING;
                      pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_FALSE;
                      sapEvent.event = eSAP_MAC_START_BSS_SUCCESS;
                      sapEvent.params = pCsrRoamInfo;
                      sapEvent.u1 = eCSR_ROAM_INFRA_IND;
                      sapEvent.u2 = eCSR_ROAM_RESULT_INFRA_STARTED;
                   }
               }
               else
               {
                  VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_MED,
                  "sapdfs: from state %s => %s on sapctx[%pK]",
                  "eSAP_DISCONNECTING", "eSAP_STARTING", sapContext);

                  /* non-DFS channel */
                  sapContext->sapsMachine = eSAP_STARTING;
                  pMac->sap.SapDfsInfo.sap_radar_found_status = VOS_FALSE;
                  sapEvent.event = eSAP_MAC_START_BSS_SUCCESS;
                  sapEvent.params = pCsrRoamInfo;
                  sapEvent.u1 = eCSR_ROAM_INFRA_IND;
                  sapEvent.u2 = eCSR_ROAM_RESULT_INFRA_STARTED;
               }

               /* Handle the event */
               vosStatus = sapFsm(sapContext, &sapEvent);
               if(!VOS_IS_STATUS_SUCCESS(vosStatus))
               {
                  halStatus = eHAL_STATUS_FAILURE;
               }

            }
            else
            {
               /* We may have a requirment in the future for SAP to perform
                * channel change, hence leaving this here
                */
            }

            break;
        }
        case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE:
        {
            /* This is much more serious issue, we have to vacate the
             * channel due to the presence of radar but our channel change
             * failed, stop the BSS operation completely and inform hostapd
             */
            sapEvent.event = eWNI_SME_CHANNEL_CHANGE_RSP;
            sapEvent.params = 0;
            sapEvent.u1 = eCSR_ROAM_INFRA_IND;
            sapEvent.u2 = eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE;

            vosStatus = sapFsm(sapContext, &sapEvent);
            if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;
        }
        case eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND:
        {
            vosStatus = sapSignalHDDevent(sapContext, pCsrRoamInfo,
                               eSAP_ECSA_CHANGE_CHAN_IND, (v_PVOID_t)NULL);
            if (!VOS_IS_STATUS_SUCCESS(vosStatus))
            {
                halStatus = eHAL_STATUS_FAILURE;
            }
            break;
        }
        default:
            VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
                          FL("CSR roamResult = %s (%d) not handled"),
                             get_eCsrRoamResult_str(roamResult),
                             roamResult);
            break;
    }

    return halStatus;
}
