2 * Copyright (c) 2007-2008 Atheros Communications Inc.
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.
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.
18 * The power saving manager is to save the power as much as possible.
19 * Generally speaking, it controls:
27 void zfPowerSavingMgrInit(zdev_t
* dev
)
29 zmw_get_wlan_dev(dev
);
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;
39 static u16_t
zfPowerSavingMgrHandlePsNone(zdev_t
* dev
, u8_t
*isWakeUpRequired
)
42 zmw_get_wlan_dev(dev
);
44 switch(wd
->sta
.psMgr
.state
)
46 case ZM_PS_MSG_STATE_ACTIVE
:
47 *isWakeUpRequired
= 0;
50 case ZM_PS_MSG_STATE_T1
:
51 case ZM_PS_MSG_STATE_T2
:
52 case ZM_PS_MSG_STATE_SLEEP
:
54 *isWakeUpRequired
= 1;
55 zm_debug_msg0("zfPowerSavingMgrHandlePsNone: Wake up now\n");
56 if ( zfStaIsConnected(dev
) )
58 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
59 //zfSendNullData(dev, 0);
63 wd
->sta
.psMgr
.state
= ZM_PS_MSG_STATE_ACTIVE
;
69 static void zfPowerSavingMgrHandlePs(zdev_t
* dev
)
71 zmw_get_wlan_dev(dev
);
73 switch(wd
->sta
.psMgr
.state
)
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;
80 case ZM_PS_MSG_STATE_T1
:
81 case ZM_PS_MSG_STATE_T2
:
82 case ZM_PS_MSG_STATE_SLEEP
:
88 void zfPowerSavingMgrSetMode(zdev_t
* dev
, u8_t mode
)
91 u8_t isWakeUpRequired
= 0;
93 zmw_get_wlan_dev(dev
);
94 zmw_declare_for_critical_section();
96 zm_debug_msg1("mode = ", mode
);
98 if (mode
> ZM_STA_PS_LIGHT
)
100 zm_debug_msg0("return - wrong power save mode");
104 zmw_enter_critical_section(dev
);
110 sendNull
= zfPowerSavingMgrHandlePsNone(dev
, &isWakeUpRequired
);
114 case ZM_STA_PS_LIGHT
:
115 wd
->sta
.psMgr
.maxSleepPeriods
= 1;
116 zfPowerSavingMgrHandlePs(dev
);
120 wd
->sta
.psMgr
.maxSleepPeriods
= ZM_PS_MAX_SLEEP_PERIODS
;
121 zfPowerSavingMgrHandlePs(dev
);
125 switch(wd
->sta
.psMgr
.state
)
127 case ZM_PS_MSG_STATE_ACTIVE
:
128 if ( mode
!= ZM_STA_PS_NONE
)
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
;
136 case ZM_PS_MSG_STATE_SLEEP
:
141 wd
->sta
.powerSaveMode
= mode
;
142 zmw_leave_critical_section(dev
);
144 if ( isWakeUpRequired
)
146 zfHpPowerSaveSetState(dev
, 0);
147 wd
->sta
.psMgr
.tempWakeUp
= 0;
150 if ( zfStaIsConnected(dev
)
151 && (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
) )
156 zfHpPowerSaveSetMode(dev
, 0, 0, wd
->beaconInterval
);
161 case ZM_STA_PS_LIGHT
:
162 zfHpPowerSaveSetMode(dev
, 0, 1, wd
->beaconInterval
);
166 zfHpPowerSaveSetMode(dev
, 0, 0, wd
->beaconInterval
);
173 zfSendNullData(dev
, 0);
179 static void zfPowerSavingMgrNotifyPSToAP(zdev_t
*dev
)
181 zmw_get_wlan_dev(dev
);
182 zmw_declare_for_critical_section();
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
) )
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
);
195 zfSendNullData(dev
, 1);
199 static void zfPowerSavingMgrOnHandleT1(zdev_t
* dev
)
201 zmw_get_wlan_dev(dev
);
202 zmw_declare_for_critical_section();
204 // If the tx Q is not empty...return
205 if ( zfIsVtxqEmpty(dev
) == FALSE
)
210 zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n");
212 // The the HAL TX Q is not empty...return
213 if ( zfHpGetFreeTxdCount(dev
) != zfHpGetMaxTxdCount(dev
) )
218 zm_debug_msg0("HAL TXQ is empty now...Could go to sleep...\n");
220 zmw_enter_critical_section(dev
);
222 if (wd
->sta
.powerSaveMode
== ZM_STA_PS_LIGHT
)
224 if (wd
->sta
.ReceivedPktRatePerSecond
> 200)
226 zmw_leave_critical_section(dev
);
230 if ( zfStaIsConnected(dev
)
231 && (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
) )
233 if (wd
->sta
.psMgr
.sleepAllowedtick
) {
234 wd
->sta
.psMgr
.sleepAllowedtick
--;
235 zmw_leave_critical_section(dev
);
241 wd
->sta
.psMgr
.state
= ZM_PS_MSG_STATE_T2
;
243 zmw_leave_critical_section(dev
);
245 // Send the Null pkt to AP to notify that I'm going to sleep
246 if ( zfStaIsConnected(dev
) )
248 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
249 zfPowerSavingMgrNotifyPSToAP(dev
);
253 // zfTxEngineStop(dev);
256 static void zfPowerSavingMgrOnHandleT2(zdev_t
* dev
)
258 zmw_get_wlan_dev(dev
);
259 zmw_declare_for_critical_section();
261 // Wait until the Null pkt is transmitted
262 if ( zfHpGetFreeTxdCount(dev
) != zfHpGetMaxTxdCount(dev
) )
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
);
274 // Let CHIP sleep now
275 zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n");
276 zfHpPowerSaveSetState(dev
, 1);
277 wd
->sta
.psMgr
.tempWakeUp
= 0;
280 u8_t
zfPowerSavingMgrIsSleeping(zdev_t
*dev
)
282 u8_t isSleeping
= FALSE
;
283 zmw_get_wlan_dev(dev
);
284 zmw_declare_for_critical_section();
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
)
292 zmw_leave_critical_section(dev
);
296 static u8_t
zfPowerSavingMgrIsIdle(zdev_t
*dev
)
300 zmw_get_wlan_dev(dev
);
301 zmw_declare_for_critical_section();
303 zmw_enter_critical_section(dev
);
305 if ( zfStaIsConnected(dev
) && wd
->sta
.psMgr
.isSleepAllowed
== 0 )
310 if ( wd
->sta
.bChannelScan
)
315 if ( zfStaIsConnecting(dev
) )
320 if (wd
->sta
.powerSaveMode
== ZM_STA_PS_LIGHT
)
322 if (wd
->sta
.ReceivedPktRatePerSecond
> 200)
327 if ( zfStaIsConnected(dev
)
328 && (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
) )
330 if (wd
->sta
.psMgr
.sleepAllowedtick
) {
331 wd
->sta
.psMgr
.sleepAllowedtick
--;
340 zmw_leave_critical_section(dev
);
342 if ( zfIsVtxqEmpty(dev
) == FALSE
)
350 static void zfPowerSavingMgrSleepIfIdle(zdev_t
*dev
)
354 zmw_get_wlan_dev(dev
);
355 zmw_declare_for_critical_section();
357 isIdle
= zfPowerSavingMgrIsIdle(dev
);
364 zmw_enter_critical_section(dev
);
366 switch(wd
->sta
.powerSaveMode
)
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
;
379 zmw_leave_critical_section(dev
);
382 static void zfPowerSavingMgrDisconnectMain(zdev_t
* dev
)
384 #ifdef ZM_ENABLE_DISCONNECT_PS
385 switch(wd
->sta
.psMgr
.state
)
387 case ZM_PS_MSG_STATE_ACTIVE
:
388 zfPowerSavingMgrSleepIfIdle(dev
);
391 case ZM_PS_MSG_STATE_SLEEP
:
394 case ZM_PS_MSG_STATE_T1
:
395 zfPowerSavingMgrOnHandleT1(dev
);
398 case ZM_PS_MSG_STATE_T2
:
399 zfPowerSavingMgrOnHandleT2(dev
);
403 zfPowerSavingMgrWakeup(dev
);
407 static void zfPowerSavingMgrInfraMain(zdev_t
* dev
)
409 zmw_get_wlan_dev(dev
);
411 switch(wd
->sta
.psMgr
.state
)
413 case ZM_PS_MSG_STATE_ACTIVE
:
414 zfPowerSavingMgrSleepIfIdle(dev
);
417 case ZM_PS_MSG_STATE_SLEEP
:
420 case ZM_PS_MSG_STATE_T1
:
421 zfPowerSavingMgrOnHandleT1(dev
);
424 case ZM_PS_MSG_STATE_T2
:
425 zfPowerSavingMgrOnHandleT2(dev
);
430 void zfPowerSavingMgrAtimWinExpired(zdev_t
* dev
)
432 zmw_get_wlan_dev(dev
);
434 //printk("zfPowerSavingMgrAtimWinExpired #1\n");
435 if ( wd
->sta
.powerSaveMode
== ZM_STA_PS_NONE
)
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
)
445 wd
->sta
.recvAtim
= 0;
446 zm_debug_msg0("Can't sleep due to receving ATIM window!");
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
)
454 zm_debug_msg0("Can't sleep due to just transmit a beacon!");
458 // If we buffer any data for the other stations. we could not go to sleep
459 if ( wd
->sta
.ibssPrevPSDataCount
!= 0 )
461 zm_debug_msg0("Can't sleep due to buffering data for the others!");
465 // before sleeping, we still need to notify the others by transmitting null
466 // pkt with power mgmt bit turned on.
467 zfPowerSavingMgrOnHandleT1(dev
);
470 static void zfPowerSavingMgrIBSSMain(zdev_t
* dev
)
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.
476 zmw_get_wlan_dev(dev
);
478 switch(wd
->sta
.psMgr
.state
)
480 case ZM_PS_MSG_STATE_ACTIVE
:
481 case ZM_PS_MSG_STATE_SLEEP
:
482 case ZM_PS_MSG_STATE_T1
:
485 case ZM_PS_MSG_STATE_T2
:
486 zfPowerSavingMgrOnHandleT2(dev
);
494 void zfPowerSavingMgrMain(zdev_t
* dev
)
496 zmw_get_wlan_dev(dev
);
498 switch (wd
->sta
.adapterState
)
500 case ZM_STA_STATE_DISCONNECT
:
501 zfPowerSavingMgrDisconnectMain(dev
);
503 case ZM_STA_STATE_CONNECTED
:
505 if (wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
) {
506 zfPowerSavingMgrInfraMain(dev
);
507 } else if (wd
->wlanMode
== ZM_MODE_IBSS
) {
508 zfPowerSavingMgrIBSSMain(dev
);
512 case ZM_STA_STATE_CONNECTING
:
518 void zfPowerSavingMgrMain(zdev_t
* dev
)
520 zmw_get_wlan_dev(dev
);
522 if ( wd
->wlanMode
!= ZM_MODE_INFRASTRUCTURE
)
527 switch(wd
->sta
.psMgr
.state
)
529 case ZM_PS_MSG_STATE_ACTIVE
:
533 case ZM_PS_MSG_STATE_SLEEP
:
537 case ZM_PS_MSG_STATE_T1
:
538 zfPowerSavingMgrOnHandleT1(dev
);
541 case ZM_PS_MSG_STATE_T2
:
542 zfPowerSavingMgrOnHandleT2(dev
);
552 zfPowerSavingMgrSleepIfIdle(dev
);
557 #ifdef ZM_ENABLE_POWER_SAVE
558 void zfPowerSavingMgrWakeup(zdev_t
* dev
)
560 zmw_get_wlan_dev(dev
);
561 zmw_declare_for_critical_section();
563 //zm_debug_msg0("zfPowerSavingMgrWakeup");
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
)
568 zmw_enter_critical_section(dev
);
570 wd
->sta
.psMgr
.isSleepAllowed
= 0;
571 wd
->sta
.psMgr
.state
= ZM_PS_MSG_STATE_ACTIVE
;
573 if ( wd
->sta
.powerSaveMode
> ZM_STA_PS_NONE
)
574 wd
->sta
.psMgr
.tempWakeUp
= 1;
576 zmw_leave_critical_section(dev
);
578 // Wake up the CHIP now!!
579 zfHpPowerSaveSetState(dev
, 0);
583 void zfPowerSavingMgrWakeup(zdev_t
* dev
)
588 void zfPowerSavingMgrProcessBeacon(zdev_t
* dev
, zbuf_t
* buf
)
591 u16_t offset
, n1
, n2
, q
, r
;
594 zmw_get_wlan_dev(dev
);
595 zmw_declare_for_critical_section();
597 if ( wd
->sta
.powerSaveMode
== ZM_STA_PS_NONE
)
598 //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
603 wd
->sta
.psMgr
.isSleepAllowed
= 1;
605 offset
= zfFindElement(dev
, buf
, ZM_WLAN_EID_TIM
);
606 if (offset
!= 0xffff)
608 length
= zmw_rx_buf_readb(dev
, buf
, offset
+1);
612 n1
= zmw_rx_buf_readb(dev
, buf
, offset
+4) & (~ZM_BIT_0
);
613 n2
= length
+ n1
- 4;
614 q
= wd
->sta
.aid
>> 3;
617 if ((q
>= n1
) && (q
<= n2
))
619 bitmap
= zmw_rx_buf_readb(dev
, buf
, offset
+5+q
-n1
);
621 if ( (bitmap
>> r
) & ZM_BIT_0
)
623 //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
626 wd
->sta
.psMgr
.state
= ZM_PS_MSG_STATE_S1
;
628 zfSendNullData(dev
, 0);
632 if ((wd
->sta
.qosInfo
&0xf) != 0xf)
635 //printk("zfSendPSPoll #1\n");
637 wd
->sta
.psMgr
.isSleepAllowed
= 0;
639 switch (wd
->sta
.powerSaveMode
)
643 //zm_debug_msg0("wake up and send PS-Poll\n");
646 case ZM_STA_PS_LIGHT
:
647 zm_debug_msg0("wake up and send null data\n");
649 zmw_enter_critical_section(dev
);
650 wd
->sta
.psMgr
.sleepAllowedtick
= 400;
651 zmw_leave_critical_section(dev
);
653 zfSendNullData(dev
, 0);
657 wd
->sta
.psMgr
.tempWakeUp
= 0;
665 while ((psBuf
= zfQueueGet(dev
, wd
->sta
.uapsdQ
)) != NULL
)
667 zfTxSendEth(dev
, psBuf
, 0, ZM_EXTERNAL_ALLOC_BUF
, 0);
670 //printk("zfPowerSavingMgrProcessBeacon #1\n");
671 zfPowerSavingMgrMain(dev
);
674 void zfPowerSavingMgrConnectNotify(zdev_t
*dev
)
676 zmw_get_wlan_dev(dev
);
678 if ( wd
->wlanMode
== ZM_MODE_INFRASTRUCTURE
)
680 switch(wd
->sta
.powerSaveMode
)
683 zfHpPowerSaveSetMode(dev
, 0, 0, wd
->beaconInterval
);
688 case ZM_STA_PS_LIGHT
:
689 zfHpPowerSaveSetMode(dev
, 0, 1, wd
->beaconInterval
);
693 zfHpPowerSaveSetMode(dev
, 0, 0, wd
->beaconInterval
);
699 void zfPowerSavingMgrPreTBTTInterrupt(zdev_t
*dev
)
701 zmw_get_wlan_dev(dev
);
702 zmw_declare_for_critical_section();
704 /* disable TBTT interrupt when change from connection to disconnect */
705 if (zfStaIsDisconnect(dev
)) {
706 zfHpPowerSaveSetMode(dev
, 0, 0, 0);
707 zfPowerSavingMgrWakeup(dev
);
711 zmw_enter_critical_section(dev
);
712 wd
->sta
.psMgr
.ticks
++;
714 if ( wd
->sta
.psMgr
.ticks
< wd
->sta
.psMgr
.maxSleepPeriods
)
716 zmw_leave_critical_section(dev
);
721 wd
->sta
.psMgr
.ticks
= 0;
724 zmw_leave_critical_section(dev
);
726 zfPowerSavingMgrWakeup(dev
);
729 /* Leave an empty line below to remove warning message on some compiler */