Files
kernel-agent/patches/driver/bes2600/pm-gate-on-handshake/0001-bes2600-gate-device-LP-mode-entry-on-successful-handshake.patch
T
claude-noether b04c8cd501 patches/driver/bes2600/*-danctnix + arch/arm64/scs-...: rebased on danctnix baseline (#29 redo)
PR #33's per-series mirrors were generated against the bes2600-dkms
cleanups branch (rooted at fe73571) without rebasing onto the
v7.0-danctnix1 kernel baseline. Result: per-commit diffs carried
stale baseline context (e.g. from_timer rather than the new
timer_container_of API), so the cumulative no longer applied cleanly
to ohm's actual base. pkgrel=6 build #1 failed with 'Hunk #3 FAILED'
in Patch D's sta.c.

Fix: in marfrit/bes2600-dkms, create danctnix-sync branch
(fe73571 + drop-in replace bes2600/ with v7.0-danctnix1's
drivers/staging/bes2600/), rebase cleanups onto it as
cleanups-rebased-on-danctnix, manually resolve the resulting conflicts
keeping each commit's intent + the new baseline context, rebase
Patch H accordingly. Format-patch and re-route to the same series-dir
names as PR #33.

Conflict resolution notes:
- 'remove userspace /dev/bes2600 character device interface' commit:
  the chardev wrapper was removed but two utility funcs that danctnix's
  bes2600_btuart.c depends on (bes2600_chrdev_is_bus_error,
  bes2600_chrdev_switch_subsys_glb) were re-added with EXPORT_SYMBOL_GPL.
  bes2600_switch_bt re-added as static (file-local, called only from
  bes2600_chrdev_switch_subsys_glb).
- Patch D (atomicize ba_lock): re-resolved bes2600_ba_timer's
  timer_container_of() vs from_timer() to keep the new API.
- SCS Makefile @@ hunk counts corrected from -9,6 +9,10 to -9,6 +9,11
  (the original was actually wrong; build-via-fuzz was masking it).

Cumulative b2sum: ka-promote ohm now emits
  eb179c03f35a4dbaec2e40036f0033ef04985bb6b14ab22419d68e5caaa5874f...
  (279 554 bytes, 32 patches resolved).

pkgrel=6 built from this manifest + installed on ohm 2026-05-19 ~23:39.
Functional verification: bes2600 + bes2600_btuart both load, Pattern A
0 over fresh boot, wlan0 associates to newton. srcversion
1A919EED0E6DC2478559B17 differs from pkgrel=5's BEB625FA... — the
reconstruction is functionally equivalent (5 GHz working, no
firmware/driver race conditions) but NOT byte-equivalent (the chardev
utility re-add chose different formatting than the original danctnix
code). Byte-equivalence is not a goal; per-series traceability and
working hardware are.

Closes (proper this time): #29.
Refs: #28, #30, #33 (the half-working attempt), #31, #32.
2026-05-19 23:44:29 +02:00

106 lines
3.8 KiB
Diff

From e8550e55fc7d3910ee690359d89d96c86cfb0347 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <fritsche.markus@gmail.com>
Date: Wed, 22 Apr 2026 12:37:45 +0200
Subject: [PATCH 04/29] bes2600: gate device LP-mode entry on successful
per-VIF firmware handshake
bes2600_pwr_enter_lp_mode() drives the transition to low-power for each
associated STA VIF: it pushes wsm_set_pm(), waits up to 5 seconds on
pm_enter_cmpl for the firmware to acknowledge, then unconditionally
calls bes2600_pwr_device_enter_lp_mode() to drop the device end of the
bus.
Two bugs:
1. A failed wsm_set_pm() only logs an error, then still falls into
wait_for_completion_timeout() on a completion the firmware will
never post (the set-mode command never reached it). The loop
therefore always blocks the full 5 s, logs a second error, and
proceeds.
2. A genuine wait-timeout (firmware received the set-mode command but
never posted the indication) also only logs a warning. The code
then drops to bes2600_pwr_device_enter_lp_mode(), handing the
device subsystem an inconsistent view of mac-layer state.
On PineTab2 (BES2600WM + RK3566) the second bug is the recurring
root-cause of the 'bes2600_pwr_enter_lp_mode, wait pm ind timeout'
message flooding dmesg every 5-10 s when the interface is associated
and idle. Sending the device to LP in that state cascades into the
SDIO TX path as the 'bes_sdio_memcpy_to_io_helper / sdio_tx_work'
WARN splat.
Fix:
- Add a 'timeouts' counter; bump it on both failure paths.
- Skip the wait_for_completion entirely when wsm_set_pm() failed
(there is no completion to wait for).
- Only call bes2600_pwr_device_enter_lp_mode() when every per-VIF
handshake reached firmware-ACKed completion; otherwise return
-ETIMEDOUT and leave the device in its current power state.
Tested-on: PineTab2 running linux-pinetab2 6.19.10-danctnix1-1.
Post-patch the handshake still fails on this particular firmware
revision (separate root-cause investigation outside this patch), but
the driver now returns -ETIMEDOUT cleanly instead of flooding dmesg
and destabilising the SDIO path.
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
---
bes2600/bes_pwr.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/bes2600/bes_pwr.c b/drivers/staging/bes2600/bes_pwr.c
index e7a1045..f62ae22 100644
--- a/drivers/staging/bes2600/bes_pwr.c
+++ b/drivers/staging/bes2600/bes_pwr.c
@@ -472,6 +472,7 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
int i = 0;
struct bes2600_vif *priv;
int ret = 0;
+ int timeouts = 0;
char ip_str[20];
unsigned long status = 0;
@@ -528,22 +529,35 @@ static int bes2600_pwr_enter_lp_mode(struct bes2600_common *hw_priv)
if (ret) {
atomic_set(&hw_priv->bes_power.pm_set_in_process, 0);
bes_err("%s, set operation mode fail\n", __func__);
+ timeouts++;
+ continue;
}
/* wait power save mode changed indication */
status = wait_for_completion_timeout(&hw_priv->bes_power.pm_enter_cmpl, 5 * HZ);
atomic_set(&hw_priv->bes_power.pm_set_in_process, 0);
reinit_completion(&hw_priv->bes_power.pm_enter_cmpl);
- if (!status)
+ if (!status) {
bes_err("%s, wait pm ind timeout\n", __func__);
+ timeouts++;
+ }
} else {
bes_devel("skip enter lp mode\n");
}
}
}
- /* set device low power configuration */
- bes2600_pwr_device_enter_lp_mode(hw_priv);
+ /*
+ * Enter the device-end of the LP transition only if every per-VIF
+ * mac80211 handshake reached firmware-ACKed completion. Doing the
+ * device-LP setup while any VIF is still pending leaves the driver
+ * in an inconsistent state that cascades into SDIO TX errors on
+ * the BES2600.
+ */
+ if (timeouts == 0)
+ bes2600_pwr_device_enter_lp_mode(hw_priv);
+ else
+ ret = -ETIMEDOUT;
return ret;
}
--
2.54.0