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), &param);
1448 	}
1449 	else
1450 		status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
1451 					       WLAN_VDEV_SM_EV_CONNECTION_FAIL,
1452 					       sizeof(param), &param);
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