1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
13 static int rtw_ips_pwr_up(struct rtw_dev
*rtwdev
)
17 ret
= rtw_core_start(rtwdev
);
19 rtw_err(rtwdev
, "leave idle state failed\n");
21 rtw_set_channel(rtwdev
);
22 clear_bit(RTW_FLAG_INACTIVE_PS
, rtwdev
->flags
);
27 int rtw_enter_ips(struct rtw_dev
*rtwdev
)
29 set_bit(RTW_FLAG_INACTIVE_PS
, rtwdev
->flags
);
31 rtw_coex_ips_notify(rtwdev
, COEX_IPS_ENTER
);
33 rtw_core_stop(rtwdev
);
34 rtw_hci_link_ps(rtwdev
, true);
39 static void rtw_restore_port_cfg_iter(void *data
, u8
*mac
,
40 struct ieee80211_vif
*vif
)
42 struct rtw_dev
*rtwdev
= data
;
43 struct rtw_vif
*rtwvif
= (struct rtw_vif
*)vif
->drv_priv
;
46 rtw_vif_port_config(rtwdev
, rtwvif
, config
);
49 int rtw_leave_ips(struct rtw_dev
*rtwdev
)
53 rtw_hci_link_ps(rtwdev
, false);
55 ret
= rtw_ips_pwr_up(rtwdev
);
57 rtw_err(rtwdev
, "failed to leave ips state\n");
61 rtw_iterate_vifs_atomic(rtwdev
, rtw_restore_port_cfg_iter
, rtwdev
);
63 rtw_coex_ips_notify(rtwdev
, COEX_IPS_LEAVE
);
68 void rtw_power_mode_change(struct rtw_dev
*rtwdev
, bool enter
)
70 u8 request
, confirm
, polling
;
74 for (retry_cnt
= 0; retry_cnt
< 3; retry_cnt
++) {
75 request
= rtw_read8(rtwdev
, rtwdev
->hci
.rpwm_addr
);
76 confirm
= rtw_read8(rtwdev
, rtwdev
->hci
.cpwm_addr
);
78 /* toggle to request power mode, others remain 0 */
79 request
^= request
| BIT_RPWM_TOGGLE
;
81 request
|= POWER_MODE_ACK
;
83 request
|= POWER_MODE_LCLK
;
84 if (rtw_fw_lps_deep_mode
== LPS_DEEP_MODE_PG
)
85 request
|= POWER_MODE_PG
;
88 rtw_write8(rtwdev
, rtwdev
->hci
.rpwm_addr
, request
);
93 /* check confirm power mode has left power save state */
94 for (polling_cnt
= 0; polling_cnt
< 50; polling_cnt
++) {
95 polling
= rtw_read8(rtwdev
, rtwdev
->hci
.cpwm_addr
);
96 if ((polling
^ confirm
) & BIT_RPWM_TOGGLE
)
101 /* in case of fw/hw missed the request, retry */
102 rtw_warn(rtwdev
, "failed to leave deep PS, retry=%d\n",
106 /* Hit here means that driver failed to change hardware power mode to
107 * active state after retry 3 times. If the power state is locked at
108 * Deep sleep, most of the hardware circuits is not working, even
109 * register read/write. It should be treated as fatal error and
110 * requires an entire analysis about the firmware/hardware
112 WARN(1, "Hardware power state locked\n");
114 EXPORT_SYMBOL(rtw_power_mode_change
);
116 static void __rtw_leave_lps_deep(struct rtw_dev
*rtwdev
)
118 rtw_hci_deep_ps(rtwdev
, false);
121 static void rtw_fw_leave_lps_state_check(struct rtw_dev
*rtwdev
)
125 /* Driver needs to wait for firmware to leave LPS state
126 * successfully. Firmware will send null packet to inform AP,
127 * and see if AP sends an ACK back, then firmware will restore
128 * the REG_TCR register.
130 * If driver does not wait for firmware, null packet with
131 * PS bit could be sent due to incorrect REG_TCR setting.
133 * In our test, 100ms should be enough for firmware to finish
134 * the flow. If REG_TCR Register is still incorrect after 100ms,
135 * just modify it directly, and throw a warn message.
137 for (i
= 0 ; i
< LEAVE_LPS_TRY_CNT
; i
++) {
138 if (rtw_read32_mask(rtwdev
, REG_TCR
, BIT_PWRMGT_HWDATA_EN
) == 0)
143 rtw_write32_mask(rtwdev
, REG_TCR
, BIT_PWRMGT_HWDATA_EN
, 0);
144 rtw_warn(rtwdev
, "firmware failed to restore hardware setting\n");
147 static void rtw_leave_lps_core(struct rtw_dev
*rtwdev
)
149 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
151 conf
->state
= RTW_ALL_ON
;
152 conf
->awake_interval
= 1;
156 rtw_hci_link_ps(rtwdev
, false);
157 rtw_fw_set_pwr_mode(rtwdev
);
158 rtw_fw_leave_lps_state_check(rtwdev
);
160 clear_bit(RTW_FLAG_LEISURE_PS
, rtwdev
->flags
);
162 rtw_coex_lps_notify(rtwdev
, COEX_LPS_DISABLE
);
165 static void __rtw_enter_lps_deep(struct rtw_dev
*rtwdev
)
167 if (rtwdev
->lps_conf
.deep_mode
== LPS_DEEP_MODE_NONE
)
170 if (!test_bit(RTW_FLAG_LEISURE_PS
, rtwdev
->flags
)) {
171 rtw_dbg(rtwdev
, RTW_DBG_PS
,
172 "Should enter LPS before entering deep PS\n");
176 if (rtw_fw_lps_deep_mode
== LPS_DEEP_MODE_PG
)
177 rtw_fw_set_pg_info(rtwdev
);
179 rtw_hci_deep_ps(rtwdev
, true);
182 static void rtw_enter_lps_core(struct rtw_dev
*rtwdev
)
184 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
186 conf
->state
= RTW_RF_OFF
;
187 conf
->awake_interval
= 1;
191 rtw_coex_lps_notify(rtwdev
, COEX_LPS_ENABLE
);
193 rtw_fw_set_pwr_mode(rtwdev
);
194 rtw_hci_link_ps(rtwdev
, true);
196 set_bit(RTW_FLAG_LEISURE_PS
, rtwdev
->flags
);
199 static void __rtw_enter_lps(struct rtw_dev
*rtwdev
, u8 port_id
)
201 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
203 if (test_bit(RTW_FLAG_LEISURE_PS
, rtwdev
->flags
))
206 conf
->mode
= RTW_MODE_LPS
;
207 conf
->port_id
= port_id
;
209 rtw_enter_lps_core(rtwdev
);
212 static void __rtw_leave_lps(struct rtw_dev
*rtwdev
)
214 struct rtw_lps_conf
*conf
= &rtwdev
->lps_conf
;
216 if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP
, rtwdev
->flags
)) {
217 rtw_dbg(rtwdev
, RTW_DBG_PS
,
218 "Should leave deep PS before leaving LPS\n");
219 __rtw_leave_lps_deep(rtwdev
);
222 if (!test_bit(RTW_FLAG_LEISURE_PS
, rtwdev
->flags
))
225 conf
->mode
= RTW_MODE_ACTIVE
;
227 rtw_leave_lps_core(rtwdev
);
230 void rtw_enter_lps(struct rtw_dev
*rtwdev
, u8 port_id
)
232 lockdep_assert_held(&rtwdev
->mutex
);
234 if (rtwdev
->coex
.stat
.wl_force_lps_ctrl
)
237 __rtw_enter_lps(rtwdev
, port_id
);
238 __rtw_enter_lps_deep(rtwdev
);
241 void rtw_leave_lps(struct rtw_dev
*rtwdev
)
243 lockdep_assert_held(&rtwdev
->mutex
);
245 __rtw_leave_lps_deep(rtwdev
);
246 __rtw_leave_lps(rtwdev
);
249 void rtw_leave_lps_deep(struct rtw_dev
*rtwdev
)
251 lockdep_assert_held(&rtwdev
->mutex
);
253 __rtw_leave_lps_deep(rtwdev
);