GNU Linux-libre 4.19.263-gnu1
[releases.git] / drivers / staging / vt6656 / 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  *      vnt_enable_power_saving - Enable Power Saving Mode
16  *      PSvDiasblePowerSaving - Disable Power Saving Mode
17  *      vnt_next_tbtt_wakeup - Decide if we need to wake up at next Beacon
18  *
19  * Revision History:
20  *
21  */
22
23 #include "mac.h"
24 #include "device.h"
25 #include "power.h"
26 #include "wcmd.h"
27 #include "rxtx.h"
28 #include "card.h"
29 #include "usbpipe.h"
30
31 /*
32  *
33  * Routine Description:
34  * Enable hw power saving functions
35  *
36  * Return Value:
37  *    None.
38  *
39  */
40
41 void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)
42 {
43         u16 aid = priv->current_aid | BIT(14) | BIT(15);
44
45         /* set period of power up before TBTT */
46         vnt_mac_write_word(priv, MAC_REG_PWBT, C_PWBT);
47
48         if (priv->op_mode != NL80211_IFTYPE_ADHOC)
49                 /* set AID */
50                 vnt_mac_write_word(priv, MAC_REG_AIDATIM, aid);
51
52         /* Warren:06-18-2004,the sequence must follow
53          * PSEN->AUTOSLEEP->GO2DOZE
54          */
55         /* enable power saving hw function */
56         vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_PSEN);
57
58         /* Set AutoSleep */
59         vnt_mac_reg_bits_on(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
60
61         /* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the
62          * AUTOSLEEP doesn't work
63          */
64         vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE);
65
66         if (listen_interval >= 2) {
67                 /* clear always listen beacon */
68                 vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
69
70                 /* first time set listen next beacon */
71                 vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
72         } else {
73                 /* always listen beacon */
74                 vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
75         }
76
77         dev_dbg(&priv->usb->dev,  "PS:Power Saving Mode Enable...\n");
78 }
79
80 /*
81  *
82  * Routine Description:
83  * Disable hw power saving functions
84  *
85  * Return Value:
86  *    None.
87  *
88  */
89
90 void vnt_disable_power_saving(struct vnt_private *priv)
91 {
92         /* disable power saving hw function */
93         vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0,
94                         0, 0, NULL);
95
96         /* clear AutoSleep */
97         vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
98
99         /* set always listen beacon */
100         vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
101 }
102
103 /*
104  *
105  * Routine Description:
106  * Check if Next TBTT must wake up
107  *
108  * Return Value:
109  *    None.
110  *
111  */
112
113 int vnt_next_tbtt_wakeup(struct vnt_private *priv)
114 {
115         struct ieee80211_hw *hw = priv->hw;
116         struct ieee80211_conf *conf = &hw->conf;
117         int wake_up = false;
118
119         if (conf->listen_interval > 1) {
120                 /* Turn on wake up to listen next beacon */
121                 vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
122                 wake_up = true;
123         }
124
125         return wake_up;
126 }