0001
0002
0003
0004
0005 #include "main.h"
0006 #include "reg.h"
0007 #include "fw.h"
0008 #include "ps.h"
0009 #include "mac.h"
0010 #include "coex.h"
0011 #include "debug.h"
0012
0013 static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)
0014 {
0015 int ret;
0016
0017 ret = rtw_core_start(rtwdev);
0018 if (ret)
0019 rtw_err(rtwdev, "leave idle state failed\n");
0020
0021 rtw_set_channel(rtwdev);
0022 clear_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags);
0023
0024 return ret;
0025 }
0026
0027 int rtw_enter_ips(struct rtw_dev *rtwdev)
0028 {
0029 set_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags);
0030
0031 rtw_coex_ips_notify(rtwdev, COEX_IPS_ENTER);
0032
0033 rtw_core_stop(rtwdev);
0034 rtw_hci_link_ps(rtwdev, true);
0035
0036 return 0;
0037 }
0038
0039 static void rtw_restore_port_cfg_iter(void *data, u8 *mac,
0040 struct ieee80211_vif *vif)
0041 {
0042 struct rtw_dev *rtwdev = data;
0043 struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
0044 u32 config = ~0;
0045
0046 rtw_vif_port_config(rtwdev, rtwvif, config);
0047 }
0048
0049 int rtw_leave_ips(struct rtw_dev *rtwdev)
0050 {
0051 int ret;
0052
0053 rtw_hci_link_ps(rtwdev, false);
0054
0055 ret = rtw_ips_pwr_up(rtwdev);
0056 if (ret) {
0057 rtw_err(rtwdev, "failed to leave ips state\n");
0058 return ret;
0059 }
0060
0061 rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
0062
0063 rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE);
0064
0065 return 0;
0066 }
0067
0068 void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter)
0069 {
0070 u8 request, confirm, polling;
0071 int ret;
0072
0073 request = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
0074 confirm = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr);
0075
0076
0077 request ^= request | BIT_RPWM_TOGGLE;
0078 if (enter) {
0079 request |= POWER_MODE_LCLK;
0080 if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG)
0081 request |= POWER_MODE_PG;
0082 }
0083
0084 request |= POWER_MODE_ACK;
0085
0086 if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_TX_WAKE))
0087 request |= POWER_TX_WAKE;
0088
0089 rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request);
0090
0091
0092 ret = read_poll_timeout_atomic(rtw_read8, polling,
0093 (polling ^ confirm) & BIT_RPWM_TOGGLE,
0094 100, 15000, true, rtwdev,
0095 rtwdev->hci.cpwm_addr);
0096 if (ret) {
0097
0098
0099
0100
0101
0102
0103
0104 WARN(1, "firmware failed to ack driver for %s Deep Power mode\n",
0105 enter ? "entering" : "leaving");
0106 }
0107 }
0108 EXPORT_SYMBOL(rtw_power_mode_change);
0109
0110 static void __rtw_leave_lps_deep(struct rtw_dev *rtwdev)
0111 {
0112 rtw_hci_deep_ps(rtwdev, false);
0113 }
0114
0115 static int __rtw_fw_leave_lps_check_reg(struct rtw_dev *rtwdev)
0116 {
0117 int i;
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 for (i = 0 ; i < LEAVE_LPS_TRY_CNT; i++) {
0132 if (rtw_read32_mask(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN) == 0)
0133 return 0;
0134 msleep(20);
0135 }
0136
0137 return -EBUSY;
0138 }
0139
0140 static int __rtw_fw_leave_lps_check_c2h(struct rtw_dev *rtwdev)
0141 {
0142 if (wait_for_completion_timeout(&rtwdev->lps_leave_check,
0143 LEAVE_LPS_TIMEOUT))
0144 return 0;
0145 return -EBUSY;
0146 }
0147
0148 static void rtw_fw_leave_lps_check(struct rtw_dev *rtwdev)
0149 {
0150 bool ret = false;
0151 struct rtw_fw_state *fw;
0152
0153 if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags))
0154 fw = &rtwdev->wow_fw;
0155 else
0156 fw = &rtwdev->fw;
0157
0158 if (rtw_fw_feature_check(fw, FW_FEATURE_LPS_C2H))
0159 ret = __rtw_fw_leave_lps_check_c2h(rtwdev);
0160 else
0161 ret = __rtw_fw_leave_lps_check_reg(rtwdev);
0162
0163 if (ret) {
0164 rtw_write32_clr(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN);
0165 rtw_warn(rtwdev, "firmware failed to leave lps state\n");
0166 }
0167 }
0168
0169 static void rtw_fw_leave_lps_check_prepare(struct rtw_dev *rtwdev)
0170 {
0171 struct rtw_fw_state *fw;
0172
0173 if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags))
0174 fw = &rtwdev->wow_fw;
0175 else
0176 fw = &rtwdev->fw;
0177
0178 if (rtw_fw_feature_check(fw, FW_FEATURE_LPS_C2H))
0179 reinit_completion(&rtwdev->lps_leave_check);
0180 }
0181
0182 static void rtw_leave_lps_core(struct rtw_dev *rtwdev)
0183 {
0184 struct rtw_lps_conf *conf = &rtwdev->lps_conf;
0185
0186 conf->state = RTW_ALL_ON;
0187 conf->awake_interval = 1;
0188 conf->rlbm = 0;
0189 conf->smart_ps = 0;
0190
0191 rtw_hci_link_ps(rtwdev, false);
0192 rtw_fw_leave_lps_check_prepare(rtwdev);
0193 rtw_fw_set_pwr_mode(rtwdev);
0194 rtw_fw_leave_lps_check(rtwdev);
0195
0196 clear_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags);
0197
0198 rtw_coex_lps_notify(rtwdev, COEX_LPS_DISABLE);
0199 }
0200
0201 enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev)
0202 {
0203 if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags))
0204 return rtwdev->lps_conf.wow_deep_mode;
0205 else
0206 return rtwdev->lps_conf.deep_mode;
0207 }
0208
0209 static void __rtw_enter_lps_deep(struct rtw_dev *rtwdev)
0210 {
0211 if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_NONE)
0212 return;
0213
0214 if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) {
0215 rtw_dbg(rtwdev, RTW_DBG_PS,
0216 "Should enter LPS before entering deep PS\n");
0217 return;
0218 }
0219
0220 if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG)
0221 rtw_fw_set_pg_info(rtwdev);
0222
0223 rtw_hci_deep_ps(rtwdev, true);
0224 }
0225
0226 static void rtw_enter_lps_core(struct rtw_dev *rtwdev)
0227 {
0228 struct rtw_lps_conf *conf = &rtwdev->lps_conf;
0229
0230 conf->state = RTW_RF_OFF;
0231 conf->awake_interval = 1;
0232 conf->rlbm = 1;
0233 conf->smart_ps = 2;
0234
0235 rtw_coex_lps_notify(rtwdev, COEX_LPS_ENABLE);
0236
0237 rtw_fw_set_pwr_mode(rtwdev);
0238 rtw_hci_link_ps(rtwdev, true);
0239
0240 set_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags);
0241 }
0242
0243 static void __rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id)
0244 {
0245 struct rtw_lps_conf *conf = &rtwdev->lps_conf;
0246
0247 if (test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags))
0248 return;
0249
0250 conf->mode = RTW_MODE_LPS;
0251 conf->port_id = port_id;
0252
0253 rtw_enter_lps_core(rtwdev);
0254 }
0255
0256 static void __rtw_leave_lps(struct rtw_dev *rtwdev)
0257 {
0258 struct rtw_lps_conf *conf = &rtwdev->lps_conf;
0259
0260 if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) {
0261 rtw_dbg(rtwdev, RTW_DBG_PS,
0262 "Should leave deep PS before leaving LPS\n");
0263 __rtw_leave_lps_deep(rtwdev);
0264 }
0265
0266 if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags))
0267 return;
0268
0269 conf->mode = RTW_MODE_ACTIVE;
0270
0271 rtw_leave_lps_core(rtwdev);
0272 }
0273
0274 void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id)
0275 {
0276 lockdep_assert_held(&rtwdev->mutex);
0277
0278 if (rtwdev->coex.stat.wl_force_lps_ctrl)
0279 return;
0280
0281 __rtw_enter_lps(rtwdev, port_id);
0282 __rtw_enter_lps_deep(rtwdev);
0283 }
0284
0285 void rtw_leave_lps(struct rtw_dev *rtwdev)
0286 {
0287 lockdep_assert_held(&rtwdev->mutex);
0288
0289 __rtw_leave_lps_deep(rtwdev);
0290 __rtw_leave_lps(rtwdev);
0291 }
0292
0293 void rtw_leave_lps_deep(struct rtw_dev *rtwdev)
0294 {
0295 lockdep_assert_held(&rtwdev->mutex);
0296
0297 __rtw_leave_lps_deep(rtwdev);
0298 }