1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022 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 * DOC: lim_process_mlm_host_roam.c
22 *
23 * Host based roaming MLM implementation
24 */
25 #include "cds_api.h"
26 #include "wni_cfg.h"
27 #include "ani_global.h"
28 #include "sir_api.h"
29 #include "sir_params.h"
30
31 #include "sch_api.h"
32 #include "utils_api.h"
33 #include "lim_utils.h"
34 #include "lim_assoc_utils.h"
35 #include "lim_prop_exts_utils.h"
36 #include "lim_security_utils.h"
37 #include "lim_send_messages.h"
38 #include "lim_send_messages.h"
39 #include "lim_session_utils.h"
40 #include <lim_ft.h>
41 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
42 #include "host_diag_core_log.h"
43 #endif
44 #include "wma_if.h"
45 #include "rrm_api.h"
46 #include "wma.h"
47 #include <lim_mlo.h>
48
49 static void lim_handle_sme_reaasoc_result(struct mac_context *, tSirResultCodes,
50 uint16_t, struct pe_session *);
51 /**
52 * lim_process_mlm_reassoc_req() - process mlm reassoc request.
53 *
54 * @mac_ctx: pointer to Global MAC structure
55 * @msg: pointer to the MLM message buffer
56 *
57 * This function is called to process MLM_REASSOC_REQ message
58 * from SME
59 *
60 * Return: None
61 */
lim_process_mlm_reassoc_req(struct mac_context * mac_ctx,tLimMlmReassocReq * reassoc_req)62 void lim_process_mlm_reassoc_req(struct mac_context *mac_ctx,
63 tLimMlmReassocReq *reassoc_req)
64 {
65 struct tLimPreAuthNode *auth_node;
66 tLimMlmReassocCnf reassoc_cnf;
67 struct pe_session *session;
68
69 session = pe_find_session_by_session_id(mac_ctx,
70 reassoc_req->sessionId);
71 if (!session) {
72 pe_err("Session Does not exist for given sessionId: %d",
73 reassoc_req->sessionId);
74 qdf_mem_free(reassoc_req);
75 return;
76 }
77
78 pe_debug("ReAssoc Req on session: %d role: %d mlm: %d " QDF_MAC_ADDR_FMT,
79 reassoc_req->sessionId, GET_LIM_SYSTEM_ROLE(session),
80 session->limMlmState,
81 QDF_MAC_ADDR_REF(reassoc_req->peerMacAddr));
82
83 if (LIM_IS_AP_ROLE(session) ||
84 (session->limMlmState !=
85 eLIM_MLM_LINK_ESTABLISHED_STATE)) {
86 /*
87 * Received Reassoc request in invalid state or
88 * in AP role.Return Reassoc confirm with Invalid
89 * parameters code.
90 */
91
92 pe_warn("unexpected msg state: %X role: %d MAC "
93 QDF_MAC_ADDR_FMT,
94 session->limMlmState, GET_LIM_SYSTEM_ROLE(session),
95 QDF_MAC_ADDR_REF(reassoc_req->peerMacAddr));
96 lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
97 reassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
98 reassoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
99 goto end;
100 }
101
102 if (session->pLimMlmReassocReq)
103 qdf_mem_free(session->pLimMlmReassocReq);
104
105 /*
106 * Hold Re-Assoc request as part of Session, knock-out mac_ctx
107 * Hold onto Reassoc request parameters
108 */
109 session->pLimMlmReassocReq = reassoc_req;
110
111 /* See if we have pre-auth context with new AP */
112 auth_node = lim_search_pre_auth_list(mac_ctx, session->limReAssocbssId);
113
114 if (!auth_node && (qdf_mem_cmp(reassoc_req->peerMacAddr,
115 session->bssId,
116 sizeof(tSirMacAddr)))) {
117 /*
118 * Either pre-auth context does not exist AND
119 * we are not reassociating with currently
120 * associated AP.
121 * Return Reassoc confirm with not authenticated
122 */
123 reassoc_cnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
124 reassoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
125
126 goto end;
127 }
128 /* assign the sessionId to the timer object */
129 mac_ctx->lim.lim_timers.gLimReassocFailureTimer.sessionId =
130 reassoc_req->sessionId;
131 session->limPrevMlmState = session->limMlmState;
132 session->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
133 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
134 session->limMlmState));
135
136 /* Apply previously set configuration at HW */
137 lim_apply_configuration(mac_ctx, session);
138
139 /* store the channel switch reason code in the lim global var */
140 session->channelChangeReasonCode = LIM_SWITCH_CHANNEL_REASSOC;
141 mlme_set_chan_switch_in_progress(session->vdev, true);
142 wlan_vdev_mlme_sm_deliver_evt(session->vdev,
143 WLAN_VDEV_SM_EV_FW_VDEV_RESTART,
144 sizeof(struct pe_session), session);
145 return;
146 end:
147 reassoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
148 /* Update PE session Id */
149 reassoc_cnf.sessionId = reassoc_req->sessionId;
150 /* Free up buffer allocated for reassocReq */
151 qdf_mem_free(reassoc_req);
152 session->pLimReAssocReq = NULL;
153 lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
154 (uint32_t *) &reassoc_cnf);
155 }
156
157 /**
158 * lim_handle_sme_reaasoc_result() - Handle the reassoc result
159 * @mac: Global MAC Context
160 * @resultCode: Result code
161 * @protStatusCode: Protocol Status Code
162 * @pe_session: PE Session
163 *
164 * This function is called to process reassoc failures
165 * upon receiving REASSOC_CNF with a failure code or
166 * MLM_REASSOC_CNF with a success code in case of STA role
167 *
168 * Return: None
169 */
lim_handle_sme_reaasoc_result(struct mac_context * mac,tSirResultCodes resultCode,uint16_t protStatusCode,struct pe_session * pe_session)170 static void lim_handle_sme_reaasoc_result(struct mac_context *mac,
171 tSirResultCodes resultCode, uint16_t protStatusCode,
172 struct pe_session *pe_session)
173 {
174 tpDphHashNode sta = NULL;
175 uint8_t smesessionId;
176
177 if (!pe_session) {
178 pe_err("pe_session is NULL");
179 return;
180 }
181 smesessionId = pe_session->smeSessionId;
182 if (resultCode != eSIR_SME_SUCCESS) {
183 sta =
184 dph_get_hash_entry(mac, DPH_STA_HASH_INDEX_PEER,
185 &pe_session->dph.dphHashTable);
186 if (sta) {
187 sta->mlmStaContext.disassocReason =
188 REASON_UNSPEC_FAILURE;
189 sta->mlmStaContext.cleanupTrigger =
190 eLIM_JOIN_FAILURE;
191 sta->mlmStaContext.resultCode = resultCode;
192 sta->mlmStaContext.protStatusCode = protStatusCode;
193 lim_mlo_notify_peer_disconn(pe_session, sta);
194 lim_cleanup_rx_path(mac, sta, pe_session, true);
195 /* Cleanup if add bss failed */
196 if (pe_session->add_bss_failed) {
197 dph_delete_hash_entry(mac,
198 sta->staAddr, sta->assocId,
199 &pe_session->dph.dphHashTable);
200 goto error;
201 }
202 return;
203 }
204 }
205 error:
206 /* Delete the session if REASSOC failure occurred. */
207 if (resultCode != eSIR_SME_SUCCESS) {
208 if (pe_session) {
209 pe_delete_session(mac, pe_session);
210 pe_session = NULL;
211 }
212 }
213 lim_send_sme_join_reassoc_rsp(mac, eWNI_SME_REASSOC_RSP, resultCode,
214 protStatusCode, pe_session, smesessionId);
215 }
216
217 /**
218 * lim_process_mlm_reassoc_cnf() - process mlm reassoc cnf msg
219 *
220 * @mac_ctx: Pointer to Global MAC structure
221 * @msg_buf: A pointer to the MLM message buffer
222 *
223 * This function is called to process MLM_REASSOC_CNF message from MLM State
224 * machine.
225 *
226 * @Return: void
227 */
lim_process_mlm_reassoc_cnf(struct mac_context * mac_ctx,uint32_t * msg_buf)228 void lim_process_mlm_reassoc_cnf(struct mac_context *mac_ctx, uint32_t *msg_buf)
229 {
230 struct pe_session *session;
231 tLimMlmReassocCnf *lim_mlm_reassoc_cnf;
232 struct reassoc_params param;
233 QDF_STATUS status;
234 enum wlan_vdev_state sub_state;
235
236 if (!msg_buf) {
237 pe_err("Buffer is Pointing to NULL");
238 return;
239 }
240 lim_mlm_reassoc_cnf = (tLimMlmReassocCnf *)msg_buf;
241 session = pe_find_session_by_session_id(
242 mac_ctx,
243 lim_mlm_reassoc_cnf->sessionId);
244 if (!session) {
245 pe_err("session Does not exist for given session Id");
246 return;
247 }
248 if (session->limSmeState != eLIM_SME_WT_REASSOC_STATE ||
249 LIM_IS_AP_ROLE(session)) {
250 /*
251 * Should not have received Reassocication confirm
252 * from MLM in other states OR on AP.
253 */
254 pe_err("Rcv unexpected MLM_REASSOC_CNF role: %d sme 0x%X",
255 GET_LIM_SYSTEM_ROLE(session), session->limSmeState);
256 return;
257 }
258
259 /*
260 * Upon Reassoc success or failure, freeup the cached preauth request,
261 * to ensure that channel switch is now allowed following any change in
262 * HT params.
263 */
264 if (session->ftPEContext.pFTPreAuthReq) {
265 pe_debug("Freeing pFTPreAuthReq: %pK",
266 session->ftPEContext.pFTPreAuthReq);
267 if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
268 qdf_mem_free(
269 session->ftPEContext.pFTPreAuthReq->pbssDescription);
270 session->ftPEContext.pFTPreAuthReq->pbssDescription =
271 NULL;
272 }
273 qdf_mem_free(session->ftPEContext.pFTPreAuthReq);
274 session->ftPEContext.pFTPreAuthReq = NULL;
275 session->ftPEContext.ftPreAuthSession = false;
276 }
277
278 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
279 if (session->bRoamSynchInProgress) {
280 pe_debug("LFR3:Re-set the LIM Ctxt Roam Synch In Progress");
281 session->bRoamSynchInProgress = false;
282 }
283 #endif
284
285 sub_state = wlan_vdev_mlme_get_substate(session->vdev);
286 pe_debug("Rcv MLM_REASSOC_CNF with result code: %d vdev SS %d",
287 lim_mlm_reassoc_cnf->resultCode, sub_state);
288 if (lim_mlm_reassoc_cnf->resultCode == eSIR_SME_SUCCESS) {
289 /* Successful Reassociation */
290 pe_debug("*** Reassociated with new BSS ***");
291
292 session->limSmeState = eLIM_SME_LINK_EST_STATE;
293 MTRACE(mac_trace(
294 mac_ctx, TRACE_CODE_SME_STATE,
295 session->peSessionId, session->limSmeState));
296
297 wlan_vdev_mlme_sm_deliver_evt(session->vdev,
298 WLAN_VDEV_SM_EV_START_SUCCESS,
299 0, NULL);
300
301 /* Need to send Reassoc rsp with Reassoc success to Host. */
302 lim_send_sme_join_reassoc_rsp(
303 mac_ctx, eWNI_SME_REASSOC_RSP,
304 lim_mlm_reassoc_cnf->resultCode,
305 lim_mlm_reassoc_cnf->protStatusCode,
306 session, session->smeSessionId);
307 } else if (sub_state == WLAN_VDEV_SS_START_CONN_PROGRESS ||
308 sub_state == WLAN_VDEV_SS_START_RESTART_PROGRESS) {
309 session->limSmeState = eLIM_SME_LINK_EST_STATE;
310 /*
311 * Need to send Reassoc rsp with re-Assoc failure to CM
312 * so that disconnect can be initiated.
313 */
314 lim_send_sme_join_reassoc_rsp(
315 mac_ctx, eWNI_SME_REASSOC_RSP,
316 lim_mlm_reassoc_cnf->resultCode,
317 lim_mlm_reassoc_cnf->protStatusCode,
318 session, session->smeSessionId);
319 } else {
320 param.result_code = lim_mlm_reassoc_cnf->resultCode;
321 param.prot_status_code = lim_mlm_reassoc_cnf->protStatusCode;
322 param.session = session;
323
324 mlme_set_connection_fail(session->vdev, true);
325
326 if (sub_state == WLAN_VDEV_SS_START_START_PROGRESS)
327 status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
328 WLAN_VDEV_SM_EV_START_REQ_FAIL,
329 sizeof(param), ¶m);
330 else
331 status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
332 WLAN_VDEV_SM_EV_CONNECTION_FAIL,
333 sizeof(param), ¶m);
334 }
335
336 if (session->pLimReAssocReq) {
337 qdf_mem_free(session->pLimReAssocReq);
338 session->pLimReAssocReq = NULL;
339 }
340 }
341
lim_sta_reassoc_error_handler(struct reassoc_params * param)342 QDF_STATUS lim_sta_reassoc_error_handler(struct reassoc_params *param)
343 {
344 struct pe_session *session;
345 struct mac_context *mac_ctx;
346
347 if (!param) {
348 pe_err("param is NULL");
349 return QDF_STATUS_E_INVAL;
350 }
351
352 mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
353 if (!mac_ctx)
354 return QDF_STATUS_E_INVAL;
355
356 session = param->session;
357 if (param->result_code
358 == eSIR_SME_REASSOC_REFUSED) {
359 /*
360 * Reassociation failure With the New AP but we still have the
361 * link with the Older AP
362 */
363 session->limSmeState = eLIM_SME_LINK_EST_STATE;
364 MTRACE(mac_trace(
365 mac_ctx, TRACE_CODE_SME_STATE,
366 session->peSessionId, session->limSmeState));
367
368 /* Need to send Reassoc rsp with Assoc failure to Host. */
369 lim_send_sme_join_reassoc_rsp(
370 mac_ctx, eWNI_SME_REASSOC_RSP,
371 param->result_code,
372 param->prot_status_code,
373 session, session->smeSessionId);
374 } else {
375 /* Reassociation failure */
376 session->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
377 MTRACE(mac_trace(
378 mac_ctx, TRACE_CODE_SME_STATE,
379 session->peSessionId, session->limSmeState));
380 /* Need to send Reassoc rsp with Assoc failure to Host. */
381 lim_handle_sme_reaasoc_result(
382 mac_ctx,
383 param->result_code,
384 param->prot_status_code,
385 session);
386 }
387 return QDF_STATUS_SUCCESS;
388 }
389
lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context * mac,struct add_bss_rsp * add_bss_rsp,struct pe_session * pe_session)390 void lim_process_sta_mlm_add_bss_rsp_ft(struct mac_context *mac,
391 struct add_bss_rsp *add_bss_rsp,
392 struct pe_session *pe_session)
393 {
394 tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
395 tpDphHashNode sta = NULL;
396 tpAddStaParams pAddStaParams = NULL;
397 uint32_t listenInterval = MLME_CFG_LISTEN_INTERVAL;
398 struct bss_description *bss_desc = NULL;
399
400 /* Sanity Checks */
401
402 if (!add_bss_rsp) {
403 pe_err("add_bss_rsp is NULL");
404 goto end;
405 }
406 if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE !=
407 pe_session->limMlmState) {
408 goto end;
409 }
410
411 sta = dph_add_hash_entry(mac, pe_session->bssId,
412 DPH_STA_HASH_INDEX_PEER,
413 &pe_session->dph.dphHashTable);
414 if (!sta) {
415 /* Could not add hash table entry */
416 pe_err("could not add hash entry at DPH for "QDF_MAC_ADDR_FMT,
417 QDF_MAC_ADDR_REF(pe_session->bssId));
418 goto end;
419 }
420
421 /* Prepare and send Reassociation request frame */
422 /* start reassoc timer. */
423 mac->lim.lim_timers.gLimReassocFailureTimer.sessionId =
424 pe_session->peSessionId;
425 /* / Start reassociation failure timer */
426 MTRACE(mac_trace
427 (mac, TRACE_CODE_TIMER_ACTIVATE,
428 pe_session->peSessionId, eLIM_REASSOC_FAIL_TIMER));
429
430 if (tx_timer_activate(&mac->lim.lim_timers.gLimReassocFailureTimer) !=
431 TX_SUCCESS) {
432 /* / Could not start reassoc failure timer. */
433 /* Log error */
434 pe_err("could not start Reassoc failure timer");
435 /* Return Reassoc confirm with */
436 /* Resources Unavailable */
437 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
438 mlmReassocCnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
439 goto end;
440 }
441
442 mac->lim.pe_session = pe_session;
443 if (!mac->lim.pe_session->pLimMlmReassocRetryReq) {
444 /* Take a copy of reassoc request for retrying */
445 mac->lim.pe_session->pLimMlmReassocRetryReq =
446 qdf_mem_malloc(sizeof(tLimMlmReassocReq));
447 if (!mac->lim.pe_session->pLimMlmReassocRetryReq)
448 goto end;
449
450 qdf_mem_copy(mac->lim.pe_session->pLimMlmReassocRetryReq,
451 pe_session->pLimMlmReassocReq,
452 sizeof(tLimMlmReassocReq));
453 }
454 mac->lim.reAssocRetryAttempt = 0;
455 lim_send_reassoc_req_with_ft_ies_mgmt_frame(
456 mac, pe_session->pLimMlmReassocReq, pe_session);
457
458 pe_session->limPrevMlmState = pe_session->limMlmState;
459 pe_session->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE;
460 MTRACE(mac_trace
461 (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId,
462 eLIM_MLM_WT_FT_REASSOC_RSP_STATE));
463 pe_debug("Set the mlm state: %d session: %d",
464 pe_session->limMlmState, pe_session->peSessionId);
465
466 /* Success, handle below */
467
468 pAddStaParams = qdf_mem_malloc(sizeof(tAddStaParams));
469 if (!pAddStaParams)
470 goto end;
471
472 /* / Add STA context at MAC HW (BMU, RHP & TFP) */
473 qdf_mem_copy((uint8_t *)pAddStaParams->staMac,
474 (uint8_t *)pe_session->self_mac_addr,
475 sizeof(tSirMacAddr));
476
477 qdf_mem_copy((uint8_t *)pAddStaParams->bssId,
478 pe_session->bssId, sizeof(tSirMacAddr));
479
480 pAddStaParams->staType = STA_ENTRY_SELF;
481 pAddStaParams->status = QDF_STATUS_SUCCESS;
482
483 /* Update PE session ID */
484 pAddStaParams->sessionId = pe_session->peSessionId;
485 pAddStaParams->smesessionId = pe_session->smeSessionId;
486
487 pAddStaParams->updateSta = false;
488
489 if (pe_session->lim_join_req)
490 bss_desc = &pe_session->lim_join_req->bssDescription;
491
492 lim_populate_peer_rate_set(mac, &pAddStaParams->supportedRates, NULL,
493 false, pe_session, NULL, NULL, NULL, NULL,
494 bss_desc);
495
496 if (pe_session->htCapability) {
497 pAddStaParams->htCapable = pe_session->htCapability;
498 pAddStaParams->vhtCapable = pe_session->vhtCapability;
499 pAddStaParams->ch_width = pe_session->ch_width;
500
501 pAddStaParams->mimoPS =
502 lim_get_ht_capability(mac, eHT_MIMO_POWER_SAVE,
503 pe_session);
504 pAddStaParams->maxAmpduDensity =
505 lim_get_ht_capability(mac, eHT_MPDU_DENSITY,
506 pe_session);
507 pAddStaParams->maxAmpduSize =
508 lim_get_ht_capability(mac, eHT_MAX_RX_AMPDU_FACTOR,
509 pe_session);
510 pAddStaParams->fShortGI20Mhz =
511 lim_get_ht_capability(mac, eHT_SHORT_GI_20MHZ,
512 pe_session);
513 pAddStaParams->fShortGI40Mhz =
514 lim_get_ht_capability(mac, eHT_SHORT_GI_40MHZ,
515 pe_session);
516 }
517
518 listenInterval = mac->mlme_cfg->sap_cfg.listen_interval;
519 pAddStaParams->listenInterval = (uint16_t) listenInterval;
520
521 pAddStaParams->encryptType = pe_session->encryptType;
522 pAddStaParams->maxTxPower = pe_session->maxTxPower;
523
524 /* Lets save this for when we receive the Reassoc Rsp */
525 pe_session->ftPEContext.pAddStaReq = pAddStaParams;
526
527 return;
528
529 end:
530 /* Free up buffer allocated for reassocReq */
531 if (pe_session)
532 if (pe_session->pLimMlmReassocReq) {
533 qdf_mem_free(pe_session->pLimMlmReassocReq);
534 pe_session->pLimMlmReassocReq = NULL;
535 }
536
537 mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
538 mlmReassocCnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
539 /* Update PE session Id */
540 if (pe_session)
541 mlmReassocCnf.sessionId = pe_session->peSessionId;
542 else
543 mlmReassocCnf.sessionId = 0;
544
545 lim_post_sme_message(mac, LIM_MLM_REASSOC_CNF,
546 (uint32_t *) &mlmReassocCnf);
547 }
548
lim_process_mlm_ft_reassoc_req(struct mac_context * mac,tLimMlmReassocReq * reassoc_req)549 void lim_process_mlm_ft_reassoc_req(struct mac_context *mac,
550 tLimMlmReassocReq *reassoc_req)
551 {
552 struct pe_session *session;
553 uint16_t caps;
554 uint32_t val;
555 QDF_STATUS status;
556 uint32_t teleBcnEn = 0;
557 struct wlan_objmgr_vdev *vdev;
558 struct vdev_mlme_obj *mlme_obj;
559
560 if (!reassoc_req) {
561 pe_err("reassoc_req is NULL");
562 return;
563 }
564
565 session = pe_find_session_by_session_id(mac, reassoc_req->sessionId);
566 if (!session) {
567 pe_err("session Does not exist for given session Id");
568 qdf_mem_free(reassoc_req);
569 return;
570 }
571
572 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
573 lim_diag_event_report(mac, WLAN_PE_DIAG_REASSOCIATING,
574 session, 0, 0);
575 #endif
576
577 /* Nothing to be done if the session is not in STA mode */
578 if (!LIM_IS_STA_ROLE(session)) {
579 pe_err("pe_session is not in STA mode");
580 qdf_mem_free(reassoc_req);
581 return;
582 }
583
584 if (!session->ftPEContext.pAddBssReq) {
585 pe_err("pAddBssReq is NULL");
586 return;
587 }
588
589 qdf_mem_copy(reassoc_req->peerMacAddr,
590 session->bssId, sizeof(tSirMacAddr));
591
592 if (lim_get_capability_info(mac, &caps, session) !=
593 QDF_STATUS_SUCCESS) {
594 /**
595 * Could not get Capabilities value
596 * from CFG. Log error.
597 */
598 pe_err("could not get Capabilities value");
599 qdf_mem_free(reassoc_req);
600 return;
601 }
602
603 lim_update_caps_info_for_bss(mac, &caps,
604 session->pLimReAssocReq->bssDescription.capabilityInfo);
605 pe_debug("Capabilities info FT Reassoc: 0x%X", caps);
606
607 reassoc_req->capabilityInfo = caps;
608
609 /* If telescopic beaconing is enabled, set listen interval
610 to CFG_TELE_BCN_MAX_LI
611 */
612 teleBcnEn = mac->mlme_cfg->sap_cfg.tele_bcn_wakeup_en;
613 if (teleBcnEn)
614 val = mac->mlme_cfg->sap_cfg.tele_bcn_max_li;
615 else
616 val = mac->mlme_cfg->sap_cfg.listen_interval;
617
618 reassoc_req->listenInterval = (uint16_t) val;
619
620 vdev = session->vdev;
621 if (!vdev) {
622 pe_err("vdev is NULL");
623 qdf_mem_free(reassoc_req);
624 return;
625 }
626 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
627 if (!mlme_obj) {
628 pe_err("vdev component object is NULL");
629 return;
630 }
631
632 status = lim_pre_vdev_start(mac, mlme_obj, session);
633 if (QDF_IS_STATUS_ERROR(status)) {
634 qdf_mem_free(reassoc_req);
635 return;
636 }
637 qdf_mem_copy(mlme_obj->mgmt.generic.bssid, session->bssId,
638 QDF_MAC_ADDR_SIZE);
639
640 session->pLimMlmReassocReq = reassoc_req;
641 /* we need to defer the message until we get response back from HAL */
642 SET_LIM_PROCESS_DEFD_MESGS(mac, false);
643 status = wma_add_bss_lfr2_vdev_start(session->vdev,
644 session->ftPEContext.pAddBssReq);
645 if (QDF_IS_STATUS_ERROR(status)) {
646 SET_LIM_PROCESS_DEFD_MESGS(mac, true);
647 pe_err("wma_add_bss_lfr2_vdev_start, reason: %X", status);
648 session->pLimMlmReassocReq = NULL;
649 qdf_mem_free(reassoc_req);
650 }
651 qdf_mem_free(session->ftPEContext.pAddBssReq);
652
653 session->ftPEContext.pAddBssReq = NULL;
654 return;
655 }
656
657