blob: 350bffc604d4caab48d21ad61df38d7abfd4140e [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Prashanth Bhatta9e143052015-12-04 11:56:47 -08002 * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
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_utils.cc contains the utility functions
30 * LIM uses.
31 * Author: Chandra Modumudi
32 * Date: 02/13/02
33 * History:-
34 * Date Modified by Modification Information
35 * --------------------------------------------------------------------
36 */
37
38#include "sch_api.h"
39#include "lim_utils.h"
40#include "lim_types.h"
41#include "lim_security_utils.h"
42#include "lim_prop_exts_utils.h"
43#include "lim_send_messages.h"
44#include "lim_ser_des_utils.h"
45#include "lim_admit_control.h"
46#include "lim_sta_hash_api.h"
47#include "dot11f.h"
48#include "dot11fdefs.h"
49#include "wmm_apsd.h"
50#include "lim_trace.h"
51#ifdef FEATURE_WLAN_DIAG_SUPPORT
52#include "host_diag_core_event.h"
53#endif /* FEATURE_WLAN_DIAG_SUPPORT */
54#include "lim_ibss_peer_mgmt.h"
55#include "lim_session_utils.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080056#include "lim_ft_defs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057#include "lim_session.h"
58#include "cds_reg_service.h"
59
60#ifdef WLAN_FEATURE_11W
61#include "wni_cfg.h"
62#endif
63#define ASCII_SPACE_CHARACTER 0x20
64
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065/** -------------------------------------------------------------
66 \fn lim_delete_dialogue_token_list
67 \brief deletes the complete lim dialogue token linked list.
68 \param tpAniSirGlobal pMac
69 \return None
70 -------------------------------------------------------------*/
71void lim_delete_dialogue_token_list(tpAniSirGlobal pMac)
72{
73 tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead;
74
75 while (NULL != pMac->lim.pDialogueTokenHead) {
76 pCurrNode = pMac->lim.pDialogueTokenHead;
77 pMac->lim.pDialogueTokenHead =
78 pMac->lim.pDialogueTokenHead->next;
Anurag Chouhan600c3a02016-03-01 10:33:54 +053079 qdf_mem_free(pCurrNode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080 pCurrNode = NULL;
81 }
82 pMac->lim.pDialogueTokenTail = NULL;
83}
84
85char *lim_dot11_reason_str(uint16_t reasonCode)
86{
87 switch (reasonCode) {
88 case 0:
89 return " ";
90 CASE_RETURN_STRING(eSIR_MAC_UNSPEC_FAILURE_REASON);
91 CASE_RETURN_STRING(eSIR_MAC_PREV_AUTH_NOT_VALID_REASON);
92 CASE_RETURN_STRING(eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
93 CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON);
94 CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON);
95 CASE_RETURN_STRING
96 (eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON);
97 CASE_RETURN_STRING
98 (eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON);
99 CASE_RETURN_STRING(eSIR_MAC_DISASSOC_LEAVING_BSS_REASON);
100 CASE_RETURN_STRING(eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON);
101 CASE_RETURN_STRING(eSIR_MAC_PWR_CAPABILITY_BAD_REASON);
102 CASE_RETURN_STRING(eSIR_MAC_SPRTD_CHANNELS_BAD_REASON);
103
104 CASE_RETURN_STRING(eSIR_MAC_INVALID_IE_REASON);
105 CASE_RETURN_STRING(eSIR_MAC_MIC_FAILURE_REASON);
106 CASE_RETURN_STRING(eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON);
107 CASE_RETURN_STRING(eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON);
108 CASE_RETURN_STRING(eSIR_MAC_RSN_IE_MISMATCH_REASON);
109
110 CASE_RETURN_STRING(eSIR_MAC_INVALID_MC_CIPHER_REASON);
111 CASE_RETURN_STRING(eSIR_MAC_INVALID_UC_CIPHER_REASON);
112 CASE_RETURN_STRING(eSIR_MAC_INVALID_AKMP_REASON);
113 CASE_RETURN_STRING(eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON);
114 CASE_RETURN_STRING(eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON);
115 CASE_RETURN_STRING(eSIR_MAC_1X_AUTH_FAILURE_REASON);
116 CASE_RETURN_STRING(eSIR_MAC_CIPHER_SUITE_REJECTED_REASON);
117#ifdef FEATURE_WLAN_TDLS
118 CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE);
119 CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
120#endif
121 /* Reserved 27 - 30 */
122#ifdef WLAN_FEATURE_11W
123 CASE_RETURN_STRING
124 (eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION);
125#endif
126 CASE_RETURN_STRING(eSIR_MAC_QOS_UNSPECIFIED_REASON);
127 CASE_RETURN_STRING(eSIR_MAC_QAP_NO_BANDWIDTH_REASON);
128 CASE_RETURN_STRING(eSIR_MAC_XS_UNACKED_FRAMES_REASON);
129 CASE_RETURN_STRING(eSIR_MAC_BAD_TXOP_USE_REASON);
130 CASE_RETURN_STRING(eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON);
131 CASE_RETURN_STRING(eSIR_MAC_PEER_REJECT_MECHANISIM_REASON);
132 CASE_RETURN_STRING(eSIR_MAC_MECHANISM_NOT_SETUP_REASON);
133
134 CASE_RETURN_STRING(eSIR_MAC_PEER_TIMEDOUT_REASON);
135 CASE_RETURN_STRING(eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON);
136 CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON);
137 /* Reserved 47 - 65535 */
138 default:
139 return "Unknown";
140 }
141}
142
143char *lim_mlm_state_str(tLimMlmStates state)
144{
145 switch (state) {
146 case eLIM_MLM_OFFLINE_STATE:
147 return "eLIM_MLM_OFFLINE_STATE";
148 case eLIM_MLM_IDLE_STATE:
149 return "eLIM_MLM_IDLE_STATE";
150 case eLIM_MLM_WT_PROBE_RESP_STATE:
151 return "eLIM_MLM_WT_PROBE_RESP_STATE";
152 case eLIM_MLM_PASSIVE_SCAN_STATE:
153 return "eLIM_MLM_PASSIVE_SCAN_STATE";
154 case eLIM_MLM_WT_JOIN_BEACON_STATE:
155 return "eLIM_MLM_WT_JOIN_BEACON_STATE";
156 case eLIM_MLM_JOINED_STATE:
157 return "eLIM_MLM_JOINED_STATE";
158 case eLIM_MLM_BSS_STARTED_STATE:
159 return "eLIM_MLM_BSS_STARTED_STATE";
160 case eLIM_MLM_WT_AUTH_FRAME2_STATE:
161 return "eLIM_MLM_WT_AUTH_FRAME2_STATE";
162 case eLIM_MLM_WT_AUTH_FRAME3_STATE:
163 return "eLIM_MLM_WT_AUTH_FRAME3_STATE";
164 case eLIM_MLM_WT_AUTH_FRAME4_STATE:
165 return "eLIM_MLM_WT_AUTH_FRAME4_STATE";
166 case eLIM_MLM_AUTH_RSP_TIMEOUT_STATE:
167 return "eLIM_MLM_AUTH_RSP_TIMEOUT_STATE";
168 case eLIM_MLM_AUTHENTICATED_STATE:
169 return "eLIM_MLM_AUTHENTICATED_STATE";
170 case eLIM_MLM_WT_ASSOC_RSP_STATE:
171 return "eLIM_MLM_WT_ASSOC_RSP_STATE";
172 case eLIM_MLM_WT_REASSOC_RSP_STATE:
173 return "eLIM_MLM_WT_REASSOC_RSP_STATE";
174 case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
175 return "eLIM_MLM_WT_FT_REASSOC_RSP_STATE";
176 case eLIM_MLM_WT_DEL_STA_RSP_STATE:
177 return "eLIM_MLM_WT_DEL_STA_RSP_STATE";
178 case eLIM_MLM_WT_DEL_BSS_RSP_STATE:
179 return "eLIM_MLM_WT_DEL_BSS_RSP_STATE";
180 case eLIM_MLM_WT_ADD_STA_RSP_STATE:
181 return "eLIM_MLM_WT_ADD_STA_RSP_STATE";
182 case eLIM_MLM_WT_ADD_BSS_RSP_STATE:
183 return "eLIM_MLM_WT_ADD_BSS_RSP_STATE";
184 case eLIM_MLM_REASSOCIATED_STATE:
185 return "eLIM_MLM_REASSOCIATED_STATE";
186 case eLIM_MLM_LINK_ESTABLISHED_STATE:
187 return "eLIM_MLM_LINK_ESTABLISHED_STATE";
188 case eLIM_MLM_WT_ASSOC_CNF_STATE:
189 return "eLIM_MLM_WT_ASSOC_CNF_STATE";
190 case eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE:
191 return "eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE";
192 case eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE:
193 return "eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE";
194 case eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE:
195 return "eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE";
196 case eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE:
197 return "eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE";
198 case eLIM_MLM_WT_SET_BSS_KEY_STATE:
199 return "eLIM_MLM_WT_SET_BSS_KEY_STATE";
200 case eLIM_MLM_WT_SET_STA_KEY_STATE:
201 return "eLIM_MLM_WT_SET_STA_KEY_STATE";
202 default:
203 return "INVALID MLM state";
204 }
205}
206
207void
208lim_print_mlm_state(tpAniSirGlobal pMac, uint16_t logLevel, tLimMlmStates state)
209{
210 lim_log(pMac, logLevel, lim_mlm_state_str(state));
211}
212
213char *lim_sme_state_str(tLimSmeStates state)
214{
215 switch (state) {
216 case eLIM_SME_OFFLINE_STATE:
217 return "eLIM_SME_OFFLINE_STATE";
218 case eLIM_SME_IDLE_STATE:
219 return "eLIM_SME_OFFLINE_STATE";
220 case eLIM_SME_SUSPEND_STATE:
221 return "eLIM_SME_SUSPEND_STATE";
222 case eLIM_SME_WT_SCAN_STATE:
223 return "eLIM_SME_WT_SCAN_STATE";
224 case eLIM_SME_WT_JOIN_STATE:
225 return "eLIM_SME_WT_JOIN_STATE";
226 case eLIM_SME_WT_AUTH_STATE:
227 return "eLIM_SME_WT_AUTH_STATE";
228 case eLIM_SME_WT_ASSOC_STATE:
229 return "eLIM_SME_WT_ASSOC_STATE";
230 case eLIM_SME_WT_REASSOC_STATE:
231 return "eLIM_SME_WT_REASSOC_STATE";
232 case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE:
233 return "eLIM_SME_WT_REASSOC_LINK_FAIL_STATE";
234 case eLIM_SME_JOIN_FAILURE_STATE:
235 return "eLIM_SME_JOIN_FAILURE_STATE";
236 case eLIM_SME_ASSOCIATED_STATE:
237 return "eLIM_SME_ASSOCIATED_STATE";
238 case eLIM_SME_REASSOCIATED_STATE:
239 return "eLIM_SME_REASSOCIATED_STATE";
240 case eLIM_SME_LINK_EST_STATE:
241 return "eLIM_SME_LINK_EST_STATE";
242 case eLIM_SME_LINK_EST_WT_SCAN_STATE:
243 return "eLIM_SME_LINK_EST_WT_SCAN_STATE";
244 case eLIM_SME_WT_PRE_AUTH_STATE:
245 return "eLIM_SME_WT_PRE_AUTH_STATE";
246 case eLIM_SME_WT_DISASSOC_STATE:
247 return "eLIM_SME_WT_DISASSOC_STATE";
248 case eLIM_SME_WT_DEAUTH_STATE:
249 return "eLIM_SME_WT_DEAUTH_STATE";
250 case eLIM_SME_WT_START_BSS_STATE:
251 return "eLIM_SME_WT_START_BSS_STATE";
252 case eLIM_SME_WT_STOP_BSS_STATE:
253 return "eLIM_SME_WT_STOP_BSS_STATE";
254 case eLIM_SME_NORMAL_STATE:
255 return "eLIM_SME_NORMAL_STATE";
256 case eLIM_SME_CHANNEL_SCAN_STATE:
257 return "eLIM_SME_CHANNEL_SCAN_STATE";
258 case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
259 return "eLIM_SME_NORMAL_CHANNEL_SCAN_STATE";
260 default:
261 return "INVALID SME STATE";
262 }
263}
264
265void
266lim_print_sme_state(tpAniSirGlobal pMac, uint16_t logLevel, tLimSmeStates state)
267{
268 lim_log(pMac, logLevel, lim_sme_state_str(state));
269}
270
271char *lim_msg_str(uint32_t msgType)
272{
273#ifdef FIXME_GEN6
274 switch (msgType) {
275 case eWNI_SME_SYS_READY_IND:
276 return "eWNI_SME_SYS_READY_IND";
277 case eWNI_SME_SCAN_REQ:
278 return "eWNI_SME_SCAN_REQ";
279#ifdef FEATURE_OEM_DATA_SUPPORT
280 case eWNI_SME_OEM_DATA_REQ:
281 return "eWNI_SME_OEM_DATA_REQ";
282 case eWNI_SME_OEM_DATA_RSP:
283 return "eWNI_SME_OEM_DATA_RSP";
284#endif
285 case eWNI_SME_SCAN_RSP:
286 return "eWNI_SME_SCAN_RSP";
287 case eWNI_SME_JOIN_REQ:
288 return "eWNI_SME_JOIN_REQ";
289 case eWNI_SME_JOIN_RSP:
290 return "eWNI_SME_JOIN_RSP";
291 case eWNI_SME_SETCONTEXT_REQ:
292 return "eWNI_SME_SETCONTEXT_REQ";
293 case eWNI_SME_SETCONTEXT_RSP:
294 return "eWNI_SME_SETCONTEXT_RSP";
295 case eWNI_SME_REASSOC_REQ:
296 return "eWNI_SME_REASSOC_REQ";
297 case eWNI_SME_REASSOC_RSP:
298 return "eWNI_SME_REASSOC_RSP";
299 case eWNI_SME_DISASSOC_REQ:
300 return "eWNI_SME_DISASSOC_REQ";
301 case eWNI_SME_DISASSOC_RSP:
302 return "eWNI_SME_DISASSOC_RSP";
303 case eWNI_SME_DISASSOC_IND:
304 return "eWNI_SME_DISASSOC_IND";
305 case eWNI_SME_DISASSOC_CNF:
306 return "eWNI_SME_DISASSOC_CNF";
307 case eWNI_SME_DEAUTH_REQ:
308 return "eWNI_SME_DEAUTH_REQ";
309 case eWNI_SME_DEAUTH_RSP:
310 return "eWNI_SME_DEAUTH_RSP";
311 case eWNI_SME_DEAUTH_IND:
312 return "eWNI_SME_DEAUTH_IND";
313 case eWNI_SME_WM_STATUS_CHANGE_NTF:
314 return "eWNI_SME_WM_STATUS_CHANGE_NTF";
315 case eWNI_SME_START_BSS_REQ:
316 return "eWNI_SME_START_BSS_REQ";
317 case eWNI_SME_START_BSS_RSP:
318 return "eWNI_SME_START_BSS_RSP";
319 case eWNI_SME_ASSOC_IND:
320 return "eWNI_SME_ASSOC_IND";
321 case eWNI_SME_ASSOC_CNF:
322 return "eWNI_SME_ASSOC_CNF";
323 case eWNI_SME_SWITCH_CHL_IND:
324 return "eWNI_SME_SWITCH_CHL_IND";
325 case eWNI_SME_STOP_BSS_REQ:
326 return "eWNI_SME_STOP_BSS_REQ";
327 case eWNI_SME_STOP_BSS_RSP:
328 return "eWNI_SME_STOP_BSS_RSP";
329 case eWNI_SME_NEIGHBOR_BSS_IND:
330 return "eWNI_SME_NEIGHBOR_BSS_IND";
331 case eWNI_SME_DEAUTH_CNF:
332 return "eWNI_SME_DEAUTH_CNF";
333 case eWNI_SME_ADDTS_REQ:
334 return "eWNI_SME_ADDTS_REQ";
335 case eWNI_SME_ADDTS_RSP:
336 return "eWNI_SME_ADDTS_RSP";
337 case eWNI_SME_DELTS_REQ:
338 return "eWNI_SME_DELTS_REQ";
339 case eWNI_SME_DELTS_RSP:
340 return "eWNI_SME_DELTS_RSP";
341 case eWNI_SME_DELTS_IND:
342 return "eWNI_SME_DELTS_IND";
343 case WMA_SUSPEND_ACTIVITY_RSP:
344 return "WMA_SUSPEND_ACTIVITY_RSP";
345 case SIR_LIM_RETRY_INTERRUPT_MSG:
346 return "SIR_LIM_RETRY_INTERRUPT_MSG";
347 case SIR_BB_XPORT_MGMT_MSG:
348 return "SIR_BB_XPORT_MGMT_MSG";
349 case SIR_LIM_INV_KEY_INTERRUPT_MSG:
350 return "SIR_LIM_INV_KEY_INTERRUPT_MSG";
351 case SIR_LIM_KEY_ID_INTERRUPT_MSG:
352 return "SIR_LIM_KEY_ID_INTERRUPT_MSG";
353 case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
354 return "SIR_LIM_REPLAY_THRES_INTERRUPT_MSG";
355 case SIR_LIM_JOIN_FAIL_TIMEOUT:
356 return "SIR_LIM_JOIN_FAIL_TIMEOUT";
357 case SIR_LIM_AUTH_FAIL_TIMEOUT:
358 return "SIR_LIM_AUTH_FAIL_TIMEOUT";
359 case SIR_LIM_AUTH_RSP_TIMEOUT:
360 return "SIR_LIM_AUTH_RSP_TIMEOUT";
361 case SIR_LIM_ASSOC_FAIL_TIMEOUT:
362 return "SIR_LIM_ASSOC_FAIL_TIMEOUT";
363 case SIR_LIM_REASSOC_FAIL_TIMEOUT:
364 return "SIR_LIM_REASSOC_FAIL_TIMEOUT";
365 case SIR_LIM_HEART_BEAT_TIMEOUT:
366 return "SIR_LIM_HEART_BEAT_TIMEOUT";
367 case SIR_LIM_ADDTS_RSP_TIMEOUT:
368 return "SIR_LIM_ADDTS_RSP_TIMEOUT";
369 case SIR_LIM_LINK_TEST_DURATION_TIMEOUT:
370 return "SIR_LIM_LINK_TEST_DURATION_TIMEOUT";
371 case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
372 return "SIR_LIM_HASH_MISS_THRES_TIMEOUT";
373 case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
374 return "SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT";
375 case SIR_LIM_CNF_WAIT_TIMEOUT:
376 return "SIR_LIM_CNF_WAIT_TIMEOUT";
377 case SIR_LIM_RADAR_DETECT_IND:
378 return "SIR_LIM_RADAR_DETECT_IND";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
380 return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT";
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800381 case WNI_CFG_PARAM_UPDATE_IND:
382 return "WNI_CFG_PARAM_UPDATE_IND";
383 case WNI_CFG_DNLD_REQ:
384 return "WNI_CFG_DNLD_REQ";
385 case WNI_CFG_DNLD_CNF:
386 return "WNI_CFG_DNLD_CNF";
387 case WNI_CFG_GET_RSP:
388 return "WNI_CFG_GET_RSP";
389 case WNI_CFG_SET_CNF:
390 return "WNI_CFG_SET_CNF";
391 case WNI_CFG_GET_ATTRIB_RSP:
392 return "WNI_CFG_GET_ATTRIB_RSP";
393 case WNI_CFG_ADD_GRP_ADDR_CNF:
394 return "WNI_CFG_ADD_GRP_ADDR_CNF";
395 case WNI_CFG_DEL_GRP_ADDR_CNF:
396 return "WNI_CFG_DEL_GRP_ADDR_CNF";
397 case ANI_CFG_GET_RADIO_STAT_RSP:
398 return "ANI_CFG_GET_RADIO_STAT_RSP";
399 case ANI_CFG_GET_PER_STA_STAT_RSP:
400 return "ANI_CFG_GET_PER_STA_STAT_RSP";
401 case ANI_CFG_GET_AGG_STA_STAT_RSP:
402 return "ANI_CFG_GET_AGG_STA_STAT_RSP";
403 case ANI_CFG_CLEAR_STAT_RSP:
404 return "ANI_CFG_CLEAR_STAT_RSP";
405 case WNI_CFG_DNLD_RSP:
406 return "WNI_CFG_DNLD_RSP";
407 case WNI_CFG_GET_REQ:
408 return "WNI_CFG_GET_REQ";
409 case WNI_CFG_SET_REQ:
410 return "WNI_CFG_SET_REQ";
411 case WNI_CFG_SET_REQ_NO_RSP:
412 return "WNI_CFG_SET_REQ_NO_RSP";
413 case eWNI_PMC_ENTER_IMPS_RSP:
414 return "eWNI_PMC_ENTER_IMPS_RSP";
415 case eWNI_PMC_EXIT_IMPS_RSP:
416 return "eWNI_PMC_EXIT_IMPS_RSP";
417 case eWNI_PMC_ENTER_BMPS_RSP:
418 return "eWNI_PMC_ENTER_BMPS_RSP";
419 case eWNI_PMC_EXIT_BMPS_RSP:
420 return "eWNI_PMC_EXIT_BMPS_RSP";
421 case eWNI_PMC_EXIT_BMPS_IND:
422 return "eWNI_PMC_EXIT_BMPS_IND";
423 case eWNI_SME_SET_BCN_FILTER_REQ:
424 return "eWNI_SME_SET_BCN_FILTER_REQ";
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -0800425#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 case eWNI_SME_GET_TSM_STATS_REQ:
427 return "eWNI_SME_GET_TSM_STATS_REQ";
428 case eWNI_SME_GET_TSM_STATS_RSP:
429 return "eWNI_SME_GET_TSM_STATS_RSP";
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -0800430#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 case eWNI_SME_CSA_OFFLOAD_EVENT:
432 return "eWNI_SME_CSA_OFFLOAD_EVENT";
433 case eWNI_SME_SET_HW_MODE_REQ:
434 return "eWNI_SME_SET_HW_MODE_REQ";
435 case eWNI_SME_SET_HW_MODE_RESP:
436 return "eWNI_SME_SET_HW_MODE_RESP";
437 case eWNI_SME_HW_MODE_TRANS_IND:
438 return "eWNI_SME_HW_MODE_TRANS_IND";
439 default:
440 return "INVALID SME message";
441 }
442#endif
443 return "";
444}
445
446char *lim_result_code_str(tSirResultCodes resultCode)
447{
448 switch (resultCode) {
449 case eSIR_SME_SUCCESS:
450 return "eSIR_SME_SUCCESS";
451 case eSIR_LOGP_EXCEPTION:
452 return "eSIR_LOGP_EXCEPTION";
453 case eSIR_SME_INVALID_PARAMETERS:
454 return "eSIR_SME_INVALID_PARAMETERS";
455 case eSIR_SME_UNEXPECTED_REQ_RESULT_CODE:
456 return "eSIR_SME_UNEXPECTED_REQ_RESULT_CODE";
457 case eSIR_SME_RESOURCES_UNAVAILABLE:
458 return "eSIR_SME_RESOURCES_UNAVAILABLE";
459 case eSIR_SME_SCAN_FAILED:
460 return "eSIR_SME_SCAN_FAILED";
461 case eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED:
462 return "eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED";
463 case eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE:
464 return "eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE";
465 case eSIR_SME_REFUSED:
466 return "eSIR_SME_REFUSED";
467 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
468 return "eSIR_SME_JOIN_TIMEOUT_RESULT_CODE";
469 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
470 return "eSIR_SME_AUTH_TIMEOUT_RESULT_CODE";
471 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
472 return "eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE";
473 case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE:
474 return "eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE";
475 case eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED:
476 return "eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED";
477 case eSIR_SME_AUTH_REFUSED:
478 return "eSIR_SME_AUTH_REFUSED";
479 case eSIR_SME_INVALID_WEP_DEFAULT_KEY:
480 return "eSIR_SME_INVALID_WEP_DEFAULT_KEY";
481 case eSIR_SME_ASSOC_REFUSED:
482 return "eSIR_SME_ASSOC_REFUSED";
483 case eSIR_SME_REASSOC_REFUSED:
484 return "eSIR_SME_REASSOC_REFUSED";
485 case eSIR_SME_STA_NOT_AUTHENTICATED:
486 return "eSIR_SME_STA_NOT_AUTHENTICATED";
487 case eSIR_SME_STA_NOT_ASSOCIATED:
488 return "eSIR_SME_STA_NOT_ASSOCIATED";
489 case eSIR_SME_ALREADY_JOINED_A_BSS:
490 return "eSIR_SME_ALREADY_JOINED_A_BSS";
491 case eSIR_SME_MORE_SCAN_RESULTS_FOLLOW:
492 return "eSIR_SME_MORE_SCAN_RESULTS_FOLLOW";
493 case eSIR_SME_INVALID_ASSOC_RSP_RXED:
494 return "eSIR_SME_INVALID_ASSOC_RSP_RXED";
495 case eSIR_SME_MIC_COUNTER_MEASURES:
496 return "eSIR_SME_MIC_COUNTER_MEASURES";
497 case eSIR_SME_ADDTS_RSP_TIMEOUT:
498 return "eSIR_SME_ADDTS_RSP_TIMEOUT";
499 case eSIR_SME_CHANNEL_SWITCH_FAIL:
500 return "eSIR_SME_CHANNEL_SWITCH_FAIL";
501 case eSIR_SME_HAL_SCAN_INIT_FAILED:
502 return "eSIR_SME_HAL_SCAN_INIT_FAILED";
503 case eSIR_SME_HAL_SCAN_END_FAILED:
504 return "eSIR_SME_HAL_SCAN_END_FAILED";
505 case eSIR_SME_HAL_SCAN_FINISH_FAILED:
506 return "eSIR_SME_HAL_SCAN_FINISH_FAILED";
507 case eSIR_SME_HAL_SEND_MESSAGE_FAIL:
508 return "eSIR_SME_HAL_SEND_MESSAGE_FAIL";
509
510 default:
511 return "INVALID resultCode";
512 }
513}
514
515void lim_print_msg_name(tpAniSirGlobal pMac, uint16_t logLevel, uint32_t msgType)
516{
517 lim_log(pMac, logLevel, lim_msg_str(msgType));
518}
519
520/**
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800521 * lim_init_mlm() - This function is called by limProcessSmeMessages() to
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522 * initialize MLM state machine on STA
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800523 * @pMac: Pointer to Global MAC structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524 *
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800525 * @Return: Status of operation
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526 */
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800527tSirRetStatus lim_init_mlm(tpAniSirGlobal pMac)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528{
529 uint32_t retVal;
530
531 pMac->lim.gLimTimersCreated = 0;
532
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800533 MTRACE(mac_trace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
534 pMac->lim.gLimMlmState));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800536 /* Initialize number of pre-auth contexts */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800537 pMac->lim.gLimNumPreAuthContexts = 0;
538
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800539 /* Initialize MAC based Authentication STA list */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800540 lim_init_pre_auth_list(pMac);
541
542 /* Create timers used by LIM */
543 retVal = lim_create_timers(pMac);
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800544 if (retVal != TX_SUCCESS) {
545 lim_log(pMac, LOGP, FL("lim_create_timers Failed"));
546 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800547 }
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800548
549 pMac->lim.gLimTimersCreated = 1;
550 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551} /*** end lim_init_mlm() ***/
552
553/**
554 * lim_deactivate_del_sta() - This function deactivate/delete associates STA
555 * @mac_ctx: pointer to Global Mac Structure
556 * @bss_entry: index for bss_entry
557 * @psession_entry: pointer to session entry
558 * @sta_ds: pointer to tpDphHashNode
559 *
560 * Function deactivate/delete associates STA
561 *
562 * Return: none
563 */
564static void lim_deactivate_del_sta(tpAniSirGlobal mac_ctx, uint32_t bss_entry,
565 tpPESession psession_entry, tpDphHashNode sta_ds)
566{
567 uint32_t sta_entry;
568
569 for (sta_entry = 1; sta_entry < mac_ctx->lim.gLimAssocStaLimit;
570 sta_entry++) {
571 psession_entry = &mac_ctx->lim.gpSession[bss_entry];
572 sta_ds = dph_get_hash_entry(mac_ctx, sta_entry,
573 &psession_entry->dph.dphHashTable);
574 if (NULL == sta_ds)
575 continue;
576
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530577 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800578 FL("Deleting pmfSaQueryTimer for staid[%d]"),
579 sta_ds->staIndex);
580 tx_timer_deactivate(&sta_ds->pmfSaQueryTimer);
581 tx_timer_delete(&sta_ds->pmfSaQueryTimer);
582 }
583}
584
585/**
586 * lim_cleanup_mlm() - This function is called to cleanup
587 * @mac_ctx: Pointer to Global MAC structure
588 *
589 * Function is called to cleanup any resources allocated by the MLM
590 * state machine.
591 *
592 * Return: none
593 */
594void lim_cleanup_mlm(tpAniSirGlobal mac_ctx)
595{
596 uint32_t n;
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800597 tLimPreAuthNode **pAuthNode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598#ifdef WLAN_FEATURE_11W
599 uint32_t bss_entry;
600 tpDphHashNode sta_ds = NULL;
601 tpPESession psession_entry = NULL;
602#endif
603 tLimTimers *lim_timer = NULL;
604
605 if (mac_ctx->lim.gLimTimersCreated == 1) {
606 lim_timer = &mac_ctx->lim.limTimers;
607
Varun Reddy Yeturu32de0e42016-04-15 14:25:59 +0530608 lim_delete_timers_host_roam(mac_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800609 /* Deactivate and delete Periodic Probe channel timers. */
610 tx_timer_deactivate(&lim_timer->gLimPeriodicProbeReqTimer);
611 tx_timer_delete(&lim_timer->gLimPeriodicProbeReqTimer);
612
613 /* Deactivate and delete channel switch timer. */
614 tx_timer_deactivate(&lim_timer->gLimChannelSwitchTimer);
615 tx_timer_delete(&lim_timer->gLimChannelSwitchTimer);
616
617 /* Deactivate and delete addts response timer. */
618 tx_timer_deactivate(&lim_timer->gLimAddtsRspTimer);
619 tx_timer_delete(&lim_timer->gLimAddtsRspTimer);
620
621 /* Deactivate and delete Join failure timer. */
622 tx_timer_deactivate(&lim_timer->gLimJoinFailureTimer);
623 tx_timer_delete(&lim_timer->gLimJoinFailureTimer);
624
625 /* Deactivate and delete Periodic Join Probe Request timer. */
626 tx_timer_deactivate(&lim_timer->gLimPeriodicJoinProbeReqTimer);
627 tx_timer_delete(&lim_timer->gLimPeriodicJoinProbeReqTimer);
628
Abhishek Singh7d3bc3e2016-02-03 17:45:01 +0530629 /* Deactivate and delete Auth Retry timer. */
630 tx_timer_deactivate
631 (&lim_timer->g_lim_periodic_auth_retry_timer);
632 tx_timer_delete(&lim_timer->g_lim_periodic_auth_retry_timer);
633
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800634 /* Deactivate and delete Association failure timer. */
635 tx_timer_deactivate(&lim_timer->gLimAssocFailureTimer);
636 tx_timer_delete(&lim_timer->gLimAssocFailureTimer);
637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638 /* Deactivate and delete Authentication failure timer. */
639 tx_timer_deactivate(&lim_timer->gLimAuthFailureTimer);
640 tx_timer_delete(&lim_timer->gLimAuthFailureTimer);
641
642 /* Deactivate and delete wait-for-probe-after-Heartbeat timer. */
643 tx_timer_deactivate(&lim_timer->gLimProbeAfterHBTimer);
644 tx_timer_delete(&lim_timer->gLimProbeAfterHBTimer);
645
646 /* Deactivate and delete Quiet timer. */
647 tx_timer_deactivate(&lim_timer->gLimQuietTimer);
648 tx_timer_delete(&lim_timer->gLimQuietTimer);
649
650 /* Deactivate and delete Quiet BSS timer. */
651 tx_timer_deactivate(&lim_timer->gLimQuietBssTimer);
652 tx_timer_delete(&lim_timer->gLimQuietBssTimer);
653
654 /* Deactivate and delete cnf wait timer */
655 for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
656 tx_timer_deactivate(&lim_timer->gpLimCnfWaitTimer[n]);
657 tx_timer_delete(&lim_timer->gpLimCnfWaitTimer[n]);
658 }
659
660 pAuthNode = mac_ctx->lim.gLimPreAuthTimerTable.pTable;
661
662 /* Deactivate any Authentication response timers */
663 lim_delete_pre_auth_list(mac_ctx);
664
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800665 /* Delete any Auth rsp timers, which might have been started */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666 for (n = 0; n < mac_ctx->lim.gLimPreAuthTimerTable.numEntry;
Naveen Rawate6ddcaa2016-02-05 16:50:18 -0800667 n++)
668 tx_timer_delete(&pAuthNode[n]->timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669
670 /* Deactivate and delete Hash Miss throttle timer */
671 tx_timer_deactivate(&lim_timer->
672 gLimSendDisassocFrameThresholdTimer);
673 tx_timer_delete(&lim_timer->
674 gLimSendDisassocFrameThresholdTimer);
675
676 tx_timer_deactivate(&lim_timer->gLimUpdateOlbcCacheTimer);
677 tx_timer_delete(&lim_timer->gLimUpdateOlbcCacheTimer);
678 tx_timer_deactivate(&lim_timer->gLimPreAuthClnupTimer);
679 tx_timer_delete(&lim_timer->gLimPreAuthClnupTimer);
680
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800681 /* Deactivate and delete remain on channel timer */
682 tx_timer_deactivate(&lim_timer->gLimRemainOnChannelTimer);
683 tx_timer_delete(&lim_timer->gLimRemainOnChannelTimer);
684
685
686 tx_timer_deactivate(&lim_timer->gLimDisassocAckTimer);
687 tx_timer_delete(&lim_timer->gLimDisassocAckTimer);
688
689 tx_timer_deactivate(&lim_timer->gLimDeauthAckTimer);
690 tx_timer_delete(&lim_timer->gLimDeauthAckTimer);
691
692 tx_timer_deactivate(&lim_timer->
693 gLimP2pSingleShotNoaInsertTimer);
694 tx_timer_delete(&lim_timer->
695 gLimP2pSingleShotNoaInsertTimer);
696
697 tx_timer_deactivate(&lim_timer->
698 gLimActiveToPassiveChannelTimer);
699 tx_timer_delete(&lim_timer->
700 gLimActiveToPassiveChannelTimer);
701
702 mac_ctx->lim.gLimTimersCreated = 0;
703 }
704#ifdef WLAN_FEATURE_11W
705 /*
706 * When SSR is triggered, we need to loop through
707 * each STA associated per BSSId and deactivate/delete
708 * the pmfSaQueryTimer for it
709 */
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800710 if (cds_is_driver_recovering()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530711 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712 FL("SSR is detected, proceed to clean up pmfSaQueryTimer"));
713 for (bss_entry = 0; bss_entry < mac_ctx->lim.maxBssId;
714 bss_entry++) {
715 if (!mac_ctx->lim.gpSession[bss_entry].valid)
716 continue;
717 lim_deactivate_del_sta(mac_ctx, bss_entry,
718 psession_entry, sta_ds);
719 }
720 }
721#endif
722
723} /*** end lim_cleanup_mlm() ***/
724
725/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800726 * lim_is_addr_bc()
727 *
728 ***FUNCTION:
729 * This function is called in various places within LIM code
730 * to determine whether passed MAC address is a broadcast or not
731 *
732 ***LOGIC:
733 *
734 ***ASSUMPTIONS:
735 * NA
736 *
737 ***NOTE:
738 * NA
739 *
740 * @param macAddr Indicates MAC address that need to be determined
741 * whether it is Broadcast address or not
742 *
743 * @return true if passed address is Broadcast address else false
744 */
745
746uint8_t lim_is_addr_bc(tSirMacAddr macAddr)
747{
748 int i;
749 for (i = 0; i < 6; i++) {
750 if ((macAddr[i] & 0xFF) != 0xFF)
751 return false;
752 }
753
754 return true;
755} /****** end lim_is_addr_bc() ******/
756
757/**
758 * lim_is_group_addr()
759 *
760 ***FUNCTION:
761 * This function is called in various places within LIM code
762 * to determine whether passed MAC address is a group address or not
763 *
764 ***LOGIC:
765 * If least significant bit of first octet of the MAC address is
766 * set to 1, it is a Group address.
767 *
768 ***ASSUMPTIONS:
769 * NA
770 *
771 ***NOTE:
772 * NA
773 *
774 * @param macAddr Indicates MAC address that need to be determined
775 * whether it is Group address or not
776 *
777 * @return true if passed address is Group address else false
778 */
779
780uint8_t lim_is_group_addr(tSirMacAddr macAddr)
781{
782 if ((macAddr[0] & 0x01) == 0x01)
783 return true;
784 else
785 return false;
786} /****** end lim_is_group_addr() ******/
787
788/**
789 * lim_print_mac_addr()
790 *
791 ***FUNCTION:
792 * This function is called to print passed MAC address
793 * in : format.
794 *
795 ***LOGIC:
796 *
797 ***ASSUMPTIONS:
798 * NA
799 *
800 ***NOTE:
801 * @param macAddr - MacAddr to be printed
802 * @param logLevel - Loglevel to be used
803 *
804 * @return None.
805 */
806
807void lim_print_mac_addr(tpAniSirGlobal pMac, tSirMacAddr macAddr, uint8_t logLevel)
808{
809 lim_log(pMac, logLevel, FL(MAC_ADDRESS_STR), MAC_ADDR_ARRAY(macAddr));
810} /****** end lim_print_mac_addr() ******/
811
812/*
813 * lim_reset_deferred_msg_q()
814 *
815 ***FUNCTION:
816 * This function resets the deferred message queue parameters.
817 *
818 ***PARAMS:
819 * @param pMac - Pointer to Global MAC structure
820 *
821 ***LOGIC:
822 *
823 ***ASSUMPTIONS:
824 * NA
825 *
826 ***NOTE:
827 * NA
828 *
829 ***RETURNS:
830 * None
831 */
832
833void lim_reset_deferred_msg_q(tpAniSirGlobal pMac)
834{
Nirav Shah9bf81572016-04-19 16:42:52 +0530835 tSirMsgQ *read_msg;
836
837 if (pMac->lim.gLimDeferredMsgQ.size > 0) {
838 while ((read_msg = lim_read_deferred_msg_q(pMac)) != NULL) {
839 pe_free_msg(pMac, read_msg);
840 }
841 }
842
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800843 pMac->lim.gLimDeferredMsgQ.size =
844 pMac->lim.gLimDeferredMsgQ.write =
845 pMac->lim.gLimDeferredMsgQ.read = 0;
846
847}
848
849#define LIM_DEFERRED_Q_CHECK_THRESHOLD (MAX_DEFERRED_QUEUE_LEN/2)
850#define LIM_MAX_NUM_MGMT_FRAME_DEFERRED (MAX_DEFERRED_QUEUE_LEN/2)
851
852/**
853 * lim_write_deferred_msg_q() - This function queues up a deferred message
854 *
855 * @mac_ctx: Pointer to Global MAC structure
856 * @lim_msg: a LIM message
857 *
858 * Function queues up a deferred message for later processing on the
859 * STA side.
860 *
861 * Return: none
862 */
863
864uint8_t lim_write_deferred_msg_q(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg)
865{
866 lim_log(mac_ctx, LOG1,
867 FL("Queue a deferred message (size %d, write %d) - type 0x%x "),
868 mac_ctx->lim.gLimDeferredMsgQ.size,
869 mac_ctx->lim.gLimDeferredMsgQ.write,
870 lim_msg->type);
871
872 /* check if the deferred message queue is full */
873 if (mac_ctx->lim.gLimDeferredMsgQ.size >= MAX_DEFERRED_QUEUE_LEN) {
874 if (!(mac_ctx->lim.deferredMsgCnt & 0xF)) {
875 lim_log(mac_ctx, LOGE,
876 FL("queue->MsgQ full Msg:%d Msgs Failed:%d"),
877 lim_msg->type,
878 ++mac_ctx->lim.deferredMsgCnt);
Abhishek Singh5ea86532016-04-27 14:10:53 +0530879 cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
880 WLAN_LOG_INDICATOR_HOST_DRIVER,
881 WLAN_LOG_REASON_QUEUE_FULL,
882 true, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800883 } else {
884 mac_ctx->lim.deferredMsgCnt++;
885 }
886 return TX_QUEUE_FULL;
887 }
888
889 /*
890 * In the application, there should not be more than 1 message get
891 * queued up. If happens, flags a warning. In the future, this can
892 * happen.
893 */
894 if (mac_ctx->lim.gLimDeferredMsgQ.size > 0)
895 lim_log(mac_ctx, LOGW,
896 FL("%d Deferred Msg (type 0x%x, scan %d, global sme %d, global mlme %d, addts %d)"),
897 mac_ctx->lim.gLimDeferredMsgQ.size,
898 lim_msg->type,
899 lim_is_system_in_scan_state(mac_ctx),
900 mac_ctx->lim.gLimSmeState,
901 mac_ctx->lim.gLimMlmState,
902 mac_ctx->lim.gLimAddtsSent);
903
904 /*
905 * To prevent the deferred Q is full of management frames, only give
906 * them certain space
907 */
908 if ((SIR_BB_XPORT_MGMT_MSG == lim_msg->type) &&
909 (LIM_DEFERRED_Q_CHECK_THRESHOLD <
910 mac_ctx->lim.gLimDeferredMsgQ.size)) {
911 uint16_t idx, count = 0;
912 for (idx = 0; idx < mac_ctx->lim.gLimDeferredMsgQ.size;
913 idx++) {
914 if (SIR_BB_XPORT_MGMT_MSG ==
915 mac_ctx->lim.gLimDeferredMsgQ.
916 deferredQueue[idx].type) {
917 count++;
918 }
919 }
920 if (LIM_MAX_NUM_MGMT_FRAME_DEFERRED < count) {
921 /*
922 * We reach the quota for management frames,
923 * drop this one
924 */
925 lim_log(mac_ctx, LOGW,
926 FL("Too many queue->MsgQ Msg: %d (count=%d)"),
927 lim_msg->type, count);
928 /* Return error, caller knows what to do */
929 return TX_QUEUE_FULL;
930 }
931 }
932
933 ++mac_ctx->lim.gLimDeferredMsgQ.size;
934
935 /* reset the count here since we are able to defer the message */
936 if (mac_ctx->lim.deferredMsgCnt != 0)
937 mac_ctx->lim.deferredMsgCnt = 0;
938
939 /* if the write pointer hits the end of the queue, rewind it */
940 if (mac_ctx->lim.gLimDeferredMsgQ.write >= MAX_DEFERRED_QUEUE_LEN)
941 mac_ctx->lim.gLimDeferredMsgQ.write = 0;
942
943 /* save the message to the queue and advanced the write pointer */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530944 qdf_mem_copy((uint8_t *) &mac_ctx->lim.gLimDeferredMsgQ.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800945 deferredQueue[mac_ctx->lim.gLimDeferredMsgQ.write++],
946 (uint8_t *) lim_msg, sizeof(tSirMsgQ));
947 return TX_SUCCESS;
948
949}
950
951/*
952 * lim_read_deferred_msg_q()
953 *
954 ***FUNCTION:
955 * This function dequeues a deferred message for processing on the
956 * STA side.
957 *
958 ***PARAMS:
959 * @param pMac - Pointer to Global MAC structure
960 *
961 ***LOGIC:
962 *
963 ***ASSUMPTIONS:
964 * NA
965 *
966 ***NOTE:
967 *
968 *
969 ***RETURNS:
970 * Returns the message at the head of the deferred message queue
971 */
972
973tSirMsgQ *lim_read_deferred_msg_q(tpAniSirGlobal pMac)
974{
975 tSirMsgQ *msg;
976
977 /*
978 ** check any messages left. If no, return
979 **/
980 if (pMac->lim.gLimDeferredMsgQ.size <= 0)
981 return NULL;
982
983 /*
984 ** decrement the queue size
985 **/
986 pMac->lim.gLimDeferredMsgQ.size--;
987
988 /*
989 ** retrieve the message from the head of the queue
990 **/
991 msg =
992 &pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.
993 gLimDeferredMsgQ.read];
994
995 /*
996 ** advance the read pointer
997 **/
998 pMac->lim.gLimDeferredMsgQ.read++;
999
1000 /*
1001 ** if the read pointer hits the end of the queue, rewind it
1002 **/
1003 if (pMac->lim.gLimDeferredMsgQ.read >= MAX_DEFERRED_QUEUE_LEN)
1004 pMac->lim.gLimDeferredMsgQ.read = 0;
1005
1006 PELOG1(lim_log(pMac, LOG1,
1007 FL
1008 ("** DeQueue a deferred message (size %d read %d) - type 0x%x **"),
1009 pMac->lim.gLimDeferredMsgQ.size,
1010 pMac->lim.gLimDeferredMsgQ.read, msg->type);
1011 )
1012
1013 PELOG1(lim_log
1014 (pMac, LOG1,
1015 FL
1016 ("DQ msg -- scan %d, global sme %d, global mlme %d, addts %d"),
1017 lim_is_system_in_scan_state(pMac), pMac->lim.gLimSmeState,
1018 pMac->lim.gLimMlmState, pMac->lim.gLimAddtsSent);
1019 )
1020
1021 return msg;
1022}
1023
1024tSirRetStatus
1025lim_sys_process_mmh_msg_api(tpAniSirGlobal pMac, tSirMsgQ *pMsg, uint8_t qType)
1026{
1027 /* FIXME */
1028 sys_process_mmh_msg(pMac, pMsg);
1029 return eSIR_SUCCESS;
1030}
1031
1032/*
1033 * lim_handle_update_olbc_cache() - This function update olbc cache
1034 *
1035 * @mac_ctx: Pointer to Global MAC structure
1036 *
1037 * Function updates olbc cache
1038 *
1039 * Return: none
1040 */
1041void lim_handle_update_olbc_cache(tpAniSirGlobal mac_ctx)
1042{
1043 int i;
1044 static int enable;
1045 tUpdateBeaconParams beaconParams;
1046
1047 tpPESession psessionEntry = lim_is_ap_session_active(mac_ctx);
1048
1049 if (psessionEntry == NULL) {
1050 lim_log(mac_ctx, LOGE, FL(" Session not found"));
1051 return;
1052 }
1053
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301054 qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001055 beaconParams.bssIdx = psessionEntry->bssIdx;
1056
1057 beaconParams.paramChangeBitmap = 0;
1058 /*
1059 * This is doing a 2 pass check. The first pass is to invalidate
1060 * all the cache entries. The second pass is to decide whether to
1061 * disable protection.
1062 */
1063 if (!enable) {
1064 lim_log(mac_ctx, LOG2, FL("Resetting OLBC cache"));
1065 psessionEntry->gLimOlbcParams.numSta = 0;
1066 psessionEntry->gLimOverlap11gParams.numSta = 0;
1067 psessionEntry->gLimOverlapHt20Params.numSta = 0;
1068 psessionEntry->gLimNonGfParams.numSta = 0;
1069 psessionEntry->gLimLsigTxopParams.numSta = 0;
1070
1071 for (i = 0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
1072 mac_ctx->lim.protStaOverlapCache[i].active = false;
1073
1074 enable = 1;
1075 } else {
1076 if ((!psessionEntry->gLimOlbcParams.numSta) &&
1077 (psessionEntry->gLimOlbcParams.protectionEnabled) &&
1078 (!psessionEntry->gLim11bParams.protectionEnabled)) {
1079 lim_log(mac_ctx, LOG1,
1080 FL("Overlap cache clear and no 11B STA set"));
1081 lim_enable11g_protection(mac_ctx, false, true,
1082 &beaconParams,
1083 psessionEntry);
1084 }
1085
1086 if ((!psessionEntry->gLimOverlap11gParams.numSta) &&
1087 (psessionEntry->gLimOverlap11gParams.protectionEnabled)
1088 && (!psessionEntry->gLim11gParams.protectionEnabled)) {
1089 lim_log(mac_ctx, LOG1,
1090 FL("Overlap cache clear and no 11G STA set"));
1091 lim_enable_ht_protection_from11g(mac_ctx, false, true,
1092 &beaconParams,
1093 psessionEntry);
1094 }
1095
1096 if ((!psessionEntry->gLimOverlapHt20Params.numSta) &&
1097 (psessionEntry->gLimOverlapHt20Params.protectionEnabled)
1098 && (!psessionEntry->gLimHt20Params.protectionEnabled)) {
1099 lim_log(mac_ctx, LOG1,
1100 FL("Overlap cache clear and no HT20 STA set"));
1101 lim_enable11g_protection(mac_ctx, false, true,
1102 &beaconParams,
1103 psessionEntry);
1104 }
1105
1106 enable = 0;
1107 }
1108
1109 if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
1110 && beaconParams.paramChangeBitmap) {
1111 sch_set_fixed_beacon_fields(mac_ctx, psessionEntry);
1112 lim_send_beacon_params(mac_ctx, &beaconParams, psessionEntry);
1113 }
1114 /* Start OLBC timer */
1115 if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimUpdateOlbcCacheTimer)
1116 != TX_SUCCESS)
1117 lim_log(mac_ctx, LOGE, FL("tx_timer_activate failed"));
1118}
1119
1120/**
1121 * lim_is_null_ssid() - This function checks if ssid supplied is Null SSID
1122 * @ssid: pointer to tSirMacSSid
1123 *
1124 * Function checks if ssid supplied is Null SSID
1125 *
1126 * Return: none
1127 */
1128
1129uint8_t lim_is_null_ssid(tSirMacSSid *ssid)
1130{
1131 uint8_t fnull_ssid = false;
1132 uint32_t ssid_len;
1133 uint8_t *ssid_str;
1134
1135 if (0 == ssid->length) {
1136 fnull_ssid = true;
1137 return fnull_ssid;
1138 }
1139 /* If the first charactes is space, then check if all
1140 * characters in SSID are spaces to consider it as NULL SSID
1141 */
1142 if ((ASCII_SPACE_CHARACTER == ssid->ssId[0]) &&
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301143 (ssid->length == 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001144 fnull_ssid = true;
1145 return fnull_ssid;
1146 } else {
1147 /* check if all the charactes in SSID are NULL */
1148 ssid_len = ssid->length;
1149 ssid_str = ssid->ssId;
1150
1151 while (ssid_len) {
1152 if (*ssid_str)
1153 return fnull_ssid;
1154
1155 ssid_str++;
1156 ssid_len--;
1157 }
1158
1159 if (0 == ssid_len) {
1160 fnull_ssid = true;
1161 return fnull_ssid;
1162 }
1163 }
1164
1165 return fnull_ssid;
1166}
1167
1168/** -------------------------------------------------------------
1169 \fn lim_update_prot_sta_params
1170 \brief updates protection related counters.
1171 \param tpAniSirGlobal pMac
1172 \param tSirMacAddr peerMacAddr
1173 \param tLimProtStaCacheType protStaCacheType
1174 \param tHalBitVal gfSupported
1175 \param tHalBitVal lsigTxopSupported
1176 \return None
1177 -------------------------------------------------------------*/
1178void
1179lim_update_prot_sta_params(tpAniSirGlobal pMac,
1180 tSirMacAddr peerMacAddr,
1181 tLimProtStaCacheType protStaCacheType,
1182 tHalBitVal gfSupported, tHalBitVal lsigTxopSupported,
1183 tpPESession psessionEntry)
1184{
1185 uint32_t i;
1186
1187 PELOG1(lim_log(pMac, LOG1, FL("A STA is associated:"));
1188 lim_log(pMac, LOG1, FL("Addr : "));
1189 lim_print_mac_addr(pMac, peerMacAddr, LOG1);
1190 )
1191
1192 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1193 if (psessionEntry->protStaCache[i].active) {
1194 PELOG1(lim_log(pMac, LOG1, FL("Addr: "));)
1195 PELOG1(lim_print_mac_addr
1196 (pMac, psessionEntry->protStaCache[i].addr,
1197 LOG1);
1198 )
1199
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301200 if (!qdf_mem_cmp
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 (psessionEntry->protStaCache[i].addr,
1202 peerMacAddr, sizeof(tSirMacAddr))) {
1203 PELOG1(lim_log
1204 (pMac, LOG1,
1205 FL
1206 ("matching cache entry at %d already active."),
1207 i);
1208 )
1209 return;
1210 }
1211 }
1212 }
1213
1214 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1215 if (!psessionEntry->protStaCache[i].active)
1216 break;
1217 }
1218
1219 if (i >= LIM_PROT_STA_CACHE_SIZE) {
1220 PELOGE(lim_log(pMac, LOGE, FL("No space in ProtStaCache"));)
1221 return;
1222 }
1223
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301224 qdf_mem_copy(psessionEntry->protStaCache[i].addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001225 peerMacAddr, sizeof(tSirMacAddr));
1226
1227 psessionEntry->protStaCache[i].protStaCacheType = protStaCacheType;
1228 psessionEntry->protStaCache[i].active = true;
1229 if (eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) {
1230 psessionEntry->gLim11bParams.numSta++;
1231 lim_log(pMac, LOG1, FL("11B, "));
1232 } else if (eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) {
1233 psessionEntry->gLim11gParams.numSta++;
1234 lim_log(pMac, LOG1, FL("11G, "));
1235 } else if (eLIM_PROT_STA_CACHE_TYPE_HT20 == protStaCacheType) {
1236 psessionEntry->gLimHt20Params.numSta++;
1237 lim_log(pMac, LOG1, FL("HT20, "));
1238 }
1239
1240 if (!gfSupported) {
1241 psessionEntry->gLimNonGfParams.numSta++;
1242 lim_log(pMac, LOG1, FL("NonGf, "));
1243 }
1244 if (!lsigTxopSupported) {
1245 psessionEntry->gLimLsigTxopParams.numSta++;
1246 lim_log(pMac, LOG1, FL("!lsigTxopSupported"));
1247 }
1248} /* --------------------------------------------------------------------- */
1249
1250/** -------------------------------------------------------------
1251 \fn lim_decide_ap_protection
1252 \brief Decides all the protection related staiton coexistence and also sets
1253 \ short preamble and short slot appropriately. This function will be called
1254 \ when AP is ready to send assocRsp tp the station joining right now.
1255 \param tpAniSirGlobal pMac
1256 \param tSirMacAddr peerMacAddr
1257 \return None
1258 -------------------------------------------------------------*/
1259void
1260lim_decide_ap_protection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
1261 tpUpdateBeaconParams pBeaconParams,
1262 tpPESession psessionEntry)
1263{
1264 uint16_t tmpAid;
1265 tpDphHashNode pStaDs;
1266 tSirRFBand rfBand = SIR_BAND_UNKNOWN;
1267 uint32_t phyMode;
1268 tLimProtStaCacheType protStaCacheType =
1269 eLIM_PROT_STA_CACHE_TYPE_INVALID;
1270 tHalBitVal gfSupported = eHAL_SET, lsigTxopSupported = eHAL_SET;
1271
1272 pBeaconParams->paramChangeBitmap = 0;
1273 /* check whether to enable protection or not */
1274 pStaDs =
1275 dph_lookup_hash_entry(pMac, peerMacAddr, &tmpAid,
1276 &psessionEntry->dph.dphHashTable);
1277 if (NULL == pStaDs) {
1278 PELOG1(lim_log(pMac, LOG1, FL("pStaDs is NULL"));)
1279 return;
1280 }
1281 lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
1282 /* if we are in 5 GHZ band */
1283 if (SIR_BAND_5_GHZ == rfBand) {
1284 /* We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ. */
1285 /* HT20 case is common between both the bands and handled down as common code. */
1286 if (true == psessionEntry->htCapability) {
1287 /* we are 11N and 11A station is joining. */
1288 /* protection from 11A required. */
1289 if (false == pStaDs->mlmStaContext.htCapability) {
1290 lim_update_11a_protection(pMac, true, false,
1291 pBeaconParams,
1292 psessionEntry);
1293 return;
1294 }
1295 }
1296 } else if (SIR_BAND_2_4_GHZ == rfBand) {
1297 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
1298
1299 /* We are 11G. Check if we need protection from 11b Stations. */
1300 if ((phyMode == WNI_CFG_PHY_MODE_11G) &&
1301 (false == psessionEntry->htCapability)) {
1302
1303 if (pStaDs->erpEnabled == eHAL_CLEAR) {
1304 protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
1305 /* enable protection */
1306 PELOG3(lim_log
1307 (pMac, LOG3,
1308 FL("Enabling protection from 11B"));
1309 )
1310 lim_enable11g_protection(pMac, true, false,
1311 pBeaconParams,
1312 psessionEntry);
1313 }
1314 }
1315 /* HT station. */
1316 if (true == psessionEntry->htCapability) {
1317 /* check if we need protection from 11b station */
1318 if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
1319 (!pStaDs->mlmStaContext.htCapability)) {
1320 protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
1321 /* enable protection */
1322 PELOG3(lim_log
1323 (pMac, LOG3,
1324 FL("Enabling protection from 11B"));
1325 )
1326 lim_enable11g_protection(pMac, true, false,
1327 pBeaconParams,
1328 psessionEntry);
1329 }
1330 /* station being joined is non-11b and non-ht ==> 11g device */
1331 else if (!pStaDs->mlmStaContext.htCapability) {
1332 protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llG;
1333 /* enable protection */
1334 lim_enable_ht_protection_from11g(pMac, true, false,
1335 pBeaconParams,
1336 psessionEntry);
1337 }
1338 /* ERP mode is enabled for the latest station joined */
1339 /* latest station joined is HT capable */
1340 /* This case is being handled in common code (commn between both the bands) below. */
1341 }
1342 }
1343 /* we are HT and HT station is joining. This code is common for both the bands. */
1344 if ((true == psessionEntry->htCapability) &&
1345 (true == pStaDs->mlmStaContext.htCapability)) {
1346 if (!pStaDs->htGreenfield) {
1347 lim_enable_ht_non_gf_protection(pMac, true, false,
1348 pBeaconParams,
1349 psessionEntry);
1350 gfSupported = eHAL_CLEAR;
1351 }
1352 /* Station joining is HT 20Mhz */
1353 if ((eHT_CHANNEL_WIDTH_20MHZ ==
1354 pStaDs->htSupportedChannelWidthSet) &&
1355 (eHT_CHANNEL_WIDTH_20MHZ !=
1356 psessionEntry->htSupportedChannelWidthSet)){
1357 protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_HT20;
1358 lim_enable_ht20_protection(pMac, true, false,
1359 pBeaconParams, psessionEntry);
1360 }
1361 /* Station joining does not support LSIG TXOP Protection */
1362 if (!pStaDs->htLsigTXOPProtection) {
1363 lim_enable_ht_lsig_txop_protection(pMac, false, false,
1364 pBeaconParams,
1365 psessionEntry);
1366 lsigTxopSupported = eHAL_CLEAR;
1367 }
1368 }
1369
1370 lim_update_prot_sta_params(pMac, peerMacAddr, protStaCacheType,
1371 gfSupported, lsigTxopSupported, psessionEntry);
1372
1373 return;
1374}
1375
1376/** -------------------------------------------------------------
1377 \fn lim_enable_overlap11g_protection
1378 \brief wrapper function for setting overlap 11g protection.
1379 \param tpAniSirGlobal pMac
1380 \param tpUpdateBeaconParams pBeaconParams
1381 \param tpSirMacMgmtHdr pMh
1382 \return None
1383 -------------------------------------------------------------*/
1384void
1385lim_enable_overlap11g_protection(tpAniSirGlobal pMac,
1386 tpUpdateBeaconParams pBeaconParams,
1387 tpSirMacMgmtHdr pMh, tpPESession psessionEntry)
1388{
1389 lim_update_overlap_sta_param(pMac, pMh->bssId,
1390 &(psessionEntry->gLimOlbcParams));
1391
1392 if (psessionEntry->gLimOlbcParams.numSta &&
1393 !psessionEntry->gLimOlbcParams.protectionEnabled) {
1394 /* enable protection */
1395 PELOG1(lim_log(pMac, LOG1, FL("OLBC happens!!!"));)
1396 lim_enable11g_protection(pMac, true, true, pBeaconParams,
1397 psessionEntry);
1398 }
1399}
1400
1401/**
1402 * lim_update_short_preamble() - This function Updates short preamble
1403 * @mac_ctx: pointer to Global MAC structure
1404 * @peer_mac_addr: pointer to tSirMacAddr
1405 * @pbeaconparams: pointer to tpUpdateBeaconParams
1406 * @psession_entry: pointer to tpPESession
1407 *
1408 * Function Updates short preamble if needed when a new station joins
1409 *
1410 * Return: none
1411 */
1412void
1413lim_update_short_preamble(tpAniSirGlobal mac_ctx, tSirMacAddr peer_mac_addr,
1414 tpUpdateBeaconParams beaconparams,
1415 tpPESession psession_entry)
1416{
1417 uint16_t aid;
1418 tpDphHashNode sta_ds;
1419 uint32_t phy_mode;
1420 uint16_t i;
1421
1422 /* check whether to enable protection or not */
1423 sta_ds =
1424 dph_lookup_hash_entry(mac_ctx, peer_mac_addr, &aid,
1425 &psession_entry->dph.dphHashTable);
1426
1427 lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry);
1428
1429 if (sta_ds == NULL || phy_mode != WNI_CFG_PHY_MODE_11G)
1430 return;
1431
1432 if (sta_ds->shortPreambleEnabled != eHAL_CLEAR)
1433 return;
1434
1435 lim_log(mac_ctx, LOG1,
1436 FL("Short Preamble is not enabled in Assoc Req from "));
1437
1438 lim_print_mac_addr(mac_ctx, peer_mac_addr, LOG1);
1439
1440 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1441 if (LIM_IS_AP_ROLE(psession_entry) &&
1442 (psession_entry->gLimNoShortParams.
1443 staNoShortCache[i].active) &&
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301444 (!qdf_mem_cmp
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001445 (psession_entry->gLimNoShortParams.
1446 staNoShortCache[i].addr,
1447 peer_mac_addr, sizeof(tSirMacAddr))))
1448 return;
1449 else if (!LIM_IS_AP_ROLE(psession_entry) &&
1450 (mac_ctx->lim.gLimNoShortParams.
1451 staNoShortCache[i].active) &&
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301452 (!qdf_mem_cmp(mac_ctx->lim.gLimNoShortParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001453 staNoShortCache[i].addr,
1454 peer_mac_addr,
1455 sizeof(tSirMacAddr))))
1456 return;
1457 }
1458
1459 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1460 if (LIM_IS_AP_ROLE(psession_entry) &&
1461 !psession_entry->gLimNoShortParams.
1462 staNoShortCache[i].active)
1463 break;
1464 else if (!mac_ctx->lim.gLimNoShortParams.
1465 staNoShortCache[i].active)
1466 break;
1467 }
1468
1469 if (i >= LIM_PROT_STA_CACHE_SIZE) {
1470 tLimNoShortParams *lim_params =
1471 &psession_entry->gLimNoShortParams;
1472 if (LIM_IS_AP_ROLE(psession_entry)) {
1473 lim_log(mac_ctx, LOGE,
1474 FL("No space in Short cache (#active %d, #sta %d) for sta "),
1475 i,
1476 lim_params->numNonShortPreambleSta);
1477 lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
1478 return;
1479 } else {
1480 lim_log(mac_ctx, LOGE,
1481 FL("No space in Short cache (#active %d, #sta %d) for sta "),
1482 i,
1483 lim_params->numNonShortPreambleSta);
1484 lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
1485 return;
1486 }
1487
1488 }
1489
1490 if (LIM_IS_AP_ROLE(psession_entry)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301491 qdf_mem_copy(psession_entry->gLimNoShortParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001492 staNoShortCache[i].addr,
1493 peer_mac_addr, sizeof(tSirMacAddr));
1494 psession_entry->gLimNoShortParams.staNoShortCache[i].
1495 active = true;
1496 psession_entry->gLimNoShortParams.numNonShortPreambleSta++;
1497 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301498 qdf_mem_copy(mac_ctx->lim.gLimNoShortParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 staNoShortCache[i].addr,
1500 peer_mac_addr, sizeof(tSirMacAddr));
1501 mac_ctx->lim.gLimNoShortParams.staNoShortCache[i].active = true;
1502 mac_ctx->lim.gLimNoShortParams.numNonShortPreambleSta++;
1503 }
1504
1505 /* enable long preamble */
1506 lim_log(mac_ctx, LOG1, FL("Disabling short preamble"));
1507
1508 if (lim_enable_short_preamble(mac_ctx, false, beaconparams,
1509 psession_entry) != eSIR_SUCCESS)
1510 lim_log(mac_ctx, LOGE, FL("Cannot enable long preamble"));
1511}
1512
1513/**
1514 * lim_update_short_slot_time() - This function Updates short slot time
1515 * @mac_ctx: pointer to Global MAC structure
1516 * @peer_mac_addr: pointer to tSirMacAddr
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301517 * @beacon_params: pointer to tpUpdateBeaconParams
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518 * @psession_entry: pointer to tpPESession
1519 *
1520 * Function Updates short slot time if needed when a new station joins
1521 *
1522 * Return: None
1523 */
1524void
1525lim_update_short_slot_time(tpAniSirGlobal mac_ctx, tSirMacAddr peer_mac_addr,
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301526 tpUpdateBeaconParams beacon_params,
1527 tpPESession session_entry)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528{
1529 uint16_t aid;
1530 tpDphHashNode sta_ds;
1531 uint32_t phy_mode;
1532 uint32_t val;
1533 uint16_t i;
1534
1535 /* check whether to enable protection or not */
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301536 sta_ds = dph_lookup_hash_entry(mac_ctx, peer_mac_addr, &aid,
1537 &session_entry->dph.dphHashTable);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
1539
1540 if (sta_ds == NULL || phy_mode != WNI_CFG_PHY_MODE_11G)
1541 return;
1542
1543 /*
1544 * Only in case of softap in 11g mode, slot time might change
1545 * depending on the STA being added. In 11a case, it should
1546 * be always 1 and in 11b case, it should be always 0.
1547 * Only when the new STA has short slot time disabled, we need to
1548 * change softap's overall slot time settings else the default for
1549 * softap is always short slot enabled. When the last long slot STA
1550 * leaves softAP, we take care of it in lim_decide_short_slot
1551 */
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301552 if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR)
1553 return;
1554
1555 lim_log(mac_ctx, LOG1, FL("Short Slot Time is not enabled in Assoc Req from "));
1556 lim_print_mac_addr(mac_ctx, peer_mac_addr, LOG1);
1557 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1558 if (LIM_IS_AP_ROLE(session_entry) &&
1559 session_entry->gLimNoShortSlotParams.
1560 staNoShortSlotCache[i].active) {
1561 if (!qdf_mem_cmp(session_entry->
1562 gLimNoShortSlotParams.staNoShortSlotCache[i].addr,
1563 peer_mac_addr, sizeof(tSirMacAddr)))
1564 return;
1565 } else if (!LIM_IS_AP_ROLE(session_entry)) {
1566 if (mac_ctx->lim.gLimNoShortSlotParams.
1567 staNoShortSlotCache[i].active) {
1568 if (!qdf_mem_cmp(mac_ctx->
1569 lim.gLimNoShortSlotParams.
1570 staNoShortSlotCache[i].addr,
1571 peer_mac_addr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573 }
1574 }
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301575 }
1576 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1577 if (LIM_IS_AP_ROLE(session_entry) &&
1578 !session_entry->gLimNoShortSlotParams.
1579 staNoShortSlotCache[i].active)
1580 break;
1581 else
1582 if (!mac_ctx->lim.gLimNoShortSlotParams.
1583 staNoShortSlotCache[i].active)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 break;
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301585 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001586
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301587 if (i >= LIM_PROT_STA_CACHE_SIZE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001588 if (LIM_IS_AP_ROLE(session_entry)) {
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301589 lim_log(mac_ctx, LOGE,
1590 FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "),
1591 i, session_entry->gLimNoShortSlotParams.
1592 numNonShortSlotSta);
1593 lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
1594 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595 } else {
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301596 lim_log(mac_ctx, LOGE,
1597 FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "),
1598 i,
1599 mac_ctx->lim.gLimNoShortSlotParams.
1600 numNonShortSlotSta);
1601 lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
1602 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001603 }
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301604 }
1605
1606 if (LIM_IS_AP_ROLE(session_entry)) {
1607 qdf_mem_copy(session_entry->gLimNoShortSlotParams.
1608 staNoShortSlotCache[i].addr,
1609 peer_mac_addr, sizeof(tSirMacAddr));
1610 session_entry->gLimNoShortSlotParams.
1611 staNoShortSlotCache[i].active = true;
1612 session_entry->gLimNoShortSlotParams.numNonShortSlotSta++;
1613 } else {
1614 qdf_mem_copy(mac_ctx->lim.gLimNoShortSlotParams.
1615 staNoShortSlotCache[i].addr,
1616 peer_mac_addr, sizeof(tSirMacAddr));
1617 mac_ctx->lim.gLimNoShortSlotParams.
1618 staNoShortSlotCache[i].active = true;
1619 mac_ctx->lim.gLimNoShortSlotParams.
1620 numNonShortSlotSta++;
1621 }
1622 wlan_cfg_get_int(mac_ctx, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val);
1623 /*
1624 * Here we check if we are AP role and short slot enabled
1625 * (both admin and oper modes) but we have atleast one STA
1626 * connected with only long slot enabled, we need to change
1627 * our beacon/pb rsp to broadcast short slot disabled
1628 */
1629 if ((LIM_IS_AP_ROLE(session_entry)) && (val &&
1630 session_entry->gLimNoShortSlotParams.numNonShortSlotSta
1631 && session_entry->shortSlotTimeSupported)) {
1632 /* enable long slot time */
1633 beacon_params->fShortSlotTime = false;
1634 beacon_params->paramChangeBitmap |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 PARAM_SHORT_SLOT_TIME_CHANGED;
Sreelakshmi Konamkif611d1a2016-02-19 17:47:42 +05301636 lim_log(mac_ctx, LOG1,
1637 FL("Disable short slot time. Enable long slot time."));
1638 session_entry->shortSlotTimeSupported = false;
1639 } else if (!LIM_IS_AP_ROLE(session_entry) &&
1640 (val && mac_ctx->lim.gLimNoShortSlotParams.
1641 numNonShortSlotSta &&
1642 session_entry->shortSlotTimeSupported)) {
1643 /* enable long slot time */
1644 beacon_params->fShortSlotTime = false;
1645 beacon_params->paramChangeBitmap |=
1646 PARAM_SHORT_SLOT_TIME_CHANGED;
1647 lim_log(mac_ctx, LOG1,
1648 FL("Disable short slot time. Enable long slot time."));
1649 session_entry->shortSlotTimeSupported = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 }
1651}
1652
1653/** -------------------------------------------------------------
1654 \fn lim_decide_sta_protection_on_assoc
1655 \brief Decide protection related settings on Sta while association.
1656 \param tpAniSirGlobal pMac
1657 \param tpSchBeaconStruct pBeaconStruct
1658 \return None
1659 -------------------------------------------------------------*/
1660void
1661lim_decide_sta_protection_on_assoc(tpAniSirGlobal pMac,
1662 tpSchBeaconStruct pBeaconStruct,
1663 tpPESession psessionEntry)
1664{
1665 tSirRFBand rfBand = SIR_BAND_UNKNOWN;
1666 uint32_t phyMode = WNI_CFG_PHY_MODE_NONE;
1667
1668 lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
1669 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
1670
1671 if (SIR_BAND_5_GHZ == rfBand) {
1672 if ((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) ||
1673 (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
1674 pBeaconStruct->HTInfo.opMode)) {
1675 if (pMac->lim.cfgProtection.fromlla)
1676 psessionEntry->beaconParams.llaCoexist = true;
1677 } else if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
1678 pBeaconStruct->HTInfo.opMode) {
1679 if (pMac->lim.cfgProtection.ht20)
1680 psessionEntry->beaconParams.ht20Coexist = true;
1681 }
1682
1683 } else if (SIR_BAND_2_4_GHZ == rfBand) {
1684 /* spec 7.3.2.13 */
1685 /* UseProtection will be set when nonERP STA is associated. */
1686 /* NonERPPresent bit will be set when: */
1687 /* --nonERP Sta is associated OR */
1688 /* --nonERP Sta exists in overlapping BSS */
1689 /* when useProtection is not set then protection from nonERP stations is optional. */
1690
1691 /* CFG protection from 11b is enabled and */
1692 /* 11B device in the BSS */
1693 /* TODO, This is not sessionized */
1694 if (phyMode != WNI_CFG_PHY_MODE_11B) {
1695 if (pMac->lim.cfgProtection.fromllb &&
1696 pBeaconStruct->erpPresent &&
1697 (pBeaconStruct->erpIEInfo.useProtection ||
1698 pBeaconStruct->erpIEInfo.nonErpPresent)) {
1699 psessionEntry->beaconParams.llbCoexist = true;
1700 }
1701 /* AP has no 11b station associated. */
1702 else {
1703 psessionEntry->beaconParams.llbCoexist = false;
1704 }
1705 }
1706 /* following code block is only for HT station. */
1707 if ((psessionEntry->htCapability) &&
1708 (pBeaconStruct->HTInfo.present)) {
1709 tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
1710
1711 /* Obss Non HT STA present mode */
1712 psessionEntry->beaconParams.gHTObssMode =
1713 (uint8_t) htInfo.obssNonHTStaPresent;
1714
1715 /* CFG protection from 11G is enabled and */
1716 /* our AP has at least one 11G station associated. */
1717 if (pMac->lim.cfgProtection.fromllg &&
1718 ((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
1719 (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))
1720 && (!psessionEntry->beaconParams.llbCoexist)) {
1721 if (pMac->lim.cfgProtection.fromllg)
1722 psessionEntry->beaconParams.llgCoexist =
1723 true;
1724 }
1725 /* AP has only HT stations associated and at least one station is HT 20 */
1726 /* disable protection from any non-HT devices. */
1727 /* decision for disabling protection from 11b has already been taken above. */
1728 if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) {
1729 /* Disable protection from 11G station. */
1730 psessionEntry->beaconParams.llgCoexist = false;
1731 /* CFG protection from HT 20 is enabled. */
1732 if (pMac->lim.cfgProtection.ht20)
1733 psessionEntry->beaconParams.
1734 ht20Coexist = true;
1735 }
1736 /* Disable protection from non-HT and HT20 devices. */
1737 /* decision for disabling protection from 11b has already been taken above. */
1738 if (eSIR_HT_OP_MODE_PURE == htInfo.opMode) {
1739 psessionEntry->beaconParams.llgCoexist = false;
1740 psessionEntry->beaconParams.ht20Coexist = false;
1741 }
1742
1743 }
1744 }
1745 /* protection related factors other than HT operating mode. Applies to 2.4 GHZ as well as 5 GHZ. */
1746 if ((psessionEntry->htCapability) && (pBeaconStruct->HTInfo.present)) {
1747 tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
1748 psessionEntry->beaconParams.fRIFSMode =
1749 (uint8_t) htInfo.rifsMode;
1750 psessionEntry->beaconParams.llnNonGFCoexist =
1751 (uint8_t) htInfo.nonGFDevicesPresent;
1752 psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
1753 (uint8_t) htInfo.lsigTXOPProtectionFullSupport;
1754 }
1755}
1756
1757
1758/**
1759 * lim_decide_sta_11bg_protection() - decides protection related settings on sta
1760 * @mac_ctx: pointer to global mac structure
1761 * @beacon_struct: pointer to tpschbeaconstruct
1762 * @beaconparams: pointer to tpupdatebeaconparams
1763 * @psession_entry: pointer to tppesession
1764 * @phy_mode: phy mode index
1765 *
1766 * decides 11bg protection related settings on sta while processing beacon
1767 *
1768 * Return: none
1769 */
1770static void
1771lim_decide_sta_11bg_protection(tpAniSirGlobal mac_ctx,
1772 tpSchBeaconStruct beacon_struct,
1773 tpUpdateBeaconParams beaconparams,
1774 tpPESession psession_entry,
1775 uint32_t phy_mode)
1776{
1777
1778 tDot11fIEHTInfo htInfo;
1779
1780 /*
1781 * spec 7.3.2.13
1782 * UseProtection will be set when nonERP STA is associated.
1783 * NonERPPresent bit will be set when:
1784 * --nonERP Sta is associated OR
1785 * --nonERP Sta exists in overlapping BSS
1786 * when useProtection is not set then protection from
1787 * nonERP stations is optional.
1788 */
1789 if (phy_mode != WNI_CFG_PHY_MODE_11B) {
1790 if (beacon_struct->erpPresent &&
1791 (beacon_struct->erpIEInfo.useProtection ||
1792 beacon_struct->erpIEInfo.nonErpPresent)) {
1793 lim_enable11g_protection(mac_ctx, true, false,
1794 beaconparams,
1795 psession_entry);
1796 }
1797 /* AP has no 11b station associated. */
1798 else {
1799 /* disable protection from 11b station */
1800 lim_enable11g_protection(mac_ctx, false, false,
1801 beaconparams,
1802 psession_entry);
1803 }
1804 }
1805
1806 if (!(psession_entry->htCapability) ||
1807 !(beacon_struct->HTInfo.present))
1808 return;
1809
1810 /* following code is only for HT station. */
1811
1812 htInfo = beacon_struct->HTInfo;
1813 /* AP has at least one 11G station associated. */
1814 if (((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
1815 (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode)) &&
1816 (!psession_entry->beaconParams.llbCoexist)) {
1817 lim_enable_ht_protection_from11g(mac_ctx, true, false,
1818 beaconparams, psession_entry);
1819
1820 }
1821 /*
1822 * no HT operating mode change ==> no change in
1823 * protection settings except for MIXED_MODE/Legacy
1824 * Mode.
1825 */
1826 /*
1827 * in Mixed mode/legacy Mode even if there is no
1828 * change in HT operating mode, there might be
1829 * change in 11bCoexist or 11gCoexist. Hence this
1830 * check is being done after mixed/legacy mode
1831 * check.
1832 */
1833 if (mac_ctx->lim.gHTOperMode !=
1834 (tSirMacHTOperatingMode)htInfo.opMode) {
1835 mac_ctx->lim.gHTOperMode =
1836 (tSirMacHTOperatingMode) htInfo.opMode;
1837 /*
1838 * AP has only HT stations associated and
1839 * at least one station is HT 20
1840 */
1841
1842 /* disable protection from any non-HT devices. */
1843
1844 /*
1845 * decision for disabling protection from
1846 * 11b has already been taken above.
1847 */
1848 if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
1849 htInfo.opMode) {
1850 /* Disable protection from 11G station. */
1851 lim_enable_ht_protection_from11g(mac_ctx, false,
1852 false, beaconparams,
1853 psession_entry);
1854
1855 lim_enable_ht20_protection(mac_ctx, true, false,
1856 beaconparams,
1857 psession_entry);
1858 }
1859 /*
1860 * Disable protection from non-HT and
1861 * HT20 devices.
1862 */
1863 /*
1864 * decision for disabling protection from
1865 * 11b has already been taken above.
1866 */
1867 else if (eSIR_HT_OP_MODE_PURE == htInfo.opMode) {
1868 lim_enable_ht_protection_from11g(mac_ctx, false,
1869 false, beaconparams,
1870 psession_entry);
1871
1872 lim_enable_ht20_protection(mac_ctx, false,
1873 false, beaconparams,
1874 psession_entry);
1875
1876 }
1877 }
1878
1879}
1880
1881/**
1882 * lim_decide_sta_protection() - decides protection related settings on sta
1883 * @mac_ctx: pointer to global mac structure
1884 * @beacon_struct: pointer to tpschbeaconstruct
1885 * @beaconparams: pointer to tpupdatebeaconparams
1886 * @psession_entry: pointer to tppesession
1887 *
1888 * decides protection related settings on sta while processing beacon
1889 *
1890 * Return: none
1891 */
1892void
1893lim_decide_sta_protection(tpAniSirGlobal mac_ctx,
1894 tpSchBeaconStruct beacon_struct,
1895 tpUpdateBeaconParams beaconparams,
1896 tpPESession psession_entry)
1897{
1898
1899 tSirRFBand rfband = SIR_BAND_UNKNOWN;
1900 uint32_t phy_mode = WNI_CFG_PHY_MODE_NONE;
1901
1902 lim_get_rf_band_new(mac_ctx, &rfband, psession_entry);
1903 lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry);
1904
1905 if ((SIR_BAND_5_GHZ == rfband) &&
1906 /* we are HT capable. */
1907 (true == psession_entry->htCapability) &&
1908 (beacon_struct->HTInfo.present)) {
1909 /*
1910 * we are HT capable, AP's HT OPMode is
1911 * mixed / overlap legacy ==> need protection
1912 * from 11A.
1913 */
1914 if ((eSIR_HT_OP_MODE_MIXED ==
1915 beacon_struct->HTInfo.opMode) ||
1916 (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
1917 beacon_struct->HTInfo.opMode)) {
1918 lim_update_11a_protection(mac_ctx, true, false,
1919 beaconparams, psession_entry);
1920 }
1921 /*
1922 * we are HT capable, AP's HT OPMode is
1923 * HT20 ==> disable protection from 11A if
1924 * enabled.
1925 */
1926 /* protection from HT20 if needed. */
1927 else if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
1928 beacon_struct->HTInfo.opMode) {
1929 lim_update_11a_protection(mac_ctx, false, false,
1930 beaconparams, psession_entry);
1931 lim_enable_ht20_protection(mac_ctx, true, false,
1932 beaconparams, psession_entry);
1933 } else if (eSIR_HT_OP_MODE_PURE ==
1934 beacon_struct->HTInfo.opMode) {
1935 lim_update_11a_protection(mac_ctx, false, false,
1936 beaconparams, psession_entry);
1937 lim_enable_ht20_protection(mac_ctx, false,
1938 false, beaconparams,
1939 psession_entry);
1940 }
1941 } else if (SIR_BAND_2_4_GHZ == rfband) {
1942 lim_decide_sta_11bg_protection(mac_ctx, beacon_struct,
1943 beaconparams, psession_entry, phy_mode);
1944 }
1945 /*
1946 * following code block is only for HT station.
1947 * (2.4 GHZ as well as 5 GHZ)
1948 */
1949 if ((psession_entry->htCapability) && (beacon_struct->HTInfo.present)) {
1950 tDot11fIEHTInfo htInfo = beacon_struct->HTInfo;
1951 /*
1952 * Check for changes in protection related factors other
1953 * than HT operating mode.
1954 */
1955 /*
1956 * Check for changes in RIFS mode, nonGFDevicesPresent,
1957 * lsigTXOPProtectionFullSupport.
1958 */
1959 if (psession_entry->beaconParams.fRIFSMode !=
1960 (uint8_t) htInfo.rifsMode) {
1961 beaconparams->fRIFSMode =
1962 psession_entry->beaconParams.fRIFSMode =
1963 (uint8_t) htInfo.rifsMode;
1964 beaconparams->paramChangeBitmap |=
1965 PARAM_RIFS_MODE_CHANGED;
1966 }
1967
1968 if (psession_entry->beaconParams.llnNonGFCoexist !=
1969 htInfo.nonGFDevicesPresent) {
1970 beaconparams->llnNonGFCoexist =
1971 psession_entry->beaconParams.llnNonGFCoexist =
1972 (uint8_t) htInfo.nonGFDevicesPresent;
1973 beaconparams->paramChangeBitmap |=
1974 PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
1975 }
1976
1977 if (psession_entry->beaconParams.
1978 fLsigTXOPProtectionFullSupport !=
1979 (uint8_t) htInfo.lsigTXOPProtectionFullSupport) {
1980 beaconparams->fLsigTXOPProtectionFullSupport =
1981 psession_entry->beaconParams.
1982 fLsigTXOPProtectionFullSupport =
1983 (uint8_t) htInfo.
1984 lsigTXOPProtectionFullSupport;
1985 beaconparams->paramChangeBitmap |=
1986 PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
1987 }
1988 /*
1989 * For Station just update the global lim variable,
1990 * no need to send message to HAL since Station already
1991 * taking care of HT OPR Mode=01,
1992 * meaning AP is seeing legacy
1993 */
1994 /* stations in overlapping BSS. */
1995 if (psession_entry->beaconParams.gHTObssMode !=
1996 (uint8_t) htInfo.obssNonHTStaPresent)
1997 psession_entry->beaconParams.gHTObssMode =
1998 (uint8_t) htInfo.obssNonHTStaPresent;
1999
2000 }
2001}
2002
2003/**
2004 * lim_process_channel_switch_timeout()
2005 *
2006 ***FUNCTION:
2007 * This function is invoked when Channel Switch Timer expires at
2008 * the STA. Now, STA must stop traffic, and then change/disable
2009 * primary or secondary channel.
2010 *
2011 *
2012 ***NOTE:
2013 * @param pMac - Pointer to Global MAC structure
2014 * @return None
2015 */
2016void lim_process_channel_switch_timeout(tpAniSirGlobal pMac)
2017{
2018 tpPESession psessionEntry = NULL;
2019 uint8_t channel; /* This is received and stored from channelSwitch Action frame */
2020
2021 psessionEntry = pe_find_session_by_session_id(pMac,
2022 pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId);
2023 if (psessionEntry == NULL) {
2024 lim_log(pMac, LOGP,
2025 FL("Session Does not exist for given sessionID"));
2026 return;
2027 }
2028
2029 if (!LIM_IS_STA_ROLE(psessionEntry)) {
2030 PELOGW(lim_log
2031 (pMac, LOGW,
2032 "Channel switch can be done only in STA role, Current Role = %d",
2033 GET_LIM_SYSTEM_ROLE(psessionEntry));
2034 )
2035 return;
2036 }
2037
2038 channel = psessionEntry->gLimChannelSwitch.primaryChannel;
2039 /* Restore Channel Switch parameters to default */
2040 psessionEntry->gLimChannelSwitch.switchTimeoutValue = 0;
2041
2042 /* Channel-switch timeout has occurred. reset the state */
2043 psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_END;
2044
2045 /* Check if the AP is switching to a channel that we support.
2046 * Else, just don't bother to switch. Indicate HDD to look for a
2047 * better AP to associate
2048 */
2049 if (!lim_is_channel_valid_for_channel_switch(pMac, channel)) {
2050 /* We need to restore pre-channelSwitch state on the STA */
2051 if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
2052 eSIR_SUCCESS) {
2053 lim_log(pMac, LOGP,
2054 FL
2055 ("Could not restore pre-channelSwitch (11h) state, resetting the system"));
2056 return;
2057 }
2058
2059 /* If the channel-list that AP is asking us to switch is invalid,
2060 * then we cannot switch the channel. Just disassociate from AP.
2061 * We will find a better AP !!!
2062 */
2063 lim_tear_down_link_with_ap(pMac,
2064 pMac->lim.limTimers.
2065 gLimChannelSwitchTimer.sessionId,
2066 eSIR_MAC_UNSPEC_FAILURE_REASON);
2067 return;
2068 }
2069 lim_covert_channel_scan_type(pMac, psessionEntry->currentOperChannel,
2070 false);
2071 pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] =
2072 0;
2073 switch (psessionEntry->gLimChannelSwitch.state) {
2074 case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY:
2075 PELOGW(lim_log(pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_ONLY "));)
2076 lim_switch_primary_channel(pMac,
2077 psessionEntry->gLimChannelSwitch.
2078 primaryChannel, psessionEntry);
2079 psessionEntry->gLimChannelSwitch.state =
2080 eLIM_CHANNEL_SWITCH_IDLE;
2081 break;
2082 case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY:
2083 PELOGW(lim_log
2084 (pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_AND_SECONDARY"));
2085 )
2086 lim_switch_primary_secondary_channel(pMac, psessionEntry,
2087 psessionEntry->gLimChannelSwitch.primaryChannel,
2088 psessionEntry->gLimChannelSwitch.ch_center_freq_seg0,
2089 psessionEntry->gLimChannelSwitch.ch_center_freq_seg1,
2090 psessionEntry->gLimChannelSwitch.ch_width);
2091 psessionEntry->gLimChannelSwitch.state =
2092 eLIM_CHANNEL_SWITCH_IDLE;
2093 break;
2094
2095 case eLIM_CHANNEL_SWITCH_IDLE:
2096 default:
2097 PELOGE(lim_log(pMac, LOGE, FL("incorrect state "));)
2098 if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
2099 eSIR_SUCCESS) {
2100 lim_log(pMac, LOGP,
2101 FL
2102 ("Could not restore pre-channelSwitch (11h) state, resetting the system"));
2103 }
2104 return; /* Please note, this is 'return' and not 'break' */
2105 }
2106}
2107
2108/**
2109 * lim_update_channel_switch() - This Function updates channel switch
2110 * @mac_ctx: pointer to Global MAC structure
2111 * @beacon: pointer to tpSirProbeRespBeacon
2112 * @psessionentry: pointer to tpPESession
2113 *
2114 * This function is invoked whenever Station receives
2115 * either 802.11h channel switch IE or airgo proprietary
2116 * channel switch IE.
2117 *
2118 * Return: none
2119 */
2120void
2121lim_update_channel_switch(struct sAniSirGlobal *mac_ctx,
2122 tpSirProbeRespBeacon beacon,
2123 tpPESession psession_entry)
2124{
2125 uint16_t beacon_period;
2126 tDot11fIEChanSwitchAnn *chnl_switch;
2127 tLimChannelSwitchInfo *ch_switch_params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002128 tDot11fIEWiderBWChanSwitchAnn *widerchnl_switch;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002129
2130 beacon_period = psession_entry->beaconParams.beaconInterval;
2131
2132 /* 802.11h standard channel switch IE */
2133 chnl_switch = &(beacon->channelSwitchIE);
2134 ch_switch_params = &psession_entry->gLimChannelSwitch;
2135 ch_switch_params->primaryChannel =
2136 chnl_switch->newChannel;
2137 ch_switch_params->switchCount = chnl_switch->switchCount;
2138 ch_switch_params->switchTimeoutValue =
2139 SYS_MS_TO_TICKS(beacon_period) * (chnl_switch->switchCount);
2140 ch_switch_params->switchMode = chnl_switch->switchMode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002141 widerchnl_switch = &(beacon->WiderBWChanSwitchAnn);
2142 if (beacon->WiderBWChanSwitchAnnPresent) {
2143 psession_entry->gLimWiderBWChannelSwitch.newChanWidth =
2144 widerchnl_switch->newChanWidth;
2145 psession_entry->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
2146 widerchnl_switch->newCenterChanFreq0;
2147 psession_entry->gLimWiderBWChannelSwitch.newCenterChanFreq1 =
2148 widerchnl_switch->newCenterChanFreq1;
2149 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 /* Only primary channel switch element is present */
2151 ch_switch_params->state =
2152 eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
2153 ch_switch_params->ch_width = CH_WIDTH_20MHZ;
2154
2155 /*
2156 * Do not bother to look and operate on extended channel switch element
2157 * if our own channel-bonding state is not enabled
2158 */
2159 if (psession_entry->htSupportedChannelWidthSet &&
2160 beacon->sec_chan_offset_present) {
2161 if (beacon->sec_chan_offset.secondaryChannelOffset ==
2162 PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
2163 ch_switch_params->state =
2164 eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
2165 ch_switch_params->ch_width = CH_WIDTH_40MHZ;
2166 ch_switch_params->ch_center_freq_seg0 =
2167 ch_switch_params->primaryChannel + 2;
2168 } else if (beacon->sec_chan_offset.secondaryChannelOffset ==
2169 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
2170 ch_switch_params->state =
2171 eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
2172 ch_switch_params->ch_width = CH_WIDTH_40MHZ;
2173 ch_switch_params->ch_center_freq_seg0 =
2174 ch_switch_params->primaryChannel - 2;
2175 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002176 if (psession_entry->vhtCapability &&
2177 beacon->WiderBWChanSwitchAnnPresent) {
2178 ch_switch_params->ch_width =
2179 widerchnl_switch->newChanWidth + 1;
2180 ch_switch_params->ch_center_freq_seg0 =
2181 psession_entry->gLimWiderBWChannelSwitch.
2182 newCenterChanFreq0;
2183 ch_switch_params->ch_center_freq_seg1 =
2184 psession_entry->gLimWiderBWChannelSwitch.
2185 newCenterChanFreq1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186 }
2187 }
2188 if (eSIR_SUCCESS != lim_start_channel_switch(mac_ctx, psession_entry))
2189 lim_log(mac_ctx, LOGW, FL("Could not start Channel Switch"));
2190
2191 lim_log(mac_ctx, LOGW,
2192 FL("session %d primary chl %d, ch_width %d, count %d (%d ticks)"),
2193 psession_entry->peSessionId,
2194 psession_entry->gLimChannelSwitch.primaryChannel,
2195 psession_entry->gLimChannelSwitch.ch_width,
2196 psession_entry->gLimChannelSwitch.switchCount,
2197 psession_entry->gLimChannelSwitch.switchTimeoutValue);
2198 return;
2199}
2200
2201/**
2202 * lim_cancel_dot11h_channel_switch
2203 *
2204 ***FUNCTION:
2205 * This function is called when STA does not send updated channel-swith IE
2206 * after indicating channel-switch start. This will cancel the channel-swith
2207 * timer which is already running.
2208 *
2209 ***LOGIC:
2210 *
2211 ***ASSUMPTIONS:
2212 *
2213 ***NOTE:
2214 *
2215 * @param pMac - Pointer to Global MAC structure
2216 *
2217 * @return None
2218 */
2219void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
2220 tpPESession psessionEntry)
2221{
2222 if (!LIM_IS_STA_ROLE(psessionEntry))
2223 return;
2224
2225 PELOGW(lim_log
2226 (pMac, LOGW, FL("Received a beacon without channel switch IE"));
2227 )
2228 MTRACE(mac_trace
2229 (pMac, TRACE_CODE_TIMER_DEACTIVATE,
2230 psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER));
2231
2232 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
2233 eSIR_SUCCESS) {
2234 PELOGE(lim_log(pMac, LOGE, FL("tx_timer_deactivate failed!"));)
2235 }
2236
2237 /* We need to restore pre-channelSwitch state on the STA */
2238 if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
2239 eSIR_SUCCESS) {
2240 PELOGE(lim_log
2241 (pMac, LOGE,
2242 FL
2243 ("LIM: Could not restore pre-channelSwitch (11h) state, resetting the system"));
2244 )
2245
2246 }
2247}
2248
2249/**
2250 * lim_cancel_dot11h_quiet()
2251 *
2252 * @mac_ctx: pointer to global mac structure
2253 * @psession_entry: pointer to tppesession
2254 *
2255 * Cancel the quieting on Station if latest beacon
2256 * doesn't contain quiet IE in it.
2257 *
2258 * Return: none
2259 */
2260void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry)
2261{
2262 if (!LIM_IS_STA_ROLE(psessionEntry))
2263 return;
2264
2265 if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) {
2266 MTRACE(mac_trace
2267 (pMac, TRACE_CODE_TIMER_DEACTIVATE,
2268 psessionEntry->peSessionId, eLIM_QUIET_TIMER));
2269 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) !=
2270 TX_SUCCESS) {
2271 PELOGE(lim_log
2272 (pMac, LOGE, FL("tx_timer_deactivate failed"));
2273 )
2274 }
2275 } else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) {
2276 MTRACE(mac_trace
2277 (pMac, TRACE_CODE_TIMER_DEACTIVATE,
2278 psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER));
2279 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)
2280 != TX_SUCCESS) {
2281 PELOGE(lim_log
2282 (pMac, LOGE, FL("tx_timer_deactivate failed"));
2283 )
2284 }
2285 /**
2286 * If the channel switch is already running in silent mode, dont resume the
2287 * transmission. Channel switch timer when timeout, transmission will be resumed.
2288 */
2289 if (!
2290 ((psessionEntry->gLimSpecMgmt.dot11hChanSwState ==
2291 eLIM_11H_CHANSW_RUNNING)
2292 && (psessionEntry->gLimChannelSwitch.switchMode ==
2293 eSIR_CHANSW_MODE_SILENT))) {
2294 lim_frame_transmission_control(pMac, eLIM_TX_ALL,
2295 eLIM_RESUME_TX);
2296 lim_restore_pre_quiet_state(pMac, psessionEntry);
2297 }
2298 }
2299 psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
2300}
2301
2302/**
2303 * lim_process_quiet_timeout
2304 *
2305 * FUNCTION:
2306 * This function is active only on the STA.
2307 * Handles SIR_LIM_QUIET_TIMEOUT
2308 *
2309 * LOGIC:
2310 * This timeout can occur under only one circumstance:
2311 *
2312 * 1) When gLimQuietState = eLIM_QUIET_BEGIN
2313 * This indicates that the timeout "interval" has
2314 * expired. This is a trigger for the STA to now
2315 * shut-off Tx/Rx for the specified gLimQuietDuration
2316 * -> The TIMER object gLimQuietBssTimer is
2317 * activated
2318 * -> With timeout = gLimQuietDuration
2319 * -> gLimQuietState is set to eLIM_QUIET_RUNNING
2320 *
2321 * ASSUMPTIONS:
2322 * Using two TIMER objects -
2323 * gLimQuietTimer & gLimQuietBssTimer
2324 *
2325 * NOTE:
2326 *
2327 * @param pMac - Pointer to Global MAC structure
2328 *
2329 * @return None
2330 */
2331void lim_process_quiet_timeout(tpAniSirGlobal pMac)
2332{
2333 tpPESession psessionEntry;
2334
2335 psessionEntry = pe_find_session_by_session_id(pMac,
2336 pMac->lim.limTimers.gLimQuietTimer.sessionId);
2337 if (psessionEntry == NULL) {
2338 lim_log(pMac, LOGE,
2339 FL("Session Does not exist for given sessionID"));
2340 return;
2341 }
2342
2343 PELOG1(lim_log
2344 (pMac, LOG1, FL("quietState = %d"),
2345 psessionEntry->gLimSpecMgmt.quietState);
2346 )
2347 switch (psessionEntry->gLimSpecMgmt.quietState) {
2348 case eLIM_QUIET_BEGIN:
2349 /* Time to Stop data traffic for quietDuration */
2350 /* lim_deactivate_and_change_timer(pMac, eLIM_QUIET_BSS_TIMER); */
2351 if (TX_SUCCESS != tx_timer_deactivate(
2352 &pMac->lim.limTimers.gLimQuietBssTimer)) {
2353 lim_log(pMac, LOGE,
2354 FL
2355 ("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway..."));
2356 }
2357 /* gLimQuietDuration appears to be in units of ticks */
2358 /* Use it as is */
2359 if (TX_SUCCESS !=
2360 tx_timer_change(&pMac->lim.limTimers.gLimQuietBssTimer,
2361 psessionEntry->gLimSpecMgmt.quietDuration,
2362 0)) {
2363 lim_log(pMac, LOGE,
2364 FL
2365 ("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway..."));
2366 }
2367 MTRACE(mac_trace
2368 (pMac, TRACE_CODE_TIMER_ACTIVATE,
2369 pMac->lim.limTimers.gLimQuietTimer.sessionId,
2370 eLIM_QUIET_BSS_TIMER));
2371 if (TX_SUCCESS !=
2372 tx_timer_activate(&pMac->lim.limTimers.gLimQuietBssTimer)) {
2373 lim_log(pMac, LOGW,
2374 FL
2375 ("Unable to activate gLimQuietBssTimer! The STA will be unable to honor Quiet BSS..."));
2376 } else {
2377 /* Transition to eLIM_QUIET_RUNNING */
2378 psessionEntry->gLimSpecMgmt.quietState =
2379 eLIM_QUIET_RUNNING;
2380 /* Shut-off Tx/Rx for gLimSpecMgmt.quietDuration */
2381 /* freeze the transmission */
2382 lim_frame_transmission_control(pMac, eLIM_TX_ALL,
2383 eLIM_STOP_TX);
2384
2385 lim_log(pMac, LOG2,
2386 FL("Quiet BSS: STA shutting down for %d ticks"),
2387 psessionEntry->gLimSpecMgmt.quietDuration);
2388 }
2389 break;
2390
2391 case eLIM_QUIET_RUNNING:
2392 case eLIM_QUIET_INIT:
2393 case eLIM_QUIET_END:
2394 default:
2395 /* */
2396 /* As of now, nothing to be done */
2397 /* */
2398 break;
2399 }
2400}
2401
2402/**
2403 * lim_process_quiet_bss_timeout() - Handles SIR_LIM_QUIET_BSS_TIMEOUT
2404 * @mac_ctx: pointer to Globale Mac Structure
2405 *
2406 * This function is active on the AP and STA.
2407 * Handles SIR_LIM_QUIET_BSS_TIMEOUT
2408 *
2409 * On the AP -
2410 * When the SIR_LIM_QUIET_BSS_TIMEOUT is triggered, it is
2411 * an indication for the AP to START sending out the
2412 * Quiet BSS IE.
2413 * If 802.11H is enabled, the Quiet BSS IE is sent as per
2414 * the 11H spec
2415 * If 802.11H is not enabled, the Quiet BSS IE is sent as
2416 * a Proprietary IE. This will be understood by all the
2417 * TITAN STA's
2418 * Transitioning gLimQuietState to eLIM_QUIET_BEGIN will
2419 * initiate the SCH to include the Quiet BSS IE in all
2420 * its subsequent Beacons/PR's.
2421 * The Quiet BSS IE will be included in all the Beacons
2422 * & PR's until the next DTIM period
2423 *
2424 * On the STA -
2425 * When gLimQuietState = eLIM_QUIET_RUNNING
2426 * This indicates that the STA was successfully shut-off
2427 * for the specified gLimQuietDuration. This is a trigger
2428 * for the STA to now resume data traffic.
2429 * -> gLimQuietState is set to eLIM_QUIET_INIT
2430 *
2431 *
2432 * Return: none
2433 */
2434void lim_process_quiet_bss_timeout(tpAniSirGlobal mac_ctx)
2435{
2436 tpPESession psession_entry = NULL;
2437 tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
2438
2439 psession_entry = pe_find_session_by_session_id(mac_ctx,
2440 lim_timer->gLimQuietBssTimer.sessionId);
2441
2442 if (psession_entry == NULL) {
2443 lim_log(mac_ctx, LOGP,
2444 FL("Session Does not exist for given sessionID"));
2445 return;
2446 }
2447
2448 lim_log(mac_ctx, LOG1, FL("quietState = %d"),
2449 psession_entry->gLimSpecMgmt.quietState);
2450
2451 if (LIM_IS_AP_ROLE(psession_entry))
2452 return;
2453
2454 /* eLIM_STA_ROLE */
2455 switch (psession_entry->gLimSpecMgmt.quietState) {
2456 case eLIM_QUIET_RUNNING:
2457 /* Transition to eLIM_QUIET_INIT */
2458 psession_entry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
2459
2460 /*
2461 * Resume data traffic only if channel switch is
2462 * not running in silent mode.
2463 */
2464 if (!((psession_entry->gLimSpecMgmt.dot11hChanSwState ==
2465 eLIM_11H_CHANSW_RUNNING) &&
2466 (psession_entry->gLimChannelSwitch.switchMode ==
2467 eSIR_CHANSW_MODE_SILENT))) {
2468 lim_frame_transmission_control(mac_ctx, eLIM_TX_ALL,
2469 eLIM_RESUME_TX);
2470 lim_restore_pre_quiet_state(mac_ctx, psession_entry);
2471 }
2472 lim_log(mac_ctx, LOG2, FL("Quiet BSS: Resuming traffic..."));
2473 break;
2474
2475 case eLIM_QUIET_INIT:
2476 case eLIM_QUIET_BEGIN:
2477 case eLIM_QUIET_END:
2478 lim_log(mac_ctx, LOG2, FL("Quiet state not in RUNNING"));
2479 /*
2480 * If the quiet period has ended, then resume the
2481 * frame transmission
2482 */
2483 lim_frame_transmission_control(mac_ctx, eLIM_TX_ALL,
2484 eLIM_RESUME_TX);
2485 lim_restore_pre_quiet_state(mac_ctx, psession_entry);
2486 psession_entry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
2487 break;
2488
2489 default:
2490 /* As of now, nothing to be done */
2491 break;
2492 }
2493}
2494
2495/**----------------------------------------------
2496 \fn lim_start_quiet_timer
2497 \brief Starts the quiet timer.
2498
2499 \param pMac
2500 \return NONE
2501 -----------------------------------------------*/
2502void lim_start_quiet_timer(tpAniSirGlobal pMac, uint8_t sessionId)
2503{
2504 tpPESession psessionEntry;
2505 psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
2506
2507 if (psessionEntry == NULL) {
2508 lim_log(pMac, LOGP,
2509 FL("Session Does not exist for given sessionID"));
2510 return;
2511 }
2512
2513 if (!LIM_IS_STA_ROLE(psessionEntry))
2514 return;
2515 /* First, de-activate Timer, if its already active */
2516 lim_cancel_dot11h_quiet(pMac, psessionEntry);
2517
2518 MTRACE(mac_trace
2519 (pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_QUIET_TIMER));
2520 if (TX_SUCCESS !=
2521 tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer)) {
2522 lim_log(pMac, LOGE,
2523 FL
2524 ("Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway..."));
2525 }
2526 /* Set the NEW timeout value, in ticks */
2527 if (TX_SUCCESS != tx_timer_change(&pMac->lim.limTimers.gLimQuietTimer,
2528 SYS_MS_TO_TICKS(psessionEntry->
2529 gLimSpecMgmt.
2530 quietTimeoutValue),
2531 0)) {
2532 lim_log(pMac, LOGE,
2533 FL
2534 ("Unable to change gLimQuietTimer! Will still attempt to re-activate anyway..."));
2535 }
2536
2537 pMac->lim.limTimers.gLimQuietTimer.sessionId = sessionId;
2538 if (TX_SUCCESS !=
2539 tx_timer_activate(&pMac->lim.limTimers.gLimQuietTimer)) {
2540 lim_log(pMac, LOGE,
2541 FL
2542 ("Unable to activate gLimQuietTimer! STA cannot honor Quiet BSS!"));
2543 lim_restore_pre_quiet_state(pMac, psessionEntry);
2544
2545 psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
2546 return;
2547 }
2548}
2549
2550/** ------------------------------------------------------------------------ **/
2551/**
2552 * keep track of the number of ANI peers associated in the BSS
2553 * For the first and last ANI peer, we have to update EDCA params as needed
2554 *
2555 * When the first ANI peer joins the BSS, we notify SCH
2556 * When the last ANI peer leaves the BSS, we notfiy SCH
2557 */
2558void
2559lim_util_count_sta_add(tpAniSirGlobal pMac,
2560 tpDphHashNode pSta, tpPESession psessionEntry)
2561{
2562
2563 if ((!pSta) || (!pSta->valid) || (pSta->fAniCount))
2564 return;
2565
2566 pSta->fAniCount = 1;
2567
2568 if (pMac->lim.gLimNumOfAniSTAs++ != 0)
2569 return;
2570
2571 /* get here only if this is the first ANI peer in the BSS */
2572 sch_edca_profile_update(pMac, psessionEntry);
2573}
2574
2575void
2576lim_util_count_sta_del(tpAniSirGlobal pMac,
2577 tpDphHashNode pSta, tpPESession psessionEntry)
2578{
2579
2580 if ((pSta == NULL) || (!pSta->fAniCount))
2581 return;
2582
2583 /* Only if sta is invalid and the validInDummyState bit is set to 1,
2584 * then go ahead and update the count and profiles. This ensures
2585 * that the "number of ani station" count is properly incremented/decremented.
2586 */
2587 if (pSta->valid == 1)
2588 return;
2589
2590 pSta->fAniCount = 0;
2591
2592 if (pMac->lim.gLimNumOfAniSTAs <= 0) {
2593 lim_log(pMac, LOGE,
2594 FL
2595 ("CountStaDel: ignoring Delete Req when AniPeer count is %d"),
2596 pMac->lim.gLimNumOfAniSTAs);
2597 return;
2598 }
2599
2600 pMac->lim.gLimNumOfAniSTAs--;
2601
2602 if (pMac->lim.gLimNumOfAniSTAs != 0)
2603 return;
2604
2605 /* get here only if this is the last ANI peer in the BSS */
2606 sch_edca_profile_update(pMac, psessionEntry);
2607}
2608
2609/**
2610 * lim_switch_channel_cback()
2611 *
2612 ***FUNCTION:
2613 * This is the callback function registered while requesting to switch channel
2614 * after AP indicates a channel switch for spectrum management (11h).
2615 *
2616 ***NOTE:
2617 * @param pMac Pointer to Global MAC structure
2618 * @param status Status of channel switch request
2619 * @param data User data
2620 * @param psessionEntry Session information
2621 * @return NONE
2622 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302623void lim_switch_channel_cback(tpAniSirGlobal pMac, QDF_STATUS status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002624 uint32_t *data, tpPESession psessionEntry)
2625{
2626 tSirMsgQ mmhMsg = { 0 };
2627 tSirSmeSwitchChannelInd *pSirSmeSwitchChInd;
2628
2629 psessionEntry->currentOperChannel = psessionEntry->currentReqChannel;
2630
2631 /* We need to restore pre-channelSwitch state on the STA */
2632 if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
2633 eSIR_SUCCESS) {
2634 lim_log(pMac, LOGP,
2635 FL
2636 ("Could not restore pre-channelSwitch (11h) state, resetting the system"));
2637 return;
2638 }
2639
2640 mmhMsg.type = eWNI_SME_SWITCH_CHL_IND;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302641 pSirSmeSwitchChInd = qdf_mem_malloc(sizeof(tSirSmeSwitchChannelInd));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002642 if (NULL == pSirSmeSwitchChInd) {
2643 lim_log(pMac, LOGP,
2644 FL("Failed to allocate buffer for buffer descriptor"));
2645 return;
2646 }
2647
2648 pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_IND;
2649 pSirSmeSwitchChInd->length = sizeof(tSirSmeSwitchChannelInd);
2650 pSirSmeSwitchChInd->newChannelId =
2651 psessionEntry->gLimChannelSwitch.primaryChannel;
2652 pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302653 qdf_mem_copy(pSirSmeSwitchChInd->bssid.bytes, psessionEntry->bssId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302654 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002655 mmhMsg.bodyptr = pSirSmeSwitchChInd;
2656 mmhMsg.bodyval = 0;
2657
2658 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
2659
2660 sys_process_mmh_msg(pMac, &mmhMsg);
2661}
2662
2663/**
2664 * lim_switch_primary_channel()
2665 *
2666 ***FUNCTION:
2667 * This function changes the current operating channel
2668 * and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL.
2669 *
2670 ***NOTE:
2671 * @param pMac Pointer to Global MAC structure
2672 * @param newChannel new chnannel ID
2673 * @return NONE
2674 */
2675void lim_switch_primary_channel(tpAniSirGlobal pMac, uint8_t newChannel,
2676 tpPESession psessionEntry)
2677{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678
2679 PELOG3(lim_log
2680 (pMac, LOG3,
2681 FL("lim_switch_primary_channel: old chnl %d --> new chnl %d "),
2682 psessionEntry->currentOperChannel, newChannel);
2683 )
2684 psessionEntry->currentReqChannel = newChannel;
2685 psessionEntry->limRFBand = lim_get_rf_band(newChannel);
2686
2687 psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
2688
2689 pMac->lim.gpchangeChannelCallback = lim_switch_channel_cback;
2690 pMac->lim.gpchangeChannelData = NULL;
2691
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002692 lim_send_switch_chnl_params(pMac, newChannel, 0, 0, CH_WIDTH_20MHZ,
2693 psessionEntry->maxTxPower,
2694 psessionEntry->peSessionId, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 return;
2696}
2697
2698/**
2699 * lim_switch_primary_secondary_channel()
2700 *
2701 ***FUNCTION:
2702 * This function changes the primary and secondary channel.
2703 * If 11h is enabled and user provides a "new channel ID"
2704 * that is different from the current operating channel,
2705 * then we must set this new channel in WNI_CFG_CURRENT_CHANNEL,
2706 * assign notify LIM of such change.
2707 *
2708 ***NOTE:
2709 * @param pMac Pointer to Global MAC structure
2710 * @param newChannel New chnannel ID (or current channel ID)
2711 * @param subband CB secondary info:
2712 * - eANI_CB_SECONDARY_NONE
2713 * - eANI_CB_SECONDARY_UP
2714 * - eANI_CB_SECONDARY_DOWN
2715 * @return NONE
2716 */
2717void lim_switch_primary_secondary_channel(tpAniSirGlobal pMac,
2718 tpPESession psessionEntry,
2719 uint8_t newChannel,
2720 uint8_t ch_center_freq_seg0,
2721 uint8_t ch_center_freq_seg1,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08002722 enum phy_ch_width ch_width)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002723{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002724 uint8_t subband = 0;
Deepak Dhamdhere641bf322016-01-06 15:19:03 -08002725
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002726 /* Assign the callback to resume TX once channel is changed. */
2727 psessionEntry->currentReqChannel = newChannel;
2728 psessionEntry->limRFBand = lim_get_rf_band(newChannel);
2729 psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
2730 pMac->lim.gpchangeChannelCallback = lim_switch_channel_cback;
2731 pMac->lim.gpchangeChannelData = NULL;
2732
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002733 lim_send_switch_chnl_params(pMac, newChannel, ch_center_freq_seg0,
2734 ch_center_freq_seg1, ch_width,
2735 psessionEntry->maxTxPower,
2736 psessionEntry->peSessionId,
2737 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002738
2739 /* Store the new primary and secondary channel in session entries if different */
2740 if (psessionEntry->currentOperChannel != newChannel) {
2741 lim_log(pMac, LOGW,
2742 FL("switch old chnl %d --> new chnl %d "),
2743 psessionEntry->currentOperChannel, newChannel);
2744 psessionEntry->currentOperChannel = newChannel;
2745 }
Kiran Kumar Lokere999e58c2016-01-07 02:18:39 -08002746 if (psessionEntry->htSecondaryChannelOffset !=
2747 psessionEntry->gLimChannelSwitch.sec_ch_offset) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002748 lim_log(pMac, LOGW,
2749 FL("switch old sec chnl %d --> new sec chnl %d "),
2750 psessionEntry->htSecondaryChannelOffset, subband);
Kiran Kumar Lokere999e58c2016-01-07 02:18:39 -08002751 psessionEntry->htSecondaryChannelOffset =
2752 psessionEntry->gLimChannelSwitch.sec_ch_offset;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002753 if (psessionEntry->htSecondaryChannelOffset ==
2754 PHY_SINGLE_CHANNEL_CENTERED) {
2755 psessionEntry->htSupportedChannelWidthSet =
2756 WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
2757 } else {
2758 psessionEntry->htSupportedChannelWidthSet =
2759 WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
2760 }
2761 psessionEntry->htRecommendedTxWidthSet =
2762 psessionEntry->htSupportedChannelWidthSet;
2763 }
2764
2765 return;
2766}
2767
2768/**
2769 * lim_active_scan_allowed()
2770 *
2771 ***FUNCTION:
2772 * Checks if active scans are permitted on the given channel
2773 *
2774 ***LOGIC:
2775 * The config variable SCAN_CONTROL_LIST contains pairs of (channelNum, activeScanAllowed)
2776 * Need to check if the channelNum matches, then depending on the corresponding
2777 * scan flag, return true (for activeScanAllowed==1) or false (otherwise).
2778 *
2779 ***ASSUMPTIONS:
2780 *
2781 ***NOTE:
2782 *
2783 * @param pMac Pointer to Global MAC structure
2784 * @param channelNum channel number
2785 * @return None
2786 */
2787
2788uint8_t lim_active_scan_allowed(tpAniSirGlobal pMac, uint8_t channelNum)
2789{
2790 uint32_t i;
2791 uint8_t channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN];
2792 uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
2793 if (wlan_cfg_get_str(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len)
2794 != eSIR_SUCCESS) {
2795 PELOGE(lim_log
2796 (pMac, LOGE, FL("Unable to get scan control list"));
2797 )
2798 return false;
2799 }
2800
2801 if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) {
2802 lim_log(pMac, LOGE, FL("Invalid scan control list length:%d"),
2803 len);
2804 return false;
2805 }
2806
2807 for (i = 0; (i + 1) < len; i += 2) {
2808 if (channelPair[i] == channelNum)
2809 return ((channelPair[i + 1] ==
2810 eSIR_ACTIVE_SCAN) ? true : false);
2811 }
2812 return false;
2813}
2814
2815/**
2816 * lim_get_ht_capability()
2817 *
2818 ***FUNCTION:
2819 * A utility function that returns the "current HT capability state" for the HT
2820 * capability of interest (as requested in the API)
2821 *
2822 ***LOGIC:
2823 * This routine will return with the "current" setting of a requested HT
2824 * capability. This state info could be retrieved from -
2825 * a) CFG (for static entries)
2826 * b) Run time info
2827 * - Dynamic state maintained by LIM
2828 * - Configured at radio init time by SME
2829 *
2830 *
2831 ***ASSUMPTIONS:
2832 * NA
2833 *
2834 ***NOTE:
2835 *
2836 * @param pMac Pointer to Global MAC structure
2837 * @param htCap The HT capability being queried
2838 * @return uint8_t The current state of the requested HT capability is returned in a
2839 * uint8_t variable
2840 */
2841
2842uint8_t lim_get_ht_capability(tpAniSirGlobal pMac,
2843 uint32_t htCap, tpPESession psessionEntry)
2844{
2845 uint8_t retVal = 0;
2846 uint8_t *ptr;
2847 uint32_t cfgValue;
2848 tSirMacHTCapabilityInfo macHTCapabilityInfo = { 0 };
2849 tSirMacExtendedHTCapabilityInfo macExtHTCapabilityInfo = { 0 };
2850 tSirMacTxBFCapabilityInfo macTxBFCapabilityInfo = { 0 };
2851 tSirMacASCapabilityInfo macASCapabilityInfo = { 0 };
2852
2853 /* */
2854 /* Determine which CFG to read from. Not ALL of the HT */
2855 /* related CFG's need to be read each time this API is */
2856 /* accessed */
2857 /* */
2858 if (htCap >= eHT_ANTENNA_SELECTION && htCap < eHT_SI_GRANULARITY) {
2859 /* Get Antenna Seletion HT Capabilities */
2860 if (eSIR_SUCCESS !=
2861 wlan_cfg_get_int(pMac, WNI_CFG_AS_CAP, &cfgValue))
2862 cfgValue = 0;
2863 ptr = (uint8_t *) &macASCapabilityInfo;
2864 *((uint8_t *) ptr) = (uint8_t) (cfgValue & 0xff);
2865 } else {
2866 if (htCap >= eHT_TX_BEAMFORMING &&
2867 htCap < eHT_ANTENNA_SELECTION) {
2868 /* Get Transmit Beam Forming HT Capabilities */
2869 if (eSIR_SUCCESS !=
2870 wlan_cfg_get_int(pMac, WNI_CFG_TX_BF_CAP, &cfgValue))
2871 cfgValue = 0;
2872 ptr = (uint8_t *) &macTxBFCapabilityInfo;
2873 *((uint32_t *) ptr) = (uint32_t) (cfgValue);
2874 } else {
2875 if (htCap >= eHT_PCO && htCap < eHT_TX_BEAMFORMING) {
2876 /* Get Extended HT Capabilities */
2877 if (eSIR_SUCCESS !=
2878 wlan_cfg_get_int(pMac,
2879 WNI_CFG_EXT_HT_CAP_INFO,
2880 &cfgValue))
2881 cfgValue = 0;
2882 ptr = (uint8_t *) &macExtHTCapabilityInfo;
2883 *((uint16_t *) ptr) =
2884 (uint16_t) (cfgValue & 0xffff);
2885 } else {
2886 if (htCap < eHT_MAX_RX_AMPDU_FACTOR) {
2887 /* Get HT Capabilities */
2888 if (eSIR_SUCCESS !=
2889 wlan_cfg_get_int(pMac,
2890 WNI_CFG_HT_CAP_INFO,
2891 &cfgValue))
2892 cfgValue = 0;
2893 ptr = (uint8_t *) &macHTCapabilityInfo;
2894 /* CR 265282 MDM SoftAP 2.4PL: SoftAP boot up crash in 2.4 PL builds while same WLAN SU is working on 2.1 PL */
2895 *ptr++ = cfgValue & 0xff;
2896 *ptr = (cfgValue >> 8) & 0xff;
2897 }
2898 }
2899 }
2900 }
2901
2902 switch (htCap) {
2903 case eHT_LSIG_TXOP_PROTECTION:
2904 retVal = pMac->lim.gHTLsigTXOPProtection;
2905 break;
2906
2907 case eHT_STBC_CONTROL_FRAME:
2908 retVal = (uint8_t) macHTCapabilityInfo.stbcControlFrame;
2909 break;
2910
2911 case eHT_PSMP:
2912 retVal = pMac->lim.gHTPSMPSupport;
2913 break;
2914
2915 case eHT_DSSS_CCK_MODE_40MHZ:
2916 retVal = pMac->lim.gHTDsssCckRate40MHzSupport;
2917 break;
2918
2919 case eHT_MAX_AMSDU_LENGTH:
2920 retVal = (uint8_t) macHTCapabilityInfo.maximalAMSDUsize;
2921 break;
2922
2923 case eHT_RX_STBC:
2924 retVal = (uint8_t) psessionEntry->htConfig.ht_rx_stbc;
2925 break;
2926
2927 case eHT_TX_STBC:
2928 retVal = (uint8_t) psessionEntry->htConfig.ht_tx_stbc;
2929 break;
2930
2931 case eHT_SHORT_GI_40MHZ:
2932 retVal = (uint8_t)
2933 (psessionEntry->htConfig.ht_sgi) ? macHTCapabilityInfo.
2934 shortGI40MHz : 0;
2935 break;
2936
2937 case eHT_SHORT_GI_20MHZ:
2938 retVal = (uint8_t)
2939 (psessionEntry->htConfig.ht_sgi) ? macHTCapabilityInfo.
2940 shortGI20MHz : 0;
2941 break;
2942
2943 case eHT_GREENFIELD:
2944 retVal = (uint8_t) macHTCapabilityInfo.greenField;
2945 break;
2946
2947 case eHT_MIMO_POWER_SAVE:
2948 retVal = (uint8_t) pMac->lim.gHTMIMOPSState;
2949 break;
2950
2951 case eHT_SUPPORTED_CHANNEL_WIDTH_SET:
2952 retVal = (uint8_t) psessionEntry->htSupportedChannelWidthSet;
2953 break;
2954
2955 case eHT_ADVANCED_CODING:
2956 retVal = (uint8_t) psessionEntry->htConfig.ht_rx_ldpc;
2957 break;
2958
2959 case eHT_MAX_RX_AMPDU_FACTOR:
2960 retVal = pMac->lim.gHTMaxRxAMpduFactor;
2961 break;
2962
2963 case eHT_MPDU_DENSITY:
2964 retVal = pMac->lim.gHTAMpduDensity;
2965 break;
2966
2967 case eHT_PCO:
2968 retVal = (uint8_t) macExtHTCapabilityInfo.pco;
2969 break;
2970
2971 case eHT_TRANSITION_TIME:
2972 retVal = (uint8_t) macExtHTCapabilityInfo.transitionTime;
2973 break;
2974
2975 case eHT_MCS_FEEDBACK:
2976 retVal = (uint8_t) macExtHTCapabilityInfo.mcsFeedback;
2977 break;
2978
2979 case eHT_TX_BEAMFORMING:
2980 retVal = (uint8_t) macTxBFCapabilityInfo.txBF;
2981 break;
2982
2983 case eHT_ANTENNA_SELECTION:
2984 retVal = (uint8_t) macASCapabilityInfo.antennaSelection;
2985 break;
2986
2987 case eHT_SI_GRANULARITY:
2988 retVal = pMac->lim.gHTServiceIntervalGranularity;
2989 break;
2990
2991 case eHT_CONTROLLED_ACCESS:
2992 retVal = pMac->lim.gHTControlledAccessOnly;
2993 break;
2994
2995 case eHT_RIFS_MODE:
2996 retVal = psessionEntry->beaconParams.fRIFSMode;
2997 break;
2998
2999 case eHT_RECOMMENDED_TX_WIDTH_SET:
3000 retVal = psessionEntry->htRecommendedTxWidthSet;
3001 break;
3002
3003 case eHT_EXTENSION_CHANNEL_OFFSET:
3004 retVal = psessionEntry->htSecondaryChannelOffset;
3005 break;
3006
3007 case eHT_OP_MODE:
3008 if (LIM_IS_AP_ROLE(psessionEntry))
3009 retVal = psessionEntry->htOperMode;
3010 else
3011 retVal = pMac->lim.gHTOperMode;
3012 break;
3013
3014 case eHT_BASIC_STBC_MCS:
3015 retVal = pMac->lim.gHTSTBCBasicMCS;
3016 break;
3017
3018 case eHT_DUAL_CTS_PROTECTION:
3019 retVal = pMac->lim.gHTDualCTSProtection;
3020 break;
3021
3022 case eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT:
3023 retVal =
3024 psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport;
3025 break;
3026
3027 case eHT_PCO_ACTIVE:
3028 retVal = pMac->lim.gHTPCOActive;
3029 break;
3030
3031 case eHT_PCO_PHASE:
3032 retVal = pMac->lim.gHTPCOPhase;
3033 break;
3034
3035 default:
3036 break;
3037 }
3038
3039 return retVal;
3040}
3041
3042/**
3043 * lim_enable_11a_protection() - updates protection params for enable 11a
3044 * protection request
3045 * @mac_ctx: pointer to Global MAC structure
3046 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
3047 * @bcn_prms: beacon parameters
3048 * @pe_session: pe session entry
3049 *
3050 * This fucntion updates protection params for enable 11a protection request
3051 *
3052 * @Return: void
3053 */
3054static void
3055lim_enable_11a_protection(tpAniSirGlobal mac_ctx,
3056 uint8_t overlap,
3057 tpUpdateBeaconParams bcn_prms,
3058 tpPESession pe_session)
3059{
3060 /*
3061 * If we are AP and HT capable, we need to set the HT OP mode
3062 * appropriately.
3063 */
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07003064 if (LIM_IS_AP_ROLE(pe_session) && (true == pe_session->htCapability)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065 if (overlap) {
3066 mac_ctx->lim.gLimOverlap11aParams.protectionEnabled =
3067 true;
3068 if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
3069 mac_ctx->lim.gHTOperMode)
3070 && (eSIR_HT_OP_MODE_MIXED !=
3071 mac_ctx->lim.gHTOperMode)) {
3072 mac_ctx->lim.gHTOperMode =
3073 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3074 pe_session->htOperMode =
3075 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3076 lim_enable_ht_rifs_protection(mac_ctx, true,
3077 overlap, bcn_prms, pe_session);
3078 lim_enable_ht_obss_protection(mac_ctx, true,
3079 overlap, bcn_prms, pe_session);
3080 }
3081 } else {
3082 pe_session->gLim11aParams.protectionEnabled = true;
3083 if (eSIR_HT_OP_MODE_MIXED != pe_session->htOperMode) {
3084 mac_ctx->lim.gHTOperMode =
3085 eSIR_HT_OP_MODE_MIXED;
3086 pe_session->htOperMode = eSIR_HT_OP_MODE_MIXED;
3087 lim_enable_ht_rifs_protection(mac_ctx, true,
3088 overlap, bcn_prms, pe_session);
3089 lim_enable_ht_obss_protection(mac_ctx, true,
3090 overlap, bcn_prms, pe_session);
3091 }
3092 }
3093 }
3094 /* This part is common for station as well. */
3095 if (false == pe_session->beaconParams.llaCoexist) {
3096 lim_log(mac_ctx, LOGW,
3097 FL(" => protection from 11A Enabled"));
3098 bcn_prms->llaCoexist = true;
3099 pe_session->beaconParams.llaCoexist = true;
3100 bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
3101 }
3102}
3103
3104/**
3105 * lim_disable_11a_protection() - updates protection params for disable 11a
3106 * protection request
3107 * @mac_ctx: pointer to Global MAC structure
3108 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
3109 * @bcn_prms: beacon parameters
3110 * @pe_session: pe session entry
3111 *
3112 * This fucntion updates protection params for disable 11a protection request
3113 *
3114 * @Return: void
3115 */
3116static void
3117lim_disable_11a_protection(tpAniSirGlobal mac_ctx,
3118 uint8_t overlap,
3119 tpUpdateBeaconParams bcn_prms,
3120 tpPESession pe_session)
3121{
3122 if (false == pe_session->beaconParams.llaCoexist)
3123 return;
3124
3125 /* for station role */
3126 if (!LIM_IS_AP_ROLE(pe_session)) {
3127 lim_log(mac_ctx, LOGW,
3128 FL("===> Protection from 11A Disabled"));
3129 bcn_prms->llaCoexist = false;
3130 pe_session->beaconParams.llaCoexist = false;
3131 bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
3132 return;
3133 }
3134 /*
3135 * for AP role.
3136 * we need to take care of HT OP mode change if needed.
3137 * We need to take care of Overlap cases.
3138 */
3139 if (overlap) {
3140 /* Overlap Legacy protection disabled. */
3141 mac_ctx->lim.gLimOverlap11aParams.protectionEnabled = false;
3142
3143 /*
3144 * We need to take care of HT OP mode iff we are HT AP.
3145 * OR no HT op-mode change is needed if any of the overlap
3146 * protection enabled.
3147 */
3148 if (!pe_session->htCapability ||
3149 (mac_ctx->lim.gLimOverlap11aParams.protectionEnabled
3150 || mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled
3151 || mac_ctx->lim.gLimOverlapNonGfParams.protectionEnabled))
3152 goto disable_11a_end;
3153
3154 /* Check if there is a need to change HT OP mode. */
3155 if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
3156 mac_ctx->lim.gHTOperMode) {
3157 lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
3158 bcn_prms, pe_session);
3159 lim_enable_ht_obss_protection(mac_ctx, false, overlap,
3160 bcn_prms, pe_session);
3161
3162 if (pe_session->gLimHt20Params.protectionEnabled)
3163 mac_ctx->lim.gHTOperMode =
3164 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
3165 else
3166 mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
3167 }
3168 } else {
3169 /* Disable protection from 11A stations. */
3170 pe_session->gLim11aParams.protectionEnabled = false;
3171 lim_enable_ht_obss_protection(mac_ctx, false, overlap,
3172 bcn_prms, pe_session);
3173
3174 /*
3175 * Check if any other non-HT protection enabled. Right now we
3176 * are in HT OP Mixed mode. Change HT op mode appropriately.
3177 */
3178
3179 /* Change HT OP mode to 01 if any overlap protection enabled */
3180 if (mac_ctx->lim.gLimOverlap11aParams.protectionEnabled
3181 || mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled
3182 || mac_ctx->lim.gLimOverlapNonGfParams.protectionEnabled) {
3183 mac_ctx->lim.gHTOperMode =
3184 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3185 pe_session->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3186 lim_enable_ht_rifs_protection(mac_ctx, true, overlap,
3187 bcn_prms, pe_session);
3188 } else if (pe_session->gLimHt20Params.protectionEnabled) {
3189 mac_ctx->lim.gHTOperMode =
3190 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
3191 pe_session->htOperMode =
3192 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
3193 lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
3194 bcn_prms, pe_session);
3195 } else {
3196 mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
3197 pe_session->htOperMode = eSIR_HT_OP_MODE_PURE;
3198 lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
3199 bcn_prms, pe_session);
3200 }
3201 }
3202
3203disable_11a_end:
3204 if (!mac_ctx->lim.gLimOverlap11aParams.protectionEnabled &&
3205 !pe_session->gLim11aParams.protectionEnabled) {
3206 lim_log(mac_ctx, LOGW,
3207 FL("===> Protection from 11A Disabled"));
3208 bcn_prms->llaCoexist = false;
3209 pe_session->beaconParams.llaCoexist = false;
3210 bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
3211 }
3212}
3213
3214/**
3215 * lim_update_11a_protection() - based on config setting enables\disables 11a
3216 * protection.
3217 * @mac_ctx: pointer to Global MAC structure
3218 * @enable: 1=> enable protection, 0=> disable protection.
3219 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
3220 * @bcn_prms: beacon parameters
3221 * @session: pe session entry
3222 *
3223 * This based on config setting enables\disables 11a protection.
3224 *
3225 * @Return: success of failure of operation
3226 */
3227tSirRetStatus
3228lim_update_11a_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
3229 uint8_t overlap, tpUpdateBeaconParams bcn_prms,
3230 tpPESession session)
3231{
3232 if (NULL == session) {
3233 lim_log(mac_ctx, LOGW, FL("session is NULL"));
3234 return eSIR_FAILURE;
3235 }
3236 /* overlapping protection configuration check. */
3237 if (!overlap) {
3238 /* normal protection config check */
3239 if ((LIM_IS_AP_ROLE(session)) &&
3240 (!session->cfgProtection.fromlla)) {
3241 /* protection disabled. */
3242 lim_log(mac_ctx, LOGW,
3243 FL("protection from 11a is disabled"));
3244 return eSIR_SUCCESS;
3245 }
3246 }
3247
3248 if (enable)
3249 lim_enable_11a_protection(mac_ctx, overlap, bcn_prms, session);
3250 else
3251 lim_disable_11a_protection(mac_ctx, overlap, bcn_prms, session);
3252
3253 return eSIR_SUCCESS;
3254}
3255
3256/**
3257 * lim_handle_enable11g_protection_enabled() - handle 11g protection enabled
3258 * @mac_ctx: pointer to Globale Mac structure
3259 * @beaconparams: pointer to tpUpdateBeaconParams
3260 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
3261 * @session_entry: pointer to tpPESession
3262 *
3263 * Function handles 11g protection enaled case
3264 *
3265 * Return: none
3266 */
3267static void
3268lim_handle_enable11g_protection_enabled(tpAniSirGlobal mac_ctx,
3269 tpUpdateBeaconParams beaconparams,
3270 uint8_t overlap, tpPESession session_entry)
3271{
3272 /*
3273 * If we are AP and HT capable, we need to set the HT OP mode
3274 * appropriately.
3275 */
3276 if (LIM_IS_AP_ROLE(session_entry) && overlap) {
3277 session_entry->gLimOlbcParams.protectionEnabled = true;
3278
3279 lim_log(mac_ctx, LOG1, FL("protection from olbc is enabled"));
3280
3281 if (true == session_entry->htCapability) {
3282 if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
3283 session_entry->htOperMode) &&
3284 (eSIR_HT_OP_MODE_MIXED !=
3285 session_entry->htOperMode)) {
3286 session_entry->htOperMode =
3287 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3288 }
3289 /*
3290 * CR-263021: OBSS bit is not switching back to 0 after
3291 * disabling the overlapping legacy BSS
3292 */
3293 /*
3294 * This fixes issue of OBSS bit not set after 11b, 11g
3295 * station leaves
3296 */
3297 lim_enable_ht_rifs_protection(mac_ctx, true,
3298 overlap, beaconparams, session_entry);
3299 /*
3300 * Not processing OBSS bit from other APs, as we are
3301 * already taking care of Protection from overlapping
3302 * BSS based on erp IE or useProtection bit
3303 */
3304 lim_enable_ht_obss_protection(mac_ctx, true,
3305 overlap, beaconparams, session_entry);
3306 }
3307 } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
3308 session_entry->gLim11bParams.protectionEnabled = true;
3309 lim_log(mac_ctx, LOG1, FL("protection from 11b is enabled"));
3310 if (true == session_entry->htCapability) {
3311 if (eSIR_HT_OP_MODE_MIXED !=
3312 session_entry->htOperMode) {
3313 session_entry->htOperMode =
3314 eSIR_HT_OP_MODE_MIXED;
3315 lim_enable_ht_rifs_protection(mac_ctx,
3316 true, overlap, beaconparams,
3317 session_entry);
3318 lim_enable_ht_obss_protection(mac_ctx,
3319 true, overlap, beaconparams,
3320 session_entry);
3321 }
3322 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003323 }
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07003324
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003325 /* This part is common for staiton as well. */
3326 if (false == session_entry->beaconParams.llbCoexist) {
3327 lim_log(mac_ctx, LOG1, FL("=> 11G Protection Enabled"));
3328 beaconparams->llbCoexist =
3329 session_entry->beaconParams.llbCoexist = true;
3330 beaconparams->paramChangeBitmap |=
3331 PARAM_llBCOEXIST_CHANGED;
3332 }
3333}
3334
3335/**
3336 * lim_handle_11g_protection_for_11bcoexist() - 11g protection for 11b co-ex
3337 * @mac_ctx: pointer to Globale Mac structure
3338 * @beaconparams: pointer to tpUpdateBeaconParams
3339 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
3340 * @session_entry: pointer to tpPESession
3341 *
3342 * Function handles 11g protection for 11b co-exist
3343 *
3344 * Return: none
3345 */
3346static void
3347lim_handle_11g_protection_for_11bcoexist(tpAniSirGlobal mac_ctx,
3348 tpUpdateBeaconParams beaconparams,
3349 uint8_t overlap, tpPESession session_entry)
3350{
3351 /*
3352 * For AP role:
3353 * we need to take care of HT OP mode change if needed.
3354 * We need to take care of Overlap cases.
3355 */
3356 if (LIM_IS_AP_ROLE(session_entry) && overlap) {
3357 /* Overlap Legacy protection disabled. */
3358 session_entry->gLimOlbcParams.protectionEnabled = false;
3359
3360 /* We need to take care of HT OP mode if we are HT AP. */
3361 if (session_entry->htCapability) {
3362 /*
3363 * no HT op mode change if any of the overlap
3364 * protection enabled.
3365 */
3366 if (!(session_entry->gLimOverlap11gParams.
3367 protectionEnabled ||
3368 session_entry->gLimOverlapHt20Params.
3369 protectionEnabled ||
3370 session_entry->gLimOverlapNonGfParams.
3371 protectionEnabled) &&
3372 /*
3373 * Check if there is a need to change HT
3374 * OP mode.
3375 */
3376 (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
3377 session_entry->htOperMode)) {
3378 lim_enable_ht_rifs_protection(mac_ctx, false,
3379 overlap, beaconparams, session_entry);
3380 lim_enable_ht_obss_protection(mac_ctx, false,
3381 overlap, beaconparams, session_entry);
3382 if (session_entry->gLimHt20Params.
3383 protectionEnabled) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303384 if (eHT_CHANNEL_WIDTH_20MHZ ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003385 session_entry->htSupportedChannelWidthSet)
3386 session_entry->htOperMode =
3387 eSIR_HT_OP_MODE_PURE;
3388 else
3389 session_entry->htOperMode =
3390 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
3391 } else
3392 session_entry->htOperMode =
3393 eSIR_HT_OP_MODE_PURE;
3394 }
3395 }
3396 } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
3397 /* Disable protection from 11B stations. */
3398 session_entry->gLim11bParams.protectionEnabled = false;
3399 lim_log(mac_ctx, LOG1, FL("===> 11B Protection Disabled"));
3400 /* Check if any other non-HT protection enabled. */
3401 if (!session_entry->gLim11gParams.protectionEnabled) {
3402 /* Right now we are in HT OP Mixed mode. */
3403 /* Change HT op mode appropriately. */
3404 lim_enable_ht_obss_protection(mac_ctx, false, overlap,
3405 beaconparams, session_entry);
3406 /*
3407 * Change HT OP mode to 01 if any overlap protection
3408 * enabled
3409 */
3410 if (session_entry->gLimOlbcParams.protectionEnabled ||
3411 session_entry->gLimOverlap11gParams.
3412 protectionEnabled ||
3413 session_entry->gLimOverlapHt20Params.
3414 protectionEnabled ||
3415 session_entry->gLimOverlapNonGfParams.
3416 protectionEnabled) {
3417 session_entry->htOperMode =
3418 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3419 lim_log(mac_ctx, LOG1,
3420 FL("===> 11G Protection Disabled"));
3421 lim_enable_ht_rifs_protection(mac_ctx, true,
3422 overlap, beaconparams,
3423 session_entry);
3424 } else if (session_entry->gLimHt20Params.
3425 protectionEnabled) {
3426 /* Commenting because of CR 258588 WFA cert */
3427 /* session_entry->htOperMode =
3428 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; */
3429 session_entry->htOperMode =
3430 eSIR_HT_OP_MODE_PURE;
3431 lim_log(mac_ctx, LOG1,
3432 FL("===> 11G Protection Disabled"));
3433 lim_enable_ht_rifs_protection(mac_ctx, false,
3434 overlap, beaconparams,
3435 session_entry);
3436 } else {
3437 session_entry->htOperMode =
3438 eSIR_HT_OP_MODE_PURE;
3439 lim_enable_ht_rifs_protection(mac_ctx, false,
3440 overlap, beaconparams,
3441 session_entry);
3442 }
3443 }
3444 }
3445 if (LIM_IS_AP_ROLE(session_entry)) {
3446 if (!session_entry->gLimOlbcParams.protectionEnabled &&
3447 !session_entry->gLim11bParams.protectionEnabled) {
3448 lim_log(mac_ctx, LOG1,
3449 FL("===> 11G Protection Disabled"));
3450 beaconparams->llbCoexist =
3451 session_entry->beaconParams.llbCoexist =
3452 false;
3453 beaconparams->paramChangeBitmap |=
3454 PARAM_llBCOEXIST_CHANGED;
3455 }
3456 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003457 /* For station role */
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07003458 if (!LIM_IS_AP_ROLE(session_entry)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 lim_log(mac_ctx, LOG1, FL("===> 11G Protection Disabled"));
3460 beaconparams->llbCoexist =
3461 session_entry->beaconParams.llbCoexist = false;
3462 beaconparams->paramChangeBitmap |=
3463 PARAM_llBCOEXIST_CHANGED;
3464 }
3465}
3466
3467/**
3468 * lim_enable11g_protection() - Function to enable 11g protection
3469 * @mac_ctx: pointer to Global Mac structure
3470 * @enable: 1=> enable protection, 0=> disable protection.
3471 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
3472 * @beaconparams: pointer to tpUpdateBeaconParams
3473 * @session_entry: pointer to tpPESession
3474 *
3475 * based on config setting enables\disables 11g protection.
3476 *
3477 * Return: Success - eSIR_SUCCESS - Success, Error number - Failure
3478 */
3479tSirRetStatus
3480lim_enable11g_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
3481 uint8_t overlap, tpUpdateBeaconParams beaconparams,
3482 tpPESession session_entry)
3483{
3484
3485 /* overlapping protection configuration check. */
3486 if (!overlap) {
3487 /* normal protection config check */
3488 if ((LIM_IS_AP_ROLE(session_entry)) &&
3489 !session_entry->cfgProtection.fromllb) {
3490 /* protection disabled. */
3491 lim_log(mac_ctx, LOG1,
3492 FL("protection from 11b is disabled"));
3493 return eSIR_SUCCESS;
3494 } else if (!LIM_IS_AP_ROLE(session_entry)) {
3495 if (!mac_ctx->lim.cfgProtection.fromllb) {
3496 /* protection disabled. */
3497 lim_log(mac_ctx, LOG1,
3498 FL("protection from 11b is disabled"));
3499 return eSIR_SUCCESS;
3500 }
3501 }
3502 }
3503
3504 if (enable) {
3505 lim_handle_enable11g_protection_enabled(mac_ctx, beaconparams,
3506 overlap, session_entry);
3507 } else if (true == session_entry->beaconParams.llbCoexist) {
3508 lim_handle_11g_protection_for_11bcoexist(mac_ctx, beaconparams,
3509 overlap, session_entry);
3510 }
3511 return eSIR_SUCCESS;
3512}
3513
3514/** -------------------------------------------------------------
3515 \fn lim_enable_ht_protection_from11g
3516 \brief based on cofig enables\disables protection from 11g.
3517 \param uint8_t enable : 1=> enable protection, 0=> disable protection.
3518 \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
3519 \param tpUpdateBeaconParams pBeaconParams
3520 \return None
3521 -------------------------------------------------------------*/
3522tSirRetStatus
3523lim_enable_ht_protection_from11g(tpAniSirGlobal pMac, uint8_t enable,
3524 uint8_t overlap,
3525 tpUpdateBeaconParams pBeaconParams,
3526 tpPESession psessionEntry)
3527{
3528 if (!psessionEntry->htCapability)
3529 return eSIR_SUCCESS; /* protection from 11g is only for HT stations. */
3530
3531 /* overlapping protection configuration check. */
3532 if (overlap) {
3533 if ((LIM_IS_AP_ROLE(psessionEntry))
3534 && (!psessionEntry->cfgProtection.overlapFromllg)) {
3535 /* protection disabled. */
3536 PELOG3(lim_log
3537 (pMac, LOG3,
3538 FL("overlap protection from 11g is disabled"));
3539 );
3540 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003541 }
3542 } else {
3543 /* normal protection config check */
3544 if (LIM_IS_AP_ROLE(psessionEntry) &&
3545 !psessionEntry->cfgProtection.fromllg) {
3546 /* protection disabled. */
3547 PELOG3(lim_log
3548 (pMac, LOG3,
3549 FL("protection from 11g is disabled"));
3550 )
3551 return eSIR_SUCCESS;
3552 } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
3553 if (!pMac->lim.cfgProtection.fromllg) {
3554 /* protection disabled. */
3555 PELOG3(lim_log
3556 (pMac, LOG3,
3557 FL("protection from 11g is disabled"));
3558 )
3559 return eSIR_SUCCESS;
3560 }
3561 }
3562 }
3563 if (enable) {
3564 /* If we are AP and HT capable, we need to set the HT OP mode */
3565 /* appropriately. */
3566
3567 if (LIM_IS_AP_ROLE(psessionEntry)) {
3568 if (overlap) {
3569 psessionEntry->gLimOverlap11gParams.
3570 protectionEnabled = true;
3571 /* 11g exists in overlap BSS. */
3572 /* need not to change the operating mode to overlap_legacy */
3573 /* if higher or same protection operating mode is enabled right now. */
3574 if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
3575 psessionEntry->htOperMode)
3576 && (eSIR_HT_OP_MODE_MIXED !=
3577 psessionEntry->htOperMode)) {
3578 psessionEntry->htOperMode =
3579 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3580 }
3581 lim_enable_ht_rifs_protection(pMac, true, overlap,
3582 pBeaconParams,
3583 psessionEntry);
3584 lim_enable_ht_obss_protection(pMac, true, overlap,
3585 pBeaconParams,
3586 psessionEntry);
3587 } else {
3588 /* 11g is associated to an AP operating in 11n mode. */
3589 /* Change the HT operating mode to 'mixed mode'. */
3590 psessionEntry->gLim11gParams.protectionEnabled =
3591 true;
3592 if (eSIR_HT_OP_MODE_MIXED !=
3593 psessionEntry->htOperMode) {
3594 psessionEntry->htOperMode =
3595 eSIR_HT_OP_MODE_MIXED;
3596 lim_enable_ht_rifs_protection(pMac, true,
3597 overlap,
3598 pBeaconParams,
3599 psessionEntry);
3600 lim_enable_ht_obss_protection(pMac, true,
3601 overlap,
3602 pBeaconParams,
3603 psessionEntry);
3604 }
3605 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003606 }
3607 /* This part is common for staiton as well. */
3608 if (false == psessionEntry->beaconParams.llgCoexist) {
3609 pBeaconParams->llgCoexist =
3610 psessionEntry->beaconParams.llgCoexist = true;
3611 pBeaconParams->paramChangeBitmap |=
3612 PARAM_llGCOEXIST_CHANGED;
3613 } else if (true ==
3614 psessionEntry->gLimOverlap11gParams.
3615 protectionEnabled) {
3616 /* As operating mode changed after G station assoc some way to update beacon */
3617 /* This addresses the issue of mode not changing to - 11 in beacon when OBSS overlap is enabled */
3618 /* pMac->sch.schObject.fBeaconChanged = 1; */
3619 pBeaconParams->paramChangeBitmap |=
3620 PARAM_llGCOEXIST_CHANGED;
3621 }
3622 } else if (true == psessionEntry->beaconParams.llgCoexist) {
3623 /* for AP role. */
3624 /* we need to take care of HT OP mode change if needed. */
3625 /* We need to take care of Overlap cases. */
3626
3627 if (LIM_IS_AP_ROLE(psessionEntry)) {
3628 if (overlap) {
3629 /* Overlap Legacy protection disabled. */
3630 if (psessionEntry->gLim11gParams.numSta == 0)
3631 psessionEntry->gLimOverlap11gParams.
3632 protectionEnabled = false;
3633
3634 /* no HT op mode change if any of the overlap protection enabled. */
3635 if (!
3636 (psessionEntry->gLimOlbcParams.
3637 protectionEnabled
3638 || psessionEntry->gLimOverlapHt20Params.
3639 protectionEnabled
3640 || psessionEntry->gLimOverlapNonGfParams.
3641 protectionEnabled)) {
3642 /* Check if there is a need to change HT OP mode. */
3643 if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
3644 psessionEntry->htOperMode) {
3645 lim_enable_ht_rifs_protection(pMac,
3646 false,
3647 overlap,
3648 pBeaconParams,
3649 psessionEntry);
3650 lim_enable_ht_obss_protection(pMac,
3651 false,
3652 overlap,
3653 pBeaconParams,
3654 psessionEntry);
3655
3656 if (psessionEntry->gLimHt20Params.protectionEnabled) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303657 if (eHT_CHANNEL_WIDTH_20MHZ ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003658 psessionEntry->htSupportedChannelWidthSet)
3659 psessionEntry->htOperMode =
3660 eSIR_HT_OP_MODE_PURE;
3661 else
3662 psessionEntry->htOperMode =
3663 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
3664 } else
3665 psessionEntry->htOperMode =
3666 eSIR_HT_OP_MODE_PURE;
3667 }
3668 }
3669 } else {
3670 /* Disable protection from 11G stations. */
3671 psessionEntry->gLim11gParams.protectionEnabled =
3672 false;
3673 /* Check if any other non-HT protection enabled. */
3674 if (!psessionEntry->gLim11bParams.
3675 protectionEnabled) {
3676
3677 /* Right now we are in HT OP Mixed mode. */
3678 /* Change HT op mode appropriately. */
3679 lim_enable_ht_obss_protection(pMac, false,
3680 overlap,
3681 pBeaconParams,
3682 psessionEntry);
3683
3684 /* Change HT OP mode to 01 if any overlap protection enabled */
3685 if (psessionEntry->gLimOlbcParams.
3686 protectionEnabled
3687 || psessionEntry->
3688 gLimOverlap11gParams.
3689 protectionEnabled
3690 || psessionEntry->
3691 gLimOverlapHt20Params.
3692 protectionEnabled
3693 || psessionEntry->
3694 gLimOverlapNonGfParams.
3695 protectionEnabled) {
3696 psessionEntry->htOperMode =
3697 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3698 lim_enable_ht_rifs_protection(pMac,
3699 true,
3700 overlap,
3701 pBeaconParams,
3702 psessionEntry);
3703 } else if (psessionEntry->
3704 gLimHt20Params.
3705 protectionEnabled) {
3706 /* Commenting because of CR 258588 WFA cert */
3707 /* psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; */
3708 psessionEntry->htOperMode =
3709 eSIR_HT_OP_MODE_PURE;
3710 lim_enable_ht_rifs_protection(pMac,
3711 false,
3712 overlap,
3713 pBeaconParams,
3714 psessionEntry);
3715 } else {
3716 psessionEntry->htOperMode =
3717 eSIR_HT_OP_MODE_PURE;
3718 lim_enable_ht_rifs_protection(pMac,
3719 false,
3720 overlap,
3721 pBeaconParams,
3722 psessionEntry);
3723 }
3724 }
3725 }
3726 if (!psessionEntry->gLimOverlap11gParams.
3727 protectionEnabled
3728 && !psessionEntry->gLim11gParams.
3729 protectionEnabled) {
3730 PELOG1(lim_log
3731 (pMac, LOG1,
3732 FL
3733 ("===> Protection from 11G Disabled"));
3734 )
3735 pBeaconParams->llgCoexist =
3736 psessionEntry->beaconParams.llgCoexist =
3737 false;
3738 pBeaconParams->paramChangeBitmap |=
3739 PARAM_llGCOEXIST_CHANGED;
3740 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741 }
3742 /* for station role */
3743 else {
3744 PELOG1(lim_log
3745 (pMac, LOG1,
3746 FL("===> Protection from 11G Disabled"));
3747 )
3748 pBeaconParams->llgCoexist =
3749 psessionEntry->beaconParams.llgCoexist = false;
3750 pBeaconParams->paramChangeBitmap |=
3751 PARAM_llGCOEXIST_CHANGED;
3752 }
3753 }
3754 return eSIR_SUCCESS;
3755}
3756
3757/* FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. */
3758/* This check will be done at the caller. */
3759
3760/** -------------------------------------------------------------
3761 \fn limEnableHtObssProtection
3762 \brief based on cofig enables\disables obss protection.
3763 \param uint8_t enable : 1=> enable protection, 0=> disable protection.
3764 \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
3765 \param tpUpdateBeaconParams pBeaconParams
3766 \return None
3767 -------------------------------------------------------------*/
3768tSirRetStatus
3769lim_enable_ht_obss_protection(tpAniSirGlobal pMac, uint8_t enable,
3770 uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
3771 tpPESession psessionEntry)
3772{
3773
3774 if (!psessionEntry->htCapability)
3775 return eSIR_SUCCESS; /* this protection is only for HT stations. */
3776
3777 /* overlapping protection configuration check. */
3778 if (overlap) {
3779 /* overlapping protection configuration check. */
3780 } else {
3781 /* normal protection config check */
3782 if ((LIM_IS_AP_ROLE(psessionEntry)) &&
3783 !psessionEntry->cfgProtection.obss) { /* ToDo Update this field */
3784 /* protection disabled. */
3785 PELOG1(lim_log
3786 (pMac, LOG1,
3787 FL("protection from Obss is disabled"));
3788 )
3789 return eSIR_SUCCESS;
3790 } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
3791 if (!pMac->lim.cfgProtection.obss) { /* ToDo Update this field */
3792 /* protection disabled. */
3793 PELOG1(lim_log
3794 (pMac, LOG1,
3795 FL("protection from Obss is disabled"));
3796 )
3797 return eSIR_SUCCESS;
3798 }
3799 }
3800 }
3801
3802 if (LIM_IS_AP_ROLE(psessionEntry)) {
3803 if ((enable)
3804 && (false == psessionEntry->beaconParams.gHTObssMode)) {
3805 PELOG1(lim_log
3806 (pMac, LOG1, FL("=>obss protection enabled"));
3807 )
3808 psessionEntry->beaconParams.gHTObssMode = true;
3809 pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; /* UPDATE AN ENUM FOR OBSS MODE <todo> */
3810
3811 } else if (!enable
3812 && (true ==
3813 psessionEntry->beaconParams.gHTObssMode)) {
3814 PELOG1(lim_log
3815 (pMac, LOG1,
3816 FL("===> obss Protection disabled"));
3817 )
3818 psessionEntry->beaconParams.gHTObssMode = false;
3819 pBeaconParams->paramChangeBitmap |=
3820 PARAM_OBSS_MODE_CHANGED;
3821
3822 }
3823/* CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS */
3824 if (!enable && !overlap) {
3825 psessionEntry->gLimOverlap11gParams.protectionEnabled =
3826 false;
3827 }
3828 } else {
3829 if ((enable)
3830 && (false == psessionEntry->beaconParams.gHTObssMode)) {
3831 PELOG1(lim_log
3832 (pMac, LOG1, FL("=>obss protection enabled"));
3833 )
3834 psessionEntry->beaconParams.gHTObssMode = true;
3835 pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; /* UPDATE AN ENUM FOR OBSS MODE <todo> */
3836
3837 } else if (!enable
3838 && (true ==
3839 psessionEntry->beaconParams.gHTObssMode)) {
3840
3841 PELOG1(lim_log
3842 (pMac, LOG1,
3843 FL("===> obss Protection disabled"));
3844 )
3845 psessionEntry->beaconParams.gHTObssMode = false;
3846 pBeaconParams->paramChangeBitmap |=
3847 PARAM_OBSS_MODE_CHANGED;
3848
3849 }
3850 }
3851 return eSIR_SUCCESS;
3852}
3853
3854/**
3855 * lim_handle_ht20protection_enabled() - Handle ht20 protection enabled
3856 * @mac_ctx: pointer to Gloal Mac Structure
3857 * @overlap: variable for overlap detection
3858 * @beaconparams: pointer to tpUpdateBeaconParams
3859 * @session_entry: pointer to tpPESession
3860 *
3861 * Function handles ht20 protection enabled
3862 *
3863 * Return: none
3864 */
3865static void lim_handle_ht20protection_enabled(tpAniSirGlobal mac_ctx,
3866 uint8_t overlap, tpUpdateBeaconParams beaconparams,
3867 tpPESession session_entry)
3868{
3869 /*
3870 * If we are AP and HT capable, we need to set the HT OP mode
3871 * appropriately.
3872 */
3873 if (LIM_IS_AP_ROLE(session_entry) && overlap) {
3874 session_entry->gLimOverlapHt20Params.protectionEnabled = true;
3875 if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
3876 session_entry->htOperMode) &&
3877 (eSIR_HT_OP_MODE_MIXED !=
3878 session_entry->htOperMode)) {
3879 session_entry->htOperMode =
3880 eSIR_HT_OP_MODE_OVERLAP_LEGACY;
3881 lim_enable_ht_rifs_protection(mac_ctx, true,
3882 overlap, beaconparams, session_entry);
3883 }
3884 } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
3885 session_entry->gLimHt20Params.protectionEnabled = true;
3886 if (eSIR_HT_OP_MODE_PURE == session_entry->htOperMode) {
Naveen Rawate702e9b2015-11-17 11:50:40 -08003887 if (session_entry->htSupportedChannelWidthSet !=
3888 eHT_CHANNEL_WIDTH_20MHZ)
3889 session_entry->htOperMode =
3890 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003891 lim_enable_ht_rifs_protection(mac_ctx, false,
3892 overlap, beaconparams, session_entry);
3893 lim_enable_ht_obss_protection(mac_ctx, false,
3894 overlap, beaconparams, session_entry);
3895 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003896 }
3897 /* This part is common for staiton as well. */
3898 if (false == session_entry->beaconParams.ht20Coexist) {
3899 lim_log(mac_ctx, LOG1,
3900 FL("=> Protection from HT20 Enabled"));
3901 beaconparams->ht20MhzCoexist =
3902 session_entry->beaconParams.ht20Coexist = true;
3903 beaconparams->paramChangeBitmap |=
3904 PARAM_HT20MHZCOEXIST_CHANGED;
3905 }
3906}
3907
3908/**
3909 * lim_handle_ht20coexist_ht20protection() - ht20 protection for ht20 coexist
3910 * @mac_ctx: pointer to Gloal Mac Structure
3911 * @beaconparams: pointer to tpUpdateBeaconParams
3912 * @session_entry: pointer to tpPESession
3913 * @overlap: variable for overlap detection
3914 *
3915 * Function handles ht20 protection for ht20 coexist
3916 *
3917 * Return: none
3918 */
3919static void lim_handle_ht20coexist_ht20protection(tpAniSirGlobal mac_ctx,
3920 tpUpdateBeaconParams beaconparams,
3921 tpPESession session_entry, uint8_t overlap)
3922{
3923 /*
3924 * For AP role:
3925 * we need to take care of HT OP mode change if needed.
3926 * We need to take care of Overlap cases.
3927 */
3928 if (LIM_IS_AP_ROLE(session_entry) && overlap) {
3929 /* Overlap Legacy protection disabled. */
3930 session_entry->gLimOverlapHt20Params.protectionEnabled =
3931 false;
3932 /*
3933 * no HT op mode change if any of the overlap
3934 * protection enabled.
3935 */
3936 if (!(session_entry->gLimOlbcParams.protectionEnabled ||
3937 session_entry->gLimOverlap11gParams.protectionEnabled ||
3938 session_entry->gLimOverlapHt20Params.protectionEnabled
3939 || session_entry->gLimOverlapNonGfParams.
3940 protectionEnabled) &&
3941 /*
3942 * Check if there is a need to change HT
3943 * OP mode.
3944 */
3945 (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
3946 session_entry->htOperMode)) {
3947 if (session_entry->gLimHt20Params.
3948 protectionEnabled) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303949 if (eHT_CHANNEL_WIDTH_20MHZ ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003950 session_entry->htSupportedChannelWidthSet)
3951 session_entry->htOperMode =
3952 eSIR_HT_OP_MODE_PURE;
3953 else
3954 session_entry->htOperMode =
3955 eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
3956
3957 lim_enable_ht_rifs_protection(mac_ctx,
3958 false, overlap, beaconparams,
3959 session_entry);
3960 lim_enable_ht_obss_protection(mac_ctx,
3961 false, overlap, beaconparams,
3962 session_entry);
3963 } else {
3964 session_entry->htOperMode =
3965 eSIR_HT_OP_MODE_PURE;
3966 }
3967 }
3968 } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
3969 /* Disable protection from 11G stations. */
3970 session_entry->gLimHt20Params.protectionEnabled = false;
3971 /* Change HT op mode appropriately. */
3972 if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
3973 session_entry->htOperMode) {
3974 session_entry->htOperMode =
3975 eSIR_HT_OP_MODE_PURE;
3976 lim_enable_ht_rifs_protection(mac_ctx, false,
3977 overlap, beaconparams, session_entry);
3978 lim_enable_ht_obss_protection(mac_ctx, false,
3979 overlap, beaconparams, session_entry);
3980 }
3981 }
3982 if (LIM_IS_AP_ROLE(session_entry)) {
3983 lim_log(mac_ctx, LOG1,
3984 FL("===> Protection from HT 20 Disabled"));
3985 beaconparams->ht20MhzCoexist =
3986 session_entry->beaconParams.ht20Coexist = false;
3987 beaconparams->paramChangeBitmap |=
3988 PARAM_HT20MHZCOEXIST_CHANGED;
3989 }
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07003990 if (!LIM_IS_AP_ROLE(session_entry)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003991 /* For station role */
3992 lim_log(mac_ctx, LOG1,
3993 FL("===> Protection from HT20 Disabled"));
3994 beaconparams->ht20MhzCoexist =
3995 session_entry->beaconParams.ht20Coexist = false;
3996 beaconparams->paramChangeBitmap |=
3997 PARAM_HT20MHZCOEXIST_CHANGED;
3998 }
3999}
4000
4001/**
4002 * lim_enable_ht20_protection() - Function to enable ht20 protection
4003 * @mac_ctx: pointer to Global Mac structure
4004 * @enable: 1=> enable protection, 0=> disable protection.
4005 * @overlap: 1=> called from overlap context, 0 => called from assoc context.
4006 * @beaconparams: pointer to tpUpdateBeaconParams
4007 * @session_entry: pointer to tpPESession
4008 *
4009 * based on cofig enables\disables protection from Ht20
4010 *
4011 * Return: 0 - success
4012 */
4013tSirRetStatus lim_enable_ht20_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
4014 uint8_t overlap, tpUpdateBeaconParams beaconparams,
4015 tpPESession session_entry)
4016{
4017 /* This protection is only for HT stations. */
4018 if (!session_entry->htCapability)
4019 return eSIR_SUCCESS;
4020
4021 /* overlapping protection configuration check. */
4022 if (!overlap) {
4023 /* normal protection config check */
4024 if ((LIM_IS_AP_ROLE(session_entry)) &&
4025 !session_entry->cfgProtection.ht20) {
4026 /* protection disabled. */
4027 lim_log(mac_ctx, LOG3,
4028 FL("protection from HT20 is disabled"));
4029 return eSIR_SUCCESS;
4030 } else if (!LIM_IS_AP_ROLE(session_entry)) {
4031 if (!mac_ctx->lim.cfgProtection.ht20) {
4032 /* protection disabled. */
4033 lim_log(mac_ctx, LOG3,
4034 FL("protection from HT20 is disabled"));
4035 return eSIR_SUCCESS;
4036 }
4037 }
4038 }
4039
4040 if (enable)
4041 lim_handle_ht20protection_enabled(mac_ctx, overlap,
4042 beaconparams, session_entry);
4043 else if (true == session_entry->beaconParams.ht20Coexist)
4044 lim_handle_ht20coexist_ht20protection(mac_ctx, beaconparams,
4045 session_entry, overlap);
4046
4047 return eSIR_SUCCESS;
4048}
4049
4050/** -------------------------------------------------------------
4051 \fn lim_enable_ht_non_gf_protection
4052 \brief based on cofig enables\disables protection from NonGf.
4053 \param uint8_t enable : 1=> enable protection, 0=> disable protection.
4054 \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
4055 \param tpUpdateBeaconParams pBeaconParams
4056 \return None
4057 -------------------------------------------------------------*/
4058tSirRetStatus
4059lim_enable_ht_non_gf_protection(tpAniSirGlobal pMac, uint8_t enable,
4060 uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
4061 tpPESession psessionEntry)
4062{
4063 if (!psessionEntry->htCapability)
4064 return eSIR_SUCCESS; /* this protection is only for HT stations. */
4065
4066 /* overlapping protection configuration check. */
4067 if (overlap) {
4068 } else {
4069 /* normal protection config check */
4070 if (LIM_IS_AP_ROLE(psessionEntry) &&
4071 !psessionEntry->cfgProtection.nonGf) {
4072 /* protection disabled. */
4073 PELOG3(lim_log
4074 (pMac, LOG3,
4075 FL("protection from NonGf is disabled"));
4076 )
4077 return eSIR_SUCCESS;
4078 } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
4079 /* normal protection config check */
4080 if (!pMac->lim.cfgProtection.nonGf) {
4081 /* protection disabled. */
4082 PELOG3(lim_log
4083 (pMac, LOG3,
4084 FL
4085 ("protection from NonGf is disabled"));
4086 )
4087 return eSIR_SUCCESS;
4088 }
4089 }
4090 }
4091 if (LIM_IS_AP_ROLE(psessionEntry)) {
4092 if ((enable)
4093 && (false == psessionEntry->beaconParams.llnNonGFCoexist)) {
4094 PELOG1(lim_log
4095 (pMac, LOG1,
4096 FL(" => Protection from non GF Enabled"));
4097 )
4098 pBeaconParams->llnNonGFCoexist =
4099 psessionEntry->beaconParams.llnNonGFCoexist = true;
4100 pBeaconParams->paramChangeBitmap |=
4101 PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
4102 } else if (!enable
4103 && (true ==
4104 psessionEntry->beaconParams.llnNonGFCoexist)) {
4105 PELOG1(lim_log
4106 (pMac, LOG1,
4107 FL("===> Protection from Non GF Disabled"));
4108 )
4109 pBeaconParams->llnNonGFCoexist =
4110 psessionEntry->beaconParams.llnNonGFCoexist = false;
4111 pBeaconParams->paramChangeBitmap |=
4112 PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
4113 }
4114 } else {
4115 if ((enable)
4116 && (false == psessionEntry->beaconParams.llnNonGFCoexist)) {
4117 PELOG1(lim_log
4118 (pMac, LOG1,
4119 FL(" => Protection from non GF Enabled"));
4120 )
4121 pBeaconParams->llnNonGFCoexist =
4122 psessionEntry->beaconParams.llnNonGFCoexist = true;
4123 pBeaconParams->paramChangeBitmap |=
4124 PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
4125 } else if (!enable
4126 && (true ==
4127 psessionEntry->beaconParams.llnNonGFCoexist)) {
4128 PELOG1(lim_log
4129 (pMac, LOG1,
4130 FL("===> Protection from Non GF Disabled"));
4131 )
4132 pBeaconParams->llnNonGFCoexist =
4133 psessionEntry->beaconParams.llnNonGFCoexist = false;
4134 pBeaconParams->paramChangeBitmap |=
4135 PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
4136 }
4137 }
4138
4139 return eSIR_SUCCESS;
4140}
4141
4142/** -------------------------------------------------------------
4143 \fn lim_enable_ht_lsig_txop_protection
4144 \brief based on cofig enables\disables LsigTxop protection.
4145 \param uint8_t enable : 1=> enable protection, 0=> disable protection.
4146 \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
4147 \param tpUpdateBeaconParams pBeaconParams
4148 \return None
4149 -------------------------------------------------------------*/
4150tSirRetStatus
4151lim_enable_ht_lsig_txop_protection(tpAniSirGlobal pMac, uint8_t enable,
4152 uint8_t overlap,
4153 tpUpdateBeaconParams pBeaconParams,
4154 tpPESession psessionEntry)
4155{
4156 if (!psessionEntry->htCapability)
4157 return eSIR_SUCCESS; /* this protection is only for HT stations. */
4158
4159 /* overlapping protection configuration check. */
4160 if (overlap) {
4161 } else {
4162 /* normal protection config check */
4163 if (LIM_IS_AP_ROLE(psessionEntry) &&
4164 !psessionEntry->cfgProtection.lsigTxop) {
4165 /* protection disabled. */
4166 PELOG3(lim_log
4167 (pMac, LOG3,
4168 FL
4169 (" protection from LsigTxop not supported is disabled"));
4170 )
4171 return eSIR_SUCCESS;
4172 } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
4173 /* normal protection config check */
4174 if (!pMac->lim.cfgProtection.lsigTxop) {
4175 /* protection disabled. */
4176 PELOG3(lim_log
4177 (pMac, LOG3,
4178 FL
4179 (" protection from LsigTxop not supported is disabled"));
4180 )
4181 return eSIR_SUCCESS;
4182 }
4183 }
4184 }
4185
4186 if (LIM_IS_AP_ROLE(psessionEntry)) {
4187 if ((enable)
4188 && (false ==
4189 psessionEntry->beaconParams.
4190 fLsigTXOPProtectionFullSupport)) {
4191 PELOG1(lim_log
4192 (pMac, LOG1,
4193 FL(" => Protection from LsigTxop Enabled"));
4194 )
4195 pBeaconParams->fLsigTXOPProtectionFullSupport =
4196 psessionEntry->beaconParams.
4197 fLsigTXOPProtectionFullSupport = true;
4198 pBeaconParams->paramChangeBitmap |=
4199 PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
4200 } else if (!enable
4201 && (true ==
4202 psessionEntry->beaconParams.
4203 fLsigTXOPProtectionFullSupport)) {
4204 PELOG1(lim_log
4205 (pMac, LOG1,
4206 FL("===> Protection from LsigTxop Disabled"));
4207 )
4208 pBeaconParams->fLsigTXOPProtectionFullSupport =
4209 psessionEntry->beaconParams.
4210 fLsigTXOPProtectionFullSupport = false;
4211 pBeaconParams->paramChangeBitmap |=
4212 PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
4213 }
4214 } else {
4215 if ((enable)
4216 && (false ==
4217 psessionEntry->beaconParams.
4218 fLsigTXOPProtectionFullSupport)) {
4219 PELOG1(lim_log
4220 (pMac, LOG1,
4221 FL(" => Protection from LsigTxop Enabled"));
4222 )
4223 pBeaconParams->fLsigTXOPProtectionFullSupport =
4224 psessionEntry->beaconParams.
4225 fLsigTXOPProtectionFullSupport = true;
4226 pBeaconParams->paramChangeBitmap |=
4227 PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
4228 } else if (!enable
4229 && (true ==
4230 psessionEntry->beaconParams.
4231 fLsigTXOPProtectionFullSupport)) {
4232 PELOG1(lim_log
4233 (pMac, LOG1,
4234 FL("===> Protection from LsigTxop Disabled"));
4235 )
4236 pBeaconParams->fLsigTXOPProtectionFullSupport =
4237 psessionEntry->beaconParams.
4238 fLsigTXOPProtectionFullSupport = false;
4239 pBeaconParams->paramChangeBitmap |=
4240 PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
4241 }
4242 }
4243 return eSIR_SUCCESS;
4244}
4245
4246/* FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. */
4247/* This check will be done at the caller. */
4248/** -------------------------------------------------------------
4249 \fn lim_enable_ht_rifs_protection
4250 \brief based on cofig enables\disables Rifs protection.
4251 \param uint8_t enable : 1=> enable protection, 0=> disable protection.
4252 \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
4253 \param tpUpdateBeaconParams pBeaconParams
4254 \return None
4255 -------------------------------------------------------------*/
4256tSirRetStatus
4257lim_enable_ht_rifs_protection(tpAniSirGlobal pMac, uint8_t enable,
4258 uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
4259 tpPESession psessionEntry)
4260{
4261 if (!psessionEntry->htCapability)
4262 return eSIR_SUCCESS; /* this protection is only for HT stations. */
4263
4264 /* overlapping protection configuration check. */
4265 if (overlap) {
4266 } else {
4267 /* normal protection config check */
4268 if (LIM_IS_AP_ROLE(psessionEntry) &&
4269 !psessionEntry->cfgProtection.rifs) {
4270 /* protection disabled. */
4271 PELOG3(lim_log
4272 (pMac, LOG3,
4273 FL(" protection from Rifs is disabled"));
4274 )
4275 return eSIR_SUCCESS;
4276 } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
4277 /* normal protection config check */
4278 if (!pMac->lim.cfgProtection.rifs) {
4279 /* protection disabled. */
4280 PELOG3(lim_log
4281 (pMac, LOG3,
4282 FL
4283 (" protection from Rifs is disabled"));
4284 )
4285 return eSIR_SUCCESS;
4286 }
4287 }
4288 }
4289
4290 if (LIM_IS_AP_ROLE(psessionEntry)) {
4291 /* Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS */
4292 if ((!enable)
4293 && (false == psessionEntry->beaconParams.fRIFSMode)) {
4294 PELOG1(lim_log
4295 (pMac, LOG1, FL(" => Rifs protection Disabled"));
4296 )
4297 pBeaconParams->fRIFSMode =
4298 psessionEntry->beaconParams.fRIFSMode = true;
4299 pBeaconParams->paramChangeBitmap |=
4300 PARAM_RIFS_MODE_CHANGED;
4301 }
4302 /* Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS */
4303 else if (enable
4304 && (true == psessionEntry->beaconParams.fRIFSMode)) {
4305 PELOG1(lim_log
4306 (pMac, LOG1, FL("===> Rifs Protection Enabled"));
4307 )
4308 pBeaconParams->fRIFSMode =
4309 psessionEntry->beaconParams.fRIFSMode = false;
4310 pBeaconParams->paramChangeBitmap |=
4311 PARAM_RIFS_MODE_CHANGED;
4312 }
4313 } else {
4314 /* Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS */
4315 if ((!enable)
4316 && (false == psessionEntry->beaconParams.fRIFSMode)) {
4317 PELOG1(lim_log
4318 (pMac, LOG1, FL(" => Rifs protection Disabled"));
4319 )
4320 pBeaconParams->fRIFSMode =
4321 psessionEntry->beaconParams.fRIFSMode = true;
4322 pBeaconParams->paramChangeBitmap |=
4323 PARAM_RIFS_MODE_CHANGED;
4324 }
4325 /* Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS */
4326 else if (enable
4327 && (true == psessionEntry->beaconParams.fRIFSMode)) {
4328 PELOG1(lim_log
4329 (pMac, LOG1, FL("===> Rifs Protection Enabled"));
4330 )
4331 pBeaconParams->fRIFSMode =
4332 psessionEntry->beaconParams.fRIFSMode = false;
4333 pBeaconParams->paramChangeBitmap |=
4334 PARAM_RIFS_MODE_CHANGED;
4335 }
4336 }
4337 return eSIR_SUCCESS;
4338}
4339
4340/* --------------------------------------------------------------------- */
4341/**
4342 * lim_enable_short_preamble
4343 *
4344 * FUNCTION:
4345 * Enable/Disable short preamble
4346 *
4347 * LOGIC:
4348 *
4349 * ASSUMPTIONS:
4350 *
4351 * NOTE:
4352 *
4353 * @param enable Flag to enable/disable short preamble
4354 * @return None
4355 */
4356
4357tSirRetStatus
4358lim_enable_short_preamble(tpAniSirGlobal pMac, uint8_t enable,
4359 tpUpdateBeaconParams pBeaconParams,
4360 tpPESession psessionEntry)
4361{
4362 uint32_t val;
4363
4364 if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) {
4365 /* Could not get short preamble enabled flag from CFG. Log error. */
4366 lim_log(pMac, LOGP,
4367 FL("could not retrieve short preamble flag"));
4368 return eSIR_FAILURE;
4369 }
4370
4371 if (!val)
4372 return eSIR_SUCCESS;
4373
4374 if (wlan_cfg_get_int(pMac, WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, &val) !=
4375 eSIR_SUCCESS) {
4376 lim_log(pMac, LOGP,
4377 FL
4378 ("could not retrieve 11G short preamble switching enabled flag"));
4379 return eSIR_FAILURE;
4380 }
4381
4382 if (!val) /* 11G short preamble switching is disabled. */
4383 return eSIR_SUCCESS;
4384
4385 if (LIM_IS_AP_ROLE(psessionEntry)) {
4386 if (enable && (psessionEntry->beaconParams.fShortPreamble == 0)) {
4387 PELOG1(lim_log
4388 (pMac, LOG1, FL("===> Short Preamble Enabled"));
4389 )
4390 psessionEntry->beaconParams.fShortPreamble = true;
4391 pBeaconParams->fShortPreamble =
4392 (uint8_t) psessionEntry->beaconParams.
4393 fShortPreamble;
4394 pBeaconParams->paramChangeBitmap |=
4395 PARAM_SHORT_PREAMBLE_CHANGED;
4396 } else if (!enable
4397 && (psessionEntry->beaconParams.fShortPreamble ==
4398 1)) {
4399 PELOG1(lim_log
4400 (pMac, LOG1, FL("===> Short Preamble Disabled"));
4401 )
4402 psessionEntry->beaconParams.fShortPreamble = false;
4403 pBeaconParams->fShortPreamble =
4404 (uint8_t) psessionEntry->beaconParams.
4405 fShortPreamble;
4406 pBeaconParams->paramChangeBitmap |=
4407 PARAM_SHORT_PREAMBLE_CHANGED;
4408 }
4409 }
4410
4411 return eSIR_SUCCESS;
4412}
4413
4414/**
4415 * lim_tx_complete
4416 *
4417 * Function:
4418 * This is LIM's very own "TX MGMT frame complete" completion routine.
4419 *
4420 * Logic:
4421 * LIM wants to send a MGMT frame (broadcast or unicast)
4422 * LIM allocates memory using cds_packet_alloc( ..., **pData, **pPacket )
4423 * LIM transmits the MGMT frame using the API:
4424 * wma_tx_frame( ... pPacket, ..., (void *) lim_tx_complete, pData )
4425 * HDD, via wma_tx_frame/DXE, "transfers" the packet over to BMU
4426 * HDD, if it determines that a TX completion routine (in this case
4427 * lim_tx_complete) has been provided, will invoke this callback
4428 * LIM will try to free the TX MGMT packet that was earlier allocated, in order
4429 * to send this MGMT frame, using the PAL API cds_packet_free( ... pData, pPacket )
4430 *
4431 * Assumptions:
4432 * Presently, this is ONLY being used for MGMT frames/packets
4433 * TODO:
4434 * Would it do good for LIM to have some sort of "signature" validation to
4435 * ensure that the pData argument passed in was a buffer that was actually
4436 * allocated by LIM and/or is not corrupted?
4437 *
4438 * Note: FIXME and TODO
4439 * Looks like cds_packet_free() is interested in pPacket. But, when this completion
4440 * routine is called, only pData is made available to LIM!!
4441 *
4442 * @param void A pointer to pData. Shouldn't it be pPacket?!
4443 *
4444 * @return none
4445 */
4446void lim_tx_complete(tHalHandle hHal, void *data, bool free)
4447{
4448 if (free)
4449 cds_packet_free((void *)data);
4450}
4451
4452/**
4453 * \brief This function updates lim global structure, if CB parameters in the BSS
4454 * have changed, and sends an indication to HAL also with the
4455 * updated HT Parameters.
4456 * This function does not detect the change in the primary channel, that is done as part
4457 * of channel Swtich IE processing.
4458 * If STA is configured with '20Mhz only' mode, then this function does not do anything
4459 * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz'
4460 *
4461 *
4462 * \param pMac Pointer to global MAC structure
4463 *
4464 * \param pRcvdHTInfo Pointer to HT Info IE obtained from a Beacon or
4465 * Probe Response
4466 *
4467 * \param bssIdx BSS Index of the Bss to which Station is associated.
4468 *
4469 *
4470 */
4471
4472void lim_update_sta_run_time_ht_switch_chnl_params(tpAniSirGlobal pMac,
4473 tDot11fIEHTInfo *pHTInfo,
4474 uint8_t bssIdx,
4475 tpPESession psessionEntry)
4476{
4477 uint8_t center_freq = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004478
4479 /* If self capability is set to '20Mhz only', then do not change the CB mode. */
4480 if (!lim_get_ht_capability
4481 (pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry))
4482 return;
4483
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004484 if (psessionEntry->ftPEContext.ftPreAuthSession) {
4485 lim_log(pMac, LOGE,
4486 FL("FT PREAUTH channel change is in progress"));
4487 return;
4488 }
4489
Kiran Kumar Lokerea3e5e0b2015-11-03 14:17:26 -08004490 /*
4491 * Do not try to switch channel if RoC is in progress. RoC code path
4492 * uses pMac->lim.gpLimRemainOnChanReq to notify the upper layers that
4493 * the device has started listening on the channel requested as part of
4494 * RoC, if we set pMac->lim.gpLimRemainOnChanReq to NULL as we do below
4495 * then the upper layers will think that the channel change is not
4496 * successful and the RoC from the upper layer perspective will never
4497 * end...
4498 */
4499 if (pMac->lim.gpLimRemainOnChanReq) {
4500 lim_log(pMac, LOGE, FL("RoC is in progress"));
4501 return;
4502 }
4503
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004504 if (psessionEntry->htSecondaryChannelOffset !=
4505 (uint8_t) pHTInfo->secondaryChannelOffset
4506 || psessionEntry->htRecommendedTxWidthSet !=
4507 (uint8_t) pHTInfo->recommendedTxWidthSet) {
4508 psessionEntry->htSecondaryChannelOffset =
4509 (ePhyChanBondState) pHTInfo->secondaryChannelOffset;
4510 psessionEntry->htRecommendedTxWidthSet =
4511 (uint8_t) pHTInfo->recommendedTxWidthSet;
4512 if (eHT_CHANNEL_WIDTH_40MHZ ==
4513 psessionEntry->htRecommendedTxWidthSet) {
4514 if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
4515 pHTInfo->secondaryChannelOffset)
4516 center_freq = pHTInfo->primaryChannel + 2;
4517 else if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY ==
4518 pHTInfo->secondaryChannelOffset)
4519 center_freq = pHTInfo->primaryChannel - 2;
4520 }
4521
4522 /* notify HAL */
4523 lim_log(pMac, LOGW, FL("Channel Information in HT IE change"
4524 "d; sending notification to HAL."));
4525 lim_log(pMac, LOGW, FL("Primary Channel: %d, Secondary Chan"
4526 "nel Offset: %d, Channel Width: %d"),
4527 pHTInfo->primaryChannel, center_freq,
4528 psessionEntry->htRecommendedTxWidthSet);
4529 psessionEntry->channelChangeReasonCode =
4530 LIM_SWITCH_CHANNEL_OPERATION;
4531 pMac->lim.gpchangeChannelCallback = NULL;
4532 pMac->lim.gpchangeChannelData = NULL;
4533
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004534 lim_send_switch_chnl_params(pMac, (uint8_t) pHTInfo->primaryChannel,
4535 center_freq, 0,
4536 psessionEntry->htRecommendedTxWidthSet,
4537 psessionEntry->maxTxPower,
4538 psessionEntry->peSessionId,
4539 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004540
4541 /* In case of IBSS, if STA should update HT Info IE in its beacons. */
4542 if (LIM_IS_IBSS_ROLE(psessionEntry)) {
4543 sch_set_fixed_beacon_fields(pMac, psessionEntry);
4544 }
4545
4546 }
4547} /* End limUpdateStaRunTimeHTParams. */
4548
4549/**
4550 * \brief This function updates the lim global structure, if any of the
4551 * HT Capabilities have changed.
4552 *
4553 *
4554 * \param pMac Pointer to Global MAC structure
4555 *
4556 * \param pHTCapability Pointer to HT Capability Information Element
4557 * obtained from a Beacon or Probe Response
4558 *
4559 *
4560 *
4561 */
4562
4563void lim_update_sta_run_time_ht_capability(tpAniSirGlobal pMac,
4564 tDot11fIEHTCaps *pHTCaps)
4565{
4566
4567 if (pMac->lim.gHTLsigTXOPProtection !=
4568 (uint8_t) pHTCaps->lsigTXOPProtection) {
4569 pMac->lim.gHTLsigTXOPProtection =
4570 (uint8_t) pHTCaps->lsigTXOPProtection;
4571 /* Send change notification to HAL */
4572 }
4573
4574 if (pMac->lim.gHTAMpduDensity != (uint8_t) pHTCaps->mpduDensity) {
4575 pMac->lim.gHTAMpduDensity = (uint8_t) pHTCaps->mpduDensity;
4576 /* Send change notification to HAL */
4577 }
4578
4579 if (pMac->lim.gHTMaxRxAMpduFactor !=
4580 (uint8_t) pHTCaps->maxRxAMPDUFactor) {
4581 pMac->lim.gHTMaxRxAMpduFactor =
4582 (uint8_t) pHTCaps->maxRxAMPDUFactor;
4583 /* Send change notification to HAL */
4584 }
4585
4586} /* End lim_update_sta_run_time_ht_capability. */
4587
4588/**
4589 * \brief This function updates lim global structure, if any of the HT
4590 * Info Parameters have changed.
4591 *
4592 *
4593 * \param pMac Pointer to the global MAC structure
4594 *
4595 * \param pHTInfo Pointer to the HT Info IE obtained from a Beacon or
4596 * Probe Response
4597 *
4598 *
4599 */
4600
4601void lim_update_sta_run_time_ht_info(tpAniSirGlobal pMac,
4602 tDot11fIEHTInfo *pHTInfo,
4603 tpPESession psessionEntry)
4604{
4605 if (psessionEntry->htRecommendedTxWidthSet !=
4606 (uint8_t) pHTInfo->recommendedTxWidthSet) {
4607 psessionEntry->htRecommendedTxWidthSet =
4608 (uint8_t) pHTInfo->recommendedTxWidthSet;
4609 /* Send change notification to HAL */
4610 }
4611
4612 if (psessionEntry->beaconParams.fRIFSMode !=
4613 (uint8_t) pHTInfo->rifsMode) {
4614 psessionEntry->beaconParams.fRIFSMode =
4615 (uint8_t) pHTInfo->rifsMode;
4616 /* Send change notification to HAL */
4617 }
4618
4619 if (pMac->lim.gHTServiceIntervalGranularity !=
4620 (uint8_t) pHTInfo->serviceIntervalGranularity) {
4621 pMac->lim.gHTServiceIntervalGranularity =
4622 (uint8_t) pHTInfo->serviceIntervalGranularity;
4623 /* Send change notification to HAL */
4624 }
4625
4626 if (pMac->lim.gHTOperMode != (tSirMacHTOperatingMode) pHTInfo->opMode) {
4627 pMac->lim.gHTOperMode =
4628 (tSirMacHTOperatingMode) pHTInfo->opMode;
4629 /* Send change notification to HAL */
4630 }
4631
4632 if (psessionEntry->beaconParams.llnNonGFCoexist !=
4633 pHTInfo->nonGFDevicesPresent) {
4634 psessionEntry->beaconParams.llnNonGFCoexist =
4635 (uint8_t) pHTInfo->nonGFDevicesPresent;
4636 }
4637
4638 if (pMac->lim.gHTSTBCBasicMCS != (uint8_t) pHTInfo->basicSTBCMCS) {
4639 pMac->lim.gHTSTBCBasicMCS = (uint8_t) pHTInfo->basicSTBCMCS;
4640 /* Send change notification to HAL */
4641 }
4642
4643 if (pMac->lim.gHTDualCTSProtection !=
4644 (uint8_t) pHTInfo->dualCTSProtection) {
4645 pMac->lim.gHTDualCTSProtection =
4646 (uint8_t) pHTInfo->dualCTSProtection;
4647 /* Send change notification to HAL */
4648 }
4649
4650 if (pMac->lim.gHTSecondaryBeacon != (uint8_t) pHTInfo->secondaryBeacon) {
4651 pMac->lim.gHTSecondaryBeacon =
4652 (uint8_t) pHTInfo->secondaryBeacon;
4653 /* Send change notification to HAL */
4654 }
4655
4656 if (psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport !=
4657 (uint8_t) pHTInfo->lsigTXOPProtectionFullSupport) {
4658 psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
4659 (uint8_t) pHTInfo->lsigTXOPProtectionFullSupport;
4660 /* Send change notification to HAL */
4661 }
4662
4663 if (pMac->lim.gHTPCOActive != (uint8_t) pHTInfo->pcoActive) {
4664 pMac->lim.gHTPCOActive = (uint8_t) pHTInfo->pcoActive;
4665 /* Send change notification to HAL */
4666 }
4667
4668 if (pMac->lim.gHTPCOPhase != (uint8_t) pHTInfo->pcoPhase) {
4669 pMac->lim.gHTPCOPhase = (uint8_t) pHTInfo->pcoPhase;
4670 /* Send change notification to HAL */
4671 }
4672
4673} /* End lim_update_sta_run_time_ht_info. */
4674
4675/** -------------------------------------------------------------
4676 \fn lim_process_hal_ind_messages
4677 \brief callback function for HAL indication
4678 \param tpAniSirGlobal pMac
4679 \param uint32_t mesgId
4680 \param void *mesgParam
4681 \return tSirRetStatu - status
4682 -------------------------------------------------------------*/
4683
4684tSirRetStatus lim_process_hal_ind_messages(tpAniSirGlobal pMac, uint32_t msgId,
4685 void *msgParam)
4686{
4687 /* its PE's responsibility to free msgparam when its done extracting the message parameters. */
4688 tSirMsgQ msg;
4689
4690 switch (msgId) {
4691 case SIR_LIM_DEL_TS_IND:
4692 case SIR_LIM_DELETE_STA_CONTEXT_IND:
4693 case SIR_LIM_BEACON_GEN_IND:
4694 msg.type = (uint16_t) msgId;
4695 msg.bodyptr = msgParam;
4696 msg.bodyval = 0;
4697 break;
4698
4699 default:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304700 qdf_mem_free(msgParam);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004701 lim_log(pMac, LOGP, FL("invalid message id = %d received"),
4702 msgId);
4703 return eSIR_FAILURE;
4704 }
4705
4706 if (lim_post_msg_api(pMac, &msg) != eSIR_SUCCESS) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304707 qdf_mem_free(msgParam);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004708 lim_log(pMac, LOGP, FL("lim_post_msg_api failed for msgid = %d"),
4709 msg.type);
4710 return eSIR_FAILURE;
4711 }
4712 return eSIR_SUCCESS;
4713}
4714
4715/**
4716 * lim_validate_delts_req() - This function validates DelTs req
4717 * @mac_ctx: pointer to Global Mac structure
4718 * @delts_req: pointer to delete traffic stream structure
4719 * @peer_mac_addr: variable for peer mac address
4720 *
4721 * Function validates DelTs req originated by SME or by HAL and also
4722 * sends halMsg_DelTs to HAL
4723 *
4724 * Return: eSIR_SUCCESS - Success, eSIR_FAILURE - Failure
4725 */
4726
4727tSirRetStatus
4728lim_validate_delts_req(tpAniSirGlobal mac_ctx, tpSirDeltsReq delts_req,
4729 tSirMacAddr peer_mac_addr, tpPESession psession_entry)
4730{
4731 tpDphHashNode sta;
4732 uint8_t ts_status;
4733 tSirMacTSInfo *tsinfo;
4734 uint32_t i;
4735 uint8_t tspec_idx;
4736
4737 /*
4738 * if sta
4739 * - verify assoc state
4740 * - del tspec locally
4741 * if ap
4742 * - verify sta is in assoc state
4743 * - del sta tspec locally
4744 */
4745 if (delts_req == NULL) {
4746 lim_log(mac_ctx, LOGE,
4747 FL("Delete TS request pointer is NULL"));
4748 return eSIR_FAILURE;
4749 }
4750
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07004751 if (LIM_IS_STA_ROLE(psession_entry)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004752 uint32_t val;
4753
4754 /* station always talks to the AP */
4755 sta = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
4756 &psession_entry->dph.dphHashTable);
4757
4758 val = sizeof(tSirMacAddr);
4759 sir_copy_mac_addr(peer_mac_addr, psession_entry->bssId);
4760
4761 } else {
4762 uint16_t associd;
4763 uint8_t *macaddr = (uint8_t *) peer_mac_addr;
4764
4765 associd = delts_req->aid;
4766 if (associd != 0)
4767 sta = dph_get_hash_entry(mac_ctx, associd,
4768 &psession_entry->dph.dphHashTable);
4769 else
4770 sta = dph_lookup_hash_entry(mac_ctx,
Srinivas Girigowdabab88932015-12-03 19:18:11 -08004771 delts_req->macaddr.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004772 &associd,
4773 &psession_entry->dph.
4774 dphHashTable);
4775
4776 if (sta != NULL)
4777 /* TBD: check sta assoc state as well */
4778 for (i = 0; i < sizeof(tSirMacAddr); i++)
4779 macaddr[i] = sta->staAddr[i];
4780 }
4781
4782 if (sta == NULL) {
4783 lim_log(mac_ctx, LOGE,
4784 FL("Cannot find station context for delts req"));
4785 return eSIR_FAILURE;
4786 }
4787
4788 if ((!sta->valid) ||
4789 (sta->mlmStaContext.mlmState !=
4790 eLIM_MLM_LINK_ESTABLISHED_STATE)) {
4791 lim_log(mac_ctx, LOGE,
4792 FL("Invalid Sta (or state) for DelTsReq"));
4793 return eSIR_FAILURE;
4794 }
4795
4796 delts_req->req.wsmTspecPresent = 0;
4797 delts_req->req.wmeTspecPresent = 0;
4798 delts_req->req.lleTspecPresent = 0;
4799
4800 if ((sta->wsmEnabled) &&
4801 (delts_req->req.tspec.tsinfo.traffic.accessPolicy !=
4802 SIR_MAC_ACCESSPOLICY_EDCA))
4803 delts_req->req.wsmTspecPresent = 1;
4804 else if (sta->wmeEnabled)
4805 delts_req->req.wmeTspecPresent = 1;
4806 else if (sta->lleEnabled)
4807 delts_req->req.lleTspecPresent = 1;
4808 else {
4809 lim_log(mac_ctx, LOGW,
4810 FL("DELTS_REQ ignore - qos is disabled"));
4811 return eSIR_FAILURE;
4812 }
4813
4814 tsinfo = delts_req->req.wmeTspecPresent ? &delts_req->req.tspec.tsinfo
4815 : &delts_req->req.tsinfo;
4816 lim_log(mac_ctx, LOG1,
4817 FL("received DELTS_REQ message (wmeTspecPresent = %d, lleTspecPresent = %d, wsmTspecPresent = %d, tsid %d, up %d, direction = %d)"),
4818 delts_req->req.wmeTspecPresent,
4819 delts_req->req.lleTspecPresent,
4820 delts_req->req.wsmTspecPresent, tsinfo->traffic.tsid,
4821 tsinfo->traffic.userPrio, tsinfo->traffic.direction);
4822
4823 /* if no Access Control, ignore the request */
4824 if (lim_admit_control_delete_ts(mac_ctx, sta->assocId, tsinfo,
4825 &ts_status, &tspec_idx) != eSIR_SUCCESS) {
4826 lim_log(mac_ctx, LOGE,
4827 FL("ERROR DELTS request for sta assocId %d (tsid %d, up %d)"),
4828 sta->assocId, tsinfo->traffic.tsid,
4829 tsinfo->traffic.userPrio);
4830 return eSIR_FAILURE;
4831 } else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
4832 || (tsinfo->traffic.accessPolicy ==
4833 SIR_MAC_ACCESSPOLICY_BOTH)) {
4834 /* edca only now. */
4835 } else if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
4836 /* send message to HAL to delete TS */
4837 if (eSIR_SUCCESS !=
4838 lim_send_hal_msg_del_ts(mac_ctx, sta->staIndex,
4839 tspec_idx, delts_req->req,
4840 psession_entry->peSessionId,
4841 psession_entry->bssId)) {
4842 lim_log(mac_ctx, LOGW,
4843 FL("DelTs with UP %d failed in lim_send_hal_msg_del_ts - ignoring request"),
4844 tsinfo->traffic.userPrio);
4845 return eSIR_FAILURE;
4846 }
4847 }
4848 return eSIR_SUCCESS;
4849}
4850
4851/** -------------------------------------------------------------
4852 \fn lim_register_hal_ind_call_back
4853 \brief registers callback function to HAL for any indication.
4854 \param tpAniSirGlobal pMac
4855 \return none.
4856 -------------------------------------------------------------*/
4857void lim_register_hal_ind_call_back(tpAniSirGlobal pMac)
4858{
4859 tSirMsgQ msg;
4860 tpHalIndCB pHalCB;
4861
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304862 pHalCB = qdf_mem_malloc(sizeof(tHalIndCB));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004863 if (NULL == pHalCB) {
4864 lim_log(pMac, LOGP, FL("AllocateMemory() failed"));
4865 return;
4866 }
4867
4868 pHalCB->pHalIndCB = lim_process_hal_ind_messages;
4869
4870 msg.type = WMA_REGISTER_PE_CALLBACK;
4871 msg.bodyptr = pHalCB;
4872 msg.bodyval = 0;
4873
4874 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
4875 if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304876 qdf_mem_free(pHalCB);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004877 lim_log(pMac, LOGP, FL("wma_post_ctrl_msg() failed"));
4878 }
4879
4880 return;
4881}
4882
4883/**
4884 * lim_process_del_ts_ind() - handle del_ts_ind from HAL
4885 *
4886 * @mac_ctx: pointer to Global Mac Structure
4887 * @lim_msg: pointer to msg buff
4888 *
4889 * handles the DeleteTS indication coming from HAL or generated by PE itself
4890 * in some error cases. Validates the request, sends the DelTs action frame
4891 * to the Peer and sends DelTs indicatoin to HDD.
4892 *
4893 * Return: none
4894 */
4895void lim_process_del_ts_ind(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
4896{
4897 tpDphHashNode pSta;
4898 tpDelTsParams pDelTsParam = (tpDelTsParams) (limMsg->bodyptr);
4899 tpSirDeltsReq pDelTsReq = NULL;
4900 tSirMacAddr peerMacAddr;
4901 tpSirDeltsReqInfo pDelTsReqInfo;
4902 tpLimTspecInfo pTspecInfo;
4903 tpPESession psessionEntry;
4904 uint8_t sessionId;
4905
4906 psessionEntry = pe_find_session_by_bssid(pMac, pDelTsParam->bssId,
4907 &sessionId);
4908 if (psessionEntry == NULL) {
4909 lim_log(pMac, LOGE,
4910 FL("session does not exist for given BssId"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304911 qdf_mem_free(limMsg->bodyptr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004912 limMsg->bodyptr = NULL;
4913 return;
4914 }
4915
4916 pTspecInfo = &(pMac->lim.tspecInfo[pDelTsParam->tspecIdx]);
4917 if (pTspecInfo->inuse == false) {
4918 PELOGE(lim_log
4919 (pMac, LOGE,
4920 FL("tspec entry with index %d is not in use"),
4921 pDelTsParam->tspecIdx);
4922 )
4923 goto error1;
4924 }
4925
4926 pSta =
4927 dph_get_hash_entry(pMac, pTspecInfo->assocId,
4928 &psessionEntry->dph.dphHashTable);
4929 if (pSta == NULL) {
4930 lim_log(pMac, LOGE,
4931 FL("Could not find entry in DPH table for assocId = %d"),
4932 pTspecInfo->assocId);
4933 goto error1;
4934 }
4935
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304936 pDelTsReq = qdf_mem_malloc(sizeof(tSirDeltsReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004937 if (NULL == pDelTsReq) {
4938 PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory() failed"));)
4939 goto error1;
4940 }
4941
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304942 qdf_mem_set((uint8_t *) pDelTsReq, sizeof(tSirDeltsReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004943
4944 if (pSta->wmeEnabled)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304945 qdf_mem_copy(&(pDelTsReq->req.tspec), &(pTspecInfo->tspec),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004946 sizeof(tSirMacTspecIE));
4947 else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304948 qdf_mem_copy(&(pDelTsReq->req.tsinfo),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004949 &(pTspecInfo->tspec.tsinfo),
4950 sizeof(tSirMacTSInfo));
4951
4952 /* validate the req */
4953 if (eSIR_SUCCESS !=
4954 lim_validate_delts_req(pMac, pDelTsReq, peerMacAddr, psessionEntry)) {
4955 PELOGE(lim_log(pMac, LOGE, FL("lim_validate_delts_req failed"));)
4956 goto error2;
4957 }
4958 PELOG1(lim_log(pMac, LOG1, "Sent DELTS request to station with "
4959 "assocId = %d MacAddr = " MAC_ADDRESS_STR,
4960 pDelTsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));
4961 )
4962
4963 lim_send_delts_req_action_frame(pMac, peerMacAddr,
4964 pDelTsReq->req.wmeTspecPresent,
4965 &pDelTsReq->req.tsinfo,
4966 &pDelTsReq->req.tspec, psessionEntry);
4967
4968 /* prepare and send an sme indication to HDD */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304969 pDelTsReqInfo = qdf_mem_malloc(sizeof(tSirDeltsReqInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004970 if (NULL == pDelTsReqInfo) {
4971 PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory() failed"));)
4972 goto error3;
4973 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304974 qdf_mem_set((uint8_t *) pDelTsReqInfo, sizeof(tSirDeltsReqInfo), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004975
4976 if (pSta->wmeEnabled)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304977 qdf_mem_copy(&(pDelTsReqInfo->tspec), &(pTspecInfo->tspec),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004978 sizeof(tSirMacTspecIE));
4979 else
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304980 qdf_mem_copy(&(pDelTsReqInfo->tsinfo),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004981 &(pTspecInfo->tspec.tsinfo),
4982 sizeof(tSirMacTSInfo));
4983
4984 lim_send_sme_delts_ind(pMac, pDelTsReqInfo, pDelTsReq->aid, psessionEntry);
4985
4986error3:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304987 qdf_mem_free(pDelTsReqInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004988error2:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304989 qdf_mem_free(pDelTsReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004990error1:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304991 qdf_mem_free(limMsg->bodyptr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004992 limMsg->bodyptr = NULL;
4993 return;
4994}
4995
4996/**
4997 * @function : lim_post_sm_state_update()
4998 *
4999 * @brief : This function Updates the HAL and Softmac about the change in the STA's SMPS state.
5000 *
5001 * LOGIC:
5002 *
5003 * ASSUMPTIONS:
5004 * NA
5005 *
5006 * NOTE:
5007 * NA
5008 *
5009 * @param pMac - Pointer to Global MAC structure
5010 * @param limMsg - Lim Message structure object with the MimoPSparam in body
5011 * @return None
5012 */
5013tSirRetStatus
5014lim_post_sm_state_update(tpAniSirGlobal pMac,
5015 uint16_t staIdx, tSirMacHTMIMOPowerSaveState state,
5016 uint8_t *pPeerStaMac, uint8_t sessionId)
5017{
5018 tSirRetStatus retCode = eSIR_SUCCESS;
5019 tSirMsgQ msgQ;
5020 tpSetMIMOPS pMIMO_PSParams;
5021
5022 msgQ.reserved = 0;
5023 msgQ.type = WMA_SET_MIMOPS_REQ;
5024
5025 /* Allocate for WMA_SET_MIMOPS_REQ */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305026 pMIMO_PSParams = qdf_mem_malloc(sizeof(tSetMIMOPS));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005027 if (NULL == pMIMO_PSParams) {
5028 lim_log(pMac, LOGP, FL(" AllocateMemory failed"));
5029 return eSIR_MEM_ALLOC_FAILED;
5030 }
5031
5032 pMIMO_PSParams->htMIMOPSState = state;
5033 pMIMO_PSParams->staIdx = staIdx;
5034 pMIMO_PSParams->fsendRsp = true;
5035 pMIMO_PSParams->sessionId = sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305036 qdf_mem_copy(pMIMO_PSParams->peerMac, pPeerStaMac, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005037
5038 msgQ.bodyptr = pMIMO_PSParams;
5039 msgQ.bodyval = 0;
5040
5041 lim_log(pMac, LOG2, FL("Sending WMA_SET_MIMOPS_REQ..."));
5042
5043 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
5044 retCode = wma_post_ctrl_msg(pMac, &msgQ);
5045 if (eSIR_SUCCESS != retCode) {
5046 lim_log(pMac, LOGP,
5047 FL
5048 ("Posting WMA_SET_MIMOPS_REQ to HAL failed! Reason = %d"),
5049 retCode);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305050 qdf_mem_free(pMIMO_PSParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005051 return retCode;
5052 }
5053
5054 return retCode;
5055}
5056
5057void lim_pkt_free(tpAniSirGlobal pMac,
5058 eFrameType frmType, uint8_t *pRxPacketInfo, void *pBody)
5059{
5060 (void)pMac;
5061 (void)frmType;
5062 (void)pRxPacketInfo;
5063 (void)pBody;
5064}
5065
5066/**
5067 * lim_get_b_dfrom_rx_packet()
5068 *
5069 ***FUNCTION:
5070 * This function is called to get pointer to Polaris
5071 * Buffer Descriptor containing MAC header & other control
5072 * info from the body of the message posted to LIM.
5073 *
5074 ***LOGIC:
5075 * NA
5076 *
5077 ***ASSUMPTIONS:
5078 * NA
5079 *
5080 ***NOTE:
5081 * NA
5082 *
5083 * @param body - Received message body
5084 * @param pRxPacketInfo - Pointer to received BD
5085 * @return None
5086 */
5087
5088void
5089lim_get_b_dfrom_rx_packet(tpAniSirGlobal pMac, void *body, uint32_t **pRxPacketInfo)
5090{
5091 *pRxPacketInfo = (uint32_t *) body;
5092} /*** end lim_get_b_dfrom_rx_packet() ***/
5093
5094void lim_resset_scan_channel_info(tpAniSirGlobal pMac)
5095{
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305096 qdf_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005097}
5098
5099/**
5100 * @function : lim_is_channel_valid_for_channel_switch()
5101 *
5102 * @brief : This function checks if the channel to which AP
5103 * is expecting us to switch, is a valid channel for us.
5104 * LOGIC:
5105 *
5106 * ASSUMPTIONS:
5107 * NA
5108 *
5109 * NOTE:
5110 * NA
5111 *
5112 * @param pMac - Pointer to Global MAC structure
5113 * @param channel - New channel to which we are expected to move
5114 * @return None
5115 */
5116tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac, uint8_t channel)
5117{
5118 uint8_t index;
5119 uint32_t validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5120 tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5121
5122 if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
5123 (uint8_t *) validChannelList,
5124 (uint32_t *) &validChannelListLen) !=
5125 eSIR_SUCCESS) {
5126 PELOGE(lim_log
5127 (pMac, LOGE,
5128 FL("could not retrieve valid channel list"));
5129 )
5130 return eSIR_FALSE;
5131 }
5132
5133 for (index = 0; index < validChannelListLen; index++) {
5134 if (validChannelList[index] == channel)
5135 return eSIR_TRUE;
5136 }
5137
5138 /* channel does not belong to list of valid channels */
5139 return eSIR_FALSE;
5140}
5141
5142/**------------------------------------------------------
5143 \fn __lim_fill_tx_control_params
5144 \brief Fill the message for stopping/resuming tx.
5145
5146 \param pMac
5147 \param pTxCtrlMsg - Pointer to tx control message.
5148 \param type - Which way we want to stop/ resume tx.
5149 \param mode - To stop/resume.
5150 -------------------------------------------------------*/
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305151static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005152__lim_fill_tx_control_params(tpAniSirGlobal pMac, tpTxControlParams pTxCtrlMsg,
5153 tLimQuietTxMode type, tLimControlTx mode)
5154{
5155
5156 tpPESession psessionEntry = &pMac->lim.gpSession[0];
5157
5158 if (mode == eLIM_STOP_TX)
5159 pTxCtrlMsg->stopTx = true;
5160 else
5161 pTxCtrlMsg->stopTx = false;
5162
5163 switch (type) {
5164 case eLIM_TX_ALL:
5165 /** Stops/resumes transmission completely */
5166 pTxCtrlMsg->fCtrlGlobal = 1;
5167 break;
5168
5169 case eLIM_TX_BSS_BUT_BEACON:
5170 /** Stops/resumes transmission on a particular BSS. Stopping BSS, doesnt
5171 * stop beacon transmission.
5172 */
5173 pTxCtrlMsg->ctrlBss = 1;
5174 pTxCtrlMsg->bssBitmap |= (1 << psessionEntry->bssIdx);
5175 break;
5176
5177 case eLIM_TX_STA:
5178 /** Memory for station bitmap is allocated dynamically in caller of this
5179 * so decode properly here and fill the bitmap. Now not implemented,
5180 * fall through.
5181 */
5182 case eLIM_TX_BSS:
5183 /* Fall thru... */
5184 default:
5185 PELOGW(lim_log(pMac, LOGW, FL("Invalid case: Not Handled"));)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305186 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005187 }
5188
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305189 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005190}
5191
5192/**
5193 * @function : lim_frame_transmission_control()
5194 *
5195 * @brief : This API is called by the user to halt/resume any frame
5196 * transmission from the device. If stopped, all frames will be
5197 * queued starting from hardware. Then back-pressure
5198 * is built till the driver.
5199 * LOGIC:
5200 *
5201 * ASSUMPTIONS:
5202 * NA
5203 *
5204 * NOTE:
5205 * NA
5206 *
5207 * @param pMac - Pointer to Global MAC structure
5208 * @return None
5209 */
5210void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
5211 tLimControlTx mode)
5212{
5213
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305214 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005215 tpTxControlParams pTxCtrlMsg;
5216 tSirMsgQ msgQ;
5217 uint8_t nBytes = 0; /* No of bytes required for station bitmap. */
5218
5219 /** Allocate only required number of bytes for station bitmap
5220 * Make it to align to 4 byte boundary */
5221 nBytes = (uint8_t) HALMSG_NUMBYTES_STATION_BITMAP(pMac->lim.maxStation);
5222
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305223 pTxCtrlMsg = qdf_mem_malloc(sizeof(*pTxCtrlMsg) + nBytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005224 if (NULL == pTxCtrlMsg) {
5225 lim_log(pMac, LOGP, FL("AllocateMemory() failed"));
5226 return;
5227 }
5228
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305229 qdf_mem_set((void *)pTxCtrlMsg, (sizeof(*pTxCtrlMsg) + nBytes), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005230 status = __lim_fill_tx_control_params(pMac, pTxCtrlMsg, type, mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305231 if (status != QDF_STATUS_SUCCESS) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305232 qdf_mem_free(pTxCtrlMsg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005233 lim_log(pMac, LOGP,
5234 FL("__lim_fill_tx_control_params failed, status = %d"),
5235 status);
5236 return;
5237 }
5238
5239 msgQ.bodyptr = (void *)pTxCtrlMsg;
5240 msgQ.bodyval = 0;
5241 msgQ.reserved = 0;
5242 msgQ.type = WMA_TRANSMISSION_CONTROL_IND;
5243
5244 MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
5245 if (wma_post_ctrl_msg(pMac, &msgQ) != eSIR_SUCCESS) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305246 qdf_mem_free(pTxCtrlMsg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005247 lim_log(pMac, LOGP, FL("Posting Message to HAL failed"));
5248 return;
5249 }
5250
5251 if (mode == eLIM_STOP_TX) {
5252 PELOG1(lim_log
5253 (pMac, LOG1,
5254 FL
5255 ("Stopping the transmission of all packets, indicated softmac"));
5256 )
5257 } else {
5258 PELOG1(lim_log
5259 (pMac, LOG1,
5260 FL
5261 ("Resuming the transmission of all packets, indicated softmac"));
5262 )
5263 }
5264 return;
5265}
5266
5267/**
5268 * @function : lim_restore_pre_channel_switch_state()
5269 *
5270 * @brief : This API is called by the user to undo any
5271 * specific changes done on the device during
5272 * channel switch.
5273 * LOGIC:
5274 *
5275 * ASSUMPTIONS:
5276 * NA
5277 *
5278 * NOTE:
5279 * NA
5280 *
5281 * @param pMac - Pointer to Global MAC structure
5282 * @return None
5283 */
5284
5285tSirRetStatus
5286lim_restore_pre_channel_switch_state(tpAniSirGlobal pMac, tpPESession psessionEntry)
5287{
5288
5289 tSirRetStatus retCode = eSIR_SUCCESS;
5290
5291 if (!LIM_IS_STA_ROLE(psessionEntry))
5292 return retCode;
5293
5294 /* Channel switch should be ready for the next time */
5295 psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
5296
5297 /* Restore the frame transmission, all the time. */
5298 lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
5299
5300 return retCode;
5301}
5302
5303/**--------------------------------------------
5304 \fn lim_restore_pre_quiet_state
5305 \brief Restore the pre quiet state
5306
5307 \param pMac
5308 \return NONE
5309 ---------------------------------------------*/
5310tSirRetStatus lim_restore_pre_quiet_state(tpAniSirGlobal pMac,
5311 tpPESession psessionEntry)
5312{
5313
5314 tSirRetStatus retCode = eSIR_SUCCESS;
5315
5316 if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE)
5317 return retCode;
5318
5319 /* Quiet should be ready for the next time */
5320 psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
5321
5322 /* Restore the frame transmission, all the time. */
5323 if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
5324 lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
5325
5326 return retCode;
5327}
5328
5329/**
5330 * @function: lim_prepare_for11h_channel_switch()
5331 *
5332 * @brief : This API is called by the user to prepare for
5333 * 11h channel switch. As of now, the API does
5334 * very minimal work. User can add more into the
5335 * same API if needed.
5336 * LOGIC:
5337 *
5338 * ASSUMPTIONS:
5339 * NA
5340 *
5341 * NOTE:
5342 * NA
5343 *
5344 * @param pMac - Pointer to Global MAC structure
5345 * @param psessionEntry
5346 * @return None
5347 */
5348void
5349lim_prepare_for11h_channel_switch(tpAniSirGlobal pMac, tpPESession psessionEntry)
5350{
5351 if (!LIM_IS_STA_ROLE(psessionEntry))
5352 return;
5353
5354 /* Flag to indicate 11h channel switch in progress */
5355 psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING;
5356
5357 if (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE ||
5358 pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE) {
5359 PELOGE(lim_log
5360 (pMac, LOG1,
5361 FL("Posting finish scan as we are in scan state"));
5362 )
5363 /* Stop ongoing scanning if any */
5364 if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) {
5365 /* Set the resume channel to Any valid channel (invalid). */
5366 /* This will instruct HAL to set it to any previous valid channel. */
5367 pe_set_resume_channel(pMac, 0, 0);
5368 } else {
5369 lim_restore_pre_channel_switch_state(pMac, psessionEntry);
5370 }
5371 return;
5372 } else {
5373 PELOGE(lim_log
5374 (pMac, LOG1,
5375 FL("Not in scan state, start channel switch timer"));
5376 )
5377 /** We are safe to switch channel at this point */
5378 lim_stop_tx_and_switch_channel(pMac, psessionEntry->peSessionId);
5379 }
5380}
5381
5382/**----------------------------------------------------
5383 \fn lim_get_nw_type
5384
5385 \brief Get type of the network from data packet or beacon
5386 \param pMac
5387 \param channelNum - Channel number
5388 \param type - Type of packet.
5389 \param pBeacon - Pointer to beacon or probe response
5390
5391 \return Network type a/b/g.
5392 -----------------------------------------------------*/
5393tSirNwType lim_get_nw_type(tpAniSirGlobal pMac, uint8_t channelNum, uint32_t type,
5394 tpSchBeaconStruct pBeacon)
5395{
5396 tSirNwType nwType = eSIR_11B_NW_TYPE;
5397
5398 if (type == SIR_MAC_DATA_FRAME) {
5399 if ((channelNum > 0) && (channelNum < 15)) {
5400 nwType = eSIR_11G_NW_TYPE;
5401 } else {
5402 nwType = eSIR_11A_NW_TYPE;
5403 }
5404 } else {
5405 if ((channelNum > 0) && (channelNum < 15)) {
5406 int i;
5407 /* 11b or 11g packet */
5408 /* 11g iff extended Rate IE is present or */
5409 /* if there is an A rate in suppRate IE */
5410 for (i = 0; i < pBeacon->supportedRates.numRates; i++) {
5411 if (sirIsArate
5412 (pBeacon->supportedRates.rate[i] & 0x7f)) {
5413 nwType = eSIR_11G_NW_TYPE;
5414 break;
5415 }
5416 }
5417 if (pBeacon->extendedRatesPresent) {
5418 PELOG3(lim_log
5419 (pMac, LOG3, FL("Beacon, nwtype=G"));
5420 )
5421 nwType = eSIR_11G_NW_TYPE;
5422 }
5423 } else {
5424 /* 11a packet */
5425 PELOG3(lim_log(pMac, LOG3, FL("Beacon, nwtype=A"));)
5426 nwType = eSIR_11A_NW_TYPE;
5427 }
5428 }
5429 return nwType;
5430}
5431
5432/**---------------------------------------------------------
5433 \fn lim_get_channel_from_beacon
5434 \brief To extract channel number from beacon
5435
5436 \param pMac
5437 \param pBeacon - Pointer to beacon or probe rsp
5438 \return channel number
5439 -----------------------------------------------------------*/
5440uint8_t lim_get_channel_from_beacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon)
5441{
5442 uint8_t channelNum = 0;
5443
5444 if (pBeacon->dsParamsPresent)
5445 channelNum = pBeacon->channelNumber;
5446 else if (pBeacon->HTInfo.present)
5447 channelNum = pBeacon->HTInfo.primaryChannel;
5448 else
5449 channelNum = pBeacon->channelNumber;
5450
5451 return channelNum;
5452}
5453
5454void lim_set_tspec_uapsd_mask_per_session(tpAniSirGlobal pMac,
5455 tpPESession psessionEntry,
5456 tSirMacTSInfo *pTsInfo, uint32_t action)
5457{
5458 uint8_t userPrio = (uint8_t) pTsInfo->traffic.userPrio;
5459 uint16_t direction = pTsInfo->traffic.direction;
5460 uint8_t ac = upToAc(userPrio);
5461
5462 PELOG1(lim_log
5463 (pMac, LOG1, FL("Set UAPSD mask for AC %d, dir %d, action=%d")
5464 , ac, direction, action);
5465 )
5466
5467 /* Converting AC to appropriate Uapsd Bit Mask
5468 * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3)
5469 * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2)
5470 * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1)
5471 * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0)
5472 */
5473 ac = ((~ac) & 0x3);
5474
5475 if (action == CLEAR_UAPSD_MASK) {
5476 if (direction == SIR_MAC_DIRECTION_UPLINK)
5477 psessionEntry->gUapsdPerAcTriggerEnableMask &=
5478 ~(1 << ac);
5479 else if (direction == SIR_MAC_DIRECTION_DNLINK)
5480 psessionEntry->gUapsdPerAcDeliveryEnableMask &=
5481 ~(1 << ac);
5482 else if (direction == SIR_MAC_DIRECTION_BIDIR) {
5483 psessionEntry->gUapsdPerAcTriggerEnableMask &=
5484 ~(1 << ac);
5485 psessionEntry->gUapsdPerAcDeliveryEnableMask &=
5486 ~(1 << ac);
5487 }
5488 } else if (action == SET_UAPSD_MASK) {
5489 if (direction == SIR_MAC_DIRECTION_UPLINK)
5490 psessionEntry->gUapsdPerAcTriggerEnableMask |=
5491 (1 << ac);
5492 else if (direction == SIR_MAC_DIRECTION_DNLINK)
5493 psessionEntry->gUapsdPerAcDeliveryEnableMask |=
5494 (1 << ac);
5495 else if (direction == SIR_MAC_DIRECTION_BIDIR) {
5496 psessionEntry->gUapsdPerAcTriggerEnableMask |=
5497 (1 << ac);
5498 psessionEntry->gUapsdPerAcDeliveryEnableMask |=
5499 (1 << ac);
5500 }
5501 }
5502
5503 lim_log(pMac, LOG1,
5504 FL("New psessionEntry->gUapsdPerAcTriggerEnableMask = 0x%x "),
5505 psessionEntry->gUapsdPerAcTriggerEnableMask);
5506 lim_log(pMac, LOG1,
5507 FL("New psessionEntry->gUapsdPerAcDeliveryEnableMask = 0x%x "),
5508 psessionEntry->gUapsdPerAcDeliveryEnableMask);
5509
5510 return;
5511}
5512
5513/**
5514 * lim_handle_heart_beat_timeout_for_session() - Handle heart beat time out
5515 * @mac_ctx: pointer to Global Mac Structure
5516 * @psession_entry: pointer to tpPESession
5517 *
5518 * Function handles heart beat time out for session
5519 *
5520 * Return: none
5521 */
5522void lim_handle_heart_beat_timeout_for_session(tpAniSirGlobal mac_ctx,
5523 tpPESession psession_entry)
5524{
5525 if (psession_entry->valid == true) {
5526 if (psession_entry->bssType == eSIR_IBSS_MODE)
5527 lim_ibss_heart_beat_handle(mac_ctx, psession_entry);
5528
5529 if ((psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) &&
5530 (LIM_IS_STA_ROLE(psession_entry)))
5531 lim_handle_heart_beat_failure(mac_ctx, psession_entry);
5532 }
5533 /*
5534 * In the function lim_handle_heart_beat_failure things can change
5535 * so check for the session entry valid and the other things
5536 * again
5537 */
5538 if ((psession_entry->valid == true) &&
5539 (psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) &&
5540 (LIM_IS_STA_ROLE(psession_entry)) &&
5541 (psession_entry->LimHBFailureStatus == true)) {
5542 tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
5543 /*
5544 * Activate Probe After HeartBeat Timer incase HB
5545 * Failure detected
5546 */
5547 PELOGW(lim_log(mac_ctx, LOGW,
5548 FL("Sending Probe for Session: %d"),
5549 psession_entry->bssIdx);)
5550 lim_deactivate_and_change_timer(mac_ctx,
5551 eLIM_PROBE_AFTER_HB_TIMER);
5552 MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 0,
5553 eLIM_PROBE_AFTER_HB_TIMER));
5554 if (tx_timer_activate(&lim_timer->gLimProbeAfterHBTimer)
5555 != TX_SUCCESS)
5556 lim_log(mac_ctx, LOGP,
5557 FL("Fail to re-activate Probe-after-hb timer"));
5558 }
5559}
5560
5561uint8_t lim_get_current_operating_channel(tpAniSirGlobal pMac)
5562{
5563 uint8_t i;
5564 for (i = 0; i < pMac->lim.maxBssId; i++) {
5565 if (pMac->lim.gpSession[i].valid == true) {
5566 if ((pMac->lim.gpSession[i].bssType ==
5567 eSIR_INFRASTRUCTURE_MODE)
5568 && (pMac->lim.gpSession[i].limSystemRole ==
5569 eLIM_STA_ROLE)) {
5570 return pMac->lim.gpSession[i].
5571 currentOperChannel;
5572 }
5573 }
5574 }
5575 return 0;
5576}
5577
5578void lim_process_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
5579{
5580 tpPESession psessionEntry;
5581 tpAddStaParams pAddStaParams;
5582
5583 pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
5584
5585 psessionEntry = pe_find_session_by_session_id(pMac,
5586 pAddStaParams->sessionId);
5587 if (psessionEntry == NULL) {
5588 lim_log(pMac, LOGP,
5589 FL("Session Does not exist for given sessionID"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305590 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005591 return;
5592 }
5593 psessionEntry->csaOffloadEnable = pAddStaParams->csaOffloadEnable;
5594 if (LIM_IS_IBSS_ROLE(psessionEntry))
5595 (void)lim_ibss_add_sta_rsp(pMac, limMsgQ->bodyptr, psessionEntry);
5596#ifdef FEATURE_WLAN_TDLS
5597 else if (pMac->lim.gLimAddStaTdls) {
5598 lim_process_tdls_add_sta_rsp(pMac, limMsgQ->bodyptr, psessionEntry);
5599 pMac->lim.gLimAddStaTdls = false;
5600 }
5601#endif
5602 else
5603 lim_process_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
5604
5605}
5606
5607/**
5608 * lim_update_beacon() - This function updates beacon
5609 * @mac_ctx: pointer to Global Mac Structure
5610 *
5611 * This Function is invoked to update the beacon
5612 *
5613 * Return: none
5614 */
5615void lim_update_beacon(tpAniSirGlobal mac_ctx)
5616{
5617 uint8_t i;
5618
5619 for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
5620 if (mac_ctx->lim.gpSession[i].valid != true)
5621 continue;
5622 if (((mac_ctx->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE)
5623 || (mac_ctx->lim.gpSession[i].limSystemRole ==
5624 eLIM_STA_IN_IBSS_ROLE))
5625 && (eLIM_SME_NORMAL_STATE ==
5626 mac_ctx->lim.gpSession[i].limSmeState)) {
5627
5628 sch_set_fixed_beacon_fields(mac_ctx,
5629 &mac_ctx->lim.gpSession[i]);
5630
5631 if (false == mac_ctx->sap.SapDfsInfo.
5632 is_dfs_cac_timer_running)
5633 lim_send_beacon_ind(mac_ctx,
5634 &mac_ctx->lim.gpSession[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005635 }
5636 }
5637}
5638
5639/**
5640 * lim_handle_heart_beat_failure_timeout - handle heart beat failure
5641 * @mac_ctx: pointer to Global Mac Structure
5642 *
5643 * Function handle heart beat failure timeout
5644 *
5645 * Return: none
5646 */
5647void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal mac_ctx)
5648{
5649 uint8_t i;
5650 tpPESession psession_entry;
5651 /*
5652 * Probe response is not received after HB failure.
5653 * This is handled by LMM sub module.
5654 */
5655 for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
5656 if (mac_ctx->lim.gpSession[i].valid != true)
5657 continue;
5658 psession_entry = &mac_ctx->lim.gpSession[i];
5659 if (psession_entry->LimHBFailureStatus != true)
5660 continue;
5661 lim_log(mac_ctx, LOGE, FL("SME %d, MLME %d, HB-Count %d"),
5662 psession_entry->limSmeState,
5663 psession_entry->limMlmState,
5664 psession_entry->LimRxedBeaconCntDuringHB);
5665
5666#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
5667 lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
5668 psession_entry, 0, 0);
5669#endif
5670 if ((psession_entry->limMlmState ==
5671 eLIM_MLM_LINK_ESTABLISHED_STATE) &&
5672 (psession_entry->limSmeState !=
5673 eLIM_SME_WT_DISASSOC_STATE) &&
5674 (psession_entry->limSmeState !=
5675 eLIM_SME_WT_DEAUTH_STATE) &&
5676 ((!LIM_IS_CONNECTION_ACTIVE(psession_entry)) ||
5677 /*
5678 * Disconnect even if we have not received a single
5679 * beacon after connection.
5680 */
5681 (psession_entry->currentBssBeaconCnt == 0))) {
5682 lim_log(mac_ctx, LOGE, FL("for session:%d "),
5683 psession_entry->peSessionId);
5684 /*
5685 * AP did not respond to Probe Request.
5686 * Tear down link with it.
5687 */
5688 lim_tear_down_link_with_ap(mac_ctx,
5689 psession_entry->peSessionId,
5690 eSIR_BEACON_MISSED);
5691 mac_ctx->lim.gLimProbeFailureAfterHBfailedCnt++;
5692 } else {
5693 lim_log(mac_ctx, LOGE,
5694 FL("Unexpected wt-probe-timeout in state "));
5695 lim_print_mlm_state(mac_ctx, LOGE,
5696 psession_entry->limMlmState);
5697 }
5698 }
5699 /*
5700 * Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer,
5701 * need not deactivate the timer
5702 * tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
5703 */
5704}
5705
5706/*
5707 * This function assumes there will not be more than one IBSS session active at any time.
5708 */
5709tpPESession lim_is_ibss_session_active(tpAniSirGlobal pMac)
5710{
5711 uint8_t i;
5712
5713 for (i = 0; i < pMac->lim.maxBssId; i++) {
5714 if ((pMac->lim.gpSession[i].valid) &&
5715 (pMac->lim.gpSession[i].limSystemRole ==
5716 eLIM_STA_IN_IBSS_ROLE))
5717 return &pMac->lim.gpSession[i];
5718 }
5719
5720 return NULL;
5721}
5722
5723tpPESession lim_is_ap_session_active(tpAniSirGlobal pMac)
5724{
5725 uint8_t i;
5726
5727 for (i = 0; i < pMac->lim.maxBssId; i++) {
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07005728 if (pMac->lim.gpSession[i].valid &&
5729 (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005730 return &pMac->lim.gpSession[i];
5731 }
5732
5733 return NULL;
5734}
5735
5736/**---------------------------------------------------------
5737 \fn lim_handle_defer_msg_error
5738 \brief handles error scenario, when the msg can not be deferred.
5739 \param pMac
5740 \param pLimMsg LIM msg, which could not be deferred.
5741 \return void
5742 -----------------------------------------------------------*/
5743
5744void lim_handle_defer_msg_error(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg)
5745{
5746 if (SIR_BB_XPORT_MGMT_MSG == pLimMsg->type) {
5747 cds_pkt_return_packet((cds_pkt_t *) pLimMsg->bodyptr);
5748 pLimMsg->bodyptr = NULL;
5749 } else if (pLimMsg->bodyptr != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305750 qdf_mem_free(pLimMsg->bodyptr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005751 pLimMsg->bodyptr = NULL;
5752 }
5753
5754}
5755
5756#ifdef FEATURE_WLAN_DIAG_SUPPORT
5757/**---------------------------------------------------------
5758 \fn lim_diag_event_report
5759 \brief This function reports Diag event
5760 \param pMac
5761 \param eventType
5762 \param bssid
5763 \param status
5764 \param reasonCode
5765 \return void
5766 -----------------------------------------------------------*/
5767void lim_diag_event_report(tpAniSirGlobal pMac, uint16_t eventType,
5768 tpPESession pSessionEntry, uint16_t status,
5769 uint16_t reasonCode)
5770{
5771 tSirMacAddr nullBssid = { 0, 0, 0, 0, 0, 0 };
5772 WLAN_HOST_DIAG_EVENT_DEF(peEvent, host_event_wlan_pe_payload_type);
5773
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305774 qdf_mem_set(&peEvent, sizeof(host_event_wlan_pe_payload_type), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005775
5776 if (NULL == pSessionEntry) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305777 qdf_mem_copy(peEvent.bssid, nullBssid, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005778 peEvent.sme_state = (uint16_t) pMac->lim.gLimSmeState;
5779 peEvent.mlm_state = (uint16_t) pMac->lim.gLimMlmState;
5780
5781 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305782 qdf_mem_copy(peEvent.bssid, pSessionEntry->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005783 sizeof(tSirMacAddr));
5784 peEvent.sme_state = (uint16_t) pSessionEntry->limSmeState;
5785 peEvent.mlm_state = (uint16_t) pSessionEntry->limMlmState;
5786 }
5787 peEvent.event_type = eventType;
5788 peEvent.status = status;
5789 peEvent.reason_code = reasonCode;
5790
5791 WLAN_HOST_DIAG_EVENT_REPORT(&peEvent, EVENT_WLAN_PE);
5792 return;
5793}
5794
5795#endif /* FEATURE_WLAN_DIAG_SUPPORT */
5796
5797uint8_t *lim_get_ie_ptr_new(tpAniSirGlobal pMac, uint8_t *pIes, int length,
5798 uint8_t eid, eSizeOfLenField size_of_len_field)
5799{
5800 int left = length;
5801 uint8_t *ptr = pIes;
5802 uint8_t elem_id;
5803 uint16_t elem_len;
5804
5805 while (left >= (size_of_len_field + 1)) {
5806 elem_id = ptr[0];
5807 if (size_of_len_field == TWO_BYTE) {
5808 elem_len = ((uint16_t) ptr[1]) | (ptr[2] << 8);
5809 } else {
5810 elem_len = ptr[1];
5811 }
5812
5813 left -= (size_of_len_field + 1);
5814 if (elem_len > left) {
5815 lim_log(pMac, LOGE,
5816 FL
5817 ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
5818 eid, elem_len, left);
5819 return NULL;
5820 }
5821 if (elem_id == eid) {
5822 return ptr;
5823 }
5824
5825 left -= elem_len;
5826 ptr += (elem_len + (size_of_len_field + 1));
5827 }
5828 return NULL;
5829}
5830
5831/* Returns length of P2P stream and Pointer ie passed to this function is filled with noa stream */
5832
5833uint8_t lim_build_p2p_ie(tpAniSirGlobal pMac, uint8_t *ie, uint8_t *data,
5834 uint8_t ie_len)
5835{
5836 int length = 0;
5837 uint8_t *ptr = ie;
5838
5839 ptr[length++] = SIR_MAC_EID_VENDOR;
5840 ptr[length++] = ie_len + SIR_MAC_P2P_OUI_SIZE;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305841 qdf_mem_copy(&ptr[length], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
5842 qdf_mem_copy(&ptr[length + SIR_MAC_P2P_OUI_SIZE], data, ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005843 return ie_len + SIR_P2P_IE_HEADER_LEN;
5844}
5845
5846/* Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream */
5847
5848uint8_t lim_get_noa_attr_stream_in_mult_p2p_ies(tpAniSirGlobal pMac,
5849 uint8_t *noaStream, uint8_t noaLen,
5850 uint8_t overFlowLen)
5851{
5852 uint8_t overFlowP2pStream[SIR_MAX_NOA_ATTR_LEN];
5853
5854 if ((noaLen <= (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) &&
5855 (noaLen >= overFlowLen) && (overFlowLen <= SIR_MAX_NOA_ATTR_LEN)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305856 qdf_mem_copy(overFlowP2pStream,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005857 noaStream + noaLen - overFlowLen, overFlowLen);
5858 noaStream[noaLen - overFlowLen] = SIR_MAC_EID_VENDOR;
5859 noaStream[noaLen - overFlowLen + 1] =
5860 overFlowLen + SIR_MAC_P2P_OUI_SIZE;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305861 qdf_mem_copy(noaStream + noaLen - overFlowLen + 2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005862 SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305863 qdf_mem_copy(noaStream + noaLen + 2 + SIR_MAC_P2P_OUI_SIZE -
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005864 overFlowLen, overFlowP2pStream, overFlowLen);
5865 }
5866
5867 return noaLen + SIR_P2P_IE_HEADER_LEN;
5868
5869}
5870
5871/* Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream */
5872uint8_t lim_get_noa_attr_stream(tpAniSirGlobal pMac, uint8_t *pNoaStream,
5873 tpPESession psessionEntry)
5874{
5875 uint8_t len = 0;
5876
5877 uint8_t *pBody = pNoaStream;
5878
5879 if ((psessionEntry != NULL) && (psessionEntry->valid) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +05305880 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005881 if ((!(psessionEntry->p2pGoPsUpdate.uNoa1Duration))
5882 && (!(psessionEntry->p2pGoPsUpdate.uNoa2Duration))
5883 && (!psessionEntry->p2pGoPsUpdate.oppPsFlag)
5884 )
5885 return 0; /* No NoA Descriptor then return 0 */
5886
5887 pBody[0] = SIR_P2P_NOA_ATTR;
5888
5889 pBody[3] = psessionEntry->p2pGoPsUpdate.index;
5890 pBody[4] =
5891 psessionEntry->p2pGoPsUpdate.ctWin | (psessionEntry->
5892 p2pGoPsUpdate.
5893 oppPsFlag << 7);
5894 len = 5;
5895 pBody += len;
5896
5897 if (psessionEntry->p2pGoPsUpdate.uNoa1Duration) {
5898 *pBody = psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt;
5899 pBody += 1;
5900 len += 1;
5901
5902 *((uint32_t *) (pBody)) =
5903 sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
5904 uNoa1Duration);
5905 pBody += sizeof(uint32_t);
5906 len += 4;
5907
5908 *((uint32_t *) (pBody)) =
5909 sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
5910 uNoa1Interval);
5911 pBody += sizeof(uint32_t);
5912 len += 4;
5913
5914 *((uint32_t *) (pBody)) =
5915 sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
5916 uNoa1StartTime);
5917 pBody += sizeof(uint32_t);
5918 len += 4;
5919
5920 }
5921
5922 if (psessionEntry->p2pGoPsUpdate.uNoa2Duration) {
5923 *pBody = psessionEntry->p2pGoPsUpdate.uNoa2IntervalCnt;
5924 pBody += 1;
5925 len += 1;
5926
5927 *((uint32_t *) (pBody)) =
5928 sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
5929 uNoa2Duration);
5930 pBody += sizeof(uint32_t);
5931 len += 4;
5932
5933 *((uint32_t *) (pBody)) =
5934 sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
5935 uNoa2Interval);
5936 pBody += sizeof(uint32_t);
5937 len += 4;
5938
5939 *((uint32_t *) (pBody)) =
5940 sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
5941 uNoa2StartTime);
5942 pBody += sizeof(uint32_t);
5943 len += 4;
5944
5945 }
5946
5947 pBody = pNoaStream + 1;
5948 *((uint16_t *) (pBody)) = sir_swap_u16if_needed(len - 3); /*one byte for Attr and 2 bytes for length */
5949
5950 return len;
5951
5952 }
5953 return 0;
5954
5955}
5956
5957void pe_set_resume_channel(tpAniSirGlobal pMac, uint16_t channel,
5958 ePhyChanBondState phyCbState)
5959{
5960
5961 pMac->lim.gResumeChannel = channel;
5962 pMac->lim.gResumePhyCbState = phyCbState;
5963}
5964
5965bool lim_is_noa_insert_reqd(tpAniSirGlobal pMac)
5966{
5967 uint8_t i;
5968 for (i = 0; i < pMac->lim.maxBssId; i++) {
5969 if (pMac->lim.gpSession[i].valid == true) {
5970 if ((eLIM_AP_ROLE ==
5971 pMac->lim.gpSession[i].limSystemRole)
Anurag Chouhan6d760662016-02-20 16:05:43 +05305972 && (QDF_P2P_GO_MODE ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005973 pMac->lim.gpSession[i].pePersona)
5974 ) {
5975 return true;
5976 }
5977 }
5978 }
5979 return false;
5980}
5981
5982bool lim_isconnected_on_dfs_channel(uint8_t currentChannel)
5983{
5984 if (CHANNEL_STATE_DFS ==
5985 cds_get_channel_state(currentChannel)) {
5986 return true;
5987 } else {
5988 return false;
5989 }
5990}
5991
5992#ifdef WLAN_FEATURE_11W
5993void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param)
5994{
5995 tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
5996 tPmfSaQueryTimerId timerId;
5997 tpPESession psessionEntry;
5998 tpDphHashNode pSta;
5999 uint32_t maxRetries;
6000
6001 lim_log(pMac, LOG1, FL("SA Query timer fires"));
6002 timerId.value = param;
6003
6004 /* Check that SA Query is in progress */
6005 psessionEntry = pe_find_session_by_session_id(pMac,
6006 timerId.fields.sessionId);
6007 if (psessionEntry == NULL) {
6008 lim_log(pMac, LOGE,
6009 FL("Session does not exist for given session ID %d"),
6010 timerId.fields.sessionId);
6011 return;
6012 }
6013 pSta = dph_get_hash_entry(pMac, timerId.fields.peerIdx,
6014 &psessionEntry->dph.dphHashTable);
6015 if (pSta == NULL) {
6016 lim_log(pMac, LOGE,
6017 FL("Entry does not exist for given peer index %d"),
6018 timerId.fields.peerIdx);
6019 return;
6020 }
6021 if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
6022 return;
6023
6024 /* Increment the retry count, check if reached maximum */
6025 if (wlan_cfg_get_int(pMac, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
6026 &maxRetries) != eSIR_SUCCESS) {
6027 lim_log(pMac, LOGE,
6028 FL
6029 ("Could not retrieve PMF SA Query maximum retries value"));
6030 pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
6031 return;
6032 }
6033 pSta->pmfSaQueryRetryCount++;
6034 if (pSta->pmfSaQueryRetryCount >= maxRetries) {
6035 lim_log(pMac, LOGE, FL("SA Query timed out,Deleting STA"));
6036 lim_print_mac_addr(pMac, pSta->staAddr, LOGE);
6037 lim_send_disassoc_mgmt_frame(pMac,
6038 eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
6039 pSta->staAddr, psessionEntry, false);
6040 lim_trigger_sta_deletion(pMac, pSta, psessionEntry);
6041 pSta->pmfSaQueryState = DPH_SA_QUERY_TIMED_OUT;
6042 return;
6043 }
6044 /* Retry SA Query */
6045 lim_send_sa_query_request_frame(pMac,
6046 (uint8_t *) &(pSta->
6047 pmfSaQueryCurrentTransId),
6048 pSta->staAddr, psessionEntry);
6049 pSta->pmfSaQueryCurrentTransId++;
6050 lim_log(pMac, LOGE, FL("Starting SA Query retry %d"),
6051 pSta->pmfSaQueryRetryCount);
6052 if (tx_timer_activate(&pSta->pmfSaQueryTimer) != TX_SUCCESS) {
6053 lim_log(pMac, LOGE, FL("PMF SA Query timer activation failed!"));
6054 pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
6055 }
6056}
6057#endif
6058
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006059bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
6060 uint8_t chanWidth, uint8_t staId,
6061 uint8_t *peerMac)
6062{
6063 tUpdateVHTOpMode tempParam;
6064
6065 tempParam.opMode = chanWidth;
6066 tempParam.staId = staId;
6067 tempParam.smesessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306068 qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006069
6070 lim_send_mode_update(pMac, &tempParam, psessionEntry);
6071
6072 return true;
6073}
6074
6075bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
6076 uint8_t rxNss, uint8_t staId, uint8_t *peerMac)
6077{
6078 tUpdateRxNss tempParam;
6079
6080 tempParam.rxNss = rxNss;
6081 tempParam.staId = staId;
6082 tempParam.smesessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306083 qdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006084
6085 lim_send_rx_nss_update(pMac, &tempParam, psessionEntry);
6086
6087 return true;
6088}
6089
6090bool lim_check_membership_user_position(tpAniSirGlobal pMac,
6091 tpPESession psessionEntry,
6092 uint32_t membership, uint32_t userPosition,
6093 uint8_t staId)
6094{
6095 tUpdateMembership tempParamMembership;
6096 tUpdateUserPos tempParamUserPosition;
6097
6098 tempParamMembership.membership = membership;
6099 tempParamMembership.staId = staId;
6100 tempParamMembership.smesessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306101 qdf_mem_copy(tempParamMembership.peer_mac, psessionEntry->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006102 sizeof(tSirMacAddr));
6103
6104 lim_set_membership(pMac, &tempParamMembership, psessionEntry);
6105
6106 tempParamUserPosition.userPos = userPosition;
6107 tempParamUserPosition.staId = staId;
6108 tempParamUserPosition.smesessionId = psessionEntry->smeSessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306109 qdf_mem_copy(tempParamUserPosition.peer_mac, psessionEntry->bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006110 sizeof(tSirMacAddr));
6111
6112 lim_set_user_pos(pMac, &tempParamUserPosition, psessionEntry);
6113
6114 return true;
6115}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006116
6117void lim_get_short_slot_from_phy_mode(tpAniSirGlobal pMac, tpPESession psessionEntry,
6118 uint32_t phyMode, uint8_t *pShortSlotEnabled)
6119{
6120 uint8_t val = 0;
6121
6122 /* only 2.4G band should have short slot enable, rest it should be default */
6123 if (phyMode == WNI_CFG_PHY_MODE_11G) {
6124 /* short slot is default in all other modes */
Anurag Chouhan6d760662016-02-20 16:05:43 +05306125 if ((psessionEntry->pePersona == QDF_SAP_MODE) ||
6126 (psessionEntry->pePersona == QDF_IBSS_MODE) ||
6127 (psessionEntry->pePersona == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006128 val = true;
6129 }
6130 /* Program Polaris based on AP capability */
6131 if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
6132 /* Joining BSS. */
6133 val =
6134 SIR_MAC_GET_SHORT_SLOT_TIME(psessionEntry->
6135 limCurrentBssCaps);
6136 } else if (psessionEntry->limMlmState ==
6137 eLIM_MLM_WT_REASSOC_RSP_STATE) {
6138 /* Reassociating with AP. */
6139 val =
6140 SIR_MAC_GET_SHORT_SLOT_TIME(psessionEntry->
6141 limReassocBssCaps);
6142 }
6143 } else {
6144 /*
6145 * 11B does not short slot and short slot is default
6146 * for 11A mode. Hence, not need to set this bit
6147 */
6148 val = false;
6149 }
6150
6151 lim_log(pMac, LOG1, FL("phyMode = %u shortslotsupported = %u"), phyMode,
6152 val);
6153 *pShortSlotEnabled = val;
6154}
6155
6156#ifdef WLAN_FEATURE_11W
6157/**
6158 *
6159 * \brief This function is called by various LIM modules to correctly set
6160 * the Protected bit in the Frame Control Field of the 802.11 frame MAC header
6161 *
6162 *
6163 * \param pMac Pointer to Global MAC structure
6164 *
6165 * \param psessionEntry Pointer to session corresponding to the connection
6166 *
6167 * \param peer Peer address of the STA to which the frame is to be sent
6168 *
6169 * \param pMacHdr Pointer to the frame MAC header
6170 *
6171 * \return nothing
6172 *
6173 *
6174 */
6175void
6176lim_set_protected_bit(tpAniSirGlobal pMac,
6177 tpPESession psessionEntry,
6178 tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr)
6179{
6180 uint16_t aid;
6181 tpDphHashNode pStaDs;
6182
Rajeev Kumar0ac9f2a2016-04-15 15:54:18 -07006183 if (LIM_IS_AP_ROLE(psessionEntry)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006184
6185 pStaDs = dph_lookup_hash_entry(pMac, peer, &aid,
6186 &psessionEntry->dph.dphHashTable);
6187 if (pStaDs != NULL) {
6188 /* rmfenabled will be set at the time of addbss.
6189 * but sometimes EAP auth fails and keys are not
6190 * installed then if we send any management frame
6191 * like deauth/disassoc with this bit set then
6192 * firmware crashes. so check for keys are
6193 * installed or not also before setting the bit
6194 */
6195 if (pStaDs->rmfEnabled && pStaDs->is_key_installed)
6196 pMacHdr->fc.wep = 1;
6197 }
6198 } else if (psessionEntry->limRmfEnabled &&
6199 psessionEntry->is_key_installed) {
6200 pMacHdr->fc.wep = 1;
6201 }
6202} /*** end lim_set_protected_bit() ***/
6203#endif
6204
6205void lim_set_ht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
6206 uint8_t *p_ie_start, uint32_t num_bytes)
6207{
6208 uint8_t *p_ie = NULL;
6209 tDot11fIEHTCaps dot11_ht_cap = {0,};
6210
6211 populate_dot11f_ht_caps(p_mac, p_session_entry, &dot11_ht_cap);
6212 p_ie = lim_get_ie_ptr_new(p_mac, p_ie_start, num_bytes,
6213 DOT11F_EID_HTCAPS, ONE_BYTE);
6214 lim_log(p_mac, LOG2, FL("p_ie %p dot11_ht_cap.supportedMCSSet[0]=0x%x"),
6215 p_ie, dot11_ht_cap.supportedMCSSet[0]);
6216 if (p_ie) {
6217 /* convert from unpacked to packed structure */
6218 tHtCaps *p_ht_cap = (tHtCaps *) &p_ie[2];
6219
6220 p_ht_cap->advCodingCap = dot11_ht_cap.advCodingCap;
6221 p_ht_cap->supportedChannelWidthSet =
6222 dot11_ht_cap.supportedChannelWidthSet;
6223 p_ht_cap->mimoPowerSave = dot11_ht_cap.mimoPowerSave;
6224 p_ht_cap->greenField = dot11_ht_cap.greenField;
6225 p_ht_cap->shortGI20MHz = dot11_ht_cap.shortGI20MHz;
6226 p_ht_cap->shortGI40MHz = dot11_ht_cap.shortGI40MHz;
6227 p_ht_cap->txSTBC = dot11_ht_cap.txSTBC;
6228 p_ht_cap->rxSTBC = dot11_ht_cap.rxSTBC;
6229 p_ht_cap->delayedBA = dot11_ht_cap.delayedBA;
6230 p_ht_cap->maximalAMSDUsize = dot11_ht_cap.maximalAMSDUsize;
6231 p_ht_cap->dsssCckMode40MHz = dot11_ht_cap.dsssCckMode40MHz;
6232 p_ht_cap->psmp = dot11_ht_cap.psmp;
6233 p_ht_cap->stbcControlFrame = dot11_ht_cap.stbcControlFrame;
6234 p_ht_cap->lsigTXOPProtection = dot11_ht_cap.lsigTXOPProtection;
6235 p_ht_cap->maxRxAMPDUFactor = dot11_ht_cap.maxRxAMPDUFactor;
6236 p_ht_cap->mpduDensity = dot11_ht_cap.mpduDensity;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306237 qdf_mem_copy((void *)p_ht_cap->supportedMCSSet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006238 (void *)(dot11_ht_cap.supportedMCSSet),
6239 sizeof(p_ht_cap->supportedMCSSet));
6240 p_ht_cap->pco = dot11_ht_cap.pco;
6241 p_ht_cap->transitionTime = dot11_ht_cap.transitionTime;
6242 p_ht_cap->mcsFeedback = dot11_ht_cap.mcsFeedback;
6243 p_ht_cap->txBF = dot11_ht_cap.txBF;
6244 p_ht_cap->rxStaggeredSounding =
6245 dot11_ht_cap.rxStaggeredSounding;
6246 p_ht_cap->txStaggeredSounding =
6247 dot11_ht_cap.txStaggeredSounding;
6248 p_ht_cap->rxZLF = dot11_ht_cap.rxZLF;
6249 p_ht_cap->txZLF = dot11_ht_cap.txZLF;
6250 p_ht_cap->implicitTxBF = dot11_ht_cap.implicitTxBF;
6251 p_ht_cap->calibration = dot11_ht_cap.calibration;
6252 p_ht_cap->explicitCSITxBF = dot11_ht_cap.explicitCSITxBF;
6253 p_ht_cap->explicitUncompressedSteeringMatrix =
6254 dot11_ht_cap.explicitUncompressedSteeringMatrix;
6255 p_ht_cap->explicitBFCSIFeedback =
6256 dot11_ht_cap.explicitBFCSIFeedback;
6257 p_ht_cap->explicitUncompressedSteeringMatrixFeedback =
6258 dot11_ht_cap.explicitUncompressedSteeringMatrixFeedback;
6259 p_ht_cap->explicitCompressedSteeringMatrixFeedback =
6260 dot11_ht_cap.explicitCompressedSteeringMatrixFeedback;
6261 p_ht_cap->csiNumBFAntennae = dot11_ht_cap.csiNumBFAntennae;
6262 p_ht_cap->uncompressedSteeringMatrixBFAntennae =
6263 dot11_ht_cap.uncompressedSteeringMatrixBFAntennae;
6264 p_ht_cap->compressedSteeringMatrixBFAntennae =
6265 dot11_ht_cap.compressedSteeringMatrixBFAntennae;
6266 p_ht_cap->antennaSelection = dot11_ht_cap.antennaSelection;
6267 p_ht_cap->explicitCSIFeedbackTx =
6268 dot11_ht_cap.explicitCSIFeedbackTx;
6269 p_ht_cap->antennaIndicesFeedbackTx =
6270 dot11_ht_cap.antennaIndicesFeedbackTx;
6271 p_ht_cap->explicitCSIFeedback =
6272 dot11_ht_cap.explicitCSIFeedback;
6273 p_ht_cap->antennaIndicesFeedback =
6274 dot11_ht_cap.antennaIndicesFeedback;
6275 p_ht_cap->rxAS = dot11_ht_cap.rxAS;
6276 p_ht_cap->txSoundingPPDUs = dot11_ht_cap.txSoundingPPDUs;
6277 }
6278}
6279
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006280void lim_set_vht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
6281 uint8_t *p_ie_start, uint32_t num_bytes)
6282{
6283 uint8_t *p_ie = NULL;
6284 tDot11fIEVHTCaps dot11_vht_cap;
6285
6286 populate_dot11f_vht_caps(p_mac, p_session_entry, &dot11_vht_cap);
6287 p_ie = lim_get_ie_ptr_new(p_mac, p_ie_start, num_bytes,
6288 DOT11F_EID_VHTCAPS, ONE_BYTE);
6289
6290 if (p_ie) {
6291 tSirMacVHTCapabilityInfo *vht_cap =
6292 (tSirMacVHTCapabilityInfo *) &p_ie[2];
6293 tSirVhtMcsInfo *vht_mcs = (tSirVhtMcsInfo *) &p_ie[2 +
6294 sizeof(tSirMacVHTCapabilityInfo)];
6295
6296 union {
6297 uint16_t u_value;
6298 tSirMacVHTRxSupDataRateInfo vht_rx_supp_rate;
6299 tSirMacVHTTxSupDataRateInfo vht_tx_supp_rate;
6300 } u_vht_data_rate_info;
6301
6302 vht_cap->maxMPDULen = dot11_vht_cap.maxMPDULen;
6303 vht_cap->supportedChannelWidthSet =
6304 dot11_vht_cap.supportedChannelWidthSet;
6305 vht_cap->ldpcCodingCap = dot11_vht_cap.ldpcCodingCap;
6306 vht_cap->shortGI80MHz = dot11_vht_cap.shortGI80MHz;
6307 vht_cap->shortGI160and80plus80MHz =
6308 dot11_vht_cap.shortGI160and80plus80MHz;
6309 vht_cap->txSTBC = dot11_vht_cap.txSTBC;
6310 vht_cap->rxSTBC = dot11_vht_cap.rxSTBC;
6311 vht_cap->suBeamFormerCap = dot11_vht_cap.suBeamFormerCap;
6312 vht_cap->suBeamformeeCap = dot11_vht_cap.suBeamformeeCap;
6313 vht_cap->csnofBeamformerAntSup =
6314 dot11_vht_cap.csnofBeamformerAntSup;
6315 vht_cap->numSoundingDim = dot11_vht_cap.numSoundingDim;
6316 vht_cap->muBeamformerCap = dot11_vht_cap.muBeamformerCap;
6317 vht_cap->muBeamformeeCap = dot11_vht_cap.muBeamformeeCap;
6318 vht_cap->vhtTXOPPS = dot11_vht_cap.vhtTXOPPS;
6319 vht_cap->htcVHTCap = dot11_vht_cap.htcVHTCap;
6320 vht_cap->maxAMPDULenExp = dot11_vht_cap.maxAMPDULenExp;
6321 vht_cap->vhtLinkAdaptCap = dot11_vht_cap.vhtLinkAdaptCap;
6322 vht_cap->rxAntPattern = dot11_vht_cap.rxAntPattern;
6323 vht_cap->txAntPattern = dot11_vht_cap.txAntPattern;
6324 vht_cap->reserved1 = dot11_vht_cap.reserved1;
6325
6326 /* Populate VHT MCS Information */
6327 vht_mcs->rxMcsMap = dot11_vht_cap.rxMCSMap;
6328 u_vht_data_rate_info.vht_rx_supp_rate.rxSupDataRate =
6329 dot11_vht_cap.rxHighSupDataRate;
6330 u_vht_data_rate_info.vht_rx_supp_rate.reserved =
6331 dot11_vht_cap.reserved2;
6332 vht_mcs->rxHighest = u_vht_data_rate_info.u_value;
6333
6334 vht_mcs->txMcsMap = dot11_vht_cap.txMCSMap;
6335 u_vht_data_rate_info.vht_tx_supp_rate.txSupDataRate =
6336 dot11_vht_cap.txSupDataRate;
6337 u_vht_data_rate_info.vht_tx_supp_rate.reserved =
6338 dot11_vht_cap.reserved3;
6339 vht_mcs->txHighest = u_vht_data_rate_info.u_value;
6340 }
6341}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006342
6343/**
6344 * lim_validate_received_frame_a1_addr() - To validate received frame's A1 addr
6345 * @mac_ctx: pointer to mac context
6346 * @a1: received frame's a1 address which is nothing but our self address
6347 * @session: PE session pointer
6348 *
6349 * This routine will validate, A1 addres of the received frame
6350 *
6351 * Return: true or false
6352 */
6353bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx,
6354 tSirMacAddr a1, tpPESession session)
6355{
6356 if (mac_ctx == NULL || session == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306357 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006358 "mac or session context is null");
6359 /* let main routine handle it */
6360 return true;
6361 }
6362 if (lim_is_group_addr(a1) || lim_is_addr_bc(a1)) {
6363 /* just for fail safe, don't handle MC/BC a1 in this routine */
6364 return true;
6365 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306366 if (qdf_mem_cmp(a1, session->selfMacAddr, 6)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006367 lim_log(mac_ctx, LOGE,
6368 FL("Invalid A1 address in received frame"));
6369 return false;
6370 }
6371 return true;
6372}
6373
6374/**
6375 * lim_check_and_reset_protection_params() - reset protection related parameters
6376 *
6377 * @mac_ctx: pointer to global mac structure
6378 *
6379 * resets protection related global parameters if the pe active session count
6380 * is zero.
6381 *
6382 * Return: None
6383 */
6384void lim_check_and_reset_protection_params(tpAniSirGlobal mac_ctx)
6385{
6386 if (!pe_get_active_session_count(mac_ctx)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306387 qdf_mem_zero(&mac_ctx->lim.gLimOverlap11gParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006388 sizeof(mac_ctx->lim.gLimOverlap11gParams));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306389 qdf_mem_zero(&mac_ctx->lim.gLimOverlap11aParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006390 sizeof(mac_ctx->lim.gLimOverlap11aParams));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306391 qdf_mem_zero(&mac_ctx->lim.gLimOverlapHt20Params,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006392 sizeof(mac_ctx->lim.gLimOverlapHt20Params));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306393 qdf_mem_zero(&mac_ctx->lim.gLimOverlapNonGfParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006394 sizeof(mac_ctx->lim.gLimOverlapNonGfParams));
6395
6396 mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
6397 }
6398}
6399
6400/**
6401 * lim_set_stads_rtt_cap() - update station node RTT capability
6402 * @sta_ds: Station hash node
6403 * @ext_cap: Pointer to extended capability
6404 * @mac_ctx: global MAC context
6405 *
6406 * This funciton update hash node's RTT capability based on received
6407 * Extended capability IE.
6408 *
6409 * Return: None
6410 */
6411void lim_set_stads_rtt_cap(tpDphHashNode sta_ds, struct s_ext_cap *ext_cap,
6412 tpAniSirGlobal mac_ctx)
6413{
6414 sta_ds->timingMeasCap = 0;
6415 sta_ds->timingMeasCap |= (ext_cap->timing_meas) ?
6416 RTT_TIMING_MEAS_CAPABILITY :
6417 RTT_INVALID;
6418 sta_ds->timingMeasCap |= (ext_cap->fine_time_meas_initiator) ?
6419 RTT_FINE_TIME_MEAS_INITIATOR_CAPABILITY :
6420 RTT_INVALID;
6421 sta_ds->timingMeasCap |= (ext_cap->fine_time_meas_responder) ?
6422 RTT_FINE_TIME_MEAS_RESPONDER_CAPABILITY :
6423 RTT_INVALID;
6424
6425 lim_log(mac_ctx, LOG1,
6426 FL("ExtCap present, timingMeas: %d Initiator: %d Responder: %d"),
6427 ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
6428 ext_cap->fine_time_meas_responder);
6429}
6430
6431/**
6432 * lim_send_ext_cap_ie() - send ext cap IE to FW
6433 * @mac_ctx: global MAC context
6434 * @session_entry: PE session
6435 * @extra_extcap: extracted ext cap
6436 * @merge: merge extra ext cap
6437 *
6438 * This function is invoked after VDEV is created to update firmware
6439 * about the extended capabilities that the corresponding VDEV is capable
6440 * of. Since STA/SAP can have different Extended capabilities set, this function
6441 * is called per vdev creation.
6442 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306443 * Return: QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006444 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306445QDF_STATUS lim_send_ext_cap_ie(tpAniSirGlobal mac_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006446 uint32_t session_id,
6447 tDot11fIEExtCap *extra_extcap, bool merge)
6448{
6449 tDot11fIEExtCap ext_cap_data = {0};
6450 uint32_t dot11mode, num_bytes;
6451 bool vht_enabled = false;
6452 struct vdev_ie_info *vdev_ie;
6453 cds_msg_t msg = {0};
6454 tSirRetStatus status;
6455 uint8_t *temp, i;
6456
6457 wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode);
6458 if (IS_DOT11_MODE_VHT(dot11mode))
6459 vht_enabled = true;
6460
6461 status = populate_dot11f_ext_cap(mac_ctx, vht_enabled, &ext_cap_data,
6462 NULL);
6463 if (eSIR_SUCCESS != status) {
6464 lim_log(mac_ctx, LOGE, FL("Failed to populate ext cap IE"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306465 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006466 }
6467
6468 num_bytes = ext_cap_data.num_bytes;
6469
6470 if (merge && NULL != extra_extcap && extra_extcap->num_bytes > 0) {
6471 if (extra_extcap->num_bytes > ext_cap_data.num_bytes)
6472 num_bytes = extra_extcap->num_bytes;
6473 lim_merge_extcap_struct(&ext_cap_data, extra_extcap);
6474 }
6475
6476 /* Allocate memory for the WMI request, and copy the parameter */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306477 vdev_ie = qdf_mem_malloc(sizeof(*vdev_ie) + num_bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006478 if (!vdev_ie) {
6479 lim_log(mac_ctx, LOGE, FL("Failed to allocate memory"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306480 return QDF_STATUS_E_NOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006481 }
6482
6483 vdev_ie->vdev_id = session_id;
6484 vdev_ie->ie_id = DOT11F_EID_EXTCAP;
6485 vdev_ie->length = num_bytes;
6486
6487 lim_log(mac_ctx, LOG1, FL("vdev %d ieid %d len %d"), session_id,
6488 DOT11F_EID_EXTCAP, num_bytes);
6489 temp = ext_cap_data.bytes;
6490 for (i = 0; i < num_bytes; i++, temp++)
6491 lim_log(mac_ctx, LOG1, FL("%d byte is %02x"), i+1, *temp);
6492
6493 vdev_ie->data = (uint8_t *)vdev_ie + sizeof(*vdev_ie);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306494 qdf_mem_copy(vdev_ie->data, ext_cap_data.bytes, num_bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006495
6496 msg.type = WMA_SET_IE_INFO;
6497 msg.bodyptr = vdev_ie;
6498 msg.reserved = 0;
6499
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306500 if (QDF_STATUS_SUCCESS !=
Anurag Chouhan6d760662016-02-20 16:05:43 +05306501 cds_mq_post_message(QDF_MODULE_ID_WMA, &msg)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006502 lim_log(mac_ctx, LOGE,
6503 FL("Not able to post WMA_SET_IE_INFO to WDA"));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306504 qdf_mem_free(vdev_ie);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306505 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006506 }
6507
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306508 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006509}
6510
6511/**
6512 * lim_strip_extcap_ie() - strip extended capability IE from IE buffer
6513 * @mac_ctx: global MAC context
6514 * @addn_ie: Additional IE buffer
6515 * @addn_ielen: Length of additional IE
6516 * @extracted_ie: if not NULL, copy the stripped IE to this buffer
6517 *
6518 * This utility function is used to strip of the extended capability IE present
6519 * in additional IE buffer.
6520 *
6521 * Return: tSirRetStatus
6522 */
6523tSirRetStatus lim_strip_extcap_ie(tpAniSirGlobal mac_ctx,
6524 uint8_t *addn_ie, uint16_t *addn_ielen, uint8_t *extracted_ie)
6525{
6526 uint8_t *tempbuf = NULL;
6527 uint16_t templen = 0;
6528 int left = *addn_ielen;
6529 uint8_t *ptr = addn_ie;
6530 uint8_t elem_id, elem_len;
6531
6532 if (NULL == addn_ie) {
6533 lim_log(mac_ctx, LOG1, FL("NULL addn_ie pointer"));
6534 return eSIR_IGNORE_IE;
6535 }
6536
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306537 tempbuf = qdf_mem_malloc(left);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006538 if (NULL == tempbuf) {
6539 lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
6540 return eSIR_MEM_ALLOC_FAILED;
6541 }
6542
6543 while (left >= 2) {
6544 elem_id = ptr[0];
6545 elem_len = ptr[1];
6546 left -= 2;
6547 if (elem_len > left) {
6548 lim_log(mac_ctx, LOGE,
6549 FL("Invalid IEs eid = %d elem_len=%d left=%d"),
6550 elem_id, elem_len, left);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306551 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006552 return eSIR_FAILURE;
6553 }
6554 if (!(DOT11F_EID_EXTCAP == elem_id)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306555 qdf_mem_copy(tempbuf + templen, &ptr[0], elem_len + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006556 templen += (elem_len + 2);
6557 } else {
6558 if (NULL != extracted_ie) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306559 qdf_mem_set(extracted_ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006560 DOT11F_IE_EXTCAP_MAX_LEN + 2, 0);
6561 if (elem_len <= DOT11F_IE_EXTCAP_MAX_LEN)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306562 qdf_mem_copy(extracted_ie, &ptr[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006563 elem_len + 2);
6564 }
6565 }
6566 left -= elem_len;
6567 ptr += (elem_len + 2);
6568 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306569 qdf_mem_copy(addn_ie, tempbuf, templen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006570
6571 *addn_ielen = templen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306572 qdf_mem_free(tempbuf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006573
6574 return eSIR_SUCCESS;
6575}
6576
6577/**
6578 * lim_update_extcap_struct() - poputlate the dot11f structure
6579 * @mac_ctx: global MAC context
6580 * @buf: extracted IE buffer
6581 * @dst: extended capability IE structure to be updated
6582 *
6583 * This function is used to update the extended capability structure
6584 * with @buf.
6585 *
6586 * Return: None
6587 */
6588void lim_update_extcap_struct(tpAniSirGlobal mac_ctx,
6589 uint8_t *buf, tDot11fIEExtCap *dst)
6590{
6591 uint8_t out[DOT11F_IE_EXTCAP_MAX_LEN];
6592
6593 if (NULL == buf) {
6594 lim_log(mac_ctx, LOGE, FL("Invalid Buffer Address"));
6595 return;
6596 }
6597
6598 if (NULL == dst) {
6599 lim_log(mac_ctx, LOGE, FL("NULL dst pointer"));
6600 return;
6601 }
6602
6603 if (DOT11F_EID_EXTCAP != buf[0] || buf[1] > DOT11F_IE_EXTCAP_MAX_LEN) {
6604 lim_log(mac_ctx, LOG1, FL("Invalid IEs eid = %d elem_len=%d "),
6605 buf[0], buf[1]);
6606 return;
6607 }
6608
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306609 qdf_mem_set((uint8_t *)&out[0], DOT11F_IE_EXTCAP_MAX_LEN, 0);
6610 qdf_mem_copy(&out[0], &buf[2], DOT11F_IE_EXTCAP_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006611
6612 if (DOT11F_PARSE_SUCCESS != dot11f_unpack_ie_ext_cap(mac_ctx, &out[0],
6613 DOT11F_IE_EXTCAP_MAX_LEN, dst))
6614 lim_log(mac_ctx, LOGE, FL("dot11f_unpack Parse Error "));
6615}
6616
6617/**
6618 * lim_strip_extcap_update_struct - strip extended capability IE and populate
6619 * the dot11f structure
6620 * @mac_ctx: global MAC context
6621 * @addn_ie: Additional IE buffer
6622 * @addn_ielen: Length of additional IE
6623 * @dst: extended capability IE structure to be updated
6624 *
6625 * This function is used to strip extended capability IE from IE buffer and
6626 * update the passed structure.
6627 *
6628 * Return: tSirRetStatus
6629 */
6630tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
6631 uint8_t *addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst)
6632{
6633 uint8_t extracted_buff[DOT11F_IE_EXTCAP_MAX_LEN + 2];
6634 tSirRetStatus status;
6635
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306636 qdf_mem_set((uint8_t *)&extracted_buff[0], DOT11F_IE_EXTCAP_MAX_LEN + 2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006637 0);
6638 status = lim_strip_extcap_ie(mac_ctx, addn_ie, addn_ielen,
6639 extracted_buff);
6640 if (eSIR_SUCCESS != status) {
6641 lim_log(mac_ctx, LOG1,
6642 FL("Failed to strip extcap IE status = (%d)."), status);
6643 return status;
6644 }
6645
6646 /* update the extracted ExtCap to struct*/
6647 lim_update_extcap_struct(mac_ctx, extracted_buff, dst);
6648 return status;
6649}
6650
6651/**
6652 * lim_merge_extcap_struct() - merge extended capabilities info
6653 * @dst: destination extended capabilities
6654 * @src: source extended capabilities
6655 *
6656 * This function is used to take @src info and merge it with @dst
6657 * extended capabilities info.
6658 *
6659 * Return: None
6660 */
6661void lim_merge_extcap_struct(tDot11fIEExtCap *dst,
6662 tDot11fIEExtCap *src)
6663{
6664 uint8_t *tempdst = (uint8_t *)dst->bytes;
6665 uint8_t *tempsrc = (uint8_t *)src->bytes;
6666 uint8_t structlen = member_size(tDot11fIEExtCap, bytes);
6667
6668 while (tempdst && tempsrc && structlen--) {
6669 *tempdst |= *tempsrc;
6670 tempdst++;
6671 tempsrc++;
6672 }
6673}
6674
Naveen Rawatc0c91cd2015-11-05 14:27:37 -08006675/**
6676 * lim_get_80Mhz_center_channel - finds 80 Mhz center channel
6677 *
6678 * @primary_channel: Primary channel for given 80 MHz band
6679 *
6680 * There are fixed 80MHz band and for each fixed band there is only one center
6681 * valid channel. Also location of primary channel decides what 80 MHz band will
6682 * it use, hence it decides what center channel will be used. This function
6683 * does thus calculation and returns the center channel.
6684 *
6685 * Return: center channel
6686 */
6687uint8_t
6688lim_get_80Mhz_center_channel(uint8_t primary_channel)
6689{
6690 if (primary_channel >= 36 && primary_channel <= 48)
6691 return (36+48)/2;
6692 if (primary_channel >= 52 && primary_channel <= 64)
6693 return (52+64)/2;
6694 if (primary_channel >= 100 && primary_channel <= 112)
6695 return (100+112)/2;
6696 if (primary_channel >= 116 && primary_channel <= 128)
6697 return (116+128)/2;
6698 if (primary_channel >= 132 && primary_channel <= 144)
6699 return (132+144)/2;
6700 if (primary_channel >= 149 && primary_channel <= 161)
6701 return (149+161)/2;
6702
6703 return INVALID_CHANNEL_ID;
6704}
Sreelakshmi Konamki39acb132015-12-16 13:06:22 +05306705
6706/**
6707 * lim_scan_type_to_string(): converts scan type enum to string.
6708 * @scan_type: enum value of scan_type.
6709 *
6710 * Return: Printable string for scan_type
6711 */
6712const char *lim_scan_type_to_string(const uint8_t scan_type)
6713{
6714 switch (scan_type) {
6715 CASE_RETURN_STRING(eSIR_PASSIVE_SCAN);
6716 CASE_RETURN_STRING(eSIR_ACTIVE_SCAN);
6717 CASE_RETURN_STRING(eSIR_BEACON_TABLE);
6718 default:
6719 return "Unknown scan_type";
6720 }
6721}
6722
6723/**
6724 * lim_bss_type_to_string(): converts bss type enum to string.
6725 * @bss_type: enum value of bss_type.
6726 *
6727 * Return: Printable string for bss_type
6728 */
6729const char *lim_bss_type_to_string(const uint16_t bss_type)
6730{
6731 switch (bss_type) {
6732 CASE_RETURN_STRING(eSIR_INFRASTRUCTURE_MODE);
6733 CASE_RETURN_STRING(eSIR_INFRA_AP_MODE);
6734 CASE_RETURN_STRING(eSIR_IBSS_MODE);
Sreelakshmi Konamki39acb132015-12-16 13:06:22 +05306735 CASE_RETURN_STRING(eSIR_AUTO_MODE);
6736 default:
6737 return "Unknown bss_type";
6738 }
6739}
Sandeep Puligillae0875662016-02-12 16:09:21 -08006740
6741/**
6742 * lim_init_obss_params(): Initializes the OBSS Scan Parameters
6743 * @sesssion: LIM session
6744 * @mac_ctx: Mac context
6745 *
6746 * Return: None
6747 */
6748void lim_init_obss_params(tpAniSirGlobal mac_ctx, tpPESession session)
6749{
6750 uint32_t cfg_value;
6751
6752 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME,
6753 &cfg_value) != eSIR_SUCCESS) {
6754 lim_log(mac_ctx, LOGE,
6755 FL("Fail to retrieve %x value"),
6756 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME);
6757 return;
6758 }
6759 session->obss_ht40_scanparam.obss_active_dwelltime = cfg_value;
6760
6761 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME,
6762 &cfg_value) != eSIR_SUCCESS) {
6763 lim_log(mac_ctx, LOGE,
6764 FL("Fail to retrieve %x value"),
6765 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME);
6766 return;
6767 }
6768 session->obss_ht40_scanparam.obss_passive_dwelltime = cfg_value;
6769
6770 if (wlan_cfg_get_int(mac_ctx,
6771 WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL,
6772 &cfg_value) != eSIR_SUCCESS) {
6773 lim_log(mac_ctx, LOGE,
6774 FL("Fail to retrieve %x value"),
6775 WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL);
6776 return;
6777 }
6778 session->obss_ht40_scanparam.obss_width_trigger_interval = cfg_value;
6779 if (wlan_cfg_get_int(mac_ctx,
6780 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL,
6781 &cfg_value) != eSIR_SUCCESS) {
6782 lim_log(mac_ctx, LOGE,
6783 FL("Fail to retrieve %x value"),
6784 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL);
6785 return;
6786 }
6787 session->obss_ht40_scanparam.obss_active_total_per_channel = cfg_value;
6788 if (wlan_cfg_get_int(mac_ctx,
6789 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, &cfg_value)
6790 != eSIR_SUCCESS) {
6791 lim_log(mac_ctx, LOGE,
6792 FL("Fail to retrieve %x value"),
6793 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL);
6794 return;
6795 }
6796 session->obss_ht40_scanparam.obss_passive_total_per_channel = cfg_value;
6797
6798 if (wlan_cfg_get_int(mac_ctx,
6799 WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY, &cfg_value)
6800 != eSIR_SUCCESS) {
6801 lim_log(mac_ctx, LOGE,
6802 FL("Fail to retrieve %x value"),
6803 WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY);
6804 return;
6805 }
6806 session->obss_ht40_scanparam.bsswidth_ch_trans_delay =
6807 cfg_value;
6808
6809 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD,
6810 &cfg_value) != eSIR_SUCCESS) {
6811 lim_log(mac_ctx, LOGE,
6812 FL("Fail to retrieve %x value"),
6813 WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD);
6814 return;
6815 }
6816 session->obss_ht40_scanparam.obss_activity_threshold = cfg_value;
6817}
6818
6819/**
6820 * lim_update_obss_scanparams(): Updates OBSS SCAN IE parameters to session
6821 * @sesssion: LIM session
6822 * @scan_params: Scan parameters
6823 *
6824 * Return: None
6825 */
6826void lim_update_obss_scanparams(tpPESession session,
6827 tDot11fIEOBSSScanParameters *scan_params)
6828{
6829 /*
6830 * If the recieved value is not in the range specified
6831 * by the Specification then it will be the default value
6832 * configured through cfg
6833 */
6834 if ((scan_params->obssScanActiveDwell >
6835 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN) &&
6836 (scan_params->obssScanActiveDwell <
6837 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX))
6838 session->obss_ht40_scanparam.obss_active_dwelltime =
6839 scan_params->obssScanActiveDwell;
6840
6841 if ((scan_params->obssScanPassiveDwell >
6842 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN) &&
6843 (scan_params->obssScanPassiveDwell <
6844 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX))
6845 session->obss_ht40_scanparam.obss_active_dwelltime =
6846 scan_params->obssScanPassiveDwell;
6847
6848 if ((scan_params->bssWidthChannelTransitionDelayFactor >
6849 WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMIN) &&
6850 (scan_params->bssWidthChannelTransitionDelayFactor <
6851 WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMAX))
6852 session->obss_ht40_scanparam.bsswidth_ch_trans_delay =
6853 scan_params->bssWidthChannelTransitionDelayFactor;
6854
6855 if ((scan_params->obssScanActiveTotalPerChannel >
6856 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN) &&
6857 (scan_params->obssScanActiveTotalPerChannel <
6858 WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX))
6859 session->obss_ht40_scanparam.obss_active_total_per_channel =
6860 scan_params->obssScanActiveTotalPerChannel;
6861
6862 if ((scan_params->obssScanPassiveTotalPerChannel >
6863 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN) &&
6864 (scan_params->obssScanPassiveTotalPerChannel <
6865 WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX))
6866 session->obss_ht40_scanparam.obss_passive_total_per_channel =
6867 scan_params->obssScanPassiveTotalPerChannel;
6868
6869 if ((scan_params->bssChannelWidthTriggerScanInterval >
6870 WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN) &&
6871 (scan_params->bssChannelWidthTriggerScanInterval <
6872 WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX))
6873 session->obss_ht40_scanparam.obss_width_trigger_interval =
6874 scan_params->bssChannelWidthTriggerScanInterval;
6875
6876 if ((scan_params->obssScanActivityThreshold >
6877 WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN) &&
6878 (scan_params->obssScanActivityThreshold <
6879 WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX))
6880 session->obss_ht40_scanparam.obss_activity_threshold =
6881 scan_params->obssScanActivityThreshold;
6882 return;
6883}
Rajeev Kumar03200802016-04-15 13:59:36 -07006884
6885/**
6886 * lim_is_robust_mgmt_action_frame() - Check if action category is
6887 * robust action frame
6888 * @action_category: Action frame category.
6889 *
6890 * This function is used to check if given action category is robust
6891 * action frame.
6892 *
6893 * Return: bool
6894 */
6895bool lim_is_robust_mgmt_action_frame(uint8_t action_category)
6896{
6897 switch (action_category) {
6898 /*
6899 * NOTE: This function doesn't take care of the DMG
6900 * (Directional Multi-Gigatbit) BSS case as 8011ad
6901 * support is not yet added. In future, if the support
6902 * is required then this function need few more arguments
6903 * and little change in logic.
6904 */
6905 case SIR_MAC_ACTION_SPECTRUM_MGMT:
6906 case SIR_MAC_ACTION_QOS_MGMT:
6907 case SIR_MAC_ACTION_DLP:
6908 case SIR_MAC_ACTION_BLKACK:
6909 case SIR_MAC_ACTION_RRM:
6910 case SIR_MAC_ACTION_FAST_BSS_TRNST:
6911 case SIR_MAC_ACTION_SA_QUERY:
6912 case SIR_MAC_ACTION_PROT_DUAL_PUB:
6913 case SIR_MAC_ACTION_WNM:
6914 case SIR_MAC_ACITON_MESH:
6915 case SIR_MAC_ACTION_MHF:
6916 case SIR_MAC_ACTION_FST:
6917 return true;
6918 default:
6919 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
6920 FL("non-PMF action category[%d] "),
6921 action_category);
6922 break;
6923 }
6924 return false;
6925}