/*
 * 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 ) );
}

static tANI_BOOLEAN csrIsEseCckmAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE],
                                tANI_U8 cAllSuites,
                                tANI_U8 Oui[] )
{
    return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[06], Oui ) );
}

#endif

static tANI_BOOLEAN csrIsAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
                                  tANI_U8 cAllSuites,
                                  tANI_U8 Oui[] )
{
    return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) );
}
static tANI_BOOLEAN csrIsAuthRSNPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
                                      tANI_U8 cAllSuites,
                                      tANI_U8 Oui[] )
{
    return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[02], Oui ) );
}

#ifdef WLAN_FEATURE_11W
static tANI_BOOLEAN csrIsAuthRSNPskSha256( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
                                      tANI_U8 cAllSuites,
                                      tANI_U8 Oui[] )
{
    return csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[07], Oui );
}
static tANI_BOOLEAN csrIsAuthRSN8021xSha256(tpAniSirGlobal pMac,
                                            tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
                                            tANI_U8 cAllSuites,
                                            tANI_U8 Oui[] )
{
    return csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[8], Oui );
}
#endif

#ifdef WLAN_FEATURE_FILS_SK
/*
 * csr_is_auth_fils_sha256() - check whether oui is fils sha256
 * @mac: Global MAC context
 * @all_suites: pointer to all supported akm suites
 * @suite_count: all supported akm suites count
 * @oui: Oui needs to be matched
 *
 * Return: True if OUI is FILS SHA256, false otherwise
 */
static bool csr_is_auth_fils_sha256(tpAniSirGlobal mac,
                    uint8_t all_suites[][CSR_RSN_OUI_SIZE],
                    uint8_t suite_count, uint8_t oui[])
{
    return csrIsOuiMatch(mac, all_suites, suite_count,
                csrRSNOui[ENUM_FILS_SHA256], oui);
}

/*
 * csr_is_auth_fils_sha384() - check whether oui is fils sha384
 * @mac: Global MAC context
 * @all_suites: pointer to all supported akm suites
 * @suite_count: all supported akm suites count
 * @oui: Oui needs to be matched
 *
 * Return: True if OUI is FILS SHA384, false otherwise
 */
static bool csr_is_auth_fils_sha384(tpAniSirGlobal mac,
                    uint8_t all_suites[][CSR_RSN_OUI_SIZE],
                    uint8_t suite_count, uint8_t oui[])
{
    return csrIsOuiMatch(mac, all_suites, suite_count,
                csrRSNOui[ENUM_FILS_SHA384], oui);
}

/*
 * csr_is_auth_fils_ft_sha256() - check whether oui is fils ft sha256
 * @mac: Global MAC context
 * @all_suites: pointer to all supported akm suites
 * @suite_count: all supported akm suites count
 * @oui: Oui needs to be matched
 *
 * Return: True if OUI is FT FILS SHA256, false otherwise
 */
static bool csr_is_auth_fils_ft_sha256(tpAniSirGlobal mac,
                    uint8_t all_suites[][CSR_RSN_OUI_SIZE],
                    uint8_t suite_count, uint8_t oui[])
{
    return csrIsOuiMatch(mac, all_suites, suite_count,
                csrRSNOui[ENUM_FT_FILS_SHA256], oui);
}

/*
 * csr_is_auth_fils_ft_sha384() - check whether oui is fils ft sha384
 * @mac: Global MAC context
 * @all_suites: pointer to all supported akm suites
 * @suite_count: all supported akm suites count
 * @oui: Oui needs to be matched
 *
 * Return: True if OUI is FT FILS SHA384, false otherwise
 */
static bool csr_is_auth_fils_ft_sha384(tpAniSirGlobal mac,
                    uint8_t all_suites[][CSR_RSN_OUI_SIZE],
                    uint8_t suite_count, uint8_t oui[])
{
    return csrIsOuiMatch(mac, all_suites, suite_count,
                csrRSNOui[ENUM_FT_FILS_SHA384], oui);
}
#endif

static tANI_BOOLEAN csrIsAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE],
                                tANI_U8 cAllSuites,
                                tANI_U8 Oui[] )
{
    return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[01], Oui ) );
}

static tANI_BOOLEAN csrIsAuthWpaPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE],
                                tANI_U8 cAllSuites,
                                tANI_U8 Oui[] )
{
    return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[02], Oui ) );
}

tANI_U8 csrGetOUIIndexFromCipher( eCsrEncryptionType enType )
{
    tANI_U8 OUIIndex;

        switch ( enType )
        {
            case eCSR_ENCRYPT_TYPE_WEP40:
            case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
                OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX;
                break;
            case eCSR_ENCRYPT_TYPE_WEP104:
            case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
                OUIIndex = CSR_OUI_WEP104_INDEX;
                break;
            case eCSR_ENCRYPT_TYPE_TKIP:
                OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX;
                break;
            case eCSR_ENCRYPT_TYPE_AES:
                OUIIndex = CSR_OUI_AES_INDEX;
                break;
            case eCSR_ENCRYPT_TYPE_NONE:
                OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX;
                break;
#ifdef FEATURE_WLAN_WAPI
           case eCSR_ENCRYPT_TYPE_WPI:
               OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX;
               break;
#endif /* FEATURE_WLAN_WAPI */
            default: //HOWTO handle this?
                OUIIndex = CSR_OUI_RESERVED_INDEX;
                break;
        }//switch

        return OUIIndex;
}

#ifdef WLAN_FEATURE_FILS_SK
/**
 * csr_is_fils_auth() - update negotiated auth if matches to FILS auth type
 * @mac_ctx: pointer to mac context
 * @authsuites: auth suites
 * @c_auth_suites: auth suites count
 * @authentication: authentication
 * @auth_type: authentication type list
 * @index: current counter
 * @neg_authtype: pointer to negotiated auth
 *
 * Return: None
 */
static void csr_is_fils_auth(tpAniSirGlobal mac_ctx,
    uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
    uint8_t authentication[], tCsrAuthList *auth_type,
    uint8_t index, eCsrAuthType *neg_authtype)
{
    /*
     * TODO Always try with highest security
     * move this down once sha384 is validated
     */
    if (csr_is_auth_fils_sha256(mac_ctx, authsuites,
                c_auth_suites, authentication)) {
        if (eCSR_AUTH_TYPE_FILS_SHA256 ==
                auth_type->authType[index])
            *neg_authtype = eCSR_AUTH_TYPE_FILS_SHA256;
    }
    if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
            csr_is_auth_fils_sha384(mac_ctx, authsuites,
                c_auth_suites, authentication)) {
        if (eCSR_AUTH_TYPE_FILS_SHA384 ==
                auth_type->authType[index])
            *neg_authtype = eCSR_AUTH_TYPE_FILS_SHA384;
    }
    if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
            csr_is_auth_fils_ft_sha256(mac_ctx, authsuites,
                c_auth_suites, authentication)) {
        if (eCSR_AUTH_TYPE_FT_FILS_SHA256 ==
                auth_type->authType[index])
            *neg_authtype = eCSR_AUTH_TYPE_FT_FILS_SHA256;
    }
    if ((*neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
            csr_is_auth_fils_ft_sha384(mac_ctx, authsuites,
                c_auth_suites, authentication)) {
        if (eCSR_AUTH_TYPE_FT_FILS_SHA384 ==
                auth_type->authType[index])
            *neg_authtype = eCSR_AUTH_TYPE_FT_FILS_SHA384;
    }
     VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              FL("negotiated auth type is %d"), *neg_authtype);
}
#else
static void csr_is_fils_auth(tpAniSirGlobal mac_ctx,
    uint8_t authsuites[][CSR_RSN_OUI_SIZE], uint8_t c_auth_suites,
    uint8_t authentication[], tCsrAuthList *auth_type,
    uint8_t index, eCsrAuthType *neg_authtype)
{
}
#endif

tANI_BOOLEAN csrGetRSNInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption,
                                   tDot11fIERSN *pRSNIe,
                           tANI_U8 *UnicastCypher,
                           tANI_U8 *MulticastCypher,
                           tANI_U8 *AuthSuite,
                           tCsrRSNCapabilities *Capabilities,
                           eCsrAuthType *pNegotiatedAuthtype,
                           eCsrEncryptionType *pNegotiatedMCCipher )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fAcceptableCyphers = FALSE;
    tANI_U8 cUnicastCyphers = 0;
    tANI_U8 cMulticastCyphers = 0;
    tANI_U8 cAuthSuites = 0, i;
    tANI_U8 Unicast[ CSR_RSN_OUI_SIZE ];
    tANI_U8 Multicast[ CSR_RSN_OUI_SIZE ];
    tANI_U8 AuthSuites[ CSR_RSN_MAX_AUTH_SUITES ][ CSR_RSN_OUI_SIZE ];
    tANI_U8 Authentication[ CSR_RSN_OUI_SIZE ];
    tANI_U8 MulticastCyphers[ CSR_RSN_MAX_MULTICAST_CYPHERS ][ CSR_RSN_OUI_SIZE ];
    eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;

    do{
        if ( pRSNIe->present )
        {
            cMulticastCyphers++;
            vos_mem_copy(MulticastCyphers, pRSNIe->gp_cipher_suite, CSR_RSN_OUI_SIZE);
            cUnicastCyphers = (tANI_U8)(pRSNIe->pwise_cipher_suite_count);
            cAuthSuites = (tANI_U8)(pRSNIe->akm_suite_count);
            for(i = 0; i < cAuthSuites && i < CSR_RSN_MAX_AUTH_SUITES; i++)
            {
                vos_mem_copy((void *)&AuthSuites[i],
                             (void *)&pRSNIe->akm_suites[i],
                             CSR_RSN_OUI_SIZE);
            }

            //Check - Is requested Unicast Cipher supported by the BSS.
            fAcceptableCyphers = csrMatchRSNOUIIndex( pMac, pRSNIe->pwise_cipher_suites, cUnicastCyphers,
                    csrGetOUIIndexFromCipher( enType ), Unicast );

            if( !fAcceptableCyphers ) break;


            //Unicast is supported. Pick the first matching Group cipher, if any.
            for( i = 0 ; i < pMCEncryption->numEntries ; i++ )
            {
                fAcceptableCyphers = csrMatchRSNOUIIndex( pMac, MulticastCyphers,  cMulticastCyphers,
                            csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i] ), Multicast );
                if(fAcceptableCyphers)
                {
                    break;
                }
            }
            if( !fAcceptableCyphers ) break;

            if( pNegotiatedMCCipher )
                *pNegotiatedMCCipher = pMCEncryption->encryptionType[i];

            /* Initializing with FALSE as it has TRUE value already */
            fAcceptableCyphers = FALSE;
            for (i = 0 ; i < pAuthType->numEntries; i++)
            {
                //Ciphers are supported, Match authentication algorithm and pick first matching authtype.

                 /* Set FILS as first preference */
                csr_is_fils_auth(pMac, AuthSuites, cAuthSuites,
                                 Authentication, pAuthType, i, &negAuthType);
#ifdef WLAN_FEATURE_VOWIFI_11R
                /* Changed the AKM suites according to order of preference */
                if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsFTAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_FT_RSN == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_FT_RSN;
                }
                if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsFTAuthRSNPsk( pMac, AuthSuites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_FT_RSN_PSK == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_FT_RSN_PSK;
                }
#endif
#ifdef FEATURE_WLAN_ESE
                /* ESE only supports 802.1X.  No PSK. */
                if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsEseCckmAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_CCKM_RSN == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_CCKM_RSN;
                }
#endif
                if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_RSN == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_RSN;
                }
                if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPsk( pMac, AuthSuites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_RSN_PSK == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_RSN_PSK;
                }
#ifdef WLAN_FEATURE_11W
                if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPskSha256( pMac, AuthSuites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
                }
                if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) &&
                    csrIsAuthRSN8021xSha256(pMac, AuthSuites,
                                             cAuthSuites, Authentication)) {
                    if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
                                                     pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
                }
#endif

                // The 1st auth type in the APs RSN IE, to match stations connecting
                // profiles auth type will cause us to exit this loop
                // This is added as some APs advertise multiple akms in the RSN IE.
                if (eCSR_AUTH_TYPE_UNKNOWN != negAuthType)
                {
                    fAcceptableCyphers = TRUE;
                    break;
                }
            } // for
        }

    }while (0);

    if ( fAcceptableCyphers )
    {
        if ( MulticastCypher )
        {
            vos_mem_copy(MulticastCypher, Multicast, CSR_RSN_OUI_SIZE);
        }

        if ( UnicastCypher )
        {
            vos_mem_copy(UnicastCypher, Unicast, CSR_RSN_OUI_SIZE);
        }

        if ( AuthSuite )
        {
            vos_mem_copy(AuthSuite, Authentication, CSR_RSN_OUI_SIZE);
        }

        if ( pNegotiatedAuthtype )
        {
            *pNegotiatedAuthtype = negAuthType;
        }
        if ( Capabilities )
        {
            Capabilities->PreAuthSupported = (pRSNIe->RSN_Cap[0] >> 0) & 0x1 ; // Bit 0 PreAuthentication
            Capabilities->NoPairwise = (pRSNIe->RSN_Cap[0] >> 1) & 0x1 ; // Bit 1 No Pairwise
            Capabilities->PTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 2) & 0x3 ; // Bit 2, 3 PTKSA Replay Counter
            Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4, 5 GTKSA Replay Counter
#ifdef WLAN_FEATURE_11W
            Capabilities->MFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1 ; // Bit 6 MFPR
            Capabilities->MFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1 ; // Bit 7 MFPC
#else
            Capabilities->MFPRequired = 0 ; // Bit 6 MFPR
            Capabilities->MFPCapable = 0 ; // Bit 7 MFPC
#endif
            Capabilities->Reserved = pRSNIe->RSN_Cap[1]  & 0xff ; // remaining reserved
        }
    }
    return( fAcceptableCyphers );
}

#ifdef WLAN_FEATURE_11W
/* ---------------------------------------------------------------------------
    \fn csrIsPMFCapabilitiesInRSNMatch

    \brief this function is to match our current capabilities with the AP
           to which we are expecting make the connection.

    \param hHal               - HAL Pointer
           pFilterMFPEnabled  - given by supplicant to us to specify what kind
                                of connection supplicant is expecting to make
                                if it is enabled then make PMF connection.
                                if it is disabled then make normal connection.
           pFilterMFPRequired - given by supplicant based on our configuration
                                if it is 1 then we will require mandatory
                                PMF connection and if it is 0 then we PMF
                                connection is optional.
           pFilterMFPCapable  - given by supplicant based on our configuration
                                if it 1 then we are PMF capable and if it 0
                                then we are not PMF capable.
           pRSNIe             - RSNIe from Beacon/probe response of
                                neighbor AP against which we will compare
                                our capabilities.

    \return tANI_BOOLEAN      - if our PMF capabilities matches with AP then we
                                will return true to indicate that we are good
                                to make connection with it. Else we will return
                                false.
  -------------------------------------------------------------------------------*/
