b8ba0b342e
Fold bes2600/tx-sdio-dma-oob into the linear series as 7/7. Re-cover-letter and update testing matrix. Update UPSTREAM.md table and submission route to list the 7th branch. The PS Mode Error residual note is removed from the known-limitations section -- it stopped recurring after 7/7 deployed. Both staging-prep-series/ (Mobian paths) and staging-prep-series- danctnix/ (drivers/staging/bes2600/ paths) variants regenerated; all 14 patch files checkpatch --strict clean (0/0/0). Net: +117 / -550 lines across 9 files.
187 lines
8.9 KiB
Diff
187 lines
8.9 KiB
Diff
From 10a05d21bfe4563f963e16d65228fd7a713c143d Mon Sep 17 00:00:00 2001
|
|
Message-ID: <cover.1776940528.git.fritsche.markus@gmail.com>
|
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
|
Date: Thu, 23 Apr 2026 12:35:28 +0200
|
|
Subject: [PATCH 0/7] bes2600: staging-prep cleanup for PineTab2 (BES2600WM)
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This series is a staging-prep cleanup for the out-of-tree Bestechnic
|
|
BES2600WM Wi-Fi/BT combo-chip driver as shipped by Mobian's bes2600-dkms
|
|
package (and in-tree at drivers/staging/bes2600/ in the danctnix
|
|
linux-pinetab2 fork). Target hardware is the Pine64 PineTab2 (RK3566
|
|
+ BES2600WM, SDIO vendor 0xBE57 / device 0x2002).
|
|
|
|
The driver descends from the ST-Ericsson CW1200 (drivers/net/wireless/
|
|
st/cw1200/) -- same author, Dmitry Tarnyagin, shared WSM host<->firmware
|
|
protocol, shared SDIO bus backend. Kconfig ancestry markers survive in
|
|
this tree today: CONFIG_BES2600_USE_STE_EXTENSIONS (STE = ST-Ericsson),
|
|
CONFIG_BES2600_WSM_DEBUG (WSM). ST-Ericsson wound down in 2013;
|
|
Bestechnic (founded 2015) appears to have inherited or licensed the
|
|
CW1200 IP. No linux-wireless RFC has ever linked the two chips.
|
|
|
|
The series fixes observable defects on a PineTab2 running linux-pinetab2
|
|
6.19.10-danctnix1-1 and removes two upstream blockers. Each patch is
|
|
independently testable and bisectable; the order below preserves
|
|
dependencies.
|
|
|
|
## What the series does
|
|
|
|
* 1/7 -- Replace filp_open() + kernel_read() in the factory-calibration
|
|
read path with request_firmware(). Repoint the FACTORY_PATH macro to
|
|
the firmware-class name (bes2600/bes2600_factory.txt, matching the
|
|
/lib/firmware/ layout). Kills a kernel-mainline anti-pattern and the
|
|
'(NULL device *): read and check /lib/firmware/bes2600_factory.txt
|
|
error' boot spam on PineTab2.
|
|
|
|
* 2/7 -- Default STANDARD_FACTORY_EFUSE_FLAG from y to n. The shipped
|
|
bes2600_factory.txt on PineTab2 contains 30 calibration fields; the
|
|
driver was expecting 31 (including a ##select_efuse_flag section
|
|
absent from this firmware). Also unguards the
|
|
wsm_save_factory_txt_to_mcu() prototype in wsm.h which was
|
|
inconsistently wrapped in '#if defined(STANDARD_FACTORY_EFUSE_FLAG)'
|
|
while its definition in wsm.c and its call site in sta.c were
|
|
ungated -- gcc -Werror=missing-prototypes broke the build with the
|
|
new default until this is fixed.
|
|
|
|
* 3/7 -- Thread struct device * through factory_section_read_file() via
|
|
a module-local setter invoked at SDIO probe. request_firmware() now
|
|
receives a real device pointer; '(NULL device *):' no longer prefixes
|
|
factory-related diagnostics.
|
|
|
|
* 4/7 -- Gate the device-end of the low-power transition on successful
|
|
per-VIF firmware handshake. Pre-patch bes2600_pwr_enter_lp_mode()
|
|
called bes2600_pwr_device_enter_lp_mode() unconditionally even when
|
|
wait_for_completion_timeout() returned 0 (firmware never posted the
|
|
PM-change indication). On PineTab2 this recurred every 5-10 s
|
|
whenever the interface was associated and idle, flooded dmesg, and
|
|
cascaded into sdio_tx_work WARN splats / [RX] Receive failure
|
|
messages. Post-patch: -ETIMEDOUT returned cleanly, dmesg silent,
|
|
SDIO stable.
|
|
|
|
* 5/7 -- Remove the custom /dev/bes2600 character-device interface.
|
|
file_operations, open/read/write/release, bes2600_op_*
|
|
command-dispatch table, bes2600_load_uevent, alloc_chrdev_region /
|
|
cdev_init / cdev_add / class_create / device_create in the init
|
|
path, and the matching teardown in bes2600_chrdev_free -- 519 lines
|
|
deleted. The in-kernel accessor functions (is_signal_mode,
|
|
get_fw_type, etc., 13 call sites) and the fw_type module parameter
|
|
are preserved; the userspace interface becomes rfkill + module_param
|
|
+ (with 6/7) nl80211 testmode.
|
|
|
|
* 6/7 -- Flip CONFIG_BES2600_TESTMODE default from n to y. The driver
|
|
already implements a mac80211 testmode_cmd dispatcher (routing to
|
|
the firmware's patch_wifi_testMode path), already gated on the flag;
|
|
CONFIG_NL80211_TESTMODE=y is common on target kernels. Enabling the
|
|
flag also exposes accumulated bit-rot -- ~41 calls to undefined
|
|
bes2600_info/err/warn/dbg/err_with_cond macros, and 3 TSM/roam-delay
|
|
helpers with external linkage but no prototype. Add shim macros to
|
|
bes_log.h rewiring the legacy calls onto the existing bes_info /
|
|
bes_err / bes_warn / bes_devel family, define BES2600_DBG_* subsystem
|
|
ids as 0 constants, and mark the 3 helpers static.
|
|
|
|
* 7/7 -- Bounce SDIO TX buffers to avoid DMA out-of-bounds reads.
|
|
sdio_tx_work() rounded the transfer length up to the SDIO block size
|
|
(align = blks * cur_blksize, or 1632) and handed that length to
|
|
dma_map_sg() via sg_set_buf(..., tx_buffer->buf, align); tx_buffer->buf
|
|
typically aliases into an skb linear head allocated to tx_buffer->len,
|
|
not the block-aligned length. The DMA engine therefore read up to one
|
|
block past the end of the skb -- KFENCE on PineTab2 fires as
|
|
'out-of-bounds read in __pi_memcpy_generic ... 704B right of
|
|
kfence-#...' with sdio_tx_work+0x2b4 / bes_sdio_memcpy_to_io_helper in
|
|
the stack and pskb_expand_head / validate_xmit_skb / tcp_write_xmit in
|
|
the allocator stack. Besides being undefined behavior, the padding
|
|
bytes are transmitted to the peer, leaking adjacent kernel memory on
|
|
the air. Allocate a driver-owned DMA-pages bounce buffer of
|
|
MAX_SDIO_TRANSFER_LEN, memcpy each TX buffer into its slot, zero the
|
|
padding tail, and point the SG entries at the bounce. Mirrors the
|
|
pattern already used for single_gathered_buffer; kept as a separate
|
|
allocation because sdio_tx_work accumulates SG entries before claiming
|
|
the bus.
|
|
|
|
## Testing
|
|
|
|
Reference hardware: Pine64 PineTab2 (BES2600WM + Rockchip RK3566,
|
|
8a:2e:77:1f:ec:05, LAN AP newton @ 2.4 GHz ch11, tested also on
|
|
TelekomHotspot@ERGO @ 5 GHz ch36).
|
|
|
|
Host kernel: linux-pinetab2 6.19.10-danctnix1-1-pinetab2 with
|
|
CONFIG_NL80211_TESTMODE=y and CONFIG_KFENCE=y (for 7/7 verification).
|
|
Driver installed via /lib/modules/<ver>/extra/ and verified loaded via
|
|
modinfo srcversion.
|
|
|
|
Per-patch outcomes in post-reboot dmesg (full-stack applied, 11+ min
|
|
soak, 245k RX packets / 365 MB traffic):
|
|
|
|
- 1/7: 'read and check /lib/firmware/bes2600_factory.txt error' -- gone
|
|
- 2/7: 'bes2600_factory.txt parse fail' / 'factory cali data get
|
|
failed.' -- gone
|
|
- 3/7: '(NULL device *):' prefix on factory lines -- gone
|
|
- 4/7: 'bes2600_pwr_enter_lp_mode, wait pm ind timeout' (pre-patch 20-30
|
|
msgs / 5 min window) -- 0 per 5 min; '[RX] Receive failure: 4.' --
|
|
gone
|
|
- 5/7: /dev/bes2600 -- absent; driver continues to associate
|
|
- 6/7: 'iw phy0' lists 'testmode' under Supported commands; module
|
|
builds cleanly
|
|
- 7/7: 'BUG: KFENCE: out-of-bounds read in __pi_memcpy_generic'
|
|
(pre-patch ~65 splats per 4 h of real traffic, always via
|
|
sdio_tx_work+0x2b4 / bes_sdio_memcpy_to_io_helper+0x18c) -- 0;
|
|
'sdio_tx_work+0x2b4' WARN splat residual from 4/7's cascade -- 0
|
|
(previously recurred ~1 per reboot even with 4/7 applied);
|
|
'PS Mode Error, Reason:1' benign handshake notice at T+40s --
|
|
also gone, apparently a downstream effect of no longer DMAing
|
|
uninitialised padding bytes into firmware
|
|
|
|
Full stack: wifi associates and passes traffic across 3+ reboots.
|
|
|
|
## Known limitations / out of scope
|
|
|
|
- factory_section_write_file() in bes2600_factory.c still uses
|
|
kernel_write() + filp_open(O_CREAT) to persist per-channel
|
|
calibration updates back to /lib/firmware/bes2600_factory.txt.
|
|
Converting the write-back path to debugfs or nl80211 testmode is a
|
|
follow-up.
|
|
|
|
- bes_chardev.c still carries DPD file-read/write paths gated by
|
|
BES2600_WRITE_DPD_TO_FILE (off by default, so dead code in the
|
|
default build). Same treatment needed.
|
|
|
|
- bes_fw.c:587 unconditionally creates
|
|
/lib/firmware/bes2002_fw_write.bin via filp_open() for debug
|
|
observation. Needs to go before drivers/staging/ accepts the driver.
|
|
|
|
- bes_cdev global singleton still holds sig_mode and fw_type. Moving
|
|
those to per-hw_priv state is blocked by fw_type being a module
|
|
parameter (inherently singleton). Migrating fw_type to a per-phy
|
|
debugfs knob or nl80211 testmode command is the next step; overlaps
|
|
with 6/7's testmode plumbing.
|
|
|
|
Markus Fritsche (7):
|
|
bes2600: use request_firmware() for factory.txt read
|
|
bes2600: default STANDARD_FACTORY_EFUSE_FLAG off for PineTab2
|
|
factory.txt format
|
|
bes2600: thread struct device * through factory request_firmware()
|
|
call
|
|
bes2600: gate device LP-mode entry on successful per-VIF firmware
|
|
handshake
|
|
bes2600: remove userspace /dev/bes2600 character device interface
|
|
bes2600: enable CONFIG_BES2600_TESTMODE by default + fix bit-rotted
|
|
testmode plumbing
|
|
bes2600: bounce SDIO TX buffers to avoid DMA OOB read
|
|
|
|
bes2600/Makefile | 6 +-
|
|
bes2600/bes2600_factory.c | 45 ++--
|
|
bes2600/bes2600_factory.h | 3 +
|
|
bes2600/bes2600_sdio.c | 43 +++-
|
|
bes2600/bes_chardev.c | 519 --------------------------------------
|
|
bes2600/bes_log.h | 23 ++
|
|
bes2600/bes_pwr.c | 20 +-
|
|
bes2600/sta.c | 6 +-
|
|
bes2600/wsm.h | 2 -
|
|
9 files changed, 117 insertions(+), 550 deletions(-)
|
|
|
|
--
|
|
2.53.0
|
|
|