1 /* 2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * File: power.c 16 * 17 * Purpose: Handles 802.11 power management functions 18 * 19 * Author: Lyndon Chen 20 * 21 * Date: July 17, 2002 22 * 23 * Functions: 24 * PSvEnablePowerSaving - Enable Power Saving Mode 25 * PSvDiasblePowerSaving - Disable Power Saving Mode 26 * PSbConsiderPowerDown - Decide if we can Power Down 27 * PSvSendPSPOLL - Send PS-POLL packet 28 * PSbSendNullPacket - Send Null packet 29 * PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon 30 * 31 * Revision History: 32 * 33 */ 34 35 #include "mac.h" 36 #include "device.h" 37 #include "power.h" 38 #include "card.h" 39 40 /*--------------------- Static Definitions -------------------------*/ 41 42 /*--------------------- Static Classes ----------------------------*/ 43 44 /*--------------------- Static Functions --------------------------*/ 45 46 /*--------------------- Export Variables --------------------------*/ 47 48 /*--------------------- Export Functions --------------------------*/ 49 50 /* 51 * 52 * Routine Description: 53 * Enable hw power saving functions 54 * 55 * Return Value: 56 * None. 57 * 58 */ 59 60 void 61 PSvEnablePowerSaving( 62 struct vnt_private *priv, 63 unsigned short wListenInterval 64 ) 65 { 66 u16 wAID = priv->current_aid | BIT(14) | BIT(15); 67 68 /* set period of power up before TBTT */ 69 VNSvOutPortW(priv->PortOffset + MAC_REG_PWBT, C_PWBT); 70 if (priv->op_mode != NL80211_IFTYPE_ADHOC) { 71 /* set AID */ 72 VNSvOutPortW(priv->PortOffset + MAC_REG_AIDATIM, wAID); 73 } else { 74 /* set ATIM Window */ 75 #if 0 /* TODO atim window */ 76 MACvWriteATIMW(priv->PortOffset, pMgmt->wCurrATIMWindow); 77 #endif 78 } 79 /* Set AutoSleep */ 80 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); 81 /* Set HWUTSF */ 82 MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); 83 84 if (wListenInterval >= 2) { 85 /* clear always listen beacon */ 86 MACvRegBitsOff(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 87 /* first time set listen next beacon */ 88 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); 89 } else { 90 /* always listen beacon */ 91 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 92 } 93 94 /* enable power saving hw function */ 95 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); 96 priv->bEnablePSMode = true; 97 98 priv->bPWBitOn = true; 99 pr_debug("PS:Power Saving Mode Enable...\n"); 100 } 101 102 /* 103 * 104 * Routine Description: 105 * Disable hw power saving functions 106 * 107 * Return Value: 108 * None. 109 * 110 */ 111 112 void 113 PSvDisablePowerSaving( 114 struct vnt_private *priv 115 ) 116 { 117 /* disable power saving hw function */ 118 MACbPSWakeup(priv); 119 /* clear AutoSleep */ 120 MACvRegBitsOff(priv->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); 121 /* clear HWUTSF */ 122 MACvRegBitsOff(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); 123 /* set always listen beacon */ 124 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 125 126 priv->bEnablePSMode = false; 127 128 priv->bPWBitOn = false; 129 } 130 131 /* 132 * 133 * Routine Description: 134 * Check if Next TBTT must wake up 135 * 136 * Return Value: 137 * None. 138 * 139 */ 140 141 bool 142 PSbIsNextTBTTWakeUp( 143 struct vnt_private *priv 144 ) 145 { 146 struct ieee80211_hw *hw = priv->hw; 147 struct ieee80211_conf *conf = &hw->conf; 148 bool wake_up = false; 149 150 if (conf->listen_interval > 1) { 151 if (!priv->wake_up_count) 152 priv->wake_up_count = conf->listen_interval; 153 154 --priv->wake_up_count; 155 156 if (priv->wake_up_count == 1) { 157 /* Turn on wake up to listen next beacon */ 158 MACvRegBitsOn(priv->PortOffset, 159 MAC_REG_PSCTL, PSCTL_LNBCN); 160 wake_up = true; 161 } 162 } 163 164 return wake_up; 165 } 166