static tANI_BOOLEAN
csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal,
                                tANI_BOOLEAN *pFilterMFPEnabled,
                                tANI_U8 *pFilterMFPRequired,
                                tANI_U8 *pFilterMFPCapable,
                                tDot11fIERSN *pRSNIe)
{
    tANI_U8 apProfileMFPCapable  = 0;
    tANI_U8 apProfileMFPRequired = 0;
    if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable && pFilterMFPRequired)
    {
       /* Extracting MFPCapable bit from RSN Ie */
       apProfileMFPCapable  = (pRSNIe->RSN_Cap[0] >> 7) & 0x1;
       apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1;

       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
          FL("pFilterMFPEnabled=%d pFilterMFPRequired=%d pFilterMFPCapable=%d apProfileMFPCapable=%d apProfileMFPRequired=%d"),
               *pFilterMFPEnabled, *pFilterMFPRequired, *pFilterMFPCapable,
               apProfileMFPCapable, apProfileMFPRequired);

       if (*pFilterMFPEnabled && *pFilterMFPCapable && *pFilterMFPRequired
           && (apProfileMFPCapable == 0))
       {
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
                     "AP is not capable to make PMF connection");
           return VOS_FALSE;
       }
       else if (!(*pFilterMFPCapable) &&
                apProfileMFPCapable && apProfileMFPRequired)
       {

           /*
            * In this case, AP with whom we trying to connect requires
            * mandatory PMF connections and we are not capable so this AP
            * is not good choice to connect
            */
           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
           "AP needs PMF connection and we are not capable of pmf connection");
           return VOS_FALSE;
       }
    }
    return VOS_TRUE;
}
#endif

tANI_BOOLEAN csrIsRSNMatch( tHalHandle hHal, tCsrAuthList *pAuthType,
                            eCsrEncryptionType enType,
                            tCsrEncryptionList *pEnMcType,
                            tANI_BOOLEAN *pMFPEnabled, tANI_U8 *pMFPRequired,
                            tANI_U8 *pMFPCapable,
                            tDot11fBeaconIEs *pIes,
                            eCsrAuthType *pNegotiatedAuthType,
                            eCsrEncryptionType *pNegotiatedMCCipher )
{
    tANI_BOOLEAN fRSNMatch = FALSE;

        // See if the cyphers in the Bss description match with the settings in the profile.
    fRSNMatch = csrGetRSNInformation( hHal, pAuthType, enType, pEnMcType, &pIes->RSN, NULL, NULL, NULL, NULL,
                                      pNegotiatedAuthType, pNegotiatedMCCipher );
#ifdef WLAN_FEATURE_11W
    /* If all the filter matches then finally checks for PMF capabilities */
    if (fRSNMatch)
    {
        fRSNMatch = csrIsPMFCapabilitiesInRSNMatch( hHal, pMFPEnabled,
                                                    pMFPRequired, pMFPCapable,
                                                    &pIes->RSN);
    }
#endif
    return( fRSNMatch );
}

/**
 * csr_lookup_pmkid_using_ssid() - lookup pmkid using ssid and cache_id
 * @mac: pointer to mac
 * @session: sme session pointer
 * @pmk_cache: pointer to pmk cache
 * @index: index value needs to be seached
 *
 * Return: true if pmkid is found else false
 */
static bool csr_lookup_pmkid_using_ssid(tpAniSirGlobal mac,
                    tCsrRoamSession *session,
                    tPmkidCacheInfo *pmk_cache,
                    uint32_t *index)
{
    uint32_t i;
    tPmkidCacheInfo *session_pmk;

    for (i = 0; i < session->NumPmkidCache; i++) {
        session_pmk = &session->PmkidCacheInfo[i];

        if ((!adf_os_mem_cmp(pmk_cache->ssid, session_pmk->ssid,
                  pmk_cache->ssid_len)) &&
            (!adf_os_mem_cmp(session_pmk->cache_id,
                  pmk_cache->cache_id, CACHE_ID_LEN))) {
            /* match found */
            *index = i;
            return true;
        }
    }

    return false;
}

/**
 * csr_lookup_pmkid_using_bssid() - lookup pmkid using bssid
 * @mac: pointer to mac
 * @session: sme session pointer
 * @pmk_cache: pointer to pmk cache
 * @index: index value needs to be seached
 *
 * Return: true if pmkid is found else false
 */
static bool csr_lookup_pmkid_using_bssid(tpAniSirGlobal mac,
                    tCsrRoamSession *session,
                    tPmkidCacheInfo *pmk_cache,
                    uint32_t *index)
{
    uint32_t i;
    tPmkidCacheInfo *session_pmk;

    for (i = 0; i < session->NumPmkidCache; i++) {
        session_pmk = &session->PmkidCacheInfo[i];
        if (vos_is_macaddr_equal((v_MACADDR_t *)pmk_cache->BSSID,
                     (v_MACADDR_t *)session_pmk->BSSID)) {
            /* match found */
            *index = i;
            return true;
        }
    }

    return false;
}

tANI_BOOLEAN csrLookupPMKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tPmkidCacheInfo *pmk_cache)
{
    tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE;
    tANI_U32 Index;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return FALSE;
    }

    if (pmk_cache->ssid_len) {
        /* Try to find based on cache_id and ssid first */
        fMatchFound = csr_lookup_pmkid_using_ssid(pMac, pSession,
                                                  pmk_cache, &Index);
    }

    /* If not able to find using cache id or ssid_len is not present */
    if (!fMatchFound)
        fMatchFound = csr_lookup_pmkid_using_bssid(pMac,
                                        pSession, pmk_cache, &Index);

    if (!fMatchFound) {
        smsLog(pMac, LOG2, "No PMKID Match Found");
        return false;
    }

    vos_mem_copy(pmk_cache->PMKID, pSession->PmkidCacheInfo[Index].PMKID, CSR_RSN_PMKID_SIZE);
    vos_mem_copy(pmk_cache->pmk,
                 pSession->PmkidCacheInfo[Index].pmk,
                 pSession->PmkidCacheInfo[Index].pmk_len);
    pmk_cache->pmk_len = pSession->PmkidCacheInfo[Index].pmk_len;

    fRC = TRUE;

    smsLog(pMac, LOG1, "csrLookupPMKID called return match = %d pMac->roam.NumPmkidCache = %d",
        fRC, pSession->NumPmkidCache);

    return fRC;
}

#ifdef WLAN_FEATURE_FILS_SK
/*
 * csr_update_pmksa_for_cache_id: update tPmkidCacheInfo to lookup using
 * ssid and cache id
 * @bss_desc: bss description
 * @profile: csr roam profile
 * @pmkid_cache: pmksa cache
 *
 * Return: true if cache identifier present else false
 */
static bool csr_update_pmksa_for_cache_id(tSirBssDescription *bss_desc,
                tCsrRoamProfile *profile,
                tPmkidCacheInfo *pmkid_cache)
{
    if (!bss_desc->fils_info_element.is_cache_id_present)
        return false;

    pmkid_cache->ssid_len =
        profile->SSIDs.SSIDList[0].SSID.length;
    vos_mem_copy(pmkid_cache->ssid,
        profile->SSIDs.SSIDList[0].SSID.ssId,
        profile->SSIDs.SSIDList[0].SSID.length);
    vos_mem_copy(pmkid_cache->cache_id,
        bss_desc->fils_info_element.cache_id,
        CACHE_ID_LEN);
    vos_mem_copy(pmkid_cache->BSSID,
        bss_desc->bssId, VOS_MAC_ADDR_SIZE);

    return true;
}

/*
 * csr_update_pmksa_to_profile: update pmk and pmkid to profile which will be
 * used in case of fils session
 * @profile: profile
 * @pmkid_cache: pmksa cache
 *
 * Return: None
 */
static inline void csr_update_pmksa_to_profile(tCsrRoamProfile *profile,
        tPmkidCacheInfo *pmkid_cache)
{
    if (!profile->fils_con_info)
        return;

    profile->fils_con_info->pmk_len = pmkid_cache->pmk_len;
    vos_mem_copy(profile->fils_con_info->pmk,
            pmkid_cache->pmk, pmkid_cache->pmk_len);
    vos_mem_copy(profile->fils_con_info->pmkid,
        pmkid_cache->PMKID, CSR_RSN_PMKID_SIZE);

}
#else
static inline bool csr_update_pmksa_for_cache_id(tSirBssDescription *bss_desc,
                tCsrRoamProfile *profile,
                tPmkidCacheInfo *pmkid_cache)
{
    return false;
}

static inline void csr_update_pmksa_to_profile(tCsrRoamProfile *profile,
        tPmkidCacheInfo *pmkid_cache)
{
}
#endif

tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile,
                            tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fRSNMatch;
    tANI_U8 cbRSNIe = 0;
    tANI_U8 UnicastCypher[ CSR_RSN_OUI_SIZE ];
    tANI_U8 MulticastCypher[ CSR_RSN_OUI_SIZE ];
    tANI_U8 AuthSuite[ CSR_RSN_OUI_SIZE ];
    tCsrRSNAuthIe *pAuthSuite;
    tCsrRSNCapabilities RSNCapabilities;
    tCsrRSNPMKIe        *pPMK;
    tPmkidCacheInfo pmkid_cache;
#ifdef WLAN_FEATURE_11W
    tANI_U8 *pGroupMgmtCipherSuite;
#endif
    tDot11fBeaconIEs *pIesLocal = pIes;
    eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;

    smsLog(pMac, LOGW, "%s called...", __func__);

    do
    {
        if ( !csrIsProfileRSN( pProfile ) ) break;

        if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
        {
            break;
        }

        // See if the cyphers in the Bss description match with the settings in the profile.
        fRSNMatch = csrGetRSNInformation( hHal, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType,
                                            &pProfile->mcEncryptionType, &pIesLocal->RSN,
                                            UnicastCypher, MulticastCypher, AuthSuite, &RSNCapabilities, &negAuthType, NULL );
        if ( !fRSNMatch ) break;

        pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID;

        pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED;

        vos_mem_copy(pRSNIe->MulticastOui, MulticastCypher, sizeof( MulticastCypher ));

        pRSNIe->cUnicastCyphers = 1;

        vos_mem_copy(&pRSNIe->UnicastOui[ 0 ], UnicastCypher, sizeof( UnicastCypher ));

        pAuthSuite = (tCsrRSNAuthIe *)( &pRSNIe->UnicastOui[ pRSNIe->cUnicastCyphers ] );

        pAuthSuite->cAuthenticationSuites = 1;
        vos_mem_copy(&pAuthSuite->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite ));

        /*
         * RSN capabilities follows the Auth Suite (two octets)
         * !!REVIEW - What should STA put in RSN capabilities, currently
         * just putting back APs capabilities For one, we shouldn't EVER be
         * sending out "pre-auth supported". It is an AP only capability.
         * For another, we should use the Management Frame Protection
         * values given by the supplicant
         */
        RSNCapabilities.PreAuthSupported = 0;
#ifdef WLAN_FEATURE_11W
        if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) {
            RSNCapabilities.MFPCapable = pProfile->MFPCapable;
            RSNCapabilities.MFPRequired = pProfile->MFPRequired;
        }
        else {
            RSNCapabilities.MFPCapable = 0;
            RSNCapabilities.MFPRequired = 0;
        }
#endif
        *(tANI_U16 *)( &pAuthSuite->AuthOui[ 1 ] ) = *((tANI_U16 *)(&RSNCapabilities));

        pPMK = (tCsrRSNPMKIe *)( ((tANI_U8 *)(&pAuthSuite->AuthOui[ 1 ])) + sizeof(tANI_U16) );
        if (!csr_update_pmksa_for_cache_id(pSirBssDesc, pProfile, &pmkid_cache))
            vos_mem_copy((v_MACADDR_t *)pmkid_cache.BSSID,
                        (v_MACADDR_t *)pSirBssDesc->bssId,
                         VOS_MAC_ADDR_SIZE);
        // Don't include the PMK SA IDs for CCKM associations.
        if (
#ifdef FEATURE_WLAN_ESE
                (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
#endif
              csrLookupPMKID( pMac, sessionId, &pmkid_cache))
        {
            pPMK->cPMKIDs = 1;

            vos_mem_copy(pPMK->PMKIDList[0].PMKID, 
                         pmkid_cache.PMKID,
                         CSR_RSN_PMKID_SIZE);
            csr_update_pmksa_to_profile(pProfile, &pmkid_cache);
        }
        else
        {
            pPMK->cPMKIDs = 0;
        }

#ifdef WLAN_FEATURE_11W
         /* Advertise BIP in group cipher key management only if PMF is enabled
          * and AP is capable.
          */
        if (pProfile->MFPEnabled &&
                (RSNCapabilities.MFPCapable && pProfile->MFPCapable)){
            pGroupMgmtCipherSuite = (tANI_U8 *) pPMK + sizeof ( tANI_U16 ) +
                ( pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE );
            vos_mem_copy(pGroupMgmtCipherSuite, csrRSNOui[07], CSR_WPA_OUI_SIZE);
        }
#endif

        // Add in the fixed fields plus 1 Unicast cypher, less the IE Header length
        // Add in the size of the Auth suite (count plus a single OUI)
        // Add in the RSN caps field.
        // Add PMKID count and PMKID (if any)
        // Add group management cipher suite
        pRSNIe->IeHeader.Length = (tANI_U8) (sizeof( *pRSNIe ) - sizeof ( pRSNIe->IeHeader ) +
                                  sizeof( *pAuthSuite ) +
                                  sizeof( tCsrRSNCapabilities ));
        if(pPMK->cPMKIDs)
        {
            pRSNIe->IeHeader.Length += (tANI_U8)(sizeof( tANI_U16 ) +
                                        (pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE));
        }
#ifdef WLAN_FEATURE_11W
        if (pProfile->MFPEnabled &&
                (RSNCapabilities.MFPCapable && pProfile->MFPCapable)){
            if ( 0 == pPMK->cPMKIDs )
                pRSNIe->IeHeader.Length += sizeof( tANI_U16 );
            pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE;
        }
#endif

        // return the size of the IE header (total) constructed...
        cbRSNIe = pRSNIe->IeHeader.Length + sizeof( pRSNIe->IeHeader );

    } while( 0 );

    if( !pIes && pIesLocal )
    {
        //locally allocated
        vos_mem_free(pIesLocal);
    }

    return( cbRSNIe );
}


