blob: b29c3671b0c8f67197aefcad06cd5899615218df [file] [log] [blame]
/*
* Copyright (c) 2011-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.
*/
/** ------------------------------------------------------------------------- *
------------------------------------------------------------------------- *
\file csrUtil.c
Implementation supporting routines for CSR.
========================================================================== */
#include "aniGlobal.h"
#include "palApi.h"
#include "csrSupport.h"
#include "csrInsideApi.h"
#include "smsDebug.h"
#include "smeQosInternal.h"
#include "wlan_qct_wda.h"
#include "vos_utils.h"
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "csrEse.h"
#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD*/
tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ] = {
{ 0x00, 0x50, 0xf2, 0x00 },
{ 0x00, 0x50, 0xf2, 0x01 },
{ 0x00, 0x50, 0xf2, 0x02 },
{ 0x00, 0x50, 0xf2, 0x03 },
{ 0x00, 0x50, 0xf2, 0x04 },
{ 0x00, 0x50, 0xf2, 0x05 },
#ifdef FEATURE_WLAN_ESE
{ 0x00, 0x40, 0x96, 0x00 }, // CCKM
#endif /* FEATURE_WLAN_ESE */
};
tANI_U8 csrRSNOui[][ CSR_RSN_OUI_SIZE ] = {
{ 0x00, 0x0F, 0xAC, 0x00 }, // group cipher
{ 0x00, 0x0F, 0xAC, 0x01 }, // WEP-40 or RSN
{ 0x00, 0x0F, 0xAC, 0x02 }, // TKIP or RSN-PSK
{ 0x00, 0x0F, 0xAC, 0x03 }, // Reserved
{ 0x00, 0x0F, 0xAC, 0x04 }, // AES-CCMP
{ 0x00, 0x0F, 0xAC, 0x05 }, // WEP-104
{ 0x00, 0x40, 0x96, 0x00 }, // CCKM
{ 0x00, 0x0F, 0xAC, 0x06 }, // BIP (encryption type) or RSN-PSK-SHA256 (authentication type)
/* RSN-8021X-SHA256 (authentication type) */
{ 0x00, 0x0F, 0xAC, 0x05 },
#ifdef WLAN_FEATURE_FILS_SK
#define ENUM_FILS_SHA256 9
/* FILS SHA256 */
{0x00, 0x0F, 0xAC, 0x0E},
#define ENUM_FILS_SHA384 10
/* FILS SHA384 */
{0x00, 0x0F, 0xAC, 0x0F},
#define ENUM_FT_FILS_SHA256 11
/* FILS FT SHA256 */
{0x00, 0x0F, 0xAC, 0x10},
#define ENUM_FT_FILS_SHA384 12
/* FILS FT SHA384 */
{0x00, 0x0F, 0xAC, 0x11}
#endif
/* define new oui here */
};
#ifdef FEATURE_WLAN_WAPI
tANI_U8 csrWapiOui[][ CSR_WAPI_OUI_SIZE ] = {
{ 0x00, 0x14, 0x72, 0x00 }, // Reserved
{ 0x00, 0x14, 0x72, 0x01 }, // WAI certificate or SMS4
{ 0x00, 0x14, 0x72, 0x02 } // WAI PSK
};
#endif /* FEATURE_WLAN_WAPI */
tANI_U8 csrWmeInfoOui[ CSR_WME_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 };
tANI_U8 csrWmeParmOui[ CSR_WME_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 };
static tCsrIELenInfo gCsrIELengthTable[] = {
/* 000 */ { SIR_MAC_SSID_EID_MIN, SIR_MAC_SSID_EID_MAX },
/* 001 */ { SIR_MAC_RATESET_EID_MIN, SIR_MAC_RATESET_EID_MAX },
/* 002 */ { SIR_MAC_FH_PARAM_SET_EID_MIN, SIR_MAC_FH_PARAM_SET_EID_MAX },
/* 003 */ { SIR_MAC_DS_PARAM_SET_EID_MIN, SIR_MAC_DS_PARAM_SET_EID_MAX },
/* 004 */ { SIR_MAC_CF_PARAM_SET_EID_MIN, SIR_MAC_CF_PARAM_SET_EID_MAX },
/* 005 */ { SIR_MAC_TIM_EID_MIN, SIR_MAC_TIM_EID_MAX },
/* 006 */ { SIR_MAC_IBSS_PARAM_SET_EID_MIN, SIR_MAC_IBSS_PARAM_SET_EID_MAX },
/* 007 */ { SIR_MAC_COUNTRY_EID_MIN, SIR_MAC_COUNTRY_EID_MAX },
/* 008 */ { SIR_MAC_FH_PARAMS_EID_MIN, SIR_MAC_FH_PARAMS_EID_MAX },
/* 009 */ { SIR_MAC_FH_PATTERN_EID_MIN, SIR_MAC_FH_PATTERN_EID_MAX },
/* 010 */ { SIR_MAC_REQUEST_EID_MIN, SIR_MAC_REQUEST_EID_MAX },
/* 011 */ { SIR_MAC_QBSS_LOAD_EID_MIN, SIR_MAC_QBSS_LOAD_EID_MAX },
/* 012 */ { SIR_MAC_EDCA_PARAM_SET_EID_MIN, SIR_MAC_EDCA_PARAM_SET_EID_MAX },
/* 013 */ { SIR_MAC_TSPEC_EID_MIN, SIR_MAC_TSPEC_EID_MAX },
/* 014 */ { SIR_MAC_TCLAS_EID_MIN, SIR_MAC_TCLAS_EID_MAX },
/* 015 */ { SIR_MAC_QOS_SCHEDULE_EID_MIN, SIR_MAC_QOS_SCHEDULE_EID_MAX },
/* 016 */ { SIR_MAC_CHALLENGE_TEXT_EID_MIN, SIR_MAC_CHALLENGE_TEXT_EID_MAX },
/* 017 */ { 0, 255 },
/* 018 */ { 0, 255 },
/* 019 */ { 0, 255 },
/* 020 */ { 0, 255 },
/* 021 */ { 0, 255 },
/* 022 */ { 0, 255 },
/* 023 */ { 0, 255 },
/* 024 */ { 0, 255 },
/* 025 */ { 0, 255 },
/* 026 */ { 0, 255 },
/* 027 */ { 0, 255 },
/* 028 */ { 0, 255 },
/* 029 */ { 0, 255 },
/* 030 */ { 0, 255 },
/* 031 */ { 0, 255 },
/* 032 */ { SIR_MAC_PWR_CONSTRAINT_EID_MIN, SIR_MAC_PWR_CONSTRAINT_EID_MAX },
/* 033 */ { SIR_MAC_PWR_CAPABILITY_EID_MIN, SIR_MAC_PWR_CAPABILITY_EID_MAX },
/* 034 */ { SIR_MAC_TPC_REQ_EID_MIN, SIR_MAC_TPC_REQ_EID_MAX },
/* 035 */ { SIR_MAC_TPC_RPT_EID_MIN, SIR_MAC_TPC_RPT_EID_MAX },
/* 036 */ { SIR_MAC_SPRTD_CHNLS_EID_MIN, SIR_MAC_SPRTD_CHNLS_EID_MAX },
/* 037 */ { SIR_MAC_CHNL_SWITCH_ANN_EID_MIN, SIR_MAC_CHNL_SWITCH_ANN_EID_MAX },
/* 038 */ { SIR_MAC_MEAS_REQ_EID_MIN, SIR_MAC_MEAS_REQ_EID_MAX },
/* 039 */ { SIR_MAC_MEAS_RPT_EID_MIN, SIR_MAC_MEAS_RPT_EID_MAX },
/* 040 */ { SIR_MAC_QUIET_EID_MIN, SIR_MAC_QUIET_EID_MAX },
/* 041 */ { SIR_MAC_IBSS_DFS_EID_MIN, SIR_MAC_IBSS_DFS_EID_MAX },
/* 042 */ { SIR_MAC_ERP_INFO_EID_MIN, SIR_MAC_ERP_INFO_EID_MAX },
/* 043 */ { SIR_MAC_TS_DELAY_EID_MIN, SIR_MAC_TS_DELAY_EID_MAX },
/* 044 */ { SIR_MAC_TCLAS_PROC_EID_MIN, SIR_MAC_TCLAS_PROC_EID_MAX },
/* 045 */ { SIR_MAC_QOS_ACTION_EID_MIN, SIR_MAC_QOS_ACTION_EID_MAX },
/* 046 */ { SIR_MAC_QOS_CAPABILITY_EID_MIN, SIR_MAC_QOS_CAPABILITY_EID_MAX },
/* 047 */ { 0, 255 },
/* 048 */ { SIR_MAC_RSN_EID_MIN, SIR_MAC_RSN_EID_MAX },
/* 049 */ { 0, 255 },
/* 050 */ { SIR_MAC_EXTENDED_RATE_EID_MIN, SIR_MAC_EXTENDED_RATE_EID_MAX },
/* 051 */ { 0, 255 },
/* 052 */ { 0, 255 },
/* 053 */ { 0, 255 },
/* 054 */ { 0, 255 },
/* 055 */ { 0, 255 },
/* 056 */ { 0, 255 },
/* 057 */ { 0, 255 },
/* 058 */ { 0, 255 },
/* 059 */ { SIR_MAC_OPERATING_CLASS_EID_MIN, SIR_MAC_OPERATING_CLASS_EID_MAX },
/* 060 */ { SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID_MIN, SIR_MAC_CHNL_EXTENDED_SWITCH_ANN_EID_MAX},
/* 061 */ { 0, 255 },
/* 062 */ { 0, 255 },
/* 063 */ { 0, 255 },
/* 064 */ { 0, 255 },
/* 065 */ { 0, 255 },
/* 066 */ { 0, 255 },
/* 067 */ { 0, 255 },
#ifdef FEATURE_WLAN_WAPI
/* 068 */ { DOT11F_EID_WAPI, DOT11F_IE_WAPI_MAX_LEN },
#else
/* 068 */ { 0, 255 },
#endif /* FEATURE_WLAN_WAPI */
/* 069 */ { 0, 255 },
/* 070 */ { 0, 255 },
/* 071 */ { 0, 255 },
/* 072 */ { 0, 255 },
/* 073 */ { 0, 255 },
/* 074 */ { 0, 255 },
/* 075 */ { 0, 255 },
/* 076 */ { 0, 255 },
/* 077 */ { 0, 255 },
/* 078 */ { 0, 255 },
/* 079 */ { 0, 255 },
/* 080 */ { 0, 255 },
/* 081 */ { 0, 255 },
/* 082 */ { 0, 255 },
/* 083 */ { 0, 255 },
/* 084 */ { 0, 255 },
/* 085 */ { 0, 255 },
/* 086 */ { 0, 255 },
/* 087 */ { 0, 255 },
/* 088 */ { 0, 255 },
/* 089 */ { 0, 255 },
/* 090 */ { 0, 255 },
/* 091 */ { 0, 255 },
/* 092 */ { 0, 255 },
/* 093 */ { 0, 255 },
/* 094 */ { 0, 255 },
/* 095 */ { 0, 255 },
/* 096 */ { 0, 255 },
/* 097 */ { 0, 255 },
/* 098 */ { 0, 255 },
/* 099 */ { 0, 255 },
/* 100 */ { 0, 255 },
/* 101 */ { 0, 255 },
/* 102 */ { 0, 255 },
/* 103 */ { 0, 255 },
/* 104 */ { 0, 255 },
/* 105 */ { 0, 255 },
/* 106 */ { 0, 255 },
/* 107 */ { 0, 255 },
/* 108 */ { 0, 255 },
/* 109 */ { 0, 255 },
/* 110 */ { 0, 255 },
/* 111 */ { 0, 255 },
/* 112 */ { 0, 255 },
/* 113 */ { 0, 255 },
/* 114 */ { 0, 255 },
/* 115 */ { 0, 255 },
/* 116 */ { 0, 255 },
/* 117 */ { 0, 255 },
/* 118 */ { 0, 255 },
/* 119 */ { 0, 255 },
/* 120 */ { 0, 255 },
/* 121 */ { 0, 255 },
/* 122 */ { 0, 255 },
/* 123 */ { 0, 255 },
/* 124 */ { 0, 255 },
/* 125 */ { 0, 255 },
/* 126 */ { 0, 255 },
/* 127 */ { 0, 255 },
/* 128 */ { 0, 255 },
/* 129 */ { 0, 255 },
/* 130 */ { 0, 255 },
/* 131 */ { 0, 255 },
/* 132 */ { 0, 255 },
/* 133 */ { 0, 255 },
/* 134 */ { 0, 255 },
/* 135 */ { 0, 255 },
/* 136 */ { 0, 255 },
/* 137 */ { 0, 255 },
/* 138 */ { 0, 255 },
/* 139 */ { 0, 255 },
/* 140 */ { 0, 255 },
/* 141 */ { 0, 255 },
/* 142 */ { 0, 255 },
/* 143 */ { 0, 255 },
/* 144 */ { 0, 255 },
/* 145 */ { 0, 255 },
/* 146 */ { 0, 255 },
/* 147 */ { 0, 255 },
/* 148 */ { 0, 255 },
/* 149 */ { 0, 255 },
/* 150 */ { 0, 255 },
/* 151 */ { 0, 255 },
/* 152 */ { 0, 255 },
/* 153 */ { 0, 255 },
/* 154 */ { 0, 255 },
/* 155 */ { 0, 255 },
/* 156 */ { 0, 255 },
/* 157 */ { 0, 255 },
/* 158 */ { 0, 255 },
/* 159 */ { 0, 255 },
/* 160 */ { 0, 255 },
/* 161 */ { 0, 255 },
/* 162 */ { 0, 255 },
/* 163 */ { 0, 255 },
/* 164 */ { 0, 255 },
/* 165 */ { 0, 255 },
/* 166 */ { 0, 255 },
/* 167 */ { 0, 255 },
/* 168 */ { 0, 255 },
/* 169 */ { 0, 255 },
/* 170 */ { 0, 255 },
/* 171 */ { 0, 255 },
/* 172 */ { 0, 255 },
/* 173 */ { 0, 255 },
/* 174 */ { 0, 255 },
/* 175 */ { 0, 255 },
/* 176 */ { 0, 255 },
/* 177 */ { 0, 255 },
/* 178 */ { 0, 255 },
/* 179 */ { 0, 255 },
/* 180 */ { 0, 255 },
/* 181 */ { 0, 255 },
/* 182 */ { 0, 255 },
/* 183 */ { 0, 255 },
/* 184 */ { 0, 255 },
/* 185 */ { 0, 255 },
/* 186 */ { 0, 255 },
/* 187 */ { 0, 255 },
/* 188 */ { 0, 255 },
/* 189 */ { 0, 255 },
/* 190 */ { 0, 255 },
/* 191 */ { 0, 255 },
/* 192 */ { 0, 255 },
/* 193 */ { 0, 255 },
/* 194 */ { 0, 255 },
/* 195 */ { 0, 255 },
/* 196 */ { 0, 255 },
/* 197 */ { 0, 255 },
/* 198 */ { 0, 255 },
/* 199 */ { 0, 255 },
/* 200 */ { 0, 255 },
/* 201 */ { 0, 255 },
/* 202 */ { 0, 255 },
/* 203 */ { 0, 255 },
/* 204 */ { 0, 255 },
/* 205 */ { 0, 255 },
/* 206 */ { 0, 255 },
/* 207 */ { 0, 255 },
/* 208 */ { 0, 255 },
/* 209 */ { 0, 255 },
/* 210 */ { 0, 255 },
/* 211 */ { 0, 255 },
/* 212 */ { 0, 255 },
/* 213 */ { 0, 255 },
/* 214 */ { 0, 255 },
/* 215 */ { 0, 255 },
/* 216 */ { 0, 255 },
/* 217 */ { 0, 255 },
/* 218 */ { 0, 255 },
/* 219 */ { 0, 255 },
/* 220 */ { 0, 255 },
/* 221 */ { SIR_MAC_WPA_EID_MIN, SIR_MAC_WPA_EID_MAX },
/* 222 */ { 0, 255 },
/* 223 */ { 0, 255 },
/* 224 */ { 0, 255 },
/* 225 */ { 0, 255 },
/* 226 */ { 0, 255 },
/* 227 */ { 0, 255 },
/* 228 */ { 0, 255 },
/* 229 */ { 0, 255 },
/* 230 */ { 0, 255 },
/* 231 */ { 0, 255 },
/* 232 */ { 0, 255 },
/* 233 */ { 0, 255 },
/* 234 */ { 0, 255 },
/* 235 */ { 0, 255 },
/* 236 */ { 0, 255 },
/* 237 */ { 0, 255 },
/* 238 */ { 0, 255 },
/* 239 */ { 0, 255 },
/* 240 */ { 0, 255 },
/* 241 */ { 0, 255 },
/* 242 */ { 0, 255 },
/* 243 */ { 0, 255 },
/* 244 */ { 0, 255 },
/* 245 */ { 0, 255 },
/* 246 */ { 0, 255 },
/* 247 */ { 0, 255 },
/* 248 */ { 0, 255 },
/* 249 */ { 0, 255 },
/* 250 */ { 0, 255 },
/* 251 */ { 0, 255 },
/* 252 */ { 0, 255 },
/* 253 */ { 0, 255 },
/* 254 */ { 0, 255 },
/* 255 */ { SIR_MAC_ANI_WORKAROUND_EID_MIN, SIR_MAC_ANI_WORKAROUND_EID_MAX }
};
extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS];
////////////////////////////////////////////////////////////////////////
/**
* \var gPhyRatesSuppt
*
* \brief Rate support lookup table
*
*
* This is a lookup table indexing rates & configuration parameters to
* support. Given a rate (in unites of 0.5Mpbs) & three booleans (MIMO
* Enabled, Channel Bonding Enabled, & Concatenation Enabled), one can
* determine whether the given rate is supported by computing two
* indices. The first maps the rate to table row as indicated below
* (i.e. eHddSuppRate_6Mbps maps to row zero, eHddSuppRate_9Mbps to row
* 1, and so on). Index two can be computed like so:
*
* \code
idx2 = ( fEsf ? 0x4 : 0x0 ) |
( fCb ? 0x2 : 0x0 ) |
( fMimo ? 0x1 : 0x0 );
* \endcode
*
*
* Given that:
*
\code
fSupported = gPhyRatesSuppt[idx1][idx2];
\endcode
*
*
* This table is based on the document "PHY Supported Rates.doc". This
* table is permissive in that a rate is reflected as being supported
* even when turning off an enabled feature would be required. For
* instance, "PHY Supported Rates" lists 42Mpbs as unsupported when CB,
* ESF, & MIMO are all on. However, if we turn off either of CB or
* MIMO, it then becomes supported. Therefore, we mark it as supported
* even in index 7 of this table.
*
*
*/
static const tANI_BOOLEAN gPhyRatesSuppt[24][8] = {
// SSF SSF SSF SSF ESF ESF ESF ESF
// SIMO MIMO SIMO MIMO SIMO MIMO SIMO MIMO
// No CB No CB CB CB No CB No CB CB CB
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 6Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 9Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 12Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 18Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE }, // 20Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 24Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 36Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 40Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 42Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 48Mbps
{ TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 54Mbps
{ FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 72Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 80Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 84Mbps
{ FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 96Mbps
{ FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 108Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 120Mbps
{ FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 126Mbps
{ FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 144Mbps
{ FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 160Mbps
{ FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 168Mbps
{ FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 192Mbps
{ FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 216Mbps
{ FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 240Mbps
};
#define CASE_RETURN_STR(n) case (n): return (#n)
const char *
get_eRoamCmdStatus_str(eRoamCmdStatus val)
{
switch (val)
{
CASE_RETURN_STR(eCSR_ROAM_CANCELLED);
CASE_RETURN_STR(eCSR_ROAM_FAILED);
CASE_RETURN_STR(eCSR_ROAM_ROAMING_START);
CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION);
CASE_RETURN_STR(eCSR_ROAM_CONNECT_COMPLETION);
CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START);
CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION);
CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED);
CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM);
CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS);
CASE_RETURN_STR(eCSR_ROAM_LOSTLINK);
CASE_RETURN_STR(eCSR_ROAM_LOSTLINK_DETECTED);
CASE_RETURN_STR(eCSR_ROAM_MIC_ERROR_IND);
CASE_RETURN_STR(eCSR_ROAM_IBSS_IND);
CASE_RETURN_STR(eCSR_ROAM_CONNECT_STATUS_UPDATE);
CASE_RETURN_STR(eCSR_ROAM_GEN_INFO);
CASE_RETURN_STR(eCSR_ROAM_SET_KEY_COMPLETE);
CASE_RETURN_STR(eCSR_ROAM_REMOVE_KEY_COMPLETE);
CASE_RETURN_STR(eCSR_ROAM_IBSS_LEAVE);
CASE_RETURN_STR(eCSR_ROAM_WDS_IND);
CASE_RETURN_STR(eCSR_ROAM_INFRA_IND);
CASE_RETURN_STR(eCSR_ROAM_WPS_PBC_PROBE_REQ_IND);
#ifdef WLAN_FEATURE_VOWIFI_11R
CASE_RETURN_STR(eCSR_ROAM_FT_RESPONSE);
#endif
CASE_RETURN_STR(eCSR_ROAM_FT_START);
CASE_RETURN_STR(eCSR_ROAM_REMAIN_CHAN_READY);
CASE_RETURN_STR(eCSR_ROAM_SESSION_OPENED);
CASE_RETURN_STR(eCSR_ROAM_FT_REASSOC_FAILED);
#ifdef FEATURE_WLAN_LFR
CASE_RETURN_STR(eCSR_ROAM_PMK_NOTIFY);
#endif
#ifdef FEATURE_WLAN_LFR_METRICS
CASE_RETURN_STR(eCSR_ROAM_PREAUTH_INIT_NOTIFY);
CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_SUCCESS);
CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_FAILURE);
CASE_RETURN_STR(eCSR_ROAM_HANDOVER_SUCCESS);
#endif
#ifdef FEATURE_WLAN_TDLS
CASE_RETURN_STR(eCSR_ROAM_TDLS_STATUS_UPDATE);
CASE_RETURN_STR(eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND);
#endif
CASE_RETURN_STR(eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS);
CASE_RETURN_STR(eCSR_ROAM_SEND_P2P_STOP_BSS);
#ifdef WLAN_FEATURE_11W
CASE_RETURN_STR(eCSR_ROAM_UNPROT_MGMT_FRAME_IND);
#endif
#ifdef WLAN_FEATURE_RMC
CASE_RETURN_STR(eCSR_ROAM_IBSS_PEER_INFO_COMPLETE);
#endif
#ifdef WLAN_FEATURE_AP_HT40_24G
CASE_RETURN_STR(eCSR_ROAM_2040_COEX_INFO_IND);
#endif
#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
CASE_RETURN_STR(eCSR_ROAM_TSM_IE_IND);
CASE_RETURN_STR(eCSR_ROAM_CCKM_PREAUTH_NOTIFY);
CASE_RETURN_STR(eCSR_ROAM_ESE_ADJ_AP_REPORT_IND);
CASE_RETURN_STR(eCSR_ROAM_ESE_BCN_REPORT_IND);
#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
default:
return "unknown";
}
}
const char *
get_eCsrRoamResult_str(eCsrRoamResult val)
{
switch (val)
{
CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE);
CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE);
CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED);
CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED);
CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE);
CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED);
CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND);
CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND);
CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED);
CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT);
CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE);
CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER);
CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED);
default:
return "unknown";
}
}
tANI_BOOLEAN csrGetBssIdBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tCsrBssid *pBssId )
{
vos_mem_copy(pBssId, &pSirBssDesc->bssId[ 0 ], sizeof(tCsrBssid));
return( TRUE );
}
tANI_BOOLEAN csrIsBssIdEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 )
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tANI_BOOLEAN fEqual = FALSE;
tCsrBssid bssId1;
tCsrBssid bssId2;
do {
if ( !pSirBssDesc1 ) break;
if ( !pSirBssDesc2 ) break;
if ( !csrGetBssIdBssDesc( pMac, pSirBssDesc1, &bssId1 ) ) break;
if ( !csrGetBssIdBssDesc( pMac, pSirBssDesc2, &bssId2 ) ) break;
//sirCompareMacAddr
fEqual = csrIsMacAddressEqual(pMac, &bssId1, &bssId2);
} while( 0 );
return( fEqual );
}
tANI_BOOLEAN csrIsConnStateConnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED == pMac->roam.roamSession[sessionId].connectState );
}
tANI_BOOLEAN csrIsConnStateDisconnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState );
}
tANI_BOOLEAN csrIsConnStateConnectedInfra( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == pMac->roam.roamSession[sessionId].connectState );
}
tANI_BOOLEAN csrIsConnStateConnected( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
if( csrIsConnStateConnectedIbss( pMac, sessionId ) || csrIsConnStateConnectedInfra( pMac, sessionId ) || csrIsConnStateConnectedWds( pMac, sessionId) )
return TRUE;
else
return FALSE;
}
tANI_BOOLEAN csrIsConnStateInfra( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( csrIsConnStateConnectedInfra( pMac, sessionId ) );
}
tANI_BOOLEAN csrIsConnStateIbss( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( csrIsConnStateConnectedIbss( pMac, sessionId ) || csrIsConnStateDisconnectedIbss( pMac, sessionId ) );
}
tANI_BOOLEAN csrIsConnStateConnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED == pMac->roam.roamSession[sessionId].connectState );
}
tANI_BOOLEAN csrIsConnStateConnectedInfraAp( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == pMac->roam.roamSession[sessionId].connectState) ||
(eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ) );
}
tANI_BOOLEAN csrIsConnStateDisconnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState );
}
tANI_BOOLEAN csrIsConnStateWds( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return( csrIsConnStateConnectedWds( pMac, sessionId ) ||
csrIsConnStateDisconnectedWds( pMac, sessionId ) );
}
tANI_BOOLEAN csrIsConnStateAp( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
tCsrRoamSession *pSession;
pSession = CSR_GET_SESSION(pMac, sessionId);
if (!pSession)
return eANI_BOOLEAN_FALSE;
if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) )
{
return eANI_BOOLEAN_TRUE;
}
return eANI_BOOLEAN_FALSE;
}
tANI_BOOLEAN csrIsAnySessionInConnectState( tpAniSirGlobal pMac )
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) &&
( csrIsConnStateInfra( pMac, i )
|| csrIsConnStateIbss( pMac, i )
|| csrIsConnStateAp( pMac, i) ) )
{
fRc = eANI_BOOLEAN_TRUE;
break;
}
}
return ( fRc );
}
/**
* csr_is_ndi_started() - function to check if NDI is started
* @mac_ctx: handle to mac context
* @session_id: session identifier
*
* returns: true if NDI is started, false otherwise
*/
bool csr_is_ndi_started(tpAniSirGlobal mac_ctx, uint32_t session_id)
{
tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id);
if (!session)
return false;
return (eCSR_CONNECT_STATE_TYPE_NDI_STARTED == session->connectState);
}
tANI_S8 csrGetInfraSessionId( tpAniSirGlobal pMac )
{
tANI_U8 i;
tANI_S8 sessionid = -1;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateInfra( pMac, i ) )
{
sessionid = i;
break;
}
}
return ( sessionid );
}
tANI_U8 csrGetInfraOperationChannel( tpAniSirGlobal pMac, tANI_U8 sessionId)
{
tANI_U8 channel;
if( CSR_IS_SESSION_VALID( pMac, sessionId ))
{
channel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
}
else
{
channel = 0;
}
return channel;
}
tANI_BOOLEAN csrIsSessionClientAndConnected(tpAniSirGlobal pMac, tANI_U8 sessionId)
{
tCsrRoamSession *pSession = NULL;
if (CSR_IS_SESSION_VALID( pMac, sessionId) && csrIsConnStateInfra( pMac, sessionId))
{
pSession = CSR_GET_SESSION( pMac, sessionId);
if (NULL != pSession->pCurRoamProfile)
{
if ((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) ||
(pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE))
return TRUE;
}
}
return FALSE;
}
//This routine will return operating channel on FIRST BSS that is active/operating to be used for concurrency mode.
//If other BSS is not up or not connected it will return 0
tANI_U8 csrGetConcurrentOperationChannel( tpAniSirGlobal pMac )
{
tCsrRoamSession *pSession = NULL;
tANI_U8 i = 0;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) )
{
pSession = CSR_GET_SESSION( pMac, i );
if (NULL != pSession->pCurRoamProfile)
{
if (
(((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) ||
(pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE)) &&
(pSession->connectState == eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED))
||
(((pSession->pCurRoamProfile->csrPersona == VOS_P2P_GO_MODE) ||
(pSession->pCurRoamProfile->csrPersona == VOS_STA_SAP_MODE)) &&
(pSession->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED))
)
return (pSession->connectedProfile.operationChannel);
}
}
}
return 0;
}
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
#define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2)
/* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */
#define CSR_GET_HT40_PLUS_CCH(och) ((och)+2)
#define CSR_GET_HT40_MINUS_CCH(och) ((och)-2)
#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6)
#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2)
#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2)
#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6)
void csrGetChFromHTProfile (tpAniSirGlobal pMac, tCsrRoamHTProfile *htp,
tANI_U16 och, tANI_U16 *cfreq, tANI_U16 *hbw)
{
tANI_U16 cch, ch_bond;
if (och > 14)
ch_bond = pMac->roam.configParam.channelBondingMode5GHz;
else
ch_bond = pMac->roam.configParam.channelBondingMode24GHz;
cch = och;
*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
if (!ch_bond) {
goto ret;
}
smsLog(pMac, LOG1,
FL("##HTC: %d scbw: %d rcbw: %d sco: %d"
#ifdef WLAN_FEATURE_11AC
"VHTC: %d apc: %d apbw: %d"
#endif
),
htp->htCapability, htp->htSupportedChannelWidthSet,
htp->htRecommendedTxWidthSet, htp->htSecondaryChannelOffset,
#ifdef WLAN_FEATURE_11AC
htp->vhtCapability, htp->apCenterChan, htp->apChanWidth
#endif
);
#ifdef WLAN_FEATURE_11AC
if (htp->vhtCapability) {
cch = htp->apCenterChan;
if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
*hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
*hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL);
if (!*hbw && htp->htCapability) {
if (htp->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_40MHZ)
*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
else
*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
}
} else
#endif
if (htp->htCapability) {
if (htp->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_40MHZ) {
*hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
if (htp->htSecondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
cch = CSR_GET_HT40_PLUS_CCH(och);
else if (htp->htSecondaryChannelOffset ==
PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
cch = CSR_GET_HT40_MINUS_CCH(och);
} else {
cch = och;
*hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
}
}
ret:
*cfreq = vos_chan_to_freq(cch);
return;
}
v_U16_t csrCheckConcurrentChannelOverlap(tpAniSirGlobal pMac, v_U16_t sap_ch,
eCsrPhyMode sap_phymode, v_U8_t cc_switch_mode)
{
tCsrRoamSession *pSession = NULL;
v_U8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED;
v_U16_t intf_ch=0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0, sap_cfreq = 0;
v_U16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch;
if (pMac->roam.configParam.cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_DISABLE)
return 0;
if (sap_ch !=0) {
sap_cch = sap_ch;
sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
if (sap_ch > 14)
chb = pMac->roam.configParam.channelBondingMode5GHz;
else
chb = pMac->roam.configParam.channelBondingMode24GHz;
if (chb) {
if (sap_phymode == eCSR_DOT11_MODE_11n ||
sap_phymode == eCSR_DOT11_MODE_11n_ONLY) {
sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
if (chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch);
else if (chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch);
}
#ifdef WLAN_FEATURE_11AC
else if (sap_phymode == eCSR_DOT11_MODE_11ac ||
sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) {
/*11AC only 80/40/20 Mhz supported in Rome */
if (pMac->roam.configParam.nVhtChannelWidth ==
(WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) {
sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
if (chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW-1))
sap_cch = CSR_GET_HT80_PLUS_LL_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW-1))
sap_cch = CSR_GET_HT80_PLUS_HL_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH-1))
sap_cch = CSR_GET_HT80_MINUS_LH_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH-1))
sap_cch = CSR_GET_HT80_MINUS_HH_CCH(sap_ch);
} else {
sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
if (chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW-1))
sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW-1))
sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH-1))
sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH-1))
sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch);
}
}
#endif
}
sap_cfreq = vos_chan_to_freq(sap_cch);
}
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) {
if( !CSR_IS_SESSION_VALID( pMac, i ) )
continue;
pSession = CSR_GET_SESSION( pMac, i );
if (NULL != pSession->pCurRoamProfile) {
if (((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) ||
(pSession->pCurRoamProfile->csrPersona ==
VOS_P2P_CLIENT_MODE)) &&
(pSession->connectState ==
eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) {
intf_ch = pSession->connectedProfile.operationChannel;
csrGetChFromHTProfile(pMac,
&pSession->connectedProfile.HTProfile, intf_ch,
&intf_cfreq, &intf_hbw);
} else if(((pSession->pCurRoamProfile->csrPersona ==
VOS_P2P_GO_MODE) ||
(pSession->pCurRoamProfile->csrPersona ==
VOS_STA_SAP_MODE)) &&
(pSession->connectState !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
if (pSession->ch_switch_in_progress)
continue;
/*
* if conc_custom_rule1 is defined then we don't want p2pgo to
* follow SAP's channel or SAP to follow P2PGO's channel.
*/
if (0 == pMac->roam.configParam.conc_custom_rule1 &&
0 == pMac->roam.configParam.conc_custom_rule2) {
if (sap_ch == 0) {
sap_ch = pSession->connectedProfile.operationChannel;
csrGetChFromHTProfile(pMac,
&pSession->connectedProfile.HTProfile, sap_ch,
&sap_cfreq, &sap_hbw);
} else if (sap_ch !=
pSession->connectedProfile.operationChannel) {
intf_ch = pSession->connectedProfile.operationChannel;
csrGetChFromHTProfile(pMac,
&pSession->connectedProfile.HTProfile, intf_ch,
&intf_cfreq, &intf_hbw);
}
} else {
if (sap_ch == 0 &&
(pSession->pCurRoamProfile->csrPersona ==
VOS_STA_SAP_MODE)) {
sap_ch = pSession->connectedProfile.operationChannel;
csrGetChFromHTProfile(pMac,
&pSession->connectedProfile.HTProfile, sap_ch,
&sap_cfreq, &sap_hbw);
}
}
}
}
}
if (intf_ch && sap_ch != intf_ch &&
cc_switch_mode != VOS_MCC_TO_SCC_SWITCH_FORCE) {
sap_lfreq = sap_cfreq - sap_hbw;
sap_hfreq = sap_cfreq + sap_hbw;
intf_lfreq = intf_cfreq -intf_hbw;
intf_hfreq = intf_cfreq +intf_hbw;
smsLog(pMac, LOGE,
FL("\nSAP: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d\n"
"INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d"),
sap_ch, vos_chan_to_freq(sap_ch), vos_freq_to_chan(sap_cfreq),
sap_cfreq, sap_hbw*2, sap_lfreq, sap_hfreq,
intf_ch, vos_chan_to_freq(intf_ch),
vos_freq_to_chan(intf_cfreq),
intf_cfreq, intf_hbw*2, intf_lfreq, intf_hfreq);
if (!(
((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) ||
(sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq))
|| ((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) ||
(intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq))
)) {
intf_ch = 0;
}
}
else if (!pMac->roam.configParam.band_switch_enable &&
intf_ch && sap_ch!= intf_ch &&
cc_switch_mode == VOS_MCC_TO_SCC_SWITCH_FORCE) {
if (!((intf_ch < 14 && sap_ch < 14) ||
(intf_ch > 14 && sap_ch > 14))) {
intf_ch = 0;
}
}else if (intf_ch == sap_ch)
intf_ch = 0;
smsLog(pMac, LOGE, FL("##Concurrent Channels %s Interfering"), intf_ch == 0 ?
"Not" : "Are" );
return intf_ch;
}
/**
* csr_create_sap_session_info() - create session info based on
* the input chan and phymode
* @pMac: tpAniSirGlobal ptr
* @sap_phymode: requesting phymode.
* @sap_ch: requesting channel number
* @session_info: information returned.
*
* Return: TRUE if any session info returned
*/
tANI_BOOLEAN csr_create_sap_session_info(
tHalHandle hHal,
eCsrPhyMode sap_phymode,
v_U16_t sap_ch,
session_info_t *session_info)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
v_U8_t chb = PHY_SINGLE_CHANNEL_CENTERED;
v_U16_t sap_hbw = 0, sap_cfreq = 0;
v_U16_t sap_lfreq, sap_hfreq, sap_cch;
sap_cch = sap_ch;
sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
if (sap_ch > MAX_2_4GHZ_CHANNEL)
chb = pMac->roam.configParam.channelBondingMode5GHz;
else
chb = pMac->roam.configParam.channelBondingMode24GHz;
if (!chb)
goto RET;
if (sap_phymode == eCSR_DOT11_MODE_11n ||
sap_phymode == eCSR_DOT11_MODE_11n_ONLY) {
sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
if (chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch);
else if (chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch);
}
#ifdef WLAN_FEATURE_11AC
else if (sap_phymode == eCSR_DOT11_MODE_11ac ||
sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) {
/*
* 11AC only 80/40/20 Mhz supported in Rome
*/
if (pMac->roam.configParam.nVhtChannelWidth ==
(WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) {
sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW
- 1))
sap_cch = CSR_GET_HT80_PLUS_LL_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
- 1))
sap_cch = CSR_GET_HT80_PLUS_HL_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
- 1))
sap_cch = CSR_GET_HT80_MINUS_LH_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
- 1))
sap_cch = CSR_GET_HT80_MINUS_HH_CCH(sap_ch);
} else {
sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW
- 1))
sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
- 1))
sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
- 1))
sap_cch = CSR_GET_HT40_PLUS_CCH(sap_ch);
else if (chb ==
(PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
- 1))
sap_cch = CSR_GET_HT40_MINUS_CCH(sap_ch);
}
}
#endif
RET:
sap_cfreq = vos_chan_to_freq(sap_cch);
sap_lfreq = sap_cfreq - sap_hbw;
sap_hfreq = sap_cfreq + sap_hbw;
if (sap_ch > MAX_2_4GHZ_CHANNEL)
session_info->band = eCSR_BAND_5G;
else
session_info->band = eCSR_BAND_24;
session_info->och = sap_ch;
session_info->lfreq = sap_lfreq;
session_info->hfreq = sap_hfreq;
session_info->cfreq = sap_cfreq;
session_info->hbw = sap_hbw;
session_info->con_mode = VOS_STA_SAP_MODE;
return TRUE;
}
/**
* csr_find_sta_session_info() - get sta active session info
* @pMac: tpAniSirGlobal ptr
* @session_info: information returned.
*
* Return: TRUE if sta session info returned
*/
tANI_BOOLEAN csr_find_sta_session_info(
tHalHandle hHal,
session_info_t *info)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tCsrRoamSession *pSession = NULL;
v_U8_t i = 0;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) {
if( !CSR_IS_SESSION_VALID( pMac, i ) )
continue;
pSession = CSR_GET_SESSION( pMac, i );
if (NULL == pSession->pCurRoamProfile)
continue;
if (((pSession->pCurRoamProfile->csrPersona ==
VOS_STA_MODE) ||
(pSession->pCurRoamProfile->csrPersona ==
VOS_P2P_CLIENT_MODE)) &&
(pSession->connectState ==
eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) {
info->och =
pSession->connectedProfile.operationChannel;
csrGetChFromHTProfile(pMac,
&pSession->connectedProfile.HTProfile,
info->och, &info->cfreq, &info->hbw);
info->lfreq = info->cfreq - info->hbw;
info->hfreq = info->cfreq + info->hbw;
if (info->och > MAX_2_4GHZ_CHANNEL)
info->band = eCSR_BAND_5G;
else
info->band = eCSR_BAND_24;
info->con_mode = VOS_STA_MODE;
return eANI_BOOLEAN_TRUE;
}
}
return eANI_BOOLEAN_FALSE;
}
/**
* csr_find_all_session_info() - get all active session info
* @pMac: tpAniSirGlobal ptr
* @session_info: information returned.
* @session_count: number of session
*
* Return: TRUE if any session info returned
*/
tANI_BOOLEAN csr_find_all_session_info(
tHalHandle hHal,
session_info_t *session_info,
v_U8_t *session_count)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tCsrRoamSession *pSession = NULL;
v_U8_t i = 0;
v_U8_t count = 0;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) {
if( !CSR_IS_SESSION_VALID( pMac, i ) )
continue;
pSession = CSR_GET_SESSION( pMac, i );
if (NULL == pSession->pCurRoamProfile)
continue;
if ((((pSession->pCurRoamProfile->csrPersona ==
VOS_STA_MODE) ||
(pSession->pCurRoamProfile->csrPersona ==
VOS_P2P_CLIENT_MODE)) &&
(pSession->connectState ==
eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) ||
(((pSession->pCurRoamProfile->csrPersona ==
VOS_P2P_GO_MODE) ||
(pSession->pCurRoamProfile->csrPersona ==
VOS_STA_SAP_MODE)||
(pSession->pCurRoamProfile->csrPersona ==
VOS_IBSS_MODE)) &&
(pSession->connectState !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED))) {
session_info_t *info = &session_info[count++];
info->och =
pSession->connectedProfile.operationChannel;
csrGetChFromHTProfile(pMac,
&pSession->connectedProfile.HTProfile,
info->och, &info->cfreq, &info->hbw);
info->lfreq = info->cfreq - info->hbw;
info->hfreq = info->cfreq + info->hbw;
if ((pSession->pCurRoamProfile->csrPersona ==
VOS_STA_MODE) ||
(pSession->pCurRoamProfile->csrPersona ==
VOS_P2P_CLIENT_MODE))
info->con_mode = VOS_STA_MODE;
else
info->con_mode = VOS_STA_SAP_MODE;
if (info->och > MAX_2_4GHZ_CHANNEL)
info->band = eCSR_BAND_5G;
else
info->band = eCSR_BAND_24;
}
}
*session_count = count;
return count != 0;
}
#endif
tANI_BOOLEAN csrIsAllSessionDisconnected( tpAniSirGlobal pMac )
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_TRUE;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) )
{
fRc = eANI_BOOLEAN_FALSE;
break;
}
}
return ( fRc );
}
tANI_BOOLEAN csrIsStaSessionConnected( tpAniSirGlobal pMac )
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
tCsrRoamSession *pSession = NULL;
tANI_U32 countSta = 0;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) )
{
pSession = CSR_GET_SESSION( pMac, i );
if (NULL != pSession->pCurRoamProfile)
{
if (pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) {
countSta++;
}
}
}
}
/* return TRUE if one of the following conditions is TRUE:
* - more than one STA session connected
*/
if ( countSta > 0) {
fRc = eANI_BOOLEAN_TRUE;
}
return( fRc );
}
tANI_BOOLEAN csrIsP2pOrSapSessionConnected(tpAniSirGlobal pMac)
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
tCsrRoamSession *pSession = NULL;
tANI_U32 countP2pCli = 0;
tANI_U32 countP2pGo = 0;
tANI_U32 countSAP = 0;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) )
{
pSession = CSR_GET_SESSION( pMac, i );
if (NULL != pSession->pCurRoamProfile)
{
if (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE) {
countP2pCli++;
}
if (pSession->pCurRoamProfile->csrPersona == VOS_P2P_GO_MODE) {
countP2pGo++;
}
if (pSession->pCurRoamProfile->csrPersona ==
VOS_STA_SAP_MODE) {
countSAP++;
}
}
}
}
/* return TRUE if one of the following conditions is TRUE:
* - at least one P2P CLI session is connected
* - at least one P2P GO session is connected
*/
if ((countP2pCli > 0) || (countP2pGo > 0 ) || (countSAP > 0)) {
fRc = eANI_BOOLEAN_TRUE;
}
return( fRc );
}
tANI_BOOLEAN csrIsAnySessionConnected( tpAniSirGlobal pMac )
{
tANI_U32 i, count;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
count = 0;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) )
{
count++;
}
}
if (count > 0)
{
fRc = eANI_BOOLEAN_TRUE;
}
return( fRc );
}
tANI_BOOLEAN csrIsInfraConnected( tpAniSirGlobal pMac )
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedInfra( pMac, i ) )
{
fRc = eANI_BOOLEAN_TRUE;
break;
}
}
return ( fRc );
}
tANI_BOOLEAN csrIsConcurrentInfraConnected( tpAniSirGlobal pMac )
{
tANI_U32 i, noOfConnectedInfra = 0;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedInfra( pMac, i ) )
{
++noOfConnectedInfra;
}
}
// More than one Infra Sta Connected
if(noOfConnectedInfra > 1)
{
fRc = eANI_BOOLEAN_TRUE;
}
return ( fRc );
}
tANI_BOOLEAN csrIsIBSSStarted( tpAniSirGlobal pMac )
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateIbss( pMac, i ) )
{
fRc = eANI_BOOLEAN_TRUE;
break;
}
}
return ( fRc );
}
tANI_BOOLEAN csrIsBTAMPStarted( tpAniSirGlobal pMac )
{
tANI_U32 i;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ )
{
if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedWds( pMac, i ) )
{
fRc = eANI_BOOLEAN_TRUE;
break;
}
}
return ( fRc );
}
tANI_BOOLEAN csrIsConcurrentSessionRunning( tpAniSirGlobal pMac )
{
tANI_U32 sessionId, noOfCocurrentSession = 0;
eCsrConnectState connectState;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
{
if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
{
connectState = pMac->roam.roamSession[sessionId].connectState;
if( (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == connectState) ||
(eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == connectState) ||
(eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == connectState) )
{
++noOfCocurrentSession;
}
}
}
// More than one session is Up and Running
if(noOfCocurrentSession > 1)
{
fRc = eANI_BOOLEAN_TRUE;
}
return ( fRc );
}
tANI_BOOLEAN csrIsInfraApStarted( tpAniSirGlobal pMac )
{
tANI_U32 sessionId;
tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE;
for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
{
if( CSR_IS_SESSION_VALID( pMac, sessionId ) && (csrIsConnStateConnectedInfraAp(pMac, sessionId)) )
{
fRc = eANI_BOOLEAN_TRUE;
break;
}
}
return ( fRc );
}
tANI_BOOLEAN csrIsBTAMP( tpAniSirGlobal pMac, tANI_U32 sessionId )
{
return ( csrIsConnStateConnectedWds( pMac, sessionId ) );
}
tANI_BOOLEAN csrIsConnStateDisconnected(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
return (eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED == pMac->roam.roamSession[sessionId].connectState);
}
tANI_BOOLEAN csrIsValidMcConcurrentSession(tpAniSirGlobal pMac, tANI_U32 sessionId,
tSirBssDescription *pBssDesc)
{
tCsrRoamSession *pSession = NULL;
eAniBoolean status = eANI_BOOLEAN_FALSE;
//Check for MCC support
if (!pMac->roam.configParam.fenableMCCMode)
{
return status;
}
//Validate BeaconInterval
if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
{
pSession = CSR_GET_SESSION( pMac, sessionId );
if (NULL != pSession->pCurRoamProfile)
{
if (csrIsconcurrentsessionValid (pMac, sessionId,
pSession->pCurRoamProfile->csrPersona)
== eHAL_STATUS_SUCCESS )
{
if (csrValidateMCCBeaconInterval( pMac, pBssDesc->channelId,
&pBssDesc->beaconInterval, sessionId,
pSession->pCurRoamProfile->csrPersona)
!= eHAL_STATUS_SUCCESS)
{
status = eANI_BOOLEAN_FALSE;
}
else
{
status = eANI_BOOLEAN_TRUE;
}
}
else
{
status = eANI_BOOLEAN_FALSE;
}
}
}
return status;
}
static tSirMacCapabilityInfo csrGetBssCapabilities( tSirBssDescription *pSirBssDesc )
{
tSirMacCapabilityInfo dot11Caps;
//tSirMacCapabilityInfo is 16-bit
pal_get_U16( (tANI_U8 *)&pSirBssDesc->capabilityInfo, (tANI_U16 *)&dot11Caps );
return( dot11Caps );
}
tANI_BOOLEAN csrIsInfraBssDesc( tSirBssDescription *pSirBssDesc )
{
tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc );
return( (tANI_BOOLEAN)dot11Caps.ess );
}
tANI_BOOLEAN csrIsIbssBssDesc( tSirBssDescription *pSirBssDesc )
{
tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc );
return( (tANI_BOOLEAN)dot11Caps.ibss );
}
tANI_BOOLEAN csrIsQoSBssDesc( tSirBssDescription *pSirBssDesc )
{
tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc );
return( (tANI_BOOLEAN)dot11Caps.qos );
}
tANI_BOOLEAN csrIsPrivacy( tSirBssDescription *pSirBssDesc )
{
tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc );
return( (tANI_BOOLEAN)dot11Caps.privacy );
}
tANI_BOOLEAN csrIs11dSupported(tpAniSirGlobal pMac)
{
return(pMac->roam.configParam.Is11dSupportEnabled);
}
tANI_BOOLEAN csrIs11hSupported(tpAniSirGlobal pMac)
{
return(pMac->roam.configParam.Is11hSupportEnabled);
}
tANI_BOOLEAN csrIs11eSupported(tpAniSirGlobal pMac)
{
return(pMac->roam.configParam.Is11eSupportEnabled);
}
tANI_BOOLEAN csrIsMCCSupported ( tpAniSirGlobal pMac )
{
return(pMac->roam.configParam.fenableMCCMode);
}
tANI_BOOLEAN csrIsWmmSupported(tpAniSirGlobal pMac)
{
if(eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode)
{
return eANI_BOOLEAN_FALSE;
}
else
{
return eANI_BOOLEAN_TRUE;
}
}
//pIes is the IEs for pSirBssDesc2
tANI_BOOLEAN csrIsSsidEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 )
{
tANI_BOOLEAN fEqual = FALSE;
tSirMacSSid Ssid1, Ssid2;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tDot11fBeaconIEs *pIes1 = NULL;
tDot11fBeaconIEs *pIesLocal = pIes2;
do {
if( ( NULL == pSirBssDesc1 ) || ( NULL == pSirBssDesc2 ) ) break;
if( !pIesLocal && !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesLocal)) )
{
smsLog(pMac, LOGE, FL(" fail to parse IEs"));
break;
}
if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1)))
{
break;
}
if( ( !pIes1->SSID.present ) || ( !pIesLocal->SSID.present ) ) break;
if ( pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid ) break;
vos_mem_copy(Ssid1.ssId, pIes1->SSID.ssid, pIes1->SSID.num_ssid);
vos_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid, pIesLocal->SSID.num_ssid);
fEqual = vos_mem_compare(Ssid1.ssId, Ssid2.ssId, pIesLocal->SSID.num_ssid);
} while( 0 );
if(pIes1)
{
vos_mem_free(pIes1);
}
if( pIesLocal && !pIes2 )
{
vos_mem_free(pIesLocal);
}
return( fEqual );
}
//pIes can be passed in as NULL if the caller doesn't have one prepared
tANI_BOOLEAN csrIsBssDescriptionWme( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes )
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
// Assume that WME is found...
tANI_BOOLEAN fWme = TRUE;
tDot11fBeaconIEs *pIesTemp = pIes;
do
{
if(pIesTemp == NULL)
{
if( !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesTemp)) )
{
fWme = FALSE;
break;
}
}
// if the Wme Info IE is found, then WME is supported...
if ( CSR_IS_QOS_BSS(pIesTemp) ) break;
// if none of these are found, then WME is NOT supported...
fWme = FALSE;
} while( 0 );
if( !csrIsWmmSupported( pMac ) && fWme)
{
if( !pIesTemp->HTCaps.present )
{
fWme = FALSE;
}
}
if( ( pIes == NULL ) && ( NULL != pIesTemp ) )
{
//we allocate memory here so free it before returning
vos_mem_free(pIesTemp);
}
return( fWme );
}
eCsrMediaAccessType csrGetQoSFromBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc,
tDot11fBeaconIEs *pIes )
{
eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF;
if (NULL == pIes)
{
VOS_ASSERT( pIes != NULL );
return( qosType );
}
do
{
// if we find WMM in the Bss Description, then we let this
// override and use WMM.
if ( csrIsBssDescriptionWme( hHal, pSirBssDesc, pIes ) )
{
qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
}
else
{
// if the QoS bit is on, then the AP is advertising 11E QoS...
if (csrIsQoSBssDesc(pSirBssDesc)) {
qosType = eCSR_MEDIUM_ACCESS_11e_eDCF;
} else {
qosType = eCSR_MEDIUM_ACCESS_DCF;
}
// scale back based on the types turned on for the adapter...
if ( eCSR_MEDIUM_ACCESS_11e_eDCF == qosType && !csrIs11eSupported( hHal ) )
{
qosType = eCSR_MEDIUM_ACCESS_DCF;
}
}
} while(0);
return( qosType );
}
//Caller allocates memory for pIEStruct
eHalStatus csrParseBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIEStruct)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
int ieLen = (int)GET_IE_LEN_IN_BSS(pBssDesc->length);
if(ieLen > 0 && pIEStruct)
{
if(!DOT11F_FAILED(dot11fUnpackBeaconIEs( pMac, (tANI_U8 *)pBssDesc->ieFields, ieLen, pIEStruct )))
{
status = eHAL_STATUS_SUCCESS;
}
}
return (status);
}
//This function will allocate memory for the parsed IEs to the caller. Caller must free the memory
//after it is done with the data only if this function succeeds
eHalStatus csrGetParsedBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs **ppIEStruct)
{
eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
if(pBssDesc && ppIEStruct)
{
*ppIEStruct = vos_mem_malloc(sizeof(tDot11fBeaconIEs));
if ( (*ppIEStruct) != NULL)
{
vos_mem_set((void *)*ppIEStruct, sizeof(tDot11fBeaconIEs), 0);
status = csrParseBssDescriptionIEs(hHal, pBssDesc, *ppIEStruct);
if(!HAL_STATUS_SUCCESS(status))
{
vos_mem_free(*ppIEStruct);
*ppIEStruct = NULL;
}
}
else
{
smsLog( pMac, LOGE, FL(" failed to allocate memory") );
VOS_ASSERT( 0 );
return eHAL_STATUS_FAILURE;
}
}
return (status);
}
tANI_BOOLEAN csrIsNULLSSID( tANI_U8 *pBssSsid, tANI_U8 len )
{
tANI_BOOLEAN fNullSsid = FALSE;
tANI_U32 SsidLength;
tANI_U8 *pSsidStr;
do
{
if ( 0 == len )
{
fNullSsid = TRUE;
break;
}
//Consider 0 or space for hidden SSID
if ( 0 == pBssSsid[0] )
{
fNullSsid = TRUE;
break;
}
SsidLength = len;
pSsidStr = pBssSsid;
while ( SsidLength )
{
if( *pSsidStr )
break;
pSsidStr++;
SsidLength--;
}
if( 0 == SsidLength )
{
fNullSsid = TRUE;
break;
}
}
while( 0 );
return fNullSsid;
}
tANI_U32 csrGetFragThresh( tHalHandle hHal )
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
return pMac->roam.configParam.FragmentationThreshold;
}
tANI_U32 csrGetRTSThresh( tHalHandle hHal )
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
return pMac->roam.configParam.RTSThreshold;
}
eCsrPhyMode csrTranslateToPhyModeFromBssDesc( tSirBssDescription *pSirBssDesc )
{
eCsrPhyMode phyMode;
switch ( pSirBssDesc->nwType )
{
case eSIR_11A_NW_TYPE:
phyMode = eCSR_DOT11_MODE_11a;
break;
case eSIR_11B_NW_TYPE:
phyMode = eCSR_DOT11_MODE_11b;
break;
case eSIR_11G_NW_TYPE:
phyMode = eCSR_DOT11_MODE_11g;
break;
case eSIR_11N_NW_TYPE:
phyMode = eCSR_DOT11_MODE_11n;
break;
#ifdef WLAN_FEATURE_11AC
case eSIR_11AC_NW_TYPE:
default:
phyMode = eCSR_DOT11_MODE_11ac;
#else
default:
phyMode = eCSR_DOT11_MODE_11n;
#endif
break;
}
return( phyMode );
}
tANI_U32 csrTranslateToWNICfgDot11Mode(tpAniSirGlobal pMac, eCsrCfgDot11Mode csrDot11Mode)
{
tANI_U32 ret;
switch(csrDot11Mode)
{
case eCSR_CFG_DOT11_MODE_AUTO:
smsLog(pMac, LOGW, FL(" Warning: sees eCSR_CFG_DOT11_MODE_AUTO "));
#ifdef WLAN_FEATURE_11AC
if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
ret = WNI_CFG_DOT11_MODE_11AC;
else
ret = WNI_CFG_DOT11_MODE_11N;
#else
//We cannot decide until now.
ret = WNI_CFG_DOT11_MODE_11N;
#endif
break;
case eCSR_CFG_DOT11_MODE_11A:
ret = WNI_CFG_DOT11_MODE_11A;
break;
case eCSR_CFG_DOT11_MODE_11B:
ret = WNI_CFG_DOT11_MODE_11B;
break;
case eCSR_CFG_DOT11_MODE_11G:
ret = WNI_CFG_DOT11_MODE_11G;
break;
case eCSR_CFG_DOT11_MODE_11N:
ret = WNI_CFG_DOT11_MODE_11N;
break;
case eCSR_CFG_DOT11_MODE_11G_ONLY:
ret = WNI_CFG_DOT11_MODE_11G_ONLY;
break;
case eCSR_CFG_DOT11_MODE_11N_ONLY:
ret = WNI_CFG_DOT11_MODE_11N_ONLY;
break;
#ifdef WLAN_FEATURE_11AC
case eCSR_CFG_DOT11_MODE_11AC_ONLY:
if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
ret = WNI_CFG_DOT11_MODE_11AC_ONLY;
else
ret = WNI_CFG_DOT11_MODE_11N;
break;
case eCSR_CFG_DOT11_MODE_11AC:
if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
ret = WNI_CFG_DOT11_MODE_11AC;
else
ret = WNI_CFG_DOT11_MODE_11N;
break;
#endif
default:
smsLog(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"), csrDot11Mode);
if(eCSR_BAND_24 == pMac->roam.configParam.eBand)
{
ret = WNI_CFG_DOT11_MODE_11G;
}
else
{
ret = WNI_CFG_DOT11_MODE_11A;
}
break;
}
return (ret);
}
//This function should only return the super set of supported modes. 11n implies 11b/g/a/n.
eHalStatus csrGetPhyModeFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription,
eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
eCsrPhyMode phyMode = csrTranslateToPhyModeFromBssDesc(pBSSDescription);
if (pIes) {
if (pIes->HTCaps.present) {
phyMode = eCSR_DOT11_MODE_11n;
#ifdef WLAN_FEATURE_11AC
if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) ||
IS_BSS_VHT_CAPABLE(pIes->vendor2_ie.VHTCaps))
phyMode = eCSR_DOT11_MODE_11ac;
#endif
}
*pPhyMode = phyMode;
}
return (status);
}
//This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes matches
//bssPhyMode is the mode derived from the BSS description
//f5GhzBand is derived from the channel id of BSS description
tANI_BOOLEAN csrGetPhyModeInUse( eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode, tANI_BOOLEAN f5GhzBand,
eCsrCfgDot11Mode *pCfgDot11ModeToUse )
{
tANI_BOOLEAN fMatch = FALSE;
eCsrCfgDot11Mode cfgDot11Mode;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; // to suppress compiler warning
switch( phyModeIn )
{
case eCSR_DOT11_MODE_abg: //11a or 11b or 11g
if( f5GhzBand )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
}
else if( eCSR_DOT11_MODE_11b == bssPhyMode )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
}
else
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
}
break;
case eCSR_DOT11_MODE_11a: //11a
if( f5GhzBand )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
}
break;
case eCSR_DOT11_MODE_11g:
if(!f5GhzBand)
{
if( eCSR_DOT11_MODE_11b == bssPhyMode )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
}
else
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
}
}
break;
case eCSR_DOT11_MODE_11g_ONLY:
if( eCSR_DOT11_MODE_11g == bssPhyMode )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
}
break;
case eCSR_DOT11_MODE_11b:
if( !f5GhzBand )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
}
break;
case eCSR_DOT11_MODE_11b_ONLY:
if( eCSR_DOT11_MODE_11b == bssPhyMode )
{
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
}
break;
case eCSR_DOT11_MODE_11n:
fMatch = TRUE;
switch(bssPhyMode)
{
case eCSR_DOT11_MODE_11g:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
break;
case eCSR_DOT11_MODE_11b:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
break;
case eCSR_DOT11_MODE_11a:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
break;
case eCSR_DOT11_MODE_11n:
#ifdef WLAN_FEATURE_11AC
case eCSR_DOT11_MODE_11ac:
#endif
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
break;
default:
#ifdef WLAN_FEATURE_11AC
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
#else
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
#endif
break;
}
break;
case eCSR_DOT11_MODE_11n_ONLY:
if ((eCSR_DOT11_MODE_11n == bssPhyMode)) {
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
}
break;
#ifdef WLAN_FEATURE_11AC
case eCSR_DOT11_MODE_11ac:
fMatch = TRUE;
switch(bssPhyMode)
{
case eCSR_DOT11_MODE_11g:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
break;
case eCSR_DOT11_MODE_11b:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
break;
case eCSR_DOT11_MODE_11a:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
break;
case eCSR_DOT11_MODE_11n:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
break;
case eCSR_DOT11_MODE_11ac:
default:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
break;
}
break;
case eCSR_DOT11_MODE_11ac_ONLY:
if ((eCSR_DOT11_MODE_11ac == bssPhyMode)) {
fMatch = TRUE;
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
}
break;
#endif
default:
fMatch = TRUE;
switch(bssPhyMode)
{
case eCSR_DOT11_MODE_11g:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
break;
case eCSR_DOT11_MODE_11b:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
break;
case eCSR_DOT11_MODE_11a:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
break;
case eCSR_DOT11_MODE_11n:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
break;
#ifdef WLAN_FEATURE_11AC
case eCSR_DOT11_MODE_11ac:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
break;
#endif
default:
cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
break;
}
break;
}
if ( fMatch && pCfgDot11ModeToUse )
{
#ifdef WLAN_FEATURE_11AC
if(cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)))
{
*pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
}
else
#endif
{
*pCfgDot11ModeToUse = cfgDot11Mode;
}
}
return( fMatch );
}
//This function decides whether the one of the bit of phyMode is matching the mode in the BSS and allowed by the user
//setting, pMac->roam.configParam.uCfgDot11Mode. It returns the mode that fits the criteria.
tANI_BOOLEAN csrIsPhyModeMatch( tpAniSirGlobal pMac, tANI_U32 phyMode,
tSirBssDescription *pSirBssDesc, tCsrRoamProfile *pProfile,
eCsrCfgDot11Mode *pReturnCfgDot11Mode,
tDot11fBeaconIEs *pIes)
{
tANI_BOOLEAN fMatch = FALSE;
eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2;
eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO;
tANI_U32 bitMask, loopCount;
if (HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pSirBssDesc,
&phyModeInBssDesc, pIes))) {
if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
if (eCSR_CFG_DOT11_MODE_ABG == pMac->roam.configParam.uCfgDot11Mode) {
phyMode = eCSR_DOT11_MODE_abg;
} else if (eCSR_CFG_DOT11_MODE_AUTO ==
pMac->roam.configParam.uCfgDot11Mode) {
#ifdef WLAN_FEATURE_11AC
phyMode = eCSR_DOT11_MODE_11ac;
#else
phyMode = eCSR_DOT11_MODE_11n;
#endif
} else {
//user's pick
phyMode = pMac->roam.configParam.phyMode;
}
}
if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
if (0 != phyMode) {
if (eCSR_DOT11_MODE_AUTO & phyMode) {
phyMode2 = eCSR_DOT11_MODE_AUTO & phyMode;
}
} else {
phyMode2 = phyMode;
}
fMatch = csrGetPhyModeInUse( phyMode2, phyModeInBssDesc, CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId),
&cfgDot11ModeToUse );
}
else
{
bitMask = 1;
loopCount = 0;
while(loopCount < eCSR_NUM_PHY_MODE)
{
if(0 != ( phyMode2 = (phyMode & (bitMask << loopCount++)) ))
{
fMatch = csrGetPhyModeInUse( phyMode2, phyModeInBssDesc, CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId),
&cfgDot11ModeToUse );
if(fMatch) break;
}
}
}
if ( fMatch && pReturnCfgDot11Mode )
{
if( pProfile )
{
/* IEEE 11n spec (8.4.3): HT STA shall eliminate TKIP as a
* choice for the pairwise cipher suite if CCMP is advertised
* by the AP or if the AP included an HT capabilities element
* in its Beacons and Probe Response.
*/
if ((!CSR_IS_11n_ALLOWED(pProfile->negotiatedUCEncryptionType)) &&
((eCSR_CFG_DOT11_MODE_11N == cfgDot11ModeToUse) ||
#ifdef WLAN_FEATURE_11AC
(eCSR_CFG_DOT11_MODE_11AC == cfgDot11ModeToUse)
#endif
)) {
/* We cannot do 11n here */
if (!CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId)) {
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
} else {
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
}
}
}
*pReturnCfgDot11Mode = cfgDot11ModeToUse;
}
}
return( fMatch );
}
eCsrCfgDot11Mode csrFindBestPhyMode( tpAniSirGlobal pMac, tANI_U32 phyMode )
{
eCsrCfgDot11Mode cfgDot11ModeToUse;
eCsrBand eBand = pMac->roam.configParam.eBand;
if ((0 == phyMode) ||
#ifdef WLAN_FEATURE_11AC
(eCSR_DOT11_MODE_11ac & phyMode) ||
#endif
(eCSR_DOT11_MODE_AUTO & phyMode))
{
#ifdef WLAN_FEATURE_11AC
if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
}
else
#endif
{
/* Default to 11N mode if user has configured 11ac mode
* and FW doesn't supports 11ac mode .
*/
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
}
}
else
{
if( ( eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY ) & phyMode )
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
}
else if ( eCSR_DOT11_MODE_abg & phyMode )
{
if( eCSR_BAND_24 != eBand )
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
}
else
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
}
}
else if(eCSR_DOT11_MODE_11a & phyMode)
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
}
else if( ( eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY ) & phyMode )
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
}
else
{
cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B;
}
}
return ( cfgDot11ModeToUse );
}
tANI_U32 csrGet11hPowerConstraint( tHalHandle hHal, tDot11fIEPowerConstraints *pPowerConstraint )
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tANI_U32 localPowerConstraint = 0;
// check if .11h support is enabled, if not, the power constraint is 0.
if(pMac->roam.configParam.Is11hSupportEnabled && pPowerConstraint->present)
{
localPowerConstraint = pPowerConstraint->localPowerConstraints;
}
return( localPowerConstraint );
}
tANI_BOOLEAN csrIsProfileWpa( tCsrRoamProfile *pProfile )
{
tANI_BOOLEAN fWpaProfile = FALSE;
switch ( pProfile->negotiatedAuthType )
{
case eCSR_AUTH_TYPE_WPA:
case eCSR_AUTH_TYPE_WPA_PSK:
case eCSR_AUTH_TYPE_WPA_NONE:
#ifdef FEATURE_WLAN_ESE
case eCSR_AUTH_TYPE_CCKM_WPA:
#endif
fWpaProfile = TRUE;
break;
default:
fWpaProfile = FALSE;
break;
}
if ( fWpaProfile )
{
switch ( pProfile->negotiatedUCEncryptionType )
{
case eCSR_ENCRYPT_TYPE_WEP40:
case eCSR_ENCRYPT_TYPE_WEP104:
case eCSR_ENCRYPT_TYPE_TKIP:
case eCSR_ENCRYPT_TYPE_AES:
fWpaProfile = TRUE;
break;
default:
fWpaProfile = FALSE;
break;
}
}
return( fWpaProfile );
}
tANI_BOOLEAN csrIsProfileRSN( tCsrRoamProfile *pProfile )
{
tANI_BOOLEAN fRSNProfile = FALSE;
switch ( pProfile->negotiatedAuthType )
{
case eCSR_AUTH_TYPE_RSN:
case eCSR_AUTH_TYPE_RSN_PSK:
#ifdef WLAN_FEATURE_VOWIFI_11R
case eCSR_AUTH_TYPE_FT_RSN:
case eCSR_AUTH_TYPE_FT_RSN_PSK:
#endif
#ifdef FEATURE_WLAN_ESE
case eCSR_AUTH_TYPE_CCKM_RSN:
#endif
#ifdef WLAN_FEATURE_11W
case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
#endif
fRSNProfile = TRUE;
break;
#ifdef WLAN_FEATURE_FILS_SK
/* fallthrough */
case eCSR_AUTH_TYPE_FILS_SHA256:
case eCSR_AUTH_TYPE_FILS_SHA384:
case eCSR_AUTH_TYPE_FT_FILS_SHA256:
case eCSR_AUTH_TYPE_FT_FILS_SHA384:
fRSNProfile = true;
break;
#endif
default:
fRSNProfile = FALSE;
break;
}
if ( fRSNProfile )
{
switch ( pProfile->negotiatedUCEncryptionType )
{
// !!REVIEW - For WPA2, use of RSN IE mandates
// use of AES as encryption. Here, we qualify
// even if encryption type is WEP or TKIP
case eCSR_ENCRYPT_TYPE_WEP40:
case eCSR_ENCRYPT_TYPE_WEP104:
case eCSR_ENCRYPT_TYPE_TKIP:
case eCSR_ENCRYPT_TYPE_AES:
fRSNProfile = TRUE;
break;
default:
fRSNProfile = FALSE;
break;
}
}
return( fRSNProfile );
}
eHalStatus
csrIsconcurrentsessionValid(tpAniSirGlobal pMac,tANI_U32 cursessionId,
tVOS_CON_MODE currBssPersona)
{
tANI_U32 sessionId = 0;
tANI_U8 automotive_support_enable =
(pMac->roam.configParam.conc_custom_rule1 |
pMac->roam.configParam.conc_custom_rule2);
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
bool ap_p2pgo_concurrency_enable =
pMac->roam.configParam.ap_p2pgo_concurrency_enable;
#endif
tVOS_CON_MODE bss_persona;
eCsrConnectState connect_state;
for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
if (cursessionId != sessionId ) {
if (!CSR_IS_SESSION_VALID( pMac, sessionId )) {
continue;
}
bss_persona =
pMac->roam.roamSession[sessionId].bssParams.bssPersona;
connect_state =
pMac->roam.roamSession[sessionId].connectState;
switch (currBssPersona) {
case VOS_STA_MODE:
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("** STA session **"));
return eHAL_STATUS_SUCCESS;
case VOS_STA_SAP_MODE:
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
if ((VOS_MCC_TO_SCC_SWITCH_FORCE ==
pMac->roam.configParam.cc_switch_mode) &&
(ap_p2pgo_concurrency_enable) &&
(bss_persona == VOS_P2P_GO_MODE) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("Start AP session concurrency with P2P-GO"));
return eHAL_STATUS_SUCCESS;
} else
#endif
if (((bss_persona == VOS_P2P_GO_MODE) &&
(0 == automotive_support_enable) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) ||
((bss_persona == VOS_IBSS_MODE) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED))) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Can't start multiple beaconing role"));
return eHAL_STATUS_FAILURE;
}
break;
case VOS_P2P_GO_MODE:
if ((bss_persona == VOS_P2P_GO_MODE) && (connect_state !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL(" ****P2P GO mode already exists ****"));
return eHAL_STATUS_FAILURE;
}
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
else if ((VOS_MCC_TO_SCC_SWITCH_FORCE ==
pMac->roam.configParam.cc_switch_mode) &&
(ap_p2pgo_concurrency_enable) &&
(bss_persona == VOS_STA_SAP_MODE) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("Start P2P-GO session concurrency with AP"));
return eHAL_STATUS_SUCCESS;
}
#endif
else if (((bss_persona == VOS_STA_SAP_MODE) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) &&
(0 == automotive_support_enable)) ||
((bss_persona == VOS_IBSS_MODE) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED))) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Can't start multiple beaconing role"));
return eHAL_STATUS_FAILURE;
}
break;
case VOS_IBSS_MODE:
if ((bss_persona == VOS_IBSS_MODE) &&
(connect_state !=
eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL(" ****IBSS mode already exists ****"));
return eHAL_STATUS_FAILURE;
} else if (((bss_persona == VOS_P2P_GO_MODE) ||
(bss_persona == VOS_STA_SAP_MODE)) &&
(connect_state
!= eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("**Cannot start Multiple Beaconing Role**"));
return eHAL_STATUS_FAILURE;
}
break;
case VOS_P2P_CLIENT_MODE:
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("**P2P-Client session**"));
return eHAL_STATUS_SUCCESS;
case VOS_NDI_MODE:
if (bss_persona != VOS_STA_MODE) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("***NDI mode can co-exist only with STA ***"));
return eHAL_STATUS_FAILURE;
}
break;
default :
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("**Persona not handled = %d**"),
currBssPersona);
break;
}
}
}
return eHAL_STATUS_SUCCESS;
}
eHalStatus csrUpdateMCCp2pBeaconInterval(tpAniSirGlobal pMac)
{
tANI_U32 sessionId = 0;
//If MCC is not supported just break and return SUCCESS
if ( !pMac->roam.configParam.fenableMCCMode){
return eHAL_STATUS_FAILURE;
}
for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
{
/* If GO in MCC support different beacon interval,
* change the BI of the P2P-GO */
if (pMac->roam.roamSession[sessionId].bssParams.bssPersona
== VOS_P2P_GO_MODE)
{
/* Handle different BI scenario based on the configuration set.
* If Config is set to 0x02 then Disconnect all the P2P clients
* associated. If config is set to 0x04 then update the BI
* without disconnecting all the clients
*/
if ((pMac->roam.configParam.fAllowMCCGODiffBI == 0x04) &&
(pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval))
{
return csrSendChngMCCBeaconInterval( pMac, sessionId);
}
//If the configuration of fAllowMCCGODiffBI is set to other than 0x04
else if ( pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval)
{
return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, eCSR_ROAM_RESULT_NONE);
}
}
}
return eHAL_STATUS_FAILURE;
}
tANI_U16 csrCalculateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U16 sta_bi, tANI_U16 go_gbi)
{
tANI_U8 num_beacons = 0;
tANI_U8 is_multiple = 0;
tANI_U16 go_cbi = 0;
tANI_U16 go_fbi = 0;
tANI_U16 sta_cbi = 0;
//If GO's given beacon Interval is less than 100
if(go_gbi < 100)
go_cbi = 100;
//if GO's given beacon Interval is greater than or equal to 100
else
go_cbi = 100 + (go_gbi % 100);
if ( sta_bi == 0 )
{
/* There is possibility to receive zero as value.
Which will cause divide by zero. Hence initialize with 100
*/
sta_bi = 100;
smsLog(pMac, LOGW,
FL("sta_bi 2nd parameter is zero, initialize to %d"), sta_bi);
}
// check, if either one is multiple of another
if (sta_bi > go_cbi)
{
is_multiple = !(sta_bi % go_cbi);
}
else
{
is_multiple = !(go_cbi % sta_bi);
}
// if it is multiple, then accept GO's beacon interval range [100,199] as it is
if (is_multiple)
{
return go_cbi;
}
//else , if it is not multiple, then then check for number of beacons to be
//inserted based on sta BI
num_beacons = sta_bi / 100;
if (num_beacons)
{
// GO's final beacon interval will be aligned to sta beacon interval, but
//in the range of [100, 199].
sta_cbi = sta_bi / num_beacons;
go_fbi = sta_cbi;
}
else
{
// if STA beacon interval is less than 100, use GO's change bacon interval
//instead of updating to STA's beacon interval.
go_fbi = go_cbi;
}
return go_fbi;
}
eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId,
tANI_U16 *beaconInterval, tANI_U32 cursessionId,
tVOS_CON_MODE currBssPersona)
{
tANI_U32 sessionId = 0;
tANI_U16 new_beaconInterval = 0;
//If MCC is not supported just break
if (!pMac->roam.configParam.fenableMCCMode){
return eHAL_STATUS_FAILURE;
}
for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ )
{
if (cursessionId != sessionId )
{
if (!CSR_IS_SESSION_VALID( pMac, sessionId ))
{
continue;
}
switch (currBssPersona)
{
case VOS_STA_MODE:
if (pMac->roam.roamSession[sessionId].pCurRoamProfile &&
(pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona
== VOS_P2P_CLIENT_MODE)) //check for P2P client mode
{
smsLog(pMac, LOG1, FL(" Beacon Interval Validation not required for STA/CLIENT"));
}
//IF SAP has started and STA wants to connect on different channel MCC should
//MCC should not be enabled so making it false to enforce on same channel
else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona
== VOS_STA_SAP_MODE)
{
if (pMac->roam.roamSession[sessionId].bssParams.operationChn
!= channelId )
{
smsLog(pMac, LOGE, FL("*** MCC with SAP+STA sessions ****"));
return eHAL_STATUS_SUCCESS;
}
}
else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona
== VOS_P2P_GO_MODE) //Check for P2P go scenario
{
/* if GO in MCC support different beacon interval,
* change the BI of the P2P-GO */
if ((pMac->roam.roamSession[sessionId].bssParams.operationChn
!= channelId ) &&
(pMac->roam.roamSession[sessionId].bssParams.beaconInterval
!= *beaconInterval))
{
/* if GO in MCC support different beacon interval, return success */
if ( pMac->roam.configParam.fAllowMCCGODiffBI == 0x01)
{
return eHAL_STATUS_SUCCESS;
}
// Send only Broadcast disassoc and update beaconInterval
//If configuration is set to 0x04 then dont
// disconnect all the station
else if ((pMac->roam.configParam.fAllowMCCGODiffBI == 0x02) ||
(pMac->roam.configParam.fAllowMCCGODiffBI == 0x04))
{
//Check to pass the right beacon Interval
if (pMac->roam.configParam.conc_custom_rule1 ||
pMac->roam.configParam.conc_custom_rule2) {
new_beaconInterval = CSR_CUSTOM_CONC_GO_BI;
} else {
new_beaconInterval =
csrCalculateMCCBeaconInterval(pMac,
*beaconInterval,
pMac->roam.roamSession[sessionId].bssParams.beaconInterval);
}
smsLog(pMac, LOG1, FL(" Peer AP BI : %d, new Beacon Interval: %d"),*beaconInterval,new_beaconInterval );
//Update the becon Interval
if (new_beaconInterval != pMac->roam.roamSession[sessionId].bssParams.beaconInterval)
{
//Update the beaconInterval now
smsLog(pMac, LOGE, FL(" Beacon Interval got changed config used: %d\n"),
pMac->roam.configParam.fAllowMCCGODiffBI);
pMac->roam.roamSession[sessionId].bssParams.beaconInterval = new_beaconInterval;
pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_TRUE;
return csrUpdateMCCp2pBeaconInterval(pMac);
}
return eHAL_STATUS_SUCCESS;
}
//Disconnect the P2P session
else if (pMac->roam.configParam.fAllowMCCGODiffBI == 0x03)
{
pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_FALSE;
return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SEND_P2P_STOP_BSS, eCSR_ROAM_RESULT_NONE);
}
else
{
smsLog(pMac, LOGE, FL("BeaconInterval is different cannot connect to preferred AP..."));
return eHAL_STATUS_FAILURE;
}
}
}
break;
case VOS_P2P_CLIENT_MODE:
if (pMac->roam.roamSession[sessionId].pCurRoamProfile &&
(pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona
== VOS_STA_MODE)) //check for P2P client mode
{
smsLog(pMac, LOG1, FL(" Ignore Beacon Interval Validation..."));
}
//IF SAP has started and STA wants to connect on different channel MCC should
//MCC should not be enabled so making it false to enforce on same channel
else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona
== VOS_STA_SAP_MODE)
{
if (pMac->roam.roamSession[sessionId].bssParams.operationChn
!= channelId )
{
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
if (VOS_MCC_TO_SCC_SWITCH_FORCE ==
pMac->roam.configParam.cc_switch_mode &&
pMac->roam.configParam.ap_p2pclient_concur_enable)
{
smsLog(pMac, LOG1, FL("SAP + CLIENT for MCC to SCC"));
return eHAL_STATUS_SUCCESS;
} else
#endif
{
smsLog(pMac, LOGE,
FL("***MCC is not enabled for SAP + CLIENT****"));
return eHAL_STATUS_FAILURE;
}
}
}
else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona
== VOS_P2P_GO_MODE) //Check for P2P go scenario
{
if ((pMac->roam.roamSession[sessionId].bssParams.operationChn
!= channelId ) &&
(pMac->roam.roamSession[sessionId].bssParams.beaconInterval
!= *beaconInterval))
{
smsLog(pMac, LOGE, FL("BeaconInterval is different cannot connect to P2P_GO network ..."));
return eHAL_STATUS_FAILURE;
}
}
break;
case VOS_STA_SAP_MODE :
break;
case VOS_P2P_GO_MODE :
{
if (pMac->roam.roamSession[sessionId].pCurRoamProfile &&
((pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona
== VOS_P2P_CLIENT_MODE) ||
(pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona
== VOS_STA_MODE))) //check for P2P_client scenario
{
if ((pMac->roam.roamSession[sessionId].connectedProfile.operationChannel
== 0 )&&
(pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval
== 0))
{
continue;
}
if (csrIsConnStateConnectedInfra(pMac, sessionId) &&
(pMac->roam.roamSession[sessionId].connectedProfile.operationChannel
!= channelId ) &&
(pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval
!= *beaconInterval))
{
/*
* Updated beaconInterval should be used only when
* we are starting a new BSS not in-case of client
* or STA case
*/
/* Calculate beacon Interval for P2P-GO
in-case of MCC */
if (pMac->roam.configParam.conc_custom_rule1 ||
pMac->roam.configParam.conc_custom_rule2) {
new_beaconInterval = CSR_CUSTOM_CONC_GO_BI;
} else {
new_beaconInterval =
csrCalculateMCCBeaconInterval(pMac,
pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval,
*beaconInterval);
}
if(*beaconInterval != new_beaconInterval)
*beaconInterval = new_beaconInterval;
return eHAL_STATUS_SUCCESS;
}
}
}
break;
default :
smsLog(pMac, LOGE, FL(" Persona not supported : %d"),currBssPersona);
return eHAL_STATUS_FAILURE;
}
}
}
return eHAL_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_VOWIFI_11R
/* Function to return TRUE if the auth type is 11r */
tANI_BOOLEAN csrIsAuthType11r( eCsrAuthType AuthType, tANI_U8 mdiePresent)
{
switch ( AuthType )
{
case eCSR_AUTH_TYPE_OPEN_SYSTEM:
if(mdiePresent)
return TRUE;
break;
case eCSR_AUTH_TYPE_FT_RSN_PSK:
case eCSR_AUTH_TYPE_FT_RSN:
return TRUE;
break;
default:
break;
}
return FALSE;
}
/* Function to return TRUE if the profile is 11r */
tANI_BOOLEAN csrIsProfile11r( tCsrRoamProfile *pProfile )
{
return csrIsAuthType11r( pProfile->negotiatedAuthType, pProfile->MDID.mdiePresent );
}
#endif
#ifdef FEATURE_WLAN_ESE
/* Function to return TRUE if the auth type is ESE */
tANI_BOOLEAN csrIsAuthTypeESE( eCsrAuthType AuthType )
{
switch ( AuthType )
{
case eCSR_AUTH_TYPE_CCKM_WPA:
case eCSR_AUTH_TYPE_CCKM_RSN:
return TRUE;
break;
default:
break;
}
return FALSE;
}
/* Function to return TRUE if the profile is ESE */
tANI_BOOLEAN csrIsProfileESE( tCsrRoamProfile *pProfile )
{
return (csrIsAuthTypeESE( pProfile->negotiatedAuthType ));
}
#endif
#ifdef FEATURE_WLAN_WAPI
tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile )
{
tANI_BOOLEAN fWapiProfile = FALSE;
switch ( pProfile->negotiatedAuthType )
{
case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
fWapiProfile = TRUE;
break;
default:
fWapiProfile = FALSE;
break;
}
if ( fWapiProfile )
{
switch ( pProfile->negotiatedUCEncryptionType )
{
case eCSR_ENCRYPT_TYPE_WPI:
fWapiProfile = TRUE;
break;
default:
fWapiProfile = FALSE;
break;
}
}
return( fWapiProfile );
}
static tANI_BOOLEAN csrIsWapiOuiEqual( tpAniSirGlobal pMac, tANI_U8 *Oui1, tANI_U8 *Oui2 )
{
return (vos_mem_compare(Oui1, Oui2, CSR_WAPI_OUI_SIZE));
}
static tANI_BOOLEAN csrIsWapiOuiMatch( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WAPI_OUI_SIZE],
tANI_U8 cAllCyphers,
tANI_U8 Cypher[],
tANI_U8 Oui[] )
{
tANI_BOOLEAN fYes = FALSE;
tANI_U8 idx;
for ( idx = 0; idx < cAllCyphers; idx++ )
{
if ( csrIsWapiOuiEqual( pMac, AllCyphers[ idx ], Cypher ) )
{
fYes = TRUE;
break;
}
}
if ( fYes && Oui )
{
vos_mem_copy(Oui, AllCyphers[ idx ], CSR_WAPI_OUI_SIZE);
}
return( fYes );
}
#endif /* FEATURE_WLAN_WAPI */
static tANI_BOOLEAN csrIsWpaOuiEqual( tpAniSirGlobal pMac, tANI_U8 *Oui1, tANI_U8 *Oui2 )
{
return(vos_mem_compare(Oui1, Oui2, CSR_WPA_OUI_SIZE));
}
static tANI_BOOLEAN csrIsOuiMatch( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE],
tANI_U8 cAllCyphers,
tANI_U8 Cypher[],
tANI_U8 Oui[] )
{
tANI_BOOLEAN fYes = FALSE;
tANI_U8 idx;
for ( idx = 0; idx < cAllCyphers; idx++ )
{
if ( csrIsWpaOuiEqual( pMac, AllCyphers[ idx ], Cypher ) )
{
fYes = TRUE;
break;
}
}
if ( fYes && Oui )
{
vos_mem_copy(Oui, AllCyphers[ idx ], CSR_WPA_OUI_SIZE);
}
return( fYes );
}
static tANI_BOOLEAN csrMatchRSNOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE],
tANI_U8 cAllCyphers, tANI_U8 ouiIndex,
tANI_U8 Oui[] )
{
return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui[ouiIndex], Oui ) );
}
#ifdef FEATURE_WLAN_WAPI
static tANI_BOOLEAN csrMatchWapiOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WAPI_OUI_SIZE],
tANI_U8 cAllCyphers, tANI_U8 ouiIndex,
tANI_U8 Oui[] )
{
return( csrIsWapiOuiMatch( pMac, AllCyphers, cAllCyphers, csrWapiOui[ouiIndex], Oui ) );
}
#endif /* FEATURE_WLAN_WAPI */
static tANI_BOOLEAN csrMatchWPAOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE],
tANI_U8 cAllCyphers, tANI_U8 ouiIndex,
tANI_U8 Oui[] )
{
return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui[ouiIndex], Oui ) );
}
#ifdef FEATURE_WLAN_WAPI
static tANI_BOOLEAN csrIsAuthWapiCert( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WAPI_OUI_SIZE],
tANI_U8 cAllSuites,
tANI_U8 Oui[] )
{
return( csrIsWapiOuiMatch( pMac, AllSuites, cAllSuites, csrWapiOui[1], Oui ) );
}
static tANI_BOOLEAN csrIsAuthWapiPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WAPI_OUI_SIZE],
tANI_U8 cAllSuites,
tANI_U8 Oui[] )
{
return( csrIsWapiOuiMatch( pMac, AllSuites, cAllSuites, csrWapiOui[2], Oui ) );
}
#endif /* FEATURE_WLAN_WAPI */
#ifdef WLAN_FEATURE_VOWIFI_11R
/*
* Function for 11R FT Authentication. We match the FT Authentication Cipher suite
* here. This matches for FT Auth with the 802.1X exchange.
*
*/
static tANI_BOOLEAN csrIsFTAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
tANI_U8 cAllSuites,
tANI_U8 Oui[] )
{
return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[03], Oui ) );
}
/*
* Function for 11R FT Authentication. We match the FT Authentication Cipher suite
* here. This matches for FT Auth with the PSK.
*
*/
static tANI_BOOLEAN csrIsFTAuthRSNPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
tANI_U8 cAllSuites,
tANI_U8 Oui[] )
{
return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[04], Oui ) );
}
#endif
#ifdef FEATURE_WLAN_ESE
/*
* Function for ESE CCKM AKM Authentication. We match the CCKM AKM Authentication Key Management suite
* here. This matches for CCKM AKM Auth with the 802.1X exchange.
*
*/
static tANI_BOOLEAN csrIsEseCckmAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
tANI_U8 cAllSuites,
tANI_U8 Oui[] )
{
return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ) );
}