Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[linux-2.6] / drivers / staging / otus / 80211core / cpsmgr.c
1 /*
2  * Copyright (c) 2007-2008 Atheros Communications Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /**
18   *  The power saving manager is to save the power as much as possible.
19   *  Generally speaking, it controls:
20   *
21   *         - when to sleep
22   *         -
23   *
24   */
25 #include "cprecomp.h"
26
27 void zfPowerSavingMgrInit(zdev_t* dev)
28 {
29     zmw_get_wlan_dev(dev);
30
31     wd->sta.powerSaveMode = ZM_STA_PS_NONE;
32     wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
33     wd->sta.psMgr.isSleepAllowed = 0;
34     wd->sta.psMgr.maxSleepPeriods = 1;
35     wd->sta.psMgr.ticks = 0;
36     wd->sta.psMgr.sleepAllowedtick = 0;
37 }
38
39 static u16_t zfPowerSavingMgrHandlePsNone(zdev_t* dev, u8_t *isWakeUpRequired)
40 {
41     u16_t ret = 0;
42     zmw_get_wlan_dev(dev);
43
44     switch(wd->sta.psMgr.state)
45     {
46         case ZM_PS_MSG_STATE_ACTIVE:
47             *isWakeUpRequired = 0;
48             break;
49
50         case ZM_PS_MSG_STATE_T1:
51         case ZM_PS_MSG_STATE_T2:
52         case ZM_PS_MSG_STATE_SLEEP:
53         default:
54             *isWakeUpRequired = 1;
55 zm_debug_msg0("zfPowerSavingMgrHandlePsNone: Wake up now\n");
56             if ( zfStaIsConnected(dev) )
57             {
58                 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
59                 //zfSendNullData(dev, 0);
60                 ret = 1;
61             }
62
63             wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
64             break;
65     }
66     return ret;
67 }
68
69 static void zfPowerSavingMgrHandlePs(zdev_t* dev)
70 {
71     zmw_get_wlan_dev(dev);
72
73     switch(wd->sta.psMgr.state)
74     {
75         case ZM_PS_MSG_STATE_ACTIVE:
76             //zm_debug_msg0("zfPowerSavingMgrHandlePs: Prepare to sleep...\n");
77             //wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
78             break;
79
80         case ZM_PS_MSG_STATE_T1:
81         case ZM_PS_MSG_STATE_T2:
82         case ZM_PS_MSG_STATE_SLEEP:
83         default:
84             break;
85     }
86 }
87
88 void zfPowerSavingMgrSetMode(zdev_t* dev, u8_t mode)
89 {
90     u16_t sendNull = 0;
91     u8_t isWakeUpRequired = 0;
92
93     zmw_get_wlan_dev(dev);
94     zmw_declare_for_critical_section();
95
96     zm_debug_msg1("mode = ", mode);
97
98     if (mode > ZM_STA_PS_LIGHT)
99     {
100         zm_debug_msg0("return - wrong power save mode");
101         return;
102     }
103
104     zmw_enter_critical_section(dev);
105
106     #if 1
107     switch(mode)
108     {
109         case ZM_STA_PS_NONE:
110             sendNull = zfPowerSavingMgrHandlePsNone(dev, &isWakeUpRequired);
111             break;
112
113         case ZM_STA_PS_FAST:
114         case ZM_STA_PS_LIGHT:
115             wd->sta.psMgr.maxSleepPeriods = 1;
116             zfPowerSavingMgrHandlePs(dev);
117             break;
118
119         case ZM_STA_PS_MAX:
120             wd->sta.psMgr.maxSleepPeriods = ZM_PS_MAX_SLEEP_PERIODS;
121             zfPowerSavingMgrHandlePs(dev);
122             break;
123     }
124     #else
125     switch(wd->sta.psMgr.state)
126     {
127         case ZM_PS_MSG_STATE_ACTIVE:
128             if ( mode != ZM_STA_PS_NONE )
129             {
130 zm_debug_msg0("zfPowerSavingMgrSetMode: switch from ZM_PS_MSG_STATE_ACTIVE to ZM_PS_MSG_STATE_T1\n");
131                 // Stall the TX & start to wait the pending TX to be completed
132                 wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
133             }
134             break;
135
136         case ZM_PS_MSG_STATE_SLEEP:
137             break;
138     }
139     #endif
140
141     wd->sta.powerSaveMode = mode;
142     zmw_leave_critical_section(dev);
143
144     if ( isWakeUpRequired )
145     {
146         zfHpPowerSaveSetState(dev, 0);
147         wd->sta.psMgr.tempWakeUp = 0;
148     }
149
150     if ( zfStaIsConnected(dev)
151          && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
152     {
153         switch(mode)
154         {
155             case ZM_STA_PS_NONE:
156                 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
157                 break;
158
159             case ZM_STA_PS_FAST:
160             case ZM_STA_PS_MAX:
161             case ZM_STA_PS_LIGHT:
162                 zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
163                 break;
164
165             default:
166                 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
167                 break;
168         }
169     }
170
171     if (sendNull == 1)
172     {
173         zfSendNullData(dev, 0);
174     }
175
176     return;
177 }
178
179 static void zfPowerSavingMgrNotifyPSToAP(zdev_t *dev)
180 {
181     zmw_get_wlan_dev(dev);
182     zmw_declare_for_critical_section();
183
184     if ( (wd->sta.psMgr.tempWakeUp != 1)&&
185          (wd->sta.psMgr.lastTxUnicastFrm != wd->commTally.txUnicastFrm ||
186           wd->sta.psMgr.lastTxBroadcastFrm != wd->commTally.txBroadcastFrm ||
187           wd->sta.psMgr.lastTxMulticastFrm != wd->commTally.txMulticastFrm) )
188     {
189         zmw_enter_critical_section(dev);
190         wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
191         wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
192         wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
193         zmw_leave_critical_section(dev);
194
195         zfSendNullData(dev, 1);
196     }
197 }
198
199 static void zfPowerSavingMgrOnHandleT1(zdev_t* dev)
200 {
201     zmw_get_wlan_dev(dev);
202     zmw_declare_for_critical_section();
203
204     // If the tx Q is not empty...return
205     if ( zfIsVtxqEmpty(dev) == FALSE )
206     {
207         return;
208     }
209
210 zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n");
211
212     // The the HAL TX Q is not empty...return
213     if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
214     {
215         return;
216     }
217
218 zm_debug_msg0("HAL TXQ is empty now...Could go to sleep...\n");
219
220     zmw_enter_critical_section(dev);
221
222     if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
223     {
224         if (wd->sta.ReceivedPktRatePerSecond > 200)
225         {
226             zmw_leave_critical_section(dev);
227             return;
228         }
229
230         if ( zfStaIsConnected(dev)
231              && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
232         {
233             if (wd->sta.psMgr.sleepAllowedtick) {
234                 wd->sta.psMgr.sleepAllowedtick--;
235                 zmw_leave_critical_section(dev);
236                 return;
237             }
238         }
239     }
240
241     wd->sta.psMgr.state = ZM_PS_MSG_STATE_T2;
242
243     zmw_leave_critical_section(dev);
244
245     // Send the Null pkt to AP to notify that I'm going to sleep
246     if ( zfStaIsConnected(dev) )
247     {
248 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
249         zfPowerSavingMgrNotifyPSToAP(dev);
250     }
251
252     // Stall the TX now
253     // zfTxEngineStop(dev);
254 }
255
256 static void zfPowerSavingMgrOnHandleT2(zdev_t* dev)
257 {
258     zmw_get_wlan_dev(dev);
259     zmw_declare_for_critical_section();
260
261     // Wait until the Null pkt is transmitted
262     if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
263     {
264         return;
265     }
266
267     zmw_enter_critical_section(dev);
268     wd->sta.psMgr.state = ZM_PS_MSG_STATE_SLEEP;
269     wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
270     wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
271     wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
272     zmw_leave_critical_section(dev);
273
274     // Let CHIP sleep now
275 zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n");
276     zfHpPowerSaveSetState(dev, 1);
277     wd->sta.psMgr.tempWakeUp = 0;
278 }
279
280 u8_t zfPowerSavingMgrIsSleeping(zdev_t *dev)
281 {
282     u8_t isSleeping = FALSE;
283     zmw_get_wlan_dev(dev);
284     zmw_declare_for_critical_section();
285
286     zmw_enter_critical_section(dev);
287     if ( wd->sta.psMgr.state == ZM_PS_MSG_STATE_SLEEP ||
288          wd->sta.psMgr.state == ZM_PS_MSG_STATE_T2)
289     {
290         isSleeping = TRUE;
291     }
292     zmw_leave_critical_section(dev);
293     return isSleeping;
294 }
295
296 static u8_t zfPowerSavingMgrIsIdle(zdev_t *dev)
297 {
298     u8_t isIdle = 0;
299
300     zmw_get_wlan_dev(dev);
301     zmw_declare_for_critical_section();
302
303     zmw_enter_critical_section(dev);
304
305     if ( zfStaIsConnected(dev) && wd->sta.psMgr.isSleepAllowed == 0 )
306     {
307         goto done;
308     }
309
310     if ( wd->sta.bChannelScan )
311     {
312         goto done;
313     }
314
315     if ( zfStaIsConnecting(dev) )
316     {
317         goto done;
318     }
319
320     if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
321     {
322         if (wd->sta.ReceivedPktRatePerSecond > 200)
323         {
324             goto done;
325         }
326
327         if ( zfStaIsConnected(dev)
328              && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
329         {
330             if (wd->sta.psMgr.sleepAllowedtick) {
331                 wd->sta.psMgr.sleepAllowedtick--;
332                 goto done;
333             }
334         }
335     }
336
337     isIdle = 1;
338
339 done:
340     zmw_leave_critical_section(dev);
341
342     if ( zfIsVtxqEmpty(dev) == FALSE )
343     {
344         isIdle = 0;
345     }
346
347     return isIdle;
348 }
349
350 static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev)
351 {
352     u8_t isIdle;
353
354     zmw_get_wlan_dev(dev);
355     zmw_declare_for_critical_section();
356
357     isIdle = zfPowerSavingMgrIsIdle(dev);
358
359     if ( isIdle == 0 )
360     {
361         return;
362     }
363
364     zmw_enter_critical_section(dev);
365
366     switch(wd->sta.powerSaveMode)
367     {
368         case ZM_STA_PS_NONE:
369             break;
370
371         case ZM_STA_PS_MAX:
372         case ZM_STA_PS_FAST:
373         case ZM_STA_PS_LIGHT:
374             zm_debug_msg0("zfPowerSavingMgrSleepIfIdle: IDLE so slep now...\n");
375             wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
376             break;
377     }
378
379     zmw_leave_critical_section(dev);
380 }
381
382 static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
383 {
384     zmw_get_wlan_dev(dev);
385
386 #ifdef ZM_ENABLE_DISCONNECT_PS
387     switch(wd->sta.psMgr.state)
388     {
389         case ZM_PS_MSG_STATE_ACTIVE:
390             zfPowerSavingMgrSleepIfIdle(dev);
391             break;
392
393         case ZM_PS_MSG_STATE_SLEEP:
394             break;
395
396         case ZM_PS_MSG_STATE_T1:
397             zfPowerSavingMgrOnHandleT1(dev);
398             break;
399
400         case ZM_PS_MSG_STATE_T2:
401             zfPowerSavingMgrOnHandleT2(dev);
402             break;
403     }
404 #else
405     zfPowerSavingMgrWakeup(dev);
406 #endif
407 }
408
409 static void zfPowerSavingMgrInfraMain(zdev_t* dev)
410 {
411     zmw_get_wlan_dev(dev);
412
413     switch(wd->sta.psMgr.state)
414     {
415         case ZM_PS_MSG_STATE_ACTIVE:
416             zfPowerSavingMgrSleepIfIdle(dev);
417             break;
418
419         case ZM_PS_MSG_STATE_SLEEP:
420             break;
421
422         case ZM_PS_MSG_STATE_T1:
423             zfPowerSavingMgrOnHandleT1(dev);
424             break;
425
426         case ZM_PS_MSG_STATE_T2:
427             zfPowerSavingMgrOnHandleT2(dev);
428             break;
429     }
430 }
431
432 void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
433 {
434     zmw_get_wlan_dev(dev);
435
436 //printk("zfPowerSavingMgrAtimWinExpired #1\n");
437     if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
438     {
439         return;
440     }
441
442 //printk("zfPowerSavingMgrAtimWinExpired #2\n");
443     // if we received any ATIM window from the others to indicate we have buffered data
444     // at the other station, we can't go to sleep
445     if ( wd->sta.recvAtim )
446     {
447         wd->sta.recvAtim = 0;
448         zm_debug_msg0("Can't sleep due to receving ATIM window!");
449         return;
450     }
451
452     // if we are the one to tx beacon during last beacon interval. we can't go to sleep
453     // since we need to be alive to respond the probe request!
454     if ( wd->sta.txBeaconInd )
455     {
456         zm_debug_msg0("Can't sleep due to just transmit a beacon!");
457         return;
458     }
459
460     // If we buffer any data for the other stations. we could not go to sleep
461     if ( wd->sta.ibssPrevPSDataCount != 0 )
462     {
463         zm_debug_msg0("Can't sleep due to buffering data for the others!");
464         return;
465     }
466
467     // before sleeping, we still need to notify the others by transmitting null
468     // pkt with power mgmt bit turned on.
469     zfPowerSavingMgrOnHandleT1(dev);
470 }
471
472 static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
473 {
474     // wait for the end of
475     // if need to wait to know if we are the one to transmit the beacon
476     // during the beacon interval. If it's me, we can't go to sleep.
477
478     zmw_get_wlan_dev(dev);
479
480     switch(wd->sta.psMgr.state)
481     {
482         case ZM_PS_MSG_STATE_ACTIVE:
483         case ZM_PS_MSG_STATE_SLEEP:
484         case ZM_PS_MSG_STATE_T1:
485             break;
486
487         case ZM_PS_MSG_STATE_T2:
488             zfPowerSavingMgrOnHandleT2(dev);
489             break;
490     }
491
492     return;
493 }
494
495 #if 1
496 void zfPowerSavingMgrMain(zdev_t* dev)
497 {
498     zmw_get_wlan_dev(dev);
499
500     switch (wd->sta.adapterState)
501     {
502     case ZM_STA_STATE_DISCONNECT:
503         zfPowerSavingMgrDisconnectMain(dev);
504         break;
505     case ZM_STA_STATE_CONNECTED:
506         {
507             if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) {
508                 zfPowerSavingMgrInfraMain(dev);
509             } else if (wd->wlanMode == ZM_MODE_IBSS) {
510                 zfPowerSavingMgrIBSSMain(dev);
511             }
512         }
513         break;
514     case ZM_STA_STATE_CONNECTING:
515     default:
516         break;
517     }
518 }
519 #else
520 void zfPowerSavingMgrMain(zdev_t* dev)
521 {
522     zmw_get_wlan_dev(dev);
523
524     if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
525     {
526         return;
527     }
528
529     switch(wd->sta.psMgr.state)
530     {
531         case ZM_PS_MSG_STATE_ACTIVE:
532             goto check_sleep;
533             break;
534
535         case ZM_PS_MSG_STATE_SLEEP:
536             goto sleeping;
537             break;
538
539         case ZM_PS_MSG_STATE_T1:
540             zfPowerSavingMgrOnHandleT1(dev);
541             break;
542
543         case ZM_PS_MSG_STATE_T2:
544             zfPowerSavingMgrOnHandleT2(dev);
545             break;
546     }
547
548     return;
549
550 sleeping:
551     return;
552
553 check_sleep:
554     zfPowerSavingMgrSleepIfIdle(dev);
555     return;
556 }
557 #endif
558
559 #ifdef ZM_ENABLE_POWER_SAVE
560 void zfPowerSavingMgrWakeup(zdev_t* dev)
561 {
562     zmw_get_wlan_dev(dev);
563     zmw_declare_for_critical_section();
564
565 //zm_debug_msg0("zfPowerSavingMgrWakeup");
566
567     //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE && ( zfPowerSavingMgrIsIdle(dev) == 0 ))
568     if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE )
569     {
570         zmw_enter_critical_section(dev);
571
572         wd->sta.psMgr.isSleepAllowed = 0;
573         wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
574
575         if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
576             wd->sta.psMgr.tempWakeUp = 1;
577
578         zmw_leave_critical_section(dev);
579
580         // Wake up the CHIP now!!
581         zfHpPowerSaveSetState(dev, 0);
582     }
583 }
584 #else
585 void zfPowerSavingMgrWakeup(zdev_t* dev)
586 {
587 }
588 #endif
589
590 void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf)
591 {
592     u8_t   length, bitmap;
593     u16_t  offset, n1, n2, q, r;
594     zbuf_t* psBuf;
595
596     zmw_get_wlan_dev(dev);
597     zmw_declare_for_critical_section();
598
599     if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE  )
600     //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
601     {
602         return;
603     }
604
605     wd->sta.psMgr.isSleepAllowed = 1;
606
607     if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_TIM)) != 0xffff )
608     {
609         length = zmw_rx_buf_readb(dev, buf, offset+1);
610
611         if ( length > 3 )
612         {
613             n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0);
614             n2 = length + n1 - 4;
615             q = wd->sta.aid >> 3;
616             r = wd->sta.aid & 7;
617
618             if ((q >= n1) && (q <= n2))
619             {
620                 bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1);
621
622                 if ( (bitmap >> r) &  ZM_BIT_0 )
623                 {
624                     //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
625                     if ( 0 )
626                     {
627                         wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
628                         //zfSendPSPoll(dev);
629                         zfSendNullData(dev, 0);
630                     }
631                     else
632                     {
633                         if ((wd->sta.qosInfo&0xf) != 0xf)
634                         {
635                             /* send ps-poll */
636                             //printk("zfSendPSPoll #1\n");
637
638                             wd->sta.psMgr.isSleepAllowed = 0;
639
640                             switch (wd->sta.powerSaveMode)
641                             {
642                             case ZM_STA_PS_MAX:
643                             case ZM_STA_PS_FAST:
644                                 //zm_debug_msg0("wake up and send PS-Poll\n");
645                                 zfSendPSPoll(dev);
646                                 break;
647                             case ZM_STA_PS_LIGHT:
648                                 zm_debug_msg0("wake up and send null data\n");
649
650                                 zmw_enter_critical_section(dev);
651                                 wd->sta.psMgr.sleepAllowedtick = 400;
652                                 zmw_leave_critical_section(dev);
653
654                                 zfSendNullData(dev, 0);
655                                 break;
656                             }
657
658                             wd->sta.psMgr.tempWakeUp = 0;
659                         }
660                     }
661                 }
662             }
663         }
664     }
665
666     while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL)
667     {
668         zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
669     }
670
671     //printk("zfPowerSavingMgrProcessBeacon #1\n");
672     zfPowerSavingMgrMain(dev);
673 }
674
675 void zfPowerSavingMgrConnectNotify(zdev_t *dev)
676 {
677     zmw_get_wlan_dev(dev);
678
679     if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
680     {
681         switch(wd->sta.powerSaveMode)
682         {
683             case ZM_STA_PS_NONE:
684                 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
685                 break;
686
687             case ZM_STA_PS_FAST:
688             case ZM_STA_PS_MAX:
689             case ZM_STA_PS_LIGHT:
690                 zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
691                 break;
692
693             default:
694                 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
695                 break;
696         }
697     }
698 }
699
700 void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
701 {
702     zmw_get_wlan_dev(dev);
703     zmw_declare_for_critical_section();
704
705     /* disable TBTT interrupt when change from connection to disconnect */
706     if (zfStaIsDisconnect(dev)) {
707         zfHpPowerSaveSetMode(dev, 0, 0, 0);
708         zfPowerSavingMgrWakeup(dev);
709         return;
710     }
711
712     zmw_enter_critical_section(dev);
713     wd->sta.psMgr.ticks++;
714
715     if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods )
716     {
717         zmw_leave_critical_section(dev);
718         return;
719     }
720     else
721     {
722         wd->sta.psMgr.ticks = 0;
723     }
724
725     zmw_leave_critical_section(dev);
726
727     zfPowerSavingMgrWakeup(dev);
728 }
729
730 /* Leave an empty line below to remove warning message on some compiler */
731