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