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 */
lim_delete_sta_util(struct mac_context * mac_ctx,tpDeleteStaContext msg,struct pe_session * session_entry)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 */
lim_delete_sta_context(struct mac_context * mac_ctx,struct scheduler_msg * lim_msg)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
lim_trigger_sta_deletion(struct mac_context * mac_ctx,tpDphHashNode sta_ds,struct pe_session * session_entry)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
lim_connectivity_bmiss_disconn_event(tpDphHashNode sta,struct wlan_objmgr_psoc * psoc,enum wlan_reason_code reason_code,uint32_t vdev_id)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
lim_tear_down_link_with_ap(struct mac_context * mac,uint8_t sessionId,enum wlan_reason_code reasonCode,enum eLimDisassocTrigger trigger)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
lim_handle_heart_beat_failure(struct mac_context * mac_ctx,struct pe_session * session)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
lim_rx_invalid_peer_process(struct mac_context * mac_ctx,struct scheduler_msg * lim_msg)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
lim_req_send_delba_ind_process(struct mac_context * mac_ctx,struct scheduler_msg * lim_msg)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