xref: /openbmc/linux/drivers/staging/vt6655/power.c (revision 9d4fa1a1)
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 
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 	}
62 
63 	/* Set AutoSleep */
64 	MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
65 
66 	/* Set HWUTSF */
67 	MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
68 
69 	if (wListenInterval >= 2) {
70 		/* clear always listen beacon */
71 		MACvRegBitsOff(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
72 		/* first time set listen next beacon */
73 		MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
74 	} else {
75 		/* always listen beacon */
76 		MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
77 	}
78 
79 	/* enable power saving hw function */
80 	MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
81 	priv->bEnablePSMode = true;
82 
83 	priv->bPWBitOn = true;
84 	pr_debug("PS:Power Saving Mode Enable...\n");
85 }
86 
87 /*
88  *
89  * Routine Description:
90  * Disable hw power saving functions
91  *
92  * Return Value:
93  *    None.
94  *
95  */
96 
97 void PSvDisablePowerSaving(struct vnt_private *priv)
98 {
99 	/* disable power saving hw function */
100 	MACbPSWakeup(priv);
101 
102 	/* clear AutoSleep */
103 	MACvRegBitsOff(priv->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
104 
105 	/* clear HWUTSF */
106 	MACvRegBitsOff(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
107 
108 	/* set always listen beacon */
109 	MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
110 
111 	priv->bEnablePSMode = false;
112 
113 	priv->bPWBitOn = false;
114 }
115 
116 /*
117  *
118  * Routine Description:
119  * Check if Next TBTT must wake up
120  *
121  * Return Value:
122  *    None.
123  *
124  */
125 
126 bool PSbIsNextTBTTWakeUp(struct vnt_private *priv)
127 {
128 	struct ieee80211_hw *hw = priv->hw;
129 	struct ieee80211_conf *conf = &hw->conf;
130 	bool wake_up = false;
131 
132 	if (conf->listen_interval > 1) {
133 		if (!priv->wake_up_count)
134 			priv->wake_up_count = conf->listen_interval;
135 
136 		--priv->wake_up_count;
137 
138 		if (priv->wake_up_count == 1) {
139 			/* Turn on wake up to listen next beacon */
140 			MACvRegBitsOn(priv->PortOffset,
141 				      MAC_REG_PSCTL, PSCTL_LNBCN);
142 			wake_up = true;
143 		}
144 	}
145 
146 	return wake_up;
147 }
148