blob: 9bc6c19abb7889c112b2e8568d8f5e1c5b3b9607 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * Airgo Networks, Inc proprietary. All rights reserved.
24 * This file limApi.cc contains the functions that are
25 * exported by LIM to other modules.
26 *
27 * Author: Chandra Modumudi
28 * Date: 02/11/02
29 * History:-
30 * Date Modified by Modification Information
31 * --------------------------------------------------------------------
32 *
33 */
34#include "palTypes.h"
35#ifdef ANI_PRODUCT_TYPE_AP
36#include "wniCfgAp.h"
37#else
38#include "wniCfgSta.h"
39#include "wniApi.h"
40#endif
41#include "sirCommon.h"
42#include "sirDebug.h"
43#include "aniParam.h"
44#include "cfgApi.h"
45
46#include "schApi.h"
47#include "utilsApi.h"
48#include "limApi.h"
49#include "limGlobal.h"
50#include "limTypes.h"
51#include "limUtils.h"
52#include "limAssocUtils.h"
53#include "limPropExtsUtils.h"
54#include "limSerDesUtils.h"
55#include "limIbssPeerMgmt.h"
56#include "limAdmitControl.h"
57#include "pmmApi.h"
58#include "logDump.h"
59#include "limSendSmeRspMessages.h"
60#include "wmmApsd.h"
61#include "limTrace.h"
62#include "limSession.h"
63#include "wlan_qct_wda.h"
64
65#if defined WLAN_FEATURE_VOWIFI
66#include "rrmApi.h"
67#endif
68
69#include <limFT.h>
70
71#ifdef VOSS_ENABLED
72#include "vos_types.h"
73#include "vos_packet.h"
74#include "wlan_qct_tl.h"
75#include "sysStartup.h"
76#endif
77
78
79static void __limInitScanVars(tpAniSirGlobal pMac)
80{
81 pMac->lim.gLimUseScanModeForLearnMode = 1;
82
83 pMac->lim.gLimSystemInScanLearnMode = 0;
84
85 // Scan related globals on STA
86 pMac->lim.gLimReturnAfterFirstMatch = 0;
87 pMac->lim.gLim24Band11dScanDone = 0;
88 pMac->lim.gLim50Band11dScanDone = 0;
89 pMac->lim.gLimReturnUniqueResults = 0;
90
91 // Background Scan related globals on STA
92 pMac->lim.gLimNumOfBackgroundScanSuccess = 0;
93 pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0;
94 pMac->lim.gLimNumOfForcedBkgndScan = 0;
95 pMac->lim.gLimBackgroundScanDisable = false; //based on BG timer
96 pMac->lim.gLimForceBackgroundScanDisable = false; //debug control flag
97 pMac->lim.gLimBackgroundScanTerminate = TRUE; //controlled by SME
98 pMac->lim.gLimReportBackgroundScanResults = FALSE; //controlled by SME
99
100 pMac->lim.gLimCurrentScanChannelId = 0;
101 pMac->lim.gpLimMlmScanReq = NULL;
102 pMac->lim.gLimMlmScanResultLength = 0;
103 pMac->lim.gLimSmeScanResultLength = 0;
104
105 palZeroMemory(pMac->hHdd, pMac->lim.gLimCachedScanHashTable,
106 sizeof(pMac->lim.gLimCachedScanHashTable));
107
108#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
109 pMac->lim.gLimBackgroundScanChannelId = 0;
110 pMac->lim.gLimBackgroundScanStarted = 0;
111 pMac->lim.gLimRestoreCBNumScanInterval = LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT;
112 pMac->lim.gLimRestoreCBCount = 0;
113 palZeroMemory(pMac->hHdd, pMac->lim.gLimLegacyBssidList, sizeof(pMac->lim.gLimLegacyBssidList));
114#endif
115
116 /* Fill in default values */
117 pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = 0;
118
119#ifdef ANI_AP_SDK
120 palZeroMemory(pMac->hHdd, &pMac->lim.gLimScanDurationConvert, sizeof(tLimScanDurationConvert)); /* Used to store converted scan duration values in TU and TICKS */
121#endif /* ANI_AP_SDK */
122
123 // abort scan is used to abort an on-going scan
124 pMac->lim.abortScan = 0;
125 palZeroMemory(pMac->hHdd, &pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo));
126
127//WLAN_SUSPEND_LINK Related
128 pMac->lim.gpLimSuspendCallback = NULL;
129 pMac->lim.gpLimResumeCallback = NULL;
130//end WLAN_SUSPEND_LINK Related
131}
132
133
134static void __limInitBssVars(tpAniSirGlobal pMac)
135{
136
137 palZeroMemory(pMac->hHdd, (void*)pMac->lim.gpSession, sizeof(*pMac->lim.gpSession)*pMac->lim.maxBssId);
138
139
140 //pMac->lim.gpLimStartBssReq = NULL;
141
142#if defined(ANI_PRODUCT_TYPE_AP)
143 palZeroMemory(pMac->hHdd, &pMac->lim.gLimNeighborBssList, sizeof(tSirMultipleNeighborBssInfo));
144#endif
145
146
147
148/* These global variables are moved to session table and intialization is done during session creation Oct 9th Review */
149#if 0
150
151 // Place holder for BSS description that we're
152 // currently joined with
153 palZeroMemory(pMac->hHdd, &pMac->lim.gLimCurrentBssId, sizeof(tSirMacAddr));
154 pMac->lim.gLimCurrentChannelId = HAL_INVALID_CHANNEL_ID;
155 palZeroMemory(pMac->hHdd, &pMac->lim.gLimCurrentSSID, sizeof(tSirMacSSid));
156 pMac->lim.gLimCurrentBssCaps = 0;
157 QosCaps is a bit map of various qos capabilities - see defn above
158 pMac->lim.gLimCurrentBssQosCaps = 0;
159 pMac->lim.gLimCurrentBssPropCap = 0;
160 pMac->lim.gLimSentCapsChangeNtf = 0;
161
162 // Place holder for BSS description that
163 // we're currently Reassociating
164 palZeroMemory(pMac->hHdd, &pMac->lim.gLimReassocBssId, sizeof(tSirMacAddr));
165 pMac->lim.gLimReassocChannelId = 0;
166 palZeroMemory(pMac->hHdd, &pMac->lim.gLimReassocSSID, sizeof(tSirMacSSid));
167 pMac->lim.gLimReassocBssCaps = 0;
168 pMac->lim.gLimReassocBssQosCaps = 0;
169 pMac->lim.gLimReassocBssPropCap = 0;
170 #endif
171
172 /* This is for testing purposes only, be default should always be off */
173 pMac->lim.gLimForceNoPropIE = 0;
174
175 // pMac->lim.gLimBssIdx = 0;
176
177 pMac->lim.gpLimMlmSetKeysReq = NULL;
178 pMac->lim.gpLimMlmRemoveKeyReq = NULL;
179 // pMac->lim.gLimStaid = 0; //TO SUPPORT BT-AMP
180
181}
182
183
184static void __limInitStatsVars(tpAniSirGlobal pMac)
185{
186 pMac->lim.gLimNumBeaconsRcvd = 0;
187 pMac->lim.gLimNumBeaconsIgnored = 0;
188
189 pMac->lim.gLimNumDeferredMsgs = 0;
190
191 /// Variable to keep track of number of currently associated STAs
192 pMac->lim.gLimNumOfCurrentSTAs = 0;
193 pMac->lim.gLimNumOfAniSTAs = 0; // count of ANI peers
194
195 /// This indicates number of RXed Beacons during HB period
196 //pMac->lim.gLimRxedBeaconCntDuringHB = 0;
197
198 // Heart-Beat interval value
199 pMac->lim.gLimHeartBeatCount = 0;
200
201 // Statistics to keep track of no. beacons rcvd in heart beat interval
202 palZeroMemory(pMac->hHdd, pMac->lim.gLimHeartBeatBeaconStats, sizeof(pMac->lim.gLimHeartBeatBeaconStats));
203
204#ifdef WLAN_DEBUG
205 // Debug counters
206 pMac->lim.numTot = 0;
207 pMac->lim.numBbt = 0;
208 pMac->lim.numProtErr = 0;
209 pMac->lim.numLearn = 0;
210 pMac->lim.numLearnIgnore = 0;
211 pMac->lim.numSme = 0;
212 palZeroMemory(pMac->hHdd, pMac->lim.numMAC, sizeof(pMac->lim.numMAC));
213 pMac->lim.gLimNumAssocReqDropInvldState = 0;
214 pMac->lim.gLimNumAssocReqDropACRejectTS = 0;
215 pMac->lim.gLimNumAssocReqDropACRejectSta = 0;
216 pMac->lim.gLimNumReassocReqDropInvldState = 0;
217 pMac->lim.gLimNumHashMissIgnored = 0;
218 pMac->lim.gLimUnexpBcnCnt = 0;
219 pMac->lim.gLimBcnSSIDMismatchCnt = 0;
220 pMac->lim.gLimNumLinkEsts = 0;
221 pMac->lim.gLimNumRxCleanup = 0;
222 pMac->lim.gLim11bStaAssocRejectCount = 0;
223#endif
224}
225
226
227
228static void __limInitStates(tpAniSirGlobal pMac)
229{
230 // Counts Heartbeat failures
231 pMac->lim.gLimHBfailureCntInLinkEstState = 0;
232 pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0;
233 pMac->lim.gLimHBfailureCntInOtherStates = 0;
234 pMac->lim.gLimRspReqd = 0;
235 pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE;
236
237 /// MLM State visible across all Sirius modules
238 MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, eLIM_MLM_IDLE_STATE));
239 pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
240
241 /// Previous MLM State
242 pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE;
243
244#ifdef GEN4_SCAN
245 // LIM to HAL SCAN Management Message Interface states
246 pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
247#endif // GEN4_SCAN
248
249#ifdef FEATURE_WLAN_INTEGRATED_SOC
250 /**
251 * Initialize state to eLIM_MLM_OFFLINE_STATE
252 */
253 pMac->lim.gLimSmeState = eLIM_MLM_OFFLINE_STATE;
254#else
255 /**
256 * Initialize state to suspended state and wait for
257 * HAL to send LIM_RESUME_ACTIVITY_NTF message.
258 */
259 MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
260 pMac->lim.gLimSmeState = eLIM_SME_SUSPEND_STATE;
261#endif /* FEATURE_WLAN_INTEGRATED_SOC */
262
263 /**
264 * By default assume 'unknown' role. This will be updated
265 * when SME_START_BSS_REQ is received.
266 */
267
268 palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlap11gParams, sizeof(tLimProtStaParams));
269 palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlap11aParams, sizeof(tLimProtStaParams));
270 palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlapHt20Params, sizeof(tLimProtStaParams));
271 palZeroMemory(pMac->hHdd, &pMac->lim.gLimOverlapNonGfParams, sizeof(tLimProtStaParams));
272 palZeroMemory(pMac->hHdd, &pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams));
273 palZeroMemory(pMac->hHdd, &pMac->lim.gLimNoShortSlotParams, sizeof(tLimNoShortSlotParams));
274
275 pMac->lim.gLimPhyMode = 0;
276 pMac->lim.scanStartTime = 0; // used to measure scan time
277
278 palZeroMemory(pMac->hHdd, pMac->lim.gLimBssid, sizeof(pMac->lim.gLimBssid));
279 palZeroMemory(pMac->hHdd, pMac->lim.gLimMyMacAddr, sizeof(pMac->lim.gLimMyMacAddr));
280 pMac->lim.ackPolicy = 0;
281
282#if 0 /* Moving all these to session specific elements */
283 pMac->lim.gLimQosEnabled = 0; //11E
284 pMac->lim.gLimWmeEnabled = 0; //WME
285 pMac->lim.gLimWsmEnabled = 0; //WSM
286 pMac->lim.gLimHcfEnabled = 0;
287 pMac->lim.gLim11dEnabled = 0;
288#endif
289
290 pMac->lim.gLimProbeRespDisableFlag = 0; // control over probe response
291}
292
293static void __limInitVars(tpAniSirGlobal pMac)
294{
295
296#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
297 palZeroMemory(pMac->hHdd, &pMac->lim.gLimAlternateRadioList, sizeof(tSirMultipleAlternateRadioInfo));
298#endif
299
300 // Place holder for Measurement Req/Rsp/Ind related info
301#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
302 pMac->lim.gpLimMeasReq = NULL;
303 palZeroMemory(pMac->hHdd, &pMac->lim.gLimMeasParams, sizeof(tLimMeasParams));
304 pMac->lim.gpLimMeasData = NULL;
305#endif
306
307 // WDS info
308 pMac->lim.gLimNumWdsInfoInd = 0;
309 pMac->lim.gLimNumWdsInfoSet = 0;
310 palZeroMemory(pMac->hHdd, &pMac->lim.gLimWdsInfo, sizeof(tSirWdsInfo));
311 /* initialize some parameters */
312 limInitWdsInfoParams(pMac);
313
314 // Deferred Queue Paramters
315 palZeroMemory(pMac->hHdd, &pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq));
316
317 // addts request if any - only one can be outstanding at any time
318 palZeroMemory(pMac->hHdd, &pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq));
319 pMac->lim.gLimAddtsSent = 0;
320 pMac->lim.gLimAddtsRspTimerCount = 0;
321
322 //protection related config cache
323 palZeroMemory(pMac->hHdd, &pMac->lim.cfgProtection, sizeof(tCfgProtection));
324 pMac->lim.gLimProtectionControl = 0;
325 palZeroMemory(pMac->hHdd, &pMac->lim.gLimAlternateRadio, sizeof(tSirAlternateRadioInfo));
326 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
327
328 // 11h Spectrum Management Related Flag
329 //pMac->lim.gLim11hEnable = 0;
330 pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
331 LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
332 pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE;
333
334 // 11h Quiet Element Related Flag
335 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
336 // A count-down value, used on the AP, to send out the
337 // Quiet BSS IE in that many Beacon's
338 pMac->lim.gLimSpecMgmt.quietCount = 0;
339 pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_FALSE;
340 pMac->lim.gLimSpecMgmt.fRadarIntrConfigured = eANI_BOOLEAN_FALSE;
341
342 // WMM Related Flag
343 pMac->lim.gUapsdEnable = 0;
344 pMac->lim.gUapsdPerAcBitmask = 0;
345 pMac->lim.gUapsdPerAcTriggerEnableMask = 0;
346 pMac->lim.gUapsdPerAcDeliveryEnableMask = 0;
347
348 // QoS-AC Downgrade: Initially, no AC is admitted
349 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0;
350 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0;
351
352 //dialogue token List head/tail for Action frames request sent.
353 pMac->lim.pDialogueTokenHead = NULL;
354 pMac->lim.pDialogueTokenTail = NULL;
355
356 palZeroMemory(pMac->hHdd, &pMac->lim.tspecInfo, sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX);
357
358 // admission control policy information
359 palZeroMemory(pMac->hHdd, &pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo));
360
361 pMac->lim.gLastBeaconDtimCount = 0;
362 pMac->lim.gLastBeaconDtimPeriod = 0;
363
364 //Scan in Power Save Flag
365 pMac->lim.gScanInPowersave = 0;
366}
367
368static void __limInitAssocVars(tpAniSirGlobal pMac)
369{
370 palZeroMemory(pMac->hHdd, pMac->lim.gpLimAIDpool,
371 sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1));
372 pMac->lim.freeAidHead = 0;
373 pMac->lim.freeAidTail = 0;
374 pMac->lim.gLimAssocStaLimit = WNI_CFG_ASSOC_STA_LIMIT_STADEF;
375
376 // Place holder for current authentication request
377 // being handled
378 pMac->lim.gpLimMlmAuthReq = NULL;
379 pMac->lim.gpLimMlmJoinReq = NULL;
380
381 /// MAC level Pre-authentication related globals
382 pMac->lim.gLimPreAuthChannelNumber = 0;
383 pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM;
384 palZeroMemory(pMac->hHdd, &pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr));
385 pMac->lim.gLimNumPreAuthContexts = 0;
386 palZeroMemory(pMac->hHdd, &pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable));
387
388 // Placed holder to deauth reason
389 pMac->lim.gLimDeauthReasonCode = 0;
390
391 // Place holder for Pre-authentication node list
392 pMac->lim.pLimPreAuthList = NULL;
393
394 // Send Disassociate frame threshold parameters
395 pMac->lim.gLimDisassocFrameThreshold = LIM_SEND_DISASSOC_FRAME_THRESHOLD;
396 pMac->lim.gLimDisassocFrameCredit = 0;
397
398 //One cache for each overlap and associated case.
399 palZeroMemory(pMac->hHdd, pMac->lim.protStaOverlapCache, sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE);
400 palZeroMemory(pMac->hHdd, pMac->lim.protStaCache, sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE);
401
402 // Initialize Assoc/ReAssoc Response Data/Frame
403 //pMac->lim.gLimAssocResponseData = NULL;
404
405}
406
407
408static void __limInitTitanVars(tpAniSirGlobal pMac)
409{
410 pMac->lim.gCbMode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
411 SET_CB_STATE_DISABLE( pMac->lim.gCbState );
412 palZeroMemory(pMac->hHdd, &pMac->lim.gLimChannelSwitch, sizeof(tLimChannelSwitchInfo));
413
414 pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;
415 pMac->lim.gLimChannelSwitch.secondarySubBand = eANI_CB_SECONDARY_NONE;
416
417 // Debug workaround for BEACON's
418 // State change triggered by "dump 222"
419 pMac->lim.gLimScanOverride = 1;
420 pMac->lim.gLimScanOverrideSaved = eSIR_ACTIVE_SCAN;
421
422
423 // Caches the CB State as desired by SME
424 SET_CB_STATE_DISABLE( pMac->lim.gCbStateProtected );
425
426 // TODO - This needs to be read off of a CFG variable
427
428 pMac->lim.gLimTitanStaCount = 0;
429 pMac->lim.gLimBlockNonTitanSta = 0;
430}
431
432static void __limInitHTVars(tpAniSirGlobal pMac)
433{
434 pMac->lim.htCapabilityPresentInBeacon = 0;
435 pMac->lim.htCapability = 0;
436 pMac->lim.gHTGreenfield = 0;
437 pMac->lim.gHTSupportedChannelWidthSet = 0;
438 pMac->lim.gHTShortGI40Mhz = 0;
439 pMac->lim.gHTShortGI20Mhz = 0;
440 pMac->lim.gHTMaxAmsduLength = 0;
441 pMac->lim.gHTDsssCckRate40MHzSupport = 0;
442 pMac->lim.gHTPSMPSupport = 0;
443 pMac->lim.gHTLsigTXOPProtection = 0;
444 pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC;
445 pMac->lim.gHTAMpduDensity = 0;
446
447 pMac->lim.gMaxAmsduSizeEnabled = false;
448 pMac->lim.gHTMaxRxAMpduFactor = 0;
449 pMac->lim.gHTServiceIntervalGranularity = 0;
450 pMac->lim.gHTControlledAccessOnly = 0;
451 pMac->lim.gHTRecommendedTxWidthSet = 0;
452 pMac->lim.gHTSecondaryChannelOffset = eHT_SECONDARY_CHANNEL_OFFSET_NONE;
453 pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
454 pMac->lim.gHTPCOActive = 0;
455
456 pMac->lim.gHTPCOPhase = 0;
457 pMac->lim.gHTSecondaryBeacon = 0;
458 pMac->lim.gHTDualCTSProtection = 0;
459 pMac->lim.gHTSTBCBasicMCS = 0;
460 pMac->lim.gAddBA_Declined = 0; // Flag to Decline the BAR if the particular bit (0-7) is being set
461}
462
463#if defined( FEATURE_WLAN_INTEGRATED_SOC )
464static tSirRetStatus __limInitConfig( tpAniSirGlobal pMac )
465{
466 tANI_U32 val1, val2, val3, len;
467 tANI_U16 val16;
468 tANI_U8 val8;
469 tSirMacHTCapabilityInfo *pHTCapabilityInfo;
470 tSirMacHTInfoField1 *pHTInfoField1;
471 tpSirPowerSaveCfg pPowerSaveConfig;
472 tSirMacHTParametersInfo *pAmpduParamInfo;
473
474 /* Read all the CFGs here that were updated before peStart is called */
475
476 /* WNI_CFG_CHANNEL_BONDING_MODE */
477
478 handleCBCFGChange( pMac, WNI_CFG_CHANNEL_BONDING_MODE );
479
480 //for Secondary channel, change setupCBMode function OR the caller of that
481 //function during Join (STA) or Start BSS(AP/IBSS) Now update the HT Capability
482 //CFG based on Channel Bonding CFG
483 if(wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
484 {
485 PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
486 return eSIR_FAILURE;
487 }
488
489 if(wlan_cfgGetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) != eSIR_SUCCESS)
490 {
491 PELOGE(limLog(pMac, LOGE, FL("could not retrieve Channel Bonding CFG\n"));)
492 return eSIR_FAILURE;
493 }
494 val16 = ( tANI_U16 ) val1;
495 pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
496
497 //channel bonding mode could be set to anything from 0 to 4(Titan had these
498 // modes But for Taurus we have only two modes: enable(>0) or disable(=0)
499 pHTCapabilityInfo->supportedChannelWidthSet = val2 ?
500 WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
501 if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo)
502 != eSIR_SUCCESS)
503 {
504 PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
505 return eSIR_FAILURE;
506 }
507
508 if(wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS)
509 {
510 PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT INFO Field1 CFG\n"));)
511 return eSIR_FAILURE;
512 }
513
514 val8 = ( tANI_U8 ) val1;
515 pHTInfoField1 = ( tSirMacHTInfoField1* ) &val8;
516 pHTInfoField1->recommendedTxWidthSet =
517 (tANI_U8)pHTCapabilityInfo->supportedChannelWidthSet;
518 pMac->lim.gHTRecommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet;
519 if(cfgSetInt(pMac, WNI_CFG_HT_INFO_FIELD1, *(tANI_U8*)pHTInfoField1)
520 != eSIR_SUCCESS)
521 {
522 PELOGE(limLog(pMac, LOGE, FL("could not update HT Info Field\n"));)
523 return eSIR_FAILURE;
524 }
525
526 /* WNI_CFG_HEART_BEAT_THRESHOLD */
527
528 if( wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) !=
529 eSIR_SUCCESS )
530 {
531 PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG\n"));)
532 return eSIR_FAILURE;
533 }
534 if(!val1)
535 {
536 limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER);
537 pMac->sys.gSysEnableLinkMonitorMode = 0;
538 }
539 else
540 {
541 //No need to activate the timer during init time.
542 pMac->sys.gSysEnableLinkMonitorMode = 1;
543 }
544
545 /* WNI_CFG_SHORT_GI_20MHZ */
546
547 if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS)
548 {
549 PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG\n"));)
550 return eSIR_FAILURE;
551 }
552 if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS)
553 {
554 PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG\n"));)
555 return eSIR_FAILURE;
556 }
557 if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val3) != eSIR_SUCCESS)
558 {
559 PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG\n"));)
560 return eSIR_FAILURE;
561 }
562
563 val16 = ( tANI_U16 ) val1;
564 pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16;
565 pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2;
566 pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val3;
567
568 if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) !=
569 eSIR_SUCCESS)
570 {
571 PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG\n"));)
572 return eSIR_FAILURE;
573 }
574
575 /* WNI_CFG_MAX_RX_AMPDU_FACTOR */
576
577 if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS)
578 {
579 PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG\n"));)
580 return eSIR_FAILURE;
581 }
582 if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS)
583 {
584 PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG\n"));)
585 return eSIR_FAILURE;
586 }
587 val16 = ( tANI_U16 ) val1;
588 pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16;
589 pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2;
590 if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) !=
591 eSIR_SUCCESS)
592 {
593 PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG\n"));)
594 return eSIR_FAILURE;
595 }
596
597 /* WNI_CFG_SHORT_PREAMBLE - this one is not updated in
598 limHandleCFGparamUpdate do we want to update this? */
599 if(wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val1) != eSIR_SUCCESS)
600 {
601 limLog(pMac, LOGP, FL("cfg get short preamble failed\n"));
602 return eSIR_FAILURE;
603 }
604
605 /* WNI_CFG_BSSID - this one is not updated in limHandleCFGparamUpdate do we
606 want to update this? */
607 len = 6;
608 if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, pMac->lim.gLimBssid, &len) !=
609 eSIR_SUCCESS)
610 {
611 limLog(pMac, LOGP, FL("cfg get bssid failed\n"));
612 return eSIR_FAILURE;
613 }
614
615 /* WNI_CFG_MAX_PS_POLL */
616
617 /* Allocate and fill in power save configuration. */
618 if (palAllocateMemory(pMac->hHdd, (void **)&pPowerSaveConfig,
619 sizeof(tSirPowerSaveCfg)) != eHAL_STATUS_SUCCESS)
620 {
621 PELOGE(limLog(pMac, LOGE, FL("LIM: Cannot allocate memory for power save "
622 "configuration\n"));)
623 return eSIR_FAILURE;
624 }
625
626 /* This context should be valid if power-save configuration message has been
627 * already dispatched during initialization process. Re-using the present
628 * configuration mask
629 */
630 palCopyMemory(pMac->hHdd, pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg,
631 sizeof(tSirPowerSaveCfg));
632
633 /* Note: it is okay to do this since DAL/HAL is alrady started */
634 if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS)
635 {
636 PELOGE(limLog(pMac, LOGE, FL("LIM: pmmSendPowerSaveCfg() failed \n"));)
637 return eSIR_FAILURE;
638 }
639
640 /* WNI_CFG_BG_SCAN_CHANNEL_LIST_CHANNEL_LIST */
641
642#if (WNI_POLARIS_FW_PRODUCT == WLAN_STA) || defined(ANI_AP_CLIENT_SDK)
643 PELOG1(limLog(pMac, LOG1,
644 FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel\n"));)
645 pMac->lim.gLimBackgroundScanChannelId = 0;
646#endif
647
648 /* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */
649
650 /* This was initially done after resume notification from HAL. Now, DAL is
651 started before PE so this can be done here */
652 handleCBCFGChange( pMac, ANI_IGNORE_CFG_ID );
653 handleHTCapabilityandHTInfo(pMac);
654
655 return eSIR_SUCCESS;
656}
657#endif /* FEATURE_WLAN_INTEGRATED_SOC */
658
659/*
660 limStart
661 This function is to replace the __limProcessSmeStartReq since there is no
662 eWNI_SME_START_REQ post to PE.
663*/
664tSirRetStatus limStart(tpAniSirGlobal pMac)
665{
666 tSirResultCodes retCode = eSIR_SUCCESS;
667
668 PELOG1(limLog(pMac, LOG1, FL(" enter\n"));)
669
670 if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE)
671 {
672 pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE;
673
674 MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, 0, pMac->lim.gLimSmeState));
675
676 // By default do not return after first scan match
677 pMac->lim.gLimReturnAfterFirstMatch = 0;
678
679 // Initialize MLM state machine
680 limInitMlm(pMac);
681
682 // By default return unique scan results
683 pMac->lim.gLimReturnUniqueResults = true;
684 pMac->lim.gLimSmeScanResultLength = 0;
685 }
686 else
687 {
688 /**
689 * Should not have received eWNI_SME_START_REQ in states
690 * other than OFFLINE. Return response to host and
691 * log error
692 */
693 limLog(pMac, LOGE, FL("Invalid SME state %X\n"),pMac->lim.gLimSmeState );
694 retCode = eSIR_FAILURE;
695 }
696
697 return retCode;
698}
699
700/**
701 * limInitialize()
702 *
703 *FUNCTION:
704 * This function is called from LIM thread entry function.
705 * LIM related global data structures are initialized in this function.
706 *
707 *LOGIC:
708 * NA
709 *
710 *ASSUMPTIONS:
711 * NA
712 *
713 *NOTE:
714 * NA
715 *
716 * @param pMac - Pointer to global MAC structure
717 * @return None
718 */
719
720tSirRetStatus
721limInitialize(tpAniSirGlobal pMac)
722{
723 tSirRetStatus status = eSIR_SUCCESS;
724
725 __limInitAssocVars(pMac);
726 __limInitVars(pMac);
727 __limInitStates(pMac);
728 __limInitStatsVars(pMac);
729 __limInitBssVars(pMac);
730 __limInitScanVars(pMac);
731 __limInitHTVars(pMac);
732 __limInitTitanVars(pMac);
733
734#if defined( FEATURE_WLAN_INTEGRATED_SOC )
735 status = limStart(pMac);
736 if(eSIR_SUCCESS != status)
737 {
738 return status;
739 }
740#endif /* FEATURE_WLAN_INTEGRATED_SOC */
741
742 /*
743 * MLM will be intitalized when 'START' request comes from SME.
744 * limInitMlm calls limCreateTimers, which actually relies on
745 * CFG to be downloaded. So it should not be called as part of
746 * peStart, as CFG download is happening after peStart.
747 */
748 //limInitMlm(pMac);
749 // Initializations for maintaining peers in IBSS
750 limIbssInit(pMac);
751
752 pmmInitialize(pMac);
753
754
755#if defined WLAN_FEATURE_VOWIFI
756 rrmInitialize(pMac);
757#endif
758#if defined WLAN_FEATURE_VOWIFI_11R
759 limFTOpen(pMac);
760#endif
761
762#ifdef WLAN_FEATURE_P2P
763 vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue);
764#endif
765
766#if 0
767
768 vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR);
769 vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN);
770 vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL);
771
772 vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_WARN);
773 vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_ERROR);
774
775 vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN);
776 vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR);
777 vos_trace_setLevel(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR);
778
779 vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR);
780
781 vos_trace_setLevel(VOS_MODULE_ID_SSC, VOS_TRACE_LEVEL_ERROR);
782
783 vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR);
784 vos_trace_setLevel(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR);
785
786 vos_trace_setLevel(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR);
787
788
789 vos_trace_setLevel(VOS_MODULE_ID_BAL, VOS_TRACE_LEVEL_ERROR);
790
791 vos_trace_setLevel(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR);
792#endif
793 MTRACE(limTraceInit(pMac));
794
795#if defined( FEATURE_WLAN_INTEGRATED_SOC )
796 //Initialize the configurations needed by PE
797 if( eSIR_FAILURE == __limInitConfig(pMac))
798 {
799 //We need to undo everything in limStart
800 limCleanupMlm(pMac);
801 return eSIR_FAILURE;
802 }
803
804 //initialize the TSPEC admission control table.
805 //Note that this was initially done after resume notification from HAL.
806 //Now, DAL is started before PE so this can be done here
807 limAdmitControlInit(pMac);
808 limRegisterHalIndCallBack(pMac);
809#endif /*FEATURE_WLAN_INTEGRATED_SOC*/
810
811 return status;
812
813} /*** end limInitialize() ***/
814
815
816
817/**
818 * limCleanup()
819 *
820 *FUNCTION:
821 * This function is called upon reset or persona change
822 * to cleanup LIM state
823 *
824 *LOGIC:
825 * NA
826 *
827 *ASSUMPTIONS:
828 * NA
829 *
830 *NOTE:
831 * NA
832 *
833 * @param pMac - Pointer to Global MAC structure
834 * @return None
835 */
836
837void
838limCleanup(tpAniSirGlobal pMac)
839{
840#ifdef VOSS_ENABLED
841 v_PVOID_t pvosGCTx;
842 VOS_STATUS retStatus;
843#endif
844
845#ifdef WLAN_FEATURE_P2P
846//Before destroying the list making sure all the nodes have been deleted.
847//Which should be the normal case, but a memory leak has been reported.
848
849 tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL;
850
851 while(vos_list_remove_front(&pMac->lim.gLimMgmtFrameRegistratinQueue,
852 (vos_list_node_t**)&pLimMgmtRegistration) == VOS_STATUS_SUCCESS)
853 {
854 VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
855 FL("Fixing leak! Deallocating pLimMgmtRegistration node"));
856
857 palFreeMemory(pMac, pLimMgmtRegistration);
858 }
859
860 vos_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue);
861#endif
862
863 limCleanupMlm(pMac);
864 limCleanupLmm(pMac);
865
866 // free up preAuth table
867 if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL)
868 {
869 palFreeMemory(pMac->hHdd, pMac->lim.gLimPreAuthTimerTable.pTable);
870 pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
871 pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
872 }
873
874 if(NULL != pMac->lim.pDialogueTokenHead)
875 {
876 limDeleteDialogueTokenList(pMac);
877 }
878
879 if(NULL != pMac->lim.pDialogueTokenTail)
880 {
881 palFreeMemory(pMac->hHdd, (void *) pMac->lim.pDialogueTokenTail);
882 pMac->lim.pDialogueTokenTail = NULL;
883 }
884
885 # if 0
886 if (pMac->lim.gpLimStartBssReq != NULL)
887 {
888 palFreeMemory(pMac->hHdd, pMac->lim.gpLimStartBssReq);
889 pMac->lim.gpLimStartBssReq = NULL;
890 }
891 #endif
892
893 if (pMac->lim.gpLimMlmSetKeysReq != NULL)
894 {
895 palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmSetKeysReq);
896 pMac->lim.gpLimMlmSetKeysReq = NULL;
897 }
898
899 #if 0
900 if (pMac->lim.gpLimJoinReq != NULL)
901 {
902 palFreeMemory(pMac->hHdd, pMac->lim.gpLimJoinReq);
903 pMac->lim.gpLimJoinReq = NULL;
904 }
905 #endif
906
907 if (pMac->lim.gpLimMlmAuthReq != NULL)
908 {
909 palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmAuthReq);
910 pMac->lim.gpLimMlmAuthReq = NULL;
911 }
912
913 if (pMac->lim.gpLimMlmJoinReq != NULL)
914 {
915 palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmJoinReq);
916 pMac->lim.gpLimMlmJoinReq = NULL;
917 }
918
919 #if 0
920 if (pMac->lim.gpLimReassocReq != NULL)
921 {
922 palFreeMemory(pMac->hHdd, pMac->lim.gpLimReassocReq);
923 pMac->lim.gpLimReassocReq = NULL;
924 }
925 #endif
926
927 if (pMac->lim.gpLimMlmRemoveKeyReq != NULL)
928 {
929 palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmRemoveKeyReq);
930 pMac->lim.gpLimMlmRemoveKeyReq = NULL;
931 }
932
933 if (pMac->lim.gpLimMlmScanReq != NULL)
934 {
935 palFreeMemory(pMac->hHdd, pMac->lim.gpLimMlmScanReq);
936 pMac->lim.gpLimMlmScanReq = NULL;
937 }
938
939#if 0
940 if(NULL != pMac->lim.beacon)
941 {
942 palFreeMemory(pMac->hHdd, (void*) pMac->lim.beacon);
943 pMac->lim.beacon = NULL;
944 }
945#endif
946 #if 0
947 if(NULL != pMac->lim.assocReq)
948 {
949 palFreeMemory(pMac->hHdd, (void*) pMac->lim.assocReq);
950 pMac->lim.assocReq= NULL;
951 }
952 #endif
953
954#if 0
955 if(NULL != pMac->lim.assocRsp)
956 {
957 palFreeMemory(pMac->hHdd, (void*) pMac->lim.assocRsp);
958 pMac->lim.assocRsp= NULL;
959 }
960#endif
961 // Now, finally reset the deferred message queue pointers
962 limResetDeferredMsgQ(pMac);
963
964#ifdef VOSS_ENABLED
965
966 pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
967 retStatus = WLANTL_DeRegisterMgmtFrmClient(pvosGCTx);
968
969 if ( retStatus != VOS_STATUS_SUCCESS )
970 PELOGE(limLog(pMac, LOGE, FL("DeRegistering the PE Handle with TL has failed bailing out...\n"));)
971#endif
972
973#if defined WLAN_FEATURE_VOWIFI
974 rrmCleanup(pMac);
975#endif
976#if defined WLAN_FEATURE_VOWIFI_11R
977 limFTCleanup(pMac);
978#endif
979
980} /*** end limCleanup() ***/
981
982
983/** -------------------------------------------------------------
984\fn peOpen
985\brief will be called in Open sequence from macOpen
986\param tpAniSirGlobal pMac
987\param tHalOpenParameters *pHalOpenParam
988\return tSirRetStatus
989 -------------------------------------------------------------*/
990
991tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam)
992{
993 pMac->lim.maxBssId = pMacOpenParam->maxBssId;
994 pMac->lim.maxStation = pMacOpenParam->maxStation;
995
996 if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0))
997 {
998 PELOGE(limLog(pMac, LOGE, FL("max number of Bssid or Stations cannot be zero!\n"));)
999 return eSIR_FAILURE;
1000 }
1001
1002 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1003 (void **) &pMac->lim.limTimers.gpLimCnfWaitTimer, sizeof(TX_TIMER)*pMac->lim.maxStation))
1004 {
1005 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
1006 return eSIR_FAILURE;
1007 }
1008
1009 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1010 (void **) &pMac->lim.gpLimAIDpool,
1011 sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1)))
1012 {
1013 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
1014 return eSIR_FAILURE;
1015 }
1016
1017 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1018 (void **) &pMac->lim.gpSession, sizeof(tPESession)* pMac->lim.maxBssId))
1019 {
1020 limLog(pMac, LOGE, FL("memory allocate failed!\n"));
1021 return eSIR_FAILURE;
1022 }
1023
1024 palZeroMemory(pMac->hHdd, pMac->lim.gpSession, sizeof(tPESession)*pMac->lim.maxBssId);
1025
1026
1027 /*
1028 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1029 (void **) &pMac->dph.dphHashTable.pHashTable, sizeof(tpDphHashNode)*pMac->lim.maxStation))
1030 {
1031 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
1032 return eSIR_FAILURE;
1033 }
1034
1035 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1036 (void **) &pMac->dph.dphHashTable.pDphNodeArray, sizeof(tDphHashNode)*pMac->lim.maxStation))
1037 {
1038 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
1039 return eSIR_FAILURE;
1040 }
1041 */
1042
1043#ifdef WLAN_SOFTAP_FEATURE
1044 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1045 (void **) &pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation))
1046 {
1047 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pTim!\n"));)
1048 return eSIR_FAILURE;
1049 }
1050 palZeroMemory(pMac->hHdd, pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation);
1051#endif
1052
1053#ifdef ANI_PRODUCT_TYPE_AP
1054
1055 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1056 (void **) &pMac->pmm.gPmmTim.pStaInfo, sizeof(*pMac->pmm.gPmmTim.pStaInfo) * pMac->lim.maxStation))
1057 {
1058 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pStaInfo!\n"));)
1059 return eSIR_FAILURE;
1060 }
1061
1062 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1063 (void **) &pMac->pmm.gpPmmStaState, sizeof(tPmmStaState)*pMac->lim.maxStation))
1064 {
1065 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
1066 return eSIR_FAILURE;
1067 }
1068
1069 if (eHAL_STATUS_SUCCESS != palAllocateMemory(pMac->hHdd,
1070 (void **) &pMac->pmm.gpPmmPSState, sizeof(tANI_U8)*pMac->lim.maxStation))
1071 {
1072 PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!\n"));)
1073 return eSIR_FAILURE;
1074 }
1075#endif
1076
1077
1078 return eSIR_SUCCESS;
1079}
1080
1081/** -------------------------------------------------------------
1082\fn peClose
1083\brief will be called in close sequence from macClose
1084\param tpAniSirGlobal pMac
1085\return tSirRetStatus
1086 -------------------------------------------------------------*/
1087
1088tSirRetStatus peClose(tpAniSirGlobal pMac)
1089{
1090 tANI_U8 i;
1091
1092 if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG)
1093 return eSIR_SUCCESS;
1094
1095 palFreeMemory(pMac->hHdd, pMac->lim.limTimers.gpLimCnfWaitTimer);
1096 pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
1097 palFreeMemory(pMac->hHdd, pMac->lim.gpLimAIDpool);
1098 pMac->lim.gpLimAIDpool = NULL;
1099
1100
1101 for(i =0; i < pMac->lim.maxBssId; i++)
1102 {
1103 if(pMac->lim.gpSession[i].valid == TRUE)
1104 {
1105 peDeleteSession(pMac,&pMac->lim.gpSession[i]);
1106 }
1107 }
1108
1109 palFreeMemory(pMac->hHdd, pMac->lim.gpSession);
1110 pMac->lim.gpSession = NULL;
1111 /*
1112 palFreeMemory(pMac->hHdd, pMac->dph.dphHashTable.pHashTable);
1113 pMac->dph.dphHashTable.pHashTable = NULL;
1114 palFreeMemory(pMac->hHdd, pMac->dph.dphHashTable.pDphNodeArray);
1115 pMac->dph.dphHashTable.pDphNodeArray = NULL;
1116 */
1117#ifdef WLAN_SOFTAP_FEATURE
1118 palFreeMemory(pMac->hHdd, pMac->pmm.gPmmTim.pTim);
1119 pMac->pmm.gPmmTim.pTim = NULL;
1120#endif
1121#ifdef ANI_PRODUCT_TYPE_AP
1122 palFreeMemory(pMac->hHdd, pMac->pmm.gPmmTim.pStaInfo);
1123 pMac->pmm.gPmmTim.pStaInfo = NULL;
1124 palFreeMemory(pMac->hHdd, pMac->pmm.gpPmmStaState);
1125 pMac->pmm.gpPmmStaState = NULL;
1126 palFreeMemory(pMac->hHdd, pMac->pmm.gpPmmPSState);
1127 pMac->pmm.gpPmmPSState = NULL;
1128#endif
1129
1130 return eSIR_SUCCESS;
1131}
1132
1133/** -------------------------------------------------------------
1134\fn peStart
1135\brief will be called in start sequence from macStart
1136\param tpAniSirGlobal pMac
1137\return none
1138 -------------------------------------------------------------*/
1139
1140tSirRetStatus peStart(tpAniSirGlobal pMac)
1141{
1142 tSirRetStatus status = eSIR_SUCCESS;
1143
1144 status = limInitialize(pMac);
1145#if defined(ANI_LOGDUMP)
1146 limDumpInit(pMac);
1147#endif //#if defined(ANI_LOGDUMP)
1148
1149 return status;
1150}
1151
1152/** -------------------------------------------------------------
1153\fn peStop
1154\brief will be called in stop sequence from macStop
1155\param tpAniSirGlobal pMac
1156\return none
1157 -------------------------------------------------------------*/
1158
1159void peStop(tpAniSirGlobal pMac)
1160{
1161 limCleanup(pMac);
1162 SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE);
1163 return;
1164}
1165
1166/** -------------------------------------------------------------
1167\fn peFreeMsg
1168\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs)
1169\ to free a given PE message on the TX and MC thread.
1170\ This happens when there are messages pending in the PE
1171\ queue when system is being stopped and reset.
1172\param tpAniSirGlobal pMac
1173\param tSirMsgQ pMsg
1174\return none
1175-----------------------------------------------------------------*/
1176v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg)
1177{
1178 if (pMsg != NULL)
1179 {
1180 if (NULL != pMsg->bodyptr)
1181 {
1182 if (SIR_BB_XPORT_MGMT_MSG == pMsg->type)
1183 {
1184 vos_pkt_return_packet((vos_pkt_t *)pMsg->bodyptr);
1185 }
1186 else
1187 {
1188 vos_mem_free((v_VOID_t*)pMsg->bodyptr);
1189 }
1190 }
1191 pMsg->bodyptr = 0;
1192 pMsg->bodyval = 0;
1193 pMsg->type = 0;
1194 }
1195 return;
1196}
1197
1198
1199/**
1200 * The function checks if a particular timer should be allowed
1201 * into LIM while device is sleeping
1202 */
1203tANI_U8 limIsTimerAllowedInPowerSaveState(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
1204{
1205 tANI_U8 retStatus = TRUE;
1206
1207 if(!limIsSystemInActiveState(pMac))
1208 {
1209 switch(pMsg->type)
1210 {
1211 /* Don't allow following timer messages if in sleep */
1212 case SIR_LIM_MIN_CHANNEL_TIMEOUT:
1213 case SIR_LIM_MAX_CHANNEL_TIMEOUT:
1214 case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
1215 retStatus = FALSE;
1216 break;
1217 /* May allow following timer messages in sleep mode */
1218 case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
1219
1220 /* Safe to allow as of today, this triggers background scan
1221 * which will not be started if the device is in power-save mode
1222 * might need to block in the future if we decide to implement
1223 * spectrum management
1224 */
1225 case SIR_LIM_QUIET_TIMEOUT:
1226
1227 /* Safe to allow as of today, this triggers background scan
1228 * which will not be started if the device is in power-save mode
1229 * might need to block in the future if we decide to implement
1230 * spectrum management
1231 */
1232 case SIR_LIM_QUIET_BSS_TIMEOUT:
1233
1234 /* Safe to allow this timermessage, triggers background scan
1235 * which is blocked in sleep mode
1236 */
1237 case SIR_LIM_CHANNEL_SCAN_TIMEOUT:
1238
1239 /* Safe to allow this timer, since, while in IMPS this timer will not
1240 * be started. In case of BMPS sleep, SoftMAC handles the heart-beat
1241 * when heart-beat control is handled back to PE, device would have
1242 * already woken-up due to EXIT_BMPS_IND mesage from SoftMAC
1243 */
1244 case SIR_LIM_HEART_BEAT_TIMEOUT:
1245 case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
1246
1247 /* Safe to allow, PE is not handling this message as of now. May need
1248 * to block it, basically, free the buffer and restart the timer
1249 */
1250 case SIR_LIM_REASSOC_FAIL_TIMEOUT:
1251 case SIR_LIM_JOIN_FAIL_TIMEOUT:
1252 case SIR_LIM_ASSOC_FAIL_TIMEOUT:
1253 case SIR_LIM_AUTH_FAIL_TIMEOUT:
1254 case SIR_LIM_ADDTS_RSP_TIMEOUT:
1255 retStatus = TRUE;
1256 break;
1257
1258 /* by default allow rest of messages */
1259 default:
1260 retStatus = TRUE;
1261 break;
1262
1263
1264 }
1265 }
1266
1267 return retStatus;
1268
1269}
1270
1271
1272
1273/**
1274 * limPostMsgApi()
1275 *
1276 *FUNCTION:
1277 * This function is called from other thread while posting a
1278 * message to LIM message Queue gSirLimMsgQ.
1279 *
1280 *LOGIC:
1281 * NA
1282 *
1283 *ASSUMPTIONS:
1284 * NA
1285 *
1286 *NOTE:
1287 * NA
1288 *
1289 * @param pMac - Pointer to Global MAC structure
1290 * @param pMsg - Pointer to the message structure
1291 * @return None
1292 */
1293
1294tANI_U32
1295limPostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
1296{
1297#ifdef VOSS_ENABLED
1298 return vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg);
1299
1300
1301#elif defined(ANI_OS_TYPE_LINUX) || defined(ANI_OS_TYPE_OSX)
1302 return tx_queue_send(&pMac->sys.gSirLimMsgQ, pMsg, TX_WAIT_FOREVER);
1303
1304#else
1305 /* Check if this is a timeout message from a timer
1306 * and if the timeout message is allowed if the device is in power-save state
1307 */
1308 if(!limIsTimerAllowedInPowerSaveState(pMac, pMsg))
1309 {
1310 limLog(pMac, LOGW,
1311 FL("Timeout message %d is not allowed while device is in Power-Save mode\n"),
1312 pMsg->type);
1313
1314 return TX_SUCCESS;
1315 }
1316 if(pMac->gDriverType != eDRIVER_TYPE_MFG)
1317 {
1318 limMessageProcessor(pMac, pMsg);
1319 }
1320
1321 return TX_SUCCESS;
1322
1323#endif
1324} /*** end limPostMsgApi() ***/
1325
1326
1327/*--------------------------------------------------------------------------
1328
1329 \brief pePostMsgApi() - A wrapper function to post message to Voss msg queues
1330
1331 This function can be called by legacy code to post message to voss queues OR
1332 legacy code may keep on invoking 'limPostMsgApi' to post the message to voss queue
1333 for dispatching it later.
1334
1335 \param pMac - Pointer to Global MAC structure
1336 \param pMsg - Pointer to the message structure
1337
1338 \return tANI_U32 - TX_SUCCESS for success.
1339
1340 --------------------------------------------------------------------------*/
1341
1342tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
1343{
1344 return (tSirRetStatus)limPostMsgApi(pMac, pMsg);
1345}
1346
1347/*--------------------------------------------------------------------------
1348
1349 \brief peProcessMessages() - Message Processor for PE
1350
1351 Voss calls this function to dispatch the message to PE
1352
1353 \param pMac - Pointer to Global MAC structure
1354 \param pMsg - Pointer to the message structure
1355
1356 \return tANI_U32 - TX_SUCCESS for success.
1357
1358 --------------------------------------------------------------------------*/
1359
1360tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg)
1361{
1362 if(pMac->gDriverType == eDRIVER_TYPE_MFG)
1363 {
1364 return eSIR_SUCCESS;
1365 }
1366 /**
1367 * If the Message to be handled is for CFG Module call the CFG Msg Handler and
1368 * for all the other cases post it to LIM
1369 */
1370 if ( SIR_CFG_PARAM_UPDATE_IND != pMsg->type && IS_CFG_MSG(pMsg->type))
1371 cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr);
1372 else
1373 limMessageProcessor(pMac, pMsg);
1374 return eSIR_SUCCESS;
1375}
1376
1377
1378#ifdef VOSS_ENABLED
1379
1380// ---------------------------------------------------------------------------
1381/**
1382 * peHandleMgmtFrame
1383 *
1384 * FUNCTION:
1385 * Process the Management frames from TL
1386 *
1387 * LOGIC:
1388 *
1389 * ASSUMPTIONS: TL sends the packet along with the VOS GlobalContext
1390 *
1391 * NOTE:
1392 *
1393 * @param pvosGCtx Global Vos Context
1394 * @param vossBuff Packet
1395 * @return None
1396 */
1397
1398VOS_STATUS peHandleMgmtFrame( v_PVOID_t pvosGCtx, v_PVOID_t vosBuff)
1399{
1400 tpAniSirGlobal pMac;
1401 tpSirMacMgmtHdr mHdr;
1402 tSirMsgQ msg;
1403 vos_pkt_t *pVosPkt;
1404 VOS_STATUS vosStatus;
1405 v_U8_t *pRxPacketInfo;
1406
1407 pVosPkt = (vos_pkt_t *)vosBuff;
1408 if (NULL == pVosPkt)
1409 {
1410 return VOS_STATUS_E_FAILURE;
1411 }
1412
1413 pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, pvosGCtx);
1414 if (NULL == pMac)
1415 {
1416 // cannot log a failure without a valid pMac
1417 vos_pkt_return_packet(pVosPkt);
1418 return VOS_STATUS_E_FAILURE;
1419 }
1420
1421 vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (void *)&pRxPacketInfo, VOS_FALSE );
1422
1423 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1424 {
1425 vos_pkt_return_packet(pVosPkt);
1426 return VOS_STATUS_E_FAILURE;
1427 }
1428
1429
1430 //
1431 // The MPDU header is now present at a certain "offset" in
1432 // the BD and is specified in the BD itself
1433 //
1434 mHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1435 if(mHdr->fc.type == SIR_MAC_MGMT_FRAME)
1436 {
1437 PELOG1(limLog( pMac, LOG1,
1438 FL ( "RxBd=%p mHdr=%p Type: %d Subtype: %d Sizes:FC%d Mgmt%d\n"),
1439 pRxBd, mHdr, mHdr->fc.type, mHdr->fc.subType, sizeof(tSirMacFrameCtl), sizeof(tSirMacMgmtHdr) );)
1440
1441 MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT, 0,
1442 LIM_TRACE_MAKE_RXMGMT(mHdr->fc.subType,
1443 (tANI_U16) (((tANI_U16) (mHdr->seqControl.seqNumHi << 4)) | mHdr->seqControl.seqNumLo)));)
1444 }
1445
1446
1447 // Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG
1448 msg.type = SIR_BB_XPORT_MGMT_MSG;
1449 msg.bodyptr = vosBuff;
1450 msg.bodyval = 0;
1451
1452 if( eSIR_SUCCESS != sysBbtProcessMessageCore( pMac,
1453 &msg,
1454 mHdr->fc.type,
1455 mHdr->fc.subType ))
1456 {
1457 vos_pkt_return_packet(pVosPkt);
1458 limLog( pMac, LOGW,
1459 FL ( "sysBbtProcessMessageCore failed to process SIR_BB_XPORT_MGMT_MSG\n" ));
1460 return VOS_STATUS_E_FAILURE;
1461 }
1462
1463 return VOS_STATUS_SUCCESS;
1464}
1465
1466// ---------------------------------------------------------------------------
1467/**
1468 * peRegisterTLHandle
1469 *
1470 * FUNCTION:
1471 * Registers the Handler which, process the Management frames from TL
1472 *
1473 * LOGIC:
1474 *
1475 * ASSUMPTIONS:
1476 *
1477 * NOTE:
1478 *
1479 * @return None
1480 */
1481
1482void peRegisterTLHandle(tpAniSirGlobal pMac)
1483{
1484 v_PVOID_t pvosGCTx;
1485 VOS_STATUS retStatus;
1486
1487 pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
1488
1489 retStatus = WLANTL_RegisterMgmtFrmClient(pvosGCTx, peHandleMgmtFrame);
1490
1491 if (retStatus != VOS_STATUS_SUCCESS)
1492 limLog( pMac, LOGP, FL("Registering the PE Handle with TL has failed bailing out...\n"));
1493
1494}
1495#endif
1496
1497
1498/**
1499 * limCheckStateForLearnMode()
1500 *
1501 *FUNCTION:
1502 * This function is called by SCH to verify if LIM is in a state
1503 * to put system into Learn mode
1504 *
1505 *LOGIC:
1506 * NA
1507 *
1508 *ASSUMPTIONS:
1509 * NA
1510 *
1511 *NOTE:
1512 *
1513 * @param pMac - Pointer to Global MAC structure
1514 * @return eSIR_SUCCESS - LIM is in a state to put system
1515 * into Learn Mode
1516 * eSIR_FAILURE - LIM is NOT in a state to put system
1517 * into Learn Mode
1518 */
1519
1520tSirRetStatus
1521limCheckStateForLearnMode(tpAniSirGlobal pMac)
1522{
1523 switch (pMac->lim.gLimSmeState)
1524 {
1525 case eLIM_SME_OFFLINE_STATE:
1526 case eLIM_SME_IDLE_STATE:
1527 case eLIM_SME_JOIN_FAILURE_STATE:
1528 case eLIM_SME_NORMAL_STATE:
1529 case eLIM_SME_LINK_EST_STATE:
1530 // LIM is in a state to put system into Learn mode
1531 return eSIR_SUCCESS;
1532
1533 default:
1534 // LIM is NOT in a state to put system into Learn mode
1535 return eSIR_FAILURE;
1536 }
1537} /*** end limCheckStateForLearnMode() ***/
1538
1539
1540
1541/**
1542 * limIsSystemInScanState()
1543 *
1544 *FUNCTION:
1545 * This function is called by various MAC software modules to
1546 * determine if System is in Scan/Learn state
1547 *
1548 *LOGIC:
1549 * NA
1550 *
1551 *ASSUMPTIONS:
1552 * NA
1553 *
1554 *NOTE:
1555 *
1556 * @param pMac - Pointer to Global MAC structure
1557 * @return true - System is in Scan/Learn state
1558 * false - System is NOT in Scan/Learn state
1559 */
1560
1561tANI_U8
1562limIsSystemInScanState(tpAniSirGlobal pMac)
1563{
1564 switch (pMac->lim.gLimSmeState)
1565 {
1566 case eLIM_SME_CHANNEL_SCAN_STATE:
1567 case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
1568 case eLIM_SME_LINK_EST_WT_SCAN_STATE:
1569 case eLIM_SME_WT_SCAN_STATE:
1570 // System is in Learn mode
1571 return true;
1572
1573 default:
1574 // System is NOT in Learn mode
1575 return false;
1576 }
1577} /*** end limIsSystemInScanState() ***/
1578
1579
1580
1581/**
1582 * limIsSystemInActiveState()
1583 *
1584 *FUNCTION:
1585 * This function is called by various MAC software modules to
1586 * determine if System is in Active/Wakeup state
1587 *
1588 *LOGIC:
1589 * NA
1590 *
1591 *ASSUMPTIONS:
1592 * NA
1593 *
1594 *NOTE:
1595 *
1596 * @param pMac - Pointer to Global MAC structure
1597 * @return true - System is in Active state
1598 * false - System is not in Active state
1599 */
1600
1601tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac)
1602{
1603 switch (pMac->pmm.gPmmState)
1604 {
1605 case ePMM_STATE_BMPS_WAKEUP:
1606 case ePMM_STATE_IMPS_WAKEUP:
1607 case ePMM_STATE_READY:
1608 // System is in Active mode
1609 return true;
1610 default:
1611 return false;
1612 // System is NOT in Active mode
1613 }
1614}
1615
1616
1617#if defined(ANI_PRODUCT_TYPE_AP) && (WNI_POLARIS_FW_PACKAGE == ADVANCED)
1618/**
1619 * limCheckAndQuietBSS()
1620 *
1621 *FUNCTION:
1622 * This function is called by limSetLearnMode() to check
1623 * if BSS needs to be quieted and call limQuietBSS() to
1624 * send data frame to self for that purpose.
1625 *
1626 *LOGIC:
1627 * NA
1628 *
1629 *ASSUMPTIONS:
1630 * NA
1631 *
1632 *NOTE:
1633 *
1634 * @param pMac - Pointer to Global MAC structure
1635 * @return None
1636 */
1637
1638void
1639limCheckAndQuietBSS(tpAniSirGlobal pMac)
1640{
1641 tANI_U32 dur;
1642
1643 if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE)
1644 {
1645 // LIM is in AP role. Quiet the BSS before
1646 // switching to channel to be learned
1647 if (pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration >
1648 LIM_MAX_QUIET_DURATION)
1649 {
1650 // May need to quiet BSS multiple times.
1651 // Quiet for a limit of 32 msecs on Learn
1652 // duration for now.
1653 dur = LIM_MAX_QUIET_DURATION;
1654 }
1655 else
1656 {
1657 dur =
1658 pMac->lim.gpLimMeasReq->measDuration.shortChannelScanDuration;
1659 }
1660 PELOG3(limLog(pMac, LOG3,
1661 FL("*** Going to quiet BSS for duration=%d msec\n"),
1662 dur);)
1663
1664 limQuietBss(pMac, dur);
1665 }
1666} /*** end limCheckAndQuietBSS() ***/
1667#endif
1668
1669#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
1670/**
1671 * limSetLearnMode()
1672 *
1673 *FUNCTION:
1674 * This function is called to setup system into Learn mode
1675 * to collect DFS measurements.
1676 *
1677 *LOGIC:
1678 * NA
1679 *
1680 *ASSUMPTIONS:
1681 * NA
1682 *
1683 *NOTE:
1684 *
1685 * @param pMac - Pointer to Global MAC structure
1686 * @return None
1687 */
1688
1689void
1690limSetLearnMode(tpAniSirGlobal pMac)
1691{
1692 limSendHalInitScanReq(pMac, eLIM_HAL_INIT_LEARN_WAIT_STATE, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN);
1693 return;
1694} /*** end limSetLearnMode() ***/
1695
1696/**
1697 * limContinueChannelLearn()
1698 *
1699 *FUNCTION:
1700 * This function is called to do measurement (learn) on current channel.
1701 *
1702 *LOGIC:
1703 *
1704 *ASSUMPTIONS:
1705 * NA
1706 *
1707 *NOTE:
1708 * NA
1709 *
1710 * @param pMac - Pointer to Global MAC structure
1711 *
1712 * @return None
1713 */
1714
1715void
1716limContinueChannelLearn(tpAniSirGlobal pMac)
1717{
1718 tANI_U8 chanNum;
1719 tSirMacSSid ssId;
1720 tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1721
1722 // Time to collect measurements
1723 chanNum = limGetCurrentLearnChannel(pMac);
1724
1725 // Switch channel
1726 pMac->lim.gLimSystemInScanLearnMode = 1;
1727
1728 if (pMac->lim.gpLimMeasReq->measControl.scanType == eSIR_ACTIVE_SCAN)
1729 {
1730 /// Prepare and send Probe Request frame
1731 ssId.length = 0;
1732 /* for learning channel, we don't include any additional IE */
1733 limSendProbeReqMgmtFrame(pMac, &ssId, bssId, chanNum,pMac->lim.gSelfMacAddr, 0 , NULL);
1734 }
1735
1736 // Activate Learn duration timer during which
1737 // DFS measurements are made.
1738 pMac->lim.gLimMeasParams.shortDurationCount++;
1739 limDeactivateAndChangeTimer(pMac, eLIM_LEARN_DURATION_TIMER);
1740
1741 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_LEARN_DURATION_TIMER));
1742 if (tx_timer_activate(&pMac->lim.gLimMeasParams.learnDurationTimer)
1743 != TX_SUCCESS)
1744 {
1745 /// Could not activate learn duration timer.
1746 // Log error
1747 limLog(pMac, LOGP, FL("could not activate learn duration timer\n"));
1748
1749 return;
1750 }
1751} /*** end limContinueChannelLearn() ***/
1752
1753
1754/**
1755 * limReEnableLearnMode()
1756 *
1757 *FUNCTION:
1758 * This function is called by various MAC software modules to
1759 * re-enable Learn mode measurements.
1760 *
1761 *LOGIC:
1762 * NA
1763 *
1764 *ASSUMPTIONS:
1765 * NA
1766 *
1767 *NOTE:
1768 *
1769 * @param pMac - Pointer to Global MAC structure
1770 * @return None
1771 */
1772
1773void
1774limReEnableLearnMode(tpAniSirGlobal pMac)
1775{
1776 PELOG4(limLog(pMac, LOG4, FL("quietEnabled = %d\n"),
1777 pMac->lim.gLimSpecMgmt.fQuietEnabled);)
1778
1779 /** Stop measurement temperorily when radar is detected or channel
1780 * switch is running as part of periodic DFS */
1781 if (!pMac->lim.gpLimMeasReq || LIM_IS_RADAR_DETECTED(pMac) ||
1782 (pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING))
1783 {
1784 return;
1785 }
1786
1787 if (pMac->lim.gLimSpecMgmt.fQuietEnabled)
1788 {
1789 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_QUIET_BSS_TIMER));
1790#ifdef GEN6_TODO
1791 /* revisit this piece of code to assign the appropriate sessionId below
1792 * priority - HIGH
1793 */
1794 pMac->lim.limTimers.gLimQuietBssTimer.sessionId = sessionId;
1795#endif
1796 if (tx_timer_activate(
1797 &pMac->lim.limTimers.gLimQuietBssTimer)
1798 != TX_SUCCESS)
1799 {
1800 limLog(pMac, LOGP, FL("could not start Quiet Bss timer\n"));
1801 return;
1802 }
1803 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
1804 }
1805 else
1806 {
1807 limDeactivateAndChangeTimer(pMac, eLIM_LEARN_INTERVAL_TIMER);
1808 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_LEARN_INTERVAL_TIMER));
1809#ifdef GEN6_TODO
1810 /* revisit this piece of code to assign the appropriate sessionId below
1811 */
1812 pMac->lim.gLimMeasParams.learnIntervalTimer.sessionId = sessionId;
1813#endif
1814 if (tx_timer_activate(
1815 &pMac->lim.gLimMeasParams.learnIntervalTimer)
1816 != TX_SUCCESS)
1817 {
1818 /// Could not activate Learn Interval timer.
1819 // Log error
1820 limLog(pMac, LOGP, FL("could not start Learn Interval timer\n"));
1821 return;
1822 }
1823 }
1824
1825 PELOG3(limLog(pMac, LOG3, FL("Re-enabled Learn mode Measurements\n"));)
1826 pMac->lim.gLimMeasParams.disableMeasurements = 0;
1827
1828 return;
1829} /*** end limReEnableLearnMode() ***/
1830
1831#endif //#if (defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
1832
1833
1834/**
1835*\brief limReceivedHBHandler()
1836*
1837* This function is called by schBeaconProcess() upon
1838* receiving a Beacon on STA. This also gets called upon
1839* receiving Probe Response after heat beat failure is
1840* detected.
1841*
1842* param pMac - global mac structure
1843* param channel - channel number indicated in Beacon, Probe Response
1844* return - none
1845*/
1846
1847
1848void
1849limReceivedHBHandler(tpAniSirGlobal pMac, tANI_U8 channelId, tpPESession psessionEntry)
1850{
1851 if((channelId == 0 ) || (channelId == psessionEntry->currentOperChannel) )
1852 psessionEntry->LimRxedBeaconCntDuringHB++;
1853
1854 pMac->pmm.inMissedBeaconScenario = FALSE;
1855} /*** end limReceivedHBHandler() ***/
1856
1857
1858
1859#if 0
1860void limResetHBPktCount(tpPESession psessionEntry)
1861{
1862 psessionEntry->LimRxedBeaconCntDuringHB = 0;
1863}
1864#endif
1865
1866
1867/*
1868 * limProcessWdsInfo()
1869 *
1870 *FUNCTION:
1871 * This function is called from schBeaconProcess in BP
1872 *
1873 *PARAMS:
1874 * @param pMac - Pointer to Global MAC structure
1875 * @param propIEInfo - proprietary IE info
1876 *
1877 *LOGIC:
1878 *
1879 *ASSUMPTIONS:
1880 * NA
1881 *
1882 *NOTE:
1883 *
1884 *
1885 *RETURNS:
1886 *
1887 */
1888
1889void limProcessWdsInfo(tpAniSirGlobal pMac,
1890 tSirPropIEStruct propIEInfo)
1891{
1892#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
1893 tpSirSmeWdsInfoInd pSirSmeWdsInfoInd;
1894 tANI_U8 *pTemp;
1895 tSirMsgQ mmhMsg;
1896
1897 if (propIEInfo.wdsLength &&
1898 propIEInfo.wdsLength <= ANI_WDS_INFO_MAX_LENGTH)
1899 {
1900 if (pMac->lim.gLimWdsInfo.wdsLength)
1901 {
1902 if ((propIEInfo.wdsLength ==
1903 pMac->lim.gLimWdsInfo.wdsLength) &&
1904 (palEqualMemory( pMac->hHdd,propIEInfo.wdsData,
1905 pMac->lim.gLimWdsInfo.wdsBytes,
1906 pMac->lim.gLimWdsInfo.wdsLength) ))
1907
1908 return; // no difference in WDS info
1909 else
1910 {
1911 PELOG2(limLog(pMac, LOG2,
1912 FL("Cached WDS Info: length %d bytes is: "),
1913 pMac->lim.gLimWdsInfo.wdsLength);
1914 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2,
1915 pMac->lim.gLimWdsInfo.wdsBytes,
1916 pMac->lim.gLimWdsInfo.wdsLength);)
1917
1918 PELOG2(limLog(pMac, LOG2, FL("New WDS Info: length %d bytes is: "),
1919 propIEInfo.wdsLength);
1920 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2,
1921 propIEInfo.wdsData,
1922 propIEInfo.wdsLength);)
1923
1924 pMac->lim.gLimWdsInfo.wdsLength = propIEInfo.wdsLength;
1925 palCopyMemory( pMac->hHdd, pMac->lim.gLimWdsInfo.wdsBytes,
1926 propIEInfo.wdsData,
1927 propIEInfo.wdsLength);
1928
1929 // send IND to WSM
1930 if (eHAL_STATUS_SUCCESS !=
1931 palAllocateMemory(pMac->hHdd,
1932 (void **) &pSirSmeWdsInfoInd,
1933 sizeof(tSirSmeWdsInfoInd)))
1934 {
1935 // Log error
1936 limLog(pMac, LOGP,
1937 FL("memory allocate failed for WDS_INFO_IND\n"));
1938
1939 return;
1940 }
1941
1942 pSirSmeWdsInfoInd->messageType = eWNI_SME_WDS_INFO_IND;
1943 pSirSmeWdsInfoInd->length = sizeof(tSirSmeWdsInfoInd);
1944
1945 pSirSmeWdsInfoInd->wdsInfo.wdsLength =
1946 pMac->lim.gLimWdsInfo.wdsLength;
1947
1948 palCopyMemory( pMac->hHdd, pSirSmeWdsInfoInd->wdsInfo.wdsBytes,
1949 pMac->lim.gLimWdsInfo.wdsBytes,
1950 pMac->lim.gLimWdsInfo.wdsLength);
1951
1952 pTemp = (tANI_U8 *) pSirSmeWdsInfoInd;
1953
1954 PELOG2(limLog(pMac, LOG2,
1955 FL("eWNI_SME_WDS_INFO_IND length %d bytes is: "),
1956 pSirSmeWdsInfoInd->length);
1957 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, pTemp,
1958 pSirSmeWdsInfoInd->length);)
1959
1960 mmhMsg.type = eWNI_SME_WDS_INFO_IND;
1961 mmhMsg.bodyptr = pSirSmeWdsInfoInd;
1962 mmhMsg.bodyval = 0;
1963 MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
1964 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
1965 pMac->lim.gLimNumWdsInfoInd++;
1966 }
1967 }
1968 else
1969 {
1970 // first WDS info
1971 pMac->lim.gLimWdsInfo.wdsLength = propIEInfo.wdsLength;
1972 palCopyMemory( pMac->hHdd, pMac->lim.gLimWdsInfo.wdsBytes,
1973 propIEInfo.wdsData,
1974 propIEInfo.wdsLength);
1975
1976 PELOG1(limLog(pMac, LOG1, FL("First WDS Info: length %d bytes is:\n"),
1977 pMac->lim.gLimWdsInfo.wdsLength);
1978 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1,
1979 pMac->lim.gLimWdsInfo.wdsBytes,
1980 pMac->lim.gLimWdsInfo.wdsLength);)
1981
1982 }
1983 }
1984 else
1985 {
1986 PELOG2(limLog(pMac, LOG2,
1987 FL("Illegal WDS length = %d\n"),
1988 propIEInfo.wdsLength);)
1989 }
1990#endif
1991}
1992
1993
1994
1995/**
1996 * limInitWdsInfoParams()
1997 *
1998 *FUNCTION:
1999 * This function is called while processing
2000 * START_BSS/JOIN/REASSOC_REQ to initialize WDS info
2001 * ind/set related parameters.
2002 *
2003 *LOGIC:
2004 *
2005 *ASSUMPTIONS:
2006 *
2007 *NOTE:
2008 *
2009 * @param pMac Pointer to Global MAC structure
2010 * @return None
2011 */
2012
2013void
2014limInitWdsInfoParams(tpAniSirGlobal pMac)
2015{
2016 pMac->lim.gLimWdsInfo.wdsLength = 0;
2017 pMac->lim.gLimNumWdsInfoInd = 0;
2018 pMac->lim.gLimNumWdsInfoSet = 0;
2019} /*** limInitWdsInfoParams() ***/
2020
2021
2022/** -------------------------------------------------------------
2023\fn limUpdateOverlapStaParam
2024\brief Updates overlap cache and param data structure
2025\param tpAniSirGlobal pMac
2026\param tSirMacAddr bssId
2027\param tpLimProtStaParams pStaParams
2028\return None
2029 -------------------------------------------------------------*/
2030void
2031limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams)
2032{
2033 int i;
2034 if (!pStaParams->numSta)
2035 {
2036 palCopyMemory( pMac->hHdd, pMac->lim.protStaOverlapCache[0].addr,
2037 bssId,
2038 sizeof(tSirMacAddr));
2039 pMac->lim.protStaOverlapCache[0].active = true;
2040
2041 pStaParams->numSta = 1;
2042
2043 return;
2044 }
2045
2046 for (i=0; i<LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
2047 {
2048 if (pMac->lim.protStaOverlapCache[i].active)
2049 {
2050 if (palEqualMemory( pMac->hHdd,pMac->lim.protStaOverlapCache[i].addr,
2051 bssId,
2052 sizeof(tSirMacAddr))) {
2053 return; }
2054 }
2055 else
2056 break;
2057 }
2058
2059 if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE)
2060 {
2061 PELOG1(limLog(pMac, LOG1, FL("Overlap cache is full\n"));)
2062 }
2063 else
2064 {
2065 palCopyMemory( pMac->hHdd, pMac->lim.protStaOverlapCache[i].addr,
2066 bssId,
2067 sizeof(tSirMacAddr));
2068 pMac->lim.protStaOverlapCache[i].active = true;
2069
2070 pStaParams->numSta++;
2071 }
2072}
2073
2074
2075/**
2076 * limHandleIBSScoalescing()
2077 *
2078 *FUNCTION:
2079 * This function is called upon receiving Beacon/Probe Response
2080 * while operating in IBSS mode.
2081 *
2082 *LOGIC:
2083 *
2084 *ASSUMPTIONS:
2085 *
2086 *NOTE:
2087 *
2088 * @param pMac - Pointer to Global MAC structure
2089 * @param pBeacon - Parsed Beacon Frame structure
2090 * @param pRxPacketInfo - Pointer to RX packet info structure
2091 *
2092 * @return Status whether to process or ignore received Beacon Frame
2093 */
2094
2095tSirRetStatus
2096limHandleIBSScoalescing(
2097 tpAniSirGlobal pMac,
2098 tpSchBeaconStruct pBeacon,
2099 tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
2100{
2101 tpSirMacMgmtHdr pHdr;
2102 tSirRetStatus retCode;
2103
2104 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
2105 if ( (!pBeacon->capabilityInfo.ibss) || (limCmpSSid(pMac, &pBeacon->ssId,psessionEntry) != true) )
2106 /* Received SSID does not match => Ignore received Beacon frame. */
2107 retCode = eSIR_LIM_IGNORE_BEACON;
2108 else
2109 {
2110 tANI_U32 ieLen;
2111 tANI_U16 tsfLater;
2112 tANI_U8 *pIEs;
2113 ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
2114 tsfLater = WDA_GET_RX_TSF_LATER(pRxPacketInfo);
2115 pIEs = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
2116 PELOG3(limLog(pMac, LOG3, FL("BEFORE Coalescing tsfLater val :%d"), tsfLater);)
2117 retCode = limIbssCoalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,psessionEntry);
2118 }
2119 return retCode;
2120} /*** end limHandleIBSScoalescing() ***/
2121
2122
2123
2124/**
2125 * limDetectChangeInApCapabilities()
2126 *
2127 *FUNCTION:
2128 * This function is called while SCH is processing
2129 * received Beacon from AP on STA to detect any
2130 * change in AP's capabilities. If there any change
2131 * is detected, Roaming is informed of such change
2132 * so that it can trigger reassociation.
2133 *
2134 *LOGIC:
2135 *
2136 *ASSUMPTIONS:
2137 *
2138 *NOTE:
2139 * Notification is enabled for STA product only since
2140 * it is not a requirement on BP side.
2141 *
2142 * @param pMac Pointer to Global MAC structure
2143 * @param pBeacon Pointer to parsed Beacon structure
2144 * @return None
2145 */
2146
2147void
2148limDetectChangeInApCapabilities(tpAniSirGlobal pMac,
2149 tpSirProbeRespBeacon pBeacon,
2150 tpPESession psessionEntry)
2151{
2152#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
2153 tANI_U8 len;
2154 tSirSmeApNewCaps apNewCaps;
2155 tANI_U8 newChannel;
2156 apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);
2157 newChannel = (tANI_U8) pBeacon->channelNumber;
2158
2159 if ((psessionEntry->limSentCapsChangeNtf == false) &&
2160 (((!limIsNullSsid(&pBeacon->ssId)) && (limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) == false)) ||
2161 ((SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) != SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps)) ||
2162 (SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) != SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps)) ||
2163 (SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) != SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps)) ||
2164 (SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) != SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps)) ||
2165 (newChannel != psessionEntry->currentOperChannel)
2166#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
2167 || (LIM_BSS_CAPS_GET(HCF, psessionEntry->limCurrentBssQosCaps) !=
2168 pBeacon->propIEinfo.hcfEnabled)
2169#endif
2170 )))
2171 {
2172
2173 /**
2174 * BSS capabilities have changed.
2175 * Inform Roaming.
2176 */
2177 len = sizeof(tSirMacCapabilityInfo) +
2178 sizeof(tSirMacAddr) + sizeof(tANI_U8) +
2179 3 * sizeof(tANI_U8) + // reserved fields
2180 pBeacon->ssId.length + 1;
2181
2182 palCopyMemory( pMac->hHdd, apNewCaps.bssId,
2183 psessionEntry->bssId,
2184 sizeof(tSirMacAddr));
2185 if (newChannel != psessionEntry->currentOperChannel)
2186 {
2187 PELOGE(limLog(pMac, LOGE, FL("Channel Change from %d --> %d - "
2188 "Ignoring beacon!\n"),
2189 psessionEntry->currentOperChannel, newChannel);)
2190 return;
2191 }
2192 else
2193 apNewCaps.channelId = psessionEntry->currentOperChannel;
2194 palCopyMemory( pMac->hHdd, (tANI_U8 *) &apNewCaps.ssId,
2195 (tANI_U8 *) &pBeacon->ssId,
2196 pBeacon->ssId.length + 1);
2197
2198 psessionEntry->limSentCapsChangeNtf = true;
2199 limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_AP_CAPS_CHANGED,
2200 (tANI_U32 *) &apNewCaps,
2201 len, psessionEntry->smeSessionId);
2202 }
2203#endif
2204} /*** limDetectChangeInApCapabilities() ***/
2205
2206
2207
2208
2209// ---------------------------------------------------------------------
2210/**
2211 * limUpdateShortSlot
2212 *
2213 * FUNCTION:
2214 * Enable/Disable short slot
2215 *
2216 * LOGIC:
2217 *
2218 * ASSUMPTIONS:
2219 *
2220 * NOTE:
2221 *
2222 * @param enable Flag to enable/disable short slot
2223 * @return None
2224 */
2225
2226tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, tpSirProbeRespBeacon pBeacon, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry)
2227{
2228
2229 tSirSmeApNewCaps apNewCaps;
2230 tANI_U32 cShortSlot, nShortSlot;
2231
2232 apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo);
2233
2234 if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, &cShortSlot) != eSIR_SUCCESS)
2235 limLog(pMac, LOGP, FL("unable to get short slot time\n"));
2236
2237 // Earlier implementation: determine the appropriate short slot mode based on AP advertised modes
2238 // when erp is present, apply short slot always unless, prot=on && shortSlot=off
2239 // if no erp present, use short slot based on current ap caps
2240
2241 // Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4);
2242
2243 //Resolution : always use the shortSlot setting the capability info to decide slot time.
2244 // The difference between the earlier implementation and the new one is only Case4.
2245 /*
2246 ERP IE Present | useProtection | shortSlot = QC STA Short Slot
2247 Case1 1 1 1 1 //AP should not advertise this combination.
2248 Case2 1 1 0 0
2249 Case3 1 0 1 1
2250 Case4 1 0 0 0
2251 Case5 0 1 1 1
2252 Case6 0 1 0 0
2253 Case7 0 0 1 1
2254 Case8 0 0 0 0
2255 */
2256 nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo);
2257
2258 if (nShortSlot != cShortSlot)
2259 {
2260 // Short slot time capability of AP has changed. Adopt to it.
2261 PELOG1(limLog(pMac, LOG1, FL("Shortslot capability of AP changed: %d\n"), nShortSlot);)
2262 ((tpSirMacCapabilityInfo)&psessionEntry->limCurrentBssCaps)->shortSlotTime = (tANI_U16)nShortSlot;
2263 pBeaconParams->fShortSlotTime = (tANI_U8) nShortSlot;
2264 pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED;
2265
2266 if (cfgSetInt(pMac, WNI_CFG_SHORT_SLOT_TIME, nShortSlot) != eSIR_SUCCESS)
2267 PELOGE(limLog(pMac, LOGE, FL("could not update short slot time at CFG\n"));)
2268 }
2269 return eSIR_SUCCESS;
2270}
2271
2272
2273#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && defined(ANI_PRODUCT_TYPE_AP)
2274
2275/**
2276 * limUpdateQuietIEInBeacons()
2277 *
2278 *FUNCTION:
2279 * This function is called by specialBeaconProcessing(),
2280 * when it is time to generate the next beacon.
2281 * If gLimQuietState is not in the INIT state, then it
2282 * means that the next beacon may need to include some
2283 * information about the Quiet BSS IE.
2284 * This function makes that decision based on the current
2285 * state of gLimQuietState
2286 *
2287 *LOGIC:
2288 * This routine invokes schSetFixedBeaconFields() only
2289 * if necessary, as it is expensive to update the fixed
2290 * beacon fields during each beacon interval.
2291 *
2292 *ASSUMPTIONS:
2293 * This Quiet BSS IE will be sent out as part of
2294 * Proprietary IE's. If 802.11H is enabled, this IE
2295 * will be sent out as defined in the 11H spec
2296 *
2297 *NOTE:
2298 *
2299 * @param pMac Pointer to Global MAC structure
2300 * @return true, if the beacon fields need updating
2301 * false, if not
2302 */
2303tANI_BOOLEAN limUpdateQuietIEInBeacons( tpAniSirGlobal pMac )
2304{
2305 tANI_BOOLEAN fUpdateBeaconFields = eANI_BOOLEAN_TRUE;
2306
2307 limLog( pMac, LOG2, FL("Quiet BSS State = %d\n"),
2308 pMac->lim.gLimSpecMgmt.quietState );
2309 switch( pMac->lim.gLimSpecMgmt.quietState )
2310 {
2311 case eLIM_QUIET_BEGIN:
2312 // We need to start broadcasting the Quiet BSS IE
2313 // Transition to eLIM_QUIET_RUNNING
2314 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_RUNNING;
2315 break;
2316
2317 case eLIM_QUIET_RUNNING:
2318 // Start down-counting...
2319 pMac->lim.gLimSpecMgmt.quietCount--;
2320 if( pMac->lim.gLimSpecMgmt.quietCount == 0 )
2321 {
2322 //
2323 // We no longer need to broadcast the Quiet BSS IE
2324 //
2325 // NOTE - We still need to call schSetFixedBeaconFields()
2326 // one last time, just to remove the Quiet BSS IE from
2327 // the list of fixed beacon fields
2328 //
2329 // Transition to eLIM_QUIET_END
2330 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_END;
2331 limProcessLearnIntervalTimeout(pMac);
2332 }
2333 break;
2334
2335 case eLIM_QUIET_CHANGED:
2336 //
2337 // State possibly changed via setupQuietBss().
2338 // This means, gLimQuietCount has been changed!!
2339 //
2340 // NOTE - We still need to call schSetFixedBeaconFields()
2341 // one last time, just to remove the Quiet BSS IE from
2342 // the list of fixed beacon fields
2343 //
2344
2345 // Transition to eLIM_QUIET_END
2346 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_END;
2347 break;
2348
2349 case eLIM_QUIET_INIT:
2350 case eLIM_QUIET_END:
2351 // Transition to eLIM_QUIET_INIT
2352 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
2353 // Fall thru'...
2354 default:
2355 fUpdateBeaconFields = eANI_BOOLEAN_FALSE;
2356 break;
2357 }
2358
2359 return fUpdateBeaconFields;
2360}
2361
2362#endif
2363
2364#if ((defined ANI_PRODUCT_TYPE_AP) && (defined ANI_AP_SDK))
2365void limConvertScanDuration(tpAniSirGlobal pMac)
2366{
2367 tpSirSmeMeasurementReq pMeasReq = pMac->lim.gpLimMeasReq;
2368 tpLimScanDurationConvert scanDurConv = &pMac->lim.gLimScanDurationConvert;
2369
2370 /* This is not a good idea to convert {long}shortChannelScanDuration from mS to TICKS *
2371 * The reason is that {long}shortChannelScanDuration is used all over and a lot of code *
2372 * that assumes the old mS definition was never changed to accommodate this new change to TICKS. *
2373 * If optimization is needed, create another set of shadow variables to store the converted *
2374 * values in Ticks, and TU. */
2375 scanDurConv->shortChannelScanDuration_tick =
2376 SYS_MS_TO_TICKS(pMeasReq->measDuration.shortChannelScanDuration +SYS_TICK_DUR_MS-1);
2377
2378 /* convert shortChannelScanDuration to TU also for CB scan, used to set gLimQuietDuration */
2379 /* (shortChanneScanDuration * 1000) / 2^10 */
2380 scanDurConv->shortChannelScanDuration_TU = (pMeasReq->measDuration.shortChannelScanDuration * 1000) >> 10;
2381
2382 scanDurConv->longChannelScanDuration_tick =
2383 SYS_MS_TO_TICKS(pMeasReq->measDuration.longChannelScanDuration +SYS_TICK_DUR_MS-1);
2384
2385 /* convert shortChannelScanDuration to TU also for CB scan, used to set gLimQuietDuration */
2386 /* (longChanneScanDuration * 1000) / 2^10 */
2387 scanDurConv->longChannelScanDuration_TU = (pMeasReq->measDuration.longChannelScanDuration * 1000) >> 10;
2388}
2389#endif /* ((defined ANI_PRODUCT_TYPE_AP) && (defined ANI_AP_SDK)) */
2390
2391
2392#ifdef ANI_PRODUCT_TYPE_AP
2393/**-------------------------------------------------
2394\fn limIsRadarEnabled
2395
2396\brief Checks if radar is enabled
2397\param pMac
2398\return true - if Both 11h and radar enabled
2399 false - if either is not enabled.
2400 --------------------------------------------------*/
2401tANI_BOOLEAN limIsRadarEnabled(tpAniSirGlobal pMac)
2402{
2403 tANI_U32 fEnabled;
2404
2405 if(wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &fEnabled) != eSIR_SUCCESS)
2406 {
2407 limLog(pMac, LOGP, FL("HAL: could not retrieve radar config from CFG"));
2408 return eANI_BOOLEAN_FALSE;
2409 }
2410
2411 if (!fEnabled)
2412 return eANI_BOOLEAN_FALSE;
2413
2414 if(wlan_cfgGetInt(pMac, WNI_CFG_RDET_FLAG, &fEnabled) != eSIR_SUCCESS)
2415 {
2416 limLog(pMac, LOGP, FL("HAL: could not retrieve radar config from CFG"));
2417 return eANI_BOOLEAN_FALSE;
2418 }
2419
2420 if (fEnabled)
2421 return eANI_BOOLEAN_TRUE;
2422
2423 return eANI_BOOLEAN_FALSE;
2424}
2425
2426/**---------------------------------------
2427\fn limRadarInit
2428\brief Initialize Radar Interrupt.
2429
2430\param pMac
2431\return None
2432 ----------------------------------------*/
2433void limRadarInit(tpAniSirGlobal pMac)
2434{
2435 tANI_U32 status;
2436 tSirMsgQ msg;
2437
2438 PELOG3(limLog(pMac, LOG3, FL("Radar Interrupt Already configured? %s\n"),
2439 pMac->lim.gLimSpecMgmt.fRadarIntrConfigured?"Yes":"No");)
2440 /** To avoid configuring the radar multiple times */
2441 if (pMac->lim.gLimSpecMgmt.fRadarIntrConfigured)
2442 return;
2443
2444 if (!limIsRadarEnabled(pMac))
2445 return;
2446 // Prepare and post message to HAL Message Queue
2447 msg.type = WDA_INIT_RADAR_IND;
2448 msg.bodyptr = NULL;
2449 msg.bodyval = 0;
2450 MTRACE(macTraceMsgTx(pMac, 0, msg.type));
2451 status = wdaPostCtrlMsg(pMac, &msg);
2452 if (status != eHAL_STATUS_SUCCESS)
2453 {
2454 limLog(pMac, LOGP,
2455 FL("posting to HAL failed, reason=%d\n"), status);
2456 return;
2457 }
2458 pMac->lim.gLimSpecMgmt.fRadarIntrConfigured = eANI_BOOLEAN_TRUE;
2459} /****** end limRadarInit() ******/
2460
2461#endif
2462
2463
2464/** -----------------------------------------------------------------
2465 \brief limHandleLowRssiInd() - handles low rssi indication
2466
2467 This function process the SIR_HAL_LOW_RSSI_IND message from
2468 HAL, and sends a eWNI_SME_LOW_RSSI_IND to CSR.
2469
2470 \param pMac - global mac structure
2471
2472 \return
2473
2474 \sa
2475 ----------------------------------------------------------------- */
2476void limHandleLowRssiInd(tpAniSirGlobal pMac)
2477{
2478#if 0 //RSSI related indications will now go to TL and not PE
2479 if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) ||
2480 (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)||
2481 (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) )
2482 {
2483 PELOG1(limLog(pMac, LOG1, FL("Sending LOW_RSSI_IND to SME \n"));)
2484 limSendSmeRsp(pMac, eWNI_SME_LOW_RSSI_IND, eSIR_SME_SUCCESS, 0, 0);
2485 }
2486 else
2487 {
2488 limLog(pMac, LOGE,
2489 FL("Received SIR_HAL_LOW_RSSI_IND while in incorrect state: %d\n"),
2490 pMac->pmm.gPmmState);
2491 }
2492 return;
2493#endif
2494}
2495
2496
2497/** -----------------------------------------------------------------
2498 \brief limHandleBmpsStatusInd() - handles BMPS status indication
2499
2500 This function process the SIR_HAL_BMPS_STATUS_IND message from HAL,
2501 and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND
2502 to SME with reason code 'eSME_EXIT_BMPS_IND_RCVD'.
2503
2504 HAL sends this message when Firmware fails to enter BMPS mode 'AFTER'
2505 HAL had already send PE a SIR_HAL_ENTER_BMPS_RSP with status
2506 code "success". Hence, HAL needs to notify PE to get out of BMPS mode.
2507 This message can also come from FW anytime after we have entered BMPS.
2508 This means we should handle it in WoWL and UAPSD states as well
2509
2510 \param pMac - global mac structure
2511 \return - none
2512 \sa
2513 ----------------------------------------------------------------- */
2514void limHandleBmpsStatusInd(tpAniSirGlobal pMac)
2515{
2516 switch(pMac->pmm.gPmmState)
2517 {
2518 case ePMM_STATE_BMPS_SLEEP:
2519 case ePMM_STATE_UAPSD_WT_SLEEP_RSP:
2520 case ePMM_STATE_UAPSD_SLEEP:
2521 case ePMM_STATE_UAPSD_WT_WAKEUP_RSP:
2522 case ePMM_STATE_WOWLAN:
2523 PELOG1(limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME \n"));)
2524 limSendExitBmpsInd(pMac, eSME_BMPS_STATUS_IND_RCVD);
2525 break;
2526
2527 default:
2528 limLog(pMac, LOGE,
2529 FL("Received SIR_HAL_BMPS_STATUS_IND while in incorrect state: %d\n"),
2530 pMac->pmm.gPmmState);
2531 break;
2532 }
2533 return;
2534}
2535
2536
2537/** -----------------------------------------------------------------
2538 \brief limHandleMissedBeaconInd() - handles missed beacon indication
2539
2540 This function process the SIR_HAL_MISSED_BEACON_IND message from HAL,
2541 and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND
2542 to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'.
2543
2544 \param pMac - global mac structure
2545 \return - none
2546 \sa
2547 ----------------------------------------------------------------- */
2548void limHandleMissedBeaconInd(tpAniSirGlobal pMac)
2549{
2550 if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) ||
2551 (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)||
2552 (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) )
2553 {
2554 pMac->pmm.inMissedBeaconScenario = TRUE;
2555 PELOG1(limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME \n"));)
2556 limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD);
2557 }
2558 else
2559 {
2560 limLog(pMac, LOGE,
2561 FL("Received SIR_HAL_MISSED_BEACON_IND while in incorrect state: %d\n"),
2562 pMac->pmm.gPmmState);
2563 }
2564 return;
2565}
2566
2567/** -----------------------------------------------------------------
2568 \brief limMicFailureInd() - handles mic failure indication
2569
2570 This function process the SIR_HAL_MIC_FAILURE_IND message from HAL,
2571
2572 \param pMac - global mac structure
2573 \return - none
2574 \sa
2575 ----------------------------------------------------------------- */
2576void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
2577{
2578 tpSirSmeMicFailureInd pSirSmeMicFailureInd;
2579 tpSirSmeMicFailureInd pSirMicFailureInd = (tpSirSmeMicFailureInd)pMsg->bodyptr;
2580 tSirMsgQ mmhMsg;
2581 tpPESession psessionEntry ;
2582 tANI_U8 sessionId;
2583
2584 if((psessionEntry = peFindSessionByBssid(pMac,pSirMicFailureInd->bssId,&sessionId))== NULL)
2585 {
2586 limLog(pMac, LOGE,
2587 FL("session does not exist for given BSSId\n"));
2588 return;
2589 }
2590
2591 if (eHAL_STATUS_SUCCESS !=
2592 palAllocateMemory(pMac->hHdd,
2593 (void **) &pSirSmeMicFailureInd,
2594 sizeof(tSirSmeMicFailureInd)))
2595 {
2596 // Log error
2597 limLog(pMac, LOGP,
2598 FL("memory allocate failed for eWNI_SME_MIC_FAILURE_IND\n"));
2599 return;
2600 }
2601
2602 pSirSmeMicFailureInd->messageType = eWNI_SME_MIC_FAILURE_IND;
2603 pSirSmeMicFailureInd->length = sizeof(pSirSmeMicFailureInd);
2604 pSirSmeMicFailureInd->sessionId = psessionEntry->smeSessionId;
2605
2606 vos_mem_copy(pSirSmeMicFailureInd->bssId,
2607 pSirMicFailureInd->bssId,
2608 sizeof(tSirMacAddr));
2609
2610 vos_mem_copy(pSirSmeMicFailureInd->info.srcMacAddr,
2611 pSirMicFailureInd->info.srcMacAddr,
2612 sizeof(tSirMacAddr));
2613
2614 vos_mem_copy(pSirSmeMicFailureInd->info.taMacAddr,
2615 pSirMicFailureInd->info.taMacAddr,
2616 sizeof(tSirMacAddr));
2617
2618 vos_mem_copy(pSirSmeMicFailureInd->info.dstMacAddr,
2619 pSirMicFailureInd->info.dstMacAddr,
2620 sizeof(tSirMacAddr));
2621
2622 vos_mem_copy(pSirSmeMicFailureInd->info.rxMacAddr,
2623 pSirMicFailureInd->info.rxMacAddr,
2624 sizeof(tSirMacAddr));
2625
2626 pSirSmeMicFailureInd->info.multicast =
2627 pSirMicFailureInd->info.multicast;
2628
2629 pSirSmeMicFailureInd->info.keyId=
2630 pSirMicFailureInd->info.keyId;
2631
2632 pSirSmeMicFailureInd->info.IV1=
2633 pSirMicFailureInd->info.IV1;
2634
2635 vos_mem_copy(pSirSmeMicFailureInd->info.TSC,
2636 pSirMicFailureInd->info.TSC,SIR_CIPHER_SEQ_CTR_SIZE);
2637
2638 mmhMsg.type = eWNI_SME_MIC_FAILURE_IND;
2639 mmhMsg.bodyptr = pSirSmeMicFailureInd;
2640 mmhMsg.bodyval = 0;
2641 MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type));
2642 limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
2643 return;
2644}
2645
2646
2647/** -----------------------------------------------------------------
2648 \brief limIsPktCandidateForDrop() - decides whether to drop the frame or not
2649
2650 This function is called before enqueuing the frame to PE queue for further processing.
2651 This prevents unnecessary frames getting into PE Queue and drops them right away.
2652 Frames will be droped in the following scenarios:
2653
2654 - In Scan State, drop the frames which are not marked as scan frames
2655 - In non-Scan state, drop the frames which are marked as scan frames.
2656 - Drop INFRA Beacons and Probe Responses in IBSS Mode
2657 - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
2658
2659 \param pMac - global mac structure
2660 \return - none
2661 \sa
2662 ----------------------------------------------------------------- */
2663
2664tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType)
2665{
2666 tANI_U32 framelen;
2667 tANI_U8 *pBody;
2668 tSirMacCapabilityInfo capabilityInfo;
2669
2670 /*
2671 *
2672 * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames.
2673 * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames.
2674 * Allow other mgmt frames, they must be from our own AP, as we don't allow
2675 * other than beacons or probe responses in scan state.
2676 */
2677 if( (subType == SIR_MAC_MGMT_BEACON) ||
2678 (subType == SIR_MAC_MGMT_PROBE_RSP))
2679 {
2680 if(pMac->pmm.inMissedBeaconScenario)
2681 {
2682 PELOGE(limLog(pMac, LOGE, FL("Do not drop beacon and probe response - Missed beacon sceanrio"));)
2683 return eMGMT_DROP_NO_DROP;
2684 }
2685 if (limIsSystemInScanState(pMac))
2686 {
2687 if( WDA_IS_RX_IN_SCAN(pRxPacketInfo) )
2688 return eMGMT_DROP_NO_DROP;
2689 else
2690 return eMGMT_DROP_NON_SCAN_MODE_FRAME;
2691 }
2692 else if (WDA_IS_RX_IN_SCAN(pRxPacketInfo))
2693 {
2694 return eMGMT_DROP_SCAN_MODE_FRAME;
2695 }
2696 }
2697
2698 framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
2699 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
2700
2701 /* Note sure if this is sufficient, basically this condition allows all probe responses and
2702 * beacons from an infrastructure network
2703 */
2704 *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET);
2705 if(!capabilityInfo.ibss)
2706 return eMGMT_DROP_NO_DROP;
2707#if 0
2708 //Allow the mgmt frames to be queued if STA not in IBSS mode.
2709 if (pMac->lim.gLimSystemRole != eLIM_STA_IN_IBSS_ROLE)
2710 return eMGMT_DROP_NO_DROP;
2711#endif
2712
2713 //Drop INFRA Beacons and Probe Responses in IBSS Mode
2714 if( (subType == SIR_MAC_MGMT_BEACON) ||
2715 (subType == SIR_MAC_MGMT_PROBE_RSP))
2716 {
2717 //drop the frame if length is less than 12
2718 if(framelen < LIM_MIN_BCN_PR_LENGTH)
2719 return eMGMT_DROP_INVALID_SIZE;
2720
2721 *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET);
2722
2723 //This can be enhanced to even check the SSID before deciding to enque the frame.
2724 if(capabilityInfo.ess)
2725 return eMGMT_DROP_INFRA_BCN_IN_IBSS;
2726 }
2727 else if( (subType == SIR_MAC_MGMT_PROBE_REQ) &&
2728 (!WDA_GET_RX_BEACON_SENT(pRxPacketInfo)))
2729 {
2730 //Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
2731 //In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq
2732 return eMGMT_DROP_NOT_LAST_IBSS_BCN;
2733 }
2734
2735 return eMGMT_DROP_NO_DROP;
2736}
2737
2738