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