1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "cprecomp.h"
26
27void 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
39static 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;
55zm_debug_msg0("zfPowerSavingMgrHandlePsNone: Wake up now\n");
56 if ( zfStaIsConnected(dev) )
57 {
58 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
59
60 ret = 1;
61 }
62
63 wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
64 break;
65 }
66 return ret;
67}
68
69static 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
77
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
88void 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 {
130zm_debug_msg0("zfPowerSavingMgrSetMode: switch from ZM_PS_MSG_STATE_ACTIVE to ZM_PS_MSG_STATE_T1\n");
131
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
179static 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
199static void zfPowerSavingMgrOnHandleT1(zdev_t* dev)
200{
201 zmw_get_wlan_dev(dev);
202 zmw_declare_for_critical_section();
203
204
205 if ( zfIsVtxqEmpty(dev) == FALSE )
206 {
207 return;
208 }
209
210zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n");
211
212
213 if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
214 {
215 return;
216 }
217
218zm_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
246 if ( zfStaIsConnected(dev) )
247 {
248zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
249 zfPowerSavingMgrNotifyPSToAP(dev);
250 }
251
252
253
254}
255
256static void zfPowerSavingMgrOnHandleT2(zdev_t* dev)
257{
258 zmw_get_wlan_dev(dev);
259 zmw_declare_for_critical_section();
260
261
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
275zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n");
276 zfHpPowerSaveSetState(dev, 1);
277 wd->sta.psMgr.tempWakeUp = 0;
278}
279
280u8_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
296static 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
339done:
340 zmw_leave_critical_section(dev);
341
342 if ( zfIsVtxqEmpty(dev) == FALSE )
343 {
344 isIdle = 0;
345 }
346
347 return isIdle;
348}
349
350static 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
382static 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
409static 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
432void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
433{
434 zmw_get_wlan_dev(dev);
435
436
437 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
438 {
439 return;
440 }
441
442
443
444
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
453
454 if ( wd->sta.txBeaconInd )
455 {
456 zm_debug_msg0("Can't sleep due to just transmit a beacon!");
457 return;
458 }
459
460
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
468
469 zfPowerSavingMgrOnHandleT1(dev);
470}
471
472static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
473{
474
475
476
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
496void 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
520void 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
550sleeping:
551 return;
552
553check_sleep:
554 zfPowerSavingMgrSleepIfIdle(dev);
555 return;
556}
557#endif
558
559#ifdef ZM_ENABLE_POWER_SAVE
560void zfPowerSavingMgrWakeup(zdev_t* dev)
561{
562 zmw_get_wlan_dev(dev);
563 zmw_declare_for_critical_section();
564
565
566
567
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
581 zfHpPowerSaveSetState(dev, 0);
582 }
583}
584#else
585void zfPowerSavingMgrWakeup(zdev_t* dev)
586{
587}
588#endif
589
590void 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
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
625 if ( 0 )
626 {
627 wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
628
629 zfSendNullData(dev, 0);
630 }
631 else
632 {
633 if ((wd->sta.qosInfo&0xf) != 0xf)
634 {
635
636
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
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
672 zfPowerSavingMgrMain(dev);
673}
674
675void 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
700void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
701{
702 zmw_get_wlan_dev(dev);
703 zmw_declare_for_critical_section();
704
705
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
731
732