#ifdef FEATURE_WLAN_WAPI
tANI_BOOLEAN csrGetWapiInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption,
                                   tDot11fIEWAPI *pWapiIe,
                                    tANI_U8 *UnicastCypher,
                                    tANI_U8 *MulticastCypher,
                                    tANI_U8 *AuthSuite,
                                    eCsrAuthType *pNegotiatedAuthtype,
                                    eCsrEncryptionType *pNegotiatedMCCipher )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fAcceptableCyphers = FALSE;
    tANI_U8 cUnicastCyphers = 0;
    tANI_U8 cMulticastCyphers = 0;
    tANI_U8 cAuthSuites = 0, i;
    tANI_U8 Unicast[ CSR_WAPI_OUI_SIZE ];
    tANI_U8 Multicast[ CSR_WAPI_OUI_SIZE ];
    tANI_U8 AuthSuites[ CSR_WAPI_MAX_AUTH_SUITES ][ CSR_WAPI_OUI_SIZE ];
    tANI_U8 Authentication[ CSR_WAPI_OUI_SIZE ];
    tANI_U8 MulticastCyphers[ CSR_WAPI_MAX_MULTICAST_CYPHERS ][ CSR_WAPI_OUI_SIZE ];
    eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;
    tANI_U8 wapiOuiIndex = 0;
    do{
        if ( pWapiIe->present )
        {
            cMulticastCyphers++;
            vos_mem_copy(MulticastCyphers, pWapiIe->multicast_cipher_suite,
                         CSR_WAPI_OUI_SIZE);
            cUnicastCyphers = (tANI_U8)(pWapiIe->unicast_cipher_suite_count);
            cAuthSuites = (tANI_U8)(pWapiIe->akm_suite_count);
            for(i = 0; i < cAuthSuites && i < CSR_WAPI_MAX_AUTH_SUITES; i++)
            {
                vos_mem_copy((void *)&AuthSuites[i], (void *)&pWapiIe->akm_suites[i],
                             CSR_WAPI_OUI_SIZE);
            }

            wapiOuiIndex = csrGetOUIIndexFromCipher( enType );
            if (wapiOuiIndex >= CSR_OUI_WAPI_WAI_MAX_INDEX)
            {
                smsLog(pMac, LOGE, FL("Wapi OUI index = %d out of limit"), wapiOuiIndex);
                fAcceptableCyphers = FALSE;
                break;
            }
            //Check - Is requested Unicast Cipher supported by the BSS.
            fAcceptableCyphers = csrMatchWapiOUIIndex( pMac, pWapiIe->unicast_cipher_suites, cUnicastCyphers,
                    wapiOuiIndex, Unicast );

            if( !fAcceptableCyphers ) break;

            //Unicast is supported. Pick the first matching Group cipher, if any.
            for( i = 0 ; i < pMCEncryption->numEntries ; i++ )
            {
                wapiOuiIndex = csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i] );
                if (wapiOuiIndex >= CSR_OUI_WAPI_WAI_MAX_INDEX)
                {
                    smsLog(pMac, LOGE, FL("Wapi OUI index = %d out of limit"), wapiOuiIndex);
                    fAcceptableCyphers = FALSE;
                    break;
                }
                fAcceptableCyphers = csrMatchWapiOUIIndex( pMac, MulticastCyphers,  cMulticastCyphers,
                        wapiOuiIndex, Multicast );
                if(fAcceptableCyphers)
                {
                    break;
                }
            }
            if( !fAcceptableCyphers ) break;

            if( pNegotiatedMCCipher )
                *pNegotiatedMCCipher = pMCEncryption->encryptionType[i];

            /* Ciphers are supported, Match authentication algorithm and pick
               first matching auth type. */
            if ( csrIsAuthWapiCert( pMac, AuthSuites, cAuthSuites, Authentication ) )
            {
                negAuthType = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
            }
            else if ( csrIsAuthWapiPsk( pMac, AuthSuites, cAuthSuites, Authentication ) )
            {
                negAuthType = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
            }
            else
            {
                fAcceptableCyphers = FALSE;
                negAuthType = eCSR_AUTH_TYPE_UNKNOWN;
            }
            if( ( 0 == pAuthType->numEntries ) || ( FALSE == fAcceptableCyphers ) )
            {
                //Caller doesn't care about auth type, or BSS doesn't match
                break;
            }
            fAcceptableCyphers = FALSE;
            for( i = 0 ; i < pAuthType->numEntries; i++ )
            {
                if( pAuthType->authType[i] == negAuthType )
                {
                    fAcceptableCyphers = TRUE;
                    break;
                }
            }
        }
    }while (0);

    if ( fAcceptableCyphers )
    {
        if ( MulticastCypher )
        {
           vos_mem_copy(MulticastCypher, Multicast, CSR_WAPI_OUI_SIZE);
        }

        if ( UnicastCypher )
        {
            vos_mem_copy(UnicastCypher, Unicast, CSR_WAPI_OUI_SIZE);
        }

        if ( AuthSuite )
        {
            vos_mem_copy(AuthSuite, Authentication, CSR_WAPI_OUI_SIZE);
        }

        if ( pNegotiatedAuthtype )
        {
            *pNegotiatedAuthtype = negAuthType;
        }
    }
    return( fAcceptableCyphers );
}

tANI_BOOLEAN csrIsWapiMatch( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType,
                            tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCCipher )
{
    tANI_BOOLEAN fWapiMatch = FALSE;

        // See if the cyphers in the Bss description match with the settings in the profile.
    fWapiMatch = csrGetWapiInformation( hHal, pAuthType, enType, pEnMcType, &pIes->WAPI, NULL, NULL, NULL,
                                      pNegotiatedAuthType, pNegotiatedMCCipher );

    return( fWapiMatch );
}

tANI_BOOLEAN csrLookupBKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 *pBSSId, tANI_U8 *pBKId )
{
    tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE;
    tANI_U32 Index;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

    if(!pSession)
    {
        smsLog(pMac, LOGE, FL("  session %d not found "), sessionId);
        return FALSE;
    }

    do
    {
        for( Index=0; Index < pSession->NumBkidCache; Index++ )
        {
            smsLog(pMac, LOGW, "match BKID "MAC_ADDRESS_STR" to ",
                   MAC_ADDR_ARRAY(pBSSId));
            if (vos_mem_compare(pBSSId, pSession->BkidCacheInfo[Index].BSSID, sizeof(tCsrBssid) ) )
            {
                // match found
                fMatchFound = TRUE;
                break;
            }
        }

        if( !fMatchFound ) break;

        vos_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID, CSR_WAPI_BKID_SIZE);

        fRC = TRUE;
    }
    while( 0 );
    smsLog(pMac, LOGW, "csrLookupBKID called return match = %d pMac->roam.NumBkidCache = %d", fRC, pSession->NumBkidCache);

    return fRC;
}

tANI_U8 csrConstructWapiIe( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile,
                            tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe )
{
    tANI_BOOLEAN fWapiMatch = FALSE;
    tANI_U8 cbWapiIe = 0;
    tANI_U8 UnicastCypher[ CSR_WAPI_OUI_SIZE ];
    tANI_U8 MulticastCypher[ CSR_WAPI_OUI_SIZE ];
    tANI_U8 AuthSuite[ CSR_WAPI_OUI_SIZE ];
    tANI_U8 BKId[CSR_WAPI_BKID_SIZE];
    tANI_U8 *pWapi = NULL;
    tANI_BOOLEAN fBKIDFound = FALSE;
    tDot11fBeaconIEs *pIesLocal = pIes;

    do
    {
        if ( !csrIsProfileWapi( pProfile ) ) break;

        if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
        {
            break;
        }

        // See if the cyphers in the Bss description match with the settings in the profile.
        fWapiMatch = csrGetWapiInformation( pMac, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType,
                                            &pProfile->mcEncryptionType, &pIesLocal->WAPI,
                                            UnicastCypher, MulticastCypher, AuthSuite, NULL, NULL );
        if ( !fWapiMatch ) break;

        vos_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0);

        pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI;

        pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED;

        pWapiIe->cAuthenticationSuites = 1;
        vos_mem_copy(&pWapiIe->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite ));

        pWapi = (tANI_U8 *) (&pWapiIe->AuthOui[ 1 ]);

        *pWapi = (tANI_U16)1; //cUnicastCyphers
        pWapi+=2;
        vos_mem_copy(pWapi, UnicastCypher, sizeof( UnicastCypher ));
        pWapi += sizeof( UnicastCypher );

        vos_mem_copy(pWapi, MulticastCypher, sizeof( MulticastCypher ));
        pWapi += sizeof( MulticastCypher );


        /*
         * WAPI capabilities follows the Auth Suite (two octets)
         * we shouldn't EVER be sending out "pre-auth supported".
         * It is an AP only capability & since we already did a memset
         * pWapiIe to 0, skip these fields
         */
        pWapi +=2;

        fBKIDFound = csrLookupBKID( pMac, sessionId, pSirBssDesc->bssId, &(BKId[0]) );


        if( fBKIDFound )
        {
            /* Do we need to change the endianness here */
            *pWapi = (tANI_U16)1; //cBKIDs
            pWapi+=2;
            vos_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE);
        }
        else
        {
            *pWapi = 0;
            pWapi+=1;
            *pWapi = 0;
            pWapi+=1;
        }

        // Add in the IE fields except the IE header
        // Add BKID count and BKID (if any)
        pWapiIe->IeHeader.Length = (tANI_U8) (sizeof( *pWapiIe ) - sizeof ( pWapiIe->IeHeader ));

        /*2 bytes for BKID Count field*/
        pWapiIe->IeHeader.Length += sizeof( tANI_U16 );

        if(fBKIDFound)
        {
            pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE;
        }
        // return the size of the IE header (total) constructed...
        cbWapiIe = pWapiIe->IeHeader.Length + sizeof( pWapiIe->IeHeader );

    } while( 0 );

    if( !pIes && pIesLocal )
    {
        //locally allocated
        vos_mem_free(pIesLocal);
    }

    return( cbWapiIe );
}
#endif /* FEATURE_WLAN_WAPI */

tANI_BOOLEAN csrGetWpaCyphers( tpAniSirGlobal pMac, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption,
                               tDot11fIEWPA *pWpaIe,
                           tANI_U8 *UnicastCypher,
                           tANI_U8 *MulticastCypher,
                           tANI_U8 *AuthSuite,
                           eCsrAuthType *pNegotiatedAuthtype,
                           eCsrEncryptionType *pNegotiatedMCCipher )
{
    tANI_BOOLEAN fAcceptableCyphers = FALSE;
    tANI_U8 cUnicastCyphers = 0;
    tANI_U8 cMulticastCyphers = 0;
    tANI_U8 cAuthSuites = 0;
    tANI_U8 Unicast[ CSR_WPA_OUI_SIZE ];
    tANI_U8 Multicast[ CSR_WPA_OUI_SIZE ];
    tANI_U8 Authentication[ CSR_WPA_OUI_SIZE ];
    tANI_U8 MulticastCyphers[ 1 ][ CSR_WPA_OUI_SIZE ];
    tANI_U8 i;
    eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;

    do
    {
        if ( pWpaIe->present )
        {
            cMulticastCyphers = 1;
            vos_mem_copy(MulticastCyphers, pWpaIe->multicast_cipher, CSR_WPA_OUI_SIZE);
            cUnicastCyphers = (tANI_U8)(pWpaIe->unicast_cipher_count);
            cAuthSuites = (tANI_U8)(pWpaIe->auth_suite_count);

            //Check - Is requested Unicast Cipher supported by the BSS.
            fAcceptableCyphers = csrMatchWPAOUIIndex( pMac, pWpaIe->unicast_ciphers, cUnicastCyphers,
                    csrGetOUIIndexFromCipher( enType ), Unicast );

            if( !fAcceptableCyphers ) break;


            //Unicast is supported. Pick the first matching Group cipher, if any.
            for( i = 0 ; i < pMCEncryption->numEntries ; i++ )
            {
                fAcceptableCyphers = csrMatchWPAOUIIndex( pMac, MulticastCyphers,  cMulticastCyphers,
                            csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i]), Multicast );
                if(fAcceptableCyphers)
                {
                    break;
                }
            }
            if( !fAcceptableCyphers ) break;

            if( pNegotiatedMCCipher )
                *pNegotiatedMCCipher = pMCEncryption->encryptionType[i];

                /* Initializing with FALSE as it has TRUE value already */
            fAcceptableCyphers = FALSE;
            for (i = 0 ; i < pAuthType->numEntries; i++)
            {
                /* Ciphers are supported, Match authentication algorithm
                   and pick first matching auth type */
                if ( csrIsAuthWpa( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_WPA == pAuthType->authType[i])
                    negAuthType = eCSR_AUTH_TYPE_WPA;
                }
                if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthWpaPsk( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_WPA_PSK == pAuthType->authType[i])
                    negAuthType = eCSR_AUTH_TYPE_WPA_PSK;
                }
#ifdef FEATURE_WLAN_ESE
                if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsEseCckmAuthWpa( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) )
                {
                    if (eCSR_AUTH_TYPE_CCKM_WPA == pAuthType->authType[i])
                        negAuthType = eCSR_AUTH_TYPE_CCKM_WPA;
                }
#endif /* FEATURE_WLAN_ESE */

                // The 1st auth type in the APs WPA IE, to match stations connecting
                // profiles auth type will cause us to exit this loop
                // This is added as some APs advertise multiple akms in the WPA IE.
                if (eCSR_AUTH_TYPE_UNKNOWN != negAuthType)
                {
                        fAcceptableCyphers = TRUE;
                        break;
                    }
            } // for
            }
    }while(0);

    if ( fAcceptableCyphers )
    {
        if ( MulticastCypher )
        {
            vos_mem_copy((tANI_U8 **)MulticastCypher, Multicast, CSR_WPA_OUI_SIZE);
        }

        if ( UnicastCypher )
        {
            vos_mem_copy((tANI_U8 **)UnicastCypher, Unicast, CSR_WPA_OUI_SIZE);
        }

        if ( AuthSuite )
        {
            vos_mem_copy((tANI_U8 **)AuthSuite, Authentication, CSR_WPA_OUI_SIZE);
        }

        if( pNegotiatedAuthtype )
        {
            *pNegotiatedAuthtype = negAuthType;
        }
    }

    return( fAcceptableCyphers );
}



tANI_BOOLEAN csrIsWpaEncryptionMatch( tpAniSirGlobal pMac, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType,
                                        tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthtype, eCsrEncryptionType *pNegotiatedMCCipher )
{
    tANI_BOOLEAN fWpaMatch = eANI_BOOLEAN_FALSE;

        // See if the cyphers in the Bss description match with the settings in the profile.
    fWpaMatch = csrGetWpaCyphers( pMac, pAuthType, enType, pEnMcType, &pIes->WPA, NULL, NULL, NULL, pNegotiatedAuthtype, pNegotiatedMCCipher );

    return( fWpaMatch );
}


tANI_U8 csrConstructWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc,
                           tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fWpaMatch;
    tANI_U8 cbWpaIe = 0;
    tANI_U8 UnicastCypher[ CSR_WPA_OUI_SIZE ];
    tANI_U8 MulticastCypher[ CSR_WPA_OUI_SIZE ];
    tANI_U8 AuthSuite[ CSR_WPA_OUI_SIZE ];
    tCsrWpaAuthIe *pAuthSuite;
    tDot11fBeaconIEs *pIesLocal = pIes;

    do
    {
        if ( !csrIsProfileWpa( pProfile ) ) break;

        if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
        {
            break;
        }
        // See if the cyphers in the Bss description match with the settings in the profile.
        fWpaMatch = csrGetWpaCyphers( hHal, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, &pProfile->mcEncryptionType,
                                      &pIesLocal->WPA, UnicastCypher, MulticastCypher, AuthSuite, NULL, NULL );
        if ( !fWpaMatch ) break;

        pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID;

        vos_mem_copy(pWpaIe->Oui, csrWpaOui[01], sizeof( pWpaIe->Oui ));

        pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED;

        vos_mem_copy(pWpaIe->MulticastOui, MulticastCypher, sizeof( MulticastCypher ));

        pWpaIe->cUnicastCyphers = 1;

        vos_mem_copy(&pWpaIe->UnicastOui[ 0 ], UnicastCypher, sizeof( UnicastCypher ));

        pAuthSuite = (tCsrWpaAuthIe *)( &pWpaIe->UnicastOui[ pWpaIe->cUnicastCyphers ] );

        pAuthSuite->cAuthenticationSuites = 1;
        vos_mem_copy(&pAuthSuite->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite ));

        /*
         * The WPA capabilities follows the Auth Suite (two octets)--
         * this field is optional, and we always "send" zero, so just
         * remove it.  This is consistent with our assumptions in the
         * frames compiler; c.f. bug 15234:
         * http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234
         *
         * Add in the fixed fields plus 1 Unicast cypher, less the IE Header
         * length
         * Add in the size of the Auth suite (count plus a single OUI)
         */
        pWpaIe->IeHeader.Length = sizeof( *pWpaIe ) - sizeof ( pWpaIe->IeHeader ) +
                                  sizeof( *pAuthSuite );

        // return the size of the IE header (total) constructed...
        cbWpaIe = pWpaIe->IeHeader.Length + sizeof( pWpaIe->IeHeader );

    } while( 0 );

    if( !pIes && pIesLocal )
    {
        //locally allocated
        vos_mem_free(pIesLocal);
    }

    return( cbWpaIe );
}


