diff mbox series

[rtw-next,v2,06/14] wifi: rtw89: Disable deep power saving for USB/SDIO

Message ID 1e25d8b6-fb5c-4733-81ec-b9ae9bbd8f92@gmail.com
State New
Headers show
Series wifi: rtw89: Add support for USB devices | expand

Commit Message

Bitterblue Smith June 9, 2025, 7:28 p.m. UTC
Disable rtw89_mac_send_rpwm() for USB and SDIO because it is called in
atomic context and accessing hardware registers results in "scheduling
while atomic" errors.

Disable rtw89_mac_power_mode_change() because it prints an error message
when rtw89_mac_send_rpwm() is disabled.

Modify rtw89_ps_power_mode_change() to call
rtw89_ps_power_mode_change_with_hci() only for PCI because the latter
is probably relevant only for PCI and also because it calls
napi_schedule(), which results in dereferencing a null pointer with USB.

For USB and SDIO rtw89_ps_power_mode_change() probably needs to call
rtw89_mac_power_mode_change() instead, in case deep power saving is ever
enabled for USB or SDIO.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
---
v2:
 - Disable deep power saving for SDIO also.
 - Don't disable rtw89_ps_power_mode_change() for USB/SDIO.
 - Disable rtw89_mac_power_mode_change() for USB/SDIO.
 - Call rtw89_ps_power_mode_change_with_hci() only for PCI and call
   rtw89_mac_power_mode_change() for USB/SDIO.
 - Update the commit message.
---
 drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++
 drivers/net/wireless/realtek/rtw89/ps.c  | 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

Comments

Ping-Ke Shih June 16, 2025, 1:42 a.m. UTC | #1
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> Disable rtw89_mac_send_rpwm() for USB and SDIO because it is called in
> atomic context and accessing hardware registers results in "scheduling
> while atomic" errors.
> 
> Disable rtw89_mac_power_mode_change() because it prints an error message
> when rtw89_mac_send_rpwm() is disabled.
> 
> Modify rtw89_ps_power_mode_change() to call
> rtw89_ps_power_mode_change_with_hci() only for PCI because the latter
> is probably relevant only for PCI and also because it calls
> napi_schedule(), which results in dereferencing a null pointer with USB.
> 
> For USB and SDIO rtw89_ps_power_mode_change() probably needs to call
> rtw89_mac_power_mode_change() instead, in case deep power saving is ever
> enabled for USB or SDIO.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
> ---
> v2:
>  - Disable deep power saving for SDIO also.
>  - Don't disable rtw89_ps_power_mode_change() for USB/SDIO.
>  - Disable rtw89_mac_power_mode_change() for USB/SDIO.
>  - Call rtw89_ps_power_mode_change_with_hci() only for PCI and call
>    rtw89_mac_power_mode_change() for USB/SDIO.
>  - Update the commit message.
> ---
>  drivers/net/wireless/realtek/rtw89/mac.c | 6 ++++++
>  drivers/net/wireless/realtek/rtw89/ps.c  | 3 ++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
> index 7f3c816d4704..2cebde9e9229 100644
> --- a/drivers/net/wireless/realtek/rtw89/mac.c
> +++ b/drivers/net/wireless/realtek/rtw89/mac.c
> @@ -1336,6 +1336,9 @@ static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev,
>  {
>         u16 request;
> 
> +       if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE)
> +               return;
> +

I think we can just return RTW89_PS_MODE_NONE in rtw89_update_ps_mode()
for hci.type != RTW89_HCI_TYPE_PCIE.

If not, I would like to define a 'rtwdev->hci.can_deep_ps' for the purpose
to disable deep PS temporarily. Sometime we can support it by just removing
this flag simply. But not very prefer this way though.
diff mbox series

Patch

diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 7f3c816d4704..2cebde9e9229 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -1336,6 +1336,9 @@  static void rtw89_mac_send_rpwm(struct rtw89_dev *rtwdev,
 {
 	u16 request;
 
+	if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE)
+		return;
+
 	spin_lock_bh(&rtwdev->rpwm_lock);
 
 	request = rtw89_read16(rtwdev, R_AX_RPWM);
@@ -1412,6 +1415,9 @@  void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
 	int ret;
 	int i;
 
+	if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE)
+		return;
+
 	if (enter)
 		state = rtw89_mac_get_req_pwr_state(rtwdev);
 	else
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index 8e4fe73e7d77..9f63655b7568 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -57,7 +57,8 @@  static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev,
 static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
 {
 	if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode) &&
-	    !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags))
+	    !test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags) &&
+	    rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
 		rtw89_ps_power_mode_change_with_hci(rtwdev, enter);
 	else
 		rtw89_mac_power_mode_change(rtwdev, enter);