blob: 8c7c26dcd718b71a641077f4600a288e7e446f0a [file] [log] [blame]
/*
* 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;
}