xref: /openbmc/linux/drivers/staging/vt6656/power.c (revision 31e67366)
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 	/* always listen beacon */
67 	vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
68 
69 	dev_dbg(&priv->usb->dev,  "PS:Power Saving Mode Enable...\n");
70 }
71 
72 int vnt_disable_power_saving(struct vnt_private *priv)
73 {
74 	int ret;
75 
76 	/* disable power saving hw function */
77 	ret = vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0,
78 			      0, 0, NULL);
79 	if (ret)
80 		return ret;
81 
82 	/* clear AutoSleep */
83 	vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
84 
85 	/* set always listen beacon */
86 	vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
87 
88 	return 0;
89 }
90 
91 /*
92  *
93  * Routine Description:
94  * Check if Next TBTT must wake up
95  *
96  * Return Value:
97  *    None.
98  *
99  */
100 
101 int vnt_next_tbtt_wakeup(struct vnt_private *priv)
102 {
103 	struct ieee80211_hw *hw = priv->hw;
104 	struct ieee80211_conf *conf = &hw->conf;
105 	int wake_up = false;
106 
107 	if (conf->listen_interval > 1) {
108 		/* Turn on wake up to listen next beacon */
109 		vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
110 		wake_up = true;
111 	}
112 
113 	return wake_up;
114 }
115