xref: /wlan-dirver/qcacld-3.0/core/mac/src/pe/lim/lim_process_mlm_req_messages.c (revision bf14ba81a9dde77532035d124922099fe95cd35d)
1 /*
2  * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "cds_api.h"
20 #include "wni_cfg.h"
21 #include "ani_global.h"
22 #include "sir_api.h"
23 #include "sir_params.h"
24 #include "cfg_ucfg_api.h"
25 #include "sch_api.h"
26 #include "utils_api.h"
27 #include "lim_utils.h"
28 #include "lim_assoc_utils.h"
29 #include "lim_prop_exts_utils.h"
30 #include "lim_security_utils.h"
31 #include "lim_send_messages.h"
32 #include "lim_send_messages.h"
33 #include "lim_session_utils.h"
34 #include <lim_ft.h>
35 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
36 #include "host_diag_core_log.h"
37 #endif
38 #include "wma_if.h"
39 #include "wma.h"
40 #include "wlan_reg_services_api.h"
41 #include "lim_process_fils.h"
42 #include "wlan_mlme_public_struct.h"
43 
44 static void lim_process_mlm_auth_req(struct mac_context *, uint32_t *);
45 static void lim_process_mlm_assoc_req(struct mac_context *, uint32_t *);
46 static void lim_process_mlm_disassoc_req(struct mac_context *, uint32_t *);
47 static void lim_process_mlm_set_keys_req(struct mac_context *, uint32_t *);
48 
49 /* MLM Timeout event handler templates */
50 static void lim_process_auth_rsp_timeout(struct mac_context *, uint32_t);
51 static void lim_process_periodic_join_probe_req_timer(struct mac_context *);
52 static void lim_process_auth_retry_timer(struct mac_context *);
53 
54 /**
55  * lim_process_sae_auth_timeout() - This function is called to process sae
56  * auth timeout
57  * @mac_ctx: Pointer to Global MAC structure
58  *
59  * @Return: None
60  */
61 static void lim_process_sae_auth_timeout(struct mac_context *mac_ctx)
62 {
63 	struct pe_session *session;
64 
65 	session = pe_find_session_by_session_id(mac_ctx,
66 			mac_ctx->lim.limTimers.sae_auth_timer.sessionId);
67 	if (!session) {
68 		pe_err("Session does not exist for given session id");
69 		return;
70 	}
71 
72 	pe_warn("SAE auth timeout sessionid %d mlmstate %X SmeState %X",
73 		session->peSessionId, session->limMlmState,
74 		session->limSmeState);
75 
76 	switch (session->limMlmState) {
77 	case eLIM_MLM_WT_SAE_AUTH_STATE:
78 		/*
79 		 * SAE authentication is not completed. Restore from
80 		 * auth state.
81 		 */
82 		if (session->opmode == QDF_STA_MODE)
83 			lim_restore_from_auth_state(mac_ctx,
84 				eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
85 				eSIR_MAC_UNSPEC_FAILURE_REASON, session);
86 		break;
87 	default:
88 		/* SAE authentication is timed out in unexpected state */
89 		pe_err("received unexpected SAE auth timeout in state %X",
90 			session->limMlmState);
91 		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
92 		break;
93 	}
94 }
95 
96 /**
97  * lim_process_mlm_req_messages() - process mlm request messages
98  * @mac_ctx: global MAC context
99  * @msg: mlm request message
100  *
101  * This function is called by lim_post_mlm_message(). This
102  * function handles MLM primitives invoked by SME.
103  * Depending on the message type, corresponding function will be
104  * called.
105  * ASSUMPTIONS:
106  * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes
107  *    APIs exposed by Beacon Processing module for setting parameters
108  *    at MAC hardware.
109  * 2. If attempt to Reassociate with an AP fails, link with current
110  *    AP is restored back.
111  *
112  * Return: None
113  */
114 void lim_process_mlm_req_messages(struct mac_context *mac_ctx,
115 				  struct scheduler_msg *msg)
116 {
117 	switch (msg->type) {
118 	case LIM_MLM_AUTH_REQ:
119 		lim_process_mlm_auth_req(mac_ctx, msg->bodyptr);
120 		break;
121 	case LIM_MLM_ASSOC_REQ:
122 		lim_process_mlm_assoc_req(mac_ctx, msg->bodyptr);
123 		break;
124 	case LIM_MLM_DISASSOC_REQ:
125 		lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr);
126 		break;
127 	case LIM_MLM_SETKEYS_REQ:
128 		lim_process_mlm_set_keys_req(mac_ctx, msg->bodyptr);
129 		break;
130 	case SIR_LIM_JOIN_FAIL_TIMEOUT:
131 		lim_process_join_failure_timeout(mac_ctx);
132 		break;
133 	case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
134 		lim_process_periodic_join_probe_req_timer(mac_ctx);
135 		break;
136 	case SIR_LIM_AUTH_FAIL_TIMEOUT:
137 		lim_process_auth_failure_timeout(mac_ctx);
138 		break;
139 	case SIR_LIM_AUTH_RSP_TIMEOUT:
140 		lim_process_auth_rsp_timeout(mac_ctx, msg->bodyval);
141 		break;
142 	case SIR_LIM_ASSOC_FAIL_TIMEOUT:
143 		lim_process_assoc_failure_timeout(mac_ctx, msg->bodyval);
144 		break;
145 	case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
146 		lim_process_ft_preauth_rsp_timeout(mac_ctx);
147 		break;
148 	case SIR_LIM_DISASSOC_ACK_TIMEOUT:
149 		lim_process_disassoc_ack_timeout(mac_ctx);
150 		break;
151 	case SIR_LIM_DEAUTH_ACK_TIMEOUT:
152 		lim_process_deauth_ack_timeout(mac_ctx);
153 		break;
154 	case SIR_LIM_AUTH_RETRY_TIMEOUT:
155 		lim_process_auth_retry_timer(mac_ctx);
156 		break;
157 	case SIR_LIM_AUTH_SAE_TIMEOUT:
158 		lim_process_sae_auth_timeout(mac_ctx);
159 		break;
160 	case LIM_MLM_TSPEC_REQ:
161 	default:
162 		break;
163 	} /* switch (msg->type) */
164 }
165 
166 /**
167  * mlm_add_sta() - MLM add sta
168  * @mac_ctx: global MAC context
169  * @sta_param: Add sta params
170  * @bssid: BSSID
171  * @ht_capable: HT capability
172  * @session_entry: PE session entry
173  *
174  * This function is called to update station parameters
175  *
176  * Return: None
177  */
178 static void mlm_add_sta(struct mac_context *mac_ctx, tpAddStaParams sta_param,
179 		uint8_t *bssid, uint8_t ht_capable, struct pe_session *session_entry)
180 {
181 	uint32_t val;
182 	uint32_t self_dot11mode = mac_ctx->mlme_cfg->dot11_mode.dot11_mode;
183 
184 	sta_param->staType = STA_ENTRY_SELF; /* Identifying self */
185 
186 	qdf_mem_copy(sta_param->bssId, bssid, sizeof(tSirMacAddr));
187 	qdf_mem_copy(sta_param->staMac, session_entry->self_mac_addr,
188 		     sizeof(tSirMacAddr));
189 
190 	/* Configuration related parameters to be changed to support BT-AMP */
191 
192 	val = mac_ctx->mlme_cfg->sap_cfg.listen_interval;
193 	sta_param->listenInterval = (uint16_t) val;
194 
195 	sta_param->shortPreambleSupported =
196 		mac_ctx->mlme_cfg->ht_caps.short_preamble;
197 
198 	sta_param->assocId = 0;      /* Is SMAC OK with this? */
199 	sta_param->wmmEnabled = 0;
200 	sta_param->uAPSD = 0;
201 	sta_param->maxSPLen = 0;
202 	sta_param->us32MaxAmpduDuration = 0;
203 	sta_param->maxAmpduSize = 0; /* 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k */
204 
205 	/* For Self STA get the LDPC capability from config.ini */
206 	sta_param->htLdpcCapable =
207 		(session_entry->txLdpcIniFeatureEnabled & 0x01);
208 	sta_param->vhtLdpcCapable =
209 		((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
210 
211 	if (IS_DOT11_MODE_HT(session_entry->dot11mode)) {
212 		sta_param->htCapable = ht_capable;
213 		sta_param->greenFieldCapable =
214 			lim_get_ht_capability(mac_ctx, eHT_GREENFIELD,
215 					      session_entry);
216 		sta_param->ch_width =
217 			lim_get_ht_capability(mac_ctx,
218 				eHT_SUPPORTED_CHANNEL_WIDTH_SET, session_entry);
219 		sta_param->mimoPS =
220 			(tSirMacHTMIMOPowerSaveState)lim_get_ht_capability(
221 				mac_ctx, eHT_MIMO_POWER_SAVE, session_entry);
222 		sta_param->rifsMode =
223 			lim_get_ht_capability(mac_ctx, eHT_RIFS_MODE,
224 					      session_entry);
225 		sta_param->lsigTxopProtection =
226 			lim_get_ht_capability(mac_ctx, eHT_LSIG_TXOP_PROTECTION,
227 					      session_entry);
228 		sta_param->maxAmpduDensity =
229 			lim_get_ht_capability(mac_ctx, eHT_MPDU_DENSITY,
230 					      session_entry);
231 		sta_param->maxAmsduSize =
232 			lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_LENGTH,
233 					      session_entry);
234 		sta_param->max_amsdu_num =
235 			lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_NUM,
236 					      session_entry);
237 		sta_param->fDsssCckMode40Mhz =
238 			lim_get_ht_capability(mac_ctx, eHT_DSSS_CCK_MODE_40MHZ,
239 					      session_entry);
240 		sta_param->fShortGI20Mhz =
241 			lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ,
242 					      session_entry);
243 		sta_param->fShortGI40Mhz =
244 			lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ,
245 					      session_entry);
246 	}
247 	if (session_entry->vhtCapability) {
248 		sta_param->vhtCapable = true;
249 		sta_param->vhtTxBFCapable =
250 				session_entry->vht_config.su_beam_formee;
251 		sta_param->vhtTxMUBformeeCapable =
252 				session_entry->vht_config.mu_beam_formee;
253 		sta_param->enable_su_tx_bformer =
254 				session_entry->vht_config.su_beam_former;
255 	}
256 
257 	if (lim_is_session_he_capable(session_entry))
258 		lim_add_self_he_cap(sta_param, session_entry);
259 
260 	/*
261 	 * Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE
262 	 * capabilities
263 	 */
264 	if (IS_DOT11_MODE_VHT(self_dot11mode)) {
265 		sta_param->maxAmpduSize =
266 		mac_ctx->mlme_cfg->vht_caps.vht_cap_info.ampdu_len_exponent;
267 	}
268 	sta_param->enableVhtpAid = session_entry->enableVhtpAid;
269 	sta_param->enableAmpduPs = session_entry->enableAmpduPs;
270 	sta_param->enableHtSmps = session_entry->enableHtSmps;
271 	sta_param->htSmpsconfig = session_entry->htSmpsvalue;
272 	sta_param->send_smps_action = session_entry->send_smps_action;
273 
274 	lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
275 				  false, session_entry, NULL, NULL);
276 
277 	pe_debug("GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d,"
278 		" SGI20: %d, SGI40%d", sta_param->greenFieldCapable,
279 		sta_param->ch_width, sta_param->mimoPS,
280 		sta_param->lsigTxopProtection, sta_param->fDsssCckMode40Mhz,
281 		sta_param->fShortGI20Mhz, sta_param->fShortGI40Mhz);
282 
283 	if (QDF_P2P_GO_MODE == session_entry->opmode)
284 		sta_param->p2pCapableSta = 1;
285 }
286 
287 /**
288  * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ
289  * @mac_ctx: global MAC context
290  * @mlm_start_req: MLM start request
291  * @session: PE session entry
292  *
293  * Package WMA_ADD_BSS_REQ to HAL, in order to start a BSS
294  *
295  * Return: eSIR_SME_SUCCESS on success, other error codes otherwise
296  */
297 tSirResultCodes
298 lim_mlm_add_bss(struct mac_context *mac_ctx,
299 		tLimMlmStartReq *mlm_start_req, struct pe_session *session)
300 {
301 	struct scheduler_msg msg_buf = {0};
302 	struct bss_params *addbss_param = NULL;
303 	struct wlan_mlme_qos *qos_aggr = &mac_ctx->mlme_cfg->qos_mlme_params;
304 	uint32_t retcode;
305 	bool is_ch_dfs = false;
306 
307 	/* Package WMA_ADD_BSS_REQ message parameters */
308 	addbss_param = qdf_mem_malloc(sizeof(struct bss_params));
309 	if (!addbss_param)
310 		return eSIR_SME_RESOURCES_UNAVAILABLE;
311 
312 	/* Fill in struct bss_params members */
313 	qdf_mem_copy(addbss_param->bssId, mlm_start_req->bssId,
314 		     sizeof(tSirMacAddr));
315 
316 	/* Fill in struct bss_params self_mac_addr */
317 	qdf_mem_copy(addbss_param->self_mac_addr,
318 		     session->self_mac_addr, sizeof(tSirMacAddr));
319 
320 	addbss_param->bssType = mlm_start_req->bssType;
321 	if (mlm_start_req->bssType == eSIR_IBSS_MODE)
322 		addbss_param->operMode = BSS_OPERATIONAL_MODE_STA;
323 	else if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE)
324 		addbss_param->operMode = BSS_OPERATIONAL_MODE_AP;
325 	else if (mlm_start_req->bssType == eSIR_NDI_MODE)
326 		addbss_param->operMode = BSS_OPERATIONAL_MODE_NDI;
327 
328 	addbss_param->shortSlotTimeSupported = session->shortSlotTimeSupported;
329 	addbss_param->beaconInterval = mlm_start_req->beaconPeriod;
330 	addbss_param->dtimPeriod = mlm_start_req->dtimPeriod;
331 	addbss_param->wps_state = mlm_start_req->wps_state;
332 	addbss_param->cfParamSet.cfpCount = mlm_start_req->cfParamSet.cfpCount;
333 	addbss_param->cfParamSet.cfpPeriod =
334 		mlm_start_req->cfParamSet.cfpPeriod;
335 	addbss_param->cfParamSet.cfpMaxDuration =
336 		mlm_start_req->cfParamSet.cfpMaxDuration;
337 	addbss_param->cfParamSet.cfpDurRemaining =
338 		mlm_start_req->cfParamSet.cfpDurRemaining;
339 
340 	addbss_param->rateSet.numRates = mlm_start_req->rateSet.numRates;
341 	if (addbss_param->rateSet.numRates > WLAN_SUPPORTED_RATES_IE_MAX_LEN) {
342 		pe_warn("num of sup rates %d exceeding the limit %d, resetting",
343 			addbss_param->rateSet.numRates,
344 			WLAN_SUPPORTED_RATES_IE_MAX_LEN);
345 		addbss_param->rateSet.numRates = WLAN_SUPPORTED_RATES_IE_MAX_LEN;
346 	}
347 	qdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate,
348 		     addbss_param->rateSet.numRates);
349 
350 	addbss_param->nwType = mlm_start_req->nwType;
351 	addbss_param->htCapable = mlm_start_req->htCapable;
352 	addbss_param->vhtCapable = session->vhtCapability;
353 	if (lim_is_session_he_capable(session)) {
354 		lim_update_bss_he_capable(mac_ctx, addbss_param);
355 		lim_decide_he_op(mac_ctx, addbss_param, session);
356 		lim_update_usr_he_cap(mac_ctx, session);
357 	}
358 
359 	addbss_param->ch_width = session->ch_width;
360 	addbss_param->chan_freq_seg0 =
361 		wlan_reg_chan_to_freq(mac_ctx->pdev,
362 				      session->ch_center_freq_seg0);
363 	addbss_param->chan_freq_seg1 =
364 		wlan_reg_chan_to_freq(mac_ctx->pdev,
365 				      session->ch_center_freq_seg1);
366 	addbss_param->htOperMode = mlm_start_req->htOperMode;
367 	addbss_param->dualCTSProtection = mlm_start_req->dualCTSProtection;
368 	addbss_param->txChannelWidthSet = mlm_start_req->txChannelWidthSet;
369 
370 	addbss_param->op_chan_freq =
371 		wlan_reg_chan_to_freq(mac_ctx->pdev,
372 				      mlm_start_req->channelNumber);
373 #ifdef WLAN_FEATURE_11W
374 	addbss_param->rmfEnabled = session->limRmfEnabled;
375 #endif
376 
377 	/* Update PE sessionId */
378 	addbss_param->sessionId = mlm_start_req->sessionId;
379 	addbss_param->bss_idx = session->smeSessionId;
380 
381 
382 	/* Send the SSID to HAL to enable SSID matching for IBSS */
383 	addbss_param->ssId.length = mlm_start_req->ssId.length;
384 	if (addbss_param->ssId.length > WLAN_SSID_MAX_LEN) {
385 		pe_err("Invalid ssid length %d, max length allowed %d",
386 		       addbss_param->ssId.length,
387 		       WLAN_SSID_MAX_LEN);
388 		qdf_mem_free(addbss_param);
389 		return eSIR_SME_INVALID_PARAMETERS;
390 	}
391 	qdf_mem_copy(addbss_param->ssId.ssId,
392 		     mlm_start_req->ssId.ssId, addbss_param->ssId.length);
393 	addbss_param->bHiddenSSIDEn = mlm_start_req->ssidHidden;
394 	pe_debug("TRYING TO HIDE SSID %d", addbss_param->bHiddenSSIDEn);
395 	/* CR309183. Disable Proxy Probe Rsp.  Host handles Probe Requests.  Until FW fixed. */
396 	addbss_param->bProxyProbeRespEn = 0;
397 	addbss_param->obssProtEnabled = mlm_start_req->obssProtEnabled;
398 
399 	addbss_param->maxTxPower = session->maxTxPower;
400 
401 	mlm_add_sta(mac_ctx, &addbss_param->staContext,
402 		    addbss_param->bssId, addbss_param->htCapable,
403 		    session);
404 
405 	addbss_param->status = QDF_STATUS_SUCCESS;
406 	addbss_param->respReqd = 1;
407 
408 	/* Set a new state for MLME */
409 	session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE;
410 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
411 			 session->limMlmState));
412 
413 	/* pass on the session persona to hal */
414 	addbss_param->halPersona = session->opmode;
415 
416 	if (session->ch_width == CH_WIDTH_160MHZ) {
417 		is_ch_dfs = true;
418 	} else if (session->ch_width == CH_WIDTH_80P80MHZ) {
419 		if (wlan_reg_get_channel_state(mac_ctx->pdev,
420 					mlm_start_req->channelNumber) ==
421 				CHANNEL_STATE_DFS ||
422 				wlan_reg_get_channel_state(mac_ctx->pdev,
423 					session->ch_center_freq_seg1 -
424 					SIR_80MHZ_START_CENTER_CH_DIFF) ==
425 				CHANNEL_STATE_DFS)
426 			is_ch_dfs = true;
427 	} else {
428 		if (wlan_reg_get_channel_state(mac_ctx->pdev,
429 					mlm_start_req->channelNumber) ==
430 				CHANNEL_STATE_DFS)
431 			is_ch_dfs = true;
432 	}
433 
434 	addbss_param->bSpectrumMgtEnabled =
435 				session->spectrumMgtEnabled || is_ch_dfs;
436 	addbss_param->extSetStaKeyParamValid = 0;
437 
438 	addbss_param->dot11_mode = session->dot11mode;
439 	addbss_param->nss = session->nss;
440 	addbss_param->cac_duration_ms = mlm_start_req->cac_duration_ms;
441 	addbss_param->dfs_regdomain = mlm_start_req->dfs_regdomain;
442 	addbss_param->beacon_tx_rate = session->beacon_tx_rate;
443 	if (QDF_IBSS_MODE == addbss_param->halPersona) {
444 		if (!(mac_ctx->mlme_cfg)) {
445 			pe_err("Mlme cfg NULL");
446 			return eSIR_SME_INVALID_PARAMETERS;
447 		}
448 		addbss_param->nss_2g = mac_ctx->vdev_type_nss_2g.ibss;
449 		addbss_param->nss_5g = mac_ctx->vdev_type_nss_5g.ibss;
450 		addbss_param->tx_aggregation_size =
451 					qos_aggr->tx_aggregation_size;
452 		addbss_param->tx_aggregation_size_be =
453 					qos_aggr->tx_aggregation_size_be;
454 		addbss_param->tx_aggregation_size_bk =
455 					qos_aggr->tx_aggregation_size_bk;
456 		addbss_param->tx_aggregation_size_vi =
457 					qos_aggr->tx_aggregation_size_vi;
458 		addbss_param->tx_aggregation_size_vo =
459 					qos_aggr->tx_aggregation_size_vo;
460 		addbss_param->rx_aggregation_size =
461 					qos_aggr->rx_aggregation_size;
462 	}
463 	pe_debug("dot11_mode:%d nss value:%d",
464 			addbss_param->dot11_mode, addbss_param->nss);
465 
466 	if (cds_is_5_mhz_enabled()) {
467 		addbss_param->ch_width = CH_WIDTH_5MHZ;
468 		addbss_param->staContext.ch_width = CH_WIDTH_5MHZ;
469 	} else if (cds_is_10_mhz_enabled()) {
470 		addbss_param->ch_width = CH_WIDTH_10MHZ;
471 		addbss_param->staContext.ch_width = CH_WIDTH_10MHZ;
472 	}
473 
474 	msg_buf.type = WMA_ADD_BSS_REQ;
475 	msg_buf.reserved = 0;
476 	msg_buf.bodyptr = addbss_param;
477 	msg_buf.bodyval = 0;
478 	MTRACE(mac_trace_msg_tx(mac_ctx, session->peSessionId, msg_buf.type));
479 
480 	pe_debug("Sending WMA_ADD_BSS_REQ...");
481 	retcode = wma_post_ctrl_msg(mac_ctx, &msg_buf);
482 	if (QDF_STATUS_SUCCESS != retcode) {
483 		pe_err("Posting ADD_BSS_REQ to HAL failed, reason=%X",
484 			retcode);
485 		qdf_mem_free(addbss_param);
486 		return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
487 	}
488 
489 	return eSIR_SME_SUCCESS;
490 }
491 
492 void lim_process_mlm_start_req(struct mac_context *mac_ctx,
493 			       tLimMlmStartReq *mlm_start_req)
494 {
495 	tLimMlmStartCnf mlm_start_cnf;
496 	struct pe_session *session = NULL;
497 
498 	if (!mlm_start_req) {
499 		pe_err("Buffer is Pointing to NULL");
500 		return;
501 	}
502 
503 	session = pe_find_session_by_session_id(mac_ctx,
504 				mlm_start_req->sessionId);
505 	if (!session) {
506 		pe_err("Session Does not exist for given sessionID");
507 		mlm_start_cnf.resultCode = eSIR_SME_REFUSED;
508 		goto end;
509 	}
510 
511 	if (session->limMlmState != eLIM_MLM_IDLE_STATE) {
512 		/*
513 		 * Should not have received Start req in states other than idle.
514 		 * Return Start confirm with failure code.
515 		 */
516 		pe_err("received unexpected MLM_START_REQ in state %X",
517 			session->limMlmState);
518 		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
519 		mlm_start_cnf.resultCode =
520 				eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
521 		goto end;
522 	}
523 
524 	mlm_start_cnf.resultCode =
525 		lim_mlm_add_bss(mac_ctx, mlm_start_req, session);
526 
527 end:
528 	/* Update PE session Id */
529 	mlm_start_cnf.sessionId = mlm_start_req->sessionId;
530 
531 	/*
532 	 * Respond immediately to LIM, only if MLME has not been
533 	 * successfully able to send WMA_ADD_BSS_REQ to HAL.
534 	 * Else, LIM_MLM_START_CNF will be sent after receiving
535 	 * WMA_ADD_BSS_RSP from HAL
536 	 */
537 	if (eSIR_SME_SUCCESS != mlm_start_cnf.resultCode)
538 		lim_send_start_bss_confirm(mac_ctx, &mlm_start_cnf);
539 }
540 
541 /**
542  * lim_post_join_set_link_state_callback()- registered callback to perform post
543  * peer creation operations
544  *
545  * @mac: pointer to global mac structure
546  * @callback_arg: registered callback argument
547  * @status: peer creation status
548  *
549  * this is registered callback function during association to perform
550  * post peer creation operation based on the peer creation status
551  *
552  * Return: none
553  */
554 static void lim_post_join_set_link_state_callback(
555 		struct mac_context *mac,
556 		struct pe_session *session_entry, QDF_STATUS status)
557 {
558 	tLimMlmJoinCnf mlm_join_cnf;
559 
560 	if (!session_entry) {
561 		pe_err("sessionId is NULL");
562 		return;
563 	}
564 
565 	pe_debug("Sessionid %d set link state(%d) cb status: %d",
566 		session_entry->peSessionId, session_entry->limMlmState,
567 			status);
568 
569 	if (QDF_IS_STATUS_ERROR(status)) {
570 		pe_err("failed to find pe session for session id:%d",
571 			session_entry->peSessionId);
572 		goto failure;
573 	}
574 
575 	/*
576 	 * store the channel switch session_entry in the lim
577 	 * global variable
578 	 */
579 	session_entry->channelChangeReasonCode =
580 			 LIM_SWITCH_CHANNEL_JOIN;
581 	session_entry->pLimMlmReassocRetryReq = NULL;
582 	pe_debug("[lim_process_mlm_join_req]: suspend link success(%d) "
583 		 "on sessionid: %d setting channel to: freq %d with ch_width :%d "
584 		 "and maxtxPower: %d", status, session_entry->peSessionId,
585 		 session_entry->curr_op_freq,
586 		 session_entry->ch_width,
587 		 session_entry->maxTxPower);
588 	lim_set_channel(
589 		mac,
590 		wlan_reg_freq_to_chan(mac->pdev, session_entry->curr_op_freq),
591 		session_entry->ch_center_freq_seg0,
592 		session_entry->ch_center_freq_seg1,
593 		session_entry->ch_width,
594 		session_entry->maxTxPower,
595 		session_entry->peSessionId, 0, 0);
596 	return;
597 
598 failure:
599 	MTRACE(mac_trace(mac, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
600 			 session_entry->limMlmState));
601 	session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
602 	mlm_join_cnf.resultCode = eSIR_SME_PEER_CREATE_FAILED;
603 	mlm_join_cnf.sessionId = session_entry->peSessionId;
604 	mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
605 	lim_post_sme_message(mac, LIM_MLM_JOIN_CNF, (uint32_t *) &mlm_join_cnf);
606 }
607 
608 /**
609  * lim_process_mlm_post_join_suspend_link() - This function is called after the
610  * suspend link while joining off channel.
611  *
612  * @mac_ctx:    Pointer to Global MAC structure
613  * @status:  status of suspend link.
614  * @ctx:     passed while calling suspend link(session)
615  *
616  * This function does following:
617  *   Check for suspend state.
618  *   If success, proceed with setting link state to receive the
619  *   probe response/beacon from intended AP.
620  *   Switch to the APs channel.
621  *   On an error case, send the MLM_JOIN_CNF with error status.
622  *
623  * @Return None
624  */
625 static void
626 lim_process_mlm_post_join_suspend_link(struct mac_context *mac_ctx,
627 				       QDF_STATUS status,
628 				       uint32_t *ctx)
629 {
630 	struct pe_session *session = (struct pe_session *) ctx;
631 
632 	if (QDF_STATUS_SUCCESS != status) {
633 		pe_err("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join",
634 			session->peSessionId);
635 	}
636 	lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
637 
638 	/* assign appropriate sessionId to the timer object */
639 	mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId =
640 		session->peSessionId;
641 
642 	status = wma_add_bss_peer_sta(session->self_mac_addr, session->bssId,
643 				      false);
644 	lim_post_join_set_link_state_callback(mac_ctx, session, status);
645 
646 	return;
647 }
648 
649 /**
650  * lim_process_mlm_join_req() - process mlm join request.
651  *
652  * @mac_ctx:    Pointer to Global MAC structure
653  * @mlm_join_req:        Pointer to the mlme join request
654  *
655  * This function is called to process MLM_JOIN_REQ message
656  * from SME. It does following:
657  * 1) Initialize LIM, HAL, DPH
658  * 2) Configure the BSS for which the JOIN REQ was received
659  *   a) Send WMA_ADD_BSS_REQ to HAL -
660  *   This will identify the BSS that we are interested in
661  *   --AND--
662  *   Add a STA entry for the AP (in a STA context)
663  *   b) Wait for WMA_ADD_BSS_RSP
664  *   c) Send WMA_ADD_STA_REQ to HAL
665  *   This will add the "local STA" entry to the STA table
666  * 3) Continue as before, i.e,
667  *   a) Send a PROBE REQ
668  *   b) Wait for PROBE RSP/BEACON containing the SSID that
669  *   we are interested in
670  *   c) Then start an AUTH seq
671  *   d) Followed by the ASSOC seq
672  *
673  * @Return: None
674  */
675 void lim_process_mlm_join_req(struct mac_context *mac_ctx,
676 			      tLimMlmJoinReq *mlm_join_req)
677 {
678 	tLimMlmJoinCnf mlmjoin_cnf;
679 	uint8_t sessionid;
680 	struct pe_session *session;
681 
682 	sessionid = mlm_join_req->sessionId;
683 
684 	session = pe_find_session_by_session_id(mac_ctx, sessionid);
685 	if (!session) {
686 		pe_err("SessionId:%d does not exist", sessionid);
687 		goto error;
688 	}
689 
690 	if (!LIM_IS_AP_ROLE(session) &&
691 	     ((session->limMlmState == eLIM_MLM_IDLE_STATE) ||
692 	     (session->limMlmState == eLIM_MLM_JOINED_STATE)) &&
693 	     (SIR_MAC_GET_ESS
694 		(mlm_join_req->bssDescription.capabilityInfo) !=
695 		SIR_MAC_GET_IBSS(mlm_join_req->bssDescription.
696 			capabilityInfo))) {
697 		/* Hold onto Join request parameters */
698 
699 		session->pLimMlmJoinReq = mlm_join_req;
700 		if (is_lim_session_off_channel(mac_ctx, sessionid)) {
701 			pe_debug("SessionId:%d LimSession is on OffChannel",
702 				sessionid);
703 			/* suspend link */
704 			pe_debug("Suspend link, sessionid %d is off channel",
705 				sessionid);
706 			lim_process_mlm_post_join_suspend_link(mac_ctx,
707 				QDF_STATUS_SUCCESS, (uint32_t *)session);
708 		} else {
709 			pe_debug("No need to Suspend link");
710 			 /*
711 			  * No need to Suspend link as LimSession is not
712 			  * off channel, calling
713 			  * lim_process_mlm_post_join_suspend_link with
714 			  * status as SUCCESS.
715 			  */
716 			pe_debug("SessionId:%d Join req on current chan",
717 				sessionid);
718 			lim_process_mlm_post_join_suspend_link(mac_ctx,
719 				QDF_STATUS_SUCCESS, (uint32_t *)session);
720 		}
721 		return;
722 	} else {
723 		/**
724 		 * Should not have received JOIN req in states other than
725 		 * Idle state or on AP.
726 		 * Return join confirm with invalid parameters code.
727 		 */
728 		pe_err("Session:%d Unexpected Join req, role %d state %X",
729 			session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
730 			session->limMlmState);
731 		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
732 	}
733 
734 error:
735 	qdf_mem_free(mlm_join_req);
736 	if (session)
737 		session->pLimMlmJoinReq = NULL;
738 	mlmjoin_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
739 	mlmjoin_cnf.sessionId = sessionid;
740 	mlmjoin_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
741 	lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
742 		(uint32_t *)&mlmjoin_cnf);
743 
744 }
745 
746 /**
747  * lim_is_auth_req_expected() - check if auth request is expected
748  *
749  * @mac_ctx: global MAC context
750  * @session: PE session entry
751  *
752  * This function is called by lim_process_mlm_auth_req to check
753  * if auth request is expected.
754  *
755  * Return: true if expected and false otherwise
756  */
757 static bool lim_is_auth_req_expected(struct mac_context *mac_ctx,
758 				     struct pe_session *session)
759 {
760 	bool flag = false;
761 
762 	/*
763 	 * Expect Auth request only when:
764 	 * 1. STA joined/associated with a BSS or
765 	 * 2. STA is in IBSS mode
766 	 * and STA is going to authenticate with a unicast
767 	 * address and requested authentication algorithm is
768 	 * supported.
769 	 */
770 
771 	flag = (((LIM_IS_STA_ROLE(session) &&
772 		 ((session->limMlmState == eLIM_MLM_JOINED_STATE) ||
773 		  (session->limMlmState ==
774 					eLIM_MLM_LINK_ESTABLISHED_STATE))) ||
775 		  (LIM_IS_IBSS_ROLE(session) &&
776 		  (session->limMlmState ==
777 					eLIM_MLM_BSS_STARTED_STATE))) &&
778 		(!IEEE80211_IS_MULTICAST(
779 			mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr)) &&
780 		 lim_is_auth_algo_supported(mac_ctx,
781 			mac_ctx->lim.gpLimMlmAuthReq->authType, session));
782 
783 	return flag;
784 }
785 
786 /**
787  * lim_is_preauth_ctx_exisits() - check if preauth context exists
788  *
789  * @mac_ctx:          global MAC context
790  * @session:          PE session entry
791  * @preauth_node_ptr: pointer to preauth node pointer
792  *
793  * This function is called by lim_process_mlm_auth_req to check
794  * if preauth context already exists
795  *
796  * Return: true if exists and false otherwise
797  */
798 static bool lim_is_preauth_ctx_exists(struct mac_context *mac_ctx,
799 				      struct pe_session *session,
800 				      struct tLimPreAuthNode **preauth_node_ptr)
801 {
802 	bool fl = false;
803 	struct tLimPreAuthNode *preauth_node;
804 	tpDphHashNode stads;
805 	tSirMacAddr curr_bssid;
806 
807 	preauth_node = *preauth_node_ptr;
808 	sir_copy_mac_addr(curr_bssid, session->bssId);
809 	stads = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
810 				   &session->dph.dphHashTable);
811 	preauth_node = lim_search_pre_auth_list(mac_ctx,
812 				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
813 
814 	fl = (((LIM_IS_STA_ROLE(session)) &&
815 	       (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
816 	      ((stads) &&
817 	       (mac_ctx->lim.gpLimMlmAuthReq->authType ==
818 			stads->mlmStaContext.authType)) &&
819 	       (!qdf_mem_cmp(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
820 			curr_bssid, sizeof(tSirMacAddr)))) ||
821 	      ((preauth_node) &&
822 	       (preauth_node->authType ==
823 			mac_ctx->lim.gpLimMlmAuthReq->authType)));
824 
825 	return fl;
826 }
827 
828 #ifdef WLAN_FEATURE_SAE
829 /**
830  * lim_process_mlm_auth_req_sae() - Handle SAE authentication
831  * @mac_ctx: global MAC context
832  * @session: PE session entry
833  *
834  * This function is called by lim_process_mlm_auth_req to handle SAE
835  * authentication.
836  *
837  * Return: QDF_STATUS
838  */
839 static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx,
840 		struct pe_session *session)
841 {
842 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
843 	struct sir_sae_info *sae_info;
844 	struct scheduler_msg msg = {0};
845 
846 	sae_info = qdf_mem_malloc(sizeof(*sae_info));
847 	if (!sae_info)
848 		return QDF_STATUS_E_FAILURE;
849 
850 	sae_info->msg_type = eWNI_SME_TRIGGER_SAE;
851 	sae_info->msg_len = sizeof(*sae_info);
852 	sae_info->vdev_id = session->smeSessionId;
853 
854 	qdf_mem_copy(sae_info->peer_mac_addr.bytes,
855 		session->bssId,
856 		QDF_MAC_ADDR_SIZE);
857 
858 	sae_info->ssid.length = session->ssId.length;
859 	qdf_mem_copy(sae_info->ssid.ssId,
860 		session->ssId.ssId,
861 		session->ssId.length);
862 
863 	pe_debug("vdev_id %d ssid %.*s "QDF_MAC_ADDR_STR,
864 		sae_info->vdev_id,
865 		sae_info->ssid.length,
866 		sae_info->ssid.ssId,
867 		QDF_MAC_ADDR_ARRAY(sae_info->peer_mac_addr.bytes));
868 
869 	msg.type = eWNI_SME_TRIGGER_SAE;
870 	msg.bodyptr = sae_info;
871 	msg.bodyval = 0;
872 
873 	qdf_status = mac_ctx->lim.sme_msg_callback(mac_ctx, &msg);
874 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
875 		pe_err("SAE failed for AUTH frame");
876 		qdf_mem_free(sae_info);
877 		return qdf_status;
878 	}
879 	session->limMlmState = eLIM_MLM_WT_SAE_AUTH_STATE;
880 
881 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
882 		       session->limMlmState));
883 
884 	mac_ctx->lim.limTimers.sae_auth_timer.sessionId =
885 					session->peSessionId;
886 
887 	/* Activate SAE auth timer */
888 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
889 			 session->peSessionId, eLIM_AUTH_SAE_TIMER));
890 	if (tx_timer_activate(&mac_ctx->lim.limTimers.sae_auth_timer)
891 		    != TX_SUCCESS) {
892 		pe_err("could not start Auth SAE timer");
893 	}
894 
895 	return qdf_status;
896 }
897 #else
898 static QDF_STATUS lim_process_mlm_auth_req_sae(struct mac_context *mac_ctx,
899 		struct pe_session *session)
900 {
901 	return QDF_STATUS_E_NOSUPPORT;
902 }
903 #endif
904 
905 
906 /**
907  * lim_process_mlm_auth_req() - process lim auth request
908  *
909  * @mac_ctx:   global MAC context
910  * @msg:       MLM auth request message
911  *
912  * This function is called to process MLM_AUTH_REQ message from SME
913  *
914  * @Return: None
915  */
916 static void lim_process_mlm_auth_req(struct mac_context *mac_ctx, uint32_t *msg)
917 {
918 	uint32_t num_preauth_ctx;
919 	tSirMacAddr curr_bssid;
920 	tSirMacAuthFrameBody auth_frame_body;
921 	tLimMlmAuthCnf mlm_auth_cnf;
922 	struct tLimPreAuthNode *preauth_node = NULL;
923 	uint8_t session_id;
924 	struct pe_session *session;
925 
926 	if (!msg) {
927 		pe_err("Buffer is Pointing to NULL");
928 		return;
929 	}
930 
931 	mac_ctx->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) msg;
932 	session_id = mac_ctx->lim.gpLimMlmAuthReq->sessionId;
933 	session = pe_find_session_by_session_id(mac_ctx, session_id);
934 	if (!session) {
935 		pe_err("SessionId:%d does not exist", session_id);
936 		qdf_mem_free(msg);
937 		mac_ctx->lim.gpLimMlmAuthReq = NULL;
938 		return;
939 	}
940 
941 	pe_debug("Process Auth Req sessionID %d Systemrole %d"
942 		       "mlmstate %d from: " QDF_MAC_ADDR_STR
943 		       " with authtype %d", session_id,
944 		GET_LIM_SYSTEM_ROLE(session), session->limMlmState,
945 		QDF_MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr),
946 		mac_ctx->lim.gpLimMlmAuthReq->authType);
947 
948 	sir_copy_mac_addr(curr_bssid, session->bssId);
949 
950 	if (!lim_is_auth_req_expected(mac_ctx, session)) {
951 		/*
952 		 * Unexpected auth request.
953 		 * Return Auth confirm with Invalid parameters code.
954 		 */
955 		mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
956 		goto end;
957 	}
958 
959 	/*
960 	 * This is a request for pre-authentication. Check if there exists
961 	 * context already for the requested peer OR
962 	 * if this request is for the AP we're currently associated with.
963 	 * If yes, return auth confirm immediately when
964 	 * requested auth type is same as the one used before.
965 	 */
966 	if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) {
967 		pe_debug("Already have pre-auth context with peer: "
968 		    QDF_MAC_ADDR_STR,
969 		    QDF_MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr));
970 		mlm_auth_cnf.resultCode = (tSirResultCodes)
971 						eSIR_MAC_SUCCESS_STATUS;
972 		goto end;
973 	} else {
974 		num_preauth_ctx = mac_ctx->mlme_cfg->lfr.max_num_pre_auth;
975 		if (mac_ctx->lim.gLimNumPreAuthContexts == num_preauth_ctx) {
976 			pe_warn("Number of pre-auth reached max limit");
977 			/* Return Auth confirm with reject code */
978 			mlm_auth_cnf.resultCode =
979 				eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED;
980 			goto end;
981 		}
982 	}
983 
984 	/* Delete pre-auth node if exists */
985 	if (preauth_node)
986 		lim_delete_pre_auth_node(mac_ctx,
987 			 mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
988 
989 	session->limPrevMlmState = session->limMlmState;
990 
991 	if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
992 	     !session->sae_pmk_cached) {
993 		if (lim_process_mlm_auth_req_sae(mac_ctx, session) !=
994 					QDF_STATUS_SUCCESS) {
995 			mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
996 			goto end;
997 		} else {
998 			pe_debug("lim_process_mlm_auth_req_sae is successful");
999 			auth_frame_body.authAlgoNumber = eSIR_AUTH_TYPE_SAE;
1000 			auth_frame_body.authTransactionSeqNumber =
1001 							SIR_MAC_AUTH_FRAME_1;
1002 			auth_frame_body.authStatusCode = 0;
1003 			host_log_wlan_auth_info(auth_frame_body.authAlgoNumber,
1004 				auth_frame_body.authTransactionSeqNumber,
1005 				auth_frame_body.authStatusCode);
1006 
1007 			return;
1008 		}
1009 	} else
1010 		session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
1011 
1012 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
1013 		       session->limMlmState));
1014 
1015 	/* Mark auth algo as open when auth type is SAE and PMK is cached */
1016 	if ((mac_ctx->lim.gpLimMlmAuthReq->authType == eSIR_AUTH_TYPE_SAE) &&
1017 	   session->sae_pmk_cached) {
1018 		auth_frame_body.authAlgoNumber = eSIR_OPEN_SYSTEM;
1019 	} else {
1020 		auth_frame_body.authAlgoNumber =
1021 		(uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
1022 	}
1023 
1024 	/* Prepare & send Authentication frame */
1025 	auth_frame_body.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
1026 	auth_frame_body.authStatusCode = 0;
1027 	host_log_wlan_auth_info(auth_frame_body.authAlgoNumber,
1028 				auth_frame_body.authTransactionSeqNumber,
1029 				auth_frame_body.authStatusCode);
1030 	mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
1031 	lim_send_auth_mgmt_frame(mac_ctx,
1032 		&auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
1033 		LIM_NO_WEP_IN_FC, session);
1034 
1035 	/* assign appropriate session_id to the timer object */
1036 	mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId = session_id;
1037 
1038 	/* assign appropriate sessionId to the timer object */
1039 	 mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId =
1040 								  session_id;
1041 	 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
1042 	/* Activate Auth failure timer */
1043 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
1044 			 session->peSessionId, eLIM_AUTH_FAIL_TIMER));
1045 	 lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_FAIL_TIMER);
1046 	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAuthFailureTimer)
1047 	    != TX_SUCCESS) {
1048 		pe_err("could not start Auth failure timer");
1049 		/* Cleanup as if auth timer expired */
1050 		lim_process_auth_failure_timeout(mac_ctx);
1051 	} else {
1052 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
1053 			   session->peSessionId, eLIM_AUTH_RETRY_TIMER));
1054 		/* Activate Auth Retry timer */
1055 		if (tx_timer_activate
1056 		    (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer)
1057 							      != TX_SUCCESS)
1058 			pe_err("could not activate Auth Retry timer");
1059 	}
1060 
1061 	return;
1062 end:
1063 	qdf_mem_copy((uint8_t *) &mlm_auth_cnf.peerMacAddr,
1064 		     (uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
1065 		     sizeof(tSirMacAddr));
1066 
1067 	mlm_auth_cnf.authType = mac_ctx->lim.gpLimMlmAuthReq->authType;
1068 	mlm_auth_cnf.sessionId = session_id;
1069 
1070 	qdf_mem_free(mac_ctx->lim.gpLimMlmAuthReq);
1071 	mac_ctx->lim.gpLimMlmAuthReq = NULL;
1072 	pe_debug("SessionId:%d LimPostSme LIM_MLM_AUTH_CNF",
1073 		session_id);
1074 	lim_post_sme_message(mac_ctx, LIM_MLM_AUTH_CNF,
1075 			     (uint32_t *) &mlm_auth_cnf);
1076 }
1077 
1078 /**
1079  * lim_process_mlm_assoc_req() - This function is called to process
1080  * MLM_ASSOC_REQ message from SME
1081  *
1082  * @mac_ctx:       Pointer to Global MAC structure
1083  * @msg_buf:       A pointer to the MLM message buffer
1084  *
1085  * This function is called to process MLM_ASSOC_REQ message from SME
1086  *
1087  * @Return None
1088  */
1089 
1090 static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg_buf)
1091 {
1092 	tSirMacAddr curr_bssId;
1093 	tLimMlmAssocReq *mlm_assoc_req;
1094 	tLimMlmAssocCnf mlm_assoc_cnf;
1095 	struct pe_session *session_entry;
1096 
1097 	if (!msg_buf) {
1098 		pe_err("Buffer is Pointing to NULL");
1099 		return;
1100 	}
1101 
1102 	mlm_assoc_req = (tLimMlmAssocReq *) msg_buf;
1103 	session_entry = pe_find_session_by_session_id(mac_ctx,
1104 						      mlm_assoc_req->sessionId);
1105 	if (!session_entry) {
1106 		pe_err("SessionId:%d Session Does not exist",
1107 			mlm_assoc_req->sessionId);
1108 		qdf_mem_free(mlm_assoc_req);
1109 		return;
1110 	}
1111 
1112 	sir_copy_mac_addr(curr_bssId, session_entry->bssId);
1113 
1114 	if (!(!LIM_IS_AP_ROLE(session_entry) &&
1115 		(session_entry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE ||
1116 		 session_entry->limMlmState == eLIM_MLM_JOINED_STATE) &&
1117 		(!qdf_mem_cmp(mlm_assoc_req->peerMacAddr,
1118 		 curr_bssId, sizeof(tSirMacAddr))))) {
1119 		/*
1120 		 * Received Association request either in invalid state
1121 		 * or to a peer MAC entity whose address is different
1122 		 * from one that STA is currently joined with or on AP.
1123 		 * Return Assoc confirm with Invalid parameters code.
1124 		 */
1125 		pe_warn("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= "
1126 			   QDF_MAC_ADDR_STR, session_entry->limMlmState,
1127 			GET_LIM_SYSTEM_ROLE(session_entry),
1128 			QDF_MAC_ADDR_ARRAY(mlm_assoc_req->peerMacAddr));
1129 		lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState);
1130 		mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
1131 		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
1132 		goto end;
1133 	}
1134 
1135 	/* map the session entry pointer to the AssocFailureTimer */
1136 	mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId =
1137 		mlm_assoc_req->sessionId;
1138 	session_entry->limPrevMlmState = session_entry->limMlmState;
1139 	session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
1140 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
1141 			 session_entry->peSessionId,
1142 			 session_entry->limMlmState));
1143 	pe_debug("SessionId:%d Sending Assoc_Req Frame",
1144 		session_entry->peSessionId);
1145 
1146 	/* Prepare and send Association request frame */
1147 	lim_send_assoc_req_mgmt_frame(mac_ctx, mlm_assoc_req, session_entry);
1148 
1149 	/* Start association failure timer */
1150 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
1151 			 session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER));
1152 	if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAssocFailureTimer)
1153 	    != TX_SUCCESS) {
1154 		pe_warn("SessionId:%d couldn't start Assoc failure timer",
1155 			session_entry->peSessionId);
1156 		/* Cleanup as if assoc timer expired */
1157 		lim_process_assoc_failure_timeout(mac_ctx, LIM_ASSOC);
1158 	}
1159 
1160 	return;
1161 end:
1162 	/* Update PE session Id */
1163 	mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId;
1164 	/* Free up buffer allocated for assocReq */
1165 	qdf_mem_free(mlm_assoc_req);
1166 	lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
1167 			     (uint32_t *) &mlm_assoc_cnf);
1168 }
1169 
1170 /**
1171  * lim_process_mlm_disassoc_req_ntf() - process disassoc request notification
1172  *
1173  * @mac_ctx:        global MAC context
1174  * @suspend_status: suspend status
1175  * @msg:            mlm message buffer
1176  *
1177  * This function is used to process MLM disassoc notification
1178  *
1179  * Return: None
1180  */
1181 static void
1182 lim_process_mlm_disassoc_req_ntf(struct mac_context *mac_ctx,
1183 				 QDF_STATUS suspend_status, uint32_t *msg)
1184 {
1185 	uint16_t aid;
1186 	struct qdf_mac_addr curr_bssid;
1187 	tpDphHashNode stads;
1188 	tLimMlmDisassocReq *mlm_disassocreq;
1189 	tLimMlmDisassocCnf mlm_disassoccnf;
1190 	struct pe_session *session;
1191 	extern bool send_disassoc_frame;
1192 	tLimMlmStates mlm_state;
1193 	struct disassoc_rsp *sme_disassoc_rsp;
1194 
1195 	if (QDF_STATUS_SUCCESS != suspend_status)
1196 		pe_err("Suspend Status is not success %X",
1197 			suspend_status);
1198 
1199 	mlm_disassocreq = (tLimMlmDisassocReq *) msg;
1200 
1201 	session = pe_find_session_by_session_id(mac_ctx,
1202 				mlm_disassocreq->sessionId);
1203 	if (!session) {
1204 		pe_err("session does not exist for given sessionId %d",
1205 			mlm_disassocreq->sessionId);
1206 		mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
1207 		goto end;
1208 	}
1209 
1210 	pe_debug("Process DisAssoc Req on sessionID %d Systemrole %d"
1211 		   "mlmstate %d from: " QDF_MAC_ADDR_STR,
1212 		mlm_disassocreq->sessionId, GET_LIM_SYSTEM_ROLE(session),
1213 		session->limMlmState,
1214 		QDF_MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes));
1215 
1216 	qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE);
1217 
1218 	switch (GET_LIM_SYSTEM_ROLE(session)) {
1219 	case eLIM_STA_ROLE:
1220 		if (!qdf_is_macaddr_equal(&mlm_disassocreq->peer_macaddr,
1221 				     &curr_bssid)) {
1222 			pe_warn("received MLM_DISASSOC_REQ with invalid BSS id");
1223 			lim_print_mac_addr(mac_ctx,
1224 				mlm_disassocreq->peer_macaddr.bytes, LOGW);
1225 
1226 			/*
1227 			 * Disassociation response due to host triggered
1228 			 * disassociation
1229 			 */
1230 			sme_disassoc_rsp =
1231 				qdf_mem_malloc(sizeof(*sme_disassoc_rsp));
1232 			if (!sme_disassoc_rsp) {
1233 				qdf_mem_free(mlm_disassocreq);
1234 				return;
1235 			}
1236 
1237 			pe_debug("send disassoc rsp with ret code %d for" QDF_MAC_ADDR_STR,
1238 				eSIR_SME_DEAUTH_STATUS,
1239 				QDF_MAC_ADDR_ARRAY(
1240 					mlm_disassocreq->peer_macaddr.bytes));
1241 
1242 			sme_disassoc_rsp->messageType = eWNI_SME_DISASSOC_RSP;
1243 			sme_disassoc_rsp->length = sizeof(*sme_disassoc_rsp);
1244 			sme_disassoc_rsp->sessionId =
1245 					mlm_disassocreq->sessionId;
1246 			sme_disassoc_rsp->status_code = eSIR_SME_DEAUTH_STATUS;
1247 
1248 			qdf_copy_macaddr(&sme_disassoc_rsp->peer_macaddr,
1249 					 &mlm_disassocreq->peer_macaddr);
1250 			msg = (uint32_t *)sme_disassoc_rsp;
1251 
1252 			lim_send_sme_disassoc_deauth_ntf(mac_ctx,
1253 					QDF_STATUS_SUCCESS, msg);
1254 			qdf_mem_free(mlm_disassocreq);
1255 			return;
1256 
1257 		}
1258 		break;
1259 	case eLIM_STA_IN_IBSS_ROLE:
1260 		break;
1261 	case eLIM_AP_ROLE:
1262 	case eLIM_P2P_DEVICE_GO:
1263 		if (true ==
1264 			 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
1265 			pe_err("CAC timer is running, drop disassoc from going out");
1266 			mlm_disassoccnf.resultCode = eSIR_SME_SUCCESS;
1267 			goto end;
1268 		}
1269 		break;
1270 	default:
1271 		break;
1272 	} /* end switch (GET_LIM_SYSTEM_ROLE(session)) */
1273 
1274 	/*
1275 	 * Check if there exists a context for the peer entity
1276 	 * to be disassociated with.
1277 	 */
1278 	stads = dph_lookup_hash_entry(mac_ctx,
1279 				      mlm_disassocreq->peer_macaddr.bytes,
1280 				      &aid, &session->dph.dphHashTable);
1281 	if (stads)
1282 		mlm_state = stads->mlmStaContext.mlmState;
1283 
1284 	if ((!stads) ||
1285 	    (stads &&
1286 	     ((mlm_state != eLIM_MLM_LINK_ESTABLISHED_STATE) &&
1287 	      (mlm_state != eLIM_MLM_WT_ASSOC_CNF_STATE) &&
1288 	      (mlm_state != eLIM_MLM_ASSOCIATED_STATE)))) {
1289 		/*
1290 		 * Received LIM_MLM_DISASSOC_REQ for STA that does not
1291 		 * have context or in some transit state.
1292 		 */
1293 		pe_warn("Invalid MLM_DISASSOC_REQ, Addr= " QDF_MAC_ADDR_STR,
1294 			QDF_MAC_ADDR_ARRAY(mlm_disassocreq->peer_macaddr.bytes));
1295 		if (stads)
1296 			pe_err("Sta MlmState: %d", stads->mlmStaContext.mlmState);
1297 
1298 		/* Prepare and Send LIM_MLM_DISASSOC_CNF */
1299 		mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
1300 		goto end;
1301 	}
1302 
1303 	stads->mlmStaContext.disassocReason = (tSirMacReasonCodes)
1304 					       mlm_disassocreq->reasonCode;
1305 	stads->mlmStaContext.cleanupTrigger = mlm_disassocreq->disassocTrigger;
1306 
1307 	/*
1308 	 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
1309 	 * This is to address the issue of race condition between
1310 	 * disconnect request from the HDD and deauth from AP
1311 	 */
1312 
1313 	stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
1314 
1315 	/* Send Disassociate frame to peer entity */
1316 	if (send_disassoc_frame && (mlm_disassocreq->reasonCode !=
1317 		eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
1318 		if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq) {
1319 			pe_err("pMlmDisassocReq is not NULL, freeing");
1320 			qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq.
1321 				     pMlmDisassocReq);
1322 		}
1323 		mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
1324 			mlm_disassocreq;
1325 		/*
1326 		 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
1327 		 * This is to address the issue of race condition between
1328 		 * disconnect request from the HDD and deauth from AP
1329 		 */
1330 		stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
1331 
1332 		lim_send_disassoc_mgmt_frame(mac_ctx,
1333 			mlm_disassocreq->reasonCode,
1334 			mlm_disassocreq->peer_macaddr.bytes, session, true);
1335 		/*
1336 		 * Abort Tx so that data frames won't be sent to the AP
1337 		 * after sending Disassoc.
1338 		 */
1339 		if (LIM_IS_STA_ROLE(session))
1340 			wma_tx_abort(session->smeSessionId);
1341 	} else {
1342 		/* Disassoc frame is not sent OTA */
1343 		send_disassoc_frame = 1;
1344 		/* Receive path cleanup with dummy packet */
1345 		if (QDF_STATUS_SUCCESS !=
1346 		    lim_cleanup_rx_path(mac_ctx, stads, session)) {
1347 			mlm_disassoccnf.resultCode =
1348 				eSIR_SME_RESOURCES_UNAVAILABLE;
1349 			goto end;
1350 		}
1351 		/* Free up buffer allocated for mlmDisassocReq */
1352 		qdf_mem_free(mlm_disassocreq);
1353 	}
1354 
1355 	return;
1356 
1357 end:
1358 	qdf_mem_copy((uint8_t *) &mlm_disassoccnf.peerMacAddr,
1359 		     (uint8_t *) mlm_disassocreq->peer_macaddr.bytes,
1360 		     QDF_MAC_ADDR_SIZE);
1361 	mlm_disassoccnf.aid = mlm_disassocreq->aid;
1362 	mlm_disassoccnf.disassocTrigger = mlm_disassocreq->disassocTrigger;
1363 
1364 	/* Update PE session ID */
1365 	mlm_disassoccnf.sessionId = mlm_disassocreq->sessionId;
1366 
1367 	/* Free up buffer allocated for mlmDisassocReq */
1368 	qdf_mem_free(mlm_disassocreq);
1369 
1370 	lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
1371 			     (uint32_t *) &mlm_disassoccnf);
1372 }
1373 
1374 /**
1375  * lim_check_disassoc_deauth_ack_pending() - check if deauth is pending
1376  *
1377  * @mac_ctx - global MAC context
1378  * @sta_mac - station MAC
1379  *
1380  * This function checks if diassociation or deauthentication is pending for
1381  * given station MAC address.
1382  *
1383  * Return: true if pending and false otherwise.
1384  */
1385 bool lim_check_disassoc_deauth_ack_pending(struct mac_context *mac_ctx,
1386 					   uint8_t *sta_mac)
1387 {
1388 	tLimMlmDisassocReq *disassoc_req;
1389 	tLimMlmDeauthReq *deauth_req;
1390 
1391 	disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
1392 	deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
1393 	if ((disassoc_req && (!qdf_mem_cmp((uint8_t *) sta_mac,
1394 			      (uint8_t *) &disassoc_req->peer_macaddr.bytes,
1395 			       QDF_MAC_ADDR_SIZE))) ||
1396 	    (deauth_req && (!qdf_mem_cmp((uint8_t *) sta_mac,
1397 			      (uint8_t *) &deauth_req->peer_macaddr.bytes,
1398 			       QDF_MAC_ADDR_SIZE)))) {
1399 		pe_debug("Disassoc/Deauth ack pending");
1400 		return true;
1401 	} else {
1402 		pe_debug("Disassoc/Deauth Ack not pending");
1403 		return false;
1404 	}
1405 }
1406 
1407 /*
1408  * lim_clean_up_disassoc_deauth_req() - cleans up pending disassoc or deauth req
1409  *
1410  * @mac_ctx:        mac_ctx
1411  * @sta_mac:        sta mac address
1412  * @clean_rx_path:  flag to indicate whether to cleanup rx path or not
1413  *
1414  * This function cleans up pending disassoc or deauth req
1415  *
1416  * Return: void
1417  */
1418 void lim_clean_up_disassoc_deauth_req(struct mac_context *mac_ctx,
1419 				      uint8_t *sta_mac, bool clean_rx_path)
1420 {
1421 	tLimMlmDisassocReq *mlm_disassoc_req;
1422 	tLimMlmDeauthReq *mlm_deauth_req;
1423 
1424 	mlm_disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
1425 	if (mlm_disassoc_req &&
1426 	    (!qdf_mem_cmp((uint8_t *) sta_mac,
1427 			     (uint8_t *) &mlm_disassoc_req->peer_macaddr.bytes,
1428 			     QDF_MAC_ADDR_SIZE))) {
1429 		if (clean_rx_path) {
1430 			lim_process_disassoc_ack_timeout(mac_ctx);
1431 		} else {
1432 			if (tx_timer_running(
1433 				&mac_ctx->lim.limTimers.gLimDisassocAckTimer)) {
1434 				lim_deactivate_and_change_timer(mac_ctx,
1435 						eLIM_DISASSOC_ACK_TIMER);
1436 			}
1437 			qdf_mem_free(mlm_disassoc_req);
1438 			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
1439 				NULL;
1440 		}
1441 	}
1442 
1443 	mlm_deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
1444 	if (mlm_deauth_req &&
1445 	    (!qdf_mem_cmp((uint8_t *) sta_mac,
1446 			     (uint8_t *) &mlm_deauth_req->peer_macaddr.bytes,
1447 			     QDF_MAC_ADDR_SIZE))) {
1448 		if (clean_rx_path) {
1449 			lim_process_deauth_ack_timeout(mac_ctx);
1450 		} else {
1451 			if (tx_timer_running(
1452 				&mac_ctx->lim.limTimers.gLimDeauthAckTimer)) {
1453 				lim_deactivate_and_change_timer(mac_ctx,
1454 						eLIM_DEAUTH_ACK_TIMER);
1455 			}
1456 			qdf_mem_free(mlm_deauth_req);
1457 			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq =
1458 				NULL;
1459 		}
1460 	}
1461 }
1462 
1463 /*
1464  * lim_process_disassoc_ack_timeout() - wrapper function around
1465  * lim_send_disassoc_cnf
1466  *
1467  * @mac_ctx:        mac_ctx
1468  *
1469  * wrapper function around lim_send_disassoc_cnf
1470  *
1471  * Return: void
1472  */
1473 void lim_process_disassoc_ack_timeout(struct mac_context *mac_ctx)
1474 {
1475 	lim_send_disassoc_cnf(mac_ctx);
1476 }
1477 
1478 /**
1479  * lim_process_mlm_disassoc_req() - This function is called to process
1480  * MLM_DISASSOC_REQ message from SME
1481  *
1482  * @mac_ctx:      Pointer to Global MAC structure
1483  * @msg_buf:      A pointer to the MLM message buffer
1484  *
1485  * This function is called to process MLM_DISASSOC_REQ message from SME
1486  *
1487  * @Return: None
1488  */
1489 static void
1490 lim_process_mlm_disassoc_req(struct mac_context *mac_ctx, uint32_t *msg_buf)
1491 {
1492 	tLimMlmDisassocReq *mlm_disassoc_req;
1493 
1494 	if (!msg_buf) {
1495 		pe_err("Buffer is Pointing to NULL");
1496 		return;
1497 	}
1498 
1499 	mlm_disassoc_req = (tLimMlmDisassocReq *) msg_buf;
1500 	pe_debug("Process disassoc req, sessionID %d from: "QDF_MAC_ADDR_STR,
1501 		mlm_disassoc_req->sessionId,
1502 		QDF_MAC_ADDR_ARRAY(mlm_disassoc_req->peer_macaddr.bytes));
1503 
1504 	lim_process_mlm_disassoc_req_ntf(mac_ctx, QDF_STATUS_SUCCESS,
1505 					 (uint32_t *) msg_buf);
1506 }
1507 
1508 /**
1509  * lim_process_mlm_deauth_req_ntf() - This function is process mlm deauth req
1510  * notification
1511  *
1512  * @mac_ctx:         Pointer to Global MAC structure
1513  * @suspend_status:  suspend status
1514  * @msg_buf:         A pointer to the MLM message buffer
1515  *
1516  * This function is process mlm deauth req notification
1517  *
1518  * @Return: None
1519  */
1520 static void
1521 lim_process_mlm_deauth_req_ntf(struct mac_context *mac_ctx,
1522 			       QDF_STATUS suspend_status, uint32_t *msg_buf)
1523 {
1524 	uint16_t aid;
1525 	tSirMacAddr curr_bssId;
1526 	tpDphHashNode sta_ds;
1527 	struct tLimPreAuthNode *auth_node;
1528 	tLimMlmDeauthReq *mlm_deauth_req;
1529 	tLimMlmDeauthCnf mlm_deauth_cnf;
1530 	struct pe_session *session;
1531 	struct deauth_rsp *sme_deauth_rsp;
1532 
1533 	if (QDF_STATUS_SUCCESS != suspend_status)
1534 		pe_err("Suspend Status is not success %X",
1535 			suspend_status);
1536 
1537 	mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
1538 	session = pe_find_session_by_session_id(mac_ctx,
1539 				mlm_deauth_req->sessionId);
1540 	if (!session) {
1541 		pe_err("session does not exist for given sessionId %d",
1542 			mlm_deauth_req->sessionId);
1543 		qdf_mem_free(mlm_deauth_req);
1544 		return;
1545 	}
1546 	pe_debug("Process Deauth Req on sessionID %d Systemrole %d"
1547 		       "mlmstate %d from: " QDF_MAC_ADDR_STR,
1548 		mlm_deauth_req->sessionId,
1549 		GET_LIM_SYSTEM_ROLE(session),
1550 		session->limMlmState,
1551 		QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes));
1552 	sir_copy_mac_addr(curr_bssId, session->bssId);
1553 
1554 	switch (GET_LIM_SYSTEM_ROLE(session)) {
1555 	case eLIM_STA_ROLE:
1556 		switch (session->limMlmState) {
1557 		case eLIM_MLM_IDLE_STATE:
1558 			/*
1559 			 * Attempting to Deauthenticate with a pre-authenticated
1560 			 * peer. Deauthetiate with peer if there exists a
1561 			 * pre-auth context below.
1562 			 */
1563 			break;
1564 		case eLIM_MLM_AUTHENTICATED_STATE:
1565 		case eLIM_MLM_WT_ASSOC_RSP_STATE:
1566 		case eLIM_MLM_LINK_ESTABLISHED_STATE:
1567 			if (qdf_mem_cmp(mlm_deauth_req->peer_macaddr.bytes,
1568 					curr_bssId, QDF_MAC_ADDR_SIZE)) {
1569 				pe_err("received MLM_DEAUTH_REQ with invalid BSS id "
1570 					   "Peer MAC: "QDF_MAC_ADDR_STR
1571 					   " CFG BSSID Addr : "QDF_MAC_ADDR_STR,
1572 					QDF_MAC_ADDR_ARRAY(
1573 						mlm_deauth_req->peer_macaddr.bytes),
1574 					QDF_MAC_ADDR_ARRAY(curr_bssId));
1575 				/*
1576 				 * Deauthentication response to host triggered
1577 				 * deauthentication
1578 				 */
1579 				sme_deauth_rsp =
1580 				    qdf_mem_malloc(sizeof(*sme_deauth_rsp));
1581 				if (!sme_deauth_rsp) {
1582 					qdf_mem_free(mlm_deauth_req);
1583 					return;
1584 				}
1585 
1586 				pe_debug("send deauth rsp with ret code %d for" QDF_MAC_ADDR_STR,
1587 					eSIR_SME_DEAUTH_STATUS,
1588 					QDF_MAC_ADDR_ARRAY(
1589 					  mlm_deauth_req->peer_macaddr.bytes));
1590 
1591 				sme_deauth_rsp->messageType =
1592 						eWNI_SME_DEAUTH_RSP;
1593 				sme_deauth_rsp->length =
1594 						sizeof(*sme_deauth_rsp);
1595 				sme_deauth_rsp->status_code =
1596 						eSIR_SME_DEAUTH_STATUS;
1597 				sme_deauth_rsp->sessionId =
1598 						mlm_deauth_req->sessionId;
1599 
1600 				qdf_mem_copy(sme_deauth_rsp->peer_macaddr.bytes,
1601 					     mlm_deauth_req->peer_macaddr.bytes,
1602 					     QDF_MAC_ADDR_SIZE);
1603 
1604 				msg_buf = (uint32_t *)sme_deauth_rsp;
1605 
1606 				lim_send_sme_disassoc_deauth_ntf(mac_ctx,
1607 						QDF_STATUS_SUCCESS, msg_buf);
1608 				qdf_mem_free(mlm_deauth_req);
1609 				return;
1610 			}
1611 
1612 			if ((session->limMlmState ==
1613 			     eLIM_MLM_AUTHENTICATED_STATE) ||
1614 			    (session->limMlmState ==
1615 			     eLIM_MLM_WT_ASSOC_RSP_STATE)) {
1616 				/* Send deauth frame to peer entity */
1617 				lim_send_deauth_mgmt_frame(mac_ctx,
1618 					mlm_deauth_req->reasonCode,
1619 					mlm_deauth_req->peer_macaddr.bytes,
1620 					session, false);
1621 				/* Prepare and Send LIM_MLM_DEAUTH_CNF */
1622 				mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
1623 				session->limMlmState = eLIM_MLM_IDLE_STATE;
1624 				MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
1625 						 session->peSessionId,
1626 						 session->limMlmState));
1627 				goto end;
1628 			}
1629 			break;
1630 		default:
1631 			pe_warn("received MLM_DEAUTH_REQ with in state %d for peer "
1632 				   QDF_MAC_ADDR_STR,
1633 				session->limMlmState,
1634 				QDF_MAC_ADDR_ARRAY(
1635 					mlm_deauth_req->peer_macaddr.bytes));
1636 			lim_print_mlm_state(mac_ctx, LOGW,
1637 					    session->limMlmState);
1638 			/* Prepare and Send LIM_MLM_DEAUTH_CNF */
1639 			mlm_deauth_cnf.resultCode =
1640 				eSIR_SME_STA_NOT_AUTHENTICATED;
1641 
1642 			goto end;
1643 		}
1644 		break;
1645 	case eLIM_STA_IN_IBSS_ROLE:
1646 		pe_err("received MLM_DEAUTH_REQ IBSS Mode");
1647 		mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
1648 		goto end;
1649 	case eLIM_AP_ROLE:
1650 	case eLIM_P2P_DEVICE_GO:
1651 		if (true ==
1652 			mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
1653 			pe_err("CAC timer is running, drop disassoc from going out");
1654 			mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
1655 			goto end;
1656 		}
1657 		break;
1658 
1659 	default:
1660 		break;
1661 	} /* end switch (GET_LIM_SYSTEM_ROLE(session)) */
1662 
1663 	/*
1664 	 * Check if there exists a context for the peer entity
1665 	 * to be deauthenticated with.
1666 	 */
1667 	sta_ds = dph_lookup_hash_entry(mac_ctx,
1668 				       mlm_deauth_req->peer_macaddr.bytes,
1669 				       &aid, &session->dph.dphHashTable);
1670 
1671 	if (!sta_ds) {
1672 		/* Check if there exists pre-auth context for this STA */
1673 		auth_node = lim_search_pre_auth_list(mac_ctx,
1674 					mlm_deauth_req->peer_macaddr.bytes);
1675 		if (!auth_node) {
1676 			/*
1677 			 * Received DEAUTH REQ for a STA that is neither
1678 			 * Associated nor Pre-authenticated. Log error,
1679 			 * Prepare and Send LIM_MLM_DEAUTH_CNF
1680 			 */
1681 			pe_warn("received MLM_DEAUTH_REQ in mlme state %d for STA that "
1682 				   "does not have context, Addr="
1683 				   QDF_MAC_ADDR_STR,
1684 				session->limMlmState,
1685 				QDF_MAC_ADDR_ARRAY(
1686 					mlm_deauth_req->peer_macaddr.bytes));
1687 			mlm_deauth_cnf.resultCode =
1688 				eSIR_SME_STA_NOT_AUTHENTICATED;
1689 		} else {
1690 			mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
1691 			/* Delete STA from pre-auth STA list */
1692 			lim_delete_pre_auth_node(mac_ctx,
1693 					 mlm_deauth_req->peer_macaddr.bytes);
1694 			/* Send Deauthentication frame to peer entity */
1695 			lim_send_deauth_mgmt_frame(mac_ctx,
1696 					   mlm_deauth_req->reasonCode,
1697 					   mlm_deauth_req->peer_macaddr.bytes,
1698 					   session, false);
1699 		}
1700 		goto end;
1701 	} else if ((sta_ds->mlmStaContext.mlmState !=
1702 		    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
1703 		   (sta_ds->mlmStaContext.mlmState !=
1704 		    eLIM_MLM_WT_ASSOC_CNF_STATE)) {
1705 		/*
1706 		 * received MLM_DEAUTH_REQ for STA that either has no context or
1707 		 * in some transit state
1708 		 */
1709 		pe_warn("Invalid MLM_DEAUTH_REQ, Addr="QDF_MAC_ADDR_STR,
1710 			QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes));
1711 		/* Prepare and Send LIM_MLM_DEAUTH_CNF */
1712 		mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
1713 		goto end;
1714 	}
1715 	/* sta_ds->mlmStaContext.rxPurgeReq     = 1; */
1716 	sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes)
1717 					       mlm_deauth_req->reasonCode;
1718 	sta_ds->mlmStaContext.cleanupTrigger = mlm_deauth_req->deauthTrigger;
1719 
1720 	if (mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq) {
1721 		pe_err("pMlmDeauthReq is not NULL, freeing");
1722 		qdf_mem_free(mac_ctx->lim.limDisassocDeauthCnfReq.
1723 			     pMlmDeauthReq);
1724 	}
1725 	mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = mlm_deauth_req;
1726 
1727 	/*
1728 	 * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
1729 	 * This is to address the issue of race condition between
1730 	 * disconnect request from the HDD and disassoc from
1731 	 * inactivity timer. This will make sure that we will not
1732 	 * process disassoc if deauth is in progress for the station
1733 	 * and thus mlmStaContext.cleanupTrigger will not be overwritten.
1734 	 */
1735 	sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
1736 	/* Send Deauthentication frame to peer entity */
1737 	lim_send_deauth_mgmt_frame(mac_ctx, mlm_deauth_req->reasonCode,
1738 				   mlm_deauth_req->peer_macaddr.bytes,
1739 				   session, true);
1740 	return;
1741 end:
1742 	qdf_copy_macaddr(&mlm_deauth_cnf.peer_macaddr,
1743 			 &mlm_deauth_req->peer_macaddr);
1744 	mlm_deauth_cnf.deauthTrigger = mlm_deauth_req->deauthTrigger;
1745 	mlm_deauth_cnf.aid = mlm_deauth_req->aid;
1746 	mlm_deauth_cnf.sessionId = mlm_deauth_req->sessionId;
1747 
1748 	/* Free up buffer allocated for mlmDeauthReq */
1749 	qdf_mem_free(mlm_deauth_req);
1750 	lim_post_sme_message(mac_ctx,
1751 			     LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlm_deauth_cnf);
1752 }
1753 
1754 /*
1755  * lim_process_deauth_ack_timeout() - wrapper function around
1756  * lim_send_deauth_cnf
1757  *
1758  * @mac_ctx:        mac_ctx
1759  *
1760  * wrapper function around lim_send_deauth_cnf
1761  *
1762  * Return: void
1763  */
1764 void lim_process_deauth_ack_timeout(struct mac_context *mac_ctx)
1765 {
1766 	lim_send_deauth_cnf(mac_ctx);
1767 }
1768 
1769 /*
1770  * lim_process_mlm_deauth_req() - This function is called to process
1771  * MLM_DEAUTH_REQ message from SME
1772  *
1773  * @mac_ctx:      Pointer to Global MAC structure
1774  * @msg_buf:      A pointer to the MLM message buffer
1775  *
1776  * This function is called to process MLM_DEAUTH_REQ message from SME
1777  *
1778  * @Return: None
1779  */
1780 void lim_process_mlm_deauth_req(struct mac_context *mac_ctx, uint32_t *msg_buf)
1781 {
1782 	tLimMlmDeauthReq *mlm_deauth_req;
1783 	struct pe_session *session;
1784 
1785 	if (!msg_buf) {
1786 		pe_err("Buffer is Pointing to NULL");
1787 		return;
1788 	}
1789 
1790 	mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
1791 	pe_debug("Process Deauth Req on sessionID %d from: "
1792 		   QDF_MAC_ADDR_STR,
1793 		mlm_deauth_req->sessionId,
1794 		QDF_MAC_ADDR_ARRAY(mlm_deauth_req->peer_macaddr.bytes));
1795 
1796 	session = pe_find_session_by_session_id(mac_ctx,
1797 				mlm_deauth_req->sessionId);
1798 	if (!session) {
1799 		pe_err("session does not exist for given sessionId %d",
1800 			mlm_deauth_req->sessionId);
1801 		qdf_mem_free(mlm_deauth_req);
1802 		return;
1803 	}
1804 	lim_process_mlm_deauth_req_ntf(mac_ctx, QDF_STATUS_SUCCESS,
1805 				       (uint32_t *) msg_buf);
1806 }
1807 
1808 /**
1809  * lim_process_mlm_set_keys_req() - This function is called to process
1810  * MLM_SETKEYS_REQ message from SME
1811  *
1812  * @mac_ctx:      Pointer to Global MAC structure
1813  * @msg_buf:      A pointer to the MLM message buffer
1814  *
1815  * This function is called to process MLM_SETKEYS_REQ message from SME
1816  *
1817  * @Return: None
1818  */
1819 static void
1820 lim_process_mlm_set_keys_req(struct mac_context *mac_ctx, uint32_t *msg_buf)
1821 {
1822 	uint16_t aid;
1823 	uint16_t sta_idx = 0;
1824 	uint32_t default_key_id = 0;
1825 	struct qdf_mac_addr curr_bssid;
1826 	tpDphHashNode sta_ds;
1827 	tLimMlmSetKeysReq *mlm_set_keys_req;
1828 	tLimMlmSetKeysCnf mlm_set_keys_cnf;
1829 	struct pe_session *session;
1830 
1831 	if (!msg_buf) {
1832 		pe_err("Buffer is Pointing to NULL");
1833 		return;
1834 	}
1835 
1836 	mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf;
1837 	if (mac_ctx->lim.gpLimMlmSetKeysReq) {
1838 		qdf_mem_zero(mac_ctx->lim.gpLimMlmSetKeysReq,
1839 			     sizeof(*mlm_set_keys_req));
1840 		qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
1841 		mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
1842 	}
1843 	/* Hold onto the SetKeys request parameters */
1844 	mac_ctx->lim.gpLimMlmSetKeysReq = (void *)mlm_set_keys_req;
1845 	session = pe_find_session_by_session_id(mac_ctx,
1846 				mlm_set_keys_req->sessionId);
1847 	if (!session) {
1848 		pe_err("session does not exist for given sessionId");
1849 		qdf_mem_zero(mlm_set_keys_req->key,
1850 			     sizeof(mlm_set_keys_req->key));
1851 		mlm_set_keys_req->numKeys = 0;
1852 		qdf_mem_free(mlm_set_keys_req);
1853 		mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
1854 		return;
1855 	}
1856 
1857 	pe_debug("Received MLM_SETKEYS_REQ with parameters:"
1858 		   "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - ",
1859 		mlm_set_keys_req->aid, mlm_set_keys_req->edType,
1860 		mlm_set_keys_req->numKeys);
1861 	lim_print_mac_addr(mac_ctx, mlm_set_keys_req->peer_macaddr.bytes, LOGD);
1862 	qdf_mem_copy(curr_bssid.bytes, session->bssId, QDF_MAC_ADDR_SIZE);
1863 
1864 	switch (GET_LIM_SYSTEM_ROLE(session)) {
1865 	case eLIM_STA_ROLE:
1866 		/*
1867 		 * In case of TDLS, peerMac address need not be BssId. Skip this
1868 		 * check if TDLS is enabled.
1869 		 */
1870 #ifndef FEATURE_WLAN_TDLS
1871 		if ((!qdf_is_macaddr_broadcast(
1872 				&mlm_set_keys_req->peer_macaddr)) &&
1873 		    (!qdf_is_macaddr_equal(&mlm_set_keys_req->peer_macaddr,
1874 					   &curr_bssid))) {
1875 			pe_debug("Received MLM_SETKEYS_REQ with invalid BSSID"
1876 				QDF_MAC_ADDR_STR,
1877 				QDF_MAC_ADDR_ARRAY(mlm_set_keys_req->
1878 						peer_macaddr.bytes));
1879 			/*
1880 			 * Prepare and Send LIM_MLM_SETKEYS_CNF with error code
1881 			 */
1882 			mlm_set_keys_cnf.resultCode =
1883 				eSIR_SME_INVALID_PARAMETERS;
1884 			goto end;
1885 		}
1886 #endif
1887 		break;
1888 	case eLIM_STA_IN_IBSS_ROLE:
1889 		/*
1890 		 * update the IBSS PE session encrption type based on the
1891 		 * key type
1892 		 */
1893 		session->encryptType = mlm_set_keys_req->edType;
1894 		break;
1895 	default:
1896 		break;
1897 	}
1898 
1899 	/*
1900 	 * Use the "unicast" parameter to determine if the "Group Keys"
1901 	 * are being set.
1902 	 * mlm_set_keys_req->key.unicast = 0 -> Multicast/broadcast
1903 	 * mlm_set_keys_req->key.unicast - 1 -> Unicast keys are being set
1904 	 */
1905 	if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) {
1906 		pe_debug("Trying to set Group Keys...%d",
1907 			mlm_set_keys_req->sessionId);
1908 		/*
1909 		 * When trying to set Group Keys for any security mode other
1910 		 * than WEP, use the STA Index corresponding to the AP...
1911 		 */
1912 		switch (mlm_set_keys_req->edType) {
1913 		case eSIR_ED_CCMP:
1914 		case eSIR_ED_GCMP:
1915 		case eSIR_ED_GCMP_256:
1916 #ifdef WLAN_FEATURE_11W
1917 		case eSIR_ED_AES_128_CMAC:
1918 		case eSIR_ED_AES_GMAC_128:
1919 		case eSIR_ED_AES_GMAC_256:
1920 #endif
1921 			sta_idx = session->staId;
1922 			break;
1923 		default:
1924 			break;
1925 		}
1926 	} else {
1927 		pe_debug("Trying to set Unicast Keys...");
1928 		/*
1929 		 * Check if there exists a context for the
1930 		 * peer entity for which keys need to be set.
1931 		 */
1932 		sta_ds = dph_lookup_hash_entry(mac_ctx,
1933 				mlm_set_keys_req->peer_macaddr.bytes, &aid,
1934 				&session->dph.dphHashTable);
1935 		if ((!sta_ds) ||
1936 		    ((sta_ds->mlmStaContext.mlmState !=
1937 		    eLIM_MLM_LINK_ESTABLISHED_STATE) &&
1938 		    !LIM_IS_AP_ROLE(session))) {
1939 			/*
1940 			 * Received LIM_MLM_SETKEYS_REQ for STA that does not
1941 			 * have context or in some transit state.
1942 			 */
1943 			pe_debug("Invalid MLM_SETKEYS_REQ, Addr = "
1944 				   QDF_MAC_ADDR_STR,
1945 				QDF_MAC_ADDR_ARRAY(mlm_set_keys_req->
1946 						peer_macaddr.bytes));
1947 			/* Prepare and Send LIM_MLM_SETKEYS_CNF */
1948 			mlm_set_keys_cnf.resultCode =
1949 				eSIR_SME_INVALID_PARAMETERS;
1950 			goto end;
1951 		} else {
1952 			sta_idx = sta_ds->staIndex;
1953 		}
1954 	}
1955 
1956 	if ((mlm_set_keys_req->numKeys == 0)
1957 	    && (mlm_set_keys_req->edType != eSIR_ED_NONE)) {
1958 		/*
1959 		 * Broadcast/Multicast Keys (for WEP!!) are NOT sent
1960 		 * via this interface!! This indicates to HAL that the WEP Keys
1961 		 * need to be extracted from the CFG and applied to hardware
1962 		 */
1963 		default_key_id = 0xff;
1964 	} else if (mlm_set_keys_req->key[0].keyId &&
1965 		   ((mlm_set_keys_req->edType == eSIR_ED_WEP40) ||
1966 		    (mlm_set_keys_req->edType == eSIR_ED_WEP104))) {
1967 		/*
1968 		 * If the Key Id is non zero and encryption mode is WEP,
1969 		 * the key index is coming from the upper layers so that key
1970 		 * only need to be used as the default tx key, This is being
1971 		 * used only in case of WEP mode in HAL
1972 		 */
1973 		default_key_id = mlm_set_keys_req->key[0].keyId;
1974 	} else {
1975 		default_key_id = 0;
1976 	}
1977 	pe_debug("Trying to set keys for STA Index [%d], using default_key_id [%d]",
1978 		sta_idx, default_key_id);
1979 
1980 	if (qdf_is_macaddr_broadcast(&mlm_set_keys_req->peer_macaddr)) {
1981 		session->limPrevMlmState = session->limMlmState;
1982 		session->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE;
1983 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
1984 				 session->peSessionId, session->limMlmState));
1985 		pe_debug("Trying to set Group Keys...%d",
1986 			session->peSessionId);
1987 		/* Package WMA_SET_BSSKEY_REQ message parameters */
1988 		lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session);
1989 
1990 		return;
1991 	} else {
1992 		/*
1993 		 * Package WMA_SET_STAKEY_REQ / WMA_SET_STA_BCASTKEY_REQ message
1994 		 * parameters
1995 		 */
1996 		lim_send_set_sta_key_req(mac_ctx, mlm_set_keys_req, sta_idx,
1997 					 (uint8_t) default_key_id, session,
1998 					 true);
1999 		return;
2000 	}
2001 end:
2002 	mlm_set_keys_cnf.sessionId = mlm_set_keys_req->sessionId;
2003 	lim_post_sme_set_keys_cnf(mac_ctx, mlm_set_keys_req, &mlm_set_keys_cnf);
2004 }
2005 
2006 void lim_process_join_failure_timeout(struct mac_context *mac_ctx)
2007 {
2008 	tLimMlmJoinCnf mlm_join_cnf;
2009 	uint32_t len;
2010 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2011 	host_log_rssi_pkt_type *rssi_log = NULL;
2012 #endif
2013 	struct pe_session *session;
2014 
2015 	session = pe_find_session_by_session_id(mac_ctx,
2016 			mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId);
2017 	if (!session) {
2018 		pe_err("Session Does not exist for given sessionID");
2019 		return;
2020 	}
2021 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2022 	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
2023 				host_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C);
2024 	if (rssi_log)
2025 		rssi_log->rssi = session->rssi;
2026 	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
2027 #endif
2028 
2029 	if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
2030 		len = sizeof(tSirMacAddr);
2031 		/* Change timer for future activations */
2032 		lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
2033 		/* Change Periodic probe req timer for future activation */
2034 		lim_deactivate_and_change_timer(mac_ctx,
2035 					eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
2036 		/* Issue MLM join confirm with timeout reason code */
2037 		pe_err("Join Failure Timeout, In eLIM_MLM_WT_JOIN_BEACON_STATE session:%d "
2038 			   QDF_MAC_ADDR_STR,
2039 			session->peSessionId,
2040 			QDF_MAC_ADDR_ARRAY(session->bssId));
2041 
2042 		mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE;
2043 		mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2044 		session->limMlmState = eLIM_MLM_IDLE_STATE;
2045 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
2046 				 session->peSessionId, session->limMlmState));
2047 		/* Update PE session Id */
2048 		mlm_join_cnf.sessionId = session->peSessionId;
2049 		/* Freeup buffer allocated to join request */
2050 		if (session->pLimMlmJoinReq) {
2051 			qdf_mem_free(session->pLimMlmJoinReq);
2052 			session->pLimMlmJoinReq = NULL;
2053 		}
2054 		lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
2055 				     (uint32_t *) &mlm_join_cnf);
2056 		return;
2057 	} else {
2058 		pe_warn("received unexpected JOIN failure timeout in state %X",
2059 			session->limMlmState);
2060 		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
2061 	}
2062 }
2063 
2064 /**
2065  * lim_process_periodic_join_probe_req_timer() - This function is called to
2066  * process periodic probe request send during joining process.
2067  *
2068  * @mac_ctx:      Pointer to Global MAC structure
2069  *
2070  * This function is called to process periodic probe request send during
2071  * joining process.
2072  *
2073  * @Return None
2074  */
2075 static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ctx)
2076 {
2077 	struct pe_session *session;
2078 	tSirMacSSid ssid;
2079 
2080 	session = pe_find_session_by_session_id(mac_ctx,
2081 		mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId);
2082 	if (!session) {
2083 		pe_err("session does not exist for given SessionId: %d",
2084 			mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.
2085 			sessionId);
2086 		return;
2087 	}
2088 
2089 	if ((true ==
2090 	    tx_timer_running(&mac_ctx->lim.limTimers.gLimJoinFailureTimer))
2091 		&& (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) {
2092 		qdf_mem_copy(ssid.ssId, session->ssId.ssId,
2093 			     session->ssId.length);
2094 		ssid.length = session->ssId.length;
2095 		lim_send_probe_req_mgmt_frame(mac_ctx, &ssid,
2096 			session->pLimMlmJoinReq->bssDescription.bssId,
2097 			wlan_reg_freq_to_chan(mac_ctx->pdev,
2098 					      session->curr_op_freq),
2099 			session->self_mac_addr, session->dot11mode,
2100 			&session->lim_join_req->addIEScan.length,
2101 			session->lim_join_req->addIEScan.addIEdata);
2102 		lim_deactivate_and_change_timer(mac_ctx,
2103 				eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
2104 		/* Activate Join Periodic Probe Req timer */
2105 		if (tx_timer_activate(
2106 		    &mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) !=
2107 		    TX_SUCCESS) {
2108 			pe_warn("could not activate Periodic Join req failure timer");
2109 			return;
2110 		}
2111 	}
2112 }
2113 
2114 /**
2115  * lim_process_auth_retry_timer()- function to Retry Auth
2116  * @mac_ctx:pointer to global mac
2117  *
2118  * Return: void
2119  */
2120 
2121 static void lim_process_auth_retry_timer(struct mac_context *mac_ctx)
2122 {
2123 	struct pe_session * session_entry;
2124 
2125 	session_entry =
2126 	  pe_find_session_by_session_id(mac_ctx,
2127 	  mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer.sessionId);
2128 	if (!session_entry) {
2129 		pe_err("session does not exist for given SessionId: %d",
2130 		  mac_ctx->lim.limTimers.
2131 			g_lim_periodic_auth_retry_timer.sessionId);
2132 		return;
2133 	}
2134 
2135 	if (tx_timer_running(&mac_ctx->lim.limTimers.gLimAuthFailureTimer) &&
2136 	     (session_entry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) &&
2137 	     (LIM_AUTH_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) {
2138 		tSirMacAuthFrameBody    auth_frame;
2139 
2140 		/*
2141 		 * Send the auth retry only in case we have received ack failure
2142 		 * else just restart the retry timer.
2143 		 */
2144 		if (LIM_AUTH_ACK_RCD_FAILURE == mac_ctx->auth_ack_status) {
2145 			/* Prepare & send Authentication frame */
2146 			auth_frame.authAlgoNumber =
2147 			    (uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
2148 			auth_frame.authTransactionSeqNumber =
2149 						SIR_MAC_AUTH_FRAME_1;
2150 			auth_frame.authStatusCode = 0;
2151 			pe_debug("Retry Auth");
2152 			mac_ctx->auth_ack_status = LIM_AUTH_ACK_NOT_RCD;
2153 			lim_increase_fils_sequence_number(session_entry);
2154 			lim_send_auth_mgmt_frame(mac_ctx,
2155 				&auth_frame,
2156 				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
2157 				LIM_NO_WEP_IN_FC, session_entry);
2158 		}
2159 
2160 		lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
2161 
2162 		/* Activate Auth Retry timer */
2163 		if (tx_timer_activate
2164 		     (&mac_ctx->lim.limTimers.g_lim_periodic_auth_retry_timer)
2165 			 != TX_SUCCESS) {
2166 			pe_err("could not activate Auth Retry failure timer");
2167 			return;
2168 		}
2169 	}
2170 	return;
2171 } /*** lim_process_auth_retry_timer() ***/
2172 
2173 void lim_process_auth_failure_timeout(struct mac_context *mac_ctx)
2174 {
2175 	/* fetch the pe_session based on the sessionId */
2176 	struct pe_session *session;
2177 	uint32_t val;
2178 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2179 	host_log_rssi_pkt_type *rssi_log = NULL;
2180 #endif
2181 
2182 	session = pe_find_session_by_session_id(mac_ctx,
2183 			mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId);
2184 	if (!session) {
2185 		pe_err("Session Does not exist for given sessionID");
2186 		return;
2187 	}
2188 
2189 	pe_warn("received AUTH failure timeout in sessionid %d "
2190 		   "limMlmstate %X limSmeState %X",
2191 		session->peSessionId, session->limMlmState,
2192 		session->limSmeState);
2193 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2194 	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT, session,
2195 				0, AUTH_FAILURE_TIMEOUT);
2196 
2197 	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, host_log_rssi_pkt_type,
2198 				 LOG_WLAN_RSSI_UPDATE_C);
2199 	if (rssi_log)
2200 		rssi_log->rssi = session->rssi;
2201 	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
2202 #endif
2203 
2204 	switch (session->limMlmState) {
2205 	case eLIM_MLM_WT_AUTH_FRAME2_STATE:
2206 	case eLIM_MLM_WT_AUTH_FRAME4_STATE:
2207 		/*
2208 		 * Requesting STA did not receive next auth frame before Auth
2209 		 * Failure timeout. Issue MLM auth confirm with timeout reason
2210 		 * code. Restore default failure timeout
2211 		 */
2212 		if (QDF_P2P_CLIENT_MODE == session->opmode &&
2213 		    session->defaultAuthFailureTimeout) {
2214 			if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT,
2215 					 session->defaultAuthFailureTimeout)) {
2216 				val = session->defaultAuthFailureTimeout;
2217 			} else {
2218 				val = cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
2219 				session->defaultAuthFailureTimeout = val;
2220 			}
2221 			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout = val;
2222 		}
2223 
2224 		lim_restore_from_auth_state(mac_ctx,
2225 				eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
2226 				eSIR_MAC_UNSPEC_FAILURE_REASON, session);
2227 		break;
2228 	default:
2229 		/*
2230 		 * Auth failure timer should not have timed out
2231 		 * in states other than wt_auth_frame2/4
2232 		 */
2233 		pe_err("received unexpected AUTH failure timeout in state %X",
2234 			session->limMlmState);
2235 		lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
2236 		break;
2237 	}
2238 }
2239 
2240 /**
2241  * lim_process_auth_rsp_timeout() - This function is called to process Min
2242  * Channel Timeout during channel scan.
2243  *
2244  * @mac_ctx:      Pointer to Global MAC structure
2245  *
2246  * This function is called to process Min Channel Timeout during channel scan.
2247  *
2248  * @Return: None
2249  */
2250 static void
2251 lim_process_auth_rsp_timeout(struct mac_context *mac_ctx, uint32_t auth_idx)
2252 {
2253 	struct tLimPreAuthNode *auth_node;
2254 	struct pe_session *session;
2255 	uint8_t session_id;
2256 
2257 	auth_node = lim_get_pre_auth_node_from_index(mac_ctx,
2258 				&mac_ctx->lim.gLimPreAuthTimerTable, auth_idx);
2259 	if (!auth_node) {
2260 		pe_warn("Invalid auth node");
2261 		return;
2262 	}
2263 
2264 	session = pe_find_session_by_bssid(mac_ctx, auth_node->peerMacAddr,
2265 					   &session_id);
2266 	if (!session) {
2267 		pe_warn("session does not exist for given BSSID");
2268 		return;
2269 	}
2270 
2271 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2272 		lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_TIMEOUT,
2273 				session, 0, AUTH_RESPONSE_TIMEOUT);
2274 #endif
2275 
2276 	if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) {
2277 		if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) {
2278 			pe_err("received AUTH rsp timeout in unexpected "
2279 				   "state for MAC address: " QDF_MAC_ADDR_STR,
2280 				QDF_MAC_ADDR_ARRAY(auth_node->peerMacAddr));
2281 		} else {
2282 			auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE;
2283 			auth_node->fTimerStarted = 0;
2284 			pe_debug("AUTH rsp timedout for MAC address "
2285 				   QDF_MAC_ADDR_STR,
2286 				QDF_MAC_ADDR_ARRAY(auth_node->peerMacAddr));
2287 			/* Change timer to reactivate it in future */
2288 			lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
2289 				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
2290 			lim_delete_pre_auth_node(mac_ctx,
2291 						 auth_node->peerMacAddr);
2292 		}
2293 	}
2294 }
2295 
2296 void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx,
2297 						     uint32_t msg_type)
2298 {
2299 
2300 	tLimMlmAssocCnf mlm_assoc_cnf;
2301 	struct pe_session *session;
2302 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2303 	host_log_rssi_pkt_type *rssi_log = NULL;
2304 #endif
2305 	/*
2306 	 * to fetch the lim/mlm state based on the session_id, use the
2307 	 * below pe_session
2308 	 */
2309 	uint8_t session_id;
2310 
2311 	if (msg_type == LIM_ASSOC)
2312 		session_id =
2313 		    mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId;
2314 	else
2315 		session_id =
2316 		    mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId;
2317 
2318 	session = pe_find_session_by_session_id(mac_ctx, session_id);
2319 	if (!session) {
2320 		pe_err("Session Does not exist for given sessionID");
2321 		return;
2322 	}
2323 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
2324 	lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_TIMEOUT,
2325 				session, 0, 0);
2326 
2327 	WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
2328 				 host_log_rssi_pkt_type,
2329 				 LOG_WLAN_RSSI_UPDATE_C);
2330 	if (rssi_log)
2331 		rssi_log->rssi = session->rssi;
2332 	WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
2333 #endif
2334 
2335 	pe_debug("Re/Association Response not received before timeout");
2336 
2337 	/*
2338 	 * Send Deauth to handle the scenareo where association timeout happened
2339 	 * when device has missed the assoc resp sent by peer.
2340 	 * By sending deauth try to clear the session created on peer device.
2341 	 */
2342 	pe_debug("Sessionid: %d try sending deauth on channel freq %d to BSSID: "
2343 		QDF_MAC_ADDR_STR, session->peSessionId,
2344 		session->curr_op_freq,
2345 		QDF_MAC_ADDR_ARRAY(session->bssId));
2346 	lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON,
2347 		session->bssId, session, false);
2348 
2349 	if ((LIM_IS_AP_ROLE(session)) ||
2350 	    ((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
2351 	    (session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) &&
2352 	    (session->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
2353 		/*
2354 		 * Re/Assoc failure timer should not have timedout on AP
2355 		 * or in a state other than wt_re/assoc_response.
2356 		 */
2357 		pe_warn("received unexpected REASSOC failure timeout in state %X for role %d",
2358 			session->limMlmState,
2359 			GET_LIM_SYSTEM_ROLE(session));
2360 		lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
2361 		return;
2362 	}
2363 
2364 	if ((msg_type == LIM_ASSOC) || ((msg_type == LIM_REASSOC)
2365 	     && (session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
2366 		pe_err("(Re)Assoc Failure Timeout occurred");
2367 		session->limMlmState = eLIM_MLM_IDLE_STATE;
2368 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
2369 			session->peSessionId, session->limMlmState));
2370 		/* Change timer for future activations */
2371 		lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER);
2372 		/*
2373 		 * Free up buffer allocated for JoinReq held by
2374 		 * MLM state machine
2375 		 */
2376 		if (session->pLimMlmJoinReq) {
2377 			qdf_mem_free(session->pLimMlmJoinReq);
2378 			session->pLimMlmJoinReq = NULL;
2379 		}
2380 		/* To remove the preauth node in case of fail to associate */
2381 		if (lim_search_pre_auth_list(mac_ctx, session->bssId)) {
2382 			pe_debug("delete pre auth node for "QDF_MAC_ADDR_STR,
2383 				QDF_MAC_ADDR_ARRAY(session->bssId));
2384 			lim_delete_pre_auth_node(mac_ctx,
2385 						 session->bssId);
2386 		}
2387 
2388 		mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE;
2389 		mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
2390 		/* Update PE session Id */
2391 		mlm_assoc_cnf.sessionId = session->peSessionId;
2392 		if (msg_type == LIM_ASSOC) {
2393 			lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
2394 					     (uint32_t *) &mlm_assoc_cnf);
2395 		} else {
2396 			/*
2397 			 * Will come here only in case of 11r, Ese FT
2398 			 * when reassoc rsp is not received and we
2399 			 * receive a reassoc - timesout
2400 			 */
2401 			mlm_assoc_cnf.resultCode =
2402 				eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE;
2403 			lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
2404 					     (uint32_t *) &mlm_assoc_cnf);
2405 		}
2406 	} else {
2407 		/*
2408 		 * Restore pre-reassoc req state.
2409 		 * Set BSSID to currently associated AP address.
2410 		 */
2411 		session->limMlmState = session->limPrevMlmState;
2412 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
2413 				 session->peSessionId, session->limMlmState));
2414 		lim_restore_pre_reassoc_state(mac_ctx,
2415 				eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE,
2416 				eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
2417 	}
2418 }
2419 
2420 /**
2421  * lim_set_channel() - set channel api for lim
2422  *
2423  * @mac_ctx:                Pointer to Global MAC structure
2424  * @channel:                power save state
2425  * @ch_center_freq_seg0:    center freq seq 0
2426  * @ch_center_freq_seg1:    center freq seq 1
2427  * @ch_width:               channel width
2428  * @max_tx_power:           max tx power
2429  * @pe_session_id:          pe session id
2430  *
2431  * set channel api for lim
2432  *
2433  * @Return: None
2434  */
2435 void lim_set_channel(struct mac_context *mac_ctx, uint8_t channel,
2436 		     uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1,
2437 		     enum phy_ch_width ch_width, int8_t max_tx_power,
2438 		     uint8_t pe_session_id, uint32_t cac_duration_ms,
2439 		     uint32_t dfs_regdomain)
2440 {
2441 	struct pe_session *pe_session;
2442 
2443 	pe_session = pe_find_session_by_session_id(mac_ctx, pe_session_id);
2444 
2445 	if (!pe_session) {
2446 		pe_err("Invalid PE session: %d", pe_session_id);
2447 		return;
2448 	}
2449 	lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0,
2450 				    ch_center_freq_seg1, ch_width,
2451 				    max_tx_power, pe_session_id, false,
2452 				    cac_duration_ms, dfs_regdomain);
2453 }
2454