From 0b904093c012f3d3616013d73579f44fff27bedc Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Tue, 28 Apr 2026 17:47:47 +0200 Subject: [PATCH] patches: refresh c7 (hold MCU wake-flag bit on latch to spare SDIO_RX msleep) --- ...ect-when-firmware-does-not-honor-PSM.patch | 37 ++++++++++++++----- ...ect-when-firmware-does-not-honor-PSM.patch | 37 ++++++++++++++----- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/patches/pm-detect-firmware-unsupported-danctnix/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch b/patches/pm-detect-firmware-unsupported-danctnix/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch index 4533cad77..4cc6ff216 100644 --- a/patches/pm-detect-firmware-unsupported-danctnix/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch +++ b/patches/pm-detect-firmware-unsupported-danctnix/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch @@ -1,4 +1,4 @@ -From 6535458d5c7841451605953762e0c2bec562b648 Mon Sep 17 00:00:00 2001 +From 14e4a6dd3374154eba14edb8afb26effe05a2307 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Tue, 28 Apr 2026 16:54:07 +0200 Subject: [PATCH] bes2600: self-detect when firmware does not honor PSM and @@ -64,15 +64,15 @@ firing entirely. The firmware-side wedge is observed once per boot Signed-off-by: Markus Fritsche --- - drivers/staging/bes2600/bes_pwr.c | 50 +++++++++++++++++++++++++++++++ - drivers/staging/bes2600/bes_pwr.h | 9 ++++++ - 2 files changed, 59 insertions(+) + drivers/staging/bes2600/bes_pwr.c | 67 +++++++++++++++++++++++++++++++ + drivers/staging/bes2600/bes_pwr.h | 9 +++++ + 2 files changed, 76 insertions(+) diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c -index d54e1a0bab0c..d706a6ae4efe 100644 +index d54e1a0bab0c..a88ee40e7c60 100644 --- a/drivers/staging/bes2600/bes_pwr.c +++ b/drivers/staging/bes2600/bes_pwr.c -@@ -467,6 +467,28 @@ static void bes2600_pwr_device_enter_lp_mode(struct bes2600_common *hw_priv) +@@ -467,6 +467,45 @@ static void bes2600_pwr_device_enter_lp_mode(struct bes2600_common *hw_priv) bes_devel("device enter sleep\n"); } @@ -96,12 +96,29 @@ index d54e1a0bab0c..d706a6ae4efe 100644 + hw_priv->bes_power.pm_unsupported = true; + atomic_set(&hw_priv->bes_power.chip_pm_state, + BES2600_CHIP_PM_ACTIVE); ++ ++ /* ++ * Hold the MCU wake-flag bit permanently. Without this, every ++ * sdio_rx_work invocation hits bes2600_gpio_wakeup_mcu(SDIO_RX) ++ * when gpio_wakup_flags == 0, drives the GPIO high and msleeps ++ * 10 ms per RX. With ~50 RX/s of beacons + multicast that's ++ * ~50%% of the bes_sdio workqueue thread blocked in msleep, ++ * which directly caps RX throughput. Holding the MCU bit makes ++ * those calls bit-only bookkeeping (gpio_wakeup = (flags == 0) ++ * stays false, no GPIO toggle, no msleep). The bit is never ++ * cleared once pm_unsupported is set because ++ * bes2600_pwr_device_enter_lp_mode is unreachable under the ++ * early-return. ++ */ ++ if (hw_priv->sbus_ops->gpio_wake) ++ hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, ++ GPIO_WAKE_FLAG_MCU); +} + static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) { int i = 0; -@@ -476,6 +498,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) +@@ -476,6 +515,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) char ip_str[20]; unsigned long status = 0; @@ -119,7 +136,7 @@ index d54e1a0bab0c..d706a6ae4efe 100644 /* set interface low power configuration */ bes2600_for_each_vif(hw_priv, priv, i) { #ifdef P2P_MULTIVIF -@@ -571,6 +604,9 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) +@@ -571,6 +621,9 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_UNKNOWN); timeouts++; @@ -129,7 +146,7 @@ index d54e1a0bab0c..d706a6ae4efe 100644 } } } else { -@@ -932,6 +968,8 @@ void bes2600_pwr_init(struct bes2600_common *hw_priv) +@@ -932,6 +985,8 @@ void bes2600_pwr_init(struct bes2600_common *hw_priv) mutex_init(&hw_priv->bes_power.pwr_mutex); atomic_set(&hw_priv->bes_power.dev_state, 0); atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_UNKNOWN); @@ -138,7 +155,7 @@ index d54e1a0bab0c..d706a6ae4efe 100644 init_completion(&hw_priv->bes_power.pm_enter_cmpl); sema_init(&hw_priv->bes_power.sync_lock, 1); device_set_wakeup_capable(hw_priv->pdev, true); -@@ -1321,6 +1359,18 @@ void bes2600_pwr_notify_ps_changed(struct bes2600_common *hw_priv, u8 psmode) +@@ -1321,6 +1376,18 @@ void bes2600_pwr_notify_ps_changed(struct bes2600_common *hw_priv, u8 psmode) * indication can prime a future wait against a freshly * reinit_completion()'ed state. */ diff --git a/patches/pm-detect-firmware-unsupported/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch b/patches/pm-detect-firmware-unsupported/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch index 1ea58b594..056e1c1bf 100644 --- a/patches/pm-detect-firmware-unsupported/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch +++ b/patches/pm-detect-firmware-unsupported/0001-bes2600-self-detect-when-firmware-does-not-honor-PSM.patch @@ -1,4 +1,4 @@ -From a91de9e6cadb00315e06cfde292d600bacc35020 Mon Sep 17 00:00:00 2001 +From 1012716d4d92a2fc2f29407a2aba93a9c983284b Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Tue, 28 Apr 2026 16:54:06 +0200 Subject: [PATCH] bes2600: self-detect when firmware does not honor PSM and @@ -64,15 +64,15 @@ firing entirely. The firmware-side wedge is observed once per boot Signed-off-by: Markus Fritsche --- - bes2600/bes_pwr.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ - bes2600/bes_pwr.h | 9 +++++++++ - 2 files changed, 59 insertions(+) + bes2600/bes_pwr.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++ + bes2600/bes_pwr.h | 9 +++++++ + 2 files changed, 76 insertions(+) diff --git a/bes2600/bes_pwr.c b/bes2600/bes_pwr.c -index b7b6c2f..8f46a83 100644 +index b7b6c2f..5f7979d 100644 --- a/bes2600/bes_pwr.c +++ b/bes2600/bes_pwr.c -@@ -467,6 +467,28 @@ static void bes2600_pwr_device_enter_lp_mode(struct bes2600_common *hw_priv) +@@ -467,6 +467,45 @@ static void bes2600_pwr_device_enter_lp_mode(struct bes2600_common *hw_priv) bes_devel("device enter sleep\n"); } @@ -96,12 +96,29 @@ index b7b6c2f..8f46a83 100644 + hw_priv->bes_power.pm_unsupported = true; + atomic_set(&hw_priv->bes_power.chip_pm_state, + BES2600_CHIP_PM_ACTIVE); ++ ++ /* ++ * Hold the MCU wake-flag bit permanently. Without this, every ++ * sdio_rx_work invocation hits bes2600_gpio_wakeup_mcu(SDIO_RX) ++ * when gpio_wakup_flags == 0, drives the GPIO high and msleeps ++ * 10 ms per RX. With ~50 RX/s of beacons + multicast that's ++ * ~50%% of the bes_sdio workqueue thread blocked in msleep, ++ * which directly caps RX throughput. Holding the MCU bit makes ++ * those calls bit-only bookkeeping (gpio_wakeup = (flags == 0) ++ * stays false, no GPIO toggle, no msleep). The bit is never ++ * cleared once pm_unsupported is set because ++ * bes2600_pwr_device_enter_lp_mode is unreachable under the ++ * early-return. ++ */ ++ if (hw_priv->sbus_ops->gpio_wake) ++ hw_priv->sbus_ops->gpio_wake(hw_priv->sbus_priv, ++ GPIO_WAKE_FLAG_MCU); +} + static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) { int i = 0; -@@ -476,6 +498,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) +@@ -476,6 +515,17 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) char ip_str[20]; unsigned long status = 0; @@ -119,7 +136,7 @@ index b7b6c2f..8f46a83 100644 /* set interface low power configuration */ bes2600_for_each_vif(hw_priv, priv, i) { #ifdef P2P_MULTIVIF -@@ -571,6 +604,9 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) +@@ -571,6 +621,9 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv) atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_UNKNOWN); timeouts++; @@ -129,7 +146,7 @@ index b7b6c2f..8f46a83 100644 } } } else { -@@ -932,6 +968,8 @@ void bes2600_pwr_init(struct bes2600_common *hw_priv) +@@ -932,6 +985,8 @@ void bes2600_pwr_init(struct bes2600_common *hw_priv) mutex_init(&hw_priv->bes_power.pwr_mutex); atomic_set(&hw_priv->bes_power.dev_state, 0); atomic_set(&hw_priv->bes_power.chip_pm_state, BES2600_CHIP_PM_UNKNOWN); @@ -138,7 +155,7 @@ index b7b6c2f..8f46a83 100644 init_completion(&hw_priv->bes_power.pm_enter_cmpl); sema_init(&hw_priv->bes_power.sync_lock, 1); device_set_wakeup_capable(hw_priv->pdev, true); -@@ -1321,6 +1359,18 @@ void bes2600_pwr_notify_ps_changed(struct bes2600_common *hw_priv, u8 psmode) +@@ -1321,6 +1376,18 @@ void bes2600_pwr_notify_ps_changed(struct bes2600_common *hw_priv, u8 psmode) * indication can prime a future wait against a freshly * reinit_completion()'ed state. */