1 /*
2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include "wni_api.h"
21 #include "wni_cfg.h"
22 #include "sir_api.h"
23 #include "sch_api.h"
24 #include "utils_api.h"
25 #include "lim_utils.h"
26 #include "lim_assoc_utils.h"
27 #include "lim_security_utils.h"
28 #include "lim_ser_des_utils.h"
29 #include "lim_timer_utils.h"
30 #include "lim_send_messages.h"
31 #include "lim_admit_control.h"
32 #include "lim_send_messages.h"
33 #include "lim_ft.h"
34 #include "lim_ft_defs.h"
35 #include "lim_session.h"
36 #include "lim_session_utils.h"
37 #include "rrm_api.h"
38 #include "wma_types.h"
39 #include "cds_utils.h"
40 #include "lim_types.h"
41 #include "wlan_policy_mgr_api.h"
42 #include "nan_datapath.h"
43 #include "wlan_reg_services_api.h"
44 #include "wma.h"
45 #include "wlan_pkt_capture_ucfg_api.h"
46 #include "wlan_lmac_if_def.h"
47 #include <lim_mlo.h>
48 #include "wlan_mlo_mgr_sta.h"
49 #include "utils_mlo.h"
50 #include "wlan_mlo_mgr_roam.h"
51 #include "wlan_mlme_api.h"
52
53 #define MAX_SUPPORTED_PEERS_WEP 16
54
55 void lim_process_mlm_join_cnf(struct mac_context *, uint32_t *);
56 void lim_process_mlm_auth_cnf(struct mac_context *, uint32_t *);
57 void lim_process_mlm_assoc_ind(struct mac_context *, uint32_t *);
58 void lim_process_mlm_assoc_cnf(struct mac_context *, uint32_t *);
59 void lim_process_mlm_set_keys_cnf(struct mac_context *, uint32_t *);
60 void lim_process_mlm_disassoc_ind(struct mac_context *, uint32_t *);
61 void lim_process_mlm_disassoc_cnf(struct mac_context *, uint32_t *);
62 static void lim_process_mlm_deauth_ind(struct mac_context *, tLimMlmDeauthInd *);
63 void lim_process_mlm_deauth_cnf(struct mac_context *, uint32_t *);
64 void lim_process_mlm_purge_sta_ind(struct mac_context *, uint32_t *);
65
66 /**
67 * lim_process_mlm_rsp_messages()
68 *
69 ***FUNCTION:
70 * This function is called to processes various MLM response (CNF/IND
71 * messages from MLM State machine.
72 *
73 ***LOGIC:
74 *
75 ***ASSUMPTIONS:
76 *
77 ***NOTE:
78 *
79 * @param mac Pointer to Global MAC structure
80 * @param msgType Indicates the MLM message type
81 * @param *msg_buf A pointer to the MLM message buffer
82 *
83 * @return None
84 */
85 void
lim_process_mlm_rsp_messages(struct mac_context * mac,uint32_t msgType,uint32_t * msg_buf)86 lim_process_mlm_rsp_messages(struct mac_context *mac, uint32_t msgType,
87 uint32_t *msg_buf)
88 {
89
90 if (!msg_buf) {
91 pe_err("Buffer is Pointing to NULL");
92 return;
93 }
94 MTRACE(mac_trace(mac, TRACE_CODE_TX_LIM_MSG, 0, msgType));
95 switch (msgType) {
96 case LIM_MLM_AUTH_CNF:
97 lim_process_mlm_auth_cnf(mac, msg_buf);
98 break;
99 case LIM_MLM_ASSOC_CNF:
100 lim_process_mlm_assoc_cnf(mac, msg_buf);
101 break;
102 case LIM_MLM_START_CNF:
103 lim_process_mlm_start_cnf(mac, msg_buf);
104 break;
105 case LIM_MLM_JOIN_CNF:
106 lim_process_mlm_join_cnf(mac, msg_buf);
107 break;
108 case LIM_MLM_ASSOC_IND:
109 lim_process_mlm_assoc_ind(mac, msg_buf);
110 break;
111 case LIM_MLM_REASSOC_CNF:
112 lim_process_mlm_reassoc_cnf(mac, msg_buf);
113 break;
114 case LIM_MLM_DISASSOC_CNF:
115 lim_process_mlm_disassoc_cnf(mac, msg_buf);
116 break;
117 case LIM_MLM_DISASSOC_IND:
118 lim_process_mlm_disassoc_ind(mac, msg_buf);
119 break;
120 case LIM_MLM_PURGE_STA_IND:
121 lim_process_mlm_purge_sta_ind(mac, msg_buf);
122 break;
123 case LIM_MLM_DEAUTH_CNF:
124 lim_process_mlm_deauth_cnf(mac, msg_buf);
125 break;
126 case LIM_MLM_DEAUTH_IND:
127 lim_process_mlm_deauth_ind(mac, (tLimMlmDeauthInd *)msg_buf);
128 break;
129 case LIM_MLM_SETKEYS_CNF:
130 lim_process_mlm_set_keys_cnf(mac, msg_buf);
131 break;
132 case LIM_MLM_TSPEC_CNF:
133 break;
134 default:
135 break;
136 } /* switch (msgType) */
137 return;
138 } /*** end lim_process_mlm_rsp_messages() ***/
139
140 /**
141 * lim_process_mlm_start_cnf()
142 *
143 ***FUNCTION:
144 * This function is called to processes MLM_START_CNF
145 * message from MLM State machine.
146 *
147 ***LOGIC:
148 *
149 ***ASSUMPTIONS:
150 *
151 ***NOTE:
152 *
153 * @param mac Pointer to Global MAC structure
154 * @param msg_buf A pointer to the MLM message buffer
155 *
156 * @return None
157 */
lim_process_mlm_start_cnf(struct mac_context * mac,uint32_t * msg_buf)158 void lim_process_mlm_start_cnf(struct mac_context *mac, uint32_t *msg_buf)
159 {
160 struct pe_session *pe_session = NULL;
161 tLimMlmStartCnf *pLimMlmStartCnf;
162 uint8_t smesessionId;
163 uint32_t chan_freq, ch_cfreq1 = 0;
164 uint8_t send_bcon_ind = false;
165 enum reg_wifi_band band;
166
167 if (!msg_buf) {
168 pe_err("Buffer is Pointing to NULL");
169 return;
170 }
171 pLimMlmStartCnf = (tLimMlmStartCnf *)msg_buf;
172 pe_session = pe_find_session_by_session_id(mac,
173 pLimMlmStartCnf->sessionId);
174 if (!pe_session) {
175 pe_err("Session does Not exist with given sessionId");
176 return;
177 }
178 smesessionId = pe_session->smeSessionId;
179
180 if (pe_session->limSmeState != eLIM_SME_WT_START_BSS_STATE) {
181 /*
182 * Should not have received Start confirm from MLM
183 * in other states. Log error.
184 */
185 pe_err("received unexpected MLM_START_CNF in state %X",
186 pe_session->limSmeState);
187 return;
188 }
189 if (((tLimMlmStartCnf *)msg_buf)->resultCode == eSIR_SME_SUCCESS) {
190
191 /*
192 * Update global SME state so that Beacon Generation
193 * module starts writing Beacon frames into TFP's
194 * Beacon file register.
195 */
196 pe_session->limSmeState = eLIM_SME_NORMAL_STATE;
197 MTRACE(mac_trace
198 (mac, TRACE_CODE_SME_STATE, pe_session->peSessionId,
199 pe_session->limSmeState));
200 if (pe_session->bssType == eSIR_INFRA_AP_MODE)
201 pe_debug("*** Started BSS in INFRA AP SIDE***");
202 else if (pe_session->bssType == eSIR_NDI_MODE)
203 pe_debug("*** Started BSS in NDI mode ***");
204 else
205 pe_debug("*** Started BSS ***");
206 } else {
207 /* Start BSS is a failure */
208 pe_delete_session(mac, pe_session);
209 pe_session = NULL;
210 pe_err("Start BSS Failed");
211 }
212 lim_send_sme_start_bss_rsp(mac,
213 ((tLimMlmStartCnf *)msg_buf)->resultCode,
214 pe_session, smesessionId);
215 if (pe_session &&
216 (((tLimMlmStartCnf *)msg_buf)->resultCode == eSIR_SME_SUCCESS)) {
217 lim_ndi_mlme_vdev_up_transition(pe_session);
218
219 /* We should start beacon transmission only if the channel
220 * on which we are operating is non-DFS until the channel
221 * availability check is done. The PE will receive an explicit
222 * request from upper layers to start the beacon transmission
223 */
224 chan_freq = pe_session->curr_op_freq;
225 band = wlan_reg_freq_to_band(pe_session->curr_op_freq);
226 if (pe_session->ch_center_freq_seg1)
227 ch_cfreq1 = wlan_reg_chan_band_to_freq(
228 mac->pdev,
229 pe_session->ch_center_freq_seg1,
230 BIT(band));
231
232 if (!LIM_IS_AP_ROLE(pe_session))
233 return;
234 if (pe_session->ch_width == CH_WIDTH_160MHZ) {
235 struct ch_params ch_params = {0};
236
237 if (IS_DOT11_MODE_EHT(pe_session->dot11mode))
238 wlan_reg_set_create_punc_bitmap(&ch_params, true);
239 ch_params.ch_width = pe_session->ch_width;
240 if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac->pdev,
241 chan_freq,
242 &ch_params,
243 REG_CURRENT_PWR_MODE) !=
244 CHANNEL_STATE_DFS)
245 send_bcon_ind = true;
246 } else if (pe_session->ch_width == CH_WIDTH_80P80MHZ) {
247 if ((wlan_reg_get_channel_state_for_pwrmode(
248 mac->pdev, chan_freq,
249 REG_CURRENT_PWR_MODE) !=
250 CHANNEL_STATE_DFS) &&
251 (wlan_reg_get_channel_state_for_pwrmode(
252 mac->pdev, ch_cfreq1,
253 REG_CURRENT_PWR_MODE) !=
254 CHANNEL_STATE_DFS))
255 send_bcon_ind = true;
256 } else {
257 /* Indoor channels are also marked DFS, therefore
258 * check if the channel has REGULATORY_CHAN_RADAR
259 * channel flag to identify if the channel is DFS
260 */
261 if (!wlan_reg_is_dfs_for_freq(mac->pdev, chan_freq))
262 send_bcon_ind = true;
263 }
264 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pe_session->curr_op_freq))
265 send_bcon_ind = true;
266
267 if (send_bcon_ind) {
268 /* Configure beacon and send beacons to HAL */
269 pe_debug("Start Beacon with ssid " QDF_SSID_FMT " Ch freq %d",
270 QDF_SSID_REF(pe_session->ssId.length,
271 pe_session->ssId.ssId),
272 pe_session->curr_op_freq);
273 lim_send_beacon(mac, pe_session);
274 lim_enable_obss_detection_config(mac, pe_session);
275 lim_send_obss_color_collision_cfg(mac, pe_session,
276 OBSS_COLOR_COLLISION_DETECTION);
277 } else {
278 lim_sap_move_to_cac_wait_state(pe_session);
279 }
280 }
281 }
282
283 /*** end lim_process_mlm_start_cnf() ***/
284
285 /**
286 * lim_process_mlm_join_cnf() - Processes join confirmation
287 * @mac_ctx: Pointer to Global MAC structure
288 * @msg: A pointer to the MLM message buffer
289 *
290 * This Function handles the join confirmation message
291 * LIM_MLM_JOIN_CNF.
292 *
293 * Return: None
294 */
lim_process_mlm_join_cnf(struct mac_context * mac_ctx,uint32_t * msg)295 void lim_process_mlm_join_cnf(struct mac_context *mac_ctx,
296 uint32_t *msg)
297 {
298 tSirResultCodes result_code;
299 tLimMlmJoinCnf *join_cnf;
300 struct pe_session *session_entry;
301
302 join_cnf = (tLimMlmJoinCnf *) msg;
303 session_entry = pe_find_session_by_session_id(mac_ctx,
304 join_cnf->sessionId);
305 if (!session_entry) {
306 pe_err("SessionId:%d does not exist", join_cnf->sessionId);
307 return;
308 }
309
310 wlan_connectivity_sta_info_event(mac_ctx->psoc, session_entry->vdev_id,
311 false);
312 wlan_connectivity_connecting_event(session_entry->vdev, NULL);
313
314 session_entry->join_probe_cnt = 0;
315 if (session_entry->limSmeState != eLIM_SME_WT_JOIN_STATE) {
316 pe_err("received unexpected MLM_JOIN_CNF in state %X",
317 session_entry->limSmeState);
318 return;
319 }
320
321 result_code = ((tLimMlmJoinCnf *) msg)->resultCode;
322 /* Process Join confirm from MLM */
323 if (result_code == eSIR_SME_SUCCESS) {
324 /* Setup hardware upfront */
325 if (lim_sta_send_add_bss_pre_assoc(mac_ctx,
326 session_entry) ==
327 QDF_STATUS_SUCCESS)
328 return;
329 else
330 result_code = eSIR_SME_REFUSED;
331 }
332
333 /* Join failure */
334 session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
335 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
336 session_entry->peSessionId,
337 session_entry->limSmeState));
338 /* Send Join response to Host */
339 lim_handle_sme_join_result(mac_ctx, result_code,
340 ((tLimMlmJoinCnf *) msg)->protStatusCode, session_entry);
341 return;
342 }
343
344 /**
345 * lim_send_mlm_assoc_req() - Association request will be processed
346 * mac_ctx: Pointer to Global MAC structure
347 * session_entry: Pointer to session etnry
348 *
349 * This function is sends ASSOC request MLM message to MLM State machine.
350 * ASSOC request packet would be by picking parameters from pe_session
351 * automatically based on the current state of MLM state machine.
352 * ASSUMPTIONS:
353 * this function is called in middle of connection state machine and is
354 * expected to be called after auth cnf has been received or after ASSOC rsp
355 * with TRY_AGAIN_LATER was received and required time has elapsed after that.
356 *
357 * Return: None
358 */
359
lim_send_mlm_assoc_req(struct mac_context * mac_ctx,struct pe_session * session_entry)360 static void lim_send_mlm_assoc_req(struct mac_context *mac_ctx,
361 struct pe_session *session_entry)
362 {
363 tLimMlmAssocReq *assoc_req;
364 uint32_t val;
365 uint16_t caps;
366 uint32_t tele_bcn = 0;
367 tpSirMacCapabilityInfo cap_info;
368
369 if (!session_entry->lim_join_req) {
370 pe_err("Join Request is NULL");
371 /* No need to Assert. JOIN timeout will handle this error */
372 return;
373 }
374
375 assoc_req = qdf_mem_malloc(sizeof(tLimMlmAssocReq));
376 if (!assoc_req) {
377 pe_err("call to AllocateMemory failed for mlmAssocReq");
378 return;
379 }
380 val = sizeof(tSirMacAddr);
381 sir_copy_mac_addr(assoc_req->peerMacAddr, session_entry->bssId);
382
383 if (lim_get_capability_info(mac_ctx, &caps, session_entry)
384 != QDF_STATUS_SUCCESS)
385 /* Could not get Capabilities value from CFG.*/
386 pe_err("could not retrieve Capabilities value");
387
388 /* Clear spectrum management bit if AP doesn't support it */
389 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo &
390 LIM_SPECTRUM_MANAGEMENT_BIT_MASK))
391 /*
392 * AP doesn't support spectrum management
393 * clear spectrum management bit
394 */
395 caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK);
396
397 /* Clear rrm bit if AP doesn't support it */
398 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo &
399 LIM_RRM_BIT_MASK))
400 caps &= (~LIM_RRM_BIT_MASK);
401
402 /* Clear short preamble bit if AP does not support it */
403 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo &
404 (LIM_SHORT_PREAMBLE_BIT_MASK))) {
405 caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK);
406 pe_debug("Clearing short preamble:no AP support");
407 }
408
409 /* Clear immediate block ack bit if AP does not support it */
410 if (!(session_entry->lim_join_req->bssDescription.capabilityInfo &
411 (LIM_IMMEDIATE_BLOCK_ACK_MASK))) {
412 caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK);
413 pe_debug("Clearing Immed Blk Ack:no AP support");
414 }
415
416 assoc_req->capabilityInfo = caps;
417 cap_info = ((tpSirMacCapabilityInfo) &assoc_req->capabilityInfo);
418
419 /*
420 * If telescopic beaconing is enabled, set listen interval to
421 * CFG_TELE_BCN_MAX_LI
422 */
423 tele_bcn = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_wakeup_en;
424 if (tele_bcn)
425 val = mac_ctx->mlme_cfg->sap_cfg.tele_bcn_max_li;
426 else
427 val = mac_ctx->mlme_cfg->sap_cfg.listen_interval;
428
429 #ifdef FEATURE_WLAN_DIAG_SUPPORT
430 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_REQ_EVENT,
431 session_entry, QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
432 #endif
433 assoc_req->listenInterval = (uint16_t) val;
434 pe_debug("Listen Interval : %d", assoc_req->listenInterval);
435 /* Update PE session ID */
436 assoc_req->sessionId = session_entry->peSessionId;
437 session_entry->limPrevSmeState = session_entry->limSmeState;
438 session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
439 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
440 session_entry->peSessionId, session_entry->limSmeState));
441 lim_post_mlm_message(mac_ctx, LIM_MLM_ASSOC_REQ,
442 (uint32_t *) assoc_req);
443 }
444
445 /**
446 * lim_pmf_comeback_timer_callback() -PMF callback handler
447 * @context: Timer context
448 *
449 * This function is called to processes the PMF comeback
450 * callback
451 *
452 * Return: None
453 */
lim_pmf_comeback_timer_callback(void * context)454 void lim_pmf_comeback_timer_callback(void *context)
455 {
456 struct comeback_timer_info *info =
457 (struct comeback_timer_info *)context;
458 struct mac_context *mac_ctx = info->mac;
459 struct pe_session *session;
460
461 session = pe_find_session_by_vdev_id(mac_ctx, info->vdev_id);
462 if (!session) {
463 pe_err("no session found for vdev %d", info->vdev_id);
464 return;
465 }
466
467 if (session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) {
468 pe_debug("Don't send assoc req, timer expire when limMlmState %d vdev id %d",
469 session->limMlmState, session->vdev_id);
470 return;
471 }
472
473 pe_info("comeback later timer expired. sending MLM ASSOC req for vdev %d, session limMlmState %d, info lim_mlm_state %d",
474 session->vdev_id, session->limMlmState, info->lim_mlm_state);
475
476 /* set MLM state such that ASSOC REQ packet will be sent out */
477 session->limPrevMlmState = info->lim_prev_mlm_state;
478 session->limMlmState = info->lim_mlm_state;
479 lim_send_mlm_assoc_req(mac_ctx, session);
480 }
481
482 /**
483 * lim_process_mlm_auth_cnf()-Process Auth confirmation
484 * @mac_ctx: Pointer to Global MAC structure
485 * @msg: A pointer to the MLM message buffer
486 *
487 * This function is called to processes MLM_AUTH_CNF
488 * message from MLM State machine.
489 *
490 * Return: None
491 */
lim_process_mlm_auth_cnf(struct mac_context * mac_ctx,uint32_t * msg)492 void lim_process_mlm_auth_cnf(struct mac_context *mac_ctx, uint32_t *msg)
493 {
494 tAniAuthType auth_type, auth_mode;
495 tLimMlmAuthReq *auth_req;
496 tLimMlmAuthCnf *auth_cnf;
497 struct pe_session *session_entry;
498
499 if (!msg) {
500 pe_err("Buffer is Pointing to NULL");
501 return;
502 }
503 auth_cnf = (tLimMlmAuthCnf *) msg;
504 session_entry = pe_find_session_by_session_id(mac_ctx,
505 auth_cnf->sessionId);
506 if (!session_entry) {
507 pe_err("SessionId:%d session doesn't exist",
508 auth_cnf->sessionId);
509 return;
510 }
511
512 if ((session_entry->limSmeState != eLIM_SME_WT_AUTH_STATE &&
513 session_entry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE) ||
514 LIM_IS_AP_ROLE(session_entry)) {
515 /**
516 * Should not have received AUTH confirm
517 * from MLM in other states or on AP.
518 * Log error
519 */
520 pe_err("SessionId:%d received MLM_AUTH_CNF in state %X",
521 session_entry->peSessionId, session_entry->limSmeState);
522 return;
523 }
524
525 if (auth_cnf->resultCode == eSIR_SME_SUCCESS) {
526 if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) {
527 lim_deactivate_and_change_timer(mac_ctx,
528 eLIM_ASSOC_FAIL_TIMER);
529 lim_send_mlm_assoc_req(mac_ctx, session_entry);
530 } else {
531 /*
532 * Successful Pre-authentication. Send
533 * Pre-auth response to host
534 */
535 session_entry->limSmeState =
536 session_entry->limPrevSmeState;
537 MTRACE(mac_trace
538 (mac_ctx, TRACE_CODE_SME_STATE,
539 session_entry->peSessionId,
540 session_entry->limSmeState));
541 }
542 /* Return for success case */
543 return;
544 }
545 /*
546 * Failure case handle:
547 * Process AUTH confirm from MLM
548 */
549 if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE)
550 auth_type = mac_ctx->mlme_cfg->wep_params.auth_type;
551 else
552 auth_type = mac_ctx->lim.gLimPreAuthType;
553
554 if ((auth_type == eSIR_AUTO_SWITCH) &&
555 (auth_cnf->authType == eSIR_SHARED_KEY) &&
556 ((auth_cnf->protStatusCode == STATUS_NOT_SUPPORTED_AUTH_ALG) ||
557 (auth_cnf->resultCode == eSIR_SME_AUTH_TIMEOUT_RESULT_CODE))) {
558 /*
559 * When shared authentication fails with reason
560 * code "13" and authType set to 'auto switch',
561 * Try with open Authentication
562 */
563 auth_mode = eSIR_OPEN_SYSTEM;
564 /* Trigger MAC based Authentication */
565 auth_req = qdf_mem_malloc(sizeof(tLimMlmAuthReq));
566 if (!auth_req) {
567 pe_err("mlmAuthReq :Memory alloc failed");
568 return;
569 }
570 if (session_entry->limSmeState ==
571 eLIM_SME_WT_AUTH_STATE) {
572 sir_copy_mac_addr(auth_req->peerMacAddr,
573 session_entry->bssId);
574 } else {
575 qdf_mem_copy((uint8_t *)&auth_req->peerMacAddr,
576 (uint8_t *)&mac_ctx->lim.gLimPreAuthPeerAddr,
577 sizeof(tSirMacAddr));
578 }
579 auth_req->authType = auth_mode;
580 /* Update PE session Id */
581 auth_req->sessionId = auth_cnf->sessionId;
582 lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
583 (uint32_t *) auth_req);
584 return;
585 } else {
586 /* MAC based authentication failure */
587 if (session_entry->limSmeState ==
588 eLIM_SME_WT_AUTH_STATE) {
589 pe_err("Auth Failure occurred");
590 session_entry->limSmeState =
591 eLIM_SME_JOIN_FAILURE_STATE;
592 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
593 session_entry->peSessionId,
594 session_entry->limSmeState));
595 session_entry->limMlmState =
596 eLIM_MLM_IDLE_STATE;
597 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
598 session_entry->peSessionId,
599 session_entry->limMlmState));
600
601 /* WAR for some IOT issue on specific AP:
602 * STA failed to connect to SAE AP due to incorrect
603 * password is used. Then AP will still reject the
604 * authentication even correct password is used unless
605 * STA send deauth to AP upon authentication failure.
606 *
607 * Do not send deauth mgmt frame when already in Deauth
608 * state while joining.
609 */
610 if (auth_type == eSIR_AUTH_TYPE_SAE &&
611 auth_cnf->resultCode != eSIR_SME_DEAUTH_WHILE_JOIN) {
612 pe_debug("Send deauth for SAE auth failure");
613 lim_send_deauth_mgmt_frame(mac_ctx,
614 REASON_TIMEDOUT,
615 auth_cnf->peerMacAddr,
616 session_entry, false);
617 }
618
619 /*
620 * Need to send Join response with
621 * auth failure to Host.
622 */
623 lim_handle_sme_join_result(mac_ctx,
624 auth_cnf->resultCode,
625 auth_cnf->protStatusCode,
626 session_entry);
627 } else {
628 /*
629 * Pre-authentication failure.
630 * Send Pre-auth failure response to host
631 */
632 session_entry->limSmeState =
633 session_entry->limPrevSmeState;
634 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
635 session_entry->peSessionId,
636 session_entry->limSmeState));
637 }
638 }
639 }
640
641 /**
642 * lim_process_mlm_assoc_cnf() - Process association confirmation
643 * @mac_ctx: Pointer to Global MAC structure
644 * @msg: A pointer to the MLM message buffer
645 *
646 * This function is called to processes MLM_ASSOC_CNF
647 * message from MLM State machine.
648 *
649 * Return: None
650 */
lim_process_mlm_assoc_cnf(struct mac_context * mac_ctx,uint32_t * msg)651 void lim_process_mlm_assoc_cnf(struct mac_context *mac_ctx,
652 uint32_t *msg)
653 {
654 struct pe_session *session_entry;
655 tLimMlmAssocCnf *assoc_cnf;
656
657 if (!msg) {
658 pe_err("Buffer is Pointing to NULL");
659 return;
660 }
661 assoc_cnf = (tLimMlmAssocCnf *) msg;
662 session_entry = pe_find_session_by_session_id(mac_ctx,
663 assoc_cnf->sessionId);
664 if (!session_entry) {
665 pe_err("SessionId:%d Session does not exist",
666 assoc_cnf->sessionId);
667 return;
668 }
669 if (session_entry->limSmeState != eLIM_SME_WT_ASSOC_STATE ||
670 LIM_IS_AP_ROLE(session_entry)) {
671 /*
672 * Should not have received Assocication confirm
673 * from MLM in other states OR on AP.
674 * Log error
675 */
676 pe_err("SessionId:%d Received MLM_ASSOC_CNF in state %X",
677 session_entry->peSessionId, session_entry->limSmeState);
678 return;
679 }
680 if (((tLimMlmAssocCnf *) msg)->resultCode != eSIR_SME_SUCCESS) {
681 /* Association failure */
682 pe_err("SessionId:%d Association failure resultCode: %d limSmeState:%d",
683 session_entry->peSessionId,
684 ((tLimMlmAssocCnf *) msg)->resultCode,
685 session_entry->limSmeState);
686
687 /* If driver gets deauth when its waiting for ADD_STA_RSP then
688 * we need to do DEL_STA followed by DEL_BSS. So based on below
689 * reason-code here we decide whether to do only DEL_BSS or
690 * DEL_STA + DEL_BSS.
691 */
692 if (((tLimMlmAssocCnf *) msg)->resultCode !=
693 eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA)
694 session_entry->limSmeState =
695 eLIM_SME_JOIN_FAILURE_STATE;
696
697 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
698 session_entry->peSessionId, mac_ctx->lim.gLimSmeState));
699 /*
700 * Need to send Join response with
701 * Association failure to Host.
702 */
703 lim_handle_sme_join_result(mac_ctx,
704 ((tLimMlmAssocCnf *) msg)->resultCode,
705 ((tLimMlmAssocCnf *) msg)->protStatusCode,
706 session_entry);
707 } else {
708 /* Successful Association */
709 pe_debug("SessionId:%d Associated with BSS",
710 session_entry->peSessionId);
711 session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
712 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
713 session_entry->peSessionId,
714 session_entry->limSmeState));
715 /**
716 * Need to send Join response with
717 * Association success to Host.
718 */
719 lim_handle_sme_join_result(mac_ctx,
720 ((tLimMlmAssocCnf *) msg)->resultCode,
721 ((tLimMlmAssocCnf *) msg)->protStatusCode,
722 session_entry);
723 }
724 }
725
726 #ifdef WLAN_FEATURE_11BE_MLO
727 static void
lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind * sme_assoc_ind,tpLimMlmAssocInd assoc_ind,uint32_t num_bytes)728 lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind *sme_assoc_ind,
729 tpLimMlmAssocInd assoc_ind,
730 uint32_t num_bytes)
731 {
732 qdf_mem_copy(sme_assoc_ind->peer_mld_addr, assoc_ind->peer_mld_addr,
733 num_bytes);
734 }
735
736 /**
737 * lim_update_connected_links() - Update connected mlo links bmap
738 * @session: Pointer to pe session
739 *
740 * Update connected mlo links bmap for all vdev taking
741 * part in association
742 *
743 * Return: None
744 */
lim_update_connected_links(struct pe_session * session)745 static void lim_update_connected_links(struct pe_session *session)
746 {
747 mlo_update_connected_links(session->vdev, 1);
748 mlo_update_connected_links_bmap(session->vdev->mlo_dev_ctx,
749 session->ml_partner_info);
750 }
751 #else /* WLAN_FEATURE_11BE_MLO */
752 static inline void
lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind * sme_assoc_ind,tpLimMlmAssocInd assoc_ind,uint32_t num_bytes)753 lim_fill_sme_assoc_ind_mlo_mld_addr_copy(struct assoc_ind *sme_assoc_ind,
754 tpLimMlmAssocInd assoc_ind,
755 uint32_t num_bytes)
756 {
757 }
758
lim_update_connected_links(struct pe_session * session)759 static void lim_update_connected_links(struct pe_session *session)
760 {
761 }
762 #endif /* WLAN_FEATURE_11BE_MLO */
763
764 void
lim_fill_sme_assoc_ind_params(struct mac_context * mac_ctx,tpLimMlmAssocInd assoc_ind,struct assoc_ind * sme_assoc_ind,struct pe_session * session_entry,bool assoc_req_alloc)765 lim_fill_sme_assoc_ind_params(
766 struct mac_context *mac_ctx,
767 tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind,
768 struct pe_session *session_entry, bool assoc_req_alloc)
769 {
770 sme_assoc_ind->length = sizeof(struct assoc_ind);
771 sme_assoc_ind->sessionId = session_entry->smeSessionId;
772
773 /* Required for indicating the frames to upper layer */
774 sme_assoc_ind->assocReqLength = assoc_ind->assocReqLength;
775 if (assoc_req_alloc && assoc_ind->assocReqLength) {
776 sme_assoc_ind->assocReqPtr = qdf_mem_malloc(
777 assoc_ind->assocReqLength);
778 qdf_mem_copy(sme_assoc_ind->assocReqPtr, assoc_ind->assocReqPtr,
779 assoc_ind->assocReqLength);
780 } else {
781 sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr;
782 }
783
784 /* Fill in peerMacAddr */
785 qdf_mem_copy(sme_assoc_ind->peerMacAddr, assoc_ind->peerMacAddr,
786 sizeof(tSirMacAddr));
787 lim_fill_sme_assoc_ind_mlo_mld_addr_copy(sme_assoc_ind, assoc_ind,
788 sizeof(tSirMacAddr));
789 /* Fill in aid */
790 sme_assoc_ind->aid = assoc_ind->aid;
791 /* Fill in bssId */
792 qdf_mem_copy(sme_assoc_ind->bssId, session_entry->bssId,
793 sizeof(tSirMacAddr));
794 /* Fill in authType */
795 sme_assoc_ind->authType = assoc_ind->authType;
796 /* Fill in rsn_akm_type */
797 sme_assoc_ind->akm_type = assoc_ind->akm_type;
798 /* Fill in ssId */
799 qdf_mem_copy((uint8_t *) &sme_assoc_ind->ssId,
800 (uint8_t *) &(assoc_ind->ssId), assoc_ind->ssId.length + 1);
801 sme_assoc_ind->rsnIE.length = assoc_ind->rsnIE.length;
802 qdf_mem_copy((uint8_t *) &sme_assoc_ind->rsnIE.rsnIEdata,
803 (uint8_t *) &(assoc_ind->rsnIE.rsnIEdata),
804 assoc_ind->rsnIE.length);
805
806 #ifdef FEATURE_WLAN_WAPI
807 sme_assoc_ind->wapiIE.length = assoc_ind->wapiIE.length;
808 qdf_mem_copy((uint8_t *) &sme_assoc_ind->wapiIE.wapiIEdata,
809 (uint8_t *) &(assoc_ind->wapiIE.wapiIEdata),
810 assoc_ind->wapiIE.length);
811 #endif
812 sme_assoc_ind->addIE.length = assoc_ind->addIE.length;
813 qdf_mem_copy((uint8_t *) &sme_assoc_ind->addIE.addIEdata,
814 (uint8_t *) &(assoc_ind->addIE.addIEdata),
815 assoc_ind->addIE.length);
816
817 /* Copy the new TITAN capabilities */
818 sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator;
819 if (assoc_ind->spectrumMgtIndicator == true) {
820 sme_assoc_ind->powerCap.minTxPower =
821 assoc_ind->powerCap.minTxPower;
822 sme_assoc_ind->powerCap.maxTxPower =
823 assoc_ind->powerCap.maxTxPower;
824 sme_assoc_ind->supportedChannels.numChnl =
825 assoc_ind->supportedChannels.numChnl;
826 qdf_mem_copy((uint8_t *) &sme_assoc_ind->supportedChannels.
827 channelList,
828 (uint8_t *) &(assoc_ind->supportedChannels.channelList),
829 assoc_ind->supportedChannels.numChnl);
830 }
831 qdf_mem_copy(&sme_assoc_ind->chan_info, &assoc_ind->chan_info,
832 sizeof(struct oem_channel_info));
833 /* Fill in WmmInfo */
834 sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent;
835 sme_assoc_ind->ampdu = assoc_ind->ampdu;
836 sme_assoc_ind->sgi_enable = assoc_ind->sgi_enable;
837 sme_assoc_ind->tx_stbc = assoc_ind->tx_stbc;
838 sme_assoc_ind->rx_stbc = assoc_ind->rx_stbc;
839 sme_assoc_ind->ch_width = assoc_ind->ch_width;
840 sme_assoc_ind->mode = assoc_ind->mode;
841 sme_assoc_ind->max_supp_idx = assoc_ind->max_supp_idx;
842 sme_assoc_ind->max_ext_idx = assoc_ind->max_ext_idx;
843 sme_assoc_ind->max_mcs_idx = assoc_ind->max_mcs_idx;
844 sme_assoc_ind->max_real_mcs_idx = assoc_ind->max_real_mcs_idx;
845 sme_assoc_ind->rx_mcs_map = assoc_ind->rx_mcs_map;
846 sme_assoc_ind->tx_mcs_map = assoc_ind->tx_mcs_map;
847 sme_assoc_ind->ecsa_capable = assoc_ind->ecsa_capable;
848 sme_assoc_ind->ext_cap = assoc_ind->ext_cap;
849 sme_assoc_ind->supported_band = assoc_ind->supported_band;
850
851 if (assoc_ind->ht_caps.present)
852 sme_assoc_ind->HTCaps = assoc_ind->ht_caps;
853 if (assoc_ind->vht_caps.present)
854 sme_assoc_ind->VHTCaps = assoc_ind->vht_caps;
855 sme_assoc_ind->capability_info = assoc_ind->capabilityInfo;
856 sme_assoc_ind->he_caps_present = assoc_ind->he_caps_present;
857 sme_assoc_ind->eht_caps_present = assoc_ind->eht_caps_present;
858 sme_assoc_ind->is_sae_authenticated = assoc_ind->is_sae_authenticated;
859 }
860
861 /**
862 * lim_process_mlm_assoc_ind() - This function is called to processes MLM_ASSOC_IND
863 * message from MLM State machine.
864 * @mac Pointer to Global MAC structure
865 * @msg_buf A pointer to the MLM message buffer
866 *
867 * Return: None
868 */
lim_process_mlm_assoc_ind(struct mac_context * mac,uint32_t * msg_buf)869 void lim_process_mlm_assoc_ind(struct mac_context *mac, uint32_t *msg_buf)
870 {
871 uint32_t len;
872 struct scheduler_msg msg = {0};
873 struct assoc_ind *pSirSmeAssocInd;
874 tpDphHashNode sta = 0;
875 struct pe_session *pe_session;
876
877 if (!msg_buf) {
878 pe_err("Buffer is Pointing to NULL");
879 return;
880 }
881 pe_session = pe_find_session_by_session_id(mac,
882 ((tpLimMlmAssocInd) msg_buf)->sessionId);
883 if (!pe_session) {
884 pe_err("Session Does not exist for given sessionId");
885 return;
886 }
887 /* / Inform Host of STA association */
888 len = sizeof(struct assoc_ind);
889 pSirSmeAssocInd = qdf_mem_malloc(len);
890 if (!pSirSmeAssocInd) {
891 pe_err("call to AllocateMemory failed for eWNI_SME_ASSOC_IND");
892 return;
893 }
894
895 pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND;
896 lim_fill_sme_assoc_ind_params(mac, (tpLimMlmAssocInd)msg_buf,
897 pSirSmeAssocInd,
898 pe_session, false);
899 msg.type = eWNI_SME_ASSOC_IND;
900 msg.bodyptr = pSirSmeAssocInd;
901 msg.bodyval = 0;
902 sta = dph_get_hash_entry(mac,
903 ((tpLimMlmAssocInd) msg_buf)->aid,
904 &pe_session->dph.dphHashTable);
905 if (!sta) {
906 pe_err("MLM AssocInd: Station context no longer valid (aid %d)",
907 ((tpLimMlmAssocInd) msg_buf)->aid);
908 qdf_mem_free(pSirSmeAssocInd);
909
910 return;
911 }
912
913 pSirSmeAssocInd->reassocReq = sta->mlmStaContext.subType;
914 pSirSmeAssocInd->timingMeasCap = sta->timingMeasCap;
915 MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG,
916 pe_session->peSessionId, msg.type));
917 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
918 lim_diag_event_report(mac, WLAN_PE_DIAG_ASSOC_IND_EVENT, pe_session, 0,
919 0);
920 #endif /* FEATURE_WLAN_DIAG_SUPPORT */
921 pe_debug("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND");
922 /*
923 ** turn on a timer to detect the loss of ASSOC CNF
924 **/
925 lim_activate_cnf_timer(mac,
926 (uint16_t) ((tpLimMlmAssocInd)msg_buf)->aid,
927 pe_session);
928
929 mac->lim.sme_msg_callback(mac, &msg);
930 } /*** end lim_process_mlm_assoc_ind() ***/
931
932 /**
933 * lim_process_mlm_disassoc_ind() - This function is called to processes
934 * MLM_DISASSOC_IND message from MLM State machine.
935 * @mac: Pointer to Global MAC structure
936 * @msg_buf: A pointer to the MLM message buffer
937 *
938 * Return None
939 */
lim_process_mlm_disassoc_ind(struct mac_context * mac,uint32_t * msg_buf)940 void lim_process_mlm_disassoc_ind(struct mac_context *mac, uint32_t *msg_buf)
941 {
942 tLimMlmDisassocInd *pMlmDisassocInd;
943 struct pe_session *pe_session;
944
945 pMlmDisassocInd = (tLimMlmDisassocInd *)msg_buf;
946 pe_session = pe_find_session_by_session_id(mac,
947 pMlmDisassocInd->sessionId);
948 if (!pe_session) {
949 pe_err("Session Does not exist for given sessionID");
950 return;
951 }
952 switch (GET_LIM_SYSTEM_ROLE(pe_session)) {
953 case eLIM_STA_ROLE:
954 pe_session->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
955 MTRACE(mac_trace
956 (mac, TRACE_CODE_SME_STATE, pe_session->peSessionId,
957 pe_session->limSmeState));
958 break;
959 default: /* eLIM_AP_ROLE */
960 pe_debug("*** Peer staId=%d Disassociated ***",
961 pMlmDisassocInd->aid);
962 /* Send SME_DISASOC_IND after Polaris cleanup */
963 /* (after receiving LIM_MLM_PURGE_STA_IND) */
964 break;
965 } /* end switch (GET_LIM_SYSTEM_ROLE(pe_session)) */
966 } /*** end lim_process_mlm_disassoc_ind() ***/
967
968 /**
969 * lim_process_mlm_disassoc_cnf() - Processes disassociation
970 * @mac_ctx: Pointer to Global MAC structure
971 * @msg: A pointer to the MLM message buffer
972 *
973 * This function is called to processes MLM_DISASSOC_CNF
974 * message from MLM State machine.
975 *
976 * Return: None
977 */
lim_process_mlm_disassoc_cnf(struct mac_context * mac_ctx,uint32_t * msg)978 void lim_process_mlm_disassoc_cnf(struct mac_context *mac_ctx,
979 uint32_t *msg)
980 {
981 tSirResultCodes result_code;
982 tLimMlmDisassocCnf *disassoc_cnf;
983 struct pe_session *session_entry;
984
985 disassoc_cnf = (tLimMlmDisassocCnf *) msg;
986
987 session_entry =
988 pe_find_session_by_session_id(mac_ctx, disassoc_cnf->sessionId);
989 if (!session_entry) {
990 pe_err("session Does not exist for given session Id");
991 return;
992 }
993 result_code = (tSirResultCodes)(disassoc_cnf->disassocTrigger ==
994 eLIM_LINK_MONITORING_DISASSOC) ?
995 eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
996 disassoc_cnf->resultCode;
997 if (LIM_IS_STA_ROLE(session_entry)) {
998 /* Disassociate Confirm from MLM */
999 if ((session_entry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
1000 && (session_entry->limSmeState !=
1001 eLIM_SME_WT_DEAUTH_STATE)) {
1002 /*
1003 * Should not have received
1004 * Disassociate confirm
1005 * from MLM in other states.Log error
1006 */
1007 pe_err("received MLM_DISASSOC_CNF in state %X",
1008 session_entry->limSmeState);
1009 return;
1010 }
1011 if (mac_ctx->lim.gLimRspReqd)
1012 mac_ctx->lim.gLimRspReqd = false;
1013 if (disassoc_cnf->disassocTrigger ==
1014 eLIM_PROMISCUOUS_MODE_DISASSOC) {
1015 if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
1016 session_entry->limSmeState =
1017 session_entry->limPrevSmeState;
1018 else
1019 session_entry->limSmeState =
1020 eLIM_SME_OFFLINE_STATE;
1021 MTRACE(mac_trace
1022 (mac_ctx, TRACE_CODE_SME_STATE,
1023 session_entry->peSessionId,
1024 session_entry->limSmeState));
1025 } else {
1026 if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
1027 session_entry->limSmeState =
1028 session_entry->limPrevSmeState;
1029 else
1030 session_entry->limSmeState =
1031 eLIM_SME_IDLE_STATE;
1032 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
1033 session_entry->peSessionId,
1034 session_entry->limSmeState));
1035 lim_send_sme_disassoc_ntf(mac_ctx,
1036 disassoc_cnf->peerMacAddr, result_code,
1037 disassoc_cnf->disassocTrigger,
1038 disassoc_cnf->aid, session_entry->smeSessionId,
1039 session_entry);
1040 }
1041 } else if (LIM_IS_AP_ROLE(session_entry)) {
1042 lim_send_sme_disassoc_ntf(mac_ctx, disassoc_cnf->peerMacAddr,
1043 result_code, disassoc_cnf->disassocTrigger,
1044 disassoc_cnf->aid, session_entry->smeSessionId,
1045 session_entry);
1046 }
1047 }
1048
1049 /**
1050 * lim_process_mlm_deauth_ind() - processes MLM_DEAUTH_IND
1051 * @mac_ctx: global mac structure
1052 * @deauth_ind: deauth indication
1053 *
1054 * This function is called to processes MLM_DEAUTH_IND
1055 * message from MLM State machine.
1056 *
1057 * Return: None
1058 */
lim_process_mlm_deauth_ind(struct mac_context * mac_ctx,tLimMlmDeauthInd * deauth_ind)1059 static void lim_process_mlm_deauth_ind(struct mac_context *mac_ctx,
1060 tLimMlmDeauthInd *deauth_ind)
1061 {
1062 struct pe_session *session;
1063 uint8_t session_id;
1064 enum eLimSystemRole role;
1065
1066 if (!deauth_ind) {
1067 pe_err("deauth_ind is null");
1068 return;
1069 }
1070 session = pe_find_session_by_bssid(mac_ctx,
1071 deauth_ind->peerMacAddr,
1072 &session_id);
1073 if (!session) {
1074 pe_err("session does not exist for Addr:" QDF_MAC_ADDR_FMT,
1075 QDF_MAC_ADDR_REF(deauth_ind->peerMacAddr));
1076 return;
1077 }
1078 role = GET_LIM_SYSTEM_ROLE(session);
1079 if (role == eLIM_STA_ROLE) {
1080 session->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
1081 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
1082 session->peSessionId, session->limSmeState));
1083 }
1084 }
1085
1086 /**
1087 * lim_process_mlm_deauth_cnf()
1088 *
1089 ***FUNCTION:
1090 * This function is called to processes MLM_DEAUTH_CNF
1091 * message from MLM State machine.
1092 *
1093 ***LOGIC:
1094 *
1095 ***ASSUMPTIONS:
1096 *
1097 ***NOTE:
1098 *
1099 * @param mac Pointer to Global MAC structure
1100 * @param msg_buf A pointer to the MLM message buffer
1101 *
1102 * @return None
1103 */
lim_process_mlm_deauth_cnf(struct mac_context * mac,uint32_t * msg_buf)1104 void lim_process_mlm_deauth_cnf(struct mac_context *mac, uint32_t *msg_buf)
1105 {
1106 uint16_t aid;
1107 tSirResultCodes resultCode;
1108 tLimMlmDeauthCnf *pMlmDeauthCnf;
1109 struct pe_session *pe_session;
1110
1111 if (!msg_buf) {
1112 pe_err("Buffer is Pointing to NULL");
1113 return;
1114 }
1115 pMlmDeauthCnf = (tLimMlmDeauthCnf *)msg_buf;
1116 pe_session = pe_find_session_by_session_id(mac,
1117 pMlmDeauthCnf->sessionId);
1118 if (!pe_session) {
1119 pe_err("session does not exist for given session Id");
1120 return;
1121 }
1122
1123 resultCode = (tSirResultCodes)
1124 (pMlmDeauthCnf->deauthTrigger ==
1125 eLIM_LINK_MONITORING_DEAUTH) ?
1126 eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
1127 pMlmDeauthCnf->resultCode;
1128 aid = LIM_IS_AP_ROLE(pe_session) ? pMlmDeauthCnf->aid : 1;
1129 if (LIM_IS_STA_ROLE(pe_session)) {
1130 /* Deauth Confirm from MLM */
1131 if ((pe_session->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
1132 && pe_session->limSmeState !=
1133 eLIM_SME_WT_DEAUTH_STATE) {
1134 /**
1135 * Should not have received Deauth confirm
1136 * from MLM in other states.
1137 * Log error
1138 */
1139 pe_err("received unexpected MLM_DEAUTH_CNF in state %X",
1140 pe_session->limSmeState);
1141 return;
1142 }
1143 if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) {
1144 pe_session->limSmeState = eLIM_SME_IDLE_STATE;
1145 } else
1146 pe_session->limSmeState =
1147 pe_session->limPrevSmeState;
1148 MTRACE(mac_trace
1149 (mac, TRACE_CODE_SME_STATE, pe_session->peSessionId,
1150 pe_session->limSmeState));
1151
1152 if (mac->lim.gLimRspReqd)
1153 mac->lim.gLimRspReqd = false;
1154 }
1155 /* On STA or on BASIC AP, send SME_DEAUTH_RSP to host */
1156 lim_send_sme_deauth_ntf(mac, pMlmDeauthCnf->peer_macaddr.bytes,
1157 resultCode,
1158 pMlmDeauthCnf->deauthTrigger,
1159 aid, pe_session->smeSessionId);
1160 } /*** end lim_process_mlm_deauth_cnf() ***/
1161
1162 /**
1163 * lim_process_mlm_purge_sta_ind()
1164 *
1165 ***FUNCTION:
1166 * This function is called to processes MLM_PURGE_STA_IND
1167 * message from MLM State machine.
1168 *
1169 ***LOGIC:
1170 *
1171 ***ASSUMPTIONS:
1172 *
1173 ***NOTE:
1174 *
1175 * @param mac Pointer to Global MAC structure
1176 * @param msg_buf A pointer to the MLM message buffer
1177 *
1178 * @return None
1179 */
lim_process_mlm_purge_sta_ind(struct mac_context * mac,uint32_t * msg_buf)1180 void lim_process_mlm_purge_sta_ind(struct mac_context *mac, uint32_t *msg_buf)
1181 {
1182 tSirResultCodes resultCode;
1183 tpLimMlmPurgeStaInd pMlmPurgeStaInd;
1184 struct pe_session *pe_session;
1185
1186 if (!msg_buf) {
1187 pe_err("Buffer is Pointing to NULL");
1188 return;
1189 }
1190 pMlmPurgeStaInd = (tpLimMlmPurgeStaInd)msg_buf;
1191 pe_session = pe_find_session_by_session_id(mac,
1192 pMlmPurgeStaInd->sessionId);
1193 if (!pe_session) {
1194 pe_err("session does not exist for given bssId");
1195 return;
1196 }
1197 /* Purge STA indication from MLM */
1198 resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode;
1199 switch (GET_LIM_SYSTEM_ROLE(pe_session)) {
1200 case eLIM_STA_ROLE:
1201 default: /* eLIM_AP_ROLE */
1202 if (LIM_IS_STA_ROLE(pe_session) &&
1203 (pe_session->limSmeState !=
1204 eLIM_SME_WT_DISASSOC_STATE) &&
1205 (pe_session->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
1206 /**
1207 * Should not have received
1208 * Purge STA indication
1209 * from MLM in other states.
1210 * Log error
1211 */
1212 pe_err("received unexpected MLM_PURGE_STA_IND in state %X",
1213 pe_session->limSmeState);
1214 break;
1215 }
1216 pe_debug("*** Cleanup completed for staId=%d ***",
1217 pMlmPurgeStaInd->aid);
1218 if (LIM_IS_STA_ROLE(pe_session)) {
1219 pe_session->limSmeState = eLIM_SME_IDLE_STATE;
1220 MTRACE(mac_trace
1221 (mac, TRACE_CODE_SME_STATE,
1222 pe_session->peSessionId,
1223 pe_session->limSmeState));
1224
1225 }
1226 if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) {
1227 lim_send_sme_deauth_ntf(mac,
1228 pMlmPurgeStaInd->peerMacAddr,
1229 resultCode,
1230 pMlmPurgeStaInd->purgeTrigger,
1231 pMlmPurgeStaInd->aid,
1232 pe_session->smeSessionId);
1233 } else
1234 lim_send_sme_disassoc_ntf(mac,
1235 pMlmPurgeStaInd->peerMacAddr,
1236 resultCode,
1237 pMlmPurgeStaInd->purgeTrigger,
1238 pMlmPurgeStaInd->aid,
1239 pe_session->smeSessionId,
1240 pe_session);
1241 } /* end switch (GET_LIM_SYSTEM_ROLE(pe_session)) */
1242 } /*** end lim_process_mlm_purge_sta_ind() ***/
1243
1244 /**
1245 * lim_process_mlm_set_keys_cnf()
1246 *
1247 ***FUNCTION:
1248 * This function is called to processes MLM_SETKEYS_CNF
1249 * message from MLM State machine.
1250 *
1251 ***LOGIC:
1252 *
1253 ***ASSUMPTIONS:
1254 *
1255 ***NOTE:
1256 *
1257 * @param mac Pointer to Global MAC structure
1258 * @param msg_buf A pointer to the MLM message buffer
1259 *
1260 * @return None
1261 */
lim_process_mlm_set_keys_cnf(struct mac_context * mac,uint32_t * msg_buf)1262 void lim_process_mlm_set_keys_cnf(struct mac_context *mac, uint32_t *msg_buf)
1263 {
1264 /* Prepare and send SME_SETCONTEXT_RSP message */
1265 tLimMlmSetKeysCnf *pMlmSetKeysCnf;
1266 struct pe_session *pe_session;
1267 uint16_t aid;
1268 tpDphHashNode sta_ds = NULL;
1269
1270 if (!msg_buf) {
1271 pe_err("Buffer is Pointing to NULL");
1272 return;
1273 }
1274 pMlmSetKeysCnf = (tLimMlmSetKeysCnf *)msg_buf;
1275 pe_session = pe_find_session_by_session_id(mac,
1276 pMlmSetKeysCnf->sessionId);
1277 if (!pe_session) {
1278 pe_err("session does not exist for given sessionId %d",
1279 pMlmSetKeysCnf->sessionId);
1280 return;
1281 }
1282 /* if the status is success keys are installed in the
1283 * Firmware so we can set the protection bit
1284 */
1285 if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) {
1286 sta_ds = dph_lookup_hash_entry(mac,
1287 pMlmSetKeysCnf->peer_macaddr.bytes,
1288 &aid, &pe_session->dph.dphHashTable);
1289 if (sta_ds && pMlmSetKeysCnf->key_len_nonzero)
1290 sta_ds->is_key_installed = 1;
1291 }
1292 pe_debug("vdev %d: " QDF_MAC_ADDR_FMT " Status %d key_len_nonzero %d key installed %d",
1293 pe_session->vdev_id,
1294 QDF_MAC_ADDR_REF(pMlmSetKeysCnf->peer_macaddr.bytes),
1295 pMlmSetKeysCnf->resultCode,
1296 pMlmSetKeysCnf->key_len_nonzero,
1297 sta_ds ? sta_ds->is_key_installed : 0);
1298
1299 lim_send_sme_set_context_rsp(mac,
1300 pMlmSetKeysCnf->peer_macaddr,
1301 1,
1302 (tSirResultCodes) pMlmSetKeysCnf->resultCode,
1303 pe_session, pe_session->smeSessionId);
1304
1305 wlan_mlme_update_bw_no_punct(mac->psoc, pe_session->vdev_id);
1306 } /*** end lim_process_mlm_set_keys_cnf() ***/
1307
lim_update_lost_link_rssi(struct mac_context * mac,uint32_t rssi)1308 void lim_update_lost_link_rssi(struct mac_context *mac, uint32_t rssi)
1309 {
1310 if (!mac) {
1311 pe_debug("mac is null");
1312 return;
1313 }
1314
1315 mac->lim.bss_rssi = rssi;
1316 }
1317
lim_join_result_callback(struct mac_context * mac,uint8_t vdev_id)1318 void lim_join_result_callback(struct mac_context *mac,
1319 uint8_t vdev_id)
1320 {
1321 struct pe_session *session;
1322
1323 session = pe_find_session_by_vdev_id(mac, vdev_id);
1324 if (!session) {
1325 return;
1326 }
1327 lim_send_sme_join_reassoc_rsp(mac, eWNI_SME_JOIN_RSP,
1328 session->result_code,
1329 session->prot_status_code,
1330 session, vdev_id);
1331 pe_delete_session(mac, session);
1332 }
1333
lim_sta_handle_connect_fail(join_params * param)1334 QDF_STATUS lim_sta_handle_connect_fail(join_params *param)
1335 {
1336 struct pe_session *session;
1337 struct mac_context *mac_ctx;
1338 tpDphHashNode sta_ds = NULL;
1339 QDF_STATUS status;
1340
1341 if (!param) {
1342 pe_err("param is NULL");
1343 return QDF_STATUS_E_INVAL;
1344 }
1345
1346 mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1347 if (!mac_ctx)
1348 return QDF_STATUS_E_INVAL;
1349
1350 session = pe_find_session_by_session_id(mac_ctx, param->pe_session_id);
1351 if (!session) {
1352 pe_err("session is NULL");
1353 return QDF_STATUS_E_INVAL;
1354 }
1355
1356 sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
1357 &session->dph.dphHashTable);
1358 if (sta_ds) {
1359 sta_ds->mlmStaContext.disassocReason =
1360 REASON_UNSPEC_FAILURE;
1361 sta_ds->mlmStaContext.cleanupTrigger =
1362 eLIM_JOIN_FAILURE;
1363 sta_ds->mlmStaContext.resultCode = param->result_code;
1364 sta_ds->mlmStaContext.protStatusCode = param->prot_status_code;
1365 /*
1366 * FIX_ME: at the end of lim_cleanup_rx_path,
1367 * make sure PE is sending eWNI_SME_JOIN_RSP
1368 * to SME
1369 */
1370 lim_mlo_notify_peer_disconn(session, sta_ds);
1371 lim_cleanup_rx_path(mac_ctx, sta_ds, session, true);
1372 qdf_mem_free(session->lim_join_req);
1373 session->lim_join_req = NULL;
1374 /* Cleanup if add bss failed */
1375 if (session->add_bss_failed) {
1376 dph_delete_hash_entry(mac_ctx,
1377 sta_ds->staAddr, sta_ds->assocId,
1378 &session->dph.dphHashTable);
1379 goto error;
1380 }
1381 return QDF_STATUS_SUCCESS;
1382 } else {
1383 lim_mlo_sta_notify_peer_disconn(session);
1384 }
1385 qdf_mem_free(session->lim_join_req);
1386 session->lim_join_req = NULL;
1387
1388 error:
1389 session->prot_status_code = param->prot_status_code;
1390 session->result_code = param->result_code;
1391
1392 status = wma_send_vdev_stop(session->smeSessionId);
1393 if (QDF_IS_STATUS_ERROR(status))
1394 lim_join_result_callback(mac_ctx, session->smeSessionId);
1395
1396 return status;
1397 }
1398
1399 /**
1400 * lim_handle_sme_join_result() - Handles sme join result
1401 * @mac_ctx: Pointer to Global MAC structure
1402 * @result_code: Failure code to be sent
1403 * @prot_status_code : Protocol status code
1404 * @session_entry: PE session handle
1405 *
1406 * This function is called to process join/auth/assoc failures
1407 * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or
1408 * MLM_ASSOC_CNF with a success code in case of STA role and
1409 * MLM_JOIN_CNF with success in case of STA in IBSS role.
1410 *
1411 * Return: None
1412 */
lim_handle_sme_join_result(struct mac_context * mac_ctx,tSirResultCodes result_code,uint16_t prot_status_code,struct pe_session * session)1413 void lim_handle_sme_join_result(struct mac_context *mac_ctx,
1414 tSirResultCodes result_code, uint16_t prot_status_code,
1415 struct pe_session *session)
1416 {
1417 join_params param;
1418 QDF_STATUS status;
1419
1420 if (!session) {
1421 pe_err("session is NULL");
1422 return;
1423 }
1424
1425 if (result_code == eSIR_SME_SUCCESS) {
1426 if (wlan_vdev_mlme_is_mlo_vdev(session->vdev))
1427 lim_update_connected_links(session);
1428 wlan_vdev_mlme_sm_deliver_evt(session->vdev,
1429 WLAN_VDEV_SM_EV_START_SUCCESS,
1430 0, NULL);
1431 return lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
1432 result_code,
1433 prot_status_code, session,
1434 session->smeSessionId);
1435 }
1436
1437 param.result_code = result_code;
1438 param.prot_status_code = prot_status_code;
1439 param.pe_session_id = session->peSessionId;
1440
1441 mlme_set_connection_fail(session->vdev, true);
1442 if (wlan_vdev_mlme_get_substate(session->vdev) ==
1443 WLAN_VDEV_SS_START_START_PROGRESS) {
1444 mlme_set_vdev_start_failed(session->vdev, true);
1445 status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
1446 WLAN_VDEV_SM_EV_START_REQ_FAIL,
1447 sizeof(param), ¶m);
1448 }
1449 else
1450 status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
1451 WLAN_VDEV_SM_EV_CONNECTION_FAIL,
1452 sizeof(param), ¶m);
1453
1454 return;
1455 }
1456
1457
1458 /**
1459 * lim_process_mlm_add_sta_rsp()
1460 *
1461 ***FUNCTION:
1462 * This function is called to process a WMA_ADD_STA_RSP from HAL.
1463 * Upon receipt of this message from HAL, MLME -
1464 * > Determines the "state" in which this message was received
1465 * > Forwards it to the appropriate callback
1466 *
1467 ***ASSUMPTIONS:
1468 *
1469 ***NOTE:
1470 *
1471 * @param mac Pointer to Global MAC structure
1472 * @param struct scheduler_msg The MsgQ header, which contains the
1473 * response buffer
1474 *
1475 * @return None
1476 */
lim_process_mlm_add_sta_rsp(struct mac_context * mac,struct scheduler_msg * limMsgQ,struct pe_session * pe_session)1477 void lim_process_mlm_add_sta_rsp(struct mac_context *mac,
1478 struct scheduler_msg *limMsgQ,
1479 struct pe_session *pe_session)
1480 {
1481 /* we need to process the deferred message since the initiating req. there might be nested request. */
1482 /* in the case of nested request the new request initiated from the response will take care of resetting */
1483 /* the deferred flag. */
1484 SET_LIM_PROCESS_DEFD_MESGS(mac, true);
1485 if (LIM_IS_AP_ROLE(pe_session)) {
1486 lim_process_ap_mlm_add_sta_rsp(mac, limMsgQ, pe_session);
1487 return;
1488 }
1489 lim_process_sta_mlm_add_sta_rsp(mac, limMsgQ, pe_session);
1490 }
1491
1492 #ifdef WLAN_FEATURE_11BE_MLO
1493 static void
lim_process_add_sta_rsp_mlo(struct mac_context * mac_ctx,tLimMlmAssocCnf * mlm_assoc_cnf,struct pe_session * session_entry)1494 lim_process_add_sta_rsp_mlo(struct mac_context *mac_ctx,
1495 tLimMlmAssocCnf *mlm_assoc_cnf,
1496 struct pe_session *session_entry)
1497 {
1498 if (wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) {
1499 pe_err("sending assoc cnf for MLO link vdev");
1500 mlm_assoc_cnf->resultCode = eSIR_SME_SUCCESS;
1501 mlm_assoc_cnf->sessionId = session_entry->peSessionId;
1502 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1503 (uint32_t *)mlm_assoc_cnf);
1504 }
1505 }
1506 #else /* WLAN_FEATURE_11BE_MLO */
1507 static inline void
lim_process_add_sta_rsp_mlo(struct mac_context * mac_ctx,tLimMlmAssocCnf * mlm_assoc_cnf,struct pe_session * session_entry)1508 lim_process_add_sta_rsp_mlo(struct mac_context *mac_ctx,
1509 tLimMlmAssocCnf *mlm_assoc_cnf,
1510 struct pe_session *session_entry)
1511 {
1512 }
1513 #endif /* WLAN_FEATURE_11BE_MLO */
1514
1515 /**
1516 * lim_process_sta_mlm_add_sta_rsp () - Process add sta response
1517 * @mac_ctx: Pointer to mac context
1518 * @msg: struct scheduler_msg *an Message structure
1519 * @session_entry: PE session entry
1520 *
1521 * Process ADD STA response sent from WMA and posts results
1522 * to SME.
1523 *
1524 * Return: Null
1525 */
1526
lim_process_sta_mlm_add_sta_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg,struct pe_session * session_entry)1527 void lim_process_sta_mlm_add_sta_rsp(struct mac_context *mac_ctx,
1528 struct scheduler_msg *msg, struct pe_session *session_entry)
1529 {
1530 tLimMlmAssocCnf mlm_assoc_cnf;
1531 tpDphHashNode sta_ds;
1532 uint32_t msg_type = LIM_MLM_ASSOC_CNF;
1533 tpAddStaParams add_sta_params = (tpAddStaParams) msg->bodyptr;
1534
1535 if (!add_sta_params) {
1536 pe_err("Encountered NULL Pointer");
1537 return;
1538 }
1539
1540 if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
1541 msg_type = LIM_MLM_REASSOC_CNF;
1542
1543 if (true == session_entry->fDeauthReceived) {
1544 pe_err("Received Deauth frame in ADD_STA_RESP state");
1545 if (QDF_STATUS_SUCCESS == add_sta_params->status) {
1546 pe_err("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA limMlmState: %d bssid "QDF_MAC_ADDR_FMT,
1547 session_entry->limMlmState,
1548 QDF_MAC_ADDR_REF(add_sta_params->staMac));
1549
1550 if (session_entry->limSmeState ==
1551 eLIM_SME_WT_REASSOC_STATE)
1552 msg_type = LIM_MLM_REASSOC_CNF;
1553 /*
1554 * We are sending result code
1555 * eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA which
1556 * will trigger proper cleanup (DEL_STA/DEL_BSS both
1557 * required) in either assoc cnf or reassoc cnf handler.
1558 */
1559 mlm_assoc_cnf.resultCode =
1560 eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA;
1561 mlm_assoc_cnf.protStatusCode =
1562 STATUS_UNSPECIFIED_FAILURE;
1563 goto end;
1564 }
1565 }
1566
1567 if (QDF_STATUS_SUCCESS == add_sta_params->status) {
1568 if (eLIM_MLM_WT_ADD_STA_RSP_STATE !=
1569 session_entry->limMlmState) {
1570 pe_err("Received WMA_ADD_STA_RSP in state %X",
1571 session_entry->limMlmState);
1572 mlm_assoc_cnf.resultCode =
1573 (tSirResultCodes) eSIR_SME_REFUSED;
1574 goto end;
1575 }
1576 /*
1577 * Update the DPH Hash Entry for this STA
1578 * with proper state info
1579 */
1580 sta_ds =
1581 dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
1582 &session_entry->dph.dphHashTable);
1583 if (sta_ds) {
1584 sta_ds->mlmStaContext.mlmState =
1585 eLIM_MLM_LINK_ESTABLISHED_STATE;
1586 sta_ds->nss = add_sta_params->nss;
1587 } else
1588 pe_warn("Fail to get DPH Hash Entry for AID - %d",
1589 DPH_STA_HASH_INDEX_PEER);
1590 session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
1591 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
1592 session_entry->peSessionId,
1593 session_entry->limMlmState));
1594 lim_process_add_sta_rsp_mlo(mac_ctx, &mlm_assoc_cnf,
1595 session_entry);
1596
1597 #ifdef FEATURE_WLAN_TDLS
1598 /* initialize TDLS peer related data */
1599 lim_init_tdls_data(mac_ctx, session_entry);
1600 #endif
1601 /*
1602 * Return Assoc confirm to SME with success
1603 * FIXME - Need the correct ASSOC RSP code to
1604 * be passed in here
1605 */
1606 mlm_assoc_cnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS;
1607 lim_send_obss_color_collision_cfg(mac_ctx, session_entry,
1608 OBSS_COLOR_COLLISION_DETECTION);
1609 if (lim_is_session_he_capable(session_entry) && sta_ds) {
1610 if (mac_ctx->usr_cfg_mu_edca_params) {
1611 pe_debug("Send user cfg MU EDCA params to FW");
1612 lim_send_edca_params(mac_ctx,
1613 mac_ctx->usr_mu_edca_params,
1614 session_entry->vdev_id, true);
1615 } else if (session_entry->mu_edca_present) {
1616 pe_debug("Send MU EDCA params to FW");
1617 lim_send_edca_params(mac_ctx,
1618 session_entry->ap_mu_edca_params,
1619 session_entry->vdev_id, true);
1620 }
1621 }
1622 } else {
1623 pe_err("ADD_STA failed!");
1624 if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
1625 mlm_assoc_cnf.resultCode =
1626 (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
1627 else
1628 mlm_assoc_cnf.resultCode =
1629 (tSirResultCodes) eSIR_SME_REFUSED;
1630 mlm_assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
1631 }
1632 end:
1633 if (msg->bodyptr) {
1634 qdf_mem_free(add_sta_params);
1635 msg->bodyptr = NULL;
1636 }
1637 /* Updating PE session Id */
1638 mlm_assoc_cnf.sessionId = session_entry->peSessionId;
1639 lim_post_sme_message(mac_ctx, msg_type, (uint32_t *) &mlm_assoc_cnf);
1640 if (true == session_entry->fDeauthReceived)
1641 session_entry->fDeauthReceived = false;
1642 return;
1643 }
1644
lim_process_mlm_del_bss_rsp(struct mac_context * mac,struct del_bss_resp * vdev_stop_rsp,struct pe_session * pe_session)1645 void lim_process_mlm_del_bss_rsp(struct mac_context *mac,
1646 struct del_bss_resp *vdev_stop_rsp,
1647 struct pe_session *pe_session)
1648 {
1649 /* we need to process the deferred message since the initiating req. there might be nested request. */
1650 /* in the case of nested request the new request initiated from the response will take care of resetting */
1651 /* the deferred flag. */
1652 SET_LIM_PROCESS_DEFD_MESGS(mac, true);
1653 mac->sys.gSysFrameCount[SIR_MAC_MGMT_FRAME][SIR_MAC_MGMT_DEAUTH] = 0;
1654
1655 if (LIM_IS_AP_ROLE(pe_session) &&
1656 (pe_session->statypeForBss == STA_ENTRY_SELF)) {
1657 lim_process_ap_mlm_del_bss_rsp(mac, vdev_stop_rsp, pe_session);
1658 return;
1659 }
1660 lim_process_sta_mlm_del_bss_rsp(mac, vdev_stop_rsp, pe_session);
1661
1662 if (pe_session->limRmfEnabled) {
1663 if (QDF_STATUS_SUCCESS !=
1664 lim_send_exclude_unencrypt_ind(mac, true, pe_session)) {
1665 pe_err("Could not send down Exclude Unencrypted Indication!");
1666 }
1667 }
1668 }
1669
lim_process_sta_mlm_del_bss_rsp(struct mac_context * mac,struct del_bss_resp * vdev_stop_rsp,struct pe_session * pe_session)1670 void lim_process_sta_mlm_del_bss_rsp(struct mac_context *mac,
1671 struct del_bss_resp *vdev_stop_rsp,
1672 struct pe_session *pe_session)
1673 {
1674 tpDphHashNode sta =
1675 dph_get_hash_entry(mac, DPH_STA_HASH_INDEX_PEER,
1676 &pe_session->dph.dphHashTable);
1677 tSirResultCodes status_code = eSIR_SME_SUCCESS;
1678
1679 if (!vdev_stop_rsp) {
1680 pe_err("Invalid body pointer in message");
1681 goto end;
1682 }
1683 if (vdev_stop_rsp->status == QDF_STATUS_SUCCESS) {
1684 if (!sta) {
1685 pe_err("DPH Entry for STA 1 missing");
1686 status_code = eSIR_SME_REFUSED;
1687 goto end;
1688 }
1689 if (eLIM_MLM_WT_DEL_BSS_RSP_STATE !=
1690 sta->mlmStaContext.mlmState) {
1691 pe_err("Received unexpected WMA_DEL_BSS_RSP in state %X",
1692 sta->mlmStaContext.mlmState);
1693 status_code = eSIR_SME_REFUSED;
1694 goto end;
1695 }
1696 pe_debug("STA AssocID %d MAC "QDF_MAC_ADDR_FMT, sta->assocId,
1697 QDF_MAC_ADDR_REF(sta->staAddr));
1698 } else {
1699 pe_err("DEL BSS failed!");
1700 status_code = eSIR_SME_STOP_BSS_FAILURE;
1701 }
1702 end:
1703 if (!sta)
1704 return;
1705 if ((LIM_IS_STA_ROLE(pe_session)) &&
1706 (pe_session->limSmeState !=
1707 eLIM_SME_WT_DISASSOC_STATE &&
1708 pe_session->limSmeState !=
1709 eLIM_SME_WT_DEAUTH_STATE) &&
1710 sta->mlmStaContext.cleanupTrigger !=
1711 eLIM_JOIN_FAILURE) {
1712 /** The Case where the DelBss is invoked from
1713 * context of other than normal DisAssoc / Deauth OR
1714 * as part of Join Failure.
1715 */
1716 lim_handle_del_bss_in_re_assoc_context(mac, sta, pe_session);
1717 return;
1718 }
1719 lim_prepare_and_send_del_sta_cnf(mac, sta, status_code, pe_session);
1720 return;
1721 }
1722
lim_process_ap_mlm_del_bss_rsp(struct mac_context * mac,struct del_bss_resp * vdev_stop_rsp,struct pe_session * pe_session)1723 void lim_process_ap_mlm_del_bss_rsp(struct mac_context *mac,
1724 struct del_bss_resp *vdev_stop_rsp,
1725 struct pe_session *pe_session)
1726 {
1727 tSirResultCodes rc = eSIR_SME_SUCCESS;
1728
1729 if (!pe_session) {
1730 pe_err("Session entry passed is NULL");
1731 if (vdev_stop_rsp)
1732 qdf_mem_free(vdev_stop_rsp);
1733 return;
1734 }
1735
1736 if (!vdev_stop_rsp) {
1737 pe_err("BSS: DEL_BSS_RSP with no body!");
1738 rc = eSIR_SME_REFUSED;
1739 goto end;
1740 }
1741 mac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
1742 MTRACE(mac_trace
1743 (mac, TRACE_CODE_MLM_STATE, NO_SESSION,
1744 mac->lim.gLimMlmState));
1745
1746 if (eLIM_MLM_WT_DEL_BSS_RSP_STATE != pe_session->limMlmState) {
1747 pe_err("Received unexpected WMA_DEL_BSS_RSP in state %X",
1748 pe_session->limMlmState);
1749 rc = eSIR_SME_REFUSED;
1750 goto end;
1751 }
1752 if (vdev_stop_rsp->status != QDF_STATUS_SUCCESS) {
1753 pe_err("BSS: DEL_BSS_RSP error (%x)", vdev_stop_rsp->status);
1754 rc = eSIR_SME_STOP_BSS_FAILURE;
1755 goto end;
1756 }
1757 /** Softmac may send all the buffered packets right after resuming the transmission hence
1758 * to occupy the medium during non channel occupancy period. So resume the transmission after
1759 * HAL gives back the response.
1760 */
1761 dph_hash_table_init(mac, &pe_session->dph.dphHashTable);
1762 lim_delete_pre_auth_list(mac);
1763 /* Initialize number of associated stations during cleanup */
1764 pe_session->gLimNumOfCurrentSTAs = 0;
1765 end:
1766 lim_send_stop_bss_response(mac, pe_session->vdev_id, rc);
1767 pe_delete_session(mac, pe_session);
1768 }
1769
1770 /**
1771 * lim_process_mlm_del_all_sta_rsp() - Process DEL STA response
1772 * @mac_ctx: Pointer to Global MAC structure
1773 * @msg: The MsgQ header, which contains the response buffer
1774 *
1775 * This function is called to process a WMA_DEL_ALL_STA_RSP from
1776 * WMA Upon receipt of this message from FW.
1777 *
1778 * Return: QDF_STATUS
1779 */
1780 QDF_STATUS
lim_process_mlm_del_all_sta_rsp(struct vdev_mlme_obj * vdev_mlme,struct peer_delete_all_response * rsp)1781 lim_process_mlm_del_all_sta_rsp(struct vdev_mlme_obj *vdev_mlme,
1782 struct peer_delete_all_response *rsp)
1783 {
1784 struct pe_session *session_entry;
1785 tSirResultCodes status_code = eSIR_SME_SUCCESS;
1786 struct mac_context *mac_ctx;
1787 struct wlan_objmgr_vdev *vdev;
1788 uint8_t vdev_id;
1789
1790 vdev = vdev_mlme->vdev;
1791 vdev_id = wlan_vdev_get_id(vdev);
1792
1793 mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1794 if (!mac_ctx)
1795 return QDF_STATUS_E_INVAL;
1796
1797 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
1798
1799 session_entry = pe_find_session_by_vdev_id(mac_ctx,
1800 vdev_id);
1801 if (!session_entry) {
1802 pe_err("Session Doesn't exist: %d", vdev_id);
1803 return QDF_STATUS_E_INVAL;
1804 }
1805
1806 lim_prepare_and_send_del_all_sta_cnf(mac_ctx, status_code,
1807 session_entry);
1808 return QDF_STATUS_SUCCESS;
1809 }
1810
1811 /**
1812 * lim_process_mlm_del_sta_rsp() - Process DEL STA response
1813 * @mac_ctx: Pointer to Global MAC structure
1814 * @msg: The MsgQ header, which contains the response buffer
1815 *
1816 * This function is called to process a WMA_DEL_STA_RSP from
1817 * WMA Upon receipt of this message from FW.
1818 *
1819 * Return: None
1820 */
lim_process_mlm_del_sta_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg)1821 void lim_process_mlm_del_sta_rsp(struct mac_context *mac_ctx,
1822 struct scheduler_msg *msg)
1823 {
1824 /*
1825 * we need to process the deferred message since the
1826 * initiating req. there might be nested request
1827 * in the case of nested request the new request
1828 * initiated from the response will take care of resetting
1829 * the deferred flag.
1830 */
1831 struct pe_session *session_entry;
1832 tpDeleteStaParams del_sta_params;
1833
1834 del_sta_params = (tpDeleteStaParams) msg->bodyptr;
1835 if (!del_sta_params) {
1836 pe_err("null pointer del_sta_params msg");
1837 return;
1838 }
1839 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
1840
1841 session_entry = pe_find_session_by_session_id(mac_ctx,
1842 del_sta_params->sessionId);
1843 if (!session_entry) {
1844 pe_err("Session Doesn't exist: %d",
1845 del_sta_params->sessionId);
1846 qdf_mem_free(del_sta_params);
1847 msg->bodyptr = NULL;
1848 return;
1849 }
1850
1851 if (LIM_IS_AP_ROLE(session_entry)) {
1852 lim_process_ap_mlm_del_sta_rsp(mac_ctx, msg,
1853 session_entry);
1854 return;
1855 }
1856 if (LIM_IS_NDI_ROLE(session_entry)) {
1857 lim_process_ndi_del_sta_rsp(mac_ctx, msg, session_entry);
1858 return;
1859 }
1860 lim_process_sta_mlm_del_sta_rsp(mac_ctx, msg, session_entry);
1861 }
1862
1863 /**
1864 * lim_process_ap_mlm_del_sta_rsp() - Process WMA_DEL_STA_RSP
1865 * @mac_ctx: Global pointer to MAC context
1866 * @msg: Received message
1867 * @session_entry: Session entry
1868 *
1869 * Process WMA_DEL_STA_RSP for AP role
1870 *
1871 * Retunrn: None
1872 */
lim_process_ap_mlm_del_sta_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg,struct pe_session * session_entry)1873 void lim_process_ap_mlm_del_sta_rsp(struct mac_context *mac_ctx,
1874 struct scheduler_msg *msg,
1875 struct pe_session *session_entry)
1876 {
1877 tpDeleteStaParams del_sta_params = (tpDeleteStaParams) msg->bodyptr;
1878 tpDphHashNode sta_ds;
1879 tSirResultCodes status_code = eSIR_SME_SUCCESS;
1880
1881 if (!msg->bodyptr) {
1882 pe_err("msg->bodyptr NULL");
1883 return;
1884 }
1885
1886 sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId,
1887 &session_entry->dph.dphHashTable);
1888 if (!sta_ds) {
1889 pe_err("DPH Entry for STA %X missing",
1890 del_sta_params->assocId);
1891 status_code = eSIR_SME_REFUSED;
1892 qdf_mem_free(del_sta_params);
1893 msg->bodyptr = NULL;
1894 return;
1895 }
1896 pe_debug("Received del Sta Rsp in StaD MlmState: %d",
1897 sta_ds->mlmStaContext.mlmState);
1898 if (QDF_STATUS_SUCCESS != del_sta_params->status) {
1899 pe_warn("DEL STA failed!");
1900 status_code = eSIR_SME_REFUSED;
1901 goto end;
1902 }
1903
1904 pe_debug("AP received the DEL_STA_RSP for assocID: %X sta mac "
1905 QDF_MAC_ADDR_FMT, del_sta_params->assocId,
1906 QDF_MAC_ADDR_REF(sta_ds->staAddr));
1907 if ((eLIM_MLM_WT_DEL_STA_RSP_STATE != sta_ds->mlmStaContext.mlmState) &&
1908 (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
1909 sta_ds->mlmStaContext.mlmState)) {
1910 pe_err("Received unexpected WMA_DEL_STA_RSP in state %s for assocId %d",
1911 lim_mlm_state_str(sta_ds->mlmStaContext.mlmState),
1912 sta_ds->assocId);
1913 status_code = eSIR_SME_REFUSED;
1914 goto end;
1915 }
1916
1917 pe_debug("Deleted STA AssocID %d Addr "QDF_MAC_ADDR_FMT,
1918 sta_ds->assocId, QDF_MAC_ADDR_REF(sta_ds->staAddr));
1919 if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE ==
1920 sta_ds->mlmStaContext.mlmState) {
1921 qdf_mem_free(del_sta_params);
1922 msg->bodyptr = NULL;
1923 if (lim_add_sta(mac_ctx, sta_ds, false, session_entry) !=
1924 QDF_STATUS_SUCCESS) {
1925 pe_err("could not Add STA with assocId: %d",
1926 sta_ds->assocId);
1927 /*
1928 * delete the TS if it has already been added.
1929 * send the response with error status.
1930 */
1931 if (sta_ds->qos.addtsPresent) {
1932 tpLimTspecInfo pTspecInfo;
1933
1934 if (QDF_STATUS_SUCCESS ==
1935 lim_tspec_find_by_assoc_id(mac_ctx,
1936 sta_ds->assocId,
1937 &sta_ds->qos.addts.tspec,
1938 &mac_ctx->lim.tspecInfo[0],
1939 &pTspecInfo)) {
1940 lim_admit_control_delete_ts(mac_ctx,
1941 sta_ds->assocId,
1942 &sta_ds->qos.addts.tspec.tsinfo,
1943 NULL,
1944 &pTspecInfo->idx);
1945 }
1946 }
1947 lim_reject_association(mac_ctx, sta_ds->staAddr,
1948 sta_ds->mlmStaContext.subType, true,
1949 sta_ds->mlmStaContext.authType, sta_ds->assocId,
1950 true,
1951 STATUS_UNSPECIFIED_FAILURE,
1952 session_entry);
1953 }
1954 return;
1955 }
1956 end:
1957 qdf_mem_free(del_sta_params);
1958 msg->bodyptr = NULL;
1959 if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
1960 sta_ds->mlmStaContext.mlmState) {
1961 lim_prepare_and_send_del_sta_cnf(mac_ctx, sta_ds, status_code,
1962 session_entry);
1963 }
1964 return;
1965 }
1966
lim_process_sta_mlm_del_sta_rsp(struct mac_context * mac,struct scheduler_msg * limMsgQ,struct pe_session * pe_session)1967 void lim_process_sta_mlm_del_sta_rsp(struct mac_context *mac,
1968 struct scheduler_msg *limMsgQ,
1969 struct pe_session *pe_session)
1970 {
1971 tSirResultCodes status_code = eSIR_SME_SUCCESS;
1972 tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
1973
1974 if (!pDelStaParams) {
1975 pe_err("Encountered NULL Pointer");
1976 goto end;
1977 }
1978 pe_debug("Del STA RSP received. Status: %d AssocID: %d",
1979 pDelStaParams->status, pDelStaParams->assocId);
1980
1981 #ifdef FEATURE_WLAN_TDLS
1982 if (pDelStaParams->staType == STA_ENTRY_TDLS_PEER) {
1983 pe_debug("TDLS Del STA RSP received");
1984 lim_process_tdls_del_sta_rsp(mac, limMsgQ, pe_session);
1985 return;
1986 }
1987 #endif
1988 if (QDF_STATUS_SUCCESS != pDelStaParams->status)
1989 pe_err("Del STA failed! Status:%d, proceeding with Del BSS",
1990 pDelStaParams->status);
1991
1992 if (eLIM_MLM_WT_DEL_STA_RSP_STATE != pe_session->limMlmState) {
1993 pe_err("Received unexpected WDA_DELETE_STA_RSP in state %s",
1994 lim_mlm_state_str(pe_session->limMlmState));
1995 status_code = eSIR_SME_REFUSED;
1996 goto end;
1997 }
1998 /*
1999 * we must complete all cleanup related to delSta before
2000 * calling limDelBSS.
2001 */
2002 if (0 != limMsgQ->bodyptr) {
2003 qdf_mem_free(pDelStaParams);
2004 limMsgQ->bodyptr = NULL;
2005 }
2006
2007 lim_disconnect_complete(pe_session, true);
2008
2009 return;
2010 end:
2011 if (0 != limMsgQ->bodyptr) {
2012 qdf_mem_free(pDelStaParams);
2013 limMsgQ->bodyptr = NULL;
2014 }
2015 return;
2016 }
2017
lim_process_ap_mlm_add_sta_rsp(struct mac_context * mac,struct scheduler_msg * limMsgQ,struct pe_session * pe_session)2018 void lim_process_ap_mlm_add_sta_rsp(struct mac_context *mac,
2019 struct scheduler_msg *limMsgQ,
2020 struct pe_session *pe_session)
2021 {
2022 tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
2023 tpDphHashNode sta = NULL;
2024 bool add_sta_rsp_status = true;
2025
2026 if (!pAddStaParams) {
2027 pe_err("Invalid body pointer in message");
2028 add_sta_rsp_status = false;
2029 goto end;
2030 }
2031
2032 sta =
2033 dph_get_hash_entry(mac, pAddStaParams->assocId,
2034 &pe_session->dph.dphHashTable);
2035 if (!sta) {
2036 pe_err("DPH Entry for STA %X missing", pAddStaParams->assocId);
2037 add_sta_rsp_status = false;
2038 goto end;
2039 }
2040
2041 if (eLIM_MLM_WT_ADD_STA_RSP_STATE != sta->mlmStaContext.mlmState) {
2042 pe_err("Received unexpected WMA_ADD_STA_RSP in state %X",
2043 sta->mlmStaContext.mlmState);
2044 add_sta_rsp_status = false;
2045 goto end;
2046 }
2047 if (QDF_STATUS_SUCCESS != pAddStaParams->status) {
2048 pe_err("Error! rcvd delSta rsp from HAL with status %d",
2049 pAddStaParams->status);
2050 lim_reject_association(mac, sta->staAddr,
2051 sta->mlmStaContext.subType,
2052 true, sta->mlmStaContext.authType,
2053 sta->assocId, true,
2054 STATUS_UNSPECIFIED_FAILURE,
2055 pe_session);
2056 add_sta_rsp_status = false;
2057 goto end;
2058 }
2059 sta->nss = pAddStaParams->nss;
2060 /* if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state */
2061 sta->valid = 1;
2062 sta->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
2063 pe_debug("AddStaRsp Success.STA AssocID %d sta mac" QDF_MAC_ADDR_FMT,
2064 sta->assocId, QDF_MAC_ADDR_REF(sta->staAddr));
2065
2066 /* For BTAMP-AP, the flow sequence shall be:
2067 * 1) PE sends eWNI_SME_ASSOC_IND to SME
2068 * 2) PE receives eWNI_SME_ASSOC_CNF from SME
2069 * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA
2070 */
2071 if (!lim_is_mlo_conn(pe_session, sta) &&
2072 lim_send_mlm_assoc_ind(mac, sta, pe_session) !=
2073 QDF_STATUS_SUCCESS) {
2074 lim_reject_association(mac, sta->staAddr,
2075 sta->mlmStaContext.subType,
2076 true, sta->mlmStaContext.authType,
2077 sta->assocId, true,
2078 STATUS_UNSPECIFIED_FAILURE,
2079 pe_session);
2080 add_sta_rsp_status = false;
2081 }
2082 /* fall though to reclaim the original Add STA Response message */
2083 end:
2084 if (lim_is_mlo_conn(pe_session, sta))
2085 lim_ap_mlo_sta_peer_ind(mac, pe_session, sta,
2086 add_sta_rsp_status);
2087 if (0 != limMsgQ->bodyptr) {
2088 qdf_mem_free(pAddStaParams);
2089 limMsgQ->bodyptr = NULL;
2090 }
2091 return;
2092 }
2093
lim_process_ap_mlm_add_bss_rsp(struct mac_context * mac,struct add_bss_rsp * add_bss_rsp)2094 static void lim_process_ap_mlm_add_bss_rsp(struct mac_context *mac,
2095 struct add_bss_rsp *add_bss_rsp)
2096 {
2097 tLimMlmStartCnf mlmStartCnf;
2098 struct pe_session *pe_session;
2099 uint8_t isWepEnabled = false;
2100
2101 if (!add_bss_rsp) {
2102 pe_err("Encountered NULL Pointer");
2103 return;
2104 }
2105 /* TBD: free the memory before returning, do it for all places where lookup fails. */
2106 pe_session = pe_find_session_by_vdev_id(mac, add_bss_rsp->vdev_id);
2107 if (!pe_session) {
2108 pe_err("session does not exist for vdev_id %d",
2109 add_bss_rsp->vdev_id);
2110 return;
2111 }
2112 /* Update PE session Id */
2113 mlmStartCnf.sessionId = pe_session->peSessionId;
2114 if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) {
2115 pe_debug("WMA_ADD_BSS_RSP returned with QDF_STATUS_SUCCESS");
2116 /* Set MLME state */
2117 pe_session->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
2118 pe_session->chainMask = add_bss_rsp->chain_mask;
2119 pe_session->smpsMode = add_bss_rsp->smps_mode;
2120 MTRACE(mac_trace
2121 (mac, TRACE_CODE_MLM_STATE, pe_session->peSessionId,
2122 pe_session->limMlmState));
2123 pe_session->limSystemRole = eLIM_AP_ROLE;
2124
2125 sch_edca_profile_update(mac, pe_session);
2126 /* For dual AP case, delete pre auth node if any */
2127 lim_delete_pre_auth_list(mac);
2128 /* Check the SAP security configuration.If configured to
2129 * WEP then max clients supported is 16
2130 */
2131 if (pe_session->privacy) {
2132 if ((pe_session->gStartBssRSNIe.present)
2133 || (pe_session->gStartBssWPAIe.present))
2134 pe_debug("WPA/WPA2 SAP configuration");
2135 else {
2136 if (mac->mlme_cfg->sap_cfg.assoc_sta_limit >
2137 MAX_SUPPORTED_PEERS_WEP) {
2138 pe_debug("WEP SAP Configuration");
2139 mac->mlme_cfg->sap_cfg.assoc_sta_limit
2140 = MAX_SUPPORTED_PEERS_WEP;
2141 isWepEnabled = true;
2142 }
2143 }
2144 }
2145 lim_init_peer_idxpool(mac, pe_session);
2146
2147 /* Start OLBC timer */
2148 if (tx_timer_activate
2149 (&mac->lim.lim_timers.gLimUpdateOlbcCacheTimer) !=
2150 TX_SUCCESS) {
2151 pe_err("tx_timer_activate failed");
2152 }
2153
2154 /* Apply previously set configuration at HW */
2155 lim_apply_configuration(mac, pe_session);
2156
2157 /* In lim_apply_configuration gLimAssocStaLimit is assigned from cfg.
2158 * So update the value to 16 in case SoftAP is configured in WEP.
2159 */
2160 if ((mac->mlme_cfg->sap_cfg.assoc_sta_limit >
2161 MAX_SUPPORTED_PEERS_WEP)
2162 && (isWepEnabled))
2163 mac->mlme_cfg->sap_cfg.assoc_sta_limit =
2164 MAX_SUPPORTED_PEERS_WEP;
2165 mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
2166 } else {
2167 pe_err("WMA_ADD_BSS_REQ failed with status %d",
2168 add_bss_rsp->status);
2169 mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
2170 }
2171
2172 lim_send_start_bss_confirm(mac, &mlmStartCnf);
2173 }
2174
2175 #ifdef WLAN_FEATURE_FILS_SK
2176 /*
2177 * lim_update_fils_auth_mode: API to update Auth mode in case of fils session
2178 * @session_entry: pe session entry
2179 * @auth_mode: auth mode needs to be updated
2180 *
2181 * Return: None
2182 */
lim_update_fils_auth_mode(struct pe_session * session_entry,tAniAuthType * auth_mode)2183 static void lim_update_fils_auth_mode(struct pe_session *session_entry,
2184 tAniAuthType *auth_mode)
2185 {
2186 if (!session_entry->fils_info)
2187 return;
2188
2189 if (session_entry->fils_info->is_fils_connection)
2190 *auth_mode = session_entry->fils_info->auth;
2191 }
2192 #else
lim_update_fils_auth_mode(struct pe_session * session_entry,tAniAuthType * auth_mode)2193 static void lim_update_fils_auth_mode(struct pe_session *session_entry,
2194 tAniAuthType *auth_mode)
2195 { }
2196 #endif
2197
2198 #ifdef WLAN_FEATURE_11BE_MLO
2199 static bool
lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq * pMlmAuthReq,struct pe_session * session_entry)2200 lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq *pMlmAuthReq,
2201 struct pe_session *session_entry)
2202 {
2203 if (wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) {
2204 qdf_mem_free(pMlmAuthReq);
2205 pe_err("vdev is an MLO link, skip Auth");
2206 return true;
2207 }
2208
2209 return false;
2210 }
2211 #else /* WLAN_FEATURE_11BE_MLO */
2212 static inline bool
lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq * pMlmAuthReq,struct pe_session * session_entry)2213 lim_process_mlo_sta_add_bss_skip_auth(tLimMlmAuthReq *pMlmAuthReq,
2214 struct pe_session *session_entry)
2215 {
2216 return false;
2217 }
2218 #endif /* WLAN_FEATURE_11BE_MLO */
2219
lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context * mac_ctx,struct bss_params * add_bss_params,struct pe_session * session_entry,QDF_STATUS status)2220 void lim_process_sta_add_bss_rsp_pre_assoc(struct mac_context *mac_ctx,
2221 struct bss_params *add_bss_params,
2222 struct pe_session *session_entry,
2223 QDF_STATUS status)
2224 {
2225 tAniAuthType cfgAuthType, authMode;
2226 tLimMlmAuthReq *pMlmAuthReq;
2227 tpDphHashNode sta = NULL;
2228
2229 if (!add_bss_params) {
2230 pe_err("Invalid body pointer in message");
2231 goto joinFailure;
2232 }
2233 if (QDF_IS_STATUS_SUCCESS(status)) {
2234 sta = dph_add_hash_entry(mac_ctx,
2235 add_bss_params->staContext.staMac,
2236 DPH_STA_HASH_INDEX_PEER,
2237 &session_entry->dph.dphHashTable);
2238 if (!sta) {
2239 /* Could not add hash table entry */
2240 pe_err("could not add hash entry at DPH for STA: "QDF_MAC_ADDR_FMT,
2241 QDF_MAC_ADDR_REF(
2242 add_bss_params->staContext.staMac));
2243 goto joinFailure;
2244 }
2245 /* Success, handle below */
2246 /* Trigger Authentication with AP */
2247 cfgAuthType = mac_ctx->mlme_cfg->wep_params.auth_type;
2248
2249 /* Try shared Authentication first */
2250 if (cfgAuthType == eSIR_AUTO_SWITCH)
2251 authMode = eSIR_SHARED_KEY;
2252 else
2253 authMode = cfgAuthType;
2254
2255 lim_update_fils_auth_mode(session_entry, &authMode);
2256 /* Trigger MAC based Authentication */
2257 pMlmAuthReq = qdf_mem_malloc(sizeof(tLimMlmAuthReq));
2258 if (!pMlmAuthReq) {
2259 pe_err("Allocate Memory failed for mlmAuthReq");
2260 return;
2261 }
2262 sir_copy_mac_addr(pMlmAuthReq->peerMacAddr,
2263 session_entry->bssId);
2264
2265 pMlmAuthReq->authType = authMode;
2266 session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
2267 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
2268 session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
2269 pMlmAuthReq->sessionId = session_entry->peSessionId;
2270 session_entry->limPrevSmeState = session_entry->limSmeState;
2271 session_entry->limSmeState = eLIM_SME_WT_AUTH_STATE;
2272
2273 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
2274 session_entry->peSessionId,
2275 session_entry->limSmeState));
2276
2277 if (lim_process_mlo_sta_add_bss_skip_auth(pMlmAuthReq,
2278 session_entry))
2279 return;
2280 lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
2281 (uint32_t *) pMlmAuthReq);
2282 return;
2283 }
2284
2285 joinFailure:
2286 {
2287 session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
2288 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
2289 session_entry->peSessionId,
2290 session_entry->limSmeState));
2291
2292 /* Send Join response to Host */
2293 lim_handle_sme_join_result(mac_ctx, eSIR_SME_REFUSED,
2294 STATUS_UNSPECIFIED_FAILURE, session_entry);
2295 }
2296
2297 }
2298
lim_process_sta_mlm_add_bss_rsp(struct mac_context * mac_ctx,struct add_bss_rsp * add_bss_rsp,struct pe_session * session_entry)2299 static void lim_process_sta_mlm_add_bss_rsp(struct mac_context *mac_ctx,
2300 struct add_bss_rsp *add_bss_rsp,
2301 struct pe_session *session_entry)
2302 {
2303 tLimMlmAssocCnf mlm_assoc_cnf;
2304 uint32_t msg_type = LIM_MLM_ASSOC_CNF;
2305 uint32_t sub_type = LIM_ASSOC;
2306 tpDphHashNode sta_ds = NULL;
2307 uint8_t update_sta = false;
2308
2309 mlm_assoc_cnf.resultCode = eSIR_SME_SUCCESS;
2310 if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == session_entry->limMlmState
2311 || (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
2312 session_entry->limMlmState)) {
2313 msg_type = LIM_MLM_REASSOC_CNF;
2314 sub_type = LIM_REASSOC;
2315 /*
2316 * If Reassoc is happening for the same BSS, then
2317 * use the existing StaId and indicate to HAL to update
2318 * the existing STA entry.
2319 * If Reassoc is happening for the new BSS, then
2320 * old BSS and STA entry would have been already deleted
2321 * before PE tries to add BSS for the new BSS, so set the
2322 * updateSta to false and pass INVALID STA Index.
2323 */
2324 if (sir_compare_mac_addr(session_entry->bssId,
2325 session_entry->limReAssocbssId)) {
2326 update_sta = true;
2327 }
2328 }
2329
2330 if (QDF_IS_STATUS_SUCCESS(add_bss_rsp->status)) {
2331 if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
2332 session_entry->limMlmState) {
2333 pe_debug("Mlm=%d %d", session_entry->limMlmState,
2334 eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
2335 lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx,
2336 add_bss_rsp,
2337 session_entry);
2338 return;
2339 }
2340
2341 /* Set MLME state */
2342 session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
2343 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
2344 session_entry->peSessionId,
2345 session_entry->limMlmState));
2346 /* to know the session started for self or for peer */
2347 session_entry->statypeForBss = STA_ENTRY_PEER;
2348 sta_ds =
2349 dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
2350 &session_entry->dph.dphHashTable);
2351 if (!sta_ds) {
2352 pe_err("Session:%d Fail to add Self Entry for STA",
2353 session_entry->peSessionId);
2354 mlm_assoc_cnf.resultCode =
2355 (tSirResultCodes) eSIR_SME_REFUSED;
2356 } else {
2357 /* Success, handle below */
2358 /* Downgrade the EDCA parameters if needed */
2359 lim_set_active_edca_params(mac_ctx,
2360 session_entry->gLimEdcaParams, session_entry);
2361 lim_send_edca_params(mac_ctx,
2362 session_entry->gLimEdcaParamsActive,
2363 session_entry->vdev_id, false);
2364 if (lim_add_sta_self(mac_ctx, update_sta,
2365 session_entry) != QDF_STATUS_SUCCESS) {
2366 /* Add STA context at HW */
2367 pe_err("Session:%d could not Add Self"
2368 "Entry for the station",
2369 session_entry->peSessionId);
2370 mlm_assoc_cnf.resultCode =
2371 (tSirResultCodes) eSIR_SME_REFUSED;
2372 }
2373 }
2374 } else {
2375 pe_err("SessionId: %d ADD_BSS failed!",
2376 session_entry->peSessionId);
2377 mlm_assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
2378 /* Return Assoc confirm to SME with failure */
2379 if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
2380 session_entry->limMlmState)
2381 mlm_assoc_cnf.resultCode =
2382 (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
2383 else
2384 mlm_assoc_cnf.resultCode =
2385 (tSirResultCodes) eSIR_SME_REFUSED;
2386 session_entry->add_bss_failed = true;
2387 }
2388
2389 if (mlm_assoc_cnf.resultCode != eSIR_SME_SUCCESS) {
2390 session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
2391 /* Update PE session Id */
2392 mlm_assoc_cnf.sessionId = session_entry->peSessionId;
2393 lim_post_sme_message(mac_ctx, msg_type,
2394 (uint32_t *) &mlm_assoc_cnf);
2395 }
2396 }
2397
lim_handle_add_bss_rsp(struct mac_context * mac_ctx,struct add_bss_rsp * add_bss_rsp)2398 void lim_handle_add_bss_rsp(struct mac_context *mac_ctx,
2399 struct add_bss_rsp *add_bss_rsp)
2400 {
2401 tLimMlmStartCnf mlm_start_cnf;
2402 struct pe_session *session_entry;
2403 enum bss_type bss_type;
2404 struct wlan_lmac_if_reg_tx_ops *tx_ops;
2405 struct vdev_mlme_obj *mlme_obj;
2406 struct pe_session *sta_session;
2407
2408 if (!add_bss_rsp) {
2409 pe_err("add_bss_rsp is NULL");
2410 return;
2411 }
2412
2413 /*
2414 * we need to process the deferred message since the
2415 * initiating req.there might be nested request.
2416 * in the case of nested request the new request initiated
2417 * from the response will take care of resetting the deferred
2418 * flag.
2419 */
2420 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
2421 /* Validate SME/LIM/MLME state */
2422 session_entry = pe_find_session_by_vdev_id(mac_ctx,
2423 add_bss_rsp->vdev_id);
2424 if (!session_entry) {
2425 pe_err("vdev id:%d Session Doesn't exist",
2426 add_bss_rsp->vdev_id);
2427 goto err;
2428 }
2429 if (LIM_IS_AP_ROLE(session_entry)) {
2430 if (wlan_reg_is_ext_tpc_supported(mac_ctx->psoc)) {
2431 mlme_obj =
2432 wlan_vdev_mlme_get_cmpt_obj(session_entry->vdev);
2433 if (!mlme_obj) {
2434 pe_err("vdev component object is NULL");
2435 goto err;
2436 }
2437 tx_ops = wlan_reg_get_tx_ops(mac_ctx->psoc);
2438
2439 lim_calculate_tpc(mac_ctx, session_entry);
2440
2441 if (tx_ops->set_tpc_power)
2442 tx_ops->set_tpc_power(mac_ctx->psoc,
2443 session_entry->vdev_id,
2444 &mlme_obj->reg_tpc_obj);
2445 if (wlan_get_tpc_update_required_for_sta(
2446 session_entry->vdev)) {
2447 sta_session =
2448 lim_get_concurrent_session(mac_ctx,
2449 session_entry->vdev_id,
2450 session_entry->opmode);
2451 if (!sta_session) {
2452 pe_err("TPC update required is set, but concurrent session doesn't exist");
2453 wlan_set_tpc_update_required_for_sta(
2454 session_entry->vdev,
2455 false);
2456 } else {
2457 lim_update_tx_power(mac_ctx,
2458 session_entry, sta_session,
2459 false);
2460 }
2461 }
2462 }
2463 }
2464 bss_type = session_entry->bssType;
2465 /* update PE session Id */
2466 mlm_start_cnf.sessionId = session_entry->peSessionId;
2467 if (eSIR_NDI_MODE == session_entry->bssType) {
2468 lim_process_ndi_mlm_add_bss_rsp(mac_ctx, add_bss_rsp,
2469 session_entry);
2470 } else {
2471 if (eLIM_SME_WT_START_BSS_STATE == session_entry->limSmeState) {
2472 if (eLIM_MLM_WT_ADD_BSS_RSP_STATE !=
2473 session_entry->limMlmState) {
2474 pe_err("SessionId:%d Received "
2475 " WMA_ADD_BSS_RSP in state %X",
2476 session_entry->peSessionId,
2477 session_entry->limMlmState);
2478 mlm_start_cnf.resultCode =
2479 eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
2480
2481 lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf);
2482 }
2483 lim_process_ap_mlm_add_bss_rsp(mac_ctx,
2484 add_bss_rsp);
2485 } else {
2486 /* Called while processing assoc response */
2487 lim_process_sta_mlm_add_bss_rsp(mac_ctx, add_bss_rsp,
2488 session_entry);
2489 }
2490 }
2491
2492 if (session_entry->limRmfEnabled) {
2493 if (QDF_STATUS_SUCCESS !=
2494 lim_send_exclude_unencrypt_ind(mac_ctx, false,
2495 session_entry)) {
2496 pe_err("Failed to send Exclude Unencrypted Ind");
2497 }
2498 }
2499 err:
2500 qdf_mem_free(add_bss_rsp);
2501 }
2502
lim_process_mlm_update_hidden_ssid_rsp(struct mac_context * mac_ctx,uint8_t vdev_id)2503 void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx,
2504 uint8_t vdev_id)
2505 {
2506 struct pe_session *session_entry;
2507 struct scheduler_msg message = {0};
2508 QDF_STATUS status;
2509
2510 pe_debug("hidden ssid resp for vdev_id:%d ", vdev_id);
2511
2512 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
2513 if (!session_entry) {
2514 pe_err("vdev_id:%d Session Doesn't exist",
2515 vdev_id);
2516 return;
2517 }
2518 /* Update beacon */
2519 sch_set_fixed_beacon_fields(mac_ctx, session_entry);
2520 lim_send_beacon(mac_ctx, session_entry);
2521
2522 message.type = eWNI_SME_HIDDEN_SSID_RESTART_RSP;
2523 message.bodyval = vdev_id;
2524 status = scheduler_post_message(QDF_MODULE_ID_PE,
2525 QDF_MODULE_ID_SME,
2526 QDF_MODULE_ID_SME, &message);
2527
2528 if (status != QDF_STATUS_SUCCESS)
2529 pe_err("Failed to post message %u", status);
2530 }
2531
2532 /**
2533 * lim_process_mlm_set_sta_key_rsp() - Process STA key response
2534 *
2535 * @mac_ctx: Pointer to Global MAC structure
2536 * @msg: The MsgQ header, which contains the response buffer
2537 *
2538 * This function is called to process the following two
2539 * messages from HAL:
2540 * 1) WMA_SET_BSSKEY_RSP
2541 * 2) WMA_SET_STAKEY_RSP
2542 * 3) WMA_SET_STA_BCASTKEY_RSP
2543 * Upon receipt of this message from HAL,
2544 * MLME -
2545 * > Determines the "state" in which this message was received
2546 * > Forwards it to the appropriate callback
2547 * LOGIC:
2548 * WMA_SET_BSSKEY_RSP/WMA_SET_STAKEY_RSP can be
2549 * received by MLME while in the following state:
2550 * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR--
2551 * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR--
2552 * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE
2553 * Based on this state, this API will determine where to
2554 * route the message to
2555 * Assumption:
2556 * ONLY the MLME state is being taken into account for now.
2557 * This is because, it appears that the handling of the
2558 * SETKEYS REQ is handled symmetrically on both the AP & STA
2559 *
2560 * Return: None
2561 */
lim_process_mlm_set_sta_key_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg)2562 void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
2563 struct scheduler_msg *msg)
2564 {
2565 struct sLimMlmSetKeysCnf mlm_set_key_cnf;
2566 uint8_t session_id = 0;
2567 uint8_t vdev_id;
2568 struct pe_session *session_entry;
2569 uint16_t key_len;
2570 uint16_t result_status;
2571 tSetStaKeyParams *set_key_params;
2572 tLimMlmStates mlm_state = eLIM_MLM_OFFLINE_STATE;
2573
2574 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
2575 qdf_mem_zero((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf));
2576 if (!msg->bodyptr) {
2577 pe_err("msg bodyptr is NULL");
2578 return;
2579 }
2580 set_key_params = msg->bodyptr;
2581 vdev_id = set_key_params->vdev_id;
2582 session_id = vdev_id;
2583 if (wlan_get_opmode_from_vdev_id(mac_ctx->pdev,
2584 vdev_id) != QDF_NAN_DISC_MODE) {
2585 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
2586 if (!session_entry) {
2587 pe_err("session does not exist for given vdev_id %d",
2588 vdev_id);
2589 qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params));
2590 qdf_mem_free(msg->bodyptr);
2591 msg->bodyptr = NULL;
2592 lim_send_sme_set_context_rsp(mac_ctx,
2593 mlm_set_key_cnf.peer_macaddr,
2594 0,
2595 eSIR_SME_INVALID_SESSION,
2596 NULL, vdev_id);
2597 return;
2598 }
2599 session_id = session_entry->peSessionId;
2600 mlm_state = session_entry->limMlmState;
2601 }
2602
2603 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session_id, mlm_state));
2604 result_status = set_key_params->status;
2605 key_len = set_key_params->key_len;
2606 pe_debug("PE session ID %d, vdev_id %d key_len %d status %d",
2607 session_id, vdev_id, key_len, result_status);
2608
2609 if (result_status == eSIR_SME_SUCCESS && key_len)
2610 mlm_set_key_cnf.key_len_nonzero = true;
2611 else
2612 mlm_set_key_cnf.key_len_nonzero = false;
2613
2614 qdf_copy_macaddr(&mlm_set_key_cnf.peer_macaddr,
2615 &set_key_params->macaddr);
2616 mlm_set_key_cnf.sessionId = session_id;
2617 lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
2618 (uint32_t *) &mlm_set_key_cnf);
2619
2620 qdf_mem_zero(msg->bodyptr, sizeof(*set_key_params));
2621 qdf_mem_free(msg->bodyptr);
2622 msg->bodyptr = NULL;
2623 }
2624
2625 /**
2626 * lim_process_mlm_set_bss_key_rsp() - handles BSS key
2627 *
2628 * @mac_ctx: A pointer to Global MAC structure
2629 * @msg: Message from SME
2630 *
2631 * This function processes BSS key response and updates
2632 * PE status accordingly.
2633 *
2634 * Return: NULL
2635 */
lim_process_mlm_set_bss_key_rsp(struct mac_context * mac_ctx,struct scheduler_msg * msg)2636 void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx,
2637 struct scheduler_msg *msg)
2638 {
2639 struct sLimMlmSetKeysCnf set_key_cnf;
2640 uint16_t result_status;
2641 uint8_t session_id = 0;
2642 uint8_t vdev_id;
2643 struct pe_session *session_entry;
2644 uint16_t key_len;
2645 tSetBssKeyParams *bss_key;
2646
2647 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
2648 qdf_mem_zero((void *)&set_key_cnf, sizeof(tLimMlmSetKeysCnf));
2649 if (!msg->bodyptr) {
2650 pe_err("msg bodyptr is null");
2651 return;
2652 }
2653 bss_key = msg->bodyptr;
2654 vdev_id = bss_key->vdev_id;
2655 session_entry = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
2656 if (!session_entry) {
2657 pe_err("session does not exist for vdev_id %d", vdev_id);
2658 qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams));
2659 qdf_mem_free(msg->bodyptr);
2660 msg->bodyptr = NULL;
2661 lim_send_sme_set_context_rsp(mac_ctx, set_key_cnf.peer_macaddr,
2662 0, eSIR_SME_INVALID_SESSION, NULL,
2663 vdev_id);
2664 return;
2665 }
2666
2667 session_id = session_entry->peSessionId;
2668 result_status = (uint16_t)bss_key->status;
2669 key_len = bss_key->key_len;
2670 pe_debug("vdev %d (pe %d) limMlmState %d status %d key_len %d",
2671 vdev_id, session_id, session_entry->limMlmState,
2672 result_status, key_len);
2673
2674 if (result_status == eSIR_SME_SUCCESS && key_len)
2675 set_key_cnf.key_len_nonzero = true;
2676 else
2677 set_key_cnf.key_len_nonzero = false;
2678
2679 MTRACE(mac_trace
2680 (mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
2681 session_entry->limMlmState));
2682 set_key_cnf.sessionId = session_id;
2683
2684 /* Prepare and Send LIM_MLM_SETKEYS_CNF */
2685 qdf_copy_macaddr(&set_key_cnf.peer_macaddr, &bss_key->macaddr);
2686 qdf_mem_zero(msg->bodyptr, sizeof(tSetBssKeyParams));
2687 qdf_mem_free(msg->bodyptr);
2688 msg->bodyptr = NULL;
2689
2690 lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
2691 (uint32_t *) &set_key_cnf);
2692 }
2693
2694 /**
2695 * lim_process_switch_channel_re_assoc_req()
2696 *
2697 ***FUNCTION:
2698 * This function is called to send the reassoc req mgmt frame after the
2699 * switchChannelRsp message is received from HAL.
2700 *
2701 ***LOGIC:
2702 *
2703 ***ASSUMPTIONS:
2704 * NA
2705 *
2706 ***NOTE:
2707 * NA
2708 *
2709 * @param mac - Pointer to Global MAC structure.
2710 * @param pe_session - session related information.
2711 * @param status - channel switch success/failure.
2712 *
2713 * @return None
2714 */
lim_process_switch_channel_re_assoc_req(struct mac_context * mac,struct pe_session * pe_session,QDF_STATUS status)2715 static void lim_process_switch_channel_re_assoc_req(struct mac_context *mac,
2716 struct pe_session *pe_session,
2717 QDF_STATUS status)
2718 {
2719 tLimMlmReassocCnf mlmReassocCnf;
2720 tLimMlmReassocReq *pMlmReassocReq;
2721
2722 pMlmReassocReq =
2723 (tLimMlmReassocReq *) (pe_session->pLimMlmReassocReq);
2724 if (!pMlmReassocReq) {
2725 pe_err("pLimMlmReassocReq does not exist for given switchChanSession");
2726 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
2727 goto end;
2728 }
2729
2730 if (status != QDF_STATUS_SUCCESS) {
2731 pe_err("Change channel failed!!");
2732 mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL;
2733 goto end;
2734 }
2735 /* / Start reassociation failure timer */
2736 MTRACE(mac_trace
2737 (mac, TRACE_CODE_TIMER_ACTIVATE, pe_session->peSessionId,
2738 eLIM_REASSOC_FAIL_TIMER));
2739 if (tx_timer_activate(&mac->lim.lim_timers.gLimReassocFailureTimer)
2740 != TX_SUCCESS) {
2741 pe_err("could not start Reassociation failure timer");
2742 /* Return Reassoc confirm with */
2743 /* Resources Unavailable */
2744 mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
2745 goto end;
2746 }
2747 /* / Prepare and send Reassociation request frame */
2748 lim_send_reassoc_req_mgmt_frame(mac, pMlmReassocReq, pe_session);
2749 return;
2750 end:
2751 /* Free up buffer allocated for reassocReq */
2752 if (pMlmReassocReq) {
2753 /* Update PE session Id */
2754 mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
2755 qdf_mem_free(pMlmReassocReq);
2756 pe_session->pLimMlmReassocReq = NULL;
2757 } else {
2758 mlmReassocCnf.sessionId = 0;
2759 }
2760
2761 mlmReassocCnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
2762 /* Update PE session Id */
2763 mlmReassocCnf.sessionId = pe_session->peSessionId;
2764
2765 lim_post_sme_message(mac, LIM_MLM_REASSOC_CNF,
2766 (uint32_t *) &mlmReassocCnf);
2767 }
2768
2769 #ifdef WLAN_FEATURE_11BE_MLO
2770 static QDF_STATUS
lim_process_switch_channel_join_mlo(struct pe_session * session_entry,struct mac_context * mac_ctx)2771 lim_process_switch_channel_join_mlo(struct pe_session *session_entry,
2772 struct mac_context *mac_ctx)
2773 {
2774 QDF_STATUS status = QDF_STATUS_SUCCESS;
2775 struct mlo_partner_info *partner_info;
2776 struct element_info assoc_rsp, link_assoc_rsp;
2777 tLimMlmJoinCnf mlm_join_cnf;
2778 tLimMlmAssocCnf assoc_cnf;
2779 uint8_t *frame_ie_buf, *mlie;
2780 qdf_size_t frame_ie_len, mlie_len;
2781 bool link_id_found = false;
2782 struct qdf_mac_addr sta_link_addr;
2783 uint8_t assoc_link_id, link_id;
2784 struct wlan_frame_hdr *link_frame_hdr;
2785
2786 assoc_rsp.len = 0;
2787 mlo_get_assoc_rsp(session_entry->vdev, &assoc_rsp);
2788
2789 partner_info = &session_entry->ml_partner_info;
2790 if (!partner_info->num_partner_links) {
2791 pe_debug("MLO: vdev:%d num_partner_links is 0",
2792 session_entry->vdev_id);
2793 return QDF_STATUS_E_INVAL;
2794 }
2795
2796 /* Todo: update the sta addr by matching link id */
2797 qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr,
2798 QDF_MAC_ADDR_SIZE);
2799
2800 if (!assoc_rsp.len)
2801 return status;
2802
2803 mlm_join_cnf.resultCode = eSIR_SME_SUCCESS;
2804 mlm_join_cnf.protStatusCode = STATUS_SUCCESS;
2805 /* Update PE sessionId */
2806 mlm_join_cnf.sessionId = session_entry->peSessionId;
2807 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
2808 (uint32_t *)&mlm_join_cnf);
2809
2810 session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
2811 assoc_rsp.len += SIR_MAC_HDR_LEN_3A;
2812 pe_debug("MLO:assoc rsp len + hdr %d ", assoc_rsp.len);
2813
2814 link_assoc_rsp.ptr = qdf_mem_malloc(assoc_rsp.len);
2815 if (!link_assoc_rsp.ptr)
2816 return QDF_STATUS_E_NOMEM;
2817
2818 link_assoc_rsp.len = assoc_rsp.len + 24;
2819 session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
2820
2821 link_id = wlan_vdev_get_link_id(session_entry->vdev);
2822 pe_debug("MLO: Generate and process assoc rsp for link vdev %d",
2823 link_id);
2824
2825 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(session_entry->vdev)) {
2826 frame_ie_buf = assoc_rsp.ptr + WLAN_ASSOC_RSP_IES_OFFSET;
2827 frame_ie_len = assoc_rsp.len - 24 - WLAN_ASSOC_RSP_IES_OFFSET;
2828
2829 status = util_find_mlie(frame_ie_buf, frame_ie_len,
2830 &mlie, &mlie_len);
2831 if (QDF_IS_STATUS_ERROR(status)) {
2832 pe_debug("ML IE not found");
2833 goto rsp_gen_fail;
2834 }
2835
2836 status = util_get_bvmlie_primary_linkid(mlie, mlie_len,
2837 &link_id_found,
2838 &assoc_link_id);
2839 if (QDF_IS_STATUS_ERROR(status) || !link_id_found) {
2840 pe_debug("Assoc link ID not found");
2841 goto rsp_gen_fail;
2842 }
2843
2844 if (assoc_link_id != link_id)
2845 goto gen_link_assoc_rsp;
2846
2847 pe_debug("Skip assoc rsp gen for link %d", link_id);
2848 link_frame_hdr = (struct wlan_frame_hdr *)link_assoc_rsp.ptr;
2849 qdf_ether_addr_copy(link_frame_hdr->i_addr3,
2850 session_entry->bssId);
2851 qdf_ether_addr_copy(link_frame_hdr->i_addr2,
2852 session_entry->bssId);
2853 qdf_ether_addr_copy(link_frame_hdr->i_addr1,
2854 &sta_link_addr.bytes[0]);
2855 link_frame_hdr->i_fc[0] = MLO_LINKSPECIFIC_ASSOC_RESP_FC0;
2856 link_frame_hdr->i_fc[1] = MLO_LINKSPECIFIC_ASSOC_RESP_FC1;
2857
2858 qdf_mem_copy(link_assoc_rsp.ptr + SIR_MAC_HDR_LEN_3A,
2859 assoc_rsp.ptr, assoc_rsp.len - SIR_MAC_HDR_LEN_3A);
2860
2861 goto process_assoc_rsp;
2862 }
2863
2864 gen_link_assoc_rsp:
2865 status = util_gen_link_assoc_rsp(assoc_rsp.ptr,
2866 assoc_rsp.len - 24,
2867 false, link_id, sta_link_addr,
2868 link_assoc_rsp.ptr,
2869 assoc_rsp.len,
2870 (qdf_size_t *)&link_assoc_rsp.len);
2871 process_assoc_rsp:
2872 if (QDF_IS_STATUS_SUCCESS(status)) {
2873 pe_debug("MLO: process assoc rsp for link vdev");
2874 lim_process_assoc_rsp_frame(mac_ctx,
2875 link_assoc_rsp.ptr,
2876 (link_assoc_rsp.len - SIR_MAC_HDR_LEN_3A),
2877 LIM_ASSOC,
2878 session_entry);
2879 goto mem_free;
2880 }
2881
2882 rsp_gen_fail:
2883 pe_debug("MLO: link vdev assoc rsp generation failed");
2884 assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2885 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
2886 /* Update PE sessionId */
2887 assoc_cnf.sessionId = session_entry->peSessionId;
2888 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
2889 (uint32_t *)&assoc_cnf);
2890
2891 mem_free:
2892 qdf_mem_free(link_assoc_rsp.ptr);
2893 link_assoc_rsp.ptr = NULL;
2894 link_assoc_rsp.len = 0;
2895
2896 return status;
2897 }
2898
2899 #else /* WLAN_FEATURE_11BE_MLO */
2900 static QDF_STATUS
lim_process_switch_channel_join_mlo(struct pe_session * session_entry,struct mac_context * mac_ctx)2901 lim_process_switch_channel_join_mlo(struct pe_session *session_entry,
2902 struct mac_context *mac_ctx)
2903 {
2904 return QDF_STATUS_SUCCESS;
2905 }
2906 #endif /* WLAN_FEATURE_11BE_MLO */
2907
2908 #if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_11BE_MLO)
2909 static QDF_STATUS
lim_process_switch_channel_join_mlo_roam(struct pe_session * session_entry,struct mac_context * mac_ctx)2910 lim_process_switch_channel_join_mlo_roam(struct pe_session *session_entry,
2911 struct mac_context *mac_ctx)
2912 {
2913 QDF_STATUS status;
2914 struct element_info assoc_rsp = {};
2915 struct qdf_mac_addr sta_link_addr;
2916 struct element_info link_assoc_rsp;
2917 tLimMlmJoinCnf mlm_join_cnf;
2918 tLimMlmAssocCnf assoc_cnf;
2919 struct qdf_mac_addr bssid;
2920 uint8_t link_id = 0;
2921
2922 assoc_rsp.len = 0;
2923 mlo_get_assoc_rsp(session_entry->vdev, &assoc_rsp);
2924
2925 if (!session_entry->ml_partner_info.num_partner_links) {
2926 pe_debug("MLO_ROAM: vdev:%d num_partner_links is 0",
2927 session_entry->vdev_id);
2928 return QDF_STATUS_E_INVAL;
2929 }
2930
2931 /* Todo: update the sta addr by matching link id */
2932 qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr,
2933 QDF_MAC_ADDR_SIZE);
2934
2935 pe_err("vdev:%d sta_link_addr" QDF_MAC_ADDR_FMT,
2936 session_entry->vdev_id,
2937 QDF_MAC_ADDR_REF(&sta_link_addr.bytes[0]));
2938
2939 if (!assoc_rsp.len)
2940 return QDF_STATUS_SUCCESS;
2941
2942 mlm_join_cnf.resultCode = eSIR_SME_SUCCESS;
2943 mlm_join_cnf.protStatusCode = STATUS_SUCCESS;
2944 /* Update PE sessionId */
2945 mlm_join_cnf.sessionId = session_entry->peSessionId;
2946 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
2947 (uint32_t *)&mlm_join_cnf);
2948
2949 session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
2950 pe_debug("MLO_ROAM: reassoc rsp len %d ", assoc_rsp.len);
2951
2952 link_assoc_rsp.ptr = qdf_mem_malloc(assoc_rsp.len);
2953 if (!link_assoc_rsp.ptr)
2954 return QDF_STATUS_E_NOMEM;
2955
2956 link_assoc_rsp.len = assoc_rsp.len;
2957 session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
2958 mlo_get_link_mac_addr_from_reassoc_rsp(session_entry->vdev, &bssid);
2959 sir_copy_mac_addr(session_entry->limReAssocbssId, bssid.bytes);
2960 link_id = wlan_vdev_get_link_id(session_entry->vdev);
2961 pe_debug("MLO ROAM: Generate and process assoc rsp for link_id:%d vdev %d",
2962 link_id, session_entry->vdev_id);
2963
2964 status = util_gen_link_assoc_rsp(assoc_rsp.ptr,
2965 assoc_rsp.len,
2966 true, link_id, sta_link_addr,
2967 link_assoc_rsp.ptr,
2968 assoc_rsp.len,
2969 (qdf_size_t *)&link_assoc_rsp.len);
2970 if (QDF_IS_STATUS_ERROR(status)) {
2971 pe_err("MLO_ROAM: link vdev:%d link_id:%d assoc rsp generation failed",
2972 session_entry->vdev_id, link_id);
2973 assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
2974 assoc_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
2975 /* Update PE sessionId */
2976 assoc_cnf.sessionId = session_entry->peSessionId;
2977 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
2978 (uint32_t *)&assoc_cnf);
2979
2980 session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
2981 qdf_mem_free(link_assoc_rsp.ptr);
2982
2983 return status;
2984 }
2985
2986 pe_debug("MLO_ROAM: process reassoc rsp for link vdev");
2987 lim_process_assoc_rsp_frame(mac_ctx, link_assoc_rsp.ptr,
2988 (link_assoc_rsp.len - WLAN_MAC_HDR_LEN_3A),
2989 LIM_REASSOC, session_entry);
2990 qdf_mem_free(link_assoc_rsp.ptr);
2991
2992 return QDF_STATUS_SUCCESS;
2993 }
2994 #else /* (WLAN_FEATURE_ROAM_OFFLOAD) && (WLAN_FEATURE_11BE_MLO) */
2995 static QDF_STATUS
lim_process_switch_channel_join_mlo_roam(struct pe_session * session_entry,struct mac_context * mac_ctx)2996 lim_process_switch_channel_join_mlo_roam(struct pe_session *session_entry,
2997 struct mac_context *mac_ctx)
2998 {
2999 return QDF_STATUS_SUCCESS;
3000 }
3001 #endif /* (WLAN_FEATURE_ROAM_OFFLOAD) && (WLAN_FEATURE_11BE_MLO) */
3002
3003 #ifdef WLAN_FEATURE_11BE_MLO
3004 static void
lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session * session)3005 lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session *session)
3006 {
3007 struct mlo_partner_info *partner_info;
3008 struct mlo_link_info *partner_link_info;
3009 struct wlan_channel channel = {0};
3010 struct mlo_link_switch_context *link_ctx;
3011 uint8_t i = 0;
3012
3013 if (!session->vdev) {
3014 pe_err("vdev:%d is NULL", session->vdev_id);
3015 return;
3016 }
3017
3018 if (!wlan_vdev_mlme_is_mlo_vdev(session->vdev))
3019 return;
3020
3021 if (!session->lim_join_req) {
3022 pe_err("vdev:%d lim_join_req is NULL", session->vdev_id);
3023 return;
3024 }
3025
3026 link_ctx = session->vdev->mlo_dev_ctx->link_ctx;
3027 if (!link_ctx) {
3028 pe_err("vdev:%d MLO Link_ctx not found",
3029 session->vdev_id);
3030 return;
3031 }
3032
3033 /* Populating Assoc Link Band info */
3034 channel.ch_freq = (uint16_t)session->curr_op_freq;
3035
3036 mlo_mgr_reset_ap_link_info(session->vdev);
3037 mlo_mgr_update_ap_link_info(session->vdev,
3038 wlan_vdev_get_link_id(session->vdev),
3039 session->bssId, channel);
3040
3041 /* Populating Partner link band Info */
3042 partner_info = &session->lim_join_req->partner_info;
3043 for (i = 0; i < partner_info->num_partner_links; i++) {
3044 partner_link_info = &partner_info->partner_link_info[i];
3045
3046 qdf_mem_zero(&channel, sizeof(channel));
3047 channel.ch_freq = partner_link_info->chan_freq;
3048
3049 mlo_mgr_update_ap_link_info(session->vdev,
3050 partner_link_info->link_id,
3051 partner_link_info->link_addr.bytes,
3052 channel);
3053 }
3054 }
3055 #else
3056 static void
lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session * session)3057 lim_update_mlo_mgr_ap_link_info_mbssid_connect(struct pe_session *session)
3058 {}
3059 #endif
3060
3061 /**
3062 * lim_process_switch_channel_join_req() -Initiates probe request
3063 *
3064 * @mac_ctx - A pointer to Global MAC structure
3065 * @pe_session - session related information.
3066 * @status - channel switch success/failure
3067 *
3068 * This function is called to send the probe req mgmt frame
3069 * after the switchChannelRsp message is received from HAL.
3070 *
3071 * Return None
3072 */
lim_process_switch_channel_join_req(struct mac_context * mac_ctx,struct pe_session * session_entry,QDF_STATUS status)3073 static void lim_process_switch_channel_join_req(
3074 struct mac_context *mac_ctx, struct pe_session *session_entry,
3075 QDF_STATUS status)
3076 {
3077 tSirMacSSid ssId;
3078 tLimMlmJoinCnf join_cnf;
3079 uint8_t nontx_bss_id = 0;
3080 struct bss_description *bss;
3081 struct vdev_mlme_obj *mlme_obj;
3082 struct wlan_lmac_if_reg_tx_ops *tx_ops;
3083 bool tpe_change = false;
3084 QDF_STATUS mlo_status;
3085 struct pe_session *sap_session;
3086
3087 if (status != QDF_STATUS_SUCCESS) {
3088 pe_err("Change channel failed!!");
3089 goto error;
3090 }
3091
3092 if ((!session_entry) || (!session_entry->pLimMlmJoinReq) ||
3093 (!session_entry->lim_join_req)) {
3094 pe_err("invalid pointer!!");
3095 goto error;
3096 }
3097
3098 if (lim_connect_skip_join_for_gc(session_entry)) {
3099 join_cnf.resultCode = eSIR_SME_SUCCESS;
3100 join_cnf.protStatusCode = STATUS_SUCCESS;
3101 join_cnf.sessionId = session_entry->peSessionId;
3102 lim_post_sme_message(mac_ctx,
3103 LIM_MLM_JOIN_CNF,
3104 (uint32_t *)&join_cnf.resultCode);
3105 return;
3106 }
3107
3108 bss = &session_entry->lim_join_req->bssDescription;
3109 nontx_bss_id = bss->mbssid_info.profile_num;
3110
3111 session_entry->limPrevMlmState = session_entry->limMlmState;
3112 session_entry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE;
3113
3114 /* Apply previously set configuration at HW */
3115 lim_apply_configuration(mac_ctx, session_entry);
3116
3117 if (wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) {
3118 if (mlo_roam_is_auth_status_connected(mac_ctx->psoc,
3119 session_entry->vdev_id))
3120 mlo_status = lim_process_switch_channel_join_mlo_roam(session_entry,
3121 mac_ctx);
3122 else
3123 mlo_status = lim_process_switch_channel_join_mlo(session_entry,
3124 mac_ctx);
3125
3126 if (mlo_status == QDF_STATUS_E_INVAL)
3127 goto error;
3128 else
3129 return;
3130 }
3131 /*
3132 * If deauth_before_connection is enabled, Send Deauth first to AP if
3133 * last disconnection was caused by HB failure.
3134 */
3135 if (mac_ctx->mlme_cfg->sta.deauth_before_connection) {
3136 int apCount;
3137
3138 for (apCount = 0; apCount < 2; apCount++) {
3139
3140 if (!qdf_mem_cmp(session_entry->pLimMlmJoinReq->bssDescription.bssId,
3141 mac_ctx->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) {
3142
3143 pe_err("Index %d Sessionid: %d Send deauth on "
3144 "channel freq %d to BSSID: " QDF_MAC_ADDR_FMT,
3145 apCount,
3146 session_entry->peSessionId,
3147 session_entry->curr_op_freq,
3148 QDF_MAC_ADDR_REF(
3149 session_entry->pLimMlmJoinReq->bssDescription.bssId));
3150
3151 lim_send_deauth_mgmt_frame(mac_ctx, REASON_UNSPEC_FAILURE,
3152 session_entry->pLimMlmJoinReq->bssDescription.bssId,
3153 session_entry, false);
3154
3155 qdf_mem_zero(mac_ctx->lim.gLimHeartBeatApMac[apCount],
3156 sizeof(tSirMacAddr));
3157 break;
3158 }
3159 }
3160 }
3161
3162 /*
3163 * MBSSID: Non Tx BSS may or may not respond to unicast
3164 * probe request.So dont send unicast probe request
3165 * and wait for the probe response/ beacon to post JOIN CNF
3166 */
3167 if (nontx_bss_id) {
3168 pe_debug("Skip sending join probe for MBSS candidate");
3169 session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
3170 join_cnf.sessionId = session_entry->peSessionId;
3171 join_cnf.resultCode = eSIR_SME_SUCCESS;
3172 join_cnf.protStatusCode = STATUS_SUCCESS;
3173
3174 lim_update_mlo_mgr_ap_link_info_mbssid_connect(session_entry);
3175
3176 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
3177 (uint32_t *)&join_cnf);
3178 return;
3179 }
3180
3181 /* Wait for Beacon to announce join success */
3182 qdf_mem_copy(ssId.ssId,
3183 session_entry->ssId.ssId, session_entry->ssId.length);
3184 ssId.length = session_entry->ssId.length;
3185
3186 lim_deactivate_and_change_timer(mac_ctx,
3187 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
3188
3189 /* assign appropriate sessionId to the timer object */
3190 mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer.sessionId =
3191 session_entry->peSessionId;
3192 pe_debug("vdev %d Send Probe req on freq %d " QDF_SSID_FMT " " QDF_MAC_ADDR_FMT,
3193 session_entry->vdev_id,
3194 session_entry->curr_op_freq,
3195 QDF_SSID_REF(ssId.length, ssId.ssId),
3196 QDF_MAC_ADDR_REF(
3197 session_entry->pLimMlmJoinReq->bssDescription.bssId));
3198
3199 /*
3200 * We need to wait for probe response, so start join
3201 * timeout timer.This timer will be deactivated once
3202 * we receive probe response.
3203 */
3204 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
3205 session_entry->peSessionId, eLIM_JOIN_FAIL_TIMER));
3206 if (tx_timer_activate(&mac_ctx->lim.lim_timers.gLimJoinFailureTimer) !=
3207 TX_SUCCESS) {
3208 pe_err("couldn't activate Join failure timer");
3209 session_entry->limMlmState = session_entry->limPrevMlmState;
3210 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
3211 session_entry->peSessionId,
3212 mac_ctx->lim.gLimMlmState));
3213 goto error;
3214 }
3215
3216 sap_session =
3217 lim_get_concurrent_session(mac_ctx, session_entry->vdev_id,
3218 session_entry->opmode);
3219
3220 /*
3221 * STA LPI + SAP VLP is supported. For this, STA should move to
3222 * VLP power.
3223 * If there is a concurrent SAP operating on VLP in the same channel,
3224 * then do not update the TPC if the connecting AP is in LPI.
3225 */
3226 if (sap_session &&
3227 lim_is_power_change_required_for_sta(mac_ctx, session_entry, sap_session))
3228 lim_update_tx_power(mac_ctx, sap_session, session_entry, false);
3229
3230 if (wlan_reg_is_ext_tpc_supported(mac_ctx->psoc) &&
3231 !session_entry->sta_follows_sap_power) {
3232 tx_ops = wlan_reg_get_tx_ops(mac_ctx->psoc);
3233
3234 lim_process_tpe_ie_from_beacon(mac_ctx, session_entry, bss,
3235 &tpe_change);
3236
3237 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(session_entry->vdev);
3238 if (!mlme_obj) {
3239 pe_err("vdev component object is NULL");
3240 goto error;
3241 }
3242
3243 lim_calculate_tpc(mac_ctx, session_entry);
3244
3245 if (tx_ops->set_tpc_power)
3246 tx_ops->set_tpc_power(mac_ctx->psoc,
3247 session_entry->vdev_id,
3248 &mlme_obj->reg_tpc_obj);
3249 }
3250 /* include additional IE if there is */
3251 lim_send_probe_req_mgmt_frame(mac_ctx, &ssId,
3252 session_entry->pLimMlmJoinReq->bssDescription.bssId,
3253 session_entry->curr_op_freq,
3254 session_entry->self_mac_addr,
3255 session_entry->dot11mode,
3256 &session_entry->lim_join_req->addIEScan.length,
3257 session_entry->lim_join_req->addIEScan.addIEdata);
3258
3259 /* Activate Join Periodic Probe Req timer */
3260 if (tx_timer_activate
3261 (&mac_ctx->lim.lim_timers.gLimPeriodicJoinProbeReqTimer)
3262 != TX_SUCCESS) {
3263 pe_err("Periodic JoinReq timer activate failed");
3264 goto error;
3265 }
3266
3267 session_entry->join_probe_cnt++;
3268 return;
3269 error:
3270 if (session_entry) {
3271 if (session_entry->pLimMlmJoinReq) {
3272 qdf_mem_free(session_entry->pLimMlmJoinReq);
3273 session_entry->pLimMlmJoinReq = NULL;
3274 }
3275 if (session_entry->lim_join_req) {
3276 qdf_mem_free(session_entry->lim_join_req);
3277 session_entry->lim_join_req = NULL;
3278 }
3279 join_cnf.sessionId = session_entry->peSessionId;
3280 } else {
3281 join_cnf.sessionId = 0;
3282 }
3283 join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
3284 join_cnf.protStatusCode = STATUS_UNSPECIFIED_FAILURE;
3285 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, (uint32_t *)&join_cnf);
3286 }
3287
lim_handle_mon_switch_channel_rsp(struct pe_session * session,QDF_STATUS status)3288 static void lim_handle_mon_switch_channel_rsp(struct pe_session *session,
3289 QDF_STATUS status)
3290 {
3291 struct scheduler_msg message = {0};
3292
3293 if (session->bssType != eSIR_MONITOR_MODE)
3294 return;
3295
3296 if (QDF_IS_STATUS_ERROR(status)) {
3297 enum wlan_vdev_sm_evt event = WLAN_VDEV_SM_EV_START_REQ_FAIL;
3298
3299 pe_err("Set channel failed for monitor mode vdev substate %d",
3300 wlan_vdev_mlme_get_substate(session->vdev));
3301
3302 if (QDF_IS_STATUS_SUCCESS(
3303 wlan_vdev_is_restart_progress(session->vdev)))
3304 event = WLAN_VDEV_SM_EV_RESTART_REQ_FAIL;
3305
3306 wlan_vdev_mlme_sm_deliver_evt(session->vdev, event, 0, NULL);
3307
3308 return;
3309 }
3310
3311 wlan_vdev_mlme_sm_deliver_evt(session->vdev,
3312 WLAN_VDEV_SM_EV_START_SUCCESS, 0, NULL);
3313
3314 message.type = eWNI_SME_MONITOR_MODE_VDEV_UP;
3315 message.bodyval = session->vdev_id;
3316 pe_debug("vdev id %d ", session->vdev_id);
3317
3318 if (QDF_STATUS_SUCCESS !=
3319 scheduler_post_message(QDF_MODULE_ID_PE,
3320 QDF_MODULE_ID_SME,
3321 QDF_MODULE_ID_SME, &message)) {
3322 pe_err("Failed to post message montior mode vdev up");
3323 }
3324 }
3325
3326 /**
3327 * lim_process_switch_channel_rsp()
3328 *
3329 ***FUNCTION:
3330 * This function is called to process switchChannelRsp message from HAL.
3331 *
3332 ***LOGIC:
3333 *
3334 ***ASSUMPTIONS:
3335 * NA
3336 *
3337 ***NOTE:
3338 * NA
3339 *
3340 * @param mac - Pointer to Global MAC structure
3341 * @param body - message body.
3342 *
3343 * @return None
3344 */
lim_process_switch_channel_rsp(struct mac_context * mac,struct vdev_start_response * rsp)3345 void lim_process_switch_channel_rsp(struct mac_context *mac,
3346 struct vdev_start_response *rsp)
3347 {
3348 QDF_STATUS status;
3349 uint16_t channelChangeReasonCode;
3350 struct pe_session *pe_session;
3351 struct wlan_channel *vdev_chan;
3352 /* we need to process the deferred message since the initiating req. there might be nested request. */
3353 /* in the case of nested request the new request initiated from the response will take care of resetting */
3354 /* the deferred flag. */
3355 SET_LIM_PROCESS_DEFD_MESGS(mac, true);
3356 status = rsp->status;
3357
3358 pe_session = pe_find_session_by_vdev_id(mac, rsp->vdev_id);
3359 if (!pe_session) {
3360 pe_err("session does not exist for given sessionId");
3361 return;
3362 }
3363 pe_session->ch_switch_in_progress = false;
3364 channelChangeReasonCode = pe_session->channelChangeReasonCode;
3365 /* initialize it back to invalid id */
3366 pe_session->chainMask = rsp->chain_mask;
3367 pe_session->smpsMode = rsp->smps_mode;
3368 pe_session->channelChangeReasonCode = 0xBAD;
3369
3370 vdev_chan = wlan_vdev_mlme_get_des_chan(pe_session->vdev);
3371
3372 if (WLAN_REG_IS_24GHZ_CH_FREQ(vdev_chan->ch_freq)) {
3373 if (vdev_chan->ch_phymode == WLAN_PHYMODE_11B)
3374 pe_session->nwType = eSIR_11B_NW_TYPE;
3375 else
3376 pe_session->nwType = eSIR_11G_NW_TYPE;
3377 } else {
3378 pe_session->nwType = eSIR_11A_NW_TYPE;
3379 }
3380 pe_debug("new network type for peer: %d", pe_session->nwType);
3381 switch (channelChangeReasonCode) {
3382 case LIM_SWITCH_CHANNEL_REASSOC:
3383 lim_process_switch_channel_re_assoc_req(mac, pe_session, status);
3384 break;
3385 case LIM_SWITCH_CHANNEL_JOIN:
3386 lim_process_switch_channel_join_req(mac, pe_session, status);
3387 break;
3388
3389 case LIM_SWITCH_CHANNEL_OPERATION:
3390 case LIM_SWITCH_CHANNEL_HT_WIDTH:
3391 /*
3392 * The above code should also use the callback.
3393 * mechanism below, there is scope for cleanup here.
3394 * THat way all this response handler does is call the call back
3395 * We can get rid of the reason code here.
3396 */
3397 if (mac->lim.gpchangeChannelCallback)
3398 mac->lim.gpchangeChannelCallback(mac, status,
3399 mac->lim.
3400 gpchangeChannelData,
3401 pe_session);
3402
3403 /* If MCC upgrade/DBS downgrade happened during channel switch,
3404 * the policy manager connection table needs to be updated.
3405 * STA PCL to F/W need update after sta channel switch.
3406 */
3407 policy_mgr_update_connection_info(mac->psoc,
3408 pe_session->smeSessionId);
3409 wlan_cm_handle_sta_sta_roaming_enablement(mac->psoc,
3410 pe_session->smeSessionId);
3411 if (pe_session->opmode == QDF_P2P_CLIENT_MODE) {
3412 pe_debug("Send p2p operating channel change conf action frame once first beacon is received on new channel");
3413 pe_session->send_p2p_conf_frame = true;
3414 }
3415
3416 if (ucfg_pkt_capture_get_pktcap_mode(mac->psoc))
3417 ucfg_pkt_capture_record_channel(pe_session->vdev);
3418 break;
3419 case LIM_SWITCH_CHANNEL_SAP_DFS:
3420 if (QDF_IS_STATUS_SUCCESS(status))
3421 lim_set_tpc_power(mac, pe_session, NULL);
3422
3423 /* Note: This event code specific to SAP mode
3424 * When SAP session issues channel change as performing
3425 * DFS, we will come here. Other sessions, for e.g. P2P
3426 * will have to define their own event code and channel
3427 * switch handler. This is required since the SME may
3428 * require completely different information for P2P unlike
3429 * SAP.
3430 */
3431 lim_send_sme_ap_channel_switch_resp(mac, pe_session, rsp);
3432 /* If MCC upgrade/DBS downgrade happened during channel switch,
3433 * the policy manager connection table needs to be updated.
3434 */
3435 policy_mgr_update_connection_info(mac->psoc,
3436 pe_session->smeSessionId);
3437 lim_check_conc_power_for_csa(mac, pe_session);
3438 break;
3439 case LIM_SWITCH_CHANNEL_MONITOR:
3440 lim_handle_mon_switch_channel_rsp(pe_session, status);
3441 /*
3442 * If MCC upgrade/DBS downgrade happened during channel switch,
3443 * the policy manager connection table needs to be updated.
3444 */
3445 policy_mgr_update_connection_info(mac->psoc,
3446 pe_session->smeSessionId);
3447 if (ucfg_pkt_capture_get_pktcap_mode(mac->psoc))
3448 ucfg_pkt_capture_record_channel(pe_session->vdev);
3449 break;
3450 default:
3451 break;
3452 }
3453 }
3454
lim_send_beacon_ind(struct mac_context * mac,struct pe_session * pe_session,enum sir_bcn_update_reason reason)3455 QDF_STATUS lim_send_beacon_ind(struct mac_context *mac,
3456 struct pe_session *pe_session,
3457 enum sir_bcn_update_reason reason)
3458 {
3459 struct beacon_gen_params *params;
3460 struct scheduler_msg msg = {0};
3461
3462 if (!pe_session) {
3463 pe_err("Error:Unable to get the PESessionEntry");
3464 return QDF_STATUS_E_INVAL;
3465 }
3466 params = qdf_mem_malloc(sizeof(*params));
3467 if (!params)
3468 return QDF_STATUS_E_NOMEM;
3469 qdf_mem_copy(params->bssid, pe_session->bssId, QDF_MAC_ADDR_SIZE);
3470 msg.bodyptr = params;
3471
3472 return sch_process_pre_beacon_ind(mac, &msg, reason);
3473 }
3474