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