From patchwork Fri Oct 30 08:48:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Huang X-Patchwork-Id: 315609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5EE2BC4741F for ; Fri, 30 Oct 2020 08:48:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F24A72083B for ; Fri, 30 Oct 2020 08:48:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726017AbgJ3Isz (ORCPT ); Fri, 30 Oct 2020 04:48:55 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:50440 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725355AbgJ3Isz (ORCPT ); Fri, 30 Oct 2020 04:48:55 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.73 with qID 09U8mlf87013488, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb04.realtek.com.tw[172.21.6.97]) by rtits2.realtek.com.tw (8.15.2/2.70/5.88) with ESMTPS id 09U8mlf87013488 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Oct 2020 16:48:47 +0800 Received: from localhost.localdomain (172.21.69.222) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Fri, 30 Oct 2020 16:48:46 +0800 From: To: , CC: , Subject: [PATCH v2 1/4] rtw88: sync the power state between driver and firmware Date: Fri, 30 Oct 2020 16:48:23 +0800 Message-ID: <20201030084826.9034-2-tehuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201030084826.9034-1-tehuang@realtek.com> References: <20201030084826.9034-1-tehuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.69.222] X-ClientProxiedBy: RTEXMB03.realtek.com.tw (172.21.6.96) To RTEXMB04.realtek.com.tw (172.21.6.97) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Chin-Yen Lee In current flow, driver issues power requests to firmware for entering or leaving deep power mode. But driver does not wait for an ack from firmware via reading CPWM register when driver requests to enter deep power mode. The behavior will lead to unsynchronized state between firmware and driver. Furthermore, consecutive same power requests may confuse firmware and leads to unexpected value of CPWM register. This patch ensures that the power request will wait for an ack from firmware and only send one power request each time. Signed-off-by: Chin-Yen Lee Signed-off-by: Tzu-En Huang --- drivers/net/wireless/realtek/rtw88/ps.c | 69 +++++++++++-------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c index 7a189a9926fe..8ed243628dcb 100644 --- a/drivers/net/wireless/realtek/rtw88/ps.c +++ b/drivers/net/wireless/realtek/rtw88/ps.c @@ -68,48 +68,39 @@ int rtw_leave_ips(struct rtw_dev *rtwdev) void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter) { u8 request, confirm, polling; - u8 polling_cnt; - u8 retry_cnt = 0; - - for (retry_cnt = 0; retry_cnt < 3; retry_cnt++) { - request = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); - confirm = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr); - - /* toggle to request power mode, others remain 0 */ - request ^= request | BIT_RPWM_TOGGLE; - if (!enter) { - request |= POWER_MODE_ACK; - } else { - request |= POWER_MODE_LCLK; - if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG) - request |= POWER_MODE_PG; - } - - rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request); - - if (enter) - return; + int ret; - /* check confirm power mode has left power save state */ - for (polling_cnt = 0; polling_cnt < 50; polling_cnt++) { - polling = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr); - if ((polling ^ confirm) & BIT_RPWM_TOGGLE) - return; - udelay(100); - } - - /* in case of fw/hw missed the request, retry */ - rtw_warn(rtwdev, "failed to leave deep PS, retry=%d\n", - retry_cnt); + request = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); + confirm = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr); + + /* toggle to request power mode, others remain 0 */ + request ^= request | BIT_RPWM_TOGGLE; + if (enter) { + request |= POWER_MODE_LCLK; + if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG) + request |= POWER_MODE_PG; } + /* Each request require an ack from firmware */ + request |= POWER_MODE_ACK; - /* Hit here means that driver failed to change hardware power mode to - * active state after retry 3 times. If the power state is locked at - * Deep sleep, most of the hardware circuits is not working, even - * register read/write. It should be treated as fatal error and - * requires an entire analysis about the firmware/hardware - */ - WARN(1, "Hardware power state locked\n"); + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request); + + /* Check firmware get the power requset and ack via cpwm register */ + ret = read_poll_timeout_atomic(rtw_read8, polling, + (polling ^ confirm) & BIT_RPWM_TOGGLE, + 100, 15000, true, rtwdev, + rtwdev->hci.cpwm_addr); + if (ret) { + /* Hit here means that driver failed to get an ack from firmware. + * The reason could be that hardware is locked at Deep sleep, + * so most of the hardware circuits are not working, even + * register read/write; or firmware is locked in some state and + * cannot get the request. It should be treated as fatal error + * and requires an entire analysis about the firmware/hardware. + */ + WARN(1, "firmware failed to ack driver for %s Deep Power mode\n", + enter ? "entering" : "leaving"); + } } EXPORT_SYMBOL(rtw_power_mode_change); From patchwork Fri Oct 30 08:48:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Huang X-Patchwork-Id: 315608 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1D90C55179 for ; Fri, 30 Oct 2020 08:48:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 957692083B for ; Fri, 30 Oct 2020 08:48:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726052AbgJ3Is4 (ORCPT ); Fri, 30 Oct 2020 04:48:56 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:50441 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725948AbgJ3Isz (ORCPT ); Fri, 30 Oct 2020 04:48:55 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.73 with qID 09U8mlfA7013488, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb04.realtek.com.tw[172.21.6.97]) by rtits2.realtek.com.tw (8.15.2/2.70/5.88) with ESMTPS id 09U8mlfA7013488 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Oct 2020 16:48:47 +0800 Received: from localhost.localdomain (172.21.69.222) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Fri, 30 Oct 2020 16:48:46 +0800 From: To: , CC: , Subject: [PATCH v2 2/4] rtw88: store firmware feature in firmware header Date: Fri, 30 Oct 2020 16:48:24 +0800 Message-ID: <20201030084826.9034-3-tehuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201030084826.9034-1-tehuang@realtek.com> References: <20201030084826.9034-1-tehuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.69.222] X-ClientProxiedBy: RTEXMB03.realtek.com.tw (172.21.6.96) To RTEXMB04.realtek.com.tw (172.21.6.97) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Chin-Yen Lee Some functions need the support of firmware with special version. In order to get the feature of current firmware, we store the information in firmware header and parse after firmware is loaded. The current feature list in firmware header includes checking leave lps via C2H and supported lps deep mode. Signed-off-by: Chin-Yen Lee Signed-off-by: Tzu-En Huang --- drivers/net/wireless/realtek/rtw88/fw.h | 10 +++++++++- drivers/net/wireless/realtek/rtw88/main.c | 13 +++++++++++++ drivers/net/wireless/realtek/rtw88/main.h | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.h b/drivers/net/wireless/realtek/rtw88/fw.h index 08644540d259..5b74830c4d2c 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.h +++ b/drivers/net/wireless/realtek/rtw88/fw.h @@ -72,6 +72,14 @@ enum rtw_fw_rf_type { FW_RF_MAX_TYPE = 0xF, }; +enum rtw_fw_feature { + FW_FEATURE_SIG = BIT(0), + FW_FEATURE_LPS_C2H = BIT(1), + FW_FEATURE_LCLK = BIT(2), + FW_FEATURE_PG = BIT(3), + FW_FEATURE_MAX = BIT(31), +}; + struct rtw_coex_info_req { u8 seq; u8 op_code; @@ -177,7 +185,7 @@ struct rtw_fw_hdr { u8 subversion; u8 subindex; __le32 rsvd; /* 0x08 */ - __le32 rsvd2; /* 0x0C */ + __le32 feature; /* 0x0C */ u8 month; /* 0x10 */ u8 day; u8 hour; diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 565efd880624..259ad849af93 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -1259,6 +1259,17 @@ static void rtw_unset_supported_band(struct ieee80211_hw *hw, kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); } +static void __update_firmware_feature(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + u32 feature; + const struct rtw_fw_hdr *fw_hdr = + (const struct rtw_fw_hdr *)fw->firmware->data; + + feature = le32_to_cpu(fw_hdr->feature); + fw->feature = feature & FW_FEATURE_SIG ? feature : 0; +} + static void __update_firmware_info(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) { @@ -1269,6 +1280,8 @@ static void __update_firmware_info(struct rtw_dev *rtwdev, fw->version = le16_to_cpu(fw_hdr->version); fw->sub_version = fw_hdr->subversion; fw->sub_index = fw_hdr->subindex; + + __update_firmware_feature(rtwdev, fw); } static void __update_firmware_info_legacy(struct rtw_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index ffb02e614217..b00235573a13 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -1633,6 +1633,7 @@ struct rtw_fw_state { u8 sub_index; u16 h2c_version; u8 prev_dump_seq; + u32 feature; }; struct rtw_hal { From patchwork Fri Oct 30 08:48:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Huang X-Patchwork-Id: 315607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE68DC00A89 for ; Fri, 30 Oct 2020 08:49:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9610E20704 for ; Fri, 30 Oct 2020 08:49:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726067AbgJ3Is6 (ORCPT ); Fri, 30 Oct 2020 04:48:58 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:50448 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725993AbgJ3Isz (ORCPT ); Fri, 30 Oct 2020 04:48:55 -0400 Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.73 with qID 09U8mlfC7013488, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexmb04.realtek.com.tw[172.21.6.97]) by rtits2.realtek.com.tw (8.15.2/2.70/5.88) with ESMTPS id 09U8mlfC7013488 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Oct 2020 16:48:47 +0800 Received: from localhost.localdomain (172.21.69.222) by RTEXMB04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2044.4; Fri, 30 Oct 2020 16:48:47 +0800 From: To: , CC: , Subject: [PATCH v2 4/4] rtw88: decide lps deep mode from firmware feature. Date: Fri, 30 Oct 2020 16:48:26 +0800 Message-ID: <20201030084826.9034-5-tehuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201030084826.9034-1-tehuang@realtek.com> References: <20201030084826.9034-1-tehuang@realtek.com> MIME-Version: 1.0 X-Originating-IP: [172.21.69.222] X-ClientProxiedBy: RTEXMB03.realtek.com.tw (172.21.6.96) To RTEXMB04.realtek.com.tw (172.21.6.97) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Chin-Yen Lee This patch checks the supported lps deep mode from firmware feature, and allows different firmware have different deep power mode. Original module parameter rtw_fw_lps_deep_mode is replaced with rtw_disable_lps_deep_mode for user to disable lps deep mode. Signed-off-by: Chin-Yen Lee Signed-off-by: Tzu-En Huang --- drivers/net/wireless/realtek/rtw88/fw.c | 3 +- drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +- drivers/net/wireless/realtek/rtw88/main.c | 36 ++++++++++++++----- drivers/net/wireless/realtek/rtw88/main.h | 3 +- drivers/net/wireless/realtek/rtw88/ps.c | 14 ++++++-- drivers/net/wireless/realtek/rtw88/ps.h | 2 +- drivers/net/wireless/realtek/rtw88/wow.c | 5 +-- 7 files changed, 48 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index 29fffacf4085..3cd46759802c 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -13,6 +13,7 @@ #include "debug.h" #include "util.h" #include "wow.h" +#include "ps.h" static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, struct sk_buff *skb) @@ -631,7 +632,7 @@ void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable) SET_NLO_FUN_EN(h2c_pkt, enable); if (enable) { - if (rtw_fw_lps_deep_mode) + if (rtw_get_lps_deep_mode(rtwdev) != LPS_DEEP_MODE_NONE) SET_NLO_PS_32K(h2c_pkt, enable); SET_NLO_IGNORE_SECURITY(h2c_pkt, enable); SET_NLO_LOC_NLO_INFO(h2c_pkt, loc_nlo); diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index c92fba2fa480..c69397719fdf 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -519,7 +519,7 @@ static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } /* download new cam settings for PG to backup */ - if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG) + if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG) rtw_fw_download_rsvd_page(rtwdev); out: diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 5c46f5d2e87c..71d90b98d6f1 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -16,17 +16,17 @@ #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"); @@ -1023,6 +1023,26 @@ static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) 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; @@ -1097,6 +1117,9 @@ int rtw_core_start(struct rtw_dev *rtwdev) 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); @@ -1657,10 +1680,6 @@ int rtw_core_init(struct rtw_dev *rtwdev) 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); @@ -1685,6 +1704,7 @@ int rtw_core_init(struct rtw_dev *rtwdev) return ret; } } + return 0; } EXPORT_SYMBOL(rtw_core_init); diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 53ddd8661c44..bbfc3312eef5 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -37,7 +37,7 @@ #define RTW_TP_SHIFT 18 /* bytes/2s --> Mbps */ extern bool rtw_bf_support; -extern unsigned int rtw_fw_lps_deep_mode; +extern bool rtw_disable_lps_deep_mode; extern unsigned int rtw_debug_mask; extern const struct ieee80211_ops rtw_ops; @@ -664,6 +664,7 @@ enum rtw_pwr_state { struct rtw_lps_conf { enum rtw_lps_mode mode; enum rtw_lps_deep_mode deep_mode; + enum rtw_lps_deep_mode wow_deep_mode; enum rtw_pwr_state state; u8 awake_interval; u8 rlbm; diff --git a/drivers/net/wireless/realtek/rtw88/ps.c b/drivers/net/wireless/realtek/rtw88/ps.c index 233b3df264b3..3bead34c3d10 100644 --- a/drivers/net/wireless/realtek/rtw88/ps.c +++ b/drivers/net/wireless/realtek/rtw88/ps.c @@ -77,7 +77,7 @@ void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter) 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 */ @@ -195,9 +195,17 @@ static void rtw_leave_lps_core(struct rtw_dev *rtwdev) 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)) { @@ -206,7 +214,7 @@ static void __rtw_enter_lps_deep(struct rtw_dev *rtwdev) 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); diff --git a/drivers/net/wireless/realtek/rtw88/ps.h b/drivers/net/wireless/realtek/rtw88/ps.h index 915b200081fc..7819391c8663 100644 --- a/drivers/net/wireless/realtek/rtw88/ps.h +++ b/drivers/net/wireless/realtek/rtw88/ps.h @@ -21,5 +21,5 @@ void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter); void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id); void rtw_leave_lps(struct rtw_dev *rtwdev); void rtw_leave_lps_deep(struct rtw_dev *rtwdev); - +enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev); #endif diff --git a/drivers/net/wireless/realtek/rtw88/wow.c b/drivers/net/wireless/realtek/rtw88/wow.c index 2fcdf70a3a77..b419bc28861f 100644 --- a/drivers/net/wireless/realtek/rtw88/wow.c +++ b/drivers/net/wireless/realtek/rtw88/wow.c @@ -555,7 +555,7 @@ static int rtw_wow_leave_no_link_ps(struct rtw_dev *rtwdev) 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)) { @@ -616,7 +616,8 @@ static int rtw_wow_enter_ps(struct rtw_dev *rtwdev) 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;