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