1 /* 2 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * 22 * This file lim_process_assoc_rsp_frame.cc contains the code 23 * for processing Re/Association Response Frame. 24 * Author: Chandra Modumudi 25 * Date: 03/18/02 26 * History:- 27 * Date Modified by Modification Information 28 * -------------------------------------------------------------------- 29 * 30 */ 31 32 #include "wni_api.h" 33 #include "wni_cfg.h" 34 #include "ani_global.h" 35 #include "sch_api.h" 36 37 #include "utils_api.h" 38 #include "lim_types.h" 39 #include "lim_utils.h" 40 #include "lim_assoc_utils.h" 41 #include "lim_security_utils.h" 42 #include "lim_ser_des_utils.h" 43 #include "lim_send_messages.h" 44 #include "lim_process_fils.h" 45 #include "wlan_dlm_api.h" 46 #include "wlan_mlme_twt_api.h" 47 #include "wlan_mlme_ucfg_api.h" 48 #include "wlan_connectivity_logging.h" 49 #include <lim_mlo.h> 50 #include "parser_api.h" 51 #include "wlan_twt_cfg_ext_api.h" 52 #include "wlan_mlo_mgr_roam.h" 53 54 /** 55 * lim_update_stads_htcap() - Updates station Descriptor HT capability 56 * @mac_ctx: Pointer to Global MAC structure 57 * @sta_ds: Station Descriptor in DPH 58 * @assoc_rsp: Pointer to Association Response Structure 59 * @session_entry : PE session Entry 60 * 61 * This function is called to Update the HT capabilities in 62 * Station Descriptor (dph) Details from 63 * Association / ReAssociation Response Frame 64 * 65 * Return: None 66 */ lim_update_stads_htcap(struct mac_context * mac_ctx,tpDphHashNode sta_ds,tpSirAssocRsp assoc_rsp,struct pe_session * session_entry)67 static void lim_update_stads_htcap(struct mac_context *mac_ctx, 68 tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, 69 struct pe_session *session_entry) 70 { 71 uint16_t highest_rxrate = 0; 72 tDot11fIEHTCaps *ht_caps; 73 74 ht_caps = &assoc_rsp->HTCaps; 75 sta_ds->mlmStaContext.htCapability = assoc_rsp->HTCaps.present; 76 if (assoc_rsp->HTCaps.present) { 77 sta_ds->htGreenfield = 78 (uint8_t) ht_caps->greenField; 79 if (session_entry->htSupportedChannelWidthSet) { 80 sta_ds->htSupportedChannelWidthSet = 81 (uint8_t) (ht_caps->supportedChannelWidthSet ? 82 assoc_rsp->HTInfo.recommendedTxWidthSet : 83 ht_caps->supportedChannelWidthSet); 84 } else 85 sta_ds->htSupportedChannelWidthSet = 86 eHT_CHANNEL_WIDTH_20MHZ; 87 sta_ds->htLsigTXOPProtection = 88 (uint8_t) ht_caps->lsigTXOPProtection; 89 sta_ds->htMIMOPSState = 90 (tSirMacHTMIMOPowerSaveState)ht_caps->mimoPowerSave; 91 sta_ds->htMaxAmsduLength = 92 (uint8_t) ht_caps->maximalAMSDUsize; 93 sta_ds->htAMpduDensity = ht_caps->mpduDensity; 94 sta_ds->htDsssCckRate40MHzSupport = 95 (uint8_t) ht_caps->dsssCckMode40MHz; 96 sta_ds->htMaxRxAMpduFactor = 97 ht_caps->maxRxAMPDUFactor; 98 lim_fill_rx_highest_supported_rate(mac_ctx, &highest_rxrate, 99 ht_caps->supportedMCSSet); 100 sta_ds->supportedRates.rxHighestDataRate = 101 highest_rxrate; 102 /* 103 * This is for AP as peer STA and we are INFRA STA 104 *.We will put APs offset in dph node which is peer STA 105 */ 106 sta_ds->htSecondaryChannelOffset = 107 (uint8_t) assoc_rsp->HTInfo.secondaryChannelOffset; 108 109 /* Check if we have support for gShortGI20Mhz and 110 * gShortGI40Mhz from ini file 111 */ 112 if (session_entry->ht_config.short_gi_20_mhz) 113 sta_ds->htShortGI20Mhz = 114 (uint8_t)assoc_rsp->HTCaps.shortGI20MHz; 115 else 116 sta_ds->htShortGI20Mhz = false; 117 118 if (session_entry->ht_config.short_gi_40_mhz) 119 sta_ds->htShortGI40Mhz = 120 (uint8_t)assoc_rsp->HTCaps.shortGI40MHz; 121 else 122 sta_ds->htShortGI40Mhz = false; 123 } 124 } 125 126 /** 127 * lim_update_assoc_sta_datas() - Updates station Descriptor 128 * mac_ctx: Pointer to Global MAC structure 129 * sta_ds: Station Descriptor in DPH 130 * assoc_rsp: Pointer to Association Response Structure 131 * session_entry : PE session Entry 132 * 133 * This function is called to Update the Station Descriptor (dph) Details from 134 * Association / ReAssociation Response Frame 135 * 136 * Return: None 137 */ lim_update_assoc_sta_datas(struct mac_context * mac_ctx,tpDphHashNode sta_ds,tpSirAssocRsp assoc_rsp,struct pe_session * session_entry,tSchBeaconStruct * beacon)138 void lim_update_assoc_sta_datas(struct mac_context *mac_ctx, 139 tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, 140 struct pe_session *session_entry, tSchBeaconStruct *beacon) 141 { 142 uint32_t phy_mode; 143 bool qos_mode; 144 tDot11fIEVHTCaps *vht_caps = NULL; 145 tDot11fIEhe_cap *he_cap = NULL; 146 tDot11fIEeht_cap *eht_cap = NULL; 147 struct bss_description *bss_desc = NULL; 148 tDot11fIEVHTOperation *vht_oper = NULL; 149 enum phy_ch_width omn_ie_ch_width; 150 151 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry); 152 sta_ds->staType = STA_ENTRY_SELF; 153 limGetQosMode(session_entry, &qos_mode); 154 sta_ds->mlmStaContext.authType = session_entry->limCurrentAuthType; 155 156 /* Add capabilities information, rates and AID */ 157 sta_ds->mlmStaContext.capabilityInfo = assoc_rsp->capabilityInfo; 158 sta_ds->shortPreambleEnabled = 159 (uint8_t) assoc_rsp->capabilityInfo.shortPreamble; 160 161 /* Update HT Capabilities only when the self mode supports HT */ 162 if (IS_DOT11_MODE_HT(session_entry->dot11mode)) 163 lim_update_stads_htcap(mac_ctx, sta_ds, assoc_rsp, 164 session_entry); 165 166 if (assoc_rsp->VHTCaps.present) { 167 vht_caps = &assoc_rsp->VHTCaps; 168 vht_oper = &assoc_rsp->VHTOperation; 169 } else if (assoc_rsp->vendor_vht_ie.VHTCaps.present) { 170 vht_caps = &assoc_rsp->vendor_vht_ie.VHTCaps; 171 vht_oper = &assoc_rsp->vendor_vht_ie.VHTOperation; 172 } 173 174 if (session_entry->vhtCapability && (vht_caps && vht_caps->present)) { 175 sta_ds->mlmStaContext.vhtCapability = 176 vht_caps->present; 177 178 /* 179 * If 11ac is supported and if the peer is 180 * sending VHT capabilities, 181 * then htMaxRxAMpduFactor should be 182 * overloaded with VHT maxAMPDULenExp 183 */ 184 sta_ds->htMaxRxAMpduFactor = vht_caps->maxAMPDULenExp; 185 if (session_entry->htSupportedChannelWidthSet) { 186 if (vht_oper && vht_oper->present) 187 sta_ds->vhtSupportedChannelWidthSet = 188 lim_get_vht_ch_width(vht_caps, 189 vht_oper, 190 &assoc_rsp->HTInfo); 191 else 192 sta_ds->vhtSupportedChannelWidthSet = 193 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; 194 } 195 sta_ds->vht_mcs_10_11_supp = 0; 196 if (mac_ctx->mlme_cfg->vht_caps.vht_cap_info. 197 vht_mcs_10_11_supp && 198 assoc_rsp->qcn_ie.present && 199 assoc_rsp->qcn_ie.vht_mcs11_attr.present) 200 sta_ds->vht_mcs_10_11_supp = 201 assoc_rsp->qcn_ie.vht_mcs11_attr. 202 vht_mcs_10_11_supp; 203 } 204 205 lim_update_stads_he_caps(mac_ctx, sta_ds, assoc_rsp, 206 session_entry, beacon); 207 208 lim_update_stads_eht_caps(mac_ctx, sta_ds, assoc_rsp, 209 session_entry, beacon); 210 211 if (lim_is_sta_he_capable(sta_ds)) 212 he_cap = &assoc_rsp->he_cap; 213 214 if (lim_is_sta_eht_capable(sta_ds)) 215 eht_cap = &assoc_rsp->eht_cap; 216 217 if (session_entry->lim_join_req) 218 bss_desc = &session_entry->lim_join_req->bssDescription; 219 220 if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates, 221 assoc_rsp->HTCaps.supportedMCSSet, 222 false, session_entry, 223 vht_caps, he_cap, eht_cap, 224 sta_ds, bss_desc) != 225 QDF_STATUS_SUCCESS) { 226 pe_err("could not get rateset and extended rate set"); 227 return; 228 } 229 sta_ds->vhtSupportedRxNss = 230 ((sta_ds->supportedRates.vhtTxMCSMap & MCSMAPMASK2x2) 231 == MCSMAPMASK2x2) ? 1 : 2; 232 233 /* If one of the rates is 11g rates, set the ERP mode. */ 234 if ((phy_mode == WNI_CFG_PHY_MODE_11G) && 235 sirIsArate(sta_ds->supportedRates.llaRates[0] & 0x7f)) 236 sta_ds->erpEnabled = eHAL_SET; 237 238 /* Could not get prop rateset from CFG. Log error. */ 239 sta_ds->qosMode = 0; 240 sta_ds->lleEnabled = 0; 241 242 /* update TSID to UP mapping */ 243 if (qos_mode) { 244 if (assoc_rsp->edcaPresent) { 245 QDF_STATUS status; 246 247 qdf_mem_copy(&sta_ds->qos.peer_edca_params, 248 &assoc_rsp->edca, 249 sizeof(assoc_rsp->edca)); 250 251 status = 252 sch_beacon_edca_process(mac_ctx, 253 &assoc_rsp->edca, session_entry); 254 pe_debug("Edca set update based on AssocRsp: status %d", 255 status); 256 if (status != QDF_STATUS_SUCCESS) { 257 pe_err("Edca error in AssocResp"); 258 } else { 259 /* update default tidmap based on ACM */ 260 sta_ds->qosMode = 1; 261 sta_ds->lleEnabled = 1; 262 } 263 } 264 } 265 266 sta_ds->wmeEnabled = 0; 267 sta_ds->wsmEnabled = 0; 268 if (session_entry->limWmeEnabled && assoc_rsp->wmeEdcaPresent) { 269 QDF_STATUS status; 270 271 qdf_mem_copy(&sta_ds->qos.peer_edca_params, 272 &assoc_rsp->edca, 273 sizeof(assoc_rsp->edca)); 274 275 status = sch_beacon_edca_process(mac_ctx, &assoc_rsp->edca, 276 session_entry); 277 pe_debug("WME Edca set update based on AssocRsp: status %d", 278 status); 279 280 if (status != QDF_STATUS_SUCCESS) 281 pe_err("WME Edca error in AssocResp - ignoring"); 282 283 else { 284 /* update default tidmap based on HashACM */ 285 sta_ds->qosMode = 1; 286 sta_ds->wmeEnabled = 1; 287 } 288 } else { 289 /* 290 * We received assoc rsp from a legacy AP. 291 * So fill in the default local EDCA params. 292 * This is needed (refer to bug #14989) as we'll 293 * be passing the gLimEdcaParams to HAL in 294 * lim_process_sta_mlm_add_bss_rsp(). 295 */ 296 sch_set_default_edca_params(mac_ctx, session_entry); 297 } 298 299 if (qos_mode && (!sta_ds->qosMode) && 300 sta_ds->mlmStaContext.htCapability) { 301 /* 302 * Enable QOS for all HT AP's even though WMM 303 * or 802.11E IE is not present 304 */ 305 sta_ds->qosMode = 1; 306 sta_ds->wmeEnabled = 1; 307 } 308 if (session_entry->limRmfEnabled) 309 sta_ds->rmfEnabled = 1; 310 311 if (session_entry->vhtCapability && assoc_rsp->oper_mode_ntf.present) { 312 /** 313 * OMN IE is present in the Assoc response, but the channel 314 * width/Rx NSS update will happen through the peer_assoc cmd. 315 */ 316 omn_ie_ch_width = assoc_rsp->oper_mode_ntf.chanWidth; 317 pe_debug("OMN IE present in re/assoc rsp, omn_ie_ch_width: %d", 318 omn_ie_ch_width); 319 lim_update_omn_ie_ch_width(session_entry->vdev, 320 omn_ie_ch_width); 321 } 322 323 if (lim_process_srp_ie(assoc_rsp, sta_ds) == QDF_STATUS_SUCCESS) 324 lim_update_vdev_sr_elements(session_entry, sta_ds); 325 } 326 327 /** 328 * lim_update_ric_data() - update session with ric data 329 * @mac_ctx: Pointer to Global MAC structure 330 * @session_entry: PE session handle 331 * @assoc_rsp: pointer to assoc response 332 * 333 * This function is called by lim_process_assoc_rsp_frame() to 334 * update PE session context with RIC data. 335 * 336 * Return: None 337 */ lim_update_ric_data(struct mac_context * mac_ctx,struct pe_session * session_entry,tpSirAssocRsp assoc_rsp)338 static void lim_update_ric_data(struct mac_context *mac_ctx, 339 struct pe_session *session_entry, tpSirAssocRsp assoc_rsp) 340 { 341 if (session_entry->ricData) { 342 qdf_mem_free(session_entry->ricData); 343 session_entry->ricData = NULL; 344 session_entry->RICDataLen = 0; 345 } 346 if (assoc_rsp->ricPresent) { 347 session_entry->RICDataLen = 348 assoc_rsp->num_RICData * sizeof(tDot11fIERICDataDesc); 349 if (session_entry->RICDataLen) { 350 session_entry->ricData = 351 qdf_mem_malloc(session_entry->RICDataLen); 352 if (!session_entry->ricData) 353 session_entry->RICDataLen = 0; 354 else 355 qdf_mem_copy(session_entry->ricData, 356 &assoc_rsp->RICData[0], 357 session_entry->RICDataLen); 358 } else { 359 pe_err("RIC data not present"); 360 } 361 } else { 362 session_entry->RICDataLen = 0; 363 session_entry->ricData = NULL; 364 } 365 return; 366 } 367 368 #ifdef FEATURE_WLAN_ESE 369 /** 370 * lim_update_ese_tspec() - update session with Tspec info. 371 * @mac_ctx: Pointer to Global MAC structure 372 * @session_entry: PE session handle 373 * @assoc_rsp: pointer to assoc response 374 * 375 * This function is called by lim_process_assoc_rsp_frame() to 376 * update PE session context with Tspec data. 377 * 378 * Return: None 379 */ lim_update_ese_tspec(struct mac_context * mac_ctx,struct pe_session * session_entry,tpSirAssocRsp assoc_rsp)380 static void lim_update_ese_tspec(struct mac_context *mac_ctx, 381 struct pe_session *session_entry, tpSirAssocRsp assoc_rsp) 382 { 383 if (session_entry->tspecIes) { 384 qdf_mem_free(session_entry->tspecIes); 385 session_entry->tspecIes = NULL; 386 session_entry->tspecLen = 0; 387 } 388 if (assoc_rsp->tspecPresent) { 389 pe_debug("Tspec EID present in assoc rsp"); 390 session_entry->tspecLen = 391 assoc_rsp->num_tspecs * sizeof(tDot11fIEWMMTSPEC); 392 if (session_entry->tspecLen) { 393 session_entry->tspecIes = 394 qdf_mem_malloc(session_entry->tspecLen); 395 if (!session_entry->tspecIes) 396 session_entry->tspecLen = 0; 397 else 398 qdf_mem_copy(session_entry->tspecIes, 399 &assoc_rsp->TSPECInfo[0], 400 session_entry->tspecLen); 401 } else { 402 pe_err("TSPEC has Zero length"); 403 } 404 } else { 405 session_entry->tspecLen = 0; 406 session_entry->tspecIes = NULL; 407 } 408 return; 409 } 410 411 /** 412 * lim_update_ese_tsm() - update session with TSM info. 413 * @mac_ctx: Pointer to Global MAC structure 414 * @session_entry: PE session handle 415 * @assoc_rsp: pointer to assoc response 416 * 417 * This function is called by lim_process_assoc_rsp_frame() to 418 * update PE session context with TSM IE data and send 419 * eWNI_TSM_IE_IND to SME. 420 * 421 * Return: None 422 */ lim_update_ese_tsm(struct mac_context * mac_ctx,struct pe_session * session_entry,tpSirAssocRsp assoc_rsp)423 static void lim_update_ese_tsm(struct mac_context *mac_ctx, 424 struct pe_session *session_entry, tpSirAssocRsp assoc_rsp) 425 { 426 uint8_t cnt = 0; 427 tpEseTSMContext tsm_ctx; 428 429 pe_debug("TSM IE Present in Reassoc Rsp"); 430 /* 431 * Start the TSM timer only if the TSPEC 432 * Ie is present in the reassoc rsp 433 */ 434 if (!assoc_rsp->tspecPresent) { 435 pe_debug("TSM present but TSPEC IE not present"); 436 return; 437 } 438 tsm_ctx = &session_entry->eseContext.tsm; 439 /* Find the TSPEC IE with VO user priority */ 440 for (cnt = 0; cnt < assoc_rsp->num_tspecs; cnt++) { 441 if (upToAc(assoc_rsp->TSPECInfo[cnt].user_priority) == 442 QCA_WLAN_AC_VO) { 443 tsm_ctx->tid = 444 assoc_rsp->TSPECInfo[cnt].user_priority; 445 qdf_mem_copy(&tsm_ctx->tsmInfo, 446 &assoc_rsp->tsmIE, sizeof(struct ese_tsm_ie)); 447 lim_send_sme_tsm_ie_ind(mac_ctx, 448 session_entry, assoc_rsp->tsmIE.tsid, 449 assoc_rsp->tsmIE.state, 450 assoc_rsp->tsmIE.msmt_interval); 451 if (tsm_ctx->tsmInfo.state) 452 tsm_ctx->tsmMetrics.RoamingCount++; 453 break; 454 } 455 } 456 } 457 #endif 458 459 /** 460 * lim_update_stads_ext_cap() - update sta ds with ext cap 461 * @mac_ctx: Pointer to Global MAC structure 462 * @session_entry: PE session handle 463 * @assoc_rsp: pointer to assoc response 464 * 465 * This function is called by lim_process_assoc_rsp_frame() to 466 * update STA DS with ext capabilities. 467 * 468 * Return: None 469 */ lim_update_stads_ext_cap(struct mac_context * mac_ctx,struct pe_session * session_entry,tpSirAssocRsp assoc_rsp,tpDphHashNode sta_ds)470 static void lim_update_stads_ext_cap(struct mac_context *mac_ctx, 471 struct pe_session *session_entry, tpSirAssocRsp assoc_rsp, 472 tpDphHashNode sta_ds) 473 { 474 struct s_ext_cap *ext_cap; 475 struct wlan_objmgr_vdev *vdev; 476 struct vdev_mlme_obj *mlme_obj; 477 478 if (!assoc_rsp->ExtCap.present) { 479 sta_ds->timingMeasCap = 0; 480 #ifdef FEATURE_WLAN_TDLS 481 mlme_set_tdls_prohibited(session_entry->vdev, false); 482 mlme_set_tdls_chan_switch_prohibited(session_entry->vdev, 483 false); 484 #endif 485 pe_debug("ExtCap not present"); 486 return; 487 } 488 489 ext_cap = (struct s_ext_cap *)assoc_rsp->ExtCap.bytes; 490 lim_set_stads_rtt_cap(sta_ds, ext_cap, mac_ctx); 491 492 vdev = session_entry->vdev; 493 if (vdev) { 494 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 495 if (!mlme_obj) 496 pe_err("vdev component object is NULL"); 497 else 498 mlme_obj->ext_vdev_ptr->connect_info.timing_meas_cap = 499 sta_ds->timingMeasCap; 500 } 501 502 #ifdef FEATURE_WLAN_TDLS 503 mlme_set_tdls_prohibited(session_entry->vdev, ext_cap->tdls_prohibited); 504 mlme_set_tdls_chan_switch_prohibited(session_entry->vdev, 505 ext_cap->tdls_chan_swit_prohibited); 506 ; 507 pe_debug("ExtCap: tdls_prohibited: %d tdls_chan_swit_prohibited: %d", 508 ext_cap->tdls_prohibited, 509 ext_cap->tdls_chan_swit_prohibited); 510 #endif 511 lim_set_peer_twt_cap(session_entry, ext_cap); 512 } 513 514 /** 515 * lim_stop_reassoc_retry_timer() - Cleanup after reassoc response is received 516 * @mac_ctx: Global MAC context 517 * 518 * Stop the reassoc retry timer and release the stored reassoc request. 519 * 520 * Return: None 521 */ lim_stop_reassoc_retry_timer(struct mac_context * mac_ctx)522 static void lim_stop_reassoc_retry_timer(struct mac_context *mac_ctx) 523 { 524 mac_ctx->lim.reAssocRetryAttempt = 0; 525 if ((mac_ctx->lim.pe_session) 526 && (NULL != 527 mac_ctx->lim.pe_session->pLimMlmReassocRetryReq)) { 528 qdf_mem_free( 529 mac_ctx->lim.pe_session->pLimMlmReassocRetryReq); 530 mac_ctx->lim.pe_session->pLimMlmReassocRetryReq = NULL; 531 } 532 lim_deactivate_and_change_timer(mac_ctx, eLIM_REASSOC_FAIL_TIMER); 533 } 534 lim_get_nss_supported_by_ap(tDot11fIEVHTCaps * vht_caps,tDot11fIEHTCaps * ht_caps,tDot11fIEhe_cap * he_caps)535 uint8_t lim_get_nss_supported_by_ap(tDot11fIEVHTCaps *vht_caps, 536 tDot11fIEHTCaps *ht_caps, 537 tDot11fIEhe_cap *he_caps) 538 { 539 if (he_caps->present) { 540 if ((he_caps->rx_he_mcs_map_lt_80 & 0xC0) != 0xC0) 541 return NSS_4x4_MODE; 542 543 if ((he_caps->rx_he_mcs_map_lt_80 & 0x30) != 0x30) 544 return NSS_3x3_MODE; 545 546 if ((he_caps->rx_he_mcs_map_lt_80 & 0x0C) != 0x0C) 547 return NSS_2x2_MODE; 548 } else if (vht_caps->present) { 549 if ((vht_caps->rxMCSMap & 0xC0) != 0xC0) 550 return NSS_4x4_MODE; 551 552 if ((vht_caps->rxMCSMap & 0x30) != 0x30) 553 return NSS_3x3_MODE; 554 555 if ((vht_caps->rxMCSMap & 0x0C) != 0x0C) 556 return NSS_2x2_MODE; 557 } else if (ht_caps->present) { 558 if (ht_caps->supportedMCSSet[3]) 559 return NSS_4x4_MODE; 560 561 if (ht_caps->supportedMCSSet[2]) 562 return NSS_3x3_MODE; 563 564 if (ht_caps->supportedMCSSet[1]) 565 return NSS_2x2_MODE; 566 } 567 568 return NSS_1x1_MODE; 569 } 570 571 #ifdef WLAN_FEATURE_11AX lim_process_he_info(tpSirProbeRespBeacon beacon,tpDphHashNode sta_ds)572 static void lim_process_he_info(tpSirProbeRespBeacon beacon, 573 tpDphHashNode sta_ds) 574 { 575 if (beacon->he_op.present) 576 sta_ds->parsed_ies.he_operation = beacon->he_op; 577 } 578 #else lim_process_he_info(tpSirProbeRespBeacon beacon,tpDphHashNode sta_ds)579 static inline void lim_process_he_info(tpSirProbeRespBeacon beacon, 580 tpDphHashNode sta_ds) 581 { 582 } 583 #endif 584 585 #ifdef WLAN_FEATURE_SR lim_process_srp_ie(tpSirAssocRsp ar,tpDphHashNode sta_ds)586 QDF_STATUS lim_process_srp_ie(tpSirAssocRsp ar, tpDphHashNode sta_ds) 587 { 588 QDF_STATUS status = QDF_STATUS_E_NOSUPPORT; 589 590 if (ar->srp_ie.present) { 591 sta_ds->parsed_ies.srp_ie = ar->srp_ie; 592 status = QDF_STATUS_SUCCESS; 593 } 594 595 return status; 596 } 597 #endif 598 599 #ifdef WLAN_FEATURE_11BE lim_process_eht_info(tpSirProbeRespBeacon beacon,tpDphHashNode sta_ds)600 static void lim_process_eht_info(tpSirProbeRespBeacon beacon, 601 tpDphHashNode sta_ds) 602 { 603 if (beacon->eht_op.present) 604 sta_ds->parsed_ies.eht_operation = beacon->eht_op; 605 } 606 #else lim_process_eht_info(tpSirProbeRespBeacon beacon,tpDphHashNode sta_ds)607 static inline void lim_process_eht_info(tpSirProbeRespBeacon beacon, 608 tpDphHashNode sta_ds) 609 { 610 } 611 #endif 612 613 #define MAX_RETRY_TIMER 1500 614 static QDF_STATUS lim_handle_pmfcomeback_timer(struct pe_session * session_entry,tpSirAssocRsp assoc_rsp)615 lim_handle_pmfcomeback_timer(struct pe_session *session_entry, 616 tpSirAssocRsp assoc_rsp) 617 { 618 uint16_t timeout_value; 619 620 if (session_entry->opmode != QDF_STA_MODE) 621 return QDF_STATUS_E_FAILURE; 622 623 if (session_entry->limRmfEnabled && 624 session_entry->pmf_retry_timer_info.retried && 625 assoc_rsp->status_code == STATUS_ASSOC_REJECTED_TEMPORARILY) { 626 pe_debug("Already retry in progress"); 627 return QDF_STATUS_SUCCESS; 628 } 629 630 /* 631 * Handle association Response for sta mode with RMF enabled and TRY 632 * again later with timeout interval and Assoc comeback type 633 */ 634 if (!session_entry->limRmfEnabled || assoc_rsp->status_code != 635 STATUS_ASSOC_REJECTED_TEMPORARILY || 636 !assoc_rsp->TimeoutInterval.present || 637 assoc_rsp->TimeoutInterval.timeoutType != 638 SIR_MAC_TI_TYPE_ASSOC_COMEBACK || 639 session_entry->pmf_retry_timer_info.retried) 640 return QDF_STATUS_E_FAILURE; 641 642 timeout_value = assoc_rsp->TimeoutInterval.timeoutValue; 643 if (timeout_value < 10) { 644 /* 645 * if this value is less than 10 then our timer 646 * will fail to start and due to this we will 647 * never re-attempt. Better modify the timer 648 * value here. 649 */ 650 timeout_value = 10; 651 } 652 timeout_value = QDF_MIN(MAX_RETRY_TIMER, timeout_value); 653 pe_debug("ASSOC res with eSIR_MAC_TRY_AGAIN_LATER recvd.Starting timer to wait timeout: %d", 654 timeout_value); 655 if (QDF_STATUS_SUCCESS != 656 qdf_mc_timer_start(&session_entry->pmf_retry_timer, 657 timeout_value)) { 658 pe_err("Failed to start comeback timer"); 659 return QDF_STATUS_E_FAILURE; 660 } 661 session_entry->pmf_retry_timer_info.retried = true; 662 663 return QDF_STATUS_SUCCESS; 664 } 665 clean_up_ft_sha384(tpSirAssocRsp assoc_rsp,bool sha384_akm)666 static void clean_up_ft_sha384(tpSirAssocRsp assoc_rsp, bool sha384_akm) 667 { 668 if (sha384_akm) { 669 qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk); 670 qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk); 671 } 672 } 673 674 #ifdef WLAN_FEATURE_ROAM_OFFLOAD lim_set_r0kh(tpSirAssocRsp assoc_rsp,struct pe_session * session)675 static void lim_set_r0kh(tpSirAssocRsp assoc_rsp, struct pe_session *session) 676 { 677 struct mlme_legacy_priv *mlme_priv; 678 679 mlme_priv = wlan_vdev_mlme_get_ext_hdl(session->vdev); 680 if (!mlme_priv) 681 return; 682 if (assoc_rsp->sha384_ft_subelem.r0kh_id.present) { 683 mlme_priv->connect_info.ft_info.r0kh_id_len = 684 assoc_rsp->sha384_ft_subelem.r0kh_id.num_PMK_R0_ID; 685 qdf_mem_copy(mlme_priv->connect_info.ft_info.r0kh_id, 686 assoc_rsp->sha384_ft_subelem.r0kh_id.PMK_R0_ID, 687 mlme_priv->connect_info.ft_info.r0kh_id_len); 688 } else if (assoc_rsp->FTInfo.R0KH_ID.present) { 689 mlme_priv->connect_info.ft_info.r0kh_id_len = 690 assoc_rsp->FTInfo.R0KH_ID.num_PMK_R0_ID; 691 qdf_mem_copy(mlme_priv->connect_info.ft_info.r0kh_id, 692 assoc_rsp->FTInfo.R0KH_ID.PMK_R0_ID, 693 mlme_priv->connect_info.ft_info.r0kh_id_len); 694 } else { 695 mlme_priv->connect_info.ft_info.r0kh_id_len = 0; 696 qdf_mem_zero(mlme_priv->connect_info.ft_info.r0kh_id, 697 ROAM_R0KH_ID_MAX_LEN); 698 } 699 } 700 #else 701 static inline lim_set_r0kh(tpSirAssocRsp assoc_rsp,struct pe_session * session)702 void lim_set_r0kh(tpSirAssocRsp assoc_rsp, struct pe_session *session) {} 703 #endif 704 705 /** 706 * lim_get_iot_aggr_sz() - check and get IOT aggr size for configured OUI 707 * 708 * @mac_ctx: Pointer to Global MAC structure 709 * @ie_ptr: Pointer to starting IE in Beacon/Probe Response 710 * @ie_len: Length of all IEs combined 711 * @amsdu_sz: pointer to buffer to store AMSDU size 712 * @ampdu_sz: pointer to buffer to store AMPDU size 713 * 714 * This function is called to find configured vendor specific OUIs 715 * from the IEs in Beacon/Probe Response frames, if one of the OUI is 716 * present, get the configured aggr size for the OUI. 717 * 718 * Return: true if found, false otherwise. 719 */ 720 static bool lim_get_iot_aggr_sz(struct mac_context * mac,uint8_t * ie_ptr,uint32_t ie_len,uint32_t * amsdu_sz,uint32_t * ampdu_sz)721 lim_get_iot_aggr_sz(struct mac_context *mac, uint8_t *ie_ptr, uint32_t ie_len, 722 uint32_t *amsdu_sz, uint32_t *ampdu_sz) 723 { 724 const uint8_t *oui, *vendor_ie; 725 struct wlan_mlme_iot *iot; 726 uint32_t oui_len, aggr_num; 727 int i; 728 729 iot = &mac->mlme_cfg->iot; 730 aggr_num = iot->aggr_num; 731 if (!aggr_num) 732 return false; 733 734 for (i = 0; i < aggr_num; i++) { 735 oui = iot->aggr[i].oui; 736 oui_len = iot->aggr[i].oui_len; 737 vendor_ie = wlan_get_vendor_ie_ptr_from_oui(oui, oui_len, 738 ie_ptr, ie_len); 739 if (!vendor_ie) 740 continue; 741 742 *amsdu_sz = iot->aggr[i].amsdu_sz; 743 *ampdu_sz = iot->aggr[i].ampdu_sz; 744 return true; 745 } 746 747 return false; 748 } 749 750 /** 751 * lim_update_iot_aggr_sz() - check and update IOT aggr size 752 * 753 * @mac_ctx: Pointer to Global MAC structure 754 * @ie_ptr: Pointer to starting IE in Beacon/Probe Response 755 * @ie_len: Length of all IEs combined 756 * @session_entry: A pointer to session entry 757 * 758 * This function is called to find configured vendor specific OUIs 759 * from the IEs in Beacon/Probe Response frames, and set the aggr 760 * size accordingly. 761 * 762 * Return: None 763 */ 764 static void lim_update_iot_aggr_sz(struct mac_context * mac_ctx,uint8_t * ie_ptr,uint32_t ie_len,struct pe_session * session_entry)765 lim_update_iot_aggr_sz(struct mac_context *mac_ctx, uint8_t *ie_ptr, 766 uint32_t ie_len, struct pe_session *session_entry) 767 { 768 int ret; 769 uint32_t amsdu_sz, ampdu_sz; 770 bool iot_hit; 771 772 if (!ie_ptr || !ie_len) 773 return; 774 775 iot_hit = lim_get_iot_aggr_sz(mac_ctx, ie_ptr, ie_len, 776 &amsdu_sz, &du_sz); 777 if (!iot_hit) 778 return; 779 780 pe_debug("Try to set iot amsdu size: %u", amsdu_sz); 781 ret = wma_cli_set_command(session_entry->smeSessionId, 782 GEN_VDEV_PARAM_AMSDU, amsdu_sz, GEN_CMD); 783 if (ret) 784 pe_err("Failed to set iot amsdu size: %d", ret); 785 } 786 787 /** 788 * hdd_cm_update_mcs_rate_set() - Update MCS rate set from HT capability 789 * @vdev: Pointer to vdev object 790 * @ht_cap: pointer to parsed HT capability 791 * 792 * Return: None. 793 */ 794 static inline void lim_update_mcs_rate_set(struct wlan_objmgr_vdev * vdev,tDot11fIEHTCaps * ht_cap)795 lim_update_mcs_rate_set(struct wlan_objmgr_vdev *vdev, tDot11fIEHTCaps *ht_cap) 796 { 797 qdf_size_t len = 0; 798 int i; 799 uint32_t *mcs_set; 800 uint8_t dst_rate[VALID_MAX_MCS_INDEX] = {0}; 801 802 mcs_set = (uint32_t *)ht_cap->supportedMCSSet; 803 for (i = 0; i < VALID_MAX_MCS_INDEX; i++) { 804 if (!QDF_GET_BITS(*mcs_set, i, 1)) 805 continue; 806 807 dst_rate[len++] = i; 808 } 809 810 mlme_set_mcs_rate(vdev, dst_rate, len); 811 } 812 813 #ifdef WLAN_FEATURE_11BE 814 /** 815 * lim_update_sta_vdev_punc() - Update puncture set according to assoc resp 816 * @psoc: Pointer to psoc object 817 * @vdev_id: vdev id 818 * @assoc_resp: pointer to parsed associate response 819 * 820 * Return: None. 821 */ 822 static QDF_STATUS lim_update_sta_vdev_punc(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,tpSirAssocRsp assoc_resp)823 lim_update_sta_vdev_punc(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 824 tpSirAssocRsp assoc_resp) 825 { 826 struct wlan_objmgr_vdev *vdev; 827 struct wlan_channel *des_chan; 828 enum phy_ch_width ori_bw; 829 uint16_t ori_puncture_bitmap; 830 uint16_t primary_puncture_bitmap = 0; 831 qdf_freq_t center_freq_320; 832 uint8_t band_mask; 833 834 if (!assoc_resp->eht_op.disabled_sub_chan_bitmap_present) 835 return QDF_STATUS_SUCCESS; 836 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 837 WLAN_LEGACY_MAC_ID); 838 if (!vdev) { 839 pe_err("vdev not found for id: %d", vdev_id); 840 return QDF_STATUS_E_FAILURE; 841 } 842 843 des_chan = wlan_vdev_mlme_get_des_chan(vdev); 844 ori_puncture_bitmap = 845 *(uint16_t *)assoc_resp->eht_op.disabled_sub_chan_bitmap; 846 847 ori_bw = wlan_mlme_convert_eht_op_bw_to_phy_ch_width( 848 assoc_resp->eht_op.channel_width); 849 850 if (ori_bw == CH_WIDTH_320MHZ) { 851 if (WLAN_REG_IS_24GHZ_CH_FREQ(des_chan->ch_freq)) 852 band_mask = BIT(REG_BAND_2G); 853 else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(des_chan->ch_freq)) 854 band_mask = BIT(REG_BAND_6G); 855 else 856 band_mask = BIT(REG_BAND_5G); 857 center_freq_320 = wlan_reg_chan_band_to_freq( 858 wlan_vdev_get_pdev(vdev), 859 assoc_resp->eht_op.ccfs1, 860 band_mask); 861 } else { 862 center_freq_320 = 0; 863 } 864 wlan_reg_extract_puncture_by_bw(ori_bw, ori_puncture_bitmap, 865 des_chan->ch_freq, 866 center_freq_320, 867 CH_WIDTH_20MHZ, 868 &primary_puncture_bitmap); 869 if (primary_puncture_bitmap) { 870 pe_err("sta vdev %d freq %d assoc rsp bw %d puncture 0x%x primary chan is punctured", 871 vdev_id, des_chan->ch_freq, ori_bw, ori_puncture_bitmap); 872 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 873 return QDF_STATUS_E_FAILURE; 874 } 875 if (des_chan->ch_width == ori_bw) 876 des_chan->puncture_bitmap = ori_puncture_bitmap; 877 else 878 wlan_reg_extract_puncture_by_bw(ori_bw, ori_puncture_bitmap, 879 des_chan->ch_freq, 880 center_freq_320, 881 des_chan->ch_width, 882 &des_chan->puncture_bitmap); 883 pe_debug("sta vdev %d freq %d assoc rsp bw %d puncture 0x%x 320M center frequency %d intersect bw %d puncture 0x%x", 884 vdev_id, des_chan->ch_freq, ori_bw, ori_puncture_bitmap, 885 center_freq_320, des_chan->ch_width, 886 des_chan->puncture_bitmap); 887 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 888 889 return QDF_STATUS_SUCCESS; 890 } 891 #else 892 static QDF_STATUS lim_update_sta_vdev_punc(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,tpSirAssocRsp assoc_resp)893 lim_update_sta_vdev_punc(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 894 tpSirAssocRsp assoc_resp) 895 { 896 return QDF_STATUS_SUCCESS; 897 } 898 #endif 899 900 /** 901 * hdd_cm_update_rate_set() - Update rate set according to assoc resp 902 * @psoc: Pointer to psoc object 903 * @vdev_id: vdev id 904 * @assoc_resp: pointer to parsed associate response 905 * 906 * Return: None. 907 */ 908 static void lim_update_vdev_rate_set(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,tpSirAssocRsp assoc_resp)909 lim_update_vdev_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, 910 tpSirAssocRsp assoc_resp) 911 { 912 struct wlan_objmgr_vdev *vdev; 913 914 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 915 WLAN_LEGACY_MAC_ID); 916 if (!vdev) { 917 pe_err("vdev not found for id: %d", vdev_id); 918 return; 919 } 920 921 if (assoc_resp->suppRatesPresent && assoc_resp->supportedRates.numRates) 922 mlme_set_opr_rate(vdev, assoc_resp->supportedRates.rate, 923 assoc_resp->supportedRates.numRates); 924 925 if (assoc_resp->extendedRatesPresent && 926 assoc_resp->extendedRates.numRates) 927 mlme_set_ext_opr_rate(vdev, 928 assoc_resp->extendedRates.rate, 929 assoc_resp->extendedRates.numRates); 930 else 931 mlme_clear_ext_opr_rate(vdev); 932 933 if (assoc_resp->HTCaps.present) 934 lim_update_mcs_rate_set(vdev, &assoc_resp->HTCaps); 935 else 936 mlme_clear_mcs_rate(vdev); 937 938 wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); 939 } 940 941 #ifdef WLAN_FEATURE_11BE_MLO 942 static void lim_process_assoc_rsp_t2lm(struct pe_session * session,tpSirAssocRsp assoc_rsp)943 lim_process_assoc_rsp_t2lm(struct pe_session *session, 944 tpSirAssocRsp assoc_rsp) 945 { 946 struct wlan_objmgr_vdev *vdev; 947 struct wlan_t2lm_context *t2lm_ctx; 948 struct wlan_mlo_dev_context *mlo_dev_ctx; 949 struct wlan_objmgr_psoc *psoc; 950 951 if (!session || !assoc_rsp) { 952 pe_err("invalid input parameters"); 953 return; 954 } 955 956 vdev = session->vdev; 957 if (!vdev || !wlan_vdev_mlme_is_mlo_vdev(vdev)) 958 return; 959 960 psoc = wlan_vdev_get_psoc(vdev); 961 if (!psoc) 962 return; 963 964 if (!wlan_mlme_get_t2lm_negotiation_supported(psoc)) { 965 pe_err_rl("T2LM negotiation not supported"); 966 return; 967 } 968 969 mlo_dev_ctx = wlan_vdev_get_mlo_dev_ctx(vdev); 970 if (!mlo_dev_ctx) { 971 pe_err("ml dev ctx is null"); 972 return; 973 } 974 975 if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) 976 return; 977 978 if (assoc_rsp->t2lm_ctx.upcoming_t2lm.t2lm.direction == 979 WLAN_T2LM_INVALID_DIRECTION && 980 assoc_rsp->t2lm_ctx.established_t2lm.t2lm.direction == 981 WLAN_T2LM_INVALID_DIRECTION) { 982 pe_debug("No t2lm IE"); 983 return; 984 } 985 986 t2lm_ctx = &mlo_dev_ctx->sta_ctx->copied_t2lm_ie_assoc_rsp; 987 988 if (assoc_rsp->t2lm_ctx.established_t2lm.t2lm.expected_duration_present && 989 !assoc_rsp->t2lm_ctx.established_t2lm.t2lm.mapping_switch_time_present && 990 assoc_rsp->t2lm_ctx.established_t2lm.t2lm.direction != 991 WLAN_T2LM_INVALID_DIRECTION) { 992 qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm, 993 &assoc_rsp->t2lm_ctx.established_t2lm.t2lm, 994 sizeof(struct wlan_t2lm_info)); 995 } 996 997 if (assoc_rsp->t2lm_ctx.upcoming_t2lm.t2lm.mapping_switch_time_present && 998 assoc_rsp->t2lm_ctx.established_t2lm.t2lm.direction != 999 WLAN_T2LM_INVALID_DIRECTION) { 1000 qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm, 1001 &assoc_rsp->t2lm_ctx.upcoming_t2lm.t2lm, 1002 sizeof(struct wlan_t2lm_info)); 1003 } 1004 } 1005 #else 1006 static inline void lim_process_assoc_rsp_t2lm(struct pe_session * session,tpSirAssocRsp assoc_rsp)1007 lim_process_assoc_rsp_t2lm(struct pe_session *session, 1008 tpSirAssocRsp assoc_rsp) 1009 { 1010 } 1011 #endif 1012 1013 #ifdef WLAN_FEATURE_11BE_MLO 1014 /** 1015 * lim_cache_emlsr_params() - cache the EMLSR parameters in ML STA context 1016 * @session_entry: session entry 1017 * @assoc_rsp: pointer to parsed associate response 1018 * 1019 * Return: None 1020 */ lim_cache_emlsr_params(struct pe_session * session_entry,tpSirAssocRsp assoc_rsp)1021 static void lim_cache_emlsr_params(struct pe_session *session_entry, 1022 tpSirAssocRsp assoc_rsp) 1023 { 1024 struct wlan_mlo_sta *sta_ctx; 1025 struct wlan_objmgr_vdev *vdev = session_entry->vdev; 1026 struct emlsr_capability *ml_emlcap; 1027 1028 wlan_objmgr_vdev_get_ref(vdev, WLAN_MLME_SB_ID); 1029 if (!vdev) { 1030 pe_err("vdev is null"); 1031 return; 1032 } 1033 1034 if (!vdev->mlo_dev_ctx) { 1035 pe_err("mlo dev ctx is null"); 1036 goto end; 1037 } 1038 1039 sta_ctx = vdev->mlo_dev_ctx->sta_ctx; 1040 if (!sta_ctx) { 1041 pe_err("sta ctx is null"); 1042 goto end; 1043 } 1044 1045 ml_emlcap = &sta_ctx->emlsr_cap; 1046 1047 if (wlan_vdev_mlme_cap_get(vdev, 1048 WLAN_VDEV_C_EMLSR_CAP)) { 1049 ml_emlcap->emlsr_supp = true; 1050 ml_emlcap->trans_timeout = 1051 assoc_rsp->mlo_ie.mlo_ie.eml_capabilities_info.transition_timeout; 1052 } else { 1053 ml_emlcap->emlsr_supp = false; 1054 ml_emlcap->trans_timeout = 0; 1055 } 1056 1057 pe_debug("EML caps support%d timeout%d", ml_emlcap->emlsr_supp, 1058 ml_emlcap->trans_timeout); 1059 end: 1060 wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID); 1061 } 1062 #else lim_cache_emlsr_params(struct pe_session * session_entry,tpSirAssocRsp assoc_rsp)1063 static inline void lim_cache_emlsr_params(struct pe_session *session_entry, 1064 tpSirAssocRsp assoc_rsp) 1065 { 1066 } 1067 #endif 1068 1069 /** 1070 * lim_send_join_fail_on_vdev() - Send join failure for link vdev 1071 * @mac_ctx: Pointer to Global MAC structure 1072 * @session_entry: Session entry 1073 * @result_code: result code to send in join result 1074 * 1075 * This function sends join failure when bssid of assoc/reassoc 1076 * resp doesn't match with current bssid 1077 */ 1078 static lim_send_join_fail_on_vdev(struct mac_context * mac_ctx,struct pe_session * session_entry,enum eSirResultCodes result_code)1079 void lim_send_join_fail_on_vdev(struct mac_context *mac_ctx, 1080 struct pe_session *session_entry, 1081 enum eSirResultCodes result_code) 1082 { 1083 if (!wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) 1084 return; 1085 1086 session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; 1087 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, 1088 session_entry->peSessionId, 1089 session_entry->limSmeState)); 1090 1091 /* Send Join response to Host */ 1092 lim_handle_sme_join_result( 1093 mac_ctx, result_code, STATUS_UNSPECIFIED_FAILURE, 1094 session_entry); 1095 } 1096 1097 /** 1098 * lim_process_assoc_rsp_frame() - Processes assoc response 1099 * @mac_ctx: Pointer to Global MAC structure 1100 * @rx_packet_info - A pointer to Rx packet info structure 1101 * @frame_body_length - frame body length of reassoc/assoc response frame 1102 * @sub_type - Indicates whether it is Association Response (=0) or 1103 * Reassociation Response (=1) frame 1104 * @session_entry: Session entry 1105 * 1106 * This function is called by limProcessMessageQueue() upon 1107 * Re/Association Response frame reception. 1108 * 1109 * Return: None 1110 */ 1111 void lim_process_assoc_rsp_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,uint32_t frame_body_len,uint8_t subtype,struct pe_session * session_entry)1112 lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, 1113 uint32_t frame_body_len, 1114 uint8_t subtype, struct pe_session *session_entry) 1115 { 1116 uint8_t *body, *ie; 1117 uint16_t caps, ie_len; 1118 tSirMacAddr current_bssid; 1119 tpSirMacMgmtHdr hdr = NULL; 1120 tSirMacCapabilityInfo mac_capab; 1121 tpDphHashNode sta_ds; 1122 tpSirAssocRsp assoc_rsp; 1123 tLimMlmAssocCnf assoc_cnf; 1124 tSchBeaconStruct *beacon; 1125 uint8_t ap_nss; 1126 uint16_t aid; 1127 int8_t rssi; 1128 QDF_STATUS status; 1129 enum ani_akm_type auth_type; 1130 bool sha384_akm, twt_support_in_11n = false; 1131 struct s_ext_cap *ext_cap; 1132 1133 assoc_cnf.resultCode = eSIR_SME_SUCCESS; 1134 /* Update PE session Id */ 1135 assoc_cnf.sessionId = session_entry->peSessionId; 1136 1137 if (LIM_IS_AP_ROLE(session_entry)) { 1138 /* 1139 * Should not have received Re/Association 1140 * Response frame on AP. Log error 1141 */ 1142 pe_err("Should not received Re/Assoc Response in role: %d", 1143 GET_LIM_SYSTEM_ROLE(session_entry)); 1144 return; 1145 } 1146 1147 if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry) || 1148 wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) { 1149 hdr = (tpSirMacMgmtHdr)rx_pkt_info; 1150 rssi = 0; 1151 } else { 1152 hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); 1153 rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); 1154 } 1155 1156 if (!hdr) { 1157 pe_err("LFR3: Reassoc response packet header is NULL"); 1158 return; 1159 } 1160 1161 pe_nofl_rl_info("Assoc rsp RX: subtype %d vdev %d sys role %d lim state %d rssi %d from " QDF_MAC_ADDR_FMT, 1162 subtype, session_entry->vdev_id, 1163 GET_LIM_SYSTEM_ROLE(session_entry), 1164 session_entry->limMlmState, rssi, 1165 QDF_MAC_ADDR_REF(hdr->sa)); 1166 1167 beacon = qdf_mem_malloc(sizeof(tSchBeaconStruct)); 1168 if (!beacon) 1169 return; 1170 1171 if (((subtype == LIM_ASSOC) && 1172 (session_entry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) || 1173 ((subtype == LIM_REASSOC) && 1174 !lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry) && 1175 !MLME_IS_MLO_ROAM_SYNCH_IN_PROGRESS(mac_ctx->psoc, 1176 session_entry->vdev_id) && 1177 ((session_entry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) 1178 && (session_entry->limMlmState != 1179 eLIM_MLM_WT_FT_REASSOC_RSP_STATE) 1180 ))) { 1181 /* Received unexpected Re/Association Response frame */ 1182 pe_debug("Received Re/Assoc rsp in unexpected state: %d on session: %d", 1183 session_entry->limMlmState, session_entry->peSessionId); 1184 if (!hdr->fc.retry) { 1185 if (!(mac_ctx->lim.retry_packet_cnt & 0xf)) { 1186 pe_err("recvd Re/Assoc rsp:not a retry frame"); 1187 lim_print_mlm_state(mac_ctx, LOGE, 1188 session_entry->limMlmState); 1189 } else { 1190 mac_ctx->lim.retry_packet_cnt++; 1191 } 1192 } 1193 qdf_mem_free(beacon); 1194 return; 1195 } 1196 sir_copy_mac_addr(current_bssid, session_entry->bssId); 1197 if (subtype == LIM_ASSOC) { 1198 if (qdf_mem_cmp 1199 (hdr->sa, current_bssid, sizeof(tSirMacAddr))) { 1200 /* 1201 * Received Association Response frame from an entity 1202 * other than one to which request was initiated. 1203 * Ignore this and wait until Assoc Failure Timeout 1204 */ 1205 pe_warn("received AssocRsp from unexpected peer "QDF_MAC_ADDR_FMT, 1206 QDF_MAC_ADDR_REF(hdr->sa)); 1207 1208 if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry)) { 1209 session_entry->is_unexpected_peer_error = true; 1210 qdf_mem_free(beacon); 1211 return; 1212 } 1213 /* 1214 * Send Assoc failure to avoid connection in 1215 * progress state for link vdev. 1216 */ 1217 lim_send_join_fail_on_vdev(mac_ctx, session_entry, 1218 eSIR_SME_ASSOC_REFUSED); 1219 qdf_mem_free(beacon); 1220 return; 1221 } 1222 } else { 1223 if (qdf_mem_cmp 1224 (hdr->sa, session_entry->limReAssocbssId, 1225 sizeof(tSirMacAddr))) { 1226 /* 1227 * Received Reassociation Response frame from an entity 1228 * other than one to which request was initiated. 1229 * Ignore this and wait until Reassoc Failure Timeout. 1230 */ 1231 pe_warn("received ReassocRsp from unexpected peer "QDF_MAC_ADDR_FMT, 1232 QDF_MAC_ADDR_REF(hdr->sa)); 1233 1234 if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry)) { 1235 session_entry->is_unexpected_peer_error = true; 1236 qdf_mem_free(beacon); 1237 return; 1238 } 1239 1240 /* 1241 * Send Reassoc failure to avoid connection in 1242 * progress state for link vdev. 1243 */ 1244 lim_send_join_fail_on_vdev(mac_ctx, session_entry, 1245 eSIR_SME_REASSOC_REFUSED); 1246 qdf_mem_free(beacon); 1247 return; 1248 } 1249 } 1250 1251 assoc_rsp = qdf_mem_malloc(sizeof(*assoc_rsp)); 1252 if (!assoc_rsp) { 1253 qdf_mem_free(beacon); 1254 return; 1255 } 1256 /* Get pointer to Re/Association Response frame body */ 1257 if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry) || 1258 wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) 1259 body = rx_pkt_info + SIR_MAC_HDR_LEN_3A; 1260 else 1261 body = WMA_GET_RX_MPDU_DATA(rx_pkt_info); 1262 /* parse Re/Association Response frame. */ 1263 if (sir_convert_assoc_resp_frame2_struct(mac_ctx, session_entry, body, 1264 frame_body_len, assoc_rsp) == QDF_STATUS_E_FAILURE) { 1265 qdf_mem_free(assoc_rsp); 1266 pe_err("Parse error Assoc resp subtype: %d" "length: %d", 1267 frame_body_len, subtype); 1268 qdf_mem_free(beacon); 1269 return; 1270 } 1271 1272 if (subtype == LIM_REASSOC) { 1273 lim_cp_stats_cstats_log_assoc_resp_evt 1274 (session_entry, CSTATS_DIR_RX, assoc_rsp->status_code, 1275 assoc_rsp->aid, hdr->bssId, hdr->da, 1276 assoc_rsp->HTCaps.present, 1277 assoc_rsp->VHTCaps.present, assoc_rsp->he_cap.present, 1278 assoc_rsp->eht_op.present, true); 1279 } else if (subtype == LIM_ASSOC) { 1280 lim_cp_stats_cstats_log_assoc_resp_evt 1281 (session_entry, CSTATS_DIR_RX, assoc_rsp->status_code, 1282 assoc_rsp->aid, hdr->bssId, hdr->da, 1283 assoc_rsp->HTCaps.present, 1284 assoc_rsp->VHTCaps.present, assoc_rsp->he_cap.present, 1285 assoc_rsp->eht_op.present, false); 1286 } 1287 1288 if (subtype != LIM_REASSOC) { 1289 aid = assoc_rsp->aid & 0x3FFF; 1290 wlan_connectivity_mgmt_event(mac_ctx->psoc, 1291 (struct wlan_frame_hdr *)hdr, 1292 session_entry->vdev_id, 1293 assoc_rsp->status_code, 0, rssi, 1294 0, 0, 0, aid, 1295 WLAN_ASSOC_RSP); 1296 } 1297 1298 if (lim_is_session_eht_capable(session_entry)) { 1299 uint8_t ies_offset; 1300 1301 if (subtype == LIM_ASSOC) 1302 ies_offset = WLAN_ASSOC_RSP_IES_OFFSET; 1303 else 1304 ies_offset = WLAN_REASSOC_REQ_IES_OFFSET; 1305 1306 if (frame_body_len < ies_offset) { 1307 pe_err("frame body length is < ies_offset"); 1308 return; 1309 } 1310 1311 status = lim_strip_and_decode_eht_op( 1312 body + ies_offset, 1313 frame_body_len - ies_offset, 1314 &assoc_rsp->eht_op, 1315 assoc_rsp->VHTOperation, 1316 assoc_rsp->he_op, 1317 assoc_rsp->HTInfo); 1318 1319 if (status != QDF_STATUS_SUCCESS) { 1320 pe_err("Failed to extract eht op"); 1321 return; 1322 } 1323 1324 status = lim_strip_and_decode_eht_cap( 1325 body + ies_offset, 1326 frame_body_len - ies_offset, 1327 &assoc_rsp->eht_cap, 1328 assoc_rsp->he_cap, 1329 session_entry->curr_op_freq); 1330 if (status != QDF_STATUS_SUCCESS) { 1331 pe_err("Failed to extract eht cap"); 1332 return; 1333 } 1334 } 1335 1336 if (!assoc_rsp->suppRatesPresent) { 1337 pe_debug("assoc response does not have supported rate set"); 1338 qdf_mem_copy(&assoc_rsp->supportedRates, 1339 &session_entry->rateSet, 1340 sizeof(tSirMacRateSet)); 1341 } 1342 1343 assoc_cnf.protStatusCode = assoc_rsp->status_code; 1344 if (session_entry->assocRsp) { 1345 pe_warn("session_entry->assocRsp is not NULL freeing it and setting NULL"); 1346 qdf_mem_free(session_entry->assocRsp); 1347 session_entry->assocRsp = NULL; 1348 session_entry->assocRspLen = 0; 1349 } 1350 1351 if (frame_body_len) { 1352 session_entry->assocRsp = qdf_mem_malloc(frame_body_len); 1353 if (session_entry->assocRsp) { 1354 /* 1355 * Store the Assoc response. This is sent 1356 * to csr/hdd in join cnf response. 1357 */ 1358 qdf_mem_copy(session_entry->assocRsp, body, frame_body_len); 1359 session_entry->assocRspLen = frame_body_len; 1360 } 1361 } 1362 1363 lim_update_ric_data(mac_ctx, session_entry, assoc_rsp); 1364 1365 lim_set_r0kh(assoc_rsp, session_entry); 1366 1367 #ifdef FEATURE_WLAN_ESE 1368 lim_update_ese_tspec(mac_ctx, session_entry, assoc_rsp); 1369 #endif 1370 1371 auth_type = session_entry->connected_akm; 1372 sha384_akm = lim_is_sha384_akm(auth_type); 1373 1374 if (lim_get_capability_info(mac_ctx, &caps, session_entry) 1375 != QDF_STATUS_SUCCESS) { 1376 clean_up_ft_sha384(assoc_rsp, sha384_akm); 1377 qdf_mem_free(assoc_rsp); 1378 qdf_mem_free(beacon); 1379 pe_err("could not retrieve Capabilities"); 1380 return; 1381 } 1382 lim_copy_u16((uint8_t *) &mac_capab, caps); 1383 1384 if (assoc_rsp->status_code == STATUS_DENIED_POOR_CHANNEL_CONDITIONS && 1385 assoc_rsp->rssi_assoc_rej.present) { 1386 struct sir_rssi_disallow_lst ap_info = {{0}}; 1387 1388 if (!assoc_rsp->rssi_assoc_rej.retry_delay) 1389 ap_info.expected_rssi = assoc_rsp->rssi_assoc_rej.delta_rssi + 1390 WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info) + 1391 wlan_dlm_get_rssi_denylist_threshold(mac_ctx->pdev); 1392 else 1393 ap_info.expected_rssi = assoc_rsp->rssi_assoc_rej.delta_rssi + 1394 WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); 1395 1396 ap_info.retry_delay = assoc_rsp->rssi_assoc_rej.retry_delay * 1397 QDF_MC_TIMER_TO_MS_UNIT; 1398 qdf_mem_copy(ap_info.bssid.bytes, hdr->sa, QDF_MAC_ADDR_SIZE); 1399 ap_info.reject_reason = REASON_ASSOC_REJECT_OCE; 1400 ap_info.source = ADDED_BY_DRIVER; 1401 ap_info.original_timeout = ap_info.retry_delay; 1402 ap_info.received_time = qdf_mc_timer_get_system_time(); 1403 lim_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info); 1404 } 1405 1406 status = lim_handle_pmfcomeback_timer(session_entry, assoc_rsp); 1407 /* return if retry again timer is started and ignore this assoc resp */ 1408 if (QDF_IS_STATUS_SUCCESS(status)) { 1409 qdf_mem_free(beacon); 1410 clean_up_ft_sha384(assoc_rsp, sha384_akm); 1411 qdf_mem_free(assoc_rsp); 1412 return; 1413 } 1414 1415 /* Stop Association failure timer */ 1416 if (subtype == LIM_ASSOC) 1417 lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER); 1418 else 1419 lim_stop_reassoc_retry_timer(mac_ctx); 1420 1421 if (assoc_rsp->status_code != STATUS_SUCCESS) { 1422 /* 1423 *Re/Association response was received 1424 * either with failure code. 1425 */ 1426 pe_err("received Re/AssocRsp frame failure code: %d", 1427 assoc_rsp->status_code); 1428 /* 1429 * Need to update 'association failure' error counter 1430 * along with STATUS CODE 1431 * Return Assoc confirm to SME with received failure code 1432 */ 1433 assoc_cnf.resultCode = eSIR_SME_ASSOC_REFUSED; 1434 /* Delete Pre-auth context for the associated BSS */ 1435 if (lim_search_pre_auth_list(mac_ctx, hdr->sa)) 1436 lim_delete_pre_auth_node(mac_ctx, hdr->sa); 1437 goto assocReject; 1438 } else if ((assoc_rsp->aid & 0x3FFF) > 2007) { 1439 /* 1440 * Re/Association response was received 1441 * with invalid AID value 1442 */ 1443 pe_err("received Re/AssocRsp frame with invalid aid: %X", 1444 assoc_rsp->aid); 1445 assoc_cnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; 1446 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 1447 /* Send advisory Disassociation frame to AP */ 1448 lim_send_disassoc_mgmt_frame(mac_ctx, 1449 REASON_UNSPEC_FAILURE, 1450 hdr->sa, session_entry, false); 1451 goto assocReject; 1452 } 1453 1454 /* 1455 * If it is FILS connection, check is FILS params are matching 1456 * with Authentication stage. 1457 */ 1458 if (!lim_verify_fils_params_assoc_rsp(mac_ctx, session_entry, 1459 assoc_rsp, &assoc_cnf)) { 1460 pe_err("FILS params does not match"); 1461 assoc_cnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; 1462 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 1463 /* Send advisory Disassociation frame to AP */ 1464 lim_send_disassoc_mgmt_frame(mac_ctx, 1465 REASON_UNSPEC_FAILURE, 1466 hdr->sa, session_entry, false); 1467 goto assocReject; 1468 } 1469 1470 if (assoc_rsp->QosMapSet.present) 1471 qdf_mem_copy(&session_entry->QosMapSet, 1472 &assoc_rsp->QosMapSet, 1473 sizeof(struct qos_map_set)); 1474 else 1475 qdf_mem_zero(&session_entry->QosMapSet, 1476 sizeof(struct qos_map_set)); 1477 1478 if (assoc_rsp->obss_scanparams.present) 1479 lim_update_obss_scanparams(session_entry, 1480 &assoc_rsp->obss_scanparams); 1481 1482 if (lim_is_session_he_capable(session_entry)) { 1483 if (!wlan_cm_is_vdev_roaming(session_entry->vdev)) 1484 lim_set_twt_peer_capabilities( 1485 mac_ctx, 1486 (struct qdf_mac_addr *)current_bssid, 1487 &assoc_rsp->he_cap, 1488 &assoc_rsp->he_op); 1489 1490 } else { 1491 wlan_twt_cfg_get_support_in_11n(mac_ctx->psoc, 1492 &twt_support_in_11n); 1493 if (twt_support_in_11n && session_entry->htCapability && 1494 assoc_rsp->HTCaps.present && assoc_rsp->ExtCap.present) { 1495 ext_cap = (struct s_ext_cap *)assoc_rsp->ExtCap.bytes; 1496 lim_set_twt_ext_capabilities( 1497 mac_ctx, 1498 (struct qdf_mac_addr *)current_bssid, 1499 ext_cap); 1500 } 1501 } 1502 1503 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, 1504 session_entry, 1505 (assoc_rsp->status_code ? QDF_STATUS_E_FAILURE : 1506 QDF_STATUS_SUCCESS), assoc_rsp->status_code); 1507 1508 ap_nss = lim_get_nss_supported_by_ap(&assoc_rsp->VHTCaps, 1509 &assoc_rsp->HTCaps, 1510 &assoc_rsp->he_cap); 1511 1512 if (subtype == LIM_REASSOC) { 1513 pe_debug("Successfully Reassociated with BSS"); 1514 #ifdef FEATURE_WLAN_ESE 1515 if (assoc_rsp->tsmPresent) 1516 lim_update_ese_tsm(mac_ctx, session_entry, assoc_rsp); 1517 #endif 1518 if (session_entry->pLimMlmJoinReq) { 1519 qdf_mem_free(session_entry->pLimMlmJoinReq); 1520 session_entry->pLimMlmJoinReq = NULL; 1521 } 1522 1523 if (session_entry->limAssocResponseData) { 1524 tpSirAssocRsp pre_assoc_rsp; 1525 1526 pre_assoc_rsp = (tpSirAssocRsp) 1527 session_entry->limAssocResponseData; 1528 qdf_mem_free(pre_assoc_rsp->sha384_ft_subelem.gtk); 1529 qdf_mem_free(pre_assoc_rsp->sha384_ft_subelem.igtk); 1530 qdf_mem_free(session_entry->limAssocResponseData); 1531 } 1532 session_entry->limAssocResponseData = (void *)assoc_rsp; 1533 /* 1534 * Store the ReAssocRsp Frame in DphTable 1535 * to be used during processing DelSta and 1536 * DelBss to send AddBss again 1537 */ 1538 sta_ds = 1539 dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 1540 &session_entry->dph.dphHashTable); 1541 1542 if (!sta_ds) { 1543 pe_err("could not get hash entry at DPH for SA: "QDF_MAC_ADDR_FMT, 1544 QDF_MAC_ADDR_REF(hdr->sa)); 1545 assoc_cnf.resultCode = 1546 eSIR_SME_INVALID_ASSOC_RSP_RXED; 1547 assoc_cnf.protStatusCode = 1548 STATUS_UNSPECIFIED_FAILURE; 1549 1550 /* Send advisory Disassociation frame to AP */ 1551 lim_send_disassoc_mgmt_frame(mac_ctx, 1552 REASON_UNSPEC_FAILURE, hdr->sa, 1553 session_entry, false); 1554 goto assocReject; 1555 } 1556 1557 if (ap_nss < session_entry->nss) 1558 session_entry->nss = ap_nss; 1559 1560 lim_objmgr_update_vdev_nss(mac_ctx->psoc, 1561 session_entry->smeSessionId, 1562 session_entry->nss); 1563 lim_update_vdev_rate_set(mac_ctx->psoc, 1564 session_entry->smeSessionId, 1565 assoc_rsp); 1566 1567 if ((session_entry->limMlmState == 1568 eLIM_MLM_WT_FT_REASSOC_RSP_STATE) || 1569 lim_is_roam_synch_in_progress(mac_ctx->psoc, 1570 session_entry)) { 1571 pe_debug("Sending self sta"); 1572 lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, 1573 session_entry, NULL); 1574 lim_update_stads_ext_cap(mac_ctx, session_entry, 1575 assoc_rsp, sta_ds); 1576 /* Store assigned AID for TIM processing */ 1577 session_entry->limAID = assoc_rsp->aid & 0x3FFF; 1578 /* Downgrade the EDCA parameters if needed */ 1579 lim_set_active_edca_params(mac_ctx, 1580 session_entry->gLimEdcaParams, 1581 session_entry); 1582 /* Send the active EDCA parameters to HAL */ 1583 if (!lim_is_roam_synch_in_progress(mac_ctx->psoc, 1584 session_entry)) { 1585 lim_send_edca_params(mac_ctx, 1586 session_entry->gLimEdcaParamsActive, 1587 session_entry->vdev_id, false); 1588 lim_add_ft_sta_self(mac_ctx, 1589 (assoc_rsp->aid & 0x3FFF), 1590 session_entry); 1591 } else { 1592 lim_set_emlsr_caps(mac_ctx, session_entry); 1593 lim_objmgr_update_emlsr_caps(mac_ctx->psoc, 1594 session_entry->vdev_id, 1595 assoc_rsp); 1596 lim_cache_emlsr_params(session_entry, 1597 assoc_rsp); 1598 } 1599 qdf_mem_free(beacon); 1600 return; 1601 } 1602 1603 /* 1604 * If we're re-associating to the same BSS, 1605 * we don't want to invoke delete STA, delete 1606 * BSS, as that would remove the already 1607 * established TSPEC. Just go ahead and re-add 1608 * the BSS, STA with new capability information. 1609 * However, if we're re-associating to a different 1610 * BSS, then follow thru with del STA, del BSS, 1611 * add BSS, add STA. 1612 */ 1613 if (sir_compare_mac_addr(session_entry->bssId, 1614 session_entry->limReAssocbssId)) 1615 lim_handle_add_bss_in_re_assoc_context(mac_ctx, sta_ds, 1616 session_entry); 1617 else { 1618 /* 1619 * reset the uapsd mask settings since 1620 * we're re-associating to new AP 1621 */ 1622 session_entry->gUapsdPerAcDeliveryEnableMask = 0; 1623 session_entry->gUapsdPerAcTriggerEnableMask = 0; 1624 1625 lim_mlo_notify_peer_disconn(session_entry, sta_ds); 1626 if (lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry, 1627 true) != QDF_STATUS_SUCCESS) { 1628 pe_err("Could not cleanup the rx path"); 1629 goto assocReject; 1630 } 1631 } 1632 if (!mlo_roam_is_auth_status_connected(mac_ctx->psoc, 1633 wlan_vdev_get_id(session_entry->vdev))) { 1634 qdf_mem_free(beacon); 1635 return; 1636 } 1637 } 1638 pe_debug("Successfully Associated with BSS " QDF_MAC_ADDR_FMT, 1639 QDF_MAC_ADDR_REF(hdr->sa)); 1640 1641 #ifdef FEATURE_WLAN_ESE 1642 if (session_entry->eseContext.tsm.tsmInfo.state) 1643 session_entry->eseContext.tsm.tsmMetrics.RoamingCount = 0; 1644 #endif 1645 /* Store assigned AID for TIM processing */ 1646 session_entry->limAID = assoc_rsp->aid & 0x3FFF; 1647 1648 /* STA entry was created during pre-assoc state. */ 1649 sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, 1650 &session_entry->dph.dphHashTable); 1651 if (!sta_ds) { 1652 /* Could not add hash table entry */ 1653 pe_err("could not get hash entry at DPH SA: "QDF_MAC_ADDR_FMT, 1654 QDF_MAC_ADDR_REF(hdr->sa)); 1655 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 1656 assoc_cnf.protStatusCode = eSIR_SME_SUCCESS; 1657 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 1658 (uint32_t *) &assoc_cnf); 1659 clean_up_ft_sha384(assoc_rsp, sha384_akm); 1660 /* 1661 * Don't free the assoc rsp if it's cached in pe_session. 1662 * It would be reused in link connect in cases like OWE 1663 * roaming 1664 */ 1665 if (session_entry->limAssocResponseData != assoc_rsp) 1666 qdf_mem_free(assoc_rsp); 1667 qdf_mem_free(beacon); 1668 return; 1669 } 1670 /* Delete Pre-auth context for the associated BSS */ 1671 if (lim_search_pre_auth_list(mac_ctx, hdr->sa)) 1672 lim_delete_pre_auth_node(mac_ctx, hdr->sa); 1673 1674 if (ap_nss < session_entry->nss) 1675 session_entry->nss = ap_nss; 1676 1677 lim_objmgr_update_vdev_nss(mac_ctx->psoc, 1678 session_entry->smeSessionId, 1679 session_entry->nss); 1680 lim_update_vdev_rate_set(mac_ctx->psoc, session_entry->smeSessionId, 1681 assoc_rsp); 1682 if (QDF_IS_STATUS_ERROR(lim_update_sta_vdev_punc( 1683 mac_ctx->psoc, 1684 session_entry->smeSessionId, 1685 assoc_rsp))) { 1686 assoc_cnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; 1687 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 1688 /* Send advisory Disassociation frame to AP */ 1689 lim_send_disassoc_mgmt_frame(mac_ctx, 1690 REASON_UNSPEC_FAILURE, 1691 hdr->sa, session_entry, false); 1692 goto assocReject; 1693 } 1694 1695 lim_objmgr_update_emlsr_caps(mac_ctx->psoc, session_entry->smeSessionId, 1696 assoc_rsp); 1697 1698 lim_process_assoc_rsp_t2lm(session_entry, assoc_rsp); 1699 /* 1700 * Extract the AP capabilities from the beacon that 1701 * was received earlier 1702 */ 1703 ie_len = lim_get_ielen_from_bss_description( 1704 &session_entry->lim_join_req->bssDescription); 1705 ie = (uint8_t *)session_entry->lim_join_req->bssDescription.ieFields; 1706 lim_update_iot_aggr_sz(mac_ctx, ie, ie_len, session_entry); 1707 1708 lim_extract_ap_capabilities(mac_ctx, ie, ie_len, beacon); 1709 1710 if (session_entry->opmode == QDF_STA_MODE) { 1711 lim_enable_cts_to_self_for_exempted_iot_ap( 1712 mac_ctx, session_entry, 1713 ie, ie_len); 1714 } 1715 1716 lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, 1717 session_entry, beacon); 1718 1719 if (lim_is_session_he_capable(session_entry)) { 1720 session_entry->mu_edca_present = assoc_rsp->mu_edca_present; 1721 if (session_entry->mu_edca_present) { 1722 pe_debug("Save MU EDCA params to session"); 1723 session_entry->ap_mu_edca_params[QCA_WLAN_AC_BE] = 1724 assoc_rsp->mu_edca.acbe; 1725 session_entry->ap_mu_edca_params[QCA_WLAN_AC_BK] = 1726 assoc_rsp->mu_edca.acbk; 1727 session_entry->ap_mu_edca_params[QCA_WLAN_AC_VI] = 1728 assoc_rsp->mu_edca.acvi; 1729 session_entry->ap_mu_edca_params[QCA_WLAN_AC_VO] = 1730 assoc_rsp->mu_edca.acvo; 1731 } 1732 } 1733 1734 if (beacon->VHTCaps.present) 1735 sta_ds->parsed_ies.vht_caps = beacon->VHTCaps; 1736 if (beacon->HTCaps.present) 1737 sta_ds->parsed_ies.ht_caps = beacon->HTCaps; 1738 if (beacon->hs20vendor_ie.present) 1739 sta_ds->parsed_ies.hs20vendor_ie = beacon->hs20vendor_ie; 1740 if (beacon->HTInfo.present) 1741 sta_ds->parsed_ies.ht_operation = beacon->HTInfo; 1742 if (beacon->VHTOperation.present) 1743 sta_ds->parsed_ies.vht_operation = beacon->VHTOperation; 1744 1745 lim_process_he_info(beacon, sta_ds); 1746 if (lim_process_srp_ie(assoc_rsp, sta_ds) == QDF_STATUS_SUCCESS) 1747 lim_update_vdev_sr_elements(session_entry, sta_ds); 1748 1749 if (lim_is_session_eht_capable(session_entry)) 1750 lim_process_eht_info(beacon, sta_ds); 1751 1752 if (mac_ctx->lim.gLimProtectionControl != 1753 MLME_FORCE_POLICY_PROTECTION_DISABLE) 1754 lim_decide_sta_protection_on_assoc(mac_ctx, beacon, 1755 session_entry); 1756 1757 if (beacon->erpPresent) { 1758 if (beacon->erpIEInfo.barkerPreambleMode) 1759 session_entry->beaconParams.fShortPreamble = false; 1760 else 1761 session_entry->beaconParams.fShortPreamble = true; 1762 } 1763 1764 #ifdef FEATURE_WLAN_DIAG_SUPPORT 1765 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_CONNECTED, session_entry, 1766 QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS); 1767 #endif 1768 lim_update_stads_ext_cap(mac_ctx, session_entry, assoc_rsp, sta_ds); 1769 1770 /* Update the BSS Entry, this entry was added during preassoc. */ 1771 if (QDF_STATUS_SUCCESS == 1772 lim_sta_send_add_bss(mac_ctx, assoc_rsp, beacon, 1773 &session_entry->lim_join_req->bssDescription, 1774 true, session_entry)) { 1775 clean_up_ft_sha384(assoc_rsp, sha384_akm); 1776 if (session_entry->limAssocResponseData != assoc_rsp) 1777 qdf_mem_free(assoc_rsp); 1778 1779 qdf_mem_free(beacon); 1780 1781 return; 1782 } 1783 1784 pe_err("vdev:%d could not update the bss entry", 1785 session_entry->vdev_id); 1786 assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; 1787 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE; 1788 1789 assocReject: 1790 if (subtype == LIM_ASSOC || 1791 (subtype == LIM_REASSOC && 1792 session_entry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)) { 1793 pe_err("Assoc Rejected by the peer mlmestate: %d sessionid: %d Reason: %d MACADDR:" 1794 QDF_MAC_ADDR_FMT, session_entry->limMlmState, 1795 session_entry->peSessionId, assoc_cnf.resultCode, 1796 QDF_MAC_ADDR_REF(hdr->sa)); 1797 1798 session_entry->limMlmState = eLIM_MLM_IDLE_STATE; 1799 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, 1800 session_entry->peSessionId, 1801 session_entry->limMlmState)); 1802 if (session_entry->pLimMlmJoinReq) { 1803 qdf_mem_free(session_entry->pLimMlmJoinReq); 1804 session_entry->pLimMlmJoinReq = NULL; 1805 } 1806 1807 if (subtype == LIM_ASSOC) { 1808 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF, 1809 (uint32_t *) &assoc_cnf); 1810 } else { 1811 assoc_cnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; 1812 lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF, 1813 (uint32_t *)&assoc_cnf); 1814 } 1815 } else { 1816 lim_restore_pre_reassoc_state(mac_ctx, 1817 eSIR_SME_REASSOC_REFUSED, 1818 assoc_cnf.protStatusCode, 1819 session_entry); 1820 } 1821 1822 qdf_mem_free(beacon); 1823 qdf_mem_free(assoc_rsp->sha384_ft_subelem.gtk); 1824 qdf_mem_free(assoc_rsp->sha384_ft_subelem.igtk); 1825 qdf_mem_free(assoc_rsp); 1826 1827 return; 1828 } 1829