blob: f5471fa43f98d05ea8cbdeef7902679a98fa705e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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 pmmApi.cc contains functions related to the API exposed
25 * by power management module
26 *
27 * Author: Sandesh Goel
28 * Date: 02/25/02
29 * History:-
30 * Date Modified by Modification Information
31 * --------------------------------------------------------------------
32 *
33 */
34
35#include "palTypes.h"
36#include "wniCfgSta.h"
37
38#include "sirCommon.h"
39#include "aniGlobal.h"
40
41#include "schApi.h"
42#include "limApi.h"
43#include "limSendMessages.h"
44#include "cfgApi.h"
45#include "limSessionUtils.h"
46#include "limFT.h"
47
48
49#include "pmmApi.h"
50#include "pmmDebug.h"
51#include "sirApi.h"
52#include "wmmApsd.h"
53
54#include "limSendSmeRspMessages.h"
55#include "limTimerUtils.h"
56#include "limTrace.h"
57#include "limUtils.h"
58#include "VossWrapper.h"
59#ifdef INTEGRATION_READY
60#include "vos_status.h" //VOS_STATUS
61#include "vos_mq.h" //vos_mq_post_message()
62#endif
63
64#include "wlan_qct_wda.h"
65
66// --------------------------------------------------------------------
67/**
68 * pmmInitialize
69 *
70 * FUNCTION:
71 * Initialize PMM module
72 *
73 * LOGIC:
74 *
75 * ASSUMPTIONS:
76 *
77 * NOTE:
78 *
79 * @param mode
80 * @param rate
81 * @return None
82 */
83
84tSirRetStatus
85pmmInitialize(tpAniSirGlobal pMac)
86{
87
88#if (WNI_POLARIS_FW_PRODUCT == AP)
89 pMac->pmm.gPmmNextSta = 0;
90 pMac->pmm.gPmmNumSta = 0;
91#endif
92
93 pmmResetStats(pMac);
94
95 pMac->pmm.gPmmBeaconInterval = WNI_CFG_BEACON_INTERVAL_STADEF;
96 pMac->pmm.gPmmState = ePMM_STATE_READY;
97
98
99#ifdef ANI_PRODUCT_TYPE_AP
100
101 palZeroMemory(pMac->hHdd,
102 pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation);
103
104 palZeroMemory(pMac->hHdd,
105 pMac->pmm.gPmmTim.pStaInfo, sizeof(*pMac->pmm.gPmmTim.pStaInfo)*pMac->lim.maxStation);
106
107 palZeroMemory(pMac->hHdd,
108 pMac->pmm.gpPmmStaState, sizeof(tPmmStaState)*pMac->lim.maxStation);
109
110 palZeroMemory(pMac->hHdd,
111 pMac->pmm.gpPmmPSState, sizeof(tANI_U8)*pMac->lim.maxStation);
112#endif
113
114 pMac->pmm.inMissedBeaconScenario = FALSE;
115
116 return eSIR_SUCCESS;
117}
118
119// --------------------------------------------------------------------
120/**
121 * pmmResetStats
122 *
123 * FUNCTION:
124 * Resets the statistics
125 *
126 * LOGIC:
127 *
128 * ASSUMPTIONS:
129 *
130 * NOTE:
131 *
132 * @param pMac
133 *
134 * @return None
135 */
136
137void
138pmmResetStats(void *pvMac)
139{
140 tpAniSirGlobal pMac = (tpAniSirGlobal)pvMac;
141
142 pMac->pmm.BmpsmaxSleepTime = 0;
143 pMac->pmm.BmpsavgSleepTime = 0;
144 pMac->pmm.BmpsminSleepTime = 0;
145 pMac->pmm.BmpscntSleep = 0;
146
147 pMac->pmm.BmpsmaxTimeAwake = 0;
148 pMac->pmm.BmpsavgTimeAwake = 0;
149 pMac->pmm.BmpsminTimeAwake = 0;
150 pMac->pmm.BmpscntAwake = 0;
151
152 pMac->pmm.BmpsWakeupTimeStamp = 0;
153 pMac->pmm.BmpsSleepTimeStamp = 0;
154
155 pMac->pmm.BmpsHalReqFailCnt = 0;
156 pMac->pmm.BmpsInitFailCnt = 0;
157 pMac->pmm.BmpsInitFailCnt= 0;
158 pMac->pmm.BmpsInvStateCnt= 0;
159 pMac->pmm.BmpsPktDrpInSleepMode= 0;
160 pMac->pmm.BmpsReqInInvalidRoleCnt= 0;
161 pMac->pmm.BmpsSleeReqFailCnt= 0;
162 pMac->pmm.BmpsWakeupIndCnt= 0;
163
164 pMac->pmm.ImpsWakeupTimeStamp = 0;
165 pMac->pmm.ImpsSleepTimeStamp = 0;
166 pMac->pmm.ImpsMaxTimeAwake = 0;
167 pMac->pmm.ImpsMinTimeAwake = 0;
168 pMac->pmm.ImpsAvgTimeAwake = 0;
169 pMac->pmm.ImpsCntAwake = 0;
170
171 pMac->pmm.ImpsCntSleep = 0;
172 pMac->pmm.ImpsMaxSleepTime = 0;
173 pMac->pmm.ImpsMinSleepTime = 0;
174 pMac->pmm.ImpsAvgSleepTime = 0;
175
176 pMac->pmm.ImpsSleepErrCnt = 0;
177 pMac->pmm.ImpsWakeupErrCnt = 0;
178 pMac->pmm.ImpsLastErr = 0;
179 pMac->pmm.ImpsInvalidStateCnt = 0;
180
181 return;
182}
183
184
185
186// --------------------------------------------------------------------
187/**
188 * pmmInitBmpsResponseHandler
189 *
190 * FUNCTION:
191 * This function processes the SIR_HAL_ENTER_BMPS_RSP from HAL.
192 * If the response is successful, it puts PMM in ePMM_STATE_BMP_SLEEP state
193 * and sends back success response to PMC.
194 *
195 * LOGIC:
196 *
197 * ASSUMPTIONS:
198 *
199 * NOTE:
200 *
201 * @param
202 * @return None
203 */
204
205void pmmInitBmpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus)
206{
207
208
209 tPmmState nextState = pMac->pmm.gPmmState;
210 tSirResultCodes retStatus = eSIR_SME_SUCCESS;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700211 tpPESession psessionEntry;
Jeff Johnson295189b2012-06-20 16:38:30 -0700212
213 /* we need to process all the deferred messages enqueued since
214 * the initiating the SIR_HAL_ENTER_BMPS_REQ.
215 */
216 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
217
218 if(pMac->pmm.gPmmState != ePMM_STATE_BMPS_WT_INIT_RSP)
219 {
220 PELOGE(pmmLog(pMac, LOGE,
221 FL("pmmBmps: Received 'InitPwrSaveRsp' while in incorrect state: %d\n"),
222 pMac->pmm.gPmmState);)
223
224 retStatus = eSIR_SME_INVALID_PMM_STATE;
225 pmmBmpsUpdateInvalidStateCnt(pMac);
226 goto failure;
227 }
228
229 //if response is success, then set PMM to BMPS_SLEEP state and send response back to PMC.
230 //If response is failure, then send the response back to PMC and reset its state.
231 if(rspStatus == eHAL_STATUS_SUCCESS)
232 {
Mohit Khanna23863762012-09-11 17:40:09 -0700233 PELOG2(pmmLog(pMac, LOG2,
Jeff Johnson295189b2012-06-20 16:38:30 -0700234 FL("pmmBmps: Received successful response from HAL to enter BMPS_POWER_SAVE \n"));)
235
236 pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP;
237
238 // Update sleep statistics
239 pmmUpdatePwrSaveStats(pMac);
240
241 // Disable background scan mode
242 pMac->sys.gSysEnableScanMode = false;
243
244 if (pMac->lim.gLimTimersCreated)
245 {
246 /* Disable heartbeat timer as well */
247 if(pMac->lim.limTimers.gLimHeartBeatTimer.pMac)
248 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700249 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_HEART_BEAT_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer);
251 }
252 }
253 limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, retStatus, 0, 0);
254 }
255 else
256 {
257 //if init req failed, then go back to WAKEUP state.
258 PELOGE(pmmLog(pMac, LOGE,
259 FL("pmmBmps: BMPS_INIT_PWR_SAVE_REQ failed, informing SME\n"));)
260
261 pmmBmpsUpdateInitFailureCnt(pMac);
262 nextState = ePMM_STATE_BMPS_WAKEUP;
263 retStatus = eSIR_SME_BMPS_REQ_FAILED;
264 goto failure;
265 }
266 return;
267
268failure:
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700269 psessionEntry = peGetValidPowerSaveSession(pMac);
270 if(psessionEntry != NULL)
271 {
272 if (pMac->lim.gLimTimersCreated && pMac->lim.limTimers.gLimHeartBeatTimer.pMac)
273 {
274 if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer))
275 {
276 PELOGE(pmmLog(pMac, LOGE, FL("Unexpected heartbeat timer not running"));)
277 limReactivateHeartBeatTimer(pMac, psessionEntry);
278 }
279 }
280 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700281
282 //Generate an error response back to PMC
283 pMac->pmm.gPmmState = nextState;
284 pmmBmpsUpdateSleepReqFailureCnt(pMac);
285 limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, retStatus, 0, 0);
286 return;
287
288}
289
290// --------------------------------------------------------------------
291/**
292 * pmmExitBmpsRequestHandler
293 *
294 * FUNCTION:
295 * This function will send the wakeup message to HAL
296 *
297 * LOGIC:
298 *
299 * ASSUMPTIONS:
300 *
301 * NOTE:
302 *
303 * @param pMac pointer to Global Mac structure.
304
305 * @return None
306 */
307
308void pmmExitBmpsRequestHandler(tpAniSirGlobal pMac, tpExitBmpsInfo pExitBmpsInfo)
309{
310 tSirResultCodes respStatus = eSIR_SME_SUCCESS;
311
312 tPmmState origState = pMac->pmm.gPmmState;
313
314#ifdef FEATURE_WLAN_DIAG_SUPPORT
315 limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, (tANI_U16)pExitBmpsInfo->exitBmpsReason);
316#endif //FEATURE_WLAN_DIAG_SUPPORT
317
318 if (NULL == pExitBmpsInfo)
319 {
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700320 respStatus = eSIR_SME_BMPS_REQ_REJECT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 PELOGW(pmmLog(pMac, LOGW, FL("pmmBmps: Rcvd EXIT_BMPS with NULL body\n"));)
322 goto failure;
323 }
324
325 /* PMC is not aware of Background scan, which is done in
326 * BMPS mode while Nth Beacon is delivered. Essentially, PMC
327 * can request the device to get out of power-save while
328 * background scanning is happening. since, the device is already
329 * out of powersave, just inform that device is out of powersave
330 */
331 if(limIsSystemInScanState(pMac))
332 {
333 PELOGW(pmmLog(pMac, LOGW,
334 FL("pmmBmps: Device is already awake and scanning, returning success to PMC \n"));)
335 limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, respStatus, 0, 0);
336 return;
337 }
338
339 /* send wakeup request, only when in sleep state */
340 PELOGW(pmmLog(pMac, LOGW, FL("pmmBmps: Sending eWNI_PMC_EXIT_BMPS_REQ to HAL\n"));)
341 if (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP)
342 {
343 /* Store the reason code for exiting BMPS. This value will be
344 * checked when PMM receives SIR_HAL_EXIT_BMPS_RSP from HAL
345 */
346 pMac->pmm.gPmmExitBmpsReasonCode = pExitBmpsInfo->exitBmpsReason;
347 palFreeMemory( pMac->hHdd, (tANI_U8 *) pExitBmpsInfo);
348
349 PELOGW(pmmLog(pMac, LOGW,
350 FL("pmmBmps: Rcvd EXIT_BMPS with reason code%d \n"), pMac->pmm.gPmmExitBmpsReasonCode);)
351
352
353 // Set PMM to BMPS_WT_WAKEUP_RSP state
354 pMac->pmm.gPmmState = ePMM_STATE_BMPS_WT_WAKEUP_RSP;
355 if(pmmSendChangePowerSaveMsg(pMac) != eSIR_SUCCESS)
356 {
357 /* Wakeup request failed */
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700358 respStatus = eSIR_SME_BMPS_REQ_REJECT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700359 pmmBmpsUpdateHalReqFailureCnt(pMac);
360 goto failure;
361 }
362 else
363 {
364 PELOG1(pmmLog(pMac, LOG1,
365 FL("pmmBmps: eWNI_PMC_EXIT_BMPS_REQ was successfully sent to HAL\n"));)
366 }
367 }
368 else
369 {
370 PELOGE(pmmLog(pMac, LOGE,
371 FL("pmmBmps: eWNI_PMC_EXIT_BMPS_REQ received in invalid state: %d\n"),
372 pMac->pmm.gPmmState );)
373
374 respStatus = eSIR_SME_INVALID_PMM_STATE;
375 pmmBmpsUpdateInvalidStateCnt(pMac);
Madan Mohan Koyyalamudib666eb12012-09-18 17:29:47 -0700376 palFreeMemory( pMac->hHdd, (tANI_U8 *) pExitBmpsInfo);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 goto failure;
378 }
379 return;
380
381failure:
382 pMac->pmm.gPmmState = origState;
383 pmmBmpsUpdateWakeupReqFailureCnt(pMac);
384 limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, respStatus, 0, 0);
385}
386
387
388// --------------------------------------------------------------------
389/**
390 * pmmInitBmpsPwrSave
391 *
392 * FUNCTION:
393 * This function process the eWNI_PMC_ENTER_PMC_REQ from PMC.
394 * It checks for certain conditions before it puts PMM into
395 * BMPS power save state: ePMM_STATE_BMPS_WT_INIT_RSP
396 * It also invokes pmmSendInitPowerSaveMsg() to send ENTER_BMPS_REQ
397 * to HAL.
398 *
399 * LOGIC:
400 *
401 * ASSUMPTIONS:
402 *
403 * NOTE:
404 *
405 * @param mode can be either 0(sleep mode) or 1 (active mode)
406 * @param pMac pointer to Global Mac structure.
407
408 * @return None
409 */
410
411
412void pmmInitBmpsPwrSave(tpAniSirGlobal pMac)
413{
414 tSirRetStatus retStatus = eSIR_SUCCESS;
415 tSirResultCodes respStatus = eSIR_SME_SUCCESS;
416 tpPESession psessionEntry;
417
418 tPmmState origState = pMac->pmm.gPmmState;
419
420 if((psessionEntry = peGetValidPowerSaveSession(pMac))== NULL)
421 {
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700422 respStatus = eSIR_SME_BMPS_REQ_REJECT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700423 goto failure;
424 }
425#ifdef FEATURE_WLAN_DIAG_SUPPORT
426 limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT, psessionEntry, 0, 0);
427#endif //FEATURE_WLAN_DIAG_SUPPORT
428
429 if ( ((pMac->pmm.gPmmState != ePMM_STATE_READY) &&
430 (pMac->pmm.gPmmState != ePMM_STATE_BMPS_WAKEUP)) ||
431 limIsSystemInScanState(pMac) ||
Jeff Johnsone7245742012-09-05 17:12:55 -0700432 limIsChanSwitchRunning(pMac) ||
433 limIsInQuietDuration(pMac) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700434 {
435 PELOGE(pmmLog(pMac, LOGE,
436 FL("pmmBmps: BMPS Request received in invalid state PMM=%d, SME=%d, rejecting the initpwrsave request\n"),
437 pMac->pmm.gPmmState, pMac->lim.gLimSmeState);)
438
439 respStatus = eSIR_SME_INVALID_PMM_STATE;
440 pmmBmpsUpdateInvalidStateCnt(pMac);
441 goto failure;
442 }
443
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700444 //If we are in a missed beacon scenario, we should not be attempting to enter BMPS as heartbeat probe is going on
445 if(pMac->pmm.inMissedBeaconScenario)
446 {
447 if (pMac->lim.gLimTimersCreated && pMac->lim.limTimers.gLimHeartBeatTimer.pMac)
448 {
449 if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer))
450 {
451 PELOGE(pmmLog(pMac, LOGE, FL("Unexpected heartbeat timer not running"));)
452 limReactivateHeartBeatTimer(pMac, psessionEntry);
453 }
454 }
455 respStatus = eSIR_SME_BMPS_REQ_REJECT;
456 goto failure;
457 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700458
459 /* At this point, device is associated and PMM is not in BMPS_SLEEP state.
460 * Heartbeat timer not running is an indication that PE have detected a
461 * loss of link. In this case, reject BMPS request.
462 */
463 /* TODO : We need to have a better check. This check is not valid */
464#if 0
465 if ( (pMac->sys.gSysEnableLinkMonitorMode) && (pMac->lim.limTimers.gLimHeartBeatTimer.pMac) )
466 {
467 if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer))
468 {
469 PELOGE(pmmLog(pMac, LOGE,
470 FL("Reject BMPS_REQ because HeartBeatTimer is not running. \n"));)
471 respStatus = eSIR_SME_BMPS_REQ_FAILED;
472 goto failure;
473 }
474 }
475#endif
476
477 //If the following function returns SUCCESS, then PMM will wait for an explicit
478 //response message from softmac.
479
480 //changing PMM state before posting message to HAL, as this is a synchronous call to HAL
481 pMac->pmm.gPmmState = ePMM_STATE_BMPS_WT_INIT_RSP;
482 if((retStatus = pmmSendInitPowerSaveMsg(pMac,psessionEntry)) != eSIR_SUCCESS)
483 {
484 PELOGE(pmmLog(pMac, LOGE,
485 FL("pmmBmps: Init Power Save Request Failed: Sending Response: %d\n"),
486 retStatus);)
487
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700488 respStatus = eSIR_SME_BMPS_REQ_REJECT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700489 pmmBmpsUpdateHalReqFailureCnt(pMac);
490 goto failure;
491 }
492 //Update the powerSave sessionId
493 pMac->pmm.sessionId = psessionEntry->peSessionId;
494 return;
495
496failure:
497
498 // Change the state back to original state
499 pMac->pmm.gPmmState =origState;
500 limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, respStatus, 0, 0);
501 return;
502}
503
504
505/**
506 * pmmSendChangePowerSaveMsg()
507 *
508 *FUNCTION:
509 * This function is called to send SIR_HAL_EXIT_BMPS_REQ to HAL.
510 * This message will trigger HAL to program HW to wake up.
511 *
512 *LOGIC:
513 *
514 *ASSUMPTIONS:
515 * NA
516 *
517 *NOTE:
518 * NA
519 *
520 * @param pMac pointer to Global Mac structure.
521 * @return success if message send is ok, else false.
522 */
523tSirRetStatus pmmSendChangePowerSaveMsg(tpAniSirGlobal pMac)
524{
525 tSirRetStatus retStatus = eSIR_SUCCESS;
526 tpExitBmpsParams pExitBmpsParams;
527 tSirMsgQ msgQ;
Jeff Johnsone7245742012-09-05 17:12:55 -0700528 tpPESession psessionEntry;
Jeff Johnson295189b2012-06-20 16:38:30 -0700529 tANI_U8 currentOperatingChannel = limGetCurrentOperatingChannel(pMac);
530
531 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pExitBmpsParams, sizeof(*pExitBmpsParams)) )
532 {
533 pmmLog(pMac, LOGW, FL("palAllocateMemory() failed\n"));
534 retStatus = eSIR_MEM_ALLOC_FAILED;
535 return retStatus;
536 }
537
Jeff Johnsone7245742012-09-05 17:12:55 -0700538 if((psessionEntry = peGetValidPowerSaveSession(pMac)) == NULL )
539 {
540 retStatus = eSIR_FAILURE;
541 return retStatus;
542 }
543
Jeff Johnson295189b2012-06-20 16:38:30 -0700544 palZeroMemory( pMac->hHdd, (tANI_U8 *)pExitBmpsParams, sizeof(*pExitBmpsParams));
545 msgQ.type = WDA_EXIT_BMPS_REQ;
546 msgQ.reserved = 0;
547 msgQ.bodyptr = pExitBmpsParams;
548 msgQ.bodyval = 0;
549
550 /* If reason for full power is disconnecting (ie. link is
551 * disconnected) or becasue of channel switch or full power requested
552 * because of beacon miss and connected on DFS channel
553 * then we should not send data null.
554 * For all other reason code, send data null.
555 */
556 if ( !(SIR_IS_FULL_POWER_REASON_DISCONNECTED(pMac->pmm.gPmmExitBmpsReasonCode) ||
557 ( (eSME_MISSED_BEACON_IND_RCVD == pMac->pmm.gPmmExitBmpsReasonCode) &&
558 limIsconnectedOnDFSChannel(currentOperatingChannel))))
559 pExitBmpsParams->sendDataNull = 1;
560
Jeff Johnsone7245742012-09-05 17:12:55 -0700561 pExitBmpsParams->bssIdx = psessionEntry->bssIdx;
562
Jeff Johnson295189b2012-06-20 16:38:30 -0700563 /* we need to defer any incoming messages until we
564 * get a WDA_EXIT_BMPS_RSP from HAL.
565 */
566 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
Jeff Johnsone7245742012-09-05 17:12:55 -0700567 MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700568 retStatus = wdaPostCtrlMsg( pMac, &msgQ);
569 if( eSIR_SUCCESS != retStatus )
570 {
571 PELOGE(pmmLog( pMac, LOGE, FL("Sending WDA_EXIT_BMPS_REQ failed, reason=%X \n"), retStatus );)
572 palFreeMemory(pMac->hHdd, (tANI_U8*)pExitBmpsParams);
573 return retStatus;
574 }
575
576 PELOG1(pmmLog(pMac, LOG1, FL("WDA_EXIT_BMPS_REQ has been successfully sent to HAL\n"));)
577 return retStatus;
578}
579
580
581/**
582 * pmmSendInitPowerSaveMsg()
583 *
584 *FUNCTION:
585 * This function is called to send ENTER_BMPS_REQ message to HAL.
586 * This message is sent to intialize the process of bringing the
587 * station into power save state.
588 *
589 *LOGIC:
590 *
591 *ASSUMPTIONS:
592 * NA
593 *
594 *NOTE:
595 * NA
596 *
597 * @param pMac pointer to Global Mac structure.
598 * @param mode The Power Save or Active State
599 *
600 * @return success if message send is ok, else false.
601 */
602
603tSirRetStatus pmmSendInitPowerSaveMsg(tpAniSirGlobal pMac,tpPESession psessionEntry)
604{
605 tSirRetStatus retCode = eSIR_SUCCESS;
606 tSirMsgQ msgQ;
607 tpEnterBmpsParams pBmpsParams = NULL;
608 int i=0;
609
610 tANI_U32 rssiFilterPeriod = 5;
611 tANI_U32 numBeaconPerRssiAverage = 5;
612 tANI_U32 bRssiFilterEnable = FALSE;
613
614 if(psessionEntry->currentBssBeaconCnt == 0)
615 {
616 PELOGE(pmmLog( pMac, LOGE, FL("Beacon count is zero, can not retrieve the TSF, failing the Enter Bmps Request\n"));)
617 return eSIR_FAILURE;
618 }
619
620 if (palAllocateMemory(pMac->hHdd, (void **)&pBmpsParams, sizeof(tEnterBmpsParams)) != eHAL_STATUS_SUCCESS)
621 {
622 pmmLog(pMac, LOGP, "PMM: Not able to allocate memory for Enter Bmps\n");
623 return eSIR_FAILURE;
624 }
625
626 pMac->pmm.inMissedBeaconScenario = FALSE;
627 pBmpsParams->respReqd = TRUE;
628
629 pBmpsParams->tbtt = psessionEntry->lastBeaconTimeStamp;
630 pBmpsParams->dtimCount = psessionEntry->lastBeaconDtimCount;
631 pBmpsParams->dtimPeriod = psessionEntry->lastBeaconDtimPeriod;
632 pBmpsParams->bssIdx = psessionEntry->bssIdx;
633
634 if(wlan_cfgGetInt(pMac, WNI_CFG_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS)
635 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period"));
636
637 // This flag can be overridden when 11r/CCXEnabled=1 and FastTransition=1
638 if(wlan_cfgGetInt(pMac, WNI_CFG_PS_ENABLE_RSSI_MONITOR, &bRssiFilterEnable) != eSIR_SUCCESS)
639 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi monitor enable flag"));
640 pBmpsParams->bRssiFilterEnable = bRssiFilterEnable;
641
642
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700643#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 // If there is a CCX assoc or 11r assoc we need to pick up the rssiFilterPeriod from the
645 // FT config value.
646 for(i =0; i < pMac->lim.maxBssId; i++)
647 {
648 if (limisFastTransitionRequired(pMac, i))
649 {
650 if(wlan_cfgGetInt(pMac, WNI_CFG_FT_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS)
651 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period"));
652 // We need to override the ini value to enable
653 // FW RSSI Monitoring. Basically if CCX and FT are enabled
654 // then enable FW RSSI Monitoring
655
656 pBmpsParams->bRssiFilterEnable = TRUE;
657 break;
658 }
659 }
660#endif
661
662 pBmpsParams->rssiFilterPeriod = (tANI_U8)rssiFilterPeriod;
663
664 /* The numBeaconPerRssiAverage should be <= rssiFilter Period,
665 * and less than the max allowed (default set to 20 in CFG)
666 */
667 if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, &numBeaconPerRssiAverage) != eSIR_SUCCESS)
668 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for num beacon per rssi"));
669
670 pBmpsParams->numBeaconPerRssiAverage = (tANI_U8) numBeaconPerRssiAverage;
671 if (numBeaconPerRssiAverage > rssiFilterPeriod)
672 pBmpsParams->numBeaconPerRssiAverage =
673 (tANI_U8)GET_MIN_VALUE(rssiFilterPeriod, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX);
674
675 pmmLog (pMac, LOG1,
676 "%s: [INFOLOG]RssiFilterInfo..%d %x %x\n", __func__, (int)pBmpsParams->bRssiFilterEnable,
677 (unsigned int)pBmpsParams->rssiFilterPeriod, (unsigned int)pBmpsParams->numBeaconPerRssiAverage);
678
679 msgQ.type = WDA_ENTER_BMPS_REQ;
680 msgQ.reserved = 0;
681 msgQ.bodyptr = pBmpsParams;
682 msgQ.bodyval = 0;
683
Mohit Khanna23863762012-09-11 17:40:09 -0700684 PELOG2(pmmLog( pMac, LOG2,
Jeff Johnson295189b2012-06-20 16:38:30 -0700685 FL( "pmmBmps: Sending WDA_ENTER_BMPS_REQ" ));)
686
687 /* we need to defer any incoming messages until we get a
688 * WDA_ENTER_BMPS_RSP from HAL.
689 */
690 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
691
Jeff Johnsone7245742012-09-05 17:12:55 -0700692 MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700693 if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
694 {
695 palFreeMemory(pMac->hHdd, pBmpsParams);
696 PELOGE(pmmLog( pMac, LOGE,
697 FL("Posting WDA_ENTER_BMPS_REQ to HAL failed, reason=%X\n"),
698 retCode );)
699 }
700
701 return retCode;
702}
703
704/**
705 * pmmSendPowerSaveCfg()
706 *
707 *FUNCTION:
708 * This function is called to send power save configurtion.
709 *
710 *NOTE:
711 *
712 * @param pMac pointer to Global Mac structure.
713 * @param mode The Power Save or Active State
714 *
715 * @return success if message send is ok, else false.
716 */
717tSirRetStatus pmmSendPowerSaveCfg(tpAniSirGlobal pMac, tpSirPowerSaveCfg pUpdatedPwrSaveCfg)
718{
719 tSirRetStatus retCode = eSIR_SUCCESS;
720 tSirMsgQ msgQ;
721 tANI_U32 listenInterval;
722 tANI_U32 HeartBeatCount = 1;
723 tANI_U32 maxPsPoll;
724 tANI_U32 numBeaconPerRssiAverage;
725 tANI_U32 minRssiThreshold;
726 tANI_U32 nthBeaconFilter;
727 tANI_U32 broadcastFrameFilter;
728 tANI_U32 rssiFilterPeriod;
729 tANI_U32 ignoreDtim;
730
731 if (NULL == pUpdatedPwrSaveCfg)
732 goto returnFailure;
733
734 if(pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE )
735 {
736 pmmLog(pMac, LOGE,
Jeff Johnsone7245742012-09-05 17:12:55 -0700737 FL("pmmCfg: Power Save Configuration received in invalid global sme state %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700738 pMac->lim.gLimSmeState);
739 retCode = eSIR_SME_INVALID_STATE;
740 goto returnFailure;
741 }
742
743 // Get power save configuration CFG values
744 if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS)
745 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for listen interval"));
746 pUpdatedPwrSaveCfg->listenInterval = (tANI_U16)listenInterval;
747
748 if(wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &HeartBeatCount) != eSIR_SUCCESS)
749 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for heart beat thresh"));
750
751 pMac->lim.gLimHeartBeatCount = HeartBeatCount;
752 pUpdatedPwrSaveCfg->HeartBeatCount = HeartBeatCount;
753
754 if(wlan_cfgGetInt(pMac, WNI_CFG_NTH_BEACON_FILTER, &nthBeaconFilter) != eSIR_SUCCESS)
755 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Nth beacon filter"));
756 pUpdatedPwrSaveCfg->nthBeaconFilter = nthBeaconFilter;
757
758 if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_PS_POLL, &maxPsPoll) != eSIR_SUCCESS)
759 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for max poll"));
760 pUpdatedPwrSaveCfg->maxPsPoll = maxPsPoll;
761
762 if(wlan_cfgGetInt(pMac, WNI_CFG_MIN_RSSI_THRESHOLD, &minRssiThreshold) != eSIR_SUCCESS)
763 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for min RSSI Threshold"));
764 pUpdatedPwrSaveCfg->minRssiThreshold = minRssiThreshold;
765
766 if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, &numBeaconPerRssiAverage) != eSIR_SUCCESS)
767 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for num beacon per rssi"));
768 pUpdatedPwrSaveCfg->numBeaconPerRssiAverage = (tANI_U8) numBeaconPerRssiAverage;
769
770 if(wlan_cfgGetInt(pMac, WNI_CFG_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS)
771 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period"));
772 pUpdatedPwrSaveCfg->rssiFilterPeriod = (tANI_U8) rssiFilterPeriod;
773
774 if(wlan_cfgGetInt(pMac, WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE, &broadcastFrameFilter) != eSIR_SUCCESS)
775 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Nth beacon filter"));
776 pUpdatedPwrSaveCfg->broadcastFrameFilter = (tANI_U8) broadcastFrameFilter;
777
778 if(wlan_cfgGetInt(pMac, WNI_CFG_IGNORE_DTIM, &ignoreDtim) != eSIR_SUCCESS)
779 pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for ignoreDtim"));
780 pUpdatedPwrSaveCfg->ignoreDtim = (tANI_U8) ignoreDtim;
781
782 /* The numBeaconPerRssiAverage should be <= rssiFilter Period,
783 * and less than the max allowed (default set to 20 in CFG)
784 */
785 if (numBeaconPerRssiAverage > rssiFilterPeriod)
786 pUpdatedPwrSaveCfg->numBeaconPerRssiAverage = (tANI_U8)GET_MIN_VALUE(rssiFilterPeriod, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX);
787
788 //Save a copy of the CFG in global pmm context.
789 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pMac->pmm.gPmmCfg, pUpdatedPwrSaveCfg, sizeof(tSirPowerSaveCfg));
790
791
792 msgQ.type = WDA_PWR_SAVE_CFG;
793 msgQ.reserved = 0;
794 msgQ.bodyptr = pUpdatedPwrSaveCfg;
795 msgQ.bodyval = 0;
796
797 PELOG1(pmmLog( pMac, LOG1, FL( "pmmBmps: Sending WDA_PWR_SAVE_CFG to HAL"));)
Jeff Johnsone7245742012-09-05 17:12:55 -0700798 MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -0700799 if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
800 {
801 pmmLog( pMac, LOGP,
802 FL("Posting WDA_PWR_SAVE_CFG to HAL failed, reason=%X"),
803 retCode );
804 goto returnFailure;
805 }
806 return retCode;
807
808returnFailure:
809
810 /* In case of failure, we need to free the memory */
811 if (NULL != pUpdatedPwrSaveCfg)
812 {
813 palFreeMemory( pMac->hHdd, (tANI_U8 *) pUpdatedPwrSaveCfg);
814 }
815 return retCode;
816}
817
818/**
819 * pmmExitBmpsResponseHandler
820 *
821 *FUNCTION:
822 * This function processes the Wakeup Rsp from HAL and if successfull,
823 * sends a respnose back to PMC layer.
824 *LOGIC:
825 *
826 *ASSUMPTIONS:
827 * NA
828 *
829 *NOTE:
830 * NA
831 *
832 * @param pMac pointer to Global Mac structure.
833 * @param rspStatus Status of the response, Success or an error code.
834 *
835 * @return none.
836 */
837void pmmExitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
838{
839 tpExitBmpsParams pExitBmpsRsp;
840 eHalStatus rspStatus;
841 tANI_U8 PowersavesessionId;
842 tpPESession psessionEntry;
843 tSirResultCodes retStatus = eSIR_SME_SUCCESS;
844
845 /* Copy the power save sessionId to the local variable */
846 PowersavesessionId = pMac->pmm.sessionId;
847
848 /* we need to process all the deferred messages enqueued since
849 * the initiating the SIR_HAL_EXIT_BMPS_REQ.
850 */
851
852 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
853
854 if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL)
855 {
856 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
857 return;
858 }
859
860
861
862 /* Update wakeup statistics */
863 pmmUpdateWakeupStats(pMac);
864
865 if (NULL == limMsg->bodyptr)
866 {
867 pmmLog(pMac, LOGE, FL("Received SIR_HAL_EXIT_BMPS_RSP with NULL "));
868 return;
869 }
870 pExitBmpsRsp = (tpExitBmpsParams)(limMsg->bodyptr);
871 rspStatus = pExitBmpsRsp->status;
872
873 if(pMac->pmm.gPmmState != ePMM_STATE_BMPS_WT_WAKEUP_RSP)
874 {
875 PELOGE(pmmLog(pMac, LOGE,
876 FL("Received SIR_HAL_EXIT_BMPS_RSP while in incorrect state: %d\n"),
877 pMac->pmm.gPmmState);)
878
879 retStatus = eSIR_SME_INVALID_PMM_STATE;
880 pmmBmpsUpdateInvalidStateCnt(pMac);
881 }
882 else
883 {
884 PELOGW(pmmLog(pMac, LOGW, FL("Received SIR_HAL_EXIT_BMPS_RSP in correct state. \n"));)
885 }
886
887 /* PE is going to wakeup irrespective of whether
888 * SIR_HAL_EXIT_BMPS_REQ was successful or not
889 */
890 switch (rspStatus)
891 {
892 case eHAL_STATUS_SUCCESS:
893 retStatus = eSIR_SME_SUCCESS;
894 break;
895
896 default:
897 {
898 /* PE is going to be awake irrespective of whether EXIT_BMPS_REQ
899 * failed or not. This is mainly to eliminate the dead-lock condition
900 * But, PMC will be informed about the error.
901 */
902 retStatus = eSIR_SME_BMPS_REQ_FAILED;
903 }
904 break;
905
906 }
907
908 pMac->pmm.gPmmState = ePMM_STATE_BMPS_WAKEUP;
909 pmmUpdateWakeupStats(pMac);
910
911 // turn on background scan
912 pMac->sys.gSysEnableScanMode = true;
913
914 // send response to PMC
Mohit Khanna349bc392012-09-11 17:24:52 -0700915 if(IS_SLM_SESSIONIZATION_SUPPORTED_BY_FW )
Jeff Johnsone7245742012-09-05 17:12:55 -0700916 {
917 limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, retStatus,
918 psessionEntry->smeSessionId, psessionEntry->transactionId);
919 }
920 else
921 {
922 limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, retStatus, 0, 0);
923 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700924
925 if ( pMac->pmm.gPmmExitBmpsReasonCode == eSME_MISSED_BEACON_IND_RCVD)
926 {
927 PELOGW(pmmLog(pMac, LOGW, FL("Rcvd SIR_HAL_EXIT_BMPS_RSP with MISSED_BEACON\n"));)
928 pmmMissedBeaconHandler(pMac);
929 }
930 else if(pMac->pmm.inMissedBeaconScenario)
931 {
932 PELOGW(pmmLog(pMac, LOGW, FL("Rcvd SIR_HAL_EXIT_BMPS_RSP in missed beacon scenario but reason code not correct"));)
933 pmmMissedBeaconHandler(pMac);
934 }
935 else
936 {
937 // Enable heartbeat timer
938 limReactivateHeartBeatTimer(pMac, psessionEntry);
939 }
940 return;
941}
942
943
944/**
945 * pmmMissedBeaconHandler()
946 *
947 *FUNCTION:
948 * This function is called when PMM receives an eWNI_PMC_EXIT_BMPS_REQ
949 * with reason code being eSME_MISSED_BEACON_IND_RCVD.
950 *
951 *NOTE:
952 * @param pMac pointer to Global Mac structure.
953 * @return none
954 */
955void pmmMissedBeaconHandler(tpAniSirGlobal pMac)
956{
957 tANI_U8 pwrSaveSessionId;
958 tANI_U32 beaconInterval = 0;
959 tANI_U32 heartBeatInterval = pMac->lim.gLimHeartBeatCount;
960 tpPESession psessionEntry;
961
962 /* Copy the power save sessionId to the local variable */
963 pwrSaveSessionId = pMac->pmm.sessionId;
964
965 if((psessionEntry = peFindSessionBySessionId(pMac,pwrSaveSessionId))==NULL)
966 {
967 limLog(pMac, LOGE,FL("Session Does not exist for given sessionID\n"));
968 return;
969 }
970
971
972 PELOGE(pmmLog(pMac, LOG1, FL("The device woke up due to MISSED BEACON \n"));)
973
974 /* Proceed only if HeartBeat timer is created */
975 if((pMac->lim.limTimers.gLimHeartBeatTimer.pMac) &&
976 (pMac->lim.gLimTimersCreated))
977 {
978 if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &beaconInterval) != eSIR_SUCCESS)
979 PELOG1(pmmLog(pMac, LOG1, FL("Fail to get BEACON_INTERVAL value\n"));)
980
981 /* Change timer to reactivate it in future */
982 heartBeatInterval= SYS_MS_TO_TICKS(beaconInterval * heartBeatInterval);
983
984 if( tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer,
985 (tANI_U32)heartBeatInterval, 0) != TX_SUCCESS)
986 {
987 PELOG1(pmmLog(pMac, LOG1, FL("Fail to change HeartBeat timer\n"));)
988 }
989
990 /* update some statistics */
991 if(LIM_IS_CONNECTION_ACTIVE(psessionEntry))
992 {
993 if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
994 pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++;
995 else
996 pMac->lim.gLimHeartBeatBeaconStats[0]++;
997 }
998
999 /* To handle the missed beacon failure, message is being posted to self as if the
1000 * actual timer has expired. This is done to make sure that there exists one
1001 * common entry and exit points
1002 */
1003 //limResetHBPktCount(pMac); // 090805: Where did this come from?
1004 limResetHBPktCount(psessionEntry); // 090805: This is what it SHOULD be. If we even need it.
1005 pmmSendMessageToLim(pMac, SIR_LIM_HEART_BEAT_TIMEOUT);
1006 }
1007 else
1008 {
1009 PELOGE(pmmLog(pMac, LOGE, FL("HeartBeat Timer is not created, cannot re-activate\n"));)
1010 }
1011
1012 return;
1013}
1014
1015
1016/**
1017 * pmmExitBmpsIndicationHandler
1018 *
1019 *FUNCTION:
1020 * This function sends a Power Save Indication. back to PMC layer.
1021 * This indication is originated from softmac and will occur in the following two
1022 * scenarios:
1023 * 1) When softmac is in sleep state and wakes up to parse TIM and finds that
1024 * AP has the data pending for this STA, then it sends this indication to let PMC know
1025 * that it is going to be awake and pass the control over to PMC
1026 * 2) When softmac is in sleep state and wakes up to parse TIM and determines that
1027 * current TIM is DTIM and AP has buffered broadcast/multicast frames.
1028 * In this scenario, softmac needs to remain awake for broadcast/multicast frames and it
1029 * sends an indication to PMC that it is awake and passes the control over to PMC.
1030 * 3) If station is awake and 'fEnablePwrSaveImmediately' flag is set, then softmac will transmit all
1031 * frames in its queues and go to sleep. Before going to sleep it sends the notification to PMC that
1032 * it is going to sleep.
1033 *LOGIC:
1034 *
1035 *ASSUMPTIONS:
1036 * NA
1037 *
1038 *NOTE:
1039 * NA
1040 *
1041 * @param pMac pointer to Global Mac structure.
1042 * @param rspStatus Status of the response, Success or an error code.
1043 *
1044 * @return none.
1045 */
1046
1047void pmmExitBmpsIndicationHandler(tpAniSirGlobal pMac, tANI_U8 mode, eHalStatus rspStatus)
1048{
1049
1050 tANI_U32 beaconInterval = 0;
1051 tANI_U32 heartBeatInterval = pMac->lim.gLimHeartBeatCount;
1052 tANI_U8 powersavesessionId;
1053 tpPESession psessionEntry;
1054
1055 /* Copy the power save sessionId to the local variable */
1056 powersavesessionId = pMac->pmm.sessionId;
1057
1058 psessionEntry = peFindSessionBySessionId(pMac,powersavesessionId);
1059
1060 if(psessionEntry == NULL)
1061 {
1062 PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId :%d \n"),powersavesessionId);)
1063 return;
1064 }
1065
1066 /* Since, the hardware is already wokenup, PE also wakesup and informs
1067 * the upper layers that the system is waking up. Hence always Success is
1068 * sent in the reason code for the message sent to PMC
1069 */
1070
1071 PELOGW(pmmLog(pMac, LOGW,
1072 FL("pmmBmps: Received SIR_HAL_EXIT_BMPS_IND from HAL, Exiting BMPS sleep mode\n")); )
1073
1074
1075 pMac->pmm.gPmmState = ePMM_STATE_BMPS_WAKEUP;
1076 pmmUpdateWakeupStats(pMac);
1077
1078 /* turn on background scan */
1079 pMac->sys.gSysEnableScanMode = true;
1080
1081 pmmBmpsUpdateWakeupIndCnt(pMac);
1082
1083 /* Inform SME about the system awake state */
1084 limSendSmeRsp(pMac,
1085 eWNI_PMC_EXIT_BMPS_IND,
1086 eSIR_SME_SUCCESS, 0, 0);
1087
1088 switch(rspStatus)
1089 {
1090
1091 /* The SoftMAC sends wakeup indication even when Heart-Beat timer expired
1092 * The PE should start taking action against this as soon as it identifies
1093 * that the SoftMAC has identified heart-beat miss
1094 */
1095 case eHAL_STATUS_HEARTBEAT_TMOUT:
1096 {
1097 PELOG1(pmmLog(pMac, LOG1,
1098 FL("pmmBmps: The device woke up due to HeartBeat Timeout\n"));)
1099
1100 /* Proceed only if HeartBeat timer is created */
1101 if((pMac->lim.limTimers.gLimHeartBeatTimer.pMac) &&
1102 (pMac->lim.gLimTimersCreated))
1103 {
1104
1105 /* Read the beacon interval from sessionTable */
1106 beaconInterval = psessionEntry->beaconParams.beaconInterval;
1107
1108 /* Change timer to reactivate it in future */
1109 heartBeatInterval= SYS_MS_TO_TICKS(beaconInterval * heartBeatInterval);
1110
1111 if(tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer,
1112 (tANI_U32)heartBeatInterval, 0) != TX_SUCCESS)
1113 {
1114 PELOG1(pmmLog(pMac, LOG1,
1115 FL("pmmBmps: Unable to change HeartBeat timer\n"));)
1116 }
1117
1118 /* update some statistics */
1119 if(LIM_IS_CONNECTION_ACTIVE(psessionEntry))
1120 {
1121 if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
1122 pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++;
1123 else
1124 pMac->lim.gLimHeartBeatBeaconStats[0]++;
1125 }
1126
1127 /* To handle the heartbeat failure, message is being posted to self as if the
1128 * actual timer has expired. This is done to make sure that there exists one
1129 * common entry and exit points
1130 */
1131 pmmSendMessageToLim(pMac, SIR_LIM_HEART_BEAT_TIMEOUT);
1132
1133 }
1134 else
1135 {
1136
1137 PELOGE(pmmLog(pMac, LOGE,
1138 FL("pmmBmps: HeartBeat Timer is not created, cannot re-activate\n"));)
1139 }
1140 }
1141 break;
1142
1143 case eHAL_STATUS_NTH_BEACON_DELIVERY:
1144 break;
1145
1146 default:
1147 break;
1148
1149 }
1150
1151 return;
1152
1153}
1154
1155
1156// --------------------------------------------------------------------
1157/**
1158 * pmmProcessMessageQueue
1159 *
1160 * FUNCTION:
1161 *
1162 * LOGIC:
1163 *
1164 * ASSUMPTIONS:
1165 *
1166 * NOTE:
1167 *
1168 * @param None
1169 * @return None
1170 */
1171
1172void pmmProcessMessageQueue(tpAniSirGlobal pMac)
1173{
1174#if 0
1175 tSirMsgQ msg;
1176
1177 while (1)
1178 {
1179 if (tx_queue_receive(&pMac->sys.gSirPmmMsgQ, (void *) &msg, TX_WAIT_FOREVER)
1180 != TX_SUCCESS)
1181 break;
1182
1183 pmmProcessMessage(pMac, &msg);
1184 }
1185#endif
1186}
1187
1188// --------------------------------------------------------------------
1189/**
1190 * pmmProcessMessage
1191 *
1192 * FUNCTION: Processes the next received Power Management message
1193 *
1194 * LOGIC:
1195 *
1196 * ASSUMPTIONS:
1197 *
1198 * NOTE:
1199 *
1200 * @param None
1201 * @return None
1202 */
1203
1204void pmmProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
1205{
1206 switch (pMsg->type)
1207 {
1208 case eWNI_PMC_PWR_SAVE_CFG:
1209 {
1210 tpSirPowerSaveCfg pPSCfg;
1211 tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr;
1212
1213 if (palAllocateMemory(pMac->hHdd, (void **)&pPSCfg, sizeof(tSirPowerSaveCfg)) != eHAL_STATUS_SUCCESS)
1214 {
1215 pmmLog(pMac, LOGP, "PMM: Not able to allocate memory for PMC Config\n");
1216 }
1217 (void) palCopyMemory(pMac->hHdd, pPSCfg, pMbMsg->data, sizeof(tSirPowerSaveCfg));
1218 (void) pmmSendPowerSaveCfg(pMac, pPSCfg);
1219
1220 // sending beacon filtering information down to HAL
1221 if (limSendBeaconFilterInfo(pMac) != eSIR_SUCCESS)
1222 pmmLog(pMac, LOGE, FL("Fail to send Beacon Filter Info \n"));
1223 }
1224 break;
1225
1226 case eWNI_PMC_ENTER_BMPS_REQ:
1227 pmmInitBmpsPwrSave(pMac);
1228 break;
1229
1230 case WDA_ENTER_BMPS_RSP:
1231 pmmInitBmpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval);
1232 break;
1233
1234 case eWNI_PMC_EXIT_BMPS_REQ:
1235 {
1236 tpExitBmpsInfo pExitBmpsInfo;
1237 tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr;
1238
1239 if (palAllocateMemory(pMac->hHdd, (void **)&pExitBmpsInfo, sizeof(tExitBmpsInfo)) != eHAL_STATUS_SUCCESS)
1240 {
1241 pmmLog(pMac, LOGP, "PMM: Failed to allocate memory for Exit BMPS Info \n");
1242 }
1243 (void) palCopyMemory(pMac->hHdd, pExitBmpsInfo, pMbMsg->data, sizeof(tExitBmpsInfo));
1244 (void) pmmExitBmpsRequestHandler(pMac, pExitBmpsInfo);
1245 }
1246 break;
1247
1248 case WDA_EXIT_BMPS_RSP:
1249 pmmExitBmpsResponseHandler(pMac, pMsg);
1250 break;
1251
1252 case WDA_EXIT_BMPS_IND:
1253 pmmExitBmpsIndicationHandler(pMac, SIR_PM_ACTIVE_MODE, (eHalStatus)pMsg->bodyval);
1254 break;
1255
1256 case eWNI_PMC_ENTER_IMPS_REQ:
1257 pmmEnterImpsRequestHandler(pMac);
1258 break;
1259
1260 case WDA_ENTER_IMPS_RSP:
1261 pmmEnterImpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval);
1262 break;
1263
1264 case eWNI_PMC_EXIT_IMPS_REQ:
1265 pmmExitImpsRequestHandler(pMac);
1266 break;
1267
1268 case WDA_EXIT_IMPS_RSP:
1269 pmmExitImpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval);
1270 break;
1271
1272 case eWNI_PMC_ENTER_UAPSD_REQ:
1273 pmmEnterUapsdRequestHandler(pMac);
1274 break;
1275
1276 case WDA_ENTER_UAPSD_RSP:
1277 pmmEnterUapsdResponseHandler(pMac, pMsg);
1278 break;
1279
1280 case eWNI_PMC_EXIT_UAPSD_REQ:
1281 pmmExitUapsdRequestHandler(pMac);
1282 break;
1283
1284 case WDA_EXIT_UAPSD_RSP:
1285 pmmExitUapsdResponseHandler(pMac, (eHalStatus)pMsg->bodyval);
1286 break;
1287
1288 case eWNI_PMC_WOWL_ADD_BCAST_PTRN:
1289 pmmSendWowlAddBcastPtrn(pMac, pMsg);
1290 break;
1291
1292 case eWNI_PMC_WOWL_DEL_BCAST_PTRN:
1293 pmmSendWowlDelBcastPtrn(pMac, pMsg);
1294 break;
1295
1296 case eWNI_PMC_ENTER_WOWL_REQ:
1297 pmmEnterWowlRequestHandler(pMac, pMsg);
1298 break;
1299
1300 case WDA_WOWL_ENTER_RSP:
1301 pmmEnterWowlanResponseHandler(pMac, pMsg);
1302 break;
1303
1304 case eWNI_PMC_EXIT_WOWL_REQ:
1305 pmmExitWowlanRequestHandler(pMac);
1306 break;
1307
1308 case WDA_WOWL_EXIT_RSP:
1309 pmmExitWowlanResponseHandler(pMac, (eHalStatus)pMsg->bodyval);
1310 break;
1311#ifdef WLAN_FEATURE_PACKET_FILTERING
1312 case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP:
1313 pmmFilterMatchCountResponseHandler(pMac, pMsg);
1314 break;
1315#endif // WLAN_FEATURE_PACKET_FILTERING
1316
1317
1318#ifdef WLAN_FEATURE_GTK_OFFLOAD
1319 case WDA_GTK_OFFLOAD_GETINFO_RSP:
1320 pmmGTKOffloadGetInfoResponseHandler(pMac, pMsg);
1321 break;
1322#endif // WLAN_FEATURE_GTK_OFFLOAD
1323
1324 default:
1325 PELOGW(pmmLog(pMac, LOGW,
1326 FL("PMM: Unknown message in pmmMsgQ type %d, potential memory leak!!\n"),
1327 pMsg->type);)
1328 }
1329
1330 if (NULL != pMsg->bodyptr)
1331 {
1332 palFreeMemory(pMac->hHdd, (tANI_U8 *)pMsg->bodyptr);
1333 pMsg->bodyptr = NULL;
1334 }
1335}
1336
1337
1338
1339
1340
1341
1342// --------------------------------------------------------------------
1343/**
1344 * pmmPostMessage
1345 *
1346 * FUNCTION:
1347 * Post a message to the pmm message queue
1348 *
1349 * LOGIC:
1350 *
1351 * ASSUMPTIONS:
1352 *
1353 * NOTE:
1354 *
1355 * @param pMsg pointer to message
1356 * @return None
1357 */
1358
1359tSirRetStatus
1360pmmPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
1361{
1362#if defined(VOSS_ENABLED)
1363 VOS_STATUS vosStatus;
1364 vosStatus = vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg);
1365 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1366 {
1367 pmmLog(pMac, LOGP, FL("vos_mq_post_message failed with status code %d\n"), vosStatus);
1368 return eSIR_FAILURE;
1369 }
1370#elif defined(ANI_OS_TYPE_WINDOWS)
1371 pmmProcessMessage(pMac, pMsg);
1372#else
1373 if (tx_queue_send(&pMac->sys.gSirPmmMsgQ, pMsg, TX_NO_WAIT) != TX_SUCCESS)
1374 return eSIR_FAILURE;
1375
1376#endif // VOSS_ENABLED
1377
1378 return eSIR_SUCCESS;
1379}
1380
1381
1382
1383
1384
1385/**
1386 * pmmUpdatePwrSaveStats
1387 *
1388 * FUNCTION: updated BMPS stats, when Station is going into power save state.
1389 *
1390 * LOGIC:
1391 *
1392 * ASSUMPTIONS:
1393 *
1394 * NOTE:
1395 *
1396 * @param pMac pointer to Global MAC Structure.
1397 * @return None
1398 */
1399
1400void pmmUpdatePwrSaveStats(tpAniSirGlobal pMac)
1401{
1402/*
1403 tANI_U64 TimeAwake = 0;
1404
1405 pMac->pmm.BmpsSleepTimeStamp = vos_timer_get_system_ticks();
1406
1407 if (pMac->pmm.BmpsWakeupTimeStamp)
1408 TimeAwake = (pMac->pmm.BmpsSleepTimeStamp - pMac->pmm.BmpsWakeupTimeStamp) /10;
1409 else
1410 TimeAwake = 0; // very first time
1411
1412 if (TimeAwake > pMac->pmm.BmpsmaxTimeAwake)
1413 {
1414 pMac->pmm.BmpsmaxTimeAwake = TimeAwake;
1415 }
1416
1417 if ((!pMac->pmm.BmpsminTimeAwake) || (TimeAwake < pMac->pmm.BmpsminTimeAwake))
1418 {
1419 pMac->pmm.BmpsminTimeAwake = TimeAwake;
1420 }
1421
1422 pMac->pmm.BmpsavgTimeAwake = ( ( (pMac->pmm.BmpsavgTimeAwake * pMac->pmm.BmpscntSleep) + TimeAwake ) / (pMac->pmm.BmpscntSleep + 1) );
1423
1424 pMac->pmm.BmpscntSleep++;
1425 return;
1426*/
1427}
1428
1429
1430
1431
1432/**
1433 * pmmUpdatePwrSaveStats
1434 *
1435 * FUNCTION: updated BMPS stats, when Station is waking up.
1436 *
1437 * LOGIC:
1438 *
1439 * ASSUMPTIONS:
1440 *
1441 * NOTE:
1442 *
1443 * @param pMac pointer to Global MAC Structure.
1444 * @return None
1445 */
1446
1447void pmmUpdateWakeupStats(tpAniSirGlobal pMac)
1448{
1449/*
1450
1451 tANI_U64 SleepTime = 0;
1452
1453 pMac->pmm.BmpsWakeupTimeStamp = vos_timer_get_system_ticks();
1454 SleepTime = (pMac->pmm.BmpsWakeupTimeStamp - pMac->pmm.BmpsSleepTimeStamp) / 10;
1455
1456 if (SleepTime > pMac->pmm.BmpsmaxSleepTime)
1457 {
1458 pMac->pmm.BmpsmaxSleepTime = SleepTime;
1459 }
1460
1461 if ((!pMac->pmm.BmpsminSleepTime) || (SleepTime < pMac->pmm.BmpsminSleepTime))
1462 {
1463 pMac->pmm.BmpsminSleepTime = SleepTime;
1464 }
1465
1466 pMac->pmm.BmpsavgSleepTime = ( ( (pMac->pmm.BmpsavgSleepTime * pMac->pmm.BmpscntAwake) + SleepTime ) / (pMac->pmm.BmpscntAwake + 1) );
1467
1468 pMac->pmm.BmpscntAwake++;
1469 return;
1470*/
1471}
1472
1473// --------------------------------------------------------------------
1474/**
1475 * pmmEnterImpsRequestHandler
1476 *
1477 * FUNCTION:
1478 * This function sends the idle mode power save request from host device
1479 * drive to HAL. This function is called from pmmProcessMsg()
1480 *
1481 * LOGIC:
1482 *
1483 * ASSUMPTIONS:
1484 * None
1485 *
1486 * NOTE:
1487 *
1488 * @param Global handle to MAC
1489 * @return None
1490 */
1491void pmmEnterImpsRequestHandler (tpAniSirGlobal pMac)
1492{
1493
1494 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
1495 tSirRetStatus retStatus = eSIR_SUCCESS;
1496 tPmmState origState = pMac->pmm.gPmmState;
1497
1498#ifdef FEATURE_WLAN_DIAG_SUPPORT
1499 limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0);
1500#endif //FEATURE_WLAN_DIAG_SUPPORT
1501
1502 /*Returns True even single active session present */
1503 if(peIsAnySessionActive(pMac))
1504 {
1505 resultCode = eSIR_SME_INVALID_STATE;
1506 goto failure;
1507 }
1508
1509 if ( ((pMac->pmm.gPmmState != ePMM_STATE_READY) &&
1510 (pMac->pmm.gPmmState != ePMM_STATE_IMPS_WAKEUP)) ||
1511 ((pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE) &&
1512 (pMac->lim.gLimSmeState != eLIM_SME_JOIN_FAILURE_STATE)) ||
1513 (pMac->lim.gLimMlmState != eLIM_MLM_IDLE_STATE) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07001514 limIsChanSwitchRunning (pMac) ||
1515 limIsInQuietDuration (pMac) )
Jeff Johnson295189b2012-06-20 16:38:30 -07001516 {
1517 PELOGE(pmmLog(pMac, LOGE,
Jeff Johnsone7245742012-09-05 17:12:55 -07001518 FL("pmmImps: PMM State = %d, Global MLM State = %d, Global SME State = %d, rejecting the sleep mode request\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001519 pMac->pmm.gPmmState, pMac->lim.gLimMlmState, pMac->lim.gLimSmeState);)
1520
1521 resultCode = eSIR_SME_INVALID_PMM_STATE;
1522 pmmImpsUpdateErrStateStats(pMac);
1523 goto failure;
1524 }
1525
1526 // change PE state and send the request to HAL
1527 pMac->pmm.gPmmState = ePMM_STATE_IMPS_WT_SLEEP_RSP;
1528 if( (retStatus = pmmImpsSendChangePwrSaveMsg(pMac, SIR_PM_SLEEP_MODE)) != eSIR_SUCCESS)
1529 {
1530 PELOGE(pmmLog(pMac, LOGE,
1531 FL("pmmImps: IMPS Sleep Request failed: sending response: %x\n"), retStatus);)
1532
1533 resultCode = eSIR_SME_IMPS_REQ_FAILED;
1534 goto failure;
1535 }
1536 else
1537 {
1538 PELOG1(pmmLog(pMac, LOG1,
1539 FL("pmmImps: Waiting for SoftMac response for IMPS request\n"));)
1540 }
1541 return;
1542
1543failure:
1544 pMac->pmm.gPmmState = origState;
1545 pmmImpsUpdateSleepErrStats(pMac, retStatus);
1546
1547 limSendSmeRsp(pMac,
1548 eWNI_PMC_ENTER_IMPS_RSP,
1549 resultCode, 0, 0);
1550
1551}
1552
1553// --------------------------------------------------------------------
1554/**
1555 * pmmEnterImpsResponseHandler
1556 *
1557 * FUNCTION:
1558 * This function receives the response from HAL layer for the idle mode
1559 * power save request sent. The function is also responsible for checking
1560 * the correctness of the system state before configuring the new state
1561 * on success. This function is called by pmmProcessMsg()
1562 *
1563 * LOGIC:
1564 *
1565 * ASSUMPTIONS:
1566 * None
1567 *
1568 * NOTE:
1569 *
1570 * @param Global handle to MAC, Status code
1571 * @return None
1572 */
1573void pmmEnterImpsResponseHandler (tpAniSirGlobal pMac, eHalStatus rspStatus)
1574{
1575 tPmmState nextState = pMac->pmm.gPmmState;
1576 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
1577
1578 /* we need to process all the deferred messages enqueued since
1579 * the initiating the WDA_ENTER_IMPS_REQ.
1580 */
1581 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1582
1583 if(pMac->pmm.gPmmState != ePMM_STATE_IMPS_WT_SLEEP_RSP)
1584 {
1585 PELOGE(pmmLog(pMac, LOGE,
1586 FL("pmmImps: Receives IMPS sleep rsp in invalid state: %d\n"),
1587 pMac->pmm.gPmmState);)
1588
1589 resultCode = eSIR_SME_INVALID_PMM_STATE;
1590 pmmImpsUpdateErrStateStats(pMac);
1591
1592 goto failure;
1593 }
1594
1595 if(eHAL_STATUS_SUCCESS == rspStatus)
1596 {
1597 //if success, change the state to IMPS sleep mode
1598 pMac->pmm.gPmmState = ePMM_STATE_IMPS_SLEEP;
1599
Mohit Khanna23863762012-09-11 17:40:09 -07001600 PELOG2(pmmLog(pMac, LOG2,
Jeff Johnson295189b2012-06-20 16:38:30 -07001601 FL("pmmImps: Received successful WDA_ENTER_IMPS_RSP from HAL\n"));)
1602
1603 //update power save statistics
1604 pmmImpsUpdatePwrSaveStats(pMac);
1605
1606 limSendSmeRsp(pMac,
1607 eWNI_PMC_ENTER_IMPS_RSP,
1608 resultCode, 0, 0);
1609 }
1610 else
1611 {
1612 // go back to previous state if request failed
1613 nextState = ePMM_STATE_IMPS_WAKEUP;
1614 resultCode = eSIR_SME_CANNOT_ENTER_IMPS;
1615 goto failure;
1616 }
1617 return;
1618
1619failure:
1620 PELOGE(pmmLog(pMac, LOGE,
1621 FL("pmmImpsSleepRsp failed, Ret Code: %d, next state will be: %d\n"),
1622 rspStatus,
1623 pMac->pmm.gPmmState);)
1624
1625 pMac->pmm.gPmmState = nextState;
1626
1627 limSendSmeRsp(pMac,
1628 eWNI_PMC_ENTER_IMPS_RSP,
1629 resultCode, 0, 0);
1630}
1631
1632
1633// --------------------------------------------------------------------
1634/**
1635 * pmmExitImpsRequestHandler
1636 *
1637 * FUNCTION:
1638 * This function is called by pmmProcessMsg(). The function sends a request
1639 * to HAL to wakeup the device from idle mode power save mode.
1640 *
1641 * LOGIC:
1642 *
1643 * ASSUMPTIONS:
1644 * None
1645 *
1646 * NOTE:
1647 *
1648 * @param Global handle to MAC
1649 * @return None
1650 */
1651void pmmExitImpsRequestHandler (tpAniSirGlobal pMac)
1652{
1653 tSirRetStatus retStatus = eSIR_SUCCESS;
1654 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
1655
1656 tPmmState origState = pMac->pmm.gPmmState;
1657
1658#ifdef FEATURE_WLAN_DIAG_SUPPORT
1659 limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0);
1660#endif //FEATURE_WLAN_DIAG_SUPPORT
1661
1662 if (ePMM_STATE_IMPS_SLEEP == pMac->pmm.gPmmState)
1663 {
1664 pMac->pmm.gPmmState = ePMM_STATE_IMPS_WT_WAKEUP_RSP;
1665 if( (retStatus = pmmImpsSendChangePwrSaveMsg(pMac, SIR_PM_ACTIVE_MODE)) !=
1666 eSIR_SUCCESS)
1667 {
1668 PELOGE(pmmLog(pMac, LOGE,
1669 FL("pmmImps: Wakeup request message sent to SoftMac failed\n"));)
1670 resultCode = eSIR_SME_IMPS_REQ_FAILED;
1671 goto failure;
1672 }
1673 }
1674 else
1675 {
1676 // PE in invalid state
1677 PELOGE(pmmLog(pMac, LOGE,
1678 FL("pmmImps: Wakeup Req received in invalid state: %x\n"),
1679 pMac->pmm.gPmmState);)
1680
1681 resultCode = eSIR_SME_INVALID_PMM_STATE;
1682 pmmImpsUpdateErrStateStats(pMac);
1683
1684 goto failure;
1685 }
1686 return;
1687
1688failure:
1689 PELOGE(pmmLog (pMac, LOGE,
1690 FL("pmmImps: Changing to IMPS wakeup mode failed, Ret Code: %d, Next State: %d\n"),
1691 retStatus, pMac->pmm.gPmmState);)
1692
1693 pMac->pmm.gPmmState = origState;
1694 pmmImpsUpdateWakeupErrStats(pMac, retStatus);
1695
1696 limSendSmeRsp(pMac,
1697 eWNI_PMC_EXIT_IMPS_RSP,
1698 resultCode, 0, 0);
1699}
1700
1701
1702// --------------------------------------------------------------------
1703/**
1704 * pmmExitImpsResponseHandler
1705 *
1706 * FUNCTION:
1707 * This function receives the response from HAL layer for the idle mode
1708 * power save request sent. The function is also responsible for checking
1709 * the correctness of the system state before configuring the new state
1710 * on success. This function is called by pmmProcessMsg()
1711 *
1712 * LOGIC:
1713 *
1714 * ASSUMPTIONS:
1715 * None
1716 *
1717 * NOTE:
1718 *
1719 * @param Global handle to MAC
1720 * @return None
1721 */
1722void pmmExitImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus)
1723{
1724 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
1725
1726 /* we need to process all the deferred messages enqueued since
1727 * the initiating the WDA_EXIT_IMPS_REQ.
1728 */
1729 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1730
1731 if (pMac->pmm.gPmmState != ePMM_STATE_IMPS_WT_WAKEUP_RSP)
1732 {
1733 PELOGE(pmmLog(pMac, LOGE,
1734 FL("pmmImps: Received 'Wakeup' response in invalid state: %d\n"),
1735 pMac->pmm.gPmmState);)
1736
1737 resultCode = eSIR_SME_INVALID_PMM_STATE;
1738 pmmImpsUpdateErrStateStats(pMac);
1739 }
1740
1741 switch(rspStatus)
1742 {
1743 case eHAL_STATUS_SUCCESS:
1744 {
1745 resultCode = eSIR_SME_SUCCESS;
Mohit Khanna23863762012-09-11 17:40:09 -07001746 PELOG2(pmmLog(pMac, LOG2,
Jeff Johnson295189b2012-06-20 16:38:30 -07001747 FL("pmmImps: Received WDA_EXIT_IMPS_RSP with Successful response from HAL\n"));)
1748 }
1749 break;
1750
1751 default:
1752 {
1753 resultCode = eSIR_SME_IMPS_REQ_FAILED;
1754 PELOGW(pmmLog(pMac, LOGW,
1755 FL("pmmImps: Received WDA_EXIT_IMPS_RSP with Failure Status from HAL\n"));)
1756 }
1757 break;
1758
1759 }
1760
1761 pMac->pmm.gPmmState = ePMM_STATE_IMPS_WAKEUP;
1762
1763 //update power save statistics
1764 pmmImpsUpdateWakeupStats(pMac);
1765
1766 limSendSmeRsp(pMac,
1767 eWNI_PMC_EXIT_IMPS_RSP,
1768 resultCode, 0, 0);
1769 return;
1770
1771}
1772
1773// --------------------------------------------------------------------
1774/**
1775 * pmmEnterUapsdRequestHandler
1776 *
1777 * FUNCTION:
1778 * This function process the eWNI_PMC_ENTER_UAPSD_REQ from PMC,
1779 * checks the correctness of the system state before configuring
1780 * PMM to the new ePMM_STATE_UAPSD_WT_SLEEP_RSP state, and invokes
1781 * invokes pmmUapsdSendChangePwrSaveMsg() to send
1782 * WDA_ENTER_UAPSD_REQ to HAL.
1783 *
1784 * NOTE:
1785 *
1786 * @param Global handle to MAC
1787 * @return None
1788 */
1789void pmmEnterUapsdRequestHandler (tpAniSirGlobal pMac)
1790{
1791 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
1792 tSirRetStatus retStatus = eSIR_SUCCESS;
1793
1794 tPmmState origState = pMac->pmm.gPmmState;
1795
1796#ifdef FEATURE_WLAN_DIAG_SUPPORT
1797 limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0);
1798#endif //FEATURE_WLAN_DIAG_SUPPORT
1799
1800 if ( (pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) ||
1801 limIsSystemInScanState(pMac) )
1802 {
1803 PELOGE(pmmLog(pMac, LOGE,
Jeff Johnsone7245742012-09-05 17:12:55 -07001804 FL("pmmUapsd: PMM State = %d, Global MLM State = %d, Global SME State = %d, rejecting the sleep mode request\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001805 pMac->pmm.gPmmState, pMac->lim.gLimMlmState, pMac->lim.gLimSmeState);)
1806
1807 resultCode = eSIR_SME_INVALID_PMM_STATE;
1808 goto failure;
1809 }
1810
1811 pMac->pmm.gPmmState = ePMM_STATE_UAPSD_WT_SLEEP_RSP;
1812
1813 if( (retStatus = pmmUapsdSendChangePwrSaveMsg(pMac, SIR_PM_SLEEP_MODE)) != eSIR_SUCCESS)
1814 {
1815 PELOGE(pmmLog(pMac, LOGE,
1816 FL("pmmUapsd: HAL_ENTER_UAPSD_REQ failed with response: %x\n"), retStatus);)
1817 resultCode = eSIR_SME_UAPSD_REQ_FAILED;
1818 goto failure;
1819 }
1820
1821 PELOG1(pmmLog(pMac, LOG1, FL("pmmUapsd: Waiting for WDA_ENTER_UAPSD_RSP \n"));)
1822 return;
1823
1824failure:
1825 pMac->pmm.gPmmState = origState;
1826 limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, resultCode, 0, 0);
1827 return;
1828}
1829
1830
1831// --------------------------------------------------------------------
1832/**
1833 * pmmEnterUapsdResponseHandler
1834 *
1835 * FUNCTION:
1836 * This function processes the SIR_HAL_ENTER_UAPSD_RSP from HAL.
1837 * If the response is successful, it puts PMM into ePMM_STATE_UAPSD_SLEEP
1838 * state and sends back success response to PMC.
1839 *
1840 * NOTE:
1841 *
1842 * @param limMsg
1843 * @return None
1844 */
1845void pmmEnterUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
1846{
1847 tpUapsdParams pUapsdRspMsg;
1848 tSirResultCodes retStatus = eSIR_SME_SUCCESS;
1849
Jeff Johnsone7245742012-09-05 17:12:55 -07001850 tANI_U8 PowersavesessionId;
1851 tpPESession psessionEntry;
1852
Jeff Johnson295189b2012-06-20 16:38:30 -07001853 /* we need to process all the deferred messages enqueued since
1854 * the initiating the SIR_HAL_ENTER_UAPSD_REQ.
1855 */
1856 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1857
Jeff Johnsone7245742012-09-05 17:12:55 -07001858 /* Copy the power save sessionId to the local variable */
1859 PowersavesessionId = pMac->pmm.sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -07001860
1861 if (NULL == limMsg->bodyptr)
1862 {
1863 PELOGE(pmmLog(pMac, LOGE, FL("pmmUapsd: Received SIR_HAL_ENTER_UAPSD_RSP with NULL "));)
1864 return;
1865 }
1866
1867 pUapsdRspMsg = (tpUapsdParams)(limMsg->bodyptr);
1868
Jeff Johnsone7245742012-09-05 17:12:55 -07001869 if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL)
1870 {
1871 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
1872 return;
1873 }
1874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 if(pMac->pmm.gPmmState != ePMM_STATE_UAPSD_WT_SLEEP_RSP)
1876 {
1877 PELOGE(pmmLog(pMac, LOGE,
1878 FL("pmmUapsd: Received SIR_HAL_ENTER_UAPSD_RSP while in incorrect state: %d\n"),
1879 pMac->pmm.gPmmState);)
1880 limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0);
1881 return;
1882 }
1883
Jeff Johnson43971f52012-07-17 12:26:56 -07001884 if(pUapsdRspMsg->status == eHAL_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07001885 {
1886 PELOGW(pmmLog(pMac, LOGW,
1887 FL("pmmUapsd: Received successful response from HAL to enter UAPSD mode \n"));)
1888 pMac->pmm.gPmmState = ePMM_STATE_UAPSD_SLEEP;
1889 }
1890 else
1891 {
1892 PELOGE(pmmLog(pMac, LOGE,
1893 FL("pmmUapsd: SIR_HAL_ENTER_UAPSD_RSP failed, informing SME\n"));)
1894 pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP;
1895 retStatus = eSIR_SME_UAPSD_REQ_FAILED;
1896 }
1897
Mohit Khanna349bc392012-09-11 17:24:52 -07001898 if(IS_SLM_SESSIONIZATION_SUPPORTED_BY_FW)
Jeff Johnsone7245742012-09-05 17:12:55 -07001899 {
1900 limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, retStatus,
1901 psessionEntry->smeSessionId, psessionEntry->transactionId);
1902 }
1903 else
1904 {
1905 limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, retStatus, 0, 0);
1906 }
1907
Jeff Johnson295189b2012-06-20 16:38:30 -07001908 return;
1909}
1910
1911
1912// --------------------------------------------------------------------
1913/**
1914 * pmmExitUapsdRequestHandler
1915 *
1916 * FUNCTION:
1917 * This function process the eWNI_PMC_EXIT_UAPSD_REQ from PMC,
1918 * checks the correctness of the system state before configuring
1919 * PMM to the new ePMM_STATE_UAPSD_WT_WAKEUP_RSP state, and
1920 * invokes pmmUapsdSendChangePwrSaveMsg() to send
1921 * SIR_HAL_EXIT_UAPSD_REQ to HAL.
1922 *
1923 * NOTE:
1924 *
1925 * @param Global handle to MAC
1926 * @return None
1927 */
1928void pmmExitUapsdRequestHandler(tpAniSirGlobal pMac)
1929{
1930 tSirRetStatus retStatus = eSIR_SUCCESS;
1931 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
1932
1933 tPmmState origState = pMac->pmm.gPmmState;
1934
1935#ifdef FEATURE_WLAN_DIAG_SUPPORT
1936 limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0);
1937#endif //FEATURE_WLAN_DIAG_SUPPORT
1938
1939 if (ePMM_STATE_UAPSD_SLEEP == pMac->pmm.gPmmState)
1940 {
1941 pMac->pmm.gPmmState = ePMM_STATE_UAPSD_WT_WAKEUP_RSP;
1942 if( (retStatus = pmmUapsdSendChangePwrSaveMsg(pMac, SIR_PM_ACTIVE_MODE)) !=
1943 eSIR_SUCCESS)
1944 {
1945 PELOGE(pmmLog(pMac, LOGE,
1946 FL("pmmUapsd: sending EXIT_UAPSD to HAL failed \n"));)
1947 resultCode = eSIR_SME_UAPSD_REQ_FAILED;
1948 goto failure;
1949 }
1950 }
1951 else
1952 {
1953 PELOGE(pmmLog(pMac, LOGE,
1954 FL("pmmUapsd: Rcv EXIT_UAPSD from PMC in invalid state: %x\n"),
1955 pMac->pmm.gPmmState);)
1956
1957 resultCode = eSIR_SME_INVALID_PMM_STATE;
1958 goto failure;
1959 }
1960 return;
1961
1962failure:
1963 pMac->pmm.gPmmState = origState;
1964 PELOGE(pmmLog(pMac, LOGE,
1965 FL("pmmUapsd: Waking up from UAPSD mode failed, Ret Code: %d, Next State: %d\n"),
1966 retStatus, pMac->pmm.gPmmState);)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001967 limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, 0, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07001968}
1969
1970
1971// --------------------------------------------------------------------
1972/**
1973 * pmmExitUapsdResponseHandler
1974 *
1975 * FUNCTION:
1976 * This function receives the SIR_HAL_EXIT_UAPSD_RSP from HAL and is
1977 * responsible for checking the correctness of the system state
1978 * before configuring PMM to the new ePMM_STATE_BMPS_SLEEP state
1979 * and send eWNI_PMC_EXIT_UAPSD_RSP to PMC.
1980 *
1981 * NOTE:
1982 *
1983 * @param Global handle to MAC
1984 * @return None
1985 */
1986void pmmExitUapsdResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus)
1987{
1988 tSirResultCodes resultCode = eSIR_SME_SUCCESS;
Jeff Johnsone7245742012-09-05 17:12:55 -07001989 tANI_U8 PowersavesessionId;
1990 tpPESession psessionEntry;
Jeff Johnson295189b2012-06-20 16:38:30 -07001991
1992 /* we need to process all the deferred messages enqueued since
1993 * the initiating the SIR_HAL_EXIT_UAPSD_REQ.
1994 */
1995 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1996
1997 if (pMac->pmm.gPmmState != ePMM_STATE_UAPSD_WT_WAKEUP_RSP)
1998 {
1999 PELOGE(pmmLog(pMac, LOGE,
2000 FL("Received HAL_EXIT_UAPSD_RSP in invalid state: %d\n"),
2001 pMac->pmm.gPmmState);)
2002 limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0);
2003 return;
2004 }
2005
Jeff Johnsone7245742012-09-05 17:12:55 -07002006 PowersavesessionId = pMac->pmm.sessionId;
2007 if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL)
2008 {
2009 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
2010 return;
2011 }
2012
Jeff Johnson295189b2012-06-20 16:38:30 -07002013 switch(rspStatus)
2014 {
2015 case eHAL_STATUS_SUCCESS:
2016 resultCode = eSIR_SME_SUCCESS;
2017 PELOGW(pmmLog(pMac, LOGW,
2018 FL("Received SIR_HAL_EXIT_UAPSD_RSP with Successful response \n"));)
2019 break;
2020 default:
2021 resultCode = eSIR_SME_UAPSD_REQ_FAILED;
2022 PELOGE(pmmLog(pMac, LOGW,
2023 FL("Received SIR_HAL_EXIT_UAPSD_RSP with Failure Status\n"));)
2024 break;
2025 }
2026
2027 pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002028
Mohit Khanna349bc392012-09-11 17:24:52 -07002029 if(IS_SLM_SESSIONIZATION_SUPPORTED_BY_FW)
Jeff Johnsone7245742012-09-05 17:12:55 -07002030 {
2031 limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, psessionEntry->smeSessionId,
2032 psessionEntry->transactionId);
2033 }
2034 else
2035 {
2036 limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, 0, 0);
2037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002038 return;
2039}
2040
2041/** ------------------------------------------------------------
2042\fn pmmSendWowlAddBcastPtrn
2043\brief This function sends a SIR_HAL_WOWL_ADD_BCAST_PTRN
2044\ message to HAL.
2045\param tpAniSirGlobal pMac
2046\param tpSirMsgQ pMsg
2047\return None
2048 --------------------------------------------------------------*/
2049void pmmSendWowlAddBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
2050{
2051 tpSirWowlAddBcastPtrn pBcastPtrn;
2052 tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr;
2053 tSirRetStatus retCode = eSIR_SUCCESS;
2054 tSirMsgQ msgQ;
2055
2056 if (palAllocateMemory(pMac->hHdd, (void **)&pBcastPtrn, sizeof(*pBcastPtrn)) != eHAL_STATUS_SUCCESS)
2057 {
2058 pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Add Bcast Pattern \n"));
2059 return;
2060 }
2061 (void) palCopyMemory(pMac->hHdd, pBcastPtrn, pMbMsg->data, sizeof(*pBcastPtrn));
2062
2063 if (NULL == pBcastPtrn)
2064 {
2065 pmmLog(pMac, LOGE, FL("Add broadcast pattern message is NULL \n"));
2066 return;
2067 }
2068
2069 msgQ.type = WDA_WOWL_ADD_BCAST_PTRN;
2070 msgQ.reserved = 0;
2071 msgQ.bodyptr = pBcastPtrn;
2072 msgQ.bodyval = 0;
2073
2074 pmmLog(pMac, LOG1, FL( "Sending WDA_WOWL_ADD_BCAST_PTRN to HAL"));
2075#ifdef FEATURE_WLAN_DIAG_SUPPORT
2076 limDiagEventReport(pMac, WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT, NULL, 0, 0);
2077#endif //FEATURE_WLAN_DIAG_SUPPORT
2078
2079 if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
2080 {
2081 if (pBcastPtrn != NULL)
2082 palFreeMemory( pMac->hHdd, (tANI_U8 *) pBcastPtrn);
2083 pmmLog( pMac, LOGP, FL("Posting WDA_WOWL_ADD_BCAST_PTRN failed, reason=%X"), retCode );
2084 }
2085 return;
2086}
2087
2088/** ------------------------------------------------------------
2089\fn pmmSendWowlDelBcastPtrn
2090\brief This function sends a SIR_HAL_WOWL_DEL_BCAST_PTRN
2091\ message to HAL.
2092\param tpAniSirGlobal pMac
2093\param tpSirMsgQ pMsg
2094\return None
2095 --------------------------------------------------------------*/
2096void pmmSendWowlDelBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
2097{
2098 tpSirWowlDelBcastPtrn pDeletePtrn;
2099 tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr;
2100 tSirRetStatus retCode = eSIR_SUCCESS;
2101 tSirMsgQ msgQ;
2102
2103 if (palAllocateMemory(pMac->hHdd, (void **)&pDeletePtrn, sizeof(*pDeletePtrn)) != eHAL_STATUS_SUCCESS)
2104 {
2105 pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Delete Bcast Pattern \n"));
2106 return;
2107 }
2108 (void) palCopyMemory(pMac->hHdd, pDeletePtrn, pMbMsg->data, sizeof(*pDeletePtrn));
2109
2110 if (NULL == pDeletePtrn)
2111 {
2112 pmmLog(pMac, LOGE, FL("Delete broadcast pattern message is NULL \n"));
2113 return;
2114 }
2115
2116 msgQ.type = WDA_WOWL_DEL_BCAST_PTRN;
2117 msgQ.reserved = 0;
2118 msgQ.bodyptr = pDeletePtrn;
2119 msgQ.bodyval = 0;
2120
2121 pmmLog(pMac, LOG1, FL( "Sending WDA_WOWL_DEL_BCAST_PTRN"));
2122#ifdef FEATURE_WLAN_DIAG_SUPPORT
2123 limDiagEventReport(pMac, WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT, NULL, 0, 0);
2124#endif //FEATURE_WLAN_DIAG_SUPPORT
2125
2126 if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
2127 {
2128 if (NULL != pDeletePtrn)
2129 palFreeMemory( pMac->hHdd, (tANI_U8 *) pDeletePtrn);
2130 pmmLog( pMac, LOGP, FL("Posting WDA_WOWL_DEL_BCAST_PTRN failed, reason=%X"), retCode );
2131 }
2132 return;
2133}
2134
2135/** ---------------------------------------------------------
2136\fn pmmEnterWowlRequestHandler
2137\brief LIM process the eWNI_PMC_ENTER_WOWL_REQ message, and
2138\ invokes pmmSendWowlEnterRequest() to send
2139\ WDA_WOWL_ENTER_REQ message to HAL.
2140\param tpAniSirGlobal pMac
2141\param tpSirMsgQ pMsg
2142\return None
2143 ------------------------------------------------------------*/
2144void pmmEnterWowlRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
2145{
2146 tpSirSmeWowlEnterParams pSmeWowlParams = NULL;
2147 tpSirHalWowlEnterParams pHalWowlParams = NULL;
2148 tSirRetStatus retCode = eSIR_SUCCESS;
2149 tANI_U32 cfgValue = 0;
2150 tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr;
2151
2152#ifdef FEATURE_WLAN_DIAG_SUPPORT
2153 limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT, NULL, 0, 0);
2154#endif //FEATURE_WLAN_DIAG_SUPPORT
2155
2156 pSmeWowlParams = (tpSirSmeWowlEnterParams)(pMbMsg->data);
2157
2158 if (NULL == pSmeWowlParams)
2159 return;
2160// Need to fix it ASAP - TBH
2161#if 0
2162 if (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE)
2163 {
2164 pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ when station is not associated \n"));
2165 limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_STA_NOT_ASSOCIATED, 0, 0);
2166 goto end;
2167 }
2168#endif
2169
2170
2171 if ((pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) && (pMac->pmm.gPmmState != ePMM_STATE_WOWLAN))
2172 {
2173 pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ in invalid Power Save state \n"));
2174 limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0);
2175 goto end;
2176 }
2177
2178 if (palAllocateMemory(pMac->hHdd, (void **)&pHalWowlParams, sizeof(*pHalWowlParams)) != eHAL_STATUS_SUCCESS)
2179 {
2180 pmmLog(pMac, LOGP, FL("Fail to allocate memory for Enter Wowl Request \n"));
2181 goto end;
2182 }
2183 (void) palZeroMemory(pMac->hHdd, (tANI_U8 *)pHalWowlParams, sizeof(*pHalWowlParams) );
2184
2185 // fill in the message field
2186 pHalWowlParams->ucMagicPktEnable = pSmeWowlParams->ucMagicPktEnable;
2187 pHalWowlParams->ucPatternFilteringEnable = pSmeWowlParams->ucPatternFilteringEnable;
2188 (void)palCopyMemory( pMac->hHdd, (tANI_U8 *)pHalWowlParams->magicPtrn, (tANI_U8 *)pSmeWowlParams->magicPtrn, sizeof(tSirMacAddr) );
2189
2190#ifdef WLAN_WAKEUP_EVENTS
2191 pHalWowlParams->ucWoWEAPIDRequestEnable = pSmeWowlParams->ucWoWEAPIDRequestEnable;
2192 pHalWowlParams->ucWoWEAPOL4WayEnable = pSmeWowlParams->ucWoWEAPOL4WayEnable;
2193 pHalWowlParams->ucWowNetScanOffloadMatch = pSmeWowlParams->ucWowNetScanOffloadMatch;
2194 pHalWowlParams->ucWowGTKRekeyError = pSmeWowlParams->ucWowGTKRekeyError;
2195 pHalWowlParams->ucWoWBSSConnLoss = pSmeWowlParams->ucWoWBSSConnLoss;
2196#endif // WLAN_WAKEUP_EVENTS
2197
2198 if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE, &cfgValue) != eSIR_SUCCESS)
2199 {
2200 limLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE"));
2201 goto end;
2202 }
2203 pHalWowlParams->ucUcastPatternFilteringEnable = (tANI_U8)cfgValue;
2204
2205 if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE, &cfgValue) != eSIR_SUCCESS)
2206 {
2207 limLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE"));
2208 goto end;
2209 }
2210 pHalWowlParams->ucWowChnlSwitchRcv = (tANI_U8)cfgValue;
2211
2212 if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_DEAUTH_ENABLE, &cfgValue) != eSIR_SUCCESS)
2213 {
2214 limLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE \n"));
2215 goto end;
2216 }
2217 pHalWowlParams->ucWowDeauthRcv = (tANI_U8)cfgValue;
2218
2219 if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_DISASSOC_ENABLE, &cfgValue) != eSIR_SUCCESS)
2220 {
2221 limLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE \n"));
2222 goto end;
2223 }
2224 pHalWowlParams->ucWowDisassocRcv = (tANI_U8)cfgValue;
2225
2226 if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_MAX_MISSED_BEACON, &cfgValue) != eSIR_SUCCESS)
2227 {
2228 limLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_MISSED_BEACON \n"));
2229 goto end;
2230 }
2231 pHalWowlParams->ucWowMaxMissedBeacons = (tANI_U8)cfgValue;
2232
2233 if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD, &cfgValue) != eSIR_SUCCESS)
2234 {
2235 limLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD \n"));
2236 goto end;
2237 }
2238 pHalWowlParams->ucWowMaxSleepUsec = (tANI_U8)cfgValue;
2239
2240 //Send message to HAL
2241 if( eSIR_SUCCESS != (retCode = pmmSendWowlEnterRequest( pMac, pHalWowlParams)))
2242 {
2243 pmmLog(pMac, LOGE, FL("Send ENTER_WOWL_REQ to HAL failed, reasonCode %d \n"), retCode);
2244 limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_WOWL_ENTER_REQ_FAILED, 0, 0);
2245 goto end;
2246 }
2247 return;
2248
2249end:
2250 if (pHalWowlParams != NULL)
2251 palFreeMemory( pMac->hHdd, (tANI_U8 *) pHalWowlParams);
2252 return;
2253}
2254
2255
2256/** ------------------------------------------------------------
2257\fn pmmSendWowlEnterRequest
2258\brief LIM sends a WDA_WOWL_ENTER_REQ message to HAL with
2259\ the message structure pHalWowlParams. HAL shall later
2260\ send a WDA_WOWL_ENTER_RSP with the same pointer
2261\ to the message structure back to PMM.
2262\param tpAniSirGlobal pMac
2263\param tpSirHalWowlEnterParams pHalWowlParams
2264\return tSirRetStatus
2265 --------------------------------------------------------------*/
2266tSirRetStatus pmmSendWowlEnterRequest(tpAniSirGlobal pMac, tpSirHalWowlEnterParams pHalWowlParams)
2267{
2268 tSirRetStatus retCode = eSIR_SUCCESS;
2269 tSirMsgQ msgQ;
2270
2271 if (NULL == pHalWowlParams)
2272 return eSIR_FAILURE;
2273
2274 msgQ.type = WDA_WOWL_ENTER_REQ;
2275 msgQ.reserved = 0;
2276 msgQ.bodyptr = pHalWowlParams;
2277 msgQ.bodyval = 0;
2278
2279 /* Defer any incoming message until we get
2280 * a WDA_WOWL_ENTER_RSP from HAL
2281 */
2282 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
2283
2284 retCode = wdaPostCtrlMsg(pMac, &msgQ);
2285 if( eSIR_SUCCESS != retCode )
2286 {
2287 pmmLog( pMac, LOGE, FL("Posting WDA_WOWL_ENTER_REQ failed, reason=%X"), retCode );
2288 return retCode;
2289 }
2290 return retCode;
2291}
2292
2293/** ---------------------------------------------------------
2294\fn pmmEnterWowlanResponseHandler
2295\brief LIM process the WDA_WOWL_ENTER_RSP message.
2296\ and sends eWNI_PMC_ENTER_WOWL_RSP to SME.
2297\param tpAniSirGlobal pMac
2298\param tpSirMsgQ limMsg
2299\return None
2300 ------------------------------------------------------------*/
2301void pmmEnterWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
2302{
2303 tpSirHalWowlEnterParams pHalWowlMsg;
2304 eHalStatus rspStatus;
2305 tSirResultCodes smeRspCode = eSIR_SME_SUCCESS;
2306
2307 /* we need to process all the deferred messages enqueued
2308 * since the initiating the WDA_WOWL_ENTER_REQ.
2309 */
2310 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2311
2312 pHalWowlMsg = (tpSirHalWowlEnterParams)(limMsg->bodyptr);
2313 if (NULL == pHalWowlMsg)
2314 {
2315 pmmLog(pMac, LOGE, FL("Recvd WDA_WOWL_ENTER_RSP with NULL msg "));
2316 smeRspCode = eSIR_SME_WOWL_ENTER_REQ_FAILED;
2317 }
2318 else
2319 {
2320 rspStatus = pHalWowlMsg->status;
2321 if(rspStatus == eHAL_STATUS_SUCCESS)
2322 {
2323 pmmLog(pMac, LOGW, FL("Rcv successful response from HAL to enter WOWLAN \n"));
2324 pMac->pmm.gPmmState = ePMM_STATE_WOWLAN;
2325 }
2326 else
2327 {
2328 pmmLog(pMac, LOGE, FL("HAL enter WOWLAN failed, informing SME\n"));
2329 smeRspCode = eSIR_SME_WOWL_ENTER_REQ_FAILED;
2330 }
2331 }
2332
2333 limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, smeRspCode, 0, 0);
2334 return;
2335}
2336
2337/** ---------------------------------------------------------
2338\fn pmmExitWowlanRequestHandler
2339\brief PE process the eWNI_PMC_EXIT_WOWL_REQ message.
2340\ and sends WDA_WOWL_EXIT_REQ to HAL.
2341\param tpAniSirGlobal pMac
2342\return None
2343 ------------------------------------------------------------*/
2344void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac)
2345{
2346 tSirRetStatus retStatus = eSIR_SUCCESS;
2347 tSirResultCodes smeRspCode = eSIR_SME_SUCCESS;
2348
2349#ifdef FEATURE_WLAN_DIAG_SUPPORT
2350 limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT, NULL, 0, 0);
2351#endif //FEATURE_WLAN_DIAG_SUPPORT
2352
2353 if ( pMac->pmm.gPmmState != ePMM_STATE_WOWLAN )
2354 {
2355 pmmLog(pMac, LOGE,
2356 FL("Exit WOWLAN Request received in invalid state PMM=%d \n"),
2357 pMac->pmm.gPmmState);
2358 smeRspCode = eSIR_SME_INVALID_PMM_STATE;
2359 goto failure;
2360 }
2361
2362 if((retStatus = pmmSendExitWowlReq(pMac)) != eSIR_SUCCESS)
2363 {
2364 pmmLog(pMac, LOGE,
2365 FL("Fail to send WDA_WOWL_EXIT_REQ, reason code %d\n"),
2366 retStatus);
2367 smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED;
2368 goto failure;
2369 }
2370 return;
2371
2372failure:
2373 limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, smeRspCode, 0, 0);
2374 return;
2375}
2376
2377/** ---------------------------------------------------------
2378\fn pmmSendExitWowlReq
2379\brief This function sends the WDA_WOWL_EXIT_REQ
2380\ message to HAL.
2381\param tpAniSirGlobal pMac
2382\return None
2383 ------------------------------------------------------------*/
2384tSirRetStatus pmmSendExitWowlReq(tpAniSirGlobal pMac)
2385{
2386 tSirRetStatus retCode = eSIR_SUCCESS;
2387 tSirMsgQ msgQ;
2388
2389 msgQ.type = WDA_WOWL_EXIT_REQ;
2390 msgQ.reserved = 0;
2391 msgQ.bodyptr = 0;
2392 msgQ.bodyval = 0;
2393
2394 pmmLog(pMac, LOGW, FL("Sending WDA_WOWL_EXIT_REQ"));
2395
2396 /* we need to defer any incoming messages until
2397 * we get a WDA_WOWL_EXIT_RSP from HAL.
2398 */
2399 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
2400
2401 if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ )))
2402 pmmLog( pMac, LOGE,
2403 FL("Posting WDA_WOWL_EXIT_REQ failed, reason=%X\n"),
2404 retCode );
2405
2406 return retCode;
2407}
2408
2409/** ---------------------------------------------------------
2410\fn pmmExitWowlanResponseHandler
2411\brief This function process the WDA_WOWL_EXIT_RSP message.
2412\ and sends back eWNI_PMC_EXIT_WOWL_RSP to SME.
2413\param tpAniSirGlobal pMac
2414\return None
2415 ------------------------------------------------------------*/
2416void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus)
2417{
2418 /* we need to process all the deferred messages enqueued
2419 * since the initiating the WDA_WOWL_EXIT_REQ.
2420 */
2421 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2422
2423 // restore PMM state to BMPS mode
2424 pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP;
2425
2426 if(rspStatus == eHAL_STATUS_SUCCESS)
2427 {
2428 pmmLog(pMac, LOGW, FL("Rcvd successful rsp from HAL to exit WOWLAN \n"));
2429 limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_SUCCESS, 0, 0);
2430 }
2431 else
2432 {
2433 pmmLog(pMac, LOGE, FL("Rcvd failure rsp from HAL to exit WOWLAN \n"));
2434 limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_WOWL_EXIT_REQ_FAILED, 0, 0);
2435 }
2436 return;
2437}
2438
2439
2440// --------------------------------------------------------------------
2441/**
2442 * pmmImpsSendChangePwrSaveMsg
2443 *
2444 * FUNCTION:
2445 * This function is called to toggle the Idle mode power save mode
2446 *
2447 * LOGIC:
2448 *
2449 * ASSUMPTIONS:
2450 * None
2451 *
2452 * NOTE:
2453 *
2454 * @param Global handle to MAC
2455 * @param mode to be configured
2456 * @return None
2457 */
2458
2459tSirRetStatus pmmImpsSendChangePwrSaveMsg(tpAniSirGlobal pMac, tANI_U8 mode)
2460{
2461 tSirRetStatus retStatus = eSIR_SUCCESS;
2462 tSirMsgQ msgQ;
2463
2464 if (SIR_PM_SLEEP_MODE == mode)
2465 {
2466 msgQ.type = WDA_ENTER_IMPS_REQ;
Mohit Khanna23863762012-09-11 17:40:09 -07002467 PELOG2(pmmLog (pMac, LOG2, FL("Sending WDA_ENTER_IMPS_REQ to HAL\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -07002468 }
2469 else
2470 {
2471 msgQ.type = WDA_EXIT_IMPS_REQ;
Mohit Khanna23863762012-09-11 17:40:09 -07002472 PELOG2(pmmLog (pMac, LOG2, FL("Sending WDA_EXIT_IMPS_REQ to HAL\n"));)
Jeff Johnson295189b2012-06-20 16:38:30 -07002473 }
2474
2475 msgQ.reserved = 0;
2476 msgQ.bodyptr = NULL;
2477 msgQ.bodyval = 0;
2478
2479 /* we need to defer any incoming messages until we get a
2480 * WDA_ENTER_IMPS_REQ or WDA_EXIT_IMPS_RSP from HAL.
2481 */
2482 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
Jeff Johnsone7245742012-09-05 17:12:55 -07002483 MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07002484 retStatus = wdaPostCtrlMsg(pMac, &msgQ);
2485 if ( eSIR_SUCCESS != retStatus )
2486 {
2487 PELOGE(pmmLog(pMac, LOGE,
2488 FL("WDA_ENTER/EXIT_IMPS_REQ to HAL failed, reason=%X\n"), retStatus);)
2489 }
2490
2491 return retStatus;
2492}
2493
2494// --------------------------------------------------------------------
2495/**
2496 * pmmUapsdSendChangePwrSaveMsg
2497 *
2498 * FUNCTION:
2499 * This function is called to send either WDA_ENTER_UAPSD_REQ
2500 * or WDA_EXIT_UAPSD_REQ to HAL.
2501 *
2502 * NOTE:
2503 *
2504 * @param pMac Global handle to MAC
2505 * @param mode mode to be configured
2506 * @return tSirRetStatus
2507 */
2508tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode)
2509{
2510 tSirRetStatus retStatus = eSIR_SUCCESS;
2511 tpUapsdParams pUapsdParams = NULL;
2512 tANI_U8 uapsdDeliveryMask = 0;
2513 tANI_U8 uapsdTriggerMask = 0;
2514 tSirMsgQ msgQ;
Jeff Johnsone7245742012-09-05 17:12:55 -07002515 tpPESession pSessionEntry;
Jeff Johnson295189b2012-06-20 16:38:30 -07002516
2517 if (SIR_PM_SLEEP_MODE == mode)
2518 {
2519 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pUapsdParams, sizeof(tUapsdParams)) )
2520 {
2521 PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd :palAllocateMemory() failed\n"));)
2522 retStatus = eSIR_MEM_ALLOC_FAILED;
2523 return retStatus;
2524 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002525
2526 if((pSessionEntry = peGetValidPowerSaveSession(pMac)) == NULL )
2527 {
2528 PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd :palAllocateMemory() failed\n"));)
2529 retStatus = eSIR_FAILURE;
2530 return retStatus;
2531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 palZeroMemory( pMac->hHdd, (tANI_U8 *)pUapsdParams, sizeof(tUapsdParams));
2533 msgQ.type = WDA_ENTER_UAPSD_REQ;
2534 msgQ.bodyptr = pUapsdParams;
2535
2536 uapsdDeliveryMask = (pMac->lim.gUapsdPerAcBitmask | pMac->lim.gUapsdPerAcDeliveryEnableMask);
2537 uapsdTriggerMask = (pMac->lim.gUapsdPerAcBitmask | pMac->lim.gUapsdPerAcTriggerEnableMask);
2538
2539 pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, uapsdDeliveryMask);
2540 pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, uapsdDeliveryMask);
2541 pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, uapsdDeliveryMask);
2542 pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, uapsdDeliveryMask);
2543 pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, uapsdTriggerMask);
2544 pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, uapsdTriggerMask);
2545 pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, uapsdTriggerMask);
2546 pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, uapsdTriggerMask);
Jeff Johnsone7245742012-09-05 17:12:55 -07002547 pUapsdParams->bssIdx = pSessionEntry->bssIdx;
2548
Jeff Johnson295189b2012-06-20 16:38:30 -07002549 PELOGE(pmmLog(pMac, LOGE,
2550 FL("UAPSD Mask: static = 0x%x, DeliveryEnabled = 0x%x, TriggerEnabled = 0x%x \n"),
2551 pMac->lim.gUapsdPerAcBitmask,
2552 pMac->lim.gUapsdPerAcDeliveryEnableMask,
2553 pMac->lim.gUapsdPerAcTriggerEnableMask);)
2554
2555 PELOG1(pmmLog(pMac, LOG1, FL("Delivery Enabled: BK=%d, BE=%d, Vi=%d, Vo=%d \n"),
2556 pUapsdParams->bkDeliveryEnabled,
2557 pUapsdParams->beDeliveryEnabled,
2558 pUapsdParams->viDeliveryEnabled,
2559 pUapsdParams->voDeliveryEnabled);)
2560
2561 PELOG1(pmmLog(pMac, LOG1, FL("Trigger Enabled: BK=%d, BE=%d, Vi=%d, Vo=%d \n"),
2562 pUapsdParams->bkTriggerEnabled,
2563 pUapsdParams->beTriggerEnabled,
2564 pUapsdParams->viTriggerEnabled,
2565 pUapsdParams->voTriggerEnabled);)
2566
2567 PELOGW(pmmLog (pMac, LOGW, FL("pmmUapsd: Sending WDA_ENTER_UAPSD_REQ to HAL\n"));)
2568 }
2569 else
2570 {
2571 msgQ.type = WDA_EXIT_UAPSD_REQ;
2572 msgQ.bodyptr = NULL;
2573 PELOGW(pmmLog (pMac, LOGW, FL("pmmUapsd: Sending WDA_EXIT_UAPSD_REQ to HAL\n"));)
2574 }
2575
2576 /* we need to defer any incoming messages until we get a
2577 * WDA_ENTER/EXIT_UAPSD_RSP from HAL.
2578 */
2579 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
2580
2581 msgQ.reserved = 0;
2582 msgQ.bodyval = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002583 MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 retStatus = wdaPostCtrlMsg(pMac, &msgQ);
2585 if ( eSIR_SUCCESS != retStatus )
2586 {
2587 PELOGE(pmmLog(pMac, LOGE,
2588 FL("pmmUapsd: WDA_ENTER/EXIT_UAPSD_REQ to HAL failed, reason=%X\n"),
2589 retStatus);)
2590 if (SIR_PM_SLEEP_MODE == mode)
2591 palFreeMemory(pMac->hHdd, (tANI_U8*)pUapsdParams);
2592 }
2593
2594 return retStatus;
2595}
2596
2597
2598// --------------------------------------------------------------------
2599/**
2600 * pmmUpdateImpsPwrSaveStats
2601 *
2602 * FUNCTION:
2603 * This function is called to update the power save statistics in MAC
2604 * for Idle mode power save
2605 *
2606 * LOGIC:
2607 *
2608 * ASSUMPTIONS:
2609 * None
2610 *
2611 * NOTE:
2612 *
2613 * @param Global handle to MAC
2614 * @return None
2615 */
2616
2617void pmmImpsUpdatePwrSaveStats(tpAniSirGlobal pMac)
2618{
2619/*
2620 tANI_U64 TimeAwake = 0;
2621
2622 pMac->pmm.ImpsSleepTimeStamp = vos_timer_get_system_ticks();
2623
2624 if (pMac->pmm.ImpsWakeupTimeStamp)
2625 {
2626 TimeAwake = (pMac->pmm.ImpsSleepTimeStamp - pMac->pmm.ImpsWakeupTimeStamp) / 10 ;
2627 }
2628 else
2629 {
2630 TimeAwake = 0;
2631 }
2632
2633 if (TimeAwake > pMac->pmm.ImpsMaxTimeAwake)
2634 {
2635 pMac->pmm.ImpsMaxTimeAwake = TimeAwake;
2636 }
2637
2638 if ((!pMac->pmm.ImpsMinTimeAwake) || (TimeAwake < pMac->pmm.ImpsMinTimeAwake))
2639 {
2640 pMac->pmm.ImpsMinTimeAwake = TimeAwake;
2641 }
2642
2643 pMac->pmm.ImpsAvgTimeAwake = ((pMac->pmm.ImpsAvgTimeAwake * pMac->pmm.ImpsCntSleep) + TimeAwake) / (pMac->pmm.ImpsCntSleep + 1);
2644
2645 (pMac->pmm.ImpsCntSleep)++;
2646
2647 return;
2648*/
2649}
2650
2651
2652// --------------------------------------------------------------------
2653/**
2654 * pmmImpsUpdateWakeupStats
2655 *
2656 * FUNCTION:
2657 * This function is called to update the Wake up statistics in MAC
2658 * for Idle mode power save
2659 *
2660 * LOGIC:
2661 *
2662 * ASSUMPTIONS:
2663 * None
2664 *
2665 * NOTE:
2666 *
2667 * @param Global handle to MAC
2668 * @return None
2669 */
2670
2671void pmmImpsUpdateWakeupStats (tpAniSirGlobal pMac)
2672{
2673/*
2674 tANI_U64 SleepTime = 0;
2675
2676 pMac->pmm.ImpsWakeupTimeStamp = vos_timer_get_system_ticks();
2677
2678 SleepTime = (pMac->pmm.ImpsWakeupTimeStamp - pMac->pmm.ImpsSleepTimeStamp) / 10;
2679
2680 if (SleepTime > pMac->pmm.ImpsMaxSleepTime)
2681 {
2682 pMac->pmm.ImpsMaxSleepTime = SleepTime;
2683 }
2684
2685 if ((!pMac->pmm.ImpsMinSleepTime) || (SleepTime < pMac->pmm.ImpsMinSleepTime))
2686 {
2687 pMac->pmm.ImpsMinSleepTime = SleepTime;
2688 }
2689
2690 pMac->pmm.ImpsAvgSleepTime = ( ( (pMac->pmm.ImpsAvgSleepTime * pMac->pmm.ImpsCntAwake) + SleepTime) / (pMac->pmm.ImpsCntAwake + 1));
2691
2692 (pMac->pmm.ImpsCntAwake)++;
2693
2694 return;
2695*/
2696}
2697
2698// Collects number of times error occurred while going to sleep mode
2699void pmmImpsUpdateSleepErrStats(tpAniSirGlobal pMac,
2700 tSirRetStatus retStatus)
2701{
2702 pMac->pmm.ImpsSleepErrCnt++;
2703 pMac->pmm.ImpsLastErr = retStatus;
2704 return;
2705}
2706
2707// Collects number of times error occurred while waking up from sleep mode
2708void pmmImpsUpdateWakeupErrStats(tpAniSirGlobal pMac,
2709 tSirRetStatus retStatus)
2710{
2711 pMac->pmm.ImpsWakeupErrCnt++;
2712 pMac->pmm.ImpsLastErr = retStatus;
2713 return;
2714}
2715
2716
2717// Collects number of times the system has received request or
2718// response in an invalid state
2719void pmmImpsUpdateErrStateStats(tpAniSirGlobal pMac)
2720{
2721 pMac->pmm.ImpsInvalidStateCnt++;
2722 return;
2723}
2724
2725// Collects number of packets dropped while in IMPS mode
2726void pmmImpsUpdatePktDropStats(tpAniSirGlobal pMac)
2727{
2728
2729 pMac->pmm.ImpsPktDrpInSleepMode++;
2730 return;
2731}
2732
2733// Collects number of packets dropped while in BMPS mode
2734void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac)
2735{
2736
2737 pMac->pmm.BmpsPktDrpInSleepMode++;
2738 return;
2739}
2740
2741// Collects statistics for number of times BMPS init failed
2742void pmmBmpsUpdateInitFailureCnt(tpAniSirGlobal pMac)
2743{
2744
2745 pMac->pmm.BmpsInitFailCnt++;
2746 return;
2747}
2748
2749// Collects statistics for number of times sleep request failed
2750void pmmBmpsUpdateSleepReqFailureCnt(tpAniSirGlobal pMac)
2751{
2752
2753 pMac->pmm.BmpsSleeReqFailCnt++;
2754 return;
2755}
2756
2757// Collects statistics for number of times Wakeup request failed
2758void pmmBmpsUpdateWakeupReqFailureCnt(tpAniSirGlobal pMac)
2759{
2760
2761 pMac->pmm.BmpsWakeupReqFailCnt++;
2762 return;
2763}
2764
2765// Collects statistics for number of times request / response received in invalid state
2766void pmmBmpsUpdateInvalidStateCnt(tpAniSirGlobal pMac)
2767{
2768
2769 pMac->pmm.BmpsInvStateCnt++;
2770 return;
2771}
2772
2773// Collects statistics for number of times wakeup indications received
2774void pmmBmpsUpdateWakeupIndCnt(tpAniSirGlobal pMac)
2775{
2776 pMac->pmm.BmpsWakeupIndCnt++;
2777 return;
2778}
2779
2780// Collects statistics for number of times wakeup indications received
2781void pmmBmpsUpdateHalReqFailureCnt(tpAniSirGlobal pMac)
2782{
2783 pMac->pmm.BmpsHalReqFailCnt++;
2784 return;
2785}
2786
2787// Collects statistics for number of times requests received from HDD in
2788// invalid device role
2789void pmmBmpsUpdateReqInInvalidRoleCnt(tpAniSirGlobal pMac)
2790{
2791 pMac->pmm.BmpsReqInInvalidRoleCnt++;
2792 return;
2793}
2794
2795#if 0
2796// Update the sleep statistics
2797void pmmUpdateDroppedPktStats(tpAniSirGlobal pMac)
2798{
2799 switch (pMac->pmm.gPmmState)
2800 {
2801 case ePMM_STATE_BMPS_SLEEP:
2802 pmmBmpsUpdatePktDropStats(pMac);
2803 break;
2804
2805 case ePMM_STATE_IMPS_SLEEP:
2806 pmmImpsUpdatePktDropStats(pMac);
2807 break;
2808
2809 default:
2810 break;
2811 }
2812 return;
2813
2814}
2815#endif
2816
2817// Resets PMM state ePMM_STATE_READY
2818void pmmResetPmmState(tpAniSirGlobal pMac)
2819{
2820 pMac->pmm.gPmmState = ePMM_STATE_READY;
2821
2822 pMac->pmm.inMissedBeaconScenario = FALSE;
2823 return;
2824}
2825
2826/* Sends Background scan message back to Lim */
2827void pmmSendMessageToLim(tpAniSirGlobal pMac,
2828 tANI_U32 msgId)
2829{
2830 tSirMsgQ limMsg;
2831 tANI_U32 statusCode;
2832
2833 limMsg.type = (tANI_U16) msgId;
2834 limMsg.bodyptr = NULL;
2835 limMsg.bodyval = 0;
2836
2837 if ((statusCode = limPostMsgApi(pMac, &limMsg)) != eSIR_SUCCESS)
2838 {
2839 PELOGW(pmmLog(pMac, LOGW,
2840 FL("posting message %X to LIM failed, reason=%d\n"),
2841 limMsg.type, statusCode);)
2842 }
2843}
2844
2845#ifdef WLAN_FEATURE_PACKET_FILTERING
2846void pmmFilterMatchCountResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
2847{
2848 tpSirRcvFltPktMatchRsp pRcvFltPktMatchCntRsp;
2849 eHalStatus rspStatus;
2850 tSirResultCodes smeRspCode = eSIR_SME_SUCCESS;
2851
2852 /* we need to process all the deferred messages enqueued
2853 * since the initiating the WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ.
2854 */
2855 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2856
2857 pRcvFltPktMatchCntRsp = (tpSirRcvFltPktMatchRsp)(limMsg->bodyptr);
2858 if (NULL == pRcvFltPktMatchCntRsp)
2859 {
2860 pmmLog(pMac, LOGE, FL("Received "
2861 "WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP with NULL msg "));
2862 smeRspCode = eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED;
2863 }
2864 else
2865 {
2866 rspStatus = pRcvFltPktMatchCntRsp->status;
2867 if (eHAL_STATUS_SUCCESS == rspStatus)
2868 {
2869 pmmLog(pMac, LOGE, FL("Rcv successful response from HAL to get "
2870 "Packet Coalescing Filter Match Count\n"));
2871 }
2872 else
2873 {
2874 pmmLog(pMac, LOGE, FL("HAL failed to get Packet Coalescing "
2875 "Filter Match Count, informing SME\n"));
2876 smeRspCode = eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED;
2877 }
2878 }
2879
2880 limSendSmeRsp(pMac, eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP,
2881 smeRspCode, 0, 0);
2882 return;
2883}
2884#endif // WLAN_FEATURE_PACKET_FILTERING
2885
2886#ifdef WLAN_FEATURE_GTK_OFFLOAD
2887void pmmGTKOffloadGetInfoResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
2888{
2889 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRspParams;
2890 eHalStatus rspStatus;
2891 tSirResultCodes smeRspCode = eSIR_SME_SUCCESS;
2892
2893 /* we need to process all the deferred messages enqueued
2894 * since the initiating the WDA_GTK_OFFLOAD_GETINFO_REQ.
2895 */
2896 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2897
2898 pGtkOffloadGetInfoRspParams = (tpSirGtkOffloadGetInfoRspParams)(limMsg->bodyptr);
2899 if (NULL == pGtkOffloadGetInfoRspParams)
2900 {
2901 pmmLog(pMac, LOGE, FL("Received WDA_GTK_OFFLOAD_GETINFO_RSP with NULL msg "));
2902 smeRspCode = eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED;
2903 }
2904 else
2905 {
2906 rspStatus = pGtkOffloadGetInfoRspParams->ulStatus;
2907 if(rspStatus == eHAL_STATUS_SUCCESS)
2908 {
2909 pmmLog(pMac, LOGW, FL("Rcv successful response from HAL to get GTK Offload Information\n"));
2910 }
2911 else
2912 {
2913 pmmLog(pMac, LOGE, FL("HAL failed to get GTK Offload Information, informing SME\n"));
2914 smeRspCode = eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED;
2915 }
2916 }
2917
2918 limSendSmeRsp(pMac, eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP, smeRspCode, 0, 0);
2919 return;
2920}
2921#endif // WLAN_FEATURE_GTK_OFFLOAD