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 /* 21 * This file lim_link_monitoring_algo.cc contains the code for 22 * Link monitoring algorithm on AP and heart beat failure 23 * handling on STA. 24 * Author: Chandra Modumudi 25 * Date: 03/01/02 26 * History:- 27 * Date Modified by Modification Information 28 * -------------------------------------------------------------------- 29 * 30 */ 31 32 #include "ani_global.h" 33 #include "wni_cfg.h" 34 35 #include "sch_api.h" 36 #include "utils_api.h" 37 #include "lim_assoc_utils.h" 38 #include "lim_types.h" 39 #include "lim_utils.h" 40 #include "lim_prop_exts_utils.h" 41 42 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 43 #include "host_diag_core_log.h" 44 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 45 #include "lim_ft_defs.h" 46 #include "lim_session.h" 47 #include "lim_ser_des_utils.h" 48 #include "wlan_dlm_api.h" 49 50 /** 51 * lim_delete_sta_util - utility function for deleting station context 52 * 53 * @mac_ctx: global MAC context 54 * @msg: pointer to delete station context 55 * @session_entry: PE session entry 56 * 57 * utility function called to clear up station context. 58 * 59 * Return: None. 60 */ 61 static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext msg, 62 struct pe_session *session_entry) 63 { 64 tpDphHashNode stads; 65 66 pe_debug("Deleting station: reasonCode: %d", msg->reasonCode); 67 68 stads = dph_lookup_hash_entry(mac_ctx, msg->addr2, &msg->assocId, 69 &session_entry->dph.dphHashTable); 70 71 if (!stads) { 72 pe_err("Invalid STA limSystemRole: %d", 73 GET_LIM_SYSTEM_ROLE(session_entry)); 74 return; 75 } 76 stads->del_sta_ctx_rssi = msg->rssi; 77 78 if (LIM_IS_AP_ROLE(session_entry)) { 79 pe_debug("Delete Station assocId: %d", msg->assocId); 80 /* 81 * Check if Deauth/Disassoc is triggered from Host. 82 * If mlmState is in some transient state then 83 * don't trigger STA deletion to avoid the race 84 * condition. 85 */ 86 if ((stads && 87 ((stads->mlmStaContext.mlmState != 88 eLIM_MLM_LINK_ESTABLISHED_STATE) && 89 (stads->mlmStaContext.mlmState != 90 eLIM_MLM_WT_ASSOC_CNF_STATE) && 91 (stads->mlmStaContext.mlmState != 92 eLIM_MLM_ASSOCIATED_STATE)))) { 93 pe_err("Inv Del STA assocId: %d", msg->assocId); 94 return; 95 } else { 96 if (stads->ocv_enabled && stads->last_ocv_done_freq != 97 session_entry->curr_op_freq) { 98 lim_send_deauth_mgmt_frame( 99 mac_ctx, 100 REASON_PREV_AUTH_NOT_VALID, 101 stads->staAddr, 102 session_entry, true); 103 stads->is_disassoc_deauth_in_progress = 1; 104 } else { 105 lim_send_disassoc_mgmt_frame( 106 mac_ctx, 107 REASON_DISASSOC_DUE_TO_INACTIVITY, 108 stads->staAddr, session_entry, false); 109 lim_trigger_sta_deletion(mac_ctx, stads, 110 session_entry); 111 } 112 } 113 } else { 114 #ifdef FEATURE_WLAN_TDLS 115 if (LIM_IS_STA_ROLE(session_entry) && 116 STA_ENTRY_TDLS_PEER == stads->staType) { 117 /* 118 * TeardownLink with PEER reason code 119 * HAL_DEL_STA_REASON_CODE_KEEP_ALIVE means 120 * eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE 121 */ 122 lim_send_sme_tdls_del_sta_ind(mac_ctx, stads, 123 session_entry, REASON_TDLS_PEER_UNREACHABLE); 124 } else { 125 #endif 126 /* TearDownLink with AP */ 127 tLimMlmDeauthInd mlm_deauth_ind; 128 129 pe_debug("Delete Station (assocId: %d)", msg->assocId); 130 131 if ((stads && 132 ((stads->mlmStaContext.mlmState != 133 eLIM_MLM_LINK_ESTABLISHED_STATE) && 134 (stads->mlmStaContext.mlmState != 135 eLIM_MLM_WT_ASSOC_CNF_STATE) && 136 (stads->mlmStaContext.mlmState != 137 eLIM_MLM_ASSOCIATED_STATE)))) { 138 139 /* 140 * Received SIR_LIM_DELETE_STA_CONTEXT_IND for STA that 141 * does not have context or in some transit state. 142 * Log error 143 */ 144 pe_debug("Received SIR_LIM_DELETE_STA_CONTEXT_IND for " 145 "STA that either has no context or " 146 "in some transit state, Addr = " 147 QDF_MAC_ADDR_FMT, 148 QDF_MAC_ADDR_REF(msg->bssId)); 149 return; 150 } 151 152 stads->mlmStaContext.disassocReason = 153 REASON_DISASSOC_DUE_TO_INACTIVITY; 154 stads->mlmStaContext.cleanupTrigger = 155 eLIM_LINK_MONITORING_DEAUTH; 156 157 /* Issue Deauth Indication to SME. */ 158 qdf_mem_copy((uint8_t *) &mlm_deauth_ind.peerMacAddr, 159 stads->staAddr, sizeof(tSirMacAddr)); 160 mlm_deauth_ind.reasonCode = 161 (uint8_t) stads->mlmStaContext.disassocReason; 162 mlm_deauth_ind.deauthTrigger = 163 stads->mlmStaContext.cleanupTrigger; 164 165 #ifdef FEATURE_WLAN_TDLS 166 /* Delete all TDLS peers connected before leaving BSS */ 167 lim_delete_tdls_peers(mac_ctx, session_entry); 168 #endif 169 if (LIM_IS_STA_ROLE(session_entry)) 170 lim_post_sme_message(mac_ctx, LIM_MLM_DEAUTH_IND, 171 (uint32_t *) &mlm_deauth_ind); 172 173 lim_send_sme_deauth_ind(mac_ctx, stads, session_entry); 174 #ifdef FEATURE_WLAN_TDLS 175 } 176 #endif 177 } 178 } 179 180 /** 181 * lim_delete_sta_context() - delete sta context. 182 * 183 * @mac_ctx: global mac_ctx context 184 * @lim_msg: lim message. 185 * 186 * This function handles the message from HAL: WMA_DELETE_STA_CONTEXT_IND. 187 * This function validates that the given station id exist, and if so, 188 * deletes the station by calling lim_trigger_sta_deletion. 189 * 190 * Return: none 191 */ 192 void lim_delete_sta_context(struct mac_context *mac_ctx, 193 struct scheduler_msg *lim_msg) 194 { 195 tpDeleteStaContext msg = (tpDeleteStaContext) lim_msg->bodyptr; 196 struct pe_session *session_entry; 197 tpDphHashNode sta_ds; 198 enum wlan_reason_code reason_code; 199 struct reject_ap_info ap_info; 200 201 if (!msg) { 202 pe_err("Invalid body pointer in message"); 203 return; 204 } 205 session_entry = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); 206 if (!session_entry) { 207 pe_err("session not found for given sme session"); 208 qdf_mem_free(msg); 209 return; 210 } 211 212 switch (msg->reasonCode) { 213 case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE: 214 case HAL_DEL_STA_REASON_CODE_SA_QUERY_TIMEOUT: 215 case HAL_DEL_STA_REASON_CODE_XRETRY: 216 if (LIM_IS_STA_ROLE(session_entry) && !msg->is_tdls) { 217 if (!lim_is_sb_disconnect_allowed(session_entry)) { 218 qdf_mem_free(msg); 219 return; 220 } 221 sta_ds = dph_get_hash_entry(mac_ctx, 222 DPH_STA_HASH_INDEX_PEER, 223 &session_entry->dph.dphHashTable); 224 if (!sta_ds) { 225 pe_err("Dph entry not found"); 226 qdf_mem_free(msg); 227 return; 228 } 229 lim_send_deauth_mgmt_frame(mac_ctx, 230 REASON_DISASSOC_DUE_TO_INACTIVITY, 231 msg->addr2, session_entry, false); 232 if (msg->reasonCode == 233 HAL_DEL_STA_REASON_CODE_SA_QUERY_TIMEOUT) 234 reason_code = REASON_SA_QUERY_TIMEOUT; 235 else if (msg->reasonCode == 236 HAL_DEL_STA_REASON_CODE_XRETRY) 237 reason_code = REASON_PEER_XRETRY_FAIL; 238 else 239 reason_code = REASON_PEER_INACTIVITY; 240 lim_tear_down_link_with_ap(mac_ctx, 241 session_entry->peSessionId, 242 reason_code, 243 eLIM_LINK_MONITORING_DEAUTH); 244 qdf_mem_zero(&ap_info, sizeof(struct reject_ap_info)); 245 qdf_mem_copy(&ap_info.bssid, msg->addr2, 246 QDF_MAC_ADDR_SIZE); 247 ap_info.reject_ap_type = DRIVER_AVOID_TYPE; 248 ap_info.reject_reason = REASON_STA_KICKOUT; 249 ap_info.source = ADDED_BY_DRIVER; 250 wlan_dlm_add_bssid_to_reject_list(mac_ctx->pdev, 251 &ap_info); 252 253 /* only break for STA role (non TDLS) */ 254 break; 255 } 256 lim_delete_sta_util(mac_ctx, msg, session_entry); 257 break; 258 259 case HAL_DEL_STA_REASON_CODE_UNKNOWN_A2: 260 pe_err("Deleting Unknown station: "QDF_MAC_ADDR_FMT, 261 QDF_MAC_ADDR_REF(msg->addr2)); 262 lim_send_deauth_mgmt_frame(mac_ctx, 263 REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA, 264 msg->addr2, session_entry, false); 265 break; 266 267 case HAL_DEL_STA_REASON_CODE_BTM_DISASSOC_IMMINENT: 268 if (!lim_is_sb_disconnect_allowed(session_entry)) { 269 qdf_mem_free(msg); 270 lim_msg->bodyptr = NULL; 271 return; 272 } 273 lim_send_deauth_mgmt_frame(mac_ctx, 274 REASON_DISASSOC_BSS_TRANSITION , 275 session_entry->bssId, session_entry, false); 276 lim_tear_down_link_with_ap(mac_ctx, session_entry->peSessionId, 277 REASON_DISASSOC_BSS_TRANSITION , 278 eLIM_LINK_MONITORING_DEAUTH); 279 break; 280 281 default: 282 pe_err("Unknown reason code"); 283 break; 284 } 285 qdf_mem_free(msg); 286 lim_msg->bodyptr = NULL; 287 return; 288 } 289 290 /** 291 * lim_trigger_sta_deletion() - 292 * This function is called to trigger STA context deletion. 293 * 294 * @param mac_ctx - Pointer to global MAC structure 295 * @param sta_ds - Pointer to internal STA Datastructure 296 * @session_entry: PE session entry 297 298 * @return None 299 */ 300 void 301 lim_trigger_sta_deletion(struct mac_context *mac_ctx, tpDphHashNode sta_ds, 302 struct pe_session *session_entry) 303 { 304 tLimMlmDisassocInd mlm_disassoc_ind; 305 306 if (!sta_ds) { 307 pe_warn("Skip STA deletion (invalid STA)"); 308 return; 309 } 310 311 if ((sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || 312 (sta_ds->mlmStaContext.mlmState == 313 eLIM_MLM_WT_DEL_BSS_RSP_STATE) || 314 sta_ds->sta_deletion_in_progress) { 315 /* Already in the process of deleting context for the peer */ 316 pe_debug("Deletion is in progress (%d) for peer:%pK in mlmState %d", 317 sta_ds->sta_deletion_in_progress, sta_ds->staAddr, 318 sta_ds->mlmStaContext.mlmState); 319 return; 320 } 321 sta_ds->sta_deletion_in_progress = true; 322 323 sta_ds->mlmStaContext.disassocReason = 324 REASON_DISASSOC_DUE_TO_INACTIVITY; 325 sta_ds->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DISASSOC; 326 qdf_mem_copy(&mlm_disassoc_ind.peerMacAddr, sta_ds->staAddr, 327 sizeof(tSirMacAddr)); 328 mlm_disassoc_ind.reasonCode = 329 REASON_DISASSOC_DUE_TO_INACTIVITY; 330 mlm_disassoc_ind.disassocTrigger = eLIM_LINK_MONITORING_DISASSOC; 331 332 /* Update PE session Id */ 333 mlm_disassoc_ind.sessionId = session_entry->peSessionId; 334 lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_IND, 335 (uint32_t *) &mlm_disassoc_ind); 336 if (mac_ctx->mlme_cfg->gen.fatal_event_trigger) 337 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 338 WLAN_LOG_INDICATOR_HOST_DRIVER, 339 WLAN_LOG_REASON_HB_FAILURE, 340 false, false); 341 /* Issue Disassoc Indication to SME */ 342 lim_send_sme_disassoc_ind(mac_ctx, sta_ds, session_entry); 343 } /*** end lim_trigger_st_adeletion() ***/ 344 345 static void 346 lim_connectivity_bmiss_disconn_event(tpDphHashNode sta, 347 struct wlan_objmgr_psoc *psoc, 348 enum wlan_reason_code reason_code, 349 uint32_t vdev_id) 350 { 351 if (!(reason_code == REASON_BEACON_MISSED)) 352 return; 353 354 /* 355 * Firmware sends final bmiss indication as part of roam scan stats 356 * event. Disconn log is sent as part of the final bmiss indication 357 * from roam scan stats event with specific reason. But if RSO stop 358 * or RSO deinit happens after first bmiss due to concurrent interface 359 * connection, then firmware doesn't send the final bmiss indication 360 * to driver since roam scan will be disabled. But final bmiss 361 * heartbeat failure will be indicated as part of WMI_ROAM_EVENTID with 362 * reason as BMISS. So generate DISCONN log in this case from host based 363 * on RSO state and final bmiss HB failure teardown. 364 */ 365 if (!(MLME_IS_ROAM_STATE_STOPPED(psoc, vdev_id) || 366 MLME_IS_ROAM_STATE_DEINIT(psoc, vdev_id))) 367 return; 368 369 cm_roam_beacon_loss_disconnect_event(psoc, 370 *(struct qdf_mac_addr *)sta->staAddr, 371 vdev_id); 372 } 373 374 void 375 lim_tear_down_link_with_ap(struct mac_context *mac, uint8_t sessionId, 376 enum wlan_reason_code reasonCode, 377 enum eLimDisassocTrigger trigger) 378 { 379 tpDphHashNode sta = NULL; 380 tLimMlmDeauthInd mlmDeauthInd; 381 382 /* tear down the following pe_session */ 383 struct pe_session *pe_session; 384 385 pe_session = pe_find_session_by_session_id(mac, sessionId); 386 if (!pe_session) { 387 pe_err("Session Does not exist for given sessionID"); 388 return; 389 } 390 391 pe_info("Session %d Vdev %d reason code %d trigger %d", 392 pe_session->peSessionId, pe_session->vdev_id, reasonCode, 393 trigger); 394 395 /* Add the check here in case caller missed the check */ 396 if (!lim_is_sb_disconnect_allowed(pe_session)) 397 return; 398 399 /** 400 * Heart beat failed for upto threshold value 401 * and AP did not respond for Probe request. 402 * Trigger link tear down. 403 */ 404 pe_session->pmmOffloadInfo.bcnmiss = false; 405 406 /* Delete all TDLS peers connected before leaving BSS */ 407 lim_delete_tdls_peers(mac, pe_session); 408 409 /* Announce loss of link to Roaming algorithm */ 410 /* and cleanup by sending SME_DISASSOC_REQ to SME */ 411 412 sta = dph_get_hash_entry(mac, DPH_STA_HASH_INDEX_PEER, 413 &pe_session->dph.dphHashTable); 414 if (!sta) { 415 pe_debug("vdev:%d no sta hash entry for peer:" QDF_MAC_ADDR_FMT, 416 pe_session->vdev_id, 417 QDF_MAC_ADDR_REF(pe_session->bssId)); 418 return; 419 } 420 421 if ((sta->mlmStaContext.disassocReason == 422 REASON_DEAUTH_NETWORK_LEAVING) || 423 (sta->mlmStaContext.cleanupTrigger == 424 eLIM_HOST_DEAUTH)) { 425 pe_err("Host already issued deauth, do nothing"); 426 return; 427 } 428 429 sta->mlmStaContext.disassocReason = reasonCode; 430 sta->mlmStaContext.cleanupTrigger = trigger; 431 /* / Issue Deauth Indication to SME. */ 432 qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr, 433 sta->staAddr, sizeof(tSirMacAddr)); 434 435 /* 436 * if deauth_before_connection is enabled and reasoncode is 437 * Beacon Missed Store the MAC of AP in the flip flop 438 * buffer. This MAC will be used to send Deauth before 439 * connection, if we connect to same AP after HB failure. 440 */ 441 if (mac->mlme_cfg->sta.deauth_before_connection && 442 reasonCode == REASON_BEACON_MISSED) { 443 int apCount = mac->lim.gLimHeartBeatApMacIndex; 444 445 if (mac->lim.gLimHeartBeatApMacIndex) 446 mac->lim.gLimHeartBeatApMacIndex = 0; 447 else 448 mac->lim.gLimHeartBeatApMacIndex = 1; 449 450 pe_debug("HB Failure on MAC " 451 QDF_MAC_ADDR_FMT" Store it on Index %d", 452 QDF_MAC_ADDR_REF(sta->staAddr), apCount); 453 454 sir_copy_mac_addr(mac->lim.gLimHeartBeatApMac[apCount], 455 sta->staAddr); 456 } 457 458 mlmDeauthInd.reasonCode = 459 (uint8_t) sta->mlmStaContext.disassocReason; 460 mlmDeauthInd.deauthTrigger = 461 sta->mlmStaContext.cleanupTrigger; 462 463 if (LIM_IS_STA_ROLE(pe_session)) { 464 lim_connectivity_bmiss_disconn_event(sta, mac->psoc, reasonCode, 465 pe_session->vdev_id); 466 467 lim_post_sme_message(mac, LIM_MLM_DEAUTH_IND, 468 (uint32_t *)&mlmDeauthInd); 469 } 470 471 if (mac->mlme_cfg->gen.fatal_event_trigger) 472 cds_flush_logs(WLAN_LOG_TYPE_FATAL, 473 WLAN_LOG_INDICATOR_HOST_DRIVER, 474 WLAN_LOG_REASON_HB_FAILURE, 475 false, false); 476 477 lim_send_sme_deauth_ind(mac, sta, pe_session); 478 479 } /*** lim_tear_down_link_with_ap() ***/ 480 481 /** 482 * lim_handle_heart_beat_failure() - handle hear beat failure in STA 483 * 484 * @mac_ctx: global MAC context 485 * @session: PE session entry 486 * 487 * This function is called when heartbeat (beacon reception) 488 * fails on STA 489 * 490 * Return: None 491 */ 492 493 void lim_handle_heart_beat_failure(struct mac_context *mac_ctx, 494 struct pe_session *session) 495 { 496 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 497 host_log_beacon_update_pkt_type *log_ptr = NULL; 498 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 499 500 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ 501 WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_beacon_update_pkt_type, 502 LOG_WLAN_BEACON_UPDATE_C); 503 if (log_ptr) 504 log_ptr->bcn_rx_cnt = session->LimRxedBeaconCntDuringHB; 505 WLAN_HOST_DIAG_LOG_REPORT(log_ptr); 506 #endif /* FEATURE_WLAN_DIAG_SUPPORT */ 507 508 if (LIM_IS_STA_ROLE(session) && 509 lim_is_sb_disconnect_allowed(session)) { 510 if (!mac_ctx->sys.gSysEnableLinkMonitorMode) { 511 goto hb_handler_fail; 512 } 513 514 /* Ignore HB if channel switch is in progress */ 515 if (session->gLimSpecMgmt.dot11hChanSwState == 516 eLIM_11H_CHANSW_RUNNING) { 517 pe_debug("Ignore Heartbeat failure as Channel switch is in progress"); 518 session->pmmOffloadInfo.bcnmiss = false; 519 goto hb_handler_fail; 520 } 521 /* Beacon frame not received within heartbeat timeout. */ 522 pe_warn("Heartbeat Failure"); 523 mac_ctx->lim.gLimHBfailureCntInLinkEstState++; 524 525 /* 526 * Before host received beacon miss, firmware has checked link 527 * by sending QoS NULL data, don't need host send probe req. 528 * Some IoT AP can send probe response, but can't send beacon 529 * sometimes, need disconnect too, or firmware will assert. 530 */ 531 lim_send_deauth_mgmt_frame(mac_ctx, 532 REASON_DISASSOC_DUE_TO_INACTIVITY, 533 session->bssId, 534 session, false); 535 lim_tear_down_link_with_ap(mac_ctx, 536 session->peSessionId, 537 REASON_BEACON_MISSED, 538 eLIM_LINK_MONITORING_DEAUTH); 539 } else { 540 /** 541 * Heartbeat timer may have timed out 542 * while we're doing background scanning/learning 543 * or in states other than link-established state. 544 * Log error. 545 */ 546 pe_debug("received heartbeat timeout in state %X", 547 session->limMlmState); 548 lim_print_mlm_state(mac_ctx, LOG1, session->limMlmState); 549 mac_ctx->lim.gLimHBfailureCntInOtherStates++; 550 } 551 552 hb_handler_fail: 553 if (mac_ctx->sme.tx_queue_cb) 554 mac_ctx->sme.tx_queue_cb(mac_ctx->hdd_handle, 555 session->smeSessionId, 556 WLAN_WAKE_ALL_NETIF_QUEUE, 557 WLAN_CONTROL_PATH); 558 } 559 560 void lim_rx_invalid_peer_process(struct mac_context *mac_ctx, 561 struct scheduler_msg *lim_msg) 562 { 563 struct ol_rx_inv_peer_params *msg = 564 (struct ol_rx_inv_peer_params *)lim_msg->bodyptr; 565 struct pe_session *session_entry; 566 uint16_t reason_code = REASON_CLASS3_FRAME_FROM_NON_ASSOC_STA; 567 uint16_t aid; 568 tpDphHashNode sta_ds; 569 570 if (!msg) { 571 pe_err("Invalid body pointer in message"); 572 return; 573 } 574 575 session_entry = pe_find_session_by_vdev_id(mac_ctx, msg->vdev_id); 576 if (!session_entry) { 577 pe_err_rl("session not found for given sme session"); 578 qdf_mem_free(msg); 579 return; 580 } 581 582 /* only if SAP mode */ 583 if (session_entry->bssType == eSIR_INFRA_AP_MODE) { 584 sta_ds = dph_lookup_hash_entry(mac_ctx, msg->ta, &aid, 585 &session_entry->dph.dphHashTable); 586 if (sta_ds && sta_ds->is_key_installed) { 587 /* 588 * Skip deauth for an associated STA. 589 * 590 * The deauth sent for invalid peer indication will 591 * not cleanup the SM if this is an associated STA. 592 * Therefore, the deauth for associated STA creates 593 * stale entries even after STA gets disconnected. 594 */ 595 pe_err_rl("Received Invalid rx peer indication for an associated STA " 596 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(msg->ta)); 597 qdf_mem_free(msg); 598 lim_msg->bodyptr = NULL; 599 return; 600 } 601 pe_debug("send deauth frame to non-assoc STA"); 602 lim_send_deauth_mgmt_frame(mac_ctx, 603 reason_code, 604 msg->ta, 605 session_entry, 606 false); 607 } 608 609 qdf_mem_free(msg); 610 lim_msg->bodyptr = NULL; 611 } 612 613 void lim_req_send_delba_ind_process(struct mac_context *mac_ctx, 614 struct scheduler_msg *lim_msg) 615 { 616 struct lim_delba_req_info *req = 617 (struct lim_delba_req_info *)lim_msg->bodyptr; 618 QDF_STATUS status; 619 void *dp_soc = cds_get_context(QDF_MODULE_ID_SOC); 620 621 if (!req) { 622 pe_err("Invalid body pointer in message"); 623 return; 624 } 625 626 status = lim_send_delba_action_frame(mac_ctx, req->vdev_id, 627 req->peer_macaddr, 628 req->tid, req->reason_code); 629 if (status != QDF_STATUS_SUCCESS) 630 cdp_delba_tx_completion(dp_soc, req->peer_macaddr, 631 req->vdev_id, req->tid, 632 WMI_MGMT_TX_COMP_TYPE_DISCARD); 633 qdf_mem_free(req); 634 lim_msg->bodyptr = NULL; 635 } 636