Upstream submission prep: UPSTREAM.md + 6-patch linear series with cover letter
UPSTREAM.md captures the submission-ready state:
- patch-by-patch intent and testing status
- CW1200 lineage narrative
- branch-to-patch mapping on marfrit/bes2600-dkms
- submission routes (near-term Mobian MR, longer-term linux-wireless
RFC for drivers/staging/)
- known limitations left for follow-up
- recommended CC list for a future linux-wireless RFC
patches/staging-prep-series/ contains the linear 6-patch series with
cover letter, generated from the bes2600/staging-prep-series branch on
marfrit/bes2600-dkms (cherry-picked off mobian in dependency order).
All patches checkpatch.pl --no-tree --strict clean.
Branch mapping:
1/6 bes2600/factory-request-firmware (c1)
2/6 bes2600/factory-no-efuse-flag (c5, stacked on c1)
3/6 bes2600/factory-thread-dev (c1.1, stacked on c1+c5)
4/6 bes2600/pm-gate-on-handshake (c2, standalone)
5/6 bes2600/remove-chardev-user-interface (c3, standalone)
6/6 bes2600/enable-testmode (c4, standalone)
Total: 79 insertions, 549 deletions. Net -470 lines.
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
This commit is contained in:
+190
@@ -0,0 +1,190 @@
|
|||||||
|
# BES2600 driver — upstream submission prep
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Six patches, all checkpatch-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 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`. |
|
||||||
|
|
||||||
|
Total: +45 / −576 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 running `modinfo` on 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 at `drivers/staging/bes2600/` at tag
|
||||||
|
`v6.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/bes2600` preserves 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-field
|
||||||
|
`bes2600_factory.txt`; no `parse 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 timeout` messages
|
||||||
|
per 5 min and 2+ `sdio_tx_work` WARN splats; post-patch both counts are
|
||||||
|
0 in the same window. `[RX] Receive failure: 4.` disappears too.
|
||||||
|
- **c3**: `/dev/bes2600` character device node is absent post-reboot;
|
||||||
|
`lsmod | grep bes2600` still shows both `bes2600` and `bes2600_btuart`
|
||||||
|
loaded and associated; WiFi continues to function.
|
||||||
|
- **c4**: `iw phy0` now lists `testmode` under *Supported commands*;
|
||||||
|
nl80211 testmode interface reachable via `iw 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()` in `bes2600_factory.c` still uses
|
||||||
|
`kernel_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 for
|
||||||
|
`drivers/staging/` will need to take that on.
|
||||||
|
|
||||||
|
- `bes_chardev.c` still carries `bes2600_chrdev_write_dpd_data_to_file()`
|
||||||
|
(gated `BES2600_WRITE_DPD_TO_FILE`, off by default so dead code in the
|
||||||
|
default build) and `bes2600_chrdev_read_and_check_dpd_data()`. Both use
|
||||||
|
`filp_open`/`kernel_read`/`kernel_write` and need the same treatment.
|
||||||
|
|
||||||
|
- `bes_fw.c:587` unconditionally creates `/lib/firmware/bes2002_fw_write.bin`
|
||||||
|
via `filp_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 a `bes_cdev` singleton. Threading
|
||||||
|
`struct bes2600_common *` through those call sites (13 files) requires
|
||||||
|
first replacing the `fw_type` module_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:1` at T+40s on fresh boot. Distinct
|
||||||
|
from the pre-c2 `wait pm ind timeout` cascade — 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 the `TRACE()` /
|
||||||
|
`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 6 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:
|
||||||
|
|
||||||
|
1. Create a salsa.debian.org account and add the Gitea-side SSH key.
|
||||||
|
2. 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; do
|
||||||
|
git push salsa $br
|
||||||
|
done
|
||||||
|
```
|
||||||
|
3. 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).
|
||||||
|
4. Consider bundling into a single MR with all 6 commits if the Mobian
|
||||||
|
reviewer prefers series review.
|
||||||
|
|
||||||
|
### 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.org`
|
||||||
|
- `linux-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.
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
From 6f13e008d21d453db486f707f47340a0a17e650b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
Date: Wed, 22 Apr 2026 14:15:56 +0200
|
||||||
|
Subject: [PATCH 0/6] bes2600: staging-prep cleanup for PineTab2 (BES2600WM)
|
||||||
|
|
||||||
|
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/6 — 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/6 — 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/6 — 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/6 — 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/6 — 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/6) nl80211 testmode.
|
||||||
|
|
||||||
|
* 6/6 — 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.
|
||||||
|
|
||||||
|
## 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. Driver installed via
|
||||||
|
/lib/modules/<ver>/extra/ and verified loaded via modinfo srcversion.
|
||||||
|
|
||||||
|
Per-patch outcomes in post-reboot dmesg (full-stack applied):
|
||||||
|
- 1/6: 'read and check /lib/firmware/bes2600_factory.txt error' — gone
|
||||||
|
- 2/6: 'bes2600_factory.txt parse fail' / 'factory cali data get
|
||||||
|
failed.' — gone
|
||||||
|
- 3/6: '(NULL device *):' prefix on factory lines — gone
|
||||||
|
- 4/6: 'bes2600_pwr_enter_lp_mode, wait pm ind timeout' (pre-patch 20-30
|
||||||
|
msgs / 5 min window) — 0 per 5 min; 'sdio_tx_work' WARN splat
|
||||||
|
(pre-patch 2+ / 5 min) — 0 per 5 min; '[RX] Receive failure: 4.' —
|
||||||
|
gone
|
||||||
|
- 5/6: /dev/bes2600 — absent; driver continues to associate
|
||||||
|
- 6/6: 'iw phy0' lists 'testmode' under Supported commands; module
|
||||||
|
builds cleanly
|
||||||
|
|
||||||
|
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/6's testmode plumbing.
|
||||||
|
|
||||||
|
- One residual benign notice after the full stack: 'bes2600_wlan
|
||||||
|
mmc2:0001:1: PS Mode Error, Reason:1' at T+40s on fresh boot.
|
||||||
|
Distinct from the pre-4/6 timeout cascade; driver recovers, WiFi
|
||||||
|
stays up. Root cause not investigated.
|
||||||
|
|
||||||
|
Markus Fritsche (6):
|
||||||
|
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/Makefile | 6 +-
|
||||||
|
bes2600/bes2600_factory.c | 45 ++--
|
||||||
|
bes2600/bes2600_factory.h | 3 +
|
||||||
|
bes2600/bes2600_sdio.c | 4 +
|
||||||
|
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, 79 insertions(+), 549 deletions(-)
|
||||||
|
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
|
||||||
+144
@@ -0,0 +1,144 @@
|
|||||||
|
From d18aa6a9bc03a03e455434f83577892aa1a60ffe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
Date: Wed, 22 Apr 2026 10:09:44 +0200
|
||||||
|
Subject: [PATCH 1/6] bes2600: use request_firmware() for factory.txt read
|
||||||
|
|
||||||
|
The BES2600 factory calibration file (bes2600_factory.txt) was being read
|
||||||
|
via filp_open() + kernel_read() from a hard-coded absolute path baked in
|
||||||
|
at compile time via the FACTORY_PATH Makefile macro
|
||||||
|
(default: /lib/firmware/bes2600_factory.txt).
|
||||||
|
|
||||||
|
This had several problems:
|
||||||
|
|
||||||
|
1. Path mismatch - linux-firmware-style packaging (and danctnix 0.2-5
|
||||||
|
device-pine64-pinetab2) ships the file at
|
||||||
|
/lib/firmware/bes2600/bes2600_factory.txt, not /lib/firmware/. The
|
||||||
|
driver logged '(NULL device *): read and check
|
||||||
|
/lib/firmware/bes2600_factory.txt error' on every boot on PineTab2
|
||||||
|
running linux-pinetab2 6.19.10-danctnix1-1.
|
||||||
|
|
||||||
|
2. Direct filesystem access via filp_open() / kernel_read() from a driver
|
||||||
|
is an anti-pattern that upstream rejects: drivers should use
|
||||||
|
request_firmware() to get binary data from userspace-managed firmware
|
||||||
|
directories. request_firmware() natively searches the firmware_class
|
||||||
|
path list (typically /lib/firmware + derivatives), associates the load
|
||||||
|
with a uevent, and respects the firmware-loading infrastructure.
|
||||||
|
|
||||||
|
3. The (NULL device *) prefix in error messages indicated the absence of
|
||||||
|
proper device-context logging. While this patch does not yet thread
|
||||||
|
struct device through, the upstream path uses request_firmware() which
|
||||||
|
works with dev=NULL and is the building block for a follow-up patch
|
||||||
|
that adds per-chip device context.
|
||||||
|
|
||||||
|
Repoint the FACTORY_PATH default to the firmware-class name
|
||||||
|
(bes2600/bes2600_factory.txt) - request_firmware() prepends
|
||||||
|
/lib/firmware/ from the configured search paths. The macro remains
|
||||||
|
overridable at build time for non-standard deployments.
|
||||||
|
|
||||||
|
Rewrite factory_section_read_file() to:
|
||||||
|
* Call request_firmware(&fw, path, NULL).
|
||||||
|
* Size-check fw->size against FACTORY_MAX_SIZE.
|
||||||
|
* memcpy the data into the caller's buffer.
|
||||||
|
* Always call release_firmware() on exit.
|
||||||
|
|
||||||
|
The file write path (factory_section_write_file + kernel_write) is left
|
||||||
|
unchanged in this patch; it is the subject of a follow-up patch that
|
||||||
|
removes kernel_write and moves any remaining userspace-visible factory
|
||||||
|
configuration to a standard kernel-userspace boundary (debugfs or
|
||||||
|
nl80211 testmode).
|
||||||
|
|
||||||
|
No caller signature changes. No Makefile flag drops. Bisectable.
|
||||||
|
|
||||||
|
Tested-on: PineTab2 (BES2600WM + RK3566) running linux-pinetab2
|
||||||
|
6.19.10-danctnix1-1, deployed via /lib/modules/<ver>/extra/. Verified
|
||||||
|
post-reboot: original 'read and check /lib/firmware/bes2600_factory.txt
|
||||||
|
error' is gone; request_firmware reads the file successfully (a separate
|
||||||
|
factory_parse() bug, previously masked by the read failure, is now
|
||||||
|
exposed and tracked separately).
|
||||||
|
|
||||||
|
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
---
|
||||||
|
bes2600/Makefile | 2 +-
|
||||||
|
bes2600/bes2600_factory.c | 33 ++++++++++++++-------------------
|
||||||
|
2 files changed, 15 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/bes2600/Makefile b/bes2600/Makefile
|
||||||
|
index 300912b..788aee2 100644
|
||||||
|
--- a/bes2600/Makefile
|
||||||
|
+++ b/bes2600/Makefile
|
||||||
|
@@ -66,7 +66,7 @@ BES2600_DRV_VERSION := bes2600_0.3.5_2024.0116
|
||||||
|
ifeq ($(CONFIG_BES2600_CALIB_FROM_LINUX),y)
|
||||||
|
FACTORY_CRC_CHECK ?= n
|
||||||
|
STANDARD_FACTORY_EFUSE_FLAG ?= y
|
||||||
|
-FACTORY_PATH ?= /lib/firmware/bes2600_factory.txt
|
||||||
|
+FACTORY_PATH ?= bes2600/bes2600_factory.txt
|
||||||
|
endif
|
||||||
|
|
||||||
|
# basic function
|
||||||
|
diff --git a/bes2600/bes2600_factory.c b/bes2600/bes2600_factory.c
|
||||||
|
index dc5d3da..8d60b7c 100644
|
||||||
|
--- a/bes2600/bes2600_factory.c
|
||||||
|
+++ b/bes2600/bes2600_factory.c
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
+#include <linux/firmware.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
|
@@ -137,38 +138,32 @@ static int bes2600_factory_crc_check(struct factory_t *factory_data)
|
||||||
|
*/
|
||||||
|
static int factory_section_read_file(char *path, void *buffer)
|
||||||
|
{
|
||||||
|
- int ret = 0;
|
||||||
|
- struct file *fp;
|
||||||
|
+ const struct firmware *fw;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
if (!path || !buffer) {
|
||||||
|
bes_err("%s NULL pointer err\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- bes_devel("reading %s \n", path);
|
||||||
|
+ bes_devel("requesting firmware-class %s\n", path);
|
||||||
|
|
||||||
|
- fp = filp_open(path, O_RDONLY, 0); //S_IRUSR
|
||||||
|
- if (IS_ERR(fp)) {
|
||||||
|
- bes_devel("BES2600 : can't open %s\n",path);
|
||||||
|
+ ret = request_firmware(&fw, path, NULL);
|
||||||
|
+ if (ret) {
|
||||||
|
+ bes_devel("BES2600: request_firmware(%s) failed: %d\n", path, ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (fp->f_inode->i_size <= 0 || fp->f_inode->i_size > FACTORY_MAX_SIZE) {
|
||||||
|
- bes_err( "bes2600_factory.txt size check failed, read_size: %lld max_size: %d\n",
|
||||||
|
- fp->f_inode->i_size, FACTORY_MAX_SIZE);
|
||||||
|
- filp_close(fp, NULL);
|
||||||
|
+ if (fw->size == 0 || fw->size > FACTORY_MAX_SIZE) {
|
||||||
|
+ bes_err("bes2600_factory.txt size check failed, read_size: %zu max_size: %d\n",
|
||||||
|
+ fw->size, FACTORY_MAX_SIZE);
|
||||||
|
+ release_firmware(fw);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kernel_read(fp, buffer, fp->f_inode->i_size, &fp->f_pos);
|
||||||
|
-
|
||||||
|
- filp_close(fp, NULL);
|
||||||
|
-
|
||||||
|
- if (ret != fp->f_inode->i_size) {
|
||||||
|
- bes_err("bes2600_factory.txt read fail\n");
|
||||||
|
- ret = -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ memcpy(buffer, fw->data, fw->size);
|
||||||
|
+ ret = (int)fw->size;
|
||||||
|
+ release_firmware(fw);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
|
||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
From a826f4db7d97a3a872d92079db37dbdaf9a0cdec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
Date: Wed, 22 Apr 2026 12:17:56 +0200
|
||||||
|
Subject: [PATCH 2/6] bes2600: default STANDARD_FACTORY_EFUSE_FLAG off for
|
||||||
|
PineTab2 factory.txt format
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The shipped factory calibration file bes2600_factory.txt on PineTab2
|
||||||
|
(danctnix linux-firmware 0.3.5_2023.0209) contains 30 calibration
|
||||||
|
fields: head (3), iq/xtal (3), 2.4G power 11n (5), 5G power 11n (15),
|
||||||
|
bt (4). The file terminates with '%%\n' directly after edr_power.
|
||||||
|
|
||||||
|
When STANDARD_FACTORY_EFUSE_FLAG is defined at compile time the driver
|
||||||
|
assembles STANDARD_FACTORY with an extra select_efuse_flag section
|
||||||
|
appended and expects 31 sscanf matches (FACTORY_MEMBER_NUM=31):
|
||||||
|
|
||||||
|
__STANDARD_FACTORY + \"##select_efuse_flag\\nselect_efuse:%hx\\n\"
|
||||||
|
+ \"%%%%\\n\"
|
||||||
|
|
||||||
|
The PineTab2 factory.txt has no select_efuse_flag section, so sscanf
|
||||||
|
stops after field 30 and factory_parse() returns -1 with:
|
||||||
|
|
||||||
|
bes2600_factory.txt parse fail
|
||||||
|
read and check bes2600/bes2600_factory.txt error
|
||||||
|
factory cali data get failed.
|
||||||
|
|
||||||
|
This was latent until the preceding patch (use request_firmware() for
|
||||||
|
factory.txt read) fixed the path bug that masked the parse failure.
|
||||||
|
|
||||||
|
Default STANDARD_FACTORY_EFUSE_FLAG to n. The flag remains overridable
|
||||||
|
at build time (make STANDARD_FACTORY_EFUSE_FLAG=y ...) for chips /
|
||||||
|
firmware packages that do ship the select_efuse_flag section.
|
||||||
|
|
||||||
|
Also: the wsm_save_factory_txt_to_mcu() prototype in wsm.h was
|
||||||
|
inconsistently wrapped in a conditional that keyed on
|
||||||
|
STANDARD_FACTORY_EFUSE_FLAG, but the function definition in wsm.c and
|
||||||
|
the call site in sta.c are ungated. With the flag now defaulting to
|
||||||
|
n, the gcc -Werror=missing-prototypes flag breaks the build. Drop the
|
||||||
|
conditional wrapper around the prototype — the function exists and is
|
||||||
|
used regardless of the factory-parse flag.
|
||||||
|
|
||||||
|
Tested-on: PineTab2 (BES2600WM + RK3566) running linux-pinetab2
|
||||||
|
6.19.10-danctnix1-1. With the flag defaulted off, factory_parse()
|
||||||
|
succeeds on the shipped factory.txt, factory_cali_data is populated,
|
||||||
|
and dmesg no longer shows the parse-fail / read-and-check-error /
|
||||||
|
factory-cali-data-get-failed sequence.
|
||||||
|
|
||||||
|
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
---
|
||||||
|
bes2600/Makefile | 2 +-
|
||||||
|
bes2600/wsm.h | 2 --
|
||||||
|
2 files changed, 1 insertion(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/bes2600/Makefile b/bes2600/Makefile
|
||||||
|
index 788aee2..2dcba09 100644
|
||||||
|
--- a/bes2600/Makefile
|
||||||
|
+++ b/bes2600/Makefile
|
||||||
|
@@ -65,7 +65,7 @@ BES2600_DRV_VERSION := bes2600_0.3.5_2024.0116
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BES2600_CALIB_FROM_LINUX),y)
|
||||||
|
FACTORY_CRC_CHECK ?= n
|
||||||
|
-STANDARD_FACTORY_EFUSE_FLAG ?= y
|
||||||
|
+STANDARD_FACTORY_EFUSE_FLAG ?= n
|
||||||
|
FACTORY_PATH ?= bes2600/bes2600_factory.txt
|
||||||
|
endif
|
||||||
|
|
||||||
|
diff --git a/bes2600/wsm.h b/bes2600/wsm.h
|
||||||
|
index 0673131..22845ac 100644
|
||||||
|
--- a/bes2600/wsm.h
|
||||||
|
+++ b/bes2600/wsm.h
|
||||||
|
@@ -2236,7 +2236,5 @@ int wsm_cpu_usage_cmd(struct bes2600_common *hw_priv);
|
||||||
|
|
||||||
|
int wsm_wifi_status_cmd(struct bes2600_common *hw_priv, uint32_t status);
|
||||||
|
|
||||||
|
-#if defined(STANDARD_FACTORY_EFUSE_FLAG)
|
||||||
|
int wsm_save_factory_txt_to_mcu(struct bes2600_common *hw_priv, const u8 *data, int if_id, enum bes2600_rf_cmd_type cmd_type);
|
||||||
|
-#endif
|
||||||
|
#endif /* BES2600_HWIO_H_INCLUDED */
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
|
||||||
+116
@@ -0,0 +1,116 @@
|
|||||||
|
From c7ba2044b78cc3778763737daea60c9912b710c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
Date: Wed, 22 Apr 2026 13:18:38 +0200
|
||||||
|
Subject: [PATCH 3/6] bes2600: thread struct device * through factory
|
||||||
|
request_firmware() call
|
||||||
|
|
||||||
|
Follow-up to \"bes2600: use request_firmware() for factory.txt read\".
|
||||||
|
That patch switched the factory calibration read path from filp_open()
|
||||||
|
+ kernel_read() to request_firmware(), but passed dev=NULL to
|
||||||
|
request_firmware() because factory_section_read_file() did not have a
|
||||||
|
struct device * in scope. The resulting logs carry the
|
||||||
|
'(NULL device *):' prefix and do not propagate a udev association.
|
||||||
|
|
||||||
|
Add a module-local static struct device * used as the firmware-class
|
||||||
|
load context, plus a small exported setter:
|
||||||
|
|
||||||
|
static struct device *bes2600_factory_dev;
|
||||||
|
void bes2600_factory_set_dev(struct device *dev);
|
||||||
|
|
||||||
|
Wire bes2600_factory_set_dev(&func->dev) from bes2600_sdio_probe(),
|
||||||
|
right after bes2600_platform_data_init() so the platform layer has
|
||||||
|
already had a chance to use the same struct device for its own
|
||||||
|
initialization.
|
||||||
|
|
||||||
|
factory_section_read_file() now passes bes2600_factory_dev (instead
|
||||||
|
of NULL) to request_firmware(). When the factory read happens before
|
||||||
|
probe (not currently the case on PineTab2) the pointer is still NULL
|
||||||
|
and request_firmware() accepts that; no regression.
|
||||||
|
|
||||||
|
No API changes to bes2600_get_factory_cali_data() callers. The
|
||||||
|
char *path parameter remains (it is the firmware-class name fed
|
||||||
|
straight to request_firmware()).
|
||||||
|
|
||||||
|
Tested-on: PineTab2 (BES2600WM + RK3566) running linux-pinetab2
|
||||||
|
6.19.10-danctnix1-1. Driver probes, factory data is read, and any
|
||||||
|
post-c5 factory diagnostics now carry the SDIO device identity
|
||||||
|
instead of '(NULL device *)'.
|
||||||
|
|
||||||
|
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
---
|
||||||
|
bes2600/bes2600_factory.c | 14 +++++++++++++-
|
||||||
|
bes2600/bes2600_factory.h | 3 +++
|
||||||
|
bes2600/bes2600_sdio.c | 4 ++++
|
||||||
|
3 files changed, 20 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/bes2600/bes2600_factory.c b/bes2600/bes2600_factory.c
|
||||||
|
index 8d60b7c..1cda447 100644
|
||||||
|
--- a/bes2600/bes2600_factory.c
|
||||||
|
+++ b/bes2600/bes2600_factory.c
|
||||||
|
@@ -31,6 +31,18 @@
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(factory_lock);
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * struct device * for request_firmware() context. Set once at SDIO
|
||||||
|
+ * probe via bes2600_factory_set_dev(). NULL is tolerated (falls back
|
||||||
|
+ * to the udev-less firmware-class path) but loses per-device logging.
|
||||||
|
+ */
|
||||||
|
+static struct device *bes2600_factory_dev;
|
||||||
|
+
|
||||||
|
+void bes2600_factory_set_dev(struct device *dev)
|
||||||
|
+{
|
||||||
|
+ bes2600_factory_dev = dev;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* It is only used for temporary storage.
|
||||||
|
* Every time get the factory, it will read from the
|
||||||
|
@@ -148,7 +160,7 @@ static int factory_section_read_file(char *path, void *buffer)
|
||||||
|
|
||||||
|
bes_devel("requesting firmware-class %s\n", path);
|
||||||
|
|
||||||
|
- ret = request_firmware(&fw, path, NULL);
|
||||||
|
+ ret = request_firmware(&fw, path, bes2600_factory_dev);
|
||||||
|
if (ret) {
|
||||||
|
bes_devel("BES2600: request_firmware(%s) failed: %d\n", path, ret);
|
||||||
|
return -1;
|
||||||
|
diff --git a/bes2600/bes2600_factory.h b/bes2600/bes2600_factory.h
|
||||||
|
index 3835b0d..7dbe9f8 100644
|
||||||
|
--- a/bes2600/bes2600_factory.h
|
||||||
|
+++ b/bes2600/bes2600_factory.h
|
||||||
|
@@ -199,6 +199,9 @@ enum factory_cali_status {
|
||||||
|
/* just calibrate 11n, other protocols are automatically mapped */
|
||||||
|
#define WIFI_RF_11N_MODE 0x15
|
||||||
|
|
||||||
|
+/* set the struct device * used for request_firmware() context */
|
||||||
|
+void bes2600_factory_set_dev(struct device *dev);
|
||||||
|
+
|
||||||
|
/* read wifi & bt factory cali value*/
|
||||||
|
u8* bes2600_get_factory_cali_data(u8 *file_buffer, u32 *data_len, char *path);
|
||||||
|
void factory_little_endian_cvrt(u8 *data);
|
||||||
|
diff --git a/bes2600/bes2600_sdio.c b/bes2600/bes2600_sdio.c
|
||||||
|
index b595365..371ef4f 100644
|
||||||
|
--- a/bes2600/bes2600_sdio.c
|
||||||
|
+++ b/bes2600/bes2600_sdio.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
#include "bes2600.h"
|
||||||
|
#include "sbus.h"
|
||||||
|
#include "bes2600_plat.h"
|
||||||
|
+#include "bes2600_factory.h"
|
||||||
|
#include "hwio.h"
|
||||||
|
#include "bes_chardev.h"
|
||||||
|
#include "bes_log.h"
|
||||||
|
@@ -1834,6 +1835,9 @@ static int bes2600_sdio_probe(struct sdio_func *func,
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
+ /* wire struct device into factory.c for request_firmware() context */
|
||||||
|
+ bes2600_factory_set_dev(dev);
|
||||||
|
+
|
||||||
|
self->pdata = bes2600_get_platform_data();
|
||||||
|
self->func = func;
|
||||||
|
self->dev = &func->dev;
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
|
||||||
+105
@@ -0,0 +1,105 @@
|
|||||||
|
From 108d3967eac4ba3a6e0f508d865a5f221b49079d 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 4/6] 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/bes2600/bes_pwr.c b/bes2600/bes_pwr.c
|
||||||
|
index e7a1045..f62ae22 100644
|
||||||
|
--- a/bes2600/bes_pwr.c
|
||||||
|
+++ b/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.53.0
|
||||||
|
|
||||||
+675
@@ -0,0 +1,675 @@
|
|||||||
|
From 3304b13a2b2e7388ebf076c2bcb7f02cd0b6800f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
Date: Wed, 22 Apr 2026 12:55:18 +0200
|
||||||
|
Subject: [PATCH 5/6] bes2600: remove userspace /dev/bes2600 character device
|
||||||
|
interface
|
||||||
|
|
||||||
|
bes_chardev.c implemented a custom character device at /dev/bes2600 with
|
||||||
|
its own parser and command-dispatch table, exposing operations such as
|
||||||
|
'wifi on|off', 'bt on|off', 'change_fw_type <n>', 'bt_wakeup',
|
||||||
|
'bt_sleep', and 'wakeup_read_flag'. None of these surfaces are used by
|
||||||
|
the in-tree driver - every kernel call site consumes the internal state
|
||||||
|
accessors (bes2600_chrdev_is_signal_mode, bes2600_chrdev_get_fw_type,
|
||||||
|
etc) directly, not through the cdev.
|
||||||
|
|
||||||
|
The cdev interface is a standing upstream blocker for two reasons:
|
||||||
|
|
||||||
|
1. Drivers under drivers/staging/ and drivers/net/wireless/ are
|
||||||
|
expected to expose tuning via the firmware/nl80211/debugfs
|
||||||
|
infrastructure rather than a private /dev node with an ad-hoc
|
||||||
|
parser.
|
||||||
|
|
||||||
|
2. The cdev handlers keep a global bes_cdev singleton alive whose
|
||||||
|
->cdev, ->dev_id, ->class and ->device pointers exist only to be
|
||||||
|
torn down; they add no functionality that nl80211 or rfkill do
|
||||||
|
not already provide (wifi/bt on-off, module_param for fw_type).
|
||||||
|
|
||||||
|
Remove the userspace interface:
|
||||||
|
|
||||||
|
- open / read / write / release file_operations handlers and the
|
||||||
|
bes2600_chardev_fops instance
|
||||||
|
- bes2600_op_* command handlers and bes2600_op_map_tab dispatcher
|
||||||
|
- bes2600_get_cmd_and_ifname / bes2600_recyle_cmd_and_ifname_mem
|
||||||
|
string helpers
|
||||||
|
- bes2600_load_uevent (its only caller was
|
||||||
|
bes2600_chrdev_wifi_force_close_work informing userspace of a
|
||||||
|
state it already gates via rfkill; that snprintf +
|
||||||
|
kobject_uevent_env block is gone too, the kernel-side
|
||||||
|
halt_device + switch_wifi(0) + chrdev_check_system_close
|
||||||
|
sequence remains)
|
||||||
|
- alloc_chrdev_region / cdev_init / cdev_add / class_create /
|
||||||
|
device_create in bes2600_chrdev_init plus the fail1/fail2/fail3
|
||||||
|
unwind labels
|
||||||
|
- cdev_del / unregister_chrdev_region / device_destroy /
|
||||||
|
class_destroy in bes2600_chrdev_free
|
||||||
|
- cdev/dev_id/major/minor/class/device fields in struct bes_cdev
|
||||||
|
|
||||||
|
What remains (unchanged behaviour):
|
||||||
|
|
||||||
|
- fw_type module parameter - the primary user-facing knob for
|
||||||
|
signal/no-signal/BT mode switch
|
||||||
|
- All in-kernel bes2600_chrdev_* accessor functions called from
|
||||||
|
bes2600_sdio.c, bes_pwr.c, sta.c, bh.c, main.c, wsm.c, and
|
||||||
|
wifi_testmode_cmd.c (13 call sites)
|
||||||
|
- bes2600_chrdev_init / bes2600_chrdev_free as state-init / teardown
|
||||||
|
for the remaining bes_cdev state (waitqueues, workqueues, flags)
|
||||||
|
- DPD management (bes2600_chrdev_get_dpd_buffer / update / free)
|
||||||
|
- wifi_force_close worker, system-close logic, bus-probe state
|
||||||
|
machine
|
||||||
|
|
||||||
|
Tested-on: PineTab2 (BES2600WM + RK3566) running linux-pinetab2
|
||||||
|
6.19.10-danctnix1-1. Driver continues to associate and pass traffic;
|
||||||
|
no kernel messages related to the cdev absence. Users that previously
|
||||||
|
wrote to /dev/bes2600 should switch to the fw_type module parameter
|
||||||
|
or (future patch c4) nl80211 testmode commands.
|
||||||
|
|
||||||
|
Follow-ups:
|
||||||
|
|
||||||
|
- c3.1: thread struct device * through bes2600_chrdev_is_signal_mode
|
||||||
|
and friends so the global bes2600_cdev singleton can be dropped
|
||||||
|
and the accessors scale to multi-device scenarios.
|
||||||
|
- c4: enable CONFIG_BES2600_TESTMODE and route nl80211 testmode
|
||||||
|
commands to the firmware's patch_wifi_testMode entry.
|
||||||
|
|
||||||
|
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
---
|
||||||
|
bes2600/bes_chardev.c | 519 ------------------------------------------
|
||||||
|
1 file changed, 519 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/bes2600/bes_chardev.c b/bes2600/bes_chardev.c
|
||||||
|
index 9038e48..e2e4f1b 100644
|
||||||
|
--- a/bes2600/bes_chardev.c
|
||||||
|
+++ b/bes2600/bes_chardev.c
|
||||||
|
@@ -43,12 +43,6 @@ enum bus_probe_state {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bes_cdev {
|
||||||
|
- struct cdev cdev;
|
||||||
|
- dev_t dev_id;
|
||||||
|
- int major;
|
||||||
|
- int minor;
|
||||||
|
- struct class *class;
|
||||||
|
- struct device *device;
|
||||||
|
atomic_t num_proc;
|
||||||
|
wait_queue_head_t open_wq;
|
||||||
|
spinlock_t status_lock;
|
||||||
|
@@ -249,351 +243,18 @@ int bes2600_switch_bt(bool on)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int bes2600_get_cmd_and_ifname(const char *str, char **result)
|
||||||
|
-{
|
||||||
|
- int cmd_len = 0;
|
||||||
|
- int ifname_len = 0;
|
||||||
|
- char *sp = NULL;
|
||||||
|
- char *tmp_ptr = NULL;
|
||||||
|
- char *cmd_ptr = NULL;
|
||||||
|
-
|
||||||
|
- /* check if input arguments is valid */
|
||||||
|
- if (!str || strncmp(str, "ifname:", 7) != 0)
|
||||||
|
- return -1;
|
||||||
|
-
|
||||||
|
- sp = strchr(str, ' ');
|
||||||
|
- if (strncmp(sp + 1, "cmd:", 4) != 0)
|
||||||
|
- return -1;
|
||||||
|
-
|
||||||
|
- /* extract interface name */
|
||||||
|
- ifname_len = sp - str - 7;
|
||||||
|
- tmp_ptr = kmalloc(ifname_len + 1, GFP_KERNEL);
|
||||||
|
- if (!tmp_ptr) {
|
||||||
|
- return -2;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- strncpy(tmp_ptr, str+7, ifname_len);
|
||||||
|
- tmp_ptr[ifname_len] = '\0';
|
||||||
|
- result[0] = tmp_ptr;
|
||||||
|
-
|
||||||
|
- /* get command length */
|
||||||
|
- cmd_ptr = strstr(str, "cmd:");
|
||||||
|
- cmd_ptr += 4;
|
||||||
|
- sp = strchr(cmd_ptr, ' ');
|
||||||
|
- if (!sp) { /* the command don't have any parameter */
|
||||||
|
- cmd_len = strlen(cmd_ptr);
|
||||||
|
- if (cmd_ptr[cmd_len - 1] == '\n')
|
||||||
|
- --cmd_len;
|
||||||
|
- } else { /* the command have one or more parameter */
|
||||||
|
- cmd_len = sp - cmd_ptr;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* copy command to out buffer */
|
||||||
|
- tmp_ptr = kmalloc( cmd_len + 1, GFP_KERNEL);
|
||||||
|
- if (!tmp_ptr) {
|
||||||
|
- kfree(result[0]);
|
||||||
|
- result[0] = NULL;
|
||||||
|
- return -3;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- strncpy(tmp_ptr, cmd_ptr, cmd_len);
|
||||||
|
- tmp_ptr[cmd_len] = '\0';
|
||||||
|
- result[1] = tmp_ptr;
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void bes2600_recyle_cmd_and_ifname_mem(char **info)
|
||||||
|
-{
|
||||||
|
- if (info[0]) {
|
||||||
|
- kfree(info[0]);
|
||||||
|
- info[0] = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (info[1]) {
|
||||||
|
- kfree(info[1]);
|
||||||
|
- info[1] = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int bes2600_op_default_handler(const char *str)
|
||||||
|
-{
|
||||||
|
- char *info[2] = {0};
|
||||||
|
-
|
||||||
|
- if (bes2600_get_cmd_and_ifname(str, info) == 0) {
|
||||||
|
- bes_devel("cmd(%s) on %s not handled\n", info[1], info[0]);
|
||||||
|
- } else {
|
||||||
|
- bes_err("%s get command fail, the origin string is %s\n", __func__, str);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bes2600_recyle_cmd_and_ifname_mem(info);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int bes2600_op_wifi_bt_on_off(const char *str)
|
||||||
|
-{
|
||||||
|
- char *info[2] = {0};
|
||||||
|
- int ret = 0;
|
||||||
|
- enum wait_state wait_state;
|
||||||
|
- enum bus_probe_state probe_state;
|
||||||
|
- unsigned long status = 0;
|
||||||
|
-
|
||||||
|
- spin_lock(&bes2600_cdev.status_lock);
|
||||||
|
- probe_state = bes2600_cdev.bus_probe;
|
||||||
|
- wait_state = bes2600_cdev.wait_state;
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
-
|
||||||
|
- /* only work for wifi signal mode */
|
||||||
|
- if (bes2600_cdev.fw_type != BES2600_FW_TYPE_WIFI_SIGNAL)
|
||||||
|
- return -EFAULT;
|
||||||
|
-
|
||||||
|
- /* wait bus probe operation end */
|
||||||
|
- if (probe_state == BES2600_BUS_PROBE_START) {
|
||||||
|
- bes_devel("wait bus probe operation end\n");
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq,
|
||||||
|
- (bes2600_cdev.bus_probe > BES2600_BUS_PROBE_START),
|
||||||
|
- HZ);
|
||||||
|
- WARN_ON(status <= 0);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* must wait previous operation end in critical section */
|
||||||
|
- if (wait_state != BES2600_BOOT_WAIT_NONE) {
|
||||||
|
- bes_devel("wait previous operation end\n");
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq,
|
||||||
|
- (bes2600_cdev.wait_state == BES2600_BOOT_WAIT_NONE),
|
||||||
|
- HZ * 8);
|
||||||
|
- WARN_ON(status <= 0);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* if dpd calibration is doing, modify wifi and bt state directly */
|
||||||
|
- spin_lock(&bes2600_cdev.status_lock);
|
||||||
|
- if (bes2600_cdev.bus_probe == BES2600_BUS_PROBE_OK && !bes2600_cdev.dpd_calied) {
|
||||||
|
- if (bes2600_get_cmd_and_ifname(str, info) == 0) {
|
||||||
|
- if (strncmp(info[1], "WIFI_ON", 7) == 0) {
|
||||||
|
- bes2600_cdev.wifi_opened = true;
|
||||||
|
- } else if (strncmp(info[1], "WIFI_OFF", 8) == 0) {
|
||||||
|
- bes2600_cdev.wifi_opened = false;
|
||||||
|
- } else if (strncmp(info[1], "BT_ON", 5) == 0) {
|
||||||
|
- bes2600_cdev.bt_opened = true;
|
||||||
|
- bes2600_cdev.bton_pending = true;
|
||||||
|
- } else if (strncmp(info[1], "BT_OFF", 6) == 0) {
|
||||||
|
- bes2600_cdev.bt_opened = false;
|
||||||
|
- bes2600_cdev.bton_pending = false;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- bes2600_recyle_cmd_and_ifname_mem(info);
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
-
|
||||||
|
- /* wait probe done event */
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq,
|
||||||
|
- bes2600_bootup_end(), HZ * 8);
|
||||||
|
- WARN_ON(status <= 0);
|
||||||
|
-
|
||||||
|
- return (status <= 0 || bes2600_chrdev_is_bus_error()) ? -EFAULT : 0;
|
||||||
|
- }
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
-
|
||||||
|
- /* process wifi/bt on/off operation */
|
||||||
|
- if (bes2600_get_cmd_and_ifname(str, info) == 0) {
|
||||||
|
- if (strncmp(info[1], "WIFI_ON", 7) == 0) {
|
||||||
|
- ret = bes2600_switch_wifi(1);
|
||||||
|
- } else if (strncmp(info[1], "WIFI_OFF", 8) == 0) {
|
||||||
|
- ret = bes2600_switch_wifi(0);
|
||||||
|
- } else if (strncmp(info[1], "BT_ON", 5) == 0) {
|
||||||
|
- ret = bes2600_switch_bt(1);
|
||||||
|
- } else if (strncmp(info[1], "BT_OFF", 6) == 0) {
|
||||||
|
- ret = bes2600_switch_bt(0);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!ret && bes2600_chrdev_check_system_close())
|
||||||
|
- ret = bes2600_chrdev_do_system_close(bes2600_cdev.sbus_ops,
|
||||||
|
- bes2600_cdev.sbus_priv);
|
||||||
|
-
|
||||||
|
- bes2600_recyle_cmd_and_ifname_mem(info);
|
||||||
|
-
|
||||||
|
- return ret ;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-static int bes2600_op_change_fw_type(const char *str)
|
||||||
|
-{
|
||||||
|
- int ret = 0;
|
||||||
|
- int temp = 0;
|
||||||
|
- long status = 0;
|
||||||
|
- char *cmd_ptr = NULL;
|
||||||
|
- char fw_type[5] = {0};
|
||||||
|
- bool sys_closed = bes2600_chrdev_check_system_close();
|
||||||
|
-
|
||||||
|
- bes_devel("%s is called, arg:%s\n", __func__, str);
|
||||||
|
-
|
||||||
|
- if (!bes2600_cdev.sbus_ops->power_switch && !bes2600_cdev.sbus_ops->reboot)
|
||||||
|
- return -EPERM;
|
||||||
|
-
|
||||||
|
- /* check if user input is valid */
|
||||||
|
- cmd_ptr = strstr(str, "CHANGE_FW_TYPE ");
|
||||||
|
- if (strlen(str) < 16 || !cmd_ptr) {
|
||||||
|
- bes_err("the format of \"%s\" is error\n", str);
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* convert fw_type from string to int */
|
||||||
|
- strncpy(fw_type, cmd_ptr + 14, 4);
|
||||||
|
- fw_type[0] = '+';
|
||||||
|
- ret = kstrtoint(fw_type, 10, &temp);
|
||||||
|
- if (ret < 0) {
|
||||||
|
- bes_err("%s parse error\n", __func__);
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* no need to realod firmware if new fw_type is equal to the old */
|
||||||
|
- if (temp == bes2600_cdev.fw_type ) {
|
||||||
|
- bes_devel("fw type is equal\n");
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* close wifi net device */
|
||||||
|
- if (bes2600_cdev.sbus_priv
|
||||||
|
- && bes2600_is_net_dev_created(bes2600_cdev.sbus_priv)) {
|
||||||
|
- bes2600_unregister_net_dev(bes2600_cdev.sbus_priv);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* update firmware type */
|
||||||
|
- bes2600_cdev.fw_type = temp;
|
||||||
|
- bes2600_chrdev_update_signal_mode();
|
||||||
|
-
|
||||||
|
- if (!sys_closed) {
|
||||||
|
- /* close device to call disconnect function */
|
||||||
|
- if (bes2600_cdev.sbus_ops->power_switch)
|
||||||
|
- bes2600_cdev.sbus_ops->power_switch(bes2600_cdev.sbus_priv, 0);
|
||||||
|
- else if (bes2600_cdev.sbus_ops->reboot)
|
||||||
|
- bes2600_cdev.sbus_ops->reboot(bes2600_cdev.sbus_priv);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (bes2600_cdev.sbus_ops->reboot)
|
||||||
|
- bes2600_chrdev_start_bus_probe();
|
||||||
|
-
|
||||||
|
- /* wait disconnect event */
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq, (bes2600_cdev.sbus_priv == NULL), HZ * 10);
|
||||||
|
- WARN_ON(status <= 0);
|
||||||
|
-
|
||||||
|
- if (bes2600_cdev.dpd_calied
|
||||||
|
- && bes2600_chrdev_check_system_close()) {
|
||||||
|
- bes_devel("no need to reload firmware\n");
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bes_devel("reload firmware...\n");
|
||||||
|
- /* power on device to call probe function */
|
||||||
|
- if (bes2600_cdev.sbus_ops->power_switch)
|
||||||
|
- bes2600_cdev.sbus_ops->power_switch(NULL, 1);
|
||||||
|
-
|
||||||
|
- /* wait probe done event */
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq,
|
||||||
|
- bes2600_bootup_end(), HZ * 10);
|
||||||
|
- WARN_ON(status <= 0);
|
||||||
|
-
|
||||||
|
- ret = (status <= 0 || bes2600_chrdev_is_bus_error()) ? -1 : 0;
|
||||||
|
|
||||||
|
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int bes2600_op_bt_wakeup(const char *str)
|
||||||
|
-{
|
||||||
|
- int ret = 0;
|
||||||
|
- unsigned long status = 0;
|
||||||
|
-
|
||||||
|
- spin_lock(&bes2600_cdev.status_lock);
|
||||||
|
- if (!bes2600_cdev.bt_opened) {
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
- return -EFAULT;
|
||||||
|
- }
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
|
||||||
|
- /* wait probe done event */
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq,
|
||||||
|
- bes2600_bootup_end(), HZ * 8);
|
||||||
|
- if (status <= 0 || bes2600_chrdev_is_bus_error())
|
||||||
|
- return -EFAULT;
|
||||||
|
-
|
||||||
|
- bes_devel("bes2600 wakeup bt.\n");
|
||||||
|
- ret = bes2600_chrdev_switch_subsys(GPIO_WAKE_FLAG_BT_LP_ON, SUBSYSTEM_BT_LP, true);
|
||||||
|
-
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int bes2600_op_bt_sleep(const char *str)
|
||||||
|
-{
|
||||||
|
- int ret = 0;
|
||||||
|
- unsigned long status = 0;
|
||||||
|
-
|
||||||
|
- spin_lock(&bes2600_cdev.status_lock);
|
||||||
|
- if (!bes2600_cdev.bt_opened) {
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
- return -EFAULT;
|
||||||
|
- }
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
|
||||||
|
- /* wait probe done event */
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.probe_done_wq,
|
||||||
|
- bes2600_bootup_end(), HZ * 8);
|
||||||
|
- if (status <= 0 || bes2600_chrdev_is_bus_error())
|
||||||
|
- return -EFAULT;
|
||||||
|
|
||||||
|
- bes_devel("bes2600 allow bt sleep.\n");
|
||||||
|
- ret = bes2600_chrdev_switch_subsys(GPIO_WAKE_FLAG_BT_LP_OFF, SUBSYSTEM_BT_LP, false);
|
||||||
|
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
|
||||||
|
-static int bes2600_op_set_wakeup_read_flag(const char *str)
|
||||||
|
-{
|
||||||
|
- bes_devel("%s is called, arg:%s\n", __func__, str);
|
||||||
|
- spin_lock(&bes2600_cdev.status_lock);
|
||||||
|
- bes2600_cdev.read_flag = BES_CDEV_READ_WAKEUP_STATE;
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
|
||||||
|
#ifdef FW_DOWNLOAD_UART_DAEMON
|
||||||
|
-int bes2600_load_uevent(char *env[])
|
||||||
|
-{
|
||||||
|
- return kobject_uevent_env(&bes2600_cdev.device->kobj, KOBJ_CHANGE, env);
|
||||||
|
-}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-static struct bes2600_op_map bes2600_op_map_tab[] ={
|
||||||
|
- /*op op_len handler */
|
||||||
|
- {"P2P_SET_NOA", 11, bes2600_op_default_handler},
|
||||||
|
- {"P2P_SET_PS", 10, bes2600_op_default_handler},
|
||||||
|
- {"SET_AP_WPS_P2P_IE", 17, bes2600_op_default_handler},
|
||||||
|
- {"LINKSPEED", 9, bes2600_op_default_handler},
|
||||||
|
- {"RSSI", 4, bes2600_op_default_handler},
|
||||||
|
- {"GETBAND", 7, bes2600_op_default_handler},
|
||||||
|
- {"WLS_BATCHING", 12, bes2600_op_default_handler},
|
||||||
|
- {"MACADDR", 7, bes2600_op_default_handler},
|
||||||
|
- {"RXFILTER-START", 14, bes2600_op_default_handler},
|
||||||
|
- {"RXFILTER-STOP", 13, bes2600_op_default_handler},
|
||||||
|
- {"RXFILTER-ADD", 12, bes2600_op_default_handler},
|
||||||
|
- {"RXFILTER-REMOVE", 15, bes2600_op_default_handler},
|
||||||
|
- {"BTCOEXMODE", 10, bes2600_op_default_handler},
|
||||||
|
- {"BTCOEXSCAN-START", 16, bes2600_op_default_handler},
|
||||||
|
- {"BTCOEXSCAN-STOP", 15, bes2600_op_default_handler},
|
||||||
|
- {"SETSUSPENDMODE", 14, bes2600_op_default_handler},
|
||||||
|
- {"COUNTRY", 7, bes2600_op_default_handler},
|
||||||
|
- {"WIFI_ON", 7, bes2600_op_wifi_bt_on_off},
|
||||||
|
- {"WIFI_OFF", 8, bes2600_op_wifi_bt_on_off},
|
||||||
|
- {"BT_ON", 5, bes2600_op_wifi_bt_on_off},
|
||||||
|
- {"BT_OFF", 6, bes2600_op_wifi_bt_on_off},
|
||||||
|
- {"CHANGE_FW_TYPE", 14, bes2600_op_change_fw_type},
|
||||||
|
- {"BT_WAKEUP", 9, bes2600_op_bt_wakeup},
|
||||||
|
- {"BT_SLEEP", 8, bes2600_op_bt_sleep},
|
||||||
|
- {"WAKEUP_STATE", 12, bes2600_op_set_wakeup_read_flag},
|
||||||
|
-};
|
||||||
|
|
||||||
|
static int bes2600_chrdev_check_system_close_internal(void)
|
||||||
|
{
|
||||||
|
@@ -603,123 +264,10 @@ static int bes2600_chrdev_check_system_close_internal(void)
|
||||||
|
&& (bes2600_cdev.wifi_opened == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int bes2600_chrdev_open(struct inode *inode, struct file *filp)
|
||||||
|
-{
|
||||||
|
- if (atomic_read(&bes2600_cdev.num_proc) > 0) {
|
||||||
|
- wait_event_timeout(bes2600_cdev.open_wq,
|
||||||
|
- (atomic_read(&bes2600_cdev.num_proc) == 0),
|
||||||
|
- MAX_SCHEDULE_TIMEOUT);
|
||||||
|
- }
|
||||||
|
|
||||||
|
- bes_devel("bes2600 char device is opened\n");
|
||||||
|
- atomic_inc(&bes2600_cdev.num_proc);
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
|
||||||
|
-static ssize_t bes2600_chrdev_read(struct file *file, char __user *user_buf,
|
||||||
|
- size_t count, loff_t *ppos)
|
||||||
|
-{
|
||||||
|
- char buf[64] = {0};
|
||||||
|
- unsigned int len;
|
||||||
|
- long status = 0;
|
||||||
|
|
||||||
|
- switch (bes2600_cdev.read_flag) {
|
||||||
|
- case BES_CDEV_READ_WAKEUP_STATE:
|
||||||
|
- if (bes2600_chrdev_wakeup_by_event_get() > WAKEUP_EVENT_NONE) {
|
||||||
|
- status = wait_event_timeout(bes2600_cdev.wakeup_reason_wq,
|
||||||
|
- bes2600_chrdev_wakeup_by_event_get() == WAKEUP_EVENT_NONE, HZ * 2);
|
||||||
|
- WARN_ON(status <= 0);
|
||||||
|
- }
|
||||||
|
- len = sprintf(buf, "wakeup_reason: %u, src_port: %u\n",
|
||||||
|
- bes2600_cdev.wakeup_state, bes2600_cdev.src_port);
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- len = sprintf(buf, "dpd_calied:%d wifi_opened:%d bt_opened:%d fw_type:%d\n",
|
||||||
|
- bes2600_cdev.dpd_calied,
|
||||||
|
- bes2600_cdev.wifi_opened,
|
||||||
|
- bes2600_cdev.bt_opened,
|
||||||
|
- bes2600_cdev.fw_type);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- len = sizeof(buf);
|
||||||
|
- /* reset read flag */
|
||||||
|
- spin_lock(&bes2600_cdev.status_lock);
|
||||||
|
- bes2600_cdev.read_flag = BES_CDEV_READ_NUM_MAX;
|
||||||
|
- spin_unlock(&bes2600_cdev.status_lock);
|
||||||
|
-
|
||||||
|
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static ssize_t bes2600_chrdev_write(struct file *file,
|
||||||
|
- const char __user *user_buf, size_t count, loff_t *ppos)
|
||||||
|
-{
|
||||||
|
- int i = 0;
|
||||||
|
- int cmd_num = ARRAY_SIZE(bes2600_op_map_tab);
|
||||||
|
- int cmd_len = 0;
|
||||||
|
- int ret = 0;
|
||||||
|
- char *info[2] = {0};
|
||||||
|
- char *buf = NULL;
|
||||||
|
-
|
||||||
|
- /* copy content from user space to kernel */
|
||||||
|
- /* message format:"ifname:wlanx cmd:xxx arg1 arg2 ..." */
|
||||||
|
- buf = kmalloc(count + 1, GFP_KERNEL);
|
||||||
|
- if (copy_from_user(buf, user_buf, count))
|
||||||
|
- return -EFAULT;
|
||||||
|
-
|
||||||
|
- /* add terminal character */
|
||||||
|
- buf[count] = '\0';
|
||||||
|
-
|
||||||
|
- /* extract comand and interface */
|
||||||
|
- if (bes2600_get_cmd_and_ifname(buf, info) != 0) {
|
||||||
|
- bes_err("%s get command fail, the origin string is %s\n", __func__, buf);
|
||||||
|
- kfree(buf);
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* match operation item and execure its handler */
|
||||||
|
- cmd_len = strlen(info[1]);
|
||||||
|
- for (i = 0; i < cmd_num; i++) {
|
||||||
|
- if (cmd_len < bes2600_op_map_tab[i].op_len)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- if (strncasecmp(info[1], bes2600_op_map_tab[i].op, bes2600_op_map_tab[i].op_len) == 0) {
|
||||||
|
- ret = bes2600_op_map_tab[i].handler(buf);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* operation item mismatch */
|
||||||
|
- if (i == cmd_num) {
|
||||||
|
- bes_err("cmd(%s) mismatch\n", info[1]);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bes2600_recyle_cmd_and_ifname_mem(info);
|
||||||
|
- kfree(buf);
|
||||||
|
-
|
||||||
|
- return (ret == 0) ? count : ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int bes2600_chrdev_release (struct inode *inode, struct file *file)
|
||||||
|
-{
|
||||||
|
- if (atomic_dec_and_test(&bes2600_cdev.num_proc)) {
|
||||||
|
- wake_up(&bes2600_cdev.open_wq);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bes_devel("bes2600 char device is closed\n");
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static struct file_operations bes2600_chardev_fops =
|
||||||
|
-{
|
||||||
|
- .owner = THIS_MODULE,
|
||||||
|
- .open = bes2600_chrdev_open,
|
||||||
|
- .read = bes2600_chrdev_read,
|
||||||
|
- .write = bes2600_chrdev_write,
|
||||||
|
- .release = bes2600_chrdev_release,
|
||||||
|
-};
|
||||||
|
|
||||||
|
#ifdef BES2600_WRITE_DPD_TO_FILE
|
||||||
|
static int bes2600_chrdev_write_dpd_data_to_file(const char *path, void *buffer, int size)
|
||||||
|
@@ -1124,12 +672,6 @@ void bes2600_chrdev_update_signal_mode(void)
|
||||||
|
|
||||||
|
static void bes2600_chrdev_wifi_force_close_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
- char wifi_state[15];
|
||||||
|
- char bt_state[15];
|
||||||
|
- char fw_type[15];
|
||||||
|
- char *env[] = { wifi_state, bt_state, fw_type, NULL };
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
if (bes2600_chrdev_is_wifi_opened()) {
|
||||||
|
bes_devel("system exeception, force wifi down\n");
|
||||||
|
|
||||||
|
@@ -1146,14 +688,6 @@ static void bes2600_chrdev_wifi_force_close_work(struct work_struct *work)
|
||||||
|
bes2600_chrdev_do_system_close(bes2600_cdev.sbus_ops,
|
||||||
|
bes2600_cdev.sbus_priv);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- /* notify userspace */
|
||||||
|
- snprintf(wifi_state, sizeof(wifi_state), "WIFI_OPENED=%d", bes2600_cdev.wifi_opened);
|
||||||
|
- snprintf(bt_state, sizeof(bt_state), "BT_OPENED=%d", bes2600_cdev.bt_opened);
|
||||||
|
- snprintf(fw_type, sizeof(fw_type), "FW_TYPE=%d", bes2600_cdev.fw_type);
|
||||||
|
- ret = kobject_uevent_env(&bes2600_cdev.device->kobj, KOBJ_CHANGE, env);
|
||||||
|
- if (!ret)
|
||||||
|
- bes_err("bes2600 notify userspace failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1247,46 +781,6 @@ int bes2600_chrdev_wakeup_by_event_get(void)
|
||||||
|
|
||||||
|
int bes2600_chrdev_init(struct sbus_ops *ops)
|
||||||
|
{
|
||||||
|
- int ret = 0;
|
||||||
|
-
|
||||||
|
- /* allocate devide id */
|
||||||
|
- ret = alloc_chrdev_region(&bes2600_cdev.dev_id, 0, 1, "bes2600_chrdev");
|
||||||
|
- if (ret < 0){
|
||||||
|
- bes_err("bes2600 alloc device id fail\n");
|
||||||
|
- ret = -EFAULT;
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* extract major and minor device id */
|
||||||
|
- bes2600_cdev.major = MAJOR(bes2600_cdev.dev_id);
|
||||||
|
- bes2600_cdev.minor = MINOR(bes2600_cdev.dev_id);
|
||||||
|
-
|
||||||
|
- /* add char device and bind operation function */
|
||||||
|
- bes2600_cdev.cdev.owner = THIS_MODULE;
|
||||||
|
- cdev_init(&bes2600_cdev.cdev, &bes2600_chardev_fops);
|
||||||
|
- ret = cdev_add(&bes2600_cdev.cdev, bes2600_cdev.dev_id, 1);
|
||||||
|
- if (ret < 0){
|
||||||
|
- bes_err("bes2600 char device add fail\n");
|
||||||
|
- ret = -EFAULT;
|
||||||
|
- goto fail1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* create class for creating device node */
|
||||||
|
- bes2600_cdev.class = class_create("bes2600_chrdev");
|
||||||
|
- if (IS_ERR(bes2600_cdev.class)){
|
||||||
|
- bes_err("bes2600 char device add fail\n");
|
||||||
|
- ret = -EFAULT;
|
||||||
|
- goto fail2;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* get char device pointer */
|
||||||
|
- bes2600_cdev.device = device_create(bes2600_cdev.class, NULL, bes2600_cdev.dev_id, NULL, "bes2600");
|
||||||
|
- if (IS_ERR(bes2600_cdev.device)){
|
||||||
|
- bes_err("bes2600 char device create fail\n");
|
||||||
|
- ret = -EFAULT;
|
||||||
|
- goto fail3;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* initialise global variable */
|
||||||
|
atomic_set(&bes2600_cdev.num_proc, 0);
|
||||||
|
init_waitqueue_head(&bes2600_cdev.open_wq);
|
||||||
|
@@ -1318,15 +812,6 @@ int bes2600_chrdev_init(struct sbus_ops *ops)
|
||||||
|
bes_devel("%s done\n", __func__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
-
|
||||||
|
-fail3:
|
||||||
|
- class_destroy(bes2600_cdev.class);
|
||||||
|
-fail2:
|
||||||
|
- cdev_del(&bes2600_cdev.cdev);
|
||||||
|
-fail1:
|
||||||
|
- unregister_chrdev_region(bes2600_cdev.dev_id, 1);
|
||||||
|
-fail:
|
||||||
|
- return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bes2600_chrdev_free(void)
|
||||||
|
@@ -1336,9 +821,5 @@ void bes2600_chrdev_free(void)
|
||||||
|
bes2600_free_dpd_log_buffer();
|
||||||
|
#endif
|
||||||
|
bes2600_chrdev_free_dpd_data();
|
||||||
|
- cdev_del(&bes2600_cdev.cdev);
|
||||||
|
- unregister_chrdev_region(bes2600_cdev.dev_id, 1);
|
||||||
|
- device_destroy(bes2600_cdev.class, bes2600_cdev.dev_id);
|
||||||
|
- class_destroy(bes2600_cdev.class);
|
||||||
|
bes_devel("%s done\n", __func__);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
|
||||||
+143
@@ -0,0 +1,143 @@
|
|||||||
|
From 6f13e008d21d453db486f707f47340a0a17e650b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
Date: Wed, 22 Apr 2026 13:04:27 +0200
|
||||||
|
Subject: [PATCH 6/6] bes2600: enable CONFIG_BES2600_TESTMODE by default + fix
|
||||||
|
bit-rotted testmode plumbing
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The driver implements a mac80211 testmode_cmd operation that dispatches
|
||||||
|
to a set of vendor commands (GET_TX_POWER_LEVEL, GET_TX_POWER_RANGE,
|
||||||
|
SET_SNAP_FRAME, TSM_STATS, GET_ROAM_DELAY, GET_STREAM, etc) plus the
|
||||||
|
BES2600 RF-test path (bes2600_vendor_rf_cmd → firmware
|
||||||
|
patch_wifi_testMode). The testmode handlers and the .testmode_cmd
|
||||||
|
binding in struct ieee80211_ops are conditionally compiled under
|
||||||
|
CONFIG_BES2600_TESTMODE, which previously defaulted to n.
|
||||||
|
|
||||||
|
Flip the Makefile default from n to y so wifi_testmode_cmd.o is
|
||||||
|
included in the build and the .testmode_cmd op is populated. On the
|
||||||
|
PineTab2 target kernel (linux-pinetab2 6.19.10-danctnix1, built with
|
||||||
|
CONFIG_NL80211_TESTMODE=y) this exposes the BES2600 RF-test surface
|
||||||
|
through the standard nl80211 testmode interface ('iw phy0 ...').
|
||||||
|
|
||||||
|
This also makes visible two classes of bit-rot that had accumulated
|
||||||
|
while nobody was building with CONFIG_BES2600_TESTMODE=y:
|
||||||
|
|
||||||
|
1. sta.c contains ~41 calls to bes2600_info() / bes2600_err() /
|
||||||
|
bes2600_warn() / bes2600_dbg() / bes2600_err_with_cond() - a
|
||||||
|
legacy log-macro family carrying a BES2600_DBG_* subsystem-id
|
||||||
|
first argument. Neither the macros nor any of the BES2600_DBG_*
|
||||||
|
constants are defined anywhere in the tree. The same call pattern
|
||||||
|
appears under #if defined(BES2600_DETECTION_LOGIC) in hwio.c and
|
||||||
|
under CONFIG_BES2600_ITP in itp.c, both normally disabled.
|
||||||
|
|
||||||
|
Add minimal shim macros to bes_log.h that rewire the calls onto
|
||||||
|
the existing bes_info() / bes_err() / bes_warn() / bes_devel()
|
||||||
|
family (ignoring the subsystem id). Define BES2600_DBG_SBUS,
|
||||||
|
BES2600_DBG_DOWNLOAD, BES2600_DBG_ITP and BES2600_DBG_TEST_MODE
|
||||||
|
as 0 constants for documentation / grep.
|
||||||
|
|
||||||
|
2. bes2600_start_stop_tsm(), bes2600_get_tsm_params(), and
|
||||||
|
bes2600_get_roam_delay() are declared in sta.c with external
|
||||||
|
linkage but have no prototype in any header. All callers live in
|
||||||
|
sta.c (inside bes2600_testmode_cmd). With CONFIG_BES2600_TESTMODE
|
||||||
|
off the compiler never sees them; with it on gcc
|
||||||
|
-Werror=missing-prototypes breaks the build.
|
||||||
|
|
||||||
|
Mark the three functions static. (Keeping them file-local also
|
||||||
|
matches their actual usage.)
|
||||||
|
|
||||||
|
Both changes are strictly scoped to make CONFIG_BES2600_TESTMODE=y
|
||||||
|
buildable; no behavioural change when the flag is off.
|
||||||
|
|
||||||
|
Tested-on: PineTab2 (BES2600WM + RK3566) running linux-pinetab2
|
||||||
|
6.19.10-danctnix1-1 with CONFIG_NL80211_TESTMODE=y. Module builds
|
||||||
|
cleanly, nl80211 testmode interface reachable via 'iw phy0 ...' from
|
||||||
|
userspace.
|
||||||
|
|
||||||
|
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
||||||
|
---
|
||||||
|
bes2600/Makefile | 2 +-
|
||||||
|
bes2600/bes_log.h | 23 +++++++++++++++++++++++
|
||||||
|
bes2600/sta.c | 6 +++---
|
||||||
|
3 files changed, 27 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/bes2600/Makefile b/bes2600/Makefile
|
||||||
|
index 2dcba09..2c1a850 100644
|
||||||
|
--- a/bes2600/Makefile
|
||||||
|
+++ b/bes2600/Makefile
|
||||||
|
@@ -2,7 +2,7 @@ KERN_DIR = /lib/modules/$(KERNELRELEASE)/build
|
||||||
|
# feature option
|
||||||
|
BES2600 ?= m
|
||||||
|
|
||||||
|
-CONFIG_BES2600_TESTMODE ?= n
|
||||||
|
+CONFIG_BES2600_TESTMODE ?= y
|
||||||
|
|
||||||
|
CONFIG_BES2600_ENABLE_DEVEL_LOGS ?= n
|
||||||
|
|
||||||
|
diff --git a/bes2600/bes_log.h b/bes2600/bes_log.h
|
||||||
|
index 605cea8..65cf703 100644
|
||||||
|
--- a/bes2600/bes_log.h
|
||||||
|
+++ b/bes2600/bes_log.h
|
||||||
|
@@ -8,3 +8,26 @@ extern struct device *global_dev;
|
||||||
|
#define bes_info(fmt, ...) dev_info(global_dev, fmt, ##__VA_ARGS__)
|
||||||
|
#define bes_warn(fmt, ...) dev_warn(global_dev, fmt, ##__VA_ARGS__)
|
||||||
|
#define bes_err(fmt, ...) dev_err(global_dev, fmt, ##__VA_ARGS__)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Legacy debug-subsystem-tagged log macros. The per-subsystem filtering
|
||||||
|
+ * was never implemented in-tree; these shims let code paths gated by
|
||||||
|
+ * CONFIG_BES2600_TESTMODE / CONFIG_BES2600_ITP / BES2600_DETECTION_LOGIC
|
||||||
|
+ * build when their conditions are enabled. The first argument is
|
||||||
|
+ * currently unused; pick one of the BES2600_DBG_* constants below for
|
||||||
|
+ * documentation.
|
||||||
|
+ */
|
||||||
|
+#define BES2600_DBG_SBUS 0
|
||||||
|
+#define BES2600_DBG_DOWNLOAD 0
|
||||||
|
+#define BES2600_DBG_ITP 0
|
||||||
|
+#define BES2600_DBG_TEST_MODE 0
|
||||||
|
+
|
||||||
|
+#define bes2600_info(_dbg, fmt, ...) bes_info(fmt, ##__VA_ARGS__)
|
||||||
|
+#define bes2600_err(_dbg, fmt, ...) bes_err(fmt, ##__VA_ARGS__)
|
||||||
|
+#define bes2600_warn(_dbg, fmt, ...) bes_warn(fmt, ##__VA_ARGS__)
|
||||||
|
+#define bes2600_dbg(_dbg, fmt, ...) bes_devel(fmt, ##__VA_ARGS__)
|
||||||
|
+#define bes2600_err_with_cond(_cond, _dbg, fmt, ...) \
|
||||||
|
+ do { \
|
||||||
|
+ if (_cond) \
|
||||||
|
+ bes_err(fmt, ##__VA_ARGS__); \
|
||||||
|
+ } while (0)
|
||||||
|
diff --git a/bes2600/sta.c b/bes2600/sta.c
|
||||||
|
index aa69eb8..5f1a456 100644
|
||||||
|
--- a/bes2600/sta.c
|
||||||
|
+++ b/bes2600/sta.c
|
||||||
|
@@ -3633,7 +3633,7 @@ static int bes2600_set_power_save(struct ieee80211_hw *hw,
|
||||||
|
*
|
||||||
|
* Returns: 0 on success or non zero value on failure
|
||||||
|
*/
|
||||||
|
-int bes2600_start_stop_tsm(struct ieee80211_hw *hw, void *data)
|
||||||
|
+static int bes2600_start_stop_tsm(struct ieee80211_hw *hw, void *data)
|
||||||
|
{
|
||||||
|
struct bes_msg_start_stop_tsm *start_stop_tsm =
|
||||||
|
(struct bes_msg_start_stop_tsm *) data;
|
||||||
|
@@ -3663,7 +3663,7 @@ int bes2600_start_stop_tsm(struct ieee80211_hw *hw, void *data)
|
||||||
|
*
|
||||||
|
* Returns: TSM parameters collected
|
||||||
|
*/
|
||||||
|
-int bes2600_get_tsm_params(struct ieee80211_hw *hw)
|
||||||
|
+static int bes2600_get_tsm_params(struct ieee80211_hw *hw)
|
||||||
|
{
|
||||||
|
struct bes2600_common *hw_priv = hw->priv;
|
||||||
|
struct bes_tsm_stats tsm_stats;
|
||||||
|
@@ -3703,7 +3703,7 @@ int bes2600_get_tsm_params(struct ieee80211_hw *hw)
|
||||||
|
*
|
||||||
|
* Returns: Returns the last measured roam delay
|
||||||
|
*/
|
||||||
|
-int bes2600_get_roam_delay(struct ieee80211_hw *hw)
|
||||||
|
+static int bes2600_get_roam_delay(struct ieee80211_hw *hw)
|
||||||
|
{
|
||||||
|
struct bes2600_common *hw_priv = hw->priv;
|
||||||
|
u16 roam_delay = hw_priv->tsm_info.roam_delay / 1000;
|
||||||
|
--
|
||||||
|
2.53.0
|
||||||
|
|
||||||
Reference in New Issue
Block a user