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