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