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