1 /* 2 * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "cds_api.h" 20 #include "wni_cfg.h" 21 #include "ani_global.h" 22 #include "sir_api.h" 23 #include "sir_params.h" 24 #include "cfg_ucfg_api.h" 25 #include "sch_api.h" 26 #include "utils_api.h" 27 #include "lim_utils.h" 28 #include "lim_assoc_utils.h" 29 #include "lim_prop_exts_utils.h" 30 #include "lim_security_utils.h" 31 #include "lim_send_messages.h" 32 #include "lim_send_messages.h" 33 #include "lim_session_utils.h" 34 #include <lim_ft.h> 35 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 36 #include "host_diag_core_log.h" 37 #endif 38 #include "wma_if.h" 39 #include "wma.h" 40 #include "wlan_reg_services_api.h" 41 #include "lim_process_fils.h" 42 #include "wlan_mlme_public_struct.h" 43 44 static void lim_process_mlm_auth_req(struct mac_context *, uint32_t *); 45 static void lim_process_mlm_assoc_req(struct mac_context *, uint32_t *); 46 static void lim_process_mlm_disassoc_req(struct mac_context *, uint32_t *); 47 static void lim_process_mlm_set_keys_req(struct mac_context *, uint32_t *); 48 49 /* MLM Timeout event handler templates */ 50 static void lim_process_auth_rsp_timeout(struct mac_context *, uint32_t); 51 static void lim_process_periodic_join_probe_req_timer(struct mac_context *); 52 static void lim_process_auth_retry_timer(struct mac_context *); 53 54 /** 55 * lim_process_sae_auth_timeout() - This function is called to process sae 56 * auth timeout 57 * @mac_ctx: Pointer to Global MAC structure 58 * 59 * @Return: None 60 */ 61 static void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) 62 { 63 struct pe_session *session; 64 65 session = pe_find_session_by_session_id(mac_ctx, 66 mac_ctx->lim.limTimers.sae_auth_timer.sessionId); 67 if (!session) { 68 pe_err("Session does not exist for given session id"); 69 return; 70 } 71 72 pe_warn("SAE auth timeout sessionid %d mlmstate %X SmeState %X", 73 session->peSessionId, session->limMlmState, 74 session->limSmeState); 75 76 switch (session->limMlmState) { 77 case eLIM_MLM_WT_SAE_AUTH_STATE: 78 /* 79 * SAE authentication is not completed. Restore from 80 * auth state. 81 */ 82 if (session->opmode == QDF_STA_MODE) 83 lim_restore_from_auth_state(mac_ctx, 84 eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, 85 eSIR_MAC_UNSPEC_FAILURE_REASON, session); 86 break; 87 default: 88 /* SAE authentication is timed out in unexpected state */ 89 pe_err("received unexpected SAE auth timeout in state %X", 90 session->limMlmState); 91 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 92 break; 93 } 94 } 95 96 /** 97 * lim_process_mlm_req_messages() - process mlm request messages 98 * @mac_ctx: global MAC context 99 * @msg: mlm request message 100 * 101 * This function is called by lim_post_mlm_message(). This 102 * function handles MLM primitives invoked by SME. 103 * Depending on the message type, corresponding function will be 104 * called. 105 * ASSUMPTIONS: 106 * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes 107 * APIs exposed by Beacon Processing module for setting parameters 108 * at MAC hardware. 109 * 2. If attempt to Reassociate with an AP fails, link with current 110 * AP is restored back. 111 * 112 * Return: None 113 */ 114 void lim_process_mlm_req_messages(struct mac_context *mac_ctx, 115 struct scheduler_msg *msg) 116 { 117 switch (msg->type) { 118 case LIM_MLM_AUTH_REQ: 119 lim_process_mlm_auth_req(mac_ctx, msg->bodyptr); 120 break; 121 case LIM_MLM_ASSOC_REQ: 122 lim_process_mlm_assoc_req(mac_ctx, msg->bodyptr); 123 break; 124 case LIM_MLM_DISASSOC_REQ: 125 lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr); 126 break; 127 case LIM_MLM_SETKEYS_REQ: 128 lim_process_mlm_set_keys_req(mac_ctx, msg->bodyptr); 129 break; 130 case SIR_LIM_JOIN_FAIL_TIMEOUT: 131 lim_process_join_failure_timeout(mac_ctx); 132 break; 133 case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: 134 lim_process_periodic_join_probe_req_timer(mac_ctx); 135 break; 136 case SIR_LIM_AUTH_FAIL_TIMEOUT: 137 lim_process_auth_failure_timeout(mac_ctx); 138 break; 139 case SIR_LIM_AUTH_RSP_TIMEOUT: 140 lim_process_auth_rsp_timeout(mac_ctx, msg->bodyval); 141 break; 142 case SIR_LIM_ASSOC_FAIL_TIMEOUT: 143 lim_process_assoc_failure_timeout(mac_ctx, msg->bodyval); 144 break; 145 case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: 146 lim_process_ft_preauth_rsp_timeout(mac_ctx); 147 break; 148 case SIR_LIM_DISASSOC_ACK_TIMEOUT: 149 lim_process_disassoc_ack_timeout(mac_ctx); 150 break; 151 case SIR_LIM_DEAUTH_ACK_TIMEOUT: 152 lim_process_deauth_ack_timeout(mac_ctx); 153 break; 154 case SIR_LIM_AUTH_RETRY_TIMEOUT: 155 lim_process_auth_retry_timer(mac_ctx); 156 break; 157 case SIR_LIM_AUTH_SAE_TIMEOUT: 158 lim_process_sae_auth_timeout(mac_ctx); 159 break; 160 case LIM_MLM_TSPEC_REQ: 161 default: 162 break; 163 } /* switch (msg->type) */ 164 } 165 166 /** 167 * mlm_add_sta() - MLM add sta 168 * @mac_ctx: global MAC context 169 * @sta_param: Add sta params 170 * @bssid: BSSID 171 * @ht_capable: HT capability 172 * @session_entry: PE session entry 173 * 174 * This function is called to update station parameters 175 * 176 * Return: None 177 */ 178 static void mlm_add_sta(struct mac_context *mac_ctx, tpAddStaParams sta_param, 179 uint8_t *bssid, uint8_t ht_capable, struct pe_session *session_entry) 180 { 181 uint32_t val; 182 uint32_t self_dot11mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode; 183 184 sta_param->staType = STA_ENTRY_SELF; /* Identifying self */ 185 186 qdf_mem_copy(sta_param->bssId, bssid, sizeof(tSirMacAddr)); 187 qdf_mem_copy(sta_param->staMac, session_entry->self_mac_addr, 188 sizeof(tSirMacAddr)); 189 190 /* Configuration related parameters to be changed to support BT-AMP */ 191 192 val = mac_ctx->mlme_cfg->sap_cfg.listen_interval; 193 sta_param->listenInterval = (uint16_t) val; 194 195 sta_param->shortPreambleSupported = 196 mac_ctx->mlme_cfg->ht_caps.short_preamble; 197 198 sta_param->assocId = 0; /* Is SMAC OK with this? */ 199 sta_param->wmmEnabled = 0; 200 sta_param->uAPSD = 0; 201 sta_param->maxSPLen = 0; 202 sta_param->us32MaxAmpduDuration = 0; 203 sta_param->maxAmpduSize = 0; /* 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k */ 204 205 /* For Self STA get the LDPC capability from config.ini */ 206 sta_param->htLdpcCapable = 207 (session_entry->txLdpcIniFeatureEnabled & 0x01); 208 sta_param->vhtLdpcCapable = 209 ((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01); 210 211 if (IS_DOT11_MODE_HT(session_entry->dot11mode)) { 212 sta_param->htCapable = ht_capable; 213 sta_param->greenFieldCapable = 214 lim_get_ht_capability(mac_ctx, eHT_GREENFIELD, 215 session_entry); 216 sta_param->ch_width = 217 lim_get_ht_capability(mac_ctx, 218 eHT_SUPPORTED_CHANNEL_WIDTH_SET, session_entry); 219 sta_param->mimoPS = 220 (tSirMacHTMIMOPowerSaveState)lim_get_ht_capability( 221 mac_ctx, eHT_MIMO_POWER_SAVE, session_entry); 222 sta_param->rifsMode = 223 lim_get_ht_capability(mac_ctx, eHT_RIFS_MODE, 224 session_entry); 225 sta_param->lsigTxopProtection = 226 lim_get_ht_capability(mac_ctx, eHT_LSIG_TXOP_PROTECTION, 227 session_entry); 228 sta_param->maxAmpduDensity = 229 lim_get_ht_capability(mac_ctx, eHT_MPDU_DENSITY, 230 session_entry); 231 sta_param->maxAmsduSize = 232 lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_LENGTH, 233 session_entry); 234 sta_param->max_amsdu_num = 235 lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_NUM, 236 session_entry); 237 sta_param->fDsssCckMode40Mhz = 238 lim_get_ht_capability(mac_ctx, eHT_DSSS_CCK_MODE_40MHZ, 239 session_entry); 240 sta_param->fShortGI20Mhz = 241 lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ, 242 session_entry); 243 sta_param->fShortGI40Mhz = 244 lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ, 245 session_entry); 246 } 247 if (session_entry->vhtCapability) { 248 sta_param->vhtCapable = true; 249 sta_param->vhtTxBFCapable = 250 session_entry->vht_config.su_beam_formee; 251 sta_param->vhtTxMUBformeeCapable = 252 session_entry->vht_config.mu_beam_formee; 253 sta_param->enable_su_tx_bformer = 254 session_entry->vht_config.su_beam_former; 255 } 256 257 if (lim_is_session_he_capable(session_entry)) 258 lim_add_self_he_cap(sta_param, session_entry); 259 260 /* 261 * Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE 262 * capabilities 263 */ 264 if (IS_DOT11_MODE_VHT(self_dot11mode)) { 265 sta_param->maxAmpduSize = 266 mac_ctx->mlme_cfg->vht_caps.vht_cap_info.ampdu_len_exponent; 267 } 268 sta_param->enableVhtpAid = session_entry->enableVhtpAid; 269 sta_param->enableAmpduPs = session_entry->enableAmpduPs; 270 sta_param->enableHtSmps = session_entry->enableHtSmps; 271 sta_param->htSmpsconfig = session_entry->htSmpsvalue; 272 sta_param->send_smps_action = session_entry->send_smps_action; 273 274 lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL, 275 false, session_entry, NULL, NULL); 276 277 pe_debug("GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d," 278 " SGI20: %d, SGI40%d", sta_param->greenFieldCapable, 279 sta_param->ch_width, sta_param->mimoPS, 280 sta_param->lsigTxopProtection, sta_param->fDsssCckMode40Mhz, 281 sta_param->fShortGI20Mhz, sta_param->fShortGI40Mhz); 282 283 if (QDF_P2P_GO_MODE == session_entry->opmode) 284 sta_param->p2pCapableSta = 1; 285 } 286 287 /** 288 * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ 289 * @mac_ctx: global MAC context 290 * @mlm_start_req: MLM start request 291 * @session: PE session entry 292 * 293 * Package WMA_ADD_BSS_REQ to HAL, in order to start a BSS 294 * 295 * Return: eSIR_SME_SUCCESS on success, other error codes otherwise 296 */ 297 tSirResultCodes 298 lim_mlm_add_bss(struct mac_context *mac_ctx, 299 tLimMlmStartReq *mlm_start_req, struct pe_session *session) 300 { 301 struct scheduler_msg msg_buf = {0}; 302 struct bss_params *addbss_param = NULL; 303 struct wlan_mlme_qos *qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params; 304 uint32_t retcode; 305 bool is_ch_dfs = false; 306 307 /* Package WMA_ADD_BSS_REQ message parameters */ 308 addbss_param = qdf_mem_malloc(sizeof(struct bss_params)); 309 if (!addbss_param) 310 return eSIR_SME_RESOURCES_UNAVAILABLE; 311 312 /* Fill in struct bss_params members */ 313 qdf_mem_copy(addbss_param->bssId, mlm_start_req->bssId, 314 sizeof(tSirMacAddr)); 315 316 /* Fill in struct bss_params self_mac_addr */ 317 qdf_mem_copy(addbss_param->self_mac_addr, 318 session->self_mac_addr, sizeof(tSirMacAddr)); 319 320 addbss_param->bssType = mlm_start_req->bssType; 321 if (mlm_start_req->bssType == eSIR_IBSS_MODE) 322 addbss_param->operMode = BSS_OPERATIONAL_MODE_STA; 323 else if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE) 324 addbss_param->operMode = BSS_OPERATIONAL_MODE_AP; 325 else if (mlm_start_req->bssType == eSIR_NDI_MODE) 326 addbss_param->operMode = BSS_OPERATIONAL_MODE_NDI; 327 328 addbss_param->shortSlotTimeSupported = session->shortSlotTimeSupported; 329 addbss_param->beaconInterval = mlm_start_req->beaconPeriod; 330 addbss_param->dtimPeriod = mlm_start_req->dtimPeriod; 331 addbss_param->wps_state = mlm_start_req->wps_state; 332 addbss_param->cfParamSet.cfpCount = mlm_start_req->cfParamSet.cfpCount; 333 addbss_param->cfParamSet.cfpPeriod = 334 mlm_start_req->cfParamSet.cfpPeriod; 335 addbss_param->cfParamSet.cfpMaxDuration = 336 mlm_start_req->cfParamSet.cfpMaxDuration; 337 addbss_param->cfParamSet.cfpDurRemaining = 338 mlm_start_req->cfParamSet.cfpDurRemaining; 339 340 addbss_param->rateSet.numRates = mlm_start_req->rateSet.numRates; 341 if (addbss_param->rateSet.numRates > WLAN_SUPPORTED_RATES_IE_MAX_LEN) { 342 pe_warn("num of sup rates %d exceeding the limit %d, resetting", 343 addbss_param->rateSet.numRates, 344 WLAN_SUPPORTED_RATES_IE_MAX_LEN); 345 addbss_param->rateSet.numRates = WLAN_SUPPORTED_RATES_IE_MAX_LEN; 346 } 347 qdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate, 348 addbss_param->rateSet.numRates); 349 350 addbss_param->nwType = mlm_start_req->nwType; 351 addbss_param->htCapable = mlm_start_req->htCapable; 352 addbss_param->vhtCapable = session->vhtCapability; 353 if (lim_is_session_he_capable(session)) { 354 lim_update_bss_he_capable(mac_ctx, addbss_param); 355 lim_decide_he_op(mac_ctx, addbss_param, session); 356 lim_update_usr_he_cap(mac_ctx, session); 357 } 358 359 addbss_param->ch_width = session->ch_width; 360 addbss_param->chan_freq_seg0 = 361 wlan_reg_chan_to_freq(mac_ctx->pdev, 362 session->ch_center_freq_seg0); 363 addbss_param->chan_freq_seg1 = 364 wlan_reg_chan_to_freq(mac_ctx->pdev, 365 session->ch_center_freq_seg1); 366 addbss_param->htOperMode = mlm_start_req->htOperMode; 367 addbss_param->dualCTSProtection = mlm_start_req->dualCTSProtection; 368 addbss_param->txChannelWidthSet = mlm_start_req->txChannelWidthSet; 369 370 addbss_param->op_chan_freq = 371 wlan_reg_chan_to_freq(mac_ctx->pdev, 372 mlm_start_req->channelNumber); 373 #ifdef WLAN_FEATURE_11W 374 addbss_param->rmfEnabled = session->limRmfEnabled; 375 #endif 376 377 /* Update PE sessionId */ 378 addbss_param->sessionId = mlm_start_req->sessionId; 379 addbss_param->bss_idx = session->smeSessionId; 380 381 382 /* Send the SSID to HAL to enable SSID matching for IBSS */ 383 addbss_param->ssId.length = mlm_start_req->ssId.length; 384 if (addbss_param->ssId.length > WLAN_SSID_MAX_LEN) { 385 pe_err("Invalid ssid length %d, max length allowed %d", 386 addbss_param->ssId.length, 387 WLAN_SSID_MAX_LEN); 388 qdf_mem_free(addbss_param); 389 return eSIR_SME_INVALID_PARAMETERS; 390 } 391 qdf_mem_copy(addbss_param->ssId.ssId, 392 mlm_start_req->ssId.ssId, addbss_param->ssId.length); 393 addbss_param->bHiddenSSIDEn = mlm_start_req->ssidHidden; 394 pe_debug("TRYING TO HIDE SSID %d", addbss_param->bHiddenSSIDEn); 395 /* CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed. */ 396 addbss_param->bProxyProbeRespEn = 0; 397 addbss_param->obssProtEnabled = mlm_start_req->obssProtEnabled; 398 399 addbss_param->maxTxPower = session->maxTxPower; 400 401 mlm_add_sta(mac_ctx, &addbss_param->staContext, 402 addbss_param->bssId, addbss_param->htCapable, 403 session); 404 405 addbss_param->status = QDF_STATUS_SUCCESS; 406 addbss_param->respReqd = 1; 407 408 /* Set a new state for MLME */ 409 session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE; 410 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, 411 session->limMlmState)); 412 413 /* pass on the session persona to hal */ 414 addbss_param->halPersona = session->opmode; 415 416 if (session->ch_width == CH_WIDTH_160MHZ) { 417 is_ch_dfs = true; 418 } else if (session->ch_width == CH_WIDTH_80P80MHZ) { 419 if (wlan_reg_get_channel_state(mac_ctx->pdev, 420 mlm_start_req->channelNumber) == 421 CHANNEL_STATE_DFS || 422 wlan_reg_get_channel_state(mac_ctx->pdev, 423 session->ch_center_freq_seg1 - 424 SIR_80MHZ_START_CENTER_CH_DIFF) == 425 CHANNEL_STATE_DFS) 426 is_ch_dfs = true; 427 } else { 428 if (wlan_reg_get_channel_state(mac_ctx->pdev, 429 mlm_start_req->channelNumber) == 430 CHANNEL_STATE_DFS) 431 is_ch_dfs = true; 432 } 433 434 addbss_param->bSpectrumMgtEnabled = 435 session->spectrumMgtEnabled || is_ch_dfs; 436 addbss_param->extSetStaKeyParamValid = 0; 437 438 addbss_param->dot11_mode = session->dot11mode; 439 addbss_param->nss = session->nss; 440 addbss_param->cac_duration_ms = mlm_start_req->cac_duration_ms; 441 addbss_param->dfs_regdomain = mlm_start_req->dfs_regdomain; 442 addbss_param->beacon_tx_rate = session->beacon_tx_rate; 443 if (QDF_IBSS_MODE == addbss_param->halPersona) { 444 if (!(mac_ctx->mlme_cfg)) { 445 pe_err("Mlme cfg NULL"); 446 return eSIR_SME_INVALID_PARAMETERS; 447 } 448 addbss_param->nss_2g = mac_ctx->vdev_type_nss_2g.ibss; 449 addbss_param->nss_5g = mac_ctx->vdev_type_nss_5g.ibss; 450 addbss_param->tx_aggregation_size = 451 qos_aggr->tx_aggregation_size; 452 addbss_param->tx_aggregation_size_be = 453 qos_aggr->tx_aggregation_size_be; 454 addbss_param->tx_aggregation_size_bk = 455 qos_aggr->tx_aggregation_size_bk; 456 addbss_param->tx_aggregation_size_vi = 457 qos_aggr->tx_aggregation_size_vi; 458 addbss_param->tx_aggregation_size_vo = 459 qos_aggr->tx_aggregation_size_vo; 460 addbss_param->rx_aggregation_size = 461 qos_aggr->rx_aggregation_size; 462 } 463 pe_debug("dot11_mode:%d nss value:%d", 464 addbss_param->dot11_mode, addbss_param->nss); 465 466 if (cds_is_5_mhz_enabled()) { 467 addbss_param->ch_width = CH_WIDTH_5MHZ; 468 addbss_param->staContext.ch_width = CH_WIDTH_5MHZ; 469 } else if (cds_is_10_mhz_enabled()) { 470 addbss_param->ch_width = CH_WIDTH_10MHZ; 471 addbss_param->staContext.ch_width = CH_WIDTH_10MHZ; 472 } 473 474 msg_buf.type = WMA_ADD_BSS_REQ; 475 msg_buf.reserved = 0; 476 msg_buf.bodyptr = addbss_param; 477 msg_buf.bodyval = 0; 478 MTRACE(mac_trace_msg_tx(mac_ctx, session->peSessionId, msg_buf.type)); 479 480 pe_debug("Sending WMA_ADD_BSS_REQ..."); 481 retcode = wma_post_ctrl_msg(mac_ctx, &msg_buf); 482 if (QDF_STATUS_SUCCESS != retcode) { 483 pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X", 484 retcode); 485 qdf_mem_free(addbss_param); 486 return eSIR_SME_HAL_SEND_MESSAGE_FAIL; 487 } 488 489 return eSIR_SME_SUCCESS; 490 } 491 492 void lim_process_mlm_start_req(struct mac_context *mac_ctx, 493 tLimMlmStartReq *mlm_start_req) 494 { 495 tLimMlmStartCnf mlm_start_cnf; 496 struct pe_session *session = NULL; 497 498 if (!mlm_start_req) { 499 pe_err("Buffer is Pointing to NULL"); 500 return; 501 } 502 503 session = pe_find_session_by_session_id(mac_ctx, 504 mlm_start_req->sessionId); 505 if (!session) { 506 pe_err("Session Does not exist for given sessionID"); 507 mlm_start_cnf.resultCode = eSIR_SME_REFUSED; 508 goto end; 509 } 510 511 if (session->limMlmState != eLIM_MLM_IDLE_STATE) { 512 /* 513 * Should not have received Start req in states other than idle. 514 * Return Start confirm with failure code. 515 */ 516 pe_err("received unexpected MLM_START_REQ in state %X", 517 session->limMlmState); 518 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 519 mlm_start_cnf.resultCode = 520 eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; 521 goto end; 522 } 523 524 mlm_start_cnf.resultCode = 525 lim_mlm_add_bss(mac_ctx, mlm_start_req, session); 526 527 end: 528 /* Update PE session Id */ 529 mlm_start_cnf.sessionId = mlm_start_req->sessionId; 530 531 /* 532 * Respond immediately to LIM, only if MLME has not been 533 * successfully able to send WMA_ADD_BSS_REQ to HAL. 534 * Else, LIM_MLM_START_CNF will be sent after receiving 535 * WMA_ADD_BSS_RSP from HAL 536 */ 537 if (eSIR_SME_SUCCESS != mlm_start_cnf.resultCode) 538 lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf); 539 } 540 541 /** 542 * lim_post_join_set_link_state_callback()- registered callback to perform post 543 * peer creation operations 544 * 545 * @mac: pointer to global mac structure 546 * @callback_arg: registered callback argument 547 * @status: peer creation status 548 * 549 * this is registered callback function during association to perform 550 * post peer creation operation based on the peer creation status 551 * 552 * Return: none 553 */ 554 static void lim_post_join_set_link_state_callback( 555 struct mac_context *mac, 556 struct pe_session *session_entry, QDF_STATUS status) 557 { 558 tLimMlmJoinCnf mlm_join_cnf; 559 560 if (!session_entry) { 561 pe_err("sessionId is NULL"); 562 return; 563 } 564 565 pe_debug("Sessionid %d set link state(%d) cb status: %d", 566 session_entry->peSessionId, session_entry->limMlmState, 567 status); 568 569 if (QDF_IS_STATUS_ERROR(status)) { 570 pe_err("failed to find pe session for session id:%d", 571 session_entry->peSessionId); 572 goto failure; 573 } 574 575 /* 576 * store the channel switch session_entry in the lim 577 * global variable 578 */ 579 session_entry->channelChangeReasonCode = 580 LIM_SWITCH_CHANNEL_JOIN; 581 session_entry->pLimMlmReassocRetryReq = NULL; 582 pe_debug("[lim_process_mlm_join_req]: suspend link success(%d) " 583 "on sessionid: %d setting channel to: freq %d with ch_width :%d " 584 "and maxtxPower: %d", status, session_entry->peSessionId, 585 session_entry->curr_op_freq, 586 session_entry->ch_width, 587 session_entry->maxTxPower); 588 lim_set_channel( 589 mac, 590 wlan_reg_freq_to_chan(mac->pdev, session_entry->curr_op_freq), 591 session_entry->ch_center_freq_seg0, 592 session_entry->ch_center_freq_seg1, 593 session_entry->ch_width, 594 session_entry->maxTxPower, 595 session_entry->peSessionId, 0, 0); 596 return; 597 598 failure: 599 MTRACE(mac_trace(mac, TRACE_CODE_MLM_STATE, session_entry->peSessionId, 600 session_entry->limMlmState)); 601 session_entry->limMlmState = eLIM_MLM_IDLE_STATE; 602 mlm_join_cnf.resultCode = eSIR_SME_PEER_CREATE_FAILED; 603 mlm_join_cnf.sessionId = session_entry->peSessionId; 604 mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; 605 lim_post_sme_message(mac, LIM_MLM_JOIN_CNF, (uint32_t *) &mlm_join_cnf); 606 } 607 608 /** 609 * lim_process_mlm_post_join_suspend_link() - This function is called after the 610 * suspend link while joining off channel. 611 * 612 * @mac_ctx: Pointer to Global MAC structure 613 * @status: status of suspend link. 614 * @ctx: passed while calling suspend link(session) 615 * 616 * This function does following: 617 * Check for suspend state. 618 * If success, proceed with setting link state to receive the 619 * probe response/beacon from intended AP. 620 * Switch to the APs channel. 621 * On an error case, send the MLM_JOIN_CNF with error status. 622 * 623 * @Return None 624 */ 625 static void 626 lim_process_mlm_post_join_suspend_link(struct mac_context *mac_ctx, 627 QDF_STATUS status, 628 uint32_t *ctx) 629 { 630 struct pe_session *session = (struct pe_session *) ctx; 631 632 if (QDF_STATUS_SUCCESS != status) { 633 pe_err("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join", 634 session->peSessionId); 635 } 636 lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER); 637 638 /* assign appropriate sessionId to the timer object */ 639 mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId = 640 session->peSessionId; 641 642 status = wma_add_bss_peer_sta(session->self_mac_addr, session->bssId, 643 false); 644 lim_post_join_set_link_state_callback(mac_ctx, session, status); 645 646 return; 647 } 648 649 /** 650 * lim_process_mlm_join_req() - process mlm join request. 651 * 652 * @mac_ctx: Pointer to Global MAC structure 653 * @mlm_join_req: Pointer to the mlme join request 654 * 655 * This function is called to process MLM_JOIN_REQ message 656 * from SME. It does following: 657 * 1) Initialize LIM, HAL, DPH 658 * 2) Configure the BSS for which the JOIN REQ was received 659 * a) Send WMA_ADD_BSS_REQ to HAL - 660 * This will identify the BSS that we are interested in 661 * --AND-- 662 * Add a STA entry for the AP (in a STA context) 663 * b) Wait for WMA_ADD_BSS_RSP 664 * c) Send WMA_ADD_STA_REQ to HAL 665 * This will add the "local STA" entry to the STA table 666 * 3) Continue as before, i.e, 667 * a) Send a PROBE REQ 668 * b) Wait for PROBE RSP/BEACON containing the SSID that 669 * we are interested in 670 * c) Then start an AUTH seq 671 * d) Followed by the ASSOC seq 672 * 673 * @Return: None 674 */ 675 void lim_process_mlm_join_req(struct mac_context *mac_ctx, 676 tLimMlmJoinReq *mlm_join_req) 677 { 678 tLimMlmJoinCnf mlmjoin_cnf; 679 uint8_t sessionid; 680 struct pe_session *session; 681 682 sessionid = mlm_join_req->sessionId; 683 684 session = pe_find_session_by_session_id(mac_ctx, sessionid); 685 if (!session) { 686 pe_err("SessionId:%d does not exist", sessionid); 687 goto error; 688 } 689 690 if (!LIM_IS_AP_ROLE(session) && 691 ((session->limMlmState == eLIM_MLM_IDLE_STATE) || 692 (session->limMlmState == eLIM_MLM_JOINED_STATE)) && 693 (SIR_MAC_GET_ESS 694 (mlm_join_req->bssDescription.capabilityInfo) != 695 SIR_MAC_GET_IBSS(mlm_join_req->bssDescription. 696 capabilityInfo))) { 697 /* Hold onto Join request parameters */ 698 699 session->pLimMlmJoinReq = mlm_join_req; 700 if (is_lim_session_off_channel(mac_ctx, sessionid)) { 701 pe_debug("SessionId:%d LimSession is on OffChannel", 702 sessionid); 703 /* suspend link */ 704 pe_debug("Suspend link, sessionid %d is off channel", 705 sessionid); 706 lim_process_mlm_post_join_suspend_link(mac_ctx, 707 QDF_STATUS_SUCCESS, (uint32_t *)session); 708 } else { 709 pe_debug("No need to Suspend link"); 710 /* 711 * No need to Suspend link as LimSession is not 712 * off channel, calling 713 * lim_process_mlm_post_join_suspend_link with 714 * status as SUCCESS. 715 */ 716 pe_debug("SessionId:%d Join req on current chan", 717 sessionid); 718 lim_process_mlm_post_join_suspend_link(mac_ctx, 719 QDF_STATUS_SUCCESS, (uint32_t *)session); 720 } 721 return; 722 } else { 723 /** 724 * Should not have received JOIN req in states other than 725 * Idle state or on AP. 726 * Return join confirm with invalid parameters code. 727 */ 728 pe_err("Session:%d Unexpected Join req, role %d state %X", 729 session->peSessionId, GET_LIM_SYSTEM_ROLE(session), 730 session->limMlmState); 731 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 732 } 733 734 error: 735 qdf_mem_free(mlm_join_req); 736 if (session) 737 session->pLimMlmJoinReq = NULL; 738 mlmjoin_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 739 mlmjoin_cnf.sessionId = sessionid; 740 mlmjoin_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; 741 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, 742 (uint32_t *)&mlmjoin_cnf); 743 744 } 745 746 /** 747 * lim_is_auth_req_expected() - check if auth request is expected 748 * 749 * @mac_ctx: global MAC context 750 * @session: PE session entry 751 * 752 * This function is called by lim_process_mlm_auth_req to check 753 * if auth request is expected. 754 * 755 * Return: true if expected and false otherwise 756 */ 757 static bool lim_is_auth_req_expected(struct mac_context *mac_ctx, 758 struct pe_session *session) 759 { 760 bool flag = false; 761 762 /* 763 * Expect Auth request only when: 764 * 1. STA joined/associated with a BSS or 765 * 2. STA is in IBSS mode 766 * and STA is going to authenticate with a unicast 767 * address and requested authentication algorithm is 768 * supported. 769 */ 770 771 flag = (((LIM_IS_STA_ROLE(session) && 772 ((session->limMlmState == eLIM_MLM_JOINED_STATE) || 773 (session->limMlmState == 774 eLIM_MLM_LINK_ESTABLISHED_STATE))) || 775 (LIM_IS_IBSS_ROLE(session) && 776 (session->limMlmState == 777 eLIM_MLM_BSS_STARTED_STATE))) && 778 (!IEEE80211_IS_MULTICAST( 779 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)) && 780 lim_is_auth_algo_supported(mac_ctx, 781 mac_ctx->lim.gpLimMlmAuthReq->authType, session)); 782 783 return flag; 784 } 785 786 /** 787 * lim_is_preauth_ctx_exisits() - check if preauth context exists 788 * 789 * @mac_ctx: global MAC context 790 * @session: PE session entry 791 * @preauth_node_ptr: pointer to preauth node pointer 792 * 793 * This function is called by lim_process_mlm_auth_req to check 794 * if preauth context already exists 795 * 796 * Return: true if exists and false otherwise 797 */ 798 static bool lim_is_preauth_ctx_exists(struct mac_context *mac_ctx, 799 struct pe_session *session, 800 struct tLimPreAuthNode **preauth_node_ptr) 801 { 802 bool fl = false; 803 struct tLimPreAuthNode *preauth_node; 804 tpDphHashNode stads; 805 tSirMacAddr curr_bssid; 806 807 preauth_node = *preauth_node_ptr; 808 sir_copy_mac_addr(curr_bssid, session->bssId); 809 stads = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 810 &session->dph.dphHashTable); 811 preauth_node = lim_search_pre_auth_list(mac_ctx, 812 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr); 813 814 fl = (((LIM_IS_STA_ROLE(session)) && 815 (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) && 816 ((stads) && 817 (mac_ctx->lim.gpLimMlmAuthReq->authType == 818 stads->mlmStaContext.authType)) && 819 (!qdf_mem_cmp(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 820 curr_bssid, sizeof(tSirMacAddr)))) || 821 ((preauth_node) && 822 (preauth_node->authType == 823 mac_ctx->lim.gpLimMlmAuthReq->authType))); 824 825 return fl; 826 } 827 828 #ifdef WLAN_FEATURE_SAE 829 /** 830 * lim_process_mlm_auth_req_sae() - Handle SAE authentication 831 * @mac_ctx: global MAC context 832 * @session: PE session entry 833 * 834 * This function is called by lim_process_mlm_auth_req to handle SAE 835 * authentication. 836 * 837 * Return: QDF_STATUS 838 */ 839 static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx, 840 struct pe_session *session) 841 { 842 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 843 struct sir_sae_info *sae_info; 844 struct scheduler_msg msg = {0}; 845 846 sae_info = qdf_mem_malloc(sizeof(*sae_info)); 847 if (!sae_info) 848 return QDF_STATUS_E_FAILURE; 849 850 sae_info->msg_type = eWNI_SME_TRIGGER_SAE; 851 sae_info->msg_len = sizeof(*sae_info); 852 sae_info->vdev_id = session->smeSessionId; 853 854 qdf_mem_copy(sae_info->peer_mac_addr.bytes, 855 session->bssId, 856 QDF_MAC_ADDR_SIZE); 857 858 sae_info->ssid.length = session->ssId.length; 859 qdf_mem_copy(sae_info->ssid.ssId, 860 session->ssId.ssId, 861 session->ssId.length); 862 863 pe_debug("vdev_id %d ssid %.*s "QDF_MAC_ADDR_STR, 864 sae_info->vdev_id, 865 sae_info->ssid.length, 866 sae_info->ssid.ssId, 867 QDF_MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes)); 868 869 msg.type = eWNI_SME_TRIGGER_SAE; 870 msg.bodyptr = sae_info; 871 msg.bodyval = 0; 872 873 qdf_status = mac_ctx->lim.sme_msg_callback(mac_ctx, &msg); 874 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 875 pe_err("SAE failed for AUTH frame"); 876 qdf_mem_free(sae_info); 877 return qdf_status; 878 } 879 session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE; 880 881 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, 882 session->limMlmState)); 883 884 mac_ctx->lim.limTimers.sae_auth_timer.sessionId = 885 session->peSessionId; 886 887 /* Activate SAE auth timer */ 888 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 889 session->peSessionId, eLIM_AUTH_SAE_TIMER)); 890 if (tx_timer_activate(&mac_ctx->lim.limTimers.sae_auth_timer) 891 != TX_SUCCESS) { 892 pe_err("could not start Auth SAE timer"); 893 } 894 895 return qdf_status; 896 } 897 #else 898 static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx, 899 struct pe_session *session) 900 { 901 return QDF_STATUS_E_NOSUPPORT; 902 } 903 #endif 904 905 906 /** 907 * lim_process_mlm_auth_req() - process lim auth request 908 * 909 * @mac_ctx: global MAC context 910 * @msg: MLM auth request message 911 * 912 * This function is called to process MLM_AUTH_REQ message from SME 913 * 914 * @Return: None 915 */ 916 static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) 917 { 918 uint32_t num_preauth_ctx; 919 tSirMacAddr curr_bssid; 920 tSirMacAuthFrameBody auth_frame_body; 921 tLimMlmAuthCnf mlm_auth_cnf; 922 struct tLimPreAuthNode *preauth_node = NULL; 923 uint8_t session_id; 924 struct pe_session *session; 925 926 if (!msg) { 927 pe_err("Buffer is Pointing to NULL"); 928 return; 929 } 930 931 mac_ctx->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) msg; 932 session_id = mac_ctx->lim.gpLimMlmAuthReq->sessionId; 933 session = pe_find_session_by_session_id(mac_ctx, session_id); 934 if (!session) { 935 pe_err("SessionId:%d does not exist", session_id); 936 qdf_mem_free(msg); 937 mac_ctx->lim.gpLimMlmAuthReq = NULL; 938 return; 939 } 940 941 pe_debug("Process Auth Req sessionID %d Systemrole %d" 942 "mlmstate %d from: " QDF_MAC_ADDR_STR 943 " with authtype %d", session_id, 944 GET_LIM_SYSTEM_ROLE(session), session->limMlmState, 945 QDF_MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr), 946 mac_ctx->lim.gpLimMlmAuthReq->authType); 947 948 sir_copy_mac_addr(curr_bssid, session->bssId); 949 950 if (!lim_is_auth_req_expected(mac_ctx, session)) { 951 /* 952 * Unexpected auth request. 953 * Return Auth confirm with Invalid parameters code. 954 */ 955 mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 956 goto end; 957 } 958 959 /* 960 * This is a request for pre-authentication. Check if there exists 961 * context already for the requested peer OR 962 * if this request is for the AP we're currently associated with. 963 * If yes, return auth confirm immediately when 964 * requested auth type is same as the one used before. 965 */ 966 if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) { 967 pe_debug("Already have pre-auth context with peer: " 968 QDF_MAC_ADDR_STR, 969 QDF_MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)); 970 mlm_auth_cnf.resultCode = (tSirResultCodes) 971 eSIR_MAC_SUCCESS_STATUS; 972 goto end; 973 } else { 974 num_preauth_ctx = mac_ctx->mlme_cfg->lfr.max_num_pre_auth; 975 if (mac_ctx->lim.gLimNumPreAuthContexts == num_preauth_ctx) { 976 pe_warn("Number of pre-auth reached max limit"); 977 /* Return Auth confirm with reject code */ 978 mlm_auth_cnf.resultCode = 979 eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED; 980 goto end; 981 } 982 } 983 984 /* Delete pre-auth node if exists */ 985 if (preauth_node) 986 lim_delete_pre_auth_node(mac_ctx, 987 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr); 988 989 session->limPrevMlmState = session->limMlmState; 990 991 if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) && 992 !session->sae_pmk_cached) { 993 if (lim_process_mlm_auth_req_sae(mac_ctx, session) != 994 QDF_STATUS_SUCCESS) { 995 mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 996 goto end; 997 } else { 998 pe_debug("lim_process_mlm_auth_req_sae is successful"); 999 auth_frame_body.authAlgoNumber = eSIR_AUTH_TYPE_SAE; 1000 auth_frame_body.authTransactionSeqNumber = 1001 SIR_MAC_AUTH_FRAME_1; 1002 auth_frame_body.authStatusCode = 0; 1003 host_log_wlan_auth_info(auth_frame_body.authAlgoNumber, 1004 auth_frame_body.authTransactionSeqNumber, 1005 auth_frame_body.authStatusCode); 1006 1007 return; 1008 } 1009 } else 1010 session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE; 1011 1012 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, 1013 session->limMlmState)); 1014 1015 /* Mark auth algo as open when auth type is SAE and PMK is cached */ 1016 if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) && 1017 session->sae_pmk_cached) { 1018 auth_frame_body.authAlgoNumber = eSIR_OPEN_SYSTEM; 1019 } else { 1020 auth_frame_body.authAlgoNumber = 1021 (uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType; 1022 } 1023 1024 /* Prepare & send Authentication frame */ 1025 auth_frame_body.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; 1026 auth_frame_body.authStatusCode = 0; 1027 host_log_wlan_auth_info(auth_frame_body.authAlgoNumber, 1028 auth_frame_body.authTransactionSeqNumber, 1029 auth_frame_body.authStatusCode); 1030 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; 1031 lim_send_auth_mgmt_frame(mac_ctx, 1032 &auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 1033 LIM_NO_WEP_IN_FC, session); 1034 1035 /* assign appropriate session_id to the timer object */ 1036 mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId = session_id; 1037 1038 /* assign appropriate sessionId to the timer object */ 1039 mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId = 1040 session_id; 1041 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); 1042 /* Activate Auth failure timer */ 1043 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 1044 session->peSessionId, eLIM_AUTH_FAIL_TIMER)); 1045 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_FAIL_TIMER); 1046 if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAuthFailureTimer) 1047 != TX_SUCCESS) { 1048 pe_err("could not start Auth failure timer"); 1049 /* Cleanup as if auth timer expired */ 1050 lim_process_auth_failure_timeout(mac_ctx); 1051 } else { 1052 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 1053 session->peSessionId, eLIM_AUTH_RETRY_TIMER)); 1054 /* Activate Auth Retry timer */ 1055 if (tx_timer_activate 1056 (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer) 1057 != TX_SUCCESS) 1058 pe_err("could not activate Auth Retry timer"); 1059 } 1060 1061 return; 1062 end: 1063 qdf_mem_copy((uint8_t *) &mlm_auth_cnf.peerMacAddr, 1064 (uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 1065 sizeof(tSirMacAddr)); 1066 1067 mlm_auth_cnf.authType = mac_ctx->lim.gpLimMlmAuthReq->authType; 1068 mlm_auth_cnf.sessionId = session_id; 1069 1070 qdf_mem_free(mac_ctx->lim.gpLimMlmAuthReq); 1071 mac_ctx->lim.gpLimMlmAuthReq = NULL; 1072 pe_debug("SessionId:%d LimPostSme LIM_MLM_AUTH_CNF", 1073 session_id); 1074 lim_post_sme_message(mac_ctx, LIM_MLM_AUTH_CNF, 1075 (uint32_t *) &mlm_auth_cnf); 1076 } 1077 1078 /** 1079 * lim_process_mlm_assoc_req() - This function is called to process 1080 * MLM_ASSOC_REQ message from SME 1081 * 1082 * @mac_ctx: Pointer to Global MAC structure 1083 * @msg_buf: A pointer to the MLM message buffer 1084 * 1085 * This function is called to process MLM_ASSOC_REQ message from SME 1086 * 1087 * @Return None 1088 */ 1089 1090 static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 1091 { 1092 tSirMacAddr curr_bssId; 1093 tLimMlmAssocReq *mlm_assoc_req; 1094 tLimMlmAssocCnf mlm_assoc_cnf; 1095 struct pe_session *session_entry; 1096 1097 if (!msg_buf) { 1098 pe_err("Buffer is Pointing to NULL"); 1099 return; 1100 } 1101 1102 mlm_assoc_req = (tLimMlmAssocReq *) msg_buf; 1103 session_entry = pe_find_session_by_session_id(mac_ctx, 1104 mlm_assoc_req->sessionId); 1105 if (!session_entry) { 1106 pe_err("SessionId:%d Session Does not exist", 1107 mlm_assoc_req->sessionId); 1108 qdf_mem_free(mlm_assoc_req); 1109 return; 1110 } 1111 1112 sir_copy_mac_addr(curr_bssId, session_entry->bssId); 1113 1114 if (!(!LIM_IS_AP_ROLE(session_entry) && 1115 (session_entry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || 1116 session_entry->limMlmState == eLIM_MLM_JOINED_STATE) && 1117 (!qdf_mem_cmp(mlm_assoc_req->peerMacAddr, 1118 curr_bssId, sizeof(tSirMacAddr))))) { 1119 /* 1120 * Received Association request either in invalid state 1121 * or to a peer MAC entity whose address is different 1122 * from one that STA is currently joined with or on AP. 1123 * Return Assoc confirm with Invalid parameters code. 1124 */ 1125 pe_warn("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= " 1126 QDF_MAC_ADDR_STR, session_entry->limMlmState, 1127 GET_LIM_SYSTEM_ROLE(session_entry), 1128 QDF_MAC_ADDR_ARRAY(mlm_assoc_req->peerMacAddr)); 1129 lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState); 1130 mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1131 mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; 1132 goto end; 1133 } 1134 1135 /* map the session entry pointer to the AssocFailureTimer */ 1136 mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId = 1137 mlm_assoc_req->sessionId; 1138 session_entry->limPrevMlmState = session_entry->limMlmState; 1139 session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE; 1140 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1141 session_entry->peSessionId, 1142 session_entry->limMlmState)); 1143 pe_debug("SessionId:%d Sending Assoc_Req Frame", 1144 session_entry->peSessionId); 1145 1146 /* Prepare and send Association request frame */ 1147 lim_send_assoc_req_mgmt_frame(mac_ctx, mlm_assoc_req, session_entry); 1148 1149 /* Start association failure timer */ 1150 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 1151 session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER)); 1152 if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAssocFailureTimer) 1153 != TX_SUCCESS) { 1154 pe_warn("SessionId:%d couldn't start Assoc failure timer", 1155 session_entry->peSessionId); 1156 /* Cleanup as if assoc timer expired */ 1157 lim_process_assoc_failure_timeout(mac_ctx, LIM_ASSOC); 1158 } 1159 1160 return; 1161 end: 1162 /* Update PE session Id */ 1163 mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId; 1164 /* Free up buffer allocated for assocReq */ 1165 qdf_mem_free(mlm_assoc_req); 1166 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 1167 (uint32_t *) &mlm_assoc_cnf); 1168 } 1169 1170 /** 1171 * lim_process_mlm_disassoc_req_ntf() - process disassoc request notification 1172 * 1173 * @mac_ctx: global MAC context 1174 * @suspend_status: suspend status 1175 * @msg: mlm message buffer 1176 * 1177 * This function is used to process MLM disassoc notification 1178 * 1179 * Return: None 1180 */ 1181 static void 1182 lim_process_mlm_disassoc_req_ntf(struct mac_context *mac_ctx, 1183 QDF_STATUS suspend_status, uint32_t *msg) 1184 { 1185 uint16_t aid; 1186 struct qdf_mac_addr curr_bssid; 1187 tpDphHashNode stads; 1188 tLimMlmDisassocReq *mlm_disassocreq; 1189 tLimMlmDisassocCnf mlm_disassoccnf; 1190 struct pe_session *session; 1191 extern bool send_disassoc_frame; 1192 tLimMlmStates mlm_state; 1193 struct disassoc_rsp *sme_disassoc_rsp; 1194 1195 if (QDF_STATUS_SUCCESS != suspend_status) 1196 pe_err("Suspend Status is not success %X", 1197 suspend_status); 1198 1199 mlm_disassocreq = (tLimMlmDisassocReq *) msg; 1200 1201 session = pe_find_session_by_session_id(mac_ctx, 1202 mlm_disassocreq->sessionId); 1203 if (!session) { 1204 pe_err("session does not exist for given sessionId %d", 1205 mlm_disassocreq->sessionId); 1206 mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1207 goto end; 1208 } 1209 1210 pe_debug("Process DisAssoc Req on sessionID %d Systemrole %d" 1211 "mlmstate %d from: " QDF_MAC_ADDR_STR, 1212 mlm_disassocreq->sessionId, GET_LIM_SYSTEM_ROLE(session), 1213 session->limMlmState, 1214 QDF_MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes)); 1215 1216 qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE); 1217 1218 switch (GET_LIM_SYSTEM_ROLE(session)) { 1219 case eLIM_STA_ROLE: 1220 if (!qdf_is_macaddr_equal(&mlm_disassocreq->peer_macaddr, 1221 &curr_bssid)) { 1222 pe_warn("received MLM_DISASSOC_REQ with invalid BSS id"); 1223 lim_print_mac_addr(mac_ctx, 1224 mlm_disassocreq->peer_macaddr.bytes, LOGW); 1225 1226 /* 1227 * Disassociation response due to host triggered 1228 * disassociation 1229 */ 1230 sme_disassoc_rsp = 1231 qdf_mem_malloc(sizeof(*sme_disassoc_rsp)); 1232 if (!sme_disassoc_rsp) { 1233 qdf_mem_free(mlm_disassocreq); 1234 return; 1235 } 1236 1237 pe_debug("send disassoc rsp with ret code %d for" QDF_MAC_ADDR_STR, 1238 eSIR_SME_DEAUTH_STATUS, 1239 QDF_MAC_ADDR_ARRAY( 1240 mlm_disassocreq->peer_macaddr.bytes)); 1241 1242 sme_disassoc_rsp->messageType = eWNI_SME_DISASSOC_RSP; 1243 sme_disassoc_rsp->length = sizeof(*sme_disassoc_rsp); 1244 sme_disassoc_rsp->sessionId = 1245 mlm_disassocreq->sessionId; 1246 sme_disassoc_rsp->status_code = eSIR_SME_DEAUTH_STATUS; 1247 1248 qdf_copy_macaddr(&sme_disassoc_rsp->peer_macaddr, 1249 &mlm_disassocreq->peer_macaddr); 1250 msg = (uint32_t *)sme_disassoc_rsp; 1251 1252 lim_send_sme_disassoc_deauth_ntf(mac_ctx, 1253 QDF_STATUS_SUCCESS, msg); 1254 qdf_mem_free(mlm_disassocreq); 1255 return; 1256 1257 } 1258 break; 1259 case eLIM_STA_IN_IBSS_ROLE: 1260 break; 1261 case eLIM_AP_ROLE: 1262 case eLIM_P2P_DEVICE_GO: 1263 if (true == 1264 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) { 1265 pe_err("CAC timer is running, drop disassoc from going out"); 1266 mlm_disassoccnf.resultCode = eSIR_SME_SUCCESS; 1267 goto end; 1268 } 1269 break; 1270 default: 1271 break; 1272 } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */ 1273 1274 /* 1275 * Check if there exists a context for the peer entity 1276 * to be disassociated with. 1277 */ 1278 stads = dph_lookup_hash_entry(mac_ctx, 1279 mlm_disassocreq->peer_macaddr.bytes, 1280 &aid, &session->dph.dphHashTable); 1281 if (stads) 1282 mlm_state = stads->mlmStaContext.mlmState; 1283 1284 if ((!stads) || 1285 (stads && 1286 ((mlm_state != eLIM_MLM_LINK_ESTABLISHED_STATE) && 1287 (mlm_state != eLIM_MLM_WT_ASSOC_CNF_STATE) && 1288 (mlm_state != eLIM_MLM_ASSOCIATED_STATE)))) { 1289 /* 1290 * Received LIM_MLM_DISASSOC_REQ for STA that does not 1291 * have context or in some transit state. 1292 */ 1293 pe_warn("Invalid MLM_DISASSOC_REQ, Addr= " QDF_MAC_ADDR_STR, 1294 QDF_MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes)); 1295 if (stads) 1296 pe_err("Sta MlmState: %d", stads->mlmStaContext.mlmState); 1297 1298 /* Prepare and Send LIM_MLM_DISASSOC_CNF */ 1299 mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1300 goto end; 1301 } 1302 1303 stads->mlmStaContext.disassocReason = (tSirMacReasonCodes) 1304 mlm_disassocreq->reasonCode; 1305 stads->mlmStaContext.cleanupTrigger = mlm_disassocreq->disassocTrigger; 1306 1307 /* 1308 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE 1309 * This is to address the issue of race condition between 1310 * disconnect request from the HDD and deauth from AP 1311 */ 1312 1313 stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; 1314 1315 /* Send Disassociate frame to peer entity */ 1316 if (send_disassoc_frame && (mlm_disassocreq->reasonCode != 1317 eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) { 1318 if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq) { 1319 pe_err("pMlmDisassocReq is not NULL, freeing"); 1320 qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq. 1321 pMlmDisassocReq); 1322 } 1323 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = 1324 mlm_disassocreq; 1325 /* 1326 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE 1327 * This is to address the issue of race condition between 1328 * disconnect request from the HDD and deauth from AP 1329 */ 1330 stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; 1331 1332 lim_send_disassoc_mgmt_frame(mac_ctx, 1333 mlm_disassocreq->reasonCode, 1334 mlm_disassocreq->peer_macaddr.bytes, session, true); 1335 /* 1336 * Abort Tx so that data frames won't be sent to the AP 1337 * after sending Disassoc. 1338 */ 1339 if (LIM_IS_STA_ROLE(session)) 1340 wma_tx_abort(session->smeSessionId); 1341 } else { 1342 /* Disassoc frame is not sent OTA */ 1343 send_disassoc_frame = 1; 1344 /* Receive path cleanup with dummy packet */ 1345 if (QDF_STATUS_SUCCESS != 1346 lim_cleanup_rx_path(mac_ctx, stads, session)) { 1347 mlm_disassoccnf.resultCode = 1348 eSIR_SME_RESOURCES_UNAVAILABLE; 1349 goto end; 1350 } 1351 /* Free up buffer allocated for mlmDisassocReq */ 1352 qdf_mem_free(mlm_disassocreq); 1353 } 1354 1355 return; 1356 1357 end: 1358 qdf_mem_copy((uint8_t *) &mlm_disassoccnf.peerMacAddr, 1359 (uint8_t *) mlm_disassocreq->peer_macaddr.bytes, 1360 QDF_MAC_ADDR_SIZE); 1361 mlm_disassoccnf.aid = mlm_disassocreq->aid; 1362 mlm_disassoccnf.disassocTrigger = mlm_disassocreq->disassocTrigger; 1363 1364 /* Update PE session ID */ 1365 mlm_disassoccnf.sessionId = mlm_disassocreq->sessionId; 1366 1367 /* Free up buffer allocated for mlmDisassocReq */ 1368 qdf_mem_free(mlm_disassocreq); 1369 1370 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF, 1371 (uint32_t *) &mlm_disassoccnf); 1372 } 1373 1374 /** 1375 * lim_check_disassoc_deauth_ack_pending() - check if deauth is pending 1376 * 1377 * @mac_ctx - global MAC context 1378 * @sta_mac - station MAC 1379 * 1380 * This function checks if diassociation or deauthentication is pending for 1381 * given station MAC address. 1382 * 1383 * Return: true if pending and false otherwise. 1384 */ 1385 bool lim_check_disassoc_deauth_ack_pending(struct mac_context *mac_ctx, 1386 uint8_t *sta_mac) 1387 { 1388 tLimMlmDisassocReq *disassoc_req; 1389 tLimMlmDeauthReq *deauth_req; 1390 1391 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; 1392 deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; 1393 if ((disassoc_req && (!qdf_mem_cmp((uint8_t *) sta_mac, 1394 (uint8_t *) &disassoc_req->peer_macaddr.bytes, 1395 QDF_MAC_ADDR_SIZE))) || 1396 (deauth_req && (!qdf_mem_cmp((uint8_t *) sta_mac, 1397 (uint8_t *) &deauth_req->peer_macaddr.bytes, 1398 QDF_MAC_ADDR_SIZE)))) { 1399 pe_debug("Disassoc/Deauth ack pending"); 1400 return true; 1401 } else { 1402 pe_debug("Disassoc/Deauth Ack not pending"); 1403 return false; 1404 } 1405 } 1406 1407 /* 1408 * lim_clean_up_disassoc_deauth_req() - cleans up pending disassoc or deauth req 1409 * 1410 * @mac_ctx: mac_ctx 1411 * @sta_mac: sta mac address 1412 * @clean_rx_path: flag to indicate whether to cleanup rx path or not 1413 * 1414 * This function cleans up pending disassoc or deauth req 1415 * 1416 * Return: void 1417 */ 1418 void lim_clean_up_disassoc_deauth_req(struct mac_context *mac_ctx, 1419 uint8_t *sta_mac, bool clean_rx_path) 1420 { 1421 tLimMlmDisassocReq *mlm_disassoc_req; 1422 tLimMlmDeauthReq *mlm_deauth_req; 1423 1424 mlm_disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; 1425 if (mlm_disassoc_req && 1426 (!qdf_mem_cmp((uint8_t *) sta_mac, 1427 (uint8_t *) &mlm_disassoc_req->peer_macaddr.bytes, 1428 QDF_MAC_ADDR_SIZE))) { 1429 if (clean_rx_path) { 1430 lim_process_disassoc_ack_timeout(mac_ctx); 1431 } else { 1432 if (tx_timer_running( 1433 &mac_ctx->lim.limTimers.gLimDisassocAckTimer)) { 1434 lim_deactivate_and_change_timer(mac_ctx, 1435 eLIM_DISASSOC_ACK_TIMER); 1436 } 1437 qdf_mem_free(mlm_disassoc_req); 1438 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = 1439 NULL; 1440 } 1441 } 1442 1443 mlm_deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; 1444 if (mlm_deauth_req && 1445 (!qdf_mem_cmp((uint8_t *) sta_mac, 1446 (uint8_t *) &mlm_deauth_req->peer_macaddr.bytes, 1447 QDF_MAC_ADDR_SIZE))) { 1448 if (clean_rx_path) { 1449 lim_process_deauth_ack_timeout(mac_ctx); 1450 } else { 1451 if (tx_timer_running( 1452 &mac_ctx->lim.limTimers.gLimDeauthAckTimer)) { 1453 lim_deactivate_and_change_timer(mac_ctx, 1454 eLIM_DEAUTH_ACK_TIMER); 1455 } 1456 qdf_mem_free(mlm_deauth_req); 1457 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = 1458 NULL; 1459 } 1460 } 1461 } 1462 1463 /* 1464 * lim_process_disassoc_ack_timeout() - wrapper function around 1465 * lim_send_disassoc_cnf 1466 * 1467 * @mac_ctx: mac_ctx 1468 * 1469 * wrapper function around lim_send_disassoc_cnf 1470 * 1471 * Return: void 1472 */ 1473 void lim_process_disassoc_ack_timeout(struct mac_context *mac_ctx) 1474 { 1475 lim_send_disassoc_cnf(mac_ctx); 1476 } 1477 1478 /** 1479 * lim_process_mlm_disassoc_req() - This function is called to process 1480 * MLM_DISASSOC_REQ message from SME 1481 * 1482 * @mac_ctx: Pointer to Global MAC structure 1483 * @msg_buf: A pointer to the MLM message buffer 1484 * 1485 * This function is called to process MLM_DISASSOC_REQ message from SME 1486 * 1487 * @Return: None 1488 */ 1489 static void 1490 lim_process_mlm_disassoc_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 1491 { 1492 tLimMlmDisassocReq *mlm_disassoc_req; 1493 1494 if (!msg_buf) { 1495 pe_err("Buffer is Pointing to NULL"); 1496 return; 1497 } 1498 1499 mlm_disassoc_req = (tLimMlmDisassocReq *) msg_buf; 1500 pe_debug("Process disassoc req, sessionID %d from: "QDF_MAC_ADDR_STR, 1501 mlm_disassoc_req->sessionId, 1502 QDF_MAC_ADDR_ARRAY(mlm_disassoc_req->peer_macaddr.bytes)); 1503 1504 lim_process_mlm_disassoc_req_ntf(mac_ctx, QDF_STATUS_SUCCESS, 1505 (uint32_t *) msg_buf); 1506 } 1507 1508 /** 1509 * lim_process_mlm_deauth_req_ntf() - This function is process mlm deauth req 1510 * notification 1511 * 1512 * @mac_ctx: Pointer to Global MAC structure 1513 * @suspend_status: suspend status 1514 * @msg_buf: A pointer to the MLM message buffer 1515 * 1516 * This function is process mlm deauth req notification 1517 * 1518 * @Return: None 1519 */ 1520 static void 1521 lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, 1522 QDF_STATUS suspend_status, uint32_t *msg_buf) 1523 { 1524 uint16_t aid; 1525 tSirMacAddr curr_bssId; 1526 tpDphHashNode sta_ds; 1527 struct tLimPreAuthNode *auth_node; 1528 tLimMlmDeauthReq *mlm_deauth_req; 1529 tLimMlmDeauthCnf mlm_deauth_cnf; 1530 struct pe_session *session; 1531 struct deauth_rsp *sme_deauth_rsp; 1532 1533 if (QDF_STATUS_SUCCESS != suspend_status) 1534 pe_err("Suspend Status is not success %X", 1535 suspend_status); 1536 1537 mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf; 1538 session = pe_find_session_by_session_id(mac_ctx, 1539 mlm_deauth_req->sessionId); 1540 if (!session) { 1541 pe_err("session does not exist for given sessionId %d", 1542 mlm_deauth_req->sessionId); 1543 qdf_mem_free(mlm_deauth_req); 1544 return; 1545 } 1546 pe_debug("Process Deauth Req on sessionID %d Systemrole %d" 1547 "mlmstate %d from: " QDF_MAC_ADDR_STR, 1548 mlm_deauth_req->sessionId, 1549 GET_LIM_SYSTEM_ROLE(session), 1550 session->limMlmState, 1551 QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes)); 1552 sir_copy_mac_addr(curr_bssId, session->bssId); 1553 1554 switch (GET_LIM_SYSTEM_ROLE(session)) { 1555 case eLIM_STA_ROLE: 1556 switch (session->limMlmState) { 1557 case eLIM_MLM_IDLE_STATE: 1558 /* 1559 * Attempting to Deauthenticate with a pre-authenticated 1560 * peer. Deauthetiate with peer if there exists a 1561 * pre-auth context below. 1562 */ 1563 break; 1564 case eLIM_MLM_AUTHENTICATED_STATE: 1565 case eLIM_MLM_WT_ASSOC_RSP_STATE: 1566 case eLIM_MLM_LINK_ESTABLISHED_STATE: 1567 if (qdf_mem_cmp(mlm_deauth_req->peer_macaddr.bytes, 1568 curr_bssId, QDF_MAC_ADDR_SIZE)) { 1569 pe_err("received MLM_DEAUTH_REQ with invalid BSS id " 1570 "Peer MAC: "QDF_MAC_ADDR_STR 1571 " CFG BSSID Addr : "QDF_MAC_ADDR_STR, 1572 QDF_MAC_ADDR_ARRAY( 1573 mlm_deauth_req->peer_macaddr.bytes), 1574 QDF_MAC_ADDR_ARRAY(curr_bssId)); 1575 /* 1576 * Deauthentication response to host triggered 1577 * deauthentication 1578 */ 1579 sme_deauth_rsp = 1580 qdf_mem_malloc(sizeof(*sme_deauth_rsp)); 1581 if (!sme_deauth_rsp) { 1582 qdf_mem_free(mlm_deauth_req); 1583 return; 1584 } 1585 1586 pe_debug("send deauth rsp with ret code %d for" QDF_MAC_ADDR_STR, 1587 eSIR_SME_DEAUTH_STATUS, 1588 QDF_MAC_ADDR_ARRAY( 1589 mlm_deauth_req->peer_macaddr.bytes)); 1590 1591 sme_deauth_rsp->messageType = 1592 eWNI_SME_DEAUTH_RSP; 1593 sme_deauth_rsp->length = 1594 sizeof(*sme_deauth_rsp); 1595 sme_deauth_rsp->status_code = 1596 eSIR_SME_DEAUTH_STATUS; 1597 sme_deauth_rsp->sessionId = 1598 mlm_deauth_req->sessionId; 1599 1600 qdf_mem_copy(sme_deauth_rsp->peer_macaddr.bytes, 1601 mlm_deauth_req->peer_macaddr.bytes, 1602 QDF_MAC_ADDR_SIZE); 1603 1604 msg_buf = (uint32_t *)sme_deauth_rsp; 1605 1606 lim_send_sme_disassoc_deauth_ntf(mac_ctx, 1607 QDF_STATUS_SUCCESS, msg_buf); 1608 qdf_mem_free(mlm_deauth_req); 1609 return; 1610 } 1611 1612 if ((session->limMlmState == 1613 eLIM_MLM_AUTHENTICATED_STATE) || 1614 (session->limMlmState == 1615 eLIM_MLM_WT_ASSOC_RSP_STATE)) { 1616 /* Send deauth frame to peer entity */ 1617 lim_send_deauth_mgmt_frame(mac_ctx, 1618 mlm_deauth_req->reasonCode, 1619 mlm_deauth_req->peer_macaddr.bytes, 1620 session, false); 1621 /* Prepare and Send LIM_MLM_DEAUTH_CNF */ 1622 mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; 1623 session->limMlmState = eLIM_MLM_IDLE_STATE; 1624 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1625 session->peSessionId, 1626 session->limMlmState)); 1627 goto end; 1628 } 1629 break; 1630 default: 1631 pe_warn("received MLM_DEAUTH_REQ with in state %d for peer " 1632 QDF_MAC_ADDR_STR, 1633 session->limMlmState, 1634 QDF_MAC_ADDR_ARRAY( 1635 mlm_deauth_req->peer_macaddr.bytes)); 1636 lim_print_mlm_state(mac_ctx, LOGW, 1637 session->limMlmState); 1638 /* Prepare and Send LIM_MLM_DEAUTH_CNF */ 1639 mlm_deauth_cnf.resultCode = 1640 eSIR_SME_STA_NOT_AUTHENTICATED; 1641 1642 goto end; 1643 } 1644 break; 1645 case eLIM_STA_IN_IBSS_ROLE: 1646 pe_err("received MLM_DEAUTH_REQ IBSS Mode"); 1647 mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1648 goto end; 1649 case eLIM_AP_ROLE: 1650 case eLIM_P2P_DEVICE_GO: 1651 if (true == 1652 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) { 1653 pe_err("CAC timer is running, drop disassoc from going out"); 1654 mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; 1655 goto end; 1656 } 1657 break; 1658 1659 default: 1660 break; 1661 } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */ 1662 1663 /* 1664 * Check if there exists a context for the peer entity 1665 * to be deauthenticated with. 1666 */ 1667 sta_ds = dph_lookup_hash_entry(mac_ctx, 1668 mlm_deauth_req->peer_macaddr.bytes, 1669 &aid, &session->dph.dphHashTable); 1670 1671 if (!sta_ds) { 1672 /* Check if there exists pre-auth context for this STA */ 1673 auth_node = lim_search_pre_auth_list(mac_ctx, 1674 mlm_deauth_req->peer_macaddr.bytes); 1675 if (!auth_node) { 1676 /* 1677 * Received DEAUTH REQ for a STA that is neither 1678 * Associated nor Pre-authenticated. Log error, 1679 * Prepare and Send LIM_MLM_DEAUTH_CNF 1680 */ 1681 pe_warn("received MLM_DEAUTH_REQ in mlme state %d for STA that " 1682 "does not have context, Addr=" 1683 QDF_MAC_ADDR_STR, 1684 session->limMlmState, 1685 QDF_MAC_ADDR_ARRAY( 1686 mlm_deauth_req->peer_macaddr.bytes)); 1687 mlm_deauth_cnf.resultCode = 1688 eSIR_SME_STA_NOT_AUTHENTICATED; 1689 } else { 1690 mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; 1691 /* Delete STA from pre-auth STA list */ 1692 lim_delete_pre_auth_node(mac_ctx, 1693 mlm_deauth_req->peer_macaddr.bytes); 1694 /* Send Deauthentication frame to peer entity */ 1695 lim_send_deauth_mgmt_frame(mac_ctx, 1696 mlm_deauth_req->reasonCode, 1697 mlm_deauth_req->peer_macaddr.bytes, 1698 session, false); 1699 } 1700 goto end; 1701 } else if ((sta_ds->mlmStaContext.mlmState != 1702 eLIM_MLM_LINK_ESTABLISHED_STATE) && 1703 (sta_ds->mlmStaContext.mlmState != 1704 eLIM_MLM_WT_ASSOC_CNF_STATE)) { 1705 /* 1706 * received MLM_DEAUTH_REQ for STA that either has no context or 1707 * in some transit state 1708 */ 1709 pe_warn("Invalid MLM_DEAUTH_REQ, Addr="QDF_MAC_ADDR_STR, 1710 QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes)); 1711 /* Prepare and Send LIM_MLM_DEAUTH_CNF */ 1712 mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1713 goto end; 1714 } 1715 /* sta_ds->mlmStaContext.rxPurgeReq = 1; */ 1716 sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) 1717 mlm_deauth_req->reasonCode; 1718 sta_ds->mlmStaContext.cleanupTrigger = mlm_deauth_req->deauthTrigger; 1719 1720 if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) { 1721 pe_err("pMlmDeauthReq is not NULL, freeing"); 1722 qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq. 1723 pMlmDeauthReq); 1724 } 1725 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = mlm_deauth_req; 1726 1727 /* 1728 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE 1729 * This is to address the issue of race condition between 1730 * disconnect request from the HDD and disassoc from 1731 * inactivity timer. This will make sure that we will not 1732 * process disassoc if deauth is in progress for the station 1733 * and thus mlmStaContext.cleanupTrigger will not be overwritten. 1734 */ 1735 sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; 1736 /* Send Deauthentication frame to peer entity */ 1737 lim_send_deauth_mgmt_frame(mac_ctx, mlm_deauth_req->reasonCode, 1738 mlm_deauth_req->peer_macaddr.bytes, 1739 session, true); 1740 return; 1741 end: 1742 qdf_copy_macaddr(&mlm_deauth_cnf.peer_macaddr, 1743 &mlm_deauth_req->peer_macaddr); 1744 mlm_deauth_cnf.deauthTrigger = mlm_deauth_req->deauthTrigger; 1745 mlm_deauth_cnf.aid = mlm_deauth_req->aid; 1746 mlm_deauth_cnf.sessionId = mlm_deauth_req->sessionId; 1747 1748 /* Free up buffer allocated for mlmDeauthReq */ 1749 qdf_mem_free(mlm_deauth_req); 1750 lim_post_sme_message(mac_ctx, 1751 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlm_deauth_cnf); 1752 } 1753 1754 /* 1755 * lim_process_deauth_ack_timeout() - wrapper function around 1756 * lim_send_deauth_cnf 1757 * 1758 * @mac_ctx: mac_ctx 1759 * 1760 * wrapper function around lim_send_deauth_cnf 1761 * 1762 * Return: void 1763 */ 1764 void lim_process_deauth_ack_timeout(struct mac_context *mac_ctx) 1765 { 1766 lim_send_deauth_cnf(mac_ctx); 1767 } 1768 1769 /* 1770 * lim_process_mlm_deauth_req() - This function is called to process 1771 * MLM_DEAUTH_REQ message from SME 1772 * 1773 * @mac_ctx: Pointer to Global MAC structure 1774 * @msg_buf: A pointer to the MLM message buffer 1775 * 1776 * This function is called to process MLM_DEAUTH_REQ message from SME 1777 * 1778 * @Return: None 1779 */ 1780 void lim_process_mlm_deauth_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 1781 { 1782 tLimMlmDeauthReq *mlm_deauth_req; 1783 struct pe_session *session; 1784 1785 if (!msg_buf) { 1786 pe_err("Buffer is Pointing to NULL"); 1787 return; 1788 } 1789 1790 mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf; 1791 pe_debug("Process Deauth Req on sessionID %d from: " 1792 QDF_MAC_ADDR_STR, 1793 mlm_deauth_req->sessionId, 1794 QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes)); 1795 1796 session = pe_find_session_by_session_id(mac_ctx, 1797 mlm_deauth_req->sessionId); 1798 if (!session) { 1799 pe_err("session does not exist for given sessionId %d", 1800 mlm_deauth_req->sessionId); 1801 qdf_mem_free(mlm_deauth_req); 1802 return; 1803 } 1804 lim_process_mlm_deauth_req_ntf(mac_ctx, QDF_STATUS_SUCCESS, 1805 (uint32_t *) msg_buf); 1806 } 1807 1808 /** 1809 * lim_process_mlm_set_keys_req() - This function is called to process 1810 * MLM_SETKEYS_REQ message from SME 1811 * 1812 * @mac_ctx: Pointer to Global MAC structure 1813 * @msg_buf: A pointer to the MLM message buffer 1814 * 1815 * This function is called to process MLM_SETKEYS_REQ message from SME 1816 * 1817 * @Return: None 1818 */ 1819 static void 1820 lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 1821 { 1822 uint16_t aid; 1823 uint16_t sta_idx = 0; 1824 uint32_t default_key_id = 0; 1825 struct qdf_mac_addr curr_bssid; 1826 tpDphHashNode sta_ds; 1827 tLimMlmSetKeysReq *mlm_set_keys_req; 1828 tLimMlmSetKeysCnf mlm_set_keys_cnf; 1829 struct pe_session *session; 1830 1831 if (!msg_buf) { 1832 pe_err("Buffer is Pointing to NULL"); 1833 return; 1834 } 1835 1836 mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf; 1837 if (mac_ctx->lim.gpLimMlmSetKeysReq) { 1838 qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq, 1839 sizeof(*mlm_set_keys_req)); 1840 qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq); 1841 mac_ctx->lim.gpLimMlmSetKeysReq = NULL; 1842 } 1843 /* Hold onto the SetKeys request parameters */ 1844 mac_ctx->lim.gpLimMlmSetKeysReq = (void *)mlm_set_keys_req; 1845 session = pe_find_session_by_session_id(mac_ctx, 1846 mlm_set_keys_req->sessionId); 1847 if (!session) { 1848 pe_err("session does not exist for given sessionId"); 1849 qdf_mem_zero(mlm_set_keys_req->key, 1850 sizeof(mlm_set_keys_req->key)); 1851 mlm_set_keys_req->numKeys = 0; 1852 qdf_mem_free(mlm_set_keys_req); 1853 mac_ctx->lim.gpLimMlmSetKeysReq = NULL; 1854 return; 1855 } 1856 1857 pe_debug("Received MLM_SETKEYS_REQ with parameters:" 1858 "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - ", 1859 mlm_set_keys_req->aid, mlm_set_keys_req->edType, 1860 mlm_set_keys_req->numKeys); 1861 lim_print_mac_addr(mac_ctx, mlm_set_keys_req->peer_macaddr.bytes, LOGD); 1862 qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE); 1863 1864 switch (GET_LIM_SYSTEM_ROLE(session)) { 1865 case eLIM_STA_ROLE: 1866 /* 1867 * In case of TDLS, peerMac address need not be BssId. Skip this 1868 * check if TDLS is enabled. 1869 */ 1870 #ifndef FEATURE_WLAN_TDLS 1871 if ((!qdf_is_macaddr_broadcast( 1872 &mlm_set_keys_req->peer_macaddr)) && 1873 (!qdf_is_macaddr_equal(&mlm_set_keys_req->peer_macaddr, 1874 &curr_bssid))) { 1875 pe_debug("Received MLM_SETKEYS_REQ with invalid BSSID" 1876 QDF_MAC_ADDR_STR, 1877 QDF_MAC_ADDR_ARRAY(mlm_set_keys_req-> 1878 peer_macaddr.bytes)); 1879 /* 1880 * Prepare and Send LIM_MLM_SETKEYS_CNF with error code 1881 */ 1882 mlm_set_keys_cnf.resultCode = 1883 eSIR_SME_INVALID_PARAMETERS; 1884 goto end; 1885 } 1886 #endif 1887 break; 1888 case eLIM_STA_IN_IBSS_ROLE: 1889 /* 1890 * update the IBSS PE session encrption type based on the 1891 * key type 1892 */ 1893 session->encryptType = mlm_set_keys_req->edType; 1894 break; 1895 default: 1896 break; 1897 } 1898 1899 /* 1900 * Use the "unicast" parameter to determine if the "Group Keys" 1901 * are being set. 1902 * mlm_set_keys_req->key.unicast = 0 -> Multicast/broadcast 1903 * mlm_set_keys_req->key.unicast - 1 -> Unicast keys are being set 1904 */ 1905 if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) { 1906 pe_debug("Trying to set Group Keys...%d", 1907 mlm_set_keys_req->sessionId); 1908 /* 1909 * When trying to set Group Keys for any security mode other 1910 * than WEP, use the STA Index corresponding to the AP... 1911 */ 1912 switch (mlm_set_keys_req->edType) { 1913 case eSIR_ED_CCMP: 1914 case eSIR_ED_GCMP: 1915 case eSIR_ED_GCMP_256: 1916 #ifdef WLAN_FEATURE_11W 1917 case eSIR_ED_AES_128_CMAC: 1918 case eSIR_ED_AES_GMAC_128: 1919 case eSIR_ED_AES_GMAC_256: 1920 #endif 1921 sta_idx = session->staId; 1922 break; 1923 default: 1924 break; 1925 } 1926 } else { 1927 pe_debug("Trying to set Unicast Keys..."); 1928 /* 1929 * Check if there exists a context for the 1930 * peer entity for which keys need to be set. 1931 */ 1932 sta_ds = dph_lookup_hash_entry(mac_ctx, 1933 mlm_set_keys_req->peer_macaddr.bytes, &aid, 1934 &session->dph.dphHashTable); 1935 if ((!sta_ds) || 1936 ((sta_ds->mlmStaContext.mlmState != 1937 eLIM_MLM_LINK_ESTABLISHED_STATE) && 1938 !LIM_IS_AP_ROLE(session))) { 1939 /* 1940 * Received LIM_MLM_SETKEYS_REQ for STA that does not 1941 * have context or in some transit state. 1942 */ 1943 pe_debug("Invalid MLM_SETKEYS_REQ, Addr = " 1944 QDF_MAC_ADDR_STR, 1945 QDF_MAC_ADDR_ARRAY(mlm_set_keys_req-> 1946 peer_macaddr.bytes)); 1947 /* Prepare and Send LIM_MLM_SETKEYS_CNF */ 1948 mlm_set_keys_cnf.resultCode = 1949 eSIR_SME_INVALID_PARAMETERS; 1950 goto end; 1951 } else { 1952 sta_idx = sta_ds->staIndex; 1953 } 1954 } 1955 1956 if ((mlm_set_keys_req->numKeys == 0) 1957 && (mlm_set_keys_req->edType != eSIR_ED_NONE)) { 1958 /* 1959 * Broadcast/Multicast Keys (for WEP!!) are NOT sent 1960 * via this interface!! This indicates to HAL that the WEP Keys 1961 * need to be extracted from the CFG and applied to hardware 1962 */ 1963 default_key_id = 0xff; 1964 } else if (mlm_set_keys_req->key[0].keyId && 1965 ((mlm_set_keys_req->edType == eSIR_ED_WEP40) || 1966 (mlm_set_keys_req->edType == eSIR_ED_WEP104))) { 1967 /* 1968 * If the Key Id is non zero and encryption mode is WEP, 1969 * the key index is coming from the upper layers so that key 1970 * only need to be used as the default tx key, This is being 1971 * used only in case of WEP mode in HAL 1972 */ 1973 default_key_id = mlm_set_keys_req->key[0].keyId; 1974 } else { 1975 default_key_id = 0; 1976 } 1977 pe_debug("Trying to set keys for STA Index [%d], using default_key_id [%d]", 1978 sta_idx, default_key_id); 1979 1980 if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) { 1981 session->limPrevMlmState = session->limMlmState; 1982 session->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE; 1983 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1984 session->peSessionId, session->limMlmState)); 1985 pe_debug("Trying to set Group Keys...%d", 1986 session->peSessionId); 1987 /* Package WMA_SET_BSSKEY_REQ message parameters */ 1988 lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session); 1989 1990 return; 1991 } else { 1992 /* 1993 * Package WMA_SET_STAKEY_REQ / WMA_SET_STA_BCASTKEY_REQ message 1994 * parameters 1995 */ 1996 lim_send_set_sta_key_req(mac_ctx, mlm_set_keys_req, sta_idx, 1997 (uint8_t) default_key_id, session, 1998 true); 1999 return; 2000 } 2001 end: 2002 mlm_set_keys_cnf.sessionId = mlm_set_keys_req->sessionId; 2003 lim_post_sme_set_keys_cnf(mac_ctx, mlm_set_keys_req, &mlm_set_keys_cnf); 2004 } 2005 2006 void lim_process_join_failure_timeout(struct mac_context *mac_ctx) 2007 { 2008 tLimMlmJoinCnf mlm_join_cnf; 2009 uint32_t len; 2010 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2011 host_log_rssi_pkt_type *rssi_log = NULL; 2012 #endif 2013 struct pe_session *session; 2014 2015 session = pe_find_session_by_session_id(mac_ctx, 2016 mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId); 2017 if (!session) { 2018 pe_err("Session Does not exist for given sessionID"); 2019 return; 2020 } 2021 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2022 WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, 2023 host_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); 2024 if (rssi_log) 2025 rssi_log->rssi = session->rssi; 2026 WLAN_HOST_DIAG_LOG_REPORT(rssi_log); 2027 #endif 2028 2029 if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) { 2030 len = sizeof(tSirMacAddr); 2031 /* Change timer for future activations */ 2032 lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER); 2033 /* Change Periodic probe req timer for future activation */ 2034 lim_deactivate_and_change_timer(mac_ctx, 2035 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); 2036 /* Issue MLM join confirm with timeout reason code */ 2037 pe_err("Join Failure Timeout, In eLIM_MLM_WT_JOIN_BEACON_STATE session:%d " 2038 QDF_MAC_ADDR_STR, 2039 session->peSessionId, 2040 QDF_MAC_ADDR_ARRAY(session->bssId)); 2041 2042 mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE; 2043 mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; 2044 session->limMlmState = eLIM_MLM_IDLE_STATE; 2045 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2046 session->peSessionId, session->limMlmState)); 2047 /* Update PE session Id */ 2048 mlm_join_cnf.sessionId = session->peSessionId; 2049 /* Freeup buffer allocated to join request */ 2050 if (session->pLimMlmJoinReq) { 2051 qdf_mem_free(session->pLimMlmJoinReq); 2052 session->pLimMlmJoinReq = NULL; 2053 } 2054 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, 2055 (uint32_t *) &mlm_join_cnf); 2056 return; 2057 } else { 2058 pe_warn("received unexpected JOIN failure timeout in state %X", 2059 session->limMlmState); 2060 lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState); 2061 } 2062 } 2063 2064 /** 2065 * lim_process_periodic_join_probe_req_timer() - This function is called to 2066 * process periodic probe request send during joining process. 2067 * 2068 * @mac_ctx: Pointer to Global MAC structure 2069 * 2070 * This function is called to process periodic probe request send during 2071 * joining process. 2072 * 2073 * @Return None 2074 */ 2075 static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ctx) 2076 { 2077 struct pe_session *session; 2078 tSirMacSSid ssid; 2079 2080 session = pe_find_session_by_session_id(mac_ctx, 2081 mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId); 2082 if (!session) { 2083 pe_err("session does not exist for given SessionId: %d", 2084 mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer. 2085 sessionId); 2086 return; 2087 } 2088 2089 if ((true == 2090 tx_timer_running(&mac_ctx->lim.limTimers.gLimJoinFailureTimer)) 2091 && (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) { 2092 qdf_mem_copy(ssid.ssId, session->ssId.ssId, 2093 session->ssId.length); 2094 ssid.length = session->ssId.length; 2095 lim_send_probe_req_mgmt_frame(mac_ctx, &ssid, 2096 session->pLimMlmJoinReq->bssDescription.bssId, 2097 wlan_reg_freq_to_chan(mac_ctx->pdev, 2098 session->curr_op_freq), 2099 session->self_mac_addr, session->dot11mode, 2100 &session->lim_join_req->addIEScan.length, 2101 session->lim_join_req->addIEScan.addIEdata); 2102 lim_deactivate_and_change_timer(mac_ctx, 2103 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); 2104 /* Activate Join Periodic Probe Req timer */ 2105 if (tx_timer_activate( 2106 &mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) != 2107 TX_SUCCESS) { 2108 pe_warn("could not activate Periodic Join req failure timer"); 2109 return; 2110 } 2111 } 2112 } 2113 2114 /** 2115 * lim_process_auth_retry_timer()- function to Retry Auth 2116 * @mac_ctx:pointer to global mac 2117 * 2118 * Return: void 2119 */ 2120 2121 static void lim_process_auth_retry_timer(struct mac_context *mac_ctx) 2122 { 2123 struct pe_session * session_entry; 2124 2125 session_entry = 2126 pe_find_session_by_session_id(mac_ctx, 2127 mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId); 2128 if (!session_entry) { 2129 pe_err("session does not exist for given SessionId: %d", 2130 mac_ctx->lim.limTimers. 2131 g_lim_periodic_auth_retry_timer.sessionId); 2132 return; 2133 } 2134 2135 if (tx_timer_running(&mac_ctx->lim.limTimers.gLimAuthFailureTimer) && 2136 (session_entry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) && 2137 (LIM_AUTH_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) { 2138 tSirMacAuthFrameBody auth_frame; 2139 2140 /* 2141 * Send the auth retry only in case we have received ack failure 2142 * else just restart the retry timer. 2143 */ 2144 if (LIM_AUTH_ACK_RCD_FAILURE == mac_ctx->auth_ack_status) { 2145 /* Prepare & send Authentication frame */ 2146 auth_frame.authAlgoNumber = 2147 (uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType; 2148 auth_frame.authTransactionSeqNumber = 2149 SIR_MAC_AUTH_FRAME_1; 2150 auth_frame.authStatusCode = 0; 2151 pe_debug("Retry Auth"); 2152 mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD; 2153 lim_increase_fils_sequence_number(session_entry); 2154 lim_send_auth_mgmt_frame(mac_ctx, 2155 &auth_frame, 2156 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 2157 LIM_NO_WEP_IN_FC, session_entry); 2158 } 2159 2160 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); 2161 2162 /* Activate Auth Retry timer */ 2163 if (tx_timer_activate 2164 (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer) 2165 != TX_SUCCESS) { 2166 pe_err("could not activate Auth Retry failure timer"); 2167 return; 2168 } 2169 } 2170 return; 2171 } /*** lim_process_auth_retry_timer() ***/ 2172 2173 void lim_process_auth_failure_timeout(struct mac_context *mac_ctx) 2174 { 2175 /* fetch the pe_session based on the sessionId */ 2176 struct pe_session *session; 2177 uint32_t val; 2178 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2179 host_log_rssi_pkt_type *rssi_log = NULL; 2180 #endif 2181 2182 session = pe_find_session_by_session_id(mac_ctx, 2183 mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId); 2184 if (!session) { 2185 pe_err("Session Does not exist for given sessionID"); 2186 return; 2187 } 2188 2189 pe_warn("received AUTH failure timeout in sessionid %d " 2190 "limMlmstate %X limSmeState %X", 2191 session->peSessionId, session->limMlmState, 2192 session->limSmeState); 2193 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2194 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT, session, 2195 0, AUTH_FAILURE_TIMEOUT); 2196 2197 WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, host_log_rssi_pkt_type, 2198 LOG_WLAN_RSSI_UPDATE_C); 2199 if (rssi_log) 2200 rssi_log->rssi = session->rssi; 2201 WLAN_HOST_DIAG_LOG_REPORT(rssi_log); 2202 #endif 2203 2204 switch (session->limMlmState) { 2205 case eLIM_MLM_WT_AUTH_FRAME2_STATE: 2206 case eLIM_MLM_WT_AUTH_FRAME4_STATE: 2207 /* 2208 * Requesting STA did not receive next auth frame before Auth 2209 * Failure timeout. Issue MLM auth confirm with timeout reason 2210 * code. Restore default failure timeout 2211 */ 2212 if (QDF_P2P_CLIENT_MODE == session->opmode && 2213 session->defaultAuthFailureTimeout) { 2214 if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT, 2215 session->defaultAuthFailureTimeout)) { 2216 val = session->defaultAuthFailureTimeout; 2217 } else { 2218 val = cfg_default(CFG_AUTH_FAILURE_TIMEOUT); 2219 session->defaultAuthFailureTimeout = val; 2220 } 2221 mac_ctx->mlme_cfg->timeouts.auth_failure_timeout = val; 2222 } 2223 2224 lim_restore_from_auth_state(mac_ctx, 2225 eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, 2226 eSIR_MAC_UNSPEC_FAILURE_REASON, session); 2227 break; 2228 default: 2229 /* 2230 * Auth failure timer should not have timed out 2231 * in states other than wt_auth_frame2/4 2232 */ 2233 pe_err("received unexpected AUTH failure timeout in state %X", 2234 session->limMlmState); 2235 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 2236 break; 2237 } 2238 } 2239 2240 /** 2241 * lim_process_auth_rsp_timeout() - This function is called to process Min 2242 * Channel Timeout during channel scan. 2243 * 2244 * @mac_ctx: Pointer to Global MAC structure 2245 * 2246 * This function is called to process Min Channel Timeout during channel scan. 2247 * 2248 * @Return: None 2249 */ 2250 static void 2251 lim_process_auth_rsp_timeout(struct mac_context *mac_ctx, uint32_t auth_idx) 2252 { 2253 struct tLimPreAuthNode *auth_node; 2254 struct pe_session *session; 2255 uint8_t session_id; 2256 2257 auth_node = lim_get_pre_auth_node_from_index(mac_ctx, 2258 &mac_ctx->lim.gLimPreAuthTimerTable, auth_idx); 2259 if (!auth_node) { 2260 pe_warn("Invalid auth node"); 2261 return; 2262 } 2263 2264 session = pe_find_session_by_bssid(mac_ctx, auth_node->peerMacAddr, 2265 &session_id); 2266 if (!session) { 2267 pe_warn("session does not exist for given BSSID"); 2268 return; 2269 } 2270 2271 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2272 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT, 2273 session, 0, AUTH_RESPONSE_TIMEOUT); 2274 #endif 2275 2276 if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) { 2277 if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) { 2278 pe_err("received AUTH rsp timeout in unexpected " 2279 "state for MAC address: " QDF_MAC_ADDR_STR, 2280 QDF_MAC_ADDR_ARRAY(auth_node->peerMacAddr)); 2281 } else { 2282 auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE; 2283 auth_node->fTimerStarted = 0; 2284 pe_debug("AUTH rsp timedout for MAC address " 2285 QDF_MAC_ADDR_STR, 2286 QDF_MAC_ADDR_ARRAY(auth_node->peerMacAddr)); 2287 /* Change timer to reactivate it in future */ 2288 lim_deactivate_and_change_per_sta_id_timer(mac_ctx, 2289 eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx); 2290 lim_delete_pre_auth_node(mac_ctx, 2291 auth_node->peerMacAddr); 2292 } 2293 } 2294 } 2295 2296 void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, 2297 uint32_t msg_type) 2298 { 2299 2300 tLimMlmAssocCnf mlm_assoc_cnf; 2301 struct pe_session *session; 2302 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2303 host_log_rssi_pkt_type *rssi_log = NULL; 2304 #endif 2305 /* 2306 * to fetch the lim/mlm state based on the session_id, use the 2307 * below pe_session 2308 */ 2309 uint8_t session_id; 2310 2311 if (msg_type == LIM_ASSOC) 2312 session_id = 2313 mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId; 2314 else 2315 session_id = 2316 mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId; 2317 2318 session = pe_find_session_by_session_id(mac_ctx, session_id); 2319 if (!session) { 2320 pe_err("Session Does not exist for given sessionID"); 2321 return; 2322 } 2323 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2324 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_TIMEOUT, 2325 session, 0, 0); 2326 2327 WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, 2328 host_log_rssi_pkt_type, 2329 LOG_WLAN_RSSI_UPDATE_C); 2330 if (rssi_log) 2331 rssi_log->rssi = session->rssi; 2332 WLAN_HOST_DIAG_LOG_REPORT(rssi_log); 2333 #endif 2334 2335 pe_debug("Re/Association Response not received before timeout"); 2336 2337 /* 2338 * Send Deauth to handle the scenareo where association timeout happened 2339 * when device has missed the assoc resp sent by peer. 2340 * By sending deauth try to clear the session created on peer device. 2341 */ 2342 pe_debug("Sessionid: %d try sending deauth on channel freq %d to BSSID: " 2343 QDF_MAC_ADDR_STR, session->peSessionId, 2344 session->curr_op_freq, 2345 QDF_MAC_ADDR_ARRAY(session->bssId)); 2346 lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON, 2347 session->bssId, session, false); 2348 2349 if ((LIM_IS_AP_ROLE(session)) || 2350 ((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) && 2351 (session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) && 2352 (session->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) { 2353 /* 2354 * Re/Assoc failure timer should not have timedout on AP 2355 * or in a state other than wt_re/assoc_response. 2356 */ 2357 pe_warn("received unexpected REASSOC failure timeout in state %X for role %d", 2358 session->limMlmState, 2359 GET_LIM_SYSTEM_ROLE(session)); 2360 lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState); 2361 return; 2362 } 2363 2364 if ((msg_type == LIM_ASSOC) || ((msg_type == LIM_REASSOC) 2365 && (session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) { 2366 pe_err("(Re)Assoc Failure Timeout occurred"); 2367 session->limMlmState = eLIM_MLM_IDLE_STATE; 2368 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2369 session->peSessionId, session->limMlmState)); 2370 /* Change timer for future activations */ 2371 lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER); 2372 /* 2373 * Free up buffer allocated for JoinReq held by 2374 * MLM state machine 2375 */ 2376 if (session->pLimMlmJoinReq) { 2377 qdf_mem_free(session->pLimMlmJoinReq); 2378 session->pLimMlmJoinReq = NULL; 2379 } 2380 /* To remove the preauth node in case of fail to associate */ 2381 if (lim_search_pre_auth_list(mac_ctx, session->bssId)) { 2382 pe_debug("delete pre auth node for "QDF_MAC_ADDR_STR, 2383 QDF_MAC_ADDR_ARRAY(session->bssId)); 2384 lim_delete_pre_auth_node(mac_ctx, 2385 session->bssId); 2386 } 2387 2388 mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE; 2389 mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; 2390 /* Update PE session Id */ 2391 mlm_assoc_cnf.sessionId = session->peSessionId; 2392 if (msg_type == LIM_ASSOC) { 2393 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 2394 (uint32_t *) &mlm_assoc_cnf); 2395 } else { 2396 /* 2397 * Will come here only in case of 11r, Ese FT 2398 * when reassoc rsp is not received and we 2399 * receive a reassoc - timesout 2400 */ 2401 mlm_assoc_cnf.resultCode = 2402 eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE; 2403 lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF, 2404 (uint32_t *) &mlm_assoc_cnf); 2405 } 2406 } else { 2407 /* 2408 * Restore pre-reassoc req state. 2409 * Set BSSID to currently associated AP address. 2410 */ 2411 session->limMlmState = session->limPrevMlmState; 2412 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2413 session->peSessionId, session->limMlmState)); 2414 lim_restore_pre_reassoc_state(mac_ctx, 2415 eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, 2416 eSIR_MAC_UNSPEC_FAILURE_STATUS, session); 2417 } 2418 } 2419 2420 /** 2421 * lim_set_channel() - set channel api for lim 2422 * 2423 * @mac_ctx: Pointer to Global MAC structure 2424 * @channel: power save state 2425 * @ch_center_freq_seg0: center freq seq 0 2426 * @ch_center_freq_seg1: center freq seq 1 2427 * @ch_width: channel width 2428 * @max_tx_power: max tx power 2429 * @pe_session_id: pe session id 2430 * 2431 * set channel api for lim 2432 * 2433 * @Return: None 2434 */ 2435 void lim_set_channel(struct mac_context *mac_ctx, uint8_t channel, 2436 uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1, 2437 enum phy_ch_width ch_width, int8_t max_tx_power, 2438 uint8_t pe_session_id, uint32_t cac_duration_ms, 2439 uint32_t dfs_regdomain) 2440 { 2441 struct pe_session *pe_session; 2442 2443 pe_session = pe_find_session_by_session_id(mac_ctx, pe_session_id); 2444 2445 if (!pe_session) { 2446 pe_err("Invalid PE session: %d", pe_session_id); 2447 return; 2448 } 2449 lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0, 2450 ch_center_freq_seg1, ch_width, 2451 max_tx_power, pe_session_id, false, 2452 cac_duration_ms, dfs_regdomain); 2453 } 2454