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