1 /*
2  * Copyright (c) 2011-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 /*
21  * This file lim ProcessMessageQueue.cc contains the code
22  * for processing LIM message Queue.
23  * Author:        Chandra Modumudi
24  * Date:          02/11/02
25  * History:-
26  * Date           Modified by    Modification Information
27  * --------------------------------------------------------------------
28  *
29  */
30 #include "cds_api.h"
31 #include "wni_api.h"
32 #include "wma_types.h"
33 
34 #include "wni_cfg.h"
35 #include "sir_common.h"
36 #include "utils_api.h"
37 #include "lim_types.h"
38 #include "lim_utils.h"
39 #include "lim_assoc_utils.h"
40 #include "lim_prop_exts_utils.h"
41 
42 #include "lim_admit_control.h"
43 #include "sch_api.h"
44 #include "lim_ft_defs.h"
45 #include "lim_session.h"
46 #include "lim_send_messages.h"
47 
48 #include "rrm_api.h"
49 
50 #include "lim_ft.h"
51 
52 #include "qdf_types.h"
53 #include "cds_packet.h"
54 #include "qdf_mem.h"
55 #include "wlan_policy_mgr_api.h"
56 #include "nan_datapath.h"
57 #include "wlan_reg_services_api.h"
58 #include "lim_security_utils.h"
59 #include "cds_ieee80211_common.h"
60 #include <wlan_scan_ucfg_api.h>
61 #include "wlan_mlme_public_struct.h"
62 #include "wma.h"
63 #include "wma_internal.h"
64 #include "../../core/src/vdev_mgr_ops.h"
65 #include "wlan_p2p_cfg_api.h"
66 
67 void lim_log_session_states(struct mac_context *mac);
68 static void lim_process_normal_hdd_msg(struct mac_context *mac_ctx,
69 	struct scheduler_msg *msg, uint8_t rsp_reqd);
70 
71 #ifdef WLAN_FEATURE_SAE
72 
73 /**
74  * lim_process_sae_msg_sta() - Process SAE message for STA
75  * @mac: Global MAC pointer
76  * @session: Pointer to the PE session entry
77  * @sae_msg: SAE message buffer pointer
78  *
79  * Return: None
80  */
lim_process_sae_msg_sta(struct mac_context * mac,struct pe_session * session,struct sir_sae_msg * sae_msg)81 static void lim_process_sae_msg_sta(struct mac_context *mac,
82 				    struct pe_session *session,
83 				    struct sir_sae_msg *sae_msg)
84 {
85 	struct wlan_crypto_pmksa *pmksa;
86 	uint8_t *rsn_ie_buf;
87 
88 	switch (session->limMlmState) {
89 	case eLIM_MLM_WT_SAE_AUTH_STATE:
90 		/* SAE authentication is completed.
91 		 * Restore from auth state
92 		 */
93 		if (tx_timer_running(&mac->lim.lim_timers.sae_auth_timer))
94 			lim_deactivate_and_change_timer(mac,
95 							eLIM_AUTH_SAE_TIMER);
96 		lim_sae_auth_cleanup_retry(mac, session->vdev_id);
97 		/* success */
98 		if (sae_msg->sae_status == STATUS_SUCCESS) {
99 			uint8_t zero_pmkid[PMKID_LEN] = {0};
100 
101 			if (!qdf_mem_cmp(sae_msg->pmkid, zero_pmkid,
102 					 PMKID_LEN)) {
103 				pe_debug("pmkid not received in ext auth");
104 				goto restore_auth_state;
105 			}
106 
107 			pmksa = qdf_mem_malloc(sizeof(*pmksa));
108 			if (!pmksa)
109 				goto restore_auth_state;
110 
111 			rsn_ie_buf = qdf_mem_malloc(WLAN_MAX_IE_LEN + 2);
112 			if (!rsn_ie_buf) {
113 				qdf_mem_free(pmksa);
114 				goto restore_auth_state;
115 			}
116 
117 			qdf_mem_copy(pmksa->pmkid, sae_msg->pmkid, PMKID_LEN);
118 			qdf_mem_copy(pmksa->bssid.bytes, sae_msg->peer_mac_addr,
119 				     QDF_MAC_ADDR_SIZE);
120 
121 			qdf_mem_zero(session->lim_join_req->rsnIE.rsnIEdata,
122 				     WLAN_MAX_IE_LEN + 2);
123 			lim_update_connect_rsn_ie(session, rsn_ie_buf, pmksa);
124 
125 			qdf_mem_free(pmksa);
126 			qdf_mem_free(rsn_ie_buf);
127 restore_auth_state:
128 			lim_restore_from_auth_state(mac,
129 						    eSIR_SME_SUCCESS,
130 						    STATUS_SUCCESS,
131 						    session);
132 		} else {
133 			lim_restore_from_auth_state(mac, sae_msg->result_code,
134 						    sae_msg->sae_status,
135 						    session);
136 		}
137 		break;
138 	default:
139 		/* SAE msg is received in unexpected state */
140 		pe_err("received SAE msg in state %X", session->limMlmState);
141 		lim_print_mlm_state(mac, LOGE, session->limMlmState);
142 		break;
143 	}
144 }
145 
146 /**
147  * lim_process_sae_msg_ap() - Process SAE message
148  * @mac: Global MAC pointer
149  * @session: Pointer to the PE session entry
150  * @sae_msg: SAE message buffer pointer
151  *
152  * Return: None
153  */
lim_process_sae_msg_ap(struct mac_context * mac,struct pe_session * session,struct sir_sae_msg * sae_msg)154 static void lim_process_sae_msg_ap(struct mac_context *mac,
155 				   struct pe_session *session,
156 				   struct sir_sae_msg *sae_msg)
157 {
158 	struct tLimPreAuthNode *sta_pre_auth_ctx;
159 	struct lim_assoc_data *assoc_req;
160 	bool assoc_ind_sent;
161 
162 	/* Extract pre-auth context for the STA and move limMlmState
163 	 * of preauth node to eLIM_MLM_AUTHENTICATED_STATE
164 	 */
165 	sta_pre_auth_ctx = lim_search_pre_auth_list(mac,
166 						    sae_msg->peer_mac_addr);
167 
168 	if (!sta_pre_auth_ctx) {
169 		pe_debug("No preauth node created for "
170 			 QDF_MAC_ADDR_FMT,
171 			 QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr));
172 		return;
173 	}
174 
175 	assoc_req = &sta_pre_auth_ctx->assoc_req;
176 
177 	if (sae_msg->sae_status != STATUS_SUCCESS) {
178 		pe_debug("SAE authentication failed for "
179 			 QDF_MAC_ADDR_FMT " status: %u",
180 			 QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr),
181 			 sae_msg->sae_status);
182 		if (assoc_req->present) {
183 			pe_debug("Assoc req cached; clean it up");
184 			lim_process_assoc_cleanup(mac, session,
185 						  assoc_req->assoc_req,
186 						  assoc_req->sta_ds,
187 						  assoc_req->assoc_req_copied);
188 			assoc_req->present = false;
189 		}
190 		lim_delete_pre_auth_node(mac, sae_msg->peer_mac_addr);
191 		return;
192 	}
193 	sta_pre_auth_ctx->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
194 	/* Send assoc indication to SME if any assoc request is cached*/
195 	if (assoc_req->present) {
196 		/* Assoc request is present in preauth context. Get the assoc
197 		 * request and make it invalid in preauth context. It'll be
198 		 * freed later in the legacy path.
199 		 */
200 		bool assoc_req_copied;
201 
202 		assoc_req->present = false;
203 		pe_debug("Assoc req cached; handle it");
204 		assoc_ind_sent =
205 			lim_send_assoc_ind_to_sme(mac, session,
206 						  assoc_req->sub_type,
207 						  assoc_req->sa,
208 						  assoc_req->assoc_req,
209 						  ANI_AKM_TYPE_SAE,
210 						  assoc_req->pmf_connection,
211 						  &assoc_req_copied,
212 						  assoc_req->dup_entry, false,
213 						  assoc_req->partner_peer_idx);
214 		if (!assoc_ind_sent)
215 			lim_process_assoc_cleanup(mac, session,
216 						  assoc_req->assoc_req,
217 						  assoc_req->sta_ds,
218 						  assoc_req_copied);
219 	}
220 }
221 
222 /**
223  * lim_process_sae_msg() - Process SAE message
224  * @mac: Global MAC pointer
225  * @body: Buffer pointer
226  *
227  * Return: None
228  */
lim_process_sae_msg(struct mac_context * mac,struct sir_sae_msg * body)229 void lim_process_sae_msg(struct mac_context *mac, struct sir_sae_msg *body)
230 {
231 	struct sir_sae_msg *sae_msg = body;
232 	struct pe_session *session;
233 
234 	if (!sae_msg) {
235 		pe_err("SAE msg is NULL");
236 		return;
237 	}
238 
239 	session = pe_find_session_by_vdev_id(mac, sae_msg->vdev_id);
240 	if (!session) {
241 		pe_err("SAE:Unable to find session");
242 		return;
243 	}
244 
245 	if (session->opmode != QDF_STA_MODE &&
246 	    session->opmode != QDF_SAP_MODE &&
247 	    session->opmode != QDF_P2P_GO_MODE &&
248 	    session->opmode != QDF_P2P_CLIENT_MODE) {
249 		pe_err("SAE:Not supported in this mode %d",
250 				session->opmode);
251 		return;
252 	}
253 
254 	pe_debug("SAE:status %d limMlmState %d opmode %d peer: "
255 		 QDF_MAC_ADDR_FMT, sae_msg->sae_status,
256 		 session->limMlmState, session->opmode,
257 		 QDF_MAC_ADDR_REF(sae_msg->peer_mac_addr));
258 	if (LIM_IS_STA_ROLE(session))
259 		lim_process_sae_msg_sta(mac, session, sae_msg);
260 	else if (LIM_IS_AP_ROLE(session))
261 		lim_process_sae_msg_ap(mac, session, sae_msg);
262 	else
263 		pe_debug("SAE message on unsupported interface");
264 }
265 #endif
266 
267 /**
268  * lim_process_dual_mac_cfg_resp() - Process set dual mac config response
269  * @mac: Global MAC pointer
270  * @body: Set dual mac config response in sir_dual_mac_config_resp format
271  *
272  * Process the set dual mac config response and post the message
273  * to SME to process this further and release the active
274  * command list
275  *
276  * Return: None
277  */
lim_process_dual_mac_cfg_resp(struct mac_context * mac,void * body)278 static void lim_process_dual_mac_cfg_resp(struct mac_context *mac, void *body)
279 {
280 	struct sir_dual_mac_config_resp *resp, *param;
281 	uint32_t len, fail_resp = 0;
282 	struct scheduler_msg msg = {0};
283 
284 	resp = (struct sir_dual_mac_config_resp *)body;
285 	if (!resp) {
286 		pe_err("Set dual mac cfg param is NULL");
287 		fail_resp = 1;
288 		/* Not returning here. If possible, let us proceed
289 		 * and send fail response to SME
290 		 */
291 	}
292 
293 	len = sizeof(*param);
294 
295 	param = qdf_mem_malloc(len);
296 	if (!param)
297 		return;
298 
299 	if (fail_resp) {
300 		pe_err("Send fail status to SME");
301 		param->status = SET_HW_MODE_STATUS_ECANCELED;
302 	} else {
303 		param->status = resp->status;
304 		/*
305 		 * TODO: Update this HW mode info in any UMAC params, if needed
306 		 */
307 	}
308 
309 	msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
310 	msg.bodyptr = param;
311 	msg.bodyval = 0;
312 	pe_debug("Send eWNI_SME_SET_DUAL_MAC_CFG_RESP to SME");
313 	lim_sys_process_mmh_msg_api(mac, &msg);
314 	return;
315 }
316 
317 /**
318  * lim_process_set_hw_mode_resp() - Process set HW mode response
319  * @mac: Global MAC pointer
320  * @body: Set HW mode response in sir_set_hw_mode_resp format
321  *
322  * Process the set HW mode response and post the message
323  * to SME to process this further and release the active
324  * command list
325  *
326  * Return: None
327  */
lim_process_set_hw_mode_resp(struct mac_context * mac,void * body)328 static void lim_process_set_hw_mode_resp(struct mac_context *mac, void *body)
329 {
330 	struct sir_set_hw_mode_resp *resp, *param;
331 	uint32_t len, i, fail_resp = 0;
332 	struct scheduler_msg msg = {0};
333 
334 	resp = (struct sir_set_hw_mode_resp *)body;
335 	if (!resp) {
336 		pe_err("Set HW mode param is NULL");
337 		fail_resp = 1;
338 		/* Not returning here. If possible, let us proceed
339 		 * and send fail response to SME */
340 	}
341 
342 	len = sizeof(*param);
343 
344 	param = qdf_mem_malloc(len);
345 	if (!param)
346 		return;
347 
348 	if (fail_resp) {
349 		pe_err("Send fail status to SME");
350 		param->status = SET_HW_MODE_STATUS_ECANCELED;
351 		param->cfgd_hw_mode_index = 0;
352 		param->num_vdev_mac_entries = 0;
353 	} else {
354 		param->status = resp->status;
355 		param->cfgd_hw_mode_index = resp->cfgd_hw_mode_index;
356 		param->num_vdev_mac_entries = resp->num_vdev_mac_entries;
357 
358 		for (i = 0; i < resp->num_vdev_mac_entries; i++) {
359 			param->vdev_mac_map[i].vdev_id =
360 				resp->vdev_mac_map[i].vdev_id;
361 			param->vdev_mac_map[i].mac_id =
362 				resp->vdev_mac_map[i].mac_id;
363 		}
364 		/*
365 		 * TODO: Update this HW mode info in any UMAC params, if needed
366 		 */
367 	}
368 
369 	msg.type = eWNI_SME_SET_HW_MODE_RESP;
370 	msg.bodyptr = param;
371 	msg.bodyval = 0;
372 	pe_debug("Send eWNI_SME_SET_HW_MODE_RESP to SME");
373 	lim_sys_process_mmh_msg_api(mac, &msg);
374 	return;
375 }
376 
377 /**
378  * lim_process_antenna_mode_resp() - Process set antenna mode
379  * response
380  * @mac: Global MAC pointer
381  * @body: Set antenna mode response in sir_antenna_mode_resp
382  * format
383  *
384  * Process the set antenna mode response and post the message
385  * to SME to process this further and release the active
386  * command list
387  *
388  * Return: None
389  */
lim_process_set_antenna_resp(struct mac_context * mac,void * body)390 static void lim_process_set_antenna_resp(struct mac_context *mac, void *body)
391 {
392 	struct sir_antenna_mode_resp *resp, *param;
393 	bool fail_resp = false;
394 	struct scheduler_msg msg = {0};
395 
396 	resp = (struct sir_antenna_mode_resp *)body;
397 	if (!resp) {
398 		pe_err("Set antenna mode resp is NULL");
399 		fail_resp = true;
400 		/* Not returning here. If possible, let us proceed
401 		 * and send fail response to SME
402 		 */
403 	}
404 
405 	param = qdf_mem_malloc(sizeof(*param));
406 	if (!param)
407 		return;
408 
409 	if (fail_resp) {
410 		pe_err("Send fail status to SME");
411 		param->status = SET_ANTENNA_MODE_STATUS_ECANCELED;
412 	} else {
413 		param->status = resp->status;
414 	}
415 
416 	msg.type = eWNI_SME_SET_ANTENNA_MODE_RESP;
417 	msg.bodyptr = param;
418 	msg.bodyval = 0;
419 	pe_debug("Send eWNI_SME_SET_ANTENNA_MODE_RESP to SME");
420 	lim_sys_process_mmh_msg_api(mac, &msg);
421 	return;
422 }
423 
424 /**
425  * lim_process_set_default_scan_ie_request() - Process the Set default
426  * Scan IE request from HDD.
427  * @mac_ctx: Pointer to Global MAC structure
428  * @msg_buf: Pointer to incoming data
429  *
430  * This function receives the default scan IEs and updates the ext cap IE
431  * (if present) with FTM capabilities and pass the Scan IEs to WMA.
432  *
433  * Return: None
434  */
lim_process_set_default_scan_ie_request(struct mac_context * mac_ctx,uint32_t * msg_buf)435 static void lim_process_set_default_scan_ie_request(struct mac_context *mac_ctx,
436 							uint32_t *msg_buf)
437 {
438 	struct hdd_default_scan_ie *set_ie_params;
439 	struct vdev_ie_info *wma_ie_params;
440 	uint8_t *local_ie_buf;
441 	uint16_t local_ie_len;
442 	struct scheduler_msg msg_q = {0};
443 	QDF_STATUS ret_code;
444 	struct pe_session *pe_session;
445 
446 	if (!msg_buf) {
447 		pe_err("msg_buf is NULL");
448 		return;
449 	}
450 
451 	set_ie_params = (struct hdd_default_scan_ie *) msg_buf;
452 	local_ie_len = set_ie_params->ie_len;
453 
454 	local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN);
455 	if (!local_ie_buf)
456 		return;
457 
458 	pe_session = pe_find_session_by_vdev_id(mac_ctx,
459 						set_ie_params->vdev_id);
460 	if (lim_update_ext_cap_ie(mac_ctx,
461 			(uint8_t *)set_ie_params->ie_data,
462 			local_ie_buf, &local_ie_len, pe_session)) {
463 		pe_err("Update ext cap IEs fails");
464 		goto scan_ie_send_fail;
465 	}
466 
467 	wma_ie_params = qdf_mem_malloc(sizeof(*wma_ie_params) + local_ie_len);
468 	if (!wma_ie_params)
469 		goto scan_ie_send_fail;
470 
471 	wma_ie_params->vdev_id = set_ie_params->vdev_id;
472 	wma_ie_params->ie_id = DEFAULT_SCAN_IE_ID;
473 	wma_ie_params->length = local_ie_len;
474 	wma_ie_params->data = (uint8_t *)(wma_ie_params)
475 					+ sizeof(*wma_ie_params);
476 	qdf_mem_copy(wma_ie_params->data, local_ie_buf, local_ie_len);
477 
478 	msg_q.type = WMA_SET_IE_INFO;
479 	msg_q.bodyptr = wma_ie_params;
480 	msg_q.bodyval = 0;
481 	ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
482 	if (QDF_STATUS_SUCCESS != ret_code) {
483 		pe_err("fail to send WMA_SET_IE_INFO");
484 		qdf_mem_free(wma_ie_params);
485 	}
486 scan_ie_send_fail:
487 	qdf_mem_free(local_ie_buf);
488 }
489 
490 /**
491  * def_msg_decision() - Should a message be deferred?
492  * @mac_ctx: The global MAC context
493  * @lim_msg: The message to check for potential deferral
494  *
495  * This function decides whether to defer a message or not in
496  * lim_message_processor() function
497  *
498  * Return: true if the message can be deferred, false otherwise
499  */
def_msg_decision(struct mac_context * mac_ctx,struct scheduler_msg * lim_msg)500 static bool def_msg_decision(struct mac_context *mac_ctx,
501 			     struct scheduler_msg *lim_msg)
502 {
503 	uint8_t type, subtype;
504 	QDF_STATUS status;
505 	bool mgmt_pkt_defer = true;
506 
507 	/* this function should not changed */
508 	if (mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) {
509 		/* Defer processing this message */
510 		if (lim_defer_msg(mac_ctx, lim_msg) != TX_SUCCESS) {
511 			pe_err_rl("Unable to Defer Msg in offline state");
512 			lim_log_session_states(mac_ctx);
513 			lim_handle_defer_msg_error(mac_ctx, lim_msg);
514 		}
515 
516 		return true;
517 	}
518 
519 	/*
520 	 * When defer is requested then defer all the messages except
521 	 * HAL responses.
522 	 */
523 	if (!GET_LIM_PROCESS_DEFD_MESGS(mac_ctx)) {
524 		if (lim_msg->type == SIR_BB_XPORT_MGMT_MSG) {
525 			/*
526 			 * Dont defer beacon and probe response
527 			 * because it will fill the differ queue quickly
528 			 */
529 			status = lim_util_get_type_subtype(lim_msg->bodyptr,
530 							   &type, &subtype);
531 			if (QDF_IS_STATUS_SUCCESS(status) &&
532 				(type == SIR_MAC_MGMT_FRAME) &&
533 				((subtype == SIR_MAC_MGMT_BEACON) ||
534 				 (subtype == SIR_MAC_MGMT_PROBE_RSP)))
535 				mgmt_pkt_defer = false;
536 		}
537 
538 		if ((lim_msg->type != WMA_DELETE_BSS_RSP) &&
539 		    (lim_msg->type != WMA_DELETE_BSS_HO_FAIL_RSP) &&
540 		    (lim_msg->type != WMA_ADD_STA_RSP) &&
541 		    (lim_msg->type != WMA_DELETE_STA_RSP) &&
542 		    (lim_msg->type != WMA_SET_BSSKEY_RSP) &&
543 		    (lim_msg->type != WMA_SET_STAKEY_RSP) &&
544 		    (lim_msg->type != WMA_SET_STA_BCASTKEY_RSP) &&
545 		    (lim_msg->type != WMA_AGGR_QOS_RSP) &&
546 		    (lim_msg->type != WMA_SET_MIMOPS_RSP) &&
547 		    (lim_msg->type != WMA_SWITCH_CHANNEL_RSP) &&
548 		    (lim_msg->type != WMA_P2P_NOA_ATTR_IND) &&
549 		    (lim_msg->type != WMA_ADD_TS_RSP) &&
550 		    /*
551 		     * LIM won't process any defer queue commands if gLimAddtsSent is
552 		     * set to TRUE. gLimAddtsSent will be set TRUE to while sending
553 		     * ADDTS REQ. Say, when deferring is enabled, if
554 		     * SIR_LIM_ADDTS_RSP_TIMEOUT is posted (because of not receiving ADDTS
555 		     * RSP) then this command will be added to defer queue and as
556 		     * gLimAddtsSent is set TRUE LIM will never process any commands from
557 		     * defer queue, including SIR_LIM_ADDTS_RSP_TIMEOUT. Hence allowing
558 		     * SIR_LIM_ADDTS_RSP_TIMEOUT command to be processed with deferring
559 		     * enabled, so that this will be processed immediately and sets
560 		     * gLimAddtsSent to FALSE.
561 		     */
562 		    (lim_msg->type != SIR_LIM_ADDTS_RSP_TIMEOUT) &&
563 		    /* Allow processing of RX frames while awaiting reception
564 		     * of ADD TS response over the air. This logic particularly
565 		     * handles the case when host sends ADD BA request to FW
566 		     * after ADD TS request is sent over the air and
567 		     * ADD TS response received over the air */
568 		    !(lim_msg->type == SIR_BB_XPORT_MGMT_MSG &&
569 		    mac_ctx->lim.gLimAddtsSent) &&
570 		    (mgmt_pkt_defer)) {
571 			pe_debug("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode",
572 				 lim_msg_str(lim_msg->type));
573 			/* Defer processing this message */
574 			if (lim_defer_msg(mac_ctx, lim_msg) != TX_SUCCESS) {
575 				pe_err_rl("Unable to Defer Msg");
576 				lim_log_session_states(mac_ctx);
577 				lim_handle_defer_msg_error(mac_ctx, lim_msg);
578 			}
579 			return true;
580 		}
581 	}
582 	return false;
583 }
584 
585 #ifdef FEATURE_WLAN_EXTSCAN
586 static void
__lim_pno_match_fwd_bcn_probepsp(struct mac_context * pmac,uint8_t * rx_pkt_info,tSirProbeRespBeacon * frame,uint32_t ie_len,uint32_t msg_type)587 __lim_pno_match_fwd_bcn_probepsp(struct mac_context *pmac, uint8_t *rx_pkt_info,
588 				tSirProbeRespBeacon *frame, uint32_t ie_len,
589 				uint32_t msg_type)
590 {
591 	struct pno_match_found  *result;
592 	uint8_t                 *body;
593 	struct scheduler_msg    mmh_msg = {0};
594 	tpSirMacMgmtHdr         hdr;
595 	uint32_t num_results = 1, len, i;
596 
597 	/* Upon receiving every matched beacon, bss info is forwarded to the
598 	 * the upper layer, hence num_results is set to 1 */
599 	len = sizeof(*result) + (num_results * sizeof(tSirWifiScanResult)) +
600 		ie_len;
601 
602 	result = qdf_mem_malloc(len);
603 	if (!result)
604 		return;
605 
606 	hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
607 	body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
608 
609 	/* Received frame does not have request id, hence set 0 */
610 	result->request_id = 0;
611 	result->more_data = 0;
612 	result->num_results = num_results;
613 
614 	for (i = 0; i < result->num_results; i++) {
615 		result->ap[i].ts = qdf_mc_timer_get_system_time();
616 		result->ap[i].beaconPeriod = frame->beaconInterval;
617 		result->ap[i].capability =
618 			lim_get_u16((uint8_t *) &frame->capabilityInfo);
619 		result->ap[i].channel = wlan_reg_freq_to_chan(
620 						pmac->pdev,
621 						WMA_GET_RX_FREQ(rx_pkt_info));
622 		result->ap[i].rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
623 		result->ap[i].rtt = 0;
624 		result->ap[i].rtt_sd = 0;
625 		result->ap[i].ieLength = ie_len;
626 		qdf_mem_copy((uint8_t *) &result->ap[i].ssid[0],
627 			(uint8_t *) frame->ssId.ssId, frame->ssId.length);
628 		result->ap[i].ssid[frame->ssId.length] = '\0';
629 		qdf_mem_copy((uint8_t *) &result->ap[i].bssid,
630 				(uint8_t *) hdr->bssId,
631 				sizeof(tSirMacAddr));
632 		/* Copy IE fields */
633 		qdf_mem_copy((uint8_t *) &result->ap[i].ieData,
634 				body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
635 	}
636 
637 	mmh_msg.type = msg_type;
638 	mmh_msg.bodyptr = result;
639 	mmh_msg.bodyval = 0;
640 	lim_sys_process_mmh_msg_api(pmac, &mmh_msg);
641 }
642 
643 
644 static void
__lim_ext_scan_forward_bcn_probe_rsp(struct mac_context * pmac,uint8_t * rx_pkt_info,tSirProbeRespBeacon * frame,uint32_t ie_len,uint32_t msg_type)645 __lim_ext_scan_forward_bcn_probe_rsp(struct mac_context *pmac, uint8_t *rx_pkt_info,
646 					tSirProbeRespBeacon *frame,
647 					uint32_t ie_len,
648 					uint32_t msg_type)
649 {
650 	tpSirWifiFullScanResultEvent result;
651 	uint8_t                     *body;
652 	struct scheduler_msg         mmh_msg = {0};
653 	tpSirMacMgmtHdr              hdr;
654 	uint32_t frame_len;
655 	struct bss_description *bssdescr;
656 
657 	result = qdf_mem_malloc(sizeof(*result) + ie_len);
658 	if (!result)
659 		return;
660 
661 	hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
662 	body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
663 
664 	/* Received frame does not have request id, hence set 0 */
665 	result->requestId = 0;
666 
667 	result->moreData = 0;
668 	result->ap.ts = qdf_mc_timer_get_system_time();
669 	result->ap.beaconPeriod = frame->beaconInterval;
670 	result->ap.capability =
671 			lim_get_u16((uint8_t *) &frame->capabilityInfo);
672 	result->ap.channel = wlan_reg_freq_to_chan(
673 						pmac->pdev,
674 						WMA_GET_RX_FREQ(rx_pkt_info));
675 	result->ap.rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
676 	result->ap.rtt = 0;
677 	result->ap.rtt_sd = 0;
678 	result->ap.ieLength = ie_len;
679 
680 	qdf_mem_copy((uint8_t *) &result->ap.ssid[0],
681 			(uint8_t *) frame->ssId.ssId, frame->ssId.length);
682 	result->ap.ssid[frame->ssId.length] = '\0';
683 	qdf_mem_copy((uint8_t *) &result->ap.bssid.bytes,
684 			(uint8_t *) hdr->bssId,
685 			QDF_MAC_ADDR_SIZE);
686 	/* Copy IE fields */
687 	qdf_mem_copy((uint8_t *) &result->ap.ieData,
688 			body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
689 
690 	frame_len = sizeof(*bssdescr) + ie_len - sizeof(bssdescr->ieFields[1]);
691 	bssdescr = qdf_mem_malloc(frame_len);
692 	if (!bssdescr) {
693 		qdf_mem_free(result);
694 		return;
695 	}
696 
697 	qdf_mem_zero(bssdescr, frame_len);
698 
699 	lim_collect_bss_description(pmac, bssdescr, frame, rx_pkt_info, false);
700 
701 	qdf_mem_free(bssdescr);
702 
703 	mmh_msg.type = msg_type;
704 	mmh_msg.bodyptr = result;
705 	mmh_msg.bodyval = 0;
706 	lim_sys_process_mmh_msg_api(pmac, &mmh_msg);
707 }
708 
709 static void
__lim_process_ext_scan_beacon_probe_rsp(struct mac_context * pmac,uint8_t * rx_pkt_info,uint8_t sub_type)710 __lim_process_ext_scan_beacon_probe_rsp(struct mac_context *pmac,
711 					uint8_t *rx_pkt_info,
712 					uint8_t sub_type)
713 {
714 	tSirProbeRespBeacon  *frame;
715 	uint8_t              *body;
716 	uint32_t             frm_len;
717 	QDF_STATUS        status;
718 
719 	frm_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
720 	if (frm_len <= SIR_MAC_B_PR_SSID_OFFSET) {
721 		pe_err("RX packet has invalid length %d", frm_len);
722 		return;
723 	}
724 
725 	frame = qdf_mem_malloc(sizeof(*frame));
726 	if (!frame)
727 		return;
728 
729 	if (sub_type == SIR_MAC_MGMT_BEACON) {
730 		pe_debug("Beacon due to ExtScan/epno");
731 		status = sir_convert_beacon_frame2_struct(pmac,
732 						(uint8_t *)rx_pkt_info,
733 						frame);
734 	} else if (sub_type == SIR_MAC_MGMT_PROBE_RSP) {
735 		pe_debug("Probe Rsp due to ExtScan/epno");
736 		body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
737 		status = sir_convert_probe_frame2_struct(pmac, body,
738 							frm_len, frame);
739 	} else {
740 		qdf_mem_free(frame);
741 		return;
742 	}
743 
744 	if (status != QDF_STATUS_SUCCESS) {
745 		pe_err("Frame parsing failed");
746 		qdf_mem_free(frame);
747 		return;
748 	}
749 
750 	if (WMA_IS_EXTSCAN_SCAN_SRC(rx_pkt_info))
751 		__lim_ext_scan_forward_bcn_probe_rsp(pmac, rx_pkt_info, frame,
752 					(frm_len - SIR_MAC_B_PR_SSID_OFFSET),
753 					eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND);
754 
755 	if (WMA_IS_EPNO_SCAN_SRC(rx_pkt_info))
756 		__lim_pno_match_fwd_bcn_probepsp(pmac, rx_pkt_info, frame,
757 					(frm_len - SIR_MAC_B_PR_SSID_OFFSET),
758 					eWNI_SME_EPNO_NETWORK_FOUND_IND);
759 
760 	qdf_mem_free(frame);
761 }
762 #endif
763 
764 /*
765  * Beacon Handling Cases:
766  * during scanning, when no session is active:
767  *    handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
768  * during scanning, when any session is active, but beacon/Pr does not belong to that session, pe_session will be null.
769  *    handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
770  * during scanning, when any session is active, and beacon/Pr belongs to one of the session, pe_session will not be null.
771  *    handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
772  * Not scanning, no session:
773  *    there should not be any beacon coming, if coming, should be dropped.
774  * Not Scanning,
775  */
776 static void
__lim_handle_beacon(struct mac_context * mac,struct scheduler_msg * pMsg,struct pe_session * pe_session)777 __lim_handle_beacon(struct mac_context *mac, struct scheduler_msg *pMsg,
778 		    struct pe_session *pe_session)
779 {
780 	uint8_t *pRxPacketInfo;
781 
782 	lim_get_b_dfrom_rx_packet(mac, pMsg->bodyptr,
783 				  (uint32_t **) &pRxPacketInfo);
784 
785 	/* This function should not be called if beacon is received in scan state. */
786 	/* So not doing any checks for the global state. */
787 
788 	if (!pe_session) {
789 		sch_beacon_process(mac, pRxPacketInfo, NULL);
790 	} else if ((pe_session->limSmeState == eLIM_SME_LINK_EST_STATE) ||
791 		   (pe_session->limSmeState == eLIM_SME_NORMAL_STATE)) {
792 		sch_beacon_process(mac, pRxPacketInfo, pe_session);
793 	} else
794 		lim_process_beacon_frame(mac, pRxPacketInfo, pe_session);
795 
796 	return;
797 }
798 
799 /*
800  * lim_fill_sap_bcn_pkt_meta(): Fills essential fields in Rx Pkt Meta
801  * @scan_entry: pointer to the scan cache entry of the beacon
802  * @rx_pkt: pointer to the cds pkt allocated
803  *
804  * This API fills only the essential parameters in the Rx Pkt Meta which are
805  * required while converting the beacon frame to struct and while handling
806  * the beacon for implementation of SAP protection mechanisms.
807  *
808  * Return: None
809  */
lim_fill_sap_bcn_pkt_meta(struct scan_cache_entry * scan_entry,cds_pkt_t * rx_pkt)810 static void lim_fill_sap_bcn_pkt_meta(struct scan_cache_entry *scan_entry,
811 					cds_pkt_t *rx_pkt)
812 {
813 	rx_pkt->pkt_meta.frequency = scan_entry->channel.chan_freq;
814 	rx_pkt->pkt_meta.mpdu_hdr_len = sizeof(struct ieee80211_frame);
815 	rx_pkt->pkt_meta.mpdu_len = scan_entry->raw_frame.len;
816 	rx_pkt->pkt_meta.mpdu_data_len = rx_pkt->pkt_meta.mpdu_len -
817 					rx_pkt->pkt_meta.mpdu_hdr_len;
818 
819 	rx_pkt->pkt_meta.mpdu_hdr_ptr = scan_entry->raw_frame.ptr;
820 	rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
821 					rx_pkt->pkt_meta.mpdu_hdr_len;
822 
823 	/*
824 	 * The scan_entry->raw_frame contains the qdf_nbuf->data from the SKB
825 	 * of the beacon. We set the rx_pkt->pkt_meta.mpdu_hdr_ptr to point
826 	 * to this memory directly. However we do not have the pointer to
827 	 * the SKB itself here which is usually is pointed by rx_pkt->pkt_buf.
828 	 * Also, we always get the pkt data using WMA_GET_RX_MPDU_DATA and
829 	 * dont actually use the pkt_buf. So setting this to NULL.
830 	 */
831 	rx_pkt->pkt_buf = NULL;
832 }
833 
834 /*
835  * lim_allocate_and_get_bcn() - Allocate and get the bcn frame pkt and structure
836  * @mac_ctx: pointer to global mac_ctx
837  * @pkt: pointer to the pkt to be allocated
838  * @rx_pkt_info: pointer to the allocated pkt meta
839  * @bcn: pointer to the beacon struct
840  * @scan_entry: pointer to the scan cache entry from scan module
841  *
842  * Allocates a cds_pkt for beacon frame in scan cache entry,
843  * fills the essential pkt_meta elements and converts the
844  * pkt to beacon strcut.
845  *
846  * Return: QDF_STATUS
847  */
lim_allocate_and_get_bcn(struct mac_context * mac_ctx,cds_pkt_t ** pkt,uint8_t ** rx_pkt_info,tSchBeaconStruct ** bcn,struct scan_cache_entry * scan_entry)848 static QDF_STATUS lim_allocate_and_get_bcn(
849 				struct mac_context *mac_ctx,
850 				cds_pkt_t **pkt,
851 				uint8_t **rx_pkt_info,
852 				tSchBeaconStruct **bcn,
853 				struct scan_cache_entry *scan_entry)
854 {
855 	QDF_STATUS status;
856 	uint8_t *rx_pkt_info_l = NULL;
857 	tSchBeaconStruct *bcn_l = NULL;
858 	cds_pkt_t *pkt_l = NULL;
859 
860 	pkt_l = qdf_mem_malloc_atomic(sizeof(cds_pkt_t));
861 	if (!pkt_l)
862 		return QDF_STATUS_E_FAILURE;
863 
864 	status = wma_ds_peek_rx_packet_info(pkt_l, (void *)&rx_pkt_info_l);
865 	if (!QDF_IS_STATUS_SUCCESS(status)) {
866 		pe_err("Failed to get Rx Pkt meta");
867 		goto free;
868 	}
869 
870 	bcn_l = qdf_mem_malloc_atomic(sizeof(tSchBeaconStruct));
871 	if (!bcn_l)
872 		goto free;
873 
874 	lim_fill_sap_bcn_pkt_meta(scan_entry, pkt_l);
875 
876 	/* Convert the beacon frame into a structure */
877 	if (sir_convert_beacon_frame2_struct(mac_ctx,
878 	    (uint8_t *)rx_pkt_info_l,
879 	    bcn_l) != QDF_STATUS_SUCCESS) {
880 		pe_err("beacon parsing failed");
881 		goto free;
882 	}
883 
884 	*pkt = pkt_l;
885 	*bcn = bcn_l;
886 	*rx_pkt_info = rx_pkt_info_l;
887 
888 	return QDF_STATUS_SUCCESS;
889 
890 free:
891 	if (pkt_l) {
892 		qdf_mem_free(pkt_l);
893 		pkt_l = NULL;
894 	}
895 
896 	if (bcn_l) {
897 		qdf_mem_free(bcn_l);
898 		bcn_l = NULL;
899 	}
900 
901 	return QDF_STATUS_E_FAILURE;
902 }
903 
lim_handle_sap_beacon(struct wlan_objmgr_pdev * pdev,struct scan_cache_entry * scan_entry)904 void lim_handle_sap_beacon(struct wlan_objmgr_pdev *pdev,
905 				struct scan_cache_entry *scan_entry)
906 {
907 	struct mac_context *mac_ctx;
908 	cds_pkt_t *pkt = NULL;
909 	tSchBeaconStruct *bcn = NULL;
910 	struct mgmt_beacon_probe_filter *filter;
911 	QDF_STATUS status;
912 	uint8_t *rx_pkt_info = NULL;
913 	int session_id;
914 
915 	if (!scan_entry) {
916 		pe_err("scan_entry is NULL");
917 		return;
918 	}
919 
920 	if (scan_entry->frm_subtype != MGMT_SUBTYPE_BEACON)
921 		return;
922 
923 	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
924 	if (!mac_ctx)
925 		return;
926 
927 	filter = &mac_ctx->bcn_filter;
928 
929 	if (!filter->num_sap_sessions) {
930 		return;
931 	}
932 	for (session_id = 0; session_id < mac_ctx->lim.maxBssId; session_id++) {
933 		if (filter->sap_channel[session_id] &&
934 		    (filter->sap_channel[session_id] ==
935 		    wlan_reg_freq_to_chan(pdev,
936 					  scan_entry->channel.chan_freq))) {
937 			if (!pkt) {
938 				status = lim_allocate_and_get_bcn(
939 					mac_ctx, &pkt, &rx_pkt_info,
940 					&bcn, scan_entry);
941 				if (!QDF_IS_STATUS_SUCCESS(status)) {
942 					pe_debug("lim_allocate_and_get_bcn fail!");
943 					return;
944 				}
945 			}
946 			sch_beacon_process_for_ap(mac_ctx, session_id,
947 						  rx_pkt_info, bcn);
948 		}
949 	}
950 
951 	/*
952 	 * Free only the pkt memory we allocated and not the pkt->pkt_buf.
953 	 * The actual SKB buffer is freed in the scan module from where
954 	 * this API is invoked via callback
955 	 */
956 	if (bcn)
957 		qdf_mem_free(bcn);
958 	if (pkt)
959 		qdf_mem_free(pkt);
960 }
961 
962 /**
963  * lim_defer_msg()
964  *
965  ***FUNCTION:
966  * This function is called to defer the messages received
967  * during Learn mode
968  *
969  ***LOGIC:
970  * NA
971  *
972  ***ASSUMPTIONS:
973  * NA
974  *
975  ***NOTE:
976  * NA
977  *
978  * @param  mac - Pointer to Global MAC structure
979  * @param  pMsg of type struct scheduler_msg - Pointer to the message structure
980  * @return None
981  */
982 
lim_defer_msg(struct mac_context * mac,struct scheduler_msg * pMsg)983 uint32_t lim_defer_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
984 {
985 	uint32_t retCode = TX_SUCCESS;
986 
987 	retCode = lim_write_deferred_msg_q(mac, pMsg);
988 
989 	if (retCode == TX_SUCCESS) {
990 		MTRACE(mac_trace_msg_rx
991 			(mac, NO_SESSION,
992 			LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED)));
993 	} else {
994 		pe_err_rl("Dropped lim message (0x%X) Message %s", pMsg->type,
995 			  lim_msg_str(pMsg->type));
996 		MTRACE(mac_trace_msg_rx
997 			(mac, NO_SESSION,
998 			LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED)));
999 	}
1000 
1001 	return retCode;
1002 } /*** end lim_defer_msg() ***/
1003 
1004 /**
1005  * lim_handle_unknown_a2_index_frames() - This function handles Unknown Unicast
1006  *                                        (A2 Index) packets
1007  * @mac_ctx:          Pointer to the Global Mac Context.
1008  * @rx_pkt_buffer:    Pointer to the packet Buffer descriptor.
1009  * @session_entry:    Pointer to the PE Session Entry.
1010  *
1011  * This routine will handle public action frames.
1012  *
1013  * Return:      None.
1014  */
lim_handle_unknown_a2_index_frames(struct mac_context * mac_ctx,void * rx_pkt_buffer,struct pe_session * session_entry)1015 static void lim_handle_unknown_a2_index_frames(struct mac_context *mac_ctx,
1016 	void *rx_pkt_buffer, struct pe_session *session_entry)
1017 {
1018 #ifdef FEATURE_WLAN_TDLS
1019 	tpSirMacDataHdr3a mac_hdr;
1020 #endif
1021 	if (LIM_IS_P2P_DEVICE_ROLE(session_entry))
1022 		lim_process_action_frame_no_session(mac_ctx,
1023 			(uint8_t *) rx_pkt_buffer);
1024 #ifdef FEATURE_WLAN_TDLS
1025 	mac_hdr = WMA_GET_RX_MPDUHEADER3A(rx_pkt_buffer);
1026 
1027 	if (IEEE80211_IS_MULTICAST(mac_hdr->addr2)) {
1028 		pe_debug("Ignoring A2 Invalid Packet received for MC/BC: "
1029 			 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_hdr->addr2));
1030 		return;
1031 	}
1032 	pe_debug("type=0x%x, subtype=0x%x",
1033 		 mac_hdr->fc.type, mac_hdr->fc.subType);
1034 	/* Currently only following type and subtype are handled.
1035 	 * If there are more combinations, then add switch-case
1036 	 * statements.
1037 	 */
1038 	if (LIM_IS_STA_ROLE(session_entry) &&
1039 		(mac_hdr->fc.type == SIR_MAC_MGMT_FRAME) &&
1040 		(mac_hdr->fc.subType == SIR_MAC_MGMT_ACTION))
1041 		lim_process_action_frame(mac_ctx, rx_pkt_buffer, session_entry);
1042 #endif
1043 	return;
1044 }
1045 
1046 static bool
lim_is_ignore_btm_frame(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,tSirMacFrameCtl fc,uint8_t * body,uint16_t frm_len)1047 lim_is_ignore_btm_frame(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
1048 			tSirMacFrameCtl fc, uint8_t *body, uint16_t frm_len)
1049 {
1050 	bool is_sta_roam_disabled_by_p2p, is_mbo_wo_pmf, is_disable_btm;
1051 	uint8_t action_id, category, token = 0;
1052 	tpSirMacActionFrameHdr action_hdr;
1053 	enum wlan_diag_btm_block_reason reason;
1054 	struct cm_roam_values_copy temp;
1055 
1056 	/*
1057 	 * Drop BTM frame, if BTM roam disabled by userspace via vendor
1058 	 * command QCA_WLAN_VENDOR_ATTR_CONFIG_BTM_SUPPORT
1059 	 */
1060 	wlan_cm_roam_cfg_get_value(psoc, vdev_id, IS_DISABLE_BTM, &temp);
1061 	is_disable_btm = temp.bool_value;
1062 	if (is_disable_btm) {
1063 		pe_debug("Drop BTM frame. vdev:%d BTM roam disabled by user",
1064 			 vdev_id);
1065 		return true;
1066 	}
1067 
1068 	/*
1069 	 * When DUT associated to BTM disabled AP and receives BTM req frame
1070 	 * from connected AP then instead of forwarding the BTM req frame to
1071 	 * supplicant, host should drop it
1072 	 */
1073 	if (!wlan_cm_get_assoc_btm_cap(psoc, vdev_id)) {
1074 		pe_debug("Drop BTM frame. vdev:%d BTM not supported by AP",
1075 			 vdev_id);
1076 		return true;
1077 	}
1078 
1079 	/*
1080 	 * Drop BTM frame received on STA interface if concurrent
1081 	 * P2P connection is active and p2p_disable_roam ini is
1082 	 * enabled. This will help to avoid scan triggered by
1083 	 * userspace after processing the BTM frame from AP so the
1084 	 * audio glitches are not seen in P2P connection.
1085 	 */
1086 	is_sta_roam_disabled_by_p2p = cfg_p2p_is_roam_config_disabled(psoc) &&
1087 		(policy_mgr_mode_specific_connection_count(psoc,
1088 							   PM_P2P_CLIENT_MODE,
1089 							   NULL) ||
1090 		 policy_mgr_mode_specific_connection_count(psoc,
1091 							   PM_P2P_GO_MODE,
1092 							   NULL));
1093 
1094 	is_mbo_wo_pmf = wlan_cm_is_mbo_ap_without_pmf(psoc, vdev_id);
1095 	if (!is_sta_roam_disabled_by_p2p && !is_mbo_wo_pmf)
1096 		return false;
1097 
1098 	action_hdr = (tpSirMacActionFrameHdr)body;
1099 
1100 	if (frm_len < sizeof(*action_hdr) || !action_hdr ||
1101 	    fc.type != SIR_MAC_MGMT_FRAME || fc.subType != SIR_MAC_MGMT_ACTION)
1102 		return false;
1103 
1104 	action_id = action_hdr->actionID;
1105 	category = action_hdr->category;
1106 	if (category == ACTION_CATEGORY_WNM &&
1107 	    (action_id == WNM_BSS_TM_QUERY ||
1108 	     action_id == WNM_BSS_TM_REQUEST ||
1109 	     action_id == WNM_BSS_TM_RESPONSE)) {
1110 		if (frm_len >= sizeof(*action_hdr) + 1)
1111 			token = *(body + sizeof(*action_hdr));
1112 		if (is_mbo_wo_pmf) {
1113 			pe_debug("Drop the BTM frame as it's received from MBO AP without PMF, vdev %d",
1114 				 vdev_id);
1115 			reason = WLAN_DIAG_BTM_BLOCK_MBO_WO_PMF;
1116 		} else {
1117 			pe_debug("Drop the BTM frame as p2p session is active, vdev %d",
1118 				 vdev_id);
1119 			reason = WLAN_DIAG_BTM_BLOCK_UNSUPPORTED_P2P_CONC;
1120 		}
1121 		wlan_cm_roam_btm_block_event(vdev_id, token, reason);
1122 		return true;
1123 	}
1124 
1125 	return false;
1126 }
1127 
1128 /**
1129  * lim_check_mgmt_registered_frames() - This function handles registered
1130  *                                      management frames.
1131  *
1132  * @mac_ctx:          Pointer to the Global Mac Context.
1133  * @buff_desc:        Pointer to the packet Buffer descriptor.
1134  * @session_entry:    Pointer to the PE Session Entry.
1135  *
1136  * This function is called to process to check if received frame match with
1137  * any of the registered frame from HDD. If yes pass this frame to SME.
1138  *
1139  * Return:      True or False for Match or Mismatch respectively.
1140  */
1141 static bool
lim_check_mgmt_registered_frames(struct mac_context * mac_ctx,uint8_t * buff_desc,struct pe_session * session_entry)1142 lim_check_mgmt_registered_frames(struct mac_context *mac_ctx, uint8_t *buff_desc,
1143 				 struct pe_session *session_entry)
1144 {
1145 	tSirMacFrameCtl fc;
1146 	tpSirMacMgmtHdr hdr;
1147 	uint8_t *body;
1148 	struct mgmt_frm_reg_info *mgmt_frame = NULL;
1149 	struct mgmt_frm_reg_info *next_frm = NULL;
1150 	uint16_t frm_type;
1151 	uint16_t frm_len;
1152 	uint8_t type, sub_type;
1153 	bool match = false;
1154 	uint8_t vdev_id = WLAN_INVALID_VDEV_ID;
1155 	QDF_STATUS qdf_status;
1156 
1157 	hdr = WMA_GET_RX_MAC_HEADER(buff_desc);
1158 	fc = hdr->fc;
1159 	frm_type = (fc.type << 2) | (fc.subType << 4);
1160 	body = WMA_GET_RX_MPDU_DATA(buff_desc);
1161 	frm_len = WMA_GET_RX_PAYLOAD_LEN(buff_desc);
1162 
1163 	qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
1164 	qdf_list_peek_front(&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
1165 			    (qdf_list_node_t **) &mgmt_frame);
1166 	qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
1167 
1168 	while (mgmt_frame) {
1169 		type = (mgmt_frame->frameType >> 2) & 0x03;
1170 		sub_type = (mgmt_frame->frameType >> 4) & 0x0f;
1171 		if ((type == SIR_MAC_MGMT_FRAME)
1172 		    && (fc.type == SIR_MAC_MGMT_FRAME)
1173 		    && (sub_type == SIR_MAC_MGMT_RESERVED15)) {
1174 			pe_debug("rcvd frm match for SIR_MAC_MGMT_RESERVED15");
1175 			match = true;
1176 			break;
1177 		}
1178 		if (mgmt_frame->frameType == frm_type) {
1179 			if (mgmt_frame->matchLen <= 0) {
1180 				match = true;
1181 				break;
1182 			}
1183 			if (mgmt_frame->matchLen <= frm_len &&
1184 				(!qdf_mem_cmp(mgmt_frame->matchData, body,
1185 				mgmt_frame->matchLen))) {
1186 				/* found match! */
1187 				match = true;
1188 				break;
1189 			}
1190 		}
1191 
1192 		qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
1193 		qdf_status =
1194 			qdf_list_peek_next(
1195 			&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
1196 			(qdf_list_node_t *) mgmt_frame,
1197 			(qdf_list_node_t **) &next_frm);
1198 		qdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
1199 		mgmt_frame = next_frm;
1200 		next_frm = NULL;
1201 	}
1202 	if (match) {
1203 		pe_debug("rcvd frame match with registered frame params");
1204 
1205 		if (session_entry && LIM_IS_STA_ROLE(session_entry) &&
1206 		    lim_is_ignore_btm_frame(mac_ctx->psoc,
1207 					    session_entry->vdev_id, fc, body,
1208 					    frm_len))
1209 			return match;
1210 
1211 		/*
1212 		 * Some frames like GAS_INITIAL_REQ are registered with
1213 		 * SME_SESSION_ID_ANY, and received without session.
1214 		 */
1215 		vdev_id = mgmt_frame->sessionId;
1216 		if (session_entry)
1217 			vdev_id = session_entry->vdev_id;
1218 
1219 		/* Indicate this to SME */
1220 		lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
1221 			(uint8_t *) hdr,
1222 			WMA_GET_RX_PAYLOAD_LEN(buff_desc) +
1223 			sizeof(tSirMacMgmtHdr), vdev_id,
1224 			WMA_GET_RX_FREQ(buff_desc),
1225 			WMA_GET_RX_RSSI_NORMALIZED(buff_desc),
1226 			RXMGMT_FLAG_NONE);
1227 
1228 		if ((type == SIR_MAC_MGMT_FRAME)
1229 		    && (fc.type == SIR_MAC_MGMT_FRAME)
1230 		    && (sub_type == SIR_MAC_MGMT_RESERVED15))
1231 			/* These packets needs to be processed by PE/SME
1232 			 * as well as HDD.If it returns true here,
1233 			 * the packet is forwarded to HDD only.
1234 			 */
1235 			match = false;
1236 	}
1237 
1238 	return match;
1239 }
1240 
1241 #ifdef FEATURE_WLAN_DIAG_SUPPORT
1242 /**
1243  * lim_is_mgmt_frame_loggable() - to log non-excessive mgmt frames
1244  * @type: type of frames i.e. mgmt, control, data
1245  * @subtype: subtype of frames i.e. beacon, probe rsp, probe req and etc
1246  *
1247  * This API tells if given mgmt frame is expected to come excessive in
1248  * amount or not.
1249  *
1250  * Return: true if mgmt is expected to come not that often, so makes it
1251  *         loggable. false if mgmt is expected to come too often, so makes
1252  *         it not loggable
1253  */
1254 static bool
lim_is_mgmt_frame_loggable(uint8_t type,uint8_t subtype)1255 lim_is_mgmt_frame_loggable(uint8_t type, uint8_t subtype)
1256 {
1257 	if (type != SIR_MAC_MGMT_FRAME)
1258 		return false;
1259 
1260 	switch (subtype) {
1261 	case SIR_MAC_MGMT_BEACON:
1262 	case SIR_MAC_MGMT_PROBE_REQ:
1263 	case SIR_MAC_MGMT_PROBE_RSP:
1264 		return false;
1265 	default:
1266 		return true;
1267 	}
1268 }
1269 #else
1270 static bool
lim_is_mgmt_frame_loggable(uint8_t type,uint8_t subtype)1271 lim_is_mgmt_frame_loggable(uint8_t type, uint8_t subtype)
1272 {
1273 	return false;
1274 }
1275 #endif
1276 
1277 /**
1278  * lim_handle80211_frames()
1279  *
1280  ***FUNCTION:
1281  * This function is called to process 802.11 frames
1282  * received by LIM.
1283  *
1284  ***LOGIC:
1285  * NA
1286  *
1287  ***ASSUMPTIONS:
1288  * NA
1289  *
1290  ***NOTE:
1291  * NA
1292  *
1293  * @param  mac - Pointer to Global MAC structure
1294  * @param  pMsg of type struct scheduler_msg - Pointer to the message structure
1295  * @return None
1296  */
1297 
1298 static void
lim_handle80211_frames(struct mac_context * mac,struct scheduler_msg * limMsg,uint8_t * pDeferMsg)1299 lim_handle80211_frames(struct mac_context *mac, struct scheduler_msg *limMsg,
1300 		       uint8_t *pDeferMsg)
1301 {
1302 	uint8_t *pRxPacketInfo = NULL;
1303 	tSirMacFrameCtl fc;
1304 	tpSirMacMgmtHdr pHdr = NULL;
1305 	struct pe_session *pe_session = NULL;
1306 	uint8_t sessionId;
1307 	bool isFrmFt = false;
1308 	uint32_t frequency;
1309 	bool is_hw_sbs_capable = false;
1310 
1311 	*pDeferMsg = false;
1312 	lim_get_b_dfrom_rx_packet(mac, limMsg->bodyptr,
1313 				  (uint32_t **) &pRxPacketInfo);
1314 
1315 	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
1316 	isFrmFt = WMA_GET_RX_FT_DONE(pRxPacketInfo);
1317 	frequency = WMA_GET_RX_FREQ(pRxPacketInfo);
1318 	fc = pHdr->fc;
1319 
1320 	is_hw_sbs_capable =
1321 		policy_mgr_is_hw_sbs_capable(mac->psoc);
1322 	if (WLAN_REG_IS_5GHZ_CH_FREQ(frequency) &&
1323 	    (!is_hw_sbs_capable ||
1324 	    (is_hw_sbs_capable &&
1325 	    wlan_reg_is_dfs_for_freq(mac->pdev, frequency))) &&
1326 	    mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
1327 		pe_session = pe_find_session_by_bssid(mac,
1328 					pHdr->bssId, &sessionId);
1329 		if (pe_session &&
1330 		    (QDF_SAP_MODE == pe_session->opmode)) {
1331 			pe_debug("CAC timer running - drop the frame");
1332 			goto end;
1333 		}
1334 	}
1335 
1336 #ifdef WLAN_DUMP_MGMTFRAMES
1337 	pe_debug("ProtVersion %d, Type %d, Subtype %d rateIndex=%d",
1338 		fc.protVer, fc.type, fc.subType,
1339 		WMA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
1340 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, pHdr,
1341 			   WMA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo));
1342 #endif
1343 	if (fc.type == SIR_MAC_MGMT_FRAME) {
1344 		if ((mac->mlme_cfg->gen.debug_packet_log &
1345 		    DEBUG_PKTLOG_TYPE_MGMT) &&
1346 		    (fc.subType != SIR_MAC_MGMT_PROBE_REQ) &&
1347 		    (fc.subType != SIR_MAC_MGMT_PROBE_RSP) &&
1348 		    (fc.subType != SIR_MAC_MGMT_BEACON) &&
1349 		    (fc.subType != SIR_MAC_MGMT_ACTION))
1350 			mgmt_txrx_frame_hex_dump((uint8_t *)pHdr,
1351 					 WMA_GET_RX_MPDU_LEN(pRxPacketInfo),
1352 					 false);
1353 	}
1354 
1355 #ifdef FEATURE_WLAN_EXTSCAN
1356 	if (WMA_IS_EXTSCAN_SCAN_SRC(pRxPacketInfo) ||
1357 		WMA_IS_EPNO_SCAN_SRC(pRxPacketInfo)) {
1358 		if (fc.subType == SIR_MAC_MGMT_BEACON ||
1359 		    fc.subType == SIR_MAC_MGMT_PROBE_RSP) {
1360 			__lim_process_ext_scan_beacon_probe_rsp(mac,
1361 								pRxPacketInfo,
1362 								fc.subType);
1363 		} else {
1364 			pe_err("Wrong frameType %d, Subtype %d for %d",
1365 				fc.type, fc.subType,
1366 				WMA_GET_SCAN_SRC(pRxPacketInfo));
1367 		}
1368 		goto end;
1369 	}
1370 #endif
1371 	/* Added For BT-AMP Support */
1372 	pe_session = pe_find_session_by_bssid(mac, pHdr->bssId,
1373 						 &sessionId);
1374 	if (!pe_session) {
1375 		if (fc.subType == SIR_MAC_MGMT_AUTH) {
1376 			pe_debug("ProtVersion %d, Type %d, Subtype %d rateIndex=%d bssid=" QDF_MAC_ADDR_FMT,
1377 				 fc.protVer, fc.type, fc.subType,
1378 				 WMA_GET_RX_MAC_RATE_IDX(pRxPacketInfo),
1379 				 QDF_MAC_ADDR_REF(pHdr->bssId));
1380 			if (lim_process_auth_frame_no_session
1381 				    (mac, pRxPacketInfo,
1382 				    limMsg->bodyptr) == QDF_STATUS_SUCCESS) {
1383 				goto end;
1384 			}
1385 		}
1386 		/* Public action frame can be received from non-assoc stations*/
1387 		if ((fc.subType != SIR_MAC_MGMT_PROBE_RSP) &&
1388 		    (fc.subType != SIR_MAC_MGMT_BEACON) &&
1389 		    (fc.subType != SIR_MAC_MGMT_PROBE_REQ)
1390 		    && (fc.subType != SIR_MAC_MGMT_ACTION)) {
1391 
1392 			pe_session = pe_find_session_by_peer_sta(mac,
1393 						pHdr->sa, &sessionId);
1394 			if (!pe_session) {
1395 				pe_debug("session does not exist for bssId: "QDF_MAC_ADDR_FMT,
1396 					 QDF_MAC_ADDR_REF(pHdr->sa));
1397 				goto end;
1398 			} else {
1399 				pe_debug("SessionId:%d exists for given Bssid",
1400 					pe_session->peSessionId);
1401 			}
1402 		}
1403 		/*  For p2p resp frames search for valid session with DA as */
1404 		/*  BSSID will be SA and session will be present with DA only */
1405 		if (fc.subType == SIR_MAC_MGMT_ACTION) {
1406 			pe_session =
1407 				pe_find_session_by_bssid(mac, pHdr->da, &sessionId);
1408 		}
1409 	}
1410 
1411 	/* Check if frame is registered by HDD */
1412 	if (lim_check_mgmt_registered_frames(mac, pRxPacketInfo, pe_session))
1413 		goto end;
1414 
1415 	if (fc.protVer != SIR_MAC_PROTOCOL_VERSION) {   /* Received Frame with non-zero Protocol Version */
1416 		pe_err("Unexpected frame with protVersion %d received",
1417 			fc.protVer);
1418 		lim_pkt_free(mac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
1419 			     (void *)limMsg->bodyptr);
1420 		goto end;
1421 	}
1422 
1423 	switch (fc.type) {
1424 	case SIR_MAC_MGMT_FRAME:
1425 	{
1426 		/* Received Management frame */
1427 		switch (fc.subType) {
1428 		case SIR_MAC_MGMT_ASSOC_REQ:
1429 			/* Make sure the role supports Association */
1430 			if (LIM_IS_AP_ROLE(pe_session))
1431 				lim_process_assoc_req_frame(mac,
1432 							    pRxPacketInfo,
1433 							    LIM_ASSOC,
1434 							    pe_session);
1435 			else {
1436 				pe_err("unexpected message received %X",
1437 					limMsg->type);
1438 				lim_print_msg_name(mac, LOGE,
1439 						   limMsg->type);
1440 			}
1441 			break;
1442 
1443 		case SIR_MAC_MGMT_ASSOC_RSP:
1444 			lim_process_assoc_rsp_frame(mac, pRxPacketInfo,
1445 						    WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo),
1446 						    LIM_ASSOC,
1447 						    pe_session);
1448 			break;
1449 
1450 		case SIR_MAC_MGMT_REASSOC_REQ:
1451 			/* Make sure the role supports Reassociation */
1452 			if (LIM_IS_AP_ROLE(pe_session)) {
1453 				lim_process_assoc_req_frame(mac,
1454 							    pRxPacketInfo,
1455 							    LIM_REASSOC,
1456 							    pe_session);
1457 			} else {
1458 				pe_err("unexpected message received %X",
1459 					limMsg->type);
1460 				lim_print_msg_name(mac, LOGE,
1461 					limMsg->type);
1462 			}
1463 			break;
1464 
1465 		case SIR_MAC_MGMT_REASSOC_RSP:
1466 			lim_process_assoc_rsp_frame(mac, pRxPacketInfo,
1467 						    WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo),
1468 						    LIM_REASSOC,
1469 						    pe_session);
1470 			break;
1471 
1472 		case SIR_MAC_MGMT_PROBE_REQ:
1473 			lim_process_probe_req_frame_multiple_bss(mac,
1474 								 pRxPacketInfo,
1475 								 pe_session);
1476 			break;
1477 
1478 		case SIR_MAC_MGMT_PROBE_RSP:
1479 			if (pe_session)
1480 				lim_process_probe_rsp_frame(mac,
1481 							    pRxPacketInfo,
1482 							    pe_session);
1483 			break;
1484 
1485 		case SIR_MAC_MGMT_BEACON:
1486 			__lim_handle_beacon(mac, limMsg, pe_session);
1487 			break;
1488 
1489 		case SIR_MAC_MGMT_DISASSOC:
1490 			lim_process_disassoc_frame(mac, pRxPacketInfo,
1491 						   pe_session);
1492 			break;
1493 
1494 		case SIR_MAC_MGMT_AUTH:
1495 			lim_process_auth_frame(mac, pRxPacketInfo,
1496 					       pe_session);
1497 			break;
1498 
1499 		case SIR_MAC_MGMT_DEAUTH:
1500 			lim_process_deauth_frame(mac, pRxPacketInfo,
1501 						 pe_session);
1502 			break;
1503 
1504 		case SIR_MAC_MGMT_ACTION:
1505 			if (!pe_session)
1506 				lim_process_action_frame_no_session(mac,
1507 								    pRxPacketInfo);
1508 			else {
1509 				if (mac->mlme_cfg->gen.debug_packet_log &
1510 				    DEBUG_PKTLOG_TYPE_ACTION) {
1511 					pe_debug("RX MGMT - Type %hu, SubType %hu, seq num[%d]",
1512 						 fc.type, fc.subType,
1513 						 ((pHdr->seqControl.seqNumHi << HIGH_SEQ_NUM_OFFSET) |
1514 						 pHdr->seqControl.seqNumLo));
1515 					QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE,
1516 							   QDF_TRACE_LEVEL_DEBUG,
1517 							   pHdr,
1518 							   WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)
1519 							   + SIR_MAC_HDR_LEN_3A);
1520 				}
1521 
1522 				if (WMA_GET_RX_UNKNOWN_UCAST
1523 					    (pRxPacketInfo))
1524 					lim_handle_unknown_a2_index_frames
1525 						(mac, pRxPacketInfo,
1526 						pe_session);
1527 				else
1528 					lim_process_action_frame(mac,
1529 								 pRxPacketInfo,
1530 								 pe_session);
1531 			}
1532 			break;
1533 		default:
1534 			/* Received Management frame of 'reserved' subtype */
1535 			break;
1536 		} /* switch (fc.subType) */
1537 
1538 	}
1539 	break;
1540 	case SIR_MAC_DATA_FRAME:
1541 	{
1542 	}
1543 	break;
1544 	default:
1545 		/* Received frame of type 'reserved' */
1546 		break;
1547 
1548 	} /* switch (fc.type) */
1549 	if (lim_is_mgmt_frame_loggable(fc.type, fc.subType))
1550 		lim_diag_mgmt_rx_event_report(mac, pHdr,
1551 					      pe_session,
1552 					      QDF_STATUS_SUCCESS, QDF_STATUS_SUCCESS);
1553 end:
1554 	lim_pkt_free(mac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
1555 		     (void *)limMsg->bodyptr);
1556 	return;
1557 } /*** end lim_handle80211_frames() ***/
1558 
lim_handle_frame_genby_mbssid(uint8_t * frame,uint32_t frame_len,uint8_t frm_subtype,char * bssid)1559 QDF_STATUS lim_handle_frame_genby_mbssid(uint8_t *frame, uint32_t frame_len,
1560 					 uint8_t frm_subtype, char *bssid)
1561 {
1562 	struct mac_context *mac_ctx;
1563 	struct pe_session *session;
1564 	uint8_t sessionid;
1565 	t_packetmeta meta_data = {0};
1566 
1567 	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
1568 	if (!mac_ctx) {
1569 		pe_err("mac ctx is null");
1570 		return QDF_STATUS_E_INVAL;
1571 	}
1572 
1573 	session = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
1574 	if (!session)
1575 		return QDF_STATUS_E_INVAL;
1576 
1577 	meta_data.mpdu_hdr_ptr = frame;
1578 	meta_data.mpdu_len = frame_len;
1579 	meta_data.mpdu_data_ptr = frame + sizeof(struct wlan_frame_hdr);
1580 	meta_data.mpdu_data_len = frame_len - sizeof(struct wlan_frame_hdr);
1581 
1582 	if (frm_subtype == MGMT_SUBTYPE_BEACON) {
1583 		pe_debug("Gen beacon frame for critical update feature");
1584 		if (session->limSmeState == eLIM_SME_LINK_EST_STATE ||
1585 		    session->limSmeState == eLIM_SME_NORMAL_STATE)
1586 			sch_beacon_process(mac_ctx, (uint8_t *)&meta_data,
1587 					   session);
1588 		else
1589 			lim_process_beacon_frame(mac_ctx, (uint8_t *)&meta_data,
1590 						 session);
1591 	} else if (frm_subtype == MGMT_SUBTYPE_PROBE_RESP) {
1592 		pe_debug("Gen Probe rsp frame for critical update feature");
1593 		lim_process_probe_rsp_frame(mac_ctx, (uint8_t *)&meta_data,
1594 						      session);
1595 	}
1596 
1597 	return QDF_STATUS_SUCCESS;
1598 }
1599 
lim_process_abort_scan_ind(struct mac_context * mac_ctx,uint8_t vdev_id,uint32_t scan_id,uint32_t scan_requestor_id)1600 void lim_process_abort_scan_ind(struct mac_context *mac_ctx,
1601 	uint8_t vdev_id, uint32_t scan_id, uint32_t scan_requestor_id)
1602 {
1603 	QDF_STATUS status;
1604 	struct scan_cancel_request *req;
1605 	struct wlan_objmgr_vdev *vdev;
1606 
1607 	pe_debug("scan_id %d, scan_requestor_id 0x%x",
1608 			scan_id, scan_requestor_id);
1609 
1610 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
1611 			mac_ctx->psoc, vdev_id,
1612 			WLAN_LEGACY_MAC_ID);
1613 	if (!vdev) {
1614 		pe_debug("vdev is NULL");
1615 		return;
1616 	}
1617 
1618 	req = qdf_mem_malloc(sizeof(*req));
1619 	if (!req)
1620 		goto fail;
1621 
1622 	req->vdev = vdev;
1623 	req->cancel_req.requester = scan_requestor_id;
1624 	req->cancel_req.scan_id = scan_id;
1625 	req->cancel_req.vdev_id = vdev_id;
1626 	req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE;
1627 
1628 	status = wlan_scan_cancel(req);
1629 	if (QDF_IS_STATUS_ERROR(status))
1630 		pe_err("Cancel scan request failed");
1631 
1632 fail:
1633 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
1634 }
1635 
lim_process_sme_obss_scan_ind(struct mac_context * mac_ctx,struct scheduler_msg * msg)1636 static void lim_process_sme_obss_scan_ind(struct mac_context *mac_ctx,
1637 					  struct scheduler_msg *msg)
1638 {
1639 	struct pe_session *session;
1640 	uint8_t session_id;
1641 	struct sme_obss_ht40_scanind_msg *ht40_scanind;
1642 
1643 	ht40_scanind = (struct sme_obss_ht40_scanind_msg *)msg->bodyptr;
1644 	session = pe_find_session_by_bssid(mac_ctx,
1645 			ht40_scanind->mac_addr.bytes, &session_id);
1646 	if (!session) {
1647 		pe_err("OBSS Scan not started: session id is NULL");
1648 		return;
1649 	}
1650 	pe_debug("OBSS Scan Req: vdev %d (pe session %d) htSupportedChannelWidthSet %d",
1651 		 session->vdev_id, session->peSessionId,
1652 		 session->htSupportedChannelWidthSet);
1653 	if (session->htSupportedChannelWidthSet ==
1654 	    WNI_CFG_CHANNEL_BONDING_MODE_ENABLE)
1655 		lim_send_ht40_obss_scanind(mac_ctx, session);
1656 }
1657 
1658 /**
1659  * lim_process_messages() - Process messages from upper layers.
1660  *
1661  * @mac_ctx: Pointer to the Global Mac Context.
1662  * @msg: Received message.
1663  *
1664  * Return:  None.
1665  */
lim_process_messages(struct mac_context * mac_ctx,struct scheduler_msg * msg)1666 static void lim_process_messages(struct mac_context *mac_ctx,
1667 				 struct scheduler_msg *msg)
1668 {
1669 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1670 	uint8_t vdev_id = 0;
1671 	tUpdateBeaconParams beacon_params;
1672 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1673 	uint8_t i;
1674 	struct pe_session *session_entry = NULL;
1675 	uint8_t defer_msg = false;
1676 	uint16_t pkt_len = 0;
1677 	cds_pkt_t *body_ptr = NULL;
1678 	QDF_STATUS qdf_status;
1679 	struct scheduler_msg new_msg = {0};
1680 
1681 	if (!msg) {
1682 		pe_err("Message pointer is Null");
1683 		QDF_ASSERT(0);
1684 		return;
1685 	}
1686 
1687 	if (ANI_DRIVER_TYPE(mac_ctx) == QDF_DRIVER_TYPE_MFG) {
1688 		qdf_mem_free(msg->bodyptr);
1689 		msg->bodyptr = NULL;
1690 		return;
1691 	}
1692 
1693 	/*
1694 	 * MTRACE logs not captured for events received from SME
1695 	 * SME enums (eWNI_SME_START_REQ) starts with 0x16xx.
1696 	 * Compare received SME events with SIR_SME_MODULE_ID
1697 	 */
1698 	if ((SIR_SME_MODULE_ID ==
1699 	    (uint8_t)MAC_TRACE_GET_MODULE_ID(msg->type)) &&
1700 	    (msg->type != eWNI_SME_REGISTER_MGMT_FRAME_REQ)) {
1701 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_SME_MSG,
1702 				 NO_SESSION, msg->type));
1703 	} else {
1704 		/*
1705 		 * Omitting below message types as these are too frequent
1706 		 * and when crash happens we loose critical trace logs
1707 		 * if these are also logged
1708 		 */
1709 		if (msg->type != SIR_BB_XPORT_MGMT_MSG &&
1710 		    msg->type != WMA_RX_SCAN_EVENT)
1711 			MTRACE(mac_trace_msg_rx(mac_ctx, NO_SESSION,
1712 				LIM_TRACE_MAKE_RXMSG(msg->type,
1713 				LIM_MSG_PROCESSED)));
1714 	}
1715 
1716 	switch (msg->type) {
1717 
1718 	case SIR_LIM_UPDATE_BEACON:
1719 		lim_update_beacon(mac_ctx);
1720 		break;
1721 	case SIR_BB_XPORT_MGMT_MSG:
1722 		/* These messages are from Peer MAC entity.
1723 		 * The original msg which we were deferring have the
1724 		 * bodyPointer point to 'BD' instead of 'cds pkt'. If we
1725 		 * don't make a copy of msg, then overwrite the
1726 		 * msg->bodyPointer and next time when we try to
1727 		 * process the msg, we will try to use 'BD' as
1728 		 * 'cds Pkt' which will cause a crash
1729 		 */
1730 		if (!msg->bodyptr) {
1731 			pe_err("Message bodyptr is Null");
1732 			QDF_ASSERT(0);
1733 			break;
1734 		}
1735 		qdf_mem_copy((uint8_t *) &new_msg,
1736 			(uint8_t *) msg, sizeof(struct scheduler_msg));
1737 		body_ptr = (cds_pkt_t *) new_msg.bodyptr;
1738 		cds_pkt_get_packet_length(body_ptr, &pkt_len);
1739 
1740 		qdf_status =
1741 			wma_ds_peek_rx_packet_info(body_ptr,
1742 						   (void **) &new_msg.bodyptr);
1743 
1744 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1745 			lim_decrement_pending_mgmt_count(mac_ctx);
1746 			cds_pkt_return_packet(body_ptr);
1747 			break;
1748 		}
1749 		if (WMA_GET_ROAMCANDIDATEIND(new_msg.bodyptr))
1750 			pe_debug("roamCandidateInd: %d",
1751 				 WMA_GET_ROAMCANDIDATEIND(new_msg.bodyptr));
1752 		if (WMA_GET_OFFLOADSCANLEARN(new_msg.bodyptr))
1753 			pe_debug("offloadScanLearn: %d",
1754 				 WMA_GET_OFFLOADSCANLEARN(new_msg.bodyptr));
1755 
1756 		lim_handle80211_frames(mac_ctx, &new_msg, &defer_msg);
1757 
1758 		if (defer_msg == true) {
1759 			pe_debug("Defer Msg type=%x", msg->type);
1760 			if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
1761 				pe_err("Unable to Defer Msg %x", msg->type);
1762 				lim_log_session_states(mac_ctx);
1763 				lim_decrement_pending_mgmt_count(mac_ctx);
1764 				cds_pkt_return_packet(body_ptr);
1765 			}
1766 		} else {
1767 			/* PE is not deferring this 802.11 frame so we need to
1768 			 * call cds_pkt_return. Assumption here is when Rx mgmt
1769 			 * frame processing is done, cds packet could be
1770 			 * freed here.
1771 			 */
1772 			lim_decrement_pending_mgmt_count(mac_ctx);
1773 			cds_pkt_return_packet(body_ptr);
1774 		}
1775 		break;
1776 	case eWNI_SME_DISASSOC_REQ:
1777 	case eWNI_SME_DEAUTH_REQ:
1778 #ifdef FEATURE_WLAN_TDLS
1779 	case eWNI_SME_TDLS_SEND_MGMT_REQ:
1780 	case eWNI_SME_TDLS_ADD_STA_REQ:
1781 	case eWNI_SME_TDLS_DEL_STA_REQ:
1782 	case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
1783 #endif
1784 	case eWNI_SME_SET_HW_MODE_REQ:
1785 	case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
1786 	case eWNI_SME_SET_ANTENNA_MODE_REQ:
1787 	case eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE:
1788 	case eWNI_SME_UPDATE_CONFIG:
1789 		/* These messages are from HDD. Need to respond to HDD */
1790 		lim_process_normal_hdd_msg(mac_ctx, msg, true);
1791 		break;
1792 	case eWNI_SME_SEND_DISASSOC_FRAME:
1793 		/* Need to response to hdd */
1794 		lim_process_normal_hdd_msg(mac_ctx, msg, true);
1795 		break;
1796 	case eWNI_SME_PDEV_SET_HT_VHT_IE:
1797 	case eWNI_SME_SET_VDEV_IES_PER_BAND:
1798 	case eWNI_SME_SYS_READY_IND:
1799 	case eWNI_SME_JOIN_REQ:
1800 	case eWNI_SME_REASSOC_REQ:
1801 	case eWNI_SME_START_BSS_REQ:
1802 	case eWNI_SME_STOP_BSS_REQ:
1803 	case eWNI_SME_SWITCH_CHL_IND:
1804 	case eWNI_SME_DISASSOC_CNF:
1805 	case eWNI_SME_DEAUTH_CNF:
1806 	case eWNI_SME_ASSOC_CNF:
1807 	case eWNI_SME_ADDTS_REQ:
1808 	case eWNI_SME_MSCS_REQ:
1809 	case eWNI_SME_DELTS_REQ:
1810 	case eWNI_SME_SESSION_UPDATE_PARAM:
1811 	case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
1812 	case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
1813 	case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
1814 	case eWNI_SME_CHAN_LOAD_REPORT_RESP_XMIT_IND:
1815 #if defined FEATURE_WLAN_ESE
1816 	case eWNI_SME_ESE_ADJACENT_AP_REPORT:
1817 #endif
1818 	case eWNI_SME_FT_AGGR_QOS_REQ:
1819 	case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
1820 #ifdef FEATURE_WLAN_ESE
1821 	case eWNI_SME_GET_TSM_STATS_REQ:
1822 #endif  /* FEATURE_WLAN_ESE */
1823 	case eWNI_SME_REGISTER_MGMT_FRAME_CB:
1824 	case eWNI_SME_EXT_CHANGE_CHANNEL:
1825 	case eWNI_SME_SET_ADDBA_ACCEPT:
1826 	case eWNI_SME_UPDATE_EDCA_PROFILE:
1827 	case WNI_SME_UPDATE_MU_EDCA_PARAMS:
1828 	case eWNI_SME_UPDATE_SESSION_EDCA_TXQ_PARAMS:
1829 	case WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU:
1830 	case eWNI_SME_VDEV_PAUSE_IND:
1831 		/* These messages are from HDD.No need to respond to HDD */
1832 		lim_process_normal_hdd_msg(mac_ctx, msg, false);
1833 		break;
1834 	case eWNI_SME_SEND_MGMT_FRAME_TX:
1835 		lim_send_mgmt_frame_tx(mac_ctx, msg);
1836 		qdf_mem_free(msg->bodyptr);
1837 		msg->bodyptr = NULL;
1838 		break;
1839 	case eWNI_SME_MON_INIT_SESSION:
1840 		lim_mon_init_session(mac_ctx, msg->bodyptr);
1841 		qdf_mem_free(msg->bodyptr);
1842 		msg->bodyptr = NULL;
1843 		break;
1844 	case eWNI_SME_MON_DEINIT_SESSION:
1845 		lim_mon_deinit_session(mac_ctx, msg->bodyptr);
1846 		qdf_mem_free(msg->bodyptr);
1847 		msg->bodyptr = NULL;
1848 		break;
1849 	case SIR_HAL_P2P_NOA_ATTR_IND:
1850 		session_entry = &mac_ctx->lim.gpSession[0];
1851 		pe_debug("Received message Noa_ATTR %x",
1852 			msg->type);
1853 		for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
1854 			session_entry = &mac_ctx->lim.gpSession[i];
1855 			if ((session_entry) && (session_entry->valid) &&
1856 			    (session_entry->opmode == QDF_P2P_GO_MODE)) {
1857 				/* Save P2P attr for Go */
1858 				qdf_mem_copy(&session_entry->p2pGoPsUpdate,
1859 					     msg->bodyptr,
1860 					     sizeof(tSirP2PNoaAttr));
1861 				pe_debug("bssId"
1862 					 QDF_MAC_ADDR_FMT
1863 					 " ctWin=%d oppPsFlag=%d",
1864 					 QDF_MAC_ADDR_REF(session_entry->bssId),
1865 					 session_entry->p2pGoPsUpdate.ctWin,
1866 					 session_entry->p2pGoPsUpdate.oppPsFlag);
1867 				pe_debug("uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d",
1868 					 session_entry->p2pGoPsUpdate.uNoa1IntervalCnt,
1869 					 session_entry->p2pGoPsUpdate.uNoa1Duration,
1870 					 session_entry->p2pGoPsUpdate.uNoa1Interval,
1871 					 session_entry->p2pGoPsUpdate.uNoa1StartTime);
1872 				break;
1873 			}
1874 		}
1875 		qdf_mem_free(msg->bodyptr);
1876 		msg->bodyptr = NULL;
1877 		break;
1878 	case WMA_MISSED_BEACON_IND:
1879 		lim_ps_offload_handle_missed_beacon_ind(mac_ctx, msg);
1880 		qdf_mem_free(msg->bodyptr);
1881 		msg->bodyptr = NULL;
1882 		break;
1883 	case SIR_LIM_ADDTS_RSP_TIMEOUT:
1884 		lim_process_sme_req_messages(mac_ctx, msg);
1885 		break;
1886 #ifdef FEATURE_WLAN_ESE
1887 	case WMA_TSM_STATS_RSP:
1888 		lim_send_sme_pe_ese_tsm_rsp(mac_ctx,
1889 			(tAniGetTsmStatsRsp *) msg->bodyptr);
1890 		break;
1891 #endif
1892 	case WMA_ADD_TS_RSP:
1893 		lim_process_hal_add_ts_rsp(mac_ctx, msg);
1894 		break;
1895 	case SIR_LIM_DELETE_STA_CONTEXT_IND:
1896 		lim_delete_sta_context(mac_ctx, msg);
1897 		break;
1898 	case SIR_LIM_RX_INVALID_PEER:
1899 		lim_rx_invalid_peer_process(mac_ctx, msg);
1900 		break;
1901 	case SIR_HAL_REQ_SEND_DELBA_REQ_IND:
1902 		lim_req_send_delba_ind_process(mac_ctx, msg);
1903 		break;
1904 	case SIR_LIM_JOIN_FAIL_TIMEOUT:
1905 	case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
1906 	case SIR_LIM_AUTH_FAIL_TIMEOUT:
1907 	case SIR_LIM_AUTH_RSP_TIMEOUT:
1908 	case SIR_LIM_ASSOC_FAIL_TIMEOUT:
1909 	case SIR_LIM_REASSOC_FAIL_TIMEOUT:
1910 	case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
1911 	case SIR_LIM_DISASSOC_ACK_TIMEOUT:
1912 	case SIR_LIM_AUTH_RETRY_TIMEOUT:
1913 	case SIR_LIM_AUTH_SAE_TIMEOUT:
1914 	case SIR_LIM_RRM_STA_STATS_RSP_TIMEOUT:
1915 		/* These timeout messages are handled by MLM sub module */
1916 		lim_process_mlm_req_messages(mac_ctx, msg);
1917 		break;
1918 	case SIR_LIM_HEART_BEAT_TIMEOUT:
1919 		/** check if heart beat failed, even if one Beacon
1920 		 * is rcvd within the Heart Beat interval continue
1921 		 * normal processing
1922 		 */
1923 		if (!msg->bodyptr)
1924 			pe_err("Can't Process HB TO - bodyptr is Null");
1925 		else {
1926 			session_entry = (struct pe_session *) msg->bodyptr;
1927 			pe_err("SIR_LIM_HEART_BEAT_TIMEOUT, Session %d",
1928 				((struct pe_session *) msg->bodyptr)->peSessionId);
1929 			limResetHBPktCount(session_entry);
1930 			lim_handle_heart_beat_timeout_for_session(mac_ctx,
1931 							session_entry);
1932 		}
1933 		break;
1934 	case SIR_LIM_CNF_WAIT_TIMEOUT:
1935 		/* Does not receive CNF or dummy packet */
1936 		lim_handle_cnf_wait_timeout(mac_ctx, (uint16_t) msg->bodyval);
1937 		break;
1938 	case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
1939 		lim_handle_update_olbc_cache(mac_ctx);
1940 		break;
1941 	case WMA_ADD_STA_RSP:
1942 		lim_process_add_sta_rsp(mac_ctx, msg);
1943 		break;
1944 	case WMA_DELETE_STA_RSP:
1945 		lim_process_mlm_del_sta_rsp(mac_ctx, msg);
1946 		break;
1947 	case WMA_DELETE_BSS_RSP:
1948 	case WMA_DELETE_BSS_HO_FAIL_RSP:
1949 		lim_handle_delete_bss_rsp(mac_ctx, msg->bodyptr);
1950 		break;
1951 	case WMA_CSA_OFFLOAD_EVENT:
1952 	case eWNI_SME_CSA_REQ:
1953 		lim_handle_csa_offload_msg(mac_ctx, msg);
1954 		break;
1955 	case WMA_SET_BSSKEY_RSP:
1956 	case WMA_SET_STA_BCASTKEY_RSP:
1957 		lim_process_mlm_set_bss_key_rsp(mac_ctx, msg);
1958 		break;
1959 	case WMA_SET_STAKEY_RSP:
1960 		lim_process_mlm_set_sta_key_rsp(mac_ctx, msg);
1961 		break;
1962 	case WMA_SET_MIMOPS_RSP:
1963 	case WMA_SET_TX_POWER_RSP:
1964 		qdf_mem_free((void *)msg->bodyptr);
1965 		msg->bodyptr = NULL;
1966 		break;
1967 	case WMA_SET_MAX_TX_POWER_RSP:
1968 		rrm_set_max_tx_power_rsp(mac_ctx, msg);
1969 		if (msg->bodyptr) {
1970 			qdf_mem_free((void *)msg->bodyptr);
1971 			msg->bodyptr = NULL;
1972 		}
1973 		break;
1974 	case SIR_LIM_ADDR2_MISS_IND:
1975 		pe_err(
1976 			FL("Addr2 mismatch interrupt received %X"), msg->type);
1977 		/* message from HAL indicating addr2 mismatch interrupt occurred
1978 		 * msg->bodyptr contains only pointer to 48-bit addr2 field
1979 		 */
1980 		qdf_mem_free((void *)(msg->bodyptr));
1981 		msg->bodyptr = NULL;
1982 		break;
1983 	case WMA_AGGR_QOS_RSP:
1984 		lim_process_ft_aggr_qos_rsp(mac_ctx, msg);
1985 		break;
1986 	case WMA_DFS_BEACON_TX_SUCCESS_IND:
1987 		lim_process_beacon_tx_success_ind(mac_ctx, msg->type,
1988 				(void *)msg->bodyptr);
1989 		qdf_mem_free((void *)msg->bodyptr);
1990 		msg->bodyptr = NULL;
1991 		break;
1992 	case WMA_DISASSOC_TX_COMP:
1993 		lim_disassoc_tx_complete_cnf(mac_ctx, msg->bodyval,
1994 					     msg->bodyptr);
1995 		break;
1996 	case WMA_DEAUTH_TX_COMP:
1997 		lim_deauth_tx_complete_cnf(mac_ctx, msg->bodyval,
1998 					   msg->bodyptr);
1999 		break;
2000 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
2001 	case WMA_UPDATE_Q2Q_IE_IND:
2002 		qdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
2003 		beacon_params.paramChangeBitmap = 0;
2004 		for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
2005 			vdev_id = ((uint8_t *)msg->bodyptr)[i];
2006 			session_entry = pe_find_session_by_vdev_id(mac_ctx,
2007 								   vdev_id);
2008 			if (!session_entry)
2009 				continue;
2010 			session_entry->sap_advertise_avoid_ch_ie =
2011 				(uint8_t)msg->bodyval;
2012 			/*
2013 			 * if message comes for DFS channel, no need to update:
2014 			 * 1) We won't have MCC with DFS channels. so no need to
2015 			 *    add Q2Q IE
2016 			 * 2) We cannot end up in DFS channel SCC by channel
2017 			 *    switch from non DFS MCC scenario, so no need to
2018 			 *    remove Q2Q IE
2019 			 * 3) There is however a case where device start MCC and
2020 			 *    then user modifies hostapd.conf and does SAP
2021 			 *    restart, in such a case, beacon params will be
2022 			 *    reset and thus will not contain Q2Q IE, by default
2023 			 */
2024 			if (wlan_reg_get_channel_state_for_pwrmode(
2025 				mac_ctx->pdev,
2026 				session_entry->curr_op_freq,
2027 				REG_CURRENT_PWR_MODE) !=
2028 				CHANNEL_STATE_DFS) {
2029 				beacon_params.bss_idx = session_entry->vdev_id;
2030 				beacon_params.beaconInterval =
2031 					session_entry->beaconParams.beaconInterval;
2032 				beacon_params.paramChangeBitmap |=
2033 					PARAM_BCN_INTERVAL_CHANGED;
2034 				sch_set_fixed_beacon_fields(mac_ctx,
2035 					session_entry);
2036 				lim_send_beacon_params(mac_ctx, &beacon_params,
2037 					session_entry);
2038 			}
2039 		}
2040 		qdf_mem_free(msg->bodyptr);
2041 		msg->bodyptr = NULL;
2042 		break;
2043 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
2044 	case eWNI_SME_NSS_UPDATE_REQ:
2045 	case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
2046 		lim_process_sme_req_messages(mac_ctx, msg);
2047 		qdf_mem_free((void *)msg->bodyptr);
2048 		msg->bodyptr = NULL;
2049 		break;
2050 	case eWNI_SME_CHANNEL_CHANGE_REQ:
2051 		lim_process_sme_req_messages(mac_ctx, msg);
2052 		qdf_mem_free((void *)msg->bodyptr);
2053 		msg->bodyptr = NULL;
2054 		break;
2055 	case eWNI_SME_START_BEACON_REQ:
2056 		lim_process_sme_req_messages(mac_ctx, msg);
2057 		qdf_mem_free((void *)msg->bodyptr);
2058 		msg->bodyptr = NULL;
2059 		break;
2060 	case eWNI_SME_UPDATE_ADDITIONAL_IES:
2061 		lim_process_sme_req_messages(mac_ctx, msg);
2062 		qdf_mem_free((void *)msg->bodyptr);
2063 		msg->bodyptr = NULL;
2064 		break;
2065 	case eWNI_SME_MODIFY_ADDITIONAL_IES:
2066 		lim_process_sme_req_messages(mac_ctx, msg);
2067 		qdf_mem_free((void *)msg->bodyptr);
2068 		msg->bodyptr = NULL;
2069 		break;
2070 #ifdef QCA_HT_2040_COEX
2071 	case eWNI_SME_SET_HT_2040_MODE:
2072 		lim_process_sme_req_messages(mac_ctx, msg);
2073 		qdf_mem_free((void *)msg->bodyptr);
2074 		msg->bodyptr = NULL;
2075 		break;
2076 #endif
2077 	case SIR_HAL_PDEV_SET_HW_MODE_RESP:
2078 		lim_process_set_hw_mode_resp(mac_ctx, msg->bodyptr);
2079 		qdf_mem_free((void *)msg->bodyptr);
2080 		msg->bodyptr = NULL;
2081 		break;
2082 	case SIR_HAL_PDEV_MAC_CFG_RESP:
2083 		lim_process_dual_mac_cfg_resp(mac_ctx, msg->bodyptr);
2084 		qdf_mem_free((void *)msg->bodyptr);
2085 		msg->bodyptr = NULL;
2086 		break;
2087 	case eWNI_SME_SET_IE_REQ:
2088 		lim_process_sme_req_messages(mac_ctx, msg);
2089 		qdf_mem_free((void *)msg->bodyptr);
2090 		msg->bodyptr = NULL;
2091 		break;
2092 	case eWNI_SME_HT40_OBSS_SCAN_IND:
2093 		lim_process_sme_obss_scan_ind(mac_ctx, msg);
2094 		qdf_mem_free(msg->bodyptr);
2095 		break;
2096 	case SIR_HAL_SOC_ANTENNA_MODE_RESP:
2097 		lim_process_set_antenna_resp(mac_ctx, msg->bodyptr);
2098 		qdf_mem_free((void *)msg->bodyptr);
2099 		msg->bodyptr = NULL;
2100 		break;
2101 	case eWNI_SME_DEFAULT_SCAN_IE:
2102 		lim_process_set_default_scan_ie_request(mac_ctx, msg->bodyptr);
2103 		qdf_mem_free((void *)msg->bodyptr);
2104 		msg->bodyptr = NULL;
2105 		break;
2106 	case eWNI_SME_SET_HE_BSS_COLOR:
2107 		lim_process_set_he_bss_color(mac_ctx, msg->bodyptr);
2108 		qdf_mem_free((void *)msg->bodyptr);
2109 		msg->bodyptr = NULL;
2110 		break;
2111 	case eWNI_SME_RECONFIG_OBSS_SCAN_PARAM:
2112 		lim_reconfig_obss_scan_param(mac_ctx, msg->bodyptr);
2113 		qdf_mem_free((void *)msg->bodyptr);
2114 		msg->bodyptr = NULL;
2115 		break;
2116 	case eWNI_SME_DEL_ALL_TDLS_PEERS:
2117 		lim_process_sme_del_all_tdls_peers(mac_ctx, msg->bodyptr);
2118 		qdf_mem_free((void *)msg->bodyptr);
2119 		msg->bodyptr = NULL;
2120 		break;
2121 	case WMA_OBSS_DETECTION_INFO:
2122 		lim_process_obss_detection_ind(mac_ctx, msg->bodyptr);
2123 		qdf_mem_free(msg->bodyptr);
2124 		msg->bodyptr = NULL;
2125 		break;
2126 	case eWNI_SME_SEND_SAE_MSG:
2127 		lim_process_sae_msg(mac_ctx, msg->bodyptr);
2128 		qdf_mem_free((void *)msg->bodyptr);
2129 		msg->bodyptr = NULL;
2130 		break;
2131 	case WMA_OBSS_COLOR_COLLISION_INFO:
2132 		lim_process_obss_color_collision_info(mac_ctx, msg->bodyptr);
2133 		qdf_mem_free((void *)msg->bodyptr);
2134 		msg->bodyptr = NULL;
2135 		break;
2136 	case eWNI_SME_CSA_RESTART_REQ:
2137 		lim_send_csa_restart_req(mac_ctx, msg->bodyval);
2138 		break;
2139 	case eWNI_SME_STA_CSA_CONTINUE_REQ:
2140 		lim_continue_sta_csa_req(mac_ctx, msg->bodyval);
2141 		break;
2142 	case WMA_SEND_BCN_RSP:
2143 		lim_send_bcn_rsp(mac_ctx, (tpSendbeaconParams)msg->bodyptr);
2144 		qdf_mem_free((void *)msg->bodyptr);
2145 		msg->bodyptr = NULL;
2146 		break;
2147 	case SIR_LIM_PROCESS_DEFERRED_QUEUE:
2148 		break;
2149 	case CM_BSS_PEER_CREATE_REQ:
2150 		cm_process_peer_create(msg);
2151 		break;
2152 	case CM_CONNECT_REQ:
2153 		cm_process_join_req(msg);
2154 		break;
2155 	case CM_REASSOC_REQ:
2156 		cm_process_reassoc_req(msg);
2157 		break;
2158 	case CM_DISCONNECT_REQ:
2159 		cm_process_disconnect_req(msg);
2160 		break;
2161 	case CM_PREAUTH_REQ:
2162 		cm_process_preauth_req(msg);
2163 		break;
2164 	case CM_ABORT_CONN_TIMER:
2165 		lim_deactivate_timers_for_vdev(mac_ctx, msg->bodyval);
2166 		break;
2167 	case WIFI_POS_PASN_PEER_DELETE_ALL:
2168 		lim_process_pasn_delete_all_peers(mac_ctx, msg->bodyptr);
2169 		qdf_mem_free(msg->bodyptr);
2170 		msg->bodyptr = NULL;
2171 		break;
2172 	case eWNI_SME_SAP_CH_WIDTH_UPDATE_REQ:
2173 		lim_process_sme_req_messages(mac_ctx, msg);
2174 		qdf_mem_free((void *)msg->bodyptr);
2175 		msg->bodyptr = NULL;
2176 		break;
2177 	default:
2178 		qdf_mem_free((void *)msg->bodyptr);
2179 		msg->bodyptr = NULL;
2180 		pe_debug("Discarding unexpected message received %X",
2181 			msg->type);
2182 		lim_print_msg_name(mac_ctx, LOGE, msg->type);
2183 		break;
2184 
2185 	} /* switch (msg->type) */
2186 } /*** end lim_process_messages() ***/
2187 
2188 /**
2189  * lim_process_deferred_message_queue()
2190  *
2191  * This function is called by LIM while exiting from Learn
2192  * mode. This function fetches messages posted to the LIM
2193  * deferred message queue limDeferredMsgQ.
2194  *
2195  * @mac: Pointer to Global MAC structure
2196  * @return None
2197  */
2198 
lim_process_deferred_message_queue(struct mac_context * mac)2199 static void lim_process_deferred_message_queue(struct mac_context *mac)
2200 {
2201 	struct scheduler_msg limMsg = {0};
2202 	struct scheduler_msg *readMsg;
2203 	uint16_t size;
2204 
2205 	/*
2206 	** check any deferred messages need to be processed
2207 	**/
2208 	size = mac->lim.gLimDeferredMsgQ.size;
2209 	if (size > 0) {
2210 		while ((readMsg = lim_read_deferred_msg_q(mac)) != NULL) {
2211 			qdf_mem_copy((uint8_t *) &limMsg,
2212 				     (uint8_t *) readMsg,
2213 				     sizeof(struct scheduler_msg));
2214 			size--;
2215 			lim_process_messages(mac, &limMsg);
2216 
2217 			if (!GET_LIM_PROCESS_DEFD_MESGS(mac) ||
2218 			    mac->lim.gLimAddtsSent)
2219 				break;
2220 		}
2221 	}
2222 } /*** end lim_process_deferred_message_queue() ***/
2223 
2224 /**
2225  * lim_message_processor() - Process messages from LIM.
2226  * @mac_ctx: Pointer to the Global Mac Context.
2227  * @msg: Received LIM message.
2228  *
2229  * Wrapper function for lim_process_messages when handling messages received by
2230  * LIM. Could either defer messages or process them.
2231  *
2232  * Return:  None.
2233  */
lim_message_processor(struct mac_context * mac_ctx,struct scheduler_msg * msg)2234 void lim_message_processor(struct mac_context *mac_ctx, struct scheduler_msg *msg)
2235 {
2236 	if (eLIM_MLM_OFFLINE_STATE == mac_ctx->lim.gLimMlmState) {
2237 		pe_free_msg(mac_ctx, msg);
2238 		return;
2239 	}
2240 
2241 	if (!def_msg_decision(mac_ctx, msg)) {
2242 		lim_process_messages(mac_ctx, msg);
2243 		/* process deferred message queue if allowed */
2244 		if ((!(mac_ctx->lim.gLimAddtsSent)) &&
2245 		    GET_LIM_PROCESS_DEFD_MESGS(mac_ctx))
2246 			lim_process_deferred_message_queue(mac_ctx);
2247 	}
2248 }
2249 
2250 /**
2251  * lim_process_normal_hdd_msg() - Process the message and defer if needed
2252  * @mac_ctx :     Pointer to Global MAC structure
2253  * @msg     :     The message need to be processed
2254  * @rsp_reqd:     whether return result to hdd
2255  *
2256  * This function checks the current lim state and decide whether the message
2257  * passed will be deferred or not.
2258  *
2259  * Return: None
2260  */
lim_process_normal_hdd_msg(struct mac_context * mac_ctx,struct scheduler_msg * msg,uint8_t rsp_reqd)2261 static void lim_process_normal_hdd_msg(struct mac_context *mac_ctx,
2262 				       struct scheduler_msg *msg,
2263 				       uint8_t rsp_reqd)
2264 {
2265 	bool defer_msg = true;
2266 
2267 	/* Added For BT-AMP Support */
2268 	if ((mac_ctx->lim.gLimSystemRole == eLIM_AP_ROLE)
2269 		|| (mac_ctx->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)) {
2270 		/*
2271 		 * This check is required only for the AP and in 2 cases.
2272 		 * 1. If we are in learn mode and we receive any of these
2273 		 * messages, you have to come out of scan and process the
2274 		 * message, hence dont defer the message here. In handler,
2275 		 * these message could be deferred till we actually come out of
2276 		 * scan mode.
2277 		 * 2. If radar is detected, you might have to defer all of
2278 		 * these messages except Stop BSS request/ Switch channel
2279 		 * request. This decision is also made inside its handler.
2280 		 *
2281 		 * Please be careful while using the flag defer_msg. Possibly
2282 		 * you might end up in an infinite loop.
2283 		 */
2284 		if ((msg->type == eWNI_SME_START_BSS_REQ) ||
2285 			(msg->type == eWNI_SME_STOP_BSS_REQ) ||
2286 			(msg->type == eWNI_SME_SWITCH_CHL_IND))
2287 			defer_msg = false;
2288 	}
2289 
2290 	if (mac_ctx->lim.gLimAddtsSent && defer_msg) {
2291 		/*
2292 		 * System is in DFS (Learn) mode or awaiting addts response or
2293 		 * if radar is detected, Defer processing this message
2294 		 */
2295 		if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
2296 			lim_log_session_states(mac_ctx);
2297 			/* Release body */
2298 			qdf_mem_free(msg->bodyptr);
2299 			msg->bodyptr = NULL;
2300 		}
2301 	} else {
2302 		/*
2303 		 * These messages are from HDD.Since these requests may also be
2304 		 * generated internally within LIM module, need to distinguish
2305 		 * and send response to host
2306 		 */
2307 		if (rsp_reqd)
2308 			mac_ctx->lim.gLimRspReqd = true;
2309 		if (lim_process_sme_req_messages(mac_ctx, msg)) {
2310 			/*
2311 			 * Release body. limProcessSmeReqMessage consumed the
2312 			 * buffer. We can free it.
2313 			 */
2314 			qdf_mem_free(msg->bodyptr);
2315 			msg->bodyptr = NULL;
2316 		}
2317 	}
2318 }
2319 
2320 void
handle_ht_capabilityand_ht_info(struct mac_context * mac,struct pe_session * pe_session)2321 handle_ht_capabilityand_ht_info(struct mac_context *mac,
2322 				struct pe_session *pe_session)
2323 {
2324 	struct mlme_ht_capabilities_info *ht_cap_info;
2325 
2326 	ht_cap_info = &mac->mlme_cfg->ht_caps.ht_cap_info;
2327 	mac->lim.gHTLsigTXOPProtection =
2328 		(uint8_t)ht_cap_info->l_sig_tx_op_protection;
2329 	mac->lim.gHTMIMOPSState =
2330 		(tSirMacHTMIMOPowerSaveState)ht_cap_info->mimo_power_save;
2331 	mac->lim.gHTGreenfield = (uint8_t)ht_cap_info->green_field;
2332 	mac->lim.gHTMaxAmsduLength =
2333 		(uint8_t)ht_cap_info->maximal_amsdu_size;
2334 	mac->lim.gHTShortGI20Mhz = (uint8_t)ht_cap_info->short_gi_20_mhz;
2335 	mac->lim.gHTShortGI40Mhz = (uint8_t)ht_cap_info->short_gi_40_mhz;
2336 	mac->lim.gHTPSMPSupport = (uint8_t)ht_cap_info->psmp;
2337 	mac->lim.gHTDsssCckRate40MHzSupport =
2338 		(uint8_t)ht_cap_info->dsss_cck_mode_40_mhz;
2339 
2340 	mac->lim.gHTAMpduDensity =
2341 		(uint8_t)mac->mlme_cfg->ht_caps.ampdu_params.mpdu_density;
2342 	mac->lim.gHTMaxRxAMpduFactor =
2343 		(uint8_t)mac->mlme_cfg->ht_caps.ampdu_params.
2344 		max_rx_ampdu_factor;
2345 
2346 	/* Get HT IE Info */
2347 	mac->lim.gHTServiceIntervalGranularity =
2348 		(uint8_t)mac->mlme_cfg->ht_caps.info_field_1.
2349 		service_interval_granularity;
2350 	mac->lim.gHTControlledAccessOnly =
2351 		(uint8_t)mac->mlme_cfg->ht_caps.info_field_1.
2352 		controlled_access_only;
2353 
2354 	mac->lim.gHTOperMode = (tSirMacHTOperatingMode)mac->mlme_cfg->ht_caps.
2355 		info_field_2.op_mode;
2356 
2357 	mac->lim.gHTPCOActive = (uint8_t)mac->mlme_cfg->ht_caps.info_field_3.
2358 								pco_active;
2359 	mac->lim.gHTPCOPhase = (uint8_t)mac->mlme_cfg->ht_caps.info_field_3.
2360 								pco_phase;
2361 	mac->lim.gHTSecondaryBeacon =
2362 		(uint8_t)mac->mlme_cfg->ht_caps.info_field_3.secondary_beacon;
2363 	mac->lim.gHTDualCTSProtection = (uint8_t)mac->mlme_cfg->ht_caps.
2364 					info_field_3.dual_cts_protection;
2365 	mac->lim.gHTSTBCBasicMCS = (uint8_t)mac->mlme_cfg->ht_caps.
2366 					info_field_3.basic_stbc_mcs;
2367 
2368 	/* The lim globals for channelwidth and secondary chnl have been removed and should not be used during no session;
2369 	 * instead direct cfg is read and used when no session for transmission of mgmt frames (same as old);
2370 	 * For now, we might come here during init and join with pe_session = NULL; in that case just fill the globals which exist
2371 	 * Sessionized entries values will be filled in join or add bss req. The ones which are missed in join are filled below
2372 	 */
2373 	if (pe_session) {
2374 		pe_session->htCapability =
2375 			IS_DOT11_MODE_HT(pe_session->dot11mode);
2376 		pe_session->beaconParams.fLsigTXOPProtectionFullSupport =
2377 			(uint8_t)mac->mlme_cfg->ht_caps.info_field_3.
2378 			lsig_txop_protection_full_support;
2379 		lim_init_obss_params(mac, pe_session);
2380 	}
2381 }
2382 
lim_log_session_states(struct mac_context * mac_ctx)2383 void lim_log_session_states(struct mac_context *mac_ctx)
2384 {
2385 #ifdef WLAN_DEBUG
2386 	int i;
2387 
2388 	for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
2389 		if (mac_ctx->lim.gpSession[i].valid) {
2390 			pe_debug("sysRole(%d) Session (%d)",
2391 				mac_ctx->lim.gLimSystemRole, i);
2392 			pe_debug("SME: Curr %s,Prev %s,MLM: Curr %s,Prev %s",
2393 				lim_sme_state_str(
2394 				mac_ctx->lim.gpSession[i].limSmeState),
2395 				lim_sme_state_str(
2396 				mac_ctx->lim.gpSession[i].limPrevSmeState),
2397 				lim_mlm_state_str(
2398 				mac_ctx->lim.gpSession[i].limMlmState),
2399 				lim_mlm_state_str(
2400 				mac_ctx->lim.gpSession[i].limPrevMlmState));
2401 		}
2402 	}
2403 #endif
2404 }
2405