tANI_BOOLEAN csrGetWpaRsnIe( tHalHandle hHal, tANI_U8 *pIes, tANI_U32 len,
                             tANI_U8 *pWpaIe, tANI_U8 *pcbWpaIe, tANI_U8 *pRSNIe, tANI_U8 *pcbRSNIe)
{
    tDot11IEHeader *pIEHeader;
    tSirMacPropIE *pSirMacPropIE;
    tANI_U32 cbParsed;
    tANI_U32 cbIE;
    int cExpectedIEs = 0;
    int cFoundIEs = 0;
    int cbPropIETotal;

    pIEHeader = (tDot11IEHeader *)pIes;
    if(pWpaIe) cExpectedIEs++;
    if(pRSNIe) cExpectedIEs++;

    // bss description length includes all fields other than the length itself
    cbParsed  = 0;

    // Loop as long as there is data left in the IE of the Bss Description
    // and the number of Expected IEs is NOT found yet.
    while( ( (cbParsed + sizeof( *pIEHeader )) <= len ) && ( cFoundIEs < cExpectedIEs  ) )
    {
        cbIE = sizeof( *pIEHeader ) + pIEHeader->Length;

        if ( ( cbIE + cbParsed ) > len ) break;

        if ( ( pIEHeader->Length >= gCsrIELengthTable[ pIEHeader->ElementID ].min ) &&
             ( pIEHeader->Length <= gCsrIELengthTable[ pIEHeader->ElementID ].max ) )
        {
            switch( pIEHeader->ElementID )
            {
                // Parse the 221 (0xdd) Proprietary IEs here...
                // Note that the 221 IE is overloaded, containing the WPA IE, WMM/WME IE, and the
                // Airgo proprietary IE information.
                case SIR_MAC_WPA_EID:
                {
                    tANI_U32 aniOUI;
                    tANI_U8 *pOui = (tANI_U8 *)&aniOUI;

                    pOui++;
                    aniOUI = ANI_OUI;
                    aniOUI = i_ntohl( aniOUI );

                    pSirMacPropIE = ( tSirMacPropIE *)pIEHeader;
                    cbPropIETotal = pSirMacPropIE->length;

                    // Validate the ANI OUI is in the OUI field in the proprietary IE...
                    if ( ( pSirMacPropIE->length >= WNI_CFG_MANUFACTURER_OUI_LEN ) &&
                          pOui[ 0 ] == pSirMacPropIE->oui[ 0 ] &&
                          pOui[ 1 ] == pSirMacPropIE->oui[ 1 ] &&
                          pOui[ 2 ] == pSirMacPropIE->oui[ 2 ]  )
                    {
                    }
                    else
                    {
                        tCsrWpaIe     *pIe        = ( tCsrWpaIe *    )pIEHeader;

                        if(!pWpaIe || !pcbWpaIe) break;
                        // Check if this is a valid WPA IE.  Then check that the
                        // WPA OUI is in place and the version is one that we support.
                        if ( ( pIe->IeHeader.Length >= SIR_MAC_WPA_IE_MIN_LENGTH )   &&
                             ( vos_mem_compare( pIe->Oui, (void *)csrWpaOui[1],
                                                sizeof( pIe->Oui ) ) ) &&
                             ( pIe->Version <= CSR_WPA_VERSION_SUPPORTED ) )
                        {
                            vos_mem_copy(pWpaIe, pIe,
                                  pIe->IeHeader.Length + sizeof( pIe->IeHeader ));
                            *pcbWpaIe = pIe->IeHeader.Length + sizeof( pIe->IeHeader );
                            cFoundIEs++;

                            break;
                        }
                    }

                    break;
                }

                case SIR_MAC_RSN_EID:
                {
                    tCsrRSNIe *pIe;

                    if(!pcbRSNIe || !pRSNIe) break;
                    pIe = (tCsrRSNIe *)pIEHeader;

                    // Check the length of the RSN Ie to assure it is valid.  Then check that the
                    // version is one that we support.

                    if ( pIe->IeHeader.Length < SIR_MAC_RSN_IE_MIN_LENGTH ) break;
                    if ( pIe->Version > CSR_RSN_VERSION_SUPPORTED ) break;

                    cFoundIEs++;

                    // if there is enough room in the WpaIE passed in, then copy the Wpa IE into
                    // the buffer passed in.
                    if ( *pcbRSNIe < pIe->IeHeader.Length + sizeof( pIe->IeHeader ) ) break;
                    vos_mem_copy(pRSNIe, pIe,
                                 pIe->IeHeader.Length + sizeof( pIe->IeHeader ));
                    *pcbRSNIe = pIe->IeHeader.Length + sizeof( pIe->IeHeader );

                    break;
                }

                // Add support for other IE here...
                default:
                    break;
            }
        }

        cbParsed += cbIE;

        pIEHeader = (tDot11IEHeader *)( ((tANI_U8 *)pIEHeader) + cbIE );

    }

    // return a BOOL that tells if all of the IEs asked for were found...
    return( cFoundIEs == cExpectedIEs );
}


/*
 * If a WPAIE exists in the profile, just use it. Or else construct one from
 * the BSS Caller allocated memory for pWpaIe and guarantee it can contain a max
 * length WPA IE
 */
tANI_U8 csrRetrieveWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc,
                          tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_U8 cbWpaIe = 0;

    do
    {
        if ( !csrIsProfileWpa( pProfile ) ) break;
        if(pProfile->nWPAReqIELength && pProfile->pWPAReqIE)
        {
            if(SIR_MAC_WPA_IE_MAX_LENGTH >= pProfile->nWPAReqIELength)
            {
                cbWpaIe = (tANI_U8)pProfile->nWPAReqIELength;
                vos_mem_copy(pWpaIe, pProfile->pWPAReqIE, cbWpaIe);
            }
            else
            {
                smsLog(pMac, LOGW, "  csrRetrieveWpaIe detect invalid WPA IE length (%d) ", pProfile->nWPAReqIELength);
            }
        }
        else
        {
            cbWpaIe = csrConstructWpaIe(pMac, pProfile, pSirBssDesc, pIes, pWpaIe);
        }
    }while(0);

    return (cbWpaIe);
}


/*
 * If a RSNIE exists in the profile, just use it. Or else construct one from the
 * BSS. Caller allocated memory for pWpaIe and guarantee it can contain a max
 * length WPA IE
 */
tANI_U8 csrRetrieveRsnIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile,
                         tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_U8 cbRsnIe = 0;

    do
    {
        if ( !csrIsProfileRSN( pProfile ) ) break;
#ifdef FEATURE_WLAN_LFR
        if (csrRoamIsFastRoamEnabled(pMac, sessionId))
        {
            // If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from
            // scratch. So it contains the current PMK-IDs
            cbRsnIe = csrConstructRSNIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pRsnIe);
        }
        else
#endif
        if(pProfile->nRSNReqIELength && pProfile->pRSNReqIE)
        {
            // If you have one started away, re-use it.
            if(SIR_MAC_WPA_IE_MAX_LENGTH >= pProfile->nRSNReqIELength)
            {
                cbRsnIe = (tANI_U8)pProfile->nRSNReqIELength;
                vos_mem_copy(pRsnIe, pProfile->pRSNReqIE, cbRsnIe);
            }
            else
            {
                smsLog(pMac, LOGW, "  csrRetrieveRsnIe detect invalid RSN IE length (%d) ", pProfile->nRSNReqIELength);
            }
        }
        else
        {
            cbRsnIe = csrConstructRSNIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pRsnIe);
        }
    }while(0);

    return (cbRsnIe);
}


#ifdef FEATURE_WLAN_WAPI
/*
 * If a WAPI IE exists in the profile, just use it. Or else construct one from
 * the BSS. Caller allocated memory for pWapiIe and guarantee it can contain a
 * max length WAPI IE.
 */
tANI_U8 csrRetrieveWapiIe( tHalHandle hHal, tANI_U32 sessionId,
                          tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc,
                          tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_U8 cbWapiIe = 0;

    do
    {
        if ( !csrIsProfileWapi( pProfile ) ) break;
        if(pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE)
        {
            if(DOT11F_IE_WAPI_MAX_LEN >= pProfile->nWAPIReqIELength)
            {
                cbWapiIe = (tANI_U8)pProfile->nWAPIReqIELength;
                vos_mem_copy(pWapiIe, pProfile->pWAPIReqIE, cbWapiIe);
            }
            else
            {
                smsLog(pMac, LOGW, "  csrRetrieveWapiIe detect invalid WAPI IE length (%d) ", pProfile->nWAPIReqIELength);
            }
        }
        else
        {
            cbWapiIe = csrConstructWapiIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pWapiIe);
        }
    }while(0);

    return (cbWapiIe);
}
#endif /* FEATURE_WLAN_WAPI */

tANI_BOOLEAN csrSearchChannelListForTxPower(tHalHandle hHal, tSirBssDescription *pBssDescription, tCsrChannelSet *returnChannelGroup)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tListElem *pEntry;
    tANI_U16 i;
    tANI_U16 startingChannel;
    tANI_BOOLEAN found = FALSE;
    tCsrChannelSet *pChannelGroup;

    pEntry = csrLLPeekHead( &pMac->roam.channelList5G, LL_ACCESS_LOCK );

    while ( pEntry )
    {
        pChannelGroup = GET_BASE_ADDR( pEntry, tCsrChannelSet, channelListLink );
        startingChannel = pChannelGroup->firstChannel;
        for ( i = 0; i < pChannelGroup->numChannels; i++ )
        {
            if ( startingChannel + i * pChannelGroup->interChannelOffset == pBssDescription->channelId )
            {
                found = TRUE;
                break;
            }
        }

        if ( found )
        {
            vos_mem_copy(returnChannelGroup, pChannelGroup, sizeof(tCsrChannelSet));
            break;
        }
        else
        {
            pEntry = csrLLNext( &pMac->roam.channelList5G, pEntry, LL_ACCESS_LOCK );
        }
    }

    return( found );
}

tANI_BOOLEAN csrRatesIsDot11Rate11bSupportedRate( tANI_U8 dot11Rate )
{
    tANI_BOOLEAN fSupported = FALSE;
    tANI_U16 nonBasicRate = (tANI_U16)( BITS_OFF( dot11Rate, CSR_DOT11_BASIC_RATE_MASK ) );

    switch ( nonBasicRate )
    {
        case eCsrSuppRate_1Mbps:
        case eCsrSuppRate_2Mbps:
        case eCsrSuppRate_5_5Mbps:
        case eCsrSuppRate_11Mbps:
            fSupported = TRUE;
            break;

        default:
            break;
    }

    return( fSupported );
}

tANI_BOOLEAN csrRatesIsDot11Rate11aSupportedRate( tANI_U8 dot11Rate )
{
    tANI_BOOLEAN fSupported = FALSE;
    tANI_U16 nonBasicRate = (tANI_U16)( BITS_OFF( dot11Rate, CSR_DOT11_BASIC_RATE_MASK ) );

    switch ( nonBasicRate )
    {
        case eCsrSuppRate_6Mbps:
        case eCsrSuppRate_9Mbps:
        case eCsrSuppRate_12Mbps:
        case eCsrSuppRate_18Mbps:
        case eCsrSuppRate_24Mbps:
        case eCsrSuppRate_36Mbps:
        case eCsrSuppRate_48Mbps:
        case eCsrSuppRate_54Mbps:
            fSupported = TRUE;
            break;

        default:
            break;
    }

    return( fSupported );
}



tAniEdType csrTranslateEncryptTypeToEdType( eCsrEncryptionType EncryptType )
{
    tAniEdType edType;

    switch ( EncryptType )
    {
        default:
        case eCSR_ENCRYPT_TYPE_NONE:
            edType = eSIR_ED_NONE;
            break;

        case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
        case eCSR_ENCRYPT_TYPE_WEP40:
            edType = eSIR_ED_WEP40;
            break;

        case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
        case eCSR_ENCRYPT_TYPE_WEP104:
            edType = eSIR_ED_WEP104;
            break;

        case eCSR_ENCRYPT_TYPE_TKIP:
            edType = eSIR_ED_TKIP;
            break;

        case eCSR_ENCRYPT_TYPE_AES:
            edType = eSIR_ED_CCMP;
            break;
#ifdef FEATURE_WLAN_WAPI
        case eCSR_ENCRYPT_TYPE_WPI:
            edType = eSIR_ED_WPI;
            break ;
#endif
#ifdef WLAN_FEATURE_11W
        //11w BIP
        case eCSR_ENCRYPT_TYPE_AES_CMAC:
            edType = eSIR_ED_AES_128_CMAC;
            break;
#endif
    }

    return( edType );
}


//pIes can be NULL
tANI_BOOLEAN csrValidateWep( tpAniSirGlobal pMac, eCsrEncryptionType ucEncryptionType,
                             tCsrAuthList *pAuthList, tCsrEncryptionList *pMCEncryptionList,
                             eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCEncryption,
                             tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes )
{
    tANI_U32 idx;
    tANI_BOOLEAN fMatch = FALSE;
    eCsrAuthType negotiatedAuth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
    eCsrEncryptionType negotiatedMCCipher = eCSR_ENCRYPT_TYPE_UNKNOWN;

    //This function just checks whether HDD is giving correct values for Multicast cipher and Auth.

    do
    {
        //If privacy bit is not set, consider no match
        if ( !csrIsPrivacy( pSirBssDesc ) ) break;

        for( idx = 0; idx < pMCEncryptionList->numEntries; idx++ )
        {
            switch( pMCEncryptionList->encryptionType[idx] )
            {
                case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
                case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
                case eCSR_ENCRYPT_TYPE_WEP40:
                case eCSR_ENCRYPT_TYPE_WEP104:
                    /* Multicast list may contain WEP40/WEP104. Check whether it matches UC.
                    */
                    if( ucEncryptionType == pMCEncryptionList->encryptionType[idx] )
                    {
                        fMatch = TRUE;
                        negotiatedMCCipher = pMCEncryptionList->encryptionType[idx];
                    }
                    break;
                default:
                    fMatch = FALSE;
                    break;
            }
            if(fMatch) break;
        }

        if(!fMatch) break;

        for( idx = 0; idx < pAuthList->numEntries; idx++ )
        {
            switch( pAuthList->authType[idx] )
            {
                case eCSR_AUTH_TYPE_OPEN_SYSTEM:
                case eCSR_AUTH_TYPE_SHARED_KEY:
                case eCSR_AUTH_TYPE_AUTOSWITCH:
                    fMatch = TRUE;
                    negotiatedAuth = pAuthList->authType[idx];
                    break;
                default:
                    fMatch = FALSE;
            }
            if (fMatch) break;
        }

        if(!fMatch) break;
        //In case of WPA / WPA2, check whether it supports WEP as well
        if(pIes)
        {
            //Prepare the encryption type for WPA/WPA2 functions
            if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == ucEncryptionType )
            {
                ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40;
            }
            else if( eCSR_ENCRYPT_TYPE_WEP104 == ucEncryptionType )
            {
                ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104;
            }
            //else we can use the encryption type directly
            if ( pIes->WPA.present )
            {
                fMatch = vos_mem_compare(pIes->WPA.multicast_cipher,
                                         csrWpaOui[csrGetOUIIndexFromCipher( ucEncryptionType )],
                                         CSR_WPA_OUI_SIZE);
                if( fMatch ) break;
            }
            if ( pIes->RSN.present )
            {
                fMatch = vos_mem_compare(pIes->RSN.gp_cipher_suite,
                                         csrRSNOui[csrGetOUIIndexFromCipher( ucEncryptionType )],
                                         CSR_RSN_OUI_SIZE);
            }
        }

    }while(0);

    if( fMatch )
    {
        if( pNegotiatedAuthType )
            *pNegotiatedAuthType = negotiatedAuth;

        if( pNegotiatedMCEncryption )
            *pNegotiatedMCEncryption = negotiatedMCCipher;
    }


    return fMatch;
}


//pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs
tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType,
                                 tCsrEncryptionList *pUCEncryptionType,
                                 tCsrEncryptionList *pMCEncryptionType,
                                 tANI_BOOLEAN *pMFPEnabled,
                                 tANI_U8 *pMFPRequired, tANI_U8 *pMFPCapable,
                                 tSirBssDescription *pSirBssDesc,
                                 tDot11fBeaconIEs *pIes,
                                 eCsrAuthType *negotiatedAuthtype,
                                 eCsrEncryptionType *negotiatedUCCipher,
                                 eCsrEncryptionType *negotiatedMCCipher )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fMatch = FALSE;
    tANI_U8 i,idx;
    eCsrEncryptionType mcCipher = eCSR_ENCRYPT_TYPE_UNKNOWN, ucCipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
    eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;

    for( i = 0 ; ((i < pUCEncryptionType->numEntries) && (!fMatch)) ; i++ )
    {
        ucCipher = pUCEncryptionType->encryptionType[i];
        // If the Bss description shows the Privacy bit is on, then we must have some sort of encryption configured
        // for the profile to work.  Don't attempt to join networks with Privacy bit set when profiles say NONE for
        // encryption type.
        switch ( ucCipher )
        {
            case eCSR_ENCRYPT_TYPE_NONE:
                {
                    // for NO encryption, if the Bss description has the Privacy bit turned on, then encryption is
                    // required so we have to reject this Bss.
                    if ( csrIsPrivacy( pSirBssDesc ) )
                    {
                        fMatch = FALSE;
                    }
                    else
                    {
                        fMatch = TRUE;
                    }

                    if ( fMatch )
                    {
                        fMatch = FALSE;
                        //Check Multicast cipher requested and Auth type requested.
                        for( idx = 0 ; idx < pMCEncryptionType->numEntries ; idx++ )
                        {
                            if( eCSR_ENCRYPT_TYPE_NONE == pMCEncryptionType->encryptionType[idx] )
                            {
                                fMatch = TRUE; //Multicast can only be none.
                                mcCipher = pMCEncryptionType->encryptionType[idx];
                                break;
                            }
                        }
                        if (!fMatch) break;

                        fMatch = FALSE;
                        //Check Auth list. It should contain AuthOpen.
                        for( idx = 0 ; idx < authType->numEntries ; idx++ )
                        {
                            if(( eCSR_AUTH_TYPE_OPEN_SYSTEM == authType->authType[idx] ) ||
                               ( eCSR_AUTH_TYPE_AUTOSWITCH == authType->authType[idx] ))
                            {
                               fMatch = TRUE;
                               negAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
                               break;
                            }
                        }
                        if (!fMatch) break;

                    }
                    break;
                }

            case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
            case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
                // !! might want to check for WEP keys set in the Profile.... ?
                // !! don't need to have the privacy bit in the Bss description.  Many AP policies make legacy
                // encryption 'optional' so we don't know if we can associate or not.  The AP will reject if
                // encryption is not allowed without the Privacy bit turned on.
                fMatch = csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes);

                break;

                // these are all of the WPA encryption types...
            case eCSR_ENCRYPT_TYPE_WEP40:
            case eCSR_ENCRYPT_TYPE_WEP104:
                fMatch = csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes);
                break;

            case eCSR_ENCRYPT_TYPE_TKIP:
            case eCSR_ENCRYPT_TYPE_AES:
                {
                    if(pIes)
                    {
                        // First check if there is a RSN match
                        fMatch = csrIsRSNMatch( pMac, authType, ucCipher,
                                                pMCEncryptionType, pMFPEnabled,
                                                pMFPRequired, pMFPCapable,
                                                pIes, &negAuthType, &mcCipher );
                        if( !fMatch )
                        {
                            // If not RSN, then check if there is a WPA match
                            fMatch = csrIsWpaEncryptionMatch( pMac, authType, ucCipher, pMCEncryptionType, pIes,
                                                              &negAuthType, &mcCipher );
                        }
                    }
                    else
                    {
                        fMatch = FALSE;
                    }
                    break;
                }
#ifdef FEATURE_WLAN_WAPI
           case eCSR_ENCRYPT_TYPE_WPI://WAPI
               {
                   if(pIes)
                   {
                       fMatch = csrIsWapiMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher );
                   }
                   else
                   {
                       fMatch = FALSE;
                   }
                   break;
               }
#endif /* FEATURE_WLAN_WAPI */
            case eCSR_ENCRYPT_TYPE_ANY:
            default:
            {
                tANI_BOOLEAN fMatchAny = eANI_BOOLEAN_FALSE;

                fMatch = eANI_BOOLEAN_TRUE;
                //It is allowed to match anything. Try the more secured ones first.
                if(pIes)
                {
                    //Check AES first
                    ucCipher = eCSR_ENCRYPT_TYPE_AES;
                    fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher,
                                               pMCEncryptionType, pMFPEnabled,
                                               pMFPRequired, pMFPCapable, pIes,
                                               &negAuthType, &mcCipher );
                    if(!fMatchAny)
                    {
                        //Check TKIP
                        ucCipher = eCSR_ENCRYPT_TYPE_TKIP;
                        fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher,
                                                   pMCEncryptionType,
                                                   pMFPEnabled, pMFPRequired,
                                                   pMFPCapable, pIes,
                                                   &negAuthType, &mcCipher );
                    }
#ifdef FEATURE_WLAN_WAPI
                    if(!fMatchAny)
                    {
                        //Check WAPI
                        ucCipher = eCSR_ENCRYPT_TYPE_WPI;
                        fMatchAny = csrIsWapiMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher );
                    }
#endif /* FEATURE_WLAN_WAPI */
                }
                if(!fMatchAny)
                {
                    ucCipher = eCSR_ENCRYPT_TYPE_WEP104;
                    if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes))
                    {
                        ucCipher = eCSR_ENCRYPT_TYPE_WEP40;
                        if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes))
                        {
                            ucCipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
                            if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes))
                            {
                                ucCipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
                                if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes))
                                {
                                    //It must be open and no encryption
                                    if ( csrIsPrivacy( pSirBssDesc ) )
                                    {
                                        //This is not right
                                        fMatch = eANI_BOOLEAN_FALSE;
                                    }
                                    else
                                    {
                                        negAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
                                        mcCipher = eCSR_ENCRYPT_TYPE_NONE;
                                        ucCipher = eCSR_ENCRYPT_TYPE_NONE;
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            }
        }

    }

    if( fMatch )
    {
        if( negotiatedUCCipher )
            *negotiatedUCCipher = ucCipher;

        if( negotiatedMCCipher )
            *negotiatedMCCipher = mcCipher;

        if( negotiatedAuthtype )
            *negotiatedAuthtype = negAuthType;
    }

    return( fMatch );
}


tANI_BOOLEAN csrIsSsidMatch( tpAniSirGlobal pMac, tANI_U8 *ssid1, tANI_U8 ssid1Len, tANI_U8 *bssSsid,
                            tANI_U8 bssSsidLen, tANI_BOOLEAN fSsidRequired )
{
    tANI_BOOLEAN fMatch = FALSE;

    do {
        /*
         * Check for the specification of the Broadcast SSID at the beginning
         * of the list. If specified, then all SSIDs are matches
         * (broadcast SSID means accept all SSIDs).
         */
        if ( ssid1Len == 0 )
        {
            fMatch = TRUE;
            break;
        }

        /*
         * There are a few special cases. If the Bss description has a
         * Broadcast SSID, then our Profile must have a single SSID without
         * Wild cards so we can program the SSID.
         * SSID could be suppressed in beacons. In that case SSID IE has valid
         * length but the SSID value is all NULL characters.
         * That condition is treated same as NULL SSID.
         */
        if ( csrIsNULLSSID( bssSsid, bssSsidLen ) )
        {
            if ( eANI_BOOLEAN_FALSE == fSsidRequired )
            {
                fMatch = TRUE;
                break;
            }
        }

        if(ssid1Len != bssSsidLen) break;
        if (vos_mem_compare(bssSsid, ssid1, bssSsidLen))
        {
            fMatch = TRUE;
            break;
        }

    } while( 0 );

    return( fMatch );
}


//Null ssid means match
tANI_BOOLEAN csrIsSsidInList( tHalHandle hHal, tSirMacSSid *pSsid, tCsrSSIDs *pSsidList )
{
    tANI_BOOLEAN fMatch = FALSE;
    tANI_U32 i;

    if ( pSsidList && pSsid )
    {
        for(i = 0; i < pSsidList->numOfSSIDs; i++)
        {
            if(csrIsNULLSSID(pSsidList->SSIDList[i].SSID.ssId, pSsidList->SSIDList[i].SSID.length) ||
              ((pSsidList->SSIDList[i].SSID.length == pSsid->length) &&
               vos_mem_compare(pSsid->ssId, pSsidList->SSIDList[i].SSID.ssId, pSsid->length)))
            {
                fMatch = TRUE;
                break;
            }
        }
    }

    return (fMatch);
}

//like to use sirCompareMacAddr
tANI_BOOLEAN csrIsMacAddressZero( tpAniSirGlobal pMac, tCsrBssid *pMacAddr )
{
    tANI_U8 bssid[VOS_MAC_ADDR_SIZE] = {0, 0, 0, 0, 0, 0};

    return (vos_mem_compare(bssid, pMacAddr, VOS_MAC_ADDR_SIZE));
}

