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