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 zmw_get_wlan_dev(dev);
386 #ifdef ZM_ENABLE_DISCONNECT_PS
387 switch(wd->sta.psMgr.state)
389 case ZM_PS_MSG_STATE_ACTIVE:
390 zfPowerSavingMgrSleepIfIdle(dev);
393 case ZM_PS_MSG_STATE_SLEEP:
396 case ZM_PS_MSG_STATE_T1:
397 zfPowerSavingMgrOnHandleT1(dev);
400 case ZM_PS_MSG_STATE_T2:
401 zfPowerSavingMgrOnHandleT2(dev);
405 zfPowerSavingMgrWakeup(dev);
409 static void zfPowerSavingMgrInfraMain(zdev_t* dev)
411 zmw_get_wlan_dev(dev);
413 switch(wd->sta.psMgr.state)
415 case ZM_PS_MSG_STATE_ACTIVE:
416 zfPowerSavingMgrSleepIfIdle(dev);
419 case ZM_PS_MSG_STATE_SLEEP:
422 case ZM_PS_MSG_STATE_T1:
423 zfPowerSavingMgrOnHandleT1(dev);
426 case ZM_PS_MSG_STATE_T2:
427 zfPowerSavingMgrOnHandleT2(dev);
432 void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
434 zmw_get_wlan_dev(dev);
436 //printk("zfPowerSavingMgrAtimWinExpired #1\n");
437 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
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 )
447 wd->sta.recvAtim = 0;
448 zm_debug_msg0("Can't sleep due to receving ATIM window!");
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 )
456 zm_debug_msg0("Can't sleep due to just transmit a beacon!");
460 // If we buffer any data for the other stations. we could not go to sleep
461 if ( wd->sta.ibssPrevPSDataCount != 0 )
463 zm_debug_msg0("Can't sleep due to buffering data for the others!");
467 // before sleeping, we still need to notify the others by transmitting null
468 // pkt with power mgmt bit turned on.
469 zfPowerSavingMgrOnHandleT1(dev);
472 static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
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.
478 zmw_get_wlan_dev(dev);
480 switch(wd->sta.psMgr.state)
482 case ZM_PS_MSG_STATE_ACTIVE:
483 case ZM_PS_MSG_STATE_SLEEP:
484 case ZM_PS_MSG_STATE_T1:
487 case ZM_PS_MSG_STATE_T2:
488 zfPowerSavingMgrOnHandleT2(dev);
496 void zfPowerSavingMgrMain(zdev_t* dev)
498 zmw_get_wlan_dev(dev);
500 switch (wd->sta.adapterState)
502 case ZM_STA_STATE_DISCONNECT:
503 zfPowerSavingMgrDisconnectMain(dev);
505 case ZM_STA_STATE_CONNECTED:
507 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) {
508 zfPowerSavingMgrInfraMain(dev);
509 } else if (wd->wlanMode == ZM_MODE_IBSS) {
510 zfPowerSavingMgrIBSSMain(dev);
514 case ZM_STA_STATE_CONNECTING:
520 void zfPowerSavingMgrMain(zdev_t* dev)
522 zmw_get_wlan_dev(dev);
524 if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
529 switch(wd->sta.psMgr.state)
531 case ZM_PS_MSG_STATE_ACTIVE:
535 case ZM_PS_MSG_STATE_SLEEP:
539 case ZM_PS_MSG_STATE_T1:
540 zfPowerSavingMgrOnHandleT1(dev);
543 case ZM_PS_MSG_STATE_T2:
544 zfPowerSavingMgrOnHandleT2(dev);
554 zfPowerSavingMgrSleepIfIdle(dev);
559 #ifdef ZM_ENABLE_POWER_SAVE
560 void zfPowerSavingMgrWakeup(zdev_t* dev)
562 zmw_get_wlan_dev(dev);
563 zmw_declare_for_critical_section();
565 //zm_debug_msg0("zfPowerSavingMgrWakeup");
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 )
570 zmw_enter_critical_section(dev);
572 wd->sta.psMgr.isSleepAllowed = 0;
573 wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
575 if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
576 wd->sta.psMgr.tempWakeUp = 1;
578 zmw_leave_critical_section(dev);
580 // Wake up the CHIP now!!
581 zfHpPowerSaveSetState(dev, 0);
585 void zfPowerSavingMgrWakeup(zdev_t* dev)
590 void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf)
593 u16_t offset, n1, n2, q, r;
596 zmw_get_wlan_dev(dev);
597 zmw_declare_for_critical_section();
599 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
600 //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
605 wd->sta.psMgr.isSleepAllowed = 1;
607 if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_TIM)) != 0xffff )
609 length = zmw_rx_buf_readb(dev, buf, offset+1);
613 n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0);
614 n2 = length + n1 - 4;
615 q = wd->sta.aid >> 3;
618 if ((q >= n1) && (q <= n2))
620 bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1);
622 if ( (bitmap >> r) & ZM_BIT_0 )
624 //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
627 wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
629 zfSendNullData(dev, 0);
633 if ((wd->sta.qosInfo&0xf) != 0xf)
636 //printk("zfSendPSPoll #1\n");
638 wd->sta.psMgr.isSleepAllowed = 0;
640 switch (wd->sta.powerSaveMode)
644 //zm_debug_msg0("wake up and send PS-Poll\n");
647 case ZM_STA_PS_LIGHT:
648 zm_debug_msg0("wake up and send null data\n");
650 zmw_enter_critical_section(dev);
651 wd->sta.psMgr.sleepAllowedtick = 400;
652 zmw_leave_critical_section(dev);
654 zfSendNullData(dev, 0);
658 wd->sta.psMgr.tempWakeUp = 0;
666 while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL)
668 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
671 //printk("zfPowerSavingMgrProcessBeacon #1\n");
672 zfPowerSavingMgrMain(dev);
675 void zfPowerSavingMgrConnectNotify(zdev_t *dev)
677 zmw_get_wlan_dev(dev);
679 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
681 switch(wd->sta.powerSaveMode)
684 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
689 case ZM_STA_PS_LIGHT:
690 zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
694 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
700 void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
702 zmw_get_wlan_dev(dev);
703 zmw_declare_for_critical_section();
705 /* disable TBTT interrupt when change from connection to disconnect */
706 if (zfStaIsDisconnect(dev)) {
707 zfHpPowerSaveSetMode(dev, 0, 0, 0);
708 zfPowerSavingMgrWakeup(dev);
712 zmw_enter_critical_section(dev);
713 wd->sta.psMgr.ticks++;
715 if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods )
717 zmw_leave_critical_section(dev);
722 wd->sta.psMgr.ticks = 0;
725 zmw_leave_critical_section(dev);
727 zfPowerSavingMgrWakeup(dev);
730 /* Leave an empty line below to remove warning message on some compiler */