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