1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /****************************************************************************** |
3 | * |
4 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. |
5 | * |
6 | ******************************************************************************/ |
7 | #ifndef __RTW_PWRCTRL_H_ |
8 | #define __RTW_PWRCTRL_H_ |
9 | |
10 | #include <linux/mutex.h> |
11 | |
12 | #define FW_PWR0 0 |
13 | #define FW_PWR1 1 |
14 | #define FW_PWR2 2 |
15 | #define FW_PWR3 3 |
16 | |
17 | |
18 | #define HW_PWR0 7 |
19 | #define HW_PWR1 6 |
20 | #define HW_PWR2 2 |
21 | #define HW_PWR3 0 |
22 | #define HW_PWR4 8 |
23 | |
24 | #define FW_PWRMSK 0x7 |
25 | |
26 | |
27 | #define XMIT_ALIVE BIT(0) |
28 | #define RECV_ALIVE BIT(1) |
29 | #define CMD_ALIVE BIT(2) |
30 | #define EVT_ALIVE BIT(3) |
31 | #define BTCOEX_ALIVE BIT(4) |
32 | |
33 | |
34 | enum { |
35 | PS_MODE_ACTIVE = 0, |
36 | PS_MODE_MIN, |
37 | PS_MODE_MAX, |
38 | PS_MODE_DTIM, /* PS_MODE_SELF_DEFINED */ |
39 | PS_MODE_VOIP, |
40 | PS_MODE_UAPSD_WMM, |
41 | PS_MODE_UAPSD, |
42 | PS_MODE_IBSS, |
43 | PS_MODE_WWLAN, |
44 | PM_Radio_Off, |
45 | PM_Card_Disable, |
46 | PS_MODE_NUM, |
47 | }; |
48 | |
49 | /* |
50 | BIT[2:0] = HW state |
51 | BIT[3] = Protocol PS state, 0: register active state , 1: register sleep state |
52 | BIT[4] = sub-state |
53 | */ |
54 | |
55 | #define PS_DPS BIT(0) |
56 | #define PS_LCLK (PS_DPS) |
57 | #define PS_RF_OFF BIT(1) |
58 | #define PS_ALL_ON BIT(2) |
59 | #define PS_ST_ACTIVE BIT(3) |
60 | |
61 | #define PS_ISR_ENABLE BIT(4) |
62 | #define PS_IMR_ENABLE BIT(5) |
63 | #define PS_ACK BIT(6) |
64 | #define PS_TOGGLE BIT(7) |
65 | |
66 | #define PS_STATE_MASK (0x0F) |
67 | #define PS_STATE_HW_MASK (0x07) |
68 | #define PS_SEQ_MASK (0xc0) |
69 | |
70 | #define PS_STATE(x) (PS_STATE_MASK & (x)) |
71 | #define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) |
72 | #define PS_SEQ(x) (PS_SEQ_MASK & (x)) |
73 | |
74 | #define PS_STATE_S0 (PS_DPS) |
75 | #define PS_STATE_S1 (PS_LCLK) |
76 | #define PS_STATE_S2 (PS_RF_OFF) |
77 | #define PS_STATE_S3 (PS_ALL_ON) |
78 | #define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) |
79 | |
80 | |
81 | #define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) |
82 | #define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) |
83 | #define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) |
84 | |
85 | |
86 | struct reportpwrstate_parm { |
87 | unsigned char mode; |
88 | unsigned char state; /* the CPWM value */ |
89 | unsigned short rsvd; |
90 | }; |
91 | |
92 | #define LPS_DELAY_TIME (1 * HZ) /* 1 sec */ |
93 | |
94 | #define EXE_PWR_NONE 0x01 |
95 | #define EXE_PWR_IPS 0x02 |
96 | #define EXE_PWR_LPS 0x04 |
97 | |
98 | /* RF state. */ |
99 | enum rt_rf_power_state { |
100 | rf_on, /* RF is on after RFSleep or RFOff */ |
101 | rf_sleep, /* 802.11 Power Save mode */ |
102 | rf_off, /* HW/SW Radio OFF or Inactive Power Save */ |
103 | /* Add the new RF state above this line ===== */ |
104 | rf_max |
105 | }; |
106 | |
107 | /* RF Off Level for IPS or HW/SW radio off */ |
108 | #define RT_RF_OFF_LEVL_ASPM BIT(0) /* PCI ASPM */ |
109 | #define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /* PCI clock request */ |
110 | #define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /* PCI D3 mode */ |
111 | #define RT_RF_OFF_LEVL_HALT_NIC BIT(3) /* NIC halt, re-initialize hw parameters */ |
112 | #define RT_RF_OFF_LEVL_FREE_FW BIT(4) /* FW free, re-download the FW */ |
113 | #define RT_RF_OFF_LEVL_FW_32K BIT(5) /* FW in 32k */ |
114 | #define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) /* Always enable ASPM and Clock Req in initialization. */ |
115 | #define RT_RF_LPS_DISALBE_2R BIT(30) /* When LPS is on, disable 2R if no packet is received or transmitted. */ |
116 | #define RT_RF_LPS_LEVEL_ASPM BIT(31) /* LPS with ASPM */ |
117 | |
118 | #define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) ((ppsc->cur_ps_level & _PS_FLAG) ? true : false) |
119 | #define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level &= (~(_PS_FLAG))) |
120 | #define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level |= _PS_FLAG) |
121 | |
122 | /* ASPM OSC Control bit, added by Roger, 2013.03.29. */ |
123 | #define RT_PCI_ASPM_OSC_IGNORE 0 /* PCI ASPM ignore OSC control in default */ |
124 | #define RT_PCI_ASPM_OSC_ENABLE BIT0 /* PCI ASPM controlled by OS according to ACPI Spec 5.0 */ |
125 | #define RT_PCI_ASPM_OSC_DISABLE BIT1 /* PCI ASPM controlled by driver or BIOS, i.e., force enable ASPM */ |
126 | |
127 | enum { |
128 | PSBBREG_RF0 = 0, |
129 | PSBBREG_RF1, |
130 | PSBBREG_RF2, |
131 | PSBBREG_AFE0, |
132 | PSBBREG_TOTALCNT |
133 | }; |
134 | |
135 | enum { /* for ips_mode */ |
136 | IPS_NONE = 0, |
137 | IPS_NORMAL, |
138 | IPS_LEVEL_2, |
139 | IPS_NUM |
140 | }; |
141 | |
142 | /* Design for pwrctrl_priv.ips_deny, 32 bits for 32 reasons at most */ |
143 | enum ps_deny_reason { |
144 | PS_DENY_DRV_INITIAL = 0, |
145 | PS_DENY_SCAN, |
146 | PS_DENY_JOIN, |
147 | PS_DENY_DISCONNECT, |
148 | PS_DENY_SUSPEND, |
149 | PS_DENY_IOCTL, |
150 | PS_DENY_MGNT_TX, |
151 | PS_DENY_DRV_REMOVE = 30, |
152 | PS_DENY_OTHERS = 31 |
153 | }; |
154 | |
155 | struct pwrctrl_priv { |
156 | struct mutex lock; |
157 | volatile u8 rpwm; /* requested power state for fw */ |
158 | volatile u8 cpwm; /* fw current power state. updated when 1. read from HCPWM 2. driver lowers power level */ |
159 | volatile u8 tog; /* toggling */ |
160 | volatile u8 cpwm_tog; /* toggling */ |
161 | |
162 | u8 pwr_mode; |
163 | u8 smart_ps; |
164 | u8 bcn_ant_mode; |
165 | u8 dtim; |
166 | |
167 | u32 alives; |
168 | struct work_struct cpwm_event; |
169 | u8 brpwmtimeout; |
170 | struct work_struct rpwmtimeoutwi; |
171 | struct timer_list pwr_rpwm_timer; |
172 | u8 bpower_saving; /* for LPS/IPS */ |
173 | |
174 | u8 b_hw_radio_off; |
175 | u8 reg_rfoff; |
176 | u8 reg_pdnmode; /* powerdown mode */ |
177 | u32 rfoff_reason; |
178 | |
179 | /* RF OFF Level */ |
180 | u32 cur_ps_level; |
181 | u32 reg_rfps_level; |
182 | |
183 | uint ips_enter_cnts; |
184 | uint ips_leave_cnts; |
185 | |
186 | u8 ips_mode; |
187 | u8 ips_org_mode; |
188 | u8 ips_mode_req; /* used to accept the mode setting request, will update to ipsmode later */ |
189 | bool bips_processing; |
190 | unsigned long ips_deny_time; /* will deny IPS when system time is smaller than this */ |
191 | u8 pre_ips_type;/* 0: default flow, 1: carddisbale flow */ |
192 | |
193 | /* ps_deny: if 0, power save is free to go; otherwise deny all kinds of power save. */ |
194 | /* Use enum ps_deny_reason to decide reason. */ |
195 | /* Don't access this variable directly without control function, */ |
196 | /* and this variable should be protected by lock. */ |
197 | u32 ps_deny; |
198 | |
199 | u8 ps_processing; /* temporarily used to mark whether in rtw_ps_processor */ |
200 | |
201 | u8 fw_psmode_iface_id; |
202 | u8 bLeisurePs; |
203 | u8 LpsIdleCount; |
204 | u8 power_mgnt; |
205 | u8 org_power_mgnt; |
206 | bool fw_current_in_ps_mode; |
207 | unsigned long DelayLPSLastTimeStamp; |
208 | s32 pnp_current_pwr_state; |
209 | u8 pnp_bstop_trx; |
210 | |
211 | |
212 | u8 bInternalAutoSuspend; |
213 | u8 bInSuspend; |
214 | |
215 | u8 bAutoResume; |
216 | u8 autopm_cnt; |
217 | |
218 | u8 bSupportRemoteWakeup; |
219 | u8 wowlan_wake_reason; |
220 | u8 wowlan_ap_mode; |
221 | u8 wowlan_mode; |
222 | struct timer_list pwr_state_check_timer; |
223 | struct adapter *adapter; |
224 | int pwr_state_check_interval; |
225 | u8 pwr_state_check_cnts; |
226 | |
227 | int ps_flag; /* used by autosuspend */ |
228 | |
229 | enum rt_rf_power_state rf_pwrstate;/* cur power state, only for IPS */ |
230 | /* rt_rf_power_state current_rfpwrstate; */ |
231 | enum rt_rf_power_state change_rfpwrstate; |
232 | |
233 | u8 bHWPowerdown; /* power down mode selection. 0:radio off, 1:power down */ |
234 | u8 bHWPwrPindetect; /* come from registrypriv.hwpwrp_detect. enable power down function. 0:disable, 1:enable */ |
235 | u8 bkeepfwalive; |
236 | u8 brfoffbyhw; |
237 | unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT]; |
238 | }; |
239 | |
240 | #define rtw_ips_mode_req(pwrctl, ips_mode) \ |
241 | ((pwrctl)->ips_mode_req = (ips_mode)) |
242 | |
243 | #define RTW_PWR_STATE_CHK_INTERVAL 2000 |
244 | |
245 | #define _rtw_set_pwr_state_check_timer(pwrctl, ms) \ |
246 | do { \ |
247 | _set_timer(&(pwrctl)->pwr_state_check_timer, (ms)); \ |
248 | } while (0) |
249 | |
250 | #define rtw_set_pwr_state_check_timer(pwrctl) \ |
251 | _rtw_set_pwr_state_check_timer((pwrctl), (pwrctl)->pwr_state_check_interval) |
252 | |
253 | extern void rtw_init_pwrctrl_priv(struct adapter *adapter); |
254 | extern void rtw_free_pwrctrl_priv(struct adapter *adapter); |
255 | |
256 | s32 rtw_register_task_alive(struct adapter *, u32 task); |
257 | void rtw_unregister_task_alive(struct adapter *, u32 task); |
258 | extern s32 rtw_register_tx_alive(struct adapter *padapter); |
259 | extern void rtw_unregister_tx_alive(struct adapter *padapter); |
260 | extern s32 rtw_register_cmd_alive(struct adapter *padapter); |
261 | extern void rtw_unregister_cmd_alive(struct adapter *padapter); |
262 | extern void cpwm_int_hdl(struct adapter *padapter, struct reportpwrstate_parm *preportpwrstate); |
263 | extern void LPS_Leave_check(struct adapter *padapter); |
264 | |
265 | extern void LeaveAllPowerSaveMode(struct adapter *Adapter); |
266 | extern void LeaveAllPowerSaveModeDirect(struct adapter *Adapter); |
267 | void _ips_enter(struct adapter *padapter); |
268 | void ips_enter(struct adapter *padapter); |
269 | int _ips_leave(struct adapter *padapter); |
270 | int ips_leave(struct adapter *padapter); |
271 | |
272 | void rtw_ps_processor(struct adapter *padapter); |
273 | |
274 | s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms); |
275 | void LPS_Enter(struct adapter *padapter, const char *msg); |
276 | void LPS_Leave(struct adapter *padapter, const char *msg); |
277 | void traffic_check_for_leave_lps(struct adapter *padapter, u8 tx, u32 tx_packets); |
278 | void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode, const char *msg); |
279 | void rtw_set_rpwm(struct adapter *padapter, u8 val8); |
280 | |
281 | void rtw_set_ips_deny(struct adapter *padapter, u32 ms); |
282 | int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *caller); |
283 | #define rtw_pwr_wakeup(adapter) _rtw_pwr_wakeup(adapter, RTW_PWR_STATE_CHK_INTERVAL, __func__) |
284 | #define rtw_pwr_wakeup_ex(adapter, ips_deffer_ms) _rtw_pwr_wakeup(adapter, ips_deffer_ms, __func__) |
285 | int rtw_pm_set_ips(struct adapter *padapter, u8 mode); |
286 | int rtw_pm_set_lps(struct adapter *padapter, u8 mode); |
287 | |
288 | void rtw_ps_deny(struct adapter *padapter, enum ps_deny_reason reason); |
289 | void rtw_ps_deny_cancel(struct adapter *padapter, enum ps_deny_reason reason); |
290 | u32 rtw_ps_deny_get(struct adapter *padapter); |
291 | |
292 | #endif /* __RTL871X_PWRCTRL_H_ */ |
293 | |