danctnix-besser: add patch 0022 wsm_join_confirm reset (pkgrel=6)
Picks up the fix for besser#25 (cw1200-derived) from branch bes2600/join-confirm-failure-reset in marfrit/bes2600-dkms. After wsm_join_confirm returns status 1, the driver previously left the firmware in a post-rejection intermediate state. A rapid second JOIN attempt (e.g. wpa_supplicant retrying after the PREV_AUTH_NOT_VALID deauth that mac80211 emits) then hit an inconsistent firmware context, producing the bes2600_sdio_read_rx_batch sdio read error -> wifi_force_close -> WARN_ON at tx_loop_set_enable cascade observed in pkgrel=5 boot -1 (near wohnzimmer 5 GHz AP). Patch 0022 adds direct wsm_reset in the failure path and queues unjoin_work for serialisation matching cw1200 sta.c:1339-1344. Build verification pending; soak test acceptance per besser#25 (8h near wohnzimmer 5 GHz, no cascade after observed JOIN reject). Signed-off-by: Claude (noether) <claude@reauktion.de>
This commit is contained in:
+130
@@ -0,0 +1,130 @@
|
||||
From 8dcacc4af92b1652022954aee772b436f1c339bc Mon Sep 17 00:00:00 2001
|
||||
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
Date: Thu, 21 May 2026 09:25:12 +0200
|
||||
Subject: [PATCH] bes2600: reset firmware state on wsm_join_confirm failure
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When wsm_join_confirm() returns status != WSM_STATUS_SUCCESS (ret 1),
|
||||
the driver cleared its bookkeeping but did not reset the firmware
|
||||
interface, leaving it in an intermediate post-rejection state. A rapid
|
||||
second JOIN attempt (e.g. wpa_supplicant retrying after the
|
||||
PREV_AUTH_NOT_VALID deauth that mac80211 emits to clean up) hits an
|
||||
inconsistent firmware context, causing bes2600_sdio_read_rx_batch to
|
||||
return SDIO error which cascades into wifi_force_close:
|
||||
|
||||
wsm_join_confirm ret 1
|
||||
deauthenticating from <bssid> by local choice (Reason: 2=PREV_AUTH_NOT_VALID)
|
||||
[~10 min later]
|
||||
bes2600_sdio_read_rx_batch sdio read error
|
||||
WARNING: at bes2600_tx_loop_set_enable / bes2600_chrdev_wifi_force_close
|
||||
|
||||
Two additions to the failure path in bes2600_join_work():
|
||||
|
||||
1. wsm_reset (WSM_REQ_ID_RESET, 0x000A) with reset_statistics=false.
|
||||
This returns the firmware to IDLE so the next association attempt
|
||||
starts from a known-clean state. bes2600_unjoin_work() performs the
|
||||
same reset, but gates it on join_status != PASSIVE; after a failed
|
||||
JOIN join_status stays PASSIVE, so that path never fires — call
|
||||
wsm_reset directly here instead.
|
||||
|
||||
Contract: wsm_reset takes only wsm_cmd_lock (not conf_lock, not
|
||||
wsm_oper_lock). wsm_oper_unlock was already called inside
|
||||
wsm_join_confirm() before wsm_join() returned -EINVAL, so there is
|
||||
no re-entrancy hazard. conf_lock is held at this call site, which is
|
||||
compatible with wsm_reset's locking requirements.
|
||||
|
||||
2. queue_work(workqueue, &priv->unjoin_work) instead of direct
|
||||
wsm_unlock_tx(). Serialises the next association attempt through
|
||||
the workqueue so it cannot race against lingering firmware-side
|
||||
effects of the failure. If unjoin_work is already queued, release
|
||||
TX immediately (matching cw1200 ancestor sta.c:1344 comment "Tx lock
|
||||
still held, unjoin will clear it.").
|
||||
|
||||
Ancestor reference: drivers/net/wireless/st/cw1200/sta.c, function
|
||||
cw1200_join_work(), lines 1339-1344. cw1200 queues unjoin_work on join
|
||||
failure for the same reason. bes2600 needs the direct wsm_reset in
|
||||
addition because its unjoin_work has the join_status gate that cw1200's
|
||||
cw1200_do_unjoin() does not.
|
||||
|
||||
Signed-off-by: Claude (noether) <claude@reauktion.de>
|
||||
---
|
||||
bes2600/sta.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 43 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/bes2600/sta.c b/drivers/staging/bes2600/sta.c
|
||||
index 476d875..bf86835 100644
|
||||
--- a/drivers/staging/bes2600/sta.c
|
||||
+++ b/drivers/staging/bes2600/sta.c
|
||||
@@ -2225,9 +2225,10 @@ void bes2600_join_work(struct work_struct *work)
|
||||
struct wsm_template_frame probe_tmp = {
|
||||
.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
|
||||
};
|
||||
- /*struct wsm_reset reset = {
|
||||
- .reset_statistics = true,
|
||||
- };*/
|
||||
+ struct wsm_reset join_fail_reset = {
|
||||
+ .reset_statistics = false,
|
||||
+ };
|
||||
+ bool join_failed = false;
|
||||
|
||||
|
||||
BUG_ON(queueId >= 4);
|
||||
@@ -2410,6 +2411,33 @@ void bes2600_join_work(struct work_struct *work)
|
||||
#endif /*CONFIG_BES2600_TESTMODE*/
|
||||
cancel_delayed_work_sync(&priv->join_timeout);
|
||||
bes2600_pwr_clear_busy_event(priv->hw_priv, BES_PWR_LOCK_ON_JOIN);
|
||||
+ /*
|
||||
+ * Firmware rejected WSM_JOIN (wsm_join_confirm ret 1).
|
||||
+ * Issue wsm_reset so the firmware returns to a clean
|
||||
+ * IDLE state before the next association attempt.
|
||||
+ *
|
||||
+ * Without this reset the firmware sits in an
|
||||
+ * intermediate post-reject state. A rapid second
|
||||
+ * JOIN (e.g. wpa_supplicant retrying after the
|
||||
+ * PREV_AUTH_NOT_VALID deauth that follows) hits an
|
||||
+ * inconsistent firmware context, causing
|
||||
+ * bes2600_sdio_read_rx_batch to return SDIO error
|
||||
+ * which cascades into wifi_force_close.
|
||||
+ *
|
||||
+ * cw1200 ancestor (drivers/net/wireless/st/cw1200/
|
||||
+ * sta.c:1339) queues unjoin_work on join failure for
|
||||
+ * the same reason; bes2600_unjoin_work gates its
|
||||
+ * wsm_reset on join_status != PASSIVE, so after a
|
||||
+ * failed JOIN (join_status stays PASSIVE) that path
|
||||
+ * never fires — call wsm_reset directly here instead.
|
||||
+ *
|
||||
+ * Contract: wsm_reset takes only wsm_cmd_lock; safe
|
||||
+ * to call while conf_lock is held. wsm_oper_unlock
|
||||
+ * was already called in wsm_join_confirm() before
|
||||
+ * wsm_join() returned the error.
|
||||
+ */
|
||||
+ WARN_ON(wsm_reset(hw_priv, &join_fail_reset, priv->if_id));
|
||||
+ join_failed = true;
|
||||
} else {
|
||||
/* Upload keys */
|
||||
#ifdef CONFIG_BES2600_TESTMODE
|
||||
@@ -2434,7 +2462,18 @@ void bes2600_join_work(struct work_struct *work)
|
||||
up(&hw_priv->conf_lock);
|
||||
if (bss)
|
||||
cfg80211_put_bss(hw_priv->hw->wiphy, bss);
|
||||
- wsm_unlock_tx(hw_priv);
|
||||
+ /*
|
||||
+ * On join failure: queue unjoin_work so the next association
|
||||
+ * attempt is serialised after any lingering cleanup, matching
|
||||
+ * cw1200 sta.c:1344 "Tx lock still held, unjoin will clear it."
|
||||
+ * If unjoin_work is already queued, release TX immediately.
|
||||
+ */
|
||||
+ if (join_failed) {
|
||||
+ if (queue_work(hw_priv->workqueue, &priv->unjoin_work) <= 0)
|
||||
+ wsm_unlock_tx(hw_priv);
|
||||
+ } else {
|
||||
+ wsm_unlock_tx(hw_priv);
|
||||
+ }
|
||||
}
|
||||
|
||||
void bes2600_join_timeout(struct work_struct *work)
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
pkgbase=linux-pinetab2-danctnix-besser
|
||||
pkgver=7.0.danctnix1
|
||||
pkgrel=5
|
||||
pkgrel=6
|
||||
pkgdesc='PineTab2 (BESser bes2600 driver patchset)'
|
||||
_srcname=linux-pinetab2
|
||||
_srctag=v${pkgver%.*}-${pkgver##*.}
|
||||
@@ -59,6 +59,7 @@ source=(
|
||||
0019-bes2600-take-pending_record_lock-with-_bh-to-fix-SOF.patch
|
||||
0020-bes2600-export-bus_reset-helpers-for-danctnix-bes260.patch
|
||||
0021-bes2600-bounce-sdio-tx-buffers.patch
|
||||
0022-bes2600-reset-firmware-state-on-wsm_join_confirm-fai.patch
|
||||
0002-bes2600-filter-5ghz-scan.patch
|
||||
config # the main kernel config file
|
||||
)
|
||||
@@ -92,6 +93,7 @@ b2sums=('3d9795083c8938f80f480de0d10bfd9c525640e59d5c7f22983de3f12ee42c84c31be90
|
||||
'5c71b88f2ae8a7ebd0932db9a4da72a3ba8c636f31a1bed953a81359588bcb0309f62aa9dee98db62bdc988a9b669341910da2b133d9fb92d14c27d64b54efe9'
|
||||
'e09273ddcdc44f4d40fe8a69e0fd70b963681ec4434ce63cf6114ea38954891e709ced877e0be914054854e2d295a2991e8c3d8dc0deb244bfc8b0568c681687'
|
||||
'3be2f7d74baf721ad933f04dea39d79e87a2a1dac3e987615d976e984b1043b90d8ede5ab01c4eb371784eb6ca21cdf69ff7b7c8ee6c678c0aea4bf464fdb92f'
|
||||
'e1b3977096a79252d23525d9757f7cb38255a737c7bd3bcc9b845db87d486acadbf6901dbaec8a73ae6adee1846e5a2d17bbab23e20471a39046798d23d5ba8e'
|
||||
'396acbdcf570eada62533c0b8f505ed18077e8432249bab5b8ac8d1107cabc9489bdb91a5780446237ec4fd9ba5fc57a49dff34c16ddab60dc30513fc535f00f'
|
||||
'656a998ab40cb85ee4c00f087b071a91632a6c091da2c84b0f74236b51d2dea6e9db6886625f80ad81dc249d8494ec47cd79d6dd9ea4f5e44f3cde857f861e10')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user