blob: 6bae1ccd9b32647be45f4f67a5c9a666573cb4bb [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
29 * This file lim_process_sme_req_messages.cc contains the code
30 * for processing SME request messages.
31 * Author: Chandra Modumudi
32 * Date: 02/11/02
33 * History:-
34 * Date Modified by Modification Information
35 * --------------------------------------------------------------------
36 *
37 */
38
39#include "cds_api.h"
40#include "wni_api.h"
41#include "wni_cfg.h"
42#include "cfg_api.h"
43#include "sir_api.h"
44#include "sch_api.h"
45#include "utils_api.h"
46#include "lim_types.h"
47#include "lim_utils.h"
48#include "lim_assoc_utils.h"
49#include "lim_security_utils.h"
50#include "lim_ser_des_utils.h"
51#include "lim_sme_req_utils.h"
52#include "lim_ibss_peer_mgmt.h"
53#include "lim_admit_control.h"
54#include "dph_hash_table.h"
55#include "lim_send_messages.h"
56#include "lim_api.h"
57#include "wmm_apsd.h"
58#include "sir_mac_prot_def.h"
Krishna Kumaar Natarajanf599c6e2015-11-03 11:44:03 -080059#include "rrm_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080060
61#include "sap_api.h"
62
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
64#if defined WLAN_FEATURE_VOWIFI_11R
65#include <lim_ft.h>
66#endif
67
68/*
69 * This overhead is time for sending NOA start to host in case of GO/sending
70 * NULL data & receiving ACK in case of P2P Client and starting actual scanning
71 * with init scan req/rsp plus in case of concurrency, taking care of sending
72 * null data and receiving ACK to/from AP/Also SetChannel with calibration
73 * is taking around 7ms .
74 */
75#define SCAN_MESSAGING_OVERHEAD 20 /* in msecs */
76#define JOIN_NOA_DURATION 2000 /* in msecs */
77#define OEM_DATA_NOA_DURATION 60 /* in msecs */
78#define DEFAULT_PASSIVE_MAX_CHANNEL_TIME 110 /* in msecs */
79
80#define CONV_MS_TO_US 1024 /* conversion factor from ms to us */
81
82/* SME REQ processing function templates */
83static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal, uint32_t *);
84static bool __lim_process_sme_start_bss_req(tpAniSirGlobal, tpSirMsgQ pMsg);
85static void __lim_process_sme_scan_req(tpAniSirGlobal, uint32_t *);
86static void __lim_process_sme_join_req(tpAniSirGlobal, uint32_t *);
87static void __lim_process_sme_reassoc_req(tpAniSirGlobal, uint32_t *);
88static void __lim_process_sme_disassoc_req(tpAniSirGlobal, uint32_t *);
89static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal, uint32_t *);
90static void __lim_process_sme_deauth_req(tpAniSirGlobal, uint32_t *);
91static void __lim_process_sme_set_context_req(tpAniSirGlobal, uint32_t *);
92static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal, tpSirMsgQ pMsg);
93static void lim_process_sme_channel_change_request(tpAniSirGlobal pMac,
94 uint32_t *pMsg);
95static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg);
96static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal pMac, uint32_t *pMsg);
97static void lim_process_nss_update_request(tpAniSirGlobal pMac, uint32_t *pMsg);
98static void lim_process_set_ie_req(tpAniSirGlobal pMac, uint32_t *pMsg);
99
100static void lim_start_bss_update_add_ie_buffer(tpAniSirGlobal pMac,
101 uint8_t **pDstData_buff,
102 uint16_t *pDstDataLen,
103 uint8_t *pSrcData_buff,
104 uint16_t srcDataLen);
105
106static void lim_update_add_ie_buffer(tpAniSirGlobal pMac,
107 uint8_t **pDstData_buff,
108 uint16_t *pDstDataLen,
109 uint8_t *pSrcData_buff, uint16_t srcDataLen);
110
111static void lim_process_modify_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
112
113static void lim_process_update_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
114
115extern void pe_register_wma_handle(tpAniSirGlobal pMac);
116
117/**
118 * lim_process_set_hw_mode() - Send set HW mode command to WMA
119 * @mac: Globacl MAC pointer
120 * @msg: Message containing the hw mode index
121 *
122 * Send the set HW mode command to WMA
123 *
124 * Return: CDF_STATUS_SUCCESS if message posting is successful
125 */
126static CDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
127{
128 CDF_STATUS status = CDF_STATUS_SUCCESS;
129 cds_msg_t cds_message;
130 struct sir_hw_mode *req_msg;
131 uint32_t len;
132 struct s_sir_set_hw_mode *buf;
133 tSirMsgQ resp_msg;
134 struct sir_set_hw_mode_resp *param;
135
136 buf = (struct s_sir_set_hw_mode *) msg;
137 if (!buf) {
138 lim_log(mac, LOGE, FL("Set HW mode param is NULL"));
139 /* To free the active command list */
140 goto fail;
141 }
142
143 len = sizeof(*req_msg);
144
145 req_msg = cdf_mem_malloc(len);
146 if (!req_msg) {
147 lim_log(mac, LOGE, FL("cdf_mem_malloc failed"));
148 /* Free the active command list
149 * Probably the malloc is going to fail there as well?!
150 */
151 return CDF_STATUS_E_NOMEM;
152 }
153
154 cdf_mem_zero(req_msg, len);
155
156 req_msg->hw_mode_index = buf->set_hw.hw_mode_index;
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +0530157 req_msg->reason = buf->set_hw.reason;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800158 /* Other parameters are not needed for WMA */
159
160 cds_message.bodyptr = req_msg;
161 cds_message.type = SIR_HAL_SOC_SET_HW_MODE;
162
163 lim_log(mac, LOG1, FL("Posting SIR_HAL_SOC_SET_HW_MOD to WMA"));
164 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
165 if (!CDF_IS_STATUS_SUCCESS(status)) {
166 lim_log(mac, LOGE,
167 FL("vos_mq_post_message failed!(err=%d)"),
168 status);
169 cdf_mem_free(req_msg);
170 goto fail;
171 }
172 return status;
173fail:
174 param = cdf_mem_malloc(sizeof(*param));
175 if (!param) {
176 lim_log(mac, LOGE, FL("HW mode resp failed"));
177 return CDF_STATUS_E_FAILURE;
178 }
179 param->status = SET_HW_MODE_STATUS_ECANCELED;
180 param->cfgd_hw_mode_index = 0;
181 param->num_vdev_mac_entries = 0;
182 resp_msg.type = eWNI_SME_SET_HW_MODE_RESP;
183 resp_msg.bodyptr = param;
184 resp_msg.bodyval = 0;
185 lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
186 return CDF_STATUS_SUCCESS;
187}
188
189/**
190 * lim_process_set_dual_mac_cfg_req() - Set dual mac config command to WMA
191 * @mac: Global MAC pointer
192 * @msg: Message containing the dual mac config parameter
193 *
194 * Send the set dual mac config command to WMA
195 *
196 * Return: CDF_STATUS_SUCCESS if message posting is successful
197 */
198static CDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac,
199 uint32_t *msg)
200{
201 CDF_STATUS status = CDF_STATUS_SUCCESS;
202 cds_msg_t cds_message;
203 struct sir_dual_mac_config *req_msg;
204 uint32_t len;
205 struct sir_set_dual_mac_cfg *buf;
206 tSirMsgQ resp_msg;
207 struct sir_dual_mac_config_resp *param;
208
209 buf = (struct sir_set_dual_mac_cfg *) msg;
210 if (!buf) {
211 lim_log(mac, LOGE, FL("Set Dual mac config is NULL"));
212 /* To free the active command list */
213 goto fail;
214 }
215
216 len = sizeof(*req_msg);
217
218 req_msg = cdf_mem_malloc(len);
219 if (!req_msg) {
220 lim_log(mac, LOGE, FL("vos_mem_malloc failed"));
221 /* Free the active command list
222 * Probably the malloc is going to fail there as well?!
223 */
224 return CDF_STATUS_E_NOMEM;
225 }
226
227 cdf_mem_zero(req_msg, len);
228
229 req_msg->scan_config = buf->set_dual_mac.scan_config;
230 req_msg->fw_mode_config = buf->set_dual_mac.fw_mode_config;
231 /* Other parameters are not needed for WMA */
232
233 cds_message.bodyptr = req_msg;
234 cds_message.type = SIR_HAL_SOC_DUAL_MAC_CFG_REQ;
235
236 lim_log(mac, LOG1,
237 FL("Post SIR_HAL_SOC_DUAL_MAC_CFG_REQ to WMA: %x %x"),
238 req_msg->scan_config, req_msg->fw_mode_config);
239 status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
240 if (!CDF_IS_STATUS_SUCCESS(status)) {
241 lim_log(mac, LOGE,
242 FL("vos_mq_post_message failed!(err=%d)"),
243 status);
244 cdf_mem_free(req_msg);
245 goto fail;
246 }
247 return status;
248fail:
249 param = cdf_mem_malloc(sizeof(*param));
250 if (!param) {
251 lim_log(mac, LOGE, FL("Dual mac config resp failed"));
252 return CDF_STATUS_E_FAILURE;
253 }
254 param->status = SET_HW_MODE_STATUS_ECANCELED;
255 resp_msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
256 resp_msg.bodyptr = param;
257 resp_msg.bodyval = 0;
258 lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
259 return CDF_STATUS_SUCCESS;
260}
261
262/**
263 * __lim_fresh_scan_reqd() - determine if a fresh scan request must be issued.
264 * @mac_ctx: Pointer to Global MAC structure
265 * @return_fresh_results: Trigger fresh scan.
266 *
267 * PE will do fresh scan, if all of the active sessions are in
268 * good state (Link Est or BSS Started). If one of the sessions
269 * is not in one of the above states, then PE does not do fresh
270 * scan. If no session exists (scanning very first time),
271 * then PE will always do fresh scan if SME asks it to do that.
272 *
273 * Return: true for fresh scan results, false if in invalid state.
274 */
275static uint8_t
276__lim_fresh_scan_reqd(tpAniSirGlobal mac_ctx, uint8_t return_fresh_results)
277{
278 uint8_t valid_state = true;
279 int i;
280
281 lim_log(mac_ctx, LOG1, FL("gLimSmeState: %d, returnFreshResults 0x%x"),
282 mac_ctx->lim.gLimSmeState, return_fresh_results);
283
284 if (mac_ctx->lim.gLimSmeState != eLIM_SME_IDLE_STATE) {
285 lim_log(mac_ctx, LOG1, FL("return FALSE"));
286 return false;
287 }
288
289 for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
290 lim_log(mac_ctx, LOG1,
291 FL("session %d, bsstype %d, limSystemRole %d, limSmeState %d"),
292 i, mac_ctx->lim.gpSession[i].bssType,
293 mac_ctx->lim.gpSession[i].limSystemRole,
294 mac_ctx->lim.gpSession[i].limSmeState);
295 if (mac_ctx->lim.gpSession[i].valid == true) {
296 if (!((((mac_ctx->lim.gpSession[i].bssType ==
297 eSIR_INFRASTRUCTURE_MODE) ||
298 (mac_ctx->lim.gpSession[i].limSystemRole ==
299 eLIM_BT_AMP_STA_ROLE)) &&
300 (mac_ctx->lim.gpSession[i].limSmeState ==
301 eLIM_SME_LINK_EST_STATE)) ||
302 (((mac_ctx->lim.gpSession[i].bssType ==
303 eSIR_IBSS_MODE) ||
304 (mac_ctx->lim.gpSession[i].limSystemRole ==
305 eLIM_BT_AMP_AP_ROLE) ||
306 (mac_ctx->lim.gpSession[i].limSystemRole ==
307 eLIM_BT_AMP_STA_ROLE)) &&
308 (mac_ctx->lim.gpSession[i].limSmeState ==
309 eLIM_SME_NORMAL_STATE)) ||
310 ((((mac_ctx->lim.gpSession[i].bssType ==
311 eSIR_INFRA_AP_MODE) &&
312 (mac_ctx->lim.gpSession[i].pePersona ==
313 CDF_P2P_GO_MODE)) ||
314 (mac_ctx->lim.gpSession[i].limSystemRole ==
315 eLIM_AP_ROLE)) &&
316 (mac_ctx->lim.gpSession[i].limSmeState ==
317 eLIM_SME_NORMAL_STATE)))) {
318 valid_state = false;
319 break;
320 }
321 }
322 }
323
324 lim_log(mac_ctx, LOG1, FL("valid_state: %d"), valid_state);
325
326 if ((valid_state) &&
327 (return_fresh_results & SIR_BG_SCAN_RETURN_FRESH_RESULTS))
328 return true;
329 else
330 return false;
331}
332
333/**
334 * __lim_is_sme_assoc_cnf_valid()
335 *
336 ***FUNCTION:
337 * This function is called by __lim_process_sme_assoc_cnf_new() upon
338 * receiving SME_ASSOC_CNF.
339 *
340 ***LOGIC:
341 * Message validity checks are performed in this function
342 *
343 ***ASSUMPTIONS:
344 *
345 ***NOTE:
346 *
347 * @param pMeasReq Pointer to Received ASSOC_CNF message
348 * @return true When received SME_ASSOC_CNF is formatted
349 * correctly
350 * false otherwise
351 */
352
353static inline uint8_t __lim_is_sme_assoc_cnf_valid(tpSirSmeAssocCnf pAssocCnf)
354{
355 if (lim_is_group_addr(pAssocCnf->peerMacAddr))
356 return false;
357 else
358 return true;
359} /*** end __lim_is_sme_assoc_cnf_valid() ***/
360
361/**
362 * __lim_get_sme_join_req_size_for_alloc()
363 *
364 ***FUNCTION:
365 * This function is called in various places to get IE length
366 * from tSirBssDescription structure
367 * number being scanned.
368 *
369 ***PARAMS:
370 *
371 ***LOGIC:
372 *
373 ***ASSUMPTIONS:
374 * NA
375 *
376 ***NOTE:
377 * NA
378 *
379 * @param pBssDescr
380 * @return Total IE length
381 */
382
383static uint16_t __lim_get_sme_join_req_size_for_alloc(uint8_t *pBuf)
384{
385 uint16_t len = 0;
386
387 if (!pBuf)
388 return len;
389
390 pBuf += sizeof(uint16_t);
391 len = lim_get_u16(pBuf);
392 return len + sizeof(uint16_t);
393}
394
395/**
396 * __lim_is_defered_msg_for_learn() - message handling in SME learn state
397 * @pMac: Global MAC context
398 * @pMsg: Pointer to message posted from SME to LIM.
399 *
400 * Has role only if 11h is enabled. Not used on STA side.
401 * Defers the message if SME is in learn state and brings
402 * the LIM back to normal mode.
403 *
404 * Return: true - If defered false - Otherwise
405 */
406
407static bool __lim_is_defered_msg_for_learn(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
408{
409 if (lim_is_system_in_scan_state(pMac)) {
410 if (lim_defer_msg(pMac, pMsg) != TX_SUCCESS) {
411 lim_log(pMac, LOGE, FL("Could not defer Msg = %d"),
412 pMsg->type);
413 return false;
414 }
415 lim_log(pMac, LOG1,
416 FL("Defer the message, in learn mode type = %d"),
417 pMsg->type);
418 return true;
419 }
420 return false;
421}
422
423/**
424 * __lim_is_defered_msg_for_radar() - Defers the message if radar is detected
425 * @mac_ctx: Pointer to Global MAC structure
426 * @message: Pointer to message posted from SME to LIM.
427 *
428 * Has role only if 11h is enabled. Not used on STA side.
429 * Defers the message if radar is detected.
430 *
431 * Return: true, if defered otherwise return false.
432 */
433static bool
434__lim_is_defered_msg_for_radar(tpAniSirGlobal mac_ctx, tpSirMsgQ message)
435{
436 /*
437 * fRadarDetCurOperChan will be set only if we
438 * detect radar in current operating channel and
439 * System Role == AP ROLE
440 *
441 * TODO: Need to take care radar detection.
442 *
443 * if (LIM_IS_RADAR_DETECTED(mac_ctx))
444 */
445 if (0) {
446 if (lim_defer_msg(mac_ctx, message) != TX_SUCCESS) {
447 lim_log(mac_ctx, LOGE, FL("Could not defer Msg = %d"),
448 message->type);
449 return false;
450 }
451 lim_log(mac_ctx, LOG1,
452 FL("Defer the message, in learn mode type = %d"),
453 message->type);
454 return true;
455 }
456 return false;
457}
458
459/**
460 * __lim_process_sme_sys_ready_ind () - Process ready indication from WMA
461 * @pMac: Global MAC context
462 * @pMsgBuf: Message from WMA
463 *
464 * handles the notification from HDD. PE just forwards this message to HAL.
465 *
466 * Return: true-Posting to HAL failed, so PE will consume the buffer.
467 * false-Posting to HAL successful, so HAL will consume the buffer.
468 */
469
470static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
471{
472 tSirMsgQ msg;
473 tSirSmeReadyReq *ready_req = (tSirSmeReadyReq *) pMsgBuf;
474
475 msg.type = WMA_SYS_READY_IND;
476 msg.reserved = 0;
477 msg.bodyptr = pMsgBuf;
478 msg.bodyval = 0;
479
480 if (ANI_DRIVER_TYPE(pMac) != eDRIVER_TYPE_MFG) {
481 pe_register_wma_handle(pMac);
482 pMac->lim.add_bssdescr_callback = ready_req->add_bssdescr_cb;
483 }
484 PELOGW(lim_log(pMac, LOGW, FL("sending WMA_SYS_READY_IND msg to HAL"));)
485 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
486
487 if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
488 lim_log(pMac, LOGP, FL("wma_post_ctrl_msg failed"));
489 return true;
490 }
491 return false;
492}
493
494#ifdef WLAN_FEATURE_11AC
495
496uint32_t lim_get_center_channel(tpAniSirGlobal pMac, uint8_t primarychanNum,
497 ePhyChanBondState secondaryChanOffset,
498 uint8_t chanWidth)
499{
500 if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
501 switch (secondaryChanOffset) {
502 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
503 return primarychanNum;
504 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
505 return primarychanNum + 2;
506 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
507 return primarychanNum - 2;
508 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
509 return primarychanNum + 6;
510 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
511 return primarychanNum + 2;
512 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
513 return primarychanNum - 2;
514 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
515 return primarychanNum - 6;
516 default:
517 return eSIR_CFG_INVALID_ID;
518 }
519 } else if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
520 switch (secondaryChanOffset) {
521 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
522 return primarychanNum + 2;
523 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
524 return primarychanNum - 2;
525 case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
526 return primarychanNum;
527 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
528 return primarychanNum + 2;
529 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
530 return primarychanNum - 2;
531 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
532 return primarychanNum + 2;
533 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
534 return primarychanNum - 2;
535 case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
536 return primarychanNum + 2;
537 case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
538 return primarychanNum - 2;
539 default:
540 return eSIR_CFG_INVALID_ID;
541 }
542 }
543 return primarychanNum;
544}
545
546#endif
547
548/**
549 *lim_configure_ap_start_bss_session() - Configure the AP Start BSS in session.
550 *@mac_ctx: Pointer to Global MAC structure
551 *@session: A pointer to session entry
552 *@sme_start_bss_req: Start BSS Request from upper layers.
553 *
554 * This function is used to configure the start bss parameters
555 * in to the session.
556 *
557 * Return: None.
558 */
559static void
560lim_configure_ap_start_bss_session(tpAniSirGlobal mac_ctx, tpPESession session,
561 tpSirSmeStartBssReq sme_start_bss_req)
562{
563 session->limSystemRole = eLIM_AP_ROLE;
564 session->privacy = sme_start_bss_req->privacy;
565 session->fwdWPSPBCProbeReq = sme_start_bss_req->fwdWPSPBCProbeReq;
566 session->authType = sme_start_bss_req->authType;
567 /* Store the DTIM period */
568 session->dtimPeriod = (uint8_t) sme_start_bss_req->dtimPeriod;
569 /* Enable/disable UAPSD */
570 session->apUapsdEnable = sme_start_bss_req->apUapsdEnable;
571 if (session->pePersona == CDF_P2P_GO_MODE) {
572 session->proxyProbeRspEn = 0;
573 } else {
574 /*
575 * To detect PBC overlap in SAP WPS mode,
576 * Host handles Probe Requests.
577 */
578 if (SAP_WPS_DISABLED == sme_start_bss_req->wps_state)
579 session->proxyProbeRspEn = 1;
580 else
581 session->proxyProbeRspEn = 0;
582 }
583 session->ssidHidden = sme_start_bss_req->ssidHidden;
584 session->wps_state = sme_start_bss_req->wps_state;
585 session->sap_dot11mc = sme_start_bss_req->sap_dot11mc;
586 lim_get_short_slot_from_phy_mode(mac_ctx, session, session->gLimPhyMode,
587 &session->shortSlotTimeSupported);
588 session->isCoalesingInIBSSAllowed =
589 sme_start_bss_req->isCoalesingInIBSSAllowed;
590
591}
592
593/**
594 * __lim_handle_sme_start_bss_request() - process SME_START_BSS_REQ message
595 *@mac_ctx: Pointer to Global MAC structure
596 *@msg_buf: A pointer to the SME message buffer
597 *
598 * This function is called to process SME_START_BSS_REQ message
599 * from HDD or upper layer application.
600 *
601 * Return: None
602 */
603static void
604__lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
605{
606 uint16_t size;
607 uint32_t val = 0;
608 tSirRetStatus ret_status;
609 tSirMacChanNum channel_number;
610 tLimMlmStartReq *mlm_start_req = NULL;
611 tpSirSmeStartBssReq sme_start_bss_req = NULL;
612 tSirResultCodes ret_code = eSIR_SME_SUCCESS;
613 /* Flag Used in case of IBSS to Auto generate BSSID. */
614 uint32_t auto_gen_bssid = false;
615 uint8_t session_id;
616 tpPESession session = NULL;
617 uint8_t sme_session_id = 0;
618 uint16_t sme_transaction_id = 0;
619 uint32_t chanwidth;
620 tSirRetStatus cfg_get_wmi_dfs_master_param = eSIR_SUCCESS;
621
622/* FEATURE_WLAN_DIAG_SUPPORT */
623#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
624 /*
625 * Since the session is not created yet, sending NULL.
626 * The response should have the correct state.
627 */
628 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_START_BSS_REQ_EVENT,
629 NULL, 0, 0);
630#endif /* FEATURE_WLAN_DIAG_SUPPORT */
631
632 lim_log(mac_ctx, LOG1, FL("Received START_BSS_REQ"));
633
634 /*
635 * Global Sme state and mlm states are not defined yet,
636 * for BT-AMP Suppoprt . TO BE DONE
637 */
638 if ((mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
639 (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE)) {
640 size = sizeof(tSirSmeStartBssReq);
641
642 sme_start_bss_req = cdf_mem_malloc(size);
643 if (NULL == sme_start_bss_req) {
644 lim_log(mac_ctx, LOGE,
645 FL("Allocate Memory fail for LimStartBssReq"));
646 /* Send failure response to host */
647 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
648 goto end;
649 }
650
651 cdf_mem_set((void *)sme_start_bss_req, size, 0);
652 cdf_mem_copy(sme_start_bss_req, msg_buf,
653 sizeof(tSirSmeStartBssReq));
654 if (!lim_is_sme_start_bss_req_valid(mac_ctx,
655 sme_start_bss_req)) {
656 lim_log(mac_ctx, LOGW,
657 FL("Received invalid eWNI_SME_START_BSS_REQ"));
658 ret_code = eSIR_SME_INVALID_PARAMETERS;
659 goto free;
660 }
661
662 /*
663 * This is the place where PE is going to create a session.
664 * If session is not existed, then create a new session
665 */
666 session = pe_find_session_by_bssid(mac_ctx,
667 sme_start_bss_req->bssId, &session_id);
668 if (session != NULL) {
669 lim_log(mac_ctx, LOGW,
670 FL("Session Already exists for given BSSID"));
671 ret_code = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
672 session = NULL;
673 goto free;
674 } else {
675 session = pe_create_session(mac_ctx,
676 sme_start_bss_req->bssId,
677 &session_id, mac_ctx->lim.maxStation,
678 sme_start_bss_req->bssType);
679 if (session == NULL) {
680 lim_log(mac_ctx, LOGW,
681 FL("Session Can not be created "));
682 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
683 goto free;
684 }
685 }
686
687 /* Probe resp add ie */
688 lim_start_bss_update_add_ie_buffer(mac_ctx,
689 &session->addIeParams.probeRespData_buff,
690 &session->addIeParams.probeRespDataLen,
691 sme_start_bss_req->addIeParams.probeRespData_buff,
692 sme_start_bss_req->addIeParams.probeRespDataLen);
693
694 /* Probe Beacon add ie */
695 lim_start_bss_update_add_ie_buffer(mac_ctx,
696 &session->addIeParams.probeRespBCNData_buff,
697 &session->addIeParams.probeRespBCNDataLen,
698 sme_start_bss_req->addIeParams.probeRespBCNData_buff,
699 sme_start_bss_req->addIeParams.probeRespBCNDataLen);
700
701 /* Assoc resp IE */
702 lim_start_bss_update_add_ie_buffer(mac_ctx,
703 &session->addIeParams.assocRespData_buff,
704 &session->addIeParams.assocRespDataLen,
705 sme_start_bss_req->addIeParams.assocRespData_buff,
706 sme_start_bss_req->addIeParams.assocRespDataLen);
707
708 /* Store the session related params in newly created session */
709 session->pLimStartBssReq = sme_start_bss_req;
710
711 /* Store PE session_id in session Table */
712 session->peSessionId = session_id;
713
714 /* Store SME session Id in sessionTable */
715 session->smeSessionId = sme_start_bss_req->sessionId;
716
717 session->transactionId = sme_start_bss_req->transactionId;
718
719 cdf_mem_copy(&(session->htConfig),
720 &(sme_start_bss_req->htConfig),
721 sizeof(session->htConfig));
722
723 sir_copy_mac_addr(session->selfMacAddr,
724 sme_start_bss_req->selfMacAddr);
725
726 /* Copy SSID to session table */
727 cdf_mem_copy((uint8_t *) &session->ssId,
728 (uint8_t *) &sme_start_bss_req->ssId,
729 (sme_start_bss_req->ssId.length + 1));
730
731 session->bssType = sme_start_bss_req->bssType;
732
733 session->nwType = sme_start_bss_req->nwType;
734
735 session->beaconParams.beaconInterval =
736 sme_start_bss_req->beaconInterval;
737
738 /* Store the channel number in session Table */
739 session->currentOperChannel =
740 sme_start_bss_req->channelId;
741
742 /* Store Persona */
743 session->pePersona = sme_start_bss_req->bssPersona;
744 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
745 FL("PE PERSONA=%d"), session->pePersona);
746
747 /* Update the phymode */
748 session->gLimPhyMode = sme_start_bss_req->nwType;
749
750 session->maxTxPower =
751 cfg_get_regulatory_max_transmit_power(mac_ctx,
752 session->currentOperChannel);
753 /* Store the dot 11 mode in to the session Table */
754 session->dot11mode = sme_start_bss_req->dot11mode;
755#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
756 session->cc_switch_mode =
757 sme_start_bss_req->cc_switch_mode;
758#endif
759 session->htCapability =
760 IS_DOT11_MODE_HT(session->dot11mode);
761 session->vhtCapability =
762 IS_DOT11_MODE_VHT(session->dot11mode);
763 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
764 FL("*****session->vhtCapability = %d"),
765 session->vhtCapability);
766 session->txLdpcIniFeatureEnabled =
767 sme_start_bss_req->txLdpcIniFeatureEnabled;
768
769 if (mac_ctx->roam.configParam.enable2x2)
770 session->nss = 2;
771 else
772 session->nss = 1;
773#ifdef WLAN_FEATURE_11W
774 session->limRmfEnabled =
775 sme_start_bss_req->pmfCapable ? 1 : 0;
776 lim_log(mac_ctx, LOG1, FL("Session RMF enabled: %d"),
777 session->limRmfEnabled);
778#endif
779
780 cdf_mem_copy((void *)&session->rateSet,
781 (void *)&sme_start_bss_req->operationalRateSet,
782 sizeof(tSirMacRateSet));
783 cdf_mem_copy((void *)&session->extRateSet,
784 (void *)&sme_start_bss_req->extendedRateSet,
785 sizeof(tSirMacRateSet));
786
787 switch (sme_start_bss_req->bssType) {
788 case eSIR_INFRA_AP_MODE:
789 lim_configure_ap_start_bss_session(mac_ctx, session,
790 sme_start_bss_req);
791 break;
792 case eSIR_IBSS_MODE:
793 session->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
794 lim_get_short_slot_from_phy_mode(mac_ctx, session,
795 session->gLimPhyMode,
796 &session->shortSlotTimeSupported);
797
798 /*
799 * initialize to "OPEN".
800 * will be updated upon key installation
801 */
802 session->encryptType = eSIR_ED_NONE;
803
804 break;
805
806 case eSIR_BTAMP_AP_MODE:
807 session->limSystemRole = eLIM_BT_AMP_AP_ROLE;
808 break;
809
810 case eSIR_BTAMP_STA_MODE:
811 session->limSystemRole = eLIM_BT_AMP_STA_ROLE;
812 break;
813
814 /*
815 * There is one more mode called auto mode.
816 * which is used no where
817 */
818
819 /* FORBUILD -TEMPFIX.. HOW TO use AUTO MODE????? */
820
821 default:
822 /* not used anywhere...used in scan function */
823 break;
824 }
825
826 /*
827 * BT-AMP: Allocate memory for the array of
828 * parsed (Re)Assoc request structure
829 */
830 if ((sme_start_bss_req->bssType == eSIR_BTAMP_AP_MODE) ||
831 (sme_start_bss_req->bssType == eSIR_INFRA_AP_MODE)) {
832 session->parsedAssocReq =
833 cdf_mem_malloc(session->dph.dphHashTable.
834 size * sizeof(tpSirAssocReq));
835 if (NULL == session->parsedAssocReq) {
836 lim_log(mac_ctx, LOGW,
837 FL("AllocateMemory() failed"));
838 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
839 goto free;
840 }
841 cdf_mem_set(session->parsedAssocReq,
842 (session->dph.dphHashTable.size *
843 sizeof(tpSirAssocReq)), 0);
844 }
845
846 if (!sme_start_bss_req->channelId) {
847 lim_log(mac_ctx, LOGE,
848 FL("Received invalid eWNI_SME_START_BSS_REQ"));
849 ret_code = eSIR_SME_INVALID_PARAMETERS;
850 goto free;
851 }
852 channel_number = sme_start_bss_req->channelId;
853#ifdef QCA_HT_2040_COEX
854 if (sme_start_bss_req->obssEnabled)
855 session->htSupportedChannelWidthSet =
856 session->htCapability;
857 else
858#endif
859 session->htSupportedChannelWidthSet =
860 (sme_start_bss_req->sec_ch_offset) ? 1 : 0;
861 session->htSecondaryChannelOffset =
862 sme_start_bss_req->sec_ch_offset;
863 session->htRecommendedTxWidthSet =
864 (session->htSecondaryChannelOffset) ? 1 : 0;
865 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
866 FL("cbMode %u"), sme_start_bss_req->cbMode);
867 if (session->vhtCapability || session->htCapability) {
868 chanwidth = sme_start_bss_req->vht_channel_width;
869 lim_log(mac_ctx, LOG1, FL("vht_channel_width %u"),
870 sme_start_bss_req->vht_channel_width);
871 if (channel_number <= RF_CHAN_14 &&
872 chanwidth != eHT_CHANNEL_WIDTH_20MHZ) {
873 chanwidth = CH_WIDTH_20MHZ;
874 session->htSupportedChannelWidthSet = 0;
875 lim_log(mac_ctx, LOG1,
876 FL("Set chanwidth to 20Mhz, chan %d"),
877 channel_number);
878 }
879 session->ch_width = chanwidth;
880 if (session->htSupportedChannelWidthSet) {
881 session->ch_center_freq_seg0 =
882 sme_start_bss_req->center_freq_seg0;
883 session->ch_center_freq_seg1 =
884 sme_start_bss_req->center_freq_seg1;
885 } else {
886 session->ch_center_freq_seg0 = 0;
887 session->ch_center_freq_seg1 = 0;
888 }
889 }
890
891 if (session->vhtCapability &&
892 (CH_WIDTH_160MHZ > session->ch_width)) {
893 if (wlan_cfg_get_int(mac_ctx,
894 WNI_CFG_VHT_SU_BEAMFORMER_CAP, &val) !=
895 eSIR_SUCCESS)
896 lim_log(mac_ctx, LOGE, FL(
897 "cfg get vht su bformer failed"));
898
899 session->enable_su_tx_bformer = val;
900 } else {
901 session->nss = 1;
902 }
903 lim_log(mac_ctx, LOG1, FL("vht su tx bformer %d"), val);
904
905 /* Delete pre-auth list if any */
906 lim_delete_pre_auth_list(mac_ctx);
907
908 /*
909 * keep the RSN/WPA IE information in PE Session Entry
910 * later will be using this to check when received (Re)Assoc req
911 */
912 lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(mac_ctx,
913 &sme_start_bss_req->rsnIE, session);
914
915 if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) {
916 session->gLimProtectionControl =
917 sme_start_bss_req->protEnabled;
918 /*
919 * each byte will have the following info
920 * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
921 * reserved reserved RIFS Lsig n-GF ht20 11g 11b
922 */
923 cdf_mem_copy((void *)&session->cfgProtection,
924 (void *)&sme_start_bss_req->ht_capab,
925 sizeof(uint16_t));
926 /* Initialize WPS PBC session link list */
927 session->pAPWPSPBCSession = NULL;
928 }
929 /* Prepare and Issue LIM_MLM_START_REQ to MLM */
930 mlm_start_req = cdf_mem_malloc(sizeof(tLimMlmStartReq));
931 if (NULL == mlm_start_req) {
932 lim_log(mac_ctx, LOGP,
933 FL("Allocate Memory failed for mlmStartReq"));
934 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
935 goto free;
936 }
937
938 cdf_mem_set((void *)mlm_start_req, sizeof(tLimMlmStartReq), 0);
939
940 /* Copy SSID to the MLM start structure */
941 cdf_mem_copy((uint8_t *) &mlm_start_req->ssId,
942 (uint8_t *) &sme_start_bss_req->ssId,
943 sme_start_bss_req->ssId.length + 1);
944 mlm_start_req->ssidHidden = sme_start_bss_req->ssidHidden;
945 mlm_start_req->obssProtEnabled =
946 sme_start_bss_req->obssProtEnabled;
947
948 mlm_start_req->bssType = session->bssType;
949
950 /* Fill PE session Id from the session Table */
951 mlm_start_req->sessionId = session->peSessionId;
952
953 if ((mlm_start_req->bssType == eSIR_BTAMP_STA_MODE) ||
954 (mlm_start_req->bssType == eSIR_BTAMP_AP_MODE) ||
955 (mlm_start_req->bssType == eSIR_INFRA_AP_MODE)) {
956 /*
957 * Copy the BSSId from sessionTable to
958 * mlmStartReq struct
959 */
960 sir_copy_mac_addr(mlm_start_req->bssId, session->bssId);
961 } else {
962 /* ibss mode */
963 mac_ctx->lim.gLimIbssCoalescingHappened = false;
964
965 ret_status = wlan_cfg_get_int(mac_ctx,
966 WNI_CFG_IBSS_AUTO_BSSID,
967 &auto_gen_bssid);
968 if (ret_status != eSIR_SUCCESS) {
969 lim_log(mac_ctx, LOGP,
970 FL("Get Auto Gen BSSID fail,Status=%d"),
971 ret_status);
972 ret_code = eSIR_LOGP_EXCEPTION;
973 goto free;
974 }
975
976 if (!auto_gen_bssid) {
977 /*
978 * We're not auto generating BSSID.
979 * Instead, get it from session entry
980 */
981 sir_copy_mac_addr(mlm_start_req->bssId,
982 session->bssId);
983 /*
984 * Start IBSS group BSSID
985 * Auto Generating BSSID.
986 */
987 auto_gen_bssid = ((mlm_start_req->bssId[0] &
988 0x01) ? true : false);
989 }
990
991 if (auto_gen_bssid) {
992 /*
993 * if BSSID is not any uc id.
994 * then use locally generated BSSID.
995 * Autogenerate the BSSID
996 */
997 lim_get_random_bssid(mac_ctx,
998 mlm_start_req->bssId);
999 mlm_start_req->bssId[0] = 0x02;
1000
1001 /*
1002 * Copy randomly generated BSSID
1003 * to the session Table
1004 */
1005 sir_copy_mac_addr(session->bssId,
1006 mlm_start_req->bssId);
1007 }
1008 }
1009 /* store the channel num in mlmstart req structure */
1010 mlm_start_req->channelNumber = session->currentOperChannel;
1011 mlm_start_req->cbMode = sme_start_bss_req->cbMode;
1012 mlm_start_req->beaconPeriod =
1013 session->beaconParams.beaconInterval;
1014
1015 if (LIM_IS_AP_ROLE(session)) {
1016 mlm_start_req->dtimPeriod = session->dtimPeriod;
1017 mlm_start_req->wps_state = session->wps_state;
1018
1019 } else {
1020 if (wlan_cfg_get_int(mac_ctx,
1021 WNI_CFG_DTIM_PERIOD, &val) != eSIR_SUCCESS)
1022 lim_log(mac_ctx, LOGP,
1023 FL("could not retrieve DTIM Period"));
1024 mlm_start_req->dtimPeriod = (uint8_t) val;
1025 }
1026
1027 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_CFP_PERIOD, &val) !=
1028 eSIR_SUCCESS)
1029 lim_log(mac_ctx, LOGP,
1030 FL("could not retrieve Beacon interval"));
1031 mlm_start_req->cfParamSet.cfpPeriod = (uint8_t) val;
1032
1033 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_CFP_MAX_DURATION, &val) !=
1034 eSIR_SUCCESS)
1035 lim_log(mac_ctx, LOGP,
1036 FL("could not retrieve CFPMaxDuration"));
1037 mlm_start_req->cfParamSet.cfpMaxDuration = (uint16_t) val;
1038
1039 /*
1040 * this may not be needed anymore now,
1041 * as rateSet is now included in the
1042 * session entry and MLM has session context.
1043 */
1044 cdf_mem_copy((void *)&mlm_start_req->rateSet,
1045 (void *)&session->rateSet,
1046 sizeof(tSirMacRateSet));
1047
1048 /* Now populate the 11n related parameters */
1049 mlm_start_req->nwType = session->nwType;
1050 mlm_start_req->htCapable = session->htCapability;
1051
1052 mlm_start_req->htOperMode = mac_ctx->lim.gHTOperMode;
1053 /* Unused */
1054 mlm_start_req->dualCTSProtection =
1055 mac_ctx->lim.gHTDualCTSProtection;
1056 mlm_start_req->txChannelWidthSet =
1057 session->htRecommendedTxWidthSet;
1058
1059 session->limRFBand = lim_get_rf_band(channel_number);
1060
1061 /* Initialize 11h Enable Flag */
1062 session->lim11hEnable = 0;
1063 if ((mlm_start_req->bssType != eSIR_IBSS_MODE) &&
1064 (SIR_BAND_5_GHZ == session->limRFBand)) {
1065 if (wlan_cfg_get_int(mac_ctx,
1066 WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
1067 lim_log(mac_ctx, LOGP,
1068 FL("Fail to get WNI_CFG_11H_ENABLED "));
1069 else
1070 session->lim11hEnable = val;
1071
1072 if (session->lim11hEnable &&
1073 (eSIR_INFRA_AP_MODE ==
1074 mlm_start_req->bssType)) {
1075 cfg_get_wmi_dfs_master_param =
1076 wlan_cfg_get_int(mac_ctx,
1077 WNI_CFG_DFS_MASTER_ENABLED,
1078 &val);
1079 session->lim11hEnable = val;
1080 }
1081 if (cfg_get_wmi_dfs_master_param != eSIR_SUCCESS)
1082 /* Failed get CFG WNI_CFG_DFS_MASTER_ENABLED */
1083 lim_log(mac_ctx, LOGE,
1084 FL("Get Fail, CFG DFS ENABLE"));
1085 }
1086
1087 if (!session->lim11hEnable) {
1088 if (cfg_set_int(mac_ctx,
1089 WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) !=
1090 eSIR_SUCCESS)
1091 /*
1092 * Failed to set the CFG param
1093 * WNI_CFG_LOCAL_POWER_CONSTRAINT
1094 */
1095 lim_log(mac_ctx, LOGE,
1096 FL("Set LOCAL_POWER_CONSTRAINT failed"));
1097 }
1098
1099 session->limPrevSmeState = session->limSmeState;
1100 session->limSmeState = eLIM_SME_WT_START_BSS_STATE;
1101 MTRACE(mac_trace
1102 (mac_ctx, TRACE_CODE_SME_STATE,
1103 session->peSessionId,
1104 session->limSmeState));
1105
1106 lim_post_mlm_message(mac_ctx, LIM_MLM_START_REQ,
1107 (uint32_t *) mlm_start_req);
1108 return;
1109 } else {
1110
1111 lim_log(mac_ctx, LOGE,
1112 FL("Received unexpected START_BSS_REQ, in state %X"),
1113 mac_ctx->lim.gLimSmeState);
1114 ret_code = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
1115 goto end;
1116 } /* if (mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) */
1117
1118free:
1119 if ((session != NULL) &&
1120 (session->pLimStartBssReq == sme_start_bss_req)) {
1121 session->pLimStartBssReq = NULL;
1122 }
1123 cdf_mem_free(sme_start_bss_req);
1124 cdf_mem_free(mlm_start_req);
1125
1126end:
1127 if (sme_start_bss_req != NULL) {
1128 sme_session_id = sme_start_bss_req->sessionId;
1129 sme_transaction_id = sme_start_bss_req->transactionId;
1130 }
1131 if (NULL != session) {
1132 pe_delete_session(mac_ctx, session);
1133 session = NULL;
1134 }
1135 lim_send_sme_start_bss_rsp(mac_ctx, eWNI_SME_START_BSS_RSP, ret_code,
1136 session, sme_session_id, sme_transaction_id);
1137}
1138
1139/**
1140 * __lim_process_sme_start_bss_req() - Call handler to start BSS
1141 *
1142 * @pMac: Global MAC context
1143 * @pMsg: Message pointer
1144 *
1145 * Wrapper for the function __lim_handle_sme_start_bss_request
1146 * This message will be defered until softmac come out of
1147 * scan mode or if we have detected radar on the current
1148 * operating channel.
1149 *
1150 * return true - If we consumed the buffer
1151 * false - If have defered the message.
1152 */
1153static bool __lim_process_sme_start_bss_req(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
1154{
1155 if (__lim_is_defered_msg_for_learn(pMac, pMsg) ||
1156 __lim_is_defered_msg_for_radar(pMac, pMsg)) {
1157 /**
1158 * If message defered, buffer is not consumed yet.
1159 * So return false
1160 */
1161 return false;
1162 }
1163
1164 __lim_handle_sme_start_bss_request(pMac, (uint32_t *) pMsg->bodyptr);
1165 return true;
1166}
1167
1168/**
1169 * lim_get_random_bssid()
1170 *
1171 * FUNCTION:This function is called to process generate the random number for bssid
1172 * This function is called to process SME_SCAN_REQ message
1173 * from HDD or upper layer application.
1174 *
1175 * LOGIC:
1176 *
1177 * ASSUMPTIONS:
1178 *
1179 * NOTE:
1180 * 1. geneartes the unique random number for bssid in ibss
1181 *
1182 * @param pMac Pointer to Global MAC structure
1183 * @param *data Pointer to bssid buffer
1184 * @return None
1185 */
1186void lim_get_random_bssid(tpAniSirGlobal pMac, uint8_t *data)
1187{
1188 uint32_t random[2];
1189 random[0] = tx_time_get();
1190 random[0] |= (random[0] << 15);
1191 random[1] = random[0] >> 1;
1192 cdf_mem_copy(data, (uint8_t *) random, sizeof(tSirMacAddr));
1193}
1194
1195static CDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
1196 tpSirSmeScanReq pScanReq)
1197{
1198 tSirScanOffloadReq *pScanOffloadReq;
1199 uint8_t *p;
1200 uint8_t *ht_cap_ie;
1201 tSirMsgQ msg;
1202 uint16_t i, len;
1203 uint16_t ht_cap_len = 0, addn_ie_len = 0;
1204#ifdef WLAN_FEATURE_11AC
1205 uint8_t *vht_cap_ie;
1206 uint16_t vht_cap_len = 0;
1207#endif /* WLAN_FEATURE_11AC */
1208 tSirRetStatus status, rc = eSIR_SUCCESS;
1209 tDot11fIEExtCap extracted_extcap = {0};
1210 bool extcap_present = true;
1211
1212 if (pScanReq->uIEFieldLen) {
1213 status = lim_strip_extcap_update_struct(pMac,
1214 (uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
1215 &pScanReq->uIEFieldLen, &extracted_extcap);
1216
1217 if (eSIR_SUCCESS != status) {
1218 extcap_present = false;
1219 lim_log(pMac, LOG1,
1220 FL("Unable to Strip ExtCap IE from Scan Req"));
1221 }
1222
1223 if (extcap_present) {
1224 lim_log(pMac, LOG1,
1225 FL("Extcap was part of SCAN IE - Updating FW"));
1226 lim_send_ext_cap_ie(pMac, pScanReq->sessionId,
1227 &extracted_extcap, true);
1228 }
1229 } else {
1230 lim_log(pMac, LOG1,
1231 FL("No IEs in the scan request from supplicant"));
1232 }
1233
1234 /**
1235 * The tSirScanOffloadReq will reserve the space for first channel,
1236 * so allocate the memory for (numChannels - 1) and uIEFieldLen
1237 */
1238 len = sizeof(tSirScanOffloadReq) +
1239 (pScanReq->channelList.numChannels - 1) + pScanReq->uIEFieldLen;
1240
1241 if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
1242 lim_log(pMac, LOG1,
1243 FL("Adding HT Caps IE since dot11mode=%d"),
1244 pScanReq->dot11mode);
1245 /* 2 bytes for EID and Length */
1246 ht_cap_len = 2 + sizeof(tHtCaps);
1247 len += ht_cap_len;
1248 addn_ie_len += ht_cap_len;
1249 }
1250
1251#ifdef WLAN_FEATURE_11AC
1252 if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
1253 lim_log(pMac, LOG1,
1254 FL("Adding VHT Caps IE since dot11mode=%d"),
1255 pScanReq->dot11mode);
1256 /* 2 bytes for EID and Length */
1257 vht_cap_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
1258 sizeof(tSirVhtMcsInfo);
1259 len += vht_cap_len;
1260 addn_ie_len += vht_cap_len;
1261 }
1262#endif /* WLAN_FEATURE_11AC */
1263
1264 pScanOffloadReq = cdf_mem_malloc(len);
1265 if (NULL == pScanOffloadReq) {
1266 lim_log(pMac, LOGE,
1267 FL("AllocateMemory failed for pScanOffloadReq"));
1268 return CDF_STATUS_E_NOMEM;
1269 }
1270
1271 cdf_mem_set((uint8_t *) pScanOffloadReq, len, 0);
1272
1273 msg.type = WMA_START_SCAN_OFFLOAD_REQ;
1274 msg.bodyptr = pScanOffloadReq;
1275 msg.bodyval = 0;
1276
1277 cdf_mem_copy((uint8_t *) pScanOffloadReq->bssId,
1278 (uint8_t *) pScanReq->bssId, sizeof(tSirMacAddr));
1279
1280 if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) {
1281 lim_log(pMac, LOGE,
1282 FL("Invalid value (%d) for numSsid"),
1283 SIR_SCAN_MAX_NUM_SSID);
1284 cdf_mem_free(pScanOffloadReq);
1285 return CDF_STATUS_E_FAILURE;
1286 }
1287
1288 pScanOffloadReq->numSsid = pScanReq->numSsid;
1289 for (i = 0; i < pScanOffloadReq->numSsid; i++) {
1290 pScanOffloadReq->ssId[i].length = pScanReq->ssId[i].length;
1291 cdf_mem_copy((uint8_t *) pScanOffloadReq->ssId[i].ssId,
1292 (uint8_t *) pScanReq->ssId[i].ssId,
1293 pScanOffloadReq->ssId[i].length);
1294 }
1295
1296 pScanOffloadReq->hiddenSsid = pScanReq->hiddenSsid;
1297 cdf_mem_copy((uint8_t *) pScanOffloadReq->selfMacAddr,
1298 (uint8_t *) pScanReq->selfMacAddr, sizeof(tSirMacAddr));
1299 pScanOffloadReq->bssType = pScanReq->bssType;
1300 pScanOffloadReq->dot11mode = pScanReq->dot11mode;
1301 pScanOffloadReq->scanType = pScanReq->scanType;
1302 pScanOffloadReq->minChannelTime = pScanReq->minChannelTime;
1303 pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime;
1304 pScanOffloadReq->restTime = pScanReq->restTime;
1305
1306 /* for normal scan, the value for p2pScanType should be 0
1307 always */
1308 if (pScanReq->p2pSearch)
1309 pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_SEARCH;
1310
1311 pScanOffloadReq->sessionId = pScanReq->sessionId;
1312 pScanOffloadReq->scan_id = pScanReq->scan_id;
1313
1314 if (pScanOffloadReq->sessionId >= pMac->lim.maxBssId)
1315 lim_log(pMac, LOGE, FL("Invalid pe sessionID : %d"),
1316 pScanOffloadReq->sessionId);
1317
1318 pScanOffloadReq->channelList.numChannels =
1319 pScanReq->channelList.numChannels;
1320 p = &(pScanOffloadReq->channelList.channelNumber[0]);
1321 for (i = 0; i < pScanOffloadReq->channelList.numChannels; i++)
1322 p[i] = pScanReq->channelList.channelNumber[i];
1323
1324 pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen;
1325 pScanOffloadReq->uIEFieldOffset = len - addn_ie_len -
1326 pScanOffloadReq->uIEFieldLen;
1327 cdf_mem_copy((uint8_t *) pScanOffloadReq +
1328 pScanOffloadReq->uIEFieldOffset,
1329 (uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
1330 pScanReq->uIEFieldLen);
1331
1332 /* Copy HT Capability info if dot11mode is HT */
1333 if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
1334 /* Populate EID and Length field here */
1335 ht_cap_ie = (uint8_t *) pScanOffloadReq +
1336 pScanOffloadReq->uIEFieldOffset +
1337 pScanOffloadReq->uIEFieldLen;
1338 cdf_mem_set(ht_cap_ie, ht_cap_len, 0);
1339 *ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID;
1340 *(ht_cap_ie + 1) = ht_cap_len - 2;
1341 lim_set_ht_caps(pMac, NULL, ht_cap_ie, ht_cap_len);
1342 pScanOffloadReq->uIEFieldLen += ht_cap_len;
1343 }
1344
1345#ifdef WLAN_FEATURE_11AC
1346 /* Copy VHT Capability info if dot11mode is VHT Capable */
1347 if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
1348 /* Populate EID and Length field here */
1349 vht_cap_ie = (uint8_t *) pScanOffloadReq +
1350 pScanOffloadReq->uIEFieldOffset +
1351 pScanOffloadReq->uIEFieldLen;
1352 cdf_mem_set(vht_cap_ie, vht_cap_len, 0);
1353 *vht_cap_ie = SIR_MAC_VHT_CAPABILITIES_EID;
1354 *(vht_cap_ie + 1) = vht_cap_len - 2;
1355 lim_set_vht_caps(pMac, NULL, vht_cap_ie, vht_cap_len);
1356 pScanOffloadReq->uIEFieldLen += vht_cap_len;
1357 }
1358#endif /* WLAN_FEATURE_11AC */
1359
1360 rc = wma_post_ctrl_msg(pMac, &msg);
1361 if (rc != eSIR_SUCCESS) {
1362 lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure"));
1363 cdf_mem_free(pScanOffloadReq);
1364 return CDF_STATUS_E_FAILURE;
1365 }
1366
1367 lim_log(pMac, LOG1, FL("Processed Offload Scan Request Successfully"));
1368
1369 return CDF_STATUS_SUCCESS;
1370}
1371
1372/**
1373 * __lim_process_sme_scan_req() - Process the SME Scan Request
1374 * @mac_ctx: Global MAC Context
1375 * @msg_buf: Buffer which contains the request and pertinent parameters
1376 *
1377 * This function is called to process SME_SCAN_REQ message
1378 * from HDD or upper layer application.
1379 *
1380 * Return: None
1381 */
1382
1383static void __lim_process_sme_scan_req(tpAniSirGlobal mac_ctx,
1384 uint32_t *msg_buf)
1385{
1386 tpSirSmeScanReq scan_req;
1387 uint8_t valid_req = 0;
1388
1389#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
1390 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SCAN_REQ_EVENT, NULL,
1391 eSIR_SUCCESS, eSIR_SUCCESS);
1392#endif
1393
1394 scan_req = (tpSirSmeScanReq) msg_buf;
1395 lim_log(mac_ctx, LOG1,
1396 FL("SME SCAN REQ id %d numChan %d min %d max %d IELen %d first %d fresh %d unique %d type %d rsp %d"),
1397 scan_req->scan_id, scan_req->channelList.numChannels,
1398 scan_req->minChannelTime, scan_req->maxChannelTime,
1399 scan_req->uIEFieldLen, scan_req->returnAfterFirstMatch,
1400 scan_req->returnFreshResults, scan_req->returnUniqueResults,
1401 scan_req->scanType, mac_ctx->lim.gLimRspReqd ? 1 : 0);
1402 /*
1403 * Since scan req always requires a response, we will overwrite response
1404 * required here. This is added esp to take care of the condition where
1405 * in p2p go case, we hold the scan req and insert single NOA. We send
1406 * the held scan request to FW later on getting start NOA ind from FW so
1407 * we lose state of the gLimRspReqd flag for the scan req if any other
1408 * request comes by then. e.g. While unit testing, we found when insert
1409 * single NOA is done, we see a get stats request which turns the flag
1410 * gLimRspReqd to false; now when we actually start the saved scan req
1411 * for init scan after getting NOA started, the gLimRspReqd being a
1412 * global flag is showing false instead of true value for this saved
1413 * scan req. Since all scan reqs coming to lim require a response,
1414 * there is no harm in setting the global flag gLimRspReqd to true here.
1415 */
1416 mac_ctx->lim.gLimRspReqd = true;
1417
1418 /*
1419 * copy the Self MAC address from SmeReq to the globalplace,
1420 * used for sending probe req
1421 */
1422 sir_copy_mac_addr(mac_ctx->lim.gSelfMacAddr, scan_req->selfMacAddr);
1423 valid_req = lim_is_sme_scan_req_valid(mac_ctx, scan_req);
1424
1425 if (!valid_req || mac_ctx->lim.scan_disabled) {
1426 lim_log(mac_ctx, LOGE,
1427 FL("Scan disabled %d, Valid Scan Req %d"),
1428 mac_ctx->lim.scan_disabled, valid_req);
1429
1430 if (mac_ctx->lim.gLimRspReqd) {
1431 mac_ctx->lim.gLimRspReqd = false;
1432
1433 lim_send_sme_scan_rsp(mac_ctx,
1434 eSIR_SME_INVALID_PARAMETERS,
1435 scan_req->sessionId,
1436 scan_req->transactionId,
1437 scan_req->scan_id);
1438 }
1439 return;
1440 }
1441
1442 /*
1443 * If scan request is received in idle, joinFailed
1444 * states or in link established state (in STA role)
1445 * or in normal state (in STA-in-IBSS/AP role) with
1446 * 'return fresh scan results' request from HDD or
1447 * it is periodic background scanning request,
1448 * trigger fresh scan request to MLM
1449 */
1450 if (__lim_fresh_scan_reqd(mac_ctx, scan_req->returnFreshResults)) {
1451
1452 mac_ctx->lim.gLim24Band11dScanDone = 0;
1453 mac_ctx->lim.gLim50Band11dScanDone = 0;
1454 mac_ctx->lim.gLimReturnAfterFirstMatch =
1455 scan_req->returnAfterFirstMatch;
1456 mac_ctx->lim.gLimReturnUniqueResults =
1457 ((scan_req->returnUniqueResults) > 0 ? true : false);
1458
1459 if (CDF_STATUS_SUCCESS !=
1460 lim_send_hal_start_scan_offload_req(mac_ctx,
1461 scan_req)) {
1462 lim_log(mac_ctx, LOGE, FL(
1463 "Couldn't send Offload scan request"));
1464 lim_send_sme_scan_rsp(mac_ctx,
1465 eSIR_SME_INVALID_PARAMETERS,
1466 scan_req->sessionId,
1467 scan_req->transactionId,
1468 scan_req->scan_id);
1469 return;
1470 }
1471 }
1472 else {
1473 /* In all other cases return 'cached' scan results */
1474 if (mac_ctx->lim.gLimRspReqd) {
1475 mac_ctx->lim.gLimRspReqd = false;
1476 lim_send_sme_scan_rsp(mac_ctx, eSIR_SME_SUCCESS,
1477 scan_req->sessionId,
1478 scan_req->transactionId, scan_req->scan_id);
1479 }
1480 }
1481}
1482
1483#ifdef FEATURE_OEM_DATA_SUPPORT
1484
1485static void __lim_process_sme_oem_data_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
1486{
1487 tpSirOemDataReq pOemDataReq;
1488 tLimMlmOemDataReq *pMlmOemDataReq;
1489
1490 pOemDataReq = (tpSirOemDataReq) pMsgBuf;
1491
1492 /* post the lim mlm message now */
1493 pMlmOemDataReq = cdf_mem_malloc(sizeof(tLimMlmOemDataReq));
1494 if (NULL == pMlmOemDataReq) {
1495 lim_log(pMac, LOGP,
1496 FL("AllocateMemory failed for mlmOemDataReq"));
1497 return;
1498 }
1499 /* Initialize this buffer */
1500 cdf_mem_set(pMlmOemDataReq, (sizeof(tLimMlmOemDataReq)), 0);
1501
1502 cdf_mem_copy(pMlmOemDataReq->selfMacAddr, pOemDataReq->selfMacAddr,
1503 sizeof(tSirMacAddr));
1504 cdf_mem_copy(pMlmOemDataReq->oemDataReq, pOemDataReq->oemDataReq,
1505 OEM_DATA_REQ_SIZE);
1506
1507 /* Issue LIM_MLM_OEM_DATA_REQ to MLM */
1508 lim_post_mlm_message(pMac, LIM_MLM_OEM_DATA_REQ,
1509 (uint32_t *) pMlmOemDataReq);
1510
1511 return;
1512
1513} /*** end __lim_process_sme_oem_data_req() ***/
1514
1515#endif /* FEATURE_OEM_DATA_SUPPORT */
1516
1517/**
1518 * __lim_process_clear_dfs_channel_list()
1519 *
1520 ***FUNCTION:
1521 ***Clear DFS channel list when country is changed/aquired.
1522 .*This message is sent from SME.
1523 *
1524 ***LOGIC:
1525 *
1526 ***ASSUMPTIONS:
1527 *
1528 ***NOTE:
1529 *
1530 * @param pMac Pointer to Global MAC structure
1531 * @param *pMsgBuf A pointer to the SME message buffer
1532 * @return None
1533 */
1534static void __lim_process_clear_dfs_channel_list(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
1535{
1536 cdf_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);
1537}
1538
1539/**
1540 * __lim_process_sme_join_req() - process SME_JOIN_REQ message
1541 * @mac_ctx: Pointer to Global MAC structure
1542 * @msg_buf: A pointer to the SME message buffer
1543 *
1544 * This function is called to process SME_JOIN_REQ message
1545 * from HDD or upper layer application.
1546 *
1547 * Return: None
1548 */
1549static void
1550__lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
1551{
1552 tpSirSmeJoinReq sme_join_req = NULL;
1553 tLimMlmJoinReq *mlm_join_req;
1554 tSirResultCodes ret_code = eSIR_SME_SUCCESS;
1555 uint32_t val = 0;
1556 uint16_t n_size;
1557 uint8_t session_id;
1558 tpPESession session = NULL;
1559 uint8_t sme_session_id;
1560 uint16_t sme_transaction_id;
1561 tPowerdBm local_power_constraint = 0, reg_max = 0;
1562 uint16_t ie_len;
1563 uint8_t *vendor_ie;
1564 tSirBssDescription bss_desc;
1565
1566/* FEATURE_WLAN_DIAG_SUPPORT */
1567#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
1568 /*
1569 * Not sending any session, since it is not created yet.
1570 * The response whould have correct state.
1571 */
1572 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0);
1573#endif /* FEATURE_WLAN_DIAG_SUPPORT */
1574
1575 lim_log(mac_ctx, LOG1, FL("Received SME_JOIN_REQ"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576
1577 /*
1578 * Expect Join request in idle state.
1579 * Reassociate request is expected in link established state.
1580 */
1581
1582 /* Global SME and LIM states are not defined yet for BT-AMP Support */
1583 if (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE) {
1584 n_size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)
1585 msg_buf);
1586
1587 sme_join_req = cdf_mem_malloc(n_size);
1588 if (NULL == sme_join_req) {
1589 lim_log(mac_ctx, LOGP,
1590 FL("AllocateMemory failed for sme_join_req"));
1591 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
1592 return;
1593 }
1594 (void)cdf_mem_set((void *)sme_join_req, n_size, 0);
1595 (void)cdf_mem_copy((void *)sme_join_req, (void *)msg_buf,
1596 n_size);
1597
1598 if (!lim_is_sme_join_req_valid(mac_ctx, sme_join_req)) {
1599 /* Received invalid eWNI_SME_JOIN_REQ */
1600 /* Log the event */
1601 lim_log(mac_ctx, LOGW,
1602 FL("SessionId:%d JOIN REQ with invalid data"),
1603 sme_join_req->sessionId);
1604 ret_code = eSIR_SME_INVALID_PARAMETERS;
1605 goto end;
1606 }
1607
Krishna Kumaar Natarajanf599c6e2015-11-03 11:44:03 -08001608 /*
1609 * Update the capability here itself as this is used in
1610 * lim_extract_ap_capability() below. If not updated issues
1611 * like not honoring power constraint on 1st association after
1612 * driver loading might occur.
1613 */
1614 lim_update_rrm_capability(mac_ctx, sme_join_req);
1615
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 bss_desc = sme_join_req->bssDescription;
1617 /* check for the existence of start BSS session */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618 session = pe_find_session_by_bssid(mac_ctx, bss_desc.bssId,
1619 &session_id);
1620
1621 if (session != NULL) {
1622 lim_log(mac_ctx, LOGE,
1623 FL("Session(%d) Already exists for BSSID: "
1624 MAC_ADDRESS_STR " in limSmeState = %X"),
1625 session_id,
1626 MAC_ADDR_ARRAY(bss_desc.bssId),
1627 session->limSmeState);
1628
1629 if (session->limSmeState == eLIM_SME_LINK_EST_STATE &&
1630 session->smeSessionId == sme_join_req->sessionId) {
1631 /*
1632 * Received eWNI_SME_JOIN_REQ for same
1633 * BSS as currently associated.
1634 * Log the event and send success
1635 */
1636 lim_log(mac_ctx, LOGW,
1637 FL("SessionId: %d"), session_id);
1638 lim_log(mac_ctx, LOGW,
1639 FL("JOIN_REQ for current joined BSS"));
1640 /* Send Join success response to host */
1641 ret_code = eSIR_SME_ALREADY_JOINED_A_BSS;
1642 session = NULL;
1643 goto end;
1644 } else {
1645 lim_log(mac_ctx, LOGE,
1646 FL("JOIN_REQ not for current joined BSS"));
1647 ret_code = eSIR_SME_REFUSED;
1648 session = NULL;
1649 goto end;
1650 }
1651 } else {
1652 /*
1653 * Session Entry does not exist for given BSSId
1654 * Try to Create a new session
1655 */
1656 session = pe_create_session(mac_ctx, bss_desc.bssId,
1657 &session_id, mac_ctx->lim.maxStation,
1658 eSIR_INFRASTRUCTURE_MODE);
1659 if (session == NULL) {
1660 lim_log(mac_ctx, LOGE,
1661 FL("Session Can not be created "));
1662 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
1663 goto end;
1664 } else
1665 lim_log(mac_ctx, LOG1,
1666 FL("SessionId:%d New session created"),
1667 session_id);
1668 }
1669 session->isAmsduSupportInAMPDU =
1670 sme_join_req->isAmsduSupportInAMPDU;
1671
1672 /*
1673 * Store Session related parameters
1674 * Store PE session Id in session Table
1675 */
1676 session->peSessionId = session_id;
1677
1678 /* store the smejoin req handle in session table */
1679 session->pLimJoinReq = sme_join_req;
1680
1681 /* Store SME session Id in sessionTable */
1682 session->smeSessionId = sme_join_req->sessionId;
1683
1684 /* Store SME transaction Id in session Table */
1685 session->transactionId = sme_join_req->transactionId;
1686
1687 /* Store beaconInterval */
1688 session->beaconParams.beaconInterval =
1689 bss_desc.beaconInterval;
1690
1691 cdf_mem_copy(&(session->htConfig), &(sme_join_req->htConfig),
1692 sizeof(session->htConfig));
1693
1694 /* Copying of bssId is already done, while creating session */
1695 sir_copy_mac_addr(session->selfMacAddr,
1696 sme_join_req->selfMacAddr);
1697 session->bssType = sme_join_req->bsstype;
1698
1699 session->statypeForBss = STA_ENTRY_PEER;
1700 session->limWmeEnabled = sme_join_req->isWMEenabled;
1701 session->limQosEnabled = sme_join_req->isQosEnabled;
1702
1703 /* Store vendor specfic IE for CISCO AP */
1704 ie_len = (bss_desc.length + sizeof(bss_desc.length) -
1705 GET_FIELD_OFFSET(tSirBssDescription, ieFields));
1706
1707 vendor_ie = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
1708 SIR_MAC_CISCO_OUI, SIR_MAC_CISCO_OUI_SIZE,
1709 ((uint8_t *)&bss_desc.ieFields), ie_len);
1710
1711 if (NULL != vendor_ie) {
1712 lim_log(mac_ctx, LOGE,
1713 FL("DUT is trying to connect to Cisco AP"));
1714 session->isCiscoVendorAP = true;
1715 } else {
1716 session->isCiscoVendorAP = false;
1717 }
1718
1719 /* Copy the dot 11 mode in to the session table */
1720
1721 session->dot11mode = sme_join_req->dot11mode;
1722#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1723 session->cc_switch_mode = sme_join_req->cc_switch_mode;
1724#endif
1725 session->nwType = bss_desc.nwType;
1726 session->enableAmpduPs = sme_join_req->enableAmpduPs;
1727 session->enableHtSmps = sme_join_req->enableHtSmps;
1728 session->htSmpsvalue = sme_join_req->htSmps;
1729
1730 /*Store Persona */
1731 session->pePersona = sme_join_req->staPersona;
1732 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
1733 FL("PE PERSONA=%d cbMode %u"),
1734 session->pePersona, sme_join_req->cbMode);
1735 if (mac_ctx->roam.configParam.enable2x2)
1736 session->nss = 2;
1737 else
1738 session->nss = 1;
1739#ifdef WLAN_FEATURE_11AC
1740 session->vhtCapability =
1741 IS_DOT11_MODE_VHT(session->dot11mode);
1742 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
1743 "***__lim_process_sme_join_req: vhtCapability=%d****",
1744 session->vhtCapability);
1745 if (session->vhtCapability) {
1746 if (session->pePersona == CDF_STA_MODE) {
1747 session->txBFIniFeatureEnabled =
1748 sme_join_req->txBFIniFeatureEnabled;
1749 } else {
1750 session->txBFIniFeatureEnabled = 0;
1751 }
1752 session->txMuBformee = sme_join_req->txMuBformee;
1753 session->enableVhtpAid =
1754 sme_join_req->enableVhtpAid;
1755 session->enableVhtGid =
1756 sme_join_req->enableVhtGid;
1757
1758 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
1759 FL("***txBFIniFeatureEnabled=%d***"),
1760 session->txBFIniFeatureEnabled);
1761 if (wlan_cfg_get_int(mac_ctx,
1762 WNI_CFG_VHT_SU_BEAMFORMER_CAP, &val) !=
1763 eSIR_SUCCESS)
1764 lim_log(mac_ctx, LOGE, FL(
1765 "cfg get vht su bformer failed"));
1766
1767 session->enable_su_tx_bformer = val;
1768 lim_log(mac_ctx, LOGE, FL("vht su tx bformer %d"), val);
1769 }
1770 if (session->vhtCapability && session->txBFIniFeatureEnabled) {
1771 if (cfg_set_int(mac_ctx, WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
1772 session->txBFIniFeatureEnabled) !=
1773 eSIR_SUCCESS) {
1774 /*
1775 * Set failed for
1776 * CFG_VHT_SU_BEAMFORMEE_CAP
1777 */
1778 lim_log(mac_ctx, LOGP,
1779 FL("Failed CFG_VHT_SU_BEAMFORMEE_CAP"));
1780 ret_code = eSIR_LOGP_EXCEPTION;
1781 goto end;
1782 }
1783 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
1784 "%s: txBFCsnValue=%d", __func__,
1785 sme_join_req->txBFCsnValue);
1786 if (cfg_set_int(mac_ctx,
1787 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
1788 sme_join_req->txBFCsnValue) != eSIR_SUCCESS) {
1789 /*
1790 * Set Failed for CFG
1791 * CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED
1792 */
1793 lim_log(mac_ctx, LOGP, FL("Set Fail CFG"));
1794 ret_code = eSIR_LOGP_EXCEPTION;
1795 goto end;
1796 }
1797 }
1798#endif
1799
1800 /*Phy mode */
1801 session->gLimPhyMode = bss_desc.nwType;
1802 handle_ht_capabilityand_ht_info(mac_ctx, session);
1803 /* Copy The channel Id to the session Table */
1804 session->currentOperChannel = bss_desc.channelId;
1805 /* cbMode is already merged value of peer and self -
1806 * done by csr in csr_get_cb_mode_from_ies */
1807 session->htSupportedChannelWidthSet =
1808 (sme_join_req->cbMode) ? 1 : 0;
1809 session->htRecommendedTxWidthSet =
1810 session->htSupportedChannelWidthSet;
1811 session->htSecondaryChannelOffset = sme_join_req->cbMode;
1812
1813 if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == sme_join_req->cbMode) {
1814 session->ch_center_freq_seg0 =
1815 session->currentOperChannel - 2;
1816 session->ch_width = CH_WIDTH_40MHZ;
1817 } else if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
1818 sme_join_req->cbMode) {
1819 session->ch_center_freq_seg0 =
1820 session->currentOperChannel + 2;
1821 session->ch_width = CH_WIDTH_40MHZ;
1822 } else {
1823 session->ch_center_freq_seg0 = 0;
1824 session->ch_width = CH_WIDTH_20MHZ;
1825 }
1826
1827 /* Record if management frames need to be protected */
1828#ifdef WLAN_FEATURE_11W
1829 if (eSIR_ED_AES_128_CMAC == sme_join_req->MgmtEncryptionType) {
1830 CDF_STATUS cdf_status;
1831 session->limRmfEnabled = 1;
1832 session->pmfComebackTimerInfo.pMac = mac_ctx;
1833 session->pmfComebackTimerInfo.sessionID =
1834 session_id;
1835 cdf_status = cdf_mc_timer_init(
1836 &session->pmfComebackTimer,
1837 CDF_TIMER_TYPE_SW,
1838 lim_pmf_comeback_timer_callback,
1839 (void *)&session->pmfComebackTimerInfo);
1840 if (CDF_STATUS_SUCCESS != cdf_status) {
1841 lim_log(mac_ctx, LOGP,
1842 FL("cannot init pmf comeback timer."));
1843 ret_code = eSIR_LOGP_EXCEPTION;
1844 goto end;
1845 }
1846 } else {
1847 session->limRmfEnabled = 0;
1848 }
1849#endif
1850
1851#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
1852 session->rssi = bss_desc.rssi;
1853#endif
1854
1855 /* Copy the SSID from smejoinreq to session entry */
1856 session->ssId.length = sme_join_req->ssId.length;
1857 cdf_mem_copy(session->ssId.ssId, sme_join_req->ssId.ssId,
1858 session->ssId.length);
1859
1860 /*
1861 * Determin 11r or ESE connection based on input from SME
1862 * which inturn is dependent on the profile the user wants
1863 * to connect to, So input is coming from supplicant
1864 */
1865#ifdef WLAN_FEATURE_VOWIFI_11R
1866 session->is11Rconnection = sme_join_req->is11Rconnection;
1867#endif
1868#ifdef FEATURE_WLAN_ESE
1869 session->isESEconnection = sme_join_req->isESEconnection;
1870#endif
1871#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
1872 session->isFastTransitionEnabled =
1873 sme_join_req->isFastTransitionEnabled;
1874#endif
1875
1876#ifdef FEATURE_WLAN_LFR
1877 session->isFastRoamIniFeatureEnabled =
1878 sme_join_req->isFastRoamIniFeatureEnabled;
1879#endif
1880 session->txLdpcIniFeatureEnabled =
1881 sme_join_req->txLdpcIniFeatureEnabled;
1882
1883 if (session->bssType == eSIR_INFRASTRUCTURE_MODE) {
1884 session->limSystemRole = eLIM_STA_ROLE;
1885 } else if (session->bssType == eSIR_BTAMP_AP_MODE) {
1886 session->limSystemRole = eLIM_BT_AMP_STA_ROLE;
1887 } else {
1888 /*
1889 * Throw an error and return and make
1890 * sure to delete the session.
1891 */
1892 lim_log(mac_ctx, LOGE,
1893 FL("recvd JOIN_REQ with invalid bss type %d"),
1894 session->bssType);
1895 ret_code = eSIR_SME_INVALID_PARAMETERS;
1896 goto end;
1897 }
1898
1899 if (sme_join_req->addIEScan.length)
1900 cdf_mem_copy(&session->pLimJoinReq->addIEScan,
1901 &sme_join_req->addIEScan, sizeof(tSirAddie));
1902
1903 if (sme_join_req->addIEAssoc.length)
1904 cdf_mem_copy(&session->pLimJoinReq->addIEAssoc,
1905 &sme_join_req->addIEAssoc, sizeof(tSirAddie));
1906
1907 val = sizeof(tLimMlmJoinReq) +
1908 session->pLimJoinReq->bssDescription.length + 2;
1909 mlm_join_req = cdf_mem_malloc(val);
1910 if (NULL == mlm_join_req) {
1911 lim_log(mac_ctx, LOGP,
1912 FL("AllocateMemory failed for mlmJoinReq"));
1913 return;
1914 }
1915 (void)cdf_mem_set((void *)mlm_join_req, val, 0);
1916
1917 /* PE SessionId is stored as a part of JoinReq */
1918 mlm_join_req->sessionId = session->peSessionId;
1919
1920 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_JOIN_FAILURE_TIMEOUT,
1921 (uint32_t *) &mlm_join_req->joinFailureTimeout) !=
1922 eSIR_SUCCESS) {
1923 lim_log(mac_ctx, LOGP,
1924 FL("couldn't retrieve JoinFailureTimer value"
1925 " setting to default value"));
1926 mlm_join_req->joinFailureTimeout =
1927 WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF;
1928 }
1929
1930 /* copy operational rate from session */
1931 cdf_mem_copy((void *)&session->rateSet,
1932 (void *)&sme_join_req->operationalRateSet,
1933 sizeof(tSirMacRateSet));
1934 cdf_mem_copy((void *)&session->extRateSet,
1935 (void *)&sme_join_req->extendedRateSet,
1936 sizeof(tSirMacRateSet));
1937 /*
1938 * this may not be needed anymore now, as rateSet is now
1939 * included in the session entry and MLM has session context.
1940 */
1941 cdf_mem_copy((void *)&mlm_join_req->operationalRateSet,
1942 (void *)&session->rateSet,
1943 sizeof(tSirMacRateSet));
1944
1945 session->encryptType = sme_join_req->UCEncryptionType;
1946
1947 mlm_join_req->bssDescription.length =
1948 session->pLimJoinReq->bssDescription.length;
1949
1950 cdf_mem_copy((uint8_t *) &mlm_join_req->bssDescription.bssId,
1951 (uint8_t *)
1952 &session->pLimJoinReq->bssDescription.bssId,
1953 session->pLimJoinReq->bssDescription.length + 2);
1954
1955 session->limCurrentBssCaps =
1956 session->pLimJoinReq->bssDescription.capabilityInfo;
1957
1958 reg_max = cfg_get_regulatory_max_transmit_power(mac_ctx,
1959 session->currentOperChannel);
1960 local_power_constraint = reg_max;
1961
1962 lim_extract_ap_capability(mac_ctx,
1963 (uint8_t *)
1964 session->pLimJoinReq->bssDescription.ieFields,
1965 lim_get_ielen_from_bss_description(
1966 &session->pLimJoinReq->bssDescription),
1967 &session->limCurrentBssQosCaps,
1968 &session->limCurrentBssPropCap,
1969 &session->gLimCurrentBssUapsd,
1970 &local_power_constraint, session);
1971
1972#ifdef FEATURE_WLAN_ESE
1973 session->maxTxPower = lim_get_max_tx_power(reg_max,
1974 local_power_constraint,
1975 mac_ctx->roam.configParam.nTxPowerCap);
1976#else
1977 session->maxTxPower =
1978 CDF_MIN(reg_max, (local_power_constraint));
1979#endif
1980#if defined WLAN_VOWIFI_DEBUG
1981 lim_log(mac_ctx, LOGE,
1982 "Regulatory max = %d, local power constraint = %d"
1983 reg_max, local_power_constraint);
1984 lim_log(mac_ctx, LOGE, FL(" max tx = %d"),
1985 session->maxTxPower);
1986#endif
1987
1988 if (session->gLimCurrentBssUapsd) {
1989 session->gUapsdPerAcBitmask =
1990 session->pLimJoinReq->uapsdPerAcBitmask;
1991 lim_log(mac_ctx, LOG1,
1992 FL("UAPSD flag for all AC - 0x%2x"),
1993 session->gUapsdPerAcBitmask);
1994
1995 /* resetting the dynamic uapsd mask */
1996 session->gUapsdPerAcDeliveryEnableMask = 0;
1997 session->gUapsdPerAcTriggerEnableMask = 0;
1998 }
1999
2000 session->limRFBand =
2001 lim_get_rf_band(session->currentOperChannel);
2002
2003 /* Initialize 11h Enable Flag */
2004 if (SIR_BAND_5_GHZ == session->limRFBand) {
2005 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED,
2006 &val) != eSIR_SUCCESS) {
2007 lim_log(mac_ctx, LOGP,
2008 FL("Fail to get WNI_CFG_11H_ENABLED "));
2009 session->lim11hEnable =
2010 WNI_CFG_11H_ENABLED_STADEF;
2011 } else {
2012 session->lim11hEnable = val;
2013 }
2014 } else {
2015 session->lim11hEnable = 0;
2016 }
2017
2018 /*
2019 * To care of the scenario when STA transitions from
2020 * IBSS to Infrastructure mode.
2021 */
2022 mac_ctx->lim.gLimIbssCoalescingHappened = false;
2023
2024 session->limPrevSmeState = session->limSmeState;
2025 session->limSmeState = eLIM_SME_WT_JOIN_STATE;
2026 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
2027 session->peSessionId,
2028 session->limSmeState));
2029
2030 lim_log(mac_ctx, LOG1,
2031 FL("SME JoinReq:Sessionid %d SSID len %d SSID : %s Channel %d, BSSID " MAC_ADDRESS_STR),
2032 mlm_join_req->sessionId, session->ssId.length,
2033 session->ssId.ssId, session->currentOperChannel,
2034 MAC_ADDR_ARRAY(session->bssId));
2035
2036 /* Indicate whether spectrum management is enabled */
2037 session->spectrumMgtEnabled =
2038 sme_join_req->spectrumMgtIndicator;
2039
2040 /* Enable the spectrum management if this is a DFS channel */
2041 if (session->country_info_present &&
2042 lim_isconnected_on_dfs_channel(
2043 session->currentOperChannel))
2044 session->spectrumMgtEnabled = true;
2045
2046 session->isOSENConnection = sme_join_req->isOSENConnection;
2047
2048 lim_log(mac_ctx, LOG1,
2049 FL("SessionId:%d MLM_JOIN_REQ is posted to MLM SM"),
2050 mlm_join_req->sessionId);
2051 /* Issue LIM_MLM_JOIN_REQ to MLM */
2052 lim_post_mlm_message(mac_ctx, LIM_MLM_JOIN_REQ,
2053 (uint32_t *) mlm_join_req);
2054 return;
2055
2056 } else {
2057 /* Received eWNI_SME_JOIN_REQ un expected state */
2058 lim_log(mac_ctx, LOGE,
2059 FL("received unexpected SME_JOIN_REQ in state %X"),
2060 mac_ctx->lim.gLimSmeState);
2061 lim_print_sme_state(mac_ctx, LOGE, mac_ctx->lim.gLimSmeState);
2062 ret_code = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
2063 session = NULL;
2064 goto end;
2065 }
2066
2067end:
2068 sme_session_id = sme_join_req->sessionId;
2069 sme_transaction_id = sme_join_req->transactionId;
2070
2071 if (sme_join_req) {
2072 cdf_mem_free(sme_join_req);
2073 sme_join_req = NULL;
2074 if (NULL != session)
2075 session->pLimJoinReq = NULL;
2076 }
2077 if (ret_code != eSIR_SME_SUCCESS) {
2078 if (NULL != session) {
2079 pe_delete_session(mac_ctx, session);
2080 session = NULL;
2081 }
2082 }
2083 lim_log(mac_ctx, LOG1,
2084 FL("Send failure status on sessionid: %d with ret_code = %d"),
2085 sme_session_id, ret_code);
2086 lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, ret_code,
2087 eSIR_MAC_UNSPEC_FAILURE_STATUS, session, sme_session_id,
2088 sme_transaction_id);
2089}
2090
2091#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI
2092uint8_t lim_get_max_tx_power(tPowerdBm regMax, tPowerdBm apTxPower,
2093 uint8_t iniTxPower)
2094{
2095 uint8_t maxTxPower = 0;
2096 uint8_t txPower = CDF_MIN(regMax, (apTxPower));
2097 txPower = CDF_MIN(txPower, iniTxPower);
2098 if ((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP))
2099 maxTxPower = txPower;
2100 else if (txPower < MIN_TX_PWR_CAP)
2101 maxTxPower = MIN_TX_PWR_CAP;
2102 else
2103 maxTxPower = MAX_TX_PWR_CAP;
2104
2105 return maxTxPower;
2106}
2107#endif
2108
2109/**
2110 * __lim_process_sme_reassoc_req() - process reassoc req
2111 *
2112 * @mac_ctx: Pointer to Global MAC structure
2113 * @msg_buf: pointer to the SME message buffer
2114 *
2115 * This function is called to process SME_REASSOC_REQ message
2116 * from HDD or upper layer application.
2117 *
2118 * Return: None
2119 */
2120
2121static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
2122 uint32_t *msg_buf)
2123{
2124 uint16_t caps;
2125 uint32_t val;
2126 tpSirSmeJoinReq reassoc_req = NULL;
2127 tLimMlmReassocReq *mlm_reassoc_req;
2128 tSirResultCodes ret_code = eSIR_SME_SUCCESS;
2129 tpPESession session_entry = NULL;
2130 uint8_t session_id;
2131 uint8_t sme_session_id;
2132 uint16_t transaction_id;
2133 tPowerdBm local_pwr_constraint = 0, reg_max = 0;
2134 uint32_t tele_bcn_en = 0;
2135 uint16_t size;
2136
2137 lim_log(mac_ctx, LOG3, FL("Received REASSOC_REQ"));
2138
2139 size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)msg_buf);
2140 reassoc_req = cdf_mem_malloc(size);
2141 if (NULL == reassoc_req) {
2142 lim_log(mac_ctx, LOGP,
2143 FL("call to AllocateMemory failed for reassoc_req"));
2144
2145 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
2146 goto end;
2147 }
2148 (void)cdf_mem_set((void *)reassoc_req, size, 0);
2149 (void)cdf_mem_copy((void *)reassoc_req, (void *)msg_buf, size);
2150
2151 if (!lim_is_sme_join_req_valid(mac_ctx,
2152 (tpSirSmeJoinReq)reassoc_req)) {
2153 /*
2154 * Received invalid eWNI_SME_REASSOC_REQ
2155 */
2156 lim_log(mac_ctx, LOGW,
2157 FL("received SME_REASSOC_REQ with invalid data"));
2158
2159 ret_code = eSIR_SME_INVALID_PARAMETERS;
2160 goto end;
2161 }
2162
2163 session_entry = pe_find_session_by_bssid(mac_ctx,
2164 reassoc_req->bssDescription.bssId,
2165 &session_id);
2166 if (session_entry == NULL) {
2167 lim_print_mac_addr(mac_ctx, reassoc_req->bssDescription.bssId,
2168 LOGE);
2169 lim_log(mac_ctx, LOGE,
2170 FL("Session does not exist for given bssId"));
2171 ret_code = eSIR_SME_INVALID_PARAMETERS;
2172 goto end;
2173 }
2174#ifdef FEATURE_WLAN_DIAG_SUPPORT /* FEATURE_WLAN_DIAG_SUPPORT */
2175 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_REQ_EVENT,
2176 session_entry, eSIR_SUCCESS, eSIR_SUCCESS);
2177#endif /* FEATURE_WLAN_DIAG_SUPPORT */
2178 /* mac_ctx->lim.gpLimReassocReq = reassoc_req;//TO SUPPORT BT-AMP */
2179
2180 /* Store the reassoc handle in the session Table */
2181 session_entry->pLimReAssocReq = reassoc_req;
2182
2183 session_entry->dot11mode = reassoc_req->dot11mode;
2184 session_entry->vhtCapability =
2185 IS_DOT11_MODE_VHT(reassoc_req->dot11mode);
2186 /*
2187 * Reassociate request is expected
2188 * in link established state only.
2189 */
2190
2191 if (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE) {
2192#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
2193 defined(FEATURE_WLAN_LFR)
2194 if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) {
2195 /*
2196 * May be from 11r FT pre-auth. So lets check it
2197 * before we bail out
2198 */
2199 lim_log(mac_ctx, LOG1, FL(
2200 "Session in reassoc state is %d"),
2201 session_entry->peSessionId);
2202
2203 /* Make sure its our preauth bssid */
2204 if (!cdf_mem_compare(reassoc_req->bssDescription.bssId,
2205 session_entry->limReAssocbssId,
2206 6)) {
2207 lim_print_mac_addr(mac_ctx,
2208 reassoc_req->bssDescription.
2209 bssId, LOGE);
2210 lim_log(mac_ctx, LOGP,
2211 FL("Unknown bssId in reassoc state"));
2212 ret_code = eSIR_SME_INVALID_PARAMETERS;
2213 goto end;
2214 }
2215
2216 lim_process_mlm_ft_reassoc_req(mac_ctx, msg_buf,
2217 session_entry);
2218 return;
2219 }
2220#endif
2221 /*
2222 * Should not have received eWNI_SME_REASSOC_REQ
2223 */
2224 lim_log(mac_ctx, LOGE,
2225 FL("received unexpected SME_REASSOC_REQ in state %X"),
2226 session_entry->limSmeState);
2227 lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState);
2228
2229 ret_code = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
2230 goto end;
2231 }
2232
2233 cdf_mem_copy(session_entry->limReAssocbssId,
2234 session_entry->pLimReAssocReq->bssDescription.bssId,
2235 sizeof(tSirMacAddr));
2236
2237 session_entry->limReassocChannelId =
2238 session_entry->pLimReAssocReq->bssDescription.channelId;
2239
2240 session_entry->reAssocHtSupportedChannelWidthSet =
2241 (session_entry->pLimReAssocReq->cbMode) ? 1 : 0;
2242 session_entry->reAssocHtRecommendedTxWidthSet =
2243 session_entry->reAssocHtSupportedChannelWidthSet;
2244 session_entry->reAssocHtSecondaryChannelOffset =
2245 session_entry->pLimReAssocReq->cbMode;
2246
2247 session_entry->limReassocBssCaps =
2248 session_entry->pLimReAssocReq->bssDescription.capabilityInfo;
2249 reg_max = cfg_get_regulatory_max_transmit_power(mac_ctx,
2250 session_entry->currentOperChannel);
2251 local_pwr_constraint = reg_max;
2252
2253 lim_extract_ap_capability(mac_ctx,
2254 (uint8_t *)session_entry->pLimReAssocReq->bssDescription.ieFields,
2255 lim_get_ielen_from_bss_description(
2256 &session_entry->pLimReAssocReq->bssDescription),
2257 &session_entry->limReassocBssQosCaps,
2258 &session_entry->limReassocBssPropCap,
2259 &session_entry->gLimCurrentBssUapsd,
2260 &local_pwr_constraint, session_entry);
2261 session_entry->maxTxPower = CDF_MIN(reg_max, (local_pwr_constraint));
2262#if defined WLAN_VOWIFI_DEBUG
2263 lim_log(mac_ctx, LOGE,
2264 "Regulatory max = %d, local pwr constraint = %d, max tx = %d",
2265 reg_max, local_pwr_constraint,
2266 session_entry->maxTxPower);
2267#endif
2268 /* Copy the SSID from session entry to local variable */
2269 session_entry->limReassocSSID.length = reassoc_req->ssId.length;
2270 cdf_mem_copy(session_entry->limReassocSSID.ssId,
2271 reassoc_req->ssId.ssId,
2272 session_entry->limReassocSSID.length);
2273 if (session_entry->gLimCurrentBssUapsd) {
2274 session_entry->gUapsdPerAcBitmask =
2275 session_entry->pLimReAssocReq->uapsdPerAcBitmask;
2276 lim_log(mac_ctx, LOG1,
2277 FL("UAPSD flag for all AC - 0x%2x"),
2278 session_entry->gUapsdPerAcBitmask);
2279 }
2280
2281 mlm_reassoc_req = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
2282 if (NULL == mlm_reassoc_req) {
2283 lim_log(mac_ctx, LOGP,
2284 FL("call to AllocateMemory failed for mlmReassocReq"));
2285
2286 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
2287 goto end;
2288 }
2289
2290 cdf_mem_copy(mlm_reassoc_req->peerMacAddr,
2291 session_entry->limReAssocbssId, sizeof(tSirMacAddr));
2292
2293 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
2294 (uint32_t *)&mlm_reassoc_req->reassocFailureTimeout) !=
2295 eSIR_SUCCESS) {
2296 /*
2297 * Could not get ReassocFailureTimeout value
2298 * from CFG. Log error.
2299 */
2300 lim_log(mac_ctx, LOGP,
2301 FL("could not retrieve ReassocFailureTimeout value"));
2302 }
2303
2304 if (cfg_get_capability_info(mac_ctx, &caps, session_entry) !=
2305 eSIR_SUCCESS) {
2306 /*
2307 * Could not get Capabilities value
2308 * from CFG. Log error.
2309 */
2310 lim_log(mac_ctx, LOGP, FL(
2311 "could not retrieve Capabilities value"));
2312 }
2313 mlm_reassoc_req->capabilityInfo = caps;
2314
2315 /* Update PE session_id */
2316 mlm_reassoc_req->sessionId = session_id;
2317
2318 /*
2319 * If telescopic beaconing is enabled, set listen interval to
2320 * WNI_CFG_TELE_BCN_MAX_LI
2321 */
2322 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_WAKEUP_EN,
2323 &tele_bcn_en) != eSIR_SUCCESS)
2324 lim_log(mac_ctx, LOGP,
2325 FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));
2326
2327 val = WNI_CFG_LISTEN_INTERVAL_STADEF;
2328
2329 if (tele_bcn_en) {
2330 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
2331 eSIR_SUCCESS)
2332 /*
2333 * Could not get ListenInterval value
2334 * from CFG. Log error.
2335 */
2336 lim_log(mac_ctx, LOGP,
2337 FL("could not retrieve ListenInterval"));
2338 } else {
2339 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_LISTEN_INTERVAL, &val) !=
2340 eSIR_SUCCESS)
2341 /*
2342 * Could not get ListenInterval value
2343 * from CFG. Log error.
2344 */
2345 lim_log(mac_ctx, LOGP,
2346 FL("could not retrieve ListenInterval"));
2347 }
2348
2349 mlm_reassoc_req->listenInterval = (uint16_t) val;
2350
2351 /* Indicate whether spectrum management is enabled */
2352 session_entry->spectrumMgtEnabled = reassoc_req->spectrumMgtIndicator;
2353
2354 /* Enable the spectrum management if this is a DFS channel */
2355 if (session_entry->country_info_present &&
2356 lim_isconnected_on_dfs_channel(
2357 session_entry->currentOperChannel))
2358 session_entry->spectrumMgtEnabled = true;
2359
2360 session_entry->limPrevSmeState = session_entry->limSmeState;
2361 session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
2362
2363 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
2364 session_entry->peSessionId,
2365 session_entry->limSmeState));
2366
2367 lim_post_mlm_message(mac_ctx,
2368 LIM_MLM_REASSOC_REQ, (uint32_t *)mlm_reassoc_req);
2369 return;
2370end:
2371 if (reassoc_req) {
2372 cdf_mem_free(reassoc_req);
2373 if (session_entry)
2374 session_entry->pLimReAssocReq = NULL;
2375 }
2376
2377 if (session_entry) {
2378 /*
2379 * error occurred after we determined the session so extract
2380 * session and transaction info from there
2381 */
2382 sme_session_id = session_entry->smeSessionId;
2383 transaction_id = session_entry->transactionId;
2384 } else
2385 /*
2386 * error occurred before or during the time we determined
2387 * the session so extract the session and transaction info
2388 * from the message
2389 */
2390 lim_get_session_info(mac_ctx, (uint8_t *) msg_buf,
2391 &sme_session_id, &transaction_id);
2392
2393 /*
2394 * Send Reassoc failure response to host
2395 * (note session_entry may be NULL, but that's OK)
2396 */
2397 lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
2398 ret_code, eSIR_MAC_UNSPEC_FAILURE_STATUS,
2399 session_entry, sme_session_id,
2400 transaction_id);
2401}
2402
2403bool send_disassoc_frame = 1;
2404/**
2405 * __lim_process_sme_disassoc_req()
2406 *
2407 ***FUNCTION:
2408 * This function is called to process SME_DISASSOC_REQ message
2409 * from HDD or upper layer application.
2410 *
2411 ***LOGIC:
2412 *
2413 ***ASSUMPTIONS:
2414 *
2415 ***NOTE:
2416 *
2417 * @param pMac Pointer to Global MAC structure
2418 * @param *pMsgBuf A pointer to the SME message buffer
2419 * @return None
2420 */
2421
2422static void __lim_process_sme_disassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
2423{
2424 uint16_t disassocTrigger, reasonCode;
2425 tLimMlmDisassocReq *pMlmDisassocReq;
2426 tSirResultCodes retCode = eSIR_SME_SUCCESS;
2427 tSirSmeDisassocReq smeDisassocReq;
2428 tpPESession psessionEntry = NULL;
2429 uint8_t sessionId;
2430 uint8_t smesessionId;
2431 uint16_t smetransactionId;
2432
2433 if (pMsgBuf == NULL) {
2434 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
2435 return;
2436 }
2437
2438 cdf_mem_copy(&smeDisassocReq, pMsgBuf, sizeof(tSirSmeDisassocReq));
2439 smesessionId = smeDisassocReq.sessionId;
2440 smetransactionId = smeDisassocReq.transactionId;
2441 if (!lim_is_sme_disassoc_req_valid(pMac,
2442 &smeDisassocReq,
2443 psessionEntry)) {
2444 PELOGE(lim_log(pMac, LOGE,
2445 FL("received invalid SME_DISASSOC_REQ message"));)
2446 if (pMac->lim.gLimRspReqd) {
2447 pMac->lim.gLimRspReqd = false;
2448
2449 retCode = eSIR_SME_INVALID_PARAMETERS;
2450 disassocTrigger = eLIM_HOST_DISASSOC;
2451 goto sendDisassoc;
2452 }
2453
2454 return;
2455 }
2456
2457 psessionEntry = pe_find_session_by_bssid(pMac,
2458 smeDisassocReq.bssId,
2459 &sessionId);
2460 if (psessionEntry == NULL) {
2461 lim_log(pMac, LOGE,
2462 FL("session does not exist for given bssId "
2463 MAC_ADDRESS_STR),
2464 MAC_ADDR_ARRAY(smeDisassocReq.bssId));
2465 retCode = eSIR_SME_INVALID_PARAMETERS;
2466 disassocTrigger = eLIM_HOST_DISASSOC;
2467 goto sendDisassoc;
2468 }
2469 lim_log(pMac, LOG1,
2470 FL("received DISASSOC_REQ message on sessionid %d Systemrole %d Reason: %u SmeState: %d from: "
2471 MAC_ADDRESS_STR), smesessionId,
2472 GET_LIM_SYSTEM_ROLE(psessionEntry), smeDisassocReq.reasonCode,
2473 pMac->lim.gLimSmeState,
2474 MAC_ADDR_ARRAY(smeDisassocReq.peerMacAddr));
2475
2476#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
2477 lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry,
2478 0, smeDisassocReq.reasonCode);
2479#endif /* FEATURE_WLAN_DIAG_SUPPORT */
2480
2481 /* Update SME session Id and SME transaction ID */
2482
2483 psessionEntry->smeSessionId = smesessionId;
2484 psessionEntry->transactionId = smetransactionId;
2485
2486 switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
2487 case eLIM_STA_ROLE:
2488 case eLIM_BT_AMP_STA_ROLE:
2489 switch (psessionEntry->limSmeState) {
2490 case eLIM_SME_ASSOCIATED_STATE:
2491 case eLIM_SME_LINK_EST_STATE:
2492 psessionEntry->limPrevSmeState =
2493 psessionEntry->limSmeState;
2494 psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
2495#ifdef FEATURE_WLAN_TDLS
2496 /* Delete all TDLS peers connected before leaving BSS */
2497 lim_delete_tdls_peers(pMac, psessionEntry);
2498#endif
2499 MTRACE(mac_trace
2500 (pMac, TRACE_CODE_SME_STATE,
2501 psessionEntry->peSessionId,
2502 psessionEntry->limSmeState));
2503 lim_log(pMac, LOG1,
2504 FL("Rcvd SME_DISASSOC_REQ while in limSmeState: %d "),
2505 psessionEntry->limSmeState);
2506 break;
2507
2508 case eLIM_SME_WT_DEAUTH_STATE:
2509 /* PE shall still process the DISASSOC_REQ and proceed with
2510 * link tear down even if it had already sent a DEAUTH_IND to
2511 * to SME. pMac->lim.gLimPrevSmeState shall remain the same as
2512 * its been set when PE entered WT_DEAUTH_STATE.
2513 */
2514 psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
2515 MTRACE(mac_trace
2516 (pMac, TRACE_CODE_SME_STATE,
2517 psessionEntry->peSessionId,
2518 psessionEntry->limSmeState));
2519 lim_log(pMac, LOG1,
2520 FL("Rcvd SME_DISASSOC_REQ while in SME_WT_DEAUTH_STATE. "));
2521 break;
2522
2523 case eLIM_SME_WT_DISASSOC_STATE:
2524 /* PE Recieved a Disassoc frame. Normally it gets DISASSOC_CNF but it
2525 * received DISASSOC_REQ. Which means host is also trying to disconnect.
2526 * PE can continue processing DISASSOC_REQ and send the response instead
2527 * of failing the request. SME will anyway ignore DEAUTH_IND that was sent
2528 * for disassoc frame.
2529 *
2530 * It will send a disassoc, which is ok. However, we can use the global flag
2531 * sendDisassoc to not send disassoc frame.
2532 */
2533 lim_log(pMac, LOG1,
2534 FL("Rcvd SME_DISASSOC_REQ while in SME_WT_DISASSOC_STATE. "));
2535 break;
2536
2537 case eLIM_SME_JOIN_FAILURE_STATE: {
2538 /* Already in Disconnected State, return success */
2539 lim_log(pMac, LOG1,
2540 FL("Rcvd SME_DISASSOC_REQ while in eLIM_SME_JOIN_FAILURE_STATE. "));
2541 if (pMac->lim.gLimRspReqd) {
2542 retCode = eSIR_SME_SUCCESS;
2543 disassocTrigger = eLIM_HOST_DISASSOC;
2544 goto sendDisassoc;
2545 }
2546 }
2547 break;
2548 default:
2549 /**
2550 * STA is not currently associated.
2551 * Log error and send response to host
2552 */
2553 lim_log(pMac, LOGE,
2554 FL("received unexpected SME_DISASSOC_REQ in state %X"),
2555 psessionEntry->limSmeState);
2556 lim_print_sme_state(pMac, LOGE,
2557 psessionEntry->limSmeState);
2558
2559 if (pMac->lim.gLimRspReqd) {
2560 if (psessionEntry->limSmeState !=
2561 eLIM_SME_WT_ASSOC_STATE)
2562 pMac->lim.gLimRspReqd = false;
2563
2564 retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
2565 disassocTrigger = eLIM_HOST_DISASSOC;
2566 goto sendDisassoc;
2567 }
2568
2569 return;
2570 }
2571
2572 break;
2573
2574 case eLIM_AP_ROLE:
2575 case eLIM_BT_AMP_AP_ROLE:
2576 /* Fall through */
2577 break;
2578
2579 case eLIM_STA_IN_IBSS_ROLE:
2580 default:
2581 /* eLIM_UNKNOWN_ROLE */
2582 lim_log(pMac, LOGE,
2583 FL("received unexpected SME_DISASSOC_REQ for role %d"),
2584 GET_LIM_SYSTEM_ROLE(psessionEntry));
2585
2586 retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
2587 disassocTrigger = eLIM_HOST_DISASSOC;
2588 goto sendDisassoc;
2589 } /* end switch (pMac->lim.gLimSystemRole) */
2590
2591 if (smeDisassocReq.reasonCode == eLIM_LINK_MONITORING_DISASSOC) {
2592 /* / Disassociation is triggered by Link Monitoring */
2593 lim_log(pMac, LOG1,
2594 FL("Sending Disasscoc with reason Link Monitoring"));
2595 disassocTrigger = eLIM_LINK_MONITORING_DISASSOC;
2596 reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
2597 } else {
2598 disassocTrigger = eLIM_HOST_DISASSOC;
2599 reasonCode = smeDisassocReq.reasonCode;
2600 }
2601
2602 if (smeDisassocReq.doNotSendOverTheAir) {
2603 lim_log(pMac, LOG1, FL("do not send dissoc over the air"));
2604 send_disassoc_frame = 0;
2605 }
2606 /* Trigger Disassociation frame to peer MAC entity */
2607 lim_log(pMac, LOG1, FL("Sending Disasscoc with disassoc Trigger"
2608 " : %d, reasonCode : %d"),
2609 disassocTrigger, reasonCode);
2610
2611 pMlmDisassocReq = cdf_mem_malloc(sizeof(tLimMlmDisassocReq));
2612 if (NULL == pMlmDisassocReq) {
2613 /* Log error */
2614 lim_log(pMac, LOGP,
2615 FL("call to AllocateMemory failed for mlmDisassocReq"));
2616
2617 return;
2618 }
2619
2620 cdf_mem_copy((uint8_t *) &pMlmDisassocReq->peerMacAddr,
2621 (uint8_t *) &smeDisassocReq.peerMacAddr,
2622 sizeof(tSirMacAddr));
2623
2624 pMlmDisassocReq->reasonCode = reasonCode;
2625 pMlmDisassocReq->disassocTrigger = disassocTrigger;
2626
2627 /* Update PE session ID */
2628 pMlmDisassocReq->sessionId = sessionId;
2629
2630 lim_post_mlm_message(pMac,
2631 LIM_MLM_DISASSOC_REQ, (uint32_t *) pMlmDisassocReq);
2632 return;
2633
2634sendDisassoc:
2635 if (psessionEntry)
2636 lim_send_sme_disassoc_ntf(pMac, smeDisassocReq.peerMacAddr,
2637 retCode,
2638 disassocTrigger,
2639 1, smesessionId, smetransactionId,
2640 psessionEntry);
2641 else
2642 lim_send_sme_disassoc_ntf(pMac, smeDisassocReq.peerMacAddr,
2643 retCode,
2644 disassocTrigger,
2645 1, smesessionId, smetransactionId, NULL);
2646
2647} /*** end __lim_process_sme_disassoc_req() ***/
2648
2649/** -----------------------------------------------------------------
2650 \brief __lim_process_sme_disassoc_cnf() - Process SME_DISASSOC_CNF
2651
2652 This function is called to process SME_DISASSOC_CNF message
2653 from HDD or upper layer application.
2654
2655 \param pMac - global mac structure
2656 \param pStaDs - station dph hash node
2657 \return none
2658 \sa
2659 ----------------------------------------------------------------- */
2660static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
2661{
2662 tSirSmeDisassocCnf smeDisassocCnf;
2663 uint16_t aid;
2664 tpDphHashNode pStaDs;
2665 tpPESession psessionEntry;
2666 uint8_t sessionId;
2667
2668 PELOG1(lim_log(pMac, LOG1, FL("received DISASSOC_CNF message"));)
2669
2670 cdf_mem_copy(&smeDisassocCnf, pMsgBuf,
2671 sizeof(struct sSirSmeDisassocCnf));
2672
2673 psessionEntry = pe_find_session_by_bssid(pMac,
2674 smeDisassocCnf.bssId,
2675 &sessionId);
2676 if (psessionEntry == NULL) {
2677 lim_log(pMac, LOGE,
2678 FL("session does not exist for given bssId"));
2679 return;
2680 }
2681
2682 if (!lim_is_sme_disassoc_cnf_valid(pMac, &smeDisassocCnf, psessionEntry)) {
2683 lim_log(pMac, LOGE,
2684 FL("received invalid SME_DISASSOC_CNF message"));
2685 return;
2686 }
2687#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
2688 if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF)
2689 lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
2690 psessionEntry,
2691 (uint16_t) smeDisassocCnf.statusCode, 0);
2692 else if (smeDisassocCnf.messageType == eWNI_SME_DEAUTH_CNF)
2693 lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
2694 psessionEntry,
2695 (uint16_t) smeDisassocCnf.statusCode, 0);
2696#endif /* FEATURE_WLAN_DIAG_SUPPORT */
2697
2698 switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
2699 case eLIM_STA_ROLE:
2700 case eLIM_BT_AMP_STA_ROLE: /* To test reconn */
2701 if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) &&
2702 (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
2703 && (psessionEntry->limSmeState !=
2704 eLIM_SME_WT_DEAUTH_STATE)) {
2705 lim_log(pMac, LOGE,
2706 FL
2707 ("received unexp SME_DISASSOC_CNF in state %X"),
2708 psessionEntry->limSmeState);
2709 lim_print_sme_state(pMac, LOGE,
2710 psessionEntry->limSmeState);
2711 return;
2712 }
2713 break;
2714
2715 case eLIM_AP_ROLE:
2716 /* Fall through */
2717 break;
2718
2719 case eLIM_STA_IN_IBSS_ROLE:
2720 default: /* eLIM_UNKNOWN_ROLE */
2721 lim_log(pMac, LOGE,
2722 FL("received unexpected SME_DISASSOC_CNF role %d"),
2723 GET_LIM_SYSTEM_ROLE(psessionEntry));
2724
2725 return;
2726 }
2727
2728 if ((psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) ||
2729 (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
2730 LIM_IS_AP_ROLE(psessionEntry)) {
2731 pStaDs = dph_lookup_hash_entry(pMac,
2732 smeDisassocCnf.peerMacAddr, &aid,
2733 &psessionEntry->dph.dphHashTable);
2734 if (pStaDs == NULL) {
2735 lim_log(pMac, LOGE,
2736 FL("DISASSOC_CNF for a STA with no context, addr= "
2737 MAC_ADDRESS_STR),
2738 MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr));
2739 return;
2740 }
2741#if defined WLAN_FEATURE_VOWIFI_11R
2742 /* Delete FT session if there exists one */
2743 lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
2744#endif
2745 lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
2746
2747 lim_clean_up_disassoc_deauth_req(pMac,
2748 (char *)&smeDisassocCnf.peerMacAddr,
2749 0);
2750 }
2751
2752 return;
2753}
2754
2755/**
2756 * __lim_process_sme_deauth_req() - process sme deauth req
2757 * @mac_ctx: Pointer to Global MAC structure
2758 * @msg_buf: pointer to the SME message buffer
2759 *
2760 * This function is called to process SME_DEAUTH_REQ message
2761 * from HDD or upper layer application.
2762 *
2763 * Return: None
2764 */
2765
2766static void __lim_process_sme_deauth_req(tpAniSirGlobal mac_ctx,
2767 uint32_t *msg_buf)
2768{
2769 uint16_t deauth_trigger, reason_code;
2770 tLimMlmDeauthReq *mlm_deauth_req;
2771 tSirSmeDeauthReq sme_deauth_req;
2772 tSirResultCodes ret_code = eSIR_SME_SUCCESS;
2773 tpPESession session_entry;
2774 uint8_t session_id; /* PE sessionId */
2775 uint8_t sme_session_id;
2776 uint16_t sme_transaction_id;
2777
2778 lim_log(mac_ctx, LOG1, FL("received DEAUTH_REQ message"));
2779
2780 cdf_mem_copy(&sme_deauth_req, msg_buf, sizeof(tSirSmeDeauthReq));
2781 sme_session_id = sme_deauth_req.sessionId;
2782 sme_transaction_id = sme_deauth_req.transactionId;
2783
2784 /*
2785 * We need to get a session first but we don't even know
2786 * if the message is correct.
2787 */
2788 session_entry = pe_find_session_by_bssid(mac_ctx, sme_deauth_req.bssId,
2789 &session_id);
2790 if (session_entry == NULL) {
2791 lim_log(mac_ctx, LOGE,
2792 FL("session does not exist for given bssId"));
2793 ret_code = eSIR_SME_INVALID_PARAMETERS;
2794 deauth_trigger = eLIM_HOST_DEAUTH;
2795 goto send_deauth;
2796 }
2797
2798 if (!lim_is_sme_deauth_req_valid(mac_ctx, &sme_deauth_req,
2799 session_entry)) {
2800 lim_log(mac_ctx, LOGE,
2801 FL("received invalid SME_DEAUTH_REQ message"));
2802 mac_ctx->lim.gLimRspReqd = false;
2803
2804 ret_code = eSIR_SME_INVALID_PARAMETERS;
2805 deauth_trigger = eLIM_HOST_DEAUTH;
2806 goto send_deauth;
2807 }
2808 lim_log(mac_ctx, LOG1,
2809 FL("received DEAUTH_REQ sessionid %d Systemrole %d reasoncode %u limSmestate %d from "
2810 MAC_ADDRESS_STR), sme_session_id,
2811 GET_LIM_SYSTEM_ROLE(session_entry), sme_deauth_req.reasonCode,
2812 session_entry->limSmeState,
2813 MAC_ADDR_ARRAY(sme_deauth_req.peerMacAddr));
2814#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
2815 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
2816 session_entry, 0, sme_deauth_req.reasonCode);
2817#endif /* FEATURE_WLAN_DIAG_SUPPORT */
2818
2819 /* Update SME session ID and Transaction ID */
2820 session_entry->smeSessionId = sme_session_id;
2821 session_entry->transactionId = sme_transaction_id;
2822
2823 switch (GET_LIM_SYSTEM_ROLE(session_entry)) {
2824 case eLIM_STA_ROLE:
2825 case eLIM_BT_AMP_STA_ROLE:
2826
2827 switch (session_entry->limSmeState) {
2828 case eLIM_SME_ASSOCIATED_STATE:
2829 case eLIM_SME_LINK_EST_STATE:
2830 case eLIM_SME_WT_ASSOC_STATE:
2831 case eLIM_SME_JOIN_FAILURE_STATE:
2832 case eLIM_SME_IDLE_STATE:
2833 session_entry->limPrevSmeState =
2834 session_entry->limSmeState;
2835 session_entry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
2836 MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
2837 session_entry->peSessionId,
2838 session_entry->limSmeState));
2839 /* Send Deauthentication request to MLM below */
2840 break;
2841 case eLIM_SME_WT_DEAUTH_STATE:
2842 case eLIM_SME_WT_DISASSOC_STATE:
2843 /*
2844 * PE Recieved a Deauth/Disassoc frame. Normally it get
2845 * DEAUTH_CNF/DISASSOC_CNF but it received DEAUTH_REQ.
2846 * Which means host is also trying to disconnect.
2847 * PE can continue processing DEAUTH_REQ and send
2848 * the response instead of failing the request.
2849 * SME will anyway ignore DEAUTH_IND/DISASSOC_IND that
2850 * was sent for deauth/disassoc frame.
2851 */
2852 session_entry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
2853 lim_log(mac_ctx, LOG1, FL(
2854 "Rcvd SME_DEAUTH_REQ while in SME_WT_DEAUTH_STATE"));
2855 break;
2856 default:
2857 /*
2858 * STA is not in a state to deauthenticate with
2859 * peer. Log error and send response to host.
2860 */
2861 lim_log(mac_ctx, LOGE, FL(
2862 "received unexp SME_DEAUTH_REQ in state %X"),
2863 session_entry->limSmeState);
2864 lim_print_sme_state(mac_ctx, LOGE,
2865 session_entry->limSmeState);
2866
2867 if (mac_ctx->lim.gLimRspReqd) {
2868 mac_ctx->lim.gLimRspReqd = false;
2869
2870 ret_code = eSIR_SME_STA_NOT_AUTHENTICATED;
2871 deauth_trigger = eLIM_HOST_DEAUTH;
2872
2873 /*
2874 * here we received deauth request from AP so sme state
2875 * is eLIM_SME_WT_DEAUTH_STATE.if we have ISSUED
2876 * delSta then mlm state should be
2877 * eLIM_MLM_WT_DEL_STA_RSP_STATE and ifwe got delBSS
2878 * rsp then mlm state should be eLIM_MLM_IDLE_STATE
2879 * so the below condition captures the state where
2880 * delSta not done and firmware still in
2881 * connected state.
2882 */
2883 if (session_entry->limSmeState ==
2884 eLIM_SME_WT_DEAUTH_STATE &&
2885 session_entry->limMlmState !=
2886 eLIM_MLM_IDLE_STATE &&
2887 session_entry->limMlmState !=
2888 eLIM_MLM_WT_DEL_STA_RSP_STATE)
2889 ret_code = eSIR_SME_DEAUTH_STATUS;
2890 goto send_deauth;
2891 }
2892 return;
2893 }
2894 break;
2895
2896 case eLIM_STA_IN_IBSS_ROLE:
2897 lim_log(mac_ctx, LOGE, FL("Deauth not allowed in IBSS"));
2898 if (mac_ctx->lim.gLimRspReqd) {
2899 mac_ctx->lim.gLimRspReqd = false;
2900 ret_code = eSIR_SME_INVALID_PARAMETERS;
2901 deauth_trigger = eLIM_HOST_DEAUTH;
2902 goto send_deauth;
2903 }
2904 return;
2905 case eLIM_AP_ROLE:
2906 break;
2907 default:
2908 lim_log(mac_ctx, LOGE,
2909 FL("received unexpected SME_DEAUTH_REQ for role %X"),
2910 GET_LIM_SYSTEM_ROLE(session_entry));
2911 if (mac_ctx->lim.gLimRspReqd) {
2912 mac_ctx->lim.gLimRspReqd = false;
2913 ret_code = eSIR_SME_INVALID_PARAMETERS;
2914 deauth_trigger = eLIM_HOST_DEAUTH;
2915 goto send_deauth;
2916 }
2917 return;
2918 } /* end switch (mac_ctx->lim.gLimSystemRole) */
2919
2920 if (sme_deauth_req.reasonCode == eLIM_LINK_MONITORING_DEAUTH) {
2921 /* Deauthentication is triggered by Link Monitoring */
2922 lim_log(mac_ctx, LOG1, FL("** Lost link with AP **"));
2923 deauth_trigger = eLIM_LINK_MONITORING_DEAUTH;
2924 reason_code = eSIR_MAC_UNSPEC_FAILURE_REASON;
2925 } else {
2926 deauth_trigger = eLIM_HOST_DEAUTH;
2927 reason_code = sme_deauth_req.reasonCode;
2928 }
2929
2930 /* Trigger Deauthentication frame to peer MAC entity */
2931 mlm_deauth_req = cdf_mem_malloc(sizeof(tLimMlmDeauthReq));
2932 if (NULL == mlm_deauth_req) {
2933 lim_log(mac_ctx, LOGP,
2934 FL("call to AllocateMemory failed for mlmDeauthReq"));
2935 if (mac_ctx->lim.gLimRspReqd) {
2936 mac_ctx->lim.gLimRspReqd = false;
2937 ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
2938 deauth_trigger = eLIM_HOST_DEAUTH;
2939 goto send_deauth;
2940 }
2941 return;
2942 }
2943
2944 cdf_mem_copy((uint8_t *) &mlm_deauth_req->peerMacAddr,
2945 (uint8_t *) &sme_deauth_req.peerMacAddr,
2946 sizeof(tSirMacAddr));
2947
2948 mlm_deauth_req->reasonCode = reason_code;
2949 mlm_deauth_req->deauthTrigger = deauth_trigger;
2950
2951 /* Update PE session Id */
2952 mlm_deauth_req->sessionId = session_id;
2953
2954 lim_post_mlm_message(mac_ctx, LIM_MLM_DEAUTH_REQ,
2955 (uint32_t *)mlm_deauth_req);
2956 return;
2957
2958send_deauth:
2959 lim_send_sme_deauth_ntf(mac_ctx, sme_deauth_req.peerMacAddr, ret_code,
2960 deauth_trigger, 1, sme_session_id, sme_transaction_id);
2961}
2962
2963/**
2964 * __lim_process_sme_set_context_req()
2965 *
2966 * @mac_ctx: Pointer to Global MAC structure
2967 * @msg_buf: pointer to the SME message buffer
2968 *
2969 * This function is called to process SME_SETCONTEXT_REQ message
2970 * from HDD or upper layer application.
2971 *
2972 * Return: None
2973 */
2974
2975static void
2976__lim_process_sme_set_context_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
2977{
2978 tpSirSmeSetContextReq set_context_req;
2979 tLimMlmSetKeysReq *mlm_set_key_req;
2980 tpPESession session_entry;
2981 uint8_t session_id; /* PE sessionID */
2982 uint8_t sme_session_id;
2983 uint16_t sme_transaction_id;
2984
2985 lim_log(mac_ctx, LOG1, FL("received SETCONTEXT_REQ message"));
2986
2987 if (msg_buf == NULL) {
2988 lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
2989 return;
2990 }
2991
2992 set_context_req = cdf_mem_malloc(sizeof(struct sSirSmeSetContextReq));
2993 if (NULL == set_context_req) {
2994 lim_log(mac_ctx, LOGP, FL(
2995 "call to AllocateMemory failed for set_context_req"));
2996 return;
2997 }
2998 cdf_mem_copy(set_context_req, msg_buf,
2999 sizeof(struct sSirSmeSetContextReq));
3000 sme_session_id = set_context_req->sessionId;
3001 sme_transaction_id = set_context_req->transactionId;
3002
3003 if ((!lim_is_sme_set_context_req_valid(mac_ctx, set_context_req))) {
3004 lim_log(mac_ctx, LOGW,
3005 FL("received invalid SME_SETCONTEXT_REQ message"));
3006 goto end;
3007 }
3008
3009 if (set_context_req->keyMaterial.numKeys >
3010 SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
3011 lim_log(mac_ctx, LOGE, FL(
3012 "numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS"),
3013 set_context_req->keyMaterial.numKeys);
3014 lim_send_sme_set_context_rsp(mac_ctx,
3015 set_context_req->peerMacAddr, 1,
3016 eSIR_SME_INVALID_PARAMETERS, NULL,
3017 sme_session_id, sme_transaction_id);
3018 goto end;
3019 }
3020
3021 session_entry = pe_find_session_by_bssid(mac_ctx,
3022 set_context_req->bssId, &session_id);
3023 if (session_entry == NULL) {
3024 lim_log(mac_ctx, LOGW,
3025 FL("Session does not exist for given BSSID"));
3026 lim_send_sme_set_context_rsp(mac_ctx,
3027 set_context_req->peerMacAddr, 1,
3028 eSIR_SME_INVALID_PARAMETERS, NULL,
3029 sme_session_id, sme_transaction_id);
3030 goto end;
3031 }
3032#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
3033 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
3034 session_entry, 0, 0);
3035#endif /* FEATURE_WLAN_DIAG_SUPPORT */
3036
3037 if (((LIM_IS_STA_ROLE(session_entry) ||
3038 LIM_IS_BT_AMP_STA_ROLE(session_entry)) &&
3039 (session_entry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
3040 ((LIM_IS_IBSS_ROLE(session_entry) ||
3041 LIM_IS_AP_ROLE(session_entry) ||
3042 LIM_IS_BT_AMP_AP_ROLE(session_entry)) &&
3043 (session_entry->limSmeState == eLIM_SME_NORMAL_STATE))) {
3044 /* Trigger MLM_SETKEYS_REQ */
3045 mlm_set_key_req = cdf_mem_malloc(sizeof(tLimMlmSetKeysReq));
3046 if (NULL == mlm_set_key_req) {
3047 lim_log(mac_ctx, LOGP, FL(
3048 "mem alloc failed for mlmSetKeysReq"));
3049 goto end;
3050 }
3051 mlm_set_key_req->edType = set_context_req->keyMaterial.edType;
3052 mlm_set_key_req->numKeys =
3053 set_context_req->keyMaterial.numKeys;
3054 if (mlm_set_key_req->numKeys >
3055 SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
3056 lim_log(mac_ctx, LOGP, FL(
3057 "no.of keys exceeded max num of default keys limit"));
3058 goto end;
3059 }
3060 cdf_mem_copy((uint8_t *) &mlm_set_key_req->peerMacAddr,
3061 (uint8_t *) &set_context_req->peerMacAddr,
3062 sizeof(tSirMacAddr));
3063
3064 cdf_mem_copy((uint8_t *) &mlm_set_key_req->key,
3065 (uint8_t *) &set_context_req->keyMaterial.key,
3066 sizeof(tSirKeys) *
3067 (mlm_set_key_req->numKeys ? mlm_set_key_req->
3068 numKeys : 1));
3069
3070 mlm_set_key_req->sessionId = session_id;
3071 mlm_set_key_req->smesessionId = sme_session_id;
3072#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
3073 lim_log(mac_ctx, LOG1, FL(
3074 "received SETCONTEXT_REQ message sessionId=%d"),
3075 mlm_set_key_req->sessionId);
3076#endif
3077
3078 if (((set_context_req->keyMaterial.edType == eSIR_ED_WEP40) ||
3079 (set_context_req->keyMaterial.edType == eSIR_ED_WEP104)) &&
3080 LIM_IS_AP_ROLE(session_entry)) {
3081 if (set_context_req->keyMaterial.key[0].keyLength) {
3082 uint8_t key_id;
3083 key_id =
3084 set_context_req->keyMaterial.key[0].keyId;
3085 cdf_mem_copy((uint8_t *)
3086 &session_entry->WEPKeyMaterial[key_id],
3087 (uint8_t *) &set_context_req->keyMaterial,
3088 sizeof(tSirKeyMaterial));
3089 } else {
3090 uint32_t i;
3091 for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
3092 i++) {
3093 cdf_mem_copy((uint8_t *)
3094 &mlm_set_key_req->key[i],
3095 (uint8_t *)session_entry->WEPKeyMaterial[i].key,
3096 sizeof(tSirKeys));
3097 }
3098 }
3099 }
3100 lim_post_mlm_message(mac_ctx, LIM_MLM_SETKEYS_REQ,
3101 (uint32_t *) mlm_set_key_req);
3102 } else {
3103 lim_log(mac_ctx, LOGE, FL(
3104 "rcvd unexpected SME_SETCONTEXT_REQ for role %d, state=%X"),
3105 GET_LIM_SYSTEM_ROLE(session_entry),
3106 session_entry->limSmeState);
3107 lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState);
3108
3109 lim_send_sme_set_context_rsp(mac_ctx,
3110 set_context_req->peerMacAddr, 1,
3111 eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,
3112 session_entry, sme_session_id,
3113 sme_transaction_id);
3114 }
3115end:
3116 cdf_mem_free(set_context_req);
3117 return;
3118}
3119
3120/**
3121 * lim_process_sme_get_assoc_sta_info() - process sme assoc sta req
3122 *
3123 * @mac_ctx: Pointer to Global MAC structure
3124 * @msg_buf: pointer to the SME message buffer
3125 *
3126 * This function is called to process SME_GET_ASSOC_STAS_REQ message
3127 * from HDD or upper layer application.
3128 *
3129 * Return: None
3130 */
3131
3132void lim_process_sme_get_assoc_sta_info(tpAniSirGlobal mac_ctx,
3133 uint32_t *msg_buf)
3134{
3135 tSirSmeGetAssocSTAsReq get_assoc_stas_req;
3136 tpDphHashNode sta_ds = NULL;
3137 tpPESession session_entry = NULL;
3138 tSap_Event sap_event;
3139 tpWLAN_SAPEventCB sap_event_cb = NULL;
3140 tpSap_AssocMacAddr assoc_sta_tmp = NULL;
3141 uint8_t session_id = CSR_SESSION_ID_INVALID;
3142 uint8_t assoc_id = 0;
3143 uint8_t sta_cnt = 0;
3144
3145 if (msg_buf == NULL) {
3146 lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
3147 return;
3148 }
3149
3150 cdf_mem_copy(&get_assoc_stas_req, msg_buf,
3151 sizeof(struct sSirSmeGetAssocSTAsReq));
3152 /*
3153 * Get Associated stations from PE.
3154 * Find PE session Entry
3155 */
3156 session_entry = pe_find_session_by_bssid(mac_ctx,
3157 get_assoc_stas_req.bssId,
3158 &session_id);
3159 if (session_entry == NULL) {
3160 lim_log(mac_ctx, LOGE,
3161 FL("session does not exist for given bssId"));
3162 goto lim_assoc_sta_end;
3163 }
3164
3165 if (!LIM_IS_AP_ROLE(session_entry)) {
3166 lim_log(mac_ctx, LOGE, FL(
3167 "Received unexpected message in state %X, in role %X"),
3168 session_entry->limSmeState,
3169 GET_LIM_SYSTEM_ROLE(session_entry));
3170 goto lim_assoc_sta_end;
3171 }
3172 /* Retrieve values obtained in the request message */
3173 sap_event_cb = (tpWLAN_SAPEventCB)get_assoc_stas_req.pSapEventCallback;
3174 assoc_sta_tmp = (tpSap_AssocMacAddr)get_assoc_stas_req.pAssocStasArray;
3175
3176 if (NULL == assoc_sta_tmp)
3177 goto lim_assoc_sta_end;
3178 for (assoc_id = 0; assoc_id < session_entry->dph.dphHashTable.size;
3179 assoc_id++) {
3180 sta_ds = dph_get_hash_entry(mac_ctx, assoc_id,
3181 &session_entry->dph.dphHashTable);
3182 if (NULL == sta_ds)
3183 continue;
3184 if (sta_ds->valid) {
3185 cdf_mem_copy((uint8_t *) &assoc_sta_tmp->staMac,
3186 (uint8_t *) &sta_ds->staAddr,
3187 CDF_MAC_ADDR_SIZE);
3188 assoc_sta_tmp->assocId = (uint8_t) sta_ds->assocId;
3189 assoc_sta_tmp->staId = (uint8_t) sta_ds->staIndex;
3190
3191 cdf_mem_copy((uint8_t *)&assoc_sta_tmp->supportedRates,
3192 (uint8_t *)&sta_ds->supportedRates,
3193 sizeof(tSirSupportedRates));
3194 assoc_sta_tmp->ShortGI40Mhz = sta_ds->htShortGI40Mhz;
3195 assoc_sta_tmp->ShortGI20Mhz = sta_ds->htShortGI20Mhz;
3196 assoc_sta_tmp->Support40Mhz =
3197 sta_ds->htDsssCckRate40MHzSupport;
3198
3199 lim_log(mac_ctx, LOG1, FL("dph Station Number = %d"),
3200 sta_cnt + 1);
3201 lim_log(mac_ctx, LOG1, FL("MAC = " MAC_ADDRESS_STR),
3202 MAC_ADDR_ARRAY(sta_ds->staAddr));
3203 lim_log(mac_ctx, LOG1, FL("Association Id = %d"),
3204 sta_ds->assocId);
3205 lim_log(mac_ctx, LOG1, FL("Station Index = %d"),
3206 sta_ds->staIndex);
3207 assoc_sta_tmp++;
3208 sta_cnt++;
3209 }
3210 }
3211lim_assoc_sta_end:
3212 /*
3213 * Call hdd callback with sap event to send the list of
3214 * associated stations from PE
3215 */
3216 if (sap_event_cb != NULL) {
3217 sap_event.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT;
3218 sap_event.sapevt.sapAssocStaListEvent.module =
3219 CDF_MODULE_ID_PE;
3220 sap_event.sapevt.sapAssocStaListEvent.noOfAssocSta = sta_cnt;
3221 sap_event.sapevt.sapAssocStaListEvent.pAssocStas =
3222 (tpSap_AssocMacAddr)get_assoc_stas_req.pAssocStasArray;
3223 sap_event_cb(&sap_event, get_assoc_stas_req.pUsrContext);
3224 }
3225}
3226
3227/**
3228 * lim_process_sme_get_wpspbc_sessions - process sme get wpspbc req
3229 *
3230 * @mac_ctx: Pointer to Global MAC structure
3231 * @msg_buf: pointer to WPS PBC overlap query message
3232 *
3233 * This function parses get WPS PBC overlap information
3234 * message and call callback to pass WPS PBC overlap
3235 * information back to hdd.
3236 *
3237 * Return: None
3238 */
3239void lim_process_sme_get_wpspbc_sessions(tpAniSirGlobal mac_ctx,
3240 uint32_t *msg_buf)
3241{
3242 tSirSmeGetWPSPBCSessionsReq get_wps_pbc_sessions_req;
3243 tpPESession session_entry = NULL;
3244 tSap_Event sap_event;
3245 tpWLAN_SAPEventCB sap_event_cb = NULL;
3246 uint8_t session_id = CSR_SESSION_ID_INVALID;
3247 tSirMacAddr zero_mac = { 0, 0, 0, 0, 0, 0 };
3248 tSap_GetWPSPBCSessionEvent *sap_get_wpspbc_event;
3249
3250 if (msg_buf == NULL) {
3251 lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
3252 return;
3253 }
3254
3255 sap_get_wpspbc_event = &sap_event.sapevt.sapGetWPSPBCSessionEvent;
3256 sap_get_wpspbc_event->status = CDF_STATUS_E_FAULT;
3257
3258 cdf_mem_copy(&get_wps_pbc_sessions_req, msg_buf,
3259 sizeof(struct sSirSmeGetWPSPBCSessionsReq));
3260 /*
3261 * Get Associated stations from PE
3262 * Find PE session Entry
3263 */
3264 session_entry = pe_find_session_by_bssid(mac_ctx,
3265 get_wps_pbc_sessions_req.bssId, &session_id);
3266 if (session_entry == NULL) {
3267 lim_log(mac_ctx, LOGE,
3268 FL("session does not exist for given bssId"));
3269 goto lim_get_wpspbc_sessions_end;
3270 }
3271
3272 if (!LIM_IS_AP_ROLE(session_entry)) {
3273 lim_log(mac_ctx, LOGE,
3274 FL("Received unexpected message in role %X"),
3275 GET_LIM_SYSTEM_ROLE(session_entry));
3276 goto lim_get_wpspbc_sessions_end;
3277 }
3278 /*
3279 * Call hdd callback with sap event to send the
3280 * WPS PBC overlap information
3281 */
3282 sap_event.sapHddEventCode = eSAP_GET_WPSPBC_SESSION_EVENT;
3283 sap_get_wpspbc_event->module = CDF_MODULE_ID_PE;
3284
3285 if (cdf_mem_compare(zero_mac, get_wps_pbc_sessions_req.pRemoveMac,
3286 sizeof(tSirMacAddr))) {
3287 lim_get_wpspbc_sessions(mac_ctx,
3288 sap_get_wpspbc_event->addr.bytes,
3289 sap_get_wpspbc_event->UUID_E,
3290 &sap_get_wpspbc_event->wpsPBCOverlap,
3291 session_entry);
3292 } else {
3293 lim_remove_pbc_sessions(mac_ctx,
3294 get_wps_pbc_sessions_req.pRemoveMac,
3295 session_entry);
3296 /* don't have to inform the HDD/Host */
3297 return;
3298 }
3299
3300 lim_log(mac_ctx, LOGE, FL("wpsPBCOverlap %d"),
3301 sap_get_wpspbc_event->wpsPBCOverlap);
3302 lim_print_mac_addr(mac_ctx,
3303 sap_get_wpspbc_event->addr.bytes, LOG4);
3304
3305 sap_get_wpspbc_event->status = CDF_STATUS_SUCCESS;
3306
3307lim_get_wpspbc_sessions_end:
3308 sap_event_cb =
3309 (tpWLAN_SAPEventCB)get_wps_pbc_sessions_req.pSapEventCallback;
3310 if (NULL != sap_event_cb)
3311 sap_event_cb(&sap_event, get_wps_pbc_sessions_req.pUsrContext);
3312}
3313
3314/**
3315 * __lim_counter_measures()
3316 *
3317 * FUNCTION:
3318 * This function is called to "implement" MIC counter measure
3319 * and is *temporary* only
3320 *
3321 * LOGIC: on AP, disassoc all STA associated thru TKIP,
3322 * we don't do the proper STA disassoc sequence since the
3323 * BSS will be stoped anyway
3324 *
3325 ***ASSUMPTIONS:
3326 *
3327 ***NOTE:
3328 *
3329 * @param pMac Pointer to Global MAC structure
3330 * @return None
3331 */
3332
3333static void __lim_counter_measures(tpAniSirGlobal pMac, tpPESession psessionEntry)
3334{
3335 tSirMacAddr mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
3336 if (LIM_IS_AP_ROLE(psessionEntry) ||
3337 LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
3338 LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
3339 lim_send_disassoc_mgmt_frame(pMac, eSIR_MAC_MIC_FAILURE_REASON,
3340 mac, psessionEntry, false);
3341};
3342
3343void lim_process_tkip_counter_measures(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
3344{
3345 tSirSmeTkipCntrMeasReq tkipCntrMeasReq;
3346 tpPESession psessionEntry;
3347 uint8_t sessionId; /* PE sessionId */
3348
3349 cdf_mem_copy(&tkipCntrMeasReq, pMsgBuf,
3350 sizeof(struct sSirSmeTkipCntrMeasReq));
3351
3352 psessionEntry = pe_find_session_by_bssid(pMac,
3353 tkipCntrMeasReq.bssId,
3354 &sessionId);
3355 if (NULL == psessionEntry) {
3356 lim_log(pMac, LOGE,
3357 FL("session does not exist for given BSSID "));
3358 return;
3359 }
3360
3361 if (tkipCntrMeasReq.bEnable)
3362 __lim_counter_measures(pMac, psessionEntry);
3363
3364 psessionEntry->bTkipCntrMeasActive = tkipCntrMeasReq.bEnable;
3365}
3366
3367static void
3368__lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
3369{
3370 tSirSmeStopBssReq stopBssReq;
3371 tSirRetStatus status;
3372 tLimSmeStates prevState;
3373 tpPESession psessionEntry;
3374 uint8_t smesessionId;
3375 uint8_t sessionId;
3376 uint16_t smetransactionId;
3377 uint8_t i = 0;
3378 tpDphHashNode pStaDs = NULL;
3379
3380 cdf_mem_copy(&stopBssReq, pMsgBuf, sizeof(tSirSmeStopBssReq));
3381 smesessionId = stopBssReq.sessionId;
3382 smetransactionId = stopBssReq.transactionId;
3383
3384 if (!lim_is_sme_stop_bss_req_valid(pMsgBuf)) {
3385 PELOGW(lim_log(pMac, LOGW,
3386 FL("received invalid SME_STOP_BSS_REQ message"));)
3387 /* Send Stop BSS response to host */
3388 lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
3389 eSIR_SME_INVALID_PARAMETERS, smesessionId,
3390 smetransactionId);
3391 return;
3392 }
3393
3394 psessionEntry = pe_find_session_by_bssid(pMac,
3395 stopBssReq.bssId,
3396 &sessionId);
3397 if (psessionEntry == NULL) {
3398 lim_log(pMac, LOGW,
3399 FL("session does not exist for given BSSID "));
3400 lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
3401 eSIR_SME_INVALID_PARAMETERS, smesessionId,
3402 smetransactionId);
3403 return;
3404 }
3405#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
3406 lim_diag_event_report(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry,
3407 0, 0);
3408#endif /* FEATURE_WLAN_DIAG_SUPPORT */
3409
3410 if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE || /* Added For BT -AMP Support */
3411 LIM_IS_STA_ROLE(psessionEntry)) {
3412 /**
3413 * Should not have received STOP_BSS_REQ in states
3414 * other than 'normal' state or on STA in Infrastructure
3415 * mode. Log error and return response to host.
3416 */
3417 lim_log(pMac, LOGE,
3418 FL
3419 ("received unexpected SME_STOP_BSS_REQ in state %X, for role %d"),
3420 psessionEntry->limSmeState,
3421 GET_LIM_SYSTEM_ROLE(psessionEntry));
3422 lim_print_sme_state(pMac, LOGE, psessionEntry->limSmeState);
3423 /* / Send Stop BSS response to host */
3424 lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
3425 eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, smesessionId,
3426 smetransactionId);
3427 return;
3428 }
3429
3430 if (LIM_IS_AP_ROLE(psessionEntry))
3431 lim_wpspbc_close(pMac, psessionEntry);
3432
3433 lim_log(pMac, LOGW,
3434 FL("RECEIVED STOP_BSS_REQ with reason code=%d"),
3435 stopBssReq.reasonCode);
3436
3437 prevState = psessionEntry->limSmeState;
3438
3439 psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
3440 MTRACE(mac_trace
3441 (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
3442 psessionEntry->limSmeState));
3443
3444 /* Update SME session Id and Transaction Id */
3445 psessionEntry->smeSessionId = smesessionId;
3446 psessionEntry->transactionId = smetransactionId;
3447
3448 /* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */
3449 if (!LIM_IS_IBSS_ROLE(psessionEntry) &&
3450 !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
3451 tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
3452 if (stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)
3453 /* Send disassoc all stations associated thru TKIP */
3454 __lim_counter_measures(pMac, psessionEntry);
3455 else
3456 lim_send_disassoc_mgmt_frame(pMac,
3457 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
3458 bcAddr, psessionEntry, false);
3459 }
3460
3461 /* Free the buffer allocated in START_BSS_REQ */
3462 cdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
3463 psessionEntry->addIeParams.probeRespDataLen = 0;
3464 psessionEntry->addIeParams.probeRespData_buff = NULL;
3465
3466 cdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
3467 psessionEntry->addIeParams.assocRespDataLen = 0;
3468 psessionEntry->addIeParams.assocRespData_buff = NULL;
3469
3470 cdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
3471 psessionEntry->addIeParams.probeRespBCNDataLen = 0;
3472 psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
3473
3474 /* lim_del_bss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. */
3475 pMac->lim.gLimIbssCoalescingHappened = false;
3476
3477 for (i = 1; i < pMac->lim.gLimAssocStaLimit; i++) {
3478 pStaDs =
3479 dph_get_hash_entry(pMac, i, &psessionEntry->dph.dphHashTable);
3480 if (NULL == pStaDs)
3481 continue;
3482 status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
3483 if (eSIR_SUCCESS == status) {
3484 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
3485 pStaDs->assocId, psessionEntry);
3486 lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
3487 } else {
3488 lim_log(pMac, LOGE,
3489 FL("lim_del_sta failed with Status : %d"), status);
3490 CDF_ASSERT(0);
3491 }
3492 }
3493 /* send a delBss to HAL and wait for a response */
3494 status = lim_del_bss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
3495
3496 if (status != eSIR_SUCCESS) {
3497 PELOGE(lim_log
3498 (pMac, LOGE, FL("delBss failed for bss %d"),
3499 psessionEntry->bssIdx);
3500 )
3501 psessionEntry->limSmeState = prevState;
3502
3503 MTRACE(mac_trace
3504 (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
3505 psessionEntry->limSmeState));
3506
3507 lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
3508 eSIR_SME_STOP_BSS_FAILURE, smesessionId,
3509 smetransactionId);
3510 }
3511}
3512
3513/**
3514 * __lim_process_sme_stop_bss_req() - Process STOP_BSS from SME
3515 * @pMac: Global MAC context
3516 * @pMsg: Message from SME
3517 *
3518 * Wrapper for the function __lim_handle_sme_stop_bss_request
3519 * This message will be defered until softmac come out of
3520 * scan mode. Message should be handled even if we have
3521 * detected radar in the current operating channel.
3522 *
3523 * Return: true - If we consumed the buffer
3524 * false - If have defered the message.
3525 */
3526
3527static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
3528{
3529 if (__lim_is_defered_msg_for_learn(pMac, pMsg)) {
3530 /**
3531 * If message defered, buffer is not consumed yet.
3532 * So return false
3533 */
3534 return false;
3535 }
3536 __lim_handle_sme_stop_bss_request(pMac, (uint32_t *) pMsg->bodyptr);
3537 return true;
3538} /*** end __lim_process_sme_stop_bss_req() ***/
3539
3540void lim_process_sme_del_bss_rsp(tpAniSirGlobal pMac,
3541 uint32_t body, tpPESession psessionEntry)
3542{
3543
3544 (void)body;
3545 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
3546 lim_ibss_delete(pMac, psessionEntry);
3547 dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
3548 lim_delete_pre_auth_list(pMac);
3549 lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,
3550 psessionEntry->smeSessionId,
3551 psessionEntry->transactionId);
3552 return;
3553}
3554
3555/**
3556 * __lim_process_sme_assoc_cnf_new() - process sme assoc/reassoc cnf
3557 *
3558 * @mac_ctx: pointer to mac context
3559 * @msg_type: message type
3560 * @msg_buf: pointer to the SME message buffer
3561 *
3562 * This function handles SME_ASSOC_CNF/SME_REASSOC_CNF
3563 * in BTAMP AP.
3564 *
3565 * Return: None
3566 */
3567
3568void __lim_process_sme_assoc_cnf_new(tpAniSirGlobal mac_ctx, uint32_t msg_type,
3569 uint32_t *msg_buf)
3570{
3571 tSirSmeAssocCnf assoc_cnf;
3572 tpDphHashNode sta_ds = NULL;
3573 tpPESession session_entry = NULL;
3574 uint8_t session_id;
3575 tpSirAssocReq assoc_req;
3576
3577 if (msg_buf == NULL) {
3578 lim_log(mac_ctx, LOGE, FL("msg_buf is NULL "));
3579 goto end;
3580 }
3581
3582 cdf_mem_copy(&assoc_cnf, msg_buf, sizeof(struct sSirSmeAssocCnf));
3583 if (!__lim_is_sme_assoc_cnf_valid(&assoc_cnf)) {
3584 lim_log(mac_ctx, LOGE,
3585 FL("Received invalid SME_RE(ASSOC)_CNF message "));
3586 goto end;
3587 }
3588
3589 session_entry = pe_find_session_by_bssid(mac_ctx, assoc_cnf.bssId,
3590 &session_id);
3591 if (session_entry == NULL) {
3592 lim_log(mac_ctx, LOGE,
3593 FL("session does not exist for given bssId"));
3594 goto end;
3595 }
3596
3597 if ((!LIM_IS_AP_ROLE(session_entry) &&
3598 !LIM_IS_BT_AMP_AP_ROLE(session_entry)) ||
3599 ((session_entry->limSmeState != eLIM_SME_NORMAL_STATE) &&
3600 (session_entry->limSmeState !=
3601 eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) {
3602 lim_log(mac_ctx, LOGE, FL(
3603 "Rcvd unexpected msg %X in state %X, in role %X"),
3604 msg_type, session_entry->limSmeState,
3605 GET_LIM_SYSTEM_ROLE(session_entry));
3606 goto end;
3607 }
3608 sta_ds = dph_get_hash_entry(mac_ctx, assoc_cnf.aid,
3609 &session_entry->dph.dphHashTable);
3610 if (sta_ds == NULL) {
3611 lim_log(mac_ctx, LOGE, FL(
3612 "Rcvd invalid msg %X due to no STA ctx, aid %d, peer "),
3613 msg_type, assoc_cnf.aid);
3614 lim_print_mac_addr(mac_ctx, assoc_cnf.peerMacAddr, LOG1);
3615
3616 /*
3617 * send a DISASSOC_IND message to WSM to make sure
3618 * the state in WSM and LIM is the same
3619 */
3620 lim_send_sme_disassoc_ntf(mac_ctx, assoc_cnf.peerMacAddr,
3621 eSIR_SME_STA_NOT_ASSOCIATED,
3622 eLIM_PEER_ENTITY_DISASSOC, assoc_cnf.aid,
3623 session_entry->smeSessionId,
3624 session_entry->transactionId,
3625 session_entry);
3626 goto end;
3627 }
3628 if (!cdf_mem_compare((uint8_t *)sta_ds->staAddr,
3629 (uint8_t *) assoc_cnf.peerMacAddr,
3630 sizeof(tSirMacAddr))) {
3631 lim_log(mac_ctx, LOG1, FL(
3632 "peerMacAddr mismatched for aid %d, peer "),
3633 assoc_cnf.aid);
3634 lim_print_mac_addr(mac_ctx, assoc_cnf.peerMacAddr, LOG1);
3635 goto end;
3636 }
3637
3638 if ((sta_ds->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) ||
3639 ((sta_ds->mlmStaContext.subType == LIM_ASSOC) &&
3640 (msg_type != eWNI_SME_ASSOC_CNF)) ||
3641 ((sta_ds->mlmStaContext.subType == LIM_REASSOC) &&
3642 (msg_type != eWNI_SME_ASSOC_CNF))) {
3643 lim_log(mac_ctx, LOG1, FL(
3644 "not in MLM_WT_ASSOC_CNF_STATE, for aid %d, peer"
3645 "StaD mlmState : %d"),
3646 assoc_cnf.aid, sta_ds->mlmStaContext.mlmState);
3647 lim_print_mac_addr(mac_ctx, assoc_cnf.peerMacAddr, LOG1);
3648 goto end;
3649 }
3650 /*
3651 * Deactivate/delet CNF_WAIT timer since ASSOC_CNF
3652 * has been received
3653 */
3654 lim_log(mac_ctx, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer"));
3655 lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
3656 eLIM_CNF_WAIT_TIMER, sta_ds->assocId);
3657
3658 if (assoc_cnf.statusCode == eSIR_SME_SUCCESS) {
3659 /*
3660 * In BTAMP-AP, PE already finished the WMA_ADD_STA sequence
3661 * when it had received Assoc Request frame. Now, PE just needs
3662 * to send association rsp frame to the requesting BTAMP-STA.
3663 */
3664 sta_ds->mlmStaContext.mlmState =
3665 eLIM_MLM_LINK_ESTABLISHED_STATE;
3666 lim_log(mac_ctx, LOG1,
3667 FL("sending Assoc Rsp frame to STA (assoc id=%d) "),
3668 sta_ds->assocId);
3669 lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_SUCCESS,
3670 sta_ds->assocId, sta_ds->staAddr,
3671 sta_ds->mlmStaContext.subType, sta_ds,
3672 session_entry);
3673 goto end;
3674 } else {
3675 /*
3676 * SME_ASSOC_CNF status is non-success, so STA is not allowed
3677 * to be associated since the HAL sta entry is created for
3678 * denied STA we need to remove this HAL entry.
3679 * So to do that set updateContext to 1
3680 */
3681 if (!sta_ds->mlmStaContext.updateContext)
3682 sta_ds->mlmStaContext.updateContext = 1;
3683 lim_log(mac_ctx, LOG1,
3684 FL("Recv Assoc Cnf, status Code : %d(assoc id=%d) "),
3685 assoc_cnf.statusCode, sta_ds->assocId);
3686 lim_reject_association(mac_ctx, sta_ds->staAddr,
3687 sta_ds->mlmStaContext.subType,
3688 true, sta_ds->mlmStaContext.authType,
3689 sta_ds->assocId, true,
3690 eSIR_MAC_UNSPEC_FAILURE_STATUS,
3691 session_entry);
3692 }
3693end:
3694 if (((session_entry != NULL) && (sta_ds != NULL)) &&
3695 (session_entry->parsedAssocReq[sta_ds->assocId] != NULL)) {
3696 assoc_req = (tpSirAssocReq)
3697 session_entry->parsedAssocReq[sta_ds->assocId];
3698 if (assoc_req->assocReqFrame) {
3699 cdf_mem_free(assoc_req->assocReqFrame);
3700 assoc_req->assocReqFrame = NULL;
3701 }
3702 cdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
3703 session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
3704 }
3705}
3706
3707static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
3708{
3709 tpDphHashNode pStaDs;
3710 tSirMacAddr peerMac;
3711 tpSirAddtsReq pSirAddts;
3712 uint32_t timeout;
3713 tpPESession psessionEntry;
3714 uint8_t sessionId; /* PE sessionId */
3715 uint8_t smesessionId;
3716 uint16_t smetransactionId;
3717
3718 if (pMsgBuf == NULL) {
3719 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
3720 return;
3721 }
3722
3723 lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smesessionId,
3724 &smetransactionId);
3725
3726 pSirAddts = (tpSirAddtsReq) pMsgBuf;
3727
3728 psessionEntry = pe_find_session_by_bssid(pMac,
3729 pSirAddts->bssId,
3730 &sessionId);
3731 if (psessionEntry == NULL) {
3732 lim_log(pMac, LOGE, "Session Does not exist for given bssId");
3733 return;
3734 }
3735#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
3736 lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0,
3737 0);
3738#endif /* FEATURE_WLAN_DIAG_SUPPORT */
3739
3740 /* if sta
3741 * - verify assoc state
3742 * - send addts request to ap
3743 * - wait for addts response from ap
3744 * if ap, just ignore with error log
3745 */
3746 PELOG1(lim_log(pMac, LOG1,
3747 FL("Received SME_ADDTS_REQ (TSid %d, UP %d)"),
3748 pSirAddts->req.tspec.tsinfo.traffic.tsid,
3749 pSirAddts->req.tspec.tsinfo.traffic.userPrio);
3750 )
3751
3752 if (!LIM_IS_STA_ROLE(psessionEntry) &&
3753 !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
3754 PELOGE(lim_log(pMac, LOGE, "AddTs received on AP - ignoring");)
3755 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3756 psessionEntry, pSirAddts->req.tspec,
3757 smesessionId, smetransactionId);
3758 return;
3759 }
3760 /* Ignore the request if STA is in 11B mode. */
3761 if (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B) {
3762 PELOGE(lim_log
3763 (pMac, LOGE,
3764 "AddTS received while Dot11Mode is 11B - ignoring");
3765 )
3766 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3767 psessionEntry, pSirAddts->req.tspec,
3768 smesessionId, smetransactionId);
3769 return;
3770 }
3771
3772 pStaDs =
3773 dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
3774 &psessionEntry->dph.dphHashTable);
3775
3776 if (pStaDs == NULL) {
3777 PELOGE(lim_log
3778 (pMac, LOGE, "Cannot find AP context for addts req");
3779 )
3780 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3781 psessionEntry, pSirAddts->req.tspec,
3782 smesessionId, smetransactionId);
3783 return;
3784 }
3785
3786 if ((!pStaDs->valid) || (pStaDs->mlmStaContext.mlmState !=
3787 eLIM_MLM_LINK_ESTABLISHED_STATE)) {
3788 lim_log(pMac, LOGE, "AddTs received in invalid MLM state");
3789 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3790 psessionEntry, pSirAddts->req.tspec,
3791 smesessionId, smetransactionId);
3792 return;
3793 }
3794
3795 pSirAddts->req.wsmTspecPresent = 0;
3796 pSirAddts->req.wmeTspecPresent = 0;
3797 pSirAddts->req.lleTspecPresent = 0;
3798
3799 if ((pStaDs->wsmEnabled) &&
3800 (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy !=
3801 SIR_MAC_ACCESSPOLICY_EDCA))
3802 pSirAddts->req.wsmTspecPresent = 1;
3803 else if (pStaDs->wmeEnabled)
3804 pSirAddts->req.wmeTspecPresent = 1;
3805 else if (pStaDs->lleEnabled)
3806 pSirAddts->req.lleTspecPresent = 1;
3807 else {
3808 PELOGW(lim_log
3809 (pMac, LOGW, FL("ADDTS_REQ ignore - qos is disabled"));
3810 )
3811 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3812 psessionEntry, pSirAddts->req.tspec,
3813 smesessionId, smetransactionId);
3814 return;
3815 }
3816
3817 if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
3818 (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
3819 lim_log(pMac, LOGE,
3820 "AddTs received in invalid LIMsme state (%d)",
3821 psessionEntry->limSmeState);
3822 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3823 psessionEntry, pSirAddts->req.tspec,
3824 smesessionId, smetransactionId);
3825 return;
3826 }
3827
3828 if (pMac->lim.gLimAddtsSent) {
3829 lim_log(pMac, LOGE,
3830 "Addts (token %d, tsid %d, up %d) is still pending",
3831 pMac->lim.gLimAddtsReq.req.dialogToken,
3832 pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
3833 pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.
3834 userPrio);
3835 lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
3836 psessionEntry, pSirAddts->req.tspec,
3837 smesessionId, smetransactionId);
3838 return;
3839 }
3840
3841 sir_copy_mac_addr(peerMac, psessionEntry->bssId);
3842
3843 /* save the addts request */
3844 pMac->lim.gLimAddtsSent = true;
3845 cdf_mem_copy((uint8_t *) &pMac->lim.gLimAddtsReq,
3846 (uint8_t *) pSirAddts, sizeof(tSirAddtsReq));
3847
3848 /* ship out the message now */
3849 lim_send_addts_req_action_frame(pMac, peerMac, &pSirAddts->req,
3850 psessionEntry);
3851 PELOG1(lim_log(pMac, LOG1, "Sent ADDTS request");)
3852 /* start a timer to wait for the response */
3853 if (pSirAddts->timeout)
3854 timeout = pSirAddts->timeout;
3855 else if (wlan_cfg_get_int(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &timeout) !=
3856 eSIR_SUCCESS) {
3857 lim_log(pMac, LOGP,
3858 FL("Unable to get Cfg param %d (Addts Rsp Timeout)"),
3859 WNI_CFG_ADDTS_RSP_TIMEOUT);
3860 return;
3861 }
3862
3863 timeout = SYS_MS_TO_TICKS(timeout);
3864 if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0)
3865 != TX_SUCCESS) {
3866 lim_log(pMac, LOGP, FL("AddtsRsp timer change failed!"));
3867 return;
3868 }
3869 pMac->lim.gLimAddtsRspTimerCount++;
3870 if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
3871 pMac->lim.gLimAddtsRspTimerCount) !=
3872 TX_SUCCESS) {
3873 lim_log(pMac, LOGP, FL("AddtsRsp timer change failed!"));
3874 return;
3875 }
3876 MTRACE(mac_trace
3877 (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
3878 eLIM_ADDTS_RSP_TIMER));
3879
3880 /* add the sessionId to the timer object */
3881 pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId;
3882 if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) !=
3883 TX_SUCCESS) {
3884 lim_log(pMac, LOGP, FL("AddtsRsp timer activation failed!"));
3885 return;
3886 }
3887 return;
3888}
3889
3890static void __lim_process_sme_delts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
3891{
3892 tSirMacAddr peerMacAddr;
3893 uint8_t ac;
3894 tSirMacTSInfo *pTsinfo;
3895 tpSirDeltsReq pDeltsReq = (tpSirDeltsReq) pMsgBuf;
3896 tpDphHashNode pStaDs = NULL;
3897 tpPESession psessionEntry;
3898 uint8_t sessionId;
3899 uint32_t status = eSIR_SUCCESS;
3900 uint8_t smesessionId;
3901 uint16_t smetransactionId;
3902
3903 lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smesessionId,
3904 &smetransactionId);
3905
3906 psessionEntry = pe_find_session_by_bssid(pMac,
3907 pDeltsReq->bssId,
3908 &sessionId);
3909 if (psessionEntry == NULL) {
3910 lim_log(pMac, LOGE, "Session Does not exist for given bssId");
3911 status = eSIR_FAILURE;
3912 goto end;
3913 }
3914#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
3915 lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0,
3916 0);
3917#endif /* FEATURE_WLAN_DIAG_SUPPORT */
3918
3919 if (eSIR_SUCCESS !=
3920 lim_validate_delts_req(pMac, pDeltsReq, peerMacAddr, psessionEntry)) {
3921 PELOGE(lim_log(pMac, LOGE, FL("lim_validate_delts_req failed"));)
3922 status = eSIR_FAILURE;
3923 lim_send_sme_delts_rsp(pMac, pDeltsReq, eSIR_FAILURE, psessionEntry,
3924 smesessionId, smetransactionId);
3925 return;
3926 }
3927
3928 lim_log(pMac, LOG1,
3929 FL("Sent DELTS request to station with assocId = %d MacAddr = "
3930 MAC_ADDRESS_STR),
3931 pDeltsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));
3932
3933 lim_send_delts_req_action_frame(pMac, peerMacAddr,
3934 pDeltsReq->req.wmeTspecPresent,
3935 &pDeltsReq->req.tsinfo,
3936 &pDeltsReq->req.tspec, psessionEntry);
3937
3938 pTsinfo =
3939 pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.
3940 tsinfo : &pDeltsReq->req.tsinfo;
3941
3942 /* We've successfully send DELTS frame to AP. Update the
3943 * dynamic UAPSD mask. The AC for this TSPEC to be deleted
3944 * is no longer trigger enabled or delivery enabled
3945 */
3946 lim_set_tspec_uapsd_mask_per_session(pMac, psessionEntry,
3947 pTsinfo, CLEAR_UAPSD_MASK);
3948
3949 /* We're deleting the TSPEC, so this particular AC is no longer
3950 * admitted. PE needs to downgrade the EDCA
3951 * parameters(for the AC for which TS is being deleted) to the
3952 * next best AC for which ACM is not enabled, and send the
3953 * updated values to HAL.
3954 */
3955 ac = upToAc(pTsinfo->traffic.userPrio);
3956
3957 if (pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
3958 psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
3959 ~(1 << ac);
3960 } else if (pTsinfo->traffic.direction ==
3961 SIR_MAC_DIRECTION_DNLINK) {
3962 psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
3963 ~(1 << ac);
3964 } else if (pTsinfo->traffic.direction ==
3965 SIR_MAC_DIRECTION_BIDIR) {
3966 psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
3967 ~(1 << ac);
3968 psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
3969 ~(1 << ac);
3970 }
3971
3972 lim_set_active_edca_params(pMac, psessionEntry->gLimEdcaParams,
3973 psessionEntry);
3974
3975 pStaDs =
3976 dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
3977 &psessionEntry->dph.dphHashTable);
3978 if (pStaDs != NULL) {
3979 lim_send_edca_params(pMac, psessionEntry->gLimEdcaParamsActive,
3980 pStaDs->bssId);
3981 status = eSIR_SUCCESS;
3982 } else {
3983 lim_log(pMac, LOGE, FL("Self entry missing in Hash Table "));
3984 status = eSIR_FAILURE;
3985 }
3986#ifdef FEATURE_WLAN_ESE
3987#ifdef FEATURE_WLAN_ESE_UPLOAD
3988 lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
3989#else
3990 lim_deactivate_and_change_timer(pMac, eLIM_TSM_TIMER);
3991#endif /* FEATURE_WLAN_ESE_UPLOAD */
3992#endif
3993
3994 /* send an sme response back */
3995end:
3996 lim_send_sme_delts_rsp(pMac, pDeltsReq, eSIR_SUCCESS, psessionEntry,
3997 smesessionId, smetransactionId);
3998}
3999
4000void lim_process_sme_addts_rsp_timeout(tpAniSirGlobal pMac, uint32_t param)
4001{
4002 /* fetch the sessionEntry based on the sessionId */
4003 tpPESession psessionEntry;
4004 psessionEntry = pe_find_session_by_session_id(pMac,
4005 pMac->lim.limTimers.gLimAddtsRspTimer.
4006 sessionId);
4007 if (psessionEntry == NULL) {
4008 lim_log(pMac, LOGP,
4009 FL("Session Does not exist for given sessionID"));
4010 return;
4011 }
4012
4013 if (!LIM_IS_STA_ROLE(psessionEntry) &&
4014 !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
4015 lim_log(pMac, LOGW, "AddtsRspTimeout in non-Sta role (%d)",
4016 GET_LIM_SYSTEM_ROLE(psessionEntry));
4017 pMac->lim.gLimAddtsSent = false;
4018 return;
4019 }
4020
4021 if (!pMac->lim.gLimAddtsSent) {
4022 lim_log(pMac, LOGW, "AddtsRspTimeout but no AddtsSent");
4023 return;
4024 }
4025
4026 if (param != pMac->lim.gLimAddtsRspTimerCount) {
4027 lim_log(pMac, LOGE,
4028 FL("Invalid AddtsRsp Timer count %d (exp %d)"), param,
4029 pMac->lim.gLimAddtsRspTimerCount);
4030 return;
4031 }
4032 /* this a real response timeout */
4033 pMac->lim.gLimAddtsSent = false;
4034 pMac->lim.gLimAddtsRspTimerCount++;
4035
4036 lim_send_sme_addts_rsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT,
4037 psessionEntry, pMac->lim.gLimAddtsReq.req.tspec,
4038 psessionEntry->smeSessionId,
4039 psessionEntry->transactionId);
4040}
4041
4042/**
4043 * __lim_process_sme_get_statistics_request()
4044 *
4045 ***FUNCTION:
4046 *
4047 *
4048 ***NOTE:
4049 *
4050 * @param pMac Pointer to Global MAC structure
4051 * @param *pMsgBuf A pointer to the SME message buffer
4052 * @return None
4053 */
4054static void
4055__lim_process_sme_get_statistics_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4056{
4057 tpAniGetPEStatsReq pPEStatsReq;
4058 tSirMsgQ msgQ;
4059
4060 pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf;
4061
4062 msgQ.type = WMA_GET_STATISTICS_REQ;
4063
4064 msgQ.reserved = 0;
4065 msgQ.bodyptr = pMsgBuf;
4066 msgQ.bodyval = 0;
4067 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
4068
4069 if (eSIR_SUCCESS != (wma_post_ctrl_msg(pMac, &msgQ))) {
4070 cdf_mem_free(pMsgBuf);
4071 pMsgBuf = NULL;
4072 lim_log(pMac, LOGP, "Unable to forward request");
4073 return;
4074 }
4075
4076 return;
4077}
4078
4079#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4080/**
4081 *FUNCTION: __lim_process_sme_get_tsm_stats_request()
4082 *
4083 ***NOTE:
4084 *
4085 * @param pMac Pointer to Global MAC structure
4086 * @param *pMsgBuf A pointer to the SME message buffer
4087 * @return None
4088 */
4089static void
4090__lim_process_sme_get_tsm_stats_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4091{
4092 tSirMsgQ msgQ;
4093
4094 msgQ.type = WMA_TSM_STATS_REQ;
4095 msgQ.reserved = 0;
4096 msgQ.bodyptr = pMsgBuf;
4097 msgQ.bodyval = 0;
4098 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
4099
4100 if (eSIR_SUCCESS != (wma_post_ctrl_msg(pMac, &msgQ))) {
4101 cdf_mem_free(pMsgBuf);
4102 pMsgBuf = NULL;
4103 lim_log(pMac, LOGP, "Unable to forward request");
4104 return;
4105 }
4106}
4107#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4108
4109static void
4110__lim_process_sme_update_apwpsi_es(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4111{
4112 tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq;
4113 tpPESession psessionEntry;
4114 uint8_t sessionId; /* PE sessionID */
4115
4116 PELOG1(lim_log(pMac, LOG1, FL("received UPDATE_APWPSIEs_REQ message")););
4117
4118 if (pMsgBuf == NULL) {
4119 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
4120 return;
4121 }
4122
4123 pUpdateAPWPSIEsReq = cdf_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
4124 if (NULL == pUpdateAPWPSIEsReq) {
4125 lim_log(pMac, LOGP,
4126 FL
4127 ("call to AllocateMemory failed for pUpdateAPWPSIEsReq"));
4128 return;
4129 }
4130 cdf_mem_copy(pUpdateAPWPSIEsReq, pMsgBuf,
4131 sizeof(struct sSirUpdateAPWPSIEsReq));
4132
4133 psessionEntry = pe_find_session_by_bssid(pMac,
4134 pUpdateAPWPSIEsReq->bssId,
4135 &sessionId);
4136 if (psessionEntry == NULL) {
4137 lim_log(pMac, LOGW,
4138 FL("Session does not exist for given BSSID"));
4139 goto end;
4140 }
4141
4142 cdf_mem_copy(&psessionEntry->APWPSIEs, &pUpdateAPWPSIEsReq->APWPSIEs,
4143 sizeof(tSirAPWPSIEs));
4144
4145 sch_set_fixed_beacon_fields(pMac, psessionEntry);
4146 lim_send_beacon_ind(pMac, psessionEntry);
4147
4148end:
4149 cdf_mem_free(pUpdateAPWPSIEsReq);
4150 return;
4151}
4152
4153void
4154lim_send_vdev_restart(tpAniSirGlobal pMac,
4155 tpPESession psessionEntry, uint8_t sessionId)
4156{
4157 tpHalHiddenSsidVdevRestart pHalHiddenSsidVdevRestart = NULL;
4158 tSirMsgQ msgQ;
4159 tSirRetStatus retCode = eSIR_SUCCESS;
4160
4161 if (psessionEntry == NULL) {
4162 PELOGE(lim_log
4163 (pMac, LOGE, "%s:%d: Invalid parameters", __func__,
4164 __LINE__);
4165 )
4166 return;
4167 }
4168
4169 pHalHiddenSsidVdevRestart =
4170 cdf_mem_malloc(sizeof(tHalHiddenSsidVdevRestart));
4171 if (NULL == pHalHiddenSsidVdevRestart) {
4172 PELOGE(lim_log
4173 (pMac, LOGE, "%s:%d: Unable to allocate memory",
4174 __func__, __LINE__);
4175 )
4176 return;
4177 }
4178
4179 pHalHiddenSsidVdevRestart->ssidHidden = psessionEntry->ssidHidden;
4180 pHalHiddenSsidVdevRestart->sessionId = sessionId;
4181
4182 msgQ.type = WMA_HIDDEN_SSID_VDEV_RESTART;
4183 msgQ.bodyptr = pHalHiddenSsidVdevRestart;
4184 msgQ.bodyval = 0;
4185
4186 retCode = wma_post_ctrl_msg(pMac, &msgQ);
4187 if (eSIR_SUCCESS != retCode) {
4188 PELOGE(lim_log
4189 (pMac, LOGE, "%s:%d: wma_post_ctrl_msg() failed", __func__,
4190 __LINE__);
4191 )
4192 cdf_mem_free(pHalHiddenSsidVdevRestart);
4193 }
4194}
4195
4196static void __lim_process_sme_hide_ssid(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4197{
4198 tpSirUpdateParams pUpdateParams;
4199 tpPESession psessionEntry;
4200
4201 PELOG1(lim_log(pMac, LOG1, FL("received HIDE_SSID message")););
4202
4203 if (pMsgBuf == NULL) {
4204 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
4205 return;
4206 }
4207
4208 pUpdateParams = (tpSirUpdateParams) pMsgBuf;
4209
4210 psessionEntry = pe_find_session_by_session_id(pMac,
4211 pUpdateParams->sessionId);
4212 if (psessionEntry == NULL) {
4213 lim_log(pMac, LOGW,
4214 "Session does not exist for given sessionId %d",
4215 pUpdateParams->sessionId);
4216 return;
4217 }
4218
4219 /* Update the session entry */
4220 psessionEntry->ssidHidden = pUpdateParams->ssidHidden;
4221
4222 /* Send vdev restart */
4223 lim_send_vdev_restart(pMac, psessionEntry, pUpdateParams->sessionId);
4224
4225 /* Update beacon */
4226 sch_set_fixed_beacon_fields(pMac, psessionEntry);
4227 lim_send_beacon_ind(pMac, psessionEntry);
4228
4229 return;
4230} /*** end __lim_process_sme_hide_ssid(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
4231
4232static void __lim_process_sme_set_wparsni_es(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4233{
4234 tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq;
4235 tpPESession psessionEntry;
4236 uint8_t sessionId; /* PE sessionID */
4237
4238 if (pMsgBuf == NULL) {
4239 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
4240 return;
4241 }
4242
4243 pUpdateAPWPARSNIEsReq = cdf_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
4244 if (NULL == pUpdateAPWPARSNIEsReq) {
4245 lim_log(pMac, LOGP,
4246 FL
4247 ("call to AllocateMemory failed for pUpdateAPWPARSNIEsReq"));
4248 return;
4249 }
4250 cdf_mem_copy(pUpdateAPWPARSNIEsReq, pMsgBuf,
4251 sizeof(struct sSirUpdateAPWPARSNIEsReq));
4252
4253 psessionEntry = pe_find_session_by_bssid(pMac,
4254 pUpdateAPWPARSNIEsReq->bssId,
4255 &sessionId);
4256 if (psessionEntry == NULL) {
4257 lim_log(pMac, LOGW,
4258 FL("Session does not exist for given BSSID"));
4259 goto end;
4260 }
4261
4262 cdf_mem_copy(&psessionEntry->pLimStartBssReq->rsnIE,
4263 &pUpdateAPWPARSNIEsReq->APWPARSNIEs, sizeof(tSirRSNie));
4264
4265 lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(pMac,
4266 &psessionEntry->
4267 pLimStartBssReq->rsnIE,
4268 psessionEntry);
4269
4270 psessionEntry->pLimStartBssReq->privacy = 1;
4271 psessionEntry->privacy = 1;
4272
4273 sch_set_fixed_beacon_fields(pMac, psessionEntry);
4274 lim_send_beacon_ind(pMac, psessionEntry);
4275
4276end:
4277 cdf_mem_free(pUpdateAPWPARSNIEsReq);
4278 return;
4279} /*** end __lim_process_sme_set_wparsni_es(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
4280
4281/*
4282 Update the beacon Interval dynamically if beaconInterval is different in MCC
4283 */
4284static void __lim_process_sme_change_bi(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4285{
4286 tpSirChangeBIParams pChangeBIParams;
4287 tpPESession psessionEntry;
4288 uint8_t sessionId = 0;
4289 tUpdateBeaconParams beaconParams;
4290
4291 PELOG1(lim_log(pMac, LOG1,
4292 FL("received Update Beacon Interval message"));
4293 );
4294
4295 if (pMsgBuf == NULL) {
4296 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
4297 return;
4298 }
4299
4300 cdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
4301 pChangeBIParams = (tpSirChangeBIParams) pMsgBuf;
4302
4303 psessionEntry = pe_find_session_by_bssid(pMac,
4304 pChangeBIParams->bssId,
4305 &sessionId);
4306 if (psessionEntry == NULL) {
4307 lim_log(pMac, LOGE,
4308 FL("Session does not exist for given BSSID"));
4309 return;
4310 }
4311
4312 /*Update sessionEntry Beacon Interval */
4313 if (psessionEntry->beaconParams.beaconInterval !=
4314 pChangeBIParams->beaconInterval) {
4315 psessionEntry->beaconParams.beaconInterval =
4316 pChangeBIParams->beaconInterval;
4317 }
4318
4319 /*Update sch beaconInterval */
4320 if (pMac->sch.schObject.gSchBeaconInterval !=
4321 pChangeBIParams->beaconInterval) {
4322 pMac->sch.schObject.gSchBeaconInterval =
4323 pChangeBIParams->beaconInterval;
4324
4325 PELOG1(lim_log(pMac, LOG1,
4326 FL
4327 ("LIM send update BeaconInterval Indication : %d"),
4328 pChangeBIParams->beaconInterval);
4329 );
4330
4331 if (false == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
4332 /* Update beacon */
4333 sch_set_fixed_beacon_fields(pMac, psessionEntry);
4334
4335 beaconParams.bssIdx = psessionEntry->bssIdx;
4336 /* Set change in beacon Interval */
4337 beaconParams.beaconInterval =
4338 pChangeBIParams->beaconInterval;
4339 beaconParams.paramChangeBitmap =
4340 PARAM_BCN_INTERVAL_CHANGED;
4341 lim_send_beacon_params(pMac, &beaconParams, psessionEntry);
4342 }
4343 }
4344
4345 return;
4346} /*** end __lim_process_sme_change_bi(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
4347
4348#ifdef QCA_HT_2040_COEX
4349static void __lim_process_sme_set_ht2040_mode(tpAniSirGlobal pMac,
4350 uint32_t *pMsgBuf)
4351{
4352 tpSirSetHT2040Mode pSetHT2040Mode;
4353 tpPESession psessionEntry;
4354 uint8_t sessionId = 0;
4355 cds_msg_t msg;
4356 tUpdateVHTOpMode *pHtOpMode = NULL;
4357 uint16_t staId = 0;
4358 tpDphHashNode pStaDs = NULL;
4359
4360 PELOG1(lim_log(pMac, LOG1, FL("received Set HT 20/40 mode message")););
4361 if (pMsgBuf == NULL) {
4362 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
4363 return;
4364 }
4365
4366 pSetHT2040Mode = (tpSirSetHT2040Mode) pMsgBuf;
4367
4368 psessionEntry = pe_find_session_by_bssid(pMac,
4369 pSetHT2040Mode->bssId,
4370 &sessionId);
4371 if (psessionEntry == NULL) {
4372 lim_log(pMac, LOG1,
4373 FL("Session does not exist for given BSSID "));
4374 lim_print_mac_addr(pMac, pSetHT2040Mode->bssId, LOG1);
4375 return;
4376 }
4377
4378 lim_log(pMac, LOG1, FL("Update session entry for cbMod=%d"),
4379 pSetHT2040Mode->cbMode);
4380 /*Update sessionEntry HT related fields */
4381 switch (pSetHT2040Mode->cbMode) {
4382 case PHY_SINGLE_CHANNEL_CENTERED:
4383 psessionEntry->htSecondaryChannelOffset =
4384 PHY_SINGLE_CHANNEL_CENTERED;
4385 psessionEntry->htRecommendedTxWidthSet = 0;
4386 if (pSetHT2040Mode->obssEnabled)
4387 psessionEntry->htSupportedChannelWidthSet
4388 = eHT_CHANNEL_WIDTH_40MHZ;
4389 else
4390 psessionEntry->htSupportedChannelWidthSet
4391 = eHT_CHANNEL_WIDTH_20MHZ;
4392 break;
4393 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
4394 psessionEntry->htSecondaryChannelOffset =
4395 PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
4396 psessionEntry->htRecommendedTxWidthSet = 1;
4397 break;
4398 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
4399 psessionEntry->htSecondaryChannelOffset =
4400 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
4401 psessionEntry->htRecommendedTxWidthSet = 1;
4402 break;
4403 default:
4404 lim_log(pMac, LOGE, FL("Invalid cbMode"));
4405 return;
4406 }
4407
4408 /* Update beacon */
4409 sch_set_fixed_beacon_fields(pMac, psessionEntry);
4410 lim_send_beacon_ind(pMac, psessionEntry);
4411
4412 /* update OP Mode for each associated peer */
4413 for (staId = 0; staId < psessionEntry->dph.dphHashTable.size; staId++) {
4414 pStaDs = dph_get_hash_entry(pMac, staId,
4415 &psessionEntry->dph.dphHashTable);
4416 if (NULL == pStaDs)
4417 continue;
4418
4419 if (pStaDs->valid && pStaDs->htSupportedChannelWidthSet) {
4420 pHtOpMode = cdf_mem_malloc(sizeof(tUpdateVHTOpMode));
4421 if (NULL == pHtOpMode) {
4422 lim_log(pMac, LOGE,
4423 FL
4424 ("%s: Not able to allocate memory for setting OP mode"),
4425 __func__);
4426 return;
4427 }
4428 pHtOpMode->opMode =
4429 (psessionEntry->htSecondaryChannelOffset ==
4430 PHY_SINGLE_CHANNEL_CENTERED) ?
4431 eHT_CHANNEL_WIDTH_20MHZ : eHT_CHANNEL_WIDTH_40MHZ;
4432 pHtOpMode->staId = staId;
4433 cdf_mem_copy(pHtOpMode->peer_mac, &pStaDs->staAddr,
4434 sizeof(tSirMacAddr));
4435 pHtOpMode->smesessionId = sessionId;
4436
4437 msg.type = WMA_UPDATE_OP_MODE;
4438 msg.reserved = 0;
4439 msg.bodyptr = pHtOpMode;
4440 if (!CDF_IS_STATUS_SUCCESS
4441 (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
4442 lim_log(pMac, LOGE,
4443 FL
4444 ("%s: Not able to post WMA_UPDATE_OP_MODE message to WMA"),
4445 __func__);
4446 cdf_mem_free(pHtOpMode);
4447 return;
4448 }
4449 lim_log(pMac, LOG1,
4450 FL
4451 ("%s: Notifed FW about OP mode: %d for staId=%d"),
4452 __func__, pHtOpMode->opMode, staId);
4453
4454 } else
4455 lim_log(pMac, LOG1,
4456 FL("%s: station %d does not support HT40\n"),
4457 __func__, staId);
4458 }
4459
4460 return;
4461}
4462#endif
4463
4464/* -------------------------------------------------------------------- */
4465/**
4466 * __lim_process_report_message
4467 *
4468 * FUNCTION: Processes the next received Radio Resource Management message
4469 *
4470 * LOGIC:
4471 *
4472 * ASSUMPTIONS:
4473 *
4474 * NOTE:
4475 *
4476 * @param None
4477 * @return None
4478 */
4479
4480void __lim_process_report_message(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
4481{
4482#ifdef WLAN_FEATURE_VOWIFI
4483 switch (pMsg->type) {
4484 case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
4485 rrm_process_neighbor_report_req(pMac, pMsg->bodyptr);
4486 break;
4487 case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004488 rrm_process_beacon_report_xmit(pMac, pMsg->bodyptr);
Krishna Kumaar Natarajanf599c6e2015-11-03 11:44:03 -08004489 break;
4490 default:
4491 lim_log(pMac, LOGE, FL("Invalid msg type:%d"), pMsg->type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004492 }
4493#endif
4494}
4495
4496#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_VOWIFI)
4497/* -------------------------------------------------------------------- */
4498/**
4499 * lim_send_set_max_tx_power_req
4500 *
4501 * FUNCTION: Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power.
4502 *
4503 * LOGIC:
4504 *
4505 * ASSUMPTIONS:
4506 *
4507 * NOTE:
4508 *
4509 * @param txPower txPower to be set.
4510 * @param pSessionEntry session entry.
4511 * @return None
4512 */
4513tSirRetStatus
4514lim_send_set_max_tx_power_req(tpAniSirGlobal pMac, tPowerdBm txPower,
4515 tpPESession pSessionEntry)
4516{
4517 tpMaxTxPowerParams pMaxTxParams = NULL;
4518 tSirRetStatus retCode = eSIR_SUCCESS;
4519 tSirMsgQ msgQ;
4520
4521 if (pSessionEntry == NULL) {
4522 PELOGE(lim_log
4523 (pMac, LOGE, "%s:%d: Inavalid parameters", __func__,
4524 __LINE__);
4525 )
4526 return eSIR_FAILURE;
4527 }
4528
4529 pMaxTxParams = cdf_mem_malloc(sizeof(tMaxTxPowerParams));
4530 if (NULL == pMaxTxParams) {
4531 lim_log(pMac, LOGP,
4532 FL("Unable to allocate memory for pMaxTxParams "));
4533 return eSIR_MEM_ALLOC_FAILED;
4534
4535 }
4536#if defined(WLAN_VOWIFI_DEBUG) || defined(FEATURE_WLAN_ESE)
4537 lim_log(pMac, LOG1,
4538 FL("pMaxTxParams allocated...will be freed in other module"));
4539#endif
4540 if (pMaxTxParams == NULL) {
4541 lim_log(pMac, LOGE, FL("pMaxTxParams is NULL"));
4542 return eSIR_FAILURE;
4543 }
4544 pMaxTxParams->power = txPower;
4545 cdf_mem_copy(pMaxTxParams->bssId, pSessionEntry->bssId,
4546 sizeof(tSirMacAddr));
4547 cdf_mem_copy(pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr,
4548 sizeof(tSirMacAddr));
4549
4550 msgQ.type = WMA_SET_MAX_TX_POWER_REQ;
4551 msgQ.bodyptr = pMaxTxParams;
4552 msgQ.bodyval = 0;
4553 PELOG1(lim_log
4554 (pMac, LOG1, FL("Posting WMA_SET_MAX_TX_POWER_REQ to WMA"));
4555 )
4556 MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, msgQ.type));
4557 retCode = wma_post_ctrl_msg(pMac, &msgQ);
4558 if (eSIR_SUCCESS != retCode) {
4559 lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() failed"));
4560 cdf_mem_free(pMaxTxParams);
4561 }
4562 return retCode;
4563}
4564#endif
4565
4566/**
4567 * __lim_process_sme_register_mgmt_frame_req() - process sme reg mgmt frame req
4568 *
4569 * @mac_ctx: Pointer to Global MAC structure
4570 * @msg_buf: pointer to the SME message buffer
4571 *
4572 * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message
4573 * from SME. It Register this information within PE.
4574 *
4575 * Return: None
4576 */
4577static void __lim_process_sme_register_mgmt_frame_req(tpAniSirGlobal mac_ctx,
4578 uint32_t *msg_buf)
4579{
4580 CDF_STATUS cdf_status;
4581 tpSirRegisterMgmtFrame sme_req = (tpSirRegisterMgmtFrame)msg_buf;
4582 struct mgmt_frm_reg_info *lim_mgmt_regn = NULL;
4583 struct mgmt_frm_reg_info *next = NULL;
4584 bool match = false;
4585
4586 lim_log(mac_ctx, LOG1, FL(
4587 "registerFrame %d, frameType %d, matchLen %d"),
4588 sme_req->registerFrame, sme_req->frameType,
4589 sme_req->matchLen);
4590 /* First check whether entry exists already */
4591 cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
4592 cdf_list_peek_front(&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
4593 (cdf_list_node_t **) &lim_mgmt_regn);
4594 cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
4595
4596 while (lim_mgmt_regn != NULL) {
4597 if (lim_mgmt_regn->frameType != sme_req->frameType)
4598 goto skip_match;
4599 if (sme_req->matchLen) {
4600 if ((lim_mgmt_regn->matchLen == sme_req->matchLen) &&
4601 (cdf_mem_compare(lim_mgmt_regn->matchData,
4602 sme_req->matchData,
4603 lim_mgmt_regn->matchLen))) {
4604 /* found match! */
4605 match = true;
4606 break;
4607 }
4608 } else {
4609 /* found match! */
4610 match = true;
4611 break;
4612 }
4613skip_match:
4614 cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
4615 cdf_status = cdf_list_peek_next(
4616 &mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
4617 (cdf_list_node_t *)lim_mgmt_regn,
4618 (cdf_list_node_t **)&next);
4619 cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
4620 lim_mgmt_regn = next;
4621 next = NULL;
4622 }
4623 if (match) {
4624 cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
4625 cdf_list_remove_node(
4626 &mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
4627 (cdf_list_node_t *)lim_mgmt_regn);
4628 cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
4629 cdf_mem_free(lim_mgmt_regn);
4630 }
4631
4632 if (sme_req->registerFrame) {
4633 lim_mgmt_regn =
4634 cdf_mem_malloc(sizeof(struct mgmt_frm_reg_info) +
4635 sme_req->matchLen);
4636 if (lim_mgmt_regn != NULL) {
4637 cdf_mem_set((void *)lim_mgmt_regn,
4638 sizeof(struct mgmt_frm_reg_info) +
4639 sme_req->matchLen, 0);
4640 lim_mgmt_regn->frameType = sme_req->frameType;
4641 lim_mgmt_regn->matchLen = sme_req->matchLen;
4642 lim_mgmt_regn->sessionId = sme_req->sessionId;
4643 if (sme_req->matchLen) {
4644 cdf_mem_copy(lim_mgmt_regn->matchData,
4645 sme_req->matchData,
4646 sme_req->matchLen);
4647 }
4648 cdf_mutex_acquire(
4649 &mac_ctx->lim.lim_frame_register_lock);
4650 cdf_list_insert_front(&mac_ctx->lim.
4651 gLimMgmtFrameRegistratinQueue,
4652 &lim_mgmt_regn->node);
4653 cdf_mutex_release(
4654 &mac_ctx->lim.lim_frame_register_lock);
4655 }
4656 }
4657 return;
4658}
4659
4660static void __lim_deregister_deferred_sme_req_after_noa_start(tpAniSirGlobal pMac)
4661{
4662 lim_log(pMac, LOG1, FL("Dereg msgType %d"),
4663 pMac->lim.gDeferMsgTypeForNOA);
4664 pMac->lim.gDeferMsgTypeForNOA = 0;
4665 if (pMac->lim.gpDefdSmeMsgForNOA != NULL) {
4666 /* __lim_process_sme_scan_req consumed the buffer. We can free it. */
4667 cdf_mem_free(pMac->lim.gpDefdSmeMsgForNOA);
4668 pMac->lim.gpDefdSmeMsgForNOA = NULL;
4669 }
4670}
4671
4672/**
4673 * lim_process_regd_defd_sme_req_after_noa_start()
4674 *
4675 * mac_ctx: Pointer to Global MAC structure
4676 *
4677 * This function is called to process deferred sme req message
4678 * after noa start.
4679 *
4680 * Return: None
4681 */
4682void lim_process_regd_defd_sme_req_after_noa_start(tpAniSirGlobal mac_ctx)
4683{
4684 bool buf_consumed = true;
4685
4686 lim_log(mac_ctx, LOG1, FL("Process defd sme req %d"),
4687 mac_ctx->lim.gDeferMsgTypeForNOA);
4688
4689 if ((mac_ctx->lim.gDeferMsgTypeForNOA == 0) ||
4690 (mac_ctx->lim.gpDefdSmeMsgForNOA == NULL)) {
4691 lim_log(mac_ctx, LOGW,
4692 FL("start rcvd from FW when no sme deferred msg pending. Do nothing. "));
4693 lim_log(mac_ctx, LOGW,
4694 FL("It may happen when NOA start ind and timeout happen at the same time"));
4695 return;
4696 }
4697 switch (mac_ctx->lim.gDeferMsgTypeForNOA) {
4698 case eWNI_SME_SCAN_REQ:
4699 __lim_process_sme_scan_req(mac_ctx,
4700 mac_ctx->lim.gpDefdSmeMsgForNOA);
4701 break;
4702#ifdef FEATURE_OEM_DATA_SUPPORT
4703 case eWNI_SME_OEM_DATA_REQ:
4704 __lim_process_sme_oem_data_req(mac_ctx,
4705 mac_ctx->lim.gpDefdSmeMsgForNOA);
4706 break;
4707#endif
4708 case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
4709 buf_consumed = lim_process_remain_on_chnl_req(mac_ctx,
4710 mac_ctx->lim.gpDefdSmeMsgForNOA);
4711 /*
4712 * lim_process_remain_on_chnl_req doesnt want us to free
4713 * the buffer since it is freed in lim_remain_on_chn_rsp.
4714 * this change is to avoid "double free"
4715 */
4716 if (false == buf_consumed)
4717 mac_ctx->lim.gpDefdSmeMsgForNOA = NULL;
4718 break;
4719 case eWNI_SME_JOIN_REQ:
4720 __lim_process_sme_join_req(mac_ctx,
4721 mac_ctx->lim.gpDefdSmeMsgForNOA);
4722 break;
4723 default:
4724 lim_log(mac_ctx, LOGE, FL("Unknown deferred msg type %d"),
4725 mac_ctx->lim.gDeferMsgTypeForNOA);
4726 break;
4727 }
4728 __lim_deregister_deferred_sme_req_after_noa_start(mac_ctx);
4729}
4730
4731static void
4732__lim_process_sme_reset_ap_caps_change(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
4733{
4734 tpSirResetAPCapsChange pResetCapsChange;
4735 tpPESession psessionEntry;
4736 uint8_t sessionId = 0;
4737 if (pMsgBuf == NULL) {
4738 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
4739 return;
4740 }
4741
4742 pResetCapsChange = (tpSirResetAPCapsChange) pMsgBuf;
4743 psessionEntry =
4744 pe_find_session_by_bssid(pMac, pResetCapsChange->bssId, &sessionId);
4745 if (psessionEntry == NULL) {
4746 lim_log(pMac, LOGE,
4747 FL("Session does not exist for given BSSID"));
4748 return;
4749 }
4750
4751 psessionEntry->limSentCapsChangeNtf = false;
4752 return;
4753}
4754
4755/**
4756 * lim_process_sme_req_messages()
4757 *
4758 ***FUNCTION:
4759 * This function is called by limProcessMessageQueue(). This
4760 * function processes SME request messages from HDD or upper layer
4761 * application.
4762 *
4763 ***LOGIC:
4764 *
4765 ***ASSUMPTIONS:
4766 *
4767 ***NOTE:
4768 *
4769 * @param pMac Pointer to Global MAC structure
4770 * @param msgType Indicates the SME message type
4771 * @param *pMsgBuf A pointer to the SME message buffer
4772 * @return Boolean - true - if pMsgBuf is consumed and can be freed.
4773 * false - if pMsgBuf is not to be freed.
4774 */
4775
4776bool lim_process_sme_req_messages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
4777{
4778 bool bufConsumed = true; /* Set this flag to false within case block of any following message, that doesnt want pMsgBuf to be freed. */
4779 uint32_t *pMsgBuf = pMsg->bodyptr;
4780 tpSirSmeScanReq pScanReq;
4781 PELOG1(lim_log
4782 (pMac, LOG1,
4783 FL
4784 ("LIM Received SME Message %s(%d) Global LimSmeState:%s(%d) Global LimMlmState: %s(%d)"),
4785 lim_msg_str(pMsg->type), pMsg->type,
4786 lim_sme_state_str(pMac->lim.gLimSmeState), pMac->lim.gLimSmeState,
4787 lim_mlm_state_str(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState);
4788 )
4789
4790 pScanReq = (tpSirSmeScanReq) pMsgBuf;
4791 /* If no insert NOA required then execute the code below */
4792
4793 switch (pMsg->type) {
4794 case eWNI_SME_SYS_READY_IND:
4795 bufConsumed = __lim_process_sme_sys_ready_ind(pMac, pMsgBuf);
4796 break;
4797
4798 case eWNI_SME_START_BSS_REQ:
4799 bufConsumed = __lim_process_sme_start_bss_req(pMac, pMsg);
4800 break;
4801
4802 case eWNI_SME_SCAN_REQ:
4803 __lim_process_sme_scan_req(pMac, pMsgBuf);
4804 break;
4805
4806#ifdef FEATURE_OEM_DATA_SUPPORT
4807 case eWNI_SME_OEM_DATA_REQ:
4808 __lim_process_sme_oem_data_req(pMac, pMsgBuf);
4809 break;
4810#endif
4811 case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
4812 bufConsumed = lim_process_remain_on_chnl_req(pMac, pMsgBuf);
4813 break;
4814
4815 case eWNI_SME_UPDATE_NOA:
4816 __lim_process_sme_no_a_update(pMac, pMsgBuf);
4817 break;
4818 case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
4819 __lim_process_clear_dfs_channel_list(pMac, pMsg);
4820 break;
4821 case eWNI_SME_JOIN_REQ:
4822 __lim_process_sme_join_req(pMac, pMsgBuf);
4823 break;
4824
4825 case eWNI_SME_REASSOC_REQ:
4826 __lim_process_sme_reassoc_req(pMac, pMsgBuf);
4827 break;
4828
4829 case eWNI_SME_DISASSOC_REQ:
4830 __lim_process_sme_disassoc_req(pMac, pMsgBuf);
4831 break;
4832
4833 case eWNI_SME_DISASSOC_CNF:
4834 case eWNI_SME_DEAUTH_CNF:
4835 __lim_process_sme_disassoc_cnf(pMac, pMsgBuf);
4836 break;
4837
4838 case eWNI_SME_DEAUTH_REQ:
4839 __lim_process_sme_deauth_req(pMac, pMsgBuf);
4840 break;
4841
4842 case eWNI_SME_SETCONTEXT_REQ:
4843 __lim_process_sme_set_context_req(pMac, pMsgBuf);
4844 break;
4845
4846 case eWNI_SME_STOP_BSS_REQ:
4847 bufConsumed = __lim_process_sme_stop_bss_req(pMac, pMsg);
4848 break;
4849
4850 case eWNI_SME_ASSOC_CNF:
4851 if (pMsg->type == eWNI_SME_ASSOC_CNF)
4852 PELOG1(lim_log(pMac,
4853 LOG1, FL("Received ASSOC_CNF message"));)
4854 __lim_process_sme_assoc_cnf_new(pMac, pMsg->type,
4855 pMsgBuf);
4856 break;
4857
4858 case eWNI_SME_ADDTS_REQ:
4859 PELOG1(lim_log(pMac, LOG1, FL("Received ADDTS_REQ message"));)
4860 __lim_process_sme_addts_req(pMac, pMsgBuf);
4861 break;
4862
4863 case eWNI_SME_DELTS_REQ:
4864 PELOG1(lim_log(pMac, LOG1, FL("Received DELTS_REQ message"));)
4865 __lim_process_sme_delts_req(pMac, pMsgBuf);
4866 break;
4867
4868 case SIR_LIM_ADDTS_RSP_TIMEOUT:
4869 PELOG1(lim_log
4870 (pMac, LOG1,
4871 FL("Received SIR_LIM_ADDTS_RSP_TIMEOUT message "));
4872 )
4873 lim_process_sme_addts_rsp_timeout(pMac, pMsg->bodyval);
4874 break;
4875
4876 case eWNI_SME_GET_STATISTICS_REQ:
4877 __lim_process_sme_get_statistics_request(pMac, pMsgBuf);
4878 /* HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. */
4879 bufConsumed = false;
4880 break;
4881#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4882 case eWNI_SME_GET_TSM_STATS_REQ:
4883 __lim_process_sme_get_tsm_stats_request(pMac, pMsgBuf);
4884 bufConsumed = false;
4885 break;
4886#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4887 case eWNI_SME_GET_ASSOC_STAS_REQ:
4888 lim_process_sme_get_assoc_sta_info(pMac, pMsgBuf);
4889 break;
4890 case eWNI_SME_TKIP_CNTR_MEAS_REQ:
4891 lim_process_tkip_counter_measures(pMac, pMsgBuf);
4892 break;
4893
4894 case eWNI_SME_HIDE_SSID_REQ:
4895 __lim_process_sme_hide_ssid(pMac, pMsgBuf);
4896 break;
4897 case eWNI_SME_UPDATE_APWPSIE_REQ:
4898 __lim_process_sme_update_apwpsi_es(pMac, pMsgBuf);
4899 break;
4900 case eWNI_SME_GET_WPSPBC_SESSION_REQ:
4901 lim_process_sme_get_wpspbc_sessions(pMac, pMsgBuf);
4902 break;
4903
4904 case eWNI_SME_SET_APWPARSNIEs_REQ:
4905 __lim_process_sme_set_wparsni_es(pMac, pMsgBuf);
4906 break;
4907
4908 case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
4909 /* Update the beaconInterval */
4910 __lim_process_sme_change_bi(pMac, pMsgBuf);
4911 break;
4912
4913#ifdef QCA_HT_2040_COEX
4914 case eWNI_SME_SET_HT_2040_MODE:
4915 __lim_process_sme_set_ht2040_mode(pMac, pMsgBuf);
4916 break;
4917#endif
4918
4919#if defined WLAN_FEATURE_VOWIFI
4920 case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
4921 case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
4922 __lim_process_report_message(pMac, pMsg);
4923 break;
4924#endif
4925
4926#if defined WLAN_FEATURE_VOWIFI_11R
4927 case eWNI_SME_FT_PRE_AUTH_REQ:
4928 bufConsumed = (bool) lim_process_ft_pre_auth_req(pMac, pMsg);
4929 break;
4930 case eWNI_SME_FT_UPDATE_KEY:
4931 lim_process_ft_update_key(pMac, pMsgBuf);
4932 break;
4933
4934 case eWNI_SME_FT_AGGR_QOS_REQ:
4935 lim_process_ft_aggr_qos_req(pMac, pMsgBuf);
4936 break;
4937#endif
4938
4939 case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
4940 __lim_process_sme_register_mgmt_frame_req(pMac, pMsgBuf);
4941 break;
4942#ifdef FEATURE_WLAN_TDLS
4943 case eWNI_SME_TDLS_SEND_MGMT_REQ:
4944 lim_process_sme_tdls_mgmt_send_req(pMac, pMsgBuf);
4945 break;
4946 case eWNI_SME_TDLS_ADD_STA_REQ:
4947 lim_process_sme_tdls_add_sta_req(pMac, pMsgBuf);
4948 break;
4949 case eWNI_SME_TDLS_DEL_STA_REQ:
4950 lim_process_sme_tdls_del_sta_req(pMac, pMsgBuf);
4951 break;
4952 case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
4953 lim_process_sme_tdls_link_establish_req(pMac, pMsgBuf);
4954 break;
4955#endif
4956 case eWNI_SME_RESET_AP_CAPS_CHANGED:
4957 __lim_process_sme_reset_ap_caps_change(pMac, pMsgBuf);
4958 break;
4959
4960 case eWNI_SME_CHANNEL_CHANGE_REQ:
4961 lim_process_sme_channel_change_request(pMac, pMsgBuf);
4962 break;
4963
4964 case eWNI_SME_START_BEACON_REQ:
4965 lim_process_sme_start_beacon_req(pMac, pMsgBuf);
4966 break;
4967
4968 case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
4969 lim_process_sme_dfs_csa_ie_request(pMac, pMsgBuf);
4970 break;
4971
4972 case eWNI_SME_UPDATE_ADDITIONAL_IES:
4973 lim_process_update_add_ies(pMac, pMsgBuf);
4974 break;
4975
4976 case eWNI_SME_MODIFY_ADDITIONAL_IES:
4977 lim_process_modify_add_ies(pMac, pMsgBuf);
4978 break;
4979 case eWNI_SME_SET_HW_MODE_REQ:
4980 lim_process_set_hw_mode(pMac, pMsgBuf);
4981 break;
4982 case eWNI_SME_NSS_UPDATE_REQ:
4983 lim_process_nss_update_request(pMac, pMsgBuf);
4984 break;
4985 case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
4986 lim_process_set_dual_mac_cfg_req(pMac, pMsgBuf);
4987 break;
4988 case eWNI_SME_SET_IE_REQ:
4989 lim_process_set_ie_req(pMac, pMsgBuf);
4990 break;
4991 default:
4992 cdf_mem_free((void *)pMsg->bodyptr);
4993 pMsg->bodyptr = NULL;
4994 break;
4995 } /* switch (msgType) */
4996
4997 return bufConsumed;
4998} /*** end lim_process_sme_req_messages() ***/
4999
5000/**
5001 * lim_process_sme_start_beacon_req()
5002 *
5003 ***FUNCTION:
5004 * This function is called by limProcessMessageQueue(). This
5005 * function processes SME request messages from HDD or upper layer
5006 * application.
5007 *
5008 ***LOGIC:
5009 *
5010 ***ASSUMPTIONS:
5011 *
5012 ***NOTE:
5013 *
5014 * @param pMac Pointer to Global MAC structure
5015 * @param msgType Indicates the SME message type
5016 * @param *pMsgBuf A pointer to the SME message buffer
5017 * @return Boolean - true - if pMsgBuf is consumed and can be freed.
5018 * false - if pMsgBuf is not to be freed.
5019 */
5020static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg)
5021{
5022 tpSirStartBeaconIndication pBeaconStartInd;
5023 tpPESession psessionEntry;
5024 uint8_t sessionId; /* PE sessionID */
5025
5026 if (pMsg == NULL) {
5027 lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
5028 return;
5029 }
5030
5031 pBeaconStartInd = (tpSirStartBeaconIndication) pMsg;
5032 psessionEntry = pe_find_session_by_bssid(pMac,
5033 pBeaconStartInd->bssid,
5034 &sessionId);
5035 if (psessionEntry == NULL) {
5036 lim_print_mac_addr(pMac, pBeaconStartInd->bssid, LOGE);
5037 lim_log(pMac, LOGE,
5038 FL("Session does not exist for given bssId"));
5039 return;
5040 }
5041
5042 if (pBeaconStartInd->beaconStartStatus == true) {
5043 /*
5044 * Currently this Indication comes from SAP
5045 * to start Beacon Tx on a DFS channel
5046 * since beaconing has to be done on DFS
5047 * channel only after CAC WAIT is completed.
5048 * On a DFS Channel LIM does not start beacon
5049 * Tx right after the WMA_ADD_BSS_RSP.
5050 */
5051 lim_apply_configuration(pMac, psessionEntry);
5052 CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
5053 FL("Start Beacon with ssid %s Ch %d"),
5054 psessionEntry->ssId.ssId,
5055 psessionEntry->currentOperChannel);
5056 lim_send_beacon_ind(pMac, psessionEntry);
5057 } else {
5058 lim_log(pMac, LOGE, FL("Invalid Beacon Start Indication"));
5059 return;
5060 }
5061}
5062
5063/**
5064 * lim_process_sme_channel_change_request() - process sme ch change req
5065 *
5066 * @mac_ctx: Pointer to Global MAC structure
5067 * @msg_buf: pointer to the SME message buffer
5068 *
5069 * This function is called to process SME_CHANNEL_CHANGE_REQ message
5070 *
5071 * Return: None
5072 */
5073static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx,
5074 uint32_t *msg_buf)
5075{
5076 tpSirChanChangeRequest ch_change_req;
5077 tpPESession session_entry;
5078 uint8_t session_id; /* PE session_id */
5079 tPowerdBm max_tx_pwr;
5080 uint32_t val = 0;
5081
5082 if (msg_buf == NULL) {
5083 lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
5084 return;
5085 }
5086 ch_change_req = (tpSirChanChangeRequest)msg_buf;
5087
5088 max_tx_pwr = cfg_get_regulatory_max_transmit_power(mac_ctx,
5089 ch_change_req->targetChannel);
5090
5091 if ((ch_change_req->messageType != eWNI_SME_CHANNEL_CHANGE_REQ) ||
5092 (max_tx_pwr == WMA_MAX_TXPOWER_INVALID)) {
5093 lim_log(mac_ctx, LOGE, FL("Invalid Request/max_tx_pwr"));
5094 return;
5095 }
5096
5097 session_entry = pe_find_session_by_bssid(mac_ctx,
5098 ch_change_req->bssid, &session_id);
5099 if (session_entry == NULL) {
5100 lim_print_mac_addr(mac_ctx, ch_change_req->bssid, LOGE);
5101 lim_log(mac_ctx, LOGE, FL(
5102 "Session does not exist for given bssId"));
5103 return;
5104 }
5105
5106 if (session_entry->currentOperChannel ==
5107 ch_change_req->targetChannel) {
5108 lim_log(mac_ctx, LOGE, FL("target CH is same as current CH"));
5109 return;
5110 }
5111
5112 if (LIM_IS_AP_ROLE(session_entry))
5113 session_entry->channelChangeReasonCode =
5114 LIM_SWITCH_CHANNEL_SAP_DFS;
5115 else
5116 session_entry->channelChangeReasonCode =
5117 LIM_SWITCH_CHANNEL_OPERATION;
5118
5119 lim_log(mac_ctx, LOGW, FL(
5120 "switch old chnl %d to new chnl %d, ch_bw %d"),
5121 session_entry->currentOperChannel,
5122 ch_change_req->targetChannel,
5123 ch_change_req->channel_width);
5124
5125 /* Store the New Channel Params in session_entry */
5126 session_entry->ch_width = ch_change_req->channel_width;
5127 session_entry->ch_center_freq_seg0 =
5128 ch_change_req->center_freq_seg_0;
5129 session_entry->ch_center_freq_seg1 =
5130 ch_change_req->center_freq_seg_1;
5131 session_entry->htSecondaryChannelOffset = ch_change_req->cbMode;
5132 session_entry->htSupportedChannelWidthSet =
5133 (ch_change_req->channel_width ? 1 : 0);
5134 session_entry->htRecommendedTxWidthSet =
5135 session_entry->htSupportedChannelWidthSet;
5136 session_entry->currentOperChannel =
5137 ch_change_req->targetChannel;
5138 session_entry->limRFBand =
5139 lim_get_rf_band(session_entry->currentOperChannel);
5140 /* Initialize 11h Enable Flag */
5141 if (SIR_BAND_5_GHZ == session_entry->limRFBand) {
5142 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val) !=
5143 eSIR_SUCCESS)
5144 lim_log(mac_ctx, LOGP,
5145 FL("Fail to get WNI_CFG_11H_ENABLED"));
5146 }
5147
5148 session_entry->lim11hEnable = val;
5149 session_entry->dot11mode = ch_change_req->dot11mode;
5150 cdf_mem_copy(&session_entry->rateSet,
5151 &ch_change_req->operational_rateset,
5152 sizeof(session_entry->rateSet));
5153 cdf_mem_copy(&session_entry->extRateSet,
5154 &ch_change_req->extended_rateset,
5155 sizeof(session_entry->extRateSet));
5156 lim_set_channel(mac_ctx, ch_change_req->targetChannel,
5157 session_entry->ch_center_freq_seg0,
5158 session_entry->ch_center_freq_seg1,
5159 session_entry->ch_width,
5160 max_tx_pwr, session_entry->peSessionId);
5161}
5162
5163/******************************************************************************
5164* lim_start_bss_update_add_ie_buffer()
5165*
5166***FUNCTION:
5167* This function checks the src buffer and its length and then malloc for
5168* dst buffer update the same
5169*
5170***LOGIC:
5171*
5172***ASSUMPTIONS:
5173*
5174***NOTE:
5175*
5176* @param pMac Pointer to Global MAC structure
5177* @param **pDstData_buff A pointer to pointer of uint8_t dst buffer
5178* @param *pDstDataLen A pointer to pointer of uint16_t dst buffer length
5179* @param *pSrcData_buff A pointer of uint8_t src buffer
5180* @param srcDataLen src buffer length
5181******************************************************************************/
5182
5183static void
5184lim_start_bss_update_add_ie_buffer(tpAniSirGlobal pMac,
5185 uint8_t **pDstData_buff,
5186 uint16_t *pDstDataLen,
5187 uint8_t *pSrcData_buff, uint16_t srcDataLen)
5188{
5189
5190 if (srcDataLen > 0 && pSrcData_buff != NULL) {
5191 *pDstDataLen = srcDataLen;
5192
5193 *pDstData_buff = cdf_mem_malloc(*pDstDataLen);
5194
5195 if (NULL == *pDstData_buff) {
5196 lim_log(pMac, LOGE,
5197 FL("AllocateMemory failed for pDstData_buff"));
5198 return;
5199 }
5200 cdf_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
5201 } else {
5202 *pDstData_buff = NULL;
5203 *pDstDataLen = 0;
5204 }
5205}
5206
5207/******************************************************************************
5208* lim_update_add_ie_buffer()
5209*
5210***FUNCTION:
5211* This function checks the src buffer and length if src buffer length more
5212* than dst buffer length then free the dst buffer and malloc for the new src
5213* length, and update the dst buffer and length. But if dst buffer is bigger
5214* than src buffer length then it just update the dst buffer and length
5215*
5216***LOGIC:
5217*
5218***ASSUMPTIONS:
5219*
5220***NOTE:
5221*
5222* @param pMac Pointer to Global MAC structure
5223* @param **pDstData_buff A pointer to pointer of uint8_t dst buffer
5224* @param *pDstDataLen A pointer to pointer of uint16_t dst buffer length
5225* @param *pSrcData_buff A pointer of uint8_t src buffer
5226* @param srcDataLen src buffer length
5227******************************************************************************/
5228
5229static void
5230lim_update_add_ie_buffer(tpAniSirGlobal pMac,
5231 uint8_t **pDstData_buff,
5232 uint16_t *pDstDataLen,
5233 uint8_t *pSrcData_buff, uint16_t srcDataLen)
5234{
5235
5236 if (NULL == pSrcData_buff) {
5237 lim_log(pMac, LOGE, FL("src buffer is null."));
5238 return;
5239 }
5240
5241 if (srcDataLen > *pDstDataLen) {
5242 *pDstDataLen = srcDataLen;
5243 /* free old buffer */
5244 cdf_mem_free(*pDstData_buff);
5245 /* allocate a new */
5246 *pDstData_buff = cdf_mem_malloc(*pDstDataLen);
5247
5248 if (NULL == *pDstData_buff) {
5249 lim_log(pMac, LOGE, FL("Memory allocation failed."));
5250 *pDstDataLen = 0;
5251 return;
5252 }
5253 }
5254
5255 /* copy the content of buffer into dst buffer
5256 */
5257 *pDstDataLen = srcDataLen;
5258 cdf_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
5259
5260}
5261
5262/*
5263* lim_process_modify_add_ies() - process modify additional IE req.
5264*
5265* @mac_ctx: Pointer to Global MAC structure
5266* @msg_buf: pointer to the SME message buffer
5267*
5268* This function update the PE buffers for additional IEs.
5269*
5270* Return: None
5271*/
5272static void lim_process_modify_add_ies(tpAniSirGlobal mac_ctx,
5273 uint32_t *msg_buf)
5274{
5275 tpSirModifyIEsInd modify_add_ies;
5276 tpPESession session_entry;
5277 uint8_t session_id;
5278 bool ret = false;
5279 tSirAddIeParams *add_ie_params;
5280
5281 if (msg_buf == NULL) {
5282 lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
5283 return;
5284 }
5285
5286 modify_add_ies = (tpSirModifyIEsInd)msg_buf;
5287 /* Incoming message has smeSession, use BSSID to find PE session */
5288 session_entry = pe_find_session_by_bssid(mac_ctx,
5289 modify_add_ies->modifyIE.bssid, &session_id);
5290
5291 if (NULL == session_entry) {
5292 lim_log(mac_ctx, LOGE, FL("Session not found for given bssid. "
5293 MAC_ADDRESS_STR),
5294 MAC_ADDR_ARRAY(modify_add_ies->modifyIE.bssid));
5295 goto end;
5296 }
5297 if ((0 == modify_add_ies->modifyIE.ieBufferlength) ||
5298 (0 == modify_add_ies->modifyIE.ieIDLen) ||
5299 (NULL == modify_add_ies->modifyIE.pIEBuffer)) {
5300 lim_log(mac_ctx, LOGE,
5301 FL("Invalid request pIEBuffer %p ieBufferlength %d ieIDLen %d ieID %d. update Type %d"),
5302 modify_add_ies->modifyIE.pIEBuffer,
5303 modify_add_ies->modifyIE.ieBufferlength,
5304 modify_add_ies->modifyIE.ieID,
5305 modify_add_ies->modifyIE.ieIDLen,
5306 modify_add_ies->updateType);
5307 goto end;
5308 }
5309 add_ie_params = &session_entry->addIeParams;
5310 switch (modify_add_ies->updateType) {
5311 case eUPDATE_IE_PROBE_RESP:
5312 /* Probe resp */
5313 break;
5314 case eUPDATE_IE_ASSOC_RESP:
5315 /* assoc resp IE */
5316 if (add_ie_params->assocRespDataLen == 0) {
5317 CDF_TRACE(CDF_MODULE_ID_PE,
5318 CDF_TRACE_LEVEL_ERROR, FL(
5319 "assoc resp add ie not present %d"),
5320 add_ie_params->assocRespDataLen);
5321 }
5322 /* search through the buffer and modify the IE */
5323 break;
5324 case eUPDATE_IE_PROBE_BCN:
5325 /*probe beacon IE */
5326 if (ret == true && modify_add_ies->modifyIE.notify) {
5327 lim_handle_param_update(mac_ctx,
5328 modify_add_ies->updateType);
5329 }
5330 break;
5331 default:
5332 lim_log(mac_ctx, LOGE, FL("unhandled buffer type %d"),
5333 modify_add_ies->updateType);
5334 break;
5335 }
5336end:
5337 cdf_mem_free(modify_add_ies->modifyIE.pIEBuffer);
5338 modify_add_ies->modifyIE.pIEBuffer = NULL;
5339}
5340
5341/*
5342* lim_process_update_add_ies() - process additional IE update req
5343*
5344* @mac_ctx: Pointer to Global MAC structure
5345* @msg_buf: pointer to the SME message buffer
5346*
5347* This function update the PE buffers for additional IEs.
5348*
5349* Return: None
5350*/
5351static void lim_process_update_add_ies(tpAniSirGlobal mac_ctx,
5352 uint32_t *msg_buf)
5353{
5354 tpSirUpdateIEsInd update_add_ies = (tpSirUpdateIEsInd)msg_buf;
5355 uint8_t session_id;
5356 tpPESession session_entry;
5357 tSirAddIeParams *addn_ie;
5358 uint16_t new_length = 0;
5359 uint8_t *new_ptr = NULL;
5360 tSirUpdateIE *update_ie;
5361
5362 if (msg_buf == NULL) {
5363 lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
5364 return;
5365 }
5366 update_ie = &update_add_ies->updateIE;
5367 /* incoming message has smeSession, use BSSID to find PE session */
5368 session_entry = pe_find_session_by_bssid(mac_ctx,
5369 update_ie->bssid, &session_id);
5370
5371 if (NULL == session_entry) {
5372 lim_log(mac_ctx, LOGE, FL("Session not found for given bssid. "
5373 MAC_ADDRESS_STR),
5374 MAC_ADDR_ARRAY(update_ie->bssid));
5375 goto end;
5376 }
5377 addn_ie = &session_entry->addIeParams;
5378 /* if len is 0, upper layer requested freeing of buffer */
5379 if (0 == update_ie->ieBufferlength) {
5380 switch (update_add_ies->updateType) {
5381 case eUPDATE_IE_PROBE_RESP:
5382 cdf_mem_free(addn_ie->probeRespData_buff);
5383 addn_ie->probeRespData_buff = NULL;
5384 addn_ie->probeRespDataLen = 0;
5385 break;
5386 case eUPDATE_IE_ASSOC_RESP:
5387 cdf_mem_free(addn_ie->assocRespData_buff);
5388 addn_ie->assocRespData_buff = NULL;
5389 addn_ie->assocRespDataLen = 0;
5390 break;
5391 case eUPDATE_IE_PROBE_BCN:
5392 cdf_mem_free(addn_ie->probeRespBCNData_buff);
5393 addn_ie->probeRespBCNData_buff = NULL;
5394 addn_ie->probeRespBCNDataLen = 0;
5395
5396 if (update_ie->notify)
5397 lim_handle_param_update(mac_ctx,
5398 update_add_ies->updateType);
5399 break;
5400 default:
5401 break;
5402 }
5403 return;
5404 }
5405 switch (update_add_ies->updateType) {
5406 case eUPDATE_IE_PROBE_RESP:
5407 if (update_ie->append) {
5408 /*
5409 * In case of append, allocate new memory
5410 * with combined length
5411 */
5412 new_length = update_ie->ieBufferlength +
5413 addn_ie->probeRespDataLen;
5414 new_ptr = cdf_mem_malloc(new_length);
5415 if (NULL == new_ptr) {
5416 lim_log(mac_ctx, LOGE, FL(
5417 "Memory allocation failed."));
5418 goto end;
5419 }
5420 /* append buffer to end of local buffers */
5421 cdf_mem_copy(new_ptr, addn_ie->probeRespData_buff,
5422 addn_ie->probeRespDataLen);
5423 cdf_mem_copy(&new_ptr[addn_ie->probeRespDataLen],
5424 update_ie->pAdditionIEBuffer,
5425 update_ie->ieBufferlength);
5426 /* free old memory */
5427 cdf_mem_free(addn_ie->probeRespData_buff);
5428 /* adjust length accordingly */
5429 addn_ie->probeRespDataLen = new_length;
5430 /* save refernece of local buffer in PE session */
5431 addn_ie->probeRespData_buff = new_ptr;
5432 goto end;
5433 }
5434 lim_update_add_ie_buffer(mac_ctx, &addn_ie->probeRespData_buff,
5435 &addn_ie->probeRespDataLen,
5436 update_ie->pAdditionIEBuffer,
5437 update_ie->ieBufferlength);
5438 break;
5439 case eUPDATE_IE_ASSOC_RESP:
5440 /* assoc resp IE */
5441 lim_update_add_ie_buffer(mac_ctx, &addn_ie->assocRespData_buff,
5442 &addn_ie->assocRespDataLen,
5443 update_ie->pAdditionIEBuffer,
5444 update_ie->ieBufferlength);
5445 break;
5446 case eUPDATE_IE_PROBE_BCN:
5447 /* probe resp Bcn IE */
5448 lim_update_add_ie_buffer(mac_ctx,
5449 &addn_ie->probeRespBCNData_buff,
5450 &addn_ie->probeRespBCNDataLen,
5451 update_ie->pAdditionIEBuffer,
5452 update_ie->ieBufferlength);
5453 if (update_ie->notify)
5454 lim_handle_param_update(mac_ctx,
5455 update_add_ies->updateType);
5456 break;
5457 default:
5458 lim_log(mac_ctx, LOGE, FL("unhandled buffer type %d."),
5459 update_add_ies->updateType);
5460 break;
5461 }
5462end:
5463 cdf_mem_free(update_ie->pAdditionIEBuffer);
5464 update_ie->pAdditionIEBuffer = NULL;
5465}
5466
5467/**
5468 * lim_process_sme_dfs_csa_ie_request() - process sme dfs csa ie req
5469 *
5470 * @mac_ctx: Pointer to Global MAC structure
5471 * @msg_buf: pointer to the SME message buffer
5472 *
5473 * This function processes SME request messages from HDD or upper layer
5474 * application.
5475 *
5476 * Return: None
5477 */
5478static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal mac_ctx,
5479 uint32_t *msg_buf)
5480{
5481 tpSirDfsCsaIeRequest dfs_csa_ie_req;
5482 tpPESession session_entry = NULL;
5483 uint32_t ch_width = 0;
5484 uint8_t session_id;
5485 tLimWiderBWChannelSwitchInfo *wider_bw_ch_switch;
5486
5487 if (msg_buf == NULL) {
5488 lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
5489 return;
5490 }
5491
5492 dfs_csa_ie_req = (tSirDfsCsaIeRequest *)msg_buf;
5493 session_entry = pe_find_session_by_bssid(mac_ctx,
5494 dfs_csa_ie_req->bssid, &session_id);
5495 if (session_entry == NULL) {
5496 lim_log(mac_ctx, LOGE, FL(
5497 "Session not found for given BSSID" MAC_ADDRESS_STR),
5498 MAC_ADDR_ARRAY(dfs_csa_ie_req->bssid));
5499 return;
5500 }
5501
5502 if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
5503 lim_log(mac_ctx, LOGE, FL("Invalid SystemRole %d"),
5504 GET_LIM_SYSTEM_ROLE(session_entry));
5505 return;
5506 }
5507
5508 /* target channel */
5509 session_entry->gLimChannelSwitch.primaryChannel =
5510 dfs_csa_ie_req->targetChannel;
5511
5512 /* Channel switch announcement needs to be included in beacon */
5513 session_entry->dfsIncludeChanSwIe = true;
5514 session_entry->gLimChannelSwitch.switchCount = LIM_MAX_CSA_IE_UPDATES;
5515 session_entry->gLimChannelSwitch.ch_width =
5516 dfs_csa_ie_req->ch_bandwidth;
5517 if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)
5518 session_entry->gLimChannelSwitch.switchMode = 1;
5519
5520 /*
5521 * Validate if SAP is operating HT or VHT mode and set the Channel
5522 * Switch Wrapper element with the Wide Band Switch subelement.
5523 */
5524 if (true != session_entry->vhtCapability)
5525 goto skip_vht;
5526
5527 if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ ==
5528 session_entry->vhtTxChannelWidthSet)
5529 ch_width = eHT_CHANNEL_WIDTH_80MHZ;
5530 else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ ==
5531 session_entry->vhtTxChannelWidthSet)
5532 ch_width = session_entry->htSupportedChannelWidthSet;
5533 /* Now encode the Wider Ch BW element depending on the ch width */
5534 wider_bw_ch_switch = &session_entry->gLimWiderBWChannelSwitch;
5535 switch (ch_width) {
5536 case eHT_CHANNEL_WIDTH_20MHZ:
5537 /*
5538 * Wide channel BW sublement in channel wrapper element is not
5539 * required in case of 20 Mhz operation. Currently It is set
5540 * only set in case of 40/80 Mhz Operation.
5541 */
5542 session_entry->dfsIncludeChanWrapperIe = false;
5543 wider_bw_ch_switch->newChanWidth =
5544 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
5545 break;
5546 case eHT_CHANNEL_WIDTH_40MHZ:
5547 session_entry->dfsIncludeChanWrapperIe = true;
5548 wider_bw_ch_switch->newChanWidth =
5549 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
5550 break;
5551 case eHT_CHANNEL_WIDTH_80MHZ:
5552 session_entry->dfsIncludeChanWrapperIe = true;
5553 wider_bw_ch_switch->newChanWidth =
5554 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
5555 break;
5556 case eHT_CHANNEL_WIDTH_160MHZ:
5557 session_entry->dfsIncludeChanWrapperIe = true;
5558 wider_bw_ch_switch->newChanWidth =
5559 WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
5560 break;
5561 default:
5562 session_entry->dfsIncludeChanWrapperIe = false;
5563 /*
5564 * Need to handle 80+80 Mhz Scenario. When 80+80 is supported
5565 * set the gLimWiderBWChannelSwitch.newChanWidth to 3
5566 */
5567 lim_log(mac_ctx, LOGE, FL("Invalid Channel Width"));
5568 break;
5569 }
5570 /* Fetch the center channel based on the channel width */
5571 wider_bw_ch_switch->newCenterChanFreq0 =
5572 lim_get_center_channel(mac_ctx, dfs_csa_ie_req->targetChannel,
5573 session_entry->htSecondaryChannelOffset,
5574 wider_bw_ch_switch->newChanWidth);
5575 /*
5576 * This is not applicable for 20/40/80 Mhz.Only used when we support
5577 * 80+80 Mhz operation. In case of 80+80 Mhz, this parameter indicates
5578 * center channel frequency index of 80 Mhz channel of
5579 * frequency segment 1.
5580 */
5581 wider_bw_ch_switch->newCenterChanFreq1 = 0;
5582skip_vht:
5583 /* Send CSA IE request from here */
5584 if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
5585 eSIR_SUCCESS) {
5586 lim_log(mac_ctx, LOGE, FL("Unable to set CSA IE in beacon"));
5587 return;
5588 }
5589
5590 /*
5591 * First beacon update request is sent here, the remaining updates are
5592 * done when the FW responds back after sending the first beacon after
5593 * the template update
5594 */
5595 lim_send_beacon_ind(mac_ctx, session_entry);
5596 lim_log(mac_ctx, LOG1, FL("Updated CSA IE, IE COUNT = %d"),
5597 session_entry->gLimChannelSwitch.switchCount);
5598 session_entry->gLimChannelSwitch.switchCount--;
5599}
5600
5601/**
5602 * lim_process_nss_update_request() - process sme nss update req
5603 *
5604 * @mac_ctx: Pointer to Global MAC structure
5605 * @msg_buf: pointer to the SME message buffer
5606 *
5607 * This function processes SME request messages from HDD or upper layer
5608 * application.
5609 *
5610 * Return: None
5611 */
5612static void lim_process_nss_update_request(tpAniSirGlobal mac_ctx,
5613 uint32_t *msg_buf)
5614{
5615 struct sir_nss_update_request *nss_update_req_ptr;
5616 tpPESession session_entry = NULL;
5617
5618 if (msg_buf == NULL) {
5619 lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
5620 return;
5621 }
5622
5623 nss_update_req_ptr = (struct sir_nss_update_request *)msg_buf;
5624 session_entry = pe_find_session_by_session_id(mac_ctx,
5625 nss_update_req_ptr->vdev_id);
5626 if (session_entry == NULL) {
5627 lim_log(mac_ctx, LOGE, FL(
5628 "Session not found for given session_id %d"),
5629 nss_update_req_ptr->vdev_id);
5630 return;
5631 }
5632
5633 if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
5634 lim_log(mac_ctx, LOGE, FL("Invalid SystemRole %d"),
5635 GET_LIM_SYSTEM_ROLE(session_entry));
5636 return;
5637 }
5638
5639 /* populate nss field in the beacon */
5640 session_entry->gLimOperatingMode.present = 1;
5641 session_entry->gLimOperatingMode.rxNSS = nss_update_req_ptr->new_nss;
5642 /* Send nss update request from here */
5643 if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
5644 eSIR_SUCCESS) {
5645 lim_log(mac_ctx, LOGE,
5646 FL("Unable to set op mode IE in beacon"));
5647 return;
5648 }
5649
5650 lim_send_beacon_ind(mac_ctx, session_entry);
5651}
5652
5653/**
5654 * lim_process_set_ie_req() - process sme set IE request
5655 *
5656 * @mac_ctx: Pointer to Global MAC structure
5657 * @msg_buf: pointer to the SME message buffer
5658 *
5659 * This function processes SME request messages from HDD or upper layer
5660 * application.
5661 *
5662 * Return: None
5663 */
5664static void lim_process_set_ie_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
5665{
5666 struct send_extcap_ie *msg;
5667 CDF_STATUS status;
5668
5669 if (msg_buf == NULL) {
5670 lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
5671 return;
5672 }
5673
5674 msg = (struct send_extcap_ie *)msg_buf;
5675 status = lim_send_ext_cap_ie(mac_ctx, msg->session_id, NULL, false);
5676 if (CDF_STATUS_SUCCESS != status)
5677 lim_log(mac_ctx, LOGE, FL("Unable to send ExtCap to FW"));
5678
5679}