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