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