GNU Linux-libre 4.19.264-gnu1
[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  * 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
52 PSvEnablePowerSaving(
53         struct vnt_private *priv,
54         unsigned short wListenInterval
55 )
56 {
57         u16 wAID = priv->current_aid | BIT(14) | BIT(15);
58
59         /* set period of power up before TBTT */
60         VNSvOutPortW(priv->PortOffset + MAC_REG_PWBT, C_PWBT);
61         if (priv->op_mode != NL80211_IFTYPE_ADHOC) {
62                 /* set AID */
63                 VNSvOutPortW(priv->PortOffset + MAC_REG_AIDATIM, wAID);
64         } else {
65                 /* set ATIM Window */
66 #if 0 /* TODO atim window */
67                 MACvWriteATIMW(priv->PortOffset, pMgmt->wCurrATIMWindow);
68 #endif
69         }
70         /* Set AutoSleep */
71         MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
72         /* Set HWUTSF */
73         MACvRegBitsOn(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
74
75         if (wListenInterval >= 2) {
76                 /* clear always listen beacon */
77                 MACvRegBitsOff(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
78                 /* first time set listen next beacon */
79                 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
80         } else {
81                 /* always listen beacon */
82                 MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
83         }
84
85         /* enable power saving hw function */
86         MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
87         priv->bEnablePSMode = true;
88
89         priv->bPWBitOn = true;
90         pr_debug("PS:Power Saving Mode Enable...\n");
91 }
92
93 /*
94  *
95  * Routine Description:
96  * Disable hw power saving functions
97  *
98  * Return Value:
99  *    None.
100  *
101  */
102
103 void
104 PSvDisablePowerSaving(
105         struct vnt_private *priv
106 )
107 {
108         /* disable power saving hw function */
109         MACbPSWakeup(priv);
110         /* clear AutoSleep */
111         MACvRegBitsOff(priv->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
112         /* clear HWUTSF */
113         MACvRegBitsOff(priv->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
114         /* set always listen beacon */
115         MACvRegBitsOn(priv->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
116
117         priv->bEnablePSMode = false;
118
119         priv->bPWBitOn = false;
120 }
121
122 /*
123  *
124  * Routine Description:
125  * Check if Next TBTT must wake up
126  *
127  * Return Value:
128  *    None.
129  *
130  */
131
132 bool
133 PSbIsNextTBTTWakeUp(
134         struct vnt_private *priv
135 )
136 {
137         struct ieee80211_hw *hw = priv->hw;
138         struct ieee80211_conf *conf = &hw->conf;
139         bool wake_up = false;
140
141         if (conf->listen_interval > 1) {
142                 if (!priv->wake_up_count)
143                         priv->wake_up_count = conf->listen_interval;
144
145                 --priv->wake_up_count;
146
147                 if (priv->wake_up_count == 1) {
148                         /* Turn on wake up to listen next beacon */
149                         MACvRegBitsOn(priv->PortOffset,
150                                       MAC_REG_PSCTL, PSCTL_LNBCN);
151                         wake_up = true;
152                 }
153         }
154
155         return wake_up;
156 }