1 /* 2 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "cds_api.h" 21 #include "wni_cfg.h" 22 #include "ani_global.h" 23 #include "sir_api.h" 24 #include "sir_params.h" 25 #include "cfg_ucfg_api.h" 26 #include "sch_api.h" 27 #include "utils_api.h" 28 #include "lim_utils.h" 29 #include "lim_assoc_utils.h" 30 #include "lim_prop_exts_utils.h" 31 #include "lim_security_utils.h" 32 #include "lim_send_messages.h" 33 #include "lim_send_messages.h" 34 #include "lim_session_utils.h" 35 #include <lim_ft.h> 36 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 37 #include "host_diag_core_log.h" 38 #endif 39 #include "wma_if.h" 40 #include "wma.h" 41 #include "wlan_reg_services_api.h" 42 #include "lim_process_fils.h" 43 #include "wlan_mlme_public_struct.h" 44 #include "../../core/src/vdev_mgr_ops.h" 45 #include "wlan_pmo_ucfg_api.h" 46 #include "wlan_cp_stats_utils_api.h" 47 #include "wlan_objmgr_vdev_obj.h" 48 #include <wlan_cm_api.h> 49 #include <lim_mlo.h> 50 #include "wlan_mlo_mgr_peer.h" 51 #include <son_api.h> 52 #include "wifi_pos_pasn_api.h" 53 #include "rrm_api.h" 54 #include "../../core/src/wlan_cp_stats_obj_mgr_handler.h" 55 56 static void lim_process_mlm_auth_req(struct mac_context *, uint32_t *); 57 static void lim_process_mlm_assoc_req(struct mac_context *, uint32_t *); 58 static void lim_process_mlm_disassoc_req(struct mac_context *, uint32_t *); 59 60 /* MLM Timeout event handler templates */ 61 static void lim_process_auth_rsp_timeout(struct mac_context *, uint32_t); 62 static void lim_process_periodic_join_probe_req_timer(struct mac_context *); 63 static void lim_process_auth_retry_timer(struct mac_context *); 64 lim_fill_status_code(uint8_t frame_type,enum tx_ack_status ack_status,enum wlan_status_code * proto_status_code)65 static void lim_fill_status_code(uint8_t frame_type, 66 enum tx_ack_status ack_status, 67 enum wlan_status_code *proto_status_code) 68 { 69 if (frame_type == SIR_MAC_MGMT_AUTH) { 70 switch (ack_status) { 71 case LIM_TX_FAILED: 72 *proto_status_code = STATUS_AUTH_TX_FAIL; 73 break; 74 case LIM_ACK_RCD_FAILURE: 75 case LIM_ACK_NOT_RCD: 76 *proto_status_code = STATUS_AUTH_NO_ACK_RECEIVED; 77 break; 78 case LIM_ACK_RCD_SUCCESS: 79 *proto_status_code = STATUS_AUTH_NO_RESP_RECEIVED; 80 break; 81 default: 82 *proto_status_code = STATUS_UNSPECIFIED_FAILURE; 83 } 84 } else if (frame_type == SIR_MAC_MGMT_ASSOC_RSP) { 85 switch (ack_status) { 86 case LIM_TX_FAILED: 87 *proto_status_code = STATUS_ASSOC_TX_FAIL; 88 break; 89 case LIM_ACK_RCD_FAILURE: 90 case LIM_ACK_NOT_RCD: 91 *proto_status_code = STATUS_ASSOC_NO_ACK_RECEIVED; 92 break; 93 case LIM_ACK_RCD_SUCCESS: 94 *proto_status_code = STATUS_ASSOC_NO_RESP_RECEIVED; 95 break; 96 default: 97 *proto_status_code = STATUS_UNSPECIFIED_FAILURE; 98 } 99 } 100 } 101 lim_process_rrm_sta_stats_rsp_timeout(struct mac_context * mac)102 void lim_process_rrm_sta_stats_rsp_timeout(struct mac_context *mac) 103 { 104 struct pe_session *session; 105 tSirMacRadioMeasureReport rrm_report; 106 QDF_STATUS status; 107 uint8_t index; 108 tpRRMReq pcurrent_req = NULL; 109 tRrmRetStatus rrm_status; 110 111 session = pe_find_session_by_session_id(mac, 112 mac->lim.lim_timers.rrm_sta_stats_resp_timer.sessionId); 113 if (!session) { 114 pe_err("Session does not exist for given session id %d", 115 mac->lim.lim_timers.rrm_sta_stats_resp_timer.sessionId); 116 rrm_cleanup(mac, mac->rrm.rrmPEContext.rrm_sta_stats.index); 117 return; 118 } 119 120 pe_warn("STA STATS RSP timeout vdev_id %d", session->vdev_id); 121 index = mac->rrm.rrmPEContext.rrm_sta_stats.index; 122 pcurrent_req = mac->rrm.rrmPEContext.pCurrentReq[index]; 123 if (!pcurrent_req) { 124 pe_err("Current request is NULL for index %d", index); 125 qdf_mem_zero(&mac->rrm.rrmPEContext.rrm_sta_stats, 126 sizeof(mac->rrm.rrmPEContext.rrm_sta_stats)); 127 return; 128 } 129 130 if (!mac->rrm.rrmPEContext.rrm_sta_stats.rrm_sta_stats_res_count) { 131 pe_err("response not received for previous req"); 132 rrm_status = eRRM_INCAPABLE; 133 goto err; 134 } 135 136 rrm_report = mac->rrm.rrmPEContext.rrm_sta_stats.rrm_report; 137 switch (rrm_report.report.statistics_report.group_id) { 138 /* 139 * For Counter stats and Mac stats some stats will be received 140 * via FW and some via DP. So, same handling is required for both 141 * cases. 142 */ 143 case STA_STAT_GROUP_ID_COUNTER_STATS: 144 case STA_STAT_GROUP_ID_MAC_STATS: 145 status = wlan_cp_stats_infra_cp_deregister_resp_cb(mac->psoc); 146 if (QDF_IS_STATUS_ERROR(status)) 147 pe_err("failed to deregister callback %d", status); 148 149 status = 150 rrm_send_sta_stats_req( 151 mac, session, 152 mac->rrm.rrmPEContext.rrm_sta_stats.peer); 153 if (QDF_IS_STATUS_ERROR(status)) { 154 pe_err("fail to send stats req"); 155 rrm_status = eRRM_FAILURE; 156 goto err; 157 } 158 break; 159 case STA_STAT_GROUP_ID_DELAY_STATS: 160 /* TOdo: fetch from scan ie */ 161 break; 162 } 163 return; 164 err: 165 rrm_process_rrm_sta_stats_request_failure( 166 mac, session, mac->rrm.rrmPEContext.rrm_sta_stats.peer, 167 rrm_status, mac->rrm.rrmPEContext.rrm_sta_stats.index); 168 rrm_cleanup(mac, mac->rrm.rrmPEContext.rrm_sta_stats.index); 169 } 170 lim_process_sae_auth_timeout(struct mac_context * mac_ctx)171 void lim_process_sae_auth_timeout(struct mac_context *mac_ctx) 172 { 173 struct pe_session *session; 174 enum wlan_status_code proto_status_code; 175 176 session = pe_find_session_by_session_id(mac_ctx, 177 mac_ctx->lim.lim_timers.sae_auth_timer.sessionId); 178 if (!session) { 179 pe_err("Session does not exist for given session id"); 180 return; 181 } 182 183 pe_warn("SAE auth timeout sessionid %d mlmstate %X SmeState %X", 184 session->peSessionId, session->limMlmState, 185 session->limSmeState); 186 187 switch (session->limMlmState) { 188 case eLIM_MLM_WT_SAE_AUTH_STATE: 189 lim_fill_status_code(SIR_MAC_MGMT_AUTH, 190 mac_ctx->auth_ack_status, 191 &proto_status_code); 192 /* 193 * SAE authentication is not completed. Restore from 194 * auth state. 195 */ 196 if ((session->opmode == QDF_STA_MODE) || 197 (session->opmode == QDF_P2P_CLIENT_MODE)) 198 lim_restore_from_auth_state(mac_ctx, 199 eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, 200 proto_status_code, session); 201 break; 202 default: 203 /* SAE authentication is timed out in unexpected state */ 204 pe_err("received unexpected SAE auth timeout in state %X", 205 session->limMlmState); 206 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 207 break; 208 } 209 } 210 211 /** 212 * lim_process_mlm_req_messages() - process mlm request messages 213 * @mac_ctx: global MAC context 214 * @msg: mlm request message 215 * 216 * This function is called by lim_post_mlm_message(). This 217 * function handles MLM primitives invoked by SME. 218 * Depending on the message type, corresponding function will be 219 * called. 220 * ASSUMPTIONS: 221 * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes 222 * APIs exposed by Beacon Processing module for setting parameters 223 * at MAC hardware. 224 * 2. If attempt to Reassociate with an AP fails, link with current 225 * AP is restored back. 226 * 227 * Return: None 228 */ lim_process_mlm_req_messages(struct mac_context * mac_ctx,struct scheduler_msg * msg)229 void lim_process_mlm_req_messages(struct mac_context *mac_ctx, 230 struct scheduler_msg *msg) 231 { 232 switch (msg->type) { 233 case LIM_MLM_AUTH_REQ: 234 lim_process_mlm_auth_req(mac_ctx, msg->bodyptr); 235 break; 236 case LIM_MLM_ASSOC_REQ: 237 lim_process_mlm_assoc_req(mac_ctx, msg->bodyptr); 238 break; 239 case LIM_MLM_DISASSOC_REQ: 240 lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr); 241 break; 242 case SIR_LIM_JOIN_FAIL_TIMEOUT: 243 lim_process_join_failure_timeout(mac_ctx); 244 break; 245 case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: 246 lim_process_periodic_join_probe_req_timer(mac_ctx); 247 break; 248 case SIR_LIM_AUTH_FAIL_TIMEOUT: 249 lim_process_auth_failure_timeout(mac_ctx); 250 break; 251 case SIR_LIM_AUTH_RSP_TIMEOUT: 252 lim_process_auth_rsp_timeout(mac_ctx, msg->bodyval); 253 break; 254 case SIR_LIM_ASSOC_FAIL_TIMEOUT: 255 lim_process_assoc_failure_timeout(mac_ctx, msg->bodyval); 256 break; 257 case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: 258 lim_process_ft_preauth_rsp_timeout(mac_ctx); 259 break; 260 case SIR_LIM_DISASSOC_ACK_TIMEOUT: 261 lim_process_disassoc_ack_timeout(mac_ctx); 262 break; 263 case SIR_LIM_AUTH_RETRY_TIMEOUT: 264 lim_process_auth_retry_timer(mac_ctx); 265 break; 266 case SIR_LIM_AUTH_SAE_TIMEOUT: 267 lim_process_sae_auth_timeout(mac_ctx); 268 break; 269 case SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT: 270 lim_process_rrm_sta_stats_rsp_timeout(mac_ctx); 271 break; 272 case LIM_MLM_TSPEC_REQ: 273 default: 274 break; 275 } /* switch (msg->type) */ 276 } 277 update_rmfEnabled(struct bss_params * addbss_param,struct pe_session * session)278 static void update_rmfEnabled(struct bss_params *addbss_param, 279 struct pe_session *session) 280 { 281 addbss_param->rmfEnabled = session->limRmfEnabled; 282 } 283 284 /** 285 * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ 286 * @mac_ctx: global MAC context 287 * @mlm_start_req: MLM start request 288 * @session: PE session entry 289 * 290 * Package WMA_ADD_BSS_REQ to HAL, in order to start a BSS 291 * 292 * Return: eSIR_SME_SUCCESS on success, other error codes otherwise 293 */ 294 tSirResultCodes lim_mlm_add_bss(struct mac_context * mac_ctx,tLimMlmStartReq * mlm_start_req,struct pe_session * session)295 lim_mlm_add_bss(struct mac_context *mac_ctx, 296 tLimMlmStartReq *mlm_start_req, struct pe_session *session) 297 { 298 struct vdev_mlme_obj *mlme_obj; 299 struct wlan_objmgr_vdev *vdev = session->vdev; 300 uint8_t vdev_id = session->vdev_id; 301 QDF_STATUS status = QDF_STATUS_SUCCESS; 302 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 303 struct bss_params *addbss_param = NULL; 304 305 if (!wma) 306 return eSIR_SME_INVALID_PARAMETERS; 307 308 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 309 if (!mlme_obj) { 310 pe_err("vdev component object is NULL"); 311 return eSIR_SME_INVALID_PARAMETERS; 312 } 313 314 qdf_mem_copy(mlme_obj->mgmt.generic.bssid, mlm_start_req->bssId, 315 QDF_MAC_ADDR_SIZE); 316 if (lim_is_session_he_capable(session)) { 317 lim_decide_he_op(mac_ctx, &mlme_obj->proto.he_ops_info.he_ops, 318 session); 319 lim_update_usr_he_cap(mac_ctx, session); 320 } 321 322 #ifdef WLAN_FEATURE_11BE 323 if (lim_is_session_eht_capable(session)) { 324 lim_decide_eht_op(mac_ctx, 325 &mlme_obj->proto.eht_ops_info.eht_ops, 326 session); 327 lim_update_usr_eht_cap(mac_ctx, session); 328 } 329 #endif 330 331 /* Set a new state for MLME */ 332 session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE; 333 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, 334 session->limMlmState)); 335 336 status = lim_pre_vdev_start(mac_ctx, mlme_obj, session); 337 if (QDF_IS_STATUS_ERROR(status)) 338 goto send_fail_resp; 339 340 addbss_param = qdf_mem_malloc(sizeof(struct bss_params)); 341 if (!addbss_param) 342 goto send_fail_resp; 343 344 addbss_param->vhtCapable = mlm_start_req->htCapable; 345 addbss_param->htCapable = session->vhtCapability; 346 addbss_param->ch_width = session->ch_width; 347 update_rmfEnabled(addbss_param, session); 348 addbss_param->staContext.fShortGI20Mhz = 349 lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ, session); 350 addbss_param->staContext.fShortGI40Mhz = 351 lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ, session); 352 status = wma_pre_vdev_start_setup(vdev_id, addbss_param); 353 qdf_mem_free(addbss_param); 354 if (QDF_IS_STATUS_ERROR(status)) 355 goto send_fail_resp; 356 357 if (session->wps_state == SAP_WPS_DISABLED) 358 ucfg_pmo_disable_wakeup_event(wma->psoc, vdev_id, 359 WOW_PROBE_REQ_WPS_IE_EVENT); 360 status = wma_vdev_pre_start(vdev_id, false); 361 if (QDF_IS_STATUS_ERROR(status)) 362 goto peer_cleanup; 363 status = vdev_mgr_start_send(mlme_obj, false); 364 if (QDF_IS_STATUS_ERROR(status)) 365 goto peer_cleanup; 366 wma_post_vdev_start_setup(vdev_id); 367 368 return eSIR_SME_SUCCESS; 369 370 peer_cleanup: 371 wma_remove_bss_peer_on_failure(wma, vdev_id); 372 send_fail_resp: 373 wma_send_add_bss_resp(wma, vdev_id, QDF_STATUS_E_FAILURE); 374 375 return eSIR_SME_SUCCESS; 376 } 377 lim_process_mlm_start_req(struct mac_context * mac_ctx,tLimMlmStartReq * mlm_start_req)378 void lim_process_mlm_start_req(struct mac_context *mac_ctx, 379 tLimMlmStartReq *mlm_start_req) 380 { 381 tLimMlmStartCnf mlm_start_cnf; 382 struct pe_session *session = NULL; 383 384 if (!mlm_start_req) { 385 pe_err("Buffer is Pointing to NULL"); 386 return; 387 } 388 389 session = pe_find_session_by_session_id(mac_ctx, 390 mlm_start_req->sessionId); 391 if (!session) { 392 pe_err("Session Does not exist for given sessionID"); 393 mlm_start_cnf.resultCode = eSIR_SME_REFUSED; 394 goto end; 395 } 396 397 if (session->limMlmState != eLIM_MLM_IDLE_STATE) { 398 /* 399 * Should not have received Start req in states other than idle. 400 * Return Start confirm with failure code. 401 */ 402 pe_err("received unexpected MLM_START_REQ in state %X", 403 session->limMlmState); 404 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 405 mlm_start_cnf.resultCode = 406 eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; 407 goto end; 408 } 409 410 mlm_start_cnf.resultCode = 411 lim_mlm_add_bss(mac_ctx, mlm_start_req, session); 412 413 end: 414 /* Update PE session Id */ 415 mlm_start_cnf.sessionId = mlm_start_req->sessionId; 416 417 /* 418 * Respond immediately to LIM, only if MLME has not been 419 * successfully able to send WMA_ADD_BSS_REQ to HAL. 420 * Else, LIM_MLM_START_CNF will be sent after receiving 421 * WMA_ADD_BSS_RSP from HAL 422 */ 423 if (eSIR_SME_SUCCESS != mlm_start_cnf.resultCode) 424 lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf); 425 } 426 427 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 428 void lim_pasn_peer_del_all_resp_vdev_delete_resume(struct mac_context * mac,struct wlan_objmgr_vdev * vdev)429 lim_pasn_peer_del_all_resp_vdev_delete_resume(struct mac_context *mac, 430 struct wlan_objmgr_vdev *vdev) 431 { 432 if (!mac) { 433 pe_err("Mac ctx is NULL"); 434 return; 435 } 436 437 /* 438 * If PASN peer delete all command to firmware timedout, then 439 * the PASN peers will not be cleaned up. So cleanup the 440 * objmgr peers from here and reset the peer delete all in 441 * progress flag. 442 */ 443 if (wifi_pos_get_pasn_peer_count(vdev)) 444 wifi_pos_cleanup_pasn_peers(mac->psoc, vdev); 445 446 wifi_pos_set_delete_all_peer_in_progress(vdev, false); 447 448 pe_debug("Resume vdev delete"); 449 if (mac->sme.sme_vdev_del_cb) 450 mac->sme.sme_vdev_del_cb(MAC_HANDLE(mac), vdev); 451 } 452 #endif 453 lim_send_peer_create_resp(struct mac_context * mac,uint8_t vdev_id,QDF_STATUS qdf_status,uint8_t * peer_mac)454 void lim_send_peer_create_resp(struct mac_context *mac, uint8_t vdev_id, 455 QDF_STATUS qdf_status, uint8_t *peer_mac) 456 { 457 struct wlan_objmgr_vdev *vdev; 458 QDF_STATUS status; 459 460 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, 461 vdev_id, 462 WLAN_LEGACY_MAC_ID); 463 if (!vdev) 464 return; 465 status = wlan_cm_bss_peer_create_rsp(vdev, qdf_status, 466 (struct qdf_mac_addr *)peer_mac); 467 468 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 469 } 470 471 static void lim_process_mlm_post_join_suspend_link(struct mac_context * mac_ctx,struct pe_session * session)472 lim_process_mlm_post_join_suspend_link(struct mac_context *mac_ctx, 473 struct pe_session *session) 474 { 475 lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER); 476 477 /* assign appropriate sessionId to the timer object */ 478 mac_ctx->lim.lim_timers.gLimJoinFailureTimer.sessionId = 479 session->peSessionId; 480 481 /* 482 * store the channel switch session_entry in the lim 483 * global variable 484 */ 485 session->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN; 486 session->pLimMlmReassocRetryReq = NULL; 487 lim_send_switch_chnl_params(mac_ctx, session); 488 } 489 490 /** 491 * lim_process_mlm_join_req() - process mlm join request. 492 * 493 * @mac_ctx: Pointer to Global MAC structure 494 * @mlm_join_req: Pointer to the mlme join request 495 * 496 * This function is called to process MLM_JOIN_REQ message 497 * from SME. It does following: 498 * 1) Initialize LIM, HAL, DPH 499 * 2) Configure the BSS for which the JOIN REQ was received 500 * a) Send WMA_ADD_BSS_REQ to HAL - 501 * This will identify the BSS that we are interested in 502 * --AND-- 503 * Add a STA entry for the AP (in a STA context) 504 * b) Wait for WMA_ADD_BSS_RSP 505 * c) Send WMA_ADD_STA_REQ to HAL 506 * This will add the "local STA" entry to the STA table 507 * 3) Continue as before, i.e, 508 * a) Send a PROBE REQ 509 * b) Wait for PROBE RSP/BEACON containing the SSID that 510 * we are interested in 511 * c) Then start an AUTH seq 512 * d) Followed by the ASSOC seq 513 * 514 * @Return: None 515 */ lim_process_mlm_join_req(struct mac_context * mac_ctx,tLimMlmJoinReq * mlm_join_req)516 void lim_process_mlm_join_req(struct mac_context *mac_ctx, 517 tLimMlmJoinReq *mlm_join_req) 518 { 519 uint8_t sessionid; 520 struct pe_session *session; 521 522 sessionid = mlm_join_req->sessionId; 523 524 session = pe_find_session_by_session_id(mac_ctx, sessionid); 525 if (!session) { 526 pe_err("SessionId:%d does not exist", sessionid); 527 return; 528 } 529 530 session->pLimMlmJoinReq = mlm_join_req; 531 lim_process_mlm_post_join_suspend_link(mac_ctx, session); 532 } 533 534 /** 535 * lim_is_auth_req_expected() - check if auth request is expected 536 * 537 * @mac_ctx: global MAC context 538 * @session: PE session entry 539 * 540 * This function is called by lim_process_mlm_auth_req to check 541 * if auth request is expected. 542 * 543 * Return: true if expected and false otherwise 544 */ lim_is_auth_req_expected(struct mac_context * mac_ctx,struct pe_session * session)545 static bool lim_is_auth_req_expected(struct mac_context *mac_ctx, 546 struct pe_session *session) 547 { 548 bool flag = false; 549 550 /* 551 * Expect Auth request only when: 552 * 1. STA joined/associated with a BSS or 553 * 2. STA is going to authenticate with a unicast 554 * address and requested authentication algorithm is 555 * supported. 556 */ 557 558 flag = (((LIM_IS_STA_ROLE(session) && 559 ((session->limMlmState == eLIM_MLM_JOINED_STATE) || 560 (session->limMlmState == 561 eLIM_MLM_LINK_ESTABLISHED_STATE)))) && 562 (!IEEE80211_IS_MULTICAST( 563 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)) && 564 lim_is_auth_algo_supported(mac_ctx, 565 mac_ctx->lim.gpLimMlmAuthReq->authType, session)); 566 567 return flag; 568 } 569 570 /** 571 * lim_is_preauth_ctx_exists() - check if preauth context exists 572 * @mac_ctx: global MAC context 573 * @session: PE session entry 574 * @preauth_node_ptr: pointer to preauth node pointer 575 * 576 * This function is called by lim_process_mlm_auth_req to check 577 * if preauth context already exists 578 * 579 * Return: true if exists and false otherwise 580 */ lim_is_preauth_ctx_exists(struct mac_context * mac_ctx,struct pe_session * session,struct tLimPreAuthNode ** preauth_node_ptr)581 static bool lim_is_preauth_ctx_exists(struct mac_context *mac_ctx, 582 struct pe_session *session, 583 struct tLimPreAuthNode **preauth_node_ptr) 584 { 585 bool fl = false; 586 struct tLimPreAuthNode *preauth_node; 587 tpDphHashNode stads; 588 tSirMacAddr curr_bssid; 589 590 preauth_node = *preauth_node_ptr; 591 sir_copy_mac_addr(curr_bssid, session->bssId); 592 stads = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 593 &session->dph.dphHashTable); 594 preauth_node = lim_search_pre_auth_list(mac_ctx, 595 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr); 596 597 fl = (((LIM_IS_STA_ROLE(session)) && 598 (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) && 599 ((stads) && 600 (mac_ctx->lim.gpLimMlmAuthReq->authType == 601 stads->mlmStaContext.authType)) && 602 (!qdf_mem_cmp(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 603 curr_bssid, sizeof(tSirMacAddr)))) || 604 ((preauth_node) && 605 (preauth_node->authType == 606 mac_ctx->lim.gpLimMlmAuthReq->authType))); 607 608 return fl; 609 } 610 611 #ifdef WLAN_FEATURE_SAE 612 static inline lim_get_sae_keymgmt_suite(uint32_t keymgmt)613 uint32_t lim_get_sae_keymgmt_suite(uint32_t keymgmt) 614 { 615 /* Select the best SAE AKM suite supported */ 616 if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY)) 617 return WLAN_AKM_FT_SAE_EXT_KEY; 618 else if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY)) 619 return WLAN_AKM_SAE_EXT_KEY; 620 else if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_FT_SAE)) 621 return WLAN_AKM_FT_SAE; 622 else if (QDF_HAS_PARAM(keymgmt, WLAN_CRYPTO_KEY_MGMT_SAE)) 623 return WLAN_AKM_SAE; 624 625 pe_err("Invalid SAE Keymgmt suite %d", keymgmt); 626 return WLAN_AKM_SAE; 627 } 628 lim_trigger_auth_req_sae(struct mac_context * mac_ctx,struct pe_session * session,struct qdf_mac_addr * peer_bssid)629 QDF_STATUS lim_trigger_auth_req_sae(struct mac_context *mac_ctx, 630 struct pe_session *session, 631 struct qdf_mac_addr *peer_bssid) 632 { 633 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 634 struct sir_sae_info *sae_info; 635 struct scheduler_msg msg = {0}; 636 uint32_t keymgmt; 637 638 sae_info = qdf_mem_malloc(sizeof(*sae_info)); 639 if (!sae_info) 640 return QDF_STATUS_E_FAILURE; 641 642 sae_info->msg_type = eWNI_SME_TRIGGER_SAE; 643 sae_info->msg_len = sizeof(*sae_info); 644 sae_info->vdev_id = session->smeSessionId; 645 646 qdf_copy_macaddr(&sae_info->peer_mac_addr, peer_bssid); 647 keymgmt = wlan_crypto_get_param(session->vdev, 648 WLAN_CRYPTO_PARAM_KEY_MGMT); 649 sae_info->akm = lim_get_sae_keymgmt_suite(keymgmt); 650 651 sae_info->ssid.length = session->ssId.length; 652 qdf_mem_copy(sae_info->ssid.ssId, 653 session->ssId.ssId, 654 session->ssId.length); 655 656 pe_debug("vdev_id %d ssid " QDF_SSID_FMT " " QDF_MAC_ADDR_FMT "akm %d", 657 sae_info->vdev_id, 658 QDF_SSID_REF(sae_info->ssid.length, sae_info->ssid.ssId), 659 QDF_MAC_ADDR_REF(sae_info->peer_mac_addr.bytes), 660 sae_info->akm); 661 662 msg.type = eWNI_SME_TRIGGER_SAE; 663 msg.bodyptr = sae_info; 664 msg.bodyval = 0; 665 666 qdf_status = mac_ctx->lim.sme_msg_callback(mac_ctx, &msg); 667 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 668 pe_err("SAE failed for AUTH frame"); 669 qdf_mem_free(sae_info); 670 return qdf_status; 671 } 672 673 return qdf_status; 674 } 675 676 /** 677 * lim_process_mlm_auth_req_sae() - Handle SAE authentication 678 * @mac_ctx: global MAC context 679 * @session: PE session entry 680 * 681 * This function is called by lim_process_mlm_auth_req to handle SAE 682 * authentication. 683 * 684 * Return: QDF_STATUS 685 */ lim_process_mlm_auth_req_sae(struct mac_context * mac_ctx,struct pe_session * session)686 static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx, 687 struct pe_session *session) 688 { 689 QDF_STATUS qdf_status; 690 691 qdf_status = lim_trigger_auth_req_sae( 692 mac_ctx, session, 693 (struct qdf_mac_addr *)session->bssId); 694 if (QDF_IS_STATUS_ERROR(qdf_status)) 695 return qdf_status; 696 697 session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE; 698 699 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, 700 session->limMlmState)); 701 702 mac_ctx->lim.lim_timers.sae_auth_timer.sessionId = 703 session->peSessionId; 704 705 /* Activate SAE auth timer */ 706 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 707 session->peSessionId, eLIM_AUTH_SAE_TIMER)); 708 if (tx_timer_activate(&mac_ctx->lim.lim_timers.sae_auth_timer) 709 != TX_SUCCESS) { 710 pe_err("could not start Auth SAE timer"); 711 } 712 713 return qdf_status; 714 } 715 #else lim_process_mlm_auth_req_sae(struct mac_context * mac_ctx,struct pe_session * session)716 static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx, 717 struct pe_session *session) 718 { 719 return QDF_STATUS_E_NOSUPPORT; 720 } 721 #endif 722 723 724 /** 725 * lim_process_mlm_auth_req() - process lim auth request 726 * 727 * @mac_ctx: global MAC context 728 * @msg: MLM auth request message 729 * 730 * This function is called to process MLM_AUTH_REQ message from SME 731 * 732 * @Return: None 733 */ lim_process_mlm_auth_req(struct mac_context * mac_ctx,uint32_t * msg)734 static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg) 735 { 736 uint32_t num_preauth_ctx; 737 tSirMacAddr curr_bssid; 738 tSirMacAuthFrameBody *auth_frame_body; 739 tLimMlmAuthCnf mlm_auth_cnf; 740 struct tLimPreAuthNode *preauth_node = NULL; 741 uint8_t session_id; 742 struct pe_session *session; 743 744 if (!msg) { 745 pe_err("Buffer is Pointing to NULL"); 746 return; 747 } 748 749 mac_ctx->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) msg; 750 session_id = mac_ctx->lim.gpLimMlmAuthReq->sessionId; 751 session = pe_find_session_by_session_id(mac_ctx, session_id); 752 if (!session) { 753 pe_err("SessionId:%d does not exist", session_id); 754 qdf_mem_free(msg); 755 mac_ctx->lim.gpLimMlmAuthReq = NULL; 756 return; 757 } 758 759 pe_debug("vdev %d Systemrole %d mlmstate %d from: " QDF_MAC_ADDR_FMT "with authtype %d", 760 session->vdev_id, GET_LIM_SYSTEM_ROLE(session), 761 session->limMlmState, 762 QDF_MAC_ADDR_REF(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr), 763 mac_ctx->lim.gpLimMlmAuthReq->authType); 764 765 sir_copy_mac_addr(curr_bssid, session->bssId); 766 767 if (!lim_is_auth_req_expected(mac_ctx, session)) { 768 /* 769 * Unexpected auth request. 770 * Return Auth confirm with Invalid parameters code. 771 */ 772 pe_err("Auth req not expected is_privacy_enabled %d is_auth_open_system %d auth type %d", 773 mac_ctx->mlme_cfg->wep_params.is_privacy_enabled, 774 mac_ctx->mlme_cfg->wep_params.is_auth_open_system, 775 mac_ctx->lim.gpLimMlmAuthReq->authType); 776 mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 777 goto end; 778 } 779 780 /* 781 * This is a request for pre-authentication. Check if there exists 782 * context already for the requested peer OR 783 * if this request is for the AP we're currently associated with. 784 * If yes, return auth confirm immediately when 785 * requested auth type is same as the one used before. 786 */ 787 if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) { 788 pe_debug("Already have pre-auth context with peer: " 789 QDF_MAC_ADDR_FMT, 790 QDF_MAC_ADDR_REF(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)); 791 mlm_auth_cnf.resultCode = (tSirResultCodes)STATUS_SUCCESS; 792 goto end; 793 } else { 794 num_preauth_ctx = mac_ctx->mlme_cfg->lfr.max_num_pre_auth; 795 if (mac_ctx->lim.gLimNumPreAuthContexts == num_preauth_ctx) { 796 pe_warn("Number of pre-auth reached max limit"); 797 /* Return Auth confirm with reject code */ 798 mlm_auth_cnf.resultCode = 799 eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED; 800 goto end; 801 } 802 } 803 804 /* Delete pre-auth node if exists */ 805 if (preauth_node) 806 lim_delete_pre_auth_node(mac_ctx, 807 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr); 808 809 session->limPrevMlmState = session->limMlmState; 810 811 auth_frame_body = qdf_mem_malloc(sizeof(*auth_frame_body)); 812 if (!auth_frame_body) { 813 pe_err("mem alloc failed for auth frame body"); 814 return; 815 } 816 817 if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) && 818 !session->sae_pmk_cached) { 819 if (lim_process_mlm_auth_req_sae(mac_ctx, session) != 820 QDF_STATUS_SUCCESS) { 821 mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 822 qdf_mem_free(auth_frame_body); 823 goto end; 824 } else { 825 pe_debug("lim_process_mlm_auth_req_sae is successful"); 826 auth_frame_body->authAlgoNumber = eSIR_AUTH_TYPE_SAE; 827 auth_frame_body->authTransactionSeqNumber = 828 SIR_MAC_AUTH_FRAME_1; 829 auth_frame_body->authStatusCode = 0; 830 host_log_wlan_auth_info(auth_frame_body->authAlgoNumber, 831 auth_frame_body->authTransactionSeqNumber, 832 auth_frame_body->authStatusCode); 833 834 qdf_mem_free(auth_frame_body); 835 return; 836 } 837 } else 838 session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE; 839 840 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, 841 session->limMlmState)); 842 843 /* Mark auth algo as open when auth type is SAE and PMK is cached */ 844 if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) && 845 session->sae_pmk_cached) { 846 auth_frame_body->authAlgoNumber = eSIR_OPEN_SYSTEM; 847 } else { 848 auth_frame_body->authAlgoNumber = 849 (uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType; 850 } 851 852 /* Prepare & send Authentication frame */ 853 auth_frame_body->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; 854 auth_frame_body->authStatusCode = 0; 855 host_log_wlan_auth_info(auth_frame_body->authAlgoNumber, 856 auth_frame_body->authTransactionSeqNumber, 857 auth_frame_body->authStatusCode); 858 mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; 859 lim_send_auth_mgmt_frame(mac_ctx, 860 auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 861 LIM_NO_WEP_IN_FC, session); 862 863 /* assign appropriate session_id to the timer object */ 864 mac_ctx->lim.lim_timers.gLimAuthFailureTimer.sessionId = session_id; 865 866 /* assign appropriate sessionId to the timer object */ 867 mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer.sessionId = 868 session_id; 869 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); 870 /* Activate Auth failure timer */ 871 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 872 session->peSessionId, eLIM_AUTH_FAIL_TIMER)); 873 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_FAIL_TIMER); 874 if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimAuthFailureTimer) 875 != TX_SUCCESS) { 876 pe_err("could not start Auth failure timer"); 877 /* Cleanup as if auth timer expired */ 878 lim_process_auth_failure_timeout(mac_ctx); 879 } else { 880 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 881 session->peSessionId, eLIM_AUTH_RETRY_TIMER)); 882 /* Activate Auth Retry timer */ 883 if (tx_timer_activate 884 (&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) 885 != TX_SUCCESS) 886 pe_err("could not activate Auth Retry timer"); 887 } 888 889 qdf_mem_free(auth_frame_body); 890 891 return; 892 end: 893 qdf_mem_copy((uint8_t *) &mlm_auth_cnf.peerMacAddr, 894 (uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 895 sizeof(tSirMacAddr)); 896 897 mlm_auth_cnf.authType = mac_ctx->lim.gpLimMlmAuthReq->authType; 898 mlm_auth_cnf.sessionId = session_id; 899 900 qdf_mem_free(mac_ctx->lim.gpLimMlmAuthReq); 901 mac_ctx->lim.gpLimMlmAuthReq = NULL; 902 pe_debug("SessionId:%d LimPostSme LIM_MLM_AUTH_CNF", 903 session_id); 904 lim_post_sme_message(mac_ctx, LIM_MLM_AUTH_CNF, 905 (uint32_t *) &mlm_auth_cnf); 906 } 907 lim_store_pmfcomeback_timerinfo(struct pe_session * session_entry)908 static void lim_store_pmfcomeback_timerinfo(struct pe_session *session_entry) 909 { 910 if (session_entry->opmode != QDF_STA_MODE || 911 !session_entry->limRmfEnabled) 912 return; 913 /* 914 * Store current MLM state in case ASSOC response returns with 915 * TRY_AGAIN_LATER return code. 916 */ 917 session_entry->pmf_retry_timer_info.lim_prev_mlm_state = 918 session_entry->limPrevMlmState; 919 session_entry->pmf_retry_timer_info.lim_mlm_state = 920 session_entry->limMlmState; 921 } 922 923 /** 924 * lim_process_mlm_assoc_req() - This function is called to process 925 * MLM_ASSOC_REQ message from SME 926 * 927 * @mac_ctx: Pointer to Global MAC structure 928 * @msg_buf: A pointer to the MLM message buffer 929 * 930 * This function is called to process MLM_ASSOC_REQ message from SME 931 * 932 * @Return None 933 */ 934 lim_process_mlm_assoc_req(struct mac_context * mac_ctx,uint32_t * msg_buf)935 static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 936 { 937 tSirMacAddr curr_bssId; 938 tLimMlmAssocReq *mlm_assoc_req; 939 tLimMlmAssocCnf mlm_assoc_cnf; 940 struct pe_session *session_entry; 941 942 if (!msg_buf) { 943 pe_err("Buffer is Pointing to NULL"); 944 return; 945 } 946 947 mlm_assoc_req = (tLimMlmAssocReq *) msg_buf; 948 session_entry = pe_find_session_by_session_id(mac_ctx, 949 mlm_assoc_req->sessionId); 950 if (!session_entry) { 951 pe_err("SessionId:%d Session Does not exist", 952 mlm_assoc_req->sessionId); 953 qdf_mem_free(mlm_assoc_req); 954 return; 955 } 956 957 sir_copy_mac_addr(curr_bssId, session_entry->bssId); 958 959 if (!(!LIM_IS_AP_ROLE(session_entry) && 960 (session_entry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || 961 session_entry->limMlmState == eLIM_MLM_JOINED_STATE) && 962 (!qdf_mem_cmp(mlm_assoc_req->peerMacAddr, 963 curr_bssId, sizeof(tSirMacAddr))))) { 964 /* 965 * Received Association request either in invalid state 966 * or to a peer MAC entity whose address is different 967 * from one that STA is currently joined with or on AP. 968 * Return Assoc confirm with Invalid parameters code. 969 */ 970 pe_warn("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= " 971 QDF_MAC_ADDR_FMT, session_entry->limMlmState, 972 GET_LIM_SYSTEM_ROLE(session_entry), 973 QDF_MAC_ADDR_REF(mlm_assoc_req->peerMacAddr)); 974 lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState); 975 mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 976 mlm_assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 977 goto end; 978 } 979 980 /* map the session entry pointer to the AssocFailureTimer */ 981 mac_ctx->lim.lim_timers.gLimAssocFailureTimer.sessionId = 982 mlm_assoc_req->sessionId; 983 lim_store_pmfcomeback_timerinfo(session_entry); 984 session_entry->limPrevMlmState = session_entry->limMlmState; 985 session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE; 986 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 987 session_entry->peSessionId, 988 session_entry->limMlmState)); 989 pe_debug("vdev %d Sending Assoc_Req Frame, timeout %d msec", 990 session_entry->vdev_id, 991 (int)mac_ctx->lim.lim_timers.gLimAssocFailureTimer.initScheduleTimeInMsecs); 992 993 /* Prepare and send Association request frame */ 994 lim_send_assoc_req_mgmt_frame(mac_ctx, mlm_assoc_req, session_entry); 995 996 /* Start association failure timer */ 997 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 998 session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER)); 999 if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimAssocFailureTimer) 1000 != TX_SUCCESS) { 1001 pe_warn("SessionId:%d couldn't start Assoc failure timer", 1002 session_entry->peSessionId); 1003 /* Cleanup as if assoc timer expired */ 1004 lim_process_assoc_failure_timeout(mac_ctx, LIM_ASSOC); 1005 } 1006 1007 return; 1008 end: 1009 /* Update PE session Id */ 1010 mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId; 1011 /* Free up buffer allocated for assoc_req */ 1012 qdf_mem_free(mlm_assoc_req); 1013 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 1014 (uint32_t *) &mlm_assoc_cnf); 1015 } 1016 1017 /** 1018 * lim_process_mlm_disassoc_req_ntf() - process disassoc request notification 1019 * 1020 * @mac_ctx: global MAC context 1021 * @suspend_status: suspend status 1022 * @msg: mlm message buffer 1023 * 1024 * This function is used to process MLM disassoc notification 1025 * 1026 * Return: None 1027 */ 1028 static void lim_process_mlm_disassoc_req_ntf(struct mac_context * mac_ctx,QDF_STATUS suspend_status,uint32_t * msg)1029 lim_process_mlm_disassoc_req_ntf(struct mac_context *mac_ctx, 1030 QDF_STATUS suspend_status, uint32_t *msg) 1031 { 1032 uint16_t aid; 1033 struct qdf_mac_addr curr_bssid; 1034 tpDphHashNode stads; 1035 tLimMlmDisassocReq *mlm_disassocreq; 1036 tLimMlmDisassocCnf mlm_disassoccnf; 1037 struct pe_session *session; 1038 extern bool send_disassoc_frame; 1039 tLimMlmStates mlm_state; 1040 struct disassoc_rsp *sme_disassoc_rsp; 1041 1042 if (QDF_STATUS_SUCCESS != suspend_status) 1043 pe_err("Suspend Status is not success %X", 1044 suspend_status); 1045 1046 mlm_disassocreq = (tLimMlmDisassocReq *) msg; 1047 1048 session = pe_find_session_by_session_id(mac_ctx, 1049 mlm_disassocreq->sessionId); 1050 if (!session) { 1051 pe_err("session does not exist for given sessionId %d", 1052 mlm_disassocreq->sessionId); 1053 mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1054 goto end; 1055 } 1056 1057 qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE); 1058 1059 switch (GET_LIM_SYSTEM_ROLE(session)) { 1060 case eLIM_STA_ROLE: 1061 if (!qdf_is_macaddr_equal(&mlm_disassocreq->peer_macaddr, 1062 &curr_bssid)) { 1063 pe_warn("received MLM_DISASSOC_REQ with invalid BSS: "QDF_MAC_ADDR_FMT, 1064 QDF_MAC_ADDR_REF( 1065 mlm_disassocreq->peer_macaddr.bytes)); 1066 1067 /* 1068 * Disassociation response due to host triggered 1069 * disassociation 1070 */ 1071 sme_disassoc_rsp = 1072 qdf_mem_malloc(sizeof(*sme_disassoc_rsp)); 1073 if (!sme_disassoc_rsp) { 1074 qdf_mem_free(mlm_disassocreq); 1075 return; 1076 } 1077 1078 pe_debug("send disassoc rsp with ret code %d for "QDF_MAC_ADDR_FMT, 1079 eSIR_SME_DEAUTH_STATUS, 1080 QDF_MAC_ADDR_REF( 1081 mlm_disassocreq->peer_macaddr.bytes)); 1082 1083 sme_disassoc_rsp->messageType = eWNI_SME_DISASSOC_RSP; 1084 sme_disassoc_rsp->length = sizeof(*sme_disassoc_rsp); 1085 sme_disassoc_rsp->sessionId = 1086 mlm_disassocreq->sessionId; 1087 sme_disassoc_rsp->status_code = eSIR_SME_DEAUTH_STATUS; 1088 1089 qdf_copy_macaddr(&sme_disassoc_rsp->peer_macaddr, 1090 &mlm_disassocreq->peer_macaddr); 1091 msg = (uint32_t *)sme_disassoc_rsp; 1092 1093 lim_send_sme_disassoc_deauth_ntf(mac_ctx, 1094 QDF_STATUS_SUCCESS, msg); 1095 qdf_mem_free(mlm_disassocreq); 1096 return; 1097 1098 } 1099 break; 1100 default: 1101 break; 1102 } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */ 1103 1104 /* 1105 * Check if there exists a context for the peer entity 1106 * to be disassociated with. 1107 */ 1108 stads = dph_lookup_hash_entry(mac_ctx, 1109 mlm_disassocreq->peer_macaddr.bytes, 1110 &aid, &session->dph.dphHashTable); 1111 if (stads) 1112 mlm_state = stads->mlmStaContext.mlmState; 1113 1114 if ((!stads) || 1115 (stads && 1116 ((mlm_state != eLIM_MLM_LINK_ESTABLISHED_STATE) && 1117 (mlm_state != eLIM_MLM_WT_ASSOC_CNF_STATE) && 1118 (mlm_state != eLIM_MLM_ASSOCIATED_STATE)))) { 1119 /* 1120 * Received LIM_MLM_DISASSOC_REQ for STA that does not 1121 * have context or in some transit state. 1122 */ 1123 pe_warn("Invalid MLM_DISASSOC_REQ, Addr= " QDF_MAC_ADDR_FMT, 1124 QDF_MAC_ADDR_REF(mlm_disassocreq->peer_macaddr.bytes)); 1125 if (stads) 1126 pe_err("Sta MlmState: %d", stads->mlmStaContext.mlmState); 1127 1128 /* Prepare and Send LIM_MLM_DISASSOC_CNF */ 1129 mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1130 goto end; 1131 } 1132 1133 stads->mlmStaContext.disassocReason = mlm_disassocreq->reasonCode; 1134 stads->mlmStaContext.cleanupTrigger = mlm_disassocreq->disassocTrigger; 1135 1136 /* 1137 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE 1138 * This is to address the issue of race condition between 1139 * disconnect request from the HDD and deauth from AP 1140 */ 1141 1142 stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; 1143 1144 /* Send Disassociate frame to peer entity */ 1145 if (send_disassoc_frame && (mlm_disassocreq->reasonCode != 1146 REASON_AUTHORIZED_ACCESS_LIMIT_REACHED)) { 1147 if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq) { 1148 pe_err("pMlmDisassocReq is not NULL, freeing"); 1149 qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq. 1150 pMlmDisassocReq); 1151 } 1152 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = 1153 mlm_disassocreq; 1154 /* 1155 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE 1156 * This is to address the issue of race condition between 1157 * disconnect request from the HDD and deauth from AP 1158 */ 1159 stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; 1160 1161 lim_send_disassoc_mgmt_frame(mac_ctx, 1162 mlm_disassocreq->reasonCode, 1163 mlm_disassocreq->peer_macaddr.bytes, session, true); 1164 /* 1165 * Abort Tx so that data frames won't be sent to the AP 1166 * after sending Disassoc. 1167 */ 1168 if (LIM_IS_STA_ROLE(session)) 1169 wma_tx_abort(session->smeSessionId); 1170 } else { 1171 lim_mlo_notify_peer_disconn(session, stads); 1172 /* Disassoc frame is not sent OTA */ 1173 send_disassoc_frame = 1; 1174 /* Receive path cleanup with dummy packet */ 1175 if (QDF_STATUS_SUCCESS != 1176 lim_cleanup_rx_path(mac_ctx, stads, session, true)) { 1177 mlm_disassoccnf.resultCode = 1178 eSIR_SME_RESOURCES_UNAVAILABLE; 1179 goto end; 1180 } 1181 /* Free up buffer allocated for mlmDisassocReq */ 1182 qdf_mem_free(mlm_disassocreq); 1183 } 1184 1185 return; 1186 1187 end: 1188 qdf_mem_copy((uint8_t *) &mlm_disassoccnf.peerMacAddr, 1189 (uint8_t *) mlm_disassocreq->peer_macaddr.bytes, 1190 QDF_MAC_ADDR_SIZE); 1191 mlm_disassoccnf.aid = mlm_disassocreq->aid; 1192 mlm_disassoccnf.disassocTrigger = mlm_disassocreq->disassocTrigger; 1193 1194 /* Update PE session ID */ 1195 mlm_disassoccnf.sessionId = mlm_disassocreq->sessionId; 1196 1197 /* Free up buffer allocated for mlmDisassocReq */ 1198 qdf_mem_free(mlm_disassocreq); 1199 1200 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF, 1201 (uint32_t *) &mlm_disassoccnf); 1202 } 1203 1204 /** 1205 * lim_check_disassoc_deauth_ack_pending() - check if deauth is pending 1206 * 1207 * @mac_ctx - global MAC context 1208 * @sta_mac - station MAC 1209 * 1210 * This function checks if diassociation or deauthentication is pending for 1211 * given station MAC address. 1212 * 1213 * Return: true if pending and false otherwise. 1214 */ lim_check_disassoc_deauth_ack_pending(struct mac_context * mac_ctx,uint8_t * sta_mac)1215 bool lim_check_disassoc_deauth_ack_pending(struct mac_context *mac_ctx, 1216 uint8_t *sta_mac) 1217 { 1218 tLimMlmDisassocReq *disassoc_req; 1219 tLimMlmDeauthReq *deauth_req; 1220 1221 disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; 1222 deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; 1223 if ((disassoc_req && (!qdf_mem_cmp((uint8_t *) sta_mac, 1224 (uint8_t *) &disassoc_req->peer_macaddr.bytes, 1225 QDF_MAC_ADDR_SIZE))) || 1226 (deauth_req && (!qdf_mem_cmp((uint8_t *) sta_mac, 1227 (uint8_t *) &deauth_req->peer_macaddr.bytes, 1228 QDF_MAC_ADDR_SIZE)))) { 1229 pe_debug("Disassoc/Deauth ack pending"); 1230 return true; 1231 } else { 1232 pe_debug("Disassoc/Deauth Ack not pending"); 1233 return false; 1234 } 1235 } 1236 1237 /* 1238 * lim_clean_up_disassoc_deauth_req() - cleans up pending disassoc or deauth req 1239 * 1240 * @mac_ctx: mac_ctx 1241 * @sta_mac: sta mac address 1242 * @clean_rx_path: flag to indicate whether to cleanup rx path or not 1243 * 1244 * This function cleans up pending disassoc or deauth req 1245 * 1246 * Return: void 1247 */ lim_clean_up_disassoc_deauth_req(struct mac_context * mac_ctx,uint8_t * sta_mac,bool clean_rx_path)1248 void lim_clean_up_disassoc_deauth_req(struct mac_context *mac_ctx, 1249 uint8_t *sta_mac, bool clean_rx_path) 1250 { 1251 tLimMlmDisassocReq *mlm_disassoc_req; 1252 tLimMlmDeauthReq *mlm_deauth_req; 1253 1254 mlm_disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; 1255 if (mlm_disassoc_req && 1256 (!qdf_mem_cmp((uint8_t *) sta_mac, 1257 (uint8_t *) &mlm_disassoc_req->peer_macaddr.bytes, 1258 QDF_MAC_ADDR_SIZE))) { 1259 if (clean_rx_path) { 1260 lim_process_disassoc_ack_timeout(mac_ctx); 1261 } else { 1262 if (tx_timer_running( 1263 &mac_ctx->lim.lim_timers.gLimDisassocAckTimer)) { 1264 lim_deactivate_and_change_timer(mac_ctx, 1265 eLIM_DISASSOC_ACK_TIMER); 1266 } 1267 qdf_mem_free(mlm_disassoc_req); 1268 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = 1269 NULL; 1270 } 1271 } 1272 1273 mlm_deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; 1274 if (mlm_deauth_req && 1275 (!qdf_mem_cmp((uint8_t *) sta_mac, 1276 (uint8_t *) &mlm_deauth_req->peer_macaddr.bytes, 1277 QDF_MAC_ADDR_SIZE))) { 1278 if (clean_rx_path) { 1279 lim_process_deauth_ack_timeout(mac_ctx, 1280 mlm_deauth_req->sessionId); 1281 } else { 1282 if (tx_timer_running( 1283 &mac_ctx->lim.lim_timers.gLimDeauthAckTimer)) { 1284 lim_deactivate_and_change_timer(mac_ctx, 1285 eLIM_DEAUTH_ACK_TIMER); 1286 } 1287 qdf_mem_free(mlm_deauth_req); 1288 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = 1289 NULL; 1290 } 1291 } 1292 } 1293 1294 /* 1295 * lim_process_disassoc_ack_timeout() - wrapper function around 1296 * lim_send_disassoc_cnf 1297 * 1298 * @mac_ctx: mac_ctx 1299 * 1300 * wrapper function around lim_send_disassoc_cnf 1301 * 1302 * Return: void 1303 */ lim_process_disassoc_ack_timeout(struct mac_context * mac_ctx)1304 void lim_process_disassoc_ack_timeout(struct mac_context *mac_ctx) 1305 { 1306 lim_send_disassoc_cnf(mac_ctx); 1307 } 1308 1309 /** 1310 * lim_process_mlm_disassoc_req() - This function is called to process 1311 * MLM_DISASSOC_REQ message from SME 1312 * 1313 * @mac_ctx: Pointer to Global MAC structure 1314 * @msg_buf: A pointer to the MLM message buffer 1315 * 1316 * This function is called to process MLM_DISASSOC_REQ message from SME 1317 * 1318 * @Return: None 1319 */ 1320 static void lim_process_mlm_disassoc_req(struct mac_context * mac_ctx,uint32_t * msg_buf)1321 lim_process_mlm_disassoc_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 1322 { 1323 tLimMlmDisassocReq *mlm_disassoc_req; 1324 1325 if (!msg_buf) { 1326 pe_err("Buffer is Pointing to NULL"); 1327 return; 1328 } 1329 1330 mlm_disassoc_req = (tLimMlmDisassocReq *) msg_buf; 1331 lim_process_mlm_disassoc_req_ntf(mac_ctx, QDF_STATUS_SUCCESS, 1332 (uint32_t *) msg_buf); 1333 } 1334 1335 /** 1336 * lim_process_mlm_deauth_req_ntf() - This function is process mlm deauth req 1337 * notification 1338 * 1339 * @mac_ctx: Pointer to Global MAC structure 1340 * @suspend_status: suspend status 1341 * @msg_buf: A pointer to the MLM message buffer 1342 * 1343 * This function is process mlm deauth req notification 1344 * 1345 * @Return: None 1346 */ 1347 static void lim_process_mlm_deauth_req_ntf(struct mac_context * mac_ctx,QDF_STATUS suspend_status,uint32_t * msg_buf)1348 lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx, 1349 QDF_STATUS suspend_status, uint32_t *msg_buf) 1350 { 1351 uint16_t aid, i; 1352 tSirMacAddr curr_bssId; 1353 tpDphHashNode sta_ds; 1354 struct tLimPreAuthNode *auth_node; 1355 tLimMlmDeauthReq *mlm_deauth_req; 1356 tLimMlmDeauthCnf mlm_deauth_cnf; 1357 struct pe_session *session; 1358 struct deauth_rsp *sme_deauth_rsp; 1359 1360 if (QDF_STATUS_SUCCESS != suspend_status) 1361 pe_err("Suspend Status is not success %X", 1362 suspend_status); 1363 1364 mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf; 1365 session = pe_find_session_by_session_id(mac_ctx, 1366 mlm_deauth_req->sessionId); 1367 if (!session) { 1368 pe_err("session does not exist for given sessionId %d", 1369 mlm_deauth_req->sessionId); 1370 qdf_mem_free(mlm_deauth_req); 1371 return; 1372 } 1373 sir_copy_mac_addr(curr_bssId, session->bssId); 1374 1375 switch (GET_LIM_SYSTEM_ROLE(session)) { 1376 case eLIM_STA_ROLE: 1377 switch (session->limMlmState) { 1378 case eLIM_MLM_IDLE_STATE: 1379 /* 1380 * Attempting to Deauthenticate with a pre-authenticated 1381 * peer. Deauthetiate with peer if there exists a 1382 * pre-auth context below. 1383 */ 1384 break; 1385 case eLIM_MLM_AUTHENTICATED_STATE: 1386 case eLIM_MLM_WT_ASSOC_RSP_STATE: 1387 case eLIM_MLM_LINK_ESTABLISHED_STATE: 1388 if (qdf_mem_cmp(mlm_deauth_req->peer_macaddr.bytes, 1389 curr_bssId, QDF_MAC_ADDR_SIZE)) { 1390 pe_err("received MLM_DEAUTH_REQ with invalid BSS id " 1391 "Peer MAC: "QDF_MAC_ADDR_FMT 1392 " CFG BSSID Addr : "QDF_MAC_ADDR_FMT, 1393 QDF_MAC_ADDR_REF( 1394 mlm_deauth_req->peer_macaddr.bytes), 1395 QDF_MAC_ADDR_REF(curr_bssId)); 1396 /* 1397 * Deauthentication response to host triggered 1398 * deauthentication 1399 */ 1400 sme_deauth_rsp = 1401 qdf_mem_malloc(sizeof(*sme_deauth_rsp)); 1402 if (!sme_deauth_rsp) { 1403 qdf_mem_free(mlm_deauth_req); 1404 return; 1405 } 1406 1407 sme_deauth_rsp->messageType = 1408 eWNI_SME_DEAUTH_RSP; 1409 sme_deauth_rsp->length = 1410 sizeof(*sme_deauth_rsp); 1411 sme_deauth_rsp->status_code = 1412 eSIR_SME_DEAUTH_STATUS; 1413 sme_deauth_rsp->sessionId = 1414 session->vdev_id; 1415 1416 qdf_mem_copy(sme_deauth_rsp->peer_macaddr.bytes, 1417 mlm_deauth_req->peer_macaddr.bytes, 1418 QDF_MAC_ADDR_SIZE); 1419 1420 msg_buf = (uint32_t *)sme_deauth_rsp; 1421 1422 lim_send_sme_disassoc_deauth_ntf(mac_ctx, 1423 QDF_STATUS_SUCCESS, msg_buf); 1424 qdf_mem_free(mlm_deauth_req); 1425 return; 1426 } 1427 1428 if ((session->limMlmState == 1429 eLIM_MLM_AUTHENTICATED_STATE) || 1430 (session->limMlmState == 1431 eLIM_MLM_WT_ASSOC_RSP_STATE)) { 1432 /* Send deauth frame to peer entity */ 1433 lim_send_deauth_mgmt_frame(mac_ctx, 1434 mlm_deauth_req->reasonCode, 1435 mlm_deauth_req->peer_macaddr.bytes, 1436 session, false); 1437 /* Prepare and Send LIM_MLM_DEAUTH_CNF */ 1438 mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; 1439 session->limMlmState = eLIM_MLM_IDLE_STATE; 1440 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1441 session->peSessionId, 1442 session->limMlmState)); 1443 goto end; 1444 } 1445 break; 1446 default: 1447 pe_warn("received MLM_DEAUTH_REQ with in state %d for peer " 1448 QDF_MAC_ADDR_FMT, 1449 session->limMlmState, 1450 QDF_MAC_ADDR_REF( 1451 mlm_deauth_req->peer_macaddr.bytes)); 1452 lim_print_mlm_state(mac_ctx, LOGW, 1453 session->limMlmState); 1454 /* Prepare and Send LIM_MLM_DEAUTH_CNF */ 1455 mlm_deauth_cnf.resultCode = 1456 eSIR_SME_STA_NOT_AUTHENTICATED; 1457 1458 goto end; 1459 } 1460 break; 1461 default: 1462 break; 1463 } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */ 1464 1465 /* 1466 * Check if there exists a context for the peer entity 1467 * to be deauthenticated with. 1468 */ 1469 sta_ds = dph_lookup_hash_entry(mac_ctx, 1470 mlm_deauth_req->peer_macaddr.bytes, 1471 &aid, 1472 &session->dph.dphHashTable); 1473 1474 if (!sta_ds && (!mac_ctx->mlme_cfg->sap_cfg.is_sap_bcast_deauth_enabled 1475 || (mac_ctx->mlme_cfg->sap_cfg.is_sap_bcast_deauth_enabled && 1476 !qdf_is_macaddr_broadcast(&mlm_deauth_req->peer_macaddr)))) { 1477 /* Check if there exists pre-auth context for this STA */ 1478 auth_node = lim_search_pre_auth_list(mac_ctx, mlm_deauth_req-> 1479 peer_macaddr.bytes); 1480 if (!auth_node) { 1481 /* 1482 * Received DEAUTH REQ for a STA that is neither 1483 * Associated nor Pre-authenticated. Log error, 1484 * Prepare and Send LIM_MLM_DEAUTH_CNF 1485 */ 1486 pe_warn("rcvd MLM_DEAUTH_REQ in mlme state %d STA does not have context, Addr="QDF_MAC_ADDR_FMT, 1487 session->limMlmState, 1488 QDF_MAC_ADDR_REF( 1489 mlm_deauth_req->peer_macaddr.bytes)); 1490 mlm_deauth_cnf.resultCode = 1491 eSIR_SME_STA_NOT_AUTHENTICATED; 1492 } else { 1493 mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; 1494 /* Delete STA from pre-auth STA list */ 1495 lim_delete_pre_auth_node(mac_ctx, 1496 mlm_deauth_req-> 1497 peer_macaddr.bytes); 1498 /*Send Deauthentication frame to peer entity*/ 1499 lim_send_deauth_mgmt_frame(mac_ctx, 1500 mlm_deauth_req->reasonCode, 1501 mlm_deauth_req-> 1502 peer_macaddr.bytes, 1503 session, false); 1504 } 1505 goto end; 1506 } else if (sta_ds && (sta_ds->mlmStaContext.mlmState != 1507 eLIM_MLM_LINK_ESTABLISHED_STATE) && 1508 (sta_ds->mlmStaContext.mlmState != 1509 eLIM_MLM_WT_ASSOC_CNF_STATE)) { 1510 /* 1511 * received MLM_DEAUTH_REQ for STA that either has no 1512 * context or in some transit state 1513 */ 1514 pe_warn("Invalid MLM_DEAUTH_REQ, Addr=" QDF_MAC_ADDR_FMT, 1515 QDF_MAC_ADDR_REF(mlm_deauth_req-> 1516 peer_macaddr.bytes)); 1517 /* Prepare and Send LIM_MLM_DEAUTH_CNF */ 1518 mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 1519 goto end; 1520 } else if (sta_ds) { 1521 /* sta_ds->mlmStaContext.rxPurgeReq = 1; */ 1522 sta_ds->mlmStaContext.disassocReason = 1523 mlm_deauth_req->reasonCode; 1524 sta_ds->mlmStaContext.cleanupTrigger = 1525 mlm_deauth_req->deauthTrigger; 1526 1527 /* 1528 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE 1529 * This is to address the issue of race condition between 1530 * disconnect request from the HDD and disassoc from 1531 * inactivity timer. This will make sure that we will not 1532 * process disassoc if deauth is in progress for the station 1533 * and thus mlmStaContext.cleanupTrigger will not be 1534 * overwritten. 1535 */ 1536 sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; 1537 } else if (mac_ctx->mlme_cfg->sap_cfg.is_sap_bcast_deauth_enabled && 1538 qdf_is_macaddr_broadcast(&mlm_deauth_req->peer_macaddr)) { 1539 for (i = 0; i < session->dph.dphHashTable.size; i++) { 1540 sta_ds = dph_get_hash_entry(mac_ctx, i, 1541 &session->dph.dphHashTable); 1542 if (!sta_ds) 1543 continue; 1544 1545 sta_ds->mlmStaContext.disassocReason = 1546 mlm_deauth_req->reasonCode; 1547 sta_ds->mlmStaContext.cleanupTrigger = 1548 mlm_deauth_req->deauthTrigger; 1549 sta_ds->mlmStaContext.mlmState = 1550 eLIM_MLM_WT_DEL_STA_RSP_STATE; 1551 } 1552 } 1553 1554 if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) { 1555 pe_err("pMlmDeauthReq is not NULL, freeing"); 1556 qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq. 1557 pMlmDeauthReq); 1558 } 1559 mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = mlm_deauth_req; 1560 1561 /* Send Deauthentication frame to peer entity */ 1562 if (mlm_deauth_req->reasonCode != REASON_DISASSOC_DUE_TO_INACTIVITY || 1563 wlan_son_peer_is_kickout_allow(session->vdev, sta_ds->staAddr)) { 1564 lim_send_deauth_mgmt_frame(mac_ctx, mlm_deauth_req->reasonCode, 1565 mlm_deauth_req->peer_macaddr.bytes, 1566 session, true); 1567 } else { 1568 pe_err("peer " QDF_MAC_ADDR_FMT " is in band steering, do not send deauth frame", 1569 QDF_MAC_ADDR_REF(mlm_deauth_req->peer_macaddr.bytes)); 1570 mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS; 1571 goto end; 1572 } 1573 1574 return; 1575 end: 1576 qdf_copy_macaddr(&mlm_deauth_cnf.peer_macaddr, 1577 &mlm_deauth_req->peer_macaddr); 1578 mlm_deauth_cnf.deauthTrigger = mlm_deauth_req->deauthTrigger; 1579 mlm_deauth_cnf.aid = mlm_deauth_req->aid; 1580 mlm_deauth_cnf.sessionId = mlm_deauth_req->sessionId; 1581 1582 /* Free up buffer allocated for mlmDeauthReq */ 1583 qdf_mem_free(mlm_deauth_req); 1584 lim_post_sme_message(mac_ctx, 1585 LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlm_deauth_cnf); 1586 } 1587 1588 /* 1589 * lim_process_deauth_ack_timeout() - wrapper function around 1590 * lim_send_deauth_cnf 1591 * 1592 * @pMacGlobal: mac_ctx 1593 * @vdev_id: vdev id 1594 * 1595 * wrapper function around lim_send_deauth_cnf 1596 * 1597 * Return: void 1598 */ lim_process_deauth_ack_timeout(void * pMacGlobal,uint32_t vdev_id)1599 void lim_process_deauth_ack_timeout(void *pMacGlobal, uint32_t vdev_id) 1600 { 1601 struct mac_context *mac_ctx = (struct mac_context *)pMacGlobal; 1602 1603 pe_debug("Deauth Ack timeout for vdev id %d", vdev_id); 1604 lim_send_deauth_cnf(mac_ctx, vdev_id); 1605 } 1606 1607 /* 1608 * lim_process_mlm_deauth_req() - This function is called to process 1609 * MLM_DEAUTH_REQ message from SME 1610 * 1611 * @mac_ctx: Pointer to Global MAC structure 1612 * @msg_buf: A pointer to the MLM message buffer 1613 * 1614 * This function is called to process MLM_DEAUTH_REQ message from SME 1615 * 1616 * @Return: None 1617 */ lim_process_mlm_deauth_req(struct mac_context * mac_ctx,uint32_t * msg_buf)1618 void lim_process_mlm_deauth_req(struct mac_context *mac_ctx, uint32_t *msg_buf) 1619 { 1620 tLimMlmDeauthReq *mlm_deauth_req; 1621 struct pe_session *session; 1622 1623 if (!msg_buf) { 1624 pe_err("Buffer is Pointing to NULL"); 1625 return; 1626 } 1627 1628 mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf; 1629 session = pe_find_session_by_session_id(mac_ctx, 1630 mlm_deauth_req->sessionId); 1631 if (!session) { 1632 pe_err("session does not exist for given sessionId %d", 1633 mlm_deauth_req->sessionId); 1634 qdf_mem_free(mlm_deauth_req); 1635 return; 1636 } 1637 lim_process_mlm_deauth_req_ntf(mac_ctx, QDF_STATUS_SUCCESS, 1638 (uint32_t *) msg_buf); 1639 } 1640 lim_process_join_failure_timeout(struct mac_context * mac_ctx)1641 void lim_process_join_failure_timeout(struct mac_context *mac_ctx) 1642 { 1643 tLimMlmJoinCnf mlm_join_cnf; 1644 uint32_t len; 1645 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 1646 host_log_rssi_pkt_type *rssi_log = NULL; 1647 #endif 1648 struct pe_session *session; 1649 1650 session = pe_find_session_by_session_id(mac_ctx, 1651 mac_ctx->lim.lim_timers.gLimJoinFailureTimer.sessionId); 1652 if (!session) { 1653 pe_err("Session Does not exist for given sessionID"); 1654 return; 1655 } 1656 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 1657 WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, 1658 host_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); 1659 if (rssi_log) 1660 rssi_log->rssi = session->rssi; 1661 WLAN_HOST_DIAG_LOG_REPORT(rssi_log); 1662 #endif 1663 session->join_probe_cnt = 0; 1664 1665 if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) { 1666 len = sizeof(tSirMacAddr); 1667 /* Change timer for future activations */ 1668 lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER); 1669 /* Change Periodic probe req timer for future activation */ 1670 lim_deactivate_and_change_timer(mac_ctx, 1671 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); 1672 /* Issue MLM join confirm with timeout reason code */ 1673 pe_err("Join Failure Timeout, In eLIM_MLM_WT_JOIN_BEACON_STATE session:%d " 1674 QDF_MAC_ADDR_FMT, 1675 session->peSessionId, 1676 QDF_MAC_ADDR_REF(session->bssId)); 1677 1678 mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE; 1679 mlm_join_cnf.protStatusCode = STATUS_NO_NETWORK_FOUND; 1680 session->limMlmState = eLIM_MLM_IDLE_STATE; 1681 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1682 session->peSessionId, session->limMlmState)); 1683 /* Update PE session Id */ 1684 mlm_join_cnf.sessionId = session->peSessionId; 1685 /* Freeup buffer allocated to join request */ 1686 if (session->pLimMlmJoinReq) { 1687 qdf_mem_free(session->pLimMlmJoinReq); 1688 session->pLimMlmJoinReq = NULL; 1689 } 1690 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, 1691 (uint32_t *) &mlm_join_cnf); 1692 return; 1693 } else { 1694 pe_warn("received unexpected JOIN failure timeout in state %X", 1695 session->limMlmState); 1696 lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState); 1697 } 1698 } 1699 1700 /** 1701 * lim_process_periodic_join_probe_req_timer() - This function is called to 1702 * process periodic probe request send during joining process. 1703 * 1704 * @mac_ctx: Pointer to Global MAC structure 1705 * 1706 * This function is called to process periodic probe request send during 1707 * joining process. 1708 * 1709 * @Return None 1710 */ lim_process_periodic_join_probe_req_timer(struct mac_context * mac_ctx)1711 static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ctx) 1712 { 1713 struct pe_session *session; 1714 tSirMacSSid ssid; 1715 tSirMacAddr bssid; 1716 tSirMacAddr bcast_mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 1717 1718 session = pe_find_session_by_session_id(mac_ctx, 1719 mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer.sessionId); 1720 if (!session) { 1721 pe_err("session does not exist for given SessionId: %d", 1722 mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer. 1723 sessionId); 1724 return; 1725 } 1726 1727 if ((true == 1728 tx_timer_running(&mac_ctx->lim.lim_timers.gLimJoinFailureTimer)) 1729 && (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) { 1730 qdf_mem_copy(ssid.ssId, session->ssId.ssId, 1731 session->ssId.length); 1732 ssid.length = session->ssId.length; 1733 sir_copy_mac_addr(bssid, 1734 session->pLimMlmJoinReq->bssDescription.bssId); 1735 1736 /* 1737 * Some APs broadcasting hidden SSID doesn't respond to unicast 1738 * probe requests, however those APs respond to broadcast probe 1739 * requests. Therefore for hidden ssid connections, after 3 1740 * unicast probe requests, try the pending probes with broadcast 1741 * mac. 1742 */ 1743 if (session->ssidHidden && session->join_probe_cnt > 2) 1744 sir_copy_mac_addr(bssid, bcast_mac); 1745 1746 lim_send_probe_req_mgmt_frame(mac_ctx, &ssid, bssid, 1747 session->curr_op_freq, 1748 session->self_mac_addr, session->dot11mode, 1749 &session->lim_join_req->addIEScan.length, 1750 session->lim_join_req->addIEScan.addIEdata); 1751 lim_deactivate_and_change_timer(mac_ctx, 1752 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); 1753 /* Activate Join Periodic Probe Req timer */ 1754 if (tx_timer_activate( 1755 &mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer) != 1756 TX_SUCCESS) { 1757 pe_warn("could not activate Periodic Join req failure timer"); 1758 return; 1759 } 1760 session->join_probe_cnt++; 1761 } 1762 } 1763 lim_send_pre_auth_failure(uint8_t vdev_id,tSirMacAddr bssid)1764 static void lim_send_pre_auth_failure(uint8_t vdev_id, tSirMacAddr bssid) 1765 { 1766 struct scheduler_msg sch_msg = {0}; 1767 struct wmi_roam_auth_status_params *params; 1768 QDF_STATUS status = QDF_STATUS_SUCCESS; 1769 1770 params = qdf_mem_malloc(sizeof(*params)); 1771 if (!params) 1772 return; 1773 1774 params->vdev_id = vdev_id; 1775 params->preauth_status = STATUS_UNSPECIFIED_FAILURE; 1776 qdf_mem_copy(params->bssid.bytes, bssid, QDF_MAC_ADDR_SIZE); 1777 qdf_mem_zero(params->pmkid, PMKID_LEN); 1778 1779 sch_msg.type = WMA_ROAM_PRE_AUTH_STATUS; 1780 sch_msg.bodyptr = params; 1781 pe_debug("Sending pre auth failure for mac_addr " QDF_MAC_ADDR_FMT, 1782 QDF_MAC_ADDR_REF(params->bssid.bytes)); 1783 1784 status = scheduler_post_message(QDF_MODULE_ID_PE, 1785 QDF_MODULE_ID_WMA, 1786 QDF_MODULE_ID_WMA, 1787 &sch_msg); 1788 if (QDF_IS_STATUS_ERROR(status)) { 1789 pe_err("Sending preauth status failed"); 1790 qdf_mem_free(params); 1791 } 1792 } 1793 lim_handle_sae_auth_timeout(struct mac_context * mac_ctx,struct pe_session * session_entry)1794 static void lim_handle_sae_auth_timeout(struct mac_context *mac_ctx, 1795 struct pe_session *session_entry) 1796 { 1797 struct sae_auth_retry *sae_retry; 1798 tpSirMacMgmtHdr mac_hdr; 1799 1800 sae_retry = mlme_get_sae_auth_retry(session_entry->vdev); 1801 if (!(sae_retry && sae_retry->sae_auth.ptr)) { 1802 pe_debug("sae auth frame is not buffered vdev id %d", 1803 session_entry->vdev_id); 1804 return; 1805 } 1806 1807 if (!sae_retry->sae_auth_max_retry) { 1808 if (!wlan_cm_is_vdev_connecting(session_entry->vdev)) { 1809 mac_hdr = (tpSirMacMgmtHdr)sae_retry->sae_auth.ptr; 1810 lim_send_pre_auth_failure(session_entry->vdev_id, 1811 mac_hdr->bssId); 1812 } 1813 goto free_and_deactivate_timer; 1814 } 1815 1816 pe_debug("Retry sae auth for seq num %d vdev id %d", 1817 mac_ctx->mgmtSeqNum, session_entry->vdev_id); 1818 lim_send_frame(mac_ctx, session_entry->vdev_id, sae_retry->sae_auth.ptr, 1819 sae_retry->sae_auth.len); 1820 sae_retry->sae_auth_max_retry--; 1821 1822 if (TX_SUCCESS != tx_timer_activate( 1823 &mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer)) 1824 goto free_and_deactivate_timer; 1825 return; 1826 1827 free_and_deactivate_timer: 1828 lim_sae_auth_cleanup_retry(mac_ctx, session_entry->vdev_id); 1829 } 1830 1831 /** 1832 * lim_process_auth_retry_timer()- function to Retry Auth when auth timeout 1833 * occurs 1834 * @mac_ctx:pointer to global mac 1835 * 1836 * Return: void 1837 */ lim_process_auth_retry_timer(struct mac_context * mac_ctx)1838 static void lim_process_auth_retry_timer(struct mac_context *mac_ctx) 1839 { 1840 struct pe_session *session_entry; 1841 tAniAuthType auth_type; 1842 tLimTimers *lim_timers = &mac_ctx->lim.lim_timers; 1843 uint16_t pe_session_id = 1844 lim_timers->g_lim_periodic_auth_retry_timer.sessionId; 1845 1846 session_entry = pe_find_session_by_session_id(mac_ctx, pe_session_id); 1847 if (!session_entry) { 1848 pe_err("session does not exist for pe_session_id: %d", 1849 pe_session_id); 1850 return; 1851 } 1852 1853 /** For WPA3 SAE gLimAuthFailureTimer is not running hence 1854 * we don't enter in below "if" block in case of wpa3 sae 1855 */ 1856 if (tx_timer_running(&mac_ctx->lim.lim_timers.gLimAuthFailureTimer) && 1857 (session_entry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) && 1858 (LIM_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) { 1859 /* 1860 * Send the auth retry only in case we have received ack failure 1861 * else just restart the retry timer. 1862 */ 1863 if (((mac_ctx->auth_ack_status == LIM_ACK_RCD_FAILURE) || 1864 (mac_ctx->auth_ack_status == LIM_TX_FAILED)) && 1865 mac_ctx->lim.gpLimMlmAuthReq) { 1866 tSirMacAuthFrameBody *auth_frame; 1867 1868 auth_type = mac_ctx->lim.gpLimMlmAuthReq->authType; 1869 1870 auth_frame = qdf_mem_malloc(sizeof(*auth_frame)); 1871 if (!auth_frame) { 1872 pe_err("malloc failed for auth_frame"); 1873 return; 1874 } 1875 1876 /* Prepare & send Authentication frame */ 1877 if (session_entry->sae_pmk_cached && 1878 auth_type == eSIR_AUTH_TYPE_SAE) 1879 auth_frame->authAlgoNumber = eSIR_OPEN_SYSTEM; 1880 else 1881 auth_frame->authAlgoNumber = (uint8_t)auth_type; 1882 1883 auth_frame->authTransactionSeqNumber = 1884 SIR_MAC_AUTH_FRAME_1; 1885 auth_frame->authStatusCode = 0; 1886 pe_debug("Retry Auth"); 1887 lim_increase_fils_sequence_number(session_entry); 1888 lim_send_auth_mgmt_frame(mac_ctx, auth_frame, 1889 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr, 1890 LIM_NO_WEP_IN_FC, session_entry); 1891 1892 qdf_mem_free(auth_frame); 1893 } 1894 1895 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER); 1896 1897 /* Activate Auth Retry timer */ 1898 if (tx_timer_activate 1899 (&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) 1900 != TX_SUCCESS) 1901 pe_err("could not activate Auth Retry failure timer"); 1902 1903 return; 1904 } 1905 1906 /* Auth retry time out for wpa3 sae */ 1907 lim_handle_sae_auth_timeout(mac_ctx, session_entry); 1908 } /*** lim_process_auth_retry_timer() ***/ 1909 lim_process_auth_failure_timeout(struct mac_context * mac_ctx)1910 void lim_process_auth_failure_timeout(struct mac_context *mac_ctx) 1911 { 1912 /* fetch the pe_session based on the sessionId */ 1913 struct pe_session *session; 1914 uint32_t val; 1915 enum wlan_status_code proto_status_code; 1916 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 1917 host_log_rssi_pkt_type *rssi_log = NULL; 1918 #endif 1919 1920 session = pe_find_session_by_session_id(mac_ctx, 1921 mac_ctx->lim.lim_timers.gLimAuthFailureTimer.sessionId); 1922 if (!session) { 1923 pe_err("Session Does not exist for given sessionID"); 1924 return; 1925 } 1926 1927 pe_warn("received AUTH failure timeout in sessionid %d " 1928 "limMlmstate %X limSmeState %X", 1929 session->peSessionId, session->limMlmState, 1930 session->limSmeState); 1931 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 1932 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT, session, 1933 0, AUTH_FAILURE_TIMEOUT); 1934 1935 WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, host_log_rssi_pkt_type, 1936 LOG_WLAN_RSSI_UPDATE_C); 1937 if (rssi_log) 1938 rssi_log->rssi = session->rssi; 1939 WLAN_HOST_DIAG_LOG_REPORT(rssi_log); 1940 #endif 1941 1942 switch (session->limMlmState) { 1943 case eLIM_MLM_WT_AUTH_FRAME2_STATE: 1944 case eLIM_MLM_WT_AUTH_FRAME4_STATE: 1945 /* 1946 * Requesting STA did not receive next auth frame before Auth 1947 * Failure timeout. Issue MLM auth confirm with timeout reason 1948 * code. Restore default failure timeout 1949 */ 1950 if (QDF_P2P_CLIENT_MODE == session->opmode && 1951 session->defaultAuthFailureTimeout) { 1952 if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT, 1953 session->defaultAuthFailureTimeout)) { 1954 val = session->defaultAuthFailureTimeout; 1955 } else { 1956 val = cfg_default(CFG_AUTH_FAILURE_TIMEOUT); 1957 session->defaultAuthFailureTimeout = val; 1958 } 1959 mac_ctx->mlme_cfg->timeouts.auth_failure_timeout = val; 1960 } 1961 lim_fill_status_code(SIR_MAC_MGMT_AUTH, 1962 mac_ctx->auth_ack_status, 1963 &proto_status_code); 1964 lim_restore_from_auth_state(mac_ctx, 1965 eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, 1966 proto_status_code, session); 1967 mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD; 1968 break; 1969 default: 1970 /* 1971 * Auth failure timer should not have timed out 1972 * in states other than wt_auth_frame2/4 1973 */ 1974 pe_err("received unexpected AUTH failure timeout in state %X", 1975 session->limMlmState); 1976 lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState); 1977 break; 1978 } 1979 } 1980 1981 /** 1982 * lim_process_auth_rsp_timeout() - This function is called to process Min 1983 * Channel Timeout during channel scan. 1984 * 1985 * @mac_ctx: Pointer to Global MAC structure 1986 * 1987 * This function is called to process Min Channel Timeout during channel scan. 1988 * 1989 * @Return: None 1990 */ 1991 static void lim_process_auth_rsp_timeout(struct mac_context * mac_ctx,uint32_t auth_idx)1992 lim_process_auth_rsp_timeout(struct mac_context *mac_ctx, uint32_t auth_idx) 1993 { 1994 struct tLimPreAuthNode *auth_node; 1995 struct pe_session *session; 1996 uint8_t session_id; 1997 1998 auth_node = lim_get_pre_auth_node_from_index(mac_ctx, 1999 &mac_ctx->lim.gLimPreAuthTimerTable, auth_idx); 2000 if (!auth_node) { 2001 pe_warn("Invalid auth node"); 2002 return; 2003 } 2004 2005 session = pe_find_session_by_bssid(mac_ctx, auth_node->peerMacAddr, 2006 &session_id); 2007 if (!session) { 2008 pe_warn("session does not exist for given BSSID"); 2009 return; 2010 } 2011 2012 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2013 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT, 2014 session, 0, AUTH_RESPONSE_TIMEOUT); 2015 #endif 2016 2017 if (LIM_IS_AP_ROLE(session)) { 2018 if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) { 2019 pe_err("received AUTH rsp timeout in unexpected " 2020 "state for MAC address: " QDF_MAC_ADDR_FMT, 2021 QDF_MAC_ADDR_REF(auth_node->peerMacAddr)); 2022 } else { 2023 auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE; 2024 auth_node->fTimerStarted = 0; 2025 pe_debug("AUTH rsp timedout for MAC address " 2026 QDF_MAC_ADDR_FMT, 2027 QDF_MAC_ADDR_REF(auth_node->peerMacAddr)); 2028 /* Change timer to reactivate it in future */ 2029 lim_deactivate_and_change_per_sta_id_timer(mac_ctx, 2030 eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx); 2031 lim_delete_pre_auth_node(mac_ctx, 2032 auth_node->peerMacAddr); 2033 } 2034 } 2035 } 2036 lim_process_assoc_failure_timeout(struct mac_context * mac_ctx,uint32_t msg_type)2037 void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx, 2038 uint32_t msg_type) 2039 { 2040 2041 tLimMlmAssocCnf mlm_assoc_cnf; 2042 struct pe_session *session; 2043 enum wlan_status_code proto_status_code; 2044 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2045 host_log_rssi_pkt_type *rssi_log = NULL; 2046 #endif 2047 /* 2048 * to fetch the lim/mlm state based on the session_id, use the 2049 * below pe_session 2050 */ 2051 uint8_t session_id; 2052 2053 if (msg_type == LIM_ASSOC) 2054 session_id = 2055 mac_ctx->lim.lim_timers.gLimAssocFailureTimer.sessionId; 2056 else 2057 session_id = 2058 mac_ctx->lim.lim_timers.gLimReassocFailureTimer.sessionId; 2059 2060 session = pe_find_session_by_session_id(mac_ctx, session_id); 2061 if (!session) { 2062 pe_err("Session Does not exist for given sessionID"); 2063 return; 2064 } 2065 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM 2066 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_TIMEOUT, 2067 session, 0, 0); 2068 2069 WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, 2070 host_log_rssi_pkt_type, 2071 LOG_WLAN_RSSI_UPDATE_C); 2072 if (rssi_log) 2073 rssi_log->rssi = session->rssi; 2074 WLAN_HOST_DIAG_LOG_REPORT(rssi_log); 2075 #endif 2076 2077 pe_debug("Re/Association Response not received before timeout"); 2078 2079 /* 2080 * Send Deauth to handle the scenareo where association timeout happened 2081 * when device has missed the assoc resp sent by peer. 2082 * By sending deauth try to clear the session created on peer device. 2083 */ 2084 if (msg_type == LIM_ASSOC && 2085 mlme_get_reconn_after_assoc_timeout_flag(mac_ctx->psoc, 2086 session->vdev_id)) { 2087 pe_debug("vdev: %d skip sending deauth on channel freq %d to BSSID: " 2088 QDF_MAC_ADDR_FMT, session->vdev_id, 2089 session->curr_op_freq, 2090 QDF_MAC_ADDR_REF(session->bssId)); 2091 } else { 2092 pe_debug("vdev: %d try sending deauth on channel freq %d to BSSID: " 2093 QDF_MAC_ADDR_FMT, session->vdev_id, 2094 session->curr_op_freq, 2095 QDF_MAC_ADDR_REF(session->bssId)); 2096 lim_send_deauth_mgmt_frame(mac_ctx, 2097 REASON_UNSPEC_FAILURE, 2098 session->bssId, session, false); 2099 } 2100 if ((LIM_IS_AP_ROLE(session)) || 2101 ((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) && 2102 (session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) && 2103 (session->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) { 2104 /* 2105 * Re/Assoc failure timer should not have timedout on AP 2106 * or in a state other than wt_re/assoc_response. 2107 */ 2108 pe_warn("received unexpected REASSOC failure timeout in state %X for role %d", 2109 session->limMlmState, 2110 GET_LIM_SYSTEM_ROLE(session)); 2111 lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState); 2112 return; 2113 } 2114 2115 if ((msg_type == LIM_ASSOC) || ((msg_type == LIM_REASSOC) 2116 && (session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) { 2117 pe_err("(Re)Assoc Failure Timeout occurred"); 2118 session->limMlmState = eLIM_MLM_IDLE_STATE; 2119 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2120 session->peSessionId, session->limMlmState)); 2121 /* Change timer for future activations */ 2122 lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER); 2123 lim_stop_pmfcomeback_timer(session); 2124 /* 2125 * Free up buffer allocated for JoinReq held by 2126 * MLM state machine 2127 */ 2128 if (session->pLimMlmJoinReq) { 2129 qdf_mem_free(session->pLimMlmJoinReq); 2130 session->pLimMlmJoinReq = NULL; 2131 } 2132 /* To remove the preauth node in case of fail to associate */ 2133 if (lim_search_pre_auth_list(mac_ctx, session->bssId)) { 2134 pe_debug("delete pre auth node for "QDF_MAC_ADDR_FMT, 2135 QDF_MAC_ADDR_REF(session->bssId)); 2136 lim_delete_pre_auth_node(mac_ctx, 2137 session->bssId); 2138 } 2139 lim_fill_status_code(SIR_MAC_MGMT_ASSOC_RSP, 2140 mac_ctx->assoc_ack_status, 2141 &proto_status_code); 2142 2143 mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE; 2144 mlm_assoc_cnf.protStatusCode = proto_status_code; 2145 /* Update PE session Id */ 2146 mlm_assoc_cnf.sessionId = session->peSessionId; 2147 if (msg_type == LIM_ASSOC) { 2148 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 2149 (uint32_t *) &mlm_assoc_cnf); 2150 } else { 2151 /* 2152 * Will come here only in case of 11r, Ese FT 2153 * when reassoc rsp is not received and we 2154 * receive a reassoc - timesout 2155 */ 2156 mlm_assoc_cnf.resultCode = 2157 eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE; 2158 lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF, 2159 (uint32_t *) &mlm_assoc_cnf); 2160 } 2161 } else { 2162 /* 2163 * Restore pre-reassoc req state. 2164 * Set BSSID to currently associated AP address. 2165 */ 2166 session->limMlmState = session->limPrevMlmState; 2167 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2168 session->peSessionId, session->limMlmState)); 2169 lim_restore_pre_reassoc_state(mac_ctx, 2170 eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, 2171 STATUS_UNSPECIFIED_FAILURE, session); 2172 } 2173 } 2174