1 /* 2 * Copyright (c) 2012-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 "wni_api.h" 21 #include "wni_cfg.h" 22 #include "sir_api.h" 23 #include "sch_api.h" 24 #include "utils_api.h" 25 #include "lim_utils.h" 26 #include "lim_assoc_utils.h" 27 #include "lim_security_utils.h" 28 #include "lim_ser_des_utils.h" 29 #include "lim_timer_utils.h" 30 #include "lim_send_messages.h" 31 #include "lim_admit_control.h" 32 #include "lim_send_messages.h" 33 #include "lim_ft.h" 34 #include "lim_ft_defs.h" 35 #include "lim_session.h" 36 #include "lim_session_utils.h" 37 #include "rrm_api.h" 38 #include "wma_types.h" 39 #include "cds_utils.h" 40 #include "lim_types.h" 41 #include "wlan_policy_mgr_api.h" 42 #include "nan_datapath.h" 43 #include "wlan_reg_services_api.h" 44 #include "wma.h" 45 #include "wlan_pkt_capture_ucfg_api.h" 46 #include "wlan_lmac_if_def.h" 47 #include <lim_mlo.h> 48 #include "wlan_mlo_mgr_sta.h" 49 #include "utils_mlo.h" 50 #include "wlan_mlo_mgr_roam.h" 51 #include "wlan_mlme_api.h" 52 53 #define MAX_SUPPORTED_PEERS_WEP 16 54 55 void lim_process_mlm_join_cnf(struct mac_context *, uint32_t *); 56 void lim_process_mlm_auth_cnf(struct mac_context *, uint32_t *); 57 void lim_process_mlm_assoc_ind(struct mac_context *, uint32_t *); 58 void lim_process_mlm_assoc_cnf(struct mac_context *, uint32_t *); 59 void lim_process_mlm_set_keys_cnf(struct mac_context *, uint32_t *); 60 void lim_process_mlm_disassoc_ind(struct mac_context *, uint32_t *); 61 void lim_process_mlm_disassoc_cnf(struct mac_context *, uint32_t *); 62 static void lim_process_mlm_deauth_ind(struct mac_context *, tLimMlmDeauthInd *); 63 void lim_process_mlm_deauth_cnf(struct mac_context *, uint32_t *); 64 void lim_process_mlm_purge_sta_ind(struct mac_context *, uint32_t *); 65 66 /** 67 * lim_process_mlm_rsp_messages() 68 * 69 ***FUNCTION: 70 * This function is called to processes various MLM response (CNF/IND 71 * messages from MLM State machine. 72 * 73 ***LOGIC: 74 * 75 ***ASSUMPTIONS: 76 * 77 ***NOTE: 78 * 79 * @param mac Pointer to Global MAC structure 80 * @param msgType Indicates the MLM message type 81 * @param *msg_buf A pointer to the MLM message buffer 82 * 83 * @return None 84 */ 85 void lim_process_mlm_rsp_messages(struct mac_context * mac,uint32_t msgType,uint32_t * msg_buf)86 lim_process_mlm_rsp_messages(struct mac_context *mac, uint32_t msgType, 87 uint32_t *msg_buf) 88 { 89 90 if (!msg_buf) { 91 pe_err("Buffer is Pointing to NULL"); 92 return; 93 } 94 MTRACE(mac_trace(mac, TRACE_CODE_TX_LIM_MSG, 0, msgType)); 95 switch (msgType) { 96 case LIM_MLM_AUTH_CNF: 97 lim_process_mlm_auth_cnf(mac, msg_buf); 98 break; 99 case LIM_MLM_ASSOC_CNF: 100 lim_process_mlm_assoc_cnf(mac, msg_buf); 101 break; 102 case LIM_MLM_START_CNF: 103 lim_process_mlm_start_cnf(mac, msg_buf); 104 break; 105 case LIM_MLM_JOIN_CNF: 106 lim_process_mlm_join_cnf(mac, msg_buf); 107 break; 108 case LIM_MLM_ASSOC_IND: 109 lim_process_mlm_assoc_ind(mac, msg_buf); 110 break; 111 case LIM_MLM_REASSOC_CNF: 112 lim_process_mlm_reassoc_cnf(mac, msg_buf); 113 break; 114 case LIM_MLM_DISASSOC_CNF: 115 lim_process_mlm_disassoc_cnf(mac, msg_buf); 116 break; 117 case LIM_MLM_DISASSOC_IND: 118 lim_process_mlm_disassoc_ind(mac, msg_buf); 119 break; 120 case LIM_MLM_PURGE_STA_IND: 121 lim_process_mlm_purge_sta_ind(mac, msg_buf); 122 break; 123 case LIM_MLM_DEAUTH_CNF: 124 lim_process_mlm_deauth_cnf(mac, msg_buf); 125 break; 126 case LIM_MLM_DEAUTH_IND: 127 lim_process_mlm_deauth_ind(mac, (tLimMlmDeauthInd *)msg_buf); 128 break; 129 case LIM_MLM_SETKEYS_CNF: 130 lim_process_mlm_set_keys_cnf(mac, msg_buf); 131 break; 132 case LIM_MLM_TSPEC_CNF: 133 break; 134 default: 135 break; 136 } /* switch (msgType) */ 137 return; 138 } /*** end lim_process_mlm_rsp_messages() ***/ 139 140 /** 141 * lim_process_mlm_start_cnf() 142 * 143 ***FUNCTION: 144 * This function is called to processes MLM_START_CNF 145 * message from MLM State machine. 146 * 147 ***LOGIC: 148 * 149 ***ASSUMPTIONS: 150 * 151 ***NOTE: 152 * 153 * @param mac Pointer to Global MAC structure 154 * @param msg_buf A pointer to the MLM message buffer 155 * 156 * @return None 157 */ lim_process_mlm_start_cnf(struct mac_context * mac,uint32_t * msg_buf)158 void lim_process_mlm_start_cnf(struct mac_context *mac, uint32_t *msg_buf) 159 { 160 struct pe_session *pe_session = NULL; 161 tLimMlmStartCnf *pLimMlmStartCnf; 162 uint8_t smesessionId; 163 uint32_t chan_freq, ch_cfreq1 = 0; 164 uint8_t send_bcon_ind = false; 165 enum reg_wifi_band band; 166 167 if (!msg_buf) { 168 pe_err("Buffer is Pointing to NULL"); 169 return; 170 } 171 pLimMlmStartCnf = (tLimMlmStartCnf *)msg_buf; 172 pe_session = pe_find_session_by_session_id(mac, 173 pLimMlmStartCnf->sessionId); 174 if (!pe_session) { 175 pe_err("Session does Not exist with given sessionId"); 176 return; 177 } 178 smesessionId = pe_session->smeSessionId; 179 180 if (pe_session->limSmeState != eLIM_SME_WT_START_BSS_STATE) { 181 /* 182 * Should not have received Start confirm from MLM 183 * in other states. Log error. 184 */ 185 pe_err("received unexpected MLM_START_CNF in state %X", 186 pe_session->limSmeState); 187 return; 188 } 189 if (((tLimMlmStartCnf *)msg_buf)->resultCode == eSIR_SME_SUCCESS) { 190 191 /* 192 * Update global SME state so that Beacon Generation 193 * module starts writing Beacon frames into TFP's 194 * Beacon file register. 195 */ 196 pe_session->limSmeState = eLIM_SME_NORMAL_STATE; 197 MTRACE(mac_trace 198 (mac, TRACE_CODE_SME_STATE, pe_session->peSessionId, 199 pe_session->limSmeState)); 200 if (pe_session->bssType == eSIR_INFRA_AP_MODE) 201 pe_debug("*** Started BSS in INFRA AP SIDE***"); 202 else if (pe_session->bssType == eSIR_NDI_MODE) 203 pe_debug("*** Started BSS in NDI mode ***"); 204 else 205 pe_debug("*** Started BSS ***"); 206 } else { 207 /* Start BSS is a failure */ 208 pe_delete_session(mac, pe_session); 209 pe_session = NULL; 210 pe_err("Start BSS Failed"); 211 } 212 lim_send_sme_start_bss_rsp(mac, 213 ((tLimMlmStartCnf *)msg_buf)->resultCode, 214 pe_session, smesessionId); 215 if (pe_session && 216 (((tLimMlmStartCnf *)msg_buf)->resultCode == eSIR_SME_SUCCESS)) { 217 lim_ndi_mlme_vdev_up_transition(pe_session); 218 219 /* We should start beacon transmission only if the channel 220 * on which we are operating is non-DFS until the channel 221 * availability check is done. The PE will receive an explicit 222 * request from upper layers to start the beacon transmission 223 */ 224 chan_freq = pe_session->curr_op_freq; 225 band = wlan_reg_freq_to_band(pe_session->curr_op_freq); 226 if (pe_session->ch_center_freq_seg1) 227 ch_cfreq1 = wlan_reg_chan_band_to_freq( 228 mac->pdev, 229 pe_session->ch_center_freq_seg1, 230 BIT(band)); 231 232 if (!LIM_IS_AP_ROLE(pe_session)) 233 return; 234 if (pe_session->ch_width == CH_WIDTH_160MHZ) { 235 struct ch_params ch_params = {0}; 236 237 if (IS_DOT11_MODE_EHT(pe_session->dot11mode)) 238 wlan_reg_set_create_punc_bitmap(&ch_params, true); 239 ch_params.ch_width = pe_session->ch_width; 240 if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac->pdev, 241 chan_freq, 242 &ch_params, 243 REG_CURRENT_PWR_MODE) != 244 CHANNEL_STATE_DFS) 245 send_bcon_ind = true; 246 } else if (pe_session->ch_width == CH_WIDTH_80P80MHZ) { 247 if ((wlan_reg_get_channel_state_for_pwrmode( 248 mac->pdev, chan_freq, 249 REG_CURRENT_PWR_MODE) != 250 CHANNEL_STATE_DFS) && 251 (wlan_reg_get_channel_state_for_pwrmode( 252 mac->pdev, ch_cfreq1, 253 REG_CURRENT_PWR_MODE) != 254 CHANNEL_STATE_DFS)) 255 send_bcon_ind = true; 256 } else { 257 /* Indoor channels are also marked DFS, therefore 258 * check if the channel has REGULATORY_CHAN_RADAR 259 * channel flag to identify if the channel is DFS 260 */ 261 if (!wlan_reg_is_dfs_for_freq(mac->pdev, chan_freq)) 262 send_bcon_ind = true; 263 } 264 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq)) 265 send_bcon_ind = true; 266 267 if (send_bcon_ind) { 268 /* Configure beacon and send beacons to HAL */ 269 pe_debug("Start Beacon with ssid " QDF_SSID_FMT " Ch freq %d", 270 QDF_SSID_REF(pe_session->ssId.length, 271 pe_session->ssId.ssId), 272 pe_session->curr_op_freq); 273 lim_send_beacon(mac, pe_session); 274 lim_enable_obss_detection_config(mac, pe_session); 275 lim_send_obss_color_collision_cfg(mac, pe_session, 276 OBSS_COLOR_COLLISION_DETECTION); 277 } else { 278 lim_sap_move_to_cac_wait_state(pe_session); 279 } 280 } 281 } 282 283 /*** end lim_process_mlm_start_cnf() ***/ 284 285 /** 286 * lim_process_mlm_join_cnf() - Processes join confirmation 287 * @mac_ctx: Pointer to Global MAC structure 288 * @msg: A pointer to the MLM message buffer 289 * 290 * This Function handles the join confirmation message 291 * LIM_MLM_JOIN_CNF. 292 * 293 * Return: None 294 */ lim_process_mlm_join_cnf(struct mac_context * mac_ctx,uint32_t * msg)295 void lim_process_mlm_join_cnf(struct mac_context *mac_ctx, 296 uint32_t *msg) 297 { 298 tSirResultCodes result_code; 299 tLimMlmJoinCnf *join_cnf; 300 struct pe_session *session_entry; 301 302 join_cnf = (tLimMlmJoinCnf *) msg; 303 session_entry = pe_find_session_by_session_id(mac_ctx, 304 join_cnf->sessionId); 305 if (!session_entry) { 306 pe_err("SessionId:%d does not exist", join_cnf->sessionId); 307 return; 308 } 309 310 wlan_connectivity_sta_info_event(mac_ctx->psoc, session_entry->vdev_id, 311 false); 312 wlan_connectivity_connecting_event(session_entry->vdev, NULL); 313 314 session_entry->join_probe_cnt = 0; 315 if (session_entry->limSmeState != eLIM_SME_WT_JOIN_STATE) { 316 pe_err("received unexpected MLM_JOIN_CNF in state %X", 317 session_entry->limSmeState); 318 return; 319 } 320 321 result_code = ((tLimMlmJoinCnf *) msg)->resultCode; 322 /* Process Join confirm from MLM */ 323 if (result_code == eSIR_SME_SUCCESS) { 324 /* Setup hardware upfront */ 325 if (lim_sta_send_add_bss_pre_assoc(mac_ctx, 326 session_entry) == 327 QDF_STATUS_SUCCESS) 328 return; 329 else 330 result_code = eSIR_SME_REFUSED; 331 } 332 333 /* Join failure */ 334 session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; 335 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 336 session_entry->peSessionId, 337 session_entry->limSmeState)); 338 /* Send Join response to Host */ 339 lim_handle_sme_join_result(mac_ctx, result_code, 340 ((tLimMlmJoinCnf *) msg)->protStatusCode, session_entry); 341 return; 342 } 343 344 /** 345 * lim_send_mlm_assoc_req() - Association request will be processed 346 * mac_ctx: Pointer to Global MAC structure 347 * session_entry: Pointer to session etnry 348 * 349 * This function is sends ASSOC request MLM message to MLM State machine. 350 * ASSOC request packet would be by picking parameters from pe_session 351 * automatically based on the current state of MLM state machine. 352 * ASSUMPTIONS: 353 * this function is called in middle of connection state machine and is 354 * expected to be called after auth cnf has been received or after ASSOC rsp 355 * with TRY_AGAIN_LATER was received and required time has elapsed after that. 356 * 357 * Return: None 358 */ 359 lim_send_mlm_assoc_req(struct mac_context * mac_ctx,struct pe_session * session_entry)360 static void lim_send_mlm_assoc_req(struct mac_context *mac_ctx, 361 struct pe_session *session_entry) 362 { 363 tLimMlmAssocReq *assoc_req; 364 uint32_t val; 365 uint16_t caps; 366 uint32_t tele_bcn = 0; 367 tpSirMacCapabilityInfo cap_info; 368 369 if (!session_entry->lim_join_req) { 370 pe_err("Join Request is NULL"); 371 /* No need to Assert. JOIN timeout will handle this error */ 372 return; 373 } 374 375 assoc_req = qdf_mem_malloc(sizeof(tLimMlmAssocReq)); 376 if (!assoc_req) { 377 pe_err("call to AllocateMemory failed for mlmAssocReq"); 378 return; 379 } 380 val = sizeof(tSirMacAddr); 381 sir_copy_mac_addr(assoc_req->peerMacAddr, session_entry->bssId); 382 383 if (lim_get_capability_info(mac_ctx, &caps, session_entry) 384 != QDF_STATUS_SUCCESS) 385 /* Could not get Capabilities value from CFG.*/ 386 pe_err("could not retrieve Capabilities value"); 387 388 /* Clear spectrum management bit if AP doesn't support it */ 389 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo & 390 LIM_SPECTRUM_MANAGEMENT_BIT_MASK)) 391 /* 392 * AP doesn't support spectrum management 393 * clear spectrum management bit 394 */ 395 caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK); 396 397 /* Clear rrm bit if AP doesn't support it */ 398 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo & 399 LIM_RRM_BIT_MASK)) 400 caps &= (~LIM_RRM_BIT_MASK); 401 402 /* Clear short preamble bit if AP does not support it */ 403 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo & 404 (LIM_SHORT_PREAMBLE_BIT_MASK))) { 405 caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK); 406 pe_debug("Clearing short preamble:no AP support"); 407 } 408 409 /* Clear immediate block ack bit if AP does not support it */ 410 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo & 411 (LIM_IMMEDIATE_BLOCK_ACK_MASK))) { 412 caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK); 413 pe_debug("Clearing Immed Blk Ack:no AP support"); 414 } 415 416 assoc_req->capabilityInfo = caps; 417 cap_info = ((tpSirMacCapabilityInfo) &assoc_req->capabilityInfo); 418 419 /* 420 * If telescopic beaconing is enabled, set listen interval to 421 * CFG_TELE_BCN_MAX_LI 422 */ 423 tele_bcn = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_wakeup_en; 424 if (tele_bcn) 425 val = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_max_li; 426 else 427 val = mac_ctx->mlme_cfg->sap_cfg.listen_interval; 428 429 #ifdef FEATURE_WLAN_DIAG_SUPPORT 430 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_REQ_EVENT, 431 session_entry, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 432 #endif 433 assoc_req->listenInterval = (uint16_t) val; 434 pe_debug("Listen Interval : %d", assoc_req->listenInterval); 435 /* Update PE session ID */ 436 assoc_req->sessionId = session_entry->peSessionId; 437 session_entry->limPrevSmeState = session_entry->limSmeState; 438 session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE; 439 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 440 session_entry->peSessionId, session_entry->limSmeState)); 441 lim_post_mlm_message(mac_ctx, LIM_MLM_ASSOC_REQ, 442 (uint32_t *) assoc_req); 443 } 444 445 /** 446 * lim_pmf_comeback_timer_callback() -PMF callback handler 447 * @context: Timer context 448 * 449 * This function is called to processes the PMF comeback 450 * callback 451 * 452 * Return: None 453 */ lim_pmf_comeback_timer_callback(void * context)454 void lim_pmf_comeback_timer_callback(void *context) 455 { 456 struct comeback_timer_info *info = 457 (struct comeback_timer_info *)context; 458 struct mac_context *mac_ctx = info->mac; 459 struct pe_session *session; 460 461 session = pe_find_session_by_vdev_id(mac_ctx, info->vdev_id); 462 if (!session) { 463 pe_err("no session found for vdev %d", info->vdev_id); 464 return; 465 } 466 467 if (session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) { 468 pe_debug("Don't send assoc req, timer expire when limMlmState %d vdev id %d", 469 session->limMlmState, session->vdev_id); 470 return; 471 } 472 473 pe_info("comeback later timer expired. sending MLM ASSOC req for vdev %d, session limMlmState %d, info lim_mlm_state %d", 474 session->vdev_id, session->limMlmState, info->lim_mlm_state); 475 476 /* set MLM state such that ASSOC REQ packet will be sent out */ 477 session->limPrevMlmState = info->lim_prev_mlm_state; 478 session->limMlmState = info->lim_mlm_state; 479 lim_send_mlm_assoc_req(mac_ctx, session); 480 } 481 482 /** 483 * lim_process_mlm_auth_cnf()-Process Auth confirmation 484 * @mac_ctx: Pointer to Global MAC structure 485 * @msg: A pointer to the MLM message buffer 486 * 487 * This function is called to processes MLM_AUTH_CNF 488 * message from MLM State machine. 489 * 490 * Return: None 491 */ lim_process_mlm_auth_cnf(struct mac_context * mac_ctx,uint32_t * msg)492 void lim_process_mlm_auth_cnf(struct mac_context *mac_ctx, uint32_t *msg) 493 { 494 tAniAuthType auth_type, auth_mode; 495 tLimMlmAuthReq *auth_req; 496 tLimMlmAuthCnf *auth_cnf; 497 struct pe_session *session_entry; 498 499 if (!msg) { 500 pe_err("Buffer is Pointing to NULL"); 501 return; 502 } 503 auth_cnf = (tLimMlmAuthCnf *) msg; 504 session_entry = pe_find_session_by_session_id(mac_ctx, 505 auth_cnf->sessionId); 506 if (!session_entry) { 507 pe_err("SessionId:%d session doesn't exist", 508 auth_cnf->sessionId); 509 return; 510 } 511 512 if ((session_entry->limSmeState != eLIM_SME_WT_AUTH_STATE && 513 session_entry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE) || 514 LIM_IS_AP_ROLE(session_entry)) { 515 /** 516 * Should not have received AUTH confirm 517 * from MLM in other states or on AP. 518 * Log error 519 */ 520 pe_err("SessionId:%d received MLM_AUTH_CNF in state %X", 521 session_entry->peSessionId, session_entry->limSmeState); 522 return; 523 } 524 525 if (auth_cnf->resultCode == eSIR_SME_SUCCESS) { 526 if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) { 527 lim_deactivate_and_change_timer(mac_ctx, 528 eLIM_ASSOC_FAIL_TIMER); 529 lim_send_mlm_assoc_req(mac_ctx, session_entry); 530 } else { 531 /* 532 * Successful Pre-authentication. Send 533 * Pre-auth response to host 534 */ 535 session_entry->limSmeState = 536 session_entry->limPrevSmeState; 537 MTRACE(mac_trace 538 (mac_ctx, TRACE_CODE_SME_STATE, 539 session_entry->peSessionId, 540 session_entry->limSmeState)); 541 } 542 /* Return for success case */ 543 return; 544 } 545 /* 546 * Failure case handle: 547 * Process AUTH confirm from MLM 548 */ 549 if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) 550 auth_type = mac_ctx->mlme_cfg->wep_params.auth_type; 551 else 552 auth_type = mac_ctx->lim.gLimPreAuthType; 553 554 if ((auth_type == eSIR_AUTO_SWITCH) && 555 (auth_cnf->authType == eSIR_SHARED_KEY) && 556 ((auth_cnf->protStatusCode == STATUS_NOT_SUPPORTED_AUTH_ALG) || 557 (auth_cnf->resultCode == eSIR_SME_AUTH_TIMEOUT_RESULT_CODE))) { 558 /* 559 * When shared authentication fails with reason 560 * code "13" and authType set to 'auto switch', 561 * Try with open Authentication 562 */ 563 auth_mode = eSIR_OPEN_SYSTEM; 564 /* Trigger MAC based Authentication */ 565 auth_req = qdf_mem_malloc(sizeof(tLimMlmAuthReq)); 566 if (!auth_req) { 567 pe_err("mlmAuthReq :Memory alloc failed"); 568 return; 569 } 570 if (session_entry->limSmeState == 571 eLIM_SME_WT_AUTH_STATE) { 572 sir_copy_mac_addr(auth_req->peerMacAddr, 573 session_entry->bssId); 574 } else { 575 qdf_mem_copy((uint8_t *)&auth_req->peerMacAddr, 576 (uint8_t *)&mac_ctx->lim.gLimPreAuthPeerAddr, 577 sizeof(tSirMacAddr)); 578 } 579 auth_req->authType = auth_mode; 580 /* Update PE session Id */ 581 auth_req->sessionId = auth_cnf->sessionId; 582 lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ, 583 (uint32_t *) auth_req); 584 return; 585 } else { 586 /* MAC based authentication failure */ 587 if (session_entry->limSmeState == 588 eLIM_SME_WT_AUTH_STATE) { 589 pe_err("Auth Failure occurred"); 590 session_entry->limSmeState = 591 eLIM_SME_JOIN_FAILURE_STATE; 592 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 593 session_entry->peSessionId, 594 session_entry->limSmeState)); 595 session_entry->limMlmState = 596 eLIM_MLM_IDLE_STATE; 597 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 598 session_entry->peSessionId, 599 session_entry->limMlmState)); 600 601 /* WAR for some IOT issue on specific AP: 602 * STA failed to connect to SAE AP due to incorrect 603 * password is used. Then AP will still reject the 604 * authentication even correct password is used unless 605 * STA send deauth to AP upon authentication failure. 606 * 607 * Do not send deauth mgmt frame when already in Deauth 608 * state while joining. 609 */ 610 if (auth_type == eSIR_AUTH_TYPE_SAE && 611 auth_cnf->resultCode != eSIR_SME_DEAUTH_WHILE_JOIN) { 612 pe_debug("Send deauth for SAE auth failure"); 613 lim_send_deauth_mgmt_frame(mac_ctx, 614 REASON_TIMEDOUT, 615 auth_cnf->peerMacAddr, 616 session_entry, false); 617 } 618 619 /* 620 * Need to send Join response with 621 * auth failure to Host. 622 */ 623 lim_handle_sme_join_result(mac_ctx, 624 auth_cnf->resultCode, 625 auth_cnf->protStatusCode, 626 session_entry); 627 } else { 628 /* 629 * Pre-authentication failure. 630 * Send Pre-auth failure response to host 631 */ 632 session_entry->limSmeState = 633 session_entry->limPrevSmeState; 634 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 635 session_entry->peSessionId, 636 session_entry->limSmeState)); 637 } 638 } 639 } 640 641 /** 642 * lim_process_mlm_assoc_cnf() - Process association confirmation 643 * @mac_ctx: Pointer to Global MAC structure 644 * @msg: A pointer to the MLM message buffer 645 * 646 * This function is called to processes MLM_ASSOC_CNF 647 * message from MLM State machine. 648 * 649 * Return: None 650 */ lim_process_mlm_assoc_cnf(struct mac_context * mac_ctx,uint32_t * msg)651 void lim_process_mlm_assoc_cnf(struct mac_context *mac_ctx, 652 uint32_t *msg) 653 { 654 struct pe_session *session_entry; 655 tLimMlmAssocCnf *assoc_cnf; 656 657 if (!msg) { 658 pe_err("Buffer is Pointing to NULL"); 659 return; 660 } 661 assoc_cnf = (tLimMlmAssocCnf *) msg; 662 session_entry = pe_find_session_by_session_id(mac_ctx, 663 assoc_cnf->sessionId); 664 if (!session_entry) { 665 pe_err("SessionId:%d Session does not exist", 666 assoc_cnf->sessionId); 667 return; 668 } 669 if (session_entry->limSmeState != eLIM_SME_WT_ASSOC_STATE || 670 LIM_IS_AP_ROLE(session_entry)) { 671 /* 672 * Should not have received Assocication confirm 673 * from MLM in other states OR on AP. 674 * Log error 675 */ 676 pe_err("SessionId:%d Received MLM_ASSOC_CNF in state %X", 677 session_entry->peSessionId, session_entry->limSmeState); 678 return; 679 } 680 if (((tLimMlmAssocCnf *) msg)->resultCode != eSIR_SME_SUCCESS) { 681 /* Association failure */ 682 pe_err("SessionId:%d Association failure resultCode: %d limSmeState:%d", 683 session_entry->peSessionId, 684 ((tLimMlmAssocCnf *) msg)->resultCode, 685 session_entry->limSmeState); 686 687 /* If driver gets deauth when its waiting for ADD_STA_RSP then 688 * we need to do DEL_STA followed by DEL_BSS. So based on below 689 * reason-code here we decide whether to do only DEL_BSS or 690 * DEL_STA + DEL_BSS. 691 */ 692 if (((tLimMlmAssocCnf *) msg)->resultCode != 693 eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA) 694 session_entry->limSmeState = 695 eLIM_SME_JOIN_FAILURE_STATE; 696 697 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 698 session_entry->peSessionId, mac_ctx->lim.gLimSmeState)); 699 /* 700 * Need to send Join response with 701 * Association failure to Host. 702 */ 703 lim_handle_sme_join_result(mac_ctx, 704 ((tLimMlmAssocCnf *) msg)->resultCode, 705 ((tLimMlmAssocCnf *) msg)->protStatusCode, 706 session_entry); 707 } else { 708 /* Successful Association */ 709 pe_debug("SessionId:%d Associated with BSS", 710 session_entry->peSessionId); 711 session_entry->limSmeState = eLIM_SME_LINK_EST_STATE; 712 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 713 session_entry->peSessionId, 714 session_entry->limSmeState)); 715 /** 716 * Need to send Join response with 717 * Association success to Host. 718 */ 719 lim_handle_sme_join_result(mac_ctx, 720 ((tLimMlmAssocCnf *) msg)->resultCode, 721 ((tLimMlmAssocCnf *) msg)->protStatusCode, 722 session_entry); 723 } 724 } 725 726 #ifdef WLAN_FEATURE_11BE_MLO 727 static void lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind * sme_assoc_ind,tpLimMlmAssocInd assoc_ind,uint32_t num_bytes)728 lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind *sme_assoc_ind, 729 tpLimMlmAssocInd assoc_ind, 730 uint32_t num_bytes) 731 { 732 qdf_mem_copy(sme_assoc_ind->peer_mld_addr, assoc_ind->peer_mld_addr, 733 num_bytes); 734 } 735 736 /** 737 * lim_update_connected_links() - Update connected mlo links bmap 738 * @session: Pointer to pe session 739 * 740 * Update connected mlo links bmap for all vdev taking 741 * part in association 742 * 743 * Return: None 744 */ lim_update_connected_links(struct pe_session * session)745 static void lim_update_connected_links(struct pe_session *session) 746 { 747 mlo_update_connected_links(session->vdev, 1); 748 mlo_update_connected_links_bmap(session->vdev->mlo_dev_ctx, 749 session->ml_partner_info); 750 } 751 #else /* WLAN_FEATURE_11BE_MLO */ 752 static inline void lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind * sme_assoc_ind,tpLimMlmAssocInd assoc_ind,uint32_t num_bytes)753 lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind *sme_assoc_ind, 754 tpLimMlmAssocInd assoc_ind, 755 uint32_t num_bytes) 756 { 757 } 758 lim_update_connected_links(struct pe_session * session)759 static void lim_update_connected_links(struct pe_session *session) 760 { 761 } 762 #endif /* WLAN_FEATURE_11BE_MLO */ 763 764 void lim_fill_sme_assoc_ind_params(struct mac_context * mac_ctx,tpLimMlmAssocInd assoc_ind,struct assoc_ind * sme_assoc_ind,struct pe_session * session_entry,bool assoc_req_alloc)765 lim_fill_sme_assoc_ind_params( 766 struct mac_context *mac_ctx, 767 tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind, 768 struct pe_session *session_entry, bool assoc_req_alloc) 769 { 770 sme_assoc_ind->length = sizeof(struct assoc_ind); 771 sme_assoc_ind->sessionId = session_entry->smeSessionId; 772 773 /* Required for indicating the frames to upper layer */ 774 sme_assoc_ind->assocReqLength = assoc_ind->assocReqLength; 775 if (assoc_req_alloc && assoc_ind->assocReqLength) { 776 sme_assoc_ind->assocReqPtr = qdf_mem_malloc( 777 assoc_ind->assocReqLength); 778 qdf_mem_copy(sme_assoc_ind->assocReqPtr, assoc_ind->assocReqPtr, 779 assoc_ind->assocReqLength); 780 } else { 781 sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr; 782 } 783 784 /* Fill in peerMacAddr */ 785 qdf_mem_copy(sme_assoc_ind->peerMacAddr, assoc_ind->peerMacAddr, 786 sizeof(tSirMacAddr)); 787 lim_fill_sme_assoc_ind_mlo_mld_addr_copy(sme_assoc_ind, assoc_ind, 788 sizeof(tSirMacAddr)); 789 /* Fill in aid */ 790 sme_assoc_ind->aid = assoc_ind->aid; 791 /* Fill in bssId */ 792 qdf_mem_copy(sme_assoc_ind->bssId, session_entry->bssId, 793 sizeof(tSirMacAddr)); 794 /* Fill in authType */ 795 sme_assoc_ind->authType = assoc_ind->authType; 796 /* Fill in rsn_akm_type */ 797 sme_assoc_ind->akm_type = assoc_ind->akm_type; 798 /* Fill in ssId */ 799 qdf_mem_copy((uint8_t *) &sme_assoc_ind->ssId, 800 (uint8_t *) &(assoc_ind->ssId), assoc_ind->ssId.length + 1); 801 sme_assoc_ind->rsnIE.length = assoc_ind->rsnIE.length; 802 qdf_mem_copy((uint8_t *) &sme_assoc_ind->rsnIE.rsnIEdata, 803 (uint8_t *) &(assoc_ind->rsnIE.rsnIEdata), 804 assoc_ind->rsnIE.length); 805 806 #ifdef FEATURE_WLAN_WAPI 807 sme_assoc_ind->wapiIE.length = assoc_ind->wapiIE.length; 808 qdf_mem_copy((uint8_t *) &sme_assoc_ind->wapiIE.wapiIEdata, 809 (uint8_t *) &(assoc_ind->wapiIE.wapiIEdata), 810 assoc_ind->wapiIE.length); 811 #endif 812 sme_assoc_ind->addIE.length = assoc_ind->addIE.length; 813 qdf_mem_copy((uint8_t *) &sme_assoc_ind->addIE.addIEdata, 814 (uint8_t *) &(assoc_ind->addIE.addIEdata), 815 assoc_ind->addIE.length); 816 817 /* Copy the new TITAN capabilities */ 818 sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator; 819 if (assoc_ind->spectrumMgtIndicator == true) { 820 sme_assoc_ind->powerCap.minTxPower = 821 assoc_ind->powerCap.minTxPower; 822 sme_assoc_ind->powerCap.maxTxPower = 823 assoc_ind->powerCap.maxTxPower; 824 sme_assoc_ind->supportedChannels.numChnl = 825 assoc_ind->supportedChannels.numChnl; 826 qdf_mem_copy((uint8_t *) &sme_assoc_ind->supportedChannels. 827 channelList, 828 (uint8_t *) &(assoc_ind->supportedChannels.channelList), 829 assoc_ind->supportedChannels.numChnl); 830 } 831 qdf_mem_copy(&sme_assoc_ind->chan_info, &assoc_ind->chan_info, 832 sizeof(struct oem_channel_info)); 833 /* Fill in WmmInfo */ 834 sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent; 835 sme_assoc_ind->ampdu = assoc_ind->ampdu; 836 sme_assoc_ind->sgi_enable = assoc_ind->sgi_enable; 837 sme_assoc_ind->tx_stbc = assoc_ind->tx_stbc; 838 sme_assoc_ind->rx_stbc = assoc_ind->rx_stbc; 839 sme_assoc_ind->ch_width = assoc_ind->ch_width; 840 sme_assoc_ind->mode = assoc_ind->mode; 841 sme_assoc_ind->max_supp_idx = assoc_ind->max_supp_idx; 842 sme_assoc_ind->max_ext_idx = assoc_ind->max_ext_idx; 843 sme_assoc_ind->max_mcs_idx = assoc_ind->max_mcs_idx; 844 sme_assoc_ind->max_real_mcs_idx = assoc_ind->max_real_mcs_idx; 845 sme_assoc_ind->rx_mcs_map = assoc_ind->rx_mcs_map; 846 sme_assoc_ind->tx_mcs_map = assoc_ind->tx_mcs_map; 847 sme_assoc_ind->ecsa_capable = assoc_ind->ecsa_capable; 848 sme_assoc_ind->ext_cap = assoc_ind->ext_cap; 849 sme_assoc_ind->supported_band = assoc_ind->supported_band; 850 851 if (assoc_ind->ht_caps.present) 852 sme_assoc_ind->HTCaps = assoc_ind->ht_caps; 853 if (assoc_ind->vht_caps.present) 854 sme_assoc_ind->VHTCaps = assoc_ind->vht_caps; 855 sme_assoc_ind->capability_info = assoc_ind->capabilityInfo; 856 sme_assoc_ind->he_caps_present = assoc_ind->he_caps_present; 857 sme_assoc_ind->eht_caps_present = assoc_ind->eht_caps_present; 858 sme_assoc_ind->is_sae_authenticated = assoc_ind->is_sae_authenticated; 859 } 860 861 /** 862 * lim_process_mlm_assoc_ind() - This function is called to processes MLM_ASSOC_IND 863 * message from MLM State machine. 864 * @mac Pointer to Global MAC structure 865 * @msg_buf A pointer to the MLM message buffer 866 * 867 * Return: None 868 */ lim_process_mlm_assoc_ind(struct mac_context * mac,uint32_t * msg_buf)869 void lim_process_mlm_assoc_ind(struct mac_context *mac, uint32_t *msg_buf) 870 { 871 uint32_t len; 872 struct scheduler_msg msg = {0}; 873 struct assoc_ind *pSirSmeAssocInd; 874 tpDphHashNode sta = 0; 875 struct pe_session *pe_session; 876 877 if (!msg_buf) { 878 pe_err("Buffer is Pointing to NULL"); 879 return; 880 } 881 pe_session = pe_find_session_by_session_id(mac, 882 ((tpLimMlmAssocInd) msg_buf)->sessionId); 883 if (!pe_session) { 884 pe_err("Session Does not exist for given sessionId"); 885 return; 886 } 887 /* / Inform Host of STA association */ 888 len = sizeof(struct assoc_ind); 889 pSirSmeAssocInd = qdf_mem_malloc(len); 890 if (!pSirSmeAssocInd) { 891 pe_err("call to AllocateMemory failed for eWNI_SME_ASSOC_IND"); 892 return; 893 } 894 895 pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND; 896 lim_fill_sme_assoc_ind_params(mac, (tpLimMlmAssocInd)msg_buf, 897 pSirSmeAssocInd, 898 pe_session, false); 899 msg.type = eWNI_SME_ASSOC_IND; 900 msg.bodyptr = pSirSmeAssocInd; 901 msg.bodyval = 0; 902 sta = dph_get_hash_entry(mac, 903 ((tpLimMlmAssocInd) msg_buf)->aid, 904 &pe_session->dph.dphHashTable); 905 if (!sta) { 906 pe_err("MLM AssocInd: Station context no longer valid (aid %d)", 907 ((tpLimMlmAssocInd) msg_buf)->aid); 908 qdf_mem_free(pSirSmeAssocInd); 909 910 return; 911 } 912 913 pSirSmeAssocInd->reassocReq = sta->mlmStaContext.subType; 914 pSirSmeAssocInd->timingMeasCap = sta->timingMeasCap; 915 MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG, 916 pe_session->peSessionId, msg.type)); 917 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 918 lim_diag_event_report(mac, WLAN_PE_DIAG_ASSOC_IND_EVENT, pe_session, 0, 919 0); 920 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 921 pe_debug("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND"); 922 /* 923 ** turn on a timer to detect the loss of ASSOC CNF 924 **/ 925 lim_activate_cnf_timer(mac, 926 (uint16_t) ((tpLimMlmAssocInd)msg_buf)->aid, 927 pe_session); 928 929 mac->lim.sme_msg_callback(mac, &msg); 930 } /*** end lim_process_mlm_assoc_ind() ***/ 931 932 /** 933 * lim_process_mlm_disassoc_ind() - This function is called to processes 934 * MLM_DISASSOC_IND message from MLM State machine. 935 * @mac: Pointer to Global MAC structure 936 * @msg_buf: A pointer to the MLM message buffer 937 * 938 * Return None 939 */ lim_process_mlm_disassoc_ind(struct mac_context * mac,uint32_t * msg_buf)940 void lim_process_mlm_disassoc_ind(struct mac_context *mac, uint32_t *msg_buf) 941 { 942 tLimMlmDisassocInd *pMlmDisassocInd; 943 struct pe_session *pe_session; 944 945 pMlmDisassocInd = (tLimMlmDisassocInd *)msg_buf; 946 pe_session = pe_find_session_by_session_id(mac, 947 pMlmDisassocInd->sessionId); 948 if (!pe_session) { 949 pe_err("Session Does not exist for given sessionID"); 950 return; 951 } 952 switch (GET_LIM_SYSTEM_ROLE(pe_session)) { 953 case eLIM_STA_ROLE: 954 pe_session->limSmeState = eLIM_SME_WT_DISASSOC_STATE; 955 MTRACE(mac_trace 956 (mac, TRACE_CODE_SME_STATE, pe_session->peSessionId, 957 pe_session->limSmeState)); 958 break; 959 default: /* eLIM_AP_ROLE */ 960 pe_debug("*** Peer staId=%d Disassociated ***", 961 pMlmDisassocInd->aid); 962 /* Send SME_DISASOC_IND after Polaris cleanup */ 963 /* (after receiving LIM_MLM_PURGE_STA_IND) */ 964 break; 965 } /* end switch (GET_LIM_SYSTEM_ROLE(pe_session)) */ 966 } /*** end lim_process_mlm_disassoc_ind() ***/ 967 968 /** 969 * lim_process_mlm_disassoc_cnf() - Processes disassociation 970 * @mac_ctx: Pointer to Global MAC structure 971 * @msg: A pointer to the MLM message buffer 972 * 973 * This function is called to processes MLM_DISASSOC_CNF 974 * message from MLM State machine. 975 * 976 * Return: None 977 */ lim_process_mlm_disassoc_cnf(struct mac_context * mac_ctx,uint32_t * msg)978 void lim_process_mlm_disassoc_cnf(struct mac_context *mac_ctx, 979 uint32_t *msg) 980 { 981 tSirResultCodes result_code; 982 tLimMlmDisassocCnf *disassoc_cnf; 983 struct pe_session *session_entry; 984 985 disassoc_cnf = (tLimMlmDisassocCnf *) msg; 986 987 session_entry = 988 pe_find_session_by_session_id(mac_ctx, disassoc_cnf->sessionId); 989 if (!session_entry) { 990 pe_err("session Does not exist for given session Id"); 991 return; 992 } 993 result_code = (tSirResultCodes)(disassoc_cnf->disassocTrigger == 994 eLIM_LINK_MONITORING_DISASSOC) ? 995 eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE : 996 disassoc_cnf->resultCode; 997 if (LIM_IS_STA_ROLE(session_entry)) { 998 /* Disassociate Confirm from MLM */ 999 if ((session_entry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) 1000 && (session_entry->limSmeState != 1001 eLIM_SME_WT_DEAUTH_STATE)) { 1002 /* 1003 * Should not have received 1004 * Disassociate confirm 1005 * from MLM in other states.Log error 1006 */ 1007 pe_err("received MLM_DISASSOC_CNF in state %X", 1008 session_entry->limSmeState); 1009 return; 1010 } 1011 if (mac_ctx->lim.gLimRspReqd) 1012 mac_ctx->lim.gLimRspReqd = false; 1013 if (disassoc_cnf->disassocTrigger == 1014 eLIM_PROMISCUOUS_MODE_DISASSOC) { 1015 if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS) 1016 session_entry->limSmeState = 1017 session_entry->limPrevSmeState; 1018 else 1019 session_entry->limSmeState = 1020 eLIM_SME_OFFLINE_STATE; 1021 MTRACE(mac_trace 1022 (mac_ctx, TRACE_CODE_SME_STATE, 1023 session_entry->peSessionId, 1024 session_entry->limSmeState)); 1025 } else { 1026 if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS) 1027 session_entry->limSmeState = 1028 session_entry->limPrevSmeState; 1029 else 1030 session_entry->limSmeState = 1031 eLIM_SME_IDLE_STATE; 1032 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 1033 session_entry->peSessionId, 1034 session_entry->limSmeState)); 1035 lim_send_sme_disassoc_ntf(mac_ctx, 1036 disassoc_cnf->peerMacAddr, result_code, 1037 disassoc_cnf->disassocTrigger, 1038 disassoc_cnf->aid, session_entry->smeSessionId, 1039 session_entry); 1040 } 1041 } else if (LIM_IS_AP_ROLE(session_entry)) { 1042 lim_send_sme_disassoc_ntf(mac_ctx, disassoc_cnf->peerMacAddr, 1043 result_code, disassoc_cnf->disassocTrigger, 1044 disassoc_cnf->aid, session_entry->smeSessionId, 1045 session_entry); 1046 } 1047 } 1048 1049 /** 1050 * lim_process_mlm_deauth_ind() - processes MLM_DEAUTH_IND 1051 * @mac_ctx: global mac structure 1052 * @deauth_ind: deauth indication 1053 * 1054 * This function is called to processes MLM_DEAUTH_IND 1055 * message from MLM State machine. 1056 * 1057 * Return: None 1058 */ lim_process_mlm_deauth_ind(struct mac_context * mac_ctx,tLimMlmDeauthInd * deauth_ind)1059 static void lim_process_mlm_deauth_ind(struct mac_context *mac_ctx, 1060 tLimMlmDeauthInd *deauth_ind) 1061 { 1062 struct pe_session *session; 1063 uint8_t session_id; 1064 enum eLimSystemRole role; 1065 1066 if (!deauth_ind) { 1067 pe_err("deauth_ind is null"); 1068 return; 1069 } 1070 session = pe_find_session_by_bssid(mac_ctx, 1071 deauth_ind->peerMacAddr, 1072 &session_id); 1073 if (!session) { 1074 pe_err("session does not exist for Addr:" QDF_MAC_ADDR_FMT, 1075 QDF_MAC_ADDR_REF(deauth_ind->peerMacAddr)); 1076 return; 1077 } 1078 role = GET_LIM_SYSTEM_ROLE(session); 1079 if (role == eLIM_STA_ROLE) { 1080 session->limSmeState = eLIM_SME_WT_DEAUTH_STATE; 1081 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 1082 session->peSessionId, session->limSmeState)); 1083 } 1084 } 1085 1086 /** 1087 * lim_process_mlm_deauth_cnf() 1088 * 1089 ***FUNCTION: 1090 * This function is called to processes MLM_DEAUTH_CNF 1091 * message from MLM State machine. 1092 * 1093 ***LOGIC: 1094 * 1095 ***ASSUMPTIONS: 1096 * 1097 ***NOTE: 1098 * 1099 * @param mac Pointer to Global MAC structure 1100 * @param msg_buf A pointer to the MLM message buffer 1101 * 1102 * @return None 1103 */ lim_process_mlm_deauth_cnf(struct mac_context * mac,uint32_t * msg_buf)1104 void lim_process_mlm_deauth_cnf(struct mac_context *mac, uint32_t *msg_buf) 1105 { 1106 uint16_t aid; 1107 tSirResultCodes resultCode; 1108 tLimMlmDeauthCnf *pMlmDeauthCnf; 1109 struct pe_session *pe_session; 1110 1111 if (!msg_buf) { 1112 pe_err("Buffer is Pointing to NULL"); 1113 return; 1114 } 1115 pMlmDeauthCnf = (tLimMlmDeauthCnf *)msg_buf; 1116 pe_session = pe_find_session_by_session_id(mac, 1117 pMlmDeauthCnf->sessionId); 1118 if (!pe_session) { 1119 pe_err("session does not exist for given session Id"); 1120 return; 1121 } 1122 1123 resultCode = (tSirResultCodes) 1124 (pMlmDeauthCnf->deauthTrigger == 1125 eLIM_LINK_MONITORING_DEAUTH) ? 1126 eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE : 1127 pMlmDeauthCnf->resultCode; 1128 aid = LIM_IS_AP_ROLE(pe_session) ? pMlmDeauthCnf->aid : 1; 1129 if (LIM_IS_STA_ROLE(pe_session)) { 1130 /* Deauth Confirm from MLM */ 1131 if ((pe_session->limSmeState != eLIM_SME_WT_DISASSOC_STATE) 1132 && pe_session->limSmeState != 1133 eLIM_SME_WT_DEAUTH_STATE) { 1134 /** 1135 * Should not have received Deauth confirm 1136 * from MLM in other states. 1137 * Log error 1138 */ 1139 pe_err("received unexpected MLM_DEAUTH_CNF in state %X", 1140 pe_session->limSmeState); 1141 return; 1142 } 1143 if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) { 1144 pe_session->limSmeState = eLIM_SME_IDLE_STATE; 1145 } else 1146 pe_session->limSmeState = 1147 pe_session->limPrevSmeState; 1148 MTRACE(mac_trace 1149 (mac, TRACE_CODE_SME_STATE, pe_session->peSessionId, 1150 pe_session->limSmeState)); 1151 1152 if (mac->lim.gLimRspReqd) 1153 mac->lim.gLimRspReqd = false; 1154 } 1155 /* On STA or on BASIC AP, send SME_DEAUTH_RSP to host */ 1156 lim_send_sme_deauth_ntf(mac, pMlmDeauthCnf->peer_macaddr.bytes, 1157 resultCode, 1158 pMlmDeauthCnf->deauthTrigger, 1159 aid, pe_session->smeSessionId); 1160 } /*** end lim_process_mlm_deauth_cnf() ***/ 1161 1162 /** 1163 * lim_process_mlm_purge_sta_ind() 1164 * 1165 ***FUNCTION: 1166 * This function is called to processes MLM_PURGE_STA_IND 1167 * message from MLM State machine. 1168 * 1169 ***LOGIC: 1170 * 1171 ***ASSUMPTIONS: 1172 * 1173 ***NOTE: 1174 * 1175 * @param mac Pointer to Global MAC structure 1176 * @param msg_buf A pointer to the MLM message buffer 1177 * 1178 * @return None 1179 */ lim_process_mlm_purge_sta_ind(struct mac_context * mac,uint32_t * msg_buf)1180 void lim_process_mlm_purge_sta_ind(struct mac_context *mac, uint32_t *msg_buf) 1181 { 1182 tSirResultCodes resultCode; 1183 tpLimMlmPurgeStaInd pMlmPurgeStaInd; 1184 struct pe_session *pe_session; 1185 1186 if (!msg_buf) { 1187 pe_err("Buffer is Pointing to NULL"); 1188 return; 1189 } 1190 pMlmPurgeStaInd = (tpLimMlmPurgeStaInd)msg_buf; 1191 pe_session = pe_find_session_by_session_id(mac, 1192 pMlmPurgeStaInd->sessionId); 1193 if (!pe_session) { 1194 pe_err("session does not exist for given bssId"); 1195 return; 1196 } 1197 /* Purge STA indication from MLM */ 1198 resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode; 1199 switch (GET_LIM_SYSTEM_ROLE(pe_session)) { 1200 case eLIM_STA_ROLE: 1201 default: /* eLIM_AP_ROLE */ 1202 if (LIM_IS_STA_ROLE(pe_session) && 1203 (pe_session->limSmeState != 1204 eLIM_SME_WT_DISASSOC_STATE) && 1205 (pe_session->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) { 1206 /** 1207 * Should not have received 1208 * Purge STA indication 1209 * from MLM in other states. 1210 * Log error 1211 */ 1212 pe_err("received unexpected MLM_PURGE_STA_IND in state %X", 1213 pe_session->limSmeState); 1214 break; 1215 } 1216 pe_debug("*** Cleanup completed for staId=%d ***", 1217 pMlmPurgeStaInd->aid); 1218 if (LIM_IS_STA_ROLE(pe_session)) { 1219 pe_session->limSmeState = eLIM_SME_IDLE_STATE; 1220 MTRACE(mac_trace 1221 (mac, TRACE_CODE_SME_STATE, 1222 pe_session->peSessionId, 1223 pe_session->limSmeState)); 1224 1225 } 1226 if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) { 1227 lim_send_sme_deauth_ntf(mac, 1228 pMlmPurgeStaInd->peerMacAddr, 1229 resultCode, 1230 pMlmPurgeStaInd->purgeTrigger, 1231 pMlmPurgeStaInd->aid, 1232 pe_session->smeSessionId); 1233 } else 1234 lim_send_sme_disassoc_ntf(mac, 1235 pMlmPurgeStaInd->peerMacAddr, 1236 resultCode, 1237 pMlmPurgeStaInd->purgeTrigger, 1238 pMlmPurgeStaInd->aid, 1239 pe_session->smeSessionId, 1240 pe_session); 1241 } /* end switch (GET_LIM_SYSTEM_ROLE(pe_session)) */ 1242 } /*** end lim_process_mlm_purge_sta_ind() ***/ 1243 1244 /** 1245 * lim_process_mlm_set_keys_cnf() 1246 * 1247 ***FUNCTION: 1248 * This function is called to processes MLM_SETKEYS_CNF 1249 * message from MLM State machine. 1250 * 1251 ***LOGIC: 1252 * 1253 ***ASSUMPTIONS: 1254 * 1255 ***NOTE: 1256 * 1257 * @param mac Pointer to Global MAC structure 1258 * @param msg_buf A pointer to the MLM message buffer 1259 * 1260 * @return None 1261 */ lim_process_mlm_set_keys_cnf(struct mac_context * mac,uint32_t * msg_buf)1262 void lim_process_mlm_set_keys_cnf(struct mac_context *mac, uint32_t *msg_buf) 1263 { 1264 /* Prepare and send SME_SETCONTEXT_RSP message */ 1265 tLimMlmSetKeysCnf *pMlmSetKeysCnf; 1266 struct pe_session *pe_session; 1267 uint16_t aid; 1268 tpDphHashNode sta_ds = NULL; 1269 1270 if (!msg_buf) { 1271 pe_err("Buffer is Pointing to NULL"); 1272 return; 1273 } 1274 pMlmSetKeysCnf = (tLimMlmSetKeysCnf *)msg_buf; 1275 pe_session = pe_find_session_by_session_id(mac, 1276 pMlmSetKeysCnf->sessionId); 1277 if (!pe_session) { 1278 pe_err("session does not exist for given sessionId %d", 1279 pMlmSetKeysCnf->sessionId); 1280 return; 1281 } 1282 /* if the status is success keys are installed in the 1283 * Firmware so we can set the protection bit 1284 */ 1285 if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) { 1286 sta_ds = dph_lookup_hash_entry(mac, 1287 pMlmSetKeysCnf->peer_macaddr.bytes, 1288 &aid, &pe_session->dph.dphHashTable); 1289 if (sta_ds && pMlmSetKeysCnf->key_len_nonzero) 1290 sta_ds->is_key_installed = 1; 1291 } 1292 pe_debug("vdev %d: " QDF_MAC_ADDR_FMT " Status %d key_len_nonzero %d key installed %d", 1293 pe_session->vdev_id, 1294 QDF_MAC_ADDR_REF(pMlmSetKeysCnf->peer_macaddr.bytes), 1295 pMlmSetKeysCnf->resultCode, 1296 pMlmSetKeysCnf->key_len_nonzero, 1297 sta_ds ? sta_ds->is_key_installed : 0); 1298 1299 lim_send_sme_set_context_rsp(mac, 1300 pMlmSetKeysCnf->peer_macaddr, 1301 1, 1302 (tSirResultCodes) pMlmSetKeysCnf->resultCode, 1303 pe_session, pe_session->smeSessionId); 1304 1305 wlan_mlme_update_bw_no_punct(mac->psoc, pe_session->vdev_id); 1306 } /*** end lim_process_mlm_set_keys_cnf() ***/ 1307 lim_update_lost_link_rssi(struct mac_context * mac,uint32_t rssi)1308 void lim_update_lost_link_rssi(struct mac_context *mac, uint32_t rssi) 1309 { 1310 if (!mac) { 1311 pe_debug("mac is null"); 1312 return; 1313 } 1314 1315 mac->lim.bss_rssi = rssi; 1316 } 1317 lim_join_result_callback(struct mac_context * mac,uint8_t vdev_id)1318 void lim_join_result_callback(struct mac_context *mac, 1319 uint8_t vdev_id) 1320 { 1321 struct pe_session *session; 1322 1323 session = pe_find_session_by_vdev_id(mac, vdev_id); 1324 if (!session) { 1325 return; 1326 } 1327 lim_send_sme_join_reassoc_rsp(mac, eWNI_SME_JOIN_RSP, 1328 session->result_code, 1329 session->prot_status_code, 1330 session, vdev_id); 1331 pe_delete_session(mac, session); 1332 } 1333 lim_sta_handle_connect_fail(join_params * param)1334 QDF_STATUS lim_sta_handle_connect_fail(join_params *param) 1335 { 1336 struct pe_session *session; 1337 struct mac_context *mac_ctx; 1338 tpDphHashNode sta_ds = NULL; 1339 QDF_STATUS status; 1340 1341 if (!param) { 1342 pe_err("param is NULL"); 1343 return QDF_STATUS_E_INVAL; 1344 } 1345 1346 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 1347 if (!mac_ctx) 1348 return QDF_STATUS_E_INVAL; 1349 1350 session = pe_find_session_by_session_id(mac_ctx, param->pe_session_id); 1351 if (!session) { 1352 pe_err("session is NULL"); 1353 return QDF_STATUS_E_INVAL; 1354 } 1355 1356 sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 1357 &session->dph.dphHashTable); 1358 if (sta_ds) { 1359 sta_ds->mlmStaContext.disassocReason = 1360 REASON_UNSPEC_FAILURE; 1361 sta_ds->mlmStaContext.cleanupTrigger = 1362 eLIM_JOIN_FAILURE; 1363 sta_ds->mlmStaContext.resultCode = param->result_code; 1364 sta_ds->mlmStaContext.protStatusCode = param->prot_status_code; 1365 /* 1366 * FIX_ME: at the end of lim_cleanup_rx_path, 1367 * make sure PE is sending eWNI_SME_JOIN_RSP 1368 * to SME 1369 */ 1370 lim_mlo_notify_peer_disconn(session, sta_ds); 1371 lim_cleanup_rx_path(mac_ctx, sta_ds, session, true); 1372 qdf_mem_free(session->lim_join_req); 1373 session->lim_join_req = NULL; 1374 /* Cleanup if add bss failed */ 1375 if (session->add_bss_failed) { 1376 dph_delete_hash_entry(mac_ctx, 1377 sta_ds->staAddr, sta_ds->assocId, 1378 &session->dph.dphHashTable); 1379 goto error; 1380 } 1381 return QDF_STATUS_SUCCESS; 1382 } else { 1383 lim_mlo_sta_notify_peer_disconn(session); 1384 } 1385 qdf_mem_free(session->lim_join_req); 1386 session->lim_join_req = NULL; 1387 1388 error: 1389 session->prot_status_code = param->prot_status_code; 1390 session->result_code = param->result_code; 1391 1392 status = wma_send_vdev_stop(session->smeSessionId); 1393 if (QDF_IS_STATUS_ERROR(status)) 1394 lim_join_result_callback(mac_ctx, session->smeSessionId); 1395 1396 return status; 1397 } 1398 1399 /** 1400 * lim_handle_sme_join_result() - Handles sme join result 1401 * @mac_ctx: Pointer to Global MAC structure 1402 * @result_code: Failure code to be sent 1403 * @prot_status_code : Protocol status code 1404 * @session_entry: PE session handle 1405 * 1406 * This function is called to process join/auth/assoc failures 1407 * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or 1408 * MLM_ASSOC_CNF with a success code in case of STA role and 1409 * MLM_JOIN_CNF with success in case of STA in IBSS role. 1410 * 1411 * Return: None 1412 */ lim_handle_sme_join_result(struct mac_context * mac_ctx,tSirResultCodes result_code,uint16_t prot_status_code,struct pe_session * session)1413 void lim_handle_sme_join_result(struct mac_context *mac_ctx, 1414 tSirResultCodes result_code, uint16_t prot_status_code, 1415 struct pe_session *session) 1416 { 1417 join_params param; 1418 QDF_STATUS status; 1419 1420 if (!session) { 1421 pe_err("session is NULL"); 1422 return; 1423 } 1424 1425 if (result_code == eSIR_SME_SUCCESS) { 1426 if (wlan_vdev_mlme_is_mlo_vdev(session->vdev)) 1427 lim_update_connected_links(session); 1428 wlan_vdev_mlme_sm_deliver_evt(session->vdev, 1429 WLAN_VDEV_SM_EV_START_SUCCESS, 1430 0, NULL); 1431 return lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, 1432 result_code, 1433 prot_status_code, session, 1434 session->smeSessionId); 1435 } 1436 1437 param.result_code = result_code; 1438 param.prot_status_code = prot_status_code; 1439 param.pe_session_id = session->peSessionId; 1440 1441 mlme_set_connection_fail(session->vdev, true); 1442 if (wlan_vdev_mlme_get_substate(session->vdev) == 1443 WLAN_VDEV_SS_START_START_PROGRESS) { 1444 mlme_set_vdev_start_failed(session->vdev, true); 1445 status = wlan_vdev_mlme_sm_deliver_evt(session->vdev, 1446 WLAN_VDEV_SM_EV_START_REQ_FAIL, 1447 sizeof(param), ¶m); 1448 } 1449 else 1450 status = wlan_vdev_mlme_sm_deliver_evt(session->vdev, 1451 WLAN_VDEV_SM_EV_CONNECTION_FAIL, 1452 sizeof(param), ¶m); 1453 1454 return; 1455 } 1456 1457 1458 /** 1459 * lim_process_mlm_add_sta_rsp() 1460 * 1461 ***FUNCTION: 1462 * This function is called to process a WMA_ADD_STA_RSP from HAL. 1463 * Upon receipt of this message from HAL, MLME - 1464 * > Determines the "state" in which this message was received 1465 * > Forwards it to the appropriate callback 1466 * 1467 ***ASSUMPTIONS: 1468 * 1469 ***NOTE: 1470 * 1471 * @param mac Pointer to Global MAC structure 1472 * @param struct scheduler_msg The MsgQ header, which contains the 1473 * response buffer 1474 * 1475 * @return None 1476 */ lim_process_mlm_add_sta_rsp(struct mac_context * mac,struct scheduler_msg * limMsgQ,struct pe_session * pe_session)1477 void lim_process_mlm_add_sta_rsp(struct mac_context *mac, 1478 struct scheduler_msg *limMsgQ, 1479 struct pe_session *pe_session) 1480 { 1481 /* we need to process the deferred message since the initiating req. there might be nested request. */ 1482 /* in the case of nested request the new request initiated from the response will take care of resetting */ 1483 /* the deferred flag. */ 1484 SET_LIM_PROCESS_DEFD_MESGS(mac, true); 1485 if (LIM_IS_AP_ROLE(pe_session)) { 1486 lim_process_ap_mlm_add_sta_rsp(mac, limMsgQ, pe_session); 1487 return; 1488 } 1489 lim_process_sta_mlm_add_sta_rsp(mac, limMsgQ, pe_session); 1490 } 1491 1492 #ifdef WLAN_FEATURE_11BE_MLO 1493 static void lim_process_add_sta_rsp_mlo(struct mac_context * mac_ctx,tLimMlmAssocCnf * mlm_assoc_cnf,struct pe_session * session_entry)1494 lim_process_add_sta_rsp_mlo(struct mac_context *mac_ctx, 1495 tLimMlmAssocCnf *mlm_assoc_cnf, 1496 struct pe_session *session_entry) 1497 { 1498 if (wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) { 1499 pe_err("sending assoc cnf for MLO link vdev"); 1500 mlm_assoc_cnf->resultCode = eSIR_SME_SUCCESS; 1501 mlm_assoc_cnf->sessionId = session_entry->peSessionId; 1502 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 1503 (uint32_t *)mlm_assoc_cnf); 1504 } 1505 } 1506 #else /* WLAN_FEATURE_11BE_MLO */ 1507 static inline void lim_process_add_sta_rsp_mlo(struct mac_context * mac_ctx,tLimMlmAssocCnf * mlm_assoc_cnf,struct pe_session * session_entry)1508 lim_process_add_sta_rsp_mlo(struct mac_context *mac_ctx, 1509 tLimMlmAssocCnf *mlm_assoc_cnf, 1510 struct pe_session *session_entry) 1511 { 1512 } 1513 #endif /* WLAN_FEATURE_11BE_MLO */ 1514 1515 /** 1516 * lim_process_sta_mlm_add_sta_rsp () - Process add sta response 1517 * @mac_ctx: Pointer to mac context 1518 * @msg: struct scheduler_msg *an Message structure 1519 * @session_entry: PE session entry 1520 * 1521 * Process ADD STA response sent from WMA and posts results 1522 * to SME. 1523 * 1524 * Return: Null 1525 */ 1526 lim_process_sta_mlm_add_sta_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg,struct pe_session * session_entry)1527 void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx, 1528 struct scheduler_msg *msg, struct pe_session *session_entry) 1529 { 1530 tLimMlmAssocCnf mlm_assoc_cnf; 1531 tpDphHashNode sta_ds; 1532 uint32_t msg_type = LIM_MLM_ASSOC_CNF; 1533 tpAddStaParams add_sta_params = (tpAddStaParams) msg->bodyptr; 1534 1535 if (!add_sta_params) { 1536 pe_err("Encountered NULL Pointer"); 1537 return; 1538 } 1539 1540 if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) 1541 msg_type = LIM_MLM_REASSOC_CNF; 1542 1543 if (true == session_entry->fDeauthReceived) { 1544 pe_err("Received Deauth frame in ADD_STA_RESP state"); 1545 if (QDF_STATUS_SUCCESS == add_sta_params->status) { 1546 pe_err("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA limMlmState: %d bssid "QDF_MAC_ADDR_FMT, 1547 session_entry->limMlmState, 1548 QDF_MAC_ADDR_REF(add_sta_params->staMac)); 1549 1550 if (session_entry->limSmeState == 1551 eLIM_SME_WT_REASSOC_STATE) 1552 msg_type = LIM_MLM_REASSOC_CNF; 1553 /* 1554 * We are sending result code 1555 * eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA which 1556 * will trigger proper cleanup (DEL_STA/DEL_BSS both 1557 * required) in either assoc cnf or reassoc cnf handler. 1558 */ 1559 mlm_assoc_cnf.resultCode = 1560 eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA; 1561 mlm_assoc_cnf.protStatusCode = 1562 STATUS_UNSPECIFIED_FAILURE; 1563 goto end; 1564 } 1565 } 1566 1567 if (QDF_STATUS_SUCCESS == add_sta_params->status) { 1568 if (eLIM_MLM_WT_ADD_STA_RSP_STATE != 1569 session_entry->limMlmState) { 1570 pe_err("Received WMA_ADD_STA_RSP in state %X", 1571 session_entry->limMlmState); 1572 mlm_assoc_cnf.resultCode = 1573 (tSirResultCodes) eSIR_SME_REFUSED; 1574 goto end; 1575 } 1576 /* 1577 * Update the DPH Hash Entry for this STA 1578 * with proper state info 1579 */ 1580 sta_ds = 1581 dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 1582 &session_entry->dph.dphHashTable); 1583 if (sta_ds) { 1584 sta_ds->mlmStaContext.mlmState = 1585 eLIM_MLM_LINK_ESTABLISHED_STATE; 1586 sta_ds->nss = add_sta_params->nss; 1587 } else 1588 pe_warn("Fail to get DPH Hash Entry for AID - %d", 1589 DPH_STA_HASH_INDEX_PEER); 1590 session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; 1591 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1592 session_entry->peSessionId, 1593 session_entry->limMlmState)); 1594 lim_process_add_sta_rsp_mlo(mac_ctx, &mlm_assoc_cnf, 1595 session_entry); 1596 1597 #ifdef FEATURE_WLAN_TDLS 1598 /* initialize TDLS peer related data */ 1599 lim_init_tdls_data(mac_ctx, session_entry); 1600 #endif 1601 /* 1602 * Return Assoc confirm to SME with success 1603 * FIXME - Need the correct ASSOC RSP code to 1604 * be passed in here 1605 */ 1606 mlm_assoc_cnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS; 1607 lim_send_obss_color_collision_cfg(mac_ctx, session_entry, 1608 OBSS_COLOR_COLLISION_DETECTION); 1609 if (lim_is_session_he_capable(session_entry) && sta_ds) { 1610 if (mac_ctx->usr_cfg_mu_edca_params) { 1611 pe_debug("Send user cfg MU EDCA params to FW"); 1612 lim_send_edca_params(mac_ctx, 1613 mac_ctx->usr_mu_edca_params, 1614 session_entry->vdev_id, true); 1615 } else if (session_entry->mu_edca_present) { 1616 pe_debug("Send MU EDCA params to FW"); 1617 lim_send_edca_params(mac_ctx, 1618 session_entry->ap_mu_edca_params, 1619 session_entry->vdev_id, true); 1620 } 1621 } 1622 } else { 1623 pe_err("ADD_STA failed!"); 1624 if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) 1625 mlm_assoc_cnf.resultCode = 1626 (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE; 1627 else 1628 mlm_assoc_cnf.resultCode = 1629 (tSirResultCodes) eSIR_SME_REFUSED; 1630 mlm_assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 1631 } 1632 end: 1633 if (msg->bodyptr) { 1634 qdf_mem_free(add_sta_params); 1635 msg->bodyptr = NULL; 1636 } 1637 /* Updating PE session Id */ 1638 mlm_assoc_cnf.sessionId = session_entry->peSessionId; 1639 lim_post_sme_message(mac_ctx, msg_type, (uint32_t *) &mlm_assoc_cnf); 1640 if (true == session_entry->fDeauthReceived) 1641 session_entry->fDeauthReceived = false; 1642 return; 1643 } 1644 lim_process_mlm_del_bss_rsp(struct mac_context * mac,struct del_bss_resp * vdev_stop_rsp,struct pe_session * pe_session)1645 void lim_process_mlm_del_bss_rsp(struct mac_context *mac, 1646 struct del_bss_resp *vdev_stop_rsp, 1647 struct pe_session *pe_session) 1648 { 1649 /* we need to process the deferred message since the initiating req. there might be nested request. */ 1650 /* in the case of nested request the new request initiated from the response will take care of resetting */ 1651 /* the deferred flag. */ 1652 SET_LIM_PROCESS_DEFD_MESGS(mac, true); 1653 mac->sys.gSysFrameCount[SIR_MAC_MGMT_FRAME][SIR_MAC_MGMT_DEAUTH] = 0; 1654 1655 if (LIM_IS_AP_ROLE(pe_session) && 1656 (pe_session->statypeForBss == STA_ENTRY_SELF)) { 1657 lim_process_ap_mlm_del_bss_rsp(mac, vdev_stop_rsp, pe_session); 1658 return; 1659 } 1660 lim_process_sta_mlm_del_bss_rsp(mac, vdev_stop_rsp, pe_session); 1661 1662 if (pe_session->limRmfEnabled) { 1663 if (QDF_STATUS_SUCCESS != 1664 lim_send_exclude_unencrypt_ind(mac, true, pe_session)) { 1665 pe_err("Could not send down Exclude Unencrypted Indication!"); 1666 } 1667 } 1668 } 1669 lim_process_sta_mlm_del_bss_rsp(struct mac_context * mac,struct del_bss_resp * vdev_stop_rsp,struct pe_session * pe_session)1670 void lim_process_sta_mlm_del_bss_rsp(struct mac_context *mac, 1671 struct del_bss_resp *vdev_stop_rsp, 1672 struct pe_session *pe_session) 1673 { 1674 tpDphHashNode sta = 1675 dph_get_hash_entry(mac, DPH_STA_HASH_INDEX_PEER, 1676 &pe_session->dph.dphHashTable); 1677 tSirResultCodes status_code = eSIR_SME_SUCCESS; 1678 1679 if (!vdev_stop_rsp) { 1680 pe_err("Invalid body pointer in message"); 1681 goto end; 1682 } 1683 if (vdev_stop_rsp->status == QDF_STATUS_SUCCESS) { 1684 if (!sta) { 1685 pe_err("DPH Entry for STA 1 missing"); 1686 status_code = eSIR_SME_REFUSED; 1687 goto end; 1688 } 1689 if (eLIM_MLM_WT_DEL_BSS_RSP_STATE != 1690 sta->mlmStaContext.mlmState) { 1691 pe_err("Received unexpected WMA_DEL_BSS_RSP in state %X", 1692 sta->mlmStaContext.mlmState); 1693 status_code = eSIR_SME_REFUSED; 1694 goto end; 1695 } 1696 pe_debug("STA AssocID %d MAC "QDF_MAC_ADDR_FMT, sta->assocId, 1697 QDF_MAC_ADDR_REF(sta->staAddr)); 1698 } else { 1699 pe_err("DEL BSS failed!"); 1700 status_code = eSIR_SME_STOP_BSS_FAILURE; 1701 } 1702 end: 1703 if (!sta) 1704 return; 1705 if ((LIM_IS_STA_ROLE(pe_session)) && 1706 (pe_session->limSmeState != 1707 eLIM_SME_WT_DISASSOC_STATE && 1708 pe_session->limSmeState != 1709 eLIM_SME_WT_DEAUTH_STATE) && 1710 sta->mlmStaContext.cleanupTrigger != 1711 eLIM_JOIN_FAILURE) { 1712 /** The Case where the DelBss is invoked from 1713 * context of other than normal DisAssoc / Deauth OR 1714 * as part of Join Failure. 1715 */ 1716 lim_handle_del_bss_in_re_assoc_context(mac, sta, pe_session); 1717 return; 1718 } 1719 lim_prepare_and_send_del_sta_cnf(mac, sta, status_code, pe_session); 1720 return; 1721 } 1722 lim_process_ap_mlm_del_bss_rsp(struct mac_context * mac,struct del_bss_resp * vdev_stop_rsp,struct pe_session * pe_session)1723 void lim_process_ap_mlm_del_bss_rsp(struct mac_context *mac, 1724 struct del_bss_resp *vdev_stop_rsp, 1725 struct pe_session *pe_session) 1726 { 1727 tSirResultCodes rc = eSIR_SME_SUCCESS; 1728 1729 if (!pe_session) { 1730 pe_err("Session entry passed is NULL"); 1731 if (vdev_stop_rsp) 1732 qdf_mem_free(vdev_stop_rsp); 1733 return; 1734 } 1735 1736 if (!vdev_stop_rsp) { 1737 pe_err("BSS: DEL_BSS_RSP with no body!"); 1738 rc = eSIR_SME_REFUSED; 1739 goto end; 1740 } 1741 mac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE; 1742 MTRACE(mac_trace 1743 (mac, TRACE_CODE_MLM_STATE, NO_SESSION, 1744 mac->lim.gLimMlmState)); 1745 1746 if (eLIM_MLM_WT_DEL_BSS_RSP_STATE != pe_session->limMlmState) { 1747 pe_err("Received unexpected WMA_DEL_BSS_RSP in state %X", 1748 pe_session->limMlmState); 1749 rc = eSIR_SME_REFUSED; 1750 goto end; 1751 } 1752 if (vdev_stop_rsp->status != QDF_STATUS_SUCCESS) { 1753 pe_err("BSS: DEL_BSS_RSP error (%x)", vdev_stop_rsp->status); 1754 rc = eSIR_SME_STOP_BSS_FAILURE; 1755 goto end; 1756 } 1757 /** Softmac may send all the buffered packets right after resuming the transmission hence 1758 * to occupy the medium during non channel occupancy period. So resume the transmission after 1759 * HAL gives back the response. 1760 */ 1761 dph_hash_table_init(mac, &pe_session->dph.dphHashTable); 1762 lim_delete_pre_auth_list(mac); 1763 /* Initialize number of associated stations during cleanup */ 1764 pe_session->gLimNumOfCurrentSTAs = 0; 1765 end: 1766 lim_send_stop_bss_response(mac, pe_session->vdev_id, rc); 1767 pe_delete_session(mac, pe_session); 1768 } 1769 1770 /** 1771 * lim_process_mlm_del_all_sta_rsp() - Process DEL STA response 1772 * @mac_ctx: Pointer to Global MAC structure 1773 * @msg: The MsgQ header, which contains the response buffer 1774 * 1775 * This function is called to process a WMA_DEL_ALL_STA_RSP from 1776 * WMA Upon receipt of this message from FW. 1777 * 1778 * Return: QDF_STATUS 1779 */ 1780 QDF_STATUS lim_process_mlm_del_all_sta_rsp(struct vdev_mlme_obj * vdev_mlme,struct peer_delete_all_response * rsp)1781 lim_process_mlm_del_all_sta_rsp(struct vdev_mlme_obj *vdev_mlme, 1782 struct peer_delete_all_response *rsp) 1783 { 1784 struct pe_session *session_entry; 1785 tSirResultCodes status_code = eSIR_SME_SUCCESS; 1786 struct mac_context *mac_ctx; 1787 struct wlan_objmgr_vdev *vdev; 1788 uint8_t vdev_id; 1789 1790 vdev = vdev_mlme->vdev; 1791 vdev_id = wlan_vdev_get_id(vdev); 1792 1793 mac_ctx = cds_get_context(QDF_MODULE_ID_PE); 1794 if (!mac_ctx) 1795 return QDF_STATUS_E_INVAL; 1796 1797 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); 1798 1799 session_entry = pe_find_session_by_vdev_id(mac_ctx, 1800 vdev_id); 1801 if (!session_entry) { 1802 pe_err("Session Doesn't exist: %d", vdev_id); 1803 return QDF_STATUS_E_INVAL; 1804 } 1805 1806 lim_prepare_and_send_del_all_sta_cnf(mac_ctx, status_code, 1807 session_entry); 1808 return QDF_STATUS_SUCCESS; 1809 } 1810 1811 /** 1812 * lim_process_mlm_del_sta_rsp() - Process DEL STA response 1813 * @mac_ctx: Pointer to Global MAC structure 1814 * @msg: The MsgQ header, which contains the response buffer 1815 * 1816 * This function is called to process a WMA_DEL_STA_RSP from 1817 * WMA Upon receipt of this message from FW. 1818 * 1819 * Return: None 1820 */ lim_process_mlm_del_sta_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg)1821 void lim_process_mlm_del_sta_rsp(struct mac_context *mac_ctx, 1822 struct scheduler_msg *msg) 1823 { 1824 /* 1825 * we need to process the deferred message since the 1826 * initiating req. there might be nested request 1827 * in the case of nested request the new request 1828 * initiated from the response will take care of resetting 1829 * the deferred flag. 1830 */ 1831 struct pe_session *session_entry; 1832 tpDeleteStaParams del_sta_params; 1833 1834 del_sta_params = (tpDeleteStaParams) msg->bodyptr; 1835 if (!del_sta_params) { 1836 pe_err("null pointer del_sta_params msg"); 1837 return; 1838 } 1839 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); 1840 1841 session_entry = pe_find_session_by_session_id(mac_ctx, 1842 del_sta_params->sessionId); 1843 if (!session_entry) { 1844 pe_err("Session Doesn't exist: %d", 1845 del_sta_params->sessionId); 1846 qdf_mem_free(del_sta_params); 1847 msg->bodyptr = NULL; 1848 return; 1849 } 1850 1851 if (LIM_IS_AP_ROLE(session_entry)) { 1852 lim_process_ap_mlm_del_sta_rsp(mac_ctx, msg, 1853 session_entry); 1854 return; 1855 } 1856 if (LIM_IS_NDI_ROLE(session_entry)) { 1857 lim_process_ndi_del_sta_rsp(mac_ctx, msg, session_entry); 1858 return; 1859 } 1860 lim_process_sta_mlm_del_sta_rsp(mac_ctx, msg, session_entry); 1861 } 1862 1863 /** 1864 * lim_process_ap_mlm_del_sta_rsp() - Process WMA_DEL_STA_RSP 1865 * @mac_ctx: Global pointer to MAC context 1866 * @msg: Received message 1867 * @session_entry: Session entry 1868 * 1869 * Process WMA_DEL_STA_RSP for AP role 1870 * 1871 * Retunrn: None 1872 */ lim_process_ap_mlm_del_sta_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg,struct pe_session * session_entry)1873 void lim_process_ap_mlm_del_sta_rsp(struct mac_context *mac_ctx, 1874 struct scheduler_msg *msg, 1875 struct pe_session *session_entry) 1876 { 1877 tpDeleteStaParams del_sta_params = (tpDeleteStaParams) msg->bodyptr; 1878 tpDphHashNode sta_ds; 1879 tSirResultCodes status_code = eSIR_SME_SUCCESS; 1880 1881 if (!msg->bodyptr) { 1882 pe_err("msg->bodyptr NULL"); 1883 return; 1884 } 1885 1886 sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId, 1887 &session_entry->dph.dphHashTable); 1888 if (!sta_ds) { 1889 pe_err("DPH Entry for STA %X missing", 1890 del_sta_params->assocId); 1891 status_code = eSIR_SME_REFUSED; 1892 qdf_mem_free(del_sta_params); 1893 msg->bodyptr = NULL; 1894 return; 1895 } 1896 pe_debug("Received del Sta Rsp in StaD MlmState: %d", 1897 sta_ds->mlmStaContext.mlmState); 1898 if (QDF_STATUS_SUCCESS != del_sta_params->status) { 1899 pe_warn("DEL STA failed!"); 1900 status_code = eSIR_SME_REFUSED; 1901 goto end; 1902 } 1903 1904 pe_debug("AP received the DEL_STA_RSP for assocID: %X sta mac " 1905 QDF_MAC_ADDR_FMT, del_sta_params->assocId, 1906 QDF_MAC_ADDR_REF(sta_ds->staAddr)); 1907 if ((eLIM_MLM_WT_DEL_STA_RSP_STATE != sta_ds->mlmStaContext.mlmState) && 1908 (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != 1909 sta_ds->mlmStaContext.mlmState)) { 1910 pe_err("Received unexpected WMA_DEL_STA_RSP in state %s for assocId %d", 1911 lim_mlm_state_str(sta_ds->mlmStaContext.mlmState), 1912 sta_ds->assocId); 1913 status_code = eSIR_SME_REFUSED; 1914 goto end; 1915 } 1916 1917 pe_debug("Deleted STA AssocID %d Addr "QDF_MAC_ADDR_FMT, 1918 sta_ds->assocId, QDF_MAC_ADDR_REF(sta_ds->staAddr)); 1919 if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE == 1920 sta_ds->mlmStaContext.mlmState) { 1921 qdf_mem_free(del_sta_params); 1922 msg->bodyptr = NULL; 1923 if (lim_add_sta(mac_ctx, sta_ds, false, session_entry) != 1924 QDF_STATUS_SUCCESS) { 1925 pe_err("could not Add STA with assocId: %d", 1926 sta_ds->assocId); 1927 /* 1928 * delete the TS if it has already been added. 1929 * send the response with error status. 1930 */ 1931 if (sta_ds->qos.addtsPresent) { 1932 tpLimTspecInfo pTspecInfo; 1933 1934 if (QDF_STATUS_SUCCESS == 1935 lim_tspec_find_by_assoc_id(mac_ctx, 1936 sta_ds->assocId, 1937 &sta_ds->qos.addts.tspec, 1938 &mac_ctx->lim.tspecInfo[0], 1939 &pTspecInfo)) { 1940 lim_admit_control_delete_ts(mac_ctx, 1941 sta_ds->assocId, 1942 &sta_ds->qos.addts.tspec.tsinfo, 1943 NULL, 1944 &pTspecInfo->idx); 1945 } 1946 } 1947 lim_reject_association(mac_ctx, sta_ds->staAddr, 1948 sta_ds->mlmStaContext.subType, true, 1949 sta_ds->mlmStaContext.authType, sta_ds->assocId, 1950 true, 1951 STATUS_UNSPECIFIED_FAILURE, 1952 session_entry); 1953 } 1954 return; 1955 } 1956 end: 1957 qdf_mem_free(del_sta_params); 1958 msg->bodyptr = NULL; 1959 if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != 1960 sta_ds->mlmStaContext.mlmState) { 1961 lim_prepare_and_send_del_sta_cnf(mac_ctx, sta_ds, status_code, 1962 session_entry); 1963 } 1964 return; 1965 } 1966 lim_process_sta_mlm_del_sta_rsp(struct mac_context * mac,struct scheduler_msg * limMsgQ,struct pe_session * pe_session)1967 void lim_process_sta_mlm_del_sta_rsp(struct mac_context *mac, 1968 struct scheduler_msg *limMsgQ, 1969 struct pe_session *pe_session) 1970 { 1971 tSirResultCodes status_code = eSIR_SME_SUCCESS; 1972 tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr; 1973 1974 if (!pDelStaParams) { 1975 pe_err("Encountered NULL Pointer"); 1976 goto end; 1977 } 1978 pe_debug("Del STA RSP received. Status: %d AssocID: %d", 1979 pDelStaParams->status, pDelStaParams->assocId); 1980 1981 #ifdef FEATURE_WLAN_TDLS 1982 if (pDelStaParams->staType == STA_ENTRY_TDLS_PEER) { 1983 pe_debug("TDLS Del STA RSP received"); 1984 lim_process_tdls_del_sta_rsp(mac, limMsgQ, pe_session); 1985 return; 1986 } 1987 #endif 1988 if (QDF_STATUS_SUCCESS != pDelStaParams->status) 1989 pe_err("Del STA failed! Status:%d, proceeding with Del BSS", 1990 pDelStaParams->status); 1991 1992 if (eLIM_MLM_WT_DEL_STA_RSP_STATE != pe_session->limMlmState) { 1993 pe_err("Received unexpected WDA_DELETE_STA_RSP in state %s", 1994 lim_mlm_state_str(pe_session->limMlmState)); 1995 status_code = eSIR_SME_REFUSED; 1996 goto end; 1997 } 1998 /* 1999 * we must complete all cleanup related to delSta before 2000 * calling limDelBSS. 2001 */ 2002 if (0 != limMsgQ->bodyptr) { 2003 qdf_mem_free(pDelStaParams); 2004 limMsgQ->bodyptr = NULL; 2005 } 2006 2007 lim_disconnect_complete(pe_session, true); 2008 2009 return; 2010 end: 2011 if (0 != limMsgQ->bodyptr) { 2012 qdf_mem_free(pDelStaParams); 2013 limMsgQ->bodyptr = NULL; 2014 } 2015 return; 2016 } 2017 lim_process_ap_mlm_add_sta_rsp(struct mac_context * mac,struct scheduler_msg * limMsgQ,struct pe_session * pe_session)2018 void lim_process_ap_mlm_add_sta_rsp(struct mac_context *mac, 2019 struct scheduler_msg *limMsgQ, 2020 struct pe_session *pe_session) 2021 { 2022 tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr; 2023 tpDphHashNode sta = NULL; 2024 bool add_sta_rsp_status = true; 2025 2026 if (!pAddStaParams) { 2027 pe_err("Invalid body pointer in message"); 2028 add_sta_rsp_status = false; 2029 goto end; 2030 } 2031 2032 sta = 2033 dph_get_hash_entry(mac, pAddStaParams->assocId, 2034 &pe_session->dph.dphHashTable); 2035 if (!sta) { 2036 pe_err("DPH Entry for STA %X missing", pAddStaParams->assocId); 2037 add_sta_rsp_status = false; 2038 goto end; 2039 } 2040 2041 if (eLIM_MLM_WT_ADD_STA_RSP_STATE != sta->mlmStaContext.mlmState) { 2042 pe_err("Received unexpected WMA_ADD_STA_RSP in state %X", 2043 sta->mlmStaContext.mlmState); 2044 add_sta_rsp_status = false; 2045 goto end; 2046 } 2047 if (QDF_STATUS_SUCCESS != pAddStaParams->status) { 2048 pe_err("Error! rcvd delSta rsp from HAL with status %d", 2049 pAddStaParams->status); 2050 lim_reject_association(mac, sta->staAddr, 2051 sta->mlmStaContext.subType, 2052 true, sta->mlmStaContext.authType, 2053 sta->assocId, true, 2054 STATUS_UNSPECIFIED_FAILURE, 2055 pe_session); 2056 add_sta_rsp_status = false; 2057 goto end; 2058 } 2059 sta->nss = pAddStaParams->nss; 2060 /* if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state */ 2061 sta->valid = 1; 2062 sta->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE; 2063 pe_debug("AddStaRsp Success.STA AssocID %d sta mac" QDF_MAC_ADDR_FMT, 2064 sta->assocId, QDF_MAC_ADDR_REF(sta->staAddr)); 2065 2066 /* For BTAMP-AP, the flow sequence shall be: 2067 * 1) PE sends eWNI_SME_ASSOC_IND to SME 2068 * 2) PE receives eWNI_SME_ASSOC_CNF from SME 2069 * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA 2070 */ 2071 if (!lim_is_mlo_conn(pe_session, sta) && 2072 lim_send_mlm_assoc_ind(mac, sta, pe_session) != 2073 QDF_STATUS_SUCCESS) { 2074 lim_reject_association(mac, sta->staAddr, 2075 sta->mlmStaContext.subType, 2076 true, sta->mlmStaContext.authType, 2077 sta->assocId, true, 2078 STATUS_UNSPECIFIED_FAILURE, 2079 pe_session); 2080 add_sta_rsp_status = false; 2081 } 2082 /* fall though to reclaim the original Add STA Response message */ 2083 end: 2084 if (lim_is_mlo_conn(pe_session, sta)) 2085 lim_ap_mlo_sta_peer_ind(mac, pe_session, sta, 2086 add_sta_rsp_status); 2087 if (0 != limMsgQ->bodyptr) { 2088 qdf_mem_free(pAddStaParams); 2089 limMsgQ->bodyptr = NULL; 2090 } 2091 return; 2092 } 2093 lim_process_ap_mlm_add_bss_rsp(struct mac_context * mac,struct add_bss_rsp * add_bss_rsp)2094 static void lim_process_ap_mlm_add_bss_rsp(struct mac_context *mac, 2095 struct add_bss_rsp *add_bss_rsp) 2096 { 2097 tLimMlmStartCnf mlmStartCnf; 2098 struct pe_session *pe_session; 2099 uint8_t isWepEnabled = false; 2100 2101 if (!add_bss_rsp) { 2102 pe_err("Encountered NULL Pointer"); 2103 return; 2104 } 2105 /* TBD: free the memory before returning, do it for all places where lookup fails. */ 2106 pe_session = pe_find_session_by_vdev_id(mac, add_bss_rsp->vdev_id); 2107 if (!pe_session) { 2108 pe_err("session does not exist for vdev_id %d", 2109 add_bss_rsp->vdev_id); 2110 return; 2111 } 2112 /* Update PE session Id */ 2113 mlmStartCnf.sessionId = pe_session->peSessionId; 2114 if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { 2115 pe_debug("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS"); 2116 /* Set MLME state */ 2117 pe_session->limMlmState = eLIM_MLM_BSS_STARTED_STATE; 2118 pe_session->chainMask = add_bss_rsp->chain_mask; 2119 pe_session->smpsMode = add_bss_rsp->smps_mode; 2120 MTRACE(mac_trace 2121 (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId, 2122 pe_session->limMlmState)); 2123 pe_session->limSystemRole = eLIM_AP_ROLE; 2124 2125 sch_edca_profile_update(mac, pe_session); 2126 /* For dual AP case, delete pre auth node if any */ 2127 lim_delete_pre_auth_list(mac); 2128 /* Check the SAP security configuration.If configured to 2129 * WEP then max clients supported is 16 2130 */ 2131 if (pe_session->privacy) { 2132 if ((pe_session->gStartBssRSNIe.present) 2133 || (pe_session->gStartBssWPAIe.present)) 2134 pe_debug("WPA/WPA2 SAP configuration"); 2135 else { 2136 if (mac->mlme_cfg->sap_cfg.assoc_sta_limit > 2137 MAX_SUPPORTED_PEERS_WEP) { 2138 pe_debug("WEP SAP Configuration"); 2139 mac->mlme_cfg->sap_cfg.assoc_sta_limit 2140 = MAX_SUPPORTED_PEERS_WEP; 2141 isWepEnabled = true; 2142 } 2143 } 2144 } 2145 lim_init_peer_idxpool(mac, pe_session); 2146 2147 /* Start OLBC timer */ 2148 if (tx_timer_activate 2149 (&mac->lim.lim_timers.gLimUpdateOlbcCacheTimer) != 2150 TX_SUCCESS) { 2151 pe_err("tx_timer_activate failed"); 2152 } 2153 2154 /* Apply previously set configuration at HW */ 2155 lim_apply_configuration(mac, pe_session); 2156 2157 /* In lim_apply_configuration gLimAssocStaLimit is assigned from cfg. 2158 * So update the value to 16 in case SoftAP is configured in WEP. 2159 */ 2160 if ((mac->mlme_cfg->sap_cfg.assoc_sta_limit > 2161 MAX_SUPPORTED_PEERS_WEP) 2162 && (isWepEnabled)) 2163 mac->mlme_cfg->sap_cfg.assoc_sta_limit = 2164 MAX_SUPPORTED_PEERS_WEP; 2165 mlmStartCnf.resultCode = eSIR_SME_SUCCESS; 2166 } else { 2167 pe_err("WMA_ADD_BSS_REQ failed with status %d", 2168 add_bss_rsp->status); 2169 mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; 2170 } 2171 2172 lim_send_start_bss_confirm(mac, &mlmStartCnf); 2173 } 2174 2175 #ifdef WLAN_FEATURE_FILS_SK 2176 /* 2177 * lim_update_fils_auth_mode: API to update Auth mode in case of fils session 2178 * @session_entry: pe session entry 2179 * @auth_mode: auth mode needs to be updated 2180 * 2181 * Return: None 2182 */ lim_update_fils_auth_mode(struct pe_session * session_entry,tAniAuthType * auth_mode)2183 static void lim_update_fils_auth_mode(struct pe_session *session_entry, 2184 tAniAuthType *auth_mode) 2185 { 2186 if (!session_entry->fils_info) 2187 return; 2188 2189 if (session_entry->fils_info->is_fils_connection) 2190 *auth_mode = session_entry->fils_info->auth; 2191 } 2192 #else lim_update_fils_auth_mode(struct pe_session * session_entry,tAniAuthType * auth_mode)2193 static void lim_update_fils_auth_mode(struct pe_session *session_entry, 2194 tAniAuthType *auth_mode) 2195 { } 2196 #endif 2197 2198 #ifdef WLAN_FEATURE_11BE_MLO 2199 static bool lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq * pMlmAuthReq,struct pe_session * session_entry)2200 lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq *pMlmAuthReq, 2201 struct pe_session *session_entry) 2202 { 2203 if (wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) { 2204 qdf_mem_free(pMlmAuthReq); 2205 pe_err("vdev is an MLO link, skip Auth"); 2206 return true; 2207 } 2208 2209 return false; 2210 } 2211 #else /* WLAN_FEATURE_11BE_MLO */ 2212 static inline bool lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq * pMlmAuthReq,struct pe_session * session_entry)2213 lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq *pMlmAuthReq, 2214 struct pe_session *session_entry) 2215 { 2216 return false; 2217 } 2218 #endif /* WLAN_FEATURE_11BE_MLO */ 2219 lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context * mac_ctx,struct bss_params * add_bss_params,struct pe_session * session_entry,QDF_STATUS status)2220 void lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx, 2221 struct bss_params *add_bss_params, 2222 struct pe_session *session_entry, 2223 QDF_STATUS status) 2224 { 2225 tAniAuthType cfgAuthType, authMode; 2226 tLimMlmAuthReq *pMlmAuthReq; 2227 tpDphHashNode sta = NULL; 2228 2229 if (!add_bss_params) { 2230 pe_err("Invalid body pointer in message"); 2231 goto joinFailure; 2232 } 2233 if (QDF_IS_STATUS_SUCCESS(status)) { 2234 sta = dph_add_hash_entry(mac_ctx, 2235 add_bss_params->staContext.staMac, 2236 DPH_STA_HASH_INDEX_PEER, 2237 &session_entry->dph.dphHashTable); 2238 if (!sta) { 2239 /* Could not add hash table entry */ 2240 pe_err("could not add hash entry at DPH for STA: "QDF_MAC_ADDR_FMT, 2241 QDF_MAC_ADDR_REF( 2242 add_bss_params->staContext.staMac)); 2243 goto joinFailure; 2244 } 2245 /* Success, handle below */ 2246 /* Trigger Authentication with AP */ 2247 cfgAuthType = mac_ctx->mlme_cfg->wep_params.auth_type; 2248 2249 /* Try shared Authentication first */ 2250 if (cfgAuthType == eSIR_AUTO_SWITCH) 2251 authMode = eSIR_SHARED_KEY; 2252 else 2253 authMode = cfgAuthType; 2254 2255 lim_update_fils_auth_mode(session_entry, &authMode); 2256 /* Trigger MAC based Authentication */ 2257 pMlmAuthReq = qdf_mem_malloc(sizeof(tLimMlmAuthReq)); 2258 if (!pMlmAuthReq) { 2259 pe_err("Allocate Memory failed for mlmAuthReq"); 2260 return; 2261 } 2262 sir_copy_mac_addr(pMlmAuthReq->peerMacAddr, 2263 session_entry->bssId); 2264 2265 pMlmAuthReq->authType = authMode; 2266 session_entry->limMlmState = eLIM_MLM_JOINED_STATE; 2267 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2268 session_entry->peSessionId, eLIM_MLM_JOINED_STATE)); 2269 pMlmAuthReq->sessionId = session_entry->peSessionId; 2270 session_entry->limPrevSmeState = session_entry->limSmeState; 2271 session_entry->limSmeState = eLIM_SME_WT_AUTH_STATE; 2272 2273 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 2274 session_entry->peSessionId, 2275 session_entry->limSmeState)); 2276 2277 if (lim_process_mlo_sta_add_bss_skip_auth(pMlmAuthReq, 2278 session_entry)) 2279 return; 2280 lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ, 2281 (uint32_t *) pMlmAuthReq); 2282 return; 2283 } 2284 2285 joinFailure: 2286 { 2287 session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; 2288 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 2289 session_entry->peSessionId, 2290 session_entry->limSmeState)); 2291 2292 /* Send Join response to Host */ 2293 lim_handle_sme_join_result(mac_ctx, eSIR_SME_REFUSED, 2294 STATUS_UNSPECIFIED_FAILURE, session_entry); 2295 } 2296 2297 } 2298 lim_process_sta_mlm_add_bss_rsp(struct mac_context * mac_ctx,struct add_bss_rsp * add_bss_rsp,struct pe_session * session_entry)2299 static void lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx, 2300 struct add_bss_rsp *add_bss_rsp, 2301 struct pe_session *session_entry) 2302 { 2303 tLimMlmAssocCnf mlm_assoc_cnf; 2304 uint32_t msg_type = LIM_MLM_ASSOC_CNF; 2305 uint32_t sub_type = LIM_ASSOC; 2306 tpDphHashNode sta_ds = NULL; 2307 uint8_t update_sta = false; 2308 2309 mlm_assoc_cnf.resultCode = eSIR_SME_SUCCESS; 2310 if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == session_entry->limMlmState 2311 || (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == 2312 session_entry->limMlmState)) { 2313 msg_type = LIM_MLM_REASSOC_CNF; 2314 sub_type = LIM_REASSOC; 2315 /* 2316 * If Reassoc is happening for the same BSS, then 2317 * use the existing StaId and indicate to HAL to update 2318 * the existing STA entry. 2319 * If Reassoc is happening for the new BSS, then 2320 * old BSS and STA entry would have been already deleted 2321 * before PE tries to add BSS for the new BSS, so set the 2322 * updateSta to false and pass INVALID STA Index. 2323 */ 2324 if (sir_compare_mac_addr(session_entry->bssId, 2325 session_entry->limReAssocbssId)) { 2326 update_sta = true; 2327 } 2328 } 2329 2330 if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) { 2331 if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == 2332 session_entry->limMlmState) { 2333 pe_debug("Mlm=%d %d", session_entry->limMlmState, 2334 eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE); 2335 lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx, 2336 add_bss_rsp, 2337 session_entry); 2338 return; 2339 } 2340 2341 /* Set MLME state */ 2342 session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; 2343 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 2344 session_entry->peSessionId, 2345 session_entry->limMlmState)); 2346 /* to know the session started for self or for peer */ 2347 session_entry->statypeForBss = STA_ENTRY_PEER; 2348 sta_ds = 2349 dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 2350 &session_entry->dph.dphHashTable); 2351 if (!sta_ds) { 2352 pe_err("Session:%d Fail to add Self Entry for STA", 2353 session_entry->peSessionId); 2354 mlm_assoc_cnf.resultCode = 2355 (tSirResultCodes) eSIR_SME_REFUSED; 2356 } else { 2357 /* Success, handle below */ 2358 /* Downgrade the EDCA parameters if needed */ 2359 lim_set_active_edca_params(mac_ctx, 2360 session_entry->gLimEdcaParams, session_entry); 2361 lim_send_edca_params(mac_ctx, 2362 session_entry->gLimEdcaParamsActive, 2363 session_entry->vdev_id, false); 2364 if (lim_add_sta_self(mac_ctx, update_sta, 2365 session_entry) != QDF_STATUS_SUCCESS) { 2366 /* Add STA context at HW */ 2367 pe_err("Session:%d could not Add Self" 2368 "Entry for the station", 2369 session_entry->peSessionId); 2370 mlm_assoc_cnf.resultCode = 2371 (tSirResultCodes) eSIR_SME_REFUSED; 2372 } 2373 } 2374 } else { 2375 pe_err("SessionId: %d ADD_BSS failed!", 2376 session_entry->peSessionId); 2377 mlm_assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 2378 /* Return Assoc confirm to SME with failure */ 2379 if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == 2380 session_entry->limMlmState) 2381 mlm_assoc_cnf.resultCode = 2382 (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE; 2383 else 2384 mlm_assoc_cnf.resultCode = 2385 (tSirResultCodes) eSIR_SME_REFUSED; 2386 session_entry->add_bss_failed = true; 2387 } 2388 2389 if (mlm_assoc_cnf.resultCode != eSIR_SME_SUCCESS) { 2390 session_entry->limMlmState = eLIM_MLM_IDLE_STATE; 2391 /* Update PE session Id */ 2392 mlm_assoc_cnf.sessionId = session_entry->peSessionId; 2393 lim_post_sme_message(mac_ctx, msg_type, 2394 (uint32_t *) &mlm_assoc_cnf); 2395 } 2396 } 2397 lim_handle_add_bss_rsp(struct mac_context * mac_ctx,struct add_bss_rsp * add_bss_rsp)2398 void lim_handle_add_bss_rsp(struct mac_context *mac_ctx, 2399 struct add_bss_rsp *add_bss_rsp) 2400 { 2401 tLimMlmStartCnf mlm_start_cnf; 2402 struct pe_session *session_entry; 2403 enum bss_type bss_type; 2404 struct wlan_lmac_if_reg_tx_ops *tx_ops; 2405 struct vdev_mlme_obj *mlme_obj; 2406 struct pe_session *sta_session; 2407 2408 if (!add_bss_rsp) { 2409 pe_err("add_bss_rsp is NULL"); 2410 return; 2411 } 2412 2413 /* 2414 * we need to process the deferred message since the 2415 * initiating req.there might be nested request. 2416 * in the case of nested request the new request initiated 2417 * from the response will take care of resetting the deferred 2418 * flag. 2419 */ 2420 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); 2421 /* Validate SME/LIM/MLME state */ 2422 session_entry = pe_find_session_by_vdev_id(mac_ctx, 2423 add_bss_rsp->vdev_id); 2424 if (!session_entry) { 2425 pe_err("vdev id:%d Session Doesn't exist", 2426 add_bss_rsp->vdev_id); 2427 goto err; 2428 } 2429 if (LIM_IS_AP_ROLE(session_entry)) { 2430 if (wlan_reg_is_ext_tpc_supported(mac_ctx->psoc)) { 2431 mlme_obj = 2432 wlan_vdev_mlme_get_cmpt_obj(session_entry->vdev); 2433 if (!mlme_obj) { 2434 pe_err("vdev component object is NULL"); 2435 goto err; 2436 } 2437 tx_ops = wlan_reg_get_tx_ops(mac_ctx->psoc); 2438 2439 lim_calculate_tpc(mac_ctx, session_entry); 2440 2441 if (tx_ops->set_tpc_power) 2442 tx_ops->set_tpc_power(mac_ctx->psoc, 2443 session_entry->vdev_id, 2444 &mlme_obj->reg_tpc_obj); 2445 if (wlan_get_tpc_update_required_for_sta( 2446 session_entry->vdev)) { 2447 sta_session = 2448 lim_get_concurrent_session(mac_ctx, 2449 session_entry->vdev_id, 2450 session_entry->opmode); 2451 if (!sta_session) { 2452 pe_err("TPC update required is set, but concurrent session doesn't exist"); 2453 wlan_set_tpc_update_required_for_sta( 2454 session_entry->vdev, 2455 false); 2456 } else { 2457 lim_update_tx_power(mac_ctx, 2458 session_entry, sta_session, 2459 false); 2460 } 2461 } 2462 } 2463 } 2464 bss_type = session_entry->bssType; 2465 /* update PE session Id */ 2466 mlm_start_cnf.sessionId = session_entry->peSessionId; 2467 if (eSIR_NDI_MODE == session_entry->bssType) { 2468 lim_process_ndi_mlm_add_bss_rsp(mac_ctx, add_bss_rsp, 2469 session_entry); 2470 } else { 2471 if (eLIM_SME_WT_START_BSS_STATE == session_entry->limSmeState) { 2472 if (eLIM_MLM_WT_ADD_BSS_RSP_STATE != 2473 session_entry->limMlmState) { 2474 pe_err("SessionId:%d Received " 2475 " WMA_ADD_BSS_RSP in state %X", 2476 session_entry->peSessionId, 2477 session_entry->limMlmState); 2478 mlm_start_cnf.resultCode = 2479 eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; 2480 2481 lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf); 2482 } 2483 lim_process_ap_mlm_add_bss_rsp(mac_ctx, 2484 add_bss_rsp); 2485 } else { 2486 /* Called while processing assoc response */ 2487 lim_process_sta_mlm_add_bss_rsp(mac_ctx, add_bss_rsp, 2488 session_entry); 2489 } 2490 } 2491 2492 if (session_entry->limRmfEnabled) { 2493 if (QDF_STATUS_SUCCESS != 2494 lim_send_exclude_unencrypt_ind(mac_ctx, false, 2495 session_entry)) { 2496 pe_err("Failed to send Exclude Unencrypted Ind"); 2497 } 2498 } 2499 err: 2500 qdf_mem_free(add_bss_rsp); 2501 } 2502 lim_process_mlm_update_hidden_ssid_rsp(struct mac_context * mac_ctx,uint8_t vdev_id)2503 void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx, 2504 uint8_t vdev_id) 2505 { 2506 struct pe_session *session_entry; 2507 struct scheduler_msg message = {0}; 2508 QDF_STATUS status; 2509 2510 pe_debug("hidden ssid resp for vdev_id:%d ", vdev_id); 2511 2512 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 2513 if (!session_entry) { 2514 pe_err("vdev_id:%d Session Doesn't exist", 2515 vdev_id); 2516 return; 2517 } 2518 /* Update beacon */ 2519 sch_set_fixed_beacon_fields(mac_ctx, session_entry); 2520 lim_send_beacon(mac_ctx, session_entry); 2521 2522 message.type = eWNI_SME_HIDDEN_SSID_RESTART_RSP; 2523 message.bodyval = vdev_id; 2524 status = scheduler_post_message(QDF_MODULE_ID_PE, 2525 QDF_MODULE_ID_SME, 2526 QDF_MODULE_ID_SME, &message); 2527 2528 if (status != QDF_STATUS_SUCCESS) 2529 pe_err("Failed to post message %u", status); 2530 } 2531 2532 /** 2533 * lim_process_mlm_set_sta_key_rsp() - Process STA key response 2534 * 2535 * @mac_ctx: Pointer to Global MAC structure 2536 * @msg: The MsgQ header, which contains the response buffer 2537 * 2538 * This function is called to process the following two 2539 * messages from HAL: 2540 * 1) WMA_SET_BSSKEY_RSP 2541 * 2) WMA_SET_STAKEY_RSP 2542 * 3) WMA_SET_STA_BCASTKEY_RSP 2543 * Upon receipt of this message from HAL, 2544 * MLME - 2545 * > Determines the "state" in which this message was received 2546 * > Forwards it to the appropriate callback 2547 * LOGIC: 2548 * WMA_SET_BSSKEY_RSP/WMA_SET_STAKEY_RSP can be 2549 * received by MLME while in the following state: 2550 * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR-- 2551 * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR-- 2552 * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE 2553 * Based on this state, this API will determine where to 2554 * route the message to 2555 * Assumption: 2556 * ONLY the MLME state is being taken into account for now. 2557 * This is because, it appears that the handling of the 2558 * SETKEYS REQ is handled symmetrically on both the AP & STA 2559 * 2560 * Return: None 2561 */ lim_process_mlm_set_sta_key_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg)2562 void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx, 2563 struct scheduler_msg *msg) 2564 { 2565 struct sLimMlmSetKeysCnf mlm_set_key_cnf; 2566 uint8_t session_id = 0; 2567 uint8_t vdev_id; 2568 struct pe_session *session_entry; 2569 uint16_t key_len; 2570 uint16_t result_status; 2571 tSetStaKeyParams *set_key_params; 2572 tLimMlmStates mlm_state = eLIM_MLM_OFFLINE_STATE; 2573 2574 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); 2575 qdf_mem_zero((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf)); 2576 if (!msg->bodyptr) { 2577 pe_err("msg bodyptr is NULL"); 2578 return; 2579 } 2580 set_key_params = msg->bodyptr; 2581 vdev_id = set_key_params->vdev_id; 2582 session_id = vdev_id; 2583 if (wlan_get_opmode_from_vdev_id(mac_ctx->pdev, 2584 vdev_id) != QDF_NAN_DISC_MODE) { 2585 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 2586 if (!session_entry) { 2587 pe_err("session does not exist for given vdev_id %d", 2588 vdev_id); 2589 qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params)); 2590 qdf_mem_free(msg->bodyptr); 2591 msg->bodyptr = NULL; 2592 lim_send_sme_set_context_rsp(mac_ctx, 2593 mlm_set_key_cnf.peer_macaddr, 2594 0, 2595 eSIR_SME_INVALID_SESSION, 2596 NULL, vdev_id); 2597 return; 2598 } 2599 session_id = session_entry->peSessionId; 2600 mlm_state = session_entry->limMlmState; 2601 } 2602 2603 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session_id, mlm_state)); 2604 result_status = set_key_params->status; 2605 key_len = set_key_params->key_len; 2606 pe_debug("PE session ID %d, vdev_id %d key_len %d status %d", 2607 session_id, vdev_id, key_len, result_status); 2608 2609 if (result_status == eSIR_SME_SUCCESS && key_len) 2610 mlm_set_key_cnf.key_len_nonzero = true; 2611 else 2612 mlm_set_key_cnf.key_len_nonzero = false; 2613 2614 qdf_copy_macaddr(&mlm_set_key_cnf.peer_macaddr, 2615 &set_key_params->macaddr); 2616 mlm_set_key_cnf.sessionId = session_id; 2617 lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF, 2618 (uint32_t *) &mlm_set_key_cnf); 2619 2620 qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params)); 2621 qdf_mem_free(msg->bodyptr); 2622 msg->bodyptr = NULL; 2623 } 2624 2625 /** 2626 * lim_process_mlm_set_bss_key_rsp() - handles BSS key 2627 * 2628 * @mac_ctx: A pointer to Global MAC structure 2629 * @msg: Message from SME 2630 * 2631 * This function processes BSS key response and updates 2632 * PE status accordingly. 2633 * 2634 * Return: NULL 2635 */ lim_process_mlm_set_bss_key_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg)2636 void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx, 2637 struct scheduler_msg *msg) 2638 { 2639 struct sLimMlmSetKeysCnf set_key_cnf; 2640 uint16_t result_status; 2641 uint8_t session_id = 0; 2642 uint8_t vdev_id; 2643 struct pe_session *session_entry; 2644 uint16_t key_len; 2645 tSetBssKeyParams *bss_key; 2646 2647 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); 2648 qdf_mem_zero((void *)&set_key_cnf, sizeof(tLimMlmSetKeysCnf)); 2649 if (!msg->bodyptr) { 2650 pe_err("msg bodyptr is null"); 2651 return; 2652 } 2653 bss_key = msg->bodyptr; 2654 vdev_id = bss_key->vdev_id; 2655 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id); 2656 if (!session_entry) { 2657 pe_err("session does not exist for vdev_id %d", vdev_id); 2658 qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); 2659 qdf_mem_free(msg->bodyptr); 2660 msg->bodyptr = NULL; 2661 lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr, 2662 0, eSIR_SME_INVALID_SESSION, NULL, 2663 vdev_id); 2664 return; 2665 } 2666 2667 session_id = session_entry->peSessionId; 2668 result_status = (uint16_t)bss_key->status; 2669 key_len = bss_key->key_len; 2670 pe_debug("vdev %d (pe %d) limMlmState %d status %d key_len %d", 2671 vdev_id, session_id, session_entry->limMlmState, 2672 result_status, key_len); 2673 2674 if (result_status == eSIR_SME_SUCCESS && key_len) 2675 set_key_cnf.key_len_nonzero = true; 2676 else 2677 set_key_cnf.key_len_nonzero = false; 2678 2679 MTRACE(mac_trace 2680 (mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId, 2681 session_entry->limMlmState)); 2682 set_key_cnf.sessionId = session_id; 2683 2684 /* Prepare and Send LIM_MLM_SETKEYS_CNF */ 2685 qdf_copy_macaddr(&set_key_cnf.peer_macaddr, &bss_key->macaddr); 2686 qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams)); 2687 qdf_mem_free(msg->bodyptr); 2688 msg->bodyptr = NULL; 2689 2690 lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF, 2691 (uint32_t *) &set_key_cnf); 2692 } 2693 2694 /** 2695 * lim_process_switch_channel_re_assoc_req() 2696 * 2697 ***FUNCTION: 2698 * This function is called to send the reassoc req mgmt frame after the 2699 * switchChannelRsp message is received from HAL. 2700 * 2701 ***LOGIC: 2702 * 2703 ***ASSUMPTIONS: 2704 * NA 2705 * 2706 ***NOTE: 2707 * NA 2708 * 2709 * @param mac - Pointer to Global MAC structure. 2710 * @param pe_session - session related information. 2711 * @param status - channel switch success/failure. 2712 * 2713 * @return None 2714 */ lim_process_switch_channel_re_assoc_req(struct mac_context * mac,struct pe_session * pe_session,QDF_STATUS status)2715 static void lim_process_switch_channel_re_assoc_req(struct mac_context *mac, 2716 struct pe_session *pe_session, 2717 QDF_STATUS status) 2718 { 2719 tLimMlmReassocCnf mlmReassocCnf; 2720 tLimMlmReassocReq *pMlmReassocReq; 2721 2722 pMlmReassocReq = 2723 (tLimMlmReassocReq *) (pe_session->pLimMlmReassocReq); 2724 if (!pMlmReassocReq) { 2725 pe_err("pLimMlmReassocReq does not exist for given switchChanSession"); 2726 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 2727 goto end; 2728 } 2729 2730 if (status != QDF_STATUS_SUCCESS) { 2731 pe_err("Change channel failed!!"); 2732 mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL; 2733 goto end; 2734 } 2735 /* / Start reassociation failure timer */ 2736 MTRACE(mac_trace 2737 (mac, TRACE_CODE_TIMER_ACTIVATE, pe_session->peSessionId, 2738 eLIM_REASSOC_FAIL_TIMER)); 2739 if (tx_timer_activate(&mac->lim.lim_timers.gLimReassocFailureTimer) 2740 != TX_SUCCESS) { 2741 pe_err("could not start Reassociation failure timer"); 2742 /* Return Reassoc confirm with */ 2743 /* Resources Unavailable */ 2744 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 2745 goto end; 2746 } 2747 /* / Prepare and send Reassociation request frame */ 2748 lim_send_reassoc_req_mgmt_frame(mac, pMlmReassocReq, pe_session); 2749 return; 2750 end: 2751 /* Free up buffer allocated for reassocReq */ 2752 if (pMlmReassocReq) { 2753 /* Update PE session Id */ 2754 mlmReassocCnf.sessionId = pMlmReassocReq->sessionId; 2755 qdf_mem_free(pMlmReassocReq); 2756 pe_session->pLimMlmReassocReq = NULL; 2757 } else { 2758 mlmReassocCnf.sessionId = 0; 2759 } 2760 2761 mlmReassocCnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 2762 /* Update PE session Id */ 2763 mlmReassocCnf.sessionId = pe_session->peSessionId; 2764 2765 lim_post_sme_message(mac, LIM_MLM_REASSOC_CNF, 2766 (uint32_t *) &mlmReassocCnf); 2767 } 2768 2769 #ifdef WLAN_FEATURE_11BE_MLO 2770 static QDF_STATUS lim_process_switch_channel_join_mlo(struct pe_session * session_entry,struct mac_context * mac_ctx)2771 lim_process_switch_channel_join_mlo(struct pe_session *session_entry, 2772 struct mac_context *mac_ctx) 2773 { 2774 QDF_STATUS status = QDF_STATUS_SUCCESS; 2775 struct mlo_partner_info *partner_info; 2776 struct element_info assoc_rsp, link_assoc_rsp; 2777 tLimMlmJoinCnf mlm_join_cnf; 2778 tLimMlmAssocCnf assoc_cnf; 2779 uint8_t *frame_ie_buf, *mlie; 2780 qdf_size_t frame_ie_len, mlie_len; 2781 bool link_id_found = false; 2782 struct qdf_mac_addr sta_link_addr; 2783 uint8_t assoc_link_id, link_id; 2784 struct wlan_frame_hdr *link_frame_hdr; 2785 2786 assoc_rsp.len = 0; 2787 mlo_get_assoc_rsp(session_entry->vdev, &assoc_rsp); 2788 2789 partner_info = &session_entry->ml_partner_info; 2790 if (!partner_info->num_partner_links) { 2791 pe_debug("MLO: vdev:%d num_partner_links is 0", 2792 session_entry->vdev_id); 2793 return QDF_STATUS_E_INVAL; 2794 } 2795 2796 /* Todo: update the sta addr by matching link id */ 2797 qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr, 2798 QDF_MAC_ADDR_SIZE); 2799 2800 if (!assoc_rsp.len) 2801 return status; 2802 2803 mlm_join_cnf.resultCode = eSIR_SME_SUCCESS; 2804 mlm_join_cnf.protStatusCode = STATUS_SUCCESS; 2805 /* Update PE sessionId */ 2806 mlm_join_cnf.sessionId = session_entry->peSessionId; 2807 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, 2808 (uint32_t *)&mlm_join_cnf); 2809 2810 session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE; 2811 assoc_rsp.len += SIR_MAC_HDR_LEN_3A; 2812 pe_debug("MLO:assoc rsp len + hdr %d ", assoc_rsp.len); 2813 2814 link_assoc_rsp.ptr = qdf_mem_malloc(assoc_rsp.len); 2815 if (!link_assoc_rsp.ptr) 2816 return QDF_STATUS_E_NOMEM; 2817 2818 link_assoc_rsp.len = assoc_rsp.len + 24; 2819 session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE; 2820 2821 link_id = wlan_vdev_get_link_id(session_entry->vdev); 2822 pe_debug("MLO: Generate and process assoc rsp for link vdev %d", 2823 link_id); 2824 2825 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(session_entry->vdev)) { 2826 frame_ie_buf = assoc_rsp.ptr + WLAN_ASSOC_RSP_IES_OFFSET; 2827 frame_ie_len = assoc_rsp.len - 24 - WLAN_ASSOC_RSP_IES_OFFSET; 2828 2829 status = util_find_mlie(frame_ie_buf, frame_ie_len, 2830 &mlie, &mlie_len); 2831 if (QDF_IS_STATUS_ERROR(status)) { 2832 pe_debug("ML IE not found"); 2833 goto rsp_gen_fail; 2834 } 2835 2836 status = util_get_bvmlie_primary_linkid(mlie, mlie_len, 2837 &link_id_found, 2838 &assoc_link_id); 2839 if (QDF_IS_STATUS_ERROR(status) || !link_id_found) { 2840 pe_debug("Assoc link ID not found"); 2841 goto rsp_gen_fail; 2842 } 2843 2844 if (assoc_link_id != link_id) 2845 goto gen_link_assoc_rsp; 2846 2847 pe_debug("Skip assoc rsp gen for link %d", link_id); 2848 link_frame_hdr = (struct wlan_frame_hdr *)link_assoc_rsp.ptr; 2849 qdf_ether_addr_copy(link_frame_hdr->i_addr3, 2850 session_entry->bssId); 2851 qdf_ether_addr_copy(link_frame_hdr->i_addr2, 2852 session_entry->bssId); 2853 qdf_ether_addr_copy(link_frame_hdr->i_addr1, 2854 &sta_link_addr.bytes[0]); 2855 link_frame_hdr->i_fc[0] = MLO_LINKSPECIFIC_ASSOC_RESP_FC0; 2856 link_frame_hdr->i_fc[1] = MLO_LINKSPECIFIC_ASSOC_RESP_FC1; 2857 2858 qdf_mem_copy(link_assoc_rsp.ptr + SIR_MAC_HDR_LEN_3A, 2859 assoc_rsp.ptr, assoc_rsp.len - SIR_MAC_HDR_LEN_3A); 2860 2861 goto process_assoc_rsp; 2862 } 2863 2864 gen_link_assoc_rsp: 2865 status = util_gen_link_assoc_rsp(assoc_rsp.ptr, 2866 assoc_rsp.len - 24, 2867 false, link_id, sta_link_addr, 2868 link_assoc_rsp.ptr, 2869 assoc_rsp.len, 2870 (qdf_size_t *)&link_assoc_rsp.len); 2871 process_assoc_rsp: 2872 if (QDF_IS_STATUS_SUCCESS(status)) { 2873 pe_debug("MLO: process assoc rsp for link vdev"); 2874 lim_process_assoc_rsp_frame(mac_ctx, 2875 link_assoc_rsp.ptr, 2876 (link_assoc_rsp.len - SIR_MAC_HDR_LEN_3A), 2877 LIM_ASSOC, 2878 session_entry); 2879 goto mem_free; 2880 } 2881 2882 rsp_gen_fail: 2883 pe_debug("MLO: link vdev assoc rsp generation failed"); 2884 assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 2885 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 2886 /* Update PE sessionId */ 2887 assoc_cnf.sessionId = session_entry->peSessionId; 2888 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 2889 (uint32_t *)&assoc_cnf); 2890 2891 mem_free: 2892 qdf_mem_free(link_assoc_rsp.ptr); 2893 link_assoc_rsp.ptr = NULL; 2894 link_assoc_rsp.len = 0; 2895 2896 return status; 2897 } 2898 2899 #else /* WLAN_FEATURE_11BE_MLO */ 2900 static QDF_STATUS lim_process_switch_channel_join_mlo(struct pe_session * session_entry,struct mac_context * mac_ctx)2901 lim_process_switch_channel_join_mlo(struct pe_session *session_entry, 2902 struct mac_context *mac_ctx) 2903 { 2904 return QDF_STATUS_SUCCESS; 2905 } 2906 #endif /* WLAN_FEATURE_11BE_MLO */ 2907 2908 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO) 2909 static QDF_STATUS lim_process_switch_channel_join_mlo_roam(struct pe_session * session_entry,struct mac_context * mac_ctx)2910 lim_process_switch_channel_join_mlo_roam(struct pe_session *session_entry, 2911 struct mac_context *mac_ctx) 2912 { 2913 QDF_STATUS status; 2914 struct element_info assoc_rsp = {}; 2915 struct qdf_mac_addr sta_link_addr; 2916 struct element_info link_assoc_rsp; 2917 tLimMlmJoinCnf mlm_join_cnf; 2918 tLimMlmAssocCnf assoc_cnf; 2919 struct qdf_mac_addr bssid; 2920 uint8_t link_id = 0; 2921 2922 assoc_rsp.len = 0; 2923 mlo_get_assoc_rsp(session_entry->vdev, &assoc_rsp); 2924 2925 if (!session_entry->ml_partner_info.num_partner_links) { 2926 pe_debug("MLO_ROAM: vdev:%d num_partner_links is 0", 2927 session_entry->vdev_id); 2928 return QDF_STATUS_E_INVAL; 2929 } 2930 2931 /* Todo: update the sta addr by matching link id */ 2932 qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr, 2933 QDF_MAC_ADDR_SIZE); 2934 2935 pe_err("vdev:%d sta_link_addr" QDF_MAC_ADDR_FMT, 2936 session_entry->vdev_id, 2937 QDF_MAC_ADDR_REF(&sta_link_addr.bytes[0])); 2938 2939 if (!assoc_rsp.len) 2940 return QDF_STATUS_SUCCESS; 2941 2942 mlm_join_cnf.resultCode = eSIR_SME_SUCCESS; 2943 mlm_join_cnf.protStatusCode = STATUS_SUCCESS; 2944 /* Update PE sessionId */ 2945 mlm_join_cnf.sessionId = session_entry->peSessionId; 2946 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, 2947 (uint32_t *)&mlm_join_cnf); 2948 2949 session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE; 2950 pe_debug("MLO_ROAM: reassoc rsp len %d ", assoc_rsp.len); 2951 2952 link_assoc_rsp.ptr = qdf_mem_malloc(assoc_rsp.len); 2953 if (!link_assoc_rsp.ptr) 2954 return QDF_STATUS_E_NOMEM; 2955 2956 link_assoc_rsp.len = assoc_rsp.len; 2957 session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; 2958 mlo_get_link_mac_addr_from_reassoc_rsp(session_entry->vdev, &bssid); 2959 sir_copy_mac_addr(session_entry->limReAssocbssId, bssid.bytes); 2960 link_id = wlan_vdev_get_link_id(session_entry->vdev); 2961 pe_debug("MLO ROAM: Generate and process assoc rsp for link_id:%d vdev %d", 2962 link_id, session_entry->vdev_id); 2963 2964 status = util_gen_link_assoc_rsp(assoc_rsp.ptr, 2965 assoc_rsp.len, 2966 true, link_id, sta_link_addr, 2967 link_assoc_rsp.ptr, 2968 assoc_rsp.len, 2969 (qdf_size_t *)&link_assoc_rsp.len); 2970 if (QDF_IS_STATUS_ERROR(status)) { 2971 pe_err("MLO_ROAM: link vdev:%d link_id:%d assoc rsp generation failed", 2972 session_entry->vdev_id, link_id); 2973 assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS; 2974 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 2975 /* Update PE sessionId */ 2976 assoc_cnf.sessionId = session_entry->peSessionId; 2977 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 2978 (uint32_t *)&assoc_cnf); 2979 2980 session_entry->limMlmState = eLIM_MLM_IDLE_STATE; 2981 qdf_mem_free(link_assoc_rsp.ptr); 2982 2983 return status; 2984 } 2985 2986 pe_debug("MLO_ROAM: process reassoc rsp for link vdev"); 2987 lim_process_assoc_rsp_frame(mac_ctx, link_assoc_rsp.ptr, 2988 (link_assoc_rsp.len - WLAN_MAC_HDR_LEN_3A), 2989 LIM_REASSOC, session_entry); 2990 qdf_mem_free(link_assoc_rsp.ptr); 2991 2992 return QDF_STATUS_SUCCESS; 2993 } 2994 #else /* (WLAN_FEATURE_ROAM_OFFLOAD) && (WLAN_FEATURE_11BE_MLO) */ 2995 static QDF_STATUS lim_process_switch_channel_join_mlo_roam(struct pe_session * session_entry,struct mac_context * mac_ctx)2996 lim_process_switch_channel_join_mlo_roam(struct pe_session *session_entry, 2997 struct mac_context *mac_ctx) 2998 { 2999 return QDF_STATUS_SUCCESS; 3000 } 3001 #endif /* (WLAN_FEATURE_ROAM_OFFLOAD) && (WLAN_FEATURE_11BE_MLO) */ 3002 3003 #ifdef WLAN_FEATURE_11BE_MLO 3004 static void lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session * session)3005 lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session *session) 3006 { 3007 struct mlo_partner_info *partner_info; 3008 struct mlo_link_info *partner_link_info; 3009 struct wlan_channel channel = {0}; 3010 struct mlo_link_switch_context *link_ctx; 3011 uint8_t i = 0; 3012 3013 if (!session->vdev) { 3014 pe_err("vdev:%d is NULL", session->vdev_id); 3015 return; 3016 } 3017 3018 if (!wlan_vdev_mlme_is_mlo_vdev(session->vdev)) 3019 return; 3020 3021 if (!session->lim_join_req) { 3022 pe_err("vdev:%d lim_join_req is NULL", session->vdev_id); 3023 return; 3024 } 3025 3026 link_ctx = session->vdev->mlo_dev_ctx->link_ctx; 3027 if (!link_ctx) { 3028 pe_err("vdev:%d MLO Link_ctx not found", 3029 session->vdev_id); 3030 return; 3031 } 3032 3033 /* Populating Assoc Link Band info */ 3034 channel.ch_freq = (uint16_t)session->curr_op_freq; 3035 3036 mlo_mgr_reset_ap_link_info(session->vdev); 3037 mlo_mgr_update_ap_link_info(session->vdev, 3038 wlan_vdev_get_link_id(session->vdev), 3039 session->bssId, channel); 3040 3041 /* Populating Partner link band Info */ 3042 partner_info = &session->lim_join_req->partner_info; 3043 for (i = 0; i < partner_info->num_partner_links; i++) { 3044 partner_link_info = &partner_info->partner_link_info[i]; 3045 3046 qdf_mem_zero(&channel, sizeof(channel)); 3047 channel.ch_freq = partner_link_info->chan_freq; 3048 3049 mlo_mgr_update_ap_link_info(session->vdev, 3050 partner_link_info->link_id, 3051 partner_link_info->link_addr.bytes, 3052 channel); 3053 } 3054 } 3055 #else 3056 static void lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session * session)3057 lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session *session) 3058 {} 3059 #endif 3060 3061 /** 3062 * lim_process_switch_channel_join_req() -Initiates probe request 3063 * 3064 * @mac_ctx - A pointer to Global MAC structure 3065 * @pe_session - session related information. 3066 * @status - channel switch success/failure 3067 * 3068 * This function is called to send the probe req mgmt frame 3069 * after the switchChannelRsp message is received from HAL. 3070 * 3071 * Return None 3072 */ lim_process_switch_channel_join_req(struct mac_context * mac_ctx,struct pe_session * session_entry,QDF_STATUS status)3073 static void lim_process_switch_channel_join_req( 3074 struct mac_context *mac_ctx, struct pe_session *session_entry, 3075 QDF_STATUS status) 3076 { 3077 tSirMacSSid ssId; 3078 tLimMlmJoinCnf join_cnf; 3079 uint8_t nontx_bss_id = 0; 3080 struct bss_description *bss; 3081 struct vdev_mlme_obj *mlme_obj; 3082 struct wlan_lmac_if_reg_tx_ops *tx_ops; 3083 bool tpe_change = false; 3084 QDF_STATUS mlo_status; 3085 struct pe_session *sap_session; 3086 3087 if (status != QDF_STATUS_SUCCESS) { 3088 pe_err("Change channel failed!!"); 3089 goto error; 3090 } 3091 3092 if ((!session_entry) || (!session_entry->pLimMlmJoinReq) || 3093 (!session_entry->lim_join_req)) { 3094 pe_err("invalid pointer!!"); 3095 goto error; 3096 } 3097 3098 if (lim_connect_skip_join_for_gc(session_entry)) { 3099 join_cnf.resultCode = eSIR_SME_SUCCESS; 3100 join_cnf.protStatusCode = STATUS_SUCCESS; 3101 join_cnf.sessionId = session_entry->peSessionId; 3102 lim_post_sme_message(mac_ctx, 3103 LIM_MLM_JOIN_CNF, 3104 (uint32_t *)&join_cnf.resultCode); 3105 return; 3106 } 3107 3108 bss = &session_entry->lim_join_req->bssDescription; 3109 nontx_bss_id = bss->mbssid_info.profile_num; 3110 3111 session_entry->limPrevMlmState = session_entry->limMlmState; 3112 session_entry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE; 3113 3114 /* Apply previously set configuration at HW */ 3115 lim_apply_configuration(mac_ctx, session_entry); 3116 3117 if (wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) { 3118 if (mlo_roam_is_auth_status_connected(mac_ctx->psoc, 3119 session_entry->vdev_id)) 3120 mlo_status = lim_process_switch_channel_join_mlo_roam(session_entry, 3121 mac_ctx); 3122 else 3123 mlo_status = lim_process_switch_channel_join_mlo(session_entry, 3124 mac_ctx); 3125 3126 if (mlo_status == QDF_STATUS_E_INVAL) 3127 goto error; 3128 else 3129 return; 3130 } 3131 /* 3132 * If deauth_before_connection is enabled, Send Deauth first to AP if 3133 * last disconnection was caused by HB failure. 3134 */ 3135 if (mac_ctx->mlme_cfg->sta.deauth_before_connection) { 3136 int apCount; 3137 3138 for (apCount = 0; apCount < 2; apCount++) { 3139 3140 if (!qdf_mem_cmp(session_entry->pLimMlmJoinReq->bssDescription.bssId, 3141 mac_ctx->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) { 3142 3143 pe_err("Index %d Sessionid: %d Send deauth on " 3144 "channel freq %d to BSSID: " QDF_MAC_ADDR_FMT, 3145 apCount, 3146 session_entry->peSessionId, 3147 session_entry->curr_op_freq, 3148 QDF_MAC_ADDR_REF( 3149 session_entry->pLimMlmJoinReq->bssDescription.bssId)); 3150 3151 lim_send_deauth_mgmt_frame(mac_ctx, REASON_UNSPEC_FAILURE, 3152 session_entry->pLimMlmJoinReq->bssDescription.bssId, 3153 session_entry, false); 3154 3155 qdf_mem_zero(mac_ctx->lim.gLimHeartBeatApMac[apCount], 3156 sizeof(tSirMacAddr)); 3157 break; 3158 } 3159 } 3160 } 3161 3162 /* 3163 * MBSSID: Non Tx BSS may or may not respond to unicast 3164 * probe request.So dont send unicast probe request 3165 * and wait for the probe response/ beacon to post JOIN CNF 3166 */ 3167 if (nontx_bss_id) { 3168 pe_debug("Skip sending join probe for MBSS candidate"); 3169 session_entry->limMlmState = eLIM_MLM_JOINED_STATE; 3170 join_cnf.sessionId = session_entry->peSessionId; 3171 join_cnf.resultCode = eSIR_SME_SUCCESS; 3172 join_cnf.protStatusCode = STATUS_SUCCESS; 3173 3174 lim_update_mlo_mgr_ap_link_info_mbssid_connect(session_entry); 3175 3176 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, 3177 (uint32_t *)&join_cnf); 3178 return; 3179 } 3180 3181 /* Wait for Beacon to announce join success */ 3182 qdf_mem_copy(ssId.ssId, 3183 session_entry->ssId.ssId, session_entry->ssId.length); 3184 ssId.length = session_entry->ssId.length; 3185 3186 lim_deactivate_and_change_timer(mac_ctx, 3187 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); 3188 3189 /* assign appropriate sessionId to the timer object */ 3190 mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer.sessionId = 3191 session_entry->peSessionId; 3192 pe_debug("vdev %d Send Probe req on freq %d " QDF_SSID_FMT " " QDF_MAC_ADDR_FMT, 3193 session_entry->vdev_id, 3194 session_entry->curr_op_freq, 3195 QDF_SSID_REF(ssId.length, ssId.ssId), 3196 QDF_MAC_ADDR_REF( 3197 session_entry->pLimMlmJoinReq->bssDescription.bssId)); 3198 3199 /* 3200 * We need to wait for probe response, so start join 3201 * timeout timer.This timer will be deactivated once 3202 * we receive probe response. 3203 */ 3204 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 3205 session_entry->peSessionId, eLIM_JOIN_FAIL_TIMER)); 3206 if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimJoinFailureTimer) != 3207 TX_SUCCESS) { 3208 pe_err("couldn't activate Join failure timer"); 3209 session_entry->limMlmState = session_entry->limPrevMlmState; 3210 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 3211 session_entry->peSessionId, 3212 mac_ctx->lim.gLimMlmState)); 3213 goto error; 3214 } 3215 3216 sap_session = 3217 lim_get_concurrent_session(mac_ctx, session_entry->vdev_id, 3218 session_entry->opmode); 3219 3220 /* 3221 * STA LPI + SAP VLP is supported. For this, STA should move to 3222 * VLP power. 3223 * If there is a concurrent SAP operating on VLP in the same channel, 3224 * then do not update the TPC if the connecting AP is in LPI. 3225 */ 3226 if (sap_session && 3227 lim_is_power_change_required_for_sta(mac_ctx, session_entry, sap_session)) 3228 lim_update_tx_power(mac_ctx, sap_session, session_entry, false); 3229 3230 if (wlan_reg_is_ext_tpc_supported(mac_ctx->psoc) && 3231 !session_entry->sta_follows_sap_power) { 3232 tx_ops = wlan_reg_get_tx_ops(mac_ctx->psoc); 3233 3234 lim_process_tpe_ie_from_beacon(mac_ctx, session_entry, bss, 3235 &tpe_change); 3236 3237 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session_entry->vdev); 3238 if (!mlme_obj) { 3239 pe_err("vdev component object is NULL"); 3240 goto error; 3241 } 3242 3243 lim_calculate_tpc(mac_ctx, session_entry); 3244 3245 if (tx_ops->set_tpc_power) 3246 tx_ops->set_tpc_power(mac_ctx->psoc, 3247 session_entry->vdev_id, 3248 &mlme_obj->reg_tpc_obj); 3249 } 3250 /* include additional IE if there is */ 3251 lim_send_probe_req_mgmt_frame(mac_ctx, &ssId, 3252 session_entry->pLimMlmJoinReq->bssDescription.bssId, 3253 session_entry->curr_op_freq, 3254 session_entry->self_mac_addr, 3255 session_entry->dot11mode, 3256 &session_entry->lim_join_req->addIEScan.length, 3257 session_entry->lim_join_req->addIEScan.addIEdata); 3258 3259 /* Activate Join Periodic Probe Req timer */ 3260 if (tx_timer_activate 3261 (&mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer) 3262 != TX_SUCCESS) { 3263 pe_err("Periodic JoinReq timer activate failed"); 3264 goto error; 3265 } 3266 3267 session_entry->join_probe_cnt++; 3268 return; 3269 error: 3270 if (session_entry) { 3271 if (session_entry->pLimMlmJoinReq) { 3272 qdf_mem_free(session_entry->pLimMlmJoinReq); 3273 session_entry->pLimMlmJoinReq = NULL; 3274 } 3275 if (session_entry->lim_join_req) { 3276 qdf_mem_free(session_entry->lim_join_req); 3277 session_entry->lim_join_req = NULL; 3278 } 3279 join_cnf.sessionId = session_entry->peSessionId; 3280 } else { 3281 join_cnf.sessionId = 0; 3282 } 3283 join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 3284 join_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 3285 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, (uint32_t *)&join_cnf); 3286 } 3287 lim_handle_mon_switch_channel_rsp(struct pe_session * session,QDF_STATUS status)3288 static void lim_handle_mon_switch_channel_rsp(struct pe_session *session, 3289 QDF_STATUS status) 3290 { 3291 struct scheduler_msg message = {0}; 3292 3293 if (session->bssType != eSIR_MONITOR_MODE) 3294 return; 3295 3296 if (QDF_IS_STATUS_ERROR(status)) { 3297 enum wlan_vdev_sm_evt event = WLAN_VDEV_SM_EV_START_REQ_FAIL; 3298 3299 pe_err("Set channel failed for monitor mode vdev substate %d", 3300 wlan_vdev_mlme_get_substate(session->vdev)); 3301 3302 if (QDF_IS_STATUS_SUCCESS( 3303 wlan_vdev_is_restart_progress(session->vdev))) 3304 event = WLAN_VDEV_SM_EV_RESTART_REQ_FAIL; 3305 3306 wlan_vdev_mlme_sm_deliver_evt(session->vdev, event, 0, NULL); 3307 3308 return; 3309 } 3310 3311 wlan_vdev_mlme_sm_deliver_evt(session->vdev, 3312 WLAN_VDEV_SM_EV_START_SUCCESS, 0, NULL); 3313 3314 message.type = eWNI_SME_MONITOR_MODE_VDEV_UP; 3315 message.bodyval = session->vdev_id; 3316 pe_debug("vdev id %d ", session->vdev_id); 3317 3318 if (QDF_STATUS_SUCCESS != 3319 scheduler_post_message(QDF_MODULE_ID_PE, 3320 QDF_MODULE_ID_SME, 3321 QDF_MODULE_ID_SME, &message)) { 3322 pe_err("Failed to post message montior mode vdev up"); 3323 } 3324 } 3325 3326 /** 3327 * lim_process_switch_channel_rsp() 3328 * 3329 ***FUNCTION: 3330 * This function is called to process switchChannelRsp message from HAL. 3331 * 3332 ***LOGIC: 3333 * 3334 ***ASSUMPTIONS: 3335 * NA 3336 * 3337 ***NOTE: 3338 * NA 3339 * 3340 * @param mac - Pointer to Global MAC structure 3341 * @param body - message body. 3342 * 3343 * @return None 3344 */ lim_process_switch_channel_rsp(struct mac_context * mac,struct vdev_start_response * rsp)3345 void lim_process_switch_channel_rsp(struct mac_context *mac, 3346 struct vdev_start_response *rsp) 3347 { 3348 QDF_STATUS status; 3349 uint16_t channelChangeReasonCode; 3350 struct pe_session *pe_session; 3351 struct wlan_channel *vdev_chan; 3352 /* we need to process the deferred message since the initiating req. there might be nested request. */ 3353 /* in the case of nested request the new request initiated from the response will take care of resetting */ 3354 /* the deferred flag. */ 3355 SET_LIM_PROCESS_DEFD_MESGS(mac, true); 3356 status = rsp->status; 3357 3358 pe_session = pe_find_session_by_vdev_id(mac, rsp->vdev_id); 3359 if (!pe_session) { 3360 pe_err("session does not exist for given sessionId"); 3361 return; 3362 } 3363 pe_session->ch_switch_in_progress = false; 3364 channelChangeReasonCode = pe_session->channelChangeReasonCode; 3365 /* initialize it back to invalid id */ 3366 pe_session->chainMask = rsp->chain_mask; 3367 pe_session->smpsMode = rsp->smps_mode; 3368 pe_session->channelChangeReasonCode = 0xBAD; 3369 3370 vdev_chan = wlan_vdev_mlme_get_des_chan(pe_session->vdev); 3371 3372 if (WLAN_REG_IS_24GHZ_CH_FREQ(vdev_chan->ch_freq)) { 3373 if (vdev_chan->ch_phymode == WLAN_PHYMODE_11B) 3374 pe_session->nwType = eSIR_11B_NW_TYPE; 3375 else 3376 pe_session->nwType = eSIR_11G_NW_TYPE; 3377 } else { 3378 pe_session->nwType = eSIR_11A_NW_TYPE; 3379 } 3380 pe_debug("new network type for peer: %d", pe_session->nwType); 3381 switch (channelChangeReasonCode) { 3382 case LIM_SWITCH_CHANNEL_REASSOC: 3383 lim_process_switch_channel_re_assoc_req(mac, pe_session, status); 3384 break; 3385 case LIM_SWITCH_CHANNEL_JOIN: 3386 lim_process_switch_channel_join_req(mac, pe_session, status); 3387 break; 3388 3389 case LIM_SWITCH_CHANNEL_OPERATION: 3390 case LIM_SWITCH_CHANNEL_HT_WIDTH: 3391 /* 3392 * The above code should also use the callback. 3393 * mechanism below, there is scope for cleanup here. 3394 * THat way all this response handler does is call the call back 3395 * We can get rid of the reason code here. 3396 */ 3397 if (mac->lim.gpchangeChannelCallback) 3398 mac->lim.gpchangeChannelCallback(mac, status, 3399 mac->lim. 3400 gpchangeChannelData, 3401 pe_session); 3402 3403 /* If MCC upgrade/DBS downgrade happened during channel switch, 3404 * the policy manager connection table needs to be updated. 3405 * STA PCL to F/W need update after sta channel switch. 3406 */ 3407 policy_mgr_update_connection_info(mac->psoc, 3408 pe_session->smeSessionId); 3409 wlan_cm_handle_sta_sta_roaming_enablement(mac->psoc, 3410 pe_session->smeSessionId); 3411 if (pe_session->opmode == QDF_P2P_CLIENT_MODE) { 3412 pe_debug("Send p2p operating channel change conf action frame once first beacon is received on new channel"); 3413 pe_session->send_p2p_conf_frame = true; 3414 } 3415 3416 if (ucfg_pkt_capture_get_pktcap_mode(mac->psoc)) 3417 ucfg_pkt_capture_record_channel(pe_session->vdev); 3418 break; 3419 case LIM_SWITCH_CHANNEL_SAP_DFS: 3420 if (QDF_IS_STATUS_SUCCESS(status)) 3421 lim_set_tpc_power(mac, pe_session, NULL); 3422 3423 /* Note: This event code specific to SAP mode 3424 * When SAP session issues channel change as performing 3425 * DFS, we will come here. Other sessions, for e.g. P2P 3426 * will have to define their own event code and channel 3427 * switch handler. This is required since the SME may 3428 * require completely different information for P2P unlike 3429 * SAP. 3430 */ 3431 lim_send_sme_ap_channel_switch_resp(mac, pe_session, rsp); 3432 /* If MCC upgrade/DBS downgrade happened during channel switch, 3433 * the policy manager connection table needs to be updated. 3434 */ 3435 policy_mgr_update_connection_info(mac->psoc, 3436 pe_session->smeSessionId); 3437 lim_check_conc_power_for_csa(mac, pe_session); 3438 break; 3439 case LIM_SWITCH_CHANNEL_MONITOR: 3440 lim_handle_mon_switch_channel_rsp(pe_session, status); 3441 /* 3442 * If MCC upgrade/DBS downgrade happened during channel switch, 3443 * the policy manager connection table needs to be updated. 3444 */ 3445 policy_mgr_update_connection_info(mac->psoc, 3446 pe_session->smeSessionId); 3447 if (ucfg_pkt_capture_get_pktcap_mode(mac->psoc)) 3448 ucfg_pkt_capture_record_channel(pe_session->vdev); 3449 break; 3450 default: 3451 break; 3452 } 3453 } 3454 lim_send_beacon_ind(struct mac_context * mac,struct pe_session * pe_session,enum sir_bcn_update_reason reason)3455 QDF_STATUS lim_send_beacon_ind(struct mac_context *mac, 3456 struct pe_session *pe_session, 3457 enum sir_bcn_update_reason reason) 3458 { 3459 struct beacon_gen_params *params; 3460 struct scheduler_msg msg = {0}; 3461 3462 if (!pe_session) { 3463 pe_err("Error:Unable to get the PESessionEntry"); 3464 return QDF_STATUS_E_INVAL; 3465 } 3466 params = qdf_mem_malloc(sizeof(*params)); 3467 if (!params) 3468 return QDF_STATUS_E_NOMEM; 3469 qdf_mem_copy(params->bssid, pe_session->bssId, QDF_MAC_ADDR_SIZE); 3470 msg.bodyptr = params; 3471 3472 return sch_process_pre_beacon_ind(mac, &msg, reason); 3473 } 3474