Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / 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 #ifdef ZM_ENABLE_DISCONNECT_PS
385 switch(wd->sta.psMgr.state)
386 {
387 case ZM_PS_MSG_STATE_ACTIVE:
388 zfPowerSavingMgrSleepIfIdle(dev);
389 break;
390
391 case ZM_PS_MSG_STATE_SLEEP:
392 break;
393
394 case ZM_PS_MSG_STATE_T1:
395 zfPowerSavingMgrOnHandleT1(dev);
396 break;
397
398 case ZM_PS_MSG_STATE_T2:
399 zfPowerSavingMgrOnHandleT2(dev);
400 break;
401 }
402 #else
403 zfPowerSavingMgrWakeup(dev);
404 #endif
405 }
406
407 static void zfPowerSavingMgrInfraMain(zdev_t* dev)
408 {
409 zmw_get_wlan_dev(dev);
410
411 switch(wd->sta.psMgr.state)
412 {
413 case ZM_PS_MSG_STATE_ACTIVE:
414 zfPowerSavingMgrSleepIfIdle(dev);
415 break;
416
417 case ZM_PS_MSG_STATE_SLEEP:
418 break;
419
420 case ZM_PS_MSG_STATE_T1:
421 zfPowerSavingMgrOnHandleT1(dev);
422 break;
423
424 case ZM_PS_MSG_STATE_T2:
425 zfPowerSavingMgrOnHandleT2(dev);
426 break;
427 }
428 }
429
430 void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
431 {
432 zmw_get_wlan_dev(dev);
433
434 //printk("zfPowerSavingMgrAtimWinExpired #1\n");
435 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
436 {
437 return;
438 }
439
440 //printk("zfPowerSavingMgrAtimWinExpired #2\n");
441 // if we received any ATIM window from the others to indicate we have buffered data
442 // at the other station, we can't go to sleep
443 if ( wd->sta.recvAtim )
444 {
445 wd->sta.recvAtim = 0;
446 zm_debug_msg0("Can't sleep due to receving ATIM window!");
447 return;
448 }
449
450 // if we are the one to tx beacon during last beacon interval. we can't go to sleep
451 // since we need to be alive to respond the probe request!
452 if ( wd->sta.txBeaconInd )
453 {
454 zm_debug_msg0("Can't sleep due to just transmit a beacon!");
455 return;
456 }
457
458 // If we buffer any data for the other stations. we could not go to sleep
459 if ( wd->sta.ibssPrevPSDataCount != 0 )
460 {
461 zm_debug_msg0("Can't sleep due to buffering data for the others!");
462 return;
463 }
464
465 // before sleeping, we still need to notify the others by transmitting null
466 // pkt with power mgmt bit turned on.
467 zfPowerSavingMgrOnHandleT1(dev);
468 }
469
470 static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
471 {
472 // wait for the end of
473 // if need to wait to know if we are the one to transmit the beacon
474 // during the beacon interval. If it's me, we can't go to sleep.
475
476 zmw_get_wlan_dev(dev);
477
478 switch(wd->sta.psMgr.state)
479 {
480 case ZM_PS_MSG_STATE_ACTIVE:
481 case ZM_PS_MSG_STATE_SLEEP:
482 case ZM_PS_MSG_STATE_T1:
483 break;
484
485 case ZM_PS_MSG_STATE_T2:
486 zfPowerSavingMgrOnHandleT2(dev);
487 break;
488 }
489
490 return;
491 }
492
493 #if 1
494 void zfPowerSavingMgrMain(zdev_t* dev)
495 {
496 zmw_get_wlan_dev(dev);
497
498 switch (wd->sta.adapterState)
499 {
500 case ZM_STA_STATE_DISCONNECT:
501 zfPowerSavingMgrDisconnectMain(dev);
502 break;
503 case ZM_STA_STATE_CONNECTED:
504 {
505 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) {
506 zfPowerSavingMgrInfraMain(dev);
507 } else if (wd->wlanMode == ZM_MODE_IBSS) {
508 zfPowerSavingMgrIBSSMain(dev);
509 }
510 }
511 break;
512 case ZM_STA_STATE_CONNECTING:
513 default:
514 break;
515 }
516 }
517 #else
518 void zfPowerSavingMgrMain(zdev_t* dev)
519 {
520 zmw_get_wlan_dev(dev);
521
522 if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
523 {
524 return;
525 }
526
527 switch(wd->sta.psMgr.state)
528 {
529 case ZM_PS_MSG_STATE_ACTIVE:
530 goto check_sleep;
531 break;
532
533 case ZM_PS_MSG_STATE_SLEEP:
534 goto sleeping;
535 break;
536
537 case ZM_PS_MSG_STATE_T1:
538 zfPowerSavingMgrOnHandleT1(dev);
539 break;
540
541 case ZM_PS_MSG_STATE_T2:
542 zfPowerSavingMgrOnHandleT2(dev);
543 break;
544 }
545
546 return;
547
548 sleeping:
549 return;
550
551 check_sleep:
552 zfPowerSavingMgrSleepIfIdle(dev);
553 return;
554 }
555 #endif
556
557 #ifdef ZM_ENABLE_POWER_SAVE
558 void zfPowerSavingMgrWakeup(zdev_t* dev)
559 {
560 zmw_get_wlan_dev(dev);
561 zmw_declare_for_critical_section();
562
563 //zm_debug_msg0("zfPowerSavingMgrWakeup");
564
565 //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE && ( zfPowerSavingMgrIsIdle(dev) == 0 ))
566 if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE )
567 {
568 zmw_enter_critical_section(dev);
569
570 wd->sta.psMgr.isSleepAllowed = 0;
571 wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
572
573 if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
574 wd->sta.psMgr.tempWakeUp = 1;
575
576 zmw_leave_critical_section(dev);
577
578 // Wake up the CHIP now!!
579 zfHpPowerSaveSetState(dev, 0);
580 }
581 }
582 #else
583 void zfPowerSavingMgrWakeup(zdev_t* dev)
584 {
585 }
586 #endif
587
588 void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf)
589 {
590 u8_t length, bitmap;
591 u16_t offset, n1, n2, q, r;
592 zbuf_t* psBuf;
593
594 zmw_get_wlan_dev(dev);
595 zmw_declare_for_critical_section();
596
597 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
598 //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
599 {
600 return;
601 }
602
603 wd->sta.psMgr.isSleepAllowed = 1;
604
605 offset = zfFindElement(dev, buf, ZM_WLAN_EID_TIM);
606 if (offset != 0xffff)
607 {
608 length = zmw_rx_buf_readb(dev, buf, offset+1);
609
610 if ( length > 3 )
611 {
612 n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0);
613 n2 = length + n1 - 4;
614 q = wd->sta.aid >> 3;
615 r = wd->sta.aid & 7;
616
617 if ((q >= n1) && (q <= n2))
618 {
619 bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1);
620
621 if ( (bitmap >> r) & ZM_BIT_0 )
622 {
623 //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
624 if ( 0 )
625 {
626 wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
627 //zfSendPSPoll(dev);
628 zfSendNullData(dev, 0);
629 }
630 else
631 {
632 if ((wd->sta.qosInfo&0xf) != 0xf)
633 {
634 /* send ps-poll */
635 //printk("zfSendPSPoll #1\n");
636
637 wd->sta.psMgr.isSleepAllowed = 0;
638
639 switch (wd->sta.powerSaveMode)
640 {
641 case ZM_STA_PS_MAX:
642 case ZM_STA_PS_FAST:
643 //zm_debug_msg0("wake up and send PS-Poll\n");
644 zfSendPSPoll(dev);
645 break;
646 case ZM_STA_PS_LIGHT:
647 zm_debug_msg0("wake up and send null data\n");
648
649 zmw_enter_critical_section(dev);
650 wd->sta.psMgr.sleepAllowedtick = 400;
651 zmw_leave_critical_section(dev);
652
653 zfSendNullData(dev, 0);
654 break;
655 }
656
657 wd->sta.psMgr.tempWakeUp = 0;
658 }
659 }
660 }
661 }
662 }
663 }
664
665 while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL)
666 {
667 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
668 }
669
670 //printk("zfPowerSavingMgrProcessBeacon #1\n");
671 zfPowerSavingMgrMain(dev);
672 }
673
674 void zfPowerSavingMgrConnectNotify(zdev_t *dev)
675 {
676 zmw_get_wlan_dev(dev);
677
678 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
679 {
680 switch(wd->sta.powerSaveMode)
681 {
682 case ZM_STA_PS_NONE:
683 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
684 break;
685
686 case ZM_STA_PS_FAST:
687 case ZM_STA_PS_MAX:
688 case ZM_STA_PS_LIGHT:
689 zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
690 break;
691
692 default:
693 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
694 break;
695 }
696 }
697 }
698
699 void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
700 {
701 zmw_get_wlan_dev(dev);
702 zmw_declare_for_critical_section();
703
704 /* disable TBTT interrupt when change from connection to disconnect */
705 if (zfStaIsDisconnect(dev)) {
706 zfHpPowerSaveSetMode(dev, 0, 0, 0);
707 zfPowerSavingMgrWakeup(dev);
708 return;
709 }
710
711 zmw_enter_critical_section(dev);
712 wd->sta.psMgr.ticks++;
713
714 if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods )
715 {
716 zmw_leave_critical_section(dev);
717 return;
718 }
719 else
720 {
721 wd->sta.psMgr.ticks = 0;
722 }
723
724 zmw_leave_critical_section(dev);
725
726 zfPowerSavingMgrWakeup(dev);
727 }
728
729 /* Leave an empty line below to remove warning message on some compiler */
730