blob: 1145c968cb3d15d0b6ba35892671e2e01afd8cfc [file] [log] [blame]
Gopichand Nakkala746a9452013-06-11 12:45:54 +05301/*
2* Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
3* All Rights Reserved.
4* Qualcomm Atheros Confidential and Proprietary.
5*/
6
7/******************************************************************************
8*
9* Name: pmcApi.c
10*
11* Description: Routines that make up the Power Management Control (PMC) API.
12*
13* Copyright 2008 (c) Qualcomm Technologies, Inc.
14* All Rights Reserved.
15* Qualcomm Technologies Confidential and Proprietary.
16*
17******************************************************************************/
18
19#include "palTypes.h"
20#include "aniGlobal.h"
21#include "palTimer.h"
22#include "csrLinkList.h"
23#include "smsDebug.h"
24#include "pmcApi.h"
25#include "pmc.h"
26#include "cfgApi.h"
27#include "smeInside.h"
28#include "csrInsideApi.h"
29#include "wlan_ps_wow_diag.h"
30#include "wlan_qct_wda.h"
31#include "limSessionUtils.h"
32#include "csrInsideApi.h"
33
34extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand );
35
36void pmcCloseDeferredMsgList(tpAniSirGlobal pMac);
37void pmcCloseDeviceStateUpdateList(tpAniSirGlobal pMac);
38void pmcCloseRequestStartUapsdList(tpAniSirGlobal pMac);
39void pmcCloseRequestBmpsList(tpAniSirGlobal pMac);
40void pmcCloseRequestFullPowerList(tpAniSirGlobal pMac);
41void pmcClosePowerSaveCheckList(tpAniSirGlobal pMac);
42
43/******************************************************************************
44*
45* Name: pmcOpen
46*
47* Description:
48* Does a PMC open operation on the device.
49*
50* Parameters:
51* hHal - HAL handle for device
52*
53* Returns:
54* eHAL_STATUS_SUCCESS - open successful
55* eHAL_STATUS_FAILURE - open not successful
56*
57******************************************************************************/
58eHalStatus pmcOpen (tHalHandle hHal)
59{
60 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
61
62 smsLog(pMac, LOG2, FL("Entering pmcOpen"));
63
64 /* Initialize basic PMC information about device. */
65 pMac->pmc.powerSource = BATTERY_POWER;
66 pMac->pmc.pmcState = STOPPED;
67 pMac->pmc.pmcReady = FALSE;
68
69 /* Initialize Power Save Modes */
70 pMac->pmc.impsEnabled = FALSE;
71 pMac->pmc.autoBmpsEntryEnabled = FALSE;
72 pMac->pmc.smpsEnabled = FALSE;
73 pMac->pmc.uapsdEnabled = TRUE;
74 pMac->pmc.bmpsEnabled = TRUE;
75 pMac->pmc.standbyEnabled = TRUE;
76 pMac->pmc.wowlEnabled = TRUE;
77 pMac->pmc.rfSuppliesVotedOff= FALSE;
78
79 palZeroMemory(pMac->hHdd, &(pMac->pmc.bmpsConfig), sizeof(tPmcBmpsConfigParams));
80 palZeroMemory(pMac->hHdd, &(pMac->pmc.impsConfig), sizeof(tPmcImpsConfigParams));
81 palZeroMemory(pMac->hHdd, &(pMac->pmc.smpsConfig), sizeof(tPmcSmpsConfigParams));
82
83 /* Allocate a timer to use with IMPS. */
84 if (palTimerAlloc(pMac->hHdd, &pMac->pmc.hImpsTimer, pmcImpsTimerExpired, hHal) != eHAL_STATUS_SUCCESS)
85 {
86 smsLog(pMac, LOGE, FL("Cannot allocate timer for IMPS"));
87 return eHAL_STATUS_FAILURE;
88 }
89
90 /* Allocate a timer used in Full Power State to measure traffic
91 levels and determine when to enter BMPS. */
92 if (!VOS_IS_STATUS_SUCCESS(vos_timer_init(&pMac->pmc.hTrafficTimer,
93 VOS_TIMER_TYPE_SW, pmcTrafficTimerExpired, hHal)))
94 {
95 smsLog(pMac, LOGE, FL("Cannot allocate timer for traffic measurement"));
96 return eHAL_STATUS_FAILURE;
97 }
98
99#ifdef FEATURE_WLAN_DIAG_SUPPORT
100 /* Allocate a timer used to report current PMC state through periodic DIAG event */
101 if (palTimerAlloc(pMac->hHdd, &pMac->pmc.hDiagEvtTimer, pmcDiagEvtTimerExpired, hHal) != eHAL_STATUS_SUCCESS)
102 {
103 smsLog(pMac, LOGE, FL("Cannot allocate timer for diag event reporting"));
104 return eHAL_STATUS_FAILURE;
105 }
106#endif
107
108 //Initialize the default value for Bmps related config.
109 pMac->pmc.bmpsConfig.trafficMeasurePeriod = BMPS_TRAFFIC_TIMER_DEFAULT;
110 pMac->pmc.bmpsConfig.bmpsPeriod = WNI_CFG_LISTEN_INTERVAL_STADEF;
111
112 /* Allocate a timer used to schedule a deferred power save mode exit. */
113 if (palTimerAlloc(pMac->hHdd, &pMac->pmc.hExitPowerSaveTimer,
114 pmcExitPowerSaveTimerExpired, hHal) != eHAL_STATUS_SUCCESS)
115 {
116 smsLog(pMac, LOGE, FL("Cannot allocate exit power save mode timer"));
117 PMC_ABORT;
118 return eHAL_STATUS_FAILURE;
119 }
120
121 /* Initialize lists for power save check routines and request full power callback routines. */
122 if (csrLLOpen(pMac->hHdd, &pMac->pmc.powerSaveCheckList) != eHAL_STATUS_SUCCESS)
123 {
124 smsLog(pMac, LOGE, FL("Cannot initialize power save check routine list"));
125 PMC_ABORT;
126 return eHAL_STATUS_FAILURE;
127 }
128 if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestFullPowerList) != eHAL_STATUS_SUCCESS)
129 {
130 smsLog(pMac, LOGE, FL("Cannot initialize request full power callback routine list"));
131 PMC_ABORT;
132 return eHAL_STATUS_FAILURE;
133 }
134
135 /* Initialize lists for request BMPS callback routines. */
136 if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestBmpsList) !=
137 eHAL_STATUS_SUCCESS)
138 {
139 smsLog(pMac, LOGE, "PMC: cannot initialize request BMPS callback routine list");
140 return eHAL_STATUS_FAILURE;
141 }
142
143 /* Initialize lists for request start UAPSD callback routines. */
144 if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestStartUapsdList) != eHAL_STATUS_SUCCESS)
145 {
146 smsLog(pMac, LOGE, "PMC: cannot initialize request start UAPSD callback routine list");
147 return eHAL_STATUS_FAILURE;
148 }
149
150 /* Initialize lists for device state update indication callback routines. */
151 if (csrLLOpen(pMac->hHdd, &pMac->pmc.deviceStateUpdateIndList) != eHAL_STATUS_SUCCESS)
152 {
153 smsLog(pMac, LOGE, "PMC: cannot initialize device state update indication callback list");
154 return eHAL_STATUS_FAILURE;
155 }
156
157 if (csrLLOpen(pMac->hHdd, &pMac->pmc.deferredMsgList) != eHAL_STATUS_SUCCESS)
158 {
159 smsLog(pMac, LOGE, FL("Cannot initialize deferred msg list"));
160 PMC_ABORT;
161 return eHAL_STATUS_FAILURE;
162 }
163
164 return eHAL_STATUS_SUCCESS;
165}
166
167
168/******************************************************************************
169*
170* Name: pmcStart
171*
172* Description:
173* Does a PMC start operation on the device.
174*
175* Parameters:
176* hHal - HAL handle for device
177*
178* Returns:
179* eHAL_STATUS_SUCCESS - start successful
180* eHAL_STATUS_FAILURE - start not successful
181*
182******************************************************************************/
183eHalStatus pmcStart (tHalHandle hHal)
184{
185 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
186 tSirMacHTMIMOPowerSaveState htMimoPowerSaveState;
187
188 smsLog(pMac, LOG2, FL("Entering pmcStart"));
189
190 /* Initialize basic PMC information about device. */
191 pMac->pmc.pmcState = FULL_POWER;
192 pMac->pmc.requestFullPowerPending = FALSE;
193 pMac->pmc.uapsdSessionRequired = FALSE;
194 pMac->pmc.wowlModeRequired = FALSE;
195 pMac->pmc.bmpsRequestedByHdd = FALSE;
196 pMac->pmc.remainInPowerActiveTillDHCP = FALSE;
197 pMac->pmc.remainInPowerActiveThreshold = 0;
198
199 /* WLAN Switch initial states. */
200 pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_ON;
201 pMac->pmc.swWlanSwitchState = ePMC_SWITCH_ON;
202
203 /* No IMPS callback routine yet. */
204 pMac->pmc.impsCallbackRoutine = NULL;
205
206 /* No STANDBY callback routine yet. */
207 pMac->pmc.standbyCallbackRoutine = NULL;
208
209 /* No WOWL callback routine yet. */
210 pMac->pmc.enterWowlCallbackRoutine = NULL;
211
212 /* Initialize BMPS traffic counts. */
213 pMac->pmc.cLastTxUnicastFrames = 0;
214 pMac->pmc.cLastRxUnicastFrames = 0;
215 pMac->pmc.ImpsReqFailed = VOS_FALSE;
216 pMac->pmc.ImpsReqFailCnt = 0;
217 pMac->pmc.ImpsReqTimerFailed = 0;
218 pMac->pmc.ImpsReqTimerfailCnt = 0;
219
220 /* Configure SMPS. */
221 if (pMac->pmc.smpsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.smpsConfig.enterOnAc))
222 {
223 if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS)
224 htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC;
225 if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS)
226 htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC;
227 }
228 else
229 htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT;
230
231 if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState,
232 sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS)
233 return eHAL_STATUS_FAILURE;
234
235#ifdef FEATURE_WLAN_DIAG_SUPPORT
236 if (pmcStartDiagEvtTimer(hHal) != eHAL_STATUS_SUCCESS)
237 {
238 return eHAL_STATUS_FAILURE;
239 }
240#endif
241
242#if defined(ANI_LOGDUMP)
243 pmcDumpInit(hHal);
244#endif
245
246 return eHAL_STATUS_SUCCESS;
247}
248
249
250/******************************************************************************
251*
252* Name: pmcStop
253*
254* Description:
255* Does a PMC stop operation on the device.
256*
257* Parameters:
258* hHal - HAL handle for device
259*
260* Returns:
261* eHAL_STATUS_SUCCESS - stop successful
262* eHAL_STATUS_FAILURE - stop not successful
263*
264******************************************************************************/
265eHalStatus pmcStop (tHalHandle hHal)
266{
267 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
268 tListElem *pEntry;
269 tPmcDeferredMsg *pDeferredMsg;
270
271 smsLog(pMac, LOG2, FL("Entering pmcStop"));
272
273 /* Cancel any running timers. */
274 if (palTimerStop(pMac->hHdd, pMac->pmc.hImpsTimer) != eHAL_STATUS_SUCCESS)
275 {
276 smsLog(pMac, LOGE, FL("Cannot cancel IMPS timer"));
277 }
278
279 pmcStopTrafficTimer(hHal);
280
281#ifdef FEATURE_WLAN_DIAG_SUPPORT
282 pmcStopDiagEvtTimer(hHal);
283#endif
284
285 if (palTimerStop(pMac->hHdd, pMac->pmc.hExitPowerSaveTimer) != eHAL_STATUS_SUCCESS)
286 {
287 smsLog(pMac, LOGE, FL("Cannot cancel exit power save mode timer"));
288 }
289
290 /* Do all the callbacks. */
291 pmcDoCallbacks(hHal, eHAL_STATUS_FAILURE);
292 pmcDoBmpsCallbacks(hHal, eHAL_STATUS_FAILURE);
293 pMac->pmc.uapsdSessionRequired = FALSE;
294 pmcDoStartUapsdCallbacks(hHal, eHAL_STATUS_FAILURE);
295 pmcDoStandbyCallbacks(hHal, eHAL_STATUS_FAILURE);
296
297 //purge the deferred msg list
298 csrLLLock( &pMac->pmc.deferredMsgList );
299 while( NULL != ( pEntry = csrLLRemoveHead( &pMac->pmc.deferredMsgList, eANI_BOOLEAN_FALSE ) ) )
300 {
301 pDeferredMsg = GET_BASE_ADDR( pEntry, tPmcDeferredMsg, link );
302 palFreeMemory( pMac->hHdd, pDeferredMsg );
303 }
304 csrLLUnlock( &pMac->pmc.deferredMsgList );
305
306 /* PMC is stopped. */
307 pMac->pmc.pmcState = STOPPED;
308 pMac->pmc.pmcReady = FALSE;
309
310 return eHAL_STATUS_SUCCESS;
311}
312
313
314/******************************************************************************
315*
316* Name: pmcClose
317*
318* Description:
319* Does a PMC close operation on the device.
320*
321* Parameters:
322* hHal - HAL handle for device
323*
324* Returns:
325* eHAL_STATUS_SUCCESS - close successful
326* eHAL_STATUS_FAILURE - close not successful
327*
328******************************************************************************/
329eHalStatus pmcClose (tHalHandle hHal)
330{
331 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
332
333 smsLog(pMac, LOG2, FL("Entering pmcClose"));
334
335 /* Free up allocated resources. */
336 if (palTimerFree(pMac->hHdd, pMac->pmc.hImpsTimer) != eHAL_STATUS_SUCCESS)
337 {
338 smsLog(pMac, LOGE, FL("Cannot deallocate IMPS timer"));
339 }
340 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(&pMac->pmc.hTrafficTimer)))
341 {
342 smsLog(pMac, LOGE, FL("Cannot deallocate traffic timer"));
343 }
344#ifdef FEATURE_WLAN_DIAG_SUPPORT
345 if (palTimerFree(pMac->hHdd, pMac->pmc.hDiagEvtTimer) != eHAL_STATUS_SUCCESS)
346 {
347 smsLog(pMac, LOGE, FL("Cannot deallocate timer for diag event reporting"));
348 }
349#endif
350 if (palTimerFree(pMac->hHdd, pMac->pmc.hExitPowerSaveTimer) != eHAL_STATUS_SUCCESS)
351 {
352 smsLog(pMac, LOGE, FL("Cannot deallocate exit power save mode timer"));
353 }
354
355 /*
356 The following list's entries are dynamically allocated so they need their own
357 cleanup function
358 */
359 pmcClosePowerSaveCheckList(pMac);
360 pmcCloseRequestFullPowerList(pMac);
361 pmcCloseRequestBmpsList(pMac);
362 pmcCloseRequestStartUapsdList(pMac);
363 pmcCloseDeviceStateUpdateList(pMac);
364 pmcCloseDeferredMsgList(pMac);
365
366 return eHAL_STATUS_SUCCESS;
367}
368
369
370/******************************************************************************
371*
372* Name: pmcSignalPowerEvent
373*
374* Description:
375* Signals to PMC that a power event has occurred.
376*
377* Parameters:
378* hHal - HAL handle for device
379* event - the event that has occurred
380*
381* Returns:
382* eHAL_STATUS_SUCCESS - signaling successful
383* eHAL_STATUS_FAILURE - signaling not successful
384*
385******************************************************************************/
386eHalStatus pmcSignalPowerEvent (tHalHandle hHal, tPmcPowerEvent event)
387{
388 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
389#ifndef GEN6_ONWARDS
390 tSirMacHTMIMOPowerSaveState htMimoPowerSaveState;
391#endif
392
393 smsLog(pMac, LOG2, FL("Entering pmcSignalPowerEvent, event %d"), event);
394
395 /* Take action based on the event being signaled. */
396 switch (event)
397 {
398#ifndef GEN6_ONWARDS
399 case ePMC_SYSTEM_HIBERNATE:
400 return pmcEnterLowPowerState(hHal);
401
402 case ePMC_SYSTEM_RESUME:
403 return pmcExitLowPowerState(hHal);
404
405 case ePMC_HW_WLAN_SWITCH_OFF:
406 pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_OFF;
407 return pmcEnterLowPowerState(hHal);
408
409 case ePMC_HW_WLAN_SWITCH_ON:
410 pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_ON;
411 return pmcExitLowPowerState(hHal);
412
413 case ePMC_SW_WLAN_SWITCH_OFF:
414 pMac->pmc.swWlanSwitchState = ePMC_SWITCH_OFF;
415 return pmcEnterLowPowerState(hHal);
416
417 case ePMC_SW_WLAN_SWITCH_ON:
418 pMac->pmc.swWlanSwitchState = ePMC_SWITCH_ON;
419 return pmcExitLowPowerState(hHal);
420
421 case ePMC_BATTERY_OPERATION:
422 pMac->pmc.powerSource = BATTERY_POWER;
423
424 /* Turn on SMPS. */
425 if (pMac->pmc.smpsEnabled)
426 {
427 if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS)
428 htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC;
429 if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS)
430 htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC;
431 if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState,
432 sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS)
433 return eHAL_STATUS_FAILURE;
434 }
435 return eHAL_STATUS_SUCCESS;
436
437 case ePMC_AC_OPERATION:
438 pMac->pmc.powerSource = AC_POWER;
439
440 /* Turn off SMPS. */
441 if (!pMac->pmc.smpsConfig.enterOnAc)
442 {
443 htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT;
444 if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState,
445 sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS)
446 return eHAL_STATUS_FAILURE;
447 }
448 return eHAL_STATUS_SUCCESS;
449#endif //GEN6_ONWARDS
450 default:
451 smsLog(pMac, LOGE, FL("Invalid event %d"), event);
452 PMC_ABORT;
453 return eHAL_STATUS_FAILURE;
454 }
455}
456
457
458/******************************************************************************
459*
460* Name: pmcSetConfigPowerSave
461*
462* Description:
463* Configures one of the power saving modes.
464*
465* Parameters:
466* hHal - HAL handle for device
467* psMode - the power saving mode to configure
468* pConfigParams - pointer to configuration parameters specific to the
469* power saving mode
470*
471* Returns:
472* eHAL_STATUS_SUCCESS - configuration successful
473* eHAL_STATUS_FAILURE - configuration not successful
474*
475******************************************************************************/
476eHalStatus pmcSetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams)
477{
478 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
479
480#ifdef FEATURE_WLAN_DIAG_SUPPORT
481 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
482#endif
483
484 smsLog(pMac, LOG2, FL("Entering pmcSetConfigPowerSave, power save mode %d"), psMode);
485
486 /* Configure the specified power saving mode. */
487 switch (psMode)
488 {
489
490 case ePMC_IDLE_MODE_POWER_SAVE:
491 pMac->pmc.impsConfig = *(tpPmcImpsConfigParams)pConfigParams;
492 smsLog(pMac, LOG3, FL("IMPS configuration"));
493 smsLog(pMac, LOG3, " enter on AC: %d",
494 pMac->pmc.impsConfig.enterOnAc);
495 break;
496
497 case ePMC_BEACON_MODE_POWER_SAVE:
498 pMac->pmc.bmpsConfig = *(tpPmcBmpsConfigParams)pConfigParams;
499 smsLog(pMac, LOG3, FL("BMPS configuration"));
500 smsLog(pMac, LOG3, " enter on AC: %d",
501 pMac->pmc.bmpsConfig.enterOnAc);
502 smsLog(pMac, LOG3, " TX threshold: %d",
503 pMac->pmc.bmpsConfig.txThreshold);
504 smsLog(pMac, LOG3, " RX threshold: %d",
505 pMac->pmc.bmpsConfig.rxThreshold);
506 smsLog(pMac, LOG3, " traffic measurement period (ms): %d",
507 pMac->pmc.bmpsConfig.trafficMeasurePeriod);
508 smsLog(pMac, LOG3, " BMPS period: %d",
509 pMac->pmc.bmpsConfig.bmpsPeriod);
510 smsLog(pMac, LOG3, " beacons to forward code: %d",
511 pMac->pmc.bmpsConfig.forwardBeacons);
512 smsLog(pMac, LOG3, " value of N: %d",
513 pMac->pmc.bmpsConfig.valueOfN);
514 smsLog(pMac, LOG3, " use PS poll: %d",
515 pMac->pmc.bmpsConfig.usePsPoll);
516 smsLog(pMac, LOG3, " set PM on last frame: %d",
517 pMac->pmc.bmpsConfig.setPmOnLastFrame);
518 smsLog(pMac, LOG3, " value of enableBeaconEarlyTermination: %d",
519 pMac->pmc.bmpsConfig.enableBeaconEarlyTermination);
520 smsLog(pMac, LOG3, " value of bcnEarlyTermWakeInterval: %d",
521 pMac->pmc.bmpsConfig.bcnEarlyTermWakeInterval);
522
523#ifdef FEATURE_WLAN_DIAG_SUPPORT
524 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
525 psRequest.event_subtype = WLAN_BMPS_SET_CONFIG;
526 /* possible loss of data due to mismatch but expectation is that
527 values can reasonably be expected to fit in target widths */
528 psRequest.bmps_auto_timer_duration = (v_U16_t)pMac->pmc.bmpsConfig.trafficMeasurePeriod;
529 psRequest.bmps_period = (v_U16_t)pMac->pmc.bmpsConfig.bmpsPeriod;
530
531 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
532#endif
533
534
535 break;
536
537 case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE:
538 pMac->pmc.smpsConfig = *(tpPmcSmpsConfigParams)pConfigParams;
539 smsLog(pMac, LOG3, FL("SMPS configuration"));
540 smsLog(pMac, LOG3, " mode: %d", pMac->pmc.smpsConfig.mode);
541 smsLog(pMac, LOG3, " enter on AC: %d",
542 pMac->pmc.smpsConfig.enterOnAc);
543 break;
544
545 default:
546 smsLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode);
547 PMC_ABORT;
548 return eHAL_STATUS_FAILURE;
549 }
550
551 //Send the power save config down to PE/HAL/FW if BMPS mode is being configured
552 //and pmcReady has been invoked
553 if(PMC_IS_READY(pMac) && psMode == ePMC_BEACON_MODE_POWER_SAVE)
554 {
555 if (pmcSendPowerSaveConfigMessage(hHal) != eHAL_STATUS_SUCCESS)
556 return eHAL_STATUS_FAILURE;
557 }
558
559 return eHAL_STATUS_SUCCESS;
560}
561
562/******************************************************************************
563*
564* Name: pmcGetConfigPowerSave
565*
566* Description:
567* Get the config for the specified power save mode
568*
569* Parameters:
570* hHal - HAL handle for device
571* psMode - the power saving mode to configure
572* pConfigParams - pointer to configuration parameters specific to the
573* power saving mode
574*
575* Returns:
576* eHAL_STATUS_SUCCESS - configuration successful
577* eHAL_STATUS_FAILURE - configuration not successful
578*
579******************************************************************************/
580eHalStatus pmcGetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams)
581{
582 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
583
584 smsLog(pMac, LOG2, FL("Entering pmcGetConfigPowerSave, power save mode %d"), psMode);
585
586 /* Configure the specified power saving mode. */
587 switch (psMode)
588 {
589
590 case ePMC_IDLE_MODE_POWER_SAVE:
591 *(tpPmcImpsConfigParams)pConfigParams = pMac->pmc.impsConfig;
592 break;
593
594 case ePMC_BEACON_MODE_POWER_SAVE:
595 *(tpPmcBmpsConfigParams)pConfigParams = pMac->pmc.bmpsConfig;
596 break;
597
598 case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE:
599 *(tpPmcSmpsConfigParams)pConfigParams = pMac->pmc.smpsConfig;
600 break;
601
602 default:
603 smsLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode);
604 return eHAL_STATUS_FAILURE;
605 }
606
607 return eHAL_STATUS_SUCCESS;
608}
609/******************************************************************************
610*
611* Name: pmcEnablePowerSave
612*
613* Description:
614* Enables one of the power saving modes.
615*
616* Parameters:
617* hHal - HAL handle for device
618* psMode - the power saving mode to enable
619*
620* Returns:
621* eHAL_STATUS_SUCCESS - successfully enabled
622* eHAL_STATUS_FAILURE - not successfully enabled
623*
624******************************************************************************/
625eHalStatus pmcEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode)
626{
627 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
628 tSirMacHTMIMOPowerSaveState htMimoPowerSaveState;
629
630#ifdef FEATURE_WLAN_DIAG_SUPPORT
631 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
632
633 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
634 psRequest.event_subtype = WLAN_PS_MODE_ENABLE_REQ;
635 psRequest.enable_disable_powersave_mode = psMode;
636
637 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
638#endif
639
640 smsLog(pMac, LOG2, FL("Entering pmcEnablePowerSave, power save mode %d"), psMode);
641
642 /* Enable the specified power saving mode. */
643 switch (psMode)
644 {
645
646 case ePMC_IDLE_MODE_POWER_SAVE:
647 pMac->pmc.impsEnabled = TRUE;
648 break;
649
650 case ePMC_BEACON_MODE_POWER_SAVE:
651 pMac->pmc.bmpsEnabled = TRUE;
652 break;
653
654 case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE:
655 pMac->pmc.smpsEnabled = TRUE;
656
657 /* If PMC already started, then turn on SMPS. */
658 if (pMac->pmc.pmcState != STOPPED)
659 if (pMac->pmc.powerSource != AC_POWER ||
660 pMac->pmc.smpsConfig.enterOnAc)
661 {
662 if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS)
663 htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC;
664 if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS)
665 htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC;
666 if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState,
667 sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS)
668 return eHAL_STATUS_FAILURE;
669 }
670 break;
671
672 case ePMC_UAPSD_MODE_POWER_SAVE:
673 pMac->pmc.uapsdEnabled = TRUE;
674 break;
675
676 case ePMC_STANDBY_MODE_POWER_SAVE:
677 pMac->pmc.standbyEnabled = TRUE;
678 break;
679
680 case ePMC_WOWL_MODE_POWER_SAVE:
681 pMac->pmc.wowlEnabled = TRUE;
682 break;
683
684 default:
685 smsLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode);
686 PMC_ABORT;
687 return eHAL_STATUS_FAILURE;
688 }
689
690 return eHAL_STATUS_SUCCESS;
691}
692/* ---------------------------------------------------------------------------
693 \fn pmcStartAutoBmpsTimer
694 \brief Starts a timer that periodically polls all the registered
695 module for entry into Bmps mode. This timer is started only if BMPS is
696 enabled and whenever the device is in full power.
697 \param hHal - The handle returned by macOpen.
698 \return eHalStatus
699 ---------------------------------------------------------------------------*/
700eHalStatus pmcStartAutoBmpsTimer (tHalHandle hHal)
701{
702 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
703
704#ifdef FEATURE_WLAN_DIAG_SUPPORT
705 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
706
707 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
708 psRequest.event_subtype = WLAN_START_BMPS_AUTO_TIMER_REQ;
709
710 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
711#endif
712
713 smsLog(pMac, LOG2, FL("Entering pmcStartAutoBmpsTimer"));
714
715 /* Check if BMPS is enabled. */
716 if (!pMac->pmc.bmpsEnabled)
717 {
718 smsLog(pMac, LOGE, "PMC: Cannot enable BMPS timer. BMPS is disabled");
719 return eHAL_STATUS_FAILURE;
720 }
721
722 pMac->pmc.autoBmpsEntryEnabled = TRUE;
723
724 /* Check if there is an Infra session. If there is no Infra session, timer will be started
725 when STA associates to AP */
726
727 if (pmcShouldBmpsTimerRun(pMac))
728 {
729 if (pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod) != eHAL_STATUS_SUCCESS)
730 return eHAL_STATUS_FAILURE;
731 }
732
733
734
735 return eHAL_STATUS_SUCCESS;
736}
737
738/* ---------------------------------------------------------------------------
739 \fn pmcStopAutoBmpsTimer
740 \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer
741 Stopping the timer does not cause a device state change. Only the timer
742 is stopped. If "Full Power" is desired, use the pmcRequestFullPower API
743 \param hHal - The handle returned by macOpen.
744 \return eHalStatus
745 ---------------------------------------------------------------------------*/
746eHalStatus pmcStopAutoBmpsTimer (tHalHandle hHal)
747{
748 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
749
750#ifdef FEATURE_WLAN_DIAG_SUPPORT
751 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
752
753 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
754 psRequest.event_subtype = WLAN_STOP_BMPS_AUTO_TIMER_REQ;
755
756 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
757#endif
758
759 smsLog(pMac, LOG2, FL("Entering pmcStopAutoBmpsTimer"));
760
761 pMac->pmc.autoBmpsEntryEnabled = FALSE;
762 /* If uapsd session is not required or HDD has not requested BMPS, stop the auto bmps timer.*/
763 if (!pMac->pmc.uapsdSessionRequired && !pMac->pmc.bmpsRequestedByHdd)
764 pmcStopTrafficTimer(hHal);
765
766 return eHAL_STATUS_SUCCESS;
767}
768
769/******************************************************************************
770*
771* Name: pmcDisablePowerSave
772*
773* Description:
774* Disables one of the power saving modes.
775*
776* Parameters:
777* hHal - HAL handle for device
778* psMode - the power saving mode to disable
779*
780* Returns:
781* eHAL_STATUS_SUCCESS - successfully disabled
782* eHAL_STATUS_FAILURE - not successfully disabled
783*
784******************************************************************************/
785eHalStatus pmcDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode)
786{
787 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
788 tSirMacHTMIMOPowerSaveState htMimoPowerSaveState;
789
790#ifdef FEATURE_WLAN_DIAG_SUPPORT
791 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
792
793 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
794 psRequest.event_subtype = WLAN_PS_MODE_DISABLE_REQ;
795 psRequest.enable_disable_powersave_mode = psMode;
796
797 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
798#endif
799
800 smsLog(pMac, LOG2, FL("Entering pmcDisablePowerSave, power save mode %d"), psMode);
801
802 /* Disable the specified power saving mode. */
803 switch (psMode)
804 {
805
806 case ePMC_IDLE_MODE_POWER_SAVE:
807 pMac->pmc.impsEnabled = FALSE;
808 break;
809
810 case ePMC_BEACON_MODE_POWER_SAVE:
811 pMac->pmc.bmpsEnabled = FALSE;
812 break;
813
814 case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE:
815 pMac->pmc.smpsEnabled = FALSE;
816
817 /* Turn off SMPS. */
818 htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT;
819 if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState,
820 sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS)
821 return eHAL_STATUS_FAILURE;
822 break;
823
824 case ePMC_UAPSD_MODE_POWER_SAVE:
825 pMac->pmc.uapsdEnabled = FALSE;
826 break;
827
828 case ePMC_STANDBY_MODE_POWER_SAVE:
829 pMac->pmc.standbyEnabled = FALSE;
830 break;
831
832 case ePMC_WOWL_MODE_POWER_SAVE:
833 pMac->pmc.wowlEnabled = FALSE;
834 break;
835
836 default:
837 smsLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode);
838 PMC_ABORT;
839 return eHAL_STATUS_FAILURE;
840 }
841
842 return eHAL_STATUS_SUCCESS;
843}
844
845
846/******************************************************************************
847*
848* Name: pmcQueryPowerState
849*
850* Description:
851* Returns the current power state of the device.
852*
853* Parameters:
854* hHal - HAL handle for device
855* pPowerState - pointer to location to return power state
856* pHwWlanSwitchState - pointer to location to return Hardware WLAN
857* Switch state
858* pSwWlanSwitchState - pointer to location to return Software WLAN
859* Switch state
860*
861* Returns:
862* eHAL_STATUS_SUCCESS - power state successfully returned
863* eHAL_STATUS_FAILURE - power state not successfully returned
864*
865******************************************************************************/
866eHalStatus pmcQueryPowerState (tHalHandle hHal, tPmcPowerState *pPowerState,
867 tPmcSwitchState *pHwWlanSwitchState, tPmcSwitchState *pSwWlanSwitchState)
868{
869 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
870
871 smsLog(pMac, LOG2, FL("Entering pmcQueryPowerState"));
872
873 /* Return current power state based on PMC state. */
874 if(pPowerState != NULL)
875 {
876 /* Return current power state based on PMC state. */
877 switch (pMac->pmc.pmcState)
878 {
879
880 case FULL_POWER:
881 *pPowerState = ePMC_FULL_POWER;
882 break;
883
884 default:
885 *pPowerState = ePMC_LOW_POWER;
886 break;
887 }
888 }
889
890 /* Return current switch settings. */
891 if(pHwWlanSwitchState != NULL)
892 *pHwWlanSwitchState = pMac->pmc.hwWlanSwitchState;
893 if(pSwWlanSwitchState != NULL)
894 *pSwWlanSwitchState = pMac->pmc.swWlanSwitchState;
895
896 return eHAL_STATUS_SUCCESS;
897}
898
899
900/******************************************************************************
901*
902* Name: pmcIsPowerSaveEnabled
903*
904* Description:
905* Checks if the device is able to enter one of the power save modes.
906* "Able to enter" means the power save mode is enabled for the device
907* and the host is using the correct power source for entry into the
908* power save mode. This routine does not indicate whether the device
909* is actually in the power save mode at a particular point in time.
910*
911* Parameters:
912* hHal - HAL handle for device
913* psMode - the power saving mode
914*
915* Returns:
916* TRUE if device is able to enter the power save mode, FALSE otherwise
917*
918******************************************************************************/
919tANI_BOOLEAN pmcIsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode)
920{
921 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
922
923 smsLog(pMac, LOG2, FL("Entering pmcIsPowerSaveEnabled, power save mode %d"), psMode);
924
925 /* Check ability to enter based on the specified power saving mode. */
926 switch (psMode)
927 {
928
929 case ePMC_IDLE_MODE_POWER_SAVE:
930 return pMac->pmc.impsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.impsConfig.enterOnAc);
931
932 case ePMC_BEACON_MODE_POWER_SAVE:
933 return pMac->pmc.bmpsEnabled;
934
935 case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE:
936 return pMac->pmc.smpsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.smpsConfig.enterOnAc);
937
938 case ePMC_UAPSD_MODE_POWER_SAVE:
939 return pMac->pmc.uapsdEnabled;
940
941 case ePMC_STANDBY_MODE_POWER_SAVE:
942 return pMac->pmc.standbyEnabled;
943
944 case ePMC_WOWL_MODE_POWER_SAVE:
945 return pMac->pmc.wowlEnabled;
946 break;
947
948 default:
949 smsLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode);
950 PMC_ABORT;
951 return FALSE;
952 }
953}
954
955
956/******************************************************************************
957*
958* Name: pmcRequestFullPower
959*
960* Description:
961* Request that the device be brought to full power state.
962*
963* Parameters:
964* hHal - HAL handle for device
965* callbackRoutine - routine to call when device actually achieves full
966* power state if "eHAL_STATUS_PMC_PENDING" is returned
967* callbackContext - value to be passed as parameter to routine specified
968* above
969* fullPowerReason - Reason for requesting full power mode. This is used
970* by PE to decide whether data null should be sent to
971* AP when exiting BMPS mode. Caller should use the
972* eSME_LINK_DISCONNECTED reason if link is disconnected
973* and there is no need to tell the AP that we are going
974* out of power save.
975*
976* Returns:
977* eHAL_STATUS_SUCCESS - device brought to full power state
978* eHAL_STATUS_FAILURE - device cannot be brought to full power state
979* eHAL_STATUS_PMC_PENDING - device is being brought to full power state,
980* callbackRoutine will be called when completed
981*
982******************************************************************************/
983eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void *callbackContext, eHalStatus status),
984 void *callbackContext, tRequestFullPowerReason fullPowerReason)
985{
986 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
987 tpRequestFullPowerEntry pEntry;
988
989#ifdef FEATURE_WLAN_DIAG_SUPPORT
990 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
991
992 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
993 psRequest.event_subtype = WLAN_ENTER_FULL_POWER_REQ;
994 psRequest.full_power_request_reason = fullPowerReason;
995
996 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
997#endif
998
999 smsLog(pMac, LOG2, FL("Entering pmcRequestFullPower"));
1000
1001 if( !PMC_IS_READY(pMac) )
1002 {
1003 smsLog(pMac, LOGE, FL("Requesting Full Power when PMC not ready"));
1004 smsLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"),
1005 pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState));
1006 return eHAL_STATUS_FAILURE;
1007 }
1008
1009 /* If HDD is requesting full power, clear any buffered requests for WOWL and BMPS that were
1010 requested by HDD previously */
1011 if(SIR_IS_FULL_POWER_NEEDED_BY_HDD(fullPowerReason))
1012 {
1013 pMac->pmc.bmpsRequestedByHdd = FALSE;
1014 pMac->pmc.wowlModeRequired = FALSE;
1015 }
1016
1017 /* If already in full power, just return. */
1018 if (pMac->pmc.pmcState == FULL_POWER)
1019 return eHAL_STATUS_SUCCESS;
1020
1021 /* If in IMPS State, then cancel the timer. */
1022 if (pMac->pmc.pmcState == IMPS)
1023 if (palTimerStop(pMac->hHdd, pMac->pmc.hImpsTimer) != eHAL_STATUS_SUCCESS)
1024 {
1025 smsLog(pMac, LOGE, FL("Cannot cancel IMPS timer"));
1026 return eHAL_STATUS_FAILURE;
1027 }
1028
1029 /* Enter Request Full Power State. */
1030 if (pmcEnterRequestFullPowerState(hHal, fullPowerReason) != eHAL_STATUS_SUCCESS)
1031 return eHAL_STATUS_FAILURE;
1032
1033 /* If able to enter Request Full Power State, then request is pending.
1034 Allocate entry for request full power callback routine list. */
1035 //If caller doesn't need a callback, simply waits up the chip.
1036 if( callbackRoutine )
1037 {
1038 if (palAllocateMemory(pMac->hHdd, (void **)&pEntry, sizeof(tRequestFullPowerEntry)) != eHAL_STATUS_SUCCESS)
1039 {
1040 smsLog(pMac, LOGE, FL("Cannot allocate memory for request full power routine list entry"));
1041 PMC_ABORT;
1042 return eHAL_STATUS_FAILURE;
1043 }
1044
1045 /* Store routine and context in entry. */
1046 pEntry->callbackRoutine = callbackRoutine;
1047 pEntry->callbackContext = callbackContext;
1048
1049 /* Add entry to list. */
1050 csrLLInsertTail(&pMac->pmc.requestFullPowerList, &pEntry->link, TRUE);
1051 }
1052
1053 return eHAL_STATUS_PMC_PENDING;
1054}
1055
1056
1057/******************************************************************************
1058*
1059* Name: pmcRequestImps
1060*
1061* Description:
1062* Request that the device be placed in Idle Mode Power Save (IMPS).
1063* The Common Scan/Roam Module makes this request. The device will be
1064* placed into IMPS for the specified amount of time, and then returned
1065* to full power.
1066*
1067* Parameters:
1068* hHal - HAL handle for device
1069* impsPeriod - amount of time to remain in IMPS (milliseconds)
1070* callbackRoutine - routine to call when IMPS period has finished and
1071* the device has been brought to full power
1072* callbackContext - value to be passed as parameter to routine specified
1073* above
1074*
1075* Returns:
1076* eHAL_STATUS_SUCCESS - device will enter IMPS
1077* eHAL_STATUS_PMC_DISABLED - IMPS is disabled
1078* eHAL_STATUS_PMC_NOT_NOW - another module is prohibiting entering IMPS
1079* at this time
1080* eHAL_STATUS_PMC_AC_POWER - IMPS is disabled when host operating from
1081* AC power
1082* eHAL_STATUS_PMC_ALREADY_IN_IMPS - device is already in IMPS
1083* eHAL_STATUS_PMC_SYS_ERROR - system error that prohibits entering IMPS
1084*
1085******************************************************************************/
1086eHalStatus pmcRequestImps (tHalHandle hHal, tANI_U32 impsPeriod,
1087 void (*callbackRoutine) (void *callbackContext, eHalStatus status),
1088 void *callbackContext)
1089{
1090 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1091 eHalStatus status;
1092
1093#ifdef FEATURE_WLAN_DIAG_SUPPORT
1094 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
1095
1096 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
1097 psRequest.event_subtype = WLAN_IMPS_ENTER_REQ;
1098 psRequest.imps_period = impsPeriod;
1099
1100 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
1101#endif
1102
1103
1104 smsLog(pMac, LOG2, FL("Entering pmcRequestImps"));
1105
1106 status = pmcEnterImpsCheck( pMac );
1107 if( HAL_STATUS_SUCCESS( status ) )
1108 {
1109 /* Enter Request IMPS State. */
1110 status = pmcEnterRequestImpsState( hHal );
1111 if (HAL_STATUS_SUCCESS( status ))
1112 {
1113 /* Save the period and callback routine for when we need it. */
1114 pMac->pmc.impsPeriod = impsPeriod;
1115 pMac->pmc.impsCallbackRoutine = callbackRoutine;
1116 pMac->pmc.impsCallbackContext = callbackContext;
1117
1118 }
1119 else
1120 {
1121 status = eHAL_STATUS_PMC_SYS_ERROR;
1122 }
1123 }
1124
1125 return status;
1126}
1127
1128
1129/******************************************************************************
1130*
1131* Name: pmcRegisterPowerSaveCheck
1132*
1133* Description:
1134* Allows a routine to be registered so that the routine is called whenever
1135* the device is about to enter one of the power save modes. This routine
1136* will say whether the device is allowed to enter the power save mode at
1137* the time of the call.
1138*
1139* Parameters:
1140* hHal - HAL handle for device
1141* checkRoutine - routine to call before entering a power save mode, should
1142* return TRUE if the device is allowed to enter the power
1143* save mode, FALSE otherwise
1144* checkContext - value to be passed as parameter to routine specified above
1145*
1146* Returns:
1147* eHAL_STATUS_SUCCESS - successfully registered
1148* eHAL_STATUS_FAILURE - not successfully registered
1149*
1150******************************************************************************/
1151eHalStatus pmcRegisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext),
1152 void *checkContext)
1153{
1154 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1155 tpPowerSaveCheckEntry pEntry;
1156
1157 smsLog(pMac, LOG2, FL("Entering pmcRegisterPowerSaveCheck"));
1158
1159 /* Allocate entry for power save check routine list. */
1160 if (palAllocateMemory(pMac->hHdd, (void **)&pEntry, sizeof(tPowerSaveCheckEntry)) != eHAL_STATUS_SUCCESS)
1161 {
1162 smsLog(pMac, LOGE, FL("Cannot allocate memory for power save check routine list entry"));
1163 PMC_ABORT;
1164 return eHAL_STATUS_FAILURE;
1165 }
1166
1167 /* Store routine and context in entry. */
1168 pEntry->checkRoutine = checkRoutine;
1169 pEntry->checkContext = checkContext;
1170
1171 /* Add entry to list. */
1172 csrLLInsertTail(&pMac->pmc.powerSaveCheckList, &pEntry->link, FALSE);
1173
1174 return eHAL_STATUS_SUCCESS;
1175}
1176
1177
1178/******************************************************************************
1179*
1180* Name: pmcDeregisterPowerSaveCheck
1181*
1182* Description:
1183* Reregisters a routine that was previously registered with
1184* pmcRegisterPowerSaveCheck.
1185*
1186* Parameters:
1187* hHal - HAL handle for device
1188* checkRoutine - routine to deregister
1189*
1190* Returns:
1191* eHAL_STATUS_SUCCESS - successfully deregistered
1192* eHAL_STATUS_FAILURE - not successfully deregistered
1193*
1194******************************************************************************/
1195eHalStatus pmcDeregisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext))
1196{
1197 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1198 tListElem *pEntry;
1199 tpPowerSaveCheckEntry pPowerSaveCheckEntry;
1200
1201 smsLog(pMac, LOG2, FL("Entering pmcDeregisterPowerSaveCheck"));
1202
1203 /* Find entry in the power save check routine list that matches
1204 the specified routine and remove it. */
1205 pEntry = csrLLPeekHead(&pMac->pmc.powerSaveCheckList, FALSE);
1206 while (pEntry != NULL)
1207 {
1208 pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link);
1209 if (pPowerSaveCheckEntry->checkRoutine == checkRoutine)
1210 {
1211 if (csrLLRemoveEntry(&pMac->pmc.powerSaveCheckList, pEntry, FALSE))
1212 {
1213 if (palFreeMemory(pMac->hHdd, pPowerSaveCheckEntry) != eHAL_STATUS_SUCCESS)
1214 {
1215 smsLog(pMac, LOGE, FL("Cannot free memory for power save check routine list entry"));
1216 PMC_ABORT;
1217 return eHAL_STATUS_FAILURE;
1218 }
1219 }
1220 else
1221 {
1222 smsLog(pMac, LOGE, FL("Cannot remove power save check routine list entry"));
1223 return eHAL_STATUS_FAILURE;
1224 }
1225 return eHAL_STATUS_SUCCESS;
1226 }
1227 pEntry = csrLLNext(&pMac->pmc.powerSaveCheckList, pEntry, FALSE);
1228 }
1229
1230 /* Could not find matching entry. */
1231 return eHAL_STATUS_FAILURE;
1232}
1233
1234
1235static void pmcProcessResponse( tpAniSirGlobal pMac, tSirSmeRsp *pMsg )
1236{
1237 tListElem *pEntry = NULL;
1238 tSmeCmd *pCommand = NULL;
1239 tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE;
1240
1241 pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
1242 if(pEntry)
1243 {
1244 pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
1245
1246 smsLog(pMac, LOG2, FL("process message = %d"), pMsg->messageType);
1247
1248 /* Process each different type of message. */
1249 switch (pMsg->messageType)
1250 {
1251
1252 /* We got a response to our IMPS request. */
1253 case eWNI_PMC_ENTER_IMPS_RSP:
1254 smsLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_IMPS_RSP with status = %d"), pMsg->statusCode);
1255 if( (eSmeCommandEnterImps != pCommand->command) && (eSmeCommandEnterStandby != pCommand->command) )
1256 {
1257 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_IMPS_RSP without request"));
1258 fRemoveCommand = eANI_BOOLEAN_FALSE;
1259 break;
1260 }
1261 if(pMac->pmc.pmcState == REQUEST_IMPS)
1262 {
1263 /* Enter IMPS State if response indicates success. */
1264 if (pMsg->statusCode == eSIR_SME_SUCCESS)
1265 {
1266 pMac->pmc.ImpsReqFailed = VOS_FALSE;
1267 pmcEnterImpsState(pMac);
1268 if (!(pMac->pmc.ImpsReqFailed || pMac->pmc.ImpsReqTimerFailed) && pMac->pmc.ImpsReqFailCnt)
1269 {
1270 smsLog(pMac, LOGE, FL("Response message to request to enter IMPS was failed %d times before success"),
1271 pMac->pmc.ImpsReqFailCnt);
1272 pMac->pmc.ImpsReqFailCnt = 0;
1273 }
1274 }
1275
1276 /* If response is failure, then we stay in Full Power State and tell everyone that we aren't going into IMPS. */
1277 else
1278 {
1279 pMac->pmc.ImpsReqFailed = VOS_TRUE;
1280 if (!(pMac->pmc.ImpsReqFailCnt & 0xF))
1281 {
1282 smsLog(pMac, LOGE, FL("Response message to request to enter IMPS indicates failure, status %x, FailCnt - %d"),
1283 pMsg->statusCode, ++pMac->pmc.ImpsReqFailCnt);
1284 }
1285 else
1286 {
1287 pMac->pmc.ImpsReqFailCnt++;
1288 }
1289 pmcEnterFullPowerState(pMac);
1290 }
1291 }
1292 else if (pMac->pmc.pmcState == REQUEST_STANDBY)
1293 {
1294 /* Enter STANDBY State if response indicates success. */
1295 if (pMsg->statusCode == eSIR_SME_SUCCESS)
1296 {
1297 pmcEnterStandbyState(pMac);
1298 pmcDoStandbyCallbacks(pMac, eHAL_STATUS_SUCCESS);
1299 }
1300
1301 /* If response is failure, then we stay in Full Power State
1302 and tell everyone that we aren't going into STANDBY. */
1303 else
1304 {
1305 smsLog(pMac, LOGE, "PMC: response message to request to enter "
1306 "standby indicates failure, status %x", pMsg->statusCode);
1307 pmcEnterFullPowerState(pMac);
1308 pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE);
1309 }
1310 }
1311 else
1312 {
1313 smsLog(pMac, LOGE, "PMC: Enter IMPS rsp rcvd when device is "
1314 "in %d state", pMac->pmc.pmcState);
1315 }
1316 break;
1317
1318 /* We got a response to our wake from IMPS request. */
1319 case eWNI_PMC_EXIT_IMPS_RSP:
1320 smsLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_IMPS_RSP with status = %d"), pMsg->statusCode);
1321 if( eSmeCommandExitImps != pCommand->command )
1322 {
1323 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_IMPS_RSP without request"));
1324 fRemoveCommand = eANI_BOOLEAN_FALSE;
1325 break;
1326 }
1327 /* Check that we are in the correct state for this message. */
1328 if (pMac->pmc.pmcState != REQUEST_FULL_POWER)
1329 {
1330 smsLog(pMac, LOGE, FL("Got Exit IMPS Response Message while in state %d"), pMac->pmc.pmcState);
1331 break;
1332 }
1333
1334 /* Enter Full Power State. */
1335 if (pMsg->statusCode != eSIR_SME_SUCCESS)
1336 {
1337 smsLog(pMac, LOGP, FL("Response message to request to exit IMPS indicates failure, status %x"),
1338 pMsg->statusCode);
1339 }
1340 pmcEnterFullPowerState(pMac);
1341 break;
1342
1343 /* We got a response to our BMPS request. */
1344 case eWNI_PMC_ENTER_BMPS_RSP:
1345 smsLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP with status = %d"), pMsg->statusCode);
1346 if( eSmeCommandEnterBmps != pCommand->command )
1347 {
1348 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP without request"));
1349 fRemoveCommand = eANI_BOOLEAN_FALSE;
1350 break;
1351 }
1352 pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE;
1353 /* Check that we are in the correct state for this message. */
1354 if (pMac->pmc.pmcState != REQUEST_BMPS)
1355 {
1356 smsLog(pMac, LOGE, FL("Got Enter BMPS Response Message while in state %d"), pMac->pmc.pmcState);
1357 break;
1358 }
1359
1360 /* Enter BMPS State if response indicates success. */
1361 if (pMsg->statusCode == eSIR_SME_SUCCESS)
1362 {
1363 pmcEnterBmpsState(pMac);
1364 /* Note: If BMPS was requested because of start UAPSD,
1365 there will no entries for BMPS callback routines and
1366 pmcDoBmpsCallbacks will be a No-Op*/
1367 pmcDoBmpsCallbacks(pMac, eHAL_STATUS_SUCCESS);
1368 }
1369 /* If response is failure, then we stay in Full Power State and tell everyone that we aren't going into BMPS. */
1370 else
1371 {
1372 smsLog(pMac, LOGE, FL("Response message to request to enter BMPS indicates failure, status %x"),
1373 pMsg->statusCode);
1374 pmcEnterFullPowerState(pMac);
1375 //Do not call UAPSD callback here since it may be re-entered
1376 pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE);
1377 }
1378 break;
1379
1380 /* We got a response to our wake from BMPS request. */
1381 case eWNI_PMC_EXIT_BMPS_RSP:
1382 smsLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP with status = %d"), pMsg->statusCode);
1383 if( eSmeCommandExitBmps != pCommand->command )
1384 {
1385 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP without request"));
1386 fRemoveCommand = eANI_BOOLEAN_FALSE;
1387 break;
1388 }
1389 /* Check that we are in the correct state for this message. */
1390 if (pMac->pmc.pmcState != REQUEST_FULL_POWER)
1391 {
1392 smsLog(pMac, LOGE, FL("Got Exit BMPS Response Message while in state %d"), pMac->pmc.pmcState);
1393 break;
1394 }
1395
1396 /* Enter Full Power State. */
1397 if (pMsg->statusCode != eSIR_SME_SUCCESS)
1398 {
1399 smsLog(pMac, LOGP, FL("Response message to request to exit BMPS indicates failure, status %x"),
1400 pMsg->statusCode);
1401 }
1402 pmcEnterFullPowerState(pMac);
1403 break;
1404
1405 /* We got a response to our Start UAPSD request. */
1406 case eWNI_PMC_ENTER_UAPSD_RSP:
1407 smsLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP with status = %d"), pMsg->statusCode);
1408 if( eSmeCommandEnterUapsd != pCommand->command )
1409 {
1410 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP without request"));
1411 fRemoveCommand = eANI_BOOLEAN_FALSE;
1412 break;
1413 }
1414 /* Check that we are in the correct state for this message. */
1415 if (pMac->pmc.pmcState != REQUEST_START_UAPSD)
1416 {
1417 smsLog(pMac, LOGE, FL("Got Enter Uapsd rsp Message while in state %d"), pMac->pmc.pmcState);
1418 break;
1419 }
1420
1421 /* Enter UAPSD State if response indicates success. */
1422 if (pMsg->statusCode == eSIR_SME_SUCCESS)
1423 {
1424 pmcEnterUapsdState(pMac);
1425 pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_SUCCESS);
1426 }
1427 /* If response is failure, then we try to put the chip back in
1428 BMPS mode*/
1429 else {
1430 smsLog(pMac, LOGE, "PMC: response message to request to enter "
1431 "UAPSD indicates failure, status %x", pMsg->statusCode);
1432 //Need to reset the UAPSD flag so pmcEnterBmpsState won't try to enter UAPSD.
1433 pMac->pmc.uapsdSessionRequired = FALSE;
1434 pmcEnterBmpsState(pMac);
1435 //UAPSD will not be retied in this case so tell requester we are done with failure
1436 pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE);
1437 }
1438 break;
1439
1440 /* We got a response to our Stop UAPSD request. */
1441 case eWNI_PMC_EXIT_UAPSD_RSP:
1442 smsLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP with status = %d"), pMsg->statusCode);
1443 if( eSmeCommandExitUapsd != pCommand->command )
1444 {
1445 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP without request"));
1446 fRemoveCommand = eANI_BOOLEAN_FALSE;
1447 break;
1448 }
1449 /* Check that we are in the correct state for this message. */
1450 if (pMac->pmc.pmcState != REQUEST_STOP_UAPSD)
1451 {
1452 smsLog(pMac, LOGE, FL("Got Exit Uapsd rsp Message while in state %d"), pMac->pmc.pmcState);
1453 break;
1454 }
1455
1456 /* Enter BMPS State */
1457 if (pMsg->statusCode != eSIR_SME_SUCCESS) {
1458 smsLog(pMac, LOGP, "PMC: response message to request to exit "
1459 "UAPSD indicates failure, status %x", pMsg->statusCode);
1460 }
1461 pmcEnterBmpsState(pMac);
1462 break;
1463
1464 /* We got a response to our enter WOWL request. */
1465 case eWNI_PMC_ENTER_WOWL_RSP:
1466
1467 if( eSmeCommandEnterWowl != pCommand->command )
1468 {
1469 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_WOWL_RSP without request"));
1470 fRemoveCommand = eANI_BOOLEAN_FALSE;
1471 break;
1472 }
1473 /* Check that we are in the correct state for this message. */
1474 if (pMac->pmc.pmcState != REQUEST_ENTER_WOWL)
1475 {
1476 smsLog(pMac, LOGE, FL("Got eWNI_PMC_ENTER_WOWL_RSP while in state %s"),
1477 pmcGetPmcStateStr(pMac->pmc.pmcState));
1478 break;
1479 }
1480
1481 /* Enter WOWL State if response indicates success. */
1482 if (pMsg->statusCode == eSIR_SME_SUCCESS) {
1483 pmcEnterWowlState(pMac);
1484 pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_SUCCESS);
1485 }
1486
1487 /* If response is failure, then we try to put the chip back in
1488 BMPS mode*/
1489 else {
1490 smsLog(pMac, LOGE, "PMC: response message to request to enter "
1491 "WOWL indicates failure, status %x", pMsg->statusCode);
1492 pmcEnterBmpsState(pMac);
1493 pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE);
1494 }
1495 break;
1496
1497 /* We got a response to our exit WOWL request. */
1498 case eWNI_PMC_EXIT_WOWL_RSP:
1499
1500 if( eSmeCommandExitWowl != pCommand->command )
1501 {
1502 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_WOWL_RSP without request"));
1503 fRemoveCommand = eANI_BOOLEAN_FALSE;
1504 break;
1505 }
1506 /* Check that we are in the correct state for this message. */
1507 if (pMac->pmc.pmcState != REQUEST_EXIT_WOWL)
1508 {
1509 smsLog(pMac, LOGE, FL("Got Exit WOWL rsp Message while in state %d"), pMac->pmc.pmcState);
1510 break;
1511 }
1512
1513 /* Enter BMPS State */
1514 if (pMsg->statusCode != eSIR_SME_SUCCESS) {
1515 smsLog(pMac, LOGP, "PMC: response message to request to exit "
1516 "WOWL indicates failure, status %x", pMsg->statusCode);
1517 }
1518 pmcEnterBmpsState(pMac);
1519 break;
1520
1521 default:
1522 smsLog(pMac, LOGE, FL("Invalid message type %d received"), pMsg->messageType);
1523 PMC_ABORT;
1524 break;
1525 }//switch
1526
1527 if( fRemoveCommand )
1528 {
1529 if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) )
1530 {
1531 pmcReleaseCommand( pMac, pCommand );
1532 smeProcessPendingQueue( pMac );
1533 }
1534 }
1535 }
1536 else
1537 {
1538 smsLog(pMac, LOGE, FL("message type %d received but no request is found"), pMsg->messageType);
1539 }
1540}
1541
1542
1543/******************************************************************************
1544*
1545* Name: pmcMessageProcessor
1546*
1547* Description:
1548* Process a message received by PMC.
1549*
1550* Parameters:
1551* hHal - HAL handle for device
1552* pMsg - pointer to received message
1553*
1554* Returns:
1555* nothing
1556*
1557******************************************************************************/
1558void pmcMessageProcessor (tHalHandle hHal, tSirSmeRsp *pMsg)
1559{
1560 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1561
1562 smsLog(pMac, LOG2, FL("Entering pmcMessageProcessor, message type %d"), pMsg->messageType);
1563
1564 switch( pMsg->messageType )
1565 {
1566 case eWNI_PMC_EXIT_BMPS_IND:
1567 //When PMC needs to handle more indication from PE, they need to be added here.
1568 {
1569 /* Device left BMPS on its own. */
1570 smsLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_BMPS_IND with status = %d"), pMsg->statusCode);
1571 /* Check that we are in the correct state for this message. */
1572 switch(pMac->pmc.pmcState)
1573 {
1574 case BMPS:
1575 case REQUEST_START_UAPSD:
1576 case UAPSD:
1577 case REQUEST_STOP_UAPSD:
1578 case REQUEST_ENTER_WOWL:
1579 case WOWL:
1580 case REQUEST_EXIT_WOWL:
1581 case REQUEST_FULL_POWER:
1582 smsLog(pMac, LOGW, FL("Got eWNI_PMC_EXIT_BMPS_IND while in state %d"), pMac->pmc.pmcState);
1583 break;
1584 default:
1585 smsLog(pMac, LOGE, FL("Got eWNI_PMC_EXIT_BMPS_IND while in state %d"), pMac->pmc.pmcState);
1586 PMC_ABORT;
1587 break;
1588 }
1589
1590 /* Enter Full Power State. */
1591 if (pMsg->statusCode != eSIR_SME_SUCCESS)
1592 {
1593 smsLog(pMac, LOGP, FL("Exit BMPS indication indicates failure, status %x"), pMsg->statusCode);
1594 }
1595 else
1596 {
1597 tpSirSmeExitBmpsInd pExitBmpsInd = (tpSirSmeExitBmpsInd)pMsg;
1598 pmcEnterRequestFullPowerState(hHal, pExitBmpsInd->exitBmpsReason);
1599 }
1600 break;
1601 }
1602
1603 default:
1604 pmcProcessResponse( pMac, pMsg );
1605 break;
1606 }
1607
1608}
1609
1610
1611tANI_BOOLEAN pmcValidateConnectState( tHalHandle hHal )
1612{
1613 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1614
1615 if ( !csrIsInfraConnected( pMac ) )
1616 {
1617 smsLog(pMac, LOGW, "PMC: STA not associated. BMPS cannot be entered");
1618 return eANI_BOOLEAN_FALSE;
1619 }
1620
1621 //Cannot have other session
1622 if ( csrIsIBSSStarted( pMac ) )
1623 {
1624 smsLog(pMac, LOGW, "PMC: IBSS started. BMPS cannot be entered");
1625 return eANI_BOOLEAN_FALSE;
1626 }
1627 if ( csrIsBTAMPStarted( pMac ) )
1628 {
1629 smsLog(pMac, LOGW, "PMC: BT-AMP exists. BMPS cannot be entered");
1630 return eANI_BOOLEAN_FALSE;
1631 }
1632 if ((vos_concurrent_sessions_running()) &&
1633 (csrIsConcurrentInfraConnected( pMac ) ||
1634 (vos_get_concurrency_mode()& VOS_SAP) ||
1635 (vos_get_concurrency_mode()& VOS_P2P_GO)))
1636 {
1637 smsLog(pMac, LOGW, "PMC: Multiple active sessions exists. BMPS cannot be entered");
1638 return eANI_BOOLEAN_FALSE;
1639 }
1640 return eANI_BOOLEAN_TRUE;
1641}
1642
1643tANI_BOOLEAN pmcAllowImps( tHalHandle hHal )
1644{
1645 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1646
1647 //Cannot have other session like IBSS or BT AMP running
1648 if ( csrIsIBSSStarted( pMac ) )
1649 {
1650 smsLog(pMac, LOGW, "PMC: IBSS started. IMPS cannot be entered");
1651 return eANI_BOOLEAN_FALSE;
1652 }
1653 if ( csrIsBTAMPStarted( pMac ) )
1654 {
1655 smsLog(pMac, LOGW, "PMC: BT-AMP exists. IMPS cannot be entered");
1656 return eANI_BOOLEAN_FALSE;
1657 }
1658
1659 //All sessions must be disconnected to allow IMPS
1660 if ( !csrIsAllSessionDisconnected( pMac ) )
1661 {
1662 smsLog(pMac, LOGW, "PMC: Atleast one connected session. IMPS cannot be entered");
1663 return eANI_BOOLEAN_FALSE;
1664 }
1665
1666 return eANI_BOOLEAN_TRUE;
1667}
1668
1669/******************************************************************************
1670*
1671* Name: pmcRequestBmps
1672*
1673* Description:
1674* Request that the device be put in BMPS state.
1675*
1676* Parameters:
1677* hHal - HAL handle for device
1678* callbackRoutine - Callback routine invoked in case of success/failure
1679* callbackContext - value to be passed as parameter to routine specified
1680* above
1681*
1682* Returns:
1683* eHAL_STATUS_SUCCESS - device is in BMPS state
1684* eHAL_STATUS_FAILURE - device cannot be brought to BMPS state
1685* eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state,
1686*
1687******************************************************************************/
1688eHalStatus pmcRequestBmps (
1689 tHalHandle hHal,
1690 void (*callbackRoutine) (void *callbackContext, eHalStatus status),
1691 void *callbackContext)
1692{
1693 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1694 tpRequestBmpsEntry pEntry;
1695 eHalStatus status;
1696
1697#ifdef FEATURE_WLAN_DIAG_SUPPORT
1698 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
1699
1700 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
1701 psRequest.event_subtype = WLAN_BMPS_ENTER_REQ;
1702
1703 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
1704#endif
1705
1706 smsLog(pMac, LOG2, "PMC: entering pmcRequestBmps");
1707
1708 /* If already in BMPS, just return. */
1709 if (pMac->pmc.pmcState == BMPS || REQUEST_START_UAPSD == pMac->pmc.pmcState || UAPSD == pMac->pmc.pmcState)
1710 {
1711 smsLog(pMac, LOG2, "PMC: Device already in BMPS pmcState %d", pMac->pmc.pmcState);
1712 pMac->pmc.bmpsRequestedByHdd = TRUE;
1713 return eHAL_STATUS_SUCCESS;
1714 }
1715
1716 status = pmcEnterBmpsCheck( pMac );
1717 if(HAL_STATUS_SUCCESS( status ))
1718 {
1719 status = pmcEnterRequestBmpsState(hHal);
1720 /* Enter Request BMPS State. */
1721 if ( HAL_STATUS_SUCCESS( status ) )
1722 {
1723 /* Remember that HDD requested BMPS. This flag will be used to put the
1724 device back into BMPS if any module other than HDD (e.g. CSR, QoS, or BAP)
1725 requests full power for any reason */
1726 pMac->pmc.bmpsRequestedByHdd = TRUE;
1727
1728 /* If able to enter Request BMPS State, then request is pending.
1729 Allocate entry for request BMPS callback routine list. */
1730 if (palAllocateMemory(
1731 pMac->hHdd, (void **)&pEntry,
1732 sizeof(tRequestBmpsEntry)) != eHAL_STATUS_SUCCESS)
1733 {
1734 smsLog(pMac, LOGE, "PMC: cannot allocate memory for request "
1735 "BMPS routine list entry");
1736 return eHAL_STATUS_FAILURE;
1737 }
1738
1739 /* Store routine and context in entry. */
1740 pEntry->callbackRoutine = callbackRoutine;
1741 pEntry->callbackContext = callbackContext;
1742
1743 /* Add entry to list. */
1744 csrLLInsertTail(&pMac->pmc.requestBmpsList, &pEntry->link, FALSE);
1745
1746 status = eHAL_STATUS_PMC_PENDING;
1747 }
1748 else
1749 {
1750 status = eHAL_STATUS_FAILURE;
1751 }
1752 }
1753 /* Retry to enter the BMPS if the
1754 status = eHAL_STATUS_PMC_NOT_NOW */
1755 else if (status == eHAL_STATUS_PMC_NOT_NOW)
1756 {
1757 pmcStopTrafficTimer(hHal);
1758 smsLog(pMac, LOG1, FL("Can't enter BMPS+++"));
1759 if (pmcShouldBmpsTimerRun(pMac))
1760 {
1761 if (pmcStartTrafficTimer(pMac,
1762 pMac->pmc.bmpsConfig.trafficMeasurePeriod)
1763 != eHAL_STATUS_SUCCESS)
1764 {
1765 smsLog(pMac, LOG1, FL("Cannot start BMPS Retry timer"));
1766 }
1767 smsLog(pMac, LOG1,
1768 FL("BMPS Retry Timer already running or started"));
1769 }
1770 }
1771
1772 return status;
1773}
1774
1775/******************************************************************************
1776*
1777* Name: pmcStartUapsd
1778*
1779* Description:
1780* Request that the device be put in UAPSD state.
1781*
1782* Parameters:
1783* hHal - HAL handle for device
1784* callbackRoutine - Callback routine invoked in case of success/failure
1785* callbackContext - value to be passed as parameter to routine specified
1786* above
1787*
1788* Returns:
1789* eHAL_STATUS_SUCCESS - device is in UAPSD state
1790* eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state
1791* eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state
1792* eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled
1793*
1794******************************************************************************/
1795eHalStatus pmcStartUapsd (
1796 tHalHandle hHal,
1797 void (*callbackRoutine) (void *callbackContext, eHalStatus status),
1798 void *callbackContext)
1799{
1800 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1801 tpStartUapsdEntry pEntry;
1802
1803#ifdef FEATURE_WLAN_DIAG_SUPPORT
1804 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
1805
1806 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
1807 psRequest.event_subtype = WLAN_UAPSD_START_REQ;
1808
1809 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
1810#endif
1811
1812 smsLog(pMac, LOG2, "PMC: entering pmcStartUapsd");
1813
1814 if( !PMC_IS_READY(pMac) )
1815 {
1816 smsLog(pMac, LOGE, FL("Requesting UAPSD when PMC not ready"));
1817 smsLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"),
1818 pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState));
1819 return eHAL_STATUS_FAILURE;
1820 }
1821
1822 /* Check if BMPS is enabled. */
1823 if (!pMac->pmc.bmpsEnabled)
1824 {
1825 smsLog(pMac, LOGE, "PMC: Cannot enter UAPSD. BMPS is disabled");
1826 return eHAL_STATUS_PMC_DISABLED;
1827 }
1828
1829 /* Check if UAPSD is enabled. */
1830 if (!pMac->pmc.uapsdEnabled)
1831 {
1832 smsLog(pMac, LOGE, "PMC: Cannot enter UAPSD. UAPSD is disabled");
1833 return eHAL_STATUS_PMC_DISABLED;
1834 }
1835
1836 /* If already in UAPSD, just return. */
1837 if (pMac->pmc.pmcState == UAPSD)
1838 return eHAL_STATUS_SUCCESS;
1839
1840 /* Check that we are associated. */
1841 if (!pmcValidateConnectState( pMac ))
1842 {
1843 smsLog(pMac, LOGE, "PMC: STA not associated with an AP. UAPSD cannot be entered");
1844 return eHAL_STATUS_FAILURE;
1845 }
1846
1847 /* Enter REQUEST_START_UAPSD State. */
1848 if (pmcEnterRequestStartUapsdState(hHal) != eHAL_STATUS_SUCCESS)
1849 return eHAL_STATUS_FAILURE;
1850
1851 if( NULL != callbackRoutine )
1852 {
1853 /* If success then request is pending. Allocate entry for callback routine list. */
1854 if (palAllocateMemory(pMac->hHdd, (void **)&pEntry,
1855 sizeof(tStartUapsdEntry)) != eHAL_STATUS_SUCCESS)
1856 {
1857 smsLog(pMac, LOGE, "PMC: cannot allocate memory for request "
1858 "start UAPSD routine list entry");
1859 return eHAL_STATUS_FAILURE;
1860 }
1861
1862 /* Store routine and context in entry. */
1863 pEntry->callbackRoutine = callbackRoutine;
1864 pEntry->callbackContext = callbackContext;
1865
1866 /* Add entry to list. */
1867 csrLLInsertTail(&pMac->pmc.requestStartUapsdList, &pEntry->link, FALSE);
1868 }
1869
1870 return eHAL_STATUS_PMC_PENDING;
1871}
1872
1873/******************************************************************************
1874*
1875* Name: pmcStopUapsd
1876*
1877* Description:
1878* Request that the device be put out of UAPSD state.
1879*
1880* Parameters:
1881* hHal - HAL handle for device
1882*
1883* Returns:
1884* eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state
1885* eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state
1886*
1887******************************************************************************/
1888eHalStatus pmcStopUapsd (tHalHandle hHal)
1889{
1890 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1891
1892#ifdef FEATURE_WLAN_DIAG_SUPPORT
1893 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
1894
1895 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
1896 psRequest.event_subtype = WLAN_UAPSD_STOP_REQ;
1897
1898 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
1899#endif
1900
1901 smsLog(pMac, LOG2, "PMC: entering pmcStopUapsd");
1902
1903 /* Clear any buffered command for entering UAPSD */
1904 pMac->pmc.uapsdSessionRequired = FALSE;
1905
1906 /* Nothing to be done if we are already out of UAPSD. This can happen if
1907 some other module (HDD, BT-AMP) requested Full Power.*/
1908 if (pMac->pmc.pmcState != UAPSD && pMac->pmc.pmcState != REQUEST_STOP_UAPSD)
1909 {
1910 smsLog(pMac, LOGW, "PMC: Device is already out of UAPSD "
1911 "state. Current state is %d", pMac->pmc.pmcState);
1912 return eHAL_STATUS_SUCCESS;
1913 }
1914
1915 /* Enter REQUEST_STOP_UAPSD State*/
1916 if (pmcEnterRequestStopUapsdState(hHal) != eHAL_STATUS_SUCCESS)
1917 return eHAL_STATUS_FAILURE;
1918
1919 return eHAL_STATUS_SUCCESS;
1920}
1921
1922/* ---------------------------------------------------------------------------
1923 \fn pmcRequestStandby
1924 \brief Request that the device be put in standby.
1925 \param hHal - The handle returned by macOpen.
1926 \param callbackRoutine - Callback routine invoked in case of success/failure
1927 \param callbackContext - value to be passed as parameter to callback
1928 \return eHalStatus
1929 eHAL_STATUS_SUCCESS - device is in Standby mode
1930 eHAL_STATUS_FAILURE - device cannot be put in standby mode
1931 eHAL_STATUS_PMC_PENDING - device is being put in standby mode
1932 ---------------------------------------------------------------------------*/
1933extern eHalStatus pmcRequestStandby (
1934 tHalHandle hHal,
1935 void (*callbackRoutine) (void *callbackContext, eHalStatus status),
1936 void *callbackContext)
1937{
1938 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1939
1940#ifdef FEATURE_WLAN_DIAG_SUPPORT
1941 WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type);
1942
1943 vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type));
1944 psRequest.event_subtype = WLAN_ENTER_STANDBY_REQ;
1945
1946 WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC);
1947#endif
1948
1949 smsLog(pMac, LOG2, "PMC: entering pmcRequestStandby");
1950
1951 /* Check if standby is enabled. */
1952 if (!pMac->pmc.standbyEnabled)
1953 {
1954 smsLog(pMac, LOGE, "PMC: Cannot enter standby. Standby is disabled");
1955 return eHAL_STATUS_PMC_DISABLED;
1956 }
1957
1958 if( !PMC_IS_READY(pMac) )
1959 {
1960 smsLog(pMac, LOGE, FL("Requesting standby when PMC not ready"));
1961 smsLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"),
1962 pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState));
1963 return eHAL_STATUS_FAILURE;
1964 }
1965
1966 /* If already in STANDBY, just return. */
1967 if (pMac->pmc.pmcState == STANDBY)
1968 return eHAL_STATUS_SUCCESS;
1969
1970
1971 if (csrIsIBSSStarted(pMac) || csrIsBTAMPStarted(pMac))
1972 {
1973 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
1974 "WLAN: IBSS or BT-AMP session present. Cannot honor standby request");
1975 return eHAL_STATUS_PMC_NOT_NOW;
1976 }
1977
1978 /* Enter Request Standby State. */
1979 if (pmcEnterRequestStandbyState(hHal) != eHAL_STATUS_SUCCESS)
1980 return eHAL_STATUS_FAILURE;
1981
1982 /* Save the callback routine for when we need it. */
1983 pMac->pmc.standbyCallbackRoutine = callbackRoutine;
1984 pMac->pmc.standbyCallbackContext = callbackContext;
1985
1986 return eHAL_STATUS_PMC_PENDING;
1987}
1988
1989/* ---------------------------------------------------------------------------
1990 \fn pmcRegisterDeviceStateUpdateInd
1991 \brief Register a callback routine that is called whenever
1992 the device enters a new device state (Full Power, BMPS, UAPSD)
1993 \param hHal - The handle returned by macOpen.
1994 \param callbackRoutine - Callback routine to be registered
1995 \param callbackContext - Cookie to be passed back during callback
1996 \return eHalStatus
1997 eHAL_STATUS_SUCCESS - successfully registered
1998 eHAL_STATUS_FAILURE - not successfully registered
1999 ---------------------------------------------------------------------------*/
2000extern eHalStatus pmcRegisterDeviceStateUpdateInd (tHalHandle hHal,
2001 void (*callbackRoutine) (void *callbackContext, tPmcState pmcState),
2002 void *callbackContext)
2003{
2004
2005 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2006 tpDeviceStateUpdateIndEntry pEntry;
2007
2008 smsLog(pMac, LOG2, FL("Entering pmcRegisterDeviceStateUpdateInd"));
2009
2010 /* Allocate entry for device power state update indication. */
2011 if (palAllocateMemory(pMac->hHdd, (void **)&pEntry, sizeof(tDeviceStateUpdateIndEntry)) != eHAL_STATUS_SUCCESS)
2012 {
2013 smsLog(pMac, LOGE, FL("Cannot allocate memory for device power state update indication"));
2014 PMC_ABORT;
2015 return eHAL_STATUS_FAILURE;
2016 }
2017
2018 /* Store routine in entry. */
2019 pEntry->callbackRoutine = callbackRoutine;
2020 pEntry->callbackContext = callbackContext;
2021
2022 /* Add entry to list. */
2023 csrLLInsertTail(&pMac->pmc.deviceStateUpdateIndList, &pEntry->link, FALSE);
2024
2025 return eHAL_STATUS_SUCCESS;
2026}
2027
2028/* ---------------------------------------------------------------------------
2029 \fn pmcDeregisterDeviceStateUpdateInd
2030 \brief Deregister a routine that was registered for device state changes
2031 \param hHal - The handle returned by macOpen.
2032 \param callbackRoutine - Callback routine to be deregistered
2033 \return eHalStatus
2034 eHAL_STATUS_SUCCESS - successfully deregistered
2035 eHAL_STATUS_FAILURE - not successfully deregistered
2036 ---------------------------------------------------------------------------*/
2037eHalStatus pmcDeregisterDeviceStateUpdateInd (tHalHandle hHal,
2038 void (*callbackRoutine) (void *callbackContext, tPmcState pmcState))
2039{
2040 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2041 tListElem *pEntry;
2042 tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry;
2043
2044 smsLog(pMac, LOG2, FL("Entering pmcDeregisterDeviceStateUpdateInd"));
2045
2046 /* Find entry in the power save update routine list that matches
2047 the specified routine and remove it. */
2048 pEntry = csrLLPeekHead(&pMac->pmc.deviceStateUpdateIndList, FALSE);
2049 while (pEntry != NULL)
2050 {
2051 pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link);
2052 if (pDeviceStateUpdateIndEntry->callbackRoutine == callbackRoutine)
2053 {
2054 if (!csrLLRemoveEntry(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE))
2055 {
2056 smsLog(pMac, LOGE, FL("Cannot remove device state update ind entry from list"));
2057 return eHAL_STATUS_FAILURE;
2058 }
2059 if (palFreeMemory(pMac->hHdd, pDeviceStateUpdateIndEntry) != eHAL_STATUS_SUCCESS)
2060 {
2061 smsLog(pMac, LOGE, FL("Cannot free memory for device state update ind routine list entry"));
2062 PMC_ABORT;
2063 return eHAL_STATUS_FAILURE;
2064 }
2065 return eHAL_STATUS_SUCCESS;
2066 }
2067 pEntry = csrLLNext(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE);
2068 }
2069
2070 /* Could not find matching entry. */
2071 return eHAL_STATUS_FAILURE;
2072}
2073
2074/* ---------------------------------------------------------------------------
2075 \fn pmcReady
2076 \brief fn to inform PMC that eWNI_SME_SYS_READY_IND has been sent to PE.
2077 This acts as a trigger to send a message to PE to update the power
2078 save related conig to FW. Note that if HDD configures any power save
2079 related stuff before this API is invoked, PMC will buffer all the
2080 configutaion.
2081 \param hHal - The handle returned by macOpen.
2082 \return eHalStatus
2083 ---------------------------------------------------------------------------*/
2084eHalStatus pmcReady(tHalHandle hHal)
2085{
2086 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2087
2088 smsLog(pMac, LOG2, FL("Entering pmcReady"));
2089
2090 if(pMac->pmc.pmcState == STOPPED)
2091 {
2092 smsLog(pMac, LOGP, FL("pmcReady is invoked even before pmcStart"));
2093 return eHAL_STATUS_FAILURE;
2094 }
2095
2096 pMac->pmc.pmcReady = TRUE;
2097 if (pmcSendPowerSaveConfigMessage(hHal) != eHAL_STATUS_SUCCESS)
2098 {
2099 return eHAL_STATUS_FAILURE;
2100 }
2101
2102 return eHAL_STATUS_SUCCESS;
2103}
2104
2105/* ---------------------------------------------------------------------------
2106 \fn pmcWowlAddBcastPattern
2107 \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will
2108 do a pattern match on these patterns when Wowl is enabled during BMPS
2109 mode. Note that Firmware performs the pattern matching only on
2110 broadcast frames and while Libra is in BMPS mode.
2111 \param hHal - The handle returned by macOpen.
2112 \param pattern - Pointer to the pattern to be added
2113 \return eHalStatus
2114 eHAL_STATUS_FAILURE Cannot add pattern
2115 eHAL_STATUS_SUCCESS Request accepted.
2116 ---------------------------------------------------------------------------*/
2117eHalStatus pmcWowlAddBcastPattern (
2118 tHalHandle hHal,
2119 tpSirWowlAddBcastPtrn pattern,
2120 tANI_U8 sessionId)
2121{
2122 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2123 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2124
2125#ifdef FEATURE_WLAN_DIAG_SUPPORT
2126 vos_log_powersave_wow_add_ptrn_pkt_type *log_ptr = NULL;
2127 WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_powersave_wow_add_ptrn_pkt_type, LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C);
2128#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT
2129
2130 smsLog(pMac, LOG2, "PMC: entering pmcWowlAddBcastPattern");
2131
2132 if(pattern == NULL)
2133 {
2134 smsLog(pMac, LOGE, FL("Null broadcast pattern being passed"));
2135 return eHAL_STATUS_FAILURE;
2136 }
2137
2138 if( pSession == NULL)
2139 {
2140 smsLog(pMac, LOGE, FL("Session not found "));
2141 return eHAL_STATUS_FAILURE;
2142 }
2143
2144#ifdef FEATURE_WLAN_DIAG_SUPPORT
2145 if( log_ptr )
2146 {
2147 log_ptr->pattern_id = pattern->ucPatternId;
2148 log_ptr->pattern_byte_offset = pattern->ucPatternByteOffset;
2149 log_ptr->pattern_size = pattern->ucPatternSize;
2150 log_ptr->pattern_mask_size = pattern->ucPatternMaskSize;
2151
2152 vos_mem_copy(log_ptr->pattern, pattern->ucPattern, SIR_WOWL_BCAST_PATTERN_MAX_SIZE);
2153 /* 1 bit in the pattern mask denotes 1 byte of pattern hence pattern mask size is 1/8 */
2154 vos_mem_copy(log_ptr->pattern_mask, pattern->ucPatternMask, SIR_WOWL_BCAST_PATTERN_MAX_SIZE >> 3);
2155 }
2156
2157 WLAN_VOS_DIAG_LOG_REPORT(log_ptr);
2158#endif
2159
2160
2161 if(pattern->ucPatternId >= SIR_WOWL_BCAST_MAX_NUM_PATTERNS )
2162 {
2163 smsLog(pMac, LOGE, FL("Pattern Id must range from 0 to %d"), SIR_WOWL_BCAST_MAX_NUM_PATTERNS-1);
2164 return eHAL_STATUS_FAILURE;
2165 }
2166
2167 if( pMac->pmc.pmcState == STANDBY || pMac->pmc.pmcState == REQUEST_STANDBY )
2168 {
2169 smsLog(pMac, LOGE, FL("Cannot add WoWL Pattern as chip is in %s state"),
2170 pmcGetPmcStateStr(pMac->pmc.pmcState));
2171 return eHAL_STATUS_FAILURE;
2172 }
2173 if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS )
2174 {
2175 eHalStatus status;
2176 vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2177 //Wake up the chip first
2178 status = pmcDeferMsg( pMac, eWNI_PMC_WOWL_ADD_BCAST_PTRN,
2179 pattern, sizeof(tSirWowlAddBcastPtrn) );
2180
2181 if( eHAL_STATUS_PMC_PENDING == status )
2182 {
2183 return eHAL_STATUS_SUCCESS;
2184 }
2185 else
2186 {
2187 //either fail or already in full power
2188 if( !HAL_STATUS_SUCCESS( status ) )
2189 {
2190 return ( status );
2191 }
2192 //else let it through because it is in full power state
2193 }
2194 }
2195
2196 if (pmcSendMessage(hHal, eWNI_PMC_WOWL_ADD_BCAST_PTRN, pattern, sizeof(tSirWowlAddBcastPtrn))
2197 != eHAL_STATUS_SUCCESS)
2198 {
2199 smsLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed"));
2200 return eHAL_STATUS_FAILURE;
2201 }
2202
2203 return eHAL_STATUS_SUCCESS;
2204}
2205
2206/* ---------------------------------------------------------------------------
2207 \fn pmcWowlDelBcastPattern
2208 \brief Delete a pattern that was added for Pattern Byte Matching.
2209 \param hHal - The handle returned by macOpen.
2210 \param pattern - Pattern to be deleted
2211 \return eHalStatus
2212 eHAL_STATUS_FAILURE Cannot delete pattern
2213 eHAL_STATUS_SUCCESS Request accepted.
2214 ---------------------------------------------------------------------------*/
2215eHalStatus pmcWowlDelBcastPattern (
2216 tHalHandle hHal,
2217 tpSirWowlDelBcastPtrn pattern,
2218 tANI_U8 sessionId)
2219{
2220 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2221 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2222
2223#ifdef FEATURE_WLAN_DIAG_SUPPORT
2224 WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type);
2225
2226 vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type));
2227 wowRequest.event_subtype = WLAN_WOW_DEL_PTRN_REQ;
2228 wowRequest.wow_del_ptrn_id = pattern->ucPatternId;
2229
2230 WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW);
2231#endif
2232
2233 smsLog(pMac, LOG2, "PMC: entering pmcWowlDelBcastPattern");
2234
2235 if( NULL == pSession )
2236 {
2237 smsLog(pMac, LOGE, FL("Session not found "));
2238 return eHAL_STATUS_FAILURE;
2239 }
2240
2241 if(pattern->ucPatternId >= SIR_WOWL_BCAST_MAX_NUM_PATTERNS )
2242 {
2243 smsLog(pMac, LOGE, FL("Pattern Id must range from 0 to %d"),
2244 SIR_WOWL_BCAST_MAX_NUM_PATTERNS-1);
2245 return eHAL_STATUS_FAILURE;
2246 }
2247
2248 if(pMac->pmc.pmcState == STANDBY || pMac->pmc.pmcState == REQUEST_STANDBY)
2249 {
2250 smsLog(pMac, LOGE, FL("Cannot delete WoWL Pattern as chip is in %s state"),
2251 pmcGetPmcStateStr(pMac->pmc.pmcState));
2252 return eHAL_STATUS_FAILURE;
2253 }
2254
2255 if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS )
2256 {
2257 eHalStatus status;
2258
2259 vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2260 //Wake up the chip first
2261 status = pmcDeferMsg( pMac, eWNI_PMC_WOWL_DEL_BCAST_PTRN,
2262 pattern, sizeof(tSirWowlDelBcastPtrn) );
2263
2264 if( eHAL_STATUS_PMC_PENDING == status )
2265 {
2266 return eHAL_STATUS_SUCCESS;
2267 }
2268 else
2269 {
2270 //either fail or already in full power
2271 if( !HAL_STATUS_SUCCESS( status ) )
2272 {
2273 return ( status );
2274 }
2275 //else let it through because it is in full power state
2276 }
2277 }
2278
2279 if (pmcSendMessage(hHal, eWNI_PMC_WOWL_DEL_BCAST_PTRN, pattern, sizeof(tSirWowlDelBcastPtrn))
2280 != eHAL_STATUS_SUCCESS)
2281 {
2282 smsLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_DEL_BCAST_PTRN to PE failed"));
2283 return eHAL_STATUS_FAILURE;
2284 }
2285
2286 return eHAL_STATUS_SUCCESS;
2287}
2288
2289/* ---------------------------------------------------------------------------
2290 \fn pmcEnterWowl
2291 \brief Request that the device be brought to full power state.
2292 Note 1: If "fullPowerReason" specificied in this API is set to
2293 eSME_FULL_PWR_NEEDED_BY_HDD, PMC will clear any "buffered wowl" requests
2294 and also clear any "buffered BMPS requests by HDD". Assumption is that since
2295 HDD is requesting full power, we need to undo any previous HDD requests for
2296 BMPS (using sme_RequestBmps) or WoWL (using sme_EnterWoWL). If the reason is
2297 specified anything other than above, the buffered requests for BMPS and WoWL
2298 will not be cleared.
2299 Note 2: Requesting full power (no matter what the fullPowerReason is) doesn't
2300 disable the "auto bmps timer" (if it is enabled) or clear any "buffered uapsd
2301 request".
2302 Note 3: When the device finally enters Full Power PMC will start a timer
2303 if any of the following holds true:
2304 - Auto BMPS mode is enabled
2305 - Uapsd request is pending
2306 - HDD's request for BMPS is pending
2307 - HDD's request for WoWL is pending
2308 On timer expiry PMC will attempt to put the device in BMPS mode if following
2309 (in addition to those listed above) holds true:
2310 - Polling of all modules through the Power Save Check routine passes
2311 - STA is associated to an access point
2312 \param hHal - The handle returned by macOpen.
2313 \param - enterWowlCallbackRoutine Callback routine invoked in case of success/failure
2314 \param - enterWowlCallbackContext - Cookie to be passed back during callback
2315 \param - wakeReasonIndCB Callback routine invoked for Wake Reason Indication
2316 \param - wakeReasonIndCBContext - Cookie to be passed back during callback
2317 \param - fullPowerReason - Reason why this API is being invoked. SME needs to
2318 distinguish between BAP and HDD requests
2319 \return eHalStatus - status
2320 eHAL_STATUS_SUCCESS - device brought to full power state
2321 eHAL_STATUS_FAILURE - device cannot be brought to full power state
2322 eHAL_STATUS_PMC_PENDING - device is being brought to full power state,
2323 ---------------------------------------------------------------------------*/
2324eHalStatus pmcEnterWowl (
2325 tHalHandle hHal,
2326 void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status),
2327 void *enterWowlCallbackContext,
2328#ifdef WLAN_WAKEUP_EVENTS
2329 void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd),
2330 void *wakeReasonIndCBContext,
2331#endif // WLAN_WAKEUP_EVENTS
2332 tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId)
2333{
2334 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2335 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2336
2337#ifdef FEATURE_WLAN_DIAG_SUPPORT
2338 WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type);
2339
2340 vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type));
2341 wowRequest.event_subtype = WLAN_WOW_ENTER_REQ;
2342 wowRequest.wow_type = 0;
2343
2344 if(wowlEnterParams->ucMagicPktEnable)
2345 {
2346 wowRequest.wow_type |= 1;
2347 vos_mem_copy(wowRequest.wow_magic_pattern, (tANI_U8 *)wowlEnterParams->magicPtrn, 6);
2348 }
2349
2350 if(wowlEnterParams->ucPatternFilteringEnable)
2351 {
2352 wowRequest.wow_type |= 2;
2353 }
2354 WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW);
2355#endif
2356
2357 smsLog(pMac, LOG2, FL("PMC: entering pmcEnterWowl"));
2358
2359 if( NULL == pSession )
2360 {
2361 smsLog(pMac, LOGE, FL("Session not found "));
2362 return eHAL_STATUS_FAILURE;
2363 }
2364
2365 vos_mem_copy(wowlEnterParams->bssId, pSession->connectedProfile.bssid,
2366 sizeof(tSirMacAddr));
2367
2368 if( !PMC_IS_READY(pMac) )
2369 {
2370 smsLog(pMac, LOGE, FL("Requesting WoWL when PMC not ready"));
2371 smsLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"),
2372 pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState));
2373 return eHAL_STATUS_FAILURE;
2374 }
2375
2376 /* Check if BMPS is enabled. */
2377 if (!pMac->pmc.bmpsEnabled)
2378 {
2379 smsLog(pMac, LOGE, "PMC: Cannot enter WoWL. BMPS is disabled");
2380 return eHAL_STATUS_PMC_DISABLED;
2381 }
2382
2383 /* Check if WoWL is enabled. */
2384 if (!pMac->pmc.wowlEnabled)
2385 {
2386 smsLog(pMac, LOGE, "PMC: Cannot enter WoWL. WoWL is disabled");
2387 return eHAL_STATUS_PMC_DISABLED;
2388 }
2389
2390 /* Check that we are associated with single Session. */
2391 if (!pmcValidateConnectState( pMac ))
2392 {
2393 smsLog(pMac, LOGE, "PMC: Cannot enable WOWL. STA not associated "
2394 "with an Access Point in Infra Mode with single active session");
2395 return eHAL_STATUS_FAILURE;
2396 }
2397
2398 /* Is there a pending UAPSD request? HDD should have triggered QoS
2399 module to do the necessary cleanup before triggring WOWL*/
2400 if(pMac->pmc.uapsdSessionRequired)
2401 {
2402 smsLog(pMac, LOGE, "PMC: Cannot request WOWL. Pending UAPSD request");
2403 return eHAL_STATUS_FAILURE;
2404 }
2405
2406 /* Check that entry into a power save mode is allowed at this time. */
2407 if (pMac->pmc.pmcState == FULL_POWER && !pmcPowerSaveCheck(hHal))
2408 {
2409 smsLog(pMac, LOGE, "PMC: Power save check failed. WOWL request "
2410 "will not be accepted");
2411 return eHAL_STATUS_FAILURE;
2412 }
2413
2414 // To avoid race condition, set callback routines before sending message.
2415 /* cache the WOWL information */
2416 pMac->pmc.wowlEnterParams = *wowlEnterParams;
2417 pMac->pmc.enterWowlCallbackRoutine = enterWowlCallbackRoutine;
2418 pMac->pmc.enterWowlCallbackContext = enterWowlCallbackContext;
2419#ifdef WLAN_WAKEUP_EVENTS
2420 /* Cache the Wake Reason Indication callback information */
2421 pMac->pmc.wakeReasonIndCB = wakeReasonIndCB;
2422 pMac->pmc.wakeReasonIndCBContext = wakeReasonIndCBContext;
2423#endif // WLAN_WAKEUP_EVENTS
2424
2425 /* Enter Request WOWL State. */
2426 if (pmcRequestEnterWowlState(hHal, wowlEnterParams) != eHAL_STATUS_SUCCESS)
2427 return eHAL_STATUS_FAILURE;
2428
2429 pMac->pmc.wowlModeRequired = TRUE;
2430
2431 return eHAL_STATUS_PMC_PENDING;
2432}
2433
2434/* ---------------------------------------------------------------------------
2435 \fn pmcExitWowl
2436 \brief This is the SME API exposed to HDD to request exit from WoWLAN mode.
2437 SME will initiate exit from WoWLAN mode and device will be put in BMPS
2438 mode.
2439 \param hHal - The handle returned by macOpen.
2440 \return eHalStatus
2441 eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode.
2442 eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode.
2443 ---------------------------------------------------------------------------*/
2444eHalStatus pmcExitWowl (tHalHandle hHal)
2445{
2446 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2447
2448#ifdef FEATURE_WLAN_DIAG_SUPPORT
2449 WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type);
2450
2451 vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type));
2452 wowRequest.event_subtype = WLAN_WOW_EXIT_REQ;
2453
2454 WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW);
2455#endif
2456
2457 smsLog(pMac, LOG2, "PMC: entering pmcExitWowl");
2458
2459 /* Clear any buffered command for entering WOWL */
2460 pMac->pmc.wowlModeRequired = FALSE;
2461
2462 /* Enter REQUEST_EXIT_WOWL State*/
2463 if (pmcRequestExitWowlState(hHal) != eHAL_STATUS_SUCCESS)
2464 return eHAL_STATUS_FAILURE;
2465
2466 /* Clear the callback routines */
2467 pMac->pmc.enterWowlCallbackRoutine = NULL;
2468 pMac->pmc.enterWowlCallbackContext = NULL;
2469
2470 return eHAL_STATUS_SUCCESS;
2471}
2472
2473
2474
2475/* ---------------------------------------------------------------------------
2476 \fn pmcSetHostOffload
2477 \brief Set the host offload feature.
2478 \param hHal - The handle returned by macOpen.
2479 \param pRequest - Pointer to the offload request.
2480 \return eHalStatus
2481 eHAL_STATUS_FAILURE Cannot set the offload.
2482 eHAL_STATUS_SUCCESS Request accepted.
2483 ---------------------------------------------------------------------------*/
2484eHalStatus pmcSetHostOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest,
2485 tANI_U8 sessionId)
2486{
2487 tpSirHostOffloadReq pRequestBuf;
2488 vos_msg_t msg;
2489 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2490 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2491
2492 VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: IP address = %d.%d.%d.%d", __func__,
2493 pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1],
2494 pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]);
2495
2496 if(NULL == pSession )
2497 {
2498 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: SESSION not Found\n", __func__);
2499 return eHAL_STATUS_FAILURE;
2500 }
2501
2502 pRequestBuf = vos_mem_malloc(sizeof(tSirHostOffloadReq));
2503 if (NULL == pRequestBuf)
2504 {
2505 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for host offload request", __func__);
2506 return eHAL_STATUS_FAILED_ALLOC;
2507 }
2508
2509 vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2510
2511 vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirHostOffloadReq));
2512
2513 msg.type = WDA_SET_HOST_OFFLOAD;
2514 msg.reserved = 0;
2515 msg.bodyptr = pRequestBuf;
2516 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
2517 {
2518 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_HOST_OFFLOAD message to WDA", __func__);
2519 vos_mem_free(pRequestBuf);
2520 return eHAL_STATUS_FAILURE;
2521 }
2522
2523 return eHAL_STATUS_SUCCESS;
2524}
2525
2526/* ---------------------------------------------------------------------------
2527 \fn pmcSetKeepAlive
2528 \brief Set the Keep Alive feature.
2529 \param hHal - The handle returned by macOpen.
2530 \param pRequest - Pointer to the Keep Alive.
2531 \return eHalStatus
2532 eHAL_STATUS_FAILURE Cannot set the keepalive.
2533 eHAL_STATUS_SUCCESS Request accepted.
2534 ---------------------------------------------------------------------------*/
2535eHalStatus pmcSetKeepAlive (tHalHandle hHal, tpSirKeepAliveReq pRequest, tANI_U8 sessionId)
2536{
2537 tpSirKeepAliveReq pRequestBuf;
2538 vos_msg_t msg;
2539 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2540 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2541
2542 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, "%s: "
2543 "WDA_SET_KEEP_ALIVE message", __func__);
2544
2545 if(pSession == NULL )
2546 {
2547 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
2548 " Session not Found", __func__);
2549 return eHAL_STATUS_FAILURE;
2550 }
2551 pRequestBuf = vos_mem_malloc(sizeof(tSirKeepAliveReq));
2552 if (NULL == pRequestBuf)
2553 {
2554 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
2555 "Not able to allocate memory for keep alive request",
2556 __func__);
2557 return eHAL_STATUS_FAILED_ALLOC;
2558 }
2559
2560 vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2561 vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirKeepAliveReq));
2562
2563 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, "buff TP %d "
2564 "input TP %d ", pRequestBuf->timePeriod, pRequest->timePeriod);
2565
2566 msg.type = WDA_SET_KEEP_ALIVE;
2567 msg.reserved = 0;
2568 msg.bodyptr = pRequestBuf;
2569 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
2570 {
2571 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
2572 "Not able to post WDA_SET_KEEP_ALIVE message to WDA",
2573 __func__);
2574 vos_mem_free(pRequestBuf);
2575 return eHAL_STATUS_FAILURE;
2576 }
2577
2578 return eHAL_STATUS_SUCCESS;
2579}
2580
2581
2582#ifdef WLAN_NS_OFFLOAD
2583
2584/* ---------------------------------------------------------------------------
2585 \fn pmcSetNSOffload
2586 \brief Set the host offload feature.
2587 \param hHal - The handle returned by macOpen.
2588 \param pRequest - Pointer to the offload request.
2589 \return eHalStatus
2590 eHAL_STATUS_FAILURE Cannot set the offload.
2591 eHAL_STATUS_SUCCESS Request accepted.
2592 ---------------------------------------------------------------------------*/
2593eHalStatus pmcSetNSOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest,
2594 tANI_U8 sessionId)
2595{
2596 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2597 tpSirHostOffloadReq pRequestBuf;
2598 vos_msg_t msg;
2599 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2600
2601 if( NULL == pSession )
2602 {
2603 smsLog(pMac, LOGE, FL("Session not found "));
2604 return eHAL_STATUS_FAILURE;
2605 }
2606
2607 vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid,
2608 sizeof(tSirMacAddr));
2609
2610 pRequestBuf = vos_mem_malloc(sizeof(tSirHostOffloadReq));
2611 if (NULL == pRequestBuf)
2612 {
2613 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for NS offload request", __func__);
2614 return eHAL_STATUS_FAILED_ALLOC;
2615 }
2616 vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirHostOffloadReq));
2617
2618 msg.type = WDA_SET_NS_OFFLOAD;
2619 msg.reserved = 0;
2620 msg.bodyptr = pRequestBuf;
2621 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
2622 {
2623 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post SIR_HAL_SET_HOST_OFFLOAD message to HAL", __func__);
2624 vos_mem_free(pRequestBuf);
2625 return eHAL_STATUS_FAILURE;
2626 }
2627
2628 return eHAL_STATUS_SUCCESS;
2629}
2630
2631#endif //WLAN_NS_OFFLOAD
2632
2633
2634void pmcClosePowerSaveCheckList(tpAniSirGlobal pMac)
2635{
2636 tListElem *pEntry;
2637 tpPowerSaveCheckEntry pPowerSaveCheckEntry;
2638
2639 csrLLLock(&pMac->pmc.powerSaveCheckList);
2640 while ( (pEntry = csrLLRemoveHead(&pMac->pmc.powerSaveCheckList, FALSE)) )
2641 {
2642 pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link);
2643 if (palFreeMemory(pMac->hHdd, pPowerSaveCheckEntry) != eHAL_STATUS_SUCCESS)
2644 {
2645 smsLog(pMac, LOGE, FL("Cannot free memory "));
2646 PMC_ABORT;
2647 break;
2648 }
2649 }
2650 csrLLUnlock(&pMac->pmc.powerSaveCheckList);
2651 csrLLClose(&pMac->pmc.powerSaveCheckList);
2652}
2653
2654
2655void pmcCloseRequestFullPowerList(tpAniSirGlobal pMac)
2656{
2657 tListElem *pEntry;
2658 tpRequestFullPowerEntry pRequestFullPowerEntry;
2659
2660 csrLLLock(&pMac->pmc.requestFullPowerList);
2661 while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestFullPowerList, FALSE)) )
2662 {
2663 pRequestFullPowerEntry = GET_BASE_ADDR(pEntry, tRequestFullPowerEntry, link);
2664 if (palFreeMemory(pMac->hHdd, pRequestFullPowerEntry) != eHAL_STATUS_SUCCESS)
2665 {
2666 smsLog(pMac, LOGE, FL("Cannot free memory "));
2667 PMC_ABORT;
2668 break;
2669 }
2670 }
2671 csrLLUnlock(&pMac->pmc.requestFullPowerList);
2672 csrLLClose(&pMac->pmc.requestFullPowerList);
2673}
2674
2675
2676void pmcCloseRequestBmpsList(tpAniSirGlobal pMac)
2677{
2678 tListElem *pEntry;
2679 tpRequestBmpsEntry pRequestBmpsEntry;
2680
2681 csrLLLock(&pMac->pmc.requestBmpsList);
2682 while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE)) )
2683 {
2684 pRequestBmpsEntry = GET_BASE_ADDR(pEntry, tRequestBmpsEntry, link);
2685 if (palFreeMemory(pMac->hHdd, pRequestBmpsEntry) != eHAL_STATUS_SUCCESS)
2686 {
2687 smsLog(pMac, LOGE, FL("Cannot free memory "));
2688 PMC_ABORT;
2689 break;
2690 }
2691 }
2692 csrLLUnlock(&pMac->pmc.requestBmpsList);
2693 csrLLClose(&pMac->pmc.requestBmpsList);
2694}
2695
2696
2697void pmcCloseRequestStartUapsdList(tpAniSirGlobal pMac)
2698{
2699 tListElem *pEntry;
2700 tpStartUapsdEntry pStartUapsdEntry;
2701
2702 csrLLLock(&pMac->pmc.requestStartUapsdList);
2703 while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE)) )
2704 {
2705 pStartUapsdEntry = GET_BASE_ADDR(pEntry, tStartUapsdEntry, link);
2706 if (palFreeMemory(pMac->hHdd, pStartUapsdEntry) != eHAL_STATUS_SUCCESS)
2707 {
2708 smsLog(pMac, LOGE, FL("Cannot free memory "));
2709 PMC_ABORT;
2710 break;
2711 }
2712 }
2713 csrLLUnlock(&pMac->pmc.requestStartUapsdList);
2714 csrLLClose(&pMac->pmc.requestStartUapsdList);
2715}
2716
2717
2718void pmcCloseDeviceStateUpdateList(tpAniSirGlobal pMac)
2719{
2720 tListElem *pEntry;
2721 tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry;
2722
2723 csrLLLock(&pMac->pmc.deviceStateUpdateIndList);
2724 while ( (pEntry = csrLLRemoveHead(&pMac->pmc.deviceStateUpdateIndList, FALSE)) )
2725 {
2726 pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link);
2727 if (palFreeMemory(pMac->hHdd, pDeviceStateUpdateIndEntry) != eHAL_STATUS_SUCCESS)
2728 {
2729 smsLog(pMac, LOGE, FL("Cannot free memory "));
2730 PMC_ABORT;
2731 break;
2732 }
2733 }
2734 csrLLUnlock(&pMac->pmc.deviceStateUpdateIndList);
2735 csrLLClose(&pMac->pmc.deviceStateUpdateIndList);
2736}
2737
2738
2739void pmcCloseDeferredMsgList(tpAniSirGlobal pMac)
2740{
2741 tListElem *pEntry;
2742 tPmcDeferredMsg *pDeferredMsg;
2743
2744 csrLLLock(&pMac->pmc.deferredMsgList);
2745 while ( (pEntry = csrLLRemoveHead(&pMac->pmc.deferredMsgList, FALSE)) )
2746 {
2747 pDeferredMsg = GET_BASE_ADDR(pEntry, tPmcDeferredMsg, link);
2748 if (palFreeMemory(pMac->hHdd, pDeferredMsg) != eHAL_STATUS_SUCCESS)
2749 {
2750 smsLog(pMac, LOGE, FL("Cannot free memory "));
2751 PMC_ABORT;
2752 break;
2753 }
2754 }
2755 csrLLUnlock(&pMac->pmc.deferredMsgList);
2756 csrLLClose(&pMac->pmc.deferredMsgList);
2757}
2758
2759
2760#ifdef FEATURE_WLAN_SCAN_PNO
2761
2762static tSirRetStatus
2763pmcPopulateMacHeader( tpAniSirGlobal pMac,
2764 tANI_U8* pBD,
2765 tANI_U8 type,
2766 tANI_U8 subType,
2767 tSirMacAddr peerAddr ,
2768 tSirMacAddr selfMacAddr)
2769{
2770 tSirRetStatus statusCode = eSIR_SUCCESS;
2771 tpSirMacMgmtHdr pMacHdr;
2772
2773 /// Prepare MAC management header
2774 pMacHdr = (tpSirMacMgmtHdr) (pBD);
2775
2776 // Prepare FC
2777 pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
2778 pMacHdr->fc.type = type;
2779 pMacHdr->fc.subType = subType;
2780
2781 // Prepare Address 1
2782 palCopyMemory( pMac->hHdd,
2783 (tANI_U8 *) pMacHdr->da,
2784 (tANI_U8 *) peerAddr,
2785 sizeof( tSirMacAddr ));
2786
2787 sirCopyMacAddr(pMacHdr->sa,selfMacAddr);
2788
2789 // Prepare Address 3
2790 palCopyMemory( pMac->hHdd,
2791 (tANI_U8 *) pMacHdr->bssId,
2792 (tANI_U8 *) peerAddr,
2793 sizeof( tSirMacAddr ));
2794 return statusCode;
2795} /*** pmcPopulateMacHeader() ***/
2796
2797
2798static tSirRetStatus
2799pmcPrepareProbeReqTemplate(tpAniSirGlobal pMac,
2800 tANI_U8 nChannelNum,
2801 tANI_U32 dot11mode,
2802 tSirMacAddr selfMacAddr,
2803 tANI_U8 *pFrame,
2804 tANI_U16 *pusLen)
2805{
2806 tDot11fProbeRequest pr;
2807 tANI_U32 nStatus, nBytes, nPayload;
2808 tSirRetStatus nSirStatus;
2809 /*Bcast tx*/
2810 tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2811 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2812
2813 // The scheme here is to fill out a 'tDot11fProbeRequest' structure
2814 // and then hand it off to 'dot11fPackProbeRequest' (for
2815 // serialization). We start by zero-initializing the structure:
2816 palZeroMemory( pMac->hHdd, ( tANI_U8* )&pr, sizeof( pr ) );
2817
2818 PopulateDot11fSuppRates( pMac, nChannelNum, &pr.SuppRates,NULL);
2819
2820 if ( WNI_CFG_DOT11_MODE_11B != dot11mode )
2821 {
2822 PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates );
2823 }
2824
2825
2826 if (IS_DOT11_MODE_HT(dot11mode))
2827 {
2828 PopulateDot11fHTCaps( pMac, NULL, &pr.HTCaps );
2829 }
2830
2831 // That's it-- now we pack it. First, how much space are we going to
2832 // need?
2833 nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload );
2834 if ( DOT11F_FAILED( nStatus ) )
2835 {
2836 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2837 "Failed to calculate the packed size f"
2838 "or a Probe Request (0x%08x).", nStatus );
2839
2840 // We'll fall back on the worst case scenario:
2841 nPayload = sizeof( tDot11fProbeRequest );
2842 }
2843 else if ( DOT11F_WARNED( nStatus ) )
2844 {
2845 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2846 "There were warnings while calculating"
2847 "the packed size for a Probe Request ("
2848 "0x%08x).", nStatus );
2849 }
2850
2851 nBytes = nPayload + sizeof( tSirMacMgmtHdr );
2852
2853 /* Prepare outgoing frame*/
2854 palZeroMemory( pMac->hHdd, pFrame, nBytes );
2855
2856 // Next, we fill out the buffer descriptor:
2857 nSirStatus = pmcPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME,
2858 SIR_MAC_MGMT_PROBE_REQ, bssId ,selfMacAddr);
2859
2860 if ( eSIR_SUCCESS != nSirStatus )
2861 {
2862 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2863 "Failed to populate the buffer descriptor for a Probe Request (%d).",
2864 nSirStatus );
2865 return nSirStatus; // allocated!
2866 }
2867
2868 // That done, pack the Probe Request:
2869 nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame +
2870 sizeof( tSirMacMgmtHdr ),
2871 nPayload, &nPayload );
2872 if ( DOT11F_FAILED( nStatus ) )
2873 {
2874 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2875 "Failed to pack a Probe Request (0x%08x).", nStatus );
2876 return eSIR_FAILURE; // allocated!
2877 }
2878 else if ( DOT11F_WARNED( nStatus ) )
2879 {
2880 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
2881 "There were warnings while packing a Probe Request" );
2882 }
2883
2884 *pusLen = nPayload + sizeof(tSirMacMgmtHdr);
2885 return eSIR_SUCCESS;
2886} // End pmcPrepareProbeReqTemplate.
2887
2888
2889eHalStatus pmcSetPreferredNetworkList
2890(
2891 tHalHandle hHal,
2892 tpSirPNOScanReq pRequest,
2893 tANI_U8 sessionId,
2894 preferredNetworkFoundIndCallback callbackRoutine,
2895 void *callbackContext
2896)
2897{
2898 tpSirPNOScanReq pRequestBuf;
2899 vos_msg_t msg;
2900 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2901 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
2902 tANI_U8 ucDot11Mode;
2903
2904 VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
2905 "%s: SSID = 0x%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx, "
2906 "0x%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx", __func__,
2907 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[0]),
2908 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[4]),
2909 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[8]),
2910 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[12]),
2911 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[16]),
2912 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[20]),
2913 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[24]),
2914 *((v_U32_t *) &pRequest->aNetworks[0].ssId.ssId[28]),
2915 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[0]),
2916 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[4]),
2917 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[8]),
2918 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[12]),
2919 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[16]),
2920 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[20]),
2921 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[24]),
2922 *((v_U32_t *) &pRequest->aNetworks[1].ssId.ssId[28]));
2923
2924
2925 pRequestBuf = vos_mem_malloc(sizeof(tSirPNOScanReq));
2926 if (NULL == pRequestBuf)
2927 {
2928 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for PNO request", __func__);
2929 return eHAL_STATUS_FAILED_ALLOC;
2930 }
2931
2932 vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirPNOScanReq));
2933
2934 /*Must translate the mode first*/
2935 ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac,
2936 csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode ));
2937
2938 /*Prepare a probe request for 2.4GHz band and one for 5GHz band*/
2939 pmcPrepareProbeReqTemplate(pMac,SIR_PNO_24G_DEFAULT_CH, ucDot11Mode, pSession->selfMacAddr,
2940 pRequestBuf->p24GProbeTemplate, &pRequestBuf->us24GProbeTemplateLen);
2941
2942 pmcPrepareProbeReqTemplate(pMac,SIR_PNO_5G_DEFAULT_CH, ucDot11Mode, pSession->selfMacAddr,
2943 pRequestBuf->p5GProbeTemplate, &pRequestBuf->us5GProbeTemplateLen);
2944
2945
2946 msg.type = WDA_SET_PNO_REQ;
2947 msg.reserved = 0;
2948 msg.bodyptr = pRequestBuf;
2949 if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
2950 {
2951 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_PNO_REQ message to WDA", __func__);
2952 vos_mem_free(pRequestBuf);
2953 return eHAL_STATUS_FAILURE;
2954 }
2955
2956 /* Cache the Preferred Network Found Indication callback information */
2957 pMac->pmc.prefNetwFoundCB = callbackRoutine;
2958 pMac->pmc.preferredNetworkFoundIndCallbackContext = callbackContext;
2959
2960 VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "-%s", __func__);
2961
2962 return eHAL_STATUS_SUCCESS;
2963}
2964
2965eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold)
2966{
2967 tpSirSetRSSIFilterReq pRequestBuf;
2968 vos_msg_t msg;
2969
2970
2971 pRequestBuf = vos_mem_malloc(sizeof(tpSirSetRSSIFilterReq));
2972 if (NULL == pRequestBuf)
2973 {
2974 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for PNO request", __func__);
2975 return eHAL_STATUS_FAILED_ALLOC;
2976 }
2977
2978
2979 pRequestBuf->rssiThreshold = rssiThreshold;
2980
2981 msg.type = WDA_SET_RSSI_FILTER_REQ;
2982 msg.reserved = 0;
2983 msg.bodyptr = pRequestBuf;
2984 if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
2985 {
2986 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_PNO_REQ message to WDA", __func__);
2987 vos_mem_free(pRequestBuf);
2988 return eHAL_STATUS_FAILURE;
2989 }
2990
2991 return eHAL_STATUS_SUCCESS;
2992}
2993
2994
2995eHalStatus pmcUpdateScanParams(tHalHandle hHal, tCsrConfig *pRequest, tCsrChannel *pChannelList, tANI_U8 b11dResolved)
2996{
2997 tpSirUpdateScanParams pRequestBuf;
2998 vos_msg_t msg;
2999 int i;
3000
3001 VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s started", __func__);
3002
3003 pRequestBuf = vos_mem_malloc(sizeof(tSirUpdateScanParams));
3004 if (NULL == pRequestBuf)
3005 {
3006 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for UpdateScanParams request", __func__);
3007 return eHAL_STATUS_FAILED_ALLOC;
3008 }
3009
3010 //
3011 // Fill pRequestBuf structure from pRequest
3012 //
3013 pRequestBuf->b11dEnabled = pRequest->Is11eSupportEnabled;
3014 pRequestBuf->b11dResolved = b11dResolved;
3015 pRequestBuf->ucChannelCount =
3016 ( pChannelList->numChannels < SIR_PNO_MAX_NETW_CHANNELS_EX )?
3017 pChannelList->numChannels:SIR_PNO_MAX_NETW_CHANNELS_EX;
3018
3019 for (i=0; i < pRequestBuf->ucChannelCount; i++)
3020 {
3021 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
3022 "%s: Channel List %d: %d", __FUNCTION__, i, pChannelList->channelList[i] );
3023
3024 pRequestBuf->aChannels[i] = pChannelList->channelList[i];
3025 }
3026 pRequestBuf->usPassiveMinChTime = pRequest->nPassiveMinChnTime;
3027 pRequestBuf->usPassiveMaxChTime = pRequest->nPassiveMaxChnTime;
3028 pRequestBuf->usActiveMinChTime = pRequest->nActiveMinChnTime;
3029 pRequestBuf->usActiveMaxChTime = pRequest->nActiveMaxChnTime;
3030 pRequestBuf->ucCBState = PHY_SINGLE_CHANNEL_CENTERED;
3031
3032 msg.type = WDA_UPDATE_SCAN_PARAMS_REQ;
3033 msg.reserved = 0;
3034 msg.bodyptr = pRequestBuf;
3035 if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
3036 {
3037 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_UPDATE_SCAN_PARAMS message to WDA", __func__);
3038 vos_mem_free(pRequestBuf);
3039 return eHAL_STATUS_FAILURE;
3040 }
3041
3042 return eHAL_STATUS_SUCCESS;
3043}
3044#endif // FEATURE_WLAN_SCAN_PNO
3045
3046eHalStatus pmcSetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced)
3047{
3048 tSirSetPowerParamsReq* pRequestBuf;
3049 vos_msg_t msg;
3050 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3051 tpPESession psessionEntry;
3052
3053 psessionEntry = peGetValidPowerSaveSession(pMac);
3054 if (!forced && (psessionEntry == NULL))
3055 {
3056 return eHAL_STATUS_NOT_INITIALIZED;
3057 }
3058
3059 pRequestBuf = vos_mem_malloc(sizeof(tSirSetPowerParamsReq));
3060 if (NULL == pRequestBuf)
3061 {
3062 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for Power Paramrequest", __func__);
3063 return eHAL_STATUS_FAILED_ALLOC;
3064 }
3065
3066
3067 vos_mem_copy(pRequestBuf, pwParams, sizeof(*pRequestBuf));
3068
3069
3070 msg.type = WDA_SET_POWER_PARAMS_REQ;
3071 msg.reserved = 0;
3072 msg.bodyptr = pRequestBuf;
3073
3074 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
3075 {
3076 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_POWER_PARAMS_REQ message to WDA", __func__);
3077 vos_mem_free(pRequestBuf);
3078 return eHAL_STATUS_FAILURE;
3079 }
3080
3081 return eHAL_STATUS_SUCCESS;
3082}
3083
3084#ifdef WLAN_FEATURE_PACKET_FILTERING
3085eHalStatus pmcGetFilterMatchCount
3086(
3087 tHalHandle hHal,
3088 FilterMatchCountCallback callbackRoutine,
3089 void *callbackContext,
3090 tANI_U8 sessionId
3091)
3092{
3093 tpSirRcvFltPktMatchRsp pRequestBuf;
3094 vos_msg_t msg;
3095 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3096 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
3097
3098 VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
3099 "%s", __func__);
3100
3101 if(NULL == pSession )
3102 {
3103 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3104 "%s: Session not found ", __func__);
3105 return eHAL_STATUS_FAILURE;
3106 }
3107
3108 pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltPktMatchRsp));
3109 if (NULL == pRequestBuf)
3110 {
3111 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3112 "%s: Not able to allocate "
3113 "memory for Get PC Filter Match Count request", __func__);
3114 return eHAL_STATUS_FAILED_ALLOC;
3115 }
3116
3117 vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
3118
3119 msg.type = WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ;
3120 msg.reserved = 0;
3121 msg.bodyptr = pRequestBuf;
3122
3123 /* Cache the Packet Coalescing Filter Match Count callback information */
3124 if (NULL != pMac->pmc.FilterMatchCountCB)
3125 {
3126 // Do we need to check if the callback is in use?
3127 // Because we are not sending the same message again when it is pending,
3128 // the only case when the callback is not NULL is that the previous message
3129 //was timed out or failed.
3130 // So, it will be safe to set the callback in this case.
3131 }
3132
3133 pMac->pmc.FilterMatchCountCB = callbackRoutine;
3134 pMac->pmc.FilterMatchCountCBContext = callbackContext;
3135
3136 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
3137 {
3138 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3139 "%s: Not able to post WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ "
3140 "message to WDA", __func__);
3141 vos_mem_free(pRequestBuf);
3142 return eHAL_STATUS_FAILURE;
3143 }
3144
3145 return eHAL_STATUS_SUCCESS;
3146}
3147#endif // WLAN_FEATURE_PACKET_FILTERING
3148
3149#ifdef WLAN_FEATURE_GTK_OFFLOAD
3150/* ---------------------------------------------------------------------------
3151 \fn pmcSetGTKOffload
3152 \brief Set GTK offload feature.
3153 \param hHal - The handle returned by macOpen.
3154 \param pGtkOffload - Pointer to the GTK offload request.
3155 \return eHalStatus
3156 eHAL_STATUS_FAILURE Cannot set the offload.
3157 eHAL_STATUS_SUCCESS Request accepted.
3158 ---------------------------------------------------------------------------*/
3159eHalStatus pmcSetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pGtkOffload,
3160 tANI_U8 sessionId)
3161{
3162 tpSirGtkOffloadParams pRequestBuf;
3163 vos_msg_t msg;
3164 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3165 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
3166
3167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: KeyReplayCounter: %d",
3168 __func__, pGtkOffload->ullKeyReplayCounter);
3169
3170 if(NULL == pSession )
3171 {
3172 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3173 "%s: Session not found ", __func__);
3174 return eHAL_STATUS_FAILURE;
3175 }
3176
3177 pRequestBuf = (tpSirGtkOffloadParams)vos_mem_malloc(sizeof(tSirGtkOffloadParams));
3178 if (NULL == pRequestBuf)
3179 {
3180 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate "
3181 "memory for GTK offload request", __func__);
3182 return eHAL_STATUS_FAILED_ALLOC;
3183 }
3184
3185 vos_mem_copy(pGtkOffload->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
3186
3187 vos_mem_copy(pRequestBuf, pGtkOffload, sizeof(tSirGtkOffloadParams));
3188
3189 msg.type = WDA_GTK_OFFLOAD_REQ;
3190 msg.reserved = 0;
3191 msg.bodyptr = pRequestBuf;
3192 if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
3193 {
3194 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post "
3195 "SIR_HAL_SET_GTK_OFFLOAD message to HAL", __func__);
3196 vos_mem_free(pRequestBuf);
3197 return eHAL_STATUS_FAILURE;
3198 }
3199
3200 return eHAL_STATUS_SUCCESS;
3201}
3202
3203/* ---------------------------------------------------------------------------
3204 \fn pmcGetGTKOffload
3205 \brief Get GTK offload information.
3206 \param hHal - The handle returned by macOpen.
3207 \param callbackRoutine - Pointer to the GTK Offload Get Info response callback routine.
3208 \return eHalStatus
3209 eHAL_STATUS_FAILURE Cannot set the offload.
3210 eHAL_STATUS_SUCCESS Request accepted.
3211 ---------------------------------------------------------------------------*/
3212eHalStatus pmcGetGTKOffload(tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine,
3213 void *callbackContext, tANI_U8 sessionId)
3214{
3215 tpSirGtkOffloadGetInfoRspParams pRequestBuf;
3216 vos_msg_t msg;
3217 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3218 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
3219
3220 VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterId = %d",
3221 __func__);
3222
3223 if(NULL == pSession )
3224 {
3225 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
3226 "%s: Session not found ", __func__);
3227 return eHAL_STATUS_FAILURE;
3228 }
3229
3230 pRequestBuf = (tpSirGtkOffloadGetInfoRspParams)
3231 vos_mem_malloc(sizeof (tSirGtkOffloadGetInfoRspParams));
3232 if (NULL == pRequestBuf)
3233 {
3234 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate "
3235 "memory for Get GTK offload request", __func__);
3236 return eHAL_STATUS_FAILED_ALLOC;
3237 }
3238
3239 vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
3240
3241 msg.type = WDA_GTK_OFFLOAD_GETINFO_REQ;
3242 msg.reserved = 0;
3243 msg.bodyptr = pRequestBuf;
3244
3245 /* Cache the Get GTK Offload callback information */
3246 if (NULL != pMac->pmc.GtkOffloadGetInfoCB)
3247 {
3248 // Do we need to check if the callback is in use?
3249 // Because we are not sending the same message again when it is pending,
3250 // the only case when the callback is not NULL is that the previous message was timed out or failed.
3251 // So, it will be safe to set the callback in this case.
3252 }
3253
3254 pMac->pmc.GtkOffloadGetInfoCB = callbackRoutine;
3255 pMac->pmc.GtkOffloadGetInfoCBContext = callbackContext;
3256
3257 if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)))
3258 {
3259 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_GTK_OFFLOAD_GETINFO_REQ message to WDA",
3260 __func__);
3261 vos_mem_free(pRequestBuf);
3262 return eHAL_STATUS_FAILURE;
3263 }
3264
3265 return eHAL_STATUS_SUCCESS;
3266}
3267#endif // WLAN_FEATURE_GTK_OFFLOAD
3268
3269v_BOOL_t IsPmcImpsReqFailed (tHalHandle hHal)
3270{
3271 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3272 v_BOOL_t impsReqFailStatus;
3273
3274 impsReqFailStatus = (pMac->pmc.ImpsReqFailed || pMac->pmc.ImpsReqTimerFailed);
3275
3276 return impsReqFailStatus;
3277
3278}
3279
3280void pmcResetImpsFailStatus (tHalHandle hHal)
3281{
3282 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3283 pMac->pmc.ImpsReqFailed = VOS_FALSE;
3284 pMac->pmc.ImpsReqTimerFailed = VOS_FALSE;
3285}