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 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * 20 * File: power.c 21 * 22 * Purpose: Handles 802.11 power management functions 23 * 24 * Author: Lyndon Chen 25 * 26 * Date: July 17, 2002 27 * 28 * Functions: 29 * PSvEnablePowerSaving - Enable Power Saving Mode 30 * PSvDiasblePowerSaving - Disable Power Saving Mode 31 * PSbConsiderPowerDown - Decide if we can Power Down 32 * PSvSendPSPOLL - Send PS-POLL packet 33 * PSbSendNullPacket - Send Null packet 34 * PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon 35 * 36 * Revision History: 37 * 38 */ 39 40#include "mac.h" 41#include "device.h" 42#include "power.h" 43#include "card.h" 44 45/*--------------------- Static Definitions -------------------------*/ 46 47/*--------------------- Static Classes ----------------------------*/ 48 49/*--------------------- Static Functions --------------------------*/ 50 51/*--------------------- Export Variables --------------------------*/ 52 53/*--------------------- Export Functions --------------------------*/ 54 55/*+ 56 * 57 * Routine Description: 58 * Enable hw power saving functions 59 * 60 * Return Value: 61 * None. 62 * 63 -*/ 64 65void 66PSvEnablePowerSaving( 67 void *hDeviceContext, 68 unsigned short wListenInterval 69) 70{ 71 struct vnt_private *pDevice = hDeviceContext; 72 u16 wAID = pDevice->current_aid | BIT(14) | BIT(15); 73 74 /* set period of power up before TBTT */ 75 VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT); 76 if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) { 77 /* set AID */ 78 VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID); 79 } else { 80 /* set ATIM Window */ 81#if 0 /* TODO atim window */ 82 MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); 83#endif 84 } 85 /* Set AutoSleep */ 86 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); 87 /* Set HWUTSF */ 88 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); 89 90 if (wListenInterval >= 2) { 91 /* clear always listen beacon */ 92 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 93 /* first time set listen next beacon */ 94 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN); 95 } else { 96 /* always listen beacon */ 97 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 98 } 99 100 /* enable power saving hw function */ 101 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN); 102 pDevice->bEnablePSMode = true; 103 104 pDevice->bPWBitOn = true; 105 pr_debug("PS:Power Saving Mode Enable...\n"); 106} 107 108/*+ 109 * 110 * Routine Description: 111 * Disable hw power saving functions 112 * 113 * Return Value: 114 * None. 115 * 116 -*/ 117 118void 119PSvDisablePowerSaving( 120 void *hDeviceContext 121) 122{ 123 struct vnt_private *pDevice = hDeviceContext; 124 125 /* disable power saving hw function */ 126 MACbPSWakeup(pDevice->PortOffset); 127 /* clear AutoSleep */ 128 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); 129 /* clear HWUTSF */ 130 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF); 131 /* set always listen beacon */ 132 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN); 133 134 pDevice->bEnablePSMode = false; 135 136 pDevice->bPWBitOn = false; 137} 138 139 140/*+ 141 * 142 * Routine Description: 143 * Check if Next TBTT must wake up 144 * 145 * Return Value: 146 * None. 147 * 148 -*/ 149 150bool 151PSbIsNextTBTTWakeUp( 152 void *hDeviceContext 153) 154{ 155 struct vnt_private *pDevice = hDeviceContext; 156 struct ieee80211_hw *hw = pDevice->hw; 157 struct ieee80211_conf *conf = &hw->conf; 158 bool bWakeUp = false; 159 160 if (conf->listen_interval > 1) { 161 if (!pDevice->wake_up_count) 162 pDevice->wake_up_count = conf->listen_interval; 163 164 --pDevice->wake_up_count; 165 166 if (pDevice->wake_up_count == 1) { 167 /* Turn on wake up to listen next beacon */ 168 MACvRegBitsOn(pDevice->PortOffset, 169 MAC_REG_PSCTL, PSCTL_LNBCN); 170 bWakeUp = true; 171 } 172 } 173 174 return bWakeUp; 175} 176