1 /* 2 * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 /** ------------------------------------------------------------------------- * 29 ------------------------------------------------------------------------- * 30 31 \file csr_util.c 32 33 Implementation supporting routines for CSR. 34 ========================================================================== */ 35 36 #include "ani_global.h" 37 38 #include "csr_support.h" 39 #include "csr_inside_api.h" 40 #include "sms_debug.h" 41 #include "sme_qos_internal.h" 42 #include "wma_types.h" 43 #include "cds_utils.h" 44 #include "cds_concurrency.h" 45 46 47 uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = { 48 {0x00, 0x50, 0xf2, 0x00} 49 , 50 {0x00, 0x50, 0xf2, 0x01} 51 , 52 {0x00, 0x50, 0xf2, 0x02} 53 , 54 {0x00, 0x50, 0xf2, 0x03} 55 , 56 {0x00, 0x50, 0xf2, 0x04} 57 , 58 {0x00, 0x50, 0xf2, 0x05} 59 , 60 #ifdef FEATURE_WLAN_ESE 61 {0x00, 0x40, 0x96, 0x00} 62 , /* CCKM */ 63 #endif /* FEATURE_WLAN_ESE */ 64 }; 65 66 uint8_t csr_rsn_oui[][CSR_RSN_OUI_SIZE] = { 67 {0x00, 0x0F, 0xAC, 0x00} 68 , /* group cipher */ 69 {0x00, 0x0F, 0xAC, 0x01} 70 , /* WEP-40 or RSN */ 71 {0x00, 0x0F, 0xAC, 0x02} 72 , /* TKIP or RSN-PSK */ 73 {0x00, 0x0F, 0xAC, 0x03} 74 , /* Reserved */ 75 {0x00, 0x0F, 0xAC, 0x04} 76 , /* AES-CCMP */ 77 {0x00, 0x0F, 0xAC, 0x05} 78 , /* WEP-104 */ 79 {0x00, 0x40, 0x96, 0x00} 80 , /* CCKM */ 81 {0x00, 0x0F, 0xAC, 0x06} 82 , /* BIP (encryption type) or 83 RSN-PSK-SHA256 (authentication type) */ 84 /* RSN-8021X-SHA256 (authentication type) */ 85 {0x00, 0x0F, 0xAC, 0x05} 86 }; 87 88 #ifdef FEATURE_WLAN_WAPI 89 uint8_t csr_wapi_oui[][CSR_WAPI_OUI_SIZE] = { 90 {0x00, 0x14, 0x72, 0x00} 91 , /* Reserved */ 92 {0x00, 0x14, 0x72, 0x01} 93 , /* WAI certificate or SMS4 */ 94 {0x00, 0x14, 0x72, 0x02} /* WAI PSK */ 95 }; 96 #endif /* FEATURE_WLAN_WAPI */ 97 uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 }; 98 uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 }; 99 100 /* ////////////////////////////////////////////////////////////////////// */ 101 102 /** 103 * \var g_phy_rates_suppt 104 * 105 * \brief Rate support lookup table 106 * 107 * 108 * This is a lookup table indexing rates & configuration parameters to 109 * support. Given a rate (in unites of 0.5Mpbs) & three bools (MIMO 110 * Enabled, Channel Bonding Enabled, & Concatenation Enabled), one can 111 * determine whether the given rate is supported by computing two 112 * indices. The first maps the rate to table row as indicated below 113 * (i.e. eHddSuppRate_6Mbps maps to row zero, eHddSuppRate_9Mbps to row 114 * 1, and so on). Index two can be computed like so: 115 * 116 * \code 117 * idx2 = ( fEsf ? 0x4 : 0x0 ) | 118 * ( fCb ? 0x2 : 0x0 ) | 119 * ( fMimo ? 0x1 : 0x0 ); 120 * \endcode 121 * 122 * 123 * Given that: 124 * 125 * \code 126 * fSupported = g_phy_rates_suppt[idx1][idx2]; 127 * \endcode 128 * 129 * 130 * This table is based on the document "PHY Supported Rates.doc". This 131 * table is permissive in that a rate is reflected as being supported 132 * even when turning off an enabled feature would be required. For 133 * instance, "PHY Supported Rates" lists 42Mpbs as unsupported when CB, 134 * ESF, & MIMO are all on. However, if we turn off either of CB or 135 * MIMO, it then becomes supported. Therefore, we mark it as supported 136 * even in index 7 of this table. 137 * 138 * 139 */ 140 141 static const bool g_phy_rates_suppt[24][8] = { 142 143 /* SSF SSF SSF SSF ESF ESF ESF ESF */ 144 /* SIMO MIMO SIMO MIMO SIMO MIMO SIMO MIMO */ 145 /* No CB No CB CB CB No CB No CB CB CB */ 146 {true, true, true, true, true, true, true, true}, /* 6Mbps */ 147 {true, true, true, true, true, true, true, true}, /* 9Mbps */ 148 {true, true, true, true, true, true, true, true}, /* 12Mbps */ 149 {true, true, true, true, true, true, true, true}, /* 18Mbps */ 150 {false, false, true, true, false, false, true, true}, /* 20Mbps */ 151 {true, true, true, true, true, true, true, true}, /* 24Mbps */ 152 {true, true, true, true, true, true, true, true}, /* 36Mbps */ 153 {false, false, true, true, false, true, true, true}, /* 40Mbps */ 154 {false, false, true, true, false, true, true, true}, /* 42Mbps */ 155 {true, true, true, true, true, true, true, true}, /* 48Mbps */ 156 {true, true, true, true, true, true, true, true}, /* 54Mbps */ 157 {false, true, true, true, false, true, true, true}, /* 72Mbps */ 158 {false, false, true, true, false, true, true, true}, /* 80Mbps */ 159 {false, false, true, true, false, true, true, true}, /* 84Mbps */ 160 {false, true, true, true, false, true, true, true}, /* 96Mbps */ 161 {false, true, true, true, false, true, true, true}, /* 108Mbps */ 162 {false, false, true, true, false, true, true, true}, /* 120Mbps */ 163 {false, false, true, true, false, true, true, true}, /* 126Mbps */ 164 {false, false, false, true, false, false, false, true}, /* 144Mbps */ 165 {false, false, false, true, false, false, false, true}, /* 160Mbps */ 166 {false, false, false, true, false, false, false, true}, /* 168Mbps */ 167 {false, false, false, true, false, false, false, true}, /* 192Mbps */ 168 {false, false, false, true, false, false, false, true}, /* 216Mbps */ 169 {false, false, false, true, false, false, false, true}, /* 240Mbps */ 170 171 }; 172 173 #define CASE_RETURN_STR(n) {\ 174 case (n): return (# n);\ 175 } 176 177 const char *get_e_roam_cmd_status_str(eRoamCmdStatus val) 178 { 179 switch (val) { 180 CASE_RETURN_STR(eCSR_ROAM_CANCELLED); 181 CASE_RETURN_STR(eCSR_ROAM_FAILED); 182 CASE_RETURN_STR(eCSR_ROAM_ROAMING_START); 183 CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION); 184 CASE_RETURN_STR(eCSR_ROAM_CONNECT_COMPLETION); 185 CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START); 186 CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION); 187 CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED); 188 CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_FAILURE); 189 CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM); 190 CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS); 191 CASE_RETURN_STR(eCSR_ROAM_LOSTLINK); 192 CASE_RETURN_STR(eCSR_ROAM_LOSTLINK_DETECTED); 193 CASE_RETURN_STR(eCSR_ROAM_MIC_ERROR_IND); 194 CASE_RETURN_STR(eCSR_ROAM_IBSS_IND); 195 CASE_RETURN_STR(eCSR_ROAM_CONNECT_STATUS_UPDATE); 196 CASE_RETURN_STR(eCSR_ROAM_GEN_INFO); 197 CASE_RETURN_STR(eCSR_ROAM_SET_KEY_COMPLETE); 198 CASE_RETURN_STR(eCSR_ROAM_IBSS_LEAVE); 199 CASE_RETURN_STR(eCSR_ROAM_INFRA_IND); 200 CASE_RETURN_STR(eCSR_ROAM_WPS_PBC_PROBE_REQ_IND); 201 CASE_RETURN_STR(eCSR_ROAM_FT_RESPONSE); 202 CASE_RETURN_STR(eCSR_ROAM_FT_START); 203 CASE_RETURN_STR(eCSR_ROAM_REMAIN_CHAN_READY); 204 CASE_RETURN_STR(eCSR_ROAM_SESSION_OPENED); 205 CASE_RETURN_STR(eCSR_ROAM_FT_REASSOC_FAILED); 206 CASE_RETURN_STR(eCSR_ROAM_PMK_NOTIFY); 207 #ifdef FEATURE_WLAN_LFR_METRICS 208 CASE_RETURN_STR(eCSR_ROAM_PREAUTH_INIT_NOTIFY); 209 CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_SUCCESS); 210 CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_FAILURE); 211 CASE_RETURN_STR(eCSR_ROAM_HANDOVER_SUCCESS); 212 #endif 213 #ifdef FEATURE_WLAN_TDLS 214 CASE_RETURN_STR(eCSR_ROAM_TDLS_STATUS_UPDATE); 215 CASE_RETURN_STR(eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND); 216 #endif 217 CASE_RETURN_STR(eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS); 218 CASE_RETURN_STR(eCSR_ROAM_SEND_P2P_STOP_BSS); 219 #ifdef WLAN_FEATURE_11W 220 CASE_RETURN_STR(eCSR_ROAM_UNPROT_MGMT_FRAME_IND); 221 #endif 222 #ifdef WLAN_FEATURE_RMC 223 CASE_RETURN_STR(eCSR_ROAM_IBSS_PEER_INFO_COMPLETE); 224 #endif 225 #ifdef FEATURE_WLAN_ESE 226 CASE_RETURN_STR(eCSR_ROAM_TSM_IE_IND); 227 CASE_RETURN_STR(eCSR_ROAM_CCKM_PREAUTH_NOTIFY); 228 CASE_RETURN_STR(eCSR_ROAM_ESE_ADJ_AP_REPORT_IND); 229 CASE_RETURN_STR(eCSR_ROAM_ESE_BCN_REPORT_IND); 230 #endif /* FEATURE_WLAN_ESE */ 231 default: 232 return "unknown"; 233 } 234 } 235 236 const char *get_e_csr_roam_result_str(eCsrRoamResult val) 237 { 238 switch (val) { 239 CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE); 240 CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE); 241 CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED); 242 CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED); 243 CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE); 244 CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED); 245 CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND); 246 CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND); 247 CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED); 248 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT); 249 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE); 250 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER); 251 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED); 252 default: 253 return "unknown"; 254 } 255 } 256 257 bool csr_get_bss_id_bss_desc(tHalHandle hHal, tSirBssDescription *pSirBssDesc, 258 struct qdf_mac_addr *pBssId) 259 { 260 qdf_mem_copy(pBssId, &pSirBssDesc->bssId[0], 261 sizeof(struct qdf_mac_addr)); 262 return true; 263 } 264 265 bool csr_is_bss_id_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1, 266 tSirBssDescription *pSirBssDesc2) 267 { 268 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 269 bool fEqual = false; 270 struct qdf_mac_addr bssId1; 271 struct qdf_mac_addr bssId2; 272 273 do { 274 if (!pSirBssDesc1) 275 break; 276 if (!pSirBssDesc2) 277 break; 278 279 if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc1, &bssId1)) 280 break; 281 if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc2, &bssId2)) 282 break; 283 284 fEqual = qdf_is_macaddr_equal(&bssId1, &bssId2); 285 } while (0); 286 287 return fEqual; 288 } 289 290 bool csr_is_conn_state_connected_ibss(tpAniSirGlobal pMac, uint32_t sessionId) 291 { 292 return eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED == 293 pMac->roam.roamSession[sessionId].connectState; 294 } 295 296 bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal pMac, 297 uint32_t sessionId) 298 { 299 return eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED == 300 pMac->roam.roamSession[sessionId].connectState; 301 } 302 303 bool csr_is_conn_state_connected_infra(tpAniSirGlobal pMac, uint32_t sessionId) 304 { 305 return eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == 306 pMac->roam.roamSession[sessionId].connectState; 307 } 308 309 bool csr_is_conn_state_connected(tpAniSirGlobal pMac, uint32_t sessionId) 310 { 311 if (csr_is_conn_state_connected_ibss(pMac, sessionId) 312 || csr_is_conn_state_connected_infra(pMac, sessionId) 313 || csr_is_conn_state_connected_wds(pMac, sessionId)) 314 return true; 315 else 316 return false; 317 } 318 319 bool csr_is_conn_state_infra(tpAniSirGlobal pMac, uint32_t sessionId) 320 { 321 return csr_is_conn_state_connected_infra(pMac, sessionId); 322 } 323 324 bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId) 325 { 326 return csr_is_conn_state_connected_ibss(pMac, sessionId) || 327 csr_is_conn_state_disconnected_ibss(pMac, sessionId); 328 } 329 330 bool csr_is_conn_state_connected_wds(tpAniSirGlobal pMac, uint32_t sessionId) 331 { 332 return eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED == 333 pMac->roam.roamSession[sessionId].connectState; 334 } 335 336 bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal pMac, 337 uint32_t sessionId) 338 { 339 return (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == 340 pMac->roam.roamSession[sessionId].connectState) || 341 (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == 342 pMac->roam.roamSession[sessionId].connectState); 343 } 344 345 bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal pMac, uint32_t sessionId) 346 { 347 return eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED == 348 pMac->roam.roamSession[sessionId].connectState; 349 } 350 351 bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId) 352 { 353 return csr_is_conn_state_connected_wds(pMac, sessionId) || 354 csr_is_conn_state_disconnected_wds(pMac, sessionId); 355 } 356 357 static bool csr_is_conn_state_ap(tpAniSirGlobal pMac, uint32_t sessionId) 358 { 359 tCsrRoamSession *pSession; 360 pSession = CSR_GET_SESSION(pMac, sessionId); 361 if (!pSession) 362 return false; 363 if (CSR_IS_INFRA_AP(&pSession->connectedProfile)) 364 return true; 365 return false; 366 } 367 368 bool csr_is_any_session_in_connect_state(tpAniSirGlobal pMac) 369 { 370 uint32_t i; 371 bool fRc = false; 372 373 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 374 if (CSR_IS_SESSION_VALID(pMac, i) && 375 (csr_is_conn_state_infra(pMac, i) 376 || csr_is_conn_state_ibss(pMac, i) 377 || csr_is_conn_state_ap(pMac, i))) { 378 fRc = true; 379 break; 380 } 381 } 382 383 return fRc; 384 } 385 386 int8_t csr_get_infra_session_id(tpAniSirGlobal pMac) 387 { 388 uint8_t i; 389 int8_t sessionid = -1; 390 391 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 392 if (CSR_IS_SESSION_VALID(pMac, i) 393 && csr_is_conn_state_infra(pMac, i)) { 394 sessionid = i; 395 break; 396 } 397 } 398 399 return sessionid; 400 } 401 402 uint8_t csr_get_infra_operation_channel(tpAniSirGlobal pMac, uint8_t sessionId) 403 { 404 uint8_t channel; 405 406 if (CSR_IS_SESSION_VALID(pMac, sessionId)) { 407 channel = 408 pMac->roam.roamSession[sessionId].connectedProfile. 409 operationChannel; 410 } else { 411 channel = 0; 412 } 413 return channel; 414 } 415 416 bool csr_is_session_client_and_connected(tpAniSirGlobal pMac, uint8_t sessionId) 417 { 418 tCsrRoamSession *pSession = NULL; 419 if (CSR_IS_SESSION_VALID(pMac, sessionId) 420 && csr_is_conn_state_infra(pMac, sessionId)) { 421 pSession = CSR_GET_SESSION(pMac, sessionId); 422 if (NULL != pSession->pCurRoamProfile) { 423 if ((pSession->pCurRoamProfile->csrPersona == 424 QDF_STA_MODE) 425 || (pSession->pCurRoamProfile->csrPersona == 426 QDF_P2P_CLIENT_MODE)) 427 return true; 428 } 429 } 430 return false; 431 } 432 433 /** 434 * csr_get_concurrent_operation_channel() - To get concurrent operating channel 435 * @mac_ctx: Pointer to mac context 436 * 437 * This routine will return operating channel on FIRST BSS that is 438 * active/operating to be used for concurrency mode. 439 * If other BSS is not up or not connected it will return 0 440 * 441 * Return: uint8_t 442 */ 443 uint8_t csr_get_concurrent_operation_channel(tpAniSirGlobal mac_ctx) 444 { 445 tCsrRoamSession *session = NULL; 446 uint8_t i = 0; 447 enum tQDF_ADAPTER_MODE persona; 448 449 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 450 if (!CSR_IS_SESSION_VALID(mac_ctx, i)) 451 continue; 452 session = CSR_GET_SESSION(mac_ctx, i); 453 if (NULL == session->pCurRoamProfile) 454 continue; 455 persona = session->pCurRoamProfile->csrPersona; 456 if ((((persona == QDF_STA_MODE) || 457 (persona == QDF_P2P_CLIENT_MODE)) && 458 (session->connectState == 459 eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) || 460 (((persona == QDF_P2P_GO_MODE) || 461 (persona == QDF_SAP_MODE)) 462 && (session->connectState != 463 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED))) 464 return session->connectedProfile.operationChannel; 465 466 } 467 return 0; 468 } 469 470 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH 471 472 #define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2) 473 474 /* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */ 475 476 #define CSR_GET_HT40_PLUS_CCH(och) ((och)+2) 477 #define CSR_GET_HT40_MINUS_CCH(och) ((och)-2) 478 479 #define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6) 480 #define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2) 481 #define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2) 482 #define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6) 483 484 /** 485 * csr_get_ch_from_ht_profile() - to get channel from HT profile 486 * @pMac: pointer to Mac context 487 * @htp: pointer to HT profile 488 * @och: operating channel 489 * @cfreq: channel frequency 490 * @hbw: half bandwidth 491 * 492 * This function will fill half bandwidth and channel frequency based 493 * on the HT profile 494 * 495 * Return: none 496 */ 497 static void csr_get_ch_from_ht_profile(tpAniSirGlobal pMac, 498 tCsrRoamHTProfile *htp, 499 uint16_t och, uint16_t *cfreq, 500 uint16_t *hbw) 501 { 502 uint16_t cch, ch_bond; 503 504 if (och > 14) 505 ch_bond = pMac->roam.configParam.channelBondingMode5GHz; 506 else 507 ch_bond = pMac->roam.configParam.channelBondingMode24GHz; 508 509 cch = och; 510 *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); 511 512 if (!ch_bond) 513 goto ret; 514 515 sms_log(pMac, LOG1, FL("##HTC: %d scbw: %d rcbw: %d sco: %d" 516 "VHTC: %d apc: %d apbw: %d" 517 ), 518 htp->htCapability, htp->htSupportedChannelWidthSet, 519 htp->htRecommendedTxWidthSet, 520 htp->htSecondaryChannelOffset, 521 htp->vhtCapability, htp->apCenterChan, htp->apChanWidth 522 ); 523 524 if (htp->vhtCapability) { 525 cch = htp->apCenterChan; 526 if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) 527 *hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL); 528 else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) 529 *hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL); 530 531 if (!*hbw && htp->htCapability) { 532 if (htp->htSupportedChannelWidthSet == 533 eHT_CHANNEL_WIDTH_40MHZ) 534 *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); 535 else 536 *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); 537 } 538 } else if (htp->htCapability) { 539 if (htp->htSupportedChannelWidthSet == 540 eHT_CHANNEL_WIDTH_40MHZ) { 541 *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); 542 if (htp->htSecondaryChannelOffset == 543 PHY_DOUBLE_CHANNEL_LOW_PRIMARY) 544 cch = CSR_GET_HT40_PLUS_CCH(och); 545 else if (htp->htSecondaryChannelOffset == 546 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) 547 cch = CSR_GET_HT40_MINUS_CCH(och); 548 } else { 549 cch = och; 550 *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); 551 } 552 } 553 554 ret: 555 *cfreq = cds_chan_to_freq(cch); 556 return; 557 } 558 559 /** 560 * csr_calc_chb_for_sap_phymode() - to calc channel bandwidth for sap phymode 561 * @mac_ctx: pointer to mac context 562 * @sap_ch: SAP operating channel 563 * @sap_phymode: SAP physical mode 564 * @sap_cch: concurrency channel 565 * @sap_hbw: SAP half bw 566 * @chb: channel bandwidth 567 * 568 * This routine is called to calculate channel bandwidth 569 * 570 * Return: none 571 */ 572 static void csr_calc_chb_for_sap_phymode(tpAniSirGlobal mac_ctx, 573 uint16_t *sap_ch, eCsrPhyMode *sap_phymode, 574 uint16_t *sap_cch, uint16_t *sap_hbw, uint8_t *chb) 575 { 576 if (*sap_phymode == eCSR_DOT11_MODE_11n || 577 *sap_phymode == eCSR_DOT11_MODE_11n_ONLY) { 578 579 *sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); 580 if (*chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) 581 *sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch); 582 else if (*chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) 583 *sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch); 584 585 } else if (*sap_phymode == eCSR_DOT11_MODE_11ac || 586 *sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) { 587 /*11AC only 80/40/20 Mhz supported in Rome */ 588 if (mac_ctx->roam.configParam.nVhtChannelWidth == 589 (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) { 590 *sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL); 591 if (*chb == 592 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1)) 593 *sap_cch = CSR_GET_HT80_PLUS_LL_CCH(*sap_ch); 594 else if (*chb == 595 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW 596 - 1)) 597 *sap_cch = CSR_GET_HT80_PLUS_HL_CCH(*sap_ch); 598 else if (*chb == 599 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH 600 - 1)) 601 *sap_cch = CSR_GET_HT80_MINUS_LH_CCH(*sap_ch); 602 else if (*chb == 603 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH 604 - 1)) 605 *sap_cch = CSR_GET_HT80_MINUS_HH_CCH(*sap_ch); 606 } else { 607 *sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL); 608 if (*chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW 609 - 1)) 610 *sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch); 611 else if (*chb == 612 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW 613 - 1)) 614 *sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch); 615 else if (*chb == 616 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH 617 - 1)) 618 *sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch); 619 else if (*chb == 620 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH 621 - 1)) 622 *sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch); 623 } 624 } 625 } 626 627 /** 628 * csr_handle_conc_chnl_overlap_for_sap_go - To handle overlap for AP+AP 629 * @mac_ctx: pointer to mac context 630 * @session: Current session 631 * @sap_ch: SAP/GO operating channel 632 * @sap_hbw: SAP/GO half bw 633 * @sap_cfreq: SAP/GO channel frequency 634 * @intf_ch: concurrent SAP/GO operating channel 635 * @intf_hbw: concurrent SAP/GO half bw 636 * @intf_cfreq: concurrent SAP/GO channel frequency 637 * 638 * This routine is called to check if one SAP/GO channel is overlapping with 639 * other SAP/GO channel 640 * 641 * Return: none 642 */ 643 static void csr_handle_conc_chnl_overlap_for_sap_go(tpAniSirGlobal mac_ctx, 644 tCsrRoamSession *session, 645 uint16_t *sap_ch, uint16_t *sap_hbw, uint16_t *sap_cfreq, 646 uint16_t *intf_ch, uint16_t *intf_hbw, uint16_t *intf_cfreq) 647 { 648 /* 649 * if conc_custom_rule1 is defined then we don't 650 * want p2pgo to follow SAP's channel or SAP to 651 * follow P2PGO's channel. 652 */ 653 if (0 == mac_ctx->roam.configParam.conc_custom_rule1 && 654 0 == mac_ctx->roam.configParam.conc_custom_rule2) { 655 if (*sap_ch == 0) { 656 *sap_ch = session->connectedProfile.operationChannel; 657 csr_get_ch_from_ht_profile(mac_ctx, 658 &session->connectedProfile.HTProfile, 659 *sap_ch, sap_cfreq, sap_hbw); 660 } else if (*sap_ch != 661 session->connectedProfile.operationChannel) { 662 *intf_ch = session->connectedProfile.operationChannel; 663 csr_get_ch_from_ht_profile(mac_ctx, 664 &session->connectedProfile.HTProfile, 665 *intf_ch, intf_cfreq, intf_hbw); 666 } 667 } else if (*sap_ch == 0 && 668 (session->pCurRoamProfile->csrPersona == 669 QDF_SAP_MODE)) { 670 *sap_ch = session->connectedProfile.operationChannel; 671 csr_get_ch_from_ht_profile(mac_ctx, 672 &session->connectedProfile.HTProfile, 673 *sap_ch, sap_cfreq, sap_hbw); 674 } 675 } 676 677 678 /** 679 * csr_check_concurrent_channel_overlap() - To check concurrent overlap chnls 680 * @mac_ctx: Pointer to mac context 681 * @sap_ch: SAP channel 682 * @sap_phymode: SAP phy mode 683 * @cc_switch_mode: concurrent switch mode 684 * 685 * This routine will be called to check concurrent overlap channels 686 * 687 * Return: uint16_t 688 */ 689 uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx, 690 uint16_t sap_ch, eCsrPhyMode sap_phymode, 691 uint8_t cc_switch_mode) 692 { 693 tCsrRoamSession *session = NULL; 694 uint8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED; 695 uint16_t intf_ch = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0; 696 uint16_t sap_cfreq = 0; 697 uint16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch = 0; 698 QDF_STATUS status; 699 700 sms_log(mac_ctx, LOG1, FL("sap_ch:%d sap_phymode:%d"), 701 sap_ch, sap_phymode); 702 703 if (mac_ctx->roam.configParam.cc_switch_mode == 704 QDF_MCC_TO_SCC_SWITCH_DISABLE) 705 return 0; 706 707 if (sap_ch != 0) { 708 sap_cch = sap_ch; 709 sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL); 710 711 if (sap_ch > 14) 712 chb = mac_ctx->roam.configParam.channelBondingMode5GHz; 713 else 714 chb = mac_ctx->roam.configParam.channelBondingMode24GHz; 715 716 if (chb) 717 csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch, 718 &sap_phymode, &sap_cch, &sap_hbw, &chb); 719 sap_cfreq = cds_chan_to_freq(sap_cch); 720 } 721 722 sms_log(mac_ctx, LOG1, 723 FL("sap_ch:%d sap_phymode:%d sap_cch:%d sap_hbw:%d chb:%d"), 724 sap_ch, sap_phymode, sap_cch, sap_hbw, chb); 725 726 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 727 if (!CSR_IS_SESSION_VALID(mac_ctx, i)) 728 continue; 729 730 session = CSR_GET_SESSION(mac_ctx, i); 731 if (NULL == session->pCurRoamProfile) 732 continue; 733 if (((session->pCurRoamProfile->csrPersona == QDF_STA_MODE) || 734 (session->pCurRoamProfile->csrPersona == 735 QDF_P2P_CLIENT_MODE)) && 736 (session->connectState == 737 eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) { 738 intf_ch = session->connectedProfile.operationChannel; 739 csr_get_ch_from_ht_profile(mac_ctx, 740 &session->connectedProfile.HTProfile, 741 intf_ch, &intf_cfreq, &intf_hbw); 742 sms_log(mac_ctx, LOG1, 743 FL("%d: intf_ch:%d intf_cfreq:%d intf_hbw:%d"), 744 i, intf_ch, intf_cfreq, intf_hbw); 745 } else if (((session->pCurRoamProfile->csrPersona == 746 QDF_P2P_GO_MODE) || 747 (session->pCurRoamProfile->csrPersona == 748 QDF_SAP_MODE)) && 749 (session->connectState != 750 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) { 751 if (session->ch_switch_in_progress) 752 continue; 753 754 csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx, 755 session, &sap_ch, &sap_hbw, &sap_cfreq, 756 &intf_ch, &intf_hbw, &intf_cfreq); 757 758 sms_log(mac_ctx, LOG1, 759 FL("%d: sap_ch:%d sap_hbw:%d sap_cfreq:%d intf_ch:%d intf_hbw:%d, intf_cfreq:%d"), 760 i, sap_ch, sap_hbw, sap_cfreq, 761 intf_ch, intf_hbw, intf_cfreq); 762 } 763 } 764 765 sms_log(mac_ctx, LOG1, 766 FL("intf_ch:%d sap_ch:%d cc_switch_mode:%d"), 767 intf_ch, sap_ch, cc_switch_mode); 768 769 if (intf_ch && sap_ch != intf_ch && 770 cc_switch_mode != QDF_MCC_TO_SCC_SWITCH_FORCE && 771 cc_switch_mode != 772 QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION && 773 cc_switch_mode != 774 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { 775 sap_lfreq = sap_cfreq - sap_hbw; 776 sap_hfreq = sap_cfreq + sap_hbw; 777 intf_lfreq = intf_cfreq - intf_hbw; 778 intf_hfreq = intf_cfreq + intf_hbw; 779 780 sms_log(mac_ctx, LOGE, 781 FL("\nSAP: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d\n" 782 "INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d"), 783 sap_ch, cds_chan_to_freq(sap_ch), 784 cds_freq_to_chan(sap_cfreq), sap_cfreq, sap_hbw * 2, 785 sap_lfreq, sap_hfreq, intf_ch, 786 cds_chan_to_freq(intf_ch), cds_freq_to_chan(intf_cfreq), 787 intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq); 788 789 if (!(((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) || 790 (sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) || 791 ((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) || 792 (intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq)))) 793 intf_ch = 0; 794 } else if (intf_ch && sap_ch != intf_ch && 795 ((cc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE) || 796 (cc_switch_mode == 797 QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) || 798 (cc_switch_mode == 799 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL))) { 800 if (!((intf_ch < 14 && sap_ch < 14) || 801 (intf_ch > 14 && sap_ch > 14))) 802 intf_ch = 0; 803 else if (cc_switch_mode == 804 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { 805 status = 806 cds_get_sap_mandatory_channel((uint32_t *)&intf_ch); 807 if (QDF_IS_STATUS_ERROR(status)) { 808 sms_log(mac_ctx, LOGE, 809 FL("no mandatory channel")); 810 intf_ch = sap_ch; 811 } 812 } 813 } else if ((intf_ch == sap_ch) && (cc_switch_mode == 814 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)) { 815 if (cds_chan_to_band(intf_ch) == CDS_BAND_2GHZ) { 816 status = 817 cds_get_sap_mandatory_channel( 818 (uint32_t *)&intf_ch); 819 if (QDF_IS_STATUS_ERROR(status)) { 820 sms_log(mac_ctx, LOGE, 821 FL("no mandatory channel")); 822 intf_ch = sap_ch; 823 } 824 } 825 } 826 827 if (intf_ch == sap_ch) 828 intf_ch = 0; 829 830 sms_log(mac_ctx, LOGE, FL("##Concurrent Channels %s Interfering"), 831 intf_ch == 0 ? "Not" : "Are"); 832 return intf_ch; 833 } 834 #endif 835 836 bool csr_is_all_session_disconnected(tpAniSirGlobal pMac) 837 { 838 uint32_t i; 839 bool fRc = true; 840 841 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 842 if (CSR_IS_SESSION_VALID(pMac, i) 843 && !csr_is_conn_state_disconnected(pMac, i)) { 844 fRc = false; 845 break; 846 } 847 } 848 849 return fRc; 850 } 851 852 /** 853 * csr_is_sta_session_connected() - to find if concurrent sta is active 854 * @mac_ctx: pointer to mac context 855 * 856 * This function will iterate through each session and check if sta 857 * session exist and active 858 * 859 * Return: true or false 860 */ 861 bool csr_is_sta_session_connected(tpAniSirGlobal mac_ctx) 862 { 863 uint32_t i; 864 tCsrRoamSession *pSession = NULL; 865 866 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 867 if (CSR_IS_SESSION_VALID(mac_ctx, i) && 868 !csr_is_conn_state_disconnected(mac_ctx, i)) { 869 pSession = CSR_GET_SESSION(mac_ctx, i); 870 871 if ((NULL != pSession->pCurRoamProfile) && 872 (QDF_STA_MODE == 873 pSession->pCurRoamProfile->csrPersona)) 874 return true; 875 } 876 } 877 878 return false; 879 } 880 881 /** 882 * csr_is_p2p_session_connected() - to find if any p2p session is active 883 * @mac_ctx: pointer to mac context 884 * 885 * This function will iterate through each session and check if any p2p 886 * session exist and active 887 * 888 * Return: true or false 889 */ 890 bool csr_is_p2p_session_connected(tpAniSirGlobal pMac) 891 { 892 uint32_t i; 893 tCsrRoamSession *pSession = NULL; 894 enum tQDF_ADAPTER_MODE persona; 895 896 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 897 if (!CSR_IS_SESSION_VALID(pMac, i)) 898 continue; 899 900 if (csr_is_conn_state_disconnected(pMac, i)) 901 continue; 902 903 pSession = CSR_GET_SESSION(pMac, i); 904 if (pSession->pCurRoamProfile == NULL) 905 continue; 906 907 persona = pSession->pCurRoamProfile->csrPersona; 908 if (QDF_P2P_CLIENT_MODE == persona || 909 QDF_P2P_GO_MODE == persona) 910 return true; 911 } 912 913 return false; 914 } 915 916 bool csr_is_any_session_connected(tpAniSirGlobal pMac) 917 { 918 uint32_t i, count; 919 bool fRc = false; 920 921 count = 0; 922 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 923 if (CSR_IS_SESSION_VALID(pMac, i) 924 && !csr_is_conn_state_disconnected(pMac, i)) 925 count++; 926 } 927 928 if (count > 0) 929 fRc = true; 930 return fRc; 931 } 932 933 bool csr_is_infra_connected(tpAniSirGlobal pMac) 934 { 935 uint32_t i; 936 bool fRc = false; 937 938 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 939 if (CSR_IS_SESSION_VALID(pMac, i) 940 && csr_is_conn_state_connected_infra(pMac, i)) { 941 fRc = true; 942 break; 943 } 944 } 945 946 return fRc; 947 } 948 949 bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac) 950 { 951 uint32_t i, noOfConnectedInfra = 0; 952 953 bool fRc = false; 954 955 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 956 if (CSR_IS_SESSION_VALID(pMac, i) 957 && csr_is_conn_state_connected_infra(pMac, i)) { 958 ++noOfConnectedInfra; 959 } 960 } 961 962 /* More than one Infra Sta Connected */ 963 if (noOfConnectedInfra > 1) 964 fRc = true; 965 return fRc; 966 } 967 968 bool csr_is_ibss_started(tpAniSirGlobal pMac) 969 { 970 uint32_t i; 971 bool fRc = false; 972 973 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 974 if (CSR_IS_SESSION_VALID(pMac, i) 975 && csr_is_conn_state_ibss(pMac, i)) { 976 fRc = true; 977 break; 978 } 979 } 980 981 return fRc; 982 } 983 984 bool csr_is_concurrent_session_running(tpAniSirGlobal pMac) 985 { 986 uint32_t sessionId, noOfCocurrentSession = 0; 987 eCsrConnectState connectState; 988 989 bool fRc = false; 990 991 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) { 992 if (CSR_IS_SESSION_VALID(pMac, sessionId)) { 993 connectState = 994 pMac->roam.roamSession[sessionId].connectState; 995 if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == 996 connectState) 997 || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == 998 connectState) 999 || (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == 1000 connectState)) { 1001 ++noOfCocurrentSession; 1002 } 1003 } 1004 } 1005 1006 /* More than one session is Up and Running */ 1007 if (noOfCocurrentSession > 1) 1008 fRc = true; 1009 return fRc; 1010 } 1011 1012 bool csr_is_infra_ap_started(tpAniSirGlobal pMac) 1013 { 1014 uint32_t sessionId; 1015 bool fRc = false; 1016 1017 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) { 1018 if (CSR_IS_SESSION_VALID(pMac, sessionId) 1019 && (csr_is_conn_state_connected_infra_ap(pMac, sessionId))) { 1020 fRc = true; 1021 break; 1022 } 1023 } 1024 1025 return fRc; 1026 1027 } 1028 1029 bool csr_is_conn_state_disconnected(tpAniSirGlobal pMac, uint32_t sessionId) 1030 { 1031 return eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED == 1032 pMac->roam.roamSession[sessionId].connectState; 1033 } 1034 1035 /** 1036 * csr_is_valid_mc_concurrent_session() - To check concurren session is valid 1037 * @mac_ctx: pointer to mac context 1038 * @session_id: session id 1039 * @bss_descr: bss description 1040 * 1041 * This function validates the concurrent session 1042 * 1043 * Return: true or false 1044 */ 1045 bool csr_is_valid_mc_concurrent_session(tpAniSirGlobal mac_ctx, 1046 uint32_t session_id, 1047 tSirBssDescription *bss_descr) 1048 { 1049 tCsrRoamSession *pSession = NULL; 1050 1051 /* Check for MCC support */ 1052 if (!mac_ctx->roam.configParam.fenableMCCMode) 1053 return false; 1054 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) 1055 return false; 1056 /* Validate BeaconInterval */ 1057 pSession = CSR_GET_SESSION(mac_ctx, session_id); 1058 if (NULL == pSession->pCurRoamProfile) 1059 return false; 1060 if (QDF_STATUS_SUCCESS == csr_validate_mcc_beacon_interval(mac_ctx, 1061 bss_descr->channelId, 1062 &bss_descr->beaconInterval, session_id, 1063 pSession->pCurRoamProfile->csrPersona)) 1064 return true; 1065 return false; 1066 } 1067 1068 static tSirMacCapabilityInfo csr_get_bss_capabilities(tSirBssDescription * 1069 pSirBssDesc) 1070 { 1071 tSirMacCapabilityInfo dot11Caps; 1072 1073 /* tSirMacCapabilityInfo is 16-bit */ 1074 qdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo, 1075 (uint16_t *) &dot11Caps); 1076 1077 return dot11Caps; 1078 } 1079 1080 bool csr_is_infra_bss_desc(tSirBssDescription *pSirBssDesc) 1081 { 1082 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); 1083 1084 return (bool) dot11Caps.ess; 1085 } 1086 1087 bool csr_is_ibss_bss_desc(tSirBssDescription *pSirBssDesc) 1088 { 1089 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); 1090 1091 return (bool) dot11Caps.ibss; 1092 } 1093 1094 static bool csr_is_qos_bss_desc(tSirBssDescription *pSirBssDesc) 1095 { 1096 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); 1097 1098 return (bool) dot11Caps.qos; 1099 } 1100 1101 bool csr_is_privacy(tSirBssDescription *pSirBssDesc) 1102 { 1103 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc); 1104 1105 return (bool) dot11Caps.privacy; 1106 } 1107 1108 bool csr_is11d_supported(tpAniSirGlobal pMac) 1109 { 1110 return pMac->roam.configParam.Is11dSupportEnabled; 1111 } 1112 1113 bool csr_is11h_supported(tpAniSirGlobal pMac) 1114 { 1115 return pMac->roam.configParam.Is11hSupportEnabled; 1116 } 1117 1118 bool csr_is11e_supported(tpAniSirGlobal pMac) 1119 { 1120 return pMac->roam.configParam.Is11eSupportEnabled; 1121 } 1122 1123 bool csr_is_mcc_supported(tpAniSirGlobal pMac) 1124 { 1125 return pMac->roam.configParam.fenableMCCMode; 1126 1127 } 1128 1129 bool csr_is_wmm_supported(tpAniSirGlobal pMac) 1130 { 1131 if (eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode) 1132 return false; 1133 else 1134 return true; 1135 } 1136 1137 /* pIes is the IEs for pSirBssDesc2 */ 1138 bool csr_is_ssid_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1, 1139 tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2) 1140 { 1141 bool fEqual = false; 1142 tSirMacSSid Ssid1, Ssid2; 1143 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1144 tDot11fBeaconIEs *pIes1 = NULL; 1145 tDot11fBeaconIEs *pIesLocal = pIes2; 1146 1147 do { 1148 if ((NULL == pSirBssDesc1) || (NULL == pSirBssDesc2)) 1149 break; 1150 if (!pIesLocal 1151 && 1152 !QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies 1153 (pMac, pSirBssDesc2, 1154 &pIesLocal))) { 1155 sms_log(pMac, LOGE, FL(" fail to parse IEs")); 1156 break; 1157 } 1158 if (!QDF_IS_STATUS_SUCCESS 1159 (csr_get_parsed_bss_description_ies(pMac, 1160 pSirBssDesc1, &pIes1))) { 1161 break; 1162 } 1163 if ((!pIes1->SSID.present) || (!pIesLocal->SSID.present)) 1164 break; 1165 if (pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid) 1166 break; 1167 qdf_mem_copy(Ssid1.ssId, pIes1->SSID.ssid, 1168 pIes1->SSID.num_ssid); 1169 qdf_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid, 1170 pIesLocal->SSID.num_ssid); 1171 1172 fEqual = (!qdf_mem_cmp(Ssid1.ssId, Ssid2.ssId, 1173 pIesLocal->SSID.num_ssid)); 1174 1175 } while (0); 1176 if (pIes1) 1177 qdf_mem_free(pIes1); 1178 if (pIesLocal && !pIes2) 1179 qdf_mem_free(pIesLocal); 1180 1181 return fEqual; 1182 } 1183 1184 /* pIes can be passed in as NULL if the caller doesn't have one prepared */ 1185 static bool csr_is_bss_description_wme(tHalHandle hHal, 1186 tSirBssDescription *pSirBssDesc, 1187 tDot11fBeaconIEs *pIes) 1188 { 1189 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1190 /* Assume that WME is found... */ 1191 bool fWme = true; 1192 tDot11fBeaconIEs *pIesTemp = pIes; 1193 1194 do { 1195 if (pIesTemp == NULL) { 1196 if (!QDF_IS_STATUS_SUCCESS 1197 (csr_get_parsed_bss_description_ies 1198 (pMac, pSirBssDesc, &pIesTemp))) { 1199 fWme = false; 1200 break; 1201 } 1202 } 1203 /* if the Wme Info IE is found, then WME is supported... */ 1204 if (CSR_IS_QOS_BSS(pIesTemp)) 1205 break; 1206 /* if none of these are found, then WME is NOT supported... */ 1207 fWme = false; 1208 } while (0); 1209 if (!csr_is_wmm_supported(pMac) && fWme) { 1210 if (!pIesTemp->HTCaps.present) { 1211 fWme = false; 1212 } 1213 } 1214 if ((pIes == NULL) && (NULL != pIesTemp)) { 1215 /* we allocate memory here so free it before returning */ 1216 qdf_mem_free(pIesTemp); 1217 } 1218 1219 return fWme; 1220 } 1221 1222 eCsrMediaAccessType csr_get_qo_s_from_bss_desc(tHalHandle hHal, 1223 tSirBssDescription *pSirBssDesc, 1224 tDot11fBeaconIEs *pIes) 1225 { 1226 eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF; 1227 1228 if (NULL == pIes) { 1229 QDF_ASSERT(pIes != NULL); 1230 return qosType; 1231 } 1232 1233 do { 1234 /* if we find WMM in the Bss Description, then we let this */ 1235 /* override and use WMM. */ 1236 if (csr_is_bss_description_wme(hHal, pSirBssDesc, pIes)) { 1237 qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; 1238 } else { 1239 /* if the QoS bit is on, then the AP is advertising 11E QoS... */ 1240 if (csr_is_qos_bss_desc(pSirBssDesc)) { 1241 qosType = eCSR_MEDIUM_ACCESS_11e_eDCF; 1242 } else { 1243 qosType = eCSR_MEDIUM_ACCESS_DCF; 1244 } 1245 /* scale back based on the types turned on for the adapter... */ 1246 if (eCSR_MEDIUM_ACCESS_11e_eDCF == qosType 1247 && !csr_is11e_supported(hHal)) { 1248 qosType = eCSR_MEDIUM_ACCESS_DCF; 1249 } 1250 } 1251 1252 } while (0); 1253 1254 return qosType; 1255 } 1256 1257 /* Caller allocates memory for pIEStruct */ 1258 QDF_STATUS csr_parse_bss_description_ies(tHalHandle hHal, 1259 tSirBssDescription *pBssDesc, 1260 tDot11fBeaconIEs *pIEStruct) 1261 { 1262 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1263 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1264 int ieLen = 1265 (int)(pBssDesc->length + sizeof(pBssDesc->length) - 1266 GET_FIELD_OFFSET(tSirBssDescription, ieFields)); 1267 1268 if (ieLen > 0 && pIEStruct) { 1269 if (!DOT11F_FAILED 1270 (dot11f_unpack_beacon_i_es 1271 (pMac, (uint8_t *) pBssDesc->ieFields, ieLen, 1272 pIEStruct))) { 1273 status = QDF_STATUS_SUCCESS; 1274 } 1275 } 1276 1277 return status; 1278 } 1279 1280 /* This function will allocate memory for the parsed IEs to the caller. Caller must free the memory */ 1281 /* after it is done with the data only if this function succeeds */ 1282 QDF_STATUS csr_get_parsed_bss_description_ies(tHalHandle hHal, 1283 tSirBssDescription *pBssDesc, 1284 tDot11fBeaconIEs **ppIEStruct) 1285 { 1286 QDF_STATUS status = QDF_STATUS_E_INVAL; 1287 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1288 1289 if (pBssDesc && ppIEStruct) { 1290 *ppIEStruct = qdf_mem_malloc(sizeof(tDot11fBeaconIEs)); 1291 if ((*ppIEStruct) != NULL) { 1292 qdf_mem_set((void *)*ppIEStruct, 1293 sizeof(tDot11fBeaconIEs), 0); 1294 status = 1295 csr_parse_bss_description_ies(hHal, pBssDesc, 1296 *ppIEStruct); 1297 if (!QDF_IS_STATUS_SUCCESS(status)) { 1298 qdf_mem_free(*ppIEStruct); 1299 *ppIEStruct = NULL; 1300 } 1301 } else { 1302 sms_log(pMac, LOGE, FL(" failed to allocate memory")); 1303 QDF_ASSERT(0); 1304 return QDF_STATUS_E_NOMEM; 1305 } 1306 } 1307 1308 return status; 1309 } 1310 1311 bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len) 1312 { 1313 bool fNullSsid = false; 1314 1315 uint32_t SsidLength; 1316 uint8_t *pSsidStr; 1317 1318 do { 1319 if (0 == len) { 1320 fNullSsid = true; 1321 break; 1322 } 1323 /* Consider 0 or space for hidden SSID */ 1324 if (0 == pBssSsid[0]) { 1325 fNullSsid = true; 1326 break; 1327 } 1328 1329 SsidLength = len; 1330 pSsidStr = pBssSsid; 1331 1332 while (SsidLength) { 1333 if (*pSsidStr) 1334 break; 1335 1336 pSsidStr++; 1337 SsidLength--; 1338 } 1339 1340 if (0 == SsidLength) { 1341 fNullSsid = true; 1342 break; 1343 } 1344 } while (0); 1345 1346 return fNullSsid; 1347 } 1348 1349 uint32_t csr_get_frag_thresh(tHalHandle hHal) 1350 { 1351 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1352 1353 return pMac->roam.configParam.FragmentationThreshold; 1354 } 1355 1356 uint32_t csr_get_rts_thresh(tHalHandle hHal) 1357 { 1358 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1359 1360 return pMac->roam.configParam.RTSThreshold; 1361 } 1362 1363 static eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc( 1364 tSirBssDescription *pSirBssDesc) 1365 { 1366 eCsrPhyMode phyMode; 1367 1368 switch (pSirBssDesc->nwType) { 1369 case eSIR_11A_NW_TYPE: 1370 phyMode = eCSR_DOT11_MODE_11a; 1371 break; 1372 1373 case eSIR_11B_NW_TYPE: 1374 phyMode = eCSR_DOT11_MODE_11b; 1375 break; 1376 1377 case eSIR_11G_NW_TYPE: 1378 phyMode = eCSR_DOT11_MODE_11g; 1379 break; 1380 1381 case eSIR_11N_NW_TYPE: 1382 phyMode = eCSR_DOT11_MODE_11n; 1383 break; 1384 case eSIR_11AC_NW_TYPE: 1385 default: 1386 phyMode = eCSR_DOT11_MODE_11ac; 1387 break; 1388 } 1389 return phyMode; 1390 } 1391 1392 uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac, 1393 eCsrCfgDot11Mode csrDot11Mode) 1394 { 1395 uint32_t ret; 1396 1397 switch (csrDot11Mode) { 1398 case eCSR_CFG_DOT11_MODE_AUTO: 1399 sms_log(pMac, LOGW, 1400 FL(" Warning: sees eCSR_CFG_DOT11_MODE_AUTO ")); 1401 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) 1402 ret = WNI_CFG_DOT11_MODE_11AC; 1403 else 1404 ret = WNI_CFG_DOT11_MODE_11N; 1405 break; 1406 case eCSR_CFG_DOT11_MODE_11A: 1407 ret = WNI_CFG_DOT11_MODE_11A; 1408 break; 1409 case eCSR_CFG_DOT11_MODE_11B: 1410 ret = WNI_CFG_DOT11_MODE_11B; 1411 break; 1412 case eCSR_CFG_DOT11_MODE_11G: 1413 ret = WNI_CFG_DOT11_MODE_11G; 1414 break; 1415 case eCSR_CFG_DOT11_MODE_11N: 1416 ret = WNI_CFG_DOT11_MODE_11N; 1417 break; 1418 case eCSR_CFG_DOT11_MODE_11G_ONLY: 1419 ret = WNI_CFG_DOT11_MODE_11G_ONLY; 1420 break; 1421 case eCSR_CFG_DOT11_MODE_11N_ONLY: 1422 ret = WNI_CFG_DOT11_MODE_11N_ONLY; 1423 break; 1424 case eCSR_CFG_DOT11_MODE_11AC_ONLY: 1425 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) 1426 ret = WNI_CFG_DOT11_MODE_11AC_ONLY; 1427 else 1428 ret = WNI_CFG_DOT11_MODE_11N; 1429 break; 1430 case eCSR_CFG_DOT11_MODE_11AC: 1431 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) 1432 ret = WNI_CFG_DOT11_MODE_11AC; 1433 else 1434 ret = WNI_CFG_DOT11_MODE_11N; 1435 break; 1436 default: 1437 sms_log(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"), 1438 csrDot11Mode); 1439 if (eCSR_BAND_24 == pMac->roam.configParam.eBand) { 1440 ret = WNI_CFG_DOT11_MODE_11G; 1441 } else { 1442 ret = WNI_CFG_DOT11_MODE_11A; 1443 } 1444 break; 1445 } 1446 1447 return ret; 1448 } 1449 1450 /** 1451 * csr_get_phy_mode_from_bss() - Get Phy Mode 1452 * @pMac: Global MAC context 1453 * @pBSSDescription: BSS Descriptor 1454 * @pPhyMode: Physical Mode 1455 * @pIes: Pointer to the IE fields 1456 * 1457 * This function should only return the super set of supported modes 1458 * 11n implies 11b/g/a/n. 1459 * 1460 * Return: success 1461 **/ 1462 QDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac, 1463 tSirBssDescription *pBSSDescription, 1464 eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes) 1465 { 1466 QDF_STATUS status = QDF_STATUS_SUCCESS; 1467 eCsrPhyMode phyMode = 1468 csr_translate_to_phy_mode_from_bss_desc(pBSSDescription); 1469 1470 if (pIes) { 1471 if (pIes->HTCaps.present) { 1472 phyMode = eCSR_DOT11_MODE_11n; 1473 if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) || 1474 IS_BSS_VHT_CAPABLE(pIes->vendor_vht_ie.VHTCaps)) 1475 phyMode = eCSR_DOT11_MODE_11ac; 1476 } 1477 *pPhyMode = phyMode; 1478 } 1479 1480 return status; 1481 } 1482 1483 /** 1484 * csr_get_phy_mode_in_use() - to get phymode 1485 * @phyModeIn: physical mode 1486 * @bssPhyMode: physical mode in bss 1487 * @f5GhzBand: 5Ghz band 1488 * @pCfgDot11ModeToUse: dot11 mode in use 1489 * 1490 * This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes 1491 * matches. bssPhyMode is the mode derived from the BSS description 1492 * f5GhzBand is derived from the channel id of BSS description 1493 * 1494 * Return: true or false 1495 */ 1496 static bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, 1497 eCsrPhyMode bssPhyMode, 1498 bool f5GhzBand, 1499 eCsrCfgDot11Mode *pCfgDot11ModeToUse) 1500 { 1501 bool fMatch = false; 1502 eCsrCfgDot11Mode cfgDot11Mode; 1503 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 1504 1505 switch (phyModeIn) { 1506 /* 11a or 11b or 11g */ 1507 case eCSR_DOT11_MODE_abg: 1508 fMatch = true; 1509 if (f5GhzBand) 1510 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; 1511 else if (eCSR_DOT11_MODE_11b == bssPhyMode) 1512 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1513 else 1514 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 1515 break; 1516 1517 case eCSR_DOT11_MODE_11a: 1518 if (f5GhzBand) { 1519 fMatch = true; 1520 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; 1521 } 1522 break; 1523 1524 case eCSR_DOT11_MODE_11g: 1525 if (!f5GhzBand) { 1526 fMatch = true; 1527 if (eCSR_DOT11_MODE_11b == bssPhyMode) 1528 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1529 else 1530 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 1531 } 1532 break; 1533 1534 case eCSR_DOT11_MODE_11g_ONLY: 1535 if (eCSR_DOT11_MODE_11g == bssPhyMode) { 1536 fMatch = true; 1537 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 1538 } 1539 break; 1540 1541 case eCSR_DOT11_MODE_11b: 1542 if (!f5GhzBand) { 1543 fMatch = true; 1544 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1545 } 1546 break; 1547 1548 case eCSR_DOT11_MODE_11b_ONLY: 1549 if (eCSR_DOT11_MODE_11b == bssPhyMode) { 1550 fMatch = true; 1551 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1552 } 1553 break; 1554 1555 case eCSR_DOT11_MODE_11n: 1556 fMatch = true; 1557 switch (bssPhyMode) { 1558 case eCSR_DOT11_MODE_11g: 1559 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 1560 break; 1561 case eCSR_DOT11_MODE_11b: 1562 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1563 break; 1564 case eCSR_DOT11_MODE_11a: 1565 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; 1566 break; 1567 case eCSR_DOT11_MODE_11n: 1568 case eCSR_DOT11_MODE_11ac: 1569 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 1570 break; 1571 1572 default: 1573 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; 1574 break; 1575 } 1576 break; 1577 1578 case eCSR_DOT11_MODE_11n_ONLY: 1579 if ((eCSR_DOT11_MODE_11n == bssPhyMode)) { 1580 fMatch = true; 1581 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 1582 1583 } 1584 1585 break; 1586 case eCSR_DOT11_MODE_11ac: 1587 fMatch = true; 1588 switch (bssPhyMode) { 1589 case eCSR_DOT11_MODE_11g: 1590 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 1591 break; 1592 case eCSR_DOT11_MODE_11b: 1593 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1594 break; 1595 case eCSR_DOT11_MODE_11a: 1596 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; 1597 break; 1598 case eCSR_DOT11_MODE_11n: 1599 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 1600 break; 1601 case eCSR_DOT11_MODE_11ac: 1602 default: 1603 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; 1604 break; 1605 } 1606 break; 1607 1608 case eCSR_DOT11_MODE_11ac_ONLY: 1609 if ((eCSR_DOT11_MODE_11ac == bssPhyMode)) { 1610 fMatch = true; 1611 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; 1612 } 1613 break; 1614 1615 default: 1616 fMatch = true; 1617 switch (bssPhyMode) { 1618 case eCSR_DOT11_MODE_11g: 1619 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 1620 break; 1621 case eCSR_DOT11_MODE_11b: 1622 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 1623 break; 1624 case eCSR_DOT11_MODE_11a: 1625 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; 1626 break; 1627 case eCSR_DOT11_MODE_11n: 1628 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 1629 break; 1630 case eCSR_DOT11_MODE_11ac: 1631 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; 1632 break; 1633 default: 1634 cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO; 1635 break; 1636 } 1637 break; 1638 } 1639 1640 if (fMatch && pCfgDot11ModeToUse) { 1641 if (cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC 1642 && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))) 1643 *pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; 1644 else 1645 *pCfgDot11ModeToUse = cfgDot11Mode; 1646 } 1647 return fMatch; 1648 } 1649 1650 /** 1651 * csr_is_phy_mode_match() - to find if phy mode matches 1652 * @pMac: pointer to mac context 1653 * @phyMode: physical mode 1654 * @pSirBssDesc: bss description 1655 * @pProfile: pointer to roam profile 1656 * @pReturnCfgDot11Mode: dot1 mode to return 1657 * @pIes: pointer to IEs 1658 * 1659 * This function decides whether the one of the bit of phyMode is matching the 1660 * mode in the BSS and allowed by the user setting 1661 * 1662 * Return: true or false based on mode that fits the criteria 1663 */ 1664 bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode, 1665 tSirBssDescription *pSirBssDesc, 1666 tCsrRoamProfile *pProfile, 1667 eCsrCfgDot11Mode *pReturnCfgDot11Mode, 1668 tDot11fBeaconIEs *pIes) 1669 { 1670 bool fMatch = false; 1671 eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2; 1672 eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO; 1673 uint32_t bitMask, loopCount; 1674 1675 if (!QDF_IS_STATUS_SUCCESS(csr_get_phy_mode_from_bss(pMac, pSirBssDesc, 1676 &phyModeInBssDesc, pIes))) 1677 return fMatch; 1678 1679 if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) { 1680 if (eCSR_CFG_DOT11_MODE_ABG == 1681 pMac->roam.configParam.uCfgDot11Mode) 1682 phyMode = eCSR_DOT11_MODE_abg; 1683 else if (eCSR_CFG_DOT11_MODE_AUTO == 1684 pMac->roam.configParam.uCfgDot11Mode) 1685 phyMode = eCSR_DOT11_MODE_11ac; 1686 else 1687 /* user's pick */ 1688 phyMode = pMac->roam.configParam.phyMode; 1689 } 1690 1691 if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) { 1692 if (0 != phyMode) { 1693 if (eCSR_DOT11_MODE_AUTO & phyMode) { 1694 phyMode2 = 1695 eCSR_DOT11_MODE_AUTO & phyMode; 1696 } 1697 } else { 1698 phyMode2 = phyMode; 1699 } 1700 fMatch = csr_get_phy_mode_in_use(phyMode2, phyModeInBssDesc, 1701 CDS_IS_CHANNEL_5GHZ(pSirBssDesc->channelId), 1702 &cfgDot11ModeToUse); 1703 } else { 1704 bitMask = 1; 1705 loopCount = 0; 1706 while (loopCount < eCSR_NUM_PHY_MODE) { 1707 phyMode2 = (phyMode & (bitMask << loopCount++)); 1708 if (0 != phyMode2 && csr_get_phy_mode_in_use(phyMode2, 1709 phyModeInBssDesc, 1710 CDS_IS_CHANNEL_5GHZ 1711 (pSirBssDesc->channelId), 1712 &cfgDot11ModeToUse)) { 1713 fMatch = true; 1714 break; 1715 } 1716 } 1717 } 1718 if (fMatch && pReturnCfgDot11Mode) { 1719 if (pProfile) { 1720 /* 1721 * IEEE 11n spec (8.4.3): HT STA shall 1722 * eliminate TKIP as a choice for the pairwise 1723 * cipher suite if CCMP is advertised by the AP 1724 * or if the AP included an HT capabilities 1725 * element in its Beacons and Probe Response. 1726 */ 1727 if ((!CSR_IS_11n_ALLOWED( 1728 pProfile->negotiatedUCEncryptionType)) 1729 && ((eCSR_CFG_DOT11_MODE_11N == 1730 cfgDot11ModeToUse) || 1731 (eCSR_CFG_DOT11_MODE_11AC == 1732 cfgDot11ModeToUse))) { 1733 /* We cannot do 11n here */ 1734 if (!CDS_IS_CHANNEL_5GHZ 1735 (pSirBssDesc->channelId)) { 1736 cfgDot11ModeToUse = 1737 eCSR_CFG_DOT11_MODE_11G; 1738 } else { 1739 cfgDot11ModeToUse = 1740 eCSR_CFG_DOT11_MODE_11A; 1741 } 1742 } 1743 } 1744 *pReturnCfgDot11Mode = cfgDot11ModeToUse; 1745 } 1746 1747 return fMatch; 1748 } 1749 1750 eCsrCfgDot11Mode csr_find_best_phy_mode(tpAniSirGlobal pMac, uint32_t phyMode) 1751 { 1752 eCsrCfgDot11Mode cfgDot11ModeToUse; 1753 eCsrBand eBand = pMac->roam.configParam.eBand; 1754 1755 if ((0 == phyMode) || 1756 (eCSR_DOT11_MODE_11ac & phyMode) || 1757 (eCSR_DOT11_MODE_AUTO & phyMode)) { 1758 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 1759 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC; 1760 } else { 1761 /* Default to 11N mode if user has configured 11ac mode 1762 * and FW doesn't supports 11ac mode . 1763 */ 1764 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; 1765 } 1766 } else { 1767 if ((eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY) & phyMode) { 1768 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; 1769 } else if (eCSR_DOT11_MODE_abg & phyMode) { 1770 if (eCSR_BAND_24 != eBand) { 1771 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; 1772 } else { 1773 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; 1774 } 1775 } else if (eCSR_DOT11_MODE_11a & phyMode) { 1776 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; 1777 } else if ((eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY) & 1778 phyMode) { 1779 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; 1780 } else { 1781 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B; 1782 } 1783 } 1784 1785 return cfgDot11ModeToUse; 1786 } 1787 1788 uint32_t csr_get11h_power_constraint(tHalHandle hHal, 1789 tDot11fIEPowerConstraints *pPowerConstraint) 1790 { 1791 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 1792 uint32_t localPowerConstraint = 0; 1793 1794 /* check if .11h support is enabled, if not, the power constraint is 0. */ 1795 if (pMac->roam.configParam.Is11hSupportEnabled 1796 && pPowerConstraint->present) { 1797 localPowerConstraint = pPowerConstraint->localPowerConstraints; 1798 } 1799 1800 return localPowerConstraint; 1801 } 1802 1803 bool csr_is_profile_wpa(tCsrRoamProfile *pProfile) 1804 { 1805 bool fWpaProfile = false; 1806 1807 switch (pProfile->negotiatedAuthType) { 1808 case eCSR_AUTH_TYPE_WPA: 1809 case eCSR_AUTH_TYPE_WPA_PSK: 1810 case eCSR_AUTH_TYPE_WPA_NONE: 1811 #ifdef FEATURE_WLAN_ESE 1812 case eCSR_AUTH_TYPE_CCKM_WPA: 1813 #endif 1814 fWpaProfile = true; 1815 break; 1816 1817 default: 1818 fWpaProfile = false; 1819 break; 1820 } 1821 1822 if (fWpaProfile) { 1823 switch (pProfile->negotiatedUCEncryptionType) { 1824 case eCSR_ENCRYPT_TYPE_WEP40: 1825 case eCSR_ENCRYPT_TYPE_WEP104: 1826 case eCSR_ENCRYPT_TYPE_TKIP: 1827 case eCSR_ENCRYPT_TYPE_AES: 1828 fWpaProfile = true; 1829 break; 1830 1831 default: 1832 fWpaProfile = false; 1833 break; 1834 } 1835 } 1836 return fWpaProfile; 1837 } 1838 1839 bool csr_is_profile_rsn(tCsrRoamProfile *pProfile) 1840 { 1841 bool fRSNProfile = false; 1842 1843 switch (pProfile->negotiatedAuthType) { 1844 case eCSR_AUTH_TYPE_RSN: 1845 case eCSR_AUTH_TYPE_RSN_PSK: 1846 case eCSR_AUTH_TYPE_FT_RSN: 1847 case eCSR_AUTH_TYPE_FT_RSN_PSK: 1848 #ifdef FEATURE_WLAN_ESE 1849 case eCSR_AUTH_TYPE_CCKM_RSN: 1850 #endif 1851 #ifdef WLAN_FEATURE_11W 1852 case eCSR_AUTH_TYPE_RSN_PSK_SHA256: 1853 case eCSR_AUTH_TYPE_RSN_8021X_SHA256: 1854 #endif 1855 fRSNProfile = true; 1856 break; 1857 1858 default: 1859 fRSNProfile = false; 1860 break; 1861 } 1862 1863 if (fRSNProfile) { 1864 switch (pProfile->negotiatedUCEncryptionType) { 1865 /* !!REVIEW - For WPA2, use of RSN IE mandates */ 1866 /* use of AES as encryption. Here, we qualify */ 1867 /* even if encryption type is WEP or TKIP */ 1868 case eCSR_ENCRYPT_TYPE_WEP40: 1869 case eCSR_ENCRYPT_TYPE_WEP104: 1870 case eCSR_ENCRYPT_TYPE_TKIP: 1871 case eCSR_ENCRYPT_TYPE_AES: 1872 fRSNProfile = true; 1873 break; 1874 1875 default: 1876 fRSNProfile = false; 1877 break; 1878 } 1879 } 1880 return fRSNProfile; 1881 } 1882 1883 /** 1884 * csr_update_mcc_p2p_beacon_interval() - update p2p beacon interval 1885 * @mac_ctx: pointer to mac context 1886 * 1887 * This function is to update the mcc p2p beacon interval 1888 * 1889 * Return: QDF_STATUS 1890 */ 1891 static QDF_STATUS csr_update_mcc_p2p_beacon_interval(tpAniSirGlobal mac_ctx) 1892 { 1893 uint32_t session_id = 0; 1894 tCsrRoamSession *roam_session; 1895 1896 /* If MCC is not supported just break and return SUCCESS */ 1897 if (!mac_ctx->roam.configParam.fenableMCCMode) 1898 return QDF_STATUS_E_FAILURE; 1899 1900 for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) { 1901 /* 1902 * If GO in MCC support different beacon interval, 1903 * change the BI of the P2P-GO 1904 */ 1905 roam_session = &mac_ctx->roam.roamSession[session_id]; 1906 if (roam_session->bssParams.bssPersona != QDF_P2P_GO_MODE) 1907 continue; 1908 /* 1909 * Handle different BI scneario based on the 1910 * configuration set.If Config is set to 0x02 then 1911 * Disconnect all the P2P clients associated. If config 1912 * is set to 0x04 then update the BI without 1913 * disconnecting all the clients 1914 */ 1915 if ((mac_ctx->roam.configParam.fAllowMCCGODiffBI == 0x04) 1916 && (roam_session->bssParams. 1917 updatebeaconInterval)) { 1918 return csr_send_chng_mcc_beacon_interval(mac_ctx, 1919 session_id); 1920 } else if (roam_session->bssParams.updatebeaconInterval) { 1921 /* 1922 * If the configuration of fAllowMCCGODiffBI is set to 1923 * other than 0x04 1924 */ 1925 return csr_roam_call_callback(mac_ctx, 1926 session_id, 1927 NULL, 0, 1928 eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, 1929 eCSR_ROAM_RESULT_NONE); 1930 } 1931 } 1932 return QDF_STATUS_E_FAILURE; 1933 } 1934 1935 static uint16_t csr_calculate_mcc_beacon_interval(tpAniSirGlobal pMac, 1936 uint16_t sta_bi, 1937 uint16_t go_gbi) 1938 { 1939 uint8_t num_beacons = 0; 1940 uint8_t is_multiple = 0; 1941 uint16_t go_cbi = 0; 1942 uint16_t go_fbi = 0; 1943 uint16_t sta_cbi = 0; 1944 1945 /* If GO's given beacon Interval is less than 100 */ 1946 if (go_gbi < 100) 1947 go_cbi = 100; 1948 /* if GO's given beacon Interval is greater than or equal to 100 */ 1949 else 1950 go_cbi = 100 + (go_gbi % 100); 1951 1952 if (sta_bi == 0) { 1953 /* There is possibility to receive zero as value. 1954 Which will cause divide by zero. Hence initialise with 100 1955 */ 1956 sta_bi = 100; 1957 sms_log(pMac, LOGW, 1958 FL("sta_bi 2nd parameter is zero, initialize to %d"), 1959 sta_bi); 1960 } 1961 /* check, if either one is multiple of another */ 1962 if (sta_bi > go_cbi) { 1963 is_multiple = !(sta_bi % go_cbi); 1964 } else { 1965 is_multiple = !(go_cbi % sta_bi); 1966 } 1967 /* if it is multiple, then accept GO's beacon interval range [100,199] as it is */ 1968 if (is_multiple) { 1969 return go_cbi; 1970 } 1971 /* else , if it is not multiple, then then check for number of beacons to be */ 1972 /* inserted based on sta BI */ 1973 num_beacons = sta_bi / 100; 1974 if (num_beacons) { 1975 /* GO's final beacon interval will be aligned to sta beacon interval, but */ 1976 /* in the range of [100, 199]. */ 1977 sta_cbi = sta_bi / num_beacons; 1978 go_fbi = sta_cbi; 1979 } else { 1980 /* if STA beacon interval is less than 100, use GO's change bacon interval */ 1981 /* instead of updating to STA's beacon interval. */ 1982 go_fbi = go_cbi; 1983 } 1984 return go_fbi; 1985 } 1986 1987 /** 1988 * csr_validate_p2pcli_bcn_intrvl() - to validate p2pcli beacon interval 1989 * @mac_ctx: pointer to mac context 1990 * @chnl_id: channel id variable 1991 * @bcn_interval: pointer to given beacon interval 1992 * @session_id: given session id 1993 * @status: fill the status in terms of QDF_STATUS to inform caller 1994 * 1995 * This API can provide the validation the beacon interval and re-calculate 1996 * in case concurrency 1997 * 1998 * Return: bool 1999 */ 2000 static bool csr_validate_p2pcli_bcn_intrvl(tpAniSirGlobal mac_ctx, 2001 uint8_t chnl_id, uint16_t *bcn_interval, uint32_t session_id, 2002 QDF_STATUS *status) 2003 { 2004 tCsrRoamSession *roamsession; 2005 2006 roamsession = &mac_ctx->roam.roamSession[session_id]; 2007 if (roamsession->pCurRoamProfile && 2008 (roamsession->pCurRoamProfile->csrPersona == 2009 QDF_STA_MODE)) { 2010 /* check for P2P client mode */ 2011 sms_log(mac_ctx, LOG1, 2012 FL(" Ignore Beacon Interval Validation...")); 2013 } else if (roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) { 2014 /* Check for P2P go scenario */ 2015 if ((roamsession->bssParams.operationChn != chnl_id) 2016 && (roamsession->bssParams.beaconInterval != 2017 *bcn_interval)) { 2018 sms_log(mac_ctx, LOGE, 2019 FL("BcnIntrvl is diff can't connect to P2P_GO network ...")); 2020 *status = QDF_STATUS_E_FAILURE; 2021 return true; 2022 } 2023 } 2024 return false; 2025 } 2026 2027 /** 2028 * csr_validate_p2pgo_bcn_intrvl() - to validate p2pgo beacon interval 2029 * @mac_ctx: pointer to mac context 2030 * @chnl_id: channel id variable 2031 * @bcn_interval: pointer to given beacon interval 2032 * @session_id: given session id 2033 * @status: fill the status in terms of QDF_STATUS to inform caller 2034 * 2035 * This API can provide the validation the beacon interval and re-calculate 2036 * in case concurrency 2037 * 2038 * Return: bool 2039 */ 2040 static bool csr_validate_p2pgo_bcn_intrvl(tpAniSirGlobal mac_ctx, 2041 uint8_t chnl_id, uint16_t *bcn_interval, 2042 uint32_t session_id, QDF_STATUS *status) 2043 { 2044 tCsrRoamSession *roamsession; 2045 tCsrConfig *cfg_param; 2046 tCsrRoamConnectedProfile *conn_profile; 2047 uint16_t new_bcn_interval; 2048 2049 roamsession = &mac_ctx->roam.roamSession[session_id]; 2050 cfg_param = &mac_ctx->roam.configParam; 2051 conn_profile = &roamsession->connectedProfile; 2052 if (roamsession->pCurRoamProfile && 2053 ((roamsession->pCurRoamProfile->csrPersona == 2054 QDF_P2P_CLIENT_MODE) || 2055 (roamsession->pCurRoamProfile->csrPersona == 2056 QDF_STA_MODE))) { 2057 /* check for P2P_client scenario */ 2058 if ((conn_profile->operationChannel == 0) && 2059 (conn_profile->beaconInterval == 0)) 2060 return false; 2061 2062 if (csr_is_conn_state_connected_infra(mac_ctx, session_id) && 2063 (conn_profile->operationChannel != chnl_id) && 2064 (conn_profile->beaconInterval != *bcn_interval)) { 2065 /* 2066 * Updated beaconInterval should be used only when 2067 * we are starting a new BSS not incase of 2068 * client or STA case 2069 */ 2070 2071 /* Calculate beacon Interval for P2P-GO incase of MCC */ 2072 if (cfg_param->conc_custom_rule1 || 2073 cfg_param->conc_custom_rule2) { 2074 new_bcn_interval = CSR_CUSTOM_CONC_GO_BI; 2075 } else { 2076 new_bcn_interval = 2077 csr_calculate_mcc_beacon_interval( 2078 mac_ctx, 2079 conn_profile->beaconInterval, 2080 *bcn_interval); 2081 } 2082 if (*bcn_interval != new_bcn_interval) 2083 *bcn_interval = new_bcn_interval; 2084 *status = QDF_STATUS_SUCCESS; 2085 return true; 2086 } 2087 } 2088 return false; 2089 } 2090 2091 /** 2092 * csr_validate_sta_bcn_intrvl() - to validate sta beacon interval 2093 * @mac_ctx: pointer to mac context 2094 * @chnl_id: channel id variable 2095 * @bcn_interval: pointer to given beacon interval 2096 * @session_id: given session id 2097 * @status: fill the status in terms of QDF_STATUS to inform caller 2098 * 2099 * This API can provide the validation the beacon interval and re-calculate 2100 * in case concurrency 2101 * 2102 * Return: bool 2103 */ 2104 static bool csr_validate_sta_bcn_intrvl(tpAniSirGlobal mac_ctx, 2105 uint8_t chnl_id, uint16_t *bcn_interval, 2106 uint32_t session_id, QDF_STATUS *status) 2107 { 2108 tCsrRoamSession *roamsession; 2109 tCsrConfig *cfg_param; 2110 uint16_t new_bcn_interval; 2111 2112 roamsession = &mac_ctx->roam.roamSession[session_id]; 2113 cfg_param = &mac_ctx->roam.configParam; 2114 2115 if (roamsession->pCurRoamProfile && 2116 (roamsession->pCurRoamProfile->csrPersona == 2117 QDF_P2P_CLIENT_MODE)) { 2118 /* check for P2P client mode */ 2119 sms_log(mac_ctx, LOG1, 2120 FL("Bcn Intrvl validation not require for STA/CLIENT")); 2121 return false; 2122 } 2123 if ((roamsession->bssParams.bssPersona == QDF_SAP_MODE) && 2124 (roamsession->bssParams.operationChn != chnl_id)) { 2125 /* 2126 * IF SAP has started and STA wants to connect 2127 * on different channel MCC should 2128 * MCC should not be enabled so making it 2129 * false to enforce on same channel 2130 */ 2131 sms_log(mac_ctx, LOGE, 2132 FL("*** MCC with SAP+STA sessions ****")); 2133 *status = QDF_STATUS_SUCCESS; 2134 return true; 2135 } 2136 /* 2137 * Check for P2P go scenario 2138 * if GO in MCC support different 2139 * beacon interval, 2140 * change the BI of the P2P-GO 2141 */ 2142 if ((roamsession->bssParams.bssPersona == QDF_P2P_GO_MODE) && 2143 (roamsession->bssParams.operationChn != chnl_id) && 2144 (roamsession->bssParams.beaconInterval != *bcn_interval)) { 2145 /* if GO in MCC support diff beacon interval, return success */ 2146 if (cfg_param->fAllowMCCGODiffBI == 0x01) { 2147 *status = QDF_STATUS_SUCCESS; 2148 return true; 2149 } 2150 /* 2151 * Send only Broadcast disassoc and update bcn_interval 2152 * If configuration is set to 0x04 then dont 2153 * disconnect all the station 2154 */ 2155 if ((cfg_param->fAllowMCCGODiffBI == 0x02) 2156 || (cfg_param->fAllowMCCGODiffBI == 0x04)) { 2157 /* Check to pass the right beacon Interval */ 2158 if (cfg_param->conc_custom_rule1 || 2159 cfg_param->conc_custom_rule2) { 2160 new_bcn_interval = CSR_CUSTOM_CONC_GO_BI; 2161 } else { 2162 new_bcn_interval = 2163 csr_calculate_mcc_beacon_interval( 2164 mac_ctx, *bcn_interval, 2165 roamsession->bssParams.beaconInterval); 2166 } 2167 sms_log(mac_ctx, LOG1, 2168 FL(" Peer AP BI : %d, new Beacon Interval: %d"), 2169 *bcn_interval, new_bcn_interval); 2170 /* Update the becon Interval */ 2171 if (new_bcn_interval != 2172 roamsession->bssParams.beaconInterval) { 2173 /* Update the bcn_interval now */ 2174 sms_log(mac_ctx, LOGE, 2175 FL(" Beacon Interval got changed config used: %d\n"), 2176 cfg_param->fAllowMCCGODiffBI); 2177 2178 roamsession->bssParams.beaconInterval = 2179 new_bcn_interval; 2180 roamsession->bssParams.updatebeaconInterval = 2181 true; 2182 *status = csr_update_mcc_p2p_beacon_interval( 2183 mac_ctx); 2184 return true; 2185 } 2186 *status = QDF_STATUS_SUCCESS; 2187 return true; 2188 } 2189 if (cfg_param->fAllowMCCGODiffBI 2190 == 0x03) { 2191 /* Disconnect the P2P session */ 2192 roamsession->bssParams.updatebeaconInterval = false; 2193 *status = csr_roam_call_callback(mac_ctx, 2194 session_id, NULL, 0, 2195 eCSR_ROAM_SEND_P2P_STOP_BSS, 2196 eCSR_ROAM_RESULT_NONE); 2197 return true; 2198 } 2199 sms_log(mac_ctx, LOGE, 2200 FL("BcnIntrvl is diff can't connect to preferred AP...")); 2201 *status = QDF_STATUS_E_FAILURE; 2202 return true; 2203 } 2204 return false; 2205 } 2206 2207 /** 2208 * csr_validate_mcc_beacon_interval() - to validate the mcc beacon interval 2209 * @mac_ctx: pointer to mac context 2210 * @chnl_id: channel number 2211 * @bcn_interval: provided beacon interval 2212 * @cur_session_id: current session id 2213 * @cur_bss_persona: Current BSS persona 2214 * 2215 * This API will validate the mcc beacon interval 2216 * 2217 * Return: QDF_STATUS 2218 */ 2219 QDF_STATUS csr_validate_mcc_beacon_interval(tpAniSirGlobal mac_ctx, 2220 uint8_t chnl_id, 2221 uint16_t *bcn_interval, 2222 uint32_t cur_session_id, 2223 enum tQDF_ADAPTER_MODE cur_bss_persona) 2224 { 2225 uint32_t session_id = 0; 2226 QDF_STATUS status; 2227 bool is_done; 2228 2229 /* If MCC is not supported just break */ 2230 if (!mac_ctx->roam.configParam.fenableMCCMode) 2231 return QDF_STATUS_E_FAILURE; 2232 2233 for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) { 2234 if (cur_session_id == session_id) 2235 continue; 2236 2237 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) 2238 continue; 2239 2240 switch (cur_bss_persona) { 2241 case QDF_STA_MODE: 2242 is_done = csr_validate_sta_bcn_intrvl(mac_ctx, chnl_id, 2243 bcn_interval, session_id, &status); 2244 if (true == is_done) 2245 return status; 2246 break; 2247 2248 case QDF_P2P_CLIENT_MODE: 2249 is_done = csr_validate_p2pcli_bcn_intrvl(mac_ctx, 2250 chnl_id, bcn_interval, session_id, 2251 &status); 2252 if (true == is_done) 2253 return status; 2254 break; 2255 2256 case QDF_SAP_MODE: 2257 case QDF_IBSS_MODE: 2258 break; 2259 2260 case QDF_P2P_GO_MODE: 2261 is_done = csr_validate_p2pgo_bcn_intrvl(mac_ctx, 2262 chnl_id, bcn_interval, 2263 session_id, &status); 2264 if (true == is_done) 2265 return status; 2266 break; 2267 2268 default: 2269 sms_log(mac_ctx, LOGE, 2270 FL("Persona not supported : %d"), 2271 cur_bss_persona); 2272 return QDF_STATUS_E_FAILURE; 2273 } 2274 } 2275 return QDF_STATUS_SUCCESS; 2276 } 2277 2278 /** 2279 * csr_is_auth_type11r() - Check if Authentication type is 11R 2280 * @auth_type: The authentication type that is used to make the connection 2281 * @mdie_present: Is MDIE IE present 2282 * 2283 * Return: true if is 11R auth type, false otherwise 2284 */ 2285 bool csr_is_auth_type11r(eCsrAuthType auth_type, uint8_t mdie_present) 2286 { 2287 switch (auth_type) { 2288 case eCSR_AUTH_TYPE_OPEN_SYSTEM: 2289 if (mdie_present) 2290 return true; 2291 break; 2292 case eCSR_AUTH_TYPE_FT_RSN_PSK: 2293 case eCSR_AUTH_TYPE_FT_RSN: 2294 return true; 2295 break; 2296 default: 2297 break; 2298 } 2299 return false; 2300 } 2301 2302 /* Function to return true if the profile is 11r */ 2303 bool csr_is_profile11r(tCsrRoamProfile *pProfile) 2304 { 2305 return csr_is_auth_type11r(pProfile->negotiatedAuthType, 2306 pProfile->MDID.mdiePresent); 2307 } 2308 2309 2310 #ifdef FEATURE_WLAN_ESE 2311 2312 /* Function to return true if the authtype is ESE */ 2313 bool csr_is_auth_type_ese(eCsrAuthType AuthType) 2314 { 2315 switch (AuthType) { 2316 case eCSR_AUTH_TYPE_CCKM_WPA: 2317 case eCSR_AUTH_TYPE_CCKM_RSN: 2318 return true; 2319 break; 2320 default: 2321 break; 2322 } 2323 return false; 2324 } 2325 2326 /* Function to return true if the profile is ESE */ 2327 bool csr_is_profile_ese(tCsrRoamProfile *pProfile) 2328 { 2329 return csr_is_auth_type_ese(pProfile->negotiatedAuthType); 2330 } 2331 2332 #endif 2333 2334 #ifdef FEATURE_WLAN_WAPI 2335 bool csr_is_profile_wapi(tCsrRoamProfile *pProfile) 2336 { 2337 bool fWapiProfile = false; 2338 2339 switch (pProfile->negotiatedAuthType) { 2340 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: 2341 case eCSR_AUTH_TYPE_WAPI_WAI_PSK: 2342 fWapiProfile = true; 2343 break; 2344 2345 default: 2346 fWapiProfile = false; 2347 break; 2348 } 2349 2350 if (fWapiProfile) { 2351 switch (pProfile->negotiatedUCEncryptionType) { 2352 case eCSR_ENCRYPT_TYPE_WPI: 2353 fWapiProfile = true; 2354 break; 2355 2356 default: 2357 fWapiProfile = false; 2358 break; 2359 } 2360 } 2361 return fWapiProfile; 2362 } 2363 2364 static bool csr_is_wapi_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1, 2365 uint8_t *Oui2) 2366 { 2367 return !qdf_mem_cmp(Oui1, Oui2, CSR_WAPI_OUI_SIZE); 2368 } 2369 2370 static bool csr_is_wapi_oui_match(tpAniSirGlobal pMac, 2371 uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE], 2372 uint8_t cAllCyphers, uint8_t Cypher[], 2373 uint8_t Oui[]) 2374 { 2375 bool fYes = false; 2376 uint8_t idx; 2377 2378 for (idx = 0; idx < cAllCyphers; idx++) { 2379 if (csr_is_wapi_oui_equal(pMac, AllCyphers[idx], Cypher)) { 2380 fYes = true; 2381 break; 2382 } 2383 } 2384 2385 if (fYes && Oui) { 2386 qdf_mem_copy(Oui, AllCyphers[idx], CSR_WAPI_OUI_SIZE); 2387 } 2388 2389 return fYes; 2390 } 2391 #endif /* FEATURE_WLAN_WAPI */ 2392 2393 static bool csr_is_wpa_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1, 2394 uint8_t *Oui2) 2395 { 2396 return !qdf_mem_cmp(Oui1, Oui2, CSR_WPA_OUI_SIZE); 2397 } 2398 2399 static bool csr_is_oui_match(tpAniSirGlobal pMac, 2400 uint8_t AllCyphers[][CSR_WPA_OUI_SIZE], 2401 uint8_t cAllCyphers, uint8_t Cypher[], uint8_t Oui[]) 2402 { 2403 bool fYes = false; 2404 uint8_t idx; 2405 2406 for (idx = 0; idx < cAllCyphers; idx++) { 2407 if (csr_is_wpa_oui_equal(pMac, AllCyphers[idx], Cypher)) { 2408 fYes = true; 2409 break; 2410 } 2411 } 2412 2413 if (fYes && Oui) { 2414 qdf_mem_copy(Oui, AllCyphers[idx], CSR_WPA_OUI_SIZE); 2415 } 2416 2417 return fYes; 2418 } 2419 2420 static bool csr_match_rsnoui_index(tpAniSirGlobal pMac, 2421 uint8_t AllCyphers[][CSR_RSN_OUI_SIZE], 2422 uint8_t cAllCyphers, uint8_t ouiIndex, 2423 uint8_t Oui[]) 2424 { 2425 return csr_is_oui_match 2426 (pMac, AllCyphers, cAllCyphers, csr_rsn_oui[ouiIndex], Oui); 2427 2428 } 2429 2430 #ifdef FEATURE_WLAN_WAPI 2431 static bool csr_match_wapi_oui_index(tpAniSirGlobal pMac, 2432 uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE], 2433 uint8_t cAllCyphers, uint8_t ouiIndex, 2434 uint8_t Oui[]) 2435 { 2436 return csr_is_wapi_oui_match 2437 (pMac, AllCyphers, cAllCyphers, csr_wapi_oui[ouiIndex], Oui); 2438 2439 } 2440 #endif /* FEATURE_WLAN_WAPI */ 2441 2442 static bool csr_match_wpaoui_index(tpAniSirGlobal pMac, 2443 uint8_t AllCyphers[][CSR_RSN_OUI_SIZE], 2444 uint8_t cAllCyphers, uint8_t ouiIndex, 2445 uint8_t Oui[]) 2446 { 2447 return csr_is_oui_match 2448 (pMac, AllCyphers, cAllCyphers, csr_wpa_oui[ouiIndex], Oui); 2449 2450 } 2451 2452 #ifdef FEATURE_WLAN_WAPI 2453 static bool csr_is_auth_wapi_cert(tpAniSirGlobal pMac, 2454 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE], 2455 uint8_t cAllSuites, uint8_t Oui[]) 2456 { 2457 return csr_is_wapi_oui_match 2458 (pMac, AllSuites, cAllSuites, csr_wapi_oui[1], Oui); 2459 } 2460 2461 static bool csr_is_auth_wapi_psk(tpAniSirGlobal pMac, 2462 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE], 2463 uint8_t cAllSuites, uint8_t Oui[]) 2464 { 2465 return csr_is_wapi_oui_match 2466 (pMac, AllSuites, cAllSuites, csr_wapi_oui[2], Oui); 2467 } 2468 #endif /* FEATURE_WLAN_WAPI */ 2469 2470 2471 /* 2472 * Function for 11R FT Authentication. We match the FT Authentication Cipher 2473 * suite here. This matches for FT Auth with the 802.1X exchange. 2474 */ 2475 static bool csr_is_ft_auth_rsn(tpAniSirGlobal pMac, 2476 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2477 uint8_t cAllSuites, uint8_t Oui[]) 2478 { 2479 return csr_is_oui_match 2480 (pMac, AllSuites, cAllSuites, csr_rsn_oui[03], Oui); 2481 } 2482 2483 /* 2484 * Function for 11R FT Authentication. We match the FT Authentication Cipher 2485 * suite here. This matches for FT Auth with the PSK. 2486 */ 2487 static bool csr_is_ft_auth_rsn_psk(tpAniSirGlobal pMac, 2488 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2489 uint8_t cAllSuites, uint8_t Oui[]) 2490 { 2491 return csr_is_oui_match 2492 (pMac, AllSuites, cAllSuites, csr_rsn_oui[04], Oui); 2493 } 2494 2495 2496 #ifdef FEATURE_WLAN_ESE 2497 2498 /* 2499 * Function for ESE CCKM AKM Authentication. We match the CCKM AKM 2500 * Authentication Key Management suite here. This matches for CCKM AKM Auth 2501 * with the 802.1X exchange. 2502 */ 2503 static bool csr_is_ese_cckm_auth_rsn(tpAniSirGlobal pMac, 2504 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2505 uint8_t cAllSuites, uint8_t Oui[]) 2506 { 2507 return csr_is_oui_match 2508 (pMac, AllSuites, cAllSuites, csr_rsn_oui[06], Oui); 2509 } 2510 2511 static bool csr_is_ese_cckm_auth_wpa(tpAniSirGlobal pMac, 2512 uint8_t AllSuites[][CSR_WPA_OUI_SIZE], 2513 uint8_t cAllSuites, uint8_t Oui[]) 2514 { 2515 return csr_is_oui_match 2516 (pMac, AllSuites, cAllSuites, csr_wpa_oui[06], Oui); 2517 } 2518 2519 #endif 2520 2521 static bool csr_is_auth_rsn(tpAniSirGlobal pMac, 2522 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2523 uint8_t cAllSuites, uint8_t Oui[]) 2524 { 2525 return csr_is_oui_match 2526 (pMac, AllSuites, cAllSuites, csr_rsn_oui[01], Oui); 2527 } 2528 2529 static bool csr_is_auth_rsn_psk(tpAniSirGlobal pMac, 2530 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2531 uint8_t cAllSuites, uint8_t Oui[]) 2532 { 2533 return csr_is_oui_match 2534 (pMac, AllSuites, cAllSuites, csr_rsn_oui[02], Oui); 2535 } 2536 2537 #ifdef WLAN_FEATURE_11W 2538 static bool csr_is_auth_rsn_psk_sha256(tpAniSirGlobal pMac, 2539 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2540 uint8_t cAllSuites, uint8_t Oui[]) 2541 { 2542 return csr_is_oui_match 2543 (pMac, AllSuites, cAllSuites, csr_rsn_oui[07], Oui); 2544 } 2545 static bool csr_is_auth_rsn8021x_sha256(tpAniSirGlobal pMac, 2546 uint8_t AllSuites[][CSR_RSN_OUI_SIZE], 2547 uint8_t cAllSuites, uint8_t Oui[]) 2548 { 2549 return csr_is_oui_match 2550 (pMac, AllSuites, cAllSuites, csr_rsn_oui[8], Oui); 2551 } 2552 #endif 2553 2554 static bool csr_is_auth_wpa(tpAniSirGlobal pMac, 2555 uint8_t AllSuites[][CSR_WPA_OUI_SIZE], 2556 uint8_t cAllSuites, uint8_t Oui[]) 2557 { 2558 return csr_is_oui_match 2559 (pMac, AllSuites, cAllSuites, csr_wpa_oui[01], Oui); 2560 } 2561 2562 static bool csr_is_auth_wpa_psk(tpAniSirGlobal pMac, 2563 uint8_t AllSuites[][CSR_WPA_OUI_SIZE], 2564 uint8_t cAllSuites, uint8_t Oui[]) 2565 { 2566 return csr_is_oui_match 2567 (pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui); 2568 } 2569 2570 static uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType) 2571 { 2572 uint8_t OUIIndex; 2573 2574 switch (enType) { 2575 case eCSR_ENCRYPT_TYPE_WEP40: 2576 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: 2577 OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX; 2578 break; 2579 case eCSR_ENCRYPT_TYPE_WEP104: 2580 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: 2581 OUIIndex = CSR_OUI_WEP104_INDEX; 2582 break; 2583 case eCSR_ENCRYPT_TYPE_TKIP: 2584 OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX; 2585 break; 2586 case eCSR_ENCRYPT_TYPE_AES: 2587 OUIIndex = CSR_OUI_AES_INDEX; 2588 break; 2589 case eCSR_ENCRYPT_TYPE_NONE: 2590 OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX; 2591 break; 2592 #ifdef FEATURE_WLAN_WAPI 2593 case eCSR_ENCRYPT_TYPE_WPI: 2594 OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX; 2595 break; 2596 #endif /* FEATURE_WLAN_WAPI */ 2597 default: /* HOWTO handle this? */ 2598 OUIIndex = CSR_OUI_RESERVED_INDEX; 2599 break; 2600 } /* switch */ 2601 2602 return OUIIndex; 2603 } 2604 /** 2605 * csr_get_rsn_information() - to get RSN infomation 2606 * @hal: pointer to HAL 2607 * @auth_type: auth type 2608 * @encr_type: encryption type 2609 * @mc_encryption: multicast encryption type 2610 * @rsn_ie: pointer to RSN IE 2611 * @ucast_cipher: Unicast cipher 2612 * @mcast_cipher: Multicast cipher 2613 * @auth_suite: Authentication suite 2614 * @capabilities: RSN capabilities 2615 * @negotiated_authtype: Negotiated auth type 2616 * @negotiated_mccipher: negotiated multicast cipher 2617 * 2618 * This routine will get all RSN information 2619 * 2620 * Return: bool 2621 */ 2622 static bool csr_get_rsn_information(tHalHandle hal, tCsrAuthList *auth_type, 2623 eCsrEncryptionType encr_type, 2624 tCsrEncryptionList *mc_encryption, 2625 tDot11fIERSN *rsn_ie, uint8_t *ucast_cipher, 2626 uint8_t *mcast_cipher, uint8_t *auth_suite, 2627 tCsrRSNCapabilities *capabilities, 2628 eCsrAuthType *negotiated_authtype, 2629 eCsrEncryptionType *negotiated_mccipher) 2630 { 2631 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 2632 bool acceptable_cipher = false; 2633 uint8_t c_ucast_cipher = 0; 2634 uint8_t c_mcast_cipher = 0; 2635 uint8_t c_auth_suites = 0, i; 2636 uint8_t unicast[CSR_RSN_OUI_SIZE]; 2637 uint8_t multicast[CSR_RSN_OUI_SIZE]; 2638 uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE]; 2639 uint8_t authentication[CSR_RSN_OUI_SIZE]; 2640 uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE]; 2641 eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; 2642 2643 if (!rsn_ie->present) 2644 goto end; 2645 c_mcast_cipher++; 2646 qdf_mem_copy(mccipher_arr, rsn_ie->gp_cipher_suite, 2647 CSR_RSN_OUI_SIZE); 2648 c_ucast_cipher = 2649 (uint8_t) (rsn_ie->pwise_cipher_suite_count); 2650 c_auth_suites = (uint8_t) (rsn_ie->akm_suite_count); 2651 for (i = 0; i < c_auth_suites && i < CSR_RSN_MAX_AUTH_SUITES; i++) { 2652 qdf_mem_copy((void *)&authsuites[i], 2653 (void *)&rsn_ie->akm_suites[i], CSR_RSN_OUI_SIZE); 2654 } 2655 2656 /* Check - Is requested unicast Cipher supported by the BSS. */ 2657 acceptable_cipher = csr_match_rsnoui_index(mac_ctx, 2658 rsn_ie->pwise_cipher_suites, c_ucast_cipher, 2659 csr_get_oui_index_from_cipher(encr_type), 2660 unicast); 2661 2662 if (!acceptable_cipher) 2663 goto end; 2664 2665 /* unicast is supported. Pick the first matching Group cipher, if any */ 2666 for (i = 0; i < mc_encryption->numEntries; i++) { 2667 acceptable_cipher = csr_match_rsnoui_index(mac_ctx, 2668 mccipher_arr, c_mcast_cipher, 2669 csr_get_oui_index_from_cipher( 2670 mc_encryption->encryptionType[i]), 2671 multicast); 2672 if (acceptable_cipher) 2673 break; 2674 } 2675 if (!acceptable_cipher) 2676 goto end; 2677 2678 if (negotiated_mccipher) 2679 *negotiated_mccipher = mc_encryption->encryptionType[i]; 2680 2681 /* Initializing with false as it has true value already */ 2682 acceptable_cipher = false; 2683 for (i = 0; i < auth_type->numEntries; i++) { 2684 /* 2685 * Ciphers are supported, Match authentication algorithm and 2686 * pick first matching authtype. 2687 */ 2688 /* Changed the AKM suites according to order of preference */ 2689 if (csr_is_ft_auth_rsn(mac_ctx, authsuites, 2690 c_auth_suites, authentication)) { 2691 if (eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i]) 2692 neg_authtype = eCSR_AUTH_TYPE_FT_RSN; 2693 } 2694 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) 2695 && csr_is_ft_auth_rsn_psk(mac_ctx, authsuites, 2696 c_auth_suites, authentication)) { 2697 if (eCSR_AUTH_TYPE_FT_RSN_PSK == 2698 auth_type->authType[i]) 2699 neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK; 2700 } 2701 #ifdef FEATURE_WLAN_ESE 2702 /* ESE only supports 802.1X. No PSK. */ 2703 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && 2704 csr_is_ese_cckm_auth_rsn(mac_ctx, authsuites, 2705 c_auth_suites, authentication)) { 2706 if (eCSR_AUTH_TYPE_CCKM_RSN == auth_type->authType[i]) 2707 neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN; 2708 } 2709 #endif 2710 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) 2711 && csr_is_auth_rsn(mac_ctx, authsuites, 2712 c_auth_suites, authentication)) { 2713 if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i]) 2714 neg_authtype = eCSR_AUTH_TYPE_RSN; 2715 } 2716 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) 2717 && csr_is_auth_rsn_psk(mac_ctx, authsuites, 2718 c_auth_suites, authentication)) { 2719 if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i]) 2720 neg_authtype = eCSR_AUTH_TYPE_RSN_PSK; 2721 } 2722 #ifdef WLAN_FEATURE_11W 2723 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) 2724 && csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites, 2725 c_auth_suites, authentication)) { 2726 if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == 2727 auth_type->authType[i]) 2728 neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256; 2729 } 2730 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && 2731 csr_is_auth_rsn8021x_sha256(mac_ctx, authsuites, 2732 c_auth_suites, authentication)) { 2733 if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == 2734 auth_type->authType[i]) 2735 neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256; 2736 } 2737 #endif 2738 2739 /* 2740 * The 1st auth type in the APs RSN IE, to match stations 2741 * connecting profiles auth type will cause us to exit this 2742 * loop. This is added as some APs advertise multiple akms in 2743 * the RSN IE 2744 */ 2745 if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) { 2746 acceptable_cipher = true; 2747 break; 2748 } 2749 } /* for */ 2750 end: 2751 if (acceptable_cipher) { 2752 if (mcast_cipher) 2753 qdf_mem_copy(mcast_cipher, multicast, 2754 CSR_RSN_OUI_SIZE); 2755 2756 if (ucast_cipher) 2757 qdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE); 2758 2759 if (auth_suite) 2760 qdf_mem_copy(auth_suite, authentication, 2761 CSR_RSN_OUI_SIZE); 2762 2763 if (negotiated_authtype) 2764 *negotiated_authtype = neg_authtype; 2765 2766 if (capabilities) { 2767 /* Bit 0 Preauthentication */ 2768 capabilities->PreAuthSupported = 2769 (rsn_ie->RSN_Cap[0] >> 0) & 0x1; 2770 /* Bit 1 No Pairwise */ 2771 capabilities->NoPairwise = 2772 (rsn_ie->RSN_Cap[0] >> 1) & 0x1; 2773 /* Bit 2, 3 PTKSA Replay Counter */ 2774 capabilities->PTKSAReplayCounter = 2775 (rsn_ie->RSN_Cap[0] >> 2) & 0x3; 2776 /* Bit 4, 5 GTKSA Replay Counter */ 2777 capabilities->GTKSAReplayCounter = 2778 (rsn_ie->RSN_Cap[0] >> 4) & 0x3; 2779 #ifdef WLAN_FEATURE_11W 2780 /* Bit 6 MFPR */ 2781 capabilities->MFPRequired = 2782 (rsn_ie->RSN_Cap[0] >> 6) & 0x1; 2783 /* Bit 7 MFPC */ 2784 capabilities->MFPCapable = 2785 (rsn_ie->RSN_Cap[0] >> 7) & 0x1; 2786 #else 2787 /* Bit 6 MFPR */ 2788 capabilities->MFPRequired = 0; 2789 /* Bit 7 MFPC */ 2790 capabilities->MFPCapable = 0; 2791 #endif 2792 /* remaining reserved */ 2793 capabilities->Reserved = rsn_ie->RSN_Cap[1] & 0xff; 2794 } 2795 } 2796 return acceptable_cipher; 2797 } 2798 2799 #ifdef WLAN_FEATURE_11W 2800 /** 2801 * csr_is_pmf_capabilities_in_rsn_match() - check for PMF capability 2802 * @hHal: Global HAL handle 2803 * @pFilterMFPEnabled: given by supplicant to us to specify what kind 2804 * of connection supplicant is expecting to make 2805 * if it is enabled then make PMF connection. 2806 * if it is disabled then make normal connection. 2807 * @pFilterMFPRequired: given by supplicant based on our configuration 2808 * if it is 1 then we will require mandatory 2809 * PMF connection and if it is 0 then we PMF 2810 * connection is optional. 2811 * @pFilterMFPCapable: given by supplicant based on our configuration 2812 * if it 1 then we are PMF capable and if it 0 2813 * then we are not PMF capable. 2814 * @pRSNIe: RSNIe from Beacon/probe response of 2815 * neighbor AP against which we will compare 2816 * our capabilities. 2817 * 2818 * This function is to match our current capabilities with the AP 2819 * to which we are expecting make the connection. 2820 * 2821 * Return: if our PMF capabilities matches with AP then we 2822 * will return true to indicate that we are good 2823 * to make connection with it. Else we will return false 2824 **/ 2825 static bool 2826 csr_is_pmf_capabilities_in_rsn_match(tHalHandle hHal, 2827 bool *pFilterMFPEnabled, 2828 uint8_t *pFilterMFPRequired, 2829 uint8_t *pFilterMFPCapable, 2830 tDot11fIERSN *pRSNIe) 2831 { 2832 uint8_t apProfileMFPCapable = 0; 2833 uint8_t apProfileMFPRequired = 0; 2834 if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable 2835 && pFilterMFPRequired) { 2836 /* Extracting MFPCapable bit from RSN Ie */ 2837 apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1; 2838 apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1; 2839 2840 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 2841 FL("pFilterMFPEnabled=%d pFilterMFPRequired=%d" 2842 "pFilterMFPCapable=%d apProfileMFPCapable=%d" 2843 "apProfileMFPRequired=%d"), 2844 *pFilterMFPEnabled, *pFilterMFPRequired, 2845 *pFilterMFPCapable, apProfileMFPCapable, 2846 apProfileMFPRequired); 2847 2848 if (*pFilterMFPEnabled && *pFilterMFPCapable 2849 && *pFilterMFPRequired && (apProfileMFPCapable == 0)) { 2850 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 2851 "AP is not capable to make PMF connection"); 2852 return false; 2853 } else if (!(*pFilterMFPCapable) && 2854 apProfileMFPCapable && apProfileMFPRequired) { 2855 2856 /* 2857 * In this case, AP with whom we trying to connect 2858 * requires mandatory PMF connections and we are not 2859 * capable so this AP is not good choice to connect 2860 */ 2861 QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO, 2862 "AP needs PMF connection and we are not capable of pmf connection"); 2863 return false; 2864 } 2865 } 2866 return true; 2867 } 2868 #endif 2869 2870 static bool csr_is_rsn_match(tHalHandle hHal, tCsrAuthList *pAuthType, 2871 eCsrEncryptionType enType, 2872 tCsrEncryptionList *pEnMcType, 2873 bool *pMFPEnabled, uint8_t *pMFPRequired, 2874 uint8_t *pMFPCapable, 2875 tDot11fBeaconIEs *pIes, 2876 eCsrAuthType *pNegotiatedAuthType, 2877 eCsrEncryptionType *pNegotiatedMCCipher) 2878 { 2879 bool fRSNMatch = false; 2880 2881 /* See if the cyphers in the Bss description match with the settings in the profile. */ 2882 fRSNMatch = 2883 csr_get_rsn_information(hHal, pAuthType, enType, pEnMcType, &pIes->RSN, 2884 NULL, NULL, NULL, NULL, pNegotiatedAuthType, 2885 pNegotiatedMCCipher); 2886 #ifdef WLAN_FEATURE_11W 2887 /* If all the filter matches then finally checks for PMF capabilities */ 2888 if (fRSNMatch) { 2889 fRSNMatch = csr_is_pmf_capabilities_in_rsn_match(hHal, pMFPEnabled, 2890 pMFPRequired, 2891 pMFPCapable, 2892 &pIes->RSN); 2893 } 2894 #endif 2895 return fRSNMatch; 2896 } 2897 2898 static bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId, 2899 uint8_t *pBSSId, uint8_t *pPMKId) 2900 { 2901 bool fRC = false, fMatchFound = false; 2902 uint32_t Index; 2903 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); 2904 2905 if (!pSession) { 2906 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId); 2907 return false; 2908 } 2909 2910 do { 2911 for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) { 2912 sms_log(pMac, LOG1, 2913 "match PMKID " MAC_ADDRESS_STR " to ", 2914 MAC_ADDR_ARRAY(pBSSId)); 2915 if (!qdf_mem_cmp 2916 (pBSSId, pSession->PmkidCacheInfo[Index].BSSID.bytes, 2917 sizeof(struct qdf_mac_addr))) { 2918 /* match found */ 2919 fMatchFound = true; 2920 break; 2921 } 2922 } 2923 2924 if (!fMatchFound) 2925 break; 2926 2927 qdf_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID, 2928 CSR_RSN_PMKID_SIZE); 2929 2930 fRC = true; 2931 } while (0); 2932 sms_log(pMac, LOGW, 2933 "csr_lookup_pmkid called return match = %d pMac->roam.NumPmkidCache = %d", 2934 fRC, pSession->NumPmkidCache); 2935 2936 return fRC; 2937 } 2938 2939 uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId, 2940 tCsrRoamProfile *pProfile, 2941 tSirBssDescription *pSirBssDesc, 2942 tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe) 2943 { 2944 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 2945 bool fRSNMatch; 2946 uint8_t cbRSNIe = 0; 2947 uint8_t UnicastCypher[CSR_RSN_OUI_SIZE]; 2948 uint8_t MulticastCypher[CSR_RSN_OUI_SIZE]; 2949 uint8_t AuthSuite[CSR_RSN_OUI_SIZE]; 2950 tCsrRSNAuthIe *pAuthSuite; 2951 tCsrRSNCapabilities RSNCapabilities; 2952 tCsrRSNPMKIe *pPMK; 2953 uint8_t PMKId[CSR_RSN_PMKID_SIZE]; 2954 #ifdef WLAN_FEATURE_11W 2955 uint8_t *pGroupMgmtCipherSuite; 2956 #endif 2957 tDot11fBeaconIEs *pIesLocal = pIes; 2958 eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; 2959 2960 sms_log(pMac, LOGW, "%s called...", __func__); 2961 2962 do { 2963 if (!csr_is_profile_rsn(pProfile)) 2964 break; 2965 2966 if (!pIesLocal 2967 && 2968 (!QDF_IS_STATUS_SUCCESS 2969 (csr_get_parsed_bss_description_ies 2970 (pMac, pSirBssDesc, &pIesLocal)))) { 2971 break; 2972 } 2973 /* See if the cyphers in the Bss description match with the settings in the profile. */ 2974 fRSNMatch = 2975 csr_get_rsn_information(hHal, &pProfile->AuthType, 2976 pProfile->negotiatedUCEncryptionType, 2977 &pProfile->mcEncryptionType, 2978 &pIesLocal->RSN, UnicastCypher, 2979 MulticastCypher, AuthSuite, 2980 &RSNCapabilities, &negAuthType, NULL); 2981 if (!fRSNMatch) 2982 break; 2983 2984 pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID; 2985 2986 pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED; 2987 2988 qdf_mem_copy(pRSNIe->MulticastOui, MulticastCypher, 2989 sizeof(MulticastCypher)); 2990 2991 pRSNIe->cUnicastCyphers = 1; 2992 2993 qdf_mem_copy(&pRSNIe->UnicastOui[0], UnicastCypher, 2994 sizeof(UnicastCypher)); 2995 2996 pAuthSuite = 2997 (tCsrRSNAuthIe *) (&pRSNIe-> 2998 UnicastOui[pRSNIe->cUnicastCyphers]); 2999 3000 pAuthSuite->cAuthenticationSuites = 1; 3001 qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite, 3002 sizeof(AuthSuite)); 3003 3004 /* RSN capabilities follows the Auth Suite (two octects) */ 3005 /* !!REVIEW - What should STA put in RSN capabilities, currently */ 3006 /* just putting back APs capabilities */ 3007 /* For one, we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability */ 3008 /* For another, we should use the Management Frame Protection values given by the supplicant */ 3009 RSNCapabilities.PreAuthSupported = 0; 3010 #ifdef WLAN_FEATURE_11W 3011 if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) { 3012 RSNCapabilities.MFPCapable = pProfile->MFPCapable; 3013 RSNCapabilities.MFPRequired = pProfile->MFPRequired; 3014 } else { 3015 RSNCapabilities.MFPCapable = 0; 3016 RSNCapabilities.MFPRequired = 0; 3017 } 3018 #endif 3019 *(uint16_t *) (&pAuthSuite->AuthOui[1]) = 3020 *((uint16_t *) (&RSNCapabilities)); 3021 3022 pPMK = 3023 (tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1])) + 3024 sizeof(uint16_t)); 3025 3026 /* Don't include the PMK SA IDs for CCKM associations. */ 3027 if ( 3028 #ifdef FEATURE_WLAN_ESE 3029 (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) && 3030 #endif 3031 csr_lookup_pmkid(pMac, sessionId, pSirBssDesc->bssId, 3032 &(PMKId[0]))) { 3033 pPMK->cPMKIDs = 1; 3034 3035 qdf_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId, 3036 CSR_RSN_PMKID_SIZE); 3037 } else { 3038 pPMK->cPMKIDs = 0; 3039 } 3040 3041 #ifdef WLAN_FEATURE_11W 3042 /* Advertise BIP in group cipher key management only if PMF is 3043 * enabled and AP is capable. 3044 */ 3045 if (pProfile->MFPEnabled && 3046 (RSNCapabilities.MFPCapable && pProfile->MFPCapable)) { 3047 pGroupMgmtCipherSuite = 3048 (uint8_t *) pPMK + sizeof(uint16_t) + 3049 (pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE); 3050 qdf_mem_copy(pGroupMgmtCipherSuite, csr_rsn_oui[07], 3051 CSR_WPA_OUI_SIZE); 3052 } 3053 #endif 3054 3055 /* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */ 3056 /* Add in the size of the Auth suite (count plus a single OUI) */ 3057 /* Add in the RSN caps field. */ 3058 /* Add PMKID count and PMKID (if any) */ 3059 /* Add group management cipher suite */ 3060 pRSNIe->IeHeader.Length = 3061 (uint8_t) (sizeof(*pRSNIe) - sizeof(pRSNIe->IeHeader) + 3062 sizeof(*pAuthSuite) + 3063 sizeof(tCsrRSNCapabilities)); 3064 if (pPMK->cPMKIDs) { 3065 pRSNIe->IeHeader.Length += (uint8_t) (sizeof(uint16_t) + 3066 (pPMK->cPMKIDs * 3067 CSR_RSN_PMKID_SIZE)); 3068 } 3069 #ifdef WLAN_FEATURE_11W 3070 if (pProfile->MFPEnabled && 3071 (RSNCapabilities.MFPCapable && pProfile->MFPCapable)) { 3072 if (0 == pPMK->cPMKIDs) 3073 pRSNIe->IeHeader.Length += sizeof(uint16_t); 3074 pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE; 3075 } 3076 #endif 3077 3078 /* return the size of the IE header (total) constructed... */ 3079 cbRSNIe = pRSNIe->IeHeader.Length + sizeof(pRSNIe->IeHeader); 3080 3081 } while (0); 3082 3083 if (!pIes && pIesLocal) { 3084 /* locally allocated */ 3085 qdf_mem_free(pIesLocal); 3086 } 3087 3088 return cbRSNIe; 3089 } 3090 3091 #ifdef FEATURE_WLAN_WAPI 3092 /** 3093 * csr_get_wapi_information() - to get WAPI infomation 3094 * @hal: pointer to HAL 3095 * @auth_type: auth type 3096 * @encr_type: encryption type 3097 * @mc_encryption: multicast encryption type 3098 * @wapi_ie: pointer to WAPI IE 3099 * @ucast_cipher: Unicast cipher 3100 * @mcast_cipher: Multicast cipher 3101 * @auth_suite: Authentication suite 3102 * @negotiated_authtype: Negotiated auth type 3103 * @negotiated_mccipher: negotiated multicast cipher 3104 * 3105 * This routine will get all WAPI information 3106 * 3107 * Return: bool 3108 */ 3109 static bool csr_get_wapi_information(tHalHandle hal, tCsrAuthList *auth_type, 3110 eCsrEncryptionType encr_type, 3111 tCsrEncryptionList *mc_encryption, 3112 tDot11fIEWAPI *wapi_ie, 3113 uint8_t *ucast_cipher, 3114 uint8_t *mcast_cipher, uint8_t *auth_suite, 3115 eCsrAuthType *negotiated_authtype, 3116 eCsrEncryptionType *negotiated_mccipher) 3117 { 3118 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 3119 bool acceptable_cipher = false; 3120 uint8_t c_ucast_cipher = 0; 3121 uint8_t c_mcast_cipher = 0; 3122 uint8_t c_auth_suites = 0, i; 3123 uint8_t unicast[CSR_WAPI_OUI_SIZE]; 3124 uint8_t multicast[CSR_WAPI_OUI_SIZE]; 3125 uint8_t authsuites[CSR_WAPI_MAX_AUTH_SUITES][CSR_WAPI_OUI_SIZE]; 3126 uint8_t authentication[CSR_WAPI_OUI_SIZE]; 3127 uint8_t mccipher_arr[CSR_WAPI_MAX_MULTICAST_CYPHERS][CSR_WAPI_OUI_SIZE]; 3128 eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; 3129 uint8_t wapioui_idx = 0; 3130 3131 if (!wapi_ie->present) 3132 goto end; 3133 3134 c_mcast_cipher++; 3135 qdf_mem_copy(mccipher_arr, wapi_ie->multicast_cipher_suite, 3136 CSR_WAPI_OUI_SIZE); 3137 c_ucast_cipher = (uint8_t) (wapi_ie->unicast_cipher_suite_count); 3138 c_auth_suites = (uint8_t) (wapi_ie->akm_suite_count); 3139 for (i = 0; i < c_auth_suites && i < CSR_WAPI_MAX_AUTH_SUITES; i++) 3140 qdf_mem_copy((void *)&authsuites[i], 3141 (void *)&wapi_ie->akm_suites[i], CSR_WAPI_OUI_SIZE); 3142 3143 wapioui_idx = csr_get_oui_index_from_cipher(encr_type); 3144 if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) { 3145 sms_log(mac_ctx, LOGE, 3146 FL("Wapi OUI index = %d out of limit"), 3147 wapioui_idx); 3148 acceptable_cipher = false; 3149 goto end; 3150 } 3151 /* Check - Is requested unicast Cipher supported by the BSS. */ 3152 acceptable_cipher = csr_match_wapi_oui_index(mac_ctx, 3153 wapi_ie->unicast_cipher_suites, 3154 c_ucast_cipher, wapioui_idx, unicast); 3155 if (!acceptable_cipher) 3156 goto end; 3157 3158 /* unicast is supported. Pick the first matching Group cipher, if any */ 3159 for (i = 0; i < mc_encryption->numEntries; i++) { 3160 wapioui_idx = csr_get_oui_index_from_cipher( 3161 mc_encryption->encryptionType[i]); 3162 if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) { 3163 sms_log(mac_ctx, LOGE, 3164 FL("Wapi OUI index = %d out of limit"), 3165 wapioui_idx); 3166 acceptable_cipher = false; 3167 break; 3168 } 3169 acceptable_cipher = csr_match_wapi_oui_index(mac_ctx, 3170 mccipher_arr, c_mcast_cipher, 3171 wapioui_idx, multicast); 3172 if (acceptable_cipher) 3173 break; 3174 } 3175 if (!acceptable_cipher) 3176 goto end; 3177 3178 if (negotiated_mccipher) 3179 *negotiated_mccipher = 3180 mc_encryption->encryptionType[i]; 3181 3182 /* 3183 * Ciphers are supported, Match authentication algorithm and 3184 * pick first matching authtype 3185 */ 3186 if (csr_is_auth_wapi_cert 3187 (mac_ctx, authsuites, c_auth_suites, authentication)) { 3188 neg_authtype = 3189 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; 3190 } else if (csr_is_auth_wapi_psk(mac_ctx, authsuites, 3191 c_auth_suites, authentication)) { 3192 neg_authtype = eCSR_AUTH_TYPE_WAPI_WAI_PSK; 3193 } else { 3194 acceptable_cipher = false; 3195 neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; 3196 } 3197 3198 /* Caller doesn't care about auth type, or BSS doesn't match */ 3199 if ((0 == auth_type->numEntries) || (false == acceptable_cipher)) 3200 goto end; 3201 3202 acceptable_cipher = false; 3203 for (i = 0; i < auth_type->numEntries; i++) { 3204 if (auth_type->authType[i] == neg_authtype) { 3205 acceptable_cipher = true; 3206 break; 3207 } 3208 } 3209 3210 end: 3211 if (acceptable_cipher) { 3212 if (mcast_cipher) 3213 qdf_mem_copy(mcast_cipher, multicast, 3214 CSR_WAPI_OUI_SIZE); 3215 if (ucast_cipher) 3216 qdf_mem_copy(ucast_cipher, unicast, CSR_WAPI_OUI_SIZE); 3217 if (auth_suite) 3218 qdf_mem_copy(auth_suite, authentication, 3219 CSR_WAPI_OUI_SIZE); 3220 if (negotiated_authtype) 3221 *negotiated_authtype = neg_authtype; 3222 } 3223 return acceptable_cipher; 3224 } 3225 3226 static bool csr_is_wapi_match(tHalHandle hHal, tCsrAuthList *pAuthType, 3227 eCsrEncryptionType enType, 3228 tCsrEncryptionList *pEnMcType, 3229 tDot11fBeaconIEs *pIes, 3230 eCsrAuthType *pNegotiatedAuthType, 3231 eCsrEncryptionType *pNegotiatedMCCipher) 3232 { 3233 bool fWapiMatch = false; 3234 3235 /* See if the cyphers in the Bss description match with the settings in the profile. */ 3236 fWapiMatch = 3237 csr_get_wapi_information(hHal, pAuthType, enType, pEnMcType, 3238 &pIes->WAPI, NULL, NULL, NULL, 3239 pNegotiatedAuthType, 3240 pNegotiatedMCCipher); 3241 3242 return fWapiMatch; 3243 } 3244 3245 static bool csr_lookup_bkid(tpAniSirGlobal pMac, uint32_t sessionId, 3246 uint8_t *pBSSId, uint8_t *pBKId) 3247 { 3248 bool fRC = false, fMatchFound = false; 3249 uint32_t Index; 3250 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); 3251 3252 if (!pSession) { 3253 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId); 3254 return false; 3255 } 3256 3257 do { 3258 for (Index = 0; Index < pSession->NumBkidCache; Index++) { 3259 sms_log(pMac, LOGW, "match BKID " MAC_ADDRESS_STR " to ", 3260 MAC_ADDR_ARRAY(pBSSId)); 3261 if (!qdf_mem_cmp 3262 (pBSSId, pSession->BkidCacheInfo[Index].BSSID.bytes, 3263 sizeof(struct qdf_mac_addr))) { 3264 /* match found */ 3265 fMatchFound = true; 3266 break; 3267 } 3268 } 3269 3270 if (!fMatchFound) 3271 break; 3272 3273 qdf_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID, 3274 CSR_WAPI_BKID_SIZE); 3275 3276 fRC = true; 3277 } while (0); 3278 sms_log(pMac, LOGW, 3279 "csr_lookup_bkid called return match = %d pMac->roam.NumBkidCache = %d", 3280 fRC, pSession->NumBkidCache); 3281 3282 return fRC; 3283 } 3284 3285 uint8_t csr_construct_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId, 3286 tCsrRoamProfile *pProfile, 3287 tSirBssDescription *pSirBssDesc, 3288 tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe) 3289 { 3290 bool fWapiMatch = false; 3291 uint8_t cbWapiIe = 0; 3292 uint8_t UnicastCypher[CSR_WAPI_OUI_SIZE]; 3293 uint8_t MulticastCypher[CSR_WAPI_OUI_SIZE]; 3294 uint8_t AuthSuite[CSR_WAPI_OUI_SIZE]; 3295 uint8_t BKId[CSR_WAPI_BKID_SIZE]; 3296 uint8_t *pWapi = NULL; 3297 bool fBKIDFound = false; 3298 tDot11fBeaconIEs *pIesLocal = pIes; 3299 3300 do { 3301 if (!csr_is_profile_wapi(pProfile)) 3302 break; 3303 3304 if (!pIesLocal 3305 && 3306 (!QDF_IS_STATUS_SUCCESS 3307 (csr_get_parsed_bss_description_ies 3308 (pMac, pSirBssDesc, &pIesLocal)))) { 3309 break; 3310 } 3311 /* See if the cyphers in the Bss description match with the settings in the profile. */ 3312 fWapiMatch = 3313 csr_get_wapi_information(pMac, &pProfile->AuthType, 3314 pProfile->negotiatedUCEncryptionType, 3315 &pProfile->mcEncryptionType, 3316 &pIesLocal->WAPI, UnicastCypher, 3317 MulticastCypher, AuthSuite, NULL, 3318 NULL); 3319 if (!fWapiMatch) 3320 break; 3321 3322 qdf_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0); 3323 3324 pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI; 3325 3326 pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED; 3327 3328 pWapiIe->cAuthenticationSuites = 1; 3329 qdf_mem_copy(&pWapiIe->AuthOui[0], AuthSuite, 3330 sizeof(AuthSuite)); 3331 3332 pWapi = (uint8_t *) (&pWapiIe->AuthOui[1]); 3333 3334 *pWapi = (uint16_t) 1; /* cUnicastCyphers */ 3335 pWapi += 2; 3336 qdf_mem_copy(pWapi, UnicastCypher, sizeof(UnicastCypher)); 3337 pWapi += sizeof(UnicastCypher); 3338 3339 qdf_mem_copy(pWapi, MulticastCypher, sizeof(MulticastCypher)); 3340 pWapi += sizeof(MulticastCypher); 3341 3342 /* WAPI capabilities follows the Auth Suite (two octects) */ 3343 /* we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability */ 3344 /* & since we already did a memset pWapiIe to 0, skip these fields */ 3345 pWapi += 2; 3346 3347 fBKIDFound = 3348 csr_lookup_bkid(pMac, sessionId, pSirBssDesc->bssId, 3349 &(BKId[0])); 3350 3351 if (fBKIDFound) { 3352 /* Do we need to change the endianness here */ 3353 *pWapi = (uint16_t) 1; /* cBKIDs */ 3354 pWapi += 2; 3355 qdf_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE); 3356 } else { 3357 *pWapi = 0; 3358 pWapi += 1; 3359 *pWapi = 0; 3360 pWapi += 1; 3361 } 3362 3363 /* Add in the IE fields except the IE header */ 3364 /* Add BKID count and BKID (if any) */ 3365 pWapiIe->IeHeader.Length = 3366 (uint8_t) (sizeof(*pWapiIe) - sizeof(pWapiIe->IeHeader)); 3367 3368 /*2 bytes for BKID Count field */ 3369 pWapiIe->IeHeader.Length += sizeof(uint16_t); 3370 3371 if (fBKIDFound) { 3372 pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE; 3373 } 3374 /* return the size of the IE header (total) constructed... */ 3375 cbWapiIe = pWapiIe->IeHeader.Length + sizeof(pWapiIe->IeHeader); 3376 3377 } while (0); 3378 3379 if (!pIes && pIesLocal) { 3380 /* locally allocated */ 3381 qdf_mem_free(pIesLocal); 3382 } 3383 3384 return cbWapiIe; 3385 } 3386 #endif /* FEATURE_WLAN_WAPI */ 3387 3388 /** 3389 * csr_get_wpa_cyphers() - to get WPA cipher info 3390 * @mac_ctx: pointer to mac context 3391 * @auth_type: auth type 3392 * @encr_type: encryption type 3393 * @mc_encryption: multicast encryption type 3394 * @wpa_ie: pointer to WPA IE 3395 * @ucast_cipher: Unicast cipher 3396 * @mcast_cipher: Multicast cipher 3397 * @auth_suite: Authentication suite 3398 * @negotiated_authtype: Negotiated auth type 3399 * @negotiated_mccipher: negotiated multicast cipher 3400 * 3401 * This routine will get all WPA information 3402 * 3403 * Return: bool 3404 */ 3405 static bool csr_get_wpa_cyphers(tpAniSirGlobal mac_ctx, tCsrAuthList *auth_type, 3406 eCsrEncryptionType encr_type, 3407 tCsrEncryptionList *mc_encryption, 3408 tDot11fIEWPA *wpa_ie, uint8_t *ucast_cipher, 3409 uint8_t *mcast_cipher, uint8_t *auth_suite, 3410 eCsrAuthType *negotiated_authtype, 3411 eCsrEncryptionType *negotiated_mccipher) 3412 { 3413 bool acceptable_cipher = false; 3414 uint8_t c_ucast_cipher = 0; 3415 uint8_t c_mcast_cipher = 0; 3416 uint8_t c_auth_suites = 0; 3417 uint8_t unicast[CSR_WPA_OUI_SIZE]; 3418 uint8_t multicast[CSR_WPA_OUI_SIZE]; 3419 uint8_t authentication[CSR_WPA_OUI_SIZE]; 3420 uint8_t mccipher_arr[1][CSR_WPA_OUI_SIZE]; 3421 uint8_t i; 3422 eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN; 3423 3424 if (!wpa_ie->present) 3425 goto end; 3426 c_mcast_cipher = 1; 3427 qdf_mem_copy(mccipher_arr, wpa_ie->multicast_cipher, CSR_WPA_OUI_SIZE); 3428 c_ucast_cipher = (uint8_t) (wpa_ie->unicast_cipher_count); 3429 c_auth_suites = (uint8_t) (wpa_ie->auth_suite_count); 3430 3431 /* Check - Is requested unicast Cipher supported by the BSS. */ 3432 acceptable_cipher = csr_match_wpaoui_index(mac_ctx, 3433 wpa_ie->unicast_ciphers, c_ucast_cipher, 3434 csr_get_oui_index_from_cipher(encr_type), 3435 unicast); 3436 if (!acceptable_cipher) 3437 goto end; 3438 /* unicast is supported. Pick the first matching Group cipher, if any */ 3439 for (i = 0; i < mc_encryption->numEntries; i++) { 3440 acceptable_cipher = csr_match_wpaoui_index(mac_ctx, 3441 mccipher_arr, c_mcast_cipher, 3442 csr_get_oui_index_from_cipher( 3443 mc_encryption->encryptionType[i]), 3444 multicast); 3445 if (acceptable_cipher) 3446 break; 3447 } 3448 if (!acceptable_cipher) 3449 goto end; 3450 3451 if (negotiated_mccipher) 3452 *negotiated_mccipher = mc_encryption->encryptionType[i]; 3453 3454 /* Initializing with false as it has true value already */ 3455 acceptable_cipher = false; 3456 for (i = 0; i < auth_type->numEntries; i++) { 3457 /* 3458 * Ciphers are supported, Match authentication algorithm and 3459 * pick first matching authtype 3460 */ 3461 if (csr_is_auth_wpa(mac_ctx, wpa_ie->auth_suites, c_auth_suites, 3462 authentication)) { 3463 if (eCSR_AUTH_TYPE_WPA == auth_type->authType[i]) 3464 neg_authtype = eCSR_AUTH_TYPE_WPA; 3465 } 3466 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) && 3467 csr_is_auth_wpa_psk(mac_ctx, 3468 wpa_ie->auth_suites, c_auth_suites, 3469 authentication)) { 3470 if (eCSR_AUTH_TYPE_WPA_PSK == auth_type->authType[i]) 3471 neg_authtype = eCSR_AUTH_TYPE_WPA_PSK; 3472 } 3473 #ifdef FEATURE_WLAN_ESE 3474 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) 3475 && csr_is_ese_cckm_auth_wpa(mac_ctx, 3476 wpa_ie->auth_suites, c_auth_suites, 3477 authentication)) { 3478 if (eCSR_AUTH_TYPE_CCKM_WPA == auth_type->authType[i]) 3479 neg_authtype = eCSR_AUTH_TYPE_CCKM_WPA; 3480 } 3481 #endif /* FEATURE_WLAN_ESE */ 3482 3483 /* 3484 * The 1st auth type in the APs WPA IE, to match stations 3485 * connecting profiles auth type will cause us to exit this 3486 * loop. This is added as some APs advertise multiple akms in 3487 * the WPA IE 3488 */ 3489 if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) { 3490 acceptable_cipher = true; 3491 break; 3492 } 3493 } 3494 3495 end: 3496 if (acceptable_cipher) { 3497 if (mcast_cipher) 3498 qdf_mem_copy((uint8_t **) mcast_cipher, multicast, 3499 CSR_WPA_OUI_SIZE); 3500 3501 if (ucast_cipher) 3502 qdf_mem_copy((uint8_t **) ucast_cipher, unicast, 3503 CSR_WPA_OUI_SIZE); 3504 3505 if (auth_suite) 3506 qdf_mem_copy((uint8_t **) auth_suite, authentication, 3507 CSR_WPA_OUI_SIZE); 3508 3509 if (negotiated_authtype) 3510 *negotiated_authtype = neg_authtype; 3511 } 3512 3513 return acceptable_cipher; 3514 } 3515 3516 static bool csr_is_wpa_encryption_match(tpAniSirGlobal pMac, 3517 tCsrAuthList *pAuthType, 3518 eCsrEncryptionType enType, 3519 tCsrEncryptionList *pEnMcType, 3520 tDot11fBeaconIEs *pIes, 3521 eCsrAuthType *pNegotiatedAuthtype, 3522 eCsrEncryptionType *pNegotiatedMCCipher) 3523 { 3524 bool fWpaMatch = false; 3525 3526 /* See if the cyphers in the Bss description match with the settings in the profile. */ 3527 fWpaMatch = 3528 csr_get_wpa_cyphers(pMac, pAuthType, enType, pEnMcType, &pIes->WPA, 3529 NULL, NULL, NULL, pNegotiatedAuthtype, 3530 pNegotiatedMCCipher); 3531 3532 return fWpaMatch; 3533 } 3534 3535 uint8_t csr_construct_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile, 3536 tSirBssDescription *pSirBssDesc, 3537 tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe) 3538 { 3539 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3540 bool fWpaMatch; 3541 uint8_t cbWpaIe = 0; 3542 uint8_t UnicastCypher[CSR_WPA_OUI_SIZE]; 3543 uint8_t MulticastCypher[CSR_WPA_OUI_SIZE]; 3544 uint8_t AuthSuite[CSR_WPA_OUI_SIZE]; 3545 tCsrWpaAuthIe *pAuthSuite; 3546 tDot11fBeaconIEs *pIesLocal = pIes; 3547 3548 do { 3549 if (!csr_is_profile_wpa(pProfile)) 3550 break; 3551 3552 if (!pIesLocal 3553 && 3554 (!QDF_IS_STATUS_SUCCESS 3555 (csr_get_parsed_bss_description_ies 3556 (pMac, pSirBssDesc, &pIesLocal)))) { 3557 break; 3558 } 3559 /* See if the cyphers in the Bss description match with the settings in the profile. */ 3560 fWpaMatch = 3561 csr_get_wpa_cyphers(hHal, &pProfile->AuthType, 3562 pProfile->negotiatedUCEncryptionType, 3563 &pProfile->mcEncryptionType, 3564 &pIesLocal->WPA, UnicastCypher, 3565 MulticastCypher, AuthSuite, NULL, NULL); 3566 if (!fWpaMatch) 3567 break; 3568 3569 pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID; 3570 3571 qdf_mem_copy(pWpaIe->Oui, csr_wpa_oui[01], sizeof(pWpaIe->Oui)); 3572 3573 pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED; 3574 3575 qdf_mem_copy(pWpaIe->MulticastOui, MulticastCypher, 3576 sizeof(MulticastCypher)); 3577 3578 pWpaIe->cUnicastCyphers = 1; 3579 3580 qdf_mem_copy(&pWpaIe->UnicastOui[0], UnicastCypher, 3581 sizeof(UnicastCypher)); 3582 3583 pAuthSuite = 3584 (tCsrWpaAuthIe *) (&pWpaIe-> 3585 UnicastOui[pWpaIe->cUnicastCyphers]); 3586 3587 pAuthSuite->cAuthenticationSuites = 1; 3588 qdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite, 3589 sizeof(AuthSuite)); 3590 3591 /* The WPA capabilities follows the Auth Suite (two octects)-- */ 3592 /* this field is optional, and we always "send" zero, so just */ 3593 /* remove it. This is consistent with our assumptions in the */ 3594 /* frames compiler; c.f. bug 15234: */ 3595 /* http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 */ 3596 3597 /* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */ 3598 /* Add in the size of the Auth suite (count plus a single OUI) */ 3599 pWpaIe->IeHeader.Length = 3600 sizeof(*pWpaIe) - sizeof(pWpaIe->IeHeader) + 3601 sizeof(*pAuthSuite); 3602 3603 /* return the size of the IE header (total) constructed... */ 3604 cbWpaIe = pWpaIe->IeHeader.Length + sizeof(pWpaIe->IeHeader); 3605 3606 } while (0); 3607 3608 if (!pIes && pIesLocal) { 3609 /* locally allocated */ 3610 qdf_mem_free(pIesLocal); 3611 } 3612 3613 return cbWpaIe; 3614 } 3615 3616 /* If a WPAIE exists in the profile, just use it. Or else construct one from the BSS */ 3617 /* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */ 3618 uint8_t csr_retrieve_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile, 3619 tSirBssDescription *pSirBssDesc, 3620 tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe) 3621 { 3622 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3623 uint8_t cbWpaIe = 0; 3624 3625 do { 3626 if (!csr_is_profile_wpa(pProfile)) 3627 break; 3628 if (pProfile->nWPAReqIELength && pProfile->pWPAReqIE) { 3629 if (SIR_MAC_WPA_IE_MAX_LENGTH >= 3630 pProfile->nWPAReqIELength) { 3631 cbWpaIe = (uint8_t) pProfile->nWPAReqIELength; 3632 qdf_mem_copy(pWpaIe, pProfile->pWPAReqIE, 3633 cbWpaIe); 3634 } else { 3635 sms_log(pMac, LOGW, 3636 " csr_retrieve_wpa_ie detect invalid WPA IE length (%d) ", 3637 pProfile->nWPAReqIELength); 3638 } 3639 } else { 3640 cbWpaIe = 3641 csr_construct_wpa_ie(pMac, pProfile, pSirBssDesc, pIes, 3642 pWpaIe); 3643 } 3644 } while (0); 3645 3646 return cbWpaIe; 3647 } 3648 3649 /* If a RSNIE exists in the profile, just use it. Or else construct one from the BSS */ 3650 /* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */ 3651 uint8_t csr_retrieve_rsn_ie(tHalHandle hHal, uint32_t sessionId, 3652 tCsrRoamProfile *pProfile, 3653 tSirBssDescription *pSirBssDesc, 3654 tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe) 3655 { 3656 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3657 uint8_t cbRsnIe = 0; 3658 3659 do { 3660 if (!csr_is_profile_rsn(pProfile)) 3661 break; 3662 if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) { 3663 /* If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from */ 3664 /* scratch. So it contains the current PMK-IDs */ 3665 cbRsnIe = 3666 csr_construct_rsn_ie(pMac, sessionId, pProfile, 3667 pSirBssDesc, pIes, pRsnIe); 3668 } else if (pProfile->nRSNReqIELength && pProfile->pRSNReqIE) { 3669 /* If you have one started away, re-use it. */ 3670 if (SIR_MAC_WPA_IE_MAX_LENGTH >= 3671 pProfile->nRSNReqIELength) { 3672 cbRsnIe = (uint8_t) pProfile->nRSNReqIELength; 3673 qdf_mem_copy(pRsnIe, pProfile->pRSNReqIE, 3674 cbRsnIe); 3675 } else { 3676 sms_log(pMac, LOGW, 3677 " csr_retrieve_rsn_ie detect invalid RSN IE length (%d) ", 3678 pProfile->nRSNReqIELength); 3679 } 3680 } else { 3681 cbRsnIe = 3682 csr_construct_rsn_ie(pMac, sessionId, pProfile, 3683 pSirBssDesc, pIes, pRsnIe); 3684 } 3685 } while (0); 3686 3687 return cbRsnIe; 3688 } 3689 3690 #ifdef FEATURE_WLAN_WAPI 3691 /* If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS */ 3692 /* Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE */ 3693 uint8_t csr_retrieve_wapi_ie(tHalHandle hHal, uint32_t sessionId, 3694 tCsrRoamProfile *pProfile, 3695 tSirBssDescription *pSirBssDesc, 3696 tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe) 3697 { 3698 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 3699 uint8_t cbWapiIe = 0; 3700 3701 do { 3702 if (!csr_is_profile_wapi(pProfile)) 3703 break; 3704 if (pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) { 3705 if (DOT11F_IE_WAPI_MAX_LEN >= 3706 pProfile->nWAPIReqIELength) { 3707 cbWapiIe = (uint8_t) pProfile->nWAPIReqIELength; 3708 qdf_mem_copy(pWapiIe, pProfile->pWAPIReqIE, 3709 cbWapiIe); 3710 } else { 3711 sms_log(pMac, LOGW, 3712 " csr_retrieve_wapi_ie detect invalid WAPI IE length (%d) ", 3713 pProfile->nWAPIReqIELength); 3714 } 3715 } else { 3716 cbWapiIe = 3717 csr_construct_wapi_ie(pMac, sessionId, pProfile, 3718 pSirBssDesc, pIes, pWapiIe); 3719 } 3720 } while (0); 3721 3722 return cbWapiIe; 3723 } 3724 #endif /* FEATURE_WLAN_WAPI */ 3725 3726 bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate) 3727 { 3728 bool fSupported = false; 3729 uint16_t nonBasicRate = 3730 (uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK)); 3731 3732 switch (nonBasicRate) { 3733 case eCsrSuppRate_1Mbps: 3734 case eCsrSuppRate_2Mbps: 3735 case eCsrSuppRate_5_5Mbps: 3736 case eCsrSuppRate_11Mbps: 3737 fSupported = true; 3738 break; 3739 3740 default: 3741 break; 3742 } 3743 3744 return fSupported; 3745 } 3746 3747 bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate) 3748 { 3749 bool fSupported = false; 3750 uint16_t nonBasicRate = 3751 (uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK)); 3752 3753 switch (nonBasicRate) { 3754 case eCsrSuppRate_6Mbps: 3755 case eCsrSuppRate_9Mbps: 3756 case eCsrSuppRate_12Mbps: 3757 case eCsrSuppRate_18Mbps: 3758 case eCsrSuppRate_24Mbps: 3759 case eCsrSuppRate_36Mbps: 3760 case eCsrSuppRate_48Mbps: 3761 case eCsrSuppRate_54Mbps: 3762 fSupported = true; 3763 break; 3764 3765 default: 3766 break; 3767 } 3768 3769 return fSupported; 3770 } 3771 3772 tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType) 3773 { 3774 tAniEdType edType; 3775 3776 switch (EncryptType) { 3777 default: 3778 case eCSR_ENCRYPT_TYPE_NONE: 3779 edType = eSIR_ED_NONE; 3780 break; 3781 3782 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: 3783 case eCSR_ENCRYPT_TYPE_WEP40: 3784 edType = eSIR_ED_WEP40; 3785 break; 3786 3787 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: 3788 case eCSR_ENCRYPT_TYPE_WEP104: 3789 edType = eSIR_ED_WEP104; 3790 break; 3791 3792 case eCSR_ENCRYPT_TYPE_TKIP: 3793 edType = eSIR_ED_TKIP; 3794 break; 3795 3796 case eCSR_ENCRYPT_TYPE_AES: 3797 edType = eSIR_ED_CCMP; 3798 break; 3799 #ifdef FEATURE_WLAN_WAPI 3800 case eCSR_ENCRYPT_TYPE_WPI: 3801 edType = eSIR_ED_WPI; 3802 break; 3803 #endif 3804 #ifdef WLAN_FEATURE_11W 3805 /* 11w BIP */ 3806 case eCSR_ENCRYPT_TYPE_AES_CMAC: 3807 edType = eSIR_ED_AES_128_CMAC; 3808 break; 3809 #endif 3810 } 3811 3812 return edType; 3813 } 3814 3815 /** 3816 * csr_validate_wep() - to validate wep 3817 * @uc_encry_type: unicast encryption type 3818 * @auth_list: Auth list 3819 * @mc_encryption_list: multicast encryption type 3820 * @negotiated_authtype: negotiated auth type 3821 * @negotiated_mc_encry: negotiated mc encry type 3822 * @bss_descr: BSS description 3823 * @ie_ptr: IE pointer 3824 * 3825 * This function just checks whether HDD is giving correct values for 3826 * Multicast cipher and Auth 3827 * 3828 * Return: bool 3829 */ 3830 static bool csr_validate_wep(tpAniSirGlobal mac_ctx, 3831 eCsrEncryptionType uc_encry_type, 3832 tCsrAuthList *auth_list, 3833 tCsrEncryptionList *mc_encryption_list, 3834 eCsrAuthType *negotiated_authtype, 3835 eCsrEncryptionType *negotiated_mc_encry, 3836 tSirBssDescription *bss_descr, 3837 tDot11fBeaconIEs *ie_ptr) 3838 { 3839 uint32_t idx; 3840 bool match = false; 3841 eCsrAuthType negotiated_auth = eCSR_AUTH_TYPE_OPEN_SYSTEM; 3842 eCsrEncryptionType negotiated_mccipher = eCSR_ENCRYPT_TYPE_UNKNOWN; 3843 3844 /* If privacy bit is not set, consider no match */ 3845 if (!csr_is_privacy(bss_descr)) 3846 goto end; 3847 3848 for (idx = 0; idx < mc_encryption_list->numEntries; idx++) { 3849 switch (mc_encryption_list->encryptionType[idx]) { 3850 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: 3851 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: 3852 case eCSR_ENCRYPT_TYPE_WEP40: 3853 case eCSR_ENCRYPT_TYPE_WEP104: 3854 /* 3855 * Multicast list may contain WEP40/WEP104. 3856 * Check whether it matches UC. 3857 */ 3858 if (uc_encry_type == 3859 mc_encryption_list->encryptionType[idx]) { 3860 match = true; 3861 negotiated_mccipher = 3862 mc_encryption_list->encryptionType[idx]; 3863 } 3864 break; 3865 default: 3866 match = false; 3867 break; 3868 } 3869 if (match) 3870 break; 3871 } 3872 3873 if (!match) 3874 goto end; 3875 3876 for (idx = 0; idx < auth_list->numEntries; idx++) { 3877 switch (auth_list->authType[idx]) { 3878 case eCSR_AUTH_TYPE_OPEN_SYSTEM: 3879 case eCSR_AUTH_TYPE_SHARED_KEY: 3880 case eCSR_AUTH_TYPE_AUTOSWITCH: 3881 match = true; 3882 negotiated_auth = auth_list->authType[idx]; 3883 break; 3884 default: 3885 match = false; 3886 } 3887 if (match) 3888 break; 3889 } 3890 3891 if (!match) 3892 goto end; 3893 3894 if (!ie_ptr) 3895 goto end; 3896 3897 /* 3898 * In case of WPA / WPA2, check whether it supports WEP as well. 3899 * Prepare the encryption type for WPA/WPA2 functions 3900 */ 3901 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == uc_encry_type) 3902 uc_encry_type = eCSR_ENCRYPT_TYPE_WEP40; 3903 else if (eCSR_ENCRYPT_TYPE_WEP104 == uc_encry_type) 3904 uc_encry_type = eCSR_ENCRYPT_TYPE_WEP104; 3905 3906 /* else we can use the encryption type directly */ 3907 if (ie_ptr->WPA.present) { 3908 match = (!qdf_mem_cmp(ie_ptr->WPA.multicast_cipher, 3909 csr_wpa_oui[csr_get_oui_index_from_cipher( 3910 uc_encry_type)], 3911 CSR_WPA_OUI_SIZE)); 3912 if (match) 3913 goto end; 3914 } 3915 if (ie_ptr->RSN.present) { 3916 match = (!qdf_mem_cmp(ie_ptr->RSN.gp_cipher_suite, 3917 csr_rsn_oui[csr_get_oui_index_from_cipher( 3918 uc_encry_type)], 3919 CSR_RSN_OUI_SIZE)); 3920 } 3921 3922 3923 end: 3924 if (match) { 3925 if (negotiated_authtype) 3926 *negotiated_authtype = negotiated_auth; 3927 if (negotiated_mc_encry) 3928 *negotiated_mc_encry = negotiated_mccipher; 3929 } 3930 return match; 3931 } 3932 3933 /** 3934 * csr_validate_open_none() - Check if the security is matching 3935 * @bss_desc: BSS Descriptor on which the check is done 3936 * @mc_enc_type: Multicast encryption type 3937 * @mc_cipher: Multicast Cipher 3938 * @auth_type: Authentication type 3939 * @neg_auth_type: Negotiated Auth type with the AP 3940 * 3941 * Return: Boolean value to tell if matched or not. 3942 */ 3943 static bool csr_validate_open_none(tSirBssDescription *bss_desc, 3944 tCsrEncryptionList *mc_enc_type, eCsrEncryptionType *mc_cipher, 3945 tCsrAuthList *auth_type, eCsrAuthType *neg_auth_type) 3946 { 3947 bool match; 3948 uint8_t idx; 3949 3950 /* 3951 * for NO encryption, if the Bss description has the 3952 * Privacy bit turned on, then encryption is required 3953 * so we have to reject this Bss. 3954 */ 3955 if (csr_is_privacy(bss_desc)) 3956 match = false; 3957 else 3958 match = true; 3959 if (match) { 3960 match = false; 3961 /* Check MC cipher and Auth type requested. */ 3962 for (idx = 0; idx < mc_enc_type->numEntries; idx++) { 3963 if (eCSR_ENCRYPT_TYPE_NONE == 3964 mc_enc_type->encryptionType[idx]) { 3965 match = true; 3966 *mc_cipher = mc_enc_type->encryptionType[idx]; 3967 break; 3968 } 3969 } 3970 if (!match) 3971 return match; 3972 3973 match = false; 3974 /* Check Auth list. It should contain AuthOpen. */ 3975 for (idx = 0; idx < auth_type->numEntries; idx++) { 3976 if ((eCSR_AUTH_TYPE_OPEN_SYSTEM == 3977 auth_type->authType[idx]) || 3978 (eCSR_AUTH_TYPE_AUTOSWITCH == 3979 auth_type->authType[idx])) { 3980 match = true; 3981 *neg_auth_type = 3982 eCSR_AUTH_TYPE_OPEN_SYSTEM; 3983 break; 3984 } 3985 } 3986 if (!match) 3987 return match; 3988 3989 } 3990 return match; 3991 } 3992 3993 /** 3994 * csr_validate_any_default() - Check if the security is matching 3995 * @hal: Global HAL handle 3996 * @auth_type: Authentication type 3997 * @mc_enc_type: Multicast encryption type 3998 * @mfp_enabled: Management frame protection feature 3999 * @mfp_required: Mangement frame protection mandatory 4000 * @mfp_capable: Device capable of MFP 4001 * @ies_ptr: Pointer to the IE fields 4002 * @neg_auth_type: Negotiated Auth type with the AP 4003 * @bss_desc: BSS Descriptor 4004 * @neg_uc_cipher: Negotiated unicast cipher suite 4005 * @neg_mc_cipher: Negotiated multicast cipher 4006 * 4007 * Return: Boolean value to tell if matched or not. 4008 */ 4009 static bool csr_validate_any_default(tHalHandle hal, tCsrAuthList *auth_type, 4010 tCsrEncryptionList *mc_enc_type, bool *mfp_enabled, 4011 uint8_t *mfp_required, uint8_t *mfp_capable, 4012 tDot11fBeaconIEs *ies_ptr, eCsrAuthType *neg_auth_type, 4013 tSirBssDescription *bss_desc, eCsrEncryptionType *uc_cipher, 4014 eCsrEncryptionType *mc_cipher) 4015 { 4016 bool match_any = false; 4017 bool match = true; 4018 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 4019 /* It is allowed to match anything. Try the more secured ones first. */ 4020 if (ies_ptr) { 4021 /* Check AES first */ 4022 *uc_cipher = eCSR_ENCRYPT_TYPE_AES; 4023 match_any = csr_is_rsn_match(hal, auth_type, 4024 *uc_cipher, mc_enc_type, mfp_enabled, 4025 mfp_required, mfp_capable, ies_ptr, 4026 neg_auth_type, mc_cipher); 4027 if (!match_any) { 4028 /* Check TKIP */ 4029 *uc_cipher = eCSR_ENCRYPT_TYPE_TKIP; 4030 match_any = csr_is_rsn_match(hal, auth_type, *uc_cipher, 4031 mc_enc_type, mfp_enabled, mfp_required, 4032 mfp_capable, ies_ptr, neg_auth_type, 4033 mc_cipher); 4034 } 4035 #ifdef FEATURE_WLAN_WAPI 4036 if (!match_any) { 4037 /* Check WAPI */ 4038 *uc_cipher = eCSR_ENCRYPT_TYPE_WPI; 4039 match_any = csr_is_wapi_match(hal, auth_type, 4040 *uc_cipher, mc_enc_type, ies_ptr, 4041 neg_auth_type, mc_cipher); 4042 } 4043 #endif 4044 } 4045 if (match_any) 4046 return match; 4047 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP104; 4048 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, 4049 neg_auth_type, mc_cipher, bss_desc, ies_ptr)) 4050 return match; 4051 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP40; 4052 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, 4053 neg_auth_type, mc_cipher, bss_desc, ies_ptr)) 4054 return match; 4055 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; 4056 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, 4057 neg_auth_type, mc_cipher, bss_desc, ies_ptr)) 4058 return match; 4059 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; 4060 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type, 4061 neg_auth_type, mc_cipher, bss_desc, ies_ptr)) 4062 return match; 4063 /* It must be open and no enc */ 4064 if (csr_is_privacy(bss_desc)) { 4065 match = false; 4066 return match; 4067 } 4068 4069 *neg_auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM; 4070 *mc_cipher = eCSR_ENCRYPT_TYPE_NONE; 4071 *uc_cipher = eCSR_ENCRYPT_TYPE_NONE; 4072 return match; 4073 4074 } 4075 4076 /** 4077 * csr_is_security_match() - Check if the security is matching 4078 * @hal: Global HAL handle 4079 * @auth_type: Authentication type 4080 * @uc_enc_type: Unicast Encryption type 4081 * @mc_enc_type: Multicast encryption type 4082 * @mfp_enabled: Management frame protection feature 4083 * @mfp_required: Mangement frame protection mandatory 4084 * @mfp_capable: Device capable of MFP 4085 * @bss_desc: BSS Descriptor 4086 * @ies_ptr: Pointer to the IE fields 4087 * @neg_auth_type: Negotiated Auth type with the AP 4088 * @neg_uc_cipher: Negotiated unicast cipher suite 4089 * @neg_mc_cipher: Negotiated multicast cipher 4090 * 4091 * Return: Boolean value to tell if matched or not. 4092 */ 4093 bool csr_is_security_match(tHalHandle hal, tCsrAuthList *auth_type, 4094 tCsrEncryptionList *uc_enc_type, 4095 tCsrEncryptionList *mc_enc_type, bool *mfp_enabled, 4096 uint8_t *mfp_required, uint8_t *mfp_capable, 4097 tSirBssDescription *bss_desc, tDot11fBeaconIEs *ies_ptr, 4098 eCsrAuthType *neg_auth_type, 4099 eCsrEncryptionType *neg_uc_cipher, 4100 eCsrEncryptionType *neg_mc_cipher) 4101 { 4102 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 4103 bool match = false; 4104 uint8_t i; 4105 eCsrEncryptionType mc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN; 4106 eCsrEncryptionType uc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN; 4107 eCsrAuthType local_neg_auth_type = eCSR_AUTH_TYPE_UNKNOWN; 4108 4109 for (i = 0; ((i < uc_enc_type->numEntries) && (!match)); i++) { 4110 uc_cipher = uc_enc_type->encryptionType[i]; 4111 /* 4112 * If the Bss description shows the Privacy bit is on, then we 4113 * must have some sort of encryption configured for the profile 4114 * to work. Don't attempt to join networks with Privacy bit 4115 * set when profiles say NONE for encryption type. 4116 */ 4117 switch (uc_cipher) { 4118 case eCSR_ENCRYPT_TYPE_NONE: 4119 match = csr_validate_open_none(bss_desc, mc_enc_type, 4120 &mc_cipher, auth_type, 4121 &local_neg_auth_type); 4122 break; 4123 4124 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: 4125 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: 4126 /* 4127 * !! might want to check for WEP keys set in the 4128 * Profile.... ? !! don't need to have the privacy bit 4129 * in the Bss description. Many AP policies make 4130 * legacy encryption 'optional' so we don't know if we 4131 * can associate or not. The AP will reject if 4132 * encryption is not allowed without the Privacy bit 4133 * turned on. 4134 */ 4135 match = csr_validate_wep(mac_ctx, uc_cipher, auth_type, 4136 mc_enc_type, &local_neg_auth_type, 4137 &mc_cipher, bss_desc, ies_ptr); 4138 4139 break; 4140 /* these are all of the WPA encryption types... */ 4141 case eCSR_ENCRYPT_TYPE_WEP40: 4142 case eCSR_ENCRYPT_TYPE_WEP104: 4143 match = csr_validate_wep(mac_ctx, uc_cipher, auth_type, 4144 mc_enc_type, &local_neg_auth_type, 4145 &mc_cipher, bss_desc, ies_ptr); 4146 break; 4147 4148 case eCSR_ENCRYPT_TYPE_TKIP: 4149 case eCSR_ENCRYPT_TYPE_AES: 4150 if (!ies_ptr) { 4151 match = false; 4152 break; 4153 } 4154 /* First check if there is a RSN match */ 4155 match = csr_is_rsn_match(mac_ctx, auth_type, 4156 uc_cipher, mc_enc_type, 4157 mfp_enabled, mfp_required, 4158 mfp_capable, ies_ptr, 4159 &local_neg_auth_type, 4160 &mc_cipher); 4161 /* If not RSN, then check WPA match */ 4162 if (!match) 4163 match = csr_is_wpa_encryption_match( 4164 mac_ctx, auth_type, 4165 uc_cipher, mc_enc_type, 4166 ies_ptr, 4167 &local_neg_auth_type, 4168 &mc_cipher); 4169 break; 4170 #ifdef FEATURE_WLAN_WAPI 4171 case eCSR_ENCRYPT_TYPE_WPI: /* WAPI */ 4172 if (ies_ptr) 4173 match = csr_is_wapi_match(hal, auth_type, 4174 uc_cipher, mc_enc_type, ies_ptr, 4175 &local_neg_auth_type, 4176 &mc_cipher); 4177 else 4178 match = false; 4179 break; 4180 #endif /* FEATURE_WLAN_WAPI */ 4181 case eCSR_ENCRYPT_TYPE_ANY: 4182 default: 4183 match = csr_validate_any_default(hal, auth_type, 4184 mc_enc_type, mfp_enabled, mfp_required, 4185 mfp_capable, ies_ptr, 4186 &local_neg_auth_type, bss_desc, 4187 &uc_cipher, &mc_cipher); 4188 break; 4189 } 4190 4191 } 4192 4193 if (match) { 4194 if (neg_uc_cipher) 4195 *neg_uc_cipher = uc_cipher; 4196 if (neg_mc_cipher) 4197 *neg_mc_cipher = mc_cipher; 4198 if (neg_auth_type) 4199 *neg_auth_type = local_neg_auth_type; 4200 } 4201 return match; 4202 } 4203 4204 bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len, 4205 uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired) 4206 { 4207 bool fMatch = false; 4208 4209 do { 4210 /* 4211 * Check for the specification of the Broadcast SSID at the 4212 * beginning of the list. If specified, then all SSIDs are 4213 * matches (broadcast SSID means accept all SSIDs). 4214 */ 4215 if (ssid1Len == 0) { 4216 fMatch = true; 4217 break; 4218 } 4219 4220 /* There are a few special cases. If the Bss description has a Broadcast SSID, */ 4221 /* then our Profile must have a single SSID without Wildcards so we can program */ 4222 /* the SSID. */ 4223 /* SSID could be suppressed in beacons. In that case SSID IE has valid length */ 4224 /* but the SSID value is all NULL characters. That condition is trated same */ 4225 /* as NULL SSID */ 4226 if (csr_is_nullssid(bssSsid, bssSsidLen)) { 4227 if (false == fSsidRequired) { 4228 fMatch = true; 4229 break; 4230 } 4231 } 4232 4233 if (ssid1Len != bssSsidLen) 4234 break; 4235 if (!qdf_mem_cmp(bssSsid, ssid1, bssSsidLen)) { 4236 fMatch = true; 4237 break; 4238 } 4239 4240 } while (0); 4241 4242 return fMatch; 4243 } 4244 4245 /* Null ssid means match */ 4246 bool csr_is_ssid_in_list(tHalHandle hHal, tSirMacSSid *pSsid, 4247 tCsrSSIDs *pSsidList) 4248 { 4249 bool fMatch = false; 4250 uint32_t i; 4251 4252 if (pSsidList && pSsid) { 4253 for (i = 0; i < pSsidList->numOfSSIDs; i++) { 4254 if (csr_is_nullssid 4255 (pSsidList->SSIDList[i].SSID.ssId, 4256 pSsidList->SSIDList[i].SSID.length) 4257 || 4258 ((pSsidList->SSIDList[i].SSID.length == 4259 pSsid->length) 4260 && (!qdf_mem_cmp(pSsid->ssId, 4261 pSsidList->SSIDList[i].SSID. 4262 ssId, pSsid->length)))) { 4263 fMatch = true; 4264 break; 4265 } 4266 } 4267 } 4268 4269 return fMatch; 4270 } 4271 4272 bool csr_is_bssid_match(tHalHandle hHal, struct qdf_mac_addr *pProfBssid, 4273 struct qdf_mac_addr *BssBssid) 4274 { 4275 bool fMatch = false; 4276 struct qdf_mac_addr ProfileBssid; 4277 4278 /* for efficiency of the MAC_ADDRESS functions, move the */ 4279 /* Bssid's into MAC_ADDRESS structs. */ 4280 qdf_mem_copy(&ProfileBssid, pProfBssid, sizeof(struct qdf_mac_addr)); 4281 4282 do { 4283 4284 /* Give the profile the benefit of the doubt... accept either all 0 or */ 4285 /* the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to */ 4286 /* match any Bssids). */ 4287 if (qdf_is_macaddr_zero(&ProfileBssid) || 4288 qdf_is_macaddr_broadcast(&ProfileBssid)) { 4289 fMatch = true; 4290 break; 4291 } 4292 4293 if (qdf_is_macaddr_equal(BssBssid, &ProfileBssid)) { 4294 fMatch = true; 4295 break; 4296 } 4297 4298 } while (0); 4299 4300 return fMatch; 4301 } 4302 4303 bool csr_is_bss_type_match(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2) 4304 { 4305 if ((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2) 4306 && (bssType1 != bssType2)) 4307 return false; 4308 else 4309 return true; 4310 } 4311 4312 bool csr_is_bss_type_ibss(eCsrRoamBssType bssType) 4313 { 4314 return (bool) 4315 (eCSR_BSS_TYPE_START_IBSS == bssType 4316 || eCSR_BSS_TYPE_IBSS == bssType); 4317 } 4318 4319 4320 static bool csr_is_bss_type_caps_match(eCsrRoamBssType bssType, 4321 tSirBssDescription *pSirBssDesc) 4322 { 4323 bool fMatch = true; 4324 4325 do { 4326 switch (bssType) { 4327 case eCSR_BSS_TYPE_ANY: 4328 break; 4329 4330 case eCSR_BSS_TYPE_INFRASTRUCTURE: 4331 if (!csr_is_infra_bss_desc(pSirBssDesc)) 4332 fMatch = false; 4333 break; 4334 4335 case eCSR_BSS_TYPE_IBSS: 4336 case eCSR_BSS_TYPE_START_IBSS: 4337 if (!csr_is_ibss_bss_desc(pSirBssDesc)) 4338 fMatch = false; 4339 4340 break; 4341 default: 4342 fMatch = false; 4343 break; 4344 } 4345 } while (0); 4346 4347 return fMatch; 4348 } 4349 4350 static bool csr_is_capabilities_match(tpAniSirGlobal pMac, eCsrRoamBssType bssType, 4351 tSirBssDescription *pSirBssDesc) 4352 { 4353 return csr_is_bss_type_caps_match(bssType, pSirBssDesc); 4354 } 4355 4356 static bool csr_is_specific_channel_match(tpAniSirGlobal pMac, 4357 tSirBssDescription *pSirBssDesc, 4358 uint8_t Channel) 4359 { 4360 bool fMatch = true; 4361 4362 do { 4363 /* if the channel is ANY, then always match... */ 4364 if (eCSR_OPERATING_CHANNEL_ANY == Channel) 4365 break; 4366 if (Channel == pSirBssDesc->channelId) 4367 break; 4368 4369 /* didn't match anything.. so return NO match */ 4370 fMatch = false; 4371 4372 } while (0); 4373 4374 return fMatch; 4375 } 4376 4377 static bool csr_is_channel_band_match(tpAniSirGlobal pMac, uint8_t channelId, 4378 tSirBssDescription *pSirBssDesc) 4379 { 4380 bool fMatch = true; 4381 4382 do { 4383 /* if the profile says Any channel AND the global settings says ANY channel, then we */ 4384 /* always match... */ 4385 if (eCSR_OPERATING_CHANNEL_ANY == channelId) 4386 break; 4387 4388 if (eCSR_OPERATING_CHANNEL_ANY != channelId) { 4389 fMatch = 4390 csr_is_specific_channel_match(pMac, pSirBssDesc, 4391 channelId); 4392 } 4393 4394 } while (0); 4395 4396 return fMatch; 4397 } 4398 4399 /** 4400 * csr_is_aggregate_rate_supported() - to check if aggregate rate is supported 4401 * @mac_ctx: pointer to mac context 4402 * @rate: A rate in units of 500kbps 4403 * 4404 * 4405 * The rate encoding is just as in 802.11 Information Elements, except 4406 * that the high bit is \em not interpreted as indicating a Basic Rate, 4407 * and proprietary rates are allowed, too. 4408 * 4409 * Note that if the adapter's dot11Mode is g, we don't restrict the 4410 * rates. According to hwReadEepromParameters, this will happen when: 4411 * ... the card is configured for ALL bands through the property 4412 * page. If this occurs, and the card is not an ABG card ,then this 4413 * code is setting the dot11Mode to assume the mode that the 4414 * hardware can support. For example, if the card is an 11BG card 4415 * and we are configured to support ALL bands, then we change the 4416 * dot11Mode to 11g because ALL in this case is only what the 4417 * hardware can support. 4418 * 4419 * Return: true if the adapter is currently capable of supporting this rate 4420 */ 4421 4422 static bool csr_is_aggregate_rate_supported(tpAniSirGlobal mac_ctx, 4423 uint16_t rate) 4424 { 4425 bool supported = false; 4426 uint16_t idx, new_rate; 4427 4428 /* In case basic rate flag is set */ 4429 new_rate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK); 4430 if (eCSR_CFG_DOT11_MODE_11A == 4431 mac_ctx->roam.configParam.uCfgDot11Mode) { 4432 switch (new_rate) { 4433 case eCsrSuppRate_6Mbps: 4434 case eCsrSuppRate_9Mbps: 4435 case eCsrSuppRate_12Mbps: 4436 case eCsrSuppRate_18Mbps: 4437 case eCsrSuppRate_24Mbps: 4438 case eCsrSuppRate_36Mbps: 4439 case eCsrSuppRate_48Mbps: 4440 case eCsrSuppRate_54Mbps: 4441 supported = true; 4442 break; 4443 default: 4444 supported = false; 4445 break; 4446 } 4447 4448 } else if (eCSR_CFG_DOT11_MODE_11B == 4449 mac_ctx->roam.configParam.uCfgDot11Mode) { 4450 switch (new_rate) { 4451 case eCsrSuppRate_1Mbps: 4452 case eCsrSuppRate_2Mbps: 4453 case eCsrSuppRate_5_5Mbps: 4454 case eCsrSuppRate_11Mbps: 4455 supported = true; 4456 break; 4457 default: 4458 supported = false; 4459 break; 4460 } 4461 } else if (!mac_ctx->roam.configParam.ProprietaryRatesEnabled) { 4462 4463 switch (new_rate) { 4464 case eCsrSuppRate_1Mbps: 4465 case eCsrSuppRate_2Mbps: 4466 case eCsrSuppRate_5_5Mbps: 4467 case eCsrSuppRate_6Mbps: 4468 case eCsrSuppRate_9Mbps: 4469 case eCsrSuppRate_11Mbps: 4470 case eCsrSuppRate_12Mbps: 4471 case eCsrSuppRate_18Mbps: 4472 case eCsrSuppRate_24Mbps: 4473 case eCsrSuppRate_36Mbps: 4474 case eCsrSuppRate_48Mbps: 4475 case eCsrSuppRate_54Mbps: 4476 supported = true; 4477 break; 4478 default: 4479 supported = false; 4480 break; 4481 } 4482 } else if (eCsrSuppRate_1Mbps == new_rate || 4483 eCsrSuppRate_2Mbps == new_rate || 4484 eCsrSuppRate_5_5Mbps == new_rate || 4485 eCsrSuppRate_11Mbps == new_rate) { 4486 supported = true; 4487 } else { 4488 idx = 0x1; 4489 4490 switch (new_rate) { 4491 case eCsrSuppRate_6Mbps: 4492 supported = g_phy_rates_suppt[0][idx]; 4493 break; 4494 case eCsrSuppRate_9Mbps: 4495 supported = g_phy_rates_suppt[1][idx]; 4496 break; 4497 case eCsrSuppRate_12Mbps: 4498 supported = g_phy_rates_suppt[2][idx]; 4499 break; 4500 case eCsrSuppRate_18Mbps: 4501 supported = g_phy_rates_suppt[3][idx]; 4502 break; 4503 case eCsrSuppRate_20Mbps: 4504 supported = g_phy_rates_suppt[4][idx]; 4505 break; 4506 case eCsrSuppRate_24Mbps: 4507 supported = g_phy_rates_suppt[5][idx]; 4508 break; 4509 case eCsrSuppRate_36Mbps: 4510 supported = g_phy_rates_suppt[6][idx]; 4511 break; 4512 case eCsrSuppRate_40Mbps: 4513 supported = g_phy_rates_suppt[7][idx]; 4514 break; 4515 case eCsrSuppRate_42Mbps: 4516 supported = g_phy_rates_suppt[8][idx]; 4517 break; 4518 case eCsrSuppRate_48Mbps: 4519 supported = g_phy_rates_suppt[9][idx]; 4520 break; 4521 case eCsrSuppRate_54Mbps: 4522 supported = g_phy_rates_suppt[10][idx]; 4523 break; 4524 case eCsrSuppRate_72Mbps: 4525 supported = g_phy_rates_suppt[11][idx]; 4526 break; 4527 case eCsrSuppRate_80Mbps: 4528 supported = g_phy_rates_suppt[12][idx]; 4529 break; 4530 case eCsrSuppRate_84Mbps: 4531 supported = g_phy_rates_suppt[13][idx]; 4532 break; 4533 case eCsrSuppRate_96Mbps: 4534 supported = g_phy_rates_suppt[14][idx]; 4535 break; 4536 case eCsrSuppRate_108Mbps: 4537 supported = g_phy_rates_suppt[15][idx]; 4538 break; 4539 case eCsrSuppRate_120Mbps: 4540 supported = g_phy_rates_suppt[16][idx]; 4541 break; 4542 case eCsrSuppRate_126Mbps: 4543 supported = g_phy_rates_suppt[17][idx]; 4544 break; 4545 case eCsrSuppRate_144Mbps: 4546 supported = g_phy_rates_suppt[18][idx]; 4547 break; 4548 case eCsrSuppRate_160Mbps: 4549 supported = g_phy_rates_suppt[19][idx]; 4550 break; 4551 case eCsrSuppRate_168Mbps: 4552 supported = g_phy_rates_suppt[20][idx]; 4553 break; 4554 case eCsrSuppRate_192Mbps: 4555 supported = g_phy_rates_suppt[21][idx]; 4556 break; 4557 case eCsrSuppRate_216Mbps: 4558 supported = g_phy_rates_suppt[22][idx]; 4559 break; 4560 case eCsrSuppRate_240Mbps: 4561 supported = g_phy_rates_suppt[23][idx]; 4562 break; 4563 default: 4564 supported = false; 4565 break; 4566 } 4567 } 4568 return supported; 4569 } 4570 4571 /** 4572 * csr_is_rate_set_match() - to check if rate set is matching 4573 * @mac_ctx: pointer to mac context 4574 * @bss_supported_rates: supported rates of BSS 4575 * @bss_ext_supp_rates: extended rates of bss 4576 * 4577 * This routine is to checke if rate set is matched or no 4578 * 4579 * Return: bool 4580 */ 4581 static bool csr_is_rate_set_match(tpAniSirGlobal mac_ctx, 4582 tDot11fIESuppRates *bss_supported_rates, 4583 tDot11fIEExtSuppRates *bss_ext_supp_rates) 4584 { 4585 bool match = true; 4586 uint32_t i; 4587 4588 /* 4589 * Validate that all of the Basic rates advertised in the Bss 4590 * description are supported 4591 */ 4592 if (bss_supported_rates) { 4593 for (i = 0; i < bss_supported_rates->num_rates; i++) { 4594 if (!CSR_IS_BASIC_RATE(bss_supported_rates->rates[i])) 4595 continue; 4596 if (!csr_is_aggregate_rate_supported(mac_ctx, 4597 bss_supported_rates->rates[i])) { 4598 match = false; 4599 break; 4600 } 4601 } 4602 } 4603 if (match && bss_ext_supp_rates) { 4604 for (i = 0; i < bss_ext_supp_rates->num_rates; i++) { 4605 if (!CSR_IS_BASIC_RATE(bss_ext_supp_rates->rates[i])) 4606 continue; 4607 if (!csr_is_aggregate_rate_supported(mac_ctx, 4608 bss_ext_supp_rates->rates[i])) { 4609 match = false; 4610 break; 4611 } 4612 } 4613 } 4614 return match; 4615 } 4616 4617 /** 4618 * csr_match_bss() - to compare the bss 4619 * @hal: pointer to hal context 4620 * @bss_descr: pointer bss description 4621 * @filter: scan filter 4622 * @neg_auth: negotiated auth 4623 * @neg_uc: negotiated for unicast 4624 * @neg_mc: negotiated for multicast 4625 * @ie_dblptr: double pointer to IE 4626 * 4627 * This routine will be called to match the bss 4628 * If caller want to get the *ie_dblptr allocated by this function, 4629 * pass in *ie_dblptr = NULL 4630 * 4631 * Return: bool 4632 */ 4633 bool csr_match_bss(tHalHandle hal, tSirBssDescription *bss_descr, 4634 tCsrScanResultFilter *filter, eCsrAuthType *neg_auth, 4635 eCsrEncryptionType *neg_uc, eCsrEncryptionType *neg_mc, 4636 tDot11fBeaconIEs **ie_dblptr) 4637 { 4638 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); 4639 bool rc = false, check, blacklist_check; 4640 uint32_t i; 4641 tDot11fBeaconIEs *ie_ptr = NULL; 4642 uint8_t *pb; 4643 struct roam_ext_params *roam_params; 4644 uint8_t *p2p_macaddr = NULL; 4645 4646 roam_params = &mac_ctx->roam.configParam.roam_params; 4647 if ((NULL == ie_dblptr) || (*ie_dblptr) == NULL) { 4648 /* If no IEs passed in, get our own. */ 4649 if (!QDF_IS_STATUS_SUCCESS( 4650 csr_get_parsed_bss_description_ies(mac_ctx, 4651 bss_descr, &ie_ptr))) { 4652 goto end; 4653 } 4654 } else { 4655 /* Save the one pass in for local use */ 4656 ie_ptr = *ie_dblptr; 4657 } 4658 4659 /* Check if caller wants P2P */ 4660 check = (!filter->p2pResult || ie_ptr->P2PBeaconProbeRes.present); 4661 if (!check) 4662 goto end; 4663 4664 /* Check for Blacklist BSSID's and avoid connections */ 4665 blacklist_check = false; 4666 for (i = 0; i < roam_params->num_bssid_avoid_list; i++) { 4667 if (qdf_is_macaddr_equal((struct qdf_mac_addr *) 4668 &roam_params->bssid_avoid_list[i], 4669 (struct qdf_mac_addr *)bss_descr->bssId)) { 4670 blacklist_check = true; 4671 break; 4672 } 4673 } 4674 if (blacklist_check) { 4675 sms_log(mac_ctx, LOGE, 4676 FL("Don't Attempt connect to blacklist bssid")); 4677 goto end; 4678 } 4679 4680 if (ie_ptr->SSID.present) { 4681 for (i = 0; i < filter->SSIDs.numOfSSIDs; i++) { 4682 check = csr_is_ssid_match(mac_ctx, 4683 filter->SSIDs.SSIDList[i].SSID.ssId, 4684 filter->SSIDs.SSIDList[i].SSID.length, 4685 ie_ptr->SSID.ssid, 4686 ie_ptr->SSID.num_ssid, true); 4687 if (check) 4688 break; 4689 } 4690 if (!check) 4691 goto end; 4692 } 4693 check = true; 4694 p2p_macaddr = ie_ptr->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress; 4695 for (i = 0; i < filter->BSSIDs.numOfBSSIDs; i++) { 4696 check = csr_is_bssid_match(mac_ctx, 4697 (struct qdf_mac_addr *)&filter->BSSIDs.bssid[i], 4698 (struct qdf_mac_addr *)bss_descr->bssId); 4699 if (check) 4700 break; 4701 4702 if (filter->p2pResult && ie_ptr->P2PBeaconProbeRes.present) { 4703 check = csr_is_bssid_match(mac_ctx, 4704 (struct qdf_mac_addr *) 4705 &filter->BSSIDs.bssid[i], 4706 (struct qdf_mac_addr *)p2p_macaddr); 4707 if (check) 4708 break; 4709 } 4710 } 4711 if (!check) 4712 goto end; 4713 4714 check = true; 4715 for (i = 0; i < filter->ChannelInfo.numOfChannels; i++) { 4716 check = csr_is_channel_band_match(mac_ctx, 4717 filter->ChannelInfo.ChannelList[i], bss_descr); 4718 if (check) 4719 break; 4720 } 4721 if (!check) 4722 goto end; 4723 /* If this is for measurement filtering */ 4724 if (filter->fMeasurement) { 4725 rc = true; 4726 goto end; 4727 } 4728 if (!csr_is_phy_mode_match(mac_ctx, filter->phyMode, bss_descr, 4729 NULL, NULL, ie_ptr)) 4730 goto end; 4731 4732 #ifdef WLAN_FEATURE_11W 4733 if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) && 4734 !csr_is_security_match(mac_ctx, &filter->authType, 4735 &filter->EncryptionType, 4736 &filter->mcEncryptionType, 4737 &filter->MFPEnabled, 4738 &filter->MFPRequired, 4739 &filter->MFPCapable, 4740 bss_descr, ie_ptr, neg_auth, 4741 neg_uc, neg_mc)) 4742 #else 4743 if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) && 4744 !csr_is_security_match(mac_ctx, &filter->authType, 4745 &filter->EncryptionType, 4746 &filter->mcEncryptionType, 4747 NULL, NULL, NULL, 4748 bss_descr, ie_ptr, neg_auth, 4749 neg_uc, neg_mc)) 4750 #endif 4751 goto end; 4752 if (!csr_is_capabilities_match(mac_ctx, filter->BSSType, bss_descr)) 4753 goto end; 4754 if (!csr_is_rate_set_match(mac_ctx, &ie_ptr->SuppRates, 4755 &ie_ptr->ExtSuppRates)) 4756 goto end; 4757 if ((eCsrRoamWmmQbssOnly == mac_ctx->roam.configParam.WMMSupportMode) 4758 && !CSR_IS_QOS_BSS(ie_ptr)) 4759 goto end; 4760 /* 4761 * Check country. check even when pb is NULL because we may 4762 * want to make sure 4763 */ 4764 pb = (filter->countryCode[0]) ? (filter->countryCode) : NULL; 4765 check = csr_match_country_code(mac_ctx, pb, ie_ptr); 4766 if (!check) 4767 goto end; 4768 4769 if (filter->MDID.mdiePresent && csr_roam_is11r_assoc(mac_ctx, 4770 mac_ctx->roam.roamSession->sessionId)) { 4771 if (bss_descr->mdiePresent) { 4772 if (filter->MDID.mobilityDomain != 4773 (bss_descr->mdie[1] << 8 | 4774 bss_descr->mdie[0])) 4775 goto end; 4776 } else { 4777 goto end; 4778 } 4779 } 4780 rc = true; 4781 4782 end: 4783 if (ie_dblptr) 4784 *ie_dblptr = ie_ptr; 4785 else if (ie_ptr) 4786 qdf_mem_free(ie_ptr); 4787 return rc; 4788 } 4789 4790 static bool csr_match_connected_bss_security(tpAniSirGlobal pMac, 4791 tCsrRoamConnectedProfile *pProfile, 4792 tSirBssDescription *pBssDesc, 4793 tDot11fBeaconIEs *pIes) 4794 { 4795 tCsrEncryptionList ucEncryptionList, mcEncryptionList; 4796 tCsrAuthList authList; 4797 4798 ucEncryptionList.numEntries = 1; 4799 ucEncryptionList.encryptionType[0] = pProfile->EncryptionType; 4800 4801 mcEncryptionList.numEntries = 1; 4802 mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType; 4803 4804 authList.numEntries = 1; 4805 authList.authType[0] = pProfile->AuthType; 4806 4807 #ifdef WLAN_FEATURE_11W 4808 return csr_is_security_match(pMac, &authList, &ucEncryptionList, 4809 &mcEncryptionList, 4810 &pProfile->MFPEnabled, 4811 &pProfile->MFPRequired, 4812 &pProfile->MFPCapable, 4813 pBssDesc, pIes, NULL, NULL, NULL); 4814 #else 4815 return csr_is_security_match(pMac, &authList, &ucEncryptionList, 4816 &mcEncryptionList, NULL, NULL, NULL, 4817 pBssDesc, pIes, NULL, NULL, NULL); 4818 #endif 4819 4820 } 4821 4822 bool csr_match_bss_to_connect_profile(tHalHandle hHal, 4823 tCsrRoamConnectedProfile *pProfile, 4824 tSirBssDescription *pBssDesc, 4825 tDot11fBeaconIEs *pIes) 4826 { 4827 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 4828 bool fRC = false, fCheck; 4829 tDot11fBeaconIEs *pIesLocal = pIes; 4830 4831 do { 4832 if (!pIes) { 4833 if (!QDF_IS_STATUS_SUCCESS 4834 (csr_get_parsed_bss_description_ies 4835 (pMac, pBssDesc, &pIesLocal))) { 4836 break; 4837 } 4838 } 4839 fCheck = true; 4840 if (pIesLocal->SSID.present) { 4841 bool fCheckSsid = false; 4842 if (pProfile->SSID.length) { 4843 fCheckSsid = true; 4844 } 4845 fCheck = 4846 csr_is_ssid_match(pMac, pProfile->SSID.ssId, 4847 pProfile->SSID.length, 4848 pIesLocal->SSID.ssid, 4849 pIesLocal->SSID.num_ssid, 4850 fCheckSsid); 4851 if (!fCheck) 4852 break; 4853 } 4854 if (!csr_match_connected_bss_security 4855 (pMac, pProfile, pBssDesc, pIesLocal)) 4856 break; 4857 if (!csr_is_capabilities_match(pMac, pProfile->BSSType, pBssDesc)) 4858 break; 4859 if (!csr_is_rate_set_match 4860 (pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates)) 4861 break; 4862 fCheck = 4863 csr_is_channel_band_match(pMac, pProfile->operationChannel, 4864 pBssDesc); 4865 if (!fCheck) 4866 break; 4867 4868 fRC = true; 4869 4870 } while (0); 4871 4872 if (!pIes && pIesLocal) { 4873 /* locally allocated */ 4874 qdf_mem_free(pIesLocal); 4875 } 4876 4877 return fRC; 4878 } 4879 4880 void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap) 4881 { 4882 uint16_t rateBitmap; 4883 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK); 4884 rateBitmap = *pRateBitmap; 4885 switch (n) { 4886 case SIR_MAC_RATE_1: 4887 rateBitmap |= SIR_MAC_RATE_1_BITMAP; 4888 break; 4889 case SIR_MAC_RATE_2: 4890 rateBitmap |= SIR_MAC_RATE_2_BITMAP; 4891 break; 4892 case SIR_MAC_RATE_5_5: 4893 rateBitmap |= SIR_MAC_RATE_5_5_BITMAP; 4894 break; 4895 case SIR_MAC_RATE_11: 4896 rateBitmap |= SIR_MAC_RATE_11_BITMAP; 4897 break; 4898 case SIR_MAC_RATE_6: 4899 rateBitmap |= SIR_MAC_RATE_6_BITMAP; 4900 break; 4901 case SIR_MAC_RATE_9: 4902 rateBitmap |= SIR_MAC_RATE_9_BITMAP; 4903 break; 4904 case SIR_MAC_RATE_12: 4905 rateBitmap |= SIR_MAC_RATE_12_BITMAP; 4906 break; 4907 case SIR_MAC_RATE_18: 4908 rateBitmap |= SIR_MAC_RATE_18_BITMAP; 4909 break; 4910 case SIR_MAC_RATE_24: 4911 rateBitmap |= SIR_MAC_RATE_24_BITMAP; 4912 break; 4913 case SIR_MAC_RATE_36: 4914 rateBitmap |= SIR_MAC_RATE_36_BITMAP; 4915 break; 4916 case SIR_MAC_RATE_48: 4917 rateBitmap |= SIR_MAC_RATE_48_BITMAP; 4918 break; 4919 case SIR_MAC_RATE_54: 4920 rateBitmap |= SIR_MAC_RATE_54_BITMAP; 4921 break; 4922 } 4923 *pRateBitmap = rateBitmap; 4924 } 4925 4926 bool csr_check_rate_bitmap(uint8_t rate, uint16_t rateBitmap) 4927 { 4928 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK); 4929 4930 switch (n) { 4931 case SIR_MAC_RATE_1: 4932 rateBitmap &= SIR_MAC_RATE_1_BITMAP; 4933 break; 4934 case SIR_MAC_RATE_2: 4935 rateBitmap &= SIR_MAC_RATE_2_BITMAP; 4936 break; 4937 case SIR_MAC_RATE_5_5: 4938 rateBitmap &= SIR_MAC_RATE_5_5_BITMAP; 4939 break; 4940 case SIR_MAC_RATE_11: 4941 rateBitmap &= SIR_MAC_RATE_11_BITMAP; 4942 break; 4943 case SIR_MAC_RATE_6: 4944 rateBitmap &= SIR_MAC_RATE_6_BITMAP; 4945 break; 4946 case SIR_MAC_RATE_9: 4947 rateBitmap &= SIR_MAC_RATE_9_BITMAP; 4948 break; 4949 case SIR_MAC_RATE_12: 4950 rateBitmap &= SIR_MAC_RATE_12_BITMAP; 4951 break; 4952 case SIR_MAC_RATE_18: 4953 rateBitmap &= SIR_MAC_RATE_18_BITMAP; 4954 break; 4955 case SIR_MAC_RATE_24: 4956 rateBitmap &= SIR_MAC_RATE_24_BITMAP; 4957 break; 4958 case SIR_MAC_RATE_36: 4959 rateBitmap &= SIR_MAC_RATE_36_BITMAP; 4960 break; 4961 case SIR_MAC_RATE_48: 4962 rateBitmap &= SIR_MAC_RATE_48_BITMAP; 4963 break; 4964 case SIR_MAC_RATE_54: 4965 rateBitmap &= SIR_MAC_RATE_54_BITMAP; 4966 break; 4967 } 4968 return !!rateBitmap; 4969 } 4970 4971 bool csr_rates_is_dot11_rate_supported(tHalHandle hHal, uint8_t rate) 4972 { 4973 tpAniSirGlobal pMac = PMAC_STRUCT(hHal); 4974 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK); 4975 4976 return csr_is_aggregate_rate_supported(pMac, n); 4977 } 4978 4979 static uint16_t csr_rates_mac_prop_to_dot11(uint16_t Rate) 4980 { 4981 uint16_t ConvertedRate = Rate; 4982 4983 switch (Rate) { 4984 case SIR_MAC_RATE_1: 4985 ConvertedRate = 2; 4986 break; 4987 case SIR_MAC_RATE_2: 4988 ConvertedRate = 4; 4989 break; 4990 case SIR_MAC_RATE_5_5: 4991 ConvertedRate = 11; 4992 break; 4993 case SIR_MAC_RATE_11: 4994 ConvertedRate = 22; 4995 break; 4996 4997 case SIR_MAC_RATE_6: 4998 ConvertedRate = 12; 4999 break; 5000 case SIR_MAC_RATE_9: 5001 ConvertedRate = 18; 5002 break; 5003 case SIR_MAC_RATE_12: 5004 ConvertedRate = 24; 5005 break; 5006 case SIR_MAC_RATE_18: 5007 ConvertedRate = 36; 5008 break; 5009 case SIR_MAC_RATE_24: 5010 ConvertedRate = 48; 5011 break; 5012 case SIR_MAC_RATE_36: 5013 ConvertedRate = 72; 5014 break; 5015 case SIR_MAC_RATE_42: 5016 ConvertedRate = 84; 5017 break; 5018 case SIR_MAC_RATE_48: 5019 ConvertedRate = 96; 5020 break; 5021 case SIR_MAC_RATE_54: 5022 ConvertedRate = 108; 5023 break; 5024 5025 case SIR_MAC_RATE_72: 5026 ConvertedRate = 144; 5027 break; 5028 case SIR_MAC_RATE_84: 5029 ConvertedRate = 168; 5030 break; 5031 case SIR_MAC_RATE_96: 5032 ConvertedRate = 192; 5033 break; 5034 case SIR_MAC_RATE_108: 5035 ConvertedRate = 216; 5036 break; 5037 case SIR_MAC_RATE_126: 5038 ConvertedRate = 252; 5039 break; 5040 case SIR_MAC_RATE_144: 5041 ConvertedRate = 288; 5042 break; 5043 case SIR_MAC_RATE_168: 5044 ConvertedRate = 336; 5045 break; 5046 case SIR_MAC_RATE_192: 5047 ConvertedRate = 384; 5048 break; 5049 case SIR_MAC_RATE_216: 5050 ConvertedRate = 432; 5051 break; 5052 case SIR_MAC_RATE_240: 5053 ConvertedRate = 480; 5054 break; 5055 5056 case 0xff: 5057 ConvertedRate = 0; 5058 break; 5059 } 5060 5061 return ConvertedRate; 5062 } 5063 5064 uint16_t csr_rates_find_best_rate(tSirMacRateSet *pSuppRates, 5065 tSirMacRateSet *pExtRates, 5066 tSirMacPropRateSet *pPropRates) 5067 { 5068 uint8_t i; 5069 uint16_t nBest; 5070 5071 nBest = pSuppRates->rate[0] & (~CSR_DOT11_BASIC_RATE_MASK); 5072 5073 if (pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX) { 5074 pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX; 5075 } 5076 5077 for (i = 1U; i < pSuppRates->numRates; ++i) { 5078 nBest = 5079 (uint16_t) CSR_MAX(nBest, 5080 pSuppRates-> 5081 rate[i] & (~CSR_DOT11_BASIC_RATE_MASK)); 5082 } 5083 5084 if (NULL != pExtRates) { 5085 for (i = 0U; i < pExtRates->numRates; ++i) { 5086 nBest = 5087 (uint16_t) CSR_MAX(nBest, 5088 pExtRates-> 5089 rate[i] & 5090 (~CSR_DOT11_BASIC_RATE_MASK)); 5091 } 5092 } 5093 5094 if (NULL != pPropRates) { 5095 for (i = 0U; i < pPropRates->numPropRates; ++i) { 5096 nBest = 5097 (uint16_t) CSR_MAX(nBest, 5098 csr_rates_mac_prop_to_dot11 5099 (pPropRates->propRate[i])); 5100 } 5101 } 5102 5103 return nBest; 5104 } 5105 5106 void csr_release_profile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile) 5107 { 5108 if (pProfile) { 5109 if (pProfile->BSSIDs.bssid) { 5110 qdf_mem_free(pProfile->BSSIDs.bssid); 5111 pProfile->BSSIDs.bssid = NULL; 5112 } 5113 if (pProfile->SSIDs.SSIDList) { 5114 qdf_mem_free(pProfile->SSIDs.SSIDList); 5115 pProfile->SSIDs.SSIDList = NULL; 5116 } 5117 if (pProfile->pWPAReqIE) { 5118 qdf_mem_free(pProfile->pWPAReqIE); 5119 pProfile->pWPAReqIE = NULL; 5120 } 5121 if (pProfile->pRSNReqIE) { 5122 qdf_mem_free(pProfile->pRSNReqIE); 5123 pProfile->pRSNReqIE = NULL; 5124 } 5125 #ifdef FEATURE_WLAN_WAPI 5126 if (pProfile->pWAPIReqIE) { 5127 qdf_mem_free(pProfile->pWAPIReqIE); 5128 pProfile->pWAPIReqIE = NULL; 5129 } 5130 #endif /* FEATURE_WLAN_WAPI */ 5131 5132 if (pProfile->pAddIEScan) { 5133 qdf_mem_free(pProfile->pAddIEScan); 5134 pProfile->pAddIEScan = NULL; 5135 } 5136 5137 if (pProfile->pAddIEAssoc) { 5138 qdf_mem_free(pProfile->pAddIEAssoc); 5139 pProfile->pAddIEAssoc = NULL; 5140 } 5141 if (pProfile->ChannelInfo.ChannelList) { 5142 qdf_mem_free(pProfile->ChannelInfo.ChannelList); 5143 pProfile->ChannelInfo.ChannelList = NULL; 5144 } 5145 qdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); 5146 } 5147 } 5148 5149 void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter) 5150 { 5151 if (pScanFilter->BSSIDs.bssid) { 5152 qdf_mem_free(pScanFilter->BSSIDs.bssid); 5153 pScanFilter->BSSIDs.bssid = NULL; 5154 } 5155 if (pScanFilter->ChannelInfo.ChannelList) { 5156 qdf_mem_free(pScanFilter->ChannelInfo.ChannelList); 5157 pScanFilter->ChannelInfo.ChannelList = NULL; 5158 } 5159 if (pScanFilter->SSIDs.SSIDList) { 5160 qdf_mem_free(pScanFilter->SSIDs.SSIDList); 5161 pScanFilter->SSIDs.SSIDList = NULL; 5162 } 5163 } 5164 5165 void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId) 5166 { 5167 tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; 5168 5169 if (pSession->pCurRoamProfile) { 5170 csr_release_profile(pMac, pSession->pCurRoamProfile); 5171 qdf_mem_free(pSession->pCurRoamProfile); 5172 pSession->pCurRoamProfile = NULL; 5173 } 5174 } 5175 5176 void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId) 5177 { 5178 tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; 5179 5180 if (pSession->pConnectBssDesc) { 5181 qdf_mem_free(pSession->pConnectBssDesc); 5182 pSession->pConnectBssDesc = NULL; 5183 } 5184 } 5185 5186 tSirResultCodes csr_get_disassoc_rsp_status_code(tSirSmeDisassocRsp * 5187 pSmeDisassocRsp) 5188 { 5189 uint8_t *pBuffer = (uint8_t *) pSmeDisassocRsp; 5190 uint32_t ret; 5191 5192 pBuffer += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(tSirMacAddr)); 5193 /* tSirResultCodes is an enum, assuming is 32bit */ 5194 /* If we cannot make this assumption, use copymemory */ 5195 qdf_get_u32(pBuffer, &ret); 5196 5197 return (tSirResultCodes) ret; 5198 } 5199 5200 tSirResultCodes csr_get_de_auth_rsp_status_code(tSirSmeDeauthRsp *pSmeRsp) 5201 { 5202 uint8_t *pBuffer = (uint8_t *) pSmeRsp; 5203 uint32_t ret; 5204 5205 pBuffer += 5206 (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t) + 5207 sizeof(uint16_t)); 5208 /* tSirResultCodes is an enum, assuming is 32bit */ 5209 /* If we cannot make this assumption, use copymemory */ 5210 qdf_get_u32(pBuffer, &ret); 5211 5212 return (tSirResultCodes) ret; 5213 } 5214 5215 tSirScanType csr_get_scan_type(tpAniSirGlobal pMac, uint8_t chnId) 5216 { 5217 tSirScanType scanType = eSIR_PASSIVE_SCAN; 5218 enum channel_state channelEnabledType; 5219 5220 channelEnabledType = cds_get_channel_state(chnId); 5221 if (CHANNEL_STATE_ENABLE == channelEnabledType) { 5222 scanType = eSIR_ACTIVE_SCAN; 5223 } 5224 return scanType; 5225 } 5226 5227 uint8_t csr_to_upper(uint8_t ch) 5228 { 5229 uint8_t chOut; 5230 5231 if (ch >= 'a' && ch <= 'z') { 5232 chOut = ch - 'a' + 'A'; 5233 } else { 5234 chOut = ch; 5235 } 5236 return chOut; 5237 } 5238 5239 tSirBssType csr_translate_bsstype_to_mac_type(eCsrRoamBssType csrtype) 5240 { 5241 tSirBssType ret; 5242 5243 switch (csrtype) { 5244 case eCSR_BSS_TYPE_INFRASTRUCTURE: 5245 ret = eSIR_INFRASTRUCTURE_MODE; 5246 break; 5247 case eCSR_BSS_TYPE_IBSS: 5248 case eCSR_BSS_TYPE_START_IBSS: 5249 ret = eSIR_IBSS_MODE; 5250 break; 5251 case eCSR_BSS_TYPE_INFRA_AP: 5252 ret = eSIR_INFRA_AP_MODE; 5253 break; 5254 case eCSR_BSS_TYPE_NDI: 5255 ret = eSIR_NDI_MODE; 5256 break; 5257 case eCSR_BSS_TYPE_ANY: 5258 default: 5259 ret = eSIR_AUTO_MODE; 5260 break; 5261 } 5262 5263 return ret; 5264 } 5265 5266 /* This function use the parameters to decide the CFG value. */ 5267 /* CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG */ 5268 /* So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value */ 5269 eCsrCfgDot11Mode csr_get_cfg_dot11_mode_from_csr_phy_mode(tCsrRoamProfile *pProfile, 5270 eCsrPhyMode phyMode, 5271 bool fProprietary) 5272 { 5273 uint32_t cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG; 5274 5275 switch (phyMode) { 5276 case eCSR_DOT11_MODE_11a: 5277 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; 5278 break; 5279 case eCSR_DOT11_MODE_11b: 5280 case eCSR_DOT11_MODE_11b_ONLY: 5281 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; 5282 break; 5283 case eCSR_DOT11_MODE_11g: 5284 case eCSR_DOT11_MODE_11g_ONLY: 5285 if (pProfile && (CSR_IS_INFRA_AP(pProfile)) 5286 && (phyMode == eCSR_DOT11_MODE_11g_ONLY)) 5287 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY; 5288 else 5289 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; 5290 break; 5291 case eCSR_DOT11_MODE_11n: 5292 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 5293 break; 5294 case eCSR_DOT11_MODE_11n_ONLY: 5295 if (pProfile && CSR_IS_INFRA_AP(pProfile)) 5296 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY; 5297 else 5298 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 5299 break; 5300 case eCSR_DOT11_MODE_abg: 5301 cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG; 5302 break; 5303 case eCSR_DOT11_MODE_AUTO: 5304 cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO; 5305 break; 5306 5307 case eCSR_DOT11_MODE_11ac: 5308 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 5309 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; 5310 } else { 5311 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 5312 } 5313 break; 5314 case eCSR_DOT11_MODE_11ac_ONLY: 5315 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) { 5316 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY; 5317 } else { 5318 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; 5319 } 5320 break; 5321 default: 5322 /* No need to assign anything here */ 5323 break; 5324 } 5325 5326 return cfgDot11Mode; 5327 } 5328 5329 QDF_STATUS csr_get_regulatory_domain_for_country(tpAniSirGlobal pMac, 5330 uint8_t *pCountry, 5331 v_REGDOMAIN_t *pDomainId, 5332 enum country_src source) 5333 { 5334 QDF_STATUS status = QDF_STATUS_E_INVAL; 5335 QDF_STATUS qdf_status; 5336 uint8_t countryCode[CDS_COUNTRY_CODE_LEN + 1]; 5337 v_REGDOMAIN_t domainId; 5338 5339 if (pCountry) { 5340 countryCode[0] = pCountry[0]; 5341 countryCode[1] = pCountry[1]; 5342 qdf_status = cds_get_reg_domain_from_country_code(&domainId, 5343 countryCode, 5344 source); 5345 5346 if (QDF_IS_STATUS_SUCCESS(qdf_status)) { 5347 if (pDomainId) { 5348 *pDomainId = domainId; 5349 } 5350 status = QDF_STATUS_SUCCESS; 5351 } else { 5352 sms_log(pMac, LOGW, 5353 FL 5354 (" Couldn't find domain for country code %c%c"), 5355 pCountry[0], pCountry[1]); 5356 status = QDF_STATUS_E_INVAL; 5357 } 5358 } 5359 5360 return status; 5361 } 5362 5363 /* To check whether a country code matches the one in the IE */ 5364 /* Only check the first two characters, ignoring in/outdoor */ 5365 /* pCountry -- caller allocated buffer contain the country code that is checking against */ 5366 /* the one in pIes. It can be NULL. */ 5367 /* caller must provide pIes, it cannot be NULL */ 5368 /* This function always return true if 11d support is not turned on. */ 5369 bool csr_match_country_code(tpAniSirGlobal pMac, uint8_t *pCountry, 5370 tDot11fBeaconIEs *pIes) 5371 { 5372 bool fRet = true; 5373 5374 do { 5375 if (!csr_is11d_supported(pMac)) { 5376 break; 5377 } 5378 if (!pIes) { 5379 sms_log(pMac, LOGE, FL(" No IEs")); 5380 break; 5381 } 5382 5383 if (pCountry) { 5384 uint32_t i; 5385 5386 if (!pIes->Country.present) { 5387 fRet = false; 5388 break; 5389 } 5390 /* Convert the CountryCode characters to upper */ 5391 for (i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++) { 5392 pCountry[i] = csr_to_upper(pCountry[i]); 5393 } 5394 if (qdf_mem_cmp(pIes->Country.country, pCountry, 5395 WNI_CFG_COUNTRY_CODE_LEN - 1)) { 5396 fRet = false; 5397 break; 5398 } 5399 } 5400 } while (0); 5401 5402 return fRet; 5403 } 5404 5405 QDF_STATUS csr_get_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId, 5406 tCsrRoamModifyProfileFields * 5407 pModifyProfileFields) 5408 { 5409 5410 if (!pModifyProfileFields) { 5411 return QDF_STATUS_E_FAILURE; 5412 } 5413 5414 qdf_mem_copy(pModifyProfileFields, 5415 &pMac->roam.roamSession[sessionId].connectedProfile. 5416 modifyProfileFields, sizeof(tCsrRoamModifyProfileFields)); 5417 5418 return QDF_STATUS_SUCCESS; 5419 } 5420 5421 QDF_STATUS csr_set_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId, 5422 tCsrRoamModifyProfileFields * 5423 pModifyProfileFields) 5424 { 5425 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); 5426 5427 qdf_mem_copy(&pSession->connectedProfile.modifyProfileFields, 5428 pModifyProfileFields, sizeof(tCsrRoamModifyProfileFields)); 5429 5430 return QDF_STATUS_SUCCESS; 5431 } 5432 5433 5434 bool csr_is_set_key_allowed(tpAniSirGlobal pMac, uint32_t sessionId) 5435 { 5436 bool fRet = true; 5437 tCsrRoamSession *pSession; 5438 5439 pSession = CSR_GET_SESSION(pMac, sessionId); 5440 5441 /* 5442 * This condition is not working for infra state. When infra is in 5443 * not-connected state the pSession->pCurRoamProfile is NULL, this 5444 * function returns true, that is incorrect. 5445 * Since SAP requires to set key without any BSS started, it needs 5446 * this condition to be met. In other words, this function is useless. 5447 * The current work-around is to process setcontext_rsp no matter 5448 * what the state is. 5449 */ 5450 sms_log(pMac, LOG2, 5451 FL(" is not what it intends to. Must be revisit or removed")); 5452 if ((NULL == pSession) 5453 || (csr_is_conn_state_disconnected(pMac, sessionId) 5454 && (pSession->pCurRoamProfile != NULL) 5455 && (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile)))) 5456 ) { 5457 fRet = false; 5458 } 5459 5460 return fRet; 5461 } 5462 5463 /* no need to acquire lock for this basic function */ 5464 uint16_t sme_chn_to_freq(uint8_t chanNum) 5465 { 5466 int i; 5467 5468 for (i = 0; i < NUM_CHANNELS; i++) { 5469 if (CDS_CHANNEL_NUM(i) == chanNum) 5470 return CDS_CHANNEL_FREQ(i); 5471 } 5472 5473 return 0; 5474 } 5475 5476 /* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we 5477 * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and 5478 * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there 5479 * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to 5480 * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS 5481 */ 5482 5483 /* Remove this code once SLM_Sessionization is supported */ 5484 /* BMPS_WORKAROUND_NOT_NEEDED */ 5485 void csr_disconnect_all_active_sessions(tpAniSirGlobal pMac) 5486 { 5487 uint8_t i; 5488 5489 /* Disconnect all the active sessions */ 5490 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { 5491 if (CSR_IS_SESSION_VALID(pMac, i) 5492 && !csr_is_conn_state_disconnected(pMac, i)) { 5493 csr_roam_disconnect_internal(pMac, i, 5494 eCSR_DISCONNECT_REASON_UNSPECIFIED); 5495 } 5496 } 5497 } 5498 5499 bool csr_is_channel_present_in_list(uint8_t *pChannelList, 5500 int numChannels, uint8_t channel) 5501 { 5502 int i = 0; 5503 5504 /* Check for NULL pointer */ 5505 if (!pChannelList || (numChannels == 0)) { 5506 return false; 5507 } 5508 /* Look for the channel in the list */ 5509 for (i = 0; (i < numChannels) && 5510 (i < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++) { 5511 if (pChannelList[i] == channel) 5512 return true; 5513 } 5514 5515 return false; 5516 } 5517 5518 /** 5519 * sme_request_type_to_string(): converts scan request enum to string. 5520 * @request_type: scan request type enum. 5521 * 5522 * Return: Printable string for request_type 5523 */ 5524 const char *sme_request_type_to_string(const uint8_t request_type) 5525 { 5526 switch (request_type) { 5527 CASE_RETURN_STRING(eCSR_SCAN_REQUEST_11D_SCAN); 5528 CASE_RETURN_STRING(eCSR_SCAN_REQUEST_FULL_SCAN); 5529 CASE_RETURN_STRING(eCSR_SCAN_IDLE_MODE_SCAN); 5530 CASE_RETURN_STRING(eCSR_SCAN_HO_PROBE_SCAN); 5531 CASE_RETURN_STRING(eCSR_SCAN_P2P_DISCOVERY); 5532 CASE_RETURN_STRING(eCSR_SCAN_SOFTAP_CHANNEL_RANGE); 5533 CASE_RETURN_STRING(eCSR_SCAN_P2P_FIND_PEER); 5534 default: 5535 return "Unknown Scan Request Type"; 5536 } 5537 } 5538 5539 /** 5540 * sme_bsstype_to_string() - converts bss type to string. 5541 * @bss_type: bss type enum 5542 * 5543 * Return: printable string for bss type 5544 */ 5545 const char *sme_bss_type_to_string(const uint8_t bss_type) 5546 { 5547 switch (bss_type) { 5548 CASE_RETURN_STRING(eCSR_BSS_TYPE_INFRASTRUCTURE); 5549 CASE_RETURN_STRING(eCSR_BSS_TYPE_INFRA_AP); 5550 CASE_RETURN_STRING(eCSR_BSS_TYPE_IBSS); 5551 CASE_RETURN_STRING(eCSR_BSS_TYPE_START_IBSS); 5552 CASE_RETURN_STRING(eCSR_BSS_TYPE_ANY); 5553 default: 5554 return "unknown bss type"; 5555 } 5556 } 5557 5558 /** 5559 * sme_scantype_to_string() - converts scan type to string. 5560 * @scan_type: scan type enum 5561 * 5562 * Return: printable string for scan type 5563 */ 5564 const char *sme_scan_type_to_string(const uint8_t scan_type) 5565 { 5566 switch (scan_type) { 5567 CASE_RETURN_STRING(eSIR_PASSIVE_SCAN); 5568 CASE_RETURN_STRING(eSIR_ACTIVE_SCAN); 5569 CASE_RETURN_STRING(eSIR_BEACON_TABLE); 5570 default: 5571 return "unknown scan type"; 5572 } 5573 } 5574 5575 QDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList, 5576 int numChannels, uint8_t channel) 5577 { 5578 int i = 0; 5579 5580 /* Check for NULL pointer */ 5581 if (!pChannelList) 5582 return QDF_STATUS_E_NULL_VALUE; 5583 5584 /* Make room for the addition. (Start moving from the back.) */ 5585 for (i = numChannels; i > 0; i--) { 5586 pChannelList[i] = pChannelList[i - 1]; 5587 } 5588 5589 /* Now add the NEW channel...at the front */ 5590 pChannelList[0] = channel; 5591 5592 return QDF_STATUS_SUCCESS; 5593 } 5594 #ifdef FEATURE_WLAN_DIAG_SUPPORT 5595 /** 5596 * csr_diag_event_report() - send PE diag event 5597 * @pmac: pointer to global MAC context. 5598 * @event_typev: sub event type for DIAG event. 5599 * @status: status of the event 5600 * @reasoncode: reasoncode for the given status 5601 * 5602 * This function is called to send diag event 5603 * 5604 * Return: NA 5605 */ 5606 void csr_diag_event_report(tpAniSirGlobal pmac, uint16_t event_type, 5607 uint16_t status, uint16_t reasoncode) 5608 { 5609 WLAN_HOST_DIAG_EVENT_DEF(diag_event, host_event_wlan_pe_payload_type); 5610 5611 qdf_mem_zero(&diag_event, sizeof(host_event_wlan_pe_payload_type)); 5612 5613 /* diag_event.bssid is already all zeroes */ 5614 diag_event.sme_state = sme_get_lim_sme_state(pmac); 5615 diag_event.mlm_state = sme_get_lim_mlm_state(pmac); 5616 diag_event.event_type = event_type; 5617 diag_event.status = status; 5618 diag_event.reason_code = reasoncode; 5619 5620 WLAN_HOST_DIAG_EVENT_REPORT(&diag_event, EVENT_WLAN_PE); 5621 return; 5622 } 5623 #endif 5624 5625 /** 5626 * csr_wait_for_connection_update() - Wait for hw mode update 5627 * @mac: Pointer to the MAC context 5628 * @do_release_reacquire_lock: Indicates whether release and 5629 * re-acquisition of SME global lock is required. 5630 * 5631 * Waits for CONNECTION_UPDATE_TIMEOUT time so that the 5632 * hw mode update can get processed. 5633 * 5634 * Return: True if the wait was successful, false otherwise 5635 */ 5636 bool csr_wait_for_connection_update(tpAniSirGlobal mac, 5637 bool do_release_reacquire_lock) 5638 { 5639 QDF_STATUS status, ret; 5640 5641 if (do_release_reacquire_lock == true) { 5642 ret = sme_release_global_lock(&mac->sme); 5643 if (!QDF_IS_STATUS_SUCCESS(ret)) { 5644 cds_err("lock release fail %d", ret); 5645 return false; 5646 } 5647 } 5648 5649 status = qdf_wait_for_connection_update(); 5650 5651 if (do_release_reacquire_lock == true) { 5652 ret = sme_acquire_global_lock(&mac->sme); 5653 if (!QDF_IS_STATUS_SUCCESS(ret)) { 5654 cds_err("lock acquire fail %d", ret); 5655 return false; 5656 } 5657 } 5658 5659 if (!QDF_IS_STATUS_SUCCESS(status)) { 5660 cds_err("wait for event failed"); 5661 return false; 5662 } 5663 5664 return true; 5665 } 5666 5667 /** 5668 * csr_get_session_persona() - get persona of a session 5669 * @pmac: pointer to global MAC context 5670 * @session_id: session id 5671 * 5672 * This function is to return the persona of a session 5673 * 5674 * Reture: enum tQDF_ADAPTER_MODE persona 5675 */ 5676 enum tQDF_ADAPTER_MODE csr_get_session_persona(tpAniSirGlobal pmac, 5677 uint32_t session_id) 5678 { 5679 tCsrRoamSession *session = NULL; 5680 5681 session = CSR_GET_SESSION(pmac, session_id); 5682 if (NULL == session || NULL == session->pCurRoamProfile) 5683 return QDF_MAX_NO_OF_MODE; 5684 5685 return session->pCurRoamProfile->csrPersona; 5686 } 5687 5688 /** 5689 * csr_is_ndi_started() - function to check if NDI is started 5690 * @mac_ctx: handle to mac context 5691 * @session_id: session identifier 5692 * 5693 * returns: true if NDI is started, false otherwise 5694 */ 5695 bool csr_is_ndi_started(tpAniSirGlobal mac_ctx, uint32_t session_id) 5696 { 5697 tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id); 5698 if (!session) 5699 return false; 5700 5701 return eCSR_CONNECT_STATE_TYPE_NDI_STARTED == session->connectState; 5702 } 5703