aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/otus/80211core/cpsmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/otus/80211core/cpsmgr.c')
-rw-r--r--drivers/staging/otus/80211core/cpsmgr.c731
1 files changed, 731 insertions, 0 deletions
diff --git a/drivers/staging/otus/80211core/cpsmgr.c b/drivers/staging/otus/80211core/cpsmgr.c
new file mode 100644
index 000000000000..cf73caca8e52
--- /dev/null
+++ b/drivers/staging/otus/80211core/cpsmgr.c
@@ -0,0 +1,731 @@
+/*
+ * Copyright (c) 2007-2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * The power saving manager is to save the power as much as possible.
+ * Generally speaking, it controls:
+ *
+ * - when to sleep
+ * -
+ *
+ */
+#include "cprecomp.h"
+
+void zfPowerSavingMgrInit(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+ wd->sta.powerSaveMode = ZM_STA_PS_NONE;
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
+ wd->sta.psMgr.isSleepAllowed = 0;
+ wd->sta.psMgr.maxSleepPeriods = 1;
+ wd->sta.psMgr.ticks = 0;
+ wd->sta.psMgr.sleepAllowedtick = 0;
+}
+
+static u16_t zfPowerSavingMgrHandlePsNone(zdev_t* dev, u8_t *isWakeUpRequired)
+{
+ u16_t ret = 0;
+ zmw_get_wlan_dev(dev);
+
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ *isWakeUpRequired = 0;
+ break;
+
+ case ZM_PS_MSG_STATE_T1:
+ case ZM_PS_MSG_STATE_T2:
+ case ZM_PS_MSG_STATE_SLEEP:
+ default:
+ *isWakeUpRequired = 1;
+zm_debug_msg0("zfPowerSavingMgrHandlePsNone: Wake up now\n");
+ if ( zfStaIsConnected(dev) )
+ {
+ zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
+ //zfSendNullData(dev, 0);
+ ret = 1;
+ }
+
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
+ break;
+ }
+ return ret;
+}
+
+static void zfPowerSavingMgrHandlePs(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ //zm_debug_msg0("zfPowerSavingMgrHandlePs: Prepare to sleep...\n");
+ //wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
+ break;
+
+ case ZM_PS_MSG_STATE_T1:
+ case ZM_PS_MSG_STATE_T2:
+ case ZM_PS_MSG_STATE_SLEEP:
+ default:
+ break;
+ }
+}
+
+void zfPowerSavingMgrSetMode(zdev_t* dev, u8_t mode)
+{
+ u16_t sendNull = 0;
+ u8_t isWakeUpRequired = 0;
+
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ zm_debug_msg1("mode = ", mode);
+
+ if (mode > ZM_STA_PS_LIGHT)
+ {
+ zm_debug_msg0("return - wrong power save mode");
+ return;
+ }
+
+ zmw_enter_critical_section(dev);
+
+ #if 1
+ switch(mode)
+ {
+ case ZM_STA_PS_NONE:
+ sendNull = zfPowerSavingMgrHandlePsNone(dev, &isWakeUpRequired);
+ break;
+
+ case ZM_STA_PS_FAST:
+ case ZM_STA_PS_LIGHT:
+ wd->sta.psMgr.maxSleepPeriods = 1;
+ zfPowerSavingMgrHandlePs(dev);
+ break;
+
+ case ZM_STA_PS_MAX:
+ wd->sta.psMgr.maxSleepPeriods = ZM_PS_MAX_SLEEP_PERIODS;
+ zfPowerSavingMgrHandlePs(dev);
+ break;
+ }
+ #else
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ if ( mode != ZM_STA_PS_NONE )
+ {
+zm_debug_msg0("zfPowerSavingMgrSetMode: switch from ZM_PS_MSG_STATE_ACTIVE to ZM_PS_MSG_STATE_T1\n");
+ // Stall the TX & start to wait the pending TX to be completed
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
+ }
+ break;
+
+ case ZM_PS_MSG_STATE_SLEEP:
+ break;
+ }
+ #endif
+
+ wd->sta.powerSaveMode = mode;
+ zmw_leave_critical_section(dev);
+
+ if ( isWakeUpRequired )
+ {
+ zfHpPowerSaveSetState(dev, 0);
+ wd->sta.psMgr.tempWakeUp = 0;
+ }
+
+ if ( zfStaIsConnected(dev)
+ && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
+ {
+ switch(mode)
+ {
+ case ZM_STA_PS_NONE:
+ zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
+ break;
+
+ case ZM_STA_PS_FAST:
+ case ZM_STA_PS_MAX:
+ case ZM_STA_PS_LIGHT:
+ zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
+ break;
+
+ default:
+ zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
+ break;
+ }
+ }
+
+ if (sendNull == 1)
+ {
+ zfSendNullData(dev, 0);
+ }
+
+ return;
+}
+
+static void zfPowerSavingMgrNotifyPSToAP(zdev_t *dev)
+{
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ if ( (wd->sta.psMgr.tempWakeUp != 1)&&
+ (wd->sta.psMgr.lastTxUnicastFrm != wd->commTally.txUnicastFrm ||
+ wd->sta.psMgr.lastTxBroadcastFrm != wd->commTally.txBroadcastFrm ||
+ wd->sta.psMgr.lastTxMulticastFrm != wd->commTally.txMulticastFrm) )
+ {
+ zmw_enter_critical_section(dev);
+ wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
+ wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
+ wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
+ zmw_leave_critical_section(dev);
+
+ zfSendNullData(dev, 1);
+ }
+}
+
+static void zfPowerSavingMgrOnHandleT1(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ // If the tx Q is not empty...return
+ if ( zfIsVtxqEmpty(dev) == FALSE )
+ {
+ return;
+ }
+
+zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n");
+
+ // The the HAL TX Q is not empty...return
+ if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
+ {
+ return;
+ }
+
+zm_debug_msg0("HAL TXQ is empty now...Could go to sleep...\n");
+
+ zmw_enter_critical_section(dev);
+
+ if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
+ {
+ if (wd->sta.ReceivedPktRatePerSecond > 200)
+ {
+ zmw_leave_critical_section(dev);
+ return;
+ }
+
+ if ( zfStaIsConnected(dev)
+ && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
+ {
+ if (wd->sta.psMgr.sleepAllowedtick) {
+ wd->sta.psMgr.sleepAllowedtick--;
+ zmw_leave_critical_section(dev);
+ return;
+ }
+ }
+ }
+
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_T2;
+
+ zmw_leave_critical_section(dev);
+
+ // Send the Null pkt to AP to notify that I'm going to sleep
+ if ( zfStaIsConnected(dev) )
+ {
+zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
+ zfPowerSavingMgrNotifyPSToAP(dev);
+ }
+
+ // Stall the TX now
+ // zfTxEngineStop(dev);
+}
+
+static void zfPowerSavingMgrOnHandleT2(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ // Wait until the Null pkt is transmitted
+ if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
+ {
+ return;
+ }
+
+ zmw_enter_critical_section(dev);
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_SLEEP;
+ wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
+ wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
+ wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
+ zmw_leave_critical_section(dev);
+
+ // Let CHIP sleep now
+zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n");
+ zfHpPowerSaveSetState(dev, 1);
+ wd->sta.psMgr.tempWakeUp = 0;
+}
+
+u8_t zfPowerSavingMgrIsSleeping(zdev_t *dev)
+{
+ u8_t isSleeping = FALSE;
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ zmw_enter_critical_section(dev);
+ if ( wd->sta.psMgr.state == ZM_PS_MSG_STATE_SLEEP ||
+ wd->sta.psMgr.state == ZM_PS_MSG_STATE_T2)
+ {
+ isSleeping = TRUE;
+ }
+ zmw_leave_critical_section(dev);
+ return isSleeping;
+}
+
+static u8_t zfPowerSavingMgrIsIdle(zdev_t *dev)
+{
+ u8_t isIdle = 0;
+
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ zmw_enter_critical_section(dev);
+
+ if ( zfStaIsConnected(dev) && wd->sta.psMgr.isSleepAllowed == 0 )
+ {
+ goto done;
+ }
+
+ if ( wd->sta.bChannelScan )
+ {
+ goto done;
+ }
+
+ if ( zfStaIsConnecting(dev) )
+ {
+ goto done;
+ }
+
+ if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
+ {
+ if (wd->sta.ReceivedPktRatePerSecond > 200)
+ {
+ goto done;
+ }
+
+ if ( zfStaIsConnected(dev)
+ && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
+ {
+ if (wd->sta.psMgr.sleepAllowedtick) {
+ wd->sta.psMgr.sleepAllowedtick--;
+ goto done;
+ }
+ }
+ }
+
+ isIdle = 1;
+
+done:
+ zmw_leave_critical_section(dev);
+
+ if ( zfIsVtxqEmpty(dev) == FALSE )
+ {
+ isIdle = 0;
+ }
+
+ return isIdle;
+}
+
+static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev)
+{
+ u8_t isIdle;
+
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ isIdle = zfPowerSavingMgrIsIdle(dev);
+
+ if ( isIdle == 0 )
+ {
+ return;
+ }
+
+ zmw_enter_critical_section(dev);
+
+ switch(wd->sta.powerSaveMode)
+ {
+ case ZM_STA_PS_NONE:
+ break;
+
+ case ZM_STA_PS_MAX:
+ case ZM_STA_PS_FAST:
+ case ZM_STA_PS_LIGHT:
+ zm_debug_msg0("zfPowerSavingMgrSleepIfIdle: IDLE so slep now...\n");
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
+ break;
+ }
+
+ zmw_leave_critical_section(dev);
+}
+
+static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+#ifdef ZM_ENABLE_DISCONNECT_PS
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ zfPowerSavingMgrSleepIfIdle(dev);
+ break;
+
+ case ZM_PS_MSG_STATE_SLEEP:
+ break;
+
+ case ZM_PS_MSG_STATE_T1:
+ zfPowerSavingMgrOnHandleT1(dev);
+ break;
+
+ case ZM_PS_MSG_STATE_T2:
+ zfPowerSavingMgrOnHandleT2(dev);
+ break;
+ }
+#else
+ zfPowerSavingMgrWakeup(dev);
+#endif
+}
+
+static void zfPowerSavingMgrInfraMain(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ zfPowerSavingMgrSleepIfIdle(dev);
+ break;
+
+ case ZM_PS_MSG_STATE_SLEEP:
+ break;
+
+ case ZM_PS_MSG_STATE_T1:
+ zfPowerSavingMgrOnHandleT1(dev);
+ break;
+
+ case ZM_PS_MSG_STATE_T2:
+ zfPowerSavingMgrOnHandleT2(dev);
+ break;
+ }
+}
+
+void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+//printk("zfPowerSavingMgrAtimWinExpired #1\n");
+ if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
+ {
+ return;
+ }
+
+//printk("zfPowerSavingMgrAtimWinExpired #2\n");
+ // if we received any ATIM window from the others to indicate we have buffered data
+ // at the other station, we can't go to sleep
+ if ( wd->sta.recvAtim )
+ {
+ wd->sta.recvAtim = 0;
+ zm_debug_msg0("Can't sleep due to receving ATIM window!");
+ return;
+ }
+
+ // if we are the one to tx beacon during last beacon interval. we can't go to sleep
+ // since we need to be alive to respond the probe request!
+ if ( wd->sta.txBeaconInd )
+ {
+ zm_debug_msg0("Can't sleep due to just transmit a beacon!");
+ return;
+ }
+
+ // If we buffer any data for the other stations. we could not go to sleep
+ if ( wd->sta.ibssPrevPSDataCount != 0 )
+ {
+ zm_debug_msg0("Can't sleep due to buffering data for the others!");
+ return;
+ }
+
+ // before sleeping, we still need to notify the others by transmitting null
+ // pkt with power mgmt bit turned on.
+ zfPowerSavingMgrOnHandleT1(dev);
+}
+
+static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
+{
+ // wait for the end of
+ // if need to wait to know if we are the one to transmit the beacon
+ // during the beacon interval. If it's me, we can't go to sleep.
+
+ zmw_get_wlan_dev(dev);
+
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ case ZM_PS_MSG_STATE_SLEEP:
+ case ZM_PS_MSG_STATE_T1:
+ break;
+
+ case ZM_PS_MSG_STATE_T2:
+ zfPowerSavingMgrOnHandleT2(dev);
+ break;
+ }
+
+ return;
+}
+
+#if 1
+void zfPowerSavingMgrMain(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+ switch (wd->sta.adapterState)
+ {
+ case ZM_STA_STATE_DISCONNECT:
+ zfPowerSavingMgrDisconnectMain(dev);
+ break;
+ case ZM_STA_STATE_CONNECTED:
+ {
+ if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) {
+ zfPowerSavingMgrInfraMain(dev);
+ } else if (wd->wlanMode == ZM_MODE_IBSS) {
+ zfPowerSavingMgrIBSSMain(dev);
+ }
+ }
+ break;
+ case ZM_STA_STATE_CONNECTING:
+ default:
+ break;
+ }
+}
+#else
+void zfPowerSavingMgrMain(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+
+ if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
+ {
+ return;
+ }
+
+ switch(wd->sta.psMgr.state)
+ {
+ case ZM_PS_MSG_STATE_ACTIVE:
+ goto check_sleep;
+ break;
+
+ case ZM_PS_MSG_STATE_SLEEP:
+ goto sleeping;
+ break;
+
+ case ZM_PS_MSG_STATE_T1:
+ zfPowerSavingMgrOnHandleT1(dev);
+ break;
+
+ case ZM_PS_MSG_STATE_T2:
+ zfPowerSavingMgrOnHandleT2(dev);
+ break;
+ }
+
+ return;
+
+sleeping:
+ return;
+
+check_sleep:
+ zfPowerSavingMgrSleepIfIdle(dev);
+ return;
+}
+#endif
+
+#ifdef ZM_ENABLE_POWER_SAVE
+void zfPowerSavingMgrWakeup(zdev_t* dev)
+{
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+//zm_debug_msg0("zfPowerSavingMgrWakeup");
+
+ //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE && ( zfPowerSavingMgrIsIdle(dev) == 0 ))
+ if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE )
+ {
+ zmw_enter_critical_section(dev);
+
+ wd->sta.psMgr.isSleepAllowed = 0;
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
+
+ if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
+ wd->sta.psMgr.tempWakeUp = 1;
+
+ zmw_leave_critical_section(dev);
+
+ // Wake up the CHIP now!!
+ zfHpPowerSaveSetState(dev, 0);
+ }
+}
+#else
+void zfPowerSavingMgrWakeup(zdev_t* dev)
+{
+}
+#endif
+
+void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf)
+{
+ u8_t length, bitmap;
+ u16_t offset, n1, n2, q, r;
+ zbuf_t* psBuf;
+
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
+ //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
+ {
+ return;
+ }
+
+ wd->sta.psMgr.isSleepAllowed = 1;
+
+ if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_TIM)) != 0xffff )
+ {
+ length = zmw_rx_buf_readb(dev, buf, offset+1);
+
+ if ( length > 3 )
+ {
+ n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0);
+ n2 = length + n1 - 4;
+ q = wd->sta.aid >> 3;
+ r = wd->sta.aid & 7;
+
+ if ((q >= n1) && (q <= n2))
+ {
+ bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1);
+
+ if ( (bitmap >> r) & ZM_BIT_0 )
+ {
+ //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
+ if ( 0 )
+ {
+ wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
+ //zfSendPSPoll(dev);
+ zfSendNullData(dev, 0);
+ }
+ else
+ {
+ if ((wd->sta.qosInfo&0xf) != 0xf)
+ {
+ /* send ps-poll */
+ //printk("zfSendPSPoll #1\n");
+
+ wd->sta.psMgr.isSleepAllowed = 0;
+
+ switch (wd->sta.powerSaveMode)
+ {
+ case ZM_STA_PS_MAX:
+ case ZM_STA_PS_FAST:
+ //zm_debug_msg0("wake up and send PS-Poll\n");
+ zfSendPSPoll(dev);
+ break;
+ case ZM_STA_PS_LIGHT:
+ zm_debug_msg0("wake up and send null data\n");
+
+ zmw_enter_critical_section(dev);
+ wd->sta.psMgr.sleepAllowedtick = 400;
+ zmw_leave_critical_section(dev);
+
+ zfSendNullData(dev, 0);
+ break;
+ }
+
+ wd->sta.psMgr.tempWakeUp = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL)
+ {
+ zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
+ }
+
+ //printk("zfPowerSavingMgrProcessBeacon #1\n");
+ zfPowerSavingMgrMain(dev);
+}
+
+void zfPowerSavingMgrConnectNotify(zdev_t *dev)
+{
+ zmw_get_wlan_dev(dev);
+
+ if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
+ {
+ switch(wd->sta.powerSaveMode)
+ {
+ case ZM_STA_PS_NONE:
+ zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
+ break;
+
+ case ZM_STA_PS_FAST:
+ case ZM_STA_PS_MAX:
+ case ZM_STA_PS_LIGHT:
+ zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
+ break;
+
+ default:
+ zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
+ break;
+ }
+ }
+}
+
+void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
+{
+ zmw_get_wlan_dev(dev);
+ zmw_declare_for_critical_section();
+
+ /* disable TBTT interrupt when change from connection to disconnect */
+ if (zfStaIsDisconnect(dev)) {
+ zfHpPowerSaveSetMode(dev, 0, 0, 0);
+ zfPowerSavingMgrWakeup(dev);
+ return;
+ }
+
+ zmw_enter_critical_section(dev);
+ wd->sta.psMgr.ticks++;
+
+ if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods )
+ {
+ zmw_leave_critical_section(dev);
+ return;
+ }
+ else
+ {
+ wd->sta.psMgr.ticks = 0;
+ }
+
+ zmw_leave_critical_section(dev);
+
+ zfPowerSavingMgrWakeup(dev);
+}
+
+/* Leave an empty line below to remove warning message on some compiler */
+