Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
0002 /* Copyright(c) 2018-2019  Realtek Corporation
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     /* toggle to request power mode, others remain 0 */
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     /* Each request require an ack from firmware */
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     /* Check firmware get the power requset and ack via cpwm register */
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         /* Hit here means that driver failed to get an ack from firmware.
0098          * The reason could be that hardware is locked at Deep sleep,
0099          * so most of the hardware circuits are not working, even
0100          * register read/write; or firmware is locked in some state and
0101          * cannot get the request. It should be treated as fatal error
0102          * and requires an entire analysis about the firmware/hardware.
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     /* Driver needs to wait for firmware to leave LPS state
0120      * successfully. Firmware will send null packet to inform AP,
0121      * and see if AP sends an ACK back, then firmware will restore
0122      * the REG_TCR register.
0123      *
0124      * If driver does not wait for firmware, null packet with
0125      * PS bit could be sent due to incorrect REG_TCR setting.
0126      *
0127      * In our test, 100ms should be enough for firmware to finish
0128      * the flow. If REG_TCR Register is still incorrect after 100ms,
0129      * just modify it directly, and throw a warn message.
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 }