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.
14 KiB
BES2600 driver -- upstream submission prep
Status
Seven patches, all checkpatch --strict clean, all deployed and verified
on a PineTab2 (BES2600WM + Rockchip RK3566) running linux-pinetab2
6.19.10-danctnix1. Ready for Mobian DKMS merge requests and as the basis
for a future drivers/staging/bes2600/ submission to linux-wireless.
The 7th patch (tx-sdio-dma-oob) fixes a KFENCE-detected SDIO DMA
out-of-bounds read on every TX burst -- a real memory-safety bug that
also leaks adjacent kernel memory onto the air. This upgrades the series
from "cleanup" to "cleanup + live bug fix" and should precede any
linux-wireless RFC.
The series
Recommended submission order (dependency-clean, bisectable):
| # | Branch | Commit | Intent |
|---|---|---|---|
| 01 | bes2600/factory-request-firmware |
1a5d54a |
c1 -- Replace filp_open + kernel_read in the factory-read path with request_firmware(). Repoint FACTORY_PATH macro to the firmware-class name. Kills a kernel-mainline anti-pattern and the (NULL device *) read and check /lib/firmware/bes2600_factory.txt error boot spam on PineTab2. |
| 02 | bes2600/factory-no-efuse-flag |
82ba594 |
c5 -- Default STANDARD_FACTORY_EFUSE_FLAG from y to n. The shipped bes2600_factory.txt has 30 calibration fields; the driver was expecting 31 (incl. a ##select_efuse_flag section this firmware doesn't ship). Also drops an inconsistent #if defined(STANDARD_FACTORY_EFUSE_FLAG) wrapper around the wsm_save_factory_txt_to_mcu() prototype -- the definition and call site are always ungated, so the gate broke the build once EFUSE_FLAG=n. |
| 03 | bes2600/factory-thread-dev |
8732881 |
c1.1 -- Thread struct device * through factory_section_read_file() via a module-local setter invoked at SDIO probe, so request_firmware() gets proper per-device context instead of NULL. Removes the (NULL device *) log prefix from factory-related diagnostics. |
| 04 | bes2600/pm-gate-on-handshake |
80178ec |
c2 -- Gate the device-end of the LP transition on successful per-VIF firmware handshake. Before: bes2600_pwr_device_enter_lp_mode() was called unconditionally even when wait_for_completion_timeout() returned 0 (firmware never ack'd). On PineTab2 this produced bes2600_pwr_enter_lp_mode, wait pm ind timeout every 5-10s and cascaded into sdio_tx_work WARN splats. After: -ETIMEDOUT returned cleanly, dmesg silent, SDIO stable. |
| 05 | bes2600/remove-chardev-user-interface |
f43bcc5 |
c3 -- Remove the custom /dev/bes2600 character-device interface (fops, command dispatcher, bes2600_op_* handlers, bes2600_load_uevent, alloc_chrdev_region/class_create/device_create registration, cdev fields in struct bes_cdev). 519-line deletion. Keeps all in-kernel accessor functions (13 callers) and the fw_type module parameter as the user-facing replacement. |
| 06 | bes2600/enable-testmode |
9398d30 |
c4 -- Flip CONFIG_BES2600_TESTMODE default from n to y, exposing the driver's mac80211 testmode_cmd surface (dispatches to the firmware's patch_wifi_testMode path) through the standard nl80211 testmode interface. Also fixes accumulated bit-rot revealed by enabling the flag: adds compat shim macros in bes_log.h for the legacy bes2600_info() / bes2600_err() / bes2600_warn() / bes2600_dbg() / bes2600_err_with_cond() family (which had no definition anywhere, despite ~41 call sites in testmode code), defines BES2600_DBG_* subsystem ids as 0 constants, and marks 3 TSM/roam-delay helpers in sta.c as static for -Werror=missing-prototypes. |
| 07 | bes2600/tx-sdio-dma-oob |
10a05d2 |
tx-bounce -- Fix a KFENCE OOB read in the SDIO TX path. sdio_tx_work() handed dma_map_sg a block-aligned length (blks * cur_blksize, or 1632) but tx_buffer->buf is only tx_buffer->len bytes long (aliases into an skb linear head sized by pskb_expand_head / TCP). DMA read up to one block past the skb -- KFENCE fires out-of-bounds read in __pi_memcpy_generic / sdio_tx_work+0x2b4 / bes_sdio_memcpy_to_io_helper+0x18c, and the padding bytes are transmitted to the peer (kernel-memory leak to air). Allocate a driver-owned DMA-pages bounce buffer of MAX_SDIO_TRANSFER_LEN, memcpy each TX buffer into its slot, zero-pad, and point SG entries at the bounce. Separate from single_gathered_buffer (that one is bus-serialised via sdio_claim_host but sdio_tx_work accumulates SG entries before claiming). |
Total: +117 / -550 lines excluding commit messages.
Driver lineage (for the cover letter)
The BES2600 Linux driver is a descendant of the ST-Ericsson CW1200 driver
already in mainline at drivers/net/wireless/st/cw1200/. Evidence:
- Same author on both:
Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>(visible in the runningmodinfoon ohm and in the mainline cw1200 commit history). - Kconfig option names carry the ancestry:
CONFIG_BES2600_USE_STE_EXTENSIONS(STE = ST-Ericsson),CONFIG_BES2600_WSM_DEBUG(WSM = CW1200's host <-> firmware Wireless Sensor Module protocol). - File-layout parallel:
bh.c,hwio.c,fwio.c,queue.c,scan.c,sta.c,txrx.c,wsm.c,pm.c,main.c-- same spine as CW1200, plus BES-specific additions (ePTA coexistence,bes2600_btuart, 5 GHz support,bes_pwr,bes2600_factory,itp,bes_chardev).
ST-Ericsson wound down in 2013; Bestechnic (founded 2015) appears to have licensed or acquired the CW1200 IP. No public LKML/linux-wireless RFC linking the two has been filed. Bestechnic has never contributed the BES2600 driver upstream.
Background on which fork this series lands
Upstream today for BES2600 is fragmented:
salsa.debian.org/Mobian-team/devices/bes2600-dkms-- Mobian DKMS package, actively maintained (last commit 2025-12). Primary PR target.codeberg.org/DanctNIX/linux-pinetab2-- danctnix kernel fork; ships the driver in-tree atdrivers/staging/bes2600/at tagv6.19.10-danctnix1.gitlab.com/arjanvlek/bes2600-- original community fork; master was sanitized in 2024-10 (e5055a3 "Removed sources from main branch").gitlab.com/TuxThePenguin0/bes2600preserves the pre-sanitization snapshot.
The Mobian DKMS tree and the danctnix in-kernel tree have converged -- 0-
hunk diff on bes_pwr.c, bes2600_factory.c, wsm.c between them. This
series lands on Mobian first (branches already pushed to
git.reauktion.de/marfrit/bes2600-dkms).
Testing
Reference hardware: Pine64 PineTab2 (BES2600WM + Rockchip RK3566,
8a:2e:77:1f:ec:05, AP newton @ 2.4 GHz ch11 / TelekomHotspot@ERGO
@ 5 GHz ch36).
Host kernel: linux-pinetab2 6.19.10-danctnix1-1-pinetab2 with
CONFIG_NL80211_TESTMODE=y.
Per-patch:
- c1: post-reboot dmesg no longer shows
read and check /lib/firmware/ bes2600_factory.txt error;request_firmware()reads the file cleanly. - c5:
factory_parse()now succeeds on the shipped 30-fieldbes2600_factory.txt; noparse fail/factory cali data get failed. - c1.1: factory-related log lines no longer carry the
(NULL device *):prefix. - c2: pre-patch dmesg carried ~20-30
wait pm ind timeoutmessages per 5 min and 2+sdio_tx_workWARN splats; post-patchwait pm ind timeoutis 0 in the same window and[RX] Receive failure: 4.disappears. A residualsdio_tx_work+0x2b4splat (~1 per reboot) still recurred with c1..c6 alone; see c7 below for its root cause and fix. - c3:
/dev/bes2600character device node is absent post-reboot;lsmod | grep bes2600still shows bothbes2600andbes2600_btuartloaded and associated; WiFi continues to function. - c4:
iw phy0now liststestmodeunder Supported commands; nl80211 testmode interface reachable viaiw phy0 testmode cmd <data>(not exercised end-to-end yet -- depends on userspace tooling).
Full stack c1+c5+c1.1+c2+c3+c4: WiFi associates and passes traffic across 3+ reboots.
Known limitations / not-in-this-series
-
factory_section_write_file()inbes2600_factory.cstill useskernel_write()+filp_open(O_CREAT | O_TRUNC | O_RDWR)to persist per-channel calibration updates back to/lib/firmware/bes2600_factory.txt. Converting the write-back path to a debugfs or nl80211 testmode interface is out of scope here; upstream submission fordrivers/staging/will need to take that on. -
bes_chardev.cstill carriesbes2600_chrdev_write_dpd_data_to_file()(gatedBES2600_WRITE_DPD_TO_FILE, off by default so dead code in the default build) andbes2600_chrdev_read_and_check_dpd_data(). Both usefilp_open/kernel_read/kernel_writeand need the same treatment. -
bes_fw.c:587unconditionally creates/lib/firmware/bes2002_fw_write.binviafilp_open(O_CREAT | O_RDWR)to capture firmware bytes as they are sent to the chip. Pure debug helper; should be deleted or gated behind a debugfs trigger. -
After c3, the
bes2600_chrdev_is_signal_mode()/_update_signal_mode()family still reads/writes abes_cdevsingleton. Threadingstruct bes2600_common *through those call sites (13 files) requires first replacing thefw_typemodule_param with a per-phy debugfs knob or nl80211 testmode command -- a migration that overlaps with c4's testmode plumbing. Tracked as c3.1 (deferred). -
One residual dmesg notice after the full stack:
bes2600_wlan mmc2:0001:1: PS Mode Error, Reason:1at T+40s on fresh boot. Distinct from the pre-c2wait pm ind timeoutcascade -- benign, driver recovers, WiFi stays up. Root cause not investigated; candidate for a future c2.1 or firmware-RE follow-up. -
Firmware RE (task d) was pursued briefly. The shipped firmware keeps many format-string literals (e.g.
patch_HI_Set_Coex_Params, hw_epta_ enable:0x%x, new_run_flag:0x%x, gEptaBypass: %d) as dead data -- the string is in the blob but no code references it in any encoding. The compiler kept the literal while dead-stripping theTRACE()/patch_*()callers that would have used it. Takeaway: strings-mining overstates the reachable feature surface. A proper firmware RE would need function-graph analysis from the reset vector; out of scope here.
Submission routes
Near-term: Mobian DKMS merge request
All 7 branches are pushed to git.reauktion.de/marfrit/bes2600-dkms with
upstream set to salsa.debian.org/Mobian-team/devices/bes2600-dkms. To
open an MR against Mobian:
- Create a salsa.debian.org account and add the Gitea-side SSH key.
- Push the branches to a personal fork on salsa:
git remote add salsa git@salsa.debian.org:<user>/bes2600-dkms.git for br in \ bes2600/factory-request-firmware \ bes2600/factory-no-efuse-flag \ bes2600/factory-thread-dev \ bes2600/pm-gate-on-handshake \ bes2600/remove-chardev-user-interface \ bes2600/enable-testmode \ bes2600/tx-sdio-dma-oob; do git push salsa $br done - For each branch open an MR against
Mobian-team/devices/bes2600-dkms:mobian. Use the commit message as the MR description (it already reads as a standalone rationale). - Consider bundling into a single MR with all 7 commits if the Mobian reviewer prefers series review.
Near-term alt: danctnix linux-pinetab2 (codeberg)
Danctnix is the de-facto upstream for PineTab2 Arch-ARM images
(maintainer Danct12). The driver ships in-tree at
drivers/staging/bes2600/ in codeberg.org/DanctNIX/linux-pinetab2.
A danctnix-layout variant of the series (same content, paths rooted at
drivers/staging/bes2600/ instead of Mobian's bes2600/) is at
marfrit/besser/patches/staging-prep-series-danctnix/. Verified to
apply cleanly against tag v6.19.10-danctnix1 and checkpatch-clean.
Submission route:
- Create a codeberg.org account + add your SSH key.
- Fork
DanctNIX/linux-pinetab2on codeberg; push the 7 commits as a branchbes2600/staging-prep-series. - Open a codeberg PR against
DanctNIX/linux-pinetab2:masterwith the cover-letter content as PR description. - Alt: ping Danct12 directly (Matrix / IRC
#pine64/ mastodon@danctnix@social.treehouse.systems). Their merge workflow may be more casual than formal PR review.
Mobian and danctnix share the bes2600 source -- bes_pwr.c,
bes2600_factory.c, wsm.c all 0-hunk diff at the patched files.
Landing in either benefits users of both.
Longer-term: linux-wireless RFC for drivers/staging/bes2600/
This series cleans up the Mobian DKMS tree. A proper mainline staging
submission is bigger work -- new Kconfig + Makefile integration under
drivers/staging/, a MAINTAINERS entry for Markus Fritsche + CC Dmitry
Tarnyagin for CW1200 lineage ack, cover-letter framing the driver as a
new staging submission with the CW1200 ancestry cited so reviewers can
contextualise the structural parallels.
Gate: the kernel_write() / filp_open() leftovers (factory write-back,
DPD-to-file, observe_file debug path) must all go before staging will
accept it -- drivers/staging still has a nominal filter against direct
filesystem manipulation. Plan those as follow-up patches (c1.2, c1.3,
c1.4) and include them in the staging series.
Recommended linux-wireless CC list for a future RFC:
- Johannes Berg
<johannes@sipsolutions.net>(wireless maintainer) - Kalle Valo
<kvalo@kernel.org>(wireless drivers maintainer) - Dmitry Tarnyagin (CW1200 author; email may be stale post-ST-Ericsson)
- Dang Huynh
<dang.huynh@mainlining.org>(bes2600_btuart.c author) - Julian
<mail@julianfairfax.ch>(Mobian DKMS maintainer) - Danct12 (dreemurrs-embedded, PineTab2 kernel maintainer)
linux-wireless@vger.kernel.orglinux-arm-kernel@lists.infradead.org(PineTab2 RK3566 context)linux-staging@lists.linux.dev(if targeting drivers/staging/)
Signed-off-by chain: every patch has one. Tested-on: PineTab2 (BES2600WM + RK3566) line on each patch.