//like to use sirCompareMacAddr
tANI_BOOLEAN csrIsMacAddressBroadcast( tpAniSirGlobal pMac, tCsrBssid *pMacAddr )
{
    tANI_U8 bssid[VOS_MAC_ADDR_SIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

    return(vos_mem_compare(bssid, pMacAddr, VOS_MAC_ADDR_SIZE));
}


//like to use sirCompareMacAddr
tANI_BOOLEAN csrIsMacAddressEqual( tpAniSirGlobal pMac, tCsrBssid *pMacAddr1, tCsrBssid *pMacAddr2 )
{
    return(vos_mem_compare(pMacAddr1, pMacAddr2, sizeof(tCsrBssid)));
}


tANI_BOOLEAN csrIsBssidMatch( tHalHandle hHal, tCsrBssid *pProfBssid, tCsrBssid *BssBssid )
{
    tANI_BOOLEAN fMatch = FALSE;
    tCsrBssid ProfileBssid;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    // for efficiency of the MAC_ADDRESS functions, move the
    // Bssid's into MAC_ADDRESS structs.
    vos_mem_copy(&ProfileBssid, pProfBssid, sizeof(tCsrBssid));

    do {

        // Give the profile the benefit of the doubt... accept either all 0 or
        // the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to
        // match any Bssids).
        if ( csrIsMacAddressZero( pMac, &ProfileBssid ) ||
             csrIsMacAddressBroadcast( pMac, &ProfileBssid ) )
        {
             fMatch = TRUE;
             break;
        }

        if ( csrIsMacAddressEqual( pMac, BssBssid, &ProfileBssid ) )
        {
            fMatch = TRUE;
            break;
        }

    } while( 0 );

    return( fMatch );
}


tANI_BOOLEAN csrIsBSSTypeMatch(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2)
{
    if((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2) && (bssType1 != bssType2))
        return eANI_BOOLEAN_FALSE;
    else
        return eANI_BOOLEAN_TRUE;
}


tANI_BOOLEAN csrIsBssTypeIBSS(eCsrRoamBssType bssType)
{
    return((tANI_BOOLEAN)(eCSR_BSS_TYPE_START_IBSS == bssType || eCSR_BSS_TYPE_IBSS == bssType));
}

tANI_BOOLEAN csrIsBssTypeWDS(eCsrRoamBssType bssType)
{
    return((tANI_BOOLEAN)(eCSR_BSS_TYPE_WDS_STA == bssType || eCSR_BSS_TYPE_WDS_AP == bssType));
}

tANI_BOOLEAN csrIsBSSTypeCapsMatch( eCsrRoamBssType bssType, tSirBssDescription *pSirBssDesc )
{
    tANI_BOOLEAN fMatch = TRUE;

    do
    {
        switch( bssType )
        {
            case eCSR_BSS_TYPE_ANY:
                break;

            case eCSR_BSS_TYPE_INFRASTRUCTURE:
            case eCSR_BSS_TYPE_WDS_STA:
                if( !csrIsInfraBssDesc( pSirBssDesc ) )
                    fMatch = FALSE;

                break;

            case eCSR_BSS_TYPE_IBSS:
            case eCSR_BSS_TYPE_START_IBSS:
                if( !csrIsIbssBssDesc( pSirBssDesc ) )
                    fMatch = FALSE;

                break;

            case eCSR_BSS_TYPE_WDS_AP: //For WDS AP, no need to match anything
            default:
                fMatch = FALSE;
                break;
        }
    }
    while( 0 );


    return( fMatch );
}

static tANI_BOOLEAN csrIsCapabilitiesMatch( tpAniSirGlobal pMac, eCsrRoamBssType bssType, tSirBssDescription *pSirBssDesc )
{
  return( csrIsBSSTypeCapsMatch( bssType, pSirBssDesc ) );
}



static tANI_BOOLEAN csrIsSpecificChannelMatch( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tANI_U8 Channel )
{
    tANI_BOOLEAN fMatch = TRUE;

    do
    {
        // if the channel is ANY, then always match...
        if ( eCSR_OPERATING_CHANNEL_ANY == Channel ) break;
        if ( Channel == pSirBssDesc->channelId ) break;

        // didn't match anything.. so return NO match
        fMatch = FALSE;

    } while( 0 );

    return( fMatch );
}


tANI_BOOLEAN csrIsChannelBandMatch( tpAniSirGlobal pMac, tANI_U8 channelId, tSirBssDescription *pSirBssDesc )
{
    tANI_BOOLEAN fMatch = TRUE;

    do
    {
        // if the profile says Any channel AND the global settings says ANY channel, then we
        // always match...
        if ( eCSR_OPERATING_CHANNEL_ANY == channelId ) break;

        if ( eCSR_OPERATING_CHANNEL_ANY != channelId )
        {
            fMatch = csrIsSpecificChannelMatch( pMac, pSirBssDesc, channelId );
        }

    } while( 0 );

    return( fMatch );
}


/**
 * \brief Enquire as to whether a given rate is supported by the
 * adapter as currently configured
 *
 *
 * \param nRate A rate in units of 500kbps
 *
 * \return TRUE if  the adapter is currently capable  of supporting this
 * rate, FALSE else
 *
 *
 * The rate encoding  is just as in 802.11  Information Elements, except
 * that the high bit is \em  not interpreted as indicating a Basic Rate,
 * and proprietary rates are allowed, too.
 *
 * Note  that if the  adapter's dot11Mode  is g,  we don't  restrict the
 * rates.  According to hwReadEepromParameters, this will happen when:
 *
 *   ... the  card is  configured for ALL  bands through  the property
 *   page.  If this occurs, and the card is not an ABG card ,then this
 *   code  is  setting the  dot11Mode  to  assume  the mode  that  the
 *   hardware can support.   For example, if the card  is an 11BG card
 *   and we  are configured to support  ALL bands, then  we change the
 *   dot11Mode  to 11g  because  ALL in  this  case is  only what  the
 *   hardware can support.
 *
 *
 */

static tANI_BOOLEAN csrIsAggregateRateSupported( tpAniSirGlobal pMac, tANI_U16 rate )
{
    tANI_BOOLEAN fSupported = eANI_BOOLEAN_FALSE;
    tANI_U16 idx, newRate;

    //In case basic rate flag is set
    newRate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
    if ( eCSR_CFG_DOT11_MODE_11A == pMac->roam.configParam.uCfgDot11Mode )
    {
        switch ( newRate )
        {
        case eCsrSuppRate_6Mbps:
        case eCsrSuppRate_9Mbps:
        case eCsrSuppRate_12Mbps:
        case eCsrSuppRate_18Mbps:
        case eCsrSuppRate_24Mbps:
        case eCsrSuppRate_36Mbps:
        case eCsrSuppRate_48Mbps:
        case eCsrSuppRate_54Mbps:
            fSupported = TRUE;
            break;
        default:
            fSupported = FALSE;
            break;
        }

    }
    else if( eCSR_CFG_DOT11_MODE_11B == pMac->roam.configParam.uCfgDot11Mode )
    {
        switch ( newRate )
        {
        case eCsrSuppRate_1Mbps:
        case eCsrSuppRate_2Mbps:
        case eCsrSuppRate_5_5Mbps:
        case eCsrSuppRate_11Mbps:
            fSupported = TRUE;
            break;
        default:
            fSupported = FALSE;
            break;
        }
    }
    else if ( !pMac->roam.configParam.ProprietaryRatesEnabled )
    {

        switch ( newRate )
        {
        case eCsrSuppRate_1Mbps:
        case eCsrSuppRate_2Mbps:
        case eCsrSuppRate_5_5Mbps:
        case eCsrSuppRate_6Mbps:
        case eCsrSuppRate_9Mbps:
        case eCsrSuppRate_11Mbps:
        case eCsrSuppRate_12Mbps:
        case eCsrSuppRate_18Mbps:
        case eCsrSuppRate_24Mbps:
        case eCsrSuppRate_36Mbps:
        case eCsrSuppRate_48Mbps:
        case eCsrSuppRate_54Mbps:
            fSupported = TRUE;
            break;
        default:
            fSupported = FALSE;
            break;
        }

    }
    else {

        if ( eCsrSuppRate_1Mbps   == newRate ||
             eCsrSuppRate_2Mbps   == newRate ||
             eCsrSuppRate_5_5Mbps == newRate ||
             eCsrSuppRate_11Mbps  == newRate )
        {
            fSupported = TRUE;
        }
        else {
            idx = 0x1;

            switch ( newRate )
            {
            case eCsrSuppRate_6Mbps:
                fSupported = gPhyRatesSuppt[0][idx];
                break;
            case eCsrSuppRate_9Mbps:
                fSupported = gPhyRatesSuppt[1][idx];
                break;
            case eCsrSuppRate_12Mbps:
                fSupported = gPhyRatesSuppt[2][idx];
                break;
            case eCsrSuppRate_18Mbps:
                fSupported = gPhyRatesSuppt[3][idx];
                break;
            case eCsrSuppRate_20Mbps:
                fSupported = gPhyRatesSuppt[4][idx];
                break;
            case eCsrSuppRate_24Mbps:
                fSupported = gPhyRatesSuppt[5][idx];
                break;
            case eCsrSuppRate_36Mbps:
                fSupported = gPhyRatesSuppt[6][idx];
                break;
            case eCsrSuppRate_40Mbps:
                fSupported = gPhyRatesSuppt[7][idx];
                break;
            case eCsrSuppRate_42Mbps:
                fSupported = gPhyRatesSuppt[8][idx];
                break;
            case eCsrSuppRate_48Mbps:
                fSupported = gPhyRatesSuppt[9][idx];
                break;
            case eCsrSuppRate_54Mbps:
                fSupported = gPhyRatesSuppt[10][idx];
                break;
            case eCsrSuppRate_72Mbps:
                fSupported = gPhyRatesSuppt[11][idx];
                break;
            case eCsrSuppRate_80Mbps:
                fSupported = gPhyRatesSuppt[12][idx];
                break;
            case eCsrSuppRate_84Mbps:
                fSupported = gPhyRatesSuppt[13][idx];
                break;
            case eCsrSuppRate_96Mbps:
                fSupported = gPhyRatesSuppt[14][idx];
                break;
            case eCsrSuppRate_108Mbps:
                fSupported = gPhyRatesSuppt[15][idx];
                break;
            case eCsrSuppRate_120Mbps:
                fSupported = gPhyRatesSuppt[16][idx];
                break;
            case eCsrSuppRate_126Mbps:
                fSupported = gPhyRatesSuppt[17][idx];
                break;
            case eCsrSuppRate_144Mbps:
                fSupported = gPhyRatesSuppt[18][idx];
                break;
            case eCsrSuppRate_160Mbps:
                fSupported = gPhyRatesSuppt[19][idx];
                break;
            case eCsrSuppRate_168Mbps:
                fSupported = gPhyRatesSuppt[20][idx];
                break;
            case eCsrSuppRate_192Mbps:
                fSupported = gPhyRatesSuppt[21][idx];
                break;
            case eCsrSuppRate_216Mbps:
                fSupported = gPhyRatesSuppt[22][idx];
                break;
            case eCsrSuppRate_240Mbps:
                fSupported = gPhyRatesSuppt[23][idx];
                break;
            default:
                fSupported = FALSE;
                break;
            }
        }
    }

    return fSupported;
}



static tANI_BOOLEAN csrIsRateSetMatch( tpAniSirGlobal pMac,
                                     tDot11fIESuppRates *pBssSuppRates,
                                     tDot11fIEExtSuppRates *pBssExtSuppRates )
{
    tANI_BOOLEAN fMatch = TRUE;
    tANI_U32 i;


    // Validate that all of the Basic rates advertised in the Bss description are supported.
    if ( pBssSuppRates )
    {
        for( i = 0; i < pBssSuppRates->num_rates; i++ )
        {
            if ( CSR_IS_BASIC_RATE( pBssSuppRates->rates[ i ] ) )
            {
                if ( !csrIsAggregateRateSupported( pMac, pBssSuppRates->rates[ i ] ) )
                {
                    fMatch = FALSE;
                    break;
                }
            }
        }
    }

    if ( fMatch && pBssExtSuppRates )
    {
        for( i = 0; i < pBssExtSuppRates->num_rates; i++ )
        {
            if ( CSR_IS_BASIC_RATE( pBssExtSuppRates->rates[ i ] ) )
            {
                if ( !csrIsAggregateRateSupported( pMac, pBssExtSuppRates->rates[ i ] ) )
                {
                    fMatch = FALSE;
                    break;
                }
            }
        }
    }

    return( fMatch );

}

#ifdef WLAN_FEATURE_FILS_SK
/*
 * csr_is_fils_realm_match: API to check whether realm in scan filter is
 * matching with realm in bss info
 * @bss_descr: bss description
 * @filter: scan filter
 *
 * Return: true if success else false
 */
static bool csr_is_fils_realm_match(tSirBssDescription *bss_descr,
                        tCsrScanResultFilter *filter)
{
    int i;
    bool is_match = true;

    if (filter->realm_check) {
        is_match = false;
        for (i = 0; i < bss_descr->fils_info_element.realm_cnt; i++) {
            if (!adf_os_mem_cmp(filter->fils_realm,
                    bss_descr->fils_info_element.realm[i],
                    SIR_REALM_LEN)) {
                    return true;
            }
        }
    }
    return is_match;
}
#else
static bool csr_is_fils_realm_match(tSirBssDescription *bss_descr,
                                    tCsrScanResultFilter *filter)
{
    return true;
}
#endif

//ppIes can be NULL. If caller want to get the *ppIes allocated by this function, pass in *ppIes = NULL
tANI_BOOLEAN csrMatchBSS( tHalHandle hHal, tSirBssDescription *pBssDesc, tCsrScanResultFilter *pFilter,
                          eCsrAuthType *pNegAuth, eCsrEncryptionType *pNegUc, eCsrEncryptionType *pNegMc,
                          tDot11fBeaconIEs **ppIes)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fRC = eANI_BOOLEAN_FALSE, fCheck, blacklist_check;
    tANI_U32 i;
    tDot11fBeaconIEs *pIes = NULL;
    tANI_U8 *pb;
    tCsrBssid *blacklist_bssid = NULL;
    struct roam_ext_params *roam_params;

    roam_params = &pMac->roam.configParam.roam_params;
    do {
        if( ( NULL == ppIes ) || ( *ppIes ) == NULL )
        {
            //If no IEs passed in, get our own.
            if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes)))
            {
                break;
            }
        }
        else
        {
            //Save the one pass in for local use
            pIes = *ppIes;
        }

        //Check if caller wants P2P
        fCheck = (!pFilter->p2pResult || pIes->P2PBeaconProbeRes.present);
        if(!fCheck) break;

        /* Check for Blacklist BSSID's and avoid connections */
        blacklist_check = false;
        blacklist_bssid = (tCsrBssid *)&roam_params->bssid_avoid_list;
        for (i = 0; i < roam_params->num_bssid_avoid_list; i++) {
          if (csrIsMacAddressEqual(pMac, blacklist_bssid,
               (tCsrBssid *)pBssDesc->bssId)) {
                 blacklist_check = true;
                 break;
          }
          blacklist_bssid++;
        }
        if(blacklist_check) {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
              "Do not Attempt connection to blacklist bssid");
            break;
        }

	if(pIes->SSID.present)
        {
            for(i = 0; i < pFilter->SSIDs.numOfSSIDs; i++)
            {
                fCheck = csrIsSsidMatch( pMac, pFilter->SSIDs.SSIDList[i].SSID.ssId, pFilter->SSIDs.SSIDList[i].SSID.length,
                                        pIes->SSID.ssid,
                                        pIes->SSID.num_ssid, eANI_BOOLEAN_TRUE );
                if ( fCheck ) break;
            }
            if(!fCheck) break;
        }
        fCheck = eANI_BOOLEAN_TRUE;
        for(i = 0; i < pFilter->BSSIDs.numOfBSSIDs; i++)
        {
            fCheck = csrIsBssidMatch( pMac, (tCsrBssid *)&pFilter->BSSIDs.bssid[i], (tCsrBssid *)pBssDesc->bssId );
            if ( fCheck ) break;

            if (pFilter->p2pResult && pIes->P2PBeaconProbeRes.present)
            {
               fCheck = csrIsBssidMatch( pMac, (tCsrBssid *)&pFilter->BSSIDs.bssid[i],
                              (tCsrBssid *)pIes->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress );

               if ( fCheck ) break;
            }
        }
        if(!fCheck) break;
        fCheck = eANI_BOOLEAN_TRUE;
        for(i = 0; i < pFilter->ChannelInfo.numOfChannels; i++)
        {
            fCheck = csrIsChannelBandMatch( pMac, pFilter->ChannelInfo.ChannelList[i], pBssDesc );
            if ( fCheck ) break;
        }
        if(!fCheck)
            break;
#if defined WLAN_FEATURE_VOWIFI
        /* If this is for measurement filtering */
        if( pFilter->fMeasurement )
        {
           fRC = eANI_BOOLEAN_TRUE;
           break;
        }
#endif
        if ( !csrIsPhyModeMatch( pMac, pFilter->phyMode, pBssDesc, NULL, NULL, pIes ) ) break;
        if ( (!pFilter->bWPSAssociation) && (!pFilter->bOSENAssociation) &&
#ifdef WLAN_FEATURE_11W
             !csrIsSecurityMatch( pMac, &pFilter->authType,
                                  &pFilter->EncryptionType,
                                  &pFilter->mcEncryptionType,
                                  &pFilter->MFPEnabled,
                                  &pFilter->MFPRequired,
                                  &pFilter->MFPCapable,
                                  pBssDesc, pIes, pNegAuth,
                                  pNegUc, pNegMc )
#else
             !csrIsSecurityMatch( pMac, &pFilter->authType,
                                  &pFilter->EncryptionType,
                                  &pFilter->mcEncryptionType,
                                  NULL, NULL, NULL,
                                  pBssDesc, pIes, pNegAuth,
                                  pNegUc, pNegMc )
#endif
                                                   ) break;
        if ( !csrIsCapabilitiesMatch( pMac, pFilter->BSSType, pBssDesc ) ) break;
        if ( !csrIsRateSetMatch( pMac, &pIes->SuppRates, &pIes->ExtSuppRates ) ) break;
        //Tush-QoS: validate first if asked for APSD or WMM association
        if ( (eCsrRoamWmmQbssOnly == pMac->roam.configParam.WMMSupportMode) &&
             !CSR_IS_QOS_BSS(pIes) )
             break;
        //Check country. check even when pb is NULL because we may want to make sure
        //AP has a country code in it if fEnforceCountryCodeMatch is set.
        pb = ( pFilter->countryCode[0] ) ? ( pFilter->countryCode) : NULL;

        fCheck = csrMatchCountryCode( pMac, pb, pIes );
        if(!fCheck)
            break;

#ifdef WLAN_FEATURE_VOWIFI_11R
        if (pFilter->MDID.mdiePresent &&
                 csrRoamIs11rAssoc(pMac, pMac->roam.roamSession->sessionId)) {
            if (pBssDesc->mdiePresent)
            {
                if (pFilter->MDID.mobilityDomain != (pBssDesc->mdie[1] << 8 | pBssDesc->mdie[0]))
                    break;
            }
            else
                break;
        }
#endif
        fRC = eANI_BOOLEAN_TRUE;
        if (fRC)
            fRC = csr_is_fils_realm_match(pBssDesc, pFilter);

    } while( 0 );
    if( ppIes )
    {
        *ppIes = pIes;
    }
    else if( pIes )
    {
        vos_mem_free(pIes);
    }

    return( fRC );
}

tANI_BOOLEAN csrMatchConnectedBSSSecurity( tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile,
                                           tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes)
{
    tCsrEncryptionList ucEncryptionList, mcEncryptionList;
    tCsrAuthList authList;

    ucEncryptionList.numEntries = 1;
    ucEncryptionList.encryptionType[0] = pProfile->EncryptionType;

    mcEncryptionList.numEntries = 1;
    mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType;

    authList.numEntries = 1;
    authList.authType[0] = pProfile->AuthType;

    return( csrIsSecurityMatch( pMac, &authList, &ucEncryptionList,
                                &mcEncryptionList, NULL, NULL, NULL,
                                pBssDesc, pIes, NULL, NULL, NULL ));

}


tANI_BOOLEAN csrMatchBSSToConnectProfile( tHalHandle hHal, tCsrRoamConnectedProfile *pProfile,
                                          tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_BOOLEAN fRC = eANI_BOOLEAN_FALSE, fCheck;
    tDot11fBeaconIEs *pIesLocal = pIes;

    do {
        if( !pIes )
        {
            if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)))
            {
                break;
            }
        }
        fCheck = eANI_BOOLEAN_TRUE;
        if(pIesLocal->SSID.present)
        {
            tANI_BOOLEAN fCheckSsid = eANI_BOOLEAN_FALSE;
            if(pProfile->SSID.length)
            {
                fCheckSsid = eANI_BOOLEAN_TRUE;
            }
            fCheck = csrIsSsidMatch( pMac, pProfile->SSID.ssId, pProfile->SSID.length,
                                        pIesLocal->SSID.ssid, pIesLocal->SSID.num_ssid, fCheckSsid );
            if(!fCheck) break;
        }
        if ( !csrMatchConnectedBSSSecurity( pMac, pProfile, pBssDesc, pIesLocal) ) break;
        if ( !csrIsCapabilitiesMatch( pMac, pProfile->BSSType, pBssDesc ) ) break;
        if ( !csrIsRateSetMatch( pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates ) ) break;
        fCheck = csrIsChannelBandMatch( pMac, pProfile->operationChannel, pBssDesc );
        if(!fCheck)
            break;

        fRC = eANI_BOOLEAN_TRUE;

    } while( 0 );

    if( !pIes && pIesLocal )
    {
        //locally allocated
        vos_mem_free(pIesLocal);
    }

    return( fRC );
}

