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