GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / otus / 80211core / cpsmgr.c
blob566200402b3e8bbc312f6bae977d9a860b5dfe99
1 /*
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.
17 /**
18 * The power saving manager is to save the power as much as possible.
19 * Generally speaking, it controls:
21 * - when to sleep
22 * -
25 #include "cprecomp.h"
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)
41 u16_t ret = 0;
42 zmw_get_wlan_dev(dev);
44 switch(wd->sta.psMgr.state)
46 case ZM_PS_MSG_STATE_ACTIVE:
47 *isWakeUpRequired = 0;
48 break;
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) )
58 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
59 //zfSendNullData(dev, 0);
60 ret = 1;
63 wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
64 break;
66 return ret;
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;
78 break;
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;
88 void zfPowerSavingMgrSetMode(zdev_t* dev, u8_t mode)
90 u16_t sendNull = 0;
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");
101 return;
104 zmw_enter_critical_section(dev);
106 switch(mode)
108 case ZM_STA_PS_NONE:
109 sendNull = zfPowerSavingMgrHandlePsNone(dev, &isWakeUpRequired);
110 break;
112 case ZM_STA_PS_FAST:
113 case ZM_STA_PS_LIGHT:
114 wd->sta.psMgr.maxSleepPeriods = 1;
115 zfPowerSavingMgrHandlePs(dev);
116 break;
118 case ZM_STA_PS_MAX:
119 wd->sta.psMgr.maxSleepPeriods = ZM_PS_MAX_SLEEP_PERIODS;
120 zfPowerSavingMgrHandlePs(dev);
121 break;
124 wd->sta.powerSaveMode = mode;
125 zmw_leave_critical_section(dev);
127 if ( isWakeUpRequired )
129 zfHpPowerSaveSetState(dev, 0);
130 wd->sta.psMgr.tempWakeUp = 0;
133 if ( zfStaIsConnected(dev)
134 && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
136 switch(mode)
138 case ZM_STA_PS_NONE:
139 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
140 break;
142 case ZM_STA_PS_FAST:
143 case ZM_STA_PS_MAX:
144 case ZM_STA_PS_LIGHT:
145 zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
146 break;
148 default:
149 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
150 break;
154 if (sendNull == 1)
156 zfSendNullData(dev, 0);
159 return;
162 static void zfPowerSavingMgrNotifyPSToAP(zdev_t *dev)
164 zmw_get_wlan_dev(dev);
165 zmw_declare_for_critical_section();
167 if ( (wd->sta.psMgr.tempWakeUp != 1)&&
168 (wd->sta.psMgr.lastTxUnicastFrm != wd->commTally.txUnicastFrm ||
169 wd->sta.psMgr.lastTxBroadcastFrm != wd->commTally.txBroadcastFrm ||
170 wd->sta.psMgr.lastTxMulticastFrm != wd->commTally.txMulticastFrm) )
172 zmw_enter_critical_section(dev);
173 wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
174 wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
175 wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
176 zmw_leave_critical_section(dev);
178 zfSendNullData(dev, 1);
182 static void zfPowerSavingMgrOnHandleT1(zdev_t* dev)
184 zmw_get_wlan_dev(dev);
185 zmw_declare_for_critical_section();
187 // If the tx Q is not empty...return
188 if ( zfIsVtxqEmpty(dev) == FALSE )
190 return;
193 zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n");
195 // The the HAL TX Q is not empty...return
196 if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
198 return;
201 zm_debug_msg0("HAL TXQ is empty now...Could go to sleep...\n");
203 zmw_enter_critical_section(dev);
205 if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
207 if (wd->sta.ReceivedPktRatePerSecond > 200)
209 zmw_leave_critical_section(dev);
210 return;
213 if ( zfStaIsConnected(dev)
214 && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
216 if (wd->sta.psMgr.sleepAllowedtick) {
217 wd->sta.psMgr.sleepAllowedtick--;
218 zmw_leave_critical_section(dev);
219 return;
224 wd->sta.psMgr.state = ZM_PS_MSG_STATE_T2;
226 zmw_leave_critical_section(dev);
228 // Send the Null pkt to AP to notify that I'm going to sleep
229 if ( zfStaIsConnected(dev) )
231 zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
232 zfPowerSavingMgrNotifyPSToAP(dev);
235 // Stall the TX now
236 // zfTxEngineStop(dev);
239 static void zfPowerSavingMgrOnHandleT2(zdev_t* dev)
241 zmw_get_wlan_dev(dev);
242 zmw_declare_for_critical_section();
244 // Wait until the Null pkt is transmitted
245 if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
247 return;
250 zmw_enter_critical_section(dev);
251 wd->sta.psMgr.state = ZM_PS_MSG_STATE_SLEEP;
252 wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
253 wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
254 wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
255 zmw_leave_critical_section(dev);
257 // Let CHIP sleep now
258 zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n");
259 zfHpPowerSaveSetState(dev, 1);
260 wd->sta.psMgr.tempWakeUp = 0;
263 u8_t zfPowerSavingMgrIsSleeping(zdev_t *dev)
265 u8_t isSleeping = FALSE;
266 zmw_get_wlan_dev(dev);
267 zmw_declare_for_critical_section();
269 zmw_enter_critical_section(dev);
270 if ( wd->sta.psMgr.state == ZM_PS_MSG_STATE_SLEEP ||
271 wd->sta.psMgr.state == ZM_PS_MSG_STATE_T2)
273 isSleeping = TRUE;
275 zmw_leave_critical_section(dev);
276 return isSleeping;
279 static u8_t zfPowerSavingMgrIsIdle(zdev_t *dev)
281 u8_t isIdle = 0;
283 zmw_get_wlan_dev(dev);
284 zmw_declare_for_critical_section();
286 zmw_enter_critical_section(dev);
288 if ( zfStaIsConnected(dev) && wd->sta.psMgr.isSleepAllowed == 0 )
290 goto done;
293 if ( wd->sta.bChannelScan )
295 goto done;
298 if ( zfStaIsConnecting(dev) )
300 goto done;
303 if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
305 if (wd->sta.ReceivedPktRatePerSecond > 200)
307 goto done;
310 if ( zfStaIsConnected(dev)
311 && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
313 if (wd->sta.psMgr.sleepAllowedtick) {
314 wd->sta.psMgr.sleepAllowedtick--;
315 goto done;
320 isIdle = 1;
322 done:
323 zmw_leave_critical_section(dev);
325 if ( zfIsVtxqEmpty(dev) == FALSE )
327 isIdle = 0;
330 return isIdle;
333 static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev)
335 u8_t isIdle;
337 zmw_get_wlan_dev(dev);
338 zmw_declare_for_critical_section();
340 isIdle = zfPowerSavingMgrIsIdle(dev);
342 if ( isIdle == 0 )
344 return;
347 zmw_enter_critical_section(dev);
349 switch(wd->sta.powerSaveMode)
351 case ZM_STA_PS_NONE:
352 break;
354 case ZM_STA_PS_MAX:
355 case ZM_STA_PS_FAST:
356 case ZM_STA_PS_LIGHT:
357 zm_debug_msg0("zfPowerSavingMgrSleepIfIdle: IDLE so slep now...\n");
358 wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
359 break;
362 zmw_leave_critical_section(dev);
365 static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
367 #ifdef ZM_ENABLE_DISCONNECT_PS
368 switch(wd->sta.psMgr.state)
370 case ZM_PS_MSG_STATE_ACTIVE:
371 zfPowerSavingMgrSleepIfIdle(dev);
372 break;
374 case ZM_PS_MSG_STATE_SLEEP:
375 break;
377 case ZM_PS_MSG_STATE_T1:
378 zfPowerSavingMgrOnHandleT1(dev);
379 break;
381 case ZM_PS_MSG_STATE_T2:
382 zfPowerSavingMgrOnHandleT2(dev);
383 break;
385 #else
386 zfPowerSavingMgrWakeup(dev);
387 #endif
390 static void zfPowerSavingMgrInfraMain(zdev_t* dev)
392 zmw_get_wlan_dev(dev);
394 switch(wd->sta.psMgr.state)
396 case ZM_PS_MSG_STATE_ACTIVE:
397 zfPowerSavingMgrSleepIfIdle(dev);
398 break;
400 case ZM_PS_MSG_STATE_SLEEP:
401 break;
403 case ZM_PS_MSG_STATE_T1:
404 zfPowerSavingMgrOnHandleT1(dev);
405 break;
407 case ZM_PS_MSG_STATE_T2:
408 zfPowerSavingMgrOnHandleT2(dev);
409 break;
413 void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
415 zmw_get_wlan_dev(dev);
417 //printk("zfPowerSavingMgrAtimWinExpired #1\n");
418 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
420 return;
423 //printk("zfPowerSavingMgrAtimWinExpired #2\n");
424 // if we received any ATIM window from the others to indicate we have buffered data
425 // at the other station, we can't go to sleep
426 if ( wd->sta.recvAtim )
428 wd->sta.recvAtim = 0;
429 zm_debug_msg0("Can't sleep due to receving ATIM window!");
430 return;
433 // if we are the one to tx beacon during last beacon interval. we can't go to sleep
434 // since we need to be alive to respond the probe request!
435 if ( wd->sta.txBeaconInd )
437 zm_debug_msg0("Can't sleep due to just transmit a beacon!");
438 return;
441 // If we buffer any data for the other stations. we could not go to sleep
442 if ( wd->sta.ibssPrevPSDataCount != 0 )
444 zm_debug_msg0("Can't sleep due to buffering data for the others!");
445 return;
448 // before sleeping, we still need to notify the others by transmitting null
449 // pkt with power mgmt bit turned on.
450 zfPowerSavingMgrOnHandleT1(dev);
453 static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
455 // wait for the end of
456 // if need to wait to know if we are the one to transmit the beacon
457 // during the beacon interval. If it's me, we can't go to sleep.
459 zmw_get_wlan_dev(dev);
461 switch(wd->sta.psMgr.state)
463 case ZM_PS_MSG_STATE_ACTIVE:
464 case ZM_PS_MSG_STATE_SLEEP:
465 case ZM_PS_MSG_STATE_T1:
466 break;
468 case ZM_PS_MSG_STATE_T2:
469 zfPowerSavingMgrOnHandleT2(dev);
470 break;
473 return;
476 void zfPowerSavingMgrMain(zdev_t* dev)
478 zmw_get_wlan_dev(dev);
480 switch (wd->sta.adapterState)
482 case ZM_STA_STATE_DISCONNECT:
483 zfPowerSavingMgrDisconnectMain(dev);
484 break;
485 case ZM_STA_STATE_CONNECTED:
487 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) {
488 zfPowerSavingMgrInfraMain(dev);
489 } else if (wd->wlanMode == ZM_MODE_IBSS) {
490 zfPowerSavingMgrIBSSMain(dev);
493 break;
494 case ZM_STA_STATE_CONNECTING:
495 default:
496 break;
500 #ifdef ZM_ENABLE_POWER_SAVE
501 void zfPowerSavingMgrWakeup(zdev_t* dev)
503 zmw_get_wlan_dev(dev);
504 zmw_declare_for_critical_section();
506 //zm_debug_msg0("zfPowerSavingMgrWakeup");
508 //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE && ( zfPowerSavingMgrIsIdle(dev) == 0 ))
509 if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE )
511 zmw_enter_critical_section(dev);
513 wd->sta.psMgr.isSleepAllowed = 0;
514 wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
516 if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
517 wd->sta.psMgr.tempWakeUp = 1;
519 zmw_leave_critical_section(dev);
521 // Wake up the CHIP now!!
522 zfHpPowerSaveSetState(dev, 0);
525 #else
526 void zfPowerSavingMgrWakeup(zdev_t* dev)
529 #endif
531 void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf)
533 u8_t length, bitmap;
534 u16_t offset, n1, n2, q, r;
535 zbuf_t* psBuf;
537 zmw_get_wlan_dev(dev);
538 zmw_declare_for_critical_section();
540 if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
541 //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
543 return;
546 wd->sta.psMgr.isSleepAllowed = 1;
548 offset = zfFindElement(dev, buf, ZM_WLAN_EID_TIM);
549 if (offset != 0xffff)
551 length = zmw_rx_buf_readb(dev, buf, offset+1);
553 if ( length > 3 )
555 n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0);
556 n2 = length + n1 - 4;
557 q = wd->sta.aid >> 3;
558 r = wd->sta.aid & 7;
560 if ((q >= n1) && (q <= n2))
562 bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1);
564 if ( (bitmap >> r) & ZM_BIT_0 )
566 //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
567 if ( 0 )
569 wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
570 //zfSendPSPoll(dev);
571 zfSendNullData(dev, 0);
573 else
575 if ((wd->sta.qosInfo&0xf) != 0xf)
577 /* send ps-poll */
578 //printk("zfSendPSPoll #1\n");
580 wd->sta.psMgr.isSleepAllowed = 0;
582 switch (wd->sta.powerSaveMode)
584 case ZM_STA_PS_MAX:
585 case ZM_STA_PS_FAST:
586 //zm_debug_msg0("wake up and send PS-Poll\n");
587 zfSendPSPoll(dev);
588 break;
589 case ZM_STA_PS_LIGHT:
590 zm_debug_msg0("wake up and send null data\n");
592 zmw_enter_critical_section(dev);
593 wd->sta.psMgr.sleepAllowedtick = 400;
594 zmw_leave_critical_section(dev);
596 zfSendNullData(dev, 0);
597 break;
600 wd->sta.psMgr.tempWakeUp = 0;
608 while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL)
610 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
613 //printk("zfPowerSavingMgrProcessBeacon #1\n");
614 zfPowerSavingMgrMain(dev);
617 void zfPowerSavingMgrConnectNotify(zdev_t *dev)
619 zmw_get_wlan_dev(dev);
621 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
623 switch(wd->sta.powerSaveMode)
625 case ZM_STA_PS_NONE:
626 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
627 break;
629 case ZM_STA_PS_FAST:
630 case ZM_STA_PS_MAX:
631 case ZM_STA_PS_LIGHT:
632 zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
633 break;
635 default:
636 zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
637 break;
642 void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
644 zmw_get_wlan_dev(dev);
645 zmw_declare_for_critical_section();
647 /* disable TBTT interrupt when change from connection to disconnect */
648 if (zfStaIsDisconnect(dev)) {
649 zfHpPowerSaveSetMode(dev, 0, 0, 0);
650 zfPowerSavingMgrWakeup(dev);
651 return;
654 zmw_enter_critical_section(dev);
655 wd->sta.psMgr.ticks++;
657 if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods )
659 zmw_leave_critical_section(dev);
660 return;
662 else
664 wd->sta.psMgr.ticks = 0;
667 zmw_leave_critical_section(dev);
669 zfPowerSavingMgrWakeup(dev);
672 /* Leave an empty line below to remove warning message on some compiler */