void csrAddRateBitmap(tANI_U8 rate, tANI_U16 *pRateBitmap)
{
    tANI_U16 rateBitmap;
    tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK );
    rateBitmap = *pRateBitmap;
    switch(n)
    {
       case SIR_MAC_RATE_1:
            rateBitmap |= SIR_MAC_RATE_1_BITMAP;
            break;
        case SIR_MAC_RATE_2:
            rateBitmap |= SIR_MAC_RATE_2_BITMAP;
            break;
        case SIR_MAC_RATE_5_5:
            rateBitmap |= SIR_MAC_RATE_5_5_BITMAP;
            break;
        case SIR_MAC_RATE_11:
            rateBitmap |= SIR_MAC_RATE_11_BITMAP;
            break;
        case SIR_MAC_RATE_6:
            rateBitmap |= SIR_MAC_RATE_6_BITMAP;
            break;
        case SIR_MAC_RATE_9:
            rateBitmap |= SIR_MAC_RATE_9_BITMAP;
            break;
        case SIR_MAC_RATE_12:
            rateBitmap |= SIR_MAC_RATE_12_BITMAP;
            break;
        case SIR_MAC_RATE_18:
            rateBitmap |= SIR_MAC_RATE_18_BITMAP;
            break;
        case SIR_MAC_RATE_24:
            rateBitmap |= SIR_MAC_RATE_24_BITMAP;
            break;
        case SIR_MAC_RATE_36:
            rateBitmap |= SIR_MAC_RATE_36_BITMAP;
            break;
        case SIR_MAC_RATE_48:
            rateBitmap |= SIR_MAC_RATE_48_BITMAP;
            break;
        case SIR_MAC_RATE_54:
            rateBitmap |= SIR_MAC_RATE_54_BITMAP;
            break;
    }
    *pRateBitmap = rateBitmap;
}

tANI_BOOLEAN csrCheckRateBitmap(tANI_U8 rate, tANI_U16 rateBitmap)
{
    tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK );

    switch(n)
    {
        case SIR_MAC_RATE_1:
            rateBitmap &= SIR_MAC_RATE_1_BITMAP;
            break;
        case SIR_MAC_RATE_2:
            rateBitmap &= SIR_MAC_RATE_2_BITMAP;
            break;
        case SIR_MAC_RATE_5_5:
            rateBitmap &= SIR_MAC_RATE_5_5_BITMAP;
            break;
        case SIR_MAC_RATE_11:
            rateBitmap &= SIR_MAC_RATE_11_BITMAP;
            break;
        case SIR_MAC_RATE_6:
            rateBitmap &= SIR_MAC_RATE_6_BITMAP;
            break;
        case SIR_MAC_RATE_9:
            rateBitmap &= SIR_MAC_RATE_9_BITMAP;
            break;
        case SIR_MAC_RATE_12:
            rateBitmap &= SIR_MAC_RATE_12_BITMAP;
            break;
        case SIR_MAC_RATE_18:
            rateBitmap &= SIR_MAC_RATE_18_BITMAP;
            break;
        case SIR_MAC_RATE_24:
            rateBitmap &= SIR_MAC_RATE_24_BITMAP;
            break;
        case SIR_MAC_RATE_36:
            rateBitmap &= SIR_MAC_RATE_36_BITMAP;
            break;
        case SIR_MAC_RATE_48:
            rateBitmap &= SIR_MAC_RATE_48_BITMAP;
            break;
        case SIR_MAC_RATE_54:
            rateBitmap &= SIR_MAC_RATE_54_BITMAP;
            break;
    }
    return !!rateBitmap;
}

tANI_BOOLEAN csrRatesIsDot11RateSupported( tHalHandle hHal, tANI_U8 rate )
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK );

    return csrIsAggregateRateSupported( pMac, n );
}


tANI_U16 csrRatesMacPropToDot11( tANI_U16 Rate )
{
    tANI_U16 ConvertedRate = Rate;

    switch( Rate )
    {
        case SIR_MAC_RATE_1:
            ConvertedRate = 2;
            break;
        case SIR_MAC_RATE_2:
            ConvertedRate = 4;
            break;
        case SIR_MAC_RATE_5_5:
            ConvertedRate = 11;
            break;
        case SIR_MAC_RATE_11:
            ConvertedRate = 22;
            break;

        case SIR_MAC_RATE_6:
            ConvertedRate = 12;
            break;
        case SIR_MAC_RATE_9:
            ConvertedRate = 18;
            break;
        case SIR_MAC_RATE_12:
            ConvertedRate = 24;
            break;
        case SIR_MAC_RATE_18:
            ConvertedRate = 36;
            break;
        case SIR_MAC_RATE_24:
            ConvertedRate = 48;
            break;
        case SIR_MAC_RATE_36:
            ConvertedRate = 72;
            break;
        case SIR_MAC_RATE_42:
            ConvertedRate = 84;
            break;
        case SIR_MAC_RATE_48:
            ConvertedRate = 96;
            break;
        case SIR_MAC_RATE_54:
            ConvertedRate = 108;
            break;

        case SIR_MAC_RATE_72:
            ConvertedRate = 144;
            break;
        case SIR_MAC_RATE_84:
            ConvertedRate = 168;
            break;
        case SIR_MAC_RATE_96:
            ConvertedRate = 192;
            break;
        case SIR_MAC_RATE_108:
            ConvertedRate = 216;
            break;
        case SIR_MAC_RATE_126:
            ConvertedRate = 252;
            break;
        case SIR_MAC_RATE_144:
            ConvertedRate = 288;
            break;
        case SIR_MAC_RATE_168:
            ConvertedRate = 336;
            break;
        case SIR_MAC_RATE_192:
            ConvertedRate = 384;
            break;
        case SIR_MAC_RATE_216:
            ConvertedRate = 432;
            break;
        case SIR_MAC_RATE_240:
            ConvertedRate = 480;
            break;

        case 0xff:
            ConvertedRate = 0;
            break;
    }

    return ConvertedRate;
}


tANI_U16 csrRatesFindBestRate( tSirMacRateSet *pSuppRates, tSirMacRateSet *pExtRates, tSirMacPropRateSet *pPropRates )
{
    tANI_U8 i;
    tANI_U16 nBest;

    nBest = pSuppRates->rate[ 0 ] & ( ~CSR_DOT11_BASIC_RATE_MASK );

    if(pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX)
    {
        pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX;
    }

    for ( i = 1U; i < pSuppRates->numRates; ++i )
    {
        nBest = (tANI_U16)CSR_MAX( nBest, pSuppRates->rate[ i ] & ( ~CSR_DOT11_BASIC_RATE_MASK ) );
    }

    if ( NULL != pExtRates )
    {
        for ( i = 0U; i < pExtRates->numRates; ++i )
        {
            nBest = (tANI_U16)CSR_MAX( nBest, pExtRates->rate[ i ] & ( ~CSR_DOT11_BASIC_RATE_MASK ) );
        }
    }

    if ( NULL != pPropRates )
    {
        for ( i = 0U; i < pPropRates->numPropRates; ++i )
        {
            nBest = (tANI_U16)CSR_MAX( nBest,  csrRatesMacPropToDot11( pPropRates->propRate[ i ] ) );
        }
    }

    return nBest;
}

#ifdef WLAN_FEATURE_FILS_SK
static inline void csr_free_fils_profile_info(tCsrRoamProfile *profile)
{
    if (profile->fils_con_info) {
        vos_mem_free(profile->fils_con_info);
        profile->fils_con_info = NULL;
    }
}
#else
static inline void csr_free_fils_profile_info(tCsrRoamProfile *profile)
{ }
#endif


void csrReleaseProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile)
{
    if(pProfile)
    {
        if(pProfile->BSSIDs.bssid)
        {
            vos_mem_free(pProfile->BSSIDs.bssid);
            pProfile->BSSIDs.bssid = NULL;
        }
        if(pProfile->SSIDs.SSIDList)
        {
            vos_mem_free(pProfile->SSIDs.SSIDList);
            pProfile->SSIDs.SSIDList = NULL;
        }
        if(pProfile->pWPAReqIE)
        {
            vos_mem_free(pProfile->pWPAReqIE);
            pProfile->pWPAReqIE = NULL;
        }
        if(pProfile->pRSNReqIE)
        {
            vos_mem_free(pProfile->pRSNReqIE);
            pProfile->pRSNReqIE = NULL;
        }
#ifdef FEATURE_WLAN_WAPI
        if(pProfile->pWAPIReqIE)
        {
            vos_mem_free(pProfile->pWAPIReqIE);
            pProfile->pWAPIReqIE = NULL;
        }
#endif /* FEATURE_WLAN_WAPI */

        if(pProfile->pAddIEScan)
        {
            vos_mem_free(pProfile->pAddIEScan);
            pProfile->pAddIEScan = NULL;
        }

        if(pProfile->pAddIEAssoc)
        {
            vos_mem_free(pProfile->pAddIEAssoc);
            pProfile->pAddIEAssoc = NULL;
        }
        if(pProfile->ChannelInfo.ChannelList)
        {
            vos_mem_free(pProfile->ChannelInfo.ChannelList);
            pProfile->ChannelInfo.ChannelList = NULL;
        }
        csr_free_fils_profile_info(pProfile);
        vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
    }
}

void csrFreeScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
{
    if(pScanFilter->BSSIDs.bssid)
    {
        vos_mem_free(pScanFilter->BSSIDs.bssid);
        pScanFilter->BSSIDs.bssid = NULL;
    }
    if(pScanFilter->ChannelInfo.ChannelList)
    {
        vos_mem_free(pScanFilter->ChannelInfo.ChannelList);
        pScanFilter->ChannelInfo.ChannelList = NULL;
    }
    if(pScanFilter->SSIDs.SSIDList)
    {
        vos_mem_free(pScanFilter->SSIDs.SSIDList);
        pScanFilter->SSIDs.SSIDList = NULL;
    }
}


void csrFreeRoamProfile(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];

    if(pSession->pCurRoamProfile)
    {
        csrReleaseProfile(pMac, pSession->pCurRoamProfile);
        vos_mem_free(pSession->pCurRoamProfile);
        pSession->pCurRoamProfile = NULL;
    }
}


void csrFreeConnectBssDesc(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];

    if(pSession->pConnectBssDesc)
    {
        vos_mem_free(pSession->pConnectBssDesc);
        pSession->pConnectBssDesc = NULL;
    }
}



tSirResultCodes csrGetDisassocRspStatusCode( tSirSmeDisassocRsp *pSmeDisassocRsp )
{
    tANI_U8 *pBuffer = (tANI_U8 *)pSmeDisassocRsp;
    tANI_U32 ret;

    pBuffer += (sizeof(tANI_U16) + sizeof(tANI_U16) + sizeof(tSirMacAddr));
    /* tSirResultCodes is an enum, assuming is 32bit
       If we cannot make this assumption, use copy memory */
    pal_get_U32( pBuffer, &ret );

    return( ( tSirResultCodes )ret );
}


tSirResultCodes csrGetDeAuthRspStatusCode( tSirSmeDeauthRsp *pSmeRsp )
{
    tANI_U8 *pBuffer = (tANI_U8 *)pSmeRsp;
    tANI_U32 ret;

    pBuffer += (sizeof(tANI_U16) + sizeof(tANI_U16) + sizeof(tANI_U8) +sizeof(tANI_U16));
    /* tSirResultCodes is an enum, assuming is 32bit
       If we cannot make this assumption, use copy memory */
    pal_get_U32( pBuffer, &ret );

    return( ( tSirResultCodes )ret );
}

tSirScanType csrGetScanType(tpAniSirGlobal pMac, tANI_U8 chnId)
{
    tSirScanType scanType = eSIR_PASSIVE_SCAN;
    eNVChannelEnabledType channelEnabledType;

    channelEnabledType = vos_nv_getChannelEnabledState(chnId);
    if( NV_CHANNEL_ENABLE ==  channelEnabledType)
    {
         scanType = eSIR_ACTIVE_SCAN;
    }
    return (scanType);
}


tANI_U8 csrToUpper( tANI_U8 ch )
{
    tANI_U8 chOut;

    if ( ch >= 'a' && ch <= 'z' )
    {
        chOut = ch - 'a' + 'A';
    }
    else
    {
        chOut = ch;
    }
    return( chOut );
}


tSirBssType csrTranslateBsstypeToMacType(eCsrRoamBssType csrtype)
{
    tSirBssType ret;

    switch(csrtype)
    {
    case eCSR_BSS_TYPE_INFRASTRUCTURE:
        ret = eSIR_INFRASTRUCTURE_MODE;
        break;
    case eCSR_BSS_TYPE_IBSS:
    case eCSR_BSS_TYPE_START_IBSS:
        ret = eSIR_IBSS_MODE;
        break;
    case eCSR_BSS_TYPE_WDS_AP:
        ret = eSIR_BTAMP_AP_MODE;
        break;
    case eCSR_BSS_TYPE_WDS_STA:
        ret = eSIR_BTAMP_STA_MODE;
        break;
    case eCSR_BSS_TYPE_INFRA_AP:
        ret = eSIR_INFRA_AP_MODE;
        break;
    case eCSR_BSS_TYPE_NDI:
        ret = eSIR_NDI_MODE;
        break;
    case eCSR_BSS_TYPE_ANY:
    default:
        ret = eSIR_AUTO_MODE;
        break;
    }

    return (ret);
}


//This function use the parameters to decide the CFG value.
//CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG
//So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value
eCsrCfgDot11Mode csrGetCfgDot11ModeFromCsrPhyMode(tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tANI_BOOLEAN fProprietary)
{
    tANI_U32 cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;

    switch(phyMode)
    {
    case eCSR_DOT11_MODE_11a:
        cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
        break;
    case eCSR_DOT11_MODE_11b:
    case eCSR_DOT11_MODE_11b_ONLY:
        cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
        break;
    case eCSR_DOT11_MODE_11g:
    case eCSR_DOT11_MODE_11g_ONLY:
        if(pProfile && (CSR_IS_INFRA_AP(pProfile)) && (phyMode == eCSR_DOT11_MODE_11g_ONLY))
            cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY;
        else
        cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
        break;
    case eCSR_DOT11_MODE_11n:
        cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
        break;
    case eCSR_DOT11_MODE_11n_ONLY:
       if(pProfile && CSR_IS_INFRA_AP(pProfile))
           cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY;
       else
       cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
       break;
    case eCSR_DOT11_MODE_abg:
        cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
        break;
    case eCSR_DOT11_MODE_AUTO:
        cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
        break;

#ifdef WLAN_FEATURE_11AC
    case eCSR_DOT11_MODE_11ac:
        if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
        {
            cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
        }
        else
        {
            cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
        }
        break;
    case eCSR_DOT11_MODE_11ac_ONLY:
        if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
        {
            cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
        }
        else
        {
            cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
        }
        break;
#endif
    default:
        //No need to assign anything here
        break;
    }

    return (cfgDot11Mode);
}


eHalStatus csrSetRegulatoryDomain(tpAniSirGlobal pMac, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tANI_BOOLEAN fRestart;

    if(pMac->scan.domainIdCurrent == domainId)
    {
        //no change
        fRestart = eANI_BOOLEAN_FALSE;
    }
    else if( !pMac->roam.configParam.fEnforceDefaultDomain )
    {
        pMac->scan.domainIdCurrent = domainId;
        fRestart = eANI_BOOLEAN_TRUE;
    }
    else
    {
        //We cannot change the domain
        status = eHAL_STATUS_CSR_WRONG_STATE;
        fRestart = eANI_BOOLEAN_FALSE;
    }
    if(pfRestartNeeded)
    {
        *pfRestartNeeded = fRestart;
    }

    return (status);
}


