#include "debug.h"
 #include "bf.h"
 
-unsigned int rtw_fw_lps_deep_mode;
-EXPORT_SYMBOL(rtw_fw_lps_deep_mode);
+bool rtw_disable_lps_deep_mode;
+EXPORT_SYMBOL(rtw_disable_lps_deep_mode);
 bool rtw_bf_support = true;
 unsigned int rtw_debug_mask;
 EXPORT_SYMBOL(rtw_debug_mask);
 
-module_param_named(lps_deep_mode, rtw_fw_lps_deep_mode, uint, 0644);
+module_param_named(disable_lps_deep, rtw_disable_lps_deep_mode, bool, 0644);
 module_param_named(support_bf, rtw_bf_support, bool, 0644);
 module_param_named(debug_mask, rtw_debug_mask, uint, 0644);
 
-MODULE_PARM_DESC(lps_deep_mode, "Deeper PS mode. If 0, deep PS is disabled");
+MODULE_PARM_DESC(disable_lps_deep, "Set Y to disable Deep PS");
 MODULE_PARM_DESC(support_bf, "Set Y to enable beamformee support");
 MODULE_PARM_DESC(debug_mask, "Debugging mask");
 
        return 0;
 }
 
+static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
+                                                      struct rtw_fw_state *fw)
+{
+       struct rtw_chip_info *chip = rtwdev->chip;
+
+       if (rtw_disable_lps_deep_mode || !chip->lps_deep_mode_supported ||
+           !fw->feature)
+               return LPS_DEEP_MODE_NONE;
+
+       if ((chip->lps_deep_mode_supported & BIT(LPS_DEEP_MODE_PG)) &&
+           (fw->feature & FW_FEATURE_PG))
+               return LPS_DEEP_MODE_PG;
+
+       if ((chip->lps_deep_mode_supported & BIT(LPS_DEEP_MODE_LCLK)) &&
+           (fw->feature & FW_FEATURE_LCLK))
+               return LPS_DEEP_MODE_LCLK;
+
+       return LPS_DEEP_MODE_NONE;
+}
+
 static int rtw_power_on(struct rtw_dev *rtwdev)
 {
        struct rtw_chip_info *chip = rtwdev->chip;
 
        rtw_sec_enable_sec_engine(rtwdev);
 
+       rtwdev->lps_conf.deep_mode = rtw_update_lps_deep_mode(rtwdev, &rtwdev->fw);
+       rtwdev->lps_conf.wow_deep_mode = rtw_update_lps_deep_mode(rtwdev, &rtwdev->wow_fw);
+
        /* rcr reset after powered on */
        rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
 
        rtwdev->sec.total_cam_num = 32;
        rtwdev->hal.current_channel = 1;
        set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map);
-       if (!(BIT(rtw_fw_lps_deep_mode) & chip->lps_deep_mode_supported))
-               rtwdev->lps_conf.deep_mode = LPS_DEEP_MODE_NONE;
-       else
-               rtwdev->lps_conf.deep_mode = rtw_fw_lps_deep_mode;
 
        rtw_stats_init(rtwdev);
 
                        return ret;
                }
        }
+
        return 0;
 }
 EXPORT_SYMBOL(rtw_core_init);
 
        request ^= request | BIT_RPWM_TOGGLE;
        if (enter) {
                request |= POWER_MODE_LCLK;
-               if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG)
+               if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG)
                        request |= POWER_MODE_PG;
        }
        /* Each request require an ack from firmware */
        rtw_coex_lps_notify(rtwdev, COEX_LPS_DISABLE);
 }
 
+enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev)
+{
+       if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags))
+               return rtwdev->lps_conf.wow_deep_mode;
+       else
+               return rtwdev->lps_conf.deep_mode;
+}
+
 static void __rtw_enter_lps_deep(struct rtw_dev *rtwdev)
 {
-       if (rtwdev->lps_conf.deep_mode == LPS_DEEP_MODE_NONE)
+       if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_NONE)
                return;
 
        if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) {
                return;
        }
 
-       if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG)
+       if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG)
                rtw_fw_set_pg_info(rtwdev);
 
        rtw_hci_deep_ps(rtwdev, true);
 
        int ret = 0;
 
        if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) {
-               if (rtw_fw_lps_deep_mode)
+               if (rtw_get_lps_deep_mode(rtwdev) != LPS_DEEP_MODE_NONE)
                        rtw_leave_lps_deep(rtwdev);
        } else {
                if (test_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags)) {
 
        if (rtw_wow_mgd_linked(rtwdev))
                ret = rtw_wow_enter_linked_ps(rtwdev);
-       else if (rtw_wow_no_link(rtwdev) && rtw_fw_lps_deep_mode)
+       else if (rtw_wow_no_link(rtwdev) &&
+                rtw_get_lps_deep_mode(rtwdev) != LPS_DEEP_MODE_NONE)
                ret = rtw_wow_enter_no_link_ps(rtwdev);
 
        return ret;