v_REGDOMAIN_t csrGetCurrentRegulatoryDomain(tpAniSirGlobal pMac)
{
    return (pMac->scan.domainIdCurrent);
}


eHalStatus csrGetRegulatoryDomainForCountry
(
tpAniSirGlobal pMac,
tANI_U8 *pCountry,
v_REGDOMAIN_t *pDomainId,
v_CountryInfoSource_t source
)
{
    eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
    VOS_STATUS vosStatus;
    v_COUNTRYCODE_t countryCode;
    v_REGDOMAIN_t domainId;

    if(pCountry)
    {
        countryCode[0] = pCountry[0];
        countryCode[1] = pCountry[1];
        vosStatus = vos_nv_getRegDomainFromCountryCode(&domainId,
                                                       countryCode,
                                                       source);

        if( VOS_IS_STATUS_SUCCESS(vosStatus) )
        {
            if( pDomainId )
            {
                *pDomainId = domainId;
            }
            status = eHAL_STATUS_SUCCESS;
        }
        else
        {
            smsLog(pMac, LOGW, FL(" Couldn't find domain for country code  %c%c"), pCountry[0], pCountry[1]);
            status = eHAL_STATUS_INVALID_PARAMETER;
        }
    }

    return (status);
}

//To check whether a country code matches the one in the IE
//Only check the first two characters, ignoring in/outdoor
//pCountry -- caller allocated buffer contain the country code that is checking against
//the one in pIes. It can be NULL.
//caller must provide pIes, it cannot be NULL
//This function always return TRUE if 11d support is not turned on.
tANI_BOOLEAN csrMatchCountryCode( tpAniSirGlobal pMac, tANI_U8 *pCountry, tDot11fBeaconIEs *pIes )
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
    v_REGDOMAIN_t domainId = REGDOMAIN_COUNT;   //This is init to invalid value
    eHalStatus status;

    do
    {
        if( !csrIs11dSupported( pMac) )
        {
            break;
        }
        if( !pIes )
        {
            smsLog(pMac, LOGE, FL("  No IEs"));
            break;
        }
        if( pMac->roam.configParam.fEnforceDefaultDomain ||
            pMac->roam.configParam.fEnforceCountryCodeMatch )
        {
            //Make sure this country is recognizable
            if( pIes->Country.present )
            {
                status = csrGetRegulatoryDomainForCountry(pMac,
                                           pIes->Country.country,
                                           &domainId, COUNTRY_QUERY);
                if( !HAL_STATUS_SUCCESS( status ) )
                {
                     status = csrGetRegulatoryDomainForCountry(pMac,
                                                 pMac->scan.countryCode11d,
                                                 (v_REGDOMAIN_t *) &domainId,
                                                 COUNTRY_QUERY);
                     if( !HAL_STATUS_SUCCESS( status ) )
                     {
                           fRet = eANI_BOOLEAN_FALSE;
                           break;
                     }
                }
            }
            //check whether it is needed to enforce to the default regulatory domain first
            if( pMac->roam.configParam.fEnforceDefaultDomain )
            {
                if( domainId != pMac->scan.domainIdCurrent )
                {
                    fRet = eANI_BOOLEAN_FALSE;
                    break;
                }
            }
            if( pMac->roam.configParam.fEnforceCountryCodeMatch )
            {
            if( domainId >= REGDOMAIN_COUNT )
                {
                    fRet = eANI_BOOLEAN_FALSE;
                    break;
                }
            }
        }
        if( pCountry )
        {
            tANI_U32 i;

            if( !pIes->Country.present )
            {
                fRet = eANI_BOOLEAN_FALSE;
                break;
            }
            // Convert the CountryCode characters to upper
            for ( i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++ )
            {
                pCountry[i] = csrToUpper( pCountry[i] );
            }
            if (!vos_mem_compare(pIes->Country.country, pCountry,
                                WNI_CFG_COUNTRY_CODE_LEN - 1))
            {
                fRet = eANI_BOOLEAN_FALSE;
                break;
            }
        }
    } while(0);

    return (fRet);
}


eHalStatus csrGetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId,
                                     tCsrRoamModifyProfileFields *pModifyProfileFields)
{

   if(!pModifyProfileFields)
   {
      return eHAL_STATUS_FAILURE;
   }

   vos_mem_copy(pModifyProfileFields,
                &pMac->roam.roamSession[sessionId].connectedProfile.modifyProfileFields,
                sizeof(tCsrRoamModifyProfileFields));

   return eHAL_STATUS_SUCCESS;
}

eHalStatus csrSetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId,
                                     tCsrRoamModifyProfileFields *pModifyProfileFields)
{
   tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );

   vos_mem_copy(&pSession->connectedProfile.modifyProfileFields,
                 pModifyProfileFields,
                 sizeof(tCsrRoamModifyProfileFields));

   return eHAL_STATUS_SUCCESS;
}



/* ---------------------------------------------------------------------------
    \fn csrGetSupportedCountryCode
    \brief this function is to get a list of the country code current being supported
    \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return,
    this has the country code list. 3 bytes for each country code. This may be NULL if
    caller wants to know the needed bytes.
    \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return,
    this contains the length of the data in pBuf
    \return eHalStatus
  -------------------------------------------------------------------------------*/
eHalStatus csrGetSupportedCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U32 *pbLen)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    VOS_STATUS vosStatus;
    v_SIZE_t size = (v_SIZE_t)*pbLen;

    vosStatus = vos_nv_getSupportedCountryCode( pBuf, &size, 1 );
    /* Either way, return the value back */
    *pbLen = (tANI_U32)size;

    //If pBuf is NULL, caller just want to get the size, consider it success
    if(pBuf)
    {
        if( VOS_IS_STATUS_SUCCESS( vosStatus ) )
        {
            tANI_U32 i, n = *pbLen / 3;

            for( i = 0; i < n; i++ )
            {
                pBuf[i*3 + 2] = ' ';
            }
        }
        else
        {
            status = eHAL_STATUS_FAILURE;
        }
    }

    return (status);
}



//Upper layer to get the list of the base channels to scan for passively 11d info from csr
eHalStatus csrScanGetBaseChannels( tpAniSirGlobal pMac, tCsrChannelInfo * pChannelInfo )
{
    eHalStatus status = eHAL_STATUS_FAILURE;

    do
    {

       if(!pMac->scan.baseChannels.numChannels || !pChannelInfo)
       {
          break;
       }
       pChannelInfo->ChannelList = vos_mem_malloc(pMac->scan.baseChannels.numChannels);
       if ( NULL == pChannelInfo->ChannelList )
       {
          smsLog( pMac, LOGE, FL("csrScanGetBaseChannels: fail to allocate memory") );
          return eHAL_STATUS_FAILURE;
       }
       vos_mem_copy(pChannelInfo->ChannelList,
                    pMac->scan.baseChannels.channelList,
                    pMac->scan.baseChannels.numChannels);
       pChannelInfo->numOfChannels = pMac->scan.baseChannels.numChannels;

    }while(0);

    return ( status );
}


tANI_BOOLEAN csrIsSetKeyAllowed(tpAniSirGlobal pMac, tANI_U32 sessionId)
{
    tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE;
    tCsrRoamSession *pSession;

    pSession =CSR_GET_SESSION(pMac, sessionId);

    /*This condition is not working for infra state. When infra is in not-connected state
    * the pSession->pCurRoamProfile is NULL. And this function returns TRUE, that is incorrect.
    * Since SAP requires to set key without any BSS started, it needs this condition to be met.
    * In other words, this function is useless.
    * The current work-around is to process setcontext_rsp and removekey_rsp no matter what the
    * state is.
    */
    smsLog( pMac, LOG2, FL(" is not what it intends to. Must be revisit or removed") );
    if( (NULL == pSession) ||
        ( csrIsConnStateDisconnected( pMac, sessionId ) &&
        (pSession->pCurRoamProfile != NULL) &&
        (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) )
        )
    {
        fRet = eANI_BOOLEAN_FALSE;
    }

    return ( fRet );
}

//no need to acquire lock for this basic function
tANI_U16 sme_ChnToFreq(tANI_U8 chanNum)
{
   int i;

   for (i = 0; i < NUM_RF_CHANNELS; i++)
   {
      if (rfChannels[i].channelNum == chanNum)
      {
         return rfChannels[i].targetFreq;
      }
   }

   return (0);
}

/* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we
 * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and
 * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there
 * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to
 * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS
 */

//Remove this code once SLM_Sessionization is supported
//BMPS_WORKAROUND_NOT_NEEDED
void csrDisconnectAllActiveSessions(tpAniSirGlobal pMac)
{
    tANI_U8 i;

    /* Disconnect all the active sessions */
    for (i=0; i<CSR_ROAM_SESSION_MAX; i++)
    {
        if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) )
        {
            csrRoamDisconnectInternal(pMac, i, eCSR_DISCONNECT_REASON_UNSPECIFIED);
        }
    }
}

/**
 * csr_get_channel_status() - get chan info via channel number
 * @p_mac: Pointer to Global MAC structure
 * @channel_id: channel id
 *
 * Return: chan status info
 */
struct lim_channel_status *csr_get_channel_status(
	void *p_mac, uint32_t channel_id)
{
	uint8_t i;
	struct lim_scan_channel_status *channel_status;
	tpAniSirGlobal mac_ptr = (tpAniSirGlobal)p_mac;

	if (ACS_FW_REPORT_PARAM_CONFIGURED) {
		channel_status = (struct lim_scan_channel_status *)
				&mac_ptr->lim.scan_channel_status;
		for (i = 0; i < channel_status->total_channel; i++) {
			if (channel_status->channel_status_list[i].channel_id
				 == channel_id)
				return &channel_status->channel_status_list[i];
		}
		smsLog(mac_ptr, LOGW,
			 FL("Channel %d status info not exist"),
			  channel_id);
	}
	return NULL;
}

/**
 * csr_clear_channel_status() - clear chan info
 * @p_mac: Pointer to Global MAC structure
 *
 * Return: none
 */
void csr_clear_channel_status(void *p_mac)
{
	tpAniSirGlobal mac_ptr = (tpAniSirGlobal)p_mac;
	struct lim_scan_channel_status *channel_status;
	if (ACS_FW_REPORT_PARAM_CONFIGURED) {
		channel_status = (struct lim_scan_channel_status *)
				&mac_ptr->lim.scan_channel_status;
		channel_status->total_channel = 0;
	}
	return;
}

#ifdef FEATURE_WLAN_LFR
tANI_BOOLEAN csrIsChannelPresentInList(
        tANI_U8 *pChannelList,
        int  numChannels,
        tANI_U8   channel
        )
{
    int i = 0;

    // Check for NULL pointer
    if (!pChannelList || (numChannels == 0))
    {
       return FALSE;
    }

    // Look for the channel in the list
    for (i = 0; (i < numChannels) &&
            (i < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++)
    {
        if (pChannelList[i] == channel)
            return TRUE;
    }

    return FALSE;
}

/**
 * sme_requestTypetoString(): converts scan request enum to string.
 * @requestType: scan request type enum.
 */
const char * sme_requestTypetoString(const v_U8_t requestType)
{
    switch (requestType)
    {
        CASE_RETURN_STRING( eCSR_SCAN_REQUEST_11D_SCAN );
        CASE_RETURN_STRING( eCSR_SCAN_REQUEST_FULL_SCAN );
        CASE_RETURN_STRING( eCSR_SCAN_IDLE_MODE_SCAN );
        CASE_RETURN_STRING( eCSR_SCAN_HO_BG_SCAN );
        CASE_RETURN_STRING( eCSR_SCAN_HO_PROBE_SCAN );
        CASE_RETURN_STRING( eCSR_SCAN_HO_NT_BG_SCAN );
        CASE_RETURN_STRING( eCSR_SCAN_P2P_DISCOVERY );
        CASE_RETURN_STRING( eCSR_SCAN_SOFTAP_CHANNEL_RANGE );
        CASE_RETURN_STRING( eCSR_SCAN_P2P_FIND_PEER );
        default:
            return "Unknown Scan Request Type";
    }
}

/**
 * sme_scan_type_to_string() - converts scan type enum to string.
 * @scan_type: scan type enum
 *
 * Return: printable string for scan type
 */
const char * sme_scan_type_to_string(const uint8_t scan_type)
{
	switch (scan_type) {
	CASE_RETURN_STRING(eSIR_PASSIVE_SCAN);
	CASE_RETURN_STRING(eSIR_ACTIVE_SCAN);
	CASE_RETURN_STRING(eSIR_BEACON_TABLE);
	default:
		return "Unknown ScanType";
	}
}

/**
 * sme_bss_type_to_string() - converts bss type enum to string.
 * @bss_type: bss type enum
 *
 * Return: printable string for bss type
 */
const char * sme_bss_type_to_string(const uint8_t bss_type)
{
	switch (bss_type) {
	CASE_RETURN_STRING(eSIR_INFRASTRUCTURE_MODE);
	CASE_RETURN_STRING(eSIR_INFRA_AP_MODE);
	CASE_RETURN_STRING(eSIR_IBSS_MODE);
	CASE_RETURN_STRING(eSIR_BTAMP_STA_MODE);
	CASE_RETURN_STRING(eSIR_BTAMP_AP_MODE);
	CASE_RETURN_STRING(eSIR_AUTO_MODE);
	CASE_RETURN_STRING(eSIR_NDI_MODE);
	default:
		return "Unknown BssType";
	}
}

VOS_STATUS csrAddToChannelListFront(
        tANI_U8 *pChannelList,
        int  numChannels,
        tANI_U8   channel
        )
{
    int i = 0;

    // Check for NULL pointer
    if (!pChannelList) return eHAL_STATUS_E_NULL_VALUE;

    // Make room for the addition.  (Start moving from the back.)
    for (i = numChannels; i > 0; i--)
    {
        pChannelList[i] = pChannelList[i-1];
    }

    // Now add the NEW channel...at the front
    pChannelList[0] = channel;

    return eHAL_STATUS_SUCCESS;
}
#endif
#ifdef FEATURE_WLAN_DIAG_SUPPORT
/**
 * csr_diag_event_report() - send PE diag event
 * @pmac:        pointer to global MAC context.
 * @event_typev: sub event type for DIAG event.
 * @status:      status of the event
 * @reasoncode:  reasoncode for the given status
 *
 * This function is called to send diag event
 *
 * Return:   NA
 */

void csr_diag_event_report(tpAniSirGlobal pmac, uint16_t event_type,
			   uint16_t status, uint16_t reasoncode)
{
	tSirMacAddr nullbssid = { 0, 0, 0, 0, 0, 0 };
	WLAN_VOS_DIAG_EVENT_DEF(diag_event, vos_event_wlan_pe_payload_type);

	vos_mem_set(&diag_event, sizeof(vos_event_wlan_pe_payload_type), 0);

	vos_mem_copy(diag_event.bssid, nullbssid, sizeof(tSirMacAddr));
	diag_event.sme_state = (tANI_U16)pmac->lim.gLimSmeState;
	diag_event.mlm_state = (tANI_U16)pmac->lim.gLimMlmState;
	diag_event.event_type = event_type;
	diag_event.status = status;
	diag_event.reason_code = reasoncode;

	WLAN_VOS_DIAG_EVENT_REPORT(&diag_event, EVENT_WLAN_PE);
	return;
